@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.
Files changed (110) hide show
  1. package/README.md +214 -122
  2. package/abstract/bls.d.ts +299 -16
  3. package/abstract/bls.d.ts.map +1 -1
  4. package/abstract/bls.js +82 -22
  5. package/abstract/bls.js.map +1 -1
  6. package/abstract/curve.d.ts +274 -27
  7. package/abstract/curve.d.ts.map +1 -1
  8. package/abstract/curve.js +177 -23
  9. package/abstract/curve.js.map +1 -1
  10. package/abstract/edwards.d.ts +166 -30
  11. package/abstract/edwards.d.ts.map +1 -1
  12. package/abstract/edwards.js +221 -86
  13. package/abstract/edwards.js.map +1 -1
  14. package/abstract/fft.d.ts +322 -10
  15. package/abstract/fft.d.ts.map +1 -1
  16. package/abstract/fft.js +154 -12
  17. package/abstract/fft.js.map +1 -1
  18. package/abstract/frost.d.ts +293 -0
  19. package/abstract/frost.d.ts.map +1 -0
  20. package/abstract/frost.js +704 -0
  21. package/abstract/frost.js.map +1 -0
  22. package/abstract/hash-to-curve.d.ts +173 -24
  23. package/abstract/hash-to-curve.d.ts.map +1 -1
  24. package/abstract/hash-to-curve.js +170 -31
  25. package/abstract/hash-to-curve.js.map +1 -1
  26. package/abstract/modular.d.ts +429 -37
  27. package/abstract/modular.d.ts.map +1 -1
  28. package/abstract/modular.js +414 -119
  29. package/abstract/modular.js.map +1 -1
  30. package/abstract/montgomery.d.ts +83 -12
  31. package/abstract/montgomery.d.ts.map +1 -1
  32. package/abstract/montgomery.js +32 -7
  33. package/abstract/montgomery.js.map +1 -1
  34. package/abstract/oprf.d.ts +164 -91
  35. package/abstract/oprf.d.ts.map +1 -1
  36. package/abstract/oprf.js +88 -29
  37. package/abstract/oprf.js.map +1 -1
  38. package/abstract/poseidon.d.ts +138 -7
  39. package/abstract/poseidon.d.ts.map +1 -1
  40. package/abstract/poseidon.js +178 -15
  41. package/abstract/poseidon.js.map +1 -1
  42. package/abstract/tower.d.ts +122 -3
  43. package/abstract/tower.d.ts.map +1 -1
  44. package/abstract/tower.js +323 -139
  45. package/abstract/tower.js.map +1 -1
  46. package/abstract/weierstrass.d.ts +339 -76
  47. package/abstract/weierstrass.d.ts.map +1 -1
  48. package/abstract/weierstrass.js +395 -205
  49. package/abstract/weierstrass.js.map +1 -1
  50. package/bls12-381.d.ts +16 -2
  51. package/bls12-381.d.ts.map +1 -1
  52. package/bls12-381.js +199 -209
  53. package/bls12-381.js.map +1 -1
  54. package/bn254.d.ts +11 -2
  55. package/bn254.d.ts.map +1 -1
  56. package/bn254.js +93 -38
  57. package/bn254.js.map +1 -1
  58. package/ed25519.d.ts +125 -14
  59. package/ed25519.d.ts.map +1 -1
  60. package/ed25519.js +202 -40
  61. package/ed25519.js.map +1 -1
  62. package/ed448.d.ts +108 -14
  63. package/ed448.d.ts.map +1 -1
  64. package/ed448.js +194 -42
  65. package/ed448.js.map +1 -1
  66. package/index.js +7 -1
  67. package/index.js.map +1 -1
  68. package/misc.d.ts +106 -7
  69. package/misc.d.ts.map +1 -1
  70. package/misc.js +141 -32
  71. package/misc.js.map +1 -1
  72. package/nist.d.ts +112 -11
  73. package/nist.d.ts.map +1 -1
  74. package/nist.js +139 -17
  75. package/nist.js.map +1 -1
  76. package/package.json +11 -6
  77. package/secp256k1.d.ts +92 -15
  78. package/secp256k1.d.ts.map +1 -1
  79. package/secp256k1.js +211 -28
  80. package/secp256k1.js.map +1 -1
  81. package/src/abstract/bls.ts +350 -67
  82. package/src/abstract/curve.ts +327 -44
  83. package/src/abstract/edwards.ts +367 -143
  84. package/src/abstract/fft.ts +369 -36
  85. package/src/abstract/frost.ts +1092 -0
  86. package/src/abstract/hash-to-curve.ts +255 -56
  87. package/src/abstract/modular.ts +591 -144
  88. package/src/abstract/montgomery.ts +114 -30
  89. package/src/abstract/oprf.ts +383 -194
  90. package/src/abstract/poseidon.ts +235 -35
  91. package/src/abstract/tower.ts +428 -159
  92. package/src/abstract/weierstrass.ts +710 -312
  93. package/src/bls12-381.ts +239 -236
  94. package/src/bn254.ts +107 -46
  95. package/src/ed25519.ts +227 -55
  96. package/src/ed448.ts +227 -57
  97. package/src/index.ts +7 -1
  98. package/src/misc.ts +154 -35
  99. package/src/nist.ts +143 -20
  100. package/src/secp256k1.ts +284 -41
  101. package/src/utils.ts +583 -81
  102. package/src/webcrypto.ts +302 -73
  103. package/utils.d.ts +457 -24
  104. package/utils.d.ts.map +1 -1
  105. package/utils.js +410 -53
  106. package/utils.js.map +1 -1
  107. package/webcrypto.d.ts +167 -25
  108. package/webcrypto.d.ts.map +1 -1
  109. package/webcrypto.js +165 -58
  110. 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 { blake256 } from '@noble/hashes/blake1.js';
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
- // jubjub p = bls n, verify in bls12-381.ts
24
- const jubjub_CURVE: EdwardsOpts = {
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
- /** Curve over scalar field of bls12-381. jubjub Fp = bls n */
34
- export const jubjub: EdDSA = /* @__PURE__ */ eddsa(edwards(jubjub_CURVE), sha512);
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
- // babyjubjub p = bn254 n, verify in bn254.ts
37
- const babyjubjub_CURVE: EdwardsOpts = {
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('0x30644e72e131a029b85045b68181585d59f76dc1c90770533b94bee1c9093788'),
61
+ n: BigInt('0x060c89ce5c263405370a08b6d0302b0bab3eedb83920ee0a677297dc392126f1'),
40
62
  h: BigInt(8),
41
63
  a: BigInt('168700'),
42
64
  d: BigInt('168696'),
43
- Gx: BigInt('0x23343e3445b673d38bcba38f25645adb494b1255b1162bb40f41a59f4d4b45e'),
44
- Gy: BigInt('0xc19139cb84c680a6e14116da06056174a0cfa121e6e5c2450f87d64fc000001'),
45
- };
46
- /** Curve over scalar field of bn254. babyjubjub Fp = bn254 n */
47
- export const babyjubjub: EdDSA = /* @__PURE__ */ eddsa(edwards(babyjubjub_CURVE), blake256);
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
- const jubjub_gh_first_block = asciiToBytes(
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
- // Returns point at JubJub curve which is prime order and not zero
54
- export function jubjub_groupHash(tag: Uint8Array, personalization: Uint8Array): EdwardsPoint {
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
- // No secret data is leaked here at all.
67
- // It operates over public data:
68
- // const G_SPEND = jubjub.findGroupHash(Uint8Array.of(), asciiToBytes('Item_G_'));
69
- export function jubjub_findGroupHash(m: Uint8Array, personalization: Uint8Array): EdwardsPoint {
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
- /** Brainpool P256r1 with sha256, from RFC 5639. */
92
- export const brainpoolP256r1: ECDSA = ecdsa(weierstrass(brainpoolP256r1_CURVE), sha256);
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
- /** Brainpool P384r1 with sha384, from RFC 5639. */
116
- export const brainpoolP384r1: ECDSA = ecdsa(weierstrass(brainpoolP384r1_CURVE), sha384);
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
- /** Brainpool P521r1 with sha512, from RFC 5639. */
140
- export const brainpoolP512r1: ECDSA = ecdsa(weierstrass(brainpoolP512r1_CURVE), sha512);
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 { Field } from './abstract/modular.ts';
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
- const map = mapToCurveSimpleSWU(Point.Fp, opts);
86
- return (scalars: bigint[]) => map(scalars[0]);
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
- /** Hashing / encoding to p256 points / field. RFC 9380 methods. */
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
- /** p256 OPRF, defined in RFC 9497. */
128
- export const p256_oprf: OPRF = /* @__PURE__ */ (() =>
129
- createORPF({
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
- /** NIST P384 (aka secp384r1) curve, ECDSA and ECDH methods. Hashes inputs with sha384 by default. */
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
- /** Hashing / encoding to p384 points / field. RFC 9380 methods. */
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
- /** p384 OPRF, defined in RFC 9497. */
162
- export const p384_oprf: OPRF = /* @__PURE__ */ (() =>
163
- createORPF({
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
- const Fn521 = /* @__PURE__ */ (() => Field(p521_CURVE.n, { allowedLengths: [65, 66] }))();
173
- const p521_Point = /* @__PURE__ */ weierstrass(p521_CURVE, { Fn: Fn521 });
174
- /** NIST P521 (aka secp521r1) curve, ECDSA and ECDH methods. Hashes inputs with sha512 by default. */
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
- /** Hashing / encoding to p521 points / field. RFC 9380 methods. */
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
- /** p521 OPRF, defined in RFC 9497. */
197
- export const p521_oprf: OPRF = /* @__PURE__ */ (() =>
198
- createORPF({
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,