@noble/curves 0.3.1 → 0.4.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 (70) hide show
  1. package/README.md +2 -1
  2. package/lib/bls.d.ts +79 -0
  3. package/lib/bls.js +304 -0
  4. package/lib/edwards.d.ts +10 -6
  5. package/lib/edwards.js +16 -11
  6. package/lib/esm/bls.js +300 -0
  7. package/lib/esm/edwards.js +17 -12
  8. package/lib/esm/group.js +2 -2
  9. package/lib/esm/hashToCurve.js +105 -0
  10. package/lib/esm/modular.js +131 -50
  11. package/lib/esm/utils.js +25 -19
  12. package/lib/esm/weierstrass.js +351 -272
  13. package/lib/group.js +2 -2
  14. package/lib/hashToCurve.d.ts +13 -0
  15. package/lib/hashToCurve.js +112 -0
  16. package/lib/modular.d.ts +37 -17
  17. package/lib/modular.js +138 -54
  18. package/lib/utils.d.ts +28 -10
  19. package/lib/utils.js +31 -22
  20. package/lib/weierstrass.d.ts +106 -69
  21. package/lib/weierstrass.js +352 -272
  22. package/package.json +23 -44
  23. package/lib/crypto.d.ts +0 -4
  24. package/lib/crypto.js +0 -8
  25. package/lib/cryptoBrowser.d.ts +0 -4
  26. package/lib/cryptoBrowser.js +0 -7
  27. package/lib/definitions/_shortw_utils.d.ts +0 -63
  28. package/lib/definitions/_shortw_utils.js +0 -18
  29. package/lib/definitions/bn.d.ts +0 -7
  30. package/lib/definitions/bn.js +0 -23
  31. package/lib/definitions/ed25519.d.ts +0 -49
  32. package/lib/definitions/ed25519.js +0 -308
  33. package/lib/definitions/ed448.d.ts +0 -3
  34. package/lib/definitions/ed448.js +0 -127
  35. package/lib/definitions/index.d.ts +0 -0
  36. package/lib/definitions/index.js +0 -2
  37. package/lib/definitions/jubjub.d.ts +0 -7
  38. package/lib/definitions/jubjub.js +0 -55
  39. package/lib/definitions/p192.d.ts +0 -112
  40. package/lib/definitions/p192.js +0 -23
  41. package/lib/definitions/p224.d.ts +0 -112
  42. package/lib/definitions/p224.js +0 -24
  43. package/lib/definitions/p256.d.ts +0 -112
  44. package/lib/definitions/p256.js +0 -23
  45. package/lib/definitions/p384.d.ts +0 -112
  46. package/lib/definitions/p384.js +0 -24
  47. package/lib/definitions/p521.d.ts +0 -113
  48. package/lib/definitions/p521.js +0 -36
  49. package/lib/definitions/pasta.d.ts +0 -2
  50. package/lib/definitions/pasta.js +0 -32
  51. package/lib/definitions/secp256k1.d.ts +0 -87
  52. package/lib/definitions/secp256k1.js +0 -245
  53. package/lib/definitions/stark.d.ts +0 -62
  54. package/lib/definitions/stark.js +0 -248
  55. package/lib/esm/crypto.js +0 -5
  56. package/lib/esm/cryptoBrowser.js +0 -4
  57. package/lib/esm/definitions/_shortw_utils.js +0 -13
  58. package/lib/esm/definitions/bn.js +0 -20
  59. package/lib/esm/definitions/ed25519.js +0 -304
  60. package/lib/esm/definitions/ed448.js +0 -124
  61. package/lib/esm/definitions/index.js +0 -2
  62. package/lib/esm/definitions/jubjub.js +0 -50
  63. package/lib/esm/definitions/p192.js +0 -20
  64. package/lib/esm/definitions/p224.js +0 -21
  65. package/lib/esm/definitions/p256.js +0 -20
  66. package/lib/esm/definitions/p384.js +0 -21
  67. package/lib/esm/definitions/p521.js +0 -33
  68. package/lib/esm/definitions/pasta.js +0 -29
  69. package/lib/esm/definitions/secp256k1.js +0 -241
  70. package/lib/esm/definitions/stark.js +0 -227
@@ -2,7 +2,7 @@
2
2
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
3
3
  // Implementation of Short Weierstrass curve. The formula is: y² = x³ + ax + b
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.weierstrass = void 0;
5
+ exports.weierstrass = exports.weierstrassPoints = void 0;
6
6
  // TODO: sync vs async naming
7
7
  // TODO: default randomBytes
8
8
  // Differences from @noble/secp256k1 1.7:
@@ -12,41 +12,9 @@ exports.weierstrass = void 0;
12
12
  // 4. DRBG supports outputLen bigger than outputLen of hmac
13
13
  const mod = require("./modular.js");
14
14
  const utils_js_1 = require("./utils.js");
15
+ const utils = require("./utils.js");
16
+ const hashToCurve_js_1 = require("./hashToCurve.js");
15
17
  const group_js_1 = require("./group.js");
16
- // Should be separate from overrides, since overrides can use information about curve (for example nBits)
17
- function validateOpts(curve) {
18
- const opts = (0, utils_js_1.validateOpts)(curve);
19
- for (const i of ['a', 'b']) {
20
- if (typeof opts[i] !== 'bigint')
21
- throw new Error(`Invalid curve param ${i}=${opts[i]} (${typeof opts[i]})`);
22
- }
23
- for (const fn of ['hash', 'hmac']) {
24
- if (typeof opts[fn] !== 'function')
25
- throw new Error(`Invalid ${fn} function`);
26
- }
27
- for (const fn of ['randomBytes']) {
28
- if (opts[fn] === undefined)
29
- continue; // Optional
30
- if (typeof opts[fn] !== 'function')
31
- throw new Error(`Invalid ${fn} function`);
32
- }
33
- if (!Number.isSafeInteger(opts.hash.outputLen))
34
- throw new Error('Invalid hash function');
35
- const endo = opts.endo;
36
- if (endo) {
37
- if (opts.a !== _0n) {
38
- throw new Error('Endomorphism can only be defined for Koblitz curves that have a=0');
39
- }
40
- if (typeof endo !== 'object' ||
41
- typeof endo.beta !== 'bigint' ||
42
- typeof endo.splitScalar !== 'function') {
43
- throw new Error('Expected endomorphism with beta: bigint and splitScalar: function');
44
- }
45
- }
46
- // Set defaults
47
- return Object.freeze({ lowS: true, randomBytes: utils_js_1.randomBytes, ...opts });
48
- }
49
- // TODO: convert bits to bytes aligned to 32 bits? (224 for example)
50
18
  // DER encoding utilities
51
19
  class DERError extends Error {
52
20
  constructor(message) {
@@ -93,108 +61,73 @@ const _1n = BigInt(1);
93
61
  const _2n = BigInt(2);
94
62
  const _3n = BigInt(3);
95
63
  const _8n = BigInt(8);
96
- /**
97
- * Minimal HMAC-DRBG (NIST 800-90) for signatures.
98
- * Used only for RFC6979, does not fully implement DRBG spec.
99
- */
100
- class HmacDrbg {
101
- constructor(hashLen, qByteLen, hmacFn) {
102
- this.hashLen = hashLen;
103
- this.qByteLen = qByteLen;
104
- this.hmacFn = hmacFn;
105
- if (typeof hashLen !== 'number' || hashLen < 2)
106
- throw new Error('hashLen must be a number');
107
- if (typeof qByteLen !== 'number' || qByteLen < 2)
108
- throw new Error('qByteLen must be a number');
109
- if (typeof hmacFn !== 'function')
110
- throw new Error('hmacFn must be a function');
111
- // Step B, Step C: set hashLen to 8*ceil(hlen/8)
112
- this.v = new Uint8Array(hashLen).fill(1);
113
- this.k = new Uint8Array(hashLen).fill(0);
114
- this.counter = 0;
115
- }
116
- hmacSync(...values) {
117
- return this.hmacFn(this.k, ...values);
118
- }
119
- incr() {
120
- if (this.counter >= 1000)
121
- throw new Error('Tried 1,000 k values for sign(), all were invalid');
122
- this.counter += 1;
64
+ function validatePointOpts(curve) {
65
+ const opts = utils.validateOpts(curve);
66
+ const Fp = opts.Fp;
67
+ for (const i of ['a', 'b']) {
68
+ if (!Fp.isValid(curve[i]))
69
+ throw new Error(`Invalid curve param ${i}=${opts[i]} (${typeof opts[i]})`);
123
70
  }
124
- reseedSync(seed = new Uint8Array()) {
125
- this.k = this.hmacSync(this.v, Uint8Array.from([0x00]), seed);
126
- this.v = this.hmacSync(this.v);
127
- if (seed.length === 0)
128
- return;
129
- this.k = this.hmacSync(this.v, Uint8Array.from([0x01]), seed);
130
- this.v = this.hmacSync(this.v);
71
+ for (const i of ['isTorsionFree', 'clearCofactor', 'mapToCurve']) {
72
+ if (curve[i] === undefined)
73
+ continue; // Optional
74
+ if (typeof curve[i] !== 'function')
75
+ throw new Error(`Invalid ${i} function`);
131
76
  }
132
- // TODO: review
133
- generateSync() {
134
- this.incr();
135
- let len = 0;
136
- const out = [];
137
- while (len < this.qByteLen) {
138
- this.v = this.hmacSync(this.v);
139
- const sl = this.v.slice();
140
- out.push(sl);
141
- len += this.v.length;
77
+ const endo = opts.endo;
78
+ if (endo) {
79
+ if (!Fp.equals(opts.a, Fp.ZERO)) {
80
+ throw new Error('Endomorphism can only be defined for Koblitz curves that have a=0');
81
+ }
82
+ if (typeof endo !== 'object' ||
83
+ typeof endo.beta !== 'bigint' ||
84
+ typeof endo.splitScalar !== 'function') {
85
+ throw new Error('Expected endomorphism with beta: bigint and splitScalar: function');
142
86
  }
143
- return (0, utils_js_1.concatBytes)(...out);
144
87
  }
88
+ if (typeof opts.fromBytes !== 'function')
89
+ throw new Error('Invalid fromBytes function');
90
+ if (typeof opts.toBytes !== 'function')
91
+ throw new Error('Invalid fromBytes function');
92
+ // Requires including hashToCurve file
93
+ if (opts.htfDefaults !== undefined)
94
+ (0, hashToCurve_js_1.validateHTFOpts)(opts.htfDefaults);
95
+ // Set defaults
96
+ return Object.freeze({ ...opts });
145
97
  }
146
- // Use only input from curveOpts!
147
- function weierstrass(curveDef) {
148
- const CURVE = validateOpts(curveDef);
149
- const CURVE_ORDER = CURVE.n;
98
+ function weierstrassPoints(opts) {
99
+ const CURVE = validatePointOpts(opts);
100
+ const Fp = CURVE.Fp;
150
101
  // Lengths
151
102
  // All curves has same field / group length as for now, but it can be different for other curves
152
- const groupLen = CURVE.nByteLength;
153
- const fieldLen = CURVE.nByteLength; // 32 (length of one field element)
154
- if (fieldLen > 2048)
155
- throw new Error('Field lengths over 2048 are not supported');
156
- const compressedLen = fieldLen + 1; // 33
157
- const uncompressedLen = 2 * fieldLen + 1; // 65
103
+ const { nByteLength, nBitLength } = CURVE;
104
+ const groupLen = nByteLength;
158
105
  // Not using ** operator with bigints for old engines.
159
106
  // 2n ** (8n * 32n) == 2n << (8n * 32n - 1n)
160
- const FIELD_MASK = _2n << (_8n * BigInt(fieldLen) - _1n);
161
- function numToFieldStr(num) {
162
- if (typeof num !== 'bigint')
163
- throw new Error('Expected bigint');
164
- if (!(_0n <= num && num < FIELD_MASK))
165
- throw new Error(`Expected number < 2^${fieldLen * 8}`);
166
- return num.toString(16).padStart(2 * fieldLen, '0');
167
- }
168
- function numToField(num) {
169
- const b = (0, utils_js_1.hexToBytes)(numToFieldStr(num));
170
- if (b.length !== fieldLen)
171
- throw new Error(`Error: expected ${fieldLen} bytes`);
172
- return b;
173
- }
174
- function modP(n, m = CURVE.P) {
175
- return mod.mod(n, m);
176
- }
107
+ //const FIELD_MASK = _2n << (_8n * BigInt(fieldLen) - _1n);
108
+ // function numToFieldStr(num: bigint): string {
109
+ // if (typeof num !== 'bigint') throw new Error('Expected bigint');
110
+ // if (!(_0n <= num && num < FIELD_MASK)) throw new Error(`Expected number < 2^${fieldLen * 8}`);
111
+ // return num.toString(16).padStart(2 * fieldLen, '0');
112
+ // }
177
113
  /**
178
114
  * y² = x³ + ax + b: Short weierstrass curve formula
179
115
  * @returns y²
180
116
  */
181
117
  function weierstrassEquation(x) {
182
118
  const { a, b } = CURVE;
183
- const x2 = modP(x * x);
184
- const x3 = modP(x2 * x);
185
- return modP(x3 + a * x + b);
119
+ const x2 = Fp.square(x); // x * x
120
+ const x3 = Fp.multiply(x2, x); // x2 * x
121
+ return Fp.add(Fp.add(x3, Fp.multiply(x, a)), b); // x3 + a * x + b
186
122
  }
187
123
  function isWithinCurveOrder(num) {
188
124
  return _0n < num && num < CURVE.n;
189
125
  }
190
- function isValidFieldElement(num) {
191
- return _0n < num && num < CURVE.P;
192
- }
193
126
  function normalizePrivateKey(key) {
194
- let num;
195
127
  if (typeof CURVE.normalizePrivateKey === 'function') {
196
128
  key = CURVE.normalizePrivateKey(key);
197
129
  }
130
+ let num;
198
131
  if (typeof key === 'bigint') {
199
132
  num = key;
200
133
  }
@@ -214,32 +147,12 @@ function weierstrass(curveDef) {
214
147
  else {
215
148
  throw new TypeError('Expected valid private key');
216
149
  }
150
+ if (CURVE.wrapPrivateKey)
151
+ num = mod.mod(num, CURVE.n);
217
152
  if (!isWithinCurveOrder(num))
218
153
  throw new Error('Expected private key: 0 < key < n');
219
154
  return num;
220
155
  }
221
- /**
222
- * Normalizes hex, bytes, Point to Point. Checks for curve equation.
223
- */
224
- function normalizePublicKey(publicKey) {
225
- if (publicKey instanceof Point) {
226
- publicKey.assertValidity();
227
- return publicKey;
228
- }
229
- else if (publicKey instanceof Uint8Array || typeof publicKey === 'string') {
230
- return Point.fromHex(publicKey);
231
- // This can happen because PointType can be instance of different class
232
- }
233
- else
234
- throw new Error(`Unknown type of public key: ${publicKey}`);
235
- }
236
- function isBiggerThanHalfOrder(number) {
237
- const HALF = CURVE_ORDER >> _1n;
238
- return number > HALF;
239
- }
240
- function normalizeS(s) {
241
- return isBiggerThanHalfOrder(s) ? mod.mod(-s, CURVE_ORDER) : s;
242
- }
243
156
  function normalizeScalar(num) {
244
157
  if (typeof num === 'number' && Number.isSafeInteger(num) && num > 0)
245
158
  return BigInt(num);
@@ -247,20 +160,6 @@ function weierstrass(curveDef) {
247
160
  return num;
248
161
  throw new TypeError('Expected valid private scalar: 0 < scalar < curve.n');
249
162
  }
250
- const sqrtModCurve = CURVE.sqrtMod || mod.sqrt;
251
- // Ensures ECDSA message hashes are 32 bytes and < curve order
252
- function _truncateHash(hash, truncateOnly = false) {
253
- const { n, nBitLength } = CURVE;
254
- const byteLength = hash.length;
255
- const delta = byteLength * 8 - nBitLength; // size of curve.n (252 bits)
256
- let h = (0, utils_js_1.bytesToNumberBE)(hash);
257
- if (delta > 0)
258
- h = h >> BigInt(delta);
259
- if (!truncateOnly && h >= n)
260
- h -= n;
261
- return h;
262
- }
263
- const truncateHash = CURVE.truncateHash || _truncateHash;
264
163
  /**
265
164
  * Jacobian Point works in 3d / jacobi coordinates: (x, y, z) ∋ (x=x/z², y=y/z³)
266
165
  * Default Point works in 2d / affine coordinates: (x, y)
@@ -279,7 +178,7 @@ function weierstrass(curveDef) {
279
178
  // fromAffine(x:0, y:0) would produce (x:0, y:0, z:1), but we need (x:0, y:1, z:0)
280
179
  if (p.equals(Point.ZERO))
281
180
  return JacobianPoint.ZERO;
282
- return new JacobianPoint(p.x, p.y, _1n);
181
+ return new JacobianPoint(p.x, p.y, Fp.ONE);
283
182
  }
284
183
  /**
285
184
  * Takes a bunch of Jacobian Points but executes only one
@@ -287,7 +186,7 @@ function weierstrass(curveDef) {
287
186
  * so this improves performance massively.
288
187
  */
289
188
  static toAffineBatch(points) {
290
- const toInv = mod.invertBatch(points.map((p) => p.z), CURVE.P);
189
+ const toInv = Fp.invertBatch(points.map((p) => p.z));
291
190
  return points.map((p, i) => p.toAffine(toInv[i]));
292
191
  }
293
192
  static normalizeZ(points) {
@@ -301,19 +200,19 @@ function weierstrass(curveDef) {
301
200
  throw new TypeError('JacobianPoint expected');
302
201
  const { x: X1, y: Y1, z: Z1 } = this;
303
202
  const { x: X2, y: Y2, z: Z2 } = other;
304
- const Z1Z1 = modP(Z1 * Z1);
305
- const Z2Z2 = modP(Z2 * Z2);
306
- const U1 = modP(X1 * Z2Z2);
307
- const U2 = modP(X2 * Z1Z1);
308
- const S1 = modP(modP(Y1 * Z2) * Z2Z2);
309
- const S2 = modP(modP(Y2 * Z1) * Z1Z1);
310
- return U1 === U2 && S1 === S2;
203
+ const Z1Z1 = Fp.square(Z1); // Z1 * Z1
204
+ const Z2Z2 = Fp.square(Z2); // Z2 * Z2
205
+ const U1 = Fp.multiply(X1, Z2Z2); // X1 * Z2Z2
206
+ const U2 = Fp.multiply(X2, Z1Z1); // X2 * Z1Z1
207
+ const S1 = Fp.multiply(Fp.multiply(Y1, Z2), Z2Z2); // Y1 * Z2 * Z2Z2
208
+ const S2 = Fp.multiply(Fp.multiply(Y2, Z1), Z1Z1); // Y2 * Z1 * Z1Z1
209
+ return Fp.equals(U1, U2) && Fp.equals(S1, S2);
311
210
  }
312
211
  /**
313
212
  * Flips point to one corresponding to (x, -y) in Affine coordinates.
314
213
  */
315
214
  negate() {
316
- return new JacobianPoint(this.x, modP(-this.y), this.z);
215
+ return new JacobianPoint(this.x, Fp.negate(this.y), this.z);
317
216
  }
318
217
  // Fast algo for doubling 2 Jacobian Points.
319
218
  // From: https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-2007-bl
@@ -324,31 +223,31 @@ function weierstrass(curveDef) {
324
223
  // Faster algorithm: when a=0
325
224
  // From: https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
326
225
  // Cost: 2M + 5S + 6add + 3*2 + 1*3 + 1*8.
327
- if (a === _0n) {
328
- const A = modP(X1 * X1);
329
- const B = modP(Y1 * Y1);
330
- const C = modP(B * B);
331
- const x1b = X1 + B;
332
- const D = modP(_2n * (modP(x1b * x1b) - A - C));
333
- const E = modP(_3n * A);
334
- const F = modP(E * E);
335
- const X3 = modP(F - _2n * D);
336
- const Y3 = modP(E * (D - X3) - _8n * C);
337
- const Z3 = modP(_2n * Y1 * Z1);
226
+ if (Fp.isZero(a)) {
227
+ const A = Fp.square(X1); // X1 * X1
228
+ const B = Fp.square(Y1); // Y1 * Y1
229
+ const C = Fp.square(B); // B * B
230
+ const x1b = Fp.addN(X1, B); // X1 + B
231
+ const D = Fp.multiply(Fp.subtractN(Fp.subtractN(Fp.square(x1b), A), C), _2n); // ((x1b * x1b) - A - C) * 2
232
+ const E = Fp.multiply(A, _3n); // A * 3
233
+ const F = Fp.square(E); // E * E
234
+ const X3 = Fp.subtract(F, Fp.multiplyN(D, _2n)); // F - 2 * D
235
+ const Y3 = Fp.subtract(Fp.multiplyN(E, Fp.subtractN(D, X3)), Fp.multiplyN(C, _8n)); // E * (D - X3) - 8 * C;
236
+ const Z3 = Fp.multiply(Fp.multiplyN(Y1, _2n), Z1); // 2 * Y1 * Z1
338
237
  return new JacobianPoint(X3, Y3, Z3);
339
238
  }
340
- const XX = modP(X1 * X1);
341
- const YY = modP(Y1 * Y1);
342
- const YYYY = modP(YY * YY);
343
- const ZZ = modP(Z1 * Z1);
344
- const tmp1 = modP(X1 + YY);
345
- const S = modP(_2n * (modP(tmp1 * tmp1) - XX - YYYY)); // 2*((X1+YY)^2-XX-YYYY)
346
- const M = modP(_3n * XX + a * modP(ZZ * ZZ));
347
- const T = modP(modP(M * M) - _2n * S); // M^2-2*S
239
+ const XX = Fp.square(X1); // X1 * X1
240
+ const YY = Fp.square(Y1); // Y1 * Y1
241
+ const YYYY = Fp.square(YY); // YY * YY
242
+ const ZZ = Fp.square(Z1); // Z1 * Z1
243
+ const tmp1 = Fp.add(X1, YY); // X1 + YY
244
+ const S = Fp.multiply(Fp.subtractN(Fp.subtractN(Fp.square(tmp1), XX), YYYY), _2n); // 2*((X1+YY)^2-XX-YYYY)
245
+ const M = Fp.add(Fp.multiplyN(XX, _3n), Fp.multiplyN(Fp.square(ZZ), a)); // 3 * XX + a * ZZ^2
246
+ const T = Fp.subtract(Fp.square(M), Fp.multiplyN(S, _2n)); // M^2-2*S
348
247
  const X3 = T;
349
- const Y3 = modP(M * (S - T) - _8n * YYYY); // M*(S-T)-8*YYYY
350
- const y1az1 = modP(Y1 + Z1); // (Y1+Z1)
351
- const Z3 = modP(modP(y1az1 * y1az1) - YY - ZZ); // (Y1+Z1)^2-YY-ZZ
248
+ const Y3 = Fp.subtract(Fp.multiplyN(M, Fp.subtractN(S, T)), Fp.multiplyN(YYYY, _8n)); // M*(S-T)-8*YYYY
249
+ const y1az1 = Fp.add(Y1, Z1); // (Y1+Z1)
250
+ const Z3 = Fp.subtract(Fp.subtractN(Fp.square(y1az1), YY), ZZ); // (Y1+Z1)^2-YY-ZZ
352
251
  return new JacobianPoint(X3, Y3, Z3);
353
252
  }
354
253
  // Fast algo for adding 2 Jacobian Points.
@@ -360,28 +259,28 @@ function weierstrass(curveDef) {
360
259
  throw new TypeError('JacobianPoint expected');
361
260
  const { x: X1, y: Y1, z: Z1 } = this;
362
261
  const { x: X2, y: Y2, z: Z2 } = other;
363
- if (X2 === _0n || Y2 === _0n)
262
+ if (Fp.isZero(X2) || Fp.isZero(Y2))
364
263
  return this;
365
- if (X1 === _0n || Y1 === _0n)
264
+ if (Fp.isZero(X1) || Fp.isZero(Y1))
366
265
  return other;
367
266
  // We're using same code in equals()
368
- const Z1Z1 = modP(Z1 * Z1); // Z1Z1 = Z1^2
369
- const Z2Z2 = modP(Z2 * Z2); // Z2Z2 = Z2^2;
370
- const U1 = modP(X1 * Z2Z2); // X1 * Z2Z2
371
- const U2 = modP(X2 * Z1Z1); // X2 * Z1Z1
372
- const S1 = modP(modP(Y1 * Z2) * Z2Z2); // Y1 * Z2 * Z2Z2
373
- const S2 = modP(modP(Y2 * Z1) * Z1Z1); // Y2 * Z1 * Z1Z1
374
- const H = modP(U2 - U1); // H = U2 - U1
375
- const r = modP(S2 - S1); // S2 - S1
267
+ const Z1Z1 = Fp.square(Z1); // Z1Z1 = Z1^2
268
+ const Z2Z2 = Fp.square(Z2); // Z2Z2 = Z2^2;
269
+ const U1 = Fp.multiply(X1, Z2Z2); // X1 * Z2Z2
270
+ const U2 = Fp.multiply(X2, Z1Z1); // X2 * Z1Z1
271
+ const S1 = Fp.multiply(Fp.multiply(Y1, Z2), Z2Z2); // Y1 * Z2 * Z2Z2
272
+ const S2 = Fp.multiply(Fp.multiply(Y2, Z1), Z1Z1); // Y2 * Z1 * Z1Z1
273
+ const H = Fp.subtractN(U2, U1); // H = U2 - U1
274
+ const r = Fp.subtractN(S2, S1); // S2 - S1
376
275
  // H = 0 meaning it's the same point.
377
- if (H === _0n)
378
- return r === _0n ? this.double() : JacobianPoint.ZERO;
379
- const HH = modP(H * H); // HH = H2
380
- const HHH = modP(H * HH); // HHH = H * HH
381
- const V = modP(U1 * HH); // V = U1 * HH
382
- const X3 = modP(r * r - HHH - _2n * V); // X3 = r^2 - HHH - 2 * V;
383
- const Y3 = modP(r * (V - X3) - S1 * HHH); // Y3 = r * (V - X3) - S1 * HHH;
384
- const Z3 = modP(Z1 * Z2 * H); // Z3 = Z1 * Z2 * H;
276
+ if (Fp.isZero(H))
277
+ return Fp.isZero(r) ? this.double() : JacobianPoint.ZERO;
278
+ const HH = Fp.square(H); // HH = H2
279
+ const HHH = Fp.multiply(H, HH); // HHH = H * HH
280
+ const V = Fp.multiply(U1, HH); // V = U1 * HH
281
+ const X3 = Fp.subtract(Fp.subtractN(Fp.squareN(r), HHH), Fp.multiplyN(V, _2n)); // X3 = r^2 - HHH - 2 * V;
282
+ const Y3 = Fp.subtract(Fp.multiplyN(r, Fp.subtractN(V, X3)), Fp.multiplyN(S1, HHH)); // Y3 = r * (V - X3) - S1 * HHH;
283
+ const Z3 = Fp.multiply(Fp.multiply(Z1, Z2), H); // Z3 = Z1 * Z2 * H;
385
284
  return new JacobianPoint(X3, Y3, Z3);
386
285
  }
387
286
  subtract(other) {
@@ -420,7 +319,7 @@ function weierstrass(curveDef) {
420
319
  k1p = k1p.negate();
421
320
  if (k2neg)
422
321
  k2p = k2p.negate();
423
- k2p = new JacobianPoint(modP(k2p.x * CURVE.endo.beta), k2p.y, k2p.z);
322
+ k2p = new JacobianPoint(Fp.multiply(k2p.x, CURVE.endo.beta), k2p.y, k2p.z);
424
323
  return k1p.add(k2p);
425
324
  }
426
325
  /**
@@ -461,7 +360,7 @@ function weierstrass(curveDef) {
461
360
  let { p: k2p, f: f2p } = this.wNAF(k2, affinePoint);
462
361
  k1p = wnaf.constTimeNegate(k1neg, k1p);
463
362
  k2p = wnaf.constTimeNegate(k2neg, k2p);
464
- k2p = new JacobianPoint(modP(k2p.x * CURVE.endo.beta), k2p.y, k2p.z);
363
+ k2p = new JacobianPoint(Fp.multiply(k2p.x, CURVE.endo.beta), k2p.y, k2p.z);
465
364
  point = k1p.add(k2p);
466
365
  fake = f1p.add(f2p);
467
366
  }
@@ -481,25 +380,42 @@ function weierstrass(curveDef) {
481
380
  const { x, y, z } = this;
482
381
  const is0 = this.equals(JacobianPoint.ZERO);
483
382
  // If invZ was 0, we return zero point. However we still want to execute
484
- // all operations, so we replace invZ with a random number, 8.
383
+ // all operations, so we replace invZ with a random number, 1.
485
384
  if (invZ == null)
486
- invZ = is0 ? _8n : mod.invert(z, CURVE.P);
385
+ invZ = is0 ? Fp.ONE : Fp.invert(z);
487
386
  const iz1 = invZ;
488
- const iz2 = modP(iz1 * iz1);
489
- const iz3 = modP(iz2 * iz1);
490
- const ax = modP(x * iz2);
491
- const ay = modP(y * iz3);
492
- const zz = modP(z * iz1);
387
+ const iz2 = Fp.square(iz1); // iz1 * iz1
388
+ const iz3 = Fp.multiply(iz2, iz1); // iz2 * iz1
389
+ const ax = Fp.multiply(x, iz2); // x * iz2
390
+ const ay = Fp.multiply(y, iz3); // y * iz3
391
+ const zz = Fp.multiply(z, iz1); // z * iz1
493
392
  if (is0)
494
393
  return Point.ZERO;
495
- if (zz !== _1n)
394
+ if (!Fp.equals(zz, Fp.ONE))
496
395
  throw new Error('invZ was invalid');
497
396
  return new Point(ax, ay);
498
397
  }
398
+ isTorsionFree() {
399
+ if (CURVE.h === _1n)
400
+ return true; // No subgroups, always torsion fee
401
+ if (CURVE.isTorsionFree)
402
+ return CURVE.isTorsionFree(JacobianPoint, this);
403
+ // is multiplyUnsafe(CURVE.n) is always ok, same as for edwards?
404
+ throw new Error('Unsupported!');
405
+ }
406
+ // Clear cofactor of G1
407
+ // https://eprint.iacr.org/2019/403
408
+ clearCofactor() {
409
+ if (CURVE.h === _1n)
410
+ return this; // Fast-path
411
+ if (CURVE.clearCofactor)
412
+ return CURVE.clearCofactor(JacobianPoint, this);
413
+ return this.multiplyUnsafe(CURVE.h);
414
+ }
499
415
  }
500
- JacobianPoint.BASE = new JacobianPoint(CURVE.Gx, CURVE.Gy, _1n);
501
- JacobianPoint.ZERO = new JacobianPoint(_0n, _1n, _0n);
502
- const wnaf = (0, group_js_1.wNAF)(JacobianPoint, CURVE.endo ? CURVE.nBitLength / 2 : CURVE.nBitLength);
416
+ JacobianPoint.BASE = new JacobianPoint(CURVE.Gx, CURVE.Gy, Fp.ONE);
417
+ JacobianPoint.ZERO = new JacobianPoint(Fp.ZERO, Fp.ONE, Fp.ZERO);
418
+ const wnaf = (0, group_js_1.wNAF)(JacobianPoint, CURVE.endo ? nBitLength / 2 : nBitLength);
503
419
  // Stores precomputed values for points.
504
420
  const pointPrecomputes = new WeakMap();
505
421
  /**
@@ -517,87 +433,60 @@ function weierstrass(curveDef) {
517
433
  }
518
434
  // Checks for y % 2 == 0
519
435
  hasEvenY() {
520
- return this.y % _2n === _0n;
521
- }
522
- /**
523
- * Supports compressed ECDSA points
524
- * @returns Point instance
525
- */
526
- static fromCompressedHex(bytes) {
527
- const P = CURVE.P;
528
- const x = (0, utils_js_1.bytesToNumberBE)(bytes.subarray(1));
529
- if (!isValidFieldElement(x))
530
- throw new Error('Point is not on curve');
531
- const y2 = weierstrassEquation(x); // y² = x³ + ax + b
532
- let y = sqrtModCurve(y2, P); // y = y² ^ (p+1)/4
533
- const isYOdd = (y & _1n) === _1n;
534
- // ECDSA
535
- const isFirstByteOdd = (bytes[0] & 1) === 1;
536
- if (isFirstByteOdd !== isYOdd)
537
- y = modP(-y);
538
- const point = new Point(x, y);
539
- point.assertValidity();
540
- return point;
541
- }
542
- static fromUncompressedHex(bytes) {
543
- const x = (0, utils_js_1.bytesToNumberBE)(bytes.subarray(1, fieldLen + 1));
544
- const y = (0, utils_js_1.bytesToNumberBE)(bytes.subarray(fieldLen + 1, 2 * fieldLen + 1));
545
- const point = new Point(x, y);
546
- point.assertValidity();
547
- return point;
436
+ if (Fp.isOdd)
437
+ return !Fp.isOdd(this.y);
438
+ throw new Error("Field doesn't support isOdd");
548
439
  }
549
440
  /**
550
441
  * Converts hash string or Uint8Array to Point.
551
442
  * @param hex short/long ECDSA hex
552
443
  */
553
444
  static fromHex(hex) {
554
- const bytes = (0, utils_js_1.ensureBytes)(hex);
555
- const len = bytes.length;
556
- const header = bytes[0];
557
- // this.assertValidity() is done inside of those two functions
558
- if (len === compressedLen && (header === 0x02 || header === 0x03))
559
- return this.fromCompressedHex(bytes);
560
- if (len === uncompressedLen && header === 0x04)
561
- return this.fromUncompressedHex(bytes);
562
- throw new Error(`Point.fromHex: received invalid point. Expected ${compressedLen} compressed bytes or ${uncompressedLen} uncompressed bytes, not ${len}`);
445
+ const { x, y } = CURVE.fromBytes((0, utils_js_1.ensureBytes)(hex));
446
+ const point = new Point(x, y);
447
+ point.assertValidity();
448
+ return point;
563
449
  }
564
450
  // Multiplies generator point by privateKey.
565
451
  static fromPrivateKey(privateKey) {
566
452
  return Point.BASE.multiply(normalizePrivateKey(privateKey));
567
453
  }
568
454
  toRawBytes(isCompressed = false) {
569
- return (0, utils_js_1.hexToBytes)(this.toHex(isCompressed));
455
+ this.assertValidity();
456
+ return CURVE.toBytes(Point, this, isCompressed);
570
457
  }
571
458
  toHex(isCompressed = false) {
572
- const x = numToFieldStr(this.x);
573
- if (isCompressed) {
574
- const prefix = this.hasEvenY() ? '02' : '03';
575
- return `${prefix}${x}`;
576
- }
577
- else {
578
- return `04${x}${numToFieldStr(this.y)}`;
579
- }
459
+ return (0, utils_js_1.bytesToHex)(this.toRawBytes(isCompressed));
580
460
  }
581
461
  // A point on curve is valid if it conforms to equation.
582
462
  assertValidity() {
463
+ // Zero is valid point too!
464
+ if (this.equals(Point.ZERO)) {
465
+ if (CURVE.allowInfinityPoint)
466
+ return;
467
+ throw new Error('Point is infinity');
468
+ }
583
469
  // Some 3rd-party test vectors require different wording between here & `fromCompressedHex`
584
470
  const msg = 'Point is not on elliptic curve';
585
471
  const { x, y } = this;
586
- if (!isValidFieldElement(x) || !isValidFieldElement(y))
472
+ if (!Fp.isValid(x) || !Fp.isValid(y))
587
473
  throw new Error(msg);
588
- const left = modP(y * y);
474
+ const left = Fp.square(y);
589
475
  const right = weierstrassEquation(x);
590
- if (modP(left - right) !== _0n)
476
+ if (!Fp.equals(left, right))
591
477
  throw new Error(msg);
478
+ // TODO: flag to disable this?
479
+ if (!this.isTorsionFree())
480
+ throw new Error('Point must be of prime-order subgroup');
592
481
  }
593
482
  equals(other) {
594
483
  if (!(other instanceof Point))
595
484
  throw new TypeError('Point#equals: expected Point');
596
- return this.x === other.x && this.y === other.y;
485
+ return Fp.equals(this.x, other.x) && Fp.equals(this.y, other.y);
597
486
  }
598
487
  // Returns the same point with inverted `y`
599
488
  negate() {
600
- return new Point(this.x, modP(-this.y));
489
+ return new Point(this.x, Fp.negate(this.y));
601
490
  }
602
491
  // Adds point to itself
603
492
  double() {
@@ -614,6 +503,15 @@ function weierstrass(curveDef) {
614
503
  multiply(scalar) {
615
504
  return JacobianPoint.fromAffine(this).multiply(scalar, this).toAffine();
616
505
  }
506
+ multiplyUnsafe(scalar) {
507
+ return JacobianPoint.fromAffine(this).multiplyUnsafe(scalar).toAffine();
508
+ }
509
+ clearCofactor() {
510
+ return JacobianPoint.fromAffine(this).clearCofactor().toAffine();
511
+ }
512
+ isTorsionFree() {
513
+ return JacobianPoint.fromAffine(this).isTorsionFree();
514
+ }
617
515
  /**
618
516
  * Efficiently calculate `aP + bQ`.
619
517
  * Unsafe, can expose private key, if used incorrectly.
@@ -627,6 +525,27 @@ function weierstrass(curveDef) {
627
525
  const sum = aP.add(bQ);
628
526
  return sum.equals(JacobianPoint.ZERO) ? undefined : sum.toAffine();
629
527
  }
528
+ // Encodes byte string to elliptic curve
529
+ // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-3
530
+ static hashToCurve(msg, options) {
531
+ if (!CURVE.mapToCurve)
532
+ throw new Error('No mapToCurve defined for curve');
533
+ msg = (0, utils_js_1.ensureBytes)(msg);
534
+ const u = (0, hashToCurve_js_1.hash_to_field)(msg, 2, { ...CURVE.htfDefaults, ...options });
535
+ const { x: x0, y: y0 } = CURVE.mapToCurve(u[0]);
536
+ const { x: x1, y: y1 } = CURVE.mapToCurve(u[1]);
537
+ const p = new Point(x0, y0).add(new Point(x1, y1)).clearCofactor();
538
+ return p;
539
+ }
540
+ // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16#section-3
541
+ static encodeToCurve(msg, options) {
542
+ if (!CURVE.mapToCurve)
543
+ throw new Error('No mapToCurve defined for curve');
544
+ msg = (0, utils_js_1.ensureBytes)(msg);
545
+ const u = (0, hashToCurve_js_1.hash_to_field)(msg, 1, { ...CURVE.htfDefaults, ...options });
546
+ const { x, y } = CURVE.mapToCurve(u[0]);
547
+ return new Point(x, y).clearCofactor();
548
+ }
630
549
  }
631
550
  /**
632
551
  * Base point aka generator. public_key = Point.BASE * private_key
@@ -635,7 +554,168 @@ function weierstrass(curveDef) {
635
554
  /**
636
555
  * Identity point aka point at infinity. point = point + zero_point
637
556
  */
638
- Point.ZERO = new Point(_0n, _0n);
557
+ Point.ZERO = new Point(Fp.ZERO, Fp.ZERO);
558
+ return {
559
+ Point: Point,
560
+ JacobianPoint: JacobianPoint,
561
+ normalizePrivateKey,
562
+ weierstrassEquation,
563
+ isWithinCurveOrder,
564
+ };
565
+ }
566
+ exports.weierstrassPoints = weierstrassPoints;
567
+ function validateOpts(curve) {
568
+ const opts = utils.validateOpts(curve);
569
+ if (typeof opts.hash !== 'function' || !Number.isSafeInteger(opts.hash.outputLen))
570
+ throw new Error('Invalid hash function');
571
+ if (typeof opts.hmac !== 'function')
572
+ throw new Error('Invalid hmac function');
573
+ if (typeof opts.randomBytes !== 'function')
574
+ throw new Error('Invalid randomBytes function');
575
+ // Set defaults
576
+ return Object.freeze({ lowS: true, ...opts });
577
+ }
578
+ /**
579
+ * Minimal HMAC-DRBG (NIST 800-90) for signatures.
580
+ * Used only for RFC6979, does not fully implement DRBG spec.
581
+ */
582
+ class HmacDrbg {
583
+ constructor(hashLen, qByteLen, hmacFn) {
584
+ this.hashLen = hashLen;
585
+ this.qByteLen = qByteLen;
586
+ this.hmacFn = hmacFn;
587
+ if (typeof hashLen !== 'number' || hashLen < 2)
588
+ throw new Error('hashLen must be a number');
589
+ if (typeof qByteLen !== 'number' || qByteLen < 2)
590
+ throw new Error('qByteLen must be a number');
591
+ if (typeof hmacFn !== 'function')
592
+ throw new Error('hmacFn must be a function');
593
+ // Step B, Step C: set hashLen to 8*ceil(hlen/8)
594
+ this.v = new Uint8Array(hashLen).fill(1);
595
+ this.k = new Uint8Array(hashLen).fill(0);
596
+ this.counter = 0;
597
+ }
598
+ hmacSync(...values) {
599
+ return this.hmacFn(this.k, ...values);
600
+ }
601
+ incr() {
602
+ if (this.counter >= 1000)
603
+ throw new Error('Tried 1,000 k values for sign(), all were invalid');
604
+ this.counter += 1;
605
+ }
606
+ reseedSync(seed = new Uint8Array()) {
607
+ this.k = this.hmacSync(this.v, Uint8Array.from([0x00]), seed);
608
+ this.v = this.hmacSync(this.v);
609
+ if (seed.length === 0)
610
+ return;
611
+ this.k = this.hmacSync(this.v, Uint8Array.from([0x01]), seed);
612
+ this.v = this.hmacSync(this.v);
613
+ }
614
+ // TODO: review
615
+ generateSync() {
616
+ this.incr();
617
+ let len = 0;
618
+ const out = [];
619
+ while (len < this.qByteLen) {
620
+ this.v = this.hmacSync(this.v);
621
+ const sl = this.v.slice();
622
+ out.push(sl);
623
+ len += this.v.length;
624
+ }
625
+ return (0, utils_js_1.concatBytes)(...out);
626
+ }
627
+ }
628
+ function weierstrass(curveDef) {
629
+ const CURVE = validateOpts(curveDef);
630
+ const CURVE_ORDER = CURVE.n;
631
+ const Fp = CURVE.Fp;
632
+ const compressedLen = Fp.BYTES + 1; // 33
633
+ const uncompressedLen = 2 * Fp.BYTES + 1; // 65
634
+ function isValidFieldElement(num) {
635
+ // 0 is disallowed by arbitrary reasons. Probably because infinity point?
636
+ return _0n < num && num < Fp.ORDER;
637
+ }
638
+ const { Point, JacobianPoint, normalizePrivateKey, weierstrassEquation, isWithinCurveOrder } = weierstrassPoints({
639
+ ...CURVE,
640
+ toBytes(c, point, isCompressed) {
641
+ if (isCompressed) {
642
+ return (0, utils_js_1.concatBytes)(new Uint8Array([point.hasEvenY() ? 0x02 : 0x03]), Fp.toBytes(point.x));
643
+ }
644
+ else {
645
+ return (0, utils_js_1.concatBytes)(new Uint8Array([0x04]), Fp.toBytes(point.x), Fp.toBytes(point.y));
646
+ }
647
+ },
648
+ fromBytes(bytes) {
649
+ const len = bytes.length;
650
+ const header = bytes[0];
651
+ // this.assertValidity() is done inside of fromHex
652
+ if (len === compressedLen && (header === 0x02 || header === 0x03)) {
653
+ const x = (0, utils_js_1.bytesToNumberBE)(bytes.subarray(1));
654
+ if (!isValidFieldElement(x))
655
+ throw new Error('Point is not on curve');
656
+ const y2 = weierstrassEquation(x); // y² = x³ + ax + b
657
+ let y = Fp.sqrt(y2); // y = y² ^ (p+1)/4
658
+ const isYOdd = (y & _1n) === _1n;
659
+ // ECDSA
660
+ const isFirstByteOdd = (bytes[0] & 1) === 1;
661
+ if (isFirstByteOdd !== isYOdd)
662
+ y = Fp.negate(y);
663
+ return { x, y };
664
+ }
665
+ else if (len === uncompressedLen && header === 0x04) {
666
+ const x = Fp.fromBytes(bytes.subarray(1, Fp.BYTES + 1));
667
+ const y = Fp.fromBytes(bytes.subarray(Fp.BYTES + 1, 2 * Fp.BYTES + 1));
668
+ return { x, y };
669
+ }
670
+ else {
671
+ throw new Error(`Point.fromHex: received invalid point. Expected ${compressedLen} compressed bytes or ${uncompressedLen} uncompressed bytes, not ${len}`);
672
+ }
673
+ },
674
+ });
675
+ // Do we need these functions at all?
676
+ function numToField(num) {
677
+ if (typeof num !== 'bigint')
678
+ throw new Error('Expected bigint');
679
+ if (!(_0n <= num && num < Fp.MASK))
680
+ throw new Error(`Expected number < 2^${Fp.BYTES * 8}`);
681
+ return Fp.toBytes(num);
682
+ }
683
+ const numToFieldStr = (num) => (0, utils_js_1.bytesToHex)(numToField(num));
684
+ /**
685
+ * Normalizes hex, bytes, Point to Point. Checks for curve equation.
686
+ */
687
+ function normalizePublicKey(publicKey) {
688
+ if (publicKey instanceof Point) {
689
+ publicKey.assertValidity();
690
+ return publicKey;
691
+ }
692
+ else if (publicKey instanceof Uint8Array || typeof publicKey === 'string') {
693
+ return Point.fromHex(publicKey);
694
+ // This can happen because PointType can be instance of different class
695
+ }
696
+ else
697
+ throw new Error(`Unknown type of public key: ${publicKey}`);
698
+ }
699
+ function isBiggerThanHalfOrder(number) {
700
+ const HALF = CURVE_ORDER >> _1n;
701
+ return number > HALF;
702
+ }
703
+ function normalizeS(s) {
704
+ return isBiggerThanHalfOrder(s) ? mod.mod(-s, CURVE_ORDER) : s;
705
+ }
706
+ // Ensures ECDSA message hashes are 32 bytes and < curve order
707
+ function _truncateHash(hash, truncateOnly = false) {
708
+ const { n, nBitLength } = CURVE;
709
+ const byteLength = hash.length;
710
+ const delta = byteLength * 8 - nBitLength; // size of curve.n (252 bits)
711
+ let h = (0, utils_js_1.bytesToNumberBE)(hash);
712
+ if (delta > 0)
713
+ h = h >> BigInt(delta);
714
+ if (!truncateOnly && h >= n)
715
+ h -= n;
716
+ return h;
717
+ }
718
+ const truncateHash = CURVE.truncateHash || _truncateHash;
639
719
  /**
640
720
  * ECDSA signature with its (r, s) properties. Supports DER & compact representations.
641
721
  */
@@ -746,8 +826,8 @@ function weierstrass(curveDef) {
746
826
  }
747
827
  }
748
828
  const utils = {
749
- mod: modP,
750
- invert: (n, m = CURVE.P) => mod.invert(n, m),
829
+ mod: (n, modulo = Fp.ORDER) => mod.mod(n, modulo),
830
+ invert: Fp.invert,
751
831
  isValidPrivateKey(privateKey) {
752
832
  try {
753
833
  normalizePrivateKey(privateKey);
@@ -772,7 +852,7 @@ function weierstrass(curveDef) {
772
852
  * Produces cryptographically secure private key from random of size (nBitLength+64)
773
853
  * as per FIPS 186 B.4.1 with modulo bias being neglible.
774
854
  */
775
- randomPrivateKey: () => utils.hashToPrivateKey(CURVE.randomBytes(fieldLen + 8)),
855
+ randomPrivateKey: () => utils.hashToPrivateKey(CURVE.randomBytes(Fp.BYTES + 8)),
776
856
  /**
777
857
  * 1. Returns cached point which you can use to pass to `getSharedSecret` or `#multiply` by it.
778
858
  * 2. Precomputes point multiplication table. Is done by default on first `getPublicKey()` call.
@@ -832,7 +912,7 @@ function weierstrass(curveDef) {
832
912
  }
833
913
  // RFC6979 methods
834
914
  function bits2int(bytes) {
835
- const slice = bytes.length > fieldLen ? bytes.slice(0, fieldLen) : bytes;
915
+ const slice = bytes.length > Fp.BYTES ? bytes.slice(0, Fp.BYTES) : bytes;
836
916
  return (0, utils_js_1.bytesToNumberBE)(slice);
837
917
  }
838
918
  function bits2octets(bytes) {
@@ -856,10 +936,10 @@ function weierstrass(curveDef) {
856
936
  // RFC6979 3.6: additional k' could be provided
857
937
  if (extraEntropy != null) {
858
938
  if (extraEntropy === true)
859
- extraEntropy = CURVE.randomBytes(fieldLen);
939
+ extraEntropy = CURVE.randomBytes(Fp.BYTES);
860
940
  const e = (0, utils_js_1.ensureBytes)(extraEntropy);
861
- if (e.length !== fieldLen)
862
- throw new Error(`sign: Expected ${fieldLen} bytes of extra data`);
941
+ if (e.length !== Fp.BYTES)
942
+ throw new Error(`sign: Expected ${Fp.BYTES} bytes of extra data`);
863
943
  seedArgs.push(e);
864
944
  }
865
945
  // seed is constructed from private key and message