@taquito/signer
Version:
Software signer implementations and signing utilities for Taquito.
1,187 lines (1,170 loc) • 117 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@stablelib/nacl'), require('@taquito/utils'), require('typedarray-to-buffer'), require('@noble/curves/ed25519'), require('@noble/curves/secp256k1'), require('@noble/curves/nist.js'), require('@taquito/core'), require('@noble/curves/nist'), require('bn.js'), require('@noble/curves/bls12-381')) :
typeof define === 'function' && define.amd ? define(['exports', '@stablelib/nacl', '@taquito/utils', 'typedarray-to-buffer', '@noble/curves/ed25519', '@noble/curves/secp256k1', '@noble/curves/nist.js', '@taquito/core', '@noble/curves/nist', 'bn.js', '@noble/curves/bls12-381'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.taquitoSigner = {}, global.nacl, global.utils, global.toBuffer, global.ed25519, global.secp256k1, global.nist, global.core, global.nist, global.BN, global.bls12381));
})(this, (function (exports, nacl, utils$1, toBuffer, ed25519$1, secp256k1, nist_js, core, nist, BN, bls12381) { 'use strict';
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
function __classPrivateFieldGet(receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
}
function __classPrivateFieldSet(receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
/**
* Utilities for hex, bytes, CSPRNG.
* @module
*/
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
/** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */
function isBytes$1(a) {
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
}
/** Asserts something is positive integer. */
function anumber$1(n, title = '') {
if (!Number.isSafeInteger(n) || n < 0) {
const prefix = title && `"${title}" `;
throw new Error(`${prefix}expected integer >= 0, got ${n}`);
}
}
/** Asserts something is Uint8Array. */
function abytes(value, length, title = '') {
const bytes = isBytes$1(value);
const len = value?.length;
const needsLen = length !== undefined;
if (!bytes || (needsLen && len !== length)) {
const prefix = title && `"${title}" `;
const ofLen = needsLen ? ` of length ${length}` : '';
const got = bytes ? `length=${len}` : `type=${typeof value}`;
throw new Error(prefix + 'expected Uint8Array' + ofLen + ', got ' + got);
}
return value;
}
/** Asserts something is hash */
function ahash(h) {
if (typeof h !== 'function' || typeof h.create !== 'function')
throw new Error('Hash must wrapped by utils.createHasher');
anumber$1(h.outputLen);
anumber$1(h.blockLen);
}
/** Asserts a hash instance has not been destroyed / finished */
function aexists(instance, checkFinished = true) {
if (instance.destroyed)
throw new Error('Hash instance has been destroyed');
if (checkFinished && instance.finished)
throw new Error('Hash#digest() has already been called');
}
/** Asserts output is properly-sized byte array */
function aoutput(out, instance) {
abytes(out, undefined, 'digestInto() output');
const min = instance.outputLen;
if (out.length < min) {
throw new Error('"digestInto() output" expected to be of length >=' + min);
}
}
/** Cast u8 / u16 / u32 to u32. */
function u32(arr) {
return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
}
/** Zeroize a byte array. Warning: JS provides no guarantees. */
function clean(...arrays) {
for (let i = 0; i < arrays.length; i++) {
arrays[i].fill(0);
}
}
/** Create DataView of an array for easy byte-level manipulation. */
function createView(arr) {
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
}
/** The rotate right (circular right shift) operation for uint32 */
function rotr(word, shift) {
return (word << (32 - shift)) | (word >>> shift);
}
/** Is current platform little-endian? Most are. Big-Endian platform: IBM */
const isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();
/** The byte swap operation for uint32 */
function byteSwap(word) {
return (((word << 24) & 0xff000000) |
((word << 8) & 0xff0000) |
((word >>> 8) & 0xff00) |
((word >>> 24) & 0xff));
}
/** Conditionally byte swap if on a big-endian platform */
const swap8IfBE = isLE
? (n) => n
: (n) => byteSwap(n);
/** In place byte swap for Uint32Array */
function byteSwap32(arr) {
for (let i = 0; i < arr.length; i++) {
arr[i] = byteSwap(arr[i]);
}
return arr;
}
const swap32IfBE = isLE
? (u) => u
: byteSwap32;
/**
* Converts string to bytes using UTF8 encoding.
* Built-in doesn't validate input to be string: we do the check.
* @example utf8ToBytes('abc') // Uint8Array.from([97, 98, 99])
*/
function utf8ToBytes(str) {
if (typeof str !== 'string')
throw new Error('string expected');
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
}
/**
* Helper for KDFs: consumes uint8array or string.
* When string is passed, does utf8 decoding, using TextDecoder.
*/
function kdfInputToBytes(data, errorTitle = '') {
if (typeof data === 'string')
return utf8ToBytes(data);
return abytes(data, undefined, errorTitle);
}
/** Merges default options and passed options. */
function checkOpts(defaults, opts) {
if (opts !== undefined && {}.toString.call(opts) !== '[object Object]')
throw new Error('options must be object or undefined');
const merged = Object.assign(defaults, opts);
return merged;
}
/** Creates function with outputLen, blockLen, create properties from a class constructor. */
function createHasher(hashCons, info = {}) {
const hashC = (msg, opts) => hashCons(opts).update(msg).digest();
const tmp = hashCons(undefined);
hashC.outputLen = tmp.outputLen;
hashC.blockLen = tmp.blockLen;
hashC.create = (opts) => hashCons(opts);
Object.assign(hashC, info);
return Object.freeze(hashC);
}
/** Creates OID opts for NIST hashes, with prefix 06 09 60 86 48 01 65 03 04 02. */
const oidNist = (suffix) => ({
oid: Uint8Array.from([0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, suffix]),
});
/**
* Internal helpers for blake hash.
* @module
*/
/**
* Internal blake variable.
* For BLAKE2b, the two extra permutations for rounds 10 and 11 are SIGMA[10..11] = SIGMA[0..1].
*/
// prettier-ignore
const BSIGMA = /* @__PURE__ */ Uint8Array.from([
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3,
11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4,
7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8,
9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13,
2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9,
12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11,
13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10,
6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5,
10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3,
// Blake1, unused in others
11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4,
7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8,
9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13,
2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9,
]);
/**
* Internal Merkle-Damgard hash utils.
* @module
*/
/** Choice: a ? b : c */
function Chi(a, b, c) {
return (a & b) ^ (~a & c);
}
/** Majority function, true if any two inputs is true. */
function Maj(a, b, c) {
return (a & b) ^ (a & c) ^ (b & c);
}
/**
* Merkle-Damgard hash construction base class.
* Could be used to create MD5, RIPEMD, SHA1, SHA2.
*/
class HashMD {
blockLen;
outputLen;
padOffset;
isLE;
// For partial updates less than block size
buffer;
view;
finished = false;
length = 0;
pos = 0;
destroyed = false;
constructor(blockLen, outputLen, padOffset, isLE) {
this.blockLen = blockLen;
this.outputLen = outputLen;
this.padOffset = padOffset;
this.isLE = isLE;
this.buffer = new Uint8Array(blockLen);
this.view = createView(this.buffer);
}
update(data) {
aexists(this);
abytes(data);
const { view, buffer, blockLen } = this;
const len = data.length;
for (let pos = 0; pos < len;) {
const take = Math.min(blockLen - this.pos, len - pos);
// Fast path: we have at least one block in input, cast it to view and process
if (take === blockLen) {
const dataView = createView(data);
for (; blockLen <= len - pos; pos += blockLen)
this.process(dataView, pos);
continue;
}
buffer.set(data.subarray(pos, pos + take), this.pos);
this.pos += take;
pos += take;
if (this.pos === blockLen) {
this.process(view, 0);
this.pos = 0;
}
}
this.length += data.length;
this.roundClean();
return this;
}
digestInto(out) {
aexists(this);
aoutput(out, this);
this.finished = true;
// Padding
// We can avoid allocation of buffer for padding completely if it
// was previously not allocated here. But it won't change performance.
const { buffer, view, blockLen, isLE } = this;
let { pos } = this;
// append the bit '1' to the message
buffer[pos++] = 0b10000000;
clean(this.buffer.subarray(pos));
// we have less than padOffset left in buffer, so we cannot put length in
// current block, need process it and pad again
if (this.padOffset > blockLen - pos) {
this.process(view, 0);
pos = 0;
}
// Pad until full block byte with zeros
for (let i = pos; i < blockLen; i++)
buffer[i] = 0;
// Note: sha512 requires length to be 128bit integer, but length in JS will overflow before that
// You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen.
// So we just write lowest 64 bits of that value.
view.setBigUint64(blockLen - 8, BigInt(this.length * 8), isLE);
this.process(view, 0);
const oview = createView(out);
const len = this.outputLen;
// NOTE: we do division by 4 later, which must be fused in single op with modulo by JIT
if (len % 4)
throw new Error('_sha2: outputLen must be aligned to 32bit');
const outLen = len / 4;
const state = this.get();
if (outLen > state.length)
throw new Error('_sha2: outputLen bigger than state');
for (let i = 0; i < outLen; i++)
oview.setUint32(4 * i, state[i], isLE);
}
digest() {
const { buffer, outputLen } = this;
this.digestInto(buffer);
const res = buffer.slice(0, outputLen);
this.destroy();
return res;
}
_cloneInto(to) {
to ||= new this.constructor();
to.set(...this.get());
const { blockLen, buffer, length, finished, destroyed, pos } = this;
to.destroyed = destroyed;
to.finished = finished;
to.length = length;
to.pos = pos;
if (length % blockLen)
to.buffer.set(buffer);
return to;
}
clone() {
return this._cloneInto();
}
}
/**
* Initial SHA-2 state: fractional parts of square roots of first 16 primes 2..53.
* Check out `test/misc/sha2-gen-iv.js` for recomputation guide.
*/
/** Initial SHA256 state. Bits 0..32 of frac part of sqrt of primes 2..19 */
const SHA256_IV = /* @__PURE__ */ Uint32Array.from([
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
]);
/** Initial SHA512 state. Bits 0..64 of frac part of sqrt of primes 2..19 */
const SHA512_IV = /* @__PURE__ */ Uint32Array.from([
0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b, 0xa54ff53a, 0x5f1d36f1,
0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179,
]);
/**
* Internal helpers for u64. BigUint64Array is too slow as per 2025, so we implement it using Uint32Array.
* @todo re-check https://issues.chromium.org/issues/42212588
* @module
*/
const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
const _32n = /* @__PURE__ */ BigInt(32);
function fromBig(n, le = false) {
if (le)
return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
}
function split(lst, le = false) {
const len = lst.length;
let Ah = new Uint32Array(len);
let Al = new Uint32Array(len);
for (let i = 0; i < len; i++) {
const { h, l } = fromBig(lst[i], le);
[Ah[i], Al[i]] = [h, l];
}
return [Ah, Al];
}
// for Shift in [0, 32)
const shrSH = (h, _l, s) => h >>> s;
const shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
// Right rotate for Shift in [1, 32)
const rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s));
const rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
// Right rotate for Shift in (32, 64), NOTE: 32 is special case.
const rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32));
const rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s));
// Right rotate for shift===32 (just swaps l&h)
const rotr32H = (_h, l) => l;
const rotr32L = (h, _l) => h;
// JS uses 32-bit signed integers for bitwise operations which means we cannot
// simple take carry out of low bit sum by shift, we need to use division.
function add(Ah, Al, Bh, Bl) {
const l = (Al >>> 0) + (Bl >>> 0);
return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };
}
// Addition with more than 2 elements
const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
const add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;
const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
const add4H = (low, Ah, Bh, Ch, Dh) => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;
const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
const add5H = (low, Ah, Bh, Ch, Dh, Eh) => (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;
/**
* blake2b (64-bit) & blake2s (8 to 32-bit) hash functions.
* b could have been faster, but there is no fast u64 in js, so s is 1.5x faster.
* @module
*/
// Same as SHA512_IV, but swapped endianness: LE instead of BE. iv[1] is iv[0], etc.
const B2B_IV = /* @__PURE__ */ Uint32Array.from([
0xf3bcc908, 0x6a09e667, 0x84caa73b, 0xbb67ae85, 0xfe94f82b, 0x3c6ef372, 0x5f1d36f1, 0xa54ff53a,
0xade682d1, 0x510e527f, 0x2b3e6c1f, 0x9b05688c, 0xfb41bd6b, 0x1f83d9ab, 0x137e2179, 0x5be0cd19,
]);
// Temporary buffer
const BBUF = /* @__PURE__ */ new Uint32Array(32);
// Mixing function G splitted in two halfs
function G1b(a, b, c, d, msg, x) {
// NOTE: V is LE here
const Xl = msg[x], Xh = msg[x + 1]; // prettier-ignore
let Al = BBUF[2 * a], Ah = BBUF[2 * a + 1]; // prettier-ignore
let Bl = BBUF[2 * b], Bh = BBUF[2 * b + 1]; // prettier-ignore
let Cl = BBUF[2 * c], Ch = BBUF[2 * c + 1]; // prettier-ignore
let Dl = BBUF[2 * d], Dh = BBUF[2 * d + 1]; // prettier-ignore
// v[a] = (v[a] + v[b] + x) | 0;
let ll = add3L(Al, Bl, Xl);
Ah = add3H(ll, Ah, Bh, Xh);
Al = ll | 0;
// v[d] = rotr(v[d] ^ v[a], 32)
({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al });
({ Dh, Dl } = { Dh: rotr32H(Dh, Dl), Dl: rotr32L(Dh) });
// v[c] = (v[c] + v[d]) | 0;
({ h: Ch, l: Cl } = add(Ch, Cl, Dh, Dl));
// v[b] = rotr(v[b] ^ v[c], 24)
({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl });
({ Bh, Bl } = { Bh: rotrSH(Bh, Bl, 24), Bl: rotrSL(Bh, Bl, 24) });
((BBUF[2 * a] = Al), (BBUF[2 * a + 1] = Ah));
((BBUF[2 * b] = Bl), (BBUF[2 * b + 1] = Bh));
((BBUF[2 * c] = Cl), (BBUF[2 * c + 1] = Ch));
((BBUF[2 * d] = Dl), (BBUF[2 * d + 1] = Dh));
}
function G2b(a, b, c, d, msg, x) {
// NOTE: V is LE here
const Xl = msg[x], Xh = msg[x + 1]; // prettier-ignore
let Al = BBUF[2 * a], Ah = BBUF[2 * a + 1]; // prettier-ignore
let Bl = BBUF[2 * b], Bh = BBUF[2 * b + 1]; // prettier-ignore
let Cl = BBUF[2 * c], Ch = BBUF[2 * c + 1]; // prettier-ignore
let Dl = BBUF[2 * d], Dh = BBUF[2 * d + 1]; // prettier-ignore
// v[a] = (v[a] + v[b] + x) | 0;
let ll = add3L(Al, Bl, Xl);
Ah = add3H(ll, Ah, Bh, Xh);
Al = ll | 0;
// v[d] = rotr(v[d] ^ v[a], 16)
({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al });
({ Dh, Dl } = { Dh: rotrSH(Dh, Dl, 16), Dl: rotrSL(Dh, Dl, 16) });
// v[c] = (v[c] + v[d]) | 0;
({ h: Ch, l: Cl } = add(Ch, Cl, Dh, Dl));
// v[b] = rotr(v[b] ^ v[c], 63)
({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl });
({ Bh, Bl } = { Bh: rotrBH(Bh, Bl, 63), Bl: rotrBL(Bh, Bl, 63) });
((BBUF[2 * a] = Al), (BBUF[2 * a + 1] = Ah));
((BBUF[2 * b] = Bl), (BBUF[2 * b + 1] = Bh));
((BBUF[2 * c] = Cl), (BBUF[2 * c + 1] = Ch));
((BBUF[2 * d] = Dl), (BBUF[2 * d + 1] = Dh));
}
function checkBlake2Opts(outputLen, opts = {}, keyLen, saltLen, persLen) {
anumber$1(keyLen);
if (outputLen < 0 || outputLen > keyLen)
throw new Error('outputLen bigger than keyLen');
const { key, salt, personalization } = opts;
if (key !== undefined && (key.length < 1 || key.length > keyLen))
throw new Error('"key" expected to be undefined or of length=1..' + keyLen);
if (salt !== undefined)
abytes(salt, saltLen, 'salt');
if (personalization !== undefined)
abytes(personalization, persLen, 'personalization');
}
/** Internal base class for BLAKE2. */
class _BLAKE2 {
buffer;
buffer32;
finished = false;
destroyed = false;
length = 0;
pos = 0;
blockLen;
outputLen;
constructor(blockLen, outputLen) {
anumber$1(blockLen);
anumber$1(outputLen);
this.blockLen = blockLen;
this.outputLen = outputLen;
this.buffer = new Uint8Array(blockLen);
this.buffer32 = u32(this.buffer);
}
update(data) {
aexists(this);
abytes(data);
// Main difference with other hashes: there is flag for last block,
// so we cannot process current block before we know that there
// is the next one. This significantly complicates logic and reduces ability
// to do zero-copy processing
const { blockLen, buffer, buffer32 } = this;
const len = data.length;
const offset = data.byteOffset;
const buf = data.buffer;
for (let pos = 0; pos < len;) {
// If buffer is full and we still have input (don't process last block, same as blake2s)
if (this.pos === blockLen) {
swap32IfBE(buffer32);
this.compress(buffer32, 0, false);
swap32IfBE(buffer32);
this.pos = 0;
}
const take = Math.min(blockLen - this.pos, len - pos);
const dataOffset = offset + pos;
// full block && aligned to 4 bytes && not last in input
if (take === blockLen && !(dataOffset % 4) && pos + take < len) {
const data32 = new Uint32Array(buf, dataOffset, Math.floor((len - pos) / 4));
swap32IfBE(data32);
for (let pos32 = 0; pos + blockLen < len; pos32 += buffer32.length, pos += blockLen) {
this.length += blockLen;
this.compress(data32, pos32, false);
}
swap32IfBE(data32);
continue;
}
buffer.set(data.subarray(pos, pos + take), this.pos);
this.pos += take;
this.length += take;
pos += take;
}
return this;
}
digestInto(out) {
aexists(this);
aoutput(out, this);
const { pos, buffer32 } = this;
this.finished = true;
// Padding
clean(this.buffer.subarray(pos));
swap32IfBE(buffer32);
this.compress(buffer32, 0, true);
swap32IfBE(buffer32);
const out32 = u32(out);
this.get().forEach((v, i) => (out32[i] = swap8IfBE(v)));
}
digest() {
const { buffer, outputLen } = this;
this.digestInto(buffer);
const res = buffer.slice(0, outputLen);
this.destroy();
return res;
}
_cloneInto(to) {
const { buffer, length, finished, destroyed, outputLen, pos } = this;
to ||= new this.constructor({ dkLen: outputLen });
to.set(...this.get());
to.buffer.set(buffer);
to.destroyed = destroyed;
to.finished = finished;
to.length = length;
to.pos = pos;
// @ts-ignore
to.outputLen = outputLen;
return to;
}
clone() {
return this._cloneInto();
}
}
/** Internal blake2b hash class. */
class _BLAKE2b extends _BLAKE2 {
// Same as SHA-512, but LE
v0l = B2B_IV[0] | 0;
v0h = B2B_IV[1] | 0;
v1l = B2B_IV[2] | 0;
v1h = B2B_IV[3] | 0;
v2l = B2B_IV[4] | 0;
v2h = B2B_IV[5] | 0;
v3l = B2B_IV[6] | 0;
v3h = B2B_IV[7] | 0;
v4l = B2B_IV[8] | 0;
v4h = B2B_IV[9] | 0;
v5l = B2B_IV[10] | 0;
v5h = B2B_IV[11] | 0;
v6l = B2B_IV[12] | 0;
v6h = B2B_IV[13] | 0;
v7l = B2B_IV[14] | 0;
v7h = B2B_IV[15] | 0;
constructor(opts = {}) {
const olen = opts.dkLen === undefined ? 64 : opts.dkLen;
super(128, olen);
checkBlake2Opts(olen, opts, 64, 16, 16);
let { key, personalization, salt } = opts;
let keyLength = 0;
if (key !== undefined) {
abytes(key, undefined, 'key');
keyLength = key.length;
}
this.v0l ^= this.outputLen | (keyLength << 8) | (0x01 << 16) | (0x01 << 24);
if (salt !== undefined) {
abytes(salt, undefined, 'salt');
const slt = u32(salt);
this.v4l ^= swap8IfBE(slt[0]);
this.v4h ^= swap8IfBE(slt[1]);
this.v5l ^= swap8IfBE(slt[2]);
this.v5h ^= swap8IfBE(slt[3]);
}
if (personalization !== undefined) {
abytes(personalization, undefined, 'personalization');
const pers = u32(personalization);
this.v6l ^= swap8IfBE(pers[0]);
this.v6h ^= swap8IfBE(pers[1]);
this.v7l ^= swap8IfBE(pers[2]);
this.v7h ^= swap8IfBE(pers[3]);
}
if (key !== undefined) {
// Pad to blockLen and update
const tmp = new Uint8Array(this.blockLen);
tmp.set(key);
this.update(tmp);
}
}
// prettier-ignore
get() {
let { v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h } = this;
return [v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h];
}
// prettier-ignore
set(v0l, v0h, v1l, v1h, v2l, v2h, v3l, v3h, v4l, v4h, v5l, v5h, v6l, v6h, v7l, v7h) {
this.v0l = v0l | 0;
this.v0h = v0h | 0;
this.v1l = v1l | 0;
this.v1h = v1h | 0;
this.v2l = v2l | 0;
this.v2h = v2h | 0;
this.v3l = v3l | 0;
this.v3h = v3h | 0;
this.v4l = v4l | 0;
this.v4h = v4h | 0;
this.v5l = v5l | 0;
this.v5h = v5h | 0;
this.v6l = v6l | 0;
this.v6h = v6h | 0;
this.v7l = v7l | 0;
this.v7h = v7h | 0;
}
compress(msg, offset, isLast) {
this.get().forEach((v, i) => (BBUF[i] = v)); // First half from state.
BBUF.set(B2B_IV, 16); // Second half from IV.
let { h, l } = fromBig(BigInt(this.length));
BBUF[24] = B2B_IV[8] ^ l; // Low word of the offset.
BBUF[25] = B2B_IV[9] ^ h; // High word.
// Invert all bits for last block
if (isLast) {
BBUF[28] = ~BBUF[28];
BBUF[29] = ~BBUF[29];
}
let j = 0;
const s = BSIGMA;
for (let i = 0; i < 12; i++) {
G1b(0, 4, 8, 12, msg, offset + 2 * s[j++]);
G2b(0, 4, 8, 12, msg, offset + 2 * s[j++]);
G1b(1, 5, 9, 13, msg, offset + 2 * s[j++]);
G2b(1, 5, 9, 13, msg, offset + 2 * s[j++]);
G1b(2, 6, 10, 14, msg, offset + 2 * s[j++]);
G2b(2, 6, 10, 14, msg, offset + 2 * s[j++]);
G1b(3, 7, 11, 15, msg, offset + 2 * s[j++]);
G2b(3, 7, 11, 15, msg, offset + 2 * s[j++]);
G1b(0, 5, 10, 15, msg, offset + 2 * s[j++]);
G2b(0, 5, 10, 15, msg, offset + 2 * s[j++]);
G1b(1, 6, 11, 12, msg, offset + 2 * s[j++]);
G2b(1, 6, 11, 12, msg, offset + 2 * s[j++]);
G1b(2, 7, 8, 13, msg, offset + 2 * s[j++]);
G2b(2, 7, 8, 13, msg, offset + 2 * s[j++]);
G1b(3, 4, 9, 14, msg, offset + 2 * s[j++]);
G2b(3, 4, 9, 14, msg, offset + 2 * s[j++]);
}
this.v0l ^= BBUF[0] ^ BBUF[16];
this.v0h ^= BBUF[1] ^ BBUF[17];
this.v1l ^= BBUF[2] ^ BBUF[18];
this.v1h ^= BBUF[3] ^ BBUF[19];
this.v2l ^= BBUF[4] ^ BBUF[20];
this.v2h ^= BBUF[5] ^ BBUF[21];
this.v3l ^= BBUF[6] ^ BBUF[22];
this.v3h ^= BBUF[7] ^ BBUF[23];
this.v4l ^= BBUF[8] ^ BBUF[24];
this.v4h ^= BBUF[9] ^ BBUF[25];
this.v5l ^= BBUF[10] ^ BBUF[26];
this.v5h ^= BBUF[11] ^ BBUF[27];
this.v6l ^= BBUF[12] ^ BBUF[28];
this.v6h ^= BBUF[13] ^ BBUF[29];
this.v7l ^= BBUF[14] ^ BBUF[30];
this.v7h ^= BBUF[15] ^ BBUF[31];
clean(BBUF);
}
destroy() {
this.destroyed = true;
clean(this.buffer32);
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}
}
/**
* Blake2b hash function. 64-bit. 1.5x slower than blake2s in JS.
* @param msg - message that would be hashed
* @param opts - dkLen output length, key for MAC mode, salt, personalization
*/
const blake2b = /* @__PURE__ */ createHasher((opts) => new _BLAKE2b(opts));
var _EdKey_keyPair, _EdPublicKey_key;
function generateKeyPairFromSeed$1(seed) {
const publicKey = ed25519$1.ed25519.getPublicKey(seed);
const secretKey = new Uint8Array(64);
secretKey.set(seed);
secretKey.set(publicKey, 32);
return { secretKey, publicKey };
}
/**
* Provide signing logic for ed25519 curve based key (tz1)
*/
class EdKey {
/**
*
* @param key Encoded private key
* @param encrypted Is the private key encrypted
* @param decrypt Decrypt function
* @throws InvalidKeyError
*/
constructor(key, decrypt) {
_EdKey_keyPair.set(this, void 0);
const tmp = utils$1.b58DecodeAndCheckPrefix(key, [
utils$1.PrefixV2.Ed25519SecretKey,
utils$1.PrefixV2.Ed25519EncryptedSeed,
utils$1.PrefixV2.Ed25519Seed,
]);
let [keyData] = tmp;
const [, prefix] = tmp;
if (prefix === utils$1.PrefixV2.Ed25519SecretKey) {
__classPrivateFieldSet(this, _EdKey_keyPair, {
secretKey: keyData,
publicKey: keyData.slice(32),
}, "f");
}
else {
if (prefix === utils$1.PrefixV2.Ed25519EncryptedSeed) {
if (decrypt !== undefined) {
keyData = decrypt(keyData);
}
else {
throw new Error('decryption function is not provided');
}
}
__classPrivateFieldSet(this, _EdKey_keyPair, generateKeyPairFromSeed$1(keyData), "f");
}
}
/**
*
* @param bytes Bytes to sign
* @param bytesHash Blake2b hash of the bytes to sign
*/
sign(bytes) {
const hash = blake2b(bytes, { dkLen: 32 });
const seed = __classPrivateFieldGet(this, _EdKey_keyPair, "f").secretKey.subarray(0, 32);
const signature = ed25519$1.ed25519.sign(hash, seed);
return {
rawSignature: signature,
sig: utils$1.b58Encode(signature, utils$1.PrefixV2.GenericSignature),
prefixSig: utils$1.b58Encode(signature, utils$1.PrefixV2.Ed25519Signature),
};
}
/**
* @returns Encoded public key
*/
publicKey() {
return new EdPublicKey(__classPrivateFieldGet(this, _EdKey_keyPair, "f").publicKey);
}
/**
* @returns Encoded private key
*/
secretKey() {
return utils$1.b58Encode(__classPrivateFieldGet(this, _EdKey_keyPair, "f").secretKey, utils$1.PrefixV2.Ed25519SecretKey);
}
}
_EdKey_keyPair = new WeakMap();
class EdPublicKey {
constructor(src) {
_EdPublicKey_key.set(this, void 0);
if (typeof src === 'string') {
const [key, _] = utils$1.b58DecodeAndCheckPrefix(src, [utils$1.PrefixV2.Ed25519PublicKey]);
__classPrivateFieldSet(this, _EdPublicKey_key, key, "f");
}
else {
__classPrivateFieldSet(this, _EdPublicKey_key, src, "f");
}
}
compare(other) {
if (other instanceof EdPublicKey) {
return utils$1.compareArrays(this.bytes(), other.bytes());
}
else {
throw new utils$1.InvalidPublicKeyError('EdDSA key expected');
}
}
hash() {
return utils$1.b58Encode(blake2b(__classPrivateFieldGet(this, _EdPublicKey_key, "f"), { dkLen: 20 }), utils$1.PrefixV2.Ed25519PublicKeyHash);
}
bytes() {
return __classPrivateFieldGet(this, _EdPublicKey_key, "f");
}
toProtocol() {
const res = new Uint8Array(__classPrivateFieldGet(this, _EdPublicKey_key, "f").length + 1);
res[0] = 0;
res.set(__classPrivateFieldGet(this, _EdPublicKey_key, "f"), 1);
return res;
}
toString() {
return utils$1.b58Encode(__classPrivateFieldGet(this, _EdPublicKey_key, "f"), utils$1.PrefixV2.Ed25519PublicKey);
}
}
_EdPublicKey_key = new WeakMap();
/**
* @category Error
* Error that indicates an invalid Mnemonic being passed or used
*/
class InvalidMnemonicError extends core.ParameterValidationError {
constructor(_mnemonic) {
super();
this.name = 'InvalidMnemonicError';
this.message = 'Invalid mnemonic';
}
}
/**
* @category Error
* Error that indicates a curve with incorrect bit size being passed or used
*/
class InvalidBitSize extends core.ParameterValidationError {
constructor(message) {
super();
this.message = message;
this.name = 'InvalidBitSize';
}
}
/**
* @category Error
* Error that indicates an unsupported cureve being passed or used
*/
class InvalidCurveError extends core.ParameterValidationError {
constructor(message) {
super();
this.message = message;
this.name = 'InvalidCurveError';
}
}
/**
* @category Error
* Error that indicates a seed with invalid length being passed or used
*/
class InvalidSeedLengthError extends core.ParameterValidationError {
constructor(seedLength) {
super();
this.seedLength = seedLength;
this.name = 'InvalidSeedLengthError';
this.message = `Invalid seed length "${seedLength}" expecting length between 16 to 64.`;
}
}
/**
* @category Error
* Error that indicates a feature still under developement
*/
class ToBeImplemented extends core.UnsupportedActionError {
constructor() {
super();
this.name = 'ToBeImplemented';
this.message = 'This feature is under developement';
}
}
/**
* @category Error
* Error that indicates an invalid passphrase being passed or used
*/
class InvalidPassphraseError extends core.ParameterValidationError {
constructor(message) {
super();
this.message = message;
this.name = 'InvalidPassphraseError';
}
}
var _ECKey_keyPair, _ECPublicKey_key;
const pref = {
p256: {
pk: utils$1.PrefixV2.P256PublicKey,
sk: utils$1.PrefixV2.P256SecretKey,
pkh: utils$1.PrefixV2.P256PublicKeyHash,
sig: utils$1.PrefixV2.P256Signature,
tag: 2,
},
secp256k1: {
pk: utils$1.PrefixV2.Secp256k1PublicKey,
sk: utils$1.PrefixV2.Secp256k1SecretKey,
pkh: utils$1.PrefixV2.Secp256k1PublicKeyHash,
sig: utils$1.PrefixV2.Secp256k1Signature,
tag: 1,
},
};
/**
* Provide signing logic for elliptic curve based key (tz2, tz3)
*/
class ECKey {
/**
*
* @param key Encoded private key
* @param decrypt Decrypt function
* @throws InvalidKeyError
*/
constructor(key, decrypt) {
_ECKey_keyPair.set(this, void 0);
const [keyData, prefix] = utils$1.b58DecodeAndCheckPrefix(key, [
utils$1.PrefixV2.Secp256k1EncryptedSecretKey,
utils$1.PrefixV2.P256EncryptedSecretKey,
utils$1.PrefixV2.Secp256k1SecretKey,
utils$1.PrefixV2.P256SecretKey,
]);
const [decKey, curve] = (() => {
switch (prefix) {
case utils$1.PrefixV2.Secp256k1EncryptedSecretKey:
case utils$1.PrefixV2.P256EncryptedSecretKey:
if (decrypt === undefined) {
throw new Error('decryption function is not provided');
}
else {
return [
decrypt(keyData),
prefix === utils$1.PrefixV2.Secp256k1EncryptedSecretKey ? 'secp256k1' : 'p256',
];
}
case utils$1.PrefixV2.Secp256k1SecretKey:
return [keyData, 'secp256k1'];
default:
return [keyData, 'p256'];
}
})();
__classPrivateFieldSet(this, _ECKey_keyPair, {
curve,
secretKey: decKey,
publicKey: curve === 'secp256k1'
? secp256k1.secp256k1.getPublicKey(decKey, true)
: nist_js.p256.getPublicKey(decKey, true),
}, "f");
}
/**
*
* @param bytes Bytes to sign
* @param bytesHash Blake2b hash of the bytes to sign
*/
sign(bytes) {
const hash = blake2b(bytes, { dkLen: 32 });
let signature;
if (__classPrivateFieldGet(this, _ECKey_keyPair, "f").curve === 'secp256k1') {
signature = secp256k1.secp256k1
.sign(hash, __classPrivateFieldGet(this, _ECKey_keyPair, "f").secretKey, {
lowS: true, // Use canonical signatures (prevents malleability)
})
.toBytes('compact');
}
else {
signature = nist_js.p256
.sign(hash, __classPrivateFieldGet(this, _ECKey_keyPair, "f").secretKey, {
lowS: true, // Use canonical signatures (prevents malleability)
})
.toBytes('compact');
}
return {
rawSignature: signature,
sig: utils$1.b58Encode(signature, utils$1.PrefixV2.GenericSignature),
prefixSig: utils$1.b58Encode(signature, pref[__classPrivateFieldGet(this, _ECKey_keyPair, "f").curve].sig),
};
}
/**
* @returns Encoded public key
*/
publicKey() {
return new ECPublicKey(__classPrivateFieldGet(this, _ECKey_keyPair, "f").publicKey, __classPrivateFieldGet(this, _ECKey_keyPair, "f").curve);
}
/**
* @returns Encoded private key
*/
secretKey() {
return utils$1.b58Encode(__classPrivateFieldGet(this, _ECKey_keyPair, "f").secretKey, pref[__classPrivateFieldGet(this, _ECKey_keyPair, "f").curve].sk);
}
}
_ECKey_keyPair = new WeakMap();
class ECPublicKey {
constructor(src, curve) {
_ECPublicKey_key.set(this, void 0);
const [key, crv] = (() => {
if (typeof src === 'string') {
const [key, pre] = utils$1.b58DecodeAndCheckPrefix(src, [
utils$1.PrefixV2.Secp256k1PublicKey,
utils$1.PrefixV2.P256PublicKey,
]);
return [key, pre === utils$1.PrefixV2.Secp256k1PublicKey ? 'secp256k1' : 'p256'];
}
else if (curve !== undefined) {
return [src, curve];
}
else {
throw new InvalidCurveError('missing curve type');
}
})();
// For ECPublicKey, we don't need the private key, so we pass an empty array
// The public key is stored separately
__classPrivateFieldSet(this, _ECPublicKey_key, key, "f");
this.curve = crv;
}
compare(other) {
if (other instanceof ECPublicKey) {
if (this.curve === other.curve) {
const compress = this.curve === 'secp256k1';
return utils$1.compareArrays(this.bytes(compress), other.bytes(compress));
}
else if (this.curve === 'secp256k1') {
return -1;
}
else {
return 1;
}
}
else {
throw new utils$1.InvalidPublicKeyError('ECDSA key expected');
}
}
hash() {
const key = this.bytes();
return utils$1.b58Encode(blake2b(key, { dkLen: 20 }), pref[this.curve].pkh);
}
bytes(compress = true) {
// @noble/curves supports both compressed and uncompressed formats
// We need to convert the stored public key to the requested format
if (this.curve === 'secp256k1') {
// For secp256k1, we need to get the public key from the stored bytes and convert format
const point = secp256k1.secp256k1.Point.fromHex(__classPrivateFieldGet(this, _ECPublicKey_key, "f"));
return point.toBytes(compress);
}
else {
// For p256, we need to get the public key from the stored bytes and convert format
const point = nist_js.p256.Point.fromHex(__classPrivateFieldGet(this, _ECPublicKey_key, "f"));
return point.toBytes(compress);
}
}
toProtocol() {
const key = this.bytes();
const res = new Uint8Array(key.length + 1);
res[0] = pref[this.curve].tag;
res.set(key, 1);
return res;
}
toString() {
const key = this.bytes();
return utils$1.b58Encode(key, pref[this.curve].pk);
}
}
_ECPublicKey_key = new WeakMap();
/**
* HMAC: RFC2104 message authentication code.
* @module
*/
/** Internal class for HMAC. */
class _HMAC {
oHash;
iHash;
blockLen;
outputLen;
finished = false;
destroyed = false;
constructor(hash, key) {
ahash(hash);
abytes(key, undefined, 'key');
this.iHash = hash.create();
if (typeof this.iHash.update !== 'function')
throw new Error('Expected instance of class which extends utils.Hash');
this.blockLen = this.iHash.blockLen;
this.outputLen = this.iHash.outputLen;
const blockLen = this.blockLen;
const pad = new Uint8Array(blockLen);
// blockLen can be bigger than outputLen
pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);
for (let i = 0; i < pad.length; i++)
pad[i] ^= 0x36;
this.iHash.update(pad);
// By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
this.oHash = hash.create();
// Undo internal XOR && apply outer XOR
for (let i = 0; i < pad.length; i++)
pad[i] ^= 0x36 ^ 0x5c;
this.oHash.update(pad);
clean(pad);
}
update(buf) {
aexists(this);
this.iHash.update(buf);
return this;
}
digestInto(out) {
aexists(this);
abytes(out, this.outputLen, 'output');
this.finished = true;
this.iHash.digestInto(out);
this.oHash.update(out);
this.oHash.digestInto(out);
this.destroy();
}
digest() {
const out = new Uint8Array(this.oHash.outputLen);
this.digestInto(out);
return out;
}
_cloneInto(to) {
// Create new instance without calling constructor since key already in state and we don't know it.
to ||= Object.create(Object.getPrototypeOf(this), {});
const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
to = to;
to.finished = finished;
to.destroyed = destroyed;
to.blockLen = blockLen;
to.outputLen = outputLen;
to.oHash = oHash._cloneInto(to.oHash);
to.iHash = iHash._cloneInto(to.iHash);
return to;
}
clone() {
return this._cloneInto();
}
destroy() {
this.destroyed = true;
this.oHash.destroy();
this.iHash.destroy();
}
}
/**
* HMAC: RFC2104 message authentication code.
* @param hash - function that would be used e.g. sha256
* @param key - message key
* @param message - message data
* @example
* import { hmac } from '@noble/hashes/hmac';
* import { sha256 } from '@noble/hashes/sha2';
* const mac1 = hmac(sha256, 'key', 'message');
*/
const hmac = (hash, key, message) => new _HMAC(hash, key).update(message).digest();
hmac.create = (hash, key) => new _HMAC(hash, key);
/**
* PBKDF (RFC 2898). Can be used to create a key from password and salt.
* @module
*/
// Common start and end for sync/async functions
function pbkdf2Init(hash, _password, _salt, _opts) {
ahash(hash);
const opts = checkOpts({ dkLen: 32, asyncTick: 10 }, _opts);
const { c, dkLen, asyncTick } = opts;
anumber$1(c, 'c');
anumber$1(dkLen, 'dkLen');
anumber$1(asyncTick, 'asyncTick');
if (c < 1)
throw new Error('iterations (c) must be >= 1');
const password = kdfInputToBytes(_password, 'password');
const salt = kdfInputToBytes(_salt, 'salt');
// DK = PBKDF2(PRF, Password, Salt, c, dkLen);
const DK = new Uint8Array(dkLen);
// U1 = PRF(Password, Salt + INT_32_BE(i))
const PRF = hmac.create(hash, password);
const PRFSalt = PRF._cloneInto().update(salt);
return { c, dkLen, asyncTick, DK, PRF, PRFSalt };
}
function pbkdf2Output(PRF, PRFSalt, DK, prfW, u) {
PRF.destroy();
PRFSalt.destroy();
if (prfW)
prfW.destroy();
clean(u);
return DK;
}
/**
* PBKDF2-HMAC: RFC 2898 key derivation function
* @param hash - hash function that would be used e.g. sha256
* @param password - password from which a derived key is generated
* @param salt - cryptographic salt
* @param opts - {c, dkLen} where c is work factor and dkLen is output message size
* @example
* const key = pbkdf2(sha256, 'password', 'salt', { dkLen: 32, c: Math.pow(2, 18) });
*/
function pbkdf2(hash, password, salt, opts) {
const { c, dkLen, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);
let prfW; // Working copy
const arr = new Uint8Array(4);
const view = createView(arr);
const u = new Uint8Array(PRF.outputLen);
// DK = T1 + T2 + ⋯ + Tdklen/hlen
for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PR