@taquito/sapling 24.3.1-beta.1 → 25.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/version.js +2 -2
- package/dist/taquito-sapling.es6.js +369 -85
- package/dist/taquito-sapling.es6.js.map +1 -1
- package/dist/taquito-sapling.umd.js +369 -85
- package/dist/taquito-sapling.umd.js.map +1 -1
- package/dist/types/node_modules/@scure/base/index.d.ts +286 -24
- package/package.json +11 -11
|
@@ -3453,73 +3453,196 @@
|
|
|
3453
3453
|
_SaplingTransactionBuilder_inMemorySpendingKey = new WeakMap(), _SaplingTransactionBuilder_inMemoryProvingKey = new WeakMap(), _SaplingTransactionBuilder_saplingForger = new WeakMap(), _SaplingTransactionBuilder_contractAddress = new WeakMap(), _SaplingTransactionBuilder_saplingId = new WeakMap(), _SaplingTransactionBuilder_memoSize = new WeakMap(), _SaplingTransactionBuilder_readProvider = new WeakMap(), _SaplingTransactionBuilder_saplingWrapper = new WeakMap(), _SaplingTransactionBuilder_chainId = new WeakMap(), _SaplingTransactionBuilder_saplingState = new WeakMap();
|
|
3454
3454
|
|
|
3455
3455
|
/**
|
|
3456
|
-
*
|
|
3457
|
-
* @
|
|
3456
|
+
* Checks if something is Uint8Array. Be careful: nodejs Buffer will return true.
|
|
3457
|
+
* @param a - value to test
|
|
3458
|
+
* @returns `true` when the value is a Uint8Array-compatible view.
|
|
3459
|
+
* @example
|
|
3460
|
+
* Check whether a value is a Uint8Array-compatible view.
|
|
3461
|
+
* ```ts
|
|
3462
|
+
* isBytes(new Uint8Array([1, 2, 3]));
|
|
3463
|
+
* ```
|
|
3458
3464
|
*/
|
|
3459
|
-
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
3460
|
-
/** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */
|
|
3461
3465
|
function isBytes(a) {
|
|
3462
|
-
|
|
3466
|
+
// Plain `instanceof Uint8Array` is too strict for some Buffer / proxy / cross-realm cases.
|
|
3467
|
+
// The fallback still requires a real ArrayBuffer view, so plain
|
|
3468
|
+
// JSON-deserialized `{ constructor: ... }` spoofing is rejected, and
|
|
3469
|
+
// `BYTES_PER_ELEMENT === 1` keeps the fallback on byte-oriented views.
|
|
3470
|
+
return (a instanceof Uint8Array ||
|
|
3471
|
+
(ArrayBuffer.isView(a) &&
|
|
3472
|
+
a.constructor.name === 'Uint8Array' &&
|
|
3473
|
+
'BYTES_PER_ELEMENT' in a &&
|
|
3474
|
+
a.BYTES_PER_ELEMENT === 1));
|
|
3463
3475
|
}
|
|
3464
|
-
/**
|
|
3476
|
+
/**
|
|
3477
|
+
* Asserts something is a non-negative integer.
|
|
3478
|
+
* @param n - number to validate
|
|
3479
|
+
* @param title - label included in thrown errors
|
|
3480
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
3481
|
+
* @throws On wrong argument ranges or values. {@link RangeError}
|
|
3482
|
+
* @example
|
|
3483
|
+
* Validate a non-negative integer option.
|
|
3484
|
+
* ```ts
|
|
3485
|
+
* anumber(32, 'length');
|
|
3486
|
+
* ```
|
|
3487
|
+
*/
|
|
3465
3488
|
function anumber(n, title = '') {
|
|
3489
|
+
if (typeof n !== 'number') {
|
|
3490
|
+
const prefix = title && `"${title}" `;
|
|
3491
|
+
throw new TypeError(`${prefix}expected number, got ${typeof n}`);
|
|
3492
|
+
}
|
|
3466
3493
|
if (!Number.isSafeInteger(n) || n < 0) {
|
|
3467
3494
|
const prefix = title && `"${title}" `;
|
|
3468
|
-
throw new
|
|
3495
|
+
throw new RangeError(`${prefix}expected integer >= 0, got ${n}`);
|
|
3469
3496
|
}
|
|
3470
3497
|
}
|
|
3471
|
-
/**
|
|
3498
|
+
/**
|
|
3499
|
+
* Asserts something is Uint8Array.
|
|
3500
|
+
* @param value - value to validate
|
|
3501
|
+
* @param length - optional exact length constraint
|
|
3502
|
+
* @param title - label included in thrown errors
|
|
3503
|
+
* @returns The validated byte array.
|
|
3504
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
3505
|
+
* @throws On wrong argument ranges or values. {@link RangeError}
|
|
3506
|
+
* @example
|
|
3507
|
+
* Validate that a value is a byte array.
|
|
3508
|
+
* ```ts
|
|
3509
|
+
* abytes(new Uint8Array([1, 2, 3]));
|
|
3510
|
+
* ```
|
|
3511
|
+
*/
|
|
3472
3512
|
function abytes(value, length, title = '') {
|
|
3473
3513
|
const bytes = isBytes(value);
|
|
3474
3514
|
const len = value?.length;
|
|
3475
3515
|
const needsLen = length !== undefined;
|
|
3476
|
-
if (!bytes || (needsLen
|
|
3516
|
+
if (!bytes || (needsLen)) {
|
|
3477
3517
|
const prefix = title && `"${title}" `;
|
|
3478
|
-
const ofLen =
|
|
3518
|
+
const ofLen = '';
|
|
3479
3519
|
const got = bytes ? `length=${len}` : `type=${typeof value}`;
|
|
3480
|
-
|
|
3520
|
+
const message = prefix + 'expected Uint8Array' + ofLen + ', got ' + got;
|
|
3521
|
+
if (!bytes)
|
|
3522
|
+
throw new TypeError(message);
|
|
3523
|
+
throw new RangeError(message);
|
|
3481
3524
|
}
|
|
3482
3525
|
return value;
|
|
3483
3526
|
}
|
|
3484
|
-
/**
|
|
3527
|
+
/**
|
|
3528
|
+
* Asserts something is a wrapped hash constructor.
|
|
3529
|
+
* @param h - hash constructor to validate
|
|
3530
|
+
* @throws On wrong argument types or invalid hash wrapper shape. {@link TypeError}
|
|
3531
|
+
* @throws On invalid hash metadata ranges or values. {@link RangeError}
|
|
3532
|
+
* @throws If the hash metadata allows empty outputs or block sizes. {@link Error}
|
|
3533
|
+
* @example
|
|
3534
|
+
* Validate a callable hash wrapper.
|
|
3535
|
+
* ```ts
|
|
3536
|
+
* import { ahash } from '@noble/hashes/utils.js';
|
|
3537
|
+
* import { sha256 } from '@noble/hashes/sha2.js';
|
|
3538
|
+
* ahash(sha256);
|
|
3539
|
+
* ```
|
|
3540
|
+
*/
|
|
3485
3541
|
function ahash(h) {
|
|
3486
3542
|
if (typeof h !== 'function' || typeof h.create !== 'function')
|
|
3487
|
-
throw new
|
|
3543
|
+
throw new TypeError('Hash must wrapped by utils.createHasher');
|
|
3488
3544
|
anumber(h.outputLen);
|
|
3489
3545
|
anumber(h.blockLen);
|
|
3546
|
+
// HMAC and KDF callers treat these as real byte lengths; allowing zero lets fake wrappers pass
|
|
3547
|
+
// validation and can produce empty outputs instead of failing fast.
|
|
3548
|
+
if (h.outputLen < 1)
|
|
3549
|
+
throw new Error('"outputLen" must be >= 1');
|
|
3550
|
+
if (h.blockLen < 1)
|
|
3551
|
+
throw new Error('"blockLen" must be >= 1');
|
|
3490
3552
|
}
|
|
3491
|
-
/**
|
|
3553
|
+
/**
|
|
3554
|
+
* Asserts a hash instance has not been destroyed or finished.
|
|
3555
|
+
* @param instance - hash instance to validate
|
|
3556
|
+
* @param checkFinished - whether to reject finalized instances
|
|
3557
|
+
* @throws If the hash instance has already been destroyed or finalized. {@link Error}
|
|
3558
|
+
* @example
|
|
3559
|
+
* Validate that a hash instance is still usable.
|
|
3560
|
+
* ```ts
|
|
3561
|
+
* import { aexists } from '@noble/hashes/utils.js';
|
|
3562
|
+
* import { sha256 } from '@noble/hashes/sha2.js';
|
|
3563
|
+
* const hash = sha256.create();
|
|
3564
|
+
* aexists(hash);
|
|
3565
|
+
* ```
|
|
3566
|
+
*/
|
|
3492
3567
|
function aexists(instance, checkFinished = true) {
|
|
3493
3568
|
if (instance.destroyed)
|
|
3494
3569
|
throw new Error('Hash instance has been destroyed');
|
|
3495
3570
|
if (checkFinished && instance.finished)
|
|
3496
3571
|
throw new Error('Hash#digest() has already been called');
|
|
3497
3572
|
}
|
|
3498
|
-
/**
|
|
3573
|
+
/**
|
|
3574
|
+
* Asserts output is a sufficiently-sized byte array.
|
|
3575
|
+
* @param out - destination buffer
|
|
3576
|
+
* @param instance - hash instance providing output length
|
|
3577
|
+
* Oversized buffers are allowed; downstream code only promises to fill the first `outputLen` bytes.
|
|
3578
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
3579
|
+
* @throws On wrong argument ranges or values. {@link RangeError}
|
|
3580
|
+
* @example
|
|
3581
|
+
* Validate a caller-provided digest buffer.
|
|
3582
|
+
* ```ts
|
|
3583
|
+
* import { aoutput } from '@noble/hashes/utils.js';
|
|
3584
|
+
* import { sha256 } from '@noble/hashes/sha2.js';
|
|
3585
|
+
* const hash = sha256.create();
|
|
3586
|
+
* aoutput(new Uint8Array(hash.outputLen), hash);
|
|
3587
|
+
* ```
|
|
3588
|
+
*/
|
|
3499
3589
|
function aoutput(out, instance) {
|
|
3500
3590
|
abytes(out, undefined, 'digestInto() output');
|
|
3501
3591
|
const min = instance.outputLen;
|
|
3502
3592
|
if (out.length < min) {
|
|
3503
|
-
throw new
|
|
3593
|
+
throw new RangeError('"digestInto() output" expected to be of length >=' + min);
|
|
3504
3594
|
}
|
|
3505
3595
|
}
|
|
3506
|
-
/**
|
|
3596
|
+
/**
|
|
3597
|
+
* Zeroizes typed arrays in place. Warning: JS provides no guarantees.
|
|
3598
|
+
* @param arrays - arrays to overwrite with zeros
|
|
3599
|
+
* @example
|
|
3600
|
+
* Zeroize sensitive buffers in place.
|
|
3601
|
+
* ```ts
|
|
3602
|
+
* clean(new Uint8Array([1, 2, 3]));
|
|
3603
|
+
* ```
|
|
3604
|
+
*/
|
|
3507
3605
|
function clean(...arrays) {
|
|
3508
3606
|
for (let i = 0; i < arrays.length; i++) {
|
|
3509
3607
|
arrays[i].fill(0);
|
|
3510
3608
|
}
|
|
3511
3609
|
}
|
|
3512
|
-
/**
|
|
3610
|
+
/**
|
|
3611
|
+
* Creates a DataView for byte-level manipulation.
|
|
3612
|
+
* @param arr - source typed array
|
|
3613
|
+
* @returns DataView over the same buffer region.
|
|
3614
|
+
* @example
|
|
3615
|
+
* Create a DataView over an existing buffer.
|
|
3616
|
+
* ```ts
|
|
3617
|
+
* createView(new Uint8Array(4));
|
|
3618
|
+
* ```
|
|
3619
|
+
*/
|
|
3513
3620
|
function createView(arr) {
|
|
3514
3621
|
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
3515
3622
|
}
|
|
3516
3623
|
/**
|
|
3517
3624
|
* There is no setImmediate in browser and setTimeout is slow.
|
|
3518
|
-
*
|
|
3519
|
-
*
|
|
3625
|
+
* This yields to the Promise/microtask scheduler queue, not to timers or the
|
|
3626
|
+
* full macrotask event loop.
|
|
3627
|
+
* @example
|
|
3628
|
+
* Yield to the next scheduler tick.
|
|
3629
|
+
* ```ts
|
|
3630
|
+
* await nextTick();
|
|
3631
|
+
* ```
|
|
3520
3632
|
*/
|
|
3521
3633
|
const nextTick = async () => { };
|
|
3522
|
-
/**
|
|
3634
|
+
/**
|
|
3635
|
+
* Returns control to the Promise/microtask scheduler every `tick`
|
|
3636
|
+
* milliseconds to avoid blocking long loops.
|
|
3637
|
+
* @param iters - number of loop iterations to run
|
|
3638
|
+
* @param tick - maximum time slice in milliseconds
|
|
3639
|
+
* @param cb - callback executed on each iteration
|
|
3640
|
+
* @example
|
|
3641
|
+
* Run a loop that periodically yields back to the event loop.
|
|
3642
|
+
* ```ts
|
|
3643
|
+
* await asyncLoop(2, 0, () => {});
|
|
3644
|
+
* ```
|
|
3645
|
+
*/
|
|
3523
3646
|
async function asyncLoop(iters, tick, cb) {
|
|
3524
3647
|
let ts = Date.now();
|
|
3525
3648
|
for (let i = 0; i < iters; i++) {
|
|
@@ -3535,41 +3658,101 @@
|
|
|
3535
3658
|
/**
|
|
3536
3659
|
* Converts string to bytes using UTF8 encoding.
|
|
3537
3660
|
* Built-in doesn't validate input to be string: we do the check.
|
|
3538
|
-
*
|
|
3661
|
+
* Non-ASCII details are delegated to the platform `TextEncoder`.
|
|
3662
|
+
* @param str - string to encode
|
|
3663
|
+
* @returns UTF-8 encoded bytes.
|
|
3664
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
3665
|
+
* @example
|
|
3666
|
+
* Encode a string as UTF-8 bytes.
|
|
3667
|
+
* ```ts
|
|
3668
|
+
* utf8ToBytes('abc'); // Uint8Array.from([97, 98, 99])
|
|
3669
|
+
* ```
|
|
3539
3670
|
*/
|
|
3540
3671
|
function utf8ToBytes(str) {
|
|
3541
3672
|
if (typeof str !== 'string')
|
|
3542
|
-
throw new
|
|
3673
|
+
throw new TypeError('string expected');
|
|
3543
3674
|
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
|
3544
3675
|
}
|
|
3545
3676
|
/**
|
|
3546
|
-
* Helper for KDFs: consumes
|
|
3547
|
-
*
|
|
3677
|
+
* Helper for KDFs: consumes Uint8Array or string.
|
|
3678
|
+
* String inputs are UTF-8 encoded; byte-array inputs stay aliased to the caller buffer.
|
|
3679
|
+
* @param data - user-provided KDF input
|
|
3680
|
+
* @param errorTitle - label included in thrown errors
|
|
3681
|
+
* @returns Byte representation of the input.
|
|
3682
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
3683
|
+
* @example
|
|
3684
|
+
* Normalize KDF input to bytes.
|
|
3685
|
+
* ```ts
|
|
3686
|
+
* kdfInputToBytes('password');
|
|
3687
|
+
* ```
|
|
3548
3688
|
*/
|
|
3549
3689
|
function kdfInputToBytes(data, errorTitle = '') {
|
|
3550
3690
|
if (typeof data === 'string')
|
|
3551
3691
|
return utf8ToBytes(data);
|
|
3552
3692
|
return abytes(data, undefined, errorTitle);
|
|
3553
3693
|
}
|
|
3554
|
-
/**
|
|
3694
|
+
/**
|
|
3695
|
+
* Merges default options and passed options.
|
|
3696
|
+
* @param defaults - base option object
|
|
3697
|
+
* @param opts - user overrides
|
|
3698
|
+
* @returns Merged option object. The merge mutates `defaults` in place.
|
|
3699
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
3700
|
+
* @example
|
|
3701
|
+
* Merge user overrides onto default options.
|
|
3702
|
+
* ```ts
|
|
3703
|
+
* checkOpts({ dkLen: 32 }, { asyncTick: 10 });
|
|
3704
|
+
* ```
|
|
3705
|
+
*/
|
|
3555
3706
|
function checkOpts(defaults, opts) {
|
|
3556
3707
|
if (opts !== undefined && {}.toString.call(opts) !== '[object Object]')
|
|
3557
|
-
throw new
|
|
3708
|
+
throw new TypeError('options must be object or undefined');
|
|
3558
3709
|
const merged = Object.assign(defaults, opts);
|
|
3559
3710
|
return merged;
|
|
3560
3711
|
}
|
|
3561
|
-
/**
|
|
3712
|
+
/**
|
|
3713
|
+
* Creates a callable hash function from a stateful class constructor.
|
|
3714
|
+
* @param hashCons - hash constructor or factory
|
|
3715
|
+
* @param info - optional metadata such as DER OID
|
|
3716
|
+
* @returns Frozen callable hash wrapper with `.create()`.
|
|
3717
|
+
* Wrapper construction eagerly calls `hashCons(undefined)` once to read
|
|
3718
|
+
* `outputLen` / `blockLen`, so constructor side effects happen at module
|
|
3719
|
+
* init time.
|
|
3720
|
+
* @example
|
|
3721
|
+
* Wrap a stateful hash constructor into a callable helper.
|
|
3722
|
+
* ```ts
|
|
3723
|
+
* import { createHasher } from '@noble/hashes/utils.js';
|
|
3724
|
+
* import { sha256 } from '@noble/hashes/sha2.js';
|
|
3725
|
+
* const wrapped = createHasher(sha256.create, { oid: sha256.oid });
|
|
3726
|
+
* wrapped(new Uint8Array([1]));
|
|
3727
|
+
* ```
|
|
3728
|
+
*/
|
|
3562
3729
|
function createHasher(hashCons, info = {}) {
|
|
3563
|
-
const hashC = (msg, opts) => hashCons(opts)
|
|
3730
|
+
const hashC = (msg, opts) => hashCons(opts)
|
|
3731
|
+
.update(msg)
|
|
3732
|
+
.digest();
|
|
3564
3733
|
const tmp = hashCons(undefined);
|
|
3565
3734
|
hashC.outputLen = tmp.outputLen;
|
|
3566
3735
|
hashC.blockLen = tmp.blockLen;
|
|
3736
|
+
hashC.canXOF = tmp.canXOF;
|
|
3567
3737
|
hashC.create = (opts) => hashCons(opts);
|
|
3568
3738
|
Object.assign(hashC, info);
|
|
3569
3739
|
return Object.freeze(hashC);
|
|
3570
3740
|
}
|
|
3571
|
-
/**
|
|
3741
|
+
/**
|
|
3742
|
+
* Creates OID metadata for NIST hashes with prefix `06 09 60 86 48 01 65 03 04 02`.
|
|
3743
|
+
* @param suffix - final OID byte for the selected hash.
|
|
3744
|
+
* The helper accepts any byte even though only the documented NIST hash
|
|
3745
|
+
* suffixes are meaningful downstream.
|
|
3746
|
+
* @returns Object containing the DER-encoded OID.
|
|
3747
|
+
* @example
|
|
3748
|
+
* Build OID metadata for a NIST hash.
|
|
3749
|
+
* ```ts
|
|
3750
|
+
* oidNist(0x01);
|
|
3751
|
+
* ```
|
|
3752
|
+
*/
|
|
3572
3753
|
const oidNist = (suffix) => ({
|
|
3754
|
+
// Current NIST hashAlgs suffixes used here fit in one DER subidentifier octet.
|
|
3755
|
+
// Larger suffix values would need base-128 OID encoding and a different length byte.
|
|
3573
3756
|
oid: Uint8Array.from([0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, suffix]),
|
|
3574
3757
|
});
|
|
3575
3758
|
|
|
@@ -3577,12 +3760,17 @@
|
|
|
3577
3760
|
* HMAC: RFC2104 message authentication code.
|
|
3578
3761
|
* @module
|
|
3579
3762
|
*/
|
|
3580
|
-
/**
|
|
3763
|
+
/**
|
|
3764
|
+
* Internal class for HMAC.
|
|
3765
|
+
* Accepts any byte key, although RFC 2104 §3 recommends keys at least
|
|
3766
|
+
* `HashLen` bytes long.
|
|
3767
|
+
*/
|
|
3581
3768
|
class _HMAC {
|
|
3582
3769
|
oHash;
|
|
3583
3770
|
iHash;
|
|
3584
3771
|
blockLen;
|
|
3585
3772
|
outputLen;
|
|
3773
|
+
canXOF = false;
|
|
3586
3774
|
finished = false;
|
|
3587
3775
|
destroyed = false;
|
|
3588
3776
|
constructor(hash, key) {
|
|
@@ -3600,7 +3788,8 @@
|
|
|
3600
3788
|
for (let i = 0; i < pad.length; i++)
|
|
3601
3789
|
pad[i] ^= 0x36;
|
|
3602
3790
|
this.iHash.update(pad);
|
|
3603
|
-
// By doing update (processing of first block) of outer hash here
|
|
3791
|
+
// By doing update (processing of the first block) of the outer hash here,
|
|
3792
|
+
// we can re-use it between multiple calls via clone.
|
|
3604
3793
|
this.oHash = hash.create();
|
|
3605
3794
|
// Undo internal XOR && apply outer XOR
|
|
3606
3795
|
for (let i = 0; i < pad.length; i++)
|
|
@@ -3615,11 +3804,14 @@
|
|
|
3615
3804
|
}
|
|
3616
3805
|
digestInto(out) {
|
|
3617
3806
|
aexists(this);
|
|
3618
|
-
|
|
3807
|
+
aoutput(out, this);
|
|
3619
3808
|
this.finished = true;
|
|
3620
|
-
this.
|
|
3621
|
-
|
|
3622
|
-
|
|
3809
|
+
const buf = out.subarray(0, this.outputLen);
|
|
3810
|
+
// Reuse the first outputLen bytes for the inner digest; the outer hash consumes them before
|
|
3811
|
+
// overwriting that same prefix with the final tag, leaving any oversized tail untouched.
|
|
3812
|
+
this.iHash.digestInto(buf);
|
|
3813
|
+
this.oHash.update(buf);
|
|
3814
|
+
this.oHash.digestInto(buf);
|
|
3623
3815
|
this.destroy();
|
|
3624
3816
|
}
|
|
3625
3817
|
digest() {
|
|
@@ -3628,7 +3820,8 @@
|
|
|
3628
3820
|
return out;
|
|
3629
3821
|
}
|
|
3630
3822
|
_cloneInto(to) {
|
|
3631
|
-
// Create new instance without calling constructor since key
|
|
3823
|
+
// Create new instance without calling constructor since the key
|
|
3824
|
+
// is already in state and we don't know it.
|
|
3632
3825
|
to ||= Object.create(Object.getPrototypeOf(this), {});
|
|
3633
3826
|
const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
|
|
3634
3827
|
to = to;
|
|
@@ -3649,18 +3842,11 @@
|
|
|
3649
3842
|
this.iHash.destroy();
|
|
3650
3843
|
}
|
|
3651
3844
|
}
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
* @example
|
|
3658
|
-
* import { hmac } from '@noble/hashes/hmac';
|
|
3659
|
-
* import { sha256 } from '@noble/hashes/sha2';
|
|
3660
|
-
* const mac1 = hmac(sha256, 'key', 'message');
|
|
3661
|
-
*/
|
|
3662
|
-
const hmac = (hash, key, message) => new _HMAC(hash, key).update(message).digest();
|
|
3663
|
-
hmac.create = (hash, key) => new _HMAC(hash, key);
|
|
3845
|
+
const hmac = /* @__PURE__ */ (() => {
|
|
3846
|
+
const hmac_ = ((hash, key, message) => new _HMAC(hash, key).update(message).digest());
|
|
3847
|
+
hmac_.create = (hash, key) => new _HMAC(hash, key);
|
|
3848
|
+
return hmac_;
|
|
3849
|
+
})();
|
|
3664
3850
|
|
|
3665
3851
|
/**
|
|
3666
3852
|
* PBKDF (RFC 2898). Can be used to create a key from password and salt.
|
|
@@ -3676,16 +3862,26 @@
|
|
|
3676
3862
|
anumber(asyncTick, 'asyncTick');
|
|
3677
3863
|
if (c < 1)
|
|
3678
3864
|
throw new Error('iterations (c) must be >= 1');
|
|
3865
|
+
// RFC 8018 §5.2 defines `dkLen` as "a positive integer".
|
|
3866
|
+
if (dkLen < 1)
|
|
3867
|
+
throw new Error('"dkLen" must be >= 1');
|
|
3868
|
+
// RFC 8018 §5.2 step 1 requires rejecting oversize `dkLen`
|
|
3869
|
+
// before allocating the destination buffer.
|
|
3870
|
+
if (dkLen > (2 ** 32 - 1) * hash.outputLen)
|
|
3871
|
+
throw new Error('derived key too long');
|
|
3679
3872
|
const password = kdfInputToBytes(_password, 'password');
|
|
3680
3873
|
const salt = kdfInputToBytes(_salt, 'salt');
|
|
3681
3874
|
// DK = PBKDF2(PRF, Password, Salt, c, dkLen);
|
|
3682
3875
|
const DK = new Uint8Array(dkLen);
|
|
3683
3876
|
// U1 = PRF(Password, Salt + INT_32_BE(i))
|
|
3684
3877
|
const PRF = hmac.create(hash, password);
|
|
3878
|
+
// Cache PRF(P, S || ...) prefix state so each block only appends INT_32_BE(i).
|
|
3685
3879
|
const PRFSalt = PRF._cloneInto().update(salt);
|
|
3686
3880
|
return { c, dkLen, asyncTick, DK, PRF, PRFSalt };
|
|
3687
3881
|
}
|
|
3688
3882
|
function pbkdf2Output(PRF, PRFSalt, DK, prfW, u) {
|
|
3883
|
+
// Shared sync/async cleanup point: wipe transient PRF state
|
|
3884
|
+
// while preserving the derived key buffer.
|
|
3689
3885
|
PRF.destroy();
|
|
3690
3886
|
PRFSalt.destroy();
|
|
3691
3887
|
if (prfW)
|
|
@@ -3694,13 +3890,22 @@
|
|
|
3694
3890
|
return DK;
|
|
3695
3891
|
}
|
|
3696
3892
|
/**
|
|
3697
|
-
* PBKDF2-HMAC: RFC
|
|
3893
|
+
* PBKDF2-HMAC: RFC 8018 key derivation function.
|
|
3698
3894
|
* @param hash - hash function that would be used e.g. sha256
|
|
3699
|
-
* @param password - password from which a derived key is generated
|
|
3700
|
-
*
|
|
3701
|
-
* @param
|
|
3895
|
+
* @param password - password from which a derived key is generated;
|
|
3896
|
+
* JS string inputs are UTF-8 encoded first
|
|
3897
|
+
* @param salt - cryptographic salt; JS string inputs are UTF-8 encoded first
|
|
3898
|
+
* @param opts - PBKDF2 work factor and output settings. `dkLen`, if provided,
|
|
3899
|
+
* must be `>= 1` per RFC 8018 §5.2. See {@link Pbkdf2Opt}.
|
|
3900
|
+
* @returns Derived key bytes.
|
|
3901
|
+
* @throws If the PBKDF2 iteration count or derived-key settings are invalid. {@link Error}
|
|
3702
3902
|
* @example
|
|
3903
|
+
* PBKDF2-HMAC: RFC 2898 key derivation function.
|
|
3904
|
+
* ```ts
|
|
3905
|
+
* import { pbkdf2 } from '@noble/hashes/pbkdf2.js';
|
|
3906
|
+
* import { sha256 } from '@noble/hashes/sha2.js';
|
|
3703
3907
|
* const key = pbkdf2(sha256, 'password', 'salt', { dkLen: 32, c: Math.pow(2, 18) });
|
|
3908
|
+
* ```
|
|
3704
3909
|
*/
|
|
3705
3910
|
function pbkdf2(hash, password, salt, opts) {
|
|
3706
3911
|
const { c, dkLen, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);
|
|
@@ -3711,6 +3916,8 @@
|
|
|
3711
3916
|
// DK = T1 + T2 + ⋯ + Tdklen/hlen
|
|
3712
3917
|
for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {
|
|
3713
3918
|
// Ti = F(Password, Salt, c, i)
|
|
3919
|
+
// The last Ti view can be shorter than hLen, which applies
|
|
3920
|
+
// RFC 8018 §5.2 step 4's T_l<0..r-1> truncation without extra copies.
|
|
3714
3921
|
const Ti = DK.subarray(pos, pos + PRF.outputLen);
|
|
3715
3922
|
view.setInt32(0, ti, false);
|
|
3716
3923
|
// F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc
|
|
@@ -3727,9 +3934,24 @@
|
|
|
3727
3934
|
return pbkdf2Output(PRF, PRFSalt, DK, prfW, u);
|
|
3728
3935
|
}
|
|
3729
3936
|
/**
|
|
3730
|
-
* PBKDF2-HMAC: RFC
|
|
3937
|
+
* PBKDF2-HMAC: RFC 8018 key derivation function. Async version.
|
|
3938
|
+
* @param hash - hash function that would be used e.g. sha256
|
|
3939
|
+
* @param password - password from which a derived key is generated;
|
|
3940
|
+
* JS string inputs are UTF-8 encoded first
|
|
3941
|
+
* @param salt - cryptographic salt; JS string inputs are UTF-8 encoded first
|
|
3942
|
+
* @param opts - PBKDF2 work factor and output settings. `dkLen`, if provided,
|
|
3943
|
+
* must be `>= 1` per RFC 8018 §5.2. `asyncTick` is only a local
|
|
3944
|
+
* scheduler-yield knob for this JS wrapper, not part of RFC 8018.
|
|
3945
|
+
* See {@link Pbkdf2Opt}.
|
|
3946
|
+
* @returns Promise resolving to derived key bytes.
|
|
3947
|
+
* @throws If the PBKDF2 iteration count or derived-key settings are invalid. {@link Error}
|
|
3731
3948
|
* @example
|
|
3732
|
-
*
|
|
3949
|
+
* PBKDF2-HMAC: RFC 2898 key derivation function.
|
|
3950
|
+
* ```ts
|
|
3951
|
+
* import { pbkdf2Async } from '@noble/hashes/pbkdf2.js';
|
|
3952
|
+
* import { sha256 } from '@noble/hashes/sha2.js';
|
|
3953
|
+
* const key = await pbkdf2Async(sha256, 'password', 'salt', { dkLen: 32, c: 500_000 });
|
|
3954
|
+
* ```
|
|
3733
3955
|
*/
|
|
3734
3956
|
async function pbkdf2Async(hash, password, salt, opts) {
|
|
3735
3957
|
const { c, dkLen, asyncTick, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);
|
|
@@ -3740,6 +3962,8 @@
|
|
|
3740
3962
|
// DK = T1 + T2 + ⋯ + Tdklen/hlen
|
|
3741
3963
|
for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {
|
|
3742
3964
|
// Ti = F(Password, Salt, c, i)
|
|
3965
|
+
// The last Ti view can be shorter than hLen, which applies
|
|
3966
|
+
// RFC 8018 §5.2 step 4's T_l<0..r-1> truncation without extra copies.
|
|
3743
3967
|
const Ti = DK.subarray(pos, pos + PRF.outputLen);
|
|
3744
3968
|
view.setInt32(0, ti, false);
|
|
3745
3969
|
// F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc
|
|
@@ -3763,10 +3987,25 @@
|
|
|
3763
3987
|
/**
|
|
3764
3988
|
* Merkle-Damgard hash construction base class.
|
|
3765
3989
|
* Could be used to create MD5, RIPEMD, SHA1, SHA2.
|
|
3990
|
+
* Accepts only byte-aligned `Uint8Array` input, even when the underlying spec describes bit
|
|
3991
|
+
* strings with partial-byte tails.
|
|
3992
|
+
* @param blockLen - internal block size in bytes
|
|
3993
|
+
* @param outputLen - digest size in bytes
|
|
3994
|
+
* @param padOffset - trailing length field size in bytes
|
|
3995
|
+
* @param isLE - whether length and state words are encoded in little-endian
|
|
3996
|
+
* @example
|
|
3997
|
+
* Use a concrete subclass to get the shared Merkle-Damgard update/digest flow.
|
|
3998
|
+
* ```ts
|
|
3999
|
+
* import { _SHA1 } from '@noble/hashes/legacy.js';
|
|
4000
|
+
* const hash = new _SHA1();
|
|
4001
|
+
* hash.update(new Uint8Array([97, 98, 99]));
|
|
4002
|
+
* hash.digest();
|
|
4003
|
+
* ```
|
|
3766
4004
|
*/
|
|
3767
4005
|
class HashMD {
|
|
3768
4006
|
blockLen;
|
|
3769
4007
|
outputLen;
|
|
4008
|
+
canXOF = false;
|
|
3770
4009
|
padOffset;
|
|
3771
4010
|
isLE;
|
|
3772
4011
|
// For partial updates less than block size
|
|
@@ -3791,7 +4030,8 @@
|
|
|
3791
4030
|
const len = data.length;
|
|
3792
4031
|
for (let pos = 0; pos < len;) {
|
|
3793
4032
|
const take = Math.min(blockLen - this.pos, len - pos);
|
|
3794
|
-
// Fast path
|
|
4033
|
+
// Fast path only when there is no buffered partial block: `take === blockLen` implies
|
|
4034
|
+
// `this.pos === 0`, so we can process full blocks directly from the input view.
|
|
3795
4035
|
if (take === blockLen) {
|
|
3796
4036
|
const dataView = createView(data);
|
|
3797
4037
|
for (; blockLen <= len - pos; pos += blockLen)
|
|
@@ -3831,9 +4071,9 @@
|
|
|
3831
4071
|
// Pad until full block byte with zeros
|
|
3832
4072
|
for (let i = pos; i < blockLen; i++)
|
|
3833
4073
|
buffer[i] = 0;
|
|
3834
|
-
//
|
|
3835
|
-
//
|
|
3836
|
-
// So we
|
|
4074
|
+
// `padOffset` reserves the whole length field. For SHA-384/512 the high 64 bits stay zero from
|
|
4075
|
+
// the padding fill above, and JS will overflow before user input can make that half non-zero.
|
|
4076
|
+
// So we only need to write the low 64 bits here.
|
|
3837
4077
|
view.setBigUint64(blockLen - 8, BigInt(this.length * 8), isLE);
|
|
3838
4078
|
this.process(view, 0);
|
|
3839
4079
|
const oview = createView(out);
|
|
@@ -3851,6 +4091,8 @@
|
|
|
3851
4091
|
digest() {
|
|
3852
4092
|
const { buffer, outputLen } = this;
|
|
3853
4093
|
this.digestInto(buffer);
|
|
4094
|
+
// Copy before destroy(): subclasses wipe `buffer` during cleanup, but `digest()` must return
|
|
4095
|
+
// fresh bytes to the caller.
|
|
3854
4096
|
const res = buffer.slice(0, outputLen);
|
|
3855
4097
|
this.destroy();
|
|
3856
4098
|
return res;
|
|
@@ -3863,6 +4105,8 @@
|
|
|
3863
4105
|
to.finished = finished;
|
|
3864
4106
|
to.length = length;
|
|
3865
4107
|
to.pos = pos;
|
|
4108
|
+
// Only partial-block bytes need copying: when `length % blockLen === 0`, `pos === 0` and
|
|
4109
|
+
// later `update()` / `digestInto()` overwrite `to.buffer` from the start before reading it.
|
|
3866
4110
|
if (length % blockLen)
|
|
3867
4111
|
to.buffer.set(buffer);
|
|
3868
4112
|
return to;
|
|
@@ -3871,24 +4115,26 @@
|
|
|
3871
4115
|
return this._cloneInto();
|
|
3872
4116
|
}
|
|
3873
4117
|
}
|
|
3874
|
-
/** Initial SHA512 state
|
|
4118
|
+
/** Initial SHA512 state from RFC 6234 §6.3: eight RFC 64-bit `H(0)` words stored as sixteen
|
|
4119
|
+
* big-endian 32-bit halves. Derived from the fractional parts of the square roots of the first
|
|
4120
|
+
* eight prime numbers. Exported as a shared table; callers must treat it as read-only because
|
|
4121
|
+
* constructors copy halves from it by index. */
|
|
3875
4122
|
const SHA512_IV = /* @__PURE__ */ Uint32Array.from([
|
|
3876
4123
|
0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b, 0xa54ff53a, 0x5f1d36f1,
|
|
3877
4124
|
0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179,
|
|
3878
4125
|
]);
|
|
3879
4126
|
|
|
3880
|
-
/**
|
|
3881
|
-
* Internal helpers for u64. BigUint64Array is too slow as per 2025, so we implement it using Uint32Array.
|
|
3882
|
-
* @todo re-check https://issues.chromium.org/issues/42212588
|
|
3883
|
-
* @module
|
|
3884
|
-
*/
|
|
3885
4127
|
const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
|
3886
4128
|
const _32n = /* @__PURE__ */ BigInt(32);
|
|
4129
|
+
// Split bigint into two 32-bit halves. With `le=true`, returned fields become `{ h: low, l: high
|
|
4130
|
+
// }` to match little-endian word order rather than the property names.
|
|
3887
4131
|
function fromBig(n, le = false) {
|
|
3888
4132
|
if (le)
|
|
3889
4133
|
return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
|
|
3890
4134
|
return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
|
|
3891
4135
|
}
|
|
4136
|
+
// Split bigint list into `[highWords, lowWords]` when `le=false`; with `le=true`, the first array
|
|
4137
|
+
// holds the low halves because `fromBig(...)` swaps the semantic meaning of `h` and `l`.
|
|
3892
4138
|
function split(lst, le = false) {
|
|
3893
4139
|
const len = lst.length;
|
|
3894
4140
|
let Ah = new Uint32Array(len);
|
|
@@ -3899,39 +4145,49 @@
|
|
|
3899
4145
|
}
|
|
3900
4146
|
return [Ah, Al];
|
|
3901
4147
|
}
|
|
3902
|
-
// for
|
|
4148
|
+
// High 32-bit half of a 64-bit logical right shift for `s` in `0..31`.
|
|
3903
4149
|
const shrSH = (h, _l, s) => h >>> s;
|
|
4150
|
+
// Low 32-bit half of a 64-bit logical right shift, valid for `s` in `1..31`.
|
|
3904
4151
|
const shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
|
|
3905
|
-
//
|
|
4152
|
+
// High 32-bit half of a 64-bit right rotate, valid for `s` in `1..31`.
|
|
3906
4153
|
const rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s));
|
|
4154
|
+
// Low 32-bit half of a 64-bit right rotate, valid for `s` in `1..31`.
|
|
3907
4155
|
const rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
|
|
3908
|
-
//
|
|
4156
|
+
// High 32-bit half of a 64-bit right rotate, valid for `s` in `33..63`; `32` uses `rotr32*`.
|
|
3909
4157
|
const rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32));
|
|
4158
|
+
// Low 32-bit half of a 64-bit right rotate, valid for `s` in `33..63`; `32` uses `rotr32*`.
|
|
3910
4159
|
const rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s));
|
|
3911
|
-
//
|
|
3912
|
-
//
|
|
4160
|
+
// Add two split 64-bit words and return the split `{ h, l }` sum.
|
|
4161
|
+
// JS uses 32-bit signed integers for bitwise operations, so we cannot simply shift the carry out
|
|
4162
|
+
// of the low sum and instead use division.
|
|
3913
4163
|
function add(Ah, Al, Bh, Bl) {
|
|
3914
4164
|
const l = (Al >>> 0) + (Bl >>> 0);
|
|
3915
4165
|
return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };
|
|
3916
4166
|
}
|
|
3917
4167
|
// Addition with more than 2 elements
|
|
4168
|
+
// Unmasked low-word accumulator for 3-way addition; pass the raw result into `add3H(...)`.
|
|
3918
4169
|
const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
|
|
4170
|
+
// High-word finalize step for 3-way addition; `low` must be the untruncated output of `add3L(...)`.
|
|
3919
4171
|
const add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;
|
|
4172
|
+
// Unmasked low-word accumulator for 4-way addition; pass the raw result into `add4H(...)`.
|
|
3920
4173
|
const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
|
|
4174
|
+
// High-word finalize step for 4-way addition; `low` must be the untruncated output of `add4L(...)`.
|
|
3921
4175
|
const add4H = (low, Ah, Bh, Ch, Dh) => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;
|
|
4176
|
+
// Unmasked low-word accumulator for 5-way addition; pass the raw result into `add5H(...)`.
|
|
3922
4177
|
const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
|
|
4178
|
+
// High-word finalize step for 5-way addition; `low` must be the untruncated output of `add5L(...)`.
|
|
3923
4179
|
const add5H = (low, Ah, Bh, Ch, Dh, Eh) => (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;
|
|
3924
4180
|
|
|
3925
4181
|
/**
|
|
3926
4182
|
* SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256.
|
|
3927
4183
|
* SHA256 is the fastest hash implementable in JS, even faster than Blake3.
|
|
3928
|
-
* Check out
|
|
3929
|
-
*
|
|
4184
|
+
* Check out {@link https://www.rfc-editor.org/rfc/rfc4634 | RFC 4634} and
|
|
4185
|
+
* {@link https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf | FIPS 180-4}.
|
|
3930
4186
|
* @module
|
|
3931
4187
|
*/
|
|
3932
4188
|
// SHA2-512 is slower than sha256 in js because u64 operations are slow.
|
|
3933
|
-
//
|
|
3934
|
-
//
|
|
4189
|
+
// SHA-384 / SHA-512 round constants from RFC 6234 §5.2:
|
|
4190
|
+
// 80 full 64-bit words split into high/low halves.
|
|
3935
4191
|
// prettier-ignore
|
|
3936
4192
|
const K512 = /* @__PURE__ */ (() => split([
|
|
3937
4193
|
'0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc',
|
|
@@ -3957,10 +4213,11 @@
|
|
|
3957
4213
|
].map(n => BigInt(n))))();
|
|
3958
4214
|
const SHA512_Kh = /* @__PURE__ */ (() => K512[0])();
|
|
3959
4215
|
const SHA512_Kl = /* @__PURE__ */ (() => K512[1])();
|
|
3960
|
-
// Reusable
|
|
4216
|
+
// Reusable high-half schedule buffer for the RFC 6234 §6.4 64-bit `W_t` words.
|
|
3961
4217
|
const SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);
|
|
4218
|
+
// Reusable low-half schedule buffer for the RFC 6234 §6.4 64-bit `W_t` words.
|
|
3962
4219
|
const SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);
|
|
3963
|
-
/** Internal
|
|
4220
|
+
/** Internal SHA-384 / SHA-512 compression engine from RFC 6234 §6.4. */
|
|
3964
4221
|
class SHA2_64B extends HashMD {
|
|
3965
4222
|
constructor(outputLen) {
|
|
3966
4223
|
super(128, outputLen, 16, false);
|
|
@@ -4006,7 +4263,7 @@
|
|
|
4006
4263
|
const W2l = SHA512_W_L[i - 2] | 0;
|
|
4007
4264
|
const s1h = rotrSH(W2h, W2l, 19) ^ rotrBH(W2h, W2l, 61) ^ shrSH(W2h, W2l, 6);
|
|
4008
4265
|
const s1l = rotrSL(W2h, W2l, 19) ^ rotrBL(W2h, W2l, 61) ^ shrSL(W2h, W2l, 6);
|
|
4009
|
-
//
|
|
4266
|
+
// SHA512_W[i] = s0 + s1 + SHA512_W[i - 7] + SHA512_W[i - 16];
|
|
4010
4267
|
const SUMl = add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);
|
|
4011
4268
|
const SUMh = add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);
|
|
4012
4269
|
SHA512_W_H[i] = SUMh | 0;
|
|
@@ -4063,11 +4320,14 @@
|
|
|
4063
4320
|
clean(SHA512_W_H, SHA512_W_L);
|
|
4064
4321
|
}
|
|
4065
4322
|
destroy() {
|
|
4323
|
+
// HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves
|
|
4324
|
+
// update()/digest() callable on reused instances.
|
|
4325
|
+
this.destroyed = true;
|
|
4066
4326
|
clean(this.buffer);
|
|
4067
4327
|
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
|
4068
4328
|
}
|
|
4069
4329
|
}
|
|
4070
|
-
/** Internal
|
|
4330
|
+
/** Internal SHA-512 hash class grounded in RFC 6234 §6.3 and §6.4. */
|
|
4071
4331
|
class _SHA512 extends SHA2_64B {
|
|
4072
4332
|
Ah = SHA512_IV[0] | 0;
|
|
4073
4333
|
Al = SHA512_IV[1] | 0;
|
|
@@ -4089,7 +4349,16 @@
|
|
|
4089
4349
|
super(64);
|
|
4090
4350
|
}
|
|
4091
4351
|
}
|
|
4092
|
-
/**
|
|
4352
|
+
/**
|
|
4353
|
+
* SHA2-512 hash function from RFC 4634.
|
|
4354
|
+
* @param msg - message bytes to hash
|
|
4355
|
+
* @returns Digest bytes.
|
|
4356
|
+
* @example
|
|
4357
|
+
* Hash a message with SHA2-512.
|
|
4358
|
+
* ```ts
|
|
4359
|
+
* sha512(new Uint8Array([97, 98, 99]));
|
|
4360
|
+
* ```
|
|
4361
|
+
*/
|
|
4093
4362
|
const sha512 = /* @__PURE__ */ createHasher(() => new _SHA512(),
|
|
4094
4363
|
/* @__PURE__ */ oidNist(0x03));
|
|
4095
4364
|
|
|
@@ -4201,11 +4470,15 @@
|
|
|
4201
4470
|
// so that any two texts that are equivalent will be reduced
|
|
4202
4471
|
// to the same sequence of code points, called the normal form of the original text.
|
|
4203
4472
|
// https://tonsky.me/blog/unicode/#why-is-a----
|
|
4473
|
+
// BIP-39 requires UTF-8 NFKD for localized wordlists and mnemonic sentences.
|
|
4474
|
+
// It also applies NFKD to the "mnemonic" + passphrase salt.
|
|
4204
4475
|
function nfkd(str) {
|
|
4205
4476
|
if (typeof str !== 'string')
|
|
4206
4477
|
throw new TypeError('invalid mnemonic type: ' + typeof str);
|
|
4207
4478
|
return str.normalize('NFKD');
|
|
4208
4479
|
}
|
|
4480
|
+
// BIP-39 mnemonics are consumed in NFKD form.
|
|
4481
|
+
// They must contain 12, 15, 18, 21, or 24 words before checksum validation.
|
|
4209
4482
|
function normalize(str) {
|
|
4210
4483
|
const norm = nfkd(str);
|
|
4211
4484
|
const words = norm.split(' ');
|
|
@@ -4213,19 +4486,30 @@
|
|
|
4213
4486
|
throw new Error('Invalid mnemonic');
|
|
4214
4487
|
return { nfkd: norm, words };
|
|
4215
4488
|
}
|
|
4489
|
+
// BIP-39 salts PBKDF2 with the UTF-8 NFKD string "mnemonic" + passphrase.
|
|
4216
4490
|
const psalt = (passphrase) => nfkd('mnemonic' + passphrase);
|
|
4217
4491
|
/**
|
|
4218
4492
|
* Irreversible: Uses KDF to derive 64 bytes of key data from mnemonic + optional password.
|
|
4219
|
-
* @param mnemonic 12-24 words
|
|
4220
|
-
* @param passphrase
|
|
4221
|
-
* @returns 64 bytes of key data
|
|
4493
|
+
* @param mnemonic - 12-24 words.
|
|
4494
|
+
* @param passphrase - String that will additionally protect the key.
|
|
4495
|
+
* @returns 64 bytes of key data.
|
|
4496
|
+
* @throws If the mnemonic shape is invalid. {@link Error}
|
|
4497
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
4222
4498
|
* @example
|
|
4499
|
+
* Derive a seed from a mnemonic with the async PBKDF2 helper.
|
|
4500
|
+
* ```ts
|
|
4223
4501
|
* const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';
|
|
4224
|
-
* await mnemonicToSeed(mnem, 'password');
|
|
4225
|
-
* // new Uint8Array([...64 bytes])
|
|
4502
|
+
* const seed = await mnemonicToSeed(mnem, 'password');
|
|
4503
|
+
* // => new Uint8Array([...64 bytes])
|
|
4504
|
+
* ```
|
|
4226
4505
|
*/
|
|
4506
|
+
// BIP-39 seed derivation is independent from mnemonic generation.
|
|
4507
|
+
// These helpers normalize the phrase but do not verify checksum or wordlist membership.
|
|
4227
4508
|
function mnemonicToSeed(mnemonic, passphrase = '') {
|
|
4228
|
-
return pbkdf2Async(sha512, normalize(mnemonic).nfkd, psalt(passphrase), {
|
|
4509
|
+
return pbkdf2Async(sha512, normalize(mnemonic).nfkd, psalt(passphrase), {
|
|
4510
|
+
c: 2048,
|
|
4511
|
+
dkLen: 64,
|
|
4512
|
+
});
|
|
4229
4513
|
}
|
|
4230
4514
|
|
|
4231
4515
|
var _InMemorySpendingKey_spendingKeyBuf, _InMemorySpendingKey_saplingViewingKey;
|