summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorjsing <>2025-08-12 09:57:39 +0000
committerjsing <>2025-08-12 09:57:39 +0000
commit6579aa60908701d308df77065093fc34bffc030c (patch)
treeb8c170641e634d7f391dfc7995f5a72ca6b250c1 /src/lib
parent1536ed77315e752d31d4b4cdd51123458a06d815 (diff)
downloadopenbsd-6579aa60908701d308df77065093fc34bffc030c.tar.gz
openbsd-6579aa60908701d308df77065093fc34bffc030c.tar.bz2
openbsd-6579aa60908701d308df77065093fc34bffc030c.zip
Sync headers from s2n-bignum.
This effectively brings in new function prototypes, a chunk of const additions and some new defines.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/bn/s2n_bignum.h791
-rw-r--r--src/lib/libcrypto/bn/s2n_bignum_internal.h33
2 files changed, 588 insertions, 236 deletions
diff --git a/src/lib/libcrypto/bn/s2n_bignum.h b/src/lib/libcrypto/bn/s2n_bignum.h
index ce6e8cdc94..992dcb417f 100644
--- a/src/lib/libcrypto/bn/s2n_bignum.h
+++ b/src/lib/libcrypto/bn/s2n_bignum.h
@@ -34,182 +34,240 @@
34// throughput, generally offering higher performance there. 34// throughput, generally offering higher performance there.
35// ---------------------------------------------------------------------------- 35// ----------------------------------------------------------------------------
36 36
37
38#if defined(_MSC_VER) || !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L || defined(__STDC_NO_VLA__)
39#define S2N_BIGNUM_STATIC
40#else
41#define S2N_BIGNUM_STATIC static
42#endif
43
37// Add, z := x + y 44// Add, z := x + y
38// Inputs x[m], y[n]; outputs function return (carry-out) and z[p] 45// Inputs x[m], y[n]; outputs function return (carry-out) and z[p]
39extern uint64_t bignum_add (uint64_t p, uint64_t *z, uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 46extern uint64_t bignum_add (uint64_t p, uint64_t *z, uint64_t m, const uint64_t *x, uint64_t n, const uint64_t *y);
40 47
41// Add modulo p_25519, z := (x + y) mod p_25519, assuming x and y reduced 48// Add modulo p_25519, z := (x + y) mod p_25519, assuming x and y reduced
42// Inputs x[4], y[4]; output z[4] 49// Inputs x[4], y[4]; output z[4]
43extern void bignum_add_p25519 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 50extern void bignum_add_p25519 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4]);
44 51
45// Add modulo p_256, z := (x + y) mod p_256, assuming x and y reduced 52// Add modulo p_256, z := (x + y) mod p_256, assuming x and y reduced
46// Inputs x[4], y[4]; output z[4] 53// Inputs x[4], y[4]; output z[4]
47extern void bignum_add_p256 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 54extern void bignum_add_p256 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4]);
48 55
49// Add modulo p_256k1, z := (x + y) mod p_256k1, assuming x and y reduced 56// Add modulo p_256k1, z := (x + y) mod p_256k1, assuming x and y reduced
50// Inputs x[4], y[4]; output z[4] 57// Inputs x[4], y[4]; output z[4]
51extern void bignum_add_p256k1 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 58extern void bignum_add_p256k1 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4]);
52 59
53// Add modulo p_384, z := (x + y) mod p_384, assuming x and y reduced 60// Add modulo p_384, z := (x + y) mod p_384, assuming x and y reduced
54// Inputs x[6], y[6]; output z[6] 61// Inputs x[6], y[6]; output z[6]
55extern void bignum_add_p384 (uint64_t z[static 6], uint64_t x[static 6], uint64_t y[static 6]); 62extern void bignum_add_p384 (uint64_t z[S2N_BIGNUM_STATIC 6], const uint64_t x[S2N_BIGNUM_STATIC 6], const uint64_t y[S2N_BIGNUM_STATIC 6]);
56 63
57// Add modulo p_521, z := (x + y) mod p_521, assuming x and y reduced 64// Add modulo p_521, z := (x + y) mod p_521, assuming x and y reduced
58// Inputs x[9], y[9]; output z[9] 65// Inputs x[9], y[9]; output z[9]
59extern void bignum_add_p521 (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); 66extern void bignum_add_p521 (uint64_t z[S2N_BIGNUM_STATIC 9], const uint64_t x[S2N_BIGNUM_STATIC 9], const uint64_t y[S2N_BIGNUM_STATIC 9]);
67
68// Add modulo p_sm2, z := (x + y) mod p_sm2, assuming x and y reduced
69// Inputs x[4], y[4]; output z[4]
70extern void bignum_add_sm2 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4]);
60 71
61// Compute "amontification" constant z :== 2^{128k} (congruent mod m) 72// Compute "amontification" constant z :== 2^{128k} (congruent mod m)
62// Input m[k]; output z[k]; temporary buffer t[>=k] 73// Input m[k]; output z[k]; temporary buffer t[>=k]
63extern void bignum_amontifier (uint64_t k, uint64_t *z, uint64_t *m, uint64_t *t); 74extern void bignum_amontifier (uint64_t k, uint64_t *z, const uint64_t *m, uint64_t *t);
64 75
65// Almost-Montgomery multiply, z :== (x * y / 2^{64k}) (congruent mod m) 76// Almost-Montgomery multiply, z :== (x * y / 2^{64k}) (congruent mod m)
66// Inputs x[k], y[k], m[k]; output z[k] 77// Inputs x[k], y[k], m[k]; output z[k]
67extern void bignum_amontmul (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y, uint64_t *m); 78extern void bignum_amontmul (uint64_t k, uint64_t *z, const uint64_t *x, const uint64_t *y, const uint64_t *m);
68 79
69// Almost-Montgomery reduce, z :== (x' / 2^{64p}) (congruent mod m) 80// Almost-Montgomery reduce, z :== (x' / 2^{64p}) (congruent mod m)
70// Inputs x[n], m[k], p; output z[k] 81// Inputs x[n], m[k], p; output z[k]
71extern void bignum_amontredc (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t *m, uint64_t p); 82extern void bignum_amontredc (uint64_t k, uint64_t *z, uint64_t n, const uint64_t *x, const uint64_t *m, uint64_t p);
72 83
73// Almost-Montgomery square, z :== (x^2 / 2^{64k}) (congruent mod m) 84// Almost-Montgomery square, z :== (x^2 / 2^{64k}) (congruent mod m)
74// Inputs x[k], m[k]; output z[k] 85// Inputs x[k], m[k]; output z[k]
75extern void bignum_amontsqr (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *m); 86extern void bignum_amontsqr (uint64_t k, uint64_t *z, const uint64_t *x, const uint64_t *m);
76 87
77// Convert 4-digit (256-bit) bignum to/from big-endian form 88// Convert 4-digit (256-bit) bignum to/from big-endian form
78// Input x[4]; output z[4] 89// Input x[4]; output z[4]
79extern void bignum_bigendian_4 (uint64_t z[static 4], uint64_t x[static 4]); 90extern void bignum_bigendian_4 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
80 91
81// Convert 6-digit (384-bit) bignum to/from big-endian form 92// Convert 6-digit (384-bit) bignum to/from big-endian form
82// Input x[6]; output z[6] 93// Input x[6]; output z[6]
83extern void bignum_bigendian_6 (uint64_t z[static 6], uint64_t x[static 6]); 94extern void bignum_bigendian_6 (uint64_t z[S2N_BIGNUM_STATIC 6], const uint64_t x[S2N_BIGNUM_STATIC 6]);
84 95
85// Select bitfield starting at bit n with length l <= 64 96// Select bitfield starting at bit n with length l <= 64
86// Inputs x[k], n, l; output function return 97// Inputs x[k], n, l; output function return
87extern uint64_t bignum_bitfield (uint64_t k, uint64_t *x, uint64_t n, uint64_t l); 98extern uint64_t bignum_bitfield (uint64_t k, const uint64_t *x, uint64_t n, uint64_t l);
88 99
89// Return size of bignum in bits 100// Return size of bignum in bits
90// Input x[k]; output function return 101// Input x[k]; output function return
91extern uint64_t bignum_bitsize (uint64_t k, uint64_t *x); 102extern uint64_t bignum_bitsize (uint64_t k, const uint64_t *x);
92 103
93// Divide by a single (nonzero) word, z := x / m and return x mod m 104// Divide by a single (nonzero) word, z := x / m and return x mod m
94// Inputs x[n], m; outputs function return (remainder) and z[k] 105// Inputs x[n], m; outputs function return (remainder) and z[k]
95extern uint64_t bignum_cdiv (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t m); 106extern uint64_t bignum_cdiv (uint64_t k, uint64_t *z, uint64_t n, const uint64_t *x, uint64_t m);
96 107
97// Divide by a single word, z := x / m when known to be exact 108// Divide by a single word, z := x / m when known to be exact
98// Inputs x[n], m; output z[k] 109// Inputs x[n], m; output z[k]
99extern void bignum_cdiv_exact (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t m); 110extern void bignum_cdiv_exact (uint64_t k, uint64_t *z, uint64_t n, const uint64_t *x, uint64_t m);
100 111
101// Count leading zero digits (64-bit words) 112// Count leading zero digits (64-bit words)
102// Input x[k]; output function return 113// Input x[k]; output function return
103extern uint64_t bignum_cld (uint64_t k, uint64_t *x); 114extern uint64_t bignum_cld (uint64_t k, const uint64_t *x);
104 115
105// Count leading zero bits 116// Count leading zero bits
106// Input x[k]; output function return 117// Input x[k]; output function return
107extern uint64_t bignum_clz (uint64_t k, uint64_t *x); 118extern uint64_t bignum_clz (uint64_t k, const uint64_t *x);
108 119
109// Multiply-add with single-word multiplier, z := z + c * y 120// Multiply-add with single-word multiplier, z := z + c * y
110// Inputs c, y[n]; outputs function return (carry-out) and z[k] 121// Inputs c, y[n]; outputs function return (carry-out) and z[k]
111extern uint64_t bignum_cmadd (uint64_t k, uint64_t *z, uint64_t c, uint64_t n, uint64_t *y); 122extern uint64_t bignum_cmadd (uint64_t k, uint64_t *z, uint64_t c, uint64_t n, const uint64_t *y);
112 123
113// Negated multiply-add with single-word multiplier, z := z - c * y 124// Negated multiply-add with single-word multiplier, z := z - c * y
114// Inputs c, y[n]; outputs function return (negative carry-out) and z[k] 125// Inputs c, y[n]; outputs function return (negative carry-out) and z[k]
115extern uint64_t bignum_cmnegadd (uint64_t k, uint64_t *z, uint64_t c, uint64_t n, uint64_t *y); 126extern uint64_t bignum_cmnegadd (uint64_t k, uint64_t *z, uint64_t c, uint64_t n, const uint64_t *y);
116 127
117// Find modulus of bignum w.r.t. single nonzero word m, returning x mod m 128// Find modulus of bignum w.r.t. single nonzero word m, returning x mod m
118// Input x[k], m; output function return 129// Input x[k], m; output function return
119extern uint64_t bignum_cmod (uint64_t k, uint64_t *x, uint64_t m); 130extern uint64_t bignum_cmod (uint64_t k, const uint64_t *x, uint64_t m);
120 131
121// Multiply by a single word, z := c * y 132// Multiply by a single word, z := c * y
122// Inputs c, y[n]; outputs function return (carry-out) and z[k] 133// Inputs c, y[n]; outputs function return (carry-out) and z[k]
123extern uint64_t bignum_cmul (uint64_t k, uint64_t *z, uint64_t c, uint64_t n, uint64_t *y); 134extern uint64_t bignum_cmul (uint64_t k, uint64_t *z, uint64_t c, uint64_t n, const uint64_t *y);
124 135
125// Multiply by a single word modulo p_25519, z := (c * x) mod p_25519, assuming x reduced 136// Multiply by a single word modulo p_25519, z := (c * x) mod p_25519, assuming x reduced
126// Inputs c, x[4]; output z[4] 137// Inputs c, x[4]; output z[4]
127extern void bignum_cmul_p25519 (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); 138extern void bignum_cmul_p25519 (uint64_t z[S2N_BIGNUM_STATIC 4], uint64_t c, const uint64_t x[S2N_BIGNUM_STATIC 4]);
128extern void bignum_cmul_p25519_alt (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); 139extern void bignum_cmul_p25519_alt (uint64_t z[S2N_BIGNUM_STATIC 4], uint64_t c, const uint64_t x[S2N_BIGNUM_STATIC 4]);
129 140
130// Multiply by a single word modulo p_256, z := (c * x) mod p_256, assuming x reduced 141// Multiply by a single word modulo p_256, z := (c * x) mod p_256, assuming x reduced
131// Inputs c, x[4]; output z[4] 142// Inputs c, x[4]; output z[4]
132extern void bignum_cmul_p256 (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); 143extern void bignum_cmul_p256 (uint64_t z[S2N_BIGNUM_STATIC 4], uint64_t c, const uint64_t x[S2N_BIGNUM_STATIC 4]);
133extern void bignum_cmul_p256_alt (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); 144extern void bignum_cmul_p256_alt (uint64_t z[S2N_BIGNUM_STATIC 4], uint64_t c, const uint64_t x[S2N_BIGNUM_STATIC 4]);
134 145
135// Multiply by a single word modulo p_256k1, z := (c * x) mod p_256k1, assuming x reduced 146// Multiply by a single word modulo p_256k1, z := (c * x) mod p_256k1, assuming x reduced
136// Inputs c, x[4]; output z[4] 147// Inputs c, x[4]; output z[4]
137extern void bignum_cmul_p256k1 (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); 148extern void bignum_cmul_p256k1 (uint64_t z[S2N_BIGNUM_STATIC 4], uint64_t c, const uint64_t x[S2N_BIGNUM_STATIC 4]);
138extern void bignum_cmul_p256k1_alt (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); 149extern void bignum_cmul_p256k1_alt (uint64_t z[S2N_BIGNUM_STATIC 4], uint64_t c, const uint64_t x[S2N_BIGNUM_STATIC 4]);
139 150
140// Multiply by a single word modulo p_384, z := (c * x) mod p_384, assuming x reduced 151// Multiply by a single word modulo p_384, z := (c * x) mod p_384, assuming x reduced
141// Inputs c, x[6]; output z[6] 152// Inputs c, x[6]; output z[6]
142extern void bignum_cmul_p384 (uint64_t z[static 6], uint64_t c, uint64_t x[static 6]); 153extern void bignum_cmul_p384 (uint64_t z[S2N_BIGNUM_STATIC 6], uint64_t c, const uint64_t x[S2N_BIGNUM_STATIC 6]);
143extern void bignum_cmul_p384_alt (uint64_t z[static 6], uint64_t c, uint64_t x[static 6]); 154extern void bignum_cmul_p384_alt (uint64_t z[S2N_BIGNUM_STATIC 6], uint64_t c, const uint64_t x[S2N_BIGNUM_STATIC 6]);
144 155
145// Multiply by a single word modulo p_521, z := (c * x) mod p_521, assuming x reduced 156// Multiply by a single word modulo p_521, z := (c * x) mod p_521, assuming x reduced
146// Inputs c, x[9]; output z[9] 157// Inputs c, x[9]; output z[9]
147extern void bignum_cmul_p521 (uint64_t z[static 9], uint64_t c, uint64_t x[static 9]); 158extern void bignum_cmul_p521 (uint64_t z[S2N_BIGNUM_STATIC 9], uint64_t c, const uint64_t x[S2N_BIGNUM_STATIC 9]);
148extern void bignum_cmul_p521_alt (uint64_t z[static 9], uint64_t c, uint64_t x[static 9]); 159extern void bignum_cmul_p521_alt (uint64_t z[S2N_BIGNUM_STATIC 9], uint64_t c, const uint64_t x[S2N_BIGNUM_STATIC 9]);
160
161// Multiply by a single word modulo p_sm2, z := (c * x) mod p_sm2, assuming x reduced
162// Inputs c, x[4]; output z[4]
163extern void bignum_cmul_sm2 (uint64_t z[S2N_BIGNUM_STATIC 4], uint64_t c, const uint64_t x[S2N_BIGNUM_STATIC 4]);
164extern void bignum_cmul_sm2_alt (uint64_t z[S2N_BIGNUM_STATIC 4], uint64_t c, const uint64_t x[S2N_BIGNUM_STATIC 4]);
149 165
150// Test bignums for coprimality, gcd(x,y) = 1 166// Test bignums for coprimality, gcd(x,y) = 1
151// Inputs x[m], y[n]; output function return; temporary buffer t[>=2*max(m,n)] 167// Inputs x[m], y[n]; output function return; temporary buffer t[>=2*max(m,n)]
152extern uint64_t bignum_coprime (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y, uint64_t *t); 168extern uint64_t bignum_coprime (uint64_t m, const uint64_t *x, uint64_t n, const uint64_t *y, uint64_t *t);
153 169
154// Copy bignum with zero-extension or truncation, z := x 170// Copy bignum with zero-extension or truncation, z := x
155// Input x[n]; output z[k] 171// Input x[n]; output z[k]
156extern void bignum_copy (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x); 172extern void bignum_copy (uint64_t k, uint64_t *z, uint64_t n, const uint64_t *x);
173
174// Given table: uint64_t[height*width], copy table[idx*width...(idx+1)*width-1]
175// into z[0..width-1].
176// This function is constant-time with respect to the value of `idx`. This is
177// achieved by reading the whole table and using the bit-masking to get the
178// `idx`-th row.
179// Input table[height*width]; output z[width]
180extern void bignum_copy_row_from_table (uint64_t *z, const uint64_t *table, uint64_t height,
181 uint64_t width, uint64_t idx);
182
183// Given table: uint64_t[height*width], copy table[idx*width...(idx+1)*width-1]
184// into z[0..width-1]. width must be a multiple of 8.
185// This function is constant-time with respect to the value of `idx`. This is
186// achieved by reading the whole table and using the bit-masking to get the
187// `idx`-th row.
188// Input table[height*width]; output z[width]
189extern void bignum_copy_row_from_table_8n (uint64_t *z, const uint64_t *table,
190 uint64_t height, uint64_t width, uint64_t idx);
191
192// Given table: uint64_t[height*16], copy table[idx*16...(idx+1)*16-1] into z[0..row-1].
193// This function is constant-time with respect to the value of `idx`. This is
194// achieved by reading the whole table and using the bit-masking to get the
195// `idx`-th row.
196// Input table[height*16]; output z[16]
197extern void bignum_copy_row_from_table_16 (uint64_t *z, const uint64_t *table,
198 uint64_t height, uint64_t idx);
199
200// Given table: uint64_t[height*32], copy table[idx*32...(idx+1)*32-1] into z[0..row-1].
201// This function is constant-time with respect to the value of `idx`. This is
202// achieved by reading the whole table and using the bit-masking to get the
203// `idx`-th row.
204// Input table[height*32]; output z[32]
205extern void bignum_copy_row_from_table_32 (uint64_t *z, const uint64_t *table,
206 uint64_t height, uint64_t idx);
157 207
158// Count trailing zero digits (64-bit words) 208// Count trailing zero digits (64-bit words)
159// Input x[k]; output function return 209// Input x[k]; output function return
160extern uint64_t bignum_ctd (uint64_t k, uint64_t *x); 210extern uint64_t bignum_ctd (uint64_t k, const uint64_t *x);
161 211
162// Count trailing zero bits 212// Count trailing zero bits
163// Input x[k]; output function return 213// Input x[k]; output function return
164extern uint64_t bignum_ctz (uint64_t k, uint64_t *x); 214extern uint64_t bignum_ctz (uint64_t k, const uint64_t *x);
165 215
166// Convert from almost-Montgomery form, z := (x / 2^256) mod p_256 216// Convert from almost-Montgomery form, z := (x / 2^256) mod p_256
167// Input x[4]; output z[4] 217// Input x[4]; output z[4]
168extern void bignum_deamont_p256 (uint64_t z[static 4], uint64_t x[static 4]); 218extern void bignum_deamont_p256 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
169extern void bignum_deamont_p256_alt (uint64_t z[static 4], uint64_t x[static 4]); 219extern void bignum_deamont_p256_alt (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
170 220
171// Convert from almost-Montgomery form, z := (x / 2^256) mod p_256k1 221// Convert from almost-Montgomery form, z := (x / 2^256) mod p_256k1
172// Input x[4]; output z[4] 222// Input x[4]; output z[4]
173extern void bignum_deamont_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 223extern void bignum_deamont_p256k1 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
174 224
175// Convert from almost-Montgomery form, z := (x / 2^384) mod p_384 225// Convert from almost-Montgomery form, z := (x / 2^384) mod p_384
176// Input x[6]; output z[6] 226// Input x[6]; output z[6]
177extern void bignum_deamont_p384 (uint64_t z[static 6], uint64_t x[static 6]); 227extern void bignum_deamont_p384 (uint64_t z[S2N_BIGNUM_STATIC 6], const uint64_t x[S2N_BIGNUM_STATIC 6]);
178extern void bignum_deamont_p384_alt (uint64_t z[static 6], uint64_t x[static 6]); 228extern void bignum_deamont_p384_alt (uint64_t z[S2N_BIGNUM_STATIC 6], const uint64_t x[S2N_BIGNUM_STATIC 6]);
179 229
180// Convert from almost-Montgomery form z := (x / 2^576) mod p_521 230// Convert from almost-Montgomery form z := (x / 2^576) mod p_521
181// Input x[9]; output z[9] 231// Input x[9]; output z[9]
182extern void bignum_deamont_p521 (uint64_t z[static 9], uint64_t x[static 9]); 232extern void bignum_deamont_p521 (uint64_t z[S2N_BIGNUM_STATIC 9], const uint64_t x[S2N_BIGNUM_STATIC 9]);
233
234// Convert from almost-Montgomery form z := (x / 2^256) mod p_sm2
235// Input x[4]; output z[4]
236extern void bignum_deamont_sm2 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
183 237
184// Convert from (almost-)Montgomery form z := (x / 2^{64k}) mod m 238// Convert from (almost-)Montgomery form z := (x / 2^{64k}) mod m
185// Inputs x[k], m[k]; output z[k] 239// Inputs x[k], m[k]; output z[k]
186extern void bignum_demont (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *m); 240extern void bignum_demont (uint64_t k, uint64_t *z, const uint64_t *x, const uint64_t *m);
187 241
188// Convert from Montgomery form z := (x / 2^256) mod p_256, assuming x reduced 242// Convert from Montgomery form z := (x / 2^256) mod p_256, assuming x reduced
189// Input x[4]; output z[4] 243// Input x[4]; output z[4]
190extern void bignum_demont_p256 (uint64_t z[static 4], uint64_t x[static 4]); 244extern void bignum_demont_p256 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
191extern void bignum_demont_p256_alt (uint64_t z[static 4], uint64_t x[static 4]); 245extern void bignum_demont_p256_alt (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
192 246
193// Convert from Montgomery form z := (x / 2^256) mod p_256k1, assuming x reduced 247// Convert from Montgomery form z := (x / 2^256) mod p_256k1, assuming x reduced
194// Input x[4]; output z[4] 248// Input x[4]; output z[4]
195extern void bignum_demont_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 249extern void bignum_demont_p256k1 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
196 250
197// Convert from Montgomery form z := (x / 2^384) mod p_384, assuming x reduced 251// Convert from Montgomery form z := (x / 2^384) mod p_384, assuming x reduced
198// Input x[6]; output z[6] 252// Input x[6]; output z[6]
199extern void bignum_demont_p384 (uint64_t z[static 6], uint64_t x[static 6]); 253extern void bignum_demont_p384 (uint64_t z[S2N_BIGNUM_STATIC 6], const uint64_t x[S2N_BIGNUM_STATIC 6]);
200extern void bignum_demont_p384_alt (uint64_t z[static 6], uint64_t x[static 6]); 254extern void bignum_demont_p384_alt (uint64_t z[S2N_BIGNUM_STATIC 6], const uint64_t x[S2N_BIGNUM_STATIC 6]);
201 255
202// Convert from Montgomery form z := (x / 2^576) mod p_521, assuming x reduced 256// Convert from Montgomery form z := (x / 2^576) mod p_521, assuming x reduced
203// Input x[9]; output z[9] 257// Input x[9]; output z[9]
204extern void bignum_demont_p521 (uint64_t z[static 9], uint64_t x[static 9]); 258extern void bignum_demont_p521 (uint64_t z[S2N_BIGNUM_STATIC 9], const uint64_t x[S2N_BIGNUM_STATIC 9]);
259
260// Convert from Montgomery form z := (x / 2^256) mod p_sm2, assuming x reduced
261// Input x[4]; output z[4]
262extern void bignum_demont_sm2 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
205 263
206// Select digit x[n] 264// Select digit x[n]
207// Inputs x[k], n; output function return 265// Inputs x[k], n; output function return
208extern uint64_t bignum_digit (uint64_t k, uint64_t *x, uint64_t n); 266extern uint64_t bignum_digit (uint64_t k, const uint64_t *x, uint64_t n);
209 267
210// Return size of bignum in digits (64-bit word) 268// Return size of bignum in digits (64-bit word)
211// Input x[k]; output function return 269// Input x[k]; output function return
212extern uint64_t bignum_digitsize (uint64_t k, uint64_t *x); 270extern uint64_t bignum_digitsize (uint64_t k, const uint64_t *x);
213 271
214// Divide bignum by 10: z' := z div 10, returning remainder z mod 10 272// Divide bignum by 10: z' := z div 10, returning remainder z mod 10
215// Inputs z[k]; outputs function return (remainder) and z[k] 273// Inputs z[k]; outputs function return (remainder) and z[k]
@@ -217,294 +275,391 @@ extern uint64_t bignum_divmod10 (uint64_t k, uint64_t *z);
217 275
218// Double modulo p_25519, z := (2 * x) mod p_25519, assuming x reduced 276// Double modulo p_25519, z := (2 * x) mod p_25519, assuming x reduced
219// Input x[4]; output z[4] 277// Input x[4]; output z[4]
220extern void bignum_double_p25519 (uint64_t z[static 4], uint64_t x[static 4]); 278extern void bignum_double_p25519 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
221 279
222// Double modulo p_256, z := (2 * x) mod p_256, assuming x reduced 280// Double modulo p_256, z := (2 * x) mod p_256, assuming x reduced
223// Input x[4]; output z[4] 281// Input x[4]; output z[4]
224extern void bignum_double_p256 (uint64_t z[static 4], uint64_t x[static 4]); 282extern void bignum_double_p256 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
225 283
226// Double modulo p_256k1, z := (2 * x) mod p_256k1, assuming x reduced 284// Double modulo p_256k1, z := (2 * x) mod p_256k1, assuming x reduced
227// Input x[4]; output z[4] 285// Input x[4]; output z[4]
228extern void bignum_double_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 286extern void bignum_double_p256k1 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
229 287
230// Double modulo p_384, z := (2 * x) mod p_384, assuming x reduced 288// Double modulo p_384, z := (2 * x) mod p_384, assuming x reduced
231// Input x[6]; output z[6] 289// Input x[6]; output z[6]
232extern void bignum_double_p384 (uint64_t z[static 6], uint64_t x[static 6]); 290extern void bignum_double_p384 (uint64_t z[S2N_BIGNUM_STATIC 6], const uint64_t x[S2N_BIGNUM_STATIC 6]);
233 291
234// Double modulo p_521, z := (2 * x) mod p_521, assuming x reduced 292// Double modulo p_521, z := (2 * x) mod p_521, assuming x reduced
235// Input x[9]; output z[9] 293// Input x[9]; output z[9]
236extern void bignum_double_p521 (uint64_t z[static 9], uint64_t x[static 9]); 294extern void bignum_double_p521 (uint64_t z[S2N_BIGNUM_STATIC 9], const uint64_t x[S2N_BIGNUM_STATIC 9]);
295
296// Double modulo p_sm2, z := (2 * x) mod p_sm2, assuming x reduced
297// Input x[4]; output z[4]
298extern void bignum_double_sm2 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
237 299
238// Extended Montgomery reduce, returning results in input-output buffer 300// Extended Montgomery reduce, returning results in input-output buffer
239// Inputs z[2*k], m[k], w; outputs function return (extra result bit) and z[2*k] 301// Inputs z[2*k], m[k], w; outputs function return (extra result bit) and z[2*k]
240extern uint64_t bignum_emontredc (uint64_t k, uint64_t *z, uint64_t *m, uint64_t w); 302extern uint64_t bignum_emontredc (uint64_t k, uint64_t *z, const uint64_t *m, uint64_t w);
241 303
242// Extended Montgomery reduce in 8-digit blocks, results in input-output buffer 304// Extended Montgomery reduce in 8-digit blocks, results in input-output buffer
243// Inputs z[2*k], m[k], w; outputs function return (extra result bit) and z[2*k] 305// Inputs z[2*k], m[k], w; outputs function return (extra result bit) and z[2*k]
244extern uint64_t bignum_emontredc_8n (uint64_t k, uint64_t *z, uint64_t *m, uint64_t w); 306extern uint64_t bignum_emontredc_8n (uint64_t k, uint64_t *z, const uint64_t *m, uint64_t w);
307// Inputs z[2*k], m[k], w; outputs function return (extra result bit) and z[2*k]
308// Temporary buffer m_precalc[12*(k/4-1)]
309extern uint64_t bignum_emontredc_8n_cdiff (uint64_t k, uint64_t *z, const uint64_t *m,
310 uint64_t w, uint64_t *m_precalc);
245 311
246// Test bignums for equality, x = y 312// Test bignums for equality, x = y
247// Inputs x[m], y[n]; output function return 313// Inputs x[m], y[n]; output function return
248extern uint64_t bignum_eq (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 314extern uint64_t bignum_eq (uint64_t m, const uint64_t *x, uint64_t n, const uint64_t *y);
249 315
250// Test bignum for even-ness 316// Test bignum for even-ness
251// Input x[k]; output function return 317// Input x[k]; output function return
252extern uint64_t bignum_even (uint64_t k, uint64_t *x); 318extern uint64_t bignum_even (uint64_t k, const uint64_t *x);
253 319
254// Convert 4-digit (256-bit) bignum from big-endian bytes 320// Convert 4-digit (256-bit) bignum from big-endian bytes
255// Input x[32] (bytes); output z[4] 321// Input x[32] (bytes); output z[4]
256extern void bignum_frombebytes_4 (uint64_t z[static 4], uint8_t x[static 32]); 322extern void bignum_frombebytes_4 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint8_t x[S2N_BIGNUM_STATIC 32]);
257 323
258// Convert 6-digit (384-bit) bignum from big-endian bytes 324// Convert 6-digit (384-bit) bignum from big-endian bytes
259// Input x[48] (bytes); output z[6] 325// Input x[48] (bytes); output z[6]
260extern void bignum_frombebytes_6 (uint64_t z[static 6], uint8_t x[static 48]); 326extern void bignum_frombebytes_6 (uint64_t z[S2N_BIGNUM_STATIC 6], const uint8_t x[S2N_BIGNUM_STATIC 48]);
261 327
262// Convert 4-digit (256-bit) bignum from little-endian bytes 328// Convert 4-digit (256-bit) bignum from little-endian bytes
263// Input x[32] (bytes); output z[4] 329// Input x[32] (bytes); output z[4]
264extern void bignum_fromlebytes_4 (uint64_t z[static 4], uint8_t x[static 32]); 330extern void bignum_fromlebytes_4 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint8_t x[S2N_BIGNUM_STATIC 32]);
265 331
266// Convert 6-digit (384-bit) bignum from little-endian bytes 332// Convert 6-digit (384-bit) bignum from little-endian bytes
267// Input x[48] (bytes); output z[6] 333// Input x[48] (bytes); output z[6]
268extern void bignum_fromlebytes_6 (uint64_t z[static 6], uint8_t x[static 48]); 334extern void bignum_fromlebytes_6 (uint64_t z[S2N_BIGNUM_STATIC 6], const uint8_t x[S2N_BIGNUM_STATIC 48]);
269 335
270// Convert little-endian bytes to 9-digit 528-bit bignum 336// Convert little-endian bytes to 9-digit 528-bit bignum
271// Input x[66] (bytes); output z[9] 337// Input x[66] (bytes); output z[9]
272extern void bignum_fromlebytes_p521 (uint64_t z[static 9],uint8_t x[static 66]); 338extern void bignum_fromlebytes_p521 (uint64_t z[S2N_BIGNUM_STATIC 9],const uint8_t x[S2N_BIGNUM_STATIC 66]);
273 339
274// Compare bignums, x >= y 340// Compare bignums, x >= y
275// Inputs x[m], y[n]; output function return 341// Inputs x[m], y[n]; output function return
276extern uint64_t bignum_ge (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 342extern uint64_t bignum_ge (uint64_t m, const uint64_t *x, uint64_t n, const uint64_t *y);
277 343
278// Compare bignums, x > y 344// Compare bignums, x > y
279// Inputs x[m], y[n]; output function return 345// Inputs x[m], y[n]; output function return
280extern uint64_t bignum_gt (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 346extern uint64_t bignum_gt (uint64_t m, const uint64_t *x, uint64_t n, const uint64_t *y);
281 347
282// Halve modulo p_256, z := (x / 2) mod p_256, assuming x reduced 348// Halve modulo p_256, z := (x / 2) mod p_256, assuming x reduced
283// Input x[4]; output z[4] 349// Input x[4]; output z[4]
284extern void bignum_half_p256 (uint64_t z[static 4], uint64_t x[static 4]); 350extern void bignum_half_p256 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
285 351
286// Halve modulo p_256k1, z := (x / 2) mod p_256k1, assuming x reduced 352// Halve modulo p_256k1, z := (x / 2) mod p_256k1, assuming x reduced
287// Input x[4]; output z[4] 353// Input x[4]; output z[4]
288extern void bignum_half_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 354extern void bignum_half_p256k1 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
289 355
290// Halve modulo p_384, z := (x / 2) mod p_384, assuming x reduced 356// Halve modulo p_384, z := (x / 2) mod p_384, assuming x reduced
291// Input x[6]; output z[6] 357// Input x[6]; output z[6]
292extern void bignum_half_p384 (uint64_t z[static 6], uint64_t x[static 6]); 358extern void bignum_half_p384 (uint64_t z[S2N_BIGNUM_STATIC 6], const uint64_t x[S2N_BIGNUM_STATIC 6]);
293 359
294// Halve modulo p_521, z := (x / 2) mod p_521, assuming x reduced 360// Halve modulo p_521, z := (x / 2) mod p_521, assuming x reduced
295// Input x[9]; output z[9] 361// Input x[9]; output z[9]
296extern void bignum_half_p521 (uint64_t z[static 9], uint64_t x[static 9]); 362extern void bignum_half_p521 (uint64_t z[S2N_BIGNUM_STATIC 9], const uint64_t x[S2N_BIGNUM_STATIC 9]);
363
364// Halve modulo p_sm2, z := (x / 2) mod p_sm2, assuming x reduced
365// Input x[4]; output z[4]
366extern void bignum_half_sm2 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
367
368// Modular inverse modulo p_25519 = 2^255 - 19
369// Input x[4]; output z[4]
370extern void bignum_inv_p25519(uint64_t z[S2N_BIGNUM_STATIC 4],const uint64_t x[S2N_BIGNUM_STATIC 4]);
371
372// Modular inverse modulo p_256 = 2^256 - 2^224 + 2^192 + 2^96 - 1
373// Input x[4]; output z[4]
374extern void bignum_inv_p256(uint64_t z[S2N_BIGNUM_STATIC 4],const uint64_t x[S2N_BIGNUM_STATIC 4]);
375
376// Modular inverse modulo p_384 = 2^384 - 2^128 - 2^96 + 2^32 - 1
377// Input x[6]; output z[6]
378extern void bignum_inv_p384(uint64_t z[S2N_BIGNUM_STATIC 6],const uint64_t x[S2N_BIGNUM_STATIC 6]);
379
380// Modular inverse modulo p_521 = 2^521 - 1
381// Input x[9]; output z[9]
382extern void bignum_inv_p521(uint64_t z[S2N_BIGNUM_STATIC 9],const uint64_t x[S2N_BIGNUM_STATIC 9]);
383
384// Modular inverse modulo p_sm2 = 2^256 - 2^224 - 2^96 + 2^64 - 1
385// Input x[4]; output z[4]
386extern void bignum_inv_sm2(uint64_t z[S2N_BIGNUM_STATIC 4],const uint64_t x[S2N_BIGNUM_STATIC 4]);
387
388// Inverse square root modulo p_25519
389// Input x[4]; output function return (Legendre symbol) and z[4]
390extern int64_t bignum_invsqrt_p25519(uint64_t z[S2N_BIGNUM_STATIC 4],const uint64_t x[S2N_BIGNUM_STATIC 4]);
391extern int64_t bignum_invsqrt_p25519_alt(uint64_t z[S2N_BIGNUM_STATIC 4],const uint64_t x[S2N_BIGNUM_STATIC 4]);
297 392
298// Test bignum for zero-ness, x = 0 393// Test bignum for zero-ness, x = 0
299// Input x[k]; output function return 394// Input x[k]; output function return
300extern uint64_t bignum_iszero (uint64_t k, uint64_t *x); 395extern uint64_t bignum_iszero (uint64_t k, const uint64_t *x);
301 396
302// Multiply z := x * y 397// Multiply z := x * y
303// Inputs x[16], y[16]; output z[32]; temporary buffer t[>=32] 398// Inputs x[16], y[16]; output z[32]; temporary buffer t[>=32]
304extern void bignum_kmul_16_32 (uint64_t z[static 32], uint64_t x[static 16], uint64_t y[static 16], uint64_t t[static 32]); 399extern void bignum_kmul_16_32 (uint64_t z[S2N_BIGNUM_STATIC 32], const uint64_t x[S2N_BIGNUM_STATIC 16], const uint64_t y[S2N_BIGNUM_STATIC 16], uint64_t t[S2N_BIGNUM_STATIC 32]);
305 400
306// Multiply z := x * y 401// Multiply z := x * y
307// Inputs x[32], y[32]; output z[64]; temporary buffer t[>=96] 402// Inputs x[32], y[32]; output z[64]; temporary buffer t[>=96]
308extern void bignum_kmul_32_64 (uint64_t z[static 64], uint64_t x[static 32], uint64_t y[static 32], uint64_t t[static 96]); 403extern void bignum_kmul_32_64 (uint64_t z[S2N_BIGNUM_STATIC 64], const uint64_t x[S2N_BIGNUM_STATIC 32], const uint64_t y[S2N_BIGNUM_STATIC 32], uint64_t t[S2N_BIGNUM_STATIC 96]);
309 404
310// Square, z := x^2 405// Square, z := x^2
311// Input x[16]; output z[32]; temporary buffer t[>=24] 406// Input x[16]; output z[32]; temporary buffer t[>=24]
312extern void bignum_ksqr_16_32 (uint64_t z[static 32], uint64_t x[static 16], uint64_t t[static 24]); 407extern void bignum_ksqr_16_32 (uint64_t z[S2N_BIGNUM_STATIC 32], const uint64_t x[S2N_BIGNUM_STATIC 16], uint64_t t[S2N_BIGNUM_STATIC 24]);
313 408
314// Square, z := x^2 409// Square, z := x^2
315// Input x[32]; output z[64]; temporary buffer t[>=72] 410// Input x[32]; output z[64]; temporary buffer t[>=72]
316extern void bignum_ksqr_32_64 (uint64_t z[static 64], uint64_t x[static 32], uint64_t t[static 72]); 411extern void bignum_ksqr_32_64 (uint64_t z[S2N_BIGNUM_STATIC 64], const uint64_t x[S2N_BIGNUM_STATIC 32], uint64_t t[S2N_BIGNUM_STATIC 72]);
317 412
318// Compare bignums, x <= y 413// Compare bignums, x <= y
319// Inputs x[m], y[n]; output function return 414// Inputs x[m], y[n]; output function return
320extern uint64_t bignum_le (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 415extern uint64_t bignum_le (uint64_t m, const uint64_t *x, uint64_t n, const uint64_t *y);
321 416
322// Convert 4-digit (256-bit) bignum to/from little-endian form 417// Convert 4-digit (256-bit) bignum to/from little-endian form
323// Input x[4]; output z[4] 418// Input x[4]; output z[4]
324extern void bignum_littleendian_4 (uint64_t z[static 4], uint64_t x[static 4]); 419extern void bignum_littleendian_4 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
325 420
326// Convert 6-digit (384-bit) bignum to/from little-endian form 421// Convert 6-digit (384-bit) bignum to/from little-endian form
327// Input x[6]; output z[6] 422// Input x[6]; output z[6]
328extern void bignum_littleendian_6 (uint64_t z[static 6], uint64_t x[static 6]); 423extern void bignum_littleendian_6 (uint64_t z[S2N_BIGNUM_STATIC 6], const uint64_t x[S2N_BIGNUM_STATIC 6]);
329 424
330// Compare bignums, x < y 425// Compare bignums, x < y
331// Inputs x[m], y[n]; output function return 426// Inputs x[m], y[n]; output function return
332extern uint64_t bignum_lt (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 427extern uint64_t bignum_lt (uint64_t m, const uint64_t *x, uint64_t n, const uint64_t *y);
333 428
334// Multiply-add, z := z + x * y 429// Multiply-add, z := z + x * y
335// Inputs x[m], y[n]; outputs function return (carry-out) and z[k] 430// Inputs x[m], y[n]; outputs function return (carry-out) and z[k]
336extern uint64_t bignum_madd (uint64_t k, uint64_t *z, uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 431extern uint64_t bignum_madd (uint64_t k, uint64_t *z, uint64_t m, const uint64_t *x, uint64_t n, const uint64_t *y);
432
433// Multiply-add modulo the order of the curve25519/edwards25519 basepoint
434// Inputs x[4], y[4], c[4]; output z[4]
435extern void bignum_madd_n25519 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4], const uint64_t c[S2N_BIGNUM_STATIC 4]);
436extern void bignum_madd_n25519_alt (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4], const uint64_t c[S2N_BIGNUM_STATIC 4]);
437
438// Reduce modulo group order, z := x mod m_25519
439// Input x[4]; output z[4]
440extern void bignum_mod_m25519_4 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
441
442// Reduce modulo basepoint order, z := x mod n_25519
443// Input x[k]; output z[4]
444extern void bignum_mod_n25519 (uint64_t z[S2N_BIGNUM_STATIC 4], uint64_t k, const uint64_t *x);
445
446// Reduce modulo basepoint order, z := x mod n_25519
447// Input x[4]; output z[4]
448extern void bignum_mod_n25519_4 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
337 449
338// Reduce modulo group order, z := x mod n_256 450// Reduce modulo group order, z := x mod n_256
339// Input x[k]; output z[4] 451// Input x[k]; output z[4]
340extern void bignum_mod_n256 (uint64_t z[static 4], uint64_t k, uint64_t *x); 452extern void bignum_mod_n256 (uint64_t z[S2N_BIGNUM_STATIC 4], uint64_t k, const uint64_t *x);
341extern void bignum_mod_n256_alt (uint64_t z[static 4], uint64_t k, uint64_t *x); 453extern void bignum_mod_n256_alt (uint64_t z[S2N_BIGNUM_STATIC 4], uint64_t k, const uint64_t *x);
342 454
343// Reduce modulo group order, z := x mod n_256 455// Reduce modulo group order, z := x mod n_256
344// Input x[4]; output z[4] 456// Input x[4]; output z[4]
345extern void bignum_mod_n256_4 (uint64_t z[static 4], uint64_t x[static 4]); 457extern void bignum_mod_n256_4 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
346 458
347// Reduce modulo group order, z := x mod n_256k1 459// Reduce modulo group order, z := x mod n_256k1
348// Input x[4]; output z[4] 460// Input x[4]; output z[4]
349extern void bignum_mod_n256k1_4 (uint64_t z[static 4], uint64_t x[static 4]); 461extern void bignum_mod_n256k1_4 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
350 462
351// Reduce modulo group order, z := x mod n_384 463// Reduce modulo group order, z := x mod n_384
352// Input x[k]; output z[6] 464// Input x[k]; output z[6]
353extern void bignum_mod_n384 (uint64_t z[static 6], uint64_t k, uint64_t *x); 465extern void bignum_mod_n384 (uint64_t z[S2N_BIGNUM_STATIC 6], uint64_t k, const uint64_t *x);
354extern void bignum_mod_n384_alt (uint64_t z[static 6], uint64_t k, uint64_t *x); 466extern void bignum_mod_n384_alt (uint64_t z[S2N_BIGNUM_STATIC 6], uint64_t k, const uint64_t *x);
355 467
356// Reduce modulo group order, z := x mod n_384 468// Reduce modulo group order, z := x mod n_384
357// Input x[6]; output z[6] 469// Input x[6]; output z[6]
358extern void bignum_mod_n384_6 (uint64_t z[static 6], uint64_t x[static 6]); 470extern void bignum_mod_n384_6 (uint64_t z[S2N_BIGNUM_STATIC 6], const uint64_t x[S2N_BIGNUM_STATIC 6]);
359 471
360// Reduce modulo group order, z := x mod n_521 472// Reduce modulo group order, z := x mod n_521
361// Input x[9]; output z[9] 473// Input x[9]; output z[9]
362extern void bignum_mod_n521_9 (uint64_t z[static 9], uint64_t x[static 9]); 474extern void bignum_mod_n521_9 (uint64_t z[S2N_BIGNUM_STATIC 9], const uint64_t x[S2N_BIGNUM_STATIC 9]);
363extern void bignum_mod_n521_9_alt (uint64_t z[static 9], uint64_t x[static 9]); 475extern void bignum_mod_n521_9_alt (uint64_t z[S2N_BIGNUM_STATIC 9], const uint64_t x[S2N_BIGNUM_STATIC 9]);
476
477// Reduce modulo group order, z := x mod n_sm2
478// Input x[k]; output z[4]
479extern void bignum_mod_nsm2 (uint64_t z[S2N_BIGNUM_STATIC 4], uint64_t k, const uint64_t *x);
480extern void bignum_mod_nsm2_alt (uint64_t z[S2N_BIGNUM_STATIC 4], uint64_t k, const uint64_t *x);
481
482// Reduce modulo group order, z := x mod n_sm2
483// Input x[4]; output z[4]
484extern void bignum_mod_nsm2_4 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
364 485
365// Reduce modulo field characteristic, z := x mod p_25519 486// Reduce modulo field characteristic, z := x mod p_25519
366// Input x[4]; output z[4] 487// Input x[4]; output z[4]
367extern void bignum_mod_p25519_4 (uint64_t z[static 4], uint64_t x[static 4]); 488extern void bignum_mod_p25519_4 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
368 489
369// Reduce modulo field characteristic, z := x mod p_256 490// Reduce modulo field characteristic, z := x mod p_256
370// Input x[k]; output z[4] 491// Input x[k]; output z[4]
371extern void bignum_mod_p256 (uint64_t z[static 4], uint64_t k, uint64_t *x); 492extern void bignum_mod_p256 (uint64_t z[S2N_BIGNUM_STATIC 4], uint64_t k, const uint64_t *x);
372extern void bignum_mod_p256_alt (uint64_t z[static 4], uint64_t k, uint64_t *x); 493extern void bignum_mod_p256_alt (uint64_t z[S2N_BIGNUM_STATIC 4], uint64_t k, const uint64_t *x);
373 494
374// Reduce modulo field characteristic, z := x mod p_256 495// Reduce modulo field characteristic, z := x mod p_256
375// Input x[4]; output z[4] 496// Input x[4]; output z[4]
376extern void bignum_mod_p256_4 (uint64_t z[static 4], uint64_t x[static 4]); 497extern void bignum_mod_p256_4 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
377 498
378// Reduce modulo field characteristic, z := x mod p_256k1 499// Reduce modulo field characteristic, z := x mod p_256k1
379// Input x[4]; output z[4] 500// Input x[4]; output z[4]
380extern void bignum_mod_p256k1_4 (uint64_t z[static 4], uint64_t x[static 4]); 501extern void bignum_mod_p256k1_4 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
381 502
382// Reduce modulo field characteristic, z := x mod p_384 503// Reduce modulo field characteristic, z := x mod p_384
383// Input x[k]; output z[6] 504// Input x[k]; output z[6]
384extern void bignum_mod_p384 (uint64_t z[static 6], uint64_t k, uint64_t *x); 505extern void bignum_mod_p384 (uint64_t z[S2N_BIGNUM_STATIC 6], uint64_t k, const uint64_t *x);
385extern void bignum_mod_p384_alt (uint64_t z[static 6], uint64_t k, uint64_t *x); 506extern void bignum_mod_p384_alt (uint64_t z[S2N_BIGNUM_STATIC 6], uint64_t k, const uint64_t *x);
386 507
387// Reduce modulo field characteristic, z := x mod p_384 508// Reduce modulo field characteristic, z := x mod p_384
388// Input x[6]; output z[6] 509// Input x[6]; output z[6]
389extern void bignum_mod_p384_6 (uint64_t z[static 6], uint64_t x[static 6]); 510extern void bignum_mod_p384_6 (uint64_t z[S2N_BIGNUM_STATIC 6], const uint64_t x[S2N_BIGNUM_STATIC 6]);
390 511
391// Reduce modulo field characteristic, z := x mod p_521 512// Reduce modulo field characteristic, z := x mod p_521
392// Input x[9]; output z[9] 513// Input x[9]; output z[9]
393extern void bignum_mod_p521_9 (uint64_t z[static 9], uint64_t x[static 9]); 514extern void bignum_mod_p521_9 (uint64_t z[S2N_BIGNUM_STATIC 9], const uint64_t x[S2N_BIGNUM_STATIC 9]);
515
516// Reduce modulo field characteristic, z := x mod p_sm2
517// Input x[k]; output z[4]
518extern void bignum_mod_sm2 (uint64_t z[S2N_BIGNUM_STATIC 4], uint64_t k, const uint64_t *x);
519
520// Reduce modulo field characteristic, z := x mod p_sm2
521// Input x[4]; output z[4]
522extern void bignum_mod_sm2_4 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
394 523
395// Add modulo m, z := (x + y) mod m, assuming x and y reduced 524// Add modulo m, z := (x + y) mod m, assuming x and y reduced
396// Inputs x[k], y[k], m[k]; output z[k] 525// Inputs x[k], y[k], m[k]; output z[k]
397extern void bignum_modadd (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y, uint64_t *m); 526extern void bignum_modadd (uint64_t k, uint64_t *z, const uint64_t *x, const uint64_t *y, const uint64_t *m);
398 527
399// Double modulo m, z := (2 * x) mod m, assuming x reduced 528// Double modulo m, z := (2 * x) mod m, assuming x reduced
400// Inputs x[k], m[k]; output z[k] 529// Inputs x[k], m[k]; output z[k]
401extern void bignum_moddouble (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *m); 530extern void bignum_moddouble (uint64_t k, uint64_t *z, const uint64_t *x, const uint64_t *m);
531
532// Modular exponentiation for arbitrary odd modulus, z := (a^p) mod m
533// Inputs a[k], p[k], m[k]; output z[k], temporary buffer t[>=3*k]
534extern void bignum_modexp(uint64_t k,uint64_t *z, const uint64_t *a,const uint64_t *p,const uint64_t *m,uint64_t *t);
402 535
403// Compute "modification" constant z := 2^{64k} mod m 536// Compute "modification" constant z := 2^{64k} mod m
404// Input m[k]; output z[k]; temporary buffer t[>=k] 537// Input m[k]; output z[k]; temporary buffer t[>=k]
405extern void bignum_modifier (uint64_t k, uint64_t *z, uint64_t *m, uint64_t *t); 538extern void bignum_modifier (uint64_t k, uint64_t *z, const uint64_t *m, uint64_t *t);
406 539
407// Invert modulo m, z = (1/a) mod b, assuming b is an odd number > 1, a coprime to b 540// Invert modulo m, z = (1/a) mod b, assuming b is an odd number > 1, a coprime to b
408// Inputs a[k], b[k]; output z[k]; temporary buffer t[>=3*k] 541// Inputs a[k], b[k]; output z[k]; temporary buffer t[>=3*k]
409extern void bignum_modinv (uint64_t k, uint64_t *z, uint64_t *a, uint64_t *b, uint64_t *t); 542extern void bignum_modinv (uint64_t k, uint64_t *z, const uint64_t *a, const uint64_t *b, uint64_t *t);
410 543
411// Optionally negate modulo m, z := (-x) mod m (if p nonzero) or z := x (if p zero), assuming x reduced 544// Optionally negate modulo m, z := (-x) mod m (if p nonzero) or z := x (if p zero), assuming x reduced
412// Inputs p, x[k], m[k]; output z[k] 545// Inputs p, x[k], m[k]; output z[k]
413extern void bignum_modoptneg (uint64_t k, uint64_t *z, uint64_t p, uint64_t *x, uint64_t *m); 546extern void bignum_modoptneg (uint64_t k, uint64_t *z, uint64_t p, const uint64_t *x, const uint64_t *m);
414 547
415// Subtract modulo m, z := (x - y) mod m, assuming x and y reduced 548// Subtract modulo m, z := (x - y) mod m, assuming x and y reduced
416// Inputs x[k], y[k], m[k]; output z[k] 549// Inputs x[k], y[k], m[k]; output z[k]
417extern void bignum_modsub (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y, uint64_t *m); 550extern void bignum_modsub (uint64_t k, uint64_t *z, const uint64_t *x, const uint64_t *y, const uint64_t *m);
418 551
419// Compute "montification" constant z := 2^{128k} mod m 552// Compute "montification" constant z := 2^{128k} mod m
420// Input m[k]; output z[k]; temporary buffer t[>=k] 553// Input m[k]; output z[k]; temporary buffer t[>=k]
421extern void bignum_montifier (uint64_t k, uint64_t *z, uint64_t *m, uint64_t *t); 554extern void bignum_montifier (uint64_t k, uint64_t *z, const uint64_t *m, uint64_t *t);
555
556// Montgomery inverse modulo p_256 = 2^256 - 2^224 + 2^192 + 2^96 - 1
557// Input x[4]; output z[4]
558extern void bignum_montinv_p256(uint64_t z[S2N_BIGNUM_STATIC 4],const uint64_t x[S2N_BIGNUM_STATIC 4]);
559
560// Montgomery inverse modulo p_384 = 2^384 - 2^128 - 2^96 + 2^32 - 1
561// Input x[6]; output z[6]
562extern void bignum_montinv_p384(uint64_t z[S2N_BIGNUM_STATIC 6],const uint64_t x[S2N_BIGNUM_STATIC 6]);
563
564// Montgomery inverse modulo p_sm2 = 2^256 - 2^224 - 2^96 + 2^64 - 1
565// Input x[4]; output z[4]
566extern void bignum_montinv_sm2(uint64_t z[S2N_BIGNUM_STATIC 4],const uint64_t x[S2N_BIGNUM_STATIC 4]);
422 567
423// Montgomery multiply, z := (x * y / 2^{64k}) mod m 568// Montgomery multiply, z := (x * y / 2^{64k}) mod m
424// Inputs x[k], y[k], m[k]; output z[k] 569// Inputs x[k], y[k], m[k]; output z[k]
425extern void bignum_montmul (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y, uint64_t *m); 570extern void bignum_montmul (uint64_t k, uint64_t *z, const uint64_t *x, const uint64_t *y, const uint64_t *m);
426 571
427// Montgomery multiply, z := (x * y / 2^256) mod p_256 572// Montgomery multiply, z := (x * y / 2^256) mod p_256
428// Inputs x[4], y[4]; output z[4] 573// Inputs x[4], y[4]; output z[4]
429extern void bignum_montmul_p256 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 574extern void bignum_montmul_p256 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4]);
430extern void bignum_montmul_p256_alt (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 575extern void bignum_montmul_p256_alt (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4]);
431 576
432// Montgomery multiply, z := (x * y / 2^256) mod p_256k1 577// Montgomery multiply, z := (x * y / 2^256) mod p_256k1
433// Inputs x[4], y[4]; output z[4] 578// Inputs x[4], y[4]; output z[4]
434extern void bignum_montmul_p256k1 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 579extern void bignum_montmul_p256k1 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4]);
435extern void bignum_montmul_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 580extern void bignum_montmul_p256k1_alt (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4]);
436 581
437// Montgomery multiply, z := (x * y / 2^384) mod p_384 582// Montgomery multiply, z := (x * y / 2^384) mod p_384
438// Inputs x[6], y[6]; output z[6] 583// Inputs x[6], y[6]; output z[6]
439extern void bignum_montmul_p384 (uint64_t z[static 6], uint64_t x[static 6], uint64_t y[static 6]); 584extern void bignum_montmul_p384 (uint64_t z[S2N_BIGNUM_STATIC 6], const uint64_t x[S2N_BIGNUM_STATIC 6], const uint64_t y[S2N_BIGNUM_STATIC 6]);
440extern void bignum_montmul_p384_alt (uint64_t z[static 6], uint64_t x[static 6], uint64_t y[static 6]); 585extern void bignum_montmul_p384_alt (uint64_t z[S2N_BIGNUM_STATIC 6], const uint64_t x[S2N_BIGNUM_STATIC 6], const uint64_t y[S2N_BIGNUM_STATIC 6]);
441 586
442// Montgomery multiply, z := (x * y / 2^576) mod p_521 587// Montgomery multiply, z := (x * y / 2^576) mod p_521
443// Inputs x[9], y[9]; output z[9] 588// Inputs x[9], y[9]; output z[9]
444extern void bignum_montmul_p521 (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); 589extern void bignum_montmul_p521 (uint64_t z[S2N_BIGNUM_STATIC 9], const uint64_t x[S2N_BIGNUM_STATIC 9], const uint64_t y[S2N_BIGNUM_STATIC 9]);
445extern void bignum_montmul_p521_alt (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); 590extern void bignum_montmul_p521_alt (uint64_t z[S2N_BIGNUM_STATIC 9], const uint64_t x[S2N_BIGNUM_STATIC 9], const uint64_t y[S2N_BIGNUM_STATIC 9]);
591
592// Montgomery multiply, z := (x * y / 2^256) mod p_sm2
593// Inputs x[4], y[4]; output z[4]
594extern void bignum_montmul_sm2 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4]);
595extern void bignum_montmul_sm2_alt (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4]);
446 596
447// Montgomery reduce, z := (x' / 2^{64p}) MOD m 597// Montgomery reduce, z := (x' / 2^{64p}) MOD m
448// Inputs x[n], m[k], p; output z[k] 598// Inputs x[n], m[k], p; output z[k]
449extern void bignum_montredc (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t *m, uint64_t p); 599extern void bignum_montredc (uint64_t k, uint64_t *z, uint64_t n, const uint64_t *x, const uint64_t *m, uint64_t p);
450 600
451// Montgomery square, z := (x^2 / 2^{64k}) mod m 601// Montgomery square, z := (x^2 / 2^{64k}) mod m
452// Inputs x[k], m[k]; output z[k] 602// Inputs x[k], m[k]; output z[k]
453extern void bignum_montsqr (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *m); 603extern void bignum_montsqr (uint64_t k, uint64_t *z, const uint64_t *x, const uint64_t *m);
454 604
455// Montgomery square, z := (x^2 / 2^256) mod p_256 605// Montgomery square, z := (x^2 / 2^256) mod p_256
456// Input x[4]; output z[4] 606// Input x[4]; output z[4]
457extern void bignum_montsqr_p256 (uint64_t z[static 4], uint64_t x[static 4]); 607extern void bignum_montsqr_p256 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
458extern void bignum_montsqr_p256_alt (uint64_t z[static 4], uint64_t x[static 4]); 608extern void bignum_montsqr_p256_alt (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
459 609
460// Montgomery square, z := (x^2 / 2^256) mod p_256k1 610// Montgomery square, z := (x^2 / 2^256) mod p_256k1
461// Input x[4]; output z[4] 611// Input x[4]; output z[4]
462extern void bignum_montsqr_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 612extern void bignum_montsqr_p256k1 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
463extern void bignum_montsqr_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4]); 613extern void bignum_montsqr_p256k1_alt (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
464 614
465// Montgomery square, z := (x^2 / 2^384) mod p_384 615// Montgomery square, z := (x^2 / 2^384) mod p_384
466// Input x[6]; output z[6] 616// Input x[6]; output z[6]
467extern void bignum_montsqr_p384 (uint64_t z[static 6], uint64_t x[static 6]); 617extern void bignum_montsqr_p384 (uint64_t z[S2N_BIGNUM_STATIC 6], const uint64_t x[S2N_BIGNUM_STATIC 6]);
468extern void bignum_montsqr_p384_alt (uint64_t z[static 6], uint64_t x[static 6]); 618extern void bignum_montsqr_p384_alt (uint64_t z[S2N_BIGNUM_STATIC 6], const uint64_t x[S2N_BIGNUM_STATIC 6]);
469 619
470// Montgomery square, z := (x^2 / 2^576) mod p_521 620// Montgomery square, z := (x^2 / 2^576) mod p_521
471// Input x[9]; output z[9] 621// Input x[9]; output z[9]
472extern void bignum_montsqr_p521 (uint64_t z[static 9], uint64_t x[static 9]); 622extern void bignum_montsqr_p521 (uint64_t z[S2N_BIGNUM_STATIC 9], const uint64_t x[S2N_BIGNUM_STATIC 9]);
473extern void bignum_montsqr_p521_alt (uint64_t z[static 9], uint64_t x[static 9]); 623extern void bignum_montsqr_p521_alt (uint64_t z[S2N_BIGNUM_STATIC 9], const uint64_t x[S2N_BIGNUM_STATIC 9]);
624
625// Montgomery square, z := (x^2 / 2^256) mod p_sm2
626// Input x[4]; output z[4]
627extern void bignum_montsqr_sm2 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
628extern void bignum_montsqr_sm2_alt (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
474 629
475// Multiply z := x * y 630// Multiply z := x * y
476// Inputs x[m], y[n]; output z[k] 631// Inputs x[m], y[n]; output z[k]
477extern void bignum_mul (uint64_t k, uint64_t *z, uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 632extern void bignum_mul (uint64_t k, uint64_t *z, uint64_t m, const uint64_t *x, uint64_t n, const uint64_t *y);
478 633
479// Multiply z := x * y 634// Multiply z := x * y
480// Inputs x[4], y[4]; output z[8] 635// Inputs x[4], y[4]; output z[8]
481extern void bignum_mul_4_8 (uint64_t z[static 8], uint64_t x[static 4], uint64_t y[static 4]); 636extern void bignum_mul_4_8 (uint64_t z[S2N_BIGNUM_STATIC 8], const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4]);
482extern void bignum_mul_4_8_alt (uint64_t z[static 8], uint64_t x[static 4], uint64_t y[static 4]); 637extern void bignum_mul_4_8_alt (uint64_t z[S2N_BIGNUM_STATIC 8], const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4]);
483 638
484// Multiply z := x * y 639// Multiply z := x * y
485// Inputs x[6], y[6]; output z[12] 640// Inputs x[6], y[6]; output z[12]
486extern void bignum_mul_6_12 (uint64_t z[static 12], uint64_t x[static 6], uint64_t y[static 6]); 641extern void bignum_mul_6_12 (uint64_t z[S2N_BIGNUM_STATIC 12], const uint64_t x[S2N_BIGNUM_STATIC 6], const uint64_t y[S2N_BIGNUM_STATIC 6]);
487extern void bignum_mul_6_12_alt (uint64_t z[static 12], uint64_t x[static 6], uint64_t y[static 6]); 642extern void bignum_mul_6_12_alt (uint64_t z[S2N_BIGNUM_STATIC 12], const uint64_t x[S2N_BIGNUM_STATIC 6], const uint64_t y[S2N_BIGNUM_STATIC 6]);
488 643
489// Multiply z := x * y 644// Multiply z := x * y
490// Inputs x[8], y[8]; output z[16] 645// Inputs x[8], y[8]; output z[16]
491extern void bignum_mul_8_16 (uint64_t z[static 16], uint64_t x[static 8], uint64_t y[static 8]); 646extern void bignum_mul_8_16 (uint64_t z[S2N_BIGNUM_STATIC 16], const uint64_t x[S2N_BIGNUM_STATIC 8], const uint64_t y[S2N_BIGNUM_STATIC 8]);
492extern void bignum_mul_8_16_alt (uint64_t z[static 16], uint64_t x[static 8], uint64_t y[static 8]); 647extern void bignum_mul_8_16_alt (uint64_t z[S2N_BIGNUM_STATIC 16], const uint64_t x[S2N_BIGNUM_STATIC 8], const uint64_t y[S2N_BIGNUM_STATIC 8]);
493 648
494// Multiply modulo p_25519, z := (x * y) mod p_25519 649// Multiply modulo p_25519, z := (x * y) mod p_25519
495// Inputs x[4], y[4]; output z[4] 650// Inputs x[4], y[4]; output z[4]
496extern void bignum_mul_p25519 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 651extern void bignum_mul_p25519 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4]);
497extern void bignum_mul_p25519_alt (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 652extern void bignum_mul_p25519_alt (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4]);
498 653
499// Multiply modulo p_256k1, z := (x * y) mod p_256k1 654// Multiply modulo p_256k1, z := (x * y) mod p_256k1
500// Inputs x[4], y[4]; output z[4] 655// Inputs x[4], y[4]; output z[4]
501extern void bignum_mul_p256k1 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 656extern void bignum_mul_p256k1 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4]);
502extern void bignum_mul_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 657extern void bignum_mul_p256k1_alt (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4]);
503 658
504// Multiply modulo p_521, z := (x * y) mod p_521, assuming x and y reduced 659// Multiply modulo p_521, z := (x * y) mod p_521, assuming x and y reduced
505// Inputs x[9], y[9]; output z[9] 660// Inputs x[9], y[9]; output z[9]
506extern void bignum_mul_p521 (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); 661extern void bignum_mul_p521 (uint64_t z[S2N_BIGNUM_STATIC 9], const uint64_t x[S2N_BIGNUM_STATIC 9], const uint64_t y[S2N_BIGNUM_STATIC 9]);
507extern void bignum_mul_p521_alt (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); 662extern void bignum_mul_p521_alt (uint64_t z[S2N_BIGNUM_STATIC 9], const uint64_t x[S2N_BIGNUM_STATIC 9], const uint64_t y[S2N_BIGNUM_STATIC 9]);
508 663
509// Multiply bignum by 10 and add word: z := 10 * z + d 664// Multiply bignum by 10 and add word: z := 10 * z + d
510// Inputs z[k], d; outputs function return (carry) and z[k] 665// Inputs z[k], d; outputs function return (carry) and z[k]
@@ -512,55 +667,59 @@ extern uint64_t bignum_muladd10 (uint64_t k, uint64_t *z, uint64_t d);
512 667
513// Multiplex/select z := x (if p nonzero) or z := y (if p zero) 668// Multiplex/select z := x (if p nonzero) or z := y (if p zero)
514// Inputs p, x[k], y[k]; output z[k] 669// Inputs p, x[k], y[k]; output z[k]
515extern void bignum_mux (uint64_t p, uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y); 670extern void bignum_mux (uint64_t p, uint64_t k, uint64_t *z, const uint64_t *x, const uint64_t *y);
516 671
517// 256-bit multiplex/select z := x (if p nonzero) or z := y (if p zero) 672// 256-bit multiplex/select z := x (if p nonzero) or z := y (if p zero)
518// Inputs p, x[4], y[4]; output z[4] 673// Inputs p, x[4], y[4]; output z[4]
519extern void bignum_mux_4 (uint64_t p, uint64_t z[static 4],uint64_t x[static 4], uint64_t y[static 4]); 674extern void bignum_mux_4 (uint64_t p, uint64_t z[S2N_BIGNUM_STATIC 4],const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4]);
520 675
521// 384-bit multiplex/select z := x (if p nonzero) or z := y (if p zero) 676// 384-bit multiplex/select z := x (if p nonzero) or z := y (if p zero)
522// Inputs p, x[6], y[6]; output z[6] 677// Inputs p, x[6], y[6]; output z[6]
523extern void bignum_mux_6 (uint64_t p, uint64_t z[static 6],uint64_t x[static 6], uint64_t y[static 6]); 678extern void bignum_mux_6 (uint64_t p, uint64_t z[S2N_BIGNUM_STATIC 6],const uint64_t x[S2N_BIGNUM_STATIC 6], const uint64_t y[S2N_BIGNUM_STATIC 6]);
524 679
525// Select element from 16-element table, z := xs[k*i] 680// Select element from 16-element table, z := xs[k*i]
526// Inputs xs[16*k], i; output z[k] 681// Inputs xs[16*k], i; output z[k]
527extern void bignum_mux16 (uint64_t k, uint64_t *z, uint64_t *xs, uint64_t i); 682extern void bignum_mux16 (uint64_t k, uint64_t *z, const uint64_t *xs, uint64_t i);
528 683
529// Negate modulo p_25519, z := (-x) mod p_25519, assuming x reduced 684// Negate modulo p_25519, z := (-x) mod p_25519, assuming x reduced
530// Input x[4]; output z[4] 685// Input x[4]; output z[4]
531extern void bignum_neg_p25519 (uint64_t z[static 4], uint64_t x[static 4]); 686extern void bignum_neg_p25519 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
532 687
533// Negate modulo p_256, z := (-x) mod p_256, assuming x reduced 688// Negate modulo p_256, z := (-x) mod p_256, assuming x reduced
534// Input x[4]; output z[4] 689// Input x[4]; output z[4]
535extern void bignum_neg_p256 (uint64_t z[static 4], uint64_t x[static 4]); 690extern void bignum_neg_p256 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
536 691
537// Negate modulo p_256k1, z := (-x) mod p_256k1, assuming x reduced 692// Negate modulo p_256k1, z := (-x) mod p_256k1, assuming x reduced
538// Input x[4]; output z[4] 693// Input x[4]; output z[4]
539extern void bignum_neg_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 694extern void bignum_neg_p256k1 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
540 695
541// Negate modulo p_384, z := (-x) mod p_384, assuming x reduced 696// Negate modulo p_384, z := (-x) mod p_384, assuming x reduced
542// Input x[6]; output z[6] 697// Input x[6]; output z[6]
543extern void bignum_neg_p384 (uint64_t z[static 6], uint64_t x[static 6]); 698extern void bignum_neg_p384 (uint64_t z[S2N_BIGNUM_STATIC 6], const uint64_t x[S2N_BIGNUM_STATIC 6]);
544 699
545// Negate modulo p_521, z := (-x) mod p_521, assuming x reduced 700// Negate modulo p_521, z := (-x) mod p_521, assuming x reduced
546// Input x[9]; output z[9] 701// Input x[9]; output z[9]
547extern void bignum_neg_p521 (uint64_t z[static 9], uint64_t x[static 9]); 702extern void bignum_neg_p521 (uint64_t z[S2N_BIGNUM_STATIC 9], const uint64_t x[S2N_BIGNUM_STATIC 9]);
703
704// Negate modulo p_sm2, z := (-x) mod p_sm2, assuming x reduced
705// Input x[4]; output z[4]
706extern void bignum_neg_sm2 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
548 707
549// Negated modular inverse, z := (-1/x) mod 2^{64k} 708// Negated modular inverse, z := (-1/x) mod 2^{64k}
550// Input x[k]; output z[k] 709// Input x[k]; output z[k]
551extern void bignum_negmodinv (uint64_t k, uint64_t *z, uint64_t *x); 710extern void bignum_negmodinv (uint64_t k, uint64_t *z, const uint64_t *x);
552 711
553// Test bignum for nonzero-ness x =/= 0 712// Test bignum for nonzero-ness x =/= 0
554// Input x[k]; output function return 713// Input x[k]; output function return
555extern uint64_t bignum_nonzero (uint64_t k, uint64_t *x); 714extern uint64_t bignum_nonzero (uint64_t k, const uint64_t *x);
556 715
557// Test 256-bit bignum for nonzero-ness x =/= 0 716// Test 256-bit bignum for nonzero-ness x =/= 0
558// Input x[4]; output function return 717// Input x[4]; output function return
559extern uint64_t bignum_nonzero_4(uint64_t x[static 4]); 718extern uint64_t bignum_nonzero_4(const uint64_t x[S2N_BIGNUM_STATIC 4]);
560 719
561// Test 384-bit bignum for nonzero-ness x =/= 0 720// Test 384-bit bignum for nonzero-ness x =/= 0
562// Input x[6]; output function return 721// Input x[6]; output function return
563extern uint64_t bignum_nonzero_6(uint64_t x[static 6]); 722extern uint64_t bignum_nonzero_6(const uint64_t x[S2N_BIGNUM_STATIC 6]);
564 723
565// Normalize bignum in-place by shifting left till top bit is 1 724// Normalize bignum in-place by shifting left till top bit is 1
566// Input z[k]; outputs function return (bits shifted left) and z[k] 725// Input z[k]; outputs function return (bits shifted left) and z[k]
@@ -568,7 +727,7 @@ extern uint64_t bignum_normalize (uint64_t k, uint64_t *z);
568 727
569// Test bignum for odd-ness 728// Test bignum for odd-ness
570// Input x[k]; output function return 729// Input x[k]; output function return
571extern uint64_t bignum_odd (uint64_t k, uint64_t *x); 730extern uint64_t bignum_odd (uint64_t k, const uint64_t *x);
572 731
573// Convert single digit to bignum, z := n 732// Convert single digit to bignum, z := n
574// Input n; output z[k] 733// Input n; output z[k]
@@ -576,39 +735,43 @@ extern void bignum_of_word (uint64_t k, uint64_t *z, uint64_t n);
576 735
577// Optionally add, z := x + y (if p nonzero) or z := x (if p zero) 736// Optionally add, z := x + y (if p nonzero) or z := x (if p zero)
578// Inputs x[k], p, y[k]; outputs function return (carry-out) and z[k] 737// Inputs x[k], p, y[k]; outputs function return (carry-out) and z[k]
579extern uint64_t bignum_optadd (uint64_t k, uint64_t *z, uint64_t *x, uint64_t p, uint64_t *y); 738extern uint64_t bignum_optadd (uint64_t k, uint64_t *z, const uint64_t *x, uint64_t p, const uint64_t *y);
580 739
581// Optionally negate, z := -x (if p nonzero) or z := x (if p zero) 740// Optionally negate, z := -x (if p nonzero) or z := x (if p zero)
582// Inputs p, x[k]; outputs function return (nonzero input) and z[k] 741// Inputs p, x[k]; outputs function return (nonzero input) and z[k]
583extern uint64_t bignum_optneg (uint64_t k, uint64_t *z, uint64_t p, uint64_t *x); 742extern uint64_t bignum_optneg (uint64_t k, uint64_t *z, uint64_t p, const uint64_t *x);
584 743
585// Optionally negate modulo p_25519, z := (-x) mod p_25519 (if p nonzero) or z := x (if p zero), assuming x reduced 744// Optionally negate modulo p_25519, z := (-x) mod p_25519 (if p nonzero) or z := x (if p zero), assuming x reduced
586// Inputs p, x[4]; output z[4] 745// Inputs p, x[4]; output z[4]
587extern void bignum_optneg_p25519 (uint64_t z[static 4], uint64_t p, uint64_t x[static 4]); 746extern void bignum_optneg_p25519 (uint64_t z[S2N_BIGNUM_STATIC 4], uint64_t p, const uint64_t x[S2N_BIGNUM_STATIC 4]);
588 747
589// Optionally negate modulo p_256, z := (-x) mod p_256 (if p nonzero) or z := x (if p zero), assuming x reduced 748// Optionally negate modulo p_256, z := (-x) mod p_256 (if p nonzero) or z := x (if p zero), assuming x reduced
590// Inputs p, x[4]; output z[4] 749// Inputs p, x[4]; output z[4]
591extern void bignum_optneg_p256 (uint64_t z[static 4], uint64_t p, uint64_t x[static 4]); 750extern void bignum_optneg_p256 (uint64_t z[S2N_BIGNUM_STATIC 4], uint64_t p, const uint64_t x[S2N_BIGNUM_STATIC 4]);
592 751
593// Optionally negate modulo p_256k1, z := (-x) mod p_256k1 (if p nonzero) or z := x (if p zero), assuming x reduced 752// Optionally negate modulo p_256k1, z := (-x) mod p_256k1 (if p nonzero) or z := x (if p zero), assuming x reduced
594// Inputs p, x[4]; output z[4] 753// Inputs p, x[4]; output z[4]
595extern void bignum_optneg_p256k1 (uint64_t z[static 4], uint64_t p, uint64_t x[static 4]); 754extern void bignum_optneg_p256k1 (uint64_t z[S2N_BIGNUM_STATIC 4], uint64_t p, const uint64_t x[S2N_BIGNUM_STATIC 4]);
596 755
597// Optionally negate modulo p_384, z := (-x) mod p_384 (if p nonzero) or z := x (if p zero), assuming x reduced 756// Optionally negate modulo p_384, z := (-x) mod p_384 (if p nonzero) or z := x (if p zero), assuming x reduced
598// Inputs p, x[6]; output z[6] 757// Inputs p, x[6]; output z[6]
599extern void bignum_optneg_p384 (uint64_t z[static 6], uint64_t p, uint64_t x[static 6]); 758extern void bignum_optneg_p384 (uint64_t z[S2N_BIGNUM_STATIC 6], uint64_t p, const uint64_t x[S2N_BIGNUM_STATIC 6]);
600 759
601// Optionally negate modulo p_521, z := (-x) mod p_521 (if p nonzero) or z := x (if p zero), assuming x reduced 760// Optionally negate modulo p_521, z := (-x) mod p_521 (if p nonzero) or z := x (if p zero), assuming x reduced
602// Inputs p, x[9]; output z[9] 761// Inputs p, x[9]; output z[9]
603extern void bignum_optneg_p521 (uint64_t z[static 9], uint64_t p, uint64_t x[static 9]); 762extern void bignum_optneg_p521 (uint64_t z[S2N_BIGNUM_STATIC 9], uint64_t p, const uint64_t x[S2N_BIGNUM_STATIC 9]);
763
764// Optionally negate modulo p_sm2, z := (-x) mod p_sm2 (if p nonzero) or z := x (if p zero), assuming x reduced
765// Inputs p, x[4]; output z[4]
766extern void bignum_optneg_sm2 (uint64_t z[S2N_BIGNUM_STATIC 4], uint64_t p, const uint64_t x[S2N_BIGNUM_STATIC 4]);
604 767
605// Optionally subtract, z := x - y (if p nonzero) or z := x (if p zero) 768// Optionally subtract, z := x - y (if p nonzero) or z := x (if p zero)
606// Inputs x[k], p, y[k]; outputs function return (carry-out) and z[k] 769// Inputs x[k], p, y[k]; outputs function return (carry-out) and z[k]
607extern uint64_t bignum_optsub (uint64_t k, uint64_t *z, uint64_t *x, uint64_t p, uint64_t *y); 770extern uint64_t bignum_optsub (uint64_t k, uint64_t *z, const uint64_t *x, uint64_t p, const uint64_t *y);
608 771
609// Optionally subtract or add, z := x + sgn(p) * y interpreting p as signed 772// Optionally subtract or add, z := x + sgn(p) * y interpreting p as signed
610// Inputs x[k], p, y[k]; outputs function return (carry-out) and z[k] 773// Inputs x[k], p, y[k]; outputs function return (carry-out) and z[k]
611extern uint64_t bignum_optsubadd (uint64_t k, uint64_t *z, uint64_t *x, uint64_t p, uint64_t *y); 774extern uint64_t bignum_optsubadd (uint64_t k, uint64_t *z, const uint64_t *x, uint64_t p, const uint64_t *y);
612 775
613// Return bignum of power of 2, z := 2^n 776// Return bignum of power of 2, z := 2^n
614// Input n; output z[k] 777// Input n; output z[k]
@@ -616,216 +779,376 @@ extern void bignum_pow2 (uint64_t k, uint64_t *z, uint64_t n);
616 779
617// Shift bignum left by c < 64 bits z := x * 2^c 780// Shift bignum left by c < 64 bits z := x * 2^c
618// Inputs x[n], c; outputs function return (carry-out) and z[k] 781// Inputs x[n], c; outputs function return (carry-out) and z[k]
619extern uint64_t bignum_shl_small (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t c); 782extern uint64_t bignum_shl_small (uint64_t k, uint64_t *z, uint64_t n, const uint64_t *x, uint64_t c);
620 783
621// Shift bignum right by c < 64 bits z := floor(x / 2^c) 784// Shift bignum right by c < 64 bits z := floor(x / 2^c)
622// Inputs x[n], c; outputs function return (bits shifted out) and z[k] 785// Inputs x[n], c; outputs function return (bits shifted out) and z[k]
623extern uint64_t bignum_shr_small (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t c); 786extern uint64_t bignum_shr_small (uint64_t k, uint64_t *z, uint64_t n, const uint64_t *x, uint64_t c);
624 787
625// Square, z := x^2 788// Square, z := x^2
626// Input x[n]; output z[k] 789// Input x[n]; output z[k]
627extern void bignum_sqr (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x); 790extern void bignum_sqr (uint64_t k, uint64_t *z, uint64_t n, const uint64_t *x);
628 791
629// Square, z := x^2 792// Square, z := x^2
630// Input x[4]; output z[8] 793// Input x[4]; output z[8]
631extern void bignum_sqr_4_8 (uint64_t z[static 8], uint64_t x[static 4]); 794extern void bignum_sqr_4_8 (uint64_t z[S2N_BIGNUM_STATIC 8], const uint64_t x[S2N_BIGNUM_STATIC 4]);
632extern void bignum_sqr_4_8_alt (uint64_t z[static 8], uint64_t x[static 4]); 795extern void bignum_sqr_4_8_alt (uint64_t z[S2N_BIGNUM_STATIC 8], const uint64_t x[S2N_BIGNUM_STATIC 4]);
633 796
634// Square, z := x^2 797// Square, z := x^2
635// Input x[6]; output z[12] 798// Input x[6]; output z[12]
636extern void bignum_sqr_6_12 (uint64_t z[static 12], uint64_t x[static 6]); 799extern void bignum_sqr_6_12 (uint64_t z[S2N_BIGNUM_STATIC 12], const uint64_t x[S2N_BIGNUM_STATIC 6]);
637extern void bignum_sqr_6_12_alt (uint64_t z[static 12], uint64_t x[static 6]); 800extern void bignum_sqr_6_12_alt (uint64_t z[S2N_BIGNUM_STATIC 12], const uint64_t x[S2N_BIGNUM_STATIC 6]);
638 801
639// Square, z := x^2 802// Square, z := x^2
640// Input x[8]; output z[16] 803// Input x[8]; output z[16]
641extern void bignum_sqr_8_16 (uint64_t z[static 16], uint64_t x[static 8]); 804extern void bignum_sqr_8_16 (uint64_t z[S2N_BIGNUM_STATIC 16], const uint64_t x[S2N_BIGNUM_STATIC 8]);
642extern void bignum_sqr_8_16_alt (uint64_t z[static 16], uint64_t x[static 8]); 805extern void bignum_sqr_8_16_alt (uint64_t z[S2N_BIGNUM_STATIC 16], const uint64_t x[S2N_BIGNUM_STATIC 8]);
643 806
644// Square modulo p_25519, z := (x^2) mod p_25519 807// Square modulo p_25519, z := (x^2) mod p_25519
645// Input x[4]; output z[4] 808// Input x[4]; output z[4]
646extern void bignum_sqr_p25519 (uint64_t z[static 4], uint64_t x[static 4]); 809extern void bignum_sqr_p25519 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
647extern void bignum_sqr_p25519_alt (uint64_t z[static 4], uint64_t x[static 4]); 810extern void bignum_sqr_p25519_alt (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
648 811
649// Square modulo p_256k1, z := (x^2) mod p_256k1 812// Square modulo p_256k1, z := (x^2) mod p_256k1
650// Input x[4]; output z[4] 813// Input x[4]; output z[4]
651extern void bignum_sqr_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 814extern void bignum_sqr_p256k1 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
652extern void bignum_sqr_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4]); 815extern void bignum_sqr_p256k1_alt (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
653 816
654// Square modulo p_521, z := (x^2) mod p_521, assuming x reduced 817// Square modulo p_521, z := (x^2) mod p_521, assuming x reduced
655// Input x[9]; output z[9] 818// Input x[9]; output z[9]
656extern void bignum_sqr_p521 (uint64_t z[static 9], uint64_t x[static 9]); 819extern void bignum_sqr_p521 (uint64_t z[S2N_BIGNUM_STATIC 9], const uint64_t x[S2N_BIGNUM_STATIC 9]);
657extern void bignum_sqr_p521_alt (uint64_t z[static 9], uint64_t x[static 9]); 820extern void bignum_sqr_p521_alt (uint64_t z[S2N_BIGNUM_STATIC 9], const uint64_t x[S2N_BIGNUM_STATIC 9]);
821
822// Square root modulo p_25519
823// Input x[4]; output function return (Legendre symbol) and z[4]
824extern int64_t bignum_sqrt_p25519(uint64_t z[S2N_BIGNUM_STATIC 4],const uint64_t x[S2N_BIGNUM_STATIC 4]);
825extern int64_t bignum_sqrt_p25519_alt(uint64_t z[S2N_BIGNUM_STATIC 4],const uint64_t x[S2N_BIGNUM_STATIC 4]);
658 826
659// Subtract, z := x - y 827// Subtract, z := x - y
660// Inputs x[m], y[n]; outputs function return (carry-out) and z[p] 828// Inputs x[m], y[n]; outputs function return (carry-out) and z[p]
661extern uint64_t bignum_sub (uint64_t p, uint64_t *z, uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 829extern uint64_t bignum_sub (uint64_t p, uint64_t *z, uint64_t m, const uint64_t *x, uint64_t n, const uint64_t *y);
662 830
663// Subtract modulo p_25519, z := (x - y) mod p_25519, assuming x and y reduced 831// Subtract modulo p_25519, z := (x - y) mod p_25519, assuming x and y reduced
664// Inputs x[4], y[4]; output z[4] 832// Inputs x[4], y[4]; output z[4]
665extern void bignum_sub_p25519 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 833extern void bignum_sub_p25519 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4]);
666 834
667// Subtract modulo p_256, z := (x - y) mod p_256, assuming x and y reduced 835// Subtract modulo p_256, z := (x - y) mod p_256, assuming x and y reduced
668// Inputs x[4], y[4]; output z[4] 836// Inputs x[4], y[4]; output z[4]
669extern void bignum_sub_p256 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 837extern void bignum_sub_p256 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4]);
670 838
671// Subtract modulo p_256k1, z := (x - y) mod p_256k1, assuming x and y reduced 839// Subtract modulo p_256k1, z := (x - y) mod p_256k1, assuming x and y reduced
672// Inputs x[4], y[4]; output z[4] 840// Inputs x[4], y[4]; output z[4]
673extern void bignum_sub_p256k1 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 841extern void bignum_sub_p256k1 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4]);
674 842
675// Subtract modulo p_384, z := (x - y) mod p_384, assuming x and y reduced 843// Subtract modulo p_384, z := (x - y) mod p_384, assuming x and y reduced
676// Inputs x[6], y[6]; output z[6] 844// Inputs x[6], y[6]; output z[6]
677extern void bignum_sub_p384 (uint64_t z[static 6], uint64_t x[static 6], uint64_t y[static 6]); 845extern void bignum_sub_p384 (uint64_t z[S2N_BIGNUM_STATIC 6], const uint64_t x[S2N_BIGNUM_STATIC 6], const uint64_t y[S2N_BIGNUM_STATIC 6]);
678 846
679// Subtract modulo p_521, z := (x - y) mod p_521, assuming x and y reduced 847// Subtract modulo p_521, z := (x - y) mod p_521, assuming x and y reduced
680// Inputs x[9], y[9]; output z[9] 848// Inputs x[9], y[9]; output z[9]
681extern void bignum_sub_p521 (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); 849extern void bignum_sub_p521 (uint64_t z[S2N_BIGNUM_STATIC 9], const uint64_t x[S2N_BIGNUM_STATIC 9], const uint64_t y[S2N_BIGNUM_STATIC 9]);
850
851// Subtract modulo p_sm2, z := (x - y) mod p_sm2, assuming x and y reduced
852// Inputs x[4], y[4]; output z[4]
853extern void bignum_sub_sm2 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4], const uint64_t y[S2N_BIGNUM_STATIC 4]);
682 854
683// Convert 4-digit (256-bit) bignum to big-endian bytes 855// Convert 4-digit (256-bit) bignum to big-endian bytes
684// Input x[4]; output z[32] (bytes) 856// Input x[4]; output z[32] (bytes)
685extern void bignum_tobebytes_4 (uint8_t z[static 32], uint64_t x[static 4]); 857extern void bignum_tobebytes_4 (uint8_t z[S2N_BIGNUM_STATIC 32], const uint64_t x[S2N_BIGNUM_STATIC 4]);
686 858
687// Convert 6-digit (384-bit) bignum to big-endian bytes 859// Convert 6-digit (384-bit) bignum to big-endian bytes
688// Input x[6]; output z[48] (bytes) 860// Input x[6]; output z[48] (bytes)
689extern void bignum_tobebytes_6 (uint8_t z[static 48], uint64_t x[static 6]); 861extern void bignum_tobebytes_6 (uint8_t z[S2N_BIGNUM_STATIC 48], const uint64_t x[S2N_BIGNUM_STATIC 6]);
690 862
691// Convert 4-digit (256-bit) bignum to little-endian bytes 863// Convert 4-digit (256-bit) bignum to little-endian bytes
692// Input x[4]; output z[32] (bytes) 864// Input x[4]; output z[32] (bytes)
693extern void bignum_tolebytes_4 (uint8_t z[static 32], uint64_t x[static 4]); 865extern void bignum_tolebytes_4 (uint8_t z[S2N_BIGNUM_STATIC 32], const uint64_t x[S2N_BIGNUM_STATIC 4]);
694 866
695// Convert 6-digit (384-bit) bignum to little-endian bytes 867// Convert 6-digit (384-bit) bignum to little-endian bytes
696// Input x[6]; output z[48] (bytes) 868// Input x[6]; output z[48] (bytes)
697extern void bignum_tolebytes_6 (uint8_t z[static 48], uint64_t x[static 6]); 869extern void bignum_tolebytes_6 (uint8_t z[S2N_BIGNUM_STATIC 48], const uint64_t x[S2N_BIGNUM_STATIC 6]);
698 870
699// Convert 9-digit 528-bit bignum to little-endian bytes 871// Convert 9-digit 528-bit bignum to little-endian bytes
700// Input x[6]; output z[66] (bytes) 872// Input x[6]; output z[66] (bytes)
701extern void bignum_tolebytes_p521 (uint8_t z[static 66], uint64_t x[static 9]); 873extern void bignum_tolebytes_p521 (uint8_t z[S2N_BIGNUM_STATIC 66], const uint64_t x[S2N_BIGNUM_STATIC 9]);
702 874
703// Convert to Montgomery form z := (2^256 * x) mod p_256 875// Convert to Montgomery form z := (2^256 * x) mod p_256
704// Input x[4]; output z[4] 876// Input x[4]; output z[4]
705extern void bignum_tomont_p256 (uint64_t z[static 4], uint64_t x[static 4]); 877extern void bignum_tomont_p256 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
706extern void bignum_tomont_p256_alt (uint64_t z[static 4], uint64_t x[static 4]); 878extern void bignum_tomont_p256_alt (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
707 879
708// Convert to Montgomery form z := (2^256 * x) mod p_256k1 880// Convert to Montgomery form z := (2^256 * x) mod p_256k1
709// Input x[4]; output z[4] 881// Input x[4]; output z[4]
710extern void bignum_tomont_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 882extern void bignum_tomont_p256k1 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
711extern void bignum_tomont_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4]); 883extern void bignum_tomont_p256k1_alt (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
712 884
713// Convert to Montgomery form z := (2^384 * x) mod p_384 885// Convert to Montgomery form z := (2^384 * x) mod p_384
714// Input x[6]; output z[6] 886// Input x[6]; output z[6]
715extern void bignum_tomont_p384 (uint64_t z[static 6], uint64_t x[static 6]); 887extern void bignum_tomont_p384 (uint64_t z[S2N_BIGNUM_STATIC 6], const uint64_t x[S2N_BIGNUM_STATIC 6]);
716extern void bignum_tomont_p384_alt (uint64_t z[static 6], uint64_t x[static 6]); 888extern void bignum_tomont_p384_alt (uint64_t z[S2N_BIGNUM_STATIC 6], const uint64_t x[S2N_BIGNUM_STATIC 6]);
717 889
718// Convert to Montgomery form z := (2^576 * x) mod p_521 890// Convert to Montgomery form z := (2^576 * x) mod p_521
719// Input x[9]; output z[9] 891// Input x[9]; output z[9]
720extern void bignum_tomont_p521 (uint64_t z[static 9], uint64_t x[static 9]); 892extern void bignum_tomont_p521 (uint64_t z[S2N_BIGNUM_STATIC 9], const uint64_t x[S2N_BIGNUM_STATIC 9]);
893
894// Convert to Montgomery form z := (2^256 * x) mod p_sm2
895// Input x[4]; output z[4]
896extern void bignum_tomont_sm2 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
721 897
722// Triple modulo p_256, z := (3 * x) mod p_256 898// Triple modulo p_256, z := (3 * x) mod p_256
723// Input x[4]; output z[4] 899// Input x[4]; output z[4]
724extern void bignum_triple_p256 (uint64_t z[static 4], uint64_t x[static 4]); 900extern void bignum_triple_p256 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
725extern void bignum_triple_p256_alt (uint64_t z[static 4], uint64_t x[static 4]); 901extern void bignum_triple_p256_alt (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
726 902
727// Triple modulo p_256k1, z := (3 * x) mod p_256k1 903// Triple modulo p_256k1, z := (3 * x) mod p_256k1
728// Input x[4]; output z[4] 904// Input x[4]; output z[4]
729extern void bignum_triple_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 905extern void bignum_triple_p256k1 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
730extern void bignum_triple_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4]); 906extern void bignum_triple_p256k1_alt (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
731 907
732// Triple modulo p_384, z := (3 * x) mod p_384 908// Triple modulo p_384, z := (3 * x) mod p_384
733// Input x[6]; output z[6] 909// Input x[6]; output z[6]
734extern void bignum_triple_p384 (uint64_t z[static 6], uint64_t x[static 6]); 910extern void bignum_triple_p384 (uint64_t z[S2N_BIGNUM_STATIC 6], const uint64_t x[S2N_BIGNUM_STATIC 6]);
735extern void bignum_triple_p384_alt (uint64_t z[static 6], uint64_t x[static 6]); 911extern void bignum_triple_p384_alt (uint64_t z[S2N_BIGNUM_STATIC 6], const uint64_t x[S2N_BIGNUM_STATIC 6]);
736 912
737// Triple modulo p_521, z := (3 * x) mod p_521, assuming x reduced 913// Triple modulo p_521, z := (3 * x) mod p_521, assuming x reduced
738// Input x[9]; output z[9] 914// Input x[9]; output z[9]
739extern void bignum_triple_p521 (uint64_t z[static 9], uint64_t x[static 9]); 915extern void bignum_triple_p521 (uint64_t z[S2N_BIGNUM_STATIC 9], const uint64_t x[S2N_BIGNUM_STATIC 9]);
740extern void bignum_triple_p521_alt (uint64_t z[static 9], uint64_t x[static 9]); 916extern void bignum_triple_p521_alt (uint64_t z[S2N_BIGNUM_STATIC 9], const uint64_t x[S2N_BIGNUM_STATIC 9]);
917
918// Triple modulo p_sm2, z := (3 * x) mod p_sm2
919// Input x[4]; output z[4]
920extern void bignum_triple_sm2 (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
921extern void bignum_triple_sm2_alt (uint64_t z[S2N_BIGNUM_STATIC 4], const uint64_t x[S2N_BIGNUM_STATIC 4]);
741 922
742// Montgomery ladder step for curve25519 923// Montgomery ladder step for curve25519
743// Inputs point[8], pp[16], b; output rr[16] 924// Inputs point[8], pp[16], b; output rr[16]
744extern void curve25519_ladderstep(uint64_t rr[16],uint64_t point[8],uint64_t pp[16],uint64_t b); 925extern void curve25519_ladderstep(uint64_t rr[16],const uint64_t point[8],const uint64_t pp[16],uint64_t b);
745extern void curve25519_ladderstep_alt(uint64_t rr[16],uint64_t point[8],uint64_t pp[16],uint64_t b); 926extern void curve25519_ladderstep_alt(uint64_t rr[16],const uint64_t point[8],const uint64_t pp[16],uint64_t b);
746 927
747// Projective scalar multiplication, x coordinate only, for curve25519 928// Projective scalar multiplication, x coordinate only, for curve25519
748// Inputs scalar[4], point[4]; output res[8] 929// Inputs scalar[4], point[4]; output res[8]
749extern void curve25519_pxscalarmul(uint64_t res[static 8],uint64_t scalar[static 4],uint64_t point[static 4]); 930extern void curve25519_pxscalarmul(uint64_t res[S2N_BIGNUM_STATIC 8],const uint64_t scalar[S2N_BIGNUM_STATIC 4],const uint64_t point[S2N_BIGNUM_STATIC 4]);
750extern void curve25519_pxscalarmul_alt(uint64_t res[static 8],uint64_t scalar[static 4],uint64_t point[static 4]); 931extern void curve25519_pxscalarmul_alt(uint64_t res[S2N_BIGNUM_STATIC 8],const uint64_t scalar[S2N_BIGNUM_STATIC 4],const uint64_t point[S2N_BIGNUM_STATIC 4]);
751 932
752// x25519 function for curve25519 933// x25519 function for curve25519
753// Inputs scalar[4], point[4]; output res[4] 934// Inputs scalar[4], point[4]; output res[4]
754extern void curve25519_x25519(uint64_t res[static 4],uint64_t scalar[static 4],uint64_t point[static 4]); 935extern void curve25519_x25519(uint64_t res[S2N_BIGNUM_STATIC 4],const uint64_t scalar[S2N_BIGNUM_STATIC 4],const uint64_t point[S2N_BIGNUM_STATIC 4]);
755extern void curve25519_x25519_alt(uint64_t res[static 4],uint64_t scalar[static 4],uint64_t point[static 4]); 936extern void curve25519_x25519_alt(uint64_t res[S2N_BIGNUM_STATIC 4],const uint64_t scalar[S2N_BIGNUM_STATIC 4],const uint64_t point[S2N_BIGNUM_STATIC 4]);
937
938// x25519 function for curve25519 (byte array arguments)
939// Inputs scalar[32] (bytes), point[32] (bytes); output res[32] (bytes)
940extern void curve25519_x25519_byte(uint8_t res[S2N_BIGNUM_STATIC 32],const uint8_t scalar[S2N_BIGNUM_STATIC 32],const uint8_t point[S2N_BIGNUM_STATIC 32]);
941extern void curve25519_x25519_byte_alt(uint8_t res[S2N_BIGNUM_STATIC 32],const uint8_t scalar[S2N_BIGNUM_STATIC 32],const uint8_t point[S2N_BIGNUM_STATIC 32]);
756 942
757// x25519 function for curve25519 on base element 9 943// x25519 function for curve25519 on base element 9
758// Input scalar[4]; output res[4] 944// Input scalar[4]; output res[4]
759extern void curve25519_x25519base(uint64_t res[static 4],uint64_t scalar[static 4]); 945extern void curve25519_x25519base(uint64_t res[S2N_BIGNUM_STATIC 4],const uint64_t scalar[S2N_BIGNUM_STATIC 4]);
760extern void curve25519_x25519base_alt(uint64_t res[static 4],uint64_t scalar[static 4]); 946extern void curve25519_x25519base_alt(uint64_t res[S2N_BIGNUM_STATIC 4],const uint64_t scalar[S2N_BIGNUM_STATIC 4]);
947
948// x25519 function for curve25519 on base element 9 (byte array arguments)
949// Input scalar[32] (bytes); output res[32] (bytes)
950extern void curve25519_x25519base_byte(uint8_t res[S2N_BIGNUM_STATIC 32],const uint8_t scalar[S2N_BIGNUM_STATIC 32]);
951extern void curve25519_x25519base_byte_alt(uint8_t res[S2N_BIGNUM_STATIC 32],const uint8_t scalar[S2N_BIGNUM_STATIC 32]);
952
953// Decode compressed 256-bit form of edwards25519 point
954// Input c[32] (bytes); output function return and z[8]
955extern uint64_t edwards25519_decode(uint64_t z[S2N_BIGNUM_STATIC 8], const uint8_t c[S2N_BIGNUM_STATIC 32]);
956extern uint64_t edwards25519_decode_alt(uint64_t z[S2N_BIGNUM_STATIC 8], const uint8_t c[S2N_BIGNUM_STATIC 32]);
957
958// Encode edwards25519 point into compressed form as 256-bit number
959// Input p[8]; output z[32] (bytes)
960extern void edwards25519_encode(uint8_t z[S2N_BIGNUM_STATIC 32], const uint64_t p[S2N_BIGNUM_STATIC 8]);
761 961
762// Extended projective addition for edwards25519 962// Extended projective addition for edwards25519
763// Inputs p1[16], p2[16]; output p3[16] 963// Inputs p1[16], p2[16]; output p3[16]
764extern void edwards25519_epadd(uint64_t p3[static 16],uint64_t p1[static 16],uint64_t p2[static 16]); 964extern void edwards25519_epadd(uint64_t p3[S2N_BIGNUM_STATIC 16],const uint64_t p1[S2N_BIGNUM_STATIC 16],const uint64_t p2[S2N_BIGNUM_STATIC 16]);
765extern void edwards25519_epadd_alt(uint64_t p3[static 16],uint64_t p1[static 16],uint64_t p2[static 16]); 965extern void edwards25519_epadd_alt(uint64_t p3[S2N_BIGNUM_STATIC 16],const uint64_t p1[S2N_BIGNUM_STATIC 16],const uint64_t p2[S2N_BIGNUM_STATIC 16]);
766 966
767// Extended projective doubling for edwards25519 967// Extended projective doubling for edwards25519
768// Inputs p1[12]; output p3[16] 968// Inputs p1[12]; output p3[16]
769extern void edwards25519_epdouble(uint64_t p3[static 16],uint64_t p1[static 12]); 969extern void edwards25519_epdouble(uint64_t p3[S2N_BIGNUM_STATIC 16],const uint64_t p1[S2N_BIGNUM_STATIC 12]);
770extern void edwards25519_epdouble_alt(uint64_t p3[static 16],uint64_t p1[static 12]); 970extern void edwards25519_epdouble_alt(uint64_t p3[S2N_BIGNUM_STATIC 16],const uint64_t p1[S2N_BIGNUM_STATIC 12]);
771 971
772// Projective doubling for edwards25519 972// Projective doubling for edwards25519
773// Inputs p1[12]; output p3[12] 973// Inputs p1[12]; output p3[12]
774extern void edwards25519_pdouble(uint64_t p3[static 12],uint64_t p1[static 12]); 974extern void edwards25519_pdouble(uint64_t p3[S2N_BIGNUM_STATIC 12],const uint64_t p1[S2N_BIGNUM_STATIC 12]);
775extern void edwards25519_pdouble_alt(uint64_t p3[static 12],uint64_t p1[static 12]); 975extern void edwards25519_pdouble_alt(uint64_t p3[S2N_BIGNUM_STATIC 12],const uint64_t p1[S2N_BIGNUM_STATIC 12]);
776 976
777// Extended projective + precomputed mixed addition for edwards25519 977// Extended projective + precomputed mixed addition for edwards25519
778// Inputs p1[16], p2[12]; output p3[16] 978// Inputs p1[16], p2[12]; output p3[16]
779extern void edwards25519_pepadd(uint64_t p3[static 16],uint64_t p1[static 16],uint64_t p2[static 12]); 979extern void edwards25519_pepadd(uint64_t p3[S2N_BIGNUM_STATIC 16],const uint64_t p1[S2N_BIGNUM_STATIC 16],const uint64_t p2[S2N_BIGNUM_STATIC 12]);
780extern void edwards25519_pepadd_alt(uint64_t p3[static 16],uint64_t p1[static 16],uint64_t p2[static 12]); 980extern void edwards25519_pepadd_alt(uint64_t p3[S2N_BIGNUM_STATIC 16],const uint64_t p1[S2N_BIGNUM_STATIC 16],const uint64_t p2[S2N_BIGNUM_STATIC 12]);
981
982// Scalar multiplication by standard basepoint for edwards25519 (Ed25519)
983// Input scalar[4]; output res[8]
984extern void edwards25519_scalarmulbase(uint64_t res[S2N_BIGNUM_STATIC 8],const uint64_t scalar[S2N_BIGNUM_STATIC 4]);
985extern void edwards25519_scalarmulbase_alt(uint64_t res[S2N_BIGNUM_STATIC 8],const uint64_t scalar[S2N_BIGNUM_STATIC 4]);
986
987// Double scalar multiplication for edwards25519, fresh and base point
988// Input scalar[4], point[8], bscalar[4]; output res[8]
989extern void edwards25519_scalarmuldouble(uint64_t res[S2N_BIGNUM_STATIC 8],const uint64_t scalar[S2N_BIGNUM_STATIC 4], const uint64_t point[S2N_BIGNUM_STATIC 8],const uint64_t bscalar[S2N_BIGNUM_STATIC 4]);
990extern void edwards25519_scalarmuldouble_alt(uint64_t res[S2N_BIGNUM_STATIC 8],const uint64_t scalar[S2N_BIGNUM_STATIC 4], const uint64_t point[S2N_BIGNUM_STATIC 8],const uint64_t bscalar[S2N_BIGNUM_STATIC 4]);
991
992// Scalar product of 2-element polynomial vectors in NTT domain, with mulcache
993// Inputs a[512], b[512], bt[256] (signed 16-bit words); output r[256] (signed 16-bit words)
994extern void mlkem_basemul_k2(int16_t r[S2N_BIGNUM_STATIC 256],const int16_t a[S2N_BIGNUM_STATIC 512],const int16_t b[S2N_BIGNUM_STATIC 512],const int16_t bt[S2N_BIGNUM_STATIC 256]);
995
996// Scalar product of 3-element polynomial vectors in NTT domain, with mulcache
997// Inputs a[768], b[768], bt[384] (signed 16-bit words); output r[256] (signed 16-bit words)
998extern void mlkem_basemul_k3(int16_t r[S2N_BIGNUM_STATIC 256],const int16_t a[S2N_BIGNUM_STATIC 768],const int16_t b[S2N_BIGNUM_STATIC 768],const int16_t bt[S2N_BIGNUM_STATIC 384]);
999
1000// Scalar product of 4-element polynomial vectors in NTT domain, with mulcache
1001// Inputs a[1024], b[1024], bt[512] (signed 16-bit words); output r[256] (signed 16-bit words)
1002extern void mlkem_basemul_k4(int16_t r[S2N_BIGNUM_STATIC 256],const int16_t a[S2N_BIGNUM_STATIC 1024],const int16_t b[S2N_BIGNUM_STATIC 1024],const int16_t bt[S2N_BIGNUM_STATIC 512]);
1003
1004// Inverse number-theoretic transform from ML-KEM
1005// Input a[256] (signed 16-bit words), z_01234[80] (signed 16-bit words), z_56[384] (signed 16-bit words); output a[256] (signed 16-bit words)
1006extern void mlkem_intt(int16_t a[S2N_BIGNUM_STATIC 256],const int16_t z_01234[S2N_BIGNUM_STATIC 80],const int16_t z_56[S2N_BIGNUM_STATIC 384]);
1007
1008// Precompute the mulcache data for a polynomial in the NTT domain
1009// Inputs a[256], z[128] and t[128] (signed 16-bit words); output x[128] (signed 16-bit words)
1010extern void mlkem_mulcache_compute(int16_t x[S2N_BIGNUM_STATIC 128],const int16_t a[S2N_BIGNUM_STATIC 256],const int16_t z[S2N_BIGNUM_STATIC 128],const int16_t t[S2N_BIGNUM_STATIC 128]);
1011
1012// Forward number-theoretic transform from ML-KEM
1013// Input a[256] (signed 16-bit words), z_01234[80] (signed 16-bit words), z_56[384] (signed 16-bit words); output a[256] (signed 16-bit words)
1014extern void mlkem_ntt(int16_t a[S2N_BIGNUM_STATIC 256],const int16_t z_01234[S2N_BIGNUM_STATIC 80],const int16_t z_56[S2N_BIGNUM_STATIC 384]);
1015
1016// Canonical modular reduction of polynomial coefficients for ML-KEM
1017// Input a[256] (signed 16-bit words); output a[256] (signed 16-bit words)
1018extern void mlkem_reduce(int16_t a[S2N_BIGNUM_STATIC 256]);
1019
1020// Pack ML-KEM polynomial coefficients as 12-bit numbers
1021// Input a[256] (signed 16-bit words); output r[384] (bytes)
1022extern void mlkem_tobytes(uint8_t r[S2N_BIGNUM_STATIC 384],const int16_t a[S2N_BIGNUM_STATIC 256]);
1023
1024// Conversion of ML-KEM polynomial coefficients to Montgomery form
1025// Input a[256] (signed 16-bit words); output a[256] (signed 16-bit words)
1026extern void mlkem_tomont(int16_t a[S2N_BIGNUM_STATIC 256]);
1027
1028// Uniform rejection sampling for ML-KEM
1029// Inputs *buf (unsigned bytes), buflen, table (unsigned bytes); output r[256] (signed 16-bit words), return
1030extern uint64_t mlkem_rej_uniform_VARIABLE_TIME(int16_t r[S2N_BIGNUM_STATIC 256],const uint8_t *buf,uint64_t buflen,const uint8_t *table);
781 1031
782// Point addition on NIST curve P-256 in Montgomery-Jacobian coordinates 1032// Point addition on NIST curve P-256 in Montgomery-Jacobian coordinates
783// Inputs p1[12], p2[12]; output p3[12] 1033// Inputs p1[12], p2[12]; output p3[12]
784extern void p256_montjadd(uint64_t p3[static 12],uint64_t p1[static 12],uint64_t p2[static 12]); 1034extern void p256_montjadd(uint64_t p3[S2N_BIGNUM_STATIC 12],const uint64_t p1[S2N_BIGNUM_STATIC 12],const uint64_t p2[S2N_BIGNUM_STATIC 12]);
1035extern void p256_montjadd_alt(uint64_t p3[S2N_BIGNUM_STATIC 12],const uint64_t p1[S2N_BIGNUM_STATIC 12],const uint64_t p2[S2N_BIGNUM_STATIC 12]);
785 1036
786// Point doubling on NIST curve P-256 in Montgomery-Jacobian coordinates 1037// Point doubling on NIST curve P-256 in Montgomery-Jacobian coordinates
787// Inputs p1[12]; output p3[12] 1038// Inputs p1[12]; output p3[12]
788extern void p256_montjdouble(uint64_t p3[static 12],uint64_t p1[static 12]); 1039extern void p256_montjdouble(uint64_t p3[S2N_BIGNUM_STATIC 12],const uint64_t p1[S2N_BIGNUM_STATIC 12]);
1040extern void p256_montjdouble_alt(uint64_t p3[S2N_BIGNUM_STATIC 12],const uint64_t p1[S2N_BIGNUM_STATIC 12]);
789 1041
790// Point mixed addition on NIST curve P-256 in Montgomery-Jacobian coordinates 1042// Point mixed addition on NIST curve P-256 in Montgomery-Jacobian coordinates
791// Inputs p1[12], p2[8]; output p3[12] 1043// Inputs p1[12], p2[8]; output p3[12]
792extern void p256_montjmixadd(uint64_t p3[static 12],uint64_t p1[static 12],uint64_t p2[static 8]); 1044extern void p256_montjmixadd(uint64_t p3[S2N_BIGNUM_STATIC 12],const uint64_t p1[S2N_BIGNUM_STATIC 12],const uint64_t p2[S2N_BIGNUM_STATIC 8]);
1045extern void p256_montjmixadd_alt(uint64_t p3[S2N_BIGNUM_STATIC 12],const uint64_t p1[S2N_BIGNUM_STATIC 12],const uint64_t p2[S2N_BIGNUM_STATIC 8]);
1046
1047// Montgomery-Jacobian form scalar multiplication for P-256
1048// Input scalar[4], point[12]; output res[12]
1049extern void p256_montjscalarmul(uint64_t res[S2N_BIGNUM_STATIC 12],const uint64_t scalar[S2N_BIGNUM_STATIC 4],const uint64_t point[S2N_BIGNUM_STATIC 12]);
1050extern void p256_montjscalarmul_alt(uint64_t res[S2N_BIGNUM_STATIC 12],const uint64_t scalar[S2N_BIGNUM_STATIC 4],const uint64_t point[S2N_BIGNUM_STATIC 12]);
1051
1052// Scalar multiplication for NIST curve P-256
1053// Input scalar[4], point[8]; output res[8]
1054extern void p256_scalarmul(uint64_t res[S2N_BIGNUM_STATIC 8],const uint64_t scalar[S2N_BIGNUM_STATIC 4],const uint64_t point[S2N_BIGNUM_STATIC 8]);
1055extern void p256_scalarmul_alt(uint64_t res[S2N_BIGNUM_STATIC 8],const uint64_t scalar[S2N_BIGNUM_STATIC 4],const uint64_t point[S2N_BIGNUM_STATIC 8]);
1056
1057// Scalar multiplication for precomputed point on NIST curve P-256
1058// Input scalar[4], blocksize, table[]; output res[8]
1059extern void p256_scalarmulbase(uint64_t res[S2N_BIGNUM_STATIC 8],const uint64_t scalar[S2N_BIGNUM_STATIC 4],uint64_t blocksize,const uint64_t *table);
1060extern void p256_scalarmulbase_alt(uint64_t res[S2N_BIGNUM_STATIC 8],const uint64_t scalar[S2N_BIGNUM_STATIC 4],uint64_t blocksize,const uint64_t *table);
793 1061
794// Point addition on NIST curve P-384 in Montgomery-Jacobian coordinates 1062// Point addition on NIST curve P-384 in Montgomery-Jacobian coordinates
795// Inputs p1[18], p2[18]; output p3[18] 1063// Inputs p1[18], p2[18]; output p3[18]
796extern void p384_montjadd(uint64_t p3[static 18],uint64_t p1[static 18],uint64_t p2[static 18]); 1064extern void p384_montjadd(uint64_t p3[S2N_BIGNUM_STATIC 18],const uint64_t p1[S2N_BIGNUM_STATIC 18],const uint64_t p2[S2N_BIGNUM_STATIC 18]);
1065extern void p384_montjadd_alt(uint64_t p3[S2N_BIGNUM_STATIC 18],const uint64_t p1[S2N_BIGNUM_STATIC 18],const uint64_t p2[S2N_BIGNUM_STATIC 18]);
797 1066
798// Point doubling on NIST curve P-384 in Montgomery-Jacobian coordinates 1067// Point doubling on NIST curve P-384 in Montgomery-Jacobian coordinates
799// Inputs p1[18]; output p3[18] 1068// Inputs p1[18]; output p3[18]
800extern void p384_montjdouble(uint64_t p3[static 18],uint64_t p1[static 18]); 1069extern void p384_montjdouble(uint64_t p3[S2N_BIGNUM_STATIC 18],const uint64_t p1[S2N_BIGNUM_STATIC 18]);
1070extern void p384_montjdouble_alt(uint64_t p3[S2N_BIGNUM_STATIC 18],const uint64_t p1[S2N_BIGNUM_STATIC 18]);
801 1071
802// Point mixed addition on NIST curve P-384 in Montgomery-Jacobian coordinates 1072// Point mixed addition on NIST curve P-384 in Montgomery-Jacobian coordinates
803// Inputs p1[18], p2[12]; output p3[18] 1073// Inputs p1[18], p2[12]; output p3[18]
804extern void p384_montjmixadd(uint64_t p3[static 18],uint64_t p1[static 18],uint64_t p2[static 12]); 1074extern void p384_montjmixadd(uint64_t p3[S2N_BIGNUM_STATIC 18],const uint64_t p1[S2N_BIGNUM_STATIC 18],const uint64_t p2[S2N_BIGNUM_STATIC 12]);
1075extern void p384_montjmixadd_alt(uint64_t p3[S2N_BIGNUM_STATIC 18],const uint64_t p1[S2N_BIGNUM_STATIC 18],const uint64_t p2[S2N_BIGNUM_STATIC 12]);
1076
1077// Montgomery-Jacobian form scalar multiplication for P-384
1078// Input scalar[6], point[18]; output res[18]
1079extern void p384_montjscalarmul(uint64_t res[S2N_BIGNUM_STATIC 18],const uint64_t scalar[S2N_BIGNUM_STATIC 6],const uint64_t point[S2N_BIGNUM_STATIC 18]);
1080extern void p384_montjscalarmul_alt(uint64_t res[S2N_BIGNUM_STATIC 18],const uint64_t scalar[S2N_BIGNUM_STATIC 6],const uint64_t point[S2N_BIGNUM_STATIC 18]);
805 1081
806// Point addition on NIST curve P-521 in Jacobian coordinates 1082// Point addition on NIST curve P-521 in Jacobian coordinates
807// Inputs p1[27], p2[27]; output p3[27] 1083// Inputs p1[27], p2[27]; output p3[27]
808extern void p521_jadd(uint64_t p3[static 27],uint64_t p1[static 27],uint64_t p2[static 27]); 1084extern void p521_jadd(uint64_t p3[S2N_BIGNUM_STATIC 27],const uint64_t p1[S2N_BIGNUM_STATIC 27],const uint64_t p2[S2N_BIGNUM_STATIC 27]);
1085extern void p521_jadd_alt(uint64_t p3[S2N_BIGNUM_STATIC 27],const uint64_t p1[S2N_BIGNUM_STATIC 27],const uint64_t p2[S2N_BIGNUM_STATIC 27]);
809 1086
810// Point doubling on NIST curve P-521 in Jacobian coordinates 1087// Point doubling on NIST curve P-521 in Jacobian coordinates
811// Input p1[27]; output p3[27] 1088// Input p1[27]; output p3[27]
812extern void p521_jdouble(uint64_t p3[static 27],uint64_t p1[static 27]); 1089extern void p521_jdouble(uint64_t p3[S2N_BIGNUM_STATIC 27],const uint64_t p1[S2N_BIGNUM_STATIC 27]);
1090extern void p521_jdouble_alt(uint64_t p3[S2N_BIGNUM_STATIC 27],const uint64_t p1[S2N_BIGNUM_STATIC 27]);
813 1091
814// Point mixed addition on NIST curve P-521 in Jacobian coordinates 1092// Point mixed addition on NIST curve P-521 in Jacobian coordinates
815// Inputs p1[27], p2[18]; output p3[27] 1093// Inputs p1[27], p2[18]; output p3[27]
816extern void p521_jmixadd(uint64_t p3[static 27],uint64_t p1[static 27],uint64_t p2[static 18]); 1094extern void p521_jmixadd(uint64_t p3[S2N_BIGNUM_STATIC 27],const uint64_t p1[S2N_BIGNUM_STATIC 27],const uint64_t p2[S2N_BIGNUM_STATIC 18]);
1095extern void p521_jmixadd_alt(uint64_t p3[S2N_BIGNUM_STATIC 27],const uint64_t p1[S2N_BIGNUM_STATIC 27],const uint64_t p2[S2N_BIGNUM_STATIC 18]);
1096
1097// Jacobian form scalar multiplication for P-521
1098// Input scalar[9], point[27]; output res[27]
1099extern void p521_jscalarmul(uint64_t res[S2N_BIGNUM_STATIC 27],const uint64_t scalar[S2N_BIGNUM_STATIC 9],const uint64_t point[S2N_BIGNUM_STATIC 27]);
1100extern void p521_jscalarmul_alt(uint64_t res[S2N_BIGNUM_STATIC 27],const uint64_t scalar[S2N_BIGNUM_STATIC 9],const uint64_t point[S2N_BIGNUM_STATIC 27]);
817 1101
818// Point addition on SECG curve secp256k1 in Jacobian coordinates 1102// Point addition on SECG curve secp256k1 in Jacobian coordinates
819// Inputs p1[12], p2[12]; output p3[12] 1103// Inputs p1[12], p2[12]; output p3[12]
820extern void secp256k1_jadd(uint64_t p3[static 12],uint64_t p1[static 12],uint64_t p2[static 12]); 1104extern void secp256k1_jadd(uint64_t p3[S2N_BIGNUM_STATIC 12],const uint64_t p1[S2N_BIGNUM_STATIC 12],const uint64_t p2[S2N_BIGNUM_STATIC 12]);
1105extern void secp256k1_jadd_alt(uint64_t p3[S2N_BIGNUM_STATIC 12],const uint64_t p1[S2N_BIGNUM_STATIC 12],const uint64_t p2[S2N_BIGNUM_STATIC 12]);
821 1106
822// Point doubling on SECG curve secp256k1 in Jacobian coordinates 1107// Point doubling on SECG curve secp256k1 in Jacobian coordinates
823// Input p1[12]; output p3[12] 1108// Input p1[12]; output p3[12]
824extern void secp256k1_jdouble(uint64_t p3[static 12],uint64_t p1[static 12]); 1109extern void secp256k1_jdouble(uint64_t p3[S2N_BIGNUM_STATIC 12],const uint64_t p1[S2N_BIGNUM_STATIC 12]);
1110extern void secp256k1_jdouble_alt(uint64_t p3[S2N_BIGNUM_STATIC 12],const uint64_t p1[S2N_BIGNUM_STATIC 12]);
825 1111
826// Point mixed addition on SECG curve secp256k1 in Jacobian coordinates 1112// Point mixed addition on SECG curve secp256k1 in Jacobian coordinates
827// Inputs p1[12], p2[8]; output p3[12] 1113// Inputs p1[12], p2[8]; output p3[12]
828extern void secp256k1_jmixadd(uint64_t p3[static 12],uint64_t p1[static 12],uint64_t p2[static 8]); 1114extern void secp256k1_jmixadd(uint64_t p3[S2N_BIGNUM_STATIC 12],const uint64_t p1[S2N_BIGNUM_STATIC 12],const uint64_t p2[S2N_BIGNUM_STATIC 8]);
1115extern void secp256k1_jmixadd_alt(uint64_t p3[S2N_BIGNUM_STATIC 12],const uint64_t p1[S2N_BIGNUM_STATIC 12],const uint64_t p2[S2N_BIGNUM_STATIC 8]);
1116
1117// Keccak-f1600 permutation for SHA3
1118// Inputs a[25], rc[24]; output a[25]
1119extern void sha3_keccak_f1600(uint64_t a[S2N_BIGNUM_STATIC 25],const uint64_t rc[S2N_BIGNUM_STATIC 24]);
1120extern void sha3_keccak_f1600_alt(uint64_t a[S2N_BIGNUM_STATIC 25],const uint64_t rc[S2N_BIGNUM_STATIC 24]);
1121
1122// Batched 2-way Keccak-f1600 permutation for SHA3
1123// Inputs a[50], rc[24]; output a[50]
1124extern void sha3_keccak2_f1600(uint64_t a[S2N_BIGNUM_STATIC 50],const uint64_t rc[S2N_BIGNUM_STATIC 24]);
1125extern void sha3_keccak2_f1600_alt(uint64_t a[S2N_BIGNUM_STATIC 50],const uint64_t rc[S2N_BIGNUM_STATIC 24]);
1126
1127// Batched 4-way Keccak-f1600 permutation for SHA3
1128// Inputs a[100], rc[24]; output a[100]
1129extern void sha3_keccak4_f1600(uint64_t a[S2N_BIGNUM_STATIC 100],const uint64_t rc[S2N_BIGNUM_STATIC 24]);
1130extern void sha3_keccak4_f1600_alt(uint64_t a[S2N_BIGNUM_STATIC 100],const uint64_t rc[S2N_BIGNUM_STATIC 24]);
1131extern void sha3_keccak4_f1600_alt2(uint64_t a[S2N_BIGNUM_STATIC 100],const uint64_t rc[S2N_BIGNUM_STATIC 24]);
1132
1133// Point addition on CC curve SM2 in Montgomery-Jacobian coordinates
1134// Inputs p1[12], p2[12]; output p3[12]
1135extern void sm2_montjadd(uint64_t p3[S2N_BIGNUM_STATIC 12],const uint64_t p1[S2N_BIGNUM_STATIC 12],const uint64_t p2[S2N_BIGNUM_STATIC 12]);
1136extern void sm2_montjadd_alt(uint64_t p3[S2N_BIGNUM_STATIC 12],const uint64_t p1[S2N_BIGNUM_STATIC 12],const uint64_t p2[S2N_BIGNUM_STATIC 12]);
1137
1138// Point doubling on CC curve SM2 in Montgomery-Jacobian coordinates
1139// Inputs p1[12]; output p3[12]
1140extern void sm2_montjdouble(uint64_t p3[S2N_BIGNUM_STATIC 12],const uint64_t p1[S2N_BIGNUM_STATIC 12]);
1141extern void sm2_montjdouble_alt(uint64_t p3[S2N_BIGNUM_STATIC 12],const uint64_t p1[S2N_BIGNUM_STATIC 12]);
1142
1143// Point mixed addition on CC curve SM2 in Montgomery-Jacobian coordinates
1144// Inputs p1[12], p2[8]; output p3[12]
1145extern void sm2_montjmixadd(uint64_t p3[S2N_BIGNUM_STATIC 12],const uint64_t p1[S2N_BIGNUM_STATIC 12],const uint64_t p2[S2N_BIGNUM_STATIC 8]);
1146extern void sm2_montjmixadd_alt(uint64_t p3[S2N_BIGNUM_STATIC 12],const uint64_t p1[S2N_BIGNUM_STATIC 12],const uint64_t p2[S2N_BIGNUM_STATIC 8]);
1147
1148// Montgomery-Jacobian form scalar multiplication for CC curve SM2
1149// Input scalar[4], point[12]; output res[12]
1150extern void sm2_montjscalarmul(uint64_t res[S2N_BIGNUM_STATIC 12],const uint64_t scalar[S2N_BIGNUM_STATIC 4],const uint64_t point[S2N_BIGNUM_STATIC 12]);
1151extern void sm2_montjscalarmul_alt(uint64_t res[S2N_BIGNUM_STATIC 12],const uint64_t scalar[S2N_BIGNUM_STATIC 4],const uint64_t point[S2N_BIGNUM_STATIC 12]);
829 1152
830// Reverse the bytes in a single word 1153// Reverse the bytes in a single word
831// Input a; output function return 1154// Input a; output function return
@@ -839,6 +1162,10 @@ extern uint64_t word_clz (uint64_t a);
839// Input a; output function return 1162// Input a; output function return
840extern uint64_t word_ctz (uint64_t a); 1163extern uint64_t word_ctz (uint64_t a);
841 1164
1165// Perform 59 "divstep" iterations and return signed matrix of updates
1166// Inputs d, f, g; output m[2][2] and function return
1167extern int64_t word_divstep59(int64_t m[2][2],int64_t d,uint64_t f,uint64_t g);
1168
842// Return maximum of two unsigned 64-bit words 1169// Return maximum of two unsigned 64-bit words
843// Inputs a, b; output function return 1170// Inputs a, b; output function return
844extern uint64_t word_max (uint64_t a, uint64_t b); 1171extern uint64_t word_max (uint64_t a, uint64_t b);
@@ -851,6 +1178,10 @@ extern uint64_t word_min (uint64_t a, uint64_t b);
851// Input a; output function return 1178// Input a; output function return
852extern uint64_t word_negmodinv (uint64_t a); 1179extern uint64_t word_negmodinv (uint64_t a);
853 1180
1181// Count number of set bits in a single 64-bit word (population count)
1182// Input a; output function return
1183extern uint64_t word_popcount (uint64_t a);
1184
854// Single-word reciprocal, 2^64 + ret = ceil(2^128/a) - 1 if MSB of "a" is set 1185// Single-word reciprocal, 2^64 + ret = ceil(2^128/a) - 1 if MSB of "a" is set
855// Input a; output function return 1186// Input a; output function return
856extern uint64_t word_recip (uint64_t a); 1187extern uint64_t word_recip (uint64_t a);
diff --git a/src/lib/libcrypto/bn/s2n_bignum_internal.h b/src/lib/libcrypto/bn/s2n_bignum_internal.h
index b82db7d019..4217ca95af 100644
--- a/src/lib/libcrypto/bn/s2n_bignum_internal.h
+++ b/src/lib/libcrypto/bn/s2n_bignum_internal.h
@@ -14,14 +14,14 @@
14 14
15#ifdef __APPLE__ 15#ifdef __APPLE__
16# define S2N_BN_SYMBOL(NAME) _##NAME 16# define S2N_BN_SYMBOL(NAME) _##NAME
17# if defined(__AARCH64EL__) || defined(__ARMEL__)
18# define __LF %%
19# else
20# define __LF ;
21# endif
17#else 22#else
18# define S2N_BN_SYMBOL(name) name 23# define S2N_BN_SYMBOL(name) name
19#endif 24# define __LF ;
20
21#ifdef __CET__
22# include <cet.h>
23#else
24# define _CET_ENDBR
25#endif 25#endif
26 26
27#define S2N_BN_SYM_VISIBILITY_DIRECTIVE(name) .globl S2N_BN_SYMBOL(name) 27#define S2N_BN_SYM_VISIBILITY_DIRECTIVE(name) .globl S2N_BN_SYMBOL(name)
@@ -34,3 +34,24 @@
34#else 34#else
35# define S2N_BN_SYM_PRIVACY_DIRECTIVE(name) /* NO-OP: S2N_BN_SYM_PRIVACY_DIRECTIVE */ 35# define S2N_BN_SYM_PRIVACY_DIRECTIVE(name) /* NO-OP: S2N_BN_SYM_PRIVACY_DIRECTIVE */
36#endif 36#endif
37
38// Enable indirect branch tracking support unless explicitly disabled
39// with -DNO_IBT. If the platform supports CET, simply inherit this from
40// the usual header. Otherwise manually define _CET_ENDBR, used at each
41// x86 entry point, to be the ENDBR64 instruction, with an explicit byte
42// sequence for compilers/assemblers that don't know about it. Note that
43// it is safe to use ENDBR64 on all platforms, since the encoding is by
44// design interpreted as a NOP on all pre-CET x86_64 processors. The only
45// downside is a small increase in code size and potentially a modest
46// slowdown from executing one more instruction.
47
48#if NO_IBT
49# if defined(_CET_ENDBR)
50# error "The s2n-bignum build option NO_IBT was configured, but _CET_ENDBR is defined in this compilation unit. That is weird, so failing the build."
51# endif
52# define _CET_ENDBR
53#elif defined(__CET__)
54# include <cet.h>
55#elif !defined(_CET_ENDBR)
56# define _CET_ENDBR .byte 0xf3,0x0f,0x1e,0xfa
57#endif