1 // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 // 3 // Permission to use, copy, modify, and/or distribute this software for any 4 // purpose with or without fee is hereby granted, provided that the above 5 // copyright notice and this permission notice appear in all copies. 6 // 7 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 15 // ---------------------------------------------------------------------------- 16 // C prototypes for s2n-bignum functions, so you can use them in C programs via 17 // 18 // #include "s2n-bignum.h" 19 // 20 // The functions are listed in alphabetical order with a brief description 21 // in comments for each one. For more detailed documentation see the comment 22 // banner at the top of the corresponding assembly (.S) file, and 23 // for the last word in what properties it satisfies see the spec in the 24 // formal proof (the .ml file in the architecture-specific directory). 25 // 26 // For some functions there are additional variants with names ending in 27 // "_alt". These have the same core mathematical functionality as their 28 // non-"alt" versions, but can be better suited to some microarchitectures: 29 // 30 // - On x86, the "_alt" forms avoid BMI and ADX instruction set 31 // extensions, so will run on any x86_64 machine, even older ones 32 // 33 // - On ARM, the "_alt" forms target machines with higher multiplier 34 // throughput, generally offering higher performance there. 35 // ---------------------------------------------------------------------------- 36 37 // Add, z := x + y 38 // Inputs x[m], y[n]; outputs function return (carry-out) and z[p] 39 extern uint64_t bignum_add (uint64_t p, uint64_t *z, uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 40 41 // Add modulo p_25519, z := (x + y) mod p_25519, assuming x and y reduced 42 // Inputs x[4], y[4]; output z[4] 43 extern void bignum_add_p25519 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 44 45 // Add modulo p_256, z := (x + y) mod p_256, assuming x and y reduced 46 // Inputs x[4], y[4]; output z[4] 47 extern void bignum_add_p256 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 48 49 // Add modulo p_256k1, z := (x + y) mod p_256k1, assuming x and y reduced 50 // Inputs x[4], y[4]; output z[4] 51 extern void bignum_add_p256k1 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 52 53 // Add modulo p_384, z := (x + y) mod p_384, assuming x and y reduced 54 // Inputs x[6], y[6]; output z[6] 55 extern void bignum_add_p384 (uint64_t z[static 6], uint64_t x[static 6], uint64_t y[static 6]); 56 57 // Add modulo p_521, z := (x + y) mod p_521, assuming x and y reduced 58 // Inputs x[9], y[9]; output z[9] 59 extern void bignum_add_p521 (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); 60 61 // Compute "amontification" constant z :== 2^{128k} (congruent mod m) 62 // Input m[k]; output z[k]; temporary buffer t[>=k] 63 extern void bignum_amontifier (uint64_t k, uint64_t *z, uint64_t *m, uint64_t *t); 64 65 // Almost-Montgomery multiply, z :== (x * y / 2^{64k}) (congruent mod m) 66 // Inputs x[k], y[k], m[k]; output z[k] 67 extern void bignum_amontmul (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y, uint64_t *m); 68 69 // Almost-Montgomery reduce, z :== (x' / 2^{64p}) (congruent mod m) 70 // Inputs x[n], m[k], p; output z[k] 71 extern void bignum_amontredc (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t *m, uint64_t p); 72 73 // Almost-Montgomery square, z :== (x^2 / 2^{64k}) (congruent mod m) 74 // Inputs x[k], m[k]; output z[k] 75 extern void bignum_amontsqr (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *m); 76 77 // Convert 4-digit (256-bit) bignum to/from big-endian form 78 // Input x[4]; output z[4] 79 extern void bignum_bigendian_4 (uint64_t z[static 4], uint64_t x[static 4]); 80 81 // Convert 6-digit (384-bit) bignum to/from big-endian form 82 // Input x[6]; output z[6] 83 extern void bignum_bigendian_6 (uint64_t z[static 6], uint64_t x[static 6]); 84 85 // Select bitfield starting at bit n with length l <= 64 86 // Inputs x[k], n, l; output function return 87 extern uint64_t bignum_bitfield (uint64_t k, uint64_t *x, uint64_t n, uint64_t l); 88 89 // Return size of bignum in bits 90 // Input x[k]; output function return 91 extern uint64_t bignum_bitsize (uint64_t k, uint64_t *x); 92 93 // 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] 95 extern uint64_t bignum_cdiv (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t m); 96 97 // Divide by a single word, z := x / m when known to be exact 98 // Inputs x[n], m; output z[k] 99 extern void bignum_cdiv_exact (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t m); 100 101 // Count leading zero digits (64-bit words) 102 // Input x[k]; output function return 103 extern uint64_t bignum_cld (uint64_t k, uint64_t *x); 104 105 // Count leading zero bits 106 // Input x[k]; output function return 107 extern uint64_t bignum_clz (uint64_t k, uint64_t *x); 108 109 // Multiply-add with single-word multiplier, z := z + c * y 110 // Inputs c, y[n]; outputs function return (carry-out) and z[k] 111 extern uint64_t bignum_cmadd (uint64_t k, uint64_t *z, uint64_t c, uint64_t n, uint64_t *y); 112 113 // 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] 115 extern uint64_t bignum_cmnegadd (uint64_t k, uint64_t *z, uint64_t c, uint64_t n, uint64_t *y); 116 117 // Find modulus of bignum w.r.t. single nonzero word m, returning x mod m 118 // Input x[k], m; output function return 119 extern uint64_t bignum_cmod (uint64_t k, uint64_t *x, uint64_t m); 120 121 // Multiply by a single word, z := c * y 122 // Inputs c, y[n]; outputs function return (carry-out) and z[k] 123 extern uint64_t bignum_cmul (uint64_t k, uint64_t *z, uint64_t c, uint64_t n, uint64_t *y); 124 125 // 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] 127 extern void bignum_cmul_p25519 (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); 128 extern void bignum_cmul_p25519_alt (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); 129 130 // 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] 132 extern void bignum_cmul_p256 (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); 133 extern void bignum_cmul_p256_alt (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); 134 135 // 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] 137 extern void bignum_cmul_p256k1 (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); 138 extern void bignum_cmul_p256k1_alt (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); 139 140 // 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] 142 extern void bignum_cmul_p384 (uint64_t z[static 6], uint64_t c, uint64_t x[static 6]); 143 extern void bignum_cmul_p384_alt (uint64_t z[static 6], uint64_t c, uint64_t x[static 6]); 144 145 // 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] 147 extern void bignum_cmul_p521 (uint64_t z[static 9], uint64_t c, uint64_t x[static 9]); 148 extern void bignum_cmul_p521_alt (uint64_t z[static 9], uint64_t c, uint64_t x[static 9]); 149 150 // Test bignums for coprimality, gcd(x,y) = 1 151 // Inputs x[m], y[n]; output function return; temporary buffer t[>=2*max(m,n)] 152 extern uint64_t bignum_coprime (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y, uint64_t *t); 153 154 // Copy bignum with zero-extension or truncation, z := x 155 // Input x[n]; output z[k] 156 extern void bignum_copy (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x); 157 158 // Count trailing zero digits (64-bit words) 159 // Input x[k]; output function return 160 extern uint64_t bignum_ctd (uint64_t k, uint64_t *x); 161 162 // Count trailing zero bits 163 // Input x[k]; output function return 164 extern uint64_t bignum_ctz (uint64_t k, uint64_t *x); 165 166 // Convert from almost-Montgomery form, z := (x / 2^256) mod p_256 167 // Input x[4]; output z[4] 168 extern void bignum_deamont_p256 (uint64_t z[static 4], uint64_t x[static 4]); 169 extern void bignum_deamont_p256_alt (uint64_t z[static 4], uint64_t x[static 4]); 170 171 // Convert from almost-Montgomery form, z := (x / 2^256) mod p_256k1 172 // Input x[4]; output z[4] 173 extern void bignum_deamont_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 174 175 // Convert from almost-Montgomery form, z := (x / 2^384) mod p_384 176 // Input x[6]; output z[6] 177 extern void bignum_deamont_p384 (uint64_t z[static 6], uint64_t x[static 6]); 178 extern void bignum_deamont_p384_alt (uint64_t z[static 6], uint64_t x[static 6]); 179 180 // Convert from almost-Montgomery form z := (x / 2^576) mod p_521 181 // Input x[9]; output z[9] 182 extern void bignum_deamont_p521 (uint64_t z[static 9], uint64_t x[static 9]); 183 184 // Convert from (almost-)Montgomery form z := (x / 2^{64k}) mod m 185 // Inputs x[k], m[k]; output z[k] 186 extern void bignum_demont (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *m); 187 188 // Convert from Montgomery form z := (x / 2^256) mod p_256, assuming x reduced 189 // Input x[4]; output z[4] 190 extern void bignum_demont_p256 (uint64_t z[static 4], uint64_t x[static 4]); 191 extern void bignum_demont_p256_alt (uint64_t z[static 4], uint64_t x[static 4]); 192 193 // Convert from Montgomery form z := (x / 2^256) mod p_256k1, assuming x reduced 194 // Input x[4]; output z[4] 195 extern void bignum_demont_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 196 197 // Convert from Montgomery form z := (x / 2^384) mod p_384, assuming x reduced 198 // Input x[6]; output z[6] 199 extern void bignum_demont_p384 (uint64_t z[static 6], uint64_t x[static 6]); 200 extern void bignum_demont_p384_alt (uint64_t z[static 6], uint64_t x[static 6]); 201 202 // Convert from Montgomery form z := (x / 2^576) mod p_521, assuming x reduced 203 // Input x[9]; output z[9] 204 extern void bignum_demont_p521 (uint64_t z[static 9], uint64_t x[static 9]); 205 206 // Select digit x[n] 207 // Inputs x[k], n; output function return 208 extern uint64_t bignum_digit (uint64_t k, uint64_t *x, uint64_t n); 209 210 // Return size of bignum in digits (64-bit word) 211 // Input x[k]; output function return 212 extern uint64_t bignum_digitsize (uint64_t k, uint64_t *x); 213 214 // Divide bignum by 10: z' := z div 10, returning remainder z mod 10 215 // Inputs z[k]; outputs function return (remainder) and z[k] 216 extern uint64_t bignum_divmod10 (uint64_t k, uint64_t *z); 217 218 // Double modulo p_25519, z := (2 * x) mod p_25519, assuming x reduced 219 // Input x[4]; output z[4] 220 extern void bignum_double_p25519 (uint64_t z[static 4], uint64_t x[static 4]); 221 222 // Double modulo p_256, z := (2 * x) mod p_256, assuming x reduced 223 // Input x[4]; output z[4] 224 extern void bignum_double_p256 (uint64_t z[static 4], uint64_t x[static 4]); 225 226 // Double modulo p_256k1, z := (2 * x) mod p_256k1, assuming x reduced 227 // Input x[4]; output z[4] 228 extern void bignum_double_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 229 230 // Double modulo p_384, z := (2 * x) mod p_384, assuming x reduced 231 // Input x[6]; output z[6] 232 extern void bignum_double_p384 (uint64_t z[static 6], uint64_t x[static 6]); 233 234 // Double modulo p_521, z := (2 * x) mod p_521, assuming x reduced 235 // Input x[9]; output z[9] 236 extern void bignum_double_p521 (uint64_t z[static 9], uint64_t x[static 9]); 237 238 // 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] 240 extern uint64_t bignum_emontredc (uint64_t k, uint64_t *z, uint64_t *m, uint64_t w); 241 242 // 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] 244 extern uint64_t bignum_emontredc_8n (uint64_t k, uint64_t *z, uint64_t *m, uint64_t w); 245 246 // Test bignums for equality, x = y 247 // Inputs x[m], y[n]; output function return 248 extern uint64_t bignum_eq (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 249 250 // Test bignum for even-ness 251 // Input x[k]; output function return 252 extern uint64_t bignum_even (uint64_t k, uint64_t *x); 253 254 // Convert 4-digit (256-bit) bignum from big-endian bytes 255 // Input x[32] (bytes); output z[4] 256 extern void bignum_frombebytes_4 (uint64_t z[static 4], uint8_t x[static 32]); 257 258 // Convert 6-digit (384-bit) bignum from big-endian bytes 259 // Input x[48] (bytes); output z[6] 260 extern void bignum_frombebytes_6 (uint64_t z[static 6], uint8_t x[static 48]); 261 262 // Convert 4-digit (256-bit) bignum from little-endian bytes 263 // Input x[32] (bytes); output z[4] 264 extern void bignum_fromlebytes_4 (uint64_t z[static 4], uint8_t x[static 32]); 265 266 // Convert 6-digit (384-bit) bignum from little-endian bytes 267 // Input x[48] (bytes); output z[6] 268 extern void bignum_fromlebytes_6 (uint64_t z[static 6], uint8_t x[static 48]); 269 270 // Convert little-endian bytes to 9-digit 528-bit bignum 271 // Input x[66] (bytes); output z[9] 272 extern void bignum_fromlebytes_p521 (uint64_t z[static 9],uint8_t x[static 66]); 273 274 // Compare bignums, x >= y 275 // Inputs x[m], y[n]; output function return 276 extern uint64_t bignum_ge (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 277 278 // Compare bignums, x > y 279 // Inputs x[m], y[n]; output function return 280 extern uint64_t bignum_gt (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 281 282 // Halve modulo p_256, z := (x / 2) mod p_256, assuming x reduced 283 // Input x[4]; output z[4] 284 extern void bignum_half_p256 (uint64_t z[static 4], uint64_t x[static 4]); 285 286 // Halve modulo p_256k1, z := (x / 2) mod p_256k1, assuming x reduced 287 // Input x[4]; output z[4] 288 extern void bignum_half_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 289 290 // Halve modulo p_384, z := (x / 2) mod p_384, assuming x reduced 291 // Input x[6]; output z[6] 292 extern void bignum_half_p384 (uint64_t z[static 6], uint64_t x[static 6]); 293 294 // Halve modulo p_521, z := (x / 2) mod p_521, assuming x reduced 295 // Input x[9]; output z[9] 296 extern void bignum_half_p521 (uint64_t z[static 9], uint64_t x[static 9]); 297 298 // Test bignum for zero-ness, x = 0 299 // Input x[k]; output function return 300 extern uint64_t bignum_iszero (uint64_t k, uint64_t *x); 301 302 // Multiply z := x * y 303 // Inputs x[16], y[16]; output z[32]; temporary buffer t[>=32] 304 extern 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]); 305 306 // Multiply z := x * y 307 // Inputs x[32], y[32]; output z[64]; temporary buffer t[>=96] 308 extern 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]); 309 310 // Square, z := x^2 311 // Input x[16]; output z[32]; temporary buffer t[>=24] 312 extern void bignum_ksqr_16_32 (uint64_t z[static 32], uint64_t x[static 16], uint64_t t[static 24]); 313 314 // Square, z := x^2 315 // Input x[32]; output z[64]; temporary buffer t[>=72] 316 extern void bignum_ksqr_32_64 (uint64_t z[static 64], uint64_t x[static 32], uint64_t t[static 72]); 317 318 // Compare bignums, x <= y 319 // Inputs x[m], y[n]; output function return 320 extern uint64_t bignum_le (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 321 322 // Convert 4-digit (256-bit) bignum to/from little-endian form 323 // Input x[4]; output z[4] 324 extern void bignum_littleendian_4 (uint64_t z[static 4], uint64_t x[static 4]); 325 326 // Convert 6-digit (384-bit) bignum to/from little-endian form 327 // Input x[6]; output z[6] 328 extern void bignum_littleendian_6 (uint64_t z[static 6], uint64_t x[static 6]); 329 330 // Compare bignums, x < y 331 // Inputs x[m], y[n]; output function return 332 extern uint64_t bignum_lt (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 333 334 // Multiply-add, z := z + x * y 335 // Inputs x[m], y[n]; outputs function return (carry-out) and z[k] 336 extern uint64_t bignum_madd (uint64_t k, uint64_t *z, uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 337 338 // Reduce modulo group order, z := x mod n_256 339 // Input x[k]; output z[4] 340 extern void bignum_mod_n256 (uint64_t z[static 4], uint64_t k, uint64_t *x); 341 extern void bignum_mod_n256_alt (uint64_t z[static 4], uint64_t k, uint64_t *x); 342 343 // Reduce modulo group order, z := x mod n_256 344 // Input x[4]; output z[4] 345 extern void bignum_mod_n256_4 (uint64_t z[static 4], uint64_t x[static 4]); 346 347 // Reduce modulo group order, z := x mod n_256k1 348 // Input x[4]; output z[4] 349 extern void bignum_mod_n256k1_4 (uint64_t z[static 4], uint64_t x[static 4]); 350 351 // Reduce modulo group order, z := x mod n_384 352 // Input x[k]; output z[6] 353 extern void bignum_mod_n384 (uint64_t z[static 6], uint64_t k, uint64_t *x); 354 extern void bignum_mod_n384_alt (uint64_t z[static 6], uint64_t k, uint64_t *x); 355 356 // Reduce modulo group order, z := x mod n_384 357 // Input x[6]; output z[6] 358 extern void bignum_mod_n384_6 (uint64_t z[static 6], uint64_t x[static 6]); 359 360 // Reduce modulo group order, z := x mod n_521 361 // Input x[9]; output z[9] 362 extern void bignum_mod_n521_9 (uint64_t z[static 9], uint64_t x[static 9]); 363 extern void bignum_mod_n521_9_alt (uint64_t z[static 9], uint64_t x[static 9]); 364 365 // Reduce modulo field characteristic, z := x mod p_25519 366 // Input x[4]; output z[4] 367 extern void bignum_mod_p25519_4 (uint64_t z[static 4], uint64_t x[static 4]); 368 369 // Reduce modulo field characteristic, z := x mod p_256 370 // Input x[k]; output z[4] 371 extern void bignum_mod_p256 (uint64_t z[static 4], uint64_t k, uint64_t *x); 372 extern void bignum_mod_p256_alt (uint64_t z[static 4], uint64_t k, uint64_t *x); 373 374 // Reduce modulo field characteristic, z := x mod p_256 375 // Input x[4]; output z[4] 376 extern void bignum_mod_p256_4 (uint64_t z[static 4], uint64_t x[static 4]); 377 378 // Reduce modulo field characteristic, z := x mod p_256k1 379 // Input x[4]; output z[4] 380 extern void bignum_mod_p256k1_4 (uint64_t z[static 4], uint64_t x[static 4]); 381 382 // Reduce modulo field characteristic, z := x mod p_384 383 // Input x[k]; output z[6] 384 extern void bignum_mod_p384 (uint64_t z[static 6], uint64_t k, uint64_t *x); 385 extern void bignum_mod_p384_alt (uint64_t z[static 6], uint64_t k, uint64_t *x); 386 387 // Reduce modulo field characteristic, z := x mod p_384 388 // Input x[6]; output z[6] 389 extern void bignum_mod_p384_6 (uint64_t z[static 6], uint64_t x[static 6]); 390 391 // Reduce modulo field characteristic, z := x mod p_521 392 // Input x[9]; output z[9] 393 extern void bignum_mod_p521_9 (uint64_t z[static 9], uint64_t x[static 9]); 394 395 // Add modulo m, z := (x + y) mod m, assuming x and y reduced 396 // Inputs x[k], y[k], m[k]; output z[k] 397 extern void bignum_modadd (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y, uint64_t *m); 398 399 // Double modulo m, z := (2 * x) mod m, assuming x reduced 400 // Inputs x[k], m[k]; output z[k] 401 extern void bignum_moddouble (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *m); 402 403 // Compute "modification" constant z := 2^{64k} mod m 404 // Input m[k]; output z[k]; temporary buffer t[>=k] 405 extern void bignum_modifier (uint64_t k, uint64_t *z, uint64_t *m, uint64_t *t); 406 407 // 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] 409 extern void bignum_modinv (uint64_t k, uint64_t *z, uint64_t *a, uint64_t *b, uint64_t *t); 410 411 // 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] 413 extern void bignum_modoptneg (uint64_t k, uint64_t *z, uint64_t p, uint64_t *x, uint64_t *m); 414 415 // Subtract modulo m, z := (x - y) mod m, assuming x and y reduced 416 // Inputs x[k], y[k], m[k]; output z[k] 417 extern void bignum_modsub (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y, uint64_t *m); 418 419 // Compute "montification" constant z := 2^{128k} mod m 420 // Input m[k]; output z[k]; temporary buffer t[>=k] 421 extern void bignum_montifier (uint64_t k, uint64_t *z, uint64_t *m, uint64_t *t); 422 423 // Montgomery multiply, z := (x * y / 2^{64k}) mod m 424 // Inputs x[k], y[k], m[k]; output z[k] 425 extern void bignum_montmul (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y, uint64_t *m); 426 427 // Montgomery multiply, z := (x * y / 2^256) mod p_256 428 // Inputs x[4], y[4]; output z[4] 429 extern void bignum_montmul_p256 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 430 extern void bignum_montmul_p256_alt (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 431 432 // Montgomery multiply, z := (x * y / 2^256) mod p_256k1 433 // Inputs x[4], y[4]; output z[4] 434 extern void bignum_montmul_p256k1 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 435 extern void bignum_montmul_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 436 437 // Montgomery multiply, z := (x * y / 2^384) mod p_384 438 // Inputs x[6], y[6]; output z[6] 439 extern void bignum_montmul_p384 (uint64_t z[static 6], uint64_t x[static 6], uint64_t y[static 6]); 440 extern void bignum_montmul_p384_alt (uint64_t z[static 6], uint64_t x[static 6], uint64_t y[static 6]); 441 442 // Montgomery multiply, z := (x * y / 2^576) mod p_521 443 // Inputs x[9], y[9]; output z[9] 444 extern void bignum_montmul_p521 (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); 445 extern void bignum_montmul_p521_alt (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); 446 447 // Montgomery reduce, z := (x' / 2^{64p}) MOD m 448 // Inputs x[n], m[k], p; output z[k] 449 extern void bignum_montredc (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t *m, uint64_t p); 450 451 // Montgomery square, z := (x^2 / 2^{64k}) mod m 452 // Inputs x[k], m[k]; output z[k] 453 extern void bignum_montsqr (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *m); 454 455 // Montgomery square, z := (x^2 / 2^256) mod p_256 456 // Input x[4]; output z[4] 457 extern void bignum_montsqr_p256 (uint64_t z[static 4], uint64_t x[static 4]); 458 extern void bignum_montsqr_p256_alt (uint64_t z[static 4], uint64_t x[static 4]); 459 460 // Montgomery square, z := (x^2 / 2^256) mod p_256k1 461 // Input x[4]; output z[4] 462 extern void bignum_montsqr_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 463 extern void bignum_montsqr_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4]); 464 465 // Montgomery square, z := (x^2 / 2^384) mod p_384 466 // Input x[6]; output z[6] 467 extern void bignum_montsqr_p384 (uint64_t z[static 6], uint64_t x[static 6]); 468 extern void bignum_montsqr_p384_alt (uint64_t z[static 6], uint64_t x[static 6]); 469 470 // Montgomery square, z := (x^2 / 2^576) mod p_521 471 // Input x[9]; output z[9] 472 extern void bignum_montsqr_p521 (uint64_t z[static 9], uint64_t x[static 9]); 473 extern void bignum_montsqr_p521_alt (uint64_t z[static 9], uint64_t x[static 9]); 474 475 // Multiply z := x * y 476 // Inputs x[m], y[n]; output z[k] 477 extern void bignum_mul (uint64_t k, uint64_t *z, uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 478 479 // Multiply z := x * y 480 // Inputs x[4], y[4]; output z[8] 481 extern void bignum_mul_4_8 (uint64_t z[static 8], uint64_t x[static 4], uint64_t y[static 4]); 482 extern void bignum_mul_4_8_alt (uint64_t z[static 8], uint64_t x[static 4], uint64_t y[static 4]); 483 484 // Multiply z := x * y 485 // Inputs x[6], y[6]; output z[12] 486 extern void bignum_mul_6_12 (uint64_t z[static 12], uint64_t x[static 6], uint64_t y[static 6]); 487 extern void bignum_mul_6_12_alt (uint64_t z[static 12], uint64_t x[static 6], uint64_t y[static 6]); 488 489 // Multiply z := x * y 490 // Inputs x[8], y[8]; output z[16] 491 extern void bignum_mul_8_16 (uint64_t z[static 16], uint64_t x[static 8], uint64_t y[static 8]); 492 extern void bignum_mul_8_16_alt (uint64_t z[static 16], uint64_t x[static 8], uint64_t y[static 8]); 493 494 // Multiply modulo p_25519, z := (x * y) mod p_25519 495 // Inputs x[4], y[4]; output z[4] 496 extern void bignum_mul_p25519 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 497 extern void bignum_mul_p25519_alt (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 498 499 // Multiply modulo p_256k1, z := (x * y) mod p_256k1 500 // Inputs x[4], y[4]; output z[4] 501 extern void bignum_mul_p256k1 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 502 extern void bignum_mul_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 503 504 // Multiply modulo p_521, z := (x * y) mod p_521, assuming x and y reduced 505 // Inputs x[9], y[9]; output z[9] 506 extern void bignum_mul_p521 (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); 507 extern void bignum_mul_p521_alt (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); 508 509 // Multiply bignum by 10 and add word: z := 10 * z + d 510 // Inputs z[k], d; outputs function return (carry) and z[k] 511 extern uint64_t bignum_muladd10 (uint64_t k, uint64_t *z, uint64_t d); 512 513 // Multiplex/select z := x (if p nonzero) or z := y (if p zero) 514 // Inputs p, x[k], y[k]; output z[k] 515 extern void bignum_mux (uint64_t p, uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y); 516 517 // 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] 519 extern void bignum_mux_4 (uint64_t p, uint64_t z[static 4],uint64_t x[static 4], uint64_t y[static 4]); 520 521 // 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] 523 extern void bignum_mux_6 (uint64_t p, uint64_t z[static 6],uint64_t x[static 6], uint64_t y[static 6]); 524 525 // Select element from 16-element table, z := xs[k*i] 526 // Inputs xs[16*k], i; output z[k] 527 extern void bignum_mux16 (uint64_t k, uint64_t *z, uint64_t *xs, uint64_t i); 528 529 // Negate modulo p_25519, z := (-x) mod p_25519, assuming x reduced 530 // Input x[4]; output z[4] 531 extern void bignum_neg_p25519 (uint64_t z[static 4], uint64_t x[static 4]); 532 533 // Negate modulo p_256, z := (-x) mod p_256, assuming x reduced 534 // Input x[4]; output z[4] 535 extern void bignum_neg_p256 (uint64_t z[static 4], uint64_t x[static 4]); 536 537 // Negate modulo p_256k1, z := (-x) mod p_256k1, assuming x reduced 538 // Input x[4]; output z[4] 539 extern void bignum_neg_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 540 541 // Negate modulo p_384, z := (-x) mod p_384, assuming x reduced 542 // Input x[6]; output z[6] 543 extern void bignum_neg_p384 (uint64_t z[static 6], uint64_t x[static 6]); 544 545 // Negate modulo p_521, z := (-x) mod p_521, assuming x reduced 546 // Input x[9]; output z[9] 547 extern void bignum_neg_p521 (uint64_t z[static 9], uint64_t x[static 9]); 548 549 // Negated modular inverse, z := (-1/x) mod 2^{64k} 550 // Input x[k]; output z[k] 551 extern void bignum_negmodinv (uint64_t k, uint64_t *z, uint64_t *x); 552 553 // Test bignum for nonzero-ness x =/= 0 554 // Input x[k]; output function return 555 extern uint64_t bignum_nonzero (uint64_t k, uint64_t *x); 556 557 // Test 256-bit bignum for nonzero-ness x =/= 0 558 // Input x[4]; output function return 559 extern uint64_t bignum_nonzero_4(uint64_t x[static 4]); 560 561 // Test 384-bit bignum for nonzero-ness x =/= 0 562 // Input x[6]; output function return 563 extern uint64_t bignum_nonzero_6(uint64_t x[static 6]); 564 565 // 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] 567 extern uint64_t bignum_normalize (uint64_t k, uint64_t *z); 568 569 // Test bignum for odd-ness 570 // Input x[k]; output function return 571 extern uint64_t bignum_odd (uint64_t k, uint64_t *x); 572 573 // Convert single digit to bignum, z := n 574 // Input n; output z[k] 575 extern void bignum_of_word (uint64_t k, uint64_t *z, uint64_t n); 576 577 // 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] 579 extern uint64_t bignum_optadd (uint64_t k, uint64_t *z, uint64_t *x, uint64_t p, uint64_t *y); 580 581 // 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] 583 extern uint64_t bignum_optneg (uint64_t k, uint64_t *z, uint64_t p, uint64_t *x); 584 585 // 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] 587 extern void bignum_optneg_p25519 (uint64_t z[static 4], uint64_t p, uint64_t x[static 4]); 588 589 // 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] 591 extern void bignum_optneg_p256 (uint64_t z[static 4], uint64_t p, uint64_t x[static 4]); 592 593 // 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] 595 extern void bignum_optneg_p256k1 (uint64_t z[static 4], uint64_t p, uint64_t x[static 4]); 596 597 // 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] 599 extern void bignum_optneg_p384 (uint64_t z[static 6], uint64_t p, uint64_t x[static 6]); 600 601 // 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] 603 extern void bignum_optneg_p521 (uint64_t z[static 9], uint64_t p, uint64_t x[static 9]); 604 605 // 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] 607 extern uint64_t bignum_optsub (uint64_t k, uint64_t *z, uint64_t *x, uint64_t p, uint64_t *y); 608 609 // 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] 611 extern uint64_t bignum_optsubadd (uint64_t k, uint64_t *z, uint64_t *x, uint64_t p, uint64_t *y); 612 613 // Return bignum of power of 2, z := 2^n 614 // Input n; output z[k] 615 extern void bignum_pow2 (uint64_t k, uint64_t *z, uint64_t n); 616 617 // Shift bignum left by c < 64 bits z := x * 2^c 618 // Inputs x[n], c; outputs function return (carry-out) and z[k] 619 extern uint64_t bignum_shl_small (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t c); 620 621 // 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] 623 extern uint64_t bignum_shr_small (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t c); 624 625 // Square, z := x^2 626 // Input x[n]; output z[k] 627 extern void bignum_sqr (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x); 628 629 // Square, z := x^2 630 // Input x[4]; output z[8] 631 extern void bignum_sqr_4_8 (uint64_t z[static 8], uint64_t x[static 4]); 632 extern void bignum_sqr_4_8_alt (uint64_t z[static 8], uint64_t x[static 4]); 633 634 // Square, z := x^2 635 // Input x[6]; output z[12] 636 extern void bignum_sqr_6_12 (uint64_t z[static 12], uint64_t x[static 6]); 637 extern void bignum_sqr_6_12_alt (uint64_t z[static 12], uint64_t x[static 6]); 638 639 // Square, z := x^2 640 // Input x[8]; output z[16] 641 extern void bignum_sqr_8_16 (uint64_t z[static 16], uint64_t x[static 8]); 642 extern void bignum_sqr_8_16_alt (uint64_t z[static 16], uint64_t x[static 8]); 643 644 // Square modulo p_25519, z := (x^2) mod p_25519 645 // Input x[4]; output z[4] 646 extern void bignum_sqr_p25519 (uint64_t z[static 4], uint64_t x[static 4]); 647 extern void bignum_sqr_p25519_alt (uint64_t z[static 4], uint64_t x[static 4]); 648 649 // Square modulo p_256k1, z := (x^2) mod p_256k1 650 // Input x[4]; output z[4] 651 extern void bignum_sqr_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 652 extern void bignum_sqr_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4]); 653 654 // Square modulo p_521, z := (x^2) mod p_521, assuming x reduced 655 // Input x[9]; output z[9] 656 extern void bignum_sqr_p521 (uint64_t z[static 9], uint64_t x[static 9]); 657 extern void bignum_sqr_p521_alt (uint64_t z[static 9], uint64_t x[static 9]); 658 659 // Subtract, z := x - y 660 // Inputs x[m], y[n]; outputs function return (carry-out) and z[p] 661 extern uint64_t bignum_sub (uint64_t p, uint64_t *z, uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 662 663 // Subtract modulo p_25519, z := (x - y) mod p_25519, assuming x and y reduced 664 // Inputs x[4], y[4]; output z[4] 665 extern void bignum_sub_p25519 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 666 667 // Subtract modulo p_256, z := (x - y) mod p_256, assuming x and y reduced 668 // Inputs x[4], y[4]; output z[4] 669 extern void bignum_sub_p256 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 670 671 // Subtract modulo p_256k1, z := (x - y) mod p_256k1, assuming x and y reduced 672 // Inputs x[4], y[4]; output z[4] 673 extern void bignum_sub_p256k1 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 674 675 // Subtract modulo p_384, z := (x - y) mod p_384, assuming x and y reduced 676 // Inputs x[6], y[6]; output z[6] 677 extern void bignum_sub_p384 (uint64_t z[static 6], uint64_t x[static 6], uint64_t y[static 6]); 678 679 // Subtract modulo p_521, z := (x - y) mod p_521, assuming x and y reduced 680 // Inputs x[9], y[9]; output z[9] 681 extern void bignum_sub_p521 (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); 682 683 // Convert 4-digit (256-bit) bignum to big-endian bytes 684 // Input x[4]; output z[32] (bytes) 685 extern void bignum_tobebytes_4 (uint8_t z[static 32], uint64_t x[static 4]); 686 687 // Convert 6-digit (384-bit) bignum to big-endian bytes 688 // Input x[6]; output z[48] (bytes) 689 extern void bignum_tobebytes_6 (uint8_t z[static 48], uint64_t x[static 6]); 690 691 // Convert 4-digit (256-bit) bignum to little-endian bytes 692 // Input x[4]; output z[32] (bytes) 693 extern void bignum_tolebytes_4 (uint8_t z[static 32], uint64_t x[static 4]); 694 695 // Convert 6-digit (384-bit) bignum to little-endian bytes 696 // Input x[6]; output z[48] (bytes) 697 extern void bignum_tolebytes_6 (uint8_t z[static 48], uint64_t x[static 6]); 698 699 // Convert 9-digit 528-bit bignum to little-endian bytes 700 // Input x[6]; output z[66] (bytes) 701 extern void bignum_tolebytes_p521 (uint8_t z[static 66], uint64_t x[static 9]); 702 703 // Convert to Montgomery form z := (2^256 * x) mod p_256 704 // Input x[4]; output z[4] 705 extern void bignum_tomont_p256 (uint64_t z[static 4], uint64_t x[static 4]); 706 extern void bignum_tomont_p256_alt (uint64_t z[static 4], uint64_t x[static 4]); 707 708 // Convert to Montgomery form z := (2^256 * x) mod p_256k1 709 // Input x[4]; output z[4] 710 extern void bignum_tomont_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 711 extern void bignum_tomont_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4]); 712 713 // Convert to Montgomery form z := (2^384 * x) mod p_384 714 // Input x[6]; output z[6] 715 extern void bignum_tomont_p384 (uint64_t z[static 6], uint64_t x[static 6]); 716 extern void bignum_tomont_p384_alt (uint64_t z[static 6], uint64_t x[static 6]); 717 718 // Convert to Montgomery form z := (2^576 * x) mod p_521 719 // Input x[9]; output z[9] 720 extern void bignum_tomont_p521 (uint64_t z[static 9], uint64_t x[static 9]); 721 722 // Triple modulo p_256, z := (3 * x) mod p_256 723 // Input x[4]; output z[4] 724 extern void bignum_triple_p256 (uint64_t z[static 4], uint64_t x[static 4]); 725 extern void bignum_triple_p256_alt (uint64_t z[static 4], uint64_t x[static 4]); 726 727 // Triple modulo p_256k1, z := (3 * x) mod p_256k1 728 // Input x[4]; output z[4] 729 extern void bignum_triple_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 730 extern void bignum_triple_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4]); 731 732 // Triple modulo p_384, z := (3 * x) mod p_384 733 // Input x[6]; output z[6] 734 extern void bignum_triple_p384 (uint64_t z[static 6], uint64_t x[static 6]); 735 extern void bignum_triple_p384_alt (uint64_t z[static 6], uint64_t x[static 6]); 736 737 // Triple modulo p_521, z := (3 * x) mod p_521, assuming x reduced 738 // Input x[9]; output z[9] 739 extern void bignum_triple_p521 (uint64_t z[static 9], uint64_t x[static 9]); 740 extern void bignum_triple_p521_alt (uint64_t z[static 9], uint64_t x[static 9]); 741 742 // Montgomery ladder step for curve25519 743 // Inputs point[8], pp[16], b; output rr[16] 744 extern void curve25519_ladderstep(uint64_t rr[16],uint64_t point[8],uint64_t pp[16],uint64_t b); 745 extern void curve25519_ladderstep_alt(uint64_t rr[16],uint64_t point[8],uint64_t pp[16],uint64_t b); 746 747 // Projective scalar multiplication, x coordinate only, for curve25519 748 // Inputs scalar[4], point[4]; output res[8] 749 extern void curve25519_pxscalarmul(uint64_t res[static 8],uint64_t scalar[static 4],uint64_t point[static 4]); 750 extern void curve25519_pxscalarmul_alt(uint64_t res[static 8],uint64_t scalar[static 4],uint64_t point[static 4]); 751 752 // x25519 function for curve25519 753 // Inputs scalar[4], point[4]; output res[4] 754 extern void curve25519_x25519(uint64_t res[static 4],uint64_t scalar[static 4],uint64_t point[static 4]); 755 extern void curve25519_x25519_alt(uint64_t res[static 4],uint64_t scalar[static 4],uint64_t point[static 4]); 756 757 // x25519 function for curve25519 on base element 9 758 // Input scalar[4]; output res[4] 759 extern void curve25519_x25519base(uint64_t res[static 4],uint64_t scalar[static 4]); 760 extern void curve25519_x25519base_alt(uint64_t res[static 4],uint64_t scalar[static 4]); 761 762 // Extended projective addition for edwards25519 763 // Inputs p1[16], p2[16]; output p3[16] 764 extern void edwards25519_epadd(uint64_t p3[static 16],uint64_t p1[static 16],uint64_t p2[static 16]); 765 extern void edwards25519_epadd_alt(uint64_t p3[static 16],uint64_t p1[static 16],uint64_t p2[static 16]); 766 767 // Extended projective doubling for edwards25519 768 // Inputs p1[12]; output p3[16] 769 extern void edwards25519_epdouble(uint64_t p3[static 16],uint64_t p1[static 12]); 770 extern void edwards25519_epdouble_alt(uint64_t p3[static 16],uint64_t p1[static 12]); 771 772 // Projective doubling for edwards25519 773 // Inputs p1[12]; output p3[12] 774 extern void edwards25519_pdouble(uint64_t p3[static 12],uint64_t p1[static 12]); 775 extern void edwards25519_pdouble_alt(uint64_t p3[static 12],uint64_t p1[static 12]); 776 777 // Extended projective + precomputed mixed addition for edwards25519 778 // Inputs p1[16], p2[12]; output p3[16] 779 extern void edwards25519_pepadd(uint64_t p3[static 16],uint64_t p1[static 16],uint64_t p2[static 12]); 780 extern void edwards25519_pepadd_alt(uint64_t p3[static 16],uint64_t p1[static 16],uint64_t p2[static 12]); 781 782 // Point addition on NIST curve P-256 in Montgomery-Jacobian coordinates 783 // Inputs p1[12], p2[12]; output p3[12] 784 extern void p256_montjadd(uint64_t p3[static 12],uint64_t p1[static 12],uint64_t p2[static 12]); 785 786 // Point doubling on NIST curve P-256 in Montgomery-Jacobian coordinates 787 // Inputs p1[12]; output p3[12] 788 extern void p256_montjdouble(uint64_t p3[static 12],uint64_t p1[static 12]); 789 790 // Point mixed addition on NIST curve P-256 in Montgomery-Jacobian coordinates 791 // Inputs p1[12], p2[8]; output p3[12] 792 extern void p256_montjmixadd(uint64_t p3[static 12],uint64_t p1[static 12],uint64_t p2[static 8]); 793 794 // Point addition on NIST curve P-384 in Montgomery-Jacobian coordinates 795 // Inputs p1[18], p2[18]; output p3[18] 796 extern void p384_montjadd(uint64_t p3[static 18],uint64_t p1[static 18],uint64_t p2[static 18]); 797 798 // Point doubling on NIST curve P-384 in Montgomery-Jacobian coordinates 799 // Inputs p1[18]; output p3[18] 800 extern void p384_montjdouble(uint64_t p3[static 18],uint64_t p1[static 18]); 801 802 // Point mixed addition on NIST curve P-384 in Montgomery-Jacobian coordinates 803 // Inputs p1[18], p2[12]; output p3[18] 804 extern void p384_montjmixadd(uint64_t p3[static 18],uint64_t p1[static 18],uint64_t p2[static 12]); 805 806 // Point addition on NIST curve P-521 in Jacobian coordinates 807 // Inputs p1[27], p2[27]; output p3[27] 808 extern void p521_jadd(uint64_t p3[static 27],uint64_t p1[static 27],uint64_t p2[static 27]); 809 810 // Point doubling on NIST curve P-521 in Jacobian coordinates 811 // Input p1[27]; output p3[27] 812 extern void p521_jdouble(uint64_t p3[static 27],uint64_t p1[static 27]); 813 814 // Point mixed addition on NIST curve P-521 in Jacobian coordinates 815 // Inputs p1[27], p2[18]; output p3[27] 816 extern void p521_jmixadd(uint64_t p3[static 27],uint64_t p1[static 27],uint64_t p2[static 18]); 817 818 // Point addition on SECG curve secp256k1 in Jacobian coordinates 819 // Inputs p1[12], p2[12]; output p3[12] 820 extern void secp256k1_jadd(uint64_t p3[static 12],uint64_t p1[static 12],uint64_t p2[static 12]); 821 822 // Point doubling on SECG curve secp256k1 in Jacobian coordinates 823 // Input p1[12]; output p3[12] 824 extern void secp256k1_jdouble(uint64_t p3[static 12],uint64_t p1[static 12]); 825 826 // Point mixed addition on SECG curve secp256k1 in Jacobian coordinates 827 // Inputs p1[12], p2[8]; output p3[12] 828 extern void secp256k1_jmixadd(uint64_t p3[static 12],uint64_t p1[static 12],uint64_t p2[static 8]); 829 830 // Reverse the bytes in a single word 831 // Input a; output function return 832 extern uint64_t word_bytereverse (uint64_t a); 833 834 // Count leading zero bits in a single word 835 // Input a; output function return 836 extern uint64_t word_clz (uint64_t a); 837 838 // Count trailing zero bits in a single word 839 // Input a; output function return 840 extern uint64_t word_ctz (uint64_t a); 841 842 // Return maximum of two unsigned 64-bit words 843 // Inputs a, b; output function return 844 extern uint64_t word_max (uint64_t a, uint64_t b); 845 846 // Return minimum of two unsigned 64-bit words 847 // Inputs a, b; output function return 848 extern uint64_t word_min (uint64_t a, uint64_t b); 849 850 // Single-word negated modular inverse (-1/a) mod 2^64 851 // Input a; output function return 852 extern uint64_t word_negmodinv (uint64_t a); 853 854 // Single-word reciprocal, 2^64 + ret = ceil(2^128/a) - 1 if MSB of "a" is set 855 // Input a; output function return 856 extern uint64_t word_recip (uint64_t a); 857