8674 lines
541 KiB
JavaScript
8674 lines
541 KiB
JavaScript
|
(function (global, factory) {
|
||
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@polkadot/util')) :
|
||
|
typeof define === 'function' && define.amd ? define(['exports', '@polkadot/util'], factory) :
|
||
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.polkadotUtilCrypto = {}, global.polkadotUtil));
|
||
|
})(this, (function (exports, util) { 'use strict';
|
||
|
|
||
|
const global = typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : window;
|
||
|
|
||
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
||
|
const packageInfo$2 = { name: '@polkadot/x-global', path: (({ url: (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.src || new URL('bundle-polkadot-util-crypto.js', document.baseURI).href)) }) && (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.src || new URL('bundle-polkadot-util-crypto.js', document.baseURI).href))) ? new URL((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.src || new URL('bundle-polkadot-util-crypto.js', document.baseURI).href))).pathname.substring(0, new URL((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.src || new URL('bundle-polkadot-util-crypto.js', document.baseURI).href))).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '12.6.1' };
|
||
|
|
||
|
function evaluateThis(fn) {
|
||
|
return fn('return this');
|
||
|
}
|
||
|
const xglobal = (typeof globalThis !== 'undefined'
|
||
|
? globalThis
|
||
|
: typeof global !== 'undefined'
|
||
|
? global
|
||
|
: typeof self !== 'undefined'
|
||
|
? self
|
||
|
: typeof window !== 'undefined'
|
||
|
? window
|
||
|
: evaluateThis(Function));
|
||
|
function extractGlobal(name, fallback) {
|
||
|
return typeof xglobal[name] === 'undefined'
|
||
|
? fallback
|
||
|
: xglobal[name];
|
||
|
}
|
||
|
function exposeGlobal(name, fallback) {
|
||
|
if (typeof xglobal[name] === 'undefined') {
|
||
|
xglobal[name] = fallback;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const build = /*#__PURE__*/Object.freeze({
|
||
|
__proto__: null,
|
||
|
exposeGlobal: exposeGlobal,
|
||
|
extractGlobal: extractGlobal,
|
||
|
packageInfo: packageInfo$2,
|
||
|
xglobal: xglobal
|
||
|
});
|
||
|
|
||
|
function invalidFallback() {
|
||
|
return Number.NaN;
|
||
|
}
|
||
|
const BigInt$1 = extractGlobal('BigInt', invalidFallback);
|
||
|
|
||
|
exposeGlobal('BigInt', BigInt$1);
|
||
|
|
||
|
function getDefaultExportFromCjs (x) {
|
||
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
||
|
}
|
||
|
|
||
|
function getAugmentedNamespace(n) {
|
||
|
if (n.__esModule) return n;
|
||
|
var f = n.default;
|
||
|
if (typeof f == "function") {
|
||
|
var a = function a () {
|
||
|
if (this instanceof a) {
|
||
|
return Reflect.construct(f, arguments, this.constructor);
|
||
|
}
|
||
|
return f.apply(this, arguments);
|
||
|
};
|
||
|
a.prototype = f.prototype;
|
||
|
} else a = {};
|
||
|
Object.defineProperty(a, '__esModule', {value: true});
|
||
|
Object.keys(n).forEach(function (k) {
|
||
|
var d = Object.getOwnPropertyDescriptor(n, k);
|
||
|
Object.defineProperty(a, k, d.get ? d : {
|
||
|
enumerable: true,
|
||
|
get: function () {
|
||
|
return n[k];
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
return a;
|
||
|
}
|
||
|
|
||
|
var browser = {};
|
||
|
|
||
|
const require$$0 = /*@__PURE__*/getAugmentedNamespace(build);
|
||
|
|
||
|
var packageInfo$1 = {};
|
||
|
|
||
|
Object.defineProperty(packageInfo$1, "__esModule", { value: true });
|
||
|
packageInfo$1.packageInfo = void 0;
|
||
|
packageInfo$1.packageInfo = { name: '@polkadot/x-randomvalues', path: typeof __dirname === 'string' ? __dirname : 'auto', type: 'cjs', version: '12.6.1' };
|
||
|
|
||
|
(function (exports) {
|
||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
exports.getRandomValues = exports.crypto = exports.packageInfo = void 0;
|
||
|
const x_global_1 = require$$0;
|
||
|
var packageInfo_js_1 = packageInfo$1;
|
||
|
Object.defineProperty(exports, "packageInfo", { enumerable: true, get: function () { return packageInfo_js_1.packageInfo; } });
|
||
|
exports.crypto = x_global_1.xglobal.crypto;
|
||
|
function getRandomValues(arr) {
|
||
|
return exports.crypto.getRandomValues(arr);
|
||
|
}
|
||
|
exports.getRandomValues = getRandomValues;
|
||
|
} (browser));
|
||
|
getDefaultExportFromCjs(browser);
|
||
|
|
||
|
const DEFAULT_CRYPTO = { getRandomValues: browser.getRandomValues };
|
||
|
const DEFAULT_SELF = { crypto: DEFAULT_CRYPTO };
|
||
|
class Wbg {
|
||
|
__internal__bridge;
|
||
|
constructor(bridge) {
|
||
|
this.__internal__bridge = bridge;
|
||
|
}
|
||
|
abort = () => {
|
||
|
throw new Error('abort');
|
||
|
};
|
||
|
__wbindgen_is_undefined = (idx) => {
|
||
|
return this.__internal__bridge.getObject(idx) === undefined;
|
||
|
};
|
||
|
__wbindgen_throw = (ptr, len) => {
|
||
|
throw new Error(this.__internal__bridge.getString(ptr, len));
|
||
|
};
|
||
|
__wbg_self_1b7a39e3a92c949c = () => {
|
||
|
return this.__internal__bridge.addObject(DEFAULT_SELF);
|
||
|
};
|
||
|
__wbg_require_604837428532a733 = (ptr, len) => {
|
||
|
throw new Error(`Unable to require ${this.__internal__bridge.getString(ptr, len)}`);
|
||
|
};
|
||
|
__wbg_crypto_968f1772287e2df0 = (_idx) => {
|
||
|
return this.__internal__bridge.addObject(DEFAULT_CRYPTO);
|
||
|
};
|
||
|
__wbg_getRandomValues_a3d34b4fee3c2869 = (_idx) => {
|
||
|
return this.__internal__bridge.addObject(DEFAULT_CRYPTO.getRandomValues);
|
||
|
};
|
||
|
__wbg_getRandomValues_f5e14ab7ac8e995d = (_arg0, ptr, len) => {
|
||
|
DEFAULT_CRYPTO.getRandomValues(this.__internal__bridge.getU8a(ptr, len));
|
||
|
};
|
||
|
__wbg_randomFillSync_d5bd2d655fdf256a = (_idx, _ptr, _len) => {
|
||
|
throw new Error('randomFillsync is not available');
|
||
|
};
|
||
|
__wbindgen_object_drop_ref = (idx) => {
|
||
|
this.__internal__bridge.takeObject(idx);
|
||
|
};
|
||
|
}
|
||
|
|
||
|
class Bridge {
|
||
|
__internal__createWasm;
|
||
|
__internal__heap;
|
||
|
__internal__wbg;
|
||
|
__internal__cachegetInt32;
|
||
|
__internal__cachegetUint8;
|
||
|
__internal__heapNext;
|
||
|
__internal__wasm;
|
||
|
__internal__wasmError;
|
||
|
__internal__wasmPromise;
|
||
|
__internal__type;
|
||
|
constructor(createWasm) {
|
||
|
this.__internal__createWasm = createWasm;
|
||
|
this.__internal__cachegetInt32 = null;
|
||
|
this.__internal__cachegetUint8 = null;
|
||
|
this.__internal__heap = new Array(32)
|
||
|
.fill(undefined)
|
||
|
.concat(undefined, null, true, false);
|
||
|
this.__internal__heapNext = this.__internal__heap.length;
|
||
|
this.__internal__type = 'none';
|
||
|
this.__internal__wasm = null;
|
||
|
this.__internal__wasmError = null;
|
||
|
this.__internal__wasmPromise = null;
|
||
|
this.__internal__wbg = { ...new Wbg(this) };
|
||
|
}
|
||
|
get error() {
|
||
|
return this.__internal__wasmError;
|
||
|
}
|
||
|
get type() {
|
||
|
return this.__internal__type;
|
||
|
}
|
||
|
get wasm() {
|
||
|
return this.__internal__wasm;
|
||
|
}
|
||
|
async init(createWasm) {
|
||
|
if (!this.__internal__wasmPromise || createWasm) {
|
||
|
this.__internal__wasmPromise = (createWasm || this.__internal__createWasm)(this.__internal__wbg);
|
||
|
}
|
||
|
const { error, type, wasm } = await this.__internal__wasmPromise;
|
||
|
this.__internal__type = type;
|
||
|
this.__internal__wasm = wasm;
|
||
|
this.__internal__wasmError = error;
|
||
|
return this.__internal__wasm;
|
||
|
}
|
||
|
getObject(idx) {
|
||
|
return this.__internal__heap[idx];
|
||
|
}
|
||
|
dropObject(idx) {
|
||
|
if (idx < 36) {
|
||
|
return;
|
||
|
}
|
||
|
this.__internal__heap[idx] = this.__internal__heapNext;
|
||
|
this.__internal__heapNext = idx;
|
||
|
}
|
||
|
takeObject(idx) {
|
||
|
const ret = this.getObject(idx);
|
||
|
this.dropObject(idx);
|
||
|
return ret;
|
||
|
}
|
||
|
addObject(obj) {
|
||
|
if (this.__internal__heapNext === this.__internal__heap.length) {
|
||
|
this.__internal__heap.push(this.__internal__heap.length + 1);
|
||
|
}
|
||
|
const idx = this.__internal__heapNext;
|
||
|
this.__internal__heapNext = this.__internal__heap[idx];
|
||
|
this.__internal__heap[idx] = obj;
|
||
|
return idx;
|
||
|
}
|
||
|
getInt32() {
|
||
|
if (this.__internal__cachegetInt32 === null || this.__internal__cachegetInt32.buffer !== this.__internal__wasm.memory.buffer) {
|
||
|
this.__internal__cachegetInt32 = new Int32Array(this.__internal__wasm.memory.buffer);
|
||
|
}
|
||
|
return this.__internal__cachegetInt32;
|
||
|
}
|
||
|
getUint8() {
|
||
|
if (this.__internal__cachegetUint8 === null || this.__internal__cachegetUint8.buffer !== this.__internal__wasm.memory.buffer) {
|
||
|
this.__internal__cachegetUint8 = new Uint8Array(this.__internal__wasm.memory.buffer);
|
||
|
}
|
||
|
return this.__internal__cachegetUint8;
|
||
|
}
|
||
|
getU8a(ptr, len) {
|
||
|
return this.getUint8().subarray(ptr / 1, ptr / 1 + len);
|
||
|
}
|
||
|
getString(ptr, len) {
|
||
|
return util.u8aToString(this.getU8a(ptr, len));
|
||
|
}
|
||
|
allocU8a(arg) {
|
||
|
const ptr = this.__internal__wasm.__wbindgen_malloc(arg.length * 1);
|
||
|
this.getUint8().set(arg, ptr / 1);
|
||
|
return [ptr, arg.length];
|
||
|
}
|
||
|
allocString(arg) {
|
||
|
return this.allocU8a(util.stringToU8a(arg));
|
||
|
}
|
||
|
resultU8a() {
|
||
|
const r0 = this.getInt32()[8 / 4 + 0];
|
||
|
const r1 = this.getInt32()[8 / 4 + 1];
|
||
|
const ret = this.getU8a(r0, r1).slice();
|
||
|
this.__internal__wasm.__wbindgen_free(r0, r1 * 1);
|
||
|
return ret;
|
||
|
}
|
||
|
resultString() {
|
||
|
return util.u8aToString(this.resultU8a());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function createWasmFn(root, wasmBytes, asmFn) {
|
||
|
return async (wbg) => {
|
||
|
const result = {
|
||
|
error: null,
|
||
|
type: 'none',
|
||
|
wasm: null
|
||
|
};
|
||
|
try {
|
||
|
if (!wasmBytes?.length) {
|
||
|
throw new Error('No WebAssembly provided for initialization');
|
||
|
}
|
||
|
else if (typeof WebAssembly !== 'object' || typeof WebAssembly.instantiate !== 'function') {
|
||
|
throw new Error('WebAssembly is not available in your environment');
|
||
|
}
|
||
|
const source = await WebAssembly.instantiate(wasmBytes, { wbg });
|
||
|
result.wasm = source.instance.exports;
|
||
|
result.type = 'wasm';
|
||
|
}
|
||
|
catch (error) {
|
||
|
if (typeof asmFn === 'function') {
|
||
|
result.wasm = asmFn(wbg);
|
||
|
result.type = 'asm';
|
||
|
}
|
||
|
else {
|
||
|
result.error = `FATAL: Unable to initialize @polkadot/wasm-${root}:: ${error.message}`;
|
||
|
console.error(result.error);
|
||
|
}
|
||
|
}
|
||
|
return result;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
const chr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||
|
const map = new Array(256);
|
||
|
for (let i = 0, count = chr.length; i < count; i++) {
|
||
|
map[chr.charCodeAt(i)] = i;
|
||
|
}
|
||
|
function base64Decode$1(data, out) {
|
||
|
let byte = 0;
|
||
|
let bits = 0;
|
||
|
let pos = -1;
|
||
|
for (let i = 0, count = out.length; pos < count; i++) {
|
||
|
byte = (byte << 6) | map[data.charCodeAt(i)];
|
||
|
if ((bits += 6) >= 8) {
|
||
|
out[++pos] = (byte >>> (bits -= 8)) & 0xff;
|
||
|
}
|
||
|
}
|
||
|
return out;
|
||
|
}
|
||
|
|
||
|
const u8 = Uint8Array, u16 = Uint16Array, u32$1 = Uint32Array;
|
||
|
const clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
|
||
|
const fleb = new u8([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0, 0]);
|
||
|
const fdeb = new u8([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 0, 0]);
|
||
|
const freb = (eb, start) => {
|
||
|
const b = new u16(31);
|
||
|
for (let i = 0; i < 31; ++i) {
|
||
|
b[i] = start += 1 << eb[i - 1];
|
||
|
}
|
||
|
const r = new u32$1(b[30]);
|
||
|
for (let i = 1; i < 30; ++i) {
|
||
|
for (let j = b[i]; j < b[i + 1]; ++j) {
|
||
|
r[j] = ((j - b[i]) << 5) | i;
|
||
|
}
|
||
|
}
|
||
|
return [b, r];
|
||
|
};
|
||
|
const [fl, revfl] = freb(fleb, 2);
|
||
|
fl[28] = 258, revfl[258] = 28;
|
||
|
const [fd] = freb(fdeb, 0);
|
||
|
const rev = new u16(32768);
|
||
|
for (let i = 0; i < 32768; ++i) {
|
||
|
let x = ((i & 0xAAAA) >>> 1) | ((i & 0x5555) << 1);
|
||
|
x = ((x & 0xCCCC) >>> 2) | ((x & 0x3333) << 2);
|
||
|
x = ((x & 0xF0F0) >>> 4) | ((x & 0x0F0F) << 4);
|
||
|
rev[i] = (((x & 0xFF00) >>> 8) | ((x & 0x00FF) << 8)) >>> 1;
|
||
|
}
|
||
|
const hMap = ((cd, mb, r) => {
|
||
|
const s = cd.length;
|
||
|
let i = 0;
|
||
|
const l = new u16(mb);
|
||
|
for (; i < s; ++i)
|
||
|
++l[cd[i] - 1];
|
||
|
const le = new u16(mb);
|
||
|
for (i = 0; i < mb; ++i) {
|
||
|
le[i] = (le[i - 1] + l[i - 1]) << 1;
|
||
|
}
|
||
|
let co;
|
||
|
if (r) {
|
||
|
co = new u16(1 << mb);
|
||
|
const rvb = 15 - mb;
|
||
|
for (i = 0; i < s; ++i) {
|
||
|
if (cd[i]) {
|
||
|
const sv = (i << 4) | cd[i];
|
||
|
const r = mb - cd[i];
|
||
|
let v = le[cd[i] - 1]++ << r;
|
||
|
for (const m = v | ((1 << r) - 1); v <= m; ++v) {
|
||
|
co[rev[v] >>> rvb] = sv;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
co = new u16(s);
|
||
|
for (i = 0; i < s; ++i)
|
||
|
co[i] = rev[le[cd[i] - 1]++] >>> (15 - cd[i]);
|
||
|
}
|
||
|
return co;
|
||
|
});
|
||
|
const flt = new u8(288);
|
||
|
for (let i = 0; i < 144; ++i)
|
||
|
flt[i] = 8;
|
||
|
for (let i = 144; i < 256; ++i)
|
||
|
flt[i] = 9;
|
||
|
for (let i = 256; i < 280; ++i)
|
||
|
flt[i] = 7;
|
||
|
for (let i = 280; i < 288; ++i)
|
||
|
flt[i] = 8;
|
||
|
const fdt = new u8(32);
|
||
|
for (let i = 0; i < 32; ++i)
|
||
|
fdt[i] = 5;
|
||
|
const flrm = hMap(flt, 9, 1);
|
||
|
const fdrm = hMap(fdt, 5, 1);
|
||
|
const bits = (d, p, m) => {
|
||
|
const o = p >>> 3;
|
||
|
return ((d[o] | (d[o + 1] << 8)) >>> (p & 7)) & m;
|
||
|
};
|
||
|
const bits16 = (d, p) => {
|
||
|
const o = p >>> 3;
|
||
|
return ((d[o] | (d[o + 1] << 8) | (d[o + 2] << 16)) >>> (p & 7));
|
||
|
};
|
||
|
const shft = (p) => (p >>> 3) + (p & 7 && 1);
|
||
|
const slc = (v, s, e) => {
|
||
|
if (s == null || s < 0)
|
||
|
s = 0;
|
||
|
if (e == null || e > v.length)
|
||
|
e = v.length;
|
||
|
const n = new (v instanceof u16 ? u16 : v instanceof u32$1 ? u32$1 : u8)(e - s);
|
||
|
n.set(v.subarray(s, e));
|
||
|
return n;
|
||
|
};
|
||
|
const max = (a) => {
|
||
|
let m = a[0];
|
||
|
for (let i = 1, count = a.length; i < count; ++i) {
|
||
|
if (a[i] > m)
|
||
|
m = a[i];
|
||
|
}
|
||
|
return m;
|
||
|
};
|
||
|
const inflt = (dat, buf, st) => {
|
||
|
const noSt = !st || st.i;
|
||
|
if (!st)
|
||
|
st = {};
|
||
|
const sl = dat.length;
|
||
|
const noBuf = !buf || !noSt;
|
||
|
if (!buf)
|
||
|
buf = new u8(sl * 3);
|
||
|
const cbuf = (l) => {
|
||
|
let bl = buf.length;
|
||
|
if (l > bl) {
|
||
|
const nbuf = new u8(Math.max(bl << 1, l));
|
||
|
nbuf.set(buf);
|
||
|
buf = nbuf;
|
||
|
}
|
||
|
};
|
||
|
let final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;
|
||
|
if (final && !lm)
|
||
|
return buf;
|
||
|
const tbts = sl << 3;
|
||
|
do {
|
||
|
if (!lm) {
|
||
|
st.f = final = bits(dat, pos, 1);
|
||
|
const type = bits(dat, pos + 1, 3);
|
||
|
pos += 3;
|
||
|
if (!type) {
|
||
|
const s = shft(pos) + 4, l = dat[s - 4] | (dat[s - 3] << 8), t = s + l;
|
||
|
if (t > sl) {
|
||
|
if (noSt)
|
||
|
throw 'unexpected EOF';
|
||
|
break;
|
||
|
}
|
||
|
if (noBuf)
|
||
|
cbuf(bt + l);
|
||
|
buf.set(dat.subarray(s, t), bt);
|
||
|
st.b = bt += l, st.p = pos = t << 3;
|
||
|
continue;
|
||
|
}
|
||
|
else if (type == 1)
|
||
|
lm = flrm, dm = fdrm, lbt = 9, dbt = 5;
|
||
|
else if (type == 2) {
|
||
|
const hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;
|
||
|
const tl = hLit + bits(dat, pos + 5, 31) + 1;
|
||
|
pos += 14;
|
||
|
const ldt = new u8(tl);
|
||
|
const clt = new u8(19);
|
||
|
for (let i = 0; i < hcLen; ++i) {
|
||
|
clt[clim[i]] = bits(dat, pos + i * 3, 7);
|
||
|
}
|
||
|
pos += hcLen * 3;
|
||
|
const clb = max(clt), clbmsk = (1 << clb) - 1;
|
||
|
if (!noSt && pos + tl * (clb + 7) > tbts)
|
||
|
break;
|
||
|
const clm = hMap(clt, clb, 1);
|
||
|
for (let i = 0; i < tl;) {
|
||
|
const r = clm[bits(dat, pos, clbmsk)];
|
||
|
pos += r & 15;
|
||
|
const s = r >>> 4;
|
||
|
if (s < 16) {
|
||
|
ldt[i++] = s;
|
||
|
}
|
||
|
else {
|
||
|
let c = 0, n = 0;
|
||
|
if (s == 16)
|
||
|
n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i - 1];
|
||
|
else if (s == 17)
|
||
|
n = 3 + bits(dat, pos, 7), pos += 3;
|
||
|
else if (s == 18)
|
||
|
n = 11 + bits(dat, pos, 127), pos += 7;
|
||
|
while (n--)
|
||
|
ldt[i++] = c;
|
||
|
}
|
||
|
}
|
||
|
const lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);
|
||
|
lbt = max(lt);
|
||
|
dbt = max(dt);
|
||
|
lm = hMap(lt, lbt, 1);
|
||
|
dm = hMap(dt, dbt, 1);
|
||
|
}
|
||
|
else
|
||
|
throw 'invalid block type';
|
||
|
if (pos > tbts)
|
||
|
throw 'unexpected EOF';
|
||
|
}
|
||
|
if (noBuf)
|
||
|
cbuf(bt + 131072);
|
||
|
const lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
|
||
|
const mxa = lbt + dbt + 18;
|
||
|
while (noSt || pos + mxa < tbts) {
|
||
|
const c = lm[bits16(dat, pos) & lms], sym = c >>> 4;
|
||
|
pos += c & 15;
|
||
|
if (pos > tbts)
|
||
|
throw 'unexpected EOF';
|
||
|
if (!c)
|
||
|
throw 'invalid length/literal';
|
||
|
if (sym < 256)
|
||
|
buf[bt++] = sym;
|
||
|
else if (sym == 256) {
|
||
|
lm = undefined;
|
||
|
break;
|
||
|
}
|
||
|
else {
|
||
|
let add = sym - 254;
|
||
|
if (sym > 264) {
|
||
|
const i = sym - 257, b = fleb[i];
|
||
|
add = bits(dat, pos, (1 << b) - 1) + fl[i];
|
||
|
pos += b;
|
||
|
}
|
||
|
const d = dm[bits16(dat, pos) & dms], dsym = d >>> 4;
|
||
|
if (!d)
|
||
|
throw 'invalid distance';
|
||
|
pos += d & 15;
|
||
|
let dt = fd[dsym];
|
||
|
if (dsym > 3) {
|
||
|
const b = fdeb[dsym];
|
||
|
dt += bits16(dat, pos) & ((1 << b) - 1), pos += b;
|
||
|
}
|
||
|
if (pos > tbts)
|
||
|
throw 'unexpected EOF';
|
||
|
if (noBuf)
|
||
|
cbuf(bt + 131072);
|
||
|
const end = bt + add;
|
||
|
for (; bt < end; bt += 4) {
|
||
|
buf[bt] = buf[bt - dt];
|
||
|
buf[bt + 1] = buf[bt + 1 - dt];
|
||
|
buf[bt + 2] = buf[bt + 2 - dt];
|
||
|
buf[bt + 3] = buf[bt + 3 - dt];
|
||
|
}
|
||
|
bt = end;
|
||
|
}
|
||
|
}
|
||
|
st.l = lm, st.p = pos, st.b = bt;
|
||
|
if (lm)
|
||
|
final = 1, st.m = lbt, st.d = dm, st.n = dbt;
|
||
|
} while (!final);
|
||
|
return bt == buf.length ? buf : slc(buf, 0, bt);
|
||
|
};
|
||
|
const zlv = (d) => {
|
||
|
if ((d[0] & 15) != 8 || (d[0] >>> 4) > 7 || ((d[0] << 8 | d[1]) % 31))
|
||
|
throw 'invalid zlib data';
|
||
|
if (d[1] & 32)
|
||
|
throw 'invalid zlib data: preset dictionaries not supported';
|
||
|
};
|
||
|
function unzlibSync(data, out) {
|
||
|
return inflt((zlv(data), data.subarray(2, -4)), out);
|
||
|
}
|
||
|
|
||
|
var lenIn = 171008;
|
||
|
var lenOut = 339468;
|
||
|
var bytes_1 = 'eNqkvQmYXVd153vuuVPVvTXcmqTSfOpKtmVbskaXJMvYugU2Tuj3mi8vL1++9/X3ZNmSwSXjoSxseJ9iF1gy4oUEhZhEBPIiGhLUEAUxBTkhIIiTVhN3EMMDAaYRgQR3QkDBdMeAg/v3X2ufc4caNCDZOvuss/faa6299tprrz3caNeDr8lFUZT7x9yK2+NHH41uzz+qf3P8z2vuUXvnkdM/BdJ8KOrBs2RPEhHfwgupsqeyjGlBx/LI7ZFV8ohX8Aj/kuwOZVSqkqVVpKv5IUUsqh4JxD1ihD5iGR/xP8IQknop2oszRnW5R6L4Q3FX/uE7XrVw586H77j73t2v2nPvzrsf3Pnae3fvuevue/fsjor6urjl6313TO65c9/O3VP33b9zas9dUawMS5ThVTsf3HPPXTs33LFl16Ztezbt2rbxzm2bt90ZdSvHMs9x59Tr7993385t41vv2rBly8aNW7fs2bj7rvVezZWe51V79v3Srnt33/eaX9l1z2v3PLhz16bdmzbfsfmuPXs23blx6/g2z7zcM0/teeC1d0/t2Tm+fvPWTVs2b9x6/aaNu7Zs2hTl58F41/V7NmzeBZ13bt2zbdv1u6OcMl8RMFrOW+++557/4/X33rlz9/V37N64e/z66+/afdfG68d3kfej+Q/nc4ND0XCUy5UquahciXO5fBTl40JcLhWrpRzwqNpVKpe6yiPFXCEq5/LlXFcUlaOoiobl4q4oF+UKPZTJ5ytV8itV6MnF5VxUiHLFaEGuDDRfWDha0ZO3PNBSFFMuKuejGDSCUTJXjEGZ6y5EXbl8UXAIiCKl+Mj/+VIpjhZFfC4BjnMl/hapL84VQaAC0eLY/kTF/oiPUbREKKElzvG3J5+v5cVfvisqqL6oUCqCNtcPQbmoV50GzHEZoniPCvluaIyEJ1oqpkvFckmcliE8N5CjbK1Y6h2QxGCBz6qHF7gqUSHFomVxnC/Eue7e7jgGxif4MRpzRaTQnSdV4v/8csRL+XyUL5AB1Ppj/ZgKKVPs6+vLFxFYoZi7P/eKV8ByNFTqpvs1pqdPRdXyW8vXlF6z5zX3Tb0+jgb3vG7fzjvuvn/TNnTm3j1Tu/btiV463ASiunvu3Yfqvz763dxoG/w1d997Nx3gzqk9+6LbB9o+PbiHjjTcgvuhXffcvVu4f6km4J7dO++auu81nu+xXDXAHrz7VfdGK3vD20N7pu6+6/XRgH29455de/dsvCO6tl9vr37Nrjt3PvjqXahntLYNcv2GjdHBnKHYu+fOO3ftVZaHW96V4R25igD337EXDY9+398etJ4abfAXx/1b4ZPj/aNcl972PXzf66LVI/Zhz53377z/tXfsvPO+19w/tefBB6P35IbaPux53f30ruhIzoRh4Cbn/7cJw4BTe+68D4aj7UaqgUwa6xfb+9TO3UjjoT0w8fr7d909tfPVu6Z2R+NzfHzwvrv2Rcmi9o9Qc8/dyEjfbvKKp1po+RUTMyCr9honYypthJGe8L7rVVN79kTb7PWhqbs8d6UvfQ3Ze1ZOvfbBfeICKe7dsPOh9Ts379yAlO7dp5yojHThULxq3my79zyI5r0++v14/az5sNi7XnvPvp0Yrj2v2nXPzjt33XPPHbvu3LvzrnujD+avm7fMnqmp+6Y6SqxoMfq7du82Rd6nr/ffdzcUTUV/kO9vyXKXJHEwP9ACeg347rszOh0PtgBh1qDfi4dboHtedy/Y75vaE/1uvvutGKVGrvqLJ/OH8x/I/4/c7+WP5L8eH8k/mf/t/P/zQu7J/Nfi34yfzN/7yifyJ/IfwhjfuvPJ/ENP8n3zb+Z+zPd35v84/288t/5fJ/IfIcfvkO/J/HH+fzL/Z5Rc+mT+z3k8nvuD3AmseZrhG/GbKPRU7uNAnsx/O/ex/J/mpz6Y/2C+8vUjlQ/nn7spd9ujSZREq+Pb65UknhyPb0+iRjI5dktSadz8wFglvyOJG6eipLK3fvMv3FLYkVSSWyaTXHJz7c7FXvBX65XG6D6yd+3D/LxQfmBK6Yca0z/LP0Bq9KGpqXpeGf/DRWQsNBY9nBQafQ8/yL/5hx6cVMGXXURBiFkdJxeRcVQZV11Exj6R0mek9Bkpk0m+0f8w//QCyjcqgOpFYbvxIrCNKOOOi8i4QNUusGoXhGopufkiSm5Sxq0XkXGzqthsVWx2IeetkldeRNl1yrjmIjL2KOP6i8hYETUVo6bSZPi2ekklSy0lSYeSfFLJ9cq4+iIy9qqKXquiV1UkfVRSUGMWrDEL3pglQUoGKTmkLEjZIGWHdAnSZZAuh3Qbvb9cr4qMagsZpAMZfBIZ14uM642M642MdZNJl5X+dxdReoNKb7DSG6z0+smkPJksFnixgRcbeMFkUppMRgQeMfCIgTfD8WSySeBNBt5k4Mpkcv1k0iNwj4F7DNw7mWyYTIpitmjMFp3ZqiBVg1Qd0i9Iv0H6HTIgyIBBBhwyJMiQQYYcMizIsEGGHbJQkIUGWeiQRSJqkRG1yIjKC5A3QN4AUD4wmawTeJ2B1xkYyvsnk/UCrzfwegMvnkyqk0m36um2erq9niWCLDHIEocsFWSpQZY6ZJmEAb6i4SsaPsQ5NJksU95llneZ510OYrJ2W9ZuyzqAvnUJ2GXALgNCI2jLApcNXDYwNC6lCQUuGbhk4OJksmQSQVDbIqttkde2QpAVBlnhkESQxCCJQ8YEGTPImEPqk0iZGhZaDQutBmodm6Q5AA8beNjA1JrAqcBDBh4yMGq/AvELPGDgAQOjz4sQv8D9Bu43MIq6EPELXDVw1cAo6vBkslzkLTfyljt5KwVZaZCVDlklyCqDrHLIFYJcYZArHHKlIFca5EqHXCXIVQa5yiGrBVltkNUOuVpEXW1EXW1ELRNgmQGWGQDKr6BRBF5q4KUGhvJVNIrASwy8xMDoxMrJpK566lZP3eu5RpBrDHKNQ64V5FqDXOuQNRIG+JYbvuWGD3FeOZmsUd41lneN510LYrLWLWvdsl6Bmo0JOGbAMQNCI2gTgRMDJwaGxmtpQoFXGHiFgZdPJtdMIghqu9pqu9pru06Q6wxynUPGBRk3yLhDtgiyxSBbHLJ1EilTw2qrYbXVQK1bJmkOwFcZ+CoDU+s4nAp8pYGvNDCKeh3iF/gKA19hYBT1asQv8CoDrzIwiroa8Qu80sArDYyiXjWZrBV5a428tU7eRkE2GmSjQ7YJss0g2xxygyA3GOQGh2wXZLtBtjvkRkFuNMiNDtkhyA6D7HBII7kxuSHZmKxJrknGkhXJwmQo6U+KybpkAT6VeSVL6y/Xo1YfbSx+OBltjFB6tFF+2L2g0fqEHsP1lwB9IJlgoGwc+eaxJwqT9UF96KnfNlnHnPcko5NJb/KSyaQvmZg03C958AH+Jy28FcNbMbyN33rzN95cnqy/VAi66rdOMmxTgOyjZO9R9h7L3uPZP3Tohc8X9tZfpuyF+k2T9V6y95C9QvZeZe+17L2e/eunj304t7f+C8oeQVu9BnW9ZO8he03Za5a9FrIf+Ppn85P1X0xuBetNU2BNbjKPYbmoHjKqK5LG4GS9D67BkYyIV8a2nmQTcNI10Pcqj9APGvpBR/8v73nqc8VJ3KRK0jcFZj1B3yf0fYa+z9G/FDFM4rHVkkGQ1YCMCNmIIRtxZM/85A3fL+2tb6ZikFVgyZD1CFmPIetxZC9DSGJ8MBkB2eCsjH/gM7/5vuJeWgHpQJCQ9YKsV8h6DVmvI/sFZ1x8g2xkVjafff+3PhWrjXpFWQ/SmIPNXzQ2cRcGNWLW5E+MaJBc0ML4AqFfYOgXOPo3/OlvPJGbxN82xnvnZnxTxviCORn/5K//9bvjSZzKCzG+OWNcyBbMyvhf/vRDx2jf9Rdk/GLa90d/9uO30zE2XJBNb1+kWJAu5tFN8OKYLGhp8ZlSfOO7Dv64vBeGLsT44sk6XaKPlhHjavE+IeszZH2O7Ks/fOu70cURagcZjPMEWV7I8oaM2YqQrZusYy3gJJPizC7+lt8//Fx+b30BSArGOE+QFYSsYMjwloVsPbMfGQDQgaxvVgPwqT9+
|
||
|
|
||
|
const wasmBytes = unzlibSync(base64Decode$1(bytes_1, new Uint8Array(lenIn)), new Uint8Array(lenOut));
|
||
|
|
||
|
const createWasm = createWasmFn('crypto', wasmBytes, null);
|
||
|
|
||
|
const bridge = new Bridge(createWasm);
|
||
|
async function initBridge(createWasm) {
|
||
|
return bridge.init(createWasm);
|
||
|
}
|
||
|
|
||
|
function withWasm(fn) {
|
||
|
return (...params) => {
|
||
|
if (!bridge.wasm) {
|
||
|
throw new Error('The WASM interface has not been initialized. Ensure that you wait for the initialization Promise with waitReady() from @polkadot/wasm-crypto (or cryptoWaitReady() from @polkadot/util-crypto) before attempting to use WASM-only interfaces.');
|
||
|
}
|
||
|
return fn(bridge.wasm, ...params);
|
||
|
};
|
||
|
}
|
||
|
const bip39Generate = withWasm((wasm, words) => {
|
||
|
wasm.ext_bip39_generate(8, words);
|
||
|
return bridge.resultString();
|
||
|
});
|
||
|
const bip39ToEntropy = withWasm((wasm, phrase) => {
|
||
|
wasm.ext_bip39_to_entropy(8, ...bridge.allocString(phrase));
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const bip39ToMiniSecret = withWasm((wasm, phrase, password) => {
|
||
|
wasm.ext_bip39_to_mini_secret(8, ...bridge.allocString(phrase), ...bridge.allocString(password));
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const bip39ToSeed = withWasm((wasm, phrase, password) => {
|
||
|
wasm.ext_bip39_to_seed(8, ...bridge.allocString(phrase), ...bridge.allocString(password));
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const bip39Validate = withWasm((wasm, phrase) => {
|
||
|
const ret = wasm.ext_bip39_validate(...bridge.allocString(phrase));
|
||
|
return ret !== 0;
|
||
|
});
|
||
|
const ed25519KeypairFromSeed = withWasm((wasm, seed) => {
|
||
|
wasm.ext_ed_from_seed(8, ...bridge.allocU8a(seed));
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const ed25519Sign$1 = withWasm((wasm, pubkey, seckey, message) => {
|
||
|
wasm.ext_ed_sign(8, ...bridge.allocU8a(pubkey), ...bridge.allocU8a(seckey), ...bridge.allocU8a(message));
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const ed25519Verify$1 = withWasm((wasm, signature, message, pubkey) => {
|
||
|
const ret = wasm.ext_ed_verify(...bridge.allocU8a(signature), ...bridge.allocU8a(message), ...bridge.allocU8a(pubkey));
|
||
|
return ret !== 0;
|
||
|
});
|
||
|
const secp256k1FromSeed = withWasm((wasm, seckey) => {
|
||
|
wasm.ext_secp_from_seed(8, ...bridge.allocU8a(seckey));
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const secp256k1Compress$1 = withWasm((wasm, pubkey) => {
|
||
|
wasm.ext_secp_pub_compress(8, ...bridge.allocU8a(pubkey));
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const secp256k1Expand$1 = withWasm((wasm, pubkey) => {
|
||
|
wasm.ext_secp_pub_expand(8, ...bridge.allocU8a(pubkey));
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const secp256k1Recover$1 = withWasm((wasm, msgHash, sig, recovery) => {
|
||
|
wasm.ext_secp_recover(8, ...bridge.allocU8a(msgHash), ...bridge.allocU8a(sig), recovery);
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const secp256k1Sign$1 = withWasm((wasm, msgHash, seckey) => {
|
||
|
wasm.ext_secp_sign(8, ...bridge.allocU8a(msgHash), ...bridge.allocU8a(seckey));
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const sr25519DeriveKeypairHard = withWasm((wasm, pair, cc) => {
|
||
|
wasm.ext_sr_derive_keypair_hard(8, ...bridge.allocU8a(pair), ...bridge.allocU8a(cc));
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const sr25519DeriveKeypairSoft = withWasm((wasm, pair, cc) => {
|
||
|
wasm.ext_sr_derive_keypair_soft(8, ...bridge.allocU8a(pair), ...bridge.allocU8a(cc));
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const sr25519DerivePublicSoft = withWasm((wasm, pubkey, cc) => {
|
||
|
wasm.ext_sr_derive_public_soft(8, ...bridge.allocU8a(pubkey), ...bridge.allocU8a(cc));
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const sr25519KeypairFromSeed = withWasm((wasm, seed) => {
|
||
|
wasm.ext_sr_from_seed(8, ...bridge.allocU8a(seed));
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const sr25519Sign$1 = withWasm((wasm, pubkey, secret, message) => {
|
||
|
wasm.ext_sr_sign(8, ...bridge.allocU8a(pubkey), ...bridge.allocU8a(secret), ...bridge.allocU8a(message));
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const sr25519Verify$1 = withWasm((wasm, signature, message, pubkey) => {
|
||
|
const ret = wasm.ext_sr_verify(...bridge.allocU8a(signature), ...bridge.allocU8a(message), ...bridge.allocU8a(pubkey));
|
||
|
return ret !== 0;
|
||
|
});
|
||
|
const sr25519Agree = withWasm((wasm, pubkey, secret) => {
|
||
|
wasm.ext_sr_agree(8, ...bridge.allocU8a(pubkey), ...bridge.allocU8a(secret));
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const vrfSign = withWasm((wasm, secret, context, message, extra) => {
|
||
|
wasm.ext_vrf_sign(8, ...bridge.allocU8a(secret), ...bridge.allocU8a(context), ...bridge.allocU8a(message), ...bridge.allocU8a(extra));
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const vrfVerify = withWasm((wasm, pubkey, context, message, extra, outAndProof) => {
|
||
|
const ret = wasm.ext_vrf_verify(...bridge.allocU8a(pubkey), ...bridge.allocU8a(context), ...bridge.allocU8a(message), ...bridge.allocU8a(extra), ...bridge.allocU8a(outAndProof));
|
||
|
return ret !== 0;
|
||
|
});
|
||
|
const blake2b$1 = withWasm((wasm, data, key, size) => {
|
||
|
wasm.ext_blake2b(8, ...bridge.allocU8a(data), ...bridge.allocU8a(key), size);
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const hmacSha256 = withWasm((wasm, key, data) => {
|
||
|
wasm.ext_hmac_sha256(8, ...bridge.allocU8a(key), ...bridge.allocU8a(data));
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const hmacSha512 = withWasm((wasm, key, data) => {
|
||
|
wasm.ext_hmac_sha512(8, ...bridge.allocU8a(key), ...bridge.allocU8a(data));
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const keccak256 = withWasm((wasm, data) => {
|
||
|
wasm.ext_keccak256(8, ...bridge.allocU8a(data));
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const keccak512 = withWasm((wasm, data) => {
|
||
|
wasm.ext_keccak512(8, ...bridge.allocU8a(data));
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const pbkdf2$1 = withWasm((wasm, data, salt, rounds) => {
|
||
|
wasm.ext_pbkdf2(8, ...bridge.allocU8a(data), ...bridge.allocU8a(salt), rounds);
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const scrypt$1 = withWasm((wasm, password, salt, log2n, r, p) => {
|
||
|
wasm.ext_scrypt(8, ...bridge.allocU8a(password), ...bridge.allocU8a(salt), log2n, r, p);
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const sha256$1 = withWasm((wasm, data) => {
|
||
|
wasm.ext_sha256(8, ...bridge.allocU8a(data));
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const sha512$1 = withWasm((wasm, data) => {
|
||
|
wasm.ext_sha512(8, ...bridge.allocU8a(data));
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
const twox = withWasm((wasm, data, rounds) => {
|
||
|
wasm.ext_twox(8, ...bridge.allocU8a(data), rounds);
|
||
|
return bridge.resultU8a();
|
||
|
});
|
||
|
function isReady() {
|
||
|
return !!bridge.wasm;
|
||
|
}
|
||
|
async function waitReady() {
|
||
|
try {
|
||
|
const wasm = await initBridge();
|
||
|
return !!wasm;
|
||
|
}
|
||
|
catch {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const cryptoIsReady = isReady;
|
||
|
function cryptoWaitReady() {
|
||
|
return waitReady()
|
||
|
.then(() => {
|
||
|
if (!isReady()) {
|
||
|
throw new Error('Unable to initialize @polkadot/util-crypto');
|
||
|
}
|
||
|
return true;
|
||
|
})
|
||
|
.catch(() => false);
|
||
|
}
|
||
|
|
||
|
cryptoWaitReady().catch(() => {
|
||
|
});
|
||
|
|
||
|
const packageInfo = { name: '@polkadot/util-crypto', path: (({ url: (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.src || new URL('bundle-polkadot-util-crypto.js', document.baseURI).href)) }) && (typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.src || new URL('bundle-polkadot-util-crypto.js', document.baseURI).href))) ? new URL((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.src || new URL('bundle-polkadot-util-crypto.js', document.baseURI).href))).pathname.substring(0, new URL((typeof document === 'undefined' && typeof location === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : typeof document === 'undefined' ? location.href : (_documentCurrentScript && _documentCurrentScript.src || new URL('bundle-polkadot-util-crypto.js', document.baseURI).href))).pathname.lastIndexOf('/') + 1) : 'auto', type: 'esm', version: '12.6.1' };
|
||
|
|
||
|
/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||
|
function assertNumber(n) {
|
||
|
if (!Number.isSafeInteger(n))
|
||
|
throw new Error(`Wrong integer: ${n}`);
|
||
|
}
|
||
|
function chain(...args) {
|
||
|
const wrap = (a, b) => (c) => a(b(c));
|
||
|
const encode = Array.from(args)
|
||
|
.reverse()
|
||
|
.reduce((acc, i) => (acc ? wrap(acc, i.encode) : i.encode), undefined);
|
||
|
const decode = args.reduce((acc, i) => (acc ? wrap(acc, i.decode) : i.decode), undefined);
|
||
|
return { encode, decode };
|
||
|
}
|
||
|
function alphabet(alphabet) {
|
||
|
return {
|
||
|
encode: (digits) => {
|
||
|
if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
|
||
|
throw new Error('alphabet.encode input should be an array of numbers');
|
||
|
return digits.map((i) => {
|
||
|
assertNumber(i);
|
||
|
if (i < 0 || i >= alphabet.length)
|
||
|
throw new Error(`Digit index outside alphabet: ${i} (alphabet: ${alphabet.length})`);
|
||
|
return alphabet[i];
|
||
|
});
|
||
|
},
|
||
|
decode: (input) => {
|
||
|
if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))
|
||
|
throw new Error('alphabet.decode input should be array of strings');
|
||
|
return input.map((letter) => {
|
||
|
if (typeof letter !== 'string')
|
||
|
throw new Error(`alphabet.decode: not string element=${letter}`);
|
||
|
const index = alphabet.indexOf(letter);
|
||
|
if (index === -1)
|
||
|
throw new Error(`Unknown letter: "${letter}". Allowed: ${alphabet}`);
|
||
|
return index;
|
||
|
});
|
||
|
},
|
||
|
};
|
||
|
}
|
||
|
function join(separator = '') {
|
||
|
if (typeof separator !== 'string')
|
||
|
throw new Error('join separator should be string');
|
||
|
return {
|
||
|
encode: (from) => {
|
||
|
if (!Array.isArray(from) || (from.length && typeof from[0] !== 'string'))
|
||
|
throw new Error('join.encode input should be array of strings');
|
||
|
for (let i of from)
|
||
|
if (typeof i !== 'string')
|
||
|
throw new Error(`join.encode: non-string input=${i}`);
|
||
|
return from.join(separator);
|
||
|
},
|
||
|
decode: (to) => {
|
||
|
if (typeof to !== 'string')
|
||
|
throw new Error('join.decode input should be string');
|
||
|
return to.split(separator);
|
||
|
},
|
||
|
};
|
||
|
}
|
||
|
function padding(bits, chr = '=') {
|
||
|
assertNumber(bits);
|
||
|
if (typeof chr !== 'string')
|
||
|
throw new Error('padding chr should be string');
|
||
|
return {
|
||
|
encode(data) {
|
||
|
if (!Array.isArray(data) || (data.length && typeof data[0] !== 'string'))
|
||
|
throw new Error('padding.encode input should be array of strings');
|
||
|
for (let i of data)
|
||
|
if (typeof i !== 'string')
|
||
|
throw new Error(`padding.encode: non-string input=${i}`);
|
||
|
while ((data.length * bits) % 8)
|
||
|
data.push(chr);
|
||
|
return data;
|
||
|
},
|
||
|
decode(input) {
|
||
|
if (!Array.isArray(input) || (input.length && typeof input[0] !== 'string'))
|
||
|
throw new Error('padding.encode input should be array of strings');
|
||
|
for (let i of input)
|
||
|
if (typeof i !== 'string')
|
||
|
throw new Error(`padding.decode: non-string input=${i}`);
|
||
|
let end = input.length;
|
||
|
if ((end * bits) % 8)
|
||
|
throw new Error('Invalid padding: string should have whole number of bytes');
|
||
|
for (; end > 0 && input[end - 1] === chr; end--) {
|
||
|
if (!(((end - 1) * bits) % 8))
|
||
|
throw new Error('Invalid padding: string has too much padding');
|
||
|
}
|
||
|
return input.slice(0, end);
|
||
|
},
|
||
|
};
|
||
|
}
|
||
|
function normalize$1(fn) {
|
||
|
if (typeof fn !== 'function')
|
||
|
throw new Error('normalize fn should be function');
|
||
|
return { encode: (from) => from, decode: (to) => fn(to) };
|
||
|
}
|
||
|
function convertRadix(data, from, to) {
|
||
|
if (from < 2)
|
||
|
throw new Error(`convertRadix: wrong from=${from}, base cannot be less than 2`);
|
||
|
if (to < 2)
|
||
|
throw new Error(`convertRadix: wrong to=${to}, base cannot be less than 2`);
|
||
|
if (!Array.isArray(data))
|
||
|
throw new Error('convertRadix: data should be array');
|
||
|
if (!data.length)
|
||
|
return [];
|
||
|
let pos = 0;
|
||
|
const res = [];
|
||
|
const digits = Array.from(data);
|
||
|
digits.forEach((d) => {
|
||
|
assertNumber(d);
|
||
|
if (d < 0 || d >= from)
|
||
|
throw new Error(`Wrong integer: ${d}`);
|
||
|
});
|
||
|
while (true) {
|
||
|
let carry = 0;
|
||
|
let done = true;
|
||
|
for (let i = pos; i < digits.length; i++) {
|
||
|
const digit = digits[i];
|
||
|
const digitBase = from * carry + digit;
|
||
|
if (!Number.isSafeInteger(digitBase) ||
|
||
|
(from * carry) / from !== carry ||
|
||
|
digitBase - digit !== from * carry) {
|
||
|
throw new Error('convertRadix: carry overflow');
|
||
|
}
|
||
|
carry = digitBase % to;
|
||
|
const rounded = Math.floor(digitBase / to);
|
||
|
digits[i] = rounded;
|
||
|
if (!Number.isSafeInteger(rounded) || rounded * to + carry !== digitBase)
|
||
|
throw new Error('convertRadix: carry overflow');
|
||
|
if (!done)
|
||
|
continue;
|
||
|
else if (!rounded)
|
||
|
pos = i;
|
||
|
else
|
||
|
done = false;
|
||
|
}
|
||
|
res.push(carry);
|
||
|
if (done)
|
||
|
break;
|
||
|
}
|
||
|
for (let i = 0; i < data.length - 1 && data[i] === 0; i++)
|
||
|
res.push(0);
|
||
|
return res.reverse();
|
||
|
}
|
||
|
const gcd = (a, b) => (!b ? a : gcd(b, a % b));
|
||
|
const radix2carry = (from, to) => from + (to - gcd(from, to));
|
||
|
function convertRadix2(data, from, to, padding) {
|
||
|
if (!Array.isArray(data))
|
||
|
throw new Error('convertRadix2: data should be array');
|
||
|
if (from <= 0 || from > 32)
|
||
|
throw new Error(`convertRadix2: wrong from=${from}`);
|
||
|
if (to <= 0 || to > 32)
|
||
|
throw new Error(`convertRadix2: wrong to=${to}`);
|
||
|
if (radix2carry(from, to) > 32) {
|
||
|
throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${radix2carry(from, to)}`);
|
||
|
}
|
||
|
let carry = 0;
|
||
|
let pos = 0;
|
||
|
const mask = 2 ** to - 1;
|
||
|
const res = [];
|
||
|
for (const n of data) {
|
||
|
assertNumber(n);
|
||
|
if (n >= 2 ** from)
|
||
|
throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);
|
||
|
carry = (carry << from) | n;
|
||
|
if (pos + from > 32)
|
||
|
throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);
|
||
|
pos += from;
|
||
|
for (; pos >= to; pos -= to)
|
||
|
res.push(((carry >> (pos - to)) & mask) >>> 0);
|
||
|
carry &= 2 ** pos - 1;
|
||
|
}
|
||
|
carry = (carry << (to - pos)) & mask;
|
||
|
if (!padding && pos >= from)
|
||
|
throw new Error('Excess padding');
|
||
|
if (!padding && carry)
|
||
|
throw new Error(`Non-zero padding: ${carry}`);
|
||
|
if (padding && pos > 0)
|
||
|
res.push(carry >>> 0);
|
||
|
return res;
|
||
|
}
|
||
|
function radix(num) {
|
||
|
assertNumber(num);
|
||
|
return {
|
||
|
encode: (bytes) => {
|
||
|
if (!(bytes instanceof Uint8Array))
|
||
|
throw new Error('radix.encode input should be Uint8Array');
|
||
|
return convertRadix(Array.from(bytes), 2 ** 8, num);
|
||
|
},
|
||
|
decode: (digits) => {
|
||
|
if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
|
||
|
throw new Error('radix.decode input should be array of strings');
|
||
|
return Uint8Array.from(convertRadix(digits, num, 2 ** 8));
|
||
|
},
|
||
|
};
|
||
|
}
|
||
|
function radix2(bits, revPadding = false) {
|
||
|
assertNumber(bits);
|
||
|
if (bits <= 0 || bits > 32)
|
||
|
throw new Error('radix2: bits should be in (0..32]');
|
||
|
if (radix2carry(8, bits) > 32 || radix2carry(bits, 8) > 32)
|
||
|
throw new Error('radix2: carry overflow');
|
||
|
return {
|
||
|
encode: (bytes) => {
|
||
|
if (!(bytes instanceof Uint8Array))
|
||
|
throw new Error('radix2.encode input should be Uint8Array');
|
||
|
return convertRadix2(Array.from(bytes), 8, bits, !revPadding);
|
||
|
},
|
||
|
decode: (digits) => {
|
||
|
if (!Array.isArray(digits) || (digits.length && typeof digits[0] !== 'number'))
|
||
|
throw new Error('radix2.decode input should be array of strings');
|
||
|
return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));
|
||
|
},
|
||
|
};
|
||
|
}
|
||
|
function unsafeWrapper(fn) {
|
||
|
if (typeof fn !== 'function')
|
||
|
throw new Error('unsafeWrapper fn should be function');
|
||
|
return function (...args) {
|
||
|
try {
|
||
|
return fn.apply(null, args);
|
||
|
}
|
||
|
catch (e) { }
|
||
|
};
|
||
|
}
|
||
|
function checksum(len, fn) {
|
||
|
assertNumber(len);
|
||
|
if (typeof fn !== 'function')
|
||
|
throw new Error('checksum fn should be function');
|
||
|
return {
|
||
|
encode(data) {
|
||
|
if (!(data instanceof Uint8Array))
|
||
|
throw new Error('checksum.encode: input should be Uint8Array');
|
||
|
const checksum = fn(data).slice(0, len);
|
||
|
const res = new Uint8Array(data.length + len);
|
||
|
res.set(data);
|
||
|
res.set(checksum, data.length);
|
||
|
return res;
|
||
|
},
|
||
|
decode(data) {
|
||
|
if (!(data instanceof Uint8Array))
|
||
|
throw new Error('checksum.decode: input should be Uint8Array');
|
||
|
const payload = data.slice(0, -len);
|
||
|
const newChecksum = fn(payload).slice(0, len);
|
||
|
const oldChecksum = data.slice(-len);
|
||
|
for (let i = 0; i < len; i++)
|
||
|
if (newChecksum[i] !== oldChecksum[i])
|
||
|
throw new Error('Invalid checksum');
|
||
|
return payload;
|
||
|
},
|
||
|
};
|
||
|
}
|
||
|
const utils = { alphabet, chain, checksum, radix, radix2, join, padding };
|
||
|
chain(radix2(4), alphabet('0123456789ABCDEF'), join(''));
|
||
|
chain(radix2(5), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'), padding(5), join(''));
|
||
|
chain(radix2(5), alphabet('0123456789ABCDEFGHIJKLMNOPQRSTUV'), padding(5), join(''));
|
||
|
chain(radix2(5), alphabet('0123456789ABCDEFGHJKMNPQRSTVWXYZ'), join(''), normalize$1((s) => s.toUpperCase().replace(/O/g, '0').replace(/[IL]/g, '1')));
|
||
|
const base64 = chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'), padding(6), join(''));
|
||
|
chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), padding(6), join(''));
|
||
|
chain(radix2(6), alphabet('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'), join(''));
|
||
|
const genBase58 = (abc) => chain(radix(58), alphabet(abc), join(''));
|
||
|
const base58 = genBase58('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
|
||
|
genBase58('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ');
|
||
|
genBase58('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz');
|
||
|
const BECH_ALPHABET = chain(alphabet('qpzry9x8gf2tvdw0s3jn54khce6mua7l'), join(''));
|
||
|
const POLYMOD_GENERATORS = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
|
||
|
function bech32Polymod(pre) {
|
||
|
const b = pre >> 25;
|
||
|
let chk = (pre & 0x1ffffff) << 5;
|
||
|
for (let i = 0; i < POLYMOD_GENERATORS.length; i++) {
|
||
|
if (((b >> i) & 1) === 1)
|
||
|
chk ^= POLYMOD_GENERATORS[i];
|
||
|
}
|
||
|
return chk;
|
||
|
}
|
||
|
function bechChecksum(prefix, words, encodingConst = 1) {
|
||
|
const len = prefix.length;
|
||
|
let chk = 1;
|
||
|
for (let i = 0; i < len; i++) {
|
||
|
const c = prefix.charCodeAt(i);
|
||
|
if (c < 33 || c > 126)
|
||
|
throw new Error(`Invalid prefix (${prefix})`);
|
||
|
chk = bech32Polymod(chk) ^ (c >> 5);
|
||
|
}
|
||
|
chk = bech32Polymod(chk);
|
||
|
for (let i = 0; i < len; i++)
|
||
|
chk = bech32Polymod(chk) ^ (prefix.charCodeAt(i) & 0x1f);
|
||
|
for (let v of words)
|
||
|
chk = bech32Polymod(chk) ^ v;
|
||
|
for (let i = 0; i < 6; i++)
|
||
|
chk = bech32Polymod(chk);
|
||
|
chk ^= encodingConst;
|
||
|
return BECH_ALPHABET.encode(convertRadix2([chk % 2 ** 30], 30, 5, false));
|
||
|
}
|
||
|
function genBech32(encoding) {
|
||
|
const ENCODING_CONST = encoding === 'bech32' ? 1 : 0x2bc830a3;
|
||
|
const _words = radix2(5);
|
||
|
const fromWords = _words.decode;
|
||
|
const toWords = _words.encode;
|
||
|
const fromWordsUnsafe = unsafeWrapper(fromWords);
|
||
|
function encode(prefix, words, limit = 90) {
|
||
|
if (typeof prefix !== 'string')
|
||
|
throw new Error(`bech32.encode prefix should be string, not ${typeof prefix}`);
|
||
|
if (!Array.isArray(words) || (words.length && typeof words[0] !== 'number'))
|
||
|
throw new Error(`bech32.encode words should be array of numbers, not ${typeof words}`);
|
||
|
const actualLength = prefix.length + 7 + words.length;
|
||
|
if (limit !== false && actualLength > limit)
|
||
|
throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);
|
||
|
const lowered = prefix.toLowerCase();
|
||
|
const sum = bechChecksum(lowered, words, ENCODING_CONST);
|
||
|
return `${lowered}1${BECH_ALPHABET.encode(words)}${sum}`;
|
||
|
}
|
||
|
function decode(str, limit = 90) {
|
||
|
if (typeof str !== 'string')
|
||
|
throw new Error(`bech32.decode input should be string, not ${typeof str}`);
|
||
|
if (str.length < 8 || (limit !== false && str.length > limit))
|
||
|
throw new TypeError(`Wrong string length: ${str.length} (${str}). Expected (8..${limit})`);
|
||
|
const lowered = str.toLowerCase();
|
||
|
if (str !== lowered && str !== str.toUpperCase())
|
||
|
throw new Error(`String must be lowercase or uppercase`);
|
||
|
str = lowered;
|
||
|
const sepIndex = str.lastIndexOf('1');
|
||
|
if (sepIndex === 0 || sepIndex === -1)
|
||
|
throw new Error(`Letter "1" must be present between prefix and data only`);
|
||
|
const prefix = str.slice(0, sepIndex);
|
||
|
const _words = str.slice(sepIndex + 1);
|
||
|
if (_words.length < 6)
|
||
|
throw new Error('Data must be at least 6 characters long');
|
||
|
const words = BECH_ALPHABET.decode(_words).slice(0, -6);
|
||
|
const sum = bechChecksum(prefix, words, ENCODING_CONST);
|
||
|
if (!_words.endsWith(sum))
|
||
|
throw new Error(`Invalid checksum in ${str}: expected "${sum}"`);
|
||
|
return { prefix, words };
|
||
|
}
|
||
|
const decodeUnsafe = unsafeWrapper(decode);
|
||
|
function decodeToBytes(str) {
|
||
|
const { prefix, words } = decode(str, false);
|
||
|
return { prefix, words, bytes: fromWords(words) };
|
||
|
}
|
||
|
return { encode, decode, decodeToBytes, decodeUnsafe, fromWords, fromWordsUnsafe, toWords };
|
||
|
}
|
||
|
genBech32('bech32');
|
||
|
genBech32('bech32m');
|
||
|
chain(radix2(4), alphabet('0123456789abcdef'), join(''), normalize$1((s) => {
|
||
|
if (typeof s !== 'string' || s.length % 2)
|
||
|
throw new TypeError(`hex.decode: expected string, got ${typeof s} with length ${s.length}`);
|
||
|
return s.toLowerCase();
|
||
|
}));
|
||
|
|
||
|
function createDecode({ coder, ipfs }, validate) {
|
||
|
return (value, ipfsCompat) => {
|
||
|
validate(value, ipfsCompat);
|
||
|
return coder.decode(ipfs && ipfsCompat
|
||
|
? value.substring(1)
|
||
|
: value);
|
||
|
};
|
||
|
}
|
||
|
function createEncode({ coder, ipfs }) {
|
||
|
return (value, ipfsCompat) => {
|
||
|
const out = coder.encode(util.u8aToU8a(value));
|
||
|
return ipfs && ipfsCompat
|
||
|
? `${ipfs}${out}`
|
||
|
: out;
|
||
|
};
|
||
|
}
|
||
|
function createIs(validate) {
|
||
|
return (value, ipfsCompat) => {
|
||
|
try {
|
||
|
return validate(value, ipfsCompat);
|
||
|
}
|
||
|
catch {
|
||
|
return false;
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
function createValidate({ chars, ipfs, type, withPadding }) {
|
||
|
return (value, ipfsCompat) => {
|
||
|
if (typeof value !== 'string') {
|
||
|
throw new Error(`Expected ${type} string input`);
|
||
|
}
|
||
|
else if (ipfs && ipfsCompat && !value.startsWith(ipfs)) {
|
||
|
throw new Error(`Expected ipfs-compatible ${type} to start with '${ipfs}'`);
|
||
|
}
|
||
|
for (let i = (ipfsCompat ? 1 : 0), count = value.length; i < count; i++) {
|
||
|
if (chars.includes(value[i])) ;
|
||
|
else if (withPadding && value[i] === '=') {
|
||
|
if (i === count - 1) ;
|
||
|
else if (value[i + 1] === '=') ;
|
||
|
else {
|
||
|
throw new Error(`Invalid ${type} padding sequence "${value[i]}${value[i + 1]}" at index ${i}`);
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
throw new Error(`Invalid ${type} character "${value[i]}" (0x${value.charCodeAt(i).toString(16)}) at index ${i}`);
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
const config$2 = {
|
||
|
chars: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz',
|
||
|
coder: base58,
|
||
|
ipfs: 'z',
|
||
|
type: 'base58'
|
||
|
};
|
||
|
const base58Validate = createValidate(config$2);
|
||
|
const base58Decode = createDecode(config$2, base58Validate);
|
||
|
const base58Encode = createEncode(config$2);
|
||
|
const isBase58 = createIs(base58Validate);
|
||
|
|
||
|
function number(n) {
|
||
|
if (!Number.isSafeInteger(n) || n < 0)
|
||
|
throw new Error(`Wrong positive integer: ${n}`);
|
||
|
}
|
||
|
function bytes(b, ...lengths) {
|
||
|
if (!(b instanceof Uint8Array))
|
||
|
throw new Error('Expected Uint8Array');
|
||
|
if (lengths.length > 0 && !lengths.includes(b.length))
|
||
|
throw new Error(`Expected Uint8Array of length ${lengths}, not of length=${b.length}`);
|
||
|
}
|
||
|
function hash(hash) {
|
||
|
if (typeof hash !== 'function' || typeof hash.create !== 'function')
|
||
|
throw new Error('Hash should be wrapped by utils.wrapConstructor');
|
||
|
number(hash.outputLen);
|
||
|
number(hash.blockLen);
|
||
|
}
|
||
|
function exists(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');
|
||
|
}
|
||
|
function output(out, instance) {
|
||
|
bytes(out);
|
||
|
const min = instance.outputLen;
|
||
|
if (out.length < min) {
|
||
|
throw new Error(`digestInto() expects output buffer of length at least ${min}`);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const crypto = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
|
||
|
|
||
|
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||
|
const u8a$1 = (a) => a instanceof Uint8Array;
|
||
|
const u32 = (arr) => new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
|
||
|
const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
||
|
const rotr = (word, shift) => (word << (32 - shift)) | (word >>> shift);
|
||
|
const isLE = new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;
|
||
|
if (!isLE)
|
||
|
throw new Error('Non little-endian hardware is not supported');
|
||
|
Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
|
||
|
function utf8ToBytes$1(str) {
|
||
|
if (typeof str !== 'string')
|
||
|
throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
|
||
|
return new Uint8Array(new TextEncoder().encode(str));
|
||
|
}
|
||
|
function toBytes(data) {
|
||
|
if (typeof data === 'string')
|
||
|
data = utf8ToBytes$1(data);
|
||
|
if (!u8a$1(data))
|
||
|
throw new Error(`expected Uint8Array, got ${typeof data}`);
|
||
|
return data;
|
||
|
}
|
||
|
function concatBytes$1(...arrays) {
|
||
|
const r = new Uint8Array(arrays.reduce((sum, a) => sum + a.length, 0));
|
||
|
let pad = 0;
|
||
|
arrays.forEach((a) => {
|
||
|
if (!u8a$1(a))
|
||
|
throw new Error('Uint8Array expected');
|
||
|
r.set(a, pad);
|
||
|
pad += a.length;
|
||
|
});
|
||
|
return r;
|
||
|
}
|
||
|
class Hash {
|
||
|
clone() {
|
||
|
return this._cloneInto();
|
||
|
}
|
||
|
}
|
||
|
const toStr = {}.toString;
|
||
|
function checkOpts(defaults, opts) {
|
||
|
if (opts !== undefined && toStr.call(opts) !== '[object Object]')
|
||
|
throw new Error('Options should be object or undefined');
|
||
|
const merged = Object.assign(defaults, opts);
|
||
|
return merged;
|
||
|
}
|
||
|
function wrapConstructor(hashCons) {
|
||
|
const hashC = (msg) => hashCons().update(toBytes(msg)).digest();
|
||
|
const tmp = hashCons();
|
||
|
hashC.outputLen = tmp.outputLen;
|
||
|
hashC.blockLen = tmp.blockLen;
|
||
|
hashC.create = () => hashCons();
|
||
|
return hashC;
|
||
|
}
|
||
|
function wrapConstructorWithOpts(hashCons) {
|
||
|
const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest();
|
||
|
const tmp = hashCons({});
|
||
|
hashC.outputLen = tmp.outputLen;
|
||
|
hashC.blockLen = tmp.blockLen;
|
||
|
hashC.create = (opts) => hashCons(opts);
|
||
|
return hashC;
|
||
|
}
|
||
|
function wrapXOFConstructorWithOpts(hashCons) {
|
||
|
const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest();
|
||
|
const tmp = hashCons({});
|
||
|
hashC.outputLen = tmp.outputLen;
|
||
|
hashC.blockLen = tmp.blockLen;
|
||
|
hashC.create = (opts) => hashCons(opts);
|
||
|
return hashC;
|
||
|
}
|
||
|
function randomBytes(bytesLength = 32) {
|
||
|
if (crypto && typeof crypto.getRandomValues === 'function') {
|
||
|
return crypto.getRandomValues(new Uint8Array(bytesLength));
|
||
|
}
|
||
|
throw new Error('crypto.getRandomValues must be defined');
|
||
|
}
|
||
|
|
||
|
const SIGMA = new Uint8Array([
|
||
|
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,
|
||
|
]);
|
||
|
class BLAKE2 extends Hash {
|
||
|
constructor(blockLen, outputLen, opts = {}, keyLen, saltLen, persLen) {
|
||
|
super();
|
||
|
this.blockLen = blockLen;
|
||
|
this.outputLen = outputLen;
|
||
|
this.length = 0;
|
||
|
this.pos = 0;
|
||
|
this.finished = false;
|
||
|
this.destroyed = false;
|
||
|
number(blockLen);
|
||
|
number(outputLen);
|
||
|
number(keyLen);
|
||
|
if (outputLen < 0 || outputLen > keyLen)
|
||
|
throw new Error('outputLen bigger than keyLen');
|
||
|
if (opts.key !== undefined && (opts.key.length < 1 || opts.key.length > keyLen))
|
||
|
throw new Error(`key must be up 1..${keyLen} byte long or undefined`);
|
||
|
if (opts.salt !== undefined && opts.salt.length !== saltLen)
|
||
|
throw new Error(`salt must be ${saltLen} byte long or undefined`);
|
||
|
if (opts.personalization !== undefined && opts.personalization.length !== persLen)
|
||
|
throw new Error(`personalization must be ${persLen} byte long or undefined`);
|
||
|
this.buffer32 = u32((this.buffer = new Uint8Array(blockLen)));
|
||
|
}
|
||
|
update(data) {
|
||
|
exists(this);
|
||
|
const { blockLen, buffer, buffer32 } = this;
|
||
|
data = toBytes(data);
|
||
|
const len = data.length;
|
||
|
const offset = data.byteOffset;
|
||
|
const buf = data.buffer;
|
||
|
for (let pos = 0; pos < len;) {
|
||
|
if (this.pos === blockLen) {
|
||
|
this.compress(buffer32, 0, false);
|
||
|
this.pos = 0;
|
||
|
}
|
||
|
const take = Math.min(blockLen - this.pos, len - pos);
|
||
|
const dataOffset = offset + pos;
|
||
|
if (take === blockLen && !(dataOffset % 4) && pos + take < len) {
|
||
|
const data32 = new Uint32Array(buf, dataOffset, Math.floor((len - pos) / 4));
|
||
|
for (let pos32 = 0; pos + blockLen < len; pos32 += buffer32.length, pos += blockLen) {
|
||
|
this.length += blockLen;
|
||
|
this.compress(data32, pos32, false);
|
||
|
}
|
||
|
continue;
|
||
|
}
|
||
|
buffer.set(data.subarray(pos, pos + take), this.pos);
|
||
|
this.pos += take;
|
||
|
this.length += take;
|
||
|
pos += take;
|
||
|
}
|
||
|
return this;
|
||
|
}
|
||
|
digestInto(out) {
|
||
|
exists(this);
|
||
|
output(out, this);
|
||
|
const { pos, buffer32 } = this;
|
||
|
this.finished = true;
|
||
|
this.buffer.subarray(pos).fill(0);
|
||
|
this.compress(buffer32, 0, true);
|
||
|
const out32 = u32(out);
|
||
|
this.get().forEach((v, i) => (out32[i] = 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 || (to = new this.constructor({ dkLen: outputLen }));
|
||
|
to.set(...this.get());
|
||
|
to.length = length;
|
||
|
to.finished = finished;
|
||
|
to.destroyed = destroyed;
|
||
|
to.outputLen = outputLen;
|
||
|
to.buffer.set(buffer);
|
||
|
to.pos = pos;
|
||
|
return to;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const U32_MASK64 = BigInt(2 ** 32 - 1);
|
||
|
const _32n$1 = BigInt(32);
|
||
|
function fromBig(n, le = false) {
|
||
|
if (le)
|
||
|
return { h: Number(n & U32_MASK64), l: Number((n >> _32n$1) & U32_MASK64) };
|
||
|
return { h: Number((n >> _32n$1) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
|
||
|
}
|
||
|
function split(lst, le = false) {
|
||
|
let Ah = new Uint32Array(lst.length);
|
||
|
let Al = new Uint32Array(lst.length);
|
||
|
for (let i = 0; i < lst.length; i++) {
|
||
|
const { h, l } = fromBig(lst[i], le);
|
||
|
[Ah[i], Al[i]] = [h, l];
|
||
|
}
|
||
|
return [Ah, Al];
|
||
|
}
|
||
|
const toBig = (h, l) => (BigInt(h >>> 0) << _32n$1) | BigInt(l >>> 0);
|
||
|
const shrSH = (h, _l, s) => h >>> s;
|
||
|
const shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
|
||
|
const rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s));
|
||
|
const rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
|
||
|
const rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32));
|
||
|
const rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s));
|
||
|
const rotr32H = (_h, l) => l;
|
||
|
const rotr32L = (h, _l) => h;
|
||
|
const rotlSH = (h, l, s) => (h << s) | (l >>> (32 - s));
|
||
|
const rotlSL = (h, l, s) => (l << s) | (h >>> (32 - s));
|
||
|
const rotlBH = (h, l, s) => (l << (s - 32)) | (h >>> (64 - s));
|
||
|
const rotlBL = (h, l, s) => (h << (s - 32)) | (l >>> (64 - s));
|
||
|
function add(Ah, Al, Bh, Bl) {
|
||
|
const l = (Al >>> 0) + (Bl >>> 0);
|
||
|
return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };
|
||
|
}
|
||
|
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;
|
||
|
const u64 = {
|
||
|
fromBig, split, toBig,
|
||
|
shrSH, shrSL,
|
||
|
rotrSH, rotrSL, rotrBH, rotrBL,
|
||
|
rotr32H, rotr32L,
|
||
|
rotlSH, rotlSL, rotlBH, rotlBL,
|
||
|
add, add3L, add3H, add4L, add4H, add5H, add5L,
|
||
|
};
|
||
|
const u64$1 = u64;
|
||
|
|
||
|
const IV$1 = new Uint32Array([
|
||
|
0xf3bcc908, 0x6a09e667, 0x84caa73b, 0xbb67ae85, 0xfe94f82b, 0x3c6ef372, 0x5f1d36f1, 0xa54ff53a,
|
||
|
0xade682d1, 0x510e527f, 0x2b3e6c1f, 0x9b05688c, 0xfb41bd6b, 0x1f83d9ab, 0x137e2179, 0x5be0cd19
|
||
|
]);
|
||
|
const BUF = new Uint32Array(32);
|
||
|
function G1(a, b, c, d, msg, x) {
|
||
|
const Xl = msg[x], Xh = msg[x + 1];
|
||
|
let Al = BUF[2 * a], Ah = BUF[2 * a + 1];
|
||
|
let Bl = BUF[2 * b], Bh = BUF[2 * b + 1];
|
||
|
let Cl = BUF[2 * c], Ch = BUF[2 * c + 1];
|
||
|
let Dl = BUF[2 * d], Dh = BUF[2 * d + 1];
|
||
|
let ll = u64$1.add3L(Al, Bl, Xl);
|
||
|
Ah = u64$1.add3H(ll, Ah, Bh, Xh);
|
||
|
Al = ll | 0;
|
||
|
({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al });
|
||
|
({ Dh, Dl } = { Dh: u64$1.rotr32H(Dh, Dl), Dl: u64$1.rotr32L(Dh, Dl) });
|
||
|
({ h: Ch, l: Cl } = u64$1.add(Ch, Cl, Dh, Dl));
|
||
|
({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl });
|
||
|
({ Bh, Bl } = { Bh: u64$1.rotrSH(Bh, Bl, 24), Bl: u64$1.rotrSL(Bh, Bl, 24) });
|
||
|
(BUF[2 * a] = Al), (BUF[2 * a + 1] = Ah);
|
||
|
(BUF[2 * b] = Bl), (BUF[2 * b + 1] = Bh);
|
||
|
(BUF[2 * c] = Cl), (BUF[2 * c + 1] = Ch);
|
||
|
(BUF[2 * d] = Dl), (BUF[2 * d + 1] = Dh);
|
||
|
}
|
||
|
function G2(a, b, c, d, msg, x) {
|
||
|
const Xl = msg[x], Xh = msg[x + 1];
|
||
|
let Al = BUF[2 * a], Ah = BUF[2 * a + 1];
|
||
|
let Bl = BUF[2 * b], Bh = BUF[2 * b + 1];
|
||
|
let Cl = BUF[2 * c], Ch = BUF[2 * c + 1];
|
||
|
let Dl = BUF[2 * d], Dh = BUF[2 * d + 1];
|
||
|
let ll = u64$1.add3L(Al, Bl, Xl);
|
||
|
Ah = u64$1.add3H(ll, Ah, Bh, Xh);
|
||
|
Al = ll | 0;
|
||
|
({ Dh, Dl } = { Dh: Dh ^ Ah, Dl: Dl ^ Al });
|
||
|
({ Dh, Dl } = { Dh: u64$1.rotrSH(Dh, Dl, 16), Dl: u64$1.rotrSL(Dh, Dl, 16) });
|
||
|
({ h: Ch, l: Cl } = u64$1.add(Ch, Cl, Dh, Dl));
|
||
|
({ Bh, Bl } = { Bh: Bh ^ Ch, Bl: Bl ^ Cl });
|
||
|
({ Bh, Bl } = { Bh: u64$1.rotrBH(Bh, Bl, 63), Bl: u64$1.rotrBL(Bh, Bl, 63) });
|
||
|
(BUF[2 * a] = Al), (BUF[2 * a + 1] = Ah);
|
||
|
(BUF[2 * b] = Bl), (BUF[2 * b + 1] = Bh);
|
||
|
(BUF[2 * c] = Cl), (BUF[2 * c + 1] = Ch);
|
||
|
(BUF[2 * d] = Dl), (BUF[2 * d + 1] = Dh);
|
||
|
}
|
||
|
class BLAKE2b extends BLAKE2 {
|
||
|
constructor(opts = {}) {
|
||
|
super(128, opts.dkLen === undefined ? 64 : opts.dkLen, opts, 64, 16, 16);
|
||
|
this.v0l = IV$1[0] | 0;
|
||
|
this.v0h = IV$1[1] | 0;
|
||
|
this.v1l = IV$1[2] | 0;
|
||
|
this.v1h = IV$1[3] | 0;
|
||
|
this.v2l = IV$1[4] | 0;
|
||
|
this.v2h = IV$1[5] | 0;
|
||
|
this.v3l = IV$1[6] | 0;
|
||
|
this.v3h = IV$1[7] | 0;
|
||
|
this.v4l = IV$1[8] | 0;
|
||
|
this.v4h = IV$1[9] | 0;
|
||
|
this.v5l = IV$1[10] | 0;
|
||
|
this.v5h = IV$1[11] | 0;
|
||
|
this.v6l = IV$1[12] | 0;
|
||
|
this.v6h = IV$1[13] | 0;
|
||
|
this.v7l = IV$1[14] | 0;
|
||
|
this.v7h = IV$1[15] | 0;
|
||
|
const keyLength = opts.key ? opts.key.length : 0;
|
||
|
this.v0l ^= this.outputLen | (keyLength << 8) | (0x01 << 16) | (0x01 << 24);
|
||
|
if (opts.salt) {
|
||
|
const salt = u32(toBytes(opts.salt));
|
||
|
this.v4l ^= salt[0];
|
||
|
this.v4h ^= salt[1];
|
||
|
this.v5l ^= salt[2];
|
||
|
this.v5h ^= salt[3];
|
||
|
}
|
||
|
if (opts.personalization) {
|
||
|
const pers = u32(toBytes(opts.personalization));
|
||
|
this.v6l ^= pers[0];
|
||
|
this.v6h ^= pers[1];
|
||
|
this.v7l ^= pers[2];
|
||
|
this.v7h ^= pers[3];
|
||
|
}
|
||
|
if (opts.key) {
|
||
|
const tmp = new Uint8Array(this.blockLen);
|
||
|
tmp.set(toBytes(opts.key));
|
||
|
this.update(tmp);
|
||
|
}
|
||
|
}
|
||
|
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];
|
||
|
}
|
||
|
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) => (BUF[i] = v));
|
||
|
BUF.set(IV$1, 16);
|
||
|
let { h, l } = u64$1.fromBig(BigInt(this.length));
|
||
|
BUF[24] = IV$1[8] ^ l;
|
||
|
BUF[25] = IV$1[9] ^ h;
|
||
|
if (isLast) {
|
||
|
BUF[28] = ~BUF[28];
|
||
|
BUF[29] = ~BUF[29];
|
||
|
}
|
||
|
let j = 0;
|
||
|
const s = SIGMA;
|
||
|
for (let i = 0; i < 12; i++) {
|
||
|
G1(0, 4, 8, 12, msg, offset + 2 * s[j++]);
|
||
|
G2(0, 4, 8, 12, msg, offset + 2 * s[j++]);
|
||
|
G1(1, 5, 9, 13, msg, offset + 2 * s[j++]);
|
||
|
G2(1, 5, 9, 13, msg, offset + 2 * s[j++]);
|
||
|
G1(2, 6, 10, 14, msg, offset + 2 * s[j++]);
|
||
|
G2(2, 6, 10, 14, msg, offset + 2 * s[j++]);
|
||
|
G1(3, 7, 11, 15, msg, offset + 2 * s[j++]);
|
||
|
G2(3, 7, 11, 15, msg, offset + 2 * s[j++]);
|
||
|
G1(0, 5, 10, 15, msg, offset + 2 * s[j++]);
|
||
|
G2(0, 5, 10, 15, msg, offset + 2 * s[j++]);
|
||
|
G1(1, 6, 11, 12, msg, offset + 2 * s[j++]);
|
||
|
G2(1, 6, 11, 12, msg, offset + 2 * s[j++]);
|
||
|
G1(2, 7, 8, 13, msg, offset + 2 * s[j++]);
|
||
|
G2(2, 7, 8, 13, msg, offset + 2 * s[j++]);
|
||
|
G1(3, 4, 9, 14, msg, offset + 2 * s[j++]);
|
||
|
G2(3, 4, 9, 14, msg, offset + 2 * s[j++]);
|
||
|
}
|
||
|
this.v0l ^= BUF[0] ^ BUF[16];
|
||
|
this.v0h ^= BUF[1] ^ BUF[17];
|
||
|
this.v1l ^= BUF[2] ^ BUF[18];
|
||
|
this.v1h ^= BUF[3] ^ BUF[19];
|
||
|
this.v2l ^= BUF[4] ^ BUF[20];
|
||
|
this.v2h ^= BUF[5] ^ BUF[21];
|
||
|
this.v3l ^= BUF[6] ^ BUF[22];
|
||
|
this.v3h ^= BUF[7] ^ BUF[23];
|
||
|
this.v4l ^= BUF[8] ^ BUF[24];
|
||
|
this.v4h ^= BUF[9] ^ BUF[25];
|
||
|
this.v5l ^= BUF[10] ^ BUF[26];
|
||
|
this.v5h ^= BUF[11] ^ BUF[27];
|
||
|
this.v6l ^= BUF[12] ^ BUF[28];
|
||
|
this.v6h ^= BUF[13] ^ BUF[29];
|
||
|
this.v7l ^= BUF[14] ^ BUF[30];
|
||
|
this.v7h ^= BUF[15] ^ BUF[31];
|
||
|
BUF.fill(0);
|
||
|
}
|
||
|
destroy() {
|
||
|
this.destroyed = true;
|
||
|
this.buffer32.fill(0);
|
||
|
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||
|
}
|
||
|
}
|
||
|
const blake2b = wrapConstructorWithOpts((opts) => new BLAKE2b(opts));
|
||
|
|
||
|
function createAsHex(fn) {
|
||
|
return (...args) => util.u8aToHex(fn(...args));
|
||
|
}
|
||
|
function createBitHasher(bitLength, fn) {
|
||
|
return (data, onlyJs) => fn(data, bitLength, onlyJs);
|
||
|
}
|
||
|
function createDualHasher(wa, js) {
|
||
|
return (value, bitLength = 256, onlyJs) => {
|
||
|
const u8a = util.u8aToU8a(value);
|
||
|
return !util.hasBigInt || (!onlyJs && isReady())
|
||
|
? wa[bitLength](u8a)
|
||
|
: js[bitLength](u8a);
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function blake2AsU8a(data, bitLength = 256, key, onlyJs) {
|
||
|
const byteLength = Math.ceil(bitLength / 8);
|
||
|
const u8a = util.u8aToU8a(data);
|
||
|
return !util.hasBigInt || (!onlyJs && isReady())
|
||
|
? blake2b$1(u8a, util.u8aToU8a(key), byteLength)
|
||
|
: key
|
||
|
? blake2b(u8a, { dkLen: byteLength, key })
|
||
|
: blake2b(u8a, { dkLen: byteLength });
|
||
|
}
|
||
|
const blake2AsHex = createAsHex(blake2AsU8a);
|
||
|
|
||
|
const SS58_PREFIX = util.stringToU8a('SS58PRE');
|
||
|
function sshash(key) {
|
||
|
return blake2AsU8a(util.u8aConcat(SS58_PREFIX, key), 512);
|
||
|
}
|
||
|
|
||
|
function checkAddressChecksum(decoded) {
|
||
|
const ss58Length = (decoded[0] & 64) ? 2 : 1;
|
||
|
const ss58Decoded = ss58Length === 1
|
||
|
? decoded[0]
|
||
|
: ((decoded[0] & 63) << 2) | (decoded[1] >> 6) | ((decoded[1] & 63) << 8);
|
||
|
const isPublicKey = [34 + ss58Length, 35 + ss58Length].includes(decoded.length);
|
||
|
const length = decoded.length - (isPublicKey ? 2 : 1);
|
||
|
const hash = sshash(decoded.subarray(0, length));
|
||
|
const isValid = (decoded[0] & 128) === 0 && ![46, 47].includes(decoded[0]) && (isPublicKey
|
||
|
? decoded[decoded.length - 2] === hash[0] && decoded[decoded.length - 1] === hash[1]
|
||
|
: decoded[decoded.length - 1] === hash[0]);
|
||
|
return [isValid, length, ss58Length, ss58Decoded];
|
||
|
}
|
||
|
|
||
|
const knownSubstrate = [
|
||
|
{
|
||
|
"prefix": 0,
|
||
|
"network": "polkadot",
|
||
|
"displayName": "Polkadot Relay Chain",
|
||
|
"symbols": [
|
||
|
"DOT"
|
||
|
],
|
||
|
"decimals": [
|
||
|
10
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://polkadot.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 1,
|
||
|
"network": "BareSr25519",
|
||
|
"displayName": "Bare 32-bit Schnorr/Ristretto (S/R 25519) public key.",
|
||
|
"symbols": [],
|
||
|
"decimals": [],
|
||
|
"standardAccount": "Sr25519",
|
||
|
"website": null
|
||
|
},
|
||
|
{
|
||
|
"prefix": 2,
|
||
|
"network": "kusama",
|
||
|
"displayName": "Kusama Relay Chain",
|
||
|
"symbols": [
|
||
|
"KSM"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://kusama.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 3,
|
||
|
"network": "BareEd25519",
|
||
|
"displayName": "Bare 32-bit Ed25519 public key.",
|
||
|
"symbols": [],
|
||
|
"decimals": [],
|
||
|
"standardAccount": "Ed25519",
|
||
|
"website": null
|
||
|
},
|
||
|
{
|
||
|
"prefix": 4,
|
||
|
"network": "katalchain",
|
||
|
"displayName": "Katal Chain",
|
||
|
"symbols": [],
|
||
|
"decimals": [],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": null
|
||
|
},
|
||
|
{
|
||
|
"prefix": 5,
|
||
|
"network": "astar",
|
||
|
"displayName": "Astar Network",
|
||
|
"symbols": [
|
||
|
"ASTR"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://astar.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 6,
|
||
|
"network": "bifrost",
|
||
|
"displayName": "Bifrost",
|
||
|
"symbols": [
|
||
|
"BNC"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://bifrost.finance/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 7,
|
||
|
"network": "edgeware",
|
||
|
"displayName": "Edgeware",
|
||
|
"symbols": [
|
||
|
"EDG"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://edgewa.re"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 8,
|
||
|
"network": "karura",
|
||
|
"displayName": "Karura",
|
||
|
"symbols": [
|
||
|
"KAR"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://karura.network/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 9,
|
||
|
"network": "reynolds",
|
||
|
"displayName": "Laminar Reynolds Canary",
|
||
|
"symbols": [
|
||
|
"REY"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "http://laminar.network/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 10,
|
||
|
"network": "acala",
|
||
|
"displayName": "Acala",
|
||
|
"symbols": [
|
||
|
"ACA"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://acala.network/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 11,
|
||
|
"network": "laminar",
|
||
|
"displayName": "Laminar",
|
||
|
"symbols": [
|
||
|
"LAMI"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "http://laminar.network/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 12,
|
||
|
"network": "polymesh",
|
||
|
"displayName": "Polymesh",
|
||
|
"symbols": [
|
||
|
"POLYX"
|
||
|
],
|
||
|
"decimals": [
|
||
|
6
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://polymath.network/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 13,
|
||
|
"network": "integritee",
|
||
|
"displayName": "Integritee",
|
||
|
"symbols": [
|
||
|
"TEER"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://integritee.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 14,
|
||
|
"network": "totem",
|
||
|
"displayName": "Totem",
|
||
|
"symbols": [
|
||
|
"TOTEM"
|
||
|
],
|
||
|
"decimals": [
|
||
|
0
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://totemaccounting.com"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 15,
|
||
|
"network": "synesthesia",
|
||
|
"displayName": "Synesthesia",
|
||
|
"symbols": [
|
||
|
"SYN"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://synesthesia.network/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 16,
|
||
|
"network": "kulupu",
|
||
|
"displayName": "Kulupu",
|
||
|
"symbols": [
|
||
|
"KLP"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://kulupu.network/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 17,
|
||
|
"network": "dark",
|
||
|
"displayName": "Dark Mainnet",
|
||
|
"symbols": [],
|
||
|
"decimals": [],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": null
|
||
|
},
|
||
|
{
|
||
|
"prefix": 18,
|
||
|
"network": "darwinia",
|
||
|
"displayName": "Darwinia Network",
|
||
|
"symbols": [
|
||
|
"RING"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "secp256k1",
|
||
|
"website": "https://darwinia.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 19,
|
||
|
"network": "watr",
|
||
|
"displayName": "Watr Protocol",
|
||
|
"symbols": [
|
||
|
"WATR"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://www.watr.org"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 20,
|
||
|
"network": "stafi",
|
||
|
"displayName": "Stafi",
|
||
|
"symbols": [
|
||
|
"FIS"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://stafi.io"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 21,
|
||
|
"network": "karmachain",
|
||
|
"displayName": "Karmacoin",
|
||
|
"symbols": [
|
||
|
"KCOIN"
|
||
|
],
|
||
|
"decimals": [
|
||
|
6
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://karmaco.in"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 22,
|
||
|
"network": "dock-pos-mainnet",
|
||
|
"displayName": "Dock Mainnet",
|
||
|
"symbols": [
|
||
|
"DCK"
|
||
|
],
|
||
|
"decimals": [
|
||
|
6
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://dock.io"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 23,
|
||
|
"network": "shift",
|
||
|
"displayName": "ShiftNrg",
|
||
|
"symbols": [],
|
||
|
"decimals": [],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": null
|
||
|
},
|
||
|
{
|
||
|
"prefix": 24,
|
||
|
"network": "zero",
|
||
|
"displayName": "ZERO",
|
||
|
"symbols": [
|
||
|
"ZERO"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://zero.io"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 25,
|
||
|
"network": "zero-alphaville",
|
||
|
"displayName": "ZERO Alphaville",
|
||
|
"symbols": [
|
||
|
"ZERO"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://zero.io"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 26,
|
||
|
"network": "jupiter",
|
||
|
"displayName": "Jupiter",
|
||
|
"symbols": [
|
||
|
"jDOT"
|
||
|
],
|
||
|
"decimals": [
|
||
|
10
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://jupiter.patract.io"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 27,
|
||
|
"network": "kabocha",
|
||
|
"displayName": "Kabocha",
|
||
|
"symbols": [
|
||
|
"KAB"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://kabocha.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 28,
|
||
|
"network": "subsocial",
|
||
|
"displayName": "Subsocial",
|
||
|
"symbols": [],
|
||
|
"decimals": [],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": null
|
||
|
},
|
||
|
{
|
||
|
"prefix": 29,
|
||
|
"network": "cord",
|
||
|
"displayName": "CORD Network",
|
||
|
"symbols": [
|
||
|
"DHI",
|
||
|
"WAY"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12,
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://cord.network/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 30,
|
||
|
"network": "phala",
|
||
|
"displayName": "Phala Network",
|
||
|
"symbols": [
|
||
|
"PHA"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://phala.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 31,
|
||
|
"network": "litentry",
|
||
|
"displayName": "Litentry Network",
|
||
|
"symbols": [
|
||
|
"LIT"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://litentry.com/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 32,
|
||
|
"network": "robonomics",
|
||
|
"displayName": "Robonomics",
|
||
|
"symbols": [
|
||
|
"XRT"
|
||
|
],
|
||
|
"decimals": [
|
||
|
9
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://robonomics.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 33,
|
||
|
"network": "datahighway",
|
||
|
"displayName": "DataHighway",
|
||
|
"symbols": [],
|
||
|
"decimals": [],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": null
|
||
|
},
|
||
|
{
|
||
|
"prefix": 34,
|
||
|
"network": "ares",
|
||
|
"displayName": "Ares Protocol",
|
||
|
"symbols": [
|
||
|
"ARES"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://www.aresprotocol.com/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 35,
|
||
|
"network": "vln",
|
||
|
"displayName": "Valiu Liquidity Network",
|
||
|
"symbols": [
|
||
|
"USDv"
|
||
|
],
|
||
|
"decimals": [
|
||
|
15
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://valiu.com/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 36,
|
||
|
"network": "centrifuge",
|
||
|
"displayName": "Centrifuge Chain",
|
||
|
"symbols": [
|
||
|
"CFG"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://centrifuge.io/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 37,
|
||
|
"network": "nodle",
|
||
|
"displayName": "Nodle Chain",
|
||
|
"symbols": [
|
||
|
"NODL"
|
||
|
],
|
||
|
"decimals": [
|
||
|
11
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://nodle.io/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 38,
|
||
|
"network": "kilt",
|
||
|
"displayName": "KILT Spiritnet",
|
||
|
"symbols": [
|
||
|
"KILT"
|
||
|
],
|
||
|
"decimals": [
|
||
|
15
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://kilt.io/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 39,
|
||
|
"network": "mathchain",
|
||
|
"displayName": "MathChain mainnet",
|
||
|
"symbols": [
|
||
|
"MATH"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://mathwallet.org"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 40,
|
||
|
"network": "mathchain-testnet",
|
||
|
"displayName": "MathChain testnet",
|
||
|
"symbols": [
|
||
|
"MATH"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://mathwallet.org"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 41,
|
||
|
"network": "polimec",
|
||
|
"displayName": "Polimec Protocol",
|
||
|
"symbols": [
|
||
|
"PLMC"
|
||
|
],
|
||
|
"decimals": [
|
||
|
10
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://www.polimec.org/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 42,
|
||
|
"network": "substrate",
|
||
|
"displayName": "Substrate",
|
||
|
"symbols": [],
|
||
|
"decimals": [],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://substrate.io/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 43,
|
||
|
"network": "BareSecp256k1",
|
||
|
"displayName": "Bare 32-bit ECDSA SECP-256k1 public key.",
|
||
|
"symbols": [],
|
||
|
"decimals": [],
|
||
|
"standardAccount": "secp256k1",
|
||
|
"website": null
|
||
|
},
|
||
|
{
|
||
|
"prefix": 44,
|
||
|
"network": "chainx",
|
||
|
"displayName": "ChainX",
|
||
|
"symbols": [
|
||
|
"PCX"
|
||
|
],
|
||
|
"decimals": [
|
||
|
8
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://chainx.org/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 45,
|
||
|
"network": "uniarts",
|
||
|
"displayName": "UniArts Network",
|
||
|
"symbols": [
|
||
|
"UART",
|
||
|
"UINK"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12,
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://uniarts.me"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 46,
|
||
|
"network": "reserved46",
|
||
|
"displayName": "This prefix is reserved.",
|
||
|
"symbols": [],
|
||
|
"decimals": [],
|
||
|
"standardAccount": null,
|
||
|
"website": null
|
||
|
},
|
||
|
{
|
||
|
"prefix": 47,
|
||
|
"network": "reserved47",
|
||
|
"displayName": "This prefix is reserved.",
|
||
|
"symbols": [],
|
||
|
"decimals": [],
|
||
|
"standardAccount": null,
|
||
|
"website": null
|
||
|
},
|
||
|
{
|
||
|
"prefix": 48,
|
||
|
"network": "neatcoin",
|
||
|
"displayName": "Neatcoin Mainnet",
|
||
|
"symbols": [
|
||
|
"NEAT"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://neatcoin.org"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 49,
|
||
|
"network": "picasso",
|
||
|
"displayName": "Picasso",
|
||
|
"symbols": [
|
||
|
"PICA"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://picasso.composable.finance"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 50,
|
||
|
"network": "composable",
|
||
|
"displayName": "Composable Finance",
|
||
|
"symbols": [
|
||
|
"LAYR"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://composable.finance"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 51,
|
||
|
"network": "oak",
|
||
|
"displayName": "OAK Network",
|
||
|
"symbols": [
|
||
|
"OAK",
|
||
|
"TUR"
|
||
|
],
|
||
|
"decimals": [
|
||
|
10,
|
||
|
10
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://oak.tech"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 52,
|
||
|
"network": "KICO",
|
||
|
"displayName": "KICO",
|
||
|
"symbols": [
|
||
|
"KICO"
|
||
|
],
|
||
|
"decimals": [
|
||
|
14
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://dico.io"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 53,
|
||
|
"network": "DICO",
|
||
|
"displayName": "DICO",
|
||
|
"symbols": [
|
||
|
"DICO"
|
||
|
],
|
||
|
"decimals": [
|
||
|
14
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://dico.io"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 54,
|
||
|
"network": "cere",
|
||
|
"displayName": "Cere Network",
|
||
|
"symbols": [
|
||
|
"CERE"
|
||
|
],
|
||
|
"decimals": [
|
||
|
10
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://cere.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 55,
|
||
|
"network": "xxnetwork",
|
||
|
"displayName": "xx network",
|
||
|
"symbols": [
|
||
|
"XX"
|
||
|
],
|
||
|
"decimals": [
|
||
|
9
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://xx.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 56,
|
||
|
"network": "pendulum",
|
||
|
"displayName": "Pendulum chain",
|
||
|
"symbols": [
|
||
|
"PEN"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://pendulumchain.org/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 57,
|
||
|
"network": "amplitude",
|
||
|
"displayName": "Amplitude chain",
|
||
|
"symbols": [
|
||
|
"AMPE"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://pendulumchain.org/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 63,
|
||
|
"network": "hydradx",
|
||
|
"displayName": "HydraDX",
|
||
|
"symbols": [
|
||
|
"HDX"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://hydradx.io"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 64,
|
||
|
"network": "ewx",
|
||
|
"displayName": "Energy Web X",
|
||
|
"symbols": [
|
||
|
"EWT"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://www.energyweb.org"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 65,
|
||
|
"network": "aventus",
|
||
|
"displayName": "Aventus Mainnet",
|
||
|
"symbols": [
|
||
|
"AVT"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://aventus.io"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 66,
|
||
|
"network": "crust",
|
||
|
"displayName": "Crust Network",
|
||
|
"symbols": [
|
||
|
"CRU"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://crust.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 67,
|
||
|
"network": "genshiro",
|
||
|
"displayName": "Genshiro Network",
|
||
|
"symbols": [
|
||
|
"GENS",
|
||
|
"EQD",
|
||
|
"LPT0"
|
||
|
],
|
||
|
"decimals": [
|
||
|
9,
|
||
|
9,
|
||
|
9
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://genshiro.equilibrium.io"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 68,
|
||
|
"network": "equilibrium",
|
||
|
"displayName": "Equilibrium Network",
|
||
|
"symbols": [
|
||
|
"EQ"
|
||
|
],
|
||
|
"decimals": [
|
||
|
9
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://equilibrium.io"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 69,
|
||
|
"network": "sora",
|
||
|
"displayName": "SORA Network",
|
||
|
"symbols": [
|
||
|
"XOR"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://sora.org"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 71,
|
||
|
"network": "p3d",
|
||
|
"displayName": "3DP network",
|
||
|
"symbols": [
|
||
|
"P3D"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://3dpass.org"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 72,
|
||
|
"network": "p3dt",
|
||
|
"displayName": "3DP test network",
|
||
|
"symbols": [
|
||
|
"P3Dt"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://3dpass.org"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 73,
|
||
|
"network": "zeitgeist",
|
||
|
"displayName": "Zeitgeist",
|
||
|
"symbols": [
|
||
|
"ZTG"
|
||
|
],
|
||
|
"decimals": [
|
||
|
10
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://zeitgeist.pm"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 77,
|
||
|
"network": "manta",
|
||
|
"displayName": "Manta network",
|
||
|
"symbols": [
|
||
|
"MANTA"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://manta.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 78,
|
||
|
"network": "calamari",
|
||
|
"displayName": "Calamari: Manta Canary Network",
|
||
|
"symbols": [
|
||
|
"KMA"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://manta.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 81,
|
||
|
"network": "sora_dot_para",
|
||
|
"displayName": "SORA Polkadot Parachain",
|
||
|
"symbols": [
|
||
|
"XOR"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://sora.org"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 88,
|
||
|
"network": "polkadex",
|
||
|
"displayName": "Polkadex Mainnet",
|
||
|
"symbols": [
|
||
|
"PDEX"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://polkadex.trade"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 89,
|
||
|
"network": "polkadexparachain",
|
||
|
"displayName": "Polkadex Parachain",
|
||
|
"symbols": [
|
||
|
"PDEX"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://polkadex.trade"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 90,
|
||
|
"network": "frequency",
|
||
|
"displayName": "Frequency",
|
||
|
"symbols": [
|
||
|
"FRQCY"
|
||
|
],
|
||
|
"decimals": [
|
||
|
8
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://www.frequency.xyz"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 92,
|
||
|
"network": "anmol",
|
||
|
"displayName": "Anmol Network",
|
||
|
"symbols": [
|
||
|
"ANML"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://anmol.network/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 93,
|
||
|
"network": "fragnova",
|
||
|
"displayName": "Fragnova Network",
|
||
|
"symbols": [
|
||
|
"NOVA"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://fragnova.com"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 98,
|
||
|
"network": "polkasmith",
|
||
|
"displayName": "PolkaSmith Canary Network",
|
||
|
"symbols": [
|
||
|
"PKS"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://polkafoundry.com"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 99,
|
||
|
"network": "polkafoundry",
|
||
|
"displayName": "PolkaFoundry Network",
|
||
|
"symbols": [
|
||
|
"PKF"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://polkafoundry.com"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 100,
|
||
|
"network": "ibtida",
|
||
|
"displayName": "Anmol Network Ibtida Canary network",
|
||
|
"symbols": [
|
||
|
"IANML"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://anmol.network/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 101,
|
||
|
"network": "origintrail-parachain",
|
||
|
"displayName": "OriginTrail Parachain",
|
||
|
"symbols": [
|
||
|
"OTP"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://parachain.origintrail.io/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 105,
|
||
|
"network": "pontem-network",
|
||
|
"displayName": "Pontem Network",
|
||
|
"symbols": [
|
||
|
"PONT"
|
||
|
],
|
||
|
"decimals": [
|
||
|
10
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://pontem.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 110,
|
||
|
"network": "heiko",
|
||
|
"displayName": "Heiko",
|
||
|
"symbols": [
|
||
|
"HKO"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://parallel.fi/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 113,
|
||
|
"network": "integritee-incognito",
|
||
|
"displayName": "Integritee Incognito",
|
||
|
"symbols": [],
|
||
|
"decimals": [],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://integritee.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 117,
|
||
|
"network": "tinker",
|
||
|
"displayName": "Tinker",
|
||
|
"symbols": [
|
||
|
"TNKR"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://invarch.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 126,
|
||
|
"network": "joystream",
|
||
|
"displayName": "Joystream",
|
||
|
"symbols": [
|
||
|
"JOY"
|
||
|
],
|
||
|
"decimals": [
|
||
|
10
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://www.joystream.org"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 128,
|
||
|
"network": "clover",
|
||
|
"displayName": "Clover Finance",
|
||
|
"symbols": [
|
||
|
"CLV"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://clover.finance"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 129,
|
||
|
"network": "dorafactory-polkadot",
|
||
|
"displayName": "Dorafactory Polkadot Network",
|
||
|
"symbols": [
|
||
|
"DORA"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://dorafactory.org"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 131,
|
||
|
"network": "litmus",
|
||
|
"displayName": "Litmus Network",
|
||
|
"symbols": [
|
||
|
"LIT"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://litentry.com/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 136,
|
||
|
"network": "altair",
|
||
|
"displayName": "Altair",
|
||
|
"symbols": [
|
||
|
"AIR"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://centrifuge.io/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 137,
|
||
|
"network": "vara",
|
||
|
"displayName": "Vara Network",
|
||
|
"symbols": [
|
||
|
"VARA"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://vara-network.io/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 172,
|
||
|
"network": "parallel",
|
||
|
"displayName": "Parallel",
|
||
|
"symbols": [
|
||
|
"PARA"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://parallel.fi/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 252,
|
||
|
"network": "social-network",
|
||
|
"displayName": "Social Network",
|
||
|
"symbols": [
|
||
|
"NET"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://social.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 255,
|
||
|
"network": "quartz_mainnet",
|
||
|
"displayName": "QUARTZ by UNIQUE",
|
||
|
"symbols": [
|
||
|
"QTZ"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://unique.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 268,
|
||
|
"network": "pioneer_network",
|
||
|
"displayName": "Pioneer Network by Bit.Country",
|
||
|
"symbols": [
|
||
|
"NEER"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://bit.country"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 420,
|
||
|
"network": "sora_kusama_para",
|
||
|
"displayName": "SORA Kusama Parachain",
|
||
|
"symbols": [
|
||
|
"XOR"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://sora.org"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 440,
|
||
|
"network": "allfeat_network",
|
||
|
"displayName": "Allfeat Network",
|
||
|
"symbols": [
|
||
|
"AFT"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://allfeat.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 666,
|
||
|
"network": "metaquity_network",
|
||
|
"displayName": "Metaquity Network",
|
||
|
"symbols": [
|
||
|
"MQTY"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://metaquity.xyz/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 789,
|
||
|
"network": "geek",
|
||
|
"displayName": "GEEK Network",
|
||
|
"symbols": [
|
||
|
"GEEK"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://geek.gl"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 995,
|
||
|
"network": "ternoa",
|
||
|
"displayName": "Ternoa",
|
||
|
"symbols": [
|
||
|
"CAPS"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://www.ternoa.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 1110,
|
||
|
"network": "efinity",
|
||
|
"displayName": "Efinity",
|
||
|
"symbols": [
|
||
|
"EFI"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://efinity.io/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 1221,
|
||
|
"network": "peaq",
|
||
|
"displayName": "Peaq Network",
|
||
|
"symbols": [
|
||
|
"PEAQ"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "Sr25519",
|
||
|
"website": "https://www.peaq.network/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 1222,
|
||
|
"network": "krest",
|
||
|
"displayName": "Krest Network",
|
||
|
"symbols": [
|
||
|
"KREST"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "Sr25519",
|
||
|
"website": "https://www.peaq.network/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 1284,
|
||
|
"network": "moonbeam",
|
||
|
"displayName": "Moonbeam",
|
||
|
"symbols": [
|
||
|
"GLMR"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "secp256k1",
|
||
|
"website": "https://moonbeam.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 1285,
|
||
|
"network": "moonriver",
|
||
|
"displayName": "Moonriver",
|
||
|
"symbols": [
|
||
|
"MOVR"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "secp256k1",
|
||
|
"website": "https://moonbeam.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 1328,
|
||
|
"network": "ajuna",
|
||
|
"displayName": "Ajuna Network",
|
||
|
"symbols": [
|
||
|
"AJUN"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://ajuna.io"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 1337,
|
||
|
"network": "bajun",
|
||
|
"displayName": "Bajun Network",
|
||
|
"symbols": [
|
||
|
"BAJU"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://ajuna.io"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 1516,
|
||
|
"network": "societal",
|
||
|
"displayName": "Societal",
|
||
|
"symbols": [
|
||
|
"SCTL"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://www.sctl.xyz"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 1985,
|
||
|
"network": "seals",
|
||
|
"displayName": "Seals Network",
|
||
|
"symbols": [
|
||
|
"SEAL"
|
||
|
],
|
||
|
"decimals": [
|
||
|
9
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://seals.app"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 2007,
|
||
|
"network": "kapex",
|
||
|
"displayName": "Kapex",
|
||
|
"symbols": [
|
||
|
"KAPEX"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://totemaccounting.com"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 2009,
|
||
|
"network": "cloudwalk_mainnet",
|
||
|
"displayName": "CloudWalk Network Mainnet",
|
||
|
"symbols": [
|
||
|
"CWN"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://explorer.mainnet.cloudwalk.io"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 2021,
|
||
|
"network": "logion",
|
||
|
"displayName": "logion network",
|
||
|
"symbols": [
|
||
|
"LGNT"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://logion.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 2032,
|
||
|
"network": "interlay",
|
||
|
"displayName": "Interlay",
|
||
|
"symbols": [
|
||
|
"INTR"
|
||
|
],
|
||
|
"decimals": [
|
||
|
10
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://interlay.io/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 2092,
|
||
|
"network": "kintsugi",
|
||
|
"displayName": "Kintsugi",
|
||
|
"symbols": [
|
||
|
"KINT"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://interlay.io/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 2106,
|
||
|
"network": "bitgreen",
|
||
|
"displayName": "Bitgreen",
|
||
|
"symbols": [
|
||
|
"BBB"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://bitgreen.org/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 2112,
|
||
|
"network": "chainflip",
|
||
|
"displayName": "Chainflip",
|
||
|
"symbols": [
|
||
|
"FLIP"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://chainflip.io/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 2199,
|
||
|
"network": "moonsama",
|
||
|
"displayName": "Moonsama",
|
||
|
"symbols": [
|
||
|
"SAMA"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "secp256k1",
|
||
|
"website": "https://moonsama.com"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 2206,
|
||
|
"network": "ICE",
|
||
|
"displayName": "ICE Network",
|
||
|
"symbols": [
|
||
|
"ICY"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://icenetwork.io"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 2207,
|
||
|
"network": "SNOW",
|
||
|
"displayName": "SNOW: ICE Canary Network",
|
||
|
"symbols": [
|
||
|
"ICZ"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://icenetwork.io"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 2254,
|
||
|
"network": "subspace_testnet",
|
||
|
"displayName": "Subspace testnet",
|
||
|
"symbols": [
|
||
|
"tSSC"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://subspace.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 3333,
|
||
|
"network": "peerplays",
|
||
|
"displayName": "Peerplays",
|
||
|
"symbols": [
|
||
|
"PPY"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "secp256k1",
|
||
|
"website": "https://www.peerplays.com/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 4006,
|
||
|
"network": "tangle",
|
||
|
"displayName": "Tangle Network",
|
||
|
"symbols": [
|
||
|
"TNT"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://www.webb.tools/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 4450,
|
||
|
"network": "g1",
|
||
|
"displayName": "Ğ1",
|
||
|
"symbols": [
|
||
|
"G1"
|
||
|
],
|
||
|
"decimals": [
|
||
|
2
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://duniter.org"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 5234,
|
||
|
"network": "humanode",
|
||
|
"displayName": "Humanode Network",
|
||
|
"symbols": [
|
||
|
"HMND"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://humanode.io"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 6094,
|
||
|
"network": "subspace",
|
||
|
"displayName": "Subspace",
|
||
|
"symbols": [
|
||
|
"SSC"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://subspace.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 7007,
|
||
|
"network": "tidefi",
|
||
|
"displayName": "Tidefi",
|
||
|
"symbols": [
|
||
|
"TDFY"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://tidefi.com"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 7013,
|
||
|
"network": "gm",
|
||
|
"displayName": "GM",
|
||
|
"symbols": [
|
||
|
"FREN",
|
||
|
"GM",
|
||
|
"GN"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12,
|
||
|
0,
|
||
|
0
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://gmordie.com"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 7306,
|
||
|
"network": "krigan",
|
||
|
"displayName": "Krigan Network",
|
||
|
"symbols": [
|
||
|
"KRGN"
|
||
|
],
|
||
|
"decimals": [
|
||
|
9
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://krigan.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 7391,
|
||
|
"network": "unique_mainnet",
|
||
|
"displayName": "Unique Network",
|
||
|
"symbols": [
|
||
|
"UNQ"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://unique.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 8866,
|
||
|
"network": "golden_gate",
|
||
|
"displayName": "Golden Gate",
|
||
|
"symbols": [
|
||
|
"GGX"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://ggxchain.io/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 8883,
|
||
|
"network": "sapphire_mainnet",
|
||
|
"displayName": "Sapphire by Unique",
|
||
|
"symbols": [
|
||
|
"QTZ"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://unique.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 8886,
|
||
|
"network": "golden_gate_sydney",
|
||
|
"displayName": "Golden Gate Sydney",
|
||
|
"symbols": [
|
||
|
"GGXT"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://ggxchain.io/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 9072,
|
||
|
"network": "hashed",
|
||
|
"displayName": "Hashed Network",
|
||
|
"symbols": [
|
||
|
"HASH"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://hashed.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 9807,
|
||
|
"network": "dentnet",
|
||
|
"displayName": "DENTNet",
|
||
|
"symbols": [
|
||
|
"DENTX"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://www.dentnet.io"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 9935,
|
||
|
"network": "t3rn",
|
||
|
"displayName": "t3rn",
|
||
|
"symbols": [
|
||
|
"TRN"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://t3rn.io/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 10041,
|
||
|
"network": "basilisk",
|
||
|
"displayName": "Basilisk",
|
||
|
"symbols": [
|
||
|
"BSX"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://bsx.fi"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 11330,
|
||
|
"network": "cess-testnet",
|
||
|
"displayName": "CESS Testnet",
|
||
|
"symbols": [
|
||
|
"TCESS"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://cess.cloud"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 11331,
|
||
|
"network": "cess",
|
||
|
"displayName": "CESS",
|
||
|
"symbols": [
|
||
|
"CESS"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://cess.cloud"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 11486,
|
||
|
"network": "luhn",
|
||
|
"displayName": "Luhn Network",
|
||
|
"symbols": [
|
||
|
"LUHN"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://luhn.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 11820,
|
||
|
"network": "contextfree",
|
||
|
"displayName": "Automata ContextFree",
|
||
|
"symbols": [
|
||
|
"CTX"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://ata.network"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 12155,
|
||
|
"network": "impact",
|
||
|
"displayName": "Impact Protocol Network",
|
||
|
"symbols": [
|
||
|
"BSTY"
|
||
|
],
|
||
|
"decimals": [
|
||
|
18
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://impactprotocol.network/"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 12191,
|
||
|
"network": "nftmart",
|
||
|
"displayName": "NFTMart",
|
||
|
"symbols": [
|
||
|
"NMT"
|
||
|
],
|
||
|
"decimals": [
|
||
|
12
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://nftmart.io"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 13116,
|
||
|
"network": "bittensor",
|
||
|
"displayName": "Bittensor",
|
||
|
"symbols": [
|
||
|
"TAO"
|
||
|
],
|
||
|
"decimals": [
|
||
|
9
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://bittensor.com"
|
||
|
},
|
||
|
{
|
||
|
"prefix": 14697,
|
||
|
"network": "goro",
|
||
|
"displayName": "GORO Network",
|
||
|
"symbols": [
|
||
|
"GORO"
|
||
|
],
|
||
|
"decimals": [
|
||
|
9
|
||
|
],
|
||
|
"standardAccount": "*25519",
|
||
|
"website": "https://goro.network"
|
||
|
}
|
||
|
];
|
||
|
|
||
|
const knownGenesis = {
|
||
|
acala: [
|
||
|
'0xfc41b9bd8ef8fe53d58c7ea67c794c7ec9a73daf05e6d54b14ff6342c99ba64c'
|
||
|
],
|
||
|
ajuna: [
|
||
|
'0xe358eb1d11b31255a286c12e44fe6780b7edb171d657905a97e39f71d9c6c3ee'
|
||
|
],
|
||
|
'aleph-node': [
|
||
|
'0x70255b4d28de0fc4e1a193d7e175ad1ccef431598211c55538f1018651a0344e'
|
||
|
],
|
||
|
astar: [
|
||
|
'0x9eb76c5184c4ab8679d2d5d819fdf90b9c001403e9e17da2e14b6d8aec4029c6'
|
||
|
],
|
||
|
basilisk: [
|
||
|
'0xa85cfb9b9fd4d622a5b28289a02347af987d8f73fa3108450e2b4a11c1ce5755'
|
||
|
],
|
||
|
bifrost: [
|
||
|
'0x262e1b2ad728475fd6fe88e62d34c200abe6fd693931ddad144059b1eb884e5b'
|
||
|
],
|
||
|
'bifrost-kusama': [
|
||
|
'0x9f28c6a68e0fc9646eff64935684f6eeeece527e37bbe1f213d22caa1d9d6bed'
|
||
|
],
|
||
|
bittensor: [
|
||
|
'0x2f0555cc76fc2840a25a6ea3b9637146806f1f44b090c175ffde2a7e5ab36c03'
|
||
|
],
|
||
|
centrifuge: [
|
||
|
'0xb3db41421702df9a7fcac62b53ffeac85f7853cc4e689e0b93aeb3db18c09d82',
|
||
|
'0x67dddf2673b69e5f875f6f25277495834398eafd67f492e09f3f3345e003d1b5'
|
||
|
],
|
||
|
cere: [
|
||
|
'0x81443836a9a24caaa23f1241897d1235717535711d1d3fe24eae4fdc942c092c'
|
||
|
],
|
||
|
composable: [
|
||
|
'0xdaab8df776eb52ec604a5df5d388bb62a050a0aaec4556a64265b9d42755552d'
|
||
|
],
|
||
|
darwinia: [
|
||
|
'0xe71578b37a7c799b0ab4ee87ffa6f059a6b98f71f06fb8c84a8d88013a548ad6'
|
||
|
],
|
||
|
'dock-mainnet': [
|
||
|
'0x6bfe24dca2a3be10f22212678ac13a6446ec764103c0f3471c71609eac384aae',
|
||
|
'0xf73467c6544aa68df2ee546b135f955c46b90fa627e9b5d7935f41061bb8a5a9'
|
||
|
],
|
||
|
edgeware: [
|
||
|
'0x742a2ca70c2fda6cee4f8df98d64c4c670a052d9568058982dad9d5a7a135c5b'
|
||
|
],
|
||
|
enjin: [
|
||
|
'0xd8761d3c88f26dc12875c00d3165f7d67243d56fc85b4cf19937601a7916e5a9'
|
||
|
],
|
||
|
equilibrium: [
|
||
|
'0x6f1a800de3daff7f5e037ddf66ab22ce03ab91874debeddb1086f5f7dbd48925'
|
||
|
],
|
||
|
genshiro: [
|
||
|
'0x9b8cefc0eb5c568b527998bdd76c184e2b76ae561be76e4667072230217ea243'
|
||
|
],
|
||
|
hydradx: [
|
||
|
'0xafdc188f45c71dacbaa0b62e16a91f726c7b8699a9748cdf715459de6b7f366d',
|
||
|
'0xd2a620c27ec5cbc5621ff9a522689895074f7cca0d08e7134a7804e1a3ba86fc',
|
||
|
'0x10af6e84234477d84dc572bac0789813b254aa490767ed06fb9591191d1073f9',
|
||
|
'0x3d75507dd46301767e601265791da1d9cb47b6ebc94e87347b635e5bf58bd047',
|
||
|
'0x0ed32bfcab4a83517fac88f2aa7cbc2f88d3ab93be9a12b6188a036bf8a943c2'
|
||
|
],
|
||
|
'interlay-parachain': [
|
||
|
'0xbf88efe70e9e0e916416e8bed61f2b45717f517d7f3523e33c7b001e5ffcbc72'
|
||
|
],
|
||
|
karura: [
|
||
|
'0xbaf5aabe40646d11f0ee8abbdc64f4a4b7674925cba08e4a05ff9ebed6e2126b'
|
||
|
],
|
||
|
khala: [
|
||
|
'0xd43540ba6d3eb4897c28a77d48cb5b729fea37603cbbfc7a86a73b72adb3be8d'
|
||
|
],
|
||
|
kulupu: [
|
||
|
'0xf7a99d3cb92853d00d5275c971c132c074636256583fee53b3bbe60d7b8769ba'
|
||
|
],
|
||
|
kusama: [
|
||
|
'0xb0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe',
|
||
|
'0xe3777fa922cafbff200cadeaea1a76bd7898ad5b89f7848999058b50e715f636',
|
||
|
'0x3fd7b9eb6a00376e5be61f01abb429ffb0b104be05eaff4d458da48fcd425baf'
|
||
|
],
|
||
|
matrixchain: [
|
||
|
'0x3af4ff48ec76d2efc8476730f423ac07e25ad48f5f4c9dc39c778b164d808615'
|
||
|
],
|
||
|
nodle: [
|
||
|
'0x97da7ede98d7bad4e36b4d734b6055425a3be036da2a332ea5a7037656427a21'
|
||
|
],
|
||
|
origintrail: [
|
||
|
'0xe7e0962324a3b86c83404dbea483f25fb5dab4c224791c81b756cfc948006174'
|
||
|
],
|
||
|
p3d: [
|
||
|
'0x6c5894837ad89b6d92b114a2fb3eafa8fe3d26a54848e3447015442cd6ef4e66'
|
||
|
],
|
||
|
parallel: [
|
||
|
'0xe61a41c53f5dcd0beb09df93b34402aada44cb05117b71059cce40a2723a4e97'
|
||
|
],
|
||
|
pendulum: [
|
||
|
'0x5d3c298622d5634ed019bf61ea4b71655030015bde9beb0d6a24743714462c86'
|
||
|
],
|
||
|
phala: [
|
||
|
'0x1bb969d85965e4bb5a651abbedf21a54b6b31a21f66b5401cc3f1e286268d736'
|
||
|
],
|
||
|
picasso: [
|
||
|
'0x6811a339673c9daa897944dcdac99c6e2939cc88245ed21951a0a3c9a2be75bc',
|
||
|
'0xe8e7f0f4c4f5a00720b4821dbfddefea7490bcf0b19009961cc46957984e2c1c'
|
||
|
],
|
||
|
polkadex: [
|
||
|
'0x3920bcb4960a1eef5580cd5367ff3f430eef052774f78468852f7b9cb39f8a3c'
|
||
|
],
|
||
|
polkadot: [
|
||
|
'0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3'
|
||
|
],
|
||
|
polymesh: [
|
||
|
'0x6fbd74e5e1d0a61d52ccfe9d4adaed16dd3a7caa37c6bc4d0c2fa12e8b2f4063'
|
||
|
],
|
||
|
quartz: [
|
||
|
'0xcd4d732201ebe5d6b014edda071c4203e16867305332301dc8d092044b28e554'
|
||
|
],
|
||
|
rococo: [
|
||
|
'0x6408de7737c59c238890533af25896a2c20608d8b380bb01029acb392781063e',
|
||
|
'0xaaf2cd1b74b5f726895921259421b534124726263982522174147046b8827897',
|
||
|
'0x037f5f3c8e67b314062025fc886fcd6238ea25a4a9b45dce8d246815c9ebe770',
|
||
|
'0xc196f81260cf1686172b47a79cf002120735d7cb0eb1474e8adce56618456fff',
|
||
|
'0xf6e9983c37baf68846fedafe21e56718790e39fb1c582abc408b81bc7b208f9a',
|
||
|
'0x5fce687da39305dfe682b117f0820b319348e8bb37eb16cf34acbf6a202de9d9',
|
||
|
'0xe7c3d5edde7db964317cd9b51a3a059d7cd99f81bdbce14990047354334c9779',
|
||
|
'0x1611e1dbf0405379b861e2e27daa90f480b2e6d3682414a80835a52e8cb8a215',
|
||
|
'0x343442f12fa715489a8714e79a7b264ea88c0d5b8c66b684a7788a516032f6b9',
|
||
|
'0x78bcd530c6b3a068bc17473cf5d2aff9c287102bed9af3ae3c41c33b9d6c6147',
|
||
|
'0x47381ee0697153d64404fc578392c8fd5cba9073391908f46c888498415647bd',
|
||
|
'0x19c0e4fa8ab75f5ac7865e0b8f74ff91eb9a100d336f423cd013a8befba40299'
|
||
|
],
|
||
|
sora: [
|
||
|
'0x7e4e32d0feafd4f9c9414b0be86373f9a1efa904809b683453a9af6856d38ad5'
|
||
|
],
|
||
|
stafi: [
|
||
|
'0x290a4149f09ea0e402c74c1c7e96ae4239588577fe78932f94f5404c68243d80'
|
||
|
],
|
||
|
statemine: [
|
||
|
'0x48239ef607d7928874027a43a67689209727dfb3d3dc5e5b03a39bdc2eda771a'
|
||
|
],
|
||
|
statemint: [
|
||
|
'0x68d56f15f85d3136970ec16946040bc1752654e906147f7e43e9d539d7c3de2f'
|
||
|
],
|
||
|
subsocial: [
|
||
|
'0x0bd72c1c305172e1275278aaeb3f161e02eccb7a819e63f62d47bd53a28189f8'
|
||
|
],
|
||
|
ternoa: [
|
||
|
'0x6859c81ca95ef624c9dfe4dc6e3381c33e5d6509e35e147092bfbc780f777c4e'
|
||
|
],
|
||
|
unique: [
|
||
|
'0x84322d9cddbf35088f1e54e9a85c967a41a56a4f43445768125e61af166c7d31'
|
||
|
],
|
||
|
vtb: [
|
||
|
'0x286bc8414c7000ce1d6ee6a834e29a54c1784814b76243eb77ed0b2c5573c60f',
|
||
|
'0x7483b89572fb2bd687c7b9a93b242d0b237f9aba463aba07ec24503931038aaa'
|
||
|
],
|
||
|
westend: [
|
||
|
'0xe143f23803ac50e8f6f8e62695d1ce9e4e1d68aa36c1cd2cfd15340213f3423e'
|
||
|
],
|
||
|
xxnetwork: [
|
||
|
'0x50dd5d206917bf10502c68fb4d18a59fc8aa31586f4e8856b493e43544aa82aa'
|
||
|
],
|
||
|
zeitgeist: [
|
||
|
'0x1bf2a2ecb4a868de66ea8610f2ce7c8c43706561b6476031315f6640fe38e060'
|
||
|
]
|
||
|
};
|
||
|
|
||
|
const knownIcon = {
|
||
|
centrifuge: 'polkadot',
|
||
|
kusama: 'polkadot',
|
||
|
polkadot: 'polkadot',
|
||
|
sora: 'polkadot',
|
||
|
statemine: 'polkadot',
|
||
|
statemint: 'polkadot',
|
||
|
westmint: 'polkadot'
|
||
|
};
|
||
|
|
||
|
const knownLedger = {
|
||
|
acala: 0x00000313,
|
||
|
ajuna: 0x00000162,
|
||
|
'aleph-node': 0x00000283,
|
||
|
astar: 0x0000032a,
|
||
|
bifrost: 0x00000314,
|
||
|
'bifrost-kusama': 0x00000314,
|
||
|
centrifuge: 0x000002eb,
|
||
|
composable: 0x00000162,
|
||
|
darwinia: 0x00000162,
|
||
|
'dock-mainnet': 0x00000252,
|
||
|
edgeware: 0x0000020b,
|
||
|
enjin: 0x00000483,
|
||
|
equilibrium: 0x05f5e0fd,
|
||
|
genshiro: 0x05f5e0fc,
|
||
|
hydradx: 0x00000162,
|
||
|
'interlay-parachain': 0x00000162,
|
||
|
karura: 0x000002ae,
|
||
|
khala: 0x000001b2,
|
||
|
kusama: 0x000001b2,
|
||
|
matrixchain: 0x00000483,
|
||
|
nodle: 0x000003eb,
|
||
|
origintrail: 0x00000162,
|
||
|
parallel: 0x00000162,
|
||
|
pendulum: 0x00000162,
|
||
|
phala: 0x00000162,
|
||
|
picasso: 0x000001b2,
|
||
|
polkadex: 0x0000031f,
|
||
|
polkadot: 0x00000162,
|
||
|
polymesh: 0x00000253,
|
||
|
quartz: 0x00000277,
|
||
|
sora: 0x00000269,
|
||
|
stafi: 0x0000038b,
|
||
|
statemine: 0x000001b2,
|
||
|
statemint: 0x00000162,
|
||
|
ternoa: 0x00003e3,
|
||
|
unique: 0x00000295,
|
||
|
vtb: 0x000002b6,
|
||
|
xxnetwork: 0x000007a3,
|
||
|
zeitgeist: 0x00000162
|
||
|
};
|
||
|
|
||
|
const knownTestnet = {
|
||
|
'': true,
|
||
|
'cess-testnet': true,
|
||
|
'dock-testnet': true,
|
||
|
jupiter: true,
|
||
|
'mathchain-testnet': true,
|
||
|
p3dt: true,
|
||
|
subspace_testnet: true,
|
||
|
'zero-alphaville': true
|
||
|
};
|
||
|
|
||
|
const UNSORTED = [0, 2, 42];
|
||
|
const TESTNETS = ['testnet'];
|
||
|
function toExpanded(o) {
|
||
|
const network = o.network || '';
|
||
|
const nameParts = network.replace(/_/g, '-').split('-');
|
||
|
const n = o;
|
||
|
n.slip44 = knownLedger[network];
|
||
|
n.hasLedgerSupport = !!n.slip44;
|
||
|
n.genesisHash = knownGenesis[network] || [];
|
||
|
n.icon = knownIcon[network] || 'substrate';
|
||
|
n.isTestnet = !!knownTestnet[network] || TESTNETS.includes(nameParts[nameParts.length - 1]);
|
||
|
n.isIgnored = n.isTestnet || (!(o.standardAccount &&
|
||
|
o.decimals?.length &&
|
||
|
o.symbols?.length) &&
|
||
|
o.prefix !== 42);
|
||
|
return n;
|
||
|
}
|
||
|
function filterSelectable({ genesisHash, prefix }) {
|
||
|
return !!genesisHash.length || prefix === 42;
|
||
|
}
|
||
|
function filterAvailable(n) {
|
||
|
return !n.isIgnored && !!n.network;
|
||
|
}
|
||
|
function sortNetworks(a, b) {
|
||
|
const isUnSortedA = UNSORTED.includes(a.prefix);
|
||
|
const isUnSortedB = UNSORTED.includes(b.prefix);
|
||
|
return isUnSortedA === isUnSortedB
|
||
|
? isUnSortedA
|
||
|
? 0
|
||
|
: a.displayName.localeCompare(b.displayName)
|
||
|
: isUnSortedA
|
||
|
? -1
|
||
|
: 1;
|
||
|
}
|
||
|
const allNetworks = knownSubstrate.map(toExpanded);
|
||
|
const availableNetworks = allNetworks.filter(filterAvailable).sort(sortNetworks);
|
||
|
const selectableNetworks = availableNetworks.filter(filterSelectable);
|
||
|
|
||
|
const defaults = {
|
||
|
allowedDecodedLengths: [1, 2, 4, 8, 32, 33],
|
||
|
allowedEncodedLengths: [3, 4, 6, 10, 35, 36, 37, 38],
|
||
|
allowedPrefix: availableNetworks.map(({ prefix }) => prefix),
|
||
|
prefix: 42
|
||
|
};
|
||
|
|
||
|
function decodeAddress(encoded, ignoreChecksum, ss58Format = -1) {
|
||
|
if (!encoded) {
|
||
|
throw new Error('Invalid empty address passed');
|
||
|
}
|
||
|
if (util.isU8a(encoded) || util.isHex(encoded)) {
|
||
|
return util.u8aToU8a(encoded);
|
||
|
}
|
||
|
try {
|
||
|
const decoded = base58Decode(encoded);
|
||
|
if (!defaults.allowedEncodedLengths.includes(decoded.length)) {
|
||
|
throw new Error('Invalid decoded address length');
|
||
|
}
|
||
|
const [isValid, endPos, ss58Length, ss58Decoded] = checkAddressChecksum(decoded);
|
||
|
if (!isValid && !ignoreChecksum) {
|
||
|
throw new Error('Invalid decoded address checksum');
|
||
|
}
|
||
|
else if (ss58Format !== -1 && ss58Format !== ss58Decoded) {
|
||
|
throw new Error(`Expected ss58Format ${ss58Format}, received ${ss58Decoded}`);
|
||
|
}
|
||
|
return decoded.slice(ss58Length, endPos);
|
||
|
}
|
||
|
catch (error) {
|
||
|
throw new Error(`Decoding ${encoded}: ${error.message}`);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function addressToEvm(address, ignoreChecksum) {
|
||
|
return decodeAddress(address, ignoreChecksum).subarray(0, 20);
|
||
|
}
|
||
|
|
||
|
function checkAddress(address, prefix) {
|
||
|
let decoded;
|
||
|
try {
|
||
|
decoded = base58Decode(address);
|
||
|
}
|
||
|
catch (error) {
|
||
|
return [false, error.message];
|
||
|
}
|
||
|
const [isValid, , , ss58Decoded] = checkAddressChecksum(decoded);
|
||
|
if (ss58Decoded !== prefix) {
|
||
|
return [false, `Prefix mismatch, expected ${prefix}, found ${ss58Decoded}`];
|
||
|
}
|
||
|
else if (!defaults.allowedEncodedLengths.includes(decoded.length)) {
|
||
|
return [false, 'Invalid decoded address length'];
|
||
|
}
|
||
|
return [isValid, isValid ? null : 'Invalid decoded address checksum'];
|
||
|
}
|
||
|
|
||
|
const BN_BE_OPTS = { isLe: false };
|
||
|
const BN_LE_OPTS = { isLe: true };
|
||
|
const BN_LE_16_OPTS = { bitLength: 16, isLe: true };
|
||
|
const BN_BE_32_OPTS = { bitLength: 32, isLe: false };
|
||
|
const BN_LE_32_OPTS = { bitLength: 32, isLe: true };
|
||
|
const BN_BE_256_OPTS = { bitLength: 256, isLe: false };
|
||
|
const BN_LE_256_OPTS = { bitLength: 256, isLe: true };
|
||
|
const BN_LE_512_OPTS = { bitLength: 512, isLe: true };
|
||
|
|
||
|
const RE_NUMBER = /^\d+$/;
|
||
|
const JUNCTION_ID_LEN = 32;
|
||
|
class DeriveJunction {
|
||
|
__internal__chainCode = new Uint8Array(32);
|
||
|
__internal__isHard = false;
|
||
|
static from(value) {
|
||
|
const result = new DeriveJunction();
|
||
|
const [code, isHard] = value.startsWith('/')
|
||
|
? [value.substring(1), true]
|
||
|
: [value, false];
|
||
|
result.soft(RE_NUMBER.test(code)
|
||
|
? new util.BN(code, 10)
|
||
|
: code);
|
||
|
return isHard
|
||
|
? result.harden()
|
||
|
: result;
|
||
|
}
|
||
|
get chainCode() {
|
||
|
return this.__internal__chainCode;
|
||
|
}
|
||
|
get isHard() {
|
||
|
return this.__internal__isHard;
|
||
|
}
|
||
|
get isSoft() {
|
||
|
return !this.__internal__isHard;
|
||
|
}
|
||
|
hard(value) {
|
||
|
return this.soft(value).harden();
|
||
|
}
|
||
|
harden() {
|
||
|
this.__internal__isHard = true;
|
||
|
return this;
|
||
|
}
|
||
|
soft(value) {
|
||
|
if (util.isNumber(value) || util.isBn(value) || util.isBigInt(value)) {
|
||
|
return this.soft(util.bnToU8a(value, BN_LE_256_OPTS));
|
||
|
}
|
||
|
else if (util.isHex(value)) {
|
||
|
return this.soft(util.hexToU8a(value));
|
||
|
}
|
||
|
else if (util.isString(value)) {
|
||
|
return this.soft(util.compactAddLength(util.stringToU8a(value)));
|
||
|
}
|
||
|
else if (value.length > JUNCTION_ID_LEN) {
|
||
|
return this.soft(blake2AsU8a(value));
|
||
|
}
|
||
|
this.__internal__chainCode.fill(0);
|
||
|
this.__internal__chainCode.set(value, 0);
|
||
|
return this;
|
||
|
}
|
||
|
soften() {
|
||
|
this.__internal__isHard = false;
|
||
|
return this;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const RE_JUNCTION = /\/(\/?)([^/]+)/g;
|
||
|
function keyExtractPath(derivePath) {
|
||
|
const parts = derivePath.match(RE_JUNCTION);
|
||
|
const path = [];
|
||
|
let constructed = '';
|
||
|
if (parts) {
|
||
|
constructed = parts.join('');
|
||
|
for (const p of parts) {
|
||
|
path.push(DeriveJunction.from(p.substring(1)));
|
||
|
}
|
||
|
}
|
||
|
if (constructed !== derivePath) {
|
||
|
throw new Error(`Re-constructed path "${constructed}" does not match input`);
|
||
|
}
|
||
|
return {
|
||
|
parts,
|
||
|
path
|
||
|
};
|
||
|
}
|
||
|
|
||
|
const RE_CAPTURE = /^(\w+( \w+)*)((\/\/?[^/]+)*)(\/\/\/(.*))?$/;
|
||
|
function keyExtractSuri(suri) {
|
||
|
const matches = suri.match(RE_CAPTURE);
|
||
|
if (matches === null) {
|
||
|
throw new Error('Unable to match provided value to a secret URI');
|
||
|
}
|
||
|
const [, phrase, , derivePath, , , password] = matches;
|
||
|
const { path } = keyExtractPath(derivePath);
|
||
|
return {
|
||
|
derivePath,
|
||
|
password,
|
||
|
path,
|
||
|
phrase
|
||
|
};
|
||
|
}
|
||
|
|
||
|
const HDKD$1 = util.compactAddLength(util.stringToU8a('Secp256k1HDKD'));
|
||
|
function secp256k1DeriveHard(seed, chainCode) {
|
||
|
if (!util.isU8a(chainCode) || chainCode.length !== 32) {
|
||
|
throw new Error('Invalid chainCode passed to derive');
|
||
|
}
|
||
|
return blake2AsU8a(util.u8aConcat(HDKD$1, seed, chainCode), 256);
|
||
|
}
|
||
|
|
||
|
function setBigUint64(view, byteOffset, value, isLE) {
|
||
|
if (typeof view.setBigUint64 === 'function')
|
||
|
return view.setBigUint64(byteOffset, value, isLE);
|
||
|
const _32n = BigInt(32);
|
||
|
const _u32_max = BigInt(0xffffffff);
|
||
|
const wh = Number((value >> _32n) & _u32_max);
|
||
|
const wl = Number(value & _u32_max);
|
||
|
const h = isLE ? 4 : 0;
|
||
|
const l = isLE ? 0 : 4;
|
||
|
view.setUint32(byteOffset + h, wh, isLE);
|
||
|
view.setUint32(byteOffset + l, wl, isLE);
|
||
|
}
|
||
|
class SHA2 extends Hash {
|
||
|
constructor(blockLen, outputLen, padOffset, isLE) {
|
||
|
super();
|
||
|
this.blockLen = blockLen;
|
||
|
this.outputLen = outputLen;
|
||
|
this.padOffset = padOffset;
|
||
|
this.isLE = isLE;
|
||
|
this.finished = false;
|
||
|
this.length = 0;
|
||
|
this.pos = 0;
|
||
|
this.destroyed = false;
|
||
|
this.buffer = new Uint8Array(blockLen);
|
||
|
this.view = createView(this.buffer);
|
||
|
}
|
||
|
update(data) {
|
||
|
exists(this);
|
||
|
const { view, buffer, blockLen } = this;
|
||
|
data = toBytes(data);
|
||
|
const len = data.length;
|
||
|
for (let pos = 0; pos < len;) {
|
||
|
const take = Math.min(blockLen - this.pos, len - pos);
|
||
|
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) {
|
||
|
exists(this);
|
||
|
output(out, this);
|
||
|
this.finished = true;
|
||
|
const { buffer, view, blockLen, isLE } = this;
|
||
|
let { pos } = this;
|
||
|
buffer[pos++] = 0b10000000;
|
||
|
this.buffer.subarray(pos).fill(0);
|
||
|
if (this.padOffset > blockLen - pos) {
|
||
|
this.process(view, 0);
|
||
|
pos = 0;
|
||
|
}
|
||
|
for (let i = pos; i < blockLen; i++)
|
||
|
buffer[i] = 0;
|
||
|
setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);
|
||
|
this.process(view, 0);
|
||
|
const oview = createView(out);
|
||
|
const len = this.outputLen;
|
||
|
if (len % 4)
|
||
|
throw new Error('_sha2: outputLen should 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 || (to = new this.constructor());
|
||
|
to.set(...this.get());
|
||
|
const { blockLen, buffer, length, finished, destroyed, pos } = this;
|
||
|
to.length = length;
|
||
|
to.pos = pos;
|
||
|
to.finished = finished;
|
||
|
to.destroyed = destroyed;
|
||
|
if (length % blockLen)
|
||
|
to.buffer.set(buffer);
|
||
|
return to;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const Chi = (a, b, c) => (a & b) ^ (~a & c);
|
||
|
const Maj = (a, b, c) => (a & b) ^ (a & c) ^ (b & c);
|
||
|
const SHA256_K = new Uint32Array([
|
||
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||
|
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||
|
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||
|
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||
|
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||
|
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||
|
]);
|
||
|
const IV = new Uint32Array([
|
||
|
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
||
|
]);
|
||
|
const SHA256_W = new Uint32Array(64);
|
||
|
class SHA256 extends SHA2 {
|
||
|
constructor() {
|
||
|
super(64, 32, 8, false);
|
||
|
this.A = IV[0] | 0;
|
||
|
this.B = IV[1] | 0;
|
||
|
this.C = IV[2] | 0;
|
||
|
this.D = IV[3] | 0;
|
||
|
this.E = IV[4] | 0;
|
||
|
this.F = IV[5] | 0;
|
||
|
this.G = IV[6] | 0;
|
||
|
this.H = IV[7] | 0;
|
||
|
}
|
||
|
get() {
|
||
|
const { A, B, C, D, E, F, G, H } = this;
|
||
|
return [A, B, C, D, E, F, G, H];
|
||
|
}
|
||
|
set(A, B, C, D, E, F, G, H) {
|
||
|
this.A = A | 0;
|
||
|
this.B = B | 0;
|
||
|
this.C = C | 0;
|
||
|
this.D = D | 0;
|
||
|
this.E = E | 0;
|
||
|
this.F = F | 0;
|
||
|
this.G = G | 0;
|
||
|
this.H = H | 0;
|
||
|
}
|
||
|
process(view, offset) {
|
||
|
for (let i = 0; i < 16; i++, offset += 4)
|
||
|
SHA256_W[i] = view.getUint32(offset, false);
|
||
|
for (let i = 16; i < 64; i++) {
|
||
|
const W15 = SHA256_W[i - 15];
|
||
|
const W2 = SHA256_W[i - 2];
|
||
|
const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);
|
||
|
const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);
|
||
|
SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;
|
||
|
}
|
||
|
let { A, B, C, D, E, F, G, H } = this;
|
||
|
for (let i = 0; i < 64; i++) {
|
||
|
const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
|
||
|
const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;
|
||
|
const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
|
||
|
const T2 = (sigma0 + Maj(A, B, C)) | 0;
|
||
|
H = G;
|
||
|
G = F;
|
||
|
F = E;
|
||
|
E = (D + T1) | 0;
|
||
|
D = C;
|
||
|
C = B;
|
||
|
B = A;
|
||
|
A = (T1 + T2) | 0;
|
||
|
}
|
||
|
A = (A + this.A) | 0;
|
||
|
B = (B + this.B) | 0;
|
||
|
C = (C + this.C) | 0;
|
||
|
D = (D + this.D) | 0;
|
||
|
E = (E + this.E) | 0;
|
||
|
F = (F + this.F) | 0;
|
||
|
G = (G + this.G) | 0;
|
||
|
H = (H + this.H) | 0;
|
||
|
this.set(A, B, C, D, E, F, G, H);
|
||
|
}
|
||
|
roundClean() {
|
||
|
SHA256_W.fill(0);
|
||
|
}
|
||
|
destroy() {
|
||
|
this.set(0, 0, 0, 0, 0, 0, 0, 0);
|
||
|
this.buffer.fill(0);
|
||
|
}
|
||
|
}
|
||
|
class SHA224 extends SHA256 {
|
||
|
constructor() {
|
||
|
super();
|
||
|
this.A = 0xc1059ed8 | 0;
|
||
|
this.B = 0x367cd507 | 0;
|
||
|
this.C = 0x3070dd17 | 0;
|
||
|
this.D = 0xf70e5939 | 0;
|
||
|
this.E = 0xffc00b31 | 0;
|
||
|
this.F = 0x68581511 | 0;
|
||
|
this.G = 0x64f98fa7 | 0;
|
||
|
this.H = 0xbefa4fa4 | 0;
|
||
|
this.outputLen = 28;
|
||
|
}
|
||
|
}
|
||
|
const sha256 = wrapConstructor(() => new SHA256());
|
||
|
wrapConstructor(() => new SHA224());
|
||
|
|
||
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||
|
const _0n$8 = BigInt(0);
|
||
|
const _1n$8 = BigInt(1);
|
||
|
const _2n$6 = BigInt(2);
|
||
|
const u8a = (a) => a instanceof Uint8Array;
|
||
|
const hexes = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
|
||
|
function bytesToHex(bytes) {
|
||
|
if (!u8a(bytes))
|
||
|
throw new Error('Uint8Array expected');
|
||
|
let hex = '';
|
||
|
for (let i = 0; i < bytes.length; i++) {
|
||
|
hex += hexes[bytes[i]];
|
||
|
}
|
||
|
return hex;
|
||
|
}
|
||
|
function numberToHexUnpadded(num) {
|
||
|
const hex = num.toString(16);
|
||
|
return hex.length & 1 ? `0${hex}` : hex;
|
||
|
}
|
||
|
function hexToNumber(hex) {
|
||
|
if (typeof hex !== 'string')
|
||
|
throw new Error('hex string expected, got ' + typeof hex);
|
||
|
return BigInt(hex === '' ? '0' : `0x${hex}`);
|
||
|
}
|
||
|
function hexToBytes(hex) {
|
||
|
if (typeof hex !== 'string')
|
||
|
throw new Error('hex string expected, got ' + typeof hex);
|
||
|
const len = hex.length;
|
||
|
if (len % 2)
|
||
|
throw new Error('padded hex string expected, got unpadded hex of length ' + len);
|
||
|
const array = new Uint8Array(len / 2);
|
||
|
for (let i = 0; i < array.length; i++) {
|
||
|
const j = i * 2;
|
||
|
const hexByte = hex.slice(j, j + 2);
|
||
|
const byte = Number.parseInt(hexByte, 16);
|
||
|
if (Number.isNaN(byte) || byte < 0)
|
||
|
throw new Error('Invalid byte sequence');
|
||
|
array[i] = byte;
|
||
|
}
|
||
|
return array;
|
||
|
}
|
||
|
function bytesToNumberBE(bytes) {
|
||
|
return hexToNumber(bytesToHex(bytes));
|
||
|
}
|
||
|
function bytesToNumberLE(bytes) {
|
||
|
if (!u8a(bytes))
|
||
|
throw new Error('Uint8Array expected');
|
||
|
return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));
|
||
|
}
|
||
|
function numberToBytesBE(n, len) {
|
||
|
return hexToBytes(n.toString(16).padStart(len * 2, '0'));
|
||
|
}
|
||
|
function numberToBytesLE(n, len) {
|
||
|
return numberToBytesBE(n, len).reverse();
|
||
|
}
|
||
|
function numberToVarBytesBE(n) {
|
||
|
return hexToBytes(numberToHexUnpadded(n));
|
||
|
}
|
||
|
function ensureBytes(title, hex, expectedLength) {
|
||
|
let res;
|
||
|
if (typeof hex === 'string') {
|
||
|
try {
|
||
|
res = hexToBytes(hex);
|
||
|
}
|
||
|
catch (e) {
|
||
|
throw new Error(`${title} must be valid hex string, got "${hex}". Cause: ${e}`);
|
||
|
}
|
||
|
}
|
||
|
else if (u8a(hex)) {
|
||
|
res = Uint8Array.from(hex);
|
||
|
}
|
||
|
else {
|
||
|
throw new Error(`${title} must be hex string or Uint8Array`);
|
||
|
}
|
||
|
const len = res.length;
|
||
|
if (typeof expectedLength === 'number' && len !== expectedLength)
|
||
|
throw new Error(`${title} expected ${expectedLength} bytes, got ${len}`);
|
||
|
return res;
|
||
|
}
|
||
|
function concatBytes(...arrays) {
|
||
|
const r = new Uint8Array(arrays.reduce((sum, a) => sum + a.length, 0));
|
||
|
let pad = 0;
|
||
|
arrays.forEach((a) => {
|
||
|
if (!u8a(a))
|
||
|
throw new Error('Uint8Array expected');
|
||
|
r.set(a, pad);
|
||
|
pad += a.length;
|
||
|
});
|
||
|
return r;
|
||
|
}
|
||
|
function equalBytes(b1, b2) {
|
||
|
if (b1.length !== b2.length)
|
||
|
return false;
|
||
|
for (let i = 0; i < b1.length; i++)
|
||
|
if (b1[i] !== b2[i])
|
||
|
return false;
|
||
|
return true;
|
||
|
}
|
||
|
function utf8ToBytes(str) {
|
||
|
if (typeof str !== 'string')
|
||
|
throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
|
||
|
return new Uint8Array(new TextEncoder().encode(str));
|
||
|
}
|
||
|
function bitLen(n) {
|
||
|
let len;
|
||
|
for (len = 0; n > _0n$8; n >>= _1n$8, len += 1)
|
||
|
;
|
||
|
return len;
|
||
|
}
|
||
|
function bitGet(n, pos) {
|
||
|
return (n >> BigInt(pos)) & _1n$8;
|
||
|
}
|
||
|
const bitSet = (n, pos, value) => {
|
||
|
return n | ((value ? _1n$8 : _0n$8) << BigInt(pos));
|
||
|
};
|
||
|
const bitMask = (n) => (_2n$6 << BigInt(n - 1)) - _1n$8;
|
||
|
const u8n = (data) => new Uint8Array(data);
|
||
|
const u8fr = (arr) => Uint8Array.from(arr);
|
||
|
function createHmacDrbg(hashLen, qByteLen, hmacFn) {
|
||
|
if (typeof hashLen !== 'number' || hashLen < 2)
|
||
|
throw new Error('hashLen must be a number');
|
||
|
if (typeof qByteLen !== 'number' || qByteLen < 2)
|
||
|
throw new Error('qByteLen must be a number');
|
||
|
if (typeof hmacFn !== 'function')
|
||
|
throw new Error('hmacFn must be a function');
|
||
|
let v = u8n(hashLen);
|
||
|
let k = u8n(hashLen);
|
||
|
let i = 0;
|
||
|
const reset = () => {
|
||
|
v.fill(1);
|
||
|
k.fill(0);
|
||
|
i = 0;
|
||
|
};
|
||
|
const h = (...b) => hmacFn(k, v, ...b);
|
||
|
const reseed = (seed = u8n()) => {
|
||
|
k = h(u8fr([0x00]), seed);
|
||
|
v = h();
|
||
|
if (seed.length === 0)
|
||
|
return;
|
||
|
k = h(u8fr([0x01]), seed);
|
||
|
v = h();
|
||
|
};
|
||
|
const gen = () => {
|
||
|
if (i++ >= 1000)
|
||
|
throw new Error('drbg: tried 1000 values');
|
||
|
let len = 0;
|
||
|
const out = [];
|
||
|
while (len < qByteLen) {
|
||
|
v = h();
|
||
|
const sl = v.slice();
|
||
|
out.push(sl);
|
||
|
len += v.length;
|
||
|
}
|
||
|
return concatBytes(...out);
|
||
|
};
|
||
|
const genUntil = (seed, pred) => {
|
||
|
reset();
|
||
|
reseed(seed);
|
||
|
let res = undefined;
|
||
|
while (!(res = pred(gen())))
|
||
|
reseed();
|
||
|
reset();
|
||
|
return res;
|
||
|
};
|
||
|
return genUntil;
|
||
|
}
|
||
|
const validatorFns = {
|
||
|
bigint: (val) => typeof val === 'bigint',
|
||
|
function: (val) => typeof val === 'function',
|
||
|
boolean: (val) => typeof val === 'boolean',
|
||
|
string: (val) => typeof val === 'string',
|
||
|
stringOrUint8Array: (val) => typeof val === 'string' || val instanceof Uint8Array,
|
||
|
isSafeInteger: (val) => Number.isSafeInteger(val),
|
||
|
array: (val) => Array.isArray(val),
|
||
|
field: (val, object) => object.Fp.isValid(val),
|
||
|
hash: (val) => typeof val === 'function' && Number.isSafeInteger(val.outputLen),
|
||
|
};
|
||
|
function validateObject(object, validators, optValidators = {}) {
|
||
|
const checkField = (fieldName, type, isOptional) => {
|
||
|
const checkVal = validatorFns[type];
|
||
|
if (typeof checkVal !== 'function')
|
||
|
throw new Error(`Invalid validator "${type}", expected function`);
|
||
|
const val = object[fieldName];
|
||
|
if (isOptional && val === undefined)
|
||
|
return;
|
||
|
if (!checkVal(val, object)) {
|
||
|
throw new Error(`Invalid param ${String(fieldName)}=${val} (${typeof val}), expected ${type}`);
|
||
|
}
|
||
|
};
|
||
|
for (const [fieldName, type] of Object.entries(validators))
|
||
|
checkField(fieldName, type, false);
|
||
|
for (const [fieldName, type] of Object.entries(optValidators))
|
||
|
checkField(fieldName, type, true);
|
||
|
return object;
|
||
|
}
|
||
|
|
||
|
const ut = /*#__PURE__*/Object.freeze({
|
||
|
__proto__: null,
|
||
|
bitGet: bitGet,
|
||
|
bitLen: bitLen,
|
||
|
bitMask: bitMask,
|
||
|
bitSet: bitSet,
|
||
|
bytesToHex: bytesToHex,
|
||
|
bytesToNumberBE: bytesToNumberBE,
|
||
|
bytesToNumberLE: bytesToNumberLE,
|
||
|
concatBytes: concatBytes,
|
||
|
createHmacDrbg: createHmacDrbg,
|
||
|
ensureBytes: ensureBytes,
|
||
|
equalBytes: equalBytes,
|
||
|
hexToBytes: hexToBytes,
|
||
|
hexToNumber: hexToNumber,
|
||
|
numberToBytesBE: numberToBytesBE,
|
||
|
numberToBytesLE: numberToBytesLE,
|
||
|
numberToHexUnpadded: numberToHexUnpadded,
|
||
|
numberToVarBytesBE: numberToVarBytesBE,
|
||
|
utf8ToBytes: utf8ToBytes,
|
||
|
validateObject: validateObject
|
||
|
});
|
||
|
|
||
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||
|
const _0n$7 = BigInt(0), _1n$7 = BigInt(1), _2n$5 = BigInt(2), _3n$1 = BigInt(3);
|
||
|
const _4n$1 = BigInt(4), _5n$1 = BigInt(5), _8n$1 = BigInt(8);
|
||
|
BigInt(9); BigInt(16);
|
||
|
function mod(a, b) {
|
||
|
const result = a % b;
|
||
|
return result >= _0n$7 ? result : b + result;
|
||
|
}
|
||
|
function pow(num, power, modulo) {
|
||
|
if (modulo <= _0n$7 || power < _0n$7)
|
||
|
throw new Error('Expected power/modulo > 0');
|
||
|
if (modulo === _1n$7)
|
||
|
return _0n$7;
|
||
|
let res = _1n$7;
|
||
|
while (power > _0n$7) {
|
||
|
if (power & _1n$7)
|
||
|
res = (res * num) % modulo;
|
||
|
num = (num * num) % modulo;
|
||
|
power >>= _1n$7;
|
||
|
}
|
||
|
return res;
|
||
|
}
|
||
|
function pow2(x, power, modulo) {
|
||
|
let res = x;
|
||
|
while (power-- > _0n$7) {
|
||
|
res *= res;
|
||
|
res %= modulo;
|
||
|
}
|
||
|
return res;
|
||
|
}
|
||
|
function invert(number, modulo) {
|
||
|
if (number === _0n$7 || modulo <= _0n$7) {
|
||
|
throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`);
|
||
|
}
|
||
|
let a = mod(number, modulo);
|
||
|
let b = modulo;
|
||
|
let x = _0n$7, u = _1n$7;
|
||
|
while (a !== _0n$7) {
|
||
|
const q = b / a;
|
||
|
const r = b % a;
|
||
|
const m = x - u * q;
|
||
|
b = a, a = r, x = u, u = m;
|
||
|
}
|
||
|
const gcd = b;
|
||
|
if (gcd !== _1n$7)
|
||
|
throw new Error('invert: does not exist');
|
||
|
return mod(x, modulo);
|
||
|
}
|
||
|
function tonelliShanks(P) {
|
||
|
const legendreC = (P - _1n$7) / _2n$5;
|
||
|
let Q, S, Z;
|
||
|
for (Q = P - _1n$7, S = 0; Q % _2n$5 === _0n$7; Q /= _2n$5, S++)
|
||
|
;
|
||
|
for (Z = _2n$5; Z < P && pow(Z, legendreC, P) !== P - _1n$7; Z++)
|
||
|
;
|
||
|
if (S === 1) {
|
||
|
const p1div4 = (P + _1n$7) / _4n$1;
|
||
|
return function tonelliFast(Fp, n) {
|
||
|
const root = Fp.pow(n, p1div4);
|
||
|
if (!Fp.eql(Fp.sqr(root), n))
|
||
|
throw new Error('Cannot find square root');
|
||
|
return root;
|
||
|
};
|
||
|
}
|
||
|
const Q1div2 = (Q + _1n$7) / _2n$5;
|
||
|
return function tonelliSlow(Fp, n) {
|
||
|
if (Fp.pow(n, legendreC) === Fp.neg(Fp.ONE))
|
||
|
throw new Error('Cannot find square root');
|
||
|
let r = S;
|
||
|
let g = Fp.pow(Fp.mul(Fp.ONE, Z), Q);
|
||
|
let x = Fp.pow(n, Q1div2);
|
||
|
let b = Fp.pow(n, Q);
|
||
|
while (!Fp.eql(b, Fp.ONE)) {
|
||
|
if (Fp.eql(b, Fp.ZERO))
|
||
|
return Fp.ZERO;
|
||
|
let m = 1;
|
||
|
for (let t2 = Fp.sqr(b); m < r; m++) {
|
||
|
if (Fp.eql(t2, Fp.ONE))
|
||
|
break;
|
||
|
t2 = Fp.sqr(t2);
|
||
|
}
|
||
|
const ge = Fp.pow(g, _1n$7 << BigInt(r - m - 1));
|
||
|
g = Fp.sqr(ge);
|
||
|
x = Fp.mul(x, ge);
|
||
|
b = Fp.mul(b, g);
|
||
|
r = m;
|
||
|
}
|
||
|
return x;
|
||
|
};
|
||
|
}
|
||
|
function FpSqrt(P) {
|
||
|
if (P % _4n$1 === _3n$1) {
|
||
|
const p1div4 = (P + _1n$7) / _4n$1;
|
||
|
return function sqrt3mod4(Fp, n) {
|
||
|
const root = Fp.pow(n, p1div4);
|
||
|
if (!Fp.eql(Fp.sqr(root), n))
|
||
|
throw new Error('Cannot find square root');
|
||
|
return root;
|
||
|
};
|
||
|
}
|
||
|
if (P % _8n$1 === _5n$1) {
|
||
|
const c1 = (P - _5n$1) / _8n$1;
|
||
|
return function sqrt5mod8(Fp, n) {
|
||
|
const n2 = Fp.mul(n, _2n$5);
|
||
|
const v = Fp.pow(n2, c1);
|
||
|
const nv = Fp.mul(n, v);
|
||
|
const i = Fp.mul(Fp.mul(nv, _2n$5), v);
|
||
|
const root = Fp.mul(nv, Fp.sub(i, Fp.ONE));
|
||
|
if (!Fp.eql(Fp.sqr(root), n))
|
||
|
throw new Error('Cannot find square root');
|
||
|
return root;
|
||
|
};
|
||
|
}
|
||
|
return tonelliShanks(P);
|
||
|
}
|
||
|
const isNegativeLE = (num, modulo) => (mod(num, modulo) & _1n$7) === _1n$7;
|
||
|
const FIELD_FIELDS = [
|
||
|
'create', 'isValid', 'is0', 'neg', 'inv', 'sqrt', 'sqr',
|
||
|
'eql', 'add', 'sub', 'mul', 'pow', 'div',
|
||
|
'addN', 'subN', 'mulN', 'sqrN'
|
||
|
];
|
||
|
function validateField(field) {
|
||
|
const initial = {
|
||
|
ORDER: 'bigint',
|
||
|
MASK: 'bigint',
|
||
|
BYTES: 'isSafeInteger',
|
||
|
BITS: 'isSafeInteger',
|
||
|
};
|
||
|
const opts = FIELD_FIELDS.reduce((map, val) => {
|
||
|
map[val] = 'function';
|
||
|
return map;
|
||
|
}, initial);
|
||
|
return validateObject(field, opts);
|
||
|
}
|
||
|
function FpPow(f, num, power) {
|
||
|
if (power < _0n$7)
|
||
|
throw new Error('Expected power > 0');
|
||
|
if (power === _0n$7)
|
||
|
return f.ONE;
|
||
|
if (power === _1n$7)
|
||
|
return num;
|
||
|
let p = f.ONE;
|
||
|
let d = num;
|
||
|
while (power > _0n$7) {
|
||
|
if (power & _1n$7)
|
||
|
p = f.mul(p, d);
|
||
|
d = f.sqr(d);
|
||
|
power >>= _1n$7;
|
||
|
}
|
||
|
return p;
|
||
|
}
|
||
|
function FpInvertBatch(f, nums) {
|
||
|
const tmp = new Array(nums.length);
|
||
|
const lastMultiplied = nums.reduce((acc, num, i) => {
|
||
|
if (f.is0(num))
|
||
|
return acc;
|
||
|
tmp[i] = acc;
|
||
|
return f.mul(acc, num);
|
||
|
}, f.ONE);
|
||
|
const inverted = f.inv(lastMultiplied);
|
||
|
nums.reduceRight((acc, num, i) => {
|
||
|
if (f.is0(num))
|
||
|
return acc;
|
||
|
tmp[i] = f.mul(acc, tmp[i]);
|
||
|
return f.mul(acc, num);
|
||
|
}, inverted);
|
||
|
return tmp;
|
||
|
}
|
||
|
function nLength(n, nBitLength) {
|
||
|
const _nBitLength = nBitLength !== undefined ? nBitLength : n.toString(2).length;
|
||
|
const nByteLength = Math.ceil(_nBitLength / 8);
|
||
|
return { nBitLength: _nBitLength, nByteLength };
|
||
|
}
|
||
|
function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
||
|
if (ORDER <= _0n$7)
|
||
|
throw new Error(`Expected Field ORDER > 0, got ${ORDER}`);
|
||
|
const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, bitLen);
|
||
|
if (BYTES > 2048)
|
||
|
throw new Error('Field lengths over 2048 bytes are not supported');
|
||
|
const sqrtP = FpSqrt(ORDER);
|
||
|
const f = Object.freeze({
|
||
|
ORDER,
|
||
|
BITS,
|
||
|
BYTES,
|
||
|
MASK: bitMask(BITS),
|
||
|
ZERO: _0n$7,
|
||
|
ONE: _1n$7,
|
||
|
create: (num) => mod(num, ORDER),
|
||
|
isValid: (num) => {
|
||
|
if (typeof num !== 'bigint')
|
||
|
throw new Error(`Invalid field element: expected bigint, got ${typeof num}`);
|
||
|
return _0n$7 <= num && num < ORDER;
|
||
|
},
|
||
|
is0: (num) => num === _0n$7,
|
||
|
isOdd: (num) => (num & _1n$7) === _1n$7,
|
||
|
neg: (num) => mod(-num, ORDER),
|
||
|
eql: (lhs, rhs) => lhs === rhs,
|
||
|
sqr: (num) => mod(num * num, ORDER),
|
||
|
add: (lhs, rhs) => mod(lhs + rhs, ORDER),
|
||
|
sub: (lhs, rhs) => mod(lhs - rhs, ORDER),
|
||
|
mul: (lhs, rhs) => mod(lhs * rhs, ORDER),
|
||
|
pow: (num, power) => FpPow(f, num, power),
|
||
|
div: (lhs, rhs) => mod(lhs * invert(rhs, ORDER), ORDER),
|
||
|
sqrN: (num) => num * num,
|
||
|
addN: (lhs, rhs) => lhs + rhs,
|
||
|
subN: (lhs, rhs) => lhs - rhs,
|
||
|
mulN: (lhs, rhs) => lhs * rhs,
|
||
|
inv: (num) => invert(num, ORDER),
|
||
|
sqrt: redef.sqrt || ((n) => sqrtP(f, n)),
|
||
|
invertBatch: (lst) => FpInvertBatch(f, lst),
|
||
|
cmov: (a, b, c) => (c ? b : a),
|
||
|
toBytes: (num) => (isLE ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES)),
|
||
|
fromBytes: (bytes) => {
|
||
|
if (bytes.length !== BYTES)
|
||
|
throw new Error(`Fp.fromBytes: expected ${BYTES}, got ${bytes.length}`);
|
||
|
return isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);
|
||
|
},
|
||
|
});
|
||
|
return Object.freeze(f);
|
||
|
}
|
||
|
function FpSqrtEven(Fp, elm) {
|
||
|
if (!Fp.isOdd)
|
||
|
throw new Error(`Field doesn't have isOdd`);
|
||
|
const root = Fp.sqrt(elm);
|
||
|
return Fp.isOdd(root) ? Fp.neg(root) : root;
|
||
|
}
|
||
|
function getFieldBytesLength(fieldOrder) {
|
||
|
if (typeof fieldOrder !== 'bigint')
|
||
|
throw new Error('field order must be bigint');
|
||
|
const bitLength = fieldOrder.toString(2).length;
|
||
|
return Math.ceil(bitLength / 8);
|
||
|
}
|
||
|
function getMinHashLength(fieldOrder) {
|
||
|
const length = getFieldBytesLength(fieldOrder);
|
||
|
return length + Math.ceil(length / 2);
|
||
|
}
|
||
|
function mapHashToField(key, fieldOrder, isLE = false) {
|
||
|
const len = key.length;
|
||
|
const fieldLen = getFieldBytesLength(fieldOrder);
|
||
|
const minLen = getMinHashLength(fieldOrder);
|
||
|
if (len < 16 || len < minLen || len > 1024)
|
||
|
throw new Error(`expected ${minLen}-1024 bytes of input, got ${len}`);
|
||
|
const num = isLE ? bytesToNumberBE(key) : bytesToNumberLE(key);
|
||
|
const reduced = mod(num, fieldOrder - _1n$7) + _1n$7;
|
||
|
return isLE ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen);
|
||
|
}
|
||
|
|
||
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||
|
const _0n$6 = BigInt(0);
|
||
|
const _1n$6 = BigInt(1);
|
||
|
function wNAF(c, bits) {
|
||
|
const constTimeNegate = (condition, item) => {
|
||
|
const neg = item.negate();
|
||
|
return condition ? neg : item;
|
||
|
};
|
||
|
const opts = (W) => {
|
||
|
const windows = Math.ceil(bits / W) + 1;
|
||
|
const windowSize = 2 ** (W - 1);
|
||
|
return { windows, windowSize };
|
||
|
};
|
||
|
return {
|
||
|
constTimeNegate,
|
||
|
unsafeLadder(elm, n) {
|
||
|
let p = c.ZERO;
|
||
|
let d = elm;
|
||
|
while (n > _0n$6) {
|
||
|
if (n & _1n$6)
|
||
|
p = p.add(d);
|
||
|
d = d.double();
|
||
|
n >>= _1n$6;
|
||
|
}
|
||
|
return p;
|
||
|
},
|
||
|
precomputeWindow(elm, W) {
|
||
|
const { windows, windowSize } = opts(W);
|
||
|
const points = [];
|
||
|
let p = elm;
|
||
|
let base = p;
|
||
|
for (let window = 0; window < windows; window++) {
|
||
|
base = p;
|
||
|
points.push(base);
|
||
|
for (let i = 1; i < windowSize; i++) {
|
||
|
base = base.add(p);
|
||
|
points.push(base);
|
||
|
}
|
||
|
p = base.double();
|
||
|
}
|
||
|
return points;
|
||
|
},
|
||
|
wNAF(W, precomputes, n) {
|
||
|
const { windows, windowSize } = opts(W);
|
||
|
let p = c.ZERO;
|
||
|
let f = c.BASE;
|
||
|
const mask = BigInt(2 ** W - 1);
|
||
|
const maxNumber = 2 ** W;
|
||
|
const shiftBy = BigInt(W);
|
||
|
for (let window = 0; window < windows; window++) {
|
||
|
const offset = window * windowSize;
|
||
|
let wbits = Number(n & mask);
|
||
|
n >>= shiftBy;
|
||
|
if (wbits > windowSize) {
|
||
|
wbits -= maxNumber;
|
||
|
n += _1n$6;
|
||
|
}
|
||
|
const offset1 = offset;
|
||
|
const offset2 = offset + Math.abs(wbits) - 1;
|
||
|
const cond1 = window % 2 !== 0;
|
||
|
const cond2 = wbits < 0;
|
||
|
if (wbits === 0) {
|
||
|
f = f.add(constTimeNegate(cond1, precomputes[offset1]));
|
||
|
}
|
||
|
else {
|
||
|
p = p.add(constTimeNegate(cond2, precomputes[offset2]));
|
||
|
}
|
||
|
}
|
||
|
return { p, f };
|
||
|
},
|
||
|
wNAFCached(P, precomputesMap, n, transform) {
|
||
|
const W = P._WINDOW_SIZE || 1;
|
||
|
let comp = precomputesMap.get(P);
|
||
|
if (!comp) {
|
||
|
comp = this.precomputeWindow(P, W);
|
||
|
if (W !== 1) {
|
||
|
precomputesMap.set(P, transform(comp));
|
||
|
}
|
||
|
}
|
||
|
return this.wNAF(W, comp, n);
|
||
|
},
|
||
|
};
|
||
|
}
|
||
|
function validateBasic(curve) {
|
||
|
validateField(curve.Fp);
|
||
|
validateObject(curve, {
|
||
|
n: 'bigint',
|
||
|
h: 'bigint',
|
||
|
Gx: 'field',
|
||
|
Gy: 'field',
|
||
|
}, {
|
||
|
nBitLength: 'isSafeInteger',
|
||
|
nByteLength: 'isSafeInteger',
|
||
|
});
|
||
|
return Object.freeze({
|
||
|
...nLength(curve.n, curve.nBitLength),
|
||
|
...curve,
|
||
|
...{ p: curve.Fp.ORDER },
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||
|
function validatePointOpts(curve) {
|
||
|
const opts = validateBasic(curve);
|
||
|
validateObject(opts, {
|
||
|
a: 'field',
|
||
|
b: 'field',
|
||
|
}, {
|
||
|
allowedPrivateKeyLengths: 'array',
|
||
|
wrapPrivateKey: 'boolean',
|
||
|
isTorsionFree: 'function',
|
||
|
clearCofactor: 'function',
|
||
|
allowInfinityPoint: 'boolean',
|
||
|
fromBytes: 'function',
|
||
|
toBytes: 'function',
|
||
|
});
|
||
|
const { endo, Fp, a } = opts;
|
||
|
if (endo) {
|
||
|
if (!Fp.eql(a, Fp.ZERO)) {
|
||
|
throw new Error('Endomorphism can only be defined for Koblitz curves that have a=0');
|
||
|
}
|
||
|
if (typeof endo !== 'object' ||
|
||
|
typeof endo.beta !== 'bigint' ||
|
||
|
typeof endo.splitScalar !== 'function') {
|
||
|
throw new Error('Expected endomorphism with beta: bigint and splitScalar: function');
|
||
|
}
|
||
|
}
|
||
|
return Object.freeze({ ...opts });
|
||
|
}
|
||
|
const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
|
||
|
const DER = {
|
||
|
Err: class DERErr extends Error {
|
||
|
constructor(m = '') {
|
||
|
super(m);
|
||
|
}
|
||
|
},
|
||
|
_parseInt(data) {
|
||
|
const { Err: E } = DER;
|
||
|
if (data.length < 2 || data[0] !== 0x02)
|
||
|
throw new E('Invalid signature integer tag');
|
||
|
const len = data[1];
|
||
|
const res = data.subarray(2, len + 2);
|
||
|
if (!len || res.length !== len)
|
||
|
throw new E('Invalid signature integer: wrong length');
|
||
|
if (res[0] & 0b10000000)
|
||
|
throw new E('Invalid signature integer: negative');
|
||
|
if (res[0] === 0x00 && !(res[1] & 0b10000000))
|
||
|
throw new E('Invalid signature integer: unnecessary leading zero');
|
||
|
return { d: b2n(res), l: data.subarray(len + 2) };
|
||
|
},
|
||
|
toSig(hex) {
|
||
|
const { Err: E } = DER;
|
||
|
const data = typeof hex === 'string' ? h2b(hex) : hex;
|
||
|
if (!(data instanceof Uint8Array))
|
||
|
throw new Error('ui8a expected');
|
||
|
let l = data.length;
|
||
|
if (l < 2 || data[0] != 0x30)
|
||
|
throw new E('Invalid signature tag');
|
||
|
if (data[1] !== l - 2)
|
||
|
throw new E('Invalid signature: incorrect length');
|
||
|
const { d: r, l: sBytes } = DER._parseInt(data.subarray(2));
|
||
|
const { d: s, l: rBytesLeft } = DER._parseInt(sBytes);
|
||
|
if (rBytesLeft.length)
|
||
|
throw new E('Invalid signature: left bytes after parsing');
|
||
|
return { r, s };
|
||
|
},
|
||
|
hexFromSig(sig) {
|
||
|
const slice = (s) => (Number.parseInt(s[0], 16) & 0b1000 ? '00' + s : s);
|
||
|
const h = (num) => {
|
||
|
const hex = num.toString(16);
|
||
|
return hex.length & 1 ? `0${hex}` : hex;
|
||
|
};
|
||
|
const s = slice(h(sig.s));
|
||
|
const r = slice(h(sig.r));
|
||
|
const shl = s.length / 2;
|
||
|
const rhl = r.length / 2;
|
||
|
const sl = h(shl);
|
||
|
const rl = h(rhl);
|
||
|
return `30${h(rhl + shl + 4)}02${rl}${r}02${sl}${s}`;
|
||
|
},
|
||
|
};
|
||
|
const _0n$5 = BigInt(0), _1n$5 = BigInt(1), _2n$4 = BigInt(2), _3n = BigInt(3), _4n = BigInt(4);
|
||
|
function weierstrassPoints(opts) {
|
||
|
const CURVE = validatePointOpts(opts);
|
||
|
const { Fp } = CURVE;
|
||
|
const toBytes = CURVE.toBytes ||
|
||
|
((_c, point, _isCompressed) => {
|
||
|
const a = point.toAffine();
|
||
|
return concatBytes(Uint8Array.from([0x04]), Fp.toBytes(a.x), Fp.toBytes(a.y));
|
||
|
});
|
||
|
const fromBytes = CURVE.fromBytes ||
|
||
|
((bytes) => {
|
||
|
const tail = bytes.subarray(1);
|
||
|
const x = Fp.fromBytes(tail.subarray(0, Fp.BYTES));
|
||
|
const y = Fp.fromBytes(tail.subarray(Fp.BYTES, 2 * Fp.BYTES));
|
||
|
return { x, y };
|
||
|
});
|
||
|
function weierstrassEquation(x) {
|
||
|
const { a, b } = CURVE;
|
||
|
const x2 = Fp.sqr(x);
|
||
|
const x3 = Fp.mul(x2, x);
|
||
|
return Fp.add(Fp.add(x3, Fp.mul(x, a)), b);
|
||
|
}
|
||
|
if (!Fp.eql(Fp.sqr(CURVE.Gy), weierstrassEquation(CURVE.Gx)))
|
||
|
throw new Error('bad generator point: equation left != right');
|
||
|
function isWithinCurveOrder(num) {
|
||
|
return typeof num === 'bigint' && _0n$5 < num && num < CURVE.n;
|
||
|
}
|
||
|
function assertGE(num) {
|
||
|
if (!isWithinCurveOrder(num))
|
||
|
throw new Error('Expected valid bigint: 0 < bigint < curve.n');
|
||
|
}
|
||
|
function normPrivateKeyToScalar(key) {
|
||
|
const { allowedPrivateKeyLengths: lengths, nByteLength, wrapPrivateKey, n } = CURVE;
|
||
|
if (lengths && typeof key !== 'bigint') {
|
||
|
if (key instanceof Uint8Array)
|
||
|
key = bytesToHex(key);
|
||
|
if (typeof key !== 'string' || !lengths.includes(key.length))
|
||
|
throw new Error('Invalid key');
|
||
|
key = key.padStart(nByteLength * 2, '0');
|
||
|
}
|
||
|
let num;
|
||
|
try {
|
||
|
num =
|
||
|
typeof key === 'bigint'
|
||
|
? key
|
||
|
: bytesToNumberBE(ensureBytes('private key', key, nByteLength));
|
||
|
}
|
||
|
catch (error) {
|
||
|
throw new Error(`private key must be ${nByteLength} bytes, hex or bigint, not ${typeof key}`);
|
||
|
}
|
||
|
if (wrapPrivateKey)
|
||
|
num = mod(num, n);
|
||
|
assertGE(num);
|
||
|
return num;
|
||
|
}
|
||
|
const pointPrecomputes = new Map();
|
||
|
function assertPrjPoint(other) {
|
||
|
if (!(other instanceof Point))
|
||
|
throw new Error('ProjectivePoint expected');
|
||
|
}
|
||
|
class Point {
|
||
|
constructor(px, py, pz) {
|
||
|
this.px = px;
|
||
|
this.py = py;
|
||
|
this.pz = pz;
|
||
|
if (px == null || !Fp.isValid(px))
|
||
|
throw new Error('x required');
|
||
|
if (py == null || !Fp.isValid(py))
|
||
|
throw new Error('y required');
|
||
|
if (pz == null || !Fp.isValid(pz))
|
||
|
throw new Error('z required');
|
||
|
}
|
||
|
static fromAffine(p) {
|
||
|
const { x, y } = p || {};
|
||
|
if (!p || !Fp.isValid(x) || !Fp.isValid(y))
|
||
|
throw new Error('invalid affine point');
|
||
|
if (p instanceof Point)
|
||
|
throw new Error('projective point not allowed');
|
||
|
const is0 = (i) => Fp.eql(i, Fp.ZERO);
|
||
|
if (is0(x) && is0(y))
|
||
|
return Point.ZERO;
|
||
|
return new Point(x, y, Fp.ONE);
|
||
|
}
|
||
|
get x() {
|
||
|
return this.toAffine().x;
|
||
|
}
|
||
|
get y() {
|
||
|
return this.toAffine().y;
|
||
|
}
|
||
|
static normalizeZ(points) {
|
||
|
const toInv = Fp.invertBatch(points.map((p) => p.pz));
|
||
|
return points.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
|
||
|
}
|
||
|
static fromHex(hex) {
|
||
|
const P = Point.fromAffine(fromBytes(ensureBytes('pointHex', hex)));
|
||
|
P.assertValidity();
|
||
|
return P;
|
||
|
}
|
||
|
static fromPrivateKey(privateKey) {
|
||
|
return Point.BASE.multiply(normPrivateKeyToScalar(privateKey));
|
||
|
}
|
||
|
_setWindowSize(windowSize) {
|
||
|
this._WINDOW_SIZE = windowSize;
|
||
|
pointPrecomputes.delete(this);
|
||
|
}
|
||
|
assertValidity() {
|
||
|
if (this.is0()) {
|
||
|
if (CURVE.allowInfinityPoint && !Fp.is0(this.py))
|
||
|
return;
|
||
|
throw new Error('bad point: ZERO');
|
||
|
}
|
||
|
const { x, y } = this.toAffine();
|
||
|
if (!Fp.isValid(x) || !Fp.isValid(y))
|
||
|
throw new Error('bad point: x or y not FE');
|
||
|
const left = Fp.sqr(y);
|
||
|
const right = weierstrassEquation(x);
|
||
|
if (!Fp.eql(left, right))
|
||
|
throw new Error('bad point: equation left != right');
|
||
|
if (!this.isTorsionFree())
|
||
|
throw new Error('bad point: not in prime-order subgroup');
|
||
|
}
|
||
|
hasEvenY() {
|
||
|
const { y } = this.toAffine();
|
||
|
if (Fp.isOdd)
|
||
|
return !Fp.isOdd(y);
|
||
|
throw new Error("Field doesn't support isOdd");
|
||
|
}
|
||
|
equals(other) {
|
||
|
assertPrjPoint(other);
|
||
|
const { px: X1, py: Y1, pz: Z1 } = this;
|
||
|
const { px: X2, py: Y2, pz: Z2 } = other;
|
||
|
const U1 = Fp.eql(Fp.mul(X1, Z2), Fp.mul(X2, Z1));
|
||
|
const U2 = Fp.eql(Fp.mul(Y1, Z2), Fp.mul(Y2, Z1));
|
||
|
return U1 && U2;
|
||
|
}
|
||
|
negate() {
|
||
|
return new Point(this.px, Fp.neg(this.py), this.pz);
|
||
|
}
|
||
|
double() {
|
||
|
const { a, b } = CURVE;
|
||
|
const b3 = Fp.mul(b, _3n);
|
||
|
const { px: X1, py: Y1, pz: Z1 } = this;
|
||
|
let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO;
|
||
|
let t0 = Fp.mul(X1, X1);
|
||
|
let t1 = Fp.mul(Y1, Y1);
|
||
|
let t2 = Fp.mul(Z1, Z1);
|
||
|
let t3 = Fp.mul(X1, Y1);
|
||
|
t3 = Fp.add(t3, t3);
|
||
|
Z3 = Fp.mul(X1, Z1);
|
||
|
Z3 = Fp.add(Z3, Z3);
|
||
|
X3 = Fp.mul(a, Z3);
|
||
|
Y3 = Fp.mul(b3, t2);
|
||
|
Y3 = Fp.add(X3, Y3);
|
||
|
X3 = Fp.sub(t1, Y3);
|
||
|
Y3 = Fp.add(t1, Y3);
|
||
|
Y3 = Fp.mul(X3, Y3);
|
||
|
X3 = Fp.mul(t3, X3);
|
||
|
Z3 = Fp.mul(b3, Z3);
|
||
|
t2 = Fp.mul(a, t2);
|
||
|
t3 = Fp.sub(t0, t2);
|
||
|
t3 = Fp.mul(a, t3);
|
||
|
t3 = Fp.add(t3, Z3);
|
||
|
Z3 = Fp.add(t0, t0);
|
||
|
t0 = Fp.add(Z3, t0);
|
||
|
t0 = Fp.add(t0, t2);
|
||
|
t0 = Fp.mul(t0, t3);
|
||
|
Y3 = Fp.add(Y3, t0);
|
||
|
t2 = Fp.mul(Y1, Z1);
|
||
|
t2 = Fp.add(t2, t2);
|
||
|
t0 = Fp.mul(t2, t3);
|
||
|
X3 = Fp.sub(X3, t0);
|
||
|
Z3 = Fp.mul(t2, t1);
|
||
|
Z3 = Fp.add(Z3, Z3);
|
||
|
Z3 = Fp.add(Z3, Z3);
|
||
|
return new Point(X3, Y3, Z3);
|
||
|
}
|
||
|
add(other) {
|
||
|
assertPrjPoint(other);
|
||
|
const { px: X1, py: Y1, pz: Z1 } = this;
|
||
|
const { px: X2, py: Y2, pz: Z2 } = other;
|
||
|
let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO;
|
||
|
const a = CURVE.a;
|
||
|
const b3 = Fp.mul(CURVE.b, _3n);
|
||
|
let t0 = Fp.mul(X1, X2);
|
||
|
let t1 = Fp.mul(Y1, Y2);
|
||
|
let t2 = Fp.mul(Z1, Z2);
|
||
|
let t3 = Fp.add(X1, Y1);
|
||
|
let t4 = Fp.add(X2, Y2);
|
||
|
t3 = Fp.mul(t3, t4);
|
||
|
t4 = Fp.add(t0, t1);
|
||
|
t3 = Fp.sub(t3, t4);
|
||
|
t4 = Fp.add(X1, Z1);
|
||
|
let t5 = Fp.add(X2, Z2);
|
||
|
t4 = Fp.mul(t4, t5);
|
||
|
t5 = Fp.add(t0, t2);
|
||
|
t4 = Fp.sub(t4, t5);
|
||
|
t5 = Fp.add(Y1, Z1);
|
||
|
X3 = Fp.add(Y2, Z2);
|
||
|
t5 = Fp.mul(t5, X3);
|
||
|
X3 = Fp.add(t1, t2);
|
||
|
t5 = Fp.sub(t5, X3);
|
||
|
Z3 = Fp.mul(a, t4);
|
||
|
X3 = Fp.mul(b3, t2);
|
||
|
Z3 = Fp.add(X3, Z3);
|
||
|
X3 = Fp.sub(t1, Z3);
|
||
|
Z3 = Fp.add(t1, Z3);
|
||
|
Y3 = Fp.mul(X3, Z3);
|
||
|
t1 = Fp.add(t0, t0);
|
||
|
t1 = Fp.add(t1, t0);
|
||
|
t2 = Fp.mul(a, t2);
|
||
|
t4 = Fp.mul(b3, t4);
|
||
|
t1 = Fp.add(t1, t2);
|
||
|
t2 = Fp.sub(t0, t2);
|
||
|
t2 = Fp.mul(a, t2);
|
||
|
t4 = Fp.add(t4, t2);
|
||
|
t0 = Fp.mul(t1, t4);
|
||
|
Y3 = Fp.add(Y3, t0);
|
||
|
t0 = Fp.mul(t5, t4);
|
||
|
X3 = Fp.mul(t3, X3);
|
||
|
X3 = Fp.sub(X3, t0);
|
||
|
t0 = Fp.mul(t3, t1);
|
||
|
Z3 = Fp.mul(t5, Z3);
|
||
|
Z3 = Fp.add(Z3, t0);
|
||
|
return new Point(X3, Y3, Z3);
|
||
|
}
|
||
|
subtract(other) {
|
||
|
return this.add(other.negate());
|
||
|
}
|
||
|
is0() {
|
||
|
return this.equals(Point.ZERO);
|
||
|
}
|
||
|
wNAF(n) {
|
||
|
return wnaf.wNAFCached(this, pointPrecomputes, n, (comp) => {
|
||
|
const toInv = Fp.invertBatch(comp.map((p) => p.pz));
|
||
|
return comp.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
|
||
|
});
|
||
|
}
|
||
|
multiplyUnsafe(n) {
|
||
|
const I = Point.ZERO;
|
||
|
if (n === _0n$5)
|
||
|
return I;
|
||
|
assertGE(n);
|
||
|
if (n === _1n$5)
|
||
|
return this;
|
||
|
const { endo } = CURVE;
|
||
|
if (!endo)
|
||
|
return wnaf.unsafeLadder(this, n);
|
||
|
let { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
|
||
|
let k1p = I;
|
||
|
let k2p = I;
|
||
|
let d = this;
|
||
|
while (k1 > _0n$5 || k2 > _0n$5) {
|
||
|
if (k1 & _1n$5)
|
||
|
k1p = k1p.add(d);
|
||
|
if (k2 & _1n$5)
|
||
|
k2p = k2p.add(d);
|
||
|
d = d.double();
|
||
|
k1 >>= _1n$5;
|
||
|
k2 >>= _1n$5;
|
||
|
}
|
||
|
if (k1neg)
|
||
|
k1p = k1p.negate();
|
||
|
if (k2neg)
|
||
|
k2p = k2p.negate();
|
||
|
k2p = new Point(Fp.mul(k2p.px, endo.beta), k2p.py, k2p.pz);
|
||
|
return k1p.add(k2p);
|
||
|
}
|
||
|
multiply(scalar) {
|
||
|
assertGE(scalar);
|
||
|
let n = scalar;
|
||
|
let point, fake;
|
||
|
const { endo } = CURVE;
|
||
|
if (endo) {
|
||
|
const { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
|
||
|
let { p: k1p, f: f1p } = this.wNAF(k1);
|
||
|
let { p: k2p, f: f2p } = this.wNAF(k2);
|
||
|
k1p = wnaf.constTimeNegate(k1neg, k1p);
|
||
|
k2p = wnaf.constTimeNegate(k2neg, k2p);
|
||
|
k2p = new Point(Fp.mul(k2p.px, endo.beta), k2p.py, k2p.pz);
|
||
|
point = k1p.add(k2p);
|
||
|
fake = f1p.add(f2p);
|
||
|
}
|
||
|
else {
|
||
|
const { p, f } = this.wNAF(n);
|
||
|
point = p;
|
||
|
fake = f;
|
||
|
}
|
||
|
return Point.normalizeZ([point, fake])[0];
|
||
|
}
|
||
|
multiplyAndAddUnsafe(Q, a, b) {
|
||
|
const G = Point.BASE;
|
||
|
const mul = (P, a
|
||
|
) => (a === _0n$5 || a === _1n$5 || !P.equals(G) ? P.multiplyUnsafe(a) : P.multiply(a));
|
||
|
const sum = mul(this, a).add(mul(Q, b));
|
||
|
return sum.is0() ? undefined : sum;
|
||
|
}
|
||
|
toAffine(iz) {
|
||
|
const { px: x, py: y, pz: z } = this;
|
||
|
const is0 = this.is0();
|
||
|
if (iz == null)
|
||
|
iz = is0 ? Fp.ONE : Fp.inv(z);
|
||
|
const ax = Fp.mul(x, iz);
|
||
|
const ay = Fp.mul(y, iz);
|
||
|
const zz = Fp.mul(z, iz);
|
||
|
if (is0)
|
||
|
return { x: Fp.ZERO, y: Fp.ZERO };
|
||
|
if (!Fp.eql(zz, Fp.ONE))
|
||
|
throw new Error('invZ was invalid');
|
||
|
return { x: ax, y: ay };
|
||
|
}
|
||
|
isTorsionFree() {
|
||
|
const { h: cofactor, isTorsionFree } = CURVE;
|
||
|
if (cofactor === _1n$5)
|
||
|
return true;
|
||
|
if (isTorsionFree)
|
||
|
return isTorsionFree(Point, this);
|
||
|
throw new Error('isTorsionFree() has not been declared for the elliptic curve');
|
||
|
}
|
||
|
clearCofactor() {
|
||
|
const { h: cofactor, clearCofactor } = CURVE;
|
||
|
if (cofactor === _1n$5)
|
||
|
return this;
|
||
|
if (clearCofactor)
|
||
|
return clearCofactor(Point, this);
|
||
|
return this.multiplyUnsafe(CURVE.h);
|
||
|
}
|
||
|
toRawBytes(isCompressed = true) {
|
||
|
this.assertValidity();
|
||
|
return toBytes(Point, this, isCompressed);
|
||
|
}
|
||
|
toHex(isCompressed = true) {
|
||
|
return bytesToHex(this.toRawBytes(isCompressed));
|
||
|
}
|
||
|
}
|
||
|
Point.BASE = new Point(CURVE.Gx, CURVE.Gy, Fp.ONE);
|
||
|
Point.ZERO = new Point(Fp.ZERO, Fp.ONE, Fp.ZERO);
|
||
|
const _bits = CURVE.nBitLength;
|
||
|
const wnaf = wNAF(Point, CURVE.endo ? Math.ceil(_bits / 2) : _bits);
|
||
|
return {
|
||
|
CURVE,
|
||
|
ProjectivePoint: Point,
|
||
|
normPrivateKeyToScalar,
|
||
|
weierstrassEquation,
|
||
|
isWithinCurveOrder,
|
||
|
};
|
||
|
}
|
||
|
function validateOpts$2(curve) {
|
||
|
const opts = validateBasic(curve);
|
||
|
validateObject(opts, {
|
||
|
hash: 'hash',
|
||
|
hmac: 'function',
|
||
|
randomBytes: 'function',
|
||
|
}, {
|
||
|
bits2int: 'function',
|
||
|
bits2int_modN: 'function',
|
||
|
lowS: 'boolean',
|
||
|
});
|
||
|
return Object.freeze({ lowS: true, ...opts });
|
||
|
}
|
||
|
function weierstrass(curveDef) {
|
||
|
const CURVE = validateOpts$2(curveDef);
|
||
|
const { Fp, n: CURVE_ORDER } = CURVE;
|
||
|
const compressedLen = Fp.BYTES + 1;
|
||
|
const uncompressedLen = 2 * Fp.BYTES + 1;
|
||
|
function isValidFieldElement(num) {
|
||
|
return _0n$5 < num && num < Fp.ORDER;
|
||
|
}
|
||
|
function modN(a) {
|
||
|
return mod(a, CURVE_ORDER);
|
||
|
}
|
||
|
function invN(a) {
|
||
|
return invert(a, CURVE_ORDER);
|
||
|
}
|
||
|
const { ProjectivePoint: Point, normPrivateKeyToScalar, weierstrassEquation, isWithinCurveOrder, } = weierstrassPoints({
|
||
|
...CURVE,
|
||
|
toBytes(_c, point, isCompressed) {
|
||
|
const a = point.toAffine();
|
||
|
const x = Fp.toBytes(a.x);
|
||
|
const cat = concatBytes;
|
||
|
if (isCompressed) {
|
||
|
return cat(Uint8Array.from([point.hasEvenY() ? 0x02 : 0x03]), x);
|
||
|
}
|
||
|
else {
|
||
|
return cat(Uint8Array.from([0x04]), x, Fp.toBytes(a.y));
|
||
|
}
|
||
|
},
|
||
|
fromBytes(bytes) {
|
||
|
const len = bytes.length;
|
||
|
const head = bytes[0];
|
||
|
const tail = bytes.subarray(1);
|
||
|
if (len === compressedLen && (head === 0x02 || head === 0x03)) {
|
||
|
const x = bytesToNumberBE(tail);
|
||
|
if (!isValidFieldElement(x))
|
||
|
throw new Error('Point is not on curve');
|
||
|
const y2 = weierstrassEquation(x);
|
||
|
let y = Fp.sqrt(y2);
|
||
|
const isYOdd = (y & _1n$5) === _1n$5;
|
||
|
const isHeadOdd = (head & 1) === 1;
|
||
|
if (isHeadOdd !== isYOdd)
|
||
|
y = Fp.neg(y);
|
||
|
return { x, y };
|
||
|
}
|
||
|
else if (len === uncompressedLen && head === 0x04) {
|
||
|
const x = Fp.fromBytes(tail.subarray(0, Fp.BYTES));
|
||
|
const y = Fp.fromBytes(tail.subarray(Fp.BYTES, 2 * Fp.BYTES));
|
||
|
return { x, y };
|
||
|
}
|
||
|
else {
|
||
|
throw new Error(`Point of length ${len} was invalid. Expected ${compressedLen} compressed bytes or ${uncompressedLen} uncompressed bytes`);
|
||
|
}
|
||
|
},
|
||
|
});
|
||
|
const numToNByteStr = (num) => bytesToHex(numberToBytesBE(num, CURVE.nByteLength));
|
||
|
function isBiggerThanHalfOrder(number) {
|
||
|
const HALF = CURVE_ORDER >> _1n$5;
|
||
|
return number > HALF;
|
||
|
}
|
||
|
function normalizeS(s) {
|
||
|
return isBiggerThanHalfOrder(s) ? modN(-s) : s;
|
||
|
}
|
||
|
const slcNum = (b, from, to) => bytesToNumberBE(b.slice(from, to));
|
||
|
class Signature {
|
||
|
constructor(r, s, recovery) {
|
||
|
this.r = r;
|
||
|
this.s = s;
|
||
|
this.recovery = recovery;
|
||
|
this.assertValidity();
|
||
|
}
|
||
|
static fromCompact(hex) {
|
||
|
const l = CURVE.nByteLength;
|
||
|
hex = ensureBytes('compactSignature', hex, l * 2);
|
||
|
return new Signature(slcNum(hex, 0, l), slcNum(hex, l, 2 * l));
|
||
|
}
|
||
|
static fromDER(hex) {
|
||
|
const { r, s } = DER.toSig(ensureBytes('DER', hex));
|
||
|
return new Signature(r, s);
|
||
|
}
|
||
|
assertValidity() {
|
||
|
if (!isWithinCurveOrder(this.r))
|
||
|
throw new Error('r must be 0 < r < CURVE.n');
|
||
|
if (!isWithinCurveOrder(this.s))
|
||
|
throw new Error('s must be 0 < s < CURVE.n');
|
||
|
}
|
||
|
addRecoveryBit(recovery) {
|
||
|
return new Signature(this.r, this.s, recovery);
|
||
|
}
|
||
|
recoverPublicKey(msgHash) {
|
||
|
const { r, s, recovery: rec } = this;
|
||
|
const h = bits2int_modN(ensureBytes('msgHash', msgHash));
|
||
|
if (rec == null || ![0, 1, 2, 3].includes(rec))
|
||
|
throw new Error('recovery id invalid');
|
||
|
const radj = rec === 2 || rec === 3 ? r + CURVE.n : r;
|
||
|
if (radj >= Fp.ORDER)
|
||
|
throw new Error('recovery id 2 or 3 invalid');
|
||
|
const prefix = (rec & 1) === 0 ? '02' : '03';
|
||
|
const R = Point.fromHex(prefix + numToNByteStr(radj));
|
||
|
const ir = invN(radj);
|
||
|
const u1 = modN(-h * ir);
|
||
|
const u2 = modN(s * ir);
|
||
|
const Q = Point.BASE.multiplyAndAddUnsafe(R, u1, u2);
|
||
|
if (!Q)
|
||
|
throw new Error('point at infinify');
|
||
|
Q.assertValidity();
|
||
|
return Q;
|
||
|
}
|
||
|
hasHighS() {
|
||
|
return isBiggerThanHalfOrder(this.s);
|
||
|
}
|
||
|
normalizeS() {
|
||
|
return this.hasHighS() ? new Signature(this.r, modN(-this.s), this.recovery) : this;
|
||
|
}
|
||
|
toDERRawBytes() {
|
||
|
return hexToBytes(this.toDERHex());
|
||
|
}
|
||
|
toDERHex() {
|
||
|
return DER.hexFromSig({ r: this.r, s: this.s });
|
||
|
}
|
||
|
toCompactRawBytes() {
|
||
|
return hexToBytes(this.toCompactHex());
|
||
|
}
|
||
|
toCompactHex() {
|
||
|
return numToNByteStr(this.r) + numToNByteStr(this.s);
|
||
|
}
|
||
|
}
|
||
|
const utils = {
|
||
|
isValidPrivateKey(privateKey) {
|
||
|
try {
|
||
|
normPrivateKeyToScalar(privateKey);
|
||
|
return true;
|
||
|
}
|
||
|
catch (error) {
|
||
|
return false;
|
||
|
}
|
||
|
},
|
||
|
normPrivateKeyToScalar: normPrivateKeyToScalar,
|
||
|
randomPrivateKey: () => {
|
||
|
const length = getMinHashLength(CURVE.n);
|
||
|
return mapHashToField(CURVE.randomBytes(length), CURVE.n);
|
||
|
},
|
||
|
precompute(windowSize = 8, point = Point.BASE) {
|
||
|
point._setWindowSize(windowSize);
|
||
|
point.multiply(BigInt(3));
|
||
|
return point;
|
||
|
},
|
||
|
};
|
||
|
function getPublicKey(privateKey, isCompressed = true) {
|
||
|
return Point.fromPrivateKey(privateKey).toRawBytes(isCompressed);
|
||
|
}
|
||
|
function isProbPub(item) {
|
||
|
const arr = item instanceof Uint8Array;
|
||
|
const str = typeof item === 'string';
|
||
|
const len = (arr || str) && item.length;
|
||
|
if (arr)
|
||
|
return len === compressedLen || len === uncompressedLen;
|
||
|
if (str)
|
||
|
return len === 2 * compressedLen || len === 2 * uncompressedLen;
|
||
|
if (item instanceof Point)
|
||
|
return true;
|
||
|
return false;
|
||
|
}
|
||
|
function getSharedSecret(privateA, publicB, isCompressed = true) {
|
||
|
if (isProbPub(privateA))
|
||
|
throw new Error('first arg must be private key');
|
||
|
if (!isProbPub(publicB))
|
||
|
throw new Error('second arg must be public key');
|
||
|
const b = Point.fromHex(publicB);
|
||
|
return b.multiply(normPrivateKeyToScalar(privateA)).toRawBytes(isCompressed);
|
||
|
}
|
||
|
const bits2int = CURVE.bits2int ||
|
||
|
function (bytes) {
|
||
|
const num = bytesToNumberBE(bytes);
|
||
|
const delta = bytes.length * 8 - CURVE.nBitLength;
|
||
|
return delta > 0 ? num >> BigInt(delta) : num;
|
||
|
};
|
||
|
const bits2int_modN = CURVE.bits2int_modN ||
|
||
|
function (bytes) {
|
||
|
return modN(bits2int(bytes));
|
||
|
};
|
||
|
const ORDER_MASK = bitMask(CURVE.nBitLength);
|
||
|
function int2octets(num) {
|
||
|
if (typeof num !== 'bigint')
|
||
|
throw new Error('bigint expected');
|
||
|
if (!(_0n$5 <= num && num < ORDER_MASK))
|
||
|
throw new Error(`bigint expected < 2^${CURVE.nBitLength}`);
|
||
|
return numberToBytesBE(num, CURVE.nByteLength);
|
||
|
}
|
||
|
function prepSig(msgHash, privateKey, opts = defaultSigOpts) {
|
||
|
if (['recovered', 'canonical'].some((k) => k in opts))
|
||
|
throw new Error('sign() legacy options not supported');
|
||
|
const { hash, randomBytes } = CURVE;
|
||
|
let { lowS, prehash, extraEntropy: ent } = opts;
|
||
|
if (lowS == null)
|
||
|
lowS = true;
|
||
|
msgHash = ensureBytes('msgHash', msgHash);
|
||
|
if (prehash)
|
||
|
msgHash = ensureBytes('prehashed msgHash', hash(msgHash));
|
||
|
const h1int = bits2int_modN(msgHash);
|
||
|
const d = normPrivateKeyToScalar(privateKey);
|
||
|
const seedArgs = [int2octets(d), int2octets(h1int)];
|
||
|
if (ent != null) {
|
||
|
const e = ent === true ? randomBytes(Fp.BYTES) : ent;
|
||
|
seedArgs.push(ensureBytes('extraEntropy', e));
|
||
|
}
|
||
|
const seed = concatBytes(...seedArgs);
|
||
|
const m = h1int;
|
||
|
function k2sig(kBytes) {
|
||
|
const k = bits2int(kBytes);
|
||
|
if (!isWithinCurveOrder(k))
|
||
|
return;
|
||
|
const ik = invN(k);
|
||
|
const q = Point.BASE.multiply(k).toAffine();
|
||
|
const r = modN(q.x);
|
||
|
if (r === _0n$5)
|
||
|
return;
|
||
|
const s = modN(ik * modN(m + r * d));
|
||
|
if (s === _0n$5)
|
||
|
return;
|
||
|
let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n$5);
|
||
|
let normS = s;
|
||
|
if (lowS && isBiggerThanHalfOrder(s)) {
|
||
|
normS = normalizeS(s);
|
||
|
recovery ^= 1;
|
||
|
}
|
||
|
return new Signature(r, normS, recovery);
|
||
|
}
|
||
|
return { seed, k2sig };
|
||
|
}
|
||
|
const defaultSigOpts = { lowS: CURVE.lowS, prehash: false };
|
||
|
const defaultVerOpts = { lowS: CURVE.lowS, prehash: false };
|
||
|
function sign(msgHash, privKey, opts = defaultSigOpts) {
|
||
|
const { seed, k2sig } = prepSig(msgHash, privKey, opts);
|
||
|
const C = CURVE;
|
||
|
const drbg = createHmacDrbg(C.hash.outputLen, C.nByteLength, C.hmac);
|
||
|
return drbg(seed, k2sig);
|
||
|
}
|
||
|
Point.BASE._setWindowSize(8);
|
||
|
function verify(signature, msgHash, publicKey, opts = defaultVerOpts) {
|
||
|
const sg = signature;
|
||
|
msgHash = ensureBytes('msgHash', msgHash);
|
||
|
publicKey = ensureBytes('publicKey', publicKey);
|
||
|
if ('strict' in opts)
|
||
|
throw new Error('options.strict was renamed to lowS');
|
||
|
const { lowS, prehash } = opts;
|
||
|
let _sig = undefined;
|
||
|
let P;
|
||
|
try {
|
||
|
if (typeof sg === 'string' || sg instanceof Uint8Array) {
|
||
|
try {
|
||
|
_sig = Signature.fromDER(sg);
|
||
|
}
|
||
|
catch (derError) {
|
||
|
if (!(derError instanceof DER.Err))
|
||
|
throw derError;
|
||
|
_sig = Signature.fromCompact(sg);
|
||
|
}
|
||
|
}
|
||
|
else if (typeof sg === 'object' && typeof sg.r === 'bigint' && typeof sg.s === 'bigint') {
|
||
|
const { r, s } = sg;
|
||
|
_sig = new Signature(r, s);
|
||
|
}
|
||
|
else {
|
||
|
throw new Error('PARSE');
|
||
|
}
|
||
|
P = Point.fromHex(publicKey);
|
||
|
}
|
||
|
catch (error) {
|
||
|
if (error.message === 'PARSE')
|
||
|
throw new Error(`signature must be Signature instance, Uint8Array or hex string`);
|
||
|
return false;
|
||
|
}
|
||
|
if (lowS && _sig.hasHighS())
|
||
|
return false;
|
||
|
if (prehash)
|
||
|
msgHash = CURVE.hash(msgHash);
|
||
|
const { r, s } = _sig;
|
||
|
const h = bits2int_modN(msgHash);
|
||
|
const is = invN(s);
|
||
|
const u1 = modN(h * is);
|
||
|
const u2 = modN(r * is);
|
||
|
const R = Point.BASE.multiplyAndAddUnsafe(P, u1, u2)?.toAffine();
|
||
|
if (!R)
|
||
|
return false;
|
||
|
const v = modN(R.x);
|
||
|
return v === r;
|
||
|
}
|
||
|
return {
|
||
|
CURVE,
|
||
|
getPublicKey,
|
||
|
getSharedSecret,
|
||
|
sign,
|
||
|
verify,
|
||
|
ProjectivePoint: Point,
|
||
|
Signature,
|
||
|
utils,
|
||
|
};
|
||
|
}
|
||
|
function SWUFpSqrtRatio(Fp, Z) {
|
||
|
const q = Fp.ORDER;
|
||
|
let l = _0n$5;
|
||
|
for (let o = q - _1n$5; o % _2n$4 === _0n$5; o /= _2n$4)
|
||
|
l += _1n$5;
|
||
|
const c1 = l;
|
||
|
const _2n_pow_c1_1 = _2n$4 << (c1 - _1n$5 - _1n$5);
|
||
|
const _2n_pow_c1 = _2n_pow_c1_1 * _2n$4;
|
||
|
const c2 = (q - _1n$5) / _2n_pow_c1;
|
||
|
const c3 = (c2 - _1n$5) / _2n$4;
|
||
|
const c4 = _2n_pow_c1 - _1n$5;
|
||
|
const c5 = _2n_pow_c1_1;
|
||
|
const c6 = Fp.pow(Z, c2);
|
||
|
const c7 = Fp.pow(Z, (c2 + _1n$5) / _2n$4);
|
||
|
let sqrtRatio = (u, v) => {
|
||
|
let tv1 = c6;
|
||
|
let tv2 = Fp.pow(v, c4);
|
||
|
let tv3 = Fp.sqr(tv2);
|
||
|
tv3 = Fp.mul(tv3, v);
|
||
|
let tv5 = Fp.mul(u, tv3);
|
||
|
tv5 = Fp.pow(tv5, c3);
|
||
|
tv5 = Fp.mul(tv5, tv2);
|
||
|
tv2 = Fp.mul(tv5, v);
|
||
|
tv3 = Fp.mul(tv5, u);
|
||
|
let tv4 = Fp.mul(tv3, tv2);
|
||
|
tv5 = Fp.pow(tv4, c5);
|
||
|
let isQR = Fp.eql(tv5, Fp.ONE);
|
||
|
tv2 = Fp.mul(tv3, c7);
|
||
|
tv5 = Fp.mul(tv4, tv1);
|
||
|
tv3 = Fp.cmov(tv2, tv3, isQR);
|
||
|
tv4 = Fp.cmov(tv5, tv4, isQR);
|
||
|
for (let i = c1; i > _1n$5; i--) {
|
||
|
let tv5 = i - _2n$4;
|
||
|
tv5 = _2n$4 << (tv5 - _1n$5);
|
||
|
let tvv5 = Fp.pow(tv4, tv5);
|
||
|
const e1 = Fp.eql(tvv5, Fp.ONE);
|
||
|
tv2 = Fp.mul(tv3, tv1);
|
||
|
tv1 = Fp.mul(tv1, tv1);
|
||
|
tvv5 = Fp.mul(tv4, tv1);
|
||
|
tv3 = Fp.cmov(tv2, tv3, e1);
|
||
|
tv4 = Fp.cmov(tvv5, tv4, e1);
|
||
|
}
|
||
|
return { isValid: isQR, value: tv3 };
|
||
|
};
|
||
|
if (Fp.ORDER % _4n === _3n) {
|
||
|
const c1 = (Fp.ORDER - _3n) / _4n;
|
||
|
const c2 = Fp.sqrt(Fp.neg(Z));
|
||
|
sqrtRatio = (u, v) => {
|
||
|
let tv1 = Fp.sqr(v);
|
||
|
const tv2 = Fp.mul(u, v);
|
||
|
tv1 = Fp.mul(tv1, tv2);
|
||
|
let y1 = Fp.pow(tv1, c1);
|
||
|
y1 = Fp.mul(y1, tv2);
|
||
|
const y2 = Fp.mul(y1, c2);
|
||
|
const tv3 = Fp.mul(Fp.sqr(y1), v);
|
||
|
const isQR = Fp.eql(tv3, u);
|
||
|
let y = Fp.cmov(y2, y1, isQR);
|
||
|
return { isValid: isQR, value: y };
|
||
|
};
|
||
|
}
|
||
|
return sqrtRatio;
|
||
|
}
|
||
|
function mapToCurveSimpleSWU(Fp, opts) {
|
||
|
validateField(Fp);
|
||
|
if (!Fp.isValid(opts.A) || !Fp.isValid(opts.B) || !Fp.isValid(opts.Z))
|
||
|
throw new Error('mapToCurveSimpleSWU: invalid opts');
|
||
|
const sqrtRatio = SWUFpSqrtRatio(Fp, opts.Z);
|
||
|
if (!Fp.isOdd)
|
||
|
throw new Error('Fp.isOdd is not implemented!');
|
||
|
return (u) => {
|
||
|
let tv1, tv2, tv3, tv4, tv5, tv6, x, y;
|
||
|
tv1 = Fp.sqr(u);
|
||
|
tv1 = Fp.mul(tv1, opts.Z);
|
||
|
tv2 = Fp.sqr(tv1);
|
||
|
tv2 = Fp.add(tv2, tv1);
|
||
|
tv3 = Fp.add(tv2, Fp.ONE);
|
||
|
tv3 = Fp.mul(tv3, opts.B);
|
||
|
tv4 = Fp.cmov(opts.Z, Fp.neg(tv2), !Fp.eql(tv2, Fp.ZERO));
|
||
|
tv4 = Fp.mul(tv4, opts.A);
|
||
|
tv2 = Fp.sqr(tv3);
|
||
|
tv6 = Fp.sqr(tv4);
|
||
|
tv5 = Fp.mul(tv6, opts.A);
|
||
|
tv2 = Fp.add(tv2, tv5);
|
||
|
tv2 = Fp.mul(tv2, tv3);
|
||
|
tv6 = Fp.mul(tv6, tv4);
|
||
|
tv5 = Fp.mul(tv6, opts.B);
|
||
|
tv2 = Fp.add(tv2, tv5);
|
||
|
x = Fp.mul(tv1, tv3);
|
||
|
const { isValid, value } = sqrtRatio(tv2, tv6);
|
||
|
y = Fp.mul(tv1, u);
|
||
|
y = Fp.mul(y, value);
|
||
|
x = Fp.cmov(x, tv3, isValid);
|
||
|
y = Fp.cmov(y, value, isValid);
|
||
|
const e1 = Fp.isOdd(u) === Fp.isOdd(y);
|
||
|
y = Fp.cmov(Fp.neg(y), y, e1);
|
||
|
x = Fp.div(x, tv4);
|
||
|
return { x, y };
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function validateDST(dst) {
|
||
|
if (dst instanceof Uint8Array)
|
||
|
return dst;
|
||
|
if (typeof dst === 'string')
|
||
|
return utf8ToBytes(dst);
|
||
|
throw new Error('DST must be Uint8Array or string');
|
||
|
}
|
||
|
const os2ip = bytesToNumberBE;
|
||
|
function i2osp(value, length) {
|
||
|
if (value < 0 || value >= 1 << (8 * length)) {
|
||
|
throw new Error(`bad I2OSP call: value=${value} length=${length}`);
|
||
|
}
|
||
|
const res = Array.from({ length }).fill(0);
|
||
|
for (let i = length - 1; i >= 0; i--) {
|
||
|
res[i] = value & 0xff;
|
||
|
value >>>= 8;
|
||
|
}
|
||
|
return new Uint8Array(res);
|
||
|
}
|
||
|
function strxor(a, b) {
|
||
|
const arr = new Uint8Array(a.length);
|
||
|
for (let i = 0; i < a.length; i++) {
|
||
|
arr[i] = a[i] ^ b[i];
|
||
|
}
|
||
|
return arr;
|
||
|
}
|
||
|
function isBytes(item) {
|
||
|
if (!(item instanceof Uint8Array))
|
||
|
throw new Error('Uint8Array expected');
|
||
|
}
|
||
|
function isNum(item) {
|
||
|
if (!Number.isSafeInteger(item))
|
||
|
throw new Error('number expected');
|
||
|
}
|
||
|
function expand_message_xmd(msg, DST, lenInBytes, H) {
|
||
|
isBytes(msg);
|
||
|
isBytes(DST);
|
||
|
isNum(lenInBytes);
|
||
|
if (DST.length > 255)
|
||
|
DST = H(concatBytes(utf8ToBytes('H2C-OVERSIZE-DST-'), DST));
|
||
|
const { outputLen: b_in_bytes, blockLen: r_in_bytes } = H;
|
||
|
const ell = Math.ceil(lenInBytes / b_in_bytes);
|
||
|
if (ell > 255)
|
||
|
throw new Error('Invalid xmd length');
|
||
|
const DST_prime = concatBytes(DST, i2osp(DST.length, 1));
|
||
|
const Z_pad = i2osp(0, r_in_bytes);
|
||
|
const l_i_b_str = i2osp(lenInBytes, 2);
|
||
|
const b = new Array(ell);
|
||
|
const b_0 = H(concatBytes(Z_pad, msg, l_i_b_str, i2osp(0, 1), DST_prime));
|
||
|
b[0] = H(concatBytes(b_0, i2osp(1, 1), DST_prime));
|
||
|
for (let i = 1; i <= ell; i++) {
|
||
|
const args = [strxor(b_0, b[i - 1]), i2osp(i + 1, 1), DST_prime];
|
||
|
b[i] = H(concatBytes(...args));
|
||
|
}
|
||
|
const pseudo_random_bytes = concatBytes(...b);
|
||
|
return pseudo_random_bytes.slice(0, lenInBytes);
|
||
|
}
|
||
|
function expand_message_xof(msg, DST, lenInBytes, k, H) {
|
||
|
isBytes(msg);
|
||
|
isBytes(DST);
|
||
|
isNum(lenInBytes);
|
||
|
if (DST.length > 255) {
|
||
|
const dkLen = Math.ceil((2 * k) / 8);
|
||
|
DST = H.create({ dkLen }).update(utf8ToBytes('H2C-OVERSIZE-DST-')).update(DST).digest();
|
||
|
}
|
||
|
if (lenInBytes > 65535 || DST.length > 255)
|
||
|
throw new Error('expand_message_xof: invalid lenInBytes');
|
||
|
return (H.create({ dkLen: lenInBytes })
|
||
|
.update(msg)
|
||
|
.update(i2osp(lenInBytes, 2))
|
||
|
.update(DST)
|
||
|
.update(i2osp(DST.length, 1))
|
||
|
.digest());
|
||
|
}
|
||
|
function hash_to_field(msg, count, options) {
|
||
|
validateObject(options, {
|
||
|
DST: 'stringOrUint8Array',
|
||
|
p: 'bigint',
|
||
|
m: 'isSafeInteger',
|
||
|
k: 'isSafeInteger',
|
||
|
hash: 'hash',
|
||
|
});
|
||
|
const { p, k, m, hash, expand, DST: _DST } = options;
|
||
|
isBytes(msg);
|
||
|
isNum(count);
|
||
|
const DST = validateDST(_DST);
|
||
|
const log2p = p.toString(2).length;
|
||
|
const L = Math.ceil((log2p + k) / 8);
|
||
|
const len_in_bytes = count * m * L;
|
||
|
let prb;
|
||
|
if (expand === 'xmd') {
|
||
|
prb = expand_message_xmd(msg, DST, len_in_bytes, hash);
|
||
|
}
|
||
|
else if (expand === 'xof') {
|
||
|
prb = expand_message_xof(msg, DST, len_in_bytes, k, hash);
|
||
|
}
|
||
|
else if (expand === '_internal_pass') {
|
||
|
prb = msg;
|
||
|
}
|
||
|
else {
|
||
|
throw new Error('expand must be "xmd" or "xof"');
|
||
|
}
|
||
|
const u = new Array(count);
|
||
|
for (let i = 0; i < count; i++) {
|
||
|
const e = new Array(m);
|
||
|
for (let j = 0; j < m; j++) {
|
||
|
const elm_offset = L * (j + i * m);
|
||
|
const tv = prb.subarray(elm_offset, elm_offset + L);
|
||
|
e[j] = mod(os2ip(tv), p);
|
||
|
}
|
||
|
u[i] = e;
|
||
|
}
|
||
|
return u;
|
||
|
}
|
||
|
function isogenyMap(field, map) {
|
||
|
const COEFF = map.map((i) => Array.from(i).reverse());
|
||
|
return (x, y) => {
|
||
|
const [xNum, xDen, yNum, yDen] = COEFF.map((val) => val.reduce((acc, i) => field.add(field.mul(acc, x), i)));
|
||
|
x = field.div(xNum, xDen);
|
||
|
y = field.mul(y, field.div(yNum, yDen));
|
||
|
return { x, y };
|
||
|
};
|
||
|
}
|
||
|
function createHasher(Point, mapToCurve, def) {
|
||
|
if (typeof mapToCurve !== 'function')
|
||
|
throw new Error('mapToCurve() must be defined');
|
||
|
return {
|
||
|
hashToCurve(msg, options) {
|
||
|
const u = hash_to_field(msg, 2, { ...def, DST: def.DST, ...options });
|
||
|
const u0 = Point.fromAffine(mapToCurve(u[0]));
|
||
|
const u1 = Point.fromAffine(mapToCurve(u[1]));
|
||
|
const P = u0.add(u1).clearCofactor();
|
||
|
P.assertValidity();
|
||
|
return P;
|
||
|
},
|
||
|
encodeToCurve(msg, options) {
|
||
|
const u = hash_to_field(msg, 1, { ...def, DST: def.encodeDST, ...options });
|
||
|
const P = Point.fromAffine(mapToCurve(u[0])).clearCofactor();
|
||
|
P.assertValidity();
|
||
|
return P;
|
||
|
},
|
||
|
};
|
||
|
}
|
||
|
|
||
|
class HMAC extends Hash {
|
||
|
constructor(hash$1, _key) {
|
||
|
super();
|
||
|
this.finished = false;
|
||
|
this.destroyed = false;
|
||
|
hash(hash$1);
|
||
|
const key = toBytes(_key);
|
||
|
this.iHash = hash$1.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);
|
||
|
pad.set(key.length > blockLen ? hash$1.create().update(key).digest() : key);
|
||
|
for (let i = 0; i < pad.length; i++)
|
||
|
pad[i] ^= 0x36;
|
||
|
this.iHash.update(pad);
|
||
|
this.oHash = hash$1.create();
|
||
|
for (let i = 0; i < pad.length; i++)
|
||
|
pad[i] ^= 0x36 ^ 0x5c;
|
||
|
this.oHash.update(pad);
|
||
|
pad.fill(0);
|
||
|
}
|
||
|
update(buf) {
|
||
|
exists(this);
|
||
|
this.iHash.update(buf);
|
||
|
return this;
|
||
|
}
|
||
|
digestInto(out) {
|
||
|
exists(this);
|
||
|
bytes(out, this.outputLen);
|
||
|
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) {
|
||
|
to || (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;
|
||
|
}
|
||
|
destroy() {
|
||
|
this.destroyed = true;
|
||
|
this.oHash.destroy();
|
||
|
this.iHash.destroy();
|
||
|
}
|
||
|
}
|
||
|
const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
|
||
|
hmac.create = (hash, key) => new HMAC(hash, key);
|
||
|
|
||
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||
|
function getHash(hash) {
|
||
|
return {
|
||
|
hash,
|
||
|
hmac: (key, ...msgs) => hmac(hash, key, concatBytes$1(...msgs)),
|
||
|
randomBytes,
|
||
|
};
|
||
|
}
|
||
|
function createCurve(curveDef, defHash) {
|
||
|
const create = (hash) => weierstrass({ ...curveDef, ...getHash(hash) });
|
||
|
return Object.freeze({ ...create(defHash), create });
|
||
|
}
|
||
|
|
||
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||
|
const secp256k1P = BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f');
|
||
|
const secp256k1N = BigInt('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141');
|
||
|
const _1n$4 = BigInt(1);
|
||
|
const _2n$3 = BigInt(2);
|
||
|
const divNearest = (a, b) => (a + b / _2n$3) / b;
|
||
|
function sqrtMod(y) {
|
||
|
const P = secp256k1P;
|
||
|
const _3n = BigInt(3), _6n = BigInt(6), _11n = BigInt(11), _22n = BigInt(22);
|
||
|
const _23n = BigInt(23), _44n = BigInt(44), _88n = BigInt(88);
|
||
|
const b2 = (y * y * y) % P;
|
||
|
const b3 = (b2 * b2 * y) % P;
|
||
|
const b6 = (pow2(b3, _3n, P) * b3) % P;
|
||
|
const b9 = (pow2(b6, _3n, P) * b3) % P;
|
||
|
const b11 = (pow2(b9, _2n$3, P) * b2) % P;
|
||
|
const b22 = (pow2(b11, _11n, P) * b11) % P;
|
||
|
const b44 = (pow2(b22, _22n, P) * b22) % P;
|
||
|
const b88 = (pow2(b44, _44n, P) * b44) % P;
|
||
|
const b176 = (pow2(b88, _88n, P) * b88) % P;
|
||
|
const b220 = (pow2(b176, _44n, P) * b44) % P;
|
||
|
const b223 = (pow2(b220, _3n, P) * b3) % P;
|
||
|
const t1 = (pow2(b223, _23n, P) * b22) % P;
|
||
|
const t2 = (pow2(t1, _6n, P) * b2) % P;
|
||
|
const root = pow2(t2, _2n$3, P);
|
||
|
if (!Fp$1.eql(Fp$1.sqr(root), y))
|
||
|
throw new Error('Cannot find square root');
|
||
|
return root;
|
||
|
}
|
||
|
const Fp$1 = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
|
||
|
const secp256k1 = createCurve({
|
||
|
a: BigInt(0),
|
||
|
b: BigInt(7),
|
||
|
Fp: Fp$1,
|
||
|
n: secp256k1N,
|
||
|
Gx: BigInt('55066263022277343669578718895168534326250603453777594175500187360389116729240'),
|
||
|
Gy: BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424'),
|
||
|
h: BigInt(1),
|
||
|
lowS: true,
|
||
|
endo: {
|
||
|
beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),
|
||
|
splitScalar: (k) => {
|
||
|
const n = secp256k1N;
|
||
|
const a1 = BigInt('0x3086d221a7d46bcde86c90e49284eb15');
|
||
|
const b1 = -_1n$4 * BigInt('0xe4437ed6010e88286f547fa90abfe4c3');
|
||
|
const a2 = BigInt('0x114ca50f7a8e2f3f657c1108d9d44cfd8');
|
||
|
const b2 = a1;
|
||
|
const POW_2_128 = BigInt('0x100000000000000000000000000000000');
|
||
|
const c1 = divNearest(b2 * k, n);
|
||
|
const c2 = divNearest(-b1 * k, n);
|
||
|
let k1 = mod(k - c1 * a1 - c2 * a2, n);
|
||
|
let k2 = mod(-c1 * b1 - c2 * b2, n);
|
||
|
const k1neg = k1 > POW_2_128;
|
||
|
const k2neg = k2 > POW_2_128;
|
||
|
if (k1neg)
|
||
|
k1 = n - k1;
|
||
|
if (k2neg)
|
||
|
k2 = n - k2;
|
||
|
if (k1 > POW_2_128 || k2 > POW_2_128) {
|
||
|
throw new Error('splitScalar: Endomorphism failed, k=' + k);
|
||
|
}
|
||
|
return { k1neg, k1, k2neg, k2 };
|
||
|
},
|
||
|
},
|
||
|
}, sha256);
|
||
|
const _0n$4 = BigInt(0);
|
||
|
const fe = (x) => typeof x === 'bigint' && _0n$4 < x && x < secp256k1P;
|
||
|
const ge = (x) => typeof x === 'bigint' && _0n$4 < x && x < secp256k1N;
|
||
|
const TAGGED_HASH_PREFIXES = {};
|
||
|
function taggedHash(tag, ...messages) {
|
||
|
let tagP = TAGGED_HASH_PREFIXES[tag];
|
||
|
if (tagP === undefined) {
|
||
|
const tagH = sha256(Uint8Array.from(tag, (c) => c.charCodeAt(0)));
|
||
|
tagP = concatBytes(tagH, tagH);
|
||
|
TAGGED_HASH_PREFIXES[tag] = tagP;
|
||
|
}
|
||
|
return sha256(concatBytes(tagP, ...messages));
|
||
|
}
|
||
|
const pointToBytes = (point) => point.toRawBytes(true).slice(1);
|
||
|
const numTo32b = (n) => numberToBytesBE(n, 32);
|
||
|
const modP = (x) => mod(x, secp256k1P);
|
||
|
const modN = (x) => mod(x, secp256k1N);
|
||
|
const Point = secp256k1.ProjectivePoint;
|
||
|
const GmulAdd = (Q, a, b) => Point.BASE.multiplyAndAddUnsafe(Q, a, b);
|
||
|
function schnorrGetExtPubKey(priv) {
|
||
|
let d_ = secp256k1.utils.normPrivateKeyToScalar(priv);
|
||
|
let p = Point.fromPrivateKey(d_);
|
||
|
const scalar = p.hasEvenY() ? d_ : modN(-d_);
|
||
|
return { scalar: scalar, bytes: pointToBytes(p) };
|
||
|
}
|
||
|
function lift_x(x) {
|
||
|
if (!fe(x))
|
||
|
throw new Error('bad x: need 0 < x < p');
|
||
|
const xx = modP(x * x);
|
||
|
const c = modP(xx * x + BigInt(7));
|
||
|
let y = sqrtMod(c);
|
||
|
if (y % _2n$3 !== _0n$4)
|
||
|
y = modP(-y);
|
||
|
const p = new Point(x, y, _1n$4);
|
||
|
p.assertValidity();
|
||
|
return p;
|
||
|
}
|
||
|
function challenge(...args) {
|
||
|
return modN(bytesToNumberBE(taggedHash('BIP0340/challenge', ...args)));
|
||
|
}
|
||
|
function schnorrGetPublicKey(privateKey) {
|
||
|
return schnorrGetExtPubKey(privateKey).bytes;
|
||
|
}
|
||
|
function schnorrSign(message, privateKey, auxRand = randomBytes(32)) {
|
||
|
const m = ensureBytes('message', message);
|
||
|
const { bytes: px, scalar: d } = schnorrGetExtPubKey(privateKey);
|
||
|
const a = ensureBytes('auxRand', auxRand, 32);
|
||
|
const t = numTo32b(d ^ bytesToNumberBE(taggedHash('BIP0340/aux', a)));
|
||
|
const rand = taggedHash('BIP0340/nonce', t, px, m);
|
||
|
const k_ = modN(bytesToNumberBE(rand));
|
||
|
if (k_ === _0n$4)
|
||
|
throw new Error('sign failed: k is zero');
|
||
|
const { bytes: rx, scalar: k } = schnorrGetExtPubKey(k_);
|
||
|
const e = challenge(rx, px, m);
|
||
|
const sig = new Uint8Array(64);
|
||
|
sig.set(rx, 0);
|
||
|
sig.set(numTo32b(modN(k + e * d)), 32);
|
||
|
if (!schnorrVerify(sig, m, px))
|
||
|
throw new Error('sign: Invalid signature produced');
|
||
|
return sig;
|
||
|
}
|
||
|
function schnorrVerify(signature, message, publicKey) {
|
||
|
const sig = ensureBytes('signature', signature, 64);
|
||
|
const m = ensureBytes('message', message);
|
||
|
const pub = ensureBytes('publicKey', publicKey, 32);
|
||
|
try {
|
||
|
const P = lift_x(bytesToNumberBE(pub));
|
||
|
const r = bytesToNumberBE(sig.subarray(0, 32));
|
||
|
if (!fe(r))
|
||
|
return false;
|
||
|
const s = bytesToNumberBE(sig.subarray(32, 64));
|
||
|
if (!ge(s))
|
||
|
return false;
|
||
|
const e = challenge(numTo32b(r), pointToBytes(P), m);
|
||
|
const R = GmulAdd(P, s, modN(-e));
|
||
|
if (!R || !R.hasEvenY() || R.toAffine().x !== r)
|
||
|
return false;
|
||
|
return true;
|
||
|
}
|
||
|
catch (error) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
(() => ({
|
||
|
getPublicKey: schnorrGetPublicKey,
|
||
|
sign: schnorrSign,
|
||
|
verify: schnorrVerify,
|
||
|
utils: {
|
||
|
randomPrivateKey: secp256k1.utils.randomPrivateKey,
|
||
|
lift_x,
|
||
|
pointToBytes,
|
||
|
numberToBytesBE,
|
||
|
bytesToNumberBE,
|
||
|
taggedHash,
|
||
|
mod,
|
||
|
},
|
||
|
}))();
|
||
|
const isoMap = (() => isogenyMap(Fp$1, [
|
||
|
[
|
||
|
'0x8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38daaaaa8c7',
|
||
|
'0x7d3d4c80bc321d5b9f315cea7fd44c5d595d2fc0bf63b92dfff1044f17c6581',
|
||
|
'0x534c328d23f234e6e2a413deca25caece4506144037c40314ecbd0b53d9dd262',
|
||
|
'0x8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38daaaaa88c',
|
||
|
],
|
||
|
[
|
||
|
'0xd35771193d94918a9ca34ccbb7b640dd86cd409542f8487d9fe6b745781eb49b',
|
||
|
'0xedadc6f64383dc1df7c4b2d51b54225406d36b641f5e41bbc52a56612a8c6d14',
|
||
|
'0x0000000000000000000000000000000000000000000000000000000000000001',
|
||
|
],
|
||
|
[
|
||
|
'0x4bda12f684bda12f684bda12f684bda12f684bda12f684bda12f684b8e38e23c',
|
||
|
'0xc75e0c32d5cb7c0fa9d0a54b12a0a6d5647ab046d686da6fdffc90fc201d71a3',
|
||
|
'0x29a6194691f91a73715209ef6512e576722830a201be2018a765e85a9ecee931',
|
||
|
'0x2f684bda12f684bda12f684bda12f684bda12f684bda12f684bda12f38e38d84',
|
||
|
],
|
||
|
[
|
||
|
'0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffff93b',
|
||
|
'0x7a06534bb8bdb49fd5e9e6632722c2989467c1bfc8e8d978dfb425d2685c2573',
|
||
|
'0x6484aa716545ca2cf3a70c3fa8fe337e0a3d21162f0d6299a7bf8192bfd2a76f',
|
||
|
'0x0000000000000000000000000000000000000000000000000000000000000001',
|
||
|
],
|
||
|
].map((i) => i.map((j) => BigInt(j)))))();
|
||
|
const mapSWU = (() => mapToCurveSimpleSWU(Fp$1, {
|
||
|
A: BigInt('0x3f8731abdd661adca08a5558f0f5d272e953d363cb6f0e5d405447c01a444533'),
|
||
|
B: BigInt('1771'),
|
||
|
Z: Fp$1.create(BigInt('-11')),
|
||
|
}))();
|
||
|
(() => createHasher(secp256k1.ProjectivePoint, (scalars) => {
|
||
|
const { x, y } = mapSWU(Fp$1.create(scalars[0]));
|
||
|
return isoMap(x, y);
|
||
|
}, {
|
||
|
DST: 'secp256k1_XMD:SHA-256_SSWU_RO_',
|
||
|
encodeDST: 'secp256k1_XMD:SHA-256_SSWU_NU_',
|
||
|
p: Fp$1.ORDER,
|
||
|
m: 1,
|
||
|
k: 128,
|
||
|
expand: 'xmd',
|
||
|
hash: sha256,
|
||
|
}))();
|
||
|
|
||
|
function secp256k1PairFromSeed(seed, onlyJs) {
|
||
|
if (seed.length !== 32) {
|
||
|
throw new Error('Expected valid 32-byte private key as a seed');
|
||
|
}
|
||
|
if (!util.hasBigInt || (!onlyJs && isReady())) {
|
||
|
const full = secp256k1FromSeed(seed);
|
||
|
const publicKey = full.slice(32);
|
||
|
if (util.u8aEmpty(publicKey)) {
|
||
|
throw new Error('Invalid publicKey generated from WASM interface');
|
||
|
}
|
||
|
return {
|
||
|
publicKey,
|
||
|
secretKey: full.slice(0, 32)
|
||
|
};
|
||
|
}
|
||
|
return {
|
||
|
publicKey: secp256k1.getPublicKey(seed, true),
|
||
|
secretKey: seed
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function createSeedDeriveFn(fromSeed, derive) {
|
||
|
return (keypair, { chainCode, isHard }) => {
|
||
|
if (!isHard) {
|
||
|
throw new Error('A soft key was found in the path and is not supported');
|
||
|
}
|
||
|
return fromSeed(derive(keypair.secretKey.subarray(0, 32), chainCode));
|
||
|
};
|
||
|
}
|
||
|
|
||
|
const keyHdkdEcdsa = createSeedDeriveFn(secp256k1PairFromSeed, secp256k1DeriveHard);
|
||
|
|
||
|
const HDKD = util.compactAddLength(util.stringToU8a('Ed25519HDKD'));
|
||
|
function ed25519DeriveHard(seed, chainCode) {
|
||
|
if (!util.isU8a(chainCode) || chainCode.length !== 32) {
|
||
|
throw new Error('Invalid chainCode passed to derive');
|
||
|
}
|
||
|
return blake2AsU8a(util.u8aConcat(HDKD, seed, chainCode));
|
||
|
}
|
||
|
|
||
|
function randomAsU8a(length = 32) {
|
||
|
return browser.getRandomValues(new Uint8Array(length));
|
||
|
}
|
||
|
const randomAsHex = createAsHex(randomAsU8a);
|
||
|
|
||
|
const BN_53 = new util.BN(0b11111111111111111111111111111111111111111111111111111);
|
||
|
function randomAsNumber() {
|
||
|
return util.hexToBn(randomAsHex(8)).and(BN_53).toNumber();
|
||
|
}
|
||
|
|
||
|
const [SHA512_Kh, SHA512_Kl] = (() => u64$1.split([
|
||
|
'0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc',
|
||
|
'0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118',
|
||
|
'0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2',
|
||
|
'0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694',
|
||
|
'0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65',
|
||
|
'0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5',
|
||
|
'0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4',
|
||
|
'0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70',
|
||
|
'0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df',
|
||
|
'0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b',
|
||
|
'0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30',
|
||
|
'0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8',
|
||
|
'0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8',
|
||
|
'0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3',
|
||
|
'0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec',
|
||
|
'0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b',
|
||
|
'0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178',
|
||
|
'0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b',
|
||
|
'0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c',
|
||
|
'0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817'
|
||
|
].map(n => BigInt(n))))();
|
||
|
const SHA512_W_H = new Uint32Array(80);
|
||
|
const SHA512_W_L = new Uint32Array(80);
|
||
|
class SHA512 extends SHA2 {
|
||
|
constructor() {
|
||
|
super(128, 64, 16, false);
|
||
|
this.Ah = 0x6a09e667 | 0;
|
||
|
this.Al = 0xf3bcc908 | 0;
|
||
|
this.Bh = 0xbb67ae85 | 0;
|
||
|
this.Bl = 0x84caa73b | 0;
|
||
|
this.Ch = 0x3c6ef372 | 0;
|
||
|
this.Cl = 0xfe94f82b | 0;
|
||
|
this.Dh = 0xa54ff53a | 0;
|
||
|
this.Dl = 0x5f1d36f1 | 0;
|
||
|
this.Eh = 0x510e527f | 0;
|
||
|
this.El = 0xade682d1 | 0;
|
||
|
this.Fh = 0x9b05688c | 0;
|
||
|
this.Fl = 0x2b3e6c1f | 0;
|
||
|
this.Gh = 0x1f83d9ab | 0;
|
||
|
this.Gl = 0xfb41bd6b | 0;
|
||
|
this.Hh = 0x5be0cd19 | 0;
|
||
|
this.Hl = 0x137e2179 | 0;
|
||
|
}
|
||
|
get() {
|
||
|
const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
|
||
|
return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];
|
||
|
}
|
||
|
set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) {
|
||
|
this.Ah = Ah | 0;
|
||
|
this.Al = Al | 0;
|
||
|
this.Bh = Bh | 0;
|
||
|
this.Bl = Bl | 0;
|
||
|
this.Ch = Ch | 0;
|
||
|
this.Cl = Cl | 0;
|
||
|
this.Dh = Dh | 0;
|
||
|
this.Dl = Dl | 0;
|
||
|
this.Eh = Eh | 0;
|
||
|
this.El = El | 0;
|
||
|
this.Fh = Fh | 0;
|
||
|
this.Fl = Fl | 0;
|
||
|
this.Gh = Gh | 0;
|
||
|
this.Gl = Gl | 0;
|
||
|
this.Hh = Hh | 0;
|
||
|
this.Hl = Hl | 0;
|
||
|
}
|
||
|
process(view, offset) {
|
||
|
for (let i = 0; i < 16; i++, offset += 4) {
|
||
|
SHA512_W_H[i] = view.getUint32(offset);
|
||
|
SHA512_W_L[i] = view.getUint32((offset += 4));
|
||
|
}
|
||
|
for (let i = 16; i < 80; i++) {
|
||
|
const W15h = SHA512_W_H[i - 15] | 0;
|
||
|
const W15l = SHA512_W_L[i - 15] | 0;
|
||
|
const s0h = u64$1.rotrSH(W15h, W15l, 1) ^ u64$1.rotrSH(W15h, W15l, 8) ^ u64$1.shrSH(W15h, W15l, 7);
|
||
|
const s0l = u64$1.rotrSL(W15h, W15l, 1) ^ u64$1.rotrSL(W15h, W15l, 8) ^ u64$1.shrSL(W15h, W15l, 7);
|
||
|
const W2h = SHA512_W_H[i - 2] | 0;
|
||
|
const W2l = SHA512_W_L[i - 2] | 0;
|
||
|
const s1h = u64$1.rotrSH(W2h, W2l, 19) ^ u64$1.rotrBH(W2h, W2l, 61) ^ u64$1.shrSH(W2h, W2l, 6);
|
||
|
const s1l = u64$1.rotrSL(W2h, W2l, 19) ^ u64$1.rotrBL(W2h, W2l, 61) ^ u64$1.shrSL(W2h, W2l, 6);
|
||
|
const SUMl = u64$1.add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);
|
||
|
const SUMh = u64$1.add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);
|
||
|
SHA512_W_H[i] = SUMh | 0;
|
||
|
SHA512_W_L[i] = SUMl | 0;
|
||
|
}
|
||
|
let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
|
||
|
for (let i = 0; i < 80; i++) {
|
||
|
const sigma1h = u64$1.rotrSH(Eh, El, 14) ^ u64$1.rotrSH(Eh, El, 18) ^ u64$1.rotrBH(Eh, El, 41);
|
||
|
const sigma1l = u64$1.rotrSL(Eh, El, 14) ^ u64$1.rotrSL(Eh, El, 18) ^ u64$1.rotrBL(Eh, El, 41);
|
||
|
const CHIh = (Eh & Fh) ^ (~Eh & Gh);
|
||
|
const CHIl = (El & Fl) ^ (~El & Gl);
|
||
|
const T1ll = u64$1.add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);
|
||
|
const T1h = u64$1.add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);
|
||
|
const T1l = T1ll | 0;
|
||
|
const sigma0h = u64$1.rotrSH(Ah, Al, 28) ^ u64$1.rotrBH(Ah, Al, 34) ^ u64$1.rotrBH(Ah, Al, 39);
|
||
|
const sigma0l = u64$1.rotrSL(Ah, Al, 28) ^ u64$1.rotrBL(Ah, Al, 34) ^ u64$1.rotrBL(Ah, Al, 39);
|
||
|
const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch);
|
||
|
const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl);
|
||
|
Hh = Gh | 0;
|
||
|
Hl = Gl | 0;
|
||
|
Gh = Fh | 0;
|
||
|
Gl = Fl | 0;
|
||
|
Fh = Eh | 0;
|
||
|
Fl = El | 0;
|
||
|
({ h: Eh, l: El } = u64$1.add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));
|
||
|
Dh = Ch | 0;
|
||
|
Dl = Cl | 0;
|
||
|
Ch = Bh | 0;
|
||
|
Cl = Bl | 0;
|
||
|
Bh = Ah | 0;
|
||
|
Bl = Al | 0;
|
||
|
const All = u64$1.add3L(T1l, sigma0l, MAJl);
|
||
|
Ah = u64$1.add3H(All, T1h, sigma0h, MAJh);
|
||
|
Al = All | 0;
|
||
|
}
|
||
|
({ h: Ah, l: Al } = u64$1.add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));
|
||
|
({ h: Bh, l: Bl } = u64$1.add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));
|
||
|
({ h: Ch, l: Cl } = u64$1.add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));
|
||
|
({ h: Dh, l: Dl } = u64$1.add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));
|
||
|
({ h: Eh, l: El } = u64$1.add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));
|
||
|
({ h: Fh, l: Fl } = u64$1.add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));
|
||
|
({ h: Gh, l: Gl } = u64$1.add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));
|
||
|
({ h: Hh, l: Hl } = u64$1.add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));
|
||
|
this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
|
||
|
}
|
||
|
roundClean() {
|
||
|
SHA512_W_H.fill(0);
|
||
|
SHA512_W_L.fill(0);
|
||
|
}
|
||
|
destroy() {
|
||
|
this.buffer.fill(0);
|
||
|
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||
|
}
|
||
|
}
|
||
|
class SHA512_224 extends SHA512 {
|
||
|
constructor() {
|
||
|
super();
|
||
|
this.Ah = 0x8c3d37c8 | 0;
|
||
|
this.Al = 0x19544da2 | 0;
|
||
|
this.Bh = 0x73e19966 | 0;
|
||
|
this.Bl = 0x89dcd4d6 | 0;
|
||
|
this.Ch = 0x1dfab7ae | 0;
|
||
|
this.Cl = 0x32ff9c82 | 0;
|
||
|
this.Dh = 0x679dd514 | 0;
|
||
|
this.Dl = 0x582f9fcf | 0;
|
||
|
this.Eh = 0x0f6d2b69 | 0;
|
||
|
this.El = 0x7bd44da8 | 0;
|
||
|
this.Fh = 0x77e36f73 | 0;
|
||
|
this.Fl = 0x04c48942 | 0;
|
||
|
this.Gh = 0x3f9d85a8 | 0;
|
||
|
this.Gl = 0x6a1d36c8 | 0;
|
||
|
this.Hh = 0x1112e6ad | 0;
|
||
|
this.Hl = 0x91d692a1 | 0;
|
||
|
this.outputLen = 28;
|
||
|
}
|
||
|
}
|
||
|
class SHA512_256 extends SHA512 {
|
||
|
constructor() {
|
||
|
super();
|
||
|
this.Ah = 0x22312194 | 0;
|
||
|
this.Al = 0xfc2bf72c | 0;
|
||
|
this.Bh = 0x9f555fa3 | 0;
|
||
|
this.Bl = 0xc84c64c2 | 0;
|
||
|
this.Ch = 0x2393b86b | 0;
|
||
|
this.Cl = 0x6f53b151 | 0;
|
||
|
this.Dh = 0x96387719 | 0;
|
||
|
this.Dl = 0x5940eabd | 0;
|
||
|
this.Eh = 0x96283ee2 | 0;
|
||
|
this.El = 0xa88effe3 | 0;
|
||
|
this.Fh = 0xbe5e1e25 | 0;
|
||
|
this.Fl = 0x53863992 | 0;
|
||
|
this.Gh = 0x2b0199fc | 0;
|
||
|
this.Gl = 0x2c85b8aa | 0;
|
||
|
this.Hh = 0x0eb72ddc | 0;
|
||
|
this.Hl = 0x81c52ca2 | 0;
|
||
|
this.outputLen = 32;
|
||
|
}
|
||
|
}
|
||
|
class SHA384 extends SHA512 {
|
||
|
constructor() {
|
||
|
super();
|
||
|
this.Ah = 0xcbbb9d5d | 0;
|
||
|
this.Al = 0xc1059ed8 | 0;
|
||
|
this.Bh = 0x629a292a | 0;
|
||
|
this.Bl = 0x367cd507 | 0;
|
||
|
this.Ch = 0x9159015a | 0;
|
||
|
this.Cl = 0x3070dd17 | 0;
|
||
|
this.Dh = 0x152fecd8 | 0;
|
||
|
this.Dl = 0xf70e5939 | 0;
|
||
|
this.Eh = 0x67332667 | 0;
|
||
|
this.El = 0xffc00b31 | 0;
|
||
|
this.Fh = 0x8eb44a87 | 0;
|
||
|
this.Fl = 0x68581511 | 0;
|
||
|
this.Gh = 0xdb0c2e0d | 0;
|
||
|
this.Gl = 0x64f98fa7 | 0;
|
||
|
this.Hh = 0x47b5481d | 0;
|
||
|
this.Hl = 0xbefa4fa4 | 0;
|
||
|
this.outputLen = 48;
|
||
|
}
|
||
|
}
|
||
|
const sha512 = wrapConstructor(() => new SHA512());
|
||
|
wrapConstructor(() => new SHA512_224());
|
||
|
wrapConstructor(() => new SHA512_256());
|
||
|
wrapConstructor(() => new SHA384());
|
||
|
|
||
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||
|
const _0n$3 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n = BigInt(8);
|
||
|
const VERIFY_DEFAULT = { zip215: true };
|
||
|
function validateOpts$1(curve) {
|
||
|
const opts = validateBasic(curve);
|
||
|
validateObject(curve, {
|
||
|
hash: 'function',
|
||
|
a: 'bigint',
|
||
|
d: 'bigint',
|
||
|
randomBytes: 'function',
|
||
|
}, {
|
||
|
adjustScalarBytes: 'function',
|
||
|
domain: 'function',
|
||
|
uvRatio: 'function',
|
||
|
mapToCurve: 'function',
|
||
|
});
|
||
|
return Object.freeze({ ...opts });
|
||
|
}
|
||
|
function twistedEdwards(curveDef) {
|
||
|
const CURVE = validateOpts$1(curveDef);
|
||
|
const { Fp, n: CURVE_ORDER, prehash: prehash, hash: cHash, randomBytes, nByteLength, h: cofactor, } = CURVE;
|
||
|
const MASK = _2n$2 << (BigInt(nByteLength * 8) - _1n$3);
|
||
|
const modP = Fp.create;
|
||
|
const uvRatio = CURVE.uvRatio ||
|
||
|
((u, v) => {
|
||
|
try {
|
||
|
return { isValid: true, value: Fp.sqrt(u * Fp.inv(v)) };
|
||
|
}
|
||
|
catch (e) {
|
||
|
return { isValid: false, value: _0n$3 };
|
||
|
}
|
||
|
});
|
||
|
const adjustScalarBytes = CURVE.adjustScalarBytes || ((bytes) => bytes);
|
||
|
const domain = CURVE.domain ||
|
||
|
((data, ctx, phflag) => {
|
||
|
if (ctx.length || phflag)
|
||
|
throw new Error('Contexts/pre-hash are not supported');
|
||
|
return data;
|
||
|
});
|
||
|
const inBig = (n) => typeof n === 'bigint' && _0n$3 < n;
|
||
|
const inRange = (n, max) => inBig(n) && inBig(max) && n < max;
|
||
|
const in0MaskRange = (n) => n === _0n$3 || inRange(n, MASK);
|
||
|
function assertInRange(n, max) {
|
||
|
if (inRange(n, max))
|
||
|
return n;
|
||
|
throw new Error(`Expected valid scalar < ${max}, got ${typeof n} ${n}`);
|
||
|
}
|
||
|
function assertGE0(n) {
|
||
|
return n === _0n$3 ? n : assertInRange(n, CURVE_ORDER);
|
||
|
}
|
||
|
const pointPrecomputes = new Map();
|
||
|
function isPoint(other) {
|
||
|
if (!(other instanceof Point))
|
||
|
throw new Error('ExtendedPoint expected');
|
||
|
}
|
||
|
class Point {
|
||
|
constructor(ex, ey, ez, et) {
|
||
|
this.ex = ex;
|
||
|
this.ey = ey;
|
||
|
this.ez = ez;
|
||
|
this.et = et;
|
||
|
if (!in0MaskRange(ex))
|
||
|
throw new Error('x required');
|
||
|
if (!in0MaskRange(ey))
|
||
|
throw new Error('y required');
|
||
|
if (!in0MaskRange(ez))
|
||
|
throw new Error('z required');
|
||
|
if (!in0MaskRange(et))
|
||
|
throw new Error('t required');
|
||
|
}
|
||
|
get x() {
|
||
|
return this.toAffine().x;
|
||
|
}
|
||
|
get y() {
|
||
|
return this.toAffine().y;
|
||
|
}
|
||
|
static fromAffine(p) {
|
||
|
if (p instanceof Point)
|
||
|
throw new Error('extended point not allowed');
|
||
|
const { x, y } = p || {};
|
||
|
if (!in0MaskRange(x) || !in0MaskRange(y))
|
||
|
throw new Error('invalid affine point');
|
||
|
return new Point(x, y, _1n$3, modP(x * y));
|
||
|
}
|
||
|
static normalizeZ(points) {
|
||
|
const toInv = Fp.invertBatch(points.map((p) => p.ez));
|
||
|
return points.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
|
||
|
}
|
||
|
_setWindowSize(windowSize) {
|
||
|
this._WINDOW_SIZE = windowSize;
|
||
|
pointPrecomputes.delete(this);
|
||
|
}
|
||
|
assertValidity() {
|
||
|
const { a, d } = CURVE;
|
||
|
if (this.is0())
|
||
|
throw new Error('bad point: ZERO');
|
||
|
const { ex: X, ey: Y, ez: Z, et: T } = this;
|
||
|
const X2 = modP(X * X);
|
||
|
const Y2 = modP(Y * Y);
|
||
|
const Z2 = modP(Z * Z);
|
||
|
const Z4 = modP(Z2 * Z2);
|
||
|
const aX2 = modP(X2 * a);
|
||
|
const left = modP(Z2 * modP(aX2 + Y2));
|
||
|
const right = modP(Z4 + modP(d * modP(X2 * Y2)));
|
||
|
if (left !== right)
|
||
|
throw new Error('bad point: equation left != right (1)');
|
||
|
const XY = modP(X * Y);
|
||
|
const ZT = modP(Z * T);
|
||
|
if (XY !== ZT)
|
||
|
throw new Error('bad point: equation left != right (2)');
|
||
|
}
|
||
|
equals(other) {
|
||
|
isPoint(other);
|
||
|
const { ex: X1, ey: Y1, ez: Z1 } = this;
|
||
|
const { ex: X2, ey: Y2, ez: Z2 } = other;
|
||
|
const X1Z2 = modP(X1 * Z2);
|
||
|
const X2Z1 = modP(X2 * Z1);
|
||
|
const Y1Z2 = modP(Y1 * Z2);
|
||
|
const Y2Z1 = modP(Y2 * Z1);
|
||
|
return X1Z2 === X2Z1 && Y1Z2 === Y2Z1;
|
||
|
}
|
||
|
is0() {
|
||
|
return this.equals(Point.ZERO);
|
||
|
}
|
||
|
negate() {
|
||
|
return new Point(modP(-this.ex), this.ey, this.ez, modP(-this.et));
|
||
|
}
|
||
|
double() {
|
||
|
const { a } = CURVE;
|
||
|
const { ex: X1, ey: Y1, ez: Z1 } = this;
|
||
|
const A = modP(X1 * X1);
|
||
|
const B = modP(Y1 * Y1);
|
||
|
const C = modP(_2n$2 * modP(Z1 * Z1));
|
||
|
const D = modP(a * A);
|
||
|
const x1y1 = X1 + Y1;
|
||
|
const E = modP(modP(x1y1 * x1y1) - A - B);
|
||
|
const G = D + B;
|
||
|
const F = G - C;
|
||
|
const H = D - B;
|
||
|
const X3 = modP(E * F);
|
||
|
const Y3 = modP(G * H);
|
||
|
const T3 = modP(E * H);
|
||
|
const Z3 = modP(F * G);
|
||
|
return new Point(X3, Y3, Z3, T3);
|
||
|
}
|
||
|
add(other) {
|
||
|
isPoint(other);
|
||
|
const { a, d } = CURVE;
|
||
|
const { ex: X1, ey: Y1, ez: Z1, et: T1 } = this;
|
||
|
const { ex: X2, ey: Y2, ez: Z2, et: T2 } = other;
|
||
|
if (a === BigInt(-1)) {
|
||
|
const A = modP((Y1 - X1) * (Y2 + X2));
|
||
|
const B = modP((Y1 + X1) * (Y2 - X2));
|
||
|
const F = modP(B - A);
|
||
|
if (F === _0n$3)
|
||
|
return this.double();
|
||
|
const C = modP(Z1 * _2n$2 * T2);
|
||
|
const D = modP(T1 * _2n$2 * Z2);
|
||
|
const E = D + C;
|
||
|
const G = B + A;
|
||
|
const H = D - C;
|
||
|
const X3 = modP(E * F);
|
||
|
const Y3 = modP(G * H);
|
||
|
const T3 = modP(E * H);
|
||
|
const Z3 = modP(F * G);
|
||
|
return new Point(X3, Y3, Z3, T3);
|
||
|
}
|
||
|
const A = modP(X1 * X2);
|
||
|
const B = modP(Y1 * Y2);
|
||
|
const C = modP(T1 * d * T2);
|
||
|
const D = modP(Z1 * Z2);
|
||
|
const E = modP((X1 + Y1) * (X2 + Y2) - A - B);
|
||
|
const F = D - C;
|
||
|
const G = D + C;
|
||
|
const H = modP(B - a * A);
|
||
|
const X3 = modP(E * F);
|
||
|
const Y3 = modP(G * H);
|
||
|
const T3 = modP(E * H);
|
||
|
const Z3 = modP(F * G);
|
||
|
return new Point(X3, Y3, Z3, T3);
|
||
|
}
|
||
|
subtract(other) {
|
||
|
return this.add(other.negate());
|
||
|
}
|
||
|
wNAF(n) {
|
||
|
return wnaf.wNAFCached(this, pointPrecomputes, n, Point.normalizeZ);
|
||
|
}
|
||
|
multiply(scalar) {
|
||
|
const { p, f } = this.wNAF(assertInRange(scalar, CURVE_ORDER));
|
||
|
return Point.normalizeZ([p, f])[0];
|
||
|
}
|
||
|
multiplyUnsafe(scalar) {
|
||
|
let n = assertGE0(scalar);
|
||
|
if (n === _0n$3)
|
||
|
return I;
|
||
|
if (this.equals(I) || n === _1n$3)
|
||
|
return this;
|
||
|
if (this.equals(G))
|
||
|
return this.wNAF(n).p;
|
||
|
return wnaf.unsafeLadder(this, n);
|
||
|
}
|
||
|
isSmallOrder() {
|
||
|
return this.multiplyUnsafe(cofactor).is0();
|
||
|
}
|
||
|
isTorsionFree() {
|
||
|
return wnaf.unsafeLadder(this, CURVE_ORDER).is0();
|
||
|
}
|
||
|
toAffine(iz) {
|
||
|
const { ex: x, ey: y, ez: z } = this;
|
||
|
const is0 = this.is0();
|
||
|
if (iz == null)
|
||
|
iz = is0 ? _8n : Fp.inv(z);
|
||
|
const ax = modP(x * iz);
|
||
|
const ay = modP(y * iz);
|
||
|
const zz = modP(z * iz);
|
||
|
if (is0)
|
||
|
return { x: _0n$3, y: _1n$3 };
|
||
|
if (zz !== _1n$3)
|
||
|
throw new Error('invZ was invalid');
|
||
|
return { x: ax, y: ay };
|
||
|
}
|
||
|
clearCofactor() {
|
||
|
const { h: cofactor } = CURVE;
|
||
|
if (cofactor === _1n$3)
|
||
|
return this;
|
||
|
return this.multiplyUnsafe(cofactor);
|
||
|
}
|
||
|
static fromHex(hex, zip215 = false) {
|
||
|
const { d, a } = CURVE;
|
||
|
const len = Fp.BYTES;
|
||
|
hex = ensureBytes('pointHex', hex, len);
|
||
|
const normed = hex.slice();
|
||
|
const lastByte = hex[len - 1];
|
||
|
normed[len - 1] = lastByte & ~0x80;
|
||
|
const y = bytesToNumberLE(normed);
|
||
|
if (y === _0n$3) ;
|
||
|
else {
|
||
|
if (zip215)
|
||
|
assertInRange(y, MASK);
|
||
|
else
|
||
|
assertInRange(y, Fp.ORDER);
|
||
|
}
|
||
|
const y2 = modP(y * y);
|
||
|
const u = modP(y2 - _1n$3);
|
||
|
const v = modP(d * y2 - a);
|
||
|
let { isValid, value: x } = uvRatio(u, v);
|
||
|
if (!isValid)
|
||
|
throw new Error('Point.fromHex: invalid y coordinate');
|
||
|
const isXOdd = (x & _1n$3) === _1n$3;
|
||
|
const isLastByteOdd = (lastByte & 0x80) !== 0;
|
||
|
if (!zip215 && x === _0n$3 && isLastByteOdd)
|
||
|
throw new Error('Point.fromHex: x=0 and x_0=1');
|
||
|
if (isLastByteOdd !== isXOdd)
|
||
|
x = modP(-x);
|
||
|
return Point.fromAffine({ x, y });
|
||
|
}
|
||
|
static fromPrivateKey(privKey) {
|
||
|
return getExtendedPublicKey(privKey).point;
|
||
|
}
|
||
|
toRawBytes() {
|
||
|
const { x, y } = this.toAffine();
|
||
|
const bytes = numberToBytesLE(y, Fp.BYTES);
|
||
|
bytes[bytes.length - 1] |= x & _1n$3 ? 0x80 : 0;
|
||
|
return bytes;
|
||
|
}
|
||
|
toHex() {
|
||
|
return bytesToHex(this.toRawBytes());
|
||
|
}
|
||
|
}
|
||
|
Point.BASE = new Point(CURVE.Gx, CURVE.Gy, _1n$3, modP(CURVE.Gx * CURVE.Gy));
|
||
|
Point.ZERO = new Point(_0n$3, _1n$3, _1n$3, _0n$3);
|
||
|
const { BASE: G, ZERO: I } = Point;
|
||
|
const wnaf = wNAF(Point, nByteLength * 8);
|
||
|
function modN(a) {
|
||
|
return mod(a, CURVE_ORDER);
|
||
|
}
|
||
|
function modN_LE(hash) {
|
||
|
return modN(bytesToNumberLE(hash));
|
||
|
}
|
||
|
function getExtendedPublicKey(key) {
|
||
|
const len = nByteLength;
|
||
|
key = ensureBytes('private key', key, len);
|
||
|
const hashed = ensureBytes('hashed private key', cHash(key), 2 * len);
|
||
|
const head = adjustScalarBytes(hashed.slice(0, len));
|
||
|
const prefix = hashed.slice(len, 2 * len);
|
||
|
const scalar = modN_LE(head);
|
||
|
const point = G.multiply(scalar);
|
||
|
const pointBytes = point.toRawBytes();
|
||
|
return { head, prefix, scalar, point, pointBytes };
|
||
|
}
|
||
|
function getPublicKey(privKey) {
|
||
|
return getExtendedPublicKey(privKey).pointBytes;
|
||
|
}
|
||
|
function hashDomainToScalar(context = new Uint8Array(), ...msgs) {
|
||
|
const msg = concatBytes(...msgs);
|
||
|
return modN_LE(cHash(domain(msg, ensureBytes('context', context), !!prehash)));
|
||
|
}
|
||
|
function sign(msg, privKey, options = {}) {
|
||
|
msg = ensureBytes('message', msg);
|
||
|
if (prehash)
|
||
|
msg = prehash(msg);
|
||
|
const { prefix, scalar, pointBytes } = getExtendedPublicKey(privKey);
|
||
|
const r = hashDomainToScalar(options.context, prefix, msg);
|
||
|
const R = G.multiply(r).toRawBytes();
|
||
|
const k = hashDomainToScalar(options.context, R, pointBytes, msg);
|
||
|
const s = modN(r + k * scalar);
|
||
|
assertGE0(s);
|
||
|
const res = concatBytes(R, numberToBytesLE(s, Fp.BYTES));
|
||
|
return ensureBytes('result', res, nByteLength * 2);
|
||
|
}
|
||
|
const verifyOpts = VERIFY_DEFAULT;
|
||
|
function verify(sig, msg, publicKey, options = verifyOpts) {
|
||
|
const { context, zip215 } = options;
|
||
|
const len = Fp.BYTES;
|
||
|
sig = ensureBytes('signature', sig, 2 * len);
|
||
|
msg = ensureBytes('message', msg);
|
||
|
if (prehash)
|
||
|
msg = prehash(msg);
|
||
|
const s = bytesToNumberLE(sig.slice(len, 2 * len));
|
||
|
let A, R, SB;
|
||
|
try {
|
||
|
A = Point.fromHex(publicKey, zip215);
|
||
|
R = Point.fromHex(sig.slice(0, len), zip215);
|
||
|
SB = G.multiplyUnsafe(s);
|
||
|
}
|
||
|
catch (error) {
|
||
|
return false;
|
||
|
}
|
||
|
if (!zip215 && A.isSmallOrder())
|
||
|
return false;
|
||
|
const k = hashDomainToScalar(context, R.toRawBytes(), A.toRawBytes(), msg);
|
||
|
const RkA = R.add(A.multiplyUnsafe(k));
|
||
|
return RkA.subtract(SB).clearCofactor().equals(Point.ZERO);
|
||
|
}
|
||
|
G._setWindowSize(8);
|
||
|
const utils = {
|
||
|
getExtendedPublicKey,
|
||
|
randomPrivateKey: () => randomBytes(Fp.BYTES),
|
||
|
precompute(windowSize = 8, point = Point.BASE) {
|
||
|
point._setWindowSize(windowSize);
|
||
|
point.multiply(BigInt(3));
|
||
|
return point;
|
||
|
},
|
||
|
};
|
||
|
return {
|
||
|
CURVE,
|
||
|
getPublicKey,
|
||
|
sign,
|
||
|
verify,
|
||
|
ExtendedPoint: Point,
|
||
|
utils,
|
||
|
};
|
||
|
}
|
||
|
|
||
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||
|
const _0n$2 = BigInt(0);
|
||
|
const _1n$2 = BigInt(1);
|
||
|
function validateOpts(curve) {
|
||
|
validateObject(curve, {
|
||
|
a: 'bigint',
|
||
|
}, {
|
||
|
montgomeryBits: 'isSafeInteger',
|
||
|
nByteLength: 'isSafeInteger',
|
||
|
adjustScalarBytes: 'function',
|
||
|
domain: 'function',
|
||
|
powPminus2: 'function',
|
||
|
Gu: 'bigint',
|
||
|
});
|
||
|
return Object.freeze({ ...curve });
|
||
|
}
|
||
|
function montgomery(curveDef) {
|
||
|
const CURVE = validateOpts(curveDef);
|
||
|
const { P } = CURVE;
|
||
|
const modP = (n) => mod(n, P);
|
||
|
const montgomeryBits = CURVE.montgomeryBits;
|
||
|
const montgomeryBytes = Math.ceil(montgomeryBits / 8);
|
||
|
const fieldLen = CURVE.nByteLength;
|
||
|
const adjustScalarBytes = CURVE.adjustScalarBytes || ((bytes) => bytes);
|
||
|
const powPminus2 = CURVE.powPminus2 || ((x) => pow(x, P - BigInt(2), P));
|
||
|
function cswap(swap, x_2, x_3) {
|
||
|
const dummy = modP(swap * (x_2 - x_3));
|
||
|
x_2 = modP(x_2 - dummy);
|
||
|
x_3 = modP(x_3 + dummy);
|
||
|
return [x_2, x_3];
|
||
|
}
|
||
|
function assertFieldElement(n) {
|
||
|
if (typeof n === 'bigint' && _0n$2 <= n && n < P)
|
||
|
return n;
|
||
|
throw new Error('Expected valid scalar 0 < scalar < CURVE.P');
|
||
|
}
|
||
|
const a24 = (CURVE.a - BigInt(2)) / BigInt(4);
|
||
|
function montgomeryLadder(pointU, scalar) {
|
||
|
const u = assertFieldElement(pointU);
|
||
|
const k = assertFieldElement(scalar);
|
||
|
const x_1 = u;
|
||
|
let x_2 = _1n$2;
|
||
|
let z_2 = _0n$2;
|
||
|
let x_3 = u;
|
||
|
let z_3 = _1n$2;
|
||
|
let swap = _0n$2;
|
||
|
let sw;
|
||
|
for (let t = BigInt(montgomeryBits - 1); t >= _0n$2; t--) {
|
||
|
const k_t = (k >> t) & _1n$2;
|
||
|
swap ^= k_t;
|
||
|
sw = cswap(swap, x_2, x_3);
|
||
|
x_2 = sw[0];
|
||
|
x_3 = sw[1];
|
||
|
sw = cswap(swap, z_2, z_3);
|
||
|
z_2 = sw[0];
|
||
|
z_3 = sw[1];
|
||
|
swap = k_t;
|
||
|
const A = x_2 + z_2;
|
||
|
const AA = modP(A * A);
|
||
|
const B = x_2 - z_2;
|
||
|
const BB = modP(B * B);
|
||
|
const E = AA - BB;
|
||
|
const C = x_3 + z_3;
|
||
|
const D = x_3 - z_3;
|
||
|
const DA = modP(D * A);
|
||
|
const CB = modP(C * B);
|
||
|
const dacb = DA + CB;
|
||
|
const da_cb = DA - CB;
|
||
|
x_3 = modP(dacb * dacb);
|
||
|
z_3 = modP(x_1 * modP(da_cb * da_cb));
|
||
|
x_2 = modP(AA * BB);
|
||
|
z_2 = modP(E * (AA + modP(a24 * E)));
|
||
|
}
|
||
|
sw = cswap(swap, x_2, x_3);
|
||
|
x_2 = sw[0];
|
||
|
x_3 = sw[1];
|
||
|
sw = cswap(swap, z_2, z_3);
|
||
|
z_2 = sw[0];
|
||
|
z_3 = sw[1];
|
||
|
const z2 = powPminus2(z_2);
|
||
|
return modP(x_2 * z2);
|
||
|
}
|
||
|
function encodeUCoordinate(u) {
|
||
|
return numberToBytesLE(modP(u), montgomeryBytes);
|
||
|
}
|
||
|
function decodeUCoordinate(uEnc) {
|
||
|
const u = ensureBytes('u coordinate', uEnc, montgomeryBytes);
|
||
|
if (fieldLen === montgomeryBytes)
|
||
|
u[fieldLen - 1] &= 127;
|
||
|
return bytesToNumberLE(u);
|
||
|
}
|
||
|
function decodeScalar(n) {
|
||
|
const bytes = ensureBytes('scalar', n);
|
||
|
if (bytes.length !== montgomeryBytes && bytes.length !== fieldLen)
|
||
|
throw new Error(`Expected ${montgomeryBytes} or ${fieldLen} bytes, got ${bytes.length}`);
|
||
|
return bytesToNumberLE(adjustScalarBytes(bytes));
|
||
|
}
|
||
|
function scalarMult(scalar, u) {
|
||
|
const pointU = decodeUCoordinate(u);
|
||
|
const _scalar = decodeScalar(scalar);
|
||
|
const pu = montgomeryLadder(pointU, _scalar);
|
||
|
if (pu === _0n$2)
|
||
|
throw new Error('Invalid private or public key received');
|
||
|
return encodeUCoordinate(pu);
|
||
|
}
|
||
|
const GuBytes = encodeUCoordinate(CURVE.Gu);
|
||
|
function scalarMultBase(scalar) {
|
||
|
return scalarMult(scalar, GuBytes);
|
||
|
}
|
||
|
return {
|
||
|
scalarMult,
|
||
|
scalarMultBase,
|
||
|
getSharedSecret: (privateKey, publicKey) => scalarMult(privateKey, publicKey),
|
||
|
getPublicKey: (privateKey) => scalarMultBase(privateKey),
|
||
|
utils: { randomPrivateKey: () => CURVE.randomBytes(CURVE.nByteLength) },
|
||
|
GuBytes: GuBytes,
|
||
|
};
|
||
|
}
|
||
|
|
||
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||
|
const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
|
||
|
const ED25519_SQRT_M1 = BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
|
||
|
const _0n$1 = BigInt(0), _1n$1 = BigInt(1), _2n$1 = BigInt(2), _5n = BigInt(5);
|
||
|
const _10n = BigInt(10), _20n = BigInt(20), _40n = BigInt(40), _80n = BigInt(80);
|
||
|
function ed25519_pow_2_252_3(x) {
|
||
|
const P = ED25519_P;
|
||
|
const x2 = (x * x) % P;
|
||
|
const b2 = (x2 * x) % P;
|
||
|
const b4 = (pow2(b2, _2n$1, P) * b2) % P;
|
||
|
const b5 = (pow2(b4, _1n$1, P) * x) % P;
|
||
|
const b10 = (pow2(b5, _5n, P) * b5) % P;
|
||
|
const b20 = (pow2(b10, _10n, P) * b10) % P;
|
||
|
const b40 = (pow2(b20, _20n, P) * b20) % P;
|
||
|
const b80 = (pow2(b40, _40n, P) * b40) % P;
|
||
|
const b160 = (pow2(b80, _80n, P) * b80) % P;
|
||
|
const b240 = (pow2(b160, _80n, P) * b80) % P;
|
||
|
const b250 = (pow2(b240, _10n, P) * b10) % P;
|
||
|
const pow_p_5_8 = (pow2(b250, _2n$1, P) * x) % P;
|
||
|
return { pow_p_5_8, b2 };
|
||
|
}
|
||
|
function adjustScalarBytes(bytes) {
|
||
|
bytes[0] &= 248;
|
||
|
bytes[31] &= 127;
|
||
|
bytes[31] |= 64;
|
||
|
return bytes;
|
||
|
}
|
||
|
function uvRatio(u, v) {
|
||
|
const P = ED25519_P;
|
||
|
const v3 = mod(v * v * v, P);
|
||
|
const v7 = mod(v3 * v3 * v, P);
|
||
|
const pow = ed25519_pow_2_252_3(u * v7).pow_p_5_8;
|
||
|
let x = mod(u * v3 * pow, P);
|
||
|
const vx2 = mod(v * x * x, P);
|
||
|
const root1 = x;
|
||
|
const root2 = mod(x * ED25519_SQRT_M1, P);
|
||
|
const useRoot1 = vx2 === u;
|
||
|
const useRoot2 = vx2 === mod(-u, P);
|
||
|
const noRoot = vx2 === mod(-u * ED25519_SQRT_M1, P);
|
||
|
if (useRoot1)
|
||
|
x = root1;
|
||
|
if (useRoot2 || noRoot)
|
||
|
x = root2;
|
||
|
if (isNegativeLE(x, P))
|
||
|
x = mod(-x, P);
|
||
|
return { isValid: useRoot1 || useRoot2, value: x };
|
||
|
}
|
||
|
const Fp = Field(ED25519_P, undefined, true);
|
||
|
const ed25519Defaults = {
|
||
|
a: BigInt(-1),
|
||
|
d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
|
||
|
Fp,
|
||
|
n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
|
||
|
h: BigInt(8),
|
||
|
Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
|
||
|
Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
|
||
|
hash: sha512,
|
||
|
randomBytes,
|
||
|
adjustScalarBytes,
|
||
|
uvRatio,
|
||
|
};
|
||
|
const ed25519 = twistedEdwards(ed25519Defaults);
|
||
|
function ed25519_domain(data, ctx, phflag) {
|
||
|
if (ctx.length > 255)
|
||
|
throw new Error('Context is too big');
|
||
|
return concatBytes$1(utf8ToBytes$1('SigEd25519 no Ed25519 collisions'), new Uint8Array([phflag ? 1 : 0, ctx.length]), ctx, data);
|
||
|
}
|
||
|
twistedEdwards({
|
||
|
...ed25519Defaults,
|
||
|
domain: ed25519_domain,
|
||
|
});
|
||
|
twistedEdwards({
|
||
|
...ed25519Defaults,
|
||
|
domain: ed25519_domain,
|
||
|
prehash: sha512,
|
||
|
});
|
||
|
(() => montgomery({
|
||
|
P: ED25519_P,
|
||
|
a: BigInt(486662),
|
||
|
montgomeryBits: 255,
|
||
|
nByteLength: 32,
|
||
|
Gu: BigInt(9),
|
||
|
powPminus2: (x) => {
|
||
|
const P = ED25519_P;
|
||
|
const { pow_p_5_8, b2 } = ed25519_pow_2_252_3(x);
|
||
|
return mod(pow2(pow_p_5_8, BigInt(3), P) * b2, P);
|
||
|
},
|
||
|
adjustScalarBytes,
|
||
|
randomBytes,
|
||
|
}))();
|
||
|
const ELL2_C1 = (Fp.ORDER + BigInt(3)) / BigInt(8);
|
||
|
const ELL2_C2 = Fp.pow(_2n$1, ELL2_C1);
|
||
|
const ELL2_C3 = Fp.sqrt(Fp.neg(Fp.ONE));
|
||
|
const ELL2_C4 = (Fp.ORDER - BigInt(5)) / BigInt(8);
|
||
|
const ELL2_J = BigInt(486662);
|
||
|
function map_to_curve_elligator2_curve25519(u) {
|
||
|
let tv1 = Fp.sqr(u);
|
||
|
tv1 = Fp.mul(tv1, _2n$1);
|
||
|
let xd = Fp.add(tv1, Fp.ONE);
|
||
|
let x1n = Fp.neg(ELL2_J);
|
||
|
let tv2 = Fp.sqr(xd);
|
||
|
let gxd = Fp.mul(tv2, xd);
|
||
|
let gx1 = Fp.mul(tv1, ELL2_J);
|
||
|
gx1 = Fp.mul(gx1, x1n);
|
||
|
gx1 = Fp.add(gx1, tv2);
|
||
|
gx1 = Fp.mul(gx1, x1n);
|
||
|
let tv3 = Fp.sqr(gxd);
|
||
|
tv2 = Fp.sqr(tv3);
|
||
|
tv3 = Fp.mul(tv3, gxd);
|
||
|
tv3 = Fp.mul(tv3, gx1);
|
||
|
tv2 = Fp.mul(tv2, tv3);
|
||
|
let y11 = Fp.pow(tv2, ELL2_C4);
|
||
|
y11 = Fp.mul(y11, tv3);
|
||
|
let y12 = Fp.mul(y11, ELL2_C3);
|
||
|
tv2 = Fp.sqr(y11);
|
||
|
tv2 = Fp.mul(tv2, gxd);
|
||
|
let e1 = Fp.eql(tv2, gx1);
|
||
|
let y1 = Fp.cmov(y12, y11, e1);
|
||
|
let x2n = Fp.mul(x1n, tv1);
|
||
|
let y21 = Fp.mul(y11, u);
|
||
|
y21 = Fp.mul(y21, ELL2_C2);
|
||
|
let y22 = Fp.mul(y21, ELL2_C3);
|
||
|
let gx2 = Fp.mul(gx1, tv1);
|
||
|
tv2 = Fp.sqr(y21);
|
||
|
tv2 = Fp.mul(tv2, gxd);
|
||
|
let e2 = Fp.eql(tv2, gx2);
|
||
|
let y2 = Fp.cmov(y22, y21, e2);
|
||
|
tv2 = Fp.sqr(y1);
|
||
|
tv2 = Fp.mul(tv2, gxd);
|
||
|
let e3 = Fp.eql(tv2, gx1);
|
||
|
let xn = Fp.cmov(x2n, x1n, e3);
|
||
|
let y = Fp.cmov(y2, y1, e3);
|
||
|
let e4 = Fp.isOdd(y);
|
||
|
y = Fp.cmov(y, Fp.neg(y), e3 !== e4);
|
||
|
return { xMn: xn, xMd: xd, yMn: y, yMd: _1n$1 };
|
||
|
}
|
||
|
const ELL2_C1_EDWARDS = FpSqrtEven(Fp, Fp.neg(BigInt(486664)));
|
||
|
function map_to_curve_elligator2_edwards25519(u) {
|
||
|
const { xMn, xMd, yMn, yMd } = map_to_curve_elligator2_curve25519(u);
|
||
|
let xn = Fp.mul(xMn, yMd);
|
||
|
xn = Fp.mul(xn, ELL2_C1_EDWARDS);
|
||
|
let xd = Fp.mul(xMd, yMn);
|
||
|
let yn = Fp.sub(xMn, xMd);
|
||
|
let yd = Fp.add(xMn, xMd);
|
||
|
let tv1 = Fp.mul(xd, yd);
|
||
|
let e = Fp.eql(tv1, Fp.ZERO);
|
||
|
xn = Fp.cmov(xn, Fp.ZERO, e);
|
||
|
xd = Fp.cmov(xd, Fp.ONE, e);
|
||
|
yn = Fp.cmov(yn, Fp.ONE, e);
|
||
|
yd = Fp.cmov(yd, Fp.ONE, e);
|
||
|
const inv = Fp.invertBatch([xd, yd]);
|
||
|
return { x: Fp.mul(xn, inv[0]), y: Fp.mul(yn, inv[1]) };
|
||
|
}
|
||
|
(() => createHasher(ed25519.ExtendedPoint, (scalars) => map_to_curve_elligator2_edwards25519(scalars[0]), {
|
||
|
DST: 'edwards25519_XMD:SHA-512_ELL2_RO_',
|
||
|
encodeDST: 'edwards25519_XMD:SHA-512_ELL2_NU_',
|
||
|
p: Fp.ORDER,
|
||
|
m: 1,
|
||
|
k: 128,
|
||
|
expand: 'xmd',
|
||
|
hash: sha512,
|
||
|
}))();
|
||
|
function assertRstPoint(other) {
|
||
|
if (!(other instanceof RistPoint))
|
||
|
throw new Error('RistrettoPoint expected');
|
||
|
}
|
||
|
const SQRT_M1 = ED25519_SQRT_M1;
|
||
|
const SQRT_AD_MINUS_ONE = BigInt('25063068953384623474111414158702152701244531502492656460079210482610430750235');
|
||
|
const INVSQRT_A_MINUS_D = BigInt('54469307008909316920995813868745141605393597292927456921205312896311721017578');
|
||
|
const ONE_MINUS_D_SQ = BigInt('1159843021668779879193775521855586647937357759715417654439879720876111806838');
|
||
|
const D_MINUS_ONE_SQ = BigInt('40440834346308536858101042469323190826248399146238708352240133220865137265952');
|
||
|
const invertSqrt = (number) => uvRatio(_1n$1, number);
|
||
|
const MAX_255B = BigInt('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
|
||
|
const bytes255ToNumberLE = (bytes) => ed25519.CURVE.Fp.create(bytesToNumberLE(bytes) & MAX_255B);
|
||
|
function calcElligatorRistrettoMap(r0) {
|
||
|
const { d } = ed25519.CURVE;
|
||
|
const P = ed25519.CURVE.Fp.ORDER;
|
||
|
const mod = ed25519.CURVE.Fp.create;
|
||
|
const r = mod(SQRT_M1 * r0 * r0);
|
||
|
const Ns = mod((r + _1n$1) * ONE_MINUS_D_SQ);
|
||
|
let c = BigInt(-1);
|
||
|
const D = mod((c - d * r) * mod(r + d));
|
||
|
let { isValid: Ns_D_is_sq, value: s } = uvRatio(Ns, D);
|
||
|
let s_ = mod(s * r0);
|
||
|
if (!isNegativeLE(s_, P))
|
||
|
s_ = mod(-s_);
|
||
|
if (!Ns_D_is_sq)
|
||
|
s = s_;
|
||
|
if (!Ns_D_is_sq)
|
||
|
c = r;
|
||
|
const Nt = mod(c * (r - _1n$1) * D_MINUS_ONE_SQ - D);
|
||
|
const s2 = s * s;
|
||
|
const W0 = mod((s + s) * D);
|
||
|
const W1 = mod(Nt * SQRT_AD_MINUS_ONE);
|
||
|
const W2 = mod(_1n$1 - s2);
|
||
|
const W3 = mod(_1n$1 + s2);
|
||
|
return new ed25519.ExtendedPoint(mod(W0 * W3), mod(W2 * W1), mod(W1 * W3), mod(W0 * W2));
|
||
|
}
|
||
|
class RistPoint {
|
||
|
constructor(ep) {
|
||
|
this.ep = ep;
|
||
|
}
|
||
|
static fromAffine(ap) {
|
||
|
return new RistPoint(ed25519.ExtendedPoint.fromAffine(ap));
|
||
|
}
|
||
|
static hashToCurve(hex) {
|
||
|
hex = ensureBytes('ristrettoHash', hex, 64);
|
||
|
const r1 = bytes255ToNumberLE(hex.slice(0, 32));
|
||
|
const R1 = calcElligatorRistrettoMap(r1);
|
||
|
const r2 = bytes255ToNumberLE(hex.slice(32, 64));
|
||
|
const R2 = calcElligatorRistrettoMap(r2);
|
||
|
return new RistPoint(R1.add(R2));
|
||
|
}
|
||
|
static fromHex(hex) {
|
||
|
hex = ensureBytes('ristrettoHex', hex, 32);
|
||
|
const { a, d } = ed25519.CURVE;
|
||
|
const P = ed25519.CURVE.Fp.ORDER;
|
||
|
const mod = ed25519.CURVE.Fp.create;
|
||
|
const emsg = 'RistrettoPoint.fromHex: the hex is not valid encoding of RistrettoPoint';
|
||
|
const s = bytes255ToNumberLE(hex);
|
||
|
if (!equalBytes(numberToBytesLE(s, 32), hex) || isNegativeLE(s, P))
|
||
|
throw new Error(emsg);
|
||
|
const s2 = mod(s * s);
|
||
|
const u1 = mod(_1n$1 + a * s2);
|
||
|
const u2 = mod(_1n$1 - a * s2);
|
||
|
const u1_2 = mod(u1 * u1);
|
||
|
const u2_2 = mod(u2 * u2);
|
||
|
const v = mod(a * d * u1_2 - u2_2);
|
||
|
const { isValid, value: I } = invertSqrt(mod(v * u2_2));
|
||
|
const Dx = mod(I * u2);
|
||
|
const Dy = mod(I * Dx * v);
|
||
|
let x = mod((s + s) * Dx);
|
||
|
if (isNegativeLE(x, P))
|
||
|
x = mod(-x);
|
||
|
const y = mod(u1 * Dy);
|
||
|
const t = mod(x * y);
|
||
|
if (!isValid || isNegativeLE(t, P) || y === _0n$1)
|
||
|
throw new Error(emsg);
|
||
|
return new RistPoint(new ed25519.ExtendedPoint(x, y, _1n$1, t));
|
||
|
}
|
||
|
toRawBytes() {
|
||
|
let { ex: x, ey: y, ez: z, et: t } = this.ep;
|
||
|
const P = ed25519.CURVE.Fp.ORDER;
|
||
|
const mod = ed25519.CURVE.Fp.create;
|
||
|
const u1 = mod(mod(z + y) * mod(z - y));
|
||
|
const u2 = mod(x * y);
|
||
|
const u2sq = mod(u2 * u2);
|
||
|
const { value: invsqrt } = invertSqrt(mod(u1 * u2sq));
|
||
|
const D1 = mod(invsqrt * u1);
|
||
|
const D2 = mod(invsqrt * u2);
|
||
|
const zInv = mod(D1 * D2 * t);
|
||
|
let D;
|
||
|
if (isNegativeLE(t * zInv, P)) {
|
||
|
let _x = mod(y * SQRT_M1);
|
||
|
let _y = mod(x * SQRT_M1);
|
||
|
x = _x;
|
||
|
y = _y;
|
||
|
D = mod(D1 * INVSQRT_A_MINUS_D);
|
||
|
}
|
||
|
else {
|
||
|
D = D2;
|
||
|
}
|
||
|
if (isNegativeLE(x * zInv, P))
|
||
|
y = mod(-y);
|
||
|
let s = mod((z - y) * D);
|
||
|
if (isNegativeLE(s, P))
|
||
|
s = mod(-s);
|
||
|
return numberToBytesLE(s, 32);
|
||
|
}
|
||
|
toHex() {
|
||
|
return bytesToHex(this.toRawBytes());
|
||
|
}
|
||
|
toString() {
|
||
|
return this.toHex();
|
||
|
}
|
||
|
equals(other) {
|
||
|
assertRstPoint(other);
|
||
|
const { ex: X1, ey: Y1 } = this.ep;
|
||
|
const { ex: X2, ey: Y2 } = other.ep;
|
||
|
const mod = ed25519.CURVE.Fp.create;
|
||
|
const one = mod(X1 * Y2) === mod(Y1 * X2);
|
||
|
const two = mod(Y1 * Y2) === mod(X1 * X2);
|
||
|
return one || two;
|
||
|
}
|
||
|
add(other) {
|
||
|
assertRstPoint(other);
|
||
|
return new RistPoint(this.ep.add(other.ep));
|
||
|
}
|
||
|
subtract(other) {
|
||
|
assertRstPoint(other);
|
||
|
return new RistPoint(this.ep.subtract(other.ep));
|
||
|
}
|
||
|
multiply(scalar) {
|
||
|
return new RistPoint(this.ep.multiply(scalar));
|
||
|
}
|
||
|
multiplyUnsafe(scalar) {
|
||
|
return new RistPoint(this.ep.multiplyUnsafe(scalar));
|
||
|
}
|
||
|
}
|
||
|
(() => {
|
||
|
if (!RistPoint.BASE)
|
||
|
RistPoint.BASE = new RistPoint(ed25519.ExtendedPoint.BASE);
|
||
|
if (!RistPoint.ZERO)
|
||
|
RistPoint.ZERO = new RistPoint(ed25519.ExtendedPoint.ZERO);
|
||
|
return RistPoint;
|
||
|
})();
|
||
|
|
||
|
function ed25519PairFromSeed(seed, onlyJs) {
|
||
|
if (!util.hasBigInt || (!onlyJs && isReady())) {
|
||
|
const full = ed25519KeypairFromSeed(seed);
|
||
|
return {
|
||
|
publicKey: full.slice(32),
|
||
|
secretKey: full.slice(0, 64)
|
||
|
};
|
||
|
}
|
||
|
const publicKey = ed25519.getPublicKey(seed);
|
||
|
return {
|
||
|
publicKey,
|
||
|
secretKey: util.u8aConcatStrict([seed, publicKey])
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function ed25519PairFromRandom() {
|
||
|
return ed25519PairFromSeed(randomAsU8a());
|
||
|
}
|
||
|
|
||
|
function ed25519PairFromSecret(secretKey) {
|
||
|
if (secretKey.length !== 64) {
|
||
|
throw new Error('Invalid secretKey provided');
|
||
|
}
|
||
|
return {
|
||
|
publicKey: secretKey.slice(32),
|
||
|
secretKey
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function ed25519PairFromString(value) {
|
||
|
return ed25519PairFromSeed(blake2AsU8a(util.stringToU8a(value)));
|
||
|
}
|
||
|
|
||
|
function ed25519Sign(message, { publicKey, secretKey }, onlyJs) {
|
||
|
if (!secretKey) {
|
||
|
throw new Error('Expected a valid secretKey');
|
||
|
}
|
||
|
else if (!publicKey) {
|
||
|
throw new Error('Expected a valid publicKey');
|
||
|
}
|
||
|
const messageU8a = util.u8aToU8a(message);
|
||
|
const privateU8a = secretKey.subarray(0, 32);
|
||
|
return !util.hasBigInt || (!onlyJs && isReady())
|
||
|
? ed25519Sign$1(publicKey, privateU8a, messageU8a)
|
||
|
: ed25519.sign(messageU8a, privateU8a);
|
||
|
}
|
||
|
|
||
|
function ed25519Verify(message, signature, publicKey, onlyJs) {
|
||
|
const messageU8a = util.u8aToU8a(message);
|
||
|
const publicKeyU8a = util.u8aToU8a(publicKey);
|
||
|
const signatureU8a = util.u8aToU8a(signature);
|
||
|
if (publicKeyU8a.length !== 32) {
|
||
|
throw new Error(`Invalid publicKey, received ${publicKeyU8a.length}, expected 32`);
|
||
|
}
|
||
|
else if (signatureU8a.length !== 64) {
|
||
|
throw new Error(`Invalid signature, received ${signatureU8a.length} bytes, expected 64`);
|
||
|
}
|
||
|
try {
|
||
|
return !util.hasBigInt || (!onlyJs && isReady())
|
||
|
? ed25519Verify$1(signatureU8a, messageU8a, publicKeyU8a)
|
||
|
: ed25519.verify(signatureU8a, messageU8a, publicKeyU8a);
|
||
|
}
|
||
|
catch {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
const keyHdkdEd25519 = createSeedDeriveFn(ed25519PairFromSeed, ed25519DeriveHard);
|
||
|
|
||
|
const SEC_LEN = 64;
|
||
|
const PUB_LEN = 32;
|
||
|
const TOT_LEN = SEC_LEN + PUB_LEN;
|
||
|
function sr25519PairFromU8a(full) {
|
||
|
const fullU8a = util.u8aToU8a(full);
|
||
|
if (fullU8a.length !== TOT_LEN) {
|
||
|
throw new Error(`Expected keypair with ${TOT_LEN} bytes, found ${fullU8a.length}`);
|
||
|
}
|
||
|
return {
|
||
|
publicKey: fullU8a.slice(SEC_LEN, TOT_LEN),
|
||
|
secretKey: fullU8a.slice(0, SEC_LEN)
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function sr25519KeypairToU8a({ publicKey, secretKey }) {
|
||
|
return util.u8aConcat(secretKey, publicKey).slice();
|
||
|
}
|
||
|
|
||
|
function createDeriveFn(derive) {
|
||
|
return (keypair, chainCode) => {
|
||
|
if (!util.isU8a(chainCode) || chainCode.length !== 32) {
|
||
|
throw new Error('Invalid chainCode passed to derive');
|
||
|
}
|
||
|
return sr25519PairFromU8a(derive(sr25519KeypairToU8a(keypair), chainCode));
|
||
|
};
|
||
|
}
|
||
|
|
||
|
const sr25519DeriveHard = createDeriveFn(sr25519DeriveKeypairHard);
|
||
|
|
||
|
const sr25519DeriveSoft = createDeriveFn(sr25519DeriveKeypairSoft);
|
||
|
|
||
|
function keyHdkdSr25519(keypair, { chainCode, isSoft }) {
|
||
|
return isSoft
|
||
|
? sr25519DeriveSoft(keypair, chainCode)
|
||
|
: sr25519DeriveHard(keypair, chainCode);
|
||
|
}
|
||
|
|
||
|
const generators = {
|
||
|
ecdsa: keyHdkdEcdsa,
|
||
|
ed25519: keyHdkdEd25519,
|
||
|
ethereum: keyHdkdEcdsa,
|
||
|
sr25519: keyHdkdSr25519
|
||
|
};
|
||
|
function keyFromPath(pair, path, type) {
|
||
|
const keyHdkd = generators[type];
|
||
|
let result = pair;
|
||
|
for (const junction of path) {
|
||
|
result = keyHdkd(result, junction);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
function sr25519Agreement(secretKey, publicKey) {
|
||
|
const secretKeyU8a = util.u8aToU8a(secretKey);
|
||
|
const publicKeyU8a = util.u8aToU8a(publicKey);
|
||
|
if (publicKeyU8a.length !== 32) {
|
||
|
throw new Error(`Invalid publicKey, received ${publicKeyU8a.length} bytes, expected 32`);
|
||
|
}
|
||
|
else if (secretKeyU8a.length !== 64) {
|
||
|
throw new Error(`Invalid secretKey, received ${secretKeyU8a.length} bytes, expected 64`);
|
||
|
}
|
||
|
return sr25519Agree(publicKeyU8a, secretKeyU8a);
|
||
|
}
|
||
|
|
||
|
function sr25519DerivePublic(publicKey, chainCode) {
|
||
|
const publicKeyU8a = util.u8aToU8a(publicKey);
|
||
|
if (!util.isU8a(chainCode) || chainCode.length !== 32) {
|
||
|
throw new Error('Invalid chainCode passed to derive');
|
||
|
}
|
||
|
else if (publicKeyU8a.length !== 32) {
|
||
|
throw new Error(`Invalid publicKey, received ${publicKeyU8a.length} bytes, expected 32`);
|
||
|
}
|
||
|
return sr25519DerivePublicSoft(publicKeyU8a, chainCode);
|
||
|
}
|
||
|
|
||
|
function sr25519PairFromSeed(seed) {
|
||
|
const seedU8a = util.u8aToU8a(seed);
|
||
|
if (seedU8a.length !== 32) {
|
||
|
throw new Error(`Expected a seed matching 32 bytes, found ${seedU8a.length}`);
|
||
|
}
|
||
|
return sr25519PairFromU8a(sr25519KeypairFromSeed(seedU8a));
|
||
|
}
|
||
|
|
||
|
function sr25519Sign(message, { publicKey, secretKey }) {
|
||
|
if (publicKey?.length !== 32) {
|
||
|
throw new Error('Expected a valid publicKey, 32-bytes');
|
||
|
}
|
||
|
else if (secretKey?.length !== 64) {
|
||
|
throw new Error('Expected a valid secretKey, 64-bytes');
|
||
|
}
|
||
|
return sr25519Sign$1(publicKey, secretKey, util.u8aToU8a(message));
|
||
|
}
|
||
|
|
||
|
function sr25519Verify(message, signature, publicKey) {
|
||
|
const publicKeyU8a = util.u8aToU8a(publicKey);
|
||
|
const signatureU8a = util.u8aToU8a(signature);
|
||
|
if (publicKeyU8a.length !== 32) {
|
||
|
throw new Error(`Invalid publicKey, received ${publicKeyU8a.length} bytes, expected 32`);
|
||
|
}
|
||
|
else if (signatureU8a.length !== 64) {
|
||
|
throw new Error(`Invalid signature, received ${signatureU8a.length} bytes, expected 64`);
|
||
|
}
|
||
|
return sr25519Verify$1(signatureU8a, util.u8aToU8a(message), publicKeyU8a);
|
||
|
}
|
||
|
|
||
|
const EMPTY_U8A$1 = new Uint8Array();
|
||
|
function sr25519VrfSign(message, { secretKey }, context = EMPTY_U8A$1, extra = EMPTY_U8A$1) {
|
||
|
if (secretKey?.length !== 64) {
|
||
|
throw new Error('Invalid secretKey, expected 64-bytes');
|
||
|
}
|
||
|
return vrfSign(secretKey, util.u8aToU8a(context), util.u8aToU8a(message), util.u8aToU8a(extra));
|
||
|
}
|
||
|
|
||
|
const EMPTY_U8A = new Uint8Array();
|
||
|
function sr25519VrfVerify(message, signOutput, publicKey, context = EMPTY_U8A, extra = EMPTY_U8A) {
|
||
|
const publicKeyU8a = util.u8aToU8a(publicKey);
|
||
|
const proofU8a = util.u8aToU8a(signOutput);
|
||
|
if (publicKeyU8a.length !== 32) {
|
||
|
throw new Error('Invalid publicKey, expected 32-bytes');
|
||
|
}
|
||
|
else if (proofU8a.length !== 96) {
|
||
|
throw new Error('Invalid vrfSign output, expected 96 bytes');
|
||
|
}
|
||
|
return vrfVerify(publicKeyU8a, util.u8aToU8a(context), util.u8aToU8a(message), util.u8aToU8a(extra), proofU8a);
|
||
|
}
|
||
|
|
||
|
function encodeAddress(key, ss58Format = defaults.prefix) {
|
||
|
const u8a = decodeAddress(key);
|
||
|
if ((ss58Format < 0) || (ss58Format > 16383) || [46, 47].includes(ss58Format)) {
|
||
|
throw new Error('Out of range ss58Format specified');
|
||
|
}
|
||
|
else if (!defaults.allowedDecodedLengths.includes(u8a.length)) {
|
||
|
throw new Error(`Expected a valid key to convert, with length ${defaults.allowedDecodedLengths.join(', ')}`);
|
||
|
}
|
||
|
const input = util.u8aConcat(ss58Format < 64
|
||
|
? [ss58Format]
|
||
|
: [
|
||
|
((ss58Format & 252) >> 2) | 64,
|
||
|
(ss58Format >> 8) | ((ss58Format & 3) << 6)
|
||
|
], u8a);
|
||
|
return base58Encode(util.u8aConcat(input, sshash(input).subarray(0, [32, 33].includes(u8a.length) ? 2 : 1)));
|
||
|
}
|
||
|
|
||
|
function filterHard({ isHard }) {
|
||
|
return isHard;
|
||
|
}
|
||
|
function deriveAddress(who, suri, ss58Format) {
|
||
|
const { path } = keyExtractPath(suri);
|
||
|
if (!path.length || path.every(filterHard)) {
|
||
|
throw new Error('Expected suri to contain a combination of non-hard paths');
|
||
|
}
|
||
|
let publicKey = decodeAddress(who);
|
||
|
for (const { chainCode } of path) {
|
||
|
publicKey = sr25519DerivePublic(publicKey, chainCode);
|
||
|
}
|
||
|
return encodeAddress(publicKey, ss58Format);
|
||
|
}
|
||
|
|
||
|
const PREFIX$1 = util.stringToU8a('modlpy/utilisuba');
|
||
|
function createKeyDerived(who, index) {
|
||
|
return blake2AsU8a(util.u8aConcat(PREFIX$1, decodeAddress(who), util.bnToU8a(index, BN_LE_16_OPTS)));
|
||
|
}
|
||
|
|
||
|
function encodeDerivedAddress(who, index, ss58Format) {
|
||
|
return encodeAddress(createKeyDerived(decodeAddress(who), index), ss58Format);
|
||
|
}
|
||
|
|
||
|
function addressToU8a(who) {
|
||
|
return decodeAddress(who);
|
||
|
}
|
||
|
|
||
|
const PREFIX = util.stringToU8a('modlpy/utilisuba');
|
||
|
function createKeyMulti(who, threshold) {
|
||
|
return blake2AsU8a(util.u8aConcat(PREFIX, util.compactToU8a(who.length), ...util.u8aSorted(who.map(addressToU8a)), util.bnToU8a(threshold, BN_LE_16_OPTS)));
|
||
|
}
|
||
|
|
||
|
function encodeMultiAddress(who, threshold, ss58Format) {
|
||
|
return encodeAddress(createKeyMulti(who, threshold), ss58Format);
|
||
|
}
|
||
|
|
||
|
function addressEq(a, b) {
|
||
|
return util.u8aEq(decodeAddress(a), decodeAddress(b));
|
||
|
}
|
||
|
|
||
|
const [SHA3_PI, SHA3_ROTL, _SHA3_IOTA] = [[], [], []];
|
||
|
const _0n = BigInt(0);
|
||
|
const _1n = BigInt(1);
|
||
|
const _2n = BigInt(2);
|
||
|
const _7n$1 = BigInt(7);
|
||
|
const _256n$1 = BigInt(256);
|
||
|
const _0x71n = BigInt(0x71);
|
||
|
for (let round = 0, R = _1n, x = 1, y = 0; round < 24; round++) {
|
||
|
[x, y] = [y, (2 * x + 3 * y) % 5];
|
||
|
SHA3_PI.push(2 * (5 * y + x));
|
||
|
SHA3_ROTL.push((((round + 1) * (round + 2)) / 2) % 64);
|
||
|
let t = _0n;
|
||
|
for (let j = 0; j < 7; j++) {
|
||
|
R = ((R << _1n) ^ ((R >> _7n$1) * _0x71n)) % _256n$1;
|
||
|
if (R & _2n)
|
||
|
t ^= _1n << ((_1n << BigInt(j)) - _1n);
|
||
|
}
|
||
|
_SHA3_IOTA.push(t);
|
||
|
}
|
||
|
const [SHA3_IOTA_H, SHA3_IOTA_L] = split(_SHA3_IOTA, true);
|
||
|
const rotlH = (h, l, s) => (s > 32 ? rotlBH(h, l, s) : rotlSH(h, l, s));
|
||
|
const rotlL = (h, l, s) => (s > 32 ? rotlBL(h, l, s) : rotlSL(h, l, s));
|
||
|
function keccakP(s, rounds = 24) {
|
||
|
const B = new Uint32Array(5 * 2);
|
||
|
for (let round = 24 - rounds; round < 24; round++) {
|
||
|
for (let x = 0; x < 10; x++)
|
||
|
B[x] = s[x] ^ s[x + 10] ^ s[x + 20] ^ s[x + 30] ^ s[x + 40];
|
||
|
for (let x = 0; x < 10; x += 2) {
|
||
|
const idx1 = (x + 8) % 10;
|
||
|
const idx0 = (x + 2) % 10;
|
||
|
const B0 = B[idx0];
|
||
|
const B1 = B[idx0 + 1];
|
||
|
const Th = rotlH(B0, B1, 1) ^ B[idx1];
|
||
|
const Tl = rotlL(B0, B1, 1) ^ B[idx1 + 1];
|
||
|
for (let y = 0; y < 50; y += 10) {
|
||
|
s[x + y] ^= Th;
|
||
|
s[x + y + 1] ^= Tl;
|
||
|
}
|
||
|
}
|
||
|
let curH = s[2];
|
||
|
let curL = s[3];
|
||
|
for (let t = 0; t < 24; t++) {
|
||
|
const shift = SHA3_ROTL[t];
|
||
|
const Th = rotlH(curH, curL, shift);
|
||
|
const Tl = rotlL(curH, curL, shift);
|
||
|
const PI = SHA3_PI[t];
|
||
|
curH = s[PI];
|
||
|
curL = s[PI + 1];
|
||
|
s[PI] = Th;
|
||
|
s[PI + 1] = Tl;
|
||
|
}
|
||
|
for (let y = 0; y < 50; y += 10) {
|
||
|
for (let x = 0; x < 10; x++)
|
||
|
B[x] = s[y + x];
|
||
|
for (let x = 0; x < 10; x++)
|
||
|
s[y + x] ^= ~B[(x + 2) % 10] & B[(x + 4) % 10];
|
||
|
}
|
||
|
s[0] ^= SHA3_IOTA_H[round];
|
||
|
s[1] ^= SHA3_IOTA_L[round];
|
||
|
}
|
||
|
B.fill(0);
|
||
|
}
|
||
|
class Keccak extends Hash {
|
||
|
constructor(blockLen, suffix, outputLen, enableXOF = false, rounds = 24) {
|
||
|
super();
|
||
|
this.blockLen = blockLen;
|
||
|
this.suffix = suffix;
|
||
|
this.outputLen = outputLen;
|
||
|
this.enableXOF = enableXOF;
|
||
|
this.rounds = rounds;
|
||
|
this.pos = 0;
|
||
|
this.posOut = 0;
|
||
|
this.finished = false;
|
||
|
this.destroyed = false;
|
||
|
number(outputLen);
|
||
|
if (0 >= this.blockLen || this.blockLen >= 200)
|
||
|
throw new Error('Sha3 supports only keccak-f1600 function');
|
||
|
this.state = new Uint8Array(200);
|
||
|
this.state32 = u32(this.state);
|
||
|
}
|
||
|
keccak() {
|
||
|
keccakP(this.state32, this.rounds);
|
||
|
this.posOut = 0;
|
||
|
this.pos = 0;
|
||
|
}
|
||
|
update(data) {
|
||
|
exists(this);
|
||
|
const { blockLen, state } = this;
|
||
|
data = toBytes(data);
|
||
|
const len = data.length;
|
||
|
for (let pos = 0; pos < len;) {
|
||
|
const take = Math.min(blockLen - this.pos, len - pos);
|
||
|
for (let i = 0; i < take; i++)
|
||
|
state[this.pos++] ^= data[pos++];
|
||
|
if (this.pos === blockLen)
|
||
|
this.keccak();
|
||
|
}
|
||
|
return this;
|
||
|
}
|
||
|
finish() {
|
||
|
if (this.finished)
|
||
|
return;
|
||
|
this.finished = true;
|
||
|
const { state, suffix, pos, blockLen } = this;
|
||
|
state[pos] ^= suffix;
|
||
|
if ((suffix & 0x80) !== 0 && pos === blockLen - 1)
|
||
|
this.keccak();
|
||
|
state[blockLen - 1] ^= 0x80;
|
||
|
this.keccak();
|
||
|
}
|
||
|
writeInto(out) {
|
||
|
exists(this, false);
|
||
|
bytes(out);
|
||
|
this.finish();
|
||
|
const bufferOut = this.state;
|
||
|
const { blockLen } = this;
|
||
|
for (let pos = 0, len = out.length; pos < len;) {
|
||
|
if (this.posOut >= blockLen)
|
||
|
this.keccak();
|
||
|
const take = Math.min(blockLen - this.posOut, len - pos);
|
||
|
out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos);
|
||
|
this.posOut += take;
|
||
|
pos += take;
|
||
|
}
|
||
|
return out;
|
||
|
}
|
||
|
xofInto(out) {
|
||
|
if (!this.enableXOF)
|
||
|
throw new Error('XOF is not possible for this instance');
|
||
|
return this.writeInto(out);
|
||
|
}
|
||
|
xof(bytes) {
|
||
|
number(bytes);
|
||
|
return this.xofInto(new Uint8Array(bytes));
|
||
|
}
|
||
|
digestInto(out) {
|
||
|
output(out, this);
|
||
|
if (this.finished)
|
||
|
throw new Error('digest() was already called');
|
||
|
this.writeInto(out);
|
||
|
this.destroy();
|
||
|
return out;
|
||
|
}
|
||
|
digest() {
|
||
|
return this.digestInto(new Uint8Array(this.outputLen));
|
||
|
}
|
||
|
destroy() {
|
||
|
this.destroyed = true;
|
||
|
this.state.fill(0);
|
||
|
}
|
||
|
_cloneInto(to) {
|
||
|
const { blockLen, suffix, outputLen, rounds, enableXOF } = this;
|
||
|
to || (to = new Keccak(blockLen, suffix, outputLen, enableXOF, rounds));
|
||
|
to.state32.set(this.state32);
|
||
|
to.pos = this.pos;
|
||
|
to.posOut = this.posOut;
|
||
|
to.finished = this.finished;
|
||
|
to.rounds = rounds;
|
||
|
to.suffix = suffix;
|
||
|
to.outputLen = outputLen;
|
||
|
to.enableXOF = enableXOF;
|
||
|
to.destroyed = this.destroyed;
|
||
|
return to;
|
||
|
}
|
||
|
}
|
||
|
const gen = (suffix, blockLen, outputLen) => wrapConstructor(() => new Keccak(blockLen, suffix, outputLen));
|
||
|
gen(0x06, 144, 224 / 8);
|
||
|
gen(0x06, 136, 256 / 8);
|
||
|
gen(0x06, 104, 384 / 8);
|
||
|
gen(0x06, 72, 512 / 8);
|
||
|
gen(0x01, 144, 224 / 8);
|
||
|
const keccak_256 = gen(0x01, 136, 256 / 8);
|
||
|
gen(0x01, 104, 384 / 8);
|
||
|
const keccak_512 = gen(0x01, 72, 512 / 8);
|
||
|
const genShake = (suffix, blockLen, outputLen) => wrapXOFConstructorWithOpts((opts = {}) => new Keccak(blockLen, suffix, opts.dkLen === undefined ? outputLen : opts.dkLen, true));
|
||
|
genShake(0x1f, 168, 128 / 8);
|
||
|
genShake(0x1f, 136, 256 / 8);
|
||
|
|
||
|
const keccakAsU8a = createDualHasher({ 256: keccak256, 512: keccak512 }, { 256: keccak_256, 512: keccak_512 });
|
||
|
const keccak256AsU8a = createBitHasher(256, keccakAsU8a);
|
||
|
const keccak512AsU8a = createBitHasher(512, keccakAsU8a);
|
||
|
const keccakAsHex = createAsHex(keccakAsU8a);
|
||
|
|
||
|
function hasher(hashType, data, onlyJs) {
|
||
|
return hashType === 'keccak'
|
||
|
? keccakAsU8a(data, undefined, onlyJs)
|
||
|
: blake2AsU8a(data, undefined, undefined, onlyJs);
|
||
|
}
|
||
|
|
||
|
function evmToAddress(evmAddress, ss58Format, hashType = 'blake2') {
|
||
|
const message = util.u8aConcat('evm:', evmAddress);
|
||
|
if (message.length !== 24) {
|
||
|
throw new Error(`Converting ${evmAddress}: Invalid evm address length`);
|
||
|
}
|
||
|
return encodeAddress(hasher(hashType, message), ss58Format);
|
||
|
}
|
||
|
|
||
|
function validateAddress(encoded, ignoreChecksum, ss58Format) {
|
||
|
return !!decodeAddress(encoded, ignoreChecksum, ss58Format);
|
||
|
}
|
||
|
|
||
|
function isAddress(address, ignoreChecksum, ss58Format) {
|
||
|
try {
|
||
|
return validateAddress(address, ignoreChecksum, ss58Format);
|
||
|
}
|
||
|
catch {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function sortAddresses(addresses, ss58Format) {
|
||
|
const u8aToAddress = (u8a) => encodeAddress(u8a, ss58Format);
|
||
|
return util.u8aSorted(addresses.map(addressToU8a)).map(u8aToAddress);
|
||
|
}
|
||
|
|
||
|
const l = util.logger('setSS58Format');
|
||
|
function setSS58Format(prefix) {
|
||
|
l.warn('Global setting of the ss58Format is deprecated and not recommended. Set format on the keyring (if used) or as part of the address encode function');
|
||
|
defaults.prefix = prefix;
|
||
|
}
|
||
|
|
||
|
const chars = 'abcdefghijklmnopqrstuvwxyz234567';
|
||
|
const config$1 = {
|
||
|
chars,
|
||
|
coder: utils.chain(
|
||
|
utils.radix2(5), utils.alphabet(chars), {
|
||
|
decode: (input) => input.split(''),
|
||
|
encode: (input) => input.join('')
|
||
|
}),
|
||
|
ipfs: 'b',
|
||
|
type: 'base32'
|
||
|
};
|
||
|
const base32Validate = createValidate(config$1);
|
||
|
const isBase32 = createIs(base32Validate);
|
||
|
const base32Decode = createDecode(config$1, base32Validate);
|
||
|
const base32Encode = createEncode(config$1);
|
||
|
|
||
|
const config = {
|
||
|
chars: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
|
||
|
coder: base64,
|
||
|
type: 'base64',
|
||
|
withPadding: true
|
||
|
};
|
||
|
const base64Validate = createValidate(config);
|
||
|
const isBase64 = createIs(base64Validate);
|
||
|
const base64Decode = createDecode(config, base64Validate);
|
||
|
const base64Encode = createEncode(config);
|
||
|
|
||
|
function base64Pad(value) {
|
||
|
return value.padEnd(value.length + (value.length % 4), '=');
|
||
|
}
|
||
|
|
||
|
function base64Trim(value) {
|
||
|
while (value.length && value.endsWith('=')) {
|
||
|
value = value.slice(0, -1);
|
||
|
}
|
||
|
return value;
|
||
|
}
|
||
|
|
||
|
function secp256k1Compress(publicKey, onlyJs) {
|
||
|
if (![33, 65].includes(publicKey.length)) {
|
||
|
throw new Error(`Invalid publicKey provided, received ${publicKey.length} bytes input`);
|
||
|
}
|
||
|
if (publicKey.length === 33) {
|
||
|
return publicKey;
|
||
|
}
|
||
|
return !util.hasBigInt || (!onlyJs && isReady())
|
||
|
? secp256k1Compress$1(publicKey)
|
||
|
: secp256k1.ProjectivePoint.fromHex(publicKey).toRawBytes(true);
|
||
|
}
|
||
|
|
||
|
function secp256k1Expand(publicKey, onlyJs) {
|
||
|
if (![33, 65].includes(publicKey.length)) {
|
||
|
throw new Error(`Invalid publicKey provided, received ${publicKey.length} bytes input`);
|
||
|
}
|
||
|
if (publicKey.length === 65) {
|
||
|
return publicKey.subarray(1);
|
||
|
}
|
||
|
if (!util.hasBigInt || (!onlyJs && isReady())) {
|
||
|
return secp256k1Expand$1(publicKey).subarray(1);
|
||
|
}
|
||
|
const { px, py } = secp256k1.ProjectivePoint.fromHex(publicKey);
|
||
|
return util.u8aConcat(util.bnToU8a(px, BN_BE_256_OPTS), util.bnToU8a(py, BN_BE_256_OPTS));
|
||
|
}
|
||
|
|
||
|
function secp256k1Recover(msgHash, signature, recovery, hashType = 'blake2', onlyJs) {
|
||
|
const sig = util.u8aToU8a(signature).subarray(0, 64);
|
||
|
const msg = util.u8aToU8a(msgHash);
|
||
|
const publicKey = !util.hasBigInt || (!onlyJs && isReady())
|
||
|
? secp256k1Recover$1(msg, sig, recovery)
|
||
|
: secp256k1.Signature
|
||
|
.fromCompact(sig)
|
||
|
.addRecoveryBit(recovery)
|
||
|
.recoverPublicKey(msg)
|
||
|
.toRawBytes();
|
||
|
if (!publicKey) {
|
||
|
throw new Error('Unable to recover publicKey from signature');
|
||
|
}
|
||
|
return hashType === 'keccak'
|
||
|
? secp256k1Expand(publicKey, onlyJs)
|
||
|
: secp256k1Compress(publicKey, onlyJs);
|
||
|
}
|
||
|
|
||
|
function secp256k1Sign(message, { secretKey }, hashType = 'blake2', onlyJs) {
|
||
|
if (secretKey?.length !== 32) {
|
||
|
throw new Error('Expected valid secp256k1 secretKey, 32-bytes');
|
||
|
}
|
||
|
const data = hasher(hashType, message, onlyJs);
|
||
|
if (!util.hasBigInt || (!onlyJs && isReady())) {
|
||
|
return secp256k1Sign$1(data, secretKey);
|
||
|
}
|
||
|
const signature = secp256k1.sign(data, secretKey, { lowS: true });
|
||
|
return util.u8aConcat(util.bnToU8a(signature.r, BN_BE_256_OPTS), util.bnToU8a(signature.s, BN_BE_256_OPTS), new Uint8Array([signature.recovery || 0]));
|
||
|
}
|
||
|
|
||
|
const N = 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141'.replace(/ /g, '');
|
||
|
const N_BI = BigInt$1(`0x${N}`);
|
||
|
const N_BN = new util.BN(N, 'hex');
|
||
|
function addBi(seckey, tweak) {
|
||
|
let res = util.u8aToBigInt(tweak, BN_BE_OPTS);
|
||
|
if (res >= N_BI) {
|
||
|
throw new Error('Tweak parameter is out of range');
|
||
|
}
|
||
|
res += util.u8aToBigInt(seckey, BN_BE_OPTS);
|
||
|
if (res >= N_BI) {
|
||
|
res -= N_BI;
|
||
|
}
|
||
|
if (res === util._0n) {
|
||
|
throw new Error('Invalid resulting private key');
|
||
|
}
|
||
|
return util.nToU8a(res, BN_BE_256_OPTS);
|
||
|
}
|
||
|
function addBn(seckey, tweak) {
|
||
|
const res = new util.BN(tweak);
|
||
|
if (res.cmp(N_BN) >= 0) {
|
||
|
throw new Error('Tweak parameter is out of range');
|
||
|
}
|
||
|
res.iadd(new util.BN(seckey));
|
||
|
if (res.cmp(N_BN) >= 0) {
|
||
|
res.isub(N_BN);
|
||
|
}
|
||
|
if (res.isZero()) {
|
||
|
throw new Error('Invalid resulting private key');
|
||
|
}
|
||
|
return util.bnToU8a(res, BN_BE_256_OPTS);
|
||
|
}
|
||
|
function secp256k1PrivateKeyTweakAdd(seckey, tweak, onlyBn) {
|
||
|
if (!util.isU8a(seckey) || seckey.length !== 32) {
|
||
|
throw new Error('Expected seckey to be an Uint8Array with length 32');
|
||
|
}
|
||
|
else if (!util.isU8a(tweak) || tweak.length !== 32) {
|
||
|
throw new Error('Expected tweak to be an Uint8Array with length 32');
|
||
|
}
|
||
|
return !util.hasBigInt || onlyBn
|
||
|
? addBn(seckey, tweak)
|
||
|
: addBi(seckey, tweak);
|
||
|
}
|
||
|
|
||
|
function secp256k1Verify(msgHash, signature, address, hashType = 'blake2', onlyJs) {
|
||
|
const sig = util.u8aToU8a(signature);
|
||
|
if (sig.length !== 65) {
|
||
|
throw new Error(`Expected signature with 65 bytes, ${sig.length} found instead`);
|
||
|
}
|
||
|
const publicKey = secp256k1Recover(hasher(hashType, msgHash), sig, sig[64], hashType, onlyJs);
|
||
|
const signerAddr = hasher(hashType, publicKey, onlyJs);
|
||
|
const inputAddr = util.u8aToU8a(address);
|
||
|
return util.u8aEq(publicKey, inputAddr) || (hashType === 'keccak'
|
||
|
? util.u8aEq(signerAddr.slice(-20), inputAddr.slice(-20))
|
||
|
: util.u8aEq(signerAddr, inputAddr));
|
||
|
}
|
||
|
|
||
|
function getH160(u8a) {
|
||
|
if ([33, 65].includes(u8a.length)) {
|
||
|
u8a = keccakAsU8a(secp256k1Expand(u8a));
|
||
|
}
|
||
|
return u8a.slice(-20);
|
||
|
}
|
||
|
function ethereumEncode(addressOrPublic) {
|
||
|
if (!addressOrPublic) {
|
||
|
return '0x';
|
||
|
}
|
||
|
const u8aAddress = util.u8aToU8a(addressOrPublic);
|
||
|
if (![20, 32, 33, 65].includes(u8aAddress.length)) {
|
||
|
throw new Error(`Invalid address or publicKey provided, received ${u8aAddress.length} bytes input`);
|
||
|
}
|
||
|
const address = util.u8aToHex(getH160(u8aAddress), -1, false);
|
||
|
const hash = util.u8aToHex(keccakAsU8a(address), -1, false);
|
||
|
let result = '';
|
||
|
for (let i = 0; i < 40; i++) {
|
||
|
result = `${result}${parseInt(hash[i], 16) > 7 ? address[i].toUpperCase() : address[i]}`;
|
||
|
}
|
||
|
return `0x${result}`;
|
||
|
}
|
||
|
|
||
|
function isInvalidChar(char, byte) {
|
||
|
return char !== (byte > 7
|
||
|
? char.toUpperCase()
|
||
|
: char.toLowerCase());
|
||
|
}
|
||
|
function isEthereumChecksum(_address) {
|
||
|
const address = _address.replace('0x', '');
|
||
|
const hash = util.u8aToHex(keccakAsU8a(address.toLowerCase()), -1, false);
|
||
|
for (let i = 0; i < 40; i++) {
|
||
|
if (isInvalidChar(address[i], parseInt(hash[i], 16))) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
function isEthereumAddress(address) {
|
||
|
if (!address || address.length !== 42 || !util.isHex(address)) {
|
||
|
return false;
|
||
|
}
|
||
|
else if (/^(0x)?[0-9a-f]{40}$/.test(address) || /^(0x)?[0-9A-F]{40}$/.test(address)) {
|
||
|
return true;
|
||
|
}
|
||
|
return isEthereumChecksum(address);
|
||
|
}
|
||
|
|
||
|
const JS_HASH = {
|
||
|
256: sha256,
|
||
|
512: sha512
|
||
|
};
|
||
|
const WA_MHAC = {
|
||
|
256: hmacSha256,
|
||
|
512: hmacSha512
|
||
|
};
|
||
|
function createSha(bitLength) {
|
||
|
return (key, data, onlyJs) => hmacShaAsU8a(key, data, bitLength, onlyJs);
|
||
|
}
|
||
|
function hmacShaAsU8a(key, data, bitLength = 256, onlyJs) {
|
||
|
const u8aKey = util.u8aToU8a(key);
|
||
|
return !util.hasBigInt || (!onlyJs && isReady())
|
||
|
? WA_MHAC[bitLength](u8aKey, data)
|
||
|
: hmac(JS_HASH[bitLength], u8aKey, data);
|
||
|
}
|
||
|
const hmacSha256AsU8a = createSha(256);
|
||
|
const hmacSha512AsU8a = createSha(512);
|
||
|
|
||
|
const HARDENED = 0x80000000;
|
||
|
function hdValidatePath(path) {
|
||
|
if (!path.startsWith('m/')) {
|
||
|
return false;
|
||
|
}
|
||
|
const parts = path.split('/').slice(1);
|
||
|
for (const p of parts) {
|
||
|
const n = /^\d+'?$/.test(p)
|
||
|
? parseInt(p.replace(/'$/, ''), 10)
|
||
|
: Number.NaN;
|
||
|
if (isNaN(n) || (n >= HARDENED) || (n < 0)) {
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
const MASTER_SECRET = util.stringToU8a('Bitcoin seed');
|
||
|
function createCoded(secretKey, chainCode) {
|
||
|
return {
|
||
|
chainCode,
|
||
|
publicKey: secp256k1PairFromSeed(secretKey).publicKey,
|
||
|
secretKey
|
||
|
};
|
||
|
}
|
||
|
function deriveChild(hd, index) {
|
||
|
const indexBuffer = util.bnToU8a(index, BN_BE_32_OPTS);
|
||
|
const data = index >= HARDENED
|
||
|
? util.u8aConcat(new Uint8Array(1), hd.secretKey, indexBuffer)
|
||
|
: util.u8aConcat(hd.publicKey, indexBuffer);
|
||
|
try {
|
||
|
const I = hmacShaAsU8a(hd.chainCode, data, 512);
|
||
|
return createCoded(secp256k1PrivateKeyTweakAdd(hd.secretKey, I.slice(0, 32)), I.slice(32));
|
||
|
}
|
||
|
catch {
|
||
|
return deriveChild(hd, index + 1);
|
||
|
}
|
||
|
}
|
||
|
function hdEthereum(seed, path = '') {
|
||
|
const I = hmacShaAsU8a(MASTER_SECRET, seed, 512);
|
||
|
let hd = createCoded(I.slice(0, 32), I.slice(32));
|
||
|
if (!path || path === 'm' || path === 'M' || path === "m'" || path === "M'") {
|
||
|
return hd;
|
||
|
}
|
||
|
if (!hdValidatePath(path)) {
|
||
|
throw new Error('Invalid derivation path');
|
||
|
}
|
||
|
const parts = path.split('/').slice(1);
|
||
|
for (const p of parts) {
|
||
|
hd = deriveChild(hd, parseInt(p, 10) + ((p.length > 1) && p.endsWith("'")
|
||
|
? HARDENED
|
||
|
: 0));
|
||
|
}
|
||
|
return hd;
|
||
|
}
|
||
|
|
||
|
function pbkdf2Init(hash$1, _password, _salt, _opts) {
|
||
|
hash(hash$1);
|
||
|
const opts = checkOpts({ dkLen: 32, asyncTick: 10 }, _opts);
|
||
|
const { c, dkLen, asyncTick } = opts;
|
||
|
number(c);
|
||
|
number(dkLen);
|
||
|
number(asyncTick);
|
||
|
if (c < 1)
|
||
|
throw new Error('PBKDF2: iterations (c) should be >= 1');
|
||
|
const password = toBytes(_password);
|
||
|
const salt = toBytes(_salt);
|
||
|
const DK = new Uint8Array(dkLen);
|
||
|
const PRF = hmac.create(hash$1, 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();
|
||
|
u.fill(0);
|
||
|
return DK;
|
||
|
}
|
||
|
function pbkdf2(hash, password, salt, opts) {
|
||
|
const { c, dkLen, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);
|
||
|
let prfW;
|
||
|
const arr = new Uint8Array(4);
|
||
|
const view = createView(arr);
|
||
|
const u = new Uint8Array(PRF.outputLen);
|
||
|
for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {
|
||
|
const Ti = DK.subarray(pos, pos + PRF.outputLen);
|
||
|
view.setInt32(0, ti, false);
|
||
|
(prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u);
|
||
|
Ti.set(u.subarray(0, Ti.length));
|
||
|
for (let ui = 1; ui < c; ui++) {
|
||
|
PRF._cloneInto(prfW).update(u).digestInto(u);
|
||
|
for (let i = 0; i < Ti.length; i++)
|
||
|
Ti[i] ^= u[i];
|
||
|
}
|
||
|
}
|
||
|
return pbkdf2Output(PRF, PRFSalt, DK, prfW, u);
|
||
|
}
|
||
|
|
||
|
function pbkdf2Encode(passphrase, salt = randomAsU8a(), rounds = 2048, onlyJs) {
|
||
|
const u8aPass = util.u8aToU8a(passphrase);
|
||
|
const u8aSalt = util.u8aToU8a(salt);
|
||
|
return {
|
||
|
password: !util.hasBigInt || (!onlyJs && isReady())
|
||
|
? pbkdf2$1(u8aPass, u8aSalt, rounds)
|
||
|
: pbkdf2(sha512, u8aPass, u8aSalt, { c: rounds, dkLen: 64 }),
|
||
|
rounds,
|
||
|
salt
|
||
|
};
|
||
|
}
|
||
|
|
||
|
const shaAsU8a = createDualHasher({ 256: sha256$1, 512: sha512$1 }, { 256: sha256, 512: sha512 });
|
||
|
const sha256AsU8a = createBitHasher(256, shaAsU8a);
|
||
|
const sha512AsU8a = createBitHasher(512, shaAsU8a);
|
||
|
|
||
|
const DEFAULT_WORDLIST = 'abandon|ability|able|about|above|absent|absorb|abstract|absurd|abuse|access|accident|account|accuse|achieve|acid|acoustic|acquire|across|act|action|actor|actress|actual|adapt|add|addict|address|adjust|admit|adult|advance|advice|aerobic|affair|afford|afraid|again|age|agent|agree|ahead|aim|air|airport|aisle|alarm|album|alcohol|alert|alien|all|alley|allow|almost|alone|alpha|already|also|alter|always|amateur|amazing|among|amount|amused|analyst|anchor|ancient|anger|angle|angry|animal|ankle|announce|annual|another|answer|antenna|antique|anxiety|any|apart|apology|appear|apple|approve|april|arch|arctic|area|arena|argue|arm|armed|armor|army|around|arrange|arrest|arrive|arrow|art|artefact|artist|artwork|ask|aspect|assault|asset|assist|assume|asthma|athlete|atom|attack|attend|attitude|attract|auction|audit|august|aunt|author|auto|autumn|average|avocado|avoid|awake|aware|away|awesome|awful|awkward|axis|baby|bachelor|bacon|badge|bag|balance|balcony|ball|bamboo|banana|banner|bar|barely|bargain|barrel|base|basic|basket|battle|beach|bean|beauty|because|become|beef|before|begin|behave|behind|believe|below|belt|bench|benefit|best|betray|better|between|beyond|bicycle|bid|bike|bind|biology|bird|birth|bitter|black|blade|blame|blanket|blast|bleak|bless|blind|blood|blossom|blouse|blue|blur|blush|board|boat|body|boil|bomb|bone|bonus|book|boost|border|boring|borrow|boss|bottom|bounce|box|boy|bracket|brain|brand|brass|brave|bread|breeze|brick|bridge|brief|bright|bring|brisk|broccoli|broken|bronze|broom|brother|brown|brush|bubble|buddy|budget|buffalo|build|bulb|bulk|bullet|bundle|bunker|burden|burger|burst|bus|business|busy|butter|buyer|buzz|cabbage|cabin|cable|cactus|cage|cake|call|calm|camera|camp|can|canal|cancel|candy|cannon|canoe|canvas|canyon|capable|capital|captain|car|carbon|card|cargo|carpet|carry|cart|case|cash|casino|castle|casual|cat|catalog|catch|category|cattle|caught|cause|caution|cave|ceiling|celery|cement|census|century|cereal|certain|chair|chalk|champion|change|chaos|chapter|charge|chase|chat|cheap|check|cheese|chef|cherry|chest|chicken|chief|child|chimney|choice|choose|chronic|chuckle|chunk|churn|cigar|cinnamon|circle|citizen|city|civil|claim|clap|clarify|claw|clay|clean|clerk|clever|click|client|cliff|climb|clinic|clip|clock|clog|close|cloth|cloud|clown|club|clump|cluster|clutch|coach|coast|coconut|code|coffee|coil|coin|collect|color|column|combine|come|comfort|comic|common|company|concert|conduct|confirm|congress|connect|consider|control|convince|cook|cool|copper|copy|coral|core|corn|correct|cost|cotton|couch|country|couple|course|cousin|cover|coyote|crack|cradle|craft|cram|crane|crash|crater|crawl|crazy|cream|credit|creek|crew|cricket|crime|crisp|critic|crop|cross|crouch|crowd|crucial|cruel|cruise|crumble|crunch|crush|cry|crystal|cube|culture|cup|cupboard|curious|current|curtain|curve|cushion|custom|cute|cycle|dad|damage|damp|dance|danger|daring|dash|daughter|dawn|day|deal|debate|debris|decade|december|decide|decline|decorate|decrease|deer|defense|define|defy|degree|delay|deliver|demand|demise|denial|dentist|deny|depart|depend|deposit|depth|deputy|derive|describe|desert|design|desk|despair|destroy|detail|detect|develop|device|devote|diagram|dial|diamond|diary|dice|diesel|diet|differ|digital|dignity|dilemma|dinner|dinosaur|direct|dirt|disagree|discover|disease|dish|dismiss|disorder|display|distance|divert|divide|divorce|dizzy|doctor|document|dog|doll|dolphin|domain|donate|donkey|donor|door|dose|double|dove|draft|dragon|drama|drastic|draw|dream|dress|drift|drill|drink|drip|drive|drop|drum|dry|duck|dumb|dune|during|dust|dutch|duty|dwarf|dynamic|eager|eagle|early|earn|earth|easily|east|easy|echo|ecology|economy|edge|edit|educate|effort|egg|eight|either|elbow|elder|electric|elegant|element|elephant|elevator|elite|else|embark|embody|embrace|emerge|emotion|employ|empower|empty|enable|enact|end|endless|endorse|enemy|energy|enforce|engage|engine|enhance|enjoy|enlist|enough|enrich|enroll|ensure|enter|entire|entry|envelope|episode|equal|equip|era|erase|erode|erosion|error|erupt|escape|essay|essence|estate|
|
||
|
|
||
|
const INVALID_MNEMONIC = 'Invalid mnemonic';
|
||
|
const INVALID_ENTROPY = 'Invalid entropy';
|
||
|
const INVALID_CHECKSUM = 'Invalid mnemonic checksum';
|
||
|
function normalize(str) {
|
||
|
return (str || '').normalize('NFKD');
|
||
|
}
|
||
|
function binaryToByte(bin) {
|
||
|
return parseInt(bin, 2);
|
||
|
}
|
||
|
function bytesToBinary(bytes) {
|
||
|
return bytes.map((x) => x.toString(2).padStart(8, '0')).join('');
|
||
|
}
|
||
|
function deriveChecksumBits(entropyBuffer) {
|
||
|
return bytesToBinary(Array.from(sha256AsU8a(entropyBuffer))).slice(0, (entropyBuffer.length * 8) / 32);
|
||
|
}
|
||
|
function mnemonicToSeedSync(mnemonic, password) {
|
||
|
return pbkdf2Encode(util.stringToU8a(normalize(mnemonic)), util.stringToU8a(`mnemonic${normalize(password)}`)).password;
|
||
|
}
|
||
|
function mnemonicToEntropy$1(mnemonic, wordlist = DEFAULT_WORDLIST) {
|
||
|
const words = normalize(mnemonic).split(' ');
|
||
|
if (words.length % 3 !== 0) {
|
||
|
throw new Error(INVALID_MNEMONIC);
|
||
|
}
|
||
|
const bits = words
|
||
|
.map((word) => {
|
||
|
const index = wordlist.indexOf(word);
|
||
|
if (index === -1) {
|
||
|
throw new Error(INVALID_MNEMONIC);
|
||
|
}
|
||
|
return index.toString(2).padStart(11, '0');
|
||
|
})
|
||
|
.join('');
|
||
|
const dividerIndex = Math.floor(bits.length / 33) * 32;
|
||
|
const entropyBits = bits.slice(0, dividerIndex);
|
||
|
const checksumBits = bits.slice(dividerIndex);
|
||
|
const matched = entropyBits.match(/(.{1,8})/g);
|
||
|
const entropyBytes = matched?.map(binaryToByte);
|
||
|
if (!entropyBytes || (entropyBytes.length % 4 !== 0) || (entropyBytes.length < 16) || (entropyBytes.length > 32)) {
|
||
|
throw new Error(INVALID_ENTROPY);
|
||
|
}
|
||
|
const entropy = util.u8aToU8a(entropyBytes);
|
||
|
if (deriveChecksumBits(entropy) !== checksumBits) {
|
||
|
throw new Error(INVALID_CHECKSUM);
|
||
|
}
|
||
|
return entropy;
|
||
|
}
|
||
|
function entropyToMnemonic(entropy, wordlist = DEFAULT_WORDLIST) {
|
||
|
if ((entropy.length % 4 !== 0) || (entropy.length < 16) || (entropy.length > 32)) {
|
||
|
throw new Error(INVALID_ENTROPY);
|
||
|
}
|
||
|
const matched = `${bytesToBinary(Array.from(entropy))}${deriveChecksumBits(entropy)}`.match(/(.{1,11})/g);
|
||
|
const mapped = matched?.map((b) => wordlist[binaryToByte(b)]);
|
||
|
if (!mapped || (mapped.length < 12)) {
|
||
|
throw new Error('Unable to map entropy to mnemonic');
|
||
|
}
|
||
|
return mapped.join(' ');
|
||
|
}
|
||
|
function generateMnemonic(numWords, wordlist) {
|
||
|
return entropyToMnemonic(randomAsU8a((numWords / 3) * 4), wordlist);
|
||
|
}
|
||
|
function validateMnemonic(mnemonic, wordlist) {
|
||
|
try {
|
||
|
mnemonicToEntropy$1(mnemonic, wordlist);
|
||
|
}
|
||
|
catch {
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
function mnemonicGenerate(numWords = 12, wordlist, onlyJs) {
|
||
|
return !util.hasBigInt || (!wordlist && !onlyJs && isReady())
|
||
|
? bip39Generate(numWords)
|
||
|
: generateMnemonic(numWords, wordlist);
|
||
|
}
|
||
|
|
||
|
function mnemonicToEntropy(mnemonic, wordlist, onlyJs) {
|
||
|
return !util.hasBigInt || (!wordlist && !onlyJs && isReady())
|
||
|
? bip39ToEntropy(mnemonic)
|
||
|
: mnemonicToEntropy$1(mnemonic, wordlist);
|
||
|
}
|
||
|
|
||
|
function mnemonicValidate(mnemonic, wordlist, onlyJs) {
|
||
|
return !util.hasBigInt || (!wordlist && !onlyJs && isReady())
|
||
|
? bip39Validate(mnemonic)
|
||
|
: validateMnemonic(mnemonic, wordlist);
|
||
|
}
|
||
|
|
||
|
function mnemonicToLegacySeed(mnemonic, password = '', onlyJs, byteLength = 32) {
|
||
|
if (!mnemonicValidate(mnemonic)) {
|
||
|
throw new Error('Invalid bip39 mnemonic specified');
|
||
|
}
|
||
|
else if (![32, 64].includes(byteLength)) {
|
||
|
throw new Error(`Invalid seed length ${byteLength}, expected 32 or 64`);
|
||
|
}
|
||
|
return byteLength === 32
|
||
|
? !util.hasBigInt || (!onlyJs && isReady())
|
||
|
? bip39ToSeed(mnemonic, password)
|
||
|
: mnemonicToSeedSync(mnemonic, password).subarray(0, 32)
|
||
|
: mnemonicToSeedSync(mnemonic, password);
|
||
|
}
|
||
|
|
||
|
function mnemonicToMiniSecret(mnemonic, password = '', wordlist, onlyJs) {
|
||
|
if (!mnemonicValidate(mnemonic, wordlist, onlyJs)) {
|
||
|
throw new Error('Invalid bip39 mnemonic specified');
|
||
|
}
|
||
|
else if (!wordlist && !onlyJs && isReady()) {
|
||
|
return bip39ToMiniSecret(mnemonic, password);
|
||
|
}
|
||
|
const entropy = mnemonicToEntropy(mnemonic, wordlist);
|
||
|
const salt = util.stringToU8a(`mnemonic${password}`);
|
||
|
return pbkdf2Encode(entropy, salt).password.slice(0, 32);
|
||
|
}
|
||
|
|
||
|
function ledgerDerivePrivate(xprv, index) {
|
||
|
const kl = xprv.subarray(0, 32);
|
||
|
const kr = xprv.subarray(32, 64);
|
||
|
const cc = xprv.subarray(64, 96);
|
||
|
const data = util.u8aConcat([0], kl, kr, util.bnToU8a(index, BN_LE_32_OPTS));
|
||
|
const z = hmacShaAsU8a(cc, data, 512);
|
||
|
data[0] = 0x01;
|
||
|
return util.u8aConcat(util.bnToU8a(util.u8aToBn(kl, BN_LE_OPTS).iadd(util.u8aToBn(z.subarray(0, 28), BN_LE_OPTS).imul(util.BN_EIGHT)), BN_LE_512_OPTS).subarray(0, 32), util.bnToU8a(util.u8aToBn(kr, BN_LE_OPTS).iadd(util.u8aToBn(z.subarray(32, 64), BN_LE_OPTS)), BN_LE_512_OPTS).subarray(0, 32), hmacShaAsU8a(cc, data, 512).subarray(32, 64));
|
||
|
}
|
||
|
|
||
|
const ED25519_CRYPTO = 'ed25519 seed';
|
||
|
function ledgerMaster(mnemonic, password) {
|
||
|
const seed = mnemonicToSeedSync(mnemonic, password);
|
||
|
const chainCode = hmacShaAsU8a(ED25519_CRYPTO, new Uint8Array([1, ...seed]), 256);
|
||
|
let priv;
|
||
|
while (!priv || (priv[31] & 32)) {
|
||
|
priv = hmacShaAsU8a(ED25519_CRYPTO, priv || seed, 512);
|
||
|
}
|
||
|
priv[0] &= 248;
|
||
|
priv[31] &= 127;
|
||
|
priv[31] |= 64;
|
||
|
return util.u8aConcat(priv, chainCode);
|
||
|
}
|
||
|
|
||
|
function hdLedger(_mnemonic, path) {
|
||
|
const words = _mnemonic
|
||
|
.split(' ')
|
||
|
.map((s) => s.trim())
|
||
|
.filter((s) => s);
|
||
|
if (![12, 24, 25].includes(words.length)) {
|
||
|
throw new Error('Expected a mnemonic with 24 words (or 25 including a password)');
|
||
|
}
|
||
|
const [mnemonic, password] = words.length === 25
|
||
|
? [words.slice(0, 24).join(' '), words[24]]
|
||
|
: [words.join(' '), ''];
|
||
|
if (!mnemonicValidate(mnemonic)) {
|
||
|
throw new Error('Invalid mnemonic passed to ledger derivation');
|
||
|
}
|
||
|
else if (!hdValidatePath(path)) {
|
||
|
throw new Error('Invalid derivation path');
|
||
|
}
|
||
|
const parts = path.split('/').slice(1);
|
||
|
let seed = ledgerMaster(mnemonic, password);
|
||
|
for (const p of parts) {
|
||
|
const n = parseInt(p.replace(/'$/, ''), 10);
|
||
|
seed = ledgerDerivePrivate(seed, (n < HARDENED) ? (n + HARDENED) : n);
|
||
|
}
|
||
|
return ed25519PairFromSeed(seed.slice(0, 32));
|
||
|
}
|
||
|
|
||
|
function L32(x, c) { return (x << c) | (x >>> (32 - c)); }
|
||
|
function ld32(x, i) {
|
||
|
let u = x[i + 3] & 0xff;
|
||
|
u = (u << 8) | (x[i + 2] & 0xff);
|
||
|
u = (u << 8) | (x[i + 1] & 0xff);
|
||
|
return (u << 8) | (x[i + 0] & 0xff);
|
||
|
}
|
||
|
function st32(x, j, u) {
|
||
|
for (let i = 0; i < 4; i++) {
|
||
|
x[j + i] = u & 255;
|
||
|
u >>>= 8;
|
||
|
}
|
||
|
}
|
||
|
function vn(x, xi, y, yi, n) {
|
||
|
let d = 0;
|
||
|
for (let i = 0; i < n; i++)
|
||
|
d |= x[xi + i] ^ y[yi + i];
|
||
|
return (1 & ((d - 1) >>> 8)) - 1;
|
||
|
}
|
||
|
function core(out, inp, k, c, h) {
|
||
|
const w = new Uint32Array(16), x = new Uint32Array(16), y = new Uint32Array(16), t = new Uint32Array(4);
|
||
|
let i, j, m;
|
||
|
for (i = 0; i < 4; i++) {
|
||
|
x[5 * i] = ld32(c, 4 * i);
|
||
|
x[1 + i] = ld32(k, 4 * i);
|
||
|
x[6 + i] = ld32(inp, 4 * i);
|
||
|
x[11 + i] = ld32(k, 16 + 4 * i);
|
||
|
}
|
||
|
for (i = 0; i < 16; i++)
|
||
|
y[i] = x[i];
|
||
|
for (i = 0; i < 20; i++) {
|
||
|
for (j = 0; j < 4; j++) {
|
||
|
for (m = 0; m < 4; m++)
|
||
|
t[m] = x[(5 * j + 4 * m) % 16];
|
||
|
t[1] ^= L32((t[0] + t[3]) | 0, 7);
|
||
|
t[2] ^= L32((t[1] + t[0]) | 0, 9);
|
||
|
t[3] ^= L32((t[2] + t[1]) | 0, 13);
|
||
|
t[0] ^= L32((t[3] + t[2]) | 0, 18);
|
||
|
for (m = 0; m < 4; m++)
|
||
|
w[4 * j + (j + m) % 4] = t[m];
|
||
|
}
|
||
|
for (m = 0; m < 16; m++)
|
||
|
x[m] = w[m];
|
||
|
}
|
||
|
if (h) {
|
||
|
for (i = 0; i < 16; i++)
|
||
|
x[i] = (x[i] + y[i]) | 0;
|
||
|
for (i = 0; i < 4; i++) {
|
||
|
x[5 * i] = (x[5 * i] - ld32(c, 4 * i)) | 0;
|
||
|
x[6 + i] = (x[6 + i] - ld32(inp, 4 * i)) | 0;
|
||
|
}
|
||
|
for (i = 0; i < 4; i++) {
|
||
|
st32(out, 4 * i, x[5 * i]);
|
||
|
st32(out, 16 + 4 * i, x[6 + i]);
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
for (i = 0; i < 16; i++)
|
||
|
st32(out, 4 * i, (x[i] + y[i]) | 0);
|
||
|
}
|
||
|
}
|
||
|
const sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107]);
|
||
|
function crypto_stream_salsa20_xor(c, cpos, m, mpos, b, n, k) {
|
||
|
const z = new Uint8Array(16), x = new Uint8Array(64);
|
||
|
let u, i;
|
||
|
if (!b)
|
||
|
return 0;
|
||
|
for (i = 0; i < 16; i++)
|
||
|
z[i] = 0;
|
||
|
for (i = 0; i < 8; i++)
|
||
|
z[i] = n[i];
|
||
|
while (b >= 64) {
|
||
|
core(x, z, k, sigma, false);
|
||
|
for (i = 0; i < 64; i++)
|
||
|
c[cpos + i] = (m ? m[mpos + i] : 0) ^ x[i];
|
||
|
u = 1;
|
||
|
for (i = 8; i < 16; i++) {
|
||
|
u = u + (z[i] & 0xff) | 0;
|
||
|
z[i] = u & 0xff;
|
||
|
u >>>= 8;
|
||
|
}
|
||
|
b -= 64;
|
||
|
cpos += 64;
|
||
|
if (m)
|
||
|
mpos += 64;
|
||
|
}
|
||
|
if (b > 0) {
|
||
|
core(x, z, k, sigma, false);
|
||
|
for (i = 0; i < b; i++)
|
||
|
c[cpos + i] = (m ? m[mpos + i] : 0) ^ x[i];
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
function crypto_stream_xor(c, cpos, m, mpos, d, n, k) {
|
||
|
const s = new Uint8Array(32);
|
||
|
core(s, n, k, sigma, true);
|
||
|
return crypto_stream_salsa20_xor(c, cpos, m, mpos, d, n.subarray(16), s);
|
||
|
}
|
||
|
function add1305(h, c) {
|
||
|
let u = 0;
|
||
|
for (let j = 0; j < 17; j++) {
|
||
|
u = (u + ((h[j] + c[j]) | 0)) | 0;
|
||
|
h[j] = u & 255;
|
||
|
u >>>= 8;
|
||
|
}
|
||
|
}
|
||
|
const minusp = new Uint32Array([5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252]);
|
||
|
function crypto_onetimeauth(out, outpos, m, mpos, n, k) {
|
||
|
let i, j, u;
|
||
|
const x = new Uint32Array(17), r = new Uint32Array(17), h = new Uint32Array(17), c = new Uint32Array(17), g = new Uint32Array(17);
|
||
|
for (j = 0; j < 17; j++)
|
||
|
r[j] = h[j] = 0;
|
||
|
for (j = 0; j < 16; j++)
|
||
|
r[j] = k[j];
|
||
|
r[3] &= 15;
|
||
|
r[4] &= 252;
|
||
|
r[7] &= 15;
|
||
|
r[8] &= 252;
|
||
|
r[11] &= 15;
|
||
|
r[12] &= 252;
|
||
|
r[15] &= 15;
|
||
|
while (n > 0) {
|
||
|
for (j = 0; j < 17; j++)
|
||
|
c[j] = 0;
|
||
|
for (j = 0; (j < 16) && (j < n); ++j)
|
||
|
c[j] = m[mpos + j];
|
||
|
c[j] = 1;
|
||
|
mpos += j;
|
||
|
n -= j;
|
||
|
add1305(h, c);
|
||
|
for (i = 0; i < 17; i++) {
|
||
|
x[i] = 0;
|
||
|
for (j = 0; j < 17; j++)
|
||
|
x[i] = (x[i] + (h[j] * ((j <= i) ? r[i - j] : ((320 * r[i + 17 - j]) | 0))) | 0) | 0;
|
||
|
}
|
||
|
for (i = 0; i < 17; i++)
|
||
|
h[i] = x[i];
|
||
|
u = 0;
|
||
|
for (j = 0; j < 16; j++) {
|
||
|
u = (u + h[j]) | 0;
|
||
|
h[j] = u & 255;
|
||
|
u >>>= 8;
|
||
|
}
|
||
|
u = (u + h[16]) | 0;
|
||
|
h[16] = u & 3;
|
||
|
u = (5 * (u >>> 2)) | 0;
|
||
|
for (j = 0; j < 16; j++) {
|
||
|
u = (u + h[j]) | 0;
|
||
|
h[j] = u & 255;
|
||
|
u >>>= 8;
|
||
|
}
|
||
|
u = (u + h[16]) | 0;
|
||
|
h[16] = u;
|
||
|
}
|
||
|
for (j = 0; j < 17; j++)
|
||
|
g[j] = h[j];
|
||
|
add1305(h, minusp);
|
||
|
const s = (-(h[16] >>> 7) | 0);
|
||
|
for (j = 0; j < 17; j++)
|
||
|
h[j] ^= s & (g[j] ^ h[j]);
|
||
|
for (j = 0; j < 16; j++)
|
||
|
c[j] = k[j + 16];
|
||
|
c[16] = 0;
|
||
|
add1305(h, c);
|
||
|
for (j = 0; j < 16; j++)
|
||
|
out[outpos + j] = h[j];
|
||
|
return 0;
|
||
|
}
|
||
|
function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) {
|
||
|
const x = new Uint8Array(16);
|
||
|
crypto_onetimeauth(x, 0, m, mpos, n, k);
|
||
|
return vn(h, hpos, x, 0, 16);
|
||
|
}
|
||
|
function crypto_secretbox(c, m, d, n, k) {
|
||
|
if (d < 32)
|
||
|
return -1;
|
||
|
crypto_stream_xor(c, 0, m, 0, d, n, k);
|
||
|
crypto_onetimeauth(c, 16, c, 32, d - 32, c);
|
||
|
for (let i = 0; i < 16; i++)
|
||
|
c[i] = 0;
|
||
|
return 0;
|
||
|
}
|
||
|
function crypto_secretbox_open(m, c, d, n, k) {
|
||
|
const x = new Uint8Array(32);
|
||
|
if (d < 32)
|
||
|
return -1;
|
||
|
crypto_stream_xor(x, 0, null, 0, 32, n, k);
|
||
|
if (crypto_onetimeauth_verify(c, 16, c, 32, d - 32, x) !== 0)
|
||
|
return -1;
|
||
|
crypto_stream_xor(m, 0, c, 0, d, n, k);
|
||
|
for (let i = 0; i < 32; i++)
|
||
|
m[i] = 0;
|
||
|
return 0;
|
||
|
}
|
||
|
const crypto_secretbox_KEYBYTES = 32;
|
||
|
const crypto_secretbox_NONCEBYTES = 24;
|
||
|
const crypto_secretbox_ZEROBYTES = 32;
|
||
|
const crypto_secretbox_BOXZEROBYTES = 16;
|
||
|
function checkLengths(k, n) {
|
||
|
if (k.length !== crypto_secretbox_KEYBYTES)
|
||
|
throw new Error('bad key size');
|
||
|
if (n.length !== crypto_secretbox_NONCEBYTES)
|
||
|
throw new Error('bad nonce size');
|
||
|
}
|
||
|
function checkArrayTypes(...args) {
|
||
|
for (let i = 0, count = args.length; i < count; i++) {
|
||
|
if (!(args[i] instanceof Uint8Array))
|
||
|
throw new TypeError('unexpected type, use Uint8Array');
|
||
|
}
|
||
|
}
|
||
|
function naclSecretbox(msg, nonce, key) {
|
||
|
checkArrayTypes(msg, nonce, key);
|
||
|
checkLengths(key, nonce);
|
||
|
const m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length);
|
||
|
const c = new Uint8Array(m.length);
|
||
|
for (let i = 0; i < msg.length; i++)
|
||
|
m[i + crypto_secretbox_ZEROBYTES] = msg[i];
|
||
|
crypto_secretbox(c, m, m.length, nonce, key);
|
||
|
return c.subarray(crypto_secretbox_BOXZEROBYTES);
|
||
|
}
|
||
|
function naclSecretboxOpen(box, nonce, key) {
|
||
|
checkArrayTypes(box, nonce, key);
|
||
|
checkLengths(key, nonce);
|
||
|
const c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length);
|
||
|
const m = new Uint8Array(c.length);
|
||
|
for (let i = 0; i < box.length; i++)
|
||
|
c[i + crypto_secretbox_BOXZEROBYTES] = box[i];
|
||
|
if (c.length < 32)
|
||
|
return null;
|
||
|
if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0)
|
||
|
return null;
|
||
|
return m.subarray(crypto_secretbox_ZEROBYTES);
|
||
|
}
|
||
|
|
||
|
function naclDecrypt(encrypted, nonce, secret) {
|
||
|
return naclSecretboxOpen(encrypted, nonce, secret);
|
||
|
}
|
||
|
|
||
|
function naclEncrypt(message, secret, nonce = randomAsU8a(24)) {
|
||
|
return {
|
||
|
encrypted: naclSecretbox(message, nonce, secret),
|
||
|
nonce
|
||
|
};
|
||
|
}
|
||
|
|
||
|
const rotl$1 = (a, b) => (a << b) | (a >>> (32 - b));
|
||
|
function XorAndSalsa(prev, pi, input, ii, out, oi) {
|
||
|
let y00 = prev[pi++] ^ input[ii++], y01 = prev[pi++] ^ input[ii++];
|
||
|
let y02 = prev[pi++] ^ input[ii++], y03 = prev[pi++] ^ input[ii++];
|
||
|
let y04 = prev[pi++] ^ input[ii++], y05 = prev[pi++] ^ input[ii++];
|
||
|
let y06 = prev[pi++] ^ input[ii++], y07 = prev[pi++] ^ input[ii++];
|
||
|
let y08 = prev[pi++] ^ input[ii++], y09 = prev[pi++] ^ input[ii++];
|
||
|
let y10 = prev[pi++] ^ input[ii++], y11 = prev[pi++] ^ input[ii++];
|
||
|
let y12 = prev[pi++] ^ input[ii++], y13 = prev[pi++] ^ input[ii++];
|
||
|
let y14 = prev[pi++] ^ input[ii++], y15 = prev[pi++] ^ input[ii++];
|
||
|
let x00 = y00, x01 = y01, x02 = y02, x03 = y03, x04 = y04, x05 = y05, x06 = y06, x07 = y07, x08 = y08, x09 = y09, x10 = y10, x11 = y11, x12 = y12, x13 = y13, x14 = y14, x15 = y15;
|
||
|
for (let i = 0; i < 8; i += 2) {
|
||
|
x04 ^= rotl$1(x00 + x12 | 0, 7);
|
||
|
x08 ^= rotl$1(x04 + x00 | 0, 9);
|
||
|
x12 ^= rotl$1(x08 + x04 | 0, 13);
|
||
|
x00 ^= rotl$1(x12 + x08 | 0, 18);
|
||
|
x09 ^= rotl$1(x05 + x01 | 0, 7);
|
||
|
x13 ^= rotl$1(x09 + x05 | 0, 9);
|
||
|
x01 ^= rotl$1(x13 + x09 | 0, 13);
|
||
|
x05 ^= rotl$1(x01 + x13 | 0, 18);
|
||
|
x14 ^= rotl$1(x10 + x06 | 0, 7);
|
||
|
x02 ^= rotl$1(x14 + x10 | 0, 9);
|
||
|
x06 ^= rotl$1(x02 + x14 | 0, 13);
|
||
|
x10 ^= rotl$1(x06 + x02 | 0, 18);
|
||
|
x03 ^= rotl$1(x15 + x11 | 0, 7);
|
||
|
x07 ^= rotl$1(x03 + x15 | 0, 9);
|
||
|
x11 ^= rotl$1(x07 + x03 | 0, 13);
|
||
|
x15 ^= rotl$1(x11 + x07 | 0, 18);
|
||
|
x01 ^= rotl$1(x00 + x03 | 0, 7);
|
||
|
x02 ^= rotl$1(x01 + x00 | 0, 9);
|
||
|
x03 ^= rotl$1(x02 + x01 | 0, 13);
|
||
|
x00 ^= rotl$1(x03 + x02 | 0, 18);
|
||
|
x06 ^= rotl$1(x05 + x04 | 0, 7);
|
||
|
x07 ^= rotl$1(x06 + x05 | 0, 9);
|
||
|
x04 ^= rotl$1(x07 + x06 | 0, 13);
|
||
|
x05 ^= rotl$1(x04 + x07 | 0, 18);
|
||
|
x11 ^= rotl$1(x10 + x09 | 0, 7);
|
||
|
x08 ^= rotl$1(x11 + x10 | 0, 9);
|
||
|
x09 ^= rotl$1(x08 + x11 | 0, 13);
|
||
|
x10 ^= rotl$1(x09 + x08 | 0, 18);
|
||
|
x12 ^= rotl$1(x15 + x14 | 0, 7);
|
||
|
x13 ^= rotl$1(x12 + x15 | 0, 9);
|
||
|
x14 ^= rotl$1(x13 + x12 | 0, 13);
|
||
|
x15 ^= rotl$1(x14 + x13 | 0, 18);
|
||
|
}
|
||
|
out[oi++] = (y00 + x00) | 0;
|
||
|
out[oi++] = (y01 + x01) | 0;
|
||
|
out[oi++] = (y02 + x02) | 0;
|
||
|
out[oi++] = (y03 + x03) | 0;
|
||
|
out[oi++] = (y04 + x04) | 0;
|
||
|
out[oi++] = (y05 + x05) | 0;
|
||
|
out[oi++] = (y06 + x06) | 0;
|
||
|
out[oi++] = (y07 + x07) | 0;
|
||
|
out[oi++] = (y08 + x08) | 0;
|
||
|
out[oi++] = (y09 + x09) | 0;
|
||
|
out[oi++] = (y10 + x10) | 0;
|
||
|
out[oi++] = (y11 + x11) | 0;
|
||
|
out[oi++] = (y12 + x12) | 0;
|
||
|
out[oi++] = (y13 + x13) | 0;
|
||
|
out[oi++] = (y14 + x14) | 0;
|
||
|
out[oi++] = (y15 + x15) | 0;
|
||
|
}
|
||
|
function BlockMix(input, ii, out, oi, r) {
|
||
|
let head = oi + 0;
|
||
|
let tail = oi + 16 * r;
|
||
|
for (let i = 0; i < 16; i++)
|
||
|
out[tail + i] = input[ii + (2 * r - 1) * 16 + i];
|
||
|
for (let i = 0; i < r; i++, head += 16, ii += 16) {
|
||
|
XorAndSalsa(out, tail, input, ii, out, head);
|
||
|
if (i > 0)
|
||
|
tail += 16;
|
||
|
XorAndSalsa(out, head, input, (ii += 16), out, tail);
|
||
|
}
|
||
|
}
|
||
|
function scryptInit(password, salt, _opts) {
|
||
|
const opts = checkOpts({
|
||
|
dkLen: 32,
|
||
|
asyncTick: 10,
|
||
|
maxmem: 1024 ** 3 + 1024,
|
||
|
}, _opts);
|
||
|
const { N, r, p, dkLen, asyncTick, maxmem, onProgress } = opts;
|
||
|
number(N);
|
||
|
number(r);
|
||
|
number(p);
|
||
|
number(dkLen);
|
||
|
number(asyncTick);
|
||
|
number(maxmem);
|
||
|
if (onProgress !== undefined && typeof onProgress !== 'function')
|
||
|
throw new Error('progressCb should be function');
|
||
|
const blockSize = 128 * r;
|
||
|
const blockSize32 = blockSize / 4;
|
||
|
if (N <= 1 || (N & (N - 1)) !== 0 || N >= 2 ** (blockSize / 8) || N > 2 ** 32) {
|
||
|
throw new Error('Scrypt: N must be larger than 1, a power of 2, less than 2^(128 * r / 8) and less than 2^32');
|
||
|
}
|
||
|
if (p < 0 || p > ((2 ** 32 - 1) * 32) / blockSize) {
|
||
|
throw new Error('Scrypt: p must be a positive integer less than or equal to ((2^32 - 1) * 32) / (128 * r)');
|
||
|
}
|
||
|
if (dkLen < 0 || dkLen > (2 ** 32 - 1) * 32) {
|
||
|
throw new Error('Scrypt: dkLen should be positive integer less than or equal to (2^32 - 1) * 32');
|
||
|
}
|
||
|
const memUsed = blockSize * (N + p);
|
||
|
if (memUsed > maxmem) {
|
||
|
throw new Error(`Scrypt: parameters too large, ${memUsed} (128 * r * (N + p)) > ${maxmem} (maxmem)`);
|
||
|
}
|
||
|
const B = pbkdf2(sha256, password, salt, { c: 1, dkLen: blockSize * p });
|
||
|
const B32 = u32(B);
|
||
|
const V = u32(new Uint8Array(blockSize * N));
|
||
|
const tmp = u32(new Uint8Array(blockSize));
|
||
|
let blockMixCb = () => { };
|
||
|
if (onProgress) {
|
||
|
const totalBlockMix = 2 * N * p;
|
||
|
const callbackPer = Math.max(Math.floor(totalBlockMix / 10000), 1);
|
||
|
let blockMixCnt = 0;
|
||
|
blockMixCb = () => {
|
||
|
blockMixCnt++;
|
||
|
if (onProgress && (!(blockMixCnt % callbackPer) || blockMixCnt === totalBlockMix))
|
||
|
onProgress(blockMixCnt / totalBlockMix);
|
||
|
};
|
||
|
}
|
||
|
return { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb, asyncTick };
|
||
|
}
|
||
|
function scryptOutput(password, dkLen, B, V, tmp) {
|
||
|
const res = pbkdf2(sha256, password, B, { c: 1, dkLen });
|
||
|
B.fill(0);
|
||
|
V.fill(0);
|
||
|
tmp.fill(0);
|
||
|
return res;
|
||
|
}
|
||
|
function scrypt(password, salt, opts) {
|
||
|
const { N, r, p, dkLen, blockSize32, V, B32, B, tmp, blockMixCb } = scryptInit(password, salt, opts);
|
||
|
for (let pi = 0; pi < p; pi++) {
|
||
|
const Pi = blockSize32 * pi;
|
||
|
for (let i = 0; i < blockSize32; i++)
|
||
|
V[i] = B32[Pi + i];
|
||
|
for (let i = 0, pos = 0; i < N - 1; i++) {
|
||
|
BlockMix(V, pos, V, (pos += blockSize32), r);
|
||
|
blockMixCb();
|
||
|
}
|
||
|
BlockMix(V, (N - 1) * blockSize32, B32, Pi, r);
|
||
|
blockMixCb();
|
||
|
for (let i = 0; i < N; i++) {
|
||
|
const j = B32[Pi + blockSize32 - 16] % N;
|
||
|
for (let k = 0; k < blockSize32; k++)
|
||
|
tmp[k] = B32[Pi + k] ^ V[j * blockSize32 + k];
|
||
|
BlockMix(tmp, 0, B32, Pi, r);
|
||
|
blockMixCb();
|
||
|
}
|
||
|
}
|
||
|
return scryptOutput(password, dkLen, B, V, tmp);
|
||
|
}
|
||
|
|
||
|
const DEFAULT_PARAMS = {
|
||
|
N: 1 << 15,
|
||
|
p: 1,
|
||
|
r: 8
|
||
|
};
|
||
|
|
||
|
function scryptEncode(passphrase, salt = randomAsU8a(), params = DEFAULT_PARAMS, onlyJs) {
|
||
|
const u8a = util.u8aToU8a(passphrase);
|
||
|
return {
|
||
|
params,
|
||
|
password: !util.hasBigInt || (!onlyJs && isReady())
|
||
|
? scrypt$1(u8a, salt, Math.log2(params.N), params.r, params.p)
|
||
|
: scrypt(u8a, salt, util.objectSpread({ dkLen: 64 }, params)),
|
||
|
salt
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function scryptFromU8a(data) {
|
||
|
const salt = data.subarray(0, 32);
|
||
|
const N = util.u8aToBn(data.subarray(32 + 0, 32 + 4), BN_LE_OPTS).toNumber();
|
||
|
const p = util.u8aToBn(data.subarray(32 + 4, 32 + 8), BN_LE_OPTS).toNumber();
|
||
|
const r = util.u8aToBn(data.subarray(32 + 8, 32 + 12), BN_LE_OPTS).toNumber();
|
||
|
if (N !== DEFAULT_PARAMS.N || p !== DEFAULT_PARAMS.p || r !== DEFAULT_PARAMS.r) {
|
||
|
throw new Error('Invalid injected scrypt params found');
|
||
|
}
|
||
|
return { params: { N, p, r }, salt };
|
||
|
}
|
||
|
|
||
|
function scryptToU8a(salt, { N, p, r }) {
|
||
|
return util.u8aConcat(salt, util.bnToU8a(N, BN_LE_32_OPTS), util.bnToU8a(p, BN_LE_32_OPTS), util.bnToU8a(r, BN_LE_32_OPTS));
|
||
|
}
|
||
|
|
||
|
const ENCODING = ['scrypt', 'xsalsa20-poly1305'];
|
||
|
const ENCODING_NONE = ['none'];
|
||
|
const ENCODING_VERSION = '3';
|
||
|
const NONCE_LENGTH = 24;
|
||
|
const SCRYPT_LENGTH = 32 + (3 * 4);
|
||
|
|
||
|
function jsonDecryptData(encrypted, passphrase, encType = ENCODING) {
|
||
|
if (!encrypted) {
|
||
|
throw new Error('No encrypted data available to decode');
|
||
|
}
|
||
|
else if (encType.includes('xsalsa20-poly1305') && !passphrase) {
|
||
|
throw new Error('Password required to decode encrypted data');
|
||
|
}
|
||
|
let encoded = encrypted;
|
||
|
if (passphrase) {
|
||
|
let password;
|
||
|
if (encType.includes('scrypt')) {
|
||
|
const { params, salt } = scryptFromU8a(encrypted);
|
||
|
password = scryptEncode(passphrase, salt, params).password;
|
||
|
encrypted = encrypted.subarray(SCRYPT_LENGTH);
|
||
|
}
|
||
|
else {
|
||
|
password = util.stringToU8a(passphrase);
|
||
|
}
|
||
|
encoded = naclDecrypt(encrypted.subarray(NONCE_LENGTH), encrypted.subarray(0, NONCE_LENGTH), util.u8aFixLength(password, 256, true));
|
||
|
}
|
||
|
if (!encoded) {
|
||
|
throw new Error('Unable to decode using the supplied passphrase');
|
||
|
}
|
||
|
return encoded;
|
||
|
}
|
||
|
|
||
|
function jsonDecrypt({ encoded, encoding }, passphrase) {
|
||
|
if (!encoded) {
|
||
|
throw new Error('No encrypted data available to decode');
|
||
|
}
|
||
|
return jsonDecryptData(util.isHex(encoded)
|
||
|
? util.hexToU8a(encoded)
|
||
|
: base64Decode(encoded), passphrase, Array.isArray(encoding.type)
|
||
|
? encoding.type
|
||
|
: [encoding.type]);
|
||
|
}
|
||
|
|
||
|
function jsonEncryptFormat(encoded, contentType, isEncrypted) {
|
||
|
return {
|
||
|
encoded: base64Encode(encoded),
|
||
|
encoding: {
|
||
|
content: contentType,
|
||
|
type: isEncrypted
|
||
|
? ENCODING
|
||
|
: ENCODING_NONE,
|
||
|
version: ENCODING_VERSION
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
function jsonEncrypt(data, contentType, passphrase) {
|
||
|
let isEncrypted = false;
|
||
|
let encoded = data;
|
||
|
if (passphrase) {
|
||
|
const { params, password, salt } = scryptEncode(passphrase);
|
||
|
const { encrypted, nonce } = naclEncrypt(encoded, password.subarray(0, 32));
|
||
|
isEncrypted = true;
|
||
|
encoded = util.u8aConcat(scryptToU8a(salt, params), nonce, encrypted);
|
||
|
}
|
||
|
return jsonEncryptFormat(encoded, contentType, isEncrypted);
|
||
|
}
|
||
|
|
||
|
const secp256k1VerifyHasher = (hashType) => (message, signature, publicKey) => secp256k1Verify(message, signature, publicKey, hashType);
|
||
|
const VERIFIERS_ECDSA = [
|
||
|
['ecdsa', secp256k1VerifyHasher('blake2')],
|
||
|
['ethereum', secp256k1VerifyHasher('keccak')]
|
||
|
];
|
||
|
const VERIFIERS = [
|
||
|
['ed25519', ed25519Verify],
|
||
|
['sr25519', sr25519Verify],
|
||
|
...VERIFIERS_ECDSA
|
||
|
];
|
||
|
const CRYPTO_TYPES = ['ed25519', 'sr25519', 'ecdsa'];
|
||
|
function verifyDetect(result, { message, publicKey, signature }, verifiers = VERIFIERS) {
|
||
|
result.isValid = verifiers.some(([crypto, verify]) => {
|
||
|
try {
|
||
|
if (verify(message, signature, publicKey)) {
|
||
|
result.crypto = crypto;
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
catch {
|
||
|
}
|
||
|
return false;
|
||
|
});
|
||
|
return result;
|
||
|
}
|
||
|
function verifyMultisig(result, { message, publicKey, signature }) {
|
||
|
if (![0, 1, 2].includes(signature[0])) {
|
||
|
throw new Error(`Unknown crypto type, expected signature prefix [0..2], found ${signature[0]}`);
|
||
|
}
|
||
|
const type = CRYPTO_TYPES[signature[0]] || 'none';
|
||
|
result.crypto = type;
|
||
|
try {
|
||
|
result.isValid = {
|
||
|
ecdsa: () => verifyDetect(result, { message, publicKey, signature: signature.subarray(1) }, VERIFIERS_ECDSA).isValid,
|
||
|
ed25519: () => ed25519Verify(message, signature.subarray(1), publicKey),
|
||
|
none: () => {
|
||
|
throw Error('no verify for `none` crypto type');
|
||
|
},
|
||
|
sr25519: () => sr25519Verify(message, signature.subarray(1), publicKey)
|
||
|
}[type]();
|
||
|
}
|
||
|
catch {
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
function getVerifyFn(signature) {
|
||
|
return [0, 1, 2].includes(signature[0]) && [65, 66].includes(signature.length)
|
||
|
? verifyMultisig
|
||
|
: verifyDetect;
|
||
|
}
|
||
|
function signatureVerify(message, signature, addressOrPublicKey) {
|
||
|
const signatureU8a = util.u8aToU8a(signature);
|
||
|
if (![64, 65, 66].includes(signatureU8a.length)) {
|
||
|
throw new Error(`Invalid signature length, expected [64..66] bytes, found ${signatureU8a.length}`);
|
||
|
}
|
||
|
const publicKey = decodeAddress(addressOrPublicKey);
|
||
|
const input = { message: util.u8aToU8a(message), publicKey, signature: signatureU8a };
|
||
|
const result = { crypto: 'none', isValid: false, isWrapped: util.u8aIsWrapped(input.message, true), publicKey };
|
||
|
const isWrappedBytes = util.u8aIsWrapped(input.message, false);
|
||
|
const verifyFn = getVerifyFn(signatureU8a);
|
||
|
verifyFn(result, input);
|
||
|
if (result.crypto !== 'none' || (result.isWrapped && !isWrappedBytes)) {
|
||
|
return result;
|
||
|
}
|
||
|
input.message = isWrappedBytes
|
||
|
? util.u8aUnwrapBytes(input.message)
|
||
|
: util.u8aWrapBytes(input.message);
|
||
|
return verifyFn(result, input);
|
||
|
}
|
||
|
|
||
|
const P64_1 = BigInt$1('11400714785074694791');
|
||
|
const P64_2 = BigInt$1('14029467366897019727');
|
||
|
const P64_3 = BigInt$1('1609587929392839161');
|
||
|
const P64_4 = BigInt$1('9650029242287828579');
|
||
|
const P64_5 = BigInt$1('2870177450012600261');
|
||
|
const U64 = BigInt$1('0xffffffffffffffff');
|
||
|
const _7n = BigInt$1(7);
|
||
|
const _11n = BigInt$1(11);
|
||
|
const _12n = BigInt$1(12);
|
||
|
const _16n = BigInt$1(16);
|
||
|
const _18n = BigInt$1(18);
|
||
|
const _23n = BigInt$1(23);
|
||
|
const _27n = BigInt$1(27);
|
||
|
const _29n = BigInt$1(29);
|
||
|
const _31n = BigInt$1(31);
|
||
|
const _32n = BigInt$1(32);
|
||
|
const _33n = BigInt$1(33);
|
||
|
const _64n = BigInt$1(64);
|
||
|
const _256n = BigInt$1(256);
|
||
|
function rotl(a, b) {
|
||
|
const c = a & U64;
|
||
|
return ((c << b) | (c >> (_64n - b))) & U64;
|
||
|
}
|
||
|
function fromU8a(u8a, p, count) {
|
||
|
const bigints = new Array(count);
|
||
|
let offset = 0;
|
||
|
for (let i = 0; i < count; i++, offset += 2) {
|
||
|
bigints[i] = BigInt$1(u8a[p + offset] | (u8a[p + 1 + offset] << 8));
|
||
|
}
|
||
|
let result = util._0n;
|
||
|
for (let i = count - 1; i >= 0; i--) {
|
||
|
result = (result << _16n) + bigints[i];
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
function init(seed, input) {
|
||
|
const state = {
|
||
|
seed,
|
||
|
u8a: new Uint8Array(32),
|
||
|
u8asize: 0,
|
||
|
v1: seed + P64_1 + P64_2,
|
||
|
v2: seed + P64_2,
|
||
|
v3: seed,
|
||
|
v4: seed - P64_1
|
||
|
};
|
||
|
if (input.length < 32) {
|
||
|
state.u8a.set(input);
|
||
|
state.u8asize = input.length;
|
||
|
return state;
|
||
|
}
|
||
|
const limit = input.length - 32;
|
||
|
let p = 0;
|
||
|
if (limit >= 0) {
|
||
|
const adjustV = (v) => P64_1 * rotl(v + P64_2 * fromU8a(input, p, 4), _31n);
|
||
|
do {
|
||
|
state.v1 = adjustV(state.v1);
|
||
|
p += 8;
|
||
|
state.v2 = adjustV(state.v2);
|
||
|
p += 8;
|
||
|
state.v3 = adjustV(state.v3);
|
||
|
p += 8;
|
||
|
state.v4 = adjustV(state.v4);
|
||
|
p += 8;
|
||
|
} while (p <= limit);
|
||
|
}
|
||
|
if (p < input.length) {
|
||
|
state.u8a.set(input.subarray(p, input.length));
|
||
|
state.u8asize = input.length - p;
|
||
|
}
|
||
|
return state;
|
||
|
}
|
||
|
function xxhash64(input, initSeed) {
|
||
|
const { seed, u8a, u8asize, v1, v2, v3, v4 } = init(BigInt$1(initSeed), input);
|
||
|
let p = 0;
|
||
|
let h64 = U64 & (BigInt$1(input.length) + (input.length >= 32
|
||
|
? (((((((((rotl(v1, util._1n) + rotl(v2, _7n) + rotl(v3, _12n) + rotl(v4, _18n)) ^ (P64_1 * rotl(v1 * P64_2, _31n))) * P64_1 + P64_4) ^ (P64_1 * rotl(v2 * P64_2, _31n))) * P64_1 + P64_4) ^ (P64_1 * rotl(v3 * P64_2, _31n))) * P64_1 + P64_4) ^ (P64_1 * rotl(v4 * P64_2, _31n))) * P64_1 + P64_4)
|
||
|
: (seed + P64_5)));
|
||
|
while (p <= (u8asize - 8)) {
|
||
|
h64 = U64 & (P64_4 + P64_1 * rotl(h64 ^ (P64_1 * rotl(P64_2 * fromU8a(u8a, p, 4), _31n)), _27n));
|
||
|
p += 8;
|
||
|
}
|
||
|
if ((p + 4) <= u8asize) {
|
||
|
h64 = U64 & (P64_3 + P64_2 * rotl(h64 ^ (P64_1 * fromU8a(u8a, p, 2)), _23n));
|
||
|
p += 4;
|
||
|
}
|
||
|
while (p < u8asize) {
|
||
|
h64 = U64 & (P64_1 * rotl(h64 ^ (P64_5 * BigInt$1(u8a[p++])), _11n));
|
||
|
}
|
||
|
h64 = U64 & (P64_2 * (h64 ^ (h64 >> _33n)));
|
||
|
h64 = U64 & (P64_3 * (h64 ^ (h64 >> _29n)));
|
||
|
h64 = U64 & (h64 ^ (h64 >> _32n));
|
||
|
const result = new Uint8Array(8);
|
||
|
for (let i = 7; i >= 0; i--) {
|
||
|
result[i] = Number(h64 % _256n);
|
||
|
h64 = h64 / _256n;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
function xxhashAsU8a(data, bitLength = 64, onlyJs) {
|
||
|
const rounds = Math.ceil(bitLength / 64);
|
||
|
const u8a = util.u8aToU8a(data);
|
||
|
if (!util.hasBigInt || (!onlyJs && isReady())) {
|
||
|
return twox(u8a, rounds);
|
||
|
}
|
||
|
const result = new Uint8Array(rounds * 8);
|
||
|
for (let seed = 0; seed < rounds; seed++) {
|
||
|
result.set(xxhash64(u8a, seed).reverse(), seed * 8);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
const xxhashAsHex = createAsHex(xxhashAsU8a);
|
||
|
|
||
|
exports.addressEq = addressEq;
|
||
|
exports.addressToEvm = addressToEvm;
|
||
|
exports.allNetworks = allNetworks;
|
||
|
exports.availableNetworks = availableNetworks;
|
||
|
exports.base32Decode = base32Decode;
|
||
|
exports.base32Encode = base32Encode;
|
||
|
exports.base32Validate = base32Validate;
|
||
|
exports.base58Decode = base58Decode;
|
||
|
exports.base58Encode = base58Encode;
|
||
|
exports.base58Validate = base58Validate;
|
||
|
exports.base64Decode = base64Decode;
|
||
|
exports.base64Encode = base64Encode;
|
||
|
exports.base64Pad = base64Pad;
|
||
|
exports.base64Trim = base64Trim;
|
||
|
exports.base64Validate = base64Validate;
|
||
|
exports.blake2AsHex = blake2AsHex;
|
||
|
exports.blake2AsU8a = blake2AsU8a;
|
||
|
exports.checkAddress = checkAddress;
|
||
|
exports.checkAddressChecksum = checkAddressChecksum;
|
||
|
exports.createKeyDerived = createKeyDerived;
|
||
|
exports.createKeyMulti = createKeyMulti;
|
||
|
exports.cryptoIsReady = cryptoIsReady;
|
||
|
exports.cryptoWaitReady = cryptoWaitReady;
|
||
|
exports.decodeAddress = decodeAddress;
|
||
|
exports.deriveAddress = deriveAddress;
|
||
|
exports.ed25519DeriveHard = ed25519DeriveHard;
|
||
|
exports.ed25519PairFromRandom = ed25519PairFromRandom;
|
||
|
exports.ed25519PairFromSecret = ed25519PairFromSecret;
|
||
|
exports.ed25519PairFromSeed = ed25519PairFromSeed;
|
||
|
exports.ed25519PairFromString = ed25519PairFromString;
|
||
|
exports.ed25519Sign = ed25519Sign;
|
||
|
exports.ed25519Verify = ed25519Verify;
|
||
|
exports.encodeAddress = encodeAddress;
|
||
|
exports.encodeDerivedAddress = encodeDerivedAddress;
|
||
|
exports.encodeMultiAddress = encodeMultiAddress;
|
||
|
exports.ethereumEncode = ethereumEncode;
|
||
|
exports.evmToAddress = evmToAddress;
|
||
|
exports.hdEthereum = hdEthereum;
|
||
|
exports.hdLedger = hdLedger;
|
||
|
exports.hdValidatePath = hdValidatePath;
|
||
|
exports.hmacSha256AsU8a = hmacSha256AsU8a;
|
||
|
exports.hmacSha512AsU8a = hmacSha512AsU8a;
|
||
|
exports.hmacShaAsU8a = hmacShaAsU8a;
|
||
|
exports.isAddress = isAddress;
|
||
|
exports.isBase32 = isBase32;
|
||
|
exports.isBase58 = isBase58;
|
||
|
exports.isBase64 = isBase64;
|
||
|
exports.isEthereumAddress = isEthereumAddress;
|
||
|
exports.isEthereumChecksum = isEthereumChecksum;
|
||
|
exports.jsonDecrypt = jsonDecrypt;
|
||
|
exports.jsonDecryptData = jsonDecryptData;
|
||
|
exports.jsonEncrypt = jsonEncrypt;
|
||
|
exports.jsonEncryptFormat = jsonEncryptFormat;
|
||
|
exports.keccak256AsU8a = keccak256AsU8a;
|
||
|
exports.keccak512AsU8a = keccak512AsU8a;
|
||
|
exports.keccakAsHex = keccakAsHex;
|
||
|
exports.keccakAsU8a = keccakAsU8a;
|
||
|
exports.keyExtractPath = keyExtractPath;
|
||
|
exports.keyExtractSuri = keyExtractSuri;
|
||
|
exports.keyFromPath = keyFromPath;
|
||
|
exports.keyHdkdEcdsa = keyHdkdEcdsa;
|
||
|
exports.keyHdkdEd25519 = keyHdkdEd25519;
|
||
|
exports.keyHdkdSr25519 = keyHdkdSr25519;
|
||
|
exports.mnemonicGenerate = mnemonicGenerate;
|
||
|
exports.mnemonicToEntropy = mnemonicToEntropy;
|
||
|
exports.mnemonicToLegacySeed = mnemonicToLegacySeed;
|
||
|
exports.mnemonicToMiniSecret = mnemonicToMiniSecret;
|
||
|
exports.mnemonicValidate = mnemonicValidate;
|
||
|
exports.naclDecrypt = naclDecrypt;
|
||
|
exports.naclEncrypt = naclEncrypt;
|
||
|
exports.packageInfo = packageInfo;
|
||
|
exports.pbkdf2Encode = pbkdf2Encode;
|
||
|
exports.randomAsHex = randomAsHex;
|
||
|
exports.randomAsNumber = randomAsNumber;
|
||
|
exports.randomAsU8a = randomAsU8a;
|
||
|
exports.scryptEncode = scryptEncode;
|
||
|
exports.scryptFromU8a = scryptFromU8a;
|
||
|
exports.scryptToU8a = scryptToU8a;
|
||
|
exports.secp256k1Compress = secp256k1Compress;
|
||
|
exports.secp256k1Expand = secp256k1Expand;
|
||
|
exports.secp256k1PairFromSeed = secp256k1PairFromSeed;
|
||
|
exports.secp256k1PrivateKeyTweakAdd = secp256k1PrivateKeyTweakAdd;
|
||
|
exports.secp256k1Recover = secp256k1Recover;
|
||
|
exports.secp256k1Sign = secp256k1Sign;
|
||
|
exports.secp256k1Verify = secp256k1Verify;
|
||
|
exports.selectableNetworks = selectableNetworks;
|
||
|
exports.setSS58Format = setSS58Format;
|
||
|
exports.sha256AsU8a = sha256AsU8a;
|
||
|
exports.sha512AsU8a = sha512AsU8a;
|
||
|
exports.shaAsU8a = shaAsU8a;
|
||
|
exports.signatureVerify = signatureVerify;
|
||
|
exports.sortAddresses = sortAddresses;
|
||
|
exports.sr25519Agreement = sr25519Agreement;
|
||
|
exports.sr25519DeriveHard = sr25519DeriveHard;
|
||
|
exports.sr25519DerivePublic = sr25519DerivePublic;
|
||
|
exports.sr25519DeriveSoft = sr25519DeriveSoft;
|
||
|
exports.sr25519PairFromSeed = sr25519PairFromSeed;
|
||
|
exports.sr25519Sign = sr25519Sign;
|
||
|
exports.sr25519Verify = sr25519Verify;
|
||
|
exports.sr25519VrfSign = sr25519VrfSign;
|
||
|
exports.sr25519VrfVerify = sr25519VrfVerify;
|
||
|
exports.validateAddress = validateAddress;
|
||
|
exports.xxhashAsHex = xxhashAsHex;
|
||
|
exports.xxhashAsU8a = xxhashAsU8a;
|
||
|
|
||
|
}));
|