@cello-protocol/client 0.0.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/agent-hash-queue.d.ts +206 -0
- package/dist/agent-hash-queue.d.ts.map +1 -0
- package/dist/agent-hash-queue.js +380 -0
- package/dist/agent-hash-queue.js.map +1 -0
- package/dist/backup-key-derivation.d.ts +37 -0
- package/dist/backup-key-derivation.d.ts.map +1 -0
- package/dist/backup-key-derivation.js +48 -0
- package/dist/backup-key-derivation.js.map +1 -0
- package/dist/client-backup.d.ts +144 -0
- package/dist/client-backup.d.ts.map +1 -0
- package/dist/client-backup.js +273 -0
- package/dist/client-backup.js.map +1 -0
- package/dist/client.d.ts +249 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +4664 -0
- package/dist/client.js.map +1 -0
- package/dist/connection-policy.d.ts +163 -0
- package/dist/connection-policy.d.ts.map +1 -0
- package/dist/connection-policy.js +248 -0
- package/dist/connection-policy.js.map +1 -0
- package/dist/db-key-derivation.d.ts +26 -0
- package/dist/db-key-derivation.d.ts.map +1 -0
- package/dist/db-key-derivation.js +37 -0
- package/dist/db-key-derivation.js.map +1 -0
- package/dist/encrypted-file-signing-key-provider.d.ts +92 -0
- package/dist/encrypted-file-signing-key-provider.d.ts.map +1 -0
- package/dist/encrypted-file-signing-key-provider.js +251 -0
- package/dist/encrypted-file-signing-key-provider.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server.d.ts +270 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +1155 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/network-directory-node.d.ts +85 -0
- package/dist/network-directory-node.d.ts.map +1 -0
- package/dist/network-directory-node.js +584 -0
- package/dist/network-directory-node.js.map +1 -0
- package/dist/s3-cloud-storage-provider.d.ts +54 -0
- package/dist/s3-cloud-storage-provider.d.ts.map +1 -0
- package/dist/s3-cloud-storage-provider.js +78 -0
- package/dist/s3-cloud-storage-provider.js.map +1 -0
- package/dist/sqlcipher-client-store.d.ts +68 -0
- package/dist/sqlcipher-client-store.d.ts.map +1 -0
- package/dist/sqlcipher-client-store.js +382 -0
- package/dist/sqlcipher-client-store.js.map +1 -0
- package/dist/types.d.ts +408 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,584 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NetworkDirectoryNode — DirectoryNodeStub backed by a real libp2p connection.
|
|
3
|
+
*
|
|
4
|
+
* Implements the DirectoryNodeStub interface by dialing the directory node's
|
|
5
|
+
* /cello/frost/1.0.0 endpoint. Used in live e2e mode instead of InProcessDirectoryNodeStub.
|
|
6
|
+
*
|
|
7
|
+
* Wire protocol (one stream per operation, CBOR + it-length-prefixed):
|
|
8
|
+
* frost_bootstrap: push share material to directory (called from bootstrapKeyShares)
|
|
9
|
+
* frost_commit_request: ask directory to generate a nonce commitment
|
|
10
|
+
* frost_sign_request: ask directory to compute a partial signature
|
|
11
|
+
*/
|
|
12
|
+
import { Encoder, decode as cborDecode } from "cbor-x";
|
|
13
|
+
import * as lp from "it-length-prefixed";
|
|
14
|
+
import { ed25519_FROST, FrostThresholdSigner } from "@cello-protocol/crypto";
|
|
15
|
+
import { bootstrapKeyShares, storeDkgResult } from "@cello-protocol/crypto/frost/frost-threshold-signer.js";
|
|
16
|
+
const FROST_PROTOCOL_ID = "/cello/frost/1.0.0";
|
|
17
|
+
const CBOR_ENC = new Encoder({ tagUint8Array: false });
|
|
18
|
+
// ─── NetworkDirectoryNode ─────────────────────────────────────────────────────
|
|
19
|
+
export class NetworkDirectoryNode {
|
|
20
|
+
id;
|
|
21
|
+
#node;
|
|
22
|
+
#directoryPeerId;
|
|
23
|
+
#directoryMultiaddrs;
|
|
24
|
+
// Set during bootstrapKeyShares — used to identify which agent's share to retrieve
|
|
25
|
+
#agentPubkeyHex = null;
|
|
26
|
+
#epochId = null;
|
|
27
|
+
// Stored during receiveShare — used by tests to get the FrostPublic for signRound calls
|
|
28
|
+
#lastPub = null;
|
|
29
|
+
constructor(opts) {
|
|
30
|
+
this.id = opts.id;
|
|
31
|
+
this.#node = opts.node;
|
|
32
|
+
this.#directoryPeerId = opts.directoryPeerId;
|
|
33
|
+
this.#directoryMultiaddrs = opts.directoryMultiaddrs;
|
|
34
|
+
}
|
|
35
|
+
isReachable() {
|
|
36
|
+
// For the network path, optimistically return true at pre-ceremony check time.
|
|
37
|
+
// Actual reachability is discovered during generateCommitment/signRound.
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
/** Return the FrostPublic from the last receiveShare call. Used by tests to construct signRound params. */
|
|
41
|
+
getLastPub() {
|
|
42
|
+
return this.#lastPub;
|
|
43
|
+
}
|
|
44
|
+
async receiveShare(...[secret, pub]) {
|
|
45
|
+
this.#lastPub = pub;
|
|
46
|
+
if (!this.#agentPubkeyHex || !this.#epochId) {
|
|
47
|
+
throw new Error("NetworkDirectoryNode: setBootstrapContext must be called before receiveShare");
|
|
48
|
+
}
|
|
49
|
+
// Serialize FrostSecret: { identifier, signingShare }
|
|
50
|
+
const secretSerialized = {
|
|
51
|
+
identifier: secret.identifier,
|
|
52
|
+
signingShare: secret.signingShare,
|
|
53
|
+
};
|
|
54
|
+
// Serialize FrostPublic: { signers, commitments[], verifyingShares{} }
|
|
55
|
+
const pubSerialized = {
|
|
56
|
+
signers: pub.signers,
|
|
57
|
+
commitments: pub.commitments,
|
|
58
|
+
verifyingShares: pub.verifyingShares,
|
|
59
|
+
};
|
|
60
|
+
const frame = CBOR_ENC.encode({
|
|
61
|
+
type: "frost_bootstrap",
|
|
62
|
+
agentPubkey: this.#agentPubkeyHex,
|
|
63
|
+
epochId: this.#epochId,
|
|
64
|
+
secret: secretSerialized.signingShare,
|
|
65
|
+
identifier: secretSerialized.identifier,
|
|
66
|
+
commitments: pubSerialized.commitments,
|
|
67
|
+
verifyingShares: pubSerialized.verifyingShares,
|
|
68
|
+
signers: pubSerialized.signers,
|
|
69
|
+
});
|
|
70
|
+
const stream = await this.#openStream();
|
|
71
|
+
try {
|
|
72
|
+
stream.send(lp.encode.single(frame));
|
|
73
|
+
// Read the response before closing — directory sends frost_bootstrap_ok
|
|
74
|
+
for await (const chunk of lp.decode(stream)) {
|
|
75
|
+
const bytes = chunk instanceof Uint8Array ? chunk : chunk.slice();
|
|
76
|
+
const resp = cborDecode(bytes);
|
|
77
|
+
if (resp.type !== "frost_bootstrap_ok") {
|
|
78
|
+
throw new Error(`NetworkDirectoryNode: unexpected bootstrap response: ${resp.type}`);
|
|
79
|
+
}
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
finally {
|
|
84
|
+
stream.close().catch(() => { });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async generateCommitment() {
|
|
88
|
+
if (!this.#agentPubkeyHex || !this.#epochId) {
|
|
89
|
+
throw new Error("NetworkDirectoryNode: setBootstrapContext must be called before generateCommitment");
|
|
90
|
+
}
|
|
91
|
+
const frame = CBOR_ENC.encode({
|
|
92
|
+
type: "frost_commit_request",
|
|
93
|
+
agentPubkey: this.#agentPubkeyHex,
|
|
94
|
+
epochId: this.#epochId,
|
|
95
|
+
peerIdString: this.#node.getPeerId(),
|
|
96
|
+
});
|
|
97
|
+
const stream = await this.#openStream();
|
|
98
|
+
try {
|
|
99
|
+
stream.send(lp.encode.single(frame));
|
|
100
|
+
await stream.close();
|
|
101
|
+
for await (const chunk of lp.decode(stream)) {
|
|
102
|
+
const bytes = chunk instanceof Uint8Array ? chunk : chunk.slice();
|
|
103
|
+
const resp = cborDecode(bytes);
|
|
104
|
+
if (!resp.ok) {
|
|
105
|
+
throw new Error(`NetworkDirectoryNode: commit request failed: ${resp.reason}`);
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
nodeId: resp.nodeId,
|
|
109
|
+
nonceCommitment: resp.nonceCommitment,
|
|
110
|
+
nonces: null,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
stream.close().catch(() => { });
|
|
116
|
+
}
|
|
117
|
+
throw new Error("NetworkDirectoryNode: no response to frost_commit_request");
|
|
118
|
+
}
|
|
119
|
+
async signRound(params) {
|
|
120
|
+
if (!this.#agentPubkeyHex || !this.#epochId) {
|
|
121
|
+
throw new Error("NetworkDirectoryNode: setBootstrapContext must be called before signRound");
|
|
122
|
+
}
|
|
123
|
+
const frame = CBOR_ENC.encode({
|
|
124
|
+
type: "frost_sign_request",
|
|
125
|
+
agentPubkey: this.#agentPubkeyHex,
|
|
126
|
+
epochId: this.#epochId,
|
|
127
|
+
framedMsg: params.msg, // already framed (context\0tbs) by the coordinator
|
|
128
|
+
commitmentList: params.commitmentList,
|
|
129
|
+
ceremonyId: params.ceremonyId,
|
|
130
|
+
// Use ceremonyId as peerIdString to match directory's markInFlight registration
|
|
131
|
+
peerIdString: params.ceremonyId,
|
|
132
|
+
});
|
|
133
|
+
const stream = await this.#openStream();
|
|
134
|
+
try {
|
|
135
|
+
stream.send(lp.encode.single(frame));
|
|
136
|
+
await stream.close();
|
|
137
|
+
for await (const chunk of lp.decode(stream)) {
|
|
138
|
+
const bytes = chunk instanceof Uint8Array ? chunk : chunk.slice();
|
|
139
|
+
const resp = cborDecode(bytes);
|
|
140
|
+
if (!resp.ok) {
|
|
141
|
+
return null; // treat as timeout — coordinator will exclude this node
|
|
142
|
+
}
|
|
143
|
+
const sig = resp.partialSignature;
|
|
144
|
+
if (!sig)
|
|
145
|
+
return null;
|
|
146
|
+
return sig instanceof Uint8Array ? sig : new Uint8Array(sig);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
finally {
|
|
150
|
+
stream.close().catch(() => { });
|
|
151
|
+
}
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
// Called by the network-aware bootstrapKeyShares before distributing shares
|
|
155
|
+
setBootstrapContext(agentPubkeyHex, epochId) {
|
|
156
|
+
this.#agentPubkeyHex = agentPubkeyHex;
|
|
157
|
+
this.#epochId = epochId;
|
|
158
|
+
}
|
|
159
|
+
/** Open a /cello/frost/1.0.0 stream to this directory node. Used by DKG coordinator. */
|
|
160
|
+
async openStream() {
|
|
161
|
+
return this.#openStream();
|
|
162
|
+
}
|
|
163
|
+
async #openStream() {
|
|
164
|
+
// Ensure we have a connection to the directory node
|
|
165
|
+
try {
|
|
166
|
+
return await this.#node.newStream(this.#directoryPeerId, FROST_PROTOCOL_ID);
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
// Try dialing first if not connected
|
|
170
|
+
await this.#node.dial(this.#directoryMultiaddrs[0]);
|
|
171
|
+
return await this.#node.newStream(this.#directoryPeerId, FROST_PROTOCOL_ID);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// ─── DKG round methods on NetworkDirectoryNode ───────────────────────────────
|
|
176
|
+
// These methods are used by runNetworkDkg to execute the 3 DKG rounds
|
|
177
|
+
// over /cello/frost/1.0.0 streams. They are internal to the DKG coordinator flow.
|
|
178
|
+
/**
|
|
179
|
+
* Run DKG round 1 with this directory node.
|
|
180
|
+
* Opens a new stream, sends frost_dkg_round1_request, returns the broadcast.
|
|
181
|
+
*/
|
|
182
|
+
async function dkgRound1WithNode(node, agentPubkeyHex, epochId, signers, preAuthToken) {
|
|
183
|
+
const frame = CBOR_ENC.encode({
|
|
184
|
+
type: "frost_dkg_round1_request",
|
|
185
|
+
agentPubkey: agentPubkeyHex,
|
|
186
|
+
epochId,
|
|
187
|
+
signers,
|
|
188
|
+
// OPS-AGENT-001: include preAuthToken when present (mandatory in M6+)
|
|
189
|
+
...(preAuthToken !== undefined ? { preAuthToken } : {}),
|
|
190
|
+
});
|
|
191
|
+
const stream = await node.openStream();
|
|
192
|
+
try {
|
|
193
|
+
stream.send(lp.encode.single(frame));
|
|
194
|
+
for await (const chunk of lp.decode(stream)) {
|
|
195
|
+
const bytes = chunk instanceof Uint8Array ? chunk : chunk.slice();
|
|
196
|
+
const parsed = parseDkgRound1Response(bytes);
|
|
197
|
+
if (parsed.kind === "invalid")
|
|
198
|
+
throw new Error("dkgRound1: invalid response");
|
|
199
|
+
if (parsed.kind === "preauth_error")
|
|
200
|
+
throw new Error(`dkgRound1 rejected: ${parsed.reason}`);
|
|
201
|
+
const resp = parsed.response;
|
|
202
|
+
if (!resp.ok)
|
|
203
|
+
throw new Error(`dkgRound1 failed: ${resp.reason}`);
|
|
204
|
+
return resp.broadcast;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
finally {
|
|
208
|
+
stream.close().catch(() => { });
|
|
209
|
+
}
|
|
210
|
+
throw new Error("dkgRound1: no response received");
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Run DKG round 2 with this directory node.
|
|
214
|
+
* Opens a new stream, sends frost_dkg_round2_request, returns sharesForOthers.
|
|
215
|
+
*/
|
|
216
|
+
async function dkgRound2WithNode(node, agentPubkeyHex, epochId, othersRound1) {
|
|
217
|
+
const frame = CBOR_ENC.encode({
|
|
218
|
+
type: "frost_dkg_round2_request",
|
|
219
|
+
agentPubkey: agentPubkeyHex,
|
|
220
|
+
epochId,
|
|
221
|
+
othersRound1: othersRound1.map((b) => ({
|
|
222
|
+
identifier: b.identifier,
|
|
223
|
+
commitment: b.commitment,
|
|
224
|
+
proofOfKnowledge: b.proofOfKnowledge,
|
|
225
|
+
})),
|
|
226
|
+
});
|
|
227
|
+
const stream = await node.openStream();
|
|
228
|
+
try {
|
|
229
|
+
stream.send(lp.encode.single(frame));
|
|
230
|
+
for await (const chunk of lp.decode(stream)) {
|
|
231
|
+
const bytes = chunk instanceof Uint8Array ? chunk : chunk.slice();
|
|
232
|
+
const resp = parseDkgRound2Response(bytes);
|
|
233
|
+
if (!resp)
|
|
234
|
+
throw new Error("dkgRound2: invalid response");
|
|
235
|
+
if (!resp.ok)
|
|
236
|
+
throw new Error(`dkgRound2 failed: ${resp.reason}`);
|
|
237
|
+
return resp.sharesForOthers;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
finally {
|
|
241
|
+
stream.close().catch(() => { });
|
|
242
|
+
}
|
|
243
|
+
throw new Error("dkgRound2: no response received");
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Run DKG round 3 with this directory node.
|
|
247
|
+
* Opens a new stream, sends frost_dkg_round3_request, returns shareCommitment.
|
|
248
|
+
*/
|
|
249
|
+
async function dkgRound3WithNode(node, agentPubkeyHex, epochId, sharesForMe, allRound1) {
|
|
250
|
+
const frame = CBOR_ENC.encode({
|
|
251
|
+
type: "frost_dkg_round3_request",
|
|
252
|
+
agentPubkey: agentPubkeyHex,
|
|
253
|
+
epochId,
|
|
254
|
+
sharesForMe: sharesForMe.map((s) => ({
|
|
255
|
+
identifier: s.signerIdentifier,
|
|
256
|
+
targetIdentifier: s.targetIdentifier,
|
|
257
|
+
signingShare: s.signingShare,
|
|
258
|
+
})),
|
|
259
|
+
allOthersRound1: allRound1.map((b) => ({
|
|
260
|
+
identifier: b.identifier,
|
|
261
|
+
commitment: b.commitment,
|
|
262
|
+
proofOfKnowledge: b.proofOfKnowledge,
|
|
263
|
+
})),
|
|
264
|
+
});
|
|
265
|
+
const stream = await node.openStream();
|
|
266
|
+
try {
|
|
267
|
+
stream.send(lp.encode.single(frame));
|
|
268
|
+
for await (const chunk of lp.decode(stream)) {
|
|
269
|
+
const bytes = chunk instanceof Uint8Array ? chunk : chunk.slice();
|
|
270
|
+
const resp = parseDkgRound3Response(bytes);
|
|
271
|
+
if (!resp)
|
|
272
|
+
throw new Error("dkgRound3: invalid response");
|
|
273
|
+
if (!resp.ok)
|
|
274
|
+
throw new Error(`dkgRound3 failed: ${resp.reason}`);
|
|
275
|
+
return resp.shareCommitment;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
finally {
|
|
279
|
+
stream.close().catch(() => { });
|
|
280
|
+
}
|
|
281
|
+
throw new Error("dkgRound3: no response received");
|
|
282
|
+
}
|
|
283
|
+
function parseDkgRound1Response(bytes) {
|
|
284
|
+
let obj;
|
|
285
|
+
try {
|
|
286
|
+
obj = cborDecode(bytes);
|
|
287
|
+
}
|
|
288
|
+
catch {
|
|
289
|
+
return { kind: "invalid" };
|
|
290
|
+
}
|
|
291
|
+
if (typeof obj !== "object" || obj === null)
|
|
292
|
+
return { kind: "invalid" };
|
|
293
|
+
const o = obj;
|
|
294
|
+
// Handle preauth_error frames from the directory (CRIT-1: previously silently dropped)
|
|
295
|
+
if (o["type"] === "preauth_error") {
|
|
296
|
+
const reason = typeof o["reason"] === "string" ? o["reason"] : "PRE_AUTH_TOKEN_MISSING";
|
|
297
|
+
return { kind: "preauth_error", reason };
|
|
298
|
+
}
|
|
299
|
+
if (o["type"] !== "frost_dkg_round1_response")
|
|
300
|
+
return { kind: "invalid" };
|
|
301
|
+
if (o["ok"] === true) {
|
|
302
|
+
const raw = o["broadcast"];
|
|
303
|
+
if (typeof raw !== "object" || raw === null)
|
|
304
|
+
return { kind: "invalid" };
|
|
305
|
+
const b = raw;
|
|
306
|
+
const identifier = typeof b["identifier"] === "string" ? b["identifier"] : null;
|
|
307
|
+
const proofOfKnowledge = toU8(b["proofOfKnowledge"]);
|
|
308
|
+
const commitment = parseU8Array(b["commitment"]);
|
|
309
|
+
if (!identifier || !proofOfKnowledge || !commitment)
|
|
310
|
+
return { kind: "invalid" };
|
|
311
|
+
return { kind: "response", response: { type: "frost_dkg_round1_response", ok: true, broadcast: { identifier, commitment, proofOfKnowledge } } };
|
|
312
|
+
}
|
|
313
|
+
const reason = o["reason"];
|
|
314
|
+
if (reason !== "already_in_progress" && reason !== "internal_error")
|
|
315
|
+
return { kind: "invalid" };
|
|
316
|
+
return { kind: "response", response: { type: "frost_dkg_round1_response", ok: false, reason } };
|
|
317
|
+
}
|
|
318
|
+
function parseDkgRound2Response(bytes) {
|
|
319
|
+
let obj;
|
|
320
|
+
try {
|
|
321
|
+
obj = cborDecode(bytes);
|
|
322
|
+
}
|
|
323
|
+
catch {
|
|
324
|
+
return null;
|
|
325
|
+
}
|
|
326
|
+
if (typeof obj !== "object" || obj === null)
|
|
327
|
+
return null;
|
|
328
|
+
const o = obj;
|
|
329
|
+
if (o["type"] !== "frost_dkg_round2_response")
|
|
330
|
+
return null;
|
|
331
|
+
if (o["ok"] === true) {
|
|
332
|
+
const rawShares = o["sharesForOthers"];
|
|
333
|
+
if (!Array.isArray(rawShares))
|
|
334
|
+
return null;
|
|
335
|
+
const sharesForOthers = [];
|
|
336
|
+
for (const item of rawShares) {
|
|
337
|
+
if (typeof item !== "object" || item === null)
|
|
338
|
+
return null;
|
|
339
|
+
const s = item;
|
|
340
|
+
// Accept both "signerIdentifier" (protocol-types canonical) and "identifier" (new wire)
|
|
341
|
+
const signerIdentifier = typeof s["signerIdentifier"] === "string" ? s["signerIdentifier"] :
|
|
342
|
+
typeof s["identifier"] === "string" ? s["identifier"] : null;
|
|
343
|
+
const targetIdentifier = typeof s["targetIdentifier"] === "string" ? s["targetIdentifier"] : null;
|
|
344
|
+
const signingShare = toU8(s["signingShare"]);
|
|
345
|
+
if (!signerIdentifier || !targetIdentifier || !signingShare)
|
|
346
|
+
return null;
|
|
347
|
+
sharesForOthers.push({ signerIdentifier, targetIdentifier, signingShare });
|
|
348
|
+
}
|
|
349
|
+
return { type: "frost_dkg_round2_response", ok: true, sharesForOthers };
|
|
350
|
+
}
|
|
351
|
+
const reason = o["reason"];
|
|
352
|
+
if (reason !== "round1_not_complete" && reason !== "verification_failed" && reason !== "internal_error")
|
|
353
|
+
return null;
|
|
354
|
+
return { type: "frost_dkg_round2_response", ok: false, reason };
|
|
355
|
+
}
|
|
356
|
+
function parseDkgRound3Response(bytes) {
|
|
357
|
+
let obj;
|
|
358
|
+
try {
|
|
359
|
+
obj = cborDecode(bytes);
|
|
360
|
+
}
|
|
361
|
+
catch {
|
|
362
|
+
return null;
|
|
363
|
+
}
|
|
364
|
+
if (typeof obj !== "object" || obj === null)
|
|
365
|
+
return null;
|
|
366
|
+
const o = obj;
|
|
367
|
+
if (o["type"] !== "frost_dkg_round3_response")
|
|
368
|
+
return null;
|
|
369
|
+
if (o["ok"] === true) {
|
|
370
|
+
const sc = o["shareCommitment"];
|
|
371
|
+
// shareCommitment comes as raw bytes (CBOR-encoded Uint8Array)
|
|
372
|
+
const shareCommitment = typeof sc === "string"
|
|
373
|
+
? new Uint8Array(Buffer.from(sc, "hex"))
|
|
374
|
+
: sc instanceof Uint8Array ? sc
|
|
375
|
+
: Buffer.isBuffer(sc) ? new Uint8Array(sc)
|
|
376
|
+
: null;
|
|
377
|
+
if (!shareCommitment || shareCommitment.length !== 32)
|
|
378
|
+
return null;
|
|
379
|
+
return { type: "frost_dkg_round3_response", ok: true, shareCommitment };
|
|
380
|
+
}
|
|
381
|
+
const reason = o["reason"];
|
|
382
|
+
if (reason !== "round2_not_complete" && reason !== "share_verification_failed" && reason !== "internal_error")
|
|
383
|
+
return null;
|
|
384
|
+
return { type: "frost_dkg_round3_response", ok: false, reason };
|
|
385
|
+
}
|
|
386
|
+
function toU8(v) {
|
|
387
|
+
if (v instanceof Uint8Array)
|
|
388
|
+
return v;
|
|
389
|
+
if (Buffer.isBuffer(v))
|
|
390
|
+
return new Uint8Array(v);
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
393
|
+
function parseU8Array(v) {
|
|
394
|
+
if (!Array.isArray(v))
|
|
395
|
+
return null;
|
|
396
|
+
const result = [];
|
|
397
|
+
for (const item of v) {
|
|
398
|
+
const b = toU8(item);
|
|
399
|
+
if (!b)
|
|
400
|
+
return null;
|
|
401
|
+
result.push(b);
|
|
402
|
+
}
|
|
403
|
+
return result;
|
|
404
|
+
}
|
|
405
|
+
// ─── bootstrapNetworkKeyShares ────────────────────────────────────────────────
|
|
406
|
+
/**
|
|
407
|
+
* Network-aware FROST bootstrap for live e2e mode.
|
|
408
|
+
*
|
|
409
|
+
* Runs trustedDealer locally, then pushes each directory node's share over the
|
|
410
|
+
* /cello/frost/1.0.0 network protocol. Returns a FrostThresholdSigner configured
|
|
411
|
+
* to use NetworkDirectoryNodes, plus the primaryPubkey.
|
|
412
|
+
*
|
|
413
|
+
* NODE_ENV=test guard is kept because this still uses the trustedDealer shortcut.
|
|
414
|
+
* Real DKG (M3) will replace this entirely.
|
|
415
|
+
*/
|
|
416
|
+
export async function bootstrapNetworkKeyShares(agentPubkey, opts) {
|
|
417
|
+
// bootstrapKeyShares uses trustedDealer — a test-harness shortcut, not real DKG (M3+).
|
|
418
|
+
// This function inherits that constraint. The caller (cello-mcp.ts) guards with NODE_ENV=test.
|
|
419
|
+
if (process.env.NODE_ENV !== "test") {
|
|
420
|
+
throw new Error("bootstrapNetworkKeyShares uses trustedDealer which is test-only. Real DKG (M3) required in production.");
|
|
421
|
+
}
|
|
422
|
+
const agentPubkeyHex = Buffer.from(agentPubkey).toString("hex");
|
|
423
|
+
const epochId = `${agentPubkeyHex}:epoch:1`;
|
|
424
|
+
// Set context on all nodes so receiveShare knows which agent/epoch to use
|
|
425
|
+
for (const node of opts.directoryNodes) {
|
|
426
|
+
node.setBootstrapContext(agentPubkeyHex, epochId);
|
|
427
|
+
}
|
|
428
|
+
// bootstrapKeyShares runs trustedDealer and calls node.receiveShare() on each node.
|
|
429
|
+
// For NetworkDirectoryNode, receiveShare() sends the share over the network.
|
|
430
|
+
const result = await bootstrapKeyShares(agentPubkey, {
|
|
431
|
+
threshold: opts.threshold,
|
|
432
|
+
participants: opts.participants,
|
|
433
|
+
directoryNodeStubs: opts.directoryNodes,
|
|
434
|
+
});
|
|
435
|
+
const signer = new FrostThresholdSigner({
|
|
436
|
+
threshold: opts.threshold,
|
|
437
|
+
participants: opts.participants,
|
|
438
|
+
directoryNodeStubs: opts.directoryNodes,
|
|
439
|
+
}, agentPubkey);
|
|
440
|
+
return { signer, primaryPubkey: result.primaryPubkey };
|
|
441
|
+
}
|
|
442
|
+
// ─── runNetworkDkg ─────────────────────────────────────────────────────────────
|
|
443
|
+
/**
|
|
444
|
+
* Run a real 3-round FROST DKG ceremony with directory nodes over /cello/frost/1.0.0.
|
|
445
|
+
*
|
|
446
|
+
* Production path for key establishment. The client acts as DKG coordinator:
|
|
447
|
+
* Round 1: All nodes generate their secret polynomials. Client does the same.
|
|
448
|
+
* Round 2: Client collects all round1 broadcasts and distributes them to all nodes.
|
|
449
|
+
* All nodes compute shares for every other participant.
|
|
450
|
+
* Round 3: Client routes round2 shares to recipients and all nodes finalize.
|
|
451
|
+
* All nodes return shareCommitment = group public key.
|
|
452
|
+
*
|
|
453
|
+
* Validates that all nodes derive the same primary_pubkey before returning.
|
|
454
|
+
*
|
|
455
|
+
* After a successful DKG:
|
|
456
|
+
* - Each directory node has its FrostSecret stored (via dkgRound3)
|
|
457
|
+
* - The client's local share is stored via storeDkgResult
|
|
458
|
+
* - Returns a FrostThresholdSigner for future signing ceremonies
|
|
459
|
+
*
|
|
460
|
+
* Crypto reference: RFC 9591 (FROST DKG)
|
|
461
|
+
*
|
|
462
|
+
* @param agentPubkey - client's Ed25519 K_local public key (32 bytes)
|
|
463
|
+
* @param opts.threshold - minimum signers required (t in t-of-n)
|
|
464
|
+
* @param opts.directoryNodes - the n directory nodes (each will hold a share)
|
|
465
|
+
*/
|
|
466
|
+
export async function runNetworkDkg(agentPubkey, opts) {
|
|
467
|
+
const agentPubkeyHex = Buffer.from(agentPubkey).toString("hex");
|
|
468
|
+
// Client identifier: same derivation as used in bootstrapKeyShares for consistency
|
|
469
|
+
const clientIdStr = `client:${agentPubkeyHex}`;
|
|
470
|
+
const clientIdentifier = ed25519_FROST.Identifier.derive(clientIdStr);
|
|
471
|
+
const epochId = `${agentPubkeyHex}:epoch:1`;
|
|
472
|
+
// Total participants = directory nodes + 1 (client)
|
|
473
|
+
// threshold is the signing threshold (t-of-n where n = directoryNodes.length + 1)
|
|
474
|
+
const signers = { min: opts.threshold, max: opts.participants + 1 };
|
|
475
|
+
// ─── Round 1 ────────────────────────────────────────────────────────────────
|
|
476
|
+
// Client runs DKG.round1 locally; all directory nodes run round1 via streams.
|
|
477
|
+
// RFC 9591 §5.1
|
|
478
|
+
const clientR1 = ed25519_FROST.DKG.round1(clientIdentifier, signers);
|
|
479
|
+
const clientRound1Broadcast = {
|
|
480
|
+
identifier: clientR1.public.identifier,
|
|
481
|
+
commitment: clientR1.public.commitment.map((c) => new Uint8Array(c)),
|
|
482
|
+
proofOfKnowledge: new Uint8Array(clientR1.public.proofOfKnowledge),
|
|
483
|
+
};
|
|
484
|
+
// Directory nodes run round1 in parallel
|
|
485
|
+
const nodeRound1Broadcasts = await Promise.all(opts.directoryNodes.map((node) => dkgRound1WithNode(node, agentPubkeyHex, epochId, signers, opts.preAuthToken)));
|
|
486
|
+
// allRound1 = client + all directory node broadcasts
|
|
487
|
+
const allRound1 = [clientRound1Broadcast, ...nodeRound1Broadcasts];
|
|
488
|
+
// ─── Round 2 ────────────────────────────────────────────────────────────────
|
|
489
|
+
// Client runs DKG.round2 locally (receives others' round1 → generates shares for others).
|
|
490
|
+
// All directory nodes run round2 in parallel.
|
|
491
|
+
// RFC 9591 §5.2
|
|
492
|
+
// For the client, othersRound1 = all directory nodes' broadcasts
|
|
493
|
+
const clientOthersRound1 = nodeRound1Broadcasts.map((b) => ({
|
|
494
|
+
identifier: b.identifier,
|
|
495
|
+
commitment: b.commitment.map((c) => new Uint8Array(c)),
|
|
496
|
+
proofOfKnowledge: new Uint8Array(b.proofOfKnowledge),
|
|
497
|
+
}));
|
|
498
|
+
const clientR2 = ed25519_FROST.DKG.round2(clientR1.secret, clientOthersRound1);
|
|
499
|
+
// For each directory node, othersRound1 = all other participants EXCEPT that node itself
|
|
500
|
+
const nodeRound2Results = await Promise.all(opts.directoryNodes.map((node, i) => {
|
|
501
|
+
// Each node receives round1 from everyone EXCEPT itself
|
|
502
|
+
const othersForNode = allRound1.filter((_, j) => j !== i + 1 // i+1 because index 0 is the client
|
|
503
|
+
);
|
|
504
|
+
return dkgRound2WithNode(node, agentPubkeyHex, epochId, othersForNode);
|
|
505
|
+
}));
|
|
506
|
+
// ─── Route round2 shares ─────────────────────────────────────────────────────
|
|
507
|
+
// Collect all shares (client-generated + node-generated), route to recipients.
|
|
508
|
+
// Each participant needs shares from all OTHER participants.
|
|
509
|
+
// sharesForClient: shares where targetIdentifier === clientIdentifier
|
|
510
|
+
// sharesForNode[i]: shares where targetIdentifier === nodeRound1Broadcasts[i].identifier
|
|
511
|
+
// Build a map: targetIdentifier → accumulated DkgRound2Share[]
|
|
512
|
+
const sharesForAll = new Map();
|
|
513
|
+
// Add client's shares (for each directory node)
|
|
514
|
+
const clientSharesRecord = clientR2;
|
|
515
|
+
for (const [targetId, share] of Object.entries(clientSharesRecord)) {
|
|
516
|
+
const shares = sharesForAll.get(targetId) ?? [];
|
|
517
|
+
shares.push({
|
|
518
|
+
signerIdentifier: clientIdentifier,
|
|
519
|
+
targetIdentifier: targetId,
|
|
520
|
+
signingShare: new Uint8Array(share.signingShare),
|
|
521
|
+
});
|
|
522
|
+
sharesForAll.set(targetId, shares);
|
|
523
|
+
}
|
|
524
|
+
// Add directory node shares (for client and other directory nodes)
|
|
525
|
+
for (const nodeShares of nodeRound2Results) {
|
|
526
|
+
for (const share of nodeShares) {
|
|
527
|
+
const shares = sharesForAll.get(share.targetIdentifier) ?? [];
|
|
528
|
+
shares.push(share);
|
|
529
|
+
sharesForAll.set(share.targetIdentifier, shares);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
// ─── Round 3 ────────────────────────────────────────────────────────────────
|
|
533
|
+
// Client runs DKG.round3 locally.
|
|
534
|
+
// All directory nodes run round3 in parallel.
|
|
535
|
+
// RFC 9591 §5.3
|
|
536
|
+
// Client's round3: receives shares addressed to clientIdentifier
|
|
537
|
+
const clientSharesForMe = (sharesForAll.get(clientIdentifier) ?? []).map((s) => ({
|
|
538
|
+
identifier: s.signerIdentifier, // SENDER's identifier (for round3 matching)
|
|
539
|
+
signingShare: new Uint8Array(s.signingShare),
|
|
540
|
+
}));
|
|
541
|
+
const clientKey = ed25519_FROST.DKG.round3(clientR1.secret, clientOthersRound1, clientSharesForMe);
|
|
542
|
+
// Directory nodes' round3: parallel
|
|
543
|
+
const nodeCommitments = await Promise.all(opts.directoryNodes.map((node, i) => {
|
|
544
|
+
const nodeId = nodeRound1Broadcasts[i].identifier;
|
|
545
|
+
const nodeSharesForMe = sharesForAll.get(nodeId) ?? [];
|
|
546
|
+
const allOthersForNode = allRound1.filter((_, j) => j !== i + 1);
|
|
547
|
+
return dkgRound3WithNode(node, agentPubkeyHex, epochId, nodeSharesForMe, allOthersForNode);
|
|
548
|
+
}));
|
|
549
|
+
// ─── Verify all nodes agree on primary_pubkey ─────────────────────────────
|
|
550
|
+
const primaryPubkey = new Uint8Array(clientKey.public.commitments[0]);
|
|
551
|
+
const primaryPubkeyHex = Buffer.from(primaryPubkey).toString("hex");
|
|
552
|
+
for (const nodeCommitment of nodeCommitments) {
|
|
553
|
+
const nodeHex = Buffer.from(nodeCommitment).toString("hex");
|
|
554
|
+
if (nodeHex !== primaryPubkeyHex) {
|
|
555
|
+
// Clean up client secret to avoid leaking state
|
|
556
|
+
try {
|
|
557
|
+
ed25519_FROST.DKG.clean(clientR1.secret);
|
|
558
|
+
}
|
|
559
|
+
catch { /* ignore */ }
|
|
560
|
+
throw new Error(`DKG failed: node commitment ${nodeHex.slice(0, 16)}… does not match client primary_pubkey ${primaryPubkeyHex.slice(0, 16)}…`);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
// ─── Store client's local DKG share ──────────────────────────────────────
|
|
564
|
+
// storeDkgResult is the production key storage path (no NODE_ENV guard).
|
|
565
|
+
storeDkgResult(agentPubkeyHex, clientKey.secret, clientKey.public);
|
|
566
|
+
// Clean up DKG secret now that it's been safely stored
|
|
567
|
+
try {
|
|
568
|
+
ed25519_FROST.DKG.clean(clientR1.secret);
|
|
569
|
+
}
|
|
570
|
+
catch { /* ignore */ }
|
|
571
|
+
// Set signing context on each directory node so generateCommitment/signRound can
|
|
572
|
+
// identify which agent's share to use in future FROST signing ceremonies.
|
|
573
|
+
for (const node of opts.directoryNodes) {
|
|
574
|
+
node.setBootstrapContext(agentPubkeyHex, epochId);
|
|
575
|
+
}
|
|
576
|
+
// ─── Build FrostThresholdSigner ───────────────────────────────────────────
|
|
577
|
+
const signer = new FrostThresholdSigner({
|
|
578
|
+
threshold: opts.threshold,
|
|
579
|
+
participants: opts.participants,
|
|
580
|
+
directoryNodeStubs: opts.directoryNodes,
|
|
581
|
+
}, agentPubkey);
|
|
582
|
+
return { signer, primaryPubkey };
|
|
583
|
+
}
|
|
584
|
+
//# sourceMappingURL=network-directory-node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-directory-node.js","sourceRoot":"","sources":["../src/network-directory-node.ts"],"names":[],"mappings":"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"}
|