@taquito/signer 25.1.0-rc0 → 25.2.0-beta0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -0
- package/dist/lib/bls-key.js +17 -4
- package/dist/lib/derivation-tools/ecdsa.js +12 -9
- package/dist/lib/derivation-tools/ed25519.js +2 -2
- package/dist/lib/derivation-tools/index.js +24 -2
- package/dist/lib/ec-key.js +10 -12
- package/dist/lib/ed-key.js +3 -3
- package/dist/lib/in-memory-signer.js +40 -13
- package/dist/lib/mnemonic.js +112 -0
- package/dist/lib/taquito-signer.js +10 -1
- package/dist/lib/version.js +2 -2
- package/dist/taquito-signer.es6.js +702 -611
- package/dist/taquito-signer.es6.js.map +1 -1
- package/dist/taquito-signer.umd.js +833 -736
- package/dist/taquito-signer.umd.js.map +1 -1
- package/dist/types/bls-key.d.ts +1 -1
- package/dist/types/in-memory-signer.d.ts +4 -9
- package/dist/types/key-interface.d.ts +2 -2
- package/dist/types/mnemonic.d.ts +39 -0
- package/dist/types/taquito-signer.d.ts +5 -1
- package/package.json +13 -17
- package/dist/types/node_modules/@scure/base/index.d.ts +0 -555
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { openSecretBox } from '@stablelib/nacl';
|
|
2
2
|
import { b58DecodeAndCheckPrefix, PrefixV2, b58Encode, compareArrays, InvalidPublicKeyError, BLS12_381_DST, POP_DST, payloadLength, mergebuf, hex2buf, buf2hex } from '@taquito/utils';
|
|
3
|
-
import { ed25519 as ed25519$1 } from '@noble/curves/ed25519';
|
|
4
|
-
import { secp256k1 } from '@noble/curves/secp256k1';
|
|
3
|
+
import { ed25519 as ed25519$1 } from '@noble/curves/ed25519.js';
|
|
4
|
+
import { secp256k1 } from '@noble/curves/secp256k1.js';
|
|
5
5
|
import { p256 } from '@noble/curves/nist.js';
|
|
6
6
|
import { ParameterValidationError, UnsupportedActionError, InvalidHexStringError, InvalidDerivationPathError, InvalidKeyError, ProhibitedActionError } from '@taquito/core';
|
|
7
|
-
import { p256 as p256$1 } from '@noble/curves/nist';
|
|
8
7
|
import BN from 'bn.js';
|
|
9
|
-
import { bls12_381 } from '@noble/curves/bls12-381';
|
|
8
|
+
import { bls12_381 } from '@noble/curves/bls12-381.js';
|
|
10
9
|
|
|
11
10
|
/******************************************************************************
|
|
12
11
|
Copyright (c) Microsoft Corporation.
|
|
@@ -53,7 +52,7 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
53
52
|
* isBytes(new Uint8Array([1, 2, 3]));
|
|
54
53
|
* ```
|
|
55
54
|
*/
|
|
56
|
-
function isBytes$
|
|
55
|
+
function isBytes$1(a) {
|
|
57
56
|
// Plain `instanceof Uint8Array` is too strict for some Buffer / proxy / cross-realm cases.
|
|
58
57
|
// The fallback still requires a real ArrayBuffer view, so plain
|
|
59
58
|
// JSON-deserialized `{ constructor: ... }` spoofing is rejected, and
|
|
@@ -64,10 +63,14 @@ function isBytes$2(a) {
|
|
|
64
63
|
'BYTES_PER_ELEMENT' in a &&
|
|
65
64
|
a.BYTES_PER_ELEMENT === 1));
|
|
66
65
|
}
|
|
66
|
+
// Shared error-message prefix builder. Only called on throw paths, so assert
|
|
67
|
+
// success paths never pay for the string concatenation.
|
|
68
|
+
const atitle$2 = (title) => (title ? `"${title}" ` : '');
|
|
67
69
|
/**
|
|
68
70
|
* Asserts something is a non-negative integer.
|
|
69
71
|
* @param n - number to validate
|
|
70
72
|
* @param title - label included in thrown errors
|
|
73
|
+
* @returns The validated number.
|
|
71
74
|
* @throws On wrong argument types. {@link TypeError}
|
|
72
75
|
* @throws On wrong argument ranges or values. {@link RangeError}
|
|
73
76
|
* @example
|
|
@@ -76,15 +79,12 @@ function isBytes$2(a) {
|
|
|
76
79
|
* anumber(32, 'length');
|
|
77
80
|
* ```
|
|
78
81
|
*/
|
|
79
|
-
function anumber$
|
|
80
|
-
if (typeof n !== 'number')
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const prefix = title && `"${title}" `;
|
|
86
|
-
throw new RangeError(`${prefix}expected integer >= 0, got ${n}`);
|
|
87
|
-
}
|
|
82
|
+
function anumber$1(n, title = '') {
|
|
83
|
+
if (typeof n !== 'number')
|
|
84
|
+
throw new TypeError(atitle$2(title) + 'expected number, got ' + typeof n);
|
|
85
|
+
if (!Number.isSafeInteger(n) || n < 0)
|
|
86
|
+
throw new RangeError(atitle$2(title) + 'expected integer >= 0, got ' + n);
|
|
87
|
+
return n;
|
|
88
88
|
}
|
|
89
89
|
/**
|
|
90
90
|
* Asserts something is Uint8Array.
|
|
@@ -101,19 +101,37 @@ function anumber$2(n, title = '') {
|
|
|
101
101
|
* ```
|
|
102
102
|
*/
|
|
103
103
|
function abytes$1(value, length, title = '') {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
104
|
+
// Success path first: this runs at the start of every update() / digestInto(), and the
|
|
105
|
+
// common `abytes(data)` form must not pay for length handling it does not use.
|
|
106
|
+
if (isBytes$1(value) && (length === undefined || value.length === length))
|
|
107
|
+
return value;
|
|
108
|
+
// Error path: recompute freely to build the exact message.
|
|
109
|
+
if (length !== undefined)
|
|
110
|
+
anumber$1(length, 'length');
|
|
111
|
+
const bytes = isBytes$1(value);
|
|
112
|
+
const ofLen = length !== undefined ? ` of length ${length}` : '';
|
|
113
|
+
const got = bytes ? `length=${value.length}` : `type=${typeof value}`;
|
|
114
|
+
const message = atitle$2(title) + 'expected Uint8Array' + ofLen + ', got ' + got;
|
|
115
|
+
if (!bytes)
|
|
116
|
+
throw new TypeError(message);
|
|
117
|
+
throw new RangeError(message);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Copies bytes into a fresh Uint8Array.
|
|
121
|
+
* Buffer-style slices can alias the same backing store, so callers that need ownership should copy.
|
|
122
|
+
* @param bytes - source bytes to clone
|
|
123
|
+
* @returns Freshly allocated copy of `bytes`.
|
|
124
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
125
|
+
* @example
|
|
126
|
+
* Clone a byte array before mutating it.
|
|
127
|
+
* ```ts
|
|
128
|
+
* const copy = copyBytes(new Uint8Array([1, 2, 3]));
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
function copyBytes(bytes) {
|
|
132
|
+
// `Uint8Array.from(...)` would also accept arrays / other typed arrays. Keep this helper strict
|
|
133
|
+
// because callers use it at byte-validation boundaries before mutating the detached copy.
|
|
134
|
+
return Uint8Array.from(abytes$1(bytes));
|
|
117
135
|
}
|
|
118
136
|
/**
|
|
119
137
|
* Asserts something is a wrapped hash constructor.
|
|
@@ -131,16 +149,28 @@ function abytes$1(value, length, title = '') {
|
|
|
131
149
|
*/
|
|
132
150
|
function ahash$1(h) {
|
|
133
151
|
if (typeof h !== 'function' || typeof h.create !== 'function')
|
|
134
|
-
throw new TypeError('
|
|
135
|
-
anumber$
|
|
136
|
-
anumber$
|
|
152
|
+
throw new TypeError('expected hash wrapped by utils.createHasher');
|
|
153
|
+
anumber$1(h.outputLen);
|
|
154
|
+
anumber$1(h.blockLen);
|
|
137
155
|
// HMAC and KDF callers treat these as real byte lengths; allowing zero lets fake wrappers pass
|
|
138
156
|
// validation and can produce empty outputs instead of failing fast.
|
|
139
|
-
if (h.outputLen < 1)
|
|
140
|
-
throw new Error('
|
|
141
|
-
if (h.blockLen < 1)
|
|
142
|
-
throw new Error('"blockLen" must be >= 1');
|
|
157
|
+
if (h.outputLen < 1 || h.blockLen < 1)
|
|
158
|
+
throw new Error('hash blockLen / outputLen must be >= 1');
|
|
143
159
|
}
|
|
160
|
+
const aobject$3 = (value, label) => {
|
|
161
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value))
|
|
162
|
+
throw new TypeError((label === 'object' ? '' : `"${label}" `) + 'expected object, got type=' + typeof value);
|
|
163
|
+
};
|
|
164
|
+
const aopts$1 = (value, label) => {
|
|
165
|
+
aobject$3(value, label);
|
|
166
|
+
const proto = Object.getPrototypeOf(value);
|
|
167
|
+
if (proto !== Object.prototype && proto !== null)
|
|
168
|
+
throw new TypeError(`"${label}" expected plain object`);
|
|
169
|
+
// Object.assign() treats an own "__proto__" source key as a write to the target's legacy
|
|
170
|
+
// prototype setter. Reject it before merging so inherited option values cannot be injected.
|
|
171
|
+
if (Object.hasOwn(value, '__proto__'))
|
|
172
|
+
throw new TypeError(`"${label}.__proto__" is not allowed`);
|
|
173
|
+
};
|
|
144
174
|
/**
|
|
145
175
|
* Asserts a hash instance has not been destroyed or finished.
|
|
146
176
|
* @param instance - hash instance to validate
|
|
@@ -156,10 +186,12 @@ function ahash$1(h) {
|
|
|
156
186
|
* ```
|
|
157
187
|
*/
|
|
158
188
|
function aexists$1(instance, checkFinished = true) {
|
|
189
|
+
// Runs on every update()/digestInto(); the flags are library-owned booleans, so only their
|
|
190
|
+
// truthiness is checked - re-validating their type per call was pure hot-path overhead.
|
|
159
191
|
if (instance.destroyed)
|
|
160
|
-
throw new Error('
|
|
192
|
+
throw new Error('hash was destroyed');
|
|
161
193
|
if (checkFinished && instance.finished)
|
|
162
|
-
throw new Error('
|
|
194
|
+
throw new Error('digest() was already called');
|
|
163
195
|
}
|
|
164
196
|
/**
|
|
165
197
|
* Asserts output is a sufficiently-sized byte array.
|
|
@@ -178,10 +210,12 @@ function aexists$1(instance, checkFinished = true) {
|
|
|
178
210
|
* ```
|
|
179
211
|
*/
|
|
180
212
|
function aoutput$1(out, instance) {
|
|
181
|
-
abytes$1(out, undefined, '
|
|
213
|
+
abytes$1(out, undefined, 'output');
|
|
214
|
+
// `outputLen` is a library-owned readonly number; the negated comparison keeps failing fast
|
|
215
|
+
// when it is missing/NaN (comparisons with undefined/NaN are false) without an anumber() call.
|
|
182
216
|
const min = instance.outputLen;
|
|
183
|
-
if (out.length
|
|
184
|
-
throw new RangeError('"
|
|
217
|
+
if (!(out.length >= min)) {
|
|
218
|
+
throw new RangeError('"output" expected length >= ' + min);
|
|
185
219
|
}
|
|
186
220
|
}
|
|
187
221
|
/**
|
|
@@ -317,7 +351,15 @@ const swap32IfBE$1 = isLE$1
|
|
|
317
351
|
function utf8ToBytes(str) {
|
|
318
352
|
if (typeof str !== 'string')
|
|
319
353
|
throw new TypeError('string expected');
|
|
320
|
-
|
|
354
|
+
const encoded = new TextEncoder().encode(str);
|
|
355
|
+
try {
|
|
356
|
+
// Copy into the current realm for Firefox extension contexts. Callers that own the returned
|
|
357
|
+
// buffer can then wipe it independently of TextEncoder's temporary result.
|
|
358
|
+
return new Uint8Array(encoded); // https://bugzil.la/1681809
|
|
359
|
+
}
|
|
360
|
+
finally {
|
|
361
|
+
clean$1(encoded);
|
|
362
|
+
}
|
|
321
363
|
}
|
|
322
364
|
/**
|
|
323
365
|
* Helper for KDFs: consumes Uint8Array or string.
|
|
@@ -341,7 +383,8 @@ function kdfInputToBytes(data, errorTitle = '') {
|
|
|
341
383
|
* Merges default options and passed options.
|
|
342
384
|
* @param defaults - base option object
|
|
343
385
|
* @param opts - user overrides
|
|
344
|
-
* @
|
|
386
|
+
* @param title - label included in thrown override errors
|
|
387
|
+
* @returns Fresh merged option object with a null prototype.
|
|
345
388
|
* @throws On wrong argument types. {@link TypeError}
|
|
346
389
|
* @example
|
|
347
390
|
* Merge user overrides onto default options.
|
|
@@ -349,10 +392,13 @@ function kdfInputToBytes(data, errorTitle = '') {
|
|
|
349
392
|
* checkOpts({ dkLen: 32 }, { asyncTick: 10 });
|
|
350
393
|
* ```
|
|
351
394
|
*/
|
|
352
|
-
function checkOpts$1(defaults, opts) {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
395
|
+
function checkOpts$1(defaults, opts, title = 'opts') {
|
|
396
|
+
aopts$1(defaults, 'defaults');
|
|
397
|
+
if (opts !== undefined)
|
|
398
|
+
aopts$1(opts, title);
|
|
399
|
+
// Callers read optional fields directly, so omitted values must not fall through to ambient
|
|
400
|
+
// Object.prototype pollution (for example a forged `dkLen` changing SHAKE's default output).
|
|
401
|
+
const merged = Object.assign(Object.create(null), defaults, opts);
|
|
356
402
|
return merged;
|
|
357
403
|
}
|
|
358
404
|
/**
|
|
@@ -363,6 +409,7 @@ function checkOpts$1(defaults, opts) {
|
|
|
363
409
|
* Wrapper construction eagerly calls `hashCons(undefined)` once to read
|
|
364
410
|
* `outputLen` / `blockLen`, so constructor side effects happen at module
|
|
365
411
|
* init time.
|
|
412
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
366
413
|
* @example
|
|
367
414
|
* Wrap a stateful hash constructor into a callable helper.
|
|
368
415
|
* ```ts
|
|
@@ -373,6 +420,9 @@ function checkOpts$1(defaults, opts) {
|
|
|
373
420
|
* ```
|
|
374
421
|
*/
|
|
375
422
|
function createHasher$1(hashCons, info = {}) {
|
|
423
|
+
if (typeof hashCons !== 'function')
|
|
424
|
+
throw new TypeError('"hashCons" expected function, got type=' + typeof hashCons);
|
|
425
|
+
info = checkOpts$1({}, info, 'info');
|
|
376
426
|
const hashC = (msg, opts) => hashCons(opts)
|
|
377
427
|
.update(msg)
|
|
378
428
|
.digest();
|
|
@@ -384,6 +434,37 @@ function createHasher$1(hashCons, info = {}) {
|
|
|
384
434
|
Object.assign(hashC, info);
|
|
385
435
|
return Object.freeze(hashC);
|
|
386
436
|
}
|
|
437
|
+
/**
|
|
438
|
+
* Cryptographically secure PRNG backed by `crypto.getRandomValues`.
|
|
439
|
+
* @param bytesLength - number of random bytes to generate
|
|
440
|
+
* @returns Random bytes.
|
|
441
|
+
* The platform `getRandomValues()` implementation still defines any
|
|
442
|
+
* single-call length cap, and this helper rejects oversize requests
|
|
443
|
+
* with a stable library `RangeError` instead of host-specific errors.
|
|
444
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
445
|
+
* @throws On wrong argument ranges or values. {@link RangeError}
|
|
446
|
+
* @throws If the current runtime does not provide `crypto.getRandomValues`. {@link Error}
|
|
447
|
+
* @example
|
|
448
|
+
* Generate a fresh random key or nonce.
|
|
449
|
+
* ```ts
|
|
450
|
+
* const key = randomBytes(16);
|
|
451
|
+
* ```
|
|
452
|
+
*/
|
|
453
|
+
function randomBytes$2(bytesLength = 32) {
|
|
454
|
+
// Match the repo's other length-taking helpers instead of relying on Uint8Array coercion.
|
|
455
|
+
anumber$1(bytesLength, 'bytesLength');
|
|
456
|
+
const cr = typeof globalThis === 'object' ? globalThis.crypto : null;
|
|
457
|
+
if (typeof cr?.getRandomValues !== 'function')
|
|
458
|
+
throw new Error('crypto.getRandomValues must be defined');
|
|
459
|
+
// Web Cryptography API Level 2 §10.1.1:
|
|
460
|
+
// if `byteLength > 65536`, throw `QuotaExceededError`.
|
|
461
|
+
// Keep the guard explicit so callers can see the quota in code
|
|
462
|
+
// instead of discovering it by reading the spec or host errors.
|
|
463
|
+
// This wrapper surfaces the same quota as a stable library RangeError.
|
|
464
|
+
if (bytesLength > 65536)
|
|
465
|
+
throw new RangeError(`"bytesLength" expected <= 65536, got ${bytesLength}`);
|
|
466
|
+
return cr.getRandomValues(new Uint8Array(bytesLength));
|
|
467
|
+
}
|
|
387
468
|
/**
|
|
388
469
|
* Creates OID metadata for NIST hashes with prefix `06 09 60 86 48 01 65 03 04 02`.
|
|
389
470
|
* @param suffix - final OID byte for the selected hash.
|
|
@@ -406,6 +487,9 @@ const oidNist$1 = (suffix) => ({
|
|
|
406
487
|
* Internal helpers for blake hash.
|
|
407
488
|
* @module
|
|
408
489
|
*/
|
|
490
|
+
// Unrealized speed-up: a file-local copy of rotr measured ~1-2% faster blake2s/blake256/blake3
|
|
491
|
+
// on Node 24 (V8 does not inline it into G1s/G2s across the module boundary). Reused from
|
|
492
|
+
// utils for deduplication.
|
|
409
493
|
/**
|
|
410
494
|
* Internal blake permutation table.
|
|
411
495
|
* Rows `0..9` serve BLAKE2s, rows `0..11` serve BLAKE2b with `10..11 = 0..1`, and Blake1 also
|
|
@@ -433,6 +517,79 @@ const BSIGMA = /* @__PURE__ */ Uint8Array.from([
|
|
|
433
517
|
2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9,
|
|
434
518
|
]);
|
|
435
519
|
|
|
520
|
+
const U32_MASK64$1 = /* @__PURE__ */ (() => BigInt(2 ** 32 - 1))();
|
|
521
|
+
const _32n$1 = /* @__PURE__ */ BigInt(32);
|
|
522
|
+
// Split bigint into two 32-bit halves. With `le=true`, returned fields become `{ h: low, l: high
|
|
523
|
+
// }` to match little-endian word order rather than the property names.
|
|
524
|
+
function fromBig$1(n, le = false) {
|
|
525
|
+
if (le)
|
|
526
|
+
return { h: Number(n & U32_MASK64$1), l: Number((n >> _32n$1) & U32_MASK64$1) };
|
|
527
|
+
return { h: Number((n >> _32n$1) & U32_MASK64$1) | 0, l: Number(n & U32_MASK64$1) | 0 };
|
|
528
|
+
}
|
|
529
|
+
// Split bigint list into `[highWords, lowWords]` when `le=false`; with `le=true`, the first array
|
|
530
|
+
// holds the low halves because `fromBig(...)` swaps the semantic meaning of `h` and `l`.
|
|
531
|
+
function split$1(lst, le = false) {
|
|
532
|
+
const len = lst.length;
|
|
533
|
+
let Ah = new Uint32Array(len);
|
|
534
|
+
let Al = new Uint32Array(len);
|
|
535
|
+
for (let i = 0; i < len; i++) {
|
|
536
|
+
const { h, l } = fromBig$1(lst[i], le);
|
|
537
|
+
[Ah[i], Al[i]] = [h, l];
|
|
538
|
+
}
|
|
539
|
+
return [Ah, Al];
|
|
540
|
+
}
|
|
541
|
+
// Split a JS number into u32 halves without a BigInt allocation. Exact only for integers
|
|
542
|
+
// `0 <= n < 2**53`; callers use it on byte / bit counters, which JS length math caps far below
|
|
543
|
+
// that (an ArrayBuffer cannot exceed 2**53 - 1 bytes).
|
|
544
|
+
const fromNumH = (n) => (n / 2 ** 32) | 0;
|
|
545
|
+
const fromNumL = (n) => n >>> 0;
|
|
546
|
+
// Drop-in replacement for `view.setBigUint64(byteOffset, BigInt(n), isLE)` without the per-call
|
|
547
|
+
// BigInt allocation. Same `n < 2**53` precondition as `fromNumH`/`fromNumL`.
|
|
548
|
+
function setU64FromNum(view, byteOffset, n, isLE) {
|
|
549
|
+
const h = fromNumH(n);
|
|
550
|
+
const l = fromNumL(n);
|
|
551
|
+
view.setUint32(byteOffset, isLE ? l : h, isLE);
|
|
552
|
+
view.setUint32(byteOffset + 4, isLE ? h : l, isLE);
|
|
553
|
+
}
|
|
554
|
+
// High 32-bit half of a 64-bit logical right shift for `s` in `0..31`.
|
|
555
|
+
const shrSH = (h, _l, s) => h >>> s;
|
|
556
|
+
// Low 32-bit half of a 64-bit logical right shift, valid for `s` in `1..31`.
|
|
557
|
+
const shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
|
|
558
|
+
// High 32-bit half of a 64-bit right rotate, valid for `s` in `1..31`.
|
|
559
|
+
const rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s));
|
|
560
|
+
// Low 32-bit half of a 64-bit right rotate, valid for `s` in `1..31`.
|
|
561
|
+
const rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
|
|
562
|
+
// High 32-bit half of a 64-bit right rotate, valid for `s` in `33..63`; `32` uses `rotr32*`.
|
|
563
|
+
const rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32));
|
|
564
|
+
// Low 32-bit half of a 64-bit right rotate, valid for `s` in `33..63`; `32` uses `rotr32*`.
|
|
565
|
+
const rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s));
|
|
566
|
+
// High 32-bit half of a 64-bit right rotate for `s === 32`; this is just the swapped low half.
|
|
567
|
+
const rotr32H = (_h, l) => l;
|
|
568
|
+
// Low 32-bit half of a 64-bit right rotate for `s === 32`; this is just the swapped high half.
|
|
569
|
+
const rotr32L = (h, _l) => h;
|
|
570
|
+
// 64-bit left rotates (rotl*) are not defined here: sha3.ts, their only consumer, keeps
|
|
571
|
+
// local copies so V8 inlines them into keccakP.
|
|
572
|
+
// Add two split 64-bit words and return the split `{ h, l }` sum.
|
|
573
|
+
// JS uses 32-bit signed integers for bitwise operations, so we cannot simply shift the carry out
|
|
574
|
+
// of the low sum and instead use division.
|
|
575
|
+
function add(Ah, Al, Bh, Bl) {
|
|
576
|
+
const l = (Al >>> 0) + (Bl >>> 0);
|
|
577
|
+
return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };
|
|
578
|
+
}
|
|
579
|
+
// Addition with more than 2 elements
|
|
580
|
+
// Unmasked low-word accumulator for 3-way addition; pass the raw result into `add3H(...)`.
|
|
581
|
+
const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
|
|
582
|
+
// High-word finalize step for 3-way addition; `low` must be the untruncated output of `add3L(...)`.
|
|
583
|
+
const add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;
|
|
584
|
+
// Unmasked low-word accumulator for 4-way addition; pass the raw result into `add4H(...)`.
|
|
585
|
+
const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
|
|
586
|
+
// High-word finalize step for 4-way addition; `low` must be the untruncated output of `add4L(...)`.
|
|
587
|
+
const add4H = (low, Ah, Bh, Ch, Dh) => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;
|
|
588
|
+
// Unmasked low-word accumulator for 5-way addition; pass the raw result into `add5H(...)`.
|
|
589
|
+
const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
|
|
590
|
+
// High-word finalize step for 5-way addition; `low` must be the untruncated output of `add5L(...)`.
|
|
591
|
+
const add5H = (low, Ah, Bh, Ch, Dh, Eh) => (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;
|
|
592
|
+
|
|
436
593
|
/**
|
|
437
594
|
* Internal Merkle-Damgard hash utils.
|
|
438
595
|
* @module
|
|
@@ -515,6 +672,7 @@ class HashMD {
|
|
|
515
672
|
abytes$1(data);
|
|
516
673
|
const { view, buffer, blockLen } = this;
|
|
517
674
|
const len = data.length;
|
|
675
|
+
let processed = false;
|
|
518
676
|
for (let pos = 0; pos < len;) {
|
|
519
677
|
const take = Math.min(blockLen - this.pos, len - pos);
|
|
520
678
|
// Fast path only when there is no buffered partial block: `take === blockLen` implies
|
|
@@ -523,18 +681,25 @@ class HashMD {
|
|
|
523
681
|
const dataView = createView(data);
|
|
524
682
|
for (; blockLen <= len - pos; pos += blockLen)
|
|
525
683
|
this.process(dataView, pos);
|
|
684
|
+
processed = true;
|
|
526
685
|
continue;
|
|
527
686
|
}
|
|
528
|
-
|
|
687
|
+
// When the whole input is buffered in one go (common for short messages), passing `data`
|
|
688
|
+
// directly avoids allocating a subarray view.
|
|
689
|
+
buffer.set(pos === 0 && take === len ? data : data.subarray(pos, pos + take), this.pos);
|
|
529
690
|
this.pos += take;
|
|
530
691
|
pos += take;
|
|
531
692
|
if (this.pos === blockLen) {
|
|
532
693
|
this.process(view, 0);
|
|
533
694
|
this.pos = 0;
|
|
695
|
+
processed = true;
|
|
534
696
|
}
|
|
535
697
|
}
|
|
536
698
|
this.length += data.length;
|
|
537
|
-
|
|
699
|
+
// Shared schedule buffers only pick up input-derived words inside process(); if everything
|
|
700
|
+
// was buffered without processing, there is nothing to zero.
|
|
701
|
+
if (processed)
|
|
702
|
+
this.roundClean();
|
|
538
703
|
return this;
|
|
539
704
|
}
|
|
540
705
|
digestInto(out) {
|
|
@@ -546,32 +711,33 @@ class HashMD {
|
|
|
546
711
|
// was previously not allocated here. But it won't change performance.
|
|
547
712
|
const { buffer, view, blockLen, isLE } = this;
|
|
548
713
|
let { pos } = this;
|
|
549
|
-
// append the bit '1' to the message
|
|
714
|
+
// append the bit '1' to the message, then zero-pad the rest of the block
|
|
550
715
|
buffer[pos++] = 0b10000000;
|
|
551
|
-
|
|
716
|
+
buffer.fill(0, pos);
|
|
552
717
|
// we have less than padOffset left in buffer, so we cannot put length in
|
|
553
718
|
// current block, need process it and pad again
|
|
554
719
|
if (this.padOffset > blockLen - pos) {
|
|
555
720
|
this.process(view, 0);
|
|
556
|
-
|
|
721
|
+
buffer.fill(0);
|
|
557
722
|
}
|
|
558
|
-
// Pad until full block byte with zeros
|
|
559
|
-
for (let i = pos; i < blockLen; i++)
|
|
560
|
-
buffer[i] = 0;
|
|
561
723
|
// `padOffset` reserves the whole length field. For SHA-384/512 the high 64 bits stay zero from
|
|
562
724
|
// the padding fill above, and JS will overflow before user input can make that half non-zero.
|
|
563
|
-
// So we only need to write the low 64 bits here
|
|
564
|
-
|
|
725
|
+
// So we only need to write the low 64 bits here (`length * 8` only scales the exponent of an
|
|
726
|
+
// integer below 2**53, so the split inside the helper stays exact).
|
|
727
|
+
setU64FromNum(view, blockLen - 8, this.length * 8, isLE);
|
|
565
728
|
this.process(view, 0);
|
|
566
|
-
|
|
729
|
+
// The final block above is processed outside update(), so the shared message-schedule
|
|
730
|
+
// buffers (e.g. SHA256_W) would otherwise retain input-derived words after digest().
|
|
731
|
+
this.roundClean();
|
|
732
|
+
// digest() passes our own `buffer` as `out`; reuse its cached view instead of allocating one.
|
|
733
|
+
const oview = out === buffer ? view : createView(out);
|
|
567
734
|
const len = this.outputLen;
|
|
568
735
|
// NOTE: we do division by 4 later, which must be fused in single op with modulo by JIT
|
|
569
|
-
if (len % 4)
|
|
570
|
-
throw new Error('_sha2: outputLen must be aligned to 32bit');
|
|
571
736
|
const outLen = len / 4;
|
|
572
737
|
const state = this.get();
|
|
573
|
-
|
|
574
|
-
|
|
738
|
+
// Subclass-misconfiguration invariant: outputLen must be 32-bit aligned and fit the state.
|
|
739
|
+
if (len % 4 || outLen > state.length)
|
|
740
|
+
throw new Error('invalid outputLen');
|
|
575
741
|
for (let i = 0; i < outLen; i++)
|
|
576
742
|
oview.setUint32(4 * i, state[i], isLE);
|
|
577
743
|
}
|
|
@@ -584,18 +750,16 @@ class HashMD {
|
|
|
584
750
|
this.destroy();
|
|
585
751
|
return res;
|
|
586
752
|
}
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
to.set(...this.get());
|
|
590
|
-
const { blockLen, buffer, length, finished, destroyed, pos } = this;
|
|
753
|
+
_cloneIntoMeta(to) {
|
|
754
|
+
const { buffer, length, finished, destroyed, pos } = this;
|
|
591
755
|
to.destroyed = destroyed;
|
|
592
756
|
to.finished = finished;
|
|
593
757
|
to.length = length;
|
|
594
758
|
to.pos = pos;
|
|
595
759
|
// Only partial-block bytes need copying: when `length % blockLen === 0`, `pos === 0` and
|
|
596
760
|
// later `update()` / `digestInto()` overwrite `to.buffer` from the start before reading it.
|
|
597
|
-
if (
|
|
598
|
-
to.buffer.set(buffer);
|
|
761
|
+
if (pos)
|
|
762
|
+
to.buffer.set(buffer); // Avoid a hot modulo guard.
|
|
599
763
|
return to;
|
|
600
764
|
}
|
|
601
765
|
clone() {
|
|
@@ -621,64 +785,6 @@ const SHA512_IV = /* @__PURE__ */ Uint32Array.from([
|
|
|
621
785
|
0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179,
|
|
622
786
|
]);
|
|
623
787
|
|
|
624
|
-
const U32_MASK64$1 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
|
625
|
-
const _32n$1 = /* @__PURE__ */ BigInt(32);
|
|
626
|
-
// Split bigint into two 32-bit halves. With `le=true`, returned fields become `{ h: low, l: high
|
|
627
|
-
// }` to match little-endian word order rather than the property names.
|
|
628
|
-
function fromBig$1(n, le = false) {
|
|
629
|
-
if (le)
|
|
630
|
-
return { h: Number(n & U32_MASK64$1), l: Number((n >> _32n$1) & U32_MASK64$1) };
|
|
631
|
-
return { h: Number((n >> _32n$1) & U32_MASK64$1) | 0, l: Number(n & U32_MASK64$1) | 0 };
|
|
632
|
-
}
|
|
633
|
-
// Split bigint list into `[highWords, lowWords]` when `le=false`; with `le=true`, the first array
|
|
634
|
-
// holds the low halves because `fromBig(...)` swaps the semantic meaning of `h` and `l`.
|
|
635
|
-
function split$1(lst, le = false) {
|
|
636
|
-
const len = lst.length;
|
|
637
|
-
let Ah = new Uint32Array(len);
|
|
638
|
-
let Al = new Uint32Array(len);
|
|
639
|
-
for (let i = 0; i < len; i++) {
|
|
640
|
-
const { h, l } = fromBig$1(lst[i], le);
|
|
641
|
-
[Ah[i], Al[i]] = [h, l];
|
|
642
|
-
}
|
|
643
|
-
return [Ah, Al];
|
|
644
|
-
}
|
|
645
|
-
// High 32-bit half of a 64-bit logical right shift for `s` in `0..31`.
|
|
646
|
-
const shrSH = (h, _l, s) => h >>> s;
|
|
647
|
-
// Low 32-bit half of a 64-bit logical right shift, valid for `s` in `1..31`.
|
|
648
|
-
const shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
|
|
649
|
-
// High 32-bit half of a 64-bit right rotate, valid for `s` in `1..31`.
|
|
650
|
-
const rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s));
|
|
651
|
-
// Low 32-bit half of a 64-bit right rotate, valid for `s` in `1..31`.
|
|
652
|
-
const rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
|
|
653
|
-
// High 32-bit half of a 64-bit right rotate, valid for `s` in `33..63`; `32` uses `rotr32*`.
|
|
654
|
-
const rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32));
|
|
655
|
-
// Low 32-bit half of a 64-bit right rotate, valid for `s` in `33..63`; `32` uses `rotr32*`.
|
|
656
|
-
const rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s));
|
|
657
|
-
// High 32-bit half of a 64-bit right rotate for `s === 32`; this is just the swapped low half.
|
|
658
|
-
const rotr32H = (_h, l) => l;
|
|
659
|
-
// Low 32-bit half of a 64-bit right rotate for `s === 32`; this is just the swapped high half.
|
|
660
|
-
const rotr32L = (h, _l) => h;
|
|
661
|
-
// Add two split 64-bit words and return the split `{ h, l }` sum.
|
|
662
|
-
// JS uses 32-bit signed integers for bitwise operations, so we cannot simply shift the carry out
|
|
663
|
-
// of the low sum and instead use division.
|
|
664
|
-
function add(Ah, Al, Bh, Bl) {
|
|
665
|
-
const l = (Al >>> 0) + (Bl >>> 0);
|
|
666
|
-
return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };
|
|
667
|
-
}
|
|
668
|
-
// Addition with more than 2 elements
|
|
669
|
-
// Unmasked low-word accumulator for 3-way addition; pass the raw result into `add3H(...)`.
|
|
670
|
-
const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
|
|
671
|
-
// High-word finalize step for 3-way addition; `low` must be the untruncated output of `add3L(...)`.
|
|
672
|
-
const add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;
|
|
673
|
-
// Unmasked low-word accumulator for 4-way addition; pass the raw result into `add4H(...)`.
|
|
674
|
-
const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
|
|
675
|
-
// High-word finalize step for 4-way addition; `low` must be the untruncated output of `add4L(...)`.
|
|
676
|
-
const add4H = (low, Ah, Bh, Ch, Dh) => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;
|
|
677
|
-
// Unmasked low-word accumulator for 5-way addition; pass the raw result into `add5H(...)`.
|
|
678
|
-
const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
|
|
679
|
-
// High-word finalize step for 5-way addition; `low` must be the untruncated output of `add5L(...)`.
|
|
680
|
-
const add5H = (low, Ah, Bh, Ch, Dh, Eh) => (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;
|
|
681
|
-
|
|
682
788
|
/**
|
|
683
789
|
* blake2b (64-bit) & blake2s (8 to 32-bit) hash functions.
|
|
684
790
|
* b could have been faster, but there is no fast u64 in js, so s is 1.5x faster.
|
|
@@ -701,21 +807,28 @@ function G1b(a, b, c, d, msg, x) {
|
|
|
701
807
|
let Cl = BBUF[2 * c], Ch = BBUF[2 * c + 1]; // prettier-ignore
|
|
702
808
|
let Dl = BBUF[2 * d], Dh = BBUF[2 * d + 1]; // prettier-ignore
|
|
703
809
|
// v[a] = (v[a] + v[b] + x) | 0;
|
|
704
|
-
|
|
810
|
+
const ll = add3L(Al, Bl, Xl);
|
|
705
811
|
Ah = add3H(ll, Ah, Bh, Xh);
|
|
706
812
|
Al = ll | 0;
|
|
707
813
|
// v[d] = rotr(v[d] ^ v[a], 32)
|
|
708
|
-
|
|
709
|
-
|
|
814
|
+
let xh = Dh ^ Ah, xl = Dl ^ Al; // prettier-ignore
|
|
815
|
+
Dh = rotr32H(xh, xl);
|
|
816
|
+
Dl = rotr32L(xh);
|
|
710
817
|
// v[c] = (v[c] + v[d]) | 0;
|
|
711
818
|
({ h: Ch, l: Cl } = add(Ch, Cl, Dh, Dl));
|
|
712
819
|
// v[b] = rotr(v[b] ^ v[c], 24)
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
820
|
+
xh = Bh ^ Ch;
|
|
821
|
+
xl = Bl ^ Cl;
|
|
822
|
+
Bh = rotrSH(xh, xl, 24);
|
|
823
|
+
Bl = rotrSL(xh, xl, 24);
|
|
824
|
+
BBUF[2 * a] = Al;
|
|
825
|
+
BBUF[2 * a + 1] = Ah;
|
|
826
|
+
BBUF[2 * b] = Bl;
|
|
827
|
+
BBUF[2 * b + 1] = Bh;
|
|
828
|
+
BBUF[2 * c] = Cl;
|
|
829
|
+
BBUF[2 * c + 1] = Ch;
|
|
830
|
+
BBUF[2 * d] = Dl;
|
|
831
|
+
BBUF[2 * d + 1] = Dh;
|
|
719
832
|
}
|
|
720
833
|
// Second half-round of the same LE-limb BLAKE2b G mix; `x` is the message word offset.
|
|
721
834
|
function G2b(a, b, c, d, msg, x) {
|
|
@@ -726,27 +839,35 @@ function G2b(a, b, c, d, msg, x) {
|
|
|
726
839
|
let Cl = BBUF[2 * c], Ch = BBUF[2 * c + 1]; // prettier-ignore
|
|
727
840
|
let Dl = BBUF[2 * d], Dh = BBUF[2 * d + 1]; // prettier-ignore
|
|
728
841
|
// v[a] = (v[a] + v[b] + x) | 0;
|
|
729
|
-
|
|
842
|
+
const ll = add3L(Al, Bl, Xl);
|
|
730
843
|
Ah = add3H(ll, Ah, Bh, Xh);
|
|
731
844
|
Al = ll | 0;
|
|
732
845
|
// v[d] = rotr(v[d] ^ v[a], 16)
|
|
733
|
-
|
|
734
|
-
|
|
846
|
+
let xh = Dh ^ Ah, xl = Dl ^ Al; // prettier-ignore
|
|
847
|
+
Dh = rotrSH(xh, xl, 16);
|
|
848
|
+
Dl = rotrSL(xh, xl, 16);
|
|
735
849
|
// v[c] = (v[c] + v[d]) | 0;
|
|
736
850
|
({ h: Ch, l: Cl } = add(Ch, Cl, Dh, Dl));
|
|
737
851
|
// v[b] = rotr(v[b] ^ v[c], 63)
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
852
|
+
xh = Bh ^ Ch;
|
|
853
|
+
xl = Bl ^ Cl;
|
|
854
|
+
Bh = rotrBH(xh, xl, 63);
|
|
855
|
+
Bl = rotrBL(xh, xl, 63);
|
|
856
|
+
BBUF[2 * a] = Al;
|
|
857
|
+
BBUF[2 * a + 1] = Ah;
|
|
858
|
+
BBUF[2 * b] = Bl;
|
|
859
|
+
BBUF[2 * b + 1] = Bh;
|
|
860
|
+
BBUF[2 * c] = Cl;
|
|
861
|
+
BBUF[2 * c + 1] = Ch;
|
|
862
|
+
BBUF[2 * d] = Dl;
|
|
863
|
+
BBUF[2 * d + 1] = Dh;
|
|
744
864
|
}
|
|
745
865
|
function checkBlake2Opts(outputLen, opts = {}, keyLen, saltLen, persLen) {
|
|
746
|
-
anumber$
|
|
747
|
-
// RFC 7693 §2.1 requires digest length nn in 1..keyLen
|
|
866
|
+
anumber$1(keyLen);
|
|
867
|
+
// RFC 7693 §2.1 requires digest length nn in 1..keyLen (keyLen doubles as
|
|
868
|
+
// the per-variant max for both key and digest lengths: 64 for b, 32 for s).
|
|
748
869
|
if (outputLen <= 0 || outputLen > keyLen)
|
|
749
|
-
throw new Error('
|
|
870
|
+
throw new Error('"dkLen" must be 1..' + keyLen + ', got ' + outputLen);
|
|
750
871
|
const { key, salt, personalization } = opts;
|
|
751
872
|
// This API uses `undefined` for the RFC 7693 `kk = 0` case, so a provided key must be non-empty.
|
|
752
873
|
if (key !== undefined && (key.length < 1 || key.length > keyLen))
|
|
@@ -768,8 +889,8 @@ class _BLAKE2 {
|
|
|
768
889
|
outputLen;
|
|
769
890
|
canXOF = false;
|
|
770
891
|
constructor(blockLen, outputLen) {
|
|
771
|
-
anumber$
|
|
772
|
-
anumber$
|
|
892
|
+
anumber$1(blockLen);
|
|
893
|
+
anumber$1(outputLen);
|
|
773
894
|
this.blockLen = blockLen;
|
|
774
895
|
this.outputLen = outputLen;
|
|
775
896
|
this.buffer = new Uint8Array(blockLen);
|
|
@@ -807,7 +928,9 @@ class _BLAKE2 {
|
|
|
807
928
|
swap32IfBE$1(data32);
|
|
808
929
|
continue;
|
|
809
930
|
}
|
|
810
|
-
|
|
931
|
+
// When the whole input is buffered in one go (common for short messages), passing `data`
|
|
932
|
+
// directly avoids allocating a subarray view.
|
|
933
|
+
buffer.set(pos === 0 && take === len ? data : data.subarray(pos, pos + take), this.pos);
|
|
811
934
|
this.pos += take;
|
|
812
935
|
this.length += take;
|
|
813
936
|
pos += take;
|
|
@@ -817,18 +940,19 @@ class _BLAKE2 {
|
|
|
817
940
|
digestInto(out) {
|
|
818
941
|
aexists$1(this);
|
|
819
942
|
aoutput$1(out, this);
|
|
943
|
+
// Reject unaligned views explicitly instead of hiding them behind a full scratch copy.
|
|
944
|
+
if (out.byteOffset & 3)
|
|
945
|
+
throw new RangeError('"output" expected 4-byte aligned byteOffset, got ' + out.byteOffset);
|
|
820
946
|
const { pos, buffer32 } = this;
|
|
821
947
|
this.finished = true;
|
|
822
948
|
// Padding
|
|
823
|
-
|
|
949
|
+
this.buffer.fill(0, pos);
|
|
824
950
|
swap32IfBE$1(buffer32);
|
|
825
951
|
this.compress(buffer32, 0, true);
|
|
826
952
|
swap32IfBE$1(buffer32);
|
|
827
|
-
// Reject unaligned views explicitly instead of hiding them behind a full scratch copy.
|
|
828
|
-
if (out.byteOffset & 3)
|
|
829
|
-
throw new RangeError('"digestInto() output" expected 4-byte aligned byteOffset, got ' + out.byteOffset);
|
|
830
953
|
const state = this.get();
|
|
831
|
-
|
|
954
|
+
// digest() passes our own `buffer` as `out`; reuse its cached u32 view instead of allocating.
|
|
955
|
+
const out32 = out === this.buffer ? buffer32 : u32$1(out);
|
|
832
956
|
const full = Math.floor(this.outputLen / 4);
|
|
833
957
|
for (let i = 0; i < full; i++)
|
|
834
958
|
out32[i] = swap8IfBE(state[i]);
|
|
@@ -853,6 +977,7 @@ class _BLAKE2 {
|
|
|
853
977
|
// Recreate only `dkLen`; key/salt/personalization are already absorbed into the copied state.
|
|
854
978
|
to ||= new this.constructor({ dkLen: outputLen });
|
|
855
979
|
to.set(...this.get());
|
|
980
|
+
// Last-block-aware lazy compression keeps the pending block live even when full.
|
|
856
981
|
to.buffer.set(buffer);
|
|
857
982
|
to.destroyed = destroyed;
|
|
858
983
|
to.finished = finished;
|
|
@@ -886,6 +1011,7 @@ class _BLAKE2b extends _BLAKE2 {
|
|
|
886
1011
|
v7l = B2B_IV[14] | 0;
|
|
887
1012
|
v7h = B2B_IV[15] | 0;
|
|
888
1013
|
constructor(opts = {}) {
|
|
1014
|
+
opts = checkOpts$1({}, opts);
|
|
889
1015
|
const olen = opts.dkLen === undefined ? 64 : opts.dkLen;
|
|
890
1016
|
super(128, olen);
|
|
891
1017
|
checkBlake2Opts(olen, opts, 64, 16, 16);
|
|
@@ -900,7 +1026,8 @@ class _BLAKE2b extends _BLAKE2 {
|
|
|
900
1026
|
this.v0l ^= this.outputLen | (keyLength << 8) | (0x01 << 16) | (0x01 << 24);
|
|
901
1027
|
if (salt !== undefined) {
|
|
902
1028
|
abytes$1(salt, undefined, 'salt');
|
|
903
|
-
|
|
1029
|
+
// Copy: u32() would throw on views with byteOffset not divisible by 4.
|
|
1030
|
+
const slt = u32$1(copyBytes(salt));
|
|
904
1031
|
this.v4l ^= swap8IfBE(slt[0]);
|
|
905
1032
|
this.v4h ^= swap8IfBE(slt[1]);
|
|
906
1033
|
this.v5l ^= swap8IfBE(slt[2]);
|
|
@@ -908,7 +1035,8 @@ class _BLAKE2b extends _BLAKE2 {
|
|
|
908
1035
|
}
|
|
909
1036
|
if (personalization !== undefined) {
|
|
910
1037
|
abytes$1(personalization, undefined, 'personalization');
|
|
911
|
-
|
|
1038
|
+
// Copy: u32() would throw on views with byteOffset not divisible by 4.
|
|
1039
|
+
const pers = u32$1(copyBytes(personalization));
|
|
912
1040
|
this.v6l ^= swap8IfBE(pers[0]);
|
|
913
1041
|
this.v6h ^= swap8IfBE(pers[1]);
|
|
914
1042
|
this.v7l ^= swap8IfBE(pers[2]);
|
|
@@ -919,6 +1047,8 @@ class _BLAKE2b extends _BLAKE2 {
|
|
|
919
1047
|
const tmp = new Uint8Array(this.blockLen);
|
|
920
1048
|
tmp.set(key);
|
|
921
1049
|
this.update(tmp);
|
|
1050
|
+
// The padded copy holds key material; buffer/state keep what they need.
|
|
1051
|
+
clean$1(tmp);
|
|
922
1052
|
}
|
|
923
1053
|
}
|
|
924
1054
|
// prettier-ignore
|
|
@@ -946,9 +1076,32 @@ class _BLAKE2b extends _BLAKE2 {
|
|
|
946
1076
|
this.v7h = v7h | 0;
|
|
947
1077
|
}
|
|
948
1078
|
compress(msg, offset, isLast) {
|
|
949
|
-
|
|
1079
|
+
// First half from state. Direct writes: get() would allocate an array +
|
|
1080
|
+
// closure per block.
|
|
1081
|
+
// prettier-ignore
|
|
1082
|
+
const { v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h } = this;
|
|
1083
|
+
// prettier-ignore
|
|
1084
|
+
{
|
|
1085
|
+
BBUF[0] = v0l;
|
|
1086
|
+
BBUF[1] = v0h;
|
|
1087
|
+
BBUF[2] = v1l;
|
|
1088
|
+
BBUF[3] = v1h;
|
|
1089
|
+
BBUF[4] = v2l;
|
|
1090
|
+
BBUF[5] = v2h;
|
|
1091
|
+
BBUF[6] = v3l;
|
|
1092
|
+
BBUF[7] = v3h;
|
|
1093
|
+
BBUF[8] = v4l;
|
|
1094
|
+
BBUF[9] = v4h;
|
|
1095
|
+
BBUF[10] = v5l;
|
|
1096
|
+
BBUF[11] = v5h;
|
|
1097
|
+
BBUF[12] = v6l;
|
|
1098
|
+
BBUF[13] = v6h;
|
|
1099
|
+
BBUF[14] = v7l;
|
|
1100
|
+
BBUF[15] = v7h;
|
|
1101
|
+
}
|
|
950
1102
|
BBUF.set(B2B_IV, 16); // Second half from IV.
|
|
951
|
-
|
|
1103
|
+
const l = fromNumL(this.length);
|
|
1104
|
+
const h = fromNumH(this.length);
|
|
952
1105
|
BBUF[24] = B2B_IV[8] ^ l; // Low word of the offset.
|
|
953
1106
|
BBUF[25] = B2B_IV[9] ^ h; // High word.
|
|
954
1107
|
// Invert all bits for last block
|
|
@@ -1014,6 +1167,16 @@ class _BLAKE2b extends _BLAKE2 {
|
|
|
1014
1167
|
* ```ts
|
|
1015
1168
|
* blake2b(new Uint8Array([97, 98, 99]));
|
|
1016
1169
|
* ```
|
|
1170
|
+
* @example
|
|
1171
|
+
* Hash a message with Blake2b while selecting output, MAC, salt, and personalization settings.
|
|
1172
|
+
* ```ts
|
|
1173
|
+
* blake2b(new Uint8Array([97, 98, 99]), {
|
|
1174
|
+
* dkLen: 32,
|
|
1175
|
+
* key: new Uint8Array(32),
|
|
1176
|
+
* salt: new Uint8Array(16),
|
|
1177
|
+
* personalization: new Uint8Array(16),
|
|
1178
|
+
* });
|
|
1179
|
+
* ```
|
|
1017
1180
|
*/
|
|
1018
1181
|
const blake2b = /* @__PURE__ */ createHasher$1((opts) => new _BLAKE2b(opts));
|
|
1019
1182
|
|
|
@@ -1268,18 +1431,16 @@ class ECKey {
|
|
|
1268
1431
|
const hash = blake2b(bytes, { dkLen: 32 });
|
|
1269
1432
|
let signature;
|
|
1270
1433
|
if (__classPrivateFieldGet(this, _ECKey_keyPair, "f").curve === 'secp256k1') {
|
|
1271
|
-
signature = secp256k1
|
|
1272
|
-
.sign(hash, __classPrivateFieldGet(this, _ECKey_keyPair, "f").secretKey, {
|
|
1434
|
+
signature = secp256k1.sign(hash, __classPrivateFieldGet(this, _ECKey_keyPair, "f").secretKey, {
|
|
1273
1435
|
lowS: true, // Use canonical signatures (prevents malleability)
|
|
1274
|
-
|
|
1275
|
-
|
|
1436
|
+
prehash: false,
|
|
1437
|
+
});
|
|
1276
1438
|
}
|
|
1277
1439
|
else {
|
|
1278
|
-
signature = p256
|
|
1279
|
-
.sign(hash, __classPrivateFieldGet(this, _ECKey_keyPair, "f").secretKey, {
|
|
1440
|
+
signature = p256.sign(hash, __classPrivateFieldGet(this, _ECKey_keyPair, "f").secretKey, {
|
|
1280
1441
|
lowS: true, // Use canonical signatures (prevents malleability)
|
|
1281
|
-
|
|
1282
|
-
|
|
1442
|
+
prehash: false,
|
|
1443
|
+
});
|
|
1283
1444
|
}
|
|
1284
1445
|
return {
|
|
1285
1446
|
rawSignature: signature,
|
|
@@ -1350,12 +1511,12 @@ class ECPublicKey {
|
|
|
1350
1511
|
// We need to convert the stored public key to the requested format
|
|
1351
1512
|
if (this.curve === 'secp256k1') {
|
|
1352
1513
|
// For secp256k1, we need to get the public key from the stored bytes and convert format
|
|
1353
|
-
const point = secp256k1.Point.
|
|
1514
|
+
const point = secp256k1.Point.fromBytes(__classPrivateFieldGet(this, _ECPublicKey_key, "f"));
|
|
1354
1515
|
return point.toBytes(compress);
|
|
1355
1516
|
}
|
|
1356
1517
|
else {
|
|
1357
1518
|
// For p256, we need to get the public key from the stored bytes and convert format
|
|
1358
|
-
const point = p256.Point.
|
|
1519
|
+
const point = p256.Point.fromBytes(__classPrivateFieldGet(this, _ECPublicKey_key, "f"));
|
|
1359
1520
|
return point.toBytes(compress);
|
|
1360
1521
|
}
|
|
1361
1522
|
}
|
|
@@ -1395,7 +1556,7 @@ class _HMAC {
|
|
|
1395
1556
|
abytes$1(key, undefined, 'key');
|
|
1396
1557
|
this.iHash = hash.create();
|
|
1397
1558
|
if (typeof this.iHash.update !== 'function')
|
|
1398
|
-
throw new Error('
|
|
1559
|
+
throw new Error('expected Hash instance');
|
|
1399
1560
|
this.blockLen = this.iHash.blockLen;
|
|
1400
1561
|
this.outputLen = this.iHash.outputLen;
|
|
1401
1562
|
const blockLen = this.blockLen;
|
|
@@ -1440,12 +1601,13 @@ class _HMAC {
|
|
|
1440
1601
|
// Create new instance without calling constructor since the key
|
|
1441
1602
|
// is already in state and we don't know it.
|
|
1442
1603
|
to ||= Object.create(Object.getPrototypeOf(this), {});
|
|
1443
|
-
const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
|
|
1604
|
+
const { oHash, iHash, finished, destroyed, blockLen, outputLen, canXOF } = this;
|
|
1444
1605
|
to = to;
|
|
1445
1606
|
to.finished = finished;
|
|
1446
1607
|
to.destroyed = destroyed;
|
|
1447
1608
|
to.blockLen = blockLen;
|
|
1448
1609
|
to.outputLen = outputLen;
|
|
1610
|
+
to.canXOF = canXOF;
|
|
1449
1611
|
to.oHash = oHash._cloneInto(to.oHash);
|
|
1450
1612
|
to.iHash = iHash._cloneInto(to.iHash);
|
|
1451
1613
|
return to;
|
|
@@ -1469,16 +1631,16 @@ const hmac = /* @__PURE__ */ (() => {
|
|
|
1469
1631
|
* PBKDF (RFC 2898). Can be used to create a key from password and salt.
|
|
1470
1632
|
* @module
|
|
1471
1633
|
*/
|
|
1472
|
-
// Common
|
|
1634
|
+
// Common validation and per-call state setup for sync/async functions.
|
|
1473
1635
|
function pbkdf2Init(hash, _password, _salt, _opts) {
|
|
1474
1636
|
ahash$1(hash);
|
|
1475
1637
|
const opts = checkOpts$1({ dkLen: 32, asyncTick: 10 }, _opts);
|
|
1476
1638
|
const { c, dkLen, asyncTick } = opts;
|
|
1477
|
-
anumber$
|
|
1478
|
-
anumber$
|
|
1479
|
-
anumber$
|
|
1639
|
+
anumber$1(c, 'c');
|
|
1640
|
+
anumber$1(dkLen, 'dkLen');
|
|
1641
|
+
anumber$1(asyncTick, 'asyncTick');
|
|
1480
1642
|
if (c < 1)
|
|
1481
|
-
throw new Error('
|
|
1643
|
+
throw new Error('"c" (iterations) must be >= 1');
|
|
1482
1644
|
// RFC 8018 §5.2 defines `dkLen` as "a positive integer".
|
|
1483
1645
|
if (dkLen < 1)
|
|
1484
1646
|
throw new Error('"dkLen" must be >= 1');
|
|
@@ -1486,25 +1648,69 @@ function pbkdf2Init(hash, _password, _salt, _opts) {
|
|
|
1486
1648
|
// before allocating the destination buffer.
|
|
1487
1649
|
if (dkLen > (2 ** 32 - 1) * hash.outputLen)
|
|
1488
1650
|
throw new Error('derived key too long');
|
|
1489
|
-
const
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1651
|
+
const p = kdfInputToBytes(_password, 'password');
|
|
1652
|
+
try {
|
|
1653
|
+
const s = kdfInputToBytes(_salt, 'salt');
|
|
1654
|
+
try {
|
|
1655
|
+
// DK = PBKDF2(PRF, Password, Salt, c, dkLen);
|
|
1656
|
+
const DK = new Uint8Array(dkLen);
|
|
1657
|
+
const { iHash, oHash, outputLen } = hmac.create(hash, p);
|
|
1658
|
+
// Drive keyed hashes directly; the wrapper is only needed to initialize their HMAC midstates.
|
|
1659
|
+
const u = new Uint8Array(outputLen);
|
|
1660
|
+
const eng = pbkdf2Engine(iHash, oHash, s, u);
|
|
1661
|
+
return { c, dkLen, asyncTick, DK, outputLen, eng };
|
|
1662
|
+
}
|
|
1663
|
+
finally {
|
|
1664
|
+
// Uint8Array inputs belong to the caller; only wipe our UTF-8 conversion.
|
|
1665
|
+
if (typeof _salt === 'string')
|
|
1666
|
+
clean$1(s);
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
finally {
|
|
1670
|
+
if (typeof _password === 'string')
|
|
1671
|
+
clean$1(p);
|
|
1672
|
+
}
|
|
1498
1673
|
}
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1674
|
+
// Per-call PRF driver writes U1 into both `u` and `Ti`, then later digests into `u`;
|
|
1675
|
+
// shared by the sync and async variants.
|
|
1676
|
+
function pbkdf2Engine(iHash, oHash, salt, u) {
|
|
1677
|
+
const counter = new Uint8Array(4);
|
|
1678
|
+
const view = createView(counter);
|
|
1679
|
+
// Full clones retain tree/config state; absorb salt before async yields without cloning input.
|
|
1680
|
+
const salted = iHash._cloneInto().update(salt);
|
|
1681
|
+
// u1() overwrites the worker before reading it. Seed from the outer midstate so a long salt
|
|
1682
|
+
// cannot pre-populate a tree stack that the first reset would abandon without wiping.
|
|
1683
|
+
const work = oHash._cloneInto();
|
|
1684
|
+
const iClone = iHash._cloneInto; // Capture before mixed feedback can materialize state tuples.
|
|
1685
|
+
const oClone = oHash._cloneInto;
|
|
1686
|
+
return {
|
|
1687
|
+
u1: (ti, Ti) => {
|
|
1688
|
+
view.setInt32(0, ti, false);
|
|
1689
|
+
salted._cloneInto(work).update(counter).digestInto(u);
|
|
1690
|
+
oHash._cloneInto(work).update(u).digestInto(u);
|
|
1691
|
+
Ti.set(u.subarray(0, Ti.length));
|
|
1692
|
+
},
|
|
1693
|
+
// Whole `F` inner loop for the sync variant: one optimized function owns the hot loop.
|
|
1694
|
+
rounds: (c, Ti) => {
|
|
1695
|
+
for (let ui = 1; ui < c; ui++) {
|
|
1696
|
+
iClone.call(iHash, work).update(u).digestInto(u);
|
|
1697
|
+
oClone.call(oHash, work).update(u).digestInto(u);
|
|
1698
|
+
for (let i = 0; i < Ti.length; i++)
|
|
1699
|
+
Ti[i] ^= u[i];
|
|
1700
|
+
}
|
|
1701
|
+
},
|
|
1702
|
+
output: (DK) => {
|
|
1703
|
+
// Keyed templates and derived worker states are secret material.
|
|
1704
|
+
iHash.destroy();
|
|
1705
|
+
oHash.destroy();
|
|
1706
|
+
salted.destroy();
|
|
1707
|
+
work.destroy();
|
|
1708
|
+
// Shared sync/async cleanup point: wipe transient PRF state
|
|
1709
|
+
// while preserving the derived key buffer.
|
|
1710
|
+
clean$1(u);
|
|
1711
|
+
return DK;
|
|
1712
|
+
},
|
|
1713
|
+
};
|
|
1508
1714
|
}
|
|
1509
1715
|
/**
|
|
1510
1716
|
* PBKDF2-HMAC: RFC 8018 key derivation function.
|
|
@@ -1525,30 +1731,20 @@ function pbkdf2Output(PRF, PRFSalt, DK, prfW, u) {
|
|
|
1525
1731
|
* ```
|
|
1526
1732
|
*/
|
|
1527
1733
|
function pbkdf2(hash, password, salt, opts) {
|
|
1528
|
-
const { c, dkLen, DK,
|
|
1529
|
-
let prfW; // Working copy
|
|
1530
|
-
const arr = new Uint8Array(4);
|
|
1531
|
-
const view = createView(arr);
|
|
1532
|
-
const u = new Uint8Array(PRF.outputLen);
|
|
1734
|
+
const { c, dkLen, DK, outputLen, eng } = pbkdf2Init(hash, password, salt, opts);
|
|
1533
1735
|
// DK = T1 + T2 + ⋯ + Tdklen/hlen
|
|
1534
|
-
for (let ti = 1, pos = 0; pos < dkLen; ti++, pos +=
|
|
1736
|
+
for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += outputLen) {
|
|
1535
1737
|
// Ti = F(Password, Salt, c, i)
|
|
1536
1738
|
// The last Ti view can be shorter than hLen, which applies
|
|
1537
1739
|
// RFC 8018 §5.2 step 4's T_l<0..r-1> truncation without extra copies.
|
|
1538
|
-
const Ti = DK.subarray(pos, pos +
|
|
1539
|
-
view.setInt32(0, ti, false);
|
|
1740
|
+
const Ti = DK.subarray(pos, pos + outputLen);
|
|
1540
1741
|
// F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc
|
|
1541
1742
|
// U1 = PRF(Password, Salt + INT_32_BE(i))
|
|
1542
|
-
(
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
// Uc = PRF(Password, Uc−1)
|
|
1546
|
-
PRF._cloneInto(prfW).update(u).digestInto(u);
|
|
1547
|
-
for (let i = 0; i < Ti.length; i++)
|
|
1548
|
-
Ti[i] ^= u[i];
|
|
1549
|
-
}
|
|
1743
|
+
eng.u1(ti, Ti);
|
|
1744
|
+
// Uc = PRF(Password, Uc−1); Ti ^= Uc
|
|
1745
|
+
eng.rounds(c, Ti);
|
|
1550
1746
|
}
|
|
1551
|
-
return
|
|
1747
|
+
return eng.output(DK);
|
|
1552
1748
|
}
|
|
1553
1749
|
|
|
1554
1750
|
/**
|
|
@@ -1577,8 +1773,28 @@ const SHA256_K = /* @__PURE__ */ Uint32Array.from([
|
|
|
1577
1773
|
const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
|
|
1578
1774
|
/** Internal SHA-224 / SHA-256 compression engine from RFC 6234 §6.2. */
|
|
1579
1775
|
class SHA2_32B extends HashMD {
|
|
1580
|
-
|
|
1776
|
+
// We cannot use array here since array allows indexing by variable
|
|
1777
|
+
// which means optimizer/compiler cannot use registers.
|
|
1778
|
+
// Numeric initializers matter: starting the fields as `undefined` changes
|
|
1779
|
+
// V8's field representation and makes sha256 3x slower (measured).
|
|
1780
|
+
A = 0;
|
|
1781
|
+
B = 0;
|
|
1782
|
+
C = 0;
|
|
1783
|
+
D = 0;
|
|
1784
|
+
E = 0;
|
|
1785
|
+
F = 0;
|
|
1786
|
+
G = 0;
|
|
1787
|
+
H = 0;
|
|
1788
|
+
constructor(outputLen, IV) {
|
|
1581
1789
|
super(64, outputLen, 8, false);
|
|
1790
|
+
this.A = IV[0] | 0;
|
|
1791
|
+
this.B = IV[1] | 0;
|
|
1792
|
+
this.C = IV[2] | 0;
|
|
1793
|
+
this.D = IV[3] | 0;
|
|
1794
|
+
this.E = IV[4] | 0;
|
|
1795
|
+
this.F = IV[5] | 0;
|
|
1796
|
+
this.G = IV[6] | 0;
|
|
1797
|
+
this.H = IV[7] | 0;
|
|
1582
1798
|
}
|
|
1583
1799
|
get() {
|
|
1584
1800
|
const { A, B, C, D, E, F, G, H } = this;
|
|
@@ -1595,6 +1811,10 @@ class SHA2_32B extends HashMD {
|
|
|
1595
1811
|
this.G = G | 0;
|
|
1596
1812
|
this.H = H | 0;
|
|
1597
1813
|
}
|
|
1814
|
+
_cloneInto(to) {
|
|
1815
|
+
(to ||= new this.constructor()).set(...this.get());
|
|
1816
|
+
return this._cloneIntoMeta(to);
|
|
1817
|
+
}
|
|
1598
1818
|
process(view, offset) {
|
|
1599
1819
|
// Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array
|
|
1600
1820
|
for (let i = 0; i < 16; i++, offset += 4)
|
|
@@ -1646,18 +1866,8 @@ class SHA2_32B extends HashMD {
|
|
|
1646
1866
|
}
|
|
1647
1867
|
/** Internal SHA-256 hash class grounded in RFC 6234 §6.2. */
|
|
1648
1868
|
class _SHA256 extends SHA2_32B {
|
|
1649
|
-
// We cannot use array here since array allows indexing by variable
|
|
1650
|
-
// which means optimizer/compiler cannot use registers.
|
|
1651
|
-
A = SHA256_IV[0] | 0;
|
|
1652
|
-
B = SHA256_IV[1] | 0;
|
|
1653
|
-
C = SHA256_IV[2] | 0;
|
|
1654
|
-
D = SHA256_IV[3] | 0;
|
|
1655
|
-
E = SHA256_IV[4] | 0;
|
|
1656
|
-
F = SHA256_IV[5] | 0;
|
|
1657
|
-
G = SHA256_IV[6] | 0;
|
|
1658
|
-
H = SHA256_IV[7] | 0;
|
|
1659
1869
|
constructor() {
|
|
1660
|
-
super(32);
|
|
1870
|
+
super(32, SHA256_IV);
|
|
1661
1871
|
}
|
|
1662
1872
|
}
|
|
1663
1873
|
// SHA2-512 is slower than sha256 in js because u64 operations are slow.
|
|
@@ -1694,8 +1904,45 @@ const SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);
|
|
|
1694
1904
|
const SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);
|
|
1695
1905
|
/** Internal SHA-384 / SHA-512 compression engine from RFC 6234 §6.4. */
|
|
1696
1906
|
class SHA2_64B extends HashMD {
|
|
1697
|
-
|
|
1907
|
+
// We cannot use array here since array allows indexing by variable
|
|
1908
|
+
// which means optimizer/compiler cannot use registers.
|
|
1909
|
+
// h -- high 32 bits, l -- low 32 bits
|
|
1910
|
+
// Numeric initializers matter: starting the fields as `undefined` changes
|
|
1911
|
+
// V8's field representation and slows hashing down (measured on sha256).
|
|
1912
|
+
Ah = 0;
|
|
1913
|
+
Al = 0;
|
|
1914
|
+
Bh = 0;
|
|
1915
|
+
Bl = 0;
|
|
1916
|
+
Ch = 0;
|
|
1917
|
+
Cl = 0;
|
|
1918
|
+
Dh = 0;
|
|
1919
|
+
Dl = 0;
|
|
1920
|
+
Eh = 0;
|
|
1921
|
+
El = 0;
|
|
1922
|
+
Fh = 0;
|
|
1923
|
+
Fl = 0;
|
|
1924
|
+
Gh = 0;
|
|
1925
|
+
Gl = 0;
|
|
1926
|
+
Hh = 0;
|
|
1927
|
+
Hl = 0;
|
|
1928
|
+
constructor(outputLen, IV) {
|
|
1698
1929
|
super(128, outputLen, 16, false);
|
|
1930
|
+
this.Ah = IV[0] | 0;
|
|
1931
|
+
this.Al = IV[1] | 0;
|
|
1932
|
+
this.Bh = IV[2] | 0;
|
|
1933
|
+
this.Bl = IV[3] | 0;
|
|
1934
|
+
this.Ch = IV[4] | 0;
|
|
1935
|
+
this.Cl = IV[5] | 0;
|
|
1936
|
+
this.Dh = IV[6] | 0;
|
|
1937
|
+
this.Dl = IV[7] | 0;
|
|
1938
|
+
this.Eh = IV[8] | 0;
|
|
1939
|
+
this.El = IV[9] | 0;
|
|
1940
|
+
this.Fh = IV[10] | 0;
|
|
1941
|
+
this.Fl = IV[11] | 0;
|
|
1942
|
+
this.Gh = IV[12] | 0;
|
|
1943
|
+
this.Gl = IV[13] | 0;
|
|
1944
|
+
this.Hh = IV[14] | 0;
|
|
1945
|
+
this.Hl = IV[15] | 0;
|
|
1699
1946
|
}
|
|
1700
1947
|
// prettier-ignore
|
|
1701
1948
|
get() {
|
|
@@ -1721,6 +1968,10 @@ class SHA2_64B extends HashMD {
|
|
|
1721
1968
|
this.Hh = Hh | 0;
|
|
1722
1969
|
this.Hl = Hl | 0;
|
|
1723
1970
|
}
|
|
1971
|
+
_cloneInto(to) {
|
|
1972
|
+
(to ||= new this.constructor()).set(...this.get());
|
|
1973
|
+
return this._cloneIntoMeta(to);
|
|
1974
|
+
}
|
|
1724
1975
|
process(view, offset) {
|
|
1725
1976
|
// Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array
|
|
1726
1977
|
for (let i = 0; i < 16; i++, offset += 4) {
|
|
@@ -1804,24 +2055,8 @@ class SHA2_64B extends HashMD {
|
|
|
1804
2055
|
}
|
|
1805
2056
|
/** Internal SHA-512 hash class grounded in RFC 6234 §6.3 and §6.4. */
|
|
1806
2057
|
class _SHA512 extends SHA2_64B {
|
|
1807
|
-
Ah = SHA512_IV[0] | 0;
|
|
1808
|
-
Al = SHA512_IV[1] | 0;
|
|
1809
|
-
Bh = SHA512_IV[2] | 0;
|
|
1810
|
-
Bl = SHA512_IV[3] | 0;
|
|
1811
|
-
Ch = SHA512_IV[4] | 0;
|
|
1812
|
-
Cl = SHA512_IV[5] | 0;
|
|
1813
|
-
Dh = SHA512_IV[6] | 0;
|
|
1814
|
-
Dl = SHA512_IV[7] | 0;
|
|
1815
|
-
Eh = SHA512_IV[8] | 0;
|
|
1816
|
-
El = SHA512_IV[9] | 0;
|
|
1817
|
-
Fh = SHA512_IV[10] | 0;
|
|
1818
|
-
Fl = SHA512_IV[11] | 0;
|
|
1819
|
-
Gh = SHA512_IV[12] | 0;
|
|
1820
|
-
Gl = SHA512_IV[13] | 0;
|
|
1821
|
-
Hh = SHA512_IV[14] | 0;
|
|
1822
|
-
Hl = SHA512_IV[15] | 0;
|
|
1823
2058
|
constructor() {
|
|
1824
|
-
super(64);
|
|
2059
|
+
super(64, SHA512_IV);
|
|
1825
2060
|
}
|
|
1826
2061
|
}
|
|
1827
2062
|
/**
|
|
@@ -1832,6 +2067,7 @@ class _SHA512 extends SHA2_64B {
|
|
|
1832
2067
|
* - Each sha256 hash is executing 2^18 bit operations.
|
|
1833
2068
|
* - Good 2024 ASICs can do 200Th/sec with 3500 watts of power, corresponding to 2^36 hashes/joule.
|
|
1834
2069
|
* @param msg - message bytes to hash
|
|
2070
|
+
* @param opts - Reserved hash options.
|
|
1835
2071
|
* @returns Digest bytes.
|
|
1836
2072
|
* @example
|
|
1837
2073
|
* Hash a message with SHA2-256.
|
|
@@ -1844,6 +2080,7 @@ const sha256 = /* @__PURE__ */ createHasher$1(() => new _SHA256(),
|
|
|
1844
2080
|
/**
|
|
1845
2081
|
* SHA2-512 hash function from RFC 4634.
|
|
1846
2082
|
* @param msg - message bytes to hash
|
|
2083
|
+
* @param opts - Reserved hash options.
|
|
1847
2084
|
* @returns Digest bytes.
|
|
1848
2085
|
* @example
|
|
1849
2086
|
* Hash a message with SHA2-512.
|
|
@@ -1854,353 +2091,28 @@ const sha256 = /* @__PURE__ */ createHasher$1(() => new _SHA256(),
|
|
|
1854
2091
|
const sha512 = /* @__PURE__ */ createHasher$1(() => new _SHA512(),
|
|
1855
2092
|
/* @__PURE__ */ oidNist$1(0x03));
|
|
1856
2093
|
|
|
1857
|
-
/*! scure-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
}
|
|
1877
|
-
else {
|
|
1878
|
-
return arr.every((item) => Number.isSafeInteger(item));
|
|
2094
|
+
/*! scure-bip39 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) */
|
|
2095
|
+
// Japanese wordlist
|
|
2096
|
+
// The canonical BIP-39 Japanese wordlist starts with あいこくしん.
|
|
2097
|
+
// Use that sentinel so generated phrases use U+3000 ideographic spaces.
|
|
2098
|
+
const isJapanese = (wordlist) => wordlist[0] === '\u3042\u3044\u3053\u304f\u3057\u3093';
|
|
2099
|
+
// JavaScript strings can contain unpaired UTF-16 surrogates, which cannot be encoded as UTF-8.
|
|
2100
|
+
function isWellFormedUnicode(value) {
|
|
2101
|
+
for (let i = 0; i < value.length; i++) {
|
|
2102
|
+
const current = value.charCodeAt(i);
|
|
2103
|
+
if (current >= 0xd800 && current <= 0xdbff) {
|
|
2104
|
+
if (i + 1 >= value.length)
|
|
2105
|
+
return false;
|
|
2106
|
+
const next = value.charCodeAt(++i);
|
|
2107
|
+
if (next < 0xdc00 || next > 0xdfff)
|
|
2108
|
+
return false;
|
|
2109
|
+
}
|
|
2110
|
+
else if (current >= 0xdc00 && current <= 0xdfff) {
|
|
2111
|
+
return false;
|
|
2112
|
+
}
|
|
1879
2113
|
}
|
|
1880
|
-
}
|
|
1881
|
-
function afn(input) {
|
|
1882
|
-
if (typeof input !== 'function')
|
|
1883
|
-
throw new TypeError('function expected');
|
|
1884
2114
|
return true;
|
|
1885
2115
|
}
|
|
1886
|
-
function astr(label, input) {
|
|
1887
|
-
if (typeof input !== 'string')
|
|
1888
|
-
throw new TypeError(`${label}: string expected`);
|
|
1889
|
-
return true;
|
|
1890
|
-
}
|
|
1891
|
-
function anumber$1(n) {
|
|
1892
|
-
if (typeof n !== 'number')
|
|
1893
|
-
throw new TypeError(`number expected, got ${typeof n}`);
|
|
1894
|
-
if (!Number.isSafeInteger(n))
|
|
1895
|
-
throw new RangeError(`invalid integer: ${n}`);
|
|
1896
|
-
}
|
|
1897
|
-
function aArr(input) {
|
|
1898
|
-
if (!Array.isArray(input))
|
|
1899
|
-
throw new TypeError('array expected');
|
|
1900
|
-
}
|
|
1901
|
-
function astrArr(label, input) {
|
|
1902
|
-
if (!isArrayOf(true, input))
|
|
1903
|
-
throw new TypeError(`${label}: array of strings expected`);
|
|
1904
|
-
}
|
|
1905
|
-
function anumArr(label, input) {
|
|
1906
|
-
if (!isArrayOf(false, input))
|
|
1907
|
-
throw new TypeError(`${label}: array of numbers expected`);
|
|
1908
|
-
}
|
|
1909
|
-
/**
|
|
1910
|
-
* @__NO_SIDE_EFFECTS__
|
|
1911
|
-
*/
|
|
1912
|
-
function chain(...args) {
|
|
1913
|
-
const id = (a) => a;
|
|
1914
|
-
// Wrap call in closure so JIT can inline calls
|
|
1915
|
-
const wrap = (a, b) => (c) => a(b(c));
|
|
1916
|
-
// Construct chain of args[-1].encode(args[-2].encode([...]))
|
|
1917
|
-
const encode = args.map((x) => x.encode).reduceRight(wrap, id);
|
|
1918
|
-
// Construct chain of args[0].decode(args[1].decode(...))
|
|
1919
|
-
const decode = args.map((x) => x.decode).reduce(wrap, id);
|
|
1920
|
-
return { encode, decode };
|
|
1921
|
-
}
|
|
1922
|
-
/**
|
|
1923
|
-
* Encodes integer radix representation to array of strings using alphabet and back.
|
|
1924
|
-
* Could also be array of strings.
|
|
1925
|
-
* @__NO_SIDE_EFFECTS__
|
|
1926
|
-
*/
|
|
1927
|
-
function alphabet(letters) {
|
|
1928
|
-
// mapping 1 to "b"
|
|
1929
|
-
const lettersA = typeof letters === 'string' ? letters.split('') : letters;
|
|
1930
|
-
const len = lettersA.length;
|
|
1931
|
-
astrArr('alphabet', lettersA);
|
|
1932
|
-
// mapping "b" to 1
|
|
1933
|
-
const indexes = new Map(lettersA.map((l, i) => [l, i]));
|
|
1934
|
-
return {
|
|
1935
|
-
encode: (digits) => {
|
|
1936
|
-
aArr(digits);
|
|
1937
|
-
return digits.map((i) => {
|
|
1938
|
-
if (!Number.isSafeInteger(i) || i < 0 || i >= len)
|
|
1939
|
-
throw new Error(`alphabet.encode: digit index outside alphabet "${i}". Allowed: ${letters}`);
|
|
1940
|
-
return lettersA[i];
|
|
1941
|
-
});
|
|
1942
|
-
},
|
|
1943
|
-
decode: (input) => {
|
|
1944
|
-
aArr(input);
|
|
1945
|
-
return input.map((letter) => {
|
|
1946
|
-
astr('alphabet.decode', letter);
|
|
1947
|
-
const i = indexes.get(letter);
|
|
1948
|
-
if (i === undefined)
|
|
1949
|
-
throw new Error(`Unknown letter: "${letter}". Allowed: ${letters}`);
|
|
1950
|
-
return i;
|
|
1951
|
-
});
|
|
1952
|
-
},
|
|
1953
|
-
};
|
|
1954
|
-
}
|
|
1955
|
-
/**
|
|
1956
|
-
* @__NO_SIDE_EFFECTS__
|
|
1957
|
-
*/
|
|
1958
|
-
function join(separator = '') {
|
|
1959
|
-
astr('join', separator);
|
|
1960
|
-
// join('') is only lossless when each chunk is already unambiguous, such as single-symbol alphabets.
|
|
1961
|
-
// Multi-character tokens need a separator that cannot appear inside the chunks.
|
|
1962
|
-
return {
|
|
1963
|
-
encode: (from) => {
|
|
1964
|
-
astrArr('join.decode', from);
|
|
1965
|
-
return from.join(separator);
|
|
1966
|
-
},
|
|
1967
|
-
decode: (to) => {
|
|
1968
|
-
astr('join.decode', to);
|
|
1969
|
-
return to.split(separator);
|
|
1970
|
-
},
|
|
1971
|
-
};
|
|
1972
|
-
}
|
|
1973
|
-
/**
|
|
1974
|
-
* Pad strings array so it has integer number of bits
|
|
1975
|
-
* @__NO_SIDE_EFFECTS__
|
|
1976
|
-
*/
|
|
1977
|
-
function padding(bits, chr = '=') {
|
|
1978
|
-
anumber$1(bits);
|
|
1979
|
-
astr('padding', chr);
|
|
1980
|
-
return {
|
|
1981
|
-
encode(data) {
|
|
1982
|
-
astrArr('padding.encode', data);
|
|
1983
|
-
// Mutates the intermediate token array in place while appending pad chars.
|
|
1984
|
-
// utils.padding callers that need to preserve their input should pass a copy.
|
|
1985
|
-
while ((data.length * bits) % 8)
|
|
1986
|
-
data.push(chr);
|
|
1987
|
-
return data;
|
|
1988
|
-
},
|
|
1989
|
-
decode(input) {
|
|
1990
|
-
astrArr('padding.decode', input);
|
|
1991
|
-
let end = input.length;
|
|
1992
|
-
if ((end * bits) % 8)
|
|
1993
|
-
throw new Error('padding: invalid, string should have whole number of bytes');
|
|
1994
|
-
for (; end > 0 && input[end - 1] === chr; end--) {
|
|
1995
|
-
const last = end - 1;
|
|
1996
|
-
const byte = last * bits;
|
|
1997
|
-
if (byte % 8 === 0)
|
|
1998
|
-
throw new Error('padding: invalid, string has too much padding');
|
|
1999
|
-
}
|
|
2000
|
-
return input.slice(0, end);
|
|
2001
|
-
},
|
|
2002
|
-
};
|
|
2003
|
-
}
|
|
2004
|
-
/**
|
|
2005
|
-
* Slow: O(n^2) time complexity
|
|
2006
|
-
*/
|
|
2007
|
-
function convertRadix(data, from, to) {
|
|
2008
|
-
// base 1 is impossible
|
|
2009
|
-
if (from < 2)
|
|
2010
|
-
throw new RangeError(`convertRadix: invalid from=${from}, base cannot be less than 2`);
|
|
2011
|
-
if (to < 2)
|
|
2012
|
-
throw new RangeError(`convertRadix: invalid to=${to}, base cannot be less than 2`);
|
|
2013
|
-
aArr(data);
|
|
2014
|
-
if (!data.length)
|
|
2015
|
-
return [];
|
|
2016
|
-
let pos = 0;
|
|
2017
|
-
const res = [];
|
|
2018
|
-
const digits = Array.from(data, (d) => {
|
|
2019
|
-
anumber$1(d);
|
|
2020
|
-
if (d < 0 || d >= from)
|
|
2021
|
-
throw new Error(`invalid integer: ${d}`);
|
|
2022
|
-
return d;
|
|
2023
|
-
});
|
|
2024
|
-
const dlen = digits.length;
|
|
2025
|
-
while (true) {
|
|
2026
|
-
let carry = 0;
|
|
2027
|
-
let done = true;
|
|
2028
|
-
for (let i = pos; i < dlen; i++) {
|
|
2029
|
-
const digit = digits[i];
|
|
2030
|
-
const fromCarry = from * carry;
|
|
2031
|
-
const digitBase = fromCarry + digit;
|
|
2032
|
-
if (!Number.isSafeInteger(digitBase) ||
|
|
2033
|
-
fromCarry / from !== carry ||
|
|
2034
|
-
digitBase - digit !== fromCarry) {
|
|
2035
|
-
throw new Error('convertRadix: carry overflow');
|
|
2036
|
-
}
|
|
2037
|
-
const div = digitBase / to;
|
|
2038
|
-
carry = digitBase % to;
|
|
2039
|
-
const rounded = Math.floor(div);
|
|
2040
|
-
digits[i] = rounded;
|
|
2041
|
-
if (!Number.isSafeInteger(rounded) || rounded * to + carry !== digitBase)
|
|
2042
|
-
throw new Error('convertRadix: carry overflow');
|
|
2043
|
-
if (!done)
|
|
2044
|
-
continue;
|
|
2045
|
-
else if (!rounded)
|
|
2046
|
-
pos = i;
|
|
2047
|
-
else
|
|
2048
|
-
done = false;
|
|
2049
|
-
}
|
|
2050
|
-
res.push(carry);
|
|
2051
|
-
if (done)
|
|
2052
|
-
break;
|
|
2053
|
-
}
|
|
2054
|
-
// Preserve explicit leading zero digits so callers like base58 keep zero-prefix semantics.
|
|
2055
|
-
for (let i = 0; i < data.length - 1 && data[i] === 0; i++)
|
|
2056
|
-
res.push(0);
|
|
2057
|
-
return res.reverse();
|
|
2058
|
-
}
|
|
2059
|
-
const gcd = (a, b) => (b === 0 ? a : gcd(b, a % b));
|
|
2060
|
-
// Maximum carry width before the `pos` cycle repeats.
|
|
2061
|
-
// Residues advance in gcd(from, to) steps, so the largest pre-drain width is from + (to - gcd).
|
|
2062
|
-
const radix2carry = /* @__NO_SIDE_EFFECTS__ */ (from, to) => from + (to - gcd(from, to));
|
|
2063
|
-
const powers = /* @__PURE__ */ (() => {
|
|
2064
|
-
let res = [];
|
|
2065
|
-
for (let i = 0; i < 40; i++)
|
|
2066
|
-
res.push(2 ** i);
|
|
2067
|
-
return res;
|
|
2068
|
-
})();
|
|
2069
|
-
/**
|
|
2070
|
-
* Implemented with numbers, because BigInt is 5x slower
|
|
2071
|
-
*/
|
|
2072
|
-
function convertRadix2(data, from, to, padding) {
|
|
2073
|
-
aArr(data);
|
|
2074
|
-
if (from <= 0 || from > 32)
|
|
2075
|
-
throw new RangeError(`convertRadix2: wrong from=${from}`);
|
|
2076
|
-
if (to <= 0 || to > 32)
|
|
2077
|
-
throw new RangeError(`convertRadix2: wrong to=${to}`);
|
|
2078
|
-
if (radix2carry(from, to) > 32) {
|
|
2079
|
-
throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${radix2carry(from, to)}`);
|
|
2080
|
-
}
|
|
2081
|
-
let carry = 0;
|
|
2082
|
-
let pos = 0; // bitwise position in current element
|
|
2083
|
-
const max = powers[from];
|
|
2084
|
-
const mask = powers[to] - 1;
|
|
2085
|
-
const res = [];
|
|
2086
|
-
for (const n of data) {
|
|
2087
|
-
anumber$1(n);
|
|
2088
|
-
if (n >= max)
|
|
2089
|
-
throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);
|
|
2090
|
-
carry = (carry << from) | n;
|
|
2091
|
-
if (pos + from > 32)
|
|
2092
|
-
throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);
|
|
2093
|
-
pos += from;
|
|
2094
|
-
for (; pos >= to; pos -= to)
|
|
2095
|
-
res.push(((carry >> (pos - to)) & mask) >>> 0);
|
|
2096
|
-
const pow = powers[pos];
|
|
2097
|
-
if (pow === undefined)
|
|
2098
|
-
throw new Error('invalid carry');
|
|
2099
|
-
carry &= pow - 1; // clean carry, otherwise it will cause overflow
|
|
2100
|
-
}
|
|
2101
|
-
carry = (carry << (to - pos)) & mask;
|
|
2102
|
-
// Canonical decode paths reject leftover whole input words and non-zero pad bits.
|
|
2103
|
-
// For Bech32 5->8 regrouping, this is the "4 bits or less, all zeroes" tail rule.
|
|
2104
|
-
if (!padding && pos >= from)
|
|
2105
|
-
throw new Error('Excess padding');
|
|
2106
|
-
if (!padding && carry > 0)
|
|
2107
|
-
throw new Error(`Non-zero padding: ${carry}`);
|
|
2108
|
-
if (padding && pos > 0)
|
|
2109
|
-
res.push(carry >>> 0);
|
|
2110
|
-
return res;
|
|
2111
|
-
}
|
|
2112
|
-
/**
|
|
2113
|
-
* @__NO_SIDE_EFFECTS__
|
|
2114
|
-
*/
|
|
2115
|
-
function radix(num) {
|
|
2116
|
-
anumber$1(num);
|
|
2117
|
-
const _256 = 2 ** 8;
|
|
2118
|
-
// Base-range and carry-overflow checks live in convertRadix so encode/decode reject unsupported bases symmetrically.
|
|
2119
|
-
return {
|
|
2120
|
-
encode: (bytes) => {
|
|
2121
|
-
if (!isBytes$1(bytes))
|
|
2122
|
-
throw new TypeError('radix.encode input should be Uint8Array');
|
|
2123
|
-
return convertRadix(Array.from(bytes), _256, num);
|
|
2124
|
-
},
|
|
2125
|
-
decode: (digits) => {
|
|
2126
|
-
anumArr('radix.decode', digits);
|
|
2127
|
-
return Uint8Array.from(convertRadix(digits, num, _256));
|
|
2128
|
-
},
|
|
2129
|
-
};
|
|
2130
|
-
}
|
|
2131
|
-
/**
|
|
2132
|
-
* If both bases are power of same number (like `2**8 <-> 2**64`),
|
|
2133
|
-
* there is a linear algorithm. For now we have implementation for power-of-two bases only.
|
|
2134
|
-
* @__NO_SIDE_EFFECTS__
|
|
2135
|
-
*/
|
|
2136
|
-
function radix2(bits, revPadding = false) {
|
|
2137
|
-
anumber$1(bits);
|
|
2138
|
-
if (bits <= 0 || bits > 32)
|
|
2139
|
-
throw new RangeError('radix2: bits should be in (0..32]');
|
|
2140
|
-
if (radix2carry(8, bits) > 32 || radix2carry(bits, 8) > 32)
|
|
2141
|
-
throw new RangeError('radix2: carry overflow');
|
|
2142
|
-
// revPadding flips which direction allows a partial zero tail.
|
|
2143
|
-
// Default pads 8->bits and rejects extra bits on bits->8; `true` does the opposite.
|
|
2144
|
-
return {
|
|
2145
|
-
encode: (bytes) => {
|
|
2146
|
-
if (!isBytes$1(bytes))
|
|
2147
|
-
throw new TypeError('radix2.encode input should be Uint8Array');
|
|
2148
|
-
return convertRadix2(Array.from(bytes), 8, bits, !revPadding);
|
|
2149
|
-
},
|
|
2150
|
-
decode: (digits) => {
|
|
2151
|
-
anumArr('radix2.decode', digits);
|
|
2152
|
-
return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));
|
|
2153
|
-
},
|
|
2154
|
-
};
|
|
2155
|
-
}
|
|
2156
|
-
function checksum(len, fn) {
|
|
2157
|
-
anumber$1(len);
|
|
2158
|
-
// Reject degenerate zero-byte checksums up front so callers don't accidentally
|
|
2159
|
-
// build a no-op checksum stage.
|
|
2160
|
-
if (len <= 0)
|
|
2161
|
-
throw new RangeError(`checksum length must be positive: ${len}`);
|
|
2162
|
-
afn(fn);
|
|
2163
|
-
const _fn = fn;
|
|
2164
|
-
// Uses the first `len` bytes of fn(data) in both directions.
|
|
2165
|
-
// Current call sites rely on `len > 0` and checksum functions that return at least that many bytes.
|
|
2166
|
-
return {
|
|
2167
|
-
encode(data) {
|
|
2168
|
-
if (!isBytes$1(data))
|
|
2169
|
-
throw new TypeError('checksum.encode: input should be Uint8Array');
|
|
2170
|
-
const sum = _fn(data).slice(0, len);
|
|
2171
|
-
const res = new Uint8Array(data.length + len);
|
|
2172
|
-
res.set(data);
|
|
2173
|
-
res.set(sum, data.length);
|
|
2174
|
-
return res;
|
|
2175
|
-
},
|
|
2176
|
-
decode(data) {
|
|
2177
|
-
if (!isBytes$1(data))
|
|
2178
|
-
throw new TypeError('checksum.decode: input should be Uint8Array');
|
|
2179
|
-
const payload = data.slice(0, -len);
|
|
2180
|
-
const oldChecksum = data.slice(-len);
|
|
2181
|
-
const newChecksum = _fn(payload).slice(0, len);
|
|
2182
|
-
for (let i = 0; i < len; i++)
|
|
2183
|
-
if (newChecksum[i] !== oldChecksum[i])
|
|
2184
|
-
throw new Error('Invalid checksum');
|
|
2185
|
-
return payload;
|
|
2186
|
-
},
|
|
2187
|
-
};
|
|
2188
|
-
}
|
|
2189
|
-
// prettier-ignore
|
|
2190
|
-
/**
|
|
2191
|
-
* Low-level building blocks used by the exported codecs.
|
|
2192
|
-
* @example
|
|
2193
|
-
* Build a radix-32 coder from the low-level helpers.
|
|
2194
|
-
* ```ts
|
|
2195
|
-
* import { utils } from '@scure/base';
|
|
2196
|
-
* utils.radix2(5).encode(Uint8Array.from([1, 2, 3]));
|
|
2197
|
-
* ```
|
|
2198
|
-
*/
|
|
2199
|
-
const utils = /* @__PURE__ */ Object.freeze({
|
|
2200
|
-
alphabet, chain, checksum, convertRadix, convertRadix2, radix, radix2, join, padding,
|
|
2201
|
-
});
|
|
2202
|
-
|
|
2203
|
-
/*! scure-bip39 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) */
|
|
2204
2116
|
// Normalization replaces equivalent sequences of characters
|
|
2205
2117
|
// so that any two texts that are equivalent will be reduced
|
|
2206
2118
|
// to the same sequence of code points, called the normal form of the original text.
|
|
@@ -2210,6 +2122,8 @@ const utils = /* @__PURE__ */ Object.freeze({
|
|
|
2210
2122
|
function nfkd(str) {
|
|
2211
2123
|
if (typeof str !== 'string')
|
|
2212
2124
|
throw new TypeError('invalid mnemonic type: ' + typeof str);
|
|
2125
|
+
if (!isWellFormedUnicode(str))
|
|
2126
|
+
throw new TypeError('expected well-formed Unicode string');
|
|
2213
2127
|
return str.normalize('NFKD');
|
|
2214
2128
|
}
|
|
2215
2129
|
// BIP-39 mnemonics are consumed in NFKD form.
|
|
@@ -2227,23 +2141,97 @@ function aentropy(ent) {
|
|
|
2227
2141
|
if (![16, 20, 24, 28, 32].includes(ent.length))
|
|
2228
2142
|
throw new RangeError('invalid entropy length');
|
|
2229
2143
|
}
|
|
2144
|
+
/**
|
|
2145
|
+
* Generate x random words. Uses Cryptographically-Secure Random Number Generator.
|
|
2146
|
+
* @param wordlist - Imported wordlist for a specific language.
|
|
2147
|
+
* @param strength - Mnemonic strength, from 128 to 256 bits.
|
|
2148
|
+
* @returns 12-24 word mnemonic phrase.
|
|
2149
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
2150
|
+
* @throws On wrong argument ranges or values. {@link RangeError}
|
|
2151
|
+
* @example
|
|
2152
|
+
* Generate a new English mnemonic.
|
|
2153
|
+
* ```ts
|
|
2154
|
+
* import { generateMnemonic } from '@scure/bip39';
|
|
2155
|
+
* import { wordlist } from '@scure/bip39/wordlists/english.js';
|
|
2156
|
+
* const mnemonic = generateMnemonic(wordlist, 128);
|
|
2157
|
+
* // 'legal winner thank year wave sausage worth useful legal winner thank yellow'
|
|
2158
|
+
* ```
|
|
2159
|
+
*/
|
|
2160
|
+
function generateMnemonic$1(wordlist, strength = 128) {
|
|
2161
|
+
anumber$1(strength);
|
|
2162
|
+
if (strength % 32 !== 0 || strength > 256)
|
|
2163
|
+
throw new RangeError('Invalid entropy');
|
|
2164
|
+
return entropyToMnemonic$1(randomBytes$2(strength / 8), wordlist);
|
|
2165
|
+
}
|
|
2166
|
+
// BIP-39 checksum is the first ENT/32 bits of SHA-256(entropy).
|
|
2167
|
+
// Returned as a byte with checksum bits on the left and zeroes on the right.
|
|
2230
2168
|
const calcChecksum = (entropy) => {
|
|
2231
2169
|
// Checksum is ent.length/4 bits long
|
|
2232
2170
|
const bitsLeft = 8 - entropy.length / 4;
|
|
2233
2171
|
// Zero rightmost "bitsLeft" bits in byte
|
|
2234
2172
|
// For example: bitsLeft=4 val=10111101 -> 10110000
|
|
2235
|
-
return
|
|
2173
|
+
return (sha256(entropy)[0] >> bitsLeft) << bitsLeft;
|
|
2236
2174
|
};
|
|
2237
|
-
function
|
|
2175
|
+
function awordlist(wordlist) {
|
|
2238
2176
|
if (!Array.isArray(wordlist) || wordlist.length !== 2048 || typeof wordlist[0] !== 'string')
|
|
2239
2177
|
throw new TypeError('Wordlist: expected array of 2048 strings');
|
|
2240
2178
|
wordlist.forEach((i) => {
|
|
2241
2179
|
if (typeof i !== 'string')
|
|
2242
2180
|
throw new TypeError('wordlist: non-string element: ' + i);
|
|
2181
|
+
// Wordlists become mnemonic output, so apply the same lossless UTF-8 boundary as input phrases.
|
|
2182
|
+
if (!isWellFormedUnicode(i))
|
|
2183
|
+
throw new TypeError('wordlist: expected well-formed Unicode string');
|
|
2243
2184
|
});
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2185
|
+
}
|
|
2186
|
+
// BIP-39 appends checksum bits to entropy,
|
|
2187
|
+
// then splits the bitstream into 11-bit indexes for a 2048-word list.
|
|
2188
|
+
function encodeWords(entropy, wordlist) {
|
|
2189
|
+
awordlist(wordlist);
|
|
2190
|
+
const bytes = new Uint8Array(entropy.length + 1); // entropy || checksum byte
|
|
2191
|
+
bytes.set(entropy);
|
|
2192
|
+
bytes[entropy.length] = calcChecksum(entropy);
|
|
2193
|
+
const words = [];
|
|
2194
|
+
let carry = 0; // bit accumulator, holds < 19 bits
|
|
2195
|
+
let bits = 0;
|
|
2196
|
+
for (const byte of bytes) {
|
|
2197
|
+
carry = (carry << 8) | byte;
|
|
2198
|
+
bits += 8;
|
|
2199
|
+
if (bits >= 11) {
|
|
2200
|
+
bits -= 11;
|
|
2201
|
+
words.push(wordlist[(carry >>> bits) & 0x7ff]);
|
|
2202
|
+
carry &= (1 << bits) - 1;
|
|
2203
|
+
}
|
|
2204
|
+
}
|
|
2205
|
+
// Bits still in carry are the zero right bits of the checksum byte; drop them.
|
|
2206
|
+
return words;
|
|
2207
|
+
}
|
|
2208
|
+
// Reverse of encodeWords: repacks 11-bit indexes into bytes and verifies checksum.
|
|
2209
|
+
function decodeWords(words, wordlist) {
|
|
2210
|
+
awordlist(wordlist);
|
|
2211
|
+
const entLen = (words.length / 3) * 4; // every 3 words hold 32 entropy bits + 1 checksum bit
|
|
2212
|
+
const bytes = new Uint8Array(entLen + 1); // entropy || checksum byte
|
|
2213
|
+
let carry = 0; // bit accumulator, holds < 19 bits
|
|
2214
|
+
let bits = 0;
|
|
2215
|
+
let pos = 0;
|
|
2216
|
+
for (const word of words) {
|
|
2217
|
+
const index = wordlist.indexOf(word);
|
|
2218
|
+
if (index === -1)
|
|
2219
|
+
throw new Error('Unknown word: ' + word);
|
|
2220
|
+
carry = (carry << 11) | index;
|
|
2221
|
+
bits += 11;
|
|
2222
|
+
while (bits >= 8) {
|
|
2223
|
+
bits -= 8;
|
|
2224
|
+
bytes[pos++] = (carry >>> bits) & 0xff;
|
|
2225
|
+
}
|
|
2226
|
+
carry &= (1 << bits) - 1;
|
|
2227
|
+
}
|
|
2228
|
+
// Left-align leftover checksum bits, matching calcChecksum output.
|
|
2229
|
+
if (bits > 0)
|
|
2230
|
+
bytes[pos] = carry << (8 - bits);
|
|
2231
|
+
const entropy = bytes.subarray(0, entLen);
|
|
2232
|
+
if (bytes[entLen] !== calcChecksum(entropy))
|
|
2233
|
+
throw new Error('Invalid checksum');
|
|
2234
|
+
return Uint8Array.from(entropy);
|
|
2247
2235
|
}
|
|
2248
2236
|
/**
|
|
2249
2237
|
* Reversible: Converts mnemonic string to raw entropy in form of byte array.
|
|
@@ -2267,12 +2255,37 @@ function getCoder(wordlist) {
|
|
|
2267
2255
|
* ])
|
|
2268
2256
|
* ```
|
|
2269
2257
|
*/
|
|
2270
|
-
function mnemonicToEntropy(mnemonic, wordlist) {
|
|
2258
|
+
function mnemonicToEntropy$1(mnemonic, wordlist) {
|
|
2271
2259
|
const { words } = normalize(mnemonic);
|
|
2272
|
-
const entropy =
|
|
2260
|
+
const entropy = decodeWords(words, wordlist);
|
|
2273
2261
|
aentropy(entropy);
|
|
2274
2262
|
return entropy;
|
|
2275
2263
|
}
|
|
2264
|
+
/**
|
|
2265
|
+
* Reversible: Converts raw entropy in form of byte array to mnemonic string.
|
|
2266
|
+
* @param entropy - Byte array.
|
|
2267
|
+
* @param wordlist - Imported wordlist for a specific language.
|
|
2268
|
+
* @returns 12-24 words.
|
|
2269
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
2270
|
+
* @throws On wrong argument ranges or values. {@link RangeError}
|
|
2271
|
+
* @example
|
|
2272
|
+
* Convert raw entropy into an English mnemonic.
|
|
2273
|
+
* ```ts
|
|
2274
|
+
* import { entropyToMnemonic } from '@scure/bip39';
|
|
2275
|
+
* import { wordlist } from '@scure/bip39/wordlists/english.js';
|
|
2276
|
+
* const ent = new Uint8Array([
|
|
2277
|
+
* 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
|
|
2278
|
+
* 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f
|
|
2279
|
+
* ]);
|
|
2280
|
+
* const mnemonic = entropyToMnemonic(ent, wordlist);
|
|
2281
|
+
* // 'legal winner thank year wave sausage worth useful legal winner thank yellow'
|
|
2282
|
+
* ```
|
|
2283
|
+
*/
|
|
2284
|
+
function entropyToMnemonic$1(entropy, wordlist) {
|
|
2285
|
+
aentropy(entropy);
|
|
2286
|
+
const words = encodeWords(entropy, wordlist);
|
|
2287
|
+
return words.join(isJapanese(wordlist) ? '\u3000' : ' ');
|
|
2288
|
+
}
|
|
2276
2289
|
/**
|
|
2277
2290
|
* Validates mnemonic for being 12-24 words contained in `wordlist`.
|
|
2278
2291
|
* @param mnemonic - 12-24 words.
|
|
@@ -2292,7 +2305,7 @@ function mnemonicToEntropy(mnemonic, wordlist) {
|
|
|
2292
2305
|
*/
|
|
2293
2306
|
function validateMnemonic(mnemonic, wordlist) {
|
|
2294
2307
|
try {
|
|
2295
|
-
mnemonicToEntropy(mnemonic, wordlist);
|
|
2308
|
+
mnemonicToEntropy$1(mnemonic, wordlist);
|
|
2296
2309
|
}
|
|
2297
2310
|
catch (e) {
|
|
2298
2311
|
return false;
|
|
@@ -2300,7 +2313,11 @@ function validateMnemonic(mnemonic, wordlist) {
|
|
|
2300
2313
|
return true;
|
|
2301
2314
|
}
|
|
2302
2315
|
// BIP-39 salts PBKDF2 with the UTF-8 NFKD string "mnemonic" + passphrase.
|
|
2303
|
-
const psalt = (passphrase) =>
|
|
2316
|
+
const psalt = (passphrase) => {
|
|
2317
|
+
if (typeof passphrase !== 'string')
|
|
2318
|
+
throw new TypeError('invalid passphrase type: ' + typeof passphrase);
|
|
2319
|
+
return nfkd('mnemonic' + passphrase);
|
|
2320
|
+
};
|
|
2304
2321
|
/**
|
|
2305
2322
|
* Irreversible: Uses KDF to derive 64 bytes of key data from mnemonic + optional password.
|
|
2306
2323
|
* @param mnemonic - 12-24 words.
|
|
@@ -4487,7 +4504,7 @@ class PrivateKey {
|
|
|
4487
4504
|
const privateKeyUint8 = new Uint8Array(privateKeyBytes);
|
|
4488
4505
|
const publicKey = priv.curve === 'secp256k1'
|
|
4489
4506
|
? secp256k1.getPublicKey(privateKeyUint8, true) // compressed public key
|
|
4490
|
-
: p256
|
|
4507
|
+
: p256.getPublicKey(privateKeyUint8, true); // compressed public key
|
|
4491
4508
|
this.keyPair = {
|
|
4492
4509
|
curve: priv.curve,
|
|
4493
4510
|
secretKey: priv.secretKey,
|
|
@@ -4514,7 +4531,7 @@ class PrivateKey {
|
|
|
4514
4531
|
curveOrder = new BN(secp256k1.Point.CURVE().n.toString());
|
|
4515
4532
|
}
|
|
4516
4533
|
else {
|
|
4517
|
-
curveOrder = new BN(p256
|
|
4534
|
+
curveOrder = new BN(p256.Point.CURVE().n.toString());
|
|
4518
4535
|
}
|
|
4519
4536
|
if (curveOrder.bitLength() !== 256) {
|
|
4520
4537
|
throw new InvalidBitSize(`Invalid curve "${curve}" with bit size "${curveOrder.bitLength()}" expecting bit size "256"`);
|
|
@@ -4564,7 +4581,7 @@ class PrivateKey {
|
|
|
4564
4581
|
curveOrder = new BN(secp256k1.Point.CURVE().n.toString());
|
|
4565
4582
|
}
|
|
4566
4583
|
else {
|
|
4567
|
-
curveOrder = new BN(p256
|
|
4584
|
+
curveOrder = new BN(p256.Point.CURVE().n.toString());
|
|
4568
4585
|
}
|
|
4569
4586
|
if (d.cmp(curveOrder) < 0) {
|
|
4570
4587
|
d = d.add(this.keyPair.secretKey).mod(curveOrder);
|
|
@@ -4682,6 +4699,73 @@ const generateSecretKey = (seed, derivationPath, curve) => {
|
|
|
4682
4699
|
}
|
|
4683
4700
|
};
|
|
4684
4701
|
|
|
4702
|
+
/**
|
|
4703
|
+
* Converts an English BIP39 mnemonic to entropy bytes.
|
|
4704
|
+
* @throws InvalidMnemonicError for an invalid phrase, without including its text.
|
|
4705
|
+
*/
|
|
4706
|
+
function mnemonicToEntropy(mnemonic) {
|
|
4707
|
+
try {
|
|
4708
|
+
return mnemonicToEntropy$1(mnemonic, wordlist);
|
|
4709
|
+
}
|
|
4710
|
+
catch {
|
|
4711
|
+
throw new InvalidMnemonicError();
|
|
4712
|
+
}
|
|
4713
|
+
}
|
|
4714
|
+
/**
|
|
4715
|
+
* Converts 16, 20, 24, 28 or 32 entropy bytes to an English BIP39 mnemonic.
|
|
4716
|
+
* Strings must contain unprefixed, even-length hexadecimal. Leading zeros matter.
|
|
4717
|
+
*/
|
|
4718
|
+
function entropyToMnemonic(entropy) {
|
|
4719
|
+
let bytes;
|
|
4720
|
+
if (typeof entropy === 'string') {
|
|
4721
|
+
if (!/^(?:[0-9a-fA-F]{2})+$/.test(entropy)) {
|
|
4722
|
+
throw new Error('Entropy must be unprefixed, even-length hexadecimal');
|
|
4723
|
+
}
|
|
4724
|
+
bytes = Uint8Array.from({ length: entropy.length / 2 }, (_, index) => parseInt(entropy.slice(index * 2, index * 2 + 2), 16));
|
|
4725
|
+
}
|
|
4726
|
+
else {
|
|
4727
|
+
if (!(entropy instanceof Uint8Array) &&
|
|
4728
|
+
!(ArrayBuffer.isView(entropy) &&
|
|
4729
|
+
Object.prototype.toString.call(entropy) === '[object Uint8Array]')) {
|
|
4730
|
+
throw new TypeError('Entropy must be a Uint8Array');
|
|
4731
|
+
}
|
|
4732
|
+
bytes = new Uint8Array(entropy);
|
|
4733
|
+
}
|
|
4734
|
+
return entropyToMnemonic$1(bytes, wordlist);
|
|
4735
|
+
}
|
|
4736
|
+
/**
|
|
4737
|
+
* Generates an English BIP39 mnemonic with the dependency's secure random source.
|
|
4738
|
+
* @param strength Entropy bits, 128, 160, 192, 224 or 256. Defaults to 128.
|
|
4739
|
+
*/
|
|
4740
|
+
function generateMnemonic(strength = 128) {
|
|
4741
|
+
return generateMnemonic$1(wordlist, strength);
|
|
4742
|
+
}
|
|
4743
|
+
// Shared with the signer, but not exported from the package entrypoint.
|
|
4744
|
+
function deriveMnemonicSecretKey({ mnemonic, password = '', derivationPath = "44'/1729'/0'/0'", curve = 'ed25519', }) {
|
|
4745
|
+
if (!validateMnemonic(mnemonic, wordlist)) {
|
|
4746
|
+
throw new InvalidMnemonicError();
|
|
4747
|
+
}
|
|
4748
|
+
const seed = mnemonicToSeedSync(mnemonic, password);
|
|
4749
|
+
return { secretKey: generateSecretKey(seed, derivationPath, curve), curve };
|
|
4750
|
+
}
|
|
4751
|
+
/**
|
|
4752
|
+
* Derives key material without constructing an InMemorySigner.
|
|
4753
|
+
* Uses the same defaults, English BIP39 phrases, password and paths as fromMnemonic.
|
|
4754
|
+
* Supports Ed25519, secp256k1 and P-256 mnemonic derivation.
|
|
4755
|
+
* The returned secretKey is unencrypted and matches InMemorySigner.secretKey(),
|
|
4756
|
+
* including the expanded Ed25519 form. Avoid logging or sharing the result.
|
|
4757
|
+
*/
|
|
4758
|
+
function deriveKeyFromMnemonic(params) {
|
|
4759
|
+
const { secretKey, curve } = deriveMnemonicSecretKey(params);
|
|
4760
|
+
const key = curve === 'ed25519' ? new EdKey(secretKey) : new ECKey(secretKey);
|
|
4761
|
+
const publicKey = key.publicKey();
|
|
4762
|
+
return {
|
|
4763
|
+
publicKey: String(publicKey),
|
|
4764
|
+
publicKeyHash: publicKey.hash(),
|
|
4765
|
+
secretKey: key.secretKey(),
|
|
4766
|
+
};
|
|
4767
|
+
}
|
|
4768
|
+
|
|
4685
4769
|
function isPOP(k) {
|
|
4686
4770
|
return 'provePossession' in k;
|
|
4687
4771
|
}
|
|
@@ -4724,8 +4808,21 @@ class BLSKey {
|
|
|
4724
4808
|
sign(message) {
|
|
4725
4809
|
return this.signDst(message, BLS12_381_DST);
|
|
4726
4810
|
}
|
|
4727
|
-
provePossession() {
|
|
4728
|
-
|
|
4811
|
+
provePossession(overridePublicKey) {
|
|
4812
|
+
let message = __classPrivateFieldGet(this, _BLSKey_publicKey, "f");
|
|
4813
|
+
if (overridePublicKey !== undefined) {
|
|
4814
|
+
try {
|
|
4815
|
+
if (typeof overridePublicKey !== 'string')
|
|
4816
|
+
throw new Error('Expected a public key');
|
|
4817
|
+
message = b58DecodeAndCheckPrefix(overridePublicKey, [PrefixV2.BLS12_381PublicKey], true);
|
|
4818
|
+
// Match Octez's compressed G1 parser, including subgroup checks and its accepted infinity encoding.
|
|
4819
|
+
bls12_381.G1.Point.fromBytes(message).assertValidity();
|
|
4820
|
+
}
|
|
4821
|
+
catch {
|
|
4822
|
+
throw new InvalidPublicKeyError('BLS override public key', 'Expecting a valid BLS public key');
|
|
4823
|
+
}
|
|
4824
|
+
}
|
|
4825
|
+
return this.signDst(message, POP_DST);
|
|
4729
4826
|
}
|
|
4730
4827
|
publicKey() {
|
|
4731
4828
|
return new BLSPublicKey(__classPrivateFieldGet(this, _BLSKey_publicKey, "f"));
|
|
@@ -7311,15 +7408,9 @@ class InMemorySigner {
|
|
|
7311
7408
|
* @returns InMemorySigner
|
|
7312
7409
|
* @throws InvalidMnemonicError
|
|
7313
7410
|
*/
|
|
7314
|
-
static fromMnemonic(
|
|
7315
|
-
|
|
7316
|
-
|
|
7317
|
-
// avoiding exposing mnemonic again in case of mistake making invalid
|
|
7318
|
-
throw new InvalidMnemonicError();
|
|
7319
|
-
}
|
|
7320
|
-
const seed = mnemonicToSeedSync(mnemonic, password);
|
|
7321
|
-
const sk = generateSecretKey(seed, derivationPath, curve);
|
|
7322
|
-
return new InMemorySigner(sk);
|
|
7411
|
+
static fromMnemonic(params) {
|
|
7412
|
+
const { secretKey } = deriveMnemonicSecretKey(params);
|
|
7413
|
+
return new InMemorySigner(secretKey);
|
|
7323
7414
|
}
|
|
7324
7415
|
/**
|
|
7325
7416
|
*
|
|
@@ -7423,9 +7514,9 @@ class InMemorySigner {
|
|
|
7423
7514
|
sbytes: buf2hex(mergebuf(msg, signatureBytes)),
|
|
7424
7515
|
};
|
|
7425
7516
|
}
|
|
7426
|
-
async provePossession() {
|
|
7517
|
+
async provePossession(overridePublicKey) {
|
|
7427
7518
|
if (isPOP(__classPrivateFieldGet(this, _InMemorySigner_key, "f"))) {
|
|
7428
|
-
return __classPrivateFieldGet(this, _InMemorySigner_key, "f").provePossession();
|
|
7519
|
+
return __classPrivateFieldGet(this, _InMemorySigner_key, "f").provePossession(overridePublicKey);
|
|
7429
7520
|
}
|
|
7430
7521
|
else {
|
|
7431
7522
|
throw new ProhibitedActionError('Only BLS keys can prove possession');
|
|
@@ -7478,9 +7569,9 @@ function publicKeyFromString(src) {
|
|
|
7478
7569
|
|
|
7479
7570
|
// IMPORTANT: THIS FILE IS AUTO GENERATED! DO NOT MANUALLY EDIT!
|
|
7480
7571
|
const VERSION = {
|
|
7481
|
-
"commitHash": "
|
|
7482
|
-
"version": "25.
|
|
7572
|
+
"commitHash": "78ca0b9cb430f230c3230cd28b7e89a310e84c15",
|
|
7573
|
+
"version": "25.2.0-beta0"
|
|
7483
7574
|
};
|
|
7484
7575
|
|
|
7485
|
-
export { ecdsa as ECDSA, ed25519 as Ed25519, Hard, InMemorySigner, InvalidPassphraseError, Path, VERSION, generateSecretKey, publicKeyFromString };
|
|
7576
|
+
export { ecdsa as ECDSA, ed25519 as Ed25519, Hard, InMemorySigner, InvalidMnemonicError, InvalidPassphraseError, Path, VERSION, deriveKeyFromMnemonic, entropyToMnemonic, generateMnemonic, generateSecretKey, mnemonicToEntropy, publicKeyFromString };
|
|
7486
7577
|
//# sourceMappingURL=taquito-signer.es6.js.map
|