@noble/curves 2.0.1 → 2.2.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 +214 -122
- package/abstract/bls.d.ts +299 -16
- package/abstract/bls.d.ts.map +1 -1
- package/abstract/bls.js +82 -22
- package/abstract/bls.js.map +1 -1
- package/abstract/curve.d.ts +274 -27
- package/abstract/curve.d.ts.map +1 -1
- package/abstract/curve.js +177 -23
- package/abstract/curve.js.map +1 -1
- package/abstract/edwards.d.ts +166 -30
- package/abstract/edwards.d.ts.map +1 -1
- package/abstract/edwards.js +221 -86
- package/abstract/edwards.js.map +1 -1
- package/abstract/fft.d.ts +322 -10
- package/abstract/fft.d.ts.map +1 -1
- package/abstract/fft.js +154 -12
- package/abstract/fft.js.map +1 -1
- package/abstract/frost.d.ts +293 -0
- package/abstract/frost.d.ts.map +1 -0
- package/abstract/frost.js +704 -0
- package/abstract/frost.js.map +1 -0
- package/abstract/hash-to-curve.d.ts +173 -24
- package/abstract/hash-to-curve.d.ts.map +1 -1
- package/abstract/hash-to-curve.js +170 -31
- package/abstract/hash-to-curve.js.map +1 -1
- package/abstract/modular.d.ts +429 -37
- package/abstract/modular.d.ts.map +1 -1
- package/abstract/modular.js +414 -119
- package/abstract/modular.js.map +1 -1
- package/abstract/montgomery.d.ts +83 -12
- package/abstract/montgomery.d.ts.map +1 -1
- package/abstract/montgomery.js +32 -7
- package/abstract/montgomery.js.map +1 -1
- package/abstract/oprf.d.ts +164 -91
- package/abstract/oprf.d.ts.map +1 -1
- package/abstract/oprf.js +88 -29
- package/abstract/oprf.js.map +1 -1
- package/abstract/poseidon.d.ts +138 -7
- package/abstract/poseidon.d.ts.map +1 -1
- package/abstract/poseidon.js +178 -15
- package/abstract/poseidon.js.map +1 -1
- package/abstract/tower.d.ts +122 -3
- package/abstract/tower.d.ts.map +1 -1
- package/abstract/tower.js +323 -139
- package/abstract/tower.js.map +1 -1
- package/abstract/weierstrass.d.ts +339 -76
- package/abstract/weierstrass.d.ts.map +1 -1
- package/abstract/weierstrass.js +395 -205
- package/abstract/weierstrass.js.map +1 -1
- package/bls12-381.d.ts +16 -2
- package/bls12-381.d.ts.map +1 -1
- package/bls12-381.js +199 -209
- package/bls12-381.js.map +1 -1
- package/bn254.d.ts +11 -2
- package/bn254.d.ts.map +1 -1
- package/bn254.js +93 -38
- package/bn254.js.map +1 -1
- package/ed25519.d.ts +125 -14
- package/ed25519.d.ts.map +1 -1
- package/ed25519.js +202 -40
- package/ed25519.js.map +1 -1
- package/ed448.d.ts +108 -14
- package/ed448.d.ts.map +1 -1
- package/ed448.js +194 -42
- package/ed448.js.map +1 -1
- package/index.js +7 -1
- package/index.js.map +1 -1
- package/misc.d.ts +106 -7
- package/misc.d.ts.map +1 -1
- package/misc.js +141 -32
- package/misc.js.map +1 -1
- package/nist.d.ts +112 -11
- package/nist.d.ts.map +1 -1
- package/nist.js +139 -17
- package/nist.js.map +1 -1
- package/package.json +11 -6
- package/secp256k1.d.ts +92 -15
- package/secp256k1.d.ts.map +1 -1
- package/secp256k1.js +211 -28
- package/secp256k1.js.map +1 -1
- package/src/abstract/bls.ts +350 -67
- package/src/abstract/curve.ts +327 -44
- package/src/abstract/edwards.ts +367 -143
- package/src/abstract/fft.ts +369 -36
- package/src/abstract/frost.ts +1092 -0
- package/src/abstract/hash-to-curve.ts +255 -56
- package/src/abstract/modular.ts +591 -144
- package/src/abstract/montgomery.ts +114 -30
- package/src/abstract/oprf.ts +383 -194
- package/src/abstract/poseidon.ts +235 -35
- package/src/abstract/tower.ts +428 -159
- package/src/abstract/weierstrass.ts +710 -312
- package/src/bls12-381.ts +239 -236
- package/src/bn254.ts +107 -46
- package/src/ed25519.ts +227 -55
- package/src/ed448.ts +227 -57
- package/src/index.ts +7 -1
- package/src/misc.ts +154 -35
- package/src/nist.ts +143 -20
- package/src/secp256k1.ts +284 -41
- package/src/utils.ts +583 -81
- package/src/webcrypto.ts +302 -73
- package/utils.d.ts +457 -24
- package/utils.d.ts.map +1 -1
- package/utils.js +410 -53
- package/utils.js.map +1 -1
- package/webcrypto.d.ts +167 -25
- package/webcrypto.d.ts.map +1 -1
- package/webcrypto.js +165 -58
- package/webcrypto.js.map +1 -1
|
@@ -14,6 +14,8 @@ import {
|
|
|
14
14
|
randomBytes,
|
|
15
15
|
validateObject,
|
|
16
16
|
type CryptoKeys,
|
|
17
|
+
type TArg,
|
|
18
|
+
type TRet,
|
|
17
19
|
} from '../utils.ts';
|
|
18
20
|
import { createKeygen, type CurveLengths } from './curve.ts';
|
|
19
21
|
import { mod } from './modular.ts';
|
|
@@ -22,41 +24,118 @@ const _0n = BigInt(0);
|
|
|
22
24
|
const _1n = BigInt(1);
|
|
23
25
|
const _2n = BigInt(2);
|
|
24
26
|
|
|
27
|
+
/** Curve-specific hooks required to build one X25519/X448 helper. */
|
|
25
28
|
export type MontgomeryOpts = {
|
|
26
|
-
|
|
29
|
+
/** Prime field modulus. */
|
|
30
|
+
P: bigint;
|
|
31
|
+
/** RFC 7748 variant name. */
|
|
27
32
|
type: 'x25519' | 'x448';
|
|
28
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Clamp or otherwise normalize one scalar byte string before use.
|
|
35
|
+
* @param bytes - Raw secret scalar bytes.
|
|
36
|
+
* @returns Adjusted scalar bytes ready for Montgomery multiplication.
|
|
37
|
+
*/
|
|
38
|
+
adjustScalarBytes: (bytes: TArg<Uint8Array>) => TRet<Uint8Array>;
|
|
39
|
+
/**
|
|
40
|
+
* Invert one field element with exponentiation by `p - 2`.
|
|
41
|
+
* @param x - Field element to invert.
|
|
42
|
+
* @returns Multiplicative inverse of `x`.
|
|
43
|
+
*/
|
|
29
44
|
powPminus2: (x: bigint) => bigint;
|
|
30
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Optional randomness source for `keygen()` and `utils.randomSecretKey()`.
|
|
47
|
+
* Receives the requested byte length and returns fresh random bytes.
|
|
48
|
+
*/
|
|
49
|
+
randomBytes?: (bytesLength?: number) => TRet<Uint8Array>;
|
|
31
50
|
};
|
|
32
51
|
|
|
52
|
+
/** Public X25519/X448 ECDH API built on a Montgomery ladder. */
|
|
33
53
|
export type MontgomeryECDH = {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Multiply one scalar by one Montgomery `u` coordinate.
|
|
56
|
+
* @param scalar - Secret scalar bytes.
|
|
57
|
+
* @param u - Public Montgomery `u` coordinate.
|
|
58
|
+
* @returns Shared point encoded as bytes.
|
|
59
|
+
*/
|
|
60
|
+
scalarMult: (scalar: TArg<Uint8Array>, u: TArg<Uint8Array>) => TRet<Uint8Array>;
|
|
61
|
+
/**
|
|
62
|
+
* Multiply one scalar by the curve base point.
|
|
63
|
+
* @param scalar - Secret scalar bytes.
|
|
64
|
+
* @returns Public key bytes.
|
|
65
|
+
*/
|
|
66
|
+
scalarMultBase: (scalar: TArg<Uint8Array>) => TRet<Uint8Array>;
|
|
67
|
+
/**
|
|
68
|
+
* Derive a shared secret from a local secret key and peer public key.
|
|
69
|
+
* @param secretKeyA - Local secret key bytes.
|
|
70
|
+
* @param publicKeyB - Peer public key bytes.
|
|
71
|
+
* Rejects low-order public inputs instead of returning the all-zero shared secret.
|
|
72
|
+
* @returns Shared secret bytes.
|
|
73
|
+
*/
|
|
74
|
+
getSharedSecret: (secretKeyA: TArg<Uint8Array>, publicKeyB: TArg<Uint8Array>) => TRet<Uint8Array>;
|
|
75
|
+
/**
|
|
76
|
+
* Derive one public key from a secret key.
|
|
77
|
+
* @param secretKey - Secret key bytes.
|
|
78
|
+
* @returns Public key bytes.
|
|
79
|
+
*/
|
|
80
|
+
getPublicKey: (secretKey: TArg<Uint8Array>) => TRet<Uint8Array>;
|
|
81
|
+
/** Utility helpers for secret-key generation. */
|
|
38
82
|
utils: {
|
|
39
|
-
|
|
83
|
+
/** Generate one random secret key with the curve's expected byte length. */
|
|
84
|
+
randomSecretKey: () => TRet<Uint8Array>;
|
|
40
85
|
};
|
|
41
|
-
|
|
86
|
+
/** Encoded Montgomery base point `u`. */
|
|
87
|
+
GuBytes: TRet<Uint8Array>;
|
|
88
|
+
/** Public lengths for keys and seeds. */
|
|
42
89
|
lengths: CurveLengths;
|
|
43
|
-
|
|
90
|
+
/**
|
|
91
|
+
* Generate one random secret/public keypair.
|
|
92
|
+
* @param seed - Optional seed bytes to use instead of random generation.
|
|
93
|
+
* @returns Fresh secret/public keypair.
|
|
94
|
+
*/
|
|
95
|
+
keygen: (seed?: TArg<Uint8Array>) => {
|
|
96
|
+
secretKey: TRet<Uint8Array>;
|
|
97
|
+
publicKey: TRet<Uint8Array>;
|
|
98
|
+
};
|
|
44
99
|
};
|
|
45
100
|
|
|
46
|
-
function validateOpts(curve: MontgomeryOpts) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
101
|
+
function validateOpts(curve: TArg<MontgomeryOpts>) {
|
|
102
|
+
// Validate constructor config eagerly, but do not call user-provided hooks here:
|
|
103
|
+
// `randomBytes` may be transcript-backed or otherwise contextual. Runtime type checks are
|
|
104
|
+
// enough to fail fast on malformed configs without consuming user state.
|
|
105
|
+
validateObject(
|
|
106
|
+
curve,
|
|
107
|
+
{
|
|
108
|
+
P: 'bigint',
|
|
109
|
+
type: 'string',
|
|
110
|
+
adjustScalarBytes: 'function',
|
|
111
|
+
powPminus2: 'function',
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
randomBytes: 'function',
|
|
115
|
+
}
|
|
116
|
+
);
|
|
51
117
|
return Object.freeze({ ...curve } as const);
|
|
52
118
|
}
|
|
53
119
|
|
|
54
|
-
|
|
120
|
+
/**
|
|
121
|
+
* @param curveDef - Montgomery curve definition.
|
|
122
|
+
* @returns ECDH helper namespace.
|
|
123
|
+
* @throws If the curve definition or derived shared point is invalid. {@link Error}
|
|
124
|
+
* @example
|
|
125
|
+
* Perform one X25519 key exchange through the generic Montgomery helper.
|
|
126
|
+
*
|
|
127
|
+
* ```ts
|
|
128
|
+
* import { x25519 } from '@noble/curves/ed25519.js';
|
|
129
|
+
* const alice = x25519.keygen();
|
|
130
|
+
* const shared = x25519.getSharedSecret(alice.secretKey, alice.publicKey);
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
export function montgomery(curveDef: TArg<MontgomeryOpts>): TRet<MontgomeryECDH> {
|
|
55
134
|
const CURVE = validateOpts(curveDef);
|
|
56
135
|
const { P, type, adjustScalarBytes, powPminus2, randomBytes: rand } = CURVE;
|
|
57
136
|
const is25519 = type === 'x25519';
|
|
58
137
|
if (!is25519 && type !== 'x448') throw new Error('invalid type');
|
|
59
|
-
const randomBytes_ = rand
|
|
138
|
+
const randomBytes_ = rand === undefined ? randomBytes : rand;
|
|
60
139
|
|
|
61
140
|
const montgomeryBits = is25519 ? 255 : 448;
|
|
62
141
|
const fieldLen = is25519 ? 32 : 56;
|
|
@@ -64,7 +143,7 @@ export function montgomery(curveDef: MontgomeryOpts): MontgomeryECDH {
|
|
|
64
143
|
// RFC 7748 #5:
|
|
65
144
|
// The constant a24 is (486662 - 2) / 4 = 121665 for curve25519/X25519 and
|
|
66
145
|
// (156326 - 2) / 4 = 39081 for curve448/X448
|
|
67
|
-
// const a = is25519 ?
|
|
146
|
+
// const a = is25519 ? 486662n : 156326n;
|
|
68
147
|
const a24 = is25519 ? BigInt(121665) : BigInt(39081);
|
|
69
148
|
// RFC: x25519 "the resulting integer is of the form 2^254 plus
|
|
70
149
|
// eight times a value between 0 and 2^251 - 1 (inclusive)"
|
|
@@ -76,10 +155,10 @@ export function montgomery(curveDef: MontgomeryOpts): MontgomeryECDH {
|
|
|
76
155
|
const maxScalar = minScalar + maxAdded + _1n; // (inclusive)
|
|
77
156
|
const modP = (n: bigint) => mod(n, P);
|
|
78
157
|
const GuBytes = encodeU(Gu);
|
|
79
|
-
function encodeU(u: bigint): Uint8Array {
|
|
158
|
+
function encodeU(u: bigint): TRet<Uint8Array> {
|
|
80
159
|
return numberToBytesLE(modP(u), fieldLen);
|
|
81
160
|
}
|
|
82
|
-
function decodeU(u: Uint8Array): bigint {
|
|
161
|
+
function decodeU(u: TArg<Uint8Array>): bigint {
|
|
83
162
|
const _u = copyBytes(abytes(u, fieldLen, 'uCoordinate'));
|
|
84
163
|
// RFC: When receiving such an array, implementations of X25519
|
|
85
164
|
// (but not X448) MUST mask the most significant bit in the final byte.
|
|
@@ -90,10 +169,10 @@ export function montgomery(curveDef: MontgomeryOpts): MontgomeryECDH {
|
|
|
90
169
|
// - 1 through 2^448 - 1 for X448.
|
|
91
170
|
return modP(bytesToNumberLE(_u));
|
|
92
171
|
}
|
|
93
|
-
function decodeScalar(scalar: Uint8Array): bigint {
|
|
172
|
+
function decodeScalar(scalar: TArg<Uint8Array>): bigint {
|
|
94
173
|
return bytesToNumberLE(adjustScalarBytes(copyBytes(abytes(scalar, fieldLen, 'scalar'))));
|
|
95
174
|
}
|
|
96
|
-
function scalarMult(scalar: Uint8Array
|
|
175
|
+
function scalarMult(scalar: TArg<Uint8Array>, u: TArg<Uint8Array>): TRet<Uint8Array> {
|
|
97
176
|
const pu = montgomeryLadder(decodeU(u), decodeScalar(scalar));
|
|
98
177
|
// Some public keys are useless, of low-order. Curve author doesn't think
|
|
99
178
|
// it needs to be validated, but we do it nonetheless.
|
|
@@ -102,7 +181,7 @@ export function montgomery(curveDef: MontgomeryOpts): MontgomeryECDH {
|
|
|
102
181
|
return encodeU(pu);
|
|
103
182
|
}
|
|
104
183
|
// Computes public key from private. By doing scalar multiplication of base point.
|
|
105
|
-
function scalarMultBase(scalar: Uint8Array): Uint8Array {
|
|
184
|
+
function scalarMultBase(scalar: TArg<Uint8Array>): TRet<Uint8Array> {
|
|
106
185
|
return scalarMult(scalar, GuBytes);
|
|
107
186
|
}
|
|
108
187
|
const getPublicKey = scalarMultBase;
|
|
@@ -120,10 +199,10 @@ export function montgomery(curveDef: MontgomeryOpts): MontgomeryECDH {
|
|
|
120
199
|
}
|
|
121
200
|
|
|
122
201
|
/**
|
|
123
|
-
* Montgomery x-only multiplication ladder.
|
|
124
|
-
* @param pointU u coordinate
|
|
125
|
-
* @param scalar by which the point
|
|
126
|
-
* @returns
|
|
202
|
+
* Montgomery x-only multiplication ladder for the selected X25519/X448 curve.
|
|
203
|
+
* @param pointU - decoded Montgomery u coordinate for the selected curve
|
|
204
|
+
* @param scalar - decoded clamped scalar by which the point is multiplied
|
|
205
|
+
* @returns resulting Montgomery u coordinate for the selected curve
|
|
127
206
|
*/
|
|
128
207
|
function montgomeryLadder(u: bigint, scalar: bigint): bigint {
|
|
129
208
|
aInRange('u', u, _0n, P);
|
|
@@ -168,11 +247,16 @@ export function montgomery(curveDef: MontgomeryOpts): MontgomeryECDH {
|
|
|
168
247
|
publicKey: fieldLen,
|
|
169
248
|
seed: fieldLen,
|
|
170
249
|
};
|
|
171
|
-
const randomSecretKey = (seed
|
|
250
|
+
const randomSecretKey = (seed?: TArg<Uint8Array>): TRet<Uint8Array> => {
|
|
251
|
+
seed = seed === undefined ? randomBytes_(fieldLen) : seed;
|
|
172
252
|
abytes(seed, lengths.seed, 'seed');
|
|
173
|
-
|
|
253
|
+
// Reuse caller-supplied seed bytes verbatim; clamping is deferred until
|
|
254
|
+
// decodeScalar(...) when the secret key is actually used.
|
|
255
|
+
return seed as TRet<Uint8Array>;
|
|
174
256
|
};
|
|
175
257
|
const utils = { randomSecretKey };
|
|
258
|
+
Object.freeze(lengths);
|
|
259
|
+
Object.freeze(utils);
|
|
176
260
|
|
|
177
261
|
return Object.freeze({
|
|
178
262
|
keygen: createKeygen(randomSecretKey, getPublicKey),
|
|
@@ -181,7 +265,7 @@ export function montgomery(curveDef: MontgomeryOpts): MontgomeryECDH {
|
|
|
181
265
|
scalarMult,
|
|
182
266
|
scalarMultBase,
|
|
183
267
|
utils,
|
|
184
|
-
GuBytes: GuBytes.slice()
|
|
268
|
+
GuBytes: GuBytes.slice() as TRet<Uint8Array>,
|
|
185
269
|
lengths,
|
|
186
270
|
}) satisfies CryptoKeys;
|
|
187
271
|
}
|