@noble/curves 2.0.1 → 2.2.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 (110) hide show
  1. package/README.md +214 -122
  2. package/abstract/bls.d.ts +299 -16
  3. package/abstract/bls.d.ts.map +1 -1
  4. package/abstract/bls.js +82 -22
  5. package/abstract/bls.js.map +1 -1
  6. package/abstract/curve.d.ts +274 -27
  7. package/abstract/curve.d.ts.map +1 -1
  8. package/abstract/curve.js +177 -23
  9. package/abstract/curve.js.map +1 -1
  10. package/abstract/edwards.d.ts +166 -30
  11. package/abstract/edwards.d.ts.map +1 -1
  12. package/abstract/edwards.js +221 -86
  13. package/abstract/edwards.js.map +1 -1
  14. package/abstract/fft.d.ts +322 -10
  15. package/abstract/fft.d.ts.map +1 -1
  16. package/abstract/fft.js +154 -12
  17. package/abstract/fft.js.map +1 -1
  18. package/abstract/frost.d.ts +293 -0
  19. package/abstract/frost.d.ts.map +1 -0
  20. package/abstract/frost.js +704 -0
  21. package/abstract/frost.js.map +1 -0
  22. package/abstract/hash-to-curve.d.ts +173 -24
  23. package/abstract/hash-to-curve.d.ts.map +1 -1
  24. package/abstract/hash-to-curve.js +170 -31
  25. package/abstract/hash-to-curve.js.map +1 -1
  26. package/abstract/modular.d.ts +429 -37
  27. package/abstract/modular.d.ts.map +1 -1
  28. package/abstract/modular.js +414 -119
  29. package/abstract/modular.js.map +1 -1
  30. package/abstract/montgomery.d.ts +83 -12
  31. package/abstract/montgomery.d.ts.map +1 -1
  32. package/abstract/montgomery.js +32 -7
  33. package/abstract/montgomery.js.map +1 -1
  34. package/abstract/oprf.d.ts +164 -91
  35. package/abstract/oprf.d.ts.map +1 -1
  36. package/abstract/oprf.js +88 -29
  37. package/abstract/oprf.js.map +1 -1
  38. package/abstract/poseidon.d.ts +138 -7
  39. package/abstract/poseidon.d.ts.map +1 -1
  40. package/abstract/poseidon.js +178 -15
  41. package/abstract/poseidon.js.map +1 -1
  42. package/abstract/tower.d.ts +122 -3
  43. package/abstract/tower.d.ts.map +1 -1
  44. package/abstract/tower.js +323 -139
  45. package/abstract/tower.js.map +1 -1
  46. package/abstract/weierstrass.d.ts +339 -76
  47. package/abstract/weierstrass.d.ts.map +1 -1
  48. package/abstract/weierstrass.js +395 -205
  49. package/abstract/weierstrass.js.map +1 -1
  50. package/bls12-381.d.ts +16 -2
  51. package/bls12-381.d.ts.map +1 -1
  52. package/bls12-381.js +199 -209
  53. package/bls12-381.js.map +1 -1
  54. package/bn254.d.ts +11 -2
  55. package/bn254.d.ts.map +1 -1
  56. package/bn254.js +93 -38
  57. package/bn254.js.map +1 -1
  58. package/ed25519.d.ts +125 -14
  59. package/ed25519.d.ts.map +1 -1
  60. package/ed25519.js +202 -40
  61. package/ed25519.js.map +1 -1
  62. package/ed448.d.ts +108 -14
  63. package/ed448.d.ts.map +1 -1
  64. package/ed448.js +194 -42
  65. package/ed448.js.map +1 -1
  66. package/index.js +7 -1
  67. package/index.js.map +1 -1
  68. package/misc.d.ts +106 -7
  69. package/misc.d.ts.map +1 -1
  70. package/misc.js +141 -32
  71. package/misc.js.map +1 -1
  72. package/nist.d.ts +112 -11
  73. package/nist.d.ts.map +1 -1
  74. package/nist.js +139 -17
  75. package/nist.js.map +1 -1
  76. package/package.json +11 -6
  77. package/secp256k1.d.ts +92 -15
  78. package/secp256k1.d.ts.map +1 -1
  79. package/secp256k1.js +211 -28
  80. package/secp256k1.js.map +1 -1
  81. package/src/abstract/bls.ts +350 -67
  82. package/src/abstract/curve.ts +327 -44
  83. package/src/abstract/edwards.ts +367 -143
  84. package/src/abstract/fft.ts +369 -36
  85. package/src/abstract/frost.ts +1092 -0
  86. package/src/abstract/hash-to-curve.ts +255 -56
  87. package/src/abstract/modular.ts +591 -144
  88. package/src/abstract/montgomery.ts +114 -30
  89. package/src/abstract/oprf.ts +383 -194
  90. package/src/abstract/poseidon.ts +235 -35
  91. package/src/abstract/tower.ts +428 -159
  92. package/src/abstract/weierstrass.ts +710 -312
  93. package/src/bls12-381.ts +239 -236
  94. package/src/bn254.ts +107 -46
  95. package/src/ed25519.ts +227 -55
  96. package/src/ed448.ts +227 -57
  97. package/src/index.ts +7 -1
  98. package/src/misc.ts +154 -35
  99. package/src/nist.ts +143 -20
  100. package/src/secp256k1.ts +284 -41
  101. package/src/utils.ts +583 -81
  102. package/src/webcrypto.ts +302 -73
  103. package/utils.d.ts +457 -24
  104. package/utils.d.ts.map +1 -1
  105. package/utils.js +410 -53
  106. package/utils.js.map +1 -1
  107. package/webcrypto.d.ts +167 -25
  108. package/webcrypto.d.ts.map +1 -1
  109. package/webcrypto.js +165 -58
  110. package/webcrypto.js.map +1 -1
package/src/bn254.ts CHANGED
@@ -61,21 +61,27 @@ import {
61
61
  type BlsPostPrecomputePointAddFn,
62
62
  } from './abstract/bls.ts';
63
63
  import { Field, type IField } from './abstract/modular.ts';
64
- import type { Fp, Fp12, Fp2, Fp6 } from './abstract/tower.ts';
64
+ import type { Fp, Fp12, Fp2 } from './abstract/tower.ts';
65
65
  import { psiFrobenius, tower12 } from './abstract/tower.ts';
66
66
  import { weierstrass, type WeierstrassOpts } from './abstract/weierstrass.ts';
67
- import { bitLen } from './utils.ts';
67
+ import { bitLen, type TRet } from './utils.ts';
68
68
  // prettier-ignore
69
- const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3);
70
- const _6n = BigInt(6);
69
+ const _0n = /* @__PURE__ */ BigInt(0), _1n = /* @__PURE__ */ BigInt(1), _2n = /* @__PURE__ */ BigInt(2), _3n = /* @__PURE__ */ BigInt(3);
70
+ const _6n = /* @__PURE__ */ BigInt(6);
71
71
 
72
- const BN_X = BigInt('4965661367192848881');
73
- const BN_X_LEN = bitLen(BN_X);
74
- const SIX_X_SQUARED = _6n * BN_X ** _2n;
72
+ // Locally documented BN pairing seed. EIP-197 does not name this scalar
73
+ // directly; noble stores the positive value and derives any `-x` uses later.
74
+ const BN_X = /* @__PURE__ */ BigInt('4965661367192848881');
75
+ // Bit width of the stored seed itself, not the derived Miller-loop scalar `6x+2`.
76
+ const BN_X_LEN = /* @__PURE__ */ (() => bitLen(BN_X))();
77
+ // Derived scalar used by the optimized G2 subgroup test required by EIP-197.
78
+ const SIX_X_SQUARED = /* @__PURE__ */ (() => _6n * BN_X ** _2n)();
75
79
 
76
80
  const bn254_G1_CURVE: WeierstrassOpts<bigint> = {
77
81
  p: BigInt('0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47'),
78
82
  n: BigInt('0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001'),
83
+ // The Ethereum specs define G1 as prime-order but do not spell out the
84
+ // cofactor separately; `h = 1` is the implementation-derived value.
79
85
  h: _1n,
80
86
  a: _0n,
81
87
  b: _3n,
@@ -84,42 +90,74 @@ const bn254_G1_CURVE: WeierstrassOpts<bigint> = {
84
90
  };
85
91
 
86
92
  // r == n
87
- // Finite field over r. It's for convenience and is not used in the code below.
88
- export const bn254_Fr: IField<bigint> = Field(bn254_G1_CURVE.n);
93
+ // Finite field over r. It's for convenience and is not used in the code below,
94
+ // and its canonical `fromBytes()` decoder is stricter than the EIP-196 MUL
95
+ // scalar rule that accepts any 256-bit integer.
96
+ // These factories are side-effect free; mark them pure so single-export bundles can drop the rest.
97
+ /** bn254 scalar field. */
98
+ export const bn254_Fr: TRet<IField<bigint>> = /* @__PURE__ */ (() =>
99
+ Field(bn254_G1_CURVE.n) as TRet<IField<bigint>>)();
89
100
 
90
- // Fp2.div(Fp2.mul(Fp2.ONE, _3n), Fp2.NONRESIDUE)
91
- const Fp2B = {
101
+ // `3 / (i + 9)` from EIP-197, stored in noble's internal `(c0, c1) = (b, a)`
102
+ // order rather than the spec's `a * i + b` notation.
103
+ const Fp2B = /* @__PURE__ */ (() => ({
92
104
  c0: BigInt('19485874751759354771024239261021720505790618469301721065564631296452457478373'),
93
105
  c1: BigInt('266929791119991161246907387137283842545076965332900288569378510910307636690'),
94
- };
106
+ }))();
95
107
 
96
- const { Fp, Fp2, Fp6, Fp12 } = tower12({
97
- ORDER: bn254_G1_CURVE.p,
98
- X_LEN: BN_X_LEN,
99
- FP2_NONRESIDUE: [BigInt(9), _1n],
100
- Fp2mulByB: (num) => Fp2.mul(num, Fp2B),
101
- Fp12finalExponentiate: (num) => {
102
- const powMinusX = (num: Fp12) => Fp12.conjugate(Fp12._cyclotomicExp(num, BN_X));
103
- const r0 = Fp12.mul(Fp12.conjugate(num), Fp12.inv(num));
104
- const r = Fp12.mul(Fp12.frobeniusMap(r0, 2), r0);
105
- const y1 = Fp12._cyclotomicSquare(powMinusX(r));
106
- const y2 = Fp12.mul(Fp12._cyclotomicSquare(y1), y1);
107
- const y4 = powMinusX(y2);
108
- const y6 = powMinusX(Fp12._cyclotomicSquare(y4));
109
- const y8 = Fp12.mul(Fp12.mul(Fp12.conjugate(y6), y4), Fp12.conjugate(y2));
110
- const y9 = Fp12.mul(y8, y1);
111
- return Fp12.mul(
112
- Fp12.frobeniusMap(Fp12.mul(Fp12.conjugate(r), y9), 3),
113
- Fp12.mul(
114
- Fp12.frobeniusMap(y8, 2),
115
- Fp12.mul(Fp12.frobeniusMap(y9, 1), Fp12.mul(Fp12.mul(y8, y4), r))
116
- )
117
- );
118
- },
119
- });
108
+ // Bootstrap binding: `Fp12finalExponentiate` needs to reference the finished
109
+ // field object while `tower12(...)` is still constructing it.
110
+ let Fp12: ReturnType<typeof tower12>['Fp12'];
111
+ const tower = /* @__PURE__ */ (() => {
112
+ const res = tower12({
113
+ ORDER: bn254_G1_CURVE.p,
114
+ X_LEN: BN_X_LEN,
115
+ // Public `Fp2.NONRESIDUE` below is the sextic-tower seed `(9, 1)`, not the
116
+ // quadratic relation `i^2 + 1 = 0` from the EIP text.
117
+ FP2_NONRESIDUE: [BigInt(9), _1n],
118
+ Fp2mulByB: (num: Fp2) => Fp2.mul(num, Fp2B),
119
+ Fp12finalExponentiate: (num: Fp12) => {
120
+ const powMinusX = (num: Fp12) => Fp12.conjugate(Fp12._cyclotomicExp(num, BN_X));
121
+ const r0 = Fp12.mul(Fp12.conjugate(num), Fp12.inv(num));
122
+ const r = Fp12.mul(Fp12.frobeniusMap(r0, 2), r0);
123
+ const y1 = Fp12._cyclotomicSquare(powMinusX(r));
124
+ const y2 = Fp12.mul(Fp12._cyclotomicSquare(y1), y1);
125
+ const y4 = powMinusX(y2);
126
+ const y6 = powMinusX(Fp12._cyclotomicSquare(y4));
127
+ const y8 = Fp12.mul(Fp12.mul(Fp12.conjugate(y6), y4), Fp12.conjugate(y2));
128
+ const y9 = Fp12.mul(y8, y1);
129
+ return Fp12.mul(
130
+ Fp12.frobeniusMap(Fp12.mul(Fp12.conjugate(r), y9), 3),
131
+ Fp12.mul(
132
+ Fp12.frobeniusMap(y8, 2),
133
+ Fp12.mul(Fp12.frobeniusMap(y9, 1), Fp12.mul(Fp12.mul(y8, y4), r))
134
+ )
135
+ );
136
+ },
137
+ });
138
+ Fp12 = res.Fp12;
139
+ return res;
140
+ })();
141
+ const Fp = /* @__PURE__ */ (() => tower.Fp)();
142
+ const Fp2 = /* @__PURE__ */ (() => tower.Fp2)();
120
143
 
121
144
  // END OF CURVE FIELDS
122
- const { G2psi, psi } = psiFrobenius(Fp, Fp2, Fp2.NONRESIDUE);
145
+ // BN254 uses the same tower seed `(9, 1)` for the Frobenius helper that powers
146
+ // the divisive-twist G2 endomorphism.
147
+ let frob: ReturnType<typeof psiFrobenius> | undefined;
148
+ const getFrob = () => frob || (frob = psiFrobenius(Fp, Fp2, Fp2.NONRESIDUE));
149
+ // Eager psiFrobenius setup now dominates `bn254.js` import, so defer it to
150
+ // first use. After that these locals are rewritten to the direct helper refs.
151
+ let psi: ReturnType<typeof psiFrobenius>['psi'] = (x, y) => {
152
+ const fn = getFrob().psi;
153
+ psi = fn;
154
+ return fn(x, y);
155
+ };
156
+ let G2psi: ReturnType<typeof psiFrobenius>['G2psi'] = (c, P) => {
157
+ const fn = getFrob().G2psi;
158
+ G2psi = fn;
159
+ return fn(c, P);
160
+ };
123
161
 
124
162
  export const _postPrecompute: BlsPostPrecomputeFn = (
125
163
  Rx: Fp2,
@@ -136,9 +174,11 @@ export const _postPrecompute: BlsPostPrecomputeFn = (
136
174
  };
137
175
 
138
176
  // cofactor: (36 * X^4) + (36 * X^3) + (30 * X^2) + 6*X + 1
139
- const bn254_G2_CURVE: WeierstrassOpts<Fp2> = {
177
+ const bn254_G2_CURVE: WeierstrassOpts<Fp2> = /* @__PURE__ */ (() => ({
140
178
  p: Fp2.ORDER,
141
179
  n: bn254_G1_CURVE.n,
180
+ // As with G1, the Ethereum specs do not spell out the G2 cofactor
181
+ // separately; this literal is the implementation-derived value.
142
182
  h: BigInt('0x30644e72e131a029b85045b68181585e06ceecda572a2489345f2299c0f9fa8d'),
143
183
  a: Fp2.ZERO,
144
184
  b: Fp2B,
@@ -150,18 +190,24 @@ const bn254_G2_CURVE: WeierstrassOpts<Fp2> = {
150
190
  BigInt('8495653923123431417604973247489272438418190587263600148770280649306958101930'),
151
191
  BigInt('4082367875863433681332203403145435568316851327593401208105741076214120093531'),
152
192
  ]),
153
- };
193
+ }))();
154
194
 
155
- const fields = { Fp, Fp2, Fp6, Fp12, Fr: bn254_Fr };
156
- const bn254_G1 = weierstrass(bn254_G1_CURVE, {
195
+ const fields = /* @__PURE__ */ (() => ({ Fp, Fp2, Fp6: tower.Fp6, Fp12, Fr: bn254_Fr }))();
196
+ const bn254_G1 = /* @__PURE__ */ weierstrass(bn254_G1_CURVE, {
157
197
  Fp,
158
198
  Fn: bn254_Fr,
199
+ // Ethereum encodes infinity as `(0, 0)`, so the public point API accepts it
200
+ // even though it is not an affine curve point, and `fromAffine()` stays lazy:
201
+ // adversarial inputs still need `assertValidity()`.
159
202
  allowInfinityPoint: true,
160
203
  });
161
- const bn254_G2 = weierstrass(bn254_G2_CURVE, {
204
+ const bn254_G2 = /* @__PURE__ */ weierstrass(bn254_G2_CURVE, {
162
205
  Fp: Fp2,
163
206
  Fn: bn254_Fr,
207
+ // Ethereum encodes infinity as `((0, 0), (0, 0))`, so the public point API
208
+ // accepts it even though it is not an affine curve point.
164
209
  allowInfinityPoint: true,
210
+ // Optimized BN254 G2 subgroup test used to satisfy the EIP-197 order check.
165
211
  isTorsionFree: (c, P) => P.multiplyUnsafe(SIX_X_SQUARED).equals(G2psi(c, P)), // [p]P = [6X^2]P
166
212
  });
167
213
  /*
@@ -184,13 +230,16 @@ No hashToCurve for now (and signatures):
184
230
  // const hasherOpts = {
185
231
  // { ...htfDefaults, m: 1, DST: 'BN254G2_XMD:SHA-256_SVDW_RO_' }
186
232
  // };
187
- const bn254_params = {
233
+ const bn254_params = /* @__PURE__ */ (() => ({
234
+ // Optimal-ate Miller loop parameter derived from the positive BN seed.
188
235
  ateLoopSize: BN_X * _6n + _2n,
189
236
  r: bn254_Fr.ORDER,
190
237
  xNegative: false,
238
+ // EIP-197 writes G2 as `y^2 = x^3 + 3 / (i + 9)`, so the pairing
239
+ // configuration uses the divisive twist convention.
191
240
  twistType: 'divisive' as const,
192
241
  postPrecompute: _postPrecompute,
193
- };
242
+ }))();
194
243
  // const bn254_hasher = {
195
244
  // hasherOpts: htfDefaults,
196
245
  // hasherOptsG1: { m: 1, DST: 'BN254G2_XMD:SHA-256_SVDW_RO_' },
@@ -213,7 +262,19 @@ const bn254_params = {
213
262
 
214
263
  /**
215
264
  * bn254 (a.k.a. alt_bn128) pairing-friendly curve.
216
- * Contains G1 / G2 operations and pairings.
265
+ * Contains G1 / G2 operations and pairings only; the commented-out
266
+ * hash-to-curve and signature surface is intentionally not exposed here.
267
+ * @example
268
+ * Compute a pairing from the two generator points.
269
+ *
270
+ * ```ts
271
+ * const gt = bn254.pairing(bn254.G1.Point.BASE, bn254.G2.Point.BASE);
272
+ * ```
217
273
  */
218
274
  // bn254_hasher
219
- export const bn254: BlsCurvePair = blsBasic(fields, bn254_G1, bn254_G2, bn254_params);
275
+ export const bn254: BlsCurvePair = /* @__PURE__ */ blsBasic(
276
+ fields,
277
+ bn254_G1,
278
+ bn254_G2,
279
+ bn254_params
280
+ );