raz-encrypt 2.1.0 → 2.3.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 (49) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +448 -442
  3. package/dist/canonicalJson.d.ts +0 -15
  4. package/dist/canonicalJson.js +13 -73
  5. package/dist/canonicalJson.js.map +1 -1
  6. package/dist/core.d.ts +2 -4
  7. package/dist/core.js +1 -3
  8. package/dist/core.js.map +1 -1
  9. package/dist/crypto/classical.d.ts +0 -2
  10. package/dist/crypto/classical.js +0 -4
  11. package/dist/crypto/classical.js.map +1 -1
  12. package/dist/crypto/frameCipher.js +2 -8
  13. package/dist/crypto/frameCipher.js.map +1 -1
  14. package/dist/crypto/hybrid.d.ts +8 -95
  15. package/dist/crypto/hybrid.js +49 -374
  16. package/dist/crypto/hybrid.js.map +1 -1
  17. package/dist/crypto/nodeHybrid.d.ts +4 -6
  18. package/dist/crypto/nodeHybrid.js +2 -3
  19. package/dist/crypto/nodeHybrid.js.map +1 -1
  20. package/dist/crypto/pqc.d.ts +2 -7
  21. package/dist/crypto/pqc.js +4 -13
  22. package/dist/crypto/pqc.js.map +1 -1
  23. package/dist/crypto/ratchet.js +0 -5
  24. package/dist/crypto/ratchet.js.map +1 -1
  25. package/dist/fileCrypto.d.ts +2 -44
  26. package/dist/fileCrypto.js +28 -197
  27. package/dist/fileCrypto.js.map +1 -1
  28. package/dist/identity.d.ts +4 -69
  29. package/dist/identity.js +12 -111
  30. package/dist/identity.js.map +1 -1
  31. package/dist/index.d.ts +7 -8
  32. package/dist/index.js +4 -4
  33. package/dist/index.js.map +1 -1
  34. package/dist/store.d.ts +5 -42
  35. package/dist/store.js +22 -254
  36. package/dist/store.js.map +1 -1
  37. package/dist/trust.d.ts +2 -143
  38. package/dist/trust.js +27 -376
  39. package/dist/trust.js.map +1 -1
  40. package/package.json +69 -62
  41. package/dist/crypto/confirmedSession.d.ts +0 -47
  42. package/dist/crypto/confirmedSession.js +0 -84
  43. package/dist/crypto/confirmedSession.js.map +0 -1
  44. package/dist/crypto/frameSession.d.ts +0 -40
  45. package/dist/crypto/frameSession.js +0 -96
  46. package/dist/crypto/frameSession.js.map +0 -1
  47. package/dist/passphrase.d.ts +0 -27
  48. package/dist/passphrase.js +0 -69
  49. package/dist/passphrase.js.map +0 -1
@@ -10,9 +10,9 @@
10
10
  * resolvable by a browser bundler with no node:fs in its module graph.
11
11
  */
12
12
  import type { Identity, PublicCard } from "../identity.js";
13
- import { type DecryptDeps, type Certificate, type EncryptedBox, type SignOptions, type VerifyResult } from "./hybrid.js";
14
- export { DecryptionError, ReplayedBoxError, UntrustedPartyError } from "./hybrid.js";
15
- export type { BoxReplayInfo, Certificate, EncryptedBox, SignOptions, VerifyFailureReason, VerifyResult } from "./hybrid.js";
13
+ import { type Certificate, type EncryptedBox, type SignOptions, type VerifyResult } from "./hybrid.js";
14
+ export { UntrustedPartyError } from "./hybrid.js";
15
+ export type { Certificate, EncryptedBox, SignOptions, VerifyFailureReason, VerifyResult } from "./hybrid.js";
16
16
  /**
17
17
  * Signs `document` with both the classical (ECDSA-P384) and post-quantum
18
18
  * (ML-DSA-87) keys. Permanent by default; pass `options.expiresAt` to make
@@ -39,6 +39,4 @@ export declare function encryptFor(identity: Identity, counterpart: PublicCard,
39
39
  * in `identity`'s local trust list — this stops a caller from accidentally
40
40
  * decrypting "as if" a message came from someone they never actually trusted.
41
41
  */
42
- export declare function decryptFrom<T = unknown>(identity: Identity, counterpart: PublicCard, box: EncryptedBox, options?: {
43
- isReplay?: DecryptDeps["isReplay"];
44
- }): Promise<T>;
42
+ export declare function decryptFrom<T = unknown>(identity: Identity, counterpart: PublicCard, box: EncryptedBox): Promise<T>;
@@ -1,7 +1,7 @@
1
1
  import { appendLogEntry } from "../store.js";
2
2
  import { getTrustRecordsByAlias, getTrustedPartiesByAlias } from "../trust.js";
3
3
  import { decryptFromCore, encryptForCore, signCore, verifyCore, } from "./hybrid.js";
4
- export { DecryptionError, ReplayedBoxError, UntrustedPartyError } from "./hybrid.js";
4
+ export { UntrustedPartyError } from "./hybrid.js";
5
5
  async function trustStatusForSigner(identity, signer) {
6
6
  const allRecords = await getTrustRecordsByAlias(identity, signer.alias);
7
7
  const matchingRecord = allRecords.find((r) => r.card.classicalPublicKey === signer.classicalPublicKey && r.card.pqcSignPublicKey === signer.pqcSignPublicKey);
@@ -56,9 +56,8 @@ export async function encryptFor(identity, counterpart, data) {
56
56
  * in `identity`'s local trust list — this stops a caller from accidentally
57
57
  * decrypting "as if" a message came from someone they never actually trusted.
58
58
  */
59
- export async function decryptFrom(identity, counterpart, box, options = {}) {
59
+ export async function decryptFrom(identity, counterpart, box) {
60
60
  return decryptFromCore(identity, counterpart, box, {
61
- isReplay: options.isReplay,
62
61
  checkTrust: (card) => trustStatusForCard(identity, card),
63
62
  onLog: (entry) => appendLogEntry(identity, entry),
64
63
  });
@@ -1 +1 @@
1
- {"version":3,"file":"nodeHybrid.js","sourceRoot":"","sources":["../../src/crypto/nodeHybrid.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"nodeHybrid.js","sourceRoot":"","sources":["../../src/crypto/nodeHybrid.ts"],"names":[],"mappings":"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"}
@@ -8,9 +8,8 @@ export interface PqcKemKeypair {
8
8
  }
9
9
  /** ML-DSA-87 (FIPS 204, category-5 parameter set) — the post-quantum signing layer. */
10
10
  export declare function generatePqcSignKeypair(): PqcSignKeypair;
11
- /** `context` provides domain separation (FIPS 204 §5.4): omit it for document signing (unchanged), pass it for the session handshake so a handshake signature can't be reinterpreted in a different context. */
12
- export declare function pqcSign(message: Uint8Array, secretKey: Uint8Array, context?: Uint8Array): Uint8Array;
13
- export declare function pqcVerify(signature: Uint8Array, message: Uint8Array, publicKey: Uint8Array, context?: Uint8Array): boolean;
11
+ export declare function pqcSign(message: Uint8Array, secretKey: Uint8Array): Uint8Array;
12
+ export declare function pqcVerify(signature: Uint8Array, message: Uint8Array, publicKey: Uint8Array): boolean;
14
13
  /** ML-KEM-1024 (FIPS 203, category-5 parameter set) — the post-quantum key-exchange layer. */
15
14
  export declare function generatePqcKemKeypair(): PqcKemKeypair;
16
15
  export declare function pqcEncapsulate(theirPublicKey: Uint8Array): {
@@ -18,7 +17,3 @@ export declare function pqcEncapsulate(theirPublicKey: Uint8Array): {
18
17
  sharedSecret: Uint8Array;
19
18
  };
20
19
  export declare function pqcDecapsulate(cipherText: Uint8Array, secretKey: Uint8Array): Uint8Array;
21
- /** True iff `keypair`'s two fields are the exact byte lengths ml_dsa87's own keygen produces — a cheap sanity check for key material sourced from somewhere this library doesn't control (e.g. a caller-supplied KeyStore, issue #38). */
22
- export declare function isValidPqcSignKeypairShape(keypair: PqcSignKeypair): boolean;
23
- /** Same as isValidPqcSignKeypairShape, for ML-KEM-1024. */
24
- export declare function isValidPqcKemKeypairShape(keypair: PqcKemKeypair): boolean;
@@ -4,13 +4,12 @@ import { ml_kem1024 } from "@noble/post-quantum/ml-kem.js";
4
4
  export function generatePqcSignKeypair() {
5
5
  return ml_dsa87.keygen();
6
6
  }
7
- /** `context` provides domain separation (FIPS 204 §5.4): omit it for document signing (unchanged), pass it for the session handshake so a handshake signature can't be reinterpreted in a different context. */
8
- export function pqcSign(message, secretKey, context) {
9
- return ml_dsa87.sign(message, secretKey, context ? { context } : undefined);
7
+ export function pqcSign(message, secretKey) {
8
+ return ml_dsa87.sign(message, secretKey);
10
9
  }
11
- export function pqcVerify(signature, message, publicKey, context) {
10
+ export function pqcVerify(signature, message, publicKey) {
12
11
  try {
13
- return ml_dsa87.verify(signature, message, publicKey, context ? { context } : undefined);
12
+ return ml_dsa87.verify(signature, message, publicKey);
14
13
  }
15
14
  catch {
16
15
  return false;
@@ -26,12 +25,4 @@ export function pqcEncapsulate(theirPublicKey) {
26
25
  export function pqcDecapsulate(cipherText, secretKey) {
27
26
  return ml_kem1024.decapsulate(cipherText, secretKey);
28
27
  }
29
- /** True iff `keypair`'s two fields are the exact byte lengths ml_dsa87's own keygen produces — a cheap sanity check for key material sourced from somewhere this library doesn't control (e.g. a caller-supplied KeyStore, issue #38). */
30
- export function isValidPqcSignKeypairShape(keypair) {
31
- return keypair.secretKey.length === ml_dsa87.lengths.secretKey && keypair.publicKey.length === ml_dsa87.lengths.publicKey;
32
- }
33
- /** Same as isValidPqcSignKeypairShape, for ML-KEM-1024. */
34
- export function isValidPqcKemKeypairShape(keypair) {
35
- return keypair.secretKey.length === ml_kem1024.lengths.secretKey && keypair.publicKey.length === ml_kem1024.lengths.publicKey;
36
- }
37
28
  //# sourceMappingURL=pqc.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pqc.js","sourceRoot":"","sources":["../../src/crypto/pqc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAY3D,uFAAuF;AACvF,MAAM,UAAU,sBAAsB;IACpC,OAAO,QAAQ,CAAC,MAAM,EAAE,CAAC;AAC3B,CAAC;AAED,gNAAgN;AAChN,MAAM,UAAU,OAAO,CAAC,OAAmB,EAAE,SAAqB,EAAE,OAAoB;IACtF,OAAO,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,SAAqB,EAAE,OAAmB,EAAE,SAAqB,EAAE,OAAoB;IAC/G,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAC3F,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,qBAAqB;IACnC,OAAO,UAAU,CAAC,MAAM,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,cAA0B;IACvD,OAAO,UAAU,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,UAAsB,EAAE,SAAqB;IAC1E,OAAO,UAAU,CAAC,WAAW,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;AACvD,CAAC;AAED,0OAA0O;AAC1O,MAAM,UAAU,0BAA0B,CAAC,OAAuB;IAChE,OAAO,OAAO,CAAC,SAAS,CAAC,MAAM,KAAK,QAAQ,CAAC,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS,CAAC,MAAM,KAAK,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC;AAC5H,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,yBAAyB,CAAC,OAAsB;IAC9D,OAAO,OAAO,CAAC,SAAS,CAAC,MAAM,KAAK,UAAU,CAAC,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS,CAAC,MAAM,KAAK,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC;AAChI,CAAC"}
1
+ {"version":3,"file":"pqc.js","sourceRoot":"","sources":["../../src/crypto/pqc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAY3D,uFAAuF;AACvF,MAAM,UAAU,sBAAsB;IACpC,OAAO,QAAQ,CAAC,MAAM,EAAE,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,OAAmB,EAAE,SAAqB;IAChE,OAAO,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,SAAqB,EAAE,OAAmB,EAAE,SAAqB;IACzF,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,qBAAqB;IACnC,OAAO,UAAU,CAAC,MAAM,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,cAA0B;IACvD,OAAO,UAAU,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,UAAsB,EAAE,SAAqB;IAC1E,OAAO,UAAU,CAAC,WAAW,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;AACvD,CAAC"}
@@ -9,11 +9,6 @@ import { classicalSharedSecret } from "./classical.js";
9
9
  // group/multi-device fan-out — this stays two-party-only and in-order-only,
10
10
  // matching this project's always-ordered, always-1:1 transport).
11
11
  //
12
- // Callers should hold ONE ROOT PER DIRECTION (a send root advanced only by
13
- // their own steps, a receive root advanced only by mirroring the peer's) and
14
- // say explicitly on the wire when a step happened and which peer key it used.
15
- // A single shared root diverges when both sides step at once — see ADR 0013.
16
- //
17
12
  // Everything here is a PURE function: no "when do I step" logic, no
18
13
  // connection-level state, no wire format. The caller (`secureConnection.ts`'s
19
14
  // Envelope layer, a later, currently-blocked ticket) drives all of that.
@@ -1 +1 @@
1
- {"version":3,"file":"ratchet.js","sourceRoot":"","sources":["../../src/crypto/ratchet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAyB,MAAM,gBAAgB,CAAC;AAE9E,0EAA0E;AAC1E,6EAA6E;AAC7E,6EAA6E;AAC7E,sEAAsE;AACtE,4EAA4E;AAC5E,iEAAiE;AACjE,EAAE;AACF,2EAA2E;AAC3E,6EAA6E;AAC7E,8EAA8E;AAC9E,6EAA6E;AAC7E,EAAE;AACF,oEAAoE;AACpE,8EAA8E;AAC9E,yEAAyE;AAEzE,MAAM,iBAAiB,GAAG,WAAW,CAAC,+BAA+B,CAAC,CAAC;AACvE,MAAM,gBAAgB,GAAG,WAAW,CAAC,oCAAoC,CAAC,CAAC;AAC3E,MAAM,kBAAkB,GAAG,WAAW,CAAC,sCAAsC,CAAC,CAAC;AAC/E,MAAM,uBAAuB,GAAG,WAAW,CAAC,2CAA2C,CAAC,CAAC;AACzF,MAAM,sBAAsB,GAAG,WAAW,CAAC,0CAA0C,CAAC,CAAC;AAEvF,qKAAqK;AACrK,MAAM,CAAC,MAAM,iCAAiC,GAAG,WAAW,CAAC,iBAAiB,EAAE,WAAW,CAAC,wBAAwB,CAAC,CAAC,CAAC;AACvH,6CAA6C;AAC7C,MAAM,CAAC,MAAM,iCAAiC,GAAG,WAAW,CAAC,iBAAiB,EAAE,WAAW,CAAC,wBAAwB,CAAC,CAAC,CAAC;AAEvH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAEtC;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,OAAmB,EAAE,SAAqB;IACrE,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;AACzD,CAAC;AAUD;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAAC,QAAoB;IAClD,OAAO;QACL,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,gBAAgB,EAAE,EAAE,CAAC;QACnE,YAAY,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,kBAAkB,EAAE,EAAE,CAAC;KACxE,CAAC;AACJ,CAAC;AAQD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAmB,EACnB,SAA2B,EAC3B,6BAAyC,EACzC,gBAA4B;IAE5B,MAAM,YAAY,GAAG,qBAAqB,CAAC,SAAS,CAAC,SAAS,EAAE,6BAA6B,CAAC,CAAC;IAC/F,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,SAAS,EAAE,uBAAuB,EAAE,EAAE,CAAC,CAAC;IAC5G,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,YAAY,CAAC,UAAU,EAAE,gBAAgB,CAAC,EAAE,CAAC;AAC9F,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,OAAmB,EAAE,SAAqB,EAAE,gBAA4B;IACrG,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,SAAS,EAAE,sBAAsB,EAAE,EAAE,CAAC,CAAC;IACxG,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,YAAY,CAAC,UAAU,EAAE,gBAAgB,CAAC,EAAE,CAAC;AAC9F,CAAC"}
1
+ {"version":3,"file":"ratchet.js","sourceRoot":"","sources":["../../src/crypto/ratchet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAyB,MAAM,gBAAgB,CAAC;AAE9E,0EAA0E;AAC1E,6EAA6E;AAC7E,6EAA6E;AAC7E,sEAAsE;AACtE,4EAA4E;AAC5E,iEAAiE;AACjE,EAAE;AACF,oEAAoE;AACpE,8EAA8E;AAC9E,yEAAyE;AAEzE,MAAM,iBAAiB,GAAG,WAAW,CAAC,+BAA+B,CAAC,CAAC;AACvE,MAAM,gBAAgB,GAAG,WAAW,CAAC,oCAAoC,CAAC,CAAC;AAC3E,MAAM,kBAAkB,GAAG,WAAW,CAAC,sCAAsC,CAAC,CAAC;AAC/E,MAAM,uBAAuB,GAAG,WAAW,CAAC,2CAA2C,CAAC,CAAC;AACzF,MAAM,sBAAsB,GAAG,WAAW,CAAC,0CAA0C,CAAC,CAAC;AAEvF,qKAAqK;AACrK,MAAM,CAAC,MAAM,iCAAiC,GAAG,WAAW,CAAC,iBAAiB,EAAE,WAAW,CAAC,wBAAwB,CAAC,CAAC,CAAC;AACvH,6CAA6C;AAC7C,MAAM,CAAC,MAAM,iCAAiC,GAAG,WAAW,CAAC,iBAAiB,EAAE,WAAW,CAAC,wBAAwB,CAAC,CAAC,CAAC;AAEvH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAEtC;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,OAAmB,EAAE,SAAqB;IACrE,OAAO,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;AACzD,CAAC;AAUD;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAAC,QAAoB;IAClD,OAAO;QACL,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,gBAAgB,EAAE,EAAE,CAAC;QACnE,YAAY,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,kBAAkB,EAAE,EAAE,CAAC;KACxE,CAAC;AACJ,CAAC;AAQD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAmB,EACnB,SAA2B,EAC3B,6BAAyC,EACzC,gBAA4B;IAE5B,MAAM,YAAY,GAAG,qBAAqB,CAAC,SAAS,CAAC,SAAS,EAAE,6BAA6B,CAAC,CAAC;IAC/F,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,SAAS,EAAE,uBAAuB,EAAE,EAAE,CAAC,CAAC;IAC5G,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,YAAY,CAAC,UAAU,EAAE,gBAAgB,CAAC,EAAE,CAAC;AAC9F,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,OAAmB,EAAE,SAAqB,EAAE,gBAA4B;IACrG,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,SAAS,EAAE,sBAAsB,EAAE,EAAE,CAAC,CAAC;IACxG,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,YAAY,CAAC,UAAU,EAAE,gBAAgB,CAAC,EAAE,CAAC;AAC9F,CAAC"}
@@ -1,48 +1,6 @@
1
- /** Cost used for newly written files. Stored in each file, so it can be raised without a migration. */
2
- export declare const DEFAULT_KDF: {
3
- readonly name: "scrypt";
4
- readonly N: number;
5
- readonly r: 8;
6
- readonly p: 1;
7
- };
1
+ /** Encrypts `data` (any JSON-serializable value) at rest under a passphrase-derived AES-256-GCM key. */
2
+ export declare function encryptToFile(filePath: string, passphrase: string, data: unknown): Promise<void>;
8
3
  export declare class DecryptionFailedError extends Error {
9
4
  constructor();
10
5
  }
11
- /** The file was written by a newer raz-encrypt than this one understands. */
12
- export declare class UnsupportedFileVersionError extends Error {
13
- constructor(version: unknown);
14
- }
15
- /**
16
- * Atomically replaces `filePath` with `contents` (mode 0o600): write a temp
17
- * file in the same directory, fsync it, rename it over the target, then
18
- * best-effort fsync the directory. A crash at any point leaves either the
19
- * complete old file or the complete new file — never a partial one.
20
- */
21
- export declare function writeFileAtomic(filePath: string, contents: string, beforeRename?: () => Promise<void>): Promise<void>;
22
- /** Encrypts `data` (any JSON-serializable value) at rest under a passphrase-derived AES-256-GCM key, in the current (v2) format, atomically. */
23
- export declare function encryptToFile(filePath: string, passphrase: string, data: unknown): Promise<void>;
24
- export interface DecryptedFile<T> {
25
- data: T;
26
- /** True if the file on disk is the legacy v1 format (a caller may upgrade it with `upgradeLegacyFile`). */
27
- legacy: boolean;
28
- /** Index into the candidate passphrases that actually unlocked the file (0 = the first/preferred one). */
29
- passphraseIndex: number;
30
- }
31
- /**
32
- * Decrypts a file of any supported version and reports whether it was the
33
- * legacy format and which candidate passphrase worked. `passphrases` are tried
34
- * in order (callers pass the normalized form first, then the raw form for
35
- * files written before normalization existed). A missing file rejects with
36
- * the filesystem's ENOENT error.
37
- */
38
- export declare function decryptFileWithFormat<T>(filePath: string, passphrases: string | string[]): Promise<DecryptedFile<T>>;
39
6
  export declare function decryptFromFile<T>(filePath: string, passphrase: string): Promise<T>;
40
- /**
41
- * Rewrites a file in the current format, under `passphrase` (used for a
42
- * legacy v1 file, or one unlocked by a pre-normalization passphrase). Safe by construction:
43
- * the new file is written to a temp path, re-read and decrypted with the same
44
- * passphrase to prove it round-trips to `data`, and only then renamed over
45
- * the original — so the old file stays intact until the instant the verified
46
- * replacement atomically takes its place.
47
- */
48
- export declare function upgradeLegacyFile(filePath: string, passphrase: string, data: unknown): Promise<void>;
@@ -1,214 +1,45 @@
1
1
  import { gcm } from "@noble/ciphers/aes.js";
2
- import { scryptAsync } from "@noble/hashes/scrypt.js";
2
+ import { scrypt } from "@noble/hashes/scrypt.js";
3
3
  import { bytesToHex, hexToBytes, randomBytes, utf8ToBytes } from "@noble/hashes/utils.js";
4
- import { mkdir, open, readFile, rename, rm } from "node:fs/promises";
4
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
5
5
  import { dirname } from "node:path";
6
- import { canonicalize } from "./canonicalJson.js";
7
- // Encrypted-at-rest file format (ADR 0016).
8
- //
9
- // v2 (current): { version: 2, kdf: { name: "scrypt", N, r, p }, salt, nonce, ciphertext }
10
- // - the KDF parameters live in the file, so the cost can be raised later
11
- // without breaking files written today;
12
- // - the header (version, kdf, salt, nonce) is authenticated as AES-GCM AAD;
13
- // - written atomically (temp file + fsync + rename).
14
- // v1 (legacy, read-only): { salt, nonce, ciphertext } with fixed scrypt
15
- // N=2^17 r=8 p=1 and no AAD. Still readable forever; callers may upgrade it.
16
- /** Cost used for newly written files. Stored in each file, so it can be raised without a migration. */
17
- export const DEFAULT_KDF = { name: "scrypt", N: 2 ** 17, r: 8, p: 1 };
18
- const DK_LEN = 32;
19
- /** The only parameters v1 files could ever have used. */
20
- const LEGACY_KDF = { name: "scrypt", N: 2 ** 17, r: 8, p: 1 };
21
- // A file we are asked to open must not be able to make us allocate unbounded
22
- // memory (scrypt needs ~128*N*r bytes) or burn unbounded CPU.
23
- const MIN_N = 2 ** 14;
24
- const MAX_N = 2 ** 20;
25
- const MAX_N_TIMES_R = 2 ** 23; // ~1 GiB of scrypt memory
26
- const MAX_R = 16;
27
- const MAX_P = 4;
28
- export class DecryptionFailedError extends Error {
29
- constructor() {
30
- super("Failed to decrypt local store: wrong passphrase or corrupted/tampered file.");
31
- this.name = "DecryptionFailedError";
32
- }
33
- }
34
- /** The file was written by a newer raz-encrypt than this one understands. */
35
- export class UnsupportedFileVersionError extends Error {
36
- constructor(version) {
37
- super(`Local store has format version ${String(version)}, which this version of raz-encrypt does not understand. Upgrade raz-encrypt.`);
38
- this.name = "UnsupportedFileVersionError";
39
- }
40
- }
41
- function isPowerOfTwo(n) {
42
- return Number.isInteger(n) && n > 0 && (n & (n - 1)) === 0;
43
- }
44
- /** Rejects KDF parameters outside the range this library would ever write, before spending any memory or CPU on them. */
45
- function validateKdf(kdf) {
46
- const k = kdf;
47
- const ok = typeof k === "object" &&
48
- k !== null &&
49
- k.name === "scrypt" &&
50
- isPowerOfTwo(k.N) &&
51
- k.N >= MIN_N &&
52
- k.N <= MAX_N &&
53
- Number.isInteger(k.r) &&
54
- k.r >= 1 &&
55
- k.r <= MAX_R &&
56
- Number.isInteger(k.p) &&
57
- k.p >= 1 &&
58
- k.p <= MAX_P &&
59
- k.N * k.r <= MAX_N_TIMES_R;
60
- if (!ok)
61
- throw new DecryptionFailedError();
62
- }
63
- async function deriveKey(passphrase, salt, kdf) {
64
- return scryptAsync(utf8ToBytes(passphrase), salt, { N: kdf.N, r: kdf.r, p: kdf.p, dkLen: DK_LEN });
65
- }
66
- /** The authenticated header bytes: everything in the file except the ciphertext itself. */
67
- function headerAad(file) {
68
- return utf8ToBytes(canonicalize({ version: file.version, kdf: file.kdf, salt: file.salt, nonce: file.nonce }));
6
+ const SCRYPT_PARAMS = { N: 2 ** 17, r: 8, p: 1, dkLen: 32 };
7
+ function deriveKey(passphrase, salt) {
8
+ return scrypt(utf8ToBytes(passphrase), salt, SCRYPT_PARAMS);
69
9
  }
70
- async function encryptToString(passphrase, data) {
10
+ /** Encrypts `data` (any JSON-serializable value) at rest under a passphrase-derived AES-256-GCM key. */
11
+ export async function encryptToFile(filePath, passphrase, data) {
71
12
  const salt = randomBytes(16);
72
13
  const nonce = randomBytes(12);
73
- const kdf = { ...DEFAULT_KDF };
74
- const key = await deriveKey(passphrase, salt, kdf);
75
- const header = { version: 2, kdf, salt: bytesToHex(salt), nonce: bytesToHex(nonce) };
76
- const ciphertext = gcm(key, nonce, headerAad(header)).encrypt(utf8ToBytes(JSON.stringify(data)));
77
- const file = { ...header, ciphertext: bytesToHex(ciphertext) };
78
- return JSON.stringify(file);
79
- }
80
- /**
81
- * Atomically replaces `filePath` with `contents` (mode 0o600): write a temp
82
- * file in the same directory, fsync it, rename it over the target, then
83
- * best-effort fsync the directory. A crash at any point leaves either the
84
- * complete old file or the complete new file — never a partial one.
85
- */
86
- export async function writeFileAtomic(filePath, contents, beforeRename) {
87
- const dir = dirname(filePath);
88
- await mkdir(dir, { recursive: true, mode: 0o700 });
89
- const tmpPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
90
- try {
91
- const handle = await open(tmpPath, "w", 0o600);
92
- try {
93
- await handle.writeFile(contents, "utf8");
94
- await handle.sync();
95
- }
96
- finally {
97
- await handle.close();
98
- }
99
- if (beforeRename)
100
- await beforeRename();
101
- await rename(tmpPath, filePath);
102
- }
103
- catch (err) {
104
- await rm(tmpPath, { force: true });
105
- throw err;
106
- }
107
- try {
108
- const dirHandle = await open(dir, "r");
109
- try {
110
- await dirHandle.sync();
111
- }
112
- finally {
113
- await dirHandle.close();
114
- }
115
- }
116
- catch {
117
- // Directory fsync is best-effort (unsupported on some platforms/filesystems).
118
- }
119
- }
120
- /** Encrypts `data` (any JSON-serializable value) at rest under a passphrase-derived AES-256-GCM key, in the current (v2) format, atomically. */
121
- export async function encryptToFile(filePath, passphrase, data) {
122
- await writeFileAtomic(filePath, await encryptToString(passphrase, data));
14
+ const key = deriveKey(passphrase, salt);
15
+ const plaintext = utf8ToBytes(JSON.stringify(data));
16
+ const ciphertext = gcm(key, nonce).encrypt(plaintext);
17
+ const payload = {
18
+ salt: bytesToHex(salt),
19
+ nonce: bytesToHex(nonce),
20
+ ciphertext: bytesToHex(ciphertext),
21
+ };
22
+ await mkdir(dirname(filePath), { recursive: true });
23
+ await writeFile(filePath, JSON.stringify(payload), { mode: 0o600 });
123
24
  }
124
- async function decryptParsed(payload, passphrases) {
125
- if (typeof payload !== "object" || payload === null)
126
- throw new DecryptionFailedError();
127
- const version = payload.version;
128
- let salt;
129
- let nonce;
130
- let ciphertext;
131
- let kdf;
132
- let aad;
133
- let legacy;
134
- try {
135
- if (version === undefined) {
136
- const v1 = payload;
137
- salt = hexToBytes(v1.salt);
138
- nonce = hexToBytes(v1.nonce);
139
- ciphertext = hexToBytes(v1.ciphertext);
140
- kdf = { ...LEGACY_KDF };
141
- aad = undefined;
142
- legacy = true;
143
- }
144
- else if (version === 2) {
145
- const v2 = payload;
146
- validateKdf(v2.kdf);
147
- salt = hexToBytes(v2.salt);
148
- nonce = hexToBytes(v2.nonce);
149
- ciphertext = hexToBytes(v2.ciphertext);
150
- kdf = v2.kdf;
151
- aad = headerAad(v2);
152
- legacy = false;
153
- }
154
- else {
155
- throw new UnsupportedFileVersionError(version);
156
- }
157
- }
158
- catch (err) {
159
- if (err instanceof UnsupportedFileVersionError)
160
- throw err;
161
- throw new DecryptionFailedError();
162
- }
163
- for (let passphraseIndex = 0; passphraseIndex < passphrases.length; passphraseIndex++) {
164
- const key = await deriveKey(passphrases[passphraseIndex], salt, kdf);
165
- try {
166
- const plaintext = gcm(key, nonce, aad).decrypt(ciphertext);
167
- return { data: JSON.parse(new TextDecoder().decode(plaintext)), legacy, passphraseIndex };
168
- }
169
- catch {
170
- // Try the next candidate passphrase, if any.
171
- }
25
+ export class DecryptionFailedError extends Error {
26
+ constructor() {
27
+ super("Failed to decrypt local store: wrong passphrase or corrupted/tampered file.");
28
+ this.name = "DecryptionFailedError";
172
29
  }
173
- throw new DecryptionFailedError();
174
30
  }
175
- /**
176
- * Decrypts a file of any supported version and reports whether it was the
177
- * legacy format and which candidate passphrase worked. `passphrases` are tried
178
- * in order (callers pass the normalized form first, then the raw form for
179
- * files written before normalization existed). A missing file rejects with
180
- * the filesystem's ENOENT error.
181
- */
182
- export async function decryptFileWithFormat(filePath, passphrases) {
31
+ export async function decryptFromFile(filePath, passphrase) {
183
32
  const raw = await readFile(filePath, "utf8");
184
- let payload;
33
+ const payload = JSON.parse(raw);
34
+ const salt = hexToBytes(payload.salt);
35
+ const nonce = hexToBytes(payload.nonce);
36
+ const key = deriveKey(passphrase, salt);
185
37
  try {
186
- payload = JSON.parse(raw);
38
+ const plaintext = gcm(key, nonce).decrypt(hexToBytes(payload.ciphertext));
39
+ return JSON.parse(new TextDecoder().decode(plaintext));
187
40
  }
188
41
  catch {
189
42
  throw new DecryptionFailedError();
190
43
  }
191
- return (await decryptParsed(payload, Array.isArray(passphrases) ? passphrases : [passphrases]));
192
- }
193
- export async function decryptFromFile(filePath, passphrase) {
194
- return (await decryptFileWithFormat(filePath, passphrase)).data;
195
- }
196
- /**
197
- * Rewrites a file in the current format, under `passphrase` (used for a
198
- * legacy v1 file, or one unlocked by a pre-normalization passphrase). Safe by construction:
199
- * the new file is written to a temp path, re-read and decrypted with the same
200
- * passphrase to prove it round-trips to `data`, and only then renamed over
201
- * the original — so the old file stays intact until the instant the verified
202
- * replacement atomically takes its place.
203
- */
204
- export async function upgradeLegacyFile(filePath, passphrase, data) {
205
- const contents = await encryptToString(passphrase, data);
206
- const expected = JSON.stringify(data);
207
- await writeFileAtomic(filePath, contents, async () => {
208
- // Verify the exact bytes we are about to publish, with the real passphrase.
209
- const check = await decryptParsed(JSON.parse(contents), [passphrase]);
210
- if (JSON.stringify(check.data) !== expected)
211
- throw new Error("Upgraded identity file failed its round-trip check; leaving the original untouched.");
212
- });
213
44
  }
214
45
  //# sourceMappingURL=fileCrypto.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fileCrypto.js","sourceRoot":"","sources":["../src/fileCrypto.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fileCrypto.js","sourceRoot":"","sources":["../src/fileCrypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1F,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,aAAa,GAAG,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAQ5D,SAAS,SAAS,CAAC,UAAkB,EAAE,IAAgB;IACrD,OAAO,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,aAAa,CAAC,CAAC;AAC9D,CAAC;AAED,wGAAwG;AACxG,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAgB,EAAE,UAAkB,EAAE,IAAa;IACrF,MAAM,IAAI,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAC7B,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;IAC9B,MAAM,GAAG,GAAG,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEtD,MAAM,OAAO,GAAkB;QAC7B,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC;QACtB,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC;QACxB,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC;KACnC,CAAC;IAEF,MAAM,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,MAAM,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAC9C;QACE,KAAK,CAAC,6EAA6E,CAAC,CAAC;QACrF,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;IACtC,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAI,QAAgB,EAAE,UAAkB;IAC3E,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkB,CAAC;IACjD,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAExC,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;QAC1E,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAM,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,qBAAqB,EAAE,CAAC;IACpC,CAAC;AACH,CAAC"}
@@ -1,6 +1,4 @@
1
1
  import { type ClassicalKeypair } from "./crypto/classical.js";
2
- import { type Certificate, type SignOptions } from "./crypto/hybrid.js";
3
- import { MIN_PASSPHRASE_LENGTH, type PassphraseChecker } from "./passphrase.js";
4
2
  import { type PqcKemKeypair, type PqcSignKeypair } from "./crypto/pqc.js";
5
3
  export interface Identity {
6
4
  alias: string;
@@ -16,31 +14,22 @@ export interface PublicCard {
16
14
  pqcSignPublicKey: string;
17
15
  pqcKemPublicKey: string;
18
16
  }
19
- export { MIN_PASSPHRASE_LENGTH };
17
+ export declare const MIN_PASSPHRASE_LENGTH = 12;
20
18
  export interface CreateIdentityOptions {
21
19
  storageDir: string;
22
20
  passphrase: string;
23
21
  alias: string;
24
22
  /** Overwrite an existing identity at this storageDir. Defaults to false. */
25
23
  overwrite?: boolean;
26
- /** Optional, runs after the built-in checks below. See PassphraseChecker (ADR 0021). */
27
- checkPassphrase?: PassphraseChecker;
28
24
  }
29
25
  /**
30
26
  * Generates a new hybrid classical+post-quantum identity (one ECDSA/ECDH-P384
31
27
  * keypair, one ML-DSA-87 signing keypair, one ML-KEM-1024 key-exchange
32
28
  * keypair) and persists it encrypted-at-rest under `storageDir`.
33
29
  *
34
- * The passphrase is normalized to Unicode NFKC, must be at least
35
- * MIN_PASSPHRASE_LENGTH characters (counted as code points after
36
- * normalization), must not be a single repeated character, and must not be
37
- * on a small blocklist of very common passphrases (ADR 0017). These checks
38
- * only apply here, not to loadIdentity, so an identity created before they
39
- * existed can still be loaded with its original passphrase.
40
- *
41
- * `options.checkPassphrase`, if supplied, runs after all of the above pass
42
- * (ADR 0021) — this is where real breach-corpus checking belongs, not in
43
- * this library's own, deliberately small, blocklist.
30
+ * Requires a passphrase of at least MIN_PASSPHRASE_LENGTH characters — this
31
+ * check only applies here, not to loadIdentity, so an identity created
32
+ * before this check existed can still be loaded with its original passphrase.
44
33
  */
45
34
  export declare function createIdentity(options: CreateIdentityOptions): Promise<Identity>;
46
35
  export interface LoadIdentityOptions {
@@ -49,59 +38,5 @@ export interface LoadIdentityOptions {
49
38
  }
50
39
  /** Loads a previously-created identity back from disk. */
51
40
  export declare function loadIdentity(options: LoadIdentityOptions): Promise<Identity>;
52
- /**
53
- * Supplies an Identity's secret-key material from somewhere other than
54
- * `identity.enc.json` — an OS keychain, a TPM, an HSM, anything (issue
55
- * #38/ADR 0024). Scoped to key SOURCING, not operation delegation: once
56
- * `load()` returns, this library operates on the returned Uint8Arrays
57
- * directly in its own process memory exactly as it does for a file-loaded
58
- * Identity. There is no way to make classicalSign/pqcSign/etc. forward the
59
- * actual signing operation to the device instead — see ADR 0024 for why
60
- * that's out of scope (and, for the post-quantum half, not achievable with
61
- * any hardware that exists today regardless).
62
- */
63
- export interface KeyStore {
64
- load(): Promise<{
65
- classical: ClassicalKeypair;
66
- pqcSign: PqcSignKeypair;
67
- pqcKem: PqcKemKeypair;
68
- }>;
69
- }
70
- export interface LoadIdentityFromKeyStoreOptions {
71
- alias: string;
72
- storageDir: string;
73
- keyStore: KeyStore;
74
- }
75
- /**
76
- * Builds an Identity from a caller-supplied KeyStore instead of a
77
- * passphrase-encrypted file — `identity.enc.json` and a passphrase are
78
- * never part of the picture. The returned key material's shape (byte
79
- * lengths) is validated before trusting it, so a buggy KeyStore fails
80
- * clearly here rather than with a cryptic error the first time a signing
81
- * call happens to touch the bad bytes. `storageDir` is still required: the
82
- * trust store and audit log are a separate concern from where secret keys
83
- * live, unaffected by this function.
84
- */
85
- export declare function loadIdentityFromKeyStore(options: LoadIdentityFromKeyStoreOptions): Promise<Identity>;
86
- /**
87
- * Best-effort wipe of the secret key bytes held by `identity`: overwrites
88
- * them with zeros so they do not linger in this process's memory after you
89
- * are done. The identity is unusable afterwards. Limits: JavaScript gives no
90
- * guarantee about copies the engine or GC already made, and the hex strings
91
- * produced while saving or loading an identity are immutable and cannot be
92
- * wiped. This narrows the exposure window; it is not a secure-erase.
93
- */
94
- export declare function zeroizeIdentity(identity: Identity): void;
95
41
  /** The shareable public half of an identity — hand this to the other party out of band. */
96
42
  export declare function exportPublicIdentity(identity: Identity): PublicCard;
97
- /**
98
- * A self-signed, optionally time-limited version of `exportPublicIdentity`'s
99
- * card (ADR 0023/issue #37): the identity signs its own card, so a peer can
100
- * verify it wasn't tampered with and — if `options.expiresAt` was set —
101
- * reject it once expired, enforcing a cryptoperiod the bare card has no way
102
- * to carry (it has no signature at all). `exportPublicIdentity` itself is
103
- * unchanged; this is a separate, opt-in function precisely so every
104
- * existing caller of the bare card is unaffected. Verify and trust a
105
- * received one with `trustSignedCard`, not `trustParty`.
106
- */
107
- export declare function exportSignedCard(identity: Identity, options?: SignOptions): Promise<Certificate>;