@qntx/wallet-worker 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/kernel.node.js +404 -404
- package/dist/kernel.worker.js +411 -408
- package/dist/node.mjs.map +1 -1
- package/package.json +4 -4
package/dist/kernel.node.js
CHANGED
|
@@ -489,11 +489,11 @@ function abytes(value, length, title = "") {
|
|
|
489
489
|
return value;
|
|
490
490
|
if (length !== undefined)
|
|
491
491
|
anumber(length, "length");
|
|
492
|
-
const
|
|
492
|
+
const bytes = isBytes(value);
|
|
493
493
|
const ofLen = length !== undefined ? ` of length ${length}` : "";
|
|
494
|
-
const got =
|
|
494
|
+
const got = bytes ? `length=${value.length}` : `type=${typeof value}`;
|
|
495
495
|
const message = atitle(title) + "expected Uint8Array" + ofLen + ", got " + got;
|
|
496
|
-
if (!
|
|
496
|
+
if (!bytes)
|
|
497
497
|
throw new TypeError(message);
|
|
498
498
|
throw new RangeError(message);
|
|
499
499
|
}
|
|
@@ -530,16 +530,16 @@ function aoutput(out, instance) {
|
|
|
530
530
|
throw new RangeError('"output" expected length >= ' + min);
|
|
531
531
|
}
|
|
532
532
|
}
|
|
533
|
-
function u32(
|
|
534
|
-
return new Uint32Array(
|
|
533
|
+
function u32(arr) {
|
|
534
|
+
return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
|
|
535
535
|
}
|
|
536
536
|
function clean(...arrays) {
|
|
537
537
|
for (let i = 0;i < arrays.length; i++) {
|
|
538
538
|
arrays[i].fill(0);
|
|
539
539
|
}
|
|
540
540
|
}
|
|
541
|
-
function createView(
|
|
542
|
-
return new DataView(
|
|
541
|
+
function createView(arr) {
|
|
542
|
+
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
543
543
|
}
|
|
544
544
|
function rotr(word, shift) {
|
|
545
545
|
return word << 32 - shift | word >>> shift;
|
|
@@ -551,22 +551,22 @@ var isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([287454020]).bu
|
|
|
551
551
|
function byteSwap(word) {
|
|
552
552
|
return word << 24 & 4278190080 | word << 8 & 16711680 | word >>> 8 & 65280 | word >>> 24 & 255;
|
|
553
553
|
}
|
|
554
|
-
function byteSwap32(
|
|
555
|
-
for (let i = 0;i <
|
|
556
|
-
|
|
554
|
+
function byteSwap32(arr) {
|
|
555
|
+
for (let i = 0;i < arr.length; i++) {
|
|
556
|
+
arr[i] = byteSwap(arr[i]);
|
|
557
557
|
}
|
|
558
|
-
return
|
|
558
|
+
return arr;
|
|
559
559
|
}
|
|
560
560
|
var swap32IfBE = isLE ? (u) => u : byteSwap32;
|
|
561
561
|
var hasHexBuiltin = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toHex === "function" && typeof Uint8Array.fromHex === "function")();
|
|
562
562
|
var hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
|
|
563
|
-
function bytesToHex(
|
|
564
|
-
abytes(
|
|
563
|
+
function bytesToHex(bytes) {
|
|
564
|
+
abytes(bytes);
|
|
565
565
|
if (hasHexBuiltin)
|
|
566
|
-
return
|
|
566
|
+
return bytes.toHex();
|
|
567
567
|
let hex = "";
|
|
568
|
-
for (let i = 0;i <
|
|
569
|
-
hex += hexes[
|
|
568
|
+
for (let i = 0;i < bytes.length; i++) {
|
|
569
|
+
hex += hexes[bytes[i]];
|
|
570
570
|
}
|
|
571
571
|
return hex;
|
|
572
572
|
}
|
|
@@ -626,10 +626,10 @@ async function asyncLoop(iters, tick, cb, onReject) {
|
|
|
626
626
|
ts = Date.now();
|
|
627
627
|
}
|
|
628
628
|
}
|
|
629
|
-
function utf8ToBytes(
|
|
630
|
-
if (typeof
|
|
629
|
+
function utf8ToBytes(str) {
|
|
630
|
+
if (typeof str !== "string")
|
|
631
631
|
throw new TypeError("string expected");
|
|
632
|
-
const encoded = new TextEncoder().encode(
|
|
632
|
+
const encoded = new TextEncoder().encode(str);
|
|
633
633
|
try {
|
|
634
634
|
return new Uint8Array(encoded);
|
|
635
635
|
} finally {
|
|
@@ -695,45 +695,45 @@ function wipe(...buffers) {
|
|
|
695
695
|
buffer.fill(0);
|
|
696
696
|
}
|
|
697
697
|
}
|
|
698
|
-
function decodeUtf8Secret(
|
|
698
|
+
function decodeUtf8Secret(bytes) {
|
|
699
699
|
try {
|
|
700
|
-
return new TextDecoder("utf-8", { fatal: true }).decode(
|
|
700
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
701
701
|
} catch {
|
|
702
702
|
throw new KernelError("invalid-input", "input is not valid UTF-8");
|
|
703
703
|
} finally {
|
|
704
|
-
wipe(
|
|
704
|
+
wipe(bytes);
|
|
705
705
|
}
|
|
706
706
|
}
|
|
707
707
|
|
|
708
708
|
class Secret {
|
|
709
709
|
#bytes;
|
|
710
|
-
constructor(
|
|
711
|
-
this.#bytes =
|
|
710
|
+
constructor(bytes) {
|
|
711
|
+
this.#bytes = bytes;
|
|
712
712
|
}
|
|
713
|
-
static take(
|
|
714
|
-
return new Secret(
|
|
713
|
+
static take(bytes) {
|
|
714
|
+
return new Secret(bytes);
|
|
715
715
|
}
|
|
716
716
|
get length() {
|
|
717
|
-
const
|
|
718
|
-
if (
|
|
717
|
+
const bytes = this.#bytes;
|
|
718
|
+
if (bytes === undefined) {
|
|
719
719
|
throw new KernelError("integrity", "secret already wiped");
|
|
720
720
|
}
|
|
721
|
-
return
|
|
721
|
+
return bytes.length;
|
|
722
722
|
}
|
|
723
723
|
get wiped() {
|
|
724
724
|
return this.#bytes === undefined;
|
|
725
725
|
}
|
|
726
726
|
use(fn) {
|
|
727
|
-
const
|
|
728
|
-
if (
|
|
727
|
+
const bytes = this.#bytes;
|
|
728
|
+
if (bytes === undefined) {
|
|
729
729
|
throw new KernelError("integrity", "secret already wiped");
|
|
730
730
|
}
|
|
731
|
-
return fn(
|
|
731
|
+
return fn(bytes);
|
|
732
732
|
}
|
|
733
733
|
wipe() {
|
|
734
|
-
const
|
|
735
|
-
if (
|
|
736
|
-
|
|
734
|
+
const bytes = this.#bytes;
|
|
735
|
+
if (bytes !== undefined) {
|
|
736
|
+
bytes.fill(0);
|
|
737
737
|
this.#bytes = undefined;
|
|
738
738
|
}
|
|
739
739
|
}
|
|
@@ -916,11 +916,11 @@ function split(lst, le = false) {
|
|
|
916
916
|
}
|
|
917
917
|
var fromNumH = (n) => n / 2 ** 32 | 0;
|
|
918
918
|
var fromNumL = (n) => n >>> 0;
|
|
919
|
-
function setU64FromNum(view, byteOffset, n,
|
|
919
|
+
function setU64FromNum(view, byteOffset, n, isLE) {
|
|
920
920
|
const h = fromNumH(n);
|
|
921
921
|
const l = fromNumL(n);
|
|
922
|
-
view.setUint32(byteOffset,
|
|
923
|
-
view.setUint32(byteOffset + 4,
|
|
922
|
+
view.setUint32(byteOffset, isLE ? l : h, isLE);
|
|
923
|
+
view.setUint32(byteOffset + 4, isLE ? h : l, isLE);
|
|
924
924
|
}
|
|
925
925
|
var shrSH = (h, _l, s) => h >>> s;
|
|
926
926
|
var shrSL = (h, l, s) => h << 32 - s | l >>> s;
|
|
@@ -959,11 +959,11 @@ class HashMD {
|
|
|
959
959
|
length = 0;
|
|
960
960
|
pos = 0;
|
|
961
961
|
destroyed = false;
|
|
962
|
-
constructor(blockLen, outputLen, padOffset,
|
|
962
|
+
constructor(blockLen, outputLen, padOffset, isLE) {
|
|
963
963
|
this.blockLen = blockLen;
|
|
964
964
|
this.outputLen = outputLen;
|
|
965
965
|
this.padOffset = padOffset;
|
|
966
|
-
this.isLE =
|
|
966
|
+
this.isLE = isLE;
|
|
967
967
|
this.buffer = new Uint8Array(blockLen);
|
|
968
968
|
this.view = createView(this.buffer);
|
|
969
969
|
}
|
|
@@ -1000,7 +1000,7 @@ class HashMD {
|
|
|
1000
1000
|
aexists(this);
|
|
1001
1001
|
aoutput(out, this);
|
|
1002
1002
|
this.finished = true;
|
|
1003
|
-
const { buffer, view, blockLen, isLE
|
|
1003
|
+
const { buffer, view, blockLen, isLE } = this;
|
|
1004
1004
|
let { pos } = this;
|
|
1005
1005
|
buffer[pos++] = 128;
|
|
1006
1006
|
buffer.fill(0, pos);
|
|
@@ -1008,7 +1008,7 @@ class HashMD {
|
|
|
1008
1008
|
this.process(view, 0);
|
|
1009
1009
|
buffer.fill(0);
|
|
1010
1010
|
}
|
|
1011
|
-
setU64FromNum(view, blockLen - 8, this.length * 8,
|
|
1011
|
+
setU64FromNum(view, blockLen - 8, this.length * 8, isLE);
|
|
1012
1012
|
this.process(view, 0);
|
|
1013
1013
|
this.roundClean();
|
|
1014
1014
|
const oview = out === buffer ? view : createView(out);
|
|
@@ -1018,7 +1018,7 @@ class HashMD {
|
|
|
1018
1018
|
if (len % 4 || outLen > state.length)
|
|
1019
1019
|
throw new Error("invalid outputLen");
|
|
1020
1020
|
for (let i = 0;i < outLen; i++)
|
|
1021
|
-
oview.setUint32(4 * i, state[i],
|
|
1021
|
+
oview.setUint32(4 * i, state[i], isLE);
|
|
1022
1022
|
}
|
|
1023
1023
|
digest() {
|
|
1024
1024
|
const { buffer, outputLen } = this;
|
|
@@ -1471,15 +1471,15 @@ function isWellFormedUnicode(value) {
|
|
|
1471
1471
|
}
|
|
1472
1472
|
return true;
|
|
1473
1473
|
}
|
|
1474
|
-
function nfkd(
|
|
1475
|
-
if (typeof
|
|
1476
|
-
throw new TypeError("invalid mnemonic type: " + typeof
|
|
1477
|
-
if (!isWellFormedUnicode(
|
|
1474
|
+
function nfkd(str) {
|
|
1475
|
+
if (typeof str !== "string")
|
|
1476
|
+
throw new TypeError("invalid mnemonic type: " + typeof str);
|
|
1477
|
+
if (!isWellFormedUnicode(str))
|
|
1478
1478
|
throw new TypeError("expected well-formed Unicode string");
|
|
1479
|
-
return
|
|
1479
|
+
return str.normalize("NFKD");
|
|
1480
1480
|
}
|
|
1481
|
-
function normalize(
|
|
1482
|
-
const norm = nfkd(
|
|
1481
|
+
function normalize(str) {
|
|
1482
|
+
const norm = nfkd(str);
|
|
1483
1483
|
const words = norm.split(" ");
|
|
1484
1484
|
if (![12, 15, 18, 21, 24].includes(words.length))
|
|
1485
1485
|
throw new Error("Invalid mnemonic");
|
|
@@ -1506,13 +1506,13 @@ function awordlist(wordlist) {
|
|
|
1506
1506
|
}
|
|
1507
1507
|
function encodeWords(entropy, wordlist) {
|
|
1508
1508
|
awordlist(wordlist);
|
|
1509
|
-
const
|
|
1510
|
-
|
|
1511
|
-
|
|
1509
|
+
const bytes = new Uint8Array(entropy.length + 1);
|
|
1510
|
+
bytes.set(entropy);
|
|
1511
|
+
bytes[entropy.length] = calcChecksum(entropy);
|
|
1512
1512
|
const words = [];
|
|
1513
1513
|
let carry = 0;
|
|
1514
1514
|
let bits = 0;
|
|
1515
|
-
for (const byte of
|
|
1515
|
+
for (const byte of bytes) {
|
|
1516
1516
|
carry = carry << 8 | byte;
|
|
1517
1517
|
bits += 8;
|
|
1518
1518
|
if (bits >= 11) {
|
|
@@ -1526,7 +1526,7 @@ function encodeWords(entropy, wordlist) {
|
|
|
1526
1526
|
function decodeWords(words, wordlist) {
|
|
1527
1527
|
awordlist(wordlist);
|
|
1528
1528
|
const entLen = words.length / 3 * 4;
|
|
1529
|
-
const
|
|
1529
|
+
const bytes = new Uint8Array(entLen + 1);
|
|
1530
1530
|
let carry = 0;
|
|
1531
1531
|
let bits = 0;
|
|
1532
1532
|
let pos = 0;
|
|
@@ -1538,14 +1538,14 @@ function decodeWords(words, wordlist) {
|
|
|
1538
1538
|
bits += 11;
|
|
1539
1539
|
while (bits >= 8) {
|
|
1540
1540
|
bits -= 8;
|
|
1541
|
-
|
|
1541
|
+
bytes[pos++] = carry >>> bits & 255;
|
|
1542
1542
|
}
|
|
1543
1543
|
carry &= (1 << bits) - 1;
|
|
1544
1544
|
}
|
|
1545
1545
|
if (bits > 0)
|
|
1546
|
-
|
|
1547
|
-
const entropy =
|
|
1548
|
-
if (
|
|
1546
|
+
bytes[pos] = carry << 8 - bits;
|
|
1547
|
+
const entropy = bytes.subarray(0, entLen);
|
|
1548
|
+
if (bytes[entLen] !== calcChecksum(entropy))
|
|
1549
1549
|
throw new Error("Invalid checksum");
|
|
1550
1550
|
return Uint8Array.from(entropy);
|
|
1551
1551
|
}
|
|
@@ -3653,15 +3653,15 @@ function abytes2(b) {
|
|
|
3653
3653
|
if (!isBytes2(b))
|
|
3654
3654
|
throw new TypeError("Uint8Array expected");
|
|
3655
3655
|
}
|
|
3656
|
-
function isArrayOf(isString,
|
|
3657
|
-
if (!Array.isArray(
|
|
3656
|
+
function isArrayOf(isString, arr) {
|
|
3657
|
+
if (!Array.isArray(arr))
|
|
3658
3658
|
return false;
|
|
3659
|
-
if (
|
|
3659
|
+
if (arr.length === 0)
|
|
3660
3660
|
return true;
|
|
3661
3661
|
if (isString) {
|
|
3662
|
-
return
|
|
3662
|
+
return arr.every((item) => typeof item === "string");
|
|
3663
3663
|
} else {
|
|
3664
|
-
return
|
|
3664
|
+
return arr.every((item) => Number.isSafeInteger(item));
|
|
3665
3665
|
}
|
|
3666
3666
|
}
|
|
3667
3667
|
function afn(input) {
|
|
@@ -3729,20 +3729,20 @@ function radix2(bits) {
|
|
|
3729
3729
|
throw new RangeError("radix2: bits should be in (0..8]");
|
|
3730
3730
|
const mask = powers[bits] - 1;
|
|
3731
3731
|
return {
|
|
3732
|
-
encode: (
|
|
3733
|
-
abytes2(
|
|
3734
|
-
const len =
|
|
3732
|
+
encode: (bytes) => {
|
|
3733
|
+
abytes2(bytes);
|
|
3734
|
+
const len = bytes.length;
|
|
3735
3735
|
const res = new Uint8Array(Math.ceil(len * 8 / bits));
|
|
3736
3736
|
let carry = 0;
|
|
3737
3737
|
let pos = 0;
|
|
3738
3738
|
let j = 0;
|
|
3739
3739
|
for (let i = 0;i < len; ) {
|
|
3740
3740
|
if (i + 2 < len) {
|
|
3741
|
-
carry = carry << 24 |
|
|
3741
|
+
carry = carry << 24 | bytes[i] << 16 | bytes[i + 1] << 8 | bytes[i + 2];
|
|
3742
3742
|
pos += 24;
|
|
3743
3743
|
i += 3;
|
|
3744
3744
|
} else {
|
|
3745
|
-
carry = (carry << 8 |
|
|
3745
|
+
carry = (carry << 8 | bytes[i]) & 65535;
|
|
3746
3746
|
pos += 8;
|
|
3747
3747
|
i++;
|
|
3748
3748
|
}
|
|
@@ -3889,10 +3889,10 @@ var hasBase64Builtin = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toBase6
|
|
|
3889
3889
|
var ASCII_WHITESPACE = /[\t\n\f\r ]/;
|
|
3890
3890
|
var decodeBase64Builtin = (s, isUrl) => {
|
|
3891
3891
|
astr("base64", s);
|
|
3892
|
-
const
|
|
3892
|
+
const alphabet = isUrl ? "base64url" : "base64";
|
|
3893
3893
|
if (s.length > 0 && ASCII_WHITESPACE.test(s))
|
|
3894
3894
|
throw new Error("invalid base64");
|
|
3895
|
-
return Uint8Array.fromBase64(s, { alphabet
|
|
3895
|
+
return Uint8Array.fromBase64(s, { alphabet, lastChunkHandling: "strict" });
|
|
3896
3896
|
};
|
|
3897
3897
|
var base64Fallback = /* @__PURE__ */ freeze(() => chain(radix2(6), alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), padding(6)));
|
|
3898
3898
|
var base64 = /* @__PURE__ */ freeze(() => hasBase64Builtin ? {
|
|
@@ -3910,23 +3910,23 @@ var RADIX_BASE_N_MAX_LENGTH = 65536;
|
|
|
3910
3910
|
var BASE_N_MAX_BYTES = 2048;
|
|
3911
3911
|
var BASE_N_MAX_CHARS = 4096;
|
|
3912
3912
|
var radixBaseN = (BASE, GROUP) => ({
|
|
3913
|
-
encode: (
|
|
3914
|
-
abytes2(
|
|
3915
|
-
const blen =
|
|
3913
|
+
encode: (bytes) => {
|
|
3914
|
+
abytes2(bytes);
|
|
3915
|
+
const blen = bytes.length;
|
|
3916
3916
|
if (blen === 0)
|
|
3917
3917
|
return new Uint8Array(0);
|
|
3918
3918
|
if (blen >= RADIX_BASE_N_MAX_LENGTH)
|
|
3919
3919
|
throw new Error("invalid length");
|
|
3920
3920
|
let zeros = 0;
|
|
3921
|
-
while (zeros < blen - 1 &&
|
|
3921
|
+
while (zeros < blen - 1 && bytes[zeros] === 0)
|
|
3922
3922
|
zeros++;
|
|
3923
3923
|
const nlimbs = Math.ceil(blen / 2);
|
|
3924
3924
|
const limbs = new Uint16Array(nlimbs);
|
|
3925
3925
|
const odd = blen & 1;
|
|
3926
3926
|
if (odd)
|
|
3927
|
-
limbs[0] =
|
|
3928
|
-
for (let i = odd,
|
|
3929
|
-
limbs[
|
|
3927
|
+
limbs[0] = bytes[0];
|
|
3928
|
+
for (let i = odd, j = odd;i < blen; i += 2, j++)
|
|
3929
|
+
limbs[j] = bytes[i] << 8 | bytes[i + 1];
|
|
3930
3930
|
const groups = [];
|
|
3931
3931
|
let pos = 0;
|
|
3932
3932
|
while (pos < nlimbs) {
|
|
@@ -3977,18 +3977,18 @@ var radixBaseN = (BASE, GROUP) => ({
|
|
|
3977
3977
|
let group = dlen % 5 || 5;
|
|
3978
3978
|
while (i < dlen) {
|
|
3979
3979
|
let gval = 0;
|
|
3980
|
-
let
|
|
3980
|
+
let factor = 1;
|
|
3981
3981
|
for (const end = i + group;i < end; i++) {
|
|
3982
3982
|
const d = digits[i];
|
|
3983
3983
|
if (d >= BASE)
|
|
3984
3984
|
throw new Error(`invalid integer: ${d}`);
|
|
3985
3985
|
gval = gval * BASE + d;
|
|
3986
|
-
|
|
3986
|
+
factor *= BASE;
|
|
3987
3987
|
}
|
|
3988
3988
|
group = 5;
|
|
3989
3989
|
let carry = gval;
|
|
3990
3990
|
for (let k = 0;k < used; k++) {
|
|
3991
|
-
const cur = limbs[k] *
|
|
3991
|
+
const cur = limbs[k] * factor + carry;
|
|
3992
3992
|
carry = Math.floor(cur / 65536);
|
|
3993
3993
|
limbs[k] = cur - carry * 65536;
|
|
3994
3994
|
}
|
|
@@ -4010,26 +4010,26 @@ var radixBaseN = (BASE, GROUP) => ({
|
|
|
4010
4010
|
var genBaseN = (radix, abc) => {
|
|
4011
4011
|
const letters = alphabet(abc);
|
|
4012
4012
|
return {
|
|
4013
|
-
encode(
|
|
4014
|
-
abytes2(
|
|
4015
|
-
if (
|
|
4013
|
+
encode(bytes) {
|
|
4014
|
+
abytes2(bytes);
|
|
4015
|
+
if (bytes.length > BASE_N_MAX_BYTES)
|
|
4016
4016
|
throw new Error("invalid length");
|
|
4017
|
-
return letters.encode(radix.encode(
|
|
4017
|
+
return letters.encode(radix.encode(bytes));
|
|
4018
4018
|
},
|
|
4019
|
-
decode(
|
|
4020
|
-
astr("baseN.decode",
|
|
4021
|
-
if (
|
|
4019
|
+
decode(str) {
|
|
4020
|
+
astr("baseN.decode", str);
|
|
4021
|
+
if (str.length > BASE_N_MAX_CHARS)
|
|
4022
4022
|
throw new Error("invalid length");
|
|
4023
|
-
return radix.decode(letters.decode(
|
|
4023
|
+
return radix.decode(letters.decode(str));
|
|
4024
4024
|
}
|
|
4025
4025
|
};
|
|
4026
4026
|
};
|
|
4027
4027
|
var radix58 = /* @__PURE__ */ radixBaseN(58, B58_GROUP);
|
|
4028
4028
|
var genBase58 = (abc) => genBaseN(radix58, abc);
|
|
4029
4029
|
var base58 = /* @__PURE__ */ freeze(() => genBase58("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"));
|
|
4030
|
-
var createBase58check = (
|
|
4031
|
-
afn(
|
|
4032
|
-
const _sha256 =
|
|
4030
|
+
var createBase58check = (sha256) => {
|
|
4031
|
+
afn(sha256);
|
|
4032
|
+
const _sha256 = sha256;
|
|
4033
4033
|
return chain(checksum(4, (data) => _sha256(_sha256(data))), base58);
|
|
4034
4034
|
};
|
|
4035
4035
|
var BECH_ALPHABET = /* @__PURE__ */ alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l");
|
|
@@ -4135,17 +4135,17 @@ function genBech32(encoding) {
|
|
|
4135
4135
|
const sum = bechChecksum(lowered, words, ENCODING_CONST);
|
|
4136
4136
|
return `${lowered}1${BECH_ALPHABET.encode(wordsToU8(words))}${sum}`;
|
|
4137
4137
|
}
|
|
4138
|
-
function decode(
|
|
4139
|
-
astr("bech32.decode input",
|
|
4138
|
+
function decode(str, limit = 90) {
|
|
4139
|
+
astr("bech32.decode input", str);
|
|
4140
4140
|
if (limit !== false)
|
|
4141
4141
|
anumber2(limit, "limit");
|
|
4142
|
-
const slen =
|
|
4142
|
+
const slen = str.length;
|
|
4143
4143
|
if (slen < 8 || limit !== false && slen > limit)
|
|
4144
4144
|
throw new TypeError(`invalid string length ${slen}, expected (8..${limit})`);
|
|
4145
|
-
const lowered =
|
|
4146
|
-
if (
|
|
4147
|
-
if (!BECH_UPPERCASE_PRINTABLE.test(
|
|
4148
|
-
assertBech32Printable("bech32.decode input",
|
|
4145
|
+
const lowered = str.toLowerCase();
|
|
4146
|
+
if (str !== lowered) {
|
|
4147
|
+
if (!BECH_UPPERCASE_PRINTABLE.test(str)) {
|
|
4148
|
+
assertBech32Printable("bech32.decode input", str);
|
|
4149
4149
|
throw new Error(`mixed-case string not allowed`);
|
|
4150
4150
|
}
|
|
4151
4151
|
}
|
|
@@ -4160,20 +4160,20 @@ function genBech32(encoding) {
|
|
|
4160
4160
|
const words = u8ToNumArr(digits, digits.length - 6);
|
|
4161
4161
|
const sum = bechChecksum(prefix, words, ENCODING_CONST);
|
|
4162
4162
|
if (!data.endsWith(sum))
|
|
4163
|
-
throw new Error(`Invalid checksum in ${
|
|
4163
|
+
throw new Error(`Invalid checksum in ${str}`);
|
|
4164
4164
|
return { prefix, words };
|
|
4165
4165
|
}
|
|
4166
4166
|
const decodeUnsafe = unsafeWrapper(decode);
|
|
4167
|
-
function decodeToBytes(
|
|
4168
|
-
const { prefix, words } = decode(
|
|
4167
|
+
function decodeToBytes(str, limit = 90) {
|
|
4168
|
+
const { prefix, words } = decode(str, limit);
|
|
4169
4169
|
return {
|
|
4170
4170
|
prefix,
|
|
4171
4171
|
words,
|
|
4172
4172
|
bytes: fromWords(words)
|
|
4173
4173
|
};
|
|
4174
4174
|
}
|
|
4175
|
-
function encodeFromBytes(prefix,
|
|
4176
|
-
return encode(prefix, toWords(
|
|
4175
|
+
function encodeFromBytes(prefix, bytes) {
|
|
4176
|
+
return encode(prefix, toWords(bytes));
|
|
4177
4177
|
}
|
|
4178
4178
|
return {
|
|
4179
4179
|
encode,
|
|
@@ -4355,11 +4355,11 @@ function abytes3(value, length, title = "") {
|
|
|
4355
4355
|
return value;
|
|
4356
4356
|
if (length !== undefined)
|
|
4357
4357
|
anumber3(length, "length");
|
|
4358
|
-
const
|
|
4358
|
+
const bytes = isBytes3(value);
|
|
4359
4359
|
const ofLen = length !== undefined ? ` of length ${length}` : "";
|
|
4360
|
-
const got =
|
|
4360
|
+
const got = bytes ? `length=${value.length}` : `type=${typeof value}`;
|
|
4361
4361
|
const message = atitle2(title) + "expected Uint8Array" + ofLen + ", got " + got;
|
|
4362
|
-
if (!
|
|
4362
|
+
if (!bytes)
|
|
4363
4363
|
throw new TypeError(message);
|
|
4364
4364
|
throw new RangeError(message);
|
|
4365
4365
|
}
|
|
@@ -4380,26 +4380,26 @@ function aoutput2(out, instance) {
|
|
|
4380
4380
|
throw new RangeError('"output" expected length >= ' + min);
|
|
4381
4381
|
}
|
|
4382
4382
|
}
|
|
4383
|
-
function u322(
|
|
4384
|
-
return new Uint32Array(
|
|
4383
|
+
function u322(arr) {
|
|
4384
|
+
return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
|
|
4385
4385
|
}
|
|
4386
4386
|
function clean2(...arrays) {
|
|
4387
4387
|
for (let i = 0;i < arrays.length; i++) {
|
|
4388
4388
|
arrays[i].fill(0);
|
|
4389
4389
|
}
|
|
4390
4390
|
}
|
|
4391
|
-
function createView2(
|
|
4392
|
-
return new DataView(
|
|
4391
|
+
function createView2(arr) {
|
|
4392
|
+
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
4393
4393
|
}
|
|
4394
4394
|
var isLE2 = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68)();
|
|
4395
4395
|
function byteSwap2(word) {
|
|
4396
4396
|
return word << 24 & 4278190080 | word << 8 & 16711680 | word >>> 8 & 65280 | word >>> 24 & 255;
|
|
4397
4397
|
}
|
|
4398
|
-
function byteSwap322(
|
|
4399
|
-
for (let i = 0;i <
|
|
4400
|
-
|
|
4398
|
+
function byteSwap322(arr) {
|
|
4399
|
+
for (let i = 0;i < arr.length; i++) {
|
|
4400
|
+
arr[i] = byteSwap2(arr[i]);
|
|
4401
4401
|
}
|
|
4402
|
-
return
|
|
4402
|
+
return arr;
|
|
4403
4403
|
}
|
|
4404
4404
|
var swap32IfBE2 = isLE2 ? (u) => u : byteSwap322;
|
|
4405
4405
|
function overlapBytes(a, b) {
|
|
@@ -4492,25 +4492,25 @@ function getOutput(expectedLength, out, onlyAligned = true) {
|
|
|
4492
4492
|
throw new Error("invalid output, must be aligned");
|
|
4493
4493
|
return out;
|
|
4494
4494
|
}
|
|
4495
|
-
function u64Lengths(dataLength, aadLength,
|
|
4495
|
+
function u64Lengths(dataLength, aadLength, isLE) {
|
|
4496
4496
|
anumber3(dataLength);
|
|
4497
4497
|
anumber3(aadLength);
|
|
4498
|
-
abool(
|
|
4498
|
+
abool(isLE);
|
|
4499
4499
|
const num = new Uint8Array(16);
|
|
4500
4500
|
const view = createView2(num);
|
|
4501
|
-
view.setBigUint64(0, BigInt(aadLength),
|
|
4502
|
-
view.setBigUint64(8, BigInt(dataLength),
|
|
4501
|
+
view.setBigUint64(0, BigInt(aadLength), isLE);
|
|
4502
|
+
view.setBigUint64(8, BigInt(dataLength), isLE);
|
|
4503
4503
|
return num;
|
|
4504
4504
|
}
|
|
4505
|
-
function isAligned32(
|
|
4506
|
-
return
|
|
4505
|
+
function isAligned32(bytes) {
|
|
4506
|
+
return bytes.byteOffset % 4 === 0;
|
|
4507
4507
|
}
|
|
4508
|
-
function copyBytes(
|
|
4509
|
-
return Uint8Array.from(abytes3(
|
|
4508
|
+
function copyBytes(bytes) {
|
|
4509
|
+
return Uint8Array.from(abytes3(bytes));
|
|
4510
4510
|
}
|
|
4511
4511
|
|
|
4512
4512
|
// ../../node_modules/.bun/@noble+ciphers@2.4.0/node_modules/@noble/ciphers/_arx.js
|
|
4513
|
-
var encodeStr = (
|
|
4513
|
+
var encodeStr = (str) => Uint8Array.from(str.split(""), (c) => c.charCodeAt(0));
|
|
4514
4514
|
var sigma16_32 = /* @__PURE__ */ (() => swap32IfBE2(u322(encodeStr("expand 16-byte k"))))();
|
|
4515
4515
|
var sigma32_32 = /* @__PURE__ */ (() => swap32IfBE2(u322(encodeStr("expand 32-byte k"))))();
|
|
4516
4516
|
function rotl2(a, b) {
|
|
@@ -5186,27 +5186,27 @@ function assertPasswordPolicy(password) {
|
|
|
5186
5186
|
throw new KernelError("invalid-input", "password must be at least 10 characters");
|
|
5187
5187
|
}
|
|
5188
5188
|
}
|
|
5189
|
-
async function passwordKek(password, salt,
|
|
5189
|
+
async function passwordKek(password, salt, pbkdf2) {
|
|
5190
5190
|
const normalized = decodeUtf8Secret(password).normalize("NFKC");
|
|
5191
5191
|
const normalizedBytes = utf8ToBytes(normalized);
|
|
5192
5192
|
try {
|
|
5193
|
-
return await
|
|
5193
|
+
return await pbkdf2("sha256", normalizedBytes, salt, PASSWORD_ITERATIONS2, 32);
|
|
5194
5194
|
} finally {
|
|
5195
5195
|
wipe(normalizedBytes);
|
|
5196
5196
|
}
|
|
5197
5197
|
}
|
|
5198
|
-
function passkeyKek(prf,
|
|
5198
|
+
function passkeyKek(prf, credentialId) {
|
|
5199
5199
|
try {
|
|
5200
5200
|
if (prf.length !== 32) {
|
|
5201
5201
|
throw new KernelError("invalid-input", "PRF output must be 32 bytes");
|
|
5202
5202
|
}
|
|
5203
|
-
return hkdf(sha256, prf,
|
|
5203
|
+
return hkdf(sha256, prf, credentialId, utf8ToBytes("qntx-wallet/kek/passkey/v1"), 32);
|
|
5204
5204
|
} finally {
|
|
5205
5205
|
wipe(prf);
|
|
5206
5206
|
}
|
|
5207
5207
|
}
|
|
5208
|
-
function wrapDek(kek, dek,
|
|
5209
|
-
return dek.use((
|
|
5208
|
+
function wrapDek(kek, dek, factor, random) {
|
|
5209
|
+
return dek.use((bytes) => seal(kek, bytes, factorContext(factor.kind, factor.id), factor.header, random));
|
|
5210
5210
|
}
|
|
5211
5211
|
function unwrapDek(kek, stored) {
|
|
5212
5212
|
return Secret.take(open(kek, stored.sealed, factorContext(stored.kind, stored.id), stored.header));
|
|
@@ -5219,15 +5219,15 @@ var PASSWORD_FACTOR_ITERATIONS = 600000;
|
|
|
5219
5219
|
function factorId(random) {
|
|
5220
5220
|
return bytesToHex(random(16));
|
|
5221
5221
|
}
|
|
5222
|
-
async function newFactorKek(platform,
|
|
5223
|
-
if (
|
|
5224
|
-
assertPasswordPolicy(
|
|
5222
|
+
async function newFactorKek(platform, factor) {
|
|
5223
|
+
if (factor.kind === "password") {
|
|
5224
|
+
assertPasswordPolicy(factor.password);
|
|
5225
5225
|
const salt = platform.random(16);
|
|
5226
|
-
const
|
|
5227
|
-
return { kind: "password", kek
|
|
5226
|
+
const kek = await passwordKek(factor.password, salt, platform.pbkdf2);
|
|
5227
|
+
return { kind: "password", kek, salt };
|
|
5228
5228
|
}
|
|
5229
|
-
const kek = passkeyKek(
|
|
5230
|
-
return { kind: "passkey", kek, credentialId:
|
|
5229
|
+
const kek = passkeyKek(factor.prf, factor.credentialId);
|
|
5230
|
+
return { kind: "passkey", kek, credentialId: factor.credentialId };
|
|
5231
5231
|
}
|
|
5232
5232
|
function factorHeader(material, createdAt) {
|
|
5233
5233
|
if (material.kind === "password") {
|
|
@@ -5242,8 +5242,8 @@ function factorHeader(material, createdAt) {
|
|
|
5242
5242
|
createdAt
|
|
5243
5243
|
});
|
|
5244
5244
|
}
|
|
5245
|
-
async function makeFactor(platform,
|
|
5246
|
-
const material = await newFactorKek(platform,
|
|
5245
|
+
async function makeFactor(platform, factor, dek) {
|
|
5246
|
+
const material = await newFactorKek(platform, factor);
|
|
5247
5247
|
const id = factorId(platform.random);
|
|
5248
5248
|
const header = factorHeader(material, platform.now());
|
|
5249
5249
|
try {
|
|
@@ -5256,14 +5256,14 @@ async function makeFactor(platform, factor2, dek) {
|
|
|
5256
5256
|
}
|
|
5257
5257
|
}
|
|
5258
5258
|
}
|
|
5259
|
-
async function kekFor(platform,
|
|
5260
|
-
if (
|
|
5259
|
+
async function kekFor(platform, factor, stored) {
|
|
5260
|
+
if (factor.kind === "password") {
|
|
5261
5261
|
const { salt } = parsePasswordFactorHeader(stored.header);
|
|
5262
|
-
return passwordKek(
|
|
5262
|
+
return passwordKek(factor.password, base64urlnopad.decode(salt), platform.pbkdf2);
|
|
5263
5263
|
}
|
|
5264
|
-
return passkeyKek(
|
|
5264
|
+
return passkeyKek(factor.prf, factor.credentialId);
|
|
5265
5265
|
}
|
|
5266
|
-
async function unlock(platform, image,
|
|
5266
|
+
async function unlock(platform, image, factor) {
|
|
5267
5267
|
const { meta } = image;
|
|
5268
5268
|
if (meta === undefined) {
|
|
5269
5269
|
throw new KernelError("invalid-input", "vault is not initialized");
|
|
@@ -5273,13 +5273,13 @@ async function unlock(platform, image, factor2) {
|
|
|
5273
5273
|
throw new KernelError("rate-limited", "too many wrong passwords", meta.retryAt);
|
|
5274
5274
|
}
|
|
5275
5275
|
let dek;
|
|
5276
|
-
if (
|
|
5276
|
+
if (factor.kind === "password") {
|
|
5277
5277
|
let lastError;
|
|
5278
5278
|
for (const stored of image.factors) {
|
|
5279
5279
|
if (stored.kind !== "password") {
|
|
5280
5280
|
continue;
|
|
5281
5281
|
}
|
|
5282
|
-
const kek = await kekFor(platform,
|
|
5282
|
+
const kek = await kekFor(platform, factor, stored);
|
|
5283
5283
|
try {
|
|
5284
5284
|
dek = unwrapDek(kek, stored);
|
|
5285
5285
|
break;
|
|
@@ -5309,13 +5309,13 @@ async function unlock(platform, image, factor2) {
|
|
|
5309
5309
|
]);
|
|
5310
5310
|
}
|
|
5311
5311
|
} else {
|
|
5312
|
-
const wanted = base64urlnopad.encode(
|
|
5312
|
+
const wanted = base64urlnopad.encode(factor.credentialId);
|
|
5313
5313
|
const stored = image.factors.find((f) => f.kind === "passkey" && credentialIdOf(f) === wanted);
|
|
5314
5314
|
if (stored === undefined) {
|
|
5315
|
-
wipe(
|
|
5315
|
+
wipe(factor.prf);
|
|
5316
5316
|
throw new KernelError("integrity", "no passkey factor matches the credential");
|
|
5317
5317
|
}
|
|
5318
|
-
const kek = await kekFor(platform,
|
|
5318
|
+
const kek = await kekFor(platform, factor, stored);
|
|
5319
5319
|
try {
|
|
5320
5320
|
dek = unwrapDek(kek, stored);
|
|
5321
5321
|
} finally {
|
|
@@ -5344,7 +5344,7 @@ function authenticateRecords(dek, records) {
|
|
|
5344
5344
|
const opened = [];
|
|
5345
5345
|
try {
|
|
5346
5346
|
for (const record of records) {
|
|
5347
|
-
const plaintext = dek.use((
|
|
5347
|
+
const plaintext = dek.use((bytes) => open(bytes, record.sealed, recordContext(record.kind, record.id), record.header));
|
|
5348
5348
|
opened.push({ kind: record.kind, id: record.id, plaintext });
|
|
5349
5349
|
}
|
|
5350
5350
|
return opened;
|
|
@@ -5355,16 +5355,16 @@ function authenticateRecords(dek, records) {
|
|
|
5355
5355
|
throw error;
|
|
5356
5356
|
}
|
|
5357
5357
|
}
|
|
5358
|
-
async function verifyFactor(platform, image,
|
|
5358
|
+
async function verifyFactor(platform, image, factor, dek) {
|
|
5359
5359
|
const candidates = image.factors.filter((stored) => {
|
|
5360
|
-
if (
|
|
5360
|
+
if (factor.kind !== stored.kind) {
|
|
5361
5361
|
return false;
|
|
5362
5362
|
}
|
|
5363
|
-
return
|
|
5363
|
+
return factor.kind === "password" || credentialIdOf(stored) === base64urlnopad.encode(factor.credentialId);
|
|
5364
5364
|
});
|
|
5365
5365
|
let sawPasswordFactor = false;
|
|
5366
5366
|
for (const stored of candidates) {
|
|
5367
|
-
const kek = await kekFor(platform,
|
|
5367
|
+
const kek = await kekFor(platform, factor, stored);
|
|
5368
5368
|
try {
|
|
5369
5369
|
const opened = unwrapDek(kek, stored);
|
|
5370
5370
|
try {
|
|
@@ -5385,17 +5385,17 @@ async function verifyFactor(platform, image, factor2, dek) {
|
|
|
5385
5385
|
wipe(kek);
|
|
5386
5386
|
}
|
|
5387
5387
|
}
|
|
5388
|
-
if (
|
|
5388
|
+
if (factor.kind === "password") {
|
|
5389
5389
|
throw new KernelError(sawPasswordFactor ? "wrong-password" : "invalid-input", "password did not verify");
|
|
5390
5390
|
}
|
|
5391
5391
|
throw new KernelError("integrity", "factor did not verify");
|
|
5392
5392
|
}
|
|
5393
5393
|
function sealRecord(platform, dek, kind, id, header, plaintext) {
|
|
5394
|
-
const sealed = dek.use((
|
|
5394
|
+
const sealed = dek.use((bytes) => seal(bytes, plaintext, recordContext(kind, id), header, platform.random));
|
|
5395
5395
|
return { kind, id, header, sealed };
|
|
5396
5396
|
}
|
|
5397
5397
|
function openRecord(dek, record) {
|
|
5398
|
-
return dek.use((
|
|
5398
|
+
return dek.use((bytes) => open(bytes, record.sealed, recordContext(record.kind, record.id), record.header));
|
|
5399
5399
|
}
|
|
5400
5400
|
function findRecord(image, kind, id) {
|
|
5401
5401
|
const record = image.records.find((r) => r.kind === kind && r.id === id);
|
|
@@ -5404,12 +5404,12 @@ function findRecord(image, kind, id) {
|
|
|
5404
5404
|
}
|
|
5405
5405
|
return record;
|
|
5406
5406
|
}
|
|
5407
|
-
function establishOps(
|
|
5407
|
+
function establishOps(factor, records) {
|
|
5408
5408
|
const meta = { format: 1, failedAttempts: 0, retryAt: 0 };
|
|
5409
5409
|
return [
|
|
5410
5410
|
{ op: "expect-uninitialized" },
|
|
5411
5411
|
{ op: "put-meta", meta },
|
|
5412
|
-
{ op: "put-factor", factor
|
|
5412
|
+
{ op: "put-factor", factor },
|
|
5413
5413
|
...records.map((record) => ({ op: "put-record", record }))
|
|
5414
5414
|
];
|
|
5415
5415
|
}
|
|
@@ -5589,11 +5589,11 @@ function hexToNumber(hex) {
|
|
|
5589
5589
|
throw new TypeError("hex string expected, got " + typeof hex);
|
|
5590
5590
|
return hex === "" ? _0n : BigInt("0x" + hex);
|
|
5591
5591
|
}
|
|
5592
|
-
function bytesToNumberBE(
|
|
5593
|
-
return hexToNumber(bytesToHex(
|
|
5592
|
+
function bytesToNumberBE(bytes) {
|
|
5593
|
+
return hexToNumber(bytesToHex(bytes));
|
|
5594
5594
|
}
|
|
5595
|
-
function bytesToNumberLE(
|
|
5596
|
-
return hexToNumber(bytesToHex(copyBytes2(abytes(
|
|
5595
|
+
function bytesToNumberLE(bytes) {
|
|
5596
|
+
return hexToNumber(bytesToHex(copyBytes2(abytes(bytes)).reverse()));
|
|
5597
5597
|
}
|
|
5598
5598
|
function numberToBytesBE(n, len) {
|
|
5599
5599
|
anumber(len);
|
|
@@ -5609,8 +5609,8 @@ function numberToBytesBE(n, len) {
|
|
|
5609
5609
|
function numberToBytesLE(n, len) {
|
|
5610
5610
|
return numberToBytesBE(n, len).reverse();
|
|
5611
5611
|
}
|
|
5612
|
-
function copyBytes2(
|
|
5613
|
-
return Uint8Array.from(abytes4(
|
|
5612
|
+
function copyBytes2(bytes) {
|
|
5613
|
+
return Uint8Array.from(abytes4(bytes));
|
|
5614
5614
|
}
|
|
5615
5615
|
function asciiToBytes(ascii) {
|
|
5616
5616
|
if (typeof ascii !== "string")
|
|
@@ -5749,14 +5749,14 @@ function pow(num, power, modulo) {
|
|
|
5749
5749
|
if (d < _0n2)
|
|
5750
5750
|
d += modulo;
|
|
5751
5751
|
if (power < POW_WINDOWED_MIN) {
|
|
5752
|
-
let
|
|
5752
|
+
let p = _1n2;
|
|
5753
5753
|
while (power > _0n2) {
|
|
5754
5754
|
if (power & _1n2)
|
|
5755
|
-
|
|
5755
|
+
p = p * d % modulo;
|
|
5756
5756
|
d = d * d % modulo;
|
|
5757
5757
|
power >>= _1n2;
|
|
5758
5758
|
}
|
|
5759
|
-
return
|
|
5759
|
+
return p;
|
|
5760
5760
|
}
|
|
5761
5761
|
const digits = [];
|
|
5762
5762
|
while (power > _0n2) {
|
|
@@ -6115,20 +6115,20 @@ class _Field {
|
|
|
6115
6115
|
toBytes(num) {
|
|
6116
6116
|
return this.isLE ? numberToBytesLE(num, this.BYTES) : numberToBytesBE(num, this.BYTES);
|
|
6117
6117
|
}
|
|
6118
|
-
fromBytes(
|
|
6119
|
-
abytes4(
|
|
6120
|
-
const { _lengths: allowedLengths, BYTES, isLE
|
|
6118
|
+
fromBytes(bytes, skipValidation = false) {
|
|
6119
|
+
abytes4(bytes);
|
|
6120
|
+
const { _lengths: allowedLengths, BYTES, isLE, ORDER, _mod: modFromBytes } = this;
|
|
6121
6121
|
if (allowedLengths) {
|
|
6122
|
-
if (
|
|
6123
|
-
throw new Error("Field.fromBytes: expected " + allowedLengths + " bytes, got " +
|
|
6122
|
+
if (bytes.length < 1 || !allowedLengths.includes(bytes.length) || bytes.length > BYTES) {
|
|
6123
|
+
throw new Error("Field.fromBytes: expected " + allowedLengths + " bytes, got " + bytes.length);
|
|
6124
6124
|
}
|
|
6125
6125
|
const padded = new Uint8Array(BYTES);
|
|
6126
|
-
padded.set(
|
|
6127
|
-
|
|
6126
|
+
padded.set(bytes, isLE ? 0 : padded.length - bytes.length);
|
|
6127
|
+
bytes = padded;
|
|
6128
6128
|
}
|
|
6129
|
-
if (
|
|
6130
|
-
throw new Error("Field.fromBytes: expected " + BYTES + " bytes, got " +
|
|
6131
|
-
let scalar =
|
|
6129
|
+
if (bytes.length !== BYTES)
|
|
6130
|
+
throw new Error("Field.fromBytes: expected " + BYTES + " bytes, got " + bytes.length);
|
|
6131
|
+
let scalar = isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);
|
|
6132
6132
|
if (modFromBytes)
|
|
6133
6133
|
scalar = mod(scalar, ORDER);
|
|
6134
6134
|
if (!skipValidation) {
|
|
@@ -6161,16 +6161,16 @@ function getMinHashLength(fieldOrder) {
|
|
|
6161
6161
|
const length = getFieldBytesLength(fieldOrder);
|
|
6162
6162
|
return length + Math.ceil(length / 2);
|
|
6163
6163
|
}
|
|
6164
|
-
function mapHashToField(key, fieldOrder,
|
|
6164
|
+
function mapHashToField(key, fieldOrder, isLE = false) {
|
|
6165
6165
|
abytes4(key);
|
|
6166
6166
|
const len = key.length;
|
|
6167
6167
|
const fieldLen = getFieldBytesLength(fieldOrder);
|
|
6168
6168
|
const minLen = Math.max(getMinHashLength(fieldOrder), 16);
|
|
6169
6169
|
if (len < minLen || len > 1024)
|
|
6170
6170
|
throw new Error("expected " + minLen + "-1024 bytes of input, got " + len);
|
|
6171
|
-
const num =
|
|
6171
|
+
const num = isLE ? bytesToNumberLE(key) : bytesToNumberBE(key);
|
|
6172
6172
|
const reduced = mod(num, fieldOrder - _1n2) + _1n2;
|
|
6173
|
-
return
|
|
6173
|
+
return isLE ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen);
|
|
6174
6174
|
}
|
|
6175
6175
|
|
|
6176
6176
|
// ../../node_modules/.bun/@noble+curves@2.4.0/node_modules/@noble/curves/abstract/curve.js
|
|
@@ -6205,22 +6205,22 @@ function validateW(W, bits, min = 1) {
|
|
|
6205
6205
|
throw new Error("invalid window size, expected [" + min + ".." + bits + "], got W=" + W);
|
|
6206
6206
|
}
|
|
6207
6207
|
function validateTableBytes(numPoints, fpBytes) {
|
|
6208
|
-
const
|
|
6209
|
-
if (
|
|
6210
|
-
throw new Error("invalid window size: table would need ~" + Math.ceil(
|
|
6208
|
+
const bytes = numPoints * (4 * fpBytes + 128);
|
|
6209
|
+
if (bytes > TABLE_BYTES_MAX)
|
|
6210
|
+
throw new Error("invalid window size: table would need ~" + Math.ceil(bytes / 2 ** 20) + " MiB, max " + TABLE_BYTES_MAX / 2 ** 20 + " MiB");
|
|
6211
6211
|
}
|
|
6212
|
-
function probeRandomBytes(
|
|
6213
|
-
if (
|
|
6212
|
+
function probeRandomBytes(randomBytes, length) {
|
|
6213
|
+
if (randomBytes === undefined)
|
|
6214
6214
|
return;
|
|
6215
|
-
afunction(
|
|
6215
|
+
afunction(randomBytes, "randomBytes");
|
|
6216
6216
|
try {
|
|
6217
|
-
const probe =
|
|
6217
|
+
const probe = randomBytes(length);
|
|
6218
6218
|
if (!isBytes4(probe) || probe.length !== length)
|
|
6219
6219
|
return;
|
|
6220
6220
|
} catch {
|
|
6221
6221
|
return;
|
|
6222
6222
|
}
|
|
6223
|
-
return
|
|
6223
|
+
return randomBytes;
|
|
6224
6224
|
}
|
|
6225
6225
|
function validateMSMPoints(points, c) {
|
|
6226
6226
|
aarray(points, "points");
|
|
@@ -6313,9 +6313,9 @@ class ScalarMultiplier {
|
|
|
6313
6313
|
wnafPrecomputes = new WeakMap;
|
|
6314
6314
|
baseCanBeBlinded;
|
|
6315
6315
|
bits;
|
|
6316
|
-
constructor(Point,
|
|
6316
|
+
constructor(Point, randomBytes) {
|
|
6317
6317
|
validatePointCons(Point);
|
|
6318
|
-
this.randomBytes = probeRandomBytes(
|
|
6318
|
+
this.randomBytes = probeRandomBytes(randomBytes, BLIND_BYTES);
|
|
6319
6319
|
this.Point = Point;
|
|
6320
6320
|
this.BASE = Point.BASE;
|
|
6321
6321
|
this.ZERO = Point.ZERO;
|
|
@@ -6472,14 +6472,14 @@ function mulAddUnsafe(c, points, scalars, allowOversized = false) {
|
|
|
6472
6472
|
const digits = scalars.map((n) => wnafDigits(n, 4));
|
|
6473
6473
|
return wnafWalk(c.ZERO, tables, digits);
|
|
6474
6474
|
}
|
|
6475
|
-
function createField(order, field,
|
|
6475
|
+
function createField(order, field, isLE) {
|
|
6476
6476
|
if (field) {
|
|
6477
6477
|
if (field.ORDER !== order)
|
|
6478
6478
|
throw new Error("Field.ORDER must match order: Fp == p, Fn == n");
|
|
6479
6479
|
validateField(field);
|
|
6480
6480
|
return field;
|
|
6481
6481
|
} else {
|
|
6482
|
-
return Field(order, { isLE
|
|
6482
|
+
return Field(order, { isLE });
|
|
6483
6483
|
}
|
|
6484
6484
|
}
|
|
6485
6485
|
function createCurveFields(type, CURVE, curveOpts = {}, FpFnLE) {
|
|
@@ -6601,14 +6601,14 @@ var _DER = {
|
|
|
6601
6601
|
return bytesToNumberBE(data);
|
|
6602
6602
|
}
|
|
6603
6603
|
},
|
|
6604
|
-
toSig(
|
|
6605
|
-
const { Err: E, _int:
|
|
6604
|
+
toSig(bytes, maxScalarBytes) {
|
|
6605
|
+
const { Err: E, _int: int, _tlv: tlv } = _DER;
|
|
6606
6606
|
if (maxScalarBytes !== undefined) {
|
|
6607
6607
|
asafenumber(maxScalarBytes, "maxScalarBytes");
|
|
6608
6608
|
if (maxScalarBytes < 1)
|
|
6609
6609
|
throw new E("invalid signature: maxScalarBytes must be positive");
|
|
6610
6610
|
}
|
|
6611
|
-
const data = abytes4(
|
|
6611
|
+
const data = abytes4(bytes, undefined, "signature");
|
|
6612
6612
|
const { v: seqBytes, l: seqLeftBytes } = tlv.decode(48, data);
|
|
6613
6613
|
if (seqLeftBytes.length)
|
|
6614
6614
|
throw new E("invalid signature: left bytes after parsing");
|
|
@@ -6618,13 +6618,13 @@ var _DER = {
|
|
|
6618
6618
|
throw new E("invalid signature: left bytes after parsing");
|
|
6619
6619
|
if (maxScalarBytes !== undefined && (rBytes.length > maxScalarBytes || sBytes.length > maxScalarBytes))
|
|
6620
6620
|
throw new E("invalid signature: integer too large");
|
|
6621
|
-
return { r:
|
|
6621
|
+
return { r: int.decode(rBytes), s: int.decode(sBytes) };
|
|
6622
6622
|
},
|
|
6623
6623
|
hexFromSig(sig) {
|
|
6624
|
-
const { _tlv: tlv, _int:
|
|
6624
|
+
const { _tlv: tlv, _int: int } = _DER;
|
|
6625
6625
|
validateObject(sig, { r: "bigint", s: "bigint" }, {}, "sig");
|
|
6626
|
-
const rs = tlv.encode(2,
|
|
6627
|
-
const ss = tlv.encode(2,
|
|
6626
|
+
const rs = tlv.encode(2, int.encode(sig.r));
|
|
6627
|
+
const ss = tlv.encode(2, int.encode(sig.s));
|
|
6628
6628
|
const seq = rs + ss;
|
|
6629
6629
|
return tlv.encode(48, seq);
|
|
6630
6630
|
}
|
|
@@ -6695,7 +6695,7 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
6695
6695
|
randomBytes: "function"
|
|
6696
6696
|
});
|
|
6697
6697
|
const { endo: endoOpts, allowInfinityPoint, clearCofactor, isTorsionFree, fromBytes, toBytes } = extraOpts;
|
|
6698
|
-
const
|
|
6698
|
+
const randomBytes = extraOpts.randomBytes === undefined ? randomBytes3 : extraOpts.randomBytes;
|
|
6699
6699
|
if (endoOpts) {
|
|
6700
6700
|
if (!Fp.is0(CURVE.a) || typeof endoOpts.beta !== "bigint" || !Array.isArray(endoOpts.basises)) {
|
|
6701
6701
|
throw new Error('invalid endo: expected "beta": bigint and "basises": array');
|
|
@@ -6727,12 +6727,12 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
6727
6727
|
return concatBytes2(Uint8Array.of(4), bx, Fp.toBytes(y));
|
|
6728
6728
|
}
|
|
6729
6729
|
}
|
|
6730
|
-
function pointFromBytes(
|
|
6731
|
-
abytes4(
|
|
6730
|
+
function pointFromBytes(bytes) {
|
|
6731
|
+
abytes4(bytes, undefined, "Point");
|
|
6732
6732
|
const { publicKey: comp, publicKeyUncompressed: uncomp } = lengths;
|
|
6733
|
-
const length =
|
|
6734
|
-
const head =
|
|
6735
|
-
const tail =
|
|
6733
|
+
const length = bytes.length;
|
|
6734
|
+
const head = bytes[0];
|
|
6735
|
+
const tail = bytes.subarray(1);
|
|
6736
6736
|
if (allowInfinityPoint && length === 1 && head === 0)
|
|
6737
6737
|
return { x: Fp.ZERO, y: Fp.ZERO };
|
|
6738
6738
|
if (length === comp && (head === 2 || head === 3)) {
|
|
@@ -6840,8 +6840,8 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
6840
6840
|
return Point.ZERO;
|
|
6841
6841
|
return new Point(x, y, Fp.ONE);
|
|
6842
6842
|
}
|
|
6843
|
-
static fromBytes(
|
|
6844
|
-
const P = Point.fromAffine(decodePoint(abytes4(
|
|
6843
|
+
static fromBytes(bytes) {
|
|
6844
|
+
const P = Point.fromAffine(decodePoint(abytes4(bytes, undefined, "point")));
|
|
6845
6845
|
P.assertValidity();
|
|
6846
6846
|
return P;
|
|
6847
6847
|
}
|
|
@@ -6988,8 +6988,8 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
6988
6988
|
multiply(scalar) {
|
|
6989
6989
|
if (!Fn.isValidNot0(scalar))
|
|
6990
6990
|
throw new RangeError("invalid scalar: out of range");
|
|
6991
|
-
const { p, f } = wnaf.mulSecret(this, scalar, cofactor,
|
|
6992
|
-
return
|
|
6991
|
+
const { p, f } = wnaf.mulSecret(this, scalar, cofactor, normalize);
|
|
6992
|
+
return normalize([p, f])[0];
|
|
6993
6993
|
}
|
|
6994
6994
|
multiplyUnsafe(scalar) {
|
|
6995
6995
|
const p = this;
|
|
@@ -7001,7 +7001,7 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
7001
7001
|
if (sc === _1n4)
|
|
7002
7002
|
return p;
|
|
7003
7003
|
if (wnaf.hasWindowSize(this))
|
|
7004
|
-
return wnaf.mulUnsafe(p, sc,
|
|
7004
|
+
return wnaf.mulUnsafe(p, sc, normalize);
|
|
7005
7005
|
const points = [];
|
|
7006
7006
|
const scalars = [];
|
|
7007
7007
|
pushWnafPair(points, scalars, p, sc);
|
|
@@ -7066,8 +7066,8 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
7066
7066
|
return `<Point ${this.is0() ? "ZERO" : this.toHex()}>`;
|
|
7067
7067
|
}
|
|
7068
7068
|
}
|
|
7069
|
-
const
|
|
7070
|
-
const wnaf = new ScalarMultiplier(Point,
|
|
7069
|
+
const normalize = (points) => normalizeZ(Point, points);
|
|
7070
|
+
const wnaf = new ScalarMultiplier(Point, randomBytes);
|
|
7071
7071
|
if (wnaf.bits >= 6)
|
|
7072
7072
|
Point.BASE.precompute(6);
|
|
7073
7073
|
Object.freeze(Point.prototype);
|
|
@@ -7101,15 +7101,15 @@ function ecdh(Point, ecdhOpts = {}) {
|
|
|
7101
7101
|
return false;
|
|
7102
7102
|
}
|
|
7103
7103
|
}
|
|
7104
|
-
function isValidPublicKey(
|
|
7104
|
+
function isValidPublicKey(publicKey, isCompressed) {
|
|
7105
7105
|
const { publicKey: comp, publicKeyUncompressed } = lengths;
|
|
7106
7106
|
try {
|
|
7107
|
-
const l =
|
|
7107
|
+
const l = publicKey.length;
|
|
7108
7108
|
if (isCompressed === true && l !== comp)
|
|
7109
7109
|
return false;
|
|
7110
7110
|
if (isCompressed === false && l !== publicKeyUncompressed)
|
|
7111
7111
|
return false;
|
|
7112
|
-
return !Point.fromBytes(
|
|
7112
|
+
return !Point.fromBytes(publicKey).is0();
|
|
7113
7113
|
} catch (error) {
|
|
7114
7114
|
return false;
|
|
7115
7115
|
}
|
|
@@ -7122,12 +7122,12 @@ function ecdh(Point, ecdhOpts = {}) {
|
|
|
7122
7122
|
return Point.BASE.multiply(Fn.fromBytes(secretKey)).toBytes(isCompressed);
|
|
7123
7123
|
}
|
|
7124
7124
|
function isProbPub(item) {
|
|
7125
|
-
const { secretKey, publicKey
|
|
7125
|
+
const { secretKey, publicKey, publicKeyUncompressed } = lengths;
|
|
7126
7126
|
const allowedLengths = Fn._lengths;
|
|
7127
7127
|
if (!isBytes4(item))
|
|
7128
7128
|
return;
|
|
7129
7129
|
const l = abytes4(item, undefined, "key").length;
|
|
7130
|
-
const isPub = l ===
|
|
7130
|
+
const isPub = l === publicKey || l === publicKeyUncompressed;
|
|
7131
7131
|
const isSec = l === secretKey || !!allowedLengths?.includes(l);
|
|
7132
7132
|
if (isPub && isSec)
|
|
7133
7133
|
return;
|
|
@@ -7166,12 +7166,12 @@ function ecdsa(Point, hash, ecdsaOpts = {}) {
|
|
|
7166
7166
|
bits2int_modN: "function"
|
|
7167
7167
|
});
|
|
7168
7168
|
const opts = Object.assign({}, ecdsaOpts);
|
|
7169
|
-
const
|
|
7169
|
+
const randomBytes = opts.randomBytes === undefined ? randomBytes3 : opts.randomBytes;
|
|
7170
7170
|
const hmac2 = opts.hmac === undefined ? (key, msg) => hmac(hash_, key, msg) : opts.hmac;
|
|
7171
7171
|
const { Fp, Fn } = Point;
|
|
7172
7172
|
const { ORDER: CURVE_ORDER, BITS: fnBits } = Fn;
|
|
7173
7173
|
const blindLength = getMinHashLength(CURVE_ORDER);
|
|
7174
|
-
const csprng = probeRandomBytes(
|
|
7174
|
+
const csprng = probeRandomBytes(randomBytes, blindLength);
|
|
7175
7175
|
const { keygen, getPublicKey, getSharedSecret, utils, lengths } = ecdh(Point, opts);
|
|
7176
7176
|
const defaultSigOpts = {
|
|
7177
7177
|
prehash: true,
|
|
@@ -7201,11 +7201,11 @@ function ecdsa(Point, hash, ecdsaOpts = {}) {
|
|
|
7201
7201
|
if (hasLargeRecoveryLifts)
|
|
7202
7202
|
throw new Error('"recovered" sig type is not supported for cofactor >2 curves');
|
|
7203
7203
|
}
|
|
7204
|
-
function validateSigLength(
|
|
7204
|
+
function validateSigLength(bytes, format) {
|
|
7205
7205
|
validateSigFormat(format);
|
|
7206
7206
|
const size = lengths.signature;
|
|
7207
7207
|
const sizer = format === "compact" ? size : format === "recovered" ? size + 1 : undefined;
|
|
7208
|
-
return abytes4(
|
|
7208
|
+
return abytes4(bytes, sizer);
|
|
7209
7209
|
}
|
|
7210
7210
|
|
|
7211
7211
|
class Signature {
|
|
@@ -7223,23 +7223,23 @@ function ecdsa(Point, hash, ecdsaOpts = {}) {
|
|
|
7223
7223
|
}
|
|
7224
7224
|
Object.freeze(this);
|
|
7225
7225
|
}
|
|
7226
|
-
static fromBytes(
|
|
7227
|
-
validateSigLength(
|
|
7226
|
+
static fromBytes(bytes, format = defaultSigOpts.format) {
|
|
7227
|
+
validateSigLength(bytes, format);
|
|
7228
7228
|
let recid;
|
|
7229
7229
|
if (format === "der") {
|
|
7230
|
-
if (
|
|
7230
|
+
if (bytes.length > 2 * Fn.BYTES + 16)
|
|
7231
7231
|
throw new DER.Err("invalid signature: DER signature too long");
|
|
7232
|
-
const { r
|
|
7233
|
-
return new Signature(
|
|
7232
|
+
const { r, s } = DER.toSig(abytes4(bytes), Fn.BYTES + 1);
|
|
7233
|
+
return new Signature(r, s);
|
|
7234
7234
|
}
|
|
7235
7235
|
if (format === "recovered") {
|
|
7236
|
-
recid =
|
|
7236
|
+
recid = bytes[0];
|
|
7237
7237
|
format = "compact";
|
|
7238
|
-
|
|
7238
|
+
bytes = bytes.subarray(1);
|
|
7239
7239
|
}
|
|
7240
7240
|
const L = lengths.signature / 2;
|
|
7241
|
-
const r =
|
|
7242
|
-
const s =
|
|
7241
|
+
const r = bytes.subarray(0, L);
|
|
7242
|
+
const s = bytes.subarray(L, L * 2);
|
|
7243
7243
|
return new Signature(Fn.fromBytes(r), Fn.fromBytes(s), recid);
|
|
7244
7244
|
}
|
|
7245
7245
|
static fromHex(hex, format) {
|
|
@@ -7294,15 +7294,15 @@ function ecdsa(Point, hash, ecdsaOpts = {}) {
|
|
|
7294
7294
|
}
|
|
7295
7295
|
Object.freeze(Signature.prototype);
|
|
7296
7296
|
Object.freeze(Signature);
|
|
7297
|
-
const bits2int = opts.bits2int === undefined ? function bits2int_def(
|
|
7298
|
-
if (
|
|
7297
|
+
const bits2int = opts.bits2int === undefined ? function bits2int_def(bytes) {
|
|
7298
|
+
if (bytes.length > 8192)
|
|
7299
7299
|
throw new Error("input is too large");
|
|
7300
|
-
const num = bytesToNumberBE(
|
|
7301
|
-
const delta =
|
|
7300
|
+
const num = bytesToNumberBE(bytes);
|
|
7301
|
+
const delta = bytes.length * 8 - fnBits;
|
|
7302
7302
|
return delta > 0 ? num >> BigInt(delta) : num;
|
|
7303
7303
|
} : opts.bits2int;
|
|
7304
|
-
const bits2int_modN = opts.bits2int_modN === undefined ? function bits2int_modN_def(
|
|
7305
|
-
return Fn.create(bits2int(
|
|
7304
|
+
const bits2int_modN = opts.bits2int_modN === undefined ? function bits2int_modN_def(bytes) {
|
|
7305
|
+
return Fn.create(bits2int(bytes));
|
|
7306
7306
|
} : opts.bits2int_modN;
|
|
7307
7307
|
const ORDER_MASK = bitMask(fnBits);
|
|
7308
7308
|
function int2octets(num) {
|
|
@@ -7313,8 +7313,8 @@ function ecdsa(Point, hash, ecdsaOpts = {}) {
|
|
|
7313
7313
|
abytes4(message, undefined, "message");
|
|
7314
7314
|
return prehash ? abytes4(hash_(message), undefined, "prehashed message") : message;
|
|
7315
7315
|
}
|
|
7316
|
-
function prepSig(message, secretKey,
|
|
7317
|
-
const { lowS, prehash, extraEntropy } = validateSigOpts(
|
|
7316
|
+
function prepSig(message, secretKey, opts) {
|
|
7317
|
+
const { lowS, prehash, extraEntropy } = validateSigOpts(opts, defaultSigOpts);
|
|
7318
7318
|
message = validateMsgAndHash(message, prehash);
|
|
7319
7319
|
const h1int = bits2int_modN(message);
|
|
7320
7320
|
const d = Fn.fromBytes(secretKey);
|
|
@@ -7322,7 +7322,7 @@ function ecdsa(Point, hash, ecdsaOpts = {}) {
|
|
|
7322
7322
|
throw new Error("invalid private key");
|
|
7323
7323
|
const seedArgs = [int2octets(d), int2octets(h1int)];
|
|
7324
7324
|
if (extraEntropy != null && extraEntropy !== false) {
|
|
7325
|
-
const e = extraEntropy === true ?
|
|
7325
|
+
const e = extraEntropy === true ? randomBytes(lengths.secretKey) : extraEntropy;
|
|
7326
7326
|
seedArgs.push(abytes4(e, undefined, "extraEntropy"));
|
|
7327
7327
|
}
|
|
7328
7328
|
const seed = concatBytes2(...seedArgs);
|
|
@@ -7358,15 +7358,15 @@ function ecdsa(Point, hash, ecdsaOpts = {}) {
|
|
|
7358
7358
|
}
|
|
7359
7359
|
return { seed, k2sig };
|
|
7360
7360
|
}
|
|
7361
|
-
function sign(message, secretKey,
|
|
7362
|
-
const { seed, k2sig } = prepSig(message, secretKey,
|
|
7361
|
+
function sign(message, secretKey, opts = {}) {
|
|
7362
|
+
const { seed, k2sig } = prepSig(message, secretKey, opts);
|
|
7363
7363
|
const drbg = createHmacDrbg(hash_.outputLen, Fn.BYTES, hmac2);
|
|
7364
7364
|
const sig = drbg(seed, k2sig);
|
|
7365
|
-
return sig.toBytes(
|
|
7365
|
+
return sig.toBytes(opts.format);
|
|
7366
7366
|
}
|
|
7367
|
-
function verify(signature, message,
|
|
7368
|
-
const { lowS, prehash, format } = validateSigOpts(
|
|
7369
|
-
|
|
7367
|
+
function verify(signature, message, publicKey, opts = {}) {
|
|
7368
|
+
const { lowS, prehash, format } = validateSigOpts(opts, defaultSigOpts);
|
|
7369
|
+
publicKey = abytes4(publicKey, undefined, "publicKey");
|
|
7370
7370
|
message = validateMsgAndHash(message, prehash);
|
|
7371
7371
|
if (!isBytes4(signature)) {
|
|
7372
7372
|
const end = signature instanceof Signature ? ", use sig.toBytes()" : "";
|
|
@@ -7375,7 +7375,7 @@ function ecdsa(Point, hash, ecdsaOpts = {}) {
|
|
|
7375
7375
|
validateSigLength(signature, format);
|
|
7376
7376
|
try {
|
|
7377
7377
|
const sig = Signature.fromBytes(signature, format);
|
|
7378
|
-
const P = Point.fromBytes(
|
|
7378
|
+
const P = Point.fromBytes(publicKey);
|
|
7379
7379
|
if (P.is0())
|
|
7380
7380
|
return false;
|
|
7381
7381
|
if (lowS && sig.hasHighS())
|
|
@@ -7399,8 +7399,8 @@ function ecdsa(Point, hash, ecdsaOpts = {}) {
|
|
|
7399
7399
|
return false;
|
|
7400
7400
|
}
|
|
7401
7401
|
}
|
|
7402
|
-
function recoverPublicKey(signature, message,
|
|
7403
|
-
const { prehash } = validateSigOpts(
|
|
7402
|
+
function recoverPublicKey(signature, message, opts = {}) {
|
|
7403
|
+
const { prehash } = validateSigOpts(opts, defaultSigOpts);
|
|
7404
7404
|
message = validateMsgAndHash(message, prehash);
|
|
7405
7405
|
return Signature.fromBytes(signature, "recovered").recoverPublicKey(message).toBytes();
|
|
7406
7406
|
}
|
|
@@ -7441,19 +7441,19 @@ var _0n6 = /* @__PURE__ */ BigInt(0);
|
|
|
7441
7441
|
var _2n3 = /* @__PURE__ */ BigInt(2);
|
|
7442
7442
|
function sqrtMod(y) {
|
|
7443
7443
|
const P = secp256k1_CURVE.p;
|
|
7444
|
-
const
|
|
7444
|
+
const _3n = BigInt(3), _6n = BigInt(6), _11n = BigInt(11), _22n = BigInt(22);
|
|
7445
7445
|
const _23n = BigInt(23), _44n = BigInt(44), _88n = BigInt(88);
|
|
7446
7446
|
const b2 = y * y * y % P;
|
|
7447
7447
|
const b3 = b2 * b2 * y % P;
|
|
7448
|
-
const b6 = pow2(b3,
|
|
7449
|
-
const b9 = pow2(b6,
|
|
7448
|
+
const b6 = pow2(b3, _3n, P) * b3 % P;
|
|
7449
|
+
const b9 = pow2(b6, _3n, P) * b3 % P;
|
|
7450
7450
|
const b11 = pow2(b9, _2n3, P) * b2 % P;
|
|
7451
7451
|
const b22 = pow2(b11, _11n, P) * b11 % P;
|
|
7452
7452
|
const b44 = pow2(b22, _22n, P) * b22 % P;
|
|
7453
7453
|
const b88 = pow2(b44, _44n, P) * b44 % P;
|
|
7454
7454
|
const b176 = pow2(b88, _88n, P) * b88 % P;
|
|
7455
7455
|
const b220 = pow2(b176, _44n, P) * b44 % P;
|
|
7456
|
-
const b223 = pow2(b220,
|
|
7456
|
+
const b223 = pow2(b220, _3n, P) * b3 % P;
|
|
7457
7457
|
const t1 = pow2(b223, _23n, P) * b22 % P;
|
|
7458
7458
|
const t2 = pow2(t1, _6n, P) * b2 % P;
|
|
7459
7459
|
const root = pow2(t2, _2n3, P);
|
|
@@ -7530,11 +7530,11 @@ function schnorrSign(message, secretKey, auxRand = randomBytes(32)) {
|
|
|
7530
7530
|
throw new Error("sign: Invalid signature produced");
|
|
7531
7531
|
return sig;
|
|
7532
7532
|
}
|
|
7533
|
-
function schnorrVerify(signature, message,
|
|
7533
|
+
function schnorrVerify(signature, message, publicKey) {
|
|
7534
7534
|
const { Fp, Fn, BASE } = Pointk1;
|
|
7535
7535
|
const sig = abytes4(signature, 64, "signature");
|
|
7536
7536
|
const m = abytes4(message, undefined, "message");
|
|
7537
|
-
const pub = abytes4(
|
|
7537
|
+
const pub = abytes4(publicKey, 32, "publicKey");
|
|
7538
7538
|
try {
|
|
7539
7539
|
const P = lift_x(num(pub));
|
|
7540
7540
|
const rBytes = sig.subarray(0, 32);
|
|
@@ -7790,7 +7790,7 @@ class HDKey {
|
|
|
7790
7790
|
}
|
|
7791
7791
|
const keyView = createView(keyBuffer);
|
|
7792
7792
|
const version = keyView.getUint32(0, false);
|
|
7793
|
-
const
|
|
7793
|
+
const opt = {
|
|
7794
7794
|
versions,
|
|
7795
7795
|
depth: keyBuffer[4],
|
|
7796
7796
|
parentFingerprint: keyView.getUint32(5, false),
|
|
@@ -7803,9 +7803,9 @@ class HDKey {
|
|
|
7803
7803
|
throw new Error("Version mismatch");
|
|
7804
7804
|
}
|
|
7805
7805
|
if (isPriv) {
|
|
7806
|
-
return new HDKey({ ...
|
|
7806
|
+
return new HDKey({ ...opt, privateKey: key.slice(1) });
|
|
7807
7807
|
} else {
|
|
7808
|
-
return new HDKey({ ...
|
|
7808
|
+
return new HDKey({ ...opt, publicKey: key });
|
|
7809
7809
|
}
|
|
7810
7810
|
}
|
|
7811
7811
|
static fromJSON(json) {
|
|
@@ -7819,13 +7819,13 @@ class HDKey {
|
|
|
7819
7819
|
_privateKey;
|
|
7820
7820
|
_publicKey;
|
|
7821
7821
|
_pubHash;
|
|
7822
|
-
constructor(
|
|
7823
|
-
if (!
|
|
7822
|
+
constructor(opt) {
|
|
7823
|
+
if (!opt || typeof opt !== "object") {
|
|
7824
7824
|
throw new Error("HDKey.constructor must not be called directly");
|
|
7825
7825
|
}
|
|
7826
|
-
const depth =
|
|
7827
|
-
const index =
|
|
7828
|
-
const parentFingerprint =
|
|
7826
|
+
const depth = opt.depth ?? 0;
|
|
7827
|
+
const index = opt.index ?? 0;
|
|
7828
|
+
const parentFingerprint = opt.parentFingerprint ?? 0;
|
|
7829
7829
|
if (!Number.isSafeInteger(depth) || depth < 0 || depth > MAX_DEPTH) {
|
|
7830
7830
|
throw new RangeError("HDKey: depth must be an integer in range 0..255");
|
|
7831
7831
|
}
|
|
@@ -7834,23 +7834,23 @@ class HDKey {
|
|
|
7834
7834
|
if (depth === 0 && (index !== 0 || parentFingerprint !== 0)) {
|
|
7835
7835
|
throw new Error("HDKey: zero depth with non-zero index/parent fingerprint");
|
|
7836
7836
|
}
|
|
7837
|
-
this.versions =
|
|
7837
|
+
this.versions = opt.versions ? validateVersions(opt.versions) : BITCOIN_VERSIONS;
|
|
7838
7838
|
this.depth = depth;
|
|
7839
|
-
if (
|
|
7840
|
-
abytes(
|
|
7841
|
-
this._chainCode =
|
|
7839
|
+
if (opt.chainCode)
|
|
7840
|
+
abytes(opt.chainCode, 32);
|
|
7841
|
+
this._chainCode = opt.chainCode ? Uint8Array.from(opt.chainCode) : null;
|
|
7842
7842
|
this.index = index;
|
|
7843
7843
|
this.parentFingerprint = parentFingerprint;
|
|
7844
|
-
if (
|
|
7844
|
+
if (opt.publicKey && opt.privateKey) {
|
|
7845
7845
|
throw new Error("HDKey: publicKey and privateKey at same time.");
|
|
7846
7846
|
}
|
|
7847
|
-
if (
|
|
7848
|
-
if (!secp256k1.utils.isValidSecretKey(
|
|
7847
|
+
if (opt.privateKey) {
|
|
7848
|
+
if (!secp256k1.utils.isValidSecretKey(opt.privateKey))
|
|
7849
7849
|
throw new Error("Invalid private key");
|
|
7850
|
-
this._privateKey = Uint8Array.from(
|
|
7850
|
+
this._privateKey = Uint8Array.from(opt.privateKey);
|
|
7851
7851
|
this._publicKey = secp256k1.getPublicKey(this._privateKey, true);
|
|
7852
|
-
} else if (
|
|
7853
|
-
this._publicKey = Point.fromBytes(
|
|
7852
|
+
} else if (opt.publicKey) {
|
|
7853
|
+
this._publicKey = Point.fromBytes(opt.publicKey).toBytes(true);
|
|
7854
7854
|
} else {
|
|
7855
7855
|
throw new Error("HDKey: no public or private key provided");
|
|
7856
7856
|
}
|
|
@@ -7905,14 +7905,14 @@ class HDKey {
|
|
|
7905
7905
|
abytes(out, 64);
|
|
7906
7906
|
const childTweak = out.slice(0, 32);
|
|
7907
7907
|
const chainCode = out.slice(32);
|
|
7908
|
-
const
|
|
7908
|
+
const opt = {
|
|
7909
7909
|
versions: this.versions,
|
|
7910
7910
|
chainCode,
|
|
7911
7911
|
depth: this.depth + 1,
|
|
7912
7912
|
parentFingerprint: this.fingerprint,
|
|
7913
7913
|
index
|
|
7914
7914
|
};
|
|
7915
|
-
if (
|
|
7915
|
+
if (opt.depth > MAX_DEPTH) {
|
|
7916
7916
|
throw new Error("HDKey: depth exceeds the serializable value 255");
|
|
7917
7917
|
}
|
|
7918
7918
|
const retry = () => {
|
|
@@ -7929,15 +7929,15 @@ class HDKey {
|
|
|
7929
7929
|
const added = Fn.create(Fn.fromBytes(this._privateKey) + ctweak);
|
|
7930
7930
|
if (!Fn.isValidNot0(added))
|
|
7931
7931
|
return retry();
|
|
7932
|
-
|
|
7932
|
+
opt.privateKey = Fn.toBytes(added);
|
|
7933
7933
|
} else {
|
|
7934
7934
|
const point = Point.fromBytes(this._publicKey);
|
|
7935
7935
|
const added = ctweak === 0n ? point : point.add(Point.BASE.multiply(ctweak));
|
|
7936
7936
|
if (added.equals(Point.ZERO))
|
|
7937
7937
|
return retry();
|
|
7938
|
-
|
|
7938
|
+
opt.publicKey = added.toBytes(true);
|
|
7939
7939
|
}
|
|
7940
|
-
return new HDKey(
|
|
7940
|
+
return new HDKey(opt);
|
|
7941
7941
|
}
|
|
7942
7942
|
sign(hash) {
|
|
7943
7943
|
if (!this._privateKey) {
|
|
@@ -7986,11 +7986,11 @@ function masterKey(seed) {
|
|
|
7986
7986
|
|
|
7987
7987
|
// ../wallet-kernel/src/derive/wallet-id.ts
|
|
7988
7988
|
function walletIdOf(master) {
|
|
7989
|
-
const { publicKey
|
|
7990
|
-
if (
|
|
7989
|
+
const { publicKey } = master;
|
|
7990
|
+
if (publicKey === null || publicKey.length !== 33) {
|
|
7991
7991
|
throw new KernelError("integrity", "master key has no compressed public key");
|
|
7992
7992
|
}
|
|
7993
|
-
return bytesToHex(sha256(concatBytes(utf8ToBytes("qntx-wallet/wallet-id/v1"),
|
|
7993
|
+
return bytesToHex(sha256(concatBytes(utf8ToBytes("qntx-wallet/wallet-id/v1"), publicKey)).slice(0, 8));
|
|
7994
7994
|
}
|
|
7995
7995
|
|
|
7996
7996
|
// ../wallet-kernel/src/seed/entropy.ts
|
|
@@ -8016,17 +8016,17 @@ function entropyFromPrf(prf) {
|
|
|
8016
8016
|
}
|
|
8017
8017
|
|
|
8018
8018
|
// ../wallet-kernel/src/seed/seed.ts
|
|
8019
|
-
async function seedFromMnemonic(mnemonic, passphrase,
|
|
8019
|
+
async function seedFromMnemonic(mnemonic, passphrase, pbkdf2) {
|
|
8020
8020
|
const password = utf8ToBytes(mnemonic.normalize("NFKD"));
|
|
8021
8021
|
const salt = utf8ToBytes(`mnemonic${passphrase}`.normalize("NFKD"));
|
|
8022
8022
|
try {
|
|
8023
|
-
return await
|
|
8023
|
+
return await pbkdf2("sha512", password, salt, 2048, 64);
|
|
8024
8024
|
} finally {
|
|
8025
8025
|
wipe(password, salt);
|
|
8026
8026
|
}
|
|
8027
8027
|
}
|
|
8028
|
-
async function seedFromEntropy(entropy,
|
|
8029
|
-
return seedFromMnemonic(mnemonicFromEntropy(entropy), "",
|
|
8028
|
+
async function seedFromEntropy(entropy, pbkdf2) {
|
|
8029
|
+
return seedFromMnemonic(mnemonicFromEntropy(entropy), "", pbkdf2);
|
|
8030
8030
|
}
|
|
8031
8031
|
|
|
8032
8032
|
// ../wallet-kernel/src/commands/wallets.ts
|
|
@@ -8040,9 +8040,9 @@ async function deriveWalletMaterial(platform, entropy) {
|
|
|
8040
8040
|
}
|
|
8041
8041
|
}
|
|
8042
8042
|
async function walletMaterial(platform, entropy, origin, words) {
|
|
8043
|
-
const { master, walletId
|
|
8043
|
+
const { master, walletId } = await deriveWalletMaterial(platform, entropy);
|
|
8044
8044
|
try {
|
|
8045
|
-
return { walletId
|
|
8045
|
+
return { walletId, entropy, words, origin };
|
|
8046
8046
|
} finally {
|
|
8047
8047
|
master.wipePrivateData();
|
|
8048
8048
|
}
|
|
@@ -8066,25 +8066,25 @@ function walletRecord(ctx, dek, material, backedUp, createdAt) {
|
|
|
8066
8066
|
});
|
|
8067
8067
|
return sealRecord(ctx.platform, dek, "entropy", material.walletId, header, new Uint8Array(material.entropy));
|
|
8068
8068
|
}
|
|
8069
|
-
function gate(ctx,
|
|
8069
|
+
function gate(ctx, factor, requestSession) {
|
|
8070
8070
|
if (ctx.image.meta === undefined) {
|
|
8071
|
-
if (
|
|
8071
|
+
if (factor === undefined) {
|
|
8072
8072
|
throw new KernelError("invalid-input", "an initial factor is required");
|
|
8073
8073
|
}
|
|
8074
8074
|
return { uninitialized: true, dek: Secret.take(ctx.platform.random(32)) };
|
|
8075
8075
|
}
|
|
8076
|
-
if (
|
|
8076
|
+
if (factor !== undefined) {
|
|
8077
8077
|
throw new KernelError("invalid-input", "vault is already initialized");
|
|
8078
8078
|
}
|
|
8079
8079
|
const session = ctx.session.require(requestSession);
|
|
8080
8080
|
return { uninitialized: false, dek: session.dek };
|
|
8081
8081
|
}
|
|
8082
|
-
async function commitRecords(ctx, gated,
|
|
8082
|
+
async function commitRecords(ctx, gated, factor, records) {
|
|
8083
8083
|
if (gated.uninitialized) {
|
|
8084
|
-
if (
|
|
8084
|
+
if (factor === undefined) {
|
|
8085
8085
|
throw new KernelError("integrity", "unreachable: initial factor missing");
|
|
8086
8086
|
}
|
|
8087
|
-
const storedFactor = await makeFactor(ctx.platform,
|
|
8087
|
+
const storedFactor = await makeFactor(ctx.platform, factor, gated.dek);
|
|
8088
8088
|
try {
|
|
8089
8089
|
await ctx.commit([...establishOps(storedFactor, records)]);
|
|
8090
8090
|
} catch (error) {
|
|
@@ -8107,17 +8107,17 @@ function quizPositions(random, count) {
|
|
|
8107
8107
|
while (picked.size < 3) {
|
|
8108
8108
|
const draw = random(4);
|
|
8109
8109
|
for (let i = 0;i < 4 && picked.size < 3; i++) {
|
|
8110
|
-
const
|
|
8111
|
-
if (
|
|
8112
|
-
picked.add(
|
|
8110
|
+
const b = draw[i];
|
|
8111
|
+
if (b !== undefined && b < limit) {
|
|
8112
|
+
picked.add(b % count);
|
|
8113
8113
|
}
|
|
8114
8114
|
}
|
|
8115
8115
|
}
|
|
8116
8116
|
const [a, b, c] = [...picked];
|
|
8117
8117
|
return [a ?? 0, b ?? 0, c ?? 0];
|
|
8118
8118
|
}
|
|
8119
|
-
async function pendingFactorOf(ctx,
|
|
8120
|
-
const material = await newFactorKek(ctx.platform,
|
|
8119
|
+
async function pendingFactorOf(ctx, factor) {
|
|
8120
|
+
const material = await newFactorKek(ctx.platform, factor);
|
|
8121
8121
|
return material.kind === "password" ? { kind: "password", kek: Secret.take(material.kek), salt: material.salt } : { kind: "passkey", kek: Secret.take(material.kek), credentialId: material.credentialId };
|
|
8122
8122
|
}
|
|
8123
8123
|
async function createMnemonic(ctx, params, requestSession) {
|
|
@@ -8169,7 +8169,7 @@ async function confirmMnemonic(ctx, params) {
|
|
|
8169
8169
|
}
|
|
8170
8170
|
const taken = ctx.session.takeDraft(params.draft);
|
|
8171
8171
|
try {
|
|
8172
|
-
const entropy = taken.entropy.use((
|
|
8172
|
+
const entropy = taken.entropy.use((bytes) => new Uint8Array(bytes));
|
|
8173
8173
|
const material = await walletMaterial(ctx.platform, entropy, "mnemonic", taken.words);
|
|
8174
8174
|
try {
|
|
8175
8175
|
ensureNewWallet(ctx, material);
|
|
@@ -8177,15 +8177,15 @@ async function confirmMnemonic(ctx, params) {
|
|
|
8177
8177
|
if (taken.pendingFactor !== undefined) {
|
|
8178
8178
|
const dek = Secret.take(ctx.platform.random(32));
|
|
8179
8179
|
const storedFactor = storedFactorForPending(ctx, taken.pendingFactor, dek);
|
|
8180
|
-
const
|
|
8180
|
+
const record = walletRecord(ctx, dek, material, true, createdAt);
|
|
8181
8181
|
try {
|
|
8182
|
-
await ctx.commit(establishOps(storedFactor, [
|
|
8182
|
+
await ctx.commit(establishOps(storedFactor, [record]));
|
|
8183
8183
|
} catch (error) {
|
|
8184
8184
|
dek.wipe();
|
|
8185
8185
|
throw error;
|
|
8186
8186
|
}
|
|
8187
|
-
const
|
|
8188
|
-
return { wallet: walletInfoOf(material, true, createdAt), session
|
|
8187
|
+
const session = ctx.session.open(dek);
|
|
8188
|
+
return { wallet: walletInfoOf(material, true, createdAt), session };
|
|
8189
8189
|
}
|
|
8190
8190
|
const session = ctx.session.current();
|
|
8191
8191
|
const record = walletRecord(ctx, session.dek, material, true, createdAt);
|
|
@@ -8301,8 +8301,8 @@ var utf8Encoder = new TextEncoder;
|
|
|
8301
8301
|
var utf8Decoder = new TextDecoder;
|
|
8302
8302
|
var HEX32_RE = /^[0-9a-f]{64}$/;
|
|
8303
8303
|
var HEX64_RE = /^[0-9a-f]{128}$/;
|
|
8304
|
-
function bytesToHex$1(
|
|
8305
|
-
return bytesToHex(
|
|
8304
|
+
function bytesToHex$1(bytes) {
|
|
8305
|
+
return bytesToHex(bytes);
|
|
8306
8306
|
}
|
|
8307
8307
|
function hexToBytes$1(hex) {
|
|
8308
8308
|
try {
|
|
@@ -8323,12 +8323,12 @@ function assertHex32(value, label) {
|
|
|
8323
8323
|
throw new HexError(`invalid ${label}: expected 64-char hex`);
|
|
8324
8324
|
return normalized;
|
|
8325
8325
|
}
|
|
8326
|
-
function assertByteLength(
|
|
8327
|
-
if (
|
|
8328
|
-
throw new HexError(`invalid ${label} length: expected ${expected}, got ${
|
|
8326
|
+
function assertByteLength(bytes, expected, label) {
|
|
8327
|
+
if (bytes.length !== expected)
|
|
8328
|
+
throw new HexError(`invalid ${label} length: expected ${expected}, got ${bytes.length}`);
|
|
8329
8329
|
}
|
|
8330
|
-
function assertSecretKeyBytes(
|
|
8331
|
-
assertByteLength(
|
|
8330
|
+
function assertSecretKeyBytes(bytes) {
|
|
8331
|
+
assertByteLength(bytes, 32, "secret key");
|
|
8332
8332
|
}
|
|
8333
8333
|
function isRecord(value) {
|
|
8334
8334
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -8464,20 +8464,20 @@ function getEventHash(event) {
|
|
|
8464
8464
|
}
|
|
8465
8465
|
|
|
8466
8466
|
// ../../node_modules/.bun/@qntx+nostr@0.14.0+ea9f70ecde856c26/node_modules/@qntx/nostr/dist/key-D_oEutQ6.mjs
|
|
8467
|
-
var SecretKey = class
|
|
8467
|
+
var SecretKey = class SecretKey {
|
|
8468
8468
|
#bytes;
|
|
8469
|
-
constructor(
|
|
8470
|
-
assertSecretKeyBytes(
|
|
8471
|
-
this.#bytes = new Uint8Array(
|
|
8469
|
+
constructor(bytes) {
|
|
8470
|
+
assertSecretKeyBytes(bytes);
|
|
8471
|
+
this.#bytes = new Uint8Array(bytes);
|
|
8472
8472
|
}
|
|
8473
8473
|
static generate() {
|
|
8474
|
-
return new
|
|
8474
|
+
return new SecretKey(schnorr.utils.randomSecretKey());
|
|
8475
8475
|
}
|
|
8476
|
-
static fromBytes(
|
|
8477
|
-
return new
|
|
8476
|
+
static fromBytes(bytes) {
|
|
8477
|
+
return new SecretKey(bytes);
|
|
8478
8478
|
}
|
|
8479
8479
|
static fromHex(hex) {
|
|
8480
|
-
return new
|
|
8480
|
+
return new SecretKey(hexToBytes$1(assertHex32(hex, "secret key")));
|
|
8481
8481
|
}
|
|
8482
8482
|
get bytes() {
|
|
8483
8483
|
if (!this.#bytes)
|
|
@@ -8508,7 +8508,7 @@ var nobleSigning = {
|
|
|
8508
8508
|
function getPublicKey(secretKey) {
|
|
8509
8509
|
return bytesToHex$1(schnorr.getPublicKey(toSecretKey(secretKey).bytes));
|
|
8510
8510
|
}
|
|
8511
|
-
var Keys = class
|
|
8511
|
+
var Keys = class Keys {
|
|
8512
8512
|
secretKey;
|
|
8513
8513
|
publicKey;
|
|
8514
8514
|
backend;
|
|
@@ -8527,10 +8527,10 @@ var Keys = class Keys2 {
|
|
|
8527
8527
|
this.publicKey = bytesToHex$1(pubkey);
|
|
8528
8528
|
}
|
|
8529
8529
|
static generate(backend = nobleSigning) {
|
|
8530
|
-
return new
|
|
8530
|
+
return new Keys(SecretKey.generate(), backend);
|
|
8531
8531
|
}
|
|
8532
8532
|
static fromSecretKey(secretKey, backend = nobleSigning) {
|
|
8533
|
-
return new
|
|
8533
|
+
return new Keys(toSecretKey(secretKey), backend);
|
|
8534
8534
|
}
|
|
8535
8535
|
};
|
|
8536
8536
|
function resolveKeys(secretKey) {
|
|
@@ -8639,25 +8639,25 @@ var sbox = /* @__PURE__ */ (() => {
|
|
|
8639
8639
|
var invSbox = /* @__PURE__ */ sbox.map((_, j) => sbox.indexOf(j));
|
|
8640
8640
|
var rotr32_8 = (n) => n << 24 | n >>> 8;
|
|
8641
8641
|
var rotl32_8 = (n) => n << 8 | n >>> 24;
|
|
8642
|
-
function genTtable(
|
|
8643
|
-
if (
|
|
8642
|
+
function genTtable(sbox, fn) {
|
|
8643
|
+
if (sbox.length !== 256)
|
|
8644
8644
|
throw new Error("wrong sbox length");
|
|
8645
|
-
const T0 = new Uint32Array(256).map((_, j) => fn(
|
|
8645
|
+
const T0 = new Uint32Array(256).map((_, j) => fn(sbox[j]));
|
|
8646
8646
|
const T1 = T0.map(rotl32_8);
|
|
8647
8647
|
const T2 = T1.map(rotl32_8);
|
|
8648
8648
|
const T3 = T2.map(rotl32_8);
|
|
8649
8649
|
const T01 = new Uint32Array(256 * 256);
|
|
8650
8650
|
const T23 = new Uint32Array(256 * 256);
|
|
8651
|
-
const
|
|
8651
|
+
const sbox2 = new Uint16Array(256 * 256);
|
|
8652
8652
|
for (let i = 0;i < 256; i++) {
|
|
8653
8653
|
for (let j = 0;j < 256; j++) {
|
|
8654
8654
|
const idx = i * 256 + j;
|
|
8655
8655
|
T01[idx] = T0[i] ^ T1[j];
|
|
8656
8656
|
T23[idx] = T2[i] ^ T3[j];
|
|
8657
|
-
|
|
8657
|
+
sbox2[idx] = sbox[i] << 8 | sbox[j];
|
|
8658
8658
|
}
|
|
8659
8659
|
}
|
|
8660
|
-
return { sbox
|
|
8660
|
+
return { sbox, sbox2, T0, T1, T2, T3, T01, T23 };
|
|
8661
8661
|
}
|
|
8662
8662
|
var tableEncoding = /* @__PURE__ */ genTtable(sbox, (s) => mul(s, 3) << 24 | s << 16 | s << 8 | mul(s, 2));
|
|
8663
8663
|
var tableDecoding = /* @__PURE__ */ genTtable(invSbox, (s) => mul(s, 11) << 24 | mul(s, 13) << 16 | mul(s, 9) << 8 | mul(s, 14));
|
|
@@ -8721,11 +8721,11 @@ function encrypt(xk, s0, s1, s2, s3) {
|
|
|
8721
8721
|
s0 ^= xk[k++], s1 ^= xk[k++], s2 ^= xk[k++], s3 ^= xk[k++];
|
|
8722
8722
|
const rounds = xk.length / 4 - 2;
|
|
8723
8723
|
for (let i = 0;i < rounds; i++) {
|
|
8724
|
-
const
|
|
8725
|
-
const
|
|
8726
|
-
const
|
|
8727
|
-
const
|
|
8728
|
-
s0 =
|
|
8724
|
+
const t0 = xk[k++] ^ apply0123(T01, T23, s0, s1, s2, s3);
|
|
8725
|
+
const t1 = xk[k++] ^ apply0123(T01, T23, s1, s2, s3, s0);
|
|
8726
|
+
const t2 = xk[k++] ^ apply0123(T01, T23, s2, s3, s0, s1);
|
|
8727
|
+
const t3 = xk[k++] ^ apply0123(T01, T23, s3, s0, s1, s2);
|
|
8728
|
+
s0 = t0, s1 = t1, s2 = t2, s3 = t3;
|
|
8729
8729
|
}
|
|
8730
8730
|
const t0 = xk[k++] ^ applySbox(sbox2, s0, s1, s2, s3);
|
|
8731
8731
|
const t1 = xk[k++] ^ applySbox(sbox2, s1, s2, s3, s0);
|
|
@@ -8739,11 +8739,11 @@ function decrypt(xk, s0, s1, s2, s3) {
|
|
|
8739
8739
|
s0 ^= xk[k++], s1 ^= xk[k++], s2 ^= xk[k++], s3 ^= xk[k++];
|
|
8740
8740
|
const rounds = xk.length / 4 - 2;
|
|
8741
8741
|
for (let i = 0;i < rounds; i++) {
|
|
8742
|
-
const
|
|
8743
|
-
const
|
|
8744
|
-
const
|
|
8745
|
-
const
|
|
8746
|
-
s0 =
|
|
8742
|
+
const t0 = xk[k++] ^ apply0123(T01, T23, s0, s3, s2, s1);
|
|
8743
|
+
const t1 = xk[k++] ^ apply0123(T01, T23, s1, s0, s3, s2);
|
|
8744
|
+
const t2 = xk[k++] ^ apply0123(T01, T23, s2, s1, s0, s3);
|
|
8745
|
+
const t3 = xk[k++] ^ apply0123(T01, T23, s3, s2, s1, s0);
|
|
8746
|
+
s0 = t0, s1 = t1, s2 = t2, s3 = t3;
|
|
8747
8747
|
}
|
|
8748
8748
|
const t0 = xk[k++] ^ applySbox(sbox2, s0, s3, s2, s1);
|
|
8749
8749
|
const t1 = xk[k++] ^ applySbox(sbox2, s1, s0, s3, s2);
|
|
@@ -8941,8 +8941,8 @@ var minPlaintextSize = 1;
|
|
|
8941
8941
|
var maxPlaintextSize = 4294967295;
|
|
8942
8942
|
var extendedPrefixThreshold = 65536;
|
|
8943
8943
|
var DEFAULT_MAX_PAYLOAD_CHARS = Math.ceil((71 + calcPaddedLen(1048576)) / 3) * 4;
|
|
8944
|
-
function assert32(
|
|
8945
|
-
if (
|
|
8944
|
+
function assert32(bytes, label) {
|
|
8945
|
+
if (bytes.length !== 32)
|
|
8946
8946
|
throw new CryptoError(`${label} must be 32 bytes`);
|
|
8947
8947
|
}
|
|
8948
8948
|
function getConversationKey(privkeyA, pubkeyB) {
|
|
@@ -8973,19 +8973,19 @@ function calcPaddedLen(len) {
|
|
|
8973
8973
|
const chunk = nextPower <= 256 ? 32 : nextPower / 8;
|
|
8974
8974
|
return chunk * (Math.floor((len - 1) / chunk) + 1);
|
|
8975
8975
|
}
|
|
8976
|
-
function writeU16BE(
|
|
8977
|
-
if (!Number.isSafeInteger(
|
|
8976
|
+
function writeU16BE(num) {
|
|
8977
|
+
if (!Number.isSafeInteger(num) || num < minPlaintextSize || num > 65535)
|
|
8978
8978
|
throw new CryptoError("invalid plaintext size: must be between 1 and 65535 bytes");
|
|
8979
|
-
const
|
|
8980
|
-
new DataView(
|
|
8981
|
-
return
|
|
8979
|
+
const arr = /* @__PURE__ */ new Uint8Array(2);
|
|
8980
|
+
new DataView(arr.buffer).setUint16(0, num, false);
|
|
8981
|
+
return arr;
|
|
8982
8982
|
}
|
|
8983
|
-
function writeU32BE(
|
|
8984
|
-
if (!Number.isSafeInteger(
|
|
8983
|
+
function writeU32BE(num) {
|
|
8984
|
+
if (!Number.isSafeInteger(num) || num < extendedPrefixThreshold || num > maxPlaintextSize)
|
|
8985
8985
|
throw new CryptoError("invalid plaintext size: must be between 65536 and 4294967295 bytes");
|
|
8986
|
-
const
|
|
8987
|
-
new DataView(
|
|
8988
|
-
return
|
|
8986
|
+
const arr = /* @__PURE__ */ new Uint8Array(4);
|
|
8987
|
+
new DataView(arr.buffer).setUint32(0, num, false);
|
|
8988
|
+
return arr;
|
|
8989
8989
|
}
|
|
8990
8990
|
function pad(plaintext) {
|
|
8991
8991
|
const unpadded = utf8Encoder.encode(plaintext);
|
|
@@ -9135,11 +9135,11 @@ var KeysSigner = class {
|
|
|
9135
9135
|
};
|
|
9136
9136
|
// ../wallet-kernel/src/modules/nostr/derive.ts
|
|
9137
9137
|
var NIP06_PATH = "m/44'/1237'/i'/0/0";
|
|
9138
|
-
function nostrKeyAt(master,
|
|
9139
|
-
if (!Number.isSafeInteger(
|
|
9138
|
+
function nostrKeyAt(master, groupIndex) {
|
|
9139
|
+
if (!Number.isSafeInteger(groupIndex) || groupIndex < 0 || groupIndex > 2147483647) {
|
|
9140
9140
|
throw new KernelError("invalid-input", "group index out of range");
|
|
9141
9141
|
}
|
|
9142
|
-
const path = NIP06_PATH.split("/").map((segment) => segment === "i'" ? `${
|
|
9142
|
+
const path = NIP06_PATH.split("/").map((segment) => segment === "i'" ? `${groupIndex}'` : segment).join("/");
|
|
9143
9143
|
const node = master.derive(path);
|
|
9144
9144
|
try {
|
|
9145
9145
|
const key = node.privateKey;
|
|
@@ -9184,15 +9184,15 @@ function encodeBech32(prefix, data) {
|
|
|
9184
9184
|
const words = bech32.toWords(data);
|
|
9185
9185
|
return bech32.encode(prefix, words, Bech32MaxSize2);
|
|
9186
9186
|
}
|
|
9187
|
-
function encodeBytes(prefix,
|
|
9188
|
-
return encodeBech32(prefix,
|
|
9187
|
+
function encodeBytes(prefix, bytes) {
|
|
9188
|
+
return encodeBech32(prefix, bytes);
|
|
9189
9189
|
}
|
|
9190
9190
|
function nsecEncode2(key) {
|
|
9191
9191
|
assertByteLength(key, 32, "secret key");
|
|
9192
9192
|
return encodeBytes("nsec", key);
|
|
9193
9193
|
}
|
|
9194
|
-
function readUint32(
|
|
9195
|
-
return new DataView(
|
|
9194
|
+
function readUint32(bytes) {
|
|
9195
|
+
return new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(0);
|
|
9196
9196
|
}
|
|
9197
9197
|
function decode2(code) {
|
|
9198
9198
|
let prefix;
|
|
@@ -9496,8 +9496,8 @@ async function encrypt4(secretKey, password, opts) {
|
|
|
9496
9496
|
const nonce = randomBytes(NONCE_LEN);
|
|
9497
9497
|
const aad = Uint8Array.from([opts?.ksb ?? 2]);
|
|
9498
9498
|
const ciphertext = xchacha20poly1305(key, nonce, aad).encrypt(secretKey);
|
|
9499
|
-
const
|
|
9500
|
-
return encodeBytes("ncryptsec",
|
|
9499
|
+
const bytes = concatBytes(Uint8Array.from([VERSION2]), Uint8Array.from([logn]), salt, nonce, aad, ciphertext);
|
|
9500
|
+
return encodeBytes("ncryptsec", bytes);
|
|
9501
9501
|
}
|
|
9502
9502
|
async function decrypt4(ncryptsec, password, opts) {
|
|
9503
9503
|
const { maxLogN } = opts;
|
|
@@ -9562,10 +9562,10 @@ function isGiftWrapKind(kind) {
|
|
|
9562
9562
|
return kind === Kind.GiftWrap || kind === Kind.GiftWrapEphemeral;
|
|
9563
9563
|
}
|
|
9564
9564
|
function requireNip44Decryptor(crypto2) {
|
|
9565
|
-
const
|
|
9566
|
-
if (!
|
|
9565
|
+
const decrypt = crypto2.nip44Decrypt;
|
|
9566
|
+
if (!decrypt)
|
|
9567
9567
|
throw new Nip59Error("NIP-44 is required");
|
|
9568
|
-
return { nip44Decrypt: async (peer, payload) =>
|
|
9568
|
+
return { nip44Decrypt: async (peer, payload) => decrypt.call(crypto2, peer, payload) };
|
|
9569
9569
|
}
|
|
9570
9570
|
function parseJson(text) {
|
|
9571
9571
|
try {
|
|
@@ -9620,10 +9620,10 @@ async function unwrap(crypto2, giftWrap) {
|
|
|
9620
9620
|
throw new Nip59Error("seal tags must be empty");
|
|
9621
9621
|
if (!verifyEvent(sealRaw))
|
|
9622
9622
|
throw new Nip59Error("seal signature");
|
|
9623
|
-
const
|
|
9624
|
-
if (sealRaw.pubkey.toLowerCase() !==
|
|
9623
|
+
const rumor = parseRumor(parseJson(await decryptLayer(decryptor, sealRaw.pubkey, sealRaw.content)));
|
|
9624
|
+
if (sealRaw.pubkey.toLowerCase() !== rumor.pubkey.toLowerCase())
|
|
9625
9625
|
throw new Nip59Error("seal pubkey does not match rumor pubkey");
|
|
9626
|
-
return
|
|
9626
|
+
return rumor;
|
|
9627
9627
|
}
|
|
9628
9628
|
|
|
9629
9629
|
// ../wallet-kernel/src/modules/nostr/pool.ts
|
|
@@ -9632,25 +9632,25 @@ class SignerPool {
|
|
|
9632
9632
|
add(secretKey) {
|
|
9633
9633
|
try {
|
|
9634
9634
|
const signer = new KeysSigner(Keys.fromSecretKey(secretKey));
|
|
9635
|
-
const { publicKey
|
|
9636
|
-
this.signers.set(
|
|
9637
|
-
return
|
|
9635
|
+
const { publicKey } = signer.keys;
|
|
9636
|
+
this.signers.set(publicKey, signer);
|
|
9637
|
+
return publicKey;
|
|
9638
9638
|
} finally {
|
|
9639
9639
|
wipe(secretKey);
|
|
9640
9640
|
}
|
|
9641
9641
|
}
|
|
9642
|
-
get(
|
|
9643
|
-
const signer = this.signers.get(
|
|
9642
|
+
get(publicKey) {
|
|
9643
|
+
const signer = this.signers.get(publicKey);
|
|
9644
9644
|
if (signer === undefined) {
|
|
9645
9645
|
throw new KernelError("not-found", "no such nostr key");
|
|
9646
9646
|
}
|
|
9647
9647
|
return signer;
|
|
9648
9648
|
}
|
|
9649
|
-
remove(
|
|
9650
|
-
const signer = this.signers.get(
|
|
9649
|
+
remove(publicKey) {
|
|
9650
|
+
const signer = this.signers.get(publicKey);
|
|
9651
9651
|
if (signer !== undefined) {
|
|
9652
9652
|
signer.dispose();
|
|
9653
|
-
this.signers.delete(
|
|
9653
|
+
this.signers.delete(publicKey);
|
|
9654
9654
|
}
|
|
9655
9655
|
}
|
|
9656
9656
|
dispose() {
|
|
@@ -9702,26 +9702,26 @@ async function ncryptsecFromSecretKey(secretKey, password, ksb) {
|
|
|
9702
9702
|
const encoded = await encrypt4(secretKey, text, { logn: 16, ksb });
|
|
9703
9703
|
return new TextEncoder().encode(encoded);
|
|
9704
9704
|
}
|
|
9705
|
-
async function signEvent2(pool,
|
|
9706
|
-
if (event.pubkey !== undefined && event.pubkey !==
|
|
9705
|
+
async function signEvent2(pool, publicKey, event) {
|
|
9706
|
+
if (event.pubkey !== undefined && event.pubkey !== publicKey) {
|
|
9707
9707
|
throw new KernelError("invalid-input", "event pubkey does not match the selected key");
|
|
9708
9708
|
}
|
|
9709
9709
|
const unsigned = {
|
|
9710
|
-
pubkey:
|
|
9710
|
+
pubkey: publicKey,
|
|
9711
9711
|
kind: event.kind,
|
|
9712
9712
|
created_at: event.created_at,
|
|
9713
9713
|
tags: event.tags,
|
|
9714
9714
|
content: event.content
|
|
9715
9715
|
};
|
|
9716
|
-
return pool.get(
|
|
9716
|
+
return pool.get(publicKey).signEvent(unsigned);
|
|
9717
9717
|
}
|
|
9718
|
-
async function unwrapGiftWrap(pool,
|
|
9718
|
+
async function unwrapGiftWrap(pool, publicKey, event) {
|
|
9719
9719
|
if (!isGiftWrapKind(event.kind)) {
|
|
9720
9720
|
return { err: "invalid-input" };
|
|
9721
9721
|
}
|
|
9722
9722
|
try {
|
|
9723
|
-
const
|
|
9724
|
-
return { ok:
|
|
9723
|
+
const rumor = await unwrap(pool.get(publicKey), event);
|
|
9724
|
+
return { ok: rumor };
|
|
9725
9725
|
} catch (error) {
|
|
9726
9726
|
const err = error instanceof KernelError ? error.code : "integrity";
|
|
9727
9727
|
return { err };
|
|
@@ -9745,12 +9745,12 @@ function encodeNostrKeyHeader(header) {
|
|
|
9745
9745
|
}
|
|
9746
9746
|
function parseNostrKeyHeader(text) {
|
|
9747
9747
|
const object = headerObject(text);
|
|
9748
|
-
const
|
|
9748
|
+
const publicKey = asPublicKey(object["publicKey"]);
|
|
9749
9749
|
const createdAt = asCreatedAt(object["createdAt"]);
|
|
9750
9750
|
if (object["origin"] === "derived") {
|
|
9751
9751
|
expectKeys(object, ["publicKey", "origin", "walletId", "groupIndex", "createdAt"]);
|
|
9752
9752
|
return {
|
|
9753
|
-
publicKey
|
|
9753
|
+
publicKey,
|
|
9754
9754
|
origin: "derived",
|
|
9755
9755
|
walletId: asWalletId(object["walletId"]),
|
|
9756
9756
|
groupIndex: asGroupIndex(object["groupIndex"]),
|
|
@@ -9762,7 +9762,7 @@ function parseNostrKeyHeader(text) {
|
|
|
9762
9762
|
if (origin !== "nsec" && origin !== "ncryptsec" && origin !== "generated" && origin !== "nip46-client") {
|
|
9763
9763
|
throw headerFailure();
|
|
9764
9764
|
}
|
|
9765
|
-
return { publicKey
|
|
9765
|
+
return { publicKey, origin, createdAt };
|
|
9766
9766
|
}
|
|
9767
9767
|
function nostrKeyInfo2(header) {
|
|
9768
9768
|
return {
|
|
@@ -9789,18 +9789,18 @@ function nostrStatus2(records) {
|
|
|
9789
9789
|
function keyRecord(ctx, dek, secretKey, header) {
|
|
9790
9790
|
return sealRecord(ctx.platform, dek, NOSTR_KEY_KIND, header.publicKey, encodeNostrKeyHeader(header), new Uint8Array(secretKey));
|
|
9791
9791
|
}
|
|
9792
|
-
function ensureNewKey(ctx,
|
|
9793
|
-
if (ctx.image.records.some((r) => r.kind === NOSTR_KEY_KIND && r.id ===
|
|
9792
|
+
function ensureNewKey(ctx, publicKey) {
|
|
9793
|
+
if (ctx.image.records.some((r) => r.kind === NOSTR_KEY_KIND && r.id === publicKey)) {
|
|
9794
9794
|
throw new KernelError("already-exists", "nostr key already exists");
|
|
9795
9795
|
}
|
|
9796
9796
|
}
|
|
9797
|
-
async function addKey(ctx, pool, secretKey, origin,
|
|
9798
|
-
const gated = gate(ctx,
|
|
9799
|
-
const
|
|
9800
|
-
ensureNewKey(ctx,
|
|
9801
|
-
const header = { publicKey
|
|
9797
|
+
async function addKey(ctx, pool, secretKey, origin, factor, requestSession) {
|
|
9798
|
+
const gated = gate(ctx, factor, requestSession);
|
|
9799
|
+
const publicKey = getPublicKey(secretKey);
|
|
9800
|
+
ensureNewKey(ctx, publicKey);
|
|
9801
|
+
const header = { publicKey, origin, createdAt: ctx.platform.now() };
|
|
9802
9802
|
const record = keyRecord(ctx, gated.dek, secretKey, header);
|
|
9803
|
-
const session = await commitRecords(ctx, gated,
|
|
9803
|
+
const session = await commitRecords(ctx, gated, factor, [record]);
|
|
9804
9804
|
pool.add(secretKey);
|
|
9805
9805
|
return { key: nostrKeyInfo2(header), session };
|
|
9806
9806
|
}
|
|
@@ -9825,10 +9825,10 @@ async function createNip46ClientKey(ctx, pool, requestSession) {
|
|
|
9825
9825
|
const { dek } = ctx.session.require(requestSession);
|
|
9826
9826
|
const secretKey = generateSecretKey(ctx.platform.random);
|
|
9827
9827
|
try {
|
|
9828
|
-
const
|
|
9829
|
-
ensureNewKey(ctx,
|
|
9828
|
+
const publicKey = getPublicKey(secretKey);
|
|
9829
|
+
ensureNewKey(ctx, publicKey);
|
|
9830
9830
|
const header = {
|
|
9831
|
-
publicKey
|
|
9831
|
+
publicKey,
|
|
9832
9832
|
origin: "nip46-client",
|
|
9833
9833
|
createdAt: ctx.platform.now()
|
|
9834
9834
|
};
|
|
@@ -9850,10 +9850,10 @@ async function deriveKey2(ctx, pool, params, requestSession) {
|
|
|
9850
9850
|
try {
|
|
9851
9851
|
const secretKey = nostrKeyAt(master, params.groupIndex);
|
|
9852
9852
|
try {
|
|
9853
|
-
const
|
|
9854
|
-
ensureNewKey(ctx,
|
|
9853
|
+
const publicKey = getPublicKey(secretKey);
|
|
9854
|
+
ensureNewKey(ctx, publicKey);
|
|
9855
9855
|
const header = {
|
|
9856
|
-
publicKey
|
|
9856
|
+
publicKey,
|
|
9857
9857
|
origin: "derived",
|
|
9858
9858
|
walletId: params.walletId,
|
|
9859
9859
|
groupIndex: params.groupIndex,
|
|
@@ -9880,9 +9880,9 @@ async function discover(ctx, params, requestSession) {
|
|
|
9880
9880
|
wipe(seed);
|
|
9881
9881
|
try {
|
|
9882
9882
|
for (let i = 0;i < params.count; i++) {
|
|
9883
|
-
const
|
|
9884
|
-
const secretKey = nostrKeyAt(master,
|
|
9885
|
-
keys.push({ groupIndex
|
|
9883
|
+
const groupIndex = params.from + i;
|
|
9884
|
+
const secretKey = nostrKeyAt(master, groupIndex);
|
|
9885
|
+
keys.push({ groupIndex, publicKey: getPublicKey(secretKey) });
|
|
9886
9886
|
wipe(secretKey);
|
|
9887
9887
|
}
|
|
9888
9888
|
return { keys };
|
|
@@ -9970,14 +9970,14 @@ function createNostrModule() {
|
|
|
9970
9970
|
lock: () => {
|
|
9971
9971
|
pool.dispose();
|
|
9972
9972
|
},
|
|
9973
|
-
walletDeleteOps: (image,
|
|
9973
|
+
walletDeleteOps: (image, walletId) => {
|
|
9974
9974
|
const ids = [];
|
|
9975
9975
|
for (const record of image.records) {
|
|
9976
9976
|
if (record.kind !== NOSTR_KEY_KIND) {
|
|
9977
9977
|
continue;
|
|
9978
9978
|
}
|
|
9979
9979
|
const header = parseNostrKeyHeader(record.header);
|
|
9980
|
-
if (header.origin === "derived" && header.walletId ===
|
|
9980
|
+
if (header.origin === "derived" && header.walletId === walletId) {
|
|
9981
9981
|
ids.push(record.id);
|
|
9982
9982
|
}
|
|
9983
9983
|
}
|
|
@@ -10175,9 +10175,9 @@ function statusContents(image, modules, nostr) {
|
|
|
10175
10175
|
const wallets = [];
|
|
10176
10176
|
const owned = [];
|
|
10177
10177
|
let corrupted = false;
|
|
10178
|
-
for (const
|
|
10178
|
+
for (const factor of image.factors) {
|
|
10179
10179
|
try {
|
|
10180
|
-
factors.push(factorInfo2(
|
|
10180
|
+
factors.push(factorInfo2(factor));
|
|
10181
10181
|
} catch {
|
|
10182
10182
|
corrupted = true;
|
|
10183
10183
|
}
|
|
@@ -10240,7 +10240,7 @@ function isMethodName(method) {
|
|
|
10240
10240
|
function startKernel(platform, port) {
|
|
10241
10241
|
const nostr = createNostrModule();
|
|
10242
10242
|
const HANDLERS = {
|
|
10243
|
-
status: (
|
|
10243
|
+
status: (ctx) => statusPayload2(ctx, nostr),
|
|
10244
10244
|
...CORE_HANDLERS,
|
|
10245
10245
|
...nostr.handlers
|
|
10246
10246
|
};
|