@amritk/nish-x86_64-linux 0.17.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/INSTALL.md +43 -25
- package/bin/nish +0 -0
- package/package.json +2 -2
- package/runtime/nish.d.ts +55 -5
- package/runtime/nish.h +231 -20
- package/runtime/nish.mjs +16 -0
- package/runtime/runtime-aes.c +490 -0
- package/runtime/runtime-cross.c +366 -0
- package/runtime/runtime-host.c +7 -6
- package/runtime/runtime-net.c +93 -34
- package/runtime/runtime-os.c +213 -15
- package/runtime/runtime-parallel.c +590 -107
- package/runtime/runtime-simd.c +203 -0
- package/runtime/runtime-wasm.c +16 -3
- package/runtime/runtime.c +89 -23
- package/runtime/shim.mjs +71 -1
- package/scripts/build.sh +225 -20
- package/std/README.md +86 -55
- package/std/bytes.ts +163 -0
- package/std/crypto/LICENSE-libsecp256k1 +19 -0
- package/std/crypto/aes.ts +238 -76
- package/std/crypto/chacha20poly1305.ts +43 -9
- package/std/crypto/ed25519.ts +840 -0
- package/std/crypto/hkdf.ts +304 -12
- package/std/crypto/hmac.ts +245 -53
- package/std/crypto/p256.ts +1376 -42
- package/std/crypto/x25519.ts +55 -37
- package/std/crypto/x509-random.ts +71 -0
- package/std/crypto/x509.ts +9 -9
- package/std/json-tokenizer.ts +1296 -0
- package/std/json-typed.ts +1014 -0
- package/std/json-value.ts +1163 -0
- package/std/json.ts +1412 -70
- package/std/net/buffer-pool.ts +151 -0
- package/std/net/hpack.ts +416 -112
- package/std/net/http-fields.ts +93 -0
- package/std/net/http1-server.ts +417 -55
- package/std/net/http1.ts +31 -6
- package/std/net/http2-tls.ts +112 -24
- package/std/net/http2.ts +333 -75
- package/std/net/http3-server.ts +231 -45
- package/std/net/http3.ts +187 -28
- package/std/net/prefork.ts +412 -0
- package/std/net/quic-conn-params.ts +86 -16
- package/std/net/quic-listener.ts +576 -219
- package/std/net/quic-packet.ts +443 -58
- package/std/net/quic-recovery.ts +361 -30
- package/std/net/quic-stream.ts +434 -28
- package/std/net/quic.ts +922 -206
- package/std/net/router.ts +676 -0
- package/std/net/tls/codec.ts +426 -27
- package/std/net/tls/record-server.ts +478 -132
- package/std/net/tls/record.ts +133 -42
- package/std/net/tls/schedule.ts +464 -55
- package/std/net/tls/ticket.ts +610 -0
- package/std/net/tls-tcp.ts +204 -57
- package/std/net/tls.ts +1132 -305
- package/std/net/url.ts +571 -0
- package/std/random.ts +94 -0
- package/std/text.ts +77 -0
- package/std/threads.ts +438 -14
package/std/crypto/p256.ts
CHANGED
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
*
|
|
21
21
|
* Ported from fiat-crypto (https://github.com/mit-plv/fiat-crypto), fiat-c/src/p256_32.c and fiat-c/src/p256_scalar_32.c. Copyright (c) 2015-2020 the fiat-crypto authors (see the AUTHORS file). Used under the MIT licence; see std/crypto/LICENSE-fiat-crypto.
|
|
22
22
|
*
|
|
23
|
+
* Ported from libsecp256k1 (https://github.com/bitcoin-core/secp256k1), src/modinv32_impl.h. Copyright (c) 2020 Peter Dettman. Used under the MIT licence; see std/crypto/LICENSE-libsecp256k1.
|
|
24
|
+
*
|
|
23
25
|
* **What is ported and what is not.** The `p256Fiat*` functions are
|
|
24
26
|
* fiat-crypto's generated, formally verified Montgomery arithmetic on eight
|
|
25
27
|
* `u32` limbs with `u64` products — `mul`, `square`, `add`, `sub`,
|
|
@@ -35,9 +37,11 @@
|
|
|
35
37
|
* changes no arithmetic; it kept the input's pointer from being spilled in a
|
|
36
38
|
* way the aarch64 disassembly check once misread (#334). The
|
|
37
39
|
* scalar functions use the field's four helpers, which fiat generates
|
|
38
|
-
* identically for both.
|
|
39
|
-
*
|
|
40
|
-
*
|
|
40
|
+
* identically for both. The nonce's inverse, `p256ScalarInverse`, is
|
|
41
|
+
* libsecp256k1's 32-bit safegcd (`modinv32`), function for function; the
|
|
42
|
+
* section that holds it says what changes. Everything else in this file — the
|
|
43
|
+
* curve, the encodings, the other inversions and ECDSA — is written for this
|
|
44
|
+
* module from the documents it names.
|
|
41
45
|
*
|
|
42
46
|
* **The curve** is `y^2 = x^3 - 3x + b` over GF(p), p = 2^256 - 2^224 + 2^192
|
|
43
47
|
* + 2^96 - 1, with the base point G and its order n from SEC 2 §2.4.2 (FIPS
|
|
@@ -49,31 +53,51 @@
|
|
|
49
53
|
* of field operations, so there is no case to branch on.
|
|
50
54
|
*
|
|
51
55
|
* **Constant time where a secret is involved.** A private key and a nonce are
|
|
52
|
-
* only ever multiplied by `
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
56
|
+
* only ever multiplied by G, and that by `p256BaseMult`, a comb over a
|
|
57
|
+
* precomputed table: 4 teeth 64 bits apart, 16 sub-tables of the 15 non-zero
|
|
58
|
+
* sums of a tooth's multiples of G, one per 4-bit offset, as affine points in
|
|
59
|
+
* the Montgomery domain (`p256BaseTable`, 15 KiB, written by
|
|
60
|
+
* `scripts/gen-p256-table.mjs`). Four rows of 16 mixed additions with a
|
|
61
|
+
* doubling between rows replace the 256 doublings and 64 additions of a
|
|
62
|
+
* window, whatever the scalar. Each addition reads all fifteen entries of its
|
|
63
|
+
* sub-table and keeps one with fiat's conditional move, steered by `ctEq` on
|
|
64
|
+
* the digit; a zero digit keeps none, and the sum is then discarded by the
|
|
65
|
+
* same conditional move rather than skipped, so neither a branch nor an
|
|
66
|
+
* address depends on the scalar. `p256ScalarMult`, a fixed 4-bit window over
|
|
67
|
+
* sixteen multiples of a point, is what verification multiplies G and the
|
|
68
|
+
* received key by, and the reference the comb is held to bit for bit
|
|
69
|
+
* (`tests/link/crypto_p256_agree`). The signer inverts the nonce by
|
|
70
|
+
* Bernstein and Yang's safegcd, `p256ScalarInverse`: twenty batches of thirty
|
|
71
|
+
* divsteps, each a fixed run of masks and adds, whatever the scalar, so its
|
|
72
|
+
* loops count constants and no branch or address follows the nonce; Fermat's
|
|
73
|
+
* `p256ScalarInvert` is the reference it is held to bit for bit
|
|
74
|
+
* (`tests/link/crypto_p256_inverse`) and what verification still uses. The
|
|
75
|
+
* other inversions raise to the public exponents p - 2 and n - 2, so their
|
|
76
|
+
* branches follow a constant. The
|
|
77
|
+
* branches that remain are on public facts: a length, a limb or bit position,
|
|
78
|
+
* whether a received key or signature is in range, and — once in about 2^32
|
|
79
|
+
* signatures — RFC 6979's retry when a candidate nonce is not below n.
|
|
62
80
|
*
|
|
63
81
|
* **What is verified by disassembly and what is discipline.**
|
|
64
82
|
* `tests/cases/ct_asm_p256` holds copies of fiat's field multiply, square, add
|
|
65
83
|
* and subtract, its scalar multiply and its conditional move, the table read
|
|
66
|
-
* by a secret digit, the complete doubling and addition,
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
84
|
+
* by a secret digit, the complete doubling and addition, one window step of
|
|
85
|
+
* `p256ScalarMult`, the comb's digit, entry read, mixed addition,
|
|
86
|
+
* conditional keep and one whole comb step, and safegcd's thirty divsteps and
|
|
87
|
+
* its two matrix updates, to the check of
|
|
88
|
+
* `tests/ct-asm.js`, which refuses any branch, call it cannot follow or
|
|
89
|
+
* secret-indexed access in them on x86-64 and aarch64, following each call
|
|
90
|
+
* into the field functions. The copies of the point functions take coordinate
|
|
91
|
+
* arrays rather than points, the table reads' loops are written out there and
|
|
92
|
+
* their offsets computed with wrapping arithmetic, as that fixture's header
|
|
93
|
+
* says; its `main` runs RFC 6979 A.2.5 through them, by the window and by the
|
|
94
|
+
* comb, and three inverses through the safegcd copies. The 64-window and 4-row
|
|
95
|
+
* loops, the table build, the inversions (safegcd's twenty-batch loop, its
|
|
96
|
+
* conversions, normalisation and limb loops among them), the encodings and the
|
|
97
|
+
* nonce derivation are constant time by construction rather than by that
|
|
98
|
+
* proof.
|
|
75
99
|
*
|
|
76
|
-
* Verification multiplies only public values,
|
|
100
|
+
* Verification multiplies only public values, by `p256ScalarMult` alone.
|
|
77
101
|
*
|
|
78
102
|
* **The private key is a `Secret`** (`nish:secret`, docs/LANGUAGE.md
|
|
79
103
|
* "Secrets"). `p256PublicKey` and `p256Sign` read it only inside `expose` /
|
|
@@ -89,7 +113,7 @@
|
|
|
89
113
|
* (`docs/wp26-stdlib.md` §3e).
|
|
90
114
|
*/
|
|
91
115
|
import { Secret, expose, exposeWith, wipe } from "nish:secret"
|
|
92
|
-
import { Sha256, sha256 } from "nish/crypto/sha256"
|
|
116
|
+
import { SHA256_BLOCK, SHA256_SIZE, Sha256, sha256 } from "nish/crypto/sha256"
|
|
93
117
|
import { timingSafeEqual } from "nish/crypto/ct"
|
|
94
118
|
|
|
95
119
|
/** The length in bytes of a private key: one scalar, big-endian. */
|
|
@@ -3735,7 +3759,8 @@ const p256FieldInvert = (out: u32[], a: u32[]): void => {
|
|
|
3735
3759
|
/**
|
|
3736
3760
|
* `out = 1 / a` mod n, as `a^(n - 2)` with the scalar Montgomery multiply;
|
|
3737
3761
|
* the exponent is public, so the square-and-multiply branches only on a
|
|
3738
|
-
* constant.
|
|
3762
|
+
* constant. Verification inverts s with it; the signer's `p256ScalarInverse`
|
|
3763
|
+
* is held to it bit for bit (`tests/link/crypto_p256_inverse`).
|
|
3739
3764
|
*/
|
|
3740
3765
|
const p256ScalarInvert = (out: u32[], a: u32[]): void => {
|
|
3741
3766
|
const e: u32[] = p256Order()
|
|
@@ -3751,6 +3776,279 @@ const p256ScalarInvert = (out: u32[], a: u32[]): void => {
|
|
|
3751
3776
|
p256Copy(out, acc)
|
|
3752
3777
|
}
|
|
3753
3778
|
|
|
3779
|
+
// ---- The nonce's inverse by safegcd -------------------------------------------
|
|
3780
|
+
//
|
|
3781
|
+
// Bernstein and Yang's constant-time inversion ("Fast constant-time gcd
|
|
3782
|
+
// computation and modular inversion", 2019), as libsecp256k1's modinv32 writes
|
|
3783
|
+
// it for 32-bit targets (MIT, std/crypto/LICENSE-libsecp256k1): the functions
|
|
3784
|
+
// below are its secp256k1_modinv32_divsteps_30, _update_de_30, _update_fg_30,
|
|
3785
|
+
// _normalize_30 and secp256k1_modinv32, with its scalar_8x32 conversions to and
|
|
3786
|
+
// from signed-30, ported to Nish for the one modulus n. A value is nine limbs
|
|
3787
|
+
// of 30 bits each, limb 8 carrying the sign, held as the u32 bit patterns of
|
|
3788
|
+
// the C's int32_t: `u32` arithmetic wraps where the C's never overflows, so the
|
|
3789
|
+
// low bits agree, and the arithmetic shifts go through `i32` and `i64`.
|
|
3790
|
+
|
|
3791
|
+
/** The 32-bit pattern `a` read as an `int32_t`, widened to 64 bits with its sign. */
|
|
3792
|
+
const p256Wide = (a: u32): u64 => toU64(toI64(toI32(a)))
|
|
3793
|
+
|
|
3794
|
+
/** `c >> 30` on `c` read as an `int64_t`: the carry into the next limb. */
|
|
3795
|
+
const p256Carry30 = (c: u64): u64 => toU64(toI64(c) >> 30)
|
|
3796
|
+
|
|
3797
|
+
/** `a >> 30` on `a` read as an `int32_t`. */
|
|
3798
|
+
const p256Shift30 = (a: u32): u32 => toU32(toI32(a) >> 30)
|
|
3799
|
+
|
|
3800
|
+
/** All ones when `a`, read as an `int32_t`, is negative; zero otherwise. */
|
|
3801
|
+
const p256SignMask = (a: u32): u32 => toU32(toI32(a) >> 31)
|
|
3802
|
+
|
|
3803
|
+
/** n in nine signed-30 limbs, limb 0 the least significant. */
|
|
3804
|
+
const p256Order30 = (): u32[] => {
|
|
3805
|
+
const out: u32[] = new Array<u32>(9)
|
|
3806
|
+
out[0] = 0x3c632551
|
|
3807
|
+
out[1] = 0x0ee72b0b
|
|
3808
|
+
out[2] = 0x3179e84f
|
|
3809
|
+
out[3] = 0x39beab69
|
|
3810
|
+
out[4] = 0x3fffffbc
|
|
3811
|
+
out[5] = 0x3fffffff
|
|
3812
|
+
out[6] = 0x00000fff
|
|
3813
|
+
out[7] = 0x3fffc000
|
|
3814
|
+
out[8] = 0x0000ffff
|
|
3815
|
+
return out
|
|
3816
|
+
}
|
|
3817
|
+
|
|
3818
|
+
/**
|
|
3819
|
+
* R^3 mod n. A Montgomery multiply by it takes `(a R)^-1`, what safegcd
|
|
3820
|
+
* answers for an input in the Montgomery domain, to `a^-1 R`.
|
|
3821
|
+
*/
|
|
3822
|
+
const p256ScalarR3 = (): u32[] => {
|
|
3823
|
+
const out: u32[] = p256Limbs()
|
|
3824
|
+
p256SetLimbs(
|
|
3825
|
+
out,
|
|
3826
|
+
0x0b65a624,
|
|
3827
|
+
0xac8ebec9,
|
|
3828
|
+
0x0c0555c9,
|
|
3829
|
+
0x111f28ae,
|
|
3830
|
+
0x6ba5e93f,
|
|
3831
|
+
0x2543b924,
|
|
3832
|
+
0x6407be65,
|
|
3833
|
+
0x503a54e7
|
|
3834
|
+
)
|
|
3835
|
+
return out
|
|
3836
|
+
}
|
|
3837
|
+
|
|
3838
|
+
/** The eight 32-bit limbs `a`, below 2^256, as nine signed-30 limbs (`secp256k1_scalar_to_signed30`). */
|
|
3839
|
+
const p256ToSigned30 = (out: u32[], a: u32[]): void => {
|
|
3840
|
+
if (toI32(out.length) < 9 || toI32(a.length) < 8) {
|
|
3841
|
+
return
|
|
3842
|
+
}
|
|
3843
|
+
out[0] = a[0] & 0x3fffffff
|
|
3844
|
+
out[1] = ((a[0] >> 30) | (a[1] << 2)) & 0x3fffffff
|
|
3845
|
+
out[2] = ((a[1] >> 28) | (a[2] << 4)) & 0x3fffffff
|
|
3846
|
+
out[3] = ((a[2] >> 26) | (a[3] << 6)) & 0x3fffffff
|
|
3847
|
+
out[4] = ((a[3] >> 24) | (a[4] << 8)) & 0x3fffffff
|
|
3848
|
+
out[5] = ((a[4] >> 22) | (a[5] << 10)) & 0x3fffffff
|
|
3849
|
+
out[6] = ((a[5] >> 20) | (a[6] << 12)) & 0x3fffffff
|
|
3850
|
+
out[7] = ((a[6] >> 18) | (a[7] << 14)) & 0x3fffffff
|
|
3851
|
+
out[8] = a[7] >> 16
|
|
3852
|
+
}
|
|
3853
|
+
|
|
3854
|
+
/** Nine normalised signed-30 limbs, in [0, n), as eight 32-bit limbs (`secp256k1_scalar_from_signed30`). */
|
|
3855
|
+
const p256FromSigned30 = (out: u32[], a: u32[]): void => {
|
|
3856
|
+
if (toI32(out.length) < 8 || toI32(a.length) < 9) {
|
|
3857
|
+
return
|
|
3858
|
+
}
|
|
3859
|
+
out[0] = a[0] | (a[1] << 30)
|
|
3860
|
+
out[1] = (a[1] >> 2) | (a[2] << 28)
|
|
3861
|
+
out[2] = (a[2] >> 4) | (a[3] << 26)
|
|
3862
|
+
out[3] = (a[3] >> 6) | (a[4] << 24)
|
|
3863
|
+
out[4] = (a[4] >> 8) | (a[5] << 22)
|
|
3864
|
+
out[5] = (a[5] >> 10) | (a[6] << 20)
|
|
3865
|
+
out[6] = (a[6] >> 12) | (a[7] << 18)
|
|
3866
|
+
out[7] = (a[7] >> 14) | (a[8] << 16)
|
|
3867
|
+
}
|
|
3868
|
+
|
|
3869
|
+
/**
|
|
3870
|
+
* Thirty divsteps on the low limbs `f0` (odd) and `g0`, from `zeta` =
|
|
3871
|
+
* -(delta + 1/2): the steps' product as a 2x2 matrix `[u, v; q, r]` in `t`,
|
|
3872
|
+
* each entry in [-2^30, 2^30] as a 32-bit pattern, and the new zeta returned.
|
|
3873
|
+
* Every step does the same operations: whether g is odd and whether zeta is
|
|
3874
|
+
* negative become masks, never a branch (`secp256k1_modinv32_divsteps_30`).
|
|
3875
|
+
*/
|
|
3876
|
+
const p256Divsteps30 = (zeta: u32, f0: u32, g0: u32, t: u32[]): u32 => {
|
|
3877
|
+
if (toI32(t.length) < 4) {
|
|
3878
|
+
return zeta
|
|
3879
|
+
}
|
|
3880
|
+
const zero: u32 = 0
|
|
3881
|
+
let z: u32 = zeta
|
|
3882
|
+
let f: u32 = f0
|
|
3883
|
+
let g: u32 = g0
|
|
3884
|
+
let u: u32 = 1
|
|
3885
|
+
let v: u32 = 0
|
|
3886
|
+
let q: u32 = 0
|
|
3887
|
+
let r: u32 = 1
|
|
3888
|
+
for (let i: i32 = 0; i < 30; i++) {
|
|
3889
|
+
// Masks for zeta < 0 and for g odd.
|
|
3890
|
+
let mask1: u32 = p256SignMask(z)
|
|
3891
|
+
const mask2: u32 = zero - (g & 1)
|
|
3892
|
+
// f, u and v, negated when zeta < 0, added to g, q and r when g is odd.
|
|
3893
|
+
g = g + (((f ^ mask1) - mask1) & mask2)
|
|
3894
|
+
q = q + (((u ^ mask1) - mask1) & mask2)
|
|
3895
|
+
r = r + (((v ^ mask1) - mask1) & mask2)
|
|
3896
|
+
// When both hold, zeta becomes -zeta - 2 and the new g, q and r are added
|
|
3897
|
+
// to f, u and v (the swap); otherwise zeta becomes zeta - 1.
|
|
3898
|
+
mask1 = mask1 & mask2
|
|
3899
|
+
z = (z ^ mask1) - 1
|
|
3900
|
+
f = f + (g & mask1)
|
|
3901
|
+
u = u + (q & mask1)
|
|
3902
|
+
v = v + (r & mask1)
|
|
3903
|
+
g = g >> 1
|
|
3904
|
+
u = u << 1
|
|
3905
|
+
v = v << 1
|
|
3906
|
+
}
|
|
3907
|
+
t[0] = u
|
|
3908
|
+
t[1] = v
|
|
3909
|
+
t[2] = q
|
|
3910
|
+
t[3] = r
|
|
3911
|
+
return z
|
|
3912
|
+
}
|
|
3913
|
+
|
|
3914
|
+
/**
|
|
3915
|
+
* `[d, e] = (t [d, e] + n [md, me]) / 2^30`, with `md` and `me` chosen so
|
|
3916
|
+
* that the division is exact: d and e stay in (-2n, n) and keep tracking f
|
|
3917
|
+
* and g modulo n (`secp256k1_modinv32_update_de_30`). The products are 32 by
|
|
3918
|
+
* 32 bits into 64.
|
|
3919
|
+
*/
|
|
3920
|
+
const p256UpdateDe30 = (d: u32[], e: u32[], t: u32[], n: u32[]): void => {
|
|
3921
|
+
if (toI32(d.length) < 9 || toI32(e.length) < 9 || toI32(t.length) < 4 || toI32(n.length) < 9) {
|
|
3922
|
+
return
|
|
3923
|
+
}
|
|
3924
|
+
const u: u64 = p256Wide(t[0])
|
|
3925
|
+
const v: u64 = p256Wide(t[1])
|
|
3926
|
+
const q: u64 = p256Wide(t[2])
|
|
3927
|
+
const r: u64 = p256Wide(t[3])
|
|
3928
|
+
// n^-1 mod 2^30, which makes the sum's bottom 30 bits zero below.
|
|
3929
|
+
const inverse30: u32 = 0x11ff43b1
|
|
3930
|
+
// [md, me] start as [u, q] if d is negative plus [v, r] if e is.
|
|
3931
|
+
const sd: u32 = p256SignMask(d[8])
|
|
3932
|
+
const se: u32 = p256SignMask(e[8])
|
|
3933
|
+
let md: u32 = (t[0] & sd) + (t[1] & se)
|
|
3934
|
+
let me: u32 = (t[2] & sd) + (t[3] & se)
|
|
3935
|
+
const d0: u64 = p256Wide(d[0])
|
|
3936
|
+
const e0: u64 = p256Wide(e[0])
|
|
3937
|
+
let cd: u64 = u * d0 + v * e0
|
|
3938
|
+
let ce: u64 = q * d0 + r * e0
|
|
3939
|
+
// Correct md and me so that the bottom 30 bits of the sum are zero.
|
|
3940
|
+
md = md - ((inverse30 * toU32(cd) + md) & 0x3fffffff)
|
|
3941
|
+
me = me - ((inverse30 * toU32(ce) + me) & 0x3fffffff)
|
|
3942
|
+
const mdWide: u64 = p256Wide(md)
|
|
3943
|
+
const meWide: u64 = p256Wide(me)
|
|
3944
|
+
cd = p256Carry30(cd + p256Wide(n[0]) * mdWide)
|
|
3945
|
+
ce = p256Carry30(ce + p256Wide(n[0]) * meWide)
|
|
3946
|
+
for (let i: i32 = 1; i < 9; i++) {
|
|
3947
|
+
const di: u64 = p256Wide(d[i])
|
|
3948
|
+
const ei: u64 = p256Wide(e[i])
|
|
3949
|
+
const ni: u64 = p256Wide(n[i])
|
|
3950
|
+
cd = cd + u * di + v * ei + ni * mdWide
|
|
3951
|
+
ce = ce + q * di + r * ei + ni * meWide
|
|
3952
|
+
d[i - 1] = toU32(cd) & 0x3fffffff
|
|
3953
|
+
e[i - 1] = toU32(ce) & 0x3fffffff
|
|
3954
|
+
cd = p256Carry30(cd)
|
|
3955
|
+
ce = p256Carry30(ce)
|
|
3956
|
+
}
|
|
3957
|
+
d[8] = toU32(cd)
|
|
3958
|
+
e[8] = toU32(ce)
|
|
3959
|
+
}
|
|
3960
|
+
|
|
3961
|
+
/** `[f, g] = t [f, g] / 2^30`, which the divsteps made exact (`secp256k1_modinv32_update_fg_30`). */
|
|
3962
|
+
const p256UpdateFg30 = (f: u32[], g: u32[], t: u32[]): void => {
|
|
3963
|
+
if (toI32(f.length) < 9 || toI32(g.length) < 9 || toI32(t.length) < 4) {
|
|
3964
|
+
return
|
|
3965
|
+
}
|
|
3966
|
+
const u: u64 = p256Wide(t[0])
|
|
3967
|
+
const v: u64 = p256Wide(t[1])
|
|
3968
|
+
const q: u64 = p256Wide(t[2])
|
|
3969
|
+
const r: u64 = p256Wide(t[3])
|
|
3970
|
+
const f0: u64 = p256Wide(f[0])
|
|
3971
|
+
const g0: u64 = p256Wide(g[0])
|
|
3972
|
+
let cf: u64 = p256Carry30(u * f0 + v * g0)
|
|
3973
|
+
let cg: u64 = p256Carry30(q * f0 + r * g0)
|
|
3974
|
+
for (let i: i32 = 1; i < 9; i++) {
|
|
3975
|
+
const fi: u64 = p256Wide(f[i])
|
|
3976
|
+
const gi: u64 = p256Wide(g[i])
|
|
3977
|
+
cf = cf + u * fi + v * gi
|
|
3978
|
+
cg = cg + q * fi + r * gi
|
|
3979
|
+
f[i - 1] = toU32(cf) & 0x3fffffff
|
|
3980
|
+
g[i - 1] = toU32(cg) & 0x3fffffff
|
|
3981
|
+
cf = p256Carry30(cf)
|
|
3982
|
+
cg = p256Carry30(cg)
|
|
3983
|
+
}
|
|
3984
|
+
f[8] = toU32(cf)
|
|
3985
|
+
g[8] = toU32(cg)
|
|
3986
|
+
}
|
|
3987
|
+
|
|
3988
|
+
/** Add n to the signed-30 `a` when `mask` is all ones, then carry so every limb but the last is in [0, 2^30). */
|
|
3989
|
+
const p256AddOrder30 = (a: u32[], n: u32[], mask: u32, negate: u32): void => {
|
|
3990
|
+
if (toI32(a.length) < 9 || toI32(n.length) < 9) {
|
|
3991
|
+
return
|
|
3992
|
+
}
|
|
3993
|
+
for (let i: i32 = 0; i < 9; i++) {
|
|
3994
|
+
a[i] = ((a[i] + (n[i] & mask)) ^ negate) - negate
|
|
3995
|
+
}
|
|
3996
|
+
for (let i: i32 = 1; i < 9; i++) {
|
|
3997
|
+
a[i] = a[i] + p256Shift30(a[i - 1])
|
|
3998
|
+
a[i - 1] = a[i - 1] & 0x3fffffff
|
|
3999
|
+
}
|
|
4000
|
+
}
|
|
4001
|
+
|
|
4002
|
+
/**
|
|
4003
|
+
* `d` in (-2n, n) to [0, n), negated first when `sign`'s top bit is set: f
|
|
4004
|
+
* ended as -1 rather than 1 (`secp256k1_modinv32_normalize_30`).
|
|
4005
|
+
*/
|
|
4006
|
+
const p256Normalize30 = (d: u32[], sign: u32, n: u32[]): void => {
|
|
4007
|
+
if (toI32(d.length) < 9) {
|
|
4008
|
+
return
|
|
4009
|
+
}
|
|
4010
|
+
const zero: u32 = 0
|
|
4011
|
+
p256AddOrder30(d, n, p256SignMask(d[8]), p256SignMask(sign))
|
|
4012
|
+
p256AddOrder30(d, n, p256SignMask(d[8]), zero)
|
|
4013
|
+
}
|
|
4014
|
+
|
|
4015
|
+
/**
|
|
4016
|
+
* `out = 1 / a` mod n for `a` in the Montgomery domain, zero for a zero `a`:
|
|
4017
|
+
* the signing paths' inversion of the nonce. Twenty batches of thirty divsteps
|
|
4018
|
+
* each: 600, past the 590 that bound any 256-bit input, so the count never
|
|
4019
|
+
* depends on `a`, and every step and update runs the same instructions on any
|
|
4020
|
+
* value. The divsteps invert `a R` as a plain number; one Montgomery multiply
|
|
4021
|
+
* by R^3 takes `(a R)^-1` to `a^-1 R`. f, g, d, e and the matrix are wiped
|
|
4022
|
+
* before it returns (ECC-2).
|
|
4023
|
+
*/
|
|
4024
|
+
const p256ScalarInverse = (out: u32[], a: u32[]): void => {
|
|
4025
|
+
const n: u32[] = p256Order30()
|
|
4026
|
+
const d: u32[] = new Array<u32>(9)
|
|
4027
|
+
const e: u32[] = new Array<u32>(9)
|
|
4028
|
+
const f: u32[] = p256Order30()
|
|
4029
|
+
const g: u32[] = new Array<u32>(9)
|
|
4030
|
+
const t: u32[] = new Array<u32>(4)
|
|
4031
|
+
e[0] = 1
|
|
4032
|
+
p256ToSigned30(g, a)
|
|
4033
|
+
// zeta = -(delta + 1/2), delta starting at 1/2.
|
|
4034
|
+
let zeta: u32 = 0xffffffff
|
|
4035
|
+
for (let i: i32 = 0; i < 20; i++) {
|
|
4036
|
+
zeta = p256Divsteps30(zeta, f[0], g[0], t)
|
|
4037
|
+
p256UpdateDe30(d, e, t, n)
|
|
4038
|
+
p256UpdateFg30(f, g, t)
|
|
4039
|
+
}
|
|
4040
|
+
// g is now 0 and f is 1 or -1, with d the inverse up to that sign; for a
|
|
4041
|
+
// zero `a`, f is n and d stays 0.
|
|
4042
|
+
p256Normalize30(d, f[8], n)
|
|
4043
|
+
p256FromSigned30(out, d)
|
|
4044
|
+
p256FiatScalarMul(out, out, p256ScalarR3())
|
|
4045
|
+
wipe(d)
|
|
4046
|
+
wipe(e)
|
|
4047
|
+
wipe(f)
|
|
4048
|
+
wipe(g)
|
|
4049
|
+
wipe(t)
|
|
4050
|
+
}
|
|
4051
|
+
|
|
3754
4052
|
/**
|
|
3755
4053
|
* A point in projective coordinates (X : Y : Z), each coordinate a field
|
|
3756
4054
|
* element in the Montgomery domain. It stands for the affine (X/Z, Y/Z), and
|
|
@@ -3772,8 +4070,8 @@ class P256ProjectivePoint {
|
|
|
3772
4070
|
|
|
3773
4071
|
/**
|
|
3774
4072
|
* The temporaries of one addition or doubling, allocated once per scalar
|
|
3775
|
-
* multiplication rather than once per step,
|
|
3776
|
-
* formulas multiply by.
|
|
4073
|
+
* multiplication rather than once per step, the table entry a multiplication
|
|
4074
|
+
* selects into, and the curve's `b`, which the formulas multiply by.
|
|
3777
4075
|
*/
|
|
3778
4076
|
class P256PointScratch {
|
|
3779
4077
|
t0: u32[]
|
|
@@ -3782,6 +4080,7 @@ class P256PointScratch {
|
|
|
3782
4080
|
t3: u32[]
|
|
3783
4081
|
t4: u32[]
|
|
3784
4082
|
sum: P256ProjectivePoint
|
|
4083
|
+
entry: P256ProjectivePoint
|
|
3785
4084
|
b: u32[]
|
|
3786
4085
|
|
|
3787
4086
|
constructor() {
|
|
@@ -3791,6 +4090,7 @@ class P256PointScratch {
|
|
|
3791
4090
|
this.t3 = p256Limbs()
|
|
3792
4091
|
this.t4 = p256Limbs()
|
|
3793
4092
|
this.sum = new P256ProjectivePoint()
|
|
4093
|
+
this.entry = new P256ProjectivePoint()
|
|
3794
4094
|
this.b = p256CurveB()
|
|
3795
4095
|
}
|
|
3796
4096
|
}
|
|
@@ -3810,6 +4110,7 @@ const p256WipeScratch = (s: P256PointScratch): void => {
|
|
|
3810
4110
|
wipe(s.t3)
|
|
3811
4111
|
wipe(s.t4)
|
|
3812
4112
|
p256WipePoint(s.sum)
|
|
4113
|
+
p256WipePoint(s.entry)
|
|
3813
4114
|
}
|
|
3814
4115
|
|
|
3815
4116
|
/** `out = p`, coordinate by coordinate. */
|
|
@@ -3819,6 +4120,13 @@ const p256PointCopy = (out: P256ProjectivePoint, p: P256ProjectivePoint): void =
|
|
|
3819
4120
|
p256Copy(out.z, p.z)
|
|
3820
4121
|
}
|
|
3821
4122
|
|
|
4123
|
+
/** `p = (0 : 1 : 0)`, the identity, in place: what `new P256ProjectivePoint()` makes. */
|
|
4124
|
+
const p256SetIdentity = (p: P256ProjectivePoint): void => {
|
|
4125
|
+
p256SetZero(p.x)
|
|
4126
|
+
p256FiatSetOne(p.y)
|
|
4127
|
+
p256SetZero(p.z)
|
|
4128
|
+
}
|
|
4129
|
+
|
|
3822
4130
|
/**
|
|
3823
4131
|
* `out = p + q`, by Renes, Costello and Batina's Algorithm 4 (complete
|
|
3824
4132
|
* addition for a = -3), step for step in the paper's order and with its names.
|
|
@@ -3957,10 +4265,15 @@ const p256TableStorePoint = (table: u32[], i: i32, p: P256ProjectivePoint): void
|
|
|
3957
4265
|
* The window table: entry `i` is `i * p`, for `i` from 0 to 15. Built from
|
|
3958
4266
|
* `p`, which is public here (G or a received key) and a secret only in that
|
|
3959
4267
|
* it is about to be multiplied. Entry 0 is the identity and entry 1 is `p`;
|
|
3960
|
-
* each later one adds `p` to the one before.
|
|
4268
|
+
* each later one adds `p` to the one before, in `acc`, which the caller owns.
|
|
3961
4269
|
*/
|
|
3962
|
-
const p256TableBuild = (
|
|
3963
|
-
|
|
4270
|
+
const p256TableBuild = (
|
|
4271
|
+
table: u32[],
|
|
4272
|
+
p: P256ProjectivePoint,
|
|
4273
|
+
s: P256PointScratch,
|
|
4274
|
+
acc: P256ProjectivePoint
|
|
4275
|
+
): void => {
|
|
4276
|
+
p256SetIdentity(acc)
|
|
3964
4277
|
p256TableStorePoint(table, 0, acc)
|
|
3965
4278
|
p256PointCopy(acc, p)
|
|
3966
4279
|
p256TableStorePoint(table, 1, acc)
|
|
@@ -4022,14 +4335,17 @@ const p256ScalarMult = (
|
|
|
4022
4335
|
p: P256ProjectivePoint,
|
|
4023
4336
|
s: P256PointScratch
|
|
4024
4337
|
): void => {
|
|
4338
|
+
// The accumulator, the selected entry and the table follow the scalar's
|
|
4339
|
+
// digits, so all three are wiped before it returns.
|
|
4340
|
+
const table: u32[] = new Array<u32>(384)
|
|
4341
|
+
const acc = new P256ProjectivePoint()
|
|
4342
|
+
const entry: P256ProjectivePoint = s.entry
|
|
4025
4343
|
const kLength: i32 = toI32(k.length)
|
|
4026
4344
|
if (kLength < 32) {
|
|
4027
4345
|
return
|
|
4028
4346
|
}
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
const acc = new P256ProjectivePoint()
|
|
4032
|
-
const entry = new P256ProjectivePoint()
|
|
4347
|
+
p256TableBuild(table, p, s, acc)
|
|
4348
|
+
p256SetIdentity(acc)
|
|
4033
4349
|
for (let i: i32 = 0; i < 64; i++) {
|
|
4034
4350
|
// Digit i is the high nibble of byte i / 2 when i is even, the low when odd.
|
|
4035
4351
|
const at: i32 = i >> 1
|
|
@@ -4043,8 +4359,6 @@ const p256ScalarMult = (
|
|
|
4043
4359
|
p256PointAdd(acc, acc, entry, s)
|
|
4044
4360
|
}
|
|
4045
4361
|
p256PointCopy(out, acc)
|
|
4046
|
-
// The accumulator and the selected entry follow the scalar's digits, and a
|
|
4047
|
-
// signature's scalar is its nonce: both are wiped, and the table with them.
|
|
4048
4362
|
wipe(table)
|
|
4049
4363
|
p256WipePoint(acc)
|
|
4050
4364
|
p256WipePoint(entry)
|
|
@@ -4082,6 +4396,590 @@ const p256Generator = (): P256ProjectivePoint => {
|
|
|
4082
4396
|
return g
|
|
4083
4397
|
}
|
|
4084
4398
|
|
|
4399
|
+
// gen-p256-table:begin -- generated by scripts/gen-p256-table.mjs; edit that, not this.
|
|
4400
|
+
/**
|
|
4401
|
+
* The fixed-base comb table `p256BaseMult` reads: sub-table `c` (0 to 15),
|
|
4402
|
+
* entry `j` (1 to 15) at limb `(15c + j - 1) * 16`, is the affine point
|
|
4403
|
+
* (j_0 + j_1 2^64 + j_2 2^128 + j_3 2^192) 2^(4c) G, `j_b` bit `b` of `j`, as
|
|
4404
|
+
* X then Y in the Montgomery domain. Public: a function of G alone.
|
|
4405
|
+
*/
|
|
4406
|
+
const p256BaseTable = (): u32[] => [
|
|
4407
|
+
0x18a9143c, 0x79e730d4, 0x5fedb601, 0x75ba95fc, 0x77622510, 0x79fb732b, 0xa53755c6, 0x18905f76, 0xce95560a,
|
|
4408
|
+
0xddf25357, 0xba19e45c, 0x8b4ab8e4, 0xdd21f325, 0xd2e88688, 0x25885d85, 0x8571ff18, 0x16a0d2bb, 0x4f922fc5,
|
|
4409
|
+
0x1a623499, 0x0d5cc16c, 0x57c62c8b, 0x9241cf3a, 0xfd1b667f, 0x2f5e6961, 0xf5a01797, 0x5c15c70b, 0x60956192,
|
|
4410
|
+
0x3d20b44d, 0x071fdb52, 0x04911b37, 0x8d6f0f7b, 0xf648f916, 0xe137bbbc, 0x9e566847, 0x8a6a0bec, 0xe434469e,
|
|
4411
|
+
0x79d73463, 0xb1c42761, 0x133d0015, 0x5abe0285, 0xc04c7dab, 0x92aa837c, 0x43260c07, 0x573d9f4c, 0x78e6cc37,
|
|
4412
|
+
0x0c931562, 0x6b6f7383, 0x94bb725b, 0xbfe20925, 0x62a8c244, 0x8fdce867, 0x91c19ac3, 0xdd387063, 0x5a96a5d5,
|
|
4413
|
+
0x21d324f6, 0x61d587d4, 0xa37173ea, 0xe87673a2, 0x53778b65, 0x23848008, 0x05bab43e, 0x10f8441e, 0x4621efbe,
|
|
4414
|
+
0xfa11fe12, 0x2cb19ffd, 0x1c891f2b, 0xb1923c23, 0x01ba8d5b, 0x8ac5ca8e, 0xb6d03d67, 0x1f13bedc, 0x586eb04c,
|
|
4415
|
+
0x27e8ed09, 0x0c35c6e5, 0x1819ede2, 0x1e81a33c, 0x56c652fa, 0x278fd6c0, 0x70864f11, 0x19d5ac08, 0xd2b533d5,
|
|
4416
|
+
0x62577734, 0xa1bdddc0, 0x673b8af6, 0xa79ec293, 0x577e7c9a, 0xc3b266b1, 0xbb6de651, 0xb65259b3, 0xe7e9303a,
|
|
4417
|
+
0xd03a7480, 0xd6a0afd3, 0x9b3cfc27, 0xc5ac83d1, 0x5d18b99b, 0x60b4619a, 0x1ae5aa1c, 0xbd6a38e1, 0x49e73658,
|
|
4418
|
+
0xb8b7652b, 0xee5f87ed, 0x0b130014, 0xaeebffcd, 0x9d0f27b2, 0x7a730a55, 0xca924631, 0xddbbc83a, 0x9c955b2f,
|
|
4419
|
+
0xac019a71, 0x07c1dfe0, 0x356ec48d, 0x244a566d, 0xf4f8b16a, 0x56f8410e, 0xc47b266a, 0x97241afe, 0x6d9c87c1,
|
|
4420
|
+
0x0a406b8e, 0xcd42ab1b, 0x803f3e02, 0x04dbec69, 0x7f0309a8, 0x3bbad05f, 0xa83b85f7, 0xad8e197f, 0xc6097273,
|
|
4421
|
+
0x5067adc1, 0xc097440e, 0xc379ab34, 0x846a56f2, 0x841df8d1, 0xa8ee068b, 0x176c68ef, 0x20314459, 0x915f1f30,
|
|
4422
|
+
0xf1af32d5, 0x5d75bd50, 0x99c37531, 0xf72f67bc, 0x837cffba, 0x48d7723f, 0x0613a418, 0xe2d41c8b, 0x23d0f130,
|
|
4423
|
+
0xd5be5a2b, 0xed93e225, 0x5934f3c6, 0x6fe79983, 0x22626ffc, 0x43140926, 0x7990216a, 0x50bbb4d9, 0xe57ec63e,
|
|
4424
|
+
0x378191c6, 0x181dcdb2, 0x65422c40, 0x0236e0f6, 0x41a8099b, 0x01fe49c3, 0x2b100118, 0x9b391593, 0xfc68b5c5,
|
|
4425
|
+
0x598270fc, 0xc385f5a2, 0xd19adcbb, 0x7144f3aa, 0x83fbae0c, 0xdd558999, 0x74b82ff4, 0x93b88b8e, 0x71e734c9,
|
|
4426
|
+
0xd2e03c40, 0x43c0322a, 0x9a7a9eaf, 0x149d6041, 0xe6e4c551, 0x80ec21fe, 0x5fe14bfe, 0xc255be82, 0xf6ce116a,
|
|
4427
|
+
0x2f4a5d67, 0x98bc5a07, 0xdb7e63af, 0xfad27148, 0x29ab05b3, 0x90c0b6ac, 0x4e251ae6, 0x37a9a83c, 0xc2aade7d,
|
|
4428
|
+
0x0a7dc875, 0x9f0e1a84, 0x77387de3, 0xa56c0dd7, 0x1e9ecc49, 0x46086c74, 0xa5cffcd8, 0xf505aece, 0x8f7a1408,
|
|
4429
|
+
0xbef0c47e, 0xb37b85c0, 0xcc0e6a8f, 0x3596b6e4, 0x6b388f23, 0xfd6d4bbf, 0xc39cef4e, 0xaba453fa, 0xf9f628d5,
|
|
4430
|
+
0x9c135ac8, 0x95c8f8be, 0x0a1c7294, 0x3bf362bf, 0x2961c480, 0xdf63d4ac, 0x9e418403, 0x91ece900, 0xc109f9cb,
|
|
4431
|
+
0x58945705, 0xc2d095d0, 0xddeb85c0, 0xb9083d96, 0x7a40449b, 0x84692b8d, 0x2eee1ee1, 0x9bc3344f, 0x42913074,
|
|
4432
|
+
0x0d5ae356, 0x48a542b1, 0x55491b27, 0xb310732a, 0x469ca665, 0x5f1a4cc1, 0x29591d52, 0xb84f983f, 0xe76f5b6b,
|
|
4433
|
+
0x9f5f84e1, 0xbe7eef41, 0x80baa189, 0x1200d496, 0x18ef332c, 0x6376551f, 0x0bc6fb80, 0x808b0b65, 0x3ffe2e6b,
|
|
4434
|
+
0x5882e075, 0x2c83f549, 0xd5ef2f7c, 0x9103b723, 0x54d63c80, 0x52a23f9b, 0xf2f11bd6, 0x4b0b6587, 0x3670c319,
|
|
4435
|
+
0xb1580e9e, 0x55c4623b, 0x01efe220, 0x64edf7b2, 0xf5b343bc, 0x58af2010, 0xf2f142fe, 0x0f2e400a, 0xa85f4bdf,
|
|
4436
|
+
0x3483bfde, 0x03bfeaa9, 0xf0b1d093, 0xc7081603, 0x2ea01b95, 0x3dba1097, 0xe943e4c9, 0xb438f3a6, 0x47be92ad,
|
|
4437
|
+
0xe5bf6636, 0x00bb7742, 0x492bc95a, 0x717061e2, 0xfdb10087, 0xed2b3955, 0x727d4b2e, 0x878536b9, 0x0caa881b,
|
|
4438
|
+
0x849244fa, 0xe5f4ea0a, 0xaf2e65c7, 0x802680d4, 0xd2118940, 0x1a4babf5, 0x1e7d85d5, 0x5cc76086, 0xc1ce20e3,
|
|
4439
|
+
0xe48fb889, 0x6a7091c2, 0x7b8a9d06, 0x26882c13, 0x1b82a0e2, 0xa2498663, 0x3518152d, 0x844ed736, 0xd86e27c7,
|
|
4440
|
+
0x282f476f, 0x04afefdc, 0xa04edaca, 0x6119e34d, 0x8b256ebc, 0x0787d78b, 0x56a413e9, 0xe79b9b77, 0xcce3eab7,
|
|
4441
|
+
0x3933c815, 0x44b1f9eb, 0x9ec67e8b, 0x1f017601, 0xa15415ec, 0x660debe7, 0xf84f6c4e, 0xc49ec7fa, 0x721f7d41,
|
|
4442
|
+
0x56226f5e, 0xad7d54bc, 0x034174ea, 0xa55f8037, 0xefa077a4, 0xf75108de, 0x328ff4fe, 0x8a6a9dc9, 0x91740e8a,
|
|
4443
|
+
0xa202fb7e, 0x1847d47e, 0x5edbfacf, 0xa9d04fa1, 0x40cd7c19, 0xee23fe32, 0x78c229fb, 0xb4669b73, 0x3869c2f6,
|
|
4444
|
+
0x2819aca5, 0xb5c96085, 0xd653f05d, 0x6107115a, 0x168f3eff, 0x9a8c438a, 0x416bfc52, 0x849bb343, 0xf86328eb,
|
|
4445
|
+
0x29f4c1c4, 0x63072f96, 0x9664bf31, 0xa9fa892b, 0x5269e4ce, 0x69c52088, 0x8958f044, 0x064ef851, 0x9439cda8,
|
|
4446
|
+
0xb21bf983, 0x692ac542, 0x8303604f, 0x227b91d3, 0xf079ffe1, 0x15aaf9bd, 0x19f63e63, 0xf1f344fb, 0xf99ee565,
|
|
4447
|
+
0xd6219199, 0x8a1d661f, 0xd48ce41c, 0x8c883bc6, 0x3c74d904, 0x1065118f, 0x0faf8b1b, 0x713889ee, 0x6dbaacd8,
|
|
4448
|
+
0xc4d5ca2d, 0x3dc00d5f, 0x251f16ba, 0x69ada23e, 0x7e294cf6, 0x74281bb8, 0x8051a0fd, 0x260f928c, 0xd726f5db,
|
|
4449
|
+
0x40f31168, 0xab2425aa, 0xb4a911b5, 0x921498d8, 0x0f611044, 0x7c2f8272, 0x12c219b4, 0xece740a7, 0xe87f63a2,
|
|
4450
|
+
0x2745aec5, 0x09aba2fe, 0x47d5a921, 0xe86cd0ab, 0x87f5948f, 0x7180c826, 0x9dfca0dd, 0xf74023f2, 0x5fbfa60e,
|
|
4451
|
+
0xaf887afb, 0xa4cc0412, 0x94681a6c, 0x0cafd853, 0x318539e1, 0x6246fafb, 0xada9a75a, 0x2ef253e8, 0xd83accbd,
|
|
4452
|
+
0xd763016b, 0xca617a1c, 0x0139f615, 0xd281994e, 0x723087af, 0xeca0d5e2, 0x046fea4d, 0xc46c2cec, 0xb0e87754,
|
|
4453
|
+
0x27cc7450, 0x6f762cb5, 0x9febf21f, 0x21e5671a, 0x071dd1bb, 0x2539cab4, 0x7f4156b4, 0x73ad2bc4, 0xf10737ee,
|
|
4454
|
+
0x9d7c5267, 0x95acc35d, 0x93d85779, 0x911648d2, 0xc0eb18ad, 0x058ac5d8, 0xbd7720ad, 0x5f48bb8a, 0x09f42a6a,
|
|
4455
|
+
0xe042207b, 0xf3ce7109, 0x03af9a7d, 0x0d26f950, 0x547c9e61, 0x7d89313b, 0x25e1a21c, 0x58851410, 0xf7199a9e,
|
|
4456
|
+
0x44b98d8b, 0x8fd57923, 0x0a38867e, 0x0869e452, 0x90487017, 0xffe722d3, 0x310a74a6, 0x7f9b0239, 0x63f12dc3,
|
|
4457
|
+
0x46eda382, 0xcd25744a, 0xf2c6c1ad, 0x00de4447, 0xb5b1163e, 0x7d088476, 0x47f6433f, 0x5259e5a1, 0xa9d81957,
|
|
4458
|
+
0xc2004ab2, 0x1a16f58a, 0xc2dcd328, 0x8f865362, 0x6070bb81, 0x7482a889, 0x55ed5421, 0x3ad94297, 0x7c874697,
|
|
4459
|
+
0x526eb1d0, 0xd7a2d123, 0x6de620db, 0x990822f0, 0x4213a3e2, 0x1d2f9a4c, 0xbf28bb26, 0xd6c5cc43, 0xd621e3fc,
|
|
4460
|
+
0x7944ca3e, 0x663172e6, 0xdc2b2618, 0x696946fc, 0x486d8ffa, 0xb9cba56d, 0x50fbc6d8, 0x90f35a15, 0x7e3d423e,
|
|
4461
|
+
0xc0dd962c, 0x7c3da195, 0x3cfd5d8b, 0xe673fdb0, 0x889dfca5, 0x0704b7c2, 0xf52305aa, 0xf6ce581f, 0x914d5e53,
|
|
4462
|
+
0x399d49eb, 0xd005832a, 0x0db2fb5e, 0x91042e4f, 0x5f5efd3b, 0xed70f8ca, 0x8c4ffdc6, 0xb52da9cc, 0xe4645d0b,
|
|
4463
|
+
0xc9001d1f, 0x9596f58b, 0x4e117205, 0x52c8f0bc, 0xe398a084, 0xfd4aa0d2, 0x104f49de, 0x815bfe3a, 0x30af1053,
|
|
4464
|
+
0x664283ae, 0xcc93b904, 0x9a80886b, 0x691ba917, 0x51d9c2d2, 0x9044e4c9, 0x3b258bdc, 0xc80eebcd, 0x58caf1d3,
|
|
4465
|
+
0xf41b11e4, 0x97080530, 0xab9f8537, 0x2e59cdbc, 0x2f98c394, 0x3ef3e7c8, 0x846e364f, 0xc16c236e, 0xdea50ca0,
|
|
4466
|
+
0x7f33527c, 0x0926b86d, 0xc4810775, 0x0598e70c, 0x6c2a3609, 0xf024e924, 0xa6755e52, 0x9db4afca, 0xe0fa07a4,
|
|
4467
|
+
0x66831790, 0x15c3ce7d, 0xa6cbb0d6, 0x5b4ef350, 0xb4aba4d7, 0x355d7660, 0x9ac61be2, 0xeac600e1, 0xadf28187,
|
|
4468
|
+
0xa3609609, 0x186e5c6f, 0x96227ab0, 0xbfea853e, 0x37a1bb38, 0x6348b322, 0x3e23311c, 0x855285c7, 0xb4d7dae5,
|
|
4469
|
+
0x279570f8, 0x61e4abf1, 0x9fe571e2, 0xcd3a6f09, 0xa727241b, 0x7e2b98c8, 0x71a4495c, 0x79bfd367, 0x188c2cdb,
|
|
4470
|
+
0xe8dfc609, 0x98005dd4, 0xdf745f79, 0x1ad81c3f, 0x4c979f59, 0xc3a2d587, 0x948d24d0, 0xcfcec765, 0x7982d8d6,
|
|
4471
|
+
0x87cdb9d0, 0x28950f80, 0x14fdaa7c, 0x3c4de5b0, 0x6dfda881, 0x2b96630f, 0x93308d92, 0x1f5fe4b0, 0x83986698,
|
|
4472
|
+
0x1bc35296, 0xf48b6d2e, 0x55fb795c, 0xb9bc87b9, 0x0c6057a7, 0x67b162cb, 0xe087aaa9, 0x81fdad90, 0x25914f78,
|
|
4473
|
+
0x0d2cf6ab, 0xcf638f56, 0xcc054de5, 0xb90bc03f, 0x18b06350, 0x932811a7, 0x9bbd11ff, 0x2f00b330, 0xb4044974,
|
|
4474
|
+
0x76108a6f, 0xa851d266, 0x801bb9e0, 0xbf8990c1, 0x0dd099be, 0x3f23df13, 0xe9bc8663, 0xc7310fdc, 0x957c7ccf,
|
|
4475
|
+
0xe2f49de6, 0x76b6b19a, 0xa55cdaea, 0xa28a6099, 0x408587b7, 0xc159f236, 0xa86d2d86, 0x5551bf23, 0x6593d35b,
|
|
4476
|
+
0xaef3785b, 0xcf4cc993, 0x06cb373d, 0xc99bfa3c, 0x00e87860, 0x347ffd87, 0xe51b4996, 0x1521ec86, 0xace2d5f5,
|
|
4477
|
+
0x20d11525, 0xf04ad064, 0x11fdd77c, 0xbf6809bb, 0x80b9a491, 0xf9ad5a5a, 0x68e26ca2, 0xae2d0b06, 0x43a50244,
|
|
4478
|
+
0x4c6f408b, 0x3ad32771, 0x43b235ec, 0xc6764200, 0x14c43425, 0xe45331a6, 0xae92bd38, 0xde4e1376, 0x47c2b42e,
|
|
4479
|
+
0xdca1dfbf, 0x485b3d0b, 0x30d4bcf0, 0x167ab03f, 0x77ef1491, 0x76f93e73, 0x6aa6d8e9, 0x812c2301, 0xe4136bf5,
|
|
4480
|
+
0x5334f01e, 0xbfd073a2, 0x02bc1869, 0x1761b340, 0x7ed292da, 0x07e2d353, 0x758f85fa, 0x10466a92, 0x774f5cb8,
|
|
4481
|
+
0x257134cf, 0x9f731e22, 0x1c5c0281, 0x647bb7e5, 0xa534284a, 0xbf3ca638, 0xd4e225f5, 0x76a99ad0, 0xfecd0d0a,
|
|
4482
|
+
0x50a5c746, 0x2aeaeef7, 0x5f752e19, 0x2a7e3b6e, 0x39162456, 0xf020ef36, 0x0c6a8f12, 0xc5e148e0, 0x552eb531,
|
|
4483
|
+
0xf2e01311, 0x1dea53a9, 0xc5576768, 0xb8887803, 0xec5bbe91, 0xbbb7030d, 0x8d401059, 0x34a1f6a8, 0x55c3da6b,
|
|
4484
|
+
0x40ca7ee8, 0xa78f8c0a, 0xe7701154, 0xc2ff7cba, 0x616b7301, 0xb54e5556, 0x8290384d, 0xd091c35c, 0xdf971d6d,
|
|
4485
|
+
0x8592f335, 0x996f0327, 0xfc2b4e00, 0xf95684f7, 0xef571f04, 0x114521ac, 0x4abb78e3, 0x48d9b5ea, 0xda9891d8,
|
|
4486
|
+
0x3df9c7ba, 0x944cab81, 0x1ca68374, 0x76fdb53f, 0x98453f5b, 0xb1cd8a0e, 0x995789b8, 0xe42ce845, 0xafe5e48e,
|
|
4487
|
+
0xab4b35a2, 0x6772b0e5, 0xf5eeaacf, 0x1d8b6001, 0x795b9580, 0x728f7ce4, 0x41fb81da, 0x4a20ed2a, 0x4fec01e6,
|
|
4488
|
+
0x9f685cd4, 0xa7ff50ad, 0x3ed7ddcc, 0x0c2d97fd, 0x460fd264, 0xeb82f4f9, 0x3a241426, 0x97acf4ec, 0x3e22a7b3,
|
|
4489
|
+
0x5ea8b640, 0x0426c400, 0x4e969285, 0x5e3295a6, 0xa6a45670, 0x22aabc59, 0x5f5942bc, 0xb929714c, 0xfa3182ed,
|
|
4490
|
+
0x9a6168bd, 0x104152ba, 0x2216a665, 0xb6926368, 0x46908d03, 0x5ddf598a, 0xea262aa9, 0x845f36cc, 0x076d8f30,
|
|
4491
|
+
0xb4ee47ca, 0xec6bd09f, 0x74a45f72, 0x52f8aabe, 0xb6b52563, 0x76cd6bfc, 0x453a73e3, 0xb74ef1d6, 0xc09b38b8,
|
|
4492
|
+
0xdab3d489, 0x8260f2a4, 0xfe127fe4, 0xfa181e69, 0xef0a3fec, 0x30d69a98, 0x9ea02f81, 0x66eab95d, 0xb2e9cf8e,
|
|
4493
|
+
0x24720021, 0x520f2beb, 0x1df84361, 0x621c540a, 0x71fa6d5d, 0x12037721, 0x0ff5f6ff, 0x6e3c7b51, 0xabb2bef3,
|
|
4494
|
+
0x817a069b, 0x90e475ad, 0x11c67815, 0xb3d5dd6d, 0xe5896605, 0xafed38c7, 0xaaba94b8, 0x7e69b03d, 0xd04a17a6,
|
|
4495
|
+
0x35a866e7, 0xf004a55d, 0xa1b9cbde, 0x68053f8f, 0x95e055f9, 0xbd7d0da5, 0xdd776acb, 0x001fe5e0, 0xe4cc5a2f,
|
|
4496
|
+
0xe0bd60e5, 0xea3bea9c, 0xa1b0d70c, 0x2e977756, 0xbd3658ff, 0xb909fa31, 0x0f67db88, 0x8427e332, 0x6ddea819,
|
|
4497
|
+
0x642603ba, 0x4f21cdd2, 0xc0d37dd5, 0xff41867e, 0x229364de, 0x215c4f50, 0x0a4a8bd7, 0x1fb7918b, 0x108c9193,
|
|
4498
|
+
0xae76ec9b, 0x5664344b, 0xcf21b716, 0x0ced5add, 0x2f5ecea9, 0xbe0d176d, 0x304fe2c5, 0xe4d02617, 0x62b56606,
|
|
4499
|
+
0x2a005e0e, 0xf44d72e2, 0x53f66c85, 0xdb7af5bb, 0x060b5f61, 0xf431f462, 0x7bd057c2, 0xa56f46b4, 0x47e1bf65,
|
|
4500
|
+
0x348dca6c, 0x41bcf1ff, 0x9a38783e, 0xda710718, 0x7a5d33a9, 0x2e0aeaf6, 0x5a779987, 0x2d29d187, 0xca87314d,
|
|
4501
|
+
0xc687d733, 0xfa0edc3e, 0xe4f95225, 0x1b28e15a, 0x3df980e1, 0x4eb867f2, 0xacf4a4d9, 0x043eadd3, 0x2aa6ca92,
|
|
4502
|
+
0x9641d415, 0x342d695b, 0x841c4983, 0xa2335845, 0x6cece75a, 0x692a3765, 0xae9b262f, 0x9bd3d546, 0xe5e3935c,
|
|
4503
|
+
0x1c8955f8, 0xd6d12fb5, 0x05889204, 0x99d896eb, 0x252da333, 0x07b25abe, 0x9eae7fc0, 0x4c673c97, 0x4722592c,
|
|
4504
|
+
0x56f8a0ab, 0x117abed5, 0x93333d2f, 0x6bbb5aa2, 0x3db19b35, 0xc1015133, 0xf7d4b80b, 0x4331fdad, 0xccdf37ef,
|
|
4505
|
+
0xcb303da0, 0xf5dac1ab, 0x7cfdee8a, 0x15d317af, 0xa2e91c63, 0xfc50b381, 0xf235e580, 0x954267d2, 0x05a78396,
|
|
4506
|
+
0x7e21f4b0, 0xb0f5e0ea, 0xa13e74a2, 0xc8f91e3f, 0x6c323801, 0xebce481a, 0x65bec55b, 0x10398dfe, 0x2e4ee5d2,
|
|
4507
|
+
0x312baf40, 0xe62cd1a4, 0x427f944e, 0x1b83f749, 0x3c868075, 0xf030eddb, 0xae26e665, 0xf4656f11, 0x62ff0b26,
|
|
4508
|
+
0x5fe7821a, 0x25a8a91b, 0x61ffaefa, 0x3057665e, 0xd5a2d0cd, 0x43d6ebe6, 0xb782bcc3, 0x853579f0, 0x649acf14,
|
|
4509
|
+
0x9940863c, 0x097bd76c, 0xe19a7728, 0x3f637302, 0x0cdbc92a, 0xd39f7723, 0x511cf4d7, 0xae7e1231, 0x58ee7426,
|
|
4510
|
+
0xdd2a99d8, 0x3cfa7e56, 0xfdab2e12, 0x71f441dd, 0x985a984b, 0xae68d684, 0x6824fcf1, 0xc9e16bcd, 0x34960583,
|
|
4511
|
+
0x5d283337, 0xa6aabd92, 0xfcfd1be8, 0x13a4589e, 0xee836e7e, 0xabc81275, 0xf344cc96, 0xe6eeaff3, 0x4a2ac6d1,
|
|
4512
|
+
0x8b599423, 0xf2cbc64c, 0xfd8145a1, 0x5fd55356, 0x53bb6804, 0x3016dcfd, 0x56eeb1d8, 0x4e14d38c, 0xf93f71e4,
|
|
4513
|
+
0x916a2596, 0x51d5fc82, 0x925a14dd, 0x62e0204a, 0x2f4fd7c6, 0xc74a7c18, 0xe3779ee3, 0x0f0165fc, 0xbd495d9e,
|
|
4514
|
+
0xe00e7f9d, 0x20284e7a, 0x1fa4efa2, 0x47ac6219, 0x4564bade, 0xc4708e8e, 0x90e6312a, 0xa71e9adf, 0x4f5725fb,
|
|
4515
|
+
0x3d684b9f, 0xe95f55ae, 0x1e94b415, 0x47f7ccb1, 0xf1c367ca, 0xe4050f1c, 0xc90fbc7d, 0x9bc85a9b, 0xe1a11032,
|
|
4516
|
+
0xa373c4a2, 0xad0393a9, 0xb64232b7, 0x167dad29, 0xf5577eb0, 0x94b78ab2, 0x1604f301, 0xe829348b, 0x0baa94af,
|
|
4517
|
+
0x41654342, 0x77fbd8dd, 0xb65659b6, 0xf74b5ee5, 0x0de651de, 0x58d27206, 0x58635522, 0x9a06f93c, 0xb51b7153,
|
|
4518
|
+
0x1741dc84, 0x5e3b1cf2, 0xd74e2f48, 0xf2886a41, 0x71f6a8e9, 0x034d98f3, 0x0f719872, 0xbca289a6, 0xee792e37,
|
|
4519
|
+
0xc63c4962, 0x80531fe1, 0x981fdb25, 0x50541e89, 0xfd4c2b6b, 0xdc1291a1, 0xa6df4fca, 0xc0693a17, 0x0117f203,
|
|
4520
|
+
0xb2c4604e, 0x0a99b8d0, 0x245f1963, 0xc6212c44, 0xaedc20aa, 0x520f52a8, 0xb1ed4e56, 0x9673d875, 0x9da03662,
|
|
4521
|
+
0x3335f166, 0x47c5ce72, 0x54e58c2d, 0x24e892e3, 0x38845a00, 0x07228f01, 0x2f8855a7, 0xff9f34a2, 0xc4e307fc,
|
|
4522
|
+
0xf7d6d205, 0x3455bb93, 0xbcd425e2, 0x6d96414f, 0xd7cbb02c, 0x5e6b555b, 0x19b3edb4, 0xfd18da56, 0x958c797e,
|
|
4523
|
+
0xe98f9273, 0x22dd3354, 0x09cb54d9, 0x84212234, 0x7a6402ba, 0xe39ca71d, 0x9378f1de, 0x822d787c, 0x2beaa75d,
|
|
4524
|
+
0xaaf852d0, 0x510fc33a, 0xd8af72b4, 0x583f402b, 0xe4de6bd8, 0xb3481fdb, 0xede94383, 0x48d08e35, 0x924056d7,
|
|
4525
|
+
0xeabd2ecc, 0x8e349069, 0xe0d67374, 0x7b33363c, 0x2d8c05eb, 0x70e41945, 0x82d2ba0a, 0xb78a5b35, 0xe005d3e7,
|
|
4526
|
+
0x8490d830, 0xadf7cccf, 0x75d9bc15, 0xdfa1e1b0, 0x81a3e5d6, 0x249bc17e, 0x8c39e444, 0x8ea7fd43, 0xf37dccb2,
|
|
4527
|
+
0x907fba12, 0xda654873, 0x4a372904, 0x35daa6da, 0x6283a6c5, 0x0564cfc6, 0x4a9395bf, 0xd09fa4f6, 0x444a73f6,
|
|
4528
|
+
0x7b2c19d8, 0x6feee88a, 0xc88f4ce4, 0xd431d8d2, 0x9a1f7a70, 0xc1b25749, 0xae042119, 0x45b9ddf1, 0x467b64ce,
|
|
4529
|
+
0x689f927b, 0x45df2010, 0x01d12b64, 0xc874c671, 0xd4df95fe, 0xc4aca24d, 0x732325c7, 0xc660550e, 0xe3fe0994,
|
|
4530
|
+
0xd4d12681, 0xecfd8b7c, 0xffcfe8ed, 0x308e65b4, 0x858b5225, 0xdc162423, 0x9523f8b4, 0x24271a6b, 0x89507a80,
|
|
4531
|
+
0x658d58c5, 0xb4d2eaf6, 0xb9c205ed, 0x80e7ba28, 0x3c52ebb9, 0x46c06395, 0xd02f1e43, 0x7333d509, 0xb79ca51f,
|
|
4532
|
+
0x2d6b41fd, 0x23817a73, 0xb3b3d1dd, 0x1cf976a4, 0x1fdeddb4, 0x97b7bac8, 0x4be0fc0f, 0xa784d816, 0x1e638fd1,
|
|
4533
|
+
0xe439bf08, 0xfa4eaf60, 0x5fca6ff1, 0x8cb0c4ac, 0x4b607037, 0x9da506c2, 0x0db25734, 0x46e892ab, 0xdffb31b0,
|
|
4534
|
+
0x115fd8de, 0xc90eaaae, 0xd9135992, 0xeebf8578, 0xb41eeaa6, 0x7a389c05, 0xcb24be1e, 0xb1809587, 0x29971d57,
|
|
4535
|
+
0x418ef20c, 0x078a14ba, 0x824ba43d, 0x6a4cd780, 0xc442ac87, 0xe7447778, 0xd8bba232, 0x1c472aca, 0x44237888,
|
|
4536
|
+
0xb45c362f, 0x84ef1c00, 0x7b2c1676, 0x4500185c, 0x1e9f3c99, 0xcfb13db4, 0x8122fdd0, 0x6eff12e1, 0xe96e5c93,
|
|
4537
|
+
0x25e31583, 0x0abcc1da, 0xdc95f5f9, 0xc844e8cc, 0x301f27cf, 0x5a886b1b, 0xb7b385f0, 0x845d7086, 0x05090238,
|
|
4538
|
+
0x8d1c658c, 0x2c07960b, 0xcdd1b2a6, 0xee151588, 0xef902dcc, 0x0fea91e5, 0x85ff4f35, 0xaf91bda6, 0x32954682,
|
|
4539
|
+
0x8eeaafca, 0xfe1f173d, 0x2da4161b, 0x5badab63, 0xbf84e659, 0x2107bc51, 0xad86caa0, 0xf4368698, 0x6e9fbe0e,
|
|
4540
|
+
0x84ad8cf4, 0xb45a2551, 0xf7f134ad, 0x584c5e20, 0xa7a8746a, 0xb9dc7035, 0x267e4ea1, 0xb9548c9b, 0x593a15cf,
|
|
4541
|
+
0x4bd012f3, 0x5e6e2135, 0x8c8f936e, 0xdf31cc6a, 0xb5c241dc, 0x8af84d04, 0x345efb86, 0x63990a6f, 0xb9b962cb,
|
|
4542
|
+
0x6fef4e61, 0x87dec0e1, 0xe5aa692a, 0xf7b39d00, 0x010ded8d, 0x54cfa0b5, 0x7b1b80c8, 0xa0f8ea28, 0x66beb876,
|
|
4543
|
+
0x3476cd0e, 0x50d7f531, 0xb08d3949, 0xa63d0e65, 0x53479fc6, 0x1a09eea9, 0xf499e742, 0x82ae9891, 0xcafe34e9,
|
|
4544
|
+
0x930fbab8, 0xfaf8d02d, 0x8b33587b, 0x30db8762, 0x8c041f1c, 0x2370856f, 0x492048ca, 0x9c6cb54f, 0x8151d1aa,
|
|
4545
|
+
0xd8caa5a0, 0x1eba8b5b, 0xcf169ee5, 0x76bc6d33, 0x4e8b7981, 0xcb5b1d8a, 0x338d6e43, 0xecaff541, 0x4541d5cc,
|
|
4546
|
+
0x56f7dd73, 0x96bc88ca, 0xb5d426de, 0x9ed3a2c3, 0x48d94f6b, 0x2ef8279c, 0x6354a3bb, 0x0b1867f2, 0xd575465b,
|
|
4547
|
+
0x95225151, 0xef99b0ff, 0xf94500d8, 0xf3e19d88, 0xd7aaa073, 0x0f5f1057, 0x36c276db, 0xbbdad564, 0xfa3e5314,
|
|
4548
|
+
0x607ba0b9, 0xd4294870, 0xbe3d37d5, 0x00135f6c, 0xb20952f0, 0x35901230, 0x51ed6e5c, 0x5de179e9, 0x131ddbc6,
|
|
4549
|
+
0x4053e8b0, 0x0ba26c24, 0xddf1b03b, 0x5947e92d, 0xecff7413, 0xce76ac18, 0x03a21c67, 0x534798dc, 0xf4a61d51,
|
|
4550
|
+
0xd78496ec, 0x9d4e9a1a, 0x19c93947, 0x85a7643f, 0x66e6d3ea, 0xefab6bd8, 0x579370e7, 0x7062dc2c, 0x42ad8262,
|
|
4551
|
+
0x55af541e, 0x48b57cb4, 0x25ed55da, 0xffb93f22, 0x7ccc4e48, 0xd0fa817f, 0x5b0f1579, 0xfcc7f375, 0x8bcf3057,
|
|
4552
|
+
0xc2174926, 0x8bc81c11, 0xf252b716, 0xb4496bda, 0xbe6b96af, 0x6ab5bd65, 0x285df5ce, 0x0ebcf726, 0x103c46e6,
|
|
4553
|
+
0x6231470e, 0x4482b831, 0x487c2109, 0x6f6dfaca, 0x62e666ef, 0x2e0ace97, 0x1f8d1f42, 0x3246a9d3, 0x574944d2,
|
|
4554
|
+
0x1b1e83f1, 0xa57f334b, 0x13dfa63a, 0x9f025d81, 0x0cf8daed, 0xc7bc2f85, 0x26ba2bdd, 0x32dec41c, 0xc9e648b6,
|
|
4555
|
+
0xfc6a702d, 0xb041d057, 0xa61923e3, 0xdc6b67a8, 0x2ee75030, 0x36953013, 0xa56702a7, 0xe8f629ab, 0xff045ea3,
|
|
4556
|
+
0x4cc279c7, 0x97a42e5e, 0x5182e1c6, 0x3830cdd9, 0x38102852, 0x4a58937e, 0xc459844c, 0xa9f3bb5d, 0xe27f6491,
|
|
4557
|
+
0x6665a0db, 0x6da634dd, 0xc782a8be, 0xde95ae0b, 0x66d8b354, 0x42d01d10, 0x40d9ae3e, 0xa80812fe, 0xc6c740b5,
|
|
4558
|
+
0xdb7d946e, 0x64dcc9fc, 0xb8e91cf8, 0xa770615e, 0x3bdc86f4, 0x4b7c0092, 0xdf88dbdc, 0x8b831a86, 0xacc0b574,
|
|
4559
|
+
0xaea3ec1d, 0xe437cd0d, 0x35453527, 0xacd4d177, 0x0cce1aa8, 0x1a5bf055, 0xd11dce0d, 0xa9701b7b, 0x9dfd583b,
|
|
4560
|
+
0x3110f03d, 0x36f320cd, 0xd47088bc, 0xf022bf5d, 0x52bcfa18, 0xc0e616f7, 0xa66d5ba6, 0x36e50eee, 0x6a9f47e5,
|
|
4561
|
+
0xc6f7545d, 0xe438ea70, 0x9dafcc12, 0x771269d2, 0xd9c2282b, 0x7f90e30e, 0x2a70ac8a, 0xcb9ccd57, 0xd5503baa,
|
|
4562
|
+
0xe9aff801, 0xf83228cb, 0x9a8e261b, 0x72a10639, 0xa59fe1fe, 0xe2e5646d, 0xc0fc2b71, 0x84f2b4c5, 0xa1c87900,
|
|
4563
|
+
0xcb0be8d4, 0x3d61f821, 0x69b59d6e, 0x7ebeae3a, 0xba95ea76, 0x4d5821b2, 0xf034f97a, 0xb577d863, 0x53a9b4f7,
|
|
4564
|
+
0xea71aa81, 0x626d5850, 0x464d4bbc, 0xf3e25aec, 0xa65b8e8d, 0x30e18b9b, 0xf9b10fe7, 0xcbd5aa66, 0x25436661,
|
|
4565
|
+
0x0edadcbe, 0xaa183603, 0x585ce725, 0xaf6fd855, 0x2c3ad38a, 0x1a0ce8ab, 0xcaefdee5, 0x0a5b7032, 0xd64ef724,
|
|
4566
|
+
0x0e244c66, 0x3819187b, 0x3a330b7d, 0x8508511e, 0x66a4259b, 0xdbb3a201, 0xf3b22271, 0x1682e055, 0xf5571384,
|
|
4567
|
+
0x868af75d, 0xd9d0c8c4, 0x45c8c7ea, 0xd7325cff, 0xcc81ecb0, 0xab471996, 0x611824ed, 0xff5d55f3, 0x1977a0ee,
|
|
4568
|
+
0xbe314541, 0x722038c6, 0x5085c4c5, 0xf94bb495, 0x2d5335bf, 0xc8e2a082, 0x894ad8a6, 0xf79588c0, 0xa80d1db6,
|
|
4569
|
+
0xb55768cc, 0xfa52fc69, 0x7f54438a, 0x0b4df1ae, 0xf9b46a4f, 0x0cadd1a7, 0x1803dd6f, 0xb40ea6b3, 0x55eaae35,
|
|
4570
|
+
0x488e4fa5, 0x382e4e16, 0x9f047d55, 0x2f6e0c98, 0xc9b5b7e0, 0x5ee244e8, 0xcffcff77, 0x2c18c2c5, 0xbb62fee0,
|
|
4571
|
+
0xe8a0fada, 0x8f2d4a68, 0xae2b136b, 0x9fc23153, 0x6380179b, 0x9a2e3ca4, 0x32b9613f, 0x99edf1ef, 0x8eda79b5,
|
|
4572
|
+
0x8050cad5, 0xd3b630cc, 0x4249a3ff, 0x7189e71f, 0x32670d2f, 0x5ecf91e7, 0xc6438748, 0xdb757a21, 0x15758e57,
|
|
4573
|
+
0x290a9ce5, 0x427d09f8, 0x38384a7a, 0x846a308f, 0xb0732b99, 0xaac3acb4, 0x17845819, 0x9e941009, 0xa7ce5e03,
|
|
4574
|
+
0x95cba111, 0x674d4515, 0x7ecf3b31, 0xdcf3c04c, 0x52a5c474, 0xe3aab682, 0x161abef6, 0x2ce9c033, 0x5c24bd69,
|
|
4575
|
+
0xc605bf93, 0xd1ac15a6, 0x47a9e3a6, 0xf00b8a93, 0x5986ade3, 0xefb2a126, 0xfb89493b, 0xfc158f3b, 0xebd43774,
|
|
4576
|
+
0xeec3e34d, 0x835d2a16, 0xcd79a3d9, 0x9f47c615, 0x543e89c3, 0x14bdbd0c, 0x81f151fc, 0x0a24e3ff, 0x04931264,
|
|
4577
|
+
0x8d780e67, 0x8c0841de, 0x952d4cc7, 0x3ae4e553, 0x93c99c91, 0x22e1710a, 0xe107e98a, 0xf87397d3, 0xf031ffb1,
|
|
4578
|
+
0x28b3be02, 0x2da9f943, 0x03f1e586, 0x1c7d5327, 0x97829560, 0x21daf1e6, 0x7b930f52, 0xe2760d97, 0xbcc50a01,
|
|
4579
|
+
0x28fab177, 0xb8ac21fd, 0x192480d7, 0xbcdd3b5e, 0xe457a477, 0xa0158eea, 0xee6ddc05, 0xd19857db, 0x18c41671,
|
|
4580
|
+
0xb3265224, 0x3c2c0d58, 0x3ffdfc7e, 0x26ee7cda, 0x3a3a5254, 0xdf02c3a8, 0x341b0869, 0x723bbfc8, 0xa023bf42,
|
|
4581
|
+
0x14452691, 0x3d15002a, 0x8af3ceed, 0xaf7931a7, 0xe86814ad, 0x6811cfc1, 0xb4f03d83, 0x532a485b, 0xf761e54a,
|
|
4582
|
+
0x5499a002, 0x93f727b0, 0xdf4819a6, 0x4d529f4d, 0x10140491, 0x4fc44251, 0x0f0c8c00, 0xe3ee0074, 0x7d0b6305,
|
|
4583
|
+
0x8b6a59fe, 0x6ddd630c, 0xd1286983, 0xf221e433, 0x2113eac2, 0xcdbea310, 0xbd8533ad, 0xe972fc1c, 0x491870fd,
|
|
4584
|
+
0xcd0db09c, 0x54ae320d, 0x5f4ecab6, 0xc35c4fb3, 0x1016fbd1, 0x25e4cb1f, 0x78d1df22, 0x6e8c9b97, 0xf091b223,
|
|
4585
|
+
0x57f13f08, 0xee39b1b9, 0x99f60998, 0xc1d9f897, 0x78026534, 0x5ed2b176, 0xc7c0a727, 0x16991514, 0xda40f92f,
|
|
4586
|
+
0x6e17e142, 0xa7fc6664, 0x8e988460, 0xae7ca355, 0xbe9740f6, 0x675ea5fd, 0xb755a13a, 0xe548a53e, 0x7e16e100,
|
|
4587
|
+
0x4b1db8ef, 0xd53f7bc2, 0x14a73282, 0xaccc3898, 0xb74b3d14, 0x9c444783, 0x6f5fba65, 0x22965083, 0x13105032,
|
|
4588
|
+
0x3e576bd3, 0xd4e38cf9, 0xc5f6d8ce, 0x89a9ce49, 0xf9c282e6, 0xe652318c, 0x286d6557, 0xc567109c, 0xb04116a7,
|
|
4589
|
+
0x574e3941, 0xb40d2f0d, 0x465232af, 0x172217df, 0x593f8e37, 0x4f1473aa, 0xe6eddb53, 0x81ac4e9b, 0x34ba0407,
|
|
4590
|
+
0xba63cdcf, 0xdbe6718e, 0x78903e1e, 0x569f695d, 0xc08ce9a3, 0x07c1f4ad, 0x5e2aa546, 0x9fd00575, 0xc9a24900,
|
|
4591
|
+
0x9113aced, 0x3af797d8, 0xe253ed7e, 0x1b5d4123, 0x67a80542, 0x7dd10956, 0x3e2886b2, 0xe7781205, 0x1610cd52,
|
|
4592
|
+
0x0ed88310, 0x236a1040, 0x0da4dc01, 0x924a7203, 0x427ca1f2, 0xaafd3d7d, 0xa4737b77, 0x96a5ba97, 0x66275220,
|
|
4593
|
+
0x7ee66858, 0x87c05743, 0x37da5d39, 0xaeb7ce88, 0xd4ae3b19, 0xee946502, 0x20151427, 0x7f99824f, 0x92430206,
|
|
4594
|
+
0x206828b6, 0xe1112357, 0xaa9097d7, 0x09e414ec, 0xacf9a2f2, 0x27915356, 0xdbdac9da, 0x001efee3, 0x7e0734b7,
|
|
4595
|
+
0xd2b288e2, 0x54fab5bb, 0xf62dd09c, 0x4c630fc4, 0xbe24319a, 0xf92dda31, 0xe095a8e7, 0x03f7d28b, 0x98782185,
|
|
4596
|
+
0xa52fe840, 0x29c24dbc, 0x276ddafe, 0x1d7a64eb, 0x80cd5496, 0x7f1dbe42, 0xe4360889, 0x8438d2d5, 0x2f81a877,
|
|
4597
|
+
0x85169036, 0x7e4d52a8, 0x3e3b779e, 0xa2d8833d, 0xa667b2c3, 0x21dd8a53, 0xc9da1f25, 0x05fb5ec5, 0xf85dffeb,
|
|
4598
|
+
0xecb2468b, 0x271b8540, 0xc061f2f7, 0x41be795f, 0x003181cb, 0xbf6590ce, 0x5ee497ce, 0x9b9e69ae, 0x396ed24c,
|
|
4599
|
+
0xca8d9d1a, 0x488f1185, 0xd987ded2, 0xadf2c77d, 0x60c46124, 0x5f3039f0, 0x71e095f4, 0xe5d70b75, 0x6260e70f,
|
|
4600
|
+
0x82d58650, 0xf750d105, 0x39d75ea7, 0x75bac364, 0x8cf3d0b1, 0x21d01329, 0xf3a7564d, 0x5727c3cb, 0x1cd2f0af,
|
|
4601
|
+
0x874ed794, 0x67e40cda, 0xe86d4cd7, 0x2e8ee7be, 0x3abb5109, 0x0717bb23, 0xa8ebcf88, 0xa46260a6, 0x17268004,
|
|
4602
|
+
0x883f18ce, 0xb937c2e7, 0xad63ca96, 0x90a56a21, 0xd9a68a62, 0x0245263c, 0xcffe9420, 0x07526708, 0xdb53d24e,
|
|
4603
|
+
0x8b3f4961, 0x97292ed4, 0x8c38fd87, 0xd1a6ff3f, 0x533f1642, 0x08c1750d, 0x3a174e91, 0x734a973d, 0xa6ce129a,
|
|
4604
|
+
0x9215ba62, 0x38a5c9a0, 0xc4aa86b7, 0xebc26686, 0x0a5c25ba, 0x09a7fa96, 0xf64f0d18, 0x4cf891ce, 0x2e1a24b4,
|
|
4605
|
+
0x703fab1f, 0xa4e43d63, 0x27e7409f, 0x1454d426, 0xcafac378, 0x3a0b46c1, 0xa77e4b6e, 0x9d13839a, 0xce18d416,
|
|
4606
|
+
0xc08548e6, 0xc42bd6d2, 0xdb567d6a, 0xbb1f96ae, 0x6df86468, 0x4843b28e, 0x0efe5b1a, 0x6379b240, 0x961bbb05,
|
|
4607
|
+
0x70a6a26b, 0xb6caf5f0, 0x328e6e39, 0x70686c0d, 0x895fc8d3, 0x80da06cf, 0xb363fdc9, 0x804d8810, 0x51072566,
|
|
4608
|
+
0x27b2ebdc, 0x6e698657, 0x93b97901, 0x3932bde7, 0x38e1ca45, 0xf21f8cca, 0x0196e31e, 0x925a9c06, 0x1d208fce,
|
|
4609
|
+
0xb8563b9e, 0xcdcf2661, 0xd7b43040, 0xfa7446d3, 0xf9cbde9d, 0x1123602c, 0xd209c8d7, 0x9ab4230f, 0x72684621,
|
|
4610
|
+
0x6c9c7027, 0xd681e541, 0x2146702b, 0x796f2246, 0x86f7384b, 0xafa7ea2f, 0xe1236995, 0x53a2cc92, 0xc1a80dc0,
|
|
4611
|
+
0xb503082b, 0x14204a1a, 0xb426602f, 0xa350c9b6, 0xcd437f76, 0x52a8d512, 0x3f1886fc, 0x93bc225e, 0x4e1f3852,
|
|
4612
|
+
0x0048f8cd, 0x95879d1a, 0x51b6f0bf, 0x8fce8a01, 0xeb649177, 0x0aaea222, 0x622a0942, 0x6c406ed8, 0xa680c5dd,
|
|
4613
|
+
0x901aadd7, 0x85d2d108, 0xaa9189ae, 0xe7095279, 0xb7e79560, 0xdb9ada84, 0xb4e78b10, 0x7ae66db0, 0xb4ac9bda,
|
|
4614
|
+
0x670d5cb3, 0xa790f4d3, 0xfe518481, 0xbbd4b00b, 0x4643d478, 0xeb50c1e4, 0x4211bbe1, 0x26f6b362, 0xe1612a64,
|
|
4615
|
+
0x2b34bb2d, 0x0454abc3, 0x59be22f0, 0x68393d08, 0x861cacd8, 0x42c99ebd, 0xcf4fd5ed, 0x3c290a8b, 0x353eb82d,
|
|
4616
|
+
0x06cca9ee, 0xbf45cdcf, 0x85784848, 0x4c13d5f6, 0xdca3523e, 0xb1e06349, 0x3e8927db, 0xea2db564, 0xe798e878,
|
|
4617
|
+
0x4cd15d96, 0xc8517abd, 0x0926b612, 0xc0bff33e, 0x4163046c, 0x5d588d96, 0x3135fa4e, 0xa14a91fa, 0xeb005001,
|
|
4618
|
+
0x5231d8d2, 0x193d4a10, 0xd0d0906e, 0xc3080e9b, 0xfda05e42, 0x8782007b, 0xea3c596e, 0xfce90f7b, 0x5b7d3fa9,
|
|
4619
|
+
0x6cb55e6b, 0xe6ddf73e, 0xaf919c0b, 0xb256f0e9, 0x774c30d2, 0xf102fce9, 0x36d9c255, 0x4ade9d17, 0xd8ee8707,
|
|
4620
|
+
0x3b3298ba, 0xe306824e, 0x0ea0904c, 0x4147519a, 0x20288602, 0x26b372f0, 0xd0981eac, 0xa785ebc8, 0xa9d4a7ca,
|
|
4621
|
+
0xdbdf58e9, 0xd953c50d, 0xfd590f8f, 0x9d6361cc, 0x44e6c917, 0x72e9626b, 0x22eb64cf, 0x7fd96110, 0x9eb288f3,
|
|
4622
|
+
0x863ebb7e, 0xb0e63d34, 0x4fe7ee31, 0xa9e54fab, 0xf4600572, 0xd5e7b5a4, 0xc0493334, 0x06d54831, 0x8589fb92,
|
|
4623
|
+
0x6583553a, 0xaa70f5cc, 0xe25649e5, 0x0879094a, 0x10044652, 0xcc904507, 0x02541c4f, 0xebb0696d, 0x3b89da99,
|
|
4624
|
+
0xabbaa0c0, 0xb8284022, 0xa6f2d79e, 0xb81c05e8, 0x27847862, 0x05e54d63, 0x337a4b59, 0x21f7794a, 0x3c67500d,
|
|
4625
|
+
0x7d6d7f61, 0x207005b7, 0x04cfd6e8, 0x0a5a3781, 0xf4c2fbd6, 0x0d65e0d5, 0x6d3549cf, 0xd433e50f, 0xfacd665e,
|
|
4626
|
+
0x6f33696f, 0xce11fcb4, 0x695bfdac, 0xaf7c9860, 0x810ee252, 0x7159bb2c, 0x65450fe1, 0x758b357b, 0xf7dfbebe,
|
|
4627
|
+
0xd69fea72, 0x2b057e74, 0x92731745, 0xd485717a, 0xe83f7669, 0xce1f69bb, 0x72877d6b, 0x09f8ae82, 0x3244278d,
|
|
4628
|
+
0x9548ae54, 0xe3c2c19c, 0x207755de, 0x6fef1945, 0x87bd61d9, 0xb12d28c3, 0x18813cef, 0x72df64aa, 0x9fbcd1d6,
|
|
4629
|
+
0x7154b00d, 0x48dc5ee5, 0xf49a3154, 0xef0f469e, 0x6e2b2e9a, 0x3e85a595, 0xaa924a9c, 0x45aaec1e, 0xa09e4719,
|
|
4630
|
+
0xaa12dfc8, 0x4df69f1d, 0x26f27227, 0xa2ff5e73, 0xe0e4c82c, 0xb7a9dd44, 0xb9d8ce73, 0xe48ca901, 0x6c036e73,
|
|
4631
|
+
0xa47153f0, 0xe1e421e1, 0x920418c9, 0xb86c3b79, 0x705d7672, 0x93bdce87, 0xcab79a77, 0xf25ae793, 0x6d869d0c,
|
|
4632
|
+
0x1f3194a3, 0x4986c264, 0x9d55c882, 0x096e945e, 0x49fb5ea3, 0x13db0a3e, 0x39b8e653, 0x35d0b34a, 0xe3417bc0,
|
|
4633
|
+
0x8327c0a7, 0x440b386b, 0xac0362d1, 0x8fb7262d, 0xe0cdf943, 0x2c41114c, 0xad95a0b1, 0x2ba5cef1, 0x67d54362,
|
|
4634
|
+
0xc09b37a8, 0x01e486c9, 0x26d6cdd2, 0x42ff9297, 0x20477abf, 0xbc0a67d2, 0x0f121b41, 0x444d248a, 0x62d4760a,
|
|
4635
|
+
0x659b4737, 0x0e044f1d, 0x250bb4a8, 0x08fde365, 0x848bf287, 0xaceec3da, 0xd3369d6e, 0xc2a62182, 0x92449482,
|
|
4636
|
+
0x3582dfdc, 0x565d6cd7, 0x2f7e2fd2, 0x178a876b, 0x0a0122b5, 0x085104b4, 0x51ff96ff, 0x14f29f76, 0x050b31ab,
|
|
4637
|
+
0x5f87d4e6, 0x84abb28b, 0x8270790a, 0xd5ed439f, 0x85e3f46b, 0x2d6cb59d, 0x6c1e2212, 0x75f55c1b, 0x17655640,
|
|
4638
|
+
0xe5436f67, 0x9aeb596d, 0xc2965ecc, 0x023c92b4, 0x01ea03e7, 0x2e013961, 0x4704b4b6, 0x905ea367, 0x0ca8fd3f,
|
|
4639
|
+
0x551b2b61, 0x92523a42, 0x390fcd06, 0x1eb7a89c, 0x0392a63e, 0xe7f1d2be, 0x4ddb0c33, 0x96dca264, 0x15339848,
|
|
4640
|
+
0x231c210e, 0x70778c8d, 0xe87a28e8, 0x6956e170, 0x9d1de661, 0x2bb09c0b, 0x4ac3c938, 0x6998987d, 0x19be0551,
|
|
4641
|
+
0xae09f4d6, 0x8b2376c4, 0x1a3f933d, 0x1de0b765, 0xe39705f4, 0x380d94c7, 0x8c31c31d, 0x3685954b, 0x5bf21a0c,
|
|
4642
|
+
0x68533d00, 0x75c79ec9, 0x0bd7626e, 0x42c69d54, 0xca177547, 0xf6d2dbb2, 0xcc6edaff, 0x174a9d18, 0xfd0d8cbd,
|
|
4643
|
+
0xaa4578e8, 0x875e8793, 0x9cab2ce6, 0xa976a713, 0xb43ea1db, 0xce37ab11, 0x5259d292, 0x0a7ff1a9, 0x8f84f186,
|
|
4644
|
+
0x851b0221, 0xdefaad13, 0xa7222bea, 0x2b0a9144, 0xa2ac78ec, 0xf2fa59c5, 0x5a024051, 0x6147ce38, 0x91d1eca5,
|
|
4645
|
+
0xbc2ac690, 0xbe94d523, 0x79ec1a0f, 0x2d8daefd, 0xceb39c97, 0x3bbcd6fd, 0x58f61a95, 0xf5575ffc, 0xadf7b420,
|
|
4646
|
+
0xdbd986c4, 0x15f39eb7, 0x81aa8814, 0xb98d976c, 0x6ee2fcf5, 0xcf2f717d, 0x5465475d, 0x6860bbd0, 0x8e24d3c4,
|
|
4647
|
+
0x305406dd, 0xe27a6dbe, 0xdd5d1957, 0x8eb7dc7f, 0x387d4d8f, 0xf54a6876, 0xc7762de4, 0x9c479409, 0x99b30778,
|
|
4648
|
+
0xbe4d5b5d, 0x6e793682, 0x25380c56, 0xdac740e3, 0x602d37f3, 0x1566e4ae, 0x140deabe, 0xc8de610b, 0x0f893a5d,
|
|
4649
|
+
0x67e223ce, 0xe8c515fb, 0x4ead6dc5, 0x7774bfa6, 0x925c728f, 0x89d20f95, 0x098583ce, 0x7a1e0966, 0x93f2a7d7,
|
|
4650
|
+
0xa2eedb94, 0x4c304d4a, 0x1b282097, 0xc077282d, 0x0842e3da, 0x357a8313, 0x1aa84db9, 0x190eae46, 0xafb9c0b9,
|
|
4651
|
+
0xcd152e65, 0xca04c15a, 0x86c722db, 0x663285b7, 0x6adfc1a6, 0x2df90ab6, 0x3e5aaa65, 0x2069f55f, 0x110c8419,
|
|
4652
|
+
0x7704d1ca, 0x63ffed41, 0xfab318ca, 0x1402b9d0, 0xd3b3a13f, 0x2c7bc863, 0x573441c3, 0x578c3e6e, 0x4b301ec4,
|
|
4653
|
+
0x0adaf57e, 0xc26fc9c4, 0x7493cea3, 0x96e71bfd, 0x1af81456, 0xd05d4b3f, 0x6a8c608f, 0xdaca2a8a, 0x0725b276,
|
|
4654
|
+
0x53ef07f6, 0x1b785ecb, 0x23813d96, 0x8ffcfcc7, 0x717e8a48, 0x2e499542, 0x4f6c36ed, 0x0bd85af3, 0x9b89def7,
|
|
4655
|
+
0xa5f35549, 0x3d8ea206, 0xc649a220, 0x581385e1, 0x73cc0927, 0x9bf4bec5, 0x534181f1, 0x46395346, 0x53765db9,
|
|
4656
|
+
0x21695501, 0x2c7abc5c, 0x959dae32, 0x86483297, 0x4cea4d18, 0x4cb2284a, 0x48c3bb1b, 0xe49cb14b, 0x050c6c92,
|
|
4657
|
+
0xb704e555, 0x21e13bb2, 0x010006ee, 0x4c773b15, 0x5d8c87bf, 0x93991029, 0xb46694f9, 0x48aa81d2, 0x38b6e59f,
|
|
4658
|
+
0x0489dd73, 0x84b66165, 0x69281246, 0xebcf0593, 0xa72497ac, 0x21eeac14, 0x1b894d0a, 0x5966a835, 0x732236f1,
|
|
4659
|
+
0x974be9d6, 0xc9fcb462, 0x589b6130, 0xd6054385, 0x421d3aa4, 0xc37e2c2e, 0xe84fa840, 0xf926407c, 0x1454e41c,
|
|
4660
|
+
0x18abc03d, 0x3f7af644, 0x26605ecd, 0xd6a5eabf, 0x242341a6, 0x216b668e, 0x1edb84f4, 0x04010102, 0xd836edb8,
|
|
4661
|
+
0x945e1d8c, 0x5b337ce7, 0x444964ac, 0x4616ce55, 0x4211498b, 0x02108fbc, 0x4e546574, 0x1c8df635, 0x076291e7,
|
|
4662
|
+
0xa750080f, 0x99e78281, 0xdc3453f3, 0x4f495dce, 0x0d7779ab, 0x79ffe0cf, 0x49a3f780, 0xa795c128, 0xd78ef100,
|
|
4663
|
+
0x6543dfcc, 0xbd5b3adf, 0x0b4d762e, 0x7c413b51, 0x1bc4bc43, 0xc8ac6f83, 0x8043e8c3, 0x27c2c023, 0x40395a86,
|
|
4664
|
+
0x81250dca, 0x93c28e89, 0xd1293b9d, 0x6030a82b, 0x8d1bfc82, 0xd375db70, 0xece39ba0, 0x971de303, 0x2a61229e,
|
|
4665
|
+
0x215ee719, 0x0635ed2a, 0xbb93abb7, 0xd8e4f713, 0x5a466813, 0x8dfbde1f, 0x0b8a9de6, 0xe474d65a, 0x3b38348b,
|
|
4666
|
+
0x0e244068, 0xf2ce7593, 0xb29657f3, 0x4ec4b667, 0xce6e132e, 0x099044b1, 0x47814783, 0xa428a551, 0xf2b04d68,
|
|
4667
|
+
0x598360d3, 0x72bc9cd5, 0x2450efe5, 0xe6ffceb8, 0x425bca58, 0x5fc778b9, 0x6a6f4fa9, 0x1b6db987, 0x23e3f30d,
|
|
4668
|
+
0xd73215b0, 0x90d9a9bf, 0xefa6c8c8, 0x9bc5ef97, 0xcd275acc, 0x06718440, 0x37874249, 0x2b425efc, 0x01b53e8b,
|
|
4669
|
+
0x48dc354c, 0x63046f6e, 0x6694b583, 0x88523e44, 0xfa5c3397, 0x8d36dd7e, 0x2810af20, 0x4450cf5f, 0x53cd5c0c,
|
|
4670
|
+
0x3258e273, 0xa6a20fc9, 0x406aa1f4, 0xe3905a09, 0xc1dd6791, 0xf9b2fe60, 0x47f74947, 0x48d68f59, 0xdbeaab33,
|
|
4671
|
+
0xd7f12741, 0x177bc077, 0x3b8a0569, 0x1174d109, 0xd96628fe, 0xb154db4b, 0xd3709035, 0x3da0e52c, 0xf66ce755,
|
|
4672
|
+
0x21f7da9b, 0x8034ea56, 0x5088b8b1, 0x938ded46, 0xa5f486ac, 0x70343199, 0x3c9b6dc4, 0xe0f77614, 0x70b9fbff,
|
|
4673
|
+
0xbb422d4b, 0xa686c995, 0x3d759571, 0xa57102b0, 0x67d5e8cd, 0xc0dcc16a, 0x533ef217, 0x889f6d65, 0xc3ca2e87,
|
|
4674
|
+
0x7158c7e4, 0xdc2b4167, 0xfb670dfb, 0x844c257f, 0x75910a01, 0xcf88577d, 0xf336bf07, 0xe45e2ace, 0x22245250,
|
|
4675
|
+
0x7ca23d85, 0x2ed92e8d, 0x2b812f58, 0x29f8be4c, 0xcf7d62d2, 0x20d3c982, 0x23ba8150, 0x1f36e29d, 0x92763f9e,
|
|
4676
|
+
0x48ae0bf0, 0x1d3a7007, 0x7a527e6b, 0x581a85e3, 0xb4a89097, 0xdc158be5, 0x1f1a520f, 0x167d726e, 0xf98db37d,
|
|
4677
|
+
0x1113e862, 0x8802786e, 0x7ae72ce5, 0x75946aba, 0x04ebd226, 0x2e858934, 0xe3de94b5, 0x8580d4c9, 0x3d0683fa,
|
|
4678
|
+
0x3f521c44, 0x28c498be, 0xd800901a, 0x1b48cb90, 0x8471501f, 0x5bc58e57, 0xee87be3a, 0xfe27fa60, 0xe1123f25,
|
|
4679
|
+
0x9db3b381, 0x263a2cfb, 0xd4df0a4b, 0x9c3a2dee, 0x7d04e61f, 0x728d06e9, 0x42449325, 0x8b1adfbc, 0x7e053a1b,
|
|
4680
|
+
0x6ec1d939, 0x66daf707, 0xee2be5c7, 0x810ac7ab, 0x80ba1e14, 0xf530f174, 0xdd2ae778, 0xa464269c, 0xa4ed05fb,
|
|
4681
|
+
0x5cd2fe8b, 0x5abc28f9, 0x11a40934, 0xb3aafa22, 0xd7f35379, 0x46021d4c, 0x290777d9, 0x5771a3c2, 0x41f32772,
|
|
4682
|
+
0xb7f853de, 0xd95603f3, 0x2e348157, 0x466bbf67, 0x076f0831, 0xa297c1e5, 0x9bc7ccb1, 0x82975b7a, 0x5fac57c3,
|
|
4683
|
+
0x97648feb, 0x558880ac, 0x9306c2c3, 0xc30bd923, 0xce9835e4, 0xb4cd6bf1, 0x0ce56507, 0xd52dba58, 0xbe313df1,
|
|
4684
|
+
0x2d392c90, 0x84ceaed7, 0x4205a23e, 0x7a2dbfd7, 0x815a816b, 0x3e1e1979, 0x12809e55, 0x9c51467b, 0x4ff5ce0c,
|
|
4685
|
+
0xee996d98, 0xed5f815a, 0x0bd3db01, 0xd2e1399d, 0x7a816e68, 0x7afad0d4, 0x0b4c03db, 0x37f8db9d, 0x1c59ef24,
|
|
4686
|
+
0xd13a1cf8, 0xf23f2d92, 0x91213462, 0x60b94078, 0x6cab71bd, 0x176cde20, 0x6bdd0a63, 0xee4d54bc, 0x54c9b20c,
|
|
4687
|
+
0x9f2ac02f, 0x3cd2d8aa, 0x206eedb0, 0x03f8e617, 0x93086434, 0xc7f68e16, 0x92dd3db9, 0x831469c5, 0x936972d9,
|
|
4688
|
+
0x7e9efe70, 0x995a53e2, 0x4e209c82, 0x073e197b, 0xa955eefd, 0x9891ce26, 0x5405809c, 0x3b9fe6c3, 0xff437391,
|
|
4689
|
+
0x03ffb90e, 0xac2b12df, 0xd3f181d9, 0x09c7fd78, 0x327b97e0, 0xd5e14041, 0x1f6418f0, 0x254c673c, 0xc1cd6ec9,
|
|
4690
|
+
0x09351454, 0x1bcabe39, 0x62ce468e, 0x3a9bb28c, 0x0b40d8d4, 0x47e9f69d, 0x24bb9cdc, 0xf5fe0edc, 0x5e64766f,
|
|
4691
|
+
0xf913b301, 0x6bfc2b14, 0x625c3c70, 0x794031aa, 0x75678d7f, 0xa475d0cc, 0xaf2a70da, 0xdbd9850e, 0x1875bf36,
|
|
4692
|
+
0xdb46ef63, 0x751267fa, 0xdd0b61f5, 0xa0b0bb30, 0x05482087, 0xd5fbe9cb, 0x9cfe299d, 0x1b60814d, 0x6a178109,
|
|
4693
|
+
0xcb28431c, 0xf39be4af, 0x377e29a2, 0xf454152c, 0xdd555915, 0x0c33b51f, 0xe3bc8be9, 0x6855b7c1, 0x022e58f8,
|
|
4694
|
+
0xbbbb9bb5, 0x01ab2647, 0xce0bc1bb, 0xb6256d5a, 0x687783c8, 0xb0ca484c, 0xe4d74b53, 0xf65384f0, 0xb8fb733d,
|
|
4695
|
+
0xfdad739a, 0xaf1b1b07, 0xb5c7b972, 0xc147dfcb, 0xdf03e036, 0xc4647be5, 0x0019e846, 0xd3b5539c, 0x1239986e,
|
|
4696
|
+
0x3fcd6682, 0xbaf1b385, 0xd15a29d3, 0x35388a04, 0x28f55ca8, 0xf721fa09, 0xac1bb660, 0xc4260ce8, 0x05135b99,
|
|
4697
|
+
0x763bde32, 0xd2164b80, 0xa379ad75, 0xf233dced, 0x0ee47c9d, 0xeed33628, 0xc90572b3, 0x58ab955e, 0x7743229b,
|
|
4698
|
+
0xf4ad58c5, 0x98b678f7, 0xe16c6d44, 0x10fc036a, 0xc9b66513, 0xb2630de5, 0xbfca3418, 0x86980a16, 0xdb52a230,
|
|
4699
|
+
0x128dd83a, 0x732a1969, 0xb3f0c36e, 0x38193f06, 0xa449a0ef, 0xdef6b620, 0x69f5de63, 0xf2aa5615, 0x77945df2,
|
|
4700
|
+
0x87325c3c, 0x30e90c8d, 0xe0889276, 0x5922ac1c, 0x8df27545, 0xa52b3f63, 0xa7b3ef5c, 0x71de57c4, 0x8e77b214,
|
|
4701
|
+
0x834c008b, 0x31682c10, 0x4bd55d31, 0xc76824f0, 0x17b61c71, 0xb6d1c086, 0xc2a5089d, 0x31db0903, 0x184e5d3f,
|
|
4702
|
+
0x9c092172, 0x453cadd6, 0x8de2b7bc, 0xbc0bc1f8, 0x203900a7, 0xa6abd3af, 0xbcd86e47, 0x8502effb, 0x911cac12,
|
|
4703
|
+
0xec965469, 0x2d550242, 0x29e0017e, 0x0e9f7692, 0x65979885, 0x633f078f, 0x4cf751ef, 0xfb87d449, 0xda601f87,
|
|
4704
|
+
0x1cf2c450, 0x8f35b741, 0xeb9112f3, 0x5342813b, 0x8eb7a397, 0x1983d1c1, 0x8f80681e, 0x6758b38d, 0x6b128d2f,
|
|
4705
|
+
0xd0749ebe, 0x407f0f50, 0xea3fe0f3, 0x1b5ac2ed, 0xd8f81007, 0x05d9bcd4, 0x070d3aab, 0xe4ac8b33, 0x9a2cd5e5,
|
|
4706
|
+
0x2643672b, 0x1cfc9173, 0x52eff79b, 0x90a7c13f, 0x665ca49b, 0xb3efb998, 0x5a8dda59, 0x052f1341, 0x8a5b922d,
|
|
4707
|
+
0x3cf9a530, 0xae9ebbab, 0xf56da4d7, 0x35986e7b, 0x03446584, 0xac953951, 0x2de63038, 0x76a360ee, 0x51b2d92c,
|
|
4708
|
+
0xd6c1a0b0, 0xfe2f44bf, 0x57acc823, 0x2d3f3948, 0x9282a5de, 0xad531d9b, 0x91650935, 0xc133f48e, 0x277215fb,
|
|
4709
|
+
0x3a8ef534, 0xd06d383d, 0x6bc05381, 0x5e1e63ab, 0xd2747232, 0x92f01d1d, 0x65835dcc, 0x3fbfd9d3, 0x32cf0dc6,
|
|
4710
|
+
0x3a98901b, 0xbbf6b9ca, 0xf0b4a3d9, 0x2ddc3857, 0xda4e0901, 0xab60d025, 0xbd900e10, 0xdd19e8db, 0x53a1c135,
|
|
4711
|
+
0x6ea9f893, 0xbfe8fa00, 0xc6b72f04, 0x9b55e257, 0x957d1650, 0xff0fc327, 0x6c58e7b6, 0x4b0682c1, 0x110f9185,
|
|
4712
|
+
0xf35913e8, 0x4bbf3021, 0x1b1c1291, 0x5d433891, 0xeea4ea79, 0xf6f0f46d, 0x755d5dcd, 0x1e84e0e5, 0x19686041,
|
|
4713
|
+
0xaea34c93, 0xa5db84d3, 0x7073a732, 0xf9d5bb19, 0x6bcfd7c0, 0xb8d2fe56, 0xf3eb82fa, 0x45775f36, 0xfdff8b58,
|
|
4714
|
+
0x8cb20ccc, 0x8374c110, 0x1659b65f, 0x330c789a, 0xb8b4a422, 0x7ae592b8, 0xb2546617, 0xa0f4a9f2, 0xb2339c4a,
|
|
4715
|
+
0x79f8eae0, 0xfc5c2cf5, 0xece3ea1e, 0xd8bc8a1e, 0xcf9c747e, 0x2aa33aa5, 0x05fa10ee, 0x964f89d2, 0x0d7b8a0b,
|
|
4716
|
+
0x7e35fea3, 0x109bfe16, 0xfcc41672, 0x0c3a1577, 0x290ab802, 0x29c4d040, 0xf6374449, 0xc35d1594, 0xcad607d9,
|
|
4717
|
+
0x2ee3e88f, 0xae0d4c9a, 0x1d265b5a, 0xdb92494a, 0x29831ff8, 0xdc537351, 0xb3b69b02, 0xdc8f2b05, 0xe2928a67,
|
|
4718
|
+
0x495078df, 0x38d66c99, 0x8699baeb, 0x7d9e403d, 0x969b4663, 0x84ed304b, 0x980893fd, 0xa1938458, 0x6ed55320,
|
|
4719
|
+
0x513e63cb, 0x24b215dd, 0xf5fe1ae7, 0x05bdea1b, 0x2ce1a04f, 0xba2f9253, 0x0d7fb3c9, 0x7b955561, 0x1bea4a7d,
|
|
4720
|
+
0x1481da4d, 0xf384b29f, 0xf4fcd517, 0x55cff503, 0xf19c2016, 0x06c4df04, 0x108ac09f, 0xe90fb297, 0xefdff4ee,
|
|
4721
|
+
0xf933c12c, 0x1d8d5045, 0xcb7ef8b8, 0x975d95f5, 0xd7d604f1, 0xb4094013, 0x4bb808d6, 0x239e5f16, 0x73f42cbb,
|
|
4722
|
+
0xf9584ddb, 0x4a2902d6, 0xbde41ad6, 0xeb95cc88, 0x37dd6e2a, 0x0c72cda8, 0xd3c6ea82, 0x43d6f957, 0x7d3ab4fe,
|
|
4723
|
+
0x13d3e8e1, 0x57fd66d3, 0x2415a3d6, 0x0f4e43d1, 0xafa218cf, 0xcbc9f257, 0x8e2a4e0c, 0x3972ecb2, 0x4f76e5fa,
|
|
4724
|
+
0x7c518a58, 0x1c4e11e1, 0x583ebd0b, 0x41bfb22b, 0x26f11dd0, 0xa0ddfa83, 0x613606b1, 0x639bcf14, 0xdf9496dd,
|
|
4725
|
+
0x4e88fdae, 0xeeed36ec, 0x069604f6, 0xcedd1607, 0x39217fea, 0xde6ce26b, 0xb64d18a9, 0xf150a29f, 0x68500f4d,
|
|
4726
|
+
0x6d37083d, 0xc54f2959, 0x274a4806, 0x9af51cfb, 0x62a200de, 0x19605d08, 0xce82e5ae, 0x45887f4a, 0x819dc06d,
|
|
4727
|
+
0x0a750c0f, 0xcc7a6488, 0x4e548e83, 0x39bacfe3, 0x0c110f05, 0x3d418c76, 0xb1f11588, 0x3e4daa4c, 0x5ffc69ff,
|
|
4728
|
+
0x2733e7b5, 0x92053127, 0x46f147bc, 0xd722df94, 0x885b2434, 0xe6fc6b7c, 0x6a444f65, 0xc360e25a, 0x8ce9b6bf,
|
|
4729
|
+
0x075a1a78, 0xe6425195, 0x481732f4, 0x9dc756a8, 0x5432b57a, 0x83c0440f, 0xd720281f, 0xc670b3f1, 0xd135e051,
|
|
4730
|
+
0x2205910e, 0xdb052be7, 0xded14b0e, 0xc568ea39, 0x697b3d27, 0xb7881c8b, 0x4516b5b8, 0x9a5825b4, 0xcfe743c6,
|
|
4731
|
+
0xc24e3024, 0x3d5b8b06, 0xcf8c9326, 0x31c1a413, 0xb632ae3b, 0x5e6eee84, 0x2bd48b14, 0xdfb7eb6b, 0x9a7261e9,
|
|
4732
|
+
0x6a651529, 0xaa69133c, 0x996b358d, 0x979f3925, 0xb81d783e, 0xaf4c89a7, 0x1efd130a, 0xfd1bf7fa, 0x525c2144,
|
|
4733
|
+
0x1b265a9e, 0x4b296904, 0xb9db65b6, 0xed8e9634, 0x03599d8a, 0x35c82e32, 0x403563f3, 0xdaa7a54f, 0x022c38ab,
|
|
4734
|
+
0x9df088ad, 0x7025aa01, 0x396b8d04, 0xe23e9595, 0xa98b2ce9, 0x20bb29f4, 0x9769e7c8, 0x201a51a5, 0x23778ebb,
|
|
4735
|
+
0xa9b810a4, 0x653ff433, 0x66f269a7, 0x017773dc, 0x129ae800, 0xbce2ae82, 0x51317d6b, 0x32345151, 0xf67a99fa,
|
|
4736
|
+
0x39a3bd51, 0xba72c87f, 0x63441f7c, 0x745125ca, 0xcc3fc76f, 0x9c686d78, 0x670e00c6, 0xa0277d6d, 0xa35c29f9,
|
|
4737
|
+
0x3e443178, 0x078badcf, 0x5d1c6e16, 0x1ca01d3f, 0xfc8934cf, 0x23751c99, 0xec245c99, 0x907c4f80, 0x16273128,
|
|
4738
|
+
0xa8943d33, 0x2e233ae1, 0x8984e2cb, 0x794c6256, 0x655a4dda, 0xee6e1497, 0x88e95ce7, 0x129d3376, 0x977f927f,
|
|
4739
|
+
0x568a3ff3, 0x2758787a, 0xdc3cbce1, 0x0bdf684f, 0x1f095615, 0x1083e2ea, 0x14e68c33, 0x0a28ad77, 0x3d8818be,
|
|
4740
|
+
0x6bfc0252, 0xf35850cd, 0xb585113a, 0x30df8aa1, 0x7d935f0b, 0x4ab7e3ac, 0xaddda07c, 0x552f00cb, 0x92c34299,
|
|
4741
|
+
0x2909df6c, 0xc33ed1de, 0x10fb29b2, 0x222c4a8a, 0x30b7eb36, 0x55086586, 0x1ee898a1, 0x22d15c09, 0x854090de,
|
|
4742
|
+
0xb4a70d45, 0x6f61fbdc, 0x3be7a389, 0xfd3348c4, 0xa7d262af, 0xe66d5552, 0x9682ec29, 0x14cbb8d6, 0x5ef177ea,
|
|
4743
|
+
0x7eafb650, 0x3067f793, 0x3bf2a0cb, 0xe37dfbf4, 0x8c3ac824, 0xe6b8e19a, 0xa05e8b4b, 0x8c4930bf, 0x45cdb7bc,
|
|
4744
|
+
0xd6912676, 0x05ea892c, 0xcebdce57, 0x8015170f, 0xf00c5403, 0x7b65a3e5, 0x2e12dfcc, 0x6c5f67d0, 0x9bdfc7a9,
|
|
4745
|
+
0x986471a7, 0x64a44be0, 0xb721aca9, 0x7f12c705, 0xd760d701, 0xcc2f523c, 0xb46febf2, 0x49bb9288, 0x375964e6,
|
|
4746
|
+
0x6a207099, 0x0420792f, 0x6ca4a499, 0x38bca9e8, 0x2188c12d, 0x8ee50f1e, 0x3857f5c4, 0x09a578e4, 0xf8f801d2,
|
|
4747
|
+
0xf20f170e, 0xbe6c89fd, 0xabcf2fa9, 0x5ba08b2f, 0x486f3cfc, 0x86803b77, 0x9cf883ea, 0x846a92f7, 0x474feb56,
|
|
4748
|
+
0xbfb52676, 0xd252161a, 0x483127b0, 0x6a658c2b, 0x18288cfe, 0x0b3d9e91, 0xe9eaef2d, 0x9ae474f2, 0x58f2023f,
|
|
4749
|
+
0xbcf34170, 0x0bdae4b1, 0xb1861d12, 0x9b725d7b, 0x0b4725bb, 0x2bc04f74, 0xd2aefc19, 0xd9fe2c7c, 0x610b818e,
|
|
4750
|
+
0x5e985bb6, 0xb4998e4b, 0x58b1117c, 0xee2b2e32, 0xa2ccc539, 0x127f3f60, 0x5d1033e8, 0xbbc4b91d, 0x6958923b,
|
|
4751
|
+
0x70aa136d, 0xa077a0cf, 0x641bbf55, 0xd2fa8875, 0x32837130, 0x74d271aa, 0x33c1d7bf, 0xfe89c100, 0x32237e81,
|
|
4752
|
+
0x8de08805, 0x874dfaee, 0xf43684ec, 0x88bef633, 0xfdba26b9, 0x5d2a9c91, 0xac299404, 0xa96659e1, 0xeea6a5a0,
|
|
4753
|
+
0xd25ec31a, 0xe74a555d, 0xd7d5a482, 0x8663b8f1, 0x1b5845e4, 0x50b490d7, 0xceca9754, 0x83f49167, 0x4b7939a0,
|
|
4754
|
+
0x426d2cf6, 0x723fd0bf, 0x2555e355, 0xc4f144e2, 0xa96e6d06, 0x87880e61, 0x4768a8dd, 0xe508e4d5, 0x15543815,
|
|
4755
|
+
0xb1b65e15, 0x09d7e772, 0xac302fa0, 0x63439dd6, 0x711b0eb9, 0x96892c1f, 0x780ab954, 0xb905f2c8, 0xa20792db,
|
|
4756
|
+
0xace26309, 0x0684e126, 0xec8ac9b3, 0xb40a2447, 0x486ad8b6, 0x9fe3fb24, 0x60121fc1, 0x1a8e3b3f, 0x5626fccf,
|
|
4757
|
+
0x6ad1f394, 0x4e568622, 0x4393d2d6, 0xa1d7ba8d, 0x13408e94, 0x3f7d2593, 0xba7172f3, 0x3a6e7375, 0xfb20d9cc,
|
|
4758
|
+
0x95ba7341, 0x3726c5da, 0xf6656d08, 0x2e35af89, 0x79d48136, 0xfc71f1fe, 0xc0fa32d5, 0x7bcf2b24, 0x721925c9,
|
|
4759
|
+
0xe1337c26, 0x949c9976, 0xd73d68e5, 0x6faadebd, 0xf1b768d9, 0x9e158614, 0x9cc4f069, 0x22dfa557, 0xbe93c6d6,
|
|
4760
|
+
0xccd6da17, 0xa504f5b9, 0x24866c61, 0x8d694da1, 0x2121353c, 0x0140b8c6, 0x1c6ca580, 0xdd4d8c5b, 0x28936e2b,
|
|
4761
|
+
0xe9056535, 0x613925af, 0x6975bb30, 0x7e293447, 0x0c40bba4, 0x46c390f0, 0x1fda5cbb, 0x04df3cab, 0x9f6fb520,
|
|
4762
|
+
0x3a49e708, 0xe54a5dcf, 0x87e918f0, 0x2e7ee120, 0x6d55293c, 0x84ddc20b, 0x23c7bddf, 0x15a6415f, 0xd589bb14,
|
|
4763
|
+
0xd4622bb6, 0x9f773481, 0xfe400cc6, 0x1755547a, 0x97c77fe8, 0xfcdbcc9d, 0x94bb513c, 0x95cdc2b5, 0x434a335d,
|
|
4764
|
+
0xec3dfb65, 0xe3414909, 0x24eb954e, 0x14cf8dfd, 0x04652209, 0x8f1221a2, 0x28248c1d, 0x50c374dc, 0xa8549a3a,
|
|
4765
|
+
0x4822be54, 0xbf262258, 0x64309efd, 0x7666f41b, 0x5fd7cb3f, 0xa3bc7210, 0x817cf611, 0xce7714a7, 0x534f2cc1,
|
|
4766
|
+
0x5065639d, 0x2f41deff, 0x02b37a95, 0xe63b89b7, 0x0e44a59a, 0x143ff951, 0x673257dc, 0xd752baf4, 0x19c02205,
|
|
4767
|
+
0xc4b7d692, 0x46c23069, 0xfd1502ac, 0x2e6392c3, 0x1b220846, 0x6057b1a2, 0x0c1b5b63, 0xe51ff946, 0x96096717,
|
|
4768
|
+
0x81a628b1, 0x33149d8a, 0x2cd684be, 0xfc179122, 0x10e66a80, 0x91d1288c, 0x95bb287b, 0xc37f1929, 0x06e6cc2c,
|
|
4769
|
+
0x38ad06a9, 0x2afcc2ac, 0xac25cf5b, 0xb0f23450, 0x08b14d82, 0x8f8c414a, 0xaa1849e3, 0xed9cd03e, 0xb6f6e8f2,
|
|
4770
|
+
0xf2096239, 0xbc9c36be, 0xb0163f44, 0x333bb554, 0x66046c85, 0x680b3535, 0xec38f9ef, 0x9b758441, 0x3621c296,
|
|
4771
|
+
0xb1932627, 0xeda1428e, 0x76ef8b71, 0x41f5991b, 0x987e7bdf, 0x61b12191, 0xf154291f, 0x18638b25, 0x34bdaf82,
|
|
4772
|
+
0x983bb560, 0x947df6be, 0xc302a841, 0x94cc4093, 0xa81b53bf, 0x69be22e1, 0x1b570e8f, 0x633a3237, 0xd6c9efcb,
|
|
4773
|
+
0x471886bf, 0xbc946cf9, 0x2c419439, 0xe972082a, 0x9d835424, 0xb3250c55, 0x8653c55d, 0x555a5847, 0x66179cf7,
|
|
4774
|
+
0x6bb2590e, 0xc085d34f, 0xc9f81b3f, 0x11823da3, 0xab4b43e4, 0x49426f48, 0x1445ebd7, 0x7c831d9c, 0xfbe589d3,
|
|
4775
|
+
0x4c4cfb03, 0x47dcd3cf, 0x376ba82d, 0x2cfd4f5c, 0x1cffa8aa, 0xc3850d69, 0x946094c6, 0xe3473018, 0x8caed6bb,
|
|
4776
|
+
0x467f8bfb, 0x0fd87db7, 0x328ba71e, 0x088e5c74, 0x12c17fdd, 0x5097fcf4, 0x7bac7071, 0x3a58d915, 0x24a5d347,
|
|
4777
|
+
0xf071cb4c, 0x25f6eae5, 0x6580e9f9, 0xf05d4e5c, 0x42e9dcec, 0xb32d0317, 0xd36548dc, 0xb75ac9ff, 0xd47267b9,
|
|
4778
|
+
0xa21c8626, 0x33809d3b, 0x188aa85e, 0x5b450c67, 0xb4cd36ac, 0x8eb85241, 0xf0b18c63, 0x4df2cf69, 0x95bbaa9c,
|
|
4779
|
+
0x70932b57, 0xc77b5fbb, 0x20c41b9c, 0x7db752b8, 0xf2a403de, 0x0e5dbbfa, 0x818dae4d, 0xdcf9fa93, 0xc2e6a0a2,
|
|
4780
|
+
0x76cd248a, 0xdbe5fd07, 0xe1899f32, 0x991724f3, 0xc7913e91, 0x39cbd686, 0x5eda799c, 0x63d4fc1e, 0xddb595c7,
|
|
4781
|
+
0xac4fed54, 0x6b63b80b, 0x7e5fb516, 0x6ea0fc69, 0xd0f1c964, 0x737708ba, 0x11a92ca5, 0x9628745f, 0x9a86967a,
|
|
4782
|
+
0x61f37958, 0xd111f8ec, 0x3e0e5c9d, 0xb7c4e760, 0xbcc33f8d, 0xbd392a51, 0x702f9a91, 0xc132e92d, 0x7da4a795,
|
|
4783
|
+
0x0bb1151b, 0x1a0b0ae3, 0x02e32251, 0x54febac8, 0x694e9e78, 0xea3a5082, 0xe4fe40b8, 0xe58ffec1, 0xe842d1a6,
|
|
4784
|
+
0x0eec642e, 0x64a2f5fd, 0xa2fa16b0, 0x404ab431, 0xd68750a4, 0xeec75d66, 0x7f37a9f7, 0x79f9cb9f, 0x3b5c2bb7,
|
|
4785
|
+
0x451b2eb4, 0x27542021, 0x7d91f9d9, 0x902afc37, 0x5f36d153, 0xf23f21bb, 0x4c830320, 0xf3b7963f, 0x903203e3,
|
|
4786
|
+
0x842c7aa0, 0xe7327afb, 0xaf22ca0a, 0x967609b6, 0x38e13092, 0x757558f1, 0x73b8fb62, 0xf7eca8c1, 0x3cc3e831,
|
|
4787
|
+
0xf6331627, 0xe4174474, 0xc3c40234, 0xa77989ca, 0x00bffe1c, 0xf76c7b0b, 0x980a74d8, 0xb059034b, 0xc623a585,
|
|
4788
|
+
0x9a1dccd8, 0xe7bdc815, 0xeab877bc, 0x6e8eb98b, 0xd52de2d1, 0x4a8a0449, 0x8c53e7c2, 0x90ac5a35, 0x842350f3,
|
|
4789
|
+
0x212a67bf, 0x81c4bfee, 0xa73e192c, 0x53972552, 0x1f0ca6e8, 0x69f4df81, 0x6e2c8fb1, 0x904697cb, 0x9270341b,
|
|
4790
|
+
0x92aa39f3, 0x8e5b4d4d, 0x879221ab, 0x4c649efb, 0x3c14cac7, 0x7d407341, 0xfd27ec79, 0x5b4a63b0, 0x34e40452,
|
|
4791
|
+
0x56b1153c, 0xbaff7ab8, 0xf091458f, 0x182a1e56, 0x6d154314, 0x5c14716b, 0x6af64161, 0x355c047a, 0xd38644ab,
|
|
4792
|
+
0xfe472272, 0xe96d671d, 0xced472df, 0x9bba8f32, 0x61e249ac, 0x779c783f, 0x13157fbf, 0xee3c76cb, 0xf306a3c8,
|
|
4793
|
+
0xd32a1f6e, 0x3cf11623, 0x6863e956, 0xe6d5ab64, 0x5c005c26, 0x3b8a4cbe, 0x9ce6bb27, 0xdcd529a5, 0x04d4b16f,
|
|
4794
|
+
0xc4afaa52, 0x7923798d, 0xb0624a26, 0x6b307fab, 0x85e56df6, 0xf5bb45da, 0xa90366c6, 0x278e9bbc, 0x77a1b2e7,
|
|
4795
|
+
0x63d5de5c, 0x45dd322e, 0xcbf7777b, 0xa4e37dfd, 0x5a14ef8c, 0x93bd478e, 0xe05125c2, 0xe050df99, 0xc1e2ceb2,
|
|
4796
|
+
0x13555461, 0xa0c36e1d, 0x609a6070, 0x3907114d, 0xf37c7441, 0xc9df6b9e, 0x6993ef96, 0xa66133ec, 0x554d1256,
|
|
4797
|
+
0x5191fbf4, 0xcb2bcd73, 0x997c7091, 0xa7d78aff, 0x88c02b35, 0x3eedfcb2, 0xd9d20941, 0xfa22b7d6, 0xadf0b394,
|
|
4798
|
+
0x329900fb, 0x99018f13, 0x316bb73b, 0x17fe8f39, 0xdc500d1a, 0xd7c0806d, 0xe24e47f0, 0x137c762c, 0x20b3a8c6,
|
|
4799
|
+
0xb9ecae05, 0x7bb5d1ef, 0x7c5d2188, 0x1475bac9, 0xdf925ba2, 0xa437c526, 0x0e0398c0, 0xa209d49f, 0x7abaf98d,
|
|
4800
|
+
0x8e9c0a08, 0xfcaa77d6, 0xe5a5e63d, 0xc1a1f2cd, 0xadffa60b, 0xe699bc00, 0xc203ff10, 0xd1d2c3ca, 0xdde415fa,
|
|
4801
|
+
0x5acde66d, 0xf8bcc894, 0x4b7f7c01, 0x61775299, 0x339237bf, 0xaeceafdd, 0x9b386840, 0xd9c97d6f, 0x278cd0d5,
|
|
4802
|
+
0xf32af5dc, 0x287758a9, 0xbb6ec813, 0x541fe8e4, 0xa7090edd, 0xda2423c6, 0x4a5d9a2a, 0x374e6332, 0xd6e6b0ea,
|
|
4803
|
+
0xa04d6c11, 0x07d2b7b0, 0xd10ec7fe, 0xc79830dc, 0x6a94a09d, 0xe182e8e3, 0x25fac77c, 0xba4495d2, 0xce5e1418,
|
|
4804
|
+
0x402f6c06, 0x35a6bf4d, 0x477ff713, 0x575c625b, 0x260626e7, 0x4ff9d23e, 0x23dcff1f, 0xdfffb03c, 0xe737742e,
|
|
4805
|
+
0x7ed6aea1, 0xdd3d4640, 0x00e29b03, 0xde4cf2be, 0x5bf6b853, 0xdc38c4e3, 0x62b93d98, 0x4af556a8, 0xa4e5db9d,
|
|
4806
|
+
0x493f4823, 0xc3fcc6cc, 0x4bf133b6, 0xbcd26660, 0xb83ecd49, 0xf9b56b20, 0x313c78b6, 0x1715e3b2, 0x92c4010e,
|
|
4807
|
+
0x6424c49b, 0x646f9679, 0x67c241c9, 0xf888dfe8, 0x24f68b49, 0xe12d4b93, 0xa571df20, 0x9a6b62d8, 0x179483cb,
|
|
4808
|
+
0x81b4b26d, 0x9511fae2, 0x666f9632, 0xd53aa51f, 0xd281b3e4, 0x7f3dbd16, 0x7f96a765, 0x33f6746c, 0xc7f3a8f8,
|
|
4809
|
+
0xfea990ca, 0x21e46f65, 0xcaddb0a9, 0x915fd5c5, 0x78614555, 0xbd41f016, 0x426ffb58, 0x346f4434, 0x14dbc204,
|
|
4810
|
+
0x80559436, 0x5a969b7f, 0xf3dd20fe, 0xe899a39a, 0x9d59e956, 0x645e1aa1, 0x6261a141, 0xca2b0dde, 0x9b786a86,
|
|
4811
|
+
0x1d40a9b7, 0x2750f85c, 0xf39f5373, 0x45218944, 0x9134d4f0, 0xb81c8c9f, 0xb0f3b721, 0x108507ed, 0x688175d0,
|
|
4812
|
+
0x3571dd21, 0xa7c077e6, 0x5dd64232, 0x53544774, 0x511053e4, 0x3adba2bc, 0x834d0ecc, 0xbae371f5, 0x4215d7f7,
|
|
4813
|
+
0x6c8663bc, 0xfcfd57bf, 0xd6901b1d, 0xded2383d, 0xb5587dc3, 0x3b49fbb4, 0x07625f62, 0xfd44a08d, 0x9de9b762,
|
|
4814
|
+
0x3ee4d65b, 0x5755702b, 0xdec0913d, 0x8e94d5c6, 0x92aaa0d6, 0xdc60b301, 0x14d62bdc, 0xb2c625bf, 0x976d6d25,
|
|
4815
|
+
0x8c916145, 0xf979d8ed, 0xd4981dd6, 0xa22ea58c, 0xa6fbf04b, 0xd6713bf4, 0x4ac44bb6, 0xf3ad5f25, 0xb97c19b5,
|
|
4816
|
+
0xe31f80e3, 0x737fd627, 0xd1c0ef3f, 0xbd9760e0, 0x2c8a9c27, 0x9e5bb884, 0xbc21bb56, 0xa2b3f460, 0x0732c846,
|
|
4817
|
+
0xa7fd5e7f, 0x5ccfa7a2, 0x31a27658, 0x1c2d2e3a, 0x83075a26, 0x7bb0d9da, 0x939f2d90, 0x2dae785f, 0x535b5262,
|
|
4818
|
+
0x929daf96, 0xbea5303b, 0x824116b7, 0x98b9e2b7, 0x84a5d1f7, 0xb8c08a2e, 0xed32931f, 0x56f1f067, 0x51728344,
|
|
4819
|
+
0x61343bd2, 0x0ca144c6, 0x7e6476f2, 0xb41ad322, 0x1ec34f9e, 0x80802dc9, 0x33810603, 0xd8772d35, 0x530cb4f3,
|
|
4820
|
+
0x3f06d66c, 0xc475c129, 0x7be5ed0d, 0x31e82b10, 0xcb9e3c19, 0xc9ff6b4c, 0xc63d2857, 0x92a1b45e, 0xb92118c6,
|
|
4821
|
+
0x7285bbca, 0x0aec4414, 0x9b98f9ca, 0xa371aa4e, 0x70d42e60, 0x77928507, 0xd33cdaf3, 0xadbfe15a, 0xbd19c92a,
|
|
4822
|
+
0x89ab369a, 0x038a7064, 0x5f69e22b, 0xbdc40325, 0x733ff63b, 0xdd46c938, 0x5d011ce5, 0x26688f8f, 0xd6ef09a6,
|
|
4823
|
+
0x6ba112c4, 0x8f527301, 0x6ce9991b, 0x1c7ea712, 0x2c648e27, 0xfae740dc, 0x3f48bb41, 0x8ebe6f02, 0x292d3b22,
|
|
4824
|
+
0x3b65fc6c, 0xd72e5542, 0xa23317b5, 0x77b183a2, 0x22361785, 0x5346f472, 0x38f22b3b, 0x55c125ae, 0x73ef7443,
|
|
4825
|
+
0xf068a26f, 0x82acc836, 0x149d86c1, 0x6e650fc9, 0xc232e9ac, 0xe219f88e, 0xfba90374, 0xf2f21c00, 0x1a7c73e3,
|
|
4826
|
+
0x06d45206, 0xe5c86a4d, 0x4ec902fd, 0xbdf981b3, 0xa419a77c, 0x9e31f690, 0xebe44932, 0x37bf876d, 0xa6e6a433,
|
|
4827
|
+
0x023ece30, 0x36aed0c1, 0xe591214b, 0xe5676428, 0x284f4745, 0x31dba5e8, 0xc8fb96d2, 0x0e63dfd3, 0xbe4add86,
|
|
4828
|
+
0x6fcbb4d8, 0xa8db3b59, 0xa2479e5f, 0x160849af, 0x504dbbaa, 0x3424d98b, 0xec8af847, 0x223c1cb4, 0x563e79b5,
|
|
4829
|
+
0xa96b2820, 0x9ed209af, 0x893a9c43, 0x6923dde3, 0xe2037877, 0x3b3c8f1f, 0x5f5f2512, 0x62a37c04, 0x820d9541,
|
|
4830
|
+
0x0e581f06, 0x7306dd5d, 0xa64feeaf, 0x0dfb0149, 0x615c1d9c, 0x2023145e, 0xe77bdc51, 0xbe1f3d31, 0x4b54803c,
|
|
4831
|
+
0x77ee045f, 0xebe3a0b0, 0x7e35dc63, 0x708c07d9, 0x7ae81483, 0xa4fbfcd6, 0xe7a06617, 0x16a59ce9, 0x96a54b75,
|
|
4832
|
+
0xb6d77a6e, 0xb649d8fd, 0xf5a37e5b, 0x77f5b811, 0xf0f217e7, 0xab4256cb, 0x19567903, 0xa5df4bea, 0xf73d3938,
|
|
4833
|
+
0x1e49b510, 0xb6e71380, 0x3667f456, 0xc83b6447, 0xb59a3670, 0xc464e583,
|
|
4834
|
+
]
|
|
4835
|
+
// gen-p256-table:end
|
|
4836
|
+
|
|
4837
|
+
/** The limbs one comb table entry takes: X and Y, eight each (Z is 1). */
|
|
4838
|
+
const P256_BASE_ENTRY: i32 = 16
|
|
4839
|
+
|
|
4840
|
+
/**
|
|
4841
|
+
* Digit `i` (0 to 63) of the comb: bits `i`, `i + 64`, `i + 128` and
|
|
4842
|
+
* `i + 192` of the 32 big-endian bytes `k`, as bits 0 to 3. The byte and
|
|
4843
|
+
* bit positions are the caller's loop position; the bits only reach `digit`.
|
|
4844
|
+
*/
|
|
4845
|
+
const p256BaseDigit = (k: u8[], i: i32): u32 => {
|
|
4846
|
+
const kLength: i32 = toI32(k.length)
|
|
4847
|
+
let digit: u32 = 0
|
|
4848
|
+
for (let b: i32 = 0; b < 4; b++) {
|
|
4849
|
+
const bit: i32 = i + 64 * b
|
|
4850
|
+
const from: i32 = bit >> 3
|
|
4851
|
+
const at: i32 = 31 - from
|
|
4852
|
+
const byte: u32 = at >= 0 && at < kLength ? toU32(k[at]) : 0
|
|
4853
|
+
digit = digit | (((byte >> toU32(bit & 7)) & 1) << toU32(b))
|
|
4854
|
+
}
|
|
4855
|
+
return digit
|
|
4856
|
+
}
|
|
4857
|
+
|
|
4858
|
+
/**
|
|
4859
|
+
* Entry `digit` of comb sub-table `c` into `out.x` and `out.y`, without
|
|
4860
|
+
* indexing by `digit`: all fifteen entries are read, and `p256TableMove`
|
|
4861
|
+
* keeps entry `j` when `ctEq` says `j` is the digit. A zero digit keeps
|
|
4862
|
+
* none, and leaves `out` (0, 0), which `p256BaseKeep` then discards.
|
|
4863
|
+
*/
|
|
4864
|
+
const p256BaseSelect = (out: P256ProjectivePoint, table: u32[], c: i32, digit: u32): void => {
|
|
4865
|
+
p256SetZero(out.x)
|
|
4866
|
+
p256SetZero(out.y)
|
|
4867
|
+
for (let j: i32 = 1; j < 16; j++) {
|
|
4868
|
+
const hit: u32 = ctEq(toU32(j), digit) & 1
|
|
4869
|
+
const at: i32 = (c * 15 + j - 1) * P256_BASE_ENTRY
|
|
4870
|
+
p256TableMove(out.x, table, at, hit)
|
|
4871
|
+
p256TableMove(out.y, table, at + 8, hit)
|
|
4872
|
+
}
|
|
4873
|
+
}
|
|
4874
|
+
|
|
4875
|
+
/**
|
|
4876
|
+
* `s.sum = p + q` for an affine `q` (its Z taken as 1 and never read), by
|
|
4877
|
+
* Renes, Costello and Batina's Algorithm 5 (complete mixed addition for
|
|
4878
|
+
* a = -3), step for step in the paper's order. Complete for every `p`, the
|
|
4879
|
+
* identity included, and every `q` but the identity, which the comb table
|
|
4880
|
+
* never holds: the caller keeps or discards the sum by the digit.
|
|
4881
|
+
*/
|
|
4882
|
+
const p256PointAddMixed = (p: P256ProjectivePoint, q: P256ProjectivePoint, s: P256PointScratch): void => {
|
|
4883
|
+
const t0: u32[] = s.t0
|
|
4884
|
+
const t1: u32[] = s.t1
|
|
4885
|
+
const t2: u32[] = s.t2
|
|
4886
|
+
const t3: u32[] = s.t3
|
|
4887
|
+
const t4: u32[] = s.t4
|
|
4888
|
+
const x3: u32[] = s.sum.x
|
|
4889
|
+
const y3: u32[] = s.sum.y
|
|
4890
|
+
const z3: u32[] = s.sum.z
|
|
4891
|
+
p256FiatMul(t0, p.x, q.x) // 1
|
|
4892
|
+
p256FiatMul(t1, p.y, q.y)
|
|
4893
|
+
p256FiatAdd(t3, q.x, q.y)
|
|
4894
|
+
p256FiatAdd(t4, p.x, p.y)
|
|
4895
|
+
p256FiatMul(t3, t3, t4) // 5
|
|
4896
|
+
p256FiatAdd(t4, t0, t1)
|
|
4897
|
+
p256FiatSub(t3, t3, t4)
|
|
4898
|
+
p256FiatMul(t4, q.y, p.z)
|
|
4899
|
+
p256FiatAdd(t4, t4, p.y)
|
|
4900
|
+
p256FiatMul(y3, q.x, p.z) // 10
|
|
4901
|
+
p256FiatAdd(y3, y3, p.x)
|
|
4902
|
+
p256FiatMul(z3, s.b, p.z)
|
|
4903
|
+
p256FiatSub(x3, y3, z3)
|
|
4904
|
+
p256FiatAdd(z3, x3, x3)
|
|
4905
|
+
p256FiatAdd(x3, x3, z3) // 15
|
|
4906
|
+
p256FiatSub(z3, t1, x3)
|
|
4907
|
+
p256FiatAdd(x3, t1, x3)
|
|
4908
|
+
p256FiatMul(y3, s.b, y3)
|
|
4909
|
+
p256FiatAdd(t1, p.z, p.z)
|
|
4910
|
+
p256FiatAdd(t2, t1, p.z) // 20
|
|
4911
|
+
p256FiatSub(y3, y3, t2)
|
|
4912
|
+
p256FiatSub(y3, y3, t0)
|
|
4913
|
+
p256FiatAdd(t1, y3, y3)
|
|
4914
|
+
p256FiatAdd(y3, t1, y3)
|
|
4915
|
+
p256FiatAdd(t1, t0, t0) // 25
|
|
4916
|
+
p256FiatAdd(t0, t1, t0)
|
|
4917
|
+
p256FiatSub(t0, t0, t2)
|
|
4918
|
+
p256FiatMul(t1, t4, y3)
|
|
4919
|
+
p256FiatMul(t2, t0, y3)
|
|
4920
|
+
p256FiatMul(y3, x3, z3) // 30
|
|
4921
|
+
p256FiatAdd(y3, y3, t2)
|
|
4922
|
+
p256FiatMul(x3, t3, x3)
|
|
4923
|
+
p256FiatSub(x3, x3, t1)
|
|
4924
|
+
p256FiatMul(z3, t4, z3)
|
|
4925
|
+
p256FiatMul(t1, t3, t0) // 35
|
|
4926
|
+
p256FiatAdd(z3, z3, t1)
|
|
4927
|
+
}
|
|
4928
|
+
|
|
4929
|
+
/** `acc = sum` limb by limb when `digit` is not 0, and `acc` unchanged when it is: fiat's conditional move. */
|
|
4930
|
+
const p256BaseKeep = (acc: u32[], sum: u32[], digit: u32): void => {
|
|
4931
|
+
if (toI32(acc.length) < 8 || toI32(sum.length) < 8) {
|
|
4932
|
+
return
|
|
4933
|
+
}
|
|
4934
|
+
for (let i: i32 = 0; i < 8; i++) {
|
|
4935
|
+
acc[i] = p256FiatCmovznzU32(digit, acc[i], sum[i])
|
|
4936
|
+
}
|
|
4937
|
+
}
|
|
4938
|
+
|
|
4939
|
+
/**
|
|
4940
|
+
* `out = k * G` for 32 big-endian bytes `k`, in constant time, by the comb
|
|
4941
|
+
* described in the module's header: 4 rows from the top down, a doubling
|
|
4942
|
+
* between rows, and in each row one entry of each of the 16 sub-tables, read
|
|
4943
|
+
* by `p256BaseSelect`, added by `p256PointAddMixed` and kept by
|
|
4944
|
+
* `p256BaseKeep`. A zero digit costs what any other does: the scan, the
|
|
4945
|
+
* addition and the move all run, and only the move's mask differs. The same
|
|
4946
|
+
* point as `p256ScalarMult(out, k, G, s)`, which tests/link/crypto_p256_agree
|
|
4947
|
+
* checks bit for bit.
|
|
4948
|
+
*/
|
|
4949
|
+
const p256BaseMult = (out: P256ProjectivePoint, k: u8[], s: P256PointScratch): void => {
|
|
4950
|
+
const table: u32[] = p256BaseTable()
|
|
4951
|
+
p256BaseMultWith(out, k, s, table)
|
|
4952
|
+
}
|
|
4953
|
+
|
|
4954
|
+
/**
|
|
4955
|
+
* `p256BaseMult` in the caller's table (`p256BaseTable()`), so that it
|
|
4956
|
+
* allocates nothing: what `P256SignScratch` signs with. `out` is the
|
|
4957
|
+
* accumulator, overwritten step by step until it holds `k * G`. The entry
|
|
4958
|
+
* selected into `s.entry` follows the scalar's digits, so it is wiped before
|
|
4959
|
+
* this returns, and `s.sum` with the rest of `s` by the caller's
|
|
4960
|
+
* `p256WipeScratch`; the table is a function of G alone, and kept.
|
|
4961
|
+
*/
|
|
4962
|
+
const p256BaseMultWith = (out: P256ProjectivePoint, k: u8[], s: P256PointScratch, table: u32[]): void => {
|
|
4963
|
+
if (toI32(k.length) < 32) {
|
|
4964
|
+
return
|
|
4965
|
+
}
|
|
4966
|
+
p256SetIdentity(out)
|
|
4967
|
+
for (let r: i32 = 3; r >= 0; r--) {
|
|
4968
|
+
if (r < 3) {
|
|
4969
|
+
p256PointDouble(out, out, s)
|
|
4970
|
+
}
|
|
4971
|
+
for (let c: i32 = 0; c < 16; c++) {
|
|
4972
|
+
const digit: u32 = p256BaseDigit(k, r + 4 * c)
|
|
4973
|
+
p256BaseSelect(s.entry, table, c, digit)
|
|
4974
|
+
p256PointAddMixed(out, s.entry, s)
|
|
4975
|
+
p256BaseKeep(out.x, s.sum.x, digit)
|
|
4976
|
+
p256BaseKeep(out.y, s.sum.y, digit)
|
|
4977
|
+
p256BaseKeep(out.z, s.sum.z, digit)
|
|
4978
|
+
}
|
|
4979
|
+
}
|
|
4980
|
+
p256WipePoint(s.entry)
|
|
4981
|
+
}
|
|
4982
|
+
|
|
4085
4983
|
/**
|
|
4086
4984
|
* The affine x of `p` as plain limbs, `X / Z` out of the Montgomery domain,
|
|
4087
4985
|
* which is all ECDSA reads of a point. The identity has no affine form; its Z
|
|
@@ -4298,7 +5196,6 @@ const p256SignScalar = (priv: u8[], z: u32[]): u8[] => {
|
|
|
4298
5196
|
const dM: u32[] = p256Limbs()
|
|
4299
5197
|
p256LimbsFromBytes(dM, priv, 0)
|
|
4300
5198
|
p256FiatScalarMul(dM, dM, r2)
|
|
4301
|
-
const g: P256ProjectivePoint = p256Generator()
|
|
4302
5199
|
const scratch = new P256PointScratch()
|
|
4303
5200
|
const point = new P256ProjectivePoint()
|
|
4304
5201
|
const x: u32[] = p256Limbs()
|
|
@@ -4310,7 +5207,7 @@ const p256SignScalar = (priv: u8[], z: u32[]): u8[] => {
|
|
|
4310
5207
|
wipe(v)
|
|
4311
5208
|
v = next
|
|
4312
5209
|
if (p256ScalarInRange(v)) {
|
|
4313
|
-
|
|
5210
|
+
p256BaseMult(point, v, scratch)
|
|
4314
5211
|
p256AffineX(x, point)
|
|
4315
5212
|
p256ReduceOnce(r, x, n)
|
|
4316
5213
|
// s = k^-1 (z + r d) mod n. A Montgomery multiply of a plain value by
|
|
@@ -4318,7 +5215,7 @@ const p256SignScalar = (priv: u8[], z: u32[]): u8[] => {
|
|
|
4318
5215
|
// k^-1 are converted: r d and then (z + r d) k^-1 come out plain.
|
|
4319
5216
|
p256LimbsFromBytes(kM, v, 0)
|
|
4320
5217
|
p256FiatScalarMul(kM, kM, r2)
|
|
4321
|
-
|
|
5218
|
+
p256ScalarInverse(kM, kM)
|
|
4322
5219
|
p256FiatScalarMul(s, r, dM)
|
|
4323
5220
|
p256FiatScalarAdd(s, s, z)
|
|
4324
5221
|
p256FiatScalarMul(s, s, kM)
|
|
@@ -4353,16 +5250,22 @@ const p256SignScalar = (priv: u8[], z: u32[]): u8[] => {
|
|
|
4353
5250
|
*/
|
|
4354
5251
|
export const p256PublicKey = (priv: Secret<u8[]>): u8[] | null => expose(priv, p256PublicKeyExposed)
|
|
4355
5252
|
|
|
4356
|
-
/**
|
|
5253
|
+
/**
|
|
5254
|
+
* `p256PublicKey` on the plain key, for `expose` to run: the scratch the key's
|
|
5255
|
+
* digits steered is wiped, and so is the projective point, whose Z they steered
|
|
5256
|
+
* too; only its affine encoding, the public key, is kept.
|
|
5257
|
+
*/
|
|
4357
5258
|
const p256PublicKeyExposed = (priv: u8[]): u8[] | null => {
|
|
4358
5259
|
if (!p256ScalarInRange(priv)) {
|
|
4359
5260
|
return null
|
|
4360
5261
|
}
|
|
4361
5262
|
const point = new P256ProjectivePoint()
|
|
4362
5263
|
const scratch = new P256PointScratch()
|
|
4363
|
-
|
|
5264
|
+
p256BaseMult(point, priv, scratch)
|
|
4364
5265
|
p256WipeScratch(scratch)
|
|
4365
|
-
|
|
5266
|
+
const encoded: u8[] = p256EncodePoint(point)
|
|
5267
|
+
p256WipePoint(point)
|
|
5268
|
+
return encoded
|
|
4366
5269
|
}
|
|
4367
5270
|
|
|
4368
5271
|
/**
|
|
@@ -4461,3 +5364,434 @@ export const p256SignSha256 = (priv: Secret<u8[]>, msg: u8[]): u8[] | null => p2
|
|
|
4461
5364
|
/** `p256Verify` of the SHA-256 of `msg`. */
|
|
4462
5365
|
export const p256VerifySha256 = (pub: u8[], msg: u8[], sig: u8[]): boolean =>
|
|
4463
5366
|
p256Verify(pub, sha256(msg), sig)
|
|
5367
|
+
|
|
5368
|
+
// ---- Signing over caller-owned scratch --------------------------------------
|
|
5369
|
+
//
|
|
5370
|
+
// `p256SignSha256` makes its points, its point scratch and RFC 6979's hashers
|
|
5371
|
+
// with `new`, which stores fresh arrays into their fields, so it stores
|
|
5372
|
+
// allocations of its own: no automatic arena scope and no `using a = arena()`
|
|
5373
|
+
// block may release around it (docs/LANGUAGE.md, "`using a = arena()`",
|
|
5374
|
+
// NL2424), and every signature keeps what it made. `P256SignScratch` holds all
|
|
5375
|
+
// of that, made once, and `p256SignSha256Into` signs in it and writes `r || s`
|
|
5376
|
+
// into the caller's array, inside an arena block of its own: a signature keeps
|
|
5377
|
+
// nothing, and it is byte for byte `p256SignSha256`'s, because RFC 6979 is
|
|
5378
|
+
// deterministic.
|
|
5379
|
+
//
|
|
5380
|
+
// The private key is still read only inside `expose` / `exposeWith`, and a
|
|
5381
|
+
// function `exposeWith` runs may not write the argument it is handed (NL2450),
|
|
5382
|
+
// so the three steps that read the key — the range check, RFC 6979 §3.2 steps
|
|
5383
|
+
// d and f, and `s = k^-1 (z + r d)` — compute on fresh arrays, wipe them, and
|
|
5384
|
+
// answer a value the caller copies into the scratch. That is why the hashing
|
|
5385
|
+
// below is SHA-256 written out over plain arrays (FIPS 180-4) rather than
|
|
5386
|
+
// `Sha256` or `HmacSha256Scratch`: a hasher is an object whose state a step
|
|
5387
|
+
// inside `expose` would have to write. Everything else — the message hash,
|
|
5388
|
+
// steps e, g and h, the nonce's multiple of G and its inverse — runs on the
|
|
5389
|
+
// scratch outside `expose`, on values derived from the key but not the key.
|
|
5390
|
+
|
|
5391
|
+
/** The shift of a word's top byte, typed for `--number-mode f64`. */
|
|
5392
|
+
const P256_WORD_TOP: i32 = 24
|
|
5393
|
+
|
|
5394
|
+
/** RFC 6979 §3.2 steps d and f hash `V || sep || x || h1`: 32 + 1 + 32 + 32 bytes. */
|
|
5395
|
+
const P256_NONCE_MESSAGE: i32 = 97
|
|
5396
|
+
|
|
5397
|
+
/** ROTR^n(x) of FIPS 180-4 §3.2, `0 < n < 32`. */
|
|
5398
|
+
const p256Rotr = (x: u32, n: u32): u32 => (x >>> n) | (x << (32 - n))
|
|
5399
|
+
|
|
5400
|
+
/** The big-endian word at `buf[at .. at + 4)`; the caller has checked the window. */
|
|
5401
|
+
const p256LoadWord = (buf: u8[], at: i32): u32 =>
|
|
5402
|
+
(toU32(buf[at]) << 24) | (toU32(buf[at + 1]) << 16) | (toU32(buf[at + 2]) << 8) | toU32(buf[at + 3])
|
|
5403
|
+
|
|
5404
|
+
/**
|
|
5405
|
+
* FIPS 180-4 §6.2.2 steps 1 to 4 for the block at `src[at .. at + 64)`, folded
|
|
5406
|
+
* into the hash value `h` (8 words) with the schedule `w` (64 words) and the
|
|
5407
|
+
* round constants `kt` (§4.2.2, 64 words), all the caller's.
|
|
5408
|
+
*/
|
|
5409
|
+
const p256ShaCompress = (h: u32[], w: u32[], kt: u32[], src: u8[], at: i32): void => {
|
|
5410
|
+
if (
|
|
5411
|
+
toI32(h.length) >= 8 &&
|
|
5412
|
+
toI32(w.length) >= 64 &&
|
|
5413
|
+
toI32(kt.length) >= 64 &&
|
|
5414
|
+
at >= 0 &&
|
|
5415
|
+
at <= toI32(src.length) - SHA256_BLOCK
|
|
5416
|
+
) {
|
|
5417
|
+
for (let t: i32 = 0; t < 16; t++) {
|
|
5418
|
+
w[t] = p256LoadWord(src, at + 4 * t)
|
|
5419
|
+
}
|
|
5420
|
+
for (let t: i32 = 16; t < 64; t++) {
|
|
5421
|
+
const w2: u32 = w[t - 2]
|
|
5422
|
+
const w15: u32 = w[t - 15]
|
|
5423
|
+
const sigma1: u32 = p256Rotr(w2, 17) ^ p256Rotr(w2, 19) ^ (w2 >>> 10)
|
|
5424
|
+
const sigma0: u32 = p256Rotr(w15, 7) ^ p256Rotr(w15, 18) ^ (w15 >>> 3)
|
|
5425
|
+
w[t] = sigma1 + w[t - 7] + sigma0 + w[t - 16]
|
|
5426
|
+
}
|
|
5427
|
+
let a: u32 = h[0]
|
|
5428
|
+
let b: u32 = h[1]
|
|
5429
|
+
let c: u32 = h[2]
|
|
5430
|
+
let d: u32 = h[3]
|
|
5431
|
+
let e: u32 = h[4]
|
|
5432
|
+
let f: u32 = h[5]
|
|
5433
|
+
let g: u32 = h[6]
|
|
5434
|
+
let hh: u32 = h[7]
|
|
5435
|
+
for (let t: i32 = 0; t < 64; t++) {
|
|
5436
|
+
const bigSigma1: u32 = p256Rotr(e, 6) ^ p256Rotr(e, 11) ^ p256Rotr(e, 25)
|
|
5437
|
+
const choose: u32 = (e & f) ^ (~e & g)
|
|
5438
|
+
const t1: u32 = hh + bigSigma1 + choose + kt[t] + w[t]
|
|
5439
|
+
const bigSigma0: u32 = p256Rotr(a, 2) ^ p256Rotr(a, 13) ^ p256Rotr(a, 22)
|
|
5440
|
+
const majority: u32 = (a & b) ^ (a & c) ^ (b & c)
|
|
5441
|
+
hh = g
|
|
5442
|
+
g = f
|
|
5443
|
+
f = e
|
|
5444
|
+
e = d + t1
|
|
5445
|
+
d = c
|
|
5446
|
+
c = b
|
|
5447
|
+
b = a
|
|
5448
|
+
a = t1 + bigSigma0 + majority
|
|
5449
|
+
}
|
|
5450
|
+
h[0] += a
|
|
5451
|
+
h[1] += b
|
|
5452
|
+
h[2] += c
|
|
5453
|
+
h[3] += d
|
|
5454
|
+
h[4] += e
|
|
5455
|
+
h[5] += f
|
|
5456
|
+
h[6] += g
|
|
5457
|
+
h[7] += hh
|
|
5458
|
+
}
|
|
5459
|
+
}
|
|
5460
|
+
|
|
5461
|
+
/**
|
|
5462
|
+
* The SHA-256 of `data[off .. off + len)` into `out[at .. at + 32)`, on the
|
|
5463
|
+
* caller's hash value `h`, schedule `w` and `tail` (128 bytes, where the last
|
|
5464
|
+
* part block is padded as §5.1.1 says). Whole blocks are compressed where
|
|
5465
|
+
* they lie, so the message is never copied. `out` may be `data`: the digest is
|
|
5466
|
+
* written once every byte has been read. The caller has checked both windows.
|
|
5467
|
+
*/
|
|
5468
|
+
const p256ShaInto = (
|
|
5469
|
+
out: u8[],
|
|
5470
|
+
at: i32,
|
|
5471
|
+
data: u8[],
|
|
5472
|
+
off: i32,
|
|
5473
|
+
len: i32,
|
|
5474
|
+
kt: u32[],
|
|
5475
|
+
h: u32[],
|
|
5476
|
+
w: u32[],
|
|
5477
|
+
tail: u8[]
|
|
5478
|
+
): void => {
|
|
5479
|
+
p256SetLimbs(
|
|
5480
|
+
h,
|
|
5481
|
+
0x6a09e667,
|
|
5482
|
+
0xbb67ae85,
|
|
5483
|
+
0x3c6ef372,
|
|
5484
|
+
0xa54ff53a,
|
|
5485
|
+
0x510e527f,
|
|
5486
|
+
0x9b05688c,
|
|
5487
|
+
0x1f83d9ab,
|
|
5488
|
+
0x5be0cd19
|
|
5489
|
+
)
|
|
5490
|
+
let from: i32 = off
|
|
5491
|
+
while (len - (from - off) >= SHA256_BLOCK) {
|
|
5492
|
+
p256ShaCompress(h, w, kt, data, from)
|
|
5493
|
+
from = from + SHA256_BLOCK
|
|
5494
|
+
}
|
|
5495
|
+
const rest: i32 = len - (from - off)
|
|
5496
|
+
const tailLength: i32 = toI32(tail.length)
|
|
5497
|
+
const dataLength: i32 = toI32(data.length)
|
|
5498
|
+
for (let i: i32 = 0; i < tailLength; i++) {
|
|
5499
|
+
tail[i] = 0
|
|
5500
|
+
}
|
|
5501
|
+
for (let i: i32 = 0; i < rest && i < tailLength && from + i >= 0 && from + i < dataLength; i++) {
|
|
5502
|
+
tail[i] = data[from + i]
|
|
5503
|
+
}
|
|
5504
|
+
if (rest >= 0 && rest < tailLength) {
|
|
5505
|
+
tail[rest] = 0x80
|
|
5506
|
+
}
|
|
5507
|
+
const end: i32 = rest < SHA256_BLOCK - 8 ? SHA256_BLOCK : 2 * SHA256_BLOCK
|
|
5508
|
+
const bits: u64 = toU64(len) << 3
|
|
5509
|
+
for (let i: i32 = 0; i < 8; i++) {
|
|
5510
|
+
const j: i32 = end - 1 - i
|
|
5511
|
+
if (j >= 0 && j < tailLength) {
|
|
5512
|
+
tail[j] = toU8(bits >>> toU64(8 * i))
|
|
5513
|
+
}
|
|
5514
|
+
}
|
|
5515
|
+
p256ShaCompress(h, w, kt, tail, 0)
|
|
5516
|
+
if (end > SHA256_BLOCK) {
|
|
5517
|
+
p256ShaCompress(h, w, kt, tail, SHA256_BLOCK)
|
|
5518
|
+
}
|
|
5519
|
+
const outLength: i32 = toI32(out.length)
|
|
5520
|
+
for (let i: i32 = 0; i < 8 && i < toI32(h.length); i++) {
|
|
5521
|
+
const word: u32 = h[i]
|
|
5522
|
+
for (let b: i32 = 0; b < 4; b++) {
|
|
5523
|
+
const j: i32 = at + 4 * i + b
|
|
5524
|
+
if (j >= 0 && j < outLength) {
|
|
5525
|
+
out[j] = toU8(word >>> toU32(P256_WORD_TOP - 8 * b))
|
|
5526
|
+
}
|
|
5527
|
+
}
|
|
5528
|
+
}
|
|
5529
|
+
}
|
|
5530
|
+
|
|
5531
|
+
/**
|
|
5532
|
+
* HMAC-SHA-256 (RFC 2104) keyed by the 32-byte `key` over `message[0 .. len)`,
|
|
5533
|
+
* into `out[0 .. 32)`: the inner hash of `K XOR ipad || message` in `block`,
|
|
5534
|
+
* its digest put where the outer hash of `K XOR opad || inner` reads it. `out`
|
|
5535
|
+
* may be `key` or `message`, which are read first. Every work array the key
|
|
5536
|
+
* reached — `block`, `h`, `w` and `tail` — is wiped before it returns (ECC-2).
|
|
5537
|
+
*/
|
|
5538
|
+
const p256HmacInto = (
|
|
5539
|
+
out: u8[],
|
|
5540
|
+
key: u8[],
|
|
5541
|
+
message: u8[],
|
|
5542
|
+
len: i32,
|
|
5543
|
+
kt: u32[],
|
|
5544
|
+
h: u32[],
|
|
5545
|
+
w: u32[],
|
|
5546
|
+
tail: u8[],
|
|
5547
|
+
block: u8[]
|
|
5548
|
+
): void => {
|
|
5549
|
+
const blockLength: i32 = toI32(block.length)
|
|
5550
|
+
const keyLength: i32 = toI32(key.length)
|
|
5551
|
+
const messageLength: i32 = toI32(message.length)
|
|
5552
|
+
if (blockLength < SHA256_BLOCK + len || keyLength > SHA256_BLOCK || len > messageLength) {
|
|
5553
|
+
panic("p256HmacInto: a key, message or block outside its bounds")
|
|
5554
|
+
}
|
|
5555
|
+
for (let i: i32 = 0; i < SHA256_BLOCK && i < blockLength; i++) {
|
|
5556
|
+
block[i] = i < keyLength ? key[i] ^ 0x36 : 0x36
|
|
5557
|
+
}
|
|
5558
|
+
for (let i: i32 = 0; i < len && i < messageLength && SHA256_BLOCK + i < blockLength; i++) {
|
|
5559
|
+
block[SHA256_BLOCK + i] = message[i]
|
|
5560
|
+
}
|
|
5561
|
+
p256ShaInto(block, SHA256_BLOCK, block, P256_FROM, SHA256_BLOCK + len, kt, h, w, tail)
|
|
5562
|
+
for (let i: i32 = 0; i < SHA256_BLOCK && i < blockLength; i++) {
|
|
5563
|
+
block[i] = i < keyLength ? key[i] ^ 0x5c : 0x5c
|
|
5564
|
+
}
|
|
5565
|
+
p256ShaInto(out, P256_FROM, block, P256_FROM, SHA256_BLOCK + SHA256_SIZE, kt, h, w, tail)
|
|
5566
|
+
wipe(block)
|
|
5567
|
+
wipe(h)
|
|
5568
|
+
wipe(w)
|
|
5569
|
+
wipe(tail)
|
|
5570
|
+
}
|
|
5571
|
+
|
|
5572
|
+
/** `out[0 .. n) = from[0 .. n)`. */
|
|
5573
|
+
const p256CopyBytes = (out: u8[], from: u8[], n: i32): void => {
|
|
5574
|
+
for (let i: i32 = 0; i < n && i < toI32(out.length) && i < toI32(from.length); i++) {
|
|
5575
|
+
out[i] = from[i]
|
|
5576
|
+
}
|
|
5577
|
+
}
|
|
5578
|
+
|
|
5579
|
+
/** Whether `[at, at + len)` is a window inside an array of `length` elements. */
|
|
5580
|
+
const p256WindowFits = (length: i32, at: i32, len: i32): boolean => at >= 0 && len >= 0 && at <= length - len
|
|
5581
|
+
|
|
5582
|
+
/**
|
|
5583
|
+
* Everything `p256SignSha256Into` signs in, made once and reused: RFC 6979's
|
|
5584
|
+
* `K` and `V`, the hashing's work arrays and round constants, the nonce's
|
|
5585
|
+
* multiple of G with the comb table and point scratch, and the scalars of
|
|
5586
|
+
* the signature. One per signer, not per connection: signing is synchronous,
|
|
5587
|
+
* and every secret it held is wiped before `p256SignSha256Into` returns.
|
|
5588
|
+
*
|
|
5589
|
+
* const scratch = new P256SignScratch(); // once, outside the loop
|
|
5590
|
+
* const sig: u8[] = new Array<u8>(P256_SIGNATURE_SIZE);
|
|
5591
|
+
* const ok: boolean = p256SignSha256Into(scratch, priv, msg, 0, msg.length, sig, 0);
|
|
5592
|
+
*/
|
|
5593
|
+
export class P256SignScratch {
|
|
5594
|
+
/** FIPS 180-4 §4.2.2's round constants. */
|
|
5595
|
+
kt: u32[]
|
|
5596
|
+
/** A SHA-256 hash value, schedule and padded tail. */
|
|
5597
|
+
hash: u32[]
|
|
5598
|
+
schedule: u32[]
|
|
5599
|
+
tail: u8[]
|
|
5600
|
+
/** An HMAC key block and the message after it. */
|
|
5601
|
+
block: u8[]
|
|
5602
|
+
/** `V || sep`, where every key update's message starts (RFC 6979 §3.2 steps d, f and h.3). */
|
|
5603
|
+
message: u8[]
|
|
5604
|
+
/** RFC 6979's `K` and `V`; the last `V` is the nonce. */
|
|
5605
|
+
k: u8[]
|
|
5606
|
+
v: u8[]
|
|
5607
|
+
/** The message's digest, then int2octets of it mod n: RFC 6979's `h1`. */
|
|
5608
|
+
h1: u8[]
|
|
5609
|
+
/** The digest mod n, `r`, the nonce point's affine x, and `k^-1` in the Montgomery domain. */
|
|
5610
|
+
z: u32[]
|
|
5611
|
+
r: u32[]
|
|
5612
|
+
x: u32[]
|
|
5613
|
+
kM: u32[]
|
|
5614
|
+
/** The order n and R^2 mod n. */
|
|
5615
|
+
n: u32[]
|
|
5616
|
+
r2: u32[]
|
|
5617
|
+
/** The nonce's multiple of G, the comb table of G and point scratch. */
|
|
5618
|
+
point: P256ProjectivePoint
|
|
5619
|
+
table: u32[]
|
|
5620
|
+
points: P256PointScratch
|
|
5621
|
+
|
|
5622
|
+
constructor() {
|
|
5623
|
+
this.kt = [
|
|
5624
|
+
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
|
5625
|
+
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
|
5626
|
+
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
|
5627
|
+
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
|
5628
|
+
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
|
5629
|
+
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
|
5630
|
+
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
|
5631
|
+
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
|
|
5632
|
+
]
|
|
5633
|
+
this.hash = p256Limbs()
|
|
5634
|
+
this.schedule = new Array<u32>(64)
|
|
5635
|
+
this.tail = new Array<u8>(2 * SHA256_BLOCK)
|
|
5636
|
+
this.block = new Array<u8>(SHA256_BLOCK + P256_NONCE_MESSAGE)
|
|
5637
|
+
this.message = new Array<u8>(SHA256_SIZE + 1)
|
|
5638
|
+
this.k = new Array<u8>(SHA256_SIZE)
|
|
5639
|
+
this.v = new Array<u8>(SHA256_SIZE)
|
|
5640
|
+
this.h1 = new Array<u8>(SHA256_SIZE)
|
|
5641
|
+
this.z = p256Limbs()
|
|
5642
|
+
this.r = p256Limbs()
|
|
5643
|
+
this.x = p256Limbs()
|
|
5644
|
+
this.kM = p256Limbs()
|
|
5645
|
+
this.n = p256Order()
|
|
5646
|
+
this.r2 = p256ScalarR2()
|
|
5647
|
+
this.point = new P256ProjectivePoint()
|
|
5648
|
+
this.table = p256BaseTable()
|
|
5649
|
+
this.points = new P256PointScratch()
|
|
5650
|
+
}
|
|
5651
|
+
}
|
|
5652
|
+
|
|
5653
|
+
/** `out = HMAC_K(message[0 .. len))` with the scratch's `K` and work arrays. */
|
|
5654
|
+
const p256SignMac = (sc: P256SignScratch, out: u8[], message: u8[], len: i32): void =>
|
|
5655
|
+
p256HmacInto(out, sc.k, message, len, sc.kt, sc.hash, sc.schedule, sc.tail, sc.block)
|
|
5656
|
+
|
|
5657
|
+
/**
|
|
5658
|
+
* HMAC_K(V || sep || x || h1) for RFC 6979 §3.2 steps d and f, on the plain
|
|
5659
|
+
* key `x`, for `exposeWith` to run: `V || sep` is the scratch's `message`,
|
|
5660
|
+
* which is only read, as the rest of the scratch is; the message and the
|
|
5661
|
+
* hashing's work arrays are fresh and wiped, and the new `K` is the answer.
|
|
5662
|
+
*/
|
|
5663
|
+
const p256NonceKeyExposed = (priv: u8[], sc: P256SignScratch): u8[] => {
|
|
5664
|
+
const message: u8[] = new Array<u8>(P256_NONCE_MESSAGE)
|
|
5665
|
+
p256CopyBytes(message, sc.message, SHA256_SIZE + 1)
|
|
5666
|
+
for (let i: i32 = 0; i < SHA256_SIZE && i < toI32(priv.length) && i < toI32(sc.h1.length); i++) {
|
|
5667
|
+
const j: i32 = SHA256_SIZE + 1 + i
|
|
5668
|
+
const l: i32 = j + SHA256_SIZE
|
|
5669
|
+
if (j >= 0 && l >= 0 && j < toI32(message.length) && l < toI32(message.length)) {
|
|
5670
|
+
message[j] = priv[i]
|
|
5671
|
+
message[l] = sc.h1[i]
|
|
5672
|
+
}
|
|
5673
|
+
}
|
|
5674
|
+
const key: u8[] = new Array<u8>(SHA256_SIZE)
|
|
5675
|
+
p256HmacInto(
|
|
5676
|
+
key,
|
|
5677
|
+
sc.k,
|
|
5678
|
+
message,
|
|
5679
|
+
P256_NONCE_MESSAGE,
|
|
5680
|
+
sc.kt,
|
|
5681
|
+
p256Limbs(),
|
|
5682
|
+
new Array<u32>(64),
|
|
5683
|
+
new Array<u8>(2 * SHA256_BLOCK),
|
|
5684
|
+
new Array<u8>(SHA256_BLOCK + P256_NONCE_MESSAGE)
|
|
5685
|
+
)
|
|
5686
|
+
wipe(message)
|
|
5687
|
+
return key
|
|
5688
|
+
}
|
|
5689
|
+
|
|
5690
|
+
/**
|
|
5691
|
+
* `s = k^-1 (z + r d) mod n` on the plain key `d`, for `exposeWith` to run,
|
|
5692
|
+
* with `p256SignScalar`'s arithmetic: `d` taken into the Montgomery domain,
|
|
5693
|
+
* multiplied by the plain `r`, `z` added, and the sum multiplied by `k^-1`,
|
|
5694
|
+
* which is in the Montgomery domain, so `s` comes out plain. The key's limbs
|
|
5695
|
+
* are wiped; `s` is half of the signature, and public.
|
|
5696
|
+
*/
|
|
5697
|
+
const p256SignSExposed = (priv: u8[], sc: P256SignScratch): u32[] => {
|
|
5698
|
+
const dM: u32[] = p256Limbs()
|
|
5699
|
+
p256LimbsFromBytes(dM, priv, 0)
|
|
5700
|
+
p256FiatScalarMul(dM, dM, sc.r2)
|
|
5701
|
+
const s: u32[] = p256Limbs()
|
|
5702
|
+
p256FiatScalarMul(s, sc.r, dM)
|
|
5703
|
+
p256FiatScalarAdd(s, s, sc.z)
|
|
5704
|
+
p256FiatScalarMul(s, s, sc.kM)
|
|
5705
|
+
wipe(dM)
|
|
5706
|
+
return s
|
|
5707
|
+
}
|
|
5708
|
+
|
|
5709
|
+
/** `sc.message = V || sep`, the start of every key update's message (RFC 6979 §3.2 steps d, f and h.3). */
|
|
5710
|
+
const p256NonceSeparated = (sc: P256SignScratch, sep: u8): void => {
|
|
5711
|
+
p256CopyBytes(sc.message, sc.v, SHA256_SIZE)
|
|
5712
|
+
sc.message[SHA256_SIZE] = sep
|
|
5713
|
+
}
|
|
5714
|
+
|
|
5715
|
+
/** Steps d and f: `K` replaced by what the exposed step answers, which is wiped once copied. */
|
|
5716
|
+
const p256SignNonceKey = (sc: P256SignScratch, priv: Secret<u8[]>, sep: u8): void => {
|
|
5717
|
+
p256NonceSeparated(sc, sep)
|
|
5718
|
+
const next: u8[] = exposeWith(priv, sc, p256NonceKeyExposed)
|
|
5719
|
+
p256CopyBytes(sc.k, next, SHA256_SIZE)
|
|
5720
|
+
wipe(next)
|
|
5721
|
+
}
|
|
5722
|
+
|
|
5723
|
+
/** Zero every secret the scratch held: `K`, `V`, `k^-1`, the nonce point and its scratch (ECC-2). */
|
|
5724
|
+
const p256WipeSignScratch = (sc: P256SignScratch): void => {
|
|
5725
|
+
wipe(sc.k)
|
|
5726
|
+
wipe(sc.v)
|
|
5727
|
+
wipe(sc.message)
|
|
5728
|
+
wipe(sc.kM)
|
|
5729
|
+
p256WipePoint(sc.point)
|
|
5730
|
+
p256WipeScratch(sc.points)
|
|
5731
|
+
}
|
|
5732
|
+
|
|
5733
|
+
/**
|
|
5734
|
+
* `p256SignSha256` of `msg[off .. off + len)` in `scratch`, written as `r || s`
|
|
5735
|
+
* at `out[at .. at + 64)`: the same 64 bytes `p256SignSha256` answers for the
|
|
5736
|
+
* same key and message. Answers `false`, writing nothing, for a private key
|
|
5737
|
+
* `p256PublicKey` would refuse. A message or signature window outside its
|
|
5738
|
+
* array panics before anything is read.
|
|
5739
|
+
*
|
|
5740
|
+
* It runs inside an arena block of its own and stores nothing, so a signature
|
|
5741
|
+
* leaves the arena where it was; every secret the scratch held — RFC 6979's
|
|
5742
|
+
* `K` and `V`, the nonce's inverse, its point and the point scratch — is wiped
|
|
5743
|
+
* before it returns, as are the fresh arrays the key's own steps worked in.
|
|
5744
|
+
*/
|
|
5745
|
+
export const p256SignSha256Into = (
|
|
5746
|
+
sc: P256SignScratch,
|
|
5747
|
+
priv: Secret<u8[]>,
|
|
5748
|
+
msg: u8[],
|
|
5749
|
+
off: i32,
|
|
5750
|
+
len: i32,
|
|
5751
|
+
out: u8[],
|
|
5752
|
+
at: i32
|
|
5753
|
+
): boolean => {
|
|
5754
|
+
if (!p256WindowFits(toI32(msg.length), off, len)) {
|
|
5755
|
+
panic("p256SignSha256Into: the message window is outside its array")
|
|
5756
|
+
}
|
|
5757
|
+
if (!p256WindowFits(toI32(out.length), at, P256_SIGNATURE_SIZE)) {
|
|
5758
|
+
panic("p256SignSha256Into: the signature window is outside its array")
|
|
5759
|
+
}
|
|
5760
|
+
using _scope = arena()
|
|
5761
|
+
if (!expose(priv, p256ScalarInRange)) {
|
|
5762
|
+
return false
|
|
5763
|
+
}
|
|
5764
|
+
p256ShaInto(sc.h1, P256_FROM, msg, off, len, sc.kt, sc.hash, sc.schedule, sc.tail)
|
|
5765
|
+
p256DigestScalar(sc.z, sc.h1)
|
|
5766
|
+
p256LimbsToBytes(sc.h1, 0, sc.z)
|
|
5767
|
+
for (let i: i32 = 0; i < SHA256_SIZE && i < toI32(sc.v.length) && i < toI32(sc.k.length); i++) {
|
|
5768
|
+
sc.v[i] = 1
|
|
5769
|
+
sc.k[i] = 0
|
|
5770
|
+
}
|
|
5771
|
+
p256SignNonceKey(sc, priv, 0) // step d
|
|
5772
|
+
p256SignMac(sc, sc.v, sc.v, SHA256_SIZE) // step e
|
|
5773
|
+
p256SignNonceKey(sc, priv, 1) // step f
|
|
5774
|
+
p256SignMac(sc, sc.v, sc.v, SHA256_SIZE) // step g
|
|
5775
|
+
while (true) {
|
|
5776
|
+
p256SignMac(sc, sc.v, sc.v, SHA256_SIZE) // step h.2
|
|
5777
|
+
if (p256ScalarInRange(sc.v)) {
|
|
5778
|
+
p256BaseMultWith(sc.point, sc.v, sc.points, sc.table)
|
|
5779
|
+
p256AffineX(sc.x, sc.point)
|
|
5780
|
+
p256ReduceOnce(sc.r, sc.x, sc.n)
|
|
5781
|
+
p256LimbsFromBytes(sc.kM, sc.v, 0)
|
|
5782
|
+
p256FiatScalarMul(sc.kM, sc.kM, sc.r2)
|
|
5783
|
+
p256ScalarInverse(sc.kM, sc.kM)
|
|
5784
|
+
const s: u32[] = exposeWith(priv, sc, p256SignSExposed)
|
|
5785
|
+
if (p256FiatNonzero(sc.r) !== 0 && p256FiatNonzero(s) !== 0) {
|
|
5786
|
+
p256LimbsToBytes(out, at, sc.r)
|
|
5787
|
+
p256LimbsToBytes(out, at + 32, s)
|
|
5788
|
+
p256WipeSignScratch(sc)
|
|
5789
|
+
return true
|
|
5790
|
+
}
|
|
5791
|
+
}
|
|
5792
|
+
// step h.3: K = HMAC_K(V || 0x00), then V = HMAC_K(V).
|
|
5793
|
+
p256NonceSeparated(sc, 0)
|
|
5794
|
+
p256SignMac(sc, sc.k, sc.message, SHA256_SIZE + 1)
|
|
5795
|
+
p256SignMac(sc, sc.v, sc.v, SHA256_SIZE)
|
|
5796
|
+
}
|
|
5797
|
+
}
|