@interncom/diplomatic 0.22.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/dist/cli/bun/src/crypto.d.ts +2 -3
  2. package/dist/cli/index.mjs +4 -5
  3. package/dist/cli/shared/api/peek.d.ts +9 -1
  4. package/dist/cli/shared/api/pull.d.ts +9 -1
  5. package/dist/cli/shared/api/push.d.ts +3 -1
  6. package/dist/cli/shared/api/user.d.ts +1 -1
  7. package/dist/cli/shared/auth.d.ts +2 -2
  8. package/dist/cli/shared/bag.d.ts +11 -6
  9. package/dist/cli/shared/client.d.ts +18 -9
  10. package/dist/cli/shared/codec.d.ts +4 -0
  11. package/dist/cli/shared/codecs/kdm.d.ts +7 -0
  12. package/dist/cli/shared/codecs/notifItem.d.ts +2 -0
  13. package/dist/cli/shared/crypto/bagman.d.ts +19 -0
  14. package/dist/cli/shared/crypto/binary.d.ts +1 -0
  15. package/dist/cli/shared/crypto/derivation.d.ts +45 -0
  16. package/dist/cli/shared/crypto/enclave.d.ts +31 -102
  17. package/dist/cli/shared/crypto/largeBlob.d.ts +8 -0
  18. package/dist/cli/shared/crypto/noble.d.ts +15 -22
  19. package/dist/cli/shared/crypto/pairing.d.ts +19 -2
  20. package/dist/cli/shared/crypto/prf.d.ts +52 -0
  21. package/dist/cli/shared/crypto/realms.d.ts +7 -0
  22. package/dist/cli/shared/endpoint.d.ts +4 -5
  23. package/dist/cli/shared/http.d.ts +12 -12
  24. package/dist/cli/shared/sync.d.ts +3 -3
  25. package/dist/cli/shared/types.d.ts +24 -16
  26. package/dist/cli/shared/webauthn/prf.d.ts +8 -0
  27. package/dist/cli/src/index.d.ts +6 -5
  28. package/dist/web/client.d.ts +18 -7
  29. package/dist/web/crypto.d.ts +2 -3
  30. package/dist/web/entdb/cached.d.ts +4 -0
  31. package/dist/web/entdb/entdb.d.ts +3 -0
  32. package/dist/web/entdb/idb.d.ts +8 -5
  33. package/dist/web/index.d.ts +11 -5
  34. package/dist/web/index.mjs +1 -1
  35. package/dist/web/objEq.d.ts +1 -0
  36. package/dist/web/passkey/prf-store.d.ts +26 -10
  37. package/dist/web/passkey/seed.d.ts +12 -6
  38. package/dist/web/shared/api/peek.d.ts +9 -1
  39. package/dist/web/shared/api/pull.d.ts +9 -1
  40. package/dist/web/shared/api/push.d.ts +3 -1
  41. package/dist/web/shared/api/user.d.ts +1 -1
  42. package/dist/web/shared/auth.d.ts +2 -2
  43. package/dist/web/shared/bag.d.ts +11 -6
  44. package/dist/web/shared/blobs.d.ts +25 -0
  45. package/dist/web/shared/client.d.ts +18 -9
  46. package/dist/web/shared/codec.d.ts +4 -0
  47. package/dist/web/shared/codecs/ent.d.ts +5 -0
  48. package/dist/web/shared/codecs/kdm.d.ts +7 -0
  49. package/dist/web/shared/codecs/notifItem.d.ts +2 -0
  50. package/dist/web/shared/crypto/bagman.d.ts +19 -0
  51. package/dist/web/shared/crypto/binary.d.ts +1 -0
  52. package/dist/web/shared/crypto/derivation.d.ts +45 -0
  53. package/dist/web/shared/crypto/enclave.d.ts +31 -102
  54. package/dist/web/shared/crypto/largeBlob.d.ts +8 -0
  55. package/dist/web/shared/crypto/noble.d.ts +15 -22
  56. package/dist/web/shared/crypto/pairing.d.ts +19 -2
  57. package/dist/web/shared/crypto/prf.d.ts +52 -0
  58. package/dist/web/shared/crypto/realms.d.ts +7 -0
  59. package/dist/web/shared/crypto/tty.d.ts +3 -0
  60. package/dist/web/shared/endpoint.d.ts +4 -5
  61. package/dist/web/shared/exim.d.ts +5 -5
  62. package/dist/web/shared/http.d.ts +12 -12
  63. package/dist/web/shared/storage/memory.d.ts +2 -2
  64. package/dist/web/shared/sync.d.ts +3 -3
  65. package/dist/web/shared/types.d.ts +24 -16
  66. package/dist/web/shared/webauthn/prf.d.ts +8 -0
  67. package/dist/web/state.d.ts +1 -2
  68. package/dist/web/stores/cursor.d.ts +30 -0
  69. package/dist/web/stores/idb/account.d.ts +58 -0
  70. package/dist/web/stores/idb/catalog.d.ts +1 -0
  71. package/dist/web/stores/idb/dnlds.d.ts +3 -2
  72. package/dist/web/stores/idb/hosts.d.ts +8 -7
  73. package/dist/web/stores/idb/idbutil.d.ts +2 -0
  74. package/dist/web/stores/idb/migrate.d.ts +2 -0
  75. package/dist/web/stores/idb/msgs.d.ts +1 -1
  76. package/dist/web/stores/idb/names.d.ts +13 -0
  77. package/dist/web/stores/idb/realms.d.ts +11 -0
  78. package/dist/web/stores/idb/store.d.ts +26 -19
  79. package/dist/web/stores/idb/uplds.d.ts +1 -1
  80. package/dist/web/stores/keyTag.d.ts +14 -0
  81. package/dist/web/stores/label.d.ts +3 -0
  82. package/dist/web/stores/memory/account.d.ts +14 -0
  83. package/dist/web/stores/memory/dnlds.d.ts +4 -2
  84. package/dist/web/stores/memory/hosts.d.ts +8 -6
  85. package/dist/web/stores/memory/realms.d.ts +10 -0
  86. package/dist/web/stores/memory/store.d.ts +6 -2
  87. package/dist/web/stores/realm.d.ts +35 -0
  88. package/dist/web/sync.d.ts +18 -16
  89. package/dist/web/types.d.ts +59 -18
  90. package/dist/web/worker/client.d.ts +7 -3
  91. package/dist/web/worker/protocol.d.ts +6 -0
  92. package/dist/web/worker/runtime.d.ts +4 -2
  93. package/dist/web/worker.mjs +1 -1
  94. package/package.json +1 -2
  95. package/dist/cli/bun/src/codec.d.ts +0 -3
  96. package/dist/web/stores/idb/seed.d.ts +0 -32
  97. package/dist/web/stores/identityPin.d.ts +0 -19
  98. package/dist/web/stores/memory/seed.d.ts +0 -13
@@ -1,6 +1,8 @@
1
1
  import { ICodecStruct } from "../codec.ts";
2
+ import { type HostRlm } from "../crypto/derivation.ts";
2
3
  export interface IBagNotifItem {
3
4
  seq: number;
5
+ rlm: HostRlm;
4
6
  headCph: Uint8Array;
5
7
  bodyCph?: Uint8Array;
6
8
  }
@@ -0,0 +1,19 @@
1
+ import type { IKDM } from "../codecs/kdm.ts";
2
+ import type { PublicKey } from "../types.ts";
3
+ import { type ValStat } from "../valstat.ts";
4
+ import type { HostRlm, PDK } from "./derivation.ts";
5
+ export declare class BagManager {
6
+ #private;
7
+ readonly publicKey: PublicKey;
8
+ private idnt;
9
+ private realm;
10
+ readonly rlm: HostRlm;
11
+ readonly idKDM: Readonly<IKDM>;
12
+ readonly realmKDM: Readonly<IKDM>;
13
+ private constructor();
14
+ static init(idnt: PDK["Identity"], realm: PDK["RealmKey"], rlm: HostRlm, idKDM: IKDM, realmKDM: IKDM): Promise<ValStat<BagManager>>;
15
+ sign(message: Uint8Array | string): Promise<ValStat<Uint8Array>>;
16
+ bagKDM(msgHeadEnc: Uint8Array): Promise<ValStat<Uint8Array>>;
17
+ encrypt(kdm: Uint8Array, data: Uint8Array): Promise<ValStat<Uint8Array>>;
18
+ decrypt(kdm: Uint8Array, data: Uint8Array): Promise<ValStat<Uint8Array>>;
19
+ }
@@ -0,0 +1 @@
1
+ export declare function bytesEqual(a: Uint8Array, b: Uint8Array): boolean;
@@ -0,0 +1,45 @@
1
+ import { type IKDM } from "../codecs/kdm.ts";
2
+ import { type ValStat } from "../valstat.ts";
3
+ export declare const Purpose: {
4
+ readonly Identity: "diplomatic.identity.v1";
5
+ readonly Cipher: "diplomatic.cipher.v1";
6
+ readonly Bind: "diplomatic.bind.v1";
7
+ readonly BindTag: "diplomatic.bindtag.v1";
8
+ readonly Fingerprint: "diplomatic.fingerprint.v1";
9
+ readonly Pair: "diplomatic.qrpair.v1";
10
+ readonly BagKdm: "diplomatic.bagkdm.v1";
11
+ readonly RealmKey: "diplomatic.realmKey.v1";
12
+ readonly RealmID: "diplomatic.realmID.v1";
13
+ readonly HostRLM: "diplomatic.hostRLM.v1";
14
+ };
15
+ export type Purpose = typeof Purpose[keyof typeof Purpose];
16
+ declare const pdkSymbol: unique symbol;
17
+ export type PurposeDerivedKey<P extends Purpose> = Uint8Array & {
18
+ readonly [pdkSymbol]: P;
19
+ };
20
+ declare const childKeySymbol: unique symbol;
21
+ export type ChildKey<P extends Purpose> = Uint8Array & {
22
+ readonly [childKeySymbol]: P;
23
+ };
24
+ export type PDK = {
25
+ [K in keyof typeof Purpose]: ChildKey<(typeof Purpose)[K]>;
26
+ };
27
+ /** Host-stamped bag rlm. Peek, pull, and bag signatures use this. */
28
+ export type HostRlm = PDK["HostRLM"];
29
+ export declare const nullKDM: IKDM;
30
+ export declare function asChildKey<P extends Purpose>(bytes: Uint8Array, _purpose: P): ValStat<ChildKey<P>>;
31
+ export declare function asHostRlm(bytes: Uint8Array): ValStat<HostRlm>;
32
+ export declare function derivePDK<P extends Purpose>({ parent, purpose, }: {
33
+ parent: Uint8Array;
34
+ purpose: P;
35
+ }): Promise<ValStat<PurposeDerivedKey<P>>>;
36
+ export declare function deriveChild<P extends Purpose>({ pdk, kdm, }: {
37
+ pdk: PurposeDerivedKey<P>;
38
+ kdm: Uint8Array | IKDM;
39
+ }): Promise<ValStat<ChildKey<P>>>;
40
+ export declare function deriveKey<P extends Purpose>({ parent, purpose, kdm, }: {
41
+ parent: Uint8Array;
42
+ purpose: P;
43
+ kdm: Uint8Array | IKDM;
44
+ }): Promise<ValStat<ChildKey<P>>>;
45
+ export {};
@@ -1,98 +1,38 @@
1
1
  import type { BundleHost } from "../codecs/bundleHost.ts";
2
+ import type { IKDM } from "../codecs/kdm.ts";
3
+ import type { MasterSeed, SealedMasterKey } from "../seed.ts";
4
+ import type { ValStat } from "../valstat.ts";
5
+ import type { PDK } from "./derivation.ts";
6
+ import type { DHKEReq, DHKEResp } from "./pairing.ts";
7
+ import type { LargeBlobCreateOpts, LargeBlobRp } from "../webauthn/largeBlob.ts";
8
+ import type { BindPrior, PasskeyPrfOpts, PrfBinding, PrfBound, PrfSealedMaster } from "./prf.ts";
2
9
  import { Status } from "../consts.ts";
3
- import { MASTER_SEED_LEN, type MasterSeed, type SealedMasterKey } from "../seed.ts";
4
- import type { ICrypto, PublicKey } from "../types.ts";
5
- import { type ValStat } from "../valstat.ts";
6
- import { type DHKEReq, type DHKEResp } from "./pairing.ts";
7
- import { type LargeBlobCreateOpts, type LargeBlobRp } from "../webauthn/largeBlob.ts";
8
- import { type PrfCeremony, type PrfCreateOpts, type PrfEvalOpts, type PrfRp } from "../webauthn/prf.ts";
9
- export type { LargeBlobCreateOpts, LargeBlobRp };
10
- export type { PrfCreateOpts, PrfEvalOpts, PrfRp };
11
- /** Options for PRF seal/unseal ceremonies (no raw PRF bytes). */
12
- export type PasskeyPrfOpts = PrfCreateOpts & {
13
- credId?: Uint8Array | readonly Uint8Array[];
14
- /** Seal only: create a PRF credential first when no credId is known. */
15
- createCredIfNeeded?: boolean;
16
- };
17
- /** One binding to try on unseal (cred id + sealed master). */
18
- export type PrfBinding = {
19
- sealedMaster: SealedMasterKey;
20
- credId: Uint8Array;
21
- };
22
- /** Durable PRF-sealed master + public ceremony facts (never includes PRF output). */
23
- export type PrfSealedMaster = PrfCeremony & {
24
- sealedMaster: SealedMasterKey;
25
- salt: Uint8Array;
26
- };
27
- /** One existing keyring member used to prove this enclave matches the list. */
28
- export type BindPrior = {
29
- credId: Uint8Array;
30
- tag: Uint8Array;
31
- };
32
- /** Seal + bind-tag from {@link Enclave.bind} (tag is not a global fingerprint). */
33
- export type PrfBound = PrfSealedMaster & {
34
- tag: Uint8Array;
35
- };
36
- export type EncryptCipher = {
37
- encrypt: (data: Uint8Array) => Promise<Uint8Array>;
38
- };
39
- export type DecryptCipher = {
40
- decrypt: (data: Uint8Array) => Promise<Uint8Array>;
41
- };
42
- /** Encrypt + decrypt capability for one KDM. */
43
- export type DerivedCipher = EncryptCipher & DecryptCipher;
44
- /** Which ops the caller needs; only those methods are present on the handle. */
45
- export type CipherUsage = "encrypt" | "decrypt" | "both";
46
- /** Return shape of `deriveCipher` for a given usage (type-level enforcement). */
47
- export type CipherForUsage<U extends CipherUsage> = {
48
- encrypt: EncryptCipher;
49
- decrypt: DecryptCipher;
50
- both: DerivedCipher;
51
- }[U];
52
- /**
53
- * Path-scoped signing identity: public key is public; sign/kdmFor re-enter
54
- * the enclave so the private key never leaves. Used for hosts, export files, etc.
55
- */
56
- export type Identity = {
57
- readonly publicKey: PublicKey;
58
- sign: (message: Uint8Array | string) => Promise<Uint8Array>;
59
- /** Per-bag KDM mixed with this identity's private key (see bag seal). */
60
- kdmFor: (msgHeadEnc: Uint8Array) => Promise<Uint8Array>;
61
- };
62
- declare const SEAL_BIND_DOMAIN: Uint8Array<ArrayBufferLike>;
63
- declare const FP_MODE: Uint8Array<ArrayBufferLike>;
64
- declare const SEAL_KEY_LEN = 32;
65
- declare const SEAL_PRF_MIN_LEN = 16;
10
+ import { PairRequest } from "./pairing.ts";
11
+ import { BagManager } from "./bagman.ts";
66
12
  /** Minimum musec length (Mandatory User-Space Entropy Contribution). */
67
- declare const MUSEC_MIN_LEN = 32;
68
- declare class PairRequest {
69
- #private;
70
- private constructor();
71
- static create(): Promise<ValStat<PairRequest>>;
72
- wipe(): void;
73
- get dhkeReq(): DHKEReq;
74
- finish(dhkeResp: DHKEResp): Promise<ValStat<{
75
- enclave: Enclave;
76
- hosts: BundleHost[];
77
- }>>;
78
- }
79
- export type { PairRequest };
13
+ export declare const MUSEC_MIN_LEN = 32;
14
+ export declare function fromSeedHosts(buf: Uint8Array): ValStat<{
15
+ enclave: OuterEnclave;
16
+ hosts: BundleHost[];
17
+ }>;
80
18
  /** Brand `bytes` as {@link MasterSeed} only if length is {@link MASTER_SEED_LEN}. */
81
19
  export declare function asMasterSeed(bytes: Uint8Array): ValStat<MasterSeed>;
82
- export declare class Enclave {
20
+ declare class OuterEnclave {
83
21
  #private;
84
22
  private constructor();
85
23
  /**
86
24
  * New enclave: blake3(OS CSPRNG ‖ musec). musec is required (MUSEC_MIN_LEN).
87
- * Mix stays in this method; musec is wiped before return.
25
+ * Musec is wiped on every return, including rejection and a throw from the
26
+ * OS generator. A rejected digest is wiped. The stored seed is that digest
27
+ * buffer, so the success path must not wipe it.
88
28
  */
89
- static fromRandom(musec: Uint8Array): Promise<ValStat<Enclave>>;
29
+ static fromRandom(musec: Uint8Array): Promise<ValStat<OuterEnclave>>;
90
30
  /**
91
31
  * Construct from raw master seed bytes (import / bootstrap only).
92
32
  * Copies the seed so callers may zero their buffer after success.
93
33
  * Prefer {@link fromRandom} or {@link unsealWithPasskey} for normal flows.
94
34
  */
95
- static fromBytes(bytes: Uint8Array): ValStat<Enclave>;
35
+ static fromBytes(bytes: Uint8Array): ValStat<OuterEnclave>;
96
36
  /**
97
37
  * UV + PRF ceremony, then AEAD-seal master. Returns sealed ciphertext + public
98
38
  * meta only — never PRF output. Sealed blob on disk is useless without a
@@ -102,7 +42,7 @@ export declare class Enclave {
102
42
  */
103
43
  sealWithPasskey(opts?: PasskeyPrfOpts): Promise<ValStat<PrfSealedMaster>>;
104
44
  /**
105
- * UV + PRF seal, plus a per-cred bind tag (blake3(master ‖ domain ‖ credId)).
45
+ * UV + PRF seal, plus a per-cred bind tag (bindtag PDK child keyed by credId).
106
46
  * Tag compute and compare stay in the enclave. If `prior` is non-empty, every
107
47
  * stored tag must match this master or bind fails (one keyring, one master).
108
48
  */
@@ -114,23 +54,23 @@ export declare class Enclave {
114
54
  static unsealWithPasskey(bindings: readonly PrfBinding[], opts: PasskeyPrfOpts & {
115
55
  salt: Uint8Array;
116
56
  }): Promise<ValStat<{
117
- enclave: Enclave;
57
+ enclave: OuterEnclave;
118
58
  credId: Uint8Array;
119
59
  }>>;
120
60
  /**
121
61
  * AEAD-seal master under caller-supplied PRF IKM (CLI hmac-secret).
122
62
  * Wipes `ikm` before return. Ciphertext only — never the seed.
123
63
  */
124
- sealWithIkm(ikm: Uint8Array): Promise<ValStat<SealedMasterKey>>;
64
+ sealWithIKM(ikm: Uint8Array): Promise<ValStat<SealedMasterKey>>;
125
65
  /**
126
66
  * Unseal a PRF binding given IKM (CLI hmac-secret eval). Returns Enclave.
127
67
  * Wipes `ikm` before return.
128
68
  */
129
- static unsealWithIkm(sealed: SealedMasterKey, ikm: Uint8Array): Promise<ValStat<Enclave>>;
69
+ static unsealWithIKM(sealed: SealedMasterKey, ikm: Uint8Array): Promise<ValStat<OuterEnclave>>;
130
70
  /**
131
71
  * UV + write IdentityBundle (seed + hosts) to largeBlob.
132
- * Encode and WebAuthn write complete inside this method; nothing seed-bearing
133
- * is returned. Prefer empty `hosts` for seed-only backup.
72
+ * Inner encodes the wire and {@link writeLargeBlob} does the UV write.
73
+ * Nothing seed-bearing is returned. Prefer empty `hosts` for seed-only backup.
134
74
  *
135
75
  * Pass `opts.credId` to write an existing credential (one UV). Omit it to
136
76
  * create a largeBlob-capable credential then write (two UV). Returns the
@@ -149,7 +89,7 @@ export declare class Enclave {
149
89
  static fromLargeBlob(opts?: LargeBlobRp & {
150
90
  credId?: Uint8Array;
151
91
  }): Promise<ValStat<{
152
- enclave: Enclave;
92
+ enclave: OuterEnclave;
153
93
  hosts: BundleHost[];
154
94
  credId: Uint8Array;
155
95
  }>>;
@@ -160,7 +100,7 @@ export declare class Enclave {
160
100
  * Paced mode erases the previous line before the next (Enter between).
161
101
  * Web bundles set DIP_CLI_DUMP=false; the write is compiled out.
162
102
  */
163
- dumpToTty(): Promise<Status>;
103
+ dumpToTTY(): Promise<Status>;
164
104
  static pairRequest(): Promise<ValStat<PairRequest>>;
165
105
  /**
166
106
  * Seals seed+hosts for dhkeReq. Returns dhkeResp to send back.
@@ -186,18 +126,7 @@ export declare class Enclave {
186
126
  id: number;
187
127
  persist?: boolean;
188
128
  }): Worker;
189
- /**
190
- * Cipher for public KDM. Does not hold key bytes; each op re-enters the
191
- * enclave (async, hardware-shaped). `usage` selects the return shape:
192
- * `"encrypt"` → `{ encrypt }`, `"decrypt"` → `{ decrypt }`, `"both"` → both.
193
- */
194
- deriveCipher<U extends CipherUsage>(kdm: Uint8Array, usage: U): CipherForUsage<U>;
195
- /**
196
- * Path-scoped identity (label+index). Private key stays in the enclave; only
197
- * publicKey and capability methods are returned (frozen).
198
- */
199
- deriveIdentity(keyPath: string, idx?: number): Promise<Identity>;
129
+ bagman(idKDM: IKDM, realmKDM: IKDM): Promise<ValStat<BagManager>>;
130
+ fingerprint(kdm?: Uint8Array | IKDM): Promise<ValStat<PDK["Fingerprint"]>>;
200
131
  }
201
- /** Derive seal key from PRF output (domain-separated). Used by enclave seal/unseal. */
202
- export declare function sealKeyFromPrf(crypto: ICrypto, prf: Uint8Array, domain?: Uint8Array): Promise<ValStat<Uint8Array>>;
203
- export { FP_MODE, MASTER_SEED_LEN, MUSEC_MIN_LEN, SEAL_BIND_DOMAIN, SEAL_KEY_LEN, SEAL_PRF_MIN_LEN, };
132
+ export { OuterEnclave as Enclave };
@@ -0,0 +1,8 @@
1
+ import { Status } from "../consts.ts";
2
+ import { type ValStat } from "../valstat.ts";
3
+ import { type LargeBlobCreateOpts, type LargeBlobRp } from "../webauthn/largeBlob.ts";
4
+ export declare function largeBlobCredId(opts?: LargeBlobCreateOpts & {
5
+ credId?: Uint8Array;
6
+ }): Promise<ValStat<Uint8Array>>;
7
+ export declare function writeLargeBlob(credId: Uint8Array, data: Uint8Array, opts?: LargeBlobRp): Promise<Status>;
8
+ export declare function wipeLargeBlob(credId: Uint8Array, opts?: LargeBlobRp): Promise<Status>;
@@ -1,24 +1,17 @@
1
1
  import { type X25519Sk } from "./x25519.ts";
2
2
  import type { Blake3Opts, DerivationSeed, Hash, ICrypto, KeyPair } from "../types.ts";
3
- /**
4
- * ICrypto: noble for XSalsa20 + blake3; WebCrypto Ed25519 + X25519
5
- * (our scalar; RFC 7748 check before trusting pub/DH).
6
- */
7
- export declare class NobleCrypto implements ICrypto {
8
- private verifyKeys;
9
- genRandomBytes(bytes: number): Promise<Uint8Array>;
10
- gen256BitSecureRandomSeed(): Promise<Uint8Array>;
11
- encryptXSalsa20Poly1305Combined(data: Uint8Array, key: Uint8Array): Promise<Uint8Array>;
12
- decryptXSalsa20Poly1305Combined(data: Uint8Array, key: Uint8Array): Promise<Uint8Array>;
13
- deriveEd25519KeyPair(derivationSeed: DerivationSeed): Promise<KeyPair>;
14
- private importSignKey;
15
- private importVerifyKey;
16
- signEd25519(message: Uint8Array | string, secKey: Uint8Array): Promise<Uint8Array>;
17
- checkSigEd25519(sig: Uint8Array, message: Uint8Array | string, pubKey: Uint8Array): Promise<boolean>;
18
- blake3(data: Uint8Array, opts?: Blake3Opts): Promise<Hash>;
19
- genX25519(): Promise<{
20
- priv: X25519Sk;
21
- pub: Uint8Array;
22
- }>;
23
- x25519Shared(priv: X25519Sk, peerPub: Uint8Array): Promise<Uint8Array>;
24
- }
3
+ export declare function genRandomBytes(bytes: number): Promise<Uint8Array>;
4
+ export declare function gen256BitSecureRandomSeed(): Promise<Uint8Array>;
5
+ export declare function encryptXSalsa20Poly1305Combined(data: Uint8Array, key: Uint8Array): Promise<Uint8Array>;
6
+ export declare function decryptXSalsa20Poly1305Combined(data: Uint8Array, key: Uint8Array): Promise<Uint8Array>;
7
+ export declare function deriveEd25519KeyPair(derivationSeed: DerivationSeed): Promise<KeyPair>;
8
+ export declare function importVerifyKey(pubKey: Uint8Array): Promise<CryptoKey>;
9
+ export declare function signEd25519(message: Uint8Array | string, secKey: Uint8Array): Promise<Uint8Array>;
10
+ export declare function checkSigEd25519(sig: Uint8Array, message: Uint8Array | string, verifyKey: CryptoKey): Promise<boolean>;
11
+ export declare function blake3(data: Uint8Array, opts?: Blake3Opts): Promise<Hash>;
12
+ export declare function genX25519(): Promise<{
13
+ priv: X25519Sk;
14
+ pub: Uint8Array;
15
+ }>;
16
+ export declare function x25519Shared(priv: X25519Sk, peerPub: Uint8Array): Promise<Uint8Array>;
17
+ export declare const noble: ICrypto;
@@ -1,6 +1,8 @@
1
+ import type { BundleHost } from "../codecs/bundleHost.ts";
1
2
  import { type ValStat } from "../valstat.ts";
3
+ import { type PDK } from "./derivation.ts";
4
+ import type { Enclave } from "./enclave.ts";
2
5
  import type { X25519Sk } from "./x25519.ts";
3
- export declare const SEAL_PAIR_DOMAIN: Uint8Array<ArrayBufferLike>;
4
6
  export declare const X25519_PUB_LEN = 32;
5
7
  /** respPub (32) ‖ XSalsa nonce (24) ‖ tag (16); plaintext follows in the ct. */
6
8
  export declare const DHKE_RESP_MIN: number;
@@ -17,5 +19,20 @@ export declare function asDHKEResp(bytes: Uint8Array): ValStat<DHKEResp>;
17
19
  export declare function pairKey(sk: X25519Sk, // local X25519 priv
18
20
  peer: Uint8Array, // ECDH peer pub (enroller: dhkeReq; enrollee: respPub)
19
21
  reqPub: Uint8Array, // enrollee pub, bound into KDF
20
- respPub: Uint8Array): Promise<ValStat<Uint8Array>>;
22
+ respPub: Uint8Array): Promise<ValStat<PDK["Pair"]>>;
23
+ export declare function sealPair(dhkeReq: DHKEReq): Promise<ValStat<{
24
+ key: PDK["Pair"];
25
+ pub: Uint8Array;
26
+ }>>;
27
+ export declare class PairRequest {
28
+ #private;
29
+ private constructor();
30
+ static create(): Promise<ValStat<PairRequest>>;
31
+ wipe(): void;
32
+ dhkeReq(): ValStat<DHKEReq>;
33
+ finish(dhkeResp: DHKEResp): Promise<ValStat<{
34
+ enclave: Enclave;
35
+ hosts: BundleHost[];
36
+ }>>;
37
+ }
21
38
  export {};
@@ -0,0 +1,52 @@
1
+ import type { SealedMasterKey } from "../seed.ts";
2
+ import { type ValStat } from "../valstat.ts";
3
+ import { type PDK } from "./derivation.ts";
4
+ import { type PrfCeremony, type PrfCreateOpts, type PrfEvalOpts } from "../webauthn/prf.ts";
5
+ /** Options for PRF seal/unseal ceremonies (no raw PRF bytes). */
6
+ export type PasskeyPrfOpts = PrfCreateOpts & {
7
+ credId?: Uint8Array | readonly Uint8Array[];
8
+ /** Seal only: create a PRF credential first when no credId is known. */
9
+ createCredIfNeeded?: boolean;
10
+ };
11
+ /** One binding to try on unseal (cred id + sealed master). */
12
+ export type PrfBinding = {
13
+ sealedMaster: SealedMasterKey;
14
+ credId: Uint8Array;
15
+ /** PRF salt for this cred. Omitted salts use the ceremony salt. */
16
+ salt?: Uint8Array;
17
+ };
18
+ /** Durable PRF-sealed master + public ceremony facts (never includes PRF output). */
19
+ export type PrfSealedMaster = PrfCeremony & {
20
+ sealedMaster: SealedMasterKey;
21
+ salt: Uint8Array;
22
+ };
23
+ /** One existing keyring member used to prove this enclave matches the list. */
24
+ export type BindPrior = {
25
+ credId: Uint8Array;
26
+ tag: PDK["BindTag"];
27
+ };
28
+ /** Seal + bind-tag from {@link Enclave.bind} (tag is not a global fingerprint). */
29
+ export type PrfBound = PrfSealedMaster & {
30
+ tag: PDK["BindTag"];
31
+ };
32
+ type PrfCreateResult = PrfCeremony & {
33
+ prfEnabled: boolean;
34
+ prf?: Uint8Array;
35
+ };
36
+ type PrfEvalResult = PrfCeremony & {
37
+ prf: Uint8Array;
38
+ };
39
+ export declare function createPrfCred(opts?: PrfCreateOpts): Promise<ValStat<PrfCreateResult>>;
40
+ export declare function evalPrf(opts?: PrfEvalOpts): Promise<ValStat<PrfEvalResult>>;
41
+ export declare function sealPRF(opts: PasskeyPrfOpts | undefined): Promise<ValStat<PrfCeremony & {
42
+ prf: Uint8Array;
43
+ salt: Uint8Array;
44
+ }>>;
45
+ export declare function unsealPRF(bindings: readonly PrfBinding[], opts: PasskeyPrfOpts & {
46
+ salt: Uint8Array;
47
+ }): Promise<ValStat<{
48
+ prf: Uint8Array;
49
+ credId: Uint8Array;
50
+ order: readonly PrfBinding[];
51
+ }>>;
52
+ export {};
@@ -0,0 +1,7 @@
1
+ import { type IKDM } from "../codecs/kdm.ts";
2
+ import { type MasterSeed } from "../seed.ts";
3
+ import { type ValStat } from "../valstat.ts";
4
+ import { type PDK } from "./derivation.ts";
5
+ export declare function deriveRealmKey(parent: MasterSeed, realmKDM: IKDM): Promise<ValStat<PDK["RealmKey"]>>;
6
+ export declare function deriveRealmID(parent: MasterSeed, realmKDM: IKDM): Promise<ValStat<PDK["RealmID"]>>;
7
+ export declare function deriveHostRLM(parent: PDK["RealmID"], hostKDM: IKDM): Promise<ValStat<PDK["HostRLM"]>>;
@@ -2,21 +2,20 @@ import { IClock } from "./clock.ts";
2
2
  import { Decoder, Encoder } from "./codec.ts";
3
3
  import { IAuthTimestamp } from "./codecs/authTimestamp.ts";
4
4
  import { Status } from "./consts.ts";
5
- import { Enclave, type Identity } from "./crypto/enclave.ts";
5
+ import type { BagManager } from "./crypto/bagman.ts";
6
6
  import { ICrypto, IProtoHost } from "./types.ts";
7
7
  import { ValStat } from "./valstat.ts";
8
8
  interface IProtoClient {
9
9
  crypto: ICrypto;
10
- enclave: Enclave;
11
10
  clock: IClock;
12
11
  }
13
- export interface IAuthenticatedEndpoint<ReqItem, Resp> {
14
- encodeReq(client: IProtoClient, identity: Identity, authTS: IAuthTimestamp, body: Iterable<ReqItem>, reqEnc: Encoder): Promise<Status>;
12
+ export interface IAuthenticatedEndpoint<ReqInput, Resp> {
13
+ encodeReq(client: IProtoClient, identity: BagManager, authTS: IAuthTimestamp, body: ReqInput, reqEnc: Encoder): Promise<Status>;
15
14
  handleReq(host: IProtoHost, reqDec: Decoder, respEnc: Encoder): Promise<Status>;
16
15
  decodeResp(respDec: Decoder): ValStat<Resp>;
17
16
  }
18
17
  export interface IAuthData {
19
- identity: Identity;
18
+ identity: BagManager;
20
19
  authTS: IAuthTimestamp;
21
20
  }
22
21
  export {};
@@ -6,66 +6,66 @@ import { ValStat } from "./valstat.ts";
6
6
  export declare const api: {
7
7
  readonly user: {
8
8
  readonly path: "/user";
9
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<never, void>;
9
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<void, void>;
10
10
  readonly name: APICallName.User;
11
11
  };
12
12
  readonly push: {
13
13
  readonly path: "/push";
14
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./types.ts").IBag, import("./codecs/pushItem.ts").IBagPushItem[]>;
14
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./types.ts").IBag[], import("./codecs/pushItem.ts").IBagPushItem[]>;
15
15
  readonly name: APICallName.Push;
16
16
  };
17
17
  readonly peek: {
18
18
  readonly path: "/peek";
19
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<number, import("./codecs/peekItem.ts").IBagPeekItem[]>;
19
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./api/peek.ts").IPeekCursor, import("./codecs/peekItem.ts").IBagPeekItem[]>;
20
20
  readonly name: APICallName.Peek;
21
21
  };
22
22
  readonly pull: {
23
23
  readonly path: "/pull";
24
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<number, import("./codecs/pullItem.ts").IBagPullItem[]>;
24
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./api/pull.ts").IPullReq, import("./codecs/pullItem.ts").IBagPullItem[]>;
25
25
  readonly name: APICallName.Pull;
26
26
  };
27
27
  };
28
28
  export declare const apiCalls: {
29
29
  readonly 0: {
30
30
  readonly path: "/user";
31
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<never, void>;
31
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<void, void>;
32
32
  readonly name: APICallName.User;
33
33
  };
34
34
  readonly 2: {
35
35
  readonly path: "/push";
36
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./types.ts").IBag, import("./codecs/pushItem.ts").IBagPushItem[]>;
36
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./types.ts").IBag[], import("./codecs/pushItem.ts").IBagPushItem[]>;
37
37
  readonly name: APICallName.Push;
38
38
  };
39
39
  readonly 1: {
40
40
  readonly path: "/peek";
41
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<number, import("./codecs/peekItem.ts").IBagPeekItem[]>;
41
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./api/peek.ts").IPeekCursor, import("./codecs/peekItem.ts").IBagPeekItem[]>;
42
42
  readonly name: APICallName.Peek;
43
43
  };
44
44
  readonly 3: {
45
45
  readonly path: "/pull";
46
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<number, import("./codecs/pullItem.ts").IBagPullItem[]>;
46
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./api/pull.ts").IPullReq, import("./codecs/pullItem.ts").IBagPullItem[]>;
47
47
  readonly name: APICallName.Pull;
48
48
  };
49
49
  };
50
50
  export declare const callPaths: {
51
51
  readonly "/user": {
52
52
  readonly path: "/user";
53
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<never, void>;
53
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<void, void>;
54
54
  readonly name: APICallName.User;
55
55
  };
56
56
  readonly "/push": {
57
57
  readonly path: "/push";
58
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./types.ts").IBag, import("./codecs/pushItem.ts").IBagPushItem[]>;
58
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./types.ts").IBag[], import("./codecs/pushItem.ts").IBagPushItem[]>;
59
59
  readonly name: APICallName.Push;
60
60
  };
61
61
  readonly "/peek": {
62
62
  readonly path: "/peek";
63
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<number, import("./codecs/peekItem.ts").IBagPeekItem[]>;
63
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./api/peek.ts").IPeekCursor, import("./codecs/peekItem.ts").IBagPeekItem[]>;
64
64
  readonly name: APICallName.Peek;
65
65
  };
66
66
  readonly "/pull": {
67
67
  readonly path: "/pull";
68
- readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<number, import("./codecs/pullItem.ts").IBagPullItem[]>;
68
+ readonly endpoint: import("./endpoint.ts").IAuthenticatedEndpoint<import("./api/pull.ts").IPullReq, import("./codecs/pullItem.ts").IBagPullItem[]>;
69
69
  readonly name: APICallName.Pull;
70
70
  };
71
71
  };
@@ -1,9 +1,9 @@
1
1
  import { IBagPeekItem } from "./codecs/peekItem.ts";
2
- import { Enclave } from "./crypto/enclave.ts";
3
- import { ICrypto, PublicKey } from "./types.ts";
2
+ import { BagManager } from "./crypto/bagman.ts";
3
+ import { ICrypto } from "./types.ts";
4
4
  import { ValStat } from "./valstat.ts";
5
5
  export interface IDecryptedBagPeekItem {
6
6
  kdm: Uint8Array;
7
7
  headEnc: Uint8Array;
8
8
  }
9
- export declare function decryptPeekItem(item: IBagPeekItem, pubKey: PublicKey, enclave: Enclave, crypto: ICrypto): Promise<ValStat<IDecryptedBagPeekItem>>;
9
+ export declare function decryptPeekItem(item: IBagPeekItem, verifyKey: CryptoKey, bagMgr: BagManager, crypto: ICrypto): Promise<ValStat<IDecryptedBagPeekItem>>;
@@ -4,6 +4,7 @@ import { IAuthTimestamp } from "./codecs/authTimestamp.ts";
4
4
  import type { IBagPeekItem } from "./codecs/peekItem.ts";
5
5
  import { IUsageQuota } from "./codecs/usageQuota.ts";
6
6
  import { APICallName, Status } from "./consts.ts";
7
+ import type { HostRlm } from "./crypto/derivation.ts";
7
8
  import type { ValStat } from "./valstat.ts";
8
9
  /** Identity seed brands — defined in seed.ts; re-exported for convenience. */
9
10
  export type { MasterSeed, SealedMasterKey } from "./seed.ts";
@@ -75,27 +76,35 @@ export type IDeleteParams = {
75
76
  eid: EntityID;
76
77
  force?: boolean;
77
78
  };
79
+ /** One setBags outcome. Success carries the host seq in that bag's rlm. */
80
+ export type ISetBagResult = {
81
+ status: Status.Success;
82
+ seq: number;
83
+ } | {
84
+ status: Exclude<Status, Status.Success>;
85
+ };
78
86
  export interface IStorage {
79
87
  addUser: (pubKey: PublicKey) => Promise<ValStat<void>>;
80
88
  hasUser: (pubKey: PublicKey) => Promise<ValStat<boolean>>;
81
89
  subMeta: (pubKey: PublicKey) => Promise<ValStat<ISubscriptionMetadata>>;
82
90
  /**
83
- * Store bags for a user. Returns host seq for each bag in order.
84
- * Empty list succeeds with []. Implementations must assign contiguous
85
- * seqs atomically (transaction / single batch) so concurrent writers
86
- * cannot claim the same seq.
91
+ * Store bags for a user. One result per input bag, same order.
92
+ * An invalid rlm is InvalidParam for that bag; the others are still stored.
93
+ * Seqs are contiguous per rlm among stored bags, assigned atomically so
94
+ * concurrent writers cannot claim the same seq in the same rlm.
95
+ * Empty list succeeds with []. A storage failure fails the call.
87
96
  */
88
- setBags: (pubKey: PublicKey, bags: IBag[]) => Promise<ValStat<number[]>>;
97
+ setBags: (pubKey: PublicKey, bags: IBag[]) => Promise<ValStat<ISetBagResult[]>>;
89
98
  /**
90
- * Fetch ciphertext bodies for the given host seqs.
91
- * Returns only seqs that exist (missing seqs are omitted, not an error).
92
- * Empty `seqs` succeeds with [].
99
+ * Fetch ciphertext bodies for `seqs` in `rlm`.
100
+ * Missing seqs are omitted. Empty `seqs` succeeds with [].
93
101
  */
94
- getBodies: (pubKey: PublicKey, seqs: number[]) => Promise<ValStat<{
102
+ getBodies: (pubKey: PublicKey, rlm: HostRlm, seqs: number[]) => Promise<ValStat<{
95
103
  seq: number;
96
104
  bodyCph: Uint8Array;
97
105
  }[]>>;
98
- listHeads: (pubKey: PublicKey, minSeq: number) => Promise<ValStat<IBagPeekItem[]>>;
106
+ /** Heads in `rlm` with seq greater than minSeq, ordered by seq. */
107
+ listHeads: (pubKey: PublicKey, rlm: HostRlm, minSeq: number) => Promise<ValStat<IBagPeekItem[]>>;
99
108
  }
100
109
  export interface KeyPair {
101
110
  keyType: "ed25519";
@@ -123,7 +132,8 @@ export type Hash = Uint8Array & {
123
132
  readonly [hashSymbol]: true;
124
133
  };
125
134
  export interface IHostCrypto {
126
- checkSigEd25519: (sig: Uint8Array, message: Uint8Array | string, pubKey: PublicKey) => Promise<boolean>;
135
+ importVerifyKey: (pubKey: PublicKey) => Promise<CryptoKey>;
136
+ checkSigEd25519: (sig: Uint8Array, message: Uint8Array | string, verifyKey: CryptoKey) => Promise<boolean>;
127
137
  }
128
138
  /** BLAKE3 hash / MAC / KDF (noble: `key` XOR `context`, not both). */
129
139
  export type Blake3Opts = {
@@ -141,11 +151,6 @@ export interface ICrypto extends IHostCrypto {
141
151
  signEd25519: (message: Uint8Array | string, secKey: PrivateKey) => Promise<Uint8Array>;
142
152
  blake3: (data: Uint8Array, opts?: Blake3Opts) => Promise<Hash>;
143
153
  }
144
- export interface IMsgpackCodec {
145
- encode: (source: unknown) => Uint8Array;
146
- decode: (packed: ArrayBuffer | Uint8Array) => unknown;
147
- decodeAsync: (stream: ReadableStream<Uint8Array>) => Promise<unknown>;
148
- }
149
154
  export interface IProtoHost {
150
155
  storage: IStorage;
151
156
  crypto: IHostCrypto;
@@ -168,6 +173,9 @@ export interface IPushListener {
168
173
  disconnect(): void;
169
174
  }
170
175
  export interface IBagHeader {
176
+ /** HostRLM. Covered by sig, with headCph. */
177
+ rlm: HostRlm;
178
+ /** Ed25519 over rlm ‖ headCph. First field on the wire. */
171
179
  sig: Uint8Array;
172
180
  kdm: Uint8Array;
173
181
  }
@@ -29,6 +29,14 @@ export type PrfEvalOpts = PrfRp & {
29
29
  /** One id, or every bound id so a spare key can assert in one get(). */
30
30
  credId?: Uint8Array | readonly Uint8Array[];
31
31
  salt?: Uint8Array;
32
+ /**
33
+ * Salt for each cred when accounts do not share one.
34
+ * Sent as evalByCredential so the passkey the user picks evals its own.
35
+ */
36
+ salts?: readonly {
37
+ credId: Uint8Array;
38
+ salt: Uint8Array;
39
+ }[];
32
40
  };
33
41
  /** Best-effort: client advertises PRF extension. */
34
42
  export declare function prfCapable(): Promise<boolean>;