@interncom/diplomatic 0.12.9 → 0.13.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.
@@ -1,6 +1,5 @@
1
1
  import { Enclave } from "../shared/crypto/enclave";
2
2
  import { type SealedMasterKey } from "../shared/seed";
3
- import type { ICrypto } from "../shared/types";
4
3
  import { type ValStat } from "../shared/valstat";
5
4
  import type { ISeedStore, SetSeedOpts } from "../types";
6
5
  import type { PrfRp } from "../shared/webauthn/prf";
@@ -21,7 +20,6 @@ export type PrfSeedMeta = {
21
20
  */
22
21
  export type PersistPrfSeedMeta = (meta: PrfSeedMeta | undefined) => void | Promise<void>;
23
22
  export type PrfSeedStoreOpts = PrfRp & {
24
- crypto: ICrypto;
25
23
  /**
26
24
  * Required durable write path for sealed master + salt + credId.
27
25
  * Protocol IDB implements this via {@link IDBSeedStore.persistPrfMeta}.
@@ -1,12 +1,10 @@
1
1
  import { Enclave } from "../shared/crypto/enclave";
2
- import type { ICrypto } from "../shared/types";
3
2
  import { type ValStat } from "../shared/valstat";
4
3
  import type { ISeedStore, SetSeedOpts } from "../types";
5
4
  import { type LargeBlobRp } from "./largeBlob";
6
5
  export { defaultWebAuthnRpId } from "./webauthn";
7
6
  export { LargeBlob, type LargeBlobCreateOpts, type LargeBlobRp, } from "./largeBlob";
8
7
  export type PasskeySeedStoreOpts = LargeBlobRp & {
9
- crypto: ICrypto;
10
8
  credId?: Uint8Array;
11
9
  };
12
10
  /**
@@ -40,6 +40,7 @@ export declare class Encoder {
40
40
  writeStructs<T>(codec: ICodecStruct<T>, structs: Iterable<T>): Status;
41
41
  writeBytesSeq(bytesSeq: Iterable<Uint8Array>): void;
42
42
  result(): Uint8Array;
43
+ wipe(): void;
43
44
  scan(): Generator<Uint8Array>;
44
45
  }
45
46
  export interface ICodecStruct<T> {
@@ -6,8 +6,7 @@ export type PairPackagePlain = {
6
6
  hosts: BundleHost[];
7
7
  };
8
8
  /**
9
- * Inner plaintext body (not sealed here — AEAD is applied by the pairing
10
- * ceremony, then carried as `body` in {@link pairPackageEnvelopeCodec}):
9
+ * Inner plaintext (AEAD is applied by QR pairing: X25519 + blake3 + XSalsa20):
11
10
  * masterSeed: 32 fixed bytes
12
11
  * hostsLen: varint
13
12
  * hosts: hostsLen × BundleHost
@@ -39,7 +39,8 @@ export declare enum Status {
39
39
  CommunicationError = 25,
40
40
  VarLimitExceeded = 26,
41
41
  InvalidResponse = 27,
42
- ConnectionClosed = 28
42
+ ConnectionClosed = 28,
43
+ CryptoError = 29
43
44
  }
44
45
  export declare enum APICallName {
45
46
  User = 0,
@@ -3,6 +3,7 @@ import { Status } from "../consts.ts";
3
3
  import { MASTER_SEED_LEN, type SealedMasterKey } from "../seed.ts";
4
4
  import type { ICrypto, PublicKey } from "../types.ts";
5
5
  import { type ValStat } from "../valstat.ts";
6
+ import { type DHKEReq, type DHKEResp, PairRequest } from "./pairing.ts";
6
7
  import { type LargeBlobCreateOpts, type LargeBlobRp } from "../webauthn/largeBlob.ts";
7
8
  import { type PrfCreateOpts, type PrfEvalOpts, type PrfRp } from "../webauthn/prf.ts";
8
9
  export type { LargeBlobCreateOpts, LargeBlobRp };
@@ -48,20 +49,19 @@ export type Identity = {
48
49
  kdmFor: (msgHeadEnc: Uint8Array) => Promise<Uint8Array>;
49
50
  };
50
51
  declare const SEAL_WRAP_DOMAIN: Uint8Array<ArrayBufferLike>;
51
- declare const SEAL_PAIR_DOMAIN: Uint8Array<ArrayBufferLike>;
52
52
  declare const SEAL_KEY_LEN = 32;
53
53
  declare const SEAL_PRF_MIN_LEN = 16;
54
54
  export declare class Enclave {
55
55
  #private;
56
56
  private constructor();
57
57
  /** New enclave with a fresh 32-byte master seed. */
58
- static fromRandom(crypto: ICrypto): Promise<Enclave>;
58
+ static fromRandom(): Promise<Enclave>;
59
59
  /**
60
60
  * Construct from raw master seed bytes (import / bootstrap only).
61
61
  * Copies the seed so callers may zero their buffer after success.
62
62
  * Prefer {@link fromRandom} or {@link unsealWithPasskey} for normal flows.
63
63
  */
64
- static fromBytes(crypto: ICrypto, bytes: Uint8Array): ValStat<Enclave>;
64
+ static fromBytes(bytes: Uint8Array): ValStat<Enclave>;
65
65
  /**
66
66
  * UV + PRF ceremony, then AEAD-seal master. Returns sealed ciphertext + public
67
67
  * meta only — never PRF output. Sealed blob on disk is useless without a
@@ -75,7 +75,7 @@ export declare class Enclave {
75
75
  * Callers never supply PRF bytes — only sealed meta + RP/salt/credId.
76
76
  * Returns the credential id used so stores can persist it (skip picker next time).
77
77
  */
78
- static unsealWithPasskey(crypto: ICrypto, sealedMaster: SealedMasterKey, opts: PasskeyPrfOpts & {
78
+ static unsealWithPasskey(sealedMaster: SealedMasterKey, opts: PasskeyPrfOpts & {
79
79
  salt: Uint8Array;
80
80
  }): Promise<ValStat<{
81
81
  enclave: Enclave;
@@ -100,7 +100,7 @@ export declare class Enclave {
100
100
  * Pass `opts.credId` for a known credential; omit for discoverable assertion.
101
101
  * Returns the credential id used (useful after discover).
102
102
  */
103
- static fromLargeBlob(crypto: ICrypto, opts?: LargeBlobRp & {
103
+ static fromLargeBlob(opts?: LargeBlobRp & {
104
104
  credId?: Uint8Array;
105
105
  }): Promise<ValStat<{
106
106
  enclave: Enclave;
@@ -109,27 +109,8 @@ export declare class Enclave {
109
109
  }>>;
110
110
  /** UV + overwrite largeBlob with zeros (destroys stored seed material). */
111
111
  static clearLargeBlob(credId: Uint8Array, opts?: LargeBlobRp): Promise<Status>;
112
- /**
113
- * UV + PRF, then AEAD-seal pair-package plaintext (seed + hosts).
114
- * Returns ciphertext body + public ceremony meta (no PRF).
115
- */
116
- sealPairPackageBody(hosts: BundleHost[], opts?: PasskeyPrfOpts): Promise<ValStat<{
117
- body: Uint8Array;
118
- salt: Uint8Array;
119
- credId: Uint8Array;
120
- }>>;
121
- /**
122
- * UV + PRF (using envelope salt/credId), decrypt pair body, build Enclave.
123
- * Also seals master under the same PRF for durable IDB (single ceremony).
124
- */
125
- static openPairPackageBody(crypto: ICrypto, body: Uint8Array, opts: PasskeyPrfOpts & {
126
- salt: Uint8Array;
127
- }): Promise<ValStat<{
128
- enclave: Enclave;
129
- hosts: BundleHost[];
130
- sealedMaster: SealedMasterKey;
131
- credId: Uint8Array;
132
- }>>;
112
+ static pairRequest(): Promise<ValStat<PairRequest>>;
113
+ pairAccept(dhkeReq: DHKEReq, hosts: BundleHost[]): Promise<ValStat<DHKEResp>>;
133
114
  /**
134
115
  * Spawn a new sync Worker from the embedded bundle and inject this enclave's
135
116
  * master seed into it (transfer). Seed never goes to a caller-supplied port —
@@ -156,4 +137,4 @@ export declare class Enclave {
156
137
  }
157
138
  /** Derive seal key from PRF output (domain-separated). Used by enclave seal/unseal. */
158
139
  export declare function sealKeyFromPrf(crypto: ICrypto, prf: Uint8Array, domain?: Uint8Array): Promise<ValStat<Uint8Array>>;
159
- export { MASTER_SEED_LEN, SEAL_KEY_LEN, SEAL_PAIR_DOMAIN, SEAL_PRF_MIN_LEN, SEAL_WRAP_DOMAIN, };
140
+ export { MASTER_SEED_LEN, SEAL_KEY_LEN, SEAL_PRF_MIN_LEN, SEAL_WRAP_DOMAIN };
@@ -1,6 +1,8 @@
1
+ import { type X25519Sk } from "./x25519.ts";
1
2
  import type { DerivationSeed, Hash, ICrypto, KeyPair } from "../types.ts";
2
3
  /**
3
- * ICrypto: noble for XSalsa20 + blake3; native WebCrypto for all Ed25519.
4
+ * ICrypto: noble for XSalsa20 + blake3; WebCrypto Ed25519 + X25519
5
+ * (our scalar; RFC 7748 check before trusting pub/DH).
4
6
  */
5
7
  export declare class NobleCrypto implements ICrypto {
6
8
  private verifyKeys;
@@ -14,4 +16,9 @@ export declare class NobleCrypto implements ICrypto {
14
16
  signEd25519(message: Uint8Array | string, secKey: Uint8Array): Promise<Uint8Array>;
15
17
  checkSigEd25519(sig: Uint8Array, message: Uint8Array | string, pubKey: Uint8Array): Promise<boolean>;
16
18
  blake3(data: Uint8Array): Promise<Hash>;
19
+ genX25519(): Promise<{
20
+ priv: X25519Sk;
21
+ pub: Uint8Array;
22
+ }>;
23
+ x25519Shared(priv: X25519Sk, peerPub: Uint8Array): Promise<Uint8Array>;
17
24
  }
@@ -0,0 +1,34 @@
1
+ import type { BundleHost } from "../codecs/bundleHost.ts";
2
+ import { type ValStat } from "../valstat.ts";
3
+ import { Enclave } from "./enclave.ts";
4
+ import type { X25519Sk } from "./x25519.ts";
5
+ export declare const SEAL_PAIR_DOMAIN: Uint8Array<ArrayBufferLike>;
6
+ export declare const X25519_PUB_LEN = 32;
7
+ /** respPub (32) ‖ XSalsa nonce (24) ‖ tag (16); plaintext follows in the ct. */
8
+ export declare const DHKE_RESP_MIN: number;
9
+ declare const dhkeReqSymbol: unique symbol;
10
+ declare const dhkeRespSymbol: unique symbol;
11
+ export type DHKEReq = Uint8Array & {
12
+ readonly [dhkeReqSymbol]: true;
13
+ };
14
+ export type DHKEResp = Uint8Array & {
15
+ readonly [dhkeRespSymbol]: true;
16
+ };
17
+ export declare function asDHKEReq(bytes: Uint8Array): ValStat<DHKEReq>;
18
+ export declare function asDHKEResp(bytes: Uint8Array): ValStat<DHKEResp>;
19
+ export declare function pairKey(sk: X25519Sk, // local X25519 priv
20
+ peer: Uint8Array, // ECDH peer pub (enroller: dhkeReq; enrollee: respPub)
21
+ reqPub: Uint8Array, // enrollee pub, bound into KDF
22
+ respPub: Uint8Array): Promise<ValStat<Uint8Array>>;
23
+ export declare class PairRequest {
24
+ #private;
25
+ private constructor();
26
+ static create(): Promise<ValStat<PairRequest>>;
27
+ wipe(): void;
28
+ get dhkeReq(): DHKEReq;
29
+ finish(dhkeResp: DHKEResp): Promise<ValStat<{
30
+ enclave: Enclave;
31
+ hosts: BundleHost[];
32
+ }>>;
33
+ }
34
+ export {};
@@ -0,0 +1,10 @@
1
+ import { type ValStat } from "../valstat.ts";
2
+ export declare const X25519_SK_LEN = 32;
3
+ declare const x25519SkSymbol: unique symbol;
4
+ export type X25519Sk = Uint8Array & {
5
+ readonly [x25519SkSymbol]: true;
6
+ };
7
+ export declare function asX25519Sk(bytes: Uint8Array): ValStat<X25519Sk>;
8
+ export declare function x25519(sk: X25519Sk, u: Uint8Array): Uint8Array;
9
+ export declare function x25519Pub(sk: X25519Sk): Uint8Array;
10
+ export {};
@@ -30,7 +30,5 @@ export declare class IDBSeedStore implements ISeedStore {
30
30
  hasPrfMeta(): Promise<boolean>;
31
31
  /** Last PRF passkey id, if this device has a sealed PRF identity. */
32
32
  lastPrfCredId(): Promise<Uint8Array | undefined>;
33
- openPrfStore(opts: Omit<PrfSeedStoreOpts, "crypto" | "persistMeta" | "meta"> & {
34
- crypto?: ICrypto;
35
- }): Promise<PrfSeedStore>;
33
+ openPrfStore(opts: Omit<PrfSeedStoreOpts, "persistMeta" | "meta">): Promise<PrfSeedStore>;
36
34
  }