@cello-protocol/protocol-types 0.0.20 → 0.0.22
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/cbor.d.ts +5 -0
- package/dist/cbor.d.ts.map +1 -0
- package/dist/cbor.js +31 -0
- package/dist/cbor.js.map +1 -0
- package/dist/connection-package.d.ts +4 -0
- package/dist/connection-package.d.ts.map +1 -1
- package/dist/connection-package.js +5 -6
- package/dist/connection-package.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/limits.d.ts +10 -0
- package/dist/limits.d.ts.map +1 -0
- package/dist/limits.js +10 -0
- package/dist/limits.js.map +1 -0
- package/dist/manifest.d.ts +2 -4
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +2 -4
- package/dist/manifest.js.map +1 -1
- package/dist/primary-transfer.d.ts +5 -7
- package/dist/primary-transfer.d.ts.map +1 -1
- package/dist/primary-transfer.js +7 -12
- package/dist/primary-transfer.js.map +1 -1
- package/dist/revocation.d.ts.map +1 -1
- package/dist/revocation.js +2 -5
- package/dist/revocation.js.map +1 -1
- package/dist/session-liveness.js +4 -4
- package/dist/session-liveness.js.map +1 -1
- package/dist/session.d.ts +26 -61
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +22 -54
- package/dist/session.js.map +1 -1
- package/dist/structure1.d.ts +16 -0
- package/dist/structure1.d.ts.map +1 -0
- package/dist/structure1.js +33 -0
- package/dist/structure1.js.map +1 -0
- package/dist/structure2.d.ts.map +1 -1
- package/dist/structure2.js +7 -8
- package/dist/structure2.js.map +1 -1
- package/package.json +2 -2
- package/dist/envelope.d.ts +0 -170
- package/dist/envelope.d.ts.map +0 -1
- package/dist/envelope.js +0 -776
- package/dist/envelope.js.map +0 -1
package/dist/session.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* session.ts — session wire types and their to-be-signed encodings.
|
|
3
3
|
*
|
|
4
4
|
* SessionAssignment: shared wire type used by directory (sender), client (receiver),
|
|
5
5
|
* and relay (verifier). Lives here so client can import it without touching @cello-protocol/directory.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
* SessionAssignment is a discriminated union on `signature_type`, so TypeScript enforces that
|
|
8
|
+
* `signer_pubkey` is present exactly when the signature is FROST:
|
|
8
9
|
* signature_type: 'frost' | 'single'
|
|
9
10
|
* - 'frost': the directory_signature field carries the 64-byte combined FROST output
|
|
10
|
-
* - 'single':
|
|
11
|
+
* - 'single': legacy single-key directory signature (refused by current clients)
|
|
11
12
|
* signer_pubkey?: Uint8Array (32 bytes, present when signature_type === 'frost')
|
|
12
13
|
* - The initiator's primary_pubkey (group FROST key). Embedded so the counterparty
|
|
13
14
|
* can verify without a separate directory round-trip.
|
|
@@ -19,11 +20,11 @@
|
|
|
19
20
|
* Note: signer_pubkey is NOT in the TBS — it is derived from DKG and embedded in the frame.
|
|
20
21
|
*
|
|
21
22
|
* SealPayload: canonical CBOR of [session_id, final_root, close_timestamp, "PENDING"].
|
|
22
|
-
*
|
|
23
|
+
* content_hash = SHA-256(0x00 || SealPayload).
|
|
23
24
|
*
|
|
24
25
|
* computeGenesisPrevRoot: deterministic genesis prev_root for a two-party session.
|
|
25
26
|
*
|
|
26
|
-
* Formula
|
|
27
|
+
* Formula:
|
|
27
28
|
* SHA-256(min(A_pubkey, B_pubkey) || max(A_pubkey, B_pubkey) || session_id || timestamp_be8)
|
|
28
29
|
*
|
|
29
30
|
* Pubkeys are sorted bytewise-lexicographically (Buffer.compare).
|
|
@@ -31,46 +32,13 @@
|
|
|
31
32
|
* (milliseconds since Unix epoch). Raw byte concatenation — no CBOR at this boundary,
|
|
32
33
|
* which would introduce width ambiguity on the timestamp encoding.
|
|
33
34
|
*
|
|
34
|
-
* Per FIPS 180-4 (SHA-256)
|
|
35
|
+
* Per FIPS 180-4 (SHA-256).
|
|
35
36
|
*
|
|
36
|
-
*
|
|
37
|
+
* buildSessionEstablishmentTbs is exported from protocol-types so that BOTH the directory
|
|
38
|
+
* (signer) and the client (verifier) use identical canonical CBOR encoding. Any encoding
|
|
39
|
+
* drift causes silent verification failures.
|
|
37
40
|
*
|
|
38
|
-
*
|
|
39
|
-
* // Use a discriminated union so TypeScript enforces signer_pubkey is present for 'frost'
|
|
40
|
-
* type SessionAssignmentFrost = { ...common fields..., signature_type: 'frost', signer_pubkey: Uint8Array }
|
|
41
|
-
* type SessionAssignmentSingle = { ...common fields..., signature_type: 'single' }
|
|
42
|
-
* type SessionAssignment = SessionAssignmentFrost | SessionAssignmentSingle
|
|
43
|
-
*
|
|
44
|
-
* // Common fields (all existing SessionAssignment fields plus signature_type + signer_pubkey):
|
|
45
|
-
* session_id, participant_a, participant_b, relay_endpoint, directory_endpoint,
|
|
46
|
-
* session_timestamp, directory_pubkey, directory_signature
|
|
47
|
-
*
|
|
48
|
-
* buildSessionEstablishmentTbs(sessionId, pubA, pubB, genesisPrevRoot, timestamp):
|
|
49
|
-
* // HIGH-5: exported from protocol-types so both directory and client use identical CBOR encoding
|
|
50
|
-
* // Any encoding drift would cause silent verification failures.
|
|
51
|
-
* // TBS = canonical CBOR([session_id, agent_A_pubkey, agent_B_pubkey, genesis_prev_root, timestamp])
|
|
52
|
-
* // Per CONTEXT.md: uses CBOR_ENC.encode() with tagUint8Array: false
|
|
53
|
-
* // timestamp is uint32 or BigInt depending on size (>0xffffffff → BigInt)
|
|
54
|
-
* return CBOR_ENC.encode([sessionId, pubA, pubB, genesisPrevRoot,
|
|
55
|
-
* timestamp > 0xffffffff ? BigInt(timestamp) : timestamp])
|
|
56
|
-
*
|
|
57
|
-
* IMPORTANT-8: Existing test files that build SessionAssignment objects need updating to
|
|
58
|
-
* include signature_type. Files affected (all M1 tests add signature_type: 'single'):
|
|
59
|
-
* - packages/client/src/__tests__/session.test.ts (makeDirectoryAssignment helper)
|
|
60
|
-
* - packages/client/src/__tests__/msg004.test.ts (makeDirectoryAssignment helper)
|
|
61
|
-
* - packages/client/src/__tests__/session003.test.ts (multiple construction sites)
|
|
62
|
-
* - packages/client/src/__tests__/session006.test.ts (makeDirectoryAssignment helper)
|
|
63
|
-
* - packages/e2e-tests/src/__tests__/mcp-002.test.ts (assignment construction)
|
|
64
|
-
* - packages/relay/src/__tests__/relay-node.test.ts (makeAssignment helper)
|
|
65
|
-
* - packages/relay/src/__tests__/relay-incremental.test.ts (makeAssignment helper)
|
|
66
|
-
* - packages/directory/src/directory-frames.ts (decodeOutboundSignalingFrame parser)
|
|
67
|
-
*
|
|
68
|
-
* IMPORTANT-9: ReceiveAssignmentResult in client/src/types.ts needs 'unsupported_signature_type'
|
|
69
|
-
* added to its reason union.
|
|
70
|
-
*
|
|
71
|
-
* ─── End Phase P Pseudocode ───────────────────────────────────────────────────
|
|
72
|
-
*
|
|
73
|
-
* buildSealTbs: FROST TBS for conversation seal (SESSION-005).
|
|
41
|
+
* buildSealTbs: FROST TBS for a conversation seal.
|
|
74
42
|
* FROST TBS fields: [session_id, sealed_root, leaf_count, timestamp]
|
|
75
43
|
* Context string: "cello-frost-seal-v1" (per CONTEXT.md)
|
|
76
44
|
* Both sides (directory as signer, client as verifier) must use the same encoding.
|
|
@@ -103,16 +71,16 @@ interface SessionAssignmentCommon {
|
|
|
103
71
|
transport_mode?: 'direct' | 'relay';
|
|
104
72
|
}
|
|
105
73
|
/**
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
74
|
+
* FROST-signed assignment. `signer_pubkey` is the initiator's group public key
|
|
75
|
+
* (primary_pubkey from DKG / trustedDealer commitments[0]). Embedded so the
|
|
76
|
+
* counterparty can verify without a directory round-trip.
|
|
109
77
|
*/
|
|
110
78
|
export interface SessionAssignmentFrost extends SessionAssignmentCommon {
|
|
111
79
|
signature_type: "frost";
|
|
112
80
|
signer_pubkey: Uint8Array;
|
|
113
81
|
}
|
|
114
82
|
/**
|
|
115
|
-
*
|
|
83
|
+
* Legacy single-key directory signature. Refused by current clients.
|
|
116
84
|
*/
|
|
117
85
|
export interface SessionAssignmentSingle extends SessionAssignmentCommon {
|
|
118
86
|
signature_type: "single";
|
|
@@ -121,8 +89,8 @@ export interface SessionAssignmentSingle extends SessionAssignmentCommon {
|
|
|
121
89
|
* Discriminated union. TypeScript enforces `signer_pubkey` is present only
|
|
122
90
|
* when `signature_type === 'frost'`.
|
|
123
91
|
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
92
|
+
* Only 'frost' is handled. A 'single' assignment is rejected with
|
|
93
|
+
* `unsupported_signature_type`.
|
|
126
94
|
*/
|
|
127
95
|
export type SessionAssignment = SessionAssignmentFrost | SessionAssignmentSingle;
|
|
128
96
|
/**
|
|
@@ -157,7 +125,6 @@ export declare function buildSessionEstablishmentTbs(sessionId: Uint8Array, pubA
|
|
|
157
125
|
/**
|
|
158
126
|
* SEAL control payload carried as the content_bytes of a ctrl leaf.
|
|
159
127
|
* Canonical CBOR encoding: [session_id, final_root, close_timestamp, "PENDING"].
|
|
160
|
-
* Per SESSION-003 behavior spec.
|
|
161
128
|
*/
|
|
162
129
|
export interface SealPayload {
|
|
163
130
|
session_id: Uint8Array;
|
|
@@ -167,7 +134,7 @@ export interface SealPayload {
|
|
|
167
134
|
}
|
|
168
135
|
/**
|
|
169
136
|
* Encode a SealPayload as canonical CBOR: [session_id, final_root, close_timestamp, "PENDING"].
|
|
170
|
-
* Per
|
|
137
|
+
* Per RFC 8949 §4.2.1.
|
|
171
138
|
*/
|
|
172
139
|
export declare function encodeSealPayload(payload: SealPayload): Uint8Array;
|
|
173
140
|
/**
|
|
@@ -195,9 +162,8 @@ export interface SessionAbandoned {
|
|
|
195
162
|
session_id: Uint8Array;
|
|
196
163
|
}
|
|
197
164
|
/**
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
* @deprecated Use SessionSealedFrost instead in M2+.
|
|
165
|
+
* Legacy session_sealed frame (single-key directory signature). Refused by current clients.
|
|
166
|
+
* @deprecated Use SessionSealedFrost.
|
|
201
167
|
*/
|
|
202
168
|
export interface SessionSealedSingle {
|
|
203
169
|
type: "session_sealed";
|
|
@@ -209,8 +175,8 @@ export interface SessionSealedSingle {
|
|
|
209
175
|
legibility?: SealLegibility;
|
|
210
176
|
}
|
|
211
177
|
/**
|
|
212
|
-
*
|
|
213
|
-
*
|
|
178
|
+
* session_sealed frame carrying the FROST-notarized ceremony signature.
|
|
179
|
+
* signature_type is 'frost' when the FROST ceremony completes.
|
|
214
180
|
*/
|
|
215
181
|
export interface SessionSealedFrost {
|
|
216
182
|
type: "session_sealed";
|
|
@@ -223,16 +189,16 @@ export interface SessionSealedFrost {
|
|
|
223
189
|
leaf_count?: number;
|
|
224
190
|
legibility?: SealLegibility;
|
|
225
191
|
}
|
|
226
|
-
/** Discriminated union:
|
|
192
|
+
/** Discriminated union: current senders emit SessionSealedFrost; SessionSealedSingle is the legacy wire format. */
|
|
227
193
|
export type SessionSealed = SessionSealedSingle | SessionSealedFrost;
|
|
228
194
|
/**
|
|
229
195
|
* Per-attestation marker.
|
|
230
196
|
* 'live' — the participant produced their SEAL acknowledgement leaf
|
|
231
197
|
* contemporaneously in this ceremony (full-bilateral / present-party).
|
|
232
198
|
* 'absent' — the participant produced no acknowledgement (counterparty ABSENT;
|
|
233
|
-
*
|
|
234
|
-
* 'recovered' — the acknowledgement was added post-hoc on return (
|
|
235
|
-
* bilateral-upgrade flow
|
|
199
|
+
* set by the unilateral-notarization flow).
|
|
200
|
+
* 'recovered' — the acknowledgement was added post-hoc on return (set by the
|
|
201
|
+
* bilateral-upgrade flow).
|
|
236
202
|
*/
|
|
237
203
|
export type AttestationMode = "live" | "recovered" | "absent";
|
|
238
204
|
/**
|
|
@@ -289,7 +255,6 @@ export interface SessionSealRejected {
|
|
|
289
255
|
/**
|
|
290
256
|
* seal_verified: directory → seal initiator, after all three verification passes pass.
|
|
291
257
|
* Tells the initiator: "I've verified the tree — coordinate the FROST ceremony now."
|
|
292
|
-
* Per SESSION-005 step 4 in the seal ceremony flow.
|
|
293
258
|
*/
|
|
294
259
|
export interface SealVerified {
|
|
295
260
|
type: "seal_verified";
|
package/dist/session.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
|
package/dist/session.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* session.ts — session wire types and their to-be-signed encodings.
|
|
3
3
|
*
|
|
4
4
|
* SessionAssignment: shared wire type used by directory (sender), client (receiver),
|
|
5
5
|
* and relay (verifier). Lives here so client can import it without touching @cello-protocol/directory.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
* SessionAssignment is a discriminated union on `signature_type`, so TypeScript enforces that
|
|
8
|
+
* `signer_pubkey` is present exactly when the signature is FROST:
|
|
8
9
|
* signature_type: 'frost' | 'single'
|
|
9
10
|
* - 'frost': the directory_signature field carries the 64-byte combined FROST output
|
|
10
|
-
* - 'single':
|
|
11
|
+
* - 'single': legacy single-key directory signature (refused by current clients)
|
|
11
12
|
* signer_pubkey?: Uint8Array (32 bytes, present when signature_type === 'frost')
|
|
12
13
|
* - The initiator's primary_pubkey (group FROST key). Embedded so the counterparty
|
|
13
14
|
* can verify without a separate directory round-trip.
|
|
@@ -19,11 +20,11 @@
|
|
|
19
20
|
* Note: signer_pubkey is NOT in the TBS — it is derived from DKG and embedded in the frame.
|
|
20
21
|
*
|
|
21
22
|
* SealPayload: canonical CBOR of [session_id, final_root, close_timestamp, "PENDING"].
|
|
22
|
-
*
|
|
23
|
+
* content_hash = SHA-256(0x00 || SealPayload).
|
|
23
24
|
*
|
|
24
25
|
* computeGenesisPrevRoot: deterministic genesis prev_root for a two-party session.
|
|
25
26
|
*
|
|
26
|
-
* Formula
|
|
27
|
+
* Formula:
|
|
27
28
|
* SHA-256(min(A_pubkey, B_pubkey) || max(A_pubkey, B_pubkey) || session_id || timestamp_be8)
|
|
28
29
|
*
|
|
29
30
|
* Pubkeys are sorted bytewise-lexicographically (Buffer.compare).
|
|
@@ -31,55 +32,22 @@
|
|
|
31
32
|
* (milliseconds since Unix epoch). Raw byte concatenation — no CBOR at this boundary,
|
|
32
33
|
* which would introduce width ambiguity on the timestamp encoding.
|
|
33
34
|
*
|
|
34
|
-
* Per FIPS 180-4 (SHA-256)
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* type SessionAssignmentSingle = { ...common fields..., signature_type: 'single' }
|
|
42
|
-
* type SessionAssignment = SessionAssignmentFrost | SessionAssignmentSingle
|
|
43
|
-
*
|
|
44
|
-
* // Common fields (all existing SessionAssignment fields plus signature_type + signer_pubkey):
|
|
45
|
-
* session_id, participant_a, participant_b, relay_endpoint, directory_endpoint,
|
|
46
|
-
* session_timestamp, directory_pubkey, directory_signature
|
|
47
|
-
*
|
|
48
|
-
* buildSessionEstablishmentTbs(sessionId, pubA, pubB, genesisPrevRoot, timestamp):
|
|
49
|
-
* // HIGH-5: exported from protocol-types so both directory and client use identical CBOR encoding
|
|
50
|
-
* // Any encoding drift would cause silent verification failures.
|
|
51
|
-
* // TBS = canonical CBOR([session_id, agent_A_pubkey, agent_B_pubkey, genesis_prev_root, timestamp])
|
|
52
|
-
* // Per CONTEXT.md: uses CBOR_ENC.encode() with tagUint8Array: false
|
|
53
|
-
* // timestamp is uint32 or BigInt depending on size (>0xffffffff → BigInt)
|
|
54
|
-
* return CBOR_ENC.encode([sessionId, pubA, pubB, genesisPrevRoot,
|
|
55
|
-
* timestamp > 0xffffffff ? BigInt(timestamp) : timestamp])
|
|
56
|
-
*
|
|
57
|
-
* IMPORTANT-8: Existing test files that build SessionAssignment objects need updating to
|
|
58
|
-
* include signature_type. Files affected (all M1 tests add signature_type: 'single'):
|
|
59
|
-
* - packages/client/src/__tests__/session.test.ts (makeDirectoryAssignment helper)
|
|
60
|
-
* - packages/client/src/__tests__/msg004.test.ts (makeDirectoryAssignment helper)
|
|
61
|
-
* - packages/client/src/__tests__/session003.test.ts (multiple construction sites)
|
|
62
|
-
* - packages/client/src/__tests__/session006.test.ts (makeDirectoryAssignment helper)
|
|
63
|
-
* - packages/e2e-tests/src/__tests__/mcp-002.test.ts (assignment construction)
|
|
64
|
-
* - packages/relay/src/__tests__/relay-node.test.ts (makeAssignment helper)
|
|
65
|
-
* - packages/relay/src/__tests__/relay-incremental.test.ts (makeAssignment helper)
|
|
66
|
-
* - packages/directory/src/directory-frames.ts (decodeOutboundSignalingFrame parser)
|
|
67
|
-
*
|
|
68
|
-
* IMPORTANT-9: ReceiveAssignmentResult in client/src/types.ts needs 'unsupported_signature_type'
|
|
69
|
-
* added to its reason union.
|
|
70
|
-
*
|
|
71
|
-
* ─── End Phase P Pseudocode ───────────────────────────────────────────────────
|
|
72
|
-
*
|
|
73
|
-
* buildSealTbs: FROST TBS for conversation seal (SESSION-005).
|
|
35
|
+
* Per FIPS 180-4 (SHA-256).
|
|
36
|
+
*
|
|
37
|
+
* buildSessionEstablishmentTbs is exported from protocol-types so that BOTH the directory
|
|
38
|
+
* (signer) and the client (verifier) use identical canonical CBOR encoding. Any encoding
|
|
39
|
+
* drift causes silent verification failures.
|
|
40
|
+
*
|
|
41
|
+
* buildSealTbs: FROST TBS for a conversation seal.
|
|
74
42
|
* FROST TBS fields: [session_id, sealed_root, leaf_count, timestamp]
|
|
75
43
|
* Context string: "cello-frost-seal-v1" (per CONTEXT.md)
|
|
76
44
|
* Both sides (directory as signer, client as verifier) must use the same encoding.
|
|
77
45
|
* Per RFC 9591 (FROST), RFC 8949 (CBOR canonical), FIPS 180-4 (SHA-256).
|
|
78
46
|
*/
|
|
79
47
|
import { createHash } from "node:crypto";
|
|
80
|
-
import {
|
|
81
|
-
|
|
82
|
-
// ─── Session establishment TBS builder
|
|
48
|
+
import { decode as cborDecode } from "cbor-x";
|
|
49
|
+
import { encodeCbor } from "./cbor.js";
|
|
50
|
+
// ─── Session establishment TBS builder ────────────────────────────────────────
|
|
83
51
|
/**
|
|
84
52
|
* Build the FROST to-be-signed bytes for session establishment.
|
|
85
53
|
*
|
|
@@ -116,7 +84,7 @@ export function buildSessionEstablishmentTbs(sessionId, pubA, pubB, genesisPrevR
|
|
|
116
84
|
counterpartySessionPeerId !== undefined &&
|
|
117
85
|
counterpartySessionAddrs !== undefined &&
|
|
118
86
|
transportMode !== undefined) {
|
|
119
|
-
return
|
|
87
|
+
return encodeCbor([
|
|
120
88
|
sessionId,
|
|
121
89
|
pubA,
|
|
122
90
|
pubB,
|
|
@@ -130,7 +98,7 @@ export function buildSessionEstablishmentTbs(sessionId, pubA, pubB, genesisPrevR
|
|
|
130
98
|
]);
|
|
131
99
|
}
|
|
132
100
|
// Legacy (M1–M6): encode only the original 5 fields
|
|
133
|
-
return
|
|
101
|
+
return encodeCbor([
|
|
134
102
|
sessionId,
|
|
135
103
|
pubA,
|
|
136
104
|
pubB,
|
|
@@ -140,10 +108,10 @@ export function buildSessionEstablishmentTbs(sessionId, pubA, pubB, genesisPrevR
|
|
|
140
108
|
}
|
|
141
109
|
/**
|
|
142
110
|
* Encode a SealPayload as canonical CBOR: [session_id, final_root, close_timestamp, "PENDING"].
|
|
143
|
-
* Per
|
|
111
|
+
* Per RFC 8949 §4.2.1.
|
|
144
112
|
*/
|
|
145
113
|
export function encodeSealPayload(payload) {
|
|
146
|
-
return
|
|
114
|
+
return encodeCbor([
|
|
147
115
|
payload.session_id,
|
|
148
116
|
payload.final_root,
|
|
149
117
|
payload.close_timestamp > 0xffffffff
|
|
@@ -179,7 +147,7 @@ export function decodeSealPayload(bytes) {
|
|
|
179
147
|
return null;
|
|
180
148
|
return { session_id: sid, final_root: root, close_timestamp: ts, attestation: "PENDING" };
|
|
181
149
|
}
|
|
182
|
-
// ─── buildSealTbs
|
|
150
|
+
// ─── buildSealTbs ─────────────────────────────────────────────────────────────
|
|
183
151
|
/**
|
|
184
152
|
* Build the FROST to-be-signed bytes for a conversation seal ceremony.
|
|
185
153
|
*
|
|
@@ -196,7 +164,7 @@ export function decodeSealPayload(bytes) {
|
|
|
196
164
|
* @param timestamp - Unix milliseconds at the time of verification
|
|
197
165
|
*/
|
|
198
166
|
export function buildSealTbs(sessionId, sealedRoot, leafCount, timestamp) {
|
|
199
|
-
return
|
|
167
|
+
return encodeCbor([
|
|
200
168
|
sessionId,
|
|
201
169
|
sealedRoot,
|
|
202
170
|
leafCount,
|
package/dist/session.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** The Structure 1 version tag. Bound as the FIRST field, so a v1 claim can never read as a v2 one. */
|
|
2
|
+
export declare const STRUCTURE1_VERSION = 1;
|
|
3
|
+
/**
|
|
4
|
+
* Canonical Structure 1 bytes: [version, content_hash, sender_pubkey, session_id, last_seen_seq, timestamp].
|
|
5
|
+
*
|
|
6
|
+
* A timestamp above 2^32-1 is encoded as a CBOR bigint — a plain number would silently lose
|
|
7
|
+
* precision, and the sender's signature is over THESE bytes.
|
|
8
|
+
*/
|
|
9
|
+
export declare function encodeStructure1(fields: {
|
|
10
|
+
contentHash: Uint8Array;
|
|
11
|
+
senderPubkey: Uint8Array;
|
|
12
|
+
sessionId: Uint8Array;
|
|
13
|
+
lastSeenSeq: number;
|
|
14
|
+
timestamp: number;
|
|
15
|
+
}): Uint8Array;
|
|
16
|
+
//# sourceMappingURL=structure1.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structure1.d.ts","sourceRoot":"","sources":["../src/structure1.ts"],"names":[],"mappings":"AAcA,uGAAuG;AACvG,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAEpC;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE;IACvC,WAAW,EAAE,UAAU,CAAC;IACxB,YAAY,EAAE,UAAU,CAAC;IACzB,SAAS,EAAE,UAAU,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,UAAU,CAUb"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structure 1 — the sender's signed ordering claim, canonical CBOR.
|
|
3
|
+
*
|
|
4
|
+
* The daemon PARSES Structure 1 (it arrives from the relay, the ordering authority) but does not
|
|
5
|
+
* build one, so this encoder has no production caller. It is kept because it is the only written
|
|
6
|
+
* definition of the Structure 1 FIELD ORDER, and `structure1-canonical.json` is the only vector in
|
|
7
|
+
* either repo pinning the resulting bytes. Delete it and the wire format is defined solely by
|
|
8
|
+
* whatever the relay happens to emit, with nothing to catch a drift.
|
|
9
|
+
*
|
|
10
|
+
* Field order is LOAD-BEARING: it is signed over. Reorder a field and signatures produced by any
|
|
11
|
+
* other implementation stop verifying against ours.
|
|
12
|
+
*/
|
|
13
|
+
import { encodeCbor } from "./cbor.js";
|
|
14
|
+
/** The Structure 1 version tag. Bound as the FIRST field, so a v1 claim can never read as a v2 one. */
|
|
15
|
+
export const STRUCTURE1_VERSION = 1;
|
|
16
|
+
/**
|
|
17
|
+
* Canonical Structure 1 bytes: [version, content_hash, sender_pubkey, session_id, last_seen_seq, timestamp].
|
|
18
|
+
*
|
|
19
|
+
* A timestamp above 2^32-1 is encoded as a CBOR bigint — a plain number would silently lose
|
|
20
|
+
* precision, and the sender's signature is over THESE bytes.
|
|
21
|
+
*/
|
|
22
|
+
export function encodeStructure1(fields) {
|
|
23
|
+
const ts = fields.timestamp > 0xffffffff ? BigInt(fields.timestamp) : fields.timestamp;
|
|
24
|
+
return encodeCbor([
|
|
25
|
+
STRUCTURE1_VERSION,
|
|
26
|
+
fields.contentHash,
|
|
27
|
+
fields.senderPubkey,
|
|
28
|
+
fields.sessionId,
|
|
29
|
+
fields.lastSeenSeq,
|
|
30
|
+
ts,
|
|
31
|
+
]);
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=structure1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structure1.js","sourceRoot":"","sources":["../src/structure1.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,uGAAuG;AACvG,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAEpC;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAMhC;IACC,MAAM,EAAE,GAAG,MAAM,CAAC,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC;IACvF,OAAO,UAAU,CAAC;QAChB,kBAAkB;QAClB,MAAM,CAAC,WAAW;QAClB,MAAM,CAAC,YAAY;QACnB,MAAM,CAAC,SAAS;QAChB,MAAM,CAAC,WAAW;QAClB,EAAE;KACH,CAAC,CAAC;AACL,CAAC"}
|
package/dist/structure2.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"structure2.d.ts","sourceRoot":"","sources":["../src/structure2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"structure2.d.ts","sourceRoot":"","sources":["../src/structure2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAKhD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,IAAI,CAAC;IACZ,OAAO,EAAE,WAAW,CAAC;IACrB,UAAU,EAAE,UAAU,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,UAAU,CAAC;IAC1B,YAAY,EAAE,UAAU,CAAC;IACzB,gBAAgB,EAAE,UAAU,CAAC;IAC7B,WAAW,EAAE,kBAAkB,CAAC;IAChC,SAAS,EAAE,UAAU,CAAC;CACvB;AAED,MAAM,MAAM,qBAAqB,GAC7B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,GACpC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,aAAa,CAAA;CAAE,CAAC;AAIxC,4FAA4F;AAC5F,eAAO,MAAM,oBAAoB,EAAE,kBAIjC,CAAC;AAEH;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,IAAI,UAAU,CAiBrD;AAID;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,eAAe,EAAE,MAAM,EACvB,aAAa,EAAE,UAAU,EACzB,YAAY,EAAE,UAAU,EACxB,gBAAgB,EAAE,UAAU,EAC5B,SAAS,EAAE,UAAU,GACpB,qBAAqB,CAqCvB;AAID;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,UAAU,GAAG,UAAU,CAc3D;AAID;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CACvC,EAAE,EAAE,UAAU,EACd,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,GAAG,MAAM,GACzB,OAAO,CAWT"}
|
package/dist/structure2.js
CHANGED
|
@@ -15,9 +15,8 @@
|
|
|
15
15
|
* This is what the sender signs; verifyStructure2Signature reconstructs it from Structure 2 fields
|
|
16
16
|
* plus the session_id, last_seen_seq, and timestamp carried through the relay path.
|
|
17
17
|
*/
|
|
18
|
-
import {
|
|
18
|
+
import { encodeCbor } from "./cbor.js";
|
|
19
19
|
import { verify } from "@cello-protocol/crypto";
|
|
20
|
-
const CBOR_ENC = new Encoder({ tagUint8Array: false });
|
|
21
20
|
// ─── Sentinel ─────────────────────────────────────────────────────────────────
|
|
22
21
|
/** M1 placeholder scan_result sentinel. The scanner field is stable but unset until M4+. */
|
|
23
22
|
export const SCAN_RESULT_SENTINEL = Object.freeze({
|
|
@@ -102,11 +101,11 @@ export function encodeStructure2(s2) {
|
|
|
102
101
|
// We must embed the pre-encoded sentinel bytes as raw CBOR, not re-encode the object.
|
|
103
102
|
// Construct the 6-element array manually to preserve canonical byte representation.
|
|
104
103
|
const arrayHeader = new Uint8Array([0x86]); // 6-element CBOR array
|
|
105
|
-
const seqBytes =
|
|
106
|
-
const pubBytes =
|
|
107
|
-
const hashBytes =
|
|
108
|
-
const sigBytes =
|
|
109
|
-
const prevBytes =
|
|
104
|
+
const seqBytes = encodeCbor(s2.sequence_number);
|
|
105
|
+
const pubBytes = encodeCbor(s2.sender_pubkey);
|
|
106
|
+
const hashBytes = encodeCbor(s2.content_hash);
|
|
107
|
+
const sigBytes = encodeCbor(s2.sender_signature);
|
|
108
|
+
const prevBytes = encodeCbor(s2.prev_root);
|
|
110
109
|
return new Uint8Array(Buffer.concat([arrayHeader, seqBytes, pubBytes, hashBytes, sigBytes, sentinelBytes, prevBytes]));
|
|
111
110
|
}
|
|
112
111
|
// ─── Verify ───────────────────────────────────────────────────────────────────
|
|
@@ -125,7 +124,7 @@ export function encodeStructure2(s2) {
|
|
|
125
124
|
*/
|
|
126
125
|
export function verifyStructure2Signature(s2, session_id, last_seen_seq, timestamp) {
|
|
127
126
|
const tsEncoded = typeof timestamp === "bigint" ? timestamp : timestamp > 0xffffffff ? BigInt(timestamp) : timestamp;
|
|
128
|
-
const tbs =
|
|
127
|
+
const tbs = encodeCbor([
|
|
129
128
|
1,
|
|
130
129
|
s2.content_hash,
|
|
131
130
|
s2.sender_pubkey,
|
package/dist/structure2.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"structure2.js","sourceRoot":"","sources":["../src/structure2.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"structure2.js","sourceRoot":"","sources":["../src/structure2.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cello-protocol/protocol-types",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.22",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"cbor-x": "^1.6.4",
|
|
26
|
-
"@cello-protocol/crypto": "0.0.
|
|
26
|
+
"@cello-protocol/crypto": "0.0.21"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@claude-flow/testing": "3.0.0-alpha.6",
|