@taquito/sapling 24.3.0-beta.1 → 24.3.0-beta.3

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.
@@ -1,15 +1,12 @@
1
- import BigNumber from 'bignumber.js';
1
+ import BigNumberJs from 'bignumber.js';
2
2
  import { MichelCodecPacker } from '@taquito/taquito';
3
3
  import { b58Encode, PrefixV2, bytesToString, toHexBuf, stringToBytes, hex2buf, mergebuf, hex2Bytes, num2PaddedHex, b58DecodeAndCheckPrefix, format, b58DecodePublicKeyHash, validateKeyHash, ValidationResult } from '@taquito/utils';
4
4
  import { ParameterValidationError, TaquitoError, InvalidKeyHashError, InvalidAddressError } from '@taquito/core';
5
- import * as sapling from '@airgap/sapling-wasm';
6
- import { merkleHash } from '@airgap/sapling-wasm';
5
+ import * as sapling from '@taquito/sapling-wasm';
6
+ import { merkleHash } from '@taquito/sapling-wasm';
7
7
  import blake from 'blakejs';
8
8
  import { openSecretBox, secretBox } from '@stablelib/nacl';
9
- import { randomBytes } from '@stablelib/random';
10
9
  import toBuffer from 'typedarray-to-buffer';
11
- import pbkdf2 from 'pbkdf2';
12
- import * as bip39 from 'bip39';
13
10
 
14
11
  /******************************************************************************
15
12
  Copyright (c) Microsoft Corporation.
@@ -136,7 +133,7 @@ function readableFormat(saplingTransactionProperties) {
136
133
  };
137
134
  }
138
135
  function convertValueToBigNumber(value) {
139
- return new BigNumber(Buffer.from(value).toString('hex'), 16);
136
+ return new BigNumberJs(Buffer.from(value).toString('hex'), 16);
140
137
  }
141
138
  function bufToUint8Array(buffer) {
142
139
  return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / Uint8Array.BYTES_PER_ELEMENT);
@@ -229,7 +226,7 @@ class SaplingForger {
229
226
  const encodedMemo = Buffer.from(stringToBytes(txPlainText.memo).padEnd(txPlainText.memoSize, '0'), 'hex');
230
227
  return Buffer.concat([
231
228
  txPlainText.diversifier,
232
- toHexBuf(new BigNumber(txPlainText.amount), 64),
229
+ toHexBuf(new BigNumberJs(txPlainText.amount), 64),
233
230
  txPlainText.randomCommitmentTrapdoor,
234
231
  toHexBuf(txPlainText.memoSize, 32),
235
232
  encodedMemo,
@@ -243,6 +240,7 @@ const DEFAULT_MEMO = '';
243
240
  const DEFAULT_BOUND_DATA = Buffer.from('', 'hex');
244
241
 
245
242
  var _SaplingTransactionViewer_viewingKeyProvider, _SaplingTransactionViewer_readProvider, _SaplingTransactionViewer_saplingContractId;
243
+ const BigNumber$3 = BigNumberJs;
246
244
  /**
247
245
  * Allows to retrieve and decrypt sapling transactions using on a viewing key
248
246
  *
@@ -266,7 +264,7 @@ class SaplingTransactionViewer {
266
264
  *
267
265
  */
268
266
  async getBalance() {
269
- let balance = new BigNumber(0);
267
+ let balance = new BigNumber$3(0);
270
268
  const { commitments_and_ciphertexts, nullifiers } = await this.getSaplingDiff();
271
269
  for (let i = 0; i < commitments_and_ciphertexts.length; i++) {
272
270
  const decrypted = await this.decryptCiphertextAsReceiver(commitments_and_ciphertexts[i]);
@@ -458,6 +456,7 @@ const changeEndianness = (hex) => {
458
456
  * https://github.com/airgap-it/airgap-coin-lib/blob/master/LICENSE.md
459
457
  *
460
458
  */
459
+ const BigNumber$2 = BigNumberJs;
461
460
  /**
462
461
  * The SaplingState class's main purpose is to provide a Merkle path for the forger and the transaction builder, so that it may verify that the Sapling transaction is valid
463
462
  *
@@ -577,7 +576,7 @@ class SaplingState {
577
576
  }
578
577
  else {
579
578
  let nextPos, nextTree, otherTree;
580
- const fullTree = new BigNumber(2).pow(height - 1);
579
+ const fullTree = new BigNumber$2(2).pow(height - 1);
581
580
  if (position.lt(fullTree)) {
582
581
  nextPos = position;
583
582
  nextTree = tree[1];
@@ -596,15 +595,24 @@ class SaplingState {
596
595
  // eslint-disable-next-line @typescript-eslint/no-var-requires
597
596
  const saplingOutputParams = require('../saplingOutputParams');
598
597
  // eslint-disable-next-line @typescript-eslint/no-var-requires
599
- const saplingSpendParams = require('../saplingSpendParams');
598
+ const saplingSpendParams = require('@taquito/sapling-spend-params');
600
599
  let cachedParams;
600
+ const getRandomValueSource = () => {
601
+ const crypto = globalThis.crypto;
602
+ if (!crypto?.getRandomValues) {
603
+ throw new Error('Sapling randomness requires globalThis.crypto.getRandomValues');
604
+ }
605
+ return crypto;
606
+ };
601
607
  class SaplingWrapper {
602
608
  async withProvingContext(action) {
603
609
  await this.initSaplingParameters();
604
610
  return sapling.withProvingContext(action);
605
611
  }
606
612
  getRandomBytes(length) {
607
- return randomBytes(length);
613
+ const bytes = new Uint8Array(length);
614
+ getRandomValueSource().getRandomValues(bytes);
615
+ return bytes;
608
616
  }
609
617
  async randR() {
610
618
  return sapling.randR();
@@ -647,6 +655,7 @@ class SaplingWrapper {
647
655
  }
648
656
 
649
657
  var _SaplingTransactionBuilder_inMemorySpendingKey, _SaplingTransactionBuilder_inMemoryProvingKey, _SaplingTransactionBuilder_saplingForger, _SaplingTransactionBuilder_contractAddress, _SaplingTransactionBuilder_saplingId, _SaplingTransactionBuilder_memoSize, _SaplingTransactionBuilder_readProvider, _SaplingTransactionBuilder_saplingWrapper, _SaplingTransactionBuilder_chainId, _SaplingTransactionBuilder_saplingState;
658
+ const BigNumber$1 = BigNumberJs;
650
659
  class SaplingTransactionBuilder {
651
660
  constructor(keys, saplingForger, saplingContractDetails, readProvider, saplingWrapper = new SaplingWrapper()) {
652
661
  _SaplingTransactionBuilder_inMemorySpendingKey.set(this, void 0);
@@ -711,9 +720,9 @@ class SaplingTransactionBuilder {
711
720
  const outputs = [];
712
721
  const inputs = [];
713
722
  inputs.push(...(await this.prepareSaplingSpendDescription(saplingContext, chosenInputs.inputsToSpend)));
714
- let sumAmountOutput = new BigNumber(0);
723
+ let sumAmountOutput = new BigNumber$1(0);
715
724
  for (const i in saplingTransactionParams) {
716
- sumAmountOutput = sumAmountOutput.plus(new BigNumber(saplingTransactionParams[i].amount));
725
+ sumAmountOutput = sumAmountOutput.plus(new BigNumber$1(saplingTransactionParams[i].amount));
717
726
  const [address] = b58DecodeAndCheckPrefix(saplingTransactionParams[i].to, [
718
727
  PrefixV2.SaplingAddress,
719
728
  ]);
@@ -737,7 +746,7 @@ class SaplingTransactionBuilder {
737
746
  randomCommitmentTrapdoor: randomCommitmentTrapdoor,
738
747
  outgoingViewingKey: outgoingViewingKey,
739
748
  }, chosenInputs.sumSelectedInputs);
740
- sumAmountOutput = sumAmountOutput.plus(new BigNumber(payBackAmount));
749
+ sumAmountOutput = sumAmountOutput.plus(new BigNumber$1(payBackAmount));
741
750
  outputs.push(payBackOutput);
742
751
  }
743
752
  const balance = this.calculateTransactionBalance(chosenInputs.sumSelectedInputs.toString(), sumAmountOutput.toString());
@@ -759,7 +768,7 @@ class SaplingTransactionBuilder {
759
768
  }
760
769
  // sum of values of inputs minus sums of values of output equals balance
761
770
  calculateTransactionBalance(inputTotal, outputTotal) {
762
- return new BigNumber(inputTotal).minus(new BigNumber(outputTotal));
771
+ return new BigNumber$1(inputTotal).minus(new BigNumber$1(outputTotal));
763
772
  }
764
773
  async prepareSaplingOutputDescription(parametersOutputDescription) {
765
774
  const ephemeralPrivateKey = await __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingWrapper, "f").randR();
@@ -812,7 +821,7 @@ class SaplingTransactionBuilder {
812
821
  const saplingSpendDescriptions = [];
813
822
  for (let i = 0; i < inputsToSpend.length; i++) {
814
823
  const amount = convertValueToBigNumber(inputsToSpend[i].value).toString();
815
- const witness = await __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingState, "f").getWitness(stateTree, new BigNumber(inputsToSpend[i].position));
824
+ const witness = await __classPrivateFieldGet(this, _SaplingTransactionBuilder_saplingState, "f").getWitness(stateTree, new BigNumber$1(inputsToSpend[i].position));
816
825
  const unsignedSpendDescription = __classPrivateFieldGet(this, _SaplingTransactionBuilder_inMemoryProvingKey, "f")
817
826
  ? await __classPrivateFieldGet(this, _SaplingTransactionBuilder_inMemoryProvingKey, "f").prepareSpendDescription({
818
827
  saplingContext,
@@ -895,6 +904,647 @@ class SaplingTransactionBuilder {
895
904
  }
896
905
  _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();
897
906
 
907
+ /**
908
+ * Utilities for hex, bytes, CSPRNG.
909
+ * @module
910
+ */
911
+ /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
912
+ /** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */
913
+ function isBytes(a) {
914
+ return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
915
+ }
916
+ /** Asserts something is positive integer. */
917
+ function anumber(n, title = '') {
918
+ if (!Number.isSafeInteger(n) || n < 0) {
919
+ const prefix = title && `"${title}" `;
920
+ throw new Error(`${prefix}expected integer >= 0, got ${n}`);
921
+ }
922
+ }
923
+ /** Asserts something is Uint8Array. */
924
+ function abytes(value, length, title = '') {
925
+ const bytes = isBytes(value);
926
+ const len = value?.length;
927
+ const needsLen = length !== undefined;
928
+ if (!bytes || (needsLen && len !== length)) {
929
+ const prefix = title && `"${title}" `;
930
+ const ofLen = needsLen ? ` of length ${length}` : '';
931
+ const got = bytes ? `length=${len}` : `type=${typeof value}`;
932
+ throw new Error(prefix + 'expected Uint8Array' + ofLen + ', got ' + got);
933
+ }
934
+ return value;
935
+ }
936
+ /** Asserts something is hash */
937
+ function ahash(h) {
938
+ if (typeof h !== 'function' || typeof h.create !== 'function')
939
+ throw new Error('Hash must wrapped by utils.createHasher');
940
+ anumber(h.outputLen);
941
+ anumber(h.blockLen);
942
+ }
943
+ /** Asserts a hash instance has not been destroyed / finished */
944
+ function aexists(instance, checkFinished = true) {
945
+ if (instance.destroyed)
946
+ throw new Error('Hash instance has been destroyed');
947
+ if (checkFinished && instance.finished)
948
+ throw new Error('Hash#digest() has already been called');
949
+ }
950
+ /** Asserts output is properly-sized byte array */
951
+ function aoutput(out, instance) {
952
+ abytes(out, undefined, 'digestInto() output');
953
+ const min = instance.outputLen;
954
+ if (out.length < min) {
955
+ throw new Error('"digestInto() output" expected to be of length >=' + min);
956
+ }
957
+ }
958
+ /** Zeroize a byte array. Warning: JS provides no guarantees. */
959
+ function clean(...arrays) {
960
+ for (let i = 0; i < arrays.length; i++) {
961
+ arrays[i].fill(0);
962
+ }
963
+ }
964
+ /** Create DataView of an array for easy byte-level manipulation. */
965
+ function createView(arr) {
966
+ return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
967
+ }
968
+ /**
969
+ * There is no setImmediate in browser and setTimeout is slow.
970
+ * Call of async fn will return Promise, which will be fullfiled only on
971
+ * next scheduler queue processing step and this is exactly what we need.
972
+ */
973
+ const nextTick = async () => { };
974
+ /** Returns control to thread each 'tick' ms to avoid blocking. */
975
+ async function asyncLoop(iters, tick, cb) {
976
+ let ts = Date.now();
977
+ for (let i = 0; i < iters; i++) {
978
+ cb(i);
979
+ // Date.now() is not monotonic, so in case if clock goes backwards we return return control too
980
+ const diff = Date.now() - ts;
981
+ if (diff >= 0 && diff < tick)
982
+ continue;
983
+ await nextTick();
984
+ ts += diff;
985
+ }
986
+ }
987
+ /**
988
+ * Converts string to bytes using UTF8 encoding.
989
+ * Built-in doesn't validate input to be string: we do the check.
990
+ * @example utf8ToBytes('abc') // Uint8Array.from([97, 98, 99])
991
+ */
992
+ function utf8ToBytes(str) {
993
+ if (typeof str !== 'string')
994
+ throw new Error('string expected');
995
+ return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
996
+ }
997
+ /**
998
+ * Helper for KDFs: consumes uint8array or string.
999
+ * When string is passed, does utf8 decoding, using TextDecoder.
1000
+ */
1001
+ function kdfInputToBytes(data, errorTitle = '') {
1002
+ if (typeof data === 'string')
1003
+ return utf8ToBytes(data);
1004
+ return abytes(data, undefined, errorTitle);
1005
+ }
1006
+ /** Merges default options and passed options. */
1007
+ function checkOpts(defaults, opts) {
1008
+ if (opts !== undefined && {}.toString.call(opts) !== '[object Object]')
1009
+ throw new Error('options must be object or undefined');
1010
+ const merged = Object.assign(defaults, opts);
1011
+ return merged;
1012
+ }
1013
+ /** Creates function with outputLen, blockLen, create properties from a class constructor. */
1014
+ function createHasher(hashCons, info = {}) {
1015
+ const hashC = (msg, opts) => hashCons(opts).update(msg).digest();
1016
+ const tmp = hashCons(undefined);
1017
+ hashC.outputLen = tmp.outputLen;
1018
+ hashC.blockLen = tmp.blockLen;
1019
+ hashC.create = (opts) => hashCons(opts);
1020
+ Object.assign(hashC, info);
1021
+ return Object.freeze(hashC);
1022
+ }
1023
+ /** Creates OID opts for NIST hashes, with prefix 06 09 60 86 48 01 65 03 04 02. */
1024
+ const oidNist = (suffix) => ({
1025
+ oid: Uint8Array.from([0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, suffix]),
1026
+ });
1027
+
1028
+ /**
1029
+ * HMAC: RFC2104 message authentication code.
1030
+ * @module
1031
+ */
1032
+ /** Internal class for HMAC. */
1033
+ class _HMAC {
1034
+ oHash;
1035
+ iHash;
1036
+ blockLen;
1037
+ outputLen;
1038
+ finished = false;
1039
+ destroyed = false;
1040
+ constructor(hash, key) {
1041
+ ahash(hash);
1042
+ abytes(key, undefined, 'key');
1043
+ this.iHash = hash.create();
1044
+ if (typeof this.iHash.update !== 'function')
1045
+ throw new Error('Expected instance of class which extends utils.Hash');
1046
+ this.blockLen = this.iHash.blockLen;
1047
+ this.outputLen = this.iHash.outputLen;
1048
+ const blockLen = this.blockLen;
1049
+ const pad = new Uint8Array(blockLen);
1050
+ // blockLen can be bigger than outputLen
1051
+ pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);
1052
+ for (let i = 0; i < pad.length; i++)
1053
+ pad[i] ^= 0x36;
1054
+ this.iHash.update(pad);
1055
+ // By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
1056
+ this.oHash = hash.create();
1057
+ // Undo internal XOR && apply outer XOR
1058
+ for (let i = 0; i < pad.length; i++)
1059
+ pad[i] ^= 0x36 ^ 0x5c;
1060
+ this.oHash.update(pad);
1061
+ clean(pad);
1062
+ }
1063
+ update(buf) {
1064
+ aexists(this);
1065
+ this.iHash.update(buf);
1066
+ return this;
1067
+ }
1068
+ digestInto(out) {
1069
+ aexists(this);
1070
+ abytes(out, this.outputLen, 'output');
1071
+ this.finished = true;
1072
+ this.iHash.digestInto(out);
1073
+ this.oHash.update(out);
1074
+ this.oHash.digestInto(out);
1075
+ this.destroy();
1076
+ }
1077
+ digest() {
1078
+ const out = new Uint8Array(this.oHash.outputLen);
1079
+ this.digestInto(out);
1080
+ return out;
1081
+ }
1082
+ _cloneInto(to) {
1083
+ // Create new instance without calling constructor since key already in state and we don't know it.
1084
+ to ||= Object.create(Object.getPrototypeOf(this), {});
1085
+ const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
1086
+ to = to;
1087
+ to.finished = finished;
1088
+ to.destroyed = destroyed;
1089
+ to.blockLen = blockLen;
1090
+ to.outputLen = outputLen;
1091
+ to.oHash = oHash._cloneInto(to.oHash);
1092
+ to.iHash = iHash._cloneInto(to.iHash);
1093
+ return to;
1094
+ }
1095
+ clone() {
1096
+ return this._cloneInto();
1097
+ }
1098
+ destroy() {
1099
+ this.destroyed = true;
1100
+ this.oHash.destroy();
1101
+ this.iHash.destroy();
1102
+ }
1103
+ }
1104
+ /**
1105
+ * HMAC: RFC2104 message authentication code.
1106
+ * @param hash - function that would be used e.g. sha256
1107
+ * @param key - message key
1108
+ * @param message - message data
1109
+ * @example
1110
+ * import { hmac } from '@noble/hashes/hmac';
1111
+ * import { sha256 } from '@noble/hashes/sha2';
1112
+ * const mac1 = hmac(sha256, 'key', 'message');
1113
+ */
1114
+ const hmac = (hash, key, message) => new _HMAC(hash, key).update(message).digest();
1115
+ hmac.create = (hash, key) => new _HMAC(hash, key);
1116
+
1117
+ /**
1118
+ * PBKDF (RFC 2898). Can be used to create a key from password and salt.
1119
+ * @module
1120
+ */
1121
+ // Common start and end for sync/async functions
1122
+ function pbkdf2Init(hash, _password, _salt, _opts) {
1123
+ ahash(hash);
1124
+ const opts = checkOpts({ dkLen: 32, asyncTick: 10 }, _opts);
1125
+ const { c, dkLen, asyncTick } = opts;
1126
+ anumber(c, 'c');
1127
+ anumber(dkLen, 'dkLen');
1128
+ anumber(asyncTick, 'asyncTick');
1129
+ if (c < 1)
1130
+ throw new Error('iterations (c) must be >= 1');
1131
+ const password = kdfInputToBytes(_password, 'password');
1132
+ const salt = kdfInputToBytes(_salt, 'salt');
1133
+ // DK = PBKDF2(PRF, Password, Salt, c, dkLen);
1134
+ const DK = new Uint8Array(dkLen);
1135
+ // U1 = PRF(Password, Salt + INT_32_BE(i))
1136
+ const PRF = hmac.create(hash, password);
1137
+ const PRFSalt = PRF._cloneInto().update(salt);
1138
+ return { c, dkLen, asyncTick, DK, PRF, PRFSalt };
1139
+ }
1140
+ function pbkdf2Output(PRF, PRFSalt, DK, prfW, u) {
1141
+ PRF.destroy();
1142
+ PRFSalt.destroy();
1143
+ if (prfW)
1144
+ prfW.destroy();
1145
+ clean(u);
1146
+ return DK;
1147
+ }
1148
+ /**
1149
+ * PBKDF2-HMAC: RFC 2898 key derivation function
1150
+ * @param hash - hash function that would be used e.g. sha256
1151
+ * @param password - password from which a derived key is generated
1152
+ * @param salt - cryptographic salt
1153
+ * @param opts - {c, dkLen} where c is work factor and dkLen is output message size
1154
+ * @example
1155
+ * const key = pbkdf2(sha256, 'password', 'salt', { dkLen: 32, c: Math.pow(2, 18) });
1156
+ */
1157
+ function pbkdf2(hash, password, salt, opts) {
1158
+ const { c, dkLen, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);
1159
+ let prfW; // Working copy
1160
+ const arr = new Uint8Array(4);
1161
+ const view = createView(arr);
1162
+ const u = new Uint8Array(PRF.outputLen);
1163
+ // DK = T1 + T2 + ⋯ + Tdklen/hlen
1164
+ for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {
1165
+ // Ti = F(Password, Salt, c, i)
1166
+ const Ti = DK.subarray(pos, pos + PRF.outputLen);
1167
+ view.setInt32(0, ti, false);
1168
+ // F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc
1169
+ // U1 = PRF(Password, Salt + INT_32_BE(i))
1170
+ (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u);
1171
+ Ti.set(u.subarray(0, Ti.length));
1172
+ for (let ui = 1; ui < c; ui++) {
1173
+ // Uc = PRF(Password, Uc−1)
1174
+ PRF._cloneInto(prfW).update(u).digestInto(u);
1175
+ for (let i = 0; i < Ti.length; i++)
1176
+ Ti[i] ^= u[i];
1177
+ }
1178
+ }
1179
+ return pbkdf2Output(PRF, PRFSalt, DK, prfW, u);
1180
+ }
1181
+ /**
1182
+ * PBKDF2-HMAC: RFC 2898 key derivation function. Async version.
1183
+ * @example
1184
+ * await pbkdf2Async(sha256, 'password', 'salt', { dkLen: 32, c: 500_000 });
1185
+ */
1186
+ async function pbkdf2Async(hash, password, salt, opts) {
1187
+ const { c, dkLen, asyncTick, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);
1188
+ let prfW; // Working copy
1189
+ const arr = new Uint8Array(4);
1190
+ const view = createView(arr);
1191
+ const u = new Uint8Array(PRF.outputLen);
1192
+ // DK = T1 + T2 + ⋯ + Tdklen/hlen
1193
+ for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {
1194
+ // Ti = F(Password, Salt, c, i)
1195
+ const Ti = DK.subarray(pos, pos + PRF.outputLen);
1196
+ view.setInt32(0, ti, false);
1197
+ // F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc
1198
+ // U1 = PRF(Password, Salt + INT_32_BE(i))
1199
+ (prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u);
1200
+ Ti.set(u.subarray(0, Ti.length));
1201
+ await asyncLoop(c - 1, asyncTick, () => {
1202
+ // Uc = PRF(Password, Uc−1)
1203
+ PRF._cloneInto(prfW).update(u).digestInto(u);
1204
+ for (let i = 0; i < Ti.length; i++)
1205
+ Ti[i] ^= u[i];
1206
+ });
1207
+ }
1208
+ return pbkdf2Output(PRF, PRFSalt, DK, prfW, u);
1209
+ }
1210
+
1211
+ /**
1212
+ * Internal Merkle-Damgard hash utils.
1213
+ * @module
1214
+ */
1215
+ /**
1216
+ * Merkle-Damgard hash construction base class.
1217
+ * Could be used to create MD5, RIPEMD, SHA1, SHA2.
1218
+ */
1219
+ class HashMD {
1220
+ blockLen;
1221
+ outputLen;
1222
+ padOffset;
1223
+ isLE;
1224
+ // For partial updates less than block size
1225
+ buffer;
1226
+ view;
1227
+ finished = false;
1228
+ length = 0;
1229
+ pos = 0;
1230
+ destroyed = false;
1231
+ constructor(blockLen, outputLen, padOffset, isLE) {
1232
+ this.blockLen = blockLen;
1233
+ this.outputLen = outputLen;
1234
+ this.padOffset = padOffset;
1235
+ this.isLE = isLE;
1236
+ this.buffer = new Uint8Array(blockLen);
1237
+ this.view = createView(this.buffer);
1238
+ }
1239
+ update(data) {
1240
+ aexists(this);
1241
+ abytes(data);
1242
+ const { view, buffer, blockLen } = this;
1243
+ const len = data.length;
1244
+ for (let pos = 0; pos < len;) {
1245
+ const take = Math.min(blockLen - this.pos, len - pos);
1246
+ // Fast path: we have at least one block in input, cast it to view and process
1247
+ if (take === blockLen) {
1248
+ const dataView = createView(data);
1249
+ for (; blockLen <= len - pos; pos += blockLen)
1250
+ this.process(dataView, pos);
1251
+ continue;
1252
+ }
1253
+ buffer.set(data.subarray(pos, pos + take), this.pos);
1254
+ this.pos += take;
1255
+ pos += take;
1256
+ if (this.pos === blockLen) {
1257
+ this.process(view, 0);
1258
+ this.pos = 0;
1259
+ }
1260
+ }
1261
+ this.length += data.length;
1262
+ this.roundClean();
1263
+ return this;
1264
+ }
1265
+ digestInto(out) {
1266
+ aexists(this);
1267
+ aoutput(out, this);
1268
+ this.finished = true;
1269
+ // Padding
1270
+ // We can avoid allocation of buffer for padding completely if it
1271
+ // was previously not allocated here. But it won't change performance.
1272
+ const { buffer, view, blockLen, isLE } = this;
1273
+ let { pos } = this;
1274
+ // append the bit '1' to the message
1275
+ buffer[pos++] = 0b10000000;
1276
+ clean(this.buffer.subarray(pos));
1277
+ // we have less than padOffset left in buffer, so we cannot put length in
1278
+ // current block, need process it and pad again
1279
+ if (this.padOffset > blockLen - pos) {
1280
+ this.process(view, 0);
1281
+ pos = 0;
1282
+ }
1283
+ // Pad until full block byte with zeros
1284
+ for (let i = pos; i < blockLen; i++)
1285
+ buffer[i] = 0;
1286
+ // Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that
1287
+ // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.
1288
+ // So we just write lowest 64 bits of that value.
1289
+ view.setBigUint64(blockLen - 8, BigInt(this.length * 8), isLE);
1290
+ this.process(view, 0);
1291
+ const oview = createView(out);
1292
+ const len = this.outputLen;
1293
+ // NOTE: we do division by 4 later, which must be fused in single op with modulo by JIT
1294
+ if (len % 4)
1295
+ throw new Error('_sha2: outputLen must be aligned to 32bit');
1296
+ const outLen = len / 4;
1297
+ const state = this.get();
1298
+ if (outLen > state.length)
1299
+ throw new Error('_sha2: outputLen bigger than state');
1300
+ for (let i = 0; i < outLen; i++)
1301
+ oview.setUint32(4 * i, state[i], isLE);
1302
+ }
1303
+ digest() {
1304
+ const { buffer, outputLen } = this;
1305
+ this.digestInto(buffer);
1306
+ const res = buffer.slice(0, outputLen);
1307
+ this.destroy();
1308
+ return res;
1309
+ }
1310
+ _cloneInto(to) {
1311
+ to ||= new this.constructor();
1312
+ to.set(...this.get());
1313
+ const { blockLen, buffer, length, finished, destroyed, pos } = this;
1314
+ to.destroyed = destroyed;
1315
+ to.finished = finished;
1316
+ to.length = length;
1317
+ to.pos = pos;
1318
+ if (length % blockLen)
1319
+ to.buffer.set(buffer);
1320
+ return to;
1321
+ }
1322
+ clone() {
1323
+ return this._cloneInto();
1324
+ }
1325
+ }
1326
+ /** Initial SHA512 state. Bits 0..64 of frac part of sqrt of primes 2..19 */
1327
+ const SHA512_IV = /* @__PURE__ */ Uint32Array.from([
1328
+ 0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b, 0xa54ff53a, 0x5f1d36f1,
1329
+ 0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179,
1330
+ ]);
1331
+
1332
+ /**
1333
+ * Internal helpers for u64. BigUint64Array is too slow as per 2025, so we implement it using Uint32Array.
1334
+ * @todo re-check https://issues.chromium.org/issues/42212588
1335
+ * @module
1336
+ */
1337
+ const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
1338
+ const _32n = /* @__PURE__ */ BigInt(32);
1339
+ function fromBig(n, le = false) {
1340
+ if (le)
1341
+ return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
1342
+ return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
1343
+ }
1344
+ function split(lst, le = false) {
1345
+ const len = lst.length;
1346
+ let Ah = new Uint32Array(len);
1347
+ let Al = new Uint32Array(len);
1348
+ for (let i = 0; i < len; i++) {
1349
+ const { h, l } = fromBig(lst[i], le);
1350
+ [Ah[i], Al[i]] = [h, l];
1351
+ }
1352
+ return [Ah, Al];
1353
+ }
1354
+ // for Shift in [0, 32)
1355
+ const shrSH = (h, _l, s) => h >>> s;
1356
+ const shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
1357
+ // Right rotate for Shift in [1, 32)
1358
+ const rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s));
1359
+ const rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
1360
+ // Right rotate for Shift in (32, 64), NOTE: 32 is special case.
1361
+ const rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32));
1362
+ const rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s));
1363
+ // JS uses 32-bit signed integers for bitwise operations which means we cannot
1364
+ // simple take carry out of low bit sum by shift, we need to use division.
1365
+ function add(Ah, Al, Bh, Bl) {
1366
+ const l = (Al >>> 0) + (Bl >>> 0);
1367
+ return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };
1368
+ }
1369
+ // Addition with more than 2 elements
1370
+ const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
1371
+ const add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;
1372
+ const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
1373
+ const add4H = (low, Ah, Bh, Ch, Dh) => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;
1374
+ const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
1375
+ const add5H = (low, Ah, Bh, Ch, Dh, Eh) => (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;
1376
+
1377
+ /**
1378
+ * SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256.
1379
+ * SHA256 is the fastest hash implementable in JS, even faster than Blake3.
1380
+ * Check out [RFC 4634](https://www.rfc-editor.org/rfc/rfc4634) and
1381
+ * [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
1382
+ * @module
1383
+ */
1384
+ // SHA2-512 is slower than sha256 in js because u64 operations are slow.
1385
+ // Round contants
1386
+ // First 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409
1387
+ // prettier-ignore
1388
+ const K512 = /* @__PURE__ */ (() => split([
1389
+ '0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc',
1390
+ '0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118',
1391
+ '0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2',
1392
+ '0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694',
1393
+ '0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65',
1394
+ '0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5',
1395
+ '0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4',
1396
+ '0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70',
1397
+ '0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df',
1398
+ '0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b',
1399
+ '0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30',
1400
+ '0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8',
1401
+ '0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8',
1402
+ '0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3',
1403
+ '0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec',
1404
+ '0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b',
1405
+ '0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178',
1406
+ '0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b',
1407
+ '0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c',
1408
+ '0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817'
1409
+ ].map(n => BigInt(n))))();
1410
+ const SHA512_Kh = /* @__PURE__ */ (() => K512[0])();
1411
+ const SHA512_Kl = /* @__PURE__ */ (() => K512[1])();
1412
+ // Reusable temporary buffers
1413
+ const SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);
1414
+ const SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);
1415
+ /** Internal 64-byte base SHA2 hash class. */
1416
+ class SHA2_64B extends HashMD {
1417
+ constructor(outputLen) {
1418
+ super(128, outputLen, 16, false);
1419
+ }
1420
+ // prettier-ignore
1421
+ get() {
1422
+ const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
1423
+ return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];
1424
+ }
1425
+ // prettier-ignore
1426
+ set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) {
1427
+ this.Ah = Ah | 0;
1428
+ this.Al = Al | 0;
1429
+ this.Bh = Bh | 0;
1430
+ this.Bl = Bl | 0;
1431
+ this.Ch = Ch | 0;
1432
+ this.Cl = Cl | 0;
1433
+ this.Dh = Dh | 0;
1434
+ this.Dl = Dl | 0;
1435
+ this.Eh = Eh | 0;
1436
+ this.El = El | 0;
1437
+ this.Fh = Fh | 0;
1438
+ this.Fl = Fl | 0;
1439
+ this.Gh = Gh | 0;
1440
+ this.Gl = Gl | 0;
1441
+ this.Hh = Hh | 0;
1442
+ this.Hl = Hl | 0;
1443
+ }
1444
+ process(view, offset) {
1445
+ // Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array
1446
+ for (let i = 0; i < 16; i++, offset += 4) {
1447
+ SHA512_W_H[i] = view.getUint32(offset);
1448
+ SHA512_W_L[i] = view.getUint32((offset += 4));
1449
+ }
1450
+ for (let i = 16; i < 80; i++) {
1451
+ // s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7)
1452
+ const W15h = SHA512_W_H[i - 15] | 0;
1453
+ const W15l = SHA512_W_L[i - 15] | 0;
1454
+ const s0h = rotrSH(W15h, W15l, 1) ^ rotrSH(W15h, W15l, 8) ^ shrSH(W15h, W15l, 7);
1455
+ const s0l = rotrSL(W15h, W15l, 1) ^ rotrSL(W15h, W15l, 8) ^ shrSL(W15h, W15l, 7);
1456
+ // s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6)
1457
+ const W2h = SHA512_W_H[i - 2] | 0;
1458
+ const W2l = SHA512_W_L[i - 2] | 0;
1459
+ const s1h = rotrSH(W2h, W2l, 19) ^ rotrBH(W2h, W2l, 61) ^ shrSH(W2h, W2l, 6);
1460
+ const s1l = rotrSL(W2h, W2l, 19) ^ rotrBL(W2h, W2l, 61) ^ shrSL(W2h, W2l, 6);
1461
+ // SHA256_W[i] = s0 + s1 + SHA256_W[i - 7] + SHA256_W[i - 16];
1462
+ const SUMl = add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);
1463
+ const SUMh = add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);
1464
+ SHA512_W_H[i] = SUMh | 0;
1465
+ SHA512_W_L[i] = SUMl | 0;
1466
+ }
1467
+ let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
1468
+ // Compression function main loop, 80 rounds
1469
+ for (let i = 0; i < 80; i++) {
1470
+ // S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41)
1471
+ const sigma1h = rotrSH(Eh, El, 14) ^ rotrSH(Eh, El, 18) ^ rotrBH(Eh, El, 41);
1472
+ const sigma1l = rotrSL(Eh, El, 14) ^ rotrSL(Eh, El, 18) ^ rotrBL(Eh, El, 41);
1473
+ //const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;
1474
+ const CHIh = (Eh & Fh) ^ (~Eh & Gh);
1475
+ const CHIl = (El & Fl) ^ (~El & Gl);
1476
+ // T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i]
1477
+ // prettier-ignore
1478
+ const T1ll = add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);
1479
+ const T1h = add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);
1480
+ const T1l = T1ll | 0;
1481
+ // S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39)
1482
+ const sigma0h = rotrSH(Ah, Al, 28) ^ rotrBH(Ah, Al, 34) ^ rotrBH(Ah, Al, 39);
1483
+ const sigma0l = rotrSL(Ah, Al, 28) ^ rotrBL(Ah, Al, 34) ^ rotrBL(Ah, Al, 39);
1484
+ const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch);
1485
+ const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl);
1486
+ Hh = Gh | 0;
1487
+ Hl = Gl | 0;
1488
+ Gh = Fh | 0;
1489
+ Gl = Fl | 0;
1490
+ Fh = Eh | 0;
1491
+ Fl = El | 0;
1492
+ ({ h: Eh, l: El } = add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));
1493
+ Dh = Ch | 0;
1494
+ Dl = Cl | 0;
1495
+ Ch = Bh | 0;
1496
+ Cl = Bl | 0;
1497
+ Bh = Ah | 0;
1498
+ Bl = Al | 0;
1499
+ const All = add3L(T1l, sigma0l, MAJl);
1500
+ Ah = add3H(All, T1h, sigma0h, MAJh);
1501
+ Al = All | 0;
1502
+ }
1503
+ // Add the compressed chunk to the current hash value
1504
+ ({ h: Ah, l: Al } = add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));
1505
+ ({ h: Bh, l: Bl } = add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));
1506
+ ({ h: Ch, l: Cl } = add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));
1507
+ ({ h: Dh, l: Dl } = add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));
1508
+ ({ h: Eh, l: El } = add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));
1509
+ ({ h: Fh, l: Fl } = add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));
1510
+ ({ h: Gh, l: Gl } = add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));
1511
+ ({ h: Hh, l: Hl } = add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));
1512
+ this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
1513
+ }
1514
+ roundClean() {
1515
+ clean(SHA512_W_H, SHA512_W_L);
1516
+ }
1517
+ destroy() {
1518
+ clean(this.buffer);
1519
+ this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1520
+ }
1521
+ }
1522
+ /** Internal SHA2-512 hash class. */
1523
+ class _SHA512 extends SHA2_64B {
1524
+ Ah = SHA512_IV[0] | 0;
1525
+ Al = SHA512_IV[1] | 0;
1526
+ Bh = SHA512_IV[2] | 0;
1527
+ Bl = SHA512_IV[3] | 0;
1528
+ Ch = SHA512_IV[4] | 0;
1529
+ Cl = SHA512_IV[5] | 0;
1530
+ Dh = SHA512_IV[6] | 0;
1531
+ Dl = SHA512_IV[7] | 0;
1532
+ Eh = SHA512_IV[8] | 0;
1533
+ El = SHA512_IV[9] | 0;
1534
+ Fh = SHA512_IV[10] | 0;
1535
+ Fl = SHA512_IV[11] | 0;
1536
+ Gh = SHA512_IV[12] | 0;
1537
+ Gl = SHA512_IV[13] | 0;
1538
+ Hh = SHA512_IV[14] | 0;
1539
+ Hl = SHA512_IV[15] | 0;
1540
+ constructor() {
1541
+ super(64);
1542
+ }
1543
+ }
1544
+ /** SHA2-512 hash function from RFC 4634. */
1545
+ const sha512 = /* @__PURE__ */ createHasher(() => new _SHA512(),
1546
+ /* @__PURE__ */ oidNist(0x03));
1547
+
898
1548
  function decryptKey(spendingKey, password) {
899
1549
  const [keyArr, pre] = (() => {
900
1550
  try {
@@ -918,7 +1568,7 @@ function decryptKey(spendingKey, password) {
918
1568
  }
919
1569
  const salt = toBuffer(keyArr.slice(0, 8));
920
1570
  const encryptedSk = toBuffer(keyArr.slice(8));
921
- const encryptionKey = pbkdf2.pbkdf2Sync(password, salt, 32768, 32, 'sha512');
1571
+ const encryptionKey = pbkdf2(sha512, password, salt, { c: 32768, dkLen: 32 });
922
1572
  // Zero nonce is safe: fresh random salt per encryption produces unique PBKDF2-derived key.
923
1573
  // See: https://gitlab.com/tezos/tezos/-/blob/master/src/lib_signer_backends/encrypted.ml
924
1574
  const decrypted = openSecretBox(new Uint8Array(encryptionKey), new Uint8Array(24), // zero nonce - uniqueness provided by per-encryption derived key
@@ -998,6 +1648,38 @@ class InMemoryViewingKey {
998
1648
  }
999
1649
  _InMemoryViewingKey_fullViewingKey = new WeakMap();
1000
1650
 
1651
+ /*! scure-bip39 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) */
1652
+ // Normalization replaces equivalent sequences of characters
1653
+ // so that any two texts that are equivalent will be reduced
1654
+ // to the same sequence of code points, called the normal form of the original text.
1655
+ // https://tonsky.me/blog/unicode/#why-is-a----
1656
+ function nfkd(str) {
1657
+ if (typeof str !== 'string')
1658
+ throw new TypeError('invalid mnemonic type: ' + typeof str);
1659
+ return str.normalize('NFKD');
1660
+ }
1661
+ function normalize(str) {
1662
+ const norm = nfkd(str);
1663
+ const words = norm.split(' ');
1664
+ if (![12, 15, 18, 21, 24].includes(words.length))
1665
+ throw new Error('Invalid mnemonic');
1666
+ return { nfkd: norm, words };
1667
+ }
1668
+ const psalt = (passphrase) => nfkd('mnemonic' + passphrase);
1669
+ /**
1670
+ * Irreversible: Uses KDF to derive 64 bytes of key data from mnemonic + optional password.
1671
+ * @param mnemonic 12-24 words
1672
+ * @param passphrase string that will additionally protect the key
1673
+ * @returns 64 bytes of key data
1674
+ * @example
1675
+ * const mnem = 'legal winner thank year wave sausage worth useful legal winner thank yellow';
1676
+ * await mnemonicToSeed(mnem, 'password');
1677
+ * // new Uint8Array([...64 bytes])
1678
+ */
1679
+ function mnemonicToSeed(mnemonic, passphrase = '') {
1680
+ return pbkdf2Async(sha512, normalize(mnemonic).nfkd, psalt(passphrase), { c: 2048, dkLen: 64 });
1681
+ }
1682
+
1001
1683
  var _InMemorySpendingKey_spendingKeyBuf, _InMemorySpendingKey_saplingViewingKey;
1002
1684
  /**
1003
1685
  * holds the spending key, create proof and signature for spend descriptions
@@ -1023,7 +1705,7 @@ class InMemorySpendingKey {
1023
1705
  */
1024
1706
  static async fromMnemonic(mnemonic, derivationPath = 'm/') {
1025
1707
  // no password passed here. password provided only changes from sask -> MMXj
1026
- const fullSeed = await bip39.mnemonicToSeed(mnemonic);
1708
+ const fullSeed = await mnemonicToSeed(mnemonic);
1027
1709
  const first32 = fullSeed.slice(0, 32);
1028
1710
  const second32 = fullSeed.slice(32);
1029
1711
  // reduce seed bytes must be 32 bytes reflecting both halves
@@ -1154,6 +1836,7 @@ _InMemoryProvingKey_provingKey = new WeakMap();
1154
1836
  * @module @taquito/sapling
1155
1837
  */
1156
1838
  var _SaplingToolkit_inMemorySpendingKey, _SaplingToolkit_saplingId, _SaplingToolkit_contractAddress, _SaplingToolkit_memoSize, _SaplingToolkit_readProvider, _SaplingToolkit_packer, _SaplingToolkit_saplingForger, _SaplingToolkit_saplingTxBuilder, _SaplingToolkit_saplingTransactionViewer;
1839
+ const BigNumber = BigNumberJs;
1157
1840
  /**
1158
1841
  * Class that surfaces all of the sapling capability allowing to read from a sapling state and prepare transactions
1159
1842
  *