@private.me/xbind 3.0.2 → 3.0.3

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 (221) hide show
  1. package/README.md +2366 -204
  2. package/README.md.backup +2121 -0
  3. package/dist-standalone/_deps/mldsa-wasm/dist/mldsa.js +1 -1920
  4. package/dist-standalone/_deps/shared/cjs/errors.js +1 -729
  5. package/dist-standalone/_deps/shared/cjs/index.js +1 -463
  6. package/dist-standalone/_deps/shared/cjs/types.js +1 -315
  7. package/dist-standalone/_deps/shared/errors.js +1 -244
  8. package/dist-standalone/_deps/shared/index.js +1 -72
  9. package/dist-standalone/_deps/shared/types.js +1 -86
  10. package/dist-standalone/_deps/ux-helpers/cjs/errors.js +1 -1
  11. package/dist-standalone/_deps/ux-helpers/cjs/index.js +1 -1
  12. package/dist-standalone/_deps/ux-helpers/cjs/pagination.js +1 -1
  13. package/dist-standalone/_deps/ux-helpers/cjs/progress.js +1 -1
  14. package/dist-standalone/_deps/ux-helpers/cjs/search.js +1 -1
  15. package/dist-standalone/_deps/ux-helpers/cjs/types.js +1 -1
  16. package/dist-standalone/_deps/ux-helpers/errors.js +1 -1
  17. package/dist-standalone/_deps/ux-helpers/index.js +1 -1
  18. package/dist-standalone/_deps/ux-helpers/pagination.js +1 -1
  19. package/dist-standalone/_deps/ux-helpers/progress.js +1 -1
  20. package/dist-standalone/_deps/ux-helpers/search.js +1 -1
  21. package/dist-standalone/_deps/xchange/auto-accept.js +1 -1
  22. package/dist-standalone/_deps/xchange/cjs/auto-accept.js +1 -1
  23. package/dist-standalone/_deps/xchange/cjs/errors.js +1 -1
  24. package/dist-standalone/_deps/xchange/cjs/index.js +1 -1
  25. package/dist-standalone/_deps/xchange/cjs/invite-client.js +1 -1
  26. package/dist-standalone/_deps/xchange/cjs/lazy-init.js +1 -1
  27. package/dist-standalone/_deps/xchange/cjs/trust-integration.js +1 -1
  28. package/dist-standalone/_deps/xchange/cjs/xchange.js +1 -1
  29. package/dist-standalone/_deps/xchange/errors.js +1 -1
  30. package/dist-standalone/_deps/xchange/index.js +1 -1
  31. package/dist-standalone/_deps/xchange/invite-client.js +1 -1
  32. package/dist-standalone/_deps/xchange/lazy-init.js +1 -1
  33. package/dist-standalone/_deps/xchange/trust-integration.js +1 -1
  34. package/dist-standalone/_deps/xchange/xchange.js +1 -1
  35. package/dist-standalone/_deps/xregistry/cjs/discovery.js +1 -1
  36. package/dist-standalone/_deps/xregistry/cjs/errors.js +1 -1
  37. package/dist-standalone/_deps/xregistry/cjs/index.js +1 -1
  38. package/dist-standalone/_deps/xregistry/cjs/registry.js +1 -1
  39. package/dist-standalone/_deps/xregistry/cjs/schema.js +1 -1
  40. package/dist-standalone/_deps/xregistry/cjs/types.js +1 -1
  41. package/dist-standalone/_deps/xregistry/discovery.js +1 -1
  42. package/dist-standalone/_deps/xregistry/errors.js +1 -1
  43. package/dist-standalone/_deps/xregistry/index.js +1 -1
  44. package/dist-standalone/_deps/xregistry/registry.js +1 -1
  45. package/dist-standalone/_deps/xregistry/schema.js +1 -1
  46. package/dist-standalone/_deps/xregistry/types.js +1 -1
  47. package/dist-standalone/agent-call.d.ts +2 -2
  48. package/dist-standalone/agent-call.js +1 -659
  49. package/dist-standalone/agent-sdk.js +1 -328
  50. package/dist-standalone/agent.d.ts +2 -0
  51. package/dist-standalone/agent.js +1 -1800
  52. package/dist-standalone/approval.js +1 -193
  53. package/dist-standalone/async-iterators.d.ts +3 -3
  54. package/dist-standalone/async-iterators.js +1 -382
  55. package/dist-standalone/auth.js +1 -219
  56. package/dist-standalone/auto-accept.js +1 -229
  57. package/dist-standalone/backup-config.js +1 -201
  58. package/dist-standalone/backup.js +1 -326
  59. package/dist-standalone/batch-operations.js +1 -388
  60. package/dist-standalone/cancellation.js +1 -477
  61. package/dist-standalone/checkpoint.js +1 -186
  62. package/dist-standalone/circuit-breaker.js +1 -468
  63. package/dist-standalone/cjs/agent-call.js +1 -701
  64. package/dist-standalone/cjs/agent-sdk.js +1 -332
  65. package/dist-standalone/cjs/agent.js +1 -1837
  66. package/dist-standalone/cjs/approval.js +1 -199
  67. package/dist-standalone/cjs/async-iterators.js +1 -392
  68. package/dist-standalone/cjs/auth.js +1 -225
  69. package/dist-standalone/cjs/auto-accept.js +1 -233
  70. package/dist-standalone/cjs/backup-config.js +1 -207
  71. package/dist-standalone/cjs/backup.js +1 -330
  72. package/dist-standalone/cjs/batch-operations.js +1 -397
  73. package/dist-standalone/cjs/cancellation.js +1 -490
  74. package/dist-standalone/cjs/checkpoint.js +1 -193
  75. package/dist-standalone/cjs/circuit-breaker.js +1 -476
  76. package/dist-standalone/cjs/cli/init.js +1 -492
  77. package/dist-standalone/cjs/config-validation.js +1 -522
  78. package/dist-standalone/cjs/connect.js +1 -312
  79. package/dist-standalone/cjs/connection-pool.js +1 -506
  80. package/dist-standalone/cjs/correlation-id.js +1 -339
  81. package/dist-standalone/cjs/crypto-utils.js +1 -176
  82. package/dist-standalone/cjs/debug-mode.js +1 -534
  83. package/dist-standalone/cjs/did-document.js +1 -101
  84. package/dist-standalone/cjs/did-privateme.js +1 -130
  85. package/dist-standalone/cjs/did-web.js +1 -201
  86. package/dist-standalone/cjs/discovery.js +1 -462
  87. package/dist-standalone/cjs/dual-mode.js +1 -251
  88. package/dist-standalone/cjs/email-templates.js +1 -313
  89. package/dist-standalone/cjs/email-transport.js +1 -239
  90. package/dist-standalone/cjs/envelope.js +1 -538
  91. package/dist-standalone/cjs/errors.js +1 -913
  92. package/dist-standalone/cjs/event-emitter.js +1 -461
  93. package/dist-standalone/cjs/gateway-state.js +1 -55
  94. package/dist-standalone/cjs/gateway-transport.js +1 -120
  95. package/dist-standalone/cjs/graceful-degradation.js +1 -403
  96. package/dist-standalone/cjs/guardrails.js +1 -223
  97. package/dist-standalone/cjs/health-check.js +1 -336
  98. package/dist-standalone/cjs/http-compat.js +1 -272
  99. package/dist-standalone/cjs/http-status-map.js +1 -571
  100. package/dist-standalone/cjs/identity.js +1 -645
  101. package/dist-standalone/cjs/index.js +1 -406
  102. package/dist-standalone/cjs/invitation.js +1 -421
  103. package/dist-standalone/cjs/invite.js +1 -328
  104. package/dist-standalone/cjs/key-agreement.js +1 -335
  105. package/dist-standalone/cjs/lazy-init.js +1 -300
  106. package/dist-standalone/cjs/logger.js +1 -291
  107. package/dist-standalone/cjs/loopback-transport.js +1 -0
  108. package/dist-standalone/cjs/mdns-discovery.js +1 -202
  109. package/dist-standalone/cjs/nonce-store.js +1 -80
  110. package/dist-standalone/cjs/pairing-manager.js +1 -223
  111. package/dist-standalone/cjs/plugin-system.js +1 -264
  112. package/dist-standalone/cjs/plugins/logging.js +1 -168
  113. package/dist-standalone/cjs/plugins/metrics.js +1 -181
  114. package/dist-standalone/cjs/plugins/validation.js +1 -302
  115. package/dist-standalone/cjs/policy.js +1 -320
  116. package/dist-standalone/cjs/progress-callbacks.js +1 -583
  117. package/dist-standalone/cjs/redis-nonce-store.js +1 -76
  118. package/dist-standalone/cjs/registry-middleware.js +1 -50
  119. package/dist-standalone/cjs/retry-strategies.js +1 -544
  120. package/dist-standalone/cjs/retry-transport.js +1 -102
  121. package/dist-standalone/cjs/runtime/browser.js +1 -533
  122. package/dist-standalone/cjs/runtime/edge.js +1 -526
  123. package/dist-standalone/cjs/runtime/react-native.js +1 -394
  124. package/dist-standalone/cjs/security-policy.js +1 -245
  125. package/dist-standalone/cjs/serialization.js +1 -1040
  126. package/dist-standalone/cjs/split-channel.js +1 -225
  127. package/dist-standalone/cjs/subscription-proof.js +1 -230
  128. package/dist-standalone/cjs/succession.js +1 -148
  129. package/dist-standalone/cjs/timeouts.js +1 -412
  130. package/dist-standalone/cjs/trace-context.js +1 -424
  131. package/dist-standalone/cjs/trace-spans.js +1 -495
  132. package/dist-standalone/cjs/transport.js +1 -63
  133. package/dist-standalone/cjs/trust-registry.js +1 -991
  134. package/dist-standalone/cjs/types/error-response.js +1 -56
  135. package/dist-standalone/cjs/vault-auth.js +1 -178
  136. package/dist-standalone/cjs/vault-store-loader.js +1 -194
  137. package/dist-standalone/cjs/verify.js +1 -25
  138. package/dist-standalone/cjs/version-info.js +1 -543
  139. package/dist-standalone/cjs/xfetch.js +1 -340
  140. package/dist-standalone/cli/init.js +1 -455
  141. package/dist-standalone/cli/setup.js +1 -514
  142. package/dist-standalone/cli/types.js +1 -27
  143. package/dist-standalone/cli/xbind.js +1 -148
  144. package/dist-standalone/config-validation.js +1 -513
  145. package/dist-standalone/connect.js +1 -274
  146. package/dist-standalone/connection-pool.js +1 -500
  147. package/dist-standalone/correlation-id.js +1 -326
  148. package/dist-standalone/crypto-utils.d.ts +2 -7
  149. package/dist-standalone/crypto-utils.js +1 -157
  150. package/dist-standalone/debug-mode.js +1 -510
  151. package/dist-standalone/did-document.js +1 -96
  152. package/dist-standalone/did-privateme.js +1 -121
  153. package/dist-standalone/did-web.js +1 -196
  154. package/dist-standalone/discovery.js +1 -458
  155. package/dist-standalone/dual-mode.js +1 -247
  156. package/dist-standalone/email-templates.js +1 -309
  157. package/dist-standalone/email-transport.d.ts +2 -2
  158. package/dist-standalone/email-transport.js +1 -232
  159. package/dist-standalone/envelope.js +1 -525
  160. package/dist-standalone/errors.d.ts +13 -3
  161. package/dist-standalone/errors.js +1 -896
  162. package/dist-standalone/event-emitter.js +1 -456
  163. package/dist-standalone/gateway-state.d.ts +1 -1
  164. package/dist-standalone/gateway-state.js +1 -51
  165. package/dist-standalone/gateway-transport.js +1 -116
  166. package/dist-standalone/graceful-degradation.js +1 -396
  167. package/dist-standalone/guardrails.js +1 -216
  168. package/dist-standalone/health-check.d.ts +5 -1
  169. package/dist-standalone/health-check.js +1 -332
  170. package/dist-standalone/http-compat.d.ts +1 -1
  171. package/dist-standalone/http-compat.js +1 -267
  172. package/dist-standalone/http-status-map.js +1 -561
  173. package/dist-standalone/identity.js +1 -619
  174. package/dist-standalone/index.d.ts +15 -4
  175. package/dist-standalone/index.js +1 -78
  176. package/dist-standalone/invitation.js +1 -415
  177. package/dist-standalone/invite.js +1 -324
  178. package/dist-standalone/key-agreement.js +1 -325
  179. package/dist-standalone/lazy-init.d.ts +11 -6
  180. package/dist-standalone/lazy-init.js +1 -295
  181. package/dist-standalone/logger.js +1 -285
  182. package/dist-standalone/loopback-transport.d.ts +87 -0
  183. package/dist-standalone/loopback-transport.js +1 -0
  184. package/dist-standalone/mdns-discovery.js +1 -195
  185. package/dist-standalone/nonce-store.js +1 -76
  186. package/dist-standalone/pairing-manager.js +1 -219
  187. package/dist-standalone/plugin-system.js +1 -257
  188. package/dist-standalone/plugins/logging.js +1 -163
  189. package/dist-standalone/plugins/metrics.d.ts +4 -4
  190. package/dist-standalone/plugins/metrics.js +1 -176
  191. package/dist-standalone/plugins/validation.js +1 -297
  192. package/dist-standalone/policy.js +1 -315
  193. package/dist-standalone/progress-callbacks.js +1 -576
  194. package/dist-standalone/redis-nonce-store.js +1 -72
  195. package/dist-standalone/registry-middleware.js +1 -47
  196. package/dist-standalone/retry-strategies.js +1 -534
  197. package/dist-standalone/retry-transport.js +1 -98
  198. package/dist-standalone/runtime/browser.js +1 -516
  199. package/dist-standalone/runtime/edge.js +1 -511
  200. package/dist-standalone/runtime/react-native.d.ts +1 -1
  201. package/dist-standalone/runtime/react-native.js +1 -383
  202. package/dist-standalone/security-policy.js +1 -239
  203. package/dist-standalone/serialization.js +1 -1031
  204. package/dist-standalone/split-channel.js +1 -219
  205. package/dist-standalone/subscription-proof.js +1 -224
  206. package/dist-standalone/succession.js +1 -142
  207. package/dist-standalone/timeouts.js +1 -398
  208. package/dist-standalone/trace-context.js +1 -414
  209. package/dist-standalone/trace-spans.js +1 -488
  210. package/dist-standalone/transport.js +1 -59
  211. package/dist-standalone/trust-registry.d.ts +3 -3
  212. package/dist-standalone/trust-registry.js +1 -950
  213. package/dist-standalone/types/error-response.js +1 -52
  214. package/dist-standalone/vault-auth.js +1 -174
  215. package/dist-standalone/vault-store-loader.d.ts +9 -0
  216. package/dist-standalone/vault-store-loader.js +1 -187
  217. package/dist-standalone/verify.js +1 -16
  218. package/dist-standalone/version-info.js +1 -530
  219. package/dist-standalone/xfetch.js +1 -335
  220. package/package.json +1 -1
  221. package/share1.dat +0 -0
@@ -1,645 +1 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.ML_DSA65_SK_BYTES = exports.ML_DSA65_PK_BYTES = exports.ML_DSA65_SIG_BYTES = void 0;
7
- exports.generateIdentity = generateIdentity;
8
- exports.sign = sign;
9
- exports.verify = verify;
10
- exports.importPublicKey = importPublicKey;
11
- exports.publicKeyToDid = publicKeyToDid;
12
- exports.didToPublicKeyBytes = didToPublicKeyBytes;
13
- exports.exportPKCS8 = exportPKCS8;
14
- exports.exportX25519PKCS8 = exportX25519PKCS8;
15
- exports.importFromPKCS8 = importFromPKCS8;
16
- exports.importIdentity = importIdentity;
17
- exports.exportMlKemSecretKey = exportMlKemSecretKey;
18
- exports.exportMlKemPublicKey = exportMlKemPublicKey;
19
- exports.signMlDsa65 = signMlDsa65;
20
- exports.verifyMlDsa65 = verifyMlDsa65;
21
- exports.exportMlDsaSecretKey = exportMlDsaSecretKey;
22
- exports.exportMlDsaPublicKey = exportMlDsaPublicKey;
23
- exports.identityFromSeed = identityFromSeed;
24
- exports.extractRawEd25519 = extractRawEd25519;
25
- exports.extractRawX25519 = extractRawX25519;
26
- exports.rotateKeys = rotateKeys;
27
- const shared_1 = require("../_deps/shared/index.js");
28
- const crypto_utils_js_1 = require("./crypto-utils.js");
29
- const mlkem_1 = require("mlkem");
30
- const mldsa_wasm_1 = __importDefault(require("../_deps/mldsa-wasm/dist/mldsa.js"));
31
- /** Ed25519 multicodec varint prefix. */
32
- const ED25519_MULTICODEC = new Uint8Array([0xed, 0x01]);
33
- const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
34
- /** Copy Uint8Array to fresh ArrayBuffer (avoids SharedArrayBuffer type issues). */
35
- function toArrayBuffer(data) {
36
- const buf = new ArrayBuffer(data.byteLength);
37
- new Uint8Array(buf).set(data);
38
- return buf;
39
- }
40
- /* ── Key Generation ── */
41
- /**
42
- * Generate a new Ed25519 agent identity.
43
- * Creates keypair via Web Crypto API, derives did:key DID.
44
- *
45
- * @param opts - Optional configuration
46
- * @param opts.postQuantumSig - Enable ML-DSA-65 post-quantum signatures (default: false)
47
- * @returns Result containing the agent identity or error
48
- *
49
- * @example
50
- * ```typescript
51
- * import { generateIdentity } from '@private.me/xbind';
52
- *
53
- * // Generate identity with classical cryptography only
54
- * const identity = await generateIdentity();
55
- * if (!identity.ok) {
56
- * throw new Error(`Failed to generate identity: ${identity.error}`);
57
- * }
58
- * console.log('DID:', identity.value.did);
59
- *
60
- * // Generate identity with post-quantum signatures
61
- * const pqIdentity = await generateIdentity({ postQuantumSig: true });
62
- * if (pqIdentity.ok) {
63
- * console.log('Post-quantum DID:', pqIdentity.value.did);
64
- * console.log('Has ML-DSA key:', !!pqIdentity.value.mlDsaPublicKey);
65
- * }
66
- * ```
67
- */
68
- async function generateIdentity(opts) {
69
- try {
70
- // SAFETY: Ed25519 generateKey always returns CryptoKeyPair
71
- const keyPair = await crypto.subtle.generateKey('Ed25519', true, ['sign', 'verify']);
72
- const rawPub = new Uint8Array(await crypto.subtle.exportKey('raw', keyPair.publicKey));
73
- const did = publicKeyToDid(rawPub);
74
- // SAFETY: X25519 generateKey always returns CryptoKeyPair
75
- const x25519Pair = await crypto.subtle.generateKey({ name: 'X25519' }, true, ['deriveBits']);
76
- const rawX25519Pub = new Uint8Array(await crypto.subtle.exportKey('raw', x25519Pair.publicKey));
77
- // Generate ML-KEM-768 keypair for hybrid post-quantum KEM (always-on)
78
- let mlKemPublicKey;
79
- let mlKemSecretKey;
80
- try {
81
- const mlkem = await (0, mlkem_1.createMlKem768)();
82
- const [publicKey, secretKey] = mlkem.generateKeyPair();
83
- mlKemPublicKey = publicKey;
84
- mlKemSecretKey = secretKey;
85
- }
86
- catch (err) {
87
- console.warn('[xBind] ML-KEM-768 keygen failed, using classical crypto only:', err);
88
- }
89
- // Generate ML-DSA-65 keypair only when opt-in flag is set
90
- let mlDsaPublicKey;
91
- let mlDsaSecretKey;
92
- if (opts?.postQuantumSig) {
93
- try {
94
- const keypair = await mldsa_wasm_1.default.generateKey('ML-DSA-65', true, ['sign', 'verify']);
95
- const publicKeyRaw = await mldsa_wasm_1.default.exportKey('raw-public', keypair.publicKey);
96
- const secretKeySeed = await mldsa_wasm_1.default.exportKey('raw-seed', keypair.privateKey);
97
- mlDsaPublicKey = new Uint8Array(publicKeyRaw);
98
- // For storage, we need the full secret key, not just the seed
99
- // We'll store the seed and regenerate when needed
100
- mlDsaSecretKey = new Uint8Array(secretKeySeed);
101
- }
102
- catch (err) {
103
- console.warn('[xBind] ML-DSA-65 keygen failed, using classical crypto only:', err);
104
- }
105
- }
106
- return (0, shared_1.ok)({
107
- did,
108
- publicKey: keyPair.publicKey,
109
- privateKey: keyPair.privateKey,
110
- rawPublicKey: rawPub,
111
- x25519PrivateKey: x25519Pair.privateKey,
112
- x25519PublicKey: x25519Pair.publicKey,
113
- rawX25519PublicKey: rawX25519Pub,
114
- ...(mlKemPublicKey ? { mlKemPublicKey } : {}),
115
- ...(mlKemSecretKey ? { mlKemSecretKey } : {}),
116
- ...(mlDsaPublicKey ? { mlDsaPublicKey } : {}),
117
- ...(mlDsaSecretKey ? { mlDsaSecretKey } : {}),
118
- });
119
- }
120
- catch {
121
- return (0, shared_1.err)('KEYGEN_FAILED');
122
- }
123
- }
124
- /* ── Sign / Verify ── */
125
- /**
126
- * Sign data with an Ed25519 private key.
127
- * @returns 64-byte Ed25519 signature.
128
- */
129
- async function sign(privateKey, data) {
130
- try {
131
- const sig = new Uint8Array(await crypto.subtle.sign('Ed25519', privateKey, toArrayBuffer(data)));
132
- return (0, shared_1.ok)(sig);
133
- }
134
- catch {
135
- return (0, shared_1.err)('SIGN_FAILED');
136
- }
137
- }
138
- /**
139
- * Verify an Ed25519 signature.
140
- * @returns true if valid, false if invalid (not an error).
141
- */
142
- async function verify(publicKey, signature, data) {
143
- try {
144
- const valid = await crypto.subtle.verify('Ed25519', publicKey, toArrayBuffer(signature), toArrayBuffer(data));
145
- return (0, shared_1.ok)(valid);
146
- }
147
- catch {
148
- return (0, shared_1.err)('VERIFY_FAILED');
149
- }
150
- }
151
- /* ── Key Import ── */
152
- /**
153
- * Import a raw 32-byte Ed25519 public key into a CryptoKey.
154
- */
155
- async function importPublicKey(rawPublicKey) {
156
- if (rawPublicKey.length !== 32)
157
- return (0, shared_1.err)('INVALID_KEY_LENGTH');
158
- try {
159
- const key = await crypto.subtle.importKey('raw', toArrayBuffer(rawPublicKey), 'Ed25519', true, ['verify']);
160
- return (0, shared_1.ok)(key);
161
- }
162
- catch {
163
- return (0, shared_1.err)('KEYGEN_FAILED');
164
- }
165
- }
166
- /* ── DID Conversion ── */
167
- /**
168
- * Convert 32-byte Ed25519 public key to did:key DID.
169
- * Format: did:key:z + base58btc(0xed01 || publicKey).
170
- */
171
- function publicKeyToDid(rawPublicKey) {
172
- const prefixed = new Uint8Array(2 + rawPublicKey.length);
173
- prefixed.set(ED25519_MULTICODEC);
174
- prefixed.set(rawPublicKey, 2);
175
- return `did:key:z${base58btcEncode(prefixed)}`;
176
- }
177
- /**
178
- * Extract raw 32-byte public key bytes from a did:key DID.
179
- */
180
- function didToPublicKeyBytes(did) {
181
- if (!did.startsWith('did:key:z'))
182
- return (0, shared_1.err)('INVALID_DID');
183
- try {
184
- const encoded = did.slice('did:key:z'.length);
185
- const bytes = base58btcDecode(encoded);
186
- if (bytes[0] !== 0xed || bytes[1] !== 0x01)
187
- return (0, shared_1.err)('INVALID_DID');
188
- if (bytes.length !== 34)
189
- return (0, shared_1.err)('INVALID_DID');
190
- return (0, shared_1.ok)(bytes.slice(2));
191
- }
192
- catch {
193
- return (0, shared_1.err)('INVALID_DID');
194
- }
195
- }
196
- /* ── PKCS8 Export/Import ── */
197
- /**
198
- * Export an Ed25519 private key as PKCS8 DER bytes.
199
- *
200
- * Use this to persist an agent identity across restarts.
201
- * Node 20 does not support raw export for Ed25519 private keys —
202
- * PKCS8 is the portable format.
203
- *
204
- * @param privateKey - Ed25519 CryptoKey (must be extractable).
205
- * @returns PKCS8 DER bytes or error.
206
- */
207
- async function exportPKCS8(privateKey) {
208
- try {
209
- const buf = await crypto.subtle.exportKey('pkcs8', privateKey);
210
- return (0, shared_1.ok)(new Uint8Array(buf));
211
- }
212
- catch {
213
- return (0, shared_1.err)('EXPORT_FAILED');
214
- }
215
- }
216
- /**
217
- * Export an X25519 private key as PKCS8 DER bytes.
218
- *
219
- * @param privateKey - X25519 CryptoKey (must be extractable).
220
- * @returns PKCS8 DER bytes or error.
221
- */
222
- async function exportX25519PKCS8(privateKey) {
223
- try {
224
- const buf = await crypto.subtle.exportKey('pkcs8', privateKey);
225
- return (0, shared_1.ok)(new Uint8Array(buf));
226
- }
227
- catch {
228
- return (0, shared_1.err)('EXPORT_FAILED');
229
- }
230
- }
231
- /**
232
- * Import an Ed25519 identity from PKCS8 DER bytes.
233
- *
234
- * Generates a new X25519 keypair for forward secrecy.
235
- * Use this when you only persisted the Ed25519 key.
236
- *
237
- * @param pkcs8 - PKCS8-encoded Ed25519 private key bytes.
238
- * @returns Full AgentIdentity or error.
239
- */
240
- async function importFromPKCS8(pkcs8) {
241
- try {
242
- const privateKey = await crypto.subtle.importKey('pkcs8', toArrayBuffer(pkcs8), 'Ed25519', true, ['sign']);
243
- // Extract public key from JWK (PKCS8 import returns only private key)
244
- const jwk = await crypto.subtle.exportKey('jwk', privateKey);
245
- if (!jwk.x)
246
- return (0, shared_1.err)('IMPORT_FAILED');
247
- // JWK x field is base64url-encoded raw public key
248
- const rawPub = (0, crypto_utils_js_1.fromBase64Url)(jwk.x);
249
- const publicKey = await crypto.subtle.importKey('raw', toArrayBuffer(rawPub), 'Ed25519', true, ['verify']);
250
- const did = publicKeyToDid(rawPub);
251
- // Generate fresh X25519 keypair for forward secrecy
252
- // SAFETY: X25519 generateKey always returns CryptoKeyPair
253
- const x25519Pair = await crypto.subtle.generateKey({ name: 'X25519' }, true, ['deriveBits']);
254
- const rawX25519Pub = new Uint8Array(await crypto.subtle.exportKey('raw', x25519Pair.publicKey));
255
- return (0, shared_1.ok)({
256
- did,
257
- publicKey,
258
- privateKey,
259
- rawPublicKey: rawPub,
260
- x25519PrivateKey: x25519Pair.privateKey,
261
- x25519PublicKey: x25519Pair.publicKey,
262
- rawX25519PublicKey: rawX25519Pub,
263
- });
264
- }
265
- catch {
266
- return (0, shared_1.err)('IMPORT_FAILED');
267
- }
268
- }
269
- /**
270
- * Import a full identity from both PKCS8 blobs (Ed25519 + X25519).
271
- *
272
- * Use this when you persisted both keys for full identity restoration
273
- * including the original X25519 key (preserves registered key agreement).
274
- *
275
- * @param ed25519Pkcs8 - PKCS8-encoded Ed25519 private key bytes.
276
- * @param x25519Pkcs8 - PKCS8-encoded X25519 private key bytes.
277
- * @returns Full AgentIdentity or error.
278
- */
279
- async function importIdentity(ed25519Pkcs8, x25519Pkcs8, mlKemSecretKey, mlKemPublicKey, mlDsaSecretKey, mlDsaPublicKey) {
280
- try {
281
- const privateKey = await crypto.subtle.importKey('pkcs8', toArrayBuffer(ed25519Pkcs8), 'Ed25519', true, ['sign']);
282
- const jwk = await crypto.subtle.exportKey('jwk', privateKey);
283
- if (!jwk.x)
284
- return (0, shared_1.err)('IMPORT_FAILED');
285
- const rawPub = (0, crypto_utils_js_1.fromBase64Url)(jwk.x);
286
- const publicKey = await crypto.subtle.importKey('raw', toArrayBuffer(rawPub), 'Ed25519', true, ['verify']);
287
- const did = publicKeyToDid(rawPub);
288
- const x25519PrivateKey = await crypto.subtle.importKey('pkcs8', toArrayBuffer(x25519Pkcs8), { name: 'X25519' }, true, ['deriveBits']);
289
- const x25519Jwk = await crypto.subtle.exportKey('jwk', x25519PrivateKey);
290
- if (!x25519Jwk.x)
291
- return (0, shared_1.err)('IMPORT_FAILED');
292
- const rawX25519Pub = (0, crypto_utils_js_1.fromBase64Url)(x25519Jwk.x);
293
- const x25519PublicKey = await crypto.subtle.importKey('raw', toArrayBuffer(rawX25519Pub), { name: 'X25519' }, true, []);
294
- return (0, shared_1.ok)({
295
- did,
296
- publicKey,
297
- privateKey,
298
- rawPublicKey: rawPub,
299
- x25519PrivateKey,
300
- x25519PublicKey,
301
- rawX25519PublicKey: rawX25519Pub,
302
- ...(mlKemSecretKey ? { mlKemSecretKey } : {}),
303
- ...(mlKemPublicKey ? { mlKemPublicKey } : {}),
304
- ...(mlDsaSecretKey ? { mlDsaSecretKey } : {}),
305
- ...(mlDsaPublicKey ? { mlDsaPublicKey } : {}),
306
- });
307
- }
308
- catch {
309
- return (0, shared_1.err)('IMPORT_FAILED');
310
- }
311
- }
312
- /* ── ML-KEM Key Export ── */
313
- /**
314
- * Export ML-KEM-768 secret key bytes from an identity.
315
- *
316
- * @param identity - Agent identity with ML-KEM keys.
317
- * @returns Raw 2400-byte ML-KEM secret key or undefined if not available.
318
- */
319
- function exportMlKemSecretKey(identity) {
320
- return identity.mlKemSecretKey;
321
- }
322
- /**
323
- * Export ML-KEM-768 public key bytes from an identity.
324
- *
325
- * @param identity - Agent identity with ML-KEM keys.
326
- * @returns Raw 1184-byte ML-KEM public key or undefined if not available.
327
- */
328
- function exportMlKemPublicKey(identity) {
329
- return identity.mlKemPublicKey;
330
- }
331
- /* ── ML-DSA-65 Sign / Verify ── */
332
- /** ML-DSA-65 signature length in bytes. */
333
- exports.ML_DSA65_SIG_BYTES = 3309;
334
- /** ML-DSA-65 public key length in bytes. */
335
- exports.ML_DSA65_PK_BYTES = 1952;
336
- /** ML-DSA-65 secret key seed length in bytes (using seed format for storage). */
337
- exports.ML_DSA65_SK_BYTES = 32;
338
- /**
339
- * Sign data with an ML-DSA-65 secret key (FIPS 204).
340
- * @param secretKey - 32-byte ML-DSA-65 secret key seed.
341
- * @param data - Data to sign.
342
- * @returns 3309-byte ML-DSA-65 signature.
343
- */
344
- async function signMlDsa65(secretKey, data) {
345
- try {
346
- // Import secret key seed as CryptoKey
347
- const privateKey = await mldsa_wasm_1.default.importKey('raw-seed', toArrayBuffer(secretKey), 'ML-DSA-65', false, ['sign']);
348
- // Sign using mldsa-wasm API
349
- const signature = await mldsa_wasm_1.default.sign('ML-DSA-65', privateKey, toArrayBuffer(data));
350
- return (0, shared_1.ok)(new Uint8Array(signature));
351
- }
352
- catch {
353
- return (0, shared_1.err)('SIGN_FAILED');
354
- }
355
- }
356
- /**
357
- * Verify an ML-DSA-65 signature (FIPS 204).
358
- * @param publicKey - 1952-byte ML-DSA-65 public key.
359
- * @param signature - 3309-byte ML-DSA-65 signature.
360
- * @param data - Data that was signed.
361
- * @returns true if valid, false if invalid (not an error).
362
- */
363
- async function verifyMlDsa65(publicKey, signature, data) {
364
- try {
365
- // Import public key as CryptoKey
366
- const pubKey = await mldsa_wasm_1.default.importKey('raw-public', toArrayBuffer(publicKey), 'ML-DSA-65', false, ['verify']);
367
- // Verify using mldsa-wasm API
368
- const valid = await mldsa_wasm_1.default.verify('ML-DSA-65', pubKey, toArrayBuffer(signature), toArrayBuffer(data));
369
- return (0, shared_1.ok)(valid);
370
- }
371
- catch {
372
- return (0, shared_1.err)('VERIFY_FAILED');
373
- }
374
- }
375
- /* ── ML-DSA Key Export ── */
376
- /**
377
- * Export ML-DSA-65 secret key bytes from an identity.
378
- *
379
- * @param identity - Agent identity with ML-DSA keys.
380
- * @returns Raw 4032-byte ML-DSA-65 secret key or undefined if not available.
381
- */
382
- function exportMlDsaSecretKey(identity) {
383
- return identity.mlDsaSecretKey;
384
- }
385
- /**
386
- * Export ML-DSA-65 public key bytes from an identity.
387
- *
388
- * @param identity - Agent identity with ML-DSA keys.
389
- * @returns Raw 1952-byte ML-DSA-65 public key or undefined if not available.
390
- */
391
- function exportMlDsaPublicKey(identity) {
392
- return identity.mlDsaPublicKey;
393
- }
394
- /* ── PKCS8 ASN.1 Prefixes ── */
395
- /**
396
- * PKCS8 ASN.1 DER header for Ed25519 private keys (16 bytes).
397
- * Structure: SEQUENCE { INTEGER(0), SEQUENCE { OID(1.3.101.112) }, OCTET STRING header }
398
- * The 32-byte raw seed follows immediately after this prefix.
399
- */
400
- const ED25519_PKCS8_PREFIX = new Uint8Array([
401
- 0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06,
402
- 0x03, 0x2b, 0x65, 0x70, 0x04, 0x22, 0x04, 0x20,
403
- ]);
404
- /**
405
- * PKCS8 ASN.1 DER header for X25519 private keys (16 bytes).
406
- * Structure: SEQUENCE { INTEGER(0), SEQUENCE { OID(1.3.101.110) }, OCTET STRING header }
407
- * The 32-byte raw seed follows immediately after this prefix.
408
- */
409
- const X25519_PKCS8_PREFIX = new Uint8Array([
410
- 0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06,
411
- 0x03, 0x2b, 0x65, 0x6e, 0x04, 0x22, 0x04, 0x20,
412
- ]);
413
- /* ── Deterministic Identity from Seed ── */
414
- /**
415
- * Derive a deterministic AgentIdentity from a 32-byte seed.
416
- *
417
- * Uses HKDF-SHA256 to derive separate Ed25519 and X25519 private keys
418
- * from the seed. The same seed always produces the same identity (same DID).
419
- *
420
- * @param seed - Exactly 32 bytes of high-entropy key material.
421
- * @returns Full AgentIdentity or error.
422
- */
423
- async function identityFromSeed(seed, opts) {
424
- if (seed.length !== 32)
425
- return (0, shared_1.err)('INVALID_KEY_LENGTH');
426
- try {
427
- // Import seed as HKDF base key
428
- const baseKey = await crypto.subtle.importKey('raw', toArrayBuffer(seed), 'HKDF', false, ['deriveBits']);
429
- // Derive 32 bytes for Ed25519
430
- const edBits = new Uint8Array(await crypto.subtle.deriveBits({ name: 'HKDF', hash: 'SHA-256', salt: new Uint8Array(32), info: new TextEncoder().encode('ed25519') }, baseKey, 256));
431
- // Derive 32 bytes for X25519
432
- const x25519Bits = new Uint8Array(await crypto.subtle.deriveBits({ name: 'HKDF', hash: 'SHA-256', salt: new Uint8Array(32), info: new TextEncoder().encode('x25519') }, baseKey, 256));
433
- // Derive 64 bytes for ML-KEM-768
434
- const mlKemBits = new Uint8Array(await crypto.subtle.deriveBits({ name: 'HKDF', hash: 'SHA-256', salt: new Uint8Array(32), info: new TextEncoder().encode('ml-kem-768') }, baseKey, 512));
435
- // Wrap as PKCS8 and import
436
- const edPkcs8 = new Uint8Array(ED25519_PKCS8_PREFIX.length + edBits.length);
437
- edPkcs8.set(ED25519_PKCS8_PREFIX);
438
- edPkcs8.set(edBits, ED25519_PKCS8_PREFIX.length);
439
- const x25519Pkcs8 = new Uint8Array(X25519_PKCS8_PREFIX.length + x25519Bits.length);
440
- x25519Pkcs8.set(X25519_PKCS8_PREFIX);
441
- x25519Pkcs8.set(x25519Bits, X25519_PKCS8_PREFIX.length);
442
- // Generate deterministic ML-KEM-768 keypair from derived seed (always-on)
443
- let mlKemPublicKey;
444
- let mlKemSecretKey;
445
- try {
446
- // Use deterministic key generation from 64-byte seed (FIPS 203 compliant)
447
- const mlkem = await (0, mlkem_1.createMlKem768)();
448
- const [publicKey, secretKey] = mlkem.deriveKeyPair(mlKemBits);
449
- mlKemPublicKey = publicKey;
450
- mlKemSecretKey = secretKey;
451
- }
452
- catch (err) {
453
- console.warn('[xBind] ML-KEM-768 keygen failed, using classical crypto only:', err);
454
- }
455
- // Generate ML-DSA-65 keypair only when opt-in flag is set
456
- let mlDsaSecretKey;
457
- let mlDsaPublicKey;
458
- if (opts?.postQuantumSig) {
459
- try {
460
- const mlDsaBits = new Uint8Array(await crypto.subtle.deriveBits({ name: 'HKDF', hash: 'SHA-256', salt: new Uint8Array(32), info: new TextEncoder().encode('ml-dsa-65') }, baseKey, 256));
461
- // Import seed and generate deterministic keypair
462
- const privateKey = await mldsa_wasm_1.default.importKey('raw-seed', mlDsaBits, 'ML-DSA-65', true, ['sign']);
463
- const publicKey = await mldsa_wasm_1.default.getPublicKey(privateKey, ['verify']);
464
- const publicKeyRaw = await mldsa_wasm_1.default.exportKey('raw-public', publicKey);
465
- mlDsaPublicKey = new Uint8Array(publicKeyRaw);
466
- mlDsaSecretKey = mlDsaBits; // Store the seed for later use
467
- }
468
- catch (err) {
469
- console.warn('[xBind] ML-DSA-65 keygen failed, using classical crypto only:', err);
470
- }
471
- }
472
- return importIdentity(edPkcs8, x25519Pkcs8, mlKemSecretKey, mlKemPublicKey, mlDsaSecretKey, mlDsaPublicKey);
473
- }
474
- catch {
475
- return (0, shared_1.err)('KEYGEN_FAILED');
476
- }
477
- }
478
- /**
479
- * Extract the raw 32-byte Ed25519 private key from a PKCS8 DER blob.
480
- *
481
- * Strips the 16-byte ASN.1 header. Validates prefix matches Ed25519 OID.
482
- *
483
- * @param pkcs8 - 48-byte PKCS8 DER for Ed25519.
484
- * @returns 32-byte raw private key or error.
485
- */
486
- function extractRawEd25519(pkcs8) {
487
- if (pkcs8.length !== ED25519_PKCS8_PREFIX.length + 32) {
488
- return (0, shared_1.err)('INVALID_KEY_LENGTH');
489
- }
490
- for (let i = 0; i < ED25519_PKCS8_PREFIX.length; i++) {
491
- if (pkcs8[i] !== ED25519_PKCS8_PREFIX[i])
492
- return (0, shared_1.err)('IMPORT_FAILED');
493
- }
494
- return (0, shared_1.ok)(pkcs8.slice(ED25519_PKCS8_PREFIX.length));
495
- }
496
- /**
497
- * Extract the raw 32-byte X25519 private key from a PKCS8 DER blob.
498
- *
499
- * Strips the 16-byte ASN.1 header. Validates prefix matches X25519 OID.
500
- *
501
- * @param pkcs8 - 48-byte PKCS8 DER for X25519.
502
- * @returns 32-byte raw private key or error.
503
- */
504
- function extractRawX25519(pkcs8) {
505
- if (pkcs8.length !== X25519_PKCS8_PREFIX.length + 32) {
506
- return (0, shared_1.err)('INVALID_KEY_LENGTH');
507
- }
508
- for (let i = 0; i < X25519_PKCS8_PREFIX.length; i++) {
509
- if (pkcs8[i] !== X25519_PKCS8_PREFIX[i])
510
- return (0, shared_1.err)('IMPORT_FAILED');
511
- }
512
- return (0, shared_1.ok)(pkcs8.slice(X25519_PKCS8_PREFIX.length));
513
- }
514
- /* ── Key Rotation (ROT-1) ── */
515
- /**
516
- * Rotate ML-KEM + X25519 keys while preserving old keys for decryption.
517
- *
518
- * Generates new X25519 and ML-KEM-768 keypairs. Saves the old keys
519
- * in rotatedKeys array (with timestamp) for backward-compatible decryption
520
- * of messages encrypted with the old keys. Ed25519 keys (for signing) are
521
- * NOT rotated — they remain constant for persistent identity.
522
- *
523
- * After rotation:
524
- * - New messages use the new X25519 + ML-KEM keys
525
- * - Old messages decrypt using preserved rotatedKeys
526
- * - DID remains unchanged (anchored to Ed25519 public key)
527
- * - Registry must be updated with new X25519 + ML-KEM public keys
528
- *
529
- * @param identity - Current identity with keys to rotate
530
- * @returns Updated identity with new keys + old keys in rotatedKeys array, or error
531
- *
532
- * @example
533
- * ```ts
534
- * const rotated = await identity.rotateKeys();
535
- * if (rotated.ok) {
536
- * // New keys are active; old keys preserved for decryption
537
- * console.log('Rotated at:', rotated.value.rotatedKeys?.[0]?.rotatedAt);
538
- * // Update registry with new X25519 + ML-KEM public keys
539
- * await registry.updateKeys(rotated.value.did, rotated.value.rawX25519PublicKey, rotated.value.mlKemPublicKey);
540
- * }
541
- * ```
542
- */
543
- async function rotateKeys(identity) {
544
- try {
545
- // Preserve old keys in rotatedKeys array
546
- const oldRotatedKeys = identity.rotatedKeys ?? [];
547
- const currentRotation = {
548
- rotatedAt: Date.now(),
549
- x25519PrivateKey: identity.x25519PrivateKey,
550
- mlKemSecretKey: identity.mlKemSecretKey,
551
- };
552
- // Generate new X25519 keypair for forward secrecy
553
- // SAFETY: X25519 generateKey always returns CryptoKeyPair
554
- const newX25519Pair = await crypto.subtle.generateKey({ name: 'X25519' }, true, ['deriveBits']);
555
- const newRawX25519Pub = new Uint8Array(await crypto.subtle.exportKey('raw', newX25519Pair.publicKey));
556
- // Generate new ML-KEM-768 keypair (only if original identity had ML-KEM)
557
- let newMlKemPublicKey;
558
- let newMlKemSecretKey;
559
- if (identity.mlKemPublicKey || identity.mlKemSecretKey) {
560
- try {
561
- const mlkem = await (0, mlkem_1.createMlKem768)();
562
- const [publicKey, secretKey] = mlkem.generateKeyPair();
563
- newMlKemPublicKey = publicKey;
564
- newMlKemSecretKey = secretKey;
565
- }
566
- catch (err) {
567
- console.warn('[xBind] ML-KEM-768 rotation failed, using X25519 only:', err);
568
- }
569
- }
570
- // Preserve rotation history (keep up to 10 old key sets for decryption)
571
- const maxRotationHistory = 10;
572
- const rotatedKeys = [
573
- currentRotation,
574
- ...oldRotatedKeys,
575
- ].slice(0, maxRotationHistory);
576
- return (0, shared_1.ok)({
577
- did: identity.did,
578
- publicKey: identity.publicKey,
579
- privateKey: identity.privateKey,
580
- rawPublicKey: identity.rawPublicKey,
581
- x25519PrivateKey: newX25519Pair.privateKey,
582
- x25519PublicKey: newX25519Pair.publicKey,
583
- rawX25519PublicKey: newRawX25519Pub,
584
- mlKemPublicKey: newMlKemPublicKey,
585
- mlKemSecretKey: newMlKemSecretKey,
586
- mlDsaPublicKey: identity.mlDsaPublicKey,
587
- mlDsaSecretKey: identity.mlDsaSecretKey,
588
- rotatedKeys,
589
- });
590
- }
591
- catch {
592
- return (0, shared_1.err)('ROTATION_FAILED');
593
- }
594
- }
595
- /* ── Base58btc (internal) ── */
596
- /** Encode bytes to base58btc string. */
597
- function base58btcEncode(bytes) {
598
- let zeros = 0;
599
- for (const b of bytes) {
600
- if (b !== 0)
601
- break;
602
- zeros++;
603
- }
604
- let num = 0n;
605
- for (const b of bytes) {
606
- num = num * 256n + BigInt(b);
607
- }
608
- const chars = [];
609
- while (num > 0n) {
610
- const ch = BASE58_ALPHABET[Number(num % 58n)];
611
- if (ch !== undefined)
612
- chars.unshift(ch);
613
- num = num / 58n;
614
- }
615
- for (let i = 0; i < zeros; i++) {
616
- chars.unshift('1');
617
- }
618
- return chars.join('');
619
- }
620
- /** Decode base58btc string to bytes. */
621
- function base58btcDecode(str) {
622
- let zeros = 0;
623
- for (const c of str) {
624
- if (c !== '1')
625
- break;
626
- zeros++;
627
- }
628
- let num = 0n;
629
- for (const c of str) {
630
- const idx = BASE58_ALPHABET.indexOf(c);
631
- if (idx === -1)
632
- throw new Error('Invalid base58 character');
633
- num = num * 58n + BigInt(idx);
634
- }
635
- if (num === 0n)
636
- return new Uint8Array(zeros);
637
- const hex = num.toString(16);
638
- const paddedHex = hex.length % 2 ? '0' + hex : hex;
639
- const byteLen = paddedHex.length / 2;
640
- const result = new Uint8Array(zeros + byteLen);
641
- for (let i = 0; i < byteLen; i++) {
642
- result[zeros + i] = parseInt(paddedHex.slice(i * 2, i * 2 + 2), 16);
643
- }
644
- return result;
645
- }
1
+ "use strict";var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0}),exports.ML_DSA65_SK_BYTES=exports.ML_DSA65_PK_BYTES=exports.ML_DSA65_SIG_BYTES=void 0,exports.generateIdentity=generateIdentity,exports.sign=sign,exports.verify=verify,exports.importPublicKey=importPublicKey,exports.publicKeyToDid=publicKeyToDid,exports.didToPublicKeyBytes=didToPublicKeyBytes,exports.exportPKCS8=exportPKCS8,exports.exportX25519PKCS8=exportX25519PKCS8,exports.importFromPKCS8=importFromPKCS8,exports.importIdentity=importIdentity,exports.exportMlKemSecretKey=exportMlKemSecretKey,exports.exportMlKemPublicKey=exportMlKemPublicKey,exports.signMlDsa65=signMlDsa65,exports.verifyMlDsa65=verifyMlDsa65,exports.exportMlDsaSecretKey=exportMlDsaSecretKey,exports.exportMlDsaPublicKey=exportMlDsaPublicKey,exports.identityFromSeed=identityFromSeed,exports.extractRawEd25519=extractRawEd25519,exports.extractRawX25519=extractRawX25519,exports.rotateKeys=rotateKeys;const shared_1=require("../_deps/shared/index.js"),crypto_utils_js_1=require("./crypto-utils.js"),mlkem_1=require("mlkem"),mldsa_wasm_1=__importDefault(require("../_deps/mldsa-wasm/dist/mldsa.js")),ED25519_MULTICODEC=new Uint8Array([237,1]),BASE58_ALPHABET="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";function toArrayBuffer(e){const r=new ArrayBuffer(e.byteLength);return new Uint8Array(r).set(e),r}async function generateIdentity(e){try{const r=await crypto.subtle.generateKey("Ed25519",!0,["sign","verify"]),t=new Uint8Array(await crypto.subtle.exportKey("raw",r.publicKey)),a=publicKeyToDid(t),i=await crypto.subtle.generateKey({name:"X25519"},!0,["deriveBits"]),n=new Uint8Array(await crypto.subtle.exportKey("raw",i.publicKey));let s,o,y,c;try{const e=await(0,mlkem_1.createMlKem768)(),[r,t]=e.generateKeyPair();s=r,o=t}catch(e){console.warn("[xBind] ML-KEM-768 keygen failed, using classical crypto only:",e)}if(e?.postQuantumSig)try{const e=await mldsa_wasm_1.default.generateKey("ML-DSA-65",!0,["sign","verify"]),r=await mldsa_wasm_1.default.exportKey("raw-public",e.publicKey),t=await mldsa_wasm_1.default.exportKey("raw-seed",e.privateKey);y=new Uint8Array(r),c=new Uint8Array(t)}catch(e){console.warn("[xBind] ML-DSA-65 keygen failed, using classical crypto only:",e)}return(0,shared_1.ok)({did:a,publicKey:r.publicKey,privateKey:r.privateKey,rawPublicKey:t,x25519PrivateKey:i.privateKey,x25519PublicKey:i.publicKey,rawX25519PublicKey:n,...s?{mlKemPublicKey:s}:{},...o?{mlKemSecretKey:o}:{},...y?{mlDsaPublicKey:y}:{},...c?{mlDsaSecretKey:c}:{}})}catch{return(0,shared_1.err)("KEYGEN_FAILED")}}async function sign(e,r){try{const t=new Uint8Array(await crypto.subtle.sign("Ed25519",e,toArrayBuffer(r)));return(0,shared_1.ok)(t)}catch{return(0,shared_1.err)("SIGN_FAILED")}}async function verify(e,r,t){try{const a=await crypto.subtle.verify("Ed25519",e,toArrayBuffer(r),toArrayBuffer(t));return(0,shared_1.ok)(a)}catch{return(0,shared_1.err)("VERIFY_FAILED")}}async function importPublicKey(e){if(32!==e.length)return(0,shared_1.err)("INVALID_KEY_LENGTH");try{const r=await crypto.subtle.importKey("raw",toArrayBuffer(e),"Ed25519",!0,["verify"]);return(0,shared_1.ok)(r)}catch{return(0,shared_1.err)("KEYGEN_FAILED")}}function publicKeyToDid(e){const r=new Uint8Array(2+e.length);return r.set(ED25519_MULTICODEC),r.set(e,2),`did:key:z${base58btcEncode(r)}`}function didToPublicKeyBytes(e){if(!e.startsWith("did:key:z"))return(0,shared_1.err)("INVALID_DID");try{const r=base58btcDecode(e.slice(9));return 237!==r[0]||1!==r[1]||34!==r.length?(0,shared_1.err)("INVALID_DID"):(0,shared_1.ok)(r.slice(2))}catch{return(0,shared_1.err)("INVALID_DID")}}async function exportPKCS8(e){try{const r=await crypto.subtle.exportKey("pkcs8",e);return(0,shared_1.ok)(new Uint8Array(r))}catch{return(0,shared_1.err)("EXPORT_FAILED")}}async function exportX25519PKCS8(e){try{const r=await crypto.subtle.exportKey("pkcs8",e);return(0,shared_1.ok)(new Uint8Array(r))}catch{return(0,shared_1.err)("EXPORT_FAILED")}}async function importFromPKCS8(e){try{const r=await crypto.subtle.importKey("pkcs8",toArrayBuffer(e),"Ed25519",!0,["sign"]),t=await crypto.subtle.exportKey("jwk",r);if(!t.x)return(0,shared_1.err)("IMPORT_FAILED");const a=(0,crypto_utils_js_1.fromBase64Url)(t.x),i=await crypto.subtle.importKey("raw",toArrayBuffer(a),"Ed25519",!0,["verify"]),n=publicKeyToDid(a),s=await crypto.subtle.generateKey({name:"X25519"},!0,["deriveBits"]),o=new Uint8Array(await crypto.subtle.exportKey("raw",s.publicKey));return(0,shared_1.ok)({did:n,publicKey:i,privateKey:r,rawPublicKey:a,x25519PrivateKey:s.privateKey,x25519PublicKey:s.publicKey,rawX25519PublicKey:o})}catch{return(0,shared_1.err)("IMPORT_FAILED")}}async function importIdentity(e,r,t,a,i,n){try{const s=await crypto.subtle.importKey("pkcs8",toArrayBuffer(e),"Ed25519",!0,["sign"]),o=await crypto.subtle.exportKey("jwk",s);if(!o.x)return(0,shared_1.err)("IMPORT_FAILED");const y=(0,crypto_utils_js_1.fromBase64Url)(o.x),c=await crypto.subtle.importKey("raw",toArrayBuffer(y),"Ed25519",!0,["verify"]),l=publicKeyToDid(y),u=await crypto.subtle.importKey("pkcs8",toArrayBuffer(r),{name:"X25519"},!0,["deriveBits"]),K=await crypto.subtle.exportKey("jwk",u);if(!K.x)return(0,shared_1.err)("IMPORT_FAILED");const _=(0,crypto_utils_js_1.fromBase64Url)(K.x),d=await crypto.subtle.importKey("raw",toArrayBuffer(_),{name:"X25519"},!0,[]);return(0,shared_1.ok)({did:l,publicKey:c,privateKey:s,rawPublicKey:y,x25519PrivateKey:u,x25519PublicKey:d,rawX25519PublicKey:_,...t?{mlKemSecretKey:t}:{},...a?{mlKemPublicKey:a}:{},...i?{mlDsaSecretKey:i}:{},...n?{mlDsaPublicKey:n}:{}})}catch{return(0,shared_1.err)("IMPORT_FAILED")}}function exportMlKemSecretKey(e){return e.mlKemSecretKey}function exportMlKemPublicKey(e){return e.mlKemPublicKey}async function signMlDsa65(e,r){try{const t=await mldsa_wasm_1.default.importKey("raw-seed",toArrayBuffer(e),"ML-DSA-65",!1,["sign"]),a=await mldsa_wasm_1.default.sign("ML-DSA-65",t,toArrayBuffer(r));return(0,shared_1.ok)(new Uint8Array(a))}catch{return(0,shared_1.err)("SIGN_FAILED")}}async function verifyMlDsa65(e,r,t){try{const a=await mldsa_wasm_1.default.importKey("raw-public",toArrayBuffer(e),"ML-DSA-65",!1,["verify"]),i=await mldsa_wasm_1.default.verify("ML-DSA-65",a,toArrayBuffer(r),toArrayBuffer(t));return(0,shared_1.ok)(i)}catch{return(0,shared_1.err)("VERIFY_FAILED")}}function exportMlDsaSecretKey(e){return e.mlDsaSecretKey}function exportMlDsaPublicKey(e){return e.mlDsaPublicKey}exports.ML_DSA65_SIG_BYTES=3309,exports.ML_DSA65_PK_BYTES=1952,exports.ML_DSA65_SK_BYTES=32;const ED25519_PKCS8_PREFIX=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]),X25519_PKCS8_PREFIX=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,110,4,34,4,32]);async function identityFromSeed(e,r){if(32!==e.length)return(0,shared_1.err)("INVALID_KEY_LENGTH");try{const t=await crypto.subtle.importKey("raw",toArrayBuffer(e),"HKDF",!1,["deriveBits"]),a=new Uint8Array(await crypto.subtle.deriveBits({name:"HKDF",hash:"SHA-256",salt:new Uint8Array(32),info:(new TextEncoder).encode("ed25519")},t,256)),i=new Uint8Array(await crypto.subtle.deriveBits({name:"HKDF",hash:"SHA-256",salt:new Uint8Array(32),info:(new TextEncoder).encode("x25519")},t,256)),n=new Uint8Array(await crypto.subtle.deriveBits({name:"HKDF",hash:"SHA-256",salt:new Uint8Array(32),info:(new TextEncoder).encode("ml-kem-768")},t,512)),s=new Uint8Array(ED25519_PKCS8_PREFIX.length+a.length);s.set(ED25519_PKCS8_PREFIX),s.set(a,ED25519_PKCS8_PREFIX.length);const o=new Uint8Array(X25519_PKCS8_PREFIX.length+i.length);let y,c,l,u;o.set(X25519_PKCS8_PREFIX),o.set(i,X25519_PKCS8_PREFIX.length);try{const e=await(0,mlkem_1.createMlKem768)(),[r,t]=e.deriveKeyPair(n);y=r,c=t}catch(e){console.warn("[xBind] ML-KEM-768 keygen failed, using classical crypto only:",e)}if(r?.postQuantumSig)try{const e=new Uint8Array(await crypto.subtle.deriveBits({name:"HKDF",hash:"SHA-256",salt:new Uint8Array(32),info:(new TextEncoder).encode("ml-dsa-65")},t,256)),r=await mldsa_wasm_1.default.importKey("raw-seed",e,"ML-DSA-65",!0,["sign"]),a=await mldsa_wasm_1.default.getPublicKey(r,["verify"]),i=await mldsa_wasm_1.default.exportKey("raw-public",a);u=new Uint8Array(i),l=e}catch(e){console.warn("[xBind] ML-DSA-65 keygen failed, using classical crypto only:",e)}return importIdentity(s,o,c,y,l,u)}catch{return(0,shared_1.err)("KEYGEN_FAILED")}}function extractRawEd25519(e){if(e.length!==ED25519_PKCS8_PREFIX.length+32)return(0,shared_1.err)("INVALID_KEY_LENGTH");for(let r=0;r<ED25519_PKCS8_PREFIX.length;r++)if(e[r]!==ED25519_PKCS8_PREFIX[r])return(0,shared_1.err)("IMPORT_FAILED");return(0,shared_1.ok)(e.slice(ED25519_PKCS8_PREFIX.length))}function extractRawX25519(e){if(e.length!==X25519_PKCS8_PREFIX.length+32)return(0,shared_1.err)("INVALID_KEY_LENGTH");for(let r=0;r<X25519_PKCS8_PREFIX.length;r++)if(e[r]!==X25519_PKCS8_PREFIX[r])return(0,shared_1.err)("IMPORT_FAILED");return(0,shared_1.ok)(e.slice(X25519_PKCS8_PREFIX.length))}async function rotateKeys(e){try{const r=e.rotatedKeys??[],t={rotatedAt:Date.now(),x25519PrivateKey:e.x25519PrivateKey,mlKemSecretKey:e.mlKemSecretKey},a=await crypto.subtle.generateKey({name:"X25519"},!0,["deriveBits"]),i=new Uint8Array(await crypto.subtle.exportKey("raw",a.publicKey));let n,s;if(e.mlKemPublicKey||e.mlKemSecretKey)try{const e=await(0,mlkem_1.createMlKem768)(),[r,t]=e.generateKeyPair();n=r,s=t}catch(e){console.warn("[xBind] ML-KEM-768 rotation failed, using X25519 only:",e)}const o=[t,...r].slice(0,10);return(0,shared_1.ok)({did:e.did,publicKey:e.publicKey,privateKey:e.privateKey,rawPublicKey:e.rawPublicKey,x25519PrivateKey:a.privateKey,x25519PublicKey:a.publicKey,rawX25519PublicKey:i,mlKemPublicKey:n,mlKemSecretKey:s,mlDsaPublicKey:e.mlDsaPublicKey,mlDsaSecretKey:e.mlDsaSecretKey,rotatedKeys:o})}catch{return(0,shared_1.err)("ROTATION_FAILED")}}function base58btcEncode(e){let r=0;for(const t of e){if(0!==t)break;r++}let t=0n;for(const r of e)t=256n*t+BigInt(r);const a=[];for(;t>0n;){const e=BASE58_ALPHABET[Number(t%58n)];void 0!==e&&a.unshift(e),t/=58n}for(let e=0;e<r;e++)a.unshift("1");return a.join("")}function base58btcDecode(e){let r=0;for(const t of e){if("1"!==t)break;r++}let t=0n;for(const r of e){const e=BASE58_ALPHABET.indexOf(r);if(-1===e)throw new Error("Invalid base58 character");t=58n*t+BigInt(e)}if(0n===t)return new Uint8Array(r);const a=t.toString(16),i=a.length%2?"0"+a:a,n=i.length/2,s=new Uint8Array(r+n);for(let e=0;e<n;e++)s[r+e]=parseInt(i.slice(2*e,2*e+2),16);return s}