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