@interncom/diplomatic 0.22.0 → 0.23.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 (84) 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/bag.d.ts +7 -4
  8. package/dist/cli/shared/client.d.ts +10 -4
  9. package/dist/cli/shared/codecs/kdm.d.ts +6 -0
  10. package/dist/cli/shared/codecs/notifItem.d.ts +2 -0
  11. package/dist/cli/shared/crypto/derivation.d.ts +45 -0
  12. package/dist/cli/shared/crypto/enclave.d.ts +30 -66
  13. package/dist/cli/shared/crypto/largeBlob.d.ts +8 -0
  14. package/dist/cli/shared/crypto/noble.d.ts +15 -22
  15. package/dist/cli/shared/crypto/pairing.d.ts +19 -2
  16. package/dist/cli/shared/crypto/prf.d.ts +52 -0
  17. package/dist/cli/shared/crypto/realms.d.ts +7 -0
  18. package/dist/cli/shared/endpoint.d.ts +2 -2
  19. package/dist/cli/shared/http.d.ts +12 -12
  20. package/dist/cli/shared/sync.d.ts +4 -2
  21. package/dist/cli/shared/types.d.ts +24 -11
  22. package/dist/cli/shared/webauthn/prf.d.ts +8 -0
  23. package/dist/cli/src/index.d.ts +5 -4
  24. package/dist/web/client.d.ts +10 -5
  25. package/dist/web/crypto.d.ts +2 -3
  26. package/dist/web/entdb/cached.d.ts +4 -0
  27. package/dist/web/entdb/entdb.d.ts +3 -0
  28. package/dist/web/entdb/idb.d.ts +9 -4
  29. package/dist/web/index.d.ts +10 -5
  30. package/dist/web/index.mjs +1 -1
  31. package/dist/web/passkey/prf-store.d.ts +26 -10
  32. package/dist/web/passkey/seed.d.ts +12 -6
  33. package/dist/web/shared/api/peek.d.ts +9 -1
  34. package/dist/web/shared/api/pull.d.ts +9 -1
  35. package/dist/web/shared/api/push.d.ts +3 -1
  36. package/dist/web/shared/api/user.d.ts +1 -1
  37. package/dist/web/shared/bag.d.ts +7 -4
  38. package/dist/web/shared/client.d.ts +10 -4
  39. package/dist/web/shared/codecs/kdm.d.ts +6 -0
  40. package/dist/web/shared/codecs/notifItem.d.ts +2 -0
  41. package/dist/web/shared/crypto/derivation.d.ts +45 -0
  42. package/dist/web/shared/crypto/enclave.d.ts +30 -66
  43. package/dist/web/shared/crypto/largeBlob.d.ts +8 -0
  44. package/dist/web/shared/crypto/noble.d.ts +15 -22
  45. package/dist/web/shared/crypto/pairing.d.ts +19 -2
  46. package/dist/web/shared/crypto/prf.d.ts +52 -0
  47. package/dist/web/shared/crypto/realms.d.ts +7 -0
  48. package/dist/web/shared/crypto/tty.d.ts +3 -0
  49. package/dist/web/shared/endpoint.d.ts +2 -2
  50. package/dist/web/shared/http.d.ts +12 -12
  51. package/dist/web/shared/storage/memory.d.ts +2 -2
  52. package/dist/web/shared/sync.d.ts +4 -2
  53. package/dist/web/shared/types.d.ts +24 -11
  54. package/dist/web/shared/webauthn/prf.d.ts +8 -0
  55. package/dist/web/stores/cursor.d.ts +30 -0
  56. package/dist/web/stores/idb/account.d.ts +58 -0
  57. package/dist/web/stores/idb/catalog.d.ts +1 -0
  58. package/dist/web/stores/idb/dnlds.d.ts +3 -2
  59. package/dist/web/stores/idb/hosts.d.ts +8 -7
  60. package/dist/web/stores/idb/idbutil.d.ts +2 -0
  61. package/dist/web/stores/idb/migrate.d.ts +2 -0
  62. package/dist/web/stores/idb/msgs.d.ts +1 -1
  63. package/dist/web/stores/idb/names.d.ts +13 -0
  64. package/dist/web/stores/idb/realms.d.ts +11 -0
  65. package/dist/web/stores/idb/store.d.ts +26 -19
  66. package/dist/web/stores/idb/uplds.d.ts +1 -1
  67. package/dist/web/stores/keyTag.d.ts +14 -0
  68. package/dist/web/stores/label.d.ts +3 -0
  69. package/dist/web/stores/memory/account.d.ts +14 -0
  70. package/dist/web/stores/memory/dnlds.d.ts +4 -2
  71. package/dist/web/stores/memory/hosts.d.ts +8 -6
  72. package/dist/web/stores/memory/realms.d.ts +10 -0
  73. package/dist/web/stores/memory/store.d.ts +6 -2
  74. package/dist/web/stores/realm.d.ts +35 -0
  75. package/dist/web/sync.d.ts +14 -11
  76. package/dist/web/types.d.ts +52 -16
  77. package/dist/web/worker/client.d.ts +1 -1
  78. package/dist/web/worker/protocol.d.ts +6 -0
  79. package/dist/web/worker/runtime.d.ts +4 -2
  80. package/dist/web/worker.mjs +1 -1
  81. package/package.json +1 -1
  82. package/dist/web/stores/idb/seed.d.ts +0 -32
  83. package/dist/web/stores/identityPin.d.ts +0 -19
  84. package/dist/web/stores/memory/seed.d.ts +0 -13
@@ -1,7 +1,10 @@
1
- import { Enclave, type PasskeyPrfOpts } from "../shared/crypto/enclave";
1
+ import { Enclave } from "../shared/crypto/enclave";
2
+ import { type PDK } from "../shared/crypto/derivation";
3
+ import type { PasskeyPrfOpts } from "../shared/crypto/prf";
4
+ import { Status } from "../shared/consts";
2
5
  import { type SealedMasterKey } from "../shared/seed";
3
6
  import { type ValStat } from "../shared/valstat";
4
- import type { ISeedStore, SetSeedOpts } from "../types";
7
+ import type { IAccountStore, SetSeedOpts } from "../types";
5
8
  import { type PrfRp } from "../shared/webauthn/prf";
6
9
  import { type AuthenticatorAttachmentName, type EnrolledOs } from "../shared/webauthn/common";
7
10
  /** Max bindings on one device. Keeps allowCredentials small. */
@@ -12,8 +15,8 @@ export type KeyringEntry = {
12
15
  type: "prf";
13
16
  sealedMaster: SealedMasterKey;
14
17
  credId: Uint8Array;
15
- /** blake3(master ‖ bindtag ‖ credId); check-only, not a display fingerprint. */
16
- tag: Uint8Array;
18
+ /** Bind-tag PDK child keyed by credId; check-only, not a display fingerprint. */
19
+ tag: PDK["BindTag"];
17
20
  userId?: Uint8Array;
18
21
  nick?: string;
19
22
  enrolledAt: number;
@@ -45,10 +48,18 @@ export type KeyringRow = {
45
48
  * Persist the keyring for cold start (e.g. protocol IDB).
46
49
  * Called with `undefined` when the store is wiped.
47
50
  */
48
- export type PersistKeyring = (ring: Keyring | undefined) => void | Promise<void>;
51
+ export type PersistKeyring = (ring: Keyring | undefined) => Status | Promise<Status>;
49
52
  export type PrfSeedStoreOpts = PrfRp & {
50
53
  persistKeyring: PersistKeyring;
51
54
  keyring?: Keyring;
55
+ /**
56
+ * When set, unlock runs this instead of the keyring held here.
57
+ * The account store uses it to pick the row by the asserted credId.
58
+ */
59
+ unlockAccount?: () => Promise<ValStat<{
60
+ enclave: Enclave;
61
+ keyring?: Keyring;
62
+ }>>;
52
63
  };
53
64
  /**
54
65
  * Session + durable PRF-bound seed. Session secret is always {@link Enclave}.
@@ -57,13 +68,14 @@ export type PrfSeedStoreOpts = PrfRp & {
57
68
  * - {@link bindAndSave} creates a binding and appends/upserts a keyring entry.
58
69
  * - {@link unlock} runs PRF UV inside Enclave and returns a new enclave.
59
70
  */
60
- export declare class PrfSeedStore implements ISeedStore {
71
+ export declare class PrfSeedStore implements IAccountStore {
61
72
  #private;
62
- constructor(opts: PrfSeedStoreOpts);
73
+ constructor(opts: Omit<PrfSeedStoreOpts, "keyring">);
74
+ static open(opts: PrfSeedStoreOpts): ValStat<PrfSeedStore>;
63
75
  get keyring(): Keyring | undefined;
64
76
  /** Public rows (no sealed master). */
65
77
  list(): KeyringRow[];
66
- save(enclave: Enclave, opts?: SetSeedOpts): Promise<Enclave>;
78
+ save(enclave: Enclave, opts?: SetSeedOpts): Promise<ValStat<Enclave>>;
67
79
  /**
68
80
  * PRF UV inside Enclave.bind, persist the entry.
69
81
  * Always creates a new cred unless `credId` is passed (re-bind that cred).
@@ -73,7 +85,10 @@ export declare class PrfSeedStore implements ISeedStore {
73
85
  nick?: string;
74
86
  }): Promise<ValStat<Enclave>>;
75
87
  load(): Promise<Enclave | void>;
76
- /** Passkey UV inside Enclave → new session enclave. */
88
+ /**
89
+ * Passkey UV inside Enclave → new session enclave.
90
+ * With `unlockAccount`, the asserted credId selects the account.
91
+ */
77
92
  unlock(): Promise<ValStat<Enclave>>;
78
93
  /** Set a display nick (local only; does not update the binding key). */
79
94
  rename(credId: Uint8Array, nick: string): Promise<ValStat<void>>;
@@ -84,11 +99,12 @@ export declare class PrfSeedStore implements ISeedStore {
84
99
  remove(credId: Uint8Array): Promise<ValStat<void>>;
85
100
  wipe(): Promise<void>;
86
101
  }
87
- export declare function cloneKeyring(r: Keyring): Keyring;
102
+ export declare function cloneKeyring(r: Keyring): ValStat<Keyring>;
88
103
  /** Read a keyring from IDB structured-clone output. */
89
104
  export declare function decodeKeyring(raw: unknown): Keyring | undefined;
90
105
  /** Cred ids of every keyring entry. */
91
106
  export declare function keyringCredIds(ring: Keyring | undefined): Uint8Array[];
107
+ export declare function touchKeyring(ring: Keyring, credId: Uint8Array): ValStat<Keyring | undefined>;
92
108
  /** Inferred kind for UI. Not attested. */
93
109
  export declare function keyringKind(row: KeyringRow): string;
94
110
  /** Display label: nick, else inferred kind + short cred id. */
@@ -1,21 +1,27 @@
1
1
  import { Enclave } from "../shared/crypto/enclave";
2
2
  import { type ValStat } from "../shared/valstat";
3
- import type { ISeedStore, SetSeedOpts } from "../types";
3
+ import type { IAccountStore, SetSeedOpts } from "../types";
4
4
  import type { LargeBlobRp } from "../shared/webauthn/largeBlob";
5
5
  export type PasskeySeedStoreOpts = LargeBlobRp & {
6
6
  credId?: Uint8Array;
7
+ /** Account `credId` belongs to. Omitted is the default account, "". */
8
+ label?: string;
7
9
  };
8
10
  /**
9
- * ISeedStore backed by largeBlob. Session secret is always {@link Enclave}.
11
+ * IAccountStore backed by largeBlob. Session secret is always {@link Enclave}.
12
+ * Each account label has its own credential. Omitted label is "".
10
13
  * Persist uses {@link Enclave.persistToLargeBlob} / {@link Enclave.fromLargeBlob}.
11
14
  */
12
- export declare class PasskeySeedStore implements ISeedStore {
15
+ export declare class PasskeySeedStore implements IAccountStore {
13
16
  #private;
14
17
  constructor(opts: PasskeySeedStoreOpts);
18
+ /** Credential id of the selected account. */
15
19
  get credId(): Uint8Array | undefined;
16
- setCredId(credId: Uint8Array | undefined): void;
17
- save(enclave: Enclave, opts?: SetSeedOpts): Promise<Enclave>;
20
+ setCredId(credId: Uint8Array | undefined, label?: string): void;
21
+ save(enclave: Enclave, opts?: SetSeedOpts): Promise<ValStat<Enclave>>;
18
22
  load(): Promise<Enclave | void>;
19
- unlock(): Promise<ValStat<Enclave>>;
23
+ unlock(opts?: {
24
+ label?: string;
25
+ }): Promise<ValStat<Enclave>>;
20
26
  wipe(): Promise<void>;
21
27
  }
@@ -1,3 +1,11 @@
1
+ import { ICodecStruct } from "../codec.ts";
1
2
  import { IAuthenticatedEndpoint } from "../endpoint.ts";
2
3
  import { IBagPeekItem } from "../codecs/peekItem.ts";
3
- export declare const peekEnd: IAuthenticatedEndpoint<number, IBagPeekItem[]>;
4
+ import { type HostRlm } from "../crypto/derivation.ts";
5
+ /** One realm cursor: that rlm, and the last seq the client has in it. */
6
+ export interface IPeekCursor {
7
+ rlm: HostRlm;
8
+ seq: number;
9
+ }
10
+ export declare const peekCursorCodec: ICodecStruct<IPeekCursor>;
11
+ export declare const peekEnd: IAuthenticatedEndpoint<IPeekCursor, IBagPeekItem[]>;
@@ -1,3 +1,11 @@
1
+ import { ICodecStruct } from "../codec.ts";
1
2
  import { type IBagPullItem } from "../codecs/pullItem.ts";
3
+ import { type HostRlm } from "../crypto/derivation.ts";
2
4
  import { IAuthenticatedEndpoint } from "../endpoint.ts";
3
- export declare const pullEnd: IAuthenticatedEndpoint<number, IBagPullItem[]>;
5
+ /** One realm, and the seqs to fetch in it. */
6
+ export interface IPullReq {
7
+ rlm: HostRlm;
8
+ seqs: number[];
9
+ }
10
+ export declare const pullReqCodec: ICodecStruct<IPullReq>;
11
+ export declare const pullEnd: IAuthenticatedEndpoint<IPullReq, IBagPullItem[]>;
@@ -1,4 +1,6 @@
1
+ import { ICodecStruct } from "../codec.ts";
1
2
  import { type IBagPushItem } from "../codecs/pushItem.ts";
2
3
  import { IAuthenticatedEndpoint } from "../endpoint.ts";
3
4
  import { IBag } from "../types.ts";
4
- export declare const pushEnd: IAuthenticatedEndpoint<IBag, IBagPushItem[]>;
5
+ export declare const pushReqCodec: ICodecStruct<IBag[]>;
6
+ export declare const pushEnd: IAuthenticatedEndpoint<IBag[], IBagPushItem[]>;
@@ -1,2 +1,2 @@
1
1
  import { IAuthenticatedEndpoint } from "../endpoint.ts";
2
- export declare const userEnd: IAuthenticatedEndpoint<never, void>;
2
+ export declare const userEnd: IAuthenticatedEndpoint<void, void>;
@@ -1,10 +1,13 @@
1
+ import type { IKDM } from "./codecs/kdm.ts";
1
2
  import { IMessageHead } from "./codecs/messageHead.ts";
3
+ import type { HostRlm } from "./crypto/derivation.ts";
2
4
  import { type DecryptCipher, Enclave, type Identity } from "./crypto/enclave.ts";
3
5
  import { EncodedMessage } from "./message.ts";
4
6
  import { type ValStat } from "./valstat.ts";
5
- import type { Hash, IBag, ICrypto, IHostCrypto, IMessage, IMessageWithHash, PublicKey } from "./types.ts";
6
- export declare function bagSigValid(bag: IBag, pubKey: PublicKey, crypto: IHostCrypto): Promise<boolean>;
7
- export declare function sealBag(msg: IMessage, identity: Identity, crypto: ICrypto, enclave: Enclave): Promise<ValStat<IBag>>;
7
+ import type { Hash, IBag, ICrypto, IHostCrypto, IMessage, IMessageWithHash } from "./types.ts";
8
+ export declare function bagSigMsg(rlm: HostRlm, headCph: Uint8Array): Uint8Array;
9
+ export declare function bagSigValid(bag: IBag, verifyKey: CryptoKey, crypto: IHostCrypto): Promise<boolean>;
10
+ export declare function sealBag(msg: IMessage, identity: Identity, crypto: ICrypto, enclave: Enclave, hostKDM?: IKDM, realmKDM?: IKDM): Promise<ValStat<IBag>>;
8
11
  export interface IOpenBag {
9
12
  msgHead: IMessageHead;
10
13
  bod?: EncodedMessage;
@@ -13,4 +16,4 @@ export interface IOpenBag {
13
16
  export declare function openBagBody(headEnc: Uint8Array, bodyCph: Uint8Array | undefined, cipher: DecryptCipher, crypto: ICrypto,
14
17
  /** When set (e.g. from peek), skip blake3(headEnc). */
15
18
  headHashKnown?: Hash): Promise<ValStat<IOpenBag>>;
16
- export declare function openBag(bag: IBag, pubKey: PublicKey, crypto: ICrypto, enclave: Enclave): Promise<ValStat<IMessageWithHash>>;
19
+ export declare function openBag(bag: IBag, verifyKey: CryptoKey, crypto: ICrypto, enclave: Enclave, hostKDM?: IKDM, realms?: readonly IKDM[]): Promise<ValStat<IMessageWithHash>>;
@@ -1,9 +1,14 @@
1
1
  import { IClock } from "./clock.ts";
2
+ import type { IKDM } from "./codecs/kdm.ts";
3
+ import type { IBagPeekItem } from "./codecs/peekItem.ts";
4
+ import type { IBagPullItem } from "./codecs/pullItem.ts";
2
5
  import { Status } from "./consts.ts";
3
6
  import { Enclave, type Identity } from "./crypto/enclave.ts";
7
+ import { type HostRlm } from "./crypto/derivation.ts";
4
8
  import type { HostHandle, IBag, ICrypto, IHostConnectionInfo, IHostMetadata, IMessage, ITransport, PushReceiver } from "./types.ts";
5
9
  import { ValStat } from "./valstat.ts";
6
10
  export default class DiplomaticClientAPI<Handle extends HostHandle> {
11
+ #private;
7
12
  enclave: Enclave;
8
13
  crypto: ICrypto;
9
14
  private host;
@@ -12,12 +17,13 @@ export default class DiplomaticClientAPI<Handle extends HostHandle> {
12
17
  private updateHostMeta;
13
18
  constructor(enclave: Enclave, crypto: ICrypto, host: IHostConnectionInfo<Handle>, clock: IClock, transport: ITransport, updateHostMeta: (meta: IHostMetadata) => Promise<Status>);
14
19
  private call;
15
- identity: () => Promise<Identity>;
16
- seal: (msg: IMessage) => Promise<ValStat<IBag>>;
20
+ identity: () => Promise<ValStat<Identity>>;
21
+ hostRlm: (realm?: IKDM) => Promise<ValStat<HostRlm>>;
22
+ seal: (msg: IMessage, realm?: IKDM) => Promise<ValStat<IBag>>;
17
23
  register: () => Promise<ValStat<void>>;
18
- peek: (lastSeq: number) => Promise<ValStat<import("./codecs/peekItem.ts").IBagPeekItem[]>>;
24
+ peek: (lastSeq: number, realm?: IKDM) => Promise<ValStat<IBagPeekItem[]>>;
19
25
  push: (bags: IBag[]) => Promise<ValStat<import("./codecs/pushItem.ts").IBagPushItem[]>>;
20
- pull: (seqs: number[]) => Promise<ValStat<import("./codecs/pullItem.ts").IBagPullItem[]>>;
26
+ pull: (seqs: number[], realm?: IKDM) => Promise<ValStat<IBagPullItem[]>>;
21
27
  listen: (recv: PushReceiver, onDisconnect?: () => void, onConnect?: () => void) => Promise<Status>;
22
28
  /** Returns whether this client has an active connection to its host.
23
29
  * If a push listener is active, reports the listener's connected state.
@@ -0,0 +1,6 @@
1
+ import { ICodecStruct } from "../codec.ts";
2
+ export interface IKDM {
3
+ label: string;
4
+ index: number;
5
+ }
6
+ export declare const kdmCodec: ICodecStruct<IKDM>;
@@ -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,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,43 +1,18 @@
1
1
  import type { BundleHost } from "../codecs/bundleHost.ts";
2
+ import type { IKDM } from "../codecs/kdm.ts";
2
3
  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";
4
+ import { type MasterSeed, type SealedMasterKey } from "../seed.ts";
5
+ import type { PublicKey } from "../types.ts";
5
6
  import { type ValStat } from "../valstat.ts";
6
- import { type DHKEReq, type DHKEResp } from "./pairing.ts";
7
+ import { type HostRlm, type PDK } from "./derivation.ts";
8
+ import { type DHKEReq, type DHKEResp, PairRequest } from "./pairing.ts";
7
9
  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
- };
10
+ import { type BindPrior, type PasskeyPrfOpts, type PrfBinding, type PrfBound, type PrfSealedMaster } from "./prf.ts";
36
11
  export type EncryptCipher = {
37
- encrypt: (data: Uint8Array) => Promise<Uint8Array>;
12
+ encrypt: (data: Uint8Array) => Promise<ValStat<Uint8Array>>;
38
13
  };
39
14
  export type DecryptCipher = {
40
- decrypt: (data: Uint8Array) => Promise<Uint8Array>;
15
+ decrypt: (data: Uint8Array) => Promise<ValStat<Uint8Array>>;
41
16
  };
42
17
  /** Encrypt + decrypt capability for one KDM. */
43
18
  export type DerivedCipher = EncryptCipher & DecryptCipher;
@@ -50,33 +25,21 @@ export type CipherForUsage<U extends CipherUsage> = {
50
25
  both: DerivedCipher;
51
26
  }[U];
52
27
  /**
53
- * Path-scoped signing identity: public key is public; sign/kdmFor re-enter
28
+ * KDM-scoped signing identity: public key is public; sign/kdmFor re-enter
54
29
  * the enclave so the private key never leaves. Used for hosts, export files, etc.
55
30
  */
56
31
  export type Identity = {
57
32
  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>;
33
+ sign: (message: Uint8Array | string) => Promise<ValStat<Uint8Array>>;
34
+ /** Per-bag 8-byte KDM (bag-kdm PDK child keyed by the encoded head). */
35
+ kdmFor: (msgHeadEnc: Uint8Array) => Promise<ValStat<Uint8Array>>;
61
36
  };
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;
66
37
  /** 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 };
38
+ export declare const MUSEC_MIN_LEN = 32;
39
+ export declare function fromSeedHosts(buf: Uint8Array): ValStat<{
40
+ enclave: Enclave;
41
+ hosts: BundleHost[];
42
+ }>;
80
43
  /** Brand `bytes` as {@link MasterSeed} only if length is {@link MASTER_SEED_LEN}. */
81
44
  export declare function asMasterSeed(bytes: Uint8Array): ValStat<MasterSeed>;
82
45
  export declare class Enclave {
@@ -102,7 +65,7 @@ export declare class Enclave {
102
65
  */
103
66
  sealWithPasskey(opts?: PasskeyPrfOpts): Promise<ValStat<PrfSealedMaster>>;
104
67
  /**
105
- * UV + PRF seal, plus a per-cred bind tag (blake3(master ‖ domain ‖ credId)).
68
+ * UV + PRF seal, plus a per-cred bind tag (bindtag PDK child keyed by credId).
106
69
  * Tag compute and compare stay in the enclave. If `prior` is non-empty, every
107
70
  * stored tag must match this master or bind fails (one keyring, one master).
108
71
  */
@@ -129,8 +92,8 @@ export declare class Enclave {
129
92
  static unsealWithIkm(sealed: SealedMasterKey, ikm: Uint8Array): Promise<ValStat<Enclave>>;
130
93
  /**
131
94
  * 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.
95
+ * Encode stays here; {@link writeLargeBlob} does the UV write. Nothing
96
+ * seed-bearing is returned. Prefer empty `hosts` for seed-only backup.
134
97
  *
135
98
  * Pass `opts.credId` to write an existing credential (one UV). Omit it to
136
99
  * create a largeBlob-capable credential then write (two UV). Returns the
@@ -186,18 +149,19 @@ export declare class Enclave {
186
149
  id: number;
187
150
  persist?: boolean;
188
151
  }): Worker;
152
+ realmID(realmKDM: IKDM): Promise<ValStat<PDK["RealmID"]>>;
153
+ hostRlm(realmKDM: IKDM, hostKDM: IKDM): Promise<ValStat<PDK["HostRLM"]>>;
154
+ realmForRlm(hostKDM: IKDM, rlm: HostRlm, realms: readonly IKDM[]): Promise<ValStat<IKDM>>;
189
155
  /**
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:
156
+ * Cipher for public KDM under a realm (default: nullKDM). Does not hold
157
+ * key bytes; each op re-enters the enclave. `usage` selects the shape:
192
158
  * `"encrypt"` → `{ encrypt }`, `"decrypt"` → `{ decrypt }`, `"both"` → both.
193
159
  */
194
- deriveCipher<U extends CipherUsage>(kdm: Uint8Array, usage: U): CipherForUsage<U>;
160
+ deriveCipher<U extends CipherUsage>(kdm: Uint8Array, usage: U, realmKDM?: IKDM): CipherForUsage<U>;
195
161
  /**
196
- * Path-scoped identity (label+index). Private key stays in the enclave; only
197
- * publicKey and capability methods are returned (frozen).
162
+ * Identity from the identity PDK + KDM. Private key stays in the enclave;
163
+ * only publicKey and capability methods are returned.
198
164
  */
199
- deriveIdentity(keyPath: string, idx?: number): Promise<Identity>;
165
+ deriveIdentity(kdm: IKDM): Promise<ValStat<Identity>>;
166
+ fingerprint(kdm?: Uint8Array | IKDM): Promise<ValStat<PDK["Fingerprint"]>>;
200
167
  }
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, };
@@ -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"]>>;
@@ -0,0 +1,3 @@
1
+ import { Status } from "../consts.ts";
2
+ import { type ValStat } from "../valstat.ts";
3
+ export declare function dumpToTty(seed: Uint8Array, fingerprint: () => Promise<ValStat<Uint8Array>>): Promise<Status>;
@@ -10,8 +10,8 @@ interface IProtoClient {
10
10
  enclave: Enclave;
11
11
  clock: IClock;
12
12
  }
13
- export interface IAuthenticatedEndpoint<ReqItem, Resp> {
14
- encodeReq(client: IProtoClient, identity: Identity, authTS: IAuthTimestamp, body: Iterable<ReqItem>, reqEnc: Encoder): Promise<Status>;
13
+ export interface IAuthenticatedEndpoint<ReqInput, Resp> {
14
+ encodeReq(client: IProtoClient, identity: Identity, authTS: IAuthTimestamp, body: ReqInput, reqEnc: Encoder): Promise<Status>;
15
15
  handleReq(host: IProtoHost, reqDec: Decoder, respEnc: Encoder): Promise<Status>;
16
16
  decodeResp(respDec: Decoder): ValStat<Resp>;
17
17
  }