@private.me/xbind 1.2.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 (295) hide show
  1. package/AGENTS.md +778 -0
  2. package/LICENSE.md +27 -0
  3. package/README.md +400 -0
  4. package/dist-standalone/_deps/crypto/base64.d.ts +29 -0
  5. package/dist-standalone/_deps/crypto/base64.js +97 -0
  6. package/dist-standalone/_deps/crypto/cjs/base64.js +103 -0
  7. package/dist-standalone/_deps/crypto/cjs/errors.js +119 -0
  8. package/dist-standalone/_deps/crypto/cjs/hmac.js +71 -0
  9. package/dist-standalone/_deps/crypto/cjs/index.js +86 -0
  10. package/dist-standalone/_deps/crypto/cjs/padding.js +57 -0
  11. package/dist-standalone/_deps/crypto/cjs/share-header.js +68 -0
  12. package/dist-standalone/_deps/crypto/cjs/shares.js +152 -0
  13. package/dist-standalone/_deps/crypto/cjs/tlv.js +199 -0
  14. package/dist-standalone/_deps/crypto/cjs/uuid.js +61 -0
  15. package/dist-standalone/_deps/crypto/cjs/verify.js +24 -0
  16. package/dist-standalone/_deps/crypto/cjs/xorida.js +221 -0
  17. package/dist-standalone/_deps/crypto/errors.d.ts +51 -0
  18. package/dist-standalone/_deps/crypto/errors.js +109 -0
  19. package/dist-standalone/_deps/crypto/hmac.d.ts +39 -0
  20. package/dist-standalone/_deps/crypto/hmac.js +66 -0
  21. package/dist-standalone/_deps/crypto/index.d.ts +20 -0
  22. package/dist-standalone/_deps/crypto/index.js +45 -0
  23. package/dist-standalone/_deps/crypto/padding.d.ts +19 -0
  24. package/dist-standalone/_deps/crypto/padding.js +53 -0
  25. package/dist-standalone/_deps/crypto/share-header.d.ts +44 -0
  26. package/dist-standalone/_deps/crypto/share-header.js +63 -0
  27. package/dist-standalone/_deps/crypto/shares.d.ts +27 -0
  28. package/dist-standalone/_deps/crypto/shares.js +148 -0
  29. package/dist-standalone/_deps/crypto/tlv.d.ts +26 -0
  30. package/dist-standalone/_deps/crypto/tlv.js +195 -0
  31. package/dist-standalone/_deps/crypto/uuid.d.ts +22 -0
  32. package/dist-standalone/_deps/crypto/uuid.js +56 -0
  33. package/dist-standalone/_deps/crypto/verify.d.ts +15 -0
  34. package/dist-standalone/_deps/crypto/verify.js +15 -0
  35. package/dist-standalone/_deps/crypto/xorida.d.ts +44 -0
  36. package/dist-standalone/_deps/crypto/xorida.js +215 -0
  37. package/dist-standalone/_deps/mldsa-wasm/LICENSE +24 -0
  38. package/dist-standalone/_deps/mldsa-wasm/dist/mldsa.js +1920 -0
  39. package/dist-standalone/_deps/mldsa-wasm/package.json +46 -0
  40. package/dist-standalone/_deps/mldsa-wasm/types/mldsa.d.ts +30 -0
  41. package/dist-standalone/_deps/shared/cjs/errors.js +582 -0
  42. package/dist-standalone/_deps/shared/cjs/index.js +492 -0
  43. package/dist-standalone/_deps/shared/cjs/package.json +1 -0
  44. package/dist-standalone/_deps/shared/cjs/types.js +403 -0
  45. package/dist-standalone/_deps/shared/errors.d.ts +48 -0
  46. package/dist-standalone/_deps/shared/errors.d.ts.map +1 -0
  47. package/dist-standalone/_deps/shared/errors.js +192 -0
  48. package/dist-standalone/_deps/shared/errors.js.map +1 -0
  49. package/dist-standalone/_deps/shared/index.d.ts +4 -0
  50. package/dist-standalone/_deps/shared/index.d.ts.map +1 -0
  51. package/dist-standalone/_deps/shared/index.js +78 -0
  52. package/dist-standalone/_deps/shared/index.js.map +1 -0
  53. package/dist-standalone/_deps/shared/types.d.ts +1097 -0
  54. package/dist-standalone/_deps/shared/types.d.ts.map +1 -0
  55. package/dist-standalone/_deps/shared/types.js +89 -0
  56. package/dist-standalone/_deps/shared/types.js.map +1 -0
  57. package/dist-standalone/_deps/ux-helpers/cjs/errors.d.ts +115 -0
  58. package/dist-standalone/_deps/ux-helpers/cjs/errors.d.ts.map +1 -0
  59. package/dist-standalone/_deps/ux-helpers/cjs/errors.js +1 -0
  60. package/dist-standalone/_deps/ux-helpers/cjs/errors.js.map +1 -0
  61. package/dist-standalone/_deps/ux-helpers/cjs/index.d.ts +13 -0
  62. package/dist-standalone/_deps/ux-helpers/cjs/index.d.ts.map +1 -0
  63. package/dist-standalone/_deps/ux-helpers/cjs/index.js +1 -0
  64. package/dist-standalone/_deps/ux-helpers/cjs/index.js.map +1 -0
  65. package/dist-standalone/_deps/ux-helpers/cjs/package.json +1 -0
  66. package/dist-standalone/_deps/ux-helpers/cjs/pagination.d.ts +39 -0
  67. package/dist-standalone/_deps/ux-helpers/cjs/pagination.d.ts.map +1 -0
  68. package/dist-standalone/_deps/ux-helpers/cjs/pagination.js +83 -0
  69. package/dist-standalone/_deps/ux-helpers/cjs/pagination.js.map +1 -0
  70. package/dist-standalone/_deps/ux-helpers/cjs/progress.d.ts +99 -0
  71. package/dist-standalone/_deps/ux-helpers/cjs/progress.d.ts.map +1 -0
  72. package/dist-standalone/_deps/ux-helpers/cjs/progress.js +143 -0
  73. package/dist-standalone/_deps/ux-helpers/cjs/progress.js.map +1 -0
  74. package/dist-standalone/_deps/ux-helpers/cjs/search.d.ts +32 -0
  75. package/dist-standalone/_deps/ux-helpers/cjs/search.d.ts.map +1 -0
  76. package/dist-standalone/_deps/ux-helpers/cjs/search.js +119 -0
  77. package/dist-standalone/_deps/ux-helpers/cjs/search.js.map +1 -0
  78. package/dist-standalone/_deps/ux-helpers/cjs/types.d.ts +109 -0
  79. package/dist-standalone/_deps/ux-helpers/cjs/types.d.ts.map +1 -0
  80. package/dist-standalone/_deps/ux-helpers/cjs/types.js +8 -0
  81. package/dist-standalone/_deps/ux-helpers/cjs/types.js.map +1 -0
  82. package/dist-standalone/_deps/ux-helpers/errors.d.ts +115 -0
  83. package/dist-standalone/_deps/ux-helpers/errors.d.ts.map +1 -0
  84. package/dist-standalone/_deps/ux-helpers/errors.js +253 -0
  85. package/dist-standalone/_deps/ux-helpers/errors.js.map +1 -0
  86. package/dist-standalone/_deps/ux-helpers/index.d.ts +13 -0
  87. package/dist-standalone/_deps/ux-helpers/index.d.ts.map +1 -0
  88. package/dist-standalone/_deps/ux-helpers/index.js +16 -0
  89. package/dist-standalone/_deps/ux-helpers/index.js.map +1 -0
  90. package/dist-standalone/_deps/ux-helpers/pagination.d.ts +39 -0
  91. package/dist-standalone/_deps/ux-helpers/pagination.d.ts.map +1 -0
  92. package/dist-standalone/_deps/ux-helpers/pagination.js +79 -0
  93. package/dist-standalone/_deps/ux-helpers/pagination.js.map +1 -0
  94. package/dist-standalone/_deps/ux-helpers/progress.d.ts +99 -0
  95. package/dist-standalone/_deps/ux-helpers/progress.d.ts.map +1 -0
  96. package/dist-standalone/_deps/ux-helpers/progress.js +138 -0
  97. package/dist-standalone/_deps/ux-helpers/progress.js.map +1 -0
  98. package/dist-standalone/_deps/ux-helpers/search.d.ts +32 -0
  99. package/dist-standalone/_deps/ux-helpers/search.d.ts.map +1 -0
  100. package/dist-standalone/_deps/ux-helpers/search.js +116 -0
  101. package/dist-standalone/_deps/ux-helpers/search.js.map +1 -0
  102. package/dist-standalone/_deps/ux-helpers/types.d.ts +109 -0
  103. package/dist-standalone/_deps/ux-helpers/types.d.ts.map +1 -0
  104. package/dist-standalone/_deps/ux-helpers/types.js +7 -0
  105. package/dist-standalone/_deps/ux-helpers/types.js.map +1 -0
  106. package/dist-standalone/_deps/xchange/auto-accept.d.ts +127 -0
  107. package/dist-standalone/_deps/xchange/auto-accept.js +1 -0
  108. package/dist-standalone/_deps/xchange/cjs/auto-accept.js +1 -0
  109. package/dist-standalone/_deps/xchange/cjs/errors.js +1 -0
  110. package/dist-standalone/_deps/xchange/cjs/index.js +1 -0
  111. package/dist-standalone/_deps/xchange/cjs/invite-client.js +1 -0
  112. package/dist-standalone/_deps/xchange/cjs/lazy-init.js +1 -0
  113. package/dist-standalone/_deps/xchange/cjs/package.json +1 -0
  114. package/dist-standalone/_deps/xchange/cjs/trust-integration.js +1 -0
  115. package/dist-standalone/_deps/xchange/cjs/xchange.js +1 -0
  116. package/dist-standalone/_deps/xchange/errors.d.ts +69 -0
  117. package/dist-standalone/_deps/xchange/errors.js +1 -0
  118. package/dist-standalone/_deps/xchange/index.d.ts +15 -0
  119. package/dist-standalone/_deps/xchange/index.js +1 -0
  120. package/dist-standalone/_deps/xchange/invite-client.d.ts +178 -0
  121. package/dist-standalone/_deps/xchange/invite-client.js +1 -0
  122. package/dist-standalone/_deps/xchange/lazy-init.d.ts +176 -0
  123. package/dist-standalone/_deps/xchange/lazy-init.js +1 -0
  124. package/dist-standalone/_deps/xchange/trust-integration.d.ts +102 -0
  125. package/dist-standalone/_deps/xchange/trust-integration.js +1 -0
  126. package/dist-standalone/_deps/xchange/xchange.d.ts +60 -0
  127. package/dist-standalone/_deps/xchange/xchange.js +1 -0
  128. package/dist-standalone/_deps/xregistry/cjs/discovery.js +1 -0
  129. package/dist-standalone/_deps/xregistry/cjs/errors.js +1 -0
  130. package/dist-standalone/_deps/xregistry/cjs/index.js +1 -0
  131. package/dist-standalone/_deps/xregistry/cjs/package.json +1 -0
  132. package/dist-standalone/_deps/xregistry/cjs/registry.js +1 -0
  133. package/dist-standalone/_deps/xregistry/cjs/schema.js +1 -0
  134. package/dist-standalone/_deps/xregistry/cjs/types.js +1 -0
  135. package/dist-standalone/_deps/xregistry/discovery.d.ts +126 -0
  136. package/dist-standalone/_deps/xregistry/discovery.d.ts.map +1 -0
  137. package/dist-standalone/_deps/xregistry/discovery.js +1 -0
  138. package/dist-standalone/_deps/xregistry/discovery.js.map +1 -0
  139. package/dist-standalone/_deps/xregistry/errors.d.ts +41 -0
  140. package/dist-standalone/_deps/xregistry/errors.d.ts.map +1 -0
  141. package/dist-standalone/_deps/xregistry/errors.js +1 -0
  142. package/dist-standalone/_deps/xregistry/errors.js.map +1 -0
  143. package/dist-standalone/_deps/xregistry/index.d.ts +8 -0
  144. package/dist-standalone/_deps/xregistry/index.d.ts.map +1 -0
  145. package/dist-standalone/_deps/xregistry/index.js +1 -0
  146. package/dist-standalone/_deps/xregistry/index.js.map +1 -0
  147. package/dist-standalone/_deps/xregistry/registry.d.ts +85 -0
  148. package/dist-standalone/_deps/xregistry/registry.d.ts.map +1 -0
  149. package/dist-standalone/_deps/xregistry/registry.js +1 -0
  150. package/dist-standalone/_deps/xregistry/registry.js.map +1 -0
  151. package/dist-standalone/_deps/xregistry/schema.d.ts +81 -0
  152. package/dist-standalone/_deps/xregistry/schema.d.ts.map +1 -0
  153. package/dist-standalone/_deps/xregistry/schema.js +1 -0
  154. package/dist-standalone/_deps/xregistry/schema.js.map +1 -0
  155. package/dist-standalone/_deps/xregistry/types.d.ts +95 -0
  156. package/dist-standalone/_deps/xregistry/types.d.ts.map +1 -0
  157. package/dist-standalone/_deps/xregistry/types.js +1 -0
  158. package/dist-standalone/_deps/xregistry/types.js.map +1 -0
  159. package/dist-standalone/agent-call.d.ts +286 -0
  160. package/dist-standalone/agent-call.js +642 -0
  161. package/dist-standalone/agent-sdk.d.ts +207 -0
  162. package/dist-standalone/agent-sdk.js +328 -0
  163. package/dist-standalone/agent.d.ts +670 -0
  164. package/dist-standalone/agent.js +1529 -0
  165. package/dist-standalone/approval.d.ts +145 -0
  166. package/dist-standalone/approval.js +193 -0
  167. package/dist-standalone/auth.d.ts +75 -0
  168. package/dist-standalone/auth.js +219 -0
  169. package/dist-standalone/auto-accept.d.ts +102 -0
  170. package/dist-standalone/auto-accept.js +229 -0
  171. package/dist-standalone/backup-config.d.ts +150 -0
  172. package/dist-standalone/backup-config.js +201 -0
  173. package/dist-standalone/checkpoint.d.ts +125 -0
  174. package/dist-standalone/checkpoint.js +186 -0
  175. package/dist-standalone/cjs/agent-call.js +651 -0
  176. package/dist-standalone/cjs/agent-sdk.js +332 -0
  177. package/dist-standalone/cjs/agent.js +1566 -0
  178. package/dist-standalone/cjs/approval.js +199 -0
  179. package/dist-standalone/cjs/auth.js +225 -0
  180. package/dist-standalone/cjs/auto-accept.js +233 -0
  181. package/dist-standalone/cjs/backup-config.js +207 -0
  182. package/dist-standalone/cjs/checkpoint.js +193 -0
  183. package/dist-standalone/cjs/cli/init.js +487 -0
  184. package/dist-standalone/cjs/connect.js +312 -0
  185. package/dist-standalone/cjs/did-document.js +101 -0
  186. package/dist-standalone/cjs/did-privateme.js +130 -0
  187. package/dist-standalone/cjs/did-web.js +201 -0
  188. package/dist-standalone/cjs/discovery.js +462 -0
  189. package/dist-standalone/cjs/dual-mode.js +251 -0
  190. package/dist-standalone/cjs/email-templates.js +313 -0
  191. package/dist-standalone/cjs/email-transport.js +239 -0
  192. package/dist-standalone/cjs/envelope.js +510 -0
  193. package/dist-standalone/cjs/errors.js +562 -0
  194. package/dist-standalone/cjs/gateway-state.js +55 -0
  195. package/dist-standalone/cjs/gateway-transport.js +120 -0
  196. package/dist-standalone/cjs/guardrails.js +223 -0
  197. package/dist-standalone/cjs/http-compat.js +272 -0
  198. package/dist-standalone/cjs/identity.js +541 -0
  199. package/dist-standalone/cjs/index.js +224 -0
  200. package/dist-standalone/cjs/invitation.js +421 -0
  201. package/dist-standalone/cjs/invite.js +328 -0
  202. package/dist-standalone/cjs/key-agreement.js +246 -0
  203. package/dist-standalone/cjs/lazy-init.js +300 -0
  204. package/dist-standalone/cjs/mdns-discovery.js +202 -0
  205. package/dist-standalone/cjs/nonce-store.js +66 -0
  206. package/dist-standalone/cjs/package.json +3 -0
  207. package/dist-standalone/cjs/pairing-manager.js +223 -0
  208. package/dist-standalone/cjs/policy.js +320 -0
  209. package/dist-standalone/cjs/redis-nonce-store.js +76 -0
  210. package/dist-standalone/cjs/registry-middleware.js +50 -0
  211. package/dist-standalone/cjs/retry-transport.js +102 -0
  212. package/dist-standalone/cjs/security-policy.js +204 -0
  213. package/dist-standalone/cjs/split-channel.js +177 -0
  214. package/dist-standalone/cjs/subscription-proof.js +230 -0
  215. package/dist-standalone/cjs/succession.js +148 -0
  216. package/dist-standalone/cjs/transport.js +63 -0
  217. package/dist-standalone/cjs/trust-registry.js +742 -0
  218. package/dist-standalone/cjs/verify.js +25 -0
  219. package/dist-standalone/cjs/xfetch.js +252 -0
  220. package/dist-standalone/cli/init.d.ts +63 -0
  221. package/dist-standalone/cli/init.js +450 -0
  222. package/dist-standalone/connect.d.ts +143 -0
  223. package/dist-standalone/connect.js +274 -0
  224. package/dist-standalone/did-document.d.ts +65 -0
  225. package/dist-standalone/did-document.js +96 -0
  226. package/dist-standalone/did-privateme.d.ts +70 -0
  227. package/dist-standalone/did-privateme.js +121 -0
  228. package/dist-standalone/did-web.d.ts +73 -0
  229. package/dist-standalone/did-web.js +196 -0
  230. package/dist-standalone/discovery.d.ts +176 -0
  231. package/dist-standalone/discovery.js +458 -0
  232. package/dist-standalone/dual-mode.d.ts +145 -0
  233. package/dist-standalone/dual-mode.js +247 -0
  234. package/dist-standalone/email-templates.d.ts +41 -0
  235. package/dist-standalone/email-templates.js +309 -0
  236. package/dist-standalone/email-transport.d.ts +139 -0
  237. package/dist-standalone/email-transport.js +232 -0
  238. package/dist-standalone/envelope.d.ts +288 -0
  239. package/dist-standalone/envelope.js +497 -0
  240. package/dist-standalone/errors.d.ts +74 -0
  241. package/dist-standalone/errors.js +548 -0
  242. package/dist-standalone/gateway-state.d.ts +32 -0
  243. package/dist-standalone/gateway-state.js +51 -0
  244. package/dist-standalone/gateway-transport.d.ts +59 -0
  245. package/dist-standalone/gateway-transport.js +116 -0
  246. package/dist-standalone/guardrails.d.ts +136 -0
  247. package/dist-standalone/guardrails.js +216 -0
  248. package/dist-standalone/http-compat.d.ts +150 -0
  249. package/dist-standalone/http-compat.js +267 -0
  250. package/dist-standalone/identity.d.ts +176 -0
  251. package/dist-standalone/identity.js +516 -0
  252. package/dist-standalone/index.d.ts +83 -0
  253. package/dist-standalone/index.js +51 -0
  254. package/dist-standalone/invitation.d.ts +211 -0
  255. package/dist-standalone/invitation.js +415 -0
  256. package/dist-standalone/invite.d.ts +192 -0
  257. package/dist-standalone/invite.js +324 -0
  258. package/dist-standalone/key-agreement.d.ts +122 -0
  259. package/dist-standalone/key-agreement.js +236 -0
  260. package/dist-standalone/lazy-init.d.ts +167 -0
  261. package/dist-standalone/lazy-init.js +295 -0
  262. package/dist-standalone/mdns-discovery.d.ts +117 -0
  263. package/dist-standalone/mdns-discovery.js +195 -0
  264. package/dist-standalone/nonce-store.d.ts +39 -0
  265. package/dist-standalone/nonce-store.js +62 -0
  266. package/dist-standalone/package.json +11 -0
  267. package/dist-standalone/pairing-manager.d.ts +147 -0
  268. package/dist-standalone/pairing-manager.js +219 -0
  269. package/dist-standalone/policy.d.ts +150 -0
  270. package/dist-standalone/policy.js +315 -0
  271. package/dist-standalone/redis-nonce-store.d.ts +93 -0
  272. package/dist-standalone/redis-nonce-store.js +72 -0
  273. package/dist-standalone/registry-middleware.d.ts +38 -0
  274. package/dist-standalone/registry-middleware.js +47 -0
  275. package/dist-standalone/retry-transport.d.ts +76 -0
  276. package/dist-standalone/retry-transport.js +98 -0
  277. package/dist-standalone/security-policy.d.ts +146 -0
  278. package/dist-standalone/security-policy.js +198 -0
  279. package/dist-standalone/split-channel.d.ts +69 -0
  280. package/dist-standalone/split-channel.js +171 -0
  281. package/dist-standalone/subscription-proof.d.ts +103 -0
  282. package/dist-standalone/subscription-proof.js +224 -0
  283. package/dist-standalone/succession.d.ts +57 -0
  284. package/dist-standalone/succession.js +142 -0
  285. package/dist-standalone/transport.d.ts +50 -0
  286. package/dist-standalone/transport.js +59 -0
  287. package/dist-standalone/trust-registry.d.ts +286 -0
  288. package/dist-standalone/trust-registry.js +702 -0
  289. package/dist-standalone/verify.d.ts +16 -0
  290. package/dist-standalone/verify.js +16 -0
  291. package/dist-standalone/xfetch.d.ts +129 -0
  292. package/dist-standalone/xfetch.js +247 -0
  293. package/llms.txt +800 -0
  294. package/package.json +79 -0
  295. package/share1.dat +0 -0
@@ -0,0 +1,195 @@
1
+ /**
2
+ * TLV (Type-Length-Value) serialization for Xail messages.
3
+ *
4
+ * Format: [Type: 1 byte][Length: 4 bytes uint32 BE][Value: Length bytes]
5
+ *
6
+ * Serialization order: MESSAGE_UUID, SENDER_ID, TIMESTAMP, CONTENT_TYPE,
7
+ * MESSAGE_BODY, ATTACHMENT(s).
8
+ *
9
+ * HMAC key/signature and per-share metadata are NOT in the TLV payload —
10
+ * they travel in the share envelope.
11
+ */
12
+ import { ok, err, TLV_TYPE } from"../shared/index.js";
13
+ import { uuidToBytes, bytesToUuid } from './uuid.js';
14
+ const TEXT_ENCODER = new TextEncoder();
15
+ const TEXT_DECODER = new TextDecoder();
16
+ /**
17
+ * Serialize a XailMessage into a TLV byte stream.
18
+ *
19
+ * @param message - Message to serialize
20
+ * @returns TLV-encoded byte array
21
+ */
22
+ export function serializeMessage(message) {
23
+ const parts = [];
24
+ // MESSAGE_UUID
25
+ parts.push(encodeTlv(TLV_TYPE.MESSAGE_UUID, uuidToBytes(message.uuid)));
26
+ // SENDER_ID
27
+ parts.push(encodeTlv(TLV_TYPE.SENDER_ID, TEXT_ENCODER.encode(message.sender.name)));
28
+ // SENDER_EMAIL (optional — preserves sender's email across reconstruction)
29
+ const senderEmail = message.sender.channels[0]?.email;
30
+ if (senderEmail) {
31
+ parts.push(encodeTlv(TLV_TYPE.SENDER_EMAIL, TEXT_ENCODER.encode(senderEmail)));
32
+ }
33
+ // TIMESTAMP (8 bytes, uint64 big-endian)
34
+ const tsBuf = new Uint8Array(8);
35
+ const tsView = new DataView(tsBuf.buffer);
36
+ // Split into high 32 and low 32 bits
37
+ tsView.setUint32(0, Math.floor(message.timestamp / 0x100000000));
38
+ tsView.setUint32(4, message.timestamp >>> 0);
39
+ parts.push(encodeTlv(TLV_TYPE.TIMESTAMP, tsBuf));
40
+ // CONTENT_TYPE
41
+ parts.push(encodeTlv(TLV_TYPE.CONTENT_TYPE, TEXT_ENCODER.encode(message.contentType)));
42
+ // MESSAGE_SUBJECT (optional)
43
+ if (message.subject) {
44
+ parts.push(encodeTlv(TLV_TYPE.MESSAGE_SUBJECT, TEXT_ENCODER.encode(message.subject)));
45
+ }
46
+ // MESSAGE_BODY
47
+ parts.push(encodeTlv(TLV_TYPE.MESSAGE_BODY, TEXT_ENCODER.encode(message.body)));
48
+ // ATTACHMENTs
49
+ for (const att of message.attachments) {
50
+ parts.push(encodeTlv(TLV_TYPE.ATTACHMENT, encodeAttachment(att)));
51
+ }
52
+ // Concatenate all parts
53
+ const totalLen = parts.reduce((sum, p) => sum + p.length, 0);
54
+ const result = new Uint8Array(totalLen);
55
+ let offset = 0;
56
+ for (const part of parts) {
57
+ result.set(part, offset);
58
+ offset += part.length;
59
+ }
60
+ return result;
61
+ }
62
+ /**
63
+ * Deserialize a TLV byte stream into a XailMessage.
64
+ *
65
+ * @param data - TLV-encoded byte array
66
+ * @returns Deserialized message, or SerializationError if invalid
67
+ */
68
+ export function deserializeMessage(data) {
69
+ let uuid = '';
70
+ let senderName = '';
71
+ let senderEmail = '';
72
+ let subject = '';
73
+ let timestamp = 0;
74
+ let contentType = 'text/plain';
75
+ let body = '';
76
+ const attachments = [];
77
+ let offset = 0;
78
+ while (offset < data.length) {
79
+ if (offset + 5 > data.length) {
80
+ return err({ code: 'INVALID_TLV', message: 'Truncated TLV header' });
81
+ }
82
+ const type = data[offset];
83
+ const view = new DataView(data.buffer, data.byteOffset + offset + 1, 4);
84
+ const length = view.getUint32(0);
85
+ offset += 5;
86
+ if (offset + length > data.length) {
87
+ return err({ code: 'BUFFER_OVERFLOW', message: `TLV value exceeds data length at type 0x${type.toString(16)}` });
88
+ }
89
+ const value = data.slice(offset, offset + length);
90
+ offset += length;
91
+ switch (type) {
92
+ case TLV_TYPE.MESSAGE_UUID:
93
+ if (value.length !== 16) {
94
+ return err({ code: 'INVALID_TLV', message: 'UUID must be 16 bytes' });
95
+ }
96
+ uuid = bytesToUuid(value);
97
+ break;
98
+ case TLV_TYPE.SENDER_ID:
99
+ senderName = TEXT_DECODER.decode(value);
100
+ break;
101
+ case TLV_TYPE.SENDER_EMAIL:
102
+ senderEmail = TEXT_DECODER.decode(value);
103
+ break;
104
+ case TLV_TYPE.TIMESTAMP: {
105
+ if (value.length !== 8) {
106
+ return err({ code: 'INVALID_TLV', message: 'Timestamp must be 8 bytes' });
107
+ }
108
+ const tsView = new DataView(value.buffer, value.byteOffset, 8);
109
+ const hi = tsView.getUint32(0);
110
+ const lo = tsView.getUint32(4);
111
+ timestamp = hi * 0x100000000 + lo;
112
+ break;
113
+ }
114
+ case TLV_TYPE.CONTENT_TYPE: {
115
+ const ct = TEXT_DECODER.decode(value);
116
+ if (ct === 'text/plain' || ct === 'text/html') {
117
+ contentType = ct;
118
+ }
119
+ break;
120
+ }
121
+ case TLV_TYPE.MESSAGE_SUBJECT:
122
+ subject = TEXT_DECODER.decode(value);
123
+ break;
124
+ case TLV_TYPE.MESSAGE_BODY:
125
+ body = TEXT_DECODER.decode(value);
126
+ break;
127
+ case TLV_TYPE.ATTACHMENT:
128
+ attachments.push(decodeAttachment(value));
129
+ break;
130
+ default:
131
+ // Unknown type — skip (forward compatibility)
132
+ break;
133
+ }
134
+ }
135
+ if (!uuid) {
136
+ return err({ code: 'MISSING_FIELD', message: 'Missing MESSAGE_UUID' });
137
+ }
138
+ return ok({
139
+ uuid,
140
+ sender: {
141
+ name: senderName,
142
+ channels: senderEmail
143
+ ? [{ provider: 'imap', email: senderEmail }]
144
+ : [],
145
+ securityTier: null,
146
+ isEnterprise: false,
147
+ },
148
+ recipients: [],
149
+ ...(subject ? { subject } : {}),
150
+ body,
151
+ contentType,
152
+ attachments,
153
+ timestamp,
154
+ messageType: 'secure',
155
+ });
156
+ }
157
+ /** Encode a single TLV entry. */
158
+ function encodeTlv(type, value) {
159
+ const entry = new Uint8Array(5 + value.length);
160
+ entry[0] = type;
161
+ const view = new DataView(entry.buffer, 1, 4);
162
+ view.setUint32(0, value.length);
163
+ entry.set(value, 5);
164
+ return entry;
165
+ }
166
+ /**
167
+ * Encode an attachment: filename (null-terminated, up to 255 bytes) + content.
168
+ */
169
+ function encodeAttachment(att) {
170
+ const nameBytes = TEXT_ENCODER.encode(att.filename);
171
+ const mimeBytes = TEXT_ENCODER.encode(att.mimeType);
172
+ // Format: [nameLen:1][name][mimeLen:1][mime][data]
173
+ const result = new Uint8Array(1 + nameBytes.length + 1 + mimeBytes.length + att.data.length);
174
+ let off = 0;
175
+ result[off++] = nameBytes.length;
176
+ result.set(nameBytes, off);
177
+ off += nameBytes.length;
178
+ result[off++] = mimeBytes.length;
179
+ result.set(mimeBytes, off);
180
+ off += mimeBytes.length;
181
+ result.set(att.data, off);
182
+ return result;
183
+ }
184
+ /** Decode an attachment from the encoded format. */
185
+ function decodeAttachment(data) {
186
+ let off = 0;
187
+ const nameLen = data[off++];
188
+ const filename = TEXT_DECODER.decode(data.slice(off, off + nameLen));
189
+ off += nameLen;
190
+ const mimeLen = data[off++];
191
+ const mimeType = TEXT_DECODER.decode(data.slice(off, off + mimeLen));
192
+ off += mimeLen;
193
+ const content = data.slice(off);
194
+ return { filename, mimeType, data: content };
195
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Generate a RFC 4122 Version 4 UUID (128-bit random).
3
+ * Uses crypto.randomUUID() when available, otherwise constructs manually
4
+ * from crypto.getRandomValues() with proper version/variant bits.
5
+ *
6
+ * @returns UUID string in standard 8-4-4-4-12 hex format
7
+ */
8
+ export declare function generateUUID(): string;
9
+ /**
10
+ * Parse a UUID string into its raw 16 bytes.
11
+ *
12
+ * @param uuid - UUID string in 8-4-4-4-12 hex format
13
+ * @returns 16-byte Uint8Array
14
+ */
15
+ export declare function uuidToBytes(uuid: string): Uint8Array;
16
+ /**
17
+ * Convert raw 16 UUID bytes to the standard string format.
18
+ *
19
+ * @param bytes - 16-byte Uint8Array
20
+ * @returns UUID string in 8-4-4-4-12 hex format
21
+ */
22
+ export declare function bytesToUuid(bytes: Uint8Array): string;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Generate a RFC 4122 Version 4 UUID (128-bit random).
3
+ * Uses crypto.randomUUID() when available, otherwise constructs manually
4
+ * from crypto.getRandomValues() with proper version/variant bits.
5
+ *
6
+ * @returns UUID string in standard 8-4-4-4-12 hex format
7
+ */
8
+ export function generateUUID() {
9
+ if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {
10
+ return crypto.randomUUID();
11
+ }
12
+ const bytes = new Uint8Array(16);
13
+ crypto.getRandomValues(bytes);
14
+ // Set version 4 (bits 12-15 of time_hi_and_version)
15
+ bytes[6] = (bytes[6] & 0x0f) | 0x40;
16
+ // Set variant 10xx (bits 6-7 of clock_seq_hi_and_reserved)
17
+ bytes[8] = (bytes[8] & 0x3f) | 0x80;
18
+ const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');
19
+ return [
20
+ hex.slice(0, 8),
21
+ hex.slice(8, 12),
22
+ hex.slice(12, 16),
23
+ hex.slice(16, 20),
24
+ hex.slice(20, 32),
25
+ ].join('-');
26
+ }
27
+ /**
28
+ * Parse a UUID string into its raw 16 bytes.
29
+ *
30
+ * @param uuid - UUID string in 8-4-4-4-12 hex format
31
+ * @returns 16-byte Uint8Array
32
+ */
33
+ export function uuidToBytes(uuid) {
34
+ const hex = uuid.replace(/-/g, '');
35
+ const bytes = new Uint8Array(16);
36
+ for (let i = 0; i < 16; i++) {
37
+ bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
38
+ }
39
+ return bytes;
40
+ }
41
+ /**
42
+ * Convert raw 16 UUID bytes to the standard string format.
43
+ *
44
+ * @param bytes - 16-byte Uint8Array
45
+ * @returns UUID string in 8-4-4-4-12 hex format
46
+ */
47
+ export function bytesToUuid(bytes) {
48
+ const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');
49
+ return [
50
+ hex.slice(0, 8),
51
+ hex.slice(8, 12),
52
+ hex.slice(12, 16),
53
+ hex.slice(16, 20),
54
+ hex.slice(20, 32),
55
+ ].join('-');
56
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @module verify
3
+ * Lightweight sub-path export for verification-only use cases.
4
+ *
5
+ * Import as `@private.me/crypto/verify` for tree-shaking:
6
+ * ```ts
7
+ * import { verifyHMAC, fromBase64, isSupported } from '@private.me/crypto/verify';
8
+ * ```
9
+ *
10
+ * This module re-exports only HMAC verification, base64 decoding,
11
+ * and the capability check — no splitting, no reconstruction, no padding.
12
+ */
13
+ export { verifyHMAC } from './hmac.js';
14
+ export { fromBase64, toBase64, fromBase64Url, toBase64Url } from './base64.js';
15
+ export { isSupported } from './index.js';
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @module verify
3
+ * Lightweight sub-path export for verification-only use cases.
4
+ *
5
+ * Import as `@private.me/crypto/verify` for tree-shaking:
6
+ * ```ts
7
+ * import { verifyHMAC, fromBase64, isSupported } from '@private.me/crypto/verify';
8
+ * ```
9
+ *
10
+ * This module re-exports only HMAC verification, base64 decoding,
11
+ * and the capability check — no splitting, no reconstruction, no padding.
12
+ */
13
+ export { verifyHMAC } from './hmac.js';
14
+ export { fromBase64, toBase64, fromBase64Url, toBase64Url } from './base64.js';
15
+ export { isSupported } from './index.js';
@@ -0,0 +1,44 @@
1
+ /**
2
+ * XorIDA Threshold Secret Sharing over GF(2).
3
+ *
4
+ * Proprietary, patent-protected (k,n)-threshold secret sharing construction.
5
+ *
6
+ * All arithmetic is XOR (GF(2)). The generator matrix is constructed from a cyclic
7
+ * index formula using NextOddPrime(n). Any k-of-n shares reconstruct the original
8
+ * message via Gaussian elimination on the restricted generator matrix.
9
+ */
10
+ /**
11
+ * Find the smallest odd prime >= n.
12
+ * Used to determine the cyclic group Z_p for generator matrix construction.
13
+ *
14
+ * @param n - Total number of shares
15
+ * @returns Smallest odd prime >= n
16
+ */
17
+ export declare function nextOddPrime(n: number): number;
18
+ /**
19
+ * Split a padded message into n shares using XorIDA threshold sharing.
20
+ *
21
+ * The message length must be a multiple of b = NextOddPrime(n) - 1.
22
+ * Each share is the same length as the input message.
23
+ *
24
+ * @param paddedMessage - PKCS#7-padded message (length must be multiple of b)
25
+ * @param n - Total number of shares to produce
26
+ * @param k - Threshold: minimum shares needed for reconstruction
27
+ * @returns Array of n shares, each the same length as paddedMessage
28
+ */
29
+ export declare function splitXorIDA(paddedMessage: Uint8Array, n: number, k: number): Uint8Array[];
30
+ /**
31
+ * Split with externally provided random source arrays (for testing with known vectors).
32
+ * @internal Exported for testing only.
33
+ */
34
+ export declare function splitWithRandom(paddedMessage: Uint8Array, n: number, k: number, p: number, b: number, randomArrays?: Uint8Array[]): Uint8Array[];
35
+ /**
36
+ * Reconstruct the padded message from k shares via GF(2) Gaussian elimination.
37
+ *
38
+ * @param shares - Array of k share byte arrays
39
+ * @param indices - Original indices (0-based) of the provided shares
40
+ * @param n - Total number of shares that were produced
41
+ * @param k - Threshold used during splitting
42
+ * @returns Reconstructed padded message
43
+ */
44
+ export declare function reconstructXorIDA(shares: Uint8Array[], indices: number[], n: number, k: number): Uint8Array;
@@ -0,0 +1,215 @@
1
+ /**
2
+ * XorIDA Threshold Secret Sharing over GF(2).
3
+ *
4
+ * Proprietary, patent-protected (k,n)-threshold secret sharing construction.
5
+ *
6
+ * All arithmetic is XOR (GF(2)). The generator matrix is constructed from a cyclic
7
+ * index formula using NextOddPrime(n). Any k-of-n shares reconstruct the original
8
+ * message via Gaussian elimination on the restricted generator matrix.
9
+ */
10
+ /**
11
+ * Find the smallest odd prime >= n.
12
+ * Used to determine the cyclic group Z_p for generator matrix construction.
13
+ *
14
+ * @param n - Total number of shares
15
+ * @returns Smallest odd prime >= n
16
+ */
17
+ export function nextOddPrime(n) {
18
+ let i = n;
19
+ while (true) {
20
+ if (i >= 2 && isOddPrime(i))
21
+ return i;
22
+ i++;
23
+ }
24
+ }
25
+ /** Max bytes per crypto.getRandomValues call (Web Crypto API limit). */
26
+ const MAX_RANDOM_CHUNK = 65536;
27
+ /** Fill a Uint8Array with cryptographic random bytes, chunked to respect API limits. */
28
+ function fillRandom(arr) {
29
+ for (let offset = 0; offset < arr.length; offset += MAX_RANDOM_CHUNK) {
30
+ const end = Math.min(offset + MAX_RANDOM_CHUNK, arr.length);
31
+ crypto.getRandomValues(arr.subarray(offset, end));
32
+ }
33
+ }
34
+ /** Check if a number is an odd prime. */
35
+ function isOddPrime(n) {
36
+ if (n < 2)
37
+ return false;
38
+ if (n === 2)
39
+ return false; // even
40
+ if (n === 3)
41
+ return true;
42
+ if (n % 2 === 0)
43
+ return false;
44
+ for (let d = 3; d * d <= n; d += 2) {
45
+ if (n % d === 0)
46
+ return false;
47
+ }
48
+ return true;
49
+ }
50
+ /**
51
+ * Split a padded message into n shares using XorIDA threshold sharing.
52
+ *
53
+ * The message length must be a multiple of b = NextOddPrime(n) - 1.
54
+ * Each share is the same length as the input message.
55
+ *
56
+ * @param paddedMessage - PKCS#7-padded message (length must be multiple of b)
57
+ * @param n - Total number of shares to produce
58
+ * @param k - Threshold: minimum shares needed for reconstruction
59
+ * @returns Array of n shares, each the same length as paddedMessage
60
+ */
61
+ export function splitXorIDA(paddedMessage, n, k) {
62
+ const p = nextOddPrime(n);
63
+ const b = p - 1;
64
+ if (paddedMessage.length === 0 || paddedMessage.length % b !== 0) {
65
+ throw new Error(`Message length ${paddedMessage.length} is not a multiple of block size ${b}`);
66
+ }
67
+ return splitWithRandom(paddedMessage, n, k, p, b);
68
+ }
69
+ /**
70
+ * Split with externally provided random source arrays (for testing with known vectors).
71
+ * @internal Exported for testing only.
72
+ */
73
+ export function splitWithRandom(paddedMessage, n, k, p, b, randomArrays) {
74
+ const msgLen = paddedMessage.length;
75
+ const numBlocks = msgLen / b;
76
+ // Step 1: Create k source arrays — (k-1) random + message
77
+ const sourceArrays = [];
78
+ for (let i = 0; i < k - 1; i++) {
79
+ const provided = randomArrays?.[i];
80
+ if (provided) {
81
+ sourceArrays.push(provided);
82
+ }
83
+ else {
84
+ const rand = new Uint8Array(msgLen);
85
+ fillRandom(rand);
86
+ sourceArrays.push(rand);
87
+ }
88
+ }
89
+ sourceArrays.push(paddedMessage);
90
+ // Step 2: Construct each share using the generator matrix index formula
91
+ const shares = [];
92
+ for (let shareIdx = 0; shareIdx < n; shareIdx++) {
93
+ const share = new Uint8Array(msgLen);
94
+ for (let blockIdx = 0; blockIdx < numBlocks; blockIdx++) {
95
+ const blockOffset = blockIdx * b;
96
+ for (let destRow = 0; destRow < b; destRow++) {
97
+ for (let srcCol = 0; srcCol < k; srcCol++) {
98
+ const srcRow = (destRow + shareIdx * srcCol) % p;
99
+ if (srcRow < b) {
100
+ share[blockOffset + destRow] ^=
101
+ sourceArrays[srcCol][blockOffset + srcRow];
102
+ }
103
+ }
104
+ }
105
+ }
106
+ shares.push(share);
107
+ }
108
+ return shares;
109
+ }
110
+ /**
111
+ * Reconstruct the padded message from k shares via GF(2) Gaussian elimination.
112
+ *
113
+ * @param shares - Array of k share byte arrays
114
+ * @param indices - Original indices (0-based) of the provided shares
115
+ * @param n - Total number of shares that were produced
116
+ * @param k - Threshold used during splitting
117
+ * @returns Reconstructed padded message
118
+ */
119
+ export function reconstructXorIDA(shares, indices, n, k) {
120
+ if (shares.length !== k || indices.length !== k) {
121
+ throw new Error(`Expected ${k} shares, got ${shares.length}`);
122
+ }
123
+ const p = nextOddPrime(n);
124
+ const b = p - 1;
125
+ const shareLen = shares[0].length;
126
+ const numBlocks = shareLen / b;
127
+ // Step 1: Build restricted generator matrix G (k*b rows × k*b cols)
128
+ const numRows = k * b;
129
+ const numCols = k * b;
130
+ const recoveryMatrix = buildAndSolve(indices, k, p, b, numRows, numCols);
131
+ // Step 2: Apply recovery matrix to extract message bytes
132
+ const result = new Uint8Array(shareLen);
133
+ for (let blockIdx = 0; blockIdx < numBlocks; blockIdx++) {
134
+ const blockOffset = blockIdx * b;
135
+ for (let destByte = 0; destByte < b; destByte++) {
136
+ // Skip random rows, use message rows: row index = (k-1)*b + destByte
137
+ const recoveryRow = (k - 1) * b + destByte;
138
+ let val = 0;
139
+ for (let c = 0; c < numRows; c++) {
140
+ if (recoveryMatrix[recoveryRow][c]) {
141
+ const localShareIdx = Math.floor(c / b);
142
+ const byteInBlock = c % b;
143
+ val ^= shares[localShareIdx][blockOffset + byteInBlock];
144
+ }
145
+ }
146
+ result[blockOffset + destByte] = val;
147
+ }
148
+ }
149
+ return result;
150
+ }
151
+ /**
152
+ * Build the restricted generator matrix and solve via Gaussian elimination.
153
+ * Returns the recovery matrix (right portion of [G|I] after elimination).
154
+ */
155
+ function buildAndSolve(shareIndices, k, p, b, numRows, numCols) {
156
+ // Build augmented matrix [G | I] using Uint8Array rows
157
+ const totalCols = numCols + numRows;
158
+ const aug = [];
159
+ for (let i = 0; i < k; i++) {
160
+ const shareIdx = shareIndices[i];
161
+ for (let rowInShare = 0; rowInShare < b; rowInShare++) {
162
+ const row = new Uint8Array(totalCols);
163
+ const destRow = i * b + rowInShare;
164
+ // Fill generator matrix portion
165
+ for (let srcCol = 0; srcCol < k; srcCol++) {
166
+ const srcRow = (rowInShare + shareIdx * srcCol) % p;
167
+ if (srcRow < b) {
168
+ row[srcCol * b + srcRow] = 1;
169
+ }
170
+ }
171
+ // Fill identity portion
172
+ row[numCols + destRow] = 1;
173
+ aug.push(row);
174
+ }
175
+ }
176
+ // Gaussian elimination over GF(2)
177
+ let pivotRow = 0;
178
+ for (let col = 0; col < numCols; col++) {
179
+ // Find pivot
180
+ let found = -1;
181
+ for (let r = pivotRow; r < numRows; r++) {
182
+ if (aug[r][col]) {
183
+ found = r;
184
+ break;
185
+ }
186
+ }
187
+ if (found === -1)
188
+ continue;
189
+ // Swap
190
+ if (found !== pivotRow) {
191
+ const tmp = aug[found];
192
+ aug[found] = aug[pivotRow];
193
+ aug[pivotRow] = tmp;
194
+ }
195
+ // Eliminate
196
+ for (let r = 0; r < numRows; r++) {
197
+ if (r !== pivotRow && aug[r][col]) {
198
+ xorRow(aug[r], aug[pivotRow]);
199
+ }
200
+ }
201
+ pivotRow++;
202
+ }
203
+ // Extract recovery matrix (right portion)
204
+ const recovery = [];
205
+ for (let r = 0; r < numRows; r++) {
206
+ recovery.push(aug[r].slice(numCols));
207
+ }
208
+ return recovery;
209
+ }
210
+ /** XOR row b into row a (in-place). */
211
+ function xorRow(a, b) {
212
+ for (let i = 0; i < a.length; i++) {
213
+ a[i] ^= b[i];
214
+ }
215
+ }
@@ -0,0 +1,24 @@
1
+ Copyright (c) 2026 Dmitry Chestnykh (WASM wrapper, JavaScript)
2
+ Copyright (c) The mldsa-native project authors
3
+ Copyright (c) The mlkem-native project authors
4
+ Copyright (c) 2020 Dougall Johnson
5
+ Copyright (c) 2022 Arm Limited
6
+ SPDX-License-Identifier: MIT
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ of this software and associated documentation files (the "Software"), to deal
10
+ in the Software without restriction, including without limitation the rights
11
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ copies of the Software, and to permit persons to whom the Software is
13
+ furnished to do so, subject to the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be included in
16
+ all copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ SOFTWARE.