@bcts/frost-hubert 1.0.0-beta.1 → 1.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/frost.cjs +16 -16
- package/dist/bin/frost.cjs.map +1 -1
- package/dist/bin/frost.mjs +16 -16
- package/dist/bin/frost.mjs.map +1 -1
- package/dist/cmd/index.cjs +3 -3
- package/dist/cmd/index.mjs +3 -3
- package/dist/{cmd-CCVhHzG7.cjs → cmd-Cd5Bmjy8.cjs} +26 -26
- package/dist/{cmd-DNsHd19v.mjs.map → cmd-Cd5Bmjy8.cjs.map} +1 -1
- package/dist/{cmd-DNsHd19v.mjs → cmd-ChW3eHA8.mjs} +20 -20
- package/dist/{cmd-CCVhHzG7.cjs.map → cmd-ChW3eHA8.mjs.map} +1 -1
- package/dist/{common-DNrD_-EI.mjs → common--IfAHVkl.mjs} +2 -2
- package/dist/{common-DNrD_-EI.mjs.map → common--IfAHVkl.mjs.map} +1 -1
- package/dist/{common-CnvAUC2b.cjs → common-3msAx7hO.cjs} +3 -3
- package/dist/{common-CnvAUC2b.cjs.map → common-3msAx7hO.cjs.map} +1 -1
- package/dist/{common-Cf1UvJaP.mjs → common-4spC1kNw.mjs} +2 -2
- package/dist/{common-Cf1UvJaP.mjs.map → common-4spC1kNw.mjs.map} +1 -1
- package/dist/{common-7-BOgaTt.cjs → common-CeTqMwj0.cjs} +2 -2
- package/dist/{common-7-BOgaTt.cjs.map → common-CeTqMwj0.cjs.map} +1 -1
- package/dist/dkg/index.cjs.map +1 -1
- package/dist/dkg/index.mjs.map +1 -1
- package/dist/{finalize-BpC0rz93.mjs → finalize-BAwtGCQW.mjs} +4 -4
- package/dist/{finalize-BpC0rz93.mjs.map → finalize-BAwtGCQW.mjs.map} +1 -1
- package/dist/{finalize-Cb0obTSo.cjs → finalize-BUUNWqKC.cjs} +7 -7
- package/dist/{finalize-Cb0obTSo.cjs.map → finalize-BUUNWqKC.cjs.map} +1 -1
- package/dist/{finalize-DtRxHZ7H.mjs → finalize-Bm5RZIox.mjs} +3 -3
- package/dist/{finalize-DtRxHZ7H.mjs.map → finalize-Bm5RZIox.mjs.map} +1 -1
- package/dist/{finalize-T83Ko8nG.mjs → finalize-CELJsR4C.mjs} +4 -4
- package/dist/{finalize-T83Ko8nG.mjs.map → finalize-CELJsR4C.mjs.map} +1 -1
- package/dist/{finalize-DQ0VGUHO.cjs → finalize-D091kTVy.cjs} +7 -7
- package/dist/{finalize-DQ0VGUHO.cjs.map → finalize-D091kTVy.cjs.map} +1 -1
- package/dist/{finalize-DHEnKobp.cjs → finalize-SzzTi9BL.cjs} +6 -6
- package/dist/{finalize-DHEnKobp.cjs.map → finalize-SzzTi9BL.cjs.map} +1 -1
- package/dist/frost/index.cjs +2 -2
- package/dist/frost/index.cjs.map +1 -1
- package/dist/frost/index.d.cts.map +1 -1
- package/dist/frost/index.d.mts.map +1 -1
- package/dist/frost/index.mjs +1 -1
- package/dist/frost/index.mjs.map +1 -1
- package/dist/index-BErX9AZF.d.cts.map +1 -1
- package/dist/index-BaUVw4b1.d.mts.map +1 -1
- package/dist/index-CD50Qtgw.d.cts.map +1 -1
- package/dist/index-CD50Qtgw.d.mts.map +1 -1
- package/dist/index-Drklne-Y.d.mts.map +1 -1
- package/dist/index-gkmZzEuD.d.cts.map +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +3 -3
- package/dist/{invite-BLwtexAu.cjs → invite-5sYctfsS.cjs} +6 -6
- package/dist/{invite-BLwtexAu.cjs.map → invite-5sYctfsS.cjs.map} +1 -1
- package/dist/{invite-D8mQSnFz.mjs → invite-DNlTkwzM.mjs} +4 -4
- package/dist/{invite-D8mQSnFz.mjs.map → invite-DNlTkwzM.mjs.map} +1 -1
- package/dist/{invite-1tzg0B0P.cjs → invite-T3L4N2m0.cjs} +7 -7
- package/dist/{invite-1tzg0B0P.cjs.map → invite-T3L4N2m0.cjs.map} +1 -1
- package/dist/{invite-Be2v2SVc.mjs → invite-vRv9LMEE.mjs} +3 -3
- package/dist/{invite-Be2v2SVc.mjs.map → invite-vRv9LMEE.mjs.map} +1 -1
- package/dist/parallel-PZiwHZT8.mjs.map +1 -1
- package/dist/parallel-szwYx-bi.cjs.map +1 -1
- package/dist/proposed-participant-BvHNnpcZ.cjs.map +1 -1
- package/dist/proposed-participant-Detb823_.mjs.map +1 -1
- package/dist/{receive-g8EhZF2Y.mjs → receive-Bzn87ahI.mjs} +4 -4
- package/dist/{receive-g8EhZF2Y.mjs.map → receive-Bzn87ahI.mjs.map} +1 -1
- package/dist/{receive-dkSCSGpl.mjs → receive-C2Dwb_FQ.mjs} +4 -4
- package/dist/{receive-dkSCSGpl.mjs.map → receive-C2Dwb_FQ.mjs.map} +1 -1
- package/dist/{receive-D_r4Mryr.cjs → receive-Coqg6eFx.cjs} +7 -7
- package/dist/{receive-D_r4Mryr.cjs.map → receive-Coqg6eFx.cjs.map} +1 -1
- package/dist/{receive-BR-knnGv.cjs → receive-DZARudBa.cjs} +7 -7
- package/dist/{receive-BR-knnGv.cjs.map → receive-DZARudBa.cjs.map} +1 -1
- package/dist/registry/index.cjs +3 -3
- package/dist/registry/index.cjs.map +1 -1
- package/dist/registry/index.mjs.map +1 -1
- package/dist/{registry-CkIbA7nt.cjs → registry-D-rFKk9R.cjs} +5 -5
- package/dist/{registry-CkIbA7nt.cjs.map → registry-D-rFKk9R.cjs.map} +1 -1
- package/dist/{registry-DGjs4qDK.mjs → registry-ycylEdoc.mjs} +2 -2
- package/dist/{registry-DGjs4qDK.mjs.map → registry-ycylEdoc.mjs.map} +1 -1
- package/dist/{round1-D8t7EzIo.mjs → round1-BRgDPU4Y.mjs} +4 -4
- package/dist/{round1-D8t7EzIo.mjs.map → round1-BRgDPU4Y.mjs.map} +1 -1
- package/dist/{round1-CXkXoVQU.cjs → round1-BwNBKLYm.cjs} +8 -8
- package/dist/{round1-CXkXoVQU.cjs.map → round1-BwNBKLYm.cjs.map} +1 -1
- package/dist/{round1-9FAqFvL5.cjs → round1-C1IlXH-9.cjs} +6 -6
- package/dist/{round1-9FAqFvL5.cjs.map → round1-C1IlXH-9.cjs.map} +1 -1
- package/dist/{round1-DriPu15x.cjs → round1-CEbz7cnL.cjs} +8 -8
- package/dist/{round1-DriPu15x.cjs.map → round1-CEbz7cnL.cjs.map} +1 -1
- package/dist/{round1-B8haiMM8.mjs → round1-DL4N2QJ5.mjs} +5 -5
- package/dist/{round1-B8haiMM8.mjs.map → round1-DL4N2QJ5.mjs.map} +1 -1
- package/dist/{round1-BOIE1E4O.mjs → round1-DSaOFCar.mjs} +3 -3
- package/dist/{round1-BOIE1E4O.mjs.map → round1-DSaOFCar.mjs.map} +1 -1
- package/dist/{round1-Y2kcVwnR.mjs → round1-_fHip4H1.mjs} +5 -5
- package/dist/{round1-Y2kcVwnR.mjs.map → round1-_fHip4H1.mjs.map} +1 -1
- package/dist/{round1-Bq0vweyQ.cjs → round1-ek-G6qVi.cjs} +7 -7
- package/dist/{round1-Bq0vweyQ.cjs.map → round1-ek-G6qVi.cjs.map} +1 -1
- package/dist/{round2-Dk_w97nl.cjs → round2-BD_0N7Ab.cjs} +6 -6
- package/dist/{round2-Dk_w97nl.cjs.map → round2-BD_0N7Ab.cjs.map} +1 -1
- package/dist/{round2-Z2JhMwxc.mjs → round2-BLOgZeAo.mjs} +4 -4
- package/dist/{round2-Z2JhMwxc.mjs.map → round2-BLOgZeAo.mjs.map} +1 -1
- package/dist/{round2-BHQKVJFo.cjs → round2-C684Nir0.cjs} +7 -7
- package/dist/{round2-BHQKVJFo.cjs.map → round2-C684Nir0.cjs.map} +1 -1
- package/dist/{round2-mF6UlkT-.mjs → round2-CU-yTXHT.mjs} +4 -4
- package/dist/{round2-mF6UlkT-.mjs.map → round2-CU-yTXHT.mjs.map} +1 -1
- package/dist/{round2-BfetYacV.mjs → round2-Cq2SD6F8.mjs} +3 -3
- package/dist/{round2-BfetYacV.mjs.map → round2-Cq2SD6F8.mjs.map} +1 -1
- package/dist/{round2-AMDYMUIg.cjs → round2-D8l1PUm5.cjs} +7 -7
- package/dist/{round2-AMDYMUIg.cjs.map → round2-D8l1PUm5.cjs.map} +1 -1
- package/dist/{round2-CvrmylN1.cjs → round2-DhdFarwY.cjs} +7 -7
- package/dist/{round2-CvrmylN1.cjs.map → round2-DhdFarwY.cjs.map} +1 -1
- package/dist/{round2-Cf5CJc_8.mjs → round2-DmQvJDVj.mjs} +4 -4
- package/dist/{round2-Cf5CJc_8.mjs.map → round2-DmQvJDVj.mjs.map} +1 -1
- package/package.json +16 -16
- /package/dist/{chunk-DakpK96I.cjs → rolldown-runtime-DakpK96I.cjs} +0 -0
- /package/dist/{chunk-z9aeyW2b.mjs → rolldown-runtime-z9aeyW2b.mjs} +0 -0
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
const
|
|
1
|
+
const require_rolldown_runtime = require("./rolldown-runtime-DakpK96I.cjs");
|
|
2
2
|
const require_registry_index = require("./registry/index.cjs");
|
|
3
|
-
const require_common = require("./common-
|
|
3
|
+
const require_common = require("./common-3msAx7hO.cjs");
|
|
4
4
|
const require_busy = require("./busy-B_h0bNAJ.cjs");
|
|
5
5
|
const require_frost_index = require("./frost/index.cjs");
|
|
6
|
-
const require_common$1 = require("./common-
|
|
6
|
+
const require_common$1 = require("./common-CeTqMwj0.cjs");
|
|
7
7
|
let _bcts_components = require("@bcts/components");
|
|
8
8
|
let _bcts_dcbor = require("@bcts/dcbor");
|
|
9
9
|
let _bcts_envelope = require("@bcts/envelope");
|
|
10
10
|
let node_fs = require("node:fs");
|
|
11
|
-
node_fs =
|
|
11
|
+
node_fs = require_rolldown_runtime.__toESM(node_fs, 1);
|
|
12
12
|
let node_path = require("node:path");
|
|
13
|
-
node_path =
|
|
13
|
+
node_path = require_rolldown_runtime.__toESM(node_path, 1);
|
|
14
14
|
let _frosts_ed25519 = require("@frosts/ed25519");
|
|
15
15
|
let _frosts_core = require("@frosts/core");
|
|
16
16
|
//#region src/cmd/sign/participant/round2.ts
|
|
@@ -25,7 +25,7 @@ let _frosts_core = require("@frosts/core");
|
|
|
25
25
|
*
|
|
26
26
|
* @module
|
|
27
27
|
*/
|
|
28
|
-
var round2_exports = /* @__PURE__ */
|
|
28
|
+
var round2_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({ round2: () => round2 });
|
|
29
29
|
/**
|
|
30
30
|
* Load receive state from sign_receive.json.
|
|
31
31
|
*
|
|
@@ -302,4 +302,4 @@ Object.defineProperty(exports, "round2_exports", {
|
|
|
302
302
|
}
|
|
303
303
|
});
|
|
304
304
|
|
|
305
|
-
//# sourceMappingURL=round2-
|
|
305
|
+
//# sourceMappingURL=round2-D8l1PUm5.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"round2-AMDYMUIg.cjs","names":["path","fs","ARIDClass","parseAridUr","XIDClass","signingStateDir","Nonce","Ed25519Sha512","serde","SigningNonces","deserializeSigningCommitments","EnvelopeFunction","JSONComponent","identifierFromU16","serializeSignatureShare","Envelope","serializeSigningCommitments","resolveRegistryPath","Registry","deserializeKeyPackage","getWithIndicator","CborDate","signingRound2","createSigningPackage","putWithIndicator"],"sources":["../src/cmd/sign/participant/round2.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Sign participant round 2 command.\n *\n * Port of cmd/sign/participant/round2.rs from frost-hubert-rust.\n *\n * @module\n */\n\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport {\n type ARID,\n type XID,\n XID as XIDClass,\n ARID as ARIDClass,\n JSON as JSONComponent,\n type Digest,\n} from \"@bcts/components\";\nimport { CborDate } from \"@bcts/dcbor\";\nimport { Envelope, Function as EnvelopeFunction } from \"@bcts/envelope\";\nimport { type XIDDocument } from \"@bcts/xid\";\n\nimport { Registry, resolveRegistryPath } from \"../../../registry/index.js\";\nimport { getWithIndicator, putWithIndicator } from \"../../busy.js\";\nimport { type StorageClient } from \"../../storage.js\";\nimport { parseAridUr } from \"../../dkg/common.js\";\nimport { signingStateDir } from \"../common.js\";\nimport {\n signingRound2,\n createSigningPackage,\n deserializeKeyPackage,\n deserializeSigningCommitments,\n serializeSignatureShare,\n serializeSigningCommitments,\n identifierFromU16,\n type SerializedKeyPackage,\n type SerializedSigningCommitments,\n type FrostIdentifier,\n type FrostKeyPackage,\n type Ed25519SigningCommitments,\n type Ed25519SignatureShare,\n} from \"../../../frost/index.js\";\n\n// Import nonces from @frosts/core\nimport { Nonce, SigningNonces } from \"@frosts/core\";\nimport { Ed25519Sha512, serde } from \"@frosts/ed25519\";\n\n/**\n * Options for the sign round2 command.\n */\nexport interface SignRound2Options {\n registryPath?: string;\n sessionId: string;\n groupId?: string;\n timeoutSeconds?: number;\n preview?: boolean;\n verbose?: boolean;\n}\n\n/**\n * Result of the sign round2 command.\n */\nexport interface SignRound2Result {\n listeningArid: string;\n}\n\n/**\n * ReceiveState loaded from sign_receive.json.\n *\n * Port of `struct ReceiveState` from cmd/sign/participant/round2.rs.\n */\ninterface ReceiveState {\n groupId: ARID;\n participants: XID[];\n minSigners: number;\n targetUr: string;\n}\n\n/**\n * CommitState loaded from commit.json.\n *\n * Port of `struct CommitState` from cmd/sign/participant/round2.rs.\n */\ninterface CommitState {\n nextShareArid: ARID;\n targetUr: string;\n signingNonces: SigningNonces<typeof Ed25519Sha512>;\n signingCommitments: Ed25519SigningCommitments;\n}\n\n/**\n * Sealed request interface for GSTP.\n */\ninterface SealedRequestInstance {\n function: () => unknown;\n id: () => ARID;\n sender: () => { xid: () => XID };\n extractObjectForParameter: <T>(name: string) => T;\n objectsForParameter: (name: string) => Envelope[];\n}\n\n/**\n * Load receive state from sign_receive.json.\n *\n * Port of `load_receive_state()` from cmd/sign/participant/round2.rs.\n */\nfunction loadReceiveState(registryPath: string, sessionId: ARID, groupHint?: ARID): ReceiveState {\n const base = path.dirname(registryPath);\n const groupStateDir = path.join(base, \"group-state\");\n\n // Find candidate paths\n let groupDirs: [ARID, string][];\n\n if (groupHint) {\n groupDirs = [[groupHint, path.join(groupStateDir, groupHint.hex())]];\n } else {\n groupDirs = [];\n if (fs.existsSync(groupStateDir)) {\n for (const entry of fs.readdirSync(groupStateDir, { withFileTypes: true })) {\n if (entry.isDirectory() && entry.name.length === 64 && /^[0-9a-f]+$/i.test(entry.name)) {\n const groupId = ARIDClass.fromHex(entry.name);\n groupDirs.push([groupId, path.join(groupStateDir, entry.name)]);\n }\n }\n }\n }\n\n const candidates: [ARID, string][] = [];\n for (const [groupId, groupDir] of groupDirs) {\n const candidate = path.join(groupDir, \"signing\", sessionId.hex(), \"sign_receive.json\");\n if (fs.existsSync(candidate)) {\n candidates.push([groupId, candidate]);\n }\n }\n\n if (candidates.length === 0) {\n throw new Error(\n \"No sign_receive.json found for this session; run `frost sign participant receive` first\",\n );\n }\n if (candidates.length > 1) {\n throw new Error(\"Multiple groups contain this session; use --group to disambiguate\");\n }\n\n const [groupId, statePath] = candidates[0];\n const raw = JSON.parse(fs.readFileSync(statePath, \"utf-8\")) as Record<string, unknown>;\n\n const getStr = (key: string): string => {\n const value = raw[key];\n if (typeof value !== \"string\") {\n throw new Error(`Missing or invalid ${key} in sign_receive.json`);\n }\n return value;\n };\n\n // Validate session matches\n const sessionInState = parseAridUr(getStr(\"session\"));\n if (sessionInState.urString() !== sessionId.urString()) {\n throw new Error(\n `Session ${sessionInState.urString()} in sign_receive.json does not match requested session ${sessionId.urString()}`,\n );\n }\n\n // Validate group matches\n const groupInState = parseAridUr(getStr(\"group\"));\n if (groupInState.urString() !== groupId.urString()) {\n throw new Error(\n `Group ${groupInState.urString()} in sign_receive.json does not match directory group ${groupId.urString()}`,\n );\n }\n\n // Parse participants\n const participantsVal = raw[\"participants\"] as string[] | undefined;\n if (!participantsVal || !Array.isArray(participantsVal)) {\n throw new Error(\"Missing participants in sign_receive.json\");\n }\n\n const participants: XID[] = [];\n for (const entry of participantsVal) {\n if (typeof entry !== \"string\") {\n throw new Error(\"Invalid participant entry in sign_receive.json\");\n }\n participants.push(XIDClass.fromURString(entry));\n }\n\n // Parse min_signers\n const minSigners = raw[\"min_signers\"];\n if (typeof minSigners !== \"number\") {\n throw new Error(\"Missing min_signers in sign_receive.json\");\n }\n\n const targetUr = getStr(\"target\");\n\n return {\n groupId,\n participants,\n minSigners,\n targetUr,\n };\n}\n\n/**\n * Load commit state from commit.json (includes nonces).\n *\n * Port of `load_commit_state()` from cmd/sign/participant/round2.rs.\n */\nfunction loadCommitState(registryPath: string, groupId: ARID, sessionId: ARID): CommitState {\n const dir = signingStateDir(registryPath, groupId.hex(), sessionId.hex());\n const statePath = path.join(dir, \"commit.json\");\n\n if (!fs.existsSync(statePath)) {\n throw new Error(\n `Commit state not found at ${statePath}. Run \\`frost sign participant commit\\` first.`,\n );\n }\n\n const raw = JSON.parse(fs.readFileSync(statePath, \"utf-8\")) as Record<string, unknown>;\n\n const getStr = (key: string): string => {\n const value = raw[key];\n if (typeof value !== \"string\") {\n throw new Error(`Missing or invalid ${key} in commit.json`);\n }\n return value;\n };\n\n // Validate session matches\n const sessionInState = parseAridUr(getStr(\"session\"));\n if (sessionInState.urString() !== sessionId.urString()) {\n throw new Error(\n `Session ${sessionInState.urString()} in commit.json does not match requested session ${sessionId.urString()}`,\n );\n }\n\n const nextShareArid = parseAridUr(getStr(\"next_share_arid\"));\n const targetUr = getStr(\"target\");\n\n // Deserialize signing nonces\n const noncesRaw = raw[\"signing_nonces\"] as Record<string, string> | undefined;\n if (!noncesRaw) {\n throw new Error(\"Missing signing_nonces in commit.json\");\n }\n\n const hidingNonce = Nonce.deserialize(Ed25519Sha512, serde.hexToBytes(noncesRaw[\"hiding\"]));\n const bindingNonce = Nonce.deserialize(Ed25519Sha512, serde.hexToBytes(noncesRaw[\"binding\"]));\n const signingNonces = SigningNonces.fromNonces(Ed25519Sha512, hidingNonce, bindingNonce);\n\n // Deserialize signing commitments\n const commitmentsRaw = raw[\"signing_commitments\"] as SerializedSigningCommitments | undefined;\n if (!commitmentsRaw) {\n throw new Error(\"Missing signing_commitments in commit.json\");\n }\n const signingCommitments = deserializeSigningCommitments(commitmentsRaw);\n\n return {\n nextShareArid,\n targetUr,\n signingNonces,\n signingCommitments,\n };\n}\n\n/**\n * Validate the incoming GSTP request.\n *\n * Port of request validation logic from cmd/sign/participant/round2.rs.\n */\nfunction validateShareRequest(\n sealedRequest: SealedRequestInstance,\n sessionId: ARID,\n expectedCoordinator: XID,\n): void {\n // Check function\n const expectedFunction = EnvelopeFunction.fromString(\"signRound2\");\n const actualFunction = sealedRequest.function();\n // @ts-expect-error - function() returns unknown, but it should have .equals()\n if (actualFunction.equals(expectedFunction) !== true) {\n throw new Error(`Unexpected request function: ${String(sealedRequest.function())}`);\n }\n\n // Check session ID\n if (sealedRequest.id().urString() !== sessionId.urString()) {\n throw new Error(\n `Session ID mismatch (request ${sealedRequest.id().urString()}, expected ${sessionId.urString()})`,\n );\n }\n\n // Check sender (coordinator)\n if (sealedRequest.sender().xid().urString() !== expectedCoordinator.urString()) {\n throw new Error(\n `Unexpected request sender: ${sealedRequest.sender().xid().urString()} (expected coordinator ${expectedCoordinator.urString()})`,\n );\n }\n}\n\n/**\n * Extract all commitments from the signRound2 request.\n *\n * Port of `parse_commitments()` from cmd/sign/participant/round2.rs.\n */\nfunction extractCommitments(\n sealedRequest: SealedRequestInstance,\n receiveState: ReceiveState,\n): Map<string, Ed25519SigningCommitments> {\n const commitments = new Map<string, Ed25519SigningCommitments>();\n\n const commitmentObjects = sealedRequest.objectsForParameter(\"commitment\");\n\n for (const entry of commitmentObjects) {\n // Extract XID subject\n const xid = XIDClass.fromTaggedCbor(entry.subject().tryLeaf());\n\n // Extract commitments from the \"commitments\" predicate\n const commitmentsObjects = entry.objectsForPredicate(\"commitments\");\n if (commitmentsObjects.length === 0) {\n throw new Error(`Missing commitments for participant ${xid.urString()}`);\n }\n\n const commitmentsJson = JSONComponent.fromTaggedCbor(commitmentsObjects[0].subject().tryLeaf());\n const serializedCommitments = JSON.parse(\n commitmentsJson.asStr(),\n ) as SerializedSigningCommitments;\n const signingCommitments = deserializeSigningCommitments(serializedCommitments);\n\n const xidUr = xid.urString();\n if (commitments.has(xidUr)) {\n throw new Error(`Duplicate commitments for participant ${xidUr}`);\n }\n commitments.set(xidUr, signingCommitments);\n }\n\n if (commitments.size === 0) {\n throw new Error(\"signRound2 request contains no commitments\");\n }\n\n // Validate expected participant set\n const expectedSet = new Set(receiveState.participants.map((p) => p.urString()));\n const actualSet = new Set(commitments.keys());\n\n const missing: string[] = [];\n const extra: string[] = [];\n\n for (const xid of expectedSet) {\n if (!actualSet.has(xid)) {\n missing.push(xid);\n }\n }\n for (const xid of actualSet) {\n if (!expectedSet.has(xid)) {\n extra.push(xid);\n }\n }\n\n if (missing.length > 0 || extra.length > 0) {\n throw new Error(\n `signRound2 commitments do not match session participants (missing: ${missing.join(\", \")}; extra: ${extra.join(\", \")})`,\n );\n }\n\n return commitments;\n}\n\n/**\n * Build a map from XID to FROST identifier (sorted participant order).\n *\n * Port of `xid_identifier_map()` from cmd/sign/participant/round2.rs.\n */\nfunction xidIdentifierMap(participants: XID[]): Map<string, FrostIdentifier> {\n const map = new Map<string, FrostIdentifier>();\n for (let i = 0; i < participants.length; i++) {\n const identifier = identifierFromU16(i + 1);\n map.set(participants[i].urString(), identifier);\n }\n return map;\n}\n\n/**\n * Build signing commitments with identifiers.\n *\n * Port of `commitments_with_identifiers()` from cmd/sign/participant/round2.rs.\n */\nfunction commitmentsWithIdentifiers(\n commitments: Map<string, Ed25519SigningCommitments>,\n xidToIdentifier: Map<string, FrostIdentifier>,\n): Map<FrostIdentifier, Ed25519SigningCommitments> {\n const mapped = new Map<FrostIdentifier, Ed25519SigningCommitments>();\n for (const [xidUr, commits] of commitments) {\n const identifier = xidToIdentifier.get(xidUr);\n if (!identifier) {\n throw new Error(`Unknown participant ${xidUr}`);\n }\n mapped.set(identifier, commits);\n }\n return mapped;\n}\n\n/**\n * Build the signRound2Response body envelope.\n *\n * Port of response body construction from cmd/sign/participant/round2.rs.\n */\nfunction buildResponseBody(\n sessionId: ARID,\n signatureShare: Ed25519SignatureShare,\n finalizeArid: ARID,\n): Envelope {\n const shareHex = serializeSignatureShare(signatureShare);\n const shareJson = JSONComponent.fromString(JSON.stringify({ share: shareHex }));\n\n return Envelope.unit()\n .addType(\"signRound2Response\")\n .addAssertion(\"session\", sessionId)\n .addAssertion(\"signature_share\", shareJson)\n .addAssertion(\"response_arid\", finalizeArid);\n}\n\n/**\n * Persist share state to share.json.\n *\n * Port of `persist_share_state()` from cmd/sign/participant/round2.rs.\n */\nfunction persistShareState(\n registryPath: string,\n groupId: ARID,\n sessionId: ARID,\n responseArid: ARID,\n finalizeArid: ARID,\n signatureShare: Ed25519SignatureShare,\n commitments: Map<string, Ed25519SigningCommitments>,\n): void {\n const dir = signingStateDir(registryPath, groupId.hex(), sessionId.hex());\n fs.mkdirSync(dir, { recursive: true });\n\n // Build commitments JSON object\n const commitmentsJson: Record<string, SerializedSigningCommitments> = {};\n for (const [xidUr, commits] of commitments) {\n commitmentsJson[xidUr] = serializeSigningCommitments(commits);\n }\n\n // Build root JSON object\n const root = {\n session: sessionId.urString(),\n response_arid: responseArid.urString(),\n finalize_arid: finalizeArid.urString(),\n signature_share: { share: serializeSignatureShare(signatureShare) },\n commitments: commitmentsJson,\n };\n\n fs.writeFileSync(path.join(dir, \"share.json\"), JSON.stringify(root, null, 2));\n}\n\n/**\n * Execute the sign participant round 2 command.\n *\n * Receives round 2 request and sends signature share.\n *\n * Port of `CommandArgs::exec()` from cmd/sign/participant/round2.rs.\n */\nexport async function round2(\n client: StorageClient,\n options: SignRound2Options,\n cwd: string,\n): Promise<SignRound2Result> {\n const registryPath = resolveRegistryPath(options.registryPath, cwd);\n const registry = Registry.load(registryPath);\n\n const owner = registry.owner();\n if (!owner) {\n throw new Error(\"Registry owner is required\");\n }\n const ownerXidDocument = owner.xidDocument();\n\n const sessionId = parseAridUr(options.sessionId);\n const groupHint = options.groupId ? parseAridUr(options.groupId) : undefined;\n\n // Load receive state (finds group automatically if not specified)\n const receiveState = loadReceiveState(registryPath, sessionId, groupHint);\n const groupId = receiveState.groupId;\n\n const groupRecord = registry.group(groupId);\n if (!groupRecord) {\n throw new Error(\"Group not found in registry\");\n }\n\n // Validate min_signers matches\n if (groupRecord.minSigners() !== receiveState.minSigners) {\n throw new Error(\n `Session min_signers ${receiveState.minSigners} does not match registry ${groupRecord.minSigners()}`,\n );\n }\n\n // Validate participants match\n const registryParticipants = new Set(groupRecord.participants().map((p) => p.xid().urString()));\n const sessionParticipants = new Set(receiveState.participants.map((p) => p.urString()));\n\n if (\n registryParticipants.size !== sessionParticipants.size ||\n ![...registryParticipants].every((p) => sessionParticipants.has(p))\n ) {\n throw new Error(\"Session participants do not match registry group participants\");\n }\n\n // Validate owner participates in this session\n if (!sessionParticipants.has(owner.xid().urString())) {\n throw new Error(\"This participant is not part of the signing session\");\n }\n\n // Get listening ARID from registry\n const listeningAtArid = groupRecord.listeningAtArid();\n if (!listeningAtArid) {\n throw new Error(\n \"No listening ARID for signRound2. Did you run `frost sign participant commit`?\",\n );\n }\n\n // Load commit state and validate\n const commitState = loadCommitState(registryPath, groupId, sessionId);\n\n if (commitState.nextShareArid.urString() !== listeningAtArid.urString()) {\n throw new Error(\n `Listening ARID in registry (${listeningAtArid.urString()}) does not match persisted commit state (${commitState.nextShareArid.urString()})`,\n );\n }\n\n if (commitState.targetUr !== receiveState.targetUr) {\n throw new Error(\"Target envelope in commit state does not match persisted signInvite request\");\n }\n\n // Load key package\n const keyPackagePath = groupRecord.contributions().keyPackage;\n if (!keyPackagePath) {\n throw new Error(\"Key package path not found; did you finish DKG?\");\n }\n\n interface KeyPackageFile {\n group?: string;\n key_package: SerializedKeyPackage;\n }\n\n const keyPackageFile = JSON.parse(fs.readFileSync(keyPackagePath, \"utf-8\")) as KeyPackageFile;\n const keyPackage: FrostKeyPackage = deserializeKeyPackage(keyPackageFile.key_package);\n\n // Create finalize ARID\n const finalizeArid = ARIDClass.new();\n\n // Compute target digest from persisted target envelope\n const targetEnvelope = Envelope.fromURString(receiveState.targetUr);\n const targetDigest: Digest = targetEnvelope.subject().digest();\n\n if (options.verbose === true) {\n console.error(\"Fetching signRound2 request from Hubert...\");\n }\n\n // Fetch request from storage\n const requestEnvelope = await getWithIndicator(\n client,\n listeningAtArid,\n \"signRound2 request\",\n options.timeoutSeconds,\n options.verbose ?? false,\n );\n\n if (!requestEnvelope) {\n throw new Error(\"signRound2 request not found in Hubert storage\");\n }\n\n // Parse sealed request\n const signerPrivateKeys = ownerXidDocument.inceptionPrivateKeys();\n if (!signerPrivateKeys) {\n throw new Error(\"Owner XID document has no private keys\");\n }\n\n // eslint-disable-next-line @typescript-eslint/no-require-imports, no-undef\n const { SealedRequest: SealedRequestClass } = require(\"@bcts/gstp\") as {\n SealedRequest: {\n tryFromEnvelope: (\n envelope: Envelope,\n expectedSender: XID | undefined,\n now: CborDate,\n recipientPrivateKeys: unknown,\n ) => SealedRequestInstance;\n };\n };\n\n const now = CborDate.now();\n const sealedRequest = SealedRequestClass.tryFromEnvelope(\n requestEnvelope,\n undefined,\n now,\n signerPrivateKeys,\n );\n\n // Validate request\n const expectedCoordinator = groupRecord.coordinator().xid();\n validateShareRequest(sealedRequest, sessionId, expectedCoordinator);\n\n // Extract response ARID from request\n const responseArid: ARID = sealedRequest.extractObjectForParameter(\"response_arid\");\n\n // Extract and validate commitments\n const commitmentsByXid = extractCommitments(sealedRequest, receiveState);\n\n // Verify our commitments match\n const myCommitments = commitmentsByXid.get(owner.xid().urString());\n if (!myCommitments) {\n throw new Error(\"signRound2 request missing commitments for this participant\");\n }\n\n // Compare commitments using serialized form\n const myCommitmentsSerialized = serializeSigningCommitments(myCommitments);\n const storedCommitmentsSerialized = serializeSigningCommitments(commitState.signingCommitments);\n\n if (\n myCommitmentsSerialized.hiding !== storedCommitmentsSerialized.hiding ||\n myCommitmentsSerialized.binding !== storedCommitmentsSerialized.binding\n ) {\n throw new Error(\"signRound2 request commitments do not match locally stored commitments\");\n }\n\n // Build XID to identifier map (sorted participant order)\n const xidToIdentifier = xidIdentifierMap(receiveState.participants);\n\n // Verify our identifier matches key package\n const myIdentifier = xidToIdentifier.get(owner.xid().urString());\n if (!myIdentifier) {\n throw new Error(\"Identifier for participant not found\");\n }\n\n // Verify key package min_signers matches\n if (keyPackage.minSigners !== receiveState.minSigners) {\n throw new Error(\n `Key package min_signers ${keyPackage.minSigners} does not match session ${receiveState.minSigners}`,\n );\n }\n\n // Verify enough commitments\n if (commitmentsByXid.size < receiveState.minSigners) {\n throw new Error(\n `signRound2 request contained ${commitmentsByXid.size} commitments but requires at least ${receiveState.minSigners} signers`,\n );\n }\n\n // Build signing commitments with identifiers\n const signingCommitments = commitmentsWithIdentifiers(commitmentsByXid, xidToIdentifier);\n\n // Create signing package\n const signingPackage = createSigningPackage(signingCommitments, targetDigest.data());\n\n // Generate signature share using FROST round 2\n const signatureShare = signingRound2(signingPackage, commitState.signingNonces, keyPackage);\n\n // Build response body\n const responseBody = buildResponseBody(sessionId, signatureShare, finalizeArid);\n\n // Build sealed response\n // eslint-disable-next-line @typescript-eslint/no-require-imports, no-undef\n const { SealedResponse: SealedResponseClass } = require(\"@bcts/gstp\") as {\n SealedResponse: {\n newSuccess: (\n requestId: ARID,\n sender: XIDDocument,\n ) => {\n withResult: (result: Envelope) => {\n withPeerContinuation: (continuation: unknown) => {\n toEnvelope: (\n expiry: CborDate | undefined,\n signerPrivateKeys: unknown,\n recipient: XIDDocument | undefined,\n ) => Envelope;\n };\n toEnvelope: (\n expiry: CborDate | undefined,\n signerPrivateKeys: unknown,\n recipient: XIDDocument | undefined,\n ) => Envelope;\n };\n };\n };\n };\n\n const sealedResponse = SealedResponseClass.newSuccess(\n sealedRequest.id(),\n ownerXidDocument,\n ).withResult(responseBody);\n\n // Preview mode - print unsealed response\n if (options.preview === true) {\n const unsealed = sealedResponse.toEnvelope(undefined, signerPrivateKeys, undefined);\n console.log(unsealed.urString());\n return {\n listeningArid: finalizeArid.urString(),\n };\n }\n\n // Get coordinator XID document for encryption\n let coordinatorDoc: XIDDocument;\n if (expectedCoordinator.urString() === owner.xid().urString()) {\n coordinatorDoc = ownerXidDocument;\n } else {\n const coordinatorRecord = registry.participant(expectedCoordinator);\n if (!coordinatorRecord) {\n throw new Error(`Coordinator ${expectedCoordinator.urString()} not found in registry`);\n }\n coordinatorDoc = coordinatorRecord.xidDocument();\n }\n\n // Create response envelope with expiry\n const expiry = CborDate.withDurationFromNow(60 * 60); // 1 hour\n const responseEnvelope = sealedResponse.toEnvelope(expiry, signerPrivateKeys, coordinatorDoc);\n\n // Send response\n await putWithIndicator(\n client,\n responseArid,\n responseEnvelope,\n \"Signature Share\",\n options.verbose ?? false,\n );\n\n // Persist share state\n persistShareState(\n registryPath,\n groupId,\n sessionId,\n responseArid,\n finalizeArid,\n signatureShare,\n commitmentsByXid,\n );\n\n // Update registry with finalize listening ARID\n const groupRecordMutable = registry.group(groupId);\n if (groupRecordMutable) {\n groupRecordMutable.setListeningAtArid(finalizeArid);\n registry.save(registryPath);\n }\n\n if (options.verbose === true) {\n console.error(`Posted signature share to ${responseArid.urString()}`);\n }\n\n return {\n listeningArid: finalizeArid.urString(),\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"round2-D8l1PUm5.cjs","names":["path","fs","ARIDClass","parseAridUr","XIDClass","signingStateDir","Nonce","Ed25519Sha512","serde","SigningNonces","deserializeSigningCommitments","EnvelopeFunction","JSONComponent","identifierFromU16","serializeSignatureShare","Envelope","serializeSigningCommitments","resolveRegistryPath","Registry","deserializeKeyPackage","getWithIndicator","CborDate","signingRound2","createSigningPackage","putWithIndicator"],"sources":["../src/cmd/sign/participant/round2.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * Sign participant round 2 command.\n *\n * Port of cmd/sign/participant/round2.rs from frost-hubert-rust.\n *\n * @module\n */\n\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport {\n type ARID,\n type XID,\n XID as XIDClass,\n ARID as ARIDClass,\n JSON as JSONComponent,\n type Digest,\n} from \"@bcts/components\";\nimport { CborDate } from \"@bcts/dcbor\";\nimport { Envelope, Function as EnvelopeFunction } from \"@bcts/envelope\";\nimport { type XIDDocument } from \"@bcts/xid\";\n\nimport { Registry, resolveRegistryPath } from \"../../../registry/index.js\";\nimport { getWithIndicator, putWithIndicator } from \"../../busy.js\";\nimport { type StorageClient } from \"../../storage.js\";\nimport { parseAridUr } from \"../../dkg/common.js\";\nimport { signingStateDir } from \"../common.js\";\nimport {\n signingRound2,\n createSigningPackage,\n deserializeKeyPackage,\n deserializeSigningCommitments,\n serializeSignatureShare,\n serializeSigningCommitments,\n identifierFromU16,\n type SerializedKeyPackage,\n type SerializedSigningCommitments,\n type FrostIdentifier,\n type FrostKeyPackage,\n type Ed25519SigningCommitments,\n type Ed25519SignatureShare,\n} from \"../../../frost/index.js\";\n\n// Import nonces from @frosts/core\nimport { Nonce, SigningNonces } from \"@frosts/core\";\nimport { Ed25519Sha512, serde } from \"@frosts/ed25519\";\n\n/**\n * Options for the sign round2 command.\n */\nexport interface SignRound2Options {\n registryPath?: string;\n sessionId: string;\n groupId?: string;\n timeoutSeconds?: number;\n preview?: boolean;\n verbose?: boolean;\n}\n\n/**\n * Result of the sign round2 command.\n */\nexport interface SignRound2Result {\n listeningArid: string;\n}\n\n/**\n * ReceiveState loaded from sign_receive.json.\n *\n * Port of `struct ReceiveState` from cmd/sign/participant/round2.rs.\n */\ninterface ReceiveState {\n groupId: ARID;\n participants: XID[];\n minSigners: number;\n targetUr: string;\n}\n\n/**\n * CommitState loaded from commit.json.\n *\n * Port of `struct CommitState` from cmd/sign/participant/round2.rs.\n */\ninterface CommitState {\n nextShareArid: ARID;\n targetUr: string;\n signingNonces: SigningNonces<typeof Ed25519Sha512>;\n signingCommitments: Ed25519SigningCommitments;\n}\n\n/**\n * Sealed request interface for GSTP.\n */\ninterface SealedRequestInstance {\n function: () => unknown;\n id: () => ARID;\n sender: () => { xid: () => XID };\n extractObjectForParameter: <T>(name: string) => T;\n objectsForParameter: (name: string) => Envelope[];\n}\n\n/**\n * Load receive state from sign_receive.json.\n *\n * Port of `load_receive_state()` from cmd/sign/participant/round2.rs.\n */\nfunction loadReceiveState(registryPath: string, sessionId: ARID, groupHint?: ARID): ReceiveState {\n const base = path.dirname(registryPath);\n const groupStateDir = path.join(base, \"group-state\");\n\n // Find candidate paths\n let groupDirs: [ARID, string][];\n\n if (groupHint) {\n groupDirs = [[groupHint, path.join(groupStateDir, groupHint.hex())]];\n } else {\n groupDirs = [];\n if (fs.existsSync(groupStateDir)) {\n for (const entry of fs.readdirSync(groupStateDir, { withFileTypes: true })) {\n if (entry.isDirectory() && entry.name.length === 64 && /^[0-9a-f]+$/i.test(entry.name)) {\n const groupId = ARIDClass.fromHex(entry.name);\n groupDirs.push([groupId, path.join(groupStateDir, entry.name)]);\n }\n }\n }\n }\n\n const candidates: [ARID, string][] = [];\n for (const [groupId, groupDir] of groupDirs) {\n const candidate = path.join(groupDir, \"signing\", sessionId.hex(), \"sign_receive.json\");\n if (fs.existsSync(candidate)) {\n candidates.push([groupId, candidate]);\n }\n }\n\n if (candidates.length === 0) {\n throw new Error(\n \"No sign_receive.json found for this session; run `frost sign participant receive` first\",\n );\n }\n if (candidates.length > 1) {\n throw new Error(\"Multiple groups contain this session; use --group to disambiguate\");\n }\n\n const [groupId, statePath] = candidates[0];\n const raw = JSON.parse(fs.readFileSync(statePath, \"utf-8\")) as Record<string, unknown>;\n\n const getStr = (key: string): string => {\n const value = raw[key];\n if (typeof value !== \"string\") {\n throw new Error(`Missing or invalid ${key} in sign_receive.json`);\n }\n return value;\n };\n\n // Validate session matches\n const sessionInState = parseAridUr(getStr(\"session\"));\n if (sessionInState.urString() !== sessionId.urString()) {\n throw new Error(\n `Session ${sessionInState.urString()} in sign_receive.json does not match requested session ${sessionId.urString()}`,\n );\n }\n\n // Validate group matches\n const groupInState = parseAridUr(getStr(\"group\"));\n if (groupInState.urString() !== groupId.urString()) {\n throw new Error(\n `Group ${groupInState.urString()} in sign_receive.json does not match directory group ${groupId.urString()}`,\n );\n }\n\n // Parse participants\n const participantsVal = raw[\"participants\"] as string[] | undefined;\n if (!participantsVal || !Array.isArray(participantsVal)) {\n throw new Error(\"Missing participants in sign_receive.json\");\n }\n\n const participants: XID[] = [];\n for (const entry of participantsVal) {\n if (typeof entry !== \"string\") {\n throw new Error(\"Invalid participant entry in sign_receive.json\");\n }\n participants.push(XIDClass.fromURString(entry));\n }\n\n // Parse min_signers\n const minSigners = raw[\"min_signers\"];\n if (typeof minSigners !== \"number\") {\n throw new Error(\"Missing min_signers in sign_receive.json\");\n }\n\n const targetUr = getStr(\"target\");\n\n return {\n groupId,\n participants,\n minSigners,\n targetUr,\n };\n}\n\n/**\n * Load commit state from commit.json (includes nonces).\n *\n * Port of `load_commit_state()` from cmd/sign/participant/round2.rs.\n */\nfunction loadCommitState(registryPath: string, groupId: ARID, sessionId: ARID): CommitState {\n const dir = signingStateDir(registryPath, groupId.hex(), sessionId.hex());\n const statePath = path.join(dir, \"commit.json\");\n\n if (!fs.existsSync(statePath)) {\n throw new Error(\n `Commit state not found at ${statePath}. Run \\`frost sign participant commit\\` first.`,\n );\n }\n\n const raw = JSON.parse(fs.readFileSync(statePath, \"utf-8\")) as Record<string, unknown>;\n\n const getStr = (key: string): string => {\n const value = raw[key];\n if (typeof value !== \"string\") {\n throw new Error(`Missing or invalid ${key} in commit.json`);\n }\n return value;\n };\n\n // Validate session matches\n const sessionInState = parseAridUr(getStr(\"session\"));\n if (sessionInState.urString() !== sessionId.urString()) {\n throw new Error(\n `Session ${sessionInState.urString()} in commit.json does not match requested session ${sessionId.urString()}`,\n );\n }\n\n const nextShareArid = parseAridUr(getStr(\"next_share_arid\"));\n const targetUr = getStr(\"target\");\n\n // Deserialize signing nonces\n const noncesRaw = raw[\"signing_nonces\"] as Record<string, string> | undefined;\n if (!noncesRaw) {\n throw new Error(\"Missing signing_nonces in commit.json\");\n }\n\n const hidingNonce = Nonce.deserialize(Ed25519Sha512, serde.hexToBytes(noncesRaw[\"hiding\"]));\n const bindingNonce = Nonce.deserialize(Ed25519Sha512, serde.hexToBytes(noncesRaw[\"binding\"]));\n const signingNonces = SigningNonces.fromNonces(Ed25519Sha512, hidingNonce, bindingNonce);\n\n // Deserialize signing commitments\n const commitmentsRaw = raw[\"signing_commitments\"] as SerializedSigningCommitments | undefined;\n if (!commitmentsRaw) {\n throw new Error(\"Missing signing_commitments in commit.json\");\n }\n const signingCommitments = deserializeSigningCommitments(commitmentsRaw);\n\n return {\n nextShareArid,\n targetUr,\n signingNonces,\n signingCommitments,\n };\n}\n\n/**\n * Validate the incoming GSTP request.\n *\n * Port of request validation logic from cmd/sign/participant/round2.rs.\n */\nfunction validateShareRequest(\n sealedRequest: SealedRequestInstance,\n sessionId: ARID,\n expectedCoordinator: XID,\n): void {\n // Check function\n const expectedFunction = EnvelopeFunction.fromString(\"signRound2\");\n const actualFunction = sealedRequest.function();\n // @ts-expect-error - function() returns unknown, but it should have .equals()\n if (actualFunction.equals(expectedFunction) !== true) {\n throw new Error(`Unexpected request function: ${String(sealedRequest.function())}`);\n }\n\n // Check session ID\n if (sealedRequest.id().urString() !== sessionId.urString()) {\n throw new Error(\n `Session ID mismatch (request ${sealedRequest.id().urString()}, expected ${sessionId.urString()})`,\n );\n }\n\n // Check sender (coordinator)\n if (sealedRequest.sender().xid().urString() !== expectedCoordinator.urString()) {\n throw new Error(\n `Unexpected request sender: ${sealedRequest.sender().xid().urString()} (expected coordinator ${expectedCoordinator.urString()})`,\n );\n }\n}\n\n/**\n * Extract all commitments from the signRound2 request.\n *\n * Port of `parse_commitments()` from cmd/sign/participant/round2.rs.\n */\nfunction extractCommitments(\n sealedRequest: SealedRequestInstance,\n receiveState: ReceiveState,\n): Map<string, Ed25519SigningCommitments> {\n const commitments = new Map<string, Ed25519SigningCommitments>();\n\n const commitmentObjects = sealedRequest.objectsForParameter(\"commitment\");\n\n for (const entry of commitmentObjects) {\n // Extract XID subject\n const xid = XIDClass.fromTaggedCbor(entry.subject().tryLeaf());\n\n // Extract commitments from the \"commitments\" predicate\n const commitmentsObjects = entry.objectsForPredicate(\"commitments\");\n if (commitmentsObjects.length === 0) {\n throw new Error(`Missing commitments for participant ${xid.urString()}`);\n }\n\n const commitmentsJson = JSONComponent.fromTaggedCbor(commitmentsObjects[0].subject().tryLeaf());\n const serializedCommitments = JSON.parse(\n commitmentsJson.asStr(),\n ) as SerializedSigningCommitments;\n const signingCommitments = deserializeSigningCommitments(serializedCommitments);\n\n const xidUr = xid.urString();\n if (commitments.has(xidUr)) {\n throw new Error(`Duplicate commitments for participant ${xidUr}`);\n }\n commitments.set(xidUr, signingCommitments);\n }\n\n if (commitments.size === 0) {\n throw new Error(\"signRound2 request contains no commitments\");\n }\n\n // Validate expected participant set\n const expectedSet = new Set(receiveState.participants.map((p) => p.urString()));\n const actualSet = new Set(commitments.keys());\n\n const missing: string[] = [];\n const extra: string[] = [];\n\n for (const xid of expectedSet) {\n if (!actualSet.has(xid)) {\n missing.push(xid);\n }\n }\n for (const xid of actualSet) {\n if (!expectedSet.has(xid)) {\n extra.push(xid);\n }\n }\n\n if (missing.length > 0 || extra.length > 0) {\n throw new Error(\n `signRound2 commitments do not match session participants (missing: ${missing.join(\", \")}; extra: ${extra.join(\", \")})`,\n );\n }\n\n return commitments;\n}\n\n/**\n * Build a map from XID to FROST identifier (sorted participant order).\n *\n * Port of `xid_identifier_map()` from cmd/sign/participant/round2.rs.\n */\nfunction xidIdentifierMap(participants: XID[]): Map<string, FrostIdentifier> {\n const map = new Map<string, FrostIdentifier>();\n for (let i = 0; i < participants.length; i++) {\n const identifier = identifierFromU16(i + 1);\n map.set(participants[i].urString(), identifier);\n }\n return map;\n}\n\n/**\n * Build signing commitments with identifiers.\n *\n * Port of `commitments_with_identifiers()` from cmd/sign/participant/round2.rs.\n */\nfunction commitmentsWithIdentifiers(\n commitments: Map<string, Ed25519SigningCommitments>,\n xidToIdentifier: Map<string, FrostIdentifier>,\n): Map<FrostIdentifier, Ed25519SigningCommitments> {\n const mapped = new Map<FrostIdentifier, Ed25519SigningCommitments>();\n for (const [xidUr, commits] of commitments) {\n const identifier = xidToIdentifier.get(xidUr);\n if (!identifier) {\n throw new Error(`Unknown participant ${xidUr}`);\n }\n mapped.set(identifier, commits);\n }\n return mapped;\n}\n\n/**\n * Build the signRound2Response body envelope.\n *\n * Port of response body construction from cmd/sign/participant/round2.rs.\n */\nfunction buildResponseBody(\n sessionId: ARID,\n signatureShare: Ed25519SignatureShare,\n finalizeArid: ARID,\n): Envelope {\n const shareHex = serializeSignatureShare(signatureShare);\n const shareJson = JSONComponent.fromString(JSON.stringify({ share: shareHex }));\n\n return Envelope.unit()\n .addType(\"signRound2Response\")\n .addAssertion(\"session\", sessionId)\n .addAssertion(\"signature_share\", shareJson)\n .addAssertion(\"response_arid\", finalizeArid);\n}\n\n/**\n * Persist share state to share.json.\n *\n * Port of `persist_share_state()` from cmd/sign/participant/round2.rs.\n */\nfunction persistShareState(\n registryPath: string,\n groupId: ARID,\n sessionId: ARID,\n responseArid: ARID,\n finalizeArid: ARID,\n signatureShare: Ed25519SignatureShare,\n commitments: Map<string, Ed25519SigningCommitments>,\n): void {\n const dir = signingStateDir(registryPath, groupId.hex(), sessionId.hex());\n fs.mkdirSync(dir, { recursive: true });\n\n // Build commitments JSON object\n const commitmentsJson: Record<string, SerializedSigningCommitments> = {};\n for (const [xidUr, commits] of commitments) {\n commitmentsJson[xidUr] = serializeSigningCommitments(commits);\n }\n\n // Build root JSON object\n const root = {\n session: sessionId.urString(),\n response_arid: responseArid.urString(),\n finalize_arid: finalizeArid.urString(),\n signature_share: { share: serializeSignatureShare(signatureShare) },\n commitments: commitmentsJson,\n };\n\n fs.writeFileSync(path.join(dir, \"share.json\"), JSON.stringify(root, null, 2));\n}\n\n/**\n * Execute the sign participant round 2 command.\n *\n * Receives round 2 request and sends signature share.\n *\n * Port of `CommandArgs::exec()` from cmd/sign/participant/round2.rs.\n */\nexport async function round2(\n client: StorageClient,\n options: SignRound2Options,\n cwd: string,\n): Promise<SignRound2Result> {\n const registryPath = resolveRegistryPath(options.registryPath, cwd);\n const registry = Registry.load(registryPath);\n\n const owner = registry.owner();\n if (!owner) {\n throw new Error(\"Registry owner is required\");\n }\n const ownerXidDocument = owner.xidDocument();\n\n const sessionId = parseAridUr(options.sessionId);\n const groupHint = options.groupId ? parseAridUr(options.groupId) : undefined;\n\n // Load receive state (finds group automatically if not specified)\n const receiveState = loadReceiveState(registryPath, sessionId, groupHint);\n const groupId = receiveState.groupId;\n\n const groupRecord = registry.group(groupId);\n if (!groupRecord) {\n throw new Error(\"Group not found in registry\");\n }\n\n // Validate min_signers matches\n if (groupRecord.minSigners() !== receiveState.minSigners) {\n throw new Error(\n `Session min_signers ${receiveState.minSigners} does not match registry ${groupRecord.minSigners()}`,\n );\n }\n\n // Validate participants match\n const registryParticipants = new Set(groupRecord.participants().map((p) => p.xid().urString()));\n const sessionParticipants = new Set(receiveState.participants.map((p) => p.urString()));\n\n if (\n registryParticipants.size !== sessionParticipants.size ||\n ![...registryParticipants].every((p) => sessionParticipants.has(p))\n ) {\n throw new Error(\"Session participants do not match registry group participants\");\n }\n\n // Validate owner participates in this session\n if (!sessionParticipants.has(owner.xid().urString())) {\n throw new Error(\"This participant is not part of the signing session\");\n }\n\n // Get listening ARID from registry\n const listeningAtArid = groupRecord.listeningAtArid();\n if (!listeningAtArid) {\n throw new Error(\n \"No listening ARID for signRound2. Did you run `frost sign participant commit`?\",\n );\n }\n\n // Load commit state and validate\n const commitState = loadCommitState(registryPath, groupId, sessionId);\n\n if (commitState.nextShareArid.urString() !== listeningAtArid.urString()) {\n throw new Error(\n `Listening ARID in registry (${listeningAtArid.urString()}) does not match persisted commit state (${commitState.nextShareArid.urString()})`,\n );\n }\n\n if (commitState.targetUr !== receiveState.targetUr) {\n throw new Error(\"Target envelope in commit state does not match persisted signInvite request\");\n }\n\n // Load key package\n const keyPackagePath = groupRecord.contributions().keyPackage;\n if (!keyPackagePath) {\n throw new Error(\"Key package path not found; did you finish DKG?\");\n }\n\n interface KeyPackageFile {\n group?: string;\n key_package: SerializedKeyPackage;\n }\n\n const keyPackageFile = JSON.parse(fs.readFileSync(keyPackagePath, \"utf-8\")) as KeyPackageFile;\n const keyPackage: FrostKeyPackage = deserializeKeyPackage(keyPackageFile.key_package);\n\n // Create finalize ARID\n const finalizeArid = ARIDClass.new();\n\n // Compute target digest from persisted target envelope\n const targetEnvelope = Envelope.fromURString(receiveState.targetUr);\n const targetDigest: Digest = targetEnvelope.subject().digest();\n\n if (options.verbose === true) {\n console.error(\"Fetching signRound2 request from Hubert...\");\n }\n\n // Fetch request from storage\n const requestEnvelope = await getWithIndicator(\n client,\n listeningAtArid,\n \"signRound2 request\",\n options.timeoutSeconds,\n options.verbose ?? false,\n );\n\n if (!requestEnvelope) {\n throw new Error(\"signRound2 request not found in Hubert storage\");\n }\n\n // Parse sealed request\n const signerPrivateKeys = ownerXidDocument.inceptionPrivateKeys();\n if (!signerPrivateKeys) {\n throw new Error(\"Owner XID document has no private keys\");\n }\n\n // eslint-disable-next-line @typescript-eslint/no-require-imports, no-undef\n const { SealedRequest: SealedRequestClass } = require(\"@bcts/gstp\") as {\n SealedRequest: {\n tryFromEnvelope: (\n envelope: Envelope,\n expectedSender: XID | undefined,\n now: CborDate,\n recipientPrivateKeys: unknown,\n ) => SealedRequestInstance;\n };\n };\n\n const now = CborDate.now();\n const sealedRequest = SealedRequestClass.tryFromEnvelope(\n requestEnvelope,\n undefined,\n now,\n signerPrivateKeys,\n );\n\n // Validate request\n const expectedCoordinator = groupRecord.coordinator().xid();\n validateShareRequest(sealedRequest, sessionId, expectedCoordinator);\n\n // Extract response ARID from request\n const responseArid: ARID = sealedRequest.extractObjectForParameter(\"response_arid\");\n\n // Extract and validate commitments\n const commitmentsByXid = extractCommitments(sealedRequest, receiveState);\n\n // Verify our commitments match\n const myCommitments = commitmentsByXid.get(owner.xid().urString());\n if (!myCommitments) {\n throw new Error(\"signRound2 request missing commitments for this participant\");\n }\n\n // Compare commitments using serialized form\n const myCommitmentsSerialized = serializeSigningCommitments(myCommitments);\n const storedCommitmentsSerialized = serializeSigningCommitments(commitState.signingCommitments);\n\n if (\n myCommitmentsSerialized.hiding !== storedCommitmentsSerialized.hiding ||\n myCommitmentsSerialized.binding !== storedCommitmentsSerialized.binding\n ) {\n throw new Error(\"signRound2 request commitments do not match locally stored commitments\");\n }\n\n // Build XID to identifier map (sorted participant order)\n const xidToIdentifier = xidIdentifierMap(receiveState.participants);\n\n // Verify our identifier matches key package\n const myIdentifier = xidToIdentifier.get(owner.xid().urString());\n if (!myIdentifier) {\n throw new Error(\"Identifier for participant not found\");\n }\n\n // Verify key package min_signers matches\n if (keyPackage.minSigners !== receiveState.minSigners) {\n throw new Error(\n `Key package min_signers ${keyPackage.minSigners} does not match session ${receiveState.minSigners}`,\n );\n }\n\n // Verify enough commitments\n if (commitmentsByXid.size < receiveState.minSigners) {\n throw new Error(\n `signRound2 request contained ${commitmentsByXid.size} commitments but requires at least ${receiveState.minSigners} signers`,\n );\n }\n\n // Build signing commitments with identifiers\n const signingCommitments = commitmentsWithIdentifiers(commitmentsByXid, xidToIdentifier);\n\n // Create signing package\n const signingPackage = createSigningPackage(signingCommitments, targetDigest.data());\n\n // Generate signature share using FROST round 2\n const signatureShare = signingRound2(signingPackage, commitState.signingNonces, keyPackage);\n\n // Build response body\n const responseBody = buildResponseBody(sessionId, signatureShare, finalizeArid);\n\n // Build sealed response\n // eslint-disable-next-line @typescript-eslint/no-require-imports, no-undef\n const { SealedResponse: SealedResponseClass } = require(\"@bcts/gstp\") as {\n SealedResponse: {\n newSuccess: (\n requestId: ARID,\n sender: XIDDocument,\n ) => {\n withResult: (result: Envelope) => {\n withPeerContinuation: (continuation: unknown) => {\n toEnvelope: (\n expiry: CborDate | undefined,\n signerPrivateKeys: unknown,\n recipient: XIDDocument | undefined,\n ) => Envelope;\n };\n toEnvelope: (\n expiry: CborDate | undefined,\n signerPrivateKeys: unknown,\n recipient: XIDDocument | undefined,\n ) => Envelope;\n };\n };\n };\n };\n\n const sealedResponse = SealedResponseClass.newSuccess(\n sealedRequest.id(),\n ownerXidDocument,\n ).withResult(responseBody);\n\n // Preview mode - print unsealed response\n if (options.preview === true) {\n const unsealed = sealedResponse.toEnvelope(undefined, signerPrivateKeys, undefined);\n console.log(unsealed.urString());\n return {\n listeningArid: finalizeArid.urString(),\n };\n }\n\n // Get coordinator XID document for encryption\n let coordinatorDoc: XIDDocument;\n if (expectedCoordinator.urString() === owner.xid().urString()) {\n coordinatorDoc = ownerXidDocument;\n } else {\n const coordinatorRecord = registry.participant(expectedCoordinator);\n if (!coordinatorRecord) {\n throw new Error(`Coordinator ${expectedCoordinator.urString()} not found in registry`);\n }\n coordinatorDoc = coordinatorRecord.xidDocument();\n }\n\n // Create response envelope with expiry\n const expiry = CborDate.withDurationFromNow(60 * 60); // 1 hour\n const responseEnvelope = sealedResponse.toEnvelope(expiry, signerPrivateKeys, coordinatorDoc);\n\n // Send response\n await putWithIndicator(\n client,\n responseArid,\n responseEnvelope,\n \"Signature Share\",\n options.verbose ?? false,\n );\n\n // Persist share state\n persistShareState(\n registryPath,\n groupId,\n sessionId,\n responseArid,\n finalizeArid,\n signatureShare,\n commitmentsByXid,\n );\n\n // Update registry with finalize listening ARID\n const groupRecordMutable = registry.group(groupId);\n if (groupRecordMutable) {\n groupRecordMutable.setListeningAtArid(finalizeArid);\n registry.save(registryPath);\n }\n\n if (options.verbose === true) {\n console.error(`Posted signature share to ${responseArid.urString()}`);\n }\n\n return {\n listeningArid: finalizeArid.urString(),\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
const
|
|
1
|
+
const require_rolldown_runtime = require("./rolldown-runtime-DakpK96I.cjs");
|
|
2
2
|
const require_proposed_participant = require("./proposed-participant-BvHNnpcZ.cjs");
|
|
3
3
|
const require_registry_index = require("./registry/index.cjs");
|
|
4
|
-
const require_common = require("./common-
|
|
4
|
+
const require_common = require("./common-3msAx7hO.cjs");
|
|
5
5
|
const require_busy = require("./busy-B_h0bNAJ.cjs");
|
|
6
|
-
const require_registry = require("./registry-
|
|
6
|
+
const require_registry = require("./registry-D-rFKk9R.cjs");
|
|
7
7
|
const require_frost_index = require("./frost/index.cjs");
|
|
8
8
|
let _bcts_components = require("@bcts/components");
|
|
9
9
|
let _bcts_dcbor = require("@bcts/dcbor");
|
|
10
10
|
let _bcts_envelope = require("@bcts/envelope");
|
|
11
11
|
let _bcts_gstp = require("@bcts/gstp");
|
|
12
12
|
let node_fs = require("node:fs");
|
|
13
|
-
node_fs =
|
|
13
|
+
node_fs = require_rolldown_runtime.__toESM(node_fs, 1);
|
|
14
14
|
let node_path = require("node:path");
|
|
15
|
-
node_path =
|
|
15
|
+
node_path = require_rolldown_runtime.__toESM(node_path, 1);
|
|
16
16
|
let _frosts_ed25519 = require("@frosts/ed25519");
|
|
17
17
|
let _frosts_core = require("@frosts/core");
|
|
18
18
|
//#region src/cmd/dkg/participant/round2.ts
|
|
@@ -27,7 +27,7 @@ let _frosts_core = require("@frosts/core");
|
|
|
27
27
|
*
|
|
28
28
|
* @module
|
|
29
29
|
*/
|
|
30
|
-
var round2_exports = /* @__PURE__ */
|
|
30
|
+
var round2_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({ round2: () => round2 });
|
|
31
31
|
/**
|
|
32
32
|
* Load persisted round 1 state from disk.
|
|
33
33
|
*
|
|
@@ -290,4 +290,4 @@ Object.defineProperty(exports, "round2_exports", {
|
|
|
290
290
|
}
|
|
291
291
|
});
|
|
292
292
|
|
|
293
|
-
//# sourceMappingURL=round2-
|
|
293
|
+
//# sourceMappingURL=round2-DhdFarwY.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"round2-CvrmylN1.cjs","names":["groupStateDir","path","fs","Ed25519Sha512","hexToBytes","VerifiableSecretSharingCommitment","CoefficientCommitment","identifierFromU16","round1","serde","EnvelopeFunction","ARID","compareXidBytes","XID","JSONWrapper","identifierToHex","Envelope","serializeDkgRound2Package","bytesToHex","resolveRegistryPath","Registry","parseAridUr","isVerbose","createStorageClient","getWithIndicator","CborDate","SealedRequest","dkgPart2","SealedResponse","putWithIndicator"],"sources":["../src/cmd/dkg/participant/round2.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * DKG participant round 2 command.\n *\n * Port of cmd/dkg/participant/round2.rs from frost-hubert-rust.\n *\n * @module\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { ARID, JSON as JSONWrapper, XID } from \"@bcts/components\";\nimport { compareXidBytes } from \"../../../dkg/proposed-participant.js\";\nimport { CborDate } from \"@bcts/dcbor\";\nimport { Envelope, Function as EnvelopeFunction } from \"@bcts/envelope\";\nimport { SealedRequest, SealedResponse } from \"@bcts/gstp\";\nimport type { XIDDocument } from \"@bcts/xid\";\n\nimport { type GroupRecord, Registry, resolveRegistryPath } from \"../../../registry/index.js\";\nimport { getWithIndicator, putWithIndicator } from \"../../busy.js\";\nimport { groupStateDir, isVerbose } from \"../../common.js\";\nimport { createStorageClient, type StorageClient, type StorageSelection } from \"../../storage.js\";\nimport { parseAridUr } from \"../common.js\";\nimport {\n dkgPart2,\n serializeDkgRound2Package,\n identifierFromU16,\n identifierToHex,\n hexToBytes,\n bytesToHex,\n type DkgRound1Package,\n type DkgRound1SecretPackage,\n type DkgRound2SecretPackage,\n type FrostIdentifier,\n} from \"../../../frost/index.js\";\nimport { Ed25519Sha512, serde } from \"@frosts/ed25519\";\nimport { round1, CoefficientCommitment, VerifiableSecretSharingCommitment } from \"@frosts/core\";\n\n/**\n * Options for the DKG round2 command.\n */\nexport interface DkgRound2Options {\n registryPath?: string;\n groupId: string;\n timeoutSeconds?: number;\n preview?: boolean;\n storageSelection?: StorageSelection;\n verbose?: boolean;\n}\n\n/**\n * Result of the DKG round2 command.\n */\nexport interface DkgRound2Result {\n listeningArid: string;\n envelopeUr?: string;\n}\n\n/**\n * Persisted round 1 state loaded from disk.\n */\ninterface Round1State {\n secretPackage: DkgRound1SecretPackage;\n ourRound1Package: DkgRound1Package;\n}\n\n/**\n * Extracted round 1 packages from coordinator request.\n */\ntype Round1Packages = [Map<FrostIdentifier, DkgRound1Package>, [XID, DkgRound1Package][]];\n\n/**\n * Load persisted round 1 state from disk.\n *\n * Port of round1_secret loading from cmd/dkg/participant/round2.rs lines 86-97.\n */\nfunction loadRound1State(registryPath: string, groupId: ARID): Round1State {\n const packagesDir = groupStateDir(registryPath, groupId.hex());\n const round1SecretPath = path.join(packagesDir, \"round1_secret.json\");\n\n if (!fs.existsSync(round1SecretPath)) {\n throw new Error(\n `Round 1 secret not found at ${round1SecretPath}. Did you respond to the invite?`,\n );\n }\n\n // Mirrors Rust `frost::keys::dkg::round1::SecretPackage` JSON\n // (`frost-rust/frost-core/src/keys/dkg.rs:120-139`): no `header`,\n // snake_case `min_signers` / `max_signers`, identifier and\n // coefficients as lowercase hex strings, commitment as a flat array\n // of hex strings.\n const secretJson = JSON.parse(fs.readFileSync(round1SecretPath, \"utf-8\")) as {\n identifier: string;\n coefficients: string[];\n commitment: string[];\n min_signers: number;\n max_signers: number;\n };\n\n // Deserialize coefficients (scalars)\n const coefficients = secretJson.coefficients.map((hex) =>\n Ed25519Sha512.deserializeScalar(hexToBytes(hex)),\n );\n\n // Deserialize commitment (coefficient commitments)\n const coefficientCommitments = secretJson.commitment.map((hex) =>\n CoefficientCommitment.deserialize(Ed25519Sha512, hexToBytes(hex)),\n );\n\n const commitment = new VerifiableSecretSharingCommitment(Ed25519Sha512, coefficientCommitments);\n\n // Create the secret package\n // Need to find the actual identifier u16 value from the coefficients array length or saved state\n // The identifier is typically serialized as a scalar, but we need the u16 value\n // Parse it from the hex string - first 2 bytes as little-endian u16\n const idBytes = hexToBytes(secretJson.identifier);\n let identifierU16 = 1;\n if (idBytes.length >= 2) {\n identifierU16 = idBytes[0] | (idBytes[1] << 8);\n }\n if (identifierU16 === 0) {\n identifierU16 = 1; // Default to 1 if parsing failed\n }\n\n const parsedIdentifier = identifierFromU16(identifierU16);\n\n const secretPackage: DkgRound1SecretPackage = new round1.SecretPackage(\n Ed25519Sha512,\n parsedIdentifier,\n coefficients,\n commitment,\n secretJson.min_signers,\n secretJson.max_signers,\n );\n\n // Load the round 1 package as well\n const round1PackagePath = path.join(packagesDir, \"round1_package.json\");\n const packageJson = JSON.parse(fs.readFileSync(round1PackagePath, \"utf-8\")) as {\n header: { version: number; ciphersuite: string };\n commitment: string[];\n proof_of_knowledge: string;\n };\n\n const ourRound1Package = serde.round1PackageFromJson(packageJson);\n\n return { secretPackage, ourRound1Package };\n}\n\n/**\n * Validate the round 2 request from the coordinator.\n *\n * Port of request validation from cmd/dkg/participant/round2.rs lines 118-158.\n */\nfunction validateRound2Request(\n sealedRequest: SealedRequest,\n groupId: ARID,\n expectedCoordinator: XID,\n): ARID {\n // Validate the request function\n if (!sealedRequest.function().equals(EnvelopeFunction.fromString(\"dkgRound2\"))) {\n throw new Error(`Unexpected request function: ${sealedRequest.function().toString()}`);\n }\n\n // Validate the sender is the expected coordinator\n if (sealedRequest.sender().xid().urString() !== expectedCoordinator.urString()) {\n throw new Error(\n `Unexpected request sender: ${sealedRequest.sender().xid().urString()} ` +\n `(expected coordinator ${expectedCoordinator.urString()})`,\n );\n }\n\n // Validate the group ID matches\n const requestGroupIdEnvelope = sealedRequest.objectForParameter(\"group\");\n if (requestGroupIdEnvelope === undefined) {\n throw new Error(\"Request missing group parameter\");\n }\n const requestGroupId = requestGroupIdEnvelope.extractSubject((cbor) => ARID.fromTaggedCbor(cbor));\n if (requestGroupId.urString() !== groupId.urString()) {\n throw new Error(\n `Request group ID ${requestGroupId.urString()} does not match expected ${groupId.urString()}`,\n );\n }\n\n // Extract where we should post our response\n const responseAridEnvelope = sealedRequest.objectForParameter(\"responseArid\");\n if (responseAridEnvelope === undefined) {\n throw new Error(\"Request missing responseArid parameter\");\n }\n const responseArid = responseAridEnvelope.extractSubject((cbor) => ARID.fromTaggedCbor(cbor));\n\n return responseArid;\n}\n\n/**\n * Extract round 1 packages from the request and convert to Map<Identifier, Package>.\n *\n * Port of `extract_round1_packages()` from cmd/dkg/participant/round2.rs lines 291-366.\n */\nfunction extractRound1Packages(\n request: SealedRequest,\n groupRecord: GroupRecord,\n ownerXid: XID,\n): Round1Packages {\n // Build XID -> Identifier mapping based on sorted participant order\n const sortedXids: XID[] = groupRecord.participants().map((p) => p.xid());\n\n // Add owner if not already in list\n const ownerUrString = ownerXid.urString();\n if (!sortedXids.some((xid) => xid.urString() === ownerUrString)) {\n sortedXids.push(ownerXid);\n }\n\n // Sort by XID byte order — mirrors Rust `XID::cmp` (raw 32-byte\n // lex compare). The earlier port used `urString().localeCompare(...)`,\n // which differs from byte order for any byte ≥ 0x80 and is locale-\n // aware, producing different FROST identifier assignments than Rust.\n sortedXids.sort((a, b) => compareXidBytes(a.toData(), b.toData()));\n\n // Deduplicate\n const deduped: XID[] = [];\n for (const xid of sortedXids) {\n if (deduped.length === 0 || deduped[deduped.length - 1].urString() !== xid.urString()) {\n deduped.push(xid);\n }\n }\n\n // Build XID -> Identifier mapping (1-indexed)\n const xidToIdentifier = new Map<string, FrostIdentifier>();\n for (let i = 0; i < deduped.length; i++) {\n const identifier = identifierFromU16(i + 1);\n xidToIdentifier.set(deduped[i].urString(), identifier);\n }\n\n const myXidStr = ownerXid.urString();\n\n // Extract all round1Package parameters\n const packages = new Map<FrostIdentifier, DkgRound1Package>();\n const packagesByXid: [XID, DkgRound1Package][] = [];\n\n const packageEnvelopes = request.objectsForParameter(\"round1Package\");\n for (const packageEnvelope of packageEnvelopes) {\n // Extract participant XID from the envelope\n const participantEnvelope = packageEnvelope.objectForPredicate(\"participant\");\n if (participantEnvelope === undefined) {\n throw new Error(\"round1Package missing participant predicate\");\n }\n const participantXid = participantEnvelope.extractSubject((cbor) => XID.fromTaggedCbor(cbor));\n\n // Skip our own package\n if (participantXid.urString() === myXidStr) {\n continue;\n }\n\n // Extract the package bytes (stored as JSON tag)\n const packageJson = packageEnvelope.extractSubject((cbor) => JSONWrapper.fromTaggedCbor(cbor));\n const packageData = JSON.parse(new TextDecoder().decode(packageJson.toData())) as {\n header: { version: number; ciphersuite: string };\n commitment: string[];\n proof_of_knowledge: string;\n };\n\n const pkg = serde.round1PackageFromJson(packageData);\n\n // Get the identifier for this participant\n const identifier = xidToIdentifier.get(participantXid.urString());\n if (identifier === undefined) {\n throw new Error(`Unknown participant XID in round1Package: ${participantXid.urString()}`);\n }\n\n packages.set(identifier, pkg);\n packagesByXid.push([participantXid, pkg]);\n }\n\n // Validate we have the expected number of packages\n const expectedPackages = xidToIdentifier.size - 1; // Exclude ourselves\n if (packages.size !== expectedPackages) {\n throw new Error(`Expected ${expectedPackages} Round 1 packages, found ${packages.size}`);\n }\n\n return [packages, packagesByXid];\n}\n\n/**\n * Build the response body containing Round 2 packages.\n *\n * Port of `build_response_body()` from cmd/dkg/participant/round2.rs lines 373-425.\n */\nfunction buildResponseBody(\n groupId: ARID,\n participantXid: XID,\n responseArid: ARID,\n round2Packages: Map<FrostIdentifier, unknown>,\n groupRecord: GroupRecord,\n): Envelope {\n // Build Identifier -> XID mapping\n const sortedXids: XID[] = groupRecord.participants().map((p) => p.xid());\n\n // Add participant if not already in list\n const participantUrString = participantXid.urString();\n if (!sortedXids.some((xid) => xid.urString() === participantUrString)) {\n sortedXids.push(participantXid);\n }\n\n // Sort by XID byte order — mirrors Rust `XID::cmp` (raw 32-byte\n // lex compare). The earlier port used `urString().localeCompare(...)`,\n // which differs from byte order for any byte ≥ 0x80 and is locale-\n // aware, producing different FROST identifier assignments than Rust.\n sortedXids.sort((a, b) => compareXidBytes(a.toData(), b.toData()));\n\n // Deduplicate\n const deduped: XID[] = [];\n for (const xid of sortedXids) {\n if (deduped.length === 0 || deduped[deduped.length - 1].urString() !== xid.urString()) {\n deduped.push(xid);\n }\n }\n\n // Build Identifier -> XID mapping (1-indexed)\n const identifierToXid = new Map<string, XID>();\n for (let i = 0; i < deduped.length; i++) {\n const identifier = identifierFromU16(i + 1);\n identifierToXid.set(identifierToHex(identifier), deduped[i]);\n }\n\n let envelope = Envelope.unit()\n .addType(\"dkgRound2Response\")\n .addAssertion(\"group\", groupId)\n .addAssertion(\"participant\", participantXid)\n .addAssertion(\"response_arid\", responseArid);\n\n // Add each Round 2 package with the recipient's XID\n for (const [identifier, pkg] of round2Packages) {\n const idHex = identifierToHex(identifier);\n const recipientXid = identifierToXid.get(idHex);\n if (recipientXid === undefined) {\n throw new Error(\"Unknown identifier in round2_packages\");\n }\n\n // Serialize package to JSON and wrap in CBOR JSON tag\n const serialized = serializeDkgRound2Package(\n pkg as Parameters<typeof serializeDkgRound2Package>[0],\n );\n const jsonStr = JSON.stringify(serialized);\n const jsonBytes = new TextEncoder().encode(jsonStr);\n const jsonWrapper = JSONWrapper.fromData(jsonBytes);\n\n const packageEnvelope = Envelope.new(jsonWrapper).addAssertion(\"recipient\", recipientXid);\n\n envelope = envelope.addAssertion(\"round2Package\", packageEnvelope);\n }\n\n return envelope;\n}\n\n/**\n * Serialize round 2 secret package to JSON format for persistence.\n *\n * Mirrors the on-disk shape produced by Rust\n * `serde_json::to_vec_pretty(&frost::keys::dkg::round2::SecretPackage)`\n * (see `frost-rust/frost-core/src/keys/dkg.rs:269-287`):\n *\n * ```json\n * {\n * \"identifier\": \"<lowercase hex scalar>\",\n * \"commitment\": [\"<hex>\", \"<hex>\", ...],\n * \"secret_share\": \"<hex>\",\n * \"min_signers\": <u16>,\n * \"max_signers\": <u16>\n * }\n * ```\n *\n * `frost::keys::dkg::round2::SecretPackage` is\n * `#[serde(deny_unknown_fields)]`. The earlier port emitted\n * camelCase keys (`secretShare`, `minSigners`, `maxSigners`), a\n * nested `commitment.coefficients` shape, and a numeric\n * `identifier` — all of which Rust's standard derive would\n * reject and which had no chance of round-tripping with Rust.\n *\n * `participantIndex` is unused now that the identifier comes\n * directly from `secret.identifier.serialize()`; we keep it in the\n * signature for source-level parity with the call sites.\n */\nfunction serializeRound2SecretPackage(\n secret: DkgRound2SecretPackage,\n _participantIndex: number,\n): Record<string, unknown> {\n const commitment = secret.commitment;\n const commitmentCoefficients = commitment.serialize().map((c: Uint8Array) => bytesToHex(c));\n const secretShare = bytesToHex(Ed25519Sha512.serializeScalar(secret.secretShare()));\n\n return {\n identifier: bytesToHex(secret.identifier.serialize()),\n commitment: commitmentCoefficients,\n secret_share: secretShare,\n min_signers: secret.minSigners,\n max_signers: secret.maxSigners,\n };\n}\n\n/**\n * Persist round 2 state to disk.\n *\n * Port of round 2 secret persistence from cmd/dkg/participant/round2.rs lines 229-251.\n */\nfunction persistRound2State(\n registryPath: string,\n groupId: ARID,\n round2Secret: DkgRound2SecretPackage,\n round1PackagesByXid: [XID, DkgRound1Package][],\n participantIndex: number,\n): string {\n const packagesDir = groupStateDir(registryPath, groupId.hex());\n fs.mkdirSync(packagesDir, { recursive: true });\n\n // Persist Round 2 secret\n const round2SecretPath = path.join(packagesDir, \"round2_secret.json\");\n const round2SecretJson = serializeRound2SecretPackage(round2Secret, participantIndex);\n fs.writeFileSync(round2SecretPath, JSON.stringify(round2SecretJson, null, 2));\n\n // Persist received Round 1 packages for finalize phase\n const round1PackagesPath = path.join(packagesDir, \"collected_round1.json\");\n const round1Json: Record<string, unknown> = {};\n for (const [xid, pkg] of round1PackagesByXid) {\n const packageJson = serde.round1PackageToJson(pkg);\n round1Json[xid.urString()] = packageJson;\n }\n fs.writeFileSync(round1PackagesPath, JSON.stringify(round1Json, null, 2));\n\n return round2SecretPath;\n}\n\n/**\n * Execute the DKG participant round 2 command.\n *\n * Responds to the Round 2 request from the coordinator, runs FROST DKG part2\n * to generate Round 2 packages, and posts the response back.\n *\n * Port of `CommandArgs::exec()` from cmd/dkg/participant/round2.rs lines 55-288.\n */\nexport async function round2(\n _client: StorageClient | undefined,\n options: DkgRound2Options,\n cwd: string,\n): Promise<DkgRound2Result> {\n if (options.storageSelection === undefined) {\n throw new Error(\"Hubert storage is required for round2\");\n }\n\n const registryPath = resolveRegistryPath(options.registryPath, cwd);\n const registry = Registry.load(registryPath);\n\n const owner = registry.owner();\n if (owner === undefined) {\n throw new Error(\"Registry owner is required\");\n }\n\n const groupId = parseAridUr(options.groupId);\n const groupRecord = registry.group(groupId);\n if (groupRecord === undefined) {\n throw new Error(\"Group not found in registry\");\n }\n\n // Get the ARID where we're listening for the Round 2 request\n const listeningAtArid = groupRecord.listeningAtArid();\n if (listeningAtArid === undefined) {\n throw new Error(\"No listening ARID for this group. Did you respond to the invite?\");\n }\n\n // Load our Round 1 secret\n const round1State = loadRound1State(registryPath, groupId);\n\n if (isVerbose() || options.verbose === true) {\n console.error(\"Fetching Round 2 request from Hubert...\");\n }\n\n const client = await createStorageClient(options.storageSelection);\n\n // Fetch the Round 2 request from where we're listening\n const requestEnvelope = await getWithIndicator(\n client,\n listeningAtArid,\n \"Round 2 request\",\n options.timeoutSeconds,\n options.verbose ?? false,\n );\n\n if (requestEnvelope === null || requestEnvelope === undefined) {\n throw new Error(\"Round 2 request not found in Hubert storage\");\n }\n\n // Decrypt and validate the request\n const ownerPrivateKeys = owner.xidDocument().inceptionPrivateKeys();\n if (ownerPrivateKeys === undefined) {\n throw new Error(\"Owner XID document has no private keys\");\n }\n\n const now = CborDate.now().datetime();\n const sealedRequest = SealedRequest.tryFromEnvelope(\n requestEnvelope,\n undefined,\n now,\n ownerPrivateKeys,\n );\n\n // Validate the request and extract response ARID\n const expectedCoordinator = groupRecord.coordinator().xid();\n const responseArid = validateRound2Request(sealedRequest, groupId, expectedCoordinator);\n\n // Extract Round 1 packages from the request\n const [round1Packages, round1PackagesByXid] = extractRound1Packages(\n sealedRequest,\n groupRecord,\n owner.xid(),\n );\n\n if (isVerbose() || options.verbose === true) {\n console.error(`Received ${round1Packages.size} Round 1 packages. Running DKG part2...`);\n }\n\n // Allocate next response ARID for the finalize phase\n const nextResponseArid = ARID.new();\n\n // Run FROST DKG part2\n // Convert Map<Identifier, Package> to Map<string, Package> for dkgPart2\n const round1PackagesHex = new Map<string, DkgRound1Package>();\n for (const [id, pkg] of round1Packages) {\n round1PackagesHex.set(identifierToHex(id), pkg);\n }\n\n const [round2Secret, round2Packages] = dkgPart2(round1State.secretPackage, round1PackagesHex);\n\n if (isVerbose() || options.verbose === true) {\n console.error(`Generated ${round2Packages.size} Round 2 packages.`);\n }\n\n // Convert round2Packages back to use Identifier keys for buildResponseBody\n const round2PackagesById = new Map<FrostIdentifier, unknown>();\n for (const [idHex, pkg] of round2Packages) {\n // Find the identifier that matches this hex\n for (const [id] of round1Packages) {\n if (identifierToHex(id) === idHex) {\n round2PackagesById.set(id, pkg);\n break;\n }\n }\n }\n\n // Build response with Round 2 packages\n const responseBody = buildResponseBody(\n groupId,\n owner.xid(),\n nextResponseArid,\n round2PackagesById,\n groupRecord,\n );\n\n const signerPrivateKeys = owner.xidDocument().inceptionPrivateKeys();\n if (signerPrivateKeys === undefined) {\n throw new Error(\"Owner XID document has no signing keys\");\n }\n\n // Get coordinator's XID document for encryption\n const coordinatorXid = groupRecord.coordinator().xid();\n const coordinatorRecord = registry.participant(coordinatorXid);\n let coordinatorDoc: XIDDocument;\n if (coordinatorRecord !== undefined) {\n coordinatorDoc = coordinatorRecord.xidDocument();\n } else {\n // Check if coordinator is the owner\n if (owner.xid().urString() === coordinatorXid.urString()) {\n coordinatorDoc = owner.xidDocument();\n } else {\n throw new Error(`Coordinator ${coordinatorXid.urString()} not found in registry`);\n }\n }\n\n // Get peer continuation from the request\n const peerContinuation = sealedRequest.peerContinuation();\n\n let sealed = SealedResponse.newSuccess(sealedRequest.id(), owner.xidDocument()).withResult(\n responseBody,\n );\n\n if (peerContinuation !== undefined) {\n sealed = sealed.withPeerContinuation(peerContinuation);\n }\n\n if (options.preview === true) {\n // Show the response envelope structure without encryption\n const unsealedEnvelope = sealed.toEnvelope(\n undefined, // No expiration for responses\n signerPrivateKeys,\n undefined,\n );\n const envelopeUr = unsealedEnvelope.urString();\n console.log(envelopeUr);\n\n return {\n listeningArid: nextResponseArid.urString(),\n envelopeUr,\n };\n }\n\n // Calculate participant index for serialization. Sort by XID byte\n // order (mirrors Rust `XID::cmp`) so the 1-indexed position matches\n // what the coordinator used when assigning FROST identifiers. The\n // earlier port sorted by UR string via `Array.sort()` (default JS\n // string compare), which diverges from Rust byte order for any\n // byte ≥ 0x80.\n const sortedParticipantXids: XID[] = groupRecord.participants().map((p) => p.xid());\n const ownerXid = owner.xid();\n const ownerXidStr = ownerXid.urString();\n if (!sortedParticipantXids.some((x) => x.urString() === ownerXidStr)) {\n sortedParticipantXids.push(ownerXid);\n }\n sortedParticipantXids.sort((a, b) => compareXidBytes(a.toData(), b.toData()));\n const participantIndex = sortedParticipantXids.findIndex((x) => x.urString() === ownerXidStr) + 1; // 1-indexed\n\n // Persist Round 2 secret and collected round1 packages\n const round2SecretPath = persistRound2State(\n registryPath,\n groupId,\n round2Secret,\n round1PackagesByXid,\n participantIndex,\n );\n\n const responseEnvelope = sealed.toEnvelope(\n undefined, // No expiration for responses\n signerPrivateKeys,\n coordinatorDoc,\n );\n\n // Post the response\n await putWithIndicator(\n client,\n responseArid,\n responseEnvelope,\n \"Round 2 Response\",\n options.verbose ?? false,\n );\n\n // Update contributions in registry\n const updatedGroupRecord = registry.group(groupId);\n if (updatedGroupRecord !== undefined) {\n const contributions = updatedGroupRecord.contributions();\n contributions.round2Secret = round2SecretPath;\n updatedGroupRecord.setContributions(contributions);\n // Set new listening ARID for finalize phase\n updatedGroupRecord.setListeningAtArid(nextResponseArid);\n registry.save(registryPath);\n }\n\n if (isVerbose() || options.verbose === true) {\n console.error(`Posted Round 2 response to ${responseArid.urString()}`);\n }\n\n return {\n listeningArid: nextResponseArid.urString(),\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"round2-DhdFarwY.cjs","names":["groupStateDir","path","fs","Ed25519Sha512","hexToBytes","VerifiableSecretSharingCommitment","CoefficientCommitment","identifierFromU16","round1","serde","EnvelopeFunction","ARID","compareXidBytes","XID","JSONWrapper","identifierToHex","Envelope","serializeDkgRound2Package","bytesToHex","resolveRegistryPath","Registry","parseAridUr","isVerbose","createStorageClient","getWithIndicator","CborDate","SealedRequest","dkgPart2","SealedResponse","putWithIndicator"],"sources":["../src/cmd/dkg/participant/round2.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n *\n * DKG participant round 2 command.\n *\n * Port of cmd/dkg/participant/round2.rs from frost-hubert-rust.\n *\n * @module\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { ARID, JSON as JSONWrapper, XID } from \"@bcts/components\";\nimport { compareXidBytes } from \"../../../dkg/proposed-participant.js\";\nimport { CborDate } from \"@bcts/dcbor\";\nimport { Envelope, Function as EnvelopeFunction } from \"@bcts/envelope\";\nimport { SealedRequest, SealedResponse } from \"@bcts/gstp\";\nimport type { XIDDocument } from \"@bcts/xid\";\n\nimport { type GroupRecord, Registry, resolveRegistryPath } from \"../../../registry/index.js\";\nimport { getWithIndicator, putWithIndicator } from \"../../busy.js\";\nimport { groupStateDir, isVerbose } from \"../../common.js\";\nimport { createStorageClient, type StorageClient, type StorageSelection } from \"../../storage.js\";\nimport { parseAridUr } from \"../common.js\";\nimport {\n dkgPart2,\n serializeDkgRound2Package,\n identifierFromU16,\n identifierToHex,\n hexToBytes,\n bytesToHex,\n type DkgRound1Package,\n type DkgRound1SecretPackage,\n type DkgRound2SecretPackage,\n type FrostIdentifier,\n} from \"../../../frost/index.js\";\nimport { Ed25519Sha512, serde } from \"@frosts/ed25519\";\nimport { round1, CoefficientCommitment, VerifiableSecretSharingCommitment } from \"@frosts/core\";\n\n/**\n * Options for the DKG round2 command.\n */\nexport interface DkgRound2Options {\n registryPath?: string;\n groupId: string;\n timeoutSeconds?: number;\n preview?: boolean;\n storageSelection?: StorageSelection;\n verbose?: boolean;\n}\n\n/**\n * Result of the DKG round2 command.\n */\nexport interface DkgRound2Result {\n listeningArid: string;\n envelopeUr?: string;\n}\n\n/**\n * Persisted round 1 state loaded from disk.\n */\ninterface Round1State {\n secretPackage: DkgRound1SecretPackage;\n ourRound1Package: DkgRound1Package;\n}\n\n/**\n * Extracted round 1 packages from coordinator request.\n */\ntype Round1Packages = [Map<FrostIdentifier, DkgRound1Package>, [XID, DkgRound1Package][]];\n\n/**\n * Load persisted round 1 state from disk.\n *\n * Port of round1_secret loading from cmd/dkg/participant/round2.rs lines 86-97.\n */\nfunction loadRound1State(registryPath: string, groupId: ARID): Round1State {\n const packagesDir = groupStateDir(registryPath, groupId.hex());\n const round1SecretPath = path.join(packagesDir, \"round1_secret.json\");\n\n if (!fs.existsSync(round1SecretPath)) {\n throw new Error(\n `Round 1 secret not found at ${round1SecretPath}. Did you respond to the invite?`,\n );\n }\n\n // Mirrors Rust `frost::keys::dkg::round1::SecretPackage` JSON\n // (`frost-rust/frost-core/src/keys/dkg.rs:120-139`): no `header`,\n // snake_case `min_signers` / `max_signers`, identifier and\n // coefficients as lowercase hex strings, commitment as a flat array\n // of hex strings.\n const secretJson = JSON.parse(fs.readFileSync(round1SecretPath, \"utf-8\")) as {\n identifier: string;\n coefficients: string[];\n commitment: string[];\n min_signers: number;\n max_signers: number;\n };\n\n // Deserialize coefficients (scalars)\n const coefficients = secretJson.coefficients.map((hex) =>\n Ed25519Sha512.deserializeScalar(hexToBytes(hex)),\n );\n\n // Deserialize commitment (coefficient commitments)\n const coefficientCommitments = secretJson.commitment.map((hex) =>\n CoefficientCommitment.deserialize(Ed25519Sha512, hexToBytes(hex)),\n );\n\n const commitment = new VerifiableSecretSharingCommitment(Ed25519Sha512, coefficientCommitments);\n\n // Create the secret package\n // Need to find the actual identifier u16 value from the coefficients array length or saved state\n // The identifier is typically serialized as a scalar, but we need the u16 value\n // Parse it from the hex string - first 2 bytes as little-endian u16\n const idBytes = hexToBytes(secretJson.identifier);\n let identifierU16 = 1;\n if (idBytes.length >= 2) {\n identifierU16 = idBytes[0] | (idBytes[1] << 8);\n }\n if (identifierU16 === 0) {\n identifierU16 = 1; // Default to 1 if parsing failed\n }\n\n const parsedIdentifier = identifierFromU16(identifierU16);\n\n const secretPackage: DkgRound1SecretPackage = new round1.SecretPackage(\n Ed25519Sha512,\n parsedIdentifier,\n coefficients,\n commitment,\n secretJson.min_signers,\n secretJson.max_signers,\n );\n\n // Load the round 1 package as well\n const round1PackagePath = path.join(packagesDir, \"round1_package.json\");\n const packageJson = JSON.parse(fs.readFileSync(round1PackagePath, \"utf-8\")) as {\n header: { version: number; ciphersuite: string };\n commitment: string[];\n proof_of_knowledge: string;\n };\n\n const ourRound1Package = serde.round1PackageFromJson(packageJson);\n\n return { secretPackage, ourRound1Package };\n}\n\n/**\n * Validate the round 2 request from the coordinator.\n *\n * Port of request validation from cmd/dkg/participant/round2.rs lines 118-158.\n */\nfunction validateRound2Request(\n sealedRequest: SealedRequest,\n groupId: ARID,\n expectedCoordinator: XID,\n): ARID {\n // Validate the request function\n if (!sealedRequest.function().equals(EnvelopeFunction.fromString(\"dkgRound2\"))) {\n throw new Error(`Unexpected request function: ${sealedRequest.function().toString()}`);\n }\n\n // Validate the sender is the expected coordinator\n if (sealedRequest.sender().xid().urString() !== expectedCoordinator.urString()) {\n throw new Error(\n `Unexpected request sender: ${sealedRequest.sender().xid().urString()} ` +\n `(expected coordinator ${expectedCoordinator.urString()})`,\n );\n }\n\n // Validate the group ID matches\n const requestGroupIdEnvelope = sealedRequest.objectForParameter(\"group\");\n if (requestGroupIdEnvelope === undefined) {\n throw new Error(\"Request missing group parameter\");\n }\n const requestGroupId = requestGroupIdEnvelope.extractSubject((cbor) => ARID.fromTaggedCbor(cbor));\n if (requestGroupId.urString() !== groupId.urString()) {\n throw new Error(\n `Request group ID ${requestGroupId.urString()} does not match expected ${groupId.urString()}`,\n );\n }\n\n // Extract where we should post our response\n const responseAridEnvelope = sealedRequest.objectForParameter(\"responseArid\");\n if (responseAridEnvelope === undefined) {\n throw new Error(\"Request missing responseArid parameter\");\n }\n const responseArid = responseAridEnvelope.extractSubject((cbor) => ARID.fromTaggedCbor(cbor));\n\n return responseArid;\n}\n\n/**\n * Extract round 1 packages from the request and convert to Map<Identifier, Package>.\n *\n * Port of `extract_round1_packages()` from cmd/dkg/participant/round2.rs lines 291-366.\n */\nfunction extractRound1Packages(\n request: SealedRequest,\n groupRecord: GroupRecord,\n ownerXid: XID,\n): Round1Packages {\n // Build XID -> Identifier mapping based on sorted participant order\n const sortedXids: XID[] = groupRecord.participants().map((p) => p.xid());\n\n // Add owner if not already in list\n const ownerUrString = ownerXid.urString();\n if (!sortedXids.some((xid) => xid.urString() === ownerUrString)) {\n sortedXids.push(ownerXid);\n }\n\n // Sort by XID byte order — mirrors Rust `XID::cmp` (raw 32-byte\n // lex compare). The earlier port used `urString().localeCompare(...)`,\n // which differs from byte order for any byte ≥ 0x80 and is locale-\n // aware, producing different FROST identifier assignments than Rust.\n sortedXids.sort((a, b) => compareXidBytes(a.toData(), b.toData()));\n\n // Deduplicate\n const deduped: XID[] = [];\n for (const xid of sortedXids) {\n if (deduped.length === 0 || deduped[deduped.length - 1].urString() !== xid.urString()) {\n deduped.push(xid);\n }\n }\n\n // Build XID -> Identifier mapping (1-indexed)\n const xidToIdentifier = new Map<string, FrostIdentifier>();\n for (let i = 0; i < deduped.length; i++) {\n const identifier = identifierFromU16(i + 1);\n xidToIdentifier.set(deduped[i].urString(), identifier);\n }\n\n const myXidStr = ownerXid.urString();\n\n // Extract all round1Package parameters\n const packages = new Map<FrostIdentifier, DkgRound1Package>();\n const packagesByXid: [XID, DkgRound1Package][] = [];\n\n const packageEnvelopes = request.objectsForParameter(\"round1Package\");\n for (const packageEnvelope of packageEnvelopes) {\n // Extract participant XID from the envelope\n const participantEnvelope = packageEnvelope.objectForPredicate(\"participant\");\n if (participantEnvelope === undefined) {\n throw new Error(\"round1Package missing participant predicate\");\n }\n const participantXid = participantEnvelope.extractSubject((cbor) => XID.fromTaggedCbor(cbor));\n\n // Skip our own package\n if (participantXid.urString() === myXidStr) {\n continue;\n }\n\n // Extract the package bytes (stored as JSON tag)\n const packageJson = packageEnvelope.extractSubject((cbor) => JSONWrapper.fromTaggedCbor(cbor));\n const packageData = JSON.parse(new TextDecoder().decode(packageJson.toData())) as {\n header: { version: number; ciphersuite: string };\n commitment: string[];\n proof_of_knowledge: string;\n };\n\n const pkg = serde.round1PackageFromJson(packageData);\n\n // Get the identifier for this participant\n const identifier = xidToIdentifier.get(participantXid.urString());\n if (identifier === undefined) {\n throw new Error(`Unknown participant XID in round1Package: ${participantXid.urString()}`);\n }\n\n packages.set(identifier, pkg);\n packagesByXid.push([participantXid, pkg]);\n }\n\n // Validate we have the expected number of packages\n const expectedPackages = xidToIdentifier.size - 1; // Exclude ourselves\n if (packages.size !== expectedPackages) {\n throw new Error(`Expected ${expectedPackages} Round 1 packages, found ${packages.size}`);\n }\n\n return [packages, packagesByXid];\n}\n\n/**\n * Build the response body containing Round 2 packages.\n *\n * Port of `build_response_body()` from cmd/dkg/participant/round2.rs lines 373-425.\n */\nfunction buildResponseBody(\n groupId: ARID,\n participantXid: XID,\n responseArid: ARID,\n round2Packages: Map<FrostIdentifier, unknown>,\n groupRecord: GroupRecord,\n): Envelope {\n // Build Identifier -> XID mapping\n const sortedXids: XID[] = groupRecord.participants().map((p) => p.xid());\n\n // Add participant if not already in list\n const participantUrString = participantXid.urString();\n if (!sortedXids.some((xid) => xid.urString() === participantUrString)) {\n sortedXids.push(participantXid);\n }\n\n // Sort by XID byte order — mirrors Rust `XID::cmp` (raw 32-byte\n // lex compare). The earlier port used `urString().localeCompare(...)`,\n // which differs from byte order for any byte ≥ 0x80 and is locale-\n // aware, producing different FROST identifier assignments than Rust.\n sortedXids.sort((a, b) => compareXidBytes(a.toData(), b.toData()));\n\n // Deduplicate\n const deduped: XID[] = [];\n for (const xid of sortedXids) {\n if (deduped.length === 0 || deduped[deduped.length - 1].urString() !== xid.urString()) {\n deduped.push(xid);\n }\n }\n\n // Build Identifier -> XID mapping (1-indexed)\n const identifierToXid = new Map<string, XID>();\n for (let i = 0; i < deduped.length; i++) {\n const identifier = identifierFromU16(i + 1);\n identifierToXid.set(identifierToHex(identifier), deduped[i]);\n }\n\n let envelope = Envelope.unit()\n .addType(\"dkgRound2Response\")\n .addAssertion(\"group\", groupId)\n .addAssertion(\"participant\", participantXid)\n .addAssertion(\"response_arid\", responseArid);\n\n // Add each Round 2 package with the recipient's XID\n for (const [identifier, pkg] of round2Packages) {\n const idHex = identifierToHex(identifier);\n const recipientXid = identifierToXid.get(idHex);\n if (recipientXid === undefined) {\n throw new Error(\"Unknown identifier in round2_packages\");\n }\n\n // Serialize package to JSON and wrap in CBOR JSON tag\n const serialized = serializeDkgRound2Package(\n pkg as Parameters<typeof serializeDkgRound2Package>[0],\n );\n const jsonStr = JSON.stringify(serialized);\n const jsonBytes = new TextEncoder().encode(jsonStr);\n const jsonWrapper = JSONWrapper.fromData(jsonBytes);\n\n const packageEnvelope = Envelope.new(jsonWrapper).addAssertion(\"recipient\", recipientXid);\n\n envelope = envelope.addAssertion(\"round2Package\", packageEnvelope);\n }\n\n return envelope;\n}\n\n/**\n * Serialize round 2 secret package to JSON format for persistence.\n *\n * Mirrors the on-disk shape produced by Rust\n * `serde_json::to_vec_pretty(&frost::keys::dkg::round2::SecretPackage)`\n * (see `frost-rust/frost-core/src/keys/dkg.rs:269-287`):\n *\n * ```json\n * {\n * \"identifier\": \"<lowercase hex scalar>\",\n * \"commitment\": [\"<hex>\", \"<hex>\", ...],\n * \"secret_share\": \"<hex>\",\n * \"min_signers\": <u16>,\n * \"max_signers\": <u16>\n * }\n * ```\n *\n * `frost::keys::dkg::round2::SecretPackage` is\n * `#[serde(deny_unknown_fields)]`. The earlier port emitted\n * camelCase keys (`secretShare`, `minSigners`, `maxSigners`), a\n * nested `commitment.coefficients` shape, and a numeric\n * `identifier` — all of which Rust's standard derive would\n * reject and which had no chance of round-tripping with Rust.\n *\n * `participantIndex` is unused now that the identifier comes\n * directly from `secret.identifier.serialize()`; we keep it in the\n * signature for source-level parity with the call sites.\n */\nfunction serializeRound2SecretPackage(\n secret: DkgRound2SecretPackage,\n _participantIndex: number,\n): Record<string, unknown> {\n const commitment = secret.commitment;\n const commitmentCoefficients = commitment.serialize().map((c: Uint8Array) => bytesToHex(c));\n const secretShare = bytesToHex(Ed25519Sha512.serializeScalar(secret.secretShare()));\n\n return {\n identifier: bytesToHex(secret.identifier.serialize()),\n commitment: commitmentCoefficients,\n secret_share: secretShare,\n min_signers: secret.minSigners,\n max_signers: secret.maxSigners,\n };\n}\n\n/**\n * Persist round 2 state to disk.\n *\n * Port of round 2 secret persistence from cmd/dkg/participant/round2.rs lines 229-251.\n */\nfunction persistRound2State(\n registryPath: string,\n groupId: ARID,\n round2Secret: DkgRound2SecretPackage,\n round1PackagesByXid: [XID, DkgRound1Package][],\n participantIndex: number,\n): string {\n const packagesDir = groupStateDir(registryPath, groupId.hex());\n fs.mkdirSync(packagesDir, { recursive: true });\n\n // Persist Round 2 secret\n const round2SecretPath = path.join(packagesDir, \"round2_secret.json\");\n const round2SecretJson = serializeRound2SecretPackage(round2Secret, participantIndex);\n fs.writeFileSync(round2SecretPath, JSON.stringify(round2SecretJson, null, 2));\n\n // Persist received Round 1 packages for finalize phase\n const round1PackagesPath = path.join(packagesDir, \"collected_round1.json\");\n const round1Json: Record<string, unknown> = {};\n for (const [xid, pkg] of round1PackagesByXid) {\n const packageJson = serde.round1PackageToJson(pkg);\n round1Json[xid.urString()] = packageJson;\n }\n fs.writeFileSync(round1PackagesPath, JSON.stringify(round1Json, null, 2));\n\n return round2SecretPath;\n}\n\n/**\n * Execute the DKG participant round 2 command.\n *\n * Responds to the Round 2 request from the coordinator, runs FROST DKG part2\n * to generate Round 2 packages, and posts the response back.\n *\n * Port of `CommandArgs::exec()` from cmd/dkg/participant/round2.rs lines 55-288.\n */\nexport async function round2(\n _client: StorageClient | undefined,\n options: DkgRound2Options,\n cwd: string,\n): Promise<DkgRound2Result> {\n if (options.storageSelection === undefined) {\n throw new Error(\"Hubert storage is required for round2\");\n }\n\n const registryPath = resolveRegistryPath(options.registryPath, cwd);\n const registry = Registry.load(registryPath);\n\n const owner = registry.owner();\n if (owner === undefined) {\n throw new Error(\"Registry owner is required\");\n }\n\n const groupId = parseAridUr(options.groupId);\n const groupRecord = registry.group(groupId);\n if (groupRecord === undefined) {\n throw new Error(\"Group not found in registry\");\n }\n\n // Get the ARID where we're listening for the Round 2 request\n const listeningAtArid = groupRecord.listeningAtArid();\n if (listeningAtArid === undefined) {\n throw new Error(\"No listening ARID for this group. Did you respond to the invite?\");\n }\n\n // Load our Round 1 secret\n const round1State = loadRound1State(registryPath, groupId);\n\n if (isVerbose() || options.verbose === true) {\n console.error(\"Fetching Round 2 request from Hubert...\");\n }\n\n const client = await createStorageClient(options.storageSelection);\n\n // Fetch the Round 2 request from where we're listening\n const requestEnvelope = await getWithIndicator(\n client,\n listeningAtArid,\n \"Round 2 request\",\n options.timeoutSeconds,\n options.verbose ?? false,\n );\n\n if (requestEnvelope === null || requestEnvelope === undefined) {\n throw new Error(\"Round 2 request not found in Hubert storage\");\n }\n\n // Decrypt and validate the request\n const ownerPrivateKeys = owner.xidDocument().inceptionPrivateKeys();\n if (ownerPrivateKeys === undefined) {\n throw new Error(\"Owner XID document has no private keys\");\n }\n\n const now = CborDate.now().datetime();\n const sealedRequest = SealedRequest.tryFromEnvelope(\n requestEnvelope,\n undefined,\n now,\n ownerPrivateKeys,\n );\n\n // Validate the request and extract response ARID\n const expectedCoordinator = groupRecord.coordinator().xid();\n const responseArid = validateRound2Request(sealedRequest, groupId, expectedCoordinator);\n\n // Extract Round 1 packages from the request\n const [round1Packages, round1PackagesByXid] = extractRound1Packages(\n sealedRequest,\n groupRecord,\n owner.xid(),\n );\n\n if (isVerbose() || options.verbose === true) {\n console.error(`Received ${round1Packages.size} Round 1 packages. Running DKG part2...`);\n }\n\n // Allocate next response ARID for the finalize phase\n const nextResponseArid = ARID.new();\n\n // Run FROST DKG part2\n // Convert Map<Identifier, Package> to Map<string, Package> for dkgPart2\n const round1PackagesHex = new Map<string, DkgRound1Package>();\n for (const [id, pkg] of round1Packages) {\n round1PackagesHex.set(identifierToHex(id), pkg);\n }\n\n const [round2Secret, round2Packages] = dkgPart2(round1State.secretPackage, round1PackagesHex);\n\n if (isVerbose() || options.verbose === true) {\n console.error(`Generated ${round2Packages.size} Round 2 packages.`);\n }\n\n // Convert round2Packages back to use Identifier keys for buildResponseBody\n const round2PackagesById = new Map<FrostIdentifier, unknown>();\n for (const [idHex, pkg] of round2Packages) {\n // Find the identifier that matches this hex\n for (const [id] of round1Packages) {\n if (identifierToHex(id) === idHex) {\n round2PackagesById.set(id, pkg);\n break;\n }\n }\n }\n\n // Build response with Round 2 packages\n const responseBody = buildResponseBody(\n groupId,\n owner.xid(),\n nextResponseArid,\n round2PackagesById,\n groupRecord,\n );\n\n const signerPrivateKeys = owner.xidDocument().inceptionPrivateKeys();\n if (signerPrivateKeys === undefined) {\n throw new Error(\"Owner XID document has no signing keys\");\n }\n\n // Get coordinator's XID document for encryption\n const coordinatorXid = groupRecord.coordinator().xid();\n const coordinatorRecord = registry.participant(coordinatorXid);\n let coordinatorDoc: XIDDocument;\n if (coordinatorRecord !== undefined) {\n coordinatorDoc = coordinatorRecord.xidDocument();\n } else {\n // Check if coordinator is the owner\n if (owner.xid().urString() === coordinatorXid.urString()) {\n coordinatorDoc = owner.xidDocument();\n } else {\n throw new Error(`Coordinator ${coordinatorXid.urString()} not found in registry`);\n }\n }\n\n // Get peer continuation from the request\n const peerContinuation = sealedRequest.peerContinuation();\n\n let sealed = SealedResponse.newSuccess(sealedRequest.id(), owner.xidDocument()).withResult(\n responseBody,\n );\n\n if (peerContinuation !== undefined) {\n sealed = sealed.withPeerContinuation(peerContinuation);\n }\n\n if (options.preview === true) {\n // Show the response envelope structure without encryption\n const unsealedEnvelope = sealed.toEnvelope(\n undefined, // No expiration for responses\n signerPrivateKeys,\n undefined,\n );\n const envelopeUr = unsealedEnvelope.urString();\n console.log(envelopeUr);\n\n return {\n listeningArid: nextResponseArid.urString(),\n envelopeUr,\n };\n }\n\n // Calculate participant index for serialization. Sort by XID byte\n // order (mirrors Rust `XID::cmp`) so the 1-indexed position matches\n // what the coordinator used when assigning FROST identifiers. The\n // earlier port sorted by UR string via `Array.sort()` (default JS\n // string compare), which diverges from Rust byte order for any\n // byte ≥ 0x80.\n const sortedParticipantXids: XID[] = groupRecord.participants().map((p) => p.xid());\n const ownerXid = owner.xid();\n const ownerXidStr = ownerXid.urString();\n if (!sortedParticipantXids.some((x) => x.urString() === ownerXidStr)) {\n sortedParticipantXids.push(ownerXid);\n }\n sortedParticipantXids.sort((a, b) => compareXidBytes(a.toData(), b.toData()));\n const participantIndex = sortedParticipantXids.findIndex((x) => x.urString() === ownerXidStr) + 1; // 1-indexed\n\n // Persist Round 2 secret and collected round1 packages\n const round2SecretPath = persistRound2State(\n registryPath,\n groupId,\n round2Secret,\n round1PackagesByXid,\n participantIndex,\n );\n\n const responseEnvelope = sealed.toEnvelope(\n undefined, // No expiration for responses\n signerPrivateKeys,\n coordinatorDoc,\n );\n\n // Post the response\n await putWithIndicator(\n client,\n responseArid,\n responseEnvelope,\n \"Round 2 Response\",\n options.verbose ?? false,\n );\n\n // Update contributions in registry\n const updatedGroupRecord = registry.group(groupId);\n if (updatedGroupRecord !== undefined) {\n const contributions = updatedGroupRecord.contributions();\n contributions.round2Secret = round2SecretPath;\n updatedGroupRecord.setContributions(contributions);\n // Set new listening ARID for finalize phase\n updatedGroupRecord.setListeningAtArid(nextResponseArid);\n registry.save(registryPath);\n }\n\n if (isVerbose() || options.verbose === true) {\n console.error(`Posted Round 2 response to ${responseArid.urString()}`);\n }\n\n return {\n listeningArid: nextResponseArid.urString(),\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { t as __exportAll } from "./
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-z9aeyW2b.mjs";
|
|
2
2
|
import { n as compareXidBytes } from "./proposed-participant-Detb823_.mjs";
|
|
3
3
|
import { Registry, resolveRegistryPath } from "./registry/index.mjs";
|
|
4
|
-
import { c as parseAridUr, h as signingKeyFromVerifying } from "./common-
|
|
4
|
+
import { c as parseAridUr, h as signingKeyFromVerifying } from "./common-4spC1kNw.mjs";
|
|
5
5
|
import { n as putWithIndicator } from "./busy-BlU8_pS2.mjs";
|
|
6
6
|
import { f as parallelFetch, m as parallelSend } from "./parallel-PZiwHZT8.mjs";
|
|
7
7
|
import { aggregateSignatures, createSigningPackage, deserializePublicKeyPackage, deserializeSignatureShare, deserializeSigningCommitments, identifierFromU16, serializeSignature, serializeSignatureShare } from "./frost/index.mjs";
|
|
8
|
-
import { n as signingStateDir, t as SignFinalizeContent } from "./common
|
|
8
|
+
import { n as signingStateDir, t as SignFinalizeContent } from "./common--IfAHVkl.mjs";
|
|
9
9
|
import { ARID, JSON as JSON$1, Signature, XID } from "@bcts/components";
|
|
10
10
|
import { Envelope } from "@bcts/envelope";
|
|
11
11
|
import * as fs from "node:fs";
|
|
@@ -394,4 +394,4 @@ async function round2(client, options, cwd) {
|
|
|
394
394
|
//#endregion
|
|
395
395
|
export { round2_exports as n, round2 as t };
|
|
396
396
|
|
|
397
|
-
//# sourceMappingURL=round2-
|
|
397
|
+
//# sourceMappingURL=round2-DmQvJDVj.mjs.map
|