@noble/curves 1.8.0 → 1.8.2
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 +282 -419
- package/_shortw_utils.d.ts +2 -2
- package/_shortw_utils.d.ts.map +1 -1
- package/_shortw_utils.js +2 -2
- package/_shortw_utils.js.map +1 -1
- package/abstract/bls.d.ts +5 -5
- package/abstract/bls.d.ts.map +1 -1
- package/abstract/bls.js +14 -15
- package/abstract/bls.js.map +1 -1
- package/abstract/curve.d.ts +10 -2
- package/abstract/curve.d.ts.map +1 -1
- package/abstract/curve.js +81 -78
- package/abstract/curve.js.map +1 -1
- package/abstract/edwards.d.ts +2 -2
- package/abstract/edwards.d.ts.map +1 -1
- package/abstract/edwards.js +55 -69
- package/abstract/edwards.js.map +1 -1
- package/abstract/hash-to-curve.d.ts +5 -4
- package/abstract/hash-to-curve.d.ts.map +1 -1
- package/abstract/hash-to-curve.js +20 -18
- package/abstract/hash-to-curve.js.map +1 -1
- package/abstract/modular.d.ts.map +1 -1
- package/abstract/modular.js +9 -9
- package/abstract/montgomery.js +12 -12
- package/abstract/poseidon.d.ts +1 -1
- package/abstract/poseidon.d.ts.map +1 -1
- package/abstract/poseidon.js +3 -3
- package/abstract/poseidon.js.map +1 -1
- package/abstract/tower.d.ts +2 -2
- package/abstract/tower.js +13 -13
- package/abstract/utils.d.ts +4 -2
- package/abstract/utils.d.ts.map +1 -1
- package/abstract/utils.js +25 -14
- package/abstract/utils.js.map +1 -1
- package/abstract/weierstrass.d.ts +19 -6
- package/abstract/weierstrass.d.ts.map +1 -1
- package/abstract/weierstrass.js +97 -80
- package/abstract/weierstrass.js.map +1 -1
- package/bls12-381.d.ts +1 -1
- package/bls12-381.d.ts.map +1 -1
- package/bls12-381.js +48 -49
- package/bls12-381.js.map +1 -1
- package/bn254.d.ts +2 -2
- package/bn254.d.ts.map +1 -1
- package/bn254.js +29 -30
- package/bn254.js.map +1 -1
- package/ed25519.d.ts +8 -6
- package/ed25519.d.ts.map +1 -1
- package/ed25519.js +65 -66
- package/ed25519.js.map +1 -1
- package/ed448.d.ts +6 -6
- package/ed448.d.ts.map +1 -1
- package/ed448.js +50 -52
- package/ed448.js.map +1 -1
- package/esm/_shortw_utils.d.ts +2 -2
- package/esm/_shortw_utils.d.ts.map +1 -1
- package/esm/_shortw_utils.js +1 -1
- package/esm/_shortw_utils.js.map +1 -1
- package/esm/abstract/bls.d.ts +5 -5
- package/esm/abstract/bls.d.ts.map +1 -1
- package/esm/abstract/bls.js +5 -6
- package/esm/abstract/bls.js.map +1 -1
- package/esm/abstract/curve.d.ts +10 -2
- package/esm/abstract/curve.d.ts.map +1 -1
- package/esm/abstract/curve.js +77 -74
- package/esm/abstract/curve.js.map +1 -1
- package/esm/abstract/edwards.d.ts +2 -2
- package/esm/abstract/edwards.d.ts.map +1 -1
- package/esm/abstract/edwards.js +36 -50
- package/esm/abstract/edwards.js.map +1 -1
- package/esm/abstract/hash-to-curve.d.ts +5 -4
- package/esm/abstract/hash-to-curve.d.ts.map +1 -1
- package/esm/abstract/hash-to-curve.js +4 -2
- package/esm/abstract/hash-to-curve.js.map +1 -1
- package/esm/abstract/modular.d.ts.map +1 -1
- package/esm/abstract/modular.js +1 -1
- package/esm/abstract/montgomery.js +2 -2
- package/esm/abstract/poseidon.d.ts +1 -1
- package/esm/abstract/poseidon.d.ts.map +1 -1
- package/esm/abstract/poseidon.js +1 -1
- package/esm/abstract/poseidon.js.map +1 -1
- package/esm/abstract/tower.d.ts +2 -2
- package/esm/abstract/tower.js +5 -5
- package/esm/abstract/utils.d.ts +4 -2
- package/esm/abstract/utils.d.ts.map +1 -1
- package/esm/abstract/utils.js +24 -13
- package/esm/abstract/utils.js.map +1 -1
- package/esm/abstract/weierstrass.d.ts +19 -6
- package/esm/abstract/weierstrass.d.ts.map +1 -1
- package/esm/abstract/weierstrass.js +77 -60
- package/esm/abstract/weierstrass.js.map +1 -1
- package/esm/bls12-381.d.ts +1 -1
- package/esm/bls12-381.d.ts.map +1 -1
- package/esm/bls12-381.js +16 -17
- package/esm/bls12-381.js.map +1 -1
- package/esm/bn254.d.ts +2 -2
- package/esm/bn254.d.ts.map +1 -1
- package/esm/bn254.js +7 -8
- package/esm/bn254.js.map +1 -1
- package/esm/ed25519.d.ts +8 -6
- package/esm/ed25519.d.ts.map +1 -1
- package/esm/ed25519.js +20 -21
- package/esm/ed25519.js.map +1 -1
- package/esm/ed448.d.ts +6 -6
- package/esm/ed448.d.ts.map +1 -1
- package/esm/ed448.js +13 -15
- package/esm/ed448.js.map +1 -1
- package/esm/index.js +13 -1
- package/esm/index.js.map +1 -1
- package/esm/jubjub.d.ts +1 -4
- package/esm/jubjub.d.ts.map +1 -1
- package/esm/jubjub.js +1 -60
- package/esm/jubjub.js.map +1 -1
- package/esm/misc.d.ts +15 -0
- package/esm/misc.d.ts.map +1 -0
- package/esm/misc.js +101 -0
- package/esm/misc.js.map +1 -0
- package/esm/p256.d.ts +8 -5
- package/esm/p256.d.ts.map +1 -1
- package/esm/p256.js +13 -12
- package/esm/p256.js.map +1 -1
- package/esm/p384.d.ts +8 -5
- package/esm/p384.d.ts.map +1 -1
- package/esm/p384.js +14 -15
- package/esm/p384.js.map +1 -1
- package/esm/p521.d.ts +6 -5
- package/esm/p521.d.ts.map +1 -1
- package/esm/p521.js +19 -28
- package/esm/p521.js.map +1 -1
- package/esm/pasta.d.ts +1 -7
- package/esm/pasta.d.ts.map +1 -1
- package/esm/pasta.js +1 -33
- package/esm/pasta.js.map +1 -1
- package/esm/secp256k1.d.ts +15 -10
- package/esm/secp256k1.d.ts.map +1 -1
- package/esm/secp256k1.js +18 -14
- package/esm/secp256k1.js.map +1 -1
- package/index.js +13 -1
- package/index.js.map +1 -1
- package/jubjub.d.ts +1 -4
- package/jubjub.d.ts.map +1 -1
- package/jubjub.js +5 -63
- package/jubjub.js.map +1 -1
- package/misc.d.ts +15 -0
- package/misc.d.ts.map +1 -0
- package/misc.js +106 -0
- package/misc.js.map +1 -0
- package/p256.d.ts +8 -5
- package/p256.d.ts.map +1 -1
- package/p256.js +19 -18
- package/p256.js.map +1 -1
- package/p384.d.ts +8 -5
- package/p384.d.ts.map +1 -1
- package/p384.js +19 -20
- package/p384.js.map +1 -1
- package/p521.d.ts +6 -5
- package/p521.d.ts.map +1 -1
- package/p521.js +23 -32
- package/p521.js.map +1 -1
- package/package.json +21 -16
- package/pasta.d.ts +1 -7
- package/pasta.d.ts.map +1 -1
- package/pasta.js +4 -34
- package/pasta.js.map +1 -1
- package/secp256k1.d.ts +15 -10
- package/secp256k1.d.ts.map +1 -1
- package/secp256k1.js +57 -53
- package/secp256k1.js.map +1 -1
- package/src/_shortw_utils.ts +2 -2
- package/src/abstract/bls.ts +14 -12
- package/src/abstract/curve.ts +88 -79
- package/src/abstract/edwards.ts +52 -59
- package/src/abstract/hash-to-curve.ts +7 -5
- package/src/abstract/modular.ts +1 -1
- package/src/abstract/montgomery.ts +2 -2
- package/src/abstract/poseidon.ts +1 -1
- package/src/abstract/tower.ts +6 -6
- package/src/abstract/utils.ts +26 -15
- package/src/abstract/weierstrass.ts +99 -77
- package/src/bls12-381.ts +30 -28
- package/src/bn254.ts +11 -13
- package/src/ed25519.ts +27 -26
- package/src/ed448.ts +21 -20
- package/src/index.ts +13 -1
- package/src/jubjub.ts +5 -63
- package/src/misc.ts +117 -0
- package/src/p256.ts +13 -12
- package/src/p384.ts +18 -15
- package/src/p521.ts +27 -32
- package/src/pasta.ts +1 -39
- package/src/secp256k1.ts +20 -16
package/src/abstract/edwards.ts
CHANGED
|
@@ -5,17 +5,20 @@
|
|
|
5
5
|
*/
|
|
6
6
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
7
7
|
import {
|
|
8
|
-
AffinePoint,
|
|
9
|
-
BasicCurve,
|
|
10
|
-
Group,
|
|
11
|
-
GroupConstructor,
|
|
8
|
+
type AffinePoint,
|
|
9
|
+
type BasicCurve,
|
|
10
|
+
type Group,
|
|
11
|
+
type GroupConstructor,
|
|
12
|
+
pippenger,
|
|
12
13
|
validateBasic,
|
|
13
14
|
wNAF,
|
|
14
|
-
|
|
15
|
-
} from './
|
|
16
|
-
|
|
17
|
-
import
|
|
18
|
-
|
|
15
|
+
} from './curve.ts';
|
|
16
|
+
import { Field, mod } from './modular.ts';
|
|
17
|
+
// prettier-ignore
|
|
18
|
+
import {
|
|
19
|
+
abool, aInRange, bytesToHex, bytesToNumberLE, concatBytes,
|
|
20
|
+
ensureBytes, type FHash, type Hex, memoized, numberToBytesLE, validateObject
|
|
21
|
+
} from './utils.ts';
|
|
19
22
|
|
|
20
23
|
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
|
21
24
|
// prettier-ignore
|
|
@@ -41,7 +44,7 @@ const VERIFY_DEFAULT = { zip215: true };
|
|
|
41
44
|
|
|
42
45
|
function validateOpts(curve: CurveType): CurveTypeWithLength {
|
|
43
46
|
const opts = validateBasic(curve);
|
|
44
|
-
|
|
47
|
+
validateObject(
|
|
45
48
|
curve,
|
|
46
49
|
{
|
|
47
50
|
hash: 'function',
|
|
@@ -162,11 +165,12 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
|
|
162
165
|
}); // NOOP
|
|
163
166
|
// 0 <= n < MASK
|
|
164
167
|
// Coordinates larger than Fp.ORDER are allowed for zip215
|
|
165
|
-
function aCoordinate(title: string, n: bigint) {
|
|
166
|
-
|
|
168
|
+
function aCoordinate(title: string, n: bigint, banZero = false) {
|
|
169
|
+
const min = banZero ? _1n : _0n;
|
|
170
|
+
aInRange('coordinate ' + title, n, min, MASK);
|
|
167
171
|
}
|
|
168
172
|
|
|
169
|
-
function
|
|
173
|
+
function aextpoint(other: unknown) {
|
|
170
174
|
if (!(other instanceof Point)) throw new Error('ExtendedPoint expected');
|
|
171
175
|
}
|
|
172
176
|
// Converts Extended point to default (x, y) coordinates.
|
|
@@ -208,17 +212,20 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
|
|
208
212
|
class Point implements ExtPointType {
|
|
209
213
|
static readonly BASE = new Point(CURVE.Gx, CURVE.Gy, _1n, modP(CURVE.Gx * CURVE.Gy));
|
|
210
214
|
static readonly ZERO = new Point(_0n, _1n, _1n, _0n); // 0, 1, 1, 0
|
|
215
|
+
readonly ex: bigint;
|
|
216
|
+
readonly ey: bigint;
|
|
217
|
+
readonly ez: bigint;
|
|
218
|
+
readonly et: bigint;
|
|
211
219
|
|
|
212
|
-
constructor(
|
|
213
|
-
readonly ex: bigint,
|
|
214
|
-
readonly ey: bigint,
|
|
215
|
-
readonly ez: bigint,
|
|
216
|
-
readonly et: bigint
|
|
217
|
-
) {
|
|
220
|
+
constructor(ex: bigint, ey: bigint, ez: bigint, et: bigint) {
|
|
218
221
|
aCoordinate('x', ex);
|
|
219
222
|
aCoordinate('y', ey);
|
|
220
|
-
aCoordinate('z', ez);
|
|
223
|
+
aCoordinate('z', ez, true);
|
|
221
224
|
aCoordinate('t', et);
|
|
225
|
+
this.ex = ex;
|
|
226
|
+
this.ey = ey;
|
|
227
|
+
this.ez = ez;
|
|
228
|
+
this.et = et;
|
|
222
229
|
Object.freeze(this);
|
|
223
230
|
}
|
|
224
231
|
|
|
@@ -257,7 +264,7 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
|
|
257
264
|
|
|
258
265
|
// Compare one point to another.
|
|
259
266
|
equals(other: Point): boolean {
|
|
260
|
-
|
|
267
|
+
aextpoint(other);
|
|
261
268
|
const { ex: X1, ey: Y1, ez: Z1 } = this;
|
|
262
269
|
const { ex: X2, ey: Y2, ez: Z2 } = other;
|
|
263
270
|
const X1Z2 = modP(X1 * Z2);
|
|
@@ -302,30 +309,10 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
|
|
302
309
|
// https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#addition-add-2008-hwcd
|
|
303
310
|
// Cost: 9M + 1*a + 1*d + 7add.
|
|
304
311
|
add(other: Point) {
|
|
305
|
-
|
|
312
|
+
aextpoint(other);
|
|
306
313
|
const { a, d } = CURVE;
|
|
307
314
|
const { ex: X1, ey: Y1, ez: Z1, et: T1 } = this;
|
|
308
315
|
const { ex: X2, ey: Y2, ez: Z2, et: T2 } = other;
|
|
309
|
-
// Faster algo for adding 2 Extended Points when curve's a=-1.
|
|
310
|
-
// http://hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#addition-add-2008-hwcd-4
|
|
311
|
-
// Cost: 8M + 8add + 2*2.
|
|
312
|
-
// Note: It does not check whether the `other` point is valid.
|
|
313
|
-
if (a === BigInt(-1)) {
|
|
314
|
-
const A = modP((Y1 - X1) * (Y2 + X2));
|
|
315
|
-
const B = modP((Y1 + X1) * (Y2 - X2));
|
|
316
|
-
const F = modP(B - A);
|
|
317
|
-
if (F === _0n) return this.double(); // Same point. Tests say it doesn't affect timing
|
|
318
|
-
const C = modP(Z1 * _2n * T2);
|
|
319
|
-
const D = modP(T1 * _2n * Z2);
|
|
320
|
-
const E = D + C;
|
|
321
|
-
const G = B + A;
|
|
322
|
-
const H = D - C;
|
|
323
|
-
const X3 = modP(E * F);
|
|
324
|
-
const Y3 = modP(G * H);
|
|
325
|
-
const T3 = modP(E * H);
|
|
326
|
-
const Z3 = modP(F * G);
|
|
327
|
-
return new Point(X3, Y3, Z3, T3);
|
|
328
|
-
}
|
|
329
316
|
const A = modP(X1 * X2); // A = X1*X2
|
|
330
317
|
const B = modP(Y1 * Y2); // B = Y1*Y2
|
|
331
318
|
const C = modP(T1 * d * T2); // C = T1*d*T2
|
|
@@ -338,7 +325,6 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
|
|
338
325
|
const Y3 = modP(G * H); // Y3 = G*H
|
|
339
326
|
const T3 = modP(E * H); // T3 = E*H
|
|
340
327
|
const Z3 = modP(F * G); // Z3 = F*G
|
|
341
|
-
|
|
342
328
|
return new Point(X3, Y3, Z3, T3);
|
|
343
329
|
}
|
|
344
330
|
|
|
@@ -353,7 +339,7 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
|
|
353
339
|
// Constant-time multiplication.
|
|
354
340
|
multiply(scalar: bigint): Point {
|
|
355
341
|
const n = scalar;
|
|
356
|
-
|
|
342
|
+
aInRange('scalar', n, _1n, CURVE_ORDER); // 1 <= scalar < L
|
|
357
343
|
const { p, f } = this.wNAF(n);
|
|
358
344
|
return Point.normalizeZ([p, f])[0];
|
|
359
345
|
}
|
|
@@ -365,7 +351,7 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
|
|
365
351
|
// Accepts optional accumulator to merge with multiply (important for sparse scalars)
|
|
366
352
|
multiplyUnsafe(scalar: bigint, acc = Point.ZERO): Point {
|
|
367
353
|
const n = scalar;
|
|
368
|
-
|
|
354
|
+
aInRange('scalar', n, _0n, CURVE_ORDER); // 0 <= scalar < L
|
|
369
355
|
if (n === _0n) return I;
|
|
370
356
|
if (this.is0() || n === _1n) return this;
|
|
371
357
|
return wnaf.wNAFCachedUnsafe(this, n, Point.normalizeZ, acc);
|
|
@@ -407,14 +393,14 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
|
|
407
393
|
const normed = hex.slice(); // copy again, we'll manipulate it
|
|
408
394
|
const lastByte = hex[len - 1]; // select last byte
|
|
409
395
|
normed[len - 1] = lastByte & ~0x80; // clear last bit
|
|
410
|
-
const y =
|
|
396
|
+
const y = bytesToNumberLE(normed);
|
|
411
397
|
|
|
412
398
|
// zip215=true is good for consensus-critical apps. =false follows RFC8032 / NIST186-5.
|
|
413
399
|
// RFC8032 prohibits >= p, but ZIP215 doesn't
|
|
414
400
|
// zip215=true: 0 <= y < MASK (2^256 for ed25519)
|
|
415
401
|
// zip215=false: 0 <= y < P (2^255-19 for ed25519)
|
|
416
402
|
const max = zip215 ? MASK : Fp.ORDER;
|
|
417
|
-
|
|
403
|
+
aInRange('pointHex.y', y, _0n, max);
|
|
418
404
|
|
|
419
405
|
// Ed25519: x² = (y²-1)/(dy²+1) mod p. Ed448: x² = (y²-1)/(dy²-1) mod p. Generic case:
|
|
420
406
|
// ax²+y²=1+dx²y² => y²-1=dx²y²-ax² => y²-1=x²(dy²-a) => x²=(y²-1)/(dy²-a)
|
|
@@ -431,17 +417,18 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
|
|
431
417
|
if (isLastByteOdd !== isXOdd) x = modP(-x); // if x_0 != x mod 2, set x = p-x
|
|
432
418
|
return Point.fromAffine({ x, y });
|
|
433
419
|
}
|
|
434
|
-
static fromPrivateKey(privKey: Hex) {
|
|
435
|
-
|
|
420
|
+
static fromPrivateKey(privKey: Hex): Point {
|
|
421
|
+
const { scalar } = getPrivateScalar(privKey);
|
|
422
|
+
return G.multiply(scalar); // reduced one call of `toRawBytes`
|
|
436
423
|
}
|
|
437
424
|
toRawBytes(): Uint8Array {
|
|
438
425
|
const { x, y } = this.toAffine();
|
|
439
|
-
const bytes =
|
|
426
|
+
const bytes = numberToBytesLE(y, Fp.BYTES); // each y has 2 x values (x, -y)
|
|
440
427
|
bytes[bytes.length - 1] |= x & _1n ? 0x80 : 0; // when compressing, it's enough to store y
|
|
441
428
|
return bytes; // and use the last byte to encode sign of x
|
|
442
429
|
}
|
|
443
430
|
toHex(): string {
|
|
444
|
-
return
|
|
431
|
+
return bytesToHex(this.toRawBytes()); // Same as toRawBytes, but returns string.
|
|
445
432
|
}
|
|
446
433
|
}
|
|
447
434
|
const { BASE: G, ZERO: I } = Point;
|
|
@@ -452,11 +439,11 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
|
|
452
439
|
}
|
|
453
440
|
// Little-endian SHA512 with modulo n
|
|
454
441
|
function modN_LE(hash: Uint8Array): bigint {
|
|
455
|
-
return modN(
|
|
442
|
+
return modN(bytesToNumberLE(hash));
|
|
456
443
|
}
|
|
457
444
|
|
|
458
|
-
|
|
459
|
-
function
|
|
445
|
+
// Get the hashed private scalar per RFC8032 5.1.5
|
|
446
|
+
function getPrivateScalar(key: Hex) {
|
|
460
447
|
const len = Fp.BYTES;
|
|
461
448
|
key = ensureBytes('private key', key, len);
|
|
462
449
|
// Hash private key with curve's hash function to produce uniformingly random input
|
|
@@ -465,6 +452,12 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
|
|
465
452
|
const head = adjustScalarBytes(hashed.slice(0, len)); // clear first half bits, produce FE
|
|
466
453
|
const prefix = hashed.slice(len, 2 * len); // second half is called key prefix (5.1.6)
|
|
467
454
|
const scalar = modN_LE(head); // The actual private scalar
|
|
455
|
+
return { head, prefix, scalar };
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// Convenience method that creates public key from scalar. RFC8032 5.1.5
|
|
459
|
+
function getExtendedPublicKey(key: Hex) {
|
|
460
|
+
const { head, prefix, scalar } = getPrivateScalar(key);
|
|
468
461
|
const point = G.multiply(scalar); // Point on Edwards curve aka public key
|
|
469
462
|
const pointBytes = point.toRawBytes(); // Uint8Array representation
|
|
470
463
|
return { head, prefix, scalar, point, pointBytes };
|
|
@@ -477,7 +470,7 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
|
|
477
470
|
|
|
478
471
|
// int('LE', SHA512(dom2(F, C) || msgs)) mod N
|
|
479
472
|
function hashDomainToScalar(context: Hex = new Uint8Array(), ...msgs: Uint8Array[]) {
|
|
480
|
-
const msg =
|
|
473
|
+
const msg = concatBytes(...msgs);
|
|
481
474
|
return modN_LE(cHash(domain(msg, ensureBytes('context', context), !!prehash)));
|
|
482
475
|
}
|
|
483
476
|
|
|
@@ -490,8 +483,8 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
|
|
490
483
|
const R = G.multiply(r).toRawBytes(); // R = rG
|
|
491
484
|
const k = hashDomainToScalar(options.context, R, pointBytes, msg); // R || A || PH(M)
|
|
492
485
|
const s = modN(r + k * scalar); // S = (r + k * s) mod L
|
|
493
|
-
|
|
494
|
-
const res =
|
|
486
|
+
aInRange('signature.s', s, _0n, CURVE_ORDER); // 0 <= s < l
|
|
487
|
+
const res = concatBytes(R, numberToBytesLE(s, Fp.BYTES));
|
|
495
488
|
return ensureBytes('result', res, Fp.BYTES * 2); // 64-byte signature
|
|
496
489
|
}
|
|
497
490
|
|
|
@@ -510,7 +503,7 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
|
|
510
503
|
if (zip215 !== undefined) abool('zip215', zip215);
|
|
511
504
|
if (prehash) msg = prehash(msg); // for ed25519ph, etc
|
|
512
505
|
|
|
513
|
-
const s =
|
|
506
|
+
const s = bytesToNumberLE(sig.slice(len, 2 * len));
|
|
514
507
|
let A, R, SB;
|
|
515
508
|
try {
|
|
516
509
|
// zip215=true is good for consensus-critical apps. =false follows RFC8032 / NIST186-5.
|
|
@@ -535,7 +528,7 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
|
|
535
528
|
|
|
536
529
|
const utils = {
|
|
537
530
|
getExtendedPublicKey,
|
|
538
|
-
|
|
531
|
+
/** ed25519 priv keys are uniform 32b. No need to check for modulo bias, like in secp256k1. */
|
|
539
532
|
randomPrivateKey: (): Uint8Array => randomBytes(Fp.BYTES),
|
|
540
533
|
|
|
541
534
|
/**
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* hash-to-curve from
|
|
2
|
+
* hash-to-curve from RFC 9380.
|
|
3
3
|
* Hashes arbitrary-length byte strings to a list of one or more elements of a finite field F.
|
|
4
|
+
* https://www.rfc-editor.org/rfc/rfc9380
|
|
4
5
|
* @module
|
|
5
6
|
*/
|
|
6
7
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
7
|
-
import type { AffinePoint, Group, GroupConstructor } from './curve.
|
|
8
|
-
import { IField, mod } from './modular.
|
|
9
|
-
import type { CHash } from './utils.
|
|
10
|
-
import { abytes, bytesToNumberBE, concatBytes, utf8ToBytes, validateObject } from './utils.
|
|
8
|
+
import type { AffinePoint, Group, GroupConstructor } from './curve.ts';
|
|
9
|
+
import { type IField, mod } from './modular.ts';
|
|
10
|
+
import type { CHash } from './utils.ts';
|
|
11
|
+
import { abytes, bytesToNumberBE, concatBytes, utf8ToBytes, validateObject } from './utils.ts';
|
|
11
12
|
|
|
12
13
|
export type UnicodeOrBytes = string | Uint8Array;
|
|
13
14
|
|
|
@@ -185,6 +186,7 @@ export function isogenyMap<T, F extends IField<T>>(field: F, map: [T[], T[], T[]
|
|
|
185
186
|
const [xNum, xDen, yNum, yDen] = COEFF.map((val) =>
|
|
186
187
|
val.reduce((acc, i) => field.add(field.mul(acc, x), i))
|
|
187
188
|
);
|
|
189
|
+
if (field.is0(xDen) || field.is0(yDen)) throw new Error('bad point: ZERO');
|
|
188
190
|
x = field.div(xNum, xDen); // xNum / xDen
|
|
189
191
|
y = field.mul(y, field.div(yNum, yDen)); // y * (yNum / yDev)
|
|
190
192
|
return { x: x, y: y };
|
package/src/abstract/modular.ts
CHANGED
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
* @module
|
|
6
6
|
*/
|
|
7
7
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
8
|
-
import { mod, pow } from './modular.
|
|
8
|
+
import { mod, pow } from './modular.ts';
|
|
9
9
|
import {
|
|
10
10
|
aInRange,
|
|
11
11
|
bytesToNumberLE,
|
|
12
12
|
ensureBytes,
|
|
13
13
|
numberToBytesLE,
|
|
14
14
|
validateObject,
|
|
15
|
-
} from './utils.
|
|
15
|
+
} from './utils.ts';
|
|
16
16
|
|
|
17
17
|
const _0n = BigInt(0);
|
|
18
18
|
const _1n = BigInt(1);
|
package/src/abstract/poseidon.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @module
|
|
8
8
|
*/
|
|
9
9
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
10
|
-
import { FpPow, IField, validateField } from './modular.
|
|
10
|
+
import { FpPow, type IField, validateField } from './modular.ts';
|
|
11
11
|
|
|
12
12
|
export type PoseidonOpts = {
|
|
13
13
|
Fp: IField<bigint>;
|
package/src/abstract/tower.ts
CHANGED
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
* @module
|
|
11
11
|
*/
|
|
12
12
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
13
|
-
import * as mod from './modular.
|
|
14
|
-
import { bitLen, bitMask, concatBytes, notImplemented } from './utils.
|
|
15
|
-
import type { ProjConstructor, ProjPointType } from './weierstrass.
|
|
13
|
+
import * as mod from './modular.ts';
|
|
14
|
+
import { bitLen, bitMask, concatBytes, notImplemented } from './utils.ts';
|
|
15
|
+
import type { ProjConstructor, ProjPointType } from './weierstrass.ts';
|
|
16
16
|
|
|
17
17
|
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
|
18
18
|
// prettier-ignore
|
|
@@ -540,9 +540,9 @@ export function tower12(opts: Tower12Opts): {
|
|
|
540
540
|
const Fp12: mod.IField<Fp12> & Fp12Utils = {
|
|
541
541
|
ORDER: Fp2.ORDER, // TODO: unused, but need to verify
|
|
542
542
|
isLE: Fp6.isLE,
|
|
543
|
-
BITS: 2 *
|
|
544
|
-
BYTES: 2 *
|
|
545
|
-
MASK: bitMask(2 *
|
|
543
|
+
BITS: 2 * Fp6.BITS,
|
|
544
|
+
BYTES: 2 * Fp6.BYTES,
|
|
545
|
+
MASK: bitMask(2 * Fp6.BITS),
|
|
546
546
|
ZERO: { c0: Fp6.ZERO, c1: Fp6.ZERO },
|
|
547
547
|
ONE: { c0: Fp6.ONE, c1: Fp6.ZERO },
|
|
548
548
|
create: (num) => num,
|
package/src/abstract/utils.ts
CHANGED
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
// won't be included into their bundle.
|
|
11
11
|
const _0n = /* @__PURE__ */ BigInt(0);
|
|
12
12
|
const _1n = /* @__PURE__ */ BigInt(1);
|
|
13
|
-
const _2n = /* @__PURE__ */ BigInt(2);
|
|
14
13
|
export type Hex = Uint8Array | string; // hex strings are accepted for simplicity
|
|
15
14
|
export type PrivKey = Hex | bigint; // bigints are accepted to ease learning curve
|
|
16
15
|
export type CHash = {
|
|
@@ -33,15 +32,34 @@ export function abool(title: string, value: boolean): void {
|
|
|
33
32
|
if (typeof value !== 'boolean') throw new Error(title + ' boolean expected, got ' + value);
|
|
34
33
|
}
|
|
35
34
|
|
|
35
|
+
export function numberToHexUnpadded(num: number | bigint): string {
|
|
36
|
+
const hex = num.toString(16);
|
|
37
|
+
return hex.length & 1 ? '0' + hex : hex;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function hexToNumber(hex: string): bigint {
|
|
41
|
+
if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);
|
|
42
|
+
return hex === '' ? _0n : BigInt('0x' + hex); // Big Endian
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex
|
|
46
|
+
const hasHexBuiltin: boolean =
|
|
47
|
+
// @ts-ignore
|
|
48
|
+
typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function';
|
|
49
|
+
|
|
36
50
|
// Array where index 0xf0 (240) is mapped to string 'f0'
|
|
37
51
|
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>
|
|
38
52
|
i.toString(16).padStart(2, '0')
|
|
39
53
|
);
|
|
54
|
+
|
|
40
55
|
/**
|
|
56
|
+
* Convert byte array to hex string. Uses built-in function, when available.
|
|
41
57
|
* @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'
|
|
42
58
|
*/
|
|
43
59
|
export function bytesToHex(bytes: Uint8Array): string {
|
|
44
60
|
abytes(bytes);
|
|
61
|
+
// @ts-ignore
|
|
62
|
+
if (hasHexBuiltin) return bytes.toHex();
|
|
45
63
|
// pre-caching improves the speed 6x
|
|
46
64
|
let hex = '';
|
|
47
65
|
for (let i = 0; i < bytes.length; i++) {
|
|
@@ -50,16 +68,6 @@ export function bytesToHex(bytes: Uint8Array): string {
|
|
|
50
68
|
return hex;
|
|
51
69
|
}
|
|
52
70
|
|
|
53
|
-
export function numberToHexUnpadded(num: number | bigint): string {
|
|
54
|
-
const hex = num.toString(16);
|
|
55
|
-
return hex.length & 1 ? '0' + hex : hex;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export function hexToNumber(hex: string): bigint {
|
|
59
|
-
if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);
|
|
60
|
-
return hex === '' ? _0n : BigInt('0x' + hex); // Big Endian
|
|
61
|
-
}
|
|
62
|
-
|
|
63
71
|
// We use optimized technique to convert hex string to byte array
|
|
64
72
|
const asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 } as const;
|
|
65
73
|
function asciiToBase16(ch: number): number | undefined {
|
|
@@ -70,10 +78,13 @@ function asciiToBase16(ch: number): number | undefined {
|
|
|
70
78
|
}
|
|
71
79
|
|
|
72
80
|
/**
|
|
81
|
+
* Convert hex string to byte array. Uses built-in function, when available.
|
|
73
82
|
* @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])
|
|
74
83
|
*/
|
|
75
84
|
export function hexToBytes(hex: string): Uint8Array {
|
|
76
85
|
if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);
|
|
86
|
+
// @ts-ignore
|
|
87
|
+
if (hasHexBuiltin) return Uint8Array.fromHex(hex);
|
|
77
88
|
const hl = hex.length;
|
|
78
89
|
const al = hl / 2;
|
|
79
90
|
if (hl % 2) throw new Error('hex string expected, got unpadded hex of length ' + hl);
|
|
@@ -233,12 +244,12 @@ export function bitSet(n: bigint, pos: number, value: boolean): bigint {
|
|
|
233
244
|
* Calculate mask for N bits. Not using ** operator with bigints because of old engines.
|
|
234
245
|
* Same as BigInt(`0b${Array(i).fill('1').join('')}`)
|
|
235
246
|
*/
|
|
236
|
-
export const bitMask = (n: number): bigint => (
|
|
247
|
+
export const bitMask = (n: number): bigint => (_1n << BigInt(n)) - _1n;
|
|
237
248
|
|
|
238
249
|
// DRBG
|
|
239
250
|
|
|
240
|
-
const u8n = (
|
|
241
|
-
const u8fr = (arr:
|
|
251
|
+
const u8n = (len: number) => new Uint8Array(len); // creates Uint8Array
|
|
252
|
+
const u8fr = (arr: ArrayLike<number>) => Uint8Array.from(arr); // another shortcut
|
|
242
253
|
type Pred<T> = (v: Uint8Array) => T | undefined;
|
|
243
254
|
/**
|
|
244
255
|
* Minimal HMAC-DRBG from NIST 800-90 for RFC6979 sigs.
|
|
@@ -265,7 +276,7 @@ export function createHmacDrbg<T>(
|
|
|
265
276
|
i = 0;
|
|
266
277
|
};
|
|
267
278
|
const h = (...b: Uint8Array[]) => hmacFn(k, v, ...b); // hmac(k)(v, ...values)
|
|
268
|
-
const reseed = (seed = u8n()) => {
|
|
279
|
+
const reseed = (seed = u8n(0)) => {
|
|
269
280
|
// HMAC-DRBG reseed() function. Steps D-G
|
|
270
281
|
k = h(u8fr([0x00]), seed); // k = hmac(k || v || 0x00 || seed)
|
|
271
282
|
v = h(); // v = hmac(k || v)
|