@secondlayer/cli 19.2.0 → 19.2.2
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 +1 -1
- package/dist/cli.js +73 -4140
- package/dist/cli.js.map +4 -30
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -16258,7 +16258,7 @@ var CLARINET_SDK_INSTALL_HINT = "This command needs @stacks/clarinet-sdk. Instal
|
|
|
16258
16258
|
var init_clarinet = () => {};
|
|
16259
16259
|
|
|
16260
16260
|
// src/utils/config.ts
|
|
16261
|
-
import { randomBytes
|
|
16261
|
+
import { randomBytes } from "node:crypto";
|
|
16262
16262
|
import { promises as fs2 } from "node:fs";
|
|
16263
16263
|
import { createRequire as createRequire2 } from "node:module";
|
|
16264
16264
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
@@ -16300,7 +16300,7 @@ async function loadConfig(configPath) {
|
|
|
16300
16300
|
target: "node18",
|
|
16301
16301
|
loader: "ts"
|
|
16302
16302
|
});
|
|
16303
|
-
const tempPath = path.join(tmpdir3(), `secondlayer-config-${
|
|
16303
|
+
const tempPath = path.join(tmpdir3(), `secondlayer-config-${randomBytes(4).toString("hex")}.mjs`);
|
|
16304
16304
|
await fs2.writeFile(tempPath, result.code);
|
|
16305
16305
|
try {
|
|
16306
16306
|
const fileUrl = pathToFileURL(tempPath).href;
|
|
@@ -16442,10 +16442,10 @@ var require_ansis = __commonJS(function(exports, module) {
|
|
|
16442
16442
|
});
|
|
16443
16443
|
|
|
16444
16444
|
// ../../node_modules/ansis/index.mjs
|
|
16445
|
-
var import__2, Ansis, fg, bg, rgb, bgRgb,
|
|
16445
|
+
var import__2, Ansis, fg, bg, rgb, bgRgb, hex, bgHex, reset, inverse, hidden, visible, bold2, dim2, italic, underline, strikethrough, black, red2, green2, yellow2, blue2, magenta, cyan2, white, gray, redBright, greenBright, yellowBright, blueBright, magentaBright, cyanBright, whiteBright, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite, bgGray, bgRedBright, bgGreenBright, bgYellowBright, bgBlueBright, bgMagentaBright, bgCyanBright, bgWhiteBright;
|
|
16446
16446
|
var init_ansis = __esm(() => {
|
|
16447
16447
|
import__2 = __toESM(require_ansis(), 1);
|
|
16448
|
-
({ Ansis, fg, bg, rgb, bgRgb, hex
|
|
16448
|
+
({ Ansis, fg, bg, rgb, bgRgb, hex, bgHex, reset, inverse, hidden, visible, bold: bold2, dim: dim2, italic, underline, strikethrough, black, red: red2, green: green2, yellow: yellow2, blue: blue2, magenta, cyan: cyan2, white, gray, redBright, greenBright, yellowBright, blueBright, magentaBright, cyanBright, whiteBright, bgBlack, bgRed, bgGreen, bgYellow, bgBlue, bgMagenta, bgCyan, bgWhite, bgGray, bgRedBright, bgGreenBright, bgYellowBright, bgBlueBright, bgMagentaBright, bgCyanBright, bgWhiteBright } = import__2.default);
|
|
16449
16449
|
});
|
|
16450
16450
|
|
|
16451
16451
|
// ../../node_modules/@antfu/ni/node_modules/package-manager-detector/dist/constants.mjs
|
|
@@ -29440,7 +29440,7 @@ var init_git_status = () => {};
|
|
|
29440
29440
|
|
|
29441
29441
|
// ../../node_modules/typescript/lib/typescript.js
|
|
29442
29442
|
var require_typescript = __commonJS(function(exports, module) {
|
|
29443
|
-
var __dirname = "/Users/ryan/projects/secondlayer/.claude/worktrees/
|
|
29443
|
+
var __dirname = "/Users/ryan/projects/secondlayer/.claude/worktrees/agent-a6ba56a9f98cf6ff7/node_modules/typescript/lib", __filename = "/Users/ryan/projects/secondlayer/.claude/worktrees/agent-a6ba56a9f98cf6ff7/node_modules/typescript/lib/typescript.js";
|
|
29444
29444
|
/*! *****************************************************************************
|
|
29445
29445
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
29446
29446
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
@@ -200248,7 +200248,7 @@ function client() {
|
|
|
200248
200248
|
apiKey: resolveDataPlaneKey()
|
|
200249
200249
|
});
|
|
200250
200250
|
}
|
|
200251
|
-
function
|
|
200251
|
+
function fail(action, err) {
|
|
200252
200252
|
const message = err instanceof Error ? err.message : String(err);
|
|
200253
200253
|
error(`Failed to ${action}: ${message}`);
|
|
200254
200254
|
if (/\b403\b/.test(message) || /forbidden/i.test(message)) {
|
|
@@ -200301,7 +200301,7 @@ function registerIndexCommand(program) {
|
|
|
200301
200301
|
recipient: o.recipient
|
|
200302
200302
|
}), o.json);
|
|
200303
200303
|
} catch (err) {
|
|
200304
|
-
|
|
200304
|
+
fail("list ft transfers", err);
|
|
200305
200305
|
}
|
|
200306
200306
|
});
|
|
200307
200307
|
rangeFlags(index.command("nft-transfers")).description("List decoded SIP-009 non-fungible-token transfers").option("--sender <principal>", "Filter by sender").option("--recipient <principal>", "Filter by recipient").option("--asset-identifier <id>", "Filter by asset identifier").action(async (o) => {
|
|
@@ -200313,7 +200313,7 @@ function registerIndexCommand(program) {
|
|
|
200313
200313
|
assetIdentifier: o.assetIdentifier
|
|
200314
200314
|
}), o.json);
|
|
200315
200315
|
} catch (err) {
|
|
200316
|
-
|
|
200316
|
+
fail("list nft transfers", err);
|
|
200317
200317
|
}
|
|
200318
200318
|
});
|
|
200319
200319
|
rangeFlags(index.command("events")).description("List decoded events by type (stx_*, ft/nft mint/burn, print, …)").option("--event-type <type>", `decoded event type (${VALID_INDEX_TYPES.join(", ")})`).option("--types <type>", "alias for --event-type, ONE value (the Streams spelling)").option("--sender <principal>", "Filter by sender").option("--recipient <principal>", "Filter by recipient").option("--asset-identifier <id>", "Filter by asset identifier").action(async (o) => {
|
|
@@ -200326,7 +200326,7 @@ function registerIndexCommand(program) {
|
|
|
200326
200326
|
assetIdentifier: o.assetIdentifier
|
|
200327
200327
|
}), o.json);
|
|
200328
200328
|
} catch (err) {
|
|
200329
|
-
|
|
200329
|
+
fail("list events", err);
|
|
200330
200330
|
}
|
|
200331
200331
|
});
|
|
200332
200332
|
rangeFlags(index.command("contract-calls")).description("List decoded contract calls (function, args, result)").option("--function-name <name>", "Filter by called function").option("--sender <principal>", "Filter by caller").action(async (o) => {
|
|
@@ -200337,21 +200337,21 @@ function registerIndexCommand(program) {
|
|
|
200337
200337
|
sender: o.sender
|
|
200338
200338
|
}), o.json);
|
|
200339
200339
|
} catch (err) {
|
|
200340
|
-
|
|
200340
|
+
fail("list contract calls", err);
|
|
200341
200341
|
}
|
|
200342
200342
|
});
|
|
200343
200343
|
heightFlags(index.command("canonical")).description("List the canonical Stacks block sequence (height + hash)").action(async (o) => {
|
|
200344
200344
|
try {
|
|
200345
200345
|
emit(await client().canonical.list(heightParams(o)), o.json);
|
|
200346
200346
|
} catch (err) {
|
|
200347
|
-
|
|
200347
|
+
fail("list canonical blocks", err);
|
|
200348
200348
|
}
|
|
200349
200349
|
});
|
|
200350
200350
|
const blocks = heightFlags(index.command("blocks")).description("List decoded blocks (run `blocks get <ref>` for one block)").action(async (o) => {
|
|
200351
200351
|
try {
|
|
200352
200352
|
emit(await client().blocks.list(heightParams(o)), o.json);
|
|
200353
200353
|
} catch (err) {
|
|
200354
|
-
|
|
200354
|
+
fail("list blocks", err);
|
|
200355
200355
|
}
|
|
200356
200356
|
});
|
|
200357
200357
|
blocks.command("get <ref>").description("Get a single block by height or block hash").option("--json", "Print as JSON").action(async (ref, o) => {
|
|
@@ -200359,7 +200359,7 @@ function registerIndexCommand(program) {
|
|
|
200359
200359
|
const block = await client().blocks.get(/^\d+$/.test(ref) ? Number.parseInt(ref, 10) : ref);
|
|
200360
200360
|
emitOne(block, `block ${ref}`, o.json);
|
|
200361
200361
|
} catch (err) {
|
|
200362
|
-
|
|
200362
|
+
fail("get block", err);
|
|
200363
200363
|
}
|
|
200364
200364
|
});
|
|
200365
200365
|
const transactions = rangeFlags(index.command("transactions")).description("List decoded transactions (run `transactions get <txId>` for one)").option("--type <type>", "Filter by transaction type").option("--sender <principal>", "Filter by sender").action(async (o) => {
|
|
@@ -200370,14 +200370,14 @@ function registerIndexCommand(program) {
|
|
|
200370
200370
|
sender: o.sender
|
|
200371
200371
|
}), o.json);
|
|
200372
200372
|
} catch (err) {
|
|
200373
|
-
|
|
200373
|
+
fail("list transactions", err);
|
|
200374
200374
|
}
|
|
200375
200375
|
});
|
|
200376
200376
|
transactions.command("get <txId>").description("Get a single transaction by tx_id").option("--json", "Print as JSON").action(async (txId, o) => {
|
|
200377
200377
|
try {
|
|
200378
200378
|
emitOne(await client().transactions.get(txId), `tx ${txId}`, o.json);
|
|
200379
200379
|
} catch (err) {
|
|
200380
|
-
|
|
200380
|
+
fail("get transaction", err);
|
|
200381
200381
|
}
|
|
200382
200382
|
});
|
|
200383
200383
|
heightFlags(index.command("stacking")).description("List decoded PoX-4 stacking actions").option("--function-name <name>", "Filter by PoX function name").option("--stacker <principal>", "Filter by stacker").option("--caller <principal>", "Filter by caller").action(async (o) => {
|
|
@@ -200389,7 +200389,7 @@ function registerIndexCommand(program) {
|
|
|
200389
200389
|
caller: o.caller
|
|
200390
200390
|
}), o.json);
|
|
200391
200391
|
} catch (err) {
|
|
200392
|
-
|
|
200392
|
+
fail("list stacking actions", err);
|
|
200393
200393
|
}
|
|
200394
200394
|
});
|
|
200395
200395
|
const mempool = index.command("mempool").description("List pending mempool transactions (run `mempool get <txId>` for one)").option("--contract-id <id>", "Filter to pending calls to a contract").option("--function-name <name>", "Filter to pending calls to a function").option("--sender <principal>", "Filter by sender").option("--type <type>", "Filter by transaction type").option("--cursor <cursor>", "Resume token from a previous next_cursor").option("--limit <n>", "Rows per page").option("--json", "Print the full envelope as JSON").action(async (o) => {
|
|
@@ -200403,14 +200403,14 @@ function registerIndexCommand(program) {
|
|
|
200403
200403
|
limit: o.limit ? Number.parseInt(o.limit, 10) : undefined
|
|
200404
200404
|
}), o.json);
|
|
200405
200405
|
} catch (err) {
|
|
200406
|
-
|
|
200406
|
+
fail("list mempool", err);
|
|
200407
200407
|
}
|
|
200408
200408
|
});
|
|
200409
200409
|
mempool.command("get <txId>").description("Get a single pending transaction by tx_id (404 once mined)").option("--json", "Print as JSON").action(async (txId, o) => {
|
|
200410
200410
|
try {
|
|
200411
200411
|
emitOne(await client().mempool.get(txId), `pending tx ${txId}`, o.json);
|
|
200412
200412
|
} catch (err) {
|
|
200413
|
-
|
|
200413
|
+
fail("get mempool tx", err);
|
|
200414
200414
|
}
|
|
200415
200415
|
});
|
|
200416
200416
|
}
|
|
@@ -201469,10 +201469,10 @@ function Connection(options, queues = {}, { onopen = noop5, onend = noop5, onclo
|
|
|
201469
201469
|
async function SASLContinue(x) {
|
|
201470
201470
|
const res = x.toString("utf8", 9).split(",").reduce((acc, x) => (acc[x[0]] = x.slice(2), acc), {});
|
|
201471
201471
|
const saltedPassword = await crypto2.pbkdf2Sync(await Pass(), Buffer.from(res.s, "base64"), parseInt(res.i), 32, "sha256");
|
|
201472
|
-
const clientKey = await
|
|
201472
|
+
const clientKey = await hmac(saltedPassword, "Client Key");
|
|
201473
201473
|
const auth = "n=*,r=" + nonce + "," + "r=" + res.r + ",s=" + res.s + ",i=" + res.i + ",c=biws,r=" + res.r;
|
|
201474
|
-
serverSignature = (await
|
|
201475
|
-
const payload = "c=biws,r=" + res.r + ",p=" + xor(clientKey, Buffer.from(await
|
|
201474
|
+
serverSignature = (await hmac(await hmac(saltedPassword, "Server Key"), auth)).toString("base64");
|
|
201475
|
+
const payload = "c=biws,r=" + res.r + ",p=" + xor(clientKey, Buffer.from(await hmac(await sha256(clientKey), auth))).toString("base64");
|
|
201476
201476
|
write(bytes_default().p().str(payload).end());
|
|
201477
201477
|
}
|
|
201478
201478
|
function SASLFinal(x) {
|
|
@@ -201691,10 +201691,10 @@ function parseError(x) {
|
|
|
201691
201691
|
function md5(x) {
|
|
201692
201692
|
return crypto2.createHash("md5").update(x).digest("hex");
|
|
201693
201693
|
}
|
|
201694
|
-
function
|
|
201694
|
+
function hmac(key, x) {
|
|
201695
201695
|
return crypto2.createHmac("sha256", key).update(x).digest();
|
|
201696
201696
|
}
|
|
201697
|
-
function
|
|
201697
|
+
function sha256(x) {
|
|
201698
201698
|
return crypto2.createHash("sha256").update(x).digest();
|
|
201699
201699
|
}
|
|
201700
201700
|
function xor(a, b) {
|
|
@@ -202526,7 +202526,7 @@ var {
|
|
|
202526
202526
|
// package.json
|
|
202527
202527
|
var package_default = {
|
|
202528
202528
|
name: "@secondlayer/cli",
|
|
202529
|
-
version: "19.2.
|
|
202529
|
+
version: "19.2.2",
|
|
202530
202530
|
description: "Run a Stacks index on your own hardware — set it up, restore verified history, and keep it current.",
|
|
202531
202531
|
repository: {
|
|
202532
202532
|
type: "git",
|
|
@@ -202569,6 +202569,7 @@ var package_default = {
|
|
|
202569
202569
|
"@secondlayer/shared": "^11.20.0",
|
|
202570
202570
|
"@secondlayer/stacks": "^6.1.1",
|
|
202571
202571
|
"@secondlayer/subgraphs": "^6.3.6",
|
|
202572
|
+
"@secondlayer/verify": "^0.2.0",
|
|
202572
202573
|
esbuild: "^0.28.2",
|
|
202573
202574
|
"smol-toml": "^1.8.0",
|
|
202574
202575
|
zod: "^4.3.6"
|
|
@@ -202583,7 +202584,6 @@ var package_default = {
|
|
|
202583
202584
|
},
|
|
202584
202585
|
devDependencies: {
|
|
202585
202586
|
"@antfu/ni": "^24.4.0",
|
|
202586
|
-
"@secondlayer/verify": "workspace:*",
|
|
202587
202587
|
"@stacks/clarinet-sdk": "3.21.1",
|
|
202588
202588
|
"@types/bun": "^1.1.14",
|
|
202589
202589
|
chalk: "^5.3.0",
|
|
@@ -204002,4110 +204002,20 @@ import { getDb as getDb3 } from "@secondlayer/shared/db";
|
|
|
204002
204002
|
init_output();
|
|
204003
204003
|
init_resolve_auth();
|
|
204004
204004
|
|
|
204005
|
-
// src/commands/verify-block.ts
|
|
204006
|
-
import { readFile as readFile3 } from "node:fs/promises";
|
|
204007
|
-
|
|
204008
|
-
// ../../node_modules/@noble/hashes/utils.js
|
|
204009
|
-
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
204010
|
-
function isBytes(a) {
|
|
204011
|
-
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
|
|
204012
|
-
}
|
|
204013
|
-
function anumber(n, title = "") {
|
|
204014
|
-
if (!Number.isSafeInteger(n) || n < 0) {
|
|
204015
|
-
const prefix = title && `"${title}" `;
|
|
204016
|
-
throw new Error(`${prefix}expected integer >= 0, got ${n}`);
|
|
204017
|
-
}
|
|
204018
|
-
}
|
|
204019
|
-
function abytes(value, length, title = "") {
|
|
204020
|
-
const bytes = isBytes(value);
|
|
204021
|
-
const len = value?.length;
|
|
204022
|
-
const needsLen = length !== undefined;
|
|
204023
|
-
if (!bytes || needsLen && len !== length) {
|
|
204024
|
-
const prefix = title && `"${title}" `;
|
|
204025
|
-
const ofLen = needsLen ? ` of length ${length}` : "";
|
|
204026
|
-
const got = bytes ? `length=${len}` : `type=${typeof value}`;
|
|
204027
|
-
throw new Error(prefix + "expected Uint8Array" + ofLen + ", got " + got);
|
|
204028
|
-
}
|
|
204029
|
-
return value;
|
|
204030
|
-
}
|
|
204031
|
-
function ahash(h) {
|
|
204032
|
-
if (typeof h !== "function" || typeof h.create !== "function")
|
|
204033
|
-
throw new Error("Hash must wrapped by utils.createHasher");
|
|
204034
|
-
anumber(h.outputLen);
|
|
204035
|
-
anumber(h.blockLen);
|
|
204036
|
-
}
|
|
204037
|
-
function aexists(instance, checkFinished = true) {
|
|
204038
|
-
if (instance.destroyed)
|
|
204039
|
-
throw new Error("Hash instance has been destroyed");
|
|
204040
|
-
if (checkFinished && instance.finished)
|
|
204041
|
-
throw new Error("Hash#digest() has already been called");
|
|
204042
|
-
}
|
|
204043
|
-
function aoutput(out, instance) {
|
|
204044
|
-
abytes(out, undefined, "digestInto() output");
|
|
204045
|
-
const min = instance.outputLen;
|
|
204046
|
-
if (out.length < min) {
|
|
204047
|
-
throw new Error('"digestInto() output" expected to be of length >=' + min);
|
|
204048
|
-
}
|
|
204049
|
-
}
|
|
204050
|
-
function clean(...arrays) {
|
|
204051
|
-
for (let i = 0;i < arrays.length; i++) {
|
|
204052
|
-
arrays[i].fill(0);
|
|
204053
|
-
}
|
|
204054
|
-
}
|
|
204055
|
-
function createView(arr) {
|
|
204056
|
-
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
204057
|
-
}
|
|
204058
|
-
function rotr(word, shift) {
|
|
204059
|
-
return word << 32 - shift | word >>> shift;
|
|
204060
|
-
}
|
|
204061
|
-
function rotl(word, shift) {
|
|
204062
|
-
return word << shift | word >>> 32 - shift >>> 0;
|
|
204063
|
-
}
|
|
204064
|
-
var hasHexBuiltin = /* @__PURE__ */ (() => typeof Uint8Array.from([]).toHex === "function" && typeof Uint8Array.fromHex === "function")();
|
|
204065
|
-
var hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
|
|
204066
|
-
function bytesToHex(bytes) {
|
|
204067
|
-
abytes(bytes);
|
|
204068
|
-
if (hasHexBuiltin)
|
|
204069
|
-
return bytes.toHex();
|
|
204070
|
-
let hex = "";
|
|
204071
|
-
for (let i = 0;i < bytes.length; i++) {
|
|
204072
|
-
hex += hexes[bytes[i]];
|
|
204073
|
-
}
|
|
204074
|
-
return hex;
|
|
204075
|
-
}
|
|
204076
|
-
var asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
|
|
204077
|
-
function asciiToBase16(ch) {
|
|
204078
|
-
if (ch >= asciis._0 && ch <= asciis._9)
|
|
204079
|
-
return ch - asciis._0;
|
|
204080
|
-
if (ch >= asciis.A && ch <= asciis.F)
|
|
204081
|
-
return ch - (asciis.A - 10);
|
|
204082
|
-
if (ch >= asciis.a && ch <= asciis.f)
|
|
204083
|
-
return ch - (asciis.a - 10);
|
|
204084
|
-
return;
|
|
204085
|
-
}
|
|
204086
|
-
function hexToBytes(hex) {
|
|
204087
|
-
if (typeof hex !== "string")
|
|
204088
|
-
throw new Error("hex string expected, got " + typeof hex);
|
|
204089
|
-
if (hasHexBuiltin)
|
|
204090
|
-
return Uint8Array.fromHex(hex);
|
|
204091
|
-
const hl = hex.length;
|
|
204092
|
-
const al = hl / 2;
|
|
204093
|
-
if (hl % 2)
|
|
204094
|
-
throw new Error("hex string expected, got unpadded hex of length " + hl);
|
|
204095
|
-
const array = new Uint8Array(al);
|
|
204096
|
-
for (let ai = 0, hi = 0;ai < al; ai++, hi += 2) {
|
|
204097
|
-
const n1 = asciiToBase16(hex.charCodeAt(hi));
|
|
204098
|
-
const n2 = asciiToBase16(hex.charCodeAt(hi + 1));
|
|
204099
|
-
if (n1 === undefined || n2 === undefined) {
|
|
204100
|
-
const char = hex[hi] + hex[hi + 1];
|
|
204101
|
-
throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
|
|
204102
|
-
}
|
|
204103
|
-
array[ai] = n1 * 16 + n2;
|
|
204104
|
-
}
|
|
204105
|
-
return array;
|
|
204106
|
-
}
|
|
204107
|
-
function concatBytes(...arrays) {
|
|
204108
|
-
let sum = 0;
|
|
204109
|
-
for (let i = 0;i < arrays.length; i++) {
|
|
204110
|
-
const a = arrays[i];
|
|
204111
|
-
abytes(a);
|
|
204112
|
-
sum += a.length;
|
|
204113
|
-
}
|
|
204114
|
-
const res = new Uint8Array(sum);
|
|
204115
|
-
for (let i = 0, pad = 0;i < arrays.length; i++) {
|
|
204116
|
-
const a = arrays[i];
|
|
204117
|
-
res.set(a, pad);
|
|
204118
|
-
pad += a.length;
|
|
204119
|
-
}
|
|
204120
|
-
return res;
|
|
204121
|
-
}
|
|
204122
|
-
function createHasher(hashCons, info = {}) {
|
|
204123
|
-
const hashC = (msg, opts) => hashCons(opts).update(msg).digest();
|
|
204124
|
-
const tmp = hashCons(undefined);
|
|
204125
|
-
hashC.outputLen = tmp.outputLen;
|
|
204126
|
-
hashC.blockLen = tmp.blockLen;
|
|
204127
|
-
hashC.create = (opts) => hashCons(opts);
|
|
204128
|
-
Object.assign(hashC, info);
|
|
204129
|
-
return Object.freeze(hashC);
|
|
204130
|
-
}
|
|
204131
|
-
function randomBytes(bytesLength = 32) {
|
|
204132
|
-
const cr = typeof globalThis === "object" ? globalThis.crypto : null;
|
|
204133
|
-
if (typeof cr?.getRandomValues !== "function")
|
|
204134
|
-
throw new Error("crypto.getRandomValues must be defined");
|
|
204135
|
-
return cr.getRandomValues(new Uint8Array(bytesLength));
|
|
204136
|
-
}
|
|
204137
|
-
var oidNist = (suffix) => ({
|
|
204138
|
-
oid: Uint8Array.from([6, 9, 96, 134, 72, 1, 101, 3, 4, 2, suffix])
|
|
204139
|
-
});
|
|
204140
|
-
|
|
204141
|
-
// ../../node_modules/@noble/hashes/_md.js
|
|
204142
|
-
function Chi(a, b, c) {
|
|
204143
|
-
return a & b ^ ~a & c;
|
|
204144
|
-
}
|
|
204145
|
-
function Maj(a, b, c) {
|
|
204146
|
-
return a & b ^ a & c ^ b & c;
|
|
204147
|
-
}
|
|
204148
|
-
|
|
204149
|
-
class HashMD {
|
|
204150
|
-
blockLen;
|
|
204151
|
-
outputLen;
|
|
204152
|
-
padOffset;
|
|
204153
|
-
isLE;
|
|
204154
|
-
buffer;
|
|
204155
|
-
view;
|
|
204156
|
-
finished = false;
|
|
204157
|
-
length = 0;
|
|
204158
|
-
pos = 0;
|
|
204159
|
-
destroyed = false;
|
|
204160
|
-
constructor(blockLen, outputLen, padOffset, isLE) {
|
|
204161
|
-
this.blockLen = blockLen;
|
|
204162
|
-
this.outputLen = outputLen;
|
|
204163
|
-
this.padOffset = padOffset;
|
|
204164
|
-
this.isLE = isLE;
|
|
204165
|
-
this.buffer = new Uint8Array(blockLen);
|
|
204166
|
-
this.view = createView(this.buffer);
|
|
204167
|
-
}
|
|
204168
|
-
update(data) {
|
|
204169
|
-
aexists(this);
|
|
204170
|
-
abytes(data);
|
|
204171
|
-
const { view, buffer, blockLen } = this;
|
|
204172
|
-
const len = data.length;
|
|
204173
|
-
for (let pos = 0;pos < len; ) {
|
|
204174
|
-
const take = Math.min(blockLen - this.pos, len - pos);
|
|
204175
|
-
if (take === blockLen) {
|
|
204176
|
-
const dataView = createView(data);
|
|
204177
|
-
for (;blockLen <= len - pos; pos += blockLen)
|
|
204178
|
-
this.process(dataView, pos);
|
|
204179
|
-
continue;
|
|
204180
|
-
}
|
|
204181
|
-
buffer.set(data.subarray(pos, pos + take), this.pos);
|
|
204182
|
-
this.pos += take;
|
|
204183
|
-
pos += take;
|
|
204184
|
-
if (this.pos === blockLen) {
|
|
204185
|
-
this.process(view, 0);
|
|
204186
|
-
this.pos = 0;
|
|
204187
|
-
}
|
|
204188
|
-
}
|
|
204189
|
-
this.length += data.length;
|
|
204190
|
-
this.roundClean();
|
|
204191
|
-
return this;
|
|
204192
|
-
}
|
|
204193
|
-
digestInto(out) {
|
|
204194
|
-
aexists(this);
|
|
204195
|
-
aoutput(out, this);
|
|
204196
|
-
this.finished = true;
|
|
204197
|
-
const { buffer, view, blockLen, isLE } = this;
|
|
204198
|
-
let { pos } = this;
|
|
204199
|
-
buffer[pos++] = 128;
|
|
204200
|
-
clean(this.buffer.subarray(pos));
|
|
204201
|
-
if (this.padOffset > blockLen - pos) {
|
|
204202
|
-
this.process(view, 0);
|
|
204203
|
-
pos = 0;
|
|
204204
|
-
}
|
|
204205
|
-
for (let i = pos;i < blockLen; i++)
|
|
204206
|
-
buffer[i] = 0;
|
|
204207
|
-
view.setBigUint64(blockLen - 8, BigInt(this.length * 8), isLE);
|
|
204208
|
-
this.process(view, 0);
|
|
204209
|
-
const oview = createView(out);
|
|
204210
|
-
const len = this.outputLen;
|
|
204211
|
-
if (len % 4)
|
|
204212
|
-
throw new Error("_sha2: outputLen must be aligned to 32bit");
|
|
204213
|
-
const outLen = len / 4;
|
|
204214
|
-
const state = this.get();
|
|
204215
|
-
if (outLen > state.length)
|
|
204216
|
-
throw new Error("_sha2: outputLen bigger than state");
|
|
204217
|
-
for (let i = 0;i < outLen; i++)
|
|
204218
|
-
oview.setUint32(4 * i, state[i], isLE);
|
|
204219
|
-
}
|
|
204220
|
-
digest() {
|
|
204221
|
-
const { buffer, outputLen } = this;
|
|
204222
|
-
this.digestInto(buffer);
|
|
204223
|
-
const res = buffer.slice(0, outputLen);
|
|
204224
|
-
this.destroy();
|
|
204225
|
-
return res;
|
|
204226
|
-
}
|
|
204227
|
-
_cloneInto(to) {
|
|
204228
|
-
to ||= new this.constructor;
|
|
204229
|
-
to.set(...this.get());
|
|
204230
|
-
const { blockLen, buffer, length, finished, destroyed, pos } = this;
|
|
204231
|
-
to.destroyed = destroyed;
|
|
204232
|
-
to.finished = finished;
|
|
204233
|
-
to.length = length;
|
|
204234
|
-
to.pos = pos;
|
|
204235
|
-
if (length % blockLen)
|
|
204236
|
-
to.buffer.set(buffer);
|
|
204237
|
-
return to;
|
|
204238
|
-
}
|
|
204239
|
-
clone() {
|
|
204240
|
-
return this._cloneInto();
|
|
204241
|
-
}
|
|
204242
|
-
}
|
|
204243
|
-
var SHA256_IV = /* @__PURE__ */ Uint32Array.from([
|
|
204244
|
-
1779033703,
|
|
204245
|
-
3144134277,
|
|
204246
|
-
1013904242,
|
|
204247
|
-
2773480762,
|
|
204248
|
-
1359893119,
|
|
204249
|
-
2600822924,
|
|
204250
|
-
528734635,
|
|
204251
|
-
1541459225
|
|
204252
|
-
]);
|
|
204253
|
-
|
|
204254
|
-
// ../../node_modules/@noble/hashes/_u64.js
|
|
204255
|
-
var U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
|
204256
|
-
var _32n = /* @__PURE__ */ BigInt(32);
|
|
204257
|
-
function fromBig(n, le = false) {
|
|
204258
|
-
if (le)
|
|
204259
|
-
return { h: Number(n & U32_MASK64), l: Number(n >> _32n & U32_MASK64) };
|
|
204260
|
-
return { h: Number(n >> _32n & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
|
|
204261
|
-
}
|
|
204262
|
-
function split(lst, le = false) {
|
|
204263
|
-
const len = lst.length;
|
|
204264
|
-
let Ah = new Uint32Array(len);
|
|
204265
|
-
let Al = new Uint32Array(len);
|
|
204266
|
-
for (let i = 0;i < len; i++) {
|
|
204267
|
-
const { h, l } = fromBig(lst[i], le);
|
|
204268
|
-
[Ah[i], Al[i]] = [h, l];
|
|
204269
|
-
}
|
|
204270
|
-
return [Ah, Al];
|
|
204271
|
-
}
|
|
204272
|
-
var shrSH = (h, _l, s) => h >>> s;
|
|
204273
|
-
var shrSL = (h, l, s) => h << 32 - s | l >>> s;
|
|
204274
|
-
var rotrSH = (h, l, s) => h >>> s | l << 32 - s;
|
|
204275
|
-
var rotrSL = (h, l, s) => h << 32 - s | l >>> s;
|
|
204276
|
-
var rotrBH = (h, l, s) => h << 64 - s | l >>> s - 32;
|
|
204277
|
-
var rotrBL = (h, l, s) => h >>> s - 32 | l << 64 - s;
|
|
204278
|
-
function add(Ah, Al, Bh, Bl) {
|
|
204279
|
-
const l = (Al >>> 0) + (Bl >>> 0);
|
|
204280
|
-
return { h: Ah + Bh + (l / 2 ** 32 | 0) | 0, l: l | 0 };
|
|
204281
|
-
}
|
|
204282
|
-
var add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
|
|
204283
|
-
var add3H = (low, Ah, Bh, Ch) => Ah + Bh + Ch + (low / 2 ** 32 | 0) | 0;
|
|
204284
|
-
var add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
|
|
204285
|
-
var add4H = (low, Ah, Bh, Ch, Dh) => Ah + Bh + Ch + Dh + (low / 2 ** 32 | 0) | 0;
|
|
204286
|
-
var add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
|
|
204287
|
-
var add5H = (low, Ah, Bh, Ch, Dh, Eh) => Ah + Bh + Ch + Dh + Eh + (low / 2 ** 32 | 0) | 0;
|
|
204288
|
-
|
|
204289
|
-
// ../../node_modules/@noble/hashes/sha2.js
|
|
204290
|
-
var SHA256_K = /* @__PURE__ */ Uint32Array.from([
|
|
204291
|
-
1116352408,
|
|
204292
|
-
1899447441,
|
|
204293
|
-
3049323471,
|
|
204294
|
-
3921009573,
|
|
204295
|
-
961987163,
|
|
204296
|
-
1508970993,
|
|
204297
|
-
2453635748,
|
|
204298
|
-
2870763221,
|
|
204299
|
-
3624381080,
|
|
204300
|
-
310598401,
|
|
204301
|
-
607225278,
|
|
204302
|
-
1426881987,
|
|
204303
|
-
1925078388,
|
|
204304
|
-
2162078206,
|
|
204305
|
-
2614888103,
|
|
204306
|
-
3248222580,
|
|
204307
|
-
3835390401,
|
|
204308
|
-
4022224774,
|
|
204309
|
-
264347078,
|
|
204310
|
-
604807628,
|
|
204311
|
-
770255983,
|
|
204312
|
-
1249150122,
|
|
204313
|
-
1555081692,
|
|
204314
|
-
1996064986,
|
|
204315
|
-
2554220882,
|
|
204316
|
-
2821834349,
|
|
204317
|
-
2952996808,
|
|
204318
|
-
3210313671,
|
|
204319
|
-
3336571891,
|
|
204320
|
-
3584528711,
|
|
204321
|
-
113926993,
|
|
204322
|
-
338241895,
|
|
204323
|
-
666307205,
|
|
204324
|
-
773529912,
|
|
204325
|
-
1294757372,
|
|
204326
|
-
1396182291,
|
|
204327
|
-
1695183700,
|
|
204328
|
-
1986661051,
|
|
204329
|
-
2177026350,
|
|
204330
|
-
2456956037,
|
|
204331
|
-
2730485921,
|
|
204332
|
-
2820302411,
|
|
204333
|
-
3259730800,
|
|
204334
|
-
3345764771,
|
|
204335
|
-
3516065817,
|
|
204336
|
-
3600352804,
|
|
204337
|
-
4094571909,
|
|
204338
|
-
275423344,
|
|
204339
|
-
430227734,
|
|
204340
|
-
506948616,
|
|
204341
|
-
659060556,
|
|
204342
|
-
883997877,
|
|
204343
|
-
958139571,
|
|
204344
|
-
1322822218,
|
|
204345
|
-
1537002063,
|
|
204346
|
-
1747873779,
|
|
204347
|
-
1955562222,
|
|
204348
|
-
2024104815,
|
|
204349
|
-
2227730452,
|
|
204350
|
-
2361852424,
|
|
204351
|
-
2428436474,
|
|
204352
|
-
2756734187,
|
|
204353
|
-
3204031479,
|
|
204354
|
-
3329325298
|
|
204355
|
-
]);
|
|
204356
|
-
var SHA256_W = /* @__PURE__ */ new Uint32Array(64);
|
|
204357
|
-
|
|
204358
|
-
class SHA2_32B extends HashMD {
|
|
204359
|
-
constructor(outputLen) {
|
|
204360
|
-
super(64, outputLen, 8, false);
|
|
204361
|
-
}
|
|
204362
|
-
get() {
|
|
204363
|
-
const { A, B, C, D, E, F, G, H } = this;
|
|
204364
|
-
return [A, B, C, D, E, F, G, H];
|
|
204365
|
-
}
|
|
204366
|
-
set(A, B, C, D, E, F, G, H) {
|
|
204367
|
-
this.A = A | 0;
|
|
204368
|
-
this.B = B | 0;
|
|
204369
|
-
this.C = C | 0;
|
|
204370
|
-
this.D = D | 0;
|
|
204371
|
-
this.E = E | 0;
|
|
204372
|
-
this.F = F | 0;
|
|
204373
|
-
this.G = G | 0;
|
|
204374
|
-
this.H = H | 0;
|
|
204375
|
-
}
|
|
204376
|
-
process(view, offset) {
|
|
204377
|
-
for (let i = 0;i < 16; i++, offset += 4)
|
|
204378
|
-
SHA256_W[i] = view.getUint32(offset, false);
|
|
204379
|
-
for (let i = 16;i < 64; i++) {
|
|
204380
|
-
const W15 = SHA256_W[i - 15];
|
|
204381
|
-
const W2 = SHA256_W[i - 2];
|
|
204382
|
-
const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ W15 >>> 3;
|
|
204383
|
-
const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ W2 >>> 10;
|
|
204384
|
-
SHA256_W[i] = s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16] | 0;
|
|
204385
|
-
}
|
|
204386
|
-
let { A, B, C, D, E, F, G, H } = this;
|
|
204387
|
-
for (let i = 0;i < 64; i++) {
|
|
204388
|
-
const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
|
|
204389
|
-
const T1 = H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i] | 0;
|
|
204390
|
-
const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
|
|
204391
|
-
const T2 = sigma0 + Maj(A, B, C) | 0;
|
|
204392
|
-
H = G;
|
|
204393
|
-
G = F;
|
|
204394
|
-
F = E;
|
|
204395
|
-
E = D + T1 | 0;
|
|
204396
|
-
D = C;
|
|
204397
|
-
C = B;
|
|
204398
|
-
B = A;
|
|
204399
|
-
A = T1 + T2 | 0;
|
|
204400
|
-
}
|
|
204401
|
-
A = A + this.A | 0;
|
|
204402
|
-
B = B + this.B | 0;
|
|
204403
|
-
C = C + this.C | 0;
|
|
204404
|
-
D = D + this.D | 0;
|
|
204405
|
-
E = E + this.E | 0;
|
|
204406
|
-
F = F + this.F | 0;
|
|
204407
|
-
G = G + this.G | 0;
|
|
204408
|
-
H = H + this.H | 0;
|
|
204409
|
-
this.set(A, B, C, D, E, F, G, H);
|
|
204410
|
-
}
|
|
204411
|
-
roundClean() {
|
|
204412
|
-
clean(SHA256_W);
|
|
204413
|
-
}
|
|
204414
|
-
destroy() {
|
|
204415
|
-
this.set(0, 0, 0, 0, 0, 0, 0, 0);
|
|
204416
|
-
clean(this.buffer);
|
|
204417
|
-
}
|
|
204418
|
-
}
|
|
204419
|
-
|
|
204420
|
-
class _SHA256 extends SHA2_32B {
|
|
204421
|
-
A = SHA256_IV[0] | 0;
|
|
204422
|
-
B = SHA256_IV[1] | 0;
|
|
204423
|
-
C = SHA256_IV[2] | 0;
|
|
204424
|
-
D = SHA256_IV[3] | 0;
|
|
204425
|
-
E = SHA256_IV[4] | 0;
|
|
204426
|
-
F = SHA256_IV[5] | 0;
|
|
204427
|
-
G = SHA256_IV[6] | 0;
|
|
204428
|
-
H = SHA256_IV[7] | 0;
|
|
204429
|
-
constructor() {
|
|
204430
|
-
super(32);
|
|
204431
|
-
}
|
|
204432
|
-
}
|
|
204433
|
-
var K512 = /* @__PURE__ */ (() => split([
|
|
204434
|
-
"0x428a2f98d728ae22",
|
|
204435
|
-
"0x7137449123ef65cd",
|
|
204436
|
-
"0xb5c0fbcfec4d3b2f",
|
|
204437
|
-
"0xe9b5dba58189dbbc",
|
|
204438
|
-
"0x3956c25bf348b538",
|
|
204439
|
-
"0x59f111f1b605d019",
|
|
204440
|
-
"0x923f82a4af194f9b",
|
|
204441
|
-
"0xab1c5ed5da6d8118",
|
|
204442
|
-
"0xd807aa98a3030242",
|
|
204443
|
-
"0x12835b0145706fbe",
|
|
204444
|
-
"0x243185be4ee4b28c",
|
|
204445
|
-
"0x550c7dc3d5ffb4e2",
|
|
204446
|
-
"0x72be5d74f27b896f",
|
|
204447
|
-
"0x80deb1fe3b1696b1",
|
|
204448
|
-
"0x9bdc06a725c71235",
|
|
204449
|
-
"0xc19bf174cf692694",
|
|
204450
|
-
"0xe49b69c19ef14ad2",
|
|
204451
|
-
"0xefbe4786384f25e3",
|
|
204452
|
-
"0x0fc19dc68b8cd5b5",
|
|
204453
|
-
"0x240ca1cc77ac9c65",
|
|
204454
|
-
"0x2de92c6f592b0275",
|
|
204455
|
-
"0x4a7484aa6ea6e483",
|
|
204456
|
-
"0x5cb0a9dcbd41fbd4",
|
|
204457
|
-
"0x76f988da831153b5",
|
|
204458
|
-
"0x983e5152ee66dfab",
|
|
204459
|
-
"0xa831c66d2db43210",
|
|
204460
|
-
"0xb00327c898fb213f",
|
|
204461
|
-
"0xbf597fc7beef0ee4",
|
|
204462
|
-
"0xc6e00bf33da88fc2",
|
|
204463
|
-
"0xd5a79147930aa725",
|
|
204464
|
-
"0x06ca6351e003826f",
|
|
204465
|
-
"0x142929670a0e6e70",
|
|
204466
|
-
"0x27b70a8546d22ffc",
|
|
204467
|
-
"0x2e1b21385c26c926",
|
|
204468
|
-
"0x4d2c6dfc5ac42aed",
|
|
204469
|
-
"0x53380d139d95b3df",
|
|
204470
|
-
"0x650a73548baf63de",
|
|
204471
|
-
"0x766a0abb3c77b2a8",
|
|
204472
|
-
"0x81c2c92e47edaee6",
|
|
204473
|
-
"0x92722c851482353b",
|
|
204474
|
-
"0xa2bfe8a14cf10364",
|
|
204475
|
-
"0xa81a664bbc423001",
|
|
204476
|
-
"0xc24b8b70d0f89791",
|
|
204477
|
-
"0xc76c51a30654be30",
|
|
204478
|
-
"0xd192e819d6ef5218",
|
|
204479
|
-
"0xd69906245565a910",
|
|
204480
|
-
"0xf40e35855771202a",
|
|
204481
|
-
"0x106aa07032bbd1b8",
|
|
204482
|
-
"0x19a4c116b8d2d0c8",
|
|
204483
|
-
"0x1e376c085141ab53",
|
|
204484
|
-
"0x2748774cdf8eeb99",
|
|
204485
|
-
"0x34b0bcb5e19b48a8",
|
|
204486
|
-
"0x391c0cb3c5c95a63",
|
|
204487
|
-
"0x4ed8aa4ae3418acb",
|
|
204488
|
-
"0x5b9cca4f7763e373",
|
|
204489
|
-
"0x682e6ff3d6b2b8a3",
|
|
204490
|
-
"0x748f82ee5defb2fc",
|
|
204491
|
-
"0x78a5636f43172f60",
|
|
204492
|
-
"0x84c87814a1f0ab72",
|
|
204493
|
-
"0x8cc702081a6439ec",
|
|
204494
|
-
"0x90befffa23631e28",
|
|
204495
|
-
"0xa4506cebde82bde9",
|
|
204496
|
-
"0xbef9a3f7b2c67915",
|
|
204497
|
-
"0xc67178f2e372532b",
|
|
204498
|
-
"0xca273eceea26619c",
|
|
204499
|
-
"0xd186b8c721c0c207",
|
|
204500
|
-
"0xeada7dd6cde0eb1e",
|
|
204501
|
-
"0xf57d4f7fee6ed178",
|
|
204502
|
-
"0x06f067aa72176fba",
|
|
204503
|
-
"0x0a637dc5a2c898a6",
|
|
204504
|
-
"0x113f9804bef90dae",
|
|
204505
|
-
"0x1b710b35131c471b",
|
|
204506
|
-
"0x28db77f523047d84",
|
|
204507
|
-
"0x32caab7b40c72493",
|
|
204508
|
-
"0x3c9ebe0a15c9bebc",
|
|
204509
|
-
"0x431d67c49c100d4c",
|
|
204510
|
-
"0x4cc5d4becb3e42b6",
|
|
204511
|
-
"0x597f299cfc657e2a",
|
|
204512
|
-
"0x5fcb6fab3ad6faec",
|
|
204513
|
-
"0x6c44198c4a475817"
|
|
204514
|
-
].map((n) => BigInt(n))))();
|
|
204515
|
-
var SHA512_Kh = /* @__PURE__ */ (() => K512[0])();
|
|
204516
|
-
var SHA512_Kl = /* @__PURE__ */ (() => K512[1])();
|
|
204517
|
-
var SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);
|
|
204518
|
-
var SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);
|
|
204519
|
-
|
|
204520
|
-
class SHA2_64B extends HashMD {
|
|
204521
|
-
constructor(outputLen) {
|
|
204522
|
-
super(128, outputLen, 16, false);
|
|
204523
|
-
}
|
|
204524
|
-
get() {
|
|
204525
|
-
const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
|
|
204526
|
-
return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];
|
|
204527
|
-
}
|
|
204528
|
-
set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) {
|
|
204529
|
-
this.Ah = Ah | 0;
|
|
204530
|
-
this.Al = Al | 0;
|
|
204531
|
-
this.Bh = Bh | 0;
|
|
204532
|
-
this.Bl = Bl | 0;
|
|
204533
|
-
this.Ch = Ch | 0;
|
|
204534
|
-
this.Cl = Cl | 0;
|
|
204535
|
-
this.Dh = Dh | 0;
|
|
204536
|
-
this.Dl = Dl | 0;
|
|
204537
|
-
this.Eh = Eh | 0;
|
|
204538
|
-
this.El = El | 0;
|
|
204539
|
-
this.Fh = Fh | 0;
|
|
204540
|
-
this.Fl = Fl | 0;
|
|
204541
|
-
this.Gh = Gh | 0;
|
|
204542
|
-
this.Gl = Gl | 0;
|
|
204543
|
-
this.Hh = Hh | 0;
|
|
204544
|
-
this.Hl = Hl | 0;
|
|
204545
|
-
}
|
|
204546
|
-
process(view, offset) {
|
|
204547
|
-
for (let i = 0;i < 16; i++, offset += 4) {
|
|
204548
|
-
SHA512_W_H[i] = view.getUint32(offset);
|
|
204549
|
-
SHA512_W_L[i] = view.getUint32(offset += 4);
|
|
204550
|
-
}
|
|
204551
|
-
for (let i = 16;i < 80; i++) {
|
|
204552
|
-
const W15h = SHA512_W_H[i - 15] | 0;
|
|
204553
|
-
const W15l = SHA512_W_L[i - 15] | 0;
|
|
204554
|
-
const s0h = rotrSH(W15h, W15l, 1) ^ rotrSH(W15h, W15l, 8) ^ shrSH(W15h, W15l, 7);
|
|
204555
|
-
const s0l = rotrSL(W15h, W15l, 1) ^ rotrSL(W15h, W15l, 8) ^ shrSL(W15h, W15l, 7);
|
|
204556
|
-
const W2h = SHA512_W_H[i - 2] | 0;
|
|
204557
|
-
const W2l = SHA512_W_L[i - 2] | 0;
|
|
204558
|
-
const s1h = rotrSH(W2h, W2l, 19) ^ rotrBH(W2h, W2l, 61) ^ shrSH(W2h, W2l, 6);
|
|
204559
|
-
const s1l = rotrSL(W2h, W2l, 19) ^ rotrBL(W2h, W2l, 61) ^ shrSL(W2h, W2l, 6);
|
|
204560
|
-
const SUMl = add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);
|
|
204561
|
-
const SUMh = add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);
|
|
204562
|
-
SHA512_W_H[i] = SUMh | 0;
|
|
204563
|
-
SHA512_W_L[i] = SUMl | 0;
|
|
204564
|
-
}
|
|
204565
|
-
let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
|
|
204566
|
-
for (let i = 0;i < 80; i++) {
|
|
204567
|
-
const sigma1h = rotrSH(Eh, El, 14) ^ rotrSH(Eh, El, 18) ^ rotrBH(Eh, El, 41);
|
|
204568
|
-
const sigma1l = rotrSL(Eh, El, 14) ^ rotrSL(Eh, El, 18) ^ rotrBL(Eh, El, 41);
|
|
204569
|
-
const CHIh = Eh & Fh ^ ~Eh & Gh;
|
|
204570
|
-
const CHIl = El & Fl ^ ~El & Gl;
|
|
204571
|
-
const T1ll = add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);
|
|
204572
|
-
const T1h = add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);
|
|
204573
|
-
const T1l = T1ll | 0;
|
|
204574
|
-
const sigma0h = rotrSH(Ah, Al, 28) ^ rotrBH(Ah, Al, 34) ^ rotrBH(Ah, Al, 39);
|
|
204575
|
-
const sigma0l = rotrSL(Ah, Al, 28) ^ rotrBL(Ah, Al, 34) ^ rotrBL(Ah, Al, 39);
|
|
204576
|
-
const MAJh = Ah & Bh ^ Ah & Ch ^ Bh & Ch;
|
|
204577
|
-
const MAJl = Al & Bl ^ Al & Cl ^ Bl & Cl;
|
|
204578
|
-
Hh = Gh | 0;
|
|
204579
|
-
Hl = Gl | 0;
|
|
204580
|
-
Gh = Fh | 0;
|
|
204581
|
-
Gl = Fl | 0;
|
|
204582
|
-
Fh = Eh | 0;
|
|
204583
|
-
Fl = El | 0;
|
|
204584
|
-
({ h: Eh, l: El } = add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));
|
|
204585
|
-
Dh = Ch | 0;
|
|
204586
|
-
Dl = Cl | 0;
|
|
204587
|
-
Ch = Bh | 0;
|
|
204588
|
-
Cl = Bl | 0;
|
|
204589
|
-
Bh = Ah | 0;
|
|
204590
|
-
Bl = Al | 0;
|
|
204591
|
-
const All = add3L(T1l, sigma0l, MAJl);
|
|
204592
|
-
Ah = add3H(All, T1h, sigma0h, MAJh);
|
|
204593
|
-
Al = All | 0;
|
|
204594
|
-
}
|
|
204595
|
-
({ h: Ah, l: Al } = add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));
|
|
204596
|
-
({ h: Bh, l: Bl } = add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));
|
|
204597
|
-
({ h: Ch, l: Cl } = add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));
|
|
204598
|
-
({ h: Dh, l: Dl } = add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));
|
|
204599
|
-
({ h: Eh, l: El } = add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));
|
|
204600
|
-
({ h: Fh, l: Fl } = add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));
|
|
204601
|
-
({ h: Gh, l: Gl } = add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));
|
|
204602
|
-
({ h: Hh, l: Hl } = add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));
|
|
204603
|
-
this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
|
|
204604
|
-
}
|
|
204605
|
-
roundClean() {
|
|
204606
|
-
clean(SHA512_W_H, SHA512_W_L);
|
|
204607
|
-
}
|
|
204608
|
-
destroy() {
|
|
204609
|
-
clean(this.buffer);
|
|
204610
|
-
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
|
204611
|
-
}
|
|
204612
|
-
}
|
|
204613
|
-
var T256_IV = /* @__PURE__ */ Uint32Array.from([
|
|
204614
|
-
573645204,
|
|
204615
|
-
4230739756,
|
|
204616
|
-
2673172387,
|
|
204617
|
-
3360449730,
|
|
204618
|
-
596883563,
|
|
204619
|
-
1867755857,
|
|
204620
|
-
2520282905,
|
|
204621
|
-
1497426621,
|
|
204622
|
-
2519219938,
|
|
204623
|
-
2827943907,
|
|
204624
|
-
3193839141,
|
|
204625
|
-
1401305490,
|
|
204626
|
-
721525244,
|
|
204627
|
-
746961066,
|
|
204628
|
-
246885852,
|
|
204629
|
-
2177182882
|
|
204630
|
-
]);
|
|
204631
|
-
class _SHA512_256 extends SHA2_64B {
|
|
204632
|
-
Ah = T256_IV[0] | 0;
|
|
204633
|
-
Al = T256_IV[1] | 0;
|
|
204634
|
-
Bh = T256_IV[2] | 0;
|
|
204635
|
-
Bl = T256_IV[3] | 0;
|
|
204636
|
-
Ch = T256_IV[4] | 0;
|
|
204637
|
-
Cl = T256_IV[5] | 0;
|
|
204638
|
-
Dh = T256_IV[6] | 0;
|
|
204639
|
-
Dl = T256_IV[7] | 0;
|
|
204640
|
-
Eh = T256_IV[8] | 0;
|
|
204641
|
-
El = T256_IV[9] | 0;
|
|
204642
|
-
Fh = T256_IV[10] | 0;
|
|
204643
|
-
Fl = T256_IV[11] | 0;
|
|
204644
|
-
Gh = T256_IV[12] | 0;
|
|
204645
|
-
Gl = T256_IV[13] | 0;
|
|
204646
|
-
Hh = T256_IV[14] | 0;
|
|
204647
|
-
Hl = T256_IV[15] | 0;
|
|
204648
|
-
constructor() {
|
|
204649
|
-
super(32);
|
|
204650
|
-
}
|
|
204651
|
-
}
|
|
204652
|
-
var sha256 = /* @__PURE__ */ createHasher(() => new _SHA256, /* @__PURE__ */ oidNist(1));
|
|
204653
|
-
var sha512_256 = /* @__PURE__ */ createHasher(() => new _SHA512_256, /* @__PURE__ */ oidNist(6));
|
|
204654
|
-
|
|
204655
|
-
// ../verify/src/bytes.ts
|
|
204656
|
-
var hex = (b) => bytesToHex(b);
|
|
204657
|
-
var unhex = (s) => hexToBytes(s.startsWith("0x") ? s.slice(2) : s);
|
|
204658
|
-
var concat = (parts) => concatBytes(...parts);
|
|
204659
|
-
var bytesEqual = (a, b) => {
|
|
204660
|
-
if (a.length !== b.length)
|
|
204661
|
-
return false;
|
|
204662
|
-
for (let i = 0;i < a.length; i++)
|
|
204663
|
-
if (a[i] !== b[i])
|
|
204664
|
-
return false;
|
|
204665
|
-
return true;
|
|
204666
|
-
};
|
|
204667
|
-
var hashAll = (parts) => {
|
|
204668
|
-
const h = sha512_256.create();
|
|
204669
|
-
for (const p of parts)
|
|
204670
|
-
h.update(p);
|
|
204671
|
-
return h.digest();
|
|
204672
|
-
};
|
|
204673
|
-
|
|
204674
|
-
class Reader {
|
|
204675
|
-
buf;
|
|
204676
|
-
pos = 0;
|
|
204677
|
-
constructor(buf) {
|
|
204678
|
-
this.buf = buf;
|
|
204679
|
-
}
|
|
204680
|
-
bytes(n) {
|
|
204681
|
-
if (n < 0 || this.pos + n > this.buf.length)
|
|
204682
|
-
throw new Error(`unexpected end of input at ${this.pos} reading ${n}`);
|
|
204683
|
-
const out = this.buf.subarray(this.pos, this.pos + n);
|
|
204684
|
-
this.pos += n;
|
|
204685
|
-
return out;
|
|
204686
|
-
}
|
|
204687
|
-
view(n) {
|
|
204688
|
-
const b = this.bytes(n);
|
|
204689
|
-
return new DataView(b.buffer, b.byteOffset, n);
|
|
204690
|
-
}
|
|
204691
|
-
u8 = () => this.bytes(1)[0];
|
|
204692
|
-
u16 = () => this.view(2).getUint16(0);
|
|
204693
|
-
u32 = () => this.view(4).getUint32(0);
|
|
204694
|
-
u64 = () => this.view(8).getBigUint64(0);
|
|
204695
|
-
i64 = () => this.view(8).getBigInt64(0);
|
|
204696
|
-
vec(item, max) {
|
|
204697
|
-
const n = this.u32();
|
|
204698
|
-
if (n > max)
|
|
204699
|
-
throw new Error(`vec length ${n} exceeds ${max}`);
|
|
204700
|
-
return Array.from({ length: n }, item);
|
|
204701
|
-
}
|
|
204702
|
-
get done() {
|
|
204703
|
-
return this.pos === this.buf.length;
|
|
204704
|
-
}
|
|
204705
|
-
}
|
|
204706
|
-
// ../verify/src/header.ts
|
|
204707
|
-
var NAKAMOTO_BLOCK_VERSION_EPOCH_4 = 1;
|
|
204708
|
-
var MAX_SIGNERS = 4000;
|
|
204709
|
-
var MAX_PROBLEMATIC_TXS = 1 << 16;
|
|
204710
|
-
function parseNakamotoHeader(raw) {
|
|
204711
|
-
const r = new Reader(raw);
|
|
204712
|
-
const version = r.u8();
|
|
204713
|
-
const chainLength = r.u64();
|
|
204714
|
-
const burnSpent = r.u64();
|
|
204715
|
-
const consensusHash = r.bytes(20);
|
|
204716
|
-
const parentBlockId = r.bytes(32);
|
|
204717
|
-
const txMerkleRoot = r.bytes(32);
|
|
204718
|
-
const stateIndexRoot = r.bytes(32);
|
|
204719
|
-
const timestamp = r.u64();
|
|
204720
|
-
const minerSignature = r.bytes(65);
|
|
204721
|
-
const sigStart = r.pos;
|
|
204722
|
-
const signerSignatures = r.vec(() => r.bytes(65), MAX_SIGNERS);
|
|
204723
|
-
const sigEnd = r.pos;
|
|
204724
|
-
const bits = r.u16();
|
|
204725
|
-
if (bits === 0 || bits > MAX_SIGNERS)
|
|
204726
|
-
throw new Error(`bad pox_treatment length ${bits}`);
|
|
204727
|
-
const bitBytes = Math.ceil(bits / 8);
|
|
204728
|
-
if (r.u32() !== bitBytes)
|
|
204729
|
-
throw new Error("bad pox_treatment data length");
|
|
204730
|
-
r.bytes(bitBytes);
|
|
204731
|
-
if ((version & 127) >= NAKAMOTO_BLOCK_VERSION_EPOCH_4) {
|
|
204732
|
-
r.vec(() => r.bytes(5), MAX_PROBLEMATIC_TXS);
|
|
204733
|
-
}
|
|
204734
|
-
const end = r.pos;
|
|
204735
|
-
return {
|
|
204736
|
-
version,
|
|
204737
|
-
chainLength,
|
|
204738
|
-
burnSpent,
|
|
204739
|
-
consensusHash,
|
|
204740
|
-
parentBlockId,
|
|
204741
|
-
txMerkleRoot,
|
|
204742
|
-
stateIndexRoot,
|
|
204743
|
-
timestamp,
|
|
204744
|
-
minerSignature,
|
|
204745
|
-
signerSignatures,
|
|
204746
|
-
signerSighashPreimage: concat([
|
|
204747
|
-
raw.subarray(0, sigStart),
|
|
204748
|
-
raw.subarray(sigEnd, end)
|
|
204749
|
-
]),
|
|
204750
|
-
byteLength: end
|
|
204751
|
-
};
|
|
204752
|
-
}
|
|
204753
|
-
var signerSignatureHash = (h) => sha512_256(h.signerSighashPreimage);
|
|
204754
|
-
var blockId = (h) => hashAll([signerSignatureHash(h), h.consensusHash]);
|
|
204755
|
-
// ../verify/src/marf.ts
|
|
204756
|
-
var MARF_VALUE_SIZE = 40;
|
|
204757
|
-
var NodeId = {
|
|
204758
|
-
Empty: 0,
|
|
204759
|
-
Leaf: 1,
|
|
204760
|
-
Node4: 2,
|
|
204761
|
-
Node16: 3,
|
|
204762
|
-
Node48: 4,
|
|
204763
|
-
Node256: 5
|
|
204764
|
-
};
|
|
204765
|
-
var NODE_PTR_COUNT = {
|
|
204766
|
-
[NodeId.Node4]: 4,
|
|
204767
|
-
[NodeId.Node16]: 16,
|
|
204768
|
-
[NodeId.Node48]: 48,
|
|
204769
|
-
[NodeId.Node256]: 256
|
|
204770
|
-
};
|
|
204771
|
-
var isBackptr = (id) => (id & 128) !== 0;
|
|
204772
|
-
var marfPath = (key) => sha512_256(new TextEncoder().encode(key));
|
|
204773
|
-
function marfValue(value) {
|
|
204774
|
-
const v = new Uint8Array(MARF_VALUE_SIZE);
|
|
204775
|
-
v.set(sha512_256(new TextEncoder().encode(value)));
|
|
204776
|
-
return v;
|
|
204777
|
-
}
|
|
204778
|
-
function pathPreimage(path) {
|
|
204779
|
-
if (path.length > 32)
|
|
204780
|
-
throw new Error("trie path longer than 32 bytes");
|
|
204781
|
-
return concat([Uint8Array.of(path.length), path]);
|
|
204782
|
-
}
|
|
204783
|
-
var leafHash = (path, value) => hashAll([Uint8Array.of(NodeId.Leaf), pathPreimage(path), value]);
|
|
204784
|
-
function nodeHash(node, children) {
|
|
204785
|
-
const parts = [Uint8Array.of(node.id)];
|
|
204786
|
-
for (const p of node.ptrs)
|
|
204787
|
-
parts.push(Uint8Array.of(p.id, p.chr), p.backBlock);
|
|
204788
|
-
parts.push(pathPreimage(node.path), ...children);
|
|
204789
|
-
return hashAll(parts);
|
|
204790
|
-
}
|
|
204791
|
-
var PROOF_KIND = [
|
|
204792
|
-
"Node4",
|
|
204793
|
-
"Node16",
|
|
204794
|
-
"Node48",
|
|
204795
|
-
"Node256",
|
|
204796
|
-
"Leaf",
|
|
204797
|
-
"Shunt"
|
|
204798
|
-
];
|
|
204799
|
-
var KIND_PTRS = {
|
|
204800
|
-
Node4: 4,
|
|
204801
|
-
Node16: 16,
|
|
204802
|
-
Node48: 48,
|
|
204803
|
-
Node256: 256
|
|
204804
|
-
};
|
|
204805
|
-
function decodeProof(bytes) {
|
|
204806
|
-
const r = new Reader(bytes);
|
|
204807
|
-
const hash = () => r.bytes(32);
|
|
204808
|
-
const steps = r.vec(() => {
|
|
204809
|
-
const kind = PROOF_KIND[r.u8()];
|
|
204810
|
-
if (!kind)
|
|
204811
|
-
throw new Error("bad proof step type");
|
|
204812
|
-
if (kind === "Shunt")
|
|
204813
|
-
return { kind, idx: r.i64(), hashes: r.vec(hash, 1 << 20) };
|
|
204814
|
-
const chr = r.u8();
|
|
204815
|
-
if (kind === "Leaf")
|
|
204816
|
-
return {
|
|
204817
|
-
kind,
|
|
204818
|
-
chr,
|
|
204819
|
-
path: r.bytes(r.u32()),
|
|
204820
|
-
value: r.bytes(MARF_VALUE_SIZE)
|
|
204821
|
-
};
|
|
204822
|
-
const node = {
|
|
204823
|
-
id: r.u8(),
|
|
204824
|
-
path: r.bytes(r.u32()),
|
|
204825
|
-
ptrs: r.vec(() => ({ id: r.u8(), chr: r.u8(), backBlock: r.bytes(32) }), 256)
|
|
204826
|
-
};
|
|
204827
|
-
const hashes = Array.from({ length: KIND_PTRS[kind] - 1 }, hash);
|
|
204828
|
-
return { kind, chr, node, hashes };
|
|
204829
|
-
}, 1 << 20);
|
|
204830
|
-
if (!r.done)
|
|
204831
|
-
throw new Error("trailing bytes after proof");
|
|
204832
|
-
return steps;
|
|
204833
|
-
}
|
|
204834
|
-
var isShunt = (s) => s?.kind === "Shunt";
|
|
204835
|
-
var segmentEnd = (p, i) => {
|
|
204836
|
-
let j = i + 1;
|
|
204837
|
-
while (j < p.length && !isShunt(p[j]))
|
|
204838
|
-
j++;
|
|
204839
|
-
return j;
|
|
204840
|
-
};
|
|
204841
|
-
function segmentProofHash(step, childHash) {
|
|
204842
|
-
const count = KIND_PTRS[step.kind];
|
|
204843
|
-
if (step.node.ptrs.length !== count)
|
|
204844
|
-
return null;
|
|
204845
|
-
const all = [];
|
|
204846
|
-
let ih = 0;
|
|
204847
|
-
for (const p of step.node.ptrs) {
|
|
204848
|
-
if (p.id !== NodeId.Empty && p.chr === step.chr)
|
|
204849
|
-
all.push(childHash);
|
|
204850
|
-
else {
|
|
204851
|
-
const h = step.hashes[ih++];
|
|
204852
|
-
if (!h)
|
|
204853
|
-
return null;
|
|
204854
|
-
all.push(h);
|
|
204855
|
-
}
|
|
204856
|
-
}
|
|
204857
|
-
return all.length === count ? nodeHash(step.node, all) : null;
|
|
204858
|
-
}
|
|
204859
|
-
function verifySegment(seg, start) {
|
|
204860
|
-
let h = start;
|
|
204861
|
-
for (const s of seg) {
|
|
204862
|
-
if (s.kind === "Shunt" || !h)
|
|
204863
|
-
return null;
|
|
204864
|
-
h = s.kind === "Leaf" ? leafHash(s.path, s.value) : segmentProofHash(s, h);
|
|
204865
|
-
}
|
|
204866
|
-
return h;
|
|
204867
|
-
}
|
|
204868
|
-
function segmentPathPrefix(seg) {
|
|
204869
|
-
const parts = [];
|
|
204870
|
-
for (const s of seg) {
|
|
204871
|
-
if (s.kind === "Shunt")
|
|
204872
|
-
return null;
|
|
204873
|
-
if (s.kind === "Leaf")
|
|
204874
|
-
parts.push(s.path);
|
|
204875
|
-
else
|
|
204876
|
-
parts.push(Uint8Array.of(s.chr), s.node.path);
|
|
204877
|
-
}
|
|
204878
|
-
return concat(parts.reverse());
|
|
204879
|
-
}
|
|
204880
|
-
function isWellFormed(p, expectedPath) {
|
|
204881
|
-
if (p[0]?.kind !== "Leaf")
|
|
204882
|
-
return false;
|
|
204883
|
-
let i = 0;
|
|
204884
|
-
let path = new Uint8Array;
|
|
204885
|
-
while (i < p.length) {
|
|
204886
|
-
const j = segmentEnd(p, i);
|
|
204887
|
-
const prefix = segmentPathPrefix(p.slice(i, j));
|
|
204888
|
-
if (!prefix)
|
|
204889
|
-
return false;
|
|
204890
|
-
if (i === 0) {
|
|
204891
|
-
if (!bytesEqual(prefix, expectedPath))
|
|
204892
|
-
return false;
|
|
204893
|
-
path = prefix;
|
|
204894
|
-
} else if (prefix.length > path.length || !bytesEqual(path.subarray(0, prefix.length), prefix))
|
|
204895
|
-
return false;
|
|
204896
|
-
i = j;
|
|
204897
|
-
if (i >= p.length)
|
|
204898
|
-
return false;
|
|
204899
|
-
let k = i + 1;
|
|
204900
|
-
while (k < p.length && isShunt(p[k]))
|
|
204901
|
-
k++;
|
|
204902
|
-
i = k;
|
|
204903
|
-
}
|
|
204904
|
-
return true;
|
|
204905
|
-
}
|
|
204906
|
-
function shuntHash(lead, idx, inserted, hashes) {
|
|
204907
|
-
if (idx === 0n)
|
|
204908
|
-
return null;
|
|
204909
|
-
const all = lead ? [lead] : [];
|
|
204910
|
-
let hi = 0;
|
|
204911
|
-
for (let i = 0;i < hashes.length + 1; i++) {
|
|
204912
|
-
if (idx - 1n === BigInt(i))
|
|
204913
|
-
all.push(inserted);
|
|
204914
|
-
else {
|
|
204915
|
-
const h = hashes[hi++];
|
|
204916
|
-
if (!h)
|
|
204917
|
-
return null;
|
|
204918
|
-
all.push(h);
|
|
204919
|
-
}
|
|
204920
|
-
}
|
|
204921
|
-
return hashAll(all);
|
|
204922
|
-
}
|
|
204923
|
-
function verifySteps(proof, path, value, root, rootToBlock) {
|
|
204924
|
-
if (!isWellFormed(proof, path))
|
|
204925
|
-
return false;
|
|
204926
|
-
const first = proof[0];
|
|
204927
|
-
if (first?.kind !== "Leaf" || !bytesEqual(first.value, value))
|
|
204928
|
-
return false;
|
|
204929
|
-
let i = 0;
|
|
204930
|
-
let j = segmentEnd(proof, i);
|
|
204931
|
-
const nodeRoot = verifySegment(proof.slice(i, j), leafHash(first.path, first.value));
|
|
204932
|
-
if (!nodeRoot)
|
|
204933
|
-
return false;
|
|
204934
|
-
i = j;
|
|
204935
|
-
const head = proof[i];
|
|
204936
|
-
if (!isShunt(head) || head.idx !== 0n)
|
|
204937
|
-
return false;
|
|
204938
|
-
let trieHash = head.hashes.length === 0 ? nodeRoot : hashAll([nodeRoot, ...head.hashes]);
|
|
204939
|
-
i += 1;
|
|
204940
|
-
if (i >= proof.length)
|
|
204941
|
-
return bytesEqual(root, trieHash);
|
|
204942
|
-
let backBlock = rootToBlock.get(hex(trieHash));
|
|
204943
|
-
if (!backBlock || isShunt(proof[i]))
|
|
204944
|
-
return false;
|
|
204945
|
-
while (i < proof.length) {
|
|
204946
|
-
j = segmentEnd(proof, i);
|
|
204947
|
-
const nextNodeRoot = verifySegment(proof.slice(i, j), backBlock);
|
|
204948
|
-
if (!nextNodeRoot)
|
|
204949
|
-
return false;
|
|
204950
|
-
i = j;
|
|
204951
|
-
if (i >= proof.length)
|
|
204952
|
-
return false;
|
|
204953
|
-
j = i;
|
|
204954
|
-
while (j < proof.length) {
|
|
204955
|
-
const s = proof[j];
|
|
204956
|
-
if (!isShunt(s) || s.idx === 0n)
|
|
204957
|
-
break;
|
|
204958
|
-
j++;
|
|
204959
|
-
}
|
|
204960
|
-
j -= 1;
|
|
204961
|
-
if (j < i)
|
|
204962
|
-
return false;
|
|
204963
|
-
let penultimate = trieHash;
|
|
204964
|
-
for (const s of proof.slice(i, j)) {
|
|
204965
|
-
if (!isShunt(s))
|
|
204966
|
-
return false;
|
|
204967
|
-
const h = shuntHash(null, s.idx, penultimate, s.hashes);
|
|
204968
|
-
if (!h)
|
|
204969
|
-
return false;
|
|
204970
|
-
penultimate = h;
|
|
204971
|
-
}
|
|
204972
|
-
const junction = proof[j];
|
|
204973
|
-
if (!isShunt(junction))
|
|
204974
|
-
return false;
|
|
204975
|
-
const next = shuntHash(nextNodeRoot, junction.idx, penultimate, junction.hashes);
|
|
204976
|
-
if (!next)
|
|
204977
|
-
return false;
|
|
204978
|
-
trieHash = next;
|
|
204979
|
-
backBlock = rootToBlock.get(hex(trieHash));
|
|
204980
|
-
if (!backBlock)
|
|
204981
|
-
return false;
|
|
204982
|
-
i = j + 1;
|
|
204983
|
-
if (bytesEqual(trieHash, root))
|
|
204984
|
-
break;
|
|
204985
|
-
}
|
|
204986
|
-
return bytesEqual(root, trieHash);
|
|
204987
|
-
}
|
|
204988
|
-
function marfProofAncestors(proof) {
|
|
204989
|
-
let steps;
|
|
204990
|
-
try {
|
|
204991
|
-
steps = decodeProof(proof);
|
|
204992
|
-
} catch {
|
|
204993
|
-
return [];
|
|
204994
|
-
}
|
|
204995
|
-
const ids = new Set;
|
|
204996
|
-
for (const s of steps) {
|
|
204997
|
-
if (s.kind === "Leaf" || s.kind === "Shunt")
|
|
204998
|
-
continue;
|
|
204999
|
-
const ptr = s.node.ptrs.find((p) => p.id !== NodeId.Empty && p.chr === s.chr);
|
|
205000
|
-
if (ptr && isBackptr(ptr.id))
|
|
205001
|
-
ids.add(hex(ptr.backBlock));
|
|
205002
|
-
}
|
|
205003
|
-
return [...ids];
|
|
205004
|
-
}
|
|
205005
|
-
function verifyMarfProof(input) {
|
|
205006
|
-
const rootToBlock = new Map;
|
|
205007
|
-
for (const h of input.headers)
|
|
205008
|
-
rootToBlock.set(hex(h.stateIndexRoot), blockId(h));
|
|
205009
|
-
try {
|
|
205010
|
-
const steps = decodeProof(input.proof);
|
|
205011
|
-
return verifySteps(steps, input.path, input.value, input.root, rootToBlock);
|
|
205012
|
-
} catch {
|
|
205013
|
-
return false;
|
|
205014
|
-
}
|
|
205015
|
-
}
|
|
205016
|
-
// ../verify/src/witness.ts
|
|
205017
|
-
var WITNESS_VERSION = 3;
|
|
205018
|
-
var PATH_LEN = 32;
|
|
205019
|
-
var TRIE_HASH_EMPTY = unhex("c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a");
|
|
205020
|
-
var ZERO_BLOCK = new Uint8Array(32);
|
|
205021
|
-
function parseWitness(bytes) {
|
|
205022
|
-
const r = new Reader(bytes);
|
|
205023
|
-
const version = r.u8();
|
|
205024
|
-
if (version !== WITNESS_VERSION)
|
|
205025
|
-
throw new Error(`unsupported witness version ${version}`);
|
|
205026
|
-
const ancestorRoots = Array.from({ length: r.u32() }, () => r.bytes(32));
|
|
205027
|
-
const blockTable = Array.from({ length: r.u32() }, () => r.bytes(32));
|
|
205028
|
-
const leaves = [];
|
|
205029
|
-
const seen = new Set;
|
|
205030
|
-
let nodes = 0;
|
|
205031
|
-
const readNode = (prefix, expectedId) => {
|
|
205032
|
-
nodes++;
|
|
205033
|
-
const id = r.u8();
|
|
205034
|
-
if (expectedId !== null && id !== expectedId)
|
|
205035
|
-
throw new Error(`child id ${id} does not match its pointer id ${expectedId}`);
|
|
205036
|
-
const path = r.bytes(r.u8());
|
|
205037
|
-
const depth = prefix.length + path.length;
|
|
205038
|
-
if (id === NodeId.Leaf) {
|
|
205039
|
-
if (depth !== PATH_LEN)
|
|
205040
|
-
throw new Error("leaf path does not complete 32 bytes");
|
|
205041
|
-
const valueHash = r.bytes(32);
|
|
205042
|
-
const full = Uint8Array.from([...prefix, ...path]);
|
|
205043
|
-
const key = hex(full);
|
|
205044
|
-
if (seen.has(key))
|
|
205045
|
-
throw new Error(`duplicate leaf ${key}`);
|
|
205046
|
-
seen.add(key);
|
|
205047
|
-
leaves.push({ path: full, valueHash });
|
|
205048
|
-
return leafHash(path, padValue(valueHash));
|
|
205049
|
-
}
|
|
205050
|
-
const count = NODE_PTR_COUNT[id];
|
|
205051
|
-
if (count === undefined)
|
|
205052
|
-
throw new Error(`bad node id ${id}`);
|
|
205053
|
-
if (depth >= PATH_LEN)
|
|
205054
|
-
throw new Error("interior node at full path depth");
|
|
205055
|
-
const n = r.u16();
|
|
205056
|
-
if (n !== count)
|
|
205057
|
-
throw new Error(`node id ${id} has ${n} ptrs, expected ${count}`);
|
|
205058
|
-
const ptrs = [];
|
|
205059
|
-
for (let i = 0;i < n; i++) {
|
|
205060
|
-
const pid = r.u8();
|
|
205061
|
-
if (pid === NodeId.Empty) {
|
|
205062
|
-
ptrs.push({ id: pid, chr: 0, backBlock: ZERO_BLOCK });
|
|
205063
|
-
continue;
|
|
205064
|
-
}
|
|
205065
|
-
const chr = r.u8();
|
|
205066
|
-
if (!isBackptr(pid)) {
|
|
205067
|
-
ptrs.push({ id: pid, chr, backBlock: ZERO_BLOCK });
|
|
205068
|
-
continue;
|
|
205069
|
-
}
|
|
205070
|
-
const block = blockTable[r.u32()];
|
|
205071
|
-
if (!block)
|
|
205072
|
-
throw new Error("backptr table index out of range");
|
|
205073
|
-
ptrs.push({ id: pid, chr, backBlock: block });
|
|
205074
|
-
}
|
|
205075
|
-
const childPrefix = [...prefix, ...path];
|
|
205076
|
-
const children = ptrs.map((p) => {
|
|
205077
|
-
if (p.id === NodeId.Empty)
|
|
205078
|
-
return TRIE_HASH_EMPTY;
|
|
205079
|
-
if (isBackptr(p.id))
|
|
205080
|
-
return p.backBlock;
|
|
205081
|
-
return readNode([...childPrefix, p.chr], p.id);
|
|
205082
|
-
});
|
|
205083
|
-
return nodeHash({ id, path, ptrs }, children);
|
|
205084
|
-
};
|
|
205085
|
-
const nodeRoot = readNode([], null);
|
|
205086
|
-
if (!r.done)
|
|
205087
|
-
throw new Error("trailing bytes after witness");
|
|
205088
|
-
const root = ancestorRoots.length === 0 ? nodeRoot : hashAll([nodeRoot, ...ancestorRoots]);
|
|
205089
|
-
return { root, ancestorRoots, leaves, nodes };
|
|
205090
|
-
}
|
|
205091
|
-
var padValue = (valueHash) => {
|
|
205092
|
-
const v = new Uint8Array(MARF_VALUE_SIZE);
|
|
205093
|
-
v.set(valueHash);
|
|
205094
|
-
return v;
|
|
205095
|
-
};
|
|
205096
|
-
var leafHolds = (leaf, value) => value.length === MARF_VALUE_SIZE && bytesEqual(padValue(leaf.valueHash), value);
|
|
205097
|
-
var INTERNAL_PREFIX = "__MARF_";
|
|
205098
|
-
function classifyBlockDiff(input) {
|
|
205099
|
-
const writes = indexClaims(input.writes, (v) => marfValue(v));
|
|
205100
|
-
const internal = indexClaims(input.internal, (v) => {
|
|
205101
|
-
const value = unhex(v);
|
|
205102
|
-
if (value.length !== MARF_VALUE_SIZE)
|
|
205103
|
-
throw new Error(`internal value must be ${MARF_VALUE_SIZE} bytes`);
|
|
205104
|
-
return value;
|
|
205105
|
-
});
|
|
205106
|
-
for (const { key } of internal.values())
|
|
205107
|
-
if (!key.startsWith(INTERNAL_PREFIX))
|
|
205108
|
-
throw new Error(`internal key must start with ${INTERNAL_PREFIX}: ${key}`);
|
|
205109
|
-
const out = {
|
|
205110
|
-
writes: [],
|
|
205111
|
-
carried: [],
|
|
205112
|
-
internal: [],
|
|
205113
|
-
hidden: [],
|
|
205114
|
-
missing: [],
|
|
205115
|
-
complete: false
|
|
205116
|
-
};
|
|
205117
|
-
const matched = new Set;
|
|
205118
|
-
for (const leaf of input.leaves) {
|
|
205119
|
-
const pathHex = hex(leaf.path);
|
|
205120
|
-
const write = writes.get(pathHex);
|
|
205121
|
-
if (write && leafHolds(leaf, write.value)) {
|
|
205122
|
-
out.writes.push({ ...leaf, key: write.key });
|
|
205123
|
-
matched.add(pathHex);
|
|
205124
|
-
continue;
|
|
205125
|
-
}
|
|
205126
|
-
const bookkeeping = internal.get(pathHex);
|
|
205127
|
-
if (bookkeeping && leafHolds(leaf, bookkeeping.value)) {
|
|
205128
|
-
out.internal.push({ ...leaf, key: bookkeeping.key });
|
|
205129
|
-
continue;
|
|
205130
|
-
}
|
|
205131
|
-
const parent = write ? undefined : input.parentValue(pathHex);
|
|
205132
|
-
if (parent !== undefined && leafHolds(leaf, unhex(parent)))
|
|
205133
|
-
out.carried.push(leaf);
|
|
205134
|
-
else
|
|
205135
|
-
out.hidden.push(leaf);
|
|
205136
|
-
}
|
|
205137
|
-
for (const [pathHex, { key }] of writes)
|
|
205138
|
-
if (!matched.has(pathHex))
|
|
205139
|
-
out.missing.push(key);
|
|
205140
|
-
out.complete = out.hidden.length === 0 && out.missing.length === 0;
|
|
205141
|
-
return out;
|
|
205142
|
-
}
|
|
205143
|
-
function indexClaims(claims, toValue) {
|
|
205144
|
-
const byPath = new Map;
|
|
205145
|
-
for (const [key, value] of claims) {
|
|
205146
|
-
const pathHex = hex(marfPath(key));
|
|
205147
|
-
if (byPath.has(pathHex))
|
|
205148
|
-
throw new Error(`duplicate claimed key ${key}`);
|
|
205149
|
-
byPath.set(pathHex, { key, value: toValue(value) });
|
|
205150
|
-
}
|
|
205151
|
-
return byPath;
|
|
205152
|
-
}
|
|
205153
|
-
// ../../node_modules/@noble/curves/utils.js
|
|
205154
|
-
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
205155
|
-
var _0n = /* @__PURE__ */ BigInt(0);
|
|
205156
|
-
var _1n = /* @__PURE__ */ BigInt(1);
|
|
205157
|
-
function abool(value, title = "") {
|
|
205158
|
-
if (typeof value !== "boolean") {
|
|
205159
|
-
const prefix = title && `"${title}" `;
|
|
205160
|
-
throw new Error(prefix + "expected boolean, got type=" + typeof value);
|
|
205161
|
-
}
|
|
205162
|
-
return value;
|
|
205163
|
-
}
|
|
205164
|
-
function abignumber(n) {
|
|
205165
|
-
if (typeof n === "bigint") {
|
|
205166
|
-
if (!isPosBig(n))
|
|
205167
|
-
throw new Error("positive bigint expected, got " + n);
|
|
205168
|
-
} else
|
|
205169
|
-
anumber(n);
|
|
205170
|
-
return n;
|
|
205171
|
-
}
|
|
205172
|
-
function numberToHexUnpadded(num) {
|
|
205173
|
-
const hex = abignumber(num).toString(16);
|
|
205174
|
-
return hex.length & 1 ? "0" + hex : hex;
|
|
205175
|
-
}
|
|
205176
|
-
function hexToNumber(hex) {
|
|
205177
|
-
if (typeof hex !== "string")
|
|
205178
|
-
throw new Error("hex string expected, got " + typeof hex);
|
|
205179
|
-
return hex === "" ? _0n : BigInt("0x" + hex);
|
|
205180
|
-
}
|
|
205181
|
-
function bytesToNumberBE(bytes) {
|
|
205182
|
-
return hexToNumber(bytesToHex(bytes));
|
|
205183
|
-
}
|
|
205184
|
-
function bytesToNumberLE(bytes) {
|
|
205185
|
-
return hexToNumber(bytesToHex(copyBytes(abytes(bytes)).reverse()));
|
|
205186
|
-
}
|
|
205187
|
-
function numberToBytesBE(n, len) {
|
|
205188
|
-
anumber(len);
|
|
205189
|
-
n = abignumber(n);
|
|
205190
|
-
const res = hexToBytes(n.toString(16).padStart(len * 2, "0"));
|
|
205191
|
-
if (res.length !== len)
|
|
205192
|
-
throw new Error("number too large");
|
|
205193
|
-
return res;
|
|
205194
|
-
}
|
|
205195
|
-
function numberToBytesLE(n, len) {
|
|
205196
|
-
return numberToBytesBE(n, len).reverse();
|
|
205197
|
-
}
|
|
205198
|
-
function copyBytes(bytes) {
|
|
205199
|
-
return Uint8Array.from(bytes);
|
|
205200
|
-
}
|
|
205201
|
-
function asciiToBytes(ascii) {
|
|
205202
|
-
return Uint8Array.from(ascii, (c, i) => {
|
|
205203
|
-
const charCode = c.charCodeAt(0);
|
|
205204
|
-
if (c.length !== 1 || charCode > 127) {
|
|
205205
|
-
throw new Error(`string contains non-ASCII character "${ascii[i]}" with code ${charCode} at position ${i}`);
|
|
205206
|
-
}
|
|
205207
|
-
return charCode;
|
|
205208
|
-
});
|
|
205209
|
-
}
|
|
205210
|
-
var isPosBig = (n) => typeof n === "bigint" && _0n <= n;
|
|
205211
|
-
function inRange(n, min, max) {
|
|
205212
|
-
return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;
|
|
205213
|
-
}
|
|
205214
|
-
function aInRange(title, n, min, max) {
|
|
205215
|
-
if (!inRange(n, min, max))
|
|
205216
|
-
throw new Error("expected valid " + title + ": " + min + " <= n < " + max + ", got " + n);
|
|
205217
|
-
}
|
|
205218
|
-
function bitLen(n) {
|
|
205219
|
-
let len;
|
|
205220
|
-
for (len = 0;n > _0n; n >>= _1n, len += 1)
|
|
205221
|
-
;
|
|
205222
|
-
return len;
|
|
205223
|
-
}
|
|
205224
|
-
var bitMask = (n) => (_1n << BigInt(n)) - _1n;
|
|
205225
|
-
function createHmacDrbg(hashLen, qByteLen, hmacFn) {
|
|
205226
|
-
anumber(hashLen, "hashLen");
|
|
205227
|
-
anumber(qByteLen, "qByteLen");
|
|
205228
|
-
if (typeof hmacFn !== "function")
|
|
205229
|
-
throw new Error("hmacFn must be a function");
|
|
205230
|
-
const u8n = (len) => new Uint8Array(len);
|
|
205231
|
-
const NULL = Uint8Array.of();
|
|
205232
|
-
const byte0 = Uint8Array.of(0);
|
|
205233
|
-
const byte1 = Uint8Array.of(1);
|
|
205234
|
-
const _maxDrbgIters = 1000;
|
|
205235
|
-
let v = u8n(hashLen);
|
|
205236
|
-
let k = u8n(hashLen);
|
|
205237
|
-
let i = 0;
|
|
205238
|
-
const reset = () => {
|
|
205239
|
-
v.fill(1);
|
|
205240
|
-
k.fill(0);
|
|
205241
|
-
i = 0;
|
|
205242
|
-
};
|
|
205243
|
-
const h = (...msgs) => hmacFn(k, concatBytes(v, ...msgs));
|
|
205244
|
-
const reseed = (seed = NULL) => {
|
|
205245
|
-
k = h(byte0, seed);
|
|
205246
|
-
v = h();
|
|
205247
|
-
if (seed.length === 0)
|
|
205248
|
-
return;
|
|
205249
|
-
k = h(byte1, seed);
|
|
205250
|
-
v = h();
|
|
205251
|
-
};
|
|
205252
|
-
const gen = () => {
|
|
205253
|
-
if (i++ >= _maxDrbgIters)
|
|
205254
|
-
throw new Error("drbg: tried max amount of iterations");
|
|
205255
|
-
let len = 0;
|
|
205256
|
-
const out = [];
|
|
205257
|
-
while (len < qByteLen) {
|
|
205258
|
-
v = h();
|
|
205259
|
-
const sl = v.slice();
|
|
205260
|
-
out.push(sl);
|
|
205261
|
-
len += v.length;
|
|
205262
|
-
}
|
|
205263
|
-
return concatBytes(...out);
|
|
205264
|
-
};
|
|
205265
|
-
const genUntil = (seed, pred) => {
|
|
205266
|
-
reset();
|
|
205267
|
-
reseed(seed);
|
|
205268
|
-
let res = undefined;
|
|
205269
|
-
while (!(res = pred(gen())))
|
|
205270
|
-
reseed();
|
|
205271
|
-
reset();
|
|
205272
|
-
return res;
|
|
205273
|
-
};
|
|
205274
|
-
return genUntil;
|
|
205275
|
-
}
|
|
205276
|
-
function validateObject(object, fields = {}, optFields = {}) {
|
|
205277
|
-
if (!object || typeof object !== "object")
|
|
205278
|
-
throw new Error("expected valid options object");
|
|
205279
|
-
function checkField(fieldName, expectedType, isOpt) {
|
|
205280
|
-
const val = object[fieldName];
|
|
205281
|
-
if (isOpt && val === undefined)
|
|
205282
|
-
return;
|
|
205283
|
-
const current = typeof val;
|
|
205284
|
-
if (current !== expectedType || val === null)
|
|
205285
|
-
throw new Error(`param "${fieldName}" is invalid: expected ${expectedType}, got ${current}`);
|
|
205286
|
-
}
|
|
205287
|
-
const iter = (f, isOpt) => Object.entries(f).forEach(([k, v]) => checkField(k, v, isOpt));
|
|
205288
|
-
iter(fields, false);
|
|
205289
|
-
iter(optFields, true);
|
|
205290
|
-
}
|
|
205291
|
-
function memoized(fn) {
|
|
205292
|
-
const map = new WeakMap;
|
|
205293
|
-
return (arg, ...args) => {
|
|
205294
|
-
const val = map.get(arg);
|
|
205295
|
-
if (val !== undefined)
|
|
205296
|
-
return val;
|
|
205297
|
-
const computed = fn(arg, ...args);
|
|
205298
|
-
map.set(arg, computed);
|
|
205299
|
-
return computed;
|
|
205300
|
-
};
|
|
205301
|
-
}
|
|
205302
|
-
|
|
205303
|
-
// ../../node_modules/@noble/curves/abstract/modular.js
|
|
205304
|
-
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
205305
|
-
var _0n2 = /* @__PURE__ */ BigInt(0);
|
|
205306
|
-
var _1n2 = /* @__PURE__ */ BigInt(1);
|
|
205307
|
-
var _2n = /* @__PURE__ */ BigInt(2);
|
|
205308
|
-
var _3n = /* @__PURE__ */ BigInt(3);
|
|
205309
|
-
var _4n = /* @__PURE__ */ BigInt(4);
|
|
205310
|
-
var _5n = /* @__PURE__ */ BigInt(5);
|
|
205311
|
-
var _7n = /* @__PURE__ */ BigInt(7);
|
|
205312
|
-
var _8n = /* @__PURE__ */ BigInt(8);
|
|
205313
|
-
var _9n = /* @__PURE__ */ BigInt(9);
|
|
205314
|
-
var _16n = /* @__PURE__ */ BigInt(16);
|
|
205315
|
-
function mod(a, b) {
|
|
205316
|
-
const result = a % b;
|
|
205317
|
-
return result >= _0n2 ? result : b + result;
|
|
205318
|
-
}
|
|
205319
|
-
function pow2(x, power, modulo) {
|
|
205320
|
-
let res = x;
|
|
205321
|
-
while (power-- > _0n2) {
|
|
205322
|
-
res *= res;
|
|
205323
|
-
res %= modulo;
|
|
205324
|
-
}
|
|
205325
|
-
return res;
|
|
205326
|
-
}
|
|
205327
|
-
function invert(number, modulo) {
|
|
205328
|
-
if (number === _0n2)
|
|
205329
|
-
throw new Error("invert: expected non-zero number");
|
|
205330
|
-
if (modulo <= _0n2)
|
|
205331
|
-
throw new Error("invert: expected positive modulus, got " + modulo);
|
|
205332
|
-
let a = mod(number, modulo);
|
|
205333
|
-
let b = modulo;
|
|
205334
|
-
let x = _0n2, y = _1n2, u = _1n2, v = _0n2;
|
|
205335
|
-
while (a !== _0n2) {
|
|
205336
|
-
const q = b / a;
|
|
205337
|
-
const r = b % a;
|
|
205338
|
-
const m = x - u * q;
|
|
205339
|
-
const n = y - v * q;
|
|
205340
|
-
b = a, a = r, x = u, y = v, u = m, v = n;
|
|
205341
|
-
}
|
|
205342
|
-
const gcd = b;
|
|
205343
|
-
if (gcd !== _1n2)
|
|
205344
|
-
throw new Error("invert: does not exist");
|
|
205345
|
-
return mod(x, modulo);
|
|
205346
|
-
}
|
|
205347
|
-
function assertIsSquare(Fp, root, n) {
|
|
205348
|
-
if (!Fp.eql(Fp.sqr(root), n))
|
|
205349
|
-
throw new Error("Cannot find square root");
|
|
205350
|
-
}
|
|
205351
|
-
function sqrt3mod4(Fp, n) {
|
|
205352
|
-
const p1div4 = (Fp.ORDER + _1n2) / _4n;
|
|
205353
|
-
const root = Fp.pow(n, p1div4);
|
|
205354
|
-
assertIsSquare(Fp, root, n);
|
|
205355
|
-
return root;
|
|
205356
|
-
}
|
|
205357
|
-
function sqrt5mod8(Fp, n) {
|
|
205358
|
-
const p5div8 = (Fp.ORDER - _5n) / _8n;
|
|
205359
|
-
const n2 = Fp.mul(n, _2n);
|
|
205360
|
-
const v = Fp.pow(n2, p5div8);
|
|
205361
|
-
const nv = Fp.mul(n, v);
|
|
205362
|
-
const i = Fp.mul(Fp.mul(nv, _2n), v);
|
|
205363
|
-
const root = Fp.mul(nv, Fp.sub(i, Fp.ONE));
|
|
205364
|
-
assertIsSquare(Fp, root, n);
|
|
205365
|
-
return root;
|
|
205366
|
-
}
|
|
205367
|
-
function sqrt9mod16(P) {
|
|
205368
|
-
const Fp_ = Field(P);
|
|
205369
|
-
const tn = tonelliShanks(P);
|
|
205370
|
-
const c1 = tn(Fp_, Fp_.neg(Fp_.ONE));
|
|
205371
|
-
const c2 = tn(Fp_, c1);
|
|
205372
|
-
const c3 = tn(Fp_, Fp_.neg(c1));
|
|
205373
|
-
const c4 = (P + _7n) / _16n;
|
|
205374
|
-
return (Fp, n) => {
|
|
205375
|
-
let tv1 = Fp.pow(n, c4);
|
|
205376
|
-
let tv2 = Fp.mul(tv1, c1);
|
|
205377
|
-
const tv3 = Fp.mul(tv1, c2);
|
|
205378
|
-
const tv4 = Fp.mul(tv1, c3);
|
|
205379
|
-
const e1 = Fp.eql(Fp.sqr(tv2), n);
|
|
205380
|
-
const e2 = Fp.eql(Fp.sqr(tv3), n);
|
|
205381
|
-
tv1 = Fp.cmov(tv1, tv2, e1);
|
|
205382
|
-
tv2 = Fp.cmov(tv4, tv3, e2);
|
|
205383
|
-
const e3 = Fp.eql(Fp.sqr(tv2), n);
|
|
205384
|
-
const root = Fp.cmov(tv1, tv2, e3);
|
|
205385
|
-
assertIsSquare(Fp, root, n);
|
|
205386
|
-
return root;
|
|
205387
|
-
};
|
|
205388
|
-
}
|
|
205389
|
-
function tonelliShanks(P) {
|
|
205390
|
-
if (P < _3n)
|
|
205391
|
-
throw new Error("sqrt is not defined for small field");
|
|
205392
|
-
let Q = P - _1n2;
|
|
205393
|
-
let S = 0;
|
|
205394
|
-
while (Q % _2n === _0n2) {
|
|
205395
|
-
Q /= _2n;
|
|
205396
|
-
S++;
|
|
205397
|
-
}
|
|
205398
|
-
let Z = _2n;
|
|
205399
|
-
const _Fp = Field(P);
|
|
205400
|
-
while (FpLegendre(_Fp, Z) === 1) {
|
|
205401
|
-
if (Z++ > 1000)
|
|
205402
|
-
throw new Error("Cannot find square root: probably non-prime P");
|
|
205403
|
-
}
|
|
205404
|
-
if (S === 1)
|
|
205405
|
-
return sqrt3mod4;
|
|
205406
|
-
let cc = _Fp.pow(Z, Q);
|
|
205407
|
-
const Q1div2 = (Q + _1n2) / _2n;
|
|
205408
|
-
return function tonelliSlow(Fp, n) {
|
|
205409
|
-
if (Fp.is0(n))
|
|
205410
|
-
return n;
|
|
205411
|
-
if (FpLegendre(Fp, n) !== 1)
|
|
205412
|
-
throw new Error("Cannot find square root");
|
|
205413
|
-
let M = S;
|
|
205414
|
-
let c = Fp.mul(Fp.ONE, cc);
|
|
205415
|
-
let t = Fp.pow(n, Q);
|
|
205416
|
-
let R = Fp.pow(n, Q1div2);
|
|
205417
|
-
while (!Fp.eql(t, Fp.ONE)) {
|
|
205418
|
-
if (Fp.is0(t))
|
|
205419
|
-
return Fp.ZERO;
|
|
205420
|
-
let i = 1;
|
|
205421
|
-
let t_tmp = Fp.sqr(t);
|
|
205422
|
-
while (!Fp.eql(t_tmp, Fp.ONE)) {
|
|
205423
|
-
i++;
|
|
205424
|
-
t_tmp = Fp.sqr(t_tmp);
|
|
205425
|
-
if (i === M)
|
|
205426
|
-
throw new Error("Cannot find square root");
|
|
205427
|
-
}
|
|
205428
|
-
const exponent = _1n2 << BigInt(M - i - 1);
|
|
205429
|
-
const b = Fp.pow(c, exponent);
|
|
205430
|
-
M = i;
|
|
205431
|
-
c = Fp.sqr(b);
|
|
205432
|
-
t = Fp.mul(t, c);
|
|
205433
|
-
R = Fp.mul(R, b);
|
|
205434
|
-
}
|
|
205435
|
-
return R;
|
|
205436
|
-
};
|
|
205437
|
-
}
|
|
205438
|
-
function FpSqrt(P) {
|
|
205439
|
-
if (P % _4n === _3n)
|
|
205440
|
-
return sqrt3mod4;
|
|
205441
|
-
if (P % _8n === _5n)
|
|
205442
|
-
return sqrt5mod8;
|
|
205443
|
-
if (P % _16n === _9n)
|
|
205444
|
-
return sqrt9mod16(P);
|
|
205445
|
-
return tonelliShanks(P);
|
|
205446
|
-
}
|
|
205447
|
-
var FIELD_FIELDS = [
|
|
205448
|
-
"create",
|
|
205449
|
-
"isValid",
|
|
205450
|
-
"is0",
|
|
205451
|
-
"neg",
|
|
205452
|
-
"inv",
|
|
205453
|
-
"sqrt",
|
|
205454
|
-
"sqr",
|
|
205455
|
-
"eql",
|
|
205456
|
-
"add",
|
|
205457
|
-
"sub",
|
|
205458
|
-
"mul",
|
|
205459
|
-
"pow",
|
|
205460
|
-
"div",
|
|
205461
|
-
"addN",
|
|
205462
|
-
"subN",
|
|
205463
|
-
"mulN",
|
|
205464
|
-
"sqrN"
|
|
205465
|
-
];
|
|
205466
|
-
function validateField(field) {
|
|
205467
|
-
const initial = {
|
|
205468
|
-
ORDER: "bigint",
|
|
205469
|
-
BYTES: "number",
|
|
205470
|
-
BITS: "number"
|
|
205471
|
-
};
|
|
205472
|
-
const opts = FIELD_FIELDS.reduce((map, val) => {
|
|
205473
|
-
map[val] = "function";
|
|
205474
|
-
return map;
|
|
205475
|
-
}, initial);
|
|
205476
|
-
validateObject(field, opts);
|
|
205477
|
-
return field;
|
|
205478
|
-
}
|
|
205479
|
-
function FpPow(Fp, num, power) {
|
|
205480
|
-
if (power < _0n2)
|
|
205481
|
-
throw new Error("invalid exponent, negatives unsupported");
|
|
205482
|
-
if (power === _0n2)
|
|
205483
|
-
return Fp.ONE;
|
|
205484
|
-
if (power === _1n2)
|
|
205485
|
-
return num;
|
|
205486
|
-
let p = Fp.ONE;
|
|
205487
|
-
let d = num;
|
|
205488
|
-
while (power > _0n2) {
|
|
205489
|
-
if (power & _1n2)
|
|
205490
|
-
p = Fp.mul(p, d);
|
|
205491
|
-
d = Fp.sqr(d);
|
|
205492
|
-
power >>= _1n2;
|
|
205493
|
-
}
|
|
205494
|
-
return p;
|
|
205495
|
-
}
|
|
205496
|
-
function FpInvertBatch(Fp, nums, passZero = false) {
|
|
205497
|
-
const inverted = new Array(nums.length).fill(passZero ? Fp.ZERO : undefined);
|
|
205498
|
-
const multipliedAcc = nums.reduce((acc, num, i) => {
|
|
205499
|
-
if (Fp.is0(num))
|
|
205500
|
-
return acc;
|
|
205501
|
-
inverted[i] = acc;
|
|
205502
|
-
return Fp.mul(acc, num);
|
|
205503
|
-
}, Fp.ONE);
|
|
205504
|
-
const invertedAcc = Fp.inv(multipliedAcc);
|
|
205505
|
-
nums.reduceRight((acc, num, i) => {
|
|
205506
|
-
if (Fp.is0(num))
|
|
205507
|
-
return acc;
|
|
205508
|
-
inverted[i] = Fp.mul(acc, inverted[i]);
|
|
205509
|
-
return Fp.mul(acc, num);
|
|
205510
|
-
}, invertedAcc);
|
|
205511
|
-
return inverted;
|
|
205512
|
-
}
|
|
205513
|
-
function FpLegendre(Fp, n) {
|
|
205514
|
-
const p1mod2 = (Fp.ORDER - _1n2) / _2n;
|
|
205515
|
-
const powered = Fp.pow(n, p1mod2);
|
|
205516
|
-
const yes = Fp.eql(powered, Fp.ONE);
|
|
205517
|
-
const zero = Fp.eql(powered, Fp.ZERO);
|
|
205518
|
-
const no = Fp.eql(powered, Fp.neg(Fp.ONE));
|
|
205519
|
-
if (!yes && !zero && !no)
|
|
205520
|
-
throw new Error("invalid Legendre symbol result");
|
|
205521
|
-
return yes ? 1 : zero ? 0 : -1;
|
|
205522
|
-
}
|
|
205523
|
-
function nLength(n, nBitLength) {
|
|
205524
|
-
if (nBitLength !== undefined)
|
|
205525
|
-
anumber(nBitLength);
|
|
205526
|
-
const _nBitLength = nBitLength !== undefined ? nBitLength : n.toString(2).length;
|
|
205527
|
-
const nByteLength = Math.ceil(_nBitLength / 8);
|
|
205528
|
-
return { nBitLength: _nBitLength, nByteLength };
|
|
205529
|
-
}
|
|
205530
|
-
|
|
205531
|
-
class _Field {
|
|
205532
|
-
ORDER;
|
|
205533
|
-
BITS;
|
|
205534
|
-
BYTES;
|
|
205535
|
-
isLE;
|
|
205536
|
-
ZERO = _0n2;
|
|
205537
|
-
ONE = _1n2;
|
|
205538
|
-
_lengths;
|
|
205539
|
-
_sqrt;
|
|
205540
|
-
_mod;
|
|
205541
|
-
constructor(ORDER, opts = {}) {
|
|
205542
|
-
if (ORDER <= _0n2)
|
|
205543
|
-
throw new Error("invalid field: expected ORDER > 0, got " + ORDER);
|
|
205544
|
-
let _nbitLength = undefined;
|
|
205545
|
-
this.isLE = false;
|
|
205546
|
-
if (opts != null && typeof opts === "object") {
|
|
205547
|
-
if (typeof opts.BITS === "number")
|
|
205548
|
-
_nbitLength = opts.BITS;
|
|
205549
|
-
if (typeof opts.sqrt === "function")
|
|
205550
|
-
this.sqrt = opts.sqrt;
|
|
205551
|
-
if (typeof opts.isLE === "boolean")
|
|
205552
|
-
this.isLE = opts.isLE;
|
|
205553
|
-
if (opts.allowedLengths)
|
|
205554
|
-
this._lengths = opts.allowedLengths?.slice();
|
|
205555
|
-
if (typeof opts.modFromBytes === "boolean")
|
|
205556
|
-
this._mod = opts.modFromBytes;
|
|
205557
|
-
}
|
|
205558
|
-
const { nBitLength, nByteLength } = nLength(ORDER, _nbitLength);
|
|
205559
|
-
if (nByteLength > 2048)
|
|
205560
|
-
throw new Error("invalid field: expected ORDER of <= 2048 bytes");
|
|
205561
|
-
this.ORDER = ORDER;
|
|
205562
|
-
this.BITS = nBitLength;
|
|
205563
|
-
this.BYTES = nByteLength;
|
|
205564
|
-
this._sqrt = undefined;
|
|
205565
|
-
Object.preventExtensions(this);
|
|
205566
|
-
}
|
|
205567
|
-
create(num) {
|
|
205568
|
-
return mod(num, this.ORDER);
|
|
205569
|
-
}
|
|
205570
|
-
isValid(num) {
|
|
205571
|
-
if (typeof num !== "bigint")
|
|
205572
|
-
throw new Error("invalid field element: expected bigint, got " + typeof num);
|
|
205573
|
-
return _0n2 <= num && num < this.ORDER;
|
|
205574
|
-
}
|
|
205575
|
-
is0(num) {
|
|
205576
|
-
return num === _0n2;
|
|
205577
|
-
}
|
|
205578
|
-
isValidNot0(num) {
|
|
205579
|
-
return !this.is0(num) && this.isValid(num);
|
|
205580
|
-
}
|
|
205581
|
-
isOdd(num) {
|
|
205582
|
-
return (num & _1n2) === _1n2;
|
|
205583
|
-
}
|
|
205584
|
-
neg(num) {
|
|
205585
|
-
return mod(-num, this.ORDER);
|
|
205586
|
-
}
|
|
205587
|
-
eql(lhs, rhs) {
|
|
205588
|
-
return lhs === rhs;
|
|
205589
|
-
}
|
|
205590
|
-
sqr(num) {
|
|
205591
|
-
return mod(num * num, this.ORDER);
|
|
205592
|
-
}
|
|
205593
|
-
add(lhs, rhs) {
|
|
205594
|
-
return mod(lhs + rhs, this.ORDER);
|
|
205595
|
-
}
|
|
205596
|
-
sub(lhs, rhs) {
|
|
205597
|
-
return mod(lhs - rhs, this.ORDER);
|
|
205598
|
-
}
|
|
205599
|
-
mul(lhs, rhs) {
|
|
205600
|
-
return mod(lhs * rhs, this.ORDER);
|
|
205601
|
-
}
|
|
205602
|
-
pow(num, power) {
|
|
205603
|
-
return FpPow(this, num, power);
|
|
205604
|
-
}
|
|
205605
|
-
div(lhs, rhs) {
|
|
205606
|
-
return mod(lhs * invert(rhs, this.ORDER), this.ORDER);
|
|
205607
|
-
}
|
|
205608
|
-
sqrN(num) {
|
|
205609
|
-
return num * num;
|
|
205610
|
-
}
|
|
205611
|
-
addN(lhs, rhs) {
|
|
205612
|
-
return lhs + rhs;
|
|
205613
|
-
}
|
|
205614
|
-
subN(lhs, rhs) {
|
|
205615
|
-
return lhs - rhs;
|
|
205616
|
-
}
|
|
205617
|
-
mulN(lhs, rhs) {
|
|
205618
|
-
return lhs * rhs;
|
|
205619
|
-
}
|
|
205620
|
-
inv(num) {
|
|
205621
|
-
return invert(num, this.ORDER);
|
|
205622
|
-
}
|
|
205623
|
-
sqrt(num) {
|
|
205624
|
-
if (!this._sqrt)
|
|
205625
|
-
this._sqrt = FpSqrt(this.ORDER);
|
|
205626
|
-
return this._sqrt(this, num);
|
|
205627
|
-
}
|
|
205628
|
-
toBytes(num) {
|
|
205629
|
-
return this.isLE ? numberToBytesLE(num, this.BYTES) : numberToBytesBE(num, this.BYTES);
|
|
205630
|
-
}
|
|
205631
|
-
fromBytes(bytes, skipValidation = false) {
|
|
205632
|
-
abytes(bytes);
|
|
205633
|
-
const { _lengths: allowedLengths, BYTES, isLE, ORDER, _mod: modFromBytes } = this;
|
|
205634
|
-
if (allowedLengths) {
|
|
205635
|
-
if (!allowedLengths.includes(bytes.length) || bytes.length > BYTES) {
|
|
205636
|
-
throw new Error("Field.fromBytes: expected " + allowedLengths + " bytes, got " + bytes.length);
|
|
205637
|
-
}
|
|
205638
|
-
const padded = new Uint8Array(BYTES);
|
|
205639
|
-
padded.set(bytes, isLE ? 0 : padded.length - bytes.length);
|
|
205640
|
-
bytes = padded;
|
|
205641
|
-
}
|
|
205642
|
-
if (bytes.length !== BYTES)
|
|
205643
|
-
throw new Error("Field.fromBytes: expected " + BYTES + " bytes, got " + bytes.length);
|
|
205644
|
-
let scalar = isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);
|
|
205645
|
-
if (modFromBytes)
|
|
205646
|
-
scalar = mod(scalar, ORDER);
|
|
205647
|
-
if (!skipValidation) {
|
|
205648
|
-
if (!this.isValid(scalar))
|
|
205649
|
-
throw new Error("invalid field element: outside of range 0..ORDER");
|
|
205650
|
-
}
|
|
205651
|
-
return scalar;
|
|
205652
|
-
}
|
|
205653
|
-
invertBatch(lst) {
|
|
205654
|
-
return FpInvertBatch(this, lst);
|
|
205655
|
-
}
|
|
205656
|
-
cmov(a, b, condition) {
|
|
205657
|
-
return condition ? b : a;
|
|
205658
|
-
}
|
|
205659
|
-
}
|
|
205660
|
-
function Field(ORDER, opts = {}) {
|
|
205661
|
-
return new _Field(ORDER, opts);
|
|
205662
|
-
}
|
|
205663
|
-
function getFieldBytesLength(fieldOrder) {
|
|
205664
|
-
if (typeof fieldOrder !== "bigint")
|
|
205665
|
-
throw new Error("field order must be bigint");
|
|
205666
|
-
const bitLength = fieldOrder.toString(2).length;
|
|
205667
|
-
return Math.ceil(bitLength / 8);
|
|
205668
|
-
}
|
|
205669
|
-
function getMinHashLength(fieldOrder) {
|
|
205670
|
-
const length = getFieldBytesLength(fieldOrder);
|
|
205671
|
-
return length + Math.ceil(length / 2);
|
|
205672
|
-
}
|
|
205673
|
-
function mapHashToField(key, fieldOrder, isLE = false) {
|
|
205674
|
-
abytes(key);
|
|
205675
|
-
const len = key.length;
|
|
205676
|
-
const fieldLen = getFieldBytesLength(fieldOrder);
|
|
205677
|
-
const minLen = getMinHashLength(fieldOrder);
|
|
205678
|
-
if (len < 16 || len < minLen || len > 1024)
|
|
205679
|
-
throw new Error("expected " + minLen + "-1024 bytes of input, got " + len);
|
|
205680
|
-
const num = isLE ? bytesToNumberLE(key) : bytesToNumberBE(key);
|
|
205681
|
-
const reduced = mod(num, fieldOrder - _1n2) + _1n2;
|
|
205682
|
-
return isLE ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen);
|
|
205683
|
-
}
|
|
205684
|
-
|
|
205685
|
-
// ../../node_modules/@noble/curves/abstract/curve.js
|
|
205686
|
-
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
205687
|
-
var _0n3 = /* @__PURE__ */ BigInt(0);
|
|
205688
|
-
var _1n3 = /* @__PURE__ */ BigInt(1);
|
|
205689
|
-
function negateCt(condition, item) {
|
|
205690
|
-
const neg = item.negate();
|
|
205691
|
-
return condition ? neg : item;
|
|
205692
|
-
}
|
|
205693
|
-
function normalizeZ(c, points) {
|
|
205694
|
-
const invertedZs = FpInvertBatch(c.Fp, points.map((p) => p.Z));
|
|
205695
|
-
return points.map((p, i) => c.fromAffine(p.toAffine(invertedZs[i])));
|
|
205696
|
-
}
|
|
205697
|
-
function validateW(W, bits) {
|
|
205698
|
-
if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
|
|
205699
|
-
throw new Error("invalid window size, expected [1.." + bits + "], got W=" + W);
|
|
205700
|
-
}
|
|
205701
|
-
function calcWOpts(W, scalarBits) {
|
|
205702
|
-
validateW(W, scalarBits);
|
|
205703
|
-
const windows = Math.ceil(scalarBits / W) + 1;
|
|
205704
|
-
const windowSize = 2 ** (W - 1);
|
|
205705
|
-
const maxNumber = 2 ** W;
|
|
205706
|
-
const mask = bitMask(W);
|
|
205707
|
-
const shiftBy = BigInt(W);
|
|
205708
|
-
return { windows, windowSize, mask, maxNumber, shiftBy };
|
|
205709
|
-
}
|
|
205710
|
-
function calcOffsets(n, window2, wOpts) {
|
|
205711
|
-
const { windowSize, mask, maxNumber, shiftBy } = wOpts;
|
|
205712
|
-
let wbits = Number(n & mask);
|
|
205713
|
-
let nextN = n >> shiftBy;
|
|
205714
|
-
if (wbits > windowSize) {
|
|
205715
|
-
wbits -= maxNumber;
|
|
205716
|
-
nextN += _1n3;
|
|
205717
|
-
}
|
|
205718
|
-
const offsetStart = window2 * windowSize;
|
|
205719
|
-
const offset = offsetStart + Math.abs(wbits) - 1;
|
|
205720
|
-
const isZero = wbits === 0;
|
|
205721
|
-
const isNeg = wbits < 0;
|
|
205722
|
-
const isNegF = window2 % 2 !== 0;
|
|
205723
|
-
const offsetF = offsetStart;
|
|
205724
|
-
return { nextN, offset, isZero, isNeg, isNegF, offsetF };
|
|
205725
|
-
}
|
|
205726
|
-
var pointPrecomputes = new WeakMap;
|
|
205727
|
-
var pointWindowSizes = new WeakMap;
|
|
205728
|
-
function getW(P) {
|
|
205729
|
-
return pointWindowSizes.get(P) || 1;
|
|
205730
|
-
}
|
|
205731
|
-
function assert0(n) {
|
|
205732
|
-
if (n !== _0n3)
|
|
205733
|
-
throw new Error("invalid wNAF");
|
|
205734
|
-
}
|
|
205735
|
-
|
|
205736
|
-
class wNAF {
|
|
205737
|
-
BASE;
|
|
205738
|
-
ZERO;
|
|
205739
|
-
Fn;
|
|
205740
|
-
bits;
|
|
205741
|
-
constructor(Point, bits) {
|
|
205742
|
-
this.BASE = Point.BASE;
|
|
205743
|
-
this.ZERO = Point.ZERO;
|
|
205744
|
-
this.Fn = Point.Fn;
|
|
205745
|
-
this.bits = bits;
|
|
205746
|
-
}
|
|
205747
|
-
_unsafeLadder(elm, n, p = this.ZERO) {
|
|
205748
|
-
let d = elm;
|
|
205749
|
-
while (n > _0n3) {
|
|
205750
|
-
if (n & _1n3)
|
|
205751
|
-
p = p.add(d);
|
|
205752
|
-
d = d.double();
|
|
205753
|
-
n >>= _1n3;
|
|
205754
|
-
}
|
|
205755
|
-
return p;
|
|
205756
|
-
}
|
|
205757
|
-
precomputeWindow(point, W) {
|
|
205758
|
-
const { windows, windowSize } = calcWOpts(W, this.bits);
|
|
205759
|
-
const points = [];
|
|
205760
|
-
let p = point;
|
|
205761
|
-
let base = p;
|
|
205762
|
-
for (let window2 = 0;window2 < windows; window2++) {
|
|
205763
|
-
base = p;
|
|
205764
|
-
points.push(base);
|
|
205765
|
-
for (let i = 1;i < windowSize; i++) {
|
|
205766
|
-
base = base.add(p);
|
|
205767
|
-
points.push(base);
|
|
205768
|
-
}
|
|
205769
|
-
p = base.double();
|
|
205770
|
-
}
|
|
205771
|
-
return points;
|
|
205772
|
-
}
|
|
205773
|
-
wNAF(W, precomputes, n) {
|
|
205774
|
-
if (!this.Fn.isValid(n))
|
|
205775
|
-
throw new Error("invalid scalar");
|
|
205776
|
-
let p = this.ZERO;
|
|
205777
|
-
let f = this.BASE;
|
|
205778
|
-
const wo = calcWOpts(W, this.bits);
|
|
205779
|
-
for (let window2 = 0;window2 < wo.windows; window2++) {
|
|
205780
|
-
const { nextN, offset, isZero, isNeg, isNegF, offsetF } = calcOffsets(n, window2, wo);
|
|
205781
|
-
n = nextN;
|
|
205782
|
-
if (isZero) {
|
|
205783
|
-
f = f.add(negateCt(isNegF, precomputes[offsetF]));
|
|
205784
|
-
} else {
|
|
205785
|
-
p = p.add(negateCt(isNeg, precomputes[offset]));
|
|
205786
|
-
}
|
|
205787
|
-
}
|
|
205788
|
-
assert0(n);
|
|
205789
|
-
return { p, f };
|
|
205790
|
-
}
|
|
205791
|
-
wNAFUnsafe(W, precomputes, n, acc = this.ZERO) {
|
|
205792
|
-
const wo = calcWOpts(W, this.bits);
|
|
205793
|
-
for (let window2 = 0;window2 < wo.windows; window2++) {
|
|
205794
|
-
if (n === _0n3)
|
|
205795
|
-
break;
|
|
205796
|
-
const { nextN, offset, isZero, isNeg } = calcOffsets(n, window2, wo);
|
|
205797
|
-
n = nextN;
|
|
205798
|
-
if (isZero) {
|
|
205799
|
-
continue;
|
|
205800
|
-
} else {
|
|
205801
|
-
const item = precomputes[offset];
|
|
205802
|
-
acc = acc.add(isNeg ? item.negate() : item);
|
|
205803
|
-
}
|
|
205804
|
-
}
|
|
205805
|
-
assert0(n);
|
|
205806
|
-
return acc;
|
|
205807
|
-
}
|
|
205808
|
-
getPrecomputes(W, point, transform) {
|
|
205809
|
-
let comp = pointPrecomputes.get(point);
|
|
205810
|
-
if (!comp) {
|
|
205811
|
-
comp = this.precomputeWindow(point, W);
|
|
205812
|
-
if (W !== 1) {
|
|
205813
|
-
if (typeof transform === "function")
|
|
205814
|
-
comp = transform(comp);
|
|
205815
|
-
pointPrecomputes.set(point, comp);
|
|
205816
|
-
}
|
|
205817
|
-
}
|
|
205818
|
-
return comp;
|
|
205819
|
-
}
|
|
205820
|
-
cached(point, scalar, transform) {
|
|
205821
|
-
const W = getW(point);
|
|
205822
|
-
return this.wNAF(W, this.getPrecomputes(W, point, transform), scalar);
|
|
205823
|
-
}
|
|
205824
|
-
unsafe(point, scalar, transform, prev) {
|
|
205825
|
-
const W = getW(point);
|
|
205826
|
-
if (W === 1)
|
|
205827
|
-
return this._unsafeLadder(point, scalar, prev);
|
|
205828
|
-
return this.wNAFUnsafe(W, this.getPrecomputes(W, point, transform), scalar, prev);
|
|
205829
|
-
}
|
|
205830
|
-
createCache(P, W) {
|
|
205831
|
-
validateW(W, this.bits);
|
|
205832
|
-
pointWindowSizes.set(P, W);
|
|
205833
|
-
pointPrecomputes.delete(P);
|
|
205834
|
-
}
|
|
205835
|
-
hasCache(elm) {
|
|
205836
|
-
return getW(elm) !== 1;
|
|
205837
|
-
}
|
|
205838
|
-
}
|
|
205839
|
-
function mulEndoUnsafe(Point, point, k1, k2) {
|
|
205840
|
-
let acc = point;
|
|
205841
|
-
let p1 = Point.ZERO;
|
|
205842
|
-
let p2 = Point.ZERO;
|
|
205843
|
-
while (k1 > _0n3 || k2 > _0n3) {
|
|
205844
|
-
if (k1 & _1n3)
|
|
205845
|
-
p1 = p1.add(acc);
|
|
205846
|
-
if (k2 & _1n3)
|
|
205847
|
-
p2 = p2.add(acc);
|
|
205848
|
-
acc = acc.double();
|
|
205849
|
-
k1 >>= _1n3;
|
|
205850
|
-
k2 >>= _1n3;
|
|
205851
|
-
}
|
|
205852
|
-
return { p1, p2 };
|
|
205853
|
-
}
|
|
205854
|
-
function createField(order, field, isLE) {
|
|
205855
|
-
if (field) {
|
|
205856
|
-
if (field.ORDER !== order)
|
|
205857
|
-
throw new Error("Field.ORDER must match order: Fp == p, Fn == n");
|
|
205858
|
-
validateField(field);
|
|
205859
|
-
return field;
|
|
205860
|
-
} else {
|
|
205861
|
-
return Field(order, { isLE });
|
|
205862
|
-
}
|
|
205863
|
-
}
|
|
205864
|
-
function createCurveFields(type, CURVE, curveOpts = {}, FpFnLE) {
|
|
205865
|
-
if (FpFnLE === undefined)
|
|
205866
|
-
FpFnLE = type === "edwards";
|
|
205867
|
-
if (!CURVE || typeof CURVE !== "object")
|
|
205868
|
-
throw new Error(`expected valid ${type} CURVE object`);
|
|
205869
|
-
for (const p of ["p", "n", "h"]) {
|
|
205870
|
-
const val = CURVE[p];
|
|
205871
|
-
if (!(typeof val === "bigint" && val > _0n3))
|
|
205872
|
-
throw new Error(`CURVE.${p} must be positive bigint`);
|
|
205873
|
-
}
|
|
205874
|
-
const Fp = createField(CURVE.p, curveOpts.Fp, FpFnLE);
|
|
205875
|
-
const Fn = createField(CURVE.n, curveOpts.Fn, FpFnLE);
|
|
205876
|
-
const _b = type === "weierstrass" ? "b" : "d";
|
|
205877
|
-
const params = ["Gx", "Gy", "a", _b];
|
|
205878
|
-
for (const p of params) {
|
|
205879
|
-
if (!Fp.isValid(CURVE[p]))
|
|
205880
|
-
throw new Error(`CURVE.${p} must be valid field element of CURVE.Fp`);
|
|
205881
|
-
}
|
|
205882
|
-
CURVE = Object.freeze(Object.assign({}, CURVE));
|
|
205883
|
-
return { CURVE, Fp, Fn };
|
|
205884
|
-
}
|
|
205885
|
-
function createKeygen(randomSecretKey, getPublicKey) {
|
|
205886
|
-
return function keygen(seed) {
|
|
205887
|
-
const secretKey = randomSecretKey(seed);
|
|
205888
|
-
return { secretKey, publicKey: getPublicKey(secretKey) };
|
|
205889
|
-
};
|
|
205890
|
-
}
|
|
205891
|
-
|
|
205892
|
-
// ../../node_modules/@noble/curves/abstract/hash-to-curve.js
|
|
205893
|
-
var _DST_scalar = asciiToBytes("HashToScalar-");
|
|
205894
|
-
|
|
205895
|
-
// ../../node_modules/@noble/hashes/hmac.js
|
|
205896
|
-
class _HMAC {
|
|
205897
|
-
oHash;
|
|
205898
|
-
iHash;
|
|
205899
|
-
blockLen;
|
|
205900
|
-
outputLen;
|
|
205901
|
-
finished = false;
|
|
205902
|
-
destroyed = false;
|
|
205903
|
-
constructor(hash, key) {
|
|
205904
|
-
ahash(hash);
|
|
205905
|
-
abytes(key, undefined, "key");
|
|
205906
|
-
this.iHash = hash.create();
|
|
205907
|
-
if (typeof this.iHash.update !== "function")
|
|
205908
|
-
throw new Error("Expected instance of class which extends utils.Hash");
|
|
205909
|
-
this.blockLen = this.iHash.blockLen;
|
|
205910
|
-
this.outputLen = this.iHash.outputLen;
|
|
205911
|
-
const blockLen = this.blockLen;
|
|
205912
|
-
const pad = new Uint8Array(blockLen);
|
|
205913
|
-
pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);
|
|
205914
|
-
for (let i = 0;i < pad.length; i++)
|
|
205915
|
-
pad[i] ^= 54;
|
|
205916
|
-
this.iHash.update(pad);
|
|
205917
|
-
this.oHash = hash.create();
|
|
205918
|
-
for (let i = 0;i < pad.length; i++)
|
|
205919
|
-
pad[i] ^= 54 ^ 92;
|
|
205920
|
-
this.oHash.update(pad);
|
|
205921
|
-
clean(pad);
|
|
205922
|
-
}
|
|
205923
|
-
update(buf) {
|
|
205924
|
-
aexists(this);
|
|
205925
|
-
this.iHash.update(buf);
|
|
205926
|
-
return this;
|
|
205927
|
-
}
|
|
205928
|
-
digestInto(out) {
|
|
205929
|
-
aexists(this);
|
|
205930
|
-
abytes(out, this.outputLen, "output");
|
|
205931
|
-
this.finished = true;
|
|
205932
|
-
this.iHash.digestInto(out);
|
|
205933
|
-
this.oHash.update(out);
|
|
205934
|
-
this.oHash.digestInto(out);
|
|
205935
|
-
this.destroy();
|
|
205936
|
-
}
|
|
205937
|
-
digest() {
|
|
205938
|
-
const out = new Uint8Array(this.oHash.outputLen);
|
|
205939
|
-
this.digestInto(out);
|
|
205940
|
-
return out;
|
|
205941
|
-
}
|
|
205942
|
-
_cloneInto(to) {
|
|
205943
|
-
to ||= Object.create(Object.getPrototypeOf(this), {});
|
|
205944
|
-
const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
|
|
205945
|
-
to = to;
|
|
205946
|
-
to.finished = finished;
|
|
205947
|
-
to.destroyed = destroyed;
|
|
205948
|
-
to.blockLen = blockLen;
|
|
205949
|
-
to.outputLen = outputLen;
|
|
205950
|
-
to.oHash = oHash._cloneInto(to.oHash);
|
|
205951
|
-
to.iHash = iHash._cloneInto(to.iHash);
|
|
205952
|
-
return to;
|
|
205953
|
-
}
|
|
205954
|
-
clone() {
|
|
205955
|
-
return this._cloneInto();
|
|
205956
|
-
}
|
|
205957
|
-
destroy() {
|
|
205958
|
-
this.destroyed = true;
|
|
205959
|
-
this.oHash.destroy();
|
|
205960
|
-
this.iHash.destroy();
|
|
205961
|
-
}
|
|
205962
|
-
}
|
|
205963
|
-
var hmac = (hash, key, message) => new _HMAC(hash, key).update(message).digest();
|
|
205964
|
-
hmac.create = (hash, key) => new _HMAC(hash, key);
|
|
205965
|
-
|
|
205966
|
-
// ../../node_modules/@noble/curves/abstract/weierstrass.js
|
|
205967
|
-
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
205968
|
-
var divNearest = (num, den) => (num + (num >= 0 ? den : -den) / _2n2) / den;
|
|
205969
|
-
function _splitEndoScalar(k, basis, n) {
|
|
205970
|
-
const [[a1, b1], [a2, b2]] = basis;
|
|
205971
|
-
const c1 = divNearest(b2 * k, n);
|
|
205972
|
-
const c2 = divNearest(-b1 * k, n);
|
|
205973
|
-
let k1 = k - c1 * a1 - c2 * a2;
|
|
205974
|
-
let k2 = -c1 * b1 - c2 * b2;
|
|
205975
|
-
const k1neg = k1 < _0n4;
|
|
205976
|
-
const k2neg = k2 < _0n4;
|
|
205977
|
-
if (k1neg)
|
|
205978
|
-
k1 = -k1;
|
|
205979
|
-
if (k2neg)
|
|
205980
|
-
k2 = -k2;
|
|
205981
|
-
const MAX_NUM = bitMask(Math.ceil(bitLen(n) / 2)) + _1n4;
|
|
205982
|
-
if (k1 < _0n4 || k1 >= MAX_NUM || k2 < _0n4 || k2 >= MAX_NUM) {
|
|
205983
|
-
throw new Error("splitScalar (endomorphism): failed, k=" + k);
|
|
205984
|
-
}
|
|
205985
|
-
return { k1neg, k1, k2neg, k2 };
|
|
205986
|
-
}
|
|
205987
|
-
function validateSigFormat(format) {
|
|
205988
|
-
if (!["compact", "recovered", "der"].includes(format))
|
|
205989
|
-
throw new Error('Signature format must be "compact", "recovered", or "der"');
|
|
205990
|
-
return format;
|
|
205991
|
-
}
|
|
205992
|
-
function validateSigOpts(opts, def) {
|
|
205993
|
-
const optsn = {};
|
|
205994
|
-
for (let optName of Object.keys(def)) {
|
|
205995
|
-
optsn[optName] = opts[optName] === undefined ? def[optName] : opts[optName];
|
|
205996
|
-
}
|
|
205997
|
-
abool(optsn.lowS, "lowS");
|
|
205998
|
-
abool(optsn.prehash, "prehash");
|
|
205999
|
-
if (optsn.format !== undefined)
|
|
206000
|
-
validateSigFormat(optsn.format);
|
|
206001
|
-
return optsn;
|
|
206002
|
-
}
|
|
206003
|
-
|
|
206004
|
-
class DERErr extends Error {
|
|
206005
|
-
constructor(m = "") {
|
|
206006
|
-
super(m);
|
|
206007
|
-
}
|
|
206008
|
-
}
|
|
206009
|
-
var DER = {
|
|
206010
|
-
Err: DERErr,
|
|
206011
|
-
_tlv: {
|
|
206012
|
-
encode: (tag, data) => {
|
|
206013
|
-
const { Err: E } = DER;
|
|
206014
|
-
if (tag < 0 || tag > 256)
|
|
206015
|
-
throw new E("tlv.encode: wrong tag");
|
|
206016
|
-
if (data.length & 1)
|
|
206017
|
-
throw new E("tlv.encode: unpadded data");
|
|
206018
|
-
const dataLen = data.length / 2;
|
|
206019
|
-
const len = numberToHexUnpadded(dataLen);
|
|
206020
|
-
if (len.length / 2 & 128)
|
|
206021
|
-
throw new E("tlv.encode: long form length too big");
|
|
206022
|
-
const lenLen = dataLen > 127 ? numberToHexUnpadded(len.length / 2 | 128) : "";
|
|
206023
|
-
const t = numberToHexUnpadded(tag);
|
|
206024
|
-
return t + lenLen + len + data;
|
|
206025
|
-
},
|
|
206026
|
-
decode(tag, data) {
|
|
206027
|
-
const { Err: E } = DER;
|
|
206028
|
-
let pos = 0;
|
|
206029
|
-
if (tag < 0 || tag > 256)
|
|
206030
|
-
throw new E("tlv.encode: wrong tag");
|
|
206031
|
-
if (data.length < 2 || data[pos++] !== tag)
|
|
206032
|
-
throw new E("tlv.decode: wrong tlv");
|
|
206033
|
-
const first = data[pos++];
|
|
206034
|
-
const isLong = !!(first & 128);
|
|
206035
|
-
let length = 0;
|
|
206036
|
-
if (!isLong)
|
|
206037
|
-
length = first;
|
|
206038
|
-
else {
|
|
206039
|
-
const lenLen = first & 127;
|
|
206040
|
-
if (!lenLen)
|
|
206041
|
-
throw new E("tlv.decode(long): indefinite length not supported");
|
|
206042
|
-
if (lenLen > 4)
|
|
206043
|
-
throw new E("tlv.decode(long): byte length is too big");
|
|
206044
|
-
const lengthBytes = data.subarray(pos, pos + lenLen);
|
|
206045
|
-
if (lengthBytes.length !== lenLen)
|
|
206046
|
-
throw new E("tlv.decode: length bytes not complete");
|
|
206047
|
-
if (lengthBytes[0] === 0)
|
|
206048
|
-
throw new E("tlv.decode(long): zero leftmost byte");
|
|
206049
|
-
for (const b of lengthBytes)
|
|
206050
|
-
length = length << 8 | b;
|
|
206051
|
-
pos += lenLen;
|
|
206052
|
-
if (length < 128)
|
|
206053
|
-
throw new E("tlv.decode(long): not minimal encoding");
|
|
206054
|
-
}
|
|
206055
|
-
const v = data.subarray(pos, pos + length);
|
|
206056
|
-
if (v.length !== length)
|
|
206057
|
-
throw new E("tlv.decode: wrong value length");
|
|
206058
|
-
return { v, l: data.subarray(pos + length) };
|
|
206059
|
-
}
|
|
206060
|
-
},
|
|
206061
|
-
_int: {
|
|
206062
|
-
encode(num) {
|
|
206063
|
-
const { Err: E } = DER;
|
|
206064
|
-
if (num < _0n4)
|
|
206065
|
-
throw new E("integer: negative integers are not allowed");
|
|
206066
|
-
let hex = numberToHexUnpadded(num);
|
|
206067
|
-
if (Number.parseInt(hex[0], 16) & 8)
|
|
206068
|
-
hex = "00" + hex;
|
|
206069
|
-
if (hex.length & 1)
|
|
206070
|
-
throw new E("unexpected DER parsing assertion: unpadded hex");
|
|
206071
|
-
return hex;
|
|
206072
|
-
},
|
|
206073
|
-
decode(data) {
|
|
206074
|
-
const { Err: E } = DER;
|
|
206075
|
-
if (data[0] & 128)
|
|
206076
|
-
throw new E("invalid signature integer: negative");
|
|
206077
|
-
if (data[0] === 0 && !(data[1] & 128))
|
|
206078
|
-
throw new E("invalid signature integer: unnecessary leading zero");
|
|
206079
|
-
return bytesToNumberBE(data);
|
|
206080
|
-
}
|
|
206081
|
-
},
|
|
206082
|
-
toSig(bytes) {
|
|
206083
|
-
const { Err: E, _int: int, _tlv: tlv } = DER;
|
|
206084
|
-
const data = abytes(bytes, undefined, "signature");
|
|
206085
|
-
const { v: seqBytes, l: seqLeftBytes } = tlv.decode(48, data);
|
|
206086
|
-
if (seqLeftBytes.length)
|
|
206087
|
-
throw new E("invalid signature: left bytes after parsing");
|
|
206088
|
-
const { v: rBytes, l: rLeftBytes } = tlv.decode(2, seqBytes);
|
|
206089
|
-
const { v: sBytes, l: sLeftBytes } = tlv.decode(2, rLeftBytes);
|
|
206090
|
-
if (sLeftBytes.length)
|
|
206091
|
-
throw new E("invalid signature: left bytes after parsing");
|
|
206092
|
-
return { r: int.decode(rBytes), s: int.decode(sBytes) };
|
|
206093
|
-
},
|
|
206094
|
-
hexFromSig(sig) {
|
|
206095
|
-
const { _tlv: tlv, _int: int } = DER;
|
|
206096
|
-
const rs = tlv.encode(2, int.encode(sig.r));
|
|
206097
|
-
const ss = tlv.encode(2, int.encode(sig.s));
|
|
206098
|
-
const seq = rs + ss;
|
|
206099
|
-
return tlv.encode(48, seq);
|
|
206100
|
-
}
|
|
206101
|
-
};
|
|
206102
|
-
var _0n4 = BigInt(0);
|
|
206103
|
-
var _1n4 = BigInt(1);
|
|
206104
|
-
var _2n2 = BigInt(2);
|
|
206105
|
-
var _3n2 = BigInt(3);
|
|
206106
|
-
var _4n2 = BigInt(4);
|
|
206107
|
-
function weierstrass(params, extraOpts = {}) {
|
|
206108
|
-
const validated = createCurveFields("weierstrass", params, extraOpts);
|
|
206109
|
-
const { Fp, Fn } = validated;
|
|
206110
|
-
let CURVE = validated.CURVE;
|
|
206111
|
-
const { h: cofactor, n: CURVE_ORDER } = CURVE;
|
|
206112
|
-
validateObject(extraOpts, {}, {
|
|
206113
|
-
allowInfinityPoint: "boolean",
|
|
206114
|
-
clearCofactor: "function",
|
|
206115
|
-
isTorsionFree: "function",
|
|
206116
|
-
fromBytes: "function",
|
|
206117
|
-
toBytes: "function",
|
|
206118
|
-
endo: "object"
|
|
206119
|
-
});
|
|
206120
|
-
const { endo } = extraOpts;
|
|
206121
|
-
if (endo) {
|
|
206122
|
-
if (!Fp.is0(CURVE.a) || typeof endo.beta !== "bigint" || !Array.isArray(endo.basises)) {
|
|
206123
|
-
throw new Error('invalid endo: expected "beta": bigint and "basises": array');
|
|
206124
|
-
}
|
|
206125
|
-
}
|
|
206126
|
-
const lengths = getWLengths(Fp, Fn);
|
|
206127
|
-
function assertCompressionIsSupported() {
|
|
206128
|
-
if (!Fp.isOdd)
|
|
206129
|
-
throw new Error("compression is not supported: Field does not have .isOdd()");
|
|
206130
|
-
}
|
|
206131
|
-
function pointToBytes(_c, point, isCompressed) {
|
|
206132
|
-
const { x, y } = point.toAffine();
|
|
206133
|
-
const bx = Fp.toBytes(x);
|
|
206134
|
-
abool(isCompressed, "isCompressed");
|
|
206135
|
-
if (isCompressed) {
|
|
206136
|
-
assertCompressionIsSupported();
|
|
206137
|
-
const hasEvenY = !Fp.isOdd(y);
|
|
206138
|
-
return concatBytes(pprefix(hasEvenY), bx);
|
|
206139
|
-
} else {
|
|
206140
|
-
return concatBytes(Uint8Array.of(4), bx, Fp.toBytes(y));
|
|
206141
|
-
}
|
|
206142
|
-
}
|
|
206143
|
-
function pointFromBytes(bytes) {
|
|
206144
|
-
abytes(bytes, undefined, "Point");
|
|
206145
|
-
const { publicKey: comp, publicKeyUncompressed: uncomp } = lengths;
|
|
206146
|
-
const length = bytes.length;
|
|
206147
|
-
const head = bytes[0];
|
|
206148
|
-
const tail = bytes.subarray(1);
|
|
206149
|
-
if (length === comp && (head === 2 || head === 3)) {
|
|
206150
|
-
const x = Fp.fromBytes(tail);
|
|
206151
|
-
if (!Fp.isValid(x))
|
|
206152
|
-
throw new Error("bad point: is not on curve, wrong x");
|
|
206153
|
-
const y2 = weierstrassEquation(x);
|
|
206154
|
-
let y;
|
|
206155
|
-
try {
|
|
206156
|
-
y = Fp.sqrt(y2);
|
|
206157
|
-
} catch (sqrtError) {
|
|
206158
|
-
const err = sqrtError instanceof Error ? ": " + sqrtError.message : "";
|
|
206159
|
-
throw new Error("bad point: is not on curve, sqrt error" + err);
|
|
206160
|
-
}
|
|
206161
|
-
assertCompressionIsSupported();
|
|
206162
|
-
const evenY = Fp.isOdd(y);
|
|
206163
|
-
const evenH = (head & 1) === 1;
|
|
206164
|
-
if (evenH !== evenY)
|
|
206165
|
-
y = Fp.neg(y);
|
|
206166
|
-
return { x, y };
|
|
206167
|
-
} else if (length === uncomp && head === 4) {
|
|
206168
|
-
const L = Fp.BYTES;
|
|
206169
|
-
const x = Fp.fromBytes(tail.subarray(0, L));
|
|
206170
|
-
const y = Fp.fromBytes(tail.subarray(L, L * 2));
|
|
206171
|
-
if (!isValidXY(x, y))
|
|
206172
|
-
throw new Error("bad point: is not on curve");
|
|
206173
|
-
return { x, y };
|
|
206174
|
-
} else {
|
|
206175
|
-
throw new Error(`bad point: got length ${length}, expected compressed=${comp} or uncompressed=${uncomp}`);
|
|
206176
|
-
}
|
|
206177
|
-
}
|
|
206178
|
-
const encodePoint = extraOpts.toBytes || pointToBytes;
|
|
206179
|
-
const decodePoint = extraOpts.fromBytes || pointFromBytes;
|
|
206180
|
-
function weierstrassEquation(x) {
|
|
206181
|
-
const x2 = Fp.sqr(x);
|
|
206182
|
-
const x3 = Fp.mul(x2, x);
|
|
206183
|
-
return Fp.add(Fp.add(x3, Fp.mul(x, CURVE.a)), CURVE.b);
|
|
206184
|
-
}
|
|
206185
|
-
function isValidXY(x, y) {
|
|
206186
|
-
const left = Fp.sqr(y);
|
|
206187
|
-
const right = weierstrassEquation(x);
|
|
206188
|
-
return Fp.eql(left, right);
|
|
206189
|
-
}
|
|
206190
|
-
if (!isValidXY(CURVE.Gx, CURVE.Gy))
|
|
206191
|
-
throw new Error("bad curve params: generator point");
|
|
206192
|
-
const _4a3 = Fp.mul(Fp.pow(CURVE.a, _3n2), _4n2);
|
|
206193
|
-
const _27b2 = Fp.mul(Fp.sqr(CURVE.b), BigInt(27));
|
|
206194
|
-
if (Fp.is0(Fp.add(_4a3, _27b2)))
|
|
206195
|
-
throw new Error("bad curve params: a or b");
|
|
206196
|
-
function acoord(title, n, banZero = false) {
|
|
206197
|
-
if (!Fp.isValid(n) || banZero && Fp.is0(n))
|
|
206198
|
-
throw new Error(`bad point coordinate ${title}`);
|
|
206199
|
-
return n;
|
|
206200
|
-
}
|
|
206201
|
-
function aprjpoint(other) {
|
|
206202
|
-
if (!(other instanceof Point))
|
|
206203
|
-
throw new Error("Weierstrass Point expected");
|
|
206204
|
-
}
|
|
206205
|
-
function splitEndoScalarN(k) {
|
|
206206
|
-
if (!endo || !endo.basises)
|
|
206207
|
-
throw new Error("no endo");
|
|
206208
|
-
return _splitEndoScalar(k, endo.basises, Fn.ORDER);
|
|
206209
|
-
}
|
|
206210
|
-
const toAffineMemo = memoized((p, iz) => {
|
|
206211
|
-
const { X, Y, Z } = p;
|
|
206212
|
-
if (Fp.eql(Z, Fp.ONE))
|
|
206213
|
-
return { x: X, y: Y };
|
|
206214
|
-
const is0 = p.is0();
|
|
206215
|
-
if (iz == null)
|
|
206216
|
-
iz = is0 ? Fp.ONE : Fp.inv(Z);
|
|
206217
|
-
const x = Fp.mul(X, iz);
|
|
206218
|
-
const y = Fp.mul(Y, iz);
|
|
206219
|
-
const zz = Fp.mul(Z, iz);
|
|
206220
|
-
if (is0)
|
|
206221
|
-
return { x: Fp.ZERO, y: Fp.ZERO };
|
|
206222
|
-
if (!Fp.eql(zz, Fp.ONE))
|
|
206223
|
-
throw new Error("invZ was invalid");
|
|
206224
|
-
return { x, y };
|
|
206225
|
-
});
|
|
206226
|
-
const assertValidMemo = memoized((p) => {
|
|
206227
|
-
if (p.is0()) {
|
|
206228
|
-
if (extraOpts.allowInfinityPoint && !Fp.is0(p.Y))
|
|
206229
|
-
return;
|
|
206230
|
-
throw new Error("bad point: ZERO");
|
|
206231
|
-
}
|
|
206232
|
-
const { x, y } = p.toAffine();
|
|
206233
|
-
if (!Fp.isValid(x) || !Fp.isValid(y))
|
|
206234
|
-
throw new Error("bad point: x or y not field elements");
|
|
206235
|
-
if (!isValidXY(x, y))
|
|
206236
|
-
throw new Error("bad point: equation left != right");
|
|
206237
|
-
if (!p.isTorsionFree())
|
|
206238
|
-
throw new Error("bad point: not in prime-order subgroup");
|
|
206239
|
-
return true;
|
|
206240
|
-
});
|
|
206241
|
-
function finishEndo(endoBeta, k1p, k2p, k1neg, k2neg) {
|
|
206242
|
-
k2p = new Point(Fp.mul(k2p.X, endoBeta), k2p.Y, k2p.Z);
|
|
206243
|
-
k1p = negateCt(k1neg, k1p);
|
|
206244
|
-
k2p = negateCt(k2neg, k2p);
|
|
206245
|
-
return k1p.add(k2p);
|
|
206246
|
-
}
|
|
206247
|
-
|
|
206248
|
-
class Point {
|
|
206249
|
-
static BASE = new Point(CURVE.Gx, CURVE.Gy, Fp.ONE);
|
|
206250
|
-
static ZERO = new Point(Fp.ZERO, Fp.ONE, Fp.ZERO);
|
|
206251
|
-
static Fp = Fp;
|
|
206252
|
-
static Fn = Fn;
|
|
206253
|
-
X;
|
|
206254
|
-
Y;
|
|
206255
|
-
Z;
|
|
206256
|
-
constructor(X, Y, Z) {
|
|
206257
|
-
this.X = acoord("x", X);
|
|
206258
|
-
this.Y = acoord("y", Y, true);
|
|
206259
|
-
this.Z = acoord("z", Z);
|
|
206260
|
-
Object.freeze(this);
|
|
206261
|
-
}
|
|
206262
|
-
static CURVE() {
|
|
206263
|
-
return CURVE;
|
|
206264
|
-
}
|
|
206265
|
-
static fromAffine(p) {
|
|
206266
|
-
const { x, y } = p || {};
|
|
206267
|
-
if (!p || !Fp.isValid(x) || !Fp.isValid(y))
|
|
206268
|
-
throw new Error("invalid affine point");
|
|
206269
|
-
if (p instanceof Point)
|
|
206270
|
-
throw new Error("projective point not allowed");
|
|
206271
|
-
if (Fp.is0(x) && Fp.is0(y))
|
|
206272
|
-
return Point.ZERO;
|
|
206273
|
-
return new Point(x, y, Fp.ONE);
|
|
206274
|
-
}
|
|
206275
|
-
static fromBytes(bytes) {
|
|
206276
|
-
const P = Point.fromAffine(decodePoint(abytes(bytes, undefined, "point")));
|
|
206277
|
-
P.assertValidity();
|
|
206278
|
-
return P;
|
|
206279
|
-
}
|
|
206280
|
-
static fromHex(hex) {
|
|
206281
|
-
return Point.fromBytes(hexToBytes(hex));
|
|
206282
|
-
}
|
|
206283
|
-
get x() {
|
|
206284
|
-
return this.toAffine().x;
|
|
206285
|
-
}
|
|
206286
|
-
get y() {
|
|
206287
|
-
return this.toAffine().y;
|
|
206288
|
-
}
|
|
206289
|
-
precompute(windowSize = 8, isLazy = true) {
|
|
206290
|
-
wnaf.createCache(this, windowSize);
|
|
206291
|
-
if (!isLazy)
|
|
206292
|
-
this.multiply(_3n2);
|
|
206293
|
-
return this;
|
|
206294
|
-
}
|
|
206295
|
-
assertValidity() {
|
|
206296
|
-
assertValidMemo(this);
|
|
206297
|
-
}
|
|
206298
|
-
hasEvenY() {
|
|
206299
|
-
const { y } = this.toAffine();
|
|
206300
|
-
if (!Fp.isOdd)
|
|
206301
|
-
throw new Error("Field doesn't support isOdd");
|
|
206302
|
-
return !Fp.isOdd(y);
|
|
206303
|
-
}
|
|
206304
|
-
equals(other) {
|
|
206305
|
-
aprjpoint(other);
|
|
206306
|
-
const { X: X1, Y: Y1, Z: Z1 } = this;
|
|
206307
|
-
const { X: X2, Y: Y2, Z: Z2 } = other;
|
|
206308
|
-
const U1 = Fp.eql(Fp.mul(X1, Z2), Fp.mul(X2, Z1));
|
|
206309
|
-
const U2 = Fp.eql(Fp.mul(Y1, Z2), Fp.mul(Y2, Z1));
|
|
206310
|
-
return U1 && U2;
|
|
206311
|
-
}
|
|
206312
|
-
negate() {
|
|
206313
|
-
return new Point(this.X, Fp.neg(this.Y), this.Z);
|
|
206314
|
-
}
|
|
206315
|
-
double() {
|
|
206316
|
-
const { a, b } = CURVE;
|
|
206317
|
-
const b3 = Fp.mul(b, _3n2);
|
|
206318
|
-
const { X: X1, Y: Y1, Z: Z1 } = this;
|
|
206319
|
-
let { ZERO: X3, ZERO: Y3, ZERO: Z3 } = Fp;
|
|
206320
|
-
let t0 = Fp.mul(X1, X1);
|
|
206321
|
-
let t1 = Fp.mul(Y1, Y1);
|
|
206322
|
-
let t2 = Fp.mul(Z1, Z1);
|
|
206323
|
-
let t3 = Fp.mul(X1, Y1);
|
|
206324
|
-
t3 = Fp.add(t3, t3);
|
|
206325
|
-
Z3 = Fp.mul(X1, Z1);
|
|
206326
|
-
Z3 = Fp.add(Z3, Z3);
|
|
206327
|
-
X3 = Fp.mul(a, Z3);
|
|
206328
|
-
Y3 = Fp.mul(b3, t2);
|
|
206329
|
-
Y3 = Fp.add(X3, Y3);
|
|
206330
|
-
X3 = Fp.sub(t1, Y3);
|
|
206331
|
-
Y3 = Fp.add(t1, Y3);
|
|
206332
|
-
Y3 = Fp.mul(X3, Y3);
|
|
206333
|
-
X3 = Fp.mul(t3, X3);
|
|
206334
|
-
Z3 = Fp.mul(b3, Z3);
|
|
206335
|
-
t2 = Fp.mul(a, t2);
|
|
206336
|
-
t3 = Fp.sub(t0, t2);
|
|
206337
|
-
t3 = Fp.mul(a, t3);
|
|
206338
|
-
t3 = Fp.add(t3, Z3);
|
|
206339
|
-
Z3 = Fp.add(t0, t0);
|
|
206340
|
-
t0 = Fp.add(Z3, t0);
|
|
206341
|
-
t0 = Fp.add(t0, t2);
|
|
206342
|
-
t0 = Fp.mul(t0, t3);
|
|
206343
|
-
Y3 = Fp.add(Y3, t0);
|
|
206344
|
-
t2 = Fp.mul(Y1, Z1);
|
|
206345
|
-
t2 = Fp.add(t2, t2);
|
|
206346
|
-
t0 = Fp.mul(t2, t3);
|
|
206347
|
-
X3 = Fp.sub(X3, t0);
|
|
206348
|
-
Z3 = Fp.mul(t2, t1);
|
|
206349
|
-
Z3 = Fp.add(Z3, Z3);
|
|
206350
|
-
Z3 = Fp.add(Z3, Z3);
|
|
206351
|
-
return new Point(X3, Y3, Z3);
|
|
206352
|
-
}
|
|
206353
|
-
add(other) {
|
|
206354
|
-
aprjpoint(other);
|
|
206355
|
-
const { X: X1, Y: Y1, Z: Z1 } = this;
|
|
206356
|
-
const { X: X2, Y: Y2, Z: Z2 } = other;
|
|
206357
|
-
let { ZERO: X3, ZERO: Y3, ZERO: Z3 } = Fp;
|
|
206358
|
-
const a = CURVE.a;
|
|
206359
|
-
const b3 = Fp.mul(CURVE.b, _3n2);
|
|
206360
|
-
let t0 = Fp.mul(X1, X2);
|
|
206361
|
-
let t1 = Fp.mul(Y1, Y2);
|
|
206362
|
-
let t2 = Fp.mul(Z1, Z2);
|
|
206363
|
-
let t3 = Fp.add(X1, Y1);
|
|
206364
|
-
let t4 = Fp.add(X2, Y2);
|
|
206365
|
-
t3 = Fp.mul(t3, t4);
|
|
206366
|
-
t4 = Fp.add(t0, t1);
|
|
206367
|
-
t3 = Fp.sub(t3, t4);
|
|
206368
|
-
t4 = Fp.add(X1, Z1);
|
|
206369
|
-
let t5 = Fp.add(X2, Z2);
|
|
206370
|
-
t4 = Fp.mul(t4, t5);
|
|
206371
|
-
t5 = Fp.add(t0, t2);
|
|
206372
|
-
t4 = Fp.sub(t4, t5);
|
|
206373
|
-
t5 = Fp.add(Y1, Z1);
|
|
206374
|
-
X3 = Fp.add(Y2, Z2);
|
|
206375
|
-
t5 = Fp.mul(t5, X3);
|
|
206376
|
-
X3 = Fp.add(t1, t2);
|
|
206377
|
-
t5 = Fp.sub(t5, X3);
|
|
206378
|
-
Z3 = Fp.mul(a, t4);
|
|
206379
|
-
X3 = Fp.mul(b3, t2);
|
|
206380
|
-
Z3 = Fp.add(X3, Z3);
|
|
206381
|
-
X3 = Fp.sub(t1, Z3);
|
|
206382
|
-
Z3 = Fp.add(t1, Z3);
|
|
206383
|
-
Y3 = Fp.mul(X3, Z3);
|
|
206384
|
-
t1 = Fp.add(t0, t0);
|
|
206385
|
-
t1 = Fp.add(t1, t0);
|
|
206386
|
-
t2 = Fp.mul(a, t2);
|
|
206387
|
-
t4 = Fp.mul(b3, t4);
|
|
206388
|
-
t1 = Fp.add(t1, t2);
|
|
206389
|
-
t2 = Fp.sub(t0, t2);
|
|
206390
|
-
t2 = Fp.mul(a, t2);
|
|
206391
|
-
t4 = Fp.add(t4, t2);
|
|
206392
|
-
t0 = Fp.mul(t1, t4);
|
|
206393
|
-
Y3 = Fp.add(Y3, t0);
|
|
206394
|
-
t0 = Fp.mul(t5, t4);
|
|
206395
|
-
X3 = Fp.mul(t3, X3);
|
|
206396
|
-
X3 = Fp.sub(X3, t0);
|
|
206397
|
-
t0 = Fp.mul(t3, t1);
|
|
206398
|
-
Z3 = Fp.mul(t5, Z3);
|
|
206399
|
-
Z3 = Fp.add(Z3, t0);
|
|
206400
|
-
return new Point(X3, Y3, Z3);
|
|
206401
|
-
}
|
|
206402
|
-
subtract(other) {
|
|
206403
|
-
return this.add(other.negate());
|
|
206404
|
-
}
|
|
206405
|
-
is0() {
|
|
206406
|
-
return this.equals(Point.ZERO);
|
|
206407
|
-
}
|
|
206408
|
-
multiply(scalar) {
|
|
206409
|
-
const { endo } = extraOpts;
|
|
206410
|
-
if (!Fn.isValidNot0(scalar))
|
|
206411
|
-
throw new Error("invalid scalar: out of range");
|
|
206412
|
-
let point, fake;
|
|
206413
|
-
const mul = (n) => wnaf.cached(this, n, (p) => normalizeZ(Point, p));
|
|
206414
|
-
if (endo) {
|
|
206415
|
-
const { k1neg, k1, k2neg, k2 } = splitEndoScalarN(scalar);
|
|
206416
|
-
const { p: k1p, f: k1f } = mul(k1);
|
|
206417
|
-
const { p: k2p, f: k2f } = mul(k2);
|
|
206418
|
-
fake = k1f.add(k2f);
|
|
206419
|
-
point = finishEndo(endo.beta, k1p, k2p, k1neg, k2neg);
|
|
206420
|
-
} else {
|
|
206421
|
-
const { p, f } = mul(scalar);
|
|
206422
|
-
point = p;
|
|
206423
|
-
fake = f;
|
|
206424
|
-
}
|
|
206425
|
-
return normalizeZ(Point, [point, fake])[0];
|
|
206426
|
-
}
|
|
206427
|
-
multiplyUnsafe(sc) {
|
|
206428
|
-
const { endo } = extraOpts;
|
|
206429
|
-
const p = this;
|
|
206430
|
-
if (!Fn.isValid(sc))
|
|
206431
|
-
throw new Error("invalid scalar: out of range");
|
|
206432
|
-
if (sc === _0n4 || p.is0())
|
|
206433
|
-
return Point.ZERO;
|
|
206434
|
-
if (sc === _1n4)
|
|
206435
|
-
return p;
|
|
206436
|
-
if (wnaf.hasCache(this))
|
|
206437
|
-
return this.multiply(sc);
|
|
206438
|
-
if (endo) {
|
|
206439
|
-
const { k1neg, k1, k2neg, k2 } = splitEndoScalarN(sc);
|
|
206440
|
-
const { p1, p2 } = mulEndoUnsafe(Point, p, k1, k2);
|
|
206441
|
-
return finishEndo(endo.beta, p1, p2, k1neg, k2neg);
|
|
206442
|
-
} else {
|
|
206443
|
-
return wnaf.unsafe(p, sc);
|
|
206444
|
-
}
|
|
206445
|
-
}
|
|
206446
|
-
toAffine(invertedZ) {
|
|
206447
|
-
return toAffineMemo(this, invertedZ);
|
|
206448
|
-
}
|
|
206449
|
-
isTorsionFree() {
|
|
206450
|
-
const { isTorsionFree } = extraOpts;
|
|
206451
|
-
if (cofactor === _1n4)
|
|
206452
|
-
return true;
|
|
206453
|
-
if (isTorsionFree)
|
|
206454
|
-
return isTorsionFree(Point, this);
|
|
206455
|
-
return wnaf.unsafe(this, CURVE_ORDER).is0();
|
|
206456
|
-
}
|
|
206457
|
-
clearCofactor() {
|
|
206458
|
-
const { clearCofactor } = extraOpts;
|
|
206459
|
-
if (cofactor === _1n4)
|
|
206460
|
-
return this;
|
|
206461
|
-
if (clearCofactor)
|
|
206462
|
-
return clearCofactor(Point, this);
|
|
206463
|
-
return this.multiplyUnsafe(cofactor);
|
|
206464
|
-
}
|
|
206465
|
-
isSmallOrder() {
|
|
206466
|
-
return this.multiplyUnsafe(cofactor).is0();
|
|
206467
|
-
}
|
|
206468
|
-
toBytes(isCompressed = true) {
|
|
206469
|
-
abool(isCompressed, "isCompressed");
|
|
206470
|
-
this.assertValidity();
|
|
206471
|
-
return encodePoint(Point, this, isCompressed);
|
|
206472
|
-
}
|
|
206473
|
-
toHex(isCompressed = true) {
|
|
206474
|
-
return bytesToHex(this.toBytes(isCompressed));
|
|
206475
|
-
}
|
|
206476
|
-
toString() {
|
|
206477
|
-
return `<Point ${this.is0() ? "ZERO" : this.toHex()}>`;
|
|
206478
|
-
}
|
|
206479
|
-
}
|
|
206480
|
-
const bits = Fn.BITS;
|
|
206481
|
-
const wnaf = new wNAF(Point, extraOpts.endo ? Math.ceil(bits / 2) : bits);
|
|
206482
|
-
Point.BASE.precompute(8);
|
|
206483
|
-
return Point;
|
|
206484
|
-
}
|
|
206485
|
-
function pprefix(hasEvenY) {
|
|
206486
|
-
return Uint8Array.of(hasEvenY ? 2 : 3);
|
|
206487
|
-
}
|
|
206488
|
-
function getWLengths(Fp, Fn) {
|
|
206489
|
-
return {
|
|
206490
|
-
secretKey: Fn.BYTES,
|
|
206491
|
-
publicKey: 1 + Fp.BYTES,
|
|
206492
|
-
publicKeyUncompressed: 1 + 2 * Fp.BYTES,
|
|
206493
|
-
publicKeyHasPrefix: true,
|
|
206494
|
-
signature: 2 * Fn.BYTES
|
|
206495
|
-
};
|
|
206496
|
-
}
|
|
206497
|
-
function ecdh(Point, ecdhOpts = {}) {
|
|
206498
|
-
const { Fn } = Point;
|
|
206499
|
-
const randomBytes_ = ecdhOpts.randomBytes || randomBytes;
|
|
206500
|
-
const lengths = Object.assign(getWLengths(Point.Fp, Fn), { seed: getMinHashLength(Fn.ORDER) });
|
|
206501
|
-
function isValidSecretKey(secretKey) {
|
|
206502
|
-
try {
|
|
206503
|
-
const num = Fn.fromBytes(secretKey);
|
|
206504
|
-
return Fn.isValidNot0(num);
|
|
206505
|
-
} catch (error) {
|
|
206506
|
-
return false;
|
|
206507
|
-
}
|
|
206508
|
-
}
|
|
206509
|
-
function isValidPublicKey(publicKey, isCompressed) {
|
|
206510
|
-
const { publicKey: comp, publicKeyUncompressed } = lengths;
|
|
206511
|
-
try {
|
|
206512
|
-
const l = publicKey.length;
|
|
206513
|
-
if (isCompressed === true && l !== comp)
|
|
206514
|
-
return false;
|
|
206515
|
-
if (isCompressed === false && l !== publicKeyUncompressed)
|
|
206516
|
-
return false;
|
|
206517
|
-
return !!Point.fromBytes(publicKey);
|
|
206518
|
-
} catch (error) {
|
|
206519
|
-
return false;
|
|
206520
|
-
}
|
|
206521
|
-
}
|
|
206522
|
-
function randomSecretKey(seed = randomBytes_(lengths.seed)) {
|
|
206523
|
-
return mapHashToField(abytes(seed, lengths.seed, "seed"), Fn.ORDER);
|
|
206524
|
-
}
|
|
206525
|
-
function getPublicKey(secretKey, isCompressed = true) {
|
|
206526
|
-
return Point.BASE.multiply(Fn.fromBytes(secretKey)).toBytes(isCompressed);
|
|
206527
|
-
}
|
|
206528
|
-
function isProbPub(item) {
|
|
206529
|
-
const { secretKey, publicKey, publicKeyUncompressed } = lengths;
|
|
206530
|
-
if (!isBytes(item))
|
|
206531
|
-
return;
|
|
206532
|
-
if ("_lengths" in Fn && Fn._lengths || secretKey === publicKey)
|
|
206533
|
-
return;
|
|
206534
|
-
const l = abytes(item, undefined, "key").length;
|
|
206535
|
-
return l === publicKey || l === publicKeyUncompressed;
|
|
206536
|
-
}
|
|
206537
|
-
function getSharedSecret(secretKeyA, publicKeyB, isCompressed = true) {
|
|
206538
|
-
if (isProbPub(secretKeyA) === true)
|
|
206539
|
-
throw new Error("first arg must be private key");
|
|
206540
|
-
if (isProbPub(publicKeyB) === false)
|
|
206541
|
-
throw new Error("second arg must be public key");
|
|
206542
|
-
const s = Fn.fromBytes(secretKeyA);
|
|
206543
|
-
const b = Point.fromBytes(publicKeyB);
|
|
206544
|
-
return b.multiply(s).toBytes(isCompressed);
|
|
206545
|
-
}
|
|
206546
|
-
const utils = {
|
|
206547
|
-
isValidSecretKey,
|
|
206548
|
-
isValidPublicKey,
|
|
206549
|
-
randomSecretKey
|
|
206550
|
-
};
|
|
206551
|
-
const keygen = createKeygen(randomSecretKey, getPublicKey);
|
|
206552
|
-
return Object.freeze({ getPublicKey, getSharedSecret, keygen, Point, utils, lengths });
|
|
206553
|
-
}
|
|
206554
|
-
function ecdsa(Point, hash, ecdsaOpts = {}) {
|
|
206555
|
-
ahash(hash);
|
|
206556
|
-
validateObject(ecdsaOpts, {}, {
|
|
206557
|
-
hmac: "function",
|
|
206558
|
-
lowS: "boolean",
|
|
206559
|
-
randomBytes: "function",
|
|
206560
|
-
bits2int: "function",
|
|
206561
|
-
bits2int_modN: "function"
|
|
206562
|
-
});
|
|
206563
|
-
ecdsaOpts = Object.assign({}, ecdsaOpts);
|
|
206564
|
-
const randomBytes2 = ecdsaOpts.randomBytes || randomBytes;
|
|
206565
|
-
const hmac2 = ecdsaOpts.hmac || ((key, msg) => hmac(hash, key, msg));
|
|
206566
|
-
const { Fp, Fn } = Point;
|
|
206567
|
-
const { ORDER: CURVE_ORDER, BITS: fnBits } = Fn;
|
|
206568
|
-
const { keygen, getPublicKey, getSharedSecret, utils, lengths } = ecdh(Point, ecdsaOpts);
|
|
206569
|
-
const defaultSigOpts = {
|
|
206570
|
-
prehash: true,
|
|
206571
|
-
lowS: typeof ecdsaOpts.lowS === "boolean" ? ecdsaOpts.lowS : true,
|
|
206572
|
-
format: "compact",
|
|
206573
|
-
extraEntropy: false
|
|
206574
|
-
};
|
|
206575
|
-
const hasLargeCofactor = CURVE_ORDER * _2n2 < Fp.ORDER;
|
|
206576
|
-
function isBiggerThanHalfOrder(number) {
|
|
206577
|
-
const HALF = CURVE_ORDER >> _1n4;
|
|
206578
|
-
return number > HALF;
|
|
206579
|
-
}
|
|
206580
|
-
function validateRS(title, num) {
|
|
206581
|
-
if (!Fn.isValidNot0(num))
|
|
206582
|
-
throw new Error(`invalid signature ${title}: out of range 1..Point.Fn.ORDER`);
|
|
206583
|
-
return num;
|
|
206584
|
-
}
|
|
206585
|
-
function assertSmallCofactor() {
|
|
206586
|
-
if (hasLargeCofactor)
|
|
206587
|
-
throw new Error('"recovered" sig type is not supported for cofactor >2 curves');
|
|
206588
|
-
}
|
|
206589
|
-
function validateSigLength(bytes, format) {
|
|
206590
|
-
validateSigFormat(format);
|
|
206591
|
-
const size = lengths.signature;
|
|
206592
|
-
const sizer = format === "compact" ? size : format === "recovered" ? size + 1 : undefined;
|
|
206593
|
-
return abytes(bytes, sizer);
|
|
206594
|
-
}
|
|
206595
|
-
|
|
206596
|
-
class Signature {
|
|
206597
|
-
r;
|
|
206598
|
-
s;
|
|
206599
|
-
recovery;
|
|
206600
|
-
constructor(r, s, recovery) {
|
|
206601
|
-
this.r = validateRS("r", r);
|
|
206602
|
-
this.s = validateRS("s", s);
|
|
206603
|
-
if (recovery != null) {
|
|
206604
|
-
assertSmallCofactor();
|
|
206605
|
-
if (![0, 1, 2, 3].includes(recovery))
|
|
206606
|
-
throw new Error("invalid recovery id");
|
|
206607
|
-
this.recovery = recovery;
|
|
206608
|
-
}
|
|
206609
|
-
Object.freeze(this);
|
|
206610
|
-
}
|
|
206611
|
-
static fromBytes(bytes, format = defaultSigOpts.format) {
|
|
206612
|
-
validateSigLength(bytes, format);
|
|
206613
|
-
let recid;
|
|
206614
|
-
if (format === "der") {
|
|
206615
|
-
const { r, s } = DER.toSig(abytes(bytes));
|
|
206616
|
-
return new Signature(r, s);
|
|
206617
|
-
}
|
|
206618
|
-
if (format === "recovered") {
|
|
206619
|
-
recid = bytes[0];
|
|
206620
|
-
format = "compact";
|
|
206621
|
-
bytes = bytes.subarray(1);
|
|
206622
|
-
}
|
|
206623
|
-
const L = lengths.signature / 2;
|
|
206624
|
-
const r = bytes.subarray(0, L);
|
|
206625
|
-
const s = bytes.subarray(L, L * 2);
|
|
206626
|
-
return new Signature(Fn.fromBytes(r), Fn.fromBytes(s), recid);
|
|
206627
|
-
}
|
|
206628
|
-
static fromHex(hex, format) {
|
|
206629
|
-
return this.fromBytes(hexToBytes(hex), format);
|
|
206630
|
-
}
|
|
206631
|
-
assertRecovery() {
|
|
206632
|
-
const { recovery } = this;
|
|
206633
|
-
if (recovery == null)
|
|
206634
|
-
throw new Error("invalid recovery id: must be present");
|
|
206635
|
-
return recovery;
|
|
206636
|
-
}
|
|
206637
|
-
addRecoveryBit(recovery) {
|
|
206638
|
-
return new Signature(this.r, this.s, recovery);
|
|
206639
|
-
}
|
|
206640
|
-
recoverPublicKey(messageHash) {
|
|
206641
|
-
const { r, s } = this;
|
|
206642
|
-
const recovery = this.assertRecovery();
|
|
206643
|
-
const radj = recovery === 2 || recovery === 3 ? r + CURVE_ORDER : r;
|
|
206644
|
-
if (!Fp.isValid(radj))
|
|
206645
|
-
throw new Error("invalid recovery id: sig.r+curve.n != R.x");
|
|
206646
|
-
const x = Fp.toBytes(radj);
|
|
206647
|
-
const R = Point.fromBytes(concatBytes(pprefix((recovery & 1) === 0), x));
|
|
206648
|
-
const ir = Fn.inv(radj);
|
|
206649
|
-
const h = bits2int_modN(abytes(messageHash, undefined, "msgHash"));
|
|
206650
|
-
const u1 = Fn.create(-h * ir);
|
|
206651
|
-
const u2 = Fn.create(s * ir);
|
|
206652
|
-
const Q = Point.BASE.multiplyUnsafe(u1).add(R.multiplyUnsafe(u2));
|
|
206653
|
-
if (Q.is0())
|
|
206654
|
-
throw new Error("invalid recovery: point at infinify");
|
|
206655
|
-
Q.assertValidity();
|
|
206656
|
-
return Q;
|
|
206657
|
-
}
|
|
206658
|
-
hasHighS() {
|
|
206659
|
-
return isBiggerThanHalfOrder(this.s);
|
|
206660
|
-
}
|
|
206661
|
-
toBytes(format = defaultSigOpts.format) {
|
|
206662
|
-
validateSigFormat(format);
|
|
206663
|
-
if (format === "der")
|
|
206664
|
-
return hexToBytes(DER.hexFromSig(this));
|
|
206665
|
-
const { r, s } = this;
|
|
206666
|
-
const rb = Fn.toBytes(r);
|
|
206667
|
-
const sb = Fn.toBytes(s);
|
|
206668
|
-
if (format === "recovered") {
|
|
206669
|
-
assertSmallCofactor();
|
|
206670
|
-
return concatBytes(Uint8Array.of(this.assertRecovery()), rb, sb);
|
|
206671
|
-
}
|
|
206672
|
-
return concatBytes(rb, sb);
|
|
206673
|
-
}
|
|
206674
|
-
toHex(format) {
|
|
206675
|
-
return bytesToHex(this.toBytes(format));
|
|
206676
|
-
}
|
|
206677
|
-
}
|
|
206678
|
-
const bits2int = ecdsaOpts.bits2int || function bits2int_def(bytes) {
|
|
206679
|
-
if (bytes.length > 8192)
|
|
206680
|
-
throw new Error("input is too large");
|
|
206681
|
-
const num = bytesToNumberBE(bytes);
|
|
206682
|
-
const delta = bytes.length * 8 - fnBits;
|
|
206683
|
-
return delta > 0 ? num >> BigInt(delta) : num;
|
|
206684
|
-
};
|
|
206685
|
-
const bits2int_modN = ecdsaOpts.bits2int_modN || function bits2int_modN_def(bytes) {
|
|
206686
|
-
return Fn.create(bits2int(bytes));
|
|
206687
|
-
};
|
|
206688
|
-
const ORDER_MASK = bitMask(fnBits);
|
|
206689
|
-
function int2octets(num) {
|
|
206690
|
-
aInRange("num < 2^" + fnBits, num, _0n4, ORDER_MASK);
|
|
206691
|
-
return Fn.toBytes(num);
|
|
206692
|
-
}
|
|
206693
|
-
function validateMsgAndHash(message, prehash) {
|
|
206694
|
-
abytes(message, undefined, "message");
|
|
206695
|
-
return prehash ? abytes(hash(message), undefined, "prehashed message") : message;
|
|
206696
|
-
}
|
|
206697
|
-
function prepSig(message, secretKey, opts) {
|
|
206698
|
-
const { lowS, prehash, extraEntropy } = validateSigOpts(opts, defaultSigOpts);
|
|
206699
|
-
message = validateMsgAndHash(message, prehash);
|
|
206700
|
-
const h1int = bits2int_modN(message);
|
|
206701
|
-
const d = Fn.fromBytes(secretKey);
|
|
206702
|
-
if (!Fn.isValidNot0(d))
|
|
206703
|
-
throw new Error("invalid private key");
|
|
206704
|
-
const seedArgs = [int2octets(d), int2octets(h1int)];
|
|
206705
|
-
if (extraEntropy != null && extraEntropy !== false) {
|
|
206706
|
-
const e = extraEntropy === true ? randomBytes2(lengths.secretKey) : extraEntropy;
|
|
206707
|
-
seedArgs.push(abytes(e, undefined, "extraEntropy"));
|
|
206708
|
-
}
|
|
206709
|
-
const seed = concatBytes(...seedArgs);
|
|
206710
|
-
const m = h1int;
|
|
206711
|
-
function k2sig(kBytes) {
|
|
206712
|
-
const k = bits2int(kBytes);
|
|
206713
|
-
if (!Fn.isValidNot0(k))
|
|
206714
|
-
return;
|
|
206715
|
-
const ik = Fn.inv(k);
|
|
206716
|
-
const q = Point.BASE.multiply(k).toAffine();
|
|
206717
|
-
const r = Fn.create(q.x);
|
|
206718
|
-
if (r === _0n4)
|
|
206719
|
-
return;
|
|
206720
|
-
const s = Fn.create(ik * Fn.create(m + r * d));
|
|
206721
|
-
if (s === _0n4)
|
|
206722
|
-
return;
|
|
206723
|
-
let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n4);
|
|
206724
|
-
let normS = s;
|
|
206725
|
-
if (lowS && isBiggerThanHalfOrder(s)) {
|
|
206726
|
-
normS = Fn.neg(s);
|
|
206727
|
-
recovery ^= 1;
|
|
206728
|
-
}
|
|
206729
|
-
return new Signature(r, normS, hasLargeCofactor ? undefined : recovery);
|
|
206730
|
-
}
|
|
206731
|
-
return { seed, k2sig };
|
|
206732
|
-
}
|
|
206733
|
-
function sign(message, secretKey, opts = {}) {
|
|
206734
|
-
const { seed, k2sig } = prepSig(message, secretKey, opts);
|
|
206735
|
-
const drbg = createHmacDrbg(hash.outputLen, Fn.BYTES, hmac2);
|
|
206736
|
-
const sig = drbg(seed, k2sig);
|
|
206737
|
-
return sig.toBytes(opts.format);
|
|
206738
|
-
}
|
|
206739
|
-
function verify(signature, message, publicKey, opts = {}) {
|
|
206740
|
-
const { lowS, prehash, format } = validateSigOpts(opts, defaultSigOpts);
|
|
206741
|
-
publicKey = abytes(publicKey, undefined, "publicKey");
|
|
206742
|
-
message = validateMsgAndHash(message, prehash);
|
|
206743
|
-
if (!isBytes(signature)) {
|
|
206744
|
-
const end = signature instanceof Signature ? ", use sig.toBytes()" : "";
|
|
206745
|
-
throw new Error("verify expects Uint8Array signature" + end);
|
|
206746
|
-
}
|
|
206747
|
-
validateSigLength(signature, format);
|
|
206748
|
-
try {
|
|
206749
|
-
const sig = Signature.fromBytes(signature, format);
|
|
206750
|
-
const P = Point.fromBytes(publicKey);
|
|
206751
|
-
if (lowS && sig.hasHighS())
|
|
206752
|
-
return false;
|
|
206753
|
-
const { r, s } = sig;
|
|
206754
|
-
const h = bits2int_modN(message);
|
|
206755
|
-
const is = Fn.inv(s);
|
|
206756
|
-
const u1 = Fn.create(h * is);
|
|
206757
|
-
const u2 = Fn.create(r * is);
|
|
206758
|
-
const R = Point.BASE.multiplyUnsafe(u1).add(P.multiplyUnsafe(u2));
|
|
206759
|
-
if (R.is0())
|
|
206760
|
-
return false;
|
|
206761
|
-
const v = Fn.create(R.x);
|
|
206762
|
-
return v === r;
|
|
206763
|
-
} catch (e) {
|
|
206764
|
-
return false;
|
|
206765
|
-
}
|
|
206766
|
-
}
|
|
206767
|
-
function recoverPublicKey(signature, message, opts = {}) {
|
|
206768
|
-
const { prehash } = validateSigOpts(opts, defaultSigOpts);
|
|
206769
|
-
message = validateMsgAndHash(message, prehash);
|
|
206770
|
-
return Signature.fromBytes(signature, "recovered").recoverPublicKey(message).toBytes();
|
|
206771
|
-
}
|
|
206772
|
-
return Object.freeze({
|
|
206773
|
-
keygen,
|
|
206774
|
-
getPublicKey,
|
|
206775
|
-
getSharedSecret,
|
|
206776
|
-
utils,
|
|
206777
|
-
lengths,
|
|
206778
|
-
Point,
|
|
206779
|
-
sign,
|
|
206780
|
-
verify,
|
|
206781
|
-
recoverPublicKey,
|
|
206782
|
-
Signature,
|
|
206783
|
-
hash
|
|
206784
|
-
});
|
|
206785
|
-
}
|
|
206786
|
-
|
|
206787
|
-
// ../../node_modules/@noble/curves/secp256k1.js
|
|
206788
|
-
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
206789
|
-
var secp256k1_CURVE = {
|
|
206790
|
-
p: BigInt("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"),
|
|
206791
|
-
n: BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"),
|
|
206792
|
-
h: BigInt(1),
|
|
206793
|
-
a: BigInt(0),
|
|
206794
|
-
b: BigInt(7),
|
|
206795
|
-
Gx: BigInt("0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"),
|
|
206796
|
-
Gy: BigInt("0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8")
|
|
206797
|
-
};
|
|
206798
|
-
var secp256k1_ENDO = {
|
|
206799
|
-
beta: BigInt("0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee"),
|
|
206800
|
-
basises: [
|
|
206801
|
-
[BigInt("0x3086d221a7d46bcde86c90e49284eb15"), -BigInt("0xe4437ed6010e88286f547fa90abfe4c3")],
|
|
206802
|
-
[BigInt("0x114ca50f7a8e2f3f657c1108d9d44cfd8"), BigInt("0x3086d221a7d46bcde86c90e49284eb15")]
|
|
206803
|
-
]
|
|
206804
|
-
};
|
|
206805
|
-
var _2n3 = /* @__PURE__ */ BigInt(2);
|
|
206806
|
-
function sqrtMod(y) {
|
|
206807
|
-
const P = secp256k1_CURVE.p;
|
|
206808
|
-
const _3n = BigInt(3), _6n = BigInt(6), _11n = BigInt(11), _22n = BigInt(22);
|
|
206809
|
-
const _23n = BigInt(23), _44n = BigInt(44), _88n = BigInt(88);
|
|
206810
|
-
const b2 = y * y * y % P;
|
|
206811
|
-
const b3 = b2 * b2 * y % P;
|
|
206812
|
-
const b6 = pow2(b3, _3n, P) * b3 % P;
|
|
206813
|
-
const b9 = pow2(b6, _3n, P) * b3 % P;
|
|
206814
|
-
const b11 = pow2(b9, _2n3, P) * b2 % P;
|
|
206815
|
-
const b22 = pow2(b11, _11n, P) * b11 % P;
|
|
206816
|
-
const b44 = pow2(b22, _22n, P) * b22 % P;
|
|
206817
|
-
const b88 = pow2(b44, _44n, P) * b44 % P;
|
|
206818
|
-
const b176 = pow2(b88, _88n, P) * b88 % P;
|
|
206819
|
-
const b220 = pow2(b176, _44n, P) * b44 % P;
|
|
206820
|
-
const b223 = pow2(b220, _3n, P) * b3 % P;
|
|
206821
|
-
const t1 = pow2(b223, _23n, P) * b22 % P;
|
|
206822
|
-
const t2 = pow2(t1, _6n, P) * b2 % P;
|
|
206823
|
-
const root = pow2(t2, _2n3, P);
|
|
206824
|
-
if (!Fpk1.eql(Fpk1.sqr(root), y))
|
|
206825
|
-
throw new Error("Cannot find square root");
|
|
206826
|
-
return root;
|
|
206827
|
-
}
|
|
206828
|
-
var Fpk1 = Field(secp256k1_CURVE.p, { sqrt: sqrtMod });
|
|
206829
|
-
var Pointk1 = /* @__PURE__ */ weierstrass(secp256k1_CURVE, {
|
|
206830
|
-
Fp: Fpk1,
|
|
206831
|
-
endo: secp256k1_ENDO
|
|
206832
|
-
});
|
|
206833
|
-
var secp256k1 = /* @__PURE__ */ ecdsa(Pointk1, sha256);
|
|
206834
|
-
|
|
206835
|
-
// ../verify/src/signers.ts
|
|
206836
|
-
import { deserializeCV } from "@secondlayer/stacks/clarity";
|
|
206837
|
-
import { c32address, hash160 } from "@secondlayer/stacks/utils";
|
|
206838
|
-
var MAINNET_P2PKH = 22;
|
|
206839
|
-
var SIGNERS_CONTRACT = "SP000000000000000000002Q6VF78.signers";
|
|
206840
|
-
function decodeSignerSet(value) {
|
|
206841
|
-
const cv = deserializeCV(typeof value === "string" ? value : hex(value));
|
|
206842
|
-
if (cv.type !== "some" || cv.value.type !== "list")
|
|
206843
|
-
throw new Error("signer set must be (some (list ...))");
|
|
206844
|
-
const set = new Map;
|
|
206845
|
-
for (const entry of cv.value.value) {
|
|
206846
|
-
if (entry.type !== "tuple")
|
|
206847
|
-
throw new Error("signer entry must be a tuple");
|
|
206848
|
-
const { signer, weight } = entry.value;
|
|
206849
|
-
if (signer?.type !== "address" || weight?.type !== "uint")
|
|
206850
|
-
throw new Error("signer entry needs (signer principal) (weight uint)");
|
|
206851
|
-
if (set.has(signer.value))
|
|
206852
|
-
throw new Error(`duplicate signer ${signer.value}`);
|
|
206853
|
-
set.set(signer.value, BigInt(weight.value));
|
|
206854
|
-
}
|
|
206855
|
-
return set;
|
|
206856
|
-
}
|
|
206857
|
-
function verifySignerSignatures(header, set) {
|
|
206858
|
-
const msg = signerSignatureHash(header);
|
|
206859
|
-
let totalWeight = 0n;
|
|
206860
|
-
for (const w of set.values())
|
|
206861
|
-
totalWeight += w;
|
|
206862
|
-
const threshold = (totalWeight * 7n + 9n) / 10n;
|
|
206863
|
-
const out = {
|
|
206864
|
-
valid: false,
|
|
206865
|
-
signedWeight: 0n,
|
|
206866
|
-
totalWeight,
|
|
206867
|
-
threshold,
|
|
206868
|
-
signers: [],
|
|
206869
|
-
unknown: [],
|
|
206870
|
-
duplicates: [],
|
|
206871
|
-
invalid: 0
|
|
206872
|
-
};
|
|
206873
|
-
const seen = new Set;
|
|
206874
|
-
for (const sig of header.signerSignatures) {
|
|
206875
|
-
const who = recoverSigner(msg, sig);
|
|
206876
|
-
if (!who)
|
|
206877
|
-
out.invalid++;
|
|
206878
|
-
else if (seen.has(who))
|
|
206879
|
-
out.duplicates.push(who);
|
|
206880
|
-
else {
|
|
206881
|
-
seen.add(who);
|
|
206882
|
-
const weight = set.get(who);
|
|
206883
|
-
if (weight === undefined)
|
|
206884
|
-
out.unknown.push(who);
|
|
206885
|
-
else {
|
|
206886
|
-
out.signers.push(who);
|
|
206887
|
-
out.signedWeight += weight;
|
|
206888
|
-
}
|
|
206889
|
-
}
|
|
206890
|
-
}
|
|
206891
|
-
out.valid = totalWeight > 0n && out.signedWeight >= threshold && out.unknown.length === 0 && out.duplicates.length === 0 && out.invalid === 0;
|
|
206892
|
-
return out;
|
|
206893
|
-
}
|
|
206894
|
-
function recoverSigner(msg, sig) {
|
|
206895
|
-
try {
|
|
206896
|
-
const s = secp256k1.Signature.fromBytes(sig, "recovered");
|
|
206897
|
-
if (s.hasHighS())
|
|
206898
|
-
return null;
|
|
206899
|
-
const pubkey = s.recoverPublicKey(msg).toBytes(true);
|
|
206900
|
-
return c32address(MAINNET_P2PKH, hex(hash160(pubkey)));
|
|
206901
|
-
} catch {
|
|
206902
|
-
return null;
|
|
206903
|
-
}
|
|
206904
|
-
}
|
|
206905
|
-
// ../../node_modules/@noble/hashes/legacy.js
|
|
206906
|
-
var Rho160 = /* @__PURE__ */ Uint8Array.from([
|
|
206907
|
-
7,
|
|
206908
|
-
4,
|
|
206909
|
-
13,
|
|
206910
|
-
1,
|
|
206911
|
-
10,
|
|
206912
|
-
6,
|
|
206913
|
-
15,
|
|
206914
|
-
3,
|
|
206915
|
-
12,
|
|
206916
|
-
0,
|
|
206917
|
-
9,
|
|
206918
|
-
5,
|
|
206919
|
-
2,
|
|
206920
|
-
14,
|
|
206921
|
-
11,
|
|
206922
|
-
8
|
|
206923
|
-
]);
|
|
206924
|
-
var Id160 = /* @__PURE__ */ (() => Uint8Array.from(new Array(16).fill(0).map((_, i) => i)))();
|
|
206925
|
-
var Pi160 = /* @__PURE__ */ (() => Id160.map((i) => (9 * i + 5) % 16))();
|
|
206926
|
-
var idxLR = /* @__PURE__ */ (() => {
|
|
206927
|
-
const L = [Id160];
|
|
206928
|
-
const R = [Pi160];
|
|
206929
|
-
const res = [L, R];
|
|
206930
|
-
for (let i = 0;i < 4; i++)
|
|
206931
|
-
for (let j of res)
|
|
206932
|
-
j.push(j[i].map((k) => Rho160[k]));
|
|
206933
|
-
return res;
|
|
206934
|
-
})();
|
|
206935
|
-
var idxL = /* @__PURE__ */ (() => idxLR[0])();
|
|
206936
|
-
var idxR = /* @__PURE__ */ (() => idxLR[1])();
|
|
206937
|
-
var shifts160 = /* @__PURE__ */ [
|
|
206938
|
-
[11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8],
|
|
206939
|
-
[12, 13, 11, 15, 6, 9, 9, 7, 12, 15, 11, 13, 7, 8, 7, 7],
|
|
206940
|
-
[13, 15, 14, 11, 7, 7, 6, 8, 13, 14, 13, 12, 5, 5, 6, 9],
|
|
206941
|
-
[14, 11, 12, 14, 8, 6, 5, 5, 15, 12, 15, 14, 9, 9, 8, 6],
|
|
206942
|
-
[15, 12, 13, 13, 9, 5, 8, 6, 14, 11, 12, 11, 8, 6, 5, 5]
|
|
206943
|
-
].map((i) => Uint8Array.from(i));
|
|
206944
|
-
var shiftsL160 = /* @__PURE__ */ idxL.map((idx, i) => idx.map((j) => shifts160[i][j]));
|
|
206945
|
-
var shiftsR160 = /* @__PURE__ */ idxR.map((idx, i) => idx.map((j) => shifts160[i][j]));
|
|
206946
|
-
var Kl160 = /* @__PURE__ */ Uint32Array.from([
|
|
206947
|
-
0,
|
|
206948
|
-
1518500249,
|
|
206949
|
-
1859775393,
|
|
206950
|
-
2400959708,
|
|
206951
|
-
2840853838
|
|
206952
|
-
]);
|
|
206953
|
-
var Kr160 = /* @__PURE__ */ Uint32Array.from([
|
|
206954
|
-
1352829926,
|
|
206955
|
-
1548603684,
|
|
206956
|
-
1836072691,
|
|
206957
|
-
2053994217,
|
|
206958
|
-
0
|
|
206959
|
-
]);
|
|
206960
|
-
function ripemd_f(group, x, y, z) {
|
|
206961
|
-
if (group === 0)
|
|
206962
|
-
return x ^ y ^ z;
|
|
206963
|
-
if (group === 1)
|
|
206964
|
-
return x & y | ~x & z;
|
|
206965
|
-
if (group === 2)
|
|
206966
|
-
return (x | ~y) ^ z;
|
|
206967
|
-
if (group === 3)
|
|
206968
|
-
return x & z | y & ~z;
|
|
206969
|
-
return x ^ (y | ~z);
|
|
206970
|
-
}
|
|
206971
|
-
var BUF_160 = /* @__PURE__ */ new Uint32Array(16);
|
|
206972
|
-
|
|
206973
|
-
class _RIPEMD160 extends HashMD {
|
|
206974
|
-
h0 = 1732584193 | 0;
|
|
206975
|
-
h1 = 4023233417 | 0;
|
|
206976
|
-
h2 = 2562383102 | 0;
|
|
206977
|
-
h3 = 271733878 | 0;
|
|
206978
|
-
h4 = 3285377520 | 0;
|
|
206979
|
-
constructor() {
|
|
206980
|
-
super(64, 20, 8, true);
|
|
206981
|
-
}
|
|
206982
|
-
get() {
|
|
206983
|
-
const { h0, h1, h2, h3, h4 } = this;
|
|
206984
|
-
return [h0, h1, h2, h3, h4];
|
|
206985
|
-
}
|
|
206986
|
-
set(h0, h1, h2, h3, h4) {
|
|
206987
|
-
this.h0 = h0 | 0;
|
|
206988
|
-
this.h1 = h1 | 0;
|
|
206989
|
-
this.h2 = h2 | 0;
|
|
206990
|
-
this.h3 = h3 | 0;
|
|
206991
|
-
this.h4 = h4 | 0;
|
|
206992
|
-
}
|
|
206993
|
-
process(view, offset) {
|
|
206994
|
-
for (let i = 0;i < 16; i++, offset += 4)
|
|
206995
|
-
BUF_160[i] = view.getUint32(offset, true);
|
|
206996
|
-
let al = this.h0 | 0, ar = al, bl = this.h1 | 0, br = bl, cl = this.h2 | 0, cr = cl, dl = this.h3 | 0, dr = dl, el = this.h4 | 0, er = el;
|
|
206997
|
-
for (let group = 0;group < 5; group++) {
|
|
206998
|
-
const rGroup = 4 - group;
|
|
206999
|
-
const hbl = Kl160[group], hbr = Kr160[group];
|
|
207000
|
-
const rl = idxL[group], rr = idxR[group];
|
|
207001
|
-
const sl = shiftsL160[group], sr = shiftsR160[group];
|
|
207002
|
-
for (let i = 0;i < 16; i++) {
|
|
207003
|
-
const tl = rotl(al + ripemd_f(group, bl, cl, dl) + BUF_160[rl[i]] + hbl, sl[i]) + el | 0;
|
|
207004
|
-
al = el, el = dl, dl = rotl(cl, 10) | 0, cl = bl, bl = tl;
|
|
207005
|
-
}
|
|
207006
|
-
for (let i = 0;i < 16; i++) {
|
|
207007
|
-
const tr = rotl(ar + ripemd_f(rGroup, br, cr, dr) + BUF_160[rr[i]] + hbr, sr[i]) + er | 0;
|
|
207008
|
-
ar = er, er = dr, dr = rotl(cr, 10) | 0, cr = br, br = tr;
|
|
207009
|
-
}
|
|
207010
|
-
}
|
|
207011
|
-
this.set(this.h1 + cl + dr | 0, this.h2 + dl + er | 0, this.h3 + el + ar | 0, this.h4 + al + br | 0, this.h0 + bl + cr | 0);
|
|
207012
|
-
}
|
|
207013
|
-
roundClean() {
|
|
207014
|
-
clean(BUF_160);
|
|
207015
|
-
}
|
|
207016
|
-
destroy() {
|
|
207017
|
-
this.destroyed = true;
|
|
207018
|
-
clean(this.buffer);
|
|
207019
|
-
this.set(0, 0, 0, 0, 0);
|
|
207020
|
-
}
|
|
207021
|
-
}
|
|
207022
|
-
var ripemd160 = /* @__PURE__ */ createHasher(() => new _RIPEMD160);
|
|
207023
|
-
|
|
207024
|
-
// ../verify/src/burn.ts
|
|
207025
|
-
var PREIMAGE_PREFIX = Uint8Array.of(23, 0, 0, 0);
|
|
207026
|
-
var BHH_START = 4;
|
|
207027
|
-
var BHH_END = 36;
|
|
207028
|
-
function verifyConsensusPreimage(consensusHash, preimage) {
|
|
207029
|
-
if (consensusHash.length !== 20 || preimage.length < BHH_END)
|
|
207030
|
-
return null;
|
|
207031
|
-
if (!bytesEqual(preimage.subarray(0, BHH_START), PREIMAGE_PREFIX))
|
|
207032
|
-
return null;
|
|
207033
|
-
if (!bytesEqual(ripemd160(sha256(preimage)), consensusHash))
|
|
207034
|
-
return null;
|
|
207035
|
-
return hex(preimage.subarray(BHH_START, BHH_END));
|
|
207036
|
-
}
|
|
207037
|
-
var MAINNET_FIRST_BURN_HEIGHT = 666050;
|
|
207038
|
-
var MAINNET_REWARD_CYCLE_LENGTH = 2100;
|
|
207039
|
-
var MAINNET_PREPARE_LENGTH = 100;
|
|
207040
|
-
var cycleStart = (cycle, firstBurnHeight = MAINNET_FIRST_BURN_HEIGHT, cycleLength = MAINNET_REWARD_CYCLE_LENGTH) => firstBurnHeight + cycle * cycleLength;
|
|
207041
|
-
function rewardCycle(burnHeight, firstBurnHeight = MAINNET_FIRST_BURN_HEIGHT, cycleLength = MAINNET_REWARD_CYCLE_LENGTH) {
|
|
207042
|
-
if (burnHeight < firstBurnHeight)
|
|
207043
|
-
throw new Error(`burn height ${burnHeight} precedes the first burn block`);
|
|
207044
|
-
return Math.floor((burnHeight - firstBurnHeight) / cycleLength);
|
|
207045
|
-
}
|
|
207046
|
-
// ../verify/src/keys.ts
|
|
207047
|
-
import { serializeCV } from "@secondlayer/stacks/clarity";
|
|
207048
|
-
import { c32addressDecode } from "@secondlayer/stacks/utils";
|
|
207049
|
-
var StoreType = { DataMap: 0, Variable: 1, FungibleToken: 2 };
|
|
207050
|
-
function mapEntryKey(contractId, mapName, key) {
|
|
207051
|
-
return `vm::${contractId}::${StoreType.DataMap}::${mapName}::${serializeCV(key)}`;
|
|
207052
|
-
}
|
|
207053
|
-
function dataVarKey(contractId, varName) {
|
|
207054
|
-
return `vm::${contractId}::${StoreType.Variable}::${varName}`;
|
|
207055
|
-
}
|
|
207056
|
-
// ../verify/src/bitcoin/header.ts
|
|
207057
|
-
var HEADER_SIZE = 80;
|
|
207058
|
-
function toBytes(raw) {
|
|
207059
|
-
return typeof raw === "string" ? hexToBytes(raw) : raw;
|
|
207060
|
-
}
|
|
207061
|
-
function reverseBytes(bytes) {
|
|
207062
|
-
return Uint8Array.from(bytes).reverse();
|
|
207063
|
-
}
|
|
207064
|
-
function parseHeader(raw) {
|
|
207065
|
-
const bytes = toBytes(raw);
|
|
207066
|
-
if (bytes.length !== HEADER_SIZE) {
|
|
207067
|
-
throw new RangeError(`block header must be ${HEADER_SIZE} bytes, got ${bytes.length}`);
|
|
207068
|
-
}
|
|
207069
|
-
const view = new DataView(bytes.buffer, bytes.byteOffset, HEADER_SIZE);
|
|
207070
|
-
return {
|
|
207071
|
-
version: view.getInt32(0, true),
|
|
207072
|
-
prevHash: bytesToHex(reverseBytes(bytes.subarray(4, 36))),
|
|
207073
|
-
merkleRoot: bytesToHex(reverseBytes(bytes.subarray(36, 68))),
|
|
207074
|
-
time: view.getUint32(68, true),
|
|
207075
|
-
bits: view.getUint32(72, true),
|
|
207076
|
-
nonce: view.getUint32(76, true)
|
|
207077
|
-
};
|
|
207078
|
-
}
|
|
207079
|
-
function headerHash(raw) {
|
|
207080
|
-
const bytes = toBytes(raw);
|
|
207081
|
-
if (bytes.length !== HEADER_SIZE) {
|
|
207082
|
-
throw new RangeError(`block header must be ${HEADER_SIZE} bytes, got ${bytes.length}`);
|
|
207083
|
-
}
|
|
207084
|
-
return sha256(sha256(bytes));
|
|
207085
|
-
}
|
|
207086
|
-
|
|
207087
|
-
// ../verify/src/bitcoin/pow.ts
|
|
207088
|
-
var POW_LIMIT = 0xffffn << 208n;
|
|
207089
|
-
var RETARGET_INTERVAL = 2016;
|
|
207090
|
-
var TARGET_TIMESPAN = 14 * 24 * 60 * 60;
|
|
207091
|
-
var TWO_256 = 1n << 256n;
|
|
207092
|
-
function decodeCompact(bits) {
|
|
207093
|
-
const size = bits >>> 24;
|
|
207094
|
-
let word = bits & 8388607;
|
|
207095
|
-
let target;
|
|
207096
|
-
if (size <= 3) {
|
|
207097
|
-
word >>>= 8 * (3 - size);
|
|
207098
|
-
target = BigInt(word);
|
|
207099
|
-
} else {
|
|
207100
|
-
target = BigInt(word) << BigInt(8 * (size - 3));
|
|
207101
|
-
}
|
|
207102
|
-
const negative = word !== 0 && (bits & 8388608) !== 0;
|
|
207103
|
-
const overflow = word !== 0 && (size > 34 || word > 255 && size > 33 || word > 65535 && size > 32);
|
|
207104
|
-
return { target: target & TWO_256 - 1n, negative, overflow };
|
|
207105
|
-
}
|
|
207106
|
-
function bitsToTarget(bits) {
|
|
207107
|
-
const { target, negative, overflow } = decodeCompact(bits);
|
|
207108
|
-
if (negative || overflow || target === 0n) {
|
|
207109
|
-
throw new RangeError(`bits 0x${bits.toString(16).padStart(8, "0")} do not encode a valid target`);
|
|
207110
|
-
}
|
|
207111
|
-
return target;
|
|
207112
|
-
}
|
|
207113
|
-
function targetToBits(target) {
|
|
207114
|
-
if (target < 0n)
|
|
207115
|
-
throw new RangeError("target must be non-negative");
|
|
207116
|
-
let size = target === 0n ? 0 : Math.ceil(target.toString(2).length / 8);
|
|
207117
|
-
let compact = size <= 3 ? Number(target << BigInt(8 * (3 - size))) : Number(target >> BigInt(8 * (size - 3)));
|
|
207118
|
-
if (compact & 8388608) {
|
|
207119
|
-
compact >>>= 8;
|
|
207120
|
-
size += 1;
|
|
207121
|
-
}
|
|
207122
|
-
return (size << 24 | compact) >>> 0;
|
|
207123
|
-
}
|
|
207124
|
-
function hashToBigInt(hash) {
|
|
207125
|
-
let n = 0n;
|
|
207126
|
-
for (let i = hash.length - 1;i >= 0; i--) {
|
|
207127
|
-
n = n << 8n | BigInt(hash[i]);
|
|
207128
|
-
}
|
|
207129
|
-
return n;
|
|
207130
|
-
}
|
|
207131
|
-
function checkProofOfWork(hash, bits) {
|
|
207132
|
-
const { target, negative, overflow } = decodeCompact(bits);
|
|
207133
|
-
if (negative || overflow || target === 0n || target > POW_LIMIT) {
|
|
207134
|
-
return false;
|
|
207135
|
-
}
|
|
207136
|
-
return hashToBigInt(hash) <= target;
|
|
207137
|
-
}
|
|
207138
|
-
function headerWork(bits) {
|
|
207139
|
-
const target = bitsToTarget(bits);
|
|
207140
|
-
return (TWO_256 - 1n - target) / (target + 1n) + 1n;
|
|
207141
|
-
}
|
|
207142
|
-
function nextRetargetBits(lastBits, firstTime, lastTime) {
|
|
207143
|
-
let actual = lastTime - firstTime;
|
|
207144
|
-
if (actual < TARGET_TIMESPAN / 4)
|
|
207145
|
-
actual = TARGET_TIMESPAN / 4;
|
|
207146
|
-
if (actual > TARGET_TIMESPAN * 4)
|
|
207147
|
-
actual = TARGET_TIMESPAN * 4;
|
|
207148
|
-
let target = bitsToTarget(lastBits) * BigInt(actual) / BigInt(TARGET_TIMESPAN);
|
|
207149
|
-
if (target > POW_LIMIT)
|
|
207150
|
-
target = POW_LIMIT;
|
|
207151
|
-
return targetToBits(target);
|
|
207152
|
-
}
|
|
207153
|
-
|
|
207154
|
-
// ../verify/src/bitcoin/chain.ts
|
|
207155
|
-
var MEDIAN_TIME_SPAN = 11;
|
|
207156
|
-
var BIP65_HEIGHT = 388381;
|
|
207157
|
-
|
|
207158
|
-
class HeaderValidationError extends Error {
|
|
207159
|
-
height;
|
|
207160
|
-
rule;
|
|
207161
|
-
name = "HeaderValidationError";
|
|
207162
|
-
constructor(height, rule, detail) {
|
|
207163
|
-
super(`header at height ${height} failed ${rule}: ${detail}`);
|
|
207164
|
-
this.height = height;
|
|
207165
|
-
this.rule = rule;
|
|
207166
|
-
}
|
|
207167
|
-
}
|
|
207168
|
-
var hex8 = (n) => `0x${n.toString(16).padStart(8, "0")}`;
|
|
207169
|
-
|
|
207170
|
-
class HeaderChain {
|
|
207171
|
-
base;
|
|
207172
|
-
periodStartTime;
|
|
207173
|
-
entries = [];
|
|
207174
|
-
heights = new Map;
|
|
207175
|
-
work = 0n;
|
|
207176
|
-
constructor(base, periodStartTime) {
|
|
207177
|
-
this.base = base;
|
|
207178
|
-
this.periodStartTime = periodStartTime;
|
|
207179
|
-
}
|
|
207180
|
-
static fromCheckpoint(checkpoint) {
|
|
207181
|
-
const { height } = checkpoint;
|
|
207182
|
-
if (!Number.isSafeInteger(height) || height < 0) {
|
|
207183
|
-
throw new HeaderValidationError(height, "checkpoint", "height must be a non-negative integer");
|
|
207184
|
-
}
|
|
207185
|
-
const raw = toRaw(checkpoint.header, height);
|
|
207186
|
-
const header = parseHeader(raw);
|
|
207187
|
-
try {
|
|
207188
|
-
bitsToTarget(header.bits);
|
|
207189
|
-
} catch (err) {
|
|
207190
|
-
throw new HeaderValidationError(height, "checkpoint", err.message);
|
|
207191
|
-
}
|
|
207192
|
-
const atPeriodStart = height % RETARGET_INTERVAL === 0;
|
|
207193
|
-
let periodStartTime = checkpoint.periodStartTime;
|
|
207194
|
-
if (atPeriodStart) {
|
|
207195
|
-
if (periodStartTime !== undefined && periodStartTime !== header.time) {
|
|
207196
|
-
throw new HeaderValidationError(height, "checkpoint", `periodStartTime ${periodStartTime} disagrees with the period-start checkpoint's own time ${header.time}`);
|
|
207197
|
-
}
|
|
207198
|
-
periodStartTime = header.time;
|
|
207199
|
-
} else if (periodStartTime === undefined) {
|
|
207200
|
-
throw new HeaderValidationError(height, "checkpoint", `periodStartTime is required for a checkpoint inside a difficulty period (period starts at ${height - height % RETARGET_INTERVAL})`);
|
|
207201
|
-
}
|
|
207202
|
-
const chain = new HeaderChain(height, periodStartTime);
|
|
207203
|
-
chain.push(raw, header);
|
|
207204
|
-
return chain;
|
|
207205
|
-
}
|
|
207206
|
-
get tip() {
|
|
207207
|
-
return this.entries[this.entries.length - 1];
|
|
207208
|
-
}
|
|
207209
|
-
get totalWork() {
|
|
207210
|
-
return this.work;
|
|
207211
|
-
}
|
|
207212
|
-
get checkpointHeight() {
|
|
207213
|
-
return this.base;
|
|
207214
|
-
}
|
|
207215
|
-
heightOf(hashHex) {
|
|
207216
|
-
return this.heights.get(hashHex.toLowerCase());
|
|
207217
|
-
}
|
|
207218
|
-
headerAt(height) {
|
|
207219
|
-
return this.entries[height - this.base];
|
|
207220
|
-
}
|
|
207221
|
-
append(headers) {
|
|
207222
|
-
const before = this.entries.length;
|
|
207223
|
-
const workBefore = this.work;
|
|
207224
|
-
try {
|
|
207225
|
-
for (const item of headers) {
|
|
207226
|
-
const height = this.tip.height + 1;
|
|
207227
|
-
const raw = toRaw(item, height);
|
|
207228
|
-
this.validate(height, raw, parseHeader(raw));
|
|
207229
|
-
}
|
|
207230
|
-
} catch (err) {
|
|
207231
|
-
for (const removed of this.entries.splice(before)) {
|
|
207232
|
-
this.heights.delete(removed.hash);
|
|
207233
|
-
}
|
|
207234
|
-
this.work = workBefore;
|
|
207235
|
-
throw err;
|
|
207236
|
-
}
|
|
207237
|
-
}
|
|
207238
|
-
validate(height, raw, header) {
|
|
207239
|
-
const prev = this.tip;
|
|
207240
|
-
if (header.prevHash !== prev.hash) {
|
|
207241
|
-
const known = this.heights.get(header.prevHash);
|
|
207242
|
-
throw new HeaderValidationError(height, "prev-link", known === undefined ? `prevHash ${header.prevHash} does not match tip ${prev.hash} at ${prev.height}` : `prevHash points at height ${known}, not the tip at ${prev.height} (forks/reorgs are not supported)`);
|
|
207243
|
-
}
|
|
207244
|
-
const expectedBits = this.expectedBits(height, prev);
|
|
207245
|
-
if (header.bits !== expectedBits) {
|
|
207246
|
-
const atRetarget = height % RETARGET_INTERVAL === 0;
|
|
207247
|
-
throw new HeaderValidationError(height, atRetarget ? "retarget" : "bits", atRetarget ? `bits ${hex8(header.bits)} != retargeted ${hex8(expectedBits)}` : `bits ${hex8(header.bits)} != previous ${hex8(expectedBits)} (only height % ${RETARGET_INTERVAL} == 0 may change difficulty)`);
|
|
207248
|
-
}
|
|
207249
|
-
const mtp = this.medianTimePast();
|
|
207250
|
-
if (header.time <= mtp) {
|
|
207251
|
-
throw new HeaderValidationError(height, "median-time-past", `time ${header.time} <= median of previous ${Math.min(MEDIAN_TIME_SPAN, this.entries.length)} blocks (${mtp})`);
|
|
207252
|
-
}
|
|
207253
|
-
if (height >= BIP65_HEIGHT && header.version < 4) {
|
|
207254
|
-
throw new HeaderValidationError(height, "version", `version ${header.version} < 4 (required from height ${BIP65_HEIGHT})`);
|
|
207255
|
-
}
|
|
207256
|
-
const hash = headerHash(raw);
|
|
207257
|
-
if (!checkProofOfWork(hash, header.bits)) {
|
|
207258
|
-
throw new HeaderValidationError(height, "proof-of-work", `hash ${bytesToHex(reverseBytes(hash))} exceeds target for bits ${hex8(header.bits)}`);
|
|
207259
|
-
}
|
|
207260
|
-
this.push(raw, header, hash);
|
|
207261
|
-
}
|
|
207262
|
-
expectedBits(height, prev) {
|
|
207263
|
-
if (height % RETARGET_INTERVAL !== 0)
|
|
207264
|
-
return prev.header.bits;
|
|
207265
|
-
const firstHeight = height - RETARGET_INTERVAL;
|
|
207266
|
-
const firstTime = firstHeight < this.base ? this.periodStartTime : this.headerAt(firstHeight).header.time;
|
|
207267
|
-
return nextRetargetBits(prev.header.bits, firstTime, prev.header.time);
|
|
207268
|
-
}
|
|
207269
|
-
medianTimePast() {
|
|
207270
|
-
const times = this.entries.slice(-MEDIAN_TIME_SPAN).map((e) => e.header.time).sort((a, b) => a - b);
|
|
207271
|
-
return times[Math.floor(times.length / 2)];
|
|
207272
|
-
}
|
|
207273
|
-
push(raw, header, hash = headerHash(raw)) {
|
|
207274
|
-
const height = this.base + this.entries.length;
|
|
207275
|
-
const hashHex = bytesToHex(reverseBytes(hash));
|
|
207276
|
-
this.entries.push({ height, hash: hashHex, header, raw });
|
|
207277
|
-
this.heights.set(hashHex, height);
|
|
207278
|
-
this.work += headerWork(header.bits);
|
|
207279
|
-
}
|
|
207280
|
-
}
|
|
207281
|
-
function toRaw(item, height) {
|
|
207282
|
-
let raw;
|
|
207283
|
-
try {
|
|
207284
|
-
raw = typeof item === "string" ? hexToBytes(item) : Uint8Array.from(item);
|
|
207285
|
-
} catch {
|
|
207286
|
-
throw new HeaderValidationError(height, "format", "header is not valid hex");
|
|
207287
|
-
}
|
|
207288
|
-
if (raw.length !== HEADER_SIZE) {
|
|
207289
|
-
throw new HeaderValidationError(height, "format", `header must be ${HEADER_SIZE} bytes, got ${raw.length}`);
|
|
207290
|
-
}
|
|
207291
|
-
return raw;
|
|
207292
|
-
}
|
|
207293
|
-
// ../verify/src/checkpoint.ts
|
|
207294
|
-
var MAINNET_CHECKPOINT = {
|
|
207295
|
-
stacks: {
|
|
207296
|
-
header: [
|
|
207297
|
-
"01000000000088a9900000006629951a50e3616a1c1e0b8c05ba66615c7065053804c56e2a68dc605cf905df5a754c57",
|
|
207298
|
-
"144e9ddde1191353b05f1a5e6d3c99244aeb006ba4f4db761cb1efecfb92693a8c08fefc766a4cd5ccfcb8f13789a809",
|
|
207299
|
-
"e7ee0c2e6b7dfb64868cf1e4e6acc50513202acfab84553454b433248c0ef06cebda3c734c000000006aa28bfd013be3",
|
|
207300
|
-
"826a60039f518d7021a4799f2e083dafaaaac7a2d56fda601d674d596d3046b9bbcd52e79fba491e54d92fdab0ca3ab9",
|
|
207301
|
-
"9ccf346c6e6726fbd4c8579a02b80000000d0004f2d135dd684fcdf24973ad0e9d4f11ef10890a8159614b1df97d8f31",
|
|
207302
|
-
"76532d1ce4ebdcbbf45afcd01d5bb298ef9556b232f877f3586d65303642dabc210059012d5f341c979fd10a1ce9b48f",
|
|
207303
|
-
"4a38f68da5ccbb8749c02e164a99668328890ed706accfbec155202f63ff487a26aba793169341c2ff91a43ffed38f0e",
|
|
207304
|
-
"941c3dc1012a12bb2148d6cf23dd05e228d29286e3bb87ff717712ecc2c9f0c4297c241ac41f879baeee87a570243a31",
|
|
207305
|
-
"cf43e775862e71a7f51cb150bbc31f3a2f62a1772d00f8bdd615ab5b58841c7918d69cf98a030f52ca410c9b91a188ba",
|
|
207306
|
-
"038138563ea35f8453075907fc3cdac7e3eff8fa9f61fcb53a1e14a102309fa297e420826bfe015628863a16f1bdc077",
|
|
207307
|
-
"90c6eead0cfd7a0aa7222df6d8d41415427b0b4057eb972dc31bd413f1e425ef1bc738cc5c3b8507890bad0940bafdf2",
|
|
207308
|
-
"220a6ecadb33ed002f9a476eb20c5e532bafa7b559b285932e1dab1159c93038d8cb0da8d55d25294cc8e6b0972efc08",
|
|
207309
|
-
"fdf825407e3215d8d01531f5cddfe993db10be07b38c18fa006999eb6418eac4696bb42ca149f79832442754ea08b0e1",
|
|
207310
|
-
"c6237feb522df034a3388c0de90b1a4652218b319f839ff16a132baa90dbbca2876f52b1a5750dc07001cffca3ed6e92",
|
|
207311
|
-
"2483e6567f183a78a1c09d16846743f08c5cce93e7e06294c4a722283d31195722b6ce97087c6dd00eedecd1db77be10",
|
|
207312
|
-
"9c298c322c53e83ea43201dd0684e8171ad29f6895ed9892d3932daeb0986f32992d6758db194ae9ba8eb256fdff3b61",
|
|
207313
|
-
"af0cd448aafe5e4e62e7e75409dfcd3cef3913c792e412849a02550109083fa52598f5fa2907e840050c41db32163838",
|
|
207314
|
-
"32aa7cb5e23de14ced47961e356b23e442f2a657ea89fed2845a6b380624dc12347e4d591c80e15016ae35fc005ae002",
|
|
207315
|
-
"f1fc5837c21185b88b06cc8611cfb482c021df5329d878e2b4f221341a47e6fe02182c9250d25fe162f42a0bbe9b8ce2",
|
|
207316
|
-
"f9a70aa2dcca9e955a61a0fe24016398a0fdf5e2541d3d0838d9f7e24b4093d27660a48cd71bf0728fe5d02e6d374a3e",
|
|
207317
|
-
"aa67c91aee87635d7458bb1fe89755021fbe8d34e271fba1d765b065e266008a862c839aeec0d6a9940cfe44e0bc1586",
|
|
207318
|
-
"2bd2ac23b3ab6fc59734a8171b44401b395984f0f906b2d15b4a3a24d2136a8ca925485f197197b3aa1bb2c46d02e000",
|
|
207319
|
-
"01000000010100000000"
|
|
207320
|
-
].join(""),
|
|
207321
|
-
cycle: 143,
|
|
207322
|
-
signerSet: [
|
|
207323
|
-
"0a0b0000001d0c00000002067369676e65720516f5061b1c62f399ecc0db8cbb21f8d481af079a380677656967687401",
|
|
207324
|
-
"000000000000000000000000000002860c00000002067369676e65720516a3bbf2a4133fbd5bd1880982957b7a760347",
|
|
207325
|
-
"b2dc0677656967687401000000000000000000000000000000090c00000002067369676e657205164f72f6b5a9f5d863",
|
|
207326
|
-
"34b2f0fe701db51a7a246f3d0677656967687401000000000000000000000000000000990c00000002067369676e6572",
|
|
207327
|
-
"051653ec8b4f51c8286dad6f4ff81ca2a3409d2f382d0677656967687401000000000000000000000000000000050c00",
|
|
207328
|
-
"000002067369676e65720516dba631825ff0f15c7c5946b560070f8f5f5747cb06776569676874010000000000000000",
|
|
207329
|
-
"00000000000000240c00000002067369676e6572051600d058b39f4495b412ff7eada763eaa6386eb90a067765696768",
|
|
207330
|
-
"7401000000000000000000000000000002860c00000002067369676e65720516321ac33715d684d5e8d0cf427cd98557",
|
|
207331
|
-
"6f64c6df06776569676874010000000000000000000000000000000b0c00000002067369676e6572051677a52718ba90",
|
|
207332
|
-
"fca67984166b2a084edb9b3bd8f10677656967687401000000000000000000000000000000030c00000002067369676e",
|
|
207333
|
-
"65720516a54a20479b3b65a461a427b9161b78e64db58ba70677656967687401000000000000000000000000000001a9",
|
|
207334
|
-
"0c00000002067369676e65720516bc1a58c2a058a9e4150db25562e8331ef8a4267c0677656967687401000000000000",
|
|
207335
|
-
"000000000000000000060c00000002067369676e657205161091d2da4c9ee17a340171c0d23c4304b54ef43f06776569",
|
|
207336
|
-
"67687401000000000000000000000000000000680c00000002067369676e6572051654d01a0973ed139736a1a43032a6",
|
|
207337
|
-
"a18d9295ec7206776569676874010000000000000000000000000000008d0c00000002067369676e657205160c49f5b6",
|
|
207338
|
-
"c62f1163ddbb21f92aba86f17f7be4880677656967687401000000000000000000000000000000680c00000002067369",
|
|
207339
|
-
"676e65720516ad16c79ac56b58f0797f78c5343853674606268006776569676874010000000000000000000000000000",
|
|
207340
|
-
"00680c00000002067369676e657205169689e56df00385b6bd81fb6b7769d5b04088acb8067765696768740100000000",
|
|
207341
|
-
"0000000000000000000000ad0c00000002067369676e65720516a4f7f81412f4413771a48825cfbe2062a774d4e90677",
|
|
207342
|
-
"656967687401000000000000000000000000000003090c00000002067369676e65720516ed73a7398f1c3eb566f3bd7f",
|
|
207343
|
-
"4bd43f52adf33d8f0677656967687401000000000000000000000000000000680c00000002067369676e65720516937b",
|
|
207344
|
-
"3b43e0d94c9ef8f171892bce949709e1d41f0677656967687401000000000000000000000000000000250c0000000206",
|
|
207345
|
-
"7369676e6572051631542aacfd6e04858181c3067b5eb07399ba89df0677656967687401000000000000000000000000",
|
|
207346
|
-
"0000005b0c00000002067369676e6572051649f034cd1662a222dbc38a6acd64008ba7e5576606776569676874010000",
|
|
207347
|
-
"00000000000000000000000000060c00000002067369676e65720516a20f660dea498c169897a39cb89ce0d98856e572",
|
|
207348
|
-
"0677656967687401000000000000000000000000000000090c00000002067369676e6572051652d58897b3678f3a758f",
|
|
207349
|
-
"a4b9270744fec0605b210677656967687401000000000000000000000000000000680c00000002067369676e65720516",
|
|
207350
|
-
"31733264626dc5fef36eb683a5069d89f63b64cc0677656967687401000000000000000000000000000000090c000000",
|
|
207351
|
-
"02067369676e65720516d80db618c2def577604cd8e40a3940b5b639b1ac067765696768740100000000000000000000",
|
|
207352
|
-
"00000000000a0c00000002067369676e657205162042a380d946a82866465af8521a273efe6d2a600677656967687401",
|
|
207353
|
-
"000000000000000000000000000000490c00000002067369676e6572051635e1b36efc22bc607db92f9100cb08e3473d",
|
|
207354
|
-
"602506776569676874010000000000000000000000000000006b0c00000002067369676e657205164843b97054e43dd1",
|
|
207355
|
-
"a8571fc1e72949c5bedfb7e906776569676874010000000000000000000000000000004d0c00000002067369676e6572",
|
|
207356
|
-
"05164883355670025c19ecae644ffa20e75ce1d730ad0677656967687401000000000000000000000000000000090c00",
|
|
207357
|
-
"000002067369676e65720516089ffd0e0ecd61d9e3c8ee42ef94148acf88aa8806776569676874010000000000000000",
|
|
207358
|
-
"0000000000000015"
|
|
207359
|
-
].join("")
|
|
207360
|
-
},
|
|
207361
|
-
bitcoin: {
|
|
207362
|
-
height: 967680,
|
|
207363
|
-
header: "00000030410ccb1cba623e26f2e02f3fcb0e7f06f66998b68cb5010000000000000000003d16ae2558e8ec7b8dd369ee29bb2733fbd39bcc1058c681970a36a7f1a2bdea1135ae6ac51e0217480c3581"
|
|
207364
|
-
}
|
|
207365
|
-
};
|
|
207366
|
-
// ../verify/src/source.ts
|
|
207367
|
-
class SourceError extends Error {
|
|
207368
|
-
url;
|
|
207369
|
-
status;
|
|
207370
|
-
name = "SourceError";
|
|
207371
|
-
constructor(url, status, detail) {
|
|
207372
|
-
super(`${url}: ${detail}`);
|
|
207373
|
-
this.url = url;
|
|
207374
|
-
this.status = status;
|
|
207375
|
-
}
|
|
207376
|
-
}
|
|
207377
|
-
var MAX_ATTEMPTS = 3;
|
|
207378
|
-
var MAX_RETRY_SECONDS = 10;
|
|
207379
|
-
async function get(url, opts, attempt = 1) {
|
|
207380
|
-
const doFetch = opts.fetch ?? fetch;
|
|
207381
|
-
let res;
|
|
207382
|
-
try {
|
|
207383
|
-
res = await doFetch(url, { headers: opts.headers });
|
|
207384
|
-
} catch (err) {
|
|
207385
|
-
throw new SourceError(url, null, err.message);
|
|
207386
|
-
}
|
|
207387
|
-
if (res.status === 404)
|
|
207388
|
-
return null;
|
|
207389
|
-
if (res.status === 503 && attempt < MAX_ATTEMPTS) {
|
|
207390
|
-
const header = res.headers.get("retry-after");
|
|
207391
|
-
const seconds = header === null ? 1 : Number(header);
|
|
207392
|
-
const wait = Number.isFinite(seconds) ? Math.min(Math.max(seconds, 0), MAX_RETRY_SECONDS) : 1;
|
|
207393
|
-
await new Promise((r) => setTimeout(r, wait * 1000));
|
|
207394
|
-
return get(url, opts, attempt + 1);
|
|
207395
|
-
}
|
|
207396
|
-
if (!res.ok)
|
|
207397
|
-
throw new SourceError(url, res.status, `HTTP ${res.status}`);
|
|
207398
|
-
return res;
|
|
207399
|
-
}
|
|
207400
|
-
async function getJson(url, opts) {
|
|
207401
|
-
const res = await get(url, opts);
|
|
207402
|
-
return res ? await res.json() : null;
|
|
207403
|
-
}
|
|
207404
|
-
async function getBytes(url, opts) {
|
|
207405
|
-
const res = await get(url, opts);
|
|
207406
|
-
return res ? new Uint8Array(await res.arrayBuffer()) : null;
|
|
207407
|
-
}
|
|
207408
|
-
var required = (url, v) => {
|
|
207409
|
-
if (v === null)
|
|
207410
|
-
throw new SourceError(url, 404, "not found");
|
|
207411
|
-
return v;
|
|
207412
|
-
};
|
|
207413
|
-
var trimSlash = (s) => s.replace(/\/+$/, "");
|
|
207414
|
-
var toMarf = (url, j) => {
|
|
207415
|
-
if (j === null)
|
|
207416
|
-
return null;
|
|
207417
|
-
const proof = j.proof ?? j.marf_proof;
|
|
207418
|
-
if (typeof proof !== "string" || typeof j.data !== "string")
|
|
207419
|
-
throw new SourceError(url, 200, "MARF answer needs data and proof");
|
|
207420
|
-
return { data: j.data, proof: unhex(proof) };
|
|
207421
|
-
};
|
|
207422
|
-
var VM_WRITE_TYPES = [
|
|
207423
|
-
"var_set",
|
|
207424
|
-
"map_set",
|
|
207425
|
-
"map_insert",
|
|
207426
|
-
"map_delete"
|
|
207427
|
-
];
|
|
207428
|
-
var PAGE = 1000;
|
|
207429
|
-
|
|
207430
|
-
class SecondlayerProofSource {
|
|
207431
|
-
#base;
|
|
207432
|
-
#http;
|
|
207433
|
-
constructor(opts) {
|
|
207434
|
-
this.#base = trimSlash(opts.baseUrl);
|
|
207435
|
-
this.#http = {
|
|
207436
|
-
headers: { authorization: `Bearer ${opts.apiKey}` },
|
|
207437
|
-
fetch: opts.fetch
|
|
207438
|
-
};
|
|
207439
|
-
}
|
|
207440
|
-
getBlock = async (ref) => {
|
|
207441
|
-
const url = typeof ref === "number" ? `${this.#base}/v1/proofs/block/height/${ref}` : `${this.#base}/v1/proofs/block/${ref}`;
|
|
207442
|
-
return required(url, await getBytes(url, this.#http));
|
|
207443
|
-
};
|
|
207444
|
-
getMarfProof = async (pathHex, tipId) => {
|
|
207445
|
-
const url = `${this.#base}/v1/proofs/marf/${pathHex}?tip=${tipId}`;
|
|
207446
|
-
return toMarf(url, await getJson(url, this.#http));
|
|
207447
|
-
};
|
|
207448
|
-
getWitness = async (blockId) => {
|
|
207449
|
-
const url = `${this.#base}/v1/proofs/witness/${blockId}`;
|
|
207450
|
-
return required(url, await getBytes(url, this.#http));
|
|
207451
|
-
};
|
|
207452
|
-
getBurnPreimage = async (consensusHash) => {
|
|
207453
|
-
const url = `${this.#base}/v1/proofs/burn/${consensusHash}`;
|
|
207454
|
-
const j = required(url, await getJson(url, this.#http));
|
|
207455
|
-
return { preimage: unhex(j.preimage), burnHeight: j.burn_height };
|
|
207456
|
-
};
|
|
207457
|
-
getBitcoinHeaders = async (from, count) => {
|
|
207458
|
-
const url = `${this.#base}/v1/proofs/bitcoin-headers?from=${from}&count=${count}`;
|
|
207459
|
-
const j = required(url, await getJson(url, this.#http));
|
|
207460
|
-
if (j.from !== from)
|
|
207461
|
-
throw new SourceError(url, 200, `headers start at ${j.from}`);
|
|
207462
|
-
return j.headers;
|
|
207463
|
-
};
|
|
207464
|
-
getStateWrites = (height) => this.#pages("state_writes", `${this.#base}/v1/index/state-writes?block_height=${height}&limit=${PAGE}`);
|
|
207465
|
-
getVmEvents = async (height) => {
|
|
207466
|
-
const out = [];
|
|
207467
|
-
for (const type of VM_WRITE_TYPES) {
|
|
207468
|
-
const url = `${this.#base}/v1/index/events?event_type=${type}&from_height=${height}&to_height=${height}&limit=${PAGE}`;
|
|
207469
|
-
out.push(...await this.#pages("events", url) ?? []);
|
|
207470
|
-
}
|
|
207471
|
-
return out.sort((a, b) => a.event_index - b.event_index);
|
|
207472
|
-
};
|
|
207473
|
-
async#pages(field, url) {
|
|
207474
|
-
const out = [];
|
|
207475
|
-
let cursor = null;
|
|
207476
|
-
for (;; ) {
|
|
207477
|
-
const page = cursor ? `${url}&cursor=${encodeURIComponent(cursor)}` : url;
|
|
207478
|
-
const j = await getJson(page, this.#http);
|
|
207479
|
-
if (j === null)
|
|
207480
|
-
return cursor === null ? null : out;
|
|
207481
|
-
const rows = j[field];
|
|
207482
|
-
if (!Array.isArray(rows))
|
|
207483
|
-
throw new SourceError(page, 200, `answer has no ${field} array`);
|
|
207484
|
-
out.push(...rows);
|
|
207485
|
-
const next = j.next_cursor;
|
|
207486
|
-
if (rows.length < PAGE || typeof next !== "string" || next === cursor)
|
|
207487
|
-
return out;
|
|
207488
|
-
cursor = next;
|
|
207489
|
-
}
|
|
207490
|
-
}
|
|
207491
|
-
}
|
|
207492
|
-
|
|
207493
|
-
class NodeRpcProofSource {
|
|
207494
|
-
#base;
|
|
207495
|
-
#http;
|
|
207496
|
-
constructor(opts) {
|
|
207497
|
-
this.#base = trimSlash(opts.nodeUrl);
|
|
207498
|
-
this.#http = { fetch: opts.fetch };
|
|
207499
|
-
}
|
|
207500
|
-
getBlock = async (ref) => {
|
|
207501
|
-
const url = typeof ref === "number" ? `${this.#base}/v3/blocks/height/${ref}` : `${this.#base}/v3/blocks/${ref}`;
|
|
207502
|
-
return required(url, await getBytes(url, this.#http));
|
|
207503
|
-
};
|
|
207504
|
-
getMarfProof = async (pathHex, tipId) => {
|
|
207505
|
-
const url = `${this.#base}/v2/clarity/marf/${pathHex}?tip=${tipId}&proof=1`;
|
|
207506
|
-
return toMarf(url, await getJson(url, this.#http));
|
|
207507
|
-
};
|
|
207508
|
-
}
|
|
207509
|
-
// ../verify/src/state.ts
|
|
207510
|
-
var INTERNAL = {
|
|
207511
|
-
self: "__MARF_BLOCK_HEIGHT_SELF",
|
|
207512
|
-
heightToHash: "__MARF_BLOCK_HEIGHT_TO_HASH",
|
|
207513
|
-
hashToHeight: "__MARF_BLOCK_HASH_TO_HEIGHT"
|
|
207514
|
-
};
|
|
207515
|
-
var heightValue = (h) => {
|
|
207516
|
-
const v = new Uint8Array(MARF_VALUE_SIZE);
|
|
207517
|
-
new DataView(v.buffer).setUint32(0, h, true);
|
|
207518
|
-
return hex(v);
|
|
207519
|
-
};
|
|
207520
|
-
var padded = (b32) => `${hex(b32)}${"00".repeat(8)}`;
|
|
207521
|
-
function internalEntries(height, parentBlockId, leaves) {
|
|
207522
|
-
const out = [[INTERNAL.self, heightValue(height)]];
|
|
207523
|
-
const ownKey = `${INTERNAL.heightToHash}::${height}`;
|
|
207524
|
-
const ownPath = marfPath(ownKey);
|
|
207525
|
-
const own = leaves.find((l) => bytesEqual(l.path, ownPath));
|
|
207526
|
-
if (own) {
|
|
207527
|
-
out.push([ownKey, padded(own.valueHash)]);
|
|
207528
|
-
out.push([
|
|
207529
|
-
`${INTERNAL.hashToHeight}::${hex(own.valueHash)}`,
|
|
207530
|
-
heightValue(height)
|
|
207531
|
-
]);
|
|
207532
|
-
}
|
|
207533
|
-
if (height > 0) {
|
|
207534
|
-
out.push([
|
|
207535
|
-
`${INTERNAL.heightToHash}::${height - 1}`,
|
|
207536
|
-
padded(parentBlockId)
|
|
207537
|
-
]);
|
|
207538
|
-
out.push([
|
|
207539
|
-
`${INTERNAL.hashToHeight}::${hex(parentBlockId)}`,
|
|
207540
|
-
heightValue(height - 1)
|
|
207541
|
-
]);
|
|
207542
|
-
}
|
|
207543
|
-
return out;
|
|
207544
|
-
}
|
|
207545
|
-
var utf8 = new TextDecoder("utf-8", { fatal: true });
|
|
207546
|
-
var strip0x = (s) => s.startsWith("0x") ? s.slice(2) : s;
|
|
207547
|
-
var leafHex = (l) => ({
|
|
207548
|
-
path: hex(l.path),
|
|
207549
|
-
valueHash: hex(l.valueHash)
|
|
207550
|
-
});
|
|
207551
|
-
function lastWrites(writes, failures) {
|
|
207552
|
-
const out = new Map;
|
|
207553
|
-
for (const w of [...writes].sort((a, b) => a.ordinal - b.ordinal)) {
|
|
207554
|
-
try {
|
|
207555
|
-
out.set(w.key, {
|
|
207556
|
-
value: utf8.decode(unhex(strip0x(w.value_hex))),
|
|
207557
|
-
txIndex: w.tx_index
|
|
207558
|
-
});
|
|
207559
|
-
} catch {
|
|
207560
|
-
failures.push({
|
|
207561
|
-
step: "names",
|
|
207562
|
-
code: "bad-write",
|
|
207563
|
-
message: `state write ${w.ordinal} value is not UTF-8 hex`,
|
|
207564
|
-
key: w.key,
|
|
207565
|
-
ordinal: w.ordinal
|
|
207566
|
-
});
|
|
207567
|
-
}
|
|
207568
|
-
}
|
|
207569
|
-
return out;
|
|
207570
|
-
}
|
|
207571
|
-
function rowWrite(row) {
|
|
207572
|
-
const need = (v, name) => {
|
|
207573
|
-
if (!v)
|
|
207574
|
-
throw new Error(`${row.event_type} row has no ${name}`);
|
|
207575
|
-
return v;
|
|
207576
|
-
};
|
|
207577
|
-
if (row.event_type === "var_set")
|
|
207578
|
-
return [
|
|
207579
|
-
dataVarKey(row.contract_id, need(row.var_name, "var_name")),
|
|
207580
|
-
strip0x(need(row.raw_value, "raw_value")).toLowerCase()
|
|
207581
|
-
];
|
|
207582
|
-
const key = `vm::${row.contract_id}::0::${need(row.map, "map")}::${strip0x(need(row.raw_key, "raw_key")).toLowerCase()}`;
|
|
207583
|
-
if (row.event_type === "map_delete")
|
|
207584
|
-
return [key, "09"];
|
|
207585
|
-
return [key, `0a${strip0x(need(row.raw_value, "raw_value")).toLowerCase()}`];
|
|
207586
|
-
}
|
|
207587
|
-
function checkRows(rows, leaves, failures) {
|
|
207588
|
-
const byPath = new Map(leaves.map((l) => [hex(l.path), l]));
|
|
207589
|
-
const named = [];
|
|
207590
|
-
for (const row of [...rows].sort((a, b) => a.event_index - b.event_index)) {
|
|
207591
|
-
try {
|
|
207592
|
-
const [key, value] = rowWrite(row);
|
|
207593
|
-
named.push({ row, key, path: hex(marfPath(key)), value });
|
|
207594
|
-
} catch (err) {
|
|
207595
|
-
failures.push({
|
|
207596
|
-
step: "rows",
|
|
207597
|
-
code: "bad-row",
|
|
207598
|
-
message: err.message,
|
|
207599
|
-
ordinal: row.event_index
|
|
207600
|
-
});
|
|
207601
|
-
}
|
|
207602
|
-
}
|
|
207603
|
-
const last = new Map(named.map((n, i) => [n.path, i]));
|
|
207604
|
-
named.forEach((n, i) => {
|
|
207605
|
-
const leaf = byPath.get(n.path);
|
|
207606
|
-
const at = { key: n.key, path: n.path, ordinal: n.row.event_index };
|
|
207607
|
-
if (!leaf)
|
|
207608
|
-
failures.push({
|
|
207609
|
-
step: "rows",
|
|
207610
|
-
code: "key-not-written",
|
|
207611
|
-
message: `${n.row.event_type} row ${n.row.event_index} names a key the block did not write`,
|
|
207612
|
-
...at
|
|
207613
|
-
});
|
|
207614
|
-
else if (last.get(n.path) === i && padded(leaf.valueHash) !== hex(marfValue(n.value)))
|
|
207615
|
-
failures.push({
|
|
207616
|
-
step: "rows",
|
|
207617
|
-
code: "value-mismatch",
|
|
207618
|
-
message: `${n.row.event_type} row ${n.row.event_index} value differs from the block's leaf`,
|
|
207619
|
-
...at
|
|
207620
|
-
});
|
|
207621
|
-
});
|
|
207622
|
-
return named.length;
|
|
207623
|
-
}
|
|
207624
|
-
async function verifyBlockState(input) {
|
|
207625
|
-
const out = { rowsChecked: 0, notes: [], failures: [] };
|
|
207626
|
-
let witness;
|
|
207627
|
-
try {
|
|
207628
|
-
witness = parseWitness(input.witness);
|
|
207629
|
-
} catch (err) {
|
|
207630
|
-
out.failures.push({
|
|
207631
|
-
step: "witness",
|
|
207632
|
-
code: "malformed",
|
|
207633
|
-
message: err.message
|
|
207634
|
-
});
|
|
207635
|
-
return out;
|
|
207636
|
-
}
|
|
207637
|
-
if (!bytesEqual(witness.root, input.stateRoot)) {
|
|
207638
|
-
out.failures.push({
|
|
207639
|
-
step: "witness",
|
|
207640
|
-
code: "root-mismatch",
|
|
207641
|
-
message: `witness root ${hex(witness.root)} != header state_index_root ${hex(input.stateRoot)}`
|
|
207642
|
-
});
|
|
207643
|
-
return out;
|
|
207644
|
-
}
|
|
207645
|
-
const { leaves } = witness;
|
|
207646
|
-
const internal = internalEntries(input.height, input.parentBlockId, leaves);
|
|
207647
|
-
const named = input.writes !== null;
|
|
207648
|
-
const last = lastWrites(input.writes ?? [], out.failures);
|
|
207649
|
-
const writes = [...last].map(([k, w]) => [k, w.value]);
|
|
207650
|
-
const first = classifyBlockDiff({
|
|
207651
|
-
leaves,
|
|
207652
|
-
writes,
|
|
207653
|
-
internal,
|
|
207654
|
-
parentValue: () => {
|
|
207655
|
-
return;
|
|
207656
|
-
}
|
|
207657
|
-
});
|
|
207658
|
-
const inParent = new Map((input.parentLeaves ?? []).map((l) => [hex(l.path), hex(l.valueHash)]));
|
|
207659
|
-
const carried = new Map;
|
|
207660
|
-
for (const leaf of first.hidden) {
|
|
207661
|
-
const pathHex = hex(leaf.path);
|
|
207662
|
-
if (inParent.get(pathHex) === hex(leaf.valueHash) || named && await input.parentHolds?.(leaf))
|
|
207663
|
-
carried.set(pathHex, padded(leaf.valueHash));
|
|
207664
|
-
}
|
|
207665
|
-
const d = classifyBlockDiff({
|
|
207666
|
-
leaves,
|
|
207667
|
-
writes,
|
|
207668
|
-
internal,
|
|
207669
|
-
parentValue: (p) => carried.get(p)
|
|
207670
|
-
});
|
|
207671
|
-
out.diff = {
|
|
207672
|
-
named,
|
|
207673
|
-
writes: named ? d.writes.map((l) => ({
|
|
207674
|
-
...leafHex(l),
|
|
207675
|
-
key: l.key,
|
|
207676
|
-
txIndex: last.get(l.key)?.txIndex ?? null,
|
|
207677
|
-
named: true
|
|
207678
|
-
})) : d.hidden.map((l) => ({ ...leafHex(l), named: false })),
|
|
207679
|
-
carried: d.carried.map(leafHex),
|
|
207680
|
-
internal: d.internal.map((l) => ({ ...leafHex(l), key: l.key }))
|
|
207681
|
-
};
|
|
207682
|
-
if (!named)
|
|
207683
|
-
out.notes.push(`source has no state_writes for block ${input.height}: ${d.hidden.length} written leaves are proven in the block but unnamed`);
|
|
207684
|
-
else {
|
|
207685
|
-
for (const l of d.hidden)
|
|
207686
|
-
out.failures.push({
|
|
207687
|
-
step: "names",
|
|
207688
|
-
code: "hidden-write",
|
|
207689
|
-
message: `leaf ${hex(l.path)} is not a named write, a carried parent value or MARF bookkeeping`,
|
|
207690
|
-
path: hex(l.path)
|
|
207691
|
-
});
|
|
207692
|
-
for (const key of d.missing)
|
|
207693
|
-
out.failures.push({
|
|
207694
|
-
step: "names",
|
|
207695
|
-
code: "missing-write",
|
|
207696
|
-
message: `state write ${key} has no leaf holding its value`,
|
|
207697
|
-
key,
|
|
207698
|
-
path: hex(marfPath(key))
|
|
207699
|
-
});
|
|
207700
|
-
}
|
|
207701
|
-
if (input.rows)
|
|
207702
|
-
out.rowsChecked = checkRows(input.rows, leaves, out.failures);
|
|
207703
|
-
return out;
|
|
207704
|
-
}
|
|
207705
|
-
// ../verify/src/verify-block.ts
|
|
207706
|
-
import { uintCV } from "@secondlayer/stacks/clarity";
|
|
207707
|
-
class Broken extends Error {
|
|
207708
|
-
failure;
|
|
207709
|
-
constructor(failure) {
|
|
207710
|
-
super(failure.message);
|
|
207711
|
-
this.failure = failure;
|
|
207712
|
-
}
|
|
207713
|
-
}
|
|
207714
|
-
var fail = (f) => {
|
|
207715
|
-
throw new Broken(f);
|
|
207716
|
-
};
|
|
207717
|
-
async function fetchFor(step, what, call, extra = {}) {
|
|
207718
|
-
try {
|
|
207719
|
-
return await call();
|
|
207720
|
-
} catch (err) {
|
|
207721
|
-
if (err instanceof Broken)
|
|
207722
|
-
throw err;
|
|
207723
|
-
return fail({
|
|
207724
|
-
step,
|
|
207725
|
-
code: "unavailable",
|
|
207726
|
-
message: `${what}: ${err.message}`,
|
|
207727
|
-
...extra
|
|
207728
|
-
});
|
|
207729
|
-
}
|
|
207730
|
-
}
|
|
207731
|
-
var BITCOIN_BATCH = 2016;
|
|
207732
|
-
async function findAnchor(low, high, window2, probe, maxProbes = 32) {
|
|
207733
|
-
let [lo, hi] = [low, high];
|
|
207734
|
-
const target = (window2[0] + window2[1]) / 2;
|
|
207735
|
-
let bisect = false;
|
|
207736
|
-
for (let i = 0;i < maxProbes; i++) {
|
|
207737
|
-
const span = hi.height - lo.height;
|
|
207738
|
-
if (span <= 1)
|
|
207739
|
-
return null;
|
|
207740
|
-
let h = Math.floor((lo.height + hi.height) / 2);
|
|
207741
|
-
if (!bisect && lo.burn !== undefined && hi.burn !== undefined && hi.burn > lo.burn)
|
|
207742
|
-
h = lo.height + Math.round((target - lo.burn) * span / (hi.burn - lo.burn));
|
|
207743
|
-
h = Math.min(Math.max(h, lo.height + 1), hi.height - 1);
|
|
207744
|
-
const p = await probe(h);
|
|
207745
|
-
if (p.height <= lo.height || p.height >= hi.height)
|
|
207746
|
-
return null;
|
|
207747
|
-
if (p.burn >= window2[0] && p.burn < window2[1])
|
|
207748
|
-
return p;
|
|
207749
|
-
if (p.burn < window2[0])
|
|
207750
|
-
lo = p;
|
|
207751
|
-
else
|
|
207752
|
-
hi = p;
|
|
207753
|
-
bisect = hi.height - lo.height > span / 2;
|
|
207754
|
-
}
|
|
207755
|
-
return null;
|
|
207756
|
-
}
|
|
207757
|
-
|
|
207758
|
-
class BlockVerifier {
|
|
207759
|
-
#source;
|
|
207760
|
-
#checkpoint;
|
|
207761
|
-
#chain;
|
|
207762
|
-
#sets = new Map;
|
|
207763
|
-
#anchors = new Map;
|
|
207764
|
-
#headers = new Map;
|
|
207765
|
-
#burns = new Map;
|
|
207766
|
-
#preimages = new Map;
|
|
207767
|
-
#start;
|
|
207768
|
-
constructor(opts) {
|
|
207769
|
-
this.#source = opts.source;
|
|
207770
|
-
this.#checkpoint = opts.checkpoint ?? MAINNET_CHECKPOINT;
|
|
207771
|
-
const { stacks } = this.#checkpoint;
|
|
207772
|
-
const header = parseNakamotoHeader(unhex(stacks.header));
|
|
207773
|
-
this.#start = { header, id: hex(blockId(header)) };
|
|
207774
|
-
this.#headers.set(this.#start.id, header);
|
|
207775
|
-
this.#sets.set(stacks.cycle, decodeSignerSet(stacks.signerSet));
|
|
207776
|
-
this.#chain = HeaderChain.fromCheckpoint(this.#checkpoint.bitcoin);
|
|
207777
|
-
}
|
|
207778
|
-
async verify(ref) {
|
|
207779
|
-
const out = { ok: false, notes: [], failures: [] };
|
|
207780
|
-
try {
|
|
207781
|
-
await this.#verify(ref, out);
|
|
207782
|
-
} catch (err) {
|
|
207783
|
-
if (!(err instanceof Broken))
|
|
207784
|
-
throw err;
|
|
207785
|
-
out.failures.unshift(err.failure);
|
|
207786
|
-
}
|
|
207787
|
-
out.ok = out.failures.length === 0;
|
|
207788
|
-
return out;
|
|
207789
|
-
}
|
|
207790
|
-
async#verify(ref, out) {
|
|
207791
|
-
const src = this.#source;
|
|
207792
|
-
const raw = await fetchFor("block", `block ${ref}`, () => src.getBlock(ref));
|
|
207793
|
-
const header = parseHeader2(raw, "block");
|
|
207794
|
-
const id = hex(blockId(header));
|
|
207795
|
-
const height = Number(header.chainLength);
|
|
207796
|
-
if (typeof ref === "string" && id !== ref.replace(/^0x/, "").toLowerCase())
|
|
207797
|
-
fail({
|
|
207798
|
-
step: "block",
|
|
207799
|
-
code: "id-mismatch",
|
|
207800
|
-
message: `source returned block ${id} for ${ref}`
|
|
207801
|
-
});
|
|
207802
|
-
if (typeof ref === "number" && height !== ref)
|
|
207803
|
-
fail({
|
|
207804
|
-
step: "block",
|
|
207805
|
-
code: "height-mismatch",
|
|
207806
|
-
message: `source returned height ${height} for ${ref}`
|
|
207807
|
-
});
|
|
207808
|
-
out.height = height;
|
|
207809
|
-
out.blockId = id;
|
|
207810
|
-
out.stateRoot = hex(header.stateIndexRoot);
|
|
207811
|
-
const burn = await this.#bindBurn(header, "burn");
|
|
207812
|
-
const cycle = rewardCycle(burn.burnHeight);
|
|
207813
|
-
out.burnHeight = burn.burnHeight;
|
|
207814
|
-
out.bitcoinBlockHash = burn.hash;
|
|
207815
|
-
out.cycle = cycle;
|
|
207816
|
-
const set = await this.#signerSet(cycle, {
|
|
207817
|
-
height,
|
|
207818
|
-
burn: burn.burnHeight
|
|
207819
|
-
});
|
|
207820
|
-
const sig = verifySignerSignatures(header, set);
|
|
207821
|
-
out.signerWeight = sig.signedWeight;
|
|
207822
|
-
out.totalWeight = sig.totalWeight;
|
|
207823
|
-
out.threshold = sig.threshold;
|
|
207824
|
-
if (!sig.valid)
|
|
207825
|
-
fail(signatureFailure(sig, "signatures", cycle));
|
|
207826
|
-
const witness = await fetchFor("witness", `witness ${id}`, () => src.getWitness(id));
|
|
207827
|
-
const { getStateWrites, getVmEvents } = src;
|
|
207828
|
-
const writes = getStateWrites ? await fetchFor("names", `state_writes ${height}`, () => getStateWrites.call(src, height)) : null;
|
|
207829
|
-
const rows = getVmEvents ? await fetchFor("rows", `vm_events ${height}`, () => getVmEvents.call(src, height)) : undefined;
|
|
207830
|
-
const parentId = hex(header.parentBlockId);
|
|
207831
|
-
const state = await verifyBlockState({
|
|
207832
|
-
height,
|
|
207833
|
-
parentBlockId: header.parentBlockId,
|
|
207834
|
-
stateRoot: header.stateIndexRoot,
|
|
207835
|
-
witness,
|
|
207836
|
-
writes,
|
|
207837
|
-
rows,
|
|
207838
|
-
parentLeaves: await this.#parentLeaves(parentId, out.notes),
|
|
207839
|
-
parentHolds: (leaf) => this.#parentHolds(parentId, leaf)
|
|
207840
|
-
});
|
|
207841
|
-
out.diff = state.diff;
|
|
207842
|
-
if (rows)
|
|
207843
|
-
out.rowsChecked = state.rowsChecked;
|
|
207844
|
-
out.notes.push(...state.notes);
|
|
207845
|
-
out.failures.push(...state.failures);
|
|
207846
|
-
}
|
|
207847
|
-
async#header(id, step, extra = {}) {
|
|
207848
|
-
const known = this.#headers.get(id);
|
|
207849
|
-
if (known)
|
|
207850
|
-
return known;
|
|
207851
|
-
const raw = await fetchFor(step, `block ${id}`, () => this.#source.getBlock(id), extra);
|
|
207852
|
-
const header = parseHeader2(raw, step);
|
|
207853
|
-
if (hex(blockId(header)) !== id)
|
|
207854
|
-
fail({
|
|
207855
|
-
step,
|
|
207856
|
-
code: "id-mismatch",
|
|
207857
|
-
message: `source returned another block for ${id}`,
|
|
207858
|
-
blockId: id,
|
|
207859
|
-
...extra
|
|
207860
|
-
});
|
|
207861
|
-
this.#headers.set(id, header);
|
|
207862
|
-
return header;
|
|
207863
|
-
}
|
|
207864
|
-
async#proveAt(tip, path, value, proof, step, extra = {}) {
|
|
207865
|
-
const headers = [tip];
|
|
207866
|
-
for (const id of marfProofAncestors(proof))
|
|
207867
|
-
headers.push(await this.#header(id, step, extra));
|
|
207868
|
-
return verifyMarfProof({
|
|
207869
|
-
proof,
|
|
207870
|
-
path,
|
|
207871
|
-
value,
|
|
207872
|
-
root: tip.stateIndexRoot,
|
|
207873
|
-
headers
|
|
207874
|
-
});
|
|
207875
|
-
}
|
|
207876
|
-
async#parentLeaves(parentId, notes) {
|
|
207877
|
-
try {
|
|
207878
|
-
const parent = await this.#header(parentId, "names");
|
|
207879
|
-
const w = parseWitness(await this.#source.getWitness(parentId));
|
|
207880
|
-
if (bytesEqual(w.root, parent.stateIndexRoot))
|
|
207881
|
-
return w.leaves;
|
|
207882
|
-
notes.push(`parent witness ${parentId} root does not match its header`);
|
|
207883
|
-
} catch (err) {
|
|
207884
|
-
notes.push(`parent witness ${parentId} unavailable: ${err.message}`);
|
|
207885
|
-
}
|
|
207886
|
-
return;
|
|
207887
|
-
}
|
|
207888
|
-
async#parentHolds(parentId, leaf) {
|
|
207889
|
-
const parent = await this.#header(parentId, "names");
|
|
207890
|
-
const pathHex = hex(leaf.path);
|
|
207891
|
-
const answer = await fetchFor("names", `MARF ${pathHex} at parent`, () => this.#source.getMarfProof(pathHex, parentId));
|
|
207892
|
-
if (!answer)
|
|
207893
|
-
return false;
|
|
207894
|
-
const value = new Uint8Array(MARF_VALUE_SIZE);
|
|
207895
|
-
value.set(leaf.valueHash);
|
|
207896
|
-
return this.#proveAt(parent, leaf.path, value, answer.proof, "names");
|
|
207897
|
-
}
|
|
207898
|
-
async#bindBurn(header, step, extra = {}) {
|
|
207899
|
-
const ch = hex(header.consensusHash);
|
|
207900
|
-
const known = this.#burns.get(ch);
|
|
207901
|
-
if (known)
|
|
207902
|
-
return known;
|
|
207903
|
-
const bp = await fetchFor(step, `burn preimage ${ch}`, () => this.#preimage(ch), extra);
|
|
207904
|
-
const hash = verifyConsensusPreimage(header.consensusHash, bp.preimage);
|
|
207905
|
-
if (!hash)
|
|
207906
|
-
return fail({
|
|
207907
|
-
step,
|
|
207908
|
-
code: "preimage-mismatch",
|
|
207909
|
-
message: `preimage does not hash to consensus hash ${ch}`,
|
|
207910
|
-
...extra
|
|
207911
|
-
});
|
|
207912
|
-
if (bp.burnHeight < this.#chain.checkpointHeight)
|
|
207913
|
-
fail({
|
|
207914
|
-
step,
|
|
207915
|
-
code: "before-checkpoint",
|
|
207916
|
-
message: `burn height ${bp.burnHeight} is below the Bitcoin checkpoint ${this.#chain.checkpointHeight}`,
|
|
207917
|
-
...extra
|
|
207918
|
-
});
|
|
207919
|
-
await this.#syncBitcoin(bp.burnHeight);
|
|
207920
|
-
const burnHeight = this.#chain.heightOf(hash);
|
|
207921
|
-
if (burnHeight === undefined)
|
|
207922
|
-
return fail({
|
|
207923
|
-
step,
|
|
207924
|
-
code: "burn-not-in-chain",
|
|
207925
|
-
message: `burn block ${hash} is not in the verified Bitcoin chain (synced ${this.#chain.checkpointHeight}..${this.#chain.tip.height})`,
|
|
207926
|
-
...extra
|
|
207927
|
-
});
|
|
207928
|
-
const bound = { burnHeight, hash };
|
|
207929
|
-
this.#burns.set(ch, bound);
|
|
207930
|
-
return bound;
|
|
207931
|
-
}
|
|
207932
|
-
async#syncBitcoin(height) {
|
|
207933
|
-
while (this.#chain.tip.height < height) {
|
|
207934
|
-
const from = this.#chain.tip.height + 1;
|
|
207935
|
-
const count = Math.min(BITCOIN_BATCH, height - from + 1);
|
|
207936
|
-
const headers = await fetchFor("bitcoin", `bitcoin headers ${from}`, () => this.#source.getBitcoinHeaders(from, count));
|
|
207937
|
-
if (headers.length === 0)
|
|
207938
|
-
fail({
|
|
207939
|
-
step: "bitcoin",
|
|
207940
|
-
code: "unavailable",
|
|
207941
|
-
message: `source has no Bitcoin headers from ${from}`
|
|
207942
|
-
});
|
|
207943
|
-
try {
|
|
207944
|
-
this.#chain.append(headers);
|
|
207945
|
-
} catch (err) {
|
|
207946
|
-
if (!(err instanceof HeaderValidationError))
|
|
207947
|
-
throw err;
|
|
207948
|
-
fail({ step: "bitcoin", code: "invalid-header", message: err.message });
|
|
207949
|
-
}
|
|
207950
|
-
}
|
|
207951
|
-
}
|
|
207952
|
-
async#signerSet(cycle, target) {
|
|
207953
|
-
const known = this.#sets.get(cycle);
|
|
207954
|
-
if (known)
|
|
207955
|
-
return known;
|
|
207956
|
-
const first = this.#checkpoint.stacks.cycle;
|
|
207957
|
-
if (cycle < first)
|
|
207958
|
-
fail({
|
|
207959
|
-
step: "signer-set",
|
|
207960
|
-
code: "before-checkpoint",
|
|
207961
|
-
message: `cycle ${cycle} precedes the checkpoint's cycle ${first}`,
|
|
207962
|
-
cycle
|
|
207963
|
-
});
|
|
207964
|
-
let lo = await this.#startPoint();
|
|
207965
|
-
for (let c = first;c < cycle; c++) {
|
|
207966
|
-
const next = this.#sets.get(c + 1);
|
|
207967
|
-
if (next) {
|
|
207968
|
-
lo = this.#anchors.get(c + 1) ?? lo;
|
|
207969
|
-
continue;
|
|
207970
|
-
}
|
|
207971
|
-
const anchor = await this.#findAnchor(c + 1, lo, target);
|
|
207972
|
-
this.#sets.set(c + 1, await this.#proveNextSet(c + 1, anchor));
|
|
207973
|
-
this.#anchors.set(c + 1, anchor);
|
|
207974
|
-
lo = anchor;
|
|
207975
|
-
}
|
|
207976
|
-
return this.#sets.get(cycle);
|
|
207977
|
-
}
|
|
207978
|
-
async#startPoint() {
|
|
207979
|
-
const { header } = this.#start;
|
|
207980
|
-
const height = Number(header.chainLength);
|
|
207981
|
-
try {
|
|
207982
|
-
return { height, burn: await this.#burnHint(header) };
|
|
207983
|
-
} catch {
|
|
207984
|
-
return { height };
|
|
207985
|
-
}
|
|
207986
|
-
}
|
|
207987
|
-
async#burnHint(header) {
|
|
207988
|
-
const ch = hex(header.consensusHash);
|
|
207989
|
-
return this.#burns.get(ch)?.burnHeight ?? (await this.#preimage(ch)).burnHeight;
|
|
207990
|
-
}
|
|
207991
|
-
async#preimage(ch) {
|
|
207992
|
-
let bp = this.#preimages.get(ch);
|
|
207993
|
-
if (!bp) {
|
|
207994
|
-
bp = await this.#source.getBurnPreimage(ch);
|
|
207995
|
-
this.#preimages.set(ch, bp);
|
|
207996
|
-
}
|
|
207997
|
-
return bp;
|
|
207998
|
-
}
|
|
207999
|
-
async#findAnchor(cycle, lo, hi) {
|
|
208000
|
-
const start = cycleStart(cycle);
|
|
208001
|
-
const window2 = [start - MAINNET_PREPARE_LENGTH, start];
|
|
208002
|
-
const probe = async (h) => {
|
|
208003
|
-
const raw = await fetchFor("signer-set", `block at height ${h}`, () => this.#source.getBlock(h), { cycle });
|
|
208004
|
-
const header = parseHeader2(raw, "signer-set");
|
|
208005
|
-
const id = hex(blockId(header));
|
|
208006
|
-
this.#headers.set(id, header);
|
|
208007
|
-
const burn = await fetchFor("signer-set", `burn hint for block ${id}`, () => this.#burnHint(header), { cycle, blockId: id });
|
|
208008
|
-
return { height: Number(header.chainLength), burn, header, id };
|
|
208009
|
-
};
|
|
208010
|
-
const anchor = await findAnchor(lo, hi, window2, probe);
|
|
208011
|
-
if (!anchor)
|
|
208012
|
-
return fail({
|
|
208013
|
-
step: "signer-set",
|
|
208014
|
-
code: "anchor-not-found",
|
|
208015
|
-
message: `no block with a burn height in ${window2[0]}..${window2[1] - 1} (cycle ${cycle} prepare phase) between heights ${lo.height} and ${hi.height}`,
|
|
208016
|
-
cycle
|
|
208017
|
-
});
|
|
208018
|
-
return anchor;
|
|
208019
|
-
}
|
|
208020
|
-
async#proveNextSet(cycle, anchor) {
|
|
208021
|
-
const at = { cycle, blockId: anchor.id };
|
|
208022
|
-
const { burnHeight } = await this.#bindBurn(anchor.header, "signer-set", at);
|
|
208023
|
-
const start = cycleStart(cycle);
|
|
208024
|
-
if (burnHeight < start - MAINNET_PREPARE_LENGTH || burnHeight >= start)
|
|
208025
|
-
fail({
|
|
208026
|
-
step: "signer-set",
|
|
208027
|
-
code: "anchor-outside-window",
|
|
208028
|
-
message: `anchor burn height ${burnHeight} is outside cycle ${cycle}'s prepare phase ${start - MAINNET_PREPARE_LENGTH}..${start - 1}`,
|
|
208029
|
-
...at
|
|
208030
|
-
});
|
|
208031
|
-
const signing = rewardCycle(burnHeight);
|
|
208032
|
-
const sig = verifySignerSignatures(anchor.header, this.#sets.get(signing));
|
|
208033
|
-
if (!sig.valid)
|
|
208034
|
-
fail({
|
|
208035
|
-
...signatureFailure(sig, "signer-set", signing),
|
|
208036
|
-
...at,
|
|
208037
|
-
code: "anchor-unsigned"
|
|
208038
|
-
});
|
|
208039
|
-
const path = marfPath(mapEntryKey(SIGNERS_CONTRACT, "cycle-signer-set", uintCV(cycle)));
|
|
208040
|
-
const answer = await fetchFor("signer-set", `signer set ${cycle} at ${anchor.id}`, () => this.#source.getMarfProof(hex(path), anchor.id), at);
|
|
208041
|
-
const value = answer?.data.replace(/^0x/, "") ?? "";
|
|
208042
|
-
const proven = answer !== null && await this.#proveAt(anchor.header, path, marfValue(value), answer.proof, "signer-set", at);
|
|
208043
|
-
if (!proven)
|
|
208044
|
-
fail({
|
|
208045
|
-
step: "signer-set",
|
|
208046
|
-
code: "set-proof-invalid",
|
|
208047
|
-
message: `signer set ${cycle} is not proven in anchor ${anchor.id}'s state`,
|
|
208048
|
-
...at
|
|
208049
|
-
});
|
|
208050
|
-
let set;
|
|
208051
|
-
try {
|
|
208052
|
-
set = decodeSignerSet(value);
|
|
208053
|
-
} catch (err) {
|
|
208054
|
-
return fail({
|
|
208055
|
-
step: "signer-set",
|
|
208056
|
-
code: "set-proof-invalid",
|
|
208057
|
-
message: `signer set ${cycle}: ${err.message}`,
|
|
208058
|
-
...at
|
|
208059
|
-
});
|
|
208060
|
-
}
|
|
208061
|
-
return set;
|
|
208062
|
-
}
|
|
208063
|
-
}
|
|
208064
|
-
function parseHeader2(raw, step) {
|
|
208065
|
-
try {
|
|
208066
|
-
return parseNakamotoHeader(raw);
|
|
208067
|
-
} catch (err) {
|
|
208068
|
-
return fail({
|
|
208069
|
-
step,
|
|
208070
|
-
code: "invalid-header",
|
|
208071
|
-
message: `block bytes do not parse: ${err.message}`
|
|
208072
|
-
});
|
|
208073
|
-
}
|
|
208074
|
-
}
|
|
208075
|
-
function signatureFailure(sig, step, cycle) {
|
|
208076
|
-
const weight = `${sig.signedWeight}/${sig.totalWeight} signed, threshold ${sig.threshold}`;
|
|
208077
|
-
if (sig.unknown.length)
|
|
208078
|
-
return {
|
|
208079
|
-
step,
|
|
208080
|
-
code: "unknown-signer",
|
|
208081
|
-
message: `${sig.unknown.length} signer(s) not in cycle ${cycle}'s set (${weight})`,
|
|
208082
|
-
cycle
|
|
208083
|
-
};
|
|
208084
|
-
if (sig.duplicates.length)
|
|
208085
|
-
return {
|
|
208086
|
-
step,
|
|
208087
|
-
code: "duplicate-signer",
|
|
208088
|
-
message: `${sig.duplicates.length} duplicate signature(s) (${weight})`,
|
|
208089
|
-
cycle
|
|
208090
|
-
};
|
|
208091
|
-
if (sig.invalid)
|
|
208092
|
-
return {
|
|
208093
|
-
step,
|
|
208094
|
-
code: "bad-signature",
|
|
208095
|
-
message: `${sig.invalid} signature(s) do not recover (${weight})`,
|
|
208096
|
-
cycle
|
|
208097
|
-
};
|
|
208098
|
-
return {
|
|
208099
|
-
step,
|
|
208100
|
-
code: "below-threshold",
|
|
208101
|
-
message: `cycle ${cycle} signers: ${weight}`,
|
|
208102
|
-
cycle
|
|
208103
|
-
};
|
|
208104
|
-
}
|
|
208105
204005
|
// src/commands/verify-block.ts
|
|
208106
204006
|
init_output();
|
|
208107
204007
|
init_resolve_auth();
|
|
204008
|
+
import { readFile as readFile3 } from "node:fs/promises";
|
|
204009
|
+
import {
|
|
204010
|
+
BlockVerifier,
|
|
204011
|
+
MAINNET_CHECKPOINT,
|
|
204012
|
+
NodeRpcProofSource,
|
|
204013
|
+
SecondlayerProofSource,
|
|
204014
|
+
parseNakamotoHeader,
|
|
204015
|
+
unhex
|
|
204016
|
+
} from "@secondlayer/verify";
|
|
208108
204017
|
var LINKS = [
|
|
204018
|
+
{ step: "ancestry", label: "ancestry" },
|
|
208109
204019
|
{ step: "block", label: "block" },
|
|
208110
204020
|
{ step: "bitcoin", label: "bitcoin" },
|
|
208111
204021
|
{ step: "burn", label: "burn" },
|
|
@@ -208142,7 +204052,7 @@ function defaultSource(node) {
|
|
|
208142
204052
|
});
|
|
208143
204053
|
return node ? { ...api, ...new NodeRpcProofSource({ nodeUrl: node }) } : api;
|
|
208144
204054
|
}
|
|
208145
|
-
function prepareSource(src
|
|
204055
|
+
function prepareSource(src) {
|
|
208146
204056
|
const out = {
|
|
208147
204057
|
getBlock: (ref) => src.getBlock(ref),
|
|
208148
204058
|
getMarfProof: (path, tip) => src.getMarfProof(path, tip),
|
|
@@ -208156,10 +204066,12 @@ function prepareSource(src, rows) {
|
|
|
208156
204066
|
return src.getBitcoinHeaders(from, count);
|
|
208157
204067
|
}
|
|
208158
204068
|
};
|
|
208159
|
-
const { getStateWrites, getVmEvents } = src;
|
|
208160
|
-
if (
|
|
204069
|
+
const { getEpoch2Header, getStateWrites, getVmEvents } = src;
|
|
204070
|
+
if (getEpoch2Header)
|
|
204071
|
+
out.getEpoch2Header = (id) => getEpoch2Header.call(src, id);
|
|
204072
|
+
if (getStateWrites)
|
|
208161
204073
|
out.getStateWrites = (height) => getStateWrites.call(src, height);
|
|
208162
|
-
if (
|
|
204074
|
+
if (getVmEvents)
|
|
208163
204075
|
out.getVmEvents = (height) => {
|
|
208164
204076
|
note(` fetching indexed rows for ${n(height)}`);
|
|
208165
204077
|
return getVmEvents.call(src, height);
|
|
@@ -208168,6 +204080,14 @@ function prepareSource(src, rows) {
|
|
|
208168
204080
|
}
|
|
208169
204081
|
function linkDetail(step, r, cp, rows) {
|
|
208170
204082
|
switch (step) {
|
|
204083
|
+
case "ancestry": {
|
|
204084
|
+
const a = r.ancestry;
|
|
204085
|
+
if (!a)
|
|
204086
|
+
return "";
|
|
204087
|
+
const checkpoint = parseNakamotoHeader(unhex(cp.stacks.header));
|
|
204088
|
+
const start = a.fromHeight === Number(checkpoint.chainLength) ? `the checkpoint ${n(a.fromHeight)}` : `block ${n(a.fromHeight)}`;
|
|
204089
|
+
return a.via === "marf" ? `${n(r.height ?? 0)} proven in the state of ${start} (one MARF proof)` : `${n(r.height ?? 0)} reached from ${start} by parent links`;
|
|
204090
|
+
}
|
|
208171
204091
|
case "block":
|
|
208172
204092
|
return `${n(r.height ?? 0)} ${r.blockId}`;
|
|
208173
204093
|
case "bitcoin":
|
|
@@ -208192,18 +204112,29 @@ function linkDetail(step, r, cp, rows) {
|
|
|
208192
204112
|
return `${n(r.rowsChecked ?? 0)} vm_events rows match the diff`;
|
|
208193
204113
|
}
|
|
208194
204114
|
}
|
|
204115
|
+
function notNeeded(step, r) {
|
|
204116
|
+
if (!r.ancestry)
|
|
204117
|
+
return false;
|
|
204118
|
+
if (step === "bitcoin" || step === "burn")
|
|
204119
|
+
return r.burnHeight === undefined;
|
|
204120
|
+
return step === "signer-set" || step === "signatures";
|
|
204121
|
+
}
|
|
208195
204122
|
function report(r, cp, rows) {
|
|
208196
204123
|
const first = r.failures[0];
|
|
208197
204124
|
const broken = first ? LINKS.findIndex((l) => l.step === first.step) : LINKS.length;
|
|
208198
204125
|
for (const [i, link] of LINKS.entries()) {
|
|
208199
204126
|
const label = link.label.padEnd(LABEL_WIDTH);
|
|
208200
204127
|
const failure = r.failures.find((f) => f.step === link.step);
|
|
204128
|
+
if (link.step === "ancestry" && !failure && !r.ancestry)
|
|
204129
|
+
continue;
|
|
208201
204130
|
if (failure)
|
|
208202
204131
|
writeData(`${red("✗")} ${label} ${failure.message}`);
|
|
208203
204132
|
else if (link.step === "rows" && !rows)
|
|
208204
204133
|
writeData(dim(`· ${label} not checked (pass --rows)`));
|
|
208205
204134
|
else if (i > broken)
|
|
208206
204135
|
writeData(dim(`· ${label} not checked: an earlier link is broken`));
|
|
204136
|
+
else if (notNeeded(link.step, r))
|
|
204137
|
+
writeData(dim(`· ${label} not needed: the block is hash-chained to the checkpoint`));
|
|
208207
204138
|
else if (link.step === "rows" && r.rowsChecked === undefined)
|
|
208208
204139
|
writeData(dim(`· ${label} not checked: the source serves no indexed rows`));
|
|
208209
204140
|
else
|
|
@@ -208235,8 +204166,8 @@ async function runVerifyBlock(ref, opts, deps = {}) {
|
|
|
208235
204166
|
try {
|
|
208236
204167
|
target = parseBlockRef(ref);
|
|
208237
204168
|
checkpoint = opts.checkpoint ? await readCheckpoint(opts.checkpoint) : MAINNET_CHECKPOINT;
|
|
208238
|
-
const source = prepareSource(deps.source ?? defaultSource(opts.node)
|
|
208239
|
-
verifier = new BlockVerifier({ source, checkpoint });
|
|
204169
|
+
const source = prepareSource(deps.source ?? defaultSource(opts.node));
|
|
204170
|
+
verifier = new BlockVerifier({ source, checkpoint, rows: !!opts.rows });
|
|
208240
204171
|
} catch (err) {
|
|
208241
204172
|
printError(err instanceof Error ? err.message : String(err));
|
|
208242
204173
|
return VERIFY_EXIT.UNANCHORED;
|
|
@@ -208252,6 +204183,8 @@ async function runVerifyBlock(ref, opts, deps = {}) {
|
|
|
208252
204183
|
function attachVerifyBlockCommand(verify) {
|
|
208253
204184
|
return verify.command("block").description("Prove one Stacks block from the checkpoint built into this release, trusting nothing else").argument("<ref>", "block height or index block hash").option("--node <url>", "read blocks and MARF proofs from this Stacks node RPC instead of the API").option("--checkpoint <file>", "trust this checkpoint JSON instead of the one built into this release").option("--rows", "also prove the indexer's rows for the block (state_writes, vm_events) against its state diff").addHelpText("after", `
|
|
208254
204185
|
What is proven, link by link:
|
|
204186
|
+
ancestry below the checkpoint only: the block's id, from the checkpoint by
|
|
204187
|
+
parent links or one MARF proof (signer links are then not needed)
|
|
208255
204188
|
bitcoin headers from the checkpoint to the block's burn block: proof-of-work and retargets
|
|
208256
204189
|
burn the block's consensus hash commits to that Bitcoin block
|
|
208257
204190
|
cycle the reward cycle's signer set, proven forward from the checkpoint's set
|
|
@@ -210549,7 +206482,7 @@ init_output();
|
|
|
210549
206482
|
init_resolve_auth();
|
|
210550
206483
|
|
|
210551
206484
|
// src/commands/faucet.ts
|
|
210552
|
-
import { randomBytes as
|
|
206485
|
+
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
210553
206486
|
import { readFile as readFile5 } from "node:fs/promises";
|
|
210554
206487
|
import { join as join11 } from "node:path";
|
|
210555
206488
|
import { http as http3, createWalletClient } from "@secondlayer/stacks";
|
|
@@ -210635,8 +206568,8 @@ is what makes minting possible without Bitcoin.`).action(async (opts) => {
|
|
|
210635
206568
|
chain: devnet,
|
|
210636
206569
|
transport: http3(rpcUrl)
|
|
210637
206570
|
});
|
|
210638
|
-
const depositTxid =
|
|
210639
|
-
const sweepTxid =
|
|
206571
|
+
const depositTxid = randomBytes2(32).toString("hex");
|
|
206572
|
+
const sweepTxid = randomBytes2(32).toString("hex");
|
|
210640
206573
|
note(` minting ${amount} sats to ${opts.to}`);
|
|
210641
206574
|
note(` via ${contract} as signer ${account.address}`);
|
|
210642
206575
|
const txid = await client.callContract({
|
|
@@ -211909,7 +207842,7 @@ import { planUninstall, uninstallCommand } from "@secondlayer/shared/runtime";
|
|
|
211909
207842
|
|
|
211910
207843
|
// src/lib/instance-init.ts
|
|
211911
207844
|
init_output();
|
|
211912
|
-
import { randomBytes as
|
|
207845
|
+
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
211913
207846
|
import { existsSync as existsSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync7 } from "node:fs";
|
|
211914
207847
|
import { resolve as resolve10 } from "node:path";
|
|
211915
207848
|
import { ARCHIVE_ROOT_PUBLIC_KEY_PEM } from "@secondlayer/shared/archive/root-key";
|
|
@@ -211938,10 +207871,10 @@ function instanceNetworkFromEnv(fallback = "mainnet") {
|
|
|
211938
207871
|
}
|
|
211939
207872
|
}
|
|
211940
207873
|
function generateInstanceToken() {
|
|
211941
|
-
return
|
|
207874
|
+
return randomBytes3(32).toString("hex");
|
|
211942
207875
|
}
|
|
211943
207876
|
function generateSecretsKey() {
|
|
211944
|
-
return
|
|
207877
|
+
return randomBytes3(32).toString("hex");
|
|
211945
207878
|
}
|
|
211946
207879
|
function generateSigningPrivateKey() {
|
|
211947
207880
|
return generateEd25519KeyPair().privateKeyPem;
|
|
@@ -212760,7 +208693,7 @@ dbcache=4096
|
|
|
212760
208693
|
|
|
212761
208694
|
// src/lib/setup-wizard.ts
|
|
212762
208695
|
import { spawn as spawn3, spawnSync as spawnSync5 } from "node:child_process";
|
|
212763
|
-
import { randomBytes as
|
|
208696
|
+
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
212764
208697
|
import { existsSync as existsSync12 } from "node:fs";
|
|
212765
208698
|
import { writeFile as writeFile6 } from "node:fs/promises";
|
|
212766
208699
|
import { createServer } from "node:net";
|
|
@@ -212861,7 +208794,7 @@ async function resolveAvailablePublishSpec(spec, claimedByDocker = new Set, maxA
|
|
|
212861
208794
|
return { spec, remapped: false };
|
|
212862
208795
|
}
|
|
212863
208796
|
function randomHex(bytes) {
|
|
212864
|
-
return
|
|
208797
|
+
return randomBytes4(bytes).toString("hex");
|
|
212865
208798
|
}
|
|
212866
208799
|
function resolveSecrets(config) {
|
|
212867
208800
|
const envPath = join17(config.dir, ".env");
|
|
@@ -213596,5 +209529,5 @@ registerCreditsCommand(program);
|
|
|
213596
209529
|
registerArchiveCommand(program);
|
|
213597
209530
|
program.parse();
|
|
213598
209531
|
|
|
213599
|
-
//# debugId=
|
|
209532
|
+
//# debugId=92924A7AE61FB1AF64756E2164756E21
|
|
213600
209533
|
//# sourceMappingURL=cli.js.map
|