@did-btcr2/method 0.32.0 → 0.33.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/README.md +25 -13
- package/dist/.tsbuildinfo +1 -1
- package/dist/browser.js +149 -573
- package/dist/browser.mjs +149 -573
- package/dist/cjs/index.js +15 -12
- package/dist/esm/core/aggregation/beacon-strategy.js +5 -4
- package/dist/esm/core/aggregation/beacon-strategy.js.map +1 -1
- package/dist/esm/core/beacon/smt-beacon.js +19 -11
- package/dist/esm/core/beacon/smt-beacon.js.map +1 -1
- package/dist/esm/core/resolver.js +7 -4
- package/dist/esm/core/resolver.js.map +1 -1
- package/dist/types/core/aggregation/beacon-strategy.d.ts.map +1 -1
- package/dist/types/core/beacon/smt-beacon.d.ts.map +1 -1
- package/dist/types/core/interfaces.d.ts +14 -11
- package/dist/types/core/interfaces.d.ts.map +1 -1
- package/dist/types/core/resolver.d.ts.map +1 -1
- package/package.json +20 -8
- package/src/core/aggregation/beacon-strategy.ts +5 -4
- package/src/core/beacon/smt-beacon.ts +20 -12
- package/src/core/interfaces.ts +14 -11
- package/src/core/resolver.ts +8 -5
package/dist/browser.js
CHANGED
|
@@ -46578,11 +46578,11 @@ ${[...listenStats.errors.entries()].map(([addr, err]) => {
|
|
|
46578
46578
|
return "";
|
|
46579
46579
|
}
|
|
46580
46580
|
const dif = fullLength - str.length;
|
|
46581
|
-
const
|
|
46581
|
+
const padding2 = new Array(dif);
|
|
46582
46582
|
for (let i4 = 0; i4 < dif; i4++) {
|
|
46583
|
-
|
|
46583
|
+
padding2[i4] = "0";
|
|
46584
46584
|
}
|
|
46585
|
-
const paddingString =
|
|
46585
|
+
const paddingString = padding2.join("");
|
|
46586
46586
|
return paddingString.concat(str);
|
|
46587
46587
|
}
|
|
46588
46588
|
var log22;
|
|
@@ -93384,32 +93384,6 @@ a=end-of-candidates
|
|
|
93384
93384
|
};
|
|
93385
93385
|
}
|
|
93386
93386
|
// @__NO_SIDE_EFFECTS__
|
|
93387
|
-
function padding(bits, chr = "=") {
|
|
93388
|
-
anumber2(bits);
|
|
93389
|
-
astr("padding", chr);
|
|
93390
|
-
return {
|
|
93391
|
-
encode(data) {
|
|
93392
|
-
astrArr("padding.encode", data);
|
|
93393
|
-
while (data.length * bits % 8)
|
|
93394
|
-
data.push(chr);
|
|
93395
|
-
return data;
|
|
93396
|
-
},
|
|
93397
|
-
decode(input) {
|
|
93398
|
-
astrArr("padding.decode", input);
|
|
93399
|
-
let end = input.length;
|
|
93400
|
-
if (end * bits % 8)
|
|
93401
|
-
throw new Error("padding: invalid, string should have whole number of bytes");
|
|
93402
|
-
for (; end > 0 && input[end - 1] === chr; end--) {
|
|
93403
|
-
const last = end - 1;
|
|
93404
|
-
const byte = last * bits;
|
|
93405
|
-
if (byte % 8 === 0)
|
|
93406
|
-
throw new Error("padding: invalid, string has too much padding");
|
|
93407
|
-
}
|
|
93408
|
-
return input.slice(0, end);
|
|
93409
|
-
}
|
|
93410
|
-
};
|
|
93411
|
-
}
|
|
93412
|
-
// @__NO_SIDE_EFFECTS__
|
|
93413
93387
|
function normalize(fn) {
|
|
93414
93388
|
afn(fn);
|
|
93415
93389
|
return { encode: (from8) => from8, decode: (to) => fn(to) };
|
|
@@ -93470,7 +93444,7 @@ a=end-of-candidates
|
|
|
93470
93444
|
res.push(2 ** i4);
|
|
93471
93445
|
return res;
|
|
93472
93446
|
})();
|
|
93473
|
-
function convertRadix2(data, from8, to,
|
|
93447
|
+
function convertRadix2(data, from8, to, padding2) {
|
|
93474
93448
|
aArr(data);
|
|
93475
93449
|
if (from8 <= 0 || from8 > 32)
|
|
93476
93450
|
throw new Error(`convertRadix2: wrong from=${from8}`);
|
|
@@ -93500,11 +93474,11 @@ a=end-of-candidates
|
|
|
93500
93474
|
carry &= pow3 - 1;
|
|
93501
93475
|
}
|
|
93502
93476
|
carry = carry << to - pos & mask;
|
|
93503
|
-
if (!
|
|
93477
|
+
if (!padding2 && pos >= from8)
|
|
93504
93478
|
throw new Error("Excess padding");
|
|
93505
|
-
if (!
|
|
93479
|
+
if (!padding2 && carry > 0)
|
|
93506
93480
|
throw new Error(`Non-zero padding: ${carry}`);
|
|
93507
|
-
if (
|
|
93481
|
+
if (padding2 && pos > 0)
|
|
93508
93482
|
res.push(carry >>> 0);
|
|
93509
93483
|
return res;
|
|
93510
93484
|
}
|
|
@@ -93578,24 +93552,6 @@ a=end-of-candidates
|
|
|
93578
93552
|
}
|
|
93579
93553
|
};
|
|
93580
93554
|
}
|
|
93581
|
-
var hasBase64Builtin = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toBase64 === "function" && typeof Uint8Array.fromBase64 === "function")();
|
|
93582
|
-
var decodeBase64Builtin = (s2, isUrl) => {
|
|
93583
|
-
astr("base64", s2);
|
|
93584
|
-
const re = isUrl ? /^[A-Za-z0-9=_-]+$/ : /^[A-Za-z0-9=+/]+$/;
|
|
93585
|
-
const alphabet5 = isUrl ? "base64url" : "base64";
|
|
93586
|
-
if (s2.length > 0 && !re.test(s2))
|
|
93587
|
-
throw new Error("invalid base64");
|
|
93588
|
-
return Uint8Array.fromBase64(s2, { alphabet: alphabet5, lastChunkHandling: "strict" });
|
|
93589
|
-
};
|
|
93590
|
-
var base64 = hasBase64Builtin ? {
|
|
93591
|
-
encode(b) {
|
|
93592
|
-
abytes2(b);
|
|
93593
|
-
return b.toBase64();
|
|
93594
|
-
},
|
|
93595
|
-
decode(s2) {
|
|
93596
|
-
return decodeBase64Builtin(s2, false);
|
|
93597
|
-
}
|
|
93598
|
-
} : /* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ padding(6), /* @__PURE__ */ join(""));
|
|
93599
93555
|
var base64urlnopad = /* @__PURE__ */ chain(/* @__PURE__ */ radix2(6), /* @__PURE__ */ alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"), /* @__PURE__ */ join(""));
|
|
93600
93556
|
var genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain(/* @__PURE__ */ radix(58), /* @__PURE__ */ alphabet(abc), /* @__PURE__ */ join(""));
|
|
93601
93557
|
var base58 = /* @__PURE__ */ genBase58("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
|
|
@@ -98030,7 +97986,7 @@ a=end-of-candidates
|
|
|
98030
97986
|
};
|
|
98031
97987
|
}
|
|
98032
97988
|
// @__NO_SIDE_EFFECTS__
|
|
98033
|
-
function
|
|
97989
|
+
function padding(bits, chr = "=") {
|
|
98034
97990
|
anumber4(bits);
|
|
98035
97991
|
astr2("padding", chr);
|
|
98036
97992
|
return {
|
|
@@ -98111,7 +98067,7 @@ a=end-of-candidates
|
|
|
98111
98067
|
res.push(2 ** i4);
|
|
98112
98068
|
return res;
|
|
98113
98069
|
})();
|
|
98114
|
-
function convertRadix22(data, from8, to,
|
|
98070
|
+
function convertRadix22(data, from8, to, padding2) {
|
|
98115
98071
|
aArr2(data);
|
|
98116
98072
|
if (from8 <= 0 || from8 > 32)
|
|
98117
98073
|
throw new Error(`convertRadix2: wrong from=${from8}`);
|
|
@@ -98141,11 +98097,11 @@ a=end-of-candidates
|
|
|
98141
98097
|
carry &= pow3 - 1;
|
|
98142
98098
|
}
|
|
98143
98099
|
carry = carry << to - pos & mask;
|
|
98144
|
-
if (!
|
|
98100
|
+
if (!padding2 && pos >= from8)
|
|
98145
98101
|
throw new Error("Excess padding");
|
|
98146
|
-
if (!
|
|
98102
|
+
if (!padding2 && carry > 0)
|
|
98147
98103
|
throw new Error(`Non-zero padding: ${carry}`);
|
|
98148
|
-
if (
|
|
98104
|
+
if (padding2 && pos > 0)
|
|
98149
98105
|
res.push(carry >>> 0);
|
|
98150
98106
|
return res;
|
|
98151
98107
|
}
|
|
@@ -98193,8 +98149,8 @@ a=end-of-candidates
|
|
|
98193
98149
|
}
|
|
98194
98150
|
};
|
|
98195
98151
|
}
|
|
98196
|
-
var
|
|
98197
|
-
var
|
|
98152
|
+
var hasBase64Builtin = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toBase64 === "function" && typeof Uint8Array.fromBase64 === "function")();
|
|
98153
|
+
var decodeBase64Builtin = (s2, isUrl) => {
|
|
98198
98154
|
astr2("base64", s2);
|
|
98199
98155
|
const re = isUrl ? /^[A-Za-z0-9=_-]+$/ : /^[A-Za-z0-9=+/]+$/;
|
|
98200
98156
|
const alphabet5 = isUrl ? "base64url" : "base64";
|
|
@@ -98202,15 +98158,15 @@ a=end-of-candidates
|
|
|
98202
98158
|
throw new Error("invalid base64");
|
|
98203
98159
|
return Uint8Array.fromBase64(s2, { alphabet: alphabet5, lastChunkHandling: "strict" });
|
|
98204
98160
|
};
|
|
98205
|
-
var
|
|
98161
|
+
var base64 = hasBase64Builtin ? {
|
|
98206
98162
|
encode(b) {
|
|
98207
98163
|
abytes4(b);
|
|
98208
98164
|
return b.toBase64();
|
|
98209
98165
|
},
|
|
98210
98166
|
decode(s2) {
|
|
98211
|
-
return
|
|
98167
|
+
return decodeBase64Builtin(s2, false);
|
|
98212
98168
|
}
|
|
98213
|
-
} : /* @__PURE__ */ chain2(/* @__PURE__ */ radix22(6), /* @__PURE__ */ alphabet2("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */
|
|
98169
|
+
} : /* @__PURE__ */ chain2(/* @__PURE__ */ radix22(6), /* @__PURE__ */ alphabet2("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"), /* @__PURE__ */ padding(6), /* @__PURE__ */ join2(""));
|
|
98214
98170
|
var genBase582 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain2(/* @__PURE__ */ radix3(58), /* @__PURE__ */ alphabet2(abc), /* @__PURE__ */ join2(""));
|
|
98215
98171
|
var base582 = /* @__PURE__ */ genBase582("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
|
|
98216
98172
|
var BECH_ALPHABET2 = /* @__PURE__ */ chain2(/* @__PURE__ */ alphabet2("qpzry9x8gf2tvdw0s3jn54khce6mua7l"), /* @__PURE__ */ join2(""));
|
|
@@ -100466,125 +100422,25 @@ a=end-of-candidates
|
|
|
100466
100422
|
}
|
|
100467
100423
|
return s2;
|
|
100468
100424
|
}
|
|
100469
|
-
function hexToHash(hex2) {
|
|
100470
|
-
validateHex(hex2, true);
|
|
100471
|
-
const hash3 = new Uint8Array(HASH_BYTE_LENGTH);
|
|
100472
|
-
for (let i4 = 0; i4 < HASH_BYTE_LENGTH; i4++) {
|
|
100473
|
-
hash3[i4] = Number.parseInt(hex2.substring(i4 * 2, i4 * 2 + 2), 16);
|
|
100474
|
-
}
|
|
100475
|
-
return hash3;
|
|
100476
|
-
}
|
|
100477
|
-
function bigIntToHex(value2, padded) {
|
|
100478
|
-
const s2 = value2.toString(16);
|
|
100479
|
-
return padded ? s2.padStart(HASH_HEX_LENGTH, "0") : s2;
|
|
100480
|
-
}
|
|
100481
|
-
function hexToBigInt(hex2, padded) {
|
|
100482
|
-
validateHex(hex2, padded);
|
|
100483
|
-
return BigInt(`0x${hex2}`);
|
|
100484
|
-
}
|
|
100485
100425
|
function hashesEqual(a2, b) {
|
|
100486
100426
|
if (!isValidHash(a2) || !isValidHash(b))
|
|
100487
100427
|
return false;
|
|
100488
100428
|
return equalBytes(a2, b);
|
|
100489
100429
|
}
|
|
100490
|
-
function
|
|
100430
|
+
function hashToBase64Url(hash3) {
|
|
100491
100431
|
validateHash(hash3);
|
|
100492
|
-
return
|
|
100432
|
+
return base64urlnopad.encode(hash3);
|
|
100493
100433
|
}
|
|
100494
|
-
function
|
|
100495
|
-
const hash3 =
|
|
100434
|
+
function base64UrlToHash(b64u) {
|
|
100435
|
+
const hash3 = base64urlnopad.decode(b64u);
|
|
100496
100436
|
if (hash3.length !== HASH_BYTE_LENGTH) {
|
|
100497
|
-
throw new RangeError(`Invalid
|
|
100437
|
+
throw new RangeError(`Invalid base64url hash: expected ${HASH_BYTE_LENGTH} decoded bytes, got ${hash3.length}`);
|
|
100498
100438
|
}
|
|
100499
100439
|
return hash3;
|
|
100500
100440
|
}
|
|
100501
|
-
function bigIntToBase64(value2, padded) {
|
|
100502
|
-
let bytes3 = bigIntToHash(value2);
|
|
100503
|
-
if (!padded) {
|
|
100504
|
-
const firstNonZero = bytes3.findIndex((b) => b !== 0);
|
|
100505
|
-
bytes3 = firstNonZero === -1 ? new Uint8Array(1) : bytes3.slice(firstNonZero);
|
|
100506
|
-
}
|
|
100507
|
-
return base64.encode(bytes3);
|
|
100508
|
-
}
|
|
100509
|
-
function base64ToBigInt(b64, padded) {
|
|
100510
|
-
const bytes3 = base64.decode(b64);
|
|
100511
|
-
if (padded && bytes3.length !== HASH_BYTE_LENGTH) {
|
|
100512
|
-
throw new RangeError(`Invalid padded base64 bigint: expected ${HASH_BYTE_LENGTH} decoded bytes, got ${bytes3.length}`);
|
|
100513
|
-
}
|
|
100514
|
-
if (bytes3.length > HASH_BYTE_LENGTH) {
|
|
100515
|
-
throw new RangeError(`Value exceeds ${HASH_BYTE_LENGTH} bytes`);
|
|
100516
|
-
}
|
|
100517
|
-
let value2 = 0n;
|
|
100518
|
-
for (const byte of bytes3) {
|
|
100519
|
-
value2 = value2 << 8n | BigInt(byte);
|
|
100520
|
-
}
|
|
100521
|
-
return value2;
|
|
100522
|
-
}
|
|
100523
|
-
var HEX_RE = /^[0-9A-Fa-f]+$/;
|
|
100524
|
-
function validateHex(s2, requireHashLength) {
|
|
100525
|
-
const len = s2.length;
|
|
100526
|
-
const minLen = requireHashLength ? HASH_HEX_LENGTH : 1;
|
|
100527
|
-
if (len < minLen || len > HASH_HEX_LENGTH || !HEX_RE.test(s2)) {
|
|
100528
|
-
throw new RangeError(`Invalid hex string: expected ${requireHashLength ? HASH_HEX_LENGTH : "1-" + HASH_HEX_LENGTH} hex characters, got ${len}`);
|
|
100529
|
-
}
|
|
100530
|
-
}
|
|
100531
100441
|
|
|
100532
100442
|
// ../smt/dist/esm/node.js
|
|
100533
100443
|
init_shim();
|
|
100534
|
-
var BaseNode = class {
|
|
100535
|
-
#index;
|
|
100536
|
-
#depth;
|
|
100537
|
-
constructor(index, depth) {
|
|
100538
|
-
this.#index = index;
|
|
100539
|
-
this.#depth = depth;
|
|
100540
|
-
}
|
|
100541
|
-
get index() {
|
|
100542
|
-
return this.#index;
|
|
100543
|
-
}
|
|
100544
|
-
get depth() {
|
|
100545
|
-
return this.#depth;
|
|
100546
|
-
}
|
|
100547
|
-
};
|
|
100548
|
-
var LeafNode = class extends BaseNode {
|
|
100549
|
-
#hash = null;
|
|
100550
|
-
get hash() {
|
|
100551
|
-
return this.#hash;
|
|
100552
|
-
}
|
|
100553
|
-
set hash(value2) {
|
|
100554
|
-
if (this.#hash !== null) {
|
|
100555
|
-
throw new RangeError("Leaf hash already set");
|
|
100556
|
-
}
|
|
100557
|
-
this.#hash = value2;
|
|
100558
|
-
}
|
|
100559
|
-
reset() {
|
|
100560
|
-
this.#hash = null;
|
|
100561
|
-
}
|
|
100562
|
-
};
|
|
100563
|
-
var ParentNode = class extends BaseNode {
|
|
100564
|
-
#left;
|
|
100565
|
-
#right;
|
|
100566
|
-
constructor(index, depth, left, right) {
|
|
100567
|
-
super(index, depth);
|
|
100568
|
-
this.#left = left;
|
|
100569
|
-
this.#right = right;
|
|
100570
|
-
}
|
|
100571
|
-
get left() {
|
|
100572
|
-
return this.#left;
|
|
100573
|
-
}
|
|
100574
|
-
set left(node) {
|
|
100575
|
-
this.#left = node;
|
|
100576
|
-
}
|
|
100577
|
-
get right() {
|
|
100578
|
-
return this.#right;
|
|
100579
|
-
}
|
|
100580
|
-
set right(node) {
|
|
100581
|
-
this.#right = node;
|
|
100582
|
-
}
|
|
100583
|
-
reset() {
|
|
100584
|
-
this.#left.reset();
|
|
100585
|
-
this.#right.reset();
|
|
100586
|
-
}
|
|
100587
|
-
};
|
|
100588
100444
|
|
|
100589
100445
|
// ../smt/dist/esm/smt-proof.js
|
|
100590
100446
|
init_shim();
|
|
@@ -100594,377 +100450,84 @@ a=end-of-candidates
|
|
|
100594
100450
|
ValidationState2[ValidationState2["Valid"] = 1] = "Valid";
|
|
100595
100451
|
ValidationState2[ValidationState2["Invalid"] = 2] = "Invalid";
|
|
100596
100452
|
})(ValidationState || (ValidationState = {}));
|
|
100597
|
-
var SMTProof = class _SMTProof {
|
|
100598
|
-
#converge;
|
|
100599
|
-
#hashes;
|
|
100600
|
-
constructor(converge, hashes2) {
|
|
100601
|
-
this.#converge = converge;
|
|
100602
|
-
this.#hashes = hashes2;
|
|
100603
|
-
}
|
|
100604
|
-
/** Converge bitmap: bit `i` set means a sibling hash exists at depth `256 - i - 1`. */
|
|
100605
|
-
get converge() {
|
|
100606
|
-
return this.#converge;
|
|
100607
|
-
}
|
|
100608
|
-
/** Sibling hashes at converge points, ordered leaf-to-root. */
|
|
100609
|
-
get hashes() {
|
|
100610
|
-
return this.#hashes;
|
|
100611
|
-
}
|
|
100612
|
-
/**
|
|
100613
|
-
* Verify this proof for a single leaf.
|
|
100614
|
-
*
|
|
100615
|
-
* @param index - Leaf index in the 256-bit key space.
|
|
100616
|
-
* @param candidateHash - Expected leaf hash.
|
|
100617
|
-
* @param rootHash - Expected root hash.
|
|
100618
|
-
* @returns `true` if the proof is valid.
|
|
100619
|
-
*/
|
|
100620
|
-
isValid(index, candidateHash, rootHash) {
|
|
100621
|
-
return this.#validate(index, candidateHash, rootHash);
|
|
100622
|
-
}
|
|
100623
|
-
/**
|
|
100624
|
-
* Batch-validate multiple proofs against the same root hash.
|
|
100625
|
-
*
|
|
100626
|
-
* Caches intermediate (partial) proofs so that subsequent candidates
|
|
100627
|
-
* sharing an ancestor path can short-circuit once a cached match is found.
|
|
100628
|
-
*
|
|
100629
|
-
* @yields One {@link SMTProofResult} per candidate.
|
|
100630
|
-
*/
|
|
100631
|
-
static *isValidBatch(candidates, rootHash) {
|
|
100632
|
-
const cache4 = /* @__PURE__ */ new Map();
|
|
100633
|
-
for (const candidate of candidates) {
|
|
100634
|
-
const added = [];
|
|
100635
|
-
const { index } = candidate;
|
|
100636
|
-
const valid = candidate.proof.#validate(index | OUTER_BIT, candidate.hash, rootHash, (nodeIndex, partial) => {
|
|
100637
|
-
const cached = cache4.get(nodeIndex);
|
|
100638
|
-
if (cached === void 0) {
|
|
100639
|
-
cache4.set(nodeIndex, partial);
|
|
100640
|
-
added.push(nodeIndex);
|
|
100641
|
-
return ValidationState.Pending;
|
|
100642
|
-
}
|
|
100643
|
-
if (hashesEqual(partial.hash, cached.hash) && partial.converge === cached.converge && partial.hashes.length === cached.hashes.length && partial.hashes.every((h, i4) => hashesEqual(h, cached.hashes[i4]))) {
|
|
100644
|
-
return ValidationState.Valid;
|
|
100645
|
-
}
|
|
100646
|
-
return ValidationState.Invalid;
|
|
100647
|
-
});
|
|
100648
|
-
if (!valid) {
|
|
100649
|
-
for (const key of added)
|
|
100650
|
-
cache4.delete(key);
|
|
100651
|
-
}
|
|
100652
|
-
yield { index, valid, additional: candidate.additional };
|
|
100653
|
-
}
|
|
100654
|
-
}
|
|
100655
|
-
/**
|
|
100656
|
-
* Export to JSON.
|
|
100657
|
-
* @param base64 - Use base64 encoding instead of hex (default: `false`).
|
|
100658
|
-
* @param compact - Omit whitespace (default: `true`).
|
|
100659
|
-
*/
|
|
100660
|
-
toJSON(base646 = false, compact = true) {
|
|
100661
|
-
const convergeStr = base646 ? bigIntToBase64(this.#converge, false) : bigIntToHex(this.#converge, false);
|
|
100662
|
-
const hashStrs = this.#hashes.map((h) => base646 ? hashToBase64(h) : hashToHex(h));
|
|
100663
|
-
const obj = { converge: convergeStr, hashes: hashStrs };
|
|
100664
|
-
return JSON.stringify(obj, null, compact ? 0 : 2);
|
|
100665
|
-
}
|
|
100666
|
-
/**
|
|
100667
|
-
* Import from JSON.
|
|
100668
|
-
* @param json - JSON string.
|
|
100669
|
-
* @param base64 - Parse base64 instead of hex (default: `false`).
|
|
100670
|
-
*/
|
|
100671
|
-
static fromJSON(json, base646 = false) {
|
|
100672
|
-
const raw = JSON.parse(json);
|
|
100673
|
-
if (typeof raw?.converge !== "string" || !Array.isArray(raw.hashes)) {
|
|
100674
|
-
throw new RangeError("Invalid SMTProof JSON: expected { converge, hashes }");
|
|
100675
|
-
}
|
|
100676
|
-
const converge = base646 ? base64ToBigInt(raw.converge, false) : hexToBigInt(raw.converge, false);
|
|
100677
|
-
const hashes2 = raw.hashes.map((h) => base646 ? base64ToHash(h) : hexToHash(h));
|
|
100678
|
-
return new _SMTProof(converge, hashes2);
|
|
100679
|
-
}
|
|
100680
|
-
/**
|
|
100681
|
-
* Export to compact binary format.
|
|
100682
|
-
*
|
|
100683
|
-
* Layout: `[convergeZeroCount : 1] [truncatedConverge : 32-zc] [hashCount : 1] [hashes : N*32]`
|
|
100684
|
-
*/
|
|
100685
|
-
toBinary() {
|
|
100686
|
-
const convergeBin = bigIntToHash(this.#converge);
|
|
100687
|
-
let zc = 0;
|
|
100688
|
-
while (zc < HASH_BYTE_LENGTH && convergeBin[zc] === 0)
|
|
100689
|
-
zc++;
|
|
100690
|
-
const truncated = convergeBin.slice(zc);
|
|
100691
|
-
const hashCount = this.#hashes.length;
|
|
100692
|
-
const totalBytes = 1 + truncated.length + 1 + hashCount * HASH_BYTE_LENGTH;
|
|
100693
|
-
const out = new Uint8Array(totalBytes);
|
|
100694
|
-
let pos = 0;
|
|
100695
|
-
out[pos++] = zc;
|
|
100696
|
-
out.set(truncated, pos);
|
|
100697
|
-
pos += truncated.length;
|
|
100698
|
-
out[pos++] = hashCount;
|
|
100699
|
-
for (const h of this.#hashes) {
|
|
100700
|
-
out.set(h, pos);
|
|
100701
|
-
pos += HASH_BYTE_LENGTH;
|
|
100702
|
-
}
|
|
100703
|
-
return out;
|
|
100704
|
-
}
|
|
100705
|
-
/**
|
|
100706
|
-
* Import from compact binary format.
|
|
100707
|
-
* Accepts any sync or async byte iterable (e.g. `Uint8Array`, `ReadableStream`).
|
|
100708
|
-
*/
|
|
100709
|
-
static async fromBinary(source) {
|
|
100710
|
-
const iter = Symbol.iterator in source ? source[Symbol.iterator]() : source[Symbol.asyncIterator]();
|
|
100711
|
-
async function readBytes(n2) {
|
|
100712
|
-
const buf2 = new Uint8Array(n2);
|
|
100713
|
-
for (let i4 = 0; i4 < n2; i4++) {
|
|
100714
|
-
const r2 = await iter.next();
|
|
100715
|
-
if (r2.done)
|
|
100716
|
-
throw new Error("Unexpected end of binary source");
|
|
100717
|
-
buf2[i4] = r2.value;
|
|
100718
|
-
}
|
|
100719
|
-
return buf2;
|
|
100720
|
-
}
|
|
100721
|
-
const zc = (await readBytes(1))[0];
|
|
100722
|
-
const convergeBin = new Uint8Array(HASH_BYTE_LENGTH);
|
|
100723
|
-
convergeBin.set(await readBytes(HASH_BYTE_LENGTH - zc), zc);
|
|
100724
|
-
const hashCount = (await readBytes(1))[0];
|
|
100725
|
-
const hashes2 = new Array(hashCount);
|
|
100726
|
-
for (let i4 = 0; i4 < hashCount; i4++) {
|
|
100727
|
-
hashes2[i4] = await readBytes(HASH_BYTE_LENGTH);
|
|
100728
|
-
}
|
|
100729
|
-
return new _SMTProof(hashToBigInt(convergeBin), hashes2);
|
|
100730
|
-
}
|
|
100731
|
-
#validate(index, candidateHash, rootHash, onMerge) {
|
|
100732
|
-
let nodeIndex = index;
|
|
100733
|
-
let nodeHash = candidateHash;
|
|
100734
|
-
let remaining = this.#converge;
|
|
100735
|
-
const hashes2 = this.#hashes;
|
|
100736
|
-
let hi = 0;
|
|
100737
|
-
const leftPad = [];
|
|
100738
|
-
const rightPad = [];
|
|
100739
|
-
const finalizePadding = () => {
|
|
100740
|
-
if (leftPad.length > 0 || rightPad.length > 0) {
|
|
100741
|
-
nodeHash = blockHash(new Uint8Array(leftPad), nodeHash, new Uint8Array(rightPad));
|
|
100742
|
-
leftPad.length = 0;
|
|
100743
|
-
rightPad.length = 0;
|
|
100744
|
-
}
|
|
100745
|
-
};
|
|
100746
|
-
let state = ValidationState.Pending;
|
|
100747
|
-
for (let i4 = 0; state === ValidationState.Pending && i4 < HASH_BIT_LENGTH; i4++) {
|
|
100748
|
-
const isLeft = (nodeIndex & 1n) === 0n;
|
|
100749
|
-
nodeIndex >>= 1n;
|
|
100750
|
-
const bit = BITS[i4];
|
|
100751
|
-
if ((remaining & bit) !== 0n) {
|
|
100752
|
-
remaining ^= bit;
|
|
100753
|
-
finalizePadding();
|
|
100754
|
-
if (hi >= hashes2.length) {
|
|
100755
|
-
state = ValidationState.Invalid;
|
|
100756
|
-
} else {
|
|
100757
|
-
const peer = hashes2[hi++];
|
|
100758
|
-
nodeHash = isLeft ? blockHash(nodeHash, peer) : blockHash(peer, nodeHash);
|
|
100759
|
-
if (onMerge !== void 0) {
|
|
100760
|
-
state = onMerge(nodeIndex, {
|
|
100761
|
-
hash: nodeHash,
|
|
100762
|
-
converge: remaining,
|
|
100763
|
-
hashes: hashes2.slice(hi)
|
|
100764
|
-
});
|
|
100765
|
-
}
|
|
100766
|
-
}
|
|
100767
|
-
} else {
|
|
100768
|
-
const depth = HASH_BIT_LENGTH - i4 - 1;
|
|
100769
|
-
if (isLeft) {
|
|
100770
|
-
rightPad.push(depth);
|
|
100771
|
-
} else {
|
|
100772
|
-
leftPad.unshift(depth);
|
|
100773
|
-
}
|
|
100774
|
-
}
|
|
100775
|
-
}
|
|
100776
|
-
finalizePadding();
|
|
100777
|
-
if (state === ValidationState.Pending) {
|
|
100778
|
-
state = hi === hashes2.length && hashesEqual(nodeHash, rootHash) ? ValidationState.Valid : ValidationState.Invalid;
|
|
100779
|
-
}
|
|
100780
|
-
return state === ValidationState.Valid;
|
|
100781
|
-
}
|
|
100782
|
-
};
|
|
100783
100453
|
|
|
100784
100454
|
// ../smt/dist/esm/optimized-smt.js
|
|
100785
100455
|
init_shim();
|
|
100786
|
-
|
|
100787
|
-
|
|
100788
|
-
|
|
100789
|
-
|
|
100790
|
-
|
|
100791
|
-
|
|
100792
|
-
|
|
100793
|
-
|
|
100794
|
-
|
|
100795
|
-
|
|
100796
|
-
|
|
100797
|
-
|
|
100798
|
-
|
|
100799
|
-
return this.#allowNonInclusion;
|
|
100800
|
-
}
|
|
100801
|
-
/** Root hash. Throws if tree has not been finalized. */
|
|
100802
|
-
get rootHash() {
|
|
100803
|
-
if (this.#rootHash === null)
|
|
100804
|
-
throw new RangeError("SMT not finalized");
|
|
100805
|
-
return this.#rootHash;
|
|
100456
|
+
|
|
100457
|
+
// ../smt/dist/esm/zero-hash.js
|
|
100458
|
+
init_shim();
|
|
100459
|
+
var TREE_DEPTH = HASH_BIT_LENGTH;
|
|
100460
|
+
function bitAt(index, position) {
|
|
100461
|
+
return Number(index >> BigInt(position) & 1n);
|
|
100462
|
+
}
|
|
100463
|
+
var CACHED_ZERO = (() => {
|
|
100464
|
+
const arr = new Array(TREE_DEPTH + 1);
|
|
100465
|
+
let z = new Uint8Array(HASH_BYTE_LENGTH);
|
|
100466
|
+
for (let h = 0; h <= TREE_DEPTH; h++) {
|
|
100467
|
+
z = blockHash(z, z);
|
|
100468
|
+
arr[h] = z;
|
|
100806
100469
|
}
|
|
100807
|
-
|
|
100808
|
-
|
|
100809
|
-
|
|
100810
|
-
|
|
100811
|
-
|
|
100812
|
-
|
|
100813
|
-
|
|
100814
|
-
|
|
100815
|
-
|
|
100816
|
-
|
|
100817
|
-
|
|
100818
|
-
|
|
100819
|
-
|
|
100820
|
-
|
|
100821
|
-
|
|
100822
|
-
|
|
100470
|
+
return arr;
|
|
100471
|
+
})();
|
|
100472
|
+
function subtreeHash(leaves, height) {
|
|
100473
|
+
if (leaves.length === 0)
|
|
100474
|
+
return CACHED_ZERO[height];
|
|
100475
|
+
if (height === 0)
|
|
100476
|
+
return leaves[0].leaf;
|
|
100477
|
+
const bit = TREE_DEPTH - height;
|
|
100478
|
+
const left = [];
|
|
100479
|
+
const right = [];
|
|
100480
|
+
for (const e2 of leaves)
|
|
100481
|
+
(bitAt(e2.index, bit) === 0 ? left : right).push(e2);
|
|
100482
|
+
return blockHash(subtreeHash(left, height - 1), subtreeHash(right, height - 1));
|
|
100483
|
+
}
|
|
100484
|
+
function zeroHashRoot(leaves) {
|
|
100485
|
+
return subtreeHash(leaves, TREE_DEPTH);
|
|
100486
|
+
}
|
|
100487
|
+
function generateZeroHashProof(leaves, targetIndex) {
|
|
100488
|
+
let collapsed = 0n;
|
|
100489
|
+
const hashes2 = [];
|
|
100490
|
+
for (let height = 1; height <= TREE_DEPTH; height++) {
|
|
100491
|
+
const bit = TREE_DEPTH - height;
|
|
100492
|
+
const siblingLeaves = [];
|
|
100493
|
+
for (const e2 of leaves) {
|
|
100494
|
+
if (e2.index === targetIndex)
|
|
100823
100495
|
continue;
|
|
100824
|
-
|
|
100825
|
-
let
|
|
100826
|
-
|
|
100827
|
-
|
|
100828
|
-
|
|
100829
|
-
let commonIndex = 0n;
|
|
100830
|
-
let commonDepth = 0;
|
|
100831
|
-
let done = false;
|
|
100832
|
-
while (!done) {
|
|
100833
|
-
const bit = BITS[commonDepth];
|
|
100834
|
-
const indexBit = index & bit;
|
|
100835
|
-
const isLeft = indexBit === 0n;
|
|
100836
|
-
if (commonDepth === node.depth) {
|
|
100837
|
-
if (node instanceof ParentNode) {
|
|
100838
|
-
const parent = node;
|
|
100839
|
-
if (isLeft) {
|
|
100840
|
-
node = parent.left;
|
|
100841
|
-
replaceNode = (n2) => {
|
|
100842
|
-
parent.left = n2;
|
|
100843
|
-
};
|
|
100844
|
-
} else {
|
|
100845
|
-
node = parent.right;
|
|
100846
|
-
replaceNode = (n2) => {
|
|
100847
|
-
parent.right = n2;
|
|
100848
|
-
};
|
|
100849
|
-
}
|
|
100850
|
-
} else {
|
|
100851
|
-
throw new RangeError("Duplicate index");
|
|
100852
|
-
}
|
|
100853
|
-
} else if ((node.index & bit) === indexBit) {
|
|
100854
|
-
commonIndex |= indexBit;
|
|
100855
|
-
commonDepth++;
|
|
100856
|
-
} else {
|
|
100857
|
-
replaceNode(new ParentNode(commonIndex, commonDepth, isLeft ? leaf : node, isLeft ? node : leaf));
|
|
100858
|
-
done = true;
|
|
100496
|
+
let sharesLowerPath = true;
|
|
100497
|
+
for (let lower = 0; lower < bit; lower++) {
|
|
100498
|
+
if (bitAt(e2.index, lower) !== bitAt(targetIndex, lower)) {
|
|
100499
|
+
sharesLowerPath = false;
|
|
100500
|
+
break;
|
|
100859
100501
|
}
|
|
100860
100502
|
}
|
|
100503
|
+
if (sharesLowerPath && bitAt(e2.index, bit) !== bitAt(targetIndex, bit))
|
|
100504
|
+
siblingLeaves.push(e2);
|
|
100861
100505
|
}
|
|
100862
|
-
|
|
100863
|
-
|
|
100864
|
-
|
|
100865
|
-
|
|
100866
|
-
* Each leaf's hash can only be set once (until {@link reset}).
|
|
100867
|
-
*/
|
|
100868
|
-
setHash(index, hash3) {
|
|
100869
|
-
this.#checkNotFinalized();
|
|
100870
|
-
validateHash(hash3);
|
|
100871
|
-
let node = this.#root;
|
|
100872
|
-
if (node === null)
|
|
100873
|
-
throw new RangeError("Empty SMT");
|
|
100874
|
-
while (node instanceof ParentNode) {
|
|
100875
|
-
node = (index & BITS[node.depth]) === 0n ? node.left : node.right;
|
|
100876
|
-
}
|
|
100877
|
-
if (node.index !== index)
|
|
100878
|
-
throw new RangeError("Index not found");
|
|
100879
|
-
node.hash = hash3;
|
|
100880
|
-
}
|
|
100881
|
-
// -----------------------------------------------------------------------
|
|
100882
|
-
// Finalize phase
|
|
100883
|
-
// -----------------------------------------------------------------------
|
|
100884
|
-
/**
|
|
100885
|
-
* Compute root hash and generate all proofs in a single recursive pass.
|
|
100886
|
-
* Must be called after all hashes are set.
|
|
100887
|
-
*/
|
|
100888
|
-
finalize() {
|
|
100889
|
-
if (this.#root === null) {
|
|
100890
|
-
this.#rootHash = NULL_HASH;
|
|
100891
|
-
return;
|
|
100506
|
+
if (siblingLeaves.length === 0) {
|
|
100507
|
+
collapsed |= 1n << BigInt(bit);
|
|
100508
|
+
} else {
|
|
100509
|
+
hashes2.push(subtreeHash(siblingLeaves, height - 1));
|
|
100892
100510
|
}
|
|
100893
|
-
const result = this.#finalizeStep(this.#root, 0n, 0);
|
|
100894
|
-
this.#rootHash = result.hash;
|
|
100895
|
-
result.saveProofs([]);
|
|
100896
|
-
}
|
|
100897
|
-
/** Retrieve the proof for an index. Only valid after {@link finalize}. */
|
|
100898
|
-
proof(index) {
|
|
100899
|
-
const p2 = this.#proofs.get(index);
|
|
100900
|
-
if (p2 === void 0)
|
|
100901
|
-
throw new RangeError("Proof not found");
|
|
100902
|
-
return p2;
|
|
100903
|
-
}
|
|
100904
|
-
/** Clear hashes and proofs, keeping the tree structure for reuse. */
|
|
100905
|
-
reset() {
|
|
100906
|
-
this.#root?.reset();
|
|
100907
|
-
this.#rootHash = null;
|
|
100908
|
-
this.#proofs.clear();
|
|
100909
|
-
}
|
|
100910
|
-
/**
|
|
100911
|
-
* Check if the SMT has not been finalized yet.
|
|
100912
|
-
* @throws {Error} If the SMT has already been finalized.
|
|
100913
|
-
*/
|
|
100914
|
-
#checkNotFinalized() {
|
|
100915
|
-
if (this.#rootHash !== null)
|
|
100916
|
-
throw new Error("SMT already finalized");
|
|
100917
100511
|
}
|
|
100918
|
-
|
|
100919
|
-
|
|
100920
|
-
|
|
100921
|
-
|
|
100922
|
-
|
|
100923
|
-
|
|
100924
|
-
|
|
100925
|
-
|
|
100926
|
-
|
|
100927
|
-
|
|
100928
|
-
let saveProofs;
|
|
100929
|
-
if (node instanceof ParentNode) {
|
|
100930
|
-
const childDepth = node.depth + 1;
|
|
100931
|
-
const leftResult = this.#finalizeStep(node.left, converge, childDepth);
|
|
100932
|
-
const rightResult = this.#finalizeStep(node.right, converge, childDepth);
|
|
100933
|
-
hash3 = blockHash(leftResult.hash, rightResult.hash);
|
|
100934
|
-
saveProofs = (hashes2) => {
|
|
100935
|
-
const leftHashes = hashes2;
|
|
100936
|
-
const rightHashes = hashes2.slice();
|
|
100937
|
-
leftHashes.unshift(rightResult.hash);
|
|
100938
|
-
rightHashes.unshift(leftResult.hash);
|
|
100939
|
-
leftResult.saveProofs(leftHashes);
|
|
100940
|
-
rightResult.saveProofs(rightHashes);
|
|
100941
|
-
};
|
|
100512
|
+
return { collapsed, hashes: hashes2 };
|
|
100513
|
+
}
|
|
100514
|
+
function verifyZeroHash(collapsed, hashes2, index, candidate, root) {
|
|
100515
|
+
let acc = candidate;
|
|
100516
|
+
let hashPtr = 0;
|
|
100517
|
+
for (let n2 = 0; n2 < TREE_DEPTH; n2++) {
|
|
100518
|
+
const i4 = TREE_DEPTH - 1 - n2;
|
|
100519
|
+
let sibling;
|
|
100520
|
+
if ((collapsed >> BigInt(i4) & 1n) === 1n) {
|
|
100521
|
+
sibling = CACHED_ZERO[n2];
|
|
100942
100522
|
} else {
|
|
100943
|
-
if (
|
|
100944
|
-
|
|
100945
|
-
|
|
100946
|
-
node.hash = NULL_HASH;
|
|
100947
|
-
}
|
|
100948
|
-
hash3 = node.hash;
|
|
100949
|
-
saveProofs = (hashes2) => {
|
|
100950
|
-
this.#proofs.set(node.index, new SMTProof(converge, hashes2));
|
|
100951
|
-
};
|
|
100952
|
-
}
|
|
100953
|
-
if (node.depth !== depth) {
|
|
100954
|
-
const leftPad = [];
|
|
100955
|
-
const rightPad = [];
|
|
100956
|
-
for (let i4 = node.depth - 1; i4 >= depth; i4--) {
|
|
100957
|
-
if ((node.index & BITS[i4]) === 0n) {
|
|
100958
|
-
rightPad.push(i4);
|
|
100959
|
-
} else {
|
|
100960
|
-
leftPad.unshift(i4);
|
|
100961
|
-
}
|
|
100962
|
-
}
|
|
100963
|
-
hash3 = blockHash(new Uint8Array(leftPad), hash3, new Uint8Array(rightPad));
|
|
100523
|
+
if (hashPtr >= hashes2.length)
|
|
100524
|
+
return false;
|
|
100525
|
+
sibling = hashes2[hashPtr++];
|
|
100964
100526
|
}
|
|
100965
|
-
|
|
100527
|
+
acc = bitAt(index, i4) === 1 ? blockHash(sibling, acc) : blockHash(acc, sibling);
|
|
100966
100528
|
}
|
|
100967
|
-
|
|
100529
|
+
return hashPtr === hashes2.length && hashesEqual(acc, root);
|
|
100530
|
+
}
|
|
100968
100531
|
|
|
100969
100532
|
// ../smt/dist/esm/btcr2-leaf.js
|
|
100970
100533
|
init_shim();
|
|
@@ -100981,51 +100544,53 @@ a=end-of-candidates
|
|
|
100981
100544
|
|
|
100982
100545
|
// ../smt/dist/esm/btcr2-proof.js
|
|
100983
100546
|
init_shim();
|
|
100984
|
-
function serializeProof(
|
|
100547
|
+
function serializeProof(rootHash, proof, options2) {
|
|
100985
100548
|
const result = {
|
|
100986
|
-
id:
|
|
100987
|
-
collapsed:
|
|
100988
|
-
hashes: proof.hashes.map((h) =>
|
|
100549
|
+
id: hashToBase64Url(rootHash),
|
|
100550
|
+
collapsed: hashToBase64Url(bigIntToHash(proof.collapsed)),
|
|
100551
|
+
hashes: proof.hashes.map((h) => hashToBase64Url(h))
|
|
100989
100552
|
};
|
|
100990
100553
|
if (options2?.nonce)
|
|
100991
|
-
result.nonce =
|
|
100554
|
+
result.nonce = hashToBase64Url(options2.nonce);
|
|
100992
100555
|
if (options2?.updateId)
|
|
100993
|
-
result.updateId =
|
|
100556
|
+
result.updateId = hashToBase64Url(options2.updateId);
|
|
100994
100557
|
return result;
|
|
100995
100558
|
}
|
|
100996
100559
|
function deserializeProof(serialized) {
|
|
100997
|
-
const converge = hexToBigInt(serialized.collapsed, false);
|
|
100998
|
-
const hashes2 = serialized.hashes.map((h) => hexToHash(h));
|
|
100999
100560
|
const result = {
|
|
101000
|
-
|
|
101001
|
-
|
|
100561
|
+
rootHash: base64UrlToHash(serialized.id),
|
|
100562
|
+
collapsed: hashToBigInt(base64UrlToHash(serialized.collapsed)),
|
|
100563
|
+
hashes: serialized.hashes.map((h) => base64UrlToHash(h))
|
|
101002
100564
|
};
|
|
101003
100565
|
if (serialized.nonce)
|
|
101004
|
-
result.nonce =
|
|
100566
|
+
result.nonce = base64UrlToHash(serialized.nonce);
|
|
101005
100567
|
if (serialized.updateId)
|
|
101006
|
-
result.updateId =
|
|
100568
|
+
result.updateId = base64UrlToHash(serialized.updateId);
|
|
101007
100569
|
return result;
|
|
101008
100570
|
}
|
|
101009
100571
|
function verifySerializedProof(serialized, index, candidateHash) {
|
|
101010
|
-
const {
|
|
101011
|
-
return
|
|
100572
|
+
const { rootHash, collapsed, hashes: hashes2 } = deserializeProof(serialized);
|
|
100573
|
+
return verifyZeroHash(collapsed, hashes2, index, candidateHash, rootHash);
|
|
101012
100574
|
}
|
|
101013
100575
|
|
|
101014
100576
|
// ../smt/dist/esm/btcr2-tree.js
|
|
101015
100577
|
init_shim();
|
|
101016
100578
|
var BTCR2MerkleTree = class {
|
|
101017
|
-
#smt;
|
|
101018
100579
|
#entries = /* @__PURE__ */ new Map();
|
|
101019
100580
|
#indexByDid = /* @__PURE__ */ new Map();
|
|
101020
|
-
|
|
101021
|
-
|
|
100581
|
+
#leaves = null;
|
|
100582
|
+
#root = null;
|
|
100583
|
+
/**
|
|
100584
|
+
* @param _allowNonInclusion Retained for API compatibility; non-inclusion
|
|
100585
|
+
* leaves are always supported (an entry without `signedUpdate`).
|
|
100586
|
+
*/
|
|
100587
|
+
constructor(_allowNonInclusion = true) {
|
|
101022
100588
|
}
|
|
101023
100589
|
/**
|
|
101024
100590
|
* Add entries to the tree. May be called multiple times before
|
|
101025
100591
|
* {@link finalize}. Duplicate DIDs (same index) throw.
|
|
101026
100592
|
*/
|
|
101027
100593
|
addEntries(entries) {
|
|
101028
|
-
const indexes = [];
|
|
101029
100594
|
for (const entry of entries) {
|
|
101030
100595
|
const index = didToIndex(entry.did);
|
|
101031
100596
|
if (this.#entries.has(index)) {
|
|
@@ -101033,24 +100598,28 @@ a=end-of-candidates
|
|
|
101033
100598
|
}
|
|
101034
100599
|
this.#entries.set(index, entry);
|
|
101035
100600
|
this.#indexByDid.set(entry.did, index);
|
|
101036
|
-
indexes.push(index);
|
|
101037
100601
|
}
|
|
101038
|
-
this.#
|
|
100602
|
+
this.#leaves = null;
|
|
100603
|
+
this.#root = null;
|
|
101039
100604
|
}
|
|
101040
100605
|
/**
|
|
101041
|
-
* Compute leaf hashes and
|
|
100606
|
+
* Compute leaf hashes and the zero-hash root.
|
|
101042
100607
|
* After this call, {@link rootHash} and {@link proof} become available.
|
|
101043
100608
|
*/
|
|
101044
100609
|
finalize() {
|
|
100610
|
+
const leaves = [];
|
|
101045
100611
|
for (const [index, entry] of this.#entries) {
|
|
101046
|
-
const
|
|
101047
|
-
|
|
100612
|
+
const leaf = entry.signedUpdate !== void 0 ? inclusionLeafHash(entry.nonce, entry.signedUpdate) : nonInclusionLeafHash(entry.nonce);
|
|
100613
|
+
leaves.push({ index, leaf });
|
|
101048
100614
|
}
|
|
101049
|
-
this.#
|
|
100615
|
+
this.#leaves = leaves;
|
|
100616
|
+
this.#root = zeroHashRoot(leaves);
|
|
101050
100617
|
}
|
|
101051
100618
|
/** Root hash of the finalized tree. Throws if not finalized. */
|
|
101052
100619
|
get rootHash() {
|
|
101053
|
-
|
|
100620
|
+
if (this.#root === null)
|
|
100621
|
+
throw new Error("Tree not finalized: call finalize() first");
|
|
100622
|
+
return this.#root;
|
|
101054
100623
|
}
|
|
101055
100624
|
/**
|
|
101056
100625
|
* Get the did:btcr2 serialized proof for a DID.
|
|
@@ -101060,14 +100629,18 @@ a=end-of-candidates
|
|
|
101060
100629
|
const index = this.#indexByDid.get(did);
|
|
101061
100630
|
if (index === void 0)
|
|
101062
100631
|
throw new RangeError(`DID not in tree: ${did}`);
|
|
100632
|
+
if (this.#leaves === null || this.#root === null) {
|
|
100633
|
+
throw new Error("Tree not finalized: call finalize() first");
|
|
100634
|
+
}
|
|
101063
100635
|
const entry = this.#entries.get(index);
|
|
101064
|
-
const
|
|
100636
|
+
const proof = generateZeroHashProof(this.#leaves, index);
|
|
101065
100637
|
const updateId = entry.signedUpdate !== void 0 ? blockHash(entry.signedUpdate) : void 0;
|
|
101066
|
-
return serializeProof(
|
|
100638
|
+
return serializeProof(this.#root, proof, { nonce: entry.nonce, updateId });
|
|
101067
100639
|
}
|
|
101068
|
-
/** Clear
|
|
100640
|
+
/** Clear computed leaves and root, keeping entries. */
|
|
101069
100641
|
reset() {
|
|
101070
|
-
this.#
|
|
100642
|
+
this.#leaves = null;
|
|
100643
|
+
this.#root = null;
|
|
101071
100644
|
}
|
|
101072
100645
|
};
|
|
101073
100646
|
|
|
@@ -101102,12 +100675,12 @@ a=end-of-candidates
|
|
|
101102
100675
|
const smtProof = body.smtProof;
|
|
101103
100676
|
if (!smtProof?.updateId || !smtProof?.nonce) return { matches: false };
|
|
101104
100677
|
const canonicalBytes = new TextEncoder().encode(canonicalize2(submittedUpdate));
|
|
101105
|
-
const expectedUpdateId =
|
|
100678
|
+
const expectedUpdateId = hashToBase64Url(blockHash(canonicalBytes));
|
|
101106
100679
|
if (smtProof.updateId !== expectedUpdateId) {
|
|
101107
100680
|
return { matches: false, smtProof };
|
|
101108
100681
|
}
|
|
101109
100682
|
const index = didToIndex(participantDid);
|
|
101110
|
-
const candidateHash = blockHash(blockHash(
|
|
100683
|
+
const candidateHash = blockHash(blockHash(base64UrlToHash(smtProof.nonce)), base64UrlToHash(smtProof.updateId));
|
|
101111
100684
|
return {
|
|
101112
100685
|
matches: verifySerializedProof(smtProof, index, candidateHash),
|
|
101113
100686
|
smtProof
|
|
@@ -108444,8 +108017,8 @@ ${value2}`;
|
|
|
108444
108017
|
let iv = Uint8Array.from(randomBytes2(16));
|
|
108445
108018
|
let plaintext = utf8Encoder.encode(text);
|
|
108446
108019
|
let ciphertext = cbc(normalizedKey, iv).encrypt(plaintext);
|
|
108447
|
-
let ctb64 =
|
|
108448
|
-
let ivb64 =
|
|
108020
|
+
let ctb64 = base64.encode(new Uint8Array(ciphertext));
|
|
108021
|
+
let ivb64 = base64.encode(new Uint8Array(iv.buffer));
|
|
108449
108022
|
return `${ctb64}?iv=${ivb64}`;
|
|
108450
108023
|
}
|
|
108451
108024
|
function decrypt2(secretKey, pubkey, data) {
|
|
@@ -108453,8 +108026,8 @@ ${value2}`;
|
|
|
108453
108026
|
let [ctb64, ivb64] = data.split("?iv=");
|
|
108454
108027
|
let key = secp256k1.getSharedSecret(privkey, hexToBytes2("02" + pubkey));
|
|
108455
108028
|
let normalizedKey = getNormalizedX(key);
|
|
108456
|
-
let iv =
|
|
108457
|
-
let ciphertext =
|
|
108029
|
+
let iv = base64.decode(ivb64);
|
|
108030
|
+
let ciphertext = base64.decode(ctb64);
|
|
108458
108031
|
let plaintext = cbc(normalizedKey, iv).decrypt(ciphertext);
|
|
108459
108032
|
return utf8Decoder.decode(plaintext);
|
|
108460
108033
|
}
|
|
@@ -108774,7 +108347,7 @@ ${value2}`;
|
|
|
108774
108347
|
throw new Error("unknown encryption version");
|
|
108775
108348
|
let data;
|
|
108776
108349
|
try {
|
|
108777
|
-
data =
|
|
108350
|
+
data = base64.decode(payload);
|
|
108778
108351
|
} catch (error) {
|
|
108779
108352
|
throw new Error("invalid base64: " + error.message);
|
|
108780
108353
|
}
|
|
@@ -108795,7 +108368,7 @@ ${value2}`;
|
|
|
108795
108368
|
const padded = pad(plaintext);
|
|
108796
108369
|
const ciphertext = chacha20(chacha_key, chacha_nonce, padded);
|
|
108797
108370
|
const mac = hmacAad(hmac_key, ciphertext, nonce);
|
|
108798
|
-
return
|
|
108371
|
+
return base64.encode(concatBytes2(new Uint8Array([2]), nonce, ciphertext, mac));
|
|
108799
108372
|
}
|
|
108800
108373
|
function decrypt22(payload, conversationKey) {
|
|
108801
108374
|
const { nonce, ciphertext, mac } = decodePayload(payload);
|
|
@@ -110070,7 +109643,7 @@ ${value2}`;
|
|
|
110070
109643
|
}
|
|
110071
109644
|
const signedEvent = await sign(event);
|
|
110072
109645
|
const authorizationScheme = includeAuthorizationScheme ? _authorizationScheme : "";
|
|
110073
|
-
return authorizationScheme +
|
|
109646
|
+
return authorizationScheme + base64.encode(utf8Encoder.encode(JSON.stringify(signedEvent)));
|
|
110074
109647
|
}
|
|
110075
109648
|
async function validateToken(token, url, method) {
|
|
110076
109649
|
const event = await unpackEventFromToken(token).catch((error) => {
|
|
@@ -110086,7 +109659,7 @@ ${value2}`;
|
|
|
110086
109659
|
throw new Error("Missing token");
|
|
110087
109660
|
}
|
|
110088
109661
|
token = token.replace(_authorizationScheme, "");
|
|
110089
|
-
const eventB64 = utf8Decoder.decode(
|
|
109662
|
+
const eventB64 = utf8Decoder.decode(base64.decode(token));
|
|
110090
109663
|
if (!eventB64 || eventB64.length === 0 || !eventB64.startsWith("{")) {
|
|
110091
109664
|
throw new Error("Invalid token");
|
|
110092
109665
|
}
|
|
@@ -112779,9 +112352,6 @@ ${value2}`;
|
|
|
112779
112352
|
});
|
|
112780
112353
|
continue;
|
|
112781
112354
|
}
|
|
112782
|
-
if (!smtProof.updateId) {
|
|
112783
|
-
continue;
|
|
112784
|
-
}
|
|
112785
112355
|
if (!smtProof.nonce) {
|
|
112786
112356
|
throw new SMTBeaconError(
|
|
112787
112357
|
"SMT proof missing required nonce field.",
|
|
@@ -112790,7 +112360,8 @@ ${value2}`;
|
|
|
112790
112360
|
);
|
|
112791
112361
|
}
|
|
112792
112362
|
const index = didToIndex(did);
|
|
112793
|
-
const
|
|
112363
|
+
const nonceHash2 = base64UrlToHash(smtProof.nonce);
|
|
112364
|
+
const candidateHash = smtProof.updateId ? blockHash(blockHash(nonceHash2), base64UrlToHash(smtProof.updateId)) : blockHash(blockHash(nonceHash2));
|
|
112794
112365
|
const valid = verifySerializedProof(smtProof, index, candidateHash);
|
|
112795
112366
|
if (!valid) {
|
|
112796
112367
|
throw new SMTBeaconError(
|
|
@@ -112799,11 +112370,15 @@ ${value2}`;
|
|
|
112799
112370
|
{ smtProof, did }
|
|
112800
112371
|
);
|
|
112801
112372
|
}
|
|
112802
|
-
|
|
112373
|
+
if (!smtProof.updateId) {
|
|
112374
|
+
continue;
|
|
112375
|
+
}
|
|
112376
|
+
const updateHashHex = hashToHex(base64UrlToHash(smtProof.updateId));
|
|
112377
|
+
const signedUpdate = sidecar.updateMap.get(updateHashHex);
|
|
112803
112378
|
if (!signedUpdate) {
|
|
112804
112379
|
needs.push({
|
|
112805
112380
|
kind: "NeedSignedUpdate",
|
|
112806
|
-
updateHash:
|
|
112381
|
+
updateHash: updateHashHex,
|
|
112807
112382
|
beaconServiceId: this.service.id
|
|
112808
112383
|
});
|
|
112809
112384
|
continue;
|
|
@@ -128993,7 +128568,7 @@ ${value2}`;
|
|
|
128993
128568
|
const smtMap = /* @__PURE__ */ new Map();
|
|
128994
128569
|
if (sidecar.smtProofs?.length)
|
|
128995
128570
|
for (const proof of sidecar.smtProofs) {
|
|
128996
|
-
smtMap.set(proof.id, proof);
|
|
128571
|
+
smtMap.set(encode(decode(proof.id, "base64urlnopad"), "hex"), proof);
|
|
128997
128572
|
}
|
|
128998
128573
|
return { updateMap, casMap, smtMap };
|
|
128999
128574
|
}
|
|
@@ -129281,11 +128856,12 @@ ${value2}`;
|
|
|
129281
128856
|
case "NeedSMTProof": {
|
|
129282
128857
|
const smtNeed = need;
|
|
129283
128858
|
const proof = data;
|
|
129284
|
-
|
|
128859
|
+
const proofIdHex = encode(decode(proof.id, "base64urlnopad"), "hex");
|
|
128860
|
+
if (proofIdHex !== smtNeed.smtRootHash) {
|
|
129285
128861
|
throw new ResolveError(
|
|
129286
|
-
`SMT proof root hash mismatch: expected ${smtNeed.smtRootHash}, got ${
|
|
128862
|
+
`SMT proof root hash mismatch: expected ${smtNeed.smtRootHash}, got ${proofIdHex}`,
|
|
129287
128863
|
INVALID_DID_UPDATE,
|
|
129288
|
-
{ expected: smtNeed.smtRootHash, actual:
|
|
128864
|
+
{ expected: smtNeed.smtRootHash, actual: proofIdHex }
|
|
129289
128865
|
);
|
|
129290
128866
|
}
|
|
129291
128867
|
this.#sidecarData.smtMap.set(smtNeed.smtRootHash, proof);
|