@pinionengineering/prover-client 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bn254.js ADDED
@@ -0,0 +1,186 @@
1
+ /**
2
+ * BN254 (alt_bn128 / Ethereum) curve operations using noble/curves.
3
+ *
4
+ * Curve parameters (Ethereum EIP-197 / gnark-crypto):
5
+ * p = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47
6
+ * q = 21888242871839275222246405745257275088548364400416034343698204186575808495617
7
+ * y² = x³ + 3 over Fp
8
+ *
9
+ * Wire formats (gnark-crypto RawBytes / EIP-197):
10
+ * G1: 64 bytes = X_BE(32) || Y_BE(32)
11
+ * G2: 128 bytes = X.A1(32) || X.A0(32) || Y.A1(32) || Y.A0(32)
12
+ * (gnark-crypto A0=real, A1=imaginary; noble c0=real, c1=imaginary)
13
+ *
14
+ * hashToG1 implements RFC 9380 hash-to-curve using the SVDW map with DST
15
+ * "sw-pub-v1-BN254G1_XMD:SHA-256_SVDW_RO_", matching gnark-crypto HashToG1
16
+ * in storage-proofs/por/sw/pub.go.
17
+ *
18
+ * noble/curves v1.9.7 has SVDW for BN254 G1 marked notImplemented, so the
19
+ * map is implemented here directly from RFC 9380 §6.6.2 using BigInt arithmetic.
20
+ * Constants are from gnark-crypto ecc/bn254/hash_to_g1.go, converted from
21
+ * Montgomery form.
22
+ */
23
+ import { bn254 } from '@noble/curves/bn254';
24
+ import { hash_to_field } from '@noble/curves/abstract/hash-to-curve';
25
+ import { sha256 } from '@noble/hashes/sha256';
26
+ // ---------------------------------------------------------------------------
27
+ // Base points
28
+ // ---------------------------------------------------------------------------
29
+ export const G1_BASE = bn254.G1.ProjectivePoint.BASE;
30
+ export const G2_BASE = bn254.G2.ProjectivePoint.BASE;
31
+ // ---------------------------------------------------------------------------
32
+ // Utility
33
+ // ---------------------------------------------------------------------------
34
+ /** Convert big-endian bytes to a bigint. */
35
+ export function bytesToBigInt(bytes) {
36
+ let result = 0n;
37
+ for (let i = 0; i < bytes.length; i++)
38
+ result = (result << 8n) | BigInt(bytes[i] ?? 0);
39
+ return result;
40
+ }
41
+ // ---------------------------------------------------------------------------
42
+ // Wire format parsing
43
+ // ---------------------------------------------------------------------------
44
+ /** Deserialize a G1 point from 64 bytes (gnark-crypto RawBytes / EIP-197 format). */
45
+ export function g1FromBytes(bytes) {
46
+ if (bytes.length !== 64)
47
+ throw new Error(`BN254 G1: expected 64 bytes, got ${bytes.length}`);
48
+ const x = bytesToBigInt(bytes.subarray(0, 32));
49
+ const y = bytesToBigInt(bytes.subarray(32, 64));
50
+ return bn254.G1.ProjectivePoint.fromAffine({ x, y });
51
+ }
52
+ /**
53
+ * Deserialize a G2 point from 128 bytes (gnark-crypto RawBytes / EIP-197 format).
54
+ *
55
+ * gnark-crypto G2Affine.RawBytes() layout:
56
+ * bytes[ 0: 32] = X.A1 (imaginary)
57
+ * bytes[32: 64] = X.A0 (real)
58
+ * bytes[64: 96] = Y.A1 (imaginary)
59
+ * bytes[96:128] = Y.A0 (real)
60
+ *
61
+ * noble/curves Fp2 uses { c0: real, c1: imaginary }.
62
+ */
63
+ export function g2FromBytes(bytes) {
64
+ if (bytes.length !== 128)
65
+ throw new Error(`BN254 G2: expected 128 bytes, got ${bytes.length}`);
66
+ const xIm = bytesToBigInt(bytes.subarray(0, 32));
67
+ const xRe = bytesToBigInt(bytes.subarray(32, 64));
68
+ const yIm = bytesToBigInt(bytes.subarray(64, 96));
69
+ const yRe = bytesToBigInt(bytes.subarray(96, 128));
70
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
71
+ const Fp2 = bn254.fields.Fp2;
72
+ return bn254.G2.ProjectivePoint.fromAffine({
73
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
74
+ x: Fp2.fromBigTuple([xRe, xIm]),
75
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
76
+ y: Fp2.fromBigTuple([yRe, yIm]),
77
+ });
78
+ }
79
+ // ---------------------------------------------------------------------------
80
+ // G1 arithmetic
81
+ // ---------------------------------------------------------------------------
82
+ /** Scalar-multiply a G1 point: returns k·P. */
83
+ export function g1ScalarMult(P, k) {
84
+ return P.multiply(k);
85
+ }
86
+ /** Add two G1 points. */
87
+ export function g1Add(A, B) {
88
+ return A.add(B);
89
+ }
90
+ // ---------------------------------------------------------------------------
91
+ // Pairing
92
+ // ---------------------------------------------------------------------------
93
+ /** Compute the BN254 Ate pairing e(P, Q) → Fp12. */
94
+ export function atePairing(P, Q) {
95
+ return bn254.pairing(P, Q);
96
+ }
97
+ /** Check equality of two Fp12 elements. */
98
+ export function fp12Equal(a, b) {
99
+ return bn254.fields.Fp12.eql(a, b);
100
+ }
101
+ // ---------------------------------------------------------------------------
102
+ // RFC 9380 SVDW hash-to-G1 for BN254
103
+ // ---------------------------------------------------------------------------
104
+ const FP_P = 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47n;
105
+ const FP_B = 3n; // BN254: y² = x³ + 3
106
+ // SVDW precomputed constants for Z = 1 (from gnark-crypto, converted from Montgomery form)
107
+ const C1 = 4n; // g(Z) = Z³ + B = 1 + 3 = 4
108
+ const C2 = 0x183227397098d014dc2822db40c0ac2ecbc0b548b438e5469e10460b6c3e7ea3n; // -Z/2 mod p
109
+ const C3 = 0x16789af3a83522eb353c98fc6b36d713d5d8d1cc5dffffffan; // sqrt(-g(Z)·3Z²) mod p
110
+ const C4 = 0x10216f7ba065e00de81ac1e7808072c9dd2b2385cd7b438469602eb24829a9bdn; // -4g(Z)/(3Z²) mod p
111
+ const Z = 1n;
112
+ const SQRT_EXP = (FP_P + 1n) >> 2n; // (p+1)/4, valid since p ≡ 3 mod 4
113
+ const LEG_EXP = (FP_P - 1n) >> 1n; // (p-1)/2
114
+ function fpAdd(a, b) { return (a + b) % FP_P; }
115
+ function fpSub(a, b) { return ((a - b) % FP_P + FP_P) % FP_P; }
116
+ function fpMul(a, b) { return (a * b) % FP_P; }
117
+ function fpSqr(a) { return (a * a) % FP_P; }
118
+ function fpNeg(a) { return a === 0n ? 0n : FP_P - a; }
119
+ function fpPow(base, exp) {
120
+ let r = 1n;
121
+ let b = base % FP_P;
122
+ let e = exp;
123
+ while (e > 0n) {
124
+ if (e & 1n)
125
+ r = (r * b) % FP_P;
126
+ e >>= 1n;
127
+ b = (b * b) % FP_P;
128
+ }
129
+ return r;
130
+ }
131
+ function fpSqrt(a) { return fpPow(a, SQRT_EXP); }
132
+ function fpInv0(a) { return a === 0n ? 0n : fpPow(a, FP_P - 2n); }
133
+ function isSquare(a) { return fpPow(a, LEG_EXP) !== FP_P - 1n; }
134
+ function sgn0(a) { return a & 1n; }
135
+ function cmov(a, b, cond) { return cond ? b : a; }
136
+ /**
137
+ * RFC 9380 §6.6.2 straightline SVDW map-to-curve for BN254 G1 (A=0, B=3, Z=1).
138
+ * Matches gnark-crypto ecc/bn254/hash_to_g1.go MapToCurve1 exactly.
139
+ *
140
+ * Steps 22-26 compute x3 = (tv2² · tv3)² · c4 + Z, which is the RFC 9380
141
+ * straightline form — NOT the non-straightline form tv4²+c4.
142
+ */
143
+ function svdwMapToCurve(u) {
144
+ const tv1 = fpMul(fpSqr(u), C1); // 1-2: u²·c1
145
+ const tv2 = fpAdd(1n, tv1); // 3: 1 + tv1
146
+ const tv1b = fpSub(1n, tv1); // 4: 1 - tv1
147
+ const tv3 = fpInv0(fpMul(tv1b, tv2)); // 5-6: inv0(tv1b·tv2)
148
+ const tv4 = fpMul(fpMul(fpMul(u, tv1b), tv3), C3); // 7-9: u·tv1b·tv3·c3
149
+ const x1 = fpSub(C2, tv4); // 10: c2 - tv4
150
+ const gx1 = fpAdd(fpMul(fpSqr(x1), x1), FP_B); // 11-14: x1³+B
151
+ const e1 = isSquare(gx1); // 15
152
+ const x2 = fpAdd(C2, tv4); // 16: c2 + tv4
153
+ const gx2 = fpAdd(fpMul(fpSqr(x2), x2), FP_B); // 17-20: x2³+B
154
+ const e2 = isSquare(gx2) && !e1; // 21
155
+ const x3 = fpAdd(fpMul(fpSqr(fpMul(fpSqr(tv2), tv3)), C4), Z); // 22-26: (tv2²·tv3)²·c4+Z
156
+ const x = cmov(cmov(x3, x2, e2), x1, e1); // 27-28
157
+ const gx = fpAdd(fpMul(fpSqr(x), x), FP_B); // 29-32: x³+B
158
+ const y = fpSqrt(gx); // 33
159
+ const e3 = sgn0(u) === sgn0(y); // 34
160
+ return { x, y: cmov(fpNeg(y), y, e3) }; // 35
161
+ }
162
+ /** RFC 9380 hash-to-G1 DST matching gnark-crypto storage-proofs/por/sw/pub.go. */
163
+ const SW_PUB_DST = 'sw-pub-v1-BN254G1_XMD:SHA-256_SVDW_RO_';
164
+ const HTF_OPTS = {
165
+ DST: SW_PUB_DST,
166
+ p: FP_P,
167
+ m: 1, // G1 lives in Fp (not an extension field)
168
+ k: 128, // 128 bits of security → L = 48 bytes per element
169
+ expand: 'xmd',
170
+ hash: sha256,
171
+ };
172
+ /**
173
+ * Hash bytes to a G1 point using RFC 9380 SVDW with the SW-Pub DST.
174
+ *
175
+ * Matches gnark-crypto HashToG1(msg, pubHashDST) in storage-proofs/por/sw/pub.go.
176
+ */
177
+ export function hashToG1(msg) {
178
+ // hash_to_field returns [[u0], [u1]] for count=2, m=1
179
+ const fields = hash_to_field(msg, 2, HTF_OPTS);
180
+ const u0 = fields[0][0];
181
+ const u1 = fields[1][0];
182
+ const Q0 = bn254.G1.ProjectivePoint.fromAffine(svdwMapToCurve(u0));
183
+ const Q1 = bn254.G1.ProjectivePoint.fromAffine(svdwMapToCurve(u1));
184
+ return Q0.add(Q1);
185
+ }
186
+ //# sourceMappingURL=bn254.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bn254.js","sourceRoot":"","sources":["../src/bn254.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * BN256 curve operations matching cloudflare/bn256 used by pinion-prover.
3
+ *
4
+ * WARNING: This is NOT the Ethereum alt_bn128 / BN254 curve (p ≈ 2^254).
5
+ * cloudflare/bn256 uses a DIFFERENT 256-bit prime (p ≈ 2^256), giving a
6
+ * different field, different generator point, and different group order.
7
+ * The two curves are incompatible; libraries that call themselves "bn256"
8
+ * but mean "alt_bn128" (e.g. noble/curves/bn254) will not work here.
9
+ *
10
+ * Curve parameters (from cloudflare/bn256 constants.go):
11
+ * BN parameter u = 6518589491078791937
12
+ * Field prime p = 36u⁴+36u³+24u²+6u+1 (256 bits)
13
+ * Group order n = 36u⁴+36u³+18u²+6u+1 (256 bits)
14
+ * Curve equation = y² = x³ + 3 over Fp
15
+ * G1 generator = (1, p-2) [y = -2 mod p]
16
+ * G2 twist = D-type, y² = x³ + 3/ξ over Fp², ξ = 3+i (FP2_NONRESIDUE=[3,1])
17
+ * Ate loop size = 6u + 2
18
+ *
19
+ * Wire formats (cloudflare Marshal):
20
+ * G1: 64 bytes = x_BE(32) || y_BE(32)
21
+ * G2: 128 bytes = X_im(32) || X_re(32) || Y_im(32) || Y_re(32)
22
+ * (cloudflare gfP2 stores {x=imaginary, y=real}; noble Fp2 uses {c0=real, c1=imaginary})
23
+ *
24
+ * G2 coordinate mapping from cloudflare wire → noble Fp2:
25
+ * noble X = { c0: bytes[32:64], c1: bytes[0:32] }
26
+ * noble Y = { c0: bytes[96:128], c1: bytes[64:96] }
27
+ */
28
+ export declare const bn256: import("@noble/curves/abstract/bls").CurveFn;
29
+ export type G1Point = ReturnType<typeof bn256.G1.ProjectivePoint.fromAffine>;
30
+ export type G2Point = ReturnType<typeof bn256.G2.ProjectivePoint.fromAffine>;
31
+ export type Fp12Elem = ReturnType<typeof bn256.pairing>;
32
+ /** G1 generator. */
33
+ export declare const G1_BASE: G1Point;
34
+ /** G2 generator. */
35
+ export declare const G2_BASE: G2Point;
36
+ /**
37
+ * Deserialize a cloudflare/bn256 G1 point from 64 bytes.
38
+ * Format: x_BE(32) || y_BE(32) — no uncompressed prefix.
39
+ */
40
+ export declare function g1FromBytes(bytes: Uint8Array): G1Point;
41
+ /**
42
+ * Deserialize a cloudflare/bn256 G2 point.
43
+ *
44
+ * cloudflare G2.Marshal() returns EITHER:
45
+ * 1 byte — [0x00] for the point at infinity
46
+ * 129 bytes — [0x01] || X_im(32) || X_re(32) || Y_im(32) || Y_re(32)
47
+ *
48
+ * cloudflare gfP2 stores {x=imaginary, y=real}, so:
49
+ * bytes[1:33] = X_imaginary (noble X.c1)
50
+ * bytes[33:65] = X_real (noble X.c0)
51
+ * bytes[65:97] = Y_imaginary (noble Y.c1)
52
+ * bytes[97:129] = Y_real (noble Y.c0)
53
+ */
54
+ export declare function g2FromBytes(bytes: Uint8Array): G2Point;
55
+ /** Scalar-multiply a G1 point: returns k·P. */
56
+ export declare function g1ScalarMult(P: G1Point, k: bigint): G1Point;
57
+ /** Add two G1 points. */
58
+ export declare function g1Add(A: G1Point, B: G1Point): G1Point;
59
+ /**
60
+ * Compute the BN256 Ate pairing e(P, Q) → Fp12.
61
+ * Matches bn256.Pair() in Go.
62
+ */
63
+ export declare function atePairing(P: G1Point, Q: G2Point): Fp12Elem;
64
+ /** Check equality of two Fp12 elements. */
65
+ export declare function fp12Equal(a: Fp12Elem, b: Fp12Elem): boolean;
66
+ /** Convert big-endian bytes to a bigint. */
67
+ export declare function bytesToBigInt(bytes: Uint8Array): bigint;
68
+ //# sourceMappingURL=bn256.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bn256.d.ts","sourceRoot":"","sources":["../src/bn256.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAiGH,eAAO,MAAM,KAAK,8CAqDT,CAAC;AAMV,MAAM,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;AAC7E,MAAM,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;AAC7E,MAAM,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC;AAExD,oBAAoB;AACpB,eAAO,MAAM,OAAO,EAAE,OAAuC,CAAC;AAC9D,oBAAoB;AACpB,eAAO,MAAM,OAAO,EAAE,OAAuC,CAAC;AAE9D;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAMtD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CActD;AAED,+CAA+C;AAC/C,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED,yBAAyB;AACzB,wBAAgB,KAAK,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CAErD;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,QAAQ,CAE3D;AAED,2CAA2C;AAC3C,wBAAgB,SAAS,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,CAE3D;AAED,4CAA4C;AAC5C,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAMvD"}
package/dist/bn256.js ADDED
@@ -0,0 +1,231 @@
1
+ /**
2
+ * BN256 curve operations matching cloudflare/bn256 used by pinion-prover.
3
+ *
4
+ * WARNING: This is NOT the Ethereum alt_bn128 / BN254 curve (p ≈ 2^254).
5
+ * cloudflare/bn256 uses a DIFFERENT 256-bit prime (p ≈ 2^256), giving a
6
+ * different field, different generator point, and different group order.
7
+ * The two curves are incompatible; libraries that call themselves "bn256"
8
+ * but mean "alt_bn128" (e.g. noble/curves/bn254) will not work here.
9
+ *
10
+ * Curve parameters (from cloudflare/bn256 constants.go):
11
+ * BN parameter u = 6518589491078791937
12
+ * Field prime p = 36u⁴+36u³+24u²+6u+1 (256 bits)
13
+ * Group order n = 36u⁴+36u³+18u²+6u+1 (256 bits)
14
+ * Curve equation = y² = x³ + 3 over Fp
15
+ * G1 generator = (1, p-2) [y = -2 mod p]
16
+ * G2 twist = D-type, y² = x³ + 3/ξ over Fp², ξ = 3+i (FP2_NONRESIDUE=[3,1])
17
+ * Ate loop size = 6u + 2
18
+ *
19
+ * Wire formats (cloudflare Marshal):
20
+ * G1: 64 bytes = x_BE(32) || y_BE(32)
21
+ * G2: 128 bytes = X_im(32) || X_re(32) || Y_im(32) || Y_re(32)
22
+ * (cloudflare gfP2 stores {x=imaginary, y=real}; noble Fp2 uses {c0=real, c1=imaginary})
23
+ *
24
+ * G2 coordinate mapping from cloudflare wire → noble Fp2:
25
+ * noble X = { c0: bytes[32:64], c1: bytes[0:32] }
26
+ * noble Y = { c0: bytes[96:128], c1: bytes[64:96] }
27
+ */
28
+ import { Field } from '@noble/curves/abstract/modular';
29
+ import { tower12 } from '@noble/curves/abstract/tower';
30
+ import { bls } from '@noble/curves/abstract/bls';
31
+ import { sha256 } from '@noble/hashes/sha256';
32
+ // ---------------------------------------------------------------------------
33
+ // BN256 field parameters
34
+ // ---------------------------------------------------------------------------
35
+ const BN_X = 6518589491078791937n; // cloudflare BN256 parameter u
36
+ const BN_X_LEN = 63; // bitLen(u)
37
+ const _0n = 0n, _1n = 1n, _2n = 2n, _3n = 3n, _6n = 6n;
38
+ const SIX_X_SQUARED = _6n * BN_X ** _2n;
39
+ const BN256_P = 65000549695646603732796438742359905742825358107623003571877145026864184071783n;
40
+ const BN256_ORDER = 65000549695646603732796438742359905742570406053903786389881062969044166799969n;
41
+ // ---------------------------------------------------------------------------
42
+ // Twist b = 3/(3+i) in Fp2 (computed via Go helper: 9·10⁻¹ mod p, -3·10⁻¹ mod p)
43
+ // ---------------------------------------------------------------------------
44
+ const Fp2B_BN256 = {
45
+ c0: 45500384786952622612957507119651934019977750675336102500314001518804928850249n,
46
+ c1: 6500054969564660373279643874235990574282535810762300357187714502686418407178n,
47
+ };
48
+ // ---------------------------------------------------------------------------
49
+ // Build the field tower
50
+ // ---------------------------------------------------------------------------
51
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
52
+ const { Fp, Fp2, Fp6, Fp12 } = tower12({
53
+ ORDER: BN256_P,
54
+ X_LEN: BN_X_LEN,
55
+ // ξ = 3+i → FP2_NONRESIDUE = [c0=3, c1=1] (cloudflare uses ξ = i+3 = 3+i)
56
+ FP2_NONRESIDUE: [_3n, _1n],
57
+ // Multiply a Fp2 element by the G2 b coefficient (3/ξ).
58
+ Fp2mulByB: (num) => Fp2.mul(num, Fp2B_BN256),
59
+ // Final exponentiation using BN256's u = BN_X.
60
+ // Algorithm from Scott et al. "On the Final Exponentiation for Calculating
61
+ // Pairings on Ordinary Elliptic Curves" — same structure as BN254, just
62
+ // a different u value.
63
+ Fp12finalExponentiate: (num) => {
64
+ const powMinusX = (n) => Fp12.conjugate(Fp12._cyclotomicExp(n, BN_X));
65
+ const r0 = Fp12.mul(Fp12.conjugate(num), Fp12.inv(num));
66
+ const r = Fp12.mul(Fp12.frobeniusMap(r0, 2), r0);
67
+ const y1 = Fp12._cyclotomicSquare(powMinusX(r));
68
+ const y2 = Fp12.mul(Fp12._cyclotomicSquare(y1), y1);
69
+ const y4 = powMinusX(y2);
70
+ const y6 = powMinusX(Fp12._cyclotomicSquare(y4));
71
+ const y8 = Fp12.mul(Fp12.mul(Fp12.conjugate(y6), y4), Fp12.conjugate(y2));
72
+ const y9 = Fp12.mul(y8, y1);
73
+ return Fp12.mul(Fp12.frobeniusMap(Fp12.mul(Fp12.conjugate(r), y9), 3), Fp12.mul(Fp12.frobeniusMap(y8, 2), Fp12.mul(Fp12.frobeniusMap(y9, 1), Fp12.mul(Fp12.mul(y8, y4), r))));
74
+ },
75
+ });
76
+ // ---------------------------------------------------------------------------
77
+ // Frobenius endomorphism for G2 (needed for postPrecompute in Miller loop)
78
+ // ---------------------------------------------------------------------------
79
+ import { psiFrobenius } from '@noble/curves/abstract/tower';
80
+ const { G2psi, psi } = psiFrobenius(Fp, Fp2, Fp2.NONRESIDUE);
81
+ // ---------------------------------------------------------------------------
82
+ // G2 generator coordinates (decoded from cloudflare's String() output)
83
+ // cloudflare prints (im, re) for each coord; noble Fp2 uses {c0=real, c1=imag}
84
+ // ---------------------------------------------------------------------------
85
+ const BN256_G2_CURVE = {
86
+ p: Fp2.ORDER,
87
+ n: BN256_ORDER,
88
+ h: 21n, // cofactor for BN256 G2 (= (6u^2 + 1))
89
+ a: Fp2.ZERO,
90
+ b: Fp2B_BN256,
91
+ Gx: Fp2.fromBigTuple([
92
+ 64746500191241794695844075326670126197795977525365406531717464316923369116492n, // c0 = real
93
+ 21167961636542580255011770066570541300993051739349375019639421053990175267184n, // c1 = imaginary
94
+ ]),
95
+ Gy: Fp2.fromBigTuple([
96
+ 17778617556404439934652658462602675281523610326338642107814333856843981424549n, // c0 = real
97
+ 20666913350058776956210519119118544732556678129809273996262322366050359951122n, // c1 = imaginary
98
+ ]),
99
+ };
100
+ // ---------------------------------------------------------------------------
101
+ // Assemble the BN256 pairing instance using noble's bls() combinator
102
+ // ---------------------------------------------------------------------------
103
+ const notImpl = (..._args) => {
104
+ throw new Error('bn256: not implemented');
105
+ };
106
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
107
+ export const bn256 = bls({
108
+ fields: { Fp, Fp2, Fp6, Fp12, Fr: Field(BN256_ORDER) },
109
+ G1: {
110
+ p: BN256_P,
111
+ n: BN256_ORDER,
112
+ h: _1n,
113
+ a: _0n,
114
+ b: _3n,
115
+ Gx: _1n,
116
+ Gy: BN256_P - _2n,
117
+ Fp,
118
+ htfDefaults: { DST: '', encodeDST: '', p: BN256_P, m: 1, k: 128, expand: 'xmd', hash: sha256 },
119
+ wrapPrivateKey: true,
120
+ allowInfinityPoint: true,
121
+ mapToCurve: notImpl,
122
+ fromBytes: notImpl,
123
+ toBytes: notImpl,
124
+ ShortSignature: { fromBytes: notImpl, fromHex: notImpl, toBytes: notImpl, toRawBytes: notImpl, toHex: notImpl },
125
+ },
126
+ G2: {
127
+ ...BN256_G2_CURVE,
128
+ Fp: Fp2,
129
+ hEff: 1n,
130
+ htfDefaults: { DST: '', encodeDST: '', p: BN256_P, m: 2, k: 128, expand: 'xmd', hash: sha256 },
131
+ wrapPrivateKey: true,
132
+ allowInfinityPoint: true,
133
+ // [6u²]P = ψ(P) is the BN curve G2 torsion-freeness check.
134
+ // The cast is necessary because noble's internal G2 type is not yet resolved
135
+ // at the point where bls() is called (circular reference).
136
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
137
+ isTorsionFree: (c, P) => P.multiplyUnsafe(SIX_X_SQUARED).equals(G2psi(c, P)),
138
+ mapToCurve: notImpl,
139
+ fromBytes: notImpl,
140
+ toBytes: notImpl,
141
+ Signature: { fromBytes: notImpl, fromHex: notImpl, toBytes: notImpl, toRawBytes: notImpl, toHex: notImpl },
142
+ },
143
+ params: {
144
+ ateLoopSize: BN_X * _6n + _2n,
145
+ r: BN256_ORDER,
146
+ xNegative: false,
147
+ twistType: 'divisive',
148
+ },
149
+ htfDefaults: { DST: '', encodeDST: '', p: BN256_P, m: 1, k: 128, expand: 'xmd', hash: sha256 },
150
+ hash: sha256,
151
+ // Frobenius correction after the Miller loop (same as bn254.ts _postPrecompute).
152
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
153
+ postPrecompute: (Rx, Ry, Rz, Qx, Qy, pointAdd) => {
154
+ const q = psi(Qx, Qy);
155
+ ({ Rx, Ry, Rz } = pointAdd(Rx, Ry, Rz, q[0], q[1]));
156
+ const q2 = psi(q[0], q[1]);
157
+ pointAdd(Rx, Ry, Rz, q2[0], Fp2.neg(q2[1]));
158
+ },
159
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
160
+ });
161
+ /** G1 generator. */
162
+ export const G1_BASE = bn256.G1.ProjectivePoint.BASE;
163
+ /** G2 generator. */
164
+ export const G2_BASE = bn256.G2.ProjectivePoint.BASE;
165
+ /**
166
+ * Deserialize a cloudflare/bn256 G1 point from 64 bytes.
167
+ * Format: x_BE(32) || y_BE(32) — no uncompressed prefix.
168
+ */
169
+ export function g1FromBytes(bytes) {
170
+ if (bytes.length !== 64)
171
+ throw new Error(`BN256 G1: expected 64 bytes, got ${bytes.length}`);
172
+ const x = bytesToBigInt(bytes.subarray(0, 32));
173
+ const y = bytesToBigInt(bytes.subarray(32, 64));
174
+ return bn256.G1.ProjectivePoint.fromAffine({ x, y });
175
+ }
176
+ /**
177
+ * Deserialize a cloudflare/bn256 G2 point.
178
+ *
179
+ * cloudflare G2.Marshal() returns EITHER:
180
+ * 1 byte — [0x00] for the point at infinity
181
+ * 129 bytes — [0x01] || X_im(32) || X_re(32) || Y_im(32) || Y_re(32)
182
+ *
183
+ * cloudflare gfP2 stores {x=imaginary, y=real}, so:
184
+ * bytes[1:33] = X_imaginary (noble X.c1)
185
+ * bytes[33:65] = X_real (noble X.c0)
186
+ * bytes[65:97] = Y_imaginary (noble Y.c1)
187
+ * bytes[97:129] = Y_real (noble Y.c0)
188
+ */
189
+ export function g2FromBytes(bytes) {
190
+ if (bytes.length === 1 && bytes[0] === 0x00) {
191
+ return bn256.G2.ProjectivePoint.ZERO;
192
+ }
193
+ if (bytes.length !== 129 || bytes[0] !== 0x01)
194
+ throw new Error(`BN256 G2: expected 129 bytes (0x01 prefix), got ${bytes.length}`);
195
+ const xIm = bytesToBigInt(bytes.subarray(1, 33));
196
+ const xRe = bytesToBigInt(bytes.subarray(33, 65));
197
+ const yIm = bytesToBigInt(bytes.subarray(65, 97));
198
+ const yRe = bytesToBigInt(bytes.subarray(97, 129));
199
+ return bn256.G2.ProjectivePoint.fromAffine({
200
+ x: Fp2.fromBigTuple([xRe, xIm]),
201
+ y: Fp2.fromBigTuple([yRe, yIm]),
202
+ });
203
+ }
204
+ /** Scalar-multiply a G1 point: returns k·P. */
205
+ export function g1ScalarMult(P, k) {
206
+ return P.multiply(k);
207
+ }
208
+ /** Add two G1 points. */
209
+ export function g1Add(A, B) {
210
+ return A.add(B);
211
+ }
212
+ /**
213
+ * Compute the BN256 Ate pairing e(P, Q) → Fp12.
214
+ * Matches bn256.Pair() in Go.
215
+ */
216
+ export function atePairing(P, Q) {
217
+ return bn256.pairing(P, Q);
218
+ }
219
+ /** Check equality of two Fp12 elements. */
220
+ export function fp12Equal(a, b) {
221
+ return Fp12.eql(a, b);
222
+ }
223
+ /** Convert big-endian bytes to a bigint. */
224
+ export function bytesToBigInt(bytes) {
225
+ let result = 0n;
226
+ for (let i = 0; i < bytes.length; i++) {
227
+ result = (result << 8n) | BigInt(bytes[i] ?? 0);
228
+ }
229
+ return result;
230
+ }
231
+ //# sourceMappingURL=bn256.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bn256.js","sourceRoot":"","sources":["../src/bn256.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Challenge construction and deterministic derivation.
3
+ *
4
+ * Ports two Go functions exactly:
5
+ *
6
+ * DeriveChallenge() storage-proofs/line/chalderive.go
7
+ * blockHashG1() storage-proofs/por/sw/pub.go
8
+ *
9
+ * Any deviation from these implementations will produce challenges or
10
+ * verification paths that disagree with the server.
11
+ */
12
+ import { type G1Point } from './bn254.js';
13
+ /**
14
+ * BN254 (alt_bn128 / Ethereum) subgroup order q.
15
+ * = 21888242871839275222246405745257275088548364400416034343698204186575808495617
16
+ */
17
+ export declare const BN254_ORDER = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
18
+ /** Encode bytes to base64. */
19
+ export declare function uint8ToBase64(bytes: Uint8Array): string;
20
+ /** Decode a base64 string to bytes. */
21
+ export declare function base64ToBytes(b64: string): Uint8Array;
22
+ /**
23
+ * Build a SW-Pub challenge for POST /prove.
24
+ *
25
+ * Returns a base64-encoded JSON string matching wireChal in
26
+ * storage-proofs/line/swpub/adapter.go:
27
+ * { suite_id, seed, c, n }
28
+ *
29
+ * @param challengeSize Number of blocks to sample (≤ totalBlocks).
30
+ * @param totalBlocks Total blocks in the challenged store.
31
+ */
32
+ export declare function buildChallenge(challengeSize: number, totalBlocks: number): string;
33
+ /**
34
+ * Re-derive the challenge indices and blinding coefficients from a seed.
35
+ *
36
+ * Exact port of DeriveChallenge() in storage-proofs/line/chalderive.go (SuiteV1):
37
+ *
38
+ * idxKey = HMAC-SHA256(seed, "indices")
39
+ * coeffKey = HMAC-SHA256(seed, "coeffs")
40
+ * rank[i] = HMAC-SHA256(idxKey, ids[i]) → sort asc → first c positions
41
+ * coeff[t] = HMAC-SHA256(coeffKey, BE64(t)) mod BN254_ORDER
42
+ *
43
+ * Both challenger (browser) and prover (server) independently call this with
44
+ * the same (seed, ids) to agree on which blocks to challenge without any
45
+ * extra round-trip.
46
+ */
47
+ export declare function deriveIndicesAndCoeffs(seed: Uint8Array, ids: Uint8Array[], c: number): {
48
+ indices: number[];
49
+ coeffs: bigint[];
50
+ };
51
+ /**
52
+ * H(λ‖id) = HashToG1(λ‖id) using RFC 9380 SVDW.
53
+ *
54
+ * Exact port of blockHashG1() in storage-proofs/por/sw/pub.go.
55
+ * λ is the 16-byte file name from WireClientSetup.name; id is CID.Bytes().
56
+ * Uses DST "sw-pub-v1-BN254G1_XMD:SHA-256_SVDW_RO_" internally.
57
+ */
58
+ export declare function blockHashG1(name: Uint8Array, id: Uint8Array): G1Point;
59
+ //# sourceMappingURL=challenge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"challenge.d.ts","sourceRoot":"","sources":["../src/challenge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAA2B,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAEnE;;;GAGG;AACH,eAAO,MAAM,WAAW,iFACwD,CAAC;AAMjF,8BAA8B;AAC9B,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAIvD;AAED,uCAAuC;AACvC,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAKrD;AAMD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CASjF;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,UAAU,EAAE,EACjB,CAAC,EAAE,MAAM,GACR;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAoBzC;AAMD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,UAAU,GAAG,OAAO,CAKrE"}