@secondlayer/cli 19.1.2 → 19.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/cli.js +4352 -54
- package/dist/cli.js.map +32 -5
- package/package.json +5 -4
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 } from "node:crypto";
|
|
16261
|
+
import { randomBytes as randomBytes2 } 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-${randomBytes2(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, hex2, 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, 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);
|
|
16448
|
+
({ Ansis, fg, bg, rgb, bgRgb, hex: hex2, 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
|
|
@@ -16630,7 +16630,7 @@ var init_dist3 = __esm(() => {
|
|
|
16630
16630
|
// ../../node_modules/tinyexec/dist/main.js
|
|
16631
16631
|
import { createRequire as e } from "module";
|
|
16632
16632
|
import { spawn as t } from "node:child_process";
|
|
16633
|
-
import { delimiter as
|
|
16633
|
+
import { delimiter as n2, dirname as r, normalize as i, resolve as a2 } from "node:path";
|
|
16634
16634
|
import { cwd as o } from "node:process";
|
|
16635
16635
|
import { PassThrough as s } from "node:stream";
|
|
16636
16636
|
import c from "node:readline";
|
|
@@ -16649,7 +16649,7 @@ function x(e) {
|
|
|
16649
16649
|
return b;
|
|
16650
16650
|
}
|
|
16651
16651
|
function S(e, t) {
|
|
16652
|
-
const i = t.value.split(
|
|
16652
|
+
const i = t.value.split(n2);
|
|
16653
16653
|
let o = e;
|
|
16654
16654
|
let s;
|
|
16655
16655
|
do {
|
|
@@ -16659,7 +16659,7 @@ function S(e, t) {
|
|
|
16659
16659
|
} while (o !== s);
|
|
16660
16660
|
return {
|
|
16661
16661
|
key: t.key,
|
|
16662
|
-
value: i.join(
|
|
16662
|
+
value: i.join(n2)
|
|
16663
16663
|
};
|
|
16664
16664
|
}
|
|
16665
16665
|
function C(e, t) {
|
|
@@ -23945,19 +23945,19 @@ class c2 {
|
|
|
23945
23945
|
}
|
|
23946
23946
|
}
|
|
23947
23947
|
function i2() {
|
|
23948
|
-
return this[
|
|
23948
|
+
return this[n3].next();
|
|
23949
23949
|
}
|
|
23950
23950
|
function o2(r) {
|
|
23951
|
-
return this[
|
|
23951
|
+
return this[n3].return(r);
|
|
23952
23952
|
}
|
|
23953
23953
|
function h2({ preventCancel: r = false } = {}) {
|
|
23954
23954
|
const e = this.getReader(), t = new c2(e, r), s = Object.create(u2);
|
|
23955
|
-
return s[
|
|
23955
|
+
return s[n3] = t, s;
|
|
23956
23956
|
}
|
|
23957
|
-
var a3,
|
|
23957
|
+
var a3, n3, u2;
|
|
23958
23958
|
var init_asyncIterator = __esm(() => {
|
|
23959
23959
|
a3 = Object.getPrototypeOf(Object.getPrototypeOf(async function* () {}).prototype);
|
|
23960
|
-
|
|
23960
|
+
n3 = Symbol();
|
|
23961
23961
|
Object.defineProperty(i2, "name", { value: "next" });
|
|
23962
23962
|
Object.defineProperty(o2, "name", { value: "return" });
|
|
23963
23963
|
u2 = Object.create(a3, {
|
|
@@ -29053,13 +29053,13 @@ import { createHash as createHash3 } from "node:crypto";
|
|
|
29053
29053
|
import {
|
|
29054
29054
|
mkdir as mkdir2,
|
|
29055
29055
|
open,
|
|
29056
|
-
readFile as
|
|
29056
|
+
readFile as readFile4,
|
|
29057
29057
|
stat,
|
|
29058
29058
|
unlink as unlink3,
|
|
29059
29059
|
writeFile as writeFile4
|
|
29060
29060
|
} from "node:fs/promises";
|
|
29061
29061
|
async function readJsonFile(path) {
|
|
29062
|
-
const text = await
|
|
29062
|
+
const text = await readFile4(path, "utf-8");
|
|
29063
29063
|
return JSON.parse(text);
|
|
29064
29064
|
}
|
|
29065
29065
|
async function writeTextFile(path, content) {
|
|
@@ -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/node_modules/typescript/lib", __filename = "/Users/ryan/projects/secondlayer/node_modules/typescript/lib/typescript.js";
|
|
29443
|
+
var __dirname = "/Users/ryan/projects/secondlayer/.claude/worktrees/release/node_modules/typescript/lib", __filename = "/Users/ryan/projects/secondlayer/.claude/worktrees/release/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
|
|
@@ -198798,6 +198798,9 @@ import {
|
|
|
198798
198798
|
generatePrintSchemaSubgraph as generatePrintSchemaSubgraph2,
|
|
198799
198799
|
generateTraitSubgraph as generateTraitSubgraph2
|
|
198800
198800
|
} from "@secondlayer/scaffold";
|
|
198801
|
+
import {
|
|
198802
|
+
billingPausedCode
|
|
198803
|
+
} from "@secondlayer/shared/schemas";
|
|
198801
198804
|
import { TRAIT_STANDARDS } from "@secondlayer/stacks/clarity";
|
|
198802
198805
|
function webhookHint(apiUrl, name, firstTable) {
|
|
198803
198806
|
if (!firstTable || isMerchantUrl(apiUrl))
|
|
@@ -199150,6 +199153,10 @@ function formatOperationRange(op) {
|
|
|
199150
199153
|
return "whole subgraph";
|
|
199151
199154
|
return `${op.fromBlock ?? "start"} → ${op.toBlock ?? "tip"}`;
|
|
199152
199155
|
}
|
|
199156
|
+
function formatSubgraphStatus(status, lastError) {
|
|
199157
|
+
const code = billingPausedCode(lastError);
|
|
199158
|
+
return code ? `${status} (paused: ${code.replace(/_/g, " ")})` : status;
|
|
199159
|
+
}
|
|
199153
199160
|
function formatOperationProgress(progress) {
|
|
199154
199161
|
if (progress === null)
|
|
199155
199162
|
return "—";
|
|
@@ -199668,7 +199675,10 @@ ${data.length} subgraph(s) total`));
|
|
|
199668
199675
|
console.log(formatKeyValue([
|
|
199669
199676
|
["Name", subgraph.name],
|
|
199670
199677
|
["Version", subgraph.version],
|
|
199671
|
-
[
|
|
199678
|
+
[
|
|
199679
|
+
"Status",
|
|
199680
|
+
formatSubgraphStatus(subgraph.status, subgraph.health.lastError)
|
|
199681
|
+
],
|
|
199672
199682
|
["Sync", syncDisplay.line],
|
|
199673
199683
|
[syncDisplay.remainingLabel, syncDisplay.remaining],
|
|
199674
199684
|
["Integrity", integrity],
|
|
@@ -200238,7 +200248,7 @@ function client() {
|
|
|
200238
200248
|
apiKey: resolveDataPlaneKey()
|
|
200239
200249
|
});
|
|
200240
200250
|
}
|
|
200241
|
-
function
|
|
200251
|
+
function fail2(action, err) {
|
|
200242
200252
|
const message = err instanceof Error ? err.message : String(err);
|
|
200243
200253
|
error(`Failed to ${action}: ${message}`);
|
|
200244
200254
|
if (/\b403\b/.test(message) || /forbidden/i.test(message)) {
|
|
@@ -200291,7 +200301,7 @@ function registerIndexCommand(program) {
|
|
|
200291
200301
|
recipient: o.recipient
|
|
200292
200302
|
}), o.json);
|
|
200293
200303
|
} catch (err) {
|
|
200294
|
-
|
|
200304
|
+
fail2("list ft transfers", err);
|
|
200295
200305
|
}
|
|
200296
200306
|
});
|
|
200297
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) => {
|
|
@@ -200303,7 +200313,7 @@ function registerIndexCommand(program) {
|
|
|
200303
200313
|
assetIdentifier: o.assetIdentifier
|
|
200304
200314
|
}), o.json);
|
|
200305
200315
|
} catch (err) {
|
|
200306
|
-
|
|
200316
|
+
fail2("list nft transfers", err);
|
|
200307
200317
|
}
|
|
200308
200318
|
});
|
|
200309
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) => {
|
|
@@ -200316,7 +200326,7 @@ function registerIndexCommand(program) {
|
|
|
200316
200326
|
assetIdentifier: o.assetIdentifier
|
|
200317
200327
|
}), o.json);
|
|
200318
200328
|
} catch (err) {
|
|
200319
|
-
|
|
200329
|
+
fail2("list events", err);
|
|
200320
200330
|
}
|
|
200321
200331
|
});
|
|
200322
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) => {
|
|
@@ -200327,21 +200337,21 @@ function registerIndexCommand(program) {
|
|
|
200327
200337
|
sender: o.sender
|
|
200328
200338
|
}), o.json);
|
|
200329
200339
|
} catch (err) {
|
|
200330
|
-
|
|
200340
|
+
fail2("list contract calls", err);
|
|
200331
200341
|
}
|
|
200332
200342
|
});
|
|
200333
200343
|
heightFlags(index.command("canonical")).description("List the canonical Stacks block sequence (height + hash)").action(async (o) => {
|
|
200334
200344
|
try {
|
|
200335
200345
|
emit(await client().canonical.list(heightParams(o)), o.json);
|
|
200336
200346
|
} catch (err) {
|
|
200337
|
-
|
|
200347
|
+
fail2("list canonical blocks", err);
|
|
200338
200348
|
}
|
|
200339
200349
|
});
|
|
200340
200350
|
const blocks = heightFlags(index.command("blocks")).description("List decoded blocks (run `blocks get <ref>` for one block)").action(async (o) => {
|
|
200341
200351
|
try {
|
|
200342
200352
|
emit(await client().blocks.list(heightParams(o)), o.json);
|
|
200343
200353
|
} catch (err) {
|
|
200344
|
-
|
|
200354
|
+
fail2("list blocks", err);
|
|
200345
200355
|
}
|
|
200346
200356
|
});
|
|
200347
200357
|
blocks.command("get <ref>").description("Get a single block by height or block hash").option("--json", "Print as JSON").action(async (ref, o) => {
|
|
@@ -200349,7 +200359,7 @@ function registerIndexCommand(program) {
|
|
|
200349
200359
|
const block = await client().blocks.get(/^\d+$/.test(ref) ? Number.parseInt(ref, 10) : ref);
|
|
200350
200360
|
emitOne(block, `block ${ref}`, o.json);
|
|
200351
200361
|
} catch (err) {
|
|
200352
|
-
|
|
200362
|
+
fail2("get block", err);
|
|
200353
200363
|
}
|
|
200354
200364
|
});
|
|
200355
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) => {
|
|
@@ -200360,14 +200370,14 @@ function registerIndexCommand(program) {
|
|
|
200360
200370
|
sender: o.sender
|
|
200361
200371
|
}), o.json);
|
|
200362
200372
|
} catch (err) {
|
|
200363
|
-
|
|
200373
|
+
fail2("list transactions", err);
|
|
200364
200374
|
}
|
|
200365
200375
|
});
|
|
200366
200376
|
transactions.command("get <txId>").description("Get a single transaction by tx_id").option("--json", "Print as JSON").action(async (txId, o) => {
|
|
200367
200377
|
try {
|
|
200368
200378
|
emitOne(await client().transactions.get(txId), `tx ${txId}`, o.json);
|
|
200369
200379
|
} catch (err) {
|
|
200370
|
-
|
|
200380
|
+
fail2("get transaction", err);
|
|
200371
200381
|
}
|
|
200372
200382
|
});
|
|
200373
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) => {
|
|
@@ -200379,7 +200389,7 @@ function registerIndexCommand(program) {
|
|
|
200379
200389
|
caller: o.caller
|
|
200380
200390
|
}), o.json);
|
|
200381
200391
|
} catch (err) {
|
|
200382
|
-
|
|
200392
|
+
fail2("list stacking actions", err);
|
|
200383
200393
|
}
|
|
200384
200394
|
});
|
|
200385
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) => {
|
|
@@ -200393,14 +200403,14 @@ function registerIndexCommand(program) {
|
|
|
200393
200403
|
limit: o.limit ? Number.parseInt(o.limit, 10) : undefined
|
|
200394
200404
|
}), o.json);
|
|
200395
200405
|
} catch (err) {
|
|
200396
|
-
|
|
200406
|
+
fail2("list mempool", err);
|
|
200397
200407
|
}
|
|
200398
200408
|
});
|
|
200399
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) => {
|
|
200400
200410
|
try {
|
|
200401
200411
|
emitOne(await client().mempool.get(txId), `pending tx ${txId}`, o.json);
|
|
200402
200412
|
} catch (err) {
|
|
200403
|
-
|
|
200413
|
+
fail2("get mempool tx", err);
|
|
200404
200414
|
}
|
|
200405
200415
|
});
|
|
200406
200416
|
}
|
|
@@ -201459,10 +201469,10 @@ function Connection(options, queues = {}, { onopen = noop5, onend = noop5, onclo
|
|
|
201459
201469
|
async function SASLContinue(x) {
|
|
201460
201470
|
const res = x.toString("utf8", 9).split(",").reduce((acc, x) => (acc[x[0]] = x.slice(2), acc), {});
|
|
201461
201471
|
const saltedPassword = await crypto2.pbkdf2Sync(await Pass(), Buffer.from(res.s, "base64"), parseInt(res.i), 32, "sha256");
|
|
201462
|
-
const clientKey = await
|
|
201472
|
+
const clientKey = await hmac2(saltedPassword, "Client Key");
|
|
201463
201473
|
const auth = "n=*,r=" + nonce + "," + "r=" + res.r + ",s=" + res.s + ",i=" + res.i + ",c=biws,r=" + res.r;
|
|
201464
|
-
serverSignature = (await
|
|
201465
|
-
const payload = "c=biws,r=" + res.r + ",p=" + xor(clientKey, Buffer.from(await
|
|
201474
|
+
serverSignature = (await hmac2(await hmac2(saltedPassword, "Server Key"), auth)).toString("base64");
|
|
201475
|
+
const payload = "c=biws,r=" + res.r + ",p=" + xor(clientKey, Buffer.from(await hmac2(await sha2562(clientKey), auth))).toString("base64");
|
|
201466
201476
|
write(bytes_default().p().str(payload).end());
|
|
201467
201477
|
}
|
|
201468
201478
|
function SASLFinal(x) {
|
|
@@ -201681,10 +201691,10 @@ function parseError(x) {
|
|
|
201681
201691
|
function md5(x) {
|
|
201682
201692
|
return crypto2.createHash("md5").update(x).digest("hex");
|
|
201683
201693
|
}
|
|
201684
|
-
function
|
|
201694
|
+
function hmac2(key, x) {
|
|
201685
201695
|
return crypto2.createHmac("sha256", key).update(x).digest();
|
|
201686
201696
|
}
|
|
201687
|
-
function
|
|
201697
|
+
function sha2562(x) {
|
|
201688
201698
|
return crypto2.createHash("sha256").update(x).digest();
|
|
201689
201699
|
}
|
|
201690
201700
|
function xor(a, b) {
|
|
@@ -202516,7 +202526,7 @@ var {
|
|
|
202516
202526
|
// package.json
|
|
202517
202527
|
var package_default = {
|
|
202518
202528
|
name: "@secondlayer/cli",
|
|
202519
|
-
version: "19.
|
|
202529
|
+
version: "19.2.0",
|
|
202520
202530
|
description: "Run a Stacks index on your own hardware — set it up, restore verified history, and keep it current.",
|
|
202521
202531
|
repository: {
|
|
202522
202532
|
type: "git",
|
|
@@ -202555,10 +202565,10 @@ var package_default = {
|
|
|
202555
202565
|
"@inquirer/prompts": "^8.2.0",
|
|
202556
202566
|
"@secondlayer/bundler": "^0.6.1",
|
|
202557
202567
|
"@secondlayer/scaffold": "^1.6.1",
|
|
202558
|
-
"@secondlayer/sdk": "^14.
|
|
202559
|
-
"@secondlayer/shared": "^11.
|
|
202568
|
+
"@secondlayer/sdk": "^14.3.0",
|
|
202569
|
+
"@secondlayer/shared": "^11.20.0",
|
|
202560
202570
|
"@secondlayer/stacks": "^6.1.1",
|
|
202561
|
-
"@secondlayer/subgraphs": "^6.3.
|
|
202571
|
+
"@secondlayer/subgraphs": "^6.3.6",
|
|
202562
202572
|
esbuild: "^0.28.2",
|
|
202563
202573
|
"smol-toml": "^1.8.0",
|
|
202564
202574
|
zod: "^4.3.6"
|
|
@@ -202573,6 +202583,7 @@ var package_default = {
|
|
|
202573
202583
|
},
|
|
202574
202584
|
devDependencies: {
|
|
202575
202585
|
"@antfu/ni": "^24.4.0",
|
|
202586
|
+
"@secondlayer/verify": "workspace:*",
|
|
202576
202587
|
"@stacks/clarinet-sdk": "3.21.1",
|
|
202577
202588
|
"@types/bun": "^1.1.14",
|
|
202578
202589
|
chalk: "^5.3.0",
|
|
@@ -203990,6 +204001,4288 @@ import {
|
|
|
203990
204001
|
import { getDb as getDb3 } from "@secondlayer/shared/db";
|
|
203991
204002
|
init_output();
|
|
203992
204003
|
init_resolve_auth();
|
|
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
|
+
// src/commands/verify-block.ts
|
|
208106
|
+
init_output();
|
|
208107
|
+
init_resolve_auth();
|
|
208108
|
+
var LINKS = [
|
|
208109
|
+
{ step: "block", label: "block" },
|
|
208110
|
+
{ step: "bitcoin", label: "bitcoin" },
|
|
208111
|
+
{ step: "burn", label: "burn" },
|
|
208112
|
+
{ step: "signer-set", label: "cycle" },
|
|
208113
|
+
{ step: "signatures", label: "signatures" },
|
|
208114
|
+
{ step: "witness", label: "state root" },
|
|
208115
|
+
{ step: "names", label: "diff" },
|
|
208116
|
+
{ step: "rows", label: "rows" }
|
|
208117
|
+
];
|
|
208118
|
+
var LABEL_WIDTH = Math.max(...LINKS.map((l) => l.label.length));
|
|
208119
|
+
var n = (v) => v.toLocaleString("en-US");
|
|
208120
|
+
function parseBlockRef(raw) {
|
|
208121
|
+
if (/^\d+$/.test(raw)) {
|
|
208122
|
+
const height = Number(raw);
|
|
208123
|
+
if (Number.isSafeInteger(height))
|
|
208124
|
+
return height;
|
|
208125
|
+
}
|
|
208126
|
+
const hash = raw.replace(/^0x/i, "").toLowerCase();
|
|
208127
|
+
if (/^[0-9a-f]{64}$/.test(hash))
|
|
208128
|
+
return hash;
|
|
208129
|
+
throw new Error(`expected a block height or a 64-hex index block hash, got "${raw}"`);
|
|
208130
|
+
}
|
|
208131
|
+
async function readCheckpoint(path) {
|
|
208132
|
+
const cp = JSON.parse(await readFile3(path, "utf8"));
|
|
208133
|
+
const ok = typeof cp?.stacks?.header === "string" && Number.isSafeInteger(cp.stacks.cycle) && typeof cp.stacks.signerSet === "string" && Number.isSafeInteger(cp.bitcoin?.height) && typeof cp.bitcoin?.header === "string";
|
|
208134
|
+
if (!ok)
|
|
208135
|
+
throw new Error(`${path}: a checkpoint needs stacks.{header, cycle, signerSet} and bitcoin.{height, header}`);
|
|
208136
|
+
return cp;
|
|
208137
|
+
}
|
|
208138
|
+
function defaultSource(node) {
|
|
208139
|
+
const api = new SecondlayerProofSource({
|
|
208140
|
+
baseUrl: resolveApiUrl(),
|
|
208141
|
+
apiKey: resolveDataPlaneKey() ?? ""
|
|
208142
|
+
});
|
|
208143
|
+
return node ? { ...api, ...new NodeRpcProofSource({ nodeUrl: node }) } : api;
|
|
208144
|
+
}
|
|
208145
|
+
function prepareSource(src, rows) {
|
|
208146
|
+
const out = {
|
|
208147
|
+
getBlock: (ref) => src.getBlock(ref),
|
|
208148
|
+
getMarfProof: (path, tip) => src.getMarfProof(path, tip),
|
|
208149
|
+
getBurnPreimage: (ch) => src.getBurnPreimage(ch),
|
|
208150
|
+
getWitness: (id) => {
|
|
208151
|
+
note(` fetching state witness ${id}`);
|
|
208152
|
+
return src.getWitness(id);
|
|
208153
|
+
},
|
|
208154
|
+
getBitcoinHeaders: (from, count) => {
|
|
208155
|
+
note(` syncing Bitcoin headers ${n(from)}..${n(from + count - 1)}`);
|
|
208156
|
+
return src.getBitcoinHeaders(from, count);
|
|
208157
|
+
}
|
|
208158
|
+
};
|
|
208159
|
+
const { getStateWrites, getVmEvents } = src;
|
|
208160
|
+
if (rows && getStateWrites)
|
|
208161
|
+
out.getStateWrites = (height) => getStateWrites.call(src, height);
|
|
208162
|
+
if (rows && getVmEvents)
|
|
208163
|
+
out.getVmEvents = (height) => {
|
|
208164
|
+
note(` fetching indexed rows for ${n(height)}`);
|
|
208165
|
+
return getVmEvents.call(src, height);
|
|
208166
|
+
};
|
|
208167
|
+
return out;
|
|
208168
|
+
}
|
|
208169
|
+
function linkDetail(step, r, cp, rows) {
|
|
208170
|
+
switch (step) {
|
|
208171
|
+
case "block":
|
|
208172
|
+
return `${n(r.height ?? 0)} ${r.blockId}`;
|
|
208173
|
+
case "bitcoin":
|
|
208174
|
+
return `headers ${n(cp.bitcoin.height)}..${n(r.burnHeight ?? 0)}, proof-of-work and retargets checked`;
|
|
208175
|
+
case "burn":
|
|
208176
|
+
return `height ${n(r.burnHeight ?? 0)} ${r.bitcoinBlockHash}`;
|
|
208177
|
+
case "signer-set":
|
|
208178
|
+
return r.cycle === cp.stacks.cycle ? `${r.cycle}, the checkpoint's own signer set` : `${r.cycle}, signer set proven forward from checkpoint cycle ${cp.stacks.cycle}`;
|
|
208179
|
+
case "signatures":
|
|
208180
|
+
return `${n(r.signerWeight ?? 0n)} / ${n(r.totalWeight ?? 0n)} weight signed, threshold ${n(r.threshold ?? 0n)}`;
|
|
208181
|
+
case "witness":
|
|
208182
|
+
return `${r.stateRoot} matches the witness`;
|
|
208183
|
+
case "names": {
|
|
208184
|
+
const d = r.diff;
|
|
208185
|
+
if (!d)
|
|
208186
|
+
return "";
|
|
208187
|
+
const named = d.writes.filter((w) => w.named).length;
|
|
208188
|
+
const written = named ? `${d.writes.length} written (${named} named, ${d.writes.length - named} unnamed)` : `${d.writes.length} written (unnamed${rows ? "" : "; --rows names them"})`;
|
|
208189
|
+
return `${written}, ${d.carried.length} carried, ${d.internal.length} internal`;
|
|
208190
|
+
}
|
|
208191
|
+
case "rows":
|
|
208192
|
+
return `${n(r.rowsChecked ?? 0)} vm_events rows match the diff`;
|
|
208193
|
+
}
|
|
208194
|
+
}
|
|
208195
|
+
function report(r, cp, rows) {
|
|
208196
|
+
const first = r.failures[0];
|
|
208197
|
+
const broken = first ? LINKS.findIndex((l) => l.step === first.step) : LINKS.length;
|
|
208198
|
+
for (const [i, link] of LINKS.entries()) {
|
|
208199
|
+
const label = link.label.padEnd(LABEL_WIDTH);
|
|
208200
|
+
const failure = r.failures.find((f) => f.step === link.step);
|
|
208201
|
+
if (failure)
|
|
208202
|
+
writeData(`${red("✗")} ${label} ${failure.message}`);
|
|
208203
|
+
else if (link.step === "rows" && !rows)
|
|
208204
|
+
writeData(dim(`· ${label} not checked (pass --rows)`));
|
|
208205
|
+
else if (i > broken)
|
|
208206
|
+
writeData(dim(`· ${label} not checked: an earlier link is broken`));
|
|
208207
|
+
else if (link.step === "rows" && r.rowsChecked === undefined)
|
|
208208
|
+
writeData(dim(`· ${label} not checked: the source serves no indexed rows`));
|
|
208209
|
+
else
|
|
208210
|
+
writeData(`${green("✓")} ${label} ${linkDetail(link.step, r, cp, rows)}`);
|
|
208211
|
+
}
|
|
208212
|
+
for (const line of r.notes)
|
|
208213
|
+
if (rows || !line.includes("state_writes"))
|
|
208214
|
+
note(` note: ${line}`);
|
|
208215
|
+
if (!first) {
|
|
208216
|
+
const from = n(parseNakamotoHeader(unhex(cp.stacks.header)).chainLength);
|
|
208217
|
+
writeData(green(`✓ Block ${n(r.height ?? 0)} is proven. Trusted: only the checkpoint (Stacks ${from}, Bitcoin ${n(cp.bitcoin.height)}).`));
|
|
208218
|
+
return;
|
|
208219
|
+
}
|
|
208220
|
+
const label = LINKS[broken]?.label ?? first.step;
|
|
208221
|
+
writeData(red(first.code === "unavailable" ? `✗ Could not check the ${label} link: the source could not serve it.` : `✗ Not proven: the ${label} link is broken.`));
|
|
208222
|
+
}
|
|
208223
|
+
function verificationJson(r) {
|
|
208224
|
+
return JSON.stringify(r, (_k, v) => typeof v === "bigint" ? v.toString() : v, 2);
|
|
208225
|
+
}
|
|
208226
|
+
function exitCodeOf(r) {
|
|
208227
|
+
if (r.ok)
|
|
208228
|
+
return VERIFY_EXIT.CLEAN;
|
|
208229
|
+
return r.failures[0]?.code === "unavailable" ? VERIFY_EXIT.UNANCHORED : VERIFY_EXIT.DIVERGED;
|
|
208230
|
+
}
|
|
208231
|
+
async function runVerifyBlock(ref, opts, deps = {}) {
|
|
208232
|
+
let checkpoint;
|
|
208233
|
+
let verifier;
|
|
208234
|
+
let target;
|
|
208235
|
+
try {
|
|
208236
|
+
target = parseBlockRef(ref);
|
|
208237
|
+
checkpoint = opts.checkpoint ? await readCheckpoint(opts.checkpoint) : MAINNET_CHECKPOINT;
|
|
208238
|
+
const source = prepareSource(deps.source ?? defaultSource(opts.node), !!opts.rows);
|
|
208239
|
+
verifier = new BlockVerifier({ source, checkpoint });
|
|
208240
|
+
} catch (err) {
|
|
208241
|
+
printError(err instanceof Error ? err.message : String(err));
|
|
208242
|
+
return VERIFY_EXIT.UNANCHORED;
|
|
208243
|
+
}
|
|
208244
|
+
note(`Verifying block ${typeof target === "number" ? n(target) : target}`);
|
|
208245
|
+
const result = await verifier.verify(target);
|
|
208246
|
+
if (opts.json)
|
|
208247
|
+
writeData(verificationJson(result));
|
|
208248
|
+
else
|
|
208249
|
+
report(result, checkpoint, !!opts.rows);
|
|
208250
|
+
return exitCodeOf(result);
|
|
208251
|
+
}
|
|
208252
|
+
function attachVerifyBlockCommand(verify) {
|
|
208253
|
+
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
|
+
What is proven, link by link:
|
|
208255
|
+
bitcoin headers from the checkpoint to the block's burn block: proof-of-work and retargets
|
|
208256
|
+
burn the block's consensus hash commits to that Bitcoin block
|
|
208257
|
+
cycle the reward cycle's signer set, proven forward from the checkpoint's set
|
|
208258
|
+
signatures signers holding at least 70% of the weight signed the block header
|
|
208259
|
+
state root the state witness hashes to the root in the signed header
|
|
208260
|
+
diff every leaf the block wrote, carried, or kept as bookkeeping
|
|
208261
|
+
rows with --rows: the Index API's rows match that diff
|
|
208262
|
+
|
|
208263
|
+
Nothing is trusted except the checkpoint. Proofs come from the API
|
|
208264
|
+
(SECONDLAYER_API_URL, or --api-url) with your account key, or from a node
|
|
208265
|
+
with --node; a source that lies can fail a link but never pass one.
|
|
208266
|
+
|
|
208267
|
+
Examples:
|
|
208268
|
+
$ secondlayer verify block 9137005
|
|
208269
|
+
$ secondlayer verify block 0x2e5962b00b8f243e1a4b5a1b7ff3076618ce5e737e30c019bc61e461c92f57ff
|
|
208270
|
+
$ secondlayer verify block 9137005 --node http://127.0.0.1:20443 --rows
|
|
208271
|
+
$ secondlayer verify block 9137005 --json
|
|
208272
|
+
|
|
208273
|
+
Output: one line per link on stdout, progress on stderr. --json prints the
|
|
208274
|
+
full verification result instead (signer weights as decimal strings).
|
|
208275
|
+
|
|
208276
|
+
Exit codes:
|
|
208277
|
+
0 every link holds
|
|
208278
|
+
1 a link is broken (the first is named)
|
|
208279
|
+
2 could not check: the source could not serve a link, or bad input`).action(async (ref, opts, cmd) => {
|
|
208280
|
+
const json = cmd.optsWithGlobals().json === true;
|
|
208281
|
+
process.exit(await runVerifyBlock(ref, { ...opts, json }));
|
|
208282
|
+
});
|
|
208283
|
+
}
|
|
208284
|
+
|
|
208285
|
+
// src/commands/verify.ts
|
|
203993
208286
|
var VERIFY_EXIT = {
|
|
203994
208287
|
CLEAN: 0,
|
|
203995
208288
|
DIVERGED: 1,
|
|
@@ -204012,7 +208305,7 @@ function statusLabel(status) {
|
|
|
204012
208305
|
return yellow("missing");
|
|
204013
208306
|
}
|
|
204014
208307
|
function attachVerifyCommand(cmd) {
|
|
204015
|
-
return cmd.argument("[target]", "all | raw | decode:<name> | subgraph:<name>", "raw").option("--quick", "coverage/identity only (default)").option("--deep", "include semantic / scratch replay where available").option("--anchor", "require a verified archive signature").
|
|
208308
|
+
return cmd.argument("[target]", "all | raw | decode:<name> | subgraph:<name>", "raw").option("--quick", "coverage/identity only (default)").option("--deep", "include semantic / scratch replay where available").option("--anchor", "require a verified archive signature").option("--against <manifest>", "archive manifest: an https URL or a local file path (required)").option("--from-block <n>", "first height to check").option("--to-block <n>", "last height to check").option("--counts", "also compare transaction/event row counts (slower)").option("--semantic", "also recompute per-partition semantic digests locally and compare (slow: full re-stream)").option("--public-key <pem>", "pin a signing key; default is the archive key built into this release").option("--insecure", "skip the manifest signature check (not recommended)").option("--json", "Output as JSON").addHelpText("after", `
|
|
204016
208309
|
Examples:
|
|
204017
208310
|
$ secondlayer verify --against https://archive.secondlayer.tools/.../snapshots/<digest>.json
|
|
204018
208311
|
$ secondlayer verify raw --against ./snapshot.json --from-block 8000000 --to-block 8499999
|
|
@@ -204023,7 +208316,11 @@ Examples:
|
|
|
204023
208316
|
Exit codes:
|
|
204024
208317
|
0 local data matches the archive
|
|
204025
208318
|
1 divergence found (divergent ranges are listed)
|
|
204026
|
-
2 unanchored — reference unavailable or unverifiable`).action(async (targetArg, opts) => {
|
|
208319
|
+
2 unanchored — reference unavailable or unverifiable`).action(async (targetArg, opts, command) => {
|
|
208320
|
+
if (opts.against === undefined)
|
|
208321
|
+
command.error("error: required option '--against <manifest>' not specified", {
|
|
208322
|
+
code: "commander.missingMandatoryOptionValue"
|
|
208323
|
+
});
|
|
204027
208324
|
try {
|
|
204028
208325
|
const target = parseVerifyTarget(targetArg);
|
|
204029
208326
|
const mode = opts.deep ? "deep" : opts.anchor ? "anchor" : "quick";
|
|
@@ -204202,7 +208499,8 @@ Exit codes:
|
|
|
204202
208499
|
});
|
|
204203
208500
|
}
|
|
204204
208501
|
function registerVerifyCommand(program) {
|
|
204205
|
-
attachVerifyCommand(program.command("verify").description("Compare local chain data against a signed archive (read-only
|
|
208502
|
+
const verify = attachVerifyCommand(program.command("verify").description("Compare local chain data against a signed archive, or prove one block with `verify block` (read-only)"));
|
|
208503
|
+
attachVerifyBlockCommand(verify);
|
|
204206
208504
|
}
|
|
204207
208505
|
|
|
204208
208506
|
// src/commands/archive.ts
|
|
@@ -206251,8 +210549,8 @@ init_output();
|
|
|
206251
210549
|
init_resolve_auth();
|
|
206252
210550
|
|
|
206253
210551
|
// src/commands/faucet.ts
|
|
206254
|
-
import { randomBytes as
|
|
206255
|
-
import { readFile as
|
|
210552
|
+
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
210553
|
+
import { readFile as readFile5 } from "node:fs/promises";
|
|
206256
210554
|
import { join as join11 } from "node:path";
|
|
206257
210555
|
import { http as http3, createWalletClient } from "@secondlayer/stacks";
|
|
206258
210556
|
import { mnemonicToAccount } from "@secondlayer/stacks/accounts";
|
|
@@ -206266,7 +210564,7 @@ async function readDeployerMnemonic(projectDir) {
|
|
|
206266
210564
|
const path = join11(projectDir, "settings", "Devnet.toml");
|
|
206267
210565
|
let raw;
|
|
206268
210566
|
try {
|
|
206269
|
-
raw = await
|
|
210567
|
+
raw = await readFile5(path, "utf8");
|
|
206270
210568
|
} catch {
|
|
206271
210569
|
throw new Error(`could not read ${path}`);
|
|
206272
210570
|
}
|
|
@@ -206337,8 +210635,8 @@ is what makes minting possible without Bitcoin.`).action(async (opts) => {
|
|
|
206337
210635
|
chain: devnet,
|
|
206338
210636
|
transport: http3(rpcUrl)
|
|
206339
210637
|
});
|
|
206340
|
-
const depositTxid =
|
|
206341
|
-
const sweepTxid =
|
|
210638
|
+
const depositTxid = randomBytes3(32).toString("hex");
|
|
210639
|
+
const sweepTxid = randomBytes3(32).toString("hex");
|
|
206342
210640
|
note(` minting ${amount} sats to ${opts.to}`);
|
|
206343
210641
|
note(` via ${contract} as signer ${account.address}`);
|
|
206344
210642
|
const txid = await client.callContract({
|
|
@@ -207356,7 +211654,7 @@ import { resolveApiKey as resolveApiKey4 } from "@secondlayer/sdk";
|
|
|
207356
211654
|
|
|
207357
211655
|
// src/lib/project-file.ts
|
|
207358
211656
|
import { existsSync as existsSync8 } from "node:fs";
|
|
207359
|
-
import { mkdir as mkdir4, readFile as
|
|
211657
|
+
import { mkdir as mkdir4, readFile as readFile6, writeFile as writeFile5 } from "node:fs/promises";
|
|
207360
211658
|
import { homedir as homedir5 } from "node:os";
|
|
207361
211659
|
import { dirname as dirname10, join as join14, parse as parsePath2, resolve as resolve9 } from "node:path";
|
|
207362
211660
|
import { z as z4 } from "zod";
|
|
@@ -207373,7 +211671,7 @@ async function readActiveProject(cwd, globalDefault) {
|
|
|
207373
211671
|
const candidate = join14(dir, DIRNAME, FILENAME);
|
|
207374
211672
|
if (existsSync8(candidate)) {
|
|
207375
211673
|
try {
|
|
207376
|
-
const raw = await
|
|
211674
|
+
const raw = await readFile6(candidate, "utf8");
|
|
207377
211675
|
const parsed = ProjectFileSchema.parse(JSON.parse(raw));
|
|
207378
211676
|
return { slug: parsed.slug, resolvedFrom: candidate };
|
|
207379
211677
|
} catch {}
|
|
@@ -207611,7 +211909,7 @@ import { planUninstall, uninstallCommand } from "@secondlayer/shared/runtime";
|
|
|
207611
211909
|
|
|
207612
211910
|
// src/lib/instance-init.ts
|
|
207613
211911
|
init_output();
|
|
207614
|
-
import { randomBytes as
|
|
211912
|
+
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
207615
211913
|
import { existsSync as existsSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync7 } from "node:fs";
|
|
207616
211914
|
import { resolve as resolve10 } from "node:path";
|
|
207617
211915
|
import { ARCHIVE_ROOT_PUBLIC_KEY_PEM } from "@secondlayer/shared/archive/root-key";
|
|
@@ -207640,10 +211938,10 @@ function instanceNetworkFromEnv(fallback = "mainnet") {
|
|
|
207640
211938
|
}
|
|
207641
211939
|
}
|
|
207642
211940
|
function generateInstanceToken() {
|
|
207643
|
-
return
|
|
211941
|
+
return randomBytes4(32).toString("hex");
|
|
207644
211942
|
}
|
|
207645
211943
|
function generateSecretsKey() {
|
|
207646
|
-
return
|
|
211944
|
+
return randomBytes4(32).toString("hex");
|
|
207647
211945
|
}
|
|
207648
211946
|
function generateSigningPrivateKey() {
|
|
207649
211947
|
return generateEd25519KeyPair().privateKeyPem;
|
|
@@ -208462,7 +212760,7 @@ dbcache=4096
|
|
|
208462
212760
|
|
|
208463
212761
|
// src/lib/setup-wizard.ts
|
|
208464
212762
|
import { spawn as spawn3, spawnSync as spawnSync5 } from "node:child_process";
|
|
208465
|
-
import { randomBytes as
|
|
212763
|
+
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
208466
212764
|
import { existsSync as existsSync12 } from "node:fs";
|
|
208467
212765
|
import { writeFile as writeFile6 } from "node:fs/promises";
|
|
208468
212766
|
import { createServer } from "node:net";
|
|
@@ -208563,7 +212861,7 @@ async function resolveAvailablePublishSpec(spec, claimedByDocker = new Set, maxA
|
|
|
208563
212861
|
return { spec, remapped: false };
|
|
208564
212862
|
}
|
|
208565
212863
|
function randomHex(bytes) {
|
|
208566
|
-
return
|
|
212864
|
+
return randomBytes5(bytes).toString("hex");
|
|
208567
212865
|
}
|
|
208568
212866
|
function resolveSecrets(config) {
|
|
208569
212867
|
const envPath = join17(config.dir, ".env");
|
|
@@ -209298,5 +213596,5 @@ registerCreditsCommand(program);
|
|
|
209298
213596
|
registerArchiveCommand(program);
|
|
209299
213597
|
program.parse();
|
|
209300
213598
|
|
|
209301
|
-
//# debugId=
|
|
213599
|
+
//# debugId=2C1F9BFC90AE711664756E2164756E21
|
|
209302
213600
|
//# sourceMappingURL=cli.js.map
|