@real-life/trust-protocol 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -4
- package/dist/ceremony.d.ts +3 -0
- package/dist/ceremony.d.ts.map +1 -0
- package/dist/ceremony.js +29 -0
- package/dist/ceremony.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/probe/acks.d.ts +1 -1
- package/dist/probe/acks.d.ts.map +1 -1
- package/dist/probe/acks.js +50 -17
- package/dist/probe/acks.js.map +1 -1
- package/dist/probe/continuity.d.ts.map +1 -1
- package/dist/probe/continuity.js +24 -2
- package/dist/probe/continuity.js.map +1 -1
- package/dist/probe/encounter.d.ts +26 -0
- package/dist/probe/encounter.d.ts.map +1 -0
- package/dist/probe/encounter.js +938 -0
- package/dist/probe/encounter.js.map +1 -0
- package/dist/probe/trust.d.ts.map +1 -1
- package/dist/probe/trust.js +51 -21
- package/dist/probe/trust.js.map +1 -1
- package/dist/probe.d.ts.map +1 -1
- package/dist/probe.js +3 -0
- package/dist/probe.js.map +1 -1
- package/dist/visibility.d.ts.map +1 -1
- package/dist/visibility.js +2 -1
- package/dist/visibility.js.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -36,6 +36,7 @@ look in the code:
|
|
|
36
36
|
| `carrier` | Delivery §4.4 + §5a | The carrier side of the port as one transport-agnostic state machine: the five guarantees, the proof rule, the total binding lifecycle (unbound → live → closing → released), the verdict sets in their normative evaluation orders, wind-up and binding tombstones. The clock is injected. |
|
|
37
37
|
| `holder` | Delivery §5a + Identity §9.3 | The holder's half: proof construction for all four purposes, the closed verdict set, and the two-exchange recovery flow for a lost carrier entry. |
|
|
38
38
|
| `visibility` | Network Visibility 0.29 on Delivery 0.79 | The trust act (`anchor-mapping@2` + `grade-declaration@1`), the blinded star (`star@1`, 5.2a chunks), the admission layer and the 5.4 reconciliation automaton, §6a continuity (probe + mapping — chains instead of duplicates), and the deniable `delivery-ack/0.1`. Namespaced: `visibility.trust`, `.continuity`, `.acks`. Graduated from `/probe` on 04.09.2026 after a 39-round conformance loop. |
|
|
39
|
+
| `ceremony` | Encounter 0.29 (`encounter-scan@0.25`) on Delivery 0.79 | The ceremony's transmission: `encounter-bundle/0.1`, `encounter-credential-delivery/0.1` (counter-step in the bundle's thread), the signed `delivery-ack/0.1`; the own-challenge state model with its aging latch, the enactment record as the serialization point, the eight-step acceptance, connected and offline path with free switching; one commit discipline (prepare → verify → commit) under the §6.2 lock set; resumable issuance. Graduated from `/probe` on 05.09.2026 after a 25-round conformance loop. |
|
|
39
40
|
|
|
40
41
|
Everything is re-exported from the package root; the table is a map, not an
|
|
41
42
|
import instruction.
|
|
@@ -59,7 +60,8 @@ are **not wire-normative**: mediated introductions over a rendezvous drop
|
|
|
59
60
|
and group membership (founding, VIC invite, admission, vouching). The
|
|
60
61
|
trust act, the blinded star, §6a continuity and the deniable ack **left
|
|
61
62
|
this subpath on 04.09.2026** — they are wire-normative now and live under
|
|
62
|
-
`visibility` at the package root
|
|
63
|
+
`visibility` at the package root; the Encounter ceremony's transmission
|
|
64
|
+
**left on 05.09.2026** and lives under `ceremony`. Experiment with the rest; do not treat its wire forms
|
|
63
65
|
as an interoperability target. A subpath import is a decision someone has
|
|
64
66
|
to make — nothing behind it can be reached by accident.
|
|
65
67
|
|
|
@@ -78,15 +80,16 @@ This package uses its own semver; the specification uses castings. Each
|
|
|
78
80
|
release states, per module, whose **wire forms** it implements — and what
|
|
79
81
|
it deliberately does not:
|
|
80
82
|
|
|
81
|
-
| Module (0.
|
|
83
|
+
| Module (0.3.x) | Casting | Implemented | Not in this package |
|
|
82
84
|
|---|---|---|---|
|
|
83
85
|
| `identity` | Identity 0.50 | context derivation under the closed label registry (§6.1, unchanged since 0.13) with the ordered persona pipeline (§6.2, Unicode 15.0 pinned) | recovery derivation (§5.3), service identities (§7), the label register and its state |
|
|
84
86
|
| `carrier-identity` | Identity 0.51 (§7a) | the carrier-relationship principal derivation, identifier validation | the register's generation state (held by the holder's store) |
|
|
85
87
|
| `carrier` + `holder` | Delivery 0.79 (§4.4, §5a) + Identity 0.51 (§9.3) | the port state machine, proofs for all four purposes, verdicts, recovery | transport adapters and their policies (a carrier's budgets enter through hooks) |
|
|
86
|
-
| `encounter` | Encounter 0.29 — wire `0.25` (`rltp-card/0.25`, `encounter-scan@0.25`) | challenges, both card profiles, the enactment binding, encounter credentials | the ceremony
|
|
88
|
+
| `encounter` | Encounter 0.29 — wire `0.25` (`rltp-card/0.25`, `encounter-scan@0.25`) | challenges, both card profiles, the enactment binding, encounter credentials (the primitives) | — (the ceremony machine lives in `ceremony`) |
|
|
89
|
+
| `ceremony` | Encounter 0.29 §5.3–5.8 + Delivery 0.79 (§3, §4.1–4.3, §6) | `encounter-bundle/0.1`, `encounter-credential-delivery/0.1`, signed `delivery-ack/0.1`; own-challenge state model (aging latch, whole seconds), enactment record + record-key lock set, 5.6 acceptance in order, both 5.8 paths, thread freshness incl. re-issue, resumable issuance, chain-head carry | storage, transport adapters, the host's UI correlation (duties listed in the handoff) |
|
|
87
90
|
| `delivery` | Delivery 0.64 | the sealed envelope (§5) and the generic receive stages 1–4 | the type-specific stages, residual bookkeeping, transport adapters |
|
|
88
91
|
| `core`, `crypto` | cross-layer | canonical form, digest equality, timestamps, validator; primitives + `eddsa-jcs-2022` proof | — |
|
|
89
|
-
| `visibility` | Network Visibility 0.29 + Delivery 0.79 (§3, §4.2, §4.4) | the trust act (`anchor-mapping@2`, `grade-declaration@1`), `star@1` with 5.2a chunk assembly, the admission layer (Section 2), the 5.4 reconciliation automaton with completion via deniable acks, §6a continuity (`continuity-probe@1`, `continuity-mapping@1`, chaining), the registered task documents and `delivery-ack/0.1` with the 4.2 class rule; full §6.2 stage order on every receive path, peek→build→commit issuance on every producer | storage, transport adapters and their policies
|
|
92
|
+
| `visibility` | Network Visibility 0.29 + Delivery 0.79 (§3, §4.2, §4.4) | the trust act (`anchor-mapping@2`, `grade-declaration@1`), `star@1` with 5.2a chunk assembly, the admission layer (Section 2), the 5.4 reconciliation automaton with completion via deniable acks, §6a continuity (`continuity-probe@1`, `continuity-mapping@1`, chaining), the registered task documents and `delivery-ack/0.1` with the 4.2 class rule; full §6.2 stage order on every receive path, peek→build→commit issuance on every producer | storage, transport adapters and their policies (the Encounter ceremony's flows live in `ceremony`) |
|
|
90
93
|
| `/probe` | Network Visibility (introductions) · Membership Tasks + Access | mediated introductions, group membership — semantics of the running castings, transport shapes `@probe` | any wire-form stability whatsoever |
|
|
91
94
|
|
|
92
95
|
Persona-name validation is **pinned to Unicode 15.0** as Identity §6.2
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ceremony.d.ts","sourceRoot":"","sources":["../src/ceremony.ts"],"names":[],"mappings":"AA4BA,YAAY,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAC7C,cAAc,sBAAsB,CAAA"}
|
package/dist/ceremony.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// @real-life/trust-protocol — ceremony: the GRADUATED transmission of the
|
|
2
|
+
// Encounter ceremony on the normative forms.
|
|
3
|
+
//
|
|
4
|
+
// Graduated 05.09.2026 after a 25-round adversarial conformance loop
|
|
5
|
+
// (design/encounter-nachzug-konvergenz-2026-09.md): this module implements
|
|
6
|
+
// the one registered ceremony `encounter-scan@0.25` (Encounter 0.29, wire
|
|
7
|
+
// 0.25) carried by the Delivery Contract 0.79 —
|
|
8
|
+
//
|
|
9
|
+
// encounter-bundle/0.1 the scanner's sent card + step
|
|
10
|
+
// credential (Delivery 4.1)
|
|
11
|
+
// encounter-credential-delivery/0.1 the counter-step in the bundle's
|
|
12
|
+
// thread (Delivery 4.3)
|
|
13
|
+
// delivery-ack/0.1 (signed class) arrival, never acceptance (4.2)
|
|
14
|
+
//
|
|
15
|
+
// The machine: the own-challenge state model with its lock-free aging
|
|
16
|
+
// latch (5.3), the enactment record as the one serialization point (5.5),
|
|
17
|
+
// the eight-step acceptance (5.6), connected and offline path of 5.8 with
|
|
18
|
+
// free switching, and ONE commit discipline for every effect —
|
|
19
|
+
// prepare (async, no mutation) → verify (sync, under the 6.2 lock set) →
|
|
20
|
+
// commit (sync). `delivered` is the sender's status only on a valid ack.
|
|
21
|
+
//
|
|
22
|
+
// The module operates on the probe WORLD (a `Person`); the host owns
|
|
23
|
+
// storage and transport and carries the duties listed in the handoff
|
|
24
|
+
// (atomic writes, resume before flush, UI correlation).
|
|
25
|
+
//
|
|
26
|
+
// show · scan · counter · captureSentCard · receiveEncounter ·
|
|
27
|
+
// resumeEncounter · flushEncounter · resolve · constants
|
|
28
|
+
export * from './probe/encounter.js';
|
|
29
|
+
//# sourceMappingURL=ceremony.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ceremony.js","sourceRoot":"","sources":["../src/ceremony.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,6CAA6C;AAC7C,EAAE;AACF,qEAAqE;AACrE,2EAA2E;AAC3E,0EAA0E;AAC1E,gDAAgD;AAChD,EAAE;AACF,wEAAwE;AACxE,mEAAmE;AACnE,0EAA0E;AAC1E,+DAA+D;AAC/D,yEAAyE;AACzE,EAAE;AACF,sEAAsE;AACtE,0EAA0E;AAC1E,0EAA0E;AAC1E,+DAA+D;AAC/D,yEAAyE;AACzE,yEAAyE;AACzE,EAAE;AACF,qEAAqE;AACrE,qEAAqE;AACrE,wDAAwD;AACxD,EAAE;AACF,iEAAiE;AACjE,2DAA2D;AAG3D,cAAc,sBAAsB,CAAA","sourcesContent":["// @real-life/trust-protocol — ceremony: the GRADUATED transmission of the\n// Encounter ceremony on the normative forms.\n//\n// Graduated 05.09.2026 after a 25-round adversarial conformance loop\n// (design/encounter-nachzug-konvergenz-2026-09.md): this module implements\n// the one registered ceremony `encounter-scan@0.25` (Encounter 0.29, wire\n// 0.25) carried by the Delivery Contract 0.79 —\n//\n// encounter-bundle/0.1 the scanner's sent card + step\n// credential (Delivery 4.1)\n// encounter-credential-delivery/0.1 the counter-step in the bundle's\n// thread (Delivery 4.3)\n// delivery-ack/0.1 (signed class) arrival, never acceptance (4.2)\n//\n// The machine: the own-challenge state model with its lock-free aging\n// latch (5.3), the enactment record as the one serialization point (5.5),\n// the eight-step acceptance (5.6), connected and offline path of 5.8 with\n// free switching, and ONE commit discipline for every effect —\n// prepare (async, no mutation) → verify (sync, under the 6.2 lock set) →\n// commit (sync). `delivered` is the sender's status only on a valid ack.\n//\n// The module operates on the probe WORLD (a `Person`); the host owns\n// storage and transport and carries the duties listed in the handoff\n// (atomic writes, resume before flush, UI correlation).\n//\n// show · scan · counter · captureSentCard · receiveEncounter ·\n// resumeEncounter · flushEncounter · resolve · constants\n\nexport type { Person } from './probe/deps.js'\nexport * from './probe/encounter.js'\n"]}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAoCA,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,uBAAuB,CAAA;AACrC,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -26,6 +26,11 @@
|
|
|
26
26
|
// act, the blinded star, §6a continuity, the deniable
|
|
27
27
|
// ack (namespaced: `visibility.trust`, `.continuity`,
|
|
28
28
|
// `.acks`; graduated from /probe on 04.09.2026)
|
|
29
|
+
// ceremony Encounter 0.29's registered ceremony on Delivery
|
|
30
|
+
// 0.79 — encounter-bundle, encounter-credential-
|
|
31
|
+
// delivery, the signed ack; own-challenge state
|
|
32
|
+
// model, enactment record, 5.6 acceptance, both
|
|
33
|
+
// paths of 5.8 (graduated from /probe on 05.09.2026)
|
|
29
34
|
//
|
|
30
35
|
// Specification, schemas and vectors: https://rltp.real-life.org
|
|
31
36
|
export * from './core.js';
|
|
@@ -37,4 +42,5 @@ export * from './carrier-identity.js';
|
|
|
37
42
|
export * from './carrier.js';
|
|
38
43
|
export * from './holder.js';
|
|
39
44
|
export * as visibility from './visibility.js';
|
|
45
|
+
export * as ceremony from './ceremony.js';
|
|
40
46
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,EAAE;AACF,uEAAuE;AACvE,mEAAmE;AACnE,uEAAuE;AACvE,uEAAuE;AACvE,6BAA6B;AAC7B,EAAE;AACF,oEAAoE;AACpE,kEAAkE;AAClE,sEAAsE;AACtE,sEAAsE;AACtE,uEAAuE;AACvE,qEAAqE;AACrE,uBAAuB;AACvB,EAAE;AACF,oDAAoD;AACpD,mEAAmE;AACnE,+EAA+E;AAC/E,gFAAgF;AAChF,6EAA6E;AAC7E,wEAAwE;AACxE,yEAAyE;AACzE,8EAA8E;AAC9E,2EAA2E;AAC3E,0EAA0E;AAC1E,0EAA0E;AAC1E,oEAAoE;AACpE,EAAE;AACF,iEAAiE;AAEjE,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,uBAAuB,CAAA;AACrC,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA","sourcesContent":["// @real-life/trust-protocol — the cryptographic core of RLTP.\n//\n// What this entry point IS: the wire-level primitives of the converged\n// layers, reproducing the shipped test vectors byte for byte — the\n// canonical form, the derivation of identity contexts under the closed\n// label registry, the encounter wire builders, the sealed envelope and\n// the generic receive chain.\n//\n// What it is NOT (yet): the layers' full state machines. Identity's\n// recovery derivation, Encounter's ceremony record and acceptance\n// machinery, Delivery's type-specific stages and residual bookkeeping\n// live in the specification and its conformance fixtures, not here. A\n// conformant implementation builds ON this module; importing it is not\n// yet conformance. The README states per module which casting's wire\n// forms it implements.\n//\n// core the form every artifact obeys\n// crypto the primitives, and the Data Integrity proof\n// identity context derivation under the closed registry (§6.1/§6.2)\n// encounter the ceremony's wire forms: challenges, cards, credentials\n// delivery the sealed envelope and the generic receive stages 1–4\n// carrier-identity the carrier-relationship principal (Identity §7a)\n// carrier the carrier side of the port (Delivery §4.4 + §5a)\n// holder the holder side: proofs, verdicts, recovery (§5a, §9.3)\n// visibility Network Visibility 0.29 on Delivery 0.79 — the trust\n// act, the blinded star, §6a continuity, the deniable\n// ack (namespaced: `visibility.trust`, `.continuity`,\n// `.acks`; graduated from /probe on 04.09.2026)\n//\n// Specification, schemas and vectors: https://rltp.real-life.org\n\nexport * from './core.js'\nexport * from './crypto.js'\nexport * from './identity.js'\nexport * from './encounter.js'\nexport * from './delivery.js'\nexport * from './carrier-identity.js'\nexport * from './carrier.js'\nexport * from './holder.js'\nexport * as visibility from './visibility.js'\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,EAAE;AACF,uEAAuE;AACvE,mEAAmE;AACnE,uEAAuE;AACvE,uEAAuE;AACvE,6BAA6B;AAC7B,EAAE;AACF,oEAAoE;AACpE,kEAAkE;AAClE,sEAAsE;AACtE,sEAAsE;AACtE,uEAAuE;AACvE,qEAAqE;AACrE,uBAAuB;AACvB,EAAE;AACF,oDAAoD;AACpD,mEAAmE;AACnE,+EAA+E;AAC/E,gFAAgF;AAChF,6EAA6E;AAC7E,wEAAwE;AACxE,yEAAyE;AACzE,8EAA8E;AAC9E,2EAA2E;AAC3E,0EAA0E;AAC1E,0EAA0E;AAC1E,oEAAoE;AACpE,uEAAuE;AACvE,qEAAqE;AACrE,oEAAoE;AACpE,oEAAoE;AACpE,yEAAyE;AACzE,EAAE;AACF,iEAAiE;AAEjE,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,uBAAuB,CAAA;AACrC,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA","sourcesContent":["// @real-life/trust-protocol — the cryptographic core of RLTP.\n//\n// What this entry point IS: the wire-level primitives of the converged\n// layers, reproducing the shipped test vectors byte for byte — the\n// canonical form, the derivation of identity contexts under the closed\n// label registry, the encounter wire builders, the sealed envelope and\n// the generic receive chain.\n//\n// What it is NOT (yet): the layers' full state machines. Identity's\n// recovery derivation, Encounter's ceremony record and acceptance\n// machinery, Delivery's type-specific stages and residual bookkeeping\n// live in the specification and its conformance fixtures, not here. A\n// conformant implementation builds ON this module; importing it is not\n// yet conformance. The README states per module which casting's wire\n// forms it implements.\n//\n// core the form every artifact obeys\n// crypto the primitives, and the Data Integrity proof\n// identity context derivation under the closed registry (§6.1/§6.2)\n// encounter the ceremony's wire forms: challenges, cards, credentials\n// delivery the sealed envelope and the generic receive stages 1–4\n// carrier-identity the carrier-relationship principal (Identity §7a)\n// carrier the carrier side of the port (Delivery §4.4 + §5a)\n// holder the holder side: proofs, verdicts, recovery (§5a, §9.3)\n// visibility Network Visibility 0.29 on Delivery 0.79 — the trust\n// act, the blinded star, §6a continuity, the deniable\n// ack (namespaced: `visibility.trust`, `.continuity`,\n// `.acks`; graduated from /probe on 04.09.2026)\n// ceremony Encounter 0.29's registered ceremony on Delivery\n// 0.79 — encounter-bundle, encounter-credential-\n// delivery, the signed ack; own-challenge state\n// model, enactment record, 5.6 acceptance, both\n// paths of 5.8 (graduated from /probe on 05.09.2026)\n//\n// Specification, schemas and vectors: https://rltp.real-life.org\n\nexport * from './core.js'\nexport * from './crypto.js'\nexport * from './identity.js'\nexport * from './encounter.js'\nexport * from './delivery.js'\nexport * from './carrier-identity.js'\nexport * from './carrier.js'\nexport * from './holder.js'\nexport * as visibility from './visibility.js'\nexport * as ceremony from './ceremony.js'\n"]}
|
package/dist/probe/acks.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export declare function buildAck(p: Person, contact: any, refDigest: string, thr
|
|
|
20
20
|
* that tuple, recipient = our own pair anchor. Returns { ref, threadId }
|
|
21
21
|
* or null — the caller matches ref against what it actually sent.
|
|
22
22
|
*/
|
|
23
|
-
export declare function verifyAck(p: Person, contact: any, doc: any): Promise<{
|
|
23
|
+
export declare function verifyAck(p: Person, contact: any, doc: any, cls?: 'signature' | 'dv'): Promise<{
|
|
24
24
|
ref: string;
|
|
25
25
|
threadId: string;
|
|
26
26
|
} | null>;
|
package/dist/probe/acks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acks.d.ts","sourceRoot":"","sources":["../../src/probe/acks.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"acks.d.ts","sourceRoot":"","sources":["../../src/probe/acks.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,CAAC,MAAM,WAAW,CAAA;AAC9B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAIvC,eAAO,MAAM,QAAQ,uDAAuD,CAAA;AAa5E,0EAA0E;AAC1E,wBAAsB,MAAM,CAAE,MAAM,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,wCAI9G;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,GAAQ;;;;GA0BxH;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,GAAE,WAAW,GAAG,IAAW,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CA8CrJ"}
|
package/dist/probe/acks.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
// acks — the
|
|
2
|
-
// acknowledgement
|
|
3
|
-
// the real, registered wire form (`delivery-ack/0.1`)
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
1
|
+
// acks — the delivery acknowledgement (Delivery 4.2/4.4, the
|
|
2
|
+
// acknowledgement CLASS rule) for the probe world. The ack DOCUMENT is
|
|
3
|
+
// the real, registered wire form (`delivery-ack/0.1`) in the form the
|
|
4
|
+
// acknowledged payload's class selects: a SIGNED ack (eddsa-jcs-2022
|
|
5
|
+
// under the issuer anchor) for signature-class payloads (the Encounter
|
|
6
|
+
// forms), the DENIABLE MAC ack for designated-verifier payloads (the
|
|
7
|
+
// Visibility forms). The MAC key regime is the normative one —
|
|
8
|
+
// byte-compatible with vectors/delivery-ack.json and
|
|
9
|
+
// lib/test/vectors4.test.mjs: one channel-keyed derivation for every
|
|
10
|
+
// DV-type ack, never the payload's internal MAC structure.
|
|
8
11
|
//
|
|
9
12
|
// k = HKDF-SHA-256(ikm = X25519(pairX_issuer, pairX_recipient),
|
|
10
13
|
// salt = empty, info = "rltp/v1/delivery/mac/ack/"
|
|
@@ -52,11 +55,23 @@ export async function buildAck(p, contact, refDigest, threadId, when, ent = {})
|
|
|
52
55
|
id: ent.ackId ?? globalThis.crypto.randomUUID(),
|
|
53
56
|
type: ACK_TYPE,
|
|
54
57
|
issuer: own.anchor, // = the acked document's recipient (4.2)
|
|
55
|
-
recipient
|
|
58
|
+
// the recipient is the counterparty anchor; `ent.recipient` names it
|
|
59
|
+
// when the tuple is not yet inserted (a record-creating effect builds
|
|
60
|
+
// its ack BEFORE the one synchronous commit, Delivery 4.1)
|
|
61
|
+
recipient: ent.recipient ?? contactKeyOf(p, contact),
|
|
56
62
|
threadId,
|
|
57
63
|
issuedAt: C.iso(when),
|
|
58
64
|
payload: { ref: refDigest, meaning: 'received' },
|
|
59
65
|
};
|
|
66
|
+
// the acknowledgement CLASS rule (4.2/4.4): a payload whose authenticity
|
|
67
|
+
// is a TRANSFERABLE SIGNATURE (the Encounter forms: card + credential
|
|
68
|
+
// under DataIntegrityProof) is acknowledged with eddsa-jcs-2022 under
|
|
69
|
+
// the ack's issuer anchor — an attestation; a DESIGNATED-VERIFIER
|
|
70
|
+
// payload with the deniable channel-keyed MAC. `ent.cls` selects.
|
|
71
|
+
if (ent.cls === 'signature') {
|
|
72
|
+
const document = await C.diSign(own, doc, doc.issuedAt);
|
|
73
|
+
return { to: contact, kind: 'delivery-ack/0.1 (signiert, eddsa-jcs-2022 unter dem Issuer-Anker)', env: await C.seal(document, contact.channel.counterpartKa, ent) };
|
|
74
|
+
}
|
|
60
75
|
const k = await ackKey(own, contact.channel.counterpartKa, doc.issuer, doc.recipient);
|
|
61
76
|
const document = { ...doc, proof: { mac: await hmacU(k, jcs(doc)) } };
|
|
62
77
|
return { to: contact, kind: 'delivery-ack/0.1 (deniabel, MAC unter dem Kanal-Ack-Key)', env: await C.seal(document, contact.channel.counterpartKa, ent) };
|
|
@@ -67,7 +82,7 @@ export async function buildAck(p, contact, refDigest, threadId, when, ent = {})
|
|
|
67
82
|
* that tuple, recipient = our own pair anchor. Returns { ref, threadId }
|
|
68
83
|
* or null — the caller matches ref against what it actually sent.
|
|
69
84
|
*/
|
|
70
|
-
export async function verifyAck(p, contact, doc) {
|
|
85
|
+
export async function verifyAck(p, contact, doc, cls = 'dv') {
|
|
71
86
|
try {
|
|
72
87
|
if (doc?.type !== ACK_TYPE)
|
|
73
88
|
return null;
|
|
@@ -85,19 +100,30 @@ export async function verifyAck(p, contact, doc) {
|
|
|
85
100
|
// über JCS(Dokument ohne proof) und deckt es mit ab
|
|
86
101
|
if (Object.keys(doc).some((k) => !['id', 'type', 'issuer', 'recipient', 'threadId', 'issuedAt', 'payload', 'proof', 'ceremony'].includes(k)))
|
|
87
102
|
return null;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
// class rule: the MAC form and nothing else — a signature-form or
|
|
91
|
-
// hybrid proof for a DV payload is invalid (4.2/4.4)
|
|
92
|
-
if (typeof doc.proof.mac !== 'string' || doc.proof.proofValue !== undefined)
|
|
103
|
+
// — Stufe 7 VOR Stufe 8: das Payload-Schema zuerst
|
|
104
|
+
if (!schemaOk('payload-delivery-ack.schema.json', doc.payload))
|
|
93
105
|
return null;
|
|
106
|
+
// class rule (4.2/4.4, Stufe 8): EXACTLY the form the acknowledged
|
|
107
|
+
// payload's class selects — signature-class payload → SIGNED ack,
|
|
108
|
+
// designated-verifier payload → MAC ack. Every other combination
|
|
109
|
+
// (MAC on a signature-class payload, signature on a DV payload, a
|
|
110
|
+
// hybrid proof) is invalid
|
|
111
|
+
if (cls === 'signature') {
|
|
112
|
+
if (doc.proof.mac !== undefined || doc.proof.type !== 'DataIntegrityProof' || doc.proof.cryptosuite !== 'eddsa-jcs-2022')
|
|
113
|
+
return null;
|
|
114
|
+
if (!C.calOK(doc.proof.created))
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
if (Object.keys(doc.proof).length !== 1)
|
|
119
|
+
return null;
|
|
120
|
+
if (typeof doc.proof.mac !== 'string' || doc.proof.proofValue !== undefined)
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
94
123
|
if (!C.calOK(doc.issuedAt))
|
|
95
124
|
return null; // Kalender-Validität (Review 12, B-3)
|
|
96
125
|
if (doc.recipient !== contact.channel.own.anchor)
|
|
97
126
|
return null;
|
|
98
|
-
// — Stufe 7: Payload-Schema
|
|
99
|
-
if (!schemaOk('payload-delivery-ack.schema.json', doc.payload))
|
|
100
|
-
return null;
|
|
101
127
|
// — Stufe 8: enactment-Profilregel (Review 20, B-2: ein Ack
|
|
102
128
|
// umschließt kein Bindungsmaterial), issuer-Bindung, meaning
|
|
103
129
|
if (doc.ceremony?.enactment !== undefined)
|
|
@@ -106,6 +132,13 @@ export async function verifyAck(p, contact, doc) {
|
|
|
106
132
|
return null;
|
|
107
133
|
if (!C.shaped(doc.payload, { ref: 'string', meaning: 'string' }) || doc.payload.meaning !== 'received')
|
|
108
134
|
return null;
|
|
135
|
+
if (cls === 'signature') {
|
|
136
|
+
// the attestation: verifies under the ack's issuer anchor (= the
|
|
137
|
+
// acked document's recipient, our counterpart on the tuple)
|
|
138
|
+
if (!(await C.diVerify(doc, doc.issuer)))
|
|
139
|
+
return null;
|
|
140
|
+
return { ref: doc.payload.ref, threadId: doc.threadId };
|
|
141
|
+
}
|
|
109
142
|
const { proof, ...rest } = doc;
|
|
110
143
|
const k = await ackKey(contact.channel.own, contact.channel.counterpartKa, doc.issuer, doc.recipient);
|
|
111
144
|
if ((await hmacU(k, jcs(rest))) !== proof.mac)
|
package/dist/probe/acks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acks.js","sourceRoot":"","sources":["../../src/probe/acks.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,uEAAuE;AACvE,mEAAmE;AACnE,qDAAqD;AACrD,gEAAgE;AAChE,sEAAsE;AACtE,0BAA0B;AAC1B,EAAE;AACF,kEAAkE;AAClE,sEAAsE;AACtE,wEAAwE;AACxE,gEAAgE;AAChE,mEAAmE;AACnE,EAAE;AACF,sEAAsE;AACtE,uEAAuE;AACvE,2CAA2C;AAC3C,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,CAAC,MAAM,WAAW,CAAA;AAG9B,MAAM,EAAE,GAAG,IAAI,WAAW,EAAE,CAAA;AAC5B,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC,MAAM,CAAA;AAClC,MAAM,CAAC,MAAM,QAAQ,GAAG,oDAAoD,CAAA;AAE5E,MAAM,CAAC,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;AAChC,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAE,IAAS,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAA;AACzG,MAAM,KAAK,GAAG,KAAK,EAAE,GAAe,EAAE,GAAW,EAAE,EAAE;IACnD,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;IAC3F,OAAO,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;AAChF,CAAC,CAAA;AACD,MAAM,YAAY,GAAG,CAAC,CAAS,EAAE,OAAY,EAAE,EAAE;IAC/C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ;QAAE,IAAI,CAAC,KAAK,OAAO;YAAE,OAAO,CAAC,CAAA;IAC5D,OAAO,SAAS,CAAA;AAClB,CAAC,CAAA;AAED,0EAA0E;AAC1E,MAAM,CAAC,KAAK,UAAU,MAAM,CAAE,MAAW,EAAE,aAAqB,EAAE,YAAoB,EAAE,eAAuB;IAC7G,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAE,CAAC,CAAA;IACtE,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAA;IACnF,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,2BAA2B,GAAG,YAAY,GAAG,GAAG,GAAG,eAAe,CAAC,CAAA;AAC3F,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAE,CAAS,EAAE,OAAY,EAAE,SAAiB,EAAE,QAAgB,EAAE,IAAY,EAAE,MAAW,EAAE;IACvH,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAA;IAC/B,MAAM,GAAG,GAAG;QACV,EAAE,EAAE,GAAG,CAAC,KAAK,IAAI,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE;QAC/C,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,GAAG,CAAC,MAAM,EAAwB,yCAAyC;QACnF,SAAS,EAAE,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC;QACnC,QAAQ;QACR,QAAQ,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;QACrB,OAAO,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE;KACjD,CAAA;IACD,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,SAAU,CAAC,CAAA;IACtF,MAAM,QAAQ,GAAG,EAAE,GAAG,GAAG,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAA;IACrE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,0DAA0D,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,EAAE,CAAA;AAC3J,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAE,CAAS,EAAE,OAAY,EAAE,GAAQ;IAChE,IAAI,CAAC;QACH,IAAI,GAAG,EAAE,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAA;QACvC,gEAAgE;QAChE,mEAAmE;QACnE,kDAAkD;QAClD,6DAA6D;QAC7D,wCAAwC;QACxC,IAAI,CAAC,QAAQ,CAAC,oCAAoC,EAAE,GAAG,CAAC;YAAE,OAAO,IAAI,CAAA;QACrE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;YAAE,OAAO,IAAI,CAAA;QACpK,mEAAmE;QACnE,oEAAoE;QACpE,oDAAoD;QACpD,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAA;QACzJ,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAA;QACpD,kEAAkE;QAClE,qDAAqD;QACrD,IAAI,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,KAAK,CAAC,UAAU,KAAK,SAAS;YAAE,OAAO,IAAI,CAAA;QACxF,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,OAAO,IAAI,CAAA,CAAG,sCAAsC;QAChF,IAAI,GAAG,CAAC,SAAS,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM;YAAE,OAAO,IAAI,CAAA;QAC7D,4BAA4B;QAC5B,IAAI,CAAC,QAAQ,CAAC,kCAAkC,EAAE,GAAG,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAA;QAC3E,4DAA4D;QAC5D,+DAA+D;QAC/D,IAAI,GAAG,CAAC,QAAQ,EAAE,SAAS,KAAK,SAAS;YAAE,OAAO,IAAI,CAAA;QACtD,IAAI,GAAG,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC;YAAE,OAAO,IAAI,CAAA;QACxD,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,UAAU;YAAE,OAAO,IAAI,CAAA;QACnH,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,CAAA;QAC9B,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,SAAS,CAAC,CAAA;QACrG,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,GAAG;YAAE,OAAO,IAAI,CAAA;QAC1D,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAA;IACzD,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,IAAI,CAAA;IAAC,CAAC;AACzB,CAAC","sourcesContent":["// acks — the deniable delivery acknowledgement (Delivery 4.2/4.4, the\n// acknowledgement class rule) for the probe world. The ack DOCUMENT is\n// the real, registered wire form (`delivery-ack/0.1`), and the key\n// regime is the normative one — byte-compatible with\n// vectors/delivery-ack.json and lib/test/vectors4.test.mjs: one\n// channel-keyed derivation for every DV-type ack, never the payload's\n// internal MAC structure.\n//\n// k = HKDF-SHA-256(ikm = X25519(pairX_issuer, pairX_recipient),\n// salt = empty, info = \"rltp/v1/delivery/mac/ack/\"\n// || issuerPairAnchor || \"/\" || recipientPairAnchor,\n// 32 bytes; all-zero shared secret rejected)\n// proof = { mac: HMAC-SHA-256 over JCS(document without proof) }\n//\n// Deniable by construction: either relationship party can compute the\n// MAC — for DV payloads the ack is evidence to the sender alone, never\n// an attestation toward anyone else (4.2).\nimport { jcs, makeValidator } from '../core.js'\nimport { SCHEMAS } from '../schemas.js'\nimport * as C from './deps.js'\nimport type { Person } from './deps.js'\n\nconst te = new TextEncoder()\nconst S = globalThis.crypto.subtle\nexport const ACK_TYPE = 'https://real-life.org/trust-tasks/delivery-ack/0.1'\n\nconst V = makeValidator(SCHEMAS)\nconst schemaOk = (file: string, data: any) => V.validate(data, SCHEMAS[file], SCHEMAS[file]).length === 0\nconst hmacU = async (key: Uint8Array, msg: string) => {\n const k = await S.importKey('raw', key, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign'])\n return 'u' + C.b64uOf(new Uint8Array(await S.sign('HMAC', k, te.encode(msg))))\n}\nconst contactKeyOf = (p: Person, contact: any) => {\n for (const [k, c] of p.contacts) if (c === contact) return k\n return undefined\n}\n\n/** the channel ack key — Section 5's derivation discipline, 4.2's info */\nexport async function ackKey (ownCtx: any, counterpartKa: string, issuerAnchor: string, recipientAnchor: string) {\n const shared = await C.ecdh(ownCtx.x.priv, C.xRawOfMk(counterpartKa)!)\n if (shared.every((b: number) => b === 0)) throw new Error('all-zero X25519 output')\n return C.hkdf(shared, 'rltp/v1/delivery/mac/ack/' + issuerAnchor + '/' + recipientAnchor)\n}\n\n/**\n * Build the sealed deniable ack for a document received on `contact`'s\n * channel. `refDigest` is the acknowledged document's digest (the same\n * digest the completed-effect cache keys on); `threadId` is the acked\n * document's thread — the ack continues it (4.2).\n */\nexport async function buildAck (p: Person, contact: any, refDigest: string, threadId: string, when: number, ent: any = {}) {\n const own = contact.channel.own\n const doc = {\n id: ent.ackId ?? globalThis.crypto.randomUUID(),\n type: ACK_TYPE,\n issuer: own.anchor, // = the acked document's recipient (4.2)\n recipient: contactKeyOf(p, contact),\n threadId,\n issuedAt: C.iso(when),\n payload: { ref: refDigest, meaning: 'received' },\n }\n const k = await ackKey(own, contact.channel.counterpartKa, doc.issuer, doc.recipient!)\n const document = { ...doc, proof: { mac: await hmacU(k, jcs(doc)) } }\n return { to: contact, kind: 'delivery-ack/0.1 (deniabel, MAC unter dem Kanal-Ack-Key)', env: await C.seal(document, contact.channel.counterpartKa, ent) }\n}\n\n/**\n * Verify a received deniable ack (4.2 consistency): MAC-form proof only,\n * MAC under the arrival tuple's ack key, issuer = our counterpart on\n * that tuple, recipient = our own pair anchor. Returns { ref, threadId }\n * or null — the caller matches ref against what it actually sent.\n */\nexport async function verifyAck (p: Person, contact: any, doc: any): Promise<{ ref: string, threadId: string } | null> {\n try {\n if (doc?.type !== ACK_TYPE) return null\n // STUFENORDNUNG (Review 33, B-2): erst das DOKUMENTPROFIL + der\n // recipient (Stufe 5), dann das Payload-Schema (Stufe 7), dann die\n // Typ-Konsistenzregeln (Stufe 8), der MAC zuletzt\n // — Stufe 5: Dokument-Schema, geschlossene Form, Proof-Form,\n // Kalender, recipient = eigener Anker\n if (!schemaOk('rltp-delivery-document.schema.json', doc)) return null\n if (!C.shaped(doc, { id: 'string', issuer: 'string', recipient: 'string', threadId: 'string', issuedAt: 'string', payload: 'object', proof: 'object' })) return null\n // geschlossene Form + das OPTIONALE ceremony-Feld (Review 19, B-2:\n // „ceremony — OPTIONAL, and entirely unconstrained\"); der MAC läuft\n // über JCS(Dokument ohne proof) und deckt es mit ab\n if (Object.keys(doc).some((k) => !['id', 'type', 'issuer', 'recipient', 'threadId', 'issuedAt', 'payload', 'proof', 'ceremony'].includes(k))) return null\n if (Object.keys(doc.proof).length !== 1) return null\n // class rule: the MAC form and nothing else — a signature-form or\n // hybrid proof for a DV payload is invalid (4.2/4.4)\n if (typeof doc.proof.mac !== 'string' || doc.proof.proofValue !== undefined) return null\n if (!C.calOK(doc.issuedAt)) return null // Kalender-Validität (Review 12, B-3)\n if (doc.recipient !== contact.channel.own.anchor) return null\n // — Stufe 7: Payload-Schema\n if (!schemaOk('payload-delivery-ack.schema.json', doc.payload)) return null\n // — Stufe 8: enactment-Profilregel (Review 20, B-2: ein Ack\n // umschließt kein Bindungsmaterial), issuer-Bindung, meaning\n if (doc.ceremony?.enactment !== undefined) return null\n if (doc.issuer !== contactKeyOf(p, contact)) return null\n if (!C.shaped(doc.payload, { ref: 'string', meaning: 'string' }) || doc.payload.meaning !== 'received') return null\n const { proof, ...rest } = doc\n const k = await ackKey(contact.channel.own, contact.channel.counterpartKa, doc.issuer, doc.recipient)\n if ((await hmacU(k, jcs(rest))) !== proof.mac) return null\n return { ref: doc.payload.ref, threadId: doc.threadId }\n } catch { return null }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"acks.js","sourceRoot":"","sources":["../../src/probe/acks.ts"],"names":[],"mappings":"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","sourcesContent":["// acks — the delivery acknowledgement (Delivery 4.2/4.4, the\n// acknowledgement CLASS rule) for the probe world. The ack DOCUMENT is\n// the real, registered wire form (`delivery-ack/0.1`) in the form the\n// acknowledged payload's class selects: a SIGNED ack (eddsa-jcs-2022\n// under the issuer anchor) for signature-class payloads (the Encounter\n// forms), the DENIABLE MAC ack for designated-verifier payloads (the\n// Visibility forms). The MAC key regime is the normative one —\n// byte-compatible with vectors/delivery-ack.json and\n// lib/test/vectors4.test.mjs: one channel-keyed derivation for every\n// DV-type ack, never the payload's internal MAC structure.\n//\n// k = HKDF-SHA-256(ikm = X25519(pairX_issuer, pairX_recipient),\n// salt = empty, info = \"rltp/v1/delivery/mac/ack/\"\n// || issuerPairAnchor || \"/\" || recipientPairAnchor,\n// 32 bytes; all-zero shared secret rejected)\n// proof = { mac: HMAC-SHA-256 over JCS(document without proof) }\n//\n// Deniable by construction: either relationship party can compute the\n// MAC — for DV payloads the ack is evidence to the sender alone, never\n// an attestation toward anyone else (4.2).\nimport { jcs, makeValidator } from '../core.js'\nimport { SCHEMAS } from '../schemas.js'\nimport * as C from './deps.js'\nimport type { Person } from './deps.js'\n\nconst te = new TextEncoder()\nconst S = globalThis.crypto.subtle\nexport const ACK_TYPE = 'https://real-life.org/trust-tasks/delivery-ack/0.1'\n\nconst V = makeValidator(SCHEMAS)\nconst schemaOk = (file: string, data: any) => V.validate(data, SCHEMAS[file], SCHEMAS[file]).length === 0\nconst hmacU = async (key: Uint8Array, msg: string) => {\n const k = await S.importKey('raw', key, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign'])\n return 'u' + C.b64uOf(new Uint8Array(await S.sign('HMAC', k, te.encode(msg))))\n}\nconst contactKeyOf = (p: Person, contact: any) => {\n for (const [k, c] of p.contacts) if (c === contact) return k\n return undefined\n}\n\n/** the channel ack key — Section 5's derivation discipline, 4.2's info */\nexport async function ackKey (ownCtx: any, counterpartKa: string, issuerAnchor: string, recipientAnchor: string) {\n const shared = await C.ecdh(ownCtx.x.priv, C.xRawOfMk(counterpartKa)!)\n if (shared.every((b: number) => b === 0)) throw new Error('all-zero X25519 output')\n return C.hkdf(shared, 'rltp/v1/delivery/mac/ack/' + issuerAnchor + '/' + recipientAnchor)\n}\n\n/**\n * Build the sealed deniable ack for a document received on `contact`'s\n * channel. `refDigest` is the acknowledged document's digest (the same\n * digest the completed-effect cache keys on); `threadId` is the acked\n * document's thread — the ack continues it (4.2).\n */\nexport async function buildAck (p: Person, contact: any, refDigest: string, threadId: string, when: number, ent: any = {}) {\n const own = contact.channel.own\n const doc = {\n id: ent.ackId ?? globalThis.crypto.randomUUID(),\n type: ACK_TYPE,\n issuer: own.anchor, // = the acked document's recipient (4.2)\n // the recipient is the counterparty anchor; `ent.recipient` names it\n // when the tuple is not yet inserted (a record-creating effect builds\n // its ack BEFORE the one synchronous commit, Delivery 4.1)\n recipient: ent.recipient ?? contactKeyOf(p, contact),\n threadId,\n issuedAt: C.iso(when),\n payload: { ref: refDigest, meaning: 'received' },\n }\n // the acknowledgement CLASS rule (4.2/4.4): a payload whose authenticity\n // is a TRANSFERABLE SIGNATURE (the Encounter forms: card + credential\n // under DataIntegrityProof) is acknowledged with eddsa-jcs-2022 under\n // the ack's issuer anchor — an attestation; a DESIGNATED-VERIFIER\n // payload with the deniable channel-keyed MAC. `ent.cls` selects.\n if (ent.cls === 'signature') {\n const document = await C.diSign(own, doc, doc.issuedAt)\n return { to: contact, kind: 'delivery-ack/0.1 (signiert, eddsa-jcs-2022 unter dem Issuer-Anker)', env: await C.seal(document, contact.channel.counterpartKa, ent) }\n }\n const k = await ackKey(own, contact.channel.counterpartKa, doc.issuer, doc.recipient!)\n const document = { ...doc, proof: { mac: await hmacU(k, jcs(doc)) } }\n return { to: contact, kind: 'delivery-ack/0.1 (deniabel, MAC unter dem Kanal-Ack-Key)', env: await C.seal(document, contact.channel.counterpartKa, ent) }\n}\n\n/**\n * Verify a received deniable ack (4.2 consistency): MAC-form proof only,\n * MAC under the arrival tuple's ack key, issuer = our counterpart on\n * that tuple, recipient = our own pair anchor. Returns { ref, threadId }\n * or null — the caller matches ref against what it actually sent.\n */\nexport async function verifyAck (p: Person, contact: any, doc: any, cls: 'signature' | 'dv' = 'dv'): Promise<{ ref: string, threadId: string } | null> {\n try {\n if (doc?.type !== ACK_TYPE) return null\n // STUFENORDNUNG (Review 33, B-2): erst das DOKUMENTPROFIL + der\n // recipient (Stufe 5), dann das Payload-Schema (Stufe 7), dann die\n // Typ-Konsistenzregeln (Stufe 8), der MAC zuletzt\n // — Stufe 5: Dokument-Schema, geschlossene Form, Proof-Form,\n // Kalender, recipient = eigener Anker\n if (!schemaOk('rltp-delivery-document.schema.json', doc)) return null\n if (!C.shaped(doc, { id: 'string', issuer: 'string', recipient: 'string', threadId: 'string', issuedAt: 'string', payload: 'object', proof: 'object' })) return null\n // geschlossene Form + das OPTIONALE ceremony-Feld (Review 19, B-2:\n // „ceremony — OPTIONAL, and entirely unconstrained\"); der MAC läuft\n // über JCS(Dokument ohne proof) und deckt es mit ab\n if (Object.keys(doc).some((k) => !['id', 'type', 'issuer', 'recipient', 'threadId', 'issuedAt', 'payload', 'proof', 'ceremony'].includes(k))) return null\n // — Stufe 7 VOR Stufe 8: das Payload-Schema zuerst\n if (!schemaOk('payload-delivery-ack.schema.json', doc.payload)) return null\n // class rule (4.2/4.4, Stufe 8): EXACTLY the form the acknowledged\n // payload's class selects — signature-class payload → SIGNED ack,\n // designated-verifier payload → MAC ack. Every other combination\n // (MAC on a signature-class payload, signature on a DV payload, a\n // hybrid proof) is invalid\n if (cls === 'signature') {\n if (doc.proof.mac !== undefined || doc.proof.type !== 'DataIntegrityProof' || doc.proof.cryptosuite !== 'eddsa-jcs-2022') return null\n if (!C.calOK(doc.proof.created)) return null\n } else {\n if (Object.keys(doc.proof).length !== 1) return null\n if (typeof doc.proof.mac !== 'string' || doc.proof.proofValue !== undefined) return null\n }\n if (!C.calOK(doc.issuedAt)) return null // Kalender-Validität (Review 12, B-3)\n if (doc.recipient !== contact.channel.own.anchor) return null\n // — Stufe 8: enactment-Profilregel (Review 20, B-2: ein Ack\n // umschließt kein Bindungsmaterial), issuer-Bindung, meaning\n if (doc.ceremony?.enactment !== undefined) return null\n if (doc.issuer !== contactKeyOf(p, contact)) return null\n if (!C.shaped(doc.payload, { ref: 'string', meaning: 'string' }) || doc.payload.meaning !== 'received') return null\n if (cls === 'signature') {\n // the attestation: verifies under the ack's issuer anchor (= the\n // acked document's recipient, our counterpart on the tuple)\n if (!(await C.diVerify(doc, doc.issuer))) return null\n return { ref: doc.payload.ref, threadId: doc.threadId }\n }\n const { proof, ...rest } = doc\n const k = await ackKey(contact.channel.own, contact.channel.counterpartKa, doc.issuer, doc.recipient)\n if ((await hmacU(k, jcs(rest))) !== proof.mac) return null\n return { ref: doc.payload.ref, threadId: doc.threadId }\n } catch { return null }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"continuity.d.ts","sourceRoot":"","sources":["../../src/probe/continuity.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,CAAC,MAAM,WAAW,CAAA;AAC9B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAoBvC,eAAO,MAAM,cAAc,GAAI,GAAG,MAAM;;;CAGtC,CAAA;AAOF,wBAAsB,UAAU,CAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,GAAQ;;;;YA0DvF;
|
|
1
|
+
{"version":3,"file":"continuity.d.ts","sourceRoot":"","sources":["../../src/probe/continuity.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,CAAC,MAAM,WAAW,CAAA;AAC9B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAoBvC,eAAO,MAAM,cAAc,GAAI,GAAG,MAAM;;;CAGtC,CAAA;AAOF,wBAAsB,UAAU,CAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,GAAQ;;;;YA0DvF;AA8ID,wBAAsB,iBAAiB,CAAE,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,GAAQ,gBAwDxF;AAmQD;;;;;GAKG;AACH,wBAAsB,eAAe,CAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,GAAQ,gBAgF5F"}
|
package/dist/probe/continuity.js
CHANGED
|
@@ -174,10 +174,19 @@ function chainTuple(p, newKey, oldKey, when) {
|
|
|
174
174
|
old.deactivated = true;
|
|
175
175
|
old.chainedInto = newKey;
|
|
176
176
|
head.chain = [...(old.chain ?? []), oldKey];
|
|
177
|
+
// Zustands-Vorrang entlang der Kette (Encounter 4.2, „evidence accumulates
|
|
178
|
+
// on the relationship through its chain"): ✓ > Zeremonie-Richtung (→/←)
|
|
179
|
+
// > Vorstellung (⇄). Eine einseitige Zeremonie ist stärker als eine
|
|
180
|
+
// Vorstellung — der Kopf verliert seine Richtung nicht an ein ⇄
|
|
177
181
|
if (old.state === '✓' || head.state === '✓') {
|
|
178
182
|
head.state = '✓';
|
|
179
183
|
head.provenance = 'ceremony';
|
|
180
184
|
}
|
|
185
|
+
else if (head.state === '→' || head.state === '←') { /* die Richtung des Kopfes bleibt */ }
|
|
186
|
+
else if (old.state === '→' || old.state === '←') {
|
|
187
|
+
head.state = old.state;
|
|
188
|
+
head.provenance = 'ceremony';
|
|
189
|
+
}
|
|
181
190
|
else if (old.state === '⇄' || head.state === '⇄')
|
|
182
191
|
head.state = '⇄';
|
|
183
192
|
head.since = [old.since, head.since].filter(Boolean).sort()[0];
|
|
@@ -500,8 +509,15 @@ async function handleProbe(p, { key, t }, artifact, threadId, when, ent, mkAck,
|
|
|
500
509
|
}
|
|
501
510
|
}
|
|
502
511
|
else {
|
|
503
|
-
// Nicht-Record: Match-Report (löst NIE eine Kette aus)
|
|
504
|
-
|
|
512
|
+
// Nicht-Record: Match-Report (löst NIE eine Kette aus). Ist die
|
|
513
|
+
// Record-Wahl auf diesem Tupel schon verifiziert, ist die Report-
|
|
514
|
+
// Pflicht GESTORBEN (6a.3) — eine späte Probe der Record-Seite erzeugt
|
|
515
|
+
// keinen Report mehr: „a match report flushed after the choice is a
|
|
516
|
+
// stale counter-claim that MUST NOT be sent". Ohne diese Schranke
|
|
517
|
+
// entstand ein nie retirebarer Eintrag, den jeder Flush byte-identisch
|
|
518
|
+
// erneut sandte (Gesamtsimulator, 06.09.2026: Endlos-Retry nach der
|
|
519
|
+
// gegenseitigen Verifikation)
|
|
520
|
+
if (!t.contReported && !t.contRecordPrior) {
|
|
505
521
|
t.contReported = matches[0];
|
|
506
522
|
try {
|
|
507
523
|
outbound.push(await buildMapping(p, key, matches[0], when, ent));
|
|
@@ -698,6 +714,12 @@ export async function flushContinuity(p, newKey, when, ent = {}) {
|
|
|
698
714
|
// with freshly sampled padding" (Review 5, B-3): stale Einträge
|
|
699
715
|
// werden RETIRED (Ack-Ref bleibt, Review 6, B-3), EINE frische
|
|
700
716
|
// Probe ersetzt sie (Bau nach der Lock-Sektion)
|
|
717
|
+
// ein Report nach verifizierter Record-Wahl ist tot (6a.3) — auch wenn
|
|
718
|
+
// er der Wahl zuvorkam, aber erst danach in die Outbox gelangte
|
|
719
|
+
if (t.contRecordPrior)
|
|
720
|
+
for (const o of (t.outbox ?? new Map()).values())
|
|
721
|
+
if (o.kind === 'continuity-mapping' && o.duty !== 'align')
|
|
722
|
+
o.retired = true;
|
|
701
723
|
const retries = [...(t.outbox ?? new Map()).values()]
|
|
702
724
|
.filter((o) => o.kind === 'continuity-mapping' && !o.retired)
|
|
703
725
|
.map((o) => ({ to: t, kind: o.kind + '/0.1 (Retry, byte-identisch)', env: o.env }));
|