@noble/curves 1.0.0 → 1.1.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.
- package/README.md +165 -116
- package/_shortw_utils.d.ts +1 -1
- package/abstract/edwards.d.ts +7 -2
- package/abstract/edwards.d.ts.map +1 -1
- package/abstract/edwards.js +7 -2
- package/abstract/edwards.js.map +1 -1
- package/abstract/modular.d.ts +5 -3
- package/abstract/modular.d.ts.map +1 -1
- package/abstract/modular.js +6 -4
- package/abstract/modular.js.map +1 -1
- package/abstract/utils.d.ts +42 -5
- package/abstract/utils.d.ts.map +1 -1
- package/abstract/utils.js +68 -25
- package/abstract/utils.js.map +1 -1
- package/abstract/weierstrass.d.ts +17 -2
- package/abstract/weierstrass.d.ts.map +1 -1
- package/abstract/weierstrass.js +28 -12
- package/abstract/weierstrass.js.map +1 -1
- package/bls12-381.d.ts.map +1 -1
- package/bls12-381.js +4 -3
- package/bls12-381.js.map +1 -1
- package/ed25519.d.ts +32 -20
- package/ed25519.d.ts.map +1 -1
- package/ed25519.js +52 -33
- package/ed25519.js.map +1 -1
- package/ed448.d.ts +4 -4
- package/ed448.d.ts.map +1 -1
- package/ed448.js +12 -11
- package/ed448.js.map +1 -1
- package/esm/abstract/edwards.js +7 -2
- package/esm/abstract/edwards.js.map +1 -1
- package/esm/abstract/modular.js +6 -4
- package/esm/abstract/modular.js.map +1 -1
- package/esm/abstract/utils.js +68 -25
- package/esm/abstract/utils.js.map +1 -1
- package/esm/abstract/weierstrass.js +28 -12
- package/esm/abstract/weierstrass.js.map +1 -1
- package/esm/bls12-381.js +4 -3
- package/esm/bls12-381.js.map +1 -1
- package/esm/ed25519.js +51 -32
- package/esm/ed25519.js.map +1 -1
- package/esm/ed448.js +10 -8
- package/esm/ed448.js.map +1 -1
- package/esm/p256.js +10 -9
- package/esm/p256.js.map +1 -1
- package/esm/p384.js +7 -6
- package/esm/p384.js.map +1 -1
- package/esm/p521.js +7 -6
- package/esm/p521.js.map +1 -1
- package/esm/secp256k1.js +11 -9
- package/esm/secp256k1.js.map +1 -1
- package/p256.d.ts +4 -5
- package/p256.d.ts.map +1 -1
- package/p256.js +10 -10
- package/p256.js.map +1 -1
- package/p384.d.ts +4 -5
- package/p384.d.ts.map +1 -1
- package/p384.js +7 -7
- package/p384.js.map +1 -1
- package/p521.d.ts +4 -5
- package/p521.d.ts.map +1 -1
- package/p521.js +7 -7
- package/p521.js.map +1 -1
- package/package.json +5 -8
- package/secp256k1.d.ts +5 -5
- package/secp256k1.d.ts.map +1 -1
- package/secp256k1.js +11 -10
- package/secp256k1.js.map +1 -1
- package/src/abstract/edwards.ts +13 -4
- package/src/abstract/modular.ts +6 -8
- package/src/abstract/utils.ts +73 -32
- package/src/abstract/weierstrass.ts +39 -19
- package/src/bls12-381.ts +5 -9
- package/src/ed25519.ts +96 -69
- package/src/ed448.ts +36 -32
- package/src/p256.ts +13 -14
- package/src/p384.ts +12 -13
- package/src/p521.ts +12 -13
- package/src/secp256k1.ts +60 -55
package/src/ed25519.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
2
2
|
import { sha512 } from '@noble/hashes/sha512';
|
|
3
3
|
import { concatBytes, randomBytes, utf8ToBytes } from '@noble/hashes/utils';
|
|
4
|
-
import {
|
|
4
|
+
import { ExtPointType, twistedEdwards } from './abstract/edwards.js';
|
|
5
5
|
import { montgomery } from './abstract/montgomery.js';
|
|
6
|
-
import {
|
|
6
|
+
import { Field, FpSqrtEven, isNegativeLE, mod, pow2 } from './abstract/modular.js';
|
|
7
7
|
import {
|
|
8
|
-
equalBytes,
|
|
9
8
|
bytesToHex,
|
|
10
9
|
bytesToNumberLE,
|
|
11
|
-
numberToBytesLE,
|
|
12
|
-
Hex,
|
|
13
10
|
ensureBytes,
|
|
11
|
+
equalBytes,
|
|
12
|
+
Hex,
|
|
13
|
+
numberToBytesLE,
|
|
14
14
|
} from './abstract/utils.js';
|
|
15
|
-
import
|
|
15
|
+
import { createHasher, htfBasicOpts, expand_message_xmd } from './abstract/hash-to-curve.js';
|
|
16
16
|
import { AffinePoint } from './abstract/curve.js';
|
|
17
17
|
|
|
18
18
|
/**
|
|
@@ -34,6 +34,7 @@ const ED25519_SQRT_M1 = BigInt(
|
|
|
34
34
|
const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _5n = BigInt(5);
|
|
35
35
|
// prettier-ignore
|
|
36
36
|
const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
|
|
37
|
+
|
|
37
38
|
function ed25519_pow_2_252_3(x: bigint) {
|
|
38
39
|
const P = ED25519_P;
|
|
39
40
|
const x2 = (x * x) % P;
|
|
@@ -51,6 +52,7 @@ function ed25519_pow_2_252_3(x: bigint) {
|
|
|
51
52
|
// ^ To pow to (p+3)/8, multiply it by x.
|
|
52
53
|
return { pow_p_5_8, b2 };
|
|
53
54
|
}
|
|
55
|
+
|
|
54
56
|
function adjustScalarBytes(bytes: Uint8Array): Uint8Array {
|
|
55
57
|
// Section 5: For X25519, in order to decode 32 random bytes as an integer scalar,
|
|
56
58
|
// set the three least significant bits of the first byte
|
|
@@ -61,6 +63,7 @@ function adjustScalarBytes(bytes: Uint8Array): Uint8Array {
|
|
|
61
63
|
bytes[31] |= 64; // 0b0100_0000
|
|
62
64
|
return bytes;
|
|
63
65
|
}
|
|
66
|
+
|
|
64
67
|
// sqrt(u/v)
|
|
65
68
|
function uvRatio(u: bigint, v: bigint): { isValid: boolean; value: bigint } {
|
|
66
69
|
const P = ED25519_P;
|
|
@@ -101,10 +104,10 @@ const ed25519Defaults = {
|
|
|
101
104
|
// d is equal to -121665/121666 over finite field.
|
|
102
105
|
// Negative number is P - number, and division is invert(number, P)
|
|
103
106
|
d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
|
|
104
|
-
// Finite field 𝔽p over which we'll do calculations; 2n
|
|
107
|
+
// Finite field 𝔽p over which we'll do calculations; 2n**255n - 19n
|
|
105
108
|
Fp,
|
|
106
109
|
// Subgroup order: how many points curve has
|
|
107
|
-
// 2n
|
|
110
|
+
// 2n**252n + 27742317777372353535851937790883648493n;
|
|
108
111
|
n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
|
|
109
112
|
// Cofactor
|
|
110
113
|
h: BigInt(8),
|
|
@@ -121,6 +124,7 @@ const ed25519Defaults = {
|
|
|
121
124
|
} as const;
|
|
122
125
|
|
|
123
126
|
export const ed25519 = twistedEdwards(ed25519Defaults);
|
|
127
|
+
|
|
124
128
|
function ed25519_domain(data: Uint8Array, ctx: Uint8Array, phflag: boolean) {
|
|
125
129
|
if (ctx.length > 255) throw new Error('Context is too big');
|
|
126
130
|
return concatBytes(
|
|
@@ -130,6 +134,7 @@ function ed25519_domain(data: Uint8Array, ctx: Uint8Array, phflag: boolean) {
|
|
|
130
134
|
data
|
|
131
135
|
);
|
|
132
136
|
}
|
|
137
|
+
|
|
133
138
|
export const ed25519ctx = twistedEdwards({ ...ed25519Defaults, domain: ed25519_domain });
|
|
134
139
|
export const ed25519ph = twistedEdwards({
|
|
135
140
|
...ed25519Defaults,
|
|
@@ -137,34 +142,49 @@ export const ed25519ph = twistedEdwards({
|
|
|
137
142
|
prehash: sha512,
|
|
138
143
|
});
|
|
139
144
|
|
|
140
|
-
export const x25519 =
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
145
|
+
export const x25519 = /* @__PURE__ */ (() =>
|
|
146
|
+
montgomery({
|
|
147
|
+
P: ED25519_P,
|
|
148
|
+
a: BigInt(486662),
|
|
149
|
+
montgomeryBits: 255, // n is 253 bits
|
|
150
|
+
nByteLength: 32,
|
|
151
|
+
Gu: BigInt(9),
|
|
152
|
+
powPminus2: (x: bigint): bigint => {
|
|
153
|
+
const P = ED25519_P;
|
|
154
|
+
// x^(p-2) aka x^(2^255-21)
|
|
155
|
+
const { pow_p_5_8, b2 } = ed25519_pow_2_252_3(x);
|
|
156
|
+
return mod(pow2(pow_p_5_8, BigInt(3), P) * b2, P);
|
|
157
|
+
},
|
|
158
|
+
adjustScalarBytes,
|
|
159
|
+
randomBytes,
|
|
160
|
+
}))();
|
|
155
161
|
|
|
156
162
|
/**
|
|
157
163
|
* Converts ed25519 public key to x25519 public key. Uses formula:
|
|
158
164
|
* * `(u, v) = ((1+y)/(1-y), sqrt(-486664)*u/x)`
|
|
159
165
|
* * `(x, y) = (sqrt(-486664)*u/v, (u-1)/(u+1))`
|
|
160
166
|
* @example
|
|
161
|
-
* const
|
|
162
|
-
* x25519.
|
|
167
|
+
* const someonesPub = ed25519.getPublicKey(ed25519.utils.randomPrivateKey());
|
|
168
|
+
* const aPriv = x25519.utils.randomPrivateKey();
|
|
169
|
+
* x25519.getSharedSecret(aPriv, edwardsToMontgomeryPub(someonesPub))
|
|
163
170
|
*/
|
|
164
|
-
export function
|
|
171
|
+
export function edwardsToMontgomeryPub(edwardsPub: Hex): Uint8Array {
|
|
165
172
|
const { y } = ed25519.ExtendedPoint.fromHex(edwardsPub);
|
|
166
173
|
const _1n = BigInt(1);
|
|
167
|
-
return Fp.toBytes(Fp.create((
|
|
174
|
+
return Fp.toBytes(Fp.create((_1n + y) * Fp.inv(_1n - y)));
|
|
175
|
+
}
|
|
176
|
+
export const edwardsToMontgomery = edwardsToMontgomeryPub; // deprecated
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Converts ed25519 secret key to x25519 secret key.
|
|
180
|
+
* @example
|
|
181
|
+
* const someonesPub = x25519.getPublicKey(x25519.utils.randomPrivateKey());
|
|
182
|
+
* const aPriv = ed25519.utils.randomPrivateKey();
|
|
183
|
+
* x25519.getSharedSecret(edwardsToMontgomeryPriv(aPriv), someonesPub)
|
|
184
|
+
*/
|
|
185
|
+
export function edwardsToMontgomeryPriv(edwardsPriv: Uint8Array): Uint8Array {
|
|
186
|
+
const hashed = ed25519Defaults.hash(edwardsPriv.subarray(0, 32));
|
|
187
|
+
return ed25519Defaults.adjustScalarBytes(hashed).subarray(0, 32);
|
|
168
188
|
}
|
|
169
189
|
|
|
170
190
|
// Hash To Curve Elligator2 Map (NOTE: different from ristretto255 elligator)
|
|
@@ -223,7 +243,8 @@ function map_to_curve_elligator2_curve25519(u: bigint) {
|
|
|
223
243
|
|
|
224
244
|
const ELL2_C1_EDWARDS = FpSqrtEven(Fp, Fp.neg(BigInt(486664))); // sgn0(c1) MUST equal 0
|
|
225
245
|
function map_to_curve_elligator2_edwards25519(u: bigint) {
|
|
226
|
-
const { xMn, xMd, yMn, yMd } = map_to_curve_elligator2_curve25519(u); // 1. (xMn, xMd, yMn, yMd) =
|
|
246
|
+
const { xMn, xMd, yMn, yMd } = map_to_curve_elligator2_curve25519(u); // 1. (xMn, xMd, yMn, yMd) =
|
|
247
|
+
// map_to_curve_elligator2_curve25519(u)
|
|
227
248
|
let xn = Fp.mul(xMn, yMd); // 2. xn = xMn * yMd
|
|
228
249
|
xn = Fp.mul(xn, ELL2_C1_EDWARDS); // 3. xn = xn * c1
|
|
229
250
|
let xd = Fp.mul(xMd, yMn); // 4. xd = xMd * yMn # xn / xd = c1 * xM / yM
|
|
@@ -239,28 +260,30 @@ function map_to_curve_elligator2_edwards25519(u: bigint) {
|
|
|
239
260
|
const inv = Fp.invertBatch([xd, yd]); // batch division
|
|
240
261
|
return { x: Fp.mul(xn, inv[0]), y: Fp.mul(yn, inv[1]) }; // 13. return (xn, xd, yn, yd)
|
|
241
262
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
(
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
263
|
+
|
|
264
|
+
const htf = /* @__PURE__ */ (() =>
|
|
265
|
+
createHasher(
|
|
266
|
+
ed25519.ExtendedPoint,
|
|
267
|
+
(scalars: bigint[]) => map_to_curve_elligator2_edwards25519(scalars[0]),
|
|
268
|
+
{
|
|
269
|
+
DST: 'edwards25519_XMD:SHA-512_ELL2_RO_',
|
|
270
|
+
encodeDST: 'edwards25519_XMD:SHA-512_ELL2_NU_',
|
|
271
|
+
p: Fp.ORDER,
|
|
272
|
+
m: 1,
|
|
273
|
+
k: 128,
|
|
274
|
+
expand: 'xmd',
|
|
275
|
+
hash: sha512,
|
|
276
|
+
}
|
|
277
|
+
))();
|
|
278
|
+
export const hashToCurve = /* @__PURE__ */ (() => htf.hashToCurve)();
|
|
279
|
+
export const encodeToCurve = /* @__PURE__ */ (() => htf.encodeToCurve)();
|
|
256
280
|
|
|
257
281
|
function assertRstPoint(other: unknown) {
|
|
258
|
-
if (!(other instanceof
|
|
282
|
+
if (!(other instanceof RistPoint)) throw new Error('RistrettoPoint expected');
|
|
259
283
|
}
|
|
284
|
+
|
|
260
285
|
// √(-1) aka √(a) aka 2^((p-1)/4)
|
|
261
|
-
const SQRT_M1 =
|
|
262
|
-
'19681161376707505956807079304988542015446066515923890162744021073123829784752'
|
|
263
|
-
);
|
|
286
|
+
const SQRT_M1 = ED25519_SQRT_M1;
|
|
264
287
|
// √(ad - 1)
|
|
265
288
|
const SQRT_AD_MINUS_ONE = BigInt(
|
|
266
289
|
'25063068953384623474111414158702152701244531502492656460079210482610430750235'
|
|
@@ -317,32 +340,31 @@ function calcElligatorRistrettoMap(r0: bigint): ExtendedPoint {
|
|
|
317
340
|
* but it should work in its own namespace: do not combine those two.
|
|
318
341
|
* https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-ristretto255-decaf448
|
|
319
342
|
*/
|
|
320
|
-
|
|
321
|
-
static BASE
|
|
322
|
-
static ZERO
|
|
323
|
-
|
|
343
|
+
class RistPoint {
|
|
344
|
+
static BASE: RistPoint;
|
|
345
|
+
static ZERO: RistPoint;
|
|
324
346
|
// Private property to discourage combining ExtendedPoint + RistrettoPoint
|
|
325
347
|
// Always use Ristretto encoding/decoding instead.
|
|
326
348
|
constructor(private readonly ep: ExtendedPoint) {}
|
|
327
349
|
|
|
328
350
|
static fromAffine(ap: AffinePoint<bigint>) {
|
|
329
|
-
return new
|
|
351
|
+
return new RistPoint(ed25519.ExtendedPoint.fromAffine(ap));
|
|
330
352
|
}
|
|
331
353
|
|
|
332
354
|
/**
|
|
333
|
-
* Takes uniform output of 64-
|
|
355
|
+
* Takes uniform output of 64-byte hash function like sha512 and converts it to `RistrettoPoint`.
|
|
334
356
|
* The hash-to-group operation applies Elligator twice and adds the results.
|
|
335
357
|
* **Note:** this is one-way map, there is no conversion from point to hash.
|
|
336
358
|
* https://ristretto.group/formulas/elligator.html
|
|
337
|
-
* @param hex 64-
|
|
359
|
+
* @param hex 64-byte output of a hash function
|
|
338
360
|
*/
|
|
339
|
-
static hashToCurve(hex: Hex):
|
|
361
|
+
static hashToCurve(hex: Hex): RistPoint {
|
|
340
362
|
hex = ensureBytes('ristrettoHash', hex, 64);
|
|
341
363
|
const r1 = bytes255ToNumberLE(hex.slice(0, 32));
|
|
342
364
|
const R1 = calcElligatorRistrettoMap(r1);
|
|
343
365
|
const r2 = bytes255ToNumberLE(hex.slice(32, 64));
|
|
344
366
|
const R2 = calcElligatorRistrettoMap(r2);
|
|
345
|
-
return new
|
|
367
|
+
return new RistPoint(R1.add(R2));
|
|
346
368
|
}
|
|
347
369
|
|
|
348
370
|
/**
|
|
@@ -350,7 +372,7 @@ export class RistrettoPoint {
|
|
|
350
372
|
* https://ristretto.group/formulas/decoding.html
|
|
351
373
|
* @param hex Ristretto-encoded 32 bytes. Not every 32-byte string is valid ristretto encoding
|
|
352
374
|
*/
|
|
353
|
-
static fromHex(hex: Hex):
|
|
375
|
+
static fromHex(hex: Hex): RistPoint {
|
|
354
376
|
hex = ensureBytes('ristrettoHex', hex, 32);
|
|
355
377
|
const { a, d } = ed25519.CURVE;
|
|
356
378
|
const P = ed25519.CURVE.Fp.ORDER;
|
|
@@ -374,7 +396,7 @@ export class RistrettoPoint {
|
|
|
374
396
|
const y = mod(u1 * Dy); // 11
|
|
375
397
|
const t = mod(x * y); // 12
|
|
376
398
|
if (!isValid || isNegativeLE(t, P) || y === _0n) throw new Error(emsg);
|
|
377
|
-
return new
|
|
399
|
+
return new RistPoint(new ed25519.ExtendedPoint(x, y, _1n, t));
|
|
378
400
|
}
|
|
379
401
|
|
|
380
402
|
/**
|
|
@@ -418,7 +440,7 @@ export class RistrettoPoint {
|
|
|
418
440
|
}
|
|
419
441
|
|
|
420
442
|
// Compare one point to another.
|
|
421
|
-
equals(other:
|
|
443
|
+
equals(other: RistPoint): boolean {
|
|
422
444
|
assertRstPoint(other);
|
|
423
445
|
const { ex: X1, ey: Y1 } = this.ep;
|
|
424
446
|
const { ex: X2, ey: Y2 } = other.ep;
|
|
@@ -429,31 +451,36 @@ export class RistrettoPoint {
|
|
|
429
451
|
return one || two;
|
|
430
452
|
}
|
|
431
453
|
|
|
432
|
-
add(other:
|
|
454
|
+
add(other: RistPoint): RistPoint {
|
|
433
455
|
assertRstPoint(other);
|
|
434
|
-
return new
|
|
456
|
+
return new RistPoint(this.ep.add(other.ep));
|
|
435
457
|
}
|
|
436
458
|
|
|
437
|
-
subtract(other:
|
|
459
|
+
subtract(other: RistPoint): RistPoint {
|
|
438
460
|
assertRstPoint(other);
|
|
439
|
-
return new
|
|
461
|
+
return new RistPoint(this.ep.subtract(other.ep));
|
|
440
462
|
}
|
|
441
463
|
|
|
442
|
-
multiply(scalar: bigint):
|
|
443
|
-
return new
|
|
464
|
+
multiply(scalar: bigint): RistPoint {
|
|
465
|
+
return new RistPoint(this.ep.multiply(scalar));
|
|
444
466
|
}
|
|
445
467
|
|
|
446
|
-
multiplyUnsafe(scalar: bigint):
|
|
447
|
-
return new
|
|
468
|
+
multiplyUnsafe(scalar: bigint): RistPoint {
|
|
469
|
+
return new RistPoint(this.ep.multiplyUnsafe(scalar));
|
|
448
470
|
}
|
|
449
471
|
}
|
|
472
|
+
export const RistrettoPoint = /* @__PURE__ */ (() => {
|
|
473
|
+
if (!RistPoint.BASE) RistPoint.BASE = new RistPoint(ed25519.ExtendedPoint.BASE);
|
|
474
|
+
if (!RistPoint.ZERO) RistPoint.ZERO = new RistPoint(ed25519.ExtendedPoint.ZERO);
|
|
475
|
+
return RistPoint;
|
|
476
|
+
})();
|
|
450
477
|
|
|
451
478
|
// https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/14/
|
|
452
479
|
// Appendix B. Hashing to ristretto255
|
|
453
|
-
export const hash_to_ristretto255 = (msg: Uint8Array, options:
|
|
480
|
+
export const hash_to_ristretto255 = (msg: Uint8Array, options: htfBasicOpts) => {
|
|
454
481
|
const d = options.DST;
|
|
455
482
|
const DST = typeof d === 'string' ? utf8ToBytes(d) : d;
|
|
456
|
-
const uniform_bytes =
|
|
457
|
-
const P =
|
|
483
|
+
const uniform_bytes = expand_message_xmd(msg, DST, 64, sha512);
|
|
484
|
+
const P = RistPoint.hashToCurve(uniform_bytes);
|
|
458
485
|
return P;
|
|
459
486
|
};
|
package/src/ed448.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { concatBytes, randomBytes, utf8ToBytes, wrapConstructor } from '@noble/h
|
|
|
4
4
|
import { twistedEdwards } from './abstract/edwards.js';
|
|
5
5
|
import { mod, pow2, Field } from './abstract/modular.js';
|
|
6
6
|
import { montgomery } from './abstract/montgomery.js';
|
|
7
|
-
import
|
|
7
|
+
import { createHasher } from './abstract/hash-to-curve.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Edwards448 (not Ed448-Goldilocks) curve with following addons:
|
|
@@ -63,7 +63,7 @@ const ED448_DEF = {
|
|
|
63
63
|
d: BigInt(
|
|
64
64
|
'726838724295606890549323807888004534353641360687318060281490199180612328166730772686396383698676545930088884461843637361053498018326358'
|
|
65
65
|
),
|
|
66
|
-
// Finite field 𝔽p over which we'll do calculations; 2n
|
|
66
|
+
// Finite field 𝔽p over which we'll do calculations; 2n**448n - 2n**224n - 1n
|
|
67
67
|
Fp,
|
|
68
68
|
// Subgroup order: how many points curve has;
|
|
69
69
|
// 2n**446n - 13818066809895115352007386748515426880336692474882178609894547503885n
|
|
@@ -122,21 +122,22 @@ export const ed448 = twistedEdwards(ED448_DEF);
|
|
|
122
122
|
// NOTE: there is no ed448ctx, since ed448 supports ctx by default
|
|
123
123
|
export const ed448ph = twistedEdwards({ ...ED448_DEF, prehash: shake256_64 });
|
|
124
124
|
|
|
125
|
-
export const x448 =
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
125
|
+
export const x448 = /* @__PURE__ */ (() =>
|
|
126
|
+
montgomery({
|
|
127
|
+
a: BigInt(156326),
|
|
128
|
+
montgomeryBits: 448,
|
|
129
|
+
nByteLength: 57,
|
|
130
|
+
P: ed448P,
|
|
131
|
+
Gu: BigInt(5),
|
|
132
|
+
powPminus2: (x: bigint): bigint => {
|
|
133
|
+
const P = ed448P;
|
|
134
|
+
const Pminus3div4 = ed448_pow_Pminus3div4(x);
|
|
135
|
+
const Pminus3 = pow2(Pminus3div4, BigInt(2), P);
|
|
136
|
+
return mod(Pminus3 * x, P); // Pminus3 * x = Pminus2
|
|
137
|
+
},
|
|
138
|
+
adjustScalarBytes,
|
|
139
|
+
randomBytes,
|
|
140
|
+
}))();
|
|
140
141
|
|
|
141
142
|
/**
|
|
142
143
|
* Converts edwards448 public key to x448 public key. Uses formula:
|
|
@@ -146,11 +147,12 @@ export const x448 = montgomery({
|
|
|
146
147
|
* const aPub = ed448.getPublicKey(utils.randomPrivateKey());
|
|
147
148
|
* x448.getSharedSecret(edwardsToMontgomery(aPub), edwardsToMontgomery(someonesPub))
|
|
148
149
|
*/
|
|
149
|
-
export function
|
|
150
|
+
export function edwardsToMontgomeryPub(edwardsPub: string | Uint8Array): Uint8Array {
|
|
150
151
|
const { y } = ed448.ExtendedPoint.fromHex(edwardsPub);
|
|
151
152
|
const _1n = BigInt(1);
|
|
152
153
|
return Fp.toBytes(Fp.create((y - _1n) * Fp.inv(y + _1n)));
|
|
153
154
|
}
|
|
155
|
+
export const edwardsToMontgomery = edwardsToMontgomeryPub; // deprecated
|
|
154
156
|
|
|
155
157
|
// Hash To Curve Elligator2 Map
|
|
156
158
|
const ELL2_C1 = (Fp.ORDER - BigInt(3)) / BigInt(4); // 1. c1 = (q - 3) / 4 # Integer arithmetic
|
|
@@ -227,17 +229,19 @@ function map_to_curve_elligator2_edwards448(u: bigint) {
|
|
|
227
229
|
return { x: Fp.mul(xEn, inv[0]), y: Fp.mul(yEn, inv[1]) }; // 38. return (xEn, xEd, yEn, yEd)
|
|
228
230
|
}
|
|
229
231
|
|
|
230
|
-
const
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
232
|
+
const htf = /* @__PURE__ */ (() =>
|
|
233
|
+
createHasher(
|
|
234
|
+
ed448.ExtendedPoint,
|
|
235
|
+
(scalars: bigint[]) => map_to_curve_elligator2_edwards448(scalars[0]),
|
|
236
|
+
{
|
|
237
|
+
DST: 'edwards448_XOF:SHAKE256_ELL2_RO_',
|
|
238
|
+
encodeDST: 'edwards448_XOF:SHAKE256_ELL2_NU_',
|
|
239
|
+
p: Fp.ORDER,
|
|
240
|
+
m: 1,
|
|
241
|
+
k: 224,
|
|
242
|
+
expand: 'xof',
|
|
243
|
+
hash: shake256,
|
|
244
|
+
}
|
|
245
|
+
))();
|
|
246
|
+
export const hashToCurve = /* @__PURE__ */ (() => htf.hashToCurve)();
|
|
247
|
+
export const encodeToCurve = /* @__PURE__ */ (() => htf.encodeToCurve)();
|
package/src/p256.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { createCurve } from './_shortw_utils.js';
|
|
|
3
3
|
import { sha256 } from '@noble/hashes/sha256';
|
|
4
4
|
import { Field } from './abstract/modular.js';
|
|
5
5
|
import { mapToCurveSimpleSWU } from './abstract/weierstrass.js';
|
|
6
|
-
import
|
|
6
|
+
import { createHasher } from './abstract/hash-to-curve.js';
|
|
7
7
|
|
|
8
8
|
// NIST secp256r1 aka p256
|
|
9
9
|
// https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-256
|
|
@@ -12,12 +12,6 @@ const Fp = Field(BigInt('0xffffffff00000001000000000000000000000000fffffffffffff
|
|
|
12
12
|
const CURVE_A = Fp.create(BigInt('-3'));
|
|
13
13
|
const CURVE_B = BigInt('0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b');
|
|
14
14
|
|
|
15
|
-
const mapSWU = mapToCurveSimpleSWU(Fp, {
|
|
16
|
-
A: CURVE_A,
|
|
17
|
-
B: CURVE_B,
|
|
18
|
-
Z: Fp.create(BigInt('-10')),
|
|
19
|
-
});
|
|
20
|
-
|
|
21
15
|
// prettier-ignore
|
|
22
16
|
export const p256 = createCurve({
|
|
23
17
|
a: CURVE_A, // Equation params: a, b
|
|
@@ -33,10 +27,15 @@ export const p256 = createCurve({
|
|
|
33
27
|
} as const, sha256);
|
|
34
28
|
export const secp256r1 = p256;
|
|
35
29
|
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
30
|
+
const mapSWU = /* @__PURE__ */ (() =>
|
|
31
|
+
mapToCurveSimpleSWU(Fp, {
|
|
32
|
+
A: CURVE_A,
|
|
33
|
+
B: CURVE_B,
|
|
34
|
+
Z: Fp.create(BigInt('-10')),
|
|
35
|
+
}))();
|
|
36
|
+
|
|
37
|
+
const htf = /* @__PURE__ */ (() =>
|
|
38
|
+
createHasher(secp256r1.ProjectivePoint, (scalars: bigint[]) => mapSWU(scalars[0]), {
|
|
40
39
|
DST: 'P256_XMD:SHA-256_SSWU_RO_',
|
|
41
40
|
encodeDST: 'P256_XMD:SHA-256_SSWU_NU_',
|
|
42
41
|
p: Fp.ORDER,
|
|
@@ -44,6 +43,6 @@ const { hashToCurve, encodeToCurve } = htf.createHasher(
|
|
|
44
43
|
k: 128,
|
|
45
44
|
expand: 'xmd',
|
|
46
45
|
hash: sha256,
|
|
47
|
-
}
|
|
48
|
-
);
|
|
49
|
-
export
|
|
46
|
+
}))();
|
|
47
|
+
export const hashToCurve = /* @__PURE__ */ (() => htf.hashToCurve)();
|
|
48
|
+
export const encodeToCurve = /* @__PURE__ */ (() => htf.encodeToCurve)();
|
package/src/p384.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { createCurve } from './_shortw_utils.js';
|
|
|
3
3
|
import { sha384 } from '@noble/hashes/sha512';
|
|
4
4
|
import { Field } from './abstract/modular.js';
|
|
5
5
|
import { mapToCurveSimpleSWU } from './abstract/weierstrass.js';
|
|
6
|
-
import
|
|
6
|
+
import { createHasher } from './abstract/hash-to-curve.js';
|
|
7
7
|
|
|
8
8
|
// NIST secp384r1 aka p384
|
|
9
9
|
// https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-384
|
|
@@ -31,16 +31,15 @@ export const p384 = createCurve({
|
|
|
31
31
|
} as const, sha384);
|
|
32
32
|
export const secp384r1 = p384;
|
|
33
33
|
|
|
34
|
-
const mapSWU =
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
const mapSWU = /* @__PURE__ */ (() =>
|
|
35
|
+
mapToCurveSimpleSWU(Fp, {
|
|
36
|
+
A: CURVE_A,
|
|
37
|
+
B: CURVE_B,
|
|
38
|
+
Z: Fp.create(BigInt('-12')),
|
|
39
|
+
}))();
|
|
39
40
|
|
|
40
|
-
const
|
|
41
|
-
secp384r1.ProjectivePoint,
|
|
42
|
-
(scalars: bigint[]) => mapSWU(scalars[0]),
|
|
43
|
-
{
|
|
41
|
+
const htf = /* @__PURE__ */ (() =>
|
|
42
|
+
createHasher(secp384r1.ProjectivePoint, (scalars: bigint[]) => mapSWU(scalars[0]), {
|
|
44
43
|
DST: 'P384_XMD:SHA-384_SSWU_RO_',
|
|
45
44
|
encodeDST: 'P384_XMD:SHA-384_SSWU_NU_',
|
|
46
45
|
p: Fp.ORDER,
|
|
@@ -48,6 +47,6 @@ const { hashToCurve, encodeToCurve } = htf.createHasher(
|
|
|
48
47
|
k: 192,
|
|
49
48
|
expand: 'xmd',
|
|
50
49
|
hash: sha384,
|
|
51
|
-
}
|
|
52
|
-
);
|
|
53
|
-
export
|
|
50
|
+
}))();
|
|
51
|
+
export const hashToCurve = /* @__PURE__ */ (() => htf.hashToCurve)();
|
|
52
|
+
export const encodeToCurve = /* @__PURE__ */ (() => htf.encodeToCurve)();
|
package/src/p521.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { createCurve } from './_shortw_utils.js';
|
|
|
3
3
|
import { sha512 } from '@noble/hashes/sha512';
|
|
4
4
|
import { Field } from './abstract/modular.js';
|
|
5
5
|
import { mapToCurveSimpleSWU } from './abstract/weierstrass.js';
|
|
6
|
-
import
|
|
6
|
+
import { createHasher } from './abstract/hash-to-curve.js';
|
|
7
7
|
|
|
8
8
|
// NIST secp521r1 aka p521
|
|
9
9
|
// Note that it's 521, which differs from 512 of its hash function.
|
|
@@ -47,16 +47,15 @@ export const p521 = createCurve({
|
|
|
47
47
|
} as const, sha512);
|
|
48
48
|
export const secp521r1 = p521;
|
|
49
49
|
|
|
50
|
-
const mapSWU =
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
50
|
+
const mapSWU = /* @__PURE__ */ (() =>
|
|
51
|
+
mapToCurveSimpleSWU(Fp, {
|
|
52
|
+
A: CURVE.a,
|
|
53
|
+
B: CURVE.b,
|
|
54
|
+
Z: Fp.create(BigInt('-4')),
|
|
55
|
+
}))();
|
|
55
56
|
|
|
56
|
-
const
|
|
57
|
-
secp521r1.ProjectivePoint,
|
|
58
|
-
(scalars: bigint[]) => mapSWU(scalars[0]),
|
|
59
|
-
{
|
|
57
|
+
const htf = /* @__PURE__ */ (() =>
|
|
58
|
+
createHasher(secp521r1.ProjectivePoint, (scalars: bigint[]) => mapSWU(scalars[0]), {
|
|
60
59
|
DST: 'P521_XMD:SHA-512_SSWU_RO_',
|
|
61
60
|
encodeDST: 'P521_XMD:SHA-512_SSWU_NU_',
|
|
62
61
|
p: Fp.ORDER,
|
|
@@ -64,6 +63,6 @@ const { hashToCurve, encodeToCurve } = htf.createHasher(
|
|
|
64
63
|
k: 256,
|
|
65
64
|
expand: 'xmd',
|
|
66
65
|
hash: sha512,
|
|
67
|
-
}
|
|
68
|
-
);
|
|
69
|
-
export
|
|
66
|
+
}))();
|
|
67
|
+
export const hashToCurve = /* @__PURE__ */ (() => htf.hashToCurve)();
|
|
68
|
+
export const encodeToCurve = /* @__PURE__ */ (() => htf.encodeToCurve)();
|