@de-otio/chaoskb-client 0.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.
- package/dist/cli/agent-registry/config-merger.d.ts +28 -0
- package/dist/cli/agent-registry/config-merger.d.ts.map +1 -0
- package/dist/cli/agent-registry/config-merger.js +90 -0
- package/dist/cli/agent-registry/config-merger.js.map +1 -0
- package/dist/cli/agent-registry/detector.d.ts +7 -0
- package/dist/cli/agent-registry/detector.d.ts.map +1 -0
- package/dist/cli/agent-registry/detector.js +100 -0
- package/dist/cli/agent-registry/detector.js.map +1 -0
- package/dist/cli/agent-registry/index.d.ts +26 -0
- package/dist/cli/agent-registry/index.d.ts.map +1 -0
- package/dist/cli/agent-registry/index.js +77 -0
- package/dist/cli/agent-registry/index.js.map +1 -0
- package/dist/cli/agent-registry/path-validator.d.ts +11 -0
- package/dist/cli/agent-registry/path-validator.d.ts.map +1 -0
- package/dist/cli/agent-registry/path-validator.js +69 -0
- package/dist/cli/agent-registry/path-validator.js.map +1 -0
- package/dist/cli/agent-registry/registry.json +108 -0
- package/dist/cli/agent-registry/types.d.ts +29 -0
- package/dist/cli/agent-registry/types.d.ts.map +1 -0
- package/dist/cli/agent-registry/types.js +2 -0
- package/dist/cli/agent-registry/types.js.map +1 -0
- package/dist/cli/bootstrap-lock.d.ts +7 -0
- package/dist/cli/bootstrap-lock.d.ts.map +1 -0
- package/dist/cli/bootstrap-lock.js +62 -0
- package/dist/cli/bootstrap-lock.js.map +1 -0
- package/dist/cli/bootstrap.d.ts +23 -0
- package/dist/cli/bootstrap.d.ts.map +1 -0
- package/dist/cli/bootstrap.js +438 -0
- package/dist/cli/bootstrap.js.map +1 -0
- package/dist/cli/commands/config.d.ts +13 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +244 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/devices.d.ts +21 -0
- package/dist/cli/commands/devices.d.ts.map +1 -0
- package/dist/cli/commands/devices.js +229 -0
- package/dist/cli/commands/devices.js.map +1 -0
- package/dist/cli/commands/export.d.ts +12 -0
- package/dist/cli/commands/export.d.ts.map +1 -0
- package/dist/cli/commands/export.js +183 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/import.d.ts +26 -0
- package/dist/cli/commands/import.d.ts.map +1 -0
- package/dist/cli/commands/import.js +311 -0
- package/dist/cli/commands/import.js.map +1 -0
- package/dist/cli/commands/kb.d.ts +39 -0
- package/dist/cli/commands/kb.d.ts.map +1 -0
- package/dist/cli/commands/kb.js +138 -0
- package/dist/cli/commands/kb.js.map +1 -0
- package/dist/cli/commands/project.d.ts +6 -0
- package/dist/cli/commands/project.d.ts.map +1 -0
- package/dist/cli/commands/project.js +115 -0
- package/dist/cli/commands/project.js.map +1 -0
- package/dist/cli/commands/projects.d.ts +33 -0
- package/dist/cli/commands/projects.d.ts.map +1 -0
- package/dist/cli/commands/projects.js +189 -0
- package/dist/cli/commands/projects.js.map +1 -0
- package/dist/cli/commands/register.d.ts +8 -0
- package/dist/cli/commands/register.d.ts.map +1 -0
- package/dist/cli/commands/register.js +146 -0
- package/dist/cli/commands/register.js.map +1 -0
- package/dist/cli/commands/rotate-key.d.ts +16 -0
- package/dist/cli/commands/rotate-key.d.ts.map +1 -0
- package/dist/cli/commands/rotate-key.js +197 -0
- package/dist/cli/commands/rotate-key.js.map +1 -0
- package/dist/cli/commands/setup-sync.d.ts +2 -0
- package/dist/cli/commands/setup-sync.d.ts.map +1 -0
- package/dist/cli/commands/setup-sync.js +165 -0
- package/dist/cli/commands/setup-sync.js.map +1 -0
- package/dist/cli/commands/setup.d.ts +12 -0
- package/dist/cli/commands/setup.d.ts.map +1 -0
- package/dist/cli/commands/setup.js +39 -0
- package/dist/cli/commands/setup.js.map +1 -0
- package/dist/cli/commands/status.d.ts +5 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +96 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/uninstall.d.ts +4 -0
- package/dist/cli/commands/uninstall.d.ts.map +1 -0
- package/dist/cli/commands/uninstall.js +85 -0
- package/dist/cli/commands/uninstall.js.map +1 -0
- package/dist/cli/commands/unregister.d.ts +2 -0
- package/dist/cli/commands/unregister.d.ts.map +1 -0
- package/dist/cli/commands/unregister.js +46 -0
- package/dist/cli/commands/unregister.js.map +1 -0
- package/dist/cli/device-metadata.d.ts +15 -0
- package/dist/cli/device-metadata.d.ts.map +1 -0
- package/dist/cli/device-metadata.js +58 -0
- package/dist/cli/device-metadata.js.map +1 -0
- package/dist/cli/github.d.ts +38 -0
- package/dist/cli/github.d.ts.map +1 -0
- package/dist/cli/github.js +159 -0
- package/dist/cli/github.js.map +1 -0
- package/dist/cli/guide-hashes.json +13 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +226 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/mcp-server.d.ts +205 -0
- package/dist/cli/mcp-server.d.ts.map +1 -0
- package/dist/cli/mcp-server.js +366 -0
- package/dist/cli/mcp-server.js.map +1 -0
- package/dist/cli/tools/kb-delete.d.ts +10 -0
- package/dist/cli/tools/kb-delete.d.ts.map +1 -0
- package/dist/cli/tools/kb-delete.js +28 -0
- package/dist/cli/tools/kb-delete.js.map +1 -0
- package/dist/cli/tools/kb-ingest.d.ts +13 -0
- package/dist/cli/tools/kb-ingest.d.ts.map +1 -0
- package/dist/cli/tools/kb-ingest.js +72 -0
- package/dist/cli/tools/kb-ingest.js.map +1 -0
- package/dist/cli/tools/kb-list.d.ts +20 -0
- package/dist/cli/tools/kb-list.d.ts.map +1 -0
- package/dist/cli/tools/kb-list.js +24 -0
- package/dist/cli/tools/kb-list.js.map +1 -0
- package/dist/cli/tools/kb-query-shared.d.ts +27 -0
- package/dist/cli/tools/kb-query-shared.d.ts.map +1 -0
- package/dist/cli/tools/kb-query-shared.js +28 -0
- package/dist/cli/tools/kb-query-shared.js.map +1 -0
- package/dist/cli/tools/kb-query.d.ts +20 -0
- package/dist/cli/tools/kb-query.d.ts.map +1 -0
- package/dist/cli/tools/kb-query.js +109 -0
- package/dist/cli/tools/kb-query.js.map +1 -0
- package/dist/cli/tools/kb-summary.d.ts +29 -0
- package/dist/cli/tools/kb-summary.d.ts.map +1 -0
- package/dist/cli/tools/kb-summary.js +89 -0
- package/dist/cli/tools/kb-summary.js.map +1 -0
- package/dist/cli/tools/kb-sync-status.d.ts +7 -0
- package/dist/cli/tools/kb-sync-status.d.ts.map +1 -0
- package/dist/cli/tools/kb-sync-status.js +48 -0
- package/dist/cli/tools/kb-sync-status.js.map +1 -0
- package/dist/crypto/aad.d.ts +8 -0
- package/dist/crypto/aad.d.ts.map +1 -0
- package/dist/crypto/aad.js +11 -0
- package/dist/crypto/aad.js.map +1 -0
- package/dist/crypto/aead.d.ts +21 -0
- package/dist/crypto/aead.d.ts.map +1 -0
- package/dist/crypto/aead.js +43 -0
- package/dist/crypto/aead.js.map +1 -0
- package/dist/crypto/argon2.d.ts +11 -0
- package/dist/crypto/argon2.d.ts.map +1 -0
- package/dist/crypto/argon2.js +33 -0
- package/dist/crypto/argon2.js.map +1 -0
- package/dist/crypto/blob-id.d.ts +6 -0
- package/dist/crypto/blob-id.d.ts.map +1 -0
- package/dist/crypto/blob-id.js +33 -0
- package/dist/crypto/blob-id.js.map +1 -0
- package/dist/crypto/canonical-json.d.ts +6 -0
- package/dist/crypto/canonical-json.d.ts.map +1 -0
- package/dist/crypto/canonical-json.js +88 -0
- package/dist/crypto/canonical-json.js.map +1 -0
- package/dist/crypto/commitment.d.ts +12 -0
- package/dist/crypto/commitment.d.ts.map +1 -0
- package/dist/crypto/commitment.js +37 -0
- package/dist/crypto/commitment.js.map +1 -0
- package/dist/crypto/encryption-service.d.ts +19 -0
- package/dist/crypto/encryption-service.d.ts.map +1 -0
- package/dist/crypto/encryption-service.js +38 -0
- package/dist/crypto/encryption-service.js.map +1 -0
- package/dist/crypto/envelope-cbor.d.ts +37 -0
- package/dist/crypto/envelope-cbor.d.ts.map +1 -0
- package/dist/crypto/envelope-cbor.js +124 -0
- package/dist/crypto/envelope-cbor.js.map +1 -0
- package/dist/crypto/envelope.d.ts +34 -0
- package/dist/crypto/envelope.d.ts.map +1 -0
- package/dist/crypto/envelope.js +160 -0
- package/dist/crypto/envelope.js.map +1 -0
- package/dist/crypto/hkdf.d.ts +16 -0
- package/dist/crypto/hkdf.d.ts.map +1 -0
- package/dist/crypto/hkdf.js +33 -0
- package/dist/crypto/hkdf.js.map +1 -0
- package/dist/crypto/index.d.ts +15 -0
- package/dist/crypto/index.d.ts.map +1 -0
- package/dist/crypto/index.js +15 -0
- package/dist/crypto/index.js.map +1 -0
- package/dist/crypto/invite.d.ts +31 -0
- package/dist/crypto/invite.d.ts.map +1 -0
- package/dist/crypto/invite.js +137 -0
- package/dist/crypto/invite.js.map +1 -0
- package/dist/crypto/keyring.d.ts +37 -0
- package/dist/crypto/keyring.d.ts.map +1 -0
- package/dist/crypto/keyring.js +219 -0
- package/dist/crypto/keyring.js.map +1 -0
- package/dist/crypto/known-keys.d.ts +34 -0
- package/dist/crypto/known-keys.d.ts.map +1 -0
- package/dist/crypto/known-keys.js +106 -0
- package/dist/crypto/known-keys.js.map +1 -0
- package/dist/crypto/project-keys.d.ts +26 -0
- package/dist/crypto/project-keys.d.ts.map +1 -0
- package/dist/crypto/project-keys.js +69 -0
- package/dist/crypto/project-keys.js.map +1 -0
- package/dist/crypto/secure-buffer.d.ts +31 -0
- package/dist/crypto/secure-buffer.d.ts.map +1 -0
- package/dist/crypto/secure-buffer.js +61 -0
- package/dist/crypto/secure-buffer.js.map +1 -0
- package/dist/crypto/ssh-agent.d.ts +16 -0
- package/dist/crypto/ssh-agent.d.ts.map +1 -0
- package/dist/crypto/ssh-agent.js +225 -0
- package/dist/crypto/ssh-agent.js.map +1 -0
- package/dist/crypto/ssh-keys.d.ts +19 -0
- package/dist/crypto/ssh-keys.d.ts.map +1 -0
- package/dist/crypto/ssh-keys.js +121 -0
- package/dist/crypto/ssh-keys.js.map +1 -0
- package/dist/crypto/tiers/enhanced.d.ts +25 -0
- package/dist/crypto/tiers/enhanced.d.ts.map +1 -0
- package/dist/crypto/tiers/enhanced.js +56 -0
- package/dist/crypto/tiers/enhanced.js.map +1 -0
- package/dist/crypto/tiers/maximum.d.ts +19 -0
- package/dist/crypto/tiers/maximum.d.ts.map +1 -0
- package/dist/crypto/tiers/maximum.js +25 -0
- package/dist/crypto/tiers/maximum.js.map +1 -0
- package/dist/crypto/tiers/standard.d.ts +27 -0
- package/dist/crypto/tiers/standard.d.ts.map +1 -0
- package/dist/crypto/tiers/standard.js +147 -0
- package/dist/crypto/tiers/standard.js.map +1 -0
- package/dist/crypto/types.d.ts +169 -0
- package/dist/crypto/types.d.ts.map +1 -0
- package/dist/crypto/types.js +11 -0
- package/dist/crypto/types.js.map +1 -0
- package/dist/pipeline/chunker.d.ts +27 -0
- package/dist/pipeline/chunker.d.ts.map +1 -0
- package/dist/pipeline/chunker.js +96 -0
- package/dist/pipeline/chunker.js.map +1 -0
- package/dist/pipeline/content-pipeline.d.ts +24 -0
- package/dist/pipeline/content-pipeline.d.ts.map +1 -0
- package/dist/pipeline/content-pipeline.js +49 -0
- package/dist/pipeline/content-pipeline.js.map +1 -0
- package/dist/pipeline/embedder.d.ts +49 -0
- package/dist/pipeline/embedder.d.ts.map +1 -0
- package/dist/pipeline/embedder.js +195 -0
- package/dist/pipeline/embedder.js.map +1 -0
- package/dist/pipeline/extract.d.ts +17 -0
- package/dist/pipeline/extract.d.ts.map +1 -0
- package/dist/pipeline/extract.js +70 -0
- package/dist/pipeline/extract.js.map +1 -0
- package/dist/pipeline/fetch.d.ts +26 -0
- package/dist/pipeline/fetch.d.ts.map +1 -0
- package/dist/pipeline/fetch.js +91 -0
- package/dist/pipeline/fetch.js.map +1 -0
- package/dist/pipeline/index.d.ts +10 -0
- package/dist/pipeline/index.d.ts.map +1 -0
- package/dist/pipeline/index.js +10 -0
- package/dist/pipeline/index.js.map +1 -0
- package/dist/pipeline/model-manager.d.ts +57 -0
- package/dist/pipeline/model-manager.d.ts.map +1 -0
- package/dist/pipeline/model-manager.js +234 -0
- package/dist/pipeline/model-manager.js.map +1 -0
- package/dist/pipeline/search.d.ts +37 -0
- package/dist/pipeline/search.d.ts.map +1 -0
- package/dist/pipeline/search.js +65 -0
- package/dist/pipeline/search.js.map +1 -0
- package/dist/pipeline/tokenizer.d.ts +29 -0
- package/dist/pipeline/tokenizer.d.ts.map +1 -0
- package/dist/pipeline/tokenizer.js +54 -0
- package/dist/pipeline/tokenizer.js.map +1 -0
- package/dist/pipeline/types.d.ts +86 -0
- package/dist/pipeline/types.d.ts.map +1 -0
- package/dist/pipeline/types.js +2 -0
- package/dist/pipeline/types.js.map +1 -0
- package/dist/pipeline/wordpiece-tokenizer.d.ts +60 -0
- package/dist/pipeline/wordpiece-tokenizer.d.ts.map +1 -0
- package/dist/pipeline/wordpiece-tokenizer.js +251 -0
- package/dist/pipeline/wordpiece-tokenizer.js.map +1 -0
- package/dist/storage/chunk-repo.d.ts +29 -0
- package/dist/storage/chunk-repo.d.ts.map +1 -0
- package/dist/storage/chunk-repo.js +115 -0
- package/dist/storage/chunk-repo.js.map +1 -0
- package/dist/storage/database-manager.d.ts +17 -0
- package/dist/storage/database-manager.d.ts.map +1 -0
- package/dist/storage/database-manager.js +100 -0
- package/dist/storage/database-manager.js.map +1 -0
- package/dist/storage/database.d.ts +10 -0
- package/dist/storage/database.d.ts.map +1 -0
- package/dist/storage/database.js +34 -0
- package/dist/storage/database.js.map +1 -0
- package/dist/storage/embedding-index.d.ts +22 -0
- package/dist/storage/embedding-index.d.ts.map +1 -0
- package/dist/storage/embedding-index.js +78 -0
- package/dist/storage/embedding-index.js.map +1 -0
- package/dist/storage/index.d.ts +10 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +10 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/kb-database.d.ts +11 -0
- package/dist/storage/kb-database.d.ts.map +1 -0
- package/dist/storage/kb-database.js +24 -0
- package/dist/storage/kb-database.js.map +1 -0
- package/dist/storage/schema.d.ts +6 -0
- package/dist/storage/schema.d.ts.map +1 -0
- package/dist/storage/schema.js +122 -0
- package/dist/storage/schema.js.map +1 -0
- package/dist/storage/source-repo.d.ts +20 -0
- package/dist/storage/source-repo.d.ts.map +1 -0
- package/dist/storage/source-repo.js +120 -0
- package/dist/storage/source-repo.js.map +1 -0
- package/dist/storage/sync-status-repo.d.ts +15 -0
- package/dist/storage/sync-status-repo.d.ts.map +1 -0
- package/dist/storage/sync-status-repo.js +40 -0
- package/dist/storage/sync-status-repo.js.map +1 -0
- package/dist/storage/types.d.ts +139 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/storage/types.js +9 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/sync/canary.d.ts +14 -0
- package/dist/sync/canary.d.ts.map +1 -0
- package/dist/sync/canary.js +53 -0
- package/dist/sync/canary.js.map +1 -0
- package/dist/sync/full-sync.d.ts +16 -0
- package/dist/sync/full-sync.d.ts.map +1 -0
- package/dist/sync/full-sync.js +91 -0
- package/dist/sync/full-sync.js.map +1 -0
- package/dist/sync/http-client.d.ts +28 -0
- package/dist/sync/http-client.d.ts.map +1 -0
- package/dist/sync/http-client.js +90 -0
- package/dist/sync/http-client.js.map +1 -0
- package/dist/sync/incremental-sync.d.ts +17 -0
- package/dist/sync/incremental-sync.d.ts.map +1 -0
- package/dist/sync/incremental-sync.js +155 -0
- package/dist/sync/incremental-sync.js.map +1 -0
- package/dist/sync/index.d.ts +12 -0
- package/dist/sync/index.d.ts.map +1 -0
- package/dist/sync/index.js +12 -0
- package/dist/sync/index.js.map +1 -0
- package/dist/sync/quota.d.ts +17 -0
- package/dist/sync/quota.d.ts.map +1 -0
- package/dist/sync/quota.js +48 -0
- package/dist/sync/quota.js.map +1 -0
- package/dist/sync/sequence.d.ts +21 -0
- package/dist/sync/sequence.d.ts.map +1 -0
- package/dist/sync/sequence.js +49 -0
- package/dist/sync/sequence.js.map +1 -0
- package/dist/sync/ssh-signer.d.ts +59 -0
- package/dist/sync/ssh-signer.d.ts.map +1 -0
- package/dist/sync/ssh-signer.js +241 -0
- package/dist/sync/ssh-signer.js.map +1 -0
- package/dist/sync/sync-service.d.ts +48 -0
- package/dist/sync/sync-service.d.ts.map +1 -0
- package/dist/sync/sync-service.js +116 -0
- package/dist/sync/sync-service.js.map +1 -0
- package/dist/sync/types.d.ts +106 -0
- package/dist/sync/types.d.ts.map +1 -0
- package/dist/sync/types.js +2 -0
- package/dist/sync/types.js.map +1 -0
- package/dist/sync/upload-queue.d.ts +40 -0
- package/dist/sync/upload-queue.d.ts.map +1 -0
- package/dist/sync/upload-queue.js +148 -0
- package/dist/sync/upload-queue.js.map +1 -0
- package/dist/sync/verification.d.ts +17 -0
- package/dist/sync/verification.d.ts.map +1 -0
- package/dist/sync/verification.js +25 -0
- package/dist/sync/verification.js.map +1 -0
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +16 -0
- package/dist/vitest.config.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC 8785 Canonical JSON serialization.
|
|
3
|
+
* Sorted keys (recursive), no whitespace, proper Unicode escaping.
|
|
4
|
+
*/
|
|
5
|
+
export function canonicalJson(obj) {
|
|
6
|
+
return serializeValue(obj);
|
|
7
|
+
}
|
|
8
|
+
function serializeValue(value) {
|
|
9
|
+
if (value === null) {
|
|
10
|
+
return 'null';
|
|
11
|
+
}
|
|
12
|
+
switch (typeof value) {
|
|
13
|
+
case 'boolean':
|
|
14
|
+
return value ? 'true' : 'false';
|
|
15
|
+
case 'number':
|
|
16
|
+
return serializeNumber(value);
|
|
17
|
+
case 'string':
|
|
18
|
+
return serializeString(value);
|
|
19
|
+
case 'object':
|
|
20
|
+
if (Array.isArray(value)) {
|
|
21
|
+
return serializeArray(value);
|
|
22
|
+
}
|
|
23
|
+
return serializeObject(value);
|
|
24
|
+
default:
|
|
25
|
+
throw new TypeError(`Unsupported type: ${typeof value}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function serializeNumber(n) {
|
|
29
|
+
if (!Number.isFinite(n)) {
|
|
30
|
+
throw new TypeError(`Non-finite number: ${n}`);
|
|
31
|
+
}
|
|
32
|
+
// RFC 8785: use ES2015 Number serialization (which JSON.stringify uses)
|
|
33
|
+
// For integers, no decimal point. For floats, shortest representation.
|
|
34
|
+
if (Object.is(n, -0)) {
|
|
35
|
+
return '0';
|
|
36
|
+
}
|
|
37
|
+
return JSON.stringify(n);
|
|
38
|
+
}
|
|
39
|
+
function serializeString(s) {
|
|
40
|
+
// RFC 8785: escape control characters, backslash, double-quote.
|
|
41
|
+
// Characters U+0000..U+001F must be escaped with \uXXXX (except \b \f \n \r \t which use short form).
|
|
42
|
+
// All other characters (including non-BMP via surrogate pairs) are passed through literally.
|
|
43
|
+
let result = '"';
|
|
44
|
+
for (let i = 0; i < s.length; i++) {
|
|
45
|
+
const code = s.charCodeAt(i);
|
|
46
|
+
if (code === 0x08) {
|
|
47
|
+
result += '\\b';
|
|
48
|
+
}
|
|
49
|
+
else if (code === 0x09) {
|
|
50
|
+
result += '\\t';
|
|
51
|
+
}
|
|
52
|
+
else if (code === 0x0a) {
|
|
53
|
+
result += '\\n';
|
|
54
|
+
}
|
|
55
|
+
else if (code === 0x0c) {
|
|
56
|
+
result += '\\f';
|
|
57
|
+
}
|
|
58
|
+
else if (code === 0x0d) {
|
|
59
|
+
result += '\\r';
|
|
60
|
+
}
|
|
61
|
+
else if (code === 0x22) {
|
|
62
|
+
result += '\\"';
|
|
63
|
+
}
|
|
64
|
+
else if (code === 0x5c) {
|
|
65
|
+
result += '\\\\';
|
|
66
|
+
}
|
|
67
|
+
else if (code < 0x20) {
|
|
68
|
+
result += `\\u${code.toString(16).padStart(4, '0')}`;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
result += s[i];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
result += '"';
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
function serializeArray(arr) {
|
|
78
|
+
const items = arr.map((item) => serializeValue(item));
|
|
79
|
+
return '[' + items.join(',') + ']';
|
|
80
|
+
}
|
|
81
|
+
function serializeObject(obj) {
|
|
82
|
+
const keys = Object.keys(obj).sort();
|
|
83
|
+
const pairs = keys
|
|
84
|
+
.filter((key) => obj[key] !== undefined)
|
|
85
|
+
.map((key) => serializeString(key) + ':' + serializeValue(obj[key]));
|
|
86
|
+
return '{' + pairs.join(',') + '}';
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=canonical-json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonical-json.js","sourceRoot":"","sources":["../../crypto/canonical-json.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compute HMAC-SHA256 key commitment.
|
|
3
|
+
* commitment = HMAC-SHA256(commitKey, blobIdBytes || rawCt)
|
|
4
|
+
* where blobIdBytes is the UTF-8 encoding of the blob ID string.
|
|
5
|
+
*/
|
|
6
|
+
export declare function computeCommitment(commitKey: Uint8Array, blobId: string, rawCt: Uint8Array): Uint8Array;
|
|
7
|
+
/**
|
|
8
|
+
* Verify a key commitment using constant-time comparison.
|
|
9
|
+
* Returns true if the commitment is valid.
|
|
10
|
+
*/
|
|
11
|
+
export declare function verifyCommitment(commitKey: Uint8Array, blobId: string, rawCt: Uint8Array, expected: Uint8Array): boolean;
|
|
12
|
+
//# sourceMappingURL=commitment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commitment.d.ts","sourceRoot":"","sources":["../../crypto/commitment.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,UAAU,EACrB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,UAAU,GAChB,UAAU,CAMZ;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,UAAU,EACrB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,UAAU,GACnB,OAAO,CAGT"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { hmac } from '@noble/hashes/hmac.js';
|
|
2
|
+
import { sha256 } from '@noble/hashes/sha2.js';
|
|
3
|
+
/**
|
|
4
|
+
* Compute HMAC-SHA256 key commitment.
|
|
5
|
+
* commitment = HMAC-SHA256(commitKey, blobIdBytes || rawCt)
|
|
6
|
+
* where blobIdBytes is the UTF-8 encoding of the blob ID string.
|
|
7
|
+
*/
|
|
8
|
+
export function computeCommitment(commitKey, blobId, rawCt) {
|
|
9
|
+
const blobIdBytes = new TextEncoder().encode(blobId);
|
|
10
|
+
const message = new Uint8Array(blobIdBytes.length + rawCt.length);
|
|
11
|
+
message.set(blobIdBytes, 0);
|
|
12
|
+
message.set(rawCt, blobIdBytes.length);
|
|
13
|
+
return hmac(sha256, commitKey, message);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Verify a key commitment using constant-time comparison.
|
|
17
|
+
* Returns true if the commitment is valid.
|
|
18
|
+
*/
|
|
19
|
+
export function verifyCommitment(commitKey, blobId, rawCt, expected) {
|
|
20
|
+
const computed = computeCommitment(commitKey, blobId, rawCt);
|
|
21
|
+
return constantTimeEqual(computed, expected);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Constant-time comparison of two byte arrays.
|
|
25
|
+
* Always compares the full length to prevent timing side-channels.
|
|
26
|
+
*/
|
|
27
|
+
function constantTimeEqual(a, b) {
|
|
28
|
+
if (a.length !== b.length) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
let diff = 0;
|
|
32
|
+
for (let i = 0; i < a.length; i++) {
|
|
33
|
+
diff |= a[i] ^ b[i];
|
|
34
|
+
}
|
|
35
|
+
return diff === 0;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=commitment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commitment.js","sourceRoot":"","sources":["../../crypto/commitment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,SAAqB,EACrB,MAAc,EACd,KAAiB;IAEjB,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACvC,OAAO,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAC1C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,SAAqB,EACrB,MAAc,EACd,KAAiB,EACjB,QAAoB;IAEpB,MAAM,QAAQ,GAAG,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IAC7D,OAAO,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC/C,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CAAC,CAAa,EAAE,CAAa;IACrD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACtB,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { DerivedKeySet, DecryptResult, EncryptResult, Envelope, IEncryptionService, ISecureBuffer, KeyId, Payload } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Concrete implementation of IEncryptionService.
|
|
4
|
+
*
|
|
5
|
+
* Wraps the standalone crypto functions into a single injectable service.
|
|
6
|
+
*/
|
|
7
|
+
export declare class EncryptionService implements IEncryptionService {
|
|
8
|
+
/** Generate a new random 32-byte master key in a SecureBuffer. */
|
|
9
|
+
generateMasterKey(): ISecureBuffer;
|
|
10
|
+
/** Derive all subkeys from a master key via HKDF-SHA256. */
|
|
11
|
+
deriveKeys(masterKey: ISecureBuffer, salt?: Uint8Array): DerivedKeySet;
|
|
12
|
+
/** Encrypt a payload into an envelope. */
|
|
13
|
+
encrypt(payload: Payload, keys: DerivedKeySet, kid?: KeyId): EncryptResult;
|
|
14
|
+
/** Decrypt an envelope into a payload. */
|
|
15
|
+
decrypt(envelope: Envelope, keys: DerivedKeySet): DecryptResult;
|
|
16
|
+
/** Generate a CSPRNG blob ID (b_ prefix + base62). */
|
|
17
|
+
generateBlobId(): string;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=encryption-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption-service.d.ts","sourceRoot":"","sources":["../../crypto/encryption-service.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACb,QAAQ,EACR,kBAAkB,EAClB,aAAa,EACb,KAAK,EACL,OAAO,EACR,MAAM,YAAY,CAAC;AAEpB;;;;GAIG;AACH,qBAAa,iBAAkB,YAAW,kBAAkB;IAC1D,kEAAkE;IAClE,iBAAiB,IAAI,aAAa;IASlC,4DAA4D;IAC5D,UAAU,CAAC,SAAS,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,aAAa;IAItE,0CAA0C;IAC1C,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,CAAC,EAAE,KAAK,GAAG,aAAa;IAI1E,0CAA0C;IAC1C,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,GAAG,aAAa;IAI/D,sDAAsD;IACtD,cAAc,IAAI,MAAM;CAGzB"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import { generateBlobId } from './blob-id.js';
|
|
3
|
+
import { encryptPayload, decryptEnvelope } from './envelope.js';
|
|
4
|
+
import { deriveKeySet } from './hkdf.js';
|
|
5
|
+
import { SecureBuffer } from './secure-buffer.js';
|
|
6
|
+
/**
|
|
7
|
+
* Concrete implementation of IEncryptionService.
|
|
8
|
+
*
|
|
9
|
+
* Wraps the standalone crypto functions into a single injectable service.
|
|
10
|
+
*/
|
|
11
|
+
export class EncryptionService {
|
|
12
|
+
/** Generate a new random 32-byte master key in a SecureBuffer. */
|
|
13
|
+
generateMasterKey() {
|
|
14
|
+
const sb = SecureBuffer.alloc(32);
|
|
15
|
+
const tmp = randomBytes(32);
|
|
16
|
+
tmp.copy(sb.buffer);
|
|
17
|
+
// Zero the temporary buffer
|
|
18
|
+
tmp.fill(0);
|
|
19
|
+
return sb;
|
|
20
|
+
}
|
|
21
|
+
/** Derive all subkeys from a master key via HKDF-SHA256. */
|
|
22
|
+
deriveKeys(masterKey, salt) {
|
|
23
|
+
return deriveKeySet(new Uint8Array(masterKey.buffer), salt);
|
|
24
|
+
}
|
|
25
|
+
/** Encrypt a payload into an envelope. */
|
|
26
|
+
encrypt(payload, keys, kid) {
|
|
27
|
+
return encryptPayload(payload, keys, kid);
|
|
28
|
+
}
|
|
29
|
+
/** Decrypt an envelope into a payload. */
|
|
30
|
+
decrypt(envelope, keys) {
|
|
31
|
+
return decryptEnvelope(envelope, keys);
|
|
32
|
+
}
|
|
33
|
+
/** Generate a CSPRNG blob ID (b_ prefix + base62). */
|
|
34
|
+
generateBlobId() {
|
|
35
|
+
return generateBlobId();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=encryption-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption-service.js","sourceRoot":"","sources":["../../crypto/encryption-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAYlD;;;;GAIG;AACH,MAAM,OAAO,iBAAiB;IAC5B,kEAAkE;IAClE,iBAAiB;QACf,MAAM,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClC,MAAM,GAAG,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;QAC5B,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QACpB,4BAA4B;QAC5B,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACZ,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,4DAA4D;IAC5D,UAAU,CAAC,SAAwB,EAAE,IAAiB;QACpD,OAAO,YAAY,CAAC,IAAI,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;IAC9D,CAAC;IAED,0CAA0C;IAC1C,OAAO,CAAC,OAAgB,EAAE,IAAmB,EAAE,GAAW;QACxD,OAAO,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;IAC5C,CAAC;IAED,0CAA0C;IAC1C,OAAO,CAAC,QAAkB,EAAE,IAAmB;QAC7C,OAAO,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACzC,CAAC;IAED,sDAAsD;IACtD,cAAc;QACZ,OAAO,cAAc,EAAE,CAAC;IAC1B,CAAC;CACF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CBOR serialization for ChaosKB envelopes (v2 wire format).
|
|
3
|
+
*
|
|
4
|
+
* v2 envelopes store ciphertext and commitment as raw binary (Uint8Array)
|
|
5
|
+
* instead of base64, saving ~33% size overhead on the ciphertext field.
|
|
6
|
+
*
|
|
7
|
+
* Backward compatibility: can read both v1 (JSON) and v2 (CBOR) envelopes.
|
|
8
|
+
*/
|
|
9
|
+
import type { Envelope, EnvelopeV2, AnyEnvelope } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Serialize an envelope to CBOR binary format (v2).
|
|
12
|
+
*
|
|
13
|
+
* @param envelope - A v2 envelope with raw binary ct and commit.
|
|
14
|
+
* @returns CBOR-encoded bytes.
|
|
15
|
+
*/
|
|
16
|
+
export declare function serializeEnvelopeCBOR(envelope: EnvelopeV2): Uint8Array;
|
|
17
|
+
/**
|
|
18
|
+
* Deserialize bytes into an envelope, auto-detecting the format.
|
|
19
|
+
*
|
|
20
|
+
* - If bytes start with "CKB" magic header, decode as CBOR (v2)
|
|
21
|
+
* - If bytes start with '{', decode as JSON (v1)
|
|
22
|
+
*
|
|
23
|
+
* @param bytes - Raw envelope bytes.
|
|
24
|
+
* @returns Parsed envelope (v1 or v2).
|
|
25
|
+
*/
|
|
26
|
+
export declare function deserializeEnvelope(bytes: Uint8Array): AnyEnvelope;
|
|
27
|
+
/**
|
|
28
|
+
* Convert a v1 (JSON) envelope to a v2 (CBOR) envelope.
|
|
29
|
+
* Decodes base64 fields to raw binary.
|
|
30
|
+
*/
|
|
31
|
+
export declare function upgradeToV2(v1: Envelope): EnvelopeV2;
|
|
32
|
+
/**
|
|
33
|
+
* Convert a v2 (CBOR) envelope back to v1 (JSON) format.
|
|
34
|
+
* Encodes binary fields as base64.
|
|
35
|
+
*/
|
|
36
|
+
export declare function downgradeToV1(v2: EnvelopeV2): Envelope;
|
|
37
|
+
//# sourceMappingURL=envelope-cbor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envelope-cbor.d.ts","sourceRoot":"","sources":["../../crypto/envelope-cbor.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAKpE;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,UAAU,GAAG,UAAU,CAqBtE;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,CAalE;AAiDD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,QAAQ,GAAG,UAAU,CAYpD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,UAAU,GAAG,QAAQ,CActD"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CBOR serialization for ChaosKB envelopes (v2 wire format).
|
|
3
|
+
*
|
|
4
|
+
* v2 envelopes store ciphertext and commitment as raw binary (Uint8Array)
|
|
5
|
+
* instead of base64, saving ~33% size overhead on the ciphertext field.
|
|
6
|
+
*
|
|
7
|
+
* Backward compatibility: can read both v1 (JSON) and v2 (CBOR) envelopes.
|
|
8
|
+
*/
|
|
9
|
+
import { encode, decode } from 'cborg';
|
|
10
|
+
/** CBOR tag used to identify ChaosKB envelopes (arbitrary, in private range). */
|
|
11
|
+
const CHAOSKB_CBOR_MAGIC = new Uint8Array([0x43, 0x4b, 0x42]); // "CKB"
|
|
12
|
+
/**
|
|
13
|
+
* Serialize an envelope to CBOR binary format (v2).
|
|
14
|
+
*
|
|
15
|
+
* @param envelope - A v2 envelope with raw binary ct and commit.
|
|
16
|
+
* @returns CBOR-encoded bytes.
|
|
17
|
+
*/
|
|
18
|
+
export function serializeEnvelopeCBOR(envelope) {
|
|
19
|
+
const cborPayload = {
|
|
20
|
+
v: envelope.v,
|
|
21
|
+
id: envelope.id,
|
|
22
|
+
ts: envelope.ts,
|
|
23
|
+
enc: {
|
|
24
|
+
alg: envelope.enc.alg,
|
|
25
|
+
kid: envelope.enc.kid,
|
|
26
|
+
ct: envelope.enc.ct,
|
|
27
|
+
commit: envelope.enc.commit,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
const cborBytes = encode(cborPayload);
|
|
31
|
+
// Prepend magic header so we can distinguish CBOR from JSON
|
|
32
|
+
const result = new Uint8Array(CHAOSKB_CBOR_MAGIC.length + cborBytes.length);
|
|
33
|
+
result.set(CHAOSKB_CBOR_MAGIC, 0);
|
|
34
|
+
result.set(cborBytes, CHAOSKB_CBOR_MAGIC.length);
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Deserialize bytes into an envelope, auto-detecting the format.
|
|
39
|
+
*
|
|
40
|
+
* - If bytes start with "CKB" magic header, decode as CBOR (v2)
|
|
41
|
+
* - If bytes start with '{', decode as JSON (v1)
|
|
42
|
+
*
|
|
43
|
+
* @param bytes - Raw envelope bytes.
|
|
44
|
+
* @returns Parsed envelope (v1 or v2).
|
|
45
|
+
*/
|
|
46
|
+
export function deserializeEnvelope(bytes) {
|
|
47
|
+
// Check for CBOR magic header
|
|
48
|
+
if (bytes.length >= CHAOSKB_CBOR_MAGIC.length &&
|
|
49
|
+
bytes[0] === CHAOSKB_CBOR_MAGIC[0] &&
|
|
50
|
+
bytes[1] === CHAOSKB_CBOR_MAGIC[1] &&
|
|
51
|
+
bytes[2] === CHAOSKB_CBOR_MAGIC[2]) {
|
|
52
|
+
return deserializeCBOR(bytes.subarray(CHAOSKB_CBOR_MAGIC.length));
|
|
53
|
+
}
|
|
54
|
+
// Try JSON (v1)
|
|
55
|
+
return deserializeJSON(bytes);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Decode CBOR bytes into a v2 envelope.
|
|
59
|
+
*/
|
|
60
|
+
function deserializeCBOR(cborBytes) {
|
|
61
|
+
const parsed = decode(cborBytes);
|
|
62
|
+
if (parsed.v !== 2) {
|
|
63
|
+
throw new Error(`CBOR envelope has unexpected version: ${parsed.v}`);
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
v: 2,
|
|
67
|
+
id: parsed.id,
|
|
68
|
+
ts: parsed.ts,
|
|
69
|
+
enc: {
|
|
70
|
+
alg: parsed.enc.alg,
|
|
71
|
+
kid: parsed.enc.kid,
|
|
72
|
+
ct: new Uint8Array(parsed.enc.ct),
|
|
73
|
+
commit: new Uint8Array(parsed.enc.commit),
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Decode JSON bytes into a v1 envelope.
|
|
79
|
+
*/
|
|
80
|
+
function deserializeJSON(bytes) {
|
|
81
|
+
const json = new TextDecoder().decode(bytes);
|
|
82
|
+
const parsed = JSON.parse(json);
|
|
83
|
+
if (parsed.v !== 1) {
|
|
84
|
+
throw new Error(`JSON envelope has unexpected version: ${parsed.v}`);
|
|
85
|
+
}
|
|
86
|
+
return parsed;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Convert a v1 (JSON) envelope to a v2 (CBOR) envelope.
|
|
90
|
+
* Decodes base64 fields to raw binary.
|
|
91
|
+
*/
|
|
92
|
+
export function upgradeToV2(v1) {
|
|
93
|
+
return {
|
|
94
|
+
v: 2,
|
|
95
|
+
id: v1.id,
|
|
96
|
+
ts: v1.ts,
|
|
97
|
+
enc: {
|
|
98
|
+
alg: v1.enc.alg,
|
|
99
|
+
kid: v1.enc.kid,
|
|
100
|
+
ct: new Uint8Array(Buffer.from(v1.enc.ct, 'base64')),
|
|
101
|
+
commit: new Uint8Array(Buffer.from(v1.enc.commit, 'base64')),
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Convert a v2 (CBOR) envelope back to v1 (JSON) format.
|
|
107
|
+
* Encodes binary fields as base64.
|
|
108
|
+
*/
|
|
109
|
+
export function downgradeToV1(v2) {
|
|
110
|
+
const ctBase64 = Buffer.from(v2.enc.ct).toString('base64');
|
|
111
|
+
return {
|
|
112
|
+
v: 1,
|
|
113
|
+
id: v2.id,
|
|
114
|
+
ts: v2.ts,
|
|
115
|
+
enc: {
|
|
116
|
+
alg: v2.enc.alg,
|
|
117
|
+
kid: v2.enc.kid,
|
|
118
|
+
ct: ctBase64,
|
|
119
|
+
'ct.len': v2.enc.ct.length,
|
|
120
|
+
commit: Buffer.from(v2.enc.commit).toString('base64'),
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=envelope-cbor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envelope-cbor.js","sourceRoot":"","sources":["../../crypto/envelope-cbor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { DerivedKeySet, DecryptResult, EncryptResult, Envelope, KeyId, Payload } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Encrypt a payload into an envelope (v1).
|
|
4
|
+
*
|
|
5
|
+
* Steps per the envelope spec:
|
|
6
|
+
* 1. Serialize payload to canonical JSON, convert to UTF-8 bytes
|
|
7
|
+
* 2. Generate blob ID
|
|
8
|
+
* 3. Select key by kid (default CEK)
|
|
9
|
+
* 4. Construct AAD
|
|
10
|
+
* 5. Encrypt with AEAD
|
|
11
|
+
* 6. Concatenate: rawCt = nonce || ciphertext || tag
|
|
12
|
+
* 7. Compute commitment: HMAC-SHA256(commitKey, blobId || rawCt)
|
|
13
|
+
* 8. Verify-after-encrypt: decrypt rawCt, compare with original plaintext
|
|
14
|
+
* 9. Base64-encode ct and commit
|
|
15
|
+
* 10. Assemble Envelope object
|
|
16
|
+
* 11. Return EncryptResult with envelope and serialized JSON bytes
|
|
17
|
+
*/
|
|
18
|
+
export declare function encryptPayload(payload: Payload, keys: DerivedKeySet, kid?: KeyId): EncryptResult;
|
|
19
|
+
/**
|
|
20
|
+
* Decrypt an envelope into a payload.
|
|
21
|
+
*
|
|
22
|
+
* Steps per the envelope spec:
|
|
23
|
+
* 1. Check v == 1
|
|
24
|
+
* 2. Base64-decode ct
|
|
25
|
+
* 3. Verify ct.len matches decoded length
|
|
26
|
+
* 4. Verify key commitment
|
|
27
|
+
* 5. Construct AAD
|
|
28
|
+
* 6. Split rawCt into nonce, ciphertext, tag
|
|
29
|
+
* 7. Decrypt
|
|
30
|
+
* 8. Parse plaintext as JSON, validate type field
|
|
31
|
+
* 9. Return DecryptResult
|
|
32
|
+
*/
|
|
33
|
+
export declare function decryptEnvelope(envelope: Envelope, keys: DerivedKeySet): DecryptResult;
|
|
34
|
+
//# sourceMappingURL=envelope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../../crypto/envelope.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAEV,aAAa,EACb,aAAa,EACb,aAAa,EACb,QAAQ,EACR,KAAK,EACL,OAAO,EACR,MAAM,YAAY,CAAC;AAwBpB;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,aAAa,EACnB,GAAG,GAAE,KAAa,GACjB,aAAa,CA0Df;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,GAAG,aAAa,CA0DtF"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { aeadDecrypt, aeadEncrypt } from './aead.js';
|
|
2
|
+
import { constructAAD } from './aad.js';
|
|
3
|
+
import { generateBlobId } from './blob-id.js';
|
|
4
|
+
import { canonicalJson } from './canonical-json.js';
|
|
5
|
+
import { computeCommitment, verifyCommitment } from './commitment.js';
|
|
6
|
+
// Algorithm parameters: nonce size and tag size
|
|
7
|
+
const ALG_PARAMS = {
|
|
8
|
+
'XChaCha20-Poly1305': { nonceSize: 24, tagSize: 16 },
|
|
9
|
+
'AES-256-GCM': { nonceSize: 12, tagSize: 16 },
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Look up the encryption key for a given key identifier.
|
|
13
|
+
*/
|
|
14
|
+
function getKey(keys, kid) {
|
|
15
|
+
switch (kid) {
|
|
16
|
+
case 'CEK':
|
|
17
|
+
return new Uint8Array(keys.contentKey.buffer);
|
|
18
|
+
case 'MEK':
|
|
19
|
+
return new Uint8Array(keys.metadataKey.buffer);
|
|
20
|
+
case 'EEK':
|
|
21
|
+
return new Uint8Array(keys.embeddingKey.buffer);
|
|
22
|
+
default:
|
|
23
|
+
throw new Error(`Unknown key identifier: ${kid}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Encrypt a payload into an envelope (v1).
|
|
28
|
+
*
|
|
29
|
+
* Steps per the envelope spec:
|
|
30
|
+
* 1. Serialize payload to canonical JSON, convert to UTF-8 bytes
|
|
31
|
+
* 2. Generate blob ID
|
|
32
|
+
* 3. Select key by kid (default CEK)
|
|
33
|
+
* 4. Construct AAD
|
|
34
|
+
* 5. Encrypt with AEAD
|
|
35
|
+
* 6. Concatenate: rawCt = nonce || ciphertext || tag
|
|
36
|
+
* 7. Compute commitment: HMAC-SHA256(commitKey, blobId || rawCt)
|
|
37
|
+
* 8. Verify-after-encrypt: decrypt rawCt, compare with original plaintext
|
|
38
|
+
* 9. Base64-encode ct and commit
|
|
39
|
+
* 10. Assemble Envelope object
|
|
40
|
+
* 11. Return EncryptResult with envelope and serialized JSON bytes
|
|
41
|
+
*/
|
|
42
|
+
export function encryptPayload(payload, keys, kid = 'CEK') {
|
|
43
|
+
const alg = 'XChaCha20-Poly1305';
|
|
44
|
+
// 1. Serialize to canonical JSON
|
|
45
|
+
const json = canonicalJson(payload);
|
|
46
|
+
const plaintextBytes = new TextEncoder().encode(json);
|
|
47
|
+
// 2. Generate blob ID
|
|
48
|
+
const blobId = generateBlobId();
|
|
49
|
+
// 3. Select encryption key
|
|
50
|
+
const encKey = getKey(keys, kid);
|
|
51
|
+
// 4. Construct AAD
|
|
52
|
+
const aad = constructAAD(alg, blobId, kid, 1);
|
|
53
|
+
// 5. Encrypt
|
|
54
|
+
const { nonce, ciphertext, tag } = aeadEncrypt(encKey, plaintextBytes, aad);
|
|
55
|
+
// 6. Concatenate: rawCt = nonce || ciphertext || tag
|
|
56
|
+
const rawCt = new Uint8Array(nonce.length + ciphertext.length + tag.length);
|
|
57
|
+
rawCt.set(nonce, 0);
|
|
58
|
+
rawCt.set(ciphertext, nonce.length);
|
|
59
|
+
rawCt.set(tag, nonce.length + ciphertext.length);
|
|
60
|
+
// 7. Compute key commitment
|
|
61
|
+
const commitKey = new Uint8Array(keys.commitKey.buffer);
|
|
62
|
+
const commitment = computeCommitment(commitKey, blobId, rawCt);
|
|
63
|
+
// 8. Verify-after-encrypt: decrypt and compare
|
|
64
|
+
const recovered = aeadDecrypt(encKey, nonce, ciphertext, tag, aad);
|
|
65
|
+
if (!constantTimeEqual(recovered, plaintextBytes)) {
|
|
66
|
+
throw new Error('Verify-after-encrypt failed: decrypted plaintext does not match original');
|
|
67
|
+
}
|
|
68
|
+
// 9. Base64-encode
|
|
69
|
+
const ctBase64 = Buffer.from(rawCt).toString('base64');
|
|
70
|
+
const commitBase64 = Buffer.from(commitment).toString('base64');
|
|
71
|
+
// 10. Assemble envelope
|
|
72
|
+
const envelope = {
|
|
73
|
+
v: 1,
|
|
74
|
+
id: blobId,
|
|
75
|
+
ts: new Date().toISOString(),
|
|
76
|
+
enc: {
|
|
77
|
+
alg,
|
|
78
|
+
kid,
|
|
79
|
+
ct: ctBase64,
|
|
80
|
+
'ct.len': rawCt.length,
|
|
81
|
+
commit: commitBase64,
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
// 11. Serialize envelope to bytes
|
|
85
|
+
const envelopeJson = JSON.stringify(envelope);
|
|
86
|
+
const bytes = new TextEncoder().encode(envelopeJson);
|
|
87
|
+
return { envelope, bytes };
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Decrypt an envelope into a payload.
|
|
91
|
+
*
|
|
92
|
+
* Steps per the envelope spec:
|
|
93
|
+
* 1. Check v == 1
|
|
94
|
+
* 2. Base64-decode ct
|
|
95
|
+
* 3. Verify ct.len matches decoded length
|
|
96
|
+
* 4. Verify key commitment
|
|
97
|
+
* 5. Construct AAD
|
|
98
|
+
* 6. Split rawCt into nonce, ciphertext, tag
|
|
99
|
+
* 7. Decrypt
|
|
100
|
+
* 8. Parse plaintext as JSON, validate type field
|
|
101
|
+
* 9. Return DecryptResult
|
|
102
|
+
*/
|
|
103
|
+
export function decryptEnvelope(envelope, keys) {
|
|
104
|
+
// 1. Check version
|
|
105
|
+
if (envelope.v !== 1) {
|
|
106
|
+
throw new Error(`Unsupported envelope version: ${envelope.v}. Please update the app.`);
|
|
107
|
+
}
|
|
108
|
+
const alg = envelope.enc.alg;
|
|
109
|
+
const params = ALG_PARAMS[alg];
|
|
110
|
+
if (!params) {
|
|
111
|
+
throw new Error(`Unsupported algorithm: ${alg}`);
|
|
112
|
+
}
|
|
113
|
+
// 2. Base64-decode ct
|
|
114
|
+
const rawCt = new Uint8Array(Buffer.from(envelope.enc.ct, 'base64'));
|
|
115
|
+
// Verify minimum length
|
|
116
|
+
const minLength = params.nonceSize + params.tagSize + 1;
|
|
117
|
+
if (rawCt.length < minLength) {
|
|
118
|
+
throw new Error(`Truncated ciphertext: expected at least ${minLength} bytes, got ${rawCt.length}`);
|
|
119
|
+
}
|
|
120
|
+
// 3. Verify ct.len
|
|
121
|
+
if (envelope.enc['ct.len'] !== undefined && rawCt.length !== envelope.enc['ct.len']) {
|
|
122
|
+
throw new Error(`Ciphertext length mismatch: ct.len=${envelope.enc['ct.len']}, actual=${rawCt.length}`);
|
|
123
|
+
}
|
|
124
|
+
// 4. Verify key commitment
|
|
125
|
+
const commitKey = new Uint8Array(keys.commitKey.buffer);
|
|
126
|
+
const expectedCommit = new Uint8Array(Buffer.from(envelope.enc.commit, 'base64'));
|
|
127
|
+
if (!verifyCommitment(commitKey, envelope.id, rawCt, expectedCommit)) {
|
|
128
|
+
throw new Error('Key commitment verification failed');
|
|
129
|
+
}
|
|
130
|
+
// 5. Construct AAD
|
|
131
|
+
const aad = constructAAD(alg, envelope.id, envelope.enc.kid, envelope.v);
|
|
132
|
+
// 6. Split rawCt into nonce, ciphertext, tag
|
|
133
|
+
const nonce = rawCt.slice(0, params.nonceSize);
|
|
134
|
+
const ciphertext = rawCt.slice(params.nonceSize, rawCt.length - params.tagSize);
|
|
135
|
+
const tag = rawCt.slice(rawCt.length - params.tagSize);
|
|
136
|
+
// 7. Decrypt
|
|
137
|
+
const encKey = getKey(keys, envelope.enc.kid);
|
|
138
|
+
const plaintext = aeadDecrypt(encKey, nonce, ciphertext, tag, aad);
|
|
139
|
+
// 8. Parse plaintext as JSON
|
|
140
|
+
const json = new TextDecoder().decode(plaintext);
|
|
141
|
+
const payload = JSON.parse(json);
|
|
142
|
+
// Validate type field exists
|
|
143
|
+
if (!payload.type || !['source', 'chunk', 'canary'].includes(payload.type)) {
|
|
144
|
+
throw new Error(`Invalid payload type: ${payload.type}`);
|
|
145
|
+
}
|
|
146
|
+
// 9. Return result
|
|
147
|
+
return { payload, envelope };
|
|
148
|
+
}
|
|
149
|
+
/** Constant-time comparison of two byte arrays. */
|
|
150
|
+
function constantTimeEqual(a, b) {
|
|
151
|
+
if (a.length !== b.length) {
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
let diff = 0;
|
|
155
|
+
for (let i = 0; i < a.length; i++) {
|
|
156
|
+
diff |= a[i] ^ b[i];
|
|
157
|
+
}
|
|
158
|
+
return diff === 0;
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=envelope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envelope.js","sourceRoot":"","sources":["../../crypto/envelope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { DerivedKeySet } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Derive a key using HKDF-SHA256 (Extract+Expand per RFC 5869).
|
|
4
|
+
* @param ikm - Input keying material
|
|
5
|
+
* @param info - Context/application-specific info string
|
|
6
|
+
* @param salt - Optional salt (defaults to empty Uint8Array)
|
|
7
|
+
* @param length - Output key length in bytes (default 32)
|
|
8
|
+
*/
|
|
9
|
+
export declare function deriveKey(ikm: Uint8Array, info: string, salt?: Uint8Array, length?: number): Uint8Array;
|
|
10
|
+
/**
|
|
11
|
+
* Derive the complete set of subkeys from a master key.
|
|
12
|
+
* Returns SecureBuffer-wrapped keys for:
|
|
13
|
+
* CEK (content), MEK (metadata), EEK (embedding), CKY (commit)
|
|
14
|
+
*/
|
|
15
|
+
export declare function deriveKeySet(masterKey: Uint8Array, salt?: Uint8Array): DerivedKeySet;
|
|
16
|
+
//# sourceMappingURL=hkdf.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hkdf.d.ts","sourceRoot":"","sources":["../../crypto/hkdf.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIhD;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,UAAU,EACf,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,UAAU,EACjB,MAAM,CAAC,EAAE,MAAM,GACd,UAAU,CAGZ;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,aAAa,CAYpF"}
|