@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
package/src/misc.ts
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
7
|
-
import {
|
|
7
|
+
import { blake512 } from '@noble/hashes/blake1.js';
|
|
8
8
|
import { blake2s } from '@noble/hashes/blake2.js';
|
|
9
9
|
import { sha256, sha384, sha512 } from '@noble/hashes/sha2.js';
|
|
10
|
-
import { concatBytes } from '@noble/hashes/utils.js';
|
|
10
|
+
import { abytes, concatBytes } from '@noble/hashes/utils.js';
|
|
11
11
|
import {
|
|
12
12
|
eddsa,
|
|
13
13
|
edwards,
|
|
@@ -16,12 +16,14 @@ import {
|
|
|
16
16
|
type EdwardsPoint,
|
|
17
17
|
} from './abstract/edwards.ts';
|
|
18
18
|
import { ecdsa, weierstrass, type ECDSA, type WeierstrassOpts } from './abstract/weierstrass.ts';
|
|
19
|
-
import { asciiToBytes } from './utils.ts';
|
|
19
|
+
import { asciiToBytes, type TArg } from './utils.ts';
|
|
20
20
|
|
|
21
21
|
// Jubjub curves have 𝔽p over scalar fields of other curves. They are friendly to ZK proofs.
|
|
22
22
|
|
|
23
|
-
//
|
|
24
|
-
|
|
23
|
+
// Zcash Protocol Specification "Jubjub" parameters:
|
|
24
|
+
// q = BLS12-381 Fr, r, h = 8, a = -1, d = -10240/10241.
|
|
25
|
+
// Gx/Gy keep the canonical Jubjub base point used by Zcash implementations.
|
|
26
|
+
const jubjub_CURVE: EdwardsOpts = /* @__PURE__ */ (() => ({
|
|
25
27
|
p: BigInt('0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001'),
|
|
26
28
|
n: BigInt('0xe7db4ea6533afa906673b0101343b00a6682093ccc81082d0970e5ed6f72cb7'),
|
|
27
29
|
h: BigInt(8),
|
|
@@ -29,29 +31,88 @@ const jubjub_CURVE: EdwardsOpts = {
|
|
|
29
31
|
d: BigInt('0x2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1'),
|
|
30
32
|
Gx: BigInt('0x11dafe5d23e1218086a365b99fbf3d3be72f6afd7d1f72623e6b071492d1122b'),
|
|
31
33
|
Gy: BigInt('0x1d523cf1ddab1a1793132e78c866c0c33e26ba5cc220fed7cc3f870e59d292aa'),
|
|
32
|
-
};
|
|
33
|
-
/**
|
|
34
|
-
|
|
34
|
+
}))();
|
|
35
|
+
/**
|
|
36
|
+
* Generic EdDSA-over-Jubjub convenience wrapper with `sha512`.
|
|
37
|
+
* This is not the Zcash RedJubjub / Sapling signature scheme.
|
|
38
|
+
* @example
|
|
39
|
+
* Generate one Jubjub keypair, sign a message, and verify it.
|
|
40
|
+
*
|
|
41
|
+
* ```ts
|
|
42
|
+
* const { secretKey, publicKey } = jubjub.keygen();
|
|
43
|
+
* const msg = new TextEncoder().encode('hello noble');
|
|
44
|
+
* const sig = jubjub.sign(msg, secretKey);
|
|
45
|
+
* const isValid = jubjub.verify(sig, msg, publicKey);
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export const jubjub: EdDSA = /* @__PURE__ */ (() => eddsa(edwards(jubjub_CURVE), sha512))();
|
|
35
49
|
|
|
36
|
-
//
|
|
37
|
-
|
|
50
|
+
// BabyJubJub over bn254 Fr. EIP-2494 explicitly defines both the full-group generator G and the
|
|
51
|
+
// prime-order subgroup base point B = 8*G.
|
|
52
|
+
// noble's Edwards abstraction expects Point.BASE / curve.n to describe the prime-order subgroup, so
|
|
53
|
+
// use the EIP base point B here.
|
|
54
|
+
// Historical noble incorrectly used the EIP generator G as Point.BASE, which mismatched the
|
|
55
|
+
// abstraction and leaked the wrong order into consumers.
|
|
56
|
+
// Historical noble used G instead:
|
|
57
|
+
// Gx = 995203441582195749578291179787384436505546430278305826713579947235728471134
|
|
58
|
+
// Gy = 5472060717959818805561601436314318772137091100104008585924551046643952123905
|
|
59
|
+
const babyjubjub_CURVE: EdwardsOpts = /* @__PURE__ */ (() => ({
|
|
38
60
|
p: BigInt('0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001'),
|
|
39
|
-
n: BigInt('
|
|
61
|
+
n: BigInt('0x060c89ce5c263405370a08b6d0302b0bab3eedb83920ee0a677297dc392126f1'),
|
|
40
62
|
h: BigInt(8),
|
|
41
63
|
a: BigInt('168700'),
|
|
42
64
|
d: BigInt('168696'),
|
|
43
|
-
Gx: BigInt('
|
|
44
|
-
Gy: BigInt('
|
|
45
|
-
};
|
|
46
|
-
/**
|
|
47
|
-
|
|
65
|
+
Gx: BigInt('0xbb77a6ad63e739b4eacb2e09d6277c12ab8d8010534e0b62893f3f6bb957051'),
|
|
66
|
+
Gy: BigInt('0x25797203f7a0b24925572e1cd16bf9edfce0051fb9e133774b3c257a872d7d8b'),
|
|
67
|
+
}))();
|
|
68
|
+
/**
|
|
69
|
+
* Curve over scalar field of bn254. babyjubjub Fp = bn254 n
|
|
70
|
+
* This is a working generic EdDSA-over-BabyJubJub wrapper that uses `blake512` for the 64-byte
|
|
71
|
+
* secret expansion required by the shared EdDSA helper.
|
|
72
|
+
* It is not the BabyJubJub stack used by iden3/circomlib, `babyjubjub-rs`, or
|
|
73
|
+
* `@zk-kit/eddsa-poseidon`: those pair the subgroup base B/B8 with Blake-style secret expansion
|
|
74
|
+
* plus dedicated Poseidon / MiMC / Pedersen transcript hashing. This wrapper stays generic and is
|
|
75
|
+
* not meant as an interoperability target for those BabyJubJub signing stacks.
|
|
76
|
+
* @example
|
|
77
|
+
* Access the BabyJubJub base point and round-trip it through the point codec.
|
|
78
|
+
*
|
|
79
|
+
* ```ts
|
|
80
|
+
* import { babyjubjub } from '@noble/curves/misc.js';
|
|
81
|
+
* const base = babyjubjub.Point.BASE;
|
|
82
|
+
* const encoded = base.toBytes();
|
|
83
|
+
* const decoded = babyjubjub.Point.fromBytes(encoded);
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
export const babyjubjub: EdDSA = /* @__PURE__ */ (() =>
|
|
87
|
+
eddsa(edwards(babyjubjub_CURVE), blake512))();
|
|
48
88
|
|
|
49
|
-
|
|
89
|
+
// Sapling URS randomness beacon from the Zcash protocol. This stays as the 64-byte ASCII
|
|
90
|
+
// lowercase-hex string used for the first Blake2s block, not 32 raw bytes.
|
|
91
|
+
const jubjub_gh_first_block = /* @__PURE__ */ asciiToBytes(
|
|
50
92
|
'096b36a5804bfacef1691e173c366a47ff5ba84a44f26ddd7e8d9f79d5b42df0'
|
|
51
93
|
);
|
|
52
94
|
|
|
53
|
-
|
|
54
|
-
|
|
95
|
+
/**
|
|
96
|
+
* @param tag - Hash input.
|
|
97
|
+
* @param personalization - BLAKE2 personalization bytes.
|
|
98
|
+
* @returns Prime-order Jubjub point.
|
|
99
|
+
* @throws If the digest does not decode to a Jubjub point, or if the
|
|
100
|
+
* cofactor-cleared point has small order. {@link Error}
|
|
101
|
+
* @example
|
|
102
|
+
* Hash a tag into a prime-order Jubjub point.
|
|
103
|
+
*
|
|
104
|
+
* ```ts
|
|
105
|
+
* import { jubjub_groupHash } from '@noble/curves/misc.js';
|
|
106
|
+
* import { asciiToBytes } from '@noble/curves/utils.js';
|
|
107
|
+
* const tag = Uint8Array.of(2);
|
|
108
|
+
* const personalization = asciiToBytes('Zcash_G_');
|
|
109
|
+
* const point = jubjub_groupHash(tag, personalization);
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
export function jubjub_groupHash(
|
|
113
|
+
tag: TArg<Uint8Array>,
|
|
114
|
+
personalization: TArg<Uint8Array>
|
|
115
|
+
): EdwardsPoint {
|
|
55
116
|
const h = blake2s.create({ personalization, dkLen: 32 });
|
|
56
117
|
h.update(jubjub_gh_first_block);
|
|
57
118
|
h.update(tag);
|
|
@@ -63,10 +124,32 @@ export function jubjub_groupHash(tag: Uint8Array, personalization: Uint8Array):
|
|
|
63
124
|
return p;
|
|
64
125
|
}
|
|
65
126
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
127
|
+
/**
|
|
128
|
+
* No secret data is leaked here at all.
|
|
129
|
+
* It operates over public data.
|
|
130
|
+
* @param m - Message prefix.
|
|
131
|
+
* @param personalization - 8-byte BLAKE2 personalization bytes.
|
|
132
|
+
* @returns First non-zero group hash.
|
|
133
|
+
* @throws If the personalization is invalid, or if no non-zero Jubjub group
|
|
134
|
+
* hash can be found. {@link Error}
|
|
135
|
+
* @example
|
|
136
|
+
* Derive the first non-zero Jubjub group hash for one personalization tag.
|
|
137
|
+
*
|
|
138
|
+
* ```ts
|
|
139
|
+
* import { jubjub_findGroupHash } from '@noble/curves/misc.js';
|
|
140
|
+
* import { asciiToBytes } from '@noble/curves/utils.js';
|
|
141
|
+
* const msg = Uint8Array.of();
|
|
142
|
+
* const personalization = asciiToBytes('Zcash_G_');
|
|
143
|
+
* const point = jubjub_findGroupHash(msg, personalization);
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
export function jubjub_findGroupHash(
|
|
147
|
+
m: TArg<Uint8Array>,
|
|
148
|
+
personalization: TArg<Uint8Array>
|
|
149
|
+
): EdwardsPoint {
|
|
150
|
+
// Validate BLAKE2s personalization once up front; otherwise the retry loop swallows the real
|
|
151
|
+
// input error and turns it into a misleading "tag overflow".
|
|
152
|
+
abytes(personalization, 8, 'personalization');
|
|
70
153
|
const tag = concatBytes(m, Uint8Array.of(0));
|
|
71
154
|
const hashes = [];
|
|
72
155
|
for (let i = 0; i < 256; i++) {
|
|
@@ -79,7 +162,7 @@ export function jubjub_findGroupHash(m: Uint8Array, personalization: Uint8Array)
|
|
|
79
162
|
return hashes[0];
|
|
80
163
|
}
|
|
81
164
|
|
|
82
|
-
const brainpoolP256r1_CURVE: WeierstrassOpts<bigint> = {
|
|
165
|
+
const brainpoolP256r1_CURVE: WeierstrassOpts<bigint> = /* @__PURE__ */ (() => ({
|
|
83
166
|
p: BigInt('0xa9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377'),
|
|
84
167
|
a: BigInt('0x7d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9'),
|
|
85
168
|
b: BigInt('0x26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6'),
|
|
@@ -87,11 +170,23 @@ const brainpoolP256r1_CURVE: WeierstrassOpts<bigint> = {
|
|
|
87
170
|
Gx: BigInt('0x8bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262'),
|
|
88
171
|
Gy: BigInt('0x547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997'),
|
|
89
172
|
h: BigInt(1),
|
|
90
|
-
};
|
|
91
|
-
/**
|
|
92
|
-
|
|
173
|
+
}))();
|
|
174
|
+
/**
|
|
175
|
+
* Brainpool P256r1 with sha256, from RFC 5639.
|
|
176
|
+
* @example
|
|
177
|
+
* Generate one Brainpool P256r1 keypair, sign a message, and verify it.
|
|
178
|
+
*
|
|
179
|
+
* ```ts
|
|
180
|
+
* const { secretKey, publicKey } = brainpoolP256r1.keygen();
|
|
181
|
+
* const msg = new TextEncoder().encode('hello noble');
|
|
182
|
+
* const sig = brainpoolP256r1.sign(msg, secretKey);
|
|
183
|
+
* const isValid = brainpoolP256r1.verify(sig, msg, publicKey);
|
|
184
|
+
* ```
|
|
185
|
+
*/
|
|
186
|
+
export const brainpoolP256r1: ECDSA = /* @__PURE__ */ (() =>
|
|
187
|
+
ecdsa(weierstrass(brainpoolP256r1_CURVE), sha256))();
|
|
93
188
|
|
|
94
|
-
const brainpoolP384r1_CURVE: WeierstrassOpts<bigint> = {
|
|
189
|
+
const brainpoolP384r1_CURVE: WeierstrassOpts<bigint> = /* @__PURE__ */ (() => ({
|
|
95
190
|
p: BigInt(
|
|
96
191
|
'0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123acd3a729901d1a71874700133107ec53'
|
|
97
192
|
),
|
|
@@ -111,11 +206,23 @@ const brainpoolP384r1_CURVE: WeierstrassOpts<bigint> = {
|
|
|
111
206
|
'0x8abe1d7520f9c2a45cb1eb8e95cfd55262b70b29feec5864e19c054ff99129280e4646217791811142820341263c5315'
|
|
112
207
|
),
|
|
113
208
|
h: BigInt(1),
|
|
114
|
-
};
|
|
115
|
-
/**
|
|
116
|
-
|
|
209
|
+
}))();
|
|
210
|
+
/**
|
|
211
|
+
* Brainpool P384r1 with sha384, from RFC 5639.
|
|
212
|
+
* @example
|
|
213
|
+
* Generate one Brainpool P384r1 keypair, sign a message, and verify it.
|
|
214
|
+
*
|
|
215
|
+
* ```ts
|
|
216
|
+
* const { secretKey, publicKey } = brainpoolP384r1.keygen();
|
|
217
|
+
* const msg = new TextEncoder().encode('hello noble');
|
|
218
|
+
* const sig = brainpoolP384r1.sign(msg, secretKey);
|
|
219
|
+
* const isValid = brainpoolP384r1.verify(sig, msg, publicKey);
|
|
220
|
+
* ```
|
|
221
|
+
*/
|
|
222
|
+
export const brainpoolP384r1: ECDSA = /* @__PURE__ */ (() =>
|
|
223
|
+
ecdsa(weierstrass(brainpoolP384r1_CURVE), sha384))();
|
|
117
224
|
|
|
118
|
-
const brainpoolP512r1_CURVE: WeierstrassOpts<bigint> = {
|
|
225
|
+
const brainpoolP512r1_CURVE: WeierstrassOpts<bigint> = /* @__PURE__ */ (() => ({
|
|
119
226
|
p: BigInt(
|
|
120
227
|
'0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca703308717d4d9b009bc66842aecda12ae6a380e62881ff2f2d82c68528aa6056583a48f3'
|
|
121
228
|
),
|
|
@@ -135,6 +242,18 @@ const brainpoolP512r1_CURVE: WeierstrassOpts<bigint> = {
|
|
|
135
242
|
'0x7dde385d566332ecc0eabfa9cf7822fdf209f70024a57b1aa000c55b881f8111b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892'
|
|
136
243
|
),
|
|
137
244
|
h: BigInt(1),
|
|
138
|
-
};
|
|
139
|
-
/**
|
|
140
|
-
|
|
245
|
+
}))();
|
|
246
|
+
/**
|
|
247
|
+
* Brainpool P512r1 with sha512, from RFC 5639.
|
|
248
|
+
* @example
|
|
249
|
+
* Generate one Brainpool P512r1 keypair, sign a message, and verify it.
|
|
250
|
+
*
|
|
251
|
+
* ```ts
|
|
252
|
+
* const { secretKey, publicKey } = brainpoolP512r1.keygen();
|
|
253
|
+
* const msg = new TextEncoder().encode('hello noble');
|
|
254
|
+
* const sig = brainpoolP512r1.sign(msg, secretKey);
|
|
255
|
+
* const isValid = brainpoolP512r1.verify(sig, msg, publicKey);
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
export const brainpoolP512r1: ECDSA = /* @__PURE__ */ (() =>
|
|
259
|
+
ecdsa(weierstrass(brainpoolP512r1_CURVE), sha512))();
|
package/src/nist.ts
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
7
7
|
import { sha256, sha384, sha512 } from '@noble/hashes/sha2.js';
|
|
8
|
+
import { createFROST, type FROST } from './abstract/frost.ts';
|
|
8
9
|
import { createHasher, type H2CHasher } from './abstract/hash-to-curve.ts';
|
|
9
|
-
import {
|
|
10
|
-
import { createORPF, type OPRF } from './abstract/oprf.ts';
|
|
10
|
+
import { createOPRF, type OPRF } from './abstract/oprf.ts';
|
|
11
11
|
import {
|
|
12
12
|
ecdsa,
|
|
13
13
|
mapToCurveSimpleSWU,
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
type WeierstrassOpts,
|
|
17
17
|
type WeierstrassPointCons,
|
|
18
18
|
} from './abstract/weierstrass.ts';
|
|
19
|
+
import { type TRet } from './utils.ts';
|
|
19
20
|
|
|
20
21
|
// p = 2n**224n * (2n**32n-1n) + 2n**192n + 2n**96n - 1n
|
|
21
22
|
// a = Fp256.create(BigInt('-3'));
|
|
@@ -82,8 +83,11 @@ type SwuOpts = {
|
|
|
82
83
|
};
|
|
83
84
|
|
|
84
85
|
function createSWU(Point: WeierstrassPointCons<bigint>, opts: SwuOpts) {
|
|
85
|
-
|
|
86
|
-
|
|
86
|
+
let map: ((u: bigint) => { x: bigint; y: bigint }) | undefined;
|
|
87
|
+
// RFC 9380's NIST suites here all use m = 1, so createHasher passes one field element per map.
|
|
88
|
+
// Building the SWU sqrt-ratio helper eagerly adds noticeable `nist.js` import cost, so defer it
|
|
89
|
+
// to first use; after that the cached mapper is reused directly.
|
|
90
|
+
return (scalars: bigint[]) => (map || (map = mapToCurveSimpleSWU(Point.Fp, opts)))(scalars[0]);
|
|
87
91
|
}
|
|
88
92
|
|
|
89
93
|
// NIST P256
|
|
@@ -93,6 +97,8 @@ const p256_Point = /* @__PURE__ */ weierstrass(p256_CURVE);
|
|
|
93
97
|
* Hashes inputs with sha256 by default.
|
|
94
98
|
*
|
|
95
99
|
* @example
|
|
100
|
+
* Generate one P-256 keypair, sign a message, and verify it.
|
|
101
|
+
*
|
|
96
102
|
* ```js
|
|
97
103
|
* import { p256 } from '@noble/curves/nist.js';
|
|
98
104
|
* const { secretKey, publicKey } = p256.keygen();
|
|
@@ -104,7 +110,15 @@ const p256_Point = /* @__PURE__ */ weierstrass(p256_CURVE);
|
|
|
104
110
|
* ```
|
|
105
111
|
*/
|
|
106
112
|
export const p256: ECDSA = /* @__PURE__ */ ecdsa(p256_Point, sha256);
|
|
107
|
-
/**
|
|
113
|
+
/**
|
|
114
|
+
* Hashing / encoding to p256 points / field. RFC 9380 methods.
|
|
115
|
+
* @example
|
|
116
|
+
* Hash one message onto the P-256 curve.
|
|
117
|
+
*
|
|
118
|
+
* ```ts
|
|
119
|
+
* const point = p256_hasher.hashToCurve(new TextEncoder().encode('hello noble'));
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
108
122
|
export const p256_hasher: H2CHasher<WeierstrassPointCons<bigint>> = /* @__PURE__ */ (() => {
|
|
109
123
|
return createHasher(
|
|
110
124
|
p256_Point,
|
|
@@ -124,21 +138,71 @@ export const p256_hasher: H2CHasher<WeierstrassPointCons<bigint>> = /* @__PURE__
|
|
|
124
138
|
}
|
|
125
139
|
);
|
|
126
140
|
})();
|
|
127
|
-
/**
|
|
128
|
-
|
|
129
|
-
|
|
141
|
+
/**
|
|
142
|
+
* p256 OPRF, defined in RFC 9497.
|
|
143
|
+
* @example
|
|
144
|
+
* Run one blind/evaluate/finalize OPRF round over P-256.
|
|
145
|
+
*
|
|
146
|
+
* ```ts
|
|
147
|
+
* const input = new TextEncoder().encode('hello noble');
|
|
148
|
+
* const keys = p256_oprf.oprf.generateKeyPair();
|
|
149
|
+
* const blind = p256_oprf.oprf.blind(input);
|
|
150
|
+
* const evaluated = p256_oprf.oprf.blindEvaluate(keys.secretKey, blind.blinded);
|
|
151
|
+
* const output = p256_oprf.oprf.finalize(input, blind.blind, evaluated);
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
export const p256_oprf: TRet<OPRF> = /* @__PURE__ */ (() =>
|
|
155
|
+
createOPRF({
|
|
130
156
|
name: 'P256-SHA256',
|
|
131
157
|
Point: p256_Point,
|
|
132
158
|
hash: sha256,
|
|
133
159
|
hashToGroup: p256_hasher.hashToCurve,
|
|
134
160
|
hashToScalar: p256_hasher.hashToScalar,
|
|
135
161
|
}))();
|
|
162
|
+
/**
|
|
163
|
+
* FROST threshold signatures over p256. RFC 9591.
|
|
164
|
+
* @example
|
|
165
|
+
* Create one trusted-dealer package for 2-of-3 p256 signing.
|
|
166
|
+
*
|
|
167
|
+
* ```ts
|
|
168
|
+
* const alice = p256_FROST.Identifier.derive('alice@example.com');
|
|
169
|
+
* const bob = p256_FROST.Identifier.derive('bob@example.com');
|
|
170
|
+
* const carol = p256_FROST.Identifier.derive('carol@example.com');
|
|
171
|
+
* const deal = p256_FROST.trustedDealer({ min: 2, max: 3 }, [alice, bob, carol]);
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
174
|
+
export const p256_FROST: TRet<FROST> = /* @__PURE__ */ (() =>
|
|
175
|
+
createFROST({
|
|
176
|
+
name: 'FROST-P256-SHA256-v1',
|
|
177
|
+
Point: p256_Point,
|
|
178
|
+
hashToScalar: p256_hasher.hashToScalar,
|
|
179
|
+
hash: sha256,
|
|
180
|
+
}))();
|
|
136
181
|
|
|
137
182
|
// NIST P384
|
|
138
183
|
const p384_Point = /* @__PURE__ */ weierstrass(p384_CURVE);
|
|
139
|
-
/**
|
|
184
|
+
/**
|
|
185
|
+
* NIST P384 (aka secp384r1) curve, ECDSA and ECDH methods. Hashes inputs with sha384 by default.
|
|
186
|
+
* @example
|
|
187
|
+
* Generate one P-384 keypair, sign a message, and verify it.
|
|
188
|
+
*
|
|
189
|
+
* ```ts
|
|
190
|
+
* const { secretKey, publicKey } = p384.keygen();
|
|
191
|
+
* const msg = new TextEncoder().encode('hello noble');
|
|
192
|
+
* const sig = p384.sign(msg, secretKey);
|
|
193
|
+
* const isValid = p384.verify(sig, msg, publicKey);
|
|
194
|
+
* ```
|
|
195
|
+
*/
|
|
140
196
|
export const p384: ECDSA = /* @__PURE__ */ ecdsa(p384_Point, sha384);
|
|
141
|
-
/**
|
|
197
|
+
/**
|
|
198
|
+
* Hashing / encoding to p384 points / field. RFC 9380 methods.
|
|
199
|
+
* @example
|
|
200
|
+
* Hash one message onto the P-384 curve.
|
|
201
|
+
*
|
|
202
|
+
* ```ts
|
|
203
|
+
* const point = p384_hasher.hashToCurve(new TextEncoder().encode('hello noble'));
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
142
206
|
export const p384_hasher: H2CHasher<WeierstrassPointCons<bigint>> = /* @__PURE__ */ (() => {
|
|
143
207
|
return createHasher(
|
|
144
208
|
p384_Point,
|
|
@@ -158,9 +222,21 @@ export const p384_hasher: H2CHasher<WeierstrassPointCons<bigint>> = /* @__PURE__
|
|
|
158
222
|
}
|
|
159
223
|
);
|
|
160
224
|
})();
|
|
161
|
-
/**
|
|
162
|
-
|
|
163
|
-
|
|
225
|
+
/**
|
|
226
|
+
* p384 OPRF, defined in RFC 9497.
|
|
227
|
+
* @example
|
|
228
|
+
* Run one blind/evaluate/finalize OPRF round over P-384.
|
|
229
|
+
*
|
|
230
|
+
* ```ts
|
|
231
|
+
* const input = new TextEncoder().encode('hello noble');
|
|
232
|
+
* const keys = p384_oprf.oprf.generateKeyPair();
|
|
233
|
+
* const blind = p384_oprf.oprf.blind(input);
|
|
234
|
+
* const evaluated = p384_oprf.oprf.blindEvaluate(keys.secretKey, blind.blinded);
|
|
235
|
+
* const output = p384_oprf.oprf.finalize(input, blind.blind, evaluated);
|
|
236
|
+
* ```
|
|
237
|
+
*/
|
|
238
|
+
export const p384_oprf: TRet<OPRF> = /* @__PURE__ */ (() =>
|
|
239
|
+
createOPRF({
|
|
164
240
|
name: 'P384-SHA384',
|
|
165
241
|
Point: p384_Point,
|
|
166
242
|
hash: sha384,
|
|
@@ -169,11 +245,46 @@ export const p384_oprf: OPRF = /* @__PURE__ */ (() =>
|
|
|
169
245
|
}))();
|
|
170
246
|
|
|
171
247
|
// NIST P521
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
248
|
+
// RFC 7518 fixes the canonical JWK/JOSE width at 66 bytes:
|
|
249
|
+
// - Section 3.4 says ECDSA octet strings must not omit leading zero octets
|
|
250
|
+
// - Sections 6.2.1.2/6.2.1.3 say P-521 coordinates "x"/"y" must be 66 octets
|
|
251
|
+
// - Section 6.2.2.1 says private scalar "d" must be ceil(log2(n)/8) octets, i.e. 66 for P-521
|
|
252
|
+
// NIST FIPS 186-5 Appendix A.3.3 also routes deterministic ECDSA private keys through Appendix
|
|
253
|
+
// B.2.3, whose Integer-to-Octet-String output has explicit fixed length L; for P-521 that is the
|
|
254
|
+
// same 66-byte order width.
|
|
255
|
+
// RFC 6979 matches that width too: private key x is an integer, while `int2octets(x)` uses
|
|
256
|
+
// rlen = 8 * ceil(qlen/8); for P-521, qlen = 521 so the canonical octet width is 66 bytes.
|
|
257
|
+
// Wycheproof ECDH stores private values as integers, not fixed-width scalar bytes, so it does not
|
|
258
|
+
// require a dedicated 65-byte parser path; the repo tests now normalize those integer fixtures to
|
|
259
|
+
// the canonical 66-byte width before use. There is no good standards or oracle reason to accept
|
|
260
|
+
// exactly 65 bytes here: the coherent choices are canonical 66 only, or a broader integer-style
|
|
261
|
+
// parser across many widths. Since this field parser is fixed-width, keep it canonical and use the
|
|
262
|
+
// default exact-66-byte scalar field path.
|
|
263
|
+
const p521_Point = /* @__PURE__ */ weierstrass(p521_CURVE);
|
|
264
|
+
/**
|
|
265
|
+
* NIST P521 (aka secp521r1) curve, ECDSA and ECDH methods. Hashes inputs with sha512 by default.
|
|
266
|
+
* Deterministic `keygen(seed)` expects 99 seed bytes here because the generic scalar-derivation
|
|
267
|
+
* helper uses `getMinHashLength(n)`, not the 66-byte canonical secret-key width.
|
|
268
|
+
* @example
|
|
269
|
+
* Generate one P-521 keypair, sign a message, and verify it.
|
|
270
|
+
*
|
|
271
|
+
* ```ts
|
|
272
|
+
* const { secretKey, publicKey } = p521.keygen();
|
|
273
|
+
* const msg = new TextEncoder().encode('hello noble');
|
|
274
|
+
* const sig = p521.sign(msg, secretKey);
|
|
275
|
+
* const isValid = p521.verify(sig, msg, publicKey);
|
|
276
|
+
* ```
|
|
277
|
+
*/
|
|
175
278
|
export const p521: ECDSA = /* @__PURE__ */ ecdsa(p521_Point, sha512);
|
|
176
|
-
/**
|
|
279
|
+
/**
|
|
280
|
+
* Hashing / encoding to p521 points / field. RFC 9380 methods.
|
|
281
|
+
* @example
|
|
282
|
+
* Hash one message onto the P-521 curve.
|
|
283
|
+
*
|
|
284
|
+
* ```ts
|
|
285
|
+
* const point = p521_hasher.hashToCurve(new TextEncoder().encode('hello noble'));
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
177
288
|
export const p521_hasher: H2CHasher<WeierstrassPointCons<bigint>> = /* @__PURE__ */ (() => {
|
|
178
289
|
return createHasher(
|
|
179
290
|
p521_Point,
|
|
@@ -193,9 +304,21 @@ export const p521_hasher: H2CHasher<WeierstrassPointCons<bigint>> = /* @__PURE__
|
|
|
193
304
|
}
|
|
194
305
|
);
|
|
195
306
|
})();
|
|
196
|
-
/**
|
|
197
|
-
|
|
198
|
-
|
|
307
|
+
/**
|
|
308
|
+
* p521 OPRF, defined in RFC 9497.
|
|
309
|
+
* @example
|
|
310
|
+
* Run one blind/evaluate/finalize OPRF round over P-521.
|
|
311
|
+
*
|
|
312
|
+
* ```ts
|
|
313
|
+
* const input = new TextEncoder().encode('hello noble');
|
|
314
|
+
* const keys = p521_oprf.oprf.generateKeyPair();
|
|
315
|
+
* const blind = p521_oprf.oprf.blind(input);
|
|
316
|
+
* const evaluated = p521_oprf.oprf.blindEvaluate(keys.secretKey, blind.blinded);
|
|
317
|
+
* const output = p521_oprf.oprf.finalize(input, blind.blind, evaluated);
|
|
318
|
+
* ```
|
|
319
|
+
*/
|
|
320
|
+
export const p521_oprf: TRet<OPRF> = /* @__PURE__ */ (() =>
|
|
321
|
+
createOPRF({
|
|
199
322
|
name: 'P521-SHA512',
|
|
200
323
|
Point: p521_Point,
|
|
201
324
|
hash: sha512,
|