13afee70eSjsing // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2*78843f4eSjsing // 3*78843f4eSjsing // Permission to use, copy, modify, and/or distribute this software for any 4*78843f4eSjsing // purpose with or without fee is hereby granted, provided that the above 5*78843f4eSjsing // copyright notice and this permission notice appear in all copies. 6*78843f4eSjsing // 7*78843f4eSjsing // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8*78843f4eSjsing // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9*78843f4eSjsing // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10*78843f4eSjsing // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11*78843f4eSjsing // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12*78843f4eSjsing // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13*78843f4eSjsing // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 143afee70eSjsing 153afee70eSjsing // ---------------------------------------------------------------------------- 163afee70eSjsing // C prototypes for s2n-bignum functions, so you can use them in C programs via 173afee70eSjsing // 183afee70eSjsing // #include "s2n-bignum.h" 193afee70eSjsing // 203afee70eSjsing // The functions are listed in alphabetical order with a brief description 213afee70eSjsing // in comments for each one. For more detailed documentation see the comment 223afee70eSjsing // banner at the top of the corresponding assembly (.S) file, and 233afee70eSjsing // for the last word in what properties it satisfies see the spec in the 243afee70eSjsing // formal proof (the .ml file in the architecture-specific directory). 253afee70eSjsing // 263afee70eSjsing // For some functions there are additional variants with names ending in 273afee70eSjsing // "_alt". These have the same core mathematical functionality as their 283afee70eSjsing // non-"alt" versions, but can be better suited to some microarchitectures: 293afee70eSjsing // 303afee70eSjsing // - On x86, the "_alt" forms avoid BMI and ADX instruction set 313afee70eSjsing // extensions, so will run on any x86_64 machine, even older ones 323afee70eSjsing // 333afee70eSjsing // - On ARM, the "_alt" forms target machines with higher multiplier 343afee70eSjsing // throughput, generally offering higher performance there. 353afee70eSjsing // ---------------------------------------------------------------------------- 363afee70eSjsing 373afee70eSjsing // Add, z := x + y 383afee70eSjsing // Inputs x[m], y[n]; outputs function return (carry-out) and z[p] 393afee70eSjsing extern uint64_t bignum_add (uint64_t p, uint64_t *z, uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 403afee70eSjsing 413afee70eSjsing // Add modulo p_25519, z := (x + y) mod p_25519, assuming x and y reduced 423afee70eSjsing // Inputs x[4], y[4]; output z[4] 433afee70eSjsing extern void bignum_add_p25519 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 443afee70eSjsing 453afee70eSjsing // Add modulo p_256, z := (x + y) mod p_256, assuming x and y reduced 463afee70eSjsing // Inputs x[4], y[4]; output z[4] 473afee70eSjsing extern void bignum_add_p256 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 483afee70eSjsing 493afee70eSjsing // Add modulo p_256k1, z := (x + y) mod p_256k1, assuming x and y reduced 503afee70eSjsing // Inputs x[4], y[4]; output z[4] 513afee70eSjsing extern void bignum_add_p256k1 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 523afee70eSjsing 533afee70eSjsing // Add modulo p_384, z := (x + y) mod p_384, assuming x and y reduced 543afee70eSjsing // Inputs x[6], y[6]; output z[6] 553afee70eSjsing extern void bignum_add_p384 (uint64_t z[static 6], uint64_t x[static 6], uint64_t y[static 6]); 563afee70eSjsing 573afee70eSjsing // Add modulo p_521, z := (x + y) mod p_521, assuming x and y reduced 583afee70eSjsing // Inputs x[9], y[9]; output z[9] 593afee70eSjsing extern void bignum_add_p521 (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); 603afee70eSjsing 613afee70eSjsing // Compute "amontification" constant z :== 2^{128k} (congruent mod m) 623afee70eSjsing // Input m[k]; output z[k]; temporary buffer t[>=k] 633afee70eSjsing extern void bignum_amontifier (uint64_t k, uint64_t *z, uint64_t *m, uint64_t *t); 643afee70eSjsing 653afee70eSjsing // Almost-Montgomery multiply, z :== (x * y / 2^{64k}) (congruent mod m) 663afee70eSjsing // Inputs x[k], y[k], m[k]; output z[k] 673afee70eSjsing extern void bignum_amontmul (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y, uint64_t *m); 683afee70eSjsing 693afee70eSjsing // Almost-Montgomery reduce, z :== (x' / 2^{64p}) (congruent mod m) 703afee70eSjsing // Inputs x[n], m[k], p; output z[k] 713afee70eSjsing extern void bignum_amontredc (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t *m, uint64_t p); 723afee70eSjsing 733afee70eSjsing // Almost-Montgomery square, z :== (x^2 / 2^{64k}) (congruent mod m) 743afee70eSjsing // Inputs x[k], m[k]; output z[k] 753afee70eSjsing extern void bignum_amontsqr (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *m); 763afee70eSjsing 773afee70eSjsing // Convert 4-digit (256-bit) bignum to/from big-endian form 783afee70eSjsing // Input x[4]; output z[4] 793afee70eSjsing extern void bignum_bigendian_4 (uint64_t z[static 4], uint64_t x[static 4]); 803afee70eSjsing 813afee70eSjsing // Convert 6-digit (384-bit) bignum to/from big-endian form 823afee70eSjsing // Input x[6]; output z[6] 833afee70eSjsing extern void bignum_bigendian_6 (uint64_t z[static 6], uint64_t x[static 6]); 843afee70eSjsing 853afee70eSjsing // Select bitfield starting at bit n with length l <= 64 863afee70eSjsing // Inputs x[k], n, l; output function return 873afee70eSjsing extern uint64_t bignum_bitfield (uint64_t k, uint64_t *x, uint64_t n, uint64_t l); 883afee70eSjsing 893afee70eSjsing // Return size of bignum in bits 903afee70eSjsing // Input x[k]; output function return 913afee70eSjsing extern uint64_t bignum_bitsize (uint64_t k, uint64_t *x); 923afee70eSjsing 933afee70eSjsing // Divide by a single (nonzero) word, z := x / m and return x mod m 943afee70eSjsing // Inputs x[n], m; outputs function return (remainder) and z[k] 953afee70eSjsing extern uint64_t bignum_cdiv (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t m); 963afee70eSjsing 973afee70eSjsing // Divide by a single word, z := x / m when known to be exact 983afee70eSjsing // Inputs x[n], m; output z[k] 993afee70eSjsing extern void bignum_cdiv_exact (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t m); 1003afee70eSjsing 1013afee70eSjsing // Count leading zero digits (64-bit words) 1023afee70eSjsing // Input x[k]; output function return 1033afee70eSjsing extern uint64_t bignum_cld (uint64_t k, uint64_t *x); 1043afee70eSjsing 1053afee70eSjsing // Count leading zero bits 1063afee70eSjsing // Input x[k]; output function return 1073afee70eSjsing extern uint64_t bignum_clz (uint64_t k, uint64_t *x); 1083afee70eSjsing 1093afee70eSjsing // Multiply-add with single-word multiplier, z := z + c * y 1103afee70eSjsing // Inputs c, y[n]; outputs function return (carry-out) and z[k] 1113afee70eSjsing extern uint64_t bignum_cmadd (uint64_t k, uint64_t *z, uint64_t c, uint64_t n, uint64_t *y); 1123afee70eSjsing 1133afee70eSjsing // Negated multiply-add with single-word multiplier, z := z - c * y 1143afee70eSjsing // Inputs c, y[n]; outputs function return (negative carry-out) and z[k] 1153afee70eSjsing extern uint64_t bignum_cmnegadd (uint64_t k, uint64_t *z, uint64_t c, uint64_t n, uint64_t *y); 1163afee70eSjsing 1173afee70eSjsing // Find modulus of bignum w.r.t. single nonzero word m, returning x mod m 1183afee70eSjsing // Input x[k], m; output function return 1193afee70eSjsing extern uint64_t bignum_cmod (uint64_t k, uint64_t *x, uint64_t m); 1203afee70eSjsing 1213afee70eSjsing // Multiply by a single word, z := c * y 1223afee70eSjsing // Inputs c, y[n]; outputs function return (carry-out) and z[k] 1233afee70eSjsing extern uint64_t bignum_cmul (uint64_t k, uint64_t *z, uint64_t c, uint64_t n, uint64_t *y); 1243afee70eSjsing 1253afee70eSjsing // Multiply by a single word modulo p_25519, z := (c * x) mod p_25519, assuming x reduced 1263afee70eSjsing // Inputs c, x[4]; output z[4] 1273afee70eSjsing extern void bignum_cmul_p25519 (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); 1283afee70eSjsing extern void bignum_cmul_p25519_alt (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); 1293afee70eSjsing 1303afee70eSjsing // Multiply by a single word modulo p_256, z := (c * x) mod p_256, assuming x reduced 1313afee70eSjsing // Inputs c, x[4]; output z[4] 1323afee70eSjsing extern void bignum_cmul_p256 (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); 1333afee70eSjsing extern void bignum_cmul_p256_alt (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); 1343afee70eSjsing 1353afee70eSjsing // Multiply by a single word modulo p_256k1, z := (c * x) mod p_256k1, assuming x reduced 1363afee70eSjsing // Inputs c, x[4]; output z[4] 1373afee70eSjsing extern void bignum_cmul_p256k1 (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); 1383afee70eSjsing extern void bignum_cmul_p256k1_alt (uint64_t z[static 4], uint64_t c, uint64_t x[static 4]); 1393afee70eSjsing 1403afee70eSjsing // Multiply by a single word modulo p_384, z := (c * x) mod p_384, assuming x reduced 1413afee70eSjsing // Inputs c, x[6]; output z[6] 1423afee70eSjsing extern void bignum_cmul_p384 (uint64_t z[static 6], uint64_t c, uint64_t x[static 6]); 1433afee70eSjsing extern void bignum_cmul_p384_alt (uint64_t z[static 6], uint64_t c, uint64_t x[static 6]); 1443afee70eSjsing 1453afee70eSjsing // Multiply by a single word modulo p_521, z := (c * x) mod p_521, assuming x reduced 1463afee70eSjsing // Inputs c, x[9]; output z[9] 1473afee70eSjsing extern void bignum_cmul_p521 (uint64_t z[static 9], uint64_t c, uint64_t x[static 9]); 1483afee70eSjsing extern void bignum_cmul_p521_alt (uint64_t z[static 9], uint64_t c, uint64_t x[static 9]); 1493afee70eSjsing 1503afee70eSjsing // Test bignums for coprimality, gcd(x,y) = 1 1513afee70eSjsing // Inputs x[m], y[n]; output function return; temporary buffer t[>=2*max(m,n)] 1523afee70eSjsing extern uint64_t bignum_coprime (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y, uint64_t *t); 1533afee70eSjsing 1543afee70eSjsing // Copy bignum with zero-extension or truncation, z := x 1553afee70eSjsing // Input x[n]; output z[k] 1563afee70eSjsing extern void bignum_copy (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x); 1573afee70eSjsing 1583afee70eSjsing // Count trailing zero digits (64-bit words) 1593afee70eSjsing // Input x[k]; output function return 1603afee70eSjsing extern uint64_t bignum_ctd (uint64_t k, uint64_t *x); 1613afee70eSjsing 1623afee70eSjsing // Count trailing zero bits 1633afee70eSjsing // Input x[k]; output function return 1643afee70eSjsing extern uint64_t bignum_ctz (uint64_t k, uint64_t *x); 1653afee70eSjsing 1663afee70eSjsing // Convert from almost-Montgomery form, z := (x / 2^256) mod p_256 1673afee70eSjsing // Input x[4]; output z[4] 1683afee70eSjsing extern void bignum_deamont_p256 (uint64_t z[static 4], uint64_t x[static 4]); 1693afee70eSjsing extern void bignum_deamont_p256_alt (uint64_t z[static 4], uint64_t x[static 4]); 1703afee70eSjsing 1713afee70eSjsing // Convert from almost-Montgomery form, z := (x / 2^256) mod p_256k1 1723afee70eSjsing // Input x[4]; output z[4] 1733afee70eSjsing extern void bignum_deamont_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 1743afee70eSjsing 1753afee70eSjsing // Convert from almost-Montgomery form, z := (x / 2^384) mod p_384 1763afee70eSjsing // Input x[6]; output z[6] 1773afee70eSjsing extern void bignum_deamont_p384 (uint64_t z[static 6], uint64_t x[static 6]); 1783afee70eSjsing extern void bignum_deamont_p384_alt (uint64_t z[static 6], uint64_t x[static 6]); 1793afee70eSjsing 1803afee70eSjsing // Convert from almost-Montgomery form z := (x / 2^576) mod p_521 1813afee70eSjsing // Input x[9]; output z[9] 1823afee70eSjsing extern void bignum_deamont_p521 (uint64_t z[static 9], uint64_t x[static 9]); 1833afee70eSjsing 1843afee70eSjsing // Convert from (almost-)Montgomery form z := (x / 2^{64k}) mod m 1853afee70eSjsing // Inputs x[k], m[k]; output z[k] 1863afee70eSjsing extern void bignum_demont (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *m); 1873afee70eSjsing 1883afee70eSjsing // Convert from Montgomery form z := (x / 2^256) mod p_256, assuming x reduced 1893afee70eSjsing // Input x[4]; output z[4] 1903afee70eSjsing extern void bignum_demont_p256 (uint64_t z[static 4], uint64_t x[static 4]); 1913afee70eSjsing extern void bignum_demont_p256_alt (uint64_t z[static 4], uint64_t x[static 4]); 1923afee70eSjsing 1933afee70eSjsing // Convert from Montgomery form z := (x / 2^256) mod p_256k1, assuming x reduced 1943afee70eSjsing // Input x[4]; output z[4] 1953afee70eSjsing extern void bignum_demont_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 1963afee70eSjsing 1973afee70eSjsing // Convert from Montgomery form z := (x / 2^384) mod p_384, assuming x reduced 1983afee70eSjsing // Input x[6]; output z[6] 1993afee70eSjsing extern void bignum_demont_p384 (uint64_t z[static 6], uint64_t x[static 6]); 2003afee70eSjsing extern void bignum_demont_p384_alt (uint64_t z[static 6], uint64_t x[static 6]); 2013afee70eSjsing 2023afee70eSjsing // Convert from Montgomery form z := (x / 2^576) mod p_521, assuming x reduced 2033afee70eSjsing // Input x[9]; output z[9] 2043afee70eSjsing extern void bignum_demont_p521 (uint64_t z[static 9], uint64_t x[static 9]); 2053afee70eSjsing 2063afee70eSjsing // Select digit x[n] 2073afee70eSjsing // Inputs x[k], n; output function return 2083afee70eSjsing extern uint64_t bignum_digit (uint64_t k, uint64_t *x, uint64_t n); 2093afee70eSjsing 2103afee70eSjsing // Return size of bignum in digits (64-bit word) 2113afee70eSjsing // Input x[k]; output function return 2123afee70eSjsing extern uint64_t bignum_digitsize (uint64_t k, uint64_t *x); 2133afee70eSjsing 2143afee70eSjsing // Divide bignum by 10: z' := z div 10, returning remainder z mod 10 2153afee70eSjsing // Inputs z[k]; outputs function return (remainder) and z[k] 2163afee70eSjsing extern uint64_t bignum_divmod10 (uint64_t k, uint64_t *z); 2173afee70eSjsing 2183afee70eSjsing // Double modulo p_25519, z := (2 * x) mod p_25519, assuming x reduced 2193afee70eSjsing // Input x[4]; output z[4] 2203afee70eSjsing extern void bignum_double_p25519 (uint64_t z[static 4], uint64_t x[static 4]); 2213afee70eSjsing 2223afee70eSjsing // Double modulo p_256, z := (2 * x) mod p_256, assuming x reduced 2233afee70eSjsing // Input x[4]; output z[4] 2243afee70eSjsing extern void bignum_double_p256 (uint64_t z[static 4], uint64_t x[static 4]); 2253afee70eSjsing 2263afee70eSjsing // Double modulo p_256k1, z := (2 * x) mod p_256k1, assuming x reduced 2273afee70eSjsing // Input x[4]; output z[4] 2283afee70eSjsing extern void bignum_double_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 2293afee70eSjsing 2303afee70eSjsing // Double modulo p_384, z := (2 * x) mod p_384, assuming x reduced 2313afee70eSjsing // Input x[6]; output z[6] 2323afee70eSjsing extern void bignum_double_p384 (uint64_t z[static 6], uint64_t x[static 6]); 2333afee70eSjsing 2343afee70eSjsing // Double modulo p_521, z := (2 * x) mod p_521, assuming x reduced 2353afee70eSjsing // Input x[9]; output z[9] 2363afee70eSjsing extern void bignum_double_p521 (uint64_t z[static 9], uint64_t x[static 9]); 2373afee70eSjsing 2383afee70eSjsing // Extended Montgomery reduce, returning results in input-output buffer 2393afee70eSjsing // Inputs z[2*k], m[k], w; outputs function return (extra result bit) and z[2*k] 2403afee70eSjsing extern uint64_t bignum_emontredc (uint64_t k, uint64_t *z, uint64_t *m, uint64_t w); 2413afee70eSjsing 2423afee70eSjsing // Extended Montgomery reduce in 8-digit blocks, results in input-output buffer 2433afee70eSjsing // Inputs z[2*k], m[k], w; outputs function return (extra result bit) and z[2*k] 2443afee70eSjsing extern uint64_t bignum_emontredc_8n (uint64_t k, uint64_t *z, uint64_t *m, uint64_t w); 2453afee70eSjsing 2463afee70eSjsing // Test bignums for equality, x = y 2473afee70eSjsing // Inputs x[m], y[n]; output function return 2483afee70eSjsing extern uint64_t bignum_eq (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 2493afee70eSjsing 2503afee70eSjsing // Test bignum for even-ness 2513afee70eSjsing // Input x[k]; output function return 2523afee70eSjsing extern uint64_t bignum_even (uint64_t k, uint64_t *x); 2533afee70eSjsing 2543afee70eSjsing // Convert 4-digit (256-bit) bignum from big-endian bytes 2553afee70eSjsing // Input x[32] (bytes); output z[4] 2563afee70eSjsing extern void bignum_frombebytes_4 (uint64_t z[static 4], uint8_t x[static 32]); 2573afee70eSjsing 2583afee70eSjsing // Convert 6-digit (384-bit) bignum from big-endian bytes 2593afee70eSjsing // Input x[48] (bytes); output z[6] 2603afee70eSjsing extern void bignum_frombebytes_6 (uint64_t z[static 6], uint8_t x[static 48]); 2613afee70eSjsing 2623afee70eSjsing // Convert 4-digit (256-bit) bignum from little-endian bytes 2633afee70eSjsing // Input x[32] (bytes); output z[4] 2643afee70eSjsing extern void bignum_fromlebytes_4 (uint64_t z[static 4], uint8_t x[static 32]); 2653afee70eSjsing 2663afee70eSjsing // Convert 6-digit (384-bit) bignum from little-endian bytes 2673afee70eSjsing // Input x[48] (bytes); output z[6] 2683afee70eSjsing extern void bignum_fromlebytes_6 (uint64_t z[static 6], uint8_t x[static 48]); 2693afee70eSjsing 2703afee70eSjsing // Convert little-endian bytes to 9-digit 528-bit bignum 2713afee70eSjsing // Input x[66] (bytes); output z[9] 2723afee70eSjsing extern void bignum_fromlebytes_p521 (uint64_t z[static 9],uint8_t x[static 66]); 2733afee70eSjsing 2743afee70eSjsing // Compare bignums, x >= y 2753afee70eSjsing // Inputs x[m], y[n]; output function return 2763afee70eSjsing extern uint64_t bignum_ge (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 2773afee70eSjsing 2783afee70eSjsing // Compare bignums, x > y 2793afee70eSjsing // Inputs x[m], y[n]; output function return 2803afee70eSjsing extern uint64_t bignum_gt (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 2813afee70eSjsing 2823afee70eSjsing // Halve modulo p_256, z := (x / 2) mod p_256, assuming x reduced 2833afee70eSjsing // Input x[4]; output z[4] 2843afee70eSjsing extern void bignum_half_p256 (uint64_t z[static 4], uint64_t x[static 4]); 2853afee70eSjsing 2863afee70eSjsing // Halve modulo p_256k1, z := (x / 2) mod p_256k1, assuming x reduced 2873afee70eSjsing // Input x[4]; output z[4] 2883afee70eSjsing extern void bignum_half_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 2893afee70eSjsing 2903afee70eSjsing // Halve modulo p_384, z := (x / 2) mod p_384, assuming x reduced 2913afee70eSjsing // Input x[6]; output z[6] 2923afee70eSjsing extern void bignum_half_p384 (uint64_t z[static 6], uint64_t x[static 6]); 2933afee70eSjsing 2943afee70eSjsing // Halve modulo p_521, z := (x / 2) mod p_521, assuming x reduced 2953afee70eSjsing // Input x[9]; output z[9] 2963afee70eSjsing extern void bignum_half_p521 (uint64_t z[static 9], uint64_t x[static 9]); 2973afee70eSjsing 2983afee70eSjsing // Test bignum for zero-ness, x = 0 2993afee70eSjsing // Input x[k]; output function return 3003afee70eSjsing extern uint64_t bignum_iszero (uint64_t k, uint64_t *x); 3013afee70eSjsing 3023afee70eSjsing // Multiply z := x * y 3033afee70eSjsing // Inputs x[16], y[16]; output z[32]; temporary buffer t[>=32] 3043afee70eSjsing 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]); 3053afee70eSjsing 3063afee70eSjsing // Multiply z := x * y 3073afee70eSjsing // Inputs x[32], y[32]; output z[64]; temporary buffer t[>=96] 3083afee70eSjsing 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]); 3093afee70eSjsing 3103afee70eSjsing // Square, z := x^2 3113afee70eSjsing // Input x[16]; output z[32]; temporary buffer t[>=24] 3123afee70eSjsing extern void bignum_ksqr_16_32 (uint64_t z[static 32], uint64_t x[static 16], uint64_t t[static 24]); 3133afee70eSjsing 3143afee70eSjsing // Square, z := x^2 3153afee70eSjsing // Input x[32]; output z[64]; temporary buffer t[>=72] 3163afee70eSjsing extern void bignum_ksqr_32_64 (uint64_t z[static 64], uint64_t x[static 32], uint64_t t[static 72]); 3173afee70eSjsing 3183afee70eSjsing // Compare bignums, x <= y 3193afee70eSjsing // Inputs x[m], y[n]; output function return 3203afee70eSjsing extern uint64_t bignum_le (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 3213afee70eSjsing 3223afee70eSjsing // Convert 4-digit (256-bit) bignum to/from little-endian form 3233afee70eSjsing // Input x[4]; output z[4] 3243afee70eSjsing extern void bignum_littleendian_4 (uint64_t z[static 4], uint64_t x[static 4]); 3253afee70eSjsing 3263afee70eSjsing // Convert 6-digit (384-bit) bignum to/from little-endian form 3273afee70eSjsing // Input x[6]; output z[6] 3283afee70eSjsing extern void bignum_littleendian_6 (uint64_t z[static 6], uint64_t x[static 6]); 3293afee70eSjsing 3303afee70eSjsing // Compare bignums, x < y 3313afee70eSjsing // Inputs x[m], y[n]; output function return 3323afee70eSjsing extern uint64_t bignum_lt (uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 3333afee70eSjsing 3343afee70eSjsing // Multiply-add, z := z + x * y 3353afee70eSjsing // Inputs x[m], y[n]; outputs function return (carry-out) and z[k] 3363afee70eSjsing extern uint64_t bignum_madd (uint64_t k, uint64_t *z, uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 3373afee70eSjsing 3383afee70eSjsing // Reduce modulo group order, z := x mod n_256 3393afee70eSjsing // Input x[k]; output z[4] 3403afee70eSjsing extern void bignum_mod_n256 (uint64_t z[static 4], uint64_t k, uint64_t *x); 3413afee70eSjsing extern void bignum_mod_n256_alt (uint64_t z[static 4], uint64_t k, uint64_t *x); 3423afee70eSjsing 3433afee70eSjsing // Reduce modulo group order, z := x mod n_256 3443afee70eSjsing // Input x[4]; output z[4] 3453afee70eSjsing extern void bignum_mod_n256_4 (uint64_t z[static 4], uint64_t x[static 4]); 3463afee70eSjsing 3473afee70eSjsing // Reduce modulo group order, z := x mod n_256k1 3483afee70eSjsing // Input x[4]; output z[4] 3493afee70eSjsing extern void bignum_mod_n256k1_4 (uint64_t z[static 4], uint64_t x[static 4]); 3503afee70eSjsing 3513afee70eSjsing // Reduce modulo group order, z := x mod n_384 3523afee70eSjsing // Input x[k]; output z[6] 3533afee70eSjsing extern void bignum_mod_n384 (uint64_t z[static 6], uint64_t k, uint64_t *x); 3543afee70eSjsing extern void bignum_mod_n384_alt (uint64_t z[static 6], uint64_t k, uint64_t *x); 3553afee70eSjsing 3563afee70eSjsing // Reduce modulo group order, z := x mod n_384 3573afee70eSjsing // Input x[6]; output z[6] 3583afee70eSjsing extern void bignum_mod_n384_6 (uint64_t z[static 6], uint64_t x[static 6]); 3593afee70eSjsing 3603afee70eSjsing // Reduce modulo group order, z := x mod n_521 3613afee70eSjsing // Input x[9]; output z[9] 3623afee70eSjsing extern void bignum_mod_n521_9 (uint64_t z[static 9], uint64_t x[static 9]); 3633afee70eSjsing extern void bignum_mod_n521_9_alt (uint64_t z[static 9], uint64_t x[static 9]); 3643afee70eSjsing 3653afee70eSjsing // Reduce modulo field characteristic, z := x mod p_25519 3663afee70eSjsing // Input x[4]; output z[4] 3673afee70eSjsing extern void bignum_mod_p25519_4 (uint64_t z[static 4], uint64_t x[static 4]); 3683afee70eSjsing 3693afee70eSjsing // Reduce modulo field characteristic, z := x mod p_256 3703afee70eSjsing // Input x[k]; output z[4] 3713afee70eSjsing extern void bignum_mod_p256 (uint64_t z[static 4], uint64_t k, uint64_t *x); 3723afee70eSjsing extern void bignum_mod_p256_alt (uint64_t z[static 4], uint64_t k, uint64_t *x); 3733afee70eSjsing 3743afee70eSjsing // Reduce modulo field characteristic, z := x mod p_256 3753afee70eSjsing // Input x[4]; output z[4] 3763afee70eSjsing extern void bignum_mod_p256_4 (uint64_t z[static 4], uint64_t x[static 4]); 3773afee70eSjsing 3783afee70eSjsing // Reduce modulo field characteristic, z := x mod p_256k1 3793afee70eSjsing // Input x[4]; output z[4] 3803afee70eSjsing extern void bignum_mod_p256k1_4 (uint64_t z[static 4], uint64_t x[static 4]); 3813afee70eSjsing 3823afee70eSjsing // Reduce modulo field characteristic, z := x mod p_384 3833afee70eSjsing // Input x[k]; output z[6] 3843afee70eSjsing extern void bignum_mod_p384 (uint64_t z[static 6], uint64_t k, uint64_t *x); 3853afee70eSjsing extern void bignum_mod_p384_alt (uint64_t z[static 6], uint64_t k, uint64_t *x); 3863afee70eSjsing 3873afee70eSjsing // Reduce modulo field characteristic, z := x mod p_384 3883afee70eSjsing // Input x[6]; output z[6] 3893afee70eSjsing extern void bignum_mod_p384_6 (uint64_t z[static 6], uint64_t x[static 6]); 3903afee70eSjsing 3913afee70eSjsing // Reduce modulo field characteristic, z := x mod p_521 3923afee70eSjsing // Input x[9]; output z[9] 3933afee70eSjsing extern void bignum_mod_p521_9 (uint64_t z[static 9], uint64_t x[static 9]); 3943afee70eSjsing 3953afee70eSjsing // Add modulo m, z := (x + y) mod m, assuming x and y reduced 3963afee70eSjsing // Inputs x[k], y[k], m[k]; output z[k] 3973afee70eSjsing extern void bignum_modadd (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y, uint64_t *m); 3983afee70eSjsing 3993afee70eSjsing // Double modulo m, z := (2 * x) mod m, assuming x reduced 4003afee70eSjsing // Inputs x[k], m[k]; output z[k] 4013afee70eSjsing extern void bignum_moddouble (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *m); 4023afee70eSjsing 4033afee70eSjsing // Compute "modification" constant z := 2^{64k} mod m 4043afee70eSjsing // Input m[k]; output z[k]; temporary buffer t[>=k] 4053afee70eSjsing extern void bignum_modifier (uint64_t k, uint64_t *z, uint64_t *m, uint64_t *t); 4063afee70eSjsing 4073afee70eSjsing // Invert modulo m, z = (1/a) mod b, assuming b is an odd number > 1, a coprime to b 4083afee70eSjsing // Inputs a[k], b[k]; output z[k]; temporary buffer t[>=3*k] 4093afee70eSjsing extern void bignum_modinv (uint64_t k, uint64_t *z, uint64_t *a, uint64_t *b, uint64_t *t); 4103afee70eSjsing 4113afee70eSjsing // Optionally negate modulo m, z := (-x) mod m (if p nonzero) or z := x (if p zero), assuming x reduced 4123afee70eSjsing // Inputs p, x[k], m[k]; output z[k] 4133afee70eSjsing extern void bignum_modoptneg (uint64_t k, uint64_t *z, uint64_t p, uint64_t *x, uint64_t *m); 4143afee70eSjsing 4153afee70eSjsing // Subtract modulo m, z := (x - y) mod m, assuming x and y reduced 4163afee70eSjsing // Inputs x[k], y[k], m[k]; output z[k] 4173afee70eSjsing extern void bignum_modsub (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y, uint64_t *m); 4183afee70eSjsing 4193afee70eSjsing // Compute "montification" constant z := 2^{128k} mod m 4203afee70eSjsing // Input m[k]; output z[k]; temporary buffer t[>=k] 4213afee70eSjsing extern void bignum_montifier (uint64_t k, uint64_t *z, uint64_t *m, uint64_t *t); 4223afee70eSjsing 4233afee70eSjsing // Montgomery multiply, z := (x * y / 2^{64k}) mod m 4243afee70eSjsing // Inputs x[k], y[k], m[k]; output z[k] 4253afee70eSjsing extern void bignum_montmul (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y, uint64_t *m); 4263afee70eSjsing 4273afee70eSjsing // Montgomery multiply, z := (x * y / 2^256) mod p_256 4283afee70eSjsing // Inputs x[4], y[4]; output z[4] 4293afee70eSjsing extern void bignum_montmul_p256 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 4303afee70eSjsing extern void bignum_montmul_p256_alt (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 4313afee70eSjsing 4323afee70eSjsing // Montgomery multiply, z := (x * y / 2^256) mod p_256k1 4333afee70eSjsing // Inputs x[4], y[4]; output z[4] 4343afee70eSjsing extern void bignum_montmul_p256k1 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 4353afee70eSjsing extern void bignum_montmul_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 4363afee70eSjsing 4373afee70eSjsing // Montgomery multiply, z := (x * y / 2^384) mod p_384 4383afee70eSjsing // Inputs x[6], y[6]; output z[6] 4393afee70eSjsing extern void bignum_montmul_p384 (uint64_t z[static 6], uint64_t x[static 6], uint64_t y[static 6]); 4403afee70eSjsing extern void bignum_montmul_p384_alt (uint64_t z[static 6], uint64_t x[static 6], uint64_t y[static 6]); 4413afee70eSjsing 4423afee70eSjsing // Montgomery multiply, z := (x * y / 2^576) mod p_521 4433afee70eSjsing // Inputs x[9], y[9]; output z[9] 4443afee70eSjsing extern void bignum_montmul_p521 (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); 4453afee70eSjsing extern void bignum_montmul_p521_alt (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); 4463afee70eSjsing 4473afee70eSjsing // Montgomery reduce, z := (x' / 2^{64p}) MOD m 4483afee70eSjsing // Inputs x[n], m[k], p; output z[k] 4493afee70eSjsing extern void bignum_montredc (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t *m, uint64_t p); 4503afee70eSjsing 4513afee70eSjsing // Montgomery square, z := (x^2 / 2^{64k}) mod m 4523afee70eSjsing // Inputs x[k], m[k]; output z[k] 4533afee70eSjsing extern void bignum_montsqr (uint64_t k, uint64_t *z, uint64_t *x, uint64_t *m); 4543afee70eSjsing 4553afee70eSjsing // Montgomery square, z := (x^2 / 2^256) mod p_256 4563afee70eSjsing // Input x[4]; output z[4] 4573afee70eSjsing extern void bignum_montsqr_p256 (uint64_t z[static 4], uint64_t x[static 4]); 4583afee70eSjsing extern void bignum_montsqr_p256_alt (uint64_t z[static 4], uint64_t x[static 4]); 4593afee70eSjsing 4603afee70eSjsing // Montgomery square, z := (x^2 / 2^256) mod p_256k1 4613afee70eSjsing // Input x[4]; output z[4] 4623afee70eSjsing extern void bignum_montsqr_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 4633afee70eSjsing extern void bignum_montsqr_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4]); 4643afee70eSjsing 4653afee70eSjsing // Montgomery square, z := (x^2 / 2^384) mod p_384 4663afee70eSjsing // Input x[6]; output z[6] 4673afee70eSjsing extern void bignum_montsqr_p384 (uint64_t z[static 6], uint64_t x[static 6]); 4683afee70eSjsing extern void bignum_montsqr_p384_alt (uint64_t z[static 6], uint64_t x[static 6]); 4693afee70eSjsing 4703afee70eSjsing // Montgomery square, z := (x^2 / 2^576) mod p_521 4713afee70eSjsing // Input x[9]; output z[9] 4723afee70eSjsing extern void bignum_montsqr_p521 (uint64_t z[static 9], uint64_t x[static 9]); 4733afee70eSjsing extern void bignum_montsqr_p521_alt (uint64_t z[static 9], uint64_t x[static 9]); 4743afee70eSjsing 4753afee70eSjsing // Multiply z := x * y 4763afee70eSjsing // Inputs x[m], y[n]; output z[k] 4773afee70eSjsing extern void bignum_mul (uint64_t k, uint64_t *z, uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 4783afee70eSjsing 4793afee70eSjsing // Multiply z := x * y 4803afee70eSjsing // Inputs x[4], y[4]; output z[8] 4813afee70eSjsing extern void bignum_mul_4_8 (uint64_t z[static 8], uint64_t x[static 4], uint64_t y[static 4]); 4823afee70eSjsing extern void bignum_mul_4_8_alt (uint64_t z[static 8], uint64_t x[static 4], uint64_t y[static 4]); 4833afee70eSjsing 4843afee70eSjsing // Multiply z := x * y 4853afee70eSjsing // Inputs x[6], y[6]; output z[12] 4863afee70eSjsing extern void bignum_mul_6_12 (uint64_t z[static 12], uint64_t x[static 6], uint64_t y[static 6]); 4873afee70eSjsing extern void bignum_mul_6_12_alt (uint64_t z[static 12], uint64_t x[static 6], uint64_t y[static 6]); 4883afee70eSjsing 4893afee70eSjsing // Multiply z := x * y 4903afee70eSjsing // Inputs x[8], y[8]; output z[16] 4913afee70eSjsing extern void bignum_mul_8_16 (uint64_t z[static 16], uint64_t x[static 8], uint64_t y[static 8]); 4923afee70eSjsing extern void bignum_mul_8_16_alt (uint64_t z[static 16], uint64_t x[static 8], uint64_t y[static 8]); 4933afee70eSjsing 4943afee70eSjsing // Multiply modulo p_25519, z := (x * y) mod p_25519 4953afee70eSjsing // Inputs x[4], y[4]; output z[4] 4963afee70eSjsing extern void bignum_mul_p25519 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 4973afee70eSjsing extern void bignum_mul_p25519_alt (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 4983afee70eSjsing 4993afee70eSjsing // Multiply modulo p_256k1, z := (x * y) mod p_256k1 5003afee70eSjsing // Inputs x[4], y[4]; output z[4] 5013afee70eSjsing extern void bignum_mul_p256k1 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 5023afee70eSjsing extern void bignum_mul_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 5033afee70eSjsing 5043afee70eSjsing // Multiply modulo p_521, z := (x * y) mod p_521, assuming x and y reduced 5053afee70eSjsing // Inputs x[9], y[9]; output z[9] 5063afee70eSjsing extern void bignum_mul_p521 (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); 5073afee70eSjsing extern void bignum_mul_p521_alt (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); 5083afee70eSjsing 5093afee70eSjsing // Multiply bignum by 10 and add word: z := 10 * z + d 5103afee70eSjsing // Inputs z[k], d; outputs function return (carry) and z[k] 5113afee70eSjsing extern uint64_t bignum_muladd10 (uint64_t k, uint64_t *z, uint64_t d); 5123afee70eSjsing 5133afee70eSjsing // Multiplex/select z := x (if p nonzero) or z := y (if p zero) 5143afee70eSjsing // Inputs p, x[k], y[k]; output z[k] 5153afee70eSjsing extern void bignum_mux (uint64_t p, uint64_t k, uint64_t *z, uint64_t *x, uint64_t *y); 5163afee70eSjsing 5173afee70eSjsing // 256-bit multiplex/select z := x (if p nonzero) or z := y (if p zero) 5183afee70eSjsing // Inputs p, x[4], y[4]; output z[4] 5193afee70eSjsing extern void bignum_mux_4 (uint64_t p, uint64_t z[static 4],uint64_t x[static 4], uint64_t y[static 4]); 5203afee70eSjsing 5213afee70eSjsing // 384-bit multiplex/select z := x (if p nonzero) or z := y (if p zero) 5223afee70eSjsing // Inputs p, x[6], y[6]; output z[6] 5233afee70eSjsing extern void bignum_mux_6 (uint64_t p, uint64_t z[static 6],uint64_t x[static 6], uint64_t y[static 6]); 5243afee70eSjsing 5253afee70eSjsing // Select element from 16-element table, z := xs[k*i] 5263afee70eSjsing // Inputs xs[16*k], i; output z[k] 5273afee70eSjsing extern void bignum_mux16 (uint64_t k, uint64_t *z, uint64_t *xs, uint64_t i); 5283afee70eSjsing 5293afee70eSjsing // Negate modulo p_25519, z := (-x) mod p_25519, assuming x reduced 5303afee70eSjsing // Input x[4]; output z[4] 5313afee70eSjsing extern void bignum_neg_p25519 (uint64_t z[static 4], uint64_t x[static 4]); 5323afee70eSjsing 5333afee70eSjsing // Negate modulo p_256, z := (-x) mod p_256, assuming x reduced 5343afee70eSjsing // Input x[4]; output z[4] 5353afee70eSjsing extern void bignum_neg_p256 (uint64_t z[static 4], uint64_t x[static 4]); 5363afee70eSjsing 5373afee70eSjsing // Negate modulo p_256k1, z := (-x) mod p_256k1, assuming x reduced 5383afee70eSjsing // Input x[4]; output z[4] 5393afee70eSjsing extern void bignum_neg_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 5403afee70eSjsing 5413afee70eSjsing // Negate modulo p_384, z := (-x) mod p_384, assuming x reduced 5423afee70eSjsing // Input x[6]; output z[6] 5433afee70eSjsing extern void bignum_neg_p384 (uint64_t z[static 6], uint64_t x[static 6]); 5443afee70eSjsing 5453afee70eSjsing // Negate modulo p_521, z := (-x) mod p_521, assuming x reduced 5463afee70eSjsing // Input x[9]; output z[9] 5473afee70eSjsing extern void bignum_neg_p521 (uint64_t z[static 9], uint64_t x[static 9]); 5483afee70eSjsing 5493afee70eSjsing // Negated modular inverse, z := (-1/x) mod 2^{64k} 5503afee70eSjsing // Input x[k]; output z[k] 5513afee70eSjsing extern void bignum_negmodinv (uint64_t k, uint64_t *z, uint64_t *x); 5523afee70eSjsing 5533afee70eSjsing // Test bignum for nonzero-ness x =/= 0 5543afee70eSjsing // Input x[k]; output function return 5553afee70eSjsing extern uint64_t bignum_nonzero (uint64_t k, uint64_t *x); 5563afee70eSjsing 5573afee70eSjsing // Test 256-bit bignum for nonzero-ness x =/= 0 5583afee70eSjsing // Input x[4]; output function return 5593afee70eSjsing extern uint64_t bignum_nonzero_4(uint64_t x[static 4]); 5603afee70eSjsing 5613afee70eSjsing // Test 384-bit bignum for nonzero-ness x =/= 0 5623afee70eSjsing // Input x[6]; output function return 5633afee70eSjsing extern uint64_t bignum_nonzero_6(uint64_t x[static 6]); 5643afee70eSjsing 5653afee70eSjsing // Normalize bignum in-place by shifting left till top bit is 1 5663afee70eSjsing // Input z[k]; outputs function return (bits shifted left) and z[k] 5673afee70eSjsing extern uint64_t bignum_normalize (uint64_t k, uint64_t *z); 5683afee70eSjsing 5693afee70eSjsing // Test bignum for odd-ness 5703afee70eSjsing // Input x[k]; output function return 5713afee70eSjsing extern uint64_t bignum_odd (uint64_t k, uint64_t *x); 5723afee70eSjsing 5733afee70eSjsing // Convert single digit to bignum, z := n 5743afee70eSjsing // Input n; output z[k] 5753afee70eSjsing extern void bignum_of_word (uint64_t k, uint64_t *z, uint64_t n); 5763afee70eSjsing 5773afee70eSjsing // Optionally add, z := x + y (if p nonzero) or z := x (if p zero) 5783afee70eSjsing // Inputs x[k], p, y[k]; outputs function return (carry-out) and z[k] 5793afee70eSjsing extern uint64_t bignum_optadd (uint64_t k, uint64_t *z, uint64_t *x, uint64_t p, uint64_t *y); 5803afee70eSjsing 5813afee70eSjsing // Optionally negate, z := -x (if p nonzero) or z := x (if p zero) 5823afee70eSjsing // Inputs p, x[k]; outputs function return (nonzero input) and z[k] 5833afee70eSjsing extern uint64_t bignum_optneg (uint64_t k, uint64_t *z, uint64_t p, uint64_t *x); 5843afee70eSjsing 5853afee70eSjsing // Optionally negate modulo p_25519, z := (-x) mod p_25519 (if p nonzero) or z := x (if p zero), assuming x reduced 5863afee70eSjsing // Inputs p, x[4]; output z[4] 5873afee70eSjsing extern void bignum_optneg_p25519 (uint64_t z[static 4], uint64_t p, uint64_t x[static 4]); 5883afee70eSjsing 5893afee70eSjsing // Optionally negate modulo p_256, z := (-x) mod p_256 (if p nonzero) or z := x (if p zero), assuming x reduced 5903afee70eSjsing // Inputs p, x[4]; output z[4] 5913afee70eSjsing extern void bignum_optneg_p256 (uint64_t z[static 4], uint64_t p, uint64_t x[static 4]); 5923afee70eSjsing 5933afee70eSjsing // Optionally negate modulo p_256k1, z := (-x) mod p_256k1 (if p nonzero) or z := x (if p zero), assuming x reduced 5943afee70eSjsing // Inputs p, x[4]; output z[4] 5953afee70eSjsing extern void bignum_optneg_p256k1 (uint64_t z[static 4], uint64_t p, uint64_t x[static 4]); 5963afee70eSjsing 5973afee70eSjsing // Optionally negate modulo p_384, z := (-x) mod p_384 (if p nonzero) or z := x (if p zero), assuming x reduced 5983afee70eSjsing // Inputs p, x[6]; output z[6] 5993afee70eSjsing extern void bignum_optneg_p384 (uint64_t z[static 6], uint64_t p, uint64_t x[static 6]); 6003afee70eSjsing 6013afee70eSjsing // Optionally negate modulo p_521, z := (-x) mod p_521 (if p nonzero) or z := x (if p zero), assuming x reduced 6023afee70eSjsing // Inputs p, x[9]; output z[9] 6033afee70eSjsing extern void bignum_optneg_p521 (uint64_t z[static 9], uint64_t p, uint64_t x[static 9]); 6043afee70eSjsing 6053afee70eSjsing // Optionally subtract, z := x - y (if p nonzero) or z := x (if p zero) 6063afee70eSjsing // Inputs x[k], p, y[k]; outputs function return (carry-out) and z[k] 6073afee70eSjsing extern uint64_t bignum_optsub (uint64_t k, uint64_t *z, uint64_t *x, uint64_t p, uint64_t *y); 6083afee70eSjsing 6093afee70eSjsing // Optionally subtract or add, z := x + sgn(p) * y interpreting p as signed 6103afee70eSjsing // Inputs x[k], p, y[k]; outputs function return (carry-out) and z[k] 6113afee70eSjsing extern uint64_t bignum_optsubadd (uint64_t k, uint64_t *z, uint64_t *x, uint64_t p, uint64_t *y); 6123afee70eSjsing 6133afee70eSjsing // Return bignum of power of 2, z := 2^n 6143afee70eSjsing // Input n; output z[k] 6153afee70eSjsing extern void bignum_pow2 (uint64_t k, uint64_t *z, uint64_t n); 6163afee70eSjsing 6173afee70eSjsing // Shift bignum left by c < 64 bits z := x * 2^c 6183afee70eSjsing // Inputs x[n], c; outputs function return (carry-out) and z[k] 6193afee70eSjsing extern uint64_t bignum_shl_small (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t c); 6203afee70eSjsing 6213afee70eSjsing // Shift bignum right by c < 64 bits z := floor(x / 2^c) 6223afee70eSjsing // Inputs x[n], c; outputs function return (bits shifted out) and z[k] 6233afee70eSjsing extern uint64_t bignum_shr_small (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x, uint64_t c); 6243afee70eSjsing 6253afee70eSjsing // Square, z := x^2 6263afee70eSjsing // Input x[n]; output z[k] 6273afee70eSjsing extern void bignum_sqr (uint64_t k, uint64_t *z, uint64_t n, uint64_t *x); 6283afee70eSjsing 6293afee70eSjsing // Square, z := x^2 6303afee70eSjsing // Input x[4]; output z[8] 6313afee70eSjsing extern void bignum_sqr_4_8 (uint64_t z[static 8], uint64_t x[static 4]); 6323afee70eSjsing extern void bignum_sqr_4_8_alt (uint64_t z[static 8], uint64_t x[static 4]); 6333afee70eSjsing 6343afee70eSjsing // Square, z := x^2 6353afee70eSjsing // Input x[6]; output z[12] 6363afee70eSjsing extern void bignum_sqr_6_12 (uint64_t z[static 12], uint64_t x[static 6]); 6373afee70eSjsing extern void bignum_sqr_6_12_alt (uint64_t z[static 12], uint64_t x[static 6]); 6383afee70eSjsing 6393afee70eSjsing // Square, z := x^2 6403afee70eSjsing // Input x[8]; output z[16] 6413afee70eSjsing extern void bignum_sqr_8_16 (uint64_t z[static 16], uint64_t x[static 8]); 6423afee70eSjsing extern void bignum_sqr_8_16_alt (uint64_t z[static 16], uint64_t x[static 8]); 6433afee70eSjsing 6443afee70eSjsing // Square modulo p_25519, z := (x^2) mod p_25519 6453afee70eSjsing // Input x[4]; output z[4] 6463afee70eSjsing extern void bignum_sqr_p25519 (uint64_t z[static 4], uint64_t x[static 4]); 6473afee70eSjsing extern void bignum_sqr_p25519_alt (uint64_t z[static 4], uint64_t x[static 4]); 6483afee70eSjsing 6493afee70eSjsing // Square modulo p_256k1, z := (x^2) mod p_256k1 6503afee70eSjsing // Input x[4]; output z[4] 6513afee70eSjsing extern void bignum_sqr_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 6523afee70eSjsing extern void bignum_sqr_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4]); 6533afee70eSjsing 6543afee70eSjsing // Square modulo p_521, z := (x^2) mod p_521, assuming x reduced 6553afee70eSjsing // Input x[9]; output z[9] 6563afee70eSjsing extern void bignum_sqr_p521 (uint64_t z[static 9], uint64_t x[static 9]); 6573afee70eSjsing extern void bignum_sqr_p521_alt (uint64_t z[static 9], uint64_t x[static 9]); 6583afee70eSjsing 6593afee70eSjsing // Subtract, z := x - y 6603afee70eSjsing // Inputs x[m], y[n]; outputs function return (carry-out) and z[p] 6613afee70eSjsing extern uint64_t bignum_sub (uint64_t p, uint64_t *z, uint64_t m, uint64_t *x, uint64_t n, uint64_t *y); 6623afee70eSjsing 6633afee70eSjsing // Subtract modulo p_25519, z := (x - y) mod p_25519, assuming x and y reduced 6643afee70eSjsing // Inputs x[4], y[4]; output z[4] 6653afee70eSjsing extern void bignum_sub_p25519 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 6663afee70eSjsing 6673afee70eSjsing // Subtract modulo p_256, z := (x - y) mod p_256, assuming x and y reduced 6683afee70eSjsing // Inputs x[4], y[4]; output z[4] 6693afee70eSjsing extern void bignum_sub_p256 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 6703afee70eSjsing 6713afee70eSjsing // Subtract modulo p_256k1, z := (x - y) mod p_256k1, assuming x and y reduced 6723afee70eSjsing // Inputs x[4], y[4]; output z[4] 6733afee70eSjsing extern void bignum_sub_p256k1 (uint64_t z[static 4], uint64_t x[static 4], uint64_t y[static 4]); 6743afee70eSjsing 6753afee70eSjsing // Subtract modulo p_384, z := (x - y) mod p_384, assuming x and y reduced 6763afee70eSjsing // Inputs x[6], y[6]; output z[6] 6773afee70eSjsing extern void bignum_sub_p384 (uint64_t z[static 6], uint64_t x[static 6], uint64_t y[static 6]); 6783afee70eSjsing 6793afee70eSjsing // Subtract modulo p_521, z := (x - y) mod p_521, assuming x and y reduced 6803afee70eSjsing // Inputs x[9], y[9]; output z[9] 6813afee70eSjsing extern void bignum_sub_p521 (uint64_t z[static 9], uint64_t x[static 9], uint64_t y[static 9]); 6823afee70eSjsing 6833afee70eSjsing // Convert 4-digit (256-bit) bignum to big-endian bytes 6843afee70eSjsing // Input x[4]; output z[32] (bytes) 6853afee70eSjsing extern void bignum_tobebytes_4 (uint8_t z[static 32], uint64_t x[static 4]); 6863afee70eSjsing 6873afee70eSjsing // Convert 6-digit (384-bit) bignum to big-endian bytes 6883afee70eSjsing // Input x[6]; output z[48] (bytes) 6893afee70eSjsing extern void bignum_tobebytes_6 (uint8_t z[static 48], uint64_t x[static 6]); 6903afee70eSjsing 6913afee70eSjsing // Convert 4-digit (256-bit) bignum to little-endian bytes 6923afee70eSjsing // Input x[4]; output z[32] (bytes) 6933afee70eSjsing extern void bignum_tolebytes_4 (uint8_t z[static 32], uint64_t x[static 4]); 6943afee70eSjsing 6953afee70eSjsing // Convert 6-digit (384-bit) bignum to little-endian bytes 6963afee70eSjsing // Input x[6]; output z[48] (bytes) 6973afee70eSjsing extern void bignum_tolebytes_6 (uint8_t z[static 48], uint64_t x[static 6]); 6983afee70eSjsing 6993afee70eSjsing // Convert 9-digit 528-bit bignum to little-endian bytes 7003afee70eSjsing // Input x[6]; output z[66] (bytes) 7013afee70eSjsing extern void bignum_tolebytes_p521 (uint8_t z[static 66], uint64_t x[static 9]); 7023afee70eSjsing 7033afee70eSjsing // Convert to Montgomery form z := (2^256 * x) mod p_256 7043afee70eSjsing // Input x[4]; output z[4] 7053afee70eSjsing extern void bignum_tomont_p256 (uint64_t z[static 4], uint64_t x[static 4]); 7063afee70eSjsing extern void bignum_tomont_p256_alt (uint64_t z[static 4], uint64_t x[static 4]); 7073afee70eSjsing 7083afee70eSjsing // Convert to Montgomery form z := (2^256 * x) mod p_256k1 7093afee70eSjsing // Input x[4]; output z[4] 7103afee70eSjsing extern void bignum_tomont_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 7113afee70eSjsing extern void bignum_tomont_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4]); 7123afee70eSjsing 7133afee70eSjsing // Convert to Montgomery form z := (2^384 * x) mod p_384 7143afee70eSjsing // Input x[6]; output z[6] 7153afee70eSjsing extern void bignum_tomont_p384 (uint64_t z[static 6], uint64_t x[static 6]); 7163afee70eSjsing extern void bignum_tomont_p384_alt (uint64_t z[static 6], uint64_t x[static 6]); 7173afee70eSjsing 7183afee70eSjsing // Convert to Montgomery form z := (2^576 * x) mod p_521 7193afee70eSjsing // Input x[9]; output z[9] 7203afee70eSjsing extern void bignum_tomont_p521 (uint64_t z[static 9], uint64_t x[static 9]); 7213afee70eSjsing 7223afee70eSjsing // Triple modulo p_256, z := (3 * x) mod p_256 7233afee70eSjsing // Input x[4]; output z[4] 7243afee70eSjsing extern void bignum_triple_p256 (uint64_t z[static 4], uint64_t x[static 4]); 7253afee70eSjsing extern void bignum_triple_p256_alt (uint64_t z[static 4], uint64_t x[static 4]); 7263afee70eSjsing 7273afee70eSjsing // Triple modulo p_256k1, z := (3 * x) mod p_256k1 7283afee70eSjsing // Input x[4]; output z[4] 7293afee70eSjsing extern void bignum_triple_p256k1 (uint64_t z[static 4], uint64_t x[static 4]); 7303afee70eSjsing extern void bignum_triple_p256k1_alt (uint64_t z[static 4], uint64_t x[static 4]); 7313afee70eSjsing 7323afee70eSjsing // Triple modulo p_384, z := (3 * x) mod p_384 7333afee70eSjsing // Input x[6]; output z[6] 7343afee70eSjsing extern void bignum_triple_p384 (uint64_t z[static 6], uint64_t x[static 6]); 7353afee70eSjsing extern void bignum_triple_p384_alt (uint64_t z[static 6], uint64_t x[static 6]); 7363afee70eSjsing 7373afee70eSjsing // Triple modulo p_521, z := (3 * x) mod p_521, assuming x reduced 7383afee70eSjsing // Input x[9]; output z[9] 7393afee70eSjsing extern void bignum_triple_p521 (uint64_t z[static 9], uint64_t x[static 9]); 7403afee70eSjsing extern void bignum_triple_p521_alt (uint64_t z[static 9], uint64_t x[static 9]); 7413afee70eSjsing 7423afee70eSjsing // Montgomery ladder step for curve25519 7433afee70eSjsing // Inputs point[8], pp[16], b; output rr[16] 7443afee70eSjsing extern void curve25519_ladderstep(uint64_t rr[16],uint64_t point[8],uint64_t pp[16],uint64_t b); 7453afee70eSjsing extern void curve25519_ladderstep_alt(uint64_t rr[16],uint64_t point[8],uint64_t pp[16],uint64_t b); 7463afee70eSjsing 7473afee70eSjsing // Projective scalar multiplication, x coordinate only, for curve25519 7483afee70eSjsing // Inputs scalar[4], point[4]; output res[8] 7493afee70eSjsing extern void curve25519_pxscalarmul(uint64_t res[static 8],uint64_t scalar[static 4],uint64_t point[static 4]); 7503afee70eSjsing extern void curve25519_pxscalarmul_alt(uint64_t res[static 8],uint64_t scalar[static 4],uint64_t point[static 4]); 7513afee70eSjsing 7523afee70eSjsing // x25519 function for curve25519 7533afee70eSjsing // Inputs scalar[4], point[4]; output res[4] 7543afee70eSjsing extern void curve25519_x25519(uint64_t res[static 4],uint64_t scalar[static 4],uint64_t point[static 4]); 7553afee70eSjsing extern void curve25519_x25519_alt(uint64_t res[static 4],uint64_t scalar[static 4],uint64_t point[static 4]); 7563afee70eSjsing 7573afee70eSjsing // x25519 function for curve25519 on base element 9 7583afee70eSjsing // Input scalar[4]; output res[4] 7593afee70eSjsing extern void curve25519_x25519base(uint64_t res[static 4],uint64_t scalar[static 4]); 7603afee70eSjsing extern void curve25519_x25519base_alt(uint64_t res[static 4],uint64_t scalar[static 4]); 7613afee70eSjsing 7623afee70eSjsing // Extended projective addition for edwards25519 7633afee70eSjsing // Inputs p1[16], p2[16]; output p3[16] 7643afee70eSjsing extern void edwards25519_epadd(uint64_t p3[static 16],uint64_t p1[static 16],uint64_t p2[static 16]); 7653afee70eSjsing extern void edwards25519_epadd_alt(uint64_t p3[static 16],uint64_t p1[static 16],uint64_t p2[static 16]); 7663afee70eSjsing 7673afee70eSjsing // Extended projective doubling for edwards25519 7683afee70eSjsing // Inputs p1[12]; output p3[16] 7693afee70eSjsing extern void edwards25519_epdouble(uint64_t p3[static 16],uint64_t p1[static 12]); 7703afee70eSjsing extern void edwards25519_epdouble_alt(uint64_t p3[static 16],uint64_t p1[static 12]); 7713afee70eSjsing 7723afee70eSjsing // Projective doubling for edwards25519 7733afee70eSjsing // Inputs p1[12]; output p3[12] 7743afee70eSjsing extern void edwards25519_pdouble(uint64_t p3[static 12],uint64_t p1[static 12]); 7753afee70eSjsing extern void edwards25519_pdouble_alt(uint64_t p3[static 12],uint64_t p1[static 12]); 7763afee70eSjsing 7773afee70eSjsing // Extended projective + precomputed mixed addition for edwards25519 7783afee70eSjsing // Inputs p1[16], p2[12]; output p3[16] 7793afee70eSjsing extern void edwards25519_pepadd(uint64_t p3[static 16],uint64_t p1[static 16],uint64_t p2[static 12]); 7803afee70eSjsing extern void edwards25519_pepadd_alt(uint64_t p3[static 16],uint64_t p1[static 16],uint64_t p2[static 12]); 7813afee70eSjsing 7823afee70eSjsing // Point addition on NIST curve P-256 in Montgomery-Jacobian coordinates 7833afee70eSjsing // Inputs p1[12], p2[12]; output p3[12] 7843afee70eSjsing extern void p256_montjadd(uint64_t p3[static 12],uint64_t p1[static 12],uint64_t p2[static 12]); 7853afee70eSjsing 7863afee70eSjsing // Point doubling on NIST curve P-256 in Montgomery-Jacobian coordinates 7873afee70eSjsing // Inputs p1[12]; output p3[12] 7883afee70eSjsing extern void p256_montjdouble(uint64_t p3[static 12],uint64_t p1[static 12]); 7893afee70eSjsing 7903afee70eSjsing // Point mixed addition on NIST curve P-256 in Montgomery-Jacobian coordinates 7913afee70eSjsing // Inputs p1[12], p2[8]; output p3[12] 7923afee70eSjsing extern void p256_montjmixadd(uint64_t p3[static 12],uint64_t p1[static 12],uint64_t p2[static 8]); 7933afee70eSjsing 7943afee70eSjsing // Point addition on NIST curve P-384 in Montgomery-Jacobian coordinates 7953afee70eSjsing // Inputs p1[18], p2[18]; output p3[18] 7963afee70eSjsing extern void p384_montjadd(uint64_t p3[static 18],uint64_t p1[static 18],uint64_t p2[static 18]); 7973afee70eSjsing 7983afee70eSjsing // Point doubling on NIST curve P-384 in Montgomery-Jacobian coordinates 7993afee70eSjsing // Inputs p1[18]; output p3[18] 8003afee70eSjsing extern void p384_montjdouble(uint64_t p3[static 18],uint64_t p1[static 18]); 8013afee70eSjsing 8023afee70eSjsing // Point mixed addition on NIST curve P-384 in Montgomery-Jacobian coordinates 8033afee70eSjsing // Inputs p1[18], p2[12]; output p3[18] 8043afee70eSjsing extern void p384_montjmixadd(uint64_t p3[static 18],uint64_t p1[static 18],uint64_t p2[static 12]); 8053afee70eSjsing 8063afee70eSjsing // Point addition on NIST curve P-521 in Jacobian coordinates 8073afee70eSjsing // Inputs p1[27], p2[27]; output p3[27] 8083afee70eSjsing extern void p521_jadd(uint64_t p3[static 27],uint64_t p1[static 27],uint64_t p2[static 27]); 8093afee70eSjsing 8103afee70eSjsing // Point doubling on NIST curve P-521 in Jacobian coordinates 8113afee70eSjsing // Input p1[27]; output p3[27] 8123afee70eSjsing extern void p521_jdouble(uint64_t p3[static 27],uint64_t p1[static 27]); 8133afee70eSjsing 8143afee70eSjsing // Point mixed addition on NIST curve P-521 in Jacobian coordinates 8153afee70eSjsing // Inputs p1[27], p2[18]; output p3[27] 8163afee70eSjsing extern void p521_jmixadd(uint64_t p3[static 27],uint64_t p1[static 27],uint64_t p2[static 18]); 8173afee70eSjsing 8183afee70eSjsing // Point addition on SECG curve secp256k1 in Jacobian coordinates 8193afee70eSjsing // Inputs p1[12], p2[12]; output p3[12] 8203afee70eSjsing extern void secp256k1_jadd(uint64_t p3[static 12],uint64_t p1[static 12],uint64_t p2[static 12]); 8213afee70eSjsing 8223afee70eSjsing // Point doubling on SECG curve secp256k1 in Jacobian coordinates 8233afee70eSjsing // Input p1[12]; output p3[12] 8243afee70eSjsing extern void secp256k1_jdouble(uint64_t p3[static 12],uint64_t p1[static 12]); 8253afee70eSjsing 8263afee70eSjsing // Point mixed addition on SECG curve secp256k1 in Jacobian coordinates 8273afee70eSjsing // Inputs p1[12], p2[8]; output p3[12] 8283afee70eSjsing extern void secp256k1_jmixadd(uint64_t p3[static 12],uint64_t p1[static 12],uint64_t p2[static 8]); 8293afee70eSjsing 8303afee70eSjsing // Reverse the bytes in a single word 8313afee70eSjsing // Input a; output function return 8323afee70eSjsing extern uint64_t word_bytereverse (uint64_t a); 8333afee70eSjsing 8343afee70eSjsing // Count leading zero bits in a single word 8353afee70eSjsing // Input a; output function return 8363afee70eSjsing extern uint64_t word_clz (uint64_t a); 8373afee70eSjsing 8383afee70eSjsing // Count trailing zero bits in a single word 8393afee70eSjsing // Input a; output function return 8403afee70eSjsing extern uint64_t word_ctz (uint64_t a); 8413afee70eSjsing 8423afee70eSjsing // Return maximum of two unsigned 64-bit words 8433afee70eSjsing // Inputs a, b; output function return 8443afee70eSjsing extern uint64_t word_max (uint64_t a, uint64_t b); 8453afee70eSjsing 8463afee70eSjsing // Return minimum of two unsigned 64-bit words 8473afee70eSjsing // Inputs a, b; output function return 8483afee70eSjsing extern uint64_t word_min (uint64_t a, uint64_t b); 8493afee70eSjsing 8503afee70eSjsing // Single-word negated modular inverse (-1/a) mod 2^64 8513afee70eSjsing // Input a; output function return 8523afee70eSjsing extern uint64_t word_negmodinv (uint64_t a); 8533afee70eSjsing 8543afee70eSjsing // Single-word reciprocal, 2^64 + ret = ceil(2^128/a) - 1 if MSB of "a" is set 8553afee70eSjsing // Input a; output function return 8563afee70eSjsing extern uint64_t word_recip (uint64_t a); 857