@noble/curves 0.2.1 → 0.3.1

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 (62) hide show
  1. package/README.md +14 -19
  2. package/lib/crypto.d.ts +4 -0
  3. package/lib/crypto.js +8 -0
  4. package/lib/cryptoBrowser.d.ts +4 -0
  5. package/lib/cryptoBrowser.js +7 -0
  6. package/lib/definitions/_shortw_utils.d.ts +63 -0
  7. package/lib/definitions/_shortw_utils.js +18 -0
  8. package/lib/definitions/bn.d.ts +7 -0
  9. package/lib/definitions/bn.js +23 -0
  10. package/lib/definitions/ed25519.d.ts +49 -0
  11. package/lib/definitions/ed25519.js +308 -0
  12. package/lib/definitions/ed448.d.ts +3 -0
  13. package/lib/definitions/ed448.js +127 -0
  14. package/lib/definitions/index.d.ts +0 -0
  15. package/lib/definitions/index.js +2 -0
  16. package/lib/definitions/jubjub.d.ts +7 -0
  17. package/lib/definitions/jubjub.js +55 -0
  18. package/lib/definitions/p192.d.ts +112 -0
  19. package/lib/definitions/p192.js +23 -0
  20. package/lib/definitions/p224.d.ts +112 -0
  21. package/lib/definitions/p224.js +24 -0
  22. package/lib/definitions/p256.d.ts +112 -0
  23. package/lib/definitions/p256.js +23 -0
  24. package/lib/definitions/p384.d.ts +112 -0
  25. package/lib/definitions/p384.js +24 -0
  26. package/lib/definitions/p521.d.ts +113 -0
  27. package/lib/definitions/p521.js +36 -0
  28. package/lib/definitions/pasta.d.ts +2 -0
  29. package/lib/definitions/pasta.js +32 -0
  30. package/lib/definitions/secp256k1.d.ts +87 -0
  31. package/lib/definitions/secp256k1.js +245 -0
  32. package/lib/definitions/stark.d.ts +62 -0
  33. package/lib/definitions/stark.js +248 -0
  34. package/lib/edwards.d.ts +2 -2
  35. package/lib/edwards.js +2 -6
  36. package/lib/esm/crypto.js +5 -0
  37. package/lib/esm/cryptoBrowser.js +4 -0
  38. package/lib/esm/definitions/_shortw_utils.js +13 -0
  39. package/lib/esm/definitions/bn.js +20 -0
  40. package/lib/esm/definitions/ed25519.js +304 -0
  41. package/lib/esm/definitions/ed448.js +124 -0
  42. package/lib/esm/definitions/index.js +2 -0
  43. package/lib/esm/definitions/jubjub.js +50 -0
  44. package/lib/esm/definitions/p192.js +20 -0
  45. package/lib/esm/definitions/p224.js +21 -0
  46. package/lib/esm/definitions/p256.js +20 -0
  47. package/lib/esm/definitions/p384.js +21 -0
  48. package/lib/esm/definitions/p521.js +33 -0
  49. package/lib/esm/definitions/pasta.js +29 -0
  50. package/lib/esm/definitions/secp256k1.js +241 -0
  51. package/lib/esm/definitions/stark.js +227 -0
  52. package/lib/esm/edwards.js +3 -7
  53. package/lib/esm/modular.js +14 -9
  54. package/lib/esm/utils.js +17 -0
  55. package/lib/esm/weierstrass.js +17 -9
  56. package/lib/modular.d.ts +8 -1
  57. package/lib/modular.js +14 -9
  58. package/lib/utils.d.ts +4 -0
  59. package/lib/utils.js +19 -1
  60. package/lib/weierstrass.d.ts +5 -3
  61. package/lib/weierstrass.js +16 -8
  62. package/package.json +38 -8
@@ -0,0 +1,304 @@
1
+ /*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
+ import { sha512 } from '@noble/hashes/sha512';
3
+ import { concatBytes, utf8ToBytes } from '@noble/hashes/utils';
4
+ import { twistedEdwards } from '../edwards';
5
+ import { montgomery } from '../montgomery';
6
+ import { mod, pow2, isNegativeLE } from '../modular';
7
+ import { ensureBytes, equalBytes, bytesToHex, bytesToNumberLE, numberToBytesLE, } from '../utils';
8
+ /**
9
+ * ed25519 Twisted Edwards curve with following addons:
10
+ * - X25519 ECDH
11
+ * - Ristretto cofactor elimination
12
+ * - Elligator hash-to-group / point indistinguishability
13
+ */
14
+ const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
15
+ // √(-1) aka √(a) aka 2^((p-1)/4)
16
+ const ED25519_SQRT_M1 = BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
17
+ // prettier-ignore
18
+ const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _5n = BigInt(5);
19
+ // prettier-ignore
20
+ const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
21
+ function ed25519_pow_2_252_3(x) {
22
+ const P = ED25519_P;
23
+ const x2 = (x * x) % P;
24
+ const b2 = (x2 * x) % P; // x^3, 11
25
+ const b4 = (pow2(b2, _2n, P) * b2) % P; // x^15, 1111
26
+ const b5 = (pow2(b4, _1n, P) * x) % P; // x^31
27
+ const b10 = (pow2(b5, _5n, P) * b5) % P;
28
+ const b20 = (pow2(b10, _10n, P) * b10) % P;
29
+ const b40 = (pow2(b20, _20n, P) * b20) % P;
30
+ const b80 = (pow2(b40, _40n, P) * b40) % P;
31
+ const b160 = (pow2(b80, _80n, P) * b80) % P;
32
+ const b240 = (pow2(b160, _80n, P) * b80) % P;
33
+ const b250 = (pow2(b240, _10n, P) * b10) % P;
34
+ const pow_p_5_8 = (pow2(b250, _2n, P) * x) % P;
35
+ // ^ To pow to (p+3)/8, multiply it by x.
36
+ return { pow_p_5_8, b2 };
37
+ }
38
+ /**
39
+ * For X25519, in order to decode 32 random bytes as an integer scalar,
40
+ * set the
41
+ * three least significant bits of the first byte 0b1111_1000,
42
+ * and the most significant bit of the last to zero 0b0111_1111,
43
+ * set the second most significant bit of the last byte to 1 0b0100_0000
44
+ */
45
+ function adjustScalarBytes(bytes) {
46
+ bytes[0] &= 248;
47
+ bytes[31] &= 127;
48
+ bytes[31] |= 64;
49
+ return bytes;
50
+ }
51
+ // sqrt(u/v)
52
+ function uvRatio(u, v) {
53
+ const P = ED25519_P;
54
+ const v3 = mod(v * v * v, P); // v³
55
+ const v7 = mod(v3 * v3 * v, P); // v⁷
56
+ // (p+3)/8 and (p-5)/8
57
+ const pow = ed25519_pow_2_252_3(u * v7).pow_p_5_8;
58
+ let x = mod(u * v3 * pow, P); // (uv³)(uv⁷)^(p-5)/8
59
+ const vx2 = mod(v * x * x, P); // vx²
60
+ const root1 = x; // First root candidate
61
+ const root2 = mod(x * ED25519_SQRT_M1, P); // Second root candidate
62
+ const useRoot1 = vx2 === u; // If vx² = u (mod p), x is a square root
63
+ const useRoot2 = vx2 === mod(-u, P); // If vx² = -u, set x <-- x * 2^((p-1)/4)
64
+ const noRoot = vx2 === mod(-u * ED25519_SQRT_M1, P); // There is no valid root, vx² = -u√(-1)
65
+ if (useRoot1)
66
+ x = root1;
67
+ if (useRoot2 || noRoot)
68
+ x = root2; // We return root2 anyway, for const-time
69
+ if (isNegativeLE(x, P))
70
+ x = mod(-x, P);
71
+ return { isValid: useRoot1 || useRoot2, value: x };
72
+ }
73
+ // Just in case
74
+ export const ED25519_TORSION_SUBGROUP = [
75
+ '0100000000000000000000000000000000000000000000000000000000000000',
76
+ 'c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a',
77
+ '0000000000000000000000000000000000000000000000000000000000000080',
78
+ '26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05',
79
+ 'ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f',
80
+ '26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc85',
81
+ '0000000000000000000000000000000000000000000000000000000000000000',
82
+ 'c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa',
83
+ ];
84
+ const ED25519_DEF = {
85
+ // Param: a
86
+ a: BigInt(-1),
87
+ // Equal to -121665/121666 over finite field.
88
+ // Negative number is P - number, and division is invert(number, P)
89
+ d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
90
+ // Finite field 𝔽p over which we'll do calculations; 2n ** 255n - 19n
91
+ P: ED25519_P,
92
+ // Subgroup order: how many points ed25519 has
93
+ // 2n ** 252n + 27742317777372353535851937790883648493n;
94
+ n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
95
+ // Cofactor
96
+ h: BigInt(8),
97
+ // Base point (x, y) aka generator point
98
+ Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
99
+ Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
100
+ hash: sha512,
101
+ adjustScalarBytes,
102
+ // dom2
103
+ // Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
104
+ // Constant-time, u/√v
105
+ uvRatio,
106
+ };
107
+ export const ed25519 = twistedEdwards(ED25519_DEF);
108
+ function ed25519_domain(data, ctx, phflag) {
109
+ if (ctx.length > 255)
110
+ throw new Error('Context is too big');
111
+ return concatBytes(utf8ToBytes('SigEd25519 no Ed25519 collisions'), new Uint8Array([phflag ? 1 : 0, ctx.length]), ctx, data);
112
+ }
113
+ export const ed25519ctx = twistedEdwards({ ...ED25519_DEF, domain: ed25519_domain });
114
+ export const ed25519ph = twistedEdwards({
115
+ ...ED25519_DEF,
116
+ domain: ed25519_domain,
117
+ preHash: sha512,
118
+ });
119
+ export const x25519 = montgomery({
120
+ P: ED25519_P,
121
+ a24: BigInt('121665'),
122
+ montgomeryBits: 255,
123
+ nByteLength: 32,
124
+ Gu: '0900000000000000000000000000000000000000000000000000000000000000',
125
+ powPminus2: (x) => {
126
+ const P = ED25519_P;
127
+ // x^(p-2) aka x^(2^255-21)
128
+ const { pow_p_5_8, b2 } = ed25519_pow_2_252_3(x);
129
+ return mod(pow2(pow_p_5_8, BigInt(3), P) * b2, P);
130
+ },
131
+ adjustScalarBytes,
132
+ });
133
+ function assertRstPoint(other) {
134
+ if (!(other instanceof RistrettoPoint))
135
+ throw new TypeError('RistrettoPoint expected');
136
+ }
137
+ // √(-1) aka √(a) aka 2^((p-1)/4)
138
+ const SQRT_M1 = BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
139
+ // √(ad - 1)
140
+ const SQRT_AD_MINUS_ONE = BigInt('25063068953384623474111414158702152701244531502492656460079210482610430750235');
141
+ // 1 / √(a-d)
142
+ const INVSQRT_A_MINUS_D = BigInt('54469307008909316920995813868745141605393597292927456921205312896311721017578');
143
+ // 1-d²
144
+ const ONE_MINUS_D_SQ = BigInt('1159843021668779879193775521855586647937357759715417654439879720876111806838');
145
+ // (d-1)²
146
+ const D_MINUS_ONE_SQ = BigInt('40440834346308536858101042469323190826248399146238708352240133220865137265952');
147
+ // Calculates 1/√(number)
148
+ const invertSqrt = (number) => uvRatio(_1n, number);
149
+ const MAX_255B = BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
150
+ const bytes255ToNumberLE = (bytes) => ed25519.utils.mod(bytesToNumberLE(bytes) & MAX_255B);
151
+ /**
152
+ * Each ed25519/ExtendedPoint has 8 different equivalent points. This can be
153
+ * a source of bugs for protocols like ring signatures. Ristretto was created to solve this.
154
+ * Ristretto point operates in X:Y:Z:T extended coordinates like ExtendedPoint,
155
+ * but it should work in its own namespace: do not combine those two.
156
+ * https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-ristretto255-decaf448
157
+ */
158
+ export class RistrettoPoint {
159
+ // Private property to discourage combining ExtendedPoint + RistrettoPoint
160
+ // Always use Ristretto encoding/decoding instead.
161
+ constructor(ep) {
162
+ this.ep = ep;
163
+ }
164
+ // Computes Elligator map for Ristretto
165
+ // https://ristretto.group/formulas/elligator.html
166
+ static calcElligatorRistrettoMap(r0) {
167
+ const { d, P } = ed25519.CURVE;
168
+ const { mod } = ed25519.utils;
169
+ const r = mod(SQRT_M1 * r0 * r0); // 1
170
+ const Ns = mod((r + _1n) * ONE_MINUS_D_SQ); // 2
171
+ let c = BigInt(-1); // 3
172
+ const D = mod((c - d * r) * mod(r + d)); // 4
173
+ let { isValid: Ns_D_is_sq, value: s } = uvRatio(Ns, D); // 5
174
+ let s_ = mod(s * r0); // 6
175
+ if (!isNegativeLE(s_, P))
176
+ s_ = mod(-s_);
177
+ if (!Ns_D_is_sq)
178
+ s = s_; // 7
179
+ if (!Ns_D_is_sq)
180
+ c = r; // 8
181
+ const Nt = mod(c * (r - _1n) * D_MINUS_ONE_SQ - D); // 9
182
+ const s2 = s * s;
183
+ const W0 = mod((s + s) * D); // 10
184
+ const W1 = mod(Nt * SQRT_AD_MINUS_ONE); // 11
185
+ const W2 = mod(_1n - s2); // 12
186
+ const W3 = mod(_1n + s2); // 13
187
+ return new ed25519.ExtendedPoint(mod(W0 * W3), mod(W2 * W1), mod(W1 * W3), mod(W0 * W2));
188
+ }
189
+ /**
190
+ * Takes uniform output of 64-bit hash function like sha512 and converts it to `RistrettoPoint`.
191
+ * The hash-to-group operation applies Elligator twice and adds the results.
192
+ * **Note:** this is one-way map, there is no conversion from point to hash.
193
+ * https://ristretto.group/formulas/elligator.html
194
+ * @param hex 64-bit output of a hash function
195
+ */
196
+ static hashToCurve(hex) {
197
+ hex = ensureBytes(hex, 64);
198
+ const r1 = bytes255ToNumberLE(hex.slice(0, 32));
199
+ const R1 = this.calcElligatorRistrettoMap(r1);
200
+ const r2 = bytes255ToNumberLE(hex.slice(32, 64));
201
+ const R2 = this.calcElligatorRistrettoMap(r2);
202
+ return new RistrettoPoint(R1.add(R2));
203
+ }
204
+ /**
205
+ * Converts ristretto-encoded string to ristretto point.
206
+ * https://ristretto.group/formulas/decoding.html
207
+ * @param hex Ristretto-encoded 32 bytes. Not every 32-byte string is valid ristretto encoding
208
+ */
209
+ static fromHex(hex) {
210
+ hex = ensureBytes(hex, 32);
211
+ const { a, d, P } = ed25519.CURVE;
212
+ const { mod } = ed25519.utils;
213
+ const emsg = 'RistrettoPoint.fromHex: the hex is not valid encoding of RistrettoPoint';
214
+ const s = bytes255ToNumberLE(hex);
215
+ // 1. Check that s_bytes is the canonical encoding of a field element, or else abort.
216
+ // 3. Check that s is non-negative, or else abort
217
+ if (!equalBytes(numberToBytesLE(s, 32), hex) || isNegativeLE(s, P))
218
+ throw new Error(emsg);
219
+ const s2 = mod(s * s);
220
+ const u1 = mod(_1n + a * s2); // 4 (a is -1)
221
+ const u2 = mod(_1n - a * s2); // 5
222
+ const u1_2 = mod(u1 * u1);
223
+ const u2_2 = mod(u2 * u2);
224
+ const v = mod(a * d * u1_2 - u2_2); // 6
225
+ const { isValid, value: I } = invertSqrt(mod(v * u2_2)); // 7
226
+ const Dx = mod(I * u2); // 8
227
+ const Dy = mod(I * Dx * v); // 9
228
+ let x = mod((s + s) * Dx); // 10
229
+ if (isNegativeLE(x, P))
230
+ x = mod(-x); // 10
231
+ const y = mod(u1 * Dy); // 11
232
+ const t = mod(x * y); // 12
233
+ if (!isValid || isNegativeLE(t, P) || y === _0n)
234
+ throw new Error(emsg);
235
+ return new RistrettoPoint(new ed25519.ExtendedPoint(x, y, _1n, t));
236
+ }
237
+ /**
238
+ * Encodes ristretto point to Uint8Array.
239
+ * https://ristretto.group/formulas/encoding.html
240
+ */
241
+ toRawBytes() {
242
+ let { x, y, z, t } = this.ep;
243
+ const { P } = ed25519.CURVE;
244
+ const { mod } = ed25519.utils;
245
+ const u1 = mod(mod(z + y) * mod(z - y)); // 1
246
+ const u2 = mod(x * y); // 2
247
+ // Square root always exists
248
+ const u2sq = mod(u2 * u2);
249
+ const { value: invsqrt } = invertSqrt(mod(u1 * u2sq)); // 3
250
+ const D1 = mod(invsqrt * u1); // 4
251
+ const D2 = mod(invsqrt * u2); // 5
252
+ const zInv = mod(D1 * D2 * t); // 6
253
+ let D; // 7
254
+ if (isNegativeLE(t * zInv, P)) {
255
+ let _x = mod(y * SQRT_M1);
256
+ let _y = mod(x * SQRT_M1);
257
+ x = _x;
258
+ y = _y;
259
+ D = mod(D1 * INVSQRT_A_MINUS_D);
260
+ }
261
+ else {
262
+ D = D2; // 8
263
+ }
264
+ if (isNegativeLE(x * zInv, P))
265
+ y = mod(-y); // 9
266
+ let s = mod((z - y) * D); // 10 (check footer's note, no sqrt(-a))
267
+ if (isNegativeLE(s, P))
268
+ s = mod(-s);
269
+ return numberToBytesLE(s, 32); // 11
270
+ }
271
+ toHex() {
272
+ return bytesToHex(this.toRawBytes());
273
+ }
274
+ toString() {
275
+ return this.toHex();
276
+ }
277
+ // Compare one point to another.
278
+ equals(other) {
279
+ assertRstPoint(other);
280
+ const a = this.ep;
281
+ const b = other.ep;
282
+ const { mod } = ed25519.utils;
283
+ // (x1 * y2 == y1 * x2) | (y1 * y2 == x1 * x2)
284
+ const one = mod(a.x * b.y) === mod(a.y * b.x);
285
+ const two = mod(a.y * b.y) === mod(a.x * b.x);
286
+ return one || two;
287
+ }
288
+ add(other) {
289
+ assertRstPoint(other);
290
+ return new RistrettoPoint(this.ep.add(other.ep));
291
+ }
292
+ subtract(other) {
293
+ assertRstPoint(other);
294
+ return new RistrettoPoint(this.ep.subtract(other.ep));
295
+ }
296
+ multiply(scalar) {
297
+ return new RistrettoPoint(this.ep.multiply(scalar));
298
+ }
299
+ multiplyUnsafe(scalar) {
300
+ return new RistrettoPoint(this.ep.multiplyUnsafe(scalar));
301
+ }
302
+ }
303
+ RistrettoPoint.BASE = new RistrettoPoint(ed25519.ExtendedPoint.BASE);
304
+ RistrettoPoint.ZERO = new RistrettoPoint(ed25519.ExtendedPoint.ZERO);
@@ -0,0 +1,124 @@
1
+ /*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
+ import { shake256 } from '@noble/hashes/sha3';
3
+ import { concatBytes, utf8ToBytes, wrapConstructor } from '@noble/hashes/utils';
4
+ import { twistedEdwards } from '../edwards';
5
+ import { mod, pow2 } from '../modular';
6
+ import { montgomery } from '../montgomery';
7
+ /**
8
+ * Edwards448 (not Ed448-Goldilocks) curve with following addons:
9
+ * * X448 ECDH
10
+ * Conforms to RFC 8032 https://www.rfc-editor.org/rfc/rfc8032.html#section-5.2
11
+ */
12
+ const shake256_114 = wrapConstructor(() => shake256.create({ dkLen: 114 }));
13
+ const shake256_64 = wrapConstructor(() => shake256.create({ dkLen: 64 }));
14
+ const ed448P = BigInt('726838724295606890549323807888004534353641360687318060281490199180612328166730772686396383698676545930088884461843637361053498018365439');
15
+ // powPminus3div4 calculates z = x^k mod p, where k = (p-3)/4.
16
+ function ed448_pow_Pminus3div4(x) {
17
+ const P = ed448P;
18
+ // prettier-ignore
19
+ let [_1n, _2n, _3n, _11n, _22n, _44n, _88n, _223n] = [1, 2, 3, 11, 22, 44, 88, 223]
20
+ .map(n => BigInt(n));
21
+ // x ** ((P - 3n)/4n) % P
22
+ // [223 of 1, 0, 222 of 1], almost same as secp!
23
+ const b2 = (x * x * x) % P;
24
+ const b3 = (b2 * b2 * x) % P;
25
+ const b6 = (pow2(b3, _3n, P) * b3) % P;
26
+ const b9 = (pow2(b6, _3n, P) * b3) % P;
27
+ const b11 = (pow2(b9, _2n, P) * b2) % P;
28
+ const b22 = (pow2(b11, _11n, P) * b11) % P;
29
+ const b44 = (pow2(b22, _22n, P) * b22) % P;
30
+ const b88 = (pow2(b44, _44n, P) * b44) % P;
31
+ const b176 = (pow2(b88, _88n, P) * b88) % P;
32
+ const b220 = (pow2(b176, _44n, P) * b44) % P;
33
+ const b222 = (pow2(b220, _2n, P) * b2) % P;
34
+ const b223 = (pow2(b222, _1n, P) * x) % P;
35
+ return (pow2(b223, _223n, P) * b222) % P;
36
+ }
37
+ function adjustScalarBytes(bytes) {
38
+ // Section 5: Likewise, for X448, set the two least significant bits of the first byte to 0, and the most
39
+ // significant bit of the last byte to 1.
40
+ bytes[0] &= 252; // 0b11111100
41
+ // and the most significant bit of the last byte to 1.
42
+ bytes[55] |= 128; // 0b10000000
43
+ // NOTE: is is NOOP for 56 bytes scalars (X25519/X448)
44
+ bytes[56] = 0; // Byte outside of group (456 buts vs 448 bits)
45
+ return bytes;
46
+ }
47
+ const ED448_DEF = {
48
+ // Param: a
49
+ a: BigInt(1),
50
+ // -39081. Negative number is P - number
51
+ d: BigInt('726838724295606890549323807888004534353641360687318060281490199180612328166730772686396383698676545930088884461843637361053498018326358'),
52
+ // Finite field 𝔽p over which we'll do calculations; 2n ** 448n - 2n ** 224n - 1n
53
+ P: ed448P,
54
+ // Subgroup order: how many points ed448 has; 2n**446n - 13818066809895115352007386748515426880336692474882178609894547503885n
55
+ n: BigInt('181709681073901722637330951972001133588410340171829515070372549795146003961539585716195755291692375963310293709091662304773755859649779'),
56
+ nBitLength: 456,
57
+ // Cofactor
58
+ h: BigInt(4),
59
+ // Base point (x, y) aka generator point
60
+ Gx: BigInt('224580040295924300187604334099896036246789641632564134246125461686950415467406032909029192869357953282578032075146446173674602635247710'),
61
+ Gy: BigInt('298819210078481492676017930443930673437544040154080242095928241372331506189835876003536878655418784733982303233503462500531545062832660'),
62
+ // SHAKE256(dom4(phflag,context)||x, 114)
63
+ hash: shake256_114,
64
+ adjustScalarBytes,
65
+ // dom4
66
+ domain: (data, ctx, phflag) => {
67
+ if (ctx.length > 255)
68
+ throw new Error(`Context is too big: ${ctx.length}`);
69
+ return concatBytes(utf8ToBytes('SigEd448'), new Uint8Array([phflag ? 1 : 0, ctx.length]), ctx, data);
70
+ },
71
+ // Constant-time ratio of u to v. Allows to combine inversion and square root u/√v.
72
+ // Uses algo from RFC8032 5.1.3.
73
+ uvRatio: (u, v) => {
74
+ const P = ed448P;
75
+ // https://datatracker.ietf.org/doc/html/rfc8032#section-5.2.3
76
+ // To compute the square root of (u/v), the first step is to compute the
77
+ // candidate root x = (u/v)^((p+1)/4). This can be done using the
78
+ // following trick, to use a single modular powering for both the
79
+ // inversion of v and the square root:
80
+ // (p+1)/4 3 (p-3)/4
81
+ // x = (u/v) = u v (u^5 v^3) (mod p)
82
+ const u2v = mod(u * u * v, P);
83
+ const u3v = mod(u2v * u, P); // u^2v
84
+ const u5v3 = mod(u3v * u2v * v, P); // u^5v^3
85
+ const root = ed448_pow_Pminus3div4(u5v3);
86
+ const x = mod(u3v * root, P);
87
+ // Verify that root is exists
88
+ const x2 = mod(x * x, P); // x^2
89
+ // If v * x^2 = u, the recovered x-coordinate is x. Otherwise, no
90
+ // square root exists, and the decoding fails.
91
+ return { isValid: mod(x2 * v, P) === u, value: x };
92
+ },
93
+ };
94
+ export const ed448 = twistedEdwards(ED448_DEF);
95
+ // NOTE: there is no ed448ctx, since ed448 supports ctx by default
96
+ export const ed448ph = twistedEdwards({ ...ED448_DEF, preHash: shake256_64 });
97
+ export const x448 = montgomery({
98
+ a24: BigInt(39081),
99
+ montgomeryBits: 448,
100
+ nByteLength: 57,
101
+ P: ed448P,
102
+ Gu: '0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
103
+ powPminus2: (x) => {
104
+ const P = ed448P;
105
+ const Pminus3div4 = ed448_pow_Pminus3div4(x);
106
+ const Pminus3 = pow2(Pminus3div4, BigInt(2), P);
107
+ return mod(Pminus3 * x, P); // Pminus3 * x = Pminus2
108
+ },
109
+ adjustScalarBytes,
110
+ // The 4-isogeny maps between the Montgomery curve and this Edwards
111
+ // curve are:
112
+ // (u, v) = (y^2/x^2, (2 - x^2 - y^2)*y/x^3)
113
+ // (x, y) = (4*v*(u^2 - 1)/(u^4 - 2*u^2 + 4*v^2 + 1),
114
+ // -(u^5 - 2*u^3 - 4*u*v^2 + u)/
115
+ // (u^5 - 2*u^2*v^2 - 2*u^3 - 2*v^2 + u))
116
+ // xyToU: (p: PointType) => {
117
+ // const P = ed448P;
118
+ // const { x, y } = p;
119
+ // if (x === _0n) throw new Error(`Point with x=0 doesn't have mapping`);
120
+ // const invX = invert(x * x, P); // x^2
121
+ // const u = mod(y * y * invX, P); // (y^2/x^2)
122
+ // return numberToBytesLE(u, 56);
123
+ // },
124
+ });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ throw new Error('Incorrect usage. Import submodules instead');
@@ -0,0 +1,50 @@
1
+ /*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
+ import { sha256 } from '@noble/hashes/sha256';
3
+ import { concatBytes, utf8ToBytes } from '@noble/hashes/utils';
4
+ import { twistedEdwards } from '../edwards';
5
+ import { blake2s } from '@noble/hashes/blake2s';
6
+ /**
7
+ * jubjub Twisted Edwards curve.
8
+ * https://neuromancer.sk/std/other/JubJub
9
+ */
10
+ export const jubjub = twistedEdwards({
11
+ // Params: a, d
12
+ a: BigInt('0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000000'),
13
+ d: BigInt('0x2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1'),
14
+ // Finite field 𝔽p over which we'll do calculations
15
+ P: BigInt('0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001'),
16
+ // Subgroup order: how many points ed25519 has
17
+ // 2n ** 252n + 27742317777372353535851937790883648493n;
18
+ n: BigInt('0xe7db4ea6533afa906673b0101343b00a6682093ccc81082d0970e5ed6f72cb7'),
19
+ // Cofactor
20
+ h: BigInt(8),
21
+ // Base point (x, y) aka generator point
22
+ Gx: BigInt('0x11dafe5d23e1218086a365b99fbf3d3be72f6afd7d1f72623e6b071492d1122b'),
23
+ Gy: BigInt('0x1d523cf1ddab1a1793132e78c866c0c33e26ba5cc220fed7cc3f870e59d292aa'),
24
+ hash: sha256,
25
+ });
26
+ const GH_FIRST_BLOCK = utf8ToBytes('096b36a5804bfacef1691e173c366a47ff5ba84a44f26ddd7e8d9f79d5b42df0');
27
+ // Returns point at JubJub curve which is prime order and not zero
28
+ export function groupHash(tag, personalization) {
29
+ const h = blake2s.create({ personalization, dkLen: 32 });
30
+ h.update(GH_FIRST_BLOCK);
31
+ h.update(tag);
32
+ // NOTE: returns ExtendedPoint, in case it will be multiplied later
33
+ let p = jubjub.ExtendedPoint.fromAffine(jubjub.Point.fromHex(h.digest()));
34
+ // NOTE: cannot replace with isSmallOrder, returns Point*8
35
+ p = p.multiply(jubjub.CURVE.h);
36
+ if (p.equals(jubjub.ExtendedPoint.ZERO))
37
+ throw new Error('Point has small order');
38
+ return p;
39
+ }
40
+ export function findGroupHash(m, personalization) {
41
+ const tag = concatBytes(m, new Uint8Array([0]));
42
+ for (let i = 0; i < 256; i++) {
43
+ tag[tag.length - 1] = i;
44
+ try {
45
+ return groupHash(tag, personalization);
46
+ }
47
+ catch (e) { }
48
+ }
49
+ throw new Error('findGroupHash tag overflow');
50
+ }
@@ -0,0 +1,20 @@
1
+ /*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
+ import { createCurve } from './_shortw_utils.js';
3
+ import { sha256 } from '@noble/hashes/sha256';
4
+ // NIST secp192r1 aka P192
5
+ // https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/secg/secp192r1
6
+ export const P192 = createCurve({
7
+ // Params: a, b
8
+ a: BigInt('0xfffffffffffffffffffffffffffffffefffffffffffffffc'),
9
+ b: BigInt('0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1'),
10
+ // Field over which we'll do calculations; 2n ** 192n - 2n ** 64n - 1n
11
+ P: BigInt('0xfffffffffffffffffffffffffffffffeffffffffffffffff'),
12
+ // Curve order, total count of valid points in the field.
13
+ n: BigInt('0xffffffffffffffffffffffff99def836146bc9b1b4d22831'),
14
+ // Base point (x, y) aka generator point
15
+ Gx: BigInt('0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012'),
16
+ Gy: BigInt('0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811'),
17
+ h: BigInt(1),
18
+ lowS: false,
19
+ }, sha256);
20
+ export const secp192r1 = P192;
@@ -0,0 +1,21 @@
1
+ /*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
+ import { createCurve } from './_shortw_utils.js';
3
+ import { sha256 } from '@noble/hashes/sha256';
4
+ // NIST secp224r1 aka P224
5
+ // https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-224
6
+ export const P224 = createCurve({
7
+ // Params: a, b
8
+ a: BigInt('0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe'),
9
+ b: BigInt('0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4'),
10
+ // Field over which we'll do calculations; 2n**224n - 2n**96n + 1n
11
+ P: BigInt('0xffffffffffffffffffffffffffffffff000000000000000000000001'),
12
+ // Curve order, total count of valid points in the field
13
+ n: BigInt('0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d'),
14
+ // Base point (x, y) aka generator point
15
+ Gx: BigInt('0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21'),
16
+ Gy: BigInt('0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34'),
17
+ h: BigInt(1),
18
+ lowS: false,
19
+ }, sha256 // TODO: replace with sha224 when new @noble/hashes released
20
+ );
21
+ export const secp224r1 = P224;
@@ -0,0 +1,20 @@
1
+ /*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
+ import { createCurve } from './_shortw_utils.js';
3
+ import { sha256 } from '@noble/hashes/sha256';
4
+ // NIST secp256r1 aka P256
5
+ // https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-256
6
+ export const P256 = createCurve({
7
+ // Params: a, b
8
+ a: BigInt('0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc'),
9
+ b: BigInt('0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b'),
10
+ // Field over which we'll do calculations; 2n**224n * (2n**32n-1n) + 2n**192n + 2n**96n-1n
11
+ P: BigInt('0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff'),
12
+ // Curve order, total count of valid points in the field
13
+ n: BigInt('0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551'),
14
+ // Base point (x, y) aka generator point
15
+ Gx: BigInt('0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296'),
16
+ Gy: BigInt('0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5'),
17
+ h: BigInt(1),
18
+ lowS: false,
19
+ }, sha256);
20
+ export const secp256r1 = P256;
@@ -0,0 +1,21 @@
1
+ /*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
+ import { createCurve } from './_shortw_utils.js';
3
+ import { sha384 } from '@noble/hashes/sha512';
4
+ // NIST secp384r1 aka P384
5
+ // https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-384
6
+ // prettier-ignore
7
+ export const P384 = createCurve({
8
+ // Params: a, b
9
+ a: BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc'),
10
+ b: BigInt('0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef'),
11
+ // Field over which we'll do calculations. 2n**384n - 2n**128n - 2n**96n + 2n**32n - 1n
12
+ P: BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff'),
13
+ // Curve order, total count of valid points in the field.
14
+ n: BigInt('0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973'),
15
+ // Base point (x, y) aka generator point
16
+ Gx: BigInt('0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7'),
17
+ Gy: BigInt('0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f'),
18
+ h: BigInt(1),
19
+ lowS: false,
20
+ }, sha384);
21
+ export const secp384r1 = P384;
@@ -0,0 +1,33 @@
1
+ /*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
+ import { createCurve } from './_shortw_utils.js';
3
+ import { sha512 } from '@noble/hashes/sha512';
4
+ import { bytesToHex } from '../utils';
5
+ // NIST secp521r1 aka P521
6
+ // Note that it's 521, which differs from 512 of its hash function.
7
+ // https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-521
8
+ // prettier-ignore
9
+ export const P521 = createCurve({
10
+ // Params: a, b
11
+ a: BigInt('0x01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc'),
12
+ b: BigInt('0x0051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00'),
13
+ // Field over which we'll do calculations; 2n**521n - 1n
14
+ P: BigInt('0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'),
15
+ // Curve order, total count of valid points in the field
16
+ n: BigInt('0x01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409'),
17
+ // Base point (x, y) aka generator point
18
+ Gx: BigInt('0x00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66'),
19
+ Gy: BigInt('0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650'),
20
+ h: BigInt(1),
21
+ lowS: false,
22
+ normalizePrivateKey(key) {
23
+ if (typeof key === 'bigint')
24
+ return key;
25
+ if (key instanceof Uint8Array)
26
+ key = bytesToHex(key);
27
+ if (typeof key !== 'string' || !([130, 131, 132].includes(key.length))) {
28
+ throw new Error('Invalid key');
29
+ }
30
+ return key.padStart(66 * 2, '0');
31
+ }
32
+ }, sha512);
33
+ export const secp521r1 = P521;
@@ -0,0 +1,29 @@
1
+ /*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
2
+ import { sha256 } from '@noble/hashes/sha256';
3
+ import { weierstrass } from '../weierstrass';
4
+ import { getHash } from './_shortw_utils.js';
5
+ import * as mod from '../modular';
6
+ const p = BigInt('0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001');
7
+ const q = BigInt('0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001');
8
+ // https://neuromancer.sk/std/other/Pallas
9
+ export const pallas = weierstrass({
10
+ a: BigInt(0),
11
+ b: BigInt(5),
12
+ P: p,
13
+ n: q,
14
+ Gx: mod.mod(BigInt(-1), p),
15
+ Gy: BigInt(2),
16
+ h: BigInt(1),
17
+ ...getHash(sha256),
18
+ });
19
+ // https://neuromancer.sk/std/other/Vesta
20
+ export const vesta = weierstrass({
21
+ a: BigInt(0),
22
+ b: BigInt(5),
23
+ P: q,
24
+ n: p,
25
+ Gx: mod.mod(BigInt(-1), q),
26
+ Gy: BigInt(2),
27
+ h: BigInt(1),
28
+ ...getHash(sha256),
29
+ });