mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-22 22:38:08 +00:00
Optimized the bn_inverse method.
The new method needs about 30 % less time for prime256k1 and is about twice as fast for other moduli. The base algorithm is the same. The code is also a bit smaller and doesn't need the 8 kb precomputed table. Important canges: 1. even/odd distinction so that we need to test only one of the numbers for being even. This also leads to less duplicated code. 2. Allow for shifting by 32 bits at a time in the even test. 3. Pack u,s and v,r into the same array, which saves a bit of stack memory. 4. Don't divide by two after subtraction; this simplifies code. 5. Abort as soon as u,v are equal, instead of subtracting them. 6. Use s instead of r after the loop; no negation needed. 7. New code that divides by 2^k fast without any precomputed values.
This commit is contained in:
parent
e37ba822e6
commit
7d4cf5cedd
497
bignum.c
497
bignum.c
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
#include "bignum.h"
|
#include "bignum.h"
|
||||||
#include "secp256k1.h"
|
#include "secp256k1.h"
|
||||||
|
|
||||||
@ -283,10 +284,6 @@ void bn_sqrt(bignum256 *x, const bignum256 *prime)
|
|||||||
|
|
||||||
#if ! USE_INVERSE_FAST
|
#if ! USE_INVERSE_FAST
|
||||||
|
|
||||||
#if USE_PRECOMPUTED_IV
|
|
||||||
#warning USE_PRECOMPUTED_IV will not be used
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// in field G_prime, small but slow
|
// in field G_prime, small but slow
|
||||||
void bn_inverse(bignum256 *x, const bignum256 *prime)
|
void bn_inverse(bignum256 *x, const bignum256 *prime)
|
||||||
{
|
{
|
||||||
@ -322,285 +319,273 @@ void bn_inverse(bignum256 *x, const bignum256 *prime)
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// in field G_prime, big but fast
|
// in field G_prime, big and complicated but fast
|
||||||
// this algorithm is based on the Euklidean algorithm
|
// the input must not be 0 mod prime.
|
||||||
// the result is smaller than 2*prime
|
// the result is smaller than prime
|
||||||
void bn_inverse(bignum256 *x, const bignum256 *prime)
|
void bn_inverse(bignum256 *x, const bignum256 *prime)
|
||||||
{
|
{
|
||||||
int i, j, k, len1, len2, mask;
|
int i, j, k, cmp;
|
||||||
uint8_t buf[32];
|
struct combo {
|
||||||
uint32_t u[8], v[8], s[9], r[10], temp32;
|
uint32_t a[9];
|
||||||
uint64_t temp, temp2;
|
int len1;
|
||||||
// reduce x modulo prime
|
} us, vr, *odd, *even;
|
||||||
|
uint32_t pp[8];
|
||||||
|
uint32_t temp32;
|
||||||
|
uint64_t temp;
|
||||||
|
|
||||||
|
// The algorithm is based on Schroeppel et. al. "Almost Modular Inverse"
|
||||||
|
// algorithm. We keep four values u,v,r,s in the combo registers
|
||||||
|
// us and vr. us stores u in the first len1 limbs (little endian)
|
||||||
|
// and v in the last 9-len1 limbs (big endian). vr stores v and s.
|
||||||
|
// This is because both u*s and v*r are guaranteed to fit in 8 limbs, so
|
||||||
|
// their components are guaranteed to fit in 9. During the algorithm,
|
||||||
|
// the length of u and v shrinks while r and s grow.
|
||||||
|
// u,v,r,s correspond to F,G,B,C in Schroeppel's algorithm.
|
||||||
|
|
||||||
|
// reduce x modulo prime. This is necessary as it has to fit in 8 limbs.
|
||||||
bn_fast_mod(x, prime);
|
bn_fast_mod(x, prime);
|
||||||
bn_mod(x, prime);
|
bn_mod(x, prime);
|
||||||
// convert x and prime it to 8x32 bit limb form
|
// convert x and prime to 8x32 bit limb form
|
||||||
bn_write_be(prime, buf);
|
temp32 = prime->val[0];
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
u[i] = read_be(buf + 28 - i * 4);
|
temp32 |= prime->val[i + 1] << (30-2*i);
|
||||||
|
us.a[i] = pp[i] = temp32;
|
||||||
|
temp32 = prime->val[i + 1] >> (2+2*i);
|
||||||
}
|
}
|
||||||
bn_write_be(x, buf);
|
temp32 = x->val[0];
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
v[i] = read_be(buf + 28 - i * 4);
|
temp32 |= x->val[i + 1] << (30-2*i);
|
||||||
|
vr.a[i] = temp32;
|
||||||
|
temp32 = x->val[i + 1] >> (2+2*i);
|
||||||
}
|
}
|
||||||
len1 = 8;
|
us.len1 = 8;
|
||||||
s[0] = 1;
|
vr.len1 = 8;
|
||||||
r[0] = 0;
|
// set s = 1 and r = 0
|
||||||
len2 = 1;
|
us.a[8] = 1;
|
||||||
|
vr.a[8] = 0;
|
||||||
|
// set k = 0.
|
||||||
k = 0;
|
k = 0;
|
||||||
// u = prime, v = x len1 = numlimbs(u,v)
|
|
||||||
// r = 0 , s = 1 len2 = numlimbs(r,s)
|
// only one of the numbers u,v can be even at any time. We
|
||||||
|
// let even point to that number and odd to the other.
|
||||||
|
// Initially the prime u is guaranteed to be odd.
|
||||||
|
odd = &us;
|
||||||
|
even = &vr;
|
||||||
|
|
||||||
|
// u = prime, v = x
|
||||||
|
// r = 0 , s = 1
|
||||||
// k = 0
|
// k = 0
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// invariants:
|
// invariants:
|
||||||
// r,s,u,v >= 0
|
// let u = limbs us.a[0..u.len1-1] in little endian,
|
||||||
|
// let s = limbs us.a[u.len..8] in big endian,
|
||||||
|
// let v = limbs vr.a[0..u.len1-1] in little endian,
|
||||||
|
// let r = limbs vr.a[u.len..8] in big endian,
|
||||||
|
// r,s >= 0 ; u,v >= 1
|
||||||
// x*-r = u*2^k mod prime
|
// x*-r = u*2^k mod prime
|
||||||
// x*s = v*2^k mod prime
|
// x*s = v*2^k mod prime
|
||||||
// u*s + v*r = prime
|
// u*s + v*r = prime
|
||||||
// floor(log2(u)) + floor(log2(v)) + k <= 510
|
// floor(log2(u)) + floor(log2(v)) + k <= 510
|
||||||
// max(u,v) <= 2^k
|
// max(u,v) <= 2^k (*) see comment at end of loop
|
||||||
// gcd(u,v) = 1
|
// gcd(u,v) = 1
|
||||||
// len1 = numlimbs(u,v)
|
// {odd,even} = {&us, &vr}
|
||||||
// len2 = numlimbs(r,s)
|
// odd->a[0] and odd->a[8] are odd
|
||||||
|
// even->a[0] or even->a[8] is even
|
||||||
//
|
//
|
||||||
// first u,v are large and s,r small
|
// first u/v are large and r/s small
|
||||||
// later u,v are small and s,r large
|
// later u/v are small and r/s large
|
||||||
|
assert(odd->a[0] & 1);
|
||||||
|
assert(odd->a[8] & 1);
|
||||||
|
|
||||||
// if (is_zero(v)) break;
|
// adjust length of even.
|
||||||
for (i = 0; i < len1; i++) {
|
while (even->a[even->len1 - 1] == 0) {
|
||||||
if (v[i]) break;
|
even->len1--;
|
||||||
}
|
// if input was 0, return.
|
||||||
if (i == len1) break;
|
// This simple check prevents crashing with stack underflow
|
||||||
|
// or worse undesired behaviour for illegal input.
|
||||||
// reduce u while it is even
|
if (even->len1 < 0)
|
||||||
for (;;) {
|
return;
|
||||||
// count up to 30 zero bits of u.
|
|
||||||
for (i = 0; i < 30; i++) {
|
|
||||||
if (u[0] & (1 << i)) break;
|
|
||||||
}
|
|
||||||
// if u was odd break
|
|
||||||
if (i == 0) break;
|
|
||||||
|
|
||||||
// shift u right by i bits.
|
|
||||||
mask = (1 << i) - 1;
|
|
||||||
for (j = 0; j + 1 < len1; j++) {
|
|
||||||
u[j] = (u[j] >> i) | ((u[j + 1] & mask) << (32 - i));
|
|
||||||
}
|
|
||||||
u[j] = (u[j] >> i);
|
|
||||||
|
|
||||||
// shift s left by i bits.
|
|
||||||
mask = (1 << (32 - i)) - 1;
|
|
||||||
s[len2] = s[len2 - 1] >> (32 - i);
|
|
||||||
for (j = len2 - 1; j > 0; j--) {
|
|
||||||
s[j] = (s[j - 1] >> (32 - i)) | ((s[j] & mask) << i);
|
|
||||||
}
|
|
||||||
s[0] = (s[0] & mask) << i;
|
|
||||||
// update len2 if necessary
|
|
||||||
if (s[len2]) {
|
|
||||||
r[len2] = 0;
|
|
||||||
len2++;
|
|
||||||
}
|
|
||||||
// add i bits to k.
|
|
||||||
k += i;
|
|
||||||
}
|
|
||||||
// reduce v while it is even
|
|
||||||
for (;;) {
|
|
||||||
// count up to 30 zero bits of v.
|
|
||||||
for (i = 0; i < 30; i++) {
|
|
||||||
if (v[0] & (1 << i)) break;
|
|
||||||
}
|
|
||||||
// if v was odd break
|
|
||||||
if (i == 0) break;
|
|
||||||
|
|
||||||
// shift v right by i bits.
|
|
||||||
mask = (1 << i) - 1;
|
|
||||||
for (j = 0; j + 1 < len1; j++) {
|
|
||||||
v[j] = (v[j] >> i) | ((v[j + 1] & mask) << (32 - i));
|
|
||||||
}
|
|
||||||
v[j] = (v[j] >> i);
|
|
||||||
mask = (1 << (32 - i)) - 1;
|
|
||||||
// shift r left by i bits.
|
|
||||||
r[len2] = r[len2 - 1] >> (32 - i);
|
|
||||||
for (j = len2 - 1; j > 0; j--) {
|
|
||||||
r[j] = (r[j - 1] >> (32 - i)) | ((r[j] & mask) << i);
|
|
||||||
}
|
|
||||||
r[0] = (r[0] & mask) << i;
|
|
||||||
// update len2 if necessary
|
|
||||||
if (r[len2]) {
|
|
||||||
s[len2] = 0;
|
|
||||||
len2++;
|
|
||||||
}
|
|
||||||
// add i bits to k.
|
|
||||||
k += i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// invariant is reestablished.
|
// reduce even->a while it is even
|
||||||
i = len1 - 1;
|
while (even->a[0] == 0) {
|
||||||
while (i > 0 && u[i] == v[i]) i--;
|
// shift right first part of even by a limb
|
||||||
if (u[i] > v[i]) {
|
// and shift left second part of even by a limb.
|
||||||
// u > v:
|
|
||||||
// u = (u - v)/2;
|
|
||||||
temp = 0x100000000ull + u[0] - v[0];
|
|
||||||
u[0] = (temp >> 1) & 0x7FFFFFFF;
|
|
||||||
temp >>= 32;
|
|
||||||
for (i = 1; i < len1; i++) {
|
|
||||||
temp += 0xFFFFFFFFull + u[i] - v[i];
|
|
||||||
u[i - 1] += (temp & 1) << 31;
|
|
||||||
u[i] = (temp >> 1) & 0x7FFFFFFF;
|
|
||||||
temp >>= 32;
|
|
||||||
}
|
|
||||||
temp = temp2 = 0;
|
|
||||||
// r += s;
|
|
||||||
// s += s;
|
|
||||||
for (i = 0; i < len2; i++) {
|
|
||||||
temp += s[i];
|
|
||||||
temp += r[i];
|
|
||||||
temp2 += s[i];
|
|
||||||
temp2 += s[i];
|
|
||||||
r[i] = temp;
|
|
||||||
s[i] = temp2;
|
|
||||||
temp >>= 32;
|
|
||||||
temp2 >>= 32;
|
|
||||||
}
|
|
||||||
// expand if necessary.
|
|
||||||
if (temp != 0 || temp2 != 0) {
|
|
||||||
r[len2] = temp;
|
|
||||||
s[len2] = temp2;
|
|
||||||
len2++;
|
|
||||||
}
|
|
||||||
// note that
|
|
||||||
// u'2^(k+1) = (u - v) 2^k = x -(r + s) = x -r' mod prime
|
|
||||||
// v'2^(k+1) = 2*v 2^k = x (s + s) = x s' mod prime
|
|
||||||
// u's' + v'r' = (u-v)/2(2s) + v(r+s) = us + vr
|
|
||||||
} else {
|
|
||||||
// v >= u:
|
|
||||||
// v = v - u;
|
|
||||||
temp = 0x100000000ull + v[0] - u[0];
|
|
||||||
v[0] = (temp >> 1) & 0x7FFFFFFF;
|
|
||||||
temp >>= 32;
|
|
||||||
for (i = 1; i < len1; i++) {
|
|
||||||
temp += 0xFFFFFFFFull + v[i] - u[i];
|
|
||||||
v[i - 1] += (temp & 1) << 31;
|
|
||||||
v[i] = (temp >> 1) & 0x7FFFFFFF;
|
|
||||||
temp >>= 32;
|
|
||||||
}
|
|
||||||
// s = s + r
|
|
||||||
// r = r + r
|
|
||||||
temp = temp2 = 0;
|
|
||||||
for (i = 0; i < len2; i++) {
|
|
||||||
temp += s[i];
|
|
||||||
temp += r[i];
|
|
||||||
temp2 += r[i];
|
|
||||||
temp2 += r[i];
|
|
||||||
s[i] = temp;
|
|
||||||
r[i] = temp2;
|
|
||||||
temp >>= 32;
|
|
||||||
temp2 >>= 32;
|
|
||||||
}
|
|
||||||
if (temp != 0 || temp2 != 0) {
|
|
||||||
s[len2] = temp;
|
|
||||||
r[len2] = temp2;
|
|
||||||
len2++;
|
|
||||||
}
|
|
||||||
// note that
|
|
||||||
// u'2^(k+1) = 2*u 2^k = x -(r + r) = x -r' mod prime
|
|
||||||
// v'2^(k+1) = (v - u) 2^k = x (s + r) = x s' mod prime
|
|
||||||
// u's' + v'r' = u(r+s) + (v-u)/2(2r) = us + vr
|
|
||||||
}
|
|
||||||
// adjust len1 if possible.
|
|
||||||
if (u[len1 - 1] == 0 && v[len1 - 1] == 0) len1--;
|
|
||||||
// increase k
|
|
||||||
k++;
|
|
||||||
}
|
|
||||||
// In the last iteration just before the comparison and subtraction
|
|
||||||
// we had u=1, v=1, s+r = prime, k <= 510, 2^k > max(s,r) >= prime/2
|
|
||||||
// hence 0 <= r < prime and 255 <= k <= 510.
|
|
||||||
//
|
|
||||||
// Afterwards r is doubled, k is incremented by 1.
|
|
||||||
// Hence 0 <= r < 2*prime and 256 <= k < 512.
|
|
||||||
//
|
|
||||||
// The invariants give us x*-r = 2^k mod prime,
|
|
||||||
// hence r = -2^k * x^-1 mod prime.
|
|
||||||
// We need to compute -r/2^k mod prime.
|
|
||||||
|
|
||||||
// convert r to bignum style
|
|
||||||
j = r[0] >> 30;
|
|
||||||
r[0] = r[0] & 0x3FFFFFFFu;
|
|
||||||
for (i = 1; i < len2; i++) {
|
|
||||||
uint32_t q = r[i] >> (30 - 2 * i);
|
|
||||||
r[i] = ((r[i] << (2 * i)) & 0x3FFFFFFFu) + j;
|
|
||||||
j=q;
|
|
||||||
}
|
|
||||||
r[i] = j;
|
|
||||||
i++;
|
|
||||||
for (; i < 9; i++) r[i] = 0;
|
|
||||||
|
|
||||||
// r = r mod prime, note that r<2*prime.
|
|
||||||
i = 8;
|
|
||||||
while (i > 0 && r[i] == prime->val[i]) i--;
|
|
||||||
if (r[i] >= prime->val[i]) {
|
|
||||||
temp32 = 1;
|
|
||||||
for (i = 0; i < 9; i++) {
|
|
||||||
temp32 += 0x3FFFFFFF + r[i] - prime->val[i];
|
|
||||||
r[i] = temp32 & 0x3FFFFFFF;
|
|
||||||
temp32 >>= 30;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// negate r: r = prime - r
|
|
||||||
temp32 = 1;
|
|
||||||
for (i = 0; i < 9; i++) {
|
|
||||||
temp32 += 0x3FFFFFFF + prime->val[i] - r[i];
|
|
||||||
r[i] = temp32 & 0x3FFFFFFF;
|
|
||||||
temp32 >>= 30;
|
|
||||||
}
|
|
||||||
// now: r = 2^k * x^-1 mod prime
|
|
||||||
// compute r/2^k, 256 <= k < 511
|
|
||||||
int done = 0;
|
|
||||||
#if USE_PRECOMPUTED_IV
|
|
||||||
if (prime == &prime256k1) {
|
|
||||||
for (j = 0; j < 9; j++) {
|
|
||||||
x->val[j] = r[j];
|
|
||||||
}
|
|
||||||
// secp256k1_iv[k-256] = 2^-k mod prime
|
|
||||||
bn_multiply(secp256k1_iv + k - 256, x, prime);
|
|
||||||
// bn_fast_mod is unnecessary as bn_multiply already
|
|
||||||
// guarantees x < 2*prime
|
|
||||||
bn_fast_mod(x, prime);
|
|
||||||
// We don't guarantee x < prime!
|
|
||||||
// the slow variant and the slow case below guarantee
|
|
||||||
// this.
|
|
||||||
done = 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (!done) {
|
|
||||||
// compute r = r/2^k mod prime
|
|
||||||
for (j = 0; j < k; j++) {
|
|
||||||
// invariant: r = 2^(k-j) * x^-1 mod prime
|
|
||||||
// in each iteration divide r by 2 modulo prime.
|
|
||||||
if (r[0] & 1) {
|
|
||||||
// r is odd; compute r = (prime + r)/2
|
|
||||||
temp32 = r[0] + prime->val[0];
|
|
||||||
r[0] = (temp32 >> 1) & 0x1FFFFFFF;
|
|
||||||
temp32 >>= 30;
|
|
||||||
for (i = 1; i < 9; i++) {
|
|
||||||
temp32 += r[i] + prime->val[i];
|
|
||||||
r[i - 1] += (temp32 & 1) << 29;
|
|
||||||
r[i] = (temp32 >> 1) & 0x1FFFFFFF;
|
|
||||||
temp32 >>= 30;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// r = r / 2
|
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
r[i] = (r[i] >> 1) | ((r[i + 1] & 1) << 29);
|
even->a[i] = even->a[i+1];
|
||||||
}
|
}
|
||||||
r[8] = r[8] >> 1;
|
even->a[i] = 0;
|
||||||
|
even->len1--;
|
||||||
|
k += 32;
|
||||||
}
|
}
|
||||||
|
// count up to 32 zero bits of even->a.
|
||||||
|
j = 0;
|
||||||
|
while ((even->a[0] & (1 << j)) == 0) {
|
||||||
|
j++;
|
||||||
}
|
}
|
||||||
// r = x^-1 mod prime, since j = k
|
if (j > 0) {
|
||||||
for (j = 0; j < 9; j++) {
|
// shift first part of even right by j bits.
|
||||||
x->val[j] = r[j];
|
for (i = 0; i + 1 < even->len1; i++) {
|
||||||
|
even->a[i] = (even->a[i] >> j) | (even->a[i + 1] << (32 - j));
|
||||||
}
|
}
|
||||||
|
even->a[i] = (even->a[i] >> j);
|
||||||
|
if (even->a[i] == 0) {
|
||||||
|
even->len1--;
|
||||||
|
} else {
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// shift second part of even left by j bits.
|
||||||
|
for (; i < 8; i++) {
|
||||||
|
even->a[i] = (even->a[i] << j) | (even->a[i + 1] >> (32 - j));
|
||||||
|
}
|
||||||
|
even->a[i] = (even->a[i] << j);
|
||||||
|
// add j bits to k.
|
||||||
|
k += j;
|
||||||
|
}
|
||||||
|
// invariant is reestablished.
|
||||||
|
// now both a[0] are odd.
|
||||||
|
assert(odd->a[0] & 1);
|
||||||
|
assert(odd->a[8] & 1);
|
||||||
|
assert(even->a[0] & 1);
|
||||||
|
assert((even->a[8] & 1) == 0);
|
||||||
|
|
||||||
|
// cmp > 0 if us.a[0..len1-1] > vr.a[0..len1-1],
|
||||||
|
// cmp = 0 if equal, < 0 if less.
|
||||||
|
cmp = us.len1 - vr.len1;
|
||||||
|
if (cmp == 0) {
|
||||||
|
i = us.len1 - 1;
|
||||||
|
while (i >= 0 && us.a[i] == vr.a[i]) i--;
|
||||||
|
// both are equal to 1 and we are done.
|
||||||
|
if (i == -1)
|
||||||
|
break;
|
||||||
|
cmp = us.a[i] > vr.a[i] ? 1 : -1;
|
||||||
|
}
|
||||||
|
if (cmp > 0) {
|
||||||
|
even = &us;
|
||||||
|
odd = &vr;
|
||||||
|
} else {
|
||||||
|
even = &vr;
|
||||||
|
odd = &us;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now even > odd.
|
||||||
|
|
||||||
|
// even->a[0..len1-1] = (even->a[0..len1-1] - odd->a[0..len1-1]);
|
||||||
|
temp = 1;
|
||||||
|
for (i = 0; i < odd->len1; i++) {
|
||||||
|
temp += 0xFFFFFFFFull + even->a[i] - odd->a[i];
|
||||||
|
even->a[i] = temp & 0xFFFFFFFF;
|
||||||
|
temp >>= 32;
|
||||||
|
}
|
||||||
|
for (; i < even->len1; i++) {
|
||||||
|
temp += 0xFFFFFFFFull + even->a[i];
|
||||||
|
even->a[i] = temp & 0xFFFFFFFF;
|
||||||
|
temp >>= 32;
|
||||||
|
}
|
||||||
|
// odd->a[len1..8] = (odd->b[len1..8] + even->b[len1..8]);
|
||||||
|
temp = 0;
|
||||||
|
for (i = 8; i >= even->len1; i--) {
|
||||||
|
temp += (uint64_t) odd->a[i] + even->a[i];
|
||||||
|
odd->a[i] = temp & 0xFFFFFFFF;
|
||||||
|
temp >>= 32;
|
||||||
|
}
|
||||||
|
for (; i >= odd->len1; i--) {
|
||||||
|
temp += (uint64_t) odd->a[i];
|
||||||
|
odd->a[i] = temp & 0xFFFFFFFF;
|
||||||
|
temp >>= 32;
|
||||||
|
}
|
||||||
|
// note that
|
||||||
|
// if u > v:
|
||||||
|
// u'2^k = (u - v) 2^k = x(-r) - xs = x(-(r+s)) = x(-r') mod prime
|
||||||
|
// u's' + v'r' = (u-v)s + v(r+s) = us + vr
|
||||||
|
// if u < v:
|
||||||
|
// v'2^k = (v - u) 2^k = xs - x(-r) = x(s+r) = xs' mod prime
|
||||||
|
// u's' + v'r' = u(s+r) + (v-u)r = us + vr
|
||||||
|
|
||||||
|
// even->a[0] is difference between two odd numbers, hence even.
|
||||||
|
// odd->a[8] is sum of even and odd number, hence odd.
|
||||||
|
assert(odd->a[0] & 1);
|
||||||
|
assert(odd->a[8] & 1);
|
||||||
|
assert((even->a[0] & 1) == 0);
|
||||||
|
|
||||||
|
// The invariants are (almost) reestablished.
|
||||||
|
// The invariant max(u,v) <= 2^k can be invalidated at this point,
|
||||||
|
// because odd->a[len1..8] was changed. We only have
|
||||||
|
//
|
||||||
|
// odd->a[len1..8] <= 2^{k+1}
|
||||||
|
//
|
||||||
|
// Since even->a[0] is even, k will be incremented at the beginning
|
||||||
|
// of the next loop while odd->a[len1..8] remains unchanged.
|
||||||
|
// So after that, odd->a[len1..8] <= 2^k will hold again.
|
||||||
|
}
|
||||||
|
// In the last iteration we had u = v and gcd(u,v) = 1.
|
||||||
|
// Hence, u=1, v=1, s+r = prime, k <= 510, 2^k > max(s,r) >= prime/2
|
||||||
|
// This implies 0 <= s < prime and 255 <= k <= 510.
|
||||||
|
//
|
||||||
|
// The invariants also give us x*s = 2^k mod prime,
|
||||||
|
// hence s = -2^k * x^-1 mod prime.
|
||||||
|
// We need to compute -s/2^k mod prime.
|
||||||
|
|
||||||
|
// First we compute inverse = -prime^-1 mod 2^32, which we need later.
|
||||||
|
// We use the Explicit Quadratic Modular inverse algorithm.
|
||||||
|
// http://arxiv.org/pdf/1209.6626.pdf
|
||||||
|
// a^-1 = (2-a) * PROD_i (1 + (a - 1)^(2^i)) mod 2^32
|
||||||
|
// the product will converge quickly, because (a-1)^(2^i) will be
|
||||||
|
// zero mod 2^32 after at most five iterations.
|
||||||
|
// We want to compute -prime^-1 so we start with (pp[0]-2).
|
||||||
|
assert(pp[0] & 1);
|
||||||
|
uint32_t amone = pp[0]-1;
|
||||||
|
uint32_t inverse = pp[0] - 2;
|
||||||
|
while (amone) {
|
||||||
|
amone *= amone;
|
||||||
|
inverse *= (amone + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (k >= 32) {
|
||||||
|
// compute s / 2^32 modulo prime.
|
||||||
|
// Idea: compute factor, such that
|
||||||
|
// s + factor*prime mod 2^32 == 0
|
||||||
|
// i.e. factor = s * -1/prime mod 2^32.
|
||||||
|
// Then compute s + factor*prime and shift right by 32 bits.
|
||||||
|
uint32_t factor = (inverse * us.a[8]) & 0xffffffff;
|
||||||
|
temp = us.a[8] + (uint64_t) pp[0] * factor;
|
||||||
|
// printf("%lx %x %x %x\n", temp, us.b[0], inverse, factor);
|
||||||
|
assert((temp & 0xffffffff) == 0);
|
||||||
|
temp >>= 32;
|
||||||
|
for (i = 0; i < 7; i++) {
|
||||||
|
temp += us.a[8-(i+1)] + (uint64_t) pp[i+1] * factor;
|
||||||
|
us.a[8-i] = temp & 0xffffffff;
|
||||||
|
temp >>= 32;
|
||||||
|
}
|
||||||
|
us.a[8-i] = temp & 0xffffffff;
|
||||||
|
k -= 32;
|
||||||
|
}
|
||||||
|
if (k > 0) {
|
||||||
|
// compute s / 2^k modulo prime.
|
||||||
|
// Same idea: compute factor, such that
|
||||||
|
// s + factor*prime mod 2^k == 0
|
||||||
|
// i.e. factor = s * -1/prime mod 2^k.
|
||||||
|
// Then compute s + factor*prime and shift right by k bits.
|
||||||
|
uint32_t mask = (1 << k) - 1;
|
||||||
|
uint32_t factor = (inverse * us.a[8]) & mask;
|
||||||
|
temp = (us.a[8] + (uint64_t) pp[0] * factor) >> k;
|
||||||
|
assert(((us.a[8] + pp[0] * factor) & mask) == 0);
|
||||||
|
for (i = 0; i < 7; i++) {
|
||||||
|
temp += (us.a[8-(i+1)] + (uint64_t) pp[i+1] * factor) << (32 - k);
|
||||||
|
us.a[8-i] = temp & 0xffffffff;
|
||||||
|
temp >>= 32;
|
||||||
|
}
|
||||||
|
us.a[8-i] = temp & 0xffffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert s to bignum style
|
||||||
|
temp32 = 0;
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
x->val[i] = ((us.a[8-i] << (2 * i)) & 0x3FFFFFFFu) | temp32;
|
||||||
|
temp32 = us.a[8-i] >> (30 - 2 * i);
|
||||||
|
}
|
||||||
|
x->val[i] = temp32;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -23,11 +23,6 @@
|
|||||||
#ifndef __OPTIONS_H__
|
#ifndef __OPTIONS_H__
|
||||||
#define __OPTIONS_H__
|
#define __OPTIONS_H__
|
||||||
|
|
||||||
// use precomputed Inverse Values of powers of two
|
|
||||||
#ifndef USE_PRECOMPUTED_IV
|
|
||||||
#define USE_PRECOMPUTED_IV 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// use precomputed Curve Points (some scalar multiples of curve base point G)
|
// use precomputed Curve Points (some scalar multiples of curve base point G)
|
||||||
#ifndef USE_PRECOMPUTED_CP
|
#ifndef USE_PRECOMPUTED_CP
|
||||||
#define USE_PRECOMPUTED_CP 1
|
#define USE_PRECOMPUTED_CP 1
|
||||||
|
261
secp256k1.c
261
secp256k1.c
@ -39,267 +39,6 @@ const bignum256 order256k1_half = {
|
|||||||
const bignum256 three_over_two256k1 = {
|
const bignum256 three_over_two256k1 = {
|
||||||
/*.val =*/{0x3ffffe19, 0x3ffffffd, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x7fff}};
|
/*.val =*/{0x3ffffe19, 0x3ffffffd, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x7fff}};
|
||||||
|
|
||||||
#if USE_PRECOMPUTED_IV
|
|
||||||
const bignum256 secp256k1_iv[256] = {
|
|
||||||
{/*.val =*/{0x868192a, 0x20e02474, 0x24a059d, 0x2c88ffb7, 0x32b761bc, 0x1b0b0a57, 0x383999c4, 0x6414554, 0xc9bd}},
|
|
||||||
{/*.val =*/{0x4340c95, 0x3070123a, 0x212502ce, 0x16447fdb, 0x395bb0de, 0xd85852b, 0x1c1ccce2, 0x2320a2aa, 0x64de}},
|
|
||||||
{/*.val =*/{0x21a0462, 0x1838091b, 0x30928167, 0xb223fed, 0x3cadd86f, 0x6c2c295, 0xe0e6671, 0x11905155, 0xb26f}},
|
|
||||||
{/*.val =*/{0x210d0231, 0x2c1c048d, 0x384940b3, 0x25911ff6, 0x3e56ec37, 0x2361614a, 0x27073338, 0x28c828aa, 0x5937}},
|
|
||||||
{/*.val =*/{0x30867f30, 0x360e0244, 0x1c24a059, 0x32c88ffb, 0x1f2b761b, 0x11b0b0a5, 0x1383999c, 0x34641455, 0xac9b}},
|
|
||||||
{/*.val =*/{0x18433f98, 0x3b070122, 0x2e12502c, 0x396447fd, 0x2f95bb0d, 0x8d85852, 0x29c1ccce, 0x3a320a2a, 0x564d}},
|
|
||||||
{/*.val =*/{0xc219fcc, 0x1d838091, 0x37092816, 0x3cb223fe, 0x17cadd86, 0x46c2c29, 0x14e0e667, 0x3d190515, 0x2b26}},
|
|
||||||
{/*.val =*/{0x2610cfe6, 0xec1c048, 0x1b84940b, 0x1e5911ff, 0x2be56ec3, 0x22361614, 0x2a707333, 0x1e8c828a, 0x1593}},
|
|
||||||
{/*.val =*/{0x130867f3, 0x2760e024, 0x2dc24a05, 0x2f2c88ff, 0x15f2b761, 0x311b0b0a, 0x15383999, 0x2f464145, 0xac9}},
|
|
||||||
{/*.val =*/{0x9843211, 0x33b07010, 0x36e12502, 0x3796447f, 0xaf95bb0, 0x388d8585, 0x2a9c1ccc, 0x37a320a2, 0x8564}},
|
|
||||||
{/*.val =*/{0x4c21720, 0x19d83806, 0x3b709281, 0x1bcb223f, 0x257cadd8, 0x1c46c2c2, 0x154e0e66, 0x1bd19051, 0xc2b2}},
|
|
||||||
{/*.val =*/{0x2610b90, 0x2cec1c03, 0x3db84940, 0xde5911f, 0x12be56ec, 0xe236161, 0x2aa70733, 0xde8c828, 0x6159}},
|
|
||||||
{/*.val =*/{0x213085c8, 0x16760e01, 0x3edc24a0, 0x6f2c88f, 0x295f2b76, 0x2711b0b0, 0x15538399, 0x26f46414, 0x30ac}},
|
|
||||||
{/*.val =*/{0x309842e4, 0xb3b0700, 0x3f6e1250, 0x3796447, 0x14af95bb, 0x3388d858, 0xaa9c1cc, 0x137a320a, 0x1856}},
|
|
||||||
{/*.val =*/{0x184c2172, 0x59d8380, 0x3fb70928, 0x21bcb223, 0xa57cadd, 0x19c46c2c, 0x554e0e6, 0x9bd1905, 0xc2b}},
|
|
||||||
{/*.val =*/{0xc2610b9, 0x2cec1c0, 0x3fdb8494, 0x30de5911, 0x52be56e, 0xce23616, 0x22aa7073, 0x24de8c82, 0x615}},
|
|
||||||
{/*.val =*/{0x6130674, 0x16760de, 0x3fedc24a, 0x186f2c88, 0x295f2b7, 0x26711b0b, 0x11553839, 0x326f4641, 0x830a}},
|
|
||||||
{/*.val =*/{0x309833a, 0xb3b06f, 0x1ff6e125, 0x2c379644, 0x214af95b, 0x33388d85, 0x28aa9c1c, 0x1937a320, 0x4185}},
|
|
||||||
{/*.val =*/{0x2184c19d, 0x2059d837, 0xffb7092, 0x361bcb22, 0x30a57cad, 0x199c46c2, 0x14554e0e, 0x2c9bd190, 0x20c2}},
|
|
||||||
{/*.val =*/{0x30c25ee6, 0x102cec19, 0x7fdb849, 0x3b0de591, 0x1852be56, 0xcce2361, 0xa2aa707, 0x164de8c8, 0x9061}},
|
|
||||||
{/*.val =*/{0x38612f73, 0x2816760c, 0x23fedc24, 0x1d86f2c8, 0x2c295f2b, 0x266711b0, 0x5155383, 0x2b26f464, 0x4830}},
|
|
||||||
{/*.val =*/{0x1c3095d1, 0x140b3b04, 0x11ff6e12, 0x2ec37964, 0x1614af95, 0x333388d8, 0x28aa9c1, 0x15937a32, 0xa418}},
|
|
||||||
{/*.val =*/{0xe184900, 0xa059d80, 0x8ffb709, 0x3761bcb2, 0xb0a57ca, 0x3999c46c, 0x14554e0, 0xac9bd19, 0xd20c}},
|
|
||||||
{/*.val =*/{0x70c2480, 0x2502cec0, 0x47fdb84, 0x1bb0de59, 0x5852be5, 0x1ccce236, 0x20a2aa70, 0x564de8c, 0x6906}},
|
|
||||||
{/*.val =*/{0x3861240, 0x12816760, 0x223fedc2, 0x2dd86f2c, 0x2c295f2, 0xe66711b, 0x10515538, 0x2b26f46, 0x3483}},
|
|
||||||
{/*.val =*/{0x1c30920, 0x940b3b0, 0x111ff6e1, 0x16ec3796, 0x21614af9, 0x733388d, 0x828aa9c, 0x215937a3, 0x1a41}},
|
|
||||||
{/*.val =*/{0xe18490, 0x24a059d8, 0x88ffb70, 0x2b761bcb, 0x30b0a57c, 0x3999c46, 0x2414554e, 0x30ac9bd1, 0xd20}},
|
|
||||||
{/*.val =*/{0x70c248, 0x12502cec, 0x2447fdb8, 0x15bb0de5, 0x185852be, 0x1ccce23, 0x320a2aa7, 0x18564de8, 0x690}},
|
|
||||||
{/*.val =*/{0x386124, 0x9281676, 0x3223fedc, 0xadd86f2, 0x2c2c295f, 0x20e66711, 0x19051553, 0xc2b26f4, 0x348}},
|
|
||||||
{/*.val =*/{0x1c3092, 0x4940b3b, 0x1911ff6e, 0x256ec379, 0x361614af, 0x30733388, 0xc828aa9, 0x615937a, 0x1a4}},
|
|
||||||
{/*.val =*/{0x200e1849, 0x24a059d, 0x2c88ffb7, 0x32b761bc, 0x1b0b0a57, 0x383999c4, 0x6414554, 0x30ac9bd, 0xd2}},
|
|
||||||
{/*.val =*/{0x30070a3c, 0x212502cc, 0x16447fdb, 0x395bb0de, 0xd85852b, 0x1c1ccce2, 0x2320a2aa, 0x18564de, 0x8069}},
|
|
||||||
{/*.val =*/{0x1803851e, 0x30928166, 0xb223fed, 0x3cadd86f, 0x6c2c295, 0xe0e6671, 0x11905155, 0x20c2b26f, 0x4034}},
|
|
||||||
{/*.val =*/{0xc01c28f, 0x384940b3, 0x25911ff6, 0x3e56ec37, 0x2361614a, 0x27073338, 0x28c828aa, 0x10615937, 0x201a}},
|
|
||||||
{/*.val =*/{0x2600df5f, 0x1c24a057, 0x32c88ffb, 0x1f2b761b, 0x11b0b0a5, 0x1383999c, 0x34641455, 0x830ac9b, 0x900d}},
|
|
||||||
{/*.val =*/{0x33006dc7, 0x2e125029, 0x396447fd, 0x2f95bb0d, 0x8d85852, 0x29c1ccce, 0x3a320a2a, 0x2418564d, 0xc806}},
|
|
||||||
{/*.val =*/{0x398034fb, 0x37092812, 0x3cb223fe, 0x17cadd86, 0x46c2c29, 0x14e0e667, 0x3d190515, 0x120c2b26, 0xe403}},
|
|
||||||
{/*.val =*/{0x1cc01895, 0x1b849407, 0x1e5911ff, 0x2be56ec3, 0x22361614, 0x2a707333, 0x1e8c828a, 0x29061593, 0xf201}},
|
|
||||||
{/*.val =*/{0x2e600a62, 0x2dc24a01, 0x2f2c88ff, 0x15f2b761, 0x311b0b0a, 0x15383999, 0x2f464145, 0x34830ac9, 0xf900}},
|
|
||||||
{/*.val =*/{0x37300531, 0x36e12500, 0x3796447f, 0xaf95bb0, 0x388d8585, 0x2a9c1ccc, 0x37a320a2, 0x1a418564, 0x7c80}},
|
|
||||||
{/*.val =*/{0x1b9800b0, 0x3b70927e, 0x1bcb223f, 0x257cadd8, 0x1c46c2c2, 0x154e0e66, 0x1bd19051, 0xd20c2b2, 0xbe40}},
|
|
||||||
{/*.val =*/{0xdcc0058, 0x3db8493f, 0xde5911f, 0x12be56ec, 0xe236161, 0x2aa70733, 0xde8c828, 0x6906159, 0x5f20}},
|
|
||||||
{/*.val =*/{0x26e6002c, 0x3edc249f, 0x6f2c88f, 0x295f2b76, 0x2711b0b0, 0x15538399, 0x26f46414, 0x34830ac, 0x2f90}},
|
|
||||||
{/*.val =*/{0x33730016, 0x3f6e124f, 0x3796447, 0x14af95bb, 0x3388d858, 0xaa9c1cc, 0x137a320a, 0x1a41856, 0x17c8}},
|
|
||||||
{/*.val =*/{0x39b9800b, 0x3fb70927, 0x21bcb223, 0xa57cadd, 0x19c46c2c, 0x554e0e6, 0x9bd1905, 0xd20c2b, 0xbe4}},
|
|
||||||
{/*.val =*/{0x3cdcbe1d, 0x3fdb8491, 0x30de5911, 0x52be56e, 0xce23616, 0x22aa7073, 0x24de8c82, 0x690615, 0x85f2}},
|
|
||||||
{/*.val =*/{0x3e6e5d26, 0x3fedc246, 0x186f2c88, 0x295f2b7, 0x26711b0b, 0x11553839, 0x326f4641, 0x34830a, 0xc2f9}},
|
|
||||||
{/*.val =*/{0x1f372e93, 0x1ff6e123, 0x2c379644, 0x214af95b, 0x33388d85, 0x28aa9c1c, 0x1937a320, 0x201a4185, 0x617c}},
|
|
||||||
{/*.val =*/{0x2f9b9561, 0xffb708f, 0x361bcb22, 0x30a57cad, 0x199c46c2, 0x14554e0e, 0x2c9bd190, 0x100d20c2, 0xb0be}},
|
|
||||||
{/*.val =*/{0x37cdc8c8, 0x7fdb845, 0x3b0de591, 0x1852be56, 0xcce2361, 0xa2aa707, 0x164de8c8, 0x8069061, 0xd85f}},
|
|
||||||
{/*.val =*/{0x3be6e464, 0x23fedc22, 0x1d86f2c8, 0x2c295f2b, 0x266711b0, 0x5155383, 0x2b26f464, 0x24034830, 0x6c2f}},
|
|
||||||
{/*.val =*/{0x1df37232, 0x11ff6e11, 0x2ec37964, 0x1614af95, 0x333388d8, 0x28aa9c1, 0x15937a32, 0x3201a418, 0x3617}},
|
|
||||||
{/*.val =*/{0x2ef9b919, 0x8ffb708, 0x3761bcb2, 0xb0a57ca, 0x3999c46c, 0x14554e0, 0xac9bd19, 0x3900d20c, 0x1b0b}},
|
|
||||||
{/*.val =*/{0x177cdaa4, 0x47fdb82, 0x1bb0de59, 0x5852be5, 0x1ccce236, 0x20a2aa70, 0x564de8c, 0x3c806906, 0x8d85}},
|
|
||||||
{/*.val =*/{0xbbe6d52, 0x223fedc1, 0x2dd86f2c, 0x2c295f2, 0xe66711b, 0x10515538, 0x2b26f46, 0x3e403483, 0x46c2}},
|
|
||||||
{/*.val =*/{0x25df36a9, 0x111ff6e0, 0x16ec3796, 0x21614af9, 0x733388d, 0x828aa9c, 0x215937a3, 0x1f201a41, 0x2361}},
|
|
||||||
{/*.val =*/{0x12ef996c, 0x88ffb6e, 0x2b761bcb, 0x30b0a57c, 0x3999c46, 0x2414554e, 0x30ac9bd1, 0x2f900d20, 0x91b0}},
|
|
||||||
{/*.val =*/{0x977ccb6, 0x2447fdb7, 0x15bb0de5, 0x185852be, 0x1ccce23, 0x320a2aa7, 0x18564de8, 0x17c80690, 0x48d8}},
|
|
||||||
{/*.val =*/{0x24bbe65b, 0x3223fedb, 0xadd86f2, 0x2c2c295f, 0x20e66711, 0x19051553, 0xc2b26f4, 0xbe40348, 0x246c}},
|
|
||||||
{/*.val =*/{0x325df145, 0x1911ff6b, 0x256ec379, 0x361614af, 0x30733388, 0xc828aa9, 0x615937a, 0x5f201a4, 0x9236}},
|
|
||||||
{/*.val =*/{0x392ef6ba, 0x2c88ffb3, 0x32b761bc, 0x1b0b0a57, 0x383999c4, 0x6414554, 0x30ac9bd, 0x2f900d2, 0xc91b}},
|
|
||||||
{/*.val =*/{0x3c977b5d, 0x16447fd9, 0x395bb0de, 0xd85852b, 0x1c1ccce2, 0x2320a2aa, 0x18564de, 0x217c8069, 0x648d}},
|
|
||||||
{/*.val =*/{0x3e4bbbc6, 0xb223fea, 0x3cadd86f, 0x6c2c295, 0xe0e6671, 0x11905155, 0x20c2b26f, 0x30be4034, 0xb246}},
|
|
||||||
{/*.val =*/{0x1f25dde3, 0x25911ff5, 0x3e56ec37, 0x2361614a, 0x27073338, 0x28c828aa, 0x10615937, 0x185f201a, 0x5923}},
|
|
||||||
{/*.val =*/{0x2f92ed09, 0x32c88ff8, 0x1f2b761b, 0x11b0b0a5, 0x1383999c, 0x34641455, 0x830ac9b, 0x2c2f900d, 0xac91}},
|
|
||||||
{/*.val =*/{0x17c9749c, 0x396447fa, 0x2f95bb0d, 0x8d85852, 0x29c1ccce, 0x3a320a2a, 0x2418564d, 0x3617c806, 0xd648}},
|
|
||||||
{/*.val =*/{0xbe4ba4e, 0x3cb223fd, 0x17cadd86, 0x46c2c29, 0x14e0e667, 0x3d190515, 0x120c2b26, 0x1b0be403, 0x6b24}},
|
|
||||||
{/*.val =*/{0x25f25d27, 0x1e5911fe, 0x2be56ec3, 0x22361614, 0x2a707333, 0x1e8c828a, 0x29061593, 0xd85f201, 0x3592}},
|
|
||||||
{/*.val =*/{0x12f92cab, 0x2f2c88fd, 0x15f2b761, 0x311b0b0a, 0x15383999, 0x2f464145, 0x34830ac9, 0x6c2f900, 0x9ac9}},
|
|
||||||
{/*.val =*/{0x297c946d, 0x3796447c, 0xaf95bb0, 0x388d8585, 0x2a9c1ccc, 0x37a320a2, 0x1a418564, 0x23617c80, 0xcd64}},
|
|
||||||
{/*.val =*/{0x14be484e, 0x1bcb223c, 0x257cadd8, 0x1c46c2c2, 0x154e0e66, 0x1bd19051, 0xd20c2b2, 0x11b0be40, 0xe6b2}},
|
|
||||||
{/*.val =*/{0xa5f2427, 0xde5911e, 0x12be56ec, 0xe236161, 0x2aa70733, 0xde8c828, 0x6906159, 0x8d85f20, 0x7359}},
|
|
||||||
{/*.val =*/{0x52f902b, 0x6f2c88d, 0x295f2b76, 0x2711b0b0, 0x15538399, 0x26f46414, 0x34830ac, 0x246c2f90, 0xb9ac}},
|
|
||||||
{/*.val =*/{0x2297c62d, 0x3796444, 0x14af95bb, 0x3388d858, 0xaa9c1cc, 0x137a320a, 0x1a41856, 0x123617c8, 0xdcd6}},
|
|
||||||
{/*.val =*/{0x114be12e, 0x21bcb220, 0xa57cadd, 0x19c46c2c, 0x554e0e6, 0x9bd1905, 0xd20c2b, 0x91b0be4, 0xee6b}},
|
|
||||||
{/*.val =*/{0x8a5f097, 0x30de5910, 0x52be56e, 0xce23616, 0x22aa7073, 0x24de8c82, 0x690615, 0x248d85f2, 0x7735}},
|
|
||||||
{/*.val =*/{0x452f663, 0x186f2c86, 0x295f2b7, 0x26711b0b, 0x11553839, 0x326f4641, 0x34830a, 0x3246c2f9, 0xbb9a}},
|
|
||||||
{/*.val =*/{0x2297949, 0x2c379641, 0x214af95b, 0x33388d85, 0x28aa9c1c, 0x1937a320, 0x201a4185, 0x1923617c, 0xddcd}},
|
|
||||||
{/*.val =*/{0x2114babc, 0x361bcb1e, 0x30a57cad, 0x199c46c2, 0x14554e0e, 0x2c9bd190, 0x100d20c2, 0x2c91b0be, 0xeee6}},
|
|
||||||
{/*.val =*/{0x108a5d5e, 0x3b0de58f, 0x1852be56, 0xcce2361, 0xa2aa707, 0x164de8c8, 0x8069061, 0x1648d85f, 0x7773}},
|
|
||||||
{/*.val =*/{0x28452eaf, 0x1d86f2c7, 0x2c295f2b, 0x266711b0, 0x5155383, 0x2b26f464, 0x24034830, 0x2b246c2f, 0x3bb9}},
|
|
||||||
{/*.val =*/{0x3422956f, 0x2ec37961, 0x1614af95, 0x333388d8, 0x28aa9c1, 0x15937a32, 0x3201a418, 0x35923617, 0x9ddc}},
|
|
||||||
{/*.val =*/{0x3a1148cf, 0x3761bcae, 0xb0a57ca, 0x3999c46c, 0x14554e0, 0xac9bd19, 0x3900d20c, 0x1ac91b0b, 0xceee}},
|
|
||||||
{/*.val =*/{0x1d08a27f, 0x1bb0de55, 0x5852be5, 0x1ccce236, 0x20a2aa70, 0x564de8c, 0x3c806906, 0xd648d85, 0xe777}},
|
|
||||||
{/*.val =*/{0x2e844f57, 0x2dd86f28, 0x2c295f2, 0xe66711b, 0x10515538, 0x2b26f46, 0x3e403483, 0x26b246c2, 0xf3bb}},
|
|
||||||
{/*.val =*/{0x174225c3, 0x16ec3792, 0x21614af9, 0x733388d, 0x828aa9c, 0x215937a3, 0x1f201a41, 0x33592361, 0xf9dd}},
|
|
||||||
{/*.val =*/{0xba110f9, 0x2b761bc7, 0x30b0a57c, 0x3999c46, 0x2414554e, 0x30ac9bd1, 0x2f900d20, 0x39ac91b0, 0xfcee}},
|
|
||||||
{/*.val =*/{0x25d08694, 0x15bb0de1, 0x185852be, 0x1ccce23, 0x320a2aa7, 0x18564de8, 0x17c80690, 0x1cd648d8, 0xfe77}},
|
|
||||||
{/*.val =*/{0x32e8434a, 0xadd86f0, 0x2c2c295f, 0x20e66711, 0x19051553, 0xc2b26f4, 0xbe40348, 0x2e6b246c, 0x7f3b}},
|
|
||||||
{/*.val =*/{0x197421a5, 0x256ec378, 0x361614af, 0x30733388, 0xc828aa9, 0x615937a, 0x5f201a4, 0x37359236, 0x3f9d}},
|
|
||||||
{/*.val =*/{0xcba0eea, 0x32b761ba, 0x1b0b0a57, 0x383999c4, 0x6414554, 0x30ac9bd, 0x2f900d2, 0x3b9ac91b, 0x9fce}},
|
|
||||||
{/*.val =*/{0x65d0775, 0x395bb0dd, 0xd85852b, 0x1c1ccce2, 0x2320a2aa, 0x18564de, 0x217c8069, 0x1dcd648d, 0x4fe7}},
|
|
||||||
{/*.val =*/{0x232e81d2, 0x3cadd86c, 0x6c2c295, 0xe0e6671, 0x11905155, 0x20c2b26f, 0x30be4034, 0x2ee6b246, 0xa7f3}},
|
|
||||||
{/*.val =*/{0x119740e9, 0x3e56ec36, 0x2361614a, 0x27073338, 0x28c828aa, 0x10615937, 0x185f201a, 0x37735923, 0x53f9}},
|
|
||||||
{/*.val =*/{0x8cb9e8c, 0x1f2b7619, 0x11b0b0a5, 0x1383999c, 0x34641455, 0x830ac9b, 0x2c2f900d, 0x3bb9ac91, 0xa9fc}},
|
|
||||||
{/*.val =*/{0x2465cf46, 0x2f95bb0c, 0x8d85852, 0x29c1ccce, 0x3a320a2a, 0x2418564d, 0x3617c806, 0x1ddcd648, 0x54fe}},
|
|
||||||
{/*.val =*/{0x1232e7a3, 0x17cadd86, 0x46c2c29, 0x14e0e667, 0x3d190515, 0x120c2b26, 0x1b0be403, 0xeee6b24, 0x2a7f}},
|
|
||||||
{/*.val =*/{0x91971e9, 0x2be56ec1, 0x22361614, 0x2a707333, 0x1e8c828a, 0x29061593, 0xd85f201, 0x27773592, 0x953f}},
|
|
||||||
{/*.val =*/{0x248cb70c, 0x15f2b75e, 0x311b0b0a, 0x15383999, 0x2f464145, 0x34830ac9, 0x6c2f900, 0x33bb9ac9, 0xca9f}},
|
|
||||||
{/*.val =*/{0x12465b86, 0xaf95baf, 0x388d8585, 0x2a9c1ccc, 0x37a320a2, 0x1a418564, 0x23617c80, 0x39ddcd64, 0x654f}},
|
|
||||||
{/*.val =*/{0x29232dc3, 0x257cadd7, 0x1c46c2c2, 0x154e0e66, 0x1bd19051, 0xd20c2b2, 0x11b0be40, 0x3ceee6b2, 0x32a7}},
|
|
||||||
{/*.val =*/{0x349194f9, 0x12be56e9, 0xe236161, 0x2aa70733, 0xde8c828, 0x6906159, 0x8d85f20, 0x3e777359, 0x9953}},
|
|
||||||
{/*.val =*/{0x3a48c894, 0x295f2b72, 0x2711b0b0, 0x15538399, 0x26f46414, 0x34830ac, 0x246c2f90, 0x3f3bb9ac, 0xcca9}},
|
|
||||||
{/*.val =*/{0x1d24644a, 0x14af95b9, 0x3388d858, 0xaa9c1cc, 0x137a320a, 0x1a41856, 0x123617c8, 0x3f9ddcd6, 0x6654}},
|
|
||||||
{/*.val =*/{0x2e923225, 0xa57cadc, 0x19c46c2c, 0x554e0e6, 0x9bd1905, 0xd20c2b, 0x91b0be4, 0x1fceee6b, 0x332a}},
|
|
||||||
{/*.val =*/{0x1749172a, 0x52be56c, 0xce23616, 0x22aa7073, 0x24de8c82, 0x690615, 0x248d85f2, 0xfe77735, 0x9995}},
|
|
||||||
{/*.val =*/{0xba48b95, 0x295f2b6, 0x26711b0b, 0x11553839, 0x326f4641, 0x34830a, 0x3246c2f9, 0x27f3bb9a, 0x4cca}},
|
|
||||||
{/*.val =*/{0x5d243e2, 0x214af959, 0x33388d85, 0x28aa9c1c, 0x1937a320, 0x201a4185, 0x1923617c, 0x13f9ddcd, 0xa665}},
|
|
||||||
{/*.val =*/{0x22e921f1, 0x30a57cac, 0x199c46c2, 0x14554e0e, 0x2c9bd190, 0x100d20c2, 0x2c91b0be, 0x29fceee6, 0x5332}},
|
|
||||||
{/*.val =*/{0x11748f10, 0x1852be54, 0xcce2361, 0xa2aa707, 0x164de8c8, 0x8069061, 0x1648d85f, 0x14fe7773, 0xa999}},
|
|
||||||
{/*.val =*/{0x8ba4788, 0x2c295f2a, 0x266711b0, 0x5155383, 0x2b26f464, 0x24034830, 0x2b246c2f, 0x2a7f3bb9, 0x54cc}},
|
|
||||||
{/*.val =*/{0x45d23c4, 0x1614af95, 0x333388d8, 0x28aa9c1, 0x15937a32, 0x3201a418, 0x35923617, 0x153f9ddc, 0x2a66}},
|
|
||||||
{/*.val =*/{0x222e91e2, 0xb0a57ca, 0x3999c46c, 0x14554e0, 0xac9bd19, 0x3900d20c, 0x1ac91b0b, 0xa9fceee, 0x1533}},
|
|
||||||
{/*.val =*/{0x111748f1, 0x5852be5, 0x1ccce236, 0x20a2aa70, 0x564de8c, 0x3c806906, 0xd648d85, 0x254fe777, 0xa99}},
|
|
||||||
{/*.val =*/{0x288ba290, 0x2c295f0, 0xe66711b, 0x10515538, 0x2b26f46, 0x3e403483, 0x26b246c2, 0x32a7f3bb, 0x854c}},
|
|
||||||
{/*.val =*/{0x1445d148, 0x21614af8, 0x733388d, 0x828aa9c, 0x215937a3, 0x1f201a41, 0x33592361, 0x1953f9dd, 0x42a6}},
|
|
||||||
{/*.val =*/{0xa22e8a4, 0x30b0a57c, 0x3999c46, 0x2414554e, 0x30ac9bd1, 0x2f900d20, 0x39ac91b0, 0xca9fcee, 0x2153}},
|
|
||||||
{/*.val =*/{0x5117452, 0x185852be, 0x1ccce23, 0x320a2aa7, 0x18564de8, 0x17c80690, 0x1cd648d8, 0x2654fe77, 0x10a9}},
|
|
||||||
{/*.val =*/{0x288ba29, 0x2c2c295f, 0x20e66711, 0x19051553, 0xc2b26f4, 0xbe40348, 0x2e6b246c, 0x332a7f3b, 0x854}},
|
|
||||||
{/*.val =*/{0x21445b2c, 0x361614ad, 0x30733388, 0xc828aa9, 0x615937a, 0x5f201a4, 0x37359236, 0x19953f9d, 0x842a}},
|
|
||||||
{/*.val =*/{0x30a22d96, 0x1b0b0a56, 0x383999c4, 0x6414554, 0x30ac9bd, 0x2f900d2, 0x3b9ac91b, 0xcca9fce, 0x4215}},
|
|
||||||
{/*.val =*/{0x185116cb, 0xd85852b, 0x1c1ccce2, 0x2320a2aa, 0x18564de, 0x217c8069, 0x1dcd648d, 0x26654fe7, 0x210a}},
|
|
||||||
{/*.val =*/{0x2c28897d, 0x6c2c293, 0xe0e6671, 0x11905155, 0x20c2b26f, 0x30be4034, 0x2ee6b246, 0x1332a7f3, 0x9085}},
|
|
||||||
{/*.val =*/{0x361442d6, 0x23616147, 0x27073338, 0x28c828aa, 0x10615937, 0x185f201a, 0x37735923, 0x299953f9, 0xc842}},
|
|
||||||
{/*.val =*/{0x3b0a216b, 0x11b0b0a3, 0x1383999c, 0x34641455, 0x830ac9b, 0x2c2f900d, 0x3bb9ac91, 0x14cca9fc, 0x6421}},
|
|
||||||
{/*.val =*/{0x3d850ecd, 0x8d8584f, 0x29c1ccce, 0x3a320a2a, 0x2418564d, 0x3617c806, 0x1ddcd648, 0x2a6654fe, 0xb210}},
|
|
||||||
{/*.val =*/{0x3ec2857e, 0x46c2c25, 0x14e0e667, 0x3d190515, 0x120c2b26, 0x1b0be403, 0xeee6b24, 0x15332a7f, 0xd908}},
|
|
||||||
{/*.val =*/{0x3f6142bf, 0x22361612, 0x2a707333, 0x1e8c828a, 0x29061593, 0xd85f201, 0x27773592, 0xa99953f, 0x6c84}},
|
|
||||||
{/*.val =*/{0x1fb09f77, 0x311b0b07, 0x15383999, 0x2f464145, 0x34830ac9, 0x6c2f900, 0x33bb9ac9, 0x54cca9f, 0xb642}},
|
|
||||||
{/*.val =*/{0x2fd84dd3, 0x388d8581, 0x2a9c1ccc, 0x37a320a2, 0x1a418564, 0x23617c80, 0x39ddcd64, 0x2a6654f, 0xdb21}},
|
|
||||||
{/*.val =*/{0x37ec2501, 0x1c46c2be, 0x154e0e66, 0x1bd19051, 0xd20c2b2, 0x11b0be40, 0x3ceee6b2, 0x215332a7, 0xed90}},
|
|
||||||
{/*.val =*/{0x1bf61098, 0xe23615d, 0x2aa70733, 0xde8c828, 0x6906159, 0x8d85f20, 0x3e777359, 0x10a99953, 0xf6c8}},
|
|
||||||
{/*.val =*/{0x2dfb084c, 0x2711b0ae, 0x15538399, 0x26f46414, 0x34830ac, 0x246c2f90, 0x3f3bb9ac, 0x854cca9, 0x7b64}},
|
|
||||||
{/*.val =*/{0x16fd8426, 0x3388d857, 0xaa9c1cc, 0x137a320a, 0x1a41856, 0x123617c8, 0x3f9ddcd6, 0x42a6654, 0x3db2}},
|
|
||||||
{/*.val =*/{0x2b7ec213, 0x19c46c2b, 0x554e0e6, 0x9bd1905, 0xd20c2b, 0x91b0be4, 0x1fceee6b, 0x215332a, 0x1ed9}},
|
|
||||||
{/*.val =*/{0x35bf5f21, 0xce23613, 0x22aa7073, 0x24de8c82, 0x690615, 0x248d85f2, 0xfe77735, 0x210a9995, 0x8f6c}},
|
|
||||||
{/*.val =*/{0x3adfada8, 0x26711b07, 0x11553839, 0x326f4641, 0x34830a, 0x3246c2f9, 0x27f3bb9a, 0x10854cca, 0xc7b6}},
|
|
||||||
{/*.val =*/{0x3d6fd6d4, 0x33388d83, 0x28aa9c1c, 0x1937a320, 0x201a4185, 0x1923617c, 0x13f9ddcd, 0x842a665, 0x63db}},
|
|
||||||
{/*.val =*/{0x3eb7eb6a, 0x199c46c1, 0x14554e0e, 0x2c9bd190, 0x100d20c2, 0x2c91b0be, 0x29fceee6, 0x24215332, 0x31ed}},
|
|
||||||
{/*.val =*/{0x3f5bf5b5, 0xcce2360, 0xa2aa707, 0x164de8c8, 0x8069061, 0x1648d85f, 0x14fe7773, 0x3210a999, 0x18f6}},
|
|
||||||
{/*.val =*/{0x1fadf8f2, 0x266711ae, 0x5155383, 0x2b26f464, 0x24034830, 0x2b246c2f, 0x2a7f3bb9, 0x190854cc, 0x8c7b}},
|
|
||||||
{/*.val =*/{0xfd6fc79, 0x333388d7, 0x28aa9c1, 0x15937a32, 0x3201a418, 0x35923617, 0x153f9ddc, 0x2c842a66, 0x463d}},
|
|
||||||
{/*.val =*/{0x27eb7c54, 0x3999c469, 0x14554e0, 0xac9bd19, 0x3900d20c, 0x1ac91b0b, 0xa9fceee, 0x36421533, 0xa31e}},
|
|
||||||
{/*.val =*/{0x33f5be2a, 0x1ccce234, 0x20a2aa70, 0x564de8c, 0x3c806906, 0xd648d85, 0x254fe777, 0x1b210a99, 0x518f}},
|
|
||||||
{/*.val =*/{0x19fadf15, 0xe66711a, 0x10515538, 0x2b26f46, 0x3e403483, 0x26b246c2, 0x32a7f3bb, 0x2d90854c, 0x28c7}},
|
|
||||||
{/*.val =*/{0xcfd6da2, 0x733388b, 0x828aa9c, 0x215937a3, 0x1f201a41, 0x33592361, 0x1953f9dd, 0x36c842a6, 0x9463}},
|
|
||||||
{/*.val =*/{0x267eb6d1, 0x3999c45, 0x2414554e, 0x30ac9bd1, 0x2f900d20, 0x39ac91b0, 0xca9fcee, 0x3b642153, 0x4a31}},
|
|
||||||
{/*.val =*/{0x333f5980, 0x1ccce20, 0x320a2aa7, 0x18564de8, 0x17c80690, 0x1cd648d8, 0x2654fe77, 0x3db210a9, 0xa518}},
|
|
||||||
{/*.val =*/{0x199facc0, 0x20e66710, 0x19051553, 0xc2b26f4, 0xbe40348, 0x2e6b246c, 0x332a7f3b, 0x1ed90854, 0x528c}},
|
|
||||||
{/*.val =*/{0xccfd660, 0x30733388, 0xc828aa9, 0x615937a, 0x5f201a4, 0x37359236, 0x19953f9d, 0xf6c842a, 0x2946}},
|
|
||||||
{/*.val =*/{0x667eb30, 0x383999c4, 0x6414554, 0x30ac9bd, 0x2f900d2, 0x3b9ac91b, 0xcca9fce, 0x7b64215, 0x14a3}},
|
|
||||||
{/*.val =*/{0x333f598, 0x1c1ccce2, 0x2320a2aa, 0x18564de, 0x217c8069, 0x1dcd648d, 0x26654fe7, 0x23db210a, 0xa51}},
|
|
||||||
{/*.val =*/{0x199facc, 0xe0e6671, 0x11905155, 0x20c2b26f, 0x30be4034, 0x2ee6b246, 0x1332a7f3, 0x31ed9085, 0x528}},
|
|
||||||
{/*.val =*/{0x20ccfd66, 0x27073338, 0x28c828aa, 0x10615937, 0x185f201a, 0x37735923, 0x299953f9, 0x18f6c842, 0x294}},
|
|
||||||
{/*.val =*/{0x10667eb3, 0x1383999c, 0x34641455, 0x830ac9b, 0x2c2f900d, 0x3bb9ac91, 0x14cca9fc, 0xc7b6421, 0x14a}},
|
|
||||||
{/*.val =*/{0x8333d71, 0x29c1cccc, 0x3a320a2a, 0x2418564d, 0x3617c806, 0x1ddcd648, 0x2a6654fe, 0x63db210, 0x80a5}},
|
|
||||||
{/*.val =*/{0x4199cd0, 0x14e0e664, 0x3d190515, 0x120c2b26, 0x1b0be403, 0xeee6b24, 0x15332a7f, 0x231ed908, 0xc052}},
|
|
||||||
{/*.val =*/{0x20cce68, 0x2a707332, 0x1e8c828a, 0x29061593, 0xd85f201, 0x27773592, 0xa99953f, 0x118f6c84, 0x6029}},
|
|
||||||
{/*.val =*/{0x1066734, 0x15383999, 0x2f464145, 0x34830ac9, 0x6c2f900, 0x33bb9ac9, 0x54cca9f, 0x28c7b642, 0x3014}},
|
|
||||||
{/*.val =*/{0x2083339a, 0x2a9c1ccc, 0x37a320a2, 0x1a418564, 0x23617c80, 0x39ddcd64, 0x2a6654f, 0x1463db21, 0x180a}},
|
|
||||||
{/*.val =*/{0x104199cd, 0x154e0e66, 0x1bd19051, 0xd20c2b2, 0x11b0be40, 0x3ceee6b2, 0x215332a7, 0xa31ed90, 0xc05}},
|
|
||||||
{/*.val =*/{0x820cafe, 0x2aa70731, 0xde8c828, 0x6906159, 0x8d85f20, 0x3e777359, 0x10a99953, 0x2518f6c8, 0x8602}},
|
|
||||||
{/*.val =*/{0x2410657f, 0x15538398, 0x26f46414, 0x34830ac, 0x246c2f90, 0x3f3bb9ac, 0x854cca9, 0x128c7b64, 0x4301}},
|
|
||||||
{/*.val =*/{0x120830d7, 0xaa9c1ca, 0x137a320a, 0x1a41856, 0x123617c8, 0x3f9ddcd6, 0x42a6654, 0x29463db2, 0xa180}},
|
|
||||||
{/*.val =*/{0x9041683, 0x554e0e3, 0x9bd1905, 0xd20c2b, 0x91b0be4, 0x1fceee6b, 0x215332a, 0x14a31ed9, 0xd0c0}},
|
|
||||||
{/*.val =*/{0x24820959, 0x22aa706f, 0x24de8c82, 0x690615, 0x248d85f2, 0xfe77735, 0x210a9995, 0xa518f6c, 0xe860}},
|
|
||||||
{/*.val =*/{0x324102c4, 0x11553835, 0x326f4641, 0x34830a, 0x3246c2f9, 0x27f3bb9a, 0x10854cca, 0x528c7b6, 0xf430}},
|
|
||||||
{/*.val =*/{0x39208162, 0x28aa9c1a, 0x1937a320, 0x201a4185, 0x1923617c, 0x13f9ddcd, 0x842a665, 0x29463db, 0x7a18}},
|
|
||||||
{/*.val =*/{0x1c9040b1, 0x14554e0d, 0x2c9bd190, 0x100d20c2, 0x2c91b0be, 0x29fceee6, 0x24215332, 0x14a31ed, 0x3d0c}},
|
|
||||||
{/*.val =*/{0x2e481e70, 0xa2aa704, 0x164de8c8, 0x8069061, 0x1648d85f, 0x14fe7773, 0x3210a999, 0xa518f6, 0x9e86}},
|
|
||||||
{/*.val =*/{0x17240f38, 0x5155382, 0x2b26f464, 0x24034830, 0x2b246c2f, 0x2a7f3bb9, 0x190854cc, 0x528c7b, 0x4f43}},
|
|
||||||
{/*.val =*/{0xb92079c, 0x28aa9c1, 0x15937a32, 0x3201a418, 0x35923617, 0x153f9ddc, 0x2c842a66, 0x2029463d, 0x27a1}},
|
|
||||||
{/*.val =*/{0x25c903ce, 0x14554e0, 0xac9bd19, 0x3900d20c, 0x1ac91b0b, 0xa9fceee, 0x36421533, 0x3014a31e, 0x13d0}},
|
|
||||||
{/*.val =*/{0x12e481e7, 0x20a2aa70, 0x564de8c, 0x3c806906, 0xd648d85, 0x254fe777, 0x1b210a99, 0x180a518f, 0x9e8}},
|
|
||||||
{/*.val =*/{0x9723f0b, 0x10515536, 0x2b26f46, 0x3e403483, 0x26b246c2, 0x32a7f3bb, 0x2d90854c, 0xc0528c7, 0x84f4}},
|
|
||||||
{/*.val =*/{0x4b91d9d, 0x828aa99, 0x215937a3, 0x1f201a41, 0x33592361, 0x1953f9dd, 0x36c842a6, 0x6029463, 0xc27a}},
|
|
||||||
{/*.val =*/{0x225c8ce6, 0x2414554a, 0x30ac9bd1, 0x2f900d20, 0x39ac91b0, 0xca9fcee, 0x3b642153, 0x3014a31, 0xe13d}},
|
|
||||||
{/*.val =*/{0x112e4673, 0x320a2aa5, 0x18564de8, 0x17c80690, 0x1cd648d8, 0x2654fe77, 0x3db210a9, 0x2180a518, 0x709e}},
|
|
||||||
{/*.val =*/{0x28972151, 0x19051550, 0xc2b26f4, 0xbe40348, 0x2e6b246c, 0x332a7f3b, 0x1ed90854, 0x10c0528c, 0xb84f}},
|
|
||||||
{/*.val =*/{0x144b8ec0, 0xc828aa6, 0x615937a, 0x5f201a4, 0x37359236, 0x19953f9d, 0xf6c842a, 0x28602946, 0xdc27}},
|
|
||||||
{/*.val =*/{0xa25c760, 0x6414553, 0x30ac9bd, 0x2f900d2, 0x3b9ac91b, 0xcca9fce, 0x7b64215, 0x343014a3, 0x6e13}},
|
|
||||||
{/*.val =*/{0x2512e3b0, 0x2320a2a9, 0x18564de, 0x217c8069, 0x1dcd648d, 0x26654fe7, 0x23db210a, 0x3a180a51, 0x3709}},
|
|
||||||
{/*.val =*/{0x328971d8, 0x11905154, 0x20c2b26f, 0x30be4034, 0x2ee6b246, 0x1332a7f3, 0x31ed9085, 0x3d0c0528, 0x1b84}},
|
|
||||||
{/*.val =*/{0x1944b8ec, 0x28c828aa, 0x10615937, 0x185f201a, 0x37735923, 0x299953f9, 0x18f6c842, 0x1e860294, 0xdc2}},
|
|
||||||
{/*.val =*/{0xca25c76, 0x34641455, 0x830ac9b, 0x2c2f900d, 0x3bb9ac91, 0x14cca9fc, 0xc7b6421, 0xf43014a, 0x6e1}},
|
|
||||||
{/*.val =*/{0x26512e3b, 0x3a320a2a, 0x2418564d, 0x3617c806, 0x1ddcd648, 0x2a6654fe, 0x63db210, 0x27a180a5, 0x370}},
|
|
||||||
{/*.val =*/{0x13289535, 0x3d190513, 0x120c2b26, 0x1b0be403, 0xeee6b24, 0x15332a7f, 0x231ed908, 0x13d0c052, 0x81b8}},
|
|
||||||
{/*.val =*/{0x299448b2, 0x1e8c8287, 0x29061593, 0xd85f201, 0x27773592, 0xa99953f, 0x118f6c84, 0x9e86029, 0xc0dc}},
|
|
||||||
{/*.val =*/{0x34ca2459, 0x2f464143, 0x34830ac9, 0x6c2f900, 0x33bb9ac9, 0x54cca9f, 0x28c7b642, 0x4f43014, 0x606e}},
|
|
||||||
{/*.val =*/{0x3a651044, 0x37a3209f, 0x1a418564, 0x23617c80, 0x39ddcd64, 0x2a6654f, 0x1463db21, 0x27a180a, 0xb037}},
|
|
||||||
{/*.val =*/{0x3d328822, 0x1bd1904f, 0xd20c2b2, 0x11b0be40, 0x3ceee6b2, 0x215332a7, 0xa31ed90, 0x213d0c05, 0x581b}},
|
|
||||||
{/*.val =*/{0x3e994411, 0xde8c827, 0x6906159, 0x8d85f20, 0x3e777359, 0x10a99953, 0x2518f6c8, 0x309e8602, 0x2c0d}},
|
|
||||||
{/*.val =*/{0x3f4ca020, 0x26f46411, 0x34830ac, 0x246c2f90, 0x3f3bb9ac, 0x854cca9, 0x128c7b64, 0x384f4301, 0x9606}},
|
|
||||||
{/*.val =*/{0x3fa65010, 0x137a3208, 0x1a41856, 0x123617c8, 0x3f9ddcd6, 0x42a6654, 0x29463db2, 0x1c27a180, 0x4b03}},
|
|
||||||
{/*.val =*/{0x1fd32808, 0x9bd1904, 0xd20c2b, 0x91b0be4, 0x1fceee6b, 0x215332a, 0x14a31ed9, 0x2e13d0c0, 0x2581}},
|
|
||||||
{/*.val =*/{0xfe99404, 0x24de8c82, 0x690615, 0x248d85f2, 0xfe77735, 0x210a9995, 0xa518f6c, 0x3709e860, 0x12c0}},
|
|
||||||
{/*.val =*/{0x7f4ca02, 0x326f4641, 0x34830a, 0x3246c2f9, 0x27f3bb9a, 0x10854cca, 0x528c7b6, 0x1b84f430, 0x960}},
|
|
||||||
{/*.val =*/{0x23fa6501, 0x1937a320, 0x201a4185, 0x1923617c, 0x13f9ddcd, 0x842a665, 0x29463db, 0xdc27a18, 0x4b0}},
|
|
||||||
{/*.val =*/{0x11fd3098, 0x2c9bd18e, 0x100d20c2, 0x2c91b0be, 0x29fceee6, 0x24215332, 0x14a31ed, 0x6e13d0c, 0x8258}},
|
|
||||||
{/*.val =*/{0x8fe984c, 0x164de8c7, 0x8069061, 0x1648d85f, 0x14fe7773, 0x3210a999, 0xa518f6, 0x3709e86, 0x412c}},
|
|
||||||
{/*.val =*/{0x247f4c26, 0x2b26f463, 0x24034830, 0x2b246c2f, 0x2a7f3bb9, 0x190854cc, 0x528c7b, 0x1b84f43, 0x2096}},
|
|
||||||
{/*.val =*/{0x323fa613, 0x15937a31, 0x3201a418, 0x35923617, 0x153f9ddc, 0x2c842a66, 0x2029463d, 0xdc27a1, 0x104b}},
|
|
||||||
{/*.val =*/{0x391fd121, 0xac9bd16, 0x3900d20c, 0x1ac91b0b, 0xa9fceee, 0x36421533, 0x3014a31e, 0x206e13d0, 0x8825}},
|
|
||||||
{/*.val =*/{0x1c8fe6a8, 0x564de89, 0x3c806906, 0xd648d85, 0x254fe777, 0x1b210a99, 0x180a518f, 0x303709e8, 0xc412}},
|
|
||||||
{/*.val =*/{0x2e47f354, 0x2b26f44, 0x3e403483, 0x26b246c2, 0x32a7f3bb, 0x2d90854c, 0xc0528c7, 0x181b84f4, 0x6209}},
|
|
||||||
{/*.val =*/{0x1723f9aa, 0x215937a2, 0x1f201a41, 0x33592361, 0x1953f9dd, 0x36c842a6, 0x6029463, 0x2c0dc27a, 0x3104}},
|
|
||||||
{/*.val =*/{0xb91fcd5, 0x30ac9bd1, 0x2f900d20, 0x39ac91b0, 0xca9fcee, 0x3b642153, 0x3014a31, 0x1606e13d, 0x1882}},
|
|
||||||
{/*.val =*/{0x25c8fc82, 0x18564de6, 0x17c80690, 0x1cd648d8, 0x2654fe77, 0x3db210a9, 0x2180a518, 0xb03709e, 0x8c41}},
|
|
||||||
{/*.val =*/{0x12e47e41, 0xc2b26f3, 0xbe40348, 0x2e6b246c, 0x332a7f3b, 0x1ed90854, 0x10c0528c, 0x2581b84f, 0x4620}},
|
|
||||||
{/*.val =*/{0x29723d38, 0x6159377, 0x5f201a4, 0x37359236, 0x19953f9d, 0xf6c842a, 0x28602946, 0x12c0dc27, 0xa310}},
|
|
||||||
{/*.val =*/{0x34b91e9c, 0x30ac9bb, 0x2f900d2, 0x3b9ac91b, 0xcca9fce, 0x7b64215, 0x343014a3, 0x9606e13, 0x5188}},
|
|
||||||
{/*.val =*/{0x3a5c8f4e, 0x18564dd, 0x217c8069, 0x1dcd648d, 0x26654fe7, 0x23db210a, 0x3a180a51, 0x4b03709, 0x28c4}},
|
|
||||||
{/*.val =*/{0x3d2e47a7, 0x20c2b26e, 0x30be4034, 0x2ee6b246, 0x1332a7f3, 0x31ed9085, 0x3d0c0528, 0x2581b84, 0x1462}},
|
|
||||||
{/*.val =*/{0x1e9721eb, 0x10615935, 0x185f201a, 0x37735923, 0x299953f9, 0x18f6c842, 0x1e860294, 0x12c0dc2, 0x8a31}},
|
|
||||||
{/*.val =*/{0x2f4b8f0d, 0x830ac98, 0x2c2f900d, 0x3bb9ac91, 0x14cca9fc, 0xc7b6421, 0xf43014a, 0x209606e1, 0xc518}},
|
|
||||||
{/*.val =*/{0x17a5c59e, 0x2418564a, 0x3617c806, 0x1ddcd648, 0x2a6654fe, 0x63db210, 0x27a180a5, 0x104b0370, 0xe28c}},
|
|
||||||
{/*.val =*/{0xbd2e2cf, 0x120c2b25, 0x1b0be403, 0xeee6b24, 0x15332a7f, 0x231ed908, 0x13d0c052, 0x82581b8, 0x7146}},
|
|
||||||
{/*.val =*/{0x25e96f7f, 0x29061590, 0xd85f201, 0x27773592, 0xa99953f, 0x118f6c84, 0x9e86029, 0x412c0dc, 0xb8a3}},
|
|
||||||
{/*.val =*/{0x12f4b5d7, 0x34830ac6, 0x6c2f900, 0x33bb9ac9, 0x54cca9f, 0x28c7b642, 0x4f43014, 0x2209606e, 0xdc51}},
|
|
||||||
{/*.val =*/{0x97a5903, 0x1a418561, 0x23617c80, 0x39ddcd64, 0x2a6654f, 0x1463db21, 0x27a180a, 0x3104b037, 0xee28}},
|
|
||||||
{/*.val =*/{0x24bd2a99, 0xd20c2ae, 0x11b0be40, 0x3ceee6b2, 0x215332a7, 0xa31ed90, 0x213d0c05, 0x1882581b, 0xf714}},
|
|
||||||
{/*.val =*/{0x125e9364, 0x6906155, 0x8d85f20, 0x3e777359, 0x10a99953, 0x2518f6c8, 0x309e8602, 0xc412c0d, 0xfb8a}},
|
|
||||||
{/*.val =*/{0x292f49b2, 0x34830aa, 0x246c2f90, 0x3f3bb9ac, 0x854cca9, 0x128c7b64, 0x384f4301, 0x6209606, 0x7dc5}},
|
|
||||||
{/*.val =*/{0x1497a4d9, 0x1a41855, 0x123617c8, 0x3f9ddcd6, 0x42a6654, 0x29463db2, 0x1c27a180, 0x23104b03, 0x3ee2}},
|
|
||||||
{/*.val =*/{0x2a4bd084, 0xd20c28, 0x91b0be4, 0x1fceee6b, 0x215332a, 0x14a31ed9, 0x2e13d0c0, 0x11882581, 0x9f71}},
|
|
||||||
{/*.val =*/{0x1525e842, 0x690614, 0x248d85f2, 0xfe77735, 0x210a9995, 0xa518f6c, 0x3709e860, 0x28c412c0, 0x4fb8}},
|
|
||||||
{/*.val =*/{0xa92f421, 0x34830a, 0x3246c2f9, 0x27f3bb9a, 0x10854cca, 0x528c7b6, 0x1b84f430, 0x14620960, 0x27dc}},
|
|
||||||
{/*.val =*/{0x5497828, 0x201a4183, 0x1923617c, 0x13f9ddcd, 0x842a665, 0x29463db, 0xdc27a18, 0xa3104b0, 0x93ee}},
|
|
||||||
{/*.val =*/{0x22a4bc14, 0x100d20c1, 0x2c91b0be, 0x29fceee6, 0x24215332, 0x14a31ed, 0x6e13d0c, 0x5188258, 0x49f7}},
|
|
||||||
{/*.val =*/{0x31525e0a, 0x8069060, 0x1648d85f, 0x14fe7773, 0x3210a999, 0xa518f6, 0x3709e86, 0x228c412c, 0x24fb}},
|
|
||||||
{/*.val =*/{0x18a92f05, 0x24034830, 0x2b246c2f, 0x2a7f3bb9, 0x190854cc, 0x528c7b, 0x1b84f43, 0x31462096, 0x127d}},
|
|
||||||
{/*.val =*/{0xc54959a, 0x3201a416, 0x35923617, 0x153f9ddc, 0x2c842a66, 0x2029463d, 0xdc27a1, 0x38a3104b, 0x893e}},
|
|
||||||
{/*.val =*/{0x62a4acd, 0x3900d20b, 0x1ac91b0b, 0xa9fceee, 0x36421533, 0x3014a31e, 0x206e13d0, 0x1c518825, 0x449f}},
|
|
||||||
{/*.val =*/{0x2315237e, 0x3c806903, 0xd648d85, 0x254fe777, 0x1b210a99, 0x180a518f, 0x303709e8, 0x2e28c412, 0xa24f}},
|
|
||||||
{/*.val =*/{0x318a91bf, 0x3e403481, 0x26b246c2, 0x32a7f3bb, 0x2d90854c, 0xc0528c7, 0x181b84f4, 0x37146209, 0x5127}},
|
|
||||||
{/*.val =*/{0x38c546f7, 0x1f201a3e, 0x33592361, 0x1953f9dd, 0x36c842a6, 0x6029463, 0x2c0dc27a, 0x3b8a3104, 0xa893}},
|
|
||||||
{/*.val =*/{0x1c62a193, 0x2f900d1d, 0x39ac91b0, 0xca9fcee, 0x3b642153, 0x3014a31, 0x1606e13d, 0x3dc51882, 0xd449}},
|
|
||||||
{/*.val =*/{0x2e314ee1, 0x17c8068c, 0x1cd648d8, 0x2654fe77, 0x3db210a9, 0x2180a518, 0xb03709e, 0x3ee28c41, 0xea24}},
|
|
||||||
{/*.val =*/{0x1718a588, 0xbe40344, 0x2e6b246c, 0x332a7f3b, 0x1ed90854, 0x10c0528c, 0x2581b84f, 0x1f714620, 0xf512}},
|
|
||||||
{/*.val =*/{0xb8c52c4, 0x5f201a2, 0x37359236, 0x19953f9d, 0xf6c842a, 0x28602946, 0x12c0dc27, 0xfb8a310, 0x7a89}},
|
|
||||||
{/*.val =*/{0x5c62962, 0x2f900d1, 0x3b9ac91b, 0xcca9fce, 0x7b64215, 0x343014a3, 0x9606e13, 0x27dc5188, 0x3d44}},
|
|
||||||
{/*.val =*/{0x22e314b1, 0x217c8068, 0x1dcd648d, 0x26654fe7, 0x23db210a, 0x3a180a51, 0x4b03709, 0x13ee28c4, 0x1ea2}},
|
|
||||||
{/*.val =*/{0x11718870, 0x30be4032, 0x2ee6b246, 0x1332a7f3, 0x31ed9085, 0x3d0c0528, 0x2581b84, 0x9f71462, 0x8f51}},
|
|
||||||
{/*.val =*/{0x8b8c438, 0x185f2019, 0x37735923, 0x299953f9, 0x18f6c842, 0x1e860294, 0x12c0dc2, 0x24fb8a31, 0x47a8}},
|
|
||||||
{/*.val =*/{0x245c621c, 0x2c2f900c, 0x3bb9ac91, 0x14cca9fc, 0xc7b6421, 0xf43014a, 0x209606e1, 0x127dc518, 0x23d4}},
|
|
||||||
{/*.val =*/{0x122e310e, 0x3617c806, 0x1ddcd648, 0x2a6654fe, 0x63db210, 0x27a180a5, 0x104b0370, 0x93ee28c, 0x11ea}},
|
|
||||||
{/*.val =*/{0x9171887, 0x1b0be403, 0xeee6b24, 0x15332a7f, 0x231ed908, 0x13d0c052, 0x82581b8, 0x49f7146, 0x8f5}},
|
|
||||||
{/*.val =*/{0x248b8a5b, 0xd85f1ff, 0x27773592, 0xa99953f, 0x118f6c84, 0x9e86029, 0x412c0dc, 0x224fb8a3, 0x847a}},
|
|
||||||
{/*.val =*/{0x3245c345, 0x6c2f8fd, 0x33bb9ac9, 0x54cca9f, 0x28c7b642, 0x4f43014, 0x2209606e, 0x1127dc51, 0xc23d}},
|
|
||||||
{/*.val =*/{0x3922dfba, 0x23617c7c, 0x39ddcd64, 0x2a6654f, 0x1463db21, 0x27a180a, 0x3104b037, 0x2893ee28, 0xe11e}},
|
|
||||||
{/*.val =*/{0x1c916fdd, 0x11b0be3e, 0x3ceee6b2, 0x215332a7, 0xa31ed90, 0x213d0c05, 0x1882581b, 0x1449f714, 0x708f}},
|
|
||||||
{/*.val =*/{0xe48b606, 0x8d85f1d, 0x3e777359, 0x10a99953, 0x2518f6c8, 0x309e8602, 0xc412c0d, 0x2a24fb8a, 0xb847}},
|
|
||||||
{/*.val =*/{0x27245b03, 0x246c2f8e, 0x3f3bb9ac, 0x854cca9, 0x128c7b64, 0x384f4301, 0x6209606, 0x35127dc5, 0x5c23}},
|
|
||||||
{/*.val =*/{0x13922b99, 0x123617c5, 0x3f9ddcd6, 0x42a6654, 0x29463db2, 0x1c27a180, 0x23104b03, 0x3a893ee2, 0xae11}},
|
|
||||||
{/*.val =*/{0x29c913e4, 0x91b0be0, 0x1fceee6b, 0x215332a, 0x14a31ed9, 0x2e13d0c0, 0x11882581, 0x3d449f71, 0xd708}},
|
|
||||||
{/*.val =*/{0x14e489f2, 0x248d85f0, 0xfe77735, 0x210a9995, 0xa518f6c, 0x3709e860, 0x28c412c0, 0x1ea24fb8, 0x6b84}},
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if USE_PRECOMPUTED_CP
|
#if USE_PRECOMPUTED_CP
|
||||||
const curve_point secp256k1_cp[256] = {
|
const curve_point secp256k1_cp[256] = {
|
||||||
{/*.x =*/{/*.val =*/{0x16f81798, 0x27ca056c, 0x1ce28d95, 0x26ff36cb, 0x70b0702, 0x18a573a, 0xbbac55a, 0x199fbe77, 0x79be}},
|
{/*.x =*/{/*.val =*/{0x16f81798, 0x27ca056c, 0x1ce28d95, 0x26ff36cb, 0x70b0702, 0x18a573a, 0xbbac55a, 0x199fbe77, 0x79be}},
|
||||||
|
@ -48,10 +48,6 @@ extern const bignum256 order256k1_half;
|
|||||||
// 3/2 in G_p
|
// 3/2 in G_p
|
||||||
extern const bignum256 three_over_two256k1;
|
extern const bignum256 three_over_two256k1;
|
||||||
|
|
||||||
#if USE_PRECOMPUTED_IV
|
|
||||||
extern const bignum256 secp256k1_iv[256];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if USE_PRECOMPUTED_CP
|
#if USE_PRECOMPUTED_CP
|
||||||
extern const curve_point secp256k1_cp[256];
|
extern const curve_point secp256k1_cp[256];
|
||||||
extern const curve_point secp256k1_cp2[255];
|
extern const curve_point secp256k1_cp2[255];
|
||||||
|
Loading…
Reference in New Issue
Block a user