UltrafastSecp256k1 3.50.0
Ultra high-performance secp256k1 elliptic curve cryptography library
Loading...
Searching...
No Matches
scalar.hpp
Go to the documentation of this file.
1#ifndef SECP256K1_CT_SCALAR_HPP
2#define SECP256K1_CT_SCALAR_HPP
3
4// ============================================================================
5// Constant-Time Scalar Arithmetic
6// ============================================================================
7// Side-channel resistant scalar operations for secp256k1 curve order.
8// Operates on secp256k1::fast::Scalar -- same data type, CT execution.
9// ============================================================================
10
11#include <cstdint>
12#include "secp256k1/scalar.hpp"
13#include "secp256k1/ecdsa.hpp"
14#include "secp256k1/ct/ops.hpp"
15
16namespace secp256k1::ct {
17
19
20// --- CT Scalar Arithmetic ----------------------------------------------------
21
22// CT modular addition: r = (a + b) mod n
23Scalar scalar_add(const Scalar& a, const Scalar& b) noexcept;
24
25// CT modular subtraction: r = (a - b) mod n
26Scalar scalar_sub(const Scalar& a, const Scalar& b) noexcept;
27
28// CT modular negation: r = -a mod n
29Scalar scalar_neg(const Scalar& a) noexcept;
30
31// CT modular halving: r = a/2 mod n (if a is odd: (a+n)/2, else a/2)
32Scalar scalar_half(const Scalar& a) noexcept;
33
34// CT modular inverse: r = a^{-1} mod n
35// Uses constant-time SafeGCD (Bernstein-Yang divsteps) on platforms with
36// __int128 (~900 ns, matching FAST SafeGCD speed).
37// Fallback: Fermat a^{n-2} chain (254S + 40M) on platforms without __int128.
38Scalar scalar_inverse(const Scalar& a) noexcept;
39
40// --- CT Conditional Operations -----------------------------------------------
41
42// CT conditional move: if (mask) r = a; else r unchanged
43void scalar_cmov(Scalar* r, const Scalar& a, std::uint64_t mask) noexcept;
44
45// CT conditional swap: when mask is nonzero, swaps a and b
46void scalar_cswap(Scalar* a, Scalar* b, std::uint64_t mask) noexcept;
47
48// CT select: returns a if mask==all-ones, else b
49Scalar scalar_select(const Scalar& a, const Scalar& b,
50 std::uint64_t mask) noexcept;
51
52// CT conditional negate: if (mask) r = -a; else r = a
53Scalar scalar_cneg(const Scalar& a, std::uint64_t mask) noexcept;
54
55// --- CT Comparison -----------------------------------------------------------
56
57// Returns all-ones mask if a == 0, else 0.
58std::uint64_t scalar_is_zero(const Scalar& a) noexcept;
59
60// Returns all-ones mask if a == b, else 0.
61std::uint64_t scalar_eq(const Scalar& a, const Scalar& b) noexcept;
62
63// Returns all-ones mask if a > n/2 ("high-S"), else 0.
64// Used for CT low-S normalization in ECDSA signing.
65std::uint64_t scalar_is_high(const Scalar& a) noexcept;
66
67// --- CT Bit Access -----------------------------------------------------------
68
69// Returns bit at position 'index' (0 = LSB). CT (always same memory access).
70std::uint64_t scalar_bit(const Scalar& a, std::size_t index) noexcept;
71
72// Returns w-bit window at position 'pos' (0 = LSB). CT.
73std::uint64_t scalar_window(const Scalar& a, std::size_t pos,
74 unsigned width) noexcept;
75
76// --- CT ECDSA Low-S Normalize ------------------------------------------------
77
78// CT low-S normalization: if s > n/2 return {r, n-s}, else return {r, s}.
79// Branchless comparison + conditional negate. Required for CT signing paths
80// where the variable-time ECDSASignature::normalize() would leak via branches.
82
83} // namespace secp256k1::ct
84
85#endif // SECP256K1_CT_SCALAR_HPP
void scalar_cswap(Scalar *a, Scalar *b, std::uint64_t mask) noexcept
Scalar scalar_neg(const Scalar &a) noexcept
std::uint64_t scalar_bit(const Scalar &a, std::size_t index) noexcept
std::uint64_t scalar_is_zero(const Scalar &a) noexcept
void scalar_cmov(Scalar *r, const Scalar &a, std::uint64_t mask) noexcept
std::uint64_t scalar_is_high(const Scalar &a) noexcept
Scalar scalar_add(const Scalar &a, const Scalar &b) noexcept
ECDSASignature ct_normalize_low_s(const ECDSASignature &sig) noexcept
std::uint64_t scalar_window(const Scalar &a, std::size_t pos, unsigned width) noexcept
Scalar scalar_inverse(const Scalar &a) noexcept
Scalar scalar_sub(const Scalar &a, const Scalar &b) noexcept
Scalar scalar_select(const Scalar &a, const Scalar &b, std::uint64_t mask) noexcept
Scalar scalar_cneg(const Scalar &a, std::uint64_t mask) noexcept
std::uint64_t scalar_eq(const Scalar &a, const Scalar &b) noexcept
Scalar scalar_half(const Scalar &a) noexcept