@noble/curves 0.5.2 → 0.6.1

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/README.md +115 -41
  2. package/lib/_shortw_utils.d.ts +13 -24
  3. package/lib/abstract/bls.d.ts +39 -32
  4. package/lib/abstract/bls.js +74 -73
  5. package/lib/abstract/{group.d.ts → curve.d.ts} +30 -1
  6. package/lib/abstract/{group.js → curve.js} +33 -2
  7. package/lib/abstract/edwards.d.ts +30 -72
  8. package/lib/abstract/edwards.js +206 -389
  9. package/lib/abstract/hash-to-curve.d.ts +25 -6
  10. package/lib/abstract/hash-to-curve.js +40 -12
  11. package/lib/abstract/modular.d.ts +21 -8
  12. package/lib/abstract/modular.js +72 -48
  13. package/lib/abstract/montgomery.js +23 -68
  14. package/lib/abstract/poseidon.d.ts +29 -0
  15. package/lib/abstract/poseidon.js +115 -0
  16. package/lib/abstract/utils.d.ts +9 -37
  17. package/lib/abstract/utils.js +61 -87
  18. package/lib/abstract/weierstrass.d.ts +58 -81
  19. package/lib/abstract/weierstrass.js +485 -679
  20. package/lib/bls12-381.js +63 -58
  21. package/lib/bn.js +1 -1
  22. package/lib/ed25519.d.ts +7 -5
  23. package/lib/ed25519.js +82 -79
  24. package/lib/ed448.d.ts +3 -0
  25. package/lib/ed448.js +86 -83
  26. package/lib/esm/abstract/bls.js +75 -74
  27. package/lib/esm/abstract/{group.js → curve.js} +31 -1
  28. package/lib/esm/abstract/edwards.js +204 -387
  29. package/lib/esm/abstract/hash-to-curve.js +38 -11
  30. package/lib/esm/abstract/modular.js +69 -47
  31. package/lib/esm/abstract/montgomery.js +24 -69
  32. package/lib/esm/abstract/poseidon.js +109 -0
  33. package/lib/esm/abstract/utils.js +58 -82
  34. package/lib/esm/abstract/weierstrass.js +484 -678
  35. package/lib/esm/bls12-381.js +75 -70
  36. package/lib/esm/bn.js +1 -1
  37. package/lib/esm/ed25519.js +80 -78
  38. package/lib/esm/ed448.js +84 -82
  39. package/lib/esm/jubjub.js +1 -1
  40. package/lib/esm/p224.js +1 -1
  41. package/lib/esm/p256.js +11 -9
  42. package/lib/esm/p384.js +11 -9
  43. package/lib/esm/p521.js +12 -23
  44. package/lib/esm/secp256k1.js +124 -162
  45. package/lib/esm/stark.js +105 -41
  46. package/lib/jubjub.d.ts +2 -2
  47. package/lib/jubjub.js +1 -1
  48. package/lib/p192.d.ts +26 -48
  49. package/lib/p224.d.ts +26 -48
  50. package/lib/p224.js +1 -1
  51. package/lib/p256.d.ts +29 -48
  52. package/lib/p256.js +13 -10
  53. package/lib/p384.d.ts +29 -48
  54. package/lib/p384.js +13 -10
  55. package/lib/p521.d.ts +37 -57
  56. package/lib/p521.js +14 -24
  57. package/lib/secp256k1.d.ts +37 -46
  58. package/lib/secp256k1.js +124 -162
  59. package/lib/stark.d.ts +39 -22
  60. package/lib/stark.js +108 -41
  61. package/package.json +15 -10
@@ -1,17 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.bls = void 0;
4
- const ut = require("./utils.js");
5
- const hash_to_curve_js_1 = require("./hash-to-curve.js");
4
+ const modular_js_1 = require("./modular.js");
5
+ const utils_js_1 = require("./utils.js");
6
+ const htf = require("./hash-to-curve.js");
6
7
  const weierstrass_js_1 = require("./weierstrass.js");
7
8
  function bls(CURVE) {
8
9
  // Fields looks pretty specific for curve, so for now we need to pass them with options
9
10
  const { Fp, Fr, Fp2, Fp6, Fp12 } = CURVE;
10
- const BLS_X_LEN = ut.bitLen(CURVE.x);
11
+ const BLS_X_LEN = (0, utils_js_1.bitLen)(CURVE.x);
11
12
  const groupLen = 32; // TODO: calculate; hardcoded for now
12
13
  // Pre-compute coefficients for sparse multiplication
13
14
  // Point addition and point double calculations is reused for coefficients
14
- function calcPairingPrecomputes(x, y) {
15
+ function calcPairingPrecomputes(p) {
16
+ const { x, y } = p;
15
17
  // prettier-ignore
16
18
  const Qx = x, Qy = y, Qz = Fp2.ONE;
17
19
  // prettier-ignore
@@ -19,32 +21,32 @@ function bls(CURVE) {
19
21
  let ell_coeff = [];
20
22
  for (let i = BLS_X_LEN - 2; i >= 0; i--) {
21
23
  // Double
22
- let t0 = Fp2.square(Ry); // Ry²
23
- let t1 = Fp2.square(Rz); // Rz²
24
+ let t0 = Fp2.sqr(Ry); // Ry²
25
+ let t1 = Fp2.sqr(Rz); // Rz²
24
26
  let t2 = Fp2.multiplyByB(Fp2.mul(t1, 3n)); // 3 * T1 * B
25
27
  let t3 = Fp2.mul(t2, 3n); // 3 * T2
26
- let t4 = Fp2.sub(Fp2.sub(Fp2.square(Fp2.add(Ry, Rz)), t1), t0); // (Ry + Rz)² - T1 - T0
28
+ let t4 = Fp2.sub(Fp2.sub(Fp2.sqr(Fp2.add(Ry, Rz)), t1), t0); // (Ry + Rz)² - T1 - T0
27
29
  ell_coeff.push([
28
30
  Fp2.sub(t2, t0),
29
- Fp2.mul(Fp2.square(Rx), 3n),
30
- Fp2.negate(t4), // -T4
31
+ Fp2.mul(Fp2.sqr(Rx), 3n),
32
+ Fp2.neg(t4), // -T4
31
33
  ]);
32
34
  Rx = Fp2.div(Fp2.mul(Fp2.mul(Fp2.sub(t0, t3), Rx), Ry), 2n); // ((T0 - T3) * Rx * Ry) / 2
33
- Ry = Fp2.sub(Fp2.square(Fp2.div(Fp2.add(t0, t3), 2n)), Fp2.mul(Fp2.square(t2), 3n)); // ((T0 + T3) / 2)² - 3 * T2²
35
+ Ry = Fp2.sub(Fp2.sqr(Fp2.div(Fp2.add(t0, t3), 2n)), Fp2.mul(Fp2.sqr(t2), 3n)); // ((T0 + T3) / 2)² - 3 * T2²
34
36
  Rz = Fp2.mul(t0, t4); // T0 * T4
35
- if (ut.bitGet(CURVE.x, i)) {
37
+ if ((0, utils_js_1.bitGet)(CURVE.x, i)) {
36
38
  // Addition
37
39
  let t0 = Fp2.sub(Ry, Fp2.mul(Qy, Rz)); // Ry - Qy * Rz
38
40
  let t1 = Fp2.sub(Rx, Fp2.mul(Qx, Rz)); // Rx - Qx * Rz
39
41
  ell_coeff.push([
40
42
  Fp2.sub(Fp2.mul(t0, Qx), Fp2.mul(t1, Qy)),
41
- Fp2.negate(t0),
43
+ Fp2.neg(t0),
42
44
  t1, // T1
43
45
  ]);
44
- let t2 = Fp2.square(t1); // T1²
46
+ let t2 = Fp2.sqr(t1); // T1²
45
47
  let t3 = Fp2.mul(t2, t1); // T2 * T1
46
48
  let t4 = Fp2.mul(t2, Rx); // T2 * Rx
47
- let t5 = Fp2.add(Fp2.sub(t3, Fp2.mul(t4, 2n)), Fp2.mul(Fp2.square(t0), Rz)); // T3 - 2 * T4 + T0² * Rz
49
+ let t5 = Fp2.add(Fp2.sub(t3, Fp2.mul(t4, 2n)), Fp2.mul(Fp2.sqr(t0), Rz)); // T3 - 2 * T4 + T0² * Rz
48
50
  Rx = Fp2.mul(t1, t5); // T1 * T5
49
51
  Ry = Fp2.sub(Fp2.mul(Fp2.sub(t4, t5), t0), Fp2.mul(t3, Ry)); // (T4 - T5) * T0 - T3 * Ry
50
52
  Rz = Fp2.mul(Rz, t3); // Rz * T3
@@ -60,115 +62,114 @@ function bls(CURVE) {
60
62
  for (let j = 0, i = BLS_X_LEN - 2; i >= 0; i--, j++) {
61
63
  const E = ell[j];
62
64
  f12 = Fp12.multiplyBy014(f12, E[0], Fp2.mul(E[1], Px), Fp2.mul(E[2], Py));
63
- if (ut.bitGet(x, i)) {
65
+ if ((0, utils_js_1.bitGet)(x, i)) {
64
66
  j += 1;
65
67
  const F = ell[j];
66
68
  f12 = Fp12.multiplyBy014(f12, F[0], Fp2.mul(F[1], Px), Fp2.mul(F[2], Py));
67
69
  }
68
70
  if (i !== 0)
69
- f12 = Fp12.square(f12);
71
+ f12 = Fp12.sqr(f12);
70
72
  }
71
73
  return Fp12.conjugate(f12);
72
74
  }
73
75
  const utils = {
74
- hexToBytes: ut.hexToBytes,
75
- bytesToHex: ut.bytesToHex,
76
- stringToBytes: hash_to_curve_js_1.stringToBytes,
76
+ hexToBytes: utils_js_1.hexToBytes,
77
+ bytesToHex: utils_js_1.bytesToHex,
78
+ stringToBytes: htf.stringToBytes,
77
79
  // TODO: do we need to export it here?
78
- hashToField: (msg, count, options = {}) => (0, hash_to_curve_js_1.hash_to_field)(msg, count, { ...CURVE.htfDefaults, ...options }),
79
- expandMessageXMD: (msg, DST, lenInBytes, H = CURVE.hash) => (0, hash_to_curve_js_1.expand_message_xmd)(msg, DST, lenInBytes, H),
80
- hashToPrivateKey: (hash) => Fr.toBytes(ut.hashToPrivateScalar(hash, CURVE.r)),
80
+ hashToField: (msg, count, options = {}) => htf.hash_to_field(msg, count, { ...CURVE.htfDefaults, ...options }),
81
+ expandMessageXMD: (msg, DST, lenInBytes, H = CURVE.hash) => htf.expand_message_xmd(msg, DST, lenInBytes, H),
82
+ hashToPrivateKey: (hash) => Fr.toBytes((0, modular_js_1.hashToPrivateScalar)(hash, CURVE.r)),
81
83
  randomBytes: (bytesLength = groupLen) => CURVE.randomBytes(bytesLength),
82
84
  randomPrivateKey: () => utils.hashToPrivateKey(utils.randomBytes(groupLen + 8)),
83
- getDSTLabel: () => CURVE.htfDefaults.DST,
84
- setDSTLabel(newLabel) {
85
- // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-3.1
86
- if (typeof newLabel !== 'string' || newLabel.length > 2048 || newLabel.length === 0) {
87
- throw new TypeError('Invalid DST');
88
- }
89
- CURVE.htfDefaults.DST = newLabel;
90
- },
91
85
  };
92
86
  // Point on G1 curve: (x, y)
93
87
  const G1 = (0, weierstrass_js_1.weierstrassPoints)({
94
88
  n: Fr.ORDER,
95
89
  ...CURVE.G1,
96
90
  });
91
+ const G1HashToCurve = htf.hashToCurve(G1.ProjectivePoint, CURVE.G1.mapToCurve, {
92
+ ...CURVE.htfDefaults,
93
+ ...CURVE.G1.htfDefaults,
94
+ });
97
95
  function pairingPrecomputes(point) {
98
96
  const p = point;
99
97
  if (p._PPRECOMPUTES)
100
98
  return p._PPRECOMPUTES;
101
- p._PPRECOMPUTES = calcPairingPrecomputes(p.x, p.y);
99
+ p._PPRECOMPUTES = calcPairingPrecomputes(point.toAffine());
102
100
  return p._PPRECOMPUTES;
103
101
  }
104
- function clearPairingPrecomputes(point) {
105
- const p = point;
106
- p._PPRECOMPUTES = undefined;
107
- }
108
- clearPairingPrecomputes;
109
- function millerLoopG1(Q, P) {
110
- return millerLoop(pairingPrecomputes(P), [Q.x, Q.y]);
111
- }
102
+ // TODO: export
103
+ // function clearPairingPrecomputes(point: G2) {
104
+ // const p = point as G2 & withPairingPrecomputes;
105
+ // p._PPRECOMPUTES = undefined;
106
+ // }
112
107
  // Point on G2 curve (complex numbers): (x₁, x₂+i), (y₁, y₂+i)
113
108
  const G2 = (0, weierstrass_js_1.weierstrassPoints)({
114
109
  n: Fr.ORDER,
115
110
  ...CURVE.G2,
116
111
  });
112
+ const C = G2.ProjectivePoint; // TODO: fix
113
+ const G2HashToCurve = htf.hashToCurve(C, CURVE.G2.mapToCurve, {
114
+ ...CURVE.htfDefaults,
115
+ ...CURVE.G2.htfDefaults,
116
+ });
117
117
  const { Signature } = CURVE.G2;
118
118
  // Calculates bilinear pairing
119
- function pairing(P, Q, withFinalExponent = true) {
120
- if (P.equals(G1.Point.ZERO) || Q.equals(G2.Point.ZERO))
121
- throw new Error('No pairings at point of Infinity');
122
- P.assertValidity();
119
+ function pairing(Q, P, withFinalExponent = true) {
120
+ if (Q.equals(G1.ProjectivePoint.ZERO) || P.equals(G2.ProjectivePoint.ZERO))
121
+ throw new Error('pairing is not available for ZERO point');
123
122
  Q.assertValidity();
123
+ P.assertValidity();
124
124
  // Performance: 9ms for millerLoop and ~14ms for exp.
125
- const looped = millerLoopG1(P, Q);
125
+ const Qa = Q.toAffine();
126
+ const looped = millerLoop(pairingPrecomputes(P), [Qa.x, Qa.y]);
126
127
  return withFinalExponent ? Fp12.finalExponentiate(looped) : looped;
127
128
  }
128
129
  function normP1(point) {
129
- return point instanceof G1.Point ? point : G1.Point.fromHex(point);
130
+ return point instanceof G1.ProjectivePoint ? point : G1.ProjectivePoint.fromHex(point);
130
131
  }
131
132
  function normP2(point) {
132
- return point instanceof G2.Point ? point : Signature.decode(point);
133
+ return point instanceof G2.ProjectivePoint ? point : Signature.decode(point);
133
134
  }
134
- function normP2Hash(point) {
135
- return point instanceof G2.Point ? point : G2.Point.hashToCurve(point);
135
+ function normP2Hash(point, htfOpts) {
136
+ return point instanceof G2.ProjectivePoint
137
+ ? point
138
+ : G2HashToCurve.hashToCurve(point, htfOpts);
136
139
  }
137
140
  // Multiplies generator by private key.
138
141
  // P = pk x G
139
142
  function getPublicKey(privateKey) {
140
- return G1.Point.fromPrivateKey(privateKey).toRawBytes(true);
143
+ return G1.ProjectivePoint.fromPrivateKey(privateKey).toRawBytes(true);
141
144
  }
142
- function sign(message, privateKey) {
143
- const msgPoint = normP2Hash(message);
145
+ function sign(message, privateKey, htfOpts) {
146
+ const msgPoint = normP2Hash(message, htfOpts);
144
147
  msgPoint.assertValidity();
145
148
  const sigPoint = msgPoint.multiply(G1.normalizePrivateKey(privateKey));
146
- if (message instanceof G2.Point)
149
+ if (message instanceof G2.ProjectivePoint)
147
150
  return sigPoint;
148
151
  return Signature.encode(sigPoint);
149
152
  }
150
153
  // Checks if pairing of public key & hash is equal to pairing of generator & signature.
151
154
  // e(P, H(m)) == e(G, S)
152
- function verify(signature, message, publicKey) {
155
+ function verify(signature, message, publicKey, htfOpts) {
153
156
  const P = normP1(publicKey);
154
- const Hm = normP2Hash(message);
155
- const G = G1.Point.BASE;
157
+ const Hm = normP2Hash(message, htfOpts);
158
+ const G = G1.ProjectivePoint.BASE;
156
159
  const S = normP2(signature);
157
160
  // Instead of doing 2 exponentiations, we use property of billinear maps
158
161
  // and do one exp after multiplying 2 points.
159
162
  const ePHm = pairing(P.negate(), Hm, false);
160
163
  const eGS = pairing(G, S, false);
161
164
  const exp = Fp12.finalExponentiate(Fp12.mul(eGS, ePHm));
162
- return Fp12.equals(exp, Fp12.ONE);
165
+ return Fp12.eql(exp, Fp12.ONE);
163
166
  }
164
167
  function aggregatePublicKeys(publicKeys) {
165
168
  if (!publicKeys.length)
166
169
  throw new Error('Expected non-empty array');
167
- const agg = publicKeys
168
- .map(normP1)
169
- .reduce((sum, p) => sum.add(G1.ProjectivePoint.fromAffine(p)), G1.ProjectivePoint.ZERO);
170
- const aggAffine = agg.toAffine();
171
- if (publicKeys[0] instanceof G1.Point) {
170
+ const agg = publicKeys.map(normP1).reduce((sum, p) => sum.add(p), G1.ProjectivePoint.ZERO);
171
+ const aggAffine = agg; //.toAffine();
172
+ if (publicKeys[0] instanceof G1.ProjectivePoint) {
172
173
  aggAffine.assertValidity();
173
174
  return aggAffine;
174
175
  }
@@ -178,11 +179,9 @@ function bls(CURVE) {
178
179
  function aggregateSignatures(signatures) {
179
180
  if (!signatures.length)
180
181
  throw new Error('Expected non-empty array');
181
- const agg = signatures
182
- .map(normP2)
183
- .reduce((sum, s) => sum.add(G2.ProjectivePoint.fromAffine(s)), G2.ProjectivePoint.ZERO);
184
- const aggAffine = agg.toAffine();
185
- if (signatures[0] instanceof G2.Point) {
182
+ const agg = signatures.map(normP2).reduce((sum, s) => sum.add(s), G2.ProjectivePoint.ZERO);
183
+ const aggAffine = agg; //.toAffine();
184
+ if (signatures[0] instanceof G2.ProjectivePoint) {
186
185
  aggAffine.assertValidity();
187
186
  return aggAffine;
188
187
  }
@@ -190,33 +189,34 @@ function bls(CURVE) {
190
189
  }
191
190
  // https://ethresear.ch/t/fast-verification-of-multiple-bls-signatures/5407
192
191
  // e(G, S) = e(G, SUM(n)(Si)) = MUL(n)(e(G, Si))
193
- function verifyBatch(signature, messages, publicKeys) {
192
+ function verifyBatch(signature, messages, publicKeys, htfOpts) {
193
+ // @ts-ignore
194
+ // console.log('verifyBatch', bytesToHex(signature as any), messages, publicKeys.map(bytesToHex));
194
195
  if (!messages.length)
195
196
  throw new Error('Expected non-empty messages array');
196
197
  if (publicKeys.length !== messages.length)
197
198
  throw new Error('Pubkey count should equal msg count');
198
199
  const sig = normP2(signature);
199
- const nMessages = messages.map(normP2Hash);
200
+ const nMessages = messages.map((i) => normP2Hash(i, htfOpts));
200
201
  const nPublicKeys = publicKeys.map(normP1);
201
202
  try {
202
203
  const paired = [];
203
204
  for (const message of new Set(nMessages)) {
204
- const groupPublicKey = nMessages.reduce((groupPublicKey, subMessage, i) => subMessage === message ? groupPublicKey.add(nPublicKeys[i]) : groupPublicKey, G1.Point.ZERO);
205
+ const groupPublicKey = nMessages.reduce((groupPublicKey, subMessage, i) => subMessage === message ? groupPublicKey.add(nPublicKeys[i]) : groupPublicKey, G1.ProjectivePoint.ZERO);
205
206
  // const msg = message instanceof PointG2 ? message : await PointG2.hashToCurve(message);
206
207
  // Possible to batch pairing for same msg with different groupPublicKey here
207
208
  paired.push(pairing(groupPublicKey, message, false));
208
209
  }
209
- paired.push(pairing(G1.Point.BASE.negate(), sig, false));
210
+ paired.push(pairing(G1.ProjectivePoint.BASE.negate(), sig, false));
210
211
  const product = paired.reduce((a, b) => Fp12.mul(a, b), Fp12.ONE);
211
212
  const exp = Fp12.finalExponentiate(product);
212
- return Fp12.equals(exp, Fp12.ONE);
213
+ return Fp12.eql(exp, Fp12.ONE);
213
214
  }
214
215
  catch {
215
216
  return false;
216
217
  }
217
218
  }
218
- // Pre-compute points. Refer to README.
219
- G1.Point.BASE._setWindowSize(4);
219
+ G1.ProjectivePoint.BASE._setWindowSize(4);
220
220
  return {
221
221
  CURVE,
222
222
  Fr,
@@ -229,6 +229,7 @@ function bls(CURVE) {
229
229
  Signature,
230
230
  millerLoop,
231
231
  calcPairingPrecomputes,
232
+ hashToCurve: { G1: G1HashToCurve, G2: G2HashToCurve },
232
233
  pairing,
233
234
  getPublicKey,
234
235
  sign,
@@ -1,15 +1,25 @@
1
+ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
+ import { Field } from './modular.js';
3
+ export declare type AffinePoint<T> = {
4
+ x: T;
5
+ y: T;
6
+ } & {
7
+ z?: never;
8
+ t?: never;
9
+ };
1
10
  export interface Group<T extends Group<T>> {
2
11
  double(): T;
3
12
  negate(): T;
4
13
  add(other: T): T;
5
14
  subtract(other: T): T;
6
15
  equals(other: T): boolean;
7
- multiply(scalar: number | bigint): T;
16
+ multiply(scalar: bigint): T;
8
17
  }
9
18
  export declare type GroupConstructor<T> = {
10
19
  BASE: T;
11
20
  ZERO: T;
12
21
  };
22
+ export declare type Mapper<T> = (i: T[]) => T[];
13
23
  export declare function wNAF<T extends Group<T>>(c: GroupConstructor<T>, bits: number): {
14
24
  constTimeNegate: (condition: boolean, item: T) => T;
15
25
  unsafeLadder(elm: T, n: bigint): T;
@@ -31,4 +41,23 @@ export declare function wNAF<T extends Group<T>>(c: GroupConstructor<T>, bits: n
31
41
  p: T;
32
42
  f: T;
33
43
  };
44
+ wNAFCached(P: T, precomputesMap: Map<T, T[]>, n: bigint, transform: Mapper<T>): {
45
+ p: T;
46
+ f: T;
47
+ };
48
+ };
49
+ export declare type BasicCurve<T> = {
50
+ Fp: Field<T>;
51
+ n: bigint;
52
+ nBitLength?: number;
53
+ nByteLength?: number;
54
+ h: bigint;
55
+ hEff?: bigint;
56
+ Gx: T;
57
+ Gy: T;
58
+ allowInfinityPoint?: boolean;
34
59
  };
60
+ export declare function validateBasic<FP, T>(curve: BasicCurve<FP> & T): Readonly<{
61
+ readonly nBitLength: number;
62
+ readonly nByteLength: number;
63
+ } & BasicCurve<FP> & T>;
@@ -1,11 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.wNAF = void 0;
3
+ exports.validateBasic = exports.wNAF = void 0;
4
4
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
5
5
  // Abelian group utilities
6
+ const modular_js_1 = require("./modular.js");
7
+ const utils_js_1 = require("./utils.js");
6
8
  const _0n = BigInt(0);
7
9
  const _1n = BigInt(1);
8
- // Not big, but pretty complex and it is easy to break stuff. To avoid too much copy paste
10
+ // Elliptic curve multiplication of Point by scalar. Complicated and fragile. Uses wNAF method.
11
+ // Windowed method is 10% faster, but takes 2x longer to generate & consumes 2x memory.
9
12
  function wNAF(c, bits) {
10
13
  const constTimeNegate = (condition, item) => {
11
14
  const neg = item.negate();
@@ -107,6 +110,34 @@ function wNAF(c, bits) {
107
110
  // which makes it less const-time: around 1 bigint multiply.
108
111
  return { p, f };
109
112
  },
113
+ wNAFCached(P, precomputesMap, n, transform) {
114
+ // @ts-ignore
115
+ const W = P._WINDOW_SIZE || 1;
116
+ // Calculate precomputes on a first run, reuse them after
117
+ let comp = precomputesMap.get(P);
118
+ if (!comp) {
119
+ comp = this.precomputeWindow(P, W);
120
+ if (W !== 1) {
121
+ precomputesMap.set(P, transform(comp));
122
+ }
123
+ }
124
+ return this.wNAF(W, comp, n);
125
+ },
110
126
  };
111
127
  }
112
128
  exports.wNAF = wNAF;
129
+ function validateBasic(curve) {
130
+ (0, modular_js_1.validateField)(curve.Fp);
131
+ (0, utils_js_1.validateObject)(curve, {
132
+ n: 'bigint',
133
+ h: 'bigint',
134
+ Gx: 'field',
135
+ Gy: 'field',
136
+ }, {
137
+ nBitLength: 'isSafeInteger',
138
+ nByteLength: 'isSafeInteger',
139
+ });
140
+ // Set defaults
141
+ return Object.freeze({ ...(0, modular_js_1.nLength)(curve.n, curve.nBitLength), ...curve });
142
+ }
143
+ exports.validateBasic = validateBasic;
@@ -1,13 +1,10 @@
1
- /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
- import * as mod from './modular.js';
3
1
  import * as ut from './utils.js';
4
- import { Hex, PrivKey } from './utils.js';
5
- import { Group, GroupConstructor } from './group.js';
6
- import { htfOpts } from './hash-to-curve.js';
7
- export declare type CurveType = ut.BasicCurve<bigint> & {
2
+ import { FHash, Hex } from './utils.js';
3
+ import { Group, GroupConstructor, BasicCurve, AffinePoint } from './curve.js';
4
+ export declare type CurveType = BasicCurve<bigint> & {
8
5
  a: bigint;
9
6
  d: bigint;
10
- hash: ut.CHash;
7
+ hash: FHash;
11
8
  randomBytes: (bytesLength?: number) => Uint8Array;
12
9
  adjustScalarBytes?: (bytes: Uint8Array) => Uint8Array;
13
10
  domain?: (data: Uint8Array, ctx: Uint8Array, phflag: boolean) => Uint8Array;
@@ -15,27 +12,22 @@ export declare type CurveType = ut.BasicCurve<bigint> & {
15
12
  isValid: boolean;
16
13
  value: bigint;
17
14
  };
18
- preHash?: ut.CHash;
19
- htfDefaults?: htfOpts;
20
- mapToCurve?: (scalar: bigint[]) => {
21
- x: bigint;
22
- y: bigint;
23
- };
15
+ preHash?: FHash;
16
+ mapToCurve?: (scalar: bigint[]) => AffinePoint<bigint>;
24
17
  };
25
18
  declare function validateOpts(curve: CurveType): Readonly<{
26
19
  readonly nBitLength: number;
27
20
  readonly nByteLength: number;
28
- readonly Fp: mod.Field<bigint>;
21
+ readonly Fp: import("./modular.js").Field<bigint>;
29
22
  readonly n: bigint;
30
23
  readonly h: bigint;
31
24
  readonly hEff?: bigint | undefined;
32
25
  readonly Gx: bigint;
33
26
  readonly Gy: bigint;
34
- readonly wrapPrivateKey?: boolean | undefined;
35
27
  readonly allowInfinityPoint?: boolean | undefined;
36
28
  readonly a: bigint;
37
29
  readonly d: bigint;
38
- readonly hash: ut.CHash;
30
+ readonly hash: ut.FHash;
39
31
  readonly randomBytes: (bytesLength?: number | undefined) => Uint8Array;
40
32
  readonly adjustScalarBytes?: ((bytes: Uint8Array) => Uint8Array) | undefined;
41
33
  readonly domain?: ((data: Uint8Array, ctx: Uint8Array, phflag: boolean) => Uint8Array) | undefined;
@@ -43,75 +35,41 @@ declare function validateOpts(curve: CurveType): Readonly<{
43
35
  isValid: boolean;
44
36
  value: bigint;
45
37
  }) | undefined;
46
- readonly preHash?: ut.CHash | undefined;
47
- readonly htfDefaults?: htfOpts | undefined;
48
- readonly mapToCurve?: ((scalar: bigint[]) => {
49
- x: bigint;
50
- y: bigint;
51
- }) | undefined;
38
+ readonly preHash?: ut.FHash | undefined;
39
+ readonly mapToCurve?: ((scalar: bigint[]) => AffinePoint<bigint>) | undefined;
52
40
  }>;
53
- export interface SignatureType {
54
- readonly r: PointType;
55
- readonly s: bigint;
56
- assertValidity(): SignatureType;
57
- toRawBytes(): Uint8Array;
58
- toHex(): string;
59
- }
60
- export declare type SignatureConstructor = {
61
- new (r: PointType, s: bigint): SignatureType;
62
- fromHex(hex: Hex): SignatureType;
63
- };
64
- export interface ExtendedPointType extends Group<ExtendedPointType> {
65
- readonly x: bigint;
66
- readonly y: bigint;
67
- readonly z: bigint;
68
- readonly t: bigint;
69
- multiply(scalar: number | bigint, affinePoint?: PointType): ExtendedPointType;
70
- multiplyUnsafe(scalar: number | bigint): ExtendedPointType;
41
+ export interface ExtPointType extends Group<ExtPointType> {
42
+ readonly ex: bigint;
43
+ readonly ey: bigint;
44
+ readonly ez: bigint;
45
+ readonly et: bigint;
46
+ assertValidity(): void;
47
+ multiply(scalar: bigint): ExtPointType;
48
+ multiplyUnsafe(scalar: bigint): ExtPointType;
71
49
  isSmallOrder(): boolean;
72
50
  isTorsionFree(): boolean;
73
- toAffine(invZ?: bigint): PointType;
74
- clearCofactor(): ExtendedPointType;
75
- }
76
- export interface ExtendedPointConstructor extends GroupConstructor<ExtendedPointType> {
77
- new (x: bigint, y: bigint, z: bigint, t: bigint): ExtendedPointType;
78
- fromAffine(p: PointType): ExtendedPointType;
79
- toAffineBatch(points: ExtendedPointType[]): PointType[];
80
- normalizeZ(points: ExtendedPointType[]): ExtendedPointType[];
81
- }
82
- export interface PointType extends Group<PointType> {
83
- readonly x: bigint;
84
- readonly y: bigint;
85
- _setWindowSize(windowSize: number): void;
86
- toRawBytes(isCompressed?: boolean): Uint8Array;
87
- toHex(isCompressed?: boolean): string;
88
- isTorsionFree(): boolean;
89
- clearCofactor(): PointType;
51
+ clearCofactor(): ExtPointType;
52
+ toAffine(iz?: bigint): AffinePoint<bigint>;
90
53
  }
91
- export interface PointConstructor extends GroupConstructor<PointType> {
92
- new (x: bigint, y: bigint): PointType;
93
- fromHex(hex: Hex): PointType;
94
- fromPrivateKey(privateKey: PrivKey): PointType;
95
- hashToCurve(msg: Hex, options?: Partial<htfOpts>): PointType;
96
- encodeToCurve(msg: Hex, options?: Partial<htfOpts>): PointType;
54
+ export interface ExtPointConstructor extends GroupConstructor<ExtPointType> {
55
+ new (x: bigint, y: bigint, z: bigint, t: bigint): ExtPointType;
56
+ fromAffine(p: AffinePoint<bigint>): ExtPointType;
57
+ fromHex(hex: Hex): ExtPointType;
58
+ fromPrivateKey(privateKey: Hex): ExtPointType;
97
59
  }
98
- export declare type PubKey = Hex | PointType;
99
- export declare type SigType = Hex | SignatureType;
100
60
  export declare type CurveFn = {
101
61
  CURVE: ReturnType<typeof validateOpts>;
102
- getPublicKey: (privateKey: PrivKey, isCompressed?: boolean) => Uint8Array;
62
+ getPublicKey: (privateKey: Hex) => Uint8Array;
103
63
  sign: (message: Hex, privateKey: Hex) => Uint8Array;
104
- verify: (sig: SigType, message: Hex, publicKey: PubKey) => boolean;
105
- Point: PointConstructor;
106
- ExtendedPoint: ExtendedPointConstructor;
107
- Signature: SignatureConstructor;
64
+ verify: (sig: Hex, message: Hex, publicKey: Hex) => boolean;
65
+ ExtendedPoint: ExtPointConstructor;
108
66
  utils: {
109
67
  randomPrivateKey: () => Uint8Array;
110
- getExtendedPublicKey: (key: PrivKey) => {
68
+ getExtendedPublicKey: (key: Hex) => {
111
69
  head: Uint8Array;
112
70
  prefix: Uint8Array;
113
71
  scalar: bigint;
114
- point: PointType;
72
+ point: ExtPointType;
115
73
  pointBytes: Uint8Array;
116
74
  };
117
75
  };