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