@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.
Files changed (61) hide show
  1. package/INSTALL.md +43 -25
  2. package/bin/nish +0 -0
  3. package/package.json +2 -2
  4. package/runtime/nish.d.ts +55 -5
  5. package/runtime/nish.h +231 -20
  6. package/runtime/nish.mjs +16 -0
  7. package/runtime/runtime-aes.c +490 -0
  8. package/runtime/runtime-cross.c +366 -0
  9. package/runtime/runtime-host.c +7 -6
  10. package/runtime/runtime-net.c +93 -34
  11. package/runtime/runtime-os.c +213 -15
  12. package/runtime/runtime-parallel.c +590 -107
  13. package/runtime/runtime-simd.c +203 -0
  14. package/runtime/runtime-wasm.c +16 -3
  15. package/runtime/runtime.c +89 -23
  16. package/runtime/shim.mjs +71 -1
  17. package/scripts/build.sh +225 -20
  18. package/std/README.md +86 -55
  19. package/std/bytes.ts +163 -0
  20. package/std/crypto/LICENSE-libsecp256k1 +19 -0
  21. package/std/crypto/aes.ts +238 -76
  22. package/std/crypto/chacha20poly1305.ts +43 -9
  23. package/std/crypto/ed25519.ts +840 -0
  24. package/std/crypto/hkdf.ts +304 -12
  25. package/std/crypto/hmac.ts +245 -53
  26. package/std/crypto/p256.ts +1376 -42
  27. package/std/crypto/x25519.ts +55 -37
  28. package/std/crypto/x509-random.ts +71 -0
  29. package/std/crypto/x509.ts +9 -9
  30. package/std/json-tokenizer.ts +1296 -0
  31. package/std/json-typed.ts +1014 -0
  32. package/std/json-value.ts +1163 -0
  33. package/std/json.ts +1412 -70
  34. package/std/net/buffer-pool.ts +151 -0
  35. package/std/net/hpack.ts +416 -112
  36. package/std/net/http-fields.ts +93 -0
  37. package/std/net/http1-server.ts +417 -55
  38. package/std/net/http1.ts +31 -6
  39. package/std/net/http2-tls.ts +112 -24
  40. package/std/net/http2.ts +333 -75
  41. package/std/net/http3-server.ts +231 -45
  42. package/std/net/http3.ts +187 -28
  43. package/std/net/prefork.ts +412 -0
  44. package/std/net/quic-conn-params.ts +86 -16
  45. package/std/net/quic-listener.ts +576 -219
  46. package/std/net/quic-packet.ts +443 -58
  47. package/std/net/quic-recovery.ts +361 -30
  48. package/std/net/quic-stream.ts +434 -28
  49. package/std/net/quic.ts +922 -206
  50. package/std/net/router.ts +676 -0
  51. package/std/net/tls/codec.ts +426 -27
  52. package/std/net/tls/record-server.ts +478 -132
  53. package/std/net/tls/record.ts +133 -42
  54. package/std/net/tls/schedule.ts +464 -55
  55. package/std/net/tls/ticket.ts +610 -0
  56. package/std/net/tls-tcp.ts +204 -57
  57. package/std/net/tls.ts +1132 -305
  58. package/std/net/url.ts +571 -0
  59. package/std/random.ts +94 -0
  60. package/std/text.ts +77 -0
  61. package/std/threads.ts +438 -14
@@ -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. Everything else in this file — the curve, the encodings, the
39
- * inversions and ECDSA — is written for this module from the documents it
40
- * names.
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 `p256ScalarMult`, a fixed 4-bit window: sixteen
53
- * multiples of the point in a table, then 64 windows of four doublings, a
54
- * table read and an addition, whatever the scalar. The read loads all sixteen
55
- * entries and keeps one with fiat's conditional move, steered by `ctEq` on the
56
- * window's digit, so neither a branch nor an address depends on the scalar.
57
- * The inversions raise to the public exponents p - 2 and n - 2, so their
58
- * branches follow a constant. The branches that remain are on public facts: a
59
- * length, a limb or bit position, whether a received key or signature is in
60
- * range, and — once in about 2^32 signatures — RFC 6979's retry when a
61
- * candidate nonce is not below n.
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, and one window step
67
- * of `p256ScalarMult` to the check of `tests/ct-asm.js`, which refuses any
68
- * branch, call it cannot follow or secret-indexed access in them on x86-64 and
69
- * aarch64, following each call into the field functions. The copies of the
70
- * point functions take coordinate arrays rather than points, and the table
71
- * read's loop is written out there, as that fixture's header says; its `main`
72
- * runs RFC 6979 A.2.5 through them. The 64-window loop, the table build, the
73
- * inversions, the encodings and the nonce derivation are constant time by
74
- * construction rather than by that proof.
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, and uses the same routine.
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, and the curve's `b`, which the
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 = (table: u32[], p: P256ProjectivePoint, s: P256PointScratch): void => {
3963
- const acc = new P256ProjectivePoint()
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
- const table: u32[] = new Array<u32>(384)
4030
- p256TableBuild(table, p, s)
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
- p256ScalarMult(point, v, g, scratch)
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
- p256ScalarInvert(kM, kM)
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
- /** `p256PublicKey` on the plain key, for `expose` to run: the scratch the key's digits steered is wiped. */
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
- p256ScalarMult(point, priv, p256Generator(), scratch)
5264
+ p256BaseMult(point, priv, scratch)
4364
5265
  p256WipeScratch(scratch)
4365
- return p256EncodePoint(point)
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
+ }