@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.
- package/README.md +115 -41
- package/lib/_shortw_utils.d.ts +13 -24
- package/lib/abstract/bls.d.ts +39 -32
- package/lib/abstract/bls.js +74 -73
- package/lib/abstract/{group.d.ts → curve.d.ts} +30 -1
- package/lib/abstract/{group.js → curve.js} +33 -2
- package/lib/abstract/edwards.d.ts +30 -72
- package/lib/abstract/edwards.js +206 -389
- package/lib/abstract/hash-to-curve.d.ts +25 -6
- package/lib/abstract/hash-to-curve.js +40 -12
- package/lib/abstract/modular.d.ts +21 -8
- package/lib/abstract/modular.js +72 -48
- package/lib/abstract/montgomery.js +23 -68
- package/lib/abstract/poseidon.d.ts +29 -0
- package/lib/abstract/poseidon.js +115 -0
- package/lib/abstract/utils.d.ts +9 -37
- package/lib/abstract/utils.js +61 -87
- package/lib/abstract/weierstrass.d.ts +58 -81
- package/lib/abstract/weierstrass.js +485 -679
- package/lib/bls12-381.js +63 -58
- package/lib/bn.js +1 -1
- package/lib/ed25519.d.ts +7 -5
- package/lib/ed25519.js +82 -79
- package/lib/ed448.d.ts +3 -0
- package/lib/ed448.js +86 -83
- package/lib/esm/abstract/bls.js +75 -74
- package/lib/esm/abstract/{group.js → curve.js} +31 -1
- package/lib/esm/abstract/edwards.js +204 -387
- package/lib/esm/abstract/hash-to-curve.js +38 -11
- package/lib/esm/abstract/modular.js +69 -47
- package/lib/esm/abstract/montgomery.js +24 -69
- package/lib/esm/abstract/poseidon.js +109 -0
- package/lib/esm/abstract/utils.js +58 -82
- package/lib/esm/abstract/weierstrass.js +484 -678
- package/lib/esm/bls12-381.js +75 -70
- package/lib/esm/bn.js +1 -1
- package/lib/esm/ed25519.js +80 -78
- package/lib/esm/ed448.js +84 -82
- package/lib/esm/jubjub.js +1 -1
- package/lib/esm/p224.js +1 -1
- package/lib/esm/p256.js +11 -9
- package/lib/esm/p384.js +11 -9
- package/lib/esm/p521.js +12 -23
- package/lib/esm/secp256k1.js +124 -162
- package/lib/esm/stark.js +105 -41
- package/lib/jubjub.d.ts +2 -2
- package/lib/jubjub.js +1 -1
- package/lib/p192.d.ts +26 -48
- package/lib/p224.d.ts +26 -48
- package/lib/p224.js +1 -1
- package/lib/p256.d.ts +29 -48
- package/lib/p256.js +13 -10
- package/lib/p384.d.ts +29 -48
- package/lib/p384.js +13 -10
- package/lib/p521.d.ts +37 -57
- package/lib/p521.js +14 -24
- package/lib/secp256k1.d.ts +37 -46
- package/lib/secp256k1.js +124 -162
- package/lib/stark.d.ts +39 -22
- package/lib/stark.js +108 -41
- package/package.json +15 -10
package/lib/abstract/bls.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.bls = void 0;
|
|
4
|
-
const
|
|
5
|
-
const
|
|
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 =
|
|
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(
|
|
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.
|
|
23
|
-
let t1 = Fp2.
|
|
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.
|
|
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.
|
|
30
|
-
Fp2.
|
|
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.
|
|
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 (
|
|
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.
|
|
43
|
+
Fp2.neg(t0),
|
|
42
44
|
t1, // T1
|
|
43
45
|
]);
|
|
44
|
-
let t2 = Fp2.
|
|
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.
|
|
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 (
|
|
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.
|
|
71
|
+
f12 = Fp12.sqr(f12);
|
|
70
72
|
}
|
|
71
73
|
return Fp12.conjugate(f12);
|
|
72
74
|
}
|
|
73
75
|
const utils = {
|
|
74
|
-
hexToBytes:
|
|
75
|
-
bytesToHex:
|
|
76
|
-
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 = {}) =>
|
|
79
|
-
expandMessageXMD: (msg, DST, lenInBytes, H = CURVE.hash) =>
|
|
80
|
-
hashToPrivateKey: (hash) => Fr.toBytes(
|
|
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(
|
|
99
|
+
p._PPRECOMPUTES = calcPairingPrecomputes(point.toAffine());
|
|
102
100
|
return p._PPRECOMPUTES;
|
|
103
101
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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(
|
|
120
|
-
if (
|
|
121
|
-
throw new Error('
|
|
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
|
|
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.
|
|
130
|
+
return point instanceof G1.ProjectivePoint ? point : G1.ProjectivePoint.fromHex(point);
|
|
130
131
|
}
|
|
131
132
|
function normP2(point) {
|
|
132
|
-
return point instanceof G2.
|
|
133
|
+
return point instanceof G2.ProjectivePoint ? point : Signature.decode(point);
|
|
133
134
|
}
|
|
134
|
-
function normP2Hash(point) {
|
|
135
|
-
return point instanceof G2.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
169
|
-
|
|
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
|
-
|
|
183
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
213
|
+
return Fp12.eql(exp, Fp12.ONE);
|
|
213
214
|
}
|
|
214
215
|
catch {
|
|
215
216
|
return false;
|
|
216
217
|
}
|
|
217
218
|
}
|
|
218
|
-
|
|
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:
|
|
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
|
-
//
|
|
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 {
|
|
5
|
-
import { Group, GroupConstructor } from './
|
|
6
|
-
|
|
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:
|
|
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?:
|
|
19
|
-
|
|
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:
|
|
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.
|
|
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.
|
|
47
|
-
readonly
|
|
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
|
|
54
|
-
readonly
|
|
55
|
-
readonly
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
74
|
-
|
|
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
|
|
92
|
-
new (x: bigint, y: bigint):
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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:
|
|
62
|
+
getPublicKey: (privateKey: Hex) => Uint8Array;
|
|
103
63
|
sign: (message: Hex, privateKey: Hex) => Uint8Array;
|
|
104
|
-
verify: (sig:
|
|
105
|
-
|
|
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:
|
|
68
|
+
getExtendedPublicKey: (key: Hex) => {
|
|
111
69
|
head: Uint8Array;
|
|
112
70
|
prefix: Uint8Array;
|
|
113
71
|
scalar: bigint;
|
|
114
|
-
point:
|
|
72
|
+
point: ExtPointType;
|
|
115
73
|
pointBytes: Uint8Array;
|
|
116
74
|
};
|
|
117
75
|
};
|