UltrafastSecp256k1 3.50.0
Ultra high-performance secp256k1 elliptic curve cryptography library
Loading...
Searching...
No Matches
field.hpp
Go to the documentation of this file.
1#ifndef SECP256K1_CT_FIELD_HPP
2#define SECP256K1_CT_FIELD_HPP
3
4// ============================================================================
5// Constant-Time Field Arithmetic
6// ============================================================================
7// Side-channel resistant field operations for secp256k1.
8// Operates on secp256k1::fast::FieldElement -- same data type, CT execution.
9//
10// Guarantees:
11// - No secret-dependent branches
12// - No secret-dependent memory access patterns
13// - Fixed instruction count for all inputs
14//
15// Usage:
16// using FE = secp256k1::fast::FieldElement;
17// FE a = ..., b = ...;
18// FE r = secp256k1::ct::field_add(a, b); // CT modular addition
19// secp256k1::ct::field_cmov(&r, &a, flag); // CT conditional move
20//
21// Mixing with fast::
22// FE x = secp256k1::fast::FieldElement::from_hex("..."); // public data
23// FE secret = ...; // secret scalar, etc.
24// FE r = secp256k1::ct::field_mul(x, secret); // CT for secret operand
25// ============================================================================
26
27#include <cstdint>
28#include "secp256k1/field.hpp"
29#include "secp256k1/ct/ops.hpp"
30
31namespace secp256k1::ct {
32
34
35// --- CT Modular Arithmetic ---------------------------------------------------
36// mul and square are inherently constant-time (fixed mul count).
37// add/sub/normalize need CT reduction.
38
39// CT modular addition: r = (a + b) mod p
40FieldElement field_add(const FieldElement& a, const FieldElement& b) noexcept;
41
42// CT modular subtraction: r = (a - b) mod p
43FieldElement field_sub(const FieldElement& a, const FieldElement& b) noexcept;
44
45// CT modular multiplication: r = (a * b) mod p
46// Note: The underlying mul is already CT (fixed Comba/schoolbook).
47// This wrapper ensures CT reduction.
48FieldElement field_mul(const FieldElement& a, const FieldElement& b) noexcept;
49
50// CT modular squaring: r = a^2 mod p
52
53// CT modular negation: r = -a mod p = p - a (if a != 0), 0 (if a == 0)
55
56// CT modular half: r = a/2 mod p
57// If a is odd: r = (a + p) / 2; if even: r = a / 2. Branchless.
59
60// CT modular inverse: r = a^-^1 mod p (via Fermat: a^(p-2))
61// Fixed add-chain: always same number of mul+sqr regardless of input
63
64// --- CT Conditional Operations -----------------------------------------------
65
66// CT conditional move: if (mask == all-ones) r = a; else r unchanged
67// mask MUST be 0x0000000000000000 or 0xFFFFFFFFFFFFFFFF
69 std::uint64_t mask) noexcept;
70
71// CT conditional swap: when mask is all-ones, swaps a and b; otherwise unchanged
73 std::uint64_t mask) noexcept;
74
75// CT select: returns a if mask==all-ones, else b
77 std::uint64_t mask) noexcept;
78
79// CT conditional negate: if (mask == all-ones) r = -a; else r = a
80FieldElement field_cneg(const FieldElement& a, std::uint64_t mask) noexcept;
81
82// --- CT Comparison -----------------------------------------------------------
83
84// Returns all-ones mask if a == 0, else 0. CT (no branch).
85std::uint64_t field_is_zero(const FieldElement& a) noexcept;
86
87// Returns all-ones mask if a == b, else 0. CT (no branch).
88std::uint64_t field_eq(const FieldElement& a, const FieldElement& b) noexcept;
89
90// --- CT Normalize ------------------------------------------------------------
91// Reduces a field element to canonical form [0, p) without branches.
93
94} // namespace secp256k1::ct
95
96#endif // SECP256K1_CT_FIELD_HPP
FieldElement field_half(const FieldElement &a) noexcept
FieldElement field_neg(const FieldElement &a) noexcept
FieldElement field_mul(const FieldElement &a, const FieldElement &b) noexcept
FieldElement field_cneg(const FieldElement &a, std::uint64_t mask) noexcept
FieldElement field_sub(const FieldElement &a, const FieldElement &b) noexcept
void field_cmov(FieldElement *r, const FieldElement &a, std::uint64_t mask) noexcept
FieldElement field_select(const FieldElement &a, const FieldElement &b, std::uint64_t mask) noexcept
FieldElement field_normalize(const FieldElement &a) noexcept
FieldElement field_sqr(const FieldElement &a) noexcept
std::uint64_t field_eq(const FieldElement &a, const FieldElement &b) noexcept
FieldElement field_inv(const FieldElement &a) noexcept
FieldElement field_add(const FieldElement &a, const FieldElement &b) noexcept
void field_cswap(FieldElement *a, FieldElement *b, std::uint64_t mask) noexcept
std::uint64_t field_is_zero(const FieldElement &a) noexcept