@mnemom/mnemom 0.17.35 → 0.17.37

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 (101) hide show
  1. package/dist/commands/agent-run.d.ts +4 -0
  2. package/dist/commands/agent-run.js +9 -1
  3. package/dist/commands/agent-share-render.js +1 -1
  4. package/dist/commands/scan.d.ts +13 -3
  5. package/dist/commands/scan.js +48 -10
  6. package/dist/host/commands.js +4 -1
  7. package/dist/host/owner.d.ts +2 -0
  8. package/dist/host/verbs.d.ts +16 -1
  9. package/dist/host/verbs.js +45 -3
  10. package/dist/index.js +3 -2
  11. package/dist/lib/config.d.ts +7 -0
  12. package/dist/lib/config.js +21 -0
  13. package/dist/lib/scan/pr-source.js +2 -0
  14. package/dist/lib/scan/repo-picker.d.ts +32 -0
  15. package/dist/lib/scan/repo-picker.js +80 -0
  16. package/dist/vendor/durable-contract/index.js +6 -3
  17. package/dist/vendor/shared/durable-contract/cli-surface.js +2 -2
  18. package/dist/vendor/shared/durable-contract/codes.js +4 -1
  19. package/node_modules/@mnemom/aip-verifier/LICENSE +190 -0
  20. package/node_modules/@mnemom/aip-verifier/dist/claim-lint-CVITIRcU.d.cts +478 -0
  21. package/node_modules/@mnemom/aip-verifier/dist/claim-lint-CVITIRcU.d.ts +478 -0
  22. package/node_modules/@mnemom/aip-verifier/dist/index.cjs +971 -0
  23. package/node_modules/@mnemom/aip-verifier/dist/index.cjs.map +1 -0
  24. package/node_modules/@mnemom/aip-verifier/dist/index.d.cts +330 -0
  25. package/node_modules/@mnemom/aip-verifier/dist/index.d.ts +330 -0
  26. package/node_modules/@mnemom/aip-verifier/dist/index.js +933 -0
  27. package/node_modules/@mnemom/aip-verifier/dist/index.js.map +1 -0
  28. package/node_modules/@mnemom/aip-verifier/dist/render-lines.cjs +879 -0
  29. package/node_modules/@mnemom/aip-verifier/dist/render-lines.cjs.map +1 -0
  30. package/node_modules/@mnemom/aip-verifier/dist/render-lines.d.cts +96 -0
  31. package/node_modules/@mnemom/aip-verifier/dist/render-lines.d.ts +96 -0
  32. package/node_modules/@mnemom/aip-verifier/dist/render-lines.js +875 -0
  33. package/node_modules/@mnemom/aip-verifier/dist/render-lines.js.map +1 -0
  34. package/node_modules/@mnemom/aip-verifier/package.json +86 -0
  35. package/node_modules/@noble/ed25519/LICENSE +21 -0
  36. package/node_modules/@noble/ed25519/README.md +371 -0
  37. package/node_modules/@noble/ed25519/index.d.ts +391 -0
  38. package/node_modules/@noble/ed25519/index.js +933 -0
  39. package/node_modules/@noble/ed25519/index.ts +1134 -0
  40. package/node_modules/@noble/ed25519/package.json +54 -0
  41. package/node_modules/@noble/hashes/LICENSE +21 -0
  42. package/node_modules/@noble/hashes/README.md +478 -0
  43. package/node_modules/@noble/hashes/_blake.d.ts +20 -0
  44. package/node_modules/@noble/hashes/_blake.js +59 -0
  45. package/node_modules/@noble/hashes/_md.d.ts +95 -0
  46. package/node_modules/@noble/hashes/_md.js +209 -0
  47. package/node_modules/@noble/hashes/_u64.d.ts +36 -0
  48. package/node_modules/@noble/hashes/_u64.js +77 -0
  49. package/node_modules/@noble/hashes/argon2.d.ts +148 -0
  50. package/node_modules/@noble/hashes/argon2.js +577 -0
  51. package/node_modules/@noble/hashes/blake1.d.ts +162 -0
  52. package/node_modules/@noble/hashes/blake1.js +630 -0
  53. package/node_modules/@noble/hashes/blake2.d.ts +203 -0
  54. package/node_modules/@noble/hashes/blake2.js +573 -0
  55. package/node_modules/@noble/hashes/blake3.d.ts +68 -0
  56. package/node_modules/@noble/hashes/blake3.js +310 -0
  57. package/node_modules/@noble/hashes/eskdf.d.ts +91 -0
  58. package/node_modules/@noble/hashes/eskdf.js +225 -0
  59. package/node_modules/@noble/hashes/hkdf.d.ts +70 -0
  60. package/node_modules/@noble/hashes/hkdf.js +152 -0
  61. package/node_modules/@noble/hashes/hmac.d.ts +50 -0
  62. package/node_modules/@noble/hashes/hmac.js +93 -0
  63. package/node_modules/@noble/hashes/index.d.ts +1 -0
  64. package/node_modules/@noble/hashes/index.js +34 -0
  65. package/node_modules/@noble/hashes/legacy.d.ts +107 -0
  66. package/node_modules/@noble/hashes/legacy.js +348 -0
  67. package/node_modules/@noble/hashes/package.json +91 -0
  68. package/node_modules/@noble/hashes/pbkdf2.d.ts +66 -0
  69. package/node_modules/@noble/hashes/pbkdf2.js +176 -0
  70. package/node_modules/@noble/hashes/scrypt.d.ts +98 -0
  71. package/node_modules/@noble/hashes/scrypt.js +304 -0
  72. package/node_modules/@noble/hashes/sha2.d.ts +176 -0
  73. package/node_modules/@noble/hashes/sha2.js +446 -0
  74. package/node_modules/@noble/hashes/sha3-addons.d.ts +533 -0
  75. package/node_modules/@noble/hashes/sha3-addons.js +973 -0
  76. package/node_modules/@noble/hashes/sha3.d.ts +208 -0
  77. package/node_modules/@noble/hashes/sha3.js +475 -0
  78. package/node_modules/@noble/hashes/src/_blake.ts +67 -0
  79. package/node_modules/@noble/hashes/src/_md.ts +227 -0
  80. package/node_modules/@noble/hashes/src/_u64.ts +111 -0
  81. package/node_modules/@noble/hashes/src/argon2.ts +693 -0
  82. package/node_modules/@noble/hashes/src/blake1.ts +677 -0
  83. package/node_modules/@noble/hashes/src/blake2.ts +648 -0
  84. package/node_modules/@noble/hashes/src/blake3.ts +344 -0
  85. package/node_modules/@noble/hashes/src/eskdf.ts +265 -0
  86. package/node_modules/@noble/hashes/src/hkdf.ts +161 -0
  87. package/node_modules/@noble/hashes/src/hmac.ts +130 -0
  88. package/node_modules/@noble/hashes/src/index.ts +33 -0
  89. package/node_modules/@noble/hashes/src/legacy.ts +361 -0
  90. package/node_modules/@noble/hashes/src/pbkdf2.ts +219 -0
  91. package/node_modules/@noble/hashes/src/scrypt.ts +375 -0
  92. package/node_modules/@noble/hashes/src/sha2.ts +486 -0
  93. package/node_modules/@noble/hashes/src/sha3-addons.ts +1157 -0
  94. package/node_modules/@noble/hashes/src/sha3.ts +525 -0
  95. package/node_modules/@noble/hashes/src/utils.ts +978 -0
  96. package/node_modules/@noble/hashes/src/webcrypto.ts +283 -0
  97. package/node_modules/@noble/hashes/utils.d.ts +560 -0
  98. package/node_modules/@noble/hashes/utils.js +687 -0
  99. package/node_modules/@noble/hashes/webcrypto.d.ts +121 -0
  100. package/node_modules/@noble/hashes/webcrypto.js +228 -0
  101. package/package.json +5 -2
@@ -0,0 +1,1134 @@
1
+ /*! noble-ed25519 - MIT License (c) 2019 Paul Miller (paulmillr.com) */
2
+ /**
3
+ * 5KB JS implementation of ed25519 EdDSA signatures.
4
+ * Targets RFC8032, FIPS 186-5, and ZIP215 behavior.
5
+ * @module
6
+ * @example
7
+ * ```js
8
+ import * as ed from '@noble/ed25519';
9
+ (async () => {
10
+ const secretKey = ed.utils.randomSecretKey();
11
+ const message = Uint8Array.from([0xab, 0xbc, 0xcd, 0xde]);
12
+ const pubKey = await ed.getPublicKeyAsync(secretKey); // Sync methods are also present
13
+ const signature = await ed.signAsync(message, secretKey);
14
+ const isValid = await ed.verifyAsync(signature, message, pubKey);
15
+ })();
16
+ ```
17
+ */
18
+ /**
19
+ * Curve params. edwards25519 uses the RFC equation `-x² + y² = 1 + dx²y²`.
20
+ * The stored `a` literal below is `p - 1`, i.e. the field-element encoding of RFC `a = -1`.
21
+ * * P = `2n**255n - 19n` // field over which calculations are done
22
+ * * N = `2n**252n + 27742317777372353535851937790883648493n` // prime-order subgroup order
23
+ * * h = 8 // cofactor
24
+ * * a = `Fp.create(BigInt(-1))` // equation param, stored here as `p - 1`
25
+ * * d = -121665/121666 a.k.a. `Fp.neg(121665 * Fp.inv(121666))` // equation param
26
+ * * Gx, Gy are coordinates of Generator / base point
27
+ *
28
+ * Mirror noble-curves: Point.CURVE() exposes shared params, but callers must not be able to mutate
29
+ * that shared view and desynchronize it from the arithmetic constants captured below.
30
+ */
31
+ const freeze = Object.freeze;
32
+ const P = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffedn;
33
+ const N = 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3edn;
34
+ const _d = 0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3n;
35
+ const Gx = 0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51an;
36
+ const Gy = 0x6666666666666666666666666666666666666666666666666666666666666658n;
37
+ const _a = P - 1n; // field-element encoding of RFC `a = -1`
38
+ const ed25519_CURVE: EdwardsOpts = freeze({
39
+ p: P,
40
+ n: N,
41
+ h: 8n,
42
+ a: _a,
43
+ d: _d,
44
+ Gx,
45
+ Gy,
46
+ });
47
+ // Shared 32-byte encoded width for Ed25519 points, scalars, signatures/2, and keys. Named LEN
48
+ // rather than RFC 8032's `L`, which names the group order (stored here as `N`).
49
+ const LEN = 32;
50
+ /** Alias to Uint8Array. */
51
+ export type Bytes = Uint8Array;
52
+ /** Edwards elliptic curve options. */
53
+ export type EdwardsOpts = Readonly<{
54
+ /** Prime field modulus. */
55
+ p: bigint;
56
+ /** Group order. */
57
+ n: bigint;
58
+ /** Curve cofactor. */
59
+ h: bigint;
60
+ /** Edwards curve parameter `a`. */
61
+ a: bigint;
62
+ /** Edwards curve parameter `d`. */
63
+ d: bigint;
64
+ /** Generator x coordinate. */
65
+ Gx: bigint;
66
+ /** Generator y coordinate. */
67
+ Gy: bigint;
68
+ }>;
69
+
70
+ // Helpers and Precomputes sections are reused between libraries
71
+
72
+ // ## Helpers
73
+ // ----------
74
+ /** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */
75
+ const isBytes = (a: unknown): a is Uint8Array => {
76
+ // Plain `instanceof Uint8Array` is too strict for some Buffer / proxy / cross-realm cases.
77
+ // The fallback still requires a real ArrayBuffer view, so plain
78
+ // JSON-deserialized `{ constructor: ... }` spoofing is rejected, and
79
+ // `BYTES_PER_ELEMENT === 1` keeps the fallback on byte-oriented views.
80
+ return (
81
+ a instanceof Uint8Array ||
82
+ (ArrayBuffer.isView(a) &&
83
+ a.constructor.name === 'Uint8Array' &&
84
+ (a as Uint8Array).BYTES_PER_ELEMENT === 1)
85
+ );
86
+ };
87
+ /** Asserts something is Bytes. */
88
+ const abytes = (value: unknown, length?: number, title: string = ''): TRet<Uint8Array> => {
89
+ // Success path first: this runs at the start of every update() / digestInto(), and the
90
+ // common `abytes(data)` form must not pay for length handling it does not use.
91
+ if (isBytes(value) && (length === undefined || value.length === length))
92
+ return value as TRet<Uint8Array>;
93
+ // Error path: recompute freely to build the exact message.
94
+ const bytes = isBytes(value);
95
+ const ofLen = length !== undefined ? ` of length ${length}` : '';
96
+ const got = bytes ? `length=${value.length}` : `type=${typeof value}`;
97
+ const message = (title ? `"${title}" ` : '') + 'expected Uint8Array' + ofLen + ', got ' + got;
98
+ if (!bytes) throw new TypeError(message);
99
+ throw new RangeError(message);
100
+ };
101
+ // Validate, then take one owned copy, so later caller mutation cannot be observed — e.g. cannot
102
+ // make sign()'s nonce derivation and challenge derivation see different messages.
103
+ const snapshotBytes = (value: unknown, title: string = '', length?: number): TRet<Uint8Array> =>
104
+ Uint8Array.from(abytes(value, length, title));
105
+ // Callers keep values non-negative and within the requested width; padStart() won't truncate over-wide inputs.
106
+ const padh = (n: number | bigint, pad: number) => n.toString(16).padStart(pad, '0');
107
+ /** Convert byte array to hex string. */
108
+ const bytesToHex = (bytes: TArg<Uint8Array>): string => {
109
+ let hex = '';
110
+ for (const byte of abytes(bytes)) hex += padh(byte, 2);
111
+ return hex;
112
+ };
113
+ /** Convert hex string to byte array. */
114
+ const hexToBytes = (hex: string): TRet<Uint8Array> => {
115
+ const e = 'hex invalid'; // Strict ASCII hex only, with one generic error for parse failures.
116
+ if (typeof hex !== 'string') throw new TypeError(e);
117
+ if (hex.length % 2 || !/^[\da-f]*$/i.test(hex)) throw new RangeError(e);
118
+ const array = new Uint8Array(hex.length / 2);
119
+ for (let ai = 0, hi = 0; ai < array.length; ai++, hi += 2) {
120
+ const n1 = hex.charCodeAt(hi);
121
+ const n2 = hex.charCodeAt(hi + 1);
122
+ // Regex guarantees ASCII. For 0..9/A..F/a..f, this maps char codes to 0..15.
123
+ array[ai] = ((n1 & 15) + (n1 >> 6) * 9) * 16 + (n2 & 15) + (n2 >> 6) * 9;
124
+ }
125
+ return array as TRet<Uint8Array>;
126
+ };
127
+ declare const globalThis: Record<string, any> | undefined; // Typescript symbol present in browsers
128
+ // WebCrypto is available in all modern environments
129
+ /** Copies several Uint8Arrays into one. */
130
+ const concatBytes = (...arrays: TArg<Uint8Array[]>): TRet<Uint8Array> => {
131
+ let sum = 0;
132
+ for (const a of arrays) sum += abytes(a).length;
133
+ const res = new Uint8Array(sum);
134
+ let pad = 0;
135
+ for (const a of arrays) {
136
+ res.set(a, pad);
137
+ pad += a.length;
138
+ }
139
+ return res;
140
+ };
141
+ /**
142
+ * WebCrypto OS-level CSPRNG (random number generator).
143
+ * Will throw when not available; large-request ceilings are delegated to getRandomValues().
144
+ */
145
+ const randomBytes = (len: number = LEN): TRet<Uint8Array> => {
146
+ const c = globalThis?.crypto;
147
+ if (typeof c?.getRandomValues !== 'function')
148
+ throw new Error('crypto.getRandomValues must be defined, consider polyfill');
149
+ return c.getRandomValues(new Uint8Array(len)) as TRet<Uint8Array>;
150
+ };
151
+ /** Inclusive-lower, exclusive-upper bigint range assertion. */
152
+ const arange = (n: bigint, min: bigint, max: bigint, msg = 'bad number: out of range'): bigint => {
153
+ if (typeof n !== 'bigint') throw new TypeError(msg);
154
+ if (min <= n && n < max) return n;
155
+ throw new RangeError(msg);
156
+ };
157
+ /** Canonical modular reduction. Callers must provide a positive modulus. */
158
+ const mod = (a: bigint, b: bigint = P) => ((a %= b) >= 0n ? a : b + a);
159
+ // Low-255-bit mask used by the `2^255 - 19` fast reduction in `modP(...)`.
160
+ const P_MASK = (1n << 255n) - 1n;
161
+ // Fast reduction for the special prime `2^255 - 19`. This path assumes nonnegative inputs; the
162
+ // generic fallback would simply be `mod(num, P)`.
163
+ const modP = (num: bigint): bigint => {
164
+ if (num < 0n) throw new RangeError('negative coordinate');
165
+ let r = (num >> 255n) * 19n + (num & P_MASK);
166
+ r = (r >> 255n) * 19n + (r & P_MASK);
167
+ return r % P;
168
+ };
169
+ // Reduce modulo the subgroup order stored in implementation constant `N` (RFC 8032's `L`).
170
+ const modN = (a: bigint) => mod(a, N);
171
+ /** Modular inversion using extended euclidean GCD. Variable-time (non-CT). */
172
+ const invert = (number: bigint, modulo: bigint): bigint => {
173
+ if (number === 0n) throw new Error('invert: expected non-zero number');
174
+ // modulo = 1 is the zero ring: gcd(x, 1) = 1 makes the loop below "succeed" and return the
175
+ // useless inverse 0. Reject it like pow() and invertCt() do.
176
+ if (modulo <= 1n) throw new Error('invert: expected modulus > 1, got ' + modulo);
177
+ // This is variable-time: the loop count depends on `number`.
178
+ let a = mod(number, modulo);
179
+ let b = modulo;
180
+ // Only the Bézout coefficient of `number` (x/u chain) is tracked; the coefficient of `modulo`
181
+ // never affects the output, so it is not computed.
182
+ // prettier-ignore
183
+ let x = 0n, u = 1n;
184
+ while (a !== 0n) {
185
+ const q = b / a;
186
+ const r = b - a * q;
187
+ const m = x - u * q;
188
+ // prettier-ignore
189
+ b = a, a = r, x = u, u = m;
190
+ }
191
+ const gcd = b;
192
+ if (gcd !== 1n) throw new Error('invert: does not exist');
193
+ return mod(x, modulo);
194
+ };
195
+ // Dynamic lookup keeps sync/async hash providers configurable at runtime. Both exported slots are
196
+ // caller-owned and may be unset; wrapper helpers use this lookup first and then enforce the digest
197
+ // contract instead of trusting provider output.
198
+ const _hash = (name: string) => {
199
+ // @ts-ignore
200
+ const fn = hashes[name];
201
+ if (typeof fn !== 'function') throw new Error('hashes.' + name + ' not set');
202
+ return fn;
203
+ };
204
+ // All exported provider slots are caller-configurable and may be unset or return arbitrary values,
205
+ // so wrapper helpers must enforce the exact 64-byte SHA-512 digest contract instead of trusting providers.
206
+ const callHash = (name: string, ...m: Uint8Array[]): TRet<Uint8Array> =>
207
+ abytes(_hash(name)(concatBytes(...m)), 64, 'digest');
208
+ const callHashAsync = async (name: string, ...m: Uint8Array[]): Promise<TRet<Uint8Array>> =>
209
+ abytes(await _hash(name)(concatBytes(...m)), 64, 'digest');
210
+ /**
211
+ * SHA-512 helper used by the synchronous API.
212
+ * @param msg - Message bytes to hash.
213
+ * @returns 64-byte SHA-512 digest.
214
+ * @example
215
+ * Hash message bytes after wiring the synchronous SHA-512 implementation.
216
+ *
217
+ * ```ts
218
+ * import * as ed from '@noble/ed25519';
219
+ * import { sha512 } from '@noble/hashes/sha2.js';
220
+ *
221
+ * ed.hashes.sha512 = sha512;
222
+ * const digest = ed.hash(new Uint8Array([1, 2, 3]));
223
+ * ```
224
+ */
225
+ // Public helper validates the message boundary explicitly; the configured provider is still looked
226
+ // up dynamically and its output is checked with `callHash(...)`.
227
+ const hash = (msg: TArg<Uint8Array>): TRet<Uint8Array> =>
228
+ callHash('sha512', abytes(msg, undefined, 'message'));
229
+ // Runtime class guard: this is `instanceof Point`, so cross-realm / duplicate-bundle Point objects
230
+ // are rejected even if they are structurally identical.
231
+ const apoint = (p: unknown) => {
232
+ if (p instanceof Point) return p;
233
+ throw new TypeError('Point expected');
234
+ };
235
+ /** Point in 2d xy affine coordinates. */
236
+ export type AffinePoint = {
237
+ /** Affine x coordinate. */
238
+ x: bigint;
239
+ /** Affine y coordinate. */
240
+ y: bigint;
241
+ };
242
+ // ## End of Helpers
243
+ // -----------------
244
+
245
+ // Exclusive upper bound `2^256` used by 32-byte decode/serialization range checks.
246
+ const B256 = 2n ** 256n;
247
+ /**
248
+ * Point in XYZT extended coordinates.
249
+ * @param X - X coordinate.
250
+ * @param Y - Y coordinate.
251
+ * @param Z - Projective Z coordinate.
252
+ * @param T - Cached cross-product term.
253
+ * @example
254
+ * Do point arithmetic with the built-in base point and encode the result as hex.
255
+ *
256
+ * ```ts
257
+ * const hex = Point.BASE.double().toHex();
258
+ * ```
259
+ */
260
+ class Point {
261
+ static BASE: Point;
262
+ static ZERO: Point;
263
+ readonly X: bigint;
264
+ readonly Y: bigint;
265
+ readonly Z: bigint;
266
+ readonly T: bigint;
267
+ // Constructor only bounds-checks and freezes XYZT coordinates; it does not prove the point is
268
+ // on-curve or that T matches X*Y/Z.
269
+ constructor(X: bigint, Y: bigint, Z: bigint, T: bigint) {
270
+ const max = B256;
271
+ this.X = arange(X, 0n, max);
272
+ this.Y = arange(Y, 0n, max);
273
+ this.Z = arange(Z, 1n, max);
274
+ this.T = arange(T, 0n, max);
275
+ freeze(this);
276
+ }
277
+ static CURVE(): EdwardsOpts {
278
+ return ed25519_CURVE;
279
+ }
280
+ static fromAffine(p: AffinePoint): Point {
281
+ return new Point(p.x, p.y, 1n, modP(p.x * p.y));
282
+ }
283
+ /** RFC8032 5.1.3: Uint8Array to Point. */
284
+ static fromBytes(bytes: TArg<Uint8Array>, zip215 = false): Point {
285
+ const normed = snapshotBytes(bytes, 'point', LEN); // owned copy: sign-bit mask below mutates it
286
+ // adjust first LE byte = last BE byte
287
+ const lastByte = normed[31];
288
+ normed[31] = lastByte & ~0x80;
289
+ const y = bytesToNumberLE(normed);
290
+ // After clearing the sign bit, parsed `y` is always < 2^255. ZIP-215 still accepts the full
291
+ // post-mask range here, while strict RFC8032 decoding further requires `y < p`.
292
+ if (!zip215) arange(y, 0n, P);
293
+
294
+ const y2 = modP(y * y); // y²
295
+ const u = mod(y2 - 1n); // u=y²-1
296
+ const v = modP(_d * y2 + 1n); // v=dy²+1
297
+ let { isValid, value: x } = uvRatio(u, v); // (uv³)(uv⁷)^(p-5)/8; square root
298
+ if (!isValid) throw new Error('bad point: y not sqrt'); // not square root: bad point
299
+ const isLastByteOdd = !!(lastByte & 0x80); // x_0, last bit
300
+ // ZIP-215-compatible decoding keeps the x=0 / sign-bit=1 encoding accepted; strict RFC 8032
301
+ // rejects it, but the vendored ZIP-215 compliance vectors include this form in A/R bytes.
302
+ if (!zip215 && x === 0n && isLastByteOdd) throw new Error('bad point: x==0, isLastByteOdd'); // x=0, x_0=1
303
+ if (isLastByteOdd !== !!(x & 1n)) x = mod(-x); // adjust sign of x coordinate
304
+ return new Point(x, y, 1n, modP(x * y)); // Z=1, T=xy
305
+ }
306
+ static fromHex(hex: string, zip215?: boolean): Point {
307
+ return Point.fromBytes(hexToBytes(hex), zip215);
308
+ }
309
+ get x(): bigint {
310
+ return this.toAffine().x;
311
+ }
312
+ get y(): bigint {
313
+ return this.toAffine().y;
314
+ }
315
+ /** Checks if the point is valid and on-curve. */
316
+ assertValidity(): this {
317
+ const a = _a;
318
+ const d = _d;
319
+ const p = this;
320
+ // Intentional stricter-than-on-curve policy: reject ZERO by default because many protocols
321
+ // require a non-zero point, and silently accepting identity points is a common caller mistake.
322
+ if (p.is0()) throw new Error('bad point: ZERO');
323
+ // Equation in affine coordinates: ax² + y² = 1 + dx²y²
324
+ // Equation in projective coordinates (X/Z, Y/Z, Z): (aX² + Y²)Z² = Z⁴ + dX²Y²
325
+ const { X, Y, Z, T } = p;
326
+ const X2 = modP(X * X); // X²
327
+ const Y2 = modP(Y * Y); // Y²
328
+ const Z2 = modP(Z * Z); // Z²
329
+ const Z4 = modP(Z2 * Z2); // Z⁴
330
+ const aX2 = modP(X2 * a); // aX²
331
+ const left = modP(Z2 * (aX2 + Y2)); // (aX² + Y²)Z²
332
+ const right = mod(Z4 + modP(d * modP(X2 * Y2))); // Z⁴ + dX²Y²
333
+ if (left !== right) throw new Error('bad point: equation left != right (1)');
334
+ // In Extended coordinates we also have T, which is x*y=T/Z: check X*Y == Z*T
335
+ const XY = modP(X * Y);
336
+ const ZT = modP(Z * T);
337
+ if (XY !== ZT) throw new Error('bad point: equation left != right (2)');
338
+ return this;
339
+ }
340
+ /** Equality check: compare points P&Q. */
341
+ equals(other: Point): boolean {
342
+ const { X: X1, Y: Y1, Z: Z1 } = this;
343
+ const { X: X2, Y: Y2, Z: Z2 } = apoint(other); // checks class equality
344
+ return modP(X1 * Z2) === modP(X2 * Z1) && modP(Y1 * Z2) === modP(Y2 * Z1);
345
+ }
346
+ is0(): boolean {
347
+ return this.equals(I);
348
+ }
349
+ /** Flip point over y coordinate. */
350
+ negate(): Point {
351
+ return new Point(mod(-this.X), this.Y, this.Z, mod(-this.T));
352
+ }
353
+ /** Point doubling. Complete formula. Cost: `4M + 4S + 1*a + 6add + 1*2`. */
354
+ double(): Point {
355
+ const { X: X1, Y: Y1, Z: Z1 } = this;
356
+ const a = _a;
357
+ // https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#doubling-dbl-2008-hwcd
358
+ const A = modP(X1 * X1);
359
+ const B = modP(Y1 * Y1);
360
+ const C = modP(2n * Z1 * Z1);
361
+ const D = modP(a * A);
362
+ const x1y1 = mod(X1 + Y1);
363
+ const E = mod(modP(x1y1 * x1y1) - A - B);
364
+ const G = mod(D + B);
365
+ const F = mod(G - C);
366
+ const H = mod(D - B);
367
+ const X3 = modP(E * F);
368
+ const Y3 = modP(G * H);
369
+ const T3 = modP(E * H);
370
+ const Z3 = modP(F * G);
371
+ return new Point(X3, Y3, Z3, T3);
372
+ }
373
+ /** Point addition. Complete formula. Cost: `9M + 1*a + 1*d + 7add`. */
374
+ add(other: Point): Point {
375
+ const { X: X1, Y: Y1, Z: Z1, T: T1 } = this;
376
+ const { X: X2, Y: Y2, Z: Z2, T: T2 } = apoint(other); // doesn't check if other on-curve
377
+ const a = _a;
378
+ const d = _d;
379
+ // https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#addition-add-2008-hwcd
380
+ const A = modP(X1 * X2);
381
+ const B = modP(Y1 * Y2);
382
+ const C = modP(modP(T1 * d) * T2);
383
+ const D = modP(Z1 * Z2);
384
+ const E = mod(modP(mod(X1 + Y1) * mod(X2 + Y2)) - A - B);
385
+ const F = mod(D - C);
386
+ const G = mod(D + C);
387
+ const H = mod(B - modP(a * A));
388
+ const X3 = modP(E * F);
389
+ const Y3 = modP(G * H);
390
+ const T3 = modP(E * H);
391
+ const Z3 = modP(F * G);
392
+ return new Point(X3, Y3, Z3, T3);
393
+ }
394
+ subtract(other: Point): Point {
395
+ return this.add(apoint(other).negate());
396
+ }
397
+ /**
398
+ * Point-by-scalar multiplication. Safe mode requires `1 <= n < CURVE.n`.
399
+ * Unsafe mode additionally permits `n = 0` and returns the identity point for that case.
400
+ * Uses {@link wNAF} for base point.
401
+ * Uses fake point to mitigate side-channel leakage.
402
+ * @param n - scalar by which point is multiplied
403
+ * @param safe - safe mode guards against timing attacks; unsafe mode is faster
404
+ */
405
+ multiply(n: bigint, safe = true): Point {
406
+ // Mirror noble-curves: unsafe mode still validates scalar range first, but intentionally keeps
407
+ // `n = 0` as the one extra accepted case used by verification-style callers.
408
+ if (!safe && n === 0n) return I;
409
+ arange(n, 1n, N);
410
+ if (!safe && this.is0()) return I;
411
+ if (n === 1n) return this;
412
+ if (this.equals(G)) return wNAF(n).p;
413
+ // init result point & fake point
414
+ let p = I;
415
+ let f = G;
416
+ let d: Point = this;
417
+ // Safe mode always runs 256 iterations so ladder length can't leak the scalar's
418
+ // leading zero bits; unsafe mode stops at the top set bit for speed.
419
+ for (let i = 0; safe ? i < 256 : n > 0n; i++) {
420
+ // if bit is present, add to point
421
+ // if not present, add to fake, for timing safety
422
+ if (n & 1n) p = p.add(d);
423
+ else if (safe) f = f.add(d);
424
+ d = d.double();
425
+ n >>= 1n;
426
+ }
427
+ return p;
428
+ }
429
+ multiplyUnsafe(scalar: bigint): Point {
430
+ return this.multiply(scalar, false);
431
+ }
432
+ /** Convert point to 2d xy affine point. (X, Y, Z) ∋ (x=X/Z, y=Y/Z) */
433
+ toAffine(): AffinePoint {
434
+ const { X, Y, Z } = this;
435
+ // Fast-path only for the identity point; all other inputs still go through inversion.
436
+ if (this.equals(I)) return { x: 0n, y: 1n };
437
+ const iz = invert(Z, P);
438
+ // (Z * Z^-1) must be 1, otherwise bad math
439
+ if (modP(Z * iz) !== 1n) throw new Error('invalid inverse');
440
+ // x = X*Z^-1; y = Y*Z^-1
441
+ return { x: modP(X * iz), y: modP(Y * iz) };
442
+ }
443
+ toBytes(): TRet<Uint8Array> {
444
+ const { x, y } = this.toAffine();
445
+ const b = numTo32bLE(y);
446
+ // store sign in first LE byte
447
+ b[31] |= x & 1n ? 0x80 : 0;
448
+ return b;
449
+ }
450
+ toHex(): string {
451
+ return bytesToHex(this.toBytes());
452
+ }
453
+
454
+ clearCofactor(): Point {
455
+ return this.multiply(8n, false); // h = 8
456
+ }
457
+ isSmallOrder(): boolean {
458
+ return this.clearCofactor().is0();
459
+ }
460
+ isTorsionFree(): boolean {
461
+ // Multiply by big number N. We can't `mul(N)` because of checks. Instead, we `mul(N/2)*2+1`;
462
+ // N is odd, so N/2 truncates and the final `add(this)` is always needed.
463
+ return this.multiply(N / 2n, false)
464
+ .double()
465
+ .add(this)
466
+ .is0();
467
+ }
468
+ }
469
+ /** Generator / base point */
470
+ const G: Point = new Point(Gx, Gy, 1n, mod(Gx * Gy));
471
+ /** Identity / zero point */
472
+ const I: Point = new Point(0n, 1n, 1n, 0n);
473
+ // Static aliases
474
+ Point.BASE = G;
475
+ Point.ZERO = I;
476
+
477
+ const numTo32bLE = (num: bigint): TRet<Uint8Array> =>
478
+ hexToBytes(padh(arange(num, 0n, B256), 64)).reverse() as TRet<Uint8Array>;
479
+ // Caller-enforced width: some sites require 32-byte RFC encodings, while others intentionally feed
480
+ // wider SHA-512 output chunks through the same little-endian parser.
481
+ const bytesToNumberLE = (b: Uint8Array): bigint =>
482
+ BigInt('0x' + bytesToHex(Uint8Array.from(abytes(b)).reverse()));
483
+
484
+ const pow2 = (x: bigint, power: number): bigint => {
485
+ // pow2(x, 4) == x^(2^4)
486
+ // Negative `power` values are not rejected here and currently leave `x` unchanged.
487
+ let r = x;
488
+ while (power-- > 0) {
489
+ r = modP(r * r);
490
+ }
491
+ return r;
492
+ };
493
+
494
+ // prettier-ignore
495
+ const pow_2_252_3 = (x: bigint) => { // x^(2^252-3) unrolled util for square root
496
+ const x2 = modP(x * x); // x^2, bits 1
497
+ const b2 = modP(x2 * x); // x^3, bits 11
498
+ const b4 = modP(pow2(b2, 2) * b2); // x^(2^4-1), bits 1111
499
+ const b5 = modP(pow2(b4, 1) * x); // x^(2^5-1), bits 11111
500
+ const b10 = modP(pow2(b5, 5) * b5); // x^(2^10-1)
501
+ const b20 = modP(pow2(b10, 10) * b10); // x^(2^20-1)
502
+ const b40 = modP(pow2(b20, 20) * b20); // x^(2^40-1)
503
+ const b80 = modP(pow2(b40, 40) * b40); // x^(2^80-1)
504
+ const b160 = modP(pow2(b80, 80) * b80); // x^(2^160-1)
505
+ const b240 = modP(pow2(b160, 80) * b80); // x^(2^240-1)
506
+ const b250 = modP(pow2(b240, 10) * b10); // x^(2^250-1)
507
+ return modP(pow2(b250, 2) * x); // x^((p-5)/8), used by RFC8032 point decode
508
+ };
509
+ const RM1 = 0x2b8324804fc1df0b2b4d00993dfbd7a72f431806ad2fe478c4ee1b274a0ea0b0n; // 2^((p-1)/4) = sqrt(-1)
510
+ // RFC8032 §5.1.3 square-root helper for point decompression. `value` is only meaningful when
511
+ // `isValid` is true; callers are also expected to pass canonical field elements with non-zero `v`.
512
+ // prettier-ignore
513
+ const uvRatio = (u: bigint, v: bigint): { isValid: boolean, value: bigint } => {
514
+ const v3 = modP(v * modP(v * v)); // v³
515
+ const v7 = modP(modP(v3 * v3) * v); // v⁷
516
+ const pow = pow_2_252_3(modP(u * v7)); // (uv⁷)^(p-5)/8
517
+ let x = modP(u * modP(v3 * pow)); // (uv³)(uv⁷)^(p-5)/8
518
+ const vx2 = modP(v * modP(x * x)); // vx²
519
+ const root1 = x; // First root candidate
520
+ const root2 = modP(x * RM1); // Second root candidate; RM1 is √-1
521
+ const useRoot1 = vx2 === u; // If vx² = u (mod p), x is a square root
522
+ const useRoot2 = vx2 === mod(-u); // If vx² = -u, set x <-- x * 2^((p-1)/4)
523
+ const noRoot = vx2 === mod(-u * RM1); // There is no valid root, vx² = -u√-1
524
+ if (useRoot1) x = root1;
525
+ if (useRoot2 || noRoot) x = root2; // We return root2 anyway, for const-time
526
+ if ((mod(x) & 1n) === 1n) x = mod(-x); // edIsNegative
527
+ return { isValid: useRoot1 || useRoot2, value: x };
528
+ };
529
+ // Reduce a little-endian byte string modulo the subgroup order `N` (RFC 8032's `L`); the `hash`
530
+ // param name reflects the common caller shape, not an input restriction.
531
+ const modL_LE = (hash: Uint8Array): bigint => modN(bytesToNumberLE(hash));
532
+ type ExtK = {
533
+ head: Uint8Array;
534
+ prefix: Uint8Array;
535
+ scalar: bigint;
536
+ point: Point;
537
+ pointBytes: Uint8Array;
538
+ };
539
+
540
+ // RFC8032 5.1.5. Split the 64-byte hashed seed into the clamped scalar half and nonce prefix.
541
+ const hashedToExtK = (hashed: Uint8Array): TRet<ExtK> => {
542
+ // slice creates a copy, unlike subarray
543
+ const copy = snapshotBytes(hashed);
544
+ const head = copy.slice(0, 32);
545
+ head[0] &= 248; // Clamp bits: 0b1111_1000
546
+ head[31] &= 127; // 0b0111_1111
547
+ head[31] |= 64; // 0b0100_0000
548
+ const prefix = copy.slice(32); // secret key "prefix"
549
+ // RFC words this as `[s]B`; reducing the clamped little-endian scalar modulo `N` is equivalent
550
+ // for base-point multiplication because `G` already has subgroup order `N`.
551
+ const scalar = modL_LE(head);
552
+ const point = G.multiply(scalar); // public key point
553
+ const pointBytes = point.toBytes(); // point serialized to Uint8Array
554
+ return { head, prefix, scalar, point, pointBytes } as TRet<ExtK>;
555
+ };
556
+
557
+ // RFC8032 5.1.5; getPublicKey async, sync. Hash secret key and extract point.
558
+ const getExtendedPublicKeyAsync = (secretKey: TArg<Uint8Array>): Promise<TRet<ExtK>> =>
559
+ callHashAsync('sha512Async', abytes(secretKey, LEN, 'secretKey')).then(hashedToExtK);
560
+ const getExtendedPublicKey = (secretKey: TArg<Uint8Array>): TRet<ExtK> =>
561
+ hashedToExtK(callHash('sha512', abytes(secretKey, LEN, 'secretKey')));
562
+ /**
563
+ * Creates a 32-byte Ed25519 public key from the RFC 8032 32-byte secret-key seed. Async.
564
+ * @param secretKey - 32-byte RFC 8032 secret-key seed, not a 64-byte expanded secret key.
565
+ * @returns 32-byte public key.
566
+ * @throws On wrong argument types. {@link TypeError}
567
+ * @throws On wrong argument ranges or values. {@link RangeError}
568
+ * @example
569
+ * Derive the public key bytes for a newly generated signer secret.
570
+ *
571
+ * ```ts
572
+ * import * as ed from '@noble/ed25519';
573
+ *
574
+ * const secretKey = ed.utils.randomSecretKey();
575
+ * const publicKey = await ed.getPublicKeyAsync(secretKey);
576
+ * ```
577
+ */
578
+ const getPublicKeyAsync = (secretKey: TArg<Uint8Array>): Promise<TRet<Uint8Array>> =>
579
+ getExtendedPublicKeyAsync(secretKey).then((p) => p.pointBytes as TRet<Uint8Array>);
580
+ /**
581
+ * Creates a 32-byte Ed25519 public key from the RFC 8032 32-byte secret-key seed.
582
+ * To use, set `hashes.sha512` first.
583
+ * @param secretKey - 32-byte RFC 8032 secret-key seed, not a 64-byte expanded secret key.
584
+ * @returns 32-byte public key.
585
+ * @throws If synchronous SHA-512 has not been configured in `hashes`. {@link Error}
586
+ * @throws On wrong argument types. {@link TypeError}
587
+ * @throws On wrong argument ranges or values. {@link RangeError}
588
+ * @example
589
+ * Derive the public key entirely through the synchronous API.
590
+ *
591
+ * ```ts
592
+ * import * as ed from '@noble/ed25519';
593
+ * import { sha512 } from '@noble/hashes/sha2.js';
594
+ *
595
+ * ed.hashes.sha512 = sha512;
596
+ * const secretKey = ed.utils.randomSecretKey();
597
+ * const publicKey = ed.getPublicKey(secretKey);
598
+ * ```
599
+ */
600
+ const getPublicKey = (secretKey: TArg<Uint8Array>): TRet<Uint8Array> =>
601
+ getExtendedPublicKey(secretKey).pointBytes;
602
+ type Finishable<T> = readonly [
603
+ // Shared between sync/async sign() and verify(): hash `hashable` with SHA-512, then hand the
604
+ // resulting 64-byte digest to `finish(...)`.
605
+ Uint8Array,
606
+ (hashed: Uint8Array) => T,
607
+ ];
608
+ const hashFinishAsync = async <T>(res: Finishable<T>): Promise<T> =>
609
+ res[1](await callHashAsync('sha512Async', res[0]));
610
+ const hashFinishSync = <T>(res: Finishable<T>): T => res[1](callHash('sha512', res[0]));
611
+ // Code, shared between sync & async sign
612
+ const _sign = (
613
+ e: { pointBytes: Uint8Array; scalar: bigint },
614
+ rBytes: Uint8Array,
615
+ msg: Uint8Array
616
+ ): Finishable<TRet<Uint8Array>> => {
617
+ const { pointBytes: A, scalar: s } = e;
618
+ const r = modL_LE(rBytes); // r was created outside, reduce it modulo L
619
+ // RFC 8032 5.1.6 allows r mod L = 0, and SUPERCOP ref10 accepts the resulting identity-point
620
+ // signature.
621
+ // We intentionally keep the safe multiply() rejection here so a miswired all-zero SHA-512 provider
622
+ // fails loudly instead of silently producing a degenerate signature.
623
+ const R = G.multiply(r).toBytes(); // R = [r]B
624
+ const hashable = concatBytes(R, A, msg); // dom2(F, C) || R || A || PH(M)
625
+ const finish = (hashed: Uint8Array): TRet<Uint8Array> => {
626
+ // k = SHA512(dom2(F, C) || R || A || PH(M))
627
+ const S = modN(r + modL_LE(hashed) * s); // S = (r + k * s) mod L; 0 <= s < l
628
+ return abytes(concatBytes(R, numTo32bLE(S)), 64); // 64-byte sig: 32-byte encoded R point || 32-byte LE(S)
629
+ };
630
+ return [hashable, finish];
631
+ };
632
+ /**
633
+ * Signs message using secret key. Async.
634
+ * Follows RFC8032 5.1.6.
635
+ * @param message - Message bytes to sign.
636
+ * @param secretKey - 32-byte RFC 8032 secret-key seed, not a 64-byte expanded secret key.
637
+ * @returns 64-byte Ed25519 signature.
638
+ * @throws On wrong argument types. {@link TypeError}
639
+ * @throws On wrong argument ranges or values. {@link RangeError}
640
+ * @example
641
+ * Sign an arbitrary message with a fresh Ed25519 secret key.
642
+ *
643
+ * ```ts
644
+ * import * as ed from '@noble/ed25519';
645
+ *
646
+ * const secretKey = ed.utils.randomSecretKey();
647
+ * const message = new Uint8Array([1, 2, 3]);
648
+ * const signature = await ed.signAsync(message, secretKey);
649
+ * ```
650
+ */
651
+ const signAsync = async (
652
+ message: TArg<Uint8Array>,
653
+ secretKey: TArg<Uint8Array>
654
+ ): Promise<TRet<Uint8Array>> => {
655
+ const m = snapshotBytes(message, 'message');
656
+ const e = await getExtendedPublicKeyAsync(secretKey);
657
+ // r = SHA512(dom2(F, C) || prefix || PH(M)); then generate R, k, S and the signature.
658
+ return hashFinishAsync(_sign(e, await callHashAsync('sha512Async', e.prefix, m), m));
659
+ };
660
+ /**
661
+ * Signs message using secret key. To use, set `hashes.sha512` first.
662
+ * Follows RFC8032 5.1.6.
663
+ * @param message - Message bytes to sign.
664
+ * @param secretKey - 32-byte RFC 8032 secret-key seed, not a 64-byte expanded secret key.
665
+ * @returns 64-byte Ed25519 signature.
666
+ * @throws If synchronous SHA-512 has not been configured in `hashes`. {@link Error}
667
+ * @throws On wrong argument types. {@link TypeError}
668
+ * @throws On wrong argument ranges or values. {@link RangeError}
669
+ * @example
670
+ * Use the sync API when you've wired a SHA-512 implementation yourself.
671
+ *
672
+ * ```ts
673
+ * import * as ed from '@noble/ed25519';
674
+ * import { sha512 } from '@noble/hashes/sha2.js';
675
+ *
676
+ * ed.hashes.sha512 = sha512;
677
+ * const secretKey = ed.utils.randomSecretKey();
678
+ * const signature = ed.sign(new Uint8Array([1, 2, 3]), secretKey);
679
+ * ```
680
+ */
681
+ const sign = (message: TArg<Uint8Array>, secretKey: TArg<Uint8Array>): TRet<Uint8Array> => {
682
+ const m = snapshotBytes(message, 'message');
683
+ const e = getExtendedPublicKey(secretKey);
684
+ // r = SHA512(dom2(F, C) || prefix || PH(M)); then generate R, k, S and the signature.
685
+ return hashFinishSync(_sign(e, callHash('sha512', e.prefix, m), m));
686
+ };
687
+ /**
688
+ * Verification options. zip215: true (default) follows ZIP215 spec. false would follow RFC8032.
689
+ *
690
+ * Any message with pubkey from `ED25519_TORSION_SUBGROUP` would be valid in sigs under ZIP215.
691
+ */
692
+ export type EdDSAVerifyOpts = {
693
+ /** Whether to use ZIP215 verification semantics instead of the library's stricter branch. */
694
+ zip215?: boolean;
695
+ };
696
+ // Exported defaults favor ZIP-215 interoperability semantics; callers must opt into the stricter
697
+ // branch with `{ zip215: false }`.
698
+ // Preserves the exported ZIP-215 default for `{}` / `{ zip215: undefined }`, not just omitted opts.
699
+ const getZip215 = (options: TArg<EdDSAVerifyOpts>): boolean => {
700
+ if (options === null || typeof options !== 'object')
701
+ throw new TypeError('expected valid options object');
702
+ return options.zip215 ?? true;
703
+ };
704
+ const _verify = (
705
+ sig: Uint8Array,
706
+ msg: Uint8Array,
707
+ publicKey: Uint8Array,
708
+ options: TArg<EdDSAVerifyOpts>
709
+ ): Finishable<boolean> => {
710
+ sig = abytes(sig, 64, 'signature'); // Signature hex str/Bytes, must be 64 bytes
711
+ msg = abytes(msg, undefined, 'message'); // Message hex str/Bytes
712
+ publicKey = abytes(publicKey, LEN, 'publicKey');
713
+ const zip215 = getZip215(options);
714
+ // zip215=false keeps the library's stricter branch, which still canonicalizes `R` / `A` before
715
+ // hashing and rejects small-order public keys earlier than pure RFC8032 text would require.
716
+ const r = sig.subarray(0, LEN);
717
+ const s = bytesToNumberLE(sig.subarray(LEN, 64)); // Decode second half as an integer S;
718
+ let A: Point, R: Point, SB: Point;
719
+ let hashable: Uint8Array = Uint8Array.of();
720
+ let finished = false;
721
+ try {
722
+ // zip215=true is good for consensus-critical apps. =false follows RFC8032 / NIST186-5.
723
+ // zip215=true: 0 <= y < MASK (2^256 for ed25519)
724
+ // zip215=false: 0 <= y < P (2^255-19 for ed25519)
725
+ A = Point.fromBytes(publicKey, zip215);
726
+ R = Point.fromBytes(r, zip215);
727
+ SB = G.multiply(s, false); // 0 <= s < l is done inside
728
+ // ZIP-215 accepts noncanonical / unreduced point encodings, so the challenge hash must use the
729
+ // exact signature/public-key bytes rather than canonicalized re-encodings of the decoded points.
730
+ hashable = concatBytes(r, publicKey, msg); // dom2(F, C) || R || A || PH(M)
731
+ finished = true;
732
+ } catch (error) {}
733
+ const finish = (hashed: Uint8Array): boolean => {
734
+ if (!finished) return false;
735
+ // Policy: strict mode intentionally rejects all small-order public keys, even though the raw RFC
736
+ // equation text is looser here. This matches libsodium and avoids weak / ambiguous verification
737
+ // outcomes where unusual low-order public keys can make distinct key/signature combinations verify.
738
+ if (!zip215 && A.isSmallOrder()) return false;
739
+
740
+ // k = SHA512(dom2(F, C) || R || A || PH(M))
741
+ const k = modL_LE(hashed);
742
+ const RkA = R.add(A.multiply(k, false));
743
+ // Extended group equation
744
+ // [8][S]B = [8]R + [8][k]A'
745
+ return RkA.subtract(SB).clearCofactor().is0();
746
+ };
747
+ return [hashable, finish];
748
+ };
749
+
750
+ /**
751
+ * Verifies a signature on message and public key. Async.
752
+ * The implementation is based on RFC8032 5.1.7, but default opts use ZIP-215 semantics; pass
753
+ * `{ zip215: false }` for the library's stricter branch.
754
+ * @param signature - 64-byte signature.
755
+ * @param message - Signed message bytes.
756
+ * @param publicKey - 32-byte public key.
757
+ * @param opts - Verification options. Defaults to ZIP-215 semantics. See {@link EdDSAVerifyOpts}.
758
+ * @returns `true` when the signature is valid.
759
+ * @throws On wrong argument types. {@link TypeError}
760
+ * @throws On wrong argument ranges or values. {@link RangeError}
761
+ * @example
762
+ * Verify the signature against the same message and derived public key.
763
+ *
764
+ * ```ts
765
+ * import * as ed from '@noble/ed25519';
766
+ *
767
+ * const secretKey = ed.utils.randomSecretKey();
768
+ * const message = new Uint8Array([1, 2, 3]);
769
+ * const publicKey = await ed.getPublicKeyAsync(secretKey);
770
+ * const signature = await ed.signAsync(message, secretKey);
771
+ * const isValid = await ed.verifyAsync(signature, message, publicKey);
772
+ * ```
773
+ */
774
+ const verifyAsync = async (
775
+ signature: TArg<Uint8Array>,
776
+ message: TArg<Uint8Array>,
777
+ publicKey: TArg<Uint8Array>,
778
+ opts: TArg<EdDSAVerifyOpts> = {}
779
+ ): Promise<boolean> => hashFinishAsync(_verify(signature, message, publicKey, opts));
780
+ /**
781
+ * Verifies a signature on message and public key using the synchronous hash path.
782
+ * The implementation is based on RFC8032 5.1.7, but default opts use ZIP-215 semantics; pass
783
+ * `{ zip215: false }` for the library's stricter branch.
784
+ * @param signature - 64-byte signature.
785
+ * @param message - Signed message bytes.
786
+ * @param publicKey - 32-byte public key.
787
+ * @param opts - Verification options. Defaults to ZIP-215 semantics. See {@link EdDSAVerifyOpts}.
788
+ * @returns `true` when the signature is valid.
789
+ * @throws If synchronous SHA-512 has not been configured in `hashes`. {@link Error}
790
+ * @throws On wrong argument types. {@link TypeError}
791
+ * @throws On wrong argument ranges or values. {@link RangeError}
792
+ * @example
793
+ * Verify a signature entirely through the synchronous API.
794
+ *
795
+ * ```ts
796
+ * import * as ed from '@noble/ed25519';
797
+ * import { sha512 } from '@noble/hashes/sha2.js';
798
+ *
799
+ * ed.hashes.sha512 = sha512;
800
+ * const secretKey = ed.utils.randomSecretKey();
801
+ * const message = new Uint8Array([1, 2, 3]);
802
+ * const publicKey = ed.getPublicKey(secretKey);
803
+ * const signature = ed.sign(message, secretKey);
804
+ * const isValid = ed.verify(signature, message, publicKey);
805
+ * ```
806
+ */
807
+ const verify = (
808
+ signature: TArg<Uint8Array>,
809
+ message: TArg<Uint8Array>,
810
+ publicKey: TArg<Uint8Array>,
811
+ opts: TArg<EdDSAVerifyOpts> = {}
812
+ ): boolean => hashFinishSync(_verify(signature, message, publicKey, opts));
813
+
814
+ /**
815
+ * Math, hex, byte helpers. Not in `utils` because utils share API with noble-curves.
816
+ * Exposes the same low-level field-default `mod` reducer and non-CT `invert` helper used
817
+ * internally.
818
+ * @example
819
+ * Convert bytes to a hex string with the low-level helper namespace.
820
+ *
821
+ * ```ts
822
+ * const hex = etc.bytesToHex(new Uint8Array([1, 2, 3]));
823
+ * ```
824
+ */
825
+ const etc: {
826
+ bytesToHex: (bytes: TArg<Uint8Array>) => string;
827
+ hexToBytes: (hex: string) => TRet<Uint8Array>;
828
+ concatBytes: (...arrs: TArg<Uint8Array[]>) => TRet<Uint8Array>;
829
+ mod: (a: bigint, md?: bigint) => bigint;
830
+ invert: typeof invert;
831
+ randomBytes: (len?: number) => TRet<Uint8Array>;
832
+ } = /* @__PURE__ */ freeze({
833
+ bytesToHex,
834
+ hexToBytes,
835
+ concatBytes,
836
+ mod,
837
+ invert,
838
+ randomBytes,
839
+ });
840
+ /**
841
+ * Hash implementations used by the synchronous API plus the default async WebCrypto provider.
842
+ * Both slots are configurable API surface; wrapper helpers revalidate that providers still return
843
+ * 64-byte SHA-512 digests.
844
+ * @example
845
+ * Provide a SHA-512 implementation before calling synchronous helpers.
846
+ *
847
+ * ```ts
848
+ * import * as ed from '@noble/ed25519';
849
+ * import { sha512 } from '@noble/hashes/sha2.js';
850
+ *
851
+ * ed.hashes.sha512 = sha512;
852
+ * const { publicKey } = ed.keygen();
853
+ * ```
854
+ */
855
+ const hashes = {
856
+ sha512Async: async (message: TArg<Uint8Array>): Promise<TRet<Uint8Array>> => {
857
+ const s = globalThis?.crypto?.subtle;
858
+ if (!s) throw new Error('crypto.subtle must be defined, consider polyfill');
859
+ return new Uint8Array(await s.digest('SHA-512', concatBytes(message))) as TRet<Uint8Array>;
860
+ },
861
+ sha512: undefined as undefined | ((message: TArg<Uint8Array>) => TRet<Uint8Array>),
862
+ };
863
+
864
+ // Returns the final 32-byte Ed25519 secret-key seed verbatim, generating fresh random bytes only
865
+ // when omitted.
866
+ const randomSecretKey = (seed?: TArg<Uint8Array>): TRet<Uint8Array> => {
867
+ return abytes(seed === undefined ? randomBytes() : seed, LEN, 'seed');
868
+ };
869
+
870
+ type KeysSecPub = { secretKey: Uint8Array; publicKey: Uint8Array };
871
+ /**
872
+ * Generates a secret/public keypair.
873
+ * @param seed - Optional 32-byte Ed25519 secret-key seed, returned verbatim as `secretKey`.
874
+ * @returns Keypair with `secretKey` and `publicKey`.
875
+ * @throws If synchronous SHA-512 has not been configured in `hashes`. {@link Error}
876
+ * @throws On wrong argument types. {@link TypeError}
877
+ * @throws On wrong argument ranges or values. {@link RangeError}
878
+ * @example
879
+ * Generate a new keypair through the synchronous API after wiring SHA-512.
880
+ *
881
+ * ```ts
882
+ * import * as ed from '@noble/ed25519';
883
+ * import { sha512 } from '@noble/hashes/sha2.js';
884
+ *
885
+ * ed.hashes.sha512 = sha512;
886
+ * const { secretKey, publicKey } = ed.keygen();
887
+ * ```
888
+ */
889
+ const keygen = (seed?: TArg<Uint8Array>): TRet<KeysSecPub> => {
890
+ const secretKey = randomSecretKey(seed);
891
+ const publicKey = getPublicKey(secretKey);
892
+ return { secretKey, publicKey } as TRet<KeysSecPub>;
893
+ };
894
+ /**
895
+ * Generates a secret/public keypair asynchronously.
896
+ * @param seed - Optional 32-byte Ed25519 secret-key seed, returned verbatim as `secretKey`.
897
+ * @returns Keypair with `secretKey` and `publicKey`.
898
+ * @throws On wrong argument types. {@link TypeError}
899
+ * @throws On wrong argument ranges or values. {@link RangeError}
900
+ * @example
901
+ * Generate a new keypair through the asynchronous WebCrypto-backed path.
902
+ *
903
+ * ```ts
904
+ * import * as ed from '@noble/ed25519';
905
+ *
906
+ * const { secretKey, publicKey } = await ed.keygenAsync();
907
+ * ```
908
+ */
909
+ const keygenAsync = async (seed?: TArg<Uint8Array>): Promise<TRet<KeysSecPub>> => {
910
+ const secretKey = randomSecretKey(seed);
911
+ const publicKey = await getPublicKeyAsync(secretKey);
912
+ return { secretKey, publicKey } as TRet<KeysSecPub>;
913
+ };
914
+
915
+ /**
916
+ * Ed25519-specific key utilities.
917
+ * `utils.getExtendedPublicKey*` expose secret-derived internals (`head`, `prefix`, `scalar`, and
918
+ * point objects), not just public-key bytes.
919
+ * @example
920
+ * Generate a new Ed25519 secret key and derive the matching public key.
921
+ *
922
+ * ```ts
923
+ * import * as ed from '@noble/ed25519';
924
+ *
925
+ * const secretKey = ed.utils.randomSecretKey();
926
+ * const publicKey = await ed.getPublicKeyAsync(secretKey);
927
+ * ```
928
+ */
929
+ const utils: {
930
+ getExtendedPublicKeyAsync: typeof getExtendedPublicKeyAsync;
931
+ getExtendedPublicKey: typeof getExtendedPublicKey;
932
+ randomSecretKey: typeof randomSecretKey;
933
+ } = /* @__PURE__ */ freeze({
934
+ getExtendedPublicKeyAsync,
935
+ getExtendedPublicKey,
936
+ randomSecretKey,
937
+ });
938
+
939
+ // ## Precomputes
940
+ // --------------
941
+
942
+ // Fixed W=8 window: 33 windows (ceil(256/8) + 1, NOT 32 - see wNAF loop), 128 points per window.
943
+ // Layout is grouped by window: each block stores the positive multiples `1*base .. 128*base` for
944
+ // that window, and the extra `+1` window absorbs carries from signed-digit recoding.
945
+ const precompute = () => {
946
+ const points: Point[] = [];
947
+ let p = G;
948
+ let b: Point;
949
+ for (let w = 0; w < 33; w++) {
950
+ b = p;
951
+ points.push(b);
952
+ for (let i = 1; i < 128; i++) {
953
+ b = b.add(p);
954
+ points.push(b);
955
+ } // i=1, bc we skip 0
956
+ p = b.double();
957
+ }
958
+ return points;
959
+ };
960
+ let Gpows: Point[] | undefined = undefined; // shared process-wide cache of base-point precomputes
961
+ // Branch-based negate helper used for JS/JIT mitigation symmetry, not a strict constant-time claim.
962
+ const ctneg = (cnd: boolean, p: Point): Point => {
963
+ const n = p.negate();
964
+ return cnd ? n : p;
965
+ };
966
+
967
+ /**
968
+ * Precomputes give 12x faster getPublicKey(), 10x sign(), 2x verify() by
969
+ * caching multiples of G (base point). Cache is stored in 32MB of RAM.
970
+ * Any time `G.multiply` is done, precomputes are used.
971
+ * Not used for getSharedSecret, which instead multiplies random pubkey `P.multiply`.
972
+ *
973
+ * w-ary non-adjacent form (wNAF) precomputation method is 10% slower than windowed method,
974
+ * but takes 2x less RAM. RAM reduction is possible by utilizing `.subtract`.
975
+ * Returns the real accumulator `p` plus a fake accumulator `f`; callers only care about `p`, while
976
+ * `f` exists to keep similar work in zero-digit branches as a JS/JIT side-channel mitigation.
977
+ *
978
+ * !! Precomputes can be disabled by commenting-out call of the wNAF() inside Point#multiply().
979
+ */
980
+ const wNAF = (n: bigint): { p: Point; f: Point } => {
981
+ const comp = Gpows || (Gpows = precompute());
982
+ let p = I;
983
+ let f = G; // f must be G, or could become I in the end
984
+ for (let w = 0; w < 33; w++) {
985
+ let wbits = Number(n & 255n); // extract W=8 bits.
986
+ n >>= 8n; // shift number by W=8 bits.
987
+ // We use negative indexes to reduce size of precomputed table by 2x.
988
+ // Instead of needing precomputes 0..256, we only calculate them for 0..128.
989
+ // If an index > 128 is found, we do (256-index) - where 256 is next window.
990
+ // Naive: index +127 => 127, +224 => 224
991
+ // Optimized: index +127 => 127, +224 => 256-32
992
+ if (wbits > 128) {
993
+ wbits -= 256;
994
+ n += 1n;
995
+ }
996
+ const off = w * 128; // offset of this window's block; also the fake-add index
997
+ const offP = off + Math.abs(wbits) - 1; // real-add index; both offsets always evaluated
998
+ const isOddW = w % 2 !== 0; // conditions, evaluate both; alternates fake-add sign per window
999
+ const isNeg = wbits < 0;
1000
+ if (wbits === 0) {
1001
+ // wbits == 0 means the real index would be I: can't add it. Add window offset `off` instead.
1002
+ f = f.add(ctneg(isOddW, comp[off])); // bits are 0: add garbage to fake point
1003
+ } else {
1004
+ p = p.add(ctneg(isNeg, comp[offP])); // bits are 1: add to result point
1005
+ }
1006
+ }
1007
+ if (n !== 0n) throw new Error('invalid wnaf');
1008
+ return { p, f }; // return both real and fake points for JIT/leakage-shape symmetry
1009
+ };
1010
+
1011
+ // !! Remove the export to easily use in REPL / browser console
1012
+ export {
1013
+ etc,
1014
+ getPublicKey,
1015
+ getPublicKeyAsync,
1016
+ hash,
1017
+ hashes,
1018
+ keygen,
1019
+ keygenAsync,
1020
+ Point,
1021
+ sign,
1022
+ signAsync,
1023
+ utils,
1024
+ verify,
1025
+ verifyAsync,
1026
+ };
1027
+
1028
+ // ## TypeScript Uint8Array compat types
1029
+ // -------------------------------------
1030
+ /**
1031
+ * Bytes API type helpers for old + new TypeScript.
1032
+ *
1033
+ * TS 5.6 has `Uint8Array`, while TS 5.9+ made it generic `Uint8Array<ArrayBuffer>`.
1034
+ * We can't use specific return type, because TS 5.6 will error.
1035
+ * We can't use generic return type, because most TS 5.9 software will expect specific type.
1036
+ *
1037
+ * Maps typed-array input leaves to broad forms.
1038
+ * These are compatibility adapters, not ownership guarantees.
1039
+ *
1040
+ * - `TArg` keeps byte inputs broad.
1041
+ * - `TRet` marks byte outputs for TS 5.6 and TS 5.9+ compatibility.
1042
+ */
1043
+ export type TypedArg<T> = T extends BigInt64Array
1044
+ ? BigInt64Array
1045
+ : T extends BigUint64Array
1046
+ ? BigUint64Array
1047
+ : T extends Float32Array
1048
+ ? Float32Array
1049
+ : T extends Float64Array
1050
+ ? Float64Array
1051
+ : T extends Int16Array
1052
+ ? Int16Array
1053
+ : T extends Int32Array
1054
+ ? Int32Array
1055
+ : T extends Int8Array
1056
+ ? Int8Array
1057
+ : T extends Uint16Array
1058
+ ? Uint16Array
1059
+ : T extends Uint32Array
1060
+ ? Uint32Array
1061
+ : T extends Uint8ClampedArray
1062
+ ? Uint8ClampedArray
1063
+ : T extends Uint8Array
1064
+ ? Uint8Array
1065
+ : never;
1066
+ /** Maps typed-array output leaves to narrow TS-compatible forms. */
1067
+ export type TypedRet<T> = T extends BigInt64Array
1068
+ ? ReturnType<typeof BigInt64Array.of>
1069
+ : T extends BigUint64Array
1070
+ ? ReturnType<typeof BigUint64Array.of>
1071
+ : T extends Float32Array
1072
+ ? ReturnType<typeof Float32Array.of>
1073
+ : T extends Float64Array
1074
+ ? ReturnType<typeof Float64Array.of>
1075
+ : T extends Int16Array
1076
+ ? ReturnType<typeof Int16Array.of>
1077
+ : T extends Int32Array
1078
+ ? ReturnType<typeof Int32Array.of>
1079
+ : T extends Int8Array
1080
+ ? ReturnType<typeof Int8Array.of>
1081
+ : T extends Uint16Array
1082
+ ? ReturnType<typeof Uint16Array.of>
1083
+ : T extends Uint32Array
1084
+ ? ReturnType<typeof Uint32Array.of>
1085
+ : T extends Uint8ClampedArray
1086
+ ? ReturnType<typeof Uint8ClampedArray.of>
1087
+ : T extends Uint8Array
1088
+ ? ReturnType<typeof Uint8Array.of>
1089
+ : never;
1090
+ /** Recursively adapts byte-carrying API input types. See {@link TypedArg}. */
1091
+ export type TArg<T> =
1092
+ | T
1093
+ | ([TypedArg<T>] extends [never]
1094
+ ? T extends (...args: infer A) => infer R
1095
+ ? ((...args: { [K in keyof A]: TRet<A[K]> }) => TArg<R>) & {
1096
+ [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TArg<T[K]>;
1097
+ }
1098
+ : T extends [infer A, ...infer R]
1099
+ ? [TArg<A>, ...{ [K in keyof R]: TArg<R[K]> }]
1100
+ : T extends readonly [infer A, ...infer R]
1101
+ ? readonly [TArg<A>, ...{ [K in keyof R]: TArg<R[K]> }]
1102
+ : T extends (infer A)[]
1103
+ ? TArg<A>[]
1104
+ : T extends readonly (infer A)[]
1105
+ ? readonly TArg<A>[]
1106
+ : T extends Promise<infer A>
1107
+ ? Promise<TArg<A>>
1108
+ : T extends object
1109
+ ? { [K in keyof T]: TArg<T[K]> }
1110
+ : T
1111
+ : TypedArg<T>);
1112
+ /** Recursively adapts byte-carrying API output types. See {@link TypedArg}. */
1113
+ export type TRet<T> = T extends unknown
1114
+ ? T &
1115
+ ([TypedRet<T>] extends [never]
1116
+ ? T extends (...args: infer A) => infer R
1117
+ ? ((...args: { [K in keyof A]: TArg<A[K]> }) => TRet<R>) & {
1118
+ [K in keyof T]: T[K] extends (...args: any) => any ? T[K] : TRet<T[K]>;
1119
+ }
1120
+ : T extends [infer A, ...infer R]
1121
+ ? [TRet<A>, ...{ [K in keyof R]: TRet<R[K]> }]
1122
+ : T extends readonly [infer A, ...infer R]
1123
+ ? readonly [TRet<A>, ...{ [K in keyof R]: TRet<R[K]> }]
1124
+ : T extends (infer A)[]
1125
+ ? TRet<A>[]
1126
+ : T extends readonly (infer A)[]
1127
+ ? readonly TRet<A>[]
1128
+ : T extends Promise<infer A>
1129
+ ? Promise<TRet<A>>
1130
+ : T extends object
1131
+ ? { [K in keyof T]: TRet<T[K]> }
1132
+ : T
1133
+ : TypedRet<T>)
1134
+ : never;