@real-life/trust-protocol 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +187 -78
  3. package/dist/ack.d.ts +84 -0
  4. package/dist/ack.d.ts.map +1 -0
  5. package/dist/ack.js +114 -0
  6. package/dist/ack.js.map +1 -0
  7. package/dist/adapters/vti-mediator.d.ts +154 -0
  8. package/dist/adapters/vti-mediator.d.ts.map +1 -0
  9. package/dist/adapters/vti-mediator.js +621 -0
  10. package/dist/adapters/vti-mediator.js.map +1 -0
  11. package/dist/anchor.d.ts +226 -0
  12. package/dist/anchor.d.ts.map +1 -0
  13. package/dist/anchor.js +347 -0
  14. package/dist/anchor.js.map +1 -0
  15. package/dist/{holder.d.ts → carrier-holder.d.ts} +1 -1
  16. package/dist/carrier-holder.d.ts.map +1 -0
  17. package/dist/{holder.js → carrier-holder.js} +5 -4
  18. package/dist/carrier-holder.js.map +1 -0
  19. package/dist/carrier-identity.js +4 -4
  20. package/dist/carrier-identity.js.map +1 -1
  21. package/dist/carrier.d.ts.map +1 -1
  22. package/dist/carrier.js +4 -3
  23. package/dist/carrier.js.map +1 -1
  24. package/dist/ceremony.d.ts +3 -2
  25. package/dist/ceremony.d.ts.map +1 -1
  26. package/dist/ceremony.js +16 -26
  27. package/dist/ceremony.js.map +1 -1
  28. package/dist/codec.d.ts +46 -0
  29. package/dist/codec.d.ts.map +1 -0
  30. package/dist/codec.js +410 -0
  31. package/dist/codec.js.map +1 -0
  32. package/dist/continuity.d.ts +67 -0
  33. package/dist/continuity.d.ts.map +1 -0
  34. package/dist/continuity.js +110 -0
  35. package/dist/continuity.js.map +1 -0
  36. package/dist/core.d.ts +4 -0
  37. package/dist/core.d.ts.map +1 -1
  38. package/dist/core.js.map +1 -1
  39. package/dist/crypto.d.ts +23 -7
  40. package/dist/crypto.d.ts.map +1 -1
  41. package/dist/crypto.js +54 -20
  42. package/dist/crypto.js.map +1 -1
  43. package/dist/delivery.d.ts +31 -3
  44. package/dist/delivery.d.ts.map +1 -1
  45. package/dist/delivery.js +75 -28
  46. package/dist/delivery.js.map +1 -1
  47. package/dist/encounter/ceremony.d.ts +37 -0
  48. package/dist/encounter/ceremony.d.ts.map +1 -0
  49. package/dist/encounter/ceremony.js +662 -0
  50. package/dist/encounter/ceremony.js.map +1 -0
  51. package/dist/encounter.d.ts +91 -1
  52. package/dist/encounter.d.ts.map +1 -1
  53. package/dist/encounter.js +191 -12
  54. package/dist/encounter.js.map +1 -1
  55. package/dist/engine.d.ts +291 -0
  56. package/dist/engine.d.ts.map +1 -0
  57. package/dist/engine.js +1395 -0
  58. package/dist/engine.js.map +1 -0
  59. package/dist/entropy.d.ts +28 -0
  60. package/dist/entropy.d.ts.map +1 -0
  61. package/dist/entropy.js +96 -0
  62. package/dist/entropy.js.map +1 -0
  63. package/dist/events.d.ts +177 -0
  64. package/dist/events.d.ts.map +1 -0
  65. package/dist/events.js +2 -0
  66. package/dist/events.js.map +1 -0
  67. package/dist/fixtures.d.ts +30 -0
  68. package/dist/fixtures.d.ts.map +1 -0
  69. package/dist/fixtures.js +155 -0
  70. package/dist/fixtures.js.map +1 -0
  71. package/dist/forge.d.ts +47 -0
  72. package/dist/forge.d.ts.map +1 -0
  73. package/dist/forge.js +20 -0
  74. package/dist/forge.js.map +1 -0
  75. package/dist/group-star.d.ts +251 -0
  76. package/dist/group-star.d.ts.map +1 -0
  77. package/dist/group-star.js +348 -0
  78. package/dist/group-star.js.map +1 -0
  79. package/dist/holder-api.d.ts +137 -0
  80. package/dist/holder-api.d.ts.map +1 -0
  81. package/dist/holder-api.js +132 -0
  82. package/dist/holder-api.js.map +1 -0
  83. package/dist/holder-state-v1.d.ts +801 -0
  84. package/dist/holder-state-v1.d.ts.map +1 -0
  85. package/dist/holder-state-v1.js +2 -0
  86. package/dist/holder-state-v1.js.map +1 -0
  87. package/dist/identity-state.d.ts +43 -0
  88. package/dist/identity-state.d.ts.map +1 -0
  89. package/dist/identity-state.js +345 -0
  90. package/dist/identity-state.js.map +1 -0
  91. package/dist/identity.d.ts +24 -2
  92. package/dist/identity.d.ts.map +1 -1
  93. package/dist/identity.js +70 -11
  94. package/dist/identity.js.map +1 -1
  95. package/dist/index.d.ts +26 -1
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js +77 -29
  98. package/dist/index.js.map +1 -1
  99. package/dist/internal.d.ts +36 -0
  100. package/dist/internal.d.ts.map +1 -0
  101. package/dist/internal.js +22 -0
  102. package/dist/internal.js.map +1 -0
  103. package/dist/introduction/holder.d.ts +18 -0
  104. package/dist/introduction/holder.d.ts.map +1 -0
  105. package/dist/introduction/holder.js +757 -0
  106. package/dist/introduction/holder.js.map +1 -0
  107. package/dist/introduction.d.ts +101 -0
  108. package/dist/introduction.d.ts.map +1 -0
  109. package/dist/introduction.js +132 -0
  110. package/dist/introduction.js.map +1 -0
  111. package/dist/invariants.d.ts +43 -0
  112. package/dist/invariants.d.ts.map +1 -0
  113. package/dist/invariants.js +883 -0
  114. package/dist/invariants.js.map +1 -0
  115. package/dist/keys-seed.d.ts +7 -0
  116. package/dist/keys-seed.d.ts.map +1 -0
  117. package/dist/keys-seed.js +133 -0
  118. package/dist/keys-seed.js.map +1 -0
  119. package/dist/log-memory.d.ts +12 -0
  120. package/dist/log-memory.d.ts.map +1 -0
  121. package/dist/log-memory.js +101 -0
  122. package/dist/log-memory.js.map +1 -0
  123. package/dist/membership/holder.d.ts +35 -0
  124. package/dist/membership/holder.d.ts.map +1 -0
  125. package/dist/membership/holder.js +852 -0
  126. package/dist/membership/holder.js.map +1 -0
  127. package/dist/membership.d.ts +92 -0
  128. package/dist/membership.d.ts.map +1 -0
  129. package/dist/membership.js +157 -0
  130. package/dist/membership.js.map +1 -0
  131. package/dist/ports.d.ts +237 -0
  132. package/dist/ports.d.ts.map +1 -0
  133. package/dist/ports.js +2 -0
  134. package/dist/ports.js.map +1 -0
  135. package/dist/profile.d.ts +56 -0
  136. package/dist/profile.d.ts.map +1 -0
  137. package/dist/profile.js +193 -0
  138. package/dist/profile.js.map +1 -0
  139. package/dist/prompts.d.ts +14 -0
  140. package/dist/prompts.d.ts.map +1 -0
  141. package/dist/prompts.js +69 -0
  142. package/dist/prompts.js.map +1 -0
  143. package/dist/receive.d.ts +133 -0
  144. package/dist/receive.d.ts.map +1 -0
  145. package/dist/receive.js +298 -0
  146. package/dist/receive.js.map +1 -0
  147. package/dist/results.d.ts +158 -0
  148. package/dist/results.d.ts.map +1 -0
  149. package/dist/results.js +21 -0
  150. package/dist/results.js.map +1 -0
  151. package/dist/schemas.d.ts.map +1 -1
  152. package/dist/schemas.js +42 -38
  153. package/dist/schemas.js.map +1 -1
  154. package/dist/sha256.d.ts +3 -0
  155. package/dist/sha256.d.ts.map +1 -0
  156. package/dist/sha256.js +69 -0
  157. package/dist/sha256.js.map +1 -0
  158. package/dist/star.d.ts +31 -0
  159. package/dist/star.d.ts.map +1 -0
  160. package/dist/star.js +56 -0
  161. package/dist/star.js.map +1 -0
  162. package/dist/state-builder.d.ts +42 -0
  163. package/dist/state-builder.d.ts.map +1 -0
  164. package/dist/state-builder.js +100 -0
  165. package/dist/state-builder.js.map +1 -0
  166. package/dist/state.d.ts +853 -0
  167. package/dist/state.d.ts.map +1 -0
  168. package/dist/state.js +36 -0
  169. package/dist/state.js.map +1 -0
  170. package/dist/store-contract.d.ts +11 -0
  171. package/dist/store-contract.d.ts.map +1 -0
  172. package/dist/store-contract.js +189 -0
  173. package/dist/store-contract.js.map +1 -0
  174. package/dist/store-memory.d.ts +8 -0
  175. package/dist/store-memory.d.ts.map +1 -0
  176. package/dist/store-memory.js +17 -0
  177. package/dist/store-memory.js.map +1 -0
  178. package/dist/testing.d.ts +22 -0
  179. package/dist/testing.d.ts.map +1 -0
  180. package/dist/testing.js +21 -0
  181. package/dist/testing.js.map +1 -0
  182. package/dist/trust/continuity.d.ts +71 -0
  183. package/dist/trust/continuity.d.ts.map +1 -0
  184. package/dist/trust/continuity.js +1216 -0
  185. package/dist/trust/continuity.js.map +1 -0
  186. package/dist/trust/duties.d.ts +67 -0
  187. package/dist/trust/duties.d.ts.map +1 -0
  188. package/dist/trust/duties.js +179 -0
  189. package/dist/trust/duties.js.map +1 -0
  190. package/dist/trust/entries.d.ts +139 -0
  191. package/dist/trust/entries.d.ts.map +1 -0
  192. package/dist/trust/entries.js +694 -0
  193. package/dist/trust/entries.js.map +1 -0
  194. package/dist/trust/group-star.d.ts +43 -0
  195. package/dist/trust/group-star.d.ts.map +1 -0
  196. package/dist/trust/group-star.js +188 -0
  197. package/dist/trust/group-star.js.map +1 -0
  198. package/dist/trust/mapping.d.ts +56 -0
  199. package/dist/trust/mapping.d.ts.map +1 -0
  200. package/dist/trust/mapping.js +584 -0
  201. package/dist/trust/mapping.js.map +1 -0
  202. package/dist/trust/profile.d.ts +25 -0
  203. package/dist/trust/profile.d.ts.map +1 -0
  204. package/dist/trust/profile.js +249 -0
  205. package/dist/trust/profile.js.map +1 -0
  206. package/dist/trust/star.d.ts +208 -0
  207. package/dist/trust/star.d.ts.map +1 -0
  208. package/dist/trust/star.js +588 -0
  209. package/dist/trust/star.js.map +1 -0
  210. package/dist/trust/state.d.ts +83 -0
  211. package/dist/trust/state.d.ts.map +1 -0
  212. package/dist/trust/state.js +154 -0
  213. package/dist/trust/state.js.map +1 -0
  214. package/dist/util-freeze.d.ts +3 -0
  215. package/dist/util-freeze.d.ts.map +1 -0
  216. package/dist/util-freeze.js +11 -0
  217. package/dist/util-freeze.js.map +1 -0
  218. package/dist/views.d.ts +147 -0
  219. package/dist/views.d.ts.map +1 -0
  220. package/dist/views.js +268 -0
  221. package/dist/views.js.map +1 -0
  222. package/dist/visibility.d.ts +5 -5
  223. package/dist/visibility.d.ts.map +1 -1
  224. package/dist/visibility.js +22 -28
  225. package/dist/visibility.js.map +1 -1
  226. package/dist/wire.d.ts +178 -84
  227. package/dist/wire.d.ts.map +1 -1
  228. package/dist/wire.js.map +1 -1
  229. package/package.json +56 -10
  230. package/schemas/holder-state-v1.schema.json +3880 -0
  231. package/dist/holder.d.ts.map +0 -1
  232. package/dist/holder.js.map +0 -1
  233. package/dist/probe/acks.d.ts +0 -27
  234. package/dist/probe/acks.d.ts.map +0 -1
  235. package/dist/probe/acks.js +0 -152
  236. package/dist/probe/acks.js.map +0 -1
  237. package/dist/probe/continuity.d.ts +0 -20
  238. package/dist/probe/continuity.d.ts.map +0 -1
  239. package/dist/probe/continuity.js +0 -805
  240. package/dist/probe/continuity.js.map +0 -1
  241. package/dist/probe/deps.d.ts +0 -61
  242. package/dist/probe/deps.d.ts.map +0 -1
  243. package/dist/probe/deps.js +0 -54
  244. package/dist/probe/deps.js.map +0 -1
  245. package/dist/probe/encounter.d.ts +0 -26
  246. package/dist/probe/encounter.d.ts.map +0 -1
  247. package/dist/probe/encounter.js +0 -938
  248. package/dist/probe/encounter.js.map +0 -1
  249. package/dist/probe/introduce.d.ts +0 -62
  250. package/dist/probe/introduce.d.ts.map +0 -1
  251. package/dist/probe/introduce.js +0 -306
  252. package/dist/probe/introduce.js.map +0 -1
  253. package/dist/probe/membership.d.ts +0 -96
  254. package/dist/probe/membership.d.ts.map +0 -1
  255. package/dist/probe/membership.js +0 -467
  256. package/dist/probe/membership.js.map +0 -1
  257. package/dist/probe/trust.d.ts +0 -156
  258. package/dist/probe/trust.d.ts.map +0 -1
  259. package/dist/probe/trust.js +0 -1233
  260. package/dist/probe/trust.js.map +0 -1
  261. package/dist/probe.d.ts +0 -7
  262. package/dist/probe.d.ts.map +0 -1
  263. package/dist/probe.js +0 -42
  264. package/dist/probe.js.map +0 -1
package/dist/anchor.js ADDED
@@ -0,0 +1,347 @@
1
+ // anchor — the community anchor toward a contact (Trust Layer 0.31
2
+ // §6.1–§6.5, Identity 0.54 §5.4): self-card@2, anchor-rotation@2, the
3
+ // pre-rotation binding, the lineage, anchor-mapping@4 and what a changed
4
+ // `self` means.
5
+ //
6
+ // Pure constructions: no state, no transport. The holder's trust module
7
+ // (trust/mapping.ts) builds and verifies over its KeyProvider, through the
8
+ // agreement-based forms (assembleAnchorMapping, verifyAnchorMappingWith);
9
+ // the Context-based forms (buildAnchorMapping, verifyAnchorMapping) serve
10
+ // vectors, generators and tests.
11
+ // Every function takes an optional SubtleCrypto (the holder's resolved
12
+ // handle); without one it uses the platform's at call time.
13
+ //
14
+ // · the binding (Identity 5.4) — commit(g) = the sha2-256 multihash
15
+ // over the 34 multikey bytes 0xed 0x01 ‖ pk of generation g, in the
16
+ // `u` digest encoding (bindingOf). Generation g commits to g + 1
17
+ // before g is in use; a successor its predecessor's binding does not
18
+ // admit is no successor.
19
+ // · self-card@2 — { body: { type, anchor, keyAgreement, commit },
20
+ // proof: { proofValue } }: the card of generation g carries the
21
+ // binding to g + 1.
22
+ // · anchor-rotation@2 — { body: { type, prev, next, commit }, proof: {
23
+ // proofValue (raw Ed25519 under prev), successorProofValue (raw
24
+ // Ed25519 under next) } }, both over JCS(body). `next` is generation
25
+ // g + 1 of the same digest, `commit` the binding of `next` (to g + 2).
26
+ // The order is prev/next alone, no number. Toward a relationship that
27
+ // holds the binding of prev it proves that next is the one successor
28
+ // prev was bound to; otherwise only the joint authorization.
29
+ // · lineage — at most the LINEAGE_MAX most recent links, in chain
30
+ // order, ending at self; empty = the sender presents no history.
31
+ // · anchor-mapping@4 — { type, pair, self, to, card, lineage, revision,
32
+ // issuedAt }; `self` is the current anchor, the card is under it,
33
+ // mac2 is under its X key. 6.3 in order: 1 schema · 2 to · 3 pair ·
34
+ // 4 card · 4a lineage chain · 4b pre-rotation · 5 card.anchor = self ·
35
+ // 6 k2 from the card · 7 both MACs.
36
+ // · classification (§6.3 condition 8) — a changed `self` is a ROTATION
37
+ // when the previously held `self` is the `prev` of an element of the
38
+ // carried segment (6160), otherwise the mapping is REJECTED (6170).
39
+ // · mappingAnchors / mappingBindings — the verified anchor set of a
40
+ // mapping (self and every anchor of its lineage) and the pre-rotation
41
+ // bindings it states (6610); the convergence net merges two
42
+ // relationships whose sets meet, under the head rule and the binding
43
+ // rule (§6a.1).
44
+ import { jcs, makeValidator, calOK } from './core.js';
45
+ import { SCHEMAS } from './schemas.js';
46
+ import { base58, fromBase58, edRawOfAnchor, xRawOfMk, ecdh, hkdf, b64uOf, digestBytes } from './crypto.js';
47
+ import { communityLabel } from './identity.js';
48
+ import { platformSubtle } from './crypto.js';
49
+ const te = new TextEncoder();
50
+ const S = platformSubtle;
51
+ const VAL = makeValidator(SCHEMAS);
52
+ const schemaOk = (file, data) => VAL.validate(data, SCHEMAS[file], SCHEMAS[file]).length === 0;
53
+ /** HMAC-SHA-256 over the UTF-8 bytes of msg, in the mac encoding (`u` + base64url). */
54
+ export async function macU(keyBytes, msg, subtle = S()) {
55
+ const k = await subtle.importKey('raw', keyBytes, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
56
+ return 'u' + b64uOf(new Uint8Array(await subtle.sign('HMAC', k, te.encode(msg))));
57
+ }
58
+ /** Raw Ed25519 over JCS(body), `z` + base58btc — the abbreviated proof form of Trust §2.1 (no DI suite). */
59
+ export async function signRaw(ctx, body, subtle = S()) {
60
+ return 'z' + base58(new Uint8Array(await subtle.sign({ name: 'Ed25519' }, ctx.ed.priv, te.encode(jcs(body)))));
61
+ }
62
+ /** The raw proofValue form of an Ed25519 signature: `z` + base58btc (Trust §2.1). */
63
+ export const rawProofValue = (sig) => 'z' + base58(sig);
64
+ /** Verifies a raw Ed25519 proofValue over JCS(body) under a did:key anchor: exactly 64 bytes, canonical base58btc. */
65
+ export async function verifyRaw(did, body, proofValue, subtle) {
66
+ try {
67
+ if (typeof proofValue !== 'string' || proofValue[0] !== 'z')
68
+ return false;
69
+ const raw = edRawOfAnchor(did);
70
+ const sig = fromBase58(proofValue.slice(1));
71
+ if (!raw || !sig || sig.length !== 64 || 'z' + base58(sig) !== proofValue)
72
+ return false;
73
+ const Sx = subtle ?? S();
74
+ const key = await Sx.importKey('raw', raw, { name: 'Ed25519' }, false, ['verify']);
75
+ return await Sx.verify({ name: 'Ed25519' }, key, sig, te.encode(jcs(body)));
76
+ }
77
+ catch {
78
+ return false;
79
+ }
80
+ }
81
+ // ── the pre-rotation binding (Identity §5.4) ────────────────────────────
82
+ /**
83
+ * The binding of an Ed25519 anchor: `u` + base64url of the sha2-256
84
+ * multihash (0x12 0x20 ‖ SHA-256) over its 34 multikey bytes 0xed 0x01 ‖
85
+ * pk — exactly the bytes the did:key identifier encodes.
86
+ */
87
+ export async function bindingOf(anchor, subtle) {
88
+ const raw = edRawOfAnchor(anchor);
89
+ if (!raw || raw.length !== 32)
90
+ throw new Error('not an Ed25519 did:key anchor');
91
+ const mk = new Uint8Array(34);
92
+ mk[0] = 0xed;
93
+ mk[1] = 0x01;
94
+ mk.set(raw, 2);
95
+ return digestBytes(mk, subtle);
96
+ }
97
+ /** Whether `anchor` meets the binding `commit`. */
98
+ export const meetsBinding = async (anchor, commit, subtle) => {
99
+ try {
100
+ return typeof commit === 'string' && (await bindingOf(anchor, subtle)) === commit;
101
+ }
102
+ catch {
103
+ return false;
104
+ }
105
+ };
106
+ // the generation of a community-anchor label (Identity §5.4, §6.1):
107
+ // group/<D> is generation 1, group/<D>/<g> generation g
108
+ const generationOf = (label) => {
109
+ const m = /^group\/([^/]+)(?:\/([1-9][0-9]*))?$/.exec(label);
110
+ if (!m)
111
+ return null;
112
+ const generation = m[2] === undefined ? 1 : Number(m[2]);
113
+ return Number.isSafeInteger(generation) ? { digest: m[1], generation } : null;
114
+ };
115
+ // `next` is generation g + 1 of the digest of `prev` (Trust 6330)
116
+ const isSuccessor = (prev, next) => {
117
+ const g = generationOf(prev.label);
118
+ if (!g || g.generation >= Number.MAX_SAFE_INTEGER)
119
+ return false;
120
+ return next.label === communityLabel(g.digest, g.generation + 1);
121
+ };
122
+ // ── self-card@2 (§6.2) ──────────────────────────────────────────────────
123
+ /**
124
+ * self-card@2 of a community-anchor context: its anchor, key-agreement
125
+ * key and the binding to `nextGen`, the generation after it; signed raw
126
+ * under the anchor.
127
+ */
128
+ export async function makeSelfCard(self, nextGen, subtle) {
129
+ if (!isSuccessor(self, nextGen))
130
+ throw new Error('self-card@2: nextGen is not the generation after the anchor (Identity §5.4)');
131
+ const body = { type: 'self-card@2', anchor: self.anchor, keyAgreement: self.keyAgreement, commit: await bindingOf(nextGen.anchor, subtle) };
132
+ return { body, proof: { proofValue: await signRaw(self, body, subtle) } };
133
+ }
134
+ // ── anchor-rotation@2 (§6.5) ────────────────────────────────────────────
135
+ /**
136
+ * The link from the current community anchor (prev) to the next
137
+ * generation of the same digest (next), carrying the binding of next to
138
+ * the generation after it (after): both contexts sign the same canonical
139
+ * body. A rotation moves to exactly g + 1 (Trust 6330, Identity §5.4).
140
+ */
141
+ export async function makeAnchorRotation(prev, next, after, subtle) {
142
+ if (prev.anchor === next.anchor)
143
+ throw new Error('anchor-rotation@2: next equals prev (Trust §6.5)');
144
+ if (!isSuccessor(prev, next))
145
+ throw new Error('anchor-rotation@2: next is not the next generation of the same digest (Trust 6330)');
146
+ if (!isSuccessor(next, after))
147
+ throw new Error('anchor-rotation@2: commit must bind the generation after next (Trust 6330)');
148
+ const body = { type: 'anchor-rotation@2', prev: prev.anchor, next: next.anchor, commit: await bindingOf(after.anchor, subtle) };
149
+ return { body, proof: { proofValue: await signRaw(prev, body, subtle), successorProofValue: await signRaw(next, body, subtle) } };
150
+ }
151
+ /**
152
+ * Schema, next ≠ prev, and both signatures — prev's and next's — over
153
+ * the canonical body; with `heldBinding` (the binding held for prev),
154
+ * also that next meets it (§6.3 condition 4b).
155
+ */
156
+ export async function verifyAnchorRotation(a, heldBinding, subtle) {
157
+ if (!schemaOk('visibility-anchor-rotation.schema.json', a))
158
+ return false;
159
+ if (a.body.prev === a.body.next)
160
+ return false;
161
+ if (!((await verifyRaw(a.body.prev, a.body, a.proof.proofValue, subtle))
162
+ && (await verifyRaw(a.body.next, a.body, a.proof.successorProofValue, subtle))))
163
+ return false;
164
+ return heldBinding === undefined || meetsBinding(a.body.next, heldBinding, subtle);
165
+ }
166
+ // ── the lineage (§6.3 condition 4a) ─────────────────────────────────────
167
+ /** A mapping carries at most this many of the most recent links (§6.1; schema maxItems). */
168
+ export const LINEAGE_MAX = 64;
169
+ /**
170
+ * Condition 4a, the chain as given: at most LINEAGE_MAX elements; every
171
+ * element verifies under both its signatures; each prev equals the
172
+ * preceding element's next; the last next equals self. An empty lineage
173
+ * passes: the sender presents no history. The bindings are condition 4b
174
+ * (verifyBindings).
175
+ */
176
+ export async function verifyLineage(lineage, self, subtle) {
177
+ if (!Array.isArray(lineage))
178
+ return { ok: false, reason: 'lineage is not an array' };
179
+ if (lineage.length > LINEAGE_MAX)
180
+ return { ok: false, reason: `more than ${LINEAGE_MAX} elements` };
181
+ for (const [i, r] of lineage.entries()) {
182
+ if (!(await verifyAnchorRotation(r, undefined, subtle)))
183
+ return { ok: false, reason: `element ${i}: anchor-rotation@2 does not verify under both signatures` };
184
+ if (i > 0 && r.body.prev !== lineage[i - 1].body.next)
185
+ return { ok: false, reason: `element ${i}: prev is not the preceding next` };
186
+ }
187
+ if (lineage.length && lineage[lineage.length - 1].body.next !== self)
188
+ return { ok: false, reason: 'the last next is not self' };
189
+ return { ok: true };
190
+ }
191
+ /**
192
+ * Condition 4b, pre-rotation (Trust 6115): each element after the first
193
+ * names a next that meets the commit of the element before it; where the
194
+ * lineage is not empty, card.commit equals the commit of its last
195
+ * element; and for every anchor for which the relationship holds a
196
+ * binding (`held`, 6610), an element whose prev is that anchor names a
197
+ * next that meets it, and a card whose anchor is that anchor carries it
198
+ * as commit.
199
+ */
200
+ export async function verifyBindings(body, held, subtle) {
201
+ const L = body.lineage;
202
+ for (const [i, r] of L.entries()) {
203
+ if (i > 0 && !(await meetsBinding(r.body.next, L[i - 1].body.commit, subtle)))
204
+ return { ok: false, reason: `element ${i}: next does not meet the commit of the element before it`, rule: 'RLTP-TRU-6115' };
205
+ const h = held?.get(r.body.prev);
206
+ if (h !== undefined && !(await meetsBinding(r.body.next, h, subtle)))
207
+ return { ok: false, reason: `element ${i}: next does not meet the binding held for its prev`, rule: 'RLTP-TRU-6118' };
208
+ }
209
+ if (L.length && body.card.body.commit !== L[L.length - 1].body.commit)
210
+ return { ok: false, reason: 'card.commit is not the commit of the last element', rule: 'RLTP-TRU-6117' };
211
+ const hc = held?.get(body.card.body.anchor);
212
+ if (hc !== undefined && body.card.body.commit !== hc)
213
+ return { ok: false, reason: 'the card states another binding than the one held for its anchor', rule: 'RLTP-TRU-6118' };
214
+ return { ok: true };
215
+ }
216
+ /** Every anchor a lineage names, in chain order: the first prev, then each next. */
217
+ export const lineageAnchors = (lineage) => lineage.length ? [lineage[0].body.prev, ...lineage.map((r) => r.body.next)] : [];
218
+ /**
219
+ * The verified anchor set of a mapping (§6a.1 rung 2): its self and every
220
+ * anchor of its carried lineage, in chain order, self last. Two
221
+ * relationships converge when these sets meet.
222
+ */
223
+ export const mappingAnchors = (body) => body.lineage.length ? lineageAnchors(body.lineage) : [body.self];
224
+ /** The links prev → next a lineage carries, in chain order. */
225
+ export const lineageLinks = (lineage) => lineage.map((r) => [r.body.prev, r.body.next]);
226
+ /**
227
+ * The pre-rotation bindings a verified mapping states (Trust 6610): the
228
+ * commit of each lineage element as the binding of its next, card.commit
229
+ * as the binding of self, and, for the prev of each link, the binding
230
+ * computed over that link's next.
231
+ */
232
+ export async function mappingBindings(body, subtle) {
233
+ const out = new Map();
234
+ for (const r of body.lineage) {
235
+ out.set(r.body.prev, await bindingOf(r.body.next, subtle));
236
+ out.set(r.body.next, r.body.commit);
237
+ }
238
+ out.set(body.self, body.card.body.commit);
239
+ return out;
240
+ }
241
+ /**
242
+ * §6.3 condition 8 against the `self` this relationship holds (6150):
243
+ * 'first' where it holds none, 'same' where `self` is unchanged,
244
+ * 'rotation' where a changed `self` comes with a carried segment that
245
+ * has the held self as the `prev` of one of its elements (6160), and
246
+ * 'rejected' otherwise (6170): a change of `self` that no carried segment
247
+ * links to the held one is rejected like every mapping that fails a
248
+ * condition, with the current state kept — also after more than 64
249
+ * missed rotations (6400). Condition 4b has already refused a segment
250
+ * that names another successor of an anchor whose binding the
251
+ * relationship holds.
252
+ */
253
+ export function classifyMapping(heldSelf, body) {
254
+ if (heldSelf === undefined)
255
+ return 'first';
256
+ if (heldSelf === body.self)
257
+ return 'same';
258
+ return body.lineage.some((r) => r.body.prev === heldSelf) ? 'rotation' : 'rejected';
259
+ }
260
+ /** The two MACs of an anchor-mapping@4 over JCS(body) (Trust 6030), from
261
+ * the two shared secrets: sh1 = ECDH(pairX of the sender, pairX of the
262
+ * addressee), sh2 = ECDH(selfX of the sender, pairX of the addressee). */
263
+ export async function assembleAnchorMapping(body, sh1, sh2, subtle) {
264
+ const msg = jcs(body);
265
+ return { body, proof: {
266
+ mac1: await macU(await hkdf(sh1, 'rltp/visibility/mac/map1', 32, subtle), msg, subtle),
267
+ mac2: await macU(await hkdf(sh2, 'rltp/visibility/mac/map2', 32, subtle), msg, subtle),
268
+ } };
269
+ }
270
+ /** anchor-mapping@4: body { type, pair, self, to, card, lineage, revision, issuedAt }; mac1 (relationship key, map1) and mac2 (selfX × pairX of the addressee, map2) over JCS(body). */
271
+ export async function buildAnchorMapping(i, subtle) {
272
+ const card = await makeSelfCard(i.self, i.nextGen, subtle);
273
+ const body = { type: 'anchor-mapping@4', pair: i.pair.anchor, self: i.self.anchor, to: i.to, card, lineage: i.lineage, revision: i.revision, issuedAt: i.issuedAt };
274
+ const theirX = xRawOfMk(i.toKeyAgreement);
275
+ if (!theirX)
276
+ throw new Error('addressee key agreement is not a multikey');
277
+ return assembleAnchorMapping(body, await ecdh(i.pair.x.priv, theirX, subtle), await ecdh(i.self.x.priv, theirX, subtle), subtle);
278
+ }
279
+ /** §6.3 conditions 1–7 as numbered by verifyAnchorMapping, with the rule
280
+ * each one is; for 4b the result's `rule` names the one of 6115, 6117,
281
+ * 6118 that failed. */
282
+ export const MAPPING_CONDITION_RULE = Object.freeze({
283
+ 1: 'RLTP-TRU-6070', 2: 'RLTP-TRU-6080', 3: 'RLTP-TRU-6090', 4: 'RLTP-TRU-6100', '4a': 'RLTP-TRU-6110',
284
+ '4b': 'RLTP-TRU-6118', 5: 'RLTP-TRU-6120', 6: 'RLTP-TRU-6130', 7: 'RLTP-TRU-6140',
285
+ });
286
+ /**
287
+ * §6.3, the closed list, evaluated in its order: 1 schema (anchor-mapping
288
+ * @1 to @3 are not implemented and fail here) · 2 to = own pair anchor ·
289
+ * 3 pair = the arrival tuple's counterpart · 4 the card verifies under
290
+ * its own anchor · 4a the lineage chain · 4b pre-rotation, against the
291
+ * bindings this relationship holds (`held`, 6610) · 5 card.anchor = self ·
292
+ * 6 k2 from card.keyAgreement · 7 both MACs. Revision (8) is the
293
+ * holder's state. The addressee's own pair key acts through `agree`: the
294
+ * raw X25519 shared secret with a raw public key, or null where none is
295
+ * usable (condition 7); a throw is a failure of condition 1, as in
296
+ * verifyAnchorMapping.
297
+ */
298
+ export async function verifyAnchorMappingWith(m, at, subtle) {
299
+ try {
300
+ if (!schemaOk('visibility-anchor-mapping.schema.json', m))
301
+ return { ok: false, step: '1' };
302
+ const b = m.body;
303
+ if (!calOK(b.issuedAt))
304
+ return { ok: false, step: '1' }; // calendar validity belongs to the parse level
305
+ if (b.to !== at.ownAnchor)
306
+ return { ok: false, step: '2' };
307
+ if (b.pair !== at.pair)
308
+ return { ok: false, step: '3' };
309
+ if (!(await verifyRaw(b.card.body.anchor, b.card.body, b.card.proof.proofValue, subtle)))
310
+ return { ok: false, step: '4' };
311
+ if (!(await verifyLineage(b.lineage, b.self, subtle)).ok)
312
+ return { ok: false, step: '4a' };
313
+ const vb = await verifyBindings(b, at.held, subtle);
314
+ if (!vb.ok)
315
+ return { ok: false, step: '4b', rule: vb.rule };
316
+ if (b.card.body.anchor !== b.self)
317
+ return { ok: false, step: '5' };
318
+ const cardX = xRawOfMk(b.card.body.keyAgreement);
319
+ const pairX = xRawOfMk(at.pairKeyAgreement);
320
+ if (!cardX || !pairX)
321
+ return { ok: false, step: '6' };
322
+ const sh2 = await at.agree(cardX);
323
+ const k2 = sh2 && await hkdf(sh2, 'rltp/visibility/mac/map2', 32, subtle);
324
+ const sh1 = await at.agree(pairX);
325
+ if (!sh1 || !sh2 || !k2 || sh1.every((x) => x === 0) || sh2.every((x) => x === 0))
326
+ return { ok: false, step: '7' }; // both ECDH outputs non-zero
327
+ const msg = jcs(b);
328
+ if ((await macU(await hkdf(sh1, 'rltp/visibility/mac/map1', 32, subtle), msg, subtle)) !== m.proof.mac1)
329
+ return { ok: false, step: '7' };
330
+ if ((await macU(k2, msg, subtle)) !== m.proof.mac2)
331
+ return { ok: false, step: '7' };
332
+ return { ok: true };
333
+ }
334
+ catch {
335
+ return { ok: false, step: '1' };
336
+ }
337
+ }
338
+ /** verifyAnchorMappingWith over the addressee's own pair Context; names
339
+ * the failed condition by its step only. */
340
+ export async function verifyAnchorMapping(m, at, subtle) {
341
+ const v = await verifyAnchorMappingWith(m, {
342
+ ownAnchor: at.own?.anchor, pair: at.pair, pairKeyAgreement: at.pairKeyAgreement, held: at.held,
343
+ agree: (theirX) => ecdh(at.own.x.priv, theirX, subtle),
344
+ }, subtle);
345
+ return v.ok ? v : { ok: false, step: v.step };
346
+ }
347
+ //# sourceMappingURL=anchor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anchor.js","sourceRoot":"","sources":["../src/anchor.ts"],"names":[],"mappings":"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","sourcesContent":["// anchor — the community anchor toward a contact (Trust Layer 0.31\n// §6.1–§6.5, Identity 0.54 §5.4): self-card@2, anchor-rotation@2, the\n// pre-rotation binding, the lineage, anchor-mapping@4 and what a changed\n// `self` means.\n//\n// Pure constructions: no state, no transport. The holder's trust module\n// (trust/mapping.ts) builds and verifies over its KeyProvider, through the\n// agreement-based forms (assembleAnchorMapping, verifyAnchorMappingWith);\n// the Context-based forms (buildAnchorMapping, verifyAnchorMapping) serve\n// vectors, generators and tests.\n// Every function takes an optional SubtleCrypto (the holder's resolved\n// handle); without one it uses the platform's at call time.\n//\n// · the binding (Identity 5.4) — commit(g) = the sha2-256 multihash\n// over the 34 multikey bytes 0xed 0x01 ‖ pk of generation g, in the\n// `u` digest encoding (bindingOf). Generation g commits to g + 1\n// before g is in use; a successor its predecessor's binding does not\n// admit is no successor.\n// · self-card@2 — { body: { type, anchor, keyAgreement, commit },\n// proof: { proofValue } }: the card of generation g carries the\n// binding to g + 1.\n// · anchor-rotation@2 — { body: { type, prev, next, commit }, proof: {\n// proofValue (raw Ed25519 under prev), successorProofValue (raw\n// Ed25519 under next) } }, both over JCS(body). `next` is generation\n// g + 1 of the same digest, `commit` the binding of `next` (to g + 2).\n// The order is prev/next alone, no number. Toward a relationship that\n// holds the binding of prev it proves that next is the one successor\n// prev was bound to; otherwise only the joint authorization.\n// · lineage — at most the LINEAGE_MAX most recent links, in chain\n// order, ending at self; empty = the sender presents no history.\n// · anchor-mapping@4 — { type, pair, self, to, card, lineage, revision,\n// issuedAt }; `self` is the current anchor, the card is under it,\n// mac2 is under its X key. 6.3 in order: 1 schema · 2 to · 3 pair ·\n// 4 card · 4a lineage chain · 4b pre-rotation · 5 card.anchor = self ·\n// 6 k2 from the card · 7 both MACs.\n// · classification (§6.3 condition 8) — a changed `self` is a ROTATION\n// when the previously held `self` is the `prev` of an element of the\n// carried segment (6160), otherwise the mapping is REJECTED (6170).\n// · mappingAnchors / mappingBindings — the verified anchor set of a\n// mapping (self and every anchor of its lineage) and the pre-rotation\n// bindings it states (6610); the convergence net merges two\n// relationships whose sets meet, under the head rule and the binding\n// rule (§6a.1).\nimport { jcs, makeValidator, calOK } from './core.js'\nimport { SCHEMAS } from './schemas.js'\nimport { base58, fromBase58, edRawOfAnchor, xRawOfMk, ecdh, hkdf, b64uOf, digestBytes } from './crypto.js'\nimport { communityLabel } from './identity.js'\nimport type { Context } from './identity.js'\nimport { platformSubtle } from './crypto.js'\n\nconst te = new TextEncoder()\nconst S = platformSubtle\nconst VAL = makeValidator(SCHEMAS)\nconst schemaOk = (file: string, data: unknown): boolean => VAL.validate(data, SCHEMAS[file]!, SCHEMAS[file]!).length === 0\n\n/** HMAC-SHA-256 over the UTF-8 bytes of msg, in the mac encoding (`u` + base64url). */\nexport async function macU (keyBytes: Uint8Array, msg: string, subtle: SubtleCrypto = S()): Promise<string> {\n const k = await subtle.importKey('raw', keyBytes, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign'])\n return 'u' + b64uOf(new Uint8Array(await subtle.sign('HMAC', k, te.encode(msg))))\n}\n/** Raw Ed25519 over JCS(body), `z` + base58btc — the abbreviated proof form of Trust §2.1 (no DI suite). */\nexport async function signRaw (ctx: Pick<Context, 'ed'>, body: unknown, subtle: SubtleCrypto = S()): Promise<string> {\n return 'z' + base58(new Uint8Array(await subtle.sign({ name: 'Ed25519' }, ctx.ed.priv, te.encode(jcs(body)))))\n}\n/** The raw proofValue form of an Ed25519 signature: `z` + base58btc (Trust §2.1). */\nexport const rawProofValue = (sig: Uint8Array): string => 'z' + base58(sig)\n/** Verifies a raw Ed25519 proofValue over JCS(body) under a did:key anchor: exactly 64 bytes, canonical base58btc. */\nexport async function verifyRaw (did: unknown, body: unknown, proofValue: unknown, subtle?: SubtleCrypto): Promise<boolean> {\n try {\n if (typeof proofValue !== 'string' || proofValue[0] !== 'z') return false\n const raw = edRawOfAnchor(did)\n const sig = fromBase58(proofValue.slice(1))\n if (!raw || !sig || sig.length !== 64 || 'z' + base58(sig) !== proofValue) return false\n const Sx = subtle ?? S()\n const key = await Sx.importKey('raw', raw, { name: 'Ed25519' }, false, ['verify'])\n return await Sx.verify({ name: 'Ed25519' }, key, sig, te.encode(jcs(body)))\n } catch { return false }\n}\n\n// ── the pre-rotation binding (Identity §5.4) ────────────────────────────\n/**\n * The binding of an Ed25519 anchor: `u` + base64url of the sha2-256\n * multihash (0x12 0x20 ‖ SHA-256) over its 34 multikey bytes 0xed 0x01 ‖\n * pk — exactly the bytes the did:key identifier encodes.\n */\nexport async function bindingOf (anchor: string, subtle?: SubtleCrypto): Promise<string> {\n const raw = edRawOfAnchor(anchor)\n if (!raw || raw.length !== 32) throw new Error('not an Ed25519 did:key anchor')\n const mk = new Uint8Array(34); mk[0] = 0xed; mk[1] = 0x01; mk.set(raw, 2)\n return digestBytes(mk, subtle)\n}\n/** Whether `anchor` meets the binding `commit`. */\nexport const meetsBinding = async (anchor: string, commit: unknown, subtle?: SubtleCrypto): Promise<boolean> => {\n try { return typeof commit === 'string' && (await bindingOf(anchor, subtle)) === commit } catch { return false }\n}\n// the generation of a community-anchor label (Identity §5.4, §6.1):\n// group/<D> is generation 1, group/<D>/<g> generation g\nconst generationOf = (label: string): { digest: string, generation: number } | null => {\n const m = /^group\\/([^/]+)(?:\\/([1-9][0-9]*))?$/.exec(label)\n if (!m) return null\n const generation = m[2] === undefined ? 1 : Number(m[2])\n return Number.isSafeInteger(generation) ? { digest: m[1]!, generation } : null\n}\n// `next` is generation g + 1 of the digest of `prev` (Trust 6330)\nconst isSuccessor = (prev: Context, next: Context): boolean => {\n const g = generationOf(prev.label)\n if (!g || g.generation >= Number.MAX_SAFE_INTEGER) return false\n return next.label === communityLabel(g.digest, g.generation + 1)\n}\n\n// ── self-card@2 (§6.2) ──────────────────────────────────────────────────\n/**\n * self-card@2 of a community-anchor context: its anchor, key-agreement\n * key and the binding to `nextGen`, the generation after it; signed raw\n * under the anchor.\n */\nexport async function makeSelfCard (self: Context, nextGen: Context, subtle?: SubtleCrypto) {\n if (!isSuccessor(self, nextGen)) throw new Error('self-card@2: nextGen is not the generation after the anchor (Identity §5.4)')\n const body = { type: 'self-card@2', anchor: self.anchor, keyAgreement: self.keyAgreement, commit: await bindingOf(nextGen.anchor, subtle) }\n return { body, proof: { proofValue: await signRaw(self, body, subtle) } }\n}\n\n// ── anchor-rotation@2 (§6.5) ────────────────────────────────────────────\n/**\n * The link from the current community anchor (prev) to the next\n * generation of the same digest (next), carrying the binding of next to\n * the generation after it (after): both contexts sign the same canonical\n * body. A rotation moves to exactly g + 1 (Trust 6330, Identity §5.4).\n */\nexport async function makeAnchorRotation (prev: Context, next: Context, after: Context, subtle?: SubtleCrypto) {\n if (prev.anchor === next.anchor) throw new Error('anchor-rotation@2: next equals prev (Trust §6.5)')\n if (!isSuccessor(prev, next)) throw new Error('anchor-rotation@2: next is not the next generation of the same digest (Trust 6330)')\n if (!isSuccessor(next, after)) throw new Error('anchor-rotation@2: commit must bind the generation after next (Trust 6330)')\n const body = { type: 'anchor-rotation@2', prev: prev.anchor, next: next.anchor, commit: await bindingOf(after.anchor, subtle) }\n return { body, proof: { proofValue: await signRaw(prev, body, subtle), successorProofValue: await signRaw(next, body, subtle) } }\n}\n/**\n * Schema, next ≠ prev, and both signatures — prev's and next's — over\n * the canonical body; with `heldBinding` (the binding held for prev),\n * also that next meets it (§6.3 condition 4b).\n */\nexport async function verifyAnchorRotation (a: any, heldBinding?: string, subtle?: SubtleCrypto): Promise<boolean> {\n if (!schemaOk('visibility-anchor-rotation.schema.json', a)) return false\n if (a.body.prev === a.body.next) return false\n if (!((await verifyRaw(a.body.prev, a.body, a.proof.proofValue, subtle))\n && (await verifyRaw(a.body.next, a.body, a.proof.successorProofValue, subtle)))) return false\n return heldBinding === undefined || meetsBinding(a.body.next, heldBinding, subtle)\n}\n\n// ── the lineage (§6.3 condition 4a) ─────────────────────────────────────\n/** A mapping carries at most this many of the most recent links (§6.1; schema maxItems). */\nexport const LINEAGE_MAX = 64\n/**\n * Condition 4a, the chain as given: at most LINEAGE_MAX elements; every\n * element verifies under both its signatures; each prev equals the\n * preceding element's next; the last next equals self. An empty lineage\n * passes: the sender presents no history. The bindings are condition 4b\n * (verifyBindings).\n */\nexport async function verifyLineage (lineage: any[], self: string, subtle?: SubtleCrypto): Promise<{ ok: true } | { ok: false, reason: string }> {\n if (!Array.isArray(lineage)) return { ok: false, reason: 'lineage is not an array' }\n if (lineage.length > LINEAGE_MAX) return { ok: false, reason: `more than ${LINEAGE_MAX} elements` }\n for (const [i, r] of lineage.entries()) {\n if (!(await verifyAnchorRotation(r, undefined, subtle))) return { ok: false, reason: `element ${i}: anchor-rotation@2 does not verify under both signatures` }\n if (i > 0 && r.body.prev !== lineage[i - 1].body.next) return { ok: false, reason: `element ${i}: prev is not the preceding next` }\n }\n if (lineage.length && lineage[lineage.length - 1].body.next !== self) return { ok: false, reason: 'the last next is not self' }\n return { ok: true }\n}\n/**\n * Condition 4b, pre-rotation (Trust 6115): each element after the first\n * names a next that meets the commit of the element before it; where the\n * lineage is not empty, card.commit equals the commit of its last\n * element; and for every anchor for which the relationship holds a\n * binding (`held`, 6610), an element whose prev is that anchor names a\n * next that meets it, and a card whose anchor is that anchor carries it\n * as commit.\n */\nexport async function verifyBindings (body: { lineage: any[], card: any }, held?: Map<string, string>, subtle?: SubtleCrypto): Promise<{ ok: true } | { ok: false, reason: string, rule: 'RLTP-TRU-6115' | 'RLTP-TRU-6117' | 'RLTP-TRU-6118' }> {\n const L = body.lineage\n for (const [i, r] of L.entries()) {\n if (i > 0 && !(await meetsBinding(r.body.next, L[i - 1].body.commit, subtle))) return { ok: false, reason: `element ${i}: next does not meet the commit of the element before it`, rule: 'RLTP-TRU-6115' }\n const h = held?.get(r.body.prev)\n if (h !== undefined && !(await meetsBinding(r.body.next, h, subtle))) return { ok: false, reason: `element ${i}: next does not meet the binding held for its prev`, rule: 'RLTP-TRU-6118' }\n }\n if (L.length && body.card.body.commit !== L[L.length - 1].body.commit) return { ok: false, reason: 'card.commit is not the commit of the last element', rule: 'RLTP-TRU-6117' }\n const hc = held?.get(body.card.body.anchor)\n if (hc !== undefined && body.card.body.commit !== hc) return { ok: false, reason: 'the card states another binding than the one held for its anchor', rule: 'RLTP-TRU-6118' }\n return { ok: true }\n}\n/** Every anchor a lineage names, in chain order: the first prev, then each next. */\nexport const lineageAnchors = (lineage: any[]): string[] =>\n lineage.length ? [lineage[0].body.prev, ...lineage.map((r: any) => r.body.next)] : []\n/**\n * The verified anchor set of a mapping (§6a.1 rung 2): its self and every\n * anchor of its carried lineage, in chain order, self last. Two\n * relationships converge when these sets meet.\n */\nexport const mappingAnchors = (body: { self: string, lineage: any[] }): string[] =>\n body.lineage.length ? lineageAnchors(body.lineage) : [body.self]\n/** The links prev → next a lineage carries, in chain order. */\nexport const lineageLinks = (lineage: any[]): [string, string][] =>\n lineage.map((r: any) => [r.body.prev, r.body.next])\n/**\n * The pre-rotation bindings a verified mapping states (Trust 6610): the\n * commit of each lineage element as the binding of its next, card.commit\n * as the binding of self, and, for the prev of each link, the binding\n * computed over that link's next.\n */\nexport async function mappingBindings (body: { self: string, lineage: any[], card: any }, subtle?: SubtleCrypto): Promise<Map<string, string>> {\n const out = new Map<string, string>()\n for (const r of body.lineage) {\n out.set(r.body.prev, await bindingOf(r.body.next, subtle))\n out.set(r.body.next, r.body.commit)\n }\n out.set(body.self, body.card.body.commit)\n return out\n}\n/**\n * §6.3 condition 8 against the `self` this relationship holds (6150):\n * 'first' where it holds none, 'same' where `self` is unchanged,\n * 'rotation' where a changed `self` comes with a carried segment that\n * has the held self as the `prev` of one of its elements (6160), and\n * 'rejected' otherwise (6170): a change of `self` that no carried segment\n * links to the held one is rejected like every mapping that fails a\n * condition, with the current state kept — also after more than 64\n * missed rotations (6400). Condition 4b has already refused a segment\n * that names another successor of an anchor whose binding the\n * relationship holds.\n */\nexport function classifyMapping (heldSelf: string | undefined, body: { self: string, lineage: any[] }): 'first' | 'same' | 'rotation' | 'rejected' {\n if (heldSelf === undefined) return 'first'\n if (heldSelf === body.self) return 'same'\n return body.lineage.some((r: any) => r.body.prev === heldSelf) ? 'rotation' : 'rejected'\n}\n\n// ── anchor-mapping@4 (§6.1) ─────────────────────────────────────────────\nexport interface MappingInput {\n /** the sender's own pair context of the relationship */\n pair: Context\n /** the addressee's pair anchor and key-agreement key in this relationship */\n to: string\n toKeyAgreement: string\n /** the sender's CURRENT community anchor */\n self: Context\n /** the generation after self — its binding is the card's commit */\n nextGen: Context\n /** at most LINEAGE_MAX anchor-rotation@2 artifacts, in chain order, ending at self (or empty) */\n lineage: any[]\n revision: string\n issuedAt: string\n}\n/** The two MACs of an anchor-mapping@4 over JCS(body) (Trust 6030), from\n * the two shared secrets: sh1 = ECDH(pairX of the sender, pairX of the\n * addressee), sh2 = ECDH(selfX of the sender, pairX of the addressee). */\nexport async function assembleAnchorMapping<B extends object> (body: B, sh1: Uint8Array, sh2: Uint8Array, subtle?: SubtleCrypto): Promise<{ body: B, proof: { mac1: string, mac2: string } }> {\n const msg = jcs(body)\n return { body, proof: {\n mac1: await macU(await hkdf(sh1, 'rltp/visibility/mac/map1', 32, subtle), msg, subtle),\n mac2: await macU(await hkdf(sh2, 'rltp/visibility/mac/map2', 32, subtle), msg, subtle),\n } }\n}\n/** anchor-mapping@4: body { type, pair, self, to, card, lineage, revision, issuedAt }; mac1 (relationship key, map1) and mac2 (selfX × pairX of the addressee, map2) over JCS(body). */\nexport async function buildAnchorMapping (i: MappingInput, subtle?: SubtleCrypto) {\n const card = await makeSelfCard(i.self, i.nextGen, subtle)\n const body = { type: 'anchor-mapping@4', pair: i.pair.anchor, self: i.self.anchor, to: i.to, card, lineage: i.lineage, revision: i.revision, issuedAt: i.issuedAt }\n const theirX = xRawOfMk(i.toKeyAgreement)\n if (!theirX) throw new Error('addressee key agreement is not a multikey')\n return assembleAnchorMapping(body, await ecdh(i.pair.x.priv, theirX, subtle), await ecdh(i.self.x.priv, theirX, subtle), subtle)\n}\n/** §6.3 conditions 1–7 as numbered by verifyAnchorMapping, with the rule\n * each one is; for 4b the result's `rule` names the one of 6115, 6117,\n * 6118 that failed. */\nexport const MAPPING_CONDITION_RULE: Readonly<Record<string, string>> = Object.freeze({\n 1: 'RLTP-TRU-6070', 2: 'RLTP-TRU-6080', 3: 'RLTP-TRU-6090', 4: 'RLTP-TRU-6100', '4a': 'RLTP-TRU-6110',\n '4b': 'RLTP-TRU-6118', 5: 'RLTP-TRU-6120', 6: 'RLTP-TRU-6130', 7: 'RLTP-TRU-6140',\n})\n/**\n * §6.3, the closed list, evaluated in its order: 1 schema (anchor-mapping\n * @1 to @3 are not implemented and fail here) · 2 to = own pair anchor ·\n * 3 pair = the arrival tuple's counterpart · 4 the card verifies under\n * its own anchor · 4a the lineage chain · 4b pre-rotation, against the\n * bindings this relationship holds (`held`, 6610) · 5 card.anchor = self ·\n * 6 k2 from card.keyAgreement · 7 both MACs. Revision (8) is the\n * holder's state. The addressee's own pair key acts through `agree`: the\n * raw X25519 shared secret with a raw public key, or null where none is\n * usable (condition 7); a throw is a failure of condition 1, as in\n * verifyAnchorMapping.\n */\nexport async function verifyAnchorMappingWith (\n m: any,\n at: { ownAnchor: string, pair: string, pairKeyAgreement: string, held?: Map<string, string>, agree: (theirX: Uint8Array) => Promise<Uint8Array | null> },\n subtle?: SubtleCrypto,\n): Promise<{ ok: true } | { ok: false, step: string, rule?: string }> {\n try {\n if (!schemaOk('visibility-anchor-mapping.schema.json', m)) return { ok: false, step: '1' }\n const b = m.body\n if (!calOK(b.issuedAt)) return { ok: false, step: '1' } // calendar validity belongs to the parse level\n if (b.to !== at.ownAnchor) return { ok: false, step: '2' }\n if (b.pair !== at.pair) return { ok: false, step: '3' }\n if (!(await verifyRaw(b.card.body.anchor, b.card.body, b.card.proof.proofValue, subtle))) return { ok: false, step: '4' }\n if (!(await verifyLineage(b.lineage, b.self, subtle)).ok) return { ok: false, step: '4a' }\n const vb = await verifyBindings(b, at.held, subtle)\n if (!vb.ok) return { ok: false, step: '4b', rule: vb.rule }\n if (b.card.body.anchor !== b.self) return { ok: false, step: '5' }\n const cardX = xRawOfMk(b.card.body.keyAgreement)\n const pairX = xRawOfMk(at.pairKeyAgreement)\n if (!cardX || !pairX) return { ok: false, step: '6' }\n const sh2 = await at.agree(cardX)\n const k2 = sh2 && await hkdf(sh2, 'rltp/visibility/mac/map2', 32, subtle)\n const sh1 = await at.agree(pairX)\n if (!sh1 || !sh2 || !k2 || sh1.every((x) => x === 0) || sh2.every((x) => x === 0)) return { ok: false, step: '7' } // both ECDH outputs non-zero\n const msg = jcs(b)\n if ((await macU(await hkdf(sh1, 'rltp/visibility/mac/map1', 32, subtle), msg, subtle)) !== m.proof.mac1) return { ok: false, step: '7' }\n if ((await macU(k2, msg, subtle)) !== m.proof.mac2) return { ok: false, step: '7' }\n return { ok: true }\n } catch { return { ok: false, step: '1' } }\n}\n/** verifyAnchorMappingWith over the addressee's own pair Context; names\n * the failed condition by its step only. */\nexport async function verifyAnchorMapping (m: any, at: { own: Context, pair: string, pairKeyAgreement: string, held?: Map<string, string> }, subtle?: SubtleCrypto): Promise<{ ok: true } | { ok: false, step: string }> {\n const v = await verifyAnchorMappingWith(m, {\n ownAnchor: at.own?.anchor, pair: at.pair, pairKeyAgreement: at.pairKeyAgreement, held: at.held,\n agree: (theirX) => ecdh(at.own.x.priv, theirX, subtle),\n }, subtle)\n return v.ok ? v : { ok: false, step: v.step }\n}\n"]}
@@ -39,4 +39,4 @@ export declare function recoverCarrierEntry(initial: HolderContext, rotateTo: (g
39
39
  principalChallenge: string;
40
40
  openedAddressChallenge: string;
41
41
  }>, maxCapacityRetries?: number): Promise<RecoveryResult>;
42
- //# sourceMappingURL=holder.d.ts.map
42
+ //# sourceMappingURL=carrier-holder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"carrier-holder.d.ts","sourceRoot":"","sources":["../src/carrier-holder.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAE7D,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAMrE,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,uEAAuE;AACvE,wBAAsB,aAAa,CACjC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GACxF,OAAO,CAAC,aAAa,CAAC,CAExB;AAYD;;wEAEwE;AACxE,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,UAAU,GAAG,QAAQ,EAClD,kBAAkB,EAAE,MAAM,EAAE,sBAAsB,EAAE,MAAM,EAAE,UAAU,SAAiB,GACtF,OAAO,CAAC,YAAY,CAAC,CAEvB;AAED;wDACwD;AACxD,wBAAgB,YAAY,CAC1B,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,GAAG,UAAU,EAAE,kBAAkB,EAAE,MAAM,GAC9E,OAAO,CAAC,YAAY,CAAC,CAEvB;AAWD,eAAO,MAAM,cAAc,QAA0B,CAAA;AAErD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,mBAAmB,CAAC,SAAS,CAAC,CAAA;CACxC;AACD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAA;IACpD,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,KAAK,EAAE,YAAY,EAAE,CAAA;CACtB;AAED;;;;;;;;4DAQ4D;AAC5D,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,EACxD,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,CAAC,EACtF,UAAU,EAAE,MAAM,OAAO,CAAC;IAAE,kBAAkB,EAAE,MAAM,CAAC;IAAC,sBAAsB,EAAE,MAAM,CAAA;CAAE,CAAC,EACzF,kBAAkB,SAAI,GACrB,OAAO,CAAC,cAAc,CAAC,CA6BzB"}
@@ -1,4 +1,4 @@
1
- // holder — the holder's side of the carrier port (Delivery §5a, the
1
+ // carrier-holder — the holder's side of the carrier port (Delivery §5a, the
2
2
  // client half): proof construction for all four purposes, the recovery
3
3
  // flow of Identity §9.3, and verdict handling.
4
4
  //
@@ -13,7 +13,8 @@ import { jcs } from './core.js';
13
13
  import { base58 } from './crypto.js';
14
14
  import { carrierPrincipal } from './carrier-identity.js';
15
15
  import { PROOF_V } from './carrier.js';
16
- const S = globalThis.crypto.subtle;
16
+ import { platformSubtle } from './crypto.js';
17
+ const S = platformSubtle;
17
18
  const te = new TextEncoder();
18
19
  /** derive-and-wrap: one holder context per (relationship × carrier) */
19
20
  export async function holderContext(rootIkm, carrier, nonce, rkid, generation) {
@@ -25,7 +26,7 @@ async function sign(ctx, fields) {
25
26
  carrier: ctx.carrier, principal: ctx.identity.principal, rkid: ctx.rkid,
26
27
  ...fields,
27
28
  };
28
- const sig = new Uint8Array(await S.sign({ name: 'Ed25519' }, ctx.identity.key.priv, te.encode(jcs(p))));
29
+ const sig = new Uint8Array(await S().sign({ name: 'Ed25519' }, ctx.identity.key.priv, te.encode(jcs(p))));
29
30
  return { ...p, sig: 'z' + base58(sig) };
30
31
  }
31
32
  /** register/rebind proof: both succession fields present (§5a.3).
@@ -89,4 +90,4 @@ export async function recoverCarrierEntry(initial, rotateTo, exchange, challenge
89
90
  }
90
91
  return { outcome: 'waiting', steps };
91
92
  }
92
- //# sourceMappingURL=holder.js.map
93
+ //# sourceMappingURL=carrier-holder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"carrier-holder.js","sourceRoot":"","sources":["../src/carrier-holder.ts"],"names":[],"mappings":"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","sourcesContent":["// carrier-holder — the holder's side of the carrier port (Delivery §5a, the\n// client half): proof construction for all four purposes, the recovery\n// flow of Identity §9.3, and verdict handling.\n//\n// The holder never guesses what the carrier holds. It derives its\n// principal (carrier-identity), asks for challenges, signs proofs whose\n// bytes are fixed by §5a.3, and reads exactly the closed verdict set —\n// including the one disclosure the protocol makes: a\n// `refused(stale-generation)` carries the generation to exceed, which is\n// what makes \"carrier entry lost, pair context held\" replaceable in two\n// exchanges instead of never.\nimport { jcs } from './core.js'\nimport type { Json } from './core.js'\nimport { base58 } from './crypto.js'\nimport { carrierPrincipal } from './carrier-identity.js'\nimport type { CarrierPrincipal } from './carrier-identity.js'\nimport { PROOF_V } from './carrier.js'\nimport type { CarrierProof, RegistrationVerdict } from './carrier.js'\nimport { platformSubtle } from './crypto.js'\n\nconst S = platformSubtle\nconst te = new TextEncoder()\n\nexport interface HolderContext {\n carrier: string // C, byte-exact\n identity: CarrierPrincipal // from carrierPrincipal(rootIkm, C, N)\n rkid: string // the relationship address at this carrier\n generation: number // the register's generation for N (§7a.3)\n}\n\n/** derive-and-wrap: one holder context per (relationship × carrier) */\nexport async function holderContext (\n rootIkm: Uint8Array, carrier: string, nonce: Uint8Array, rkid: string, generation: number,\n): Promise<HolderContext> {\n return { carrier, identity: await carrierPrincipal(rootIkm, carrier, nonce), rkid, generation }\n}\n\nasync function sign (ctx: HolderContext, fields: Record<string, Json>): Promise<CarrierProof> {\n const p = {\n v: PROOF_V, type: 'carrier-registration-proof',\n carrier: ctx.carrier, principal: ctx.identity.principal, rkid: ctx.rkid,\n ...fields,\n }\n const sig = new Uint8Array(await S().sign({ name: 'Ed25519' }, ctx.identity.key.priv, te.encode(jcs(p as unknown as Json))))\n return { ...(p as unknown as CarrierProof), sig: 'z' + base58(sig) }\n}\n\n/** register/rebind proof: both succession fields present (§5a.3).\n * `openedAddressChallenge` is the value the holder decrypted from the\n * carrier's sealed challenge — possession of the rkid's private key. */\nexport function registrationProof (\n ctx: HolderContext, purpose: 'register' | 'rebind',\n principalChallenge: string, openedAddressChallenge: string, generation = ctx.generation,\n): Promise<CarrierProof> {\n return sign(ctx, { purpose, generation, principalChallenge, addressChallenge: openedAddressChallenge })\n}\n\n/** collect/conclude proof: session-scoped, neither succession field —\n * their ABSENCE is part of the signed bytes (§5a.3). */\nexport function sessionProof (\n ctx: HolderContext, purpose: 'collect' | 'conclude', principalChallenge: string,\n): Promise<CarrierProof> {\n return sign(ctx, { purpose, principalChallenge })\n}\n\n// ── the recovery flow (Identity §9.3, executable) ───────────────────────\n// After losing the carrier entry alone (pair context held), the holder\n// knows neither the old principal nor the generation to exceed. The flow\n// is: attempt at generation 1; on the disclosing refusal, ROTATE THE\n// REGISTER to disclosed + 1 — Identity §7a.3: each rotation is a fresh\n// nonce N at generation g+1, and the principal is DERIVED from the new\n// nonce; a proof that named a higher generation over an old nonce would\n// claim a register state that does not exist (port-review B-6). Only the\n// number of carrier exchanges stays two; the rotations are local.\nexport const GENERATION_MAX = Number.MAX_SAFE_INTEGER // 2^53 − 1 (Identity §7a.3)\n\nexport interface RecoveryStep {\n attempt: number\n generation: number\n verdict: RegistrationVerdict['verdict']\n}\nexport interface RecoveryResult {\n outcome: 'bound' | 'waiting' | 'failed' | 'terminal'\n finalGeneration?: number\n steps: RecoveryStep[]\n}\n\n/** One recovery run. `rotateTo(g)` performs the LOCAL register rotations\n * up to generation g — fresh nonce, re-derived principal — and returns\n * the holder context of the new canonical entry (Identity §7a.3).\n * `exchange` is the transport; `challenges` draws a fresh pair per\n * attempt. `maxCapacityRetries` bounds only this run: the protocol\n * promises order, never time (round-46 B-2). At the generation maximum\n * no rotation exists and the address is not re-registrable at this\n * carrier (Identity §7a.3) — the outcome is `terminal`, and the lever is\n * §7a.2's move to a different configured carrier string. */\nexport async function recoverCarrierEntry (\n initial: HolderContext,\n rotateTo: (generation: number) => Promise<HolderContext>,\n exchange: (proof: CarrierProof, rawGeneration: string) => Promise<RegistrationVerdict>,\n challenges: () => Promise<{ principalChallenge: string, openedAddressChallenge: string }>,\n maxCapacityRetries = 3,\n): Promise<RecoveryResult> {\n const steps: RecoveryStep[] = []\n let ctx = initial\n let purpose: 'register' | 'rebind' = 'register'\n for (let attempt = 1; attempt <= 2 + maxCapacityRetries; attempt++) {\n const ch = await challenges()\n const proof = await registrationProof(ctx, purpose, ch.principalChallenge, ch.openedAddressChallenge)\n const v = await exchange(proof, String(ctx.generation))\n steps.push({ attempt, generation: ctx.generation, verdict: v.verdict })\n switch (v.verdict) {\n case 'registered':\n case 'rebound':\n case 'registered(idempotent)':\n return { outcome: 'bound', finalGeneration: ctx.generation, steps }\n case 'refused(stale-generation)': {\n const held = (v as { heldGeneration: number }).heldGeneration\n if (held >= GENERATION_MAX) return { outcome: 'terminal', steps }\n ctx = await rotateTo(held + 1) // real rotations, fresh nonce\n purpose = 'rebind'\n break\n }\n case 'registration-refused(capacity)':\n case 'refused(admission-resource)':\n break\n default:\n return { outcome: 'failed', steps }\n }\n }\n return { outcome: 'waiting', steps }\n}\n"]}
@@ -89,8 +89,8 @@ export async function carrierPrincipal(rootIkm, carrier, nonce) {
89
89
  // M-3: the derivation reads its inputs at entry, once. Caller-held
90
90
  // buffers can be mutated while the HKDF awaits; copies make the
91
91
  // derived principal a function of the arguments as passed.
92
- const ikm = rootIkm.slice();
93
- const n = nonce.slice();
92
+ const ikm = new Uint8Array(rootIkm);
93
+ const n = new Uint8Array(nonce);
94
94
  const info = CARRIER_INFO_PREFIX + await mh(te.encode(carrier)) + await mh(n);
95
95
  const seed = await hkdf(ikm, info);
96
96
  const key = await edFromSeed(seed);
@@ -104,8 +104,8 @@ export async function carrierScopedIdentity(rootIkm, carrier, nonce, scope) {
104
104
  throw new Error('invalid carrier identifier (7a.2)');
105
105
  if (nonce.length !== 32)
106
106
  throw new Error('carrier nonce must be 32 bytes (7a.3)');
107
- const ikm = rootIkm.slice();
108
- const n = nonce.slice();
107
+ const ikm = new Uint8Array(rootIkm);
108
+ const n = new Uint8Array(nonce);
109
109
  const prefix = scope === 'connection' ? CONNECTION_INFO_PREFIX : EGRESS_INFO_PREFIX;
110
110
  const info = prefix + await mh(te.encode(carrier)) + await mh(n);
111
111
  const seed = await hkdf(ikm, info);
@@ -1 +1 @@
1
- {"version":3,"file":"carrier-identity.js","sourceRoot":"","sources":["../src/carrier-identity.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,EAAE;AACF,wEAAwE;AACxE,yEAAyE;AACzE,uEAAuE;AACvE,sEAAsE;AACtE,8DAA8D;AAC9D,EAAE;AACF,gEAAgE;AAChE,iEAAiE;AACjE,uEAAuE;AACvE,uEAAuE;AACvE,wEAAwE;AACxE,EAAE;AACF,uEAAuE;AACvE,sEAAsE;AACtE,6BAA6B;AAC7B,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE/D,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAE/C,MAAM,EAAE,GAAG,IAAI,WAAW,EAAE,CAAA;AAE5B,MAAM,CAAC,MAAM,mBAAmB,GAAG,0CAA0C,CAAA;AAE7E,mEAAmE;AACnE,qEAAqE;AACrE,iEAAiE;AACjE,sEAAsE;AACtE,qEAAqE;AACrE,kEAAkE;AAClE,uEAAuE;AACvE,MAAM,CAAC,MAAM,sBAAsB,GAAG,wCAAwC,CAAA;AAC9E,MAAM,CAAC,MAAM,kBAAkB,GAAG,oCAAoC,CAAA;AAEtE,0EAA0E;AAC1E,MAAM,EAAE,GAAG,KAAK,EAAE,KAAiB,EAAmB,EAAE,CACtD,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AAEpE,sEAAsE;AACtE,kEAAkE;AAClE,mEAAmE;AACnE,yEAAyE;AACzE,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,kEAAkE;AAClE,uEAAuE;AACvE,wEAAwE;AACxE,sEAAsE;AACtE,mEAAmE;AACnE,MAAM,KAAK,GAAG,CAAC,EAAU,EAAW,EAAE,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,CAAC,CAAA;AAC/E,MAAM,YAAY,GAA4B;IAC5C,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;IACtE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;IACtE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;IACtE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1E,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1D,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;CACvC,CAAA;AACD,MAAM,KAAK,GAAG,CAAC,EAAU,EAAW,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAA;AACxF,MAAM,UAAU,sBAAsB,CAAE,CAAU;IAChD,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IACzD,+DAA+D;IAC/D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;QACzB,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI,MAAM;YAAE,OAAO,KAAK,CAAA,CAAuB,WAAW;QAC9E,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI,MAAM,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YAC/B,IAAI,CAAC,CAAC,GAAG,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,CAAC;gBAAE,OAAO,KAAK,CAAA,CAAc,YAAY;YAC7E,CAAC,EAAE,CAAA;QACL,CAAC;IACH,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IACzC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,IAAI;QAAE,OAAO,KAAK,CAAA;IACzD,KAAK,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;QACnB,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,CAAE,CAAA;QAC7B,IAAI,KAAK,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,OAAO,KAAK,CAAA;IACpE,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AASD,wEAAwE;AACxE,0EAA0E;AAC1E,2EAA2E;AAC3E,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAmB,EAAE,OAAe,EAAE,KAAiB;IAEvD,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAA;IAC1F,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAA;IACjF,mEAAmE;IACnE,gEAAgE;IAChE,2DAA2D;IAC3D,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,EAAE,CAAA;IAC3B,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,CAAA;IACvB,MAAM,IAAI,GAAG,mBAAmB,GAAG,MAAM,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,CAAA;IAC7E,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAClC,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAA;IAClC,OAAO,EAAE,SAAS,EAAE,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAA;AAC7E,CAAC;AASD,yEAAyE;AACzE,mEAAmE;AACnE,sEAAsE;AACtE,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAAmB,EAAE,OAAe,EAAE,KAAiB,EACvD,KAA8B;IAE9B,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAA;IAC1F,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAA;IACjF,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,EAAE,CAAA;IAC3B,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,EAAE,CAAA;IACvB,MAAM,MAAM,GAAG,KAAK,KAAK,YAAY,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,kBAAkB,CAAA;IACnF,MAAM,IAAI,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,CAAA;IAChE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAClC,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAA;IAClC,OAAO,EAAE,GAAG,EAAE,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;AAC1D,CAAC","sourcesContent":["// carrier-identity — Identity §7a: the carrier-relationship identity class.\n//\n// One control principal per (relationship × carrier), Ed25519-only. The\n// derivation shares no computable relation with the relationship's other\n// principals or with its `rkid` — that absence is the privacy property\n// the whole class exists for (§7a.5), and it is why registration must\n// PROVE the binding instead of computing it (Delivery §5a.3).\n//\n// info = \"rltp/v1/carrier-relationship/ed25519/v1/\" || Dc || Dn\n// where Dc = multihash(sha2-256, UTF-8 of the configured carrier\n// identifier C) and Dn = multihash(sha2-256, 32-byte carrier nonce N),\n// each rendered as 'u' + base64url — exactly 47 characters, so the two\n// parts are length-fixed and no concatenation ambiguity exists (§7a.4).\n//\n// NO key-agreement key is derived for this class: sealing stays at the\n// `rkid` (§7a.1), and a carrier that never holds a decryption key can\n// never be asked to use one.\nimport { b64uOf, cat } from './crypto.js'\nimport { sha, hkdf, edFromSeed, anchorOfEd } from './crypto.js'\nimport type { KeyPair } from './crypto.js'\nimport { WHITE_SPACE_15 } from './unicode15.js'\n\nconst te = new TextEncoder()\n\nexport const CARRIER_INFO_PREFIX = 'rltp/v1/carrier-relationship/ed25519/v1/'\n\n// Adapter-scoped identities (profile spec/adapter-vti-mediator.md,\n// Delivery §5a.10): the mediation connection DID and the sender-side\n// egress identity. Both derive from the same root as the control\n// principal but under distinct info prefixes — each is derivable from\n// the root, none from any other. That is exactly the §5a.10 sentence\n// \"never a control principal or derivable from one\", satisfied by\n// construction: without rootIkm no party can compute one from another.\nexport const CONNECTION_INFO_PREFIX = 'rltp/v1/carrier-connection/ed25519/v1/'\nexport const EGRESS_INFO_PREFIX = 'rltp/v1/carrier-egress/ed25519/v1/'\n\n// multihash(sha2-256) in base64url — the digest form Identity §7a.4 fixes\nconst mh = async (bytes: Uint8Array): Promise<string> =>\n 'u' + b64uOf(cat(Uint8Array.from([0x12, 0x20]), await sha(bytes)))\n\n// Identity §7a.2 — the ordered validation pipeline for C, fail closed\n// and NO normalization (the deliberate difference to §6.2): valid\n// Unicode scalar values only (unpaired surrogates never repaired),\n// 1..1024 UTF-8 BYTES, and no Cc, Cf or White_Space code point anywhere.\n//\n// The category tables are PINNED to Unicode 15.0 (port-review-2 M-6):\n// evaluating against the platform's \\p{...} data would let the same\n// identifier derive a principal on one runtime and be rejected on\n// another the moment a Unicode revision moves a code point — the exact\n// defect the persona repertoire (unicode15.ts) already closed for §6.2.\n// Cc is the stable C0/C1 block; Cf is the 170-code-point Unicode-15.0\n// set, enumerated below; White_Space is unicode15.ts's pinned set.\nconst CC_15 = (cp: number): boolean => cp <= 0x1f || (cp >= 0x7f && cp <= 0x9f)\nconst CF_15_RANGES: Array<[number, number]> = [\n [0x00ad, 0x00ad], [0x0600, 0x0605], [0x061c, 0x061c], [0x06dd, 0x06dd],\n [0x070f, 0x070f], [0x0890, 0x0891], [0x08e2, 0x08e2], [0x180e, 0x180e],\n [0x200b, 0x200f], [0x202a, 0x202e], [0x2060, 0x2064], [0x2066, 0x206f],\n [0xfeff, 0xfeff], [0xfff9, 0xfffb], [0x110bd, 0x110bd], [0x110cd, 0x110cd],\n [0x13430, 0x1343f], [0x1bca0, 0x1bca3], [0x1d173, 0x1d17a],\n [0xe0001, 0xe0001], [0xe0020, 0xe007f],\n]\nconst CF_15 = (cp: number): boolean => CF_15_RANGES.some(([a, b]) => cp >= a && cp <= b)\nexport function validCarrierIdentifier (c: unknown): c is string {\n if (typeof c !== 'string' || c.length === 0) return false\n // scalar values: an unpaired surrogate is not a Unicode string\n for (let i = 0; i < c.length; i++) {\n const u = c.charCodeAt(i)\n if (u >= 0xdc00 && u <= 0xdfff) return false // lone low\n if (u >= 0xd800 && u <= 0xdbff) {\n const nxt = c.charCodeAt(i + 1)\n if (!(nxt >= 0xdc00 && nxt <= 0xdfff)) return false // lone high\n i++\n }\n }\n const bytes = new TextEncoder().encode(c)\n if (bytes.length < 1 || bytes.length > 1024) return false\n for (const ch of c) {\n const cp = ch.codePointAt(0)!\n if (CC_15(cp) || CF_15(cp) || WHITE_SPACE_15.has(cp)) return false\n }\n return true\n}\n\nexport interface CarrierPrincipal {\n principal: string // did:key:z6Mk…, the control principal\n key: KeyPair // its Ed25519 pair (for the proofs of §5a.3)\n info: string // the derivation info, for auditability\n keyAgreement: null // declared, not omitted: Ed25519-only (§7a.1)\n}\n\n// Identity §7a.4 — derive the control principal for one relationship at\n// one carrier. `carrier` is C exactly as configured (byte-exact), `nonce`\n// is the relationship's 32-byte carrier nonce N from the register (§7a.3).\nexport async function carrierPrincipal (\n rootIkm: Uint8Array, carrier: string, nonce: Uint8Array,\n): Promise<CarrierPrincipal> {\n if (!validCarrierIdentifier(carrier)) throw new Error('invalid carrier identifier (7a.2)')\n if (nonce.length !== 32) throw new Error('carrier nonce must be 32 bytes (7a.3)')\n // M-3: the derivation reads its inputs at entry, once. Caller-held\n // buffers can be mutated while the HKDF awaits; copies make the\n // derived principal a function of the arguments as passed.\n const ikm = rootIkm.slice()\n const n = nonce.slice()\n const info = CARRIER_INFO_PREFIX + await mh(te.encode(carrier)) + await mh(n)\n const seed = await hkdf(ikm, info)\n const key = await edFromSeed(seed)\n return { principal: anchorOfEd(key.pubRaw), key, info, keyAgreement: null }\n}\n\nexport interface CarrierScopedIdentity {\n did: string // did:key:z6Mk…\n key: KeyPair\n info: string\n scope: 'connection' | 'egress'\n}\n\n// One connection DID / one egress identity per (relationship × carrier),\n// same derivation discipline and same input rules as the principal\n// (§7a.4), distinct prefix. Retired with the principal, never reused.\nexport async function carrierScopedIdentity (\n rootIkm: Uint8Array, carrier: string, nonce: Uint8Array,\n scope: 'connection' | 'egress',\n): Promise<CarrierScopedIdentity> {\n if (!validCarrierIdentifier(carrier)) throw new Error('invalid carrier identifier (7a.2)')\n if (nonce.length !== 32) throw new Error('carrier nonce must be 32 bytes (7a.3)')\n const ikm = rootIkm.slice()\n const n = nonce.slice()\n const prefix = scope === 'connection' ? CONNECTION_INFO_PREFIX : EGRESS_INFO_PREFIX\n const info = prefix + await mh(te.encode(carrier)) + await mh(n)\n const seed = await hkdf(ikm, info)\n const key = await edFromSeed(seed)\n return { did: anchorOfEd(key.pubRaw), key, info, scope }\n}\n"]}
1
+ {"version":3,"file":"carrier-identity.js","sourceRoot":"","sources":["../src/carrier-identity.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,EAAE;AACF,wEAAwE;AACxE,yEAAyE;AACzE,uEAAuE;AACvE,sEAAsE;AACtE,8DAA8D;AAC9D,EAAE;AACF,gEAAgE;AAChE,iEAAiE;AACjE,uEAAuE;AACvE,uEAAuE;AACvE,wEAAwE;AACxE,EAAE;AACF,uEAAuE;AACvE,sEAAsE;AACtE,6BAA6B;AAC7B,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE/D,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAE/C,MAAM,EAAE,GAAG,IAAI,WAAW,EAAE,CAAA;AAE5B,MAAM,CAAC,MAAM,mBAAmB,GAAG,0CAA0C,CAAA;AAE7E,mEAAmE;AACnE,qEAAqE;AACrE,iEAAiE;AACjE,sEAAsE;AACtE,qEAAqE;AACrE,kEAAkE;AAClE,uEAAuE;AACvE,MAAM,CAAC,MAAM,sBAAsB,GAAG,wCAAwC,CAAA;AAC9E,MAAM,CAAC,MAAM,kBAAkB,GAAG,oCAAoC,CAAA;AAEtE,0EAA0E;AAC1E,MAAM,EAAE,GAAG,KAAK,EAAE,KAAiB,EAAmB,EAAE,CACtD,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AAEpE,sEAAsE;AACtE,kEAAkE;AAClE,mEAAmE;AACnE,yEAAyE;AACzE,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,kEAAkE;AAClE,uEAAuE;AACvE,wEAAwE;AACxE,sEAAsE;AACtE,mEAAmE;AACnE,MAAM,KAAK,GAAG,CAAC,EAAU,EAAW,EAAE,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,CAAC,CAAA;AAC/E,MAAM,YAAY,GAA4B;IAC5C,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;IACtE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;IACtE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;IACtE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1E,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1D,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC;CACvC,CAAA;AACD,MAAM,KAAK,GAAG,CAAC,EAAU,EAAW,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAA;AACxF,MAAM,UAAU,sBAAsB,CAAE,CAAU;IAChD,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IACzD,+DAA+D;IAC/D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;QACzB,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI,MAAM;YAAE,OAAO,KAAK,CAAA,CAAuB,WAAW;QAC9E,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI,MAAM,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YAC/B,IAAI,CAAC,CAAC,GAAG,IAAI,MAAM,IAAI,GAAG,IAAI,MAAM,CAAC;gBAAE,OAAO,KAAK,CAAA,CAAc,YAAY;YAC7E,CAAC,EAAE,CAAA;QACL,CAAC;IACH,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IACzC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,IAAI;QAAE,OAAO,KAAK,CAAA;IACzD,KAAK,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;QACnB,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,CAAE,CAAA;QAC7B,IAAI,KAAK,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,OAAO,KAAK,CAAA;IACpE,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AASD,wEAAwE;AACxE,0EAA0E;AAC1E,2EAA2E;AAC3E,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAmB,EAAE,OAAe,EAAE,KAAiB;IAEvD,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAA;IAC1F,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAA;IACjF,mEAAmE;IACnE,gEAAgE;IAChE,2DAA2D;IAC3D,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAA;IACnC,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAA;IAC/B,MAAM,IAAI,GAAG,mBAAmB,GAAG,MAAM,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,CAAA;IAC7E,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAClC,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAA;IAClC,OAAO,EAAE,SAAS,EAAE,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,CAAA;AAC7E,CAAC;AASD,yEAAyE;AACzE,mEAAmE;AACnE,sEAAsE;AACtE,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAAmB,EAAE,OAAe,EAAE,KAAiB,EACvD,KAA8B;IAE9B,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAA;IAC1F,IAAI,KAAK,CAAC,MAAM,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAA;IACjF,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAA;IACnC,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAA;IAC/B,MAAM,MAAM,GAAG,KAAK,KAAK,YAAY,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,kBAAkB,CAAA;IACnF,MAAM,IAAI,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,CAAA;IAChE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;IAClC,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,CAAA;IAClC,OAAO,EAAE,GAAG,EAAE,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;AAC1D,CAAC","sourcesContent":["// carrier-identity — Identity §7a: the carrier-relationship identity class.\n//\n// One control principal per (relationship × carrier), Ed25519-only. The\n// derivation shares no computable relation with the relationship's other\n// principals or with its `rkid` — that absence is the privacy property\n// the whole class exists for (§7a.5), and it is why registration must\n// PROVE the binding instead of computing it (Delivery §5a.3).\n//\n// info = \"rltp/v1/carrier-relationship/ed25519/v1/\" || Dc || Dn\n// where Dc = multihash(sha2-256, UTF-8 of the configured carrier\n// identifier C) and Dn = multihash(sha2-256, 32-byte carrier nonce N),\n// each rendered as 'u' + base64url — exactly 47 characters, so the two\n// parts are length-fixed and no concatenation ambiguity exists (§7a.4).\n//\n// NO key-agreement key is derived for this class: sealing stays at the\n// `rkid` (§7a.1), and a carrier that never holds a decryption key can\n// never be asked to use one.\nimport { b64uOf, cat } from './crypto.js'\nimport { sha, hkdf, edFromSeed, anchorOfEd } from './crypto.js'\nimport type { KeyPair } from './crypto.js'\nimport { WHITE_SPACE_15 } from './unicode15.js'\n\nconst te = new TextEncoder()\n\nexport const CARRIER_INFO_PREFIX = 'rltp/v1/carrier-relationship/ed25519/v1/'\n\n// Adapter-scoped identities (profile spec/adapter-vti-mediator.md,\n// Delivery §5a.10): the mediation connection DID and the sender-side\n// egress identity. Both derive from the same root as the control\n// principal but under distinct info prefixes — each is derivable from\n// the root, none from any other. That is exactly the §5a.10 sentence\n// \"never a control principal or derivable from one\", satisfied by\n// construction: without rootIkm no party can compute one from another.\nexport const CONNECTION_INFO_PREFIX = 'rltp/v1/carrier-connection/ed25519/v1/'\nexport const EGRESS_INFO_PREFIX = 'rltp/v1/carrier-egress/ed25519/v1/'\n\n// multihash(sha2-256) in base64url — the digest form Identity §7a.4 fixes\nconst mh = async (bytes: Uint8Array): Promise<string> =>\n 'u' + b64uOf(cat(Uint8Array.from([0x12, 0x20]), await sha(bytes)))\n\n// Identity §7a.2 — the ordered validation pipeline for C, fail closed\n// and NO normalization (the deliberate difference to §6.2): valid\n// Unicode scalar values only (unpaired surrogates never repaired),\n// 1..1024 UTF-8 BYTES, and no Cc, Cf or White_Space code point anywhere.\n//\n// The category tables are PINNED to Unicode 15.0 (port-review-2 M-6):\n// evaluating against the platform's \\p{...} data would let the same\n// identifier derive a principal on one runtime and be rejected on\n// another the moment a Unicode revision moves a code point — the exact\n// defect the persona repertoire (unicode15.ts) already closed for §6.2.\n// Cc is the stable C0/C1 block; Cf is the 170-code-point Unicode-15.0\n// set, enumerated below; White_Space is unicode15.ts's pinned set.\nconst CC_15 = (cp: number): boolean => cp <= 0x1f || (cp >= 0x7f && cp <= 0x9f)\nconst CF_15_RANGES: Array<[number, number]> = [\n [0x00ad, 0x00ad], [0x0600, 0x0605], [0x061c, 0x061c], [0x06dd, 0x06dd],\n [0x070f, 0x070f], [0x0890, 0x0891], [0x08e2, 0x08e2], [0x180e, 0x180e],\n [0x200b, 0x200f], [0x202a, 0x202e], [0x2060, 0x2064], [0x2066, 0x206f],\n [0xfeff, 0xfeff], [0xfff9, 0xfffb], [0x110bd, 0x110bd], [0x110cd, 0x110cd],\n [0x13430, 0x1343f], [0x1bca0, 0x1bca3], [0x1d173, 0x1d17a],\n [0xe0001, 0xe0001], [0xe0020, 0xe007f],\n]\nconst CF_15 = (cp: number): boolean => CF_15_RANGES.some(([a, b]) => cp >= a && cp <= b)\nexport function validCarrierIdentifier (c: unknown): c is string {\n if (typeof c !== 'string' || c.length === 0) return false\n // scalar values: an unpaired surrogate is not a Unicode string\n for (let i = 0; i < c.length; i++) {\n const u = c.charCodeAt(i)\n if (u >= 0xdc00 && u <= 0xdfff) return false // lone low\n if (u >= 0xd800 && u <= 0xdbff) {\n const nxt = c.charCodeAt(i + 1)\n if (!(nxt >= 0xdc00 && nxt <= 0xdfff)) return false // lone high\n i++\n }\n }\n const bytes = new TextEncoder().encode(c)\n if (bytes.length < 1 || bytes.length > 1024) return false\n for (const ch of c) {\n const cp = ch.codePointAt(0)!\n if (CC_15(cp) || CF_15(cp) || WHITE_SPACE_15.has(cp)) return false\n }\n return true\n}\n\nexport interface CarrierPrincipal {\n principal: string // did:key:z6Mk…, the control principal\n key: KeyPair // its Ed25519 pair (for the proofs of §5a.3)\n info: string // the derivation info, for auditability\n keyAgreement: null // declared, not omitted: Ed25519-only (§7a.1)\n}\n\n// Identity §7a.4 — derive the control principal for one relationship at\n// one carrier. `carrier` is C exactly as configured (byte-exact), `nonce`\n// is the relationship's 32-byte carrier nonce N from the register (§7a.3).\nexport async function carrierPrincipal (\n rootIkm: Uint8Array, carrier: string, nonce: Uint8Array,\n): Promise<CarrierPrincipal> {\n if (!validCarrierIdentifier(carrier)) throw new Error('invalid carrier identifier (7a.2)')\n if (nonce.length !== 32) throw new Error('carrier nonce must be 32 bytes (7a.3)')\n // M-3: the derivation reads its inputs at entry, once. Caller-held\n // buffers can be mutated while the HKDF awaits; copies make the\n // derived principal a function of the arguments as passed.\n const ikm = new Uint8Array(rootIkm)\n const n = new Uint8Array(nonce)\n const info = CARRIER_INFO_PREFIX + await mh(te.encode(carrier)) + await mh(n)\n const seed = await hkdf(ikm, info)\n const key = await edFromSeed(seed)\n return { principal: anchorOfEd(key.pubRaw), key, info, keyAgreement: null }\n}\n\nexport interface CarrierScopedIdentity {\n did: string // did:key:z6Mk…\n key: KeyPair\n info: string\n scope: 'connection' | 'egress'\n}\n\n// One connection DID / one egress identity per (relationship × carrier),\n// same derivation discipline and same input rules as the principal\n// (§7a.4), distinct prefix. Retired with the principal, never reused.\nexport async function carrierScopedIdentity (\n rootIkm: Uint8Array, carrier: string, nonce: Uint8Array,\n scope: 'connection' | 'egress',\n): Promise<CarrierScopedIdentity> {\n if (!validCarrierIdentifier(carrier)) throw new Error('invalid carrier identifier (7a.2)')\n if (nonce.length !== 32) throw new Error('carrier nonce must be 32 bytes (7a.3)')\n const ikm = new Uint8Array(rootIkm)\n const n = new Uint8Array(nonce)\n const prefix = scope === 'connection' ? CONNECTION_INFO_PREFIX : EGRESS_INFO_PREFIX\n const info = prefix + await mh(te.encode(carrier)) + await mh(n)\n const seed = await hkdf(ikm, info)\n const key = await edFromSeed(seed)\n return { did: anchorOfEd(key.pubRaw), key, info, scope }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"carrier.d.ts","sourceRoot":"","sources":["../src/carrier.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"carrier.d.ts","sourceRoot":"","sources":["../src/carrier.ts"],"names":[],"mappings":"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"}
package/dist/carrier.js CHANGED
@@ -27,7 +27,8 @@
27
27
  import { jcs } from './core.js';
28
28
  import { b64uOf, fromB64u, base58, fromBase58, sha } from './crypto.js';
29
29
  import { validCarrierIdentifier } from './carrier-identity.js';
30
- const S = globalThis.crypto.subtle;
30
+ import { platformSubtle } from './crypto.js';
31
+ const S = platformSubtle;
31
32
  const te = new TextEncoder();
32
33
  const DAY = 86_400_000;
33
34
  const DOMAINS = [
@@ -156,8 +157,8 @@ async function verifySignature(p) {
156
157
  const pub = decodedEd(p.principal);
157
158
  const sig = decodedSig(p.sig);
158
159
  const { sig: _omit, ...signed } = p;
159
- const key = await S.importKey('raw', pub, { name: 'Ed25519' }, false, ['verify']);
160
- return S.verify({ name: 'Ed25519' }, key, sig, te.encode(jcs(signed)));
160
+ const key = await S().importKey('raw', pub, { name: 'Ed25519' }, false, ['verify']);
161
+ return S().verify({ name: 'Ed25519' }, key, sig, te.encode(jcs(signed)));
161
162
  }
162
163
  /** compatibility shim for the shape+signature question alone (tests,
163
164
  * tooling): stateless, no challenge semantics. */