@msdis/shield 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/LICENSE +140 -0
  2. package/README.md +106 -0
  3. package/dist/aead/index.d.ts +37 -0
  4. package/dist/aead/index.js +7 -0
  5. package/dist/aead/index.js.map +1 -0
  6. package/dist/asymmetric/index.d.ts +32 -0
  7. package/dist/asymmetric/index.js +6 -0
  8. package/dist/asymmetric/index.js.map +1 -0
  9. package/dist/chunk-3DQPQCAR.js +114 -0
  10. package/dist/chunk-3DQPQCAR.js.map +1 -0
  11. package/dist/chunk-3HCT6A2P.js +55 -0
  12. package/dist/chunk-3HCT6A2P.js.map +1 -0
  13. package/dist/chunk-AB2WZ7Y2.js +57 -0
  14. package/dist/chunk-AB2WZ7Y2.js.map +1 -0
  15. package/dist/chunk-BUFRR5PB.js +9 -0
  16. package/dist/chunk-BUFRR5PB.js.map +1 -0
  17. package/dist/chunk-CYIGDF63.js +30 -0
  18. package/dist/chunk-CYIGDF63.js.map +1 -0
  19. package/dist/chunk-EOXWR7DS.js +153 -0
  20. package/dist/chunk-EOXWR7DS.js.map +1 -0
  21. package/dist/chunk-FUDDBD2G.js +43 -0
  22. package/dist/chunk-FUDDBD2G.js.map +1 -0
  23. package/dist/chunk-JSKIWIEC.js +56 -0
  24. package/dist/chunk-JSKIWIEC.js.map +1 -0
  25. package/dist/chunk-JVFP2GAO.js +66 -0
  26. package/dist/chunk-JVFP2GAO.js.map +1 -0
  27. package/dist/chunk-KNCZMIZA.js +55 -0
  28. package/dist/chunk-KNCZMIZA.js.map +1 -0
  29. package/dist/chunk-MJO7IJZC.js +44 -0
  30. package/dist/chunk-MJO7IJZC.js.map +1 -0
  31. package/dist/chunk-MPWYZXW7.js +66 -0
  32. package/dist/chunk-MPWYZXW7.js.map +1 -0
  33. package/dist/chunk-OA5ARYJM.js +73 -0
  34. package/dist/chunk-OA5ARYJM.js.map +1 -0
  35. package/dist/chunk-OPHN2B3N.js +147 -0
  36. package/dist/chunk-OPHN2B3N.js.map +1 -0
  37. package/dist/chunk-RTAJJZKO.js +116 -0
  38. package/dist/chunk-RTAJJZKO.js.map +1 -0
  39. package/dist/chunk-SCHZI6YY.js +35 -0
  40. package/dist/chunk-SCHZI6YY.js.map +1 -0
  41. package/dist/chunk-T3IV7SHD.js +388 -0
  42. package/dist/chunk-T3IV7SHD.js.map +1 -0
  43. package/dist/chunk-U65A4HIY.js +133 -0
  44. package/dist/chunk-U65A4HIY.js.map +1 -0
  45. package/dist/core/index.d.ts +20 -0
  46. package/dist/core/index.js +6 -0
  47. package/dist/core/index.js.map +1 -0
  48. package/dist/encoding-B-cb7Duu.d.ts +37 -0
  49. package/dist/errors-C79jA9vX.d.ts +65 -0
  50. package/dist/file-encryption/index.d.ts +135 -0
  51. package/dist/file-encryption/index.js +11 -0
  52. package/dist/file-encryption/index.js.map +1 -0
  53. package/dist/format-versioning/index.d.ts +37 -0
  54. package/dist/format-versioning/index.js +4 -0
  55. package/dist/format-versioning/index.js.map +1 -0
  56. package/dist/index.d.ts +27 -0
  57. package/dist/index.js +24 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/integrity/index.d.ts +46 -0
  60. package/dist/integrity/index.js +6 -0
  61. package/dist/integrity/index.js.map +1 -0
  62. package/dist/kdf/index.d.ts +104 -0
  63. package/dist/kdf/index.js +7 -0
  64. package/dist/kdf/index.js.map +1 -0
  65. package/dist/key-management/index.d.ts +69 -0
  66. package/dist/key-management/index.js +10 -0
  67. package/dist/key-management/index.js.map +1 -0
  68. package/dist/migrations/index.d.ts +41 -0
  69. package/dist/migrations/index.js +4 -0
  70. package/dist/migrations/index.js.map +1 -0
  71. package/dist/post-quantum/index.d.ts +153 -0
  72. package/dist/post-quantum/index.js +3 -0
  73. package/dist/post-quantum/index.js.map +1 -0
  74. package/dist/random/index.d.ts +28 -0
  75. package/dist/random/index.js +5 -0
  76. package/dist/random/index.js.map +1 -0
  77. package/dist/secure-memory/index.d.ts +40 -0
  78. package/dist/secure-memory/index.js +5 -0
  79. package/dist/secure-memory/index.js.map +1 -0
  80. package/dist/signing/index.d.ts +41 -0
  81. package/dist/signing/index.js +5 -0
  82. package/dist/signing/index.js.map +1 -0
  83. package/dist/totp/index.d.ts +69 -0
  84. package/dist/totp/index.js +4 -0
  85. package/dist/totp/index.js.map +1 -0
  86. package/dist/vault-crypto/index.d.ts +225 -0
  87. package/dist/vault-crypto/index.js +465 -0
  88. package/dist/vault-crypto/index.js.map +1 -0
  89. package/dist/vault-encryption/index.d.ts +40 -0
  90. package/dist/vault-encryption/index.js +9 -0
  91. package/dist/vault-encryption/index.js.map +1 -0
  92. package/package.json +137 -0
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Byte/string/base64 encoding helpers.
3
+ *
4
+ * These intentionally reproduce the exact base64 encoding used by Singra Vault
5
+ * and Singra Premium so that DIS is byte-compatible with already-stored
6
+ * ciphertext. Do not "optimise" the algorithm in a way that changes output.
7
+ */
8
+ /**
9
+ * Encodes bytes to a standard (RFC 4648) base64 string.
10
+ *
11
+ * Uses a chunked loop over `String.fromCharCode` + `btoa` to stay identical to
12
+ * the legacy `uint8ArrayToBase64` implementation while avoiding call-stack
13
+ * overflows on large inputs.
14
+ */
15
+ declare function bytesToBase64(bytes: Uint8Array): string;
16
+ /** Decodes a standard base64 string to bytes. */
17
+ declare function base64ToBytes(base64: string): Uint8Array;
18
+ /** UTF-8 encodes a string to bytes. */
19
+ declare function utf8ToBytes(text: string): Uint8Array;
20
+ /** UTF-8 decodes bytes to a string. */
21
+ declare function bytesToUtf8(bytes: Uint8Array): string;
22
+ /**
23
+ * Encodes bytes to an unpadded base64url (RFC 4648 §5) string.
24
+ *
25
+ * Reproduces the exact transform used by Singra Vault's `encodeBase64Url`
26
+ * (standard base64 with `+`→`-`, `/`→`_`, trailing `=` stripped) so DIS is
27
+ * byte-compatible with stored op-log signatures, hashes and public keys.
28
+ */
29
+ declare function bytesToBase64Url(bytes: Uint8Array): string;
30
+ /** Decodes an unpadded base64url string to bytes. */
31
+ declare function base64UrlToBytes(base64url: string): Uint8Array;
32
+ /** Lower-case hex string of the given bytes. */
33
+ declare function bytesToHex(bytes: Uint8Array): string;
34
+ /** Concatenates byte arrays into a single new buffer. */
35
+ declare function concatBytes(...parts: Uint8Array[]): Uint8Array;
36
+
37
+ export { base64UrlToBytes as a, base64ToBytes as b, bytesToBase64 as c, bytesToBase64Url as d, bytesToHex as e, bytesToUtf8 as f, concatBytes as g, utf8ToBytes as u };
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Pluggable crypto provider abstraction.
3
+ *
4
+ * DIS does not invent cryptography. It binds to an audited primitive provider.
5
+ * The default provider is the platform WebCrypto implementation
6
+ * (`globalThis.crypto`), which is available in modern browsers and in Node >= 20.
7
+ *
8
+ * Exposing this as an interface keeps the door open for substituting a
9
+ * hardware-backed or test provider without touching call sites, and keeps the
10
+ * rest of DIS free of direct global access.
11
+ */
12
+ /** Minimal subset of the WebCrypto API that DIS relies on. */
13
+ interface CryptoProvider {
14
+ getRandomValues<T extends ArrayBufferView>(array: T): T;
15
+ readonly subtle: SubtleCrypto;
16
+ }
17
+ /** Returns the active crypto provider, falling back to platform WebCrypto. */
18
+ declare function getCryptoProvider(): CryptoProvider;
19
+ /**
20
+ * Overrides the active crypto provider. Intended for tests and for
21
+ * environments that supply a non-global WebCrypto implementation.
22
+ * Pass `null` to reset to platform auto-detection.
23
+ */
24
+ declare function setCryptoProvider(provider: CryptoProvider | null): void;
25
+ /** Convenience accessor for `SubtleCrypto`. */
26
+ declare function subtle(): SubtleCrypto;
27
+
28
+ /**
29
+ * Central, typed error hierarchy for DIS.
30
+ *
31
+ * Errors never include secret material (keys, plaintext, passwords) in their
32
+ * message or properties. Callers may safely log `error.code` and `error.message`.
33
+ */
34
+ type DisErrorCode = 'INVALID_ARGUMENT' | 'UNSUPPORTED_FORMAT_VERSION' | 'DECRYPTION_FAILED' | 'INTEGRITY_CHECK_FAILED' | 'KEY_DERIVATION_FAILED' | 'UNSUPPORTED_KDF_VERSION' | 'LEGACY_PAYLOAD_REQUIRES_MIGRATION' | 'PROVIDER_UNAVAILABLE' | 'USE_AFTER_DESTROY';
35
+ /** Base class for all errors thrown by DIS. */
36
+ declare class DisError extends Error {
37
+ readonly code: DisErrorCode;
38
+ constructor(code: DisErrorCode, message: string);
39
+ }
40
+ /** Thrown when an argument is missing or structurally invalid. */
41
+ declare class DisInvalidArgumentError extends DisError {
42
+ constructor(message: string);
43
+ }
44
+ /**
45
+ * Thrown when AEAD decryption or authentication fails. The cause (wrong key,
46
+ * tampered ciphertext, or AAD mismatch) is intentionally not distinguished to
47
+ * avoid leaking an oracle.
48
+ */
49
+ declare class DisDecryptionError extends DisError {
50
+ constructor(message?: string);
51
+ }
52
+ /** Thrown when a versioned payload carries a version DIS cannot read. */
53
+ declare class DisUnsupportedFormatVersionError extends DisError {
54
+ constructor(message: string);
55
+ }
56
+ /** Thrown when an integrity / hash verification fails. */
57
+ declare class DisIntegrityError extends DisError {
58
+ constructor(message?: string);
59
+ }
60
+ /** Thrown when a legacy, non-migratable payload is read on a runtime path. */
61
+ declare class DisLegacyPayloadError extends DisError {
62
+ constructor(message?: string);
63
+ }
64
+
65
+ export { type CryptoProvider as C, DisDecryptionError as D, DisError as a, type DisErrorCode as b, DisIntegrityError as c, DisInvalidArgumentError as d, DisLegacyPayloadError as e, DisUnsupportedFormatVersionError as f, getCryptoProvider as g, subtle as h, setCryptoProvider as s };
@@ -0,0 +1,135 @@
1
+ /**
2
+ * dis-file-encryption / dis-attachment-streams — chunked file & attachment
3
+ * encryption.
4
+ *
5
+ * Model (byte-compatible with Singra Premium):
6
+ * - A fresh random per-file AES-256 key encrypts the file content.
7
+ * - The file is split into fixed-size chunks; each chunk is sealed with
8
+ * AES-256-GCM and a per-chunk AAD binding it to owner/item/file/revision/
9
+ * manifest-root/index/count (defeats reorder, splice and cross-file swap).
10
+ * - The file key is wrapped by an outer vault key (supplied as a callback),
11
+ * bound by a file-key AAD.
12
+ * - A manifest records chunk hashes and a manifest root; it is sealed with
13
+ * the vault key under a manifest AAD and wrapped in `sv-file-manifest-v1:`.
14
+ *
15
+ * DIS owns the cryptography and the format. It is storage-agnostic: callers
16
+ * supply chunk read/write callbacks, so transport (e.g. object storage, local
17
+ * FS) stays in the application.
18
+ */
19
+ /** Default chunk size (4 MiB), matching the Singra Premium format. */
20
+ declare const DEFAULT_CHUNK_SIZE: number;
21
+ declare const FILE_MANIFEST_V1_PREFIX = "sv-file-manifest-v1:";
22
+ /** Opaque binding context for an attachment. Ids are treated as opaque strings. */
23
+ interface AttachmentContext {
24
+ readonly ownerId: string;
25
+ readonly vaultItemId: string;
26
+ readonly fileId: string;
27
+ }
28
+ /** Encrypts text with the outer vault key (e.g. DIS aead.encryptString). */
29
+ type VaultEncryptText = (plaintext: string, aad?: string) => Promise<string>;
30
+ type VaultDecryptText = (encrypted: string, aad?: string) => Promise<string>;
31
+ type VaultEncryptBytes = (plaintext: Uint8Array, aad?: string) => Promise<string>;
32
+ type VaultDecryptBytes = (encrypted: string, aad?: string) => Promise<Uint8Array>;
33
+ interface FileChunkManifest {
34
+ readonly index: number;
35
+ readonly plaintext_size: number;
36
+ readonly ciphertext_size: number;
37
+ readonly ciphertext_sha256: string;
38
+ }
39
+ interface FileManifestV1 {
40
+ readonly version: 1;
41
+ readonly algorithm: 'AES-256-GCM';
42
+ readonly file_id: string;
43
+ readonly file_revision: number;
44
+ readonly previous_manifest_hash: string | null;
45
+ readonly manifest_root: string;
46
+ readonly owner_id: string;
47
+ readonly vault_item_id: string;
48
+ readonly original_name: string;
49
+ readonly mime_type: string | null;
50
+ readonly original_size: number;
51
+ readonly last_modified: number | null;
52
+ readonly uploaded_at: string;
53
+ readonly chunk_size: number;
54
+ readonly chunk_count: number;
55
+ readonly wrapped_file_key: string;
56
+ readonly chunks: readonly FileChunkManifest[];
57
+ readonly preview: null;
58
+ readonly notes: null;
59
+ }
60
+ declare function manifestAad(ctx: AttachmentContext): string;
61
+ declare function fileKeyAad(ctx: AttachmentContext): string;
62
+ declare function chunkAad(ctx: AttachmentContext, fileRevision: number, manifestRoot: string, chunkIndex: number, chunkCount: number): string;
63
+ /** Generates fresh per-file AES-256 key bytes (caller must wipe). */
64
+ declare function generateFileKeyBytes(): Uint8Array;
65
+ /** Imports raw file-key bytes as a non-extractable AES-GCM key. */
66
+ declare function importFileKey(rawKey: Uint8Array): Promise<CryptoKey>;
67
+ /** Seals one plaintext chunk. `plaintext` is wiped before returning. */
68
+ declare function encryptChunk(plaintext: Uint8Array, fileKey: CryptoKey, aad: string): Promise<string>;
69
+ /** Opens one chunk. Returned bytes are plaintext — caller must wipe. */
70
+ declare function decryptChunk(encryptedBase64: string, fileKey: CryptoKey, aad: string): Promise<Uint8Array>;
71
+ interface PlannedChunk {
72
+ readonly index: number;
73
+ readonly plaintext_size: number;
74
+ }
75
+ /**
76
+ * Computes the manifest root: a SHA-256 over the planned chunk layout. Binding
77
+ * each chunk's AAD to this root prevents chunk-count / size tampering.
78
+ */
79
+ declare function computeManifestRoot(input: {
80
+ fileId: string;
81
+ fileRevision: number;
82
+ chunkSize: number;
83
+ chunkCount: number;
84
+ chunks: readonly PlannedChunk[];
85
+ }): Promise<string>;
86
+ /** SHA-256 (base64) of a ciphertext chunk, for the manifest. */
87
+ declare function chunkCiphertextHash(ciphertextBase64: string): Promise<string>;
88
+ interface EncryptAttachmentInput {
89
+ readonly context: AttachmentContext;
90
+ readonly fileRevision?: number;
91
+ readonly chunkSize?: number;
92
+ /** Total plaintext size in bytes (used to plan chunks). */
93
+ readonly totalSize: number;
94
+ /** Returns the plaintext bytes for chunk `[start, end)`. */
95
+ readonly readChunk: (start: number, end: number) => Promise<Uint8Array>;
96
+ /** Persists a sealed chunk; returns its stored ciphertext size in bytes. */
97
+ readonly writeChunk: (index: number, ciphertextBase64: string) => Promise<number>;
98
+ /** Wraps the per-file key with the outer vault key. */
99
+ readonly wrapFileKey: VaultEncryptBytes;
100
+ readonly metadata: {
101
+ readonly original_name: string;
102
+ readonly mime_type: string | null;
103
+ readonly last_modified: number | null;
104
+ };
105
+ }
106
+ interface EncryptAttachmentResult {
107
+ readonly manifest: FileManifestV1;
108
+ readonly manifestRoot: string;
109
+ }
110
+ /**
111
+ * Encrypts an attachment chunk-by-chunk and produces a sealed manifest.
112
+ * Storage is delegated to `readChunk`/`writeChunk`. The returned manifest's
113
+ * `wrapped_file_key` is bound to the file via {@link fileKeyAad}.
114
+ */
115
+ declare function encryptAttachment(input: EncryptAttachmentInput): Promise<EncryptAttachmentResult>;
116
+ interface DecryptAttachmentInput {
117
+ readonly context: AttachmentContext;
118
+ readonly manifest: FileManifestV1;
119
+ /** Reads a stored ciphertext chunk by index. */
120
+ readonly readChunk: (index: number, storedSha256: string) => Promise<string>;
121
+ /** Receives a decrypted plaintext chunk (caller may stream to disk). */
122
+ readonly writeChunk: (index: number, plaintext: Uint8Array) => Promise<void>;
123
+ /** Unwraps the per-file key using the outer vault key. */
124
+ readonly unwrapFileKey: VaultDecryptBytes;
125
+ /** If true (default), verify each chunk's stored ciphertext hash. */
126
+ readonly verifyChunkHashes?: boolean;
127
+ }
128
+ /**
129
+ * Decrypts an attachment by streaming chunks through `readChunk`/`writeChunk`.
130
+ * Each chunk is authenticated by its AAD; when `verifyChunkHashes` is set the
131
+ * stored ciphertext hash is additionally checked before decryption.
132
+ */
133
+ declare function decryptAttachment(input: DecryptAttachmentInput): Promise<void>;
134
+
135
+ export { type AttachmentContext, DEFAULT_CHUNK_SIZE, type DecryptAttachmentInput, type EncryptAttachmentInput, type EncryptAttachmentResult, FILE_MANIFEST_V1_PREFIX, type FileChunkManifest, type FileManifestV1, type VaultDecryptBytes, type VaultDecryptText, type VaultEncryptBytes, type VaultEncryptText, chunkAad, chunkCiphertextHash, computeManifestRoot, decryptAttachment, decryptChunk, encryptAttachment, encryptChunk, fileKeyAad, generateFileKeyBytes, importFileKey, manifestAad };
@@ -0,0 +1,11 @@
1
+ export { DEFAULT_CHUNK_SIZE, FILE_MANIFEST_V1_PREFIX, chunkAad, chunkCiphertextHash, computeManifestRoot, decryptAttachment, decryptChunk, encryptAttachment, encryptChunk, fileKeyAad, generateFileKeyBytes, importFileKey, manifestAad } from '../chunk-EOXWR7DS.js';
2
+ import '../chunk-MPWYZXW7.js';
3
+ import '../chunk-3HCT6A2P.js';
4
+ import '../chunk-OPHN2B3N.js';
5
+ import '../chunk-U65A4HIY.js';
6
+ import '../chunk-BUFRR5PB.js';
7
+ import '../chunk-JSKIWIEC.js';
8
+ import '../chunk-CYIGDF63.js';
9
+ import '../chunk-MJO7IJZC.js';
10
+ //# sourceMappingURL=index.js.map
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * dis-format-versioning — versioned, prefix-tagged cipher envelopes.
3
+ *
4
+ * Every persisted ciphertext carries an explicit, human-readable version
5
+ * prefix (e.g. `sv-vault-v1:`). Parsing dispatches strictly by prefix and
6
+ * fails closed for unknown versions in the same family, so a future format can
7
+ * never be silently misread as a legacy payload. Payloads with no recognised
8
+ * prefix are reported as `legacy`, letting callers decide whether to allow them
9
+ * (e.g. only on an explicit migration path).
10
+ */
11
+ /** Describes a family of versioned envelopes and its current prefix. */
12
+ interface VersionedCipherEnvelopeSpec {
13
+ /** The prefix written for the current version, e.g. `sv-vault-v1:`. */
14
+ readonly currentPrefix: string;
15
+ /** The shared family prefix, e.g. `sv-vault-`. */
16
+ readonly familyPrefix: string;
17
+ /** Human-readable subject used in error messages, e.g. `vault item`. */
18
+ readonly subject: string;
19
+ }
20
+ type VersionedCipherEnvelope = {
21
+ readonly version: 1;
22
+ readonly payload: string;
23
+ } | {
24
+ readonly version: 'legacy';
25
+ readonly payload: string;
26
+ };
27
+ /** Wraps a base64 ciphertext in the spec's current version prefix. */
28
+ declare function formatEnvelope(spec: VersionedCipherEnvelopeSpec, encryptedBase64: string): string;
29
+ /**
30
+ * Parses an envelope. Returns `version: 1` for the current prefix, throws for
31
+ * an unknown in-family version, and returns `version: 'legacy'` otherwise.
32
+ */
33
+ declare function parseEnvelope(spec: VersionedCipherEnvelopeSpec, encryptedData: string): VersionedCipherEnvelope;
34
+ /** True if `encryptedData` is in the spec's current (v1) envelope format. */
35
+ declare function isCurrentEnvelope(spec: VersionedCipherEnvelopeSpec, encryptedData: string): boolean;
36
+
37
+ export { type VersionedCipherEnvelope, type VersionedCipherEnvelopeSpec, formatEnvelope, isCurrentEnvelope, parseEnvelope };
@@ -0,0 +1,4 @@
1
+ export { formatEnvelope, isCurrentEnvelope, parseEnvelope } from '../chunk-SCHZI6YY.js';
2
+ import '../chunk-MJO7IJZC.js';
3
+ //# sourceMappingURL=index.js.map
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,27 @@
1
+ export { VAULT_ITEM_ENVELOPE_V1_PREFIX, VaultEntryData, VaultEntryMigrationResult, decryptVaultEntry, decryptVaultEntryForMigration, encryptVaultEntry, isCurrentVaultEntryEnvelope } from './vault-encryption/index.js';
2
+ export { AttachmentContext, DEFAULT_CHUNK_SIZE, DecryptAttachmentInput, EncryptAttachmentInput, FILE_MANIFEST_V1_PREFIX, FileChunkManifest, FileManifestV1, decryptAttachment, decryptChunk, encryptAttachment, encryptChunk, generateFileKeyBytes, importFileKey } from './file-encryption/index.js';
3
+ export { Argon2idRawParams, CURRENT_KDF_VERSION, DEFAULT_KDF_PARAMS, DeriveRawKeyOptions, KdfParams, argon2idRaw, deriveHkdfAesGcmKey, deriveHkdfSha256Bits, deriveAesGcmKey as deriveMasterKey, deriveRawKey, generateSalt, importAesGcmKey } from './kdf/index.js';
4
+ export { DEFAULT_KEY_WRAP_SCHEME, KeyWrapScheme, UserKeyBundle, createWrappedUserKey, generateContentKeyBytes, rotateWrappedKey as rotateEncryptionKeys, unwrapUserKey, unwrapUserKeyBytes } from './key-management/index.js';
5
+ export { HYBRID_VERSION, HybridKeyPair, PQKeyPair, SECURITY_STANDARD_VERSION, SharedKeyWrapAadInput, buildSharedKeyWrapAad, generateHybridKeyPair, generatePQKeyPair, hybridDecrypt, hybridEncrypt, hybridUnwrapKey, hybridWrapKey, isCurrentStandardEncrypted, isHybridEncrypted, migrateToHybrid } from './post-quantum/index.js';
6
+ export { constantTimeEqual, hmacSha256, hmacSha256WithKey, importHmacSha256Key, sha1Hex, sha256Base64, sha256Base64Url, sha256Bytes, sha256Hex, sha256JsonBase64, verifyPayloadIntegrity } from './integrity/index.js';
7
+ export { ECDSA_P256_SIGNATURE_LENGTH, EcdsaP256KeyPair, generateEcdsaP256KeyPair, importEcdsaP256PublicKeySpki, signEcdsaP256, verifyEcdsaP256 } from './signing/index.js';
8
+ export { TotpParams, buildTotpUri, generateTotpSecret, verifyTotpCode } from './totp/index.js';
9
+ export { Migration, MigrationContext, MigrationRegistry, VersionDetector } from './migrations/index.js';
10
+ export { aesGcmDecrypt, aesGcmEncrypt, decryptBytes, decryptString, encryptBytes, encryptString, generateAesGcmKey, importAesGcmRawKey } from './aead/index.js';
11
+ export { SecureBuffer, withSecureBuffer, zeroBuffers } from './secure-memory/index.js';
12
+ export { fillRandom, randomBytes, randomInt, randomUuid } from './random/index.js';
13
+ export { VersionedCipherEnvelope, VersionedCipherEnvelopeSpec, formatEnvelope, isCurrentEnvelope, parseEnvelope } from './format-versioning/index.js';
14
+ export { C as CryptoProvider, D as DisDecryptionError, a as DisError, b as DisErrorCode, c as DisIntegrityError, d as DisInvalidArgumentError, e as DisLegacyPayloadError, f as DisUnsupportedFormatVersionError, g as getCryptoProvider, s as setCryptoProvider } from './errors-C79jA9vX.js';
15
+
16
+ /**
17
+ * DIS — Defensive Integration Shield
18
+ * Powered by DIS — Defensive Integration Shield.
19
+ *
20
+ * Stable public SDK facade. Applications should depend on this surface (or the
21
+ * individual `@dis/shield/<module>` entry points) and never call low-level
22
+ * WebCrypto directly. Internal cryptographic changes are designed not to break
23
+ * these signatures.
24
+ */
25
+ declare const DIS_BRANDING: "Powered by DIS \u2014 Defensive Integration Shield";
26
+
27
+ export { DIS_BRANDING };
package/dist/index.js ADDED
@@ -0,0 +1,24 @@
1
+ export { MigrationRegistry } from './chunk-FUDDBD2G.js';
2
+ export { DEFAULT_CHUNK_SIZE, FILE_MANIFEST_V1_PREFIX, decryptAttachment, decryptChunk, encryptAttachment, encryptChunk, generateFileKeyBytes, importFileKey } from './chunk-EOXWR7DS.js';
3
+ export { DEFAULT_KEY_WRAP_SCHEME, createWrappedUserKey, generateContentKeyBytes, rotateWrappedKey as rotateEncryptionKeys, unwrapUserKey, unwrapUserKeyBytes } from './chunk-3DQPQCAR.js';
4
+ export { HYBRID_VERSION, SECURITY_STANDARD_VERSION, buildSharedKeyWrapAad, generateHybridKeyPair, generatePQKeyPair, hybridDecrypt, hybridEncrypt, hybridUnwrapKey, hybridWrapKey, isCurrentStandardEncrypted, isHybridEncrypted, migrateToHybrid } from './chunk-T3IV7SHD.js';
5
+ export { constantTimeEqual, hmacSha256, hmacSha256WithKey, importHmacSha256Key, sha1Hex, sha256Base64, sha256Base64Url, sha256Bytes, sha256Hex, sha256JsonBase64, verifyPayloadIntegrity } from './chunk-MPWYZXW7.js';
6
+ export { ECDSA_P256_SIGNATURE_LENGTH, generateEcdsaP256KeyPair, importEcdsaP256PublicKeySpki, signEcdsaP256, verifyEcdsaP256 } from './chunk-AB2WZ7Y2.js';
7
+ export { buildTotpUri, generateTotpSecret, verifyTotpCode } from './chunk-OA5ARYJM.js';
8
+ export { fillRandom, randomBytes, randomInt, randomUuid } from './chunk-3HCT6A2P.js';
9
+ export { SecureBuffer, withSecureBuffer, zeroBuffers } from './chunk-RTAJJZKO.js';
10
+ export { CURRENT_KDF_VERSION, DEFAULT_KDF_PARAMS, argon2idRaw, deriveHkdfAesGcmKey, deriveHkdfSha256Bits, deriveAesGcmKey as deriveMasterKey, deriveRawKey, generateSalt, importAesGcmKey } from './chunk-OPHN2B3N.js';
11
+ export { VAULT_ITEM_ENVELOPE_V1_PREFIX, decryptVaultEntry, decryptVaultEntryForMigration, encryptVaultEntry, isCurrentVaultEntryEnvelope } from './chunk-JVFP2GAO.js';
12
+ export { aesGcmDecrypt, aesGcmEncrypt, decryptBytes, decryptString, encryptBytes, encryptString, generateAesGcmKey, importAesGcmRawKey } from './chunk-U65A4HIY.js';
13
+ import './chunk-BUFRR5PB.js';
14
+ import './chunk-JSKIWIEC.js';
15
+ export { getCryptoProvider, setCryptoProvider } from './chunk-CYIGDF63.js';
16
+ export { formatEnvelope, isCurrentEnvelope, parseEnvelope } from './chunk-SCHZI6YY.js';
17
+ export { DisDecryptionError, DisError, DisIntegrityError, DisInvalidArgumentError, DisLegacyPayloadError, DisUnsupportedFormatVersionError } from './chunk-MJO7IJZC.js';
18
+
19
+ // src/index.ts
20
+ var DIS_BRANDING = "Powered by DIS \u2014 Defensive Integration Shield";
21
+
22
+ export { DIS_BRANDING };
23
+ //# sourceMappingURL=index.js.map
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAUO,IAAM,YAAA,GAAe","file":"index.js","sourcesContent":["/**\r\n * DIS — Defensive Integration Shield\r\n * Powered by DIS — Defensive Integration Shield.\r\n *\r\n * Stable public SDK facade. Applications should depend on this surface (or the\r\n * individual `@dis/shield/<module>` entry points) and never call low-level\r\n * WebCrypto directly. Internal cryptographic changes are designed not to break\r\n * these signatures.\r\n */\r\n\r\nexport const DIS_BRANDING = 'Powered by DIS — Defensive Integration Shield' as const;\r\n\r\n// ---- Stable high-level API ------------------------------------------------\r\n\r\n// Vault entries\r\nexport {\r\n encryptVaultEntry,\r\n decryptVaultEntry,\r\n decryptVaultEntryForMigration,\r\n isCurrentVaultEntryEnvelope,\r\n VAULT_ITEM_ENVELOPE_V1_PREFIX,\r\n type VaultEntryData,\r\n type VaultEntryMigrationResult,\r\n} from './vault-encryption/index.js';\r\n\r\n// Attachments / files\r\nexport {\r\n encryptAttachment,\r\n decryptAttachment,\r\n encryptChunk,\r\n decryptChunk,\r\n generateFileKeyBytes,\r\n importFileKey,\r\n DEFAULT_CHUNK_SIZE,\r\n FILE_MANIFEST_V1_PREFIX,\r\n type AttachmentContext,\r\n type FileManifestV1,\r\n type FileChunkManifest,\r\n type EncryptAttachmentInput,\r\n type DecryptAttachmentInput,\r\n} from './file-encryption/index.js';\r\n\r\n// Key derivation (deriveMasterKey == deriveAesGcmKey)\r\nexport {\r\n deriveAesGcmKey as deriveMasterKey,\r\n deriveRawKey,\r\n importAesGcmKey,\r\n generateSalt,\r\n CURRENT_KDF_VERSION,\r\n DEFAULT_KDF_PARAMS,\r\n type KdfParams,\r\n type DeriveRawKeyOptions,\r\n} from './kdf/index.js';\r\n\r\n// Key management / rotation (rotateEncryptionKeys == rotateWrappedKey)\r\nexport {\r\n createWrappedUserKey,\r\n unwrapUserKey,\r\n unwrapUserKeyBytes,\r\n rotateWrappedKey as rotateEncryptionKeys,\r\n generateContentKeyBytes,\r\n DEFAULT_KEY_WRAP_SCHEME,\r\n type UserKeyBundle,\r\n type KeyWrapScheme,\r\n} from './key-management/index.js';\r\n\r\n// Post-quantum hybrid key wrapping (ML-KEM-768 + RSA-4096) for sharing /\r\n// emergency-access keys. Optional: requires the `@noble/post-quantum` peer.\r\nexport {\r\n generatePQKeyPair,\r\n generateHybridKeyPair,\r\n hybridEncrypt,\r\n hybridDecrypt,\r\n hybridWrapKey,\r\n hybridUnwrapKey,\r\n isHybridEncrypted,\r\n isCurrentStandardEncrypted,\r\n migrateToHybrid,\r\n buildSharedKeyWrapAad,\r\n HYBRID_VERSION,\r\n SECURITY_STANDARD_VERSION,\r\n type PQKeyPair,\r\n type HybridKeyPair,\r\n type SharedKeyWrapAadInput,\r\n} from './post-quantum/index.js';\r\n\r\n// Integrity & hashing\r\nexport {\r\n verifyPayloadIntegrity,\r\n sha256Bytes,\r\n sha256Base64,\r\n sha256Base64Url,\r\n sha256Hex,\r\n sha1Hex,\r\n sha256JsonBase64,\r\n hmacSha256,\r\n hmacSha256WithKey,\r\n importHmacSha256Key,\r\n constantTimeEqual,\r\n} from './integrity/index.js';\r\n\r\n// Digital signatures (ECDSA P-256)\r\nexport {\r\n generateEcdsaP256KeyPair,\r\n importEcdsaP256PublicKeySpki,\r\n signEcdsaP256,\r\n verifyEcdsaP256,\r\n ECDSA_P256_SIGNATURE_LENGTH,\r\n type EcdsaP256KeyPair,\r\n} from './signing/index.js';\r\n\r\n// Time-based one-time passwords (TOTP)\r\nexport {\r\n generateTotpSecret,\r\n buildTotpUri,\r\n verifyTotpCode,\r\n type TotpParams,\r\n} from './totp/index.js';\r\n\r\n// Migrations (migrateEncryptedPayload via the registry)\r\nexport {\r\n MigrationRegistry,\r\n type Migration,\r\n type MigrationContext,\r\n type VersionDetector,\r\n} from './migrations/index.js';\r\n\r\n// ---- Lower-level building blocks (re-exported for advanced use) -----------\r\n\r\nexport {\r\n encryptBytes,\r\n decryptBytes,\r\n encryptString,\r\n decryptString,\r\n aesGcmEncrypt,\r\n aesGcmDecrypt,\r\n importAesGcmRawKey,\r\n generateAesGcmKey,\r\n} from './aead/index.js';\r\n\r\nexport {\r\n argon2idRaw,\r\n deriveHkdfSha256Bits,\r\n deriveHkdfAesGcmKey,\r\n type Argon2idRawParams,\r\n} from './kdf/index.js';\r\n\r\nexport {\r\n SecureBuffer,\r\n withSecureBuffer,\r\n zeroBuffers,\r\n} from './secure-memory/index.js';\r\n\r\nexport { randomBytes, randomInt, fillRandom, randomUuid } from './random/index.js';\r\n\r\nexport {\r\n formatEnvelope,\r\n parseEnvelope,\r\n isCurrentEnvelope,\r\n type VersionedCipherEnvelopeSpec,\r\n type VersionedCipherEnvelope,\r\n} from './format-versioning/index.js';\r\n\r\nexport {\r\n setCryptoProvider,\r\n getCryptoProvider,\r\n type CryptoProvider,\r\n} from './core/provider.js';\r\n\r\nexport {\r\n DisError,\r\n DisInvalidArgumentError,\r\n DisDecryptionError,\r\n DisUnsupportedFormatVersionError,\r\n DisIntegrityError,\r\n DisLegacyPayloadError,\r\n type DisErrorCode,\r\n} from './core/errors.js';\r\n"]}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * dis-integrity — hashing and verification helpers.
3
+ *
4
+ * Provides SHA-256 digests (base64) and constant-time comparison. Used for
5
+ * file-chunk integrity, manifest roots, and any place that must verify a
6
+ * payload has not been altered. Confidential payloads still rely on AEAD;
7
+ * these helpers cover integrity of already-encrypted / public material.
8
+ */
9
+ /** SHA-256 of raw bytes, returned as a fresh `Uint8Array` digest. */
10
+ declare function sha256Bytes(data: Uint8Array): Promise<Uint8Array>;
11
+ /** SHA-256 of raw bytes, base64-encoded. */
12
+ declare function sha256Base64(data: Uint8Array): Promise<string>;
13
+ /** SHA-256 of raw bytes, unpadded-base64url-encoded. */
14
+ declare function sha256Base64Url(data: Uint8Array): Promise<string>;
15
+ /** SHA-256 of raw bytes, lower-case hex-encoded. */
16
+ declare function sha256Hex(data: Uint8Array): Promise<string>;
17
+ /**
18
+ * SHA-1 of raw bytes, lower-case hex-encoded.
19
+ *
20
+ * SHA-1 is collision-broken and MUST NOT be used for any security decision.
21
+ * It is provided solely for legacy interop where a remote protocol mandates
22
+ * it — specifically the HaveIBeenPwned k-anonymity range API, which keys on
23
+ * the SHA-1 of the password. Callers uppercase the hex as the API requires.
24
+ */
25
+ declare function sha1Hex(data: Uint8Array): Promise<string>;
26
+ /** Imports raw bytes as an HMAC-SHA-256 key. */
27
+ declare function importHmacSha256Key(keyBytes: Uint8Array, usages?: KeyUsage[]): Promise<CryptoKey>;
28
+ /** Computes HMAC-SHA-256 over `data` with an already-imported key. */
29
+ declare function hmacSha256WithKey(key: CryptoKey, data: Uint8Array): Promise<Uint8Array>;
30
+ /** Computes HMAC-SHA-256 over `data` with raw key bytes. */
31
+ declare function hmacSha256(keyBytes: Uint8Array, data: Uint8Array): Promise<Uint8Array>;
32
+ /** SHA-256 of a UTF-8 string, base64-encoded. */
33
+ declare function sha256StringBase64(data: string): Promise<string>;
34
+ /** SHA-256 of the JSON serialisation of `value`, base64-encoded. */
35
+ declare function sha256JsonBase64(value: unknown): Promise<string>;
36
+ /** Constant-time equality of two byte arrays. */
37
+ declare function constantTimeEqual(a: Uint8Array, b: Uint8Array): boolean;
38
+ /** Constant-time equality of two base64 strings (compared as decoded bytes). */
39
+ declare function constantTimeEqualBase64(a: string, b: string): boolean;
40
+ /**
41
+ * Verifies that `data` hashes (SHA-256) to `expectedBase64`, throwing
42
+ * {@link DisIntegrityError} on mismatch. Comparison is constant-time.
43
+ */
44
+ declare function verifyPayloadIntegrity(data: Uint8Array, expectedBase64: string): Promise<void>;
45
+
46
+ export { constantTimeEqual, constantTimeEqualBase64, hmacSha256, hmacSha256WithKey, importHmacSha256Key, sha1Hex, sha256Base64, sha256Base64Url, sha256Bytes, sha256Hex, sha256JsonBase64, sha256StringBase64, verifyPayloadIntegrity };
@@ -0,0 +1,6 @@
1
+ export { constantTimeEqual, constantTimeEqualBase64, hmacSha256, hmacSha256WithKey, importHmacSha256Key, sha1Hex, sha256Base64, sha256Base64Url, sha256Bytes, sha256Hex, sha256JsonBase64, sha256StringBase64, verifyPayloadIntegrity } from '../chunk-MPWYZXW7.js';
2
+ import '../chunk-JSKIWIEC.js';
3
+ import '../chunk-CYIGDF63.js';
4
+ import '../chunk-MJO7IJZC.js';
5
+ //# sourceMappingURL=index.js.map
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * dis-kdf — password-based key derivation.
3
+ *
4
+ * Primitive: Argon2id (via the audited `hash-wasm` implementation), with
5
+ * versioned, immutable parameter sets so accounts can be transparently
6
+ * upgraded to stronger parameters over time. Optional HKDF-Expand strengthening
7
+ * binds the derived key to a second factor (e.g. a device key) without
8
+ * weakening the password-derived material.
9
+ *
10
+ * DIS does not invent a KDF. Parameters follow OWASP Argon2id guidance.
11
+ */
12
+ /** Argon2id parameter set. Once released, a version's params are immutable. */
13
+ interface KdfParams {
14
+ /** Memory cost in KiB. */
15
+ readonly memory: number;
16
+ /** Iteration (time) cost. */
17
+ readonly iterations: number;
18
+ /** Degree of parallelism. */
19
+ readonly parallelism: number;
20
+ /** Output length in bytes. */
21
+ readonly hashLength: number;
22
+ }
23
+ /**
24
+ * Default versioned parameter registry. Byte-compatible with Singra Vault:
25
+ * v1: 64 MiB (original baseline)
26
+ * v2: 128 MiB (current; exceeds OWASP Argon2id minimum)
27
+ *
28
+ * IMPORTANT: never change an existing version's parameters — only add versions.
29
+ */
30
+ declare const DEFAULT_KDF_PARAMS: Readonly<Record<number, KdfParams>>;
31
+ /** The latest KDF version. New accounts derive with this version. */
32
+ declare const CURRENT_KDF_VERSION = 2;
33
+ /** Optional second-factor strengthening via HKDF-Expand (SHA-256). */
34
+ interface KdfStrengthenOptions {
35
+ /** Salt for HKDF (e.g. a 256-bit device key). */
36
+ readonly hkdfSalt: Uint8Array;
37
+ /** Domain-separation `info` string for HKDF. Caller-owned (format contract). */
38
+ readonly info: string;
39
+ }
40
+ interface DeriveRawKeyOptions {
41
+ /** KDF version to look up in `params`. Defaults to {@link CURRENT_KDF_VERSION}. */
42
+ readonly version?: number;
43
+ /** Parameter registry. Defaults to {@link DEFAULT_KDF_PARAMS}. */
44
+ readonly params?: Readonly<Record<number, KdfParams>>;
45
+ /** Optional HKDF strengthening (e.g. device-key binding). */
46
+ readonly strengthen?: KdfStrengthenOptions;
47
+ }
48
+ /** Generates a cryptographically secure, base64-encoded salt. */
49
+ declare function generateSalt(): string;
50
+ /**
51
+ * Derives raw key bytes from a password using Argon2id (+ optional HKDF).
52
+ *
53
+ * The caller owns the returned buffer and MUST wipe it (`.fill(0)`).
54
+ */
55
+ declare function deriveRawKey(password: string, saltBase64: string, options?: DeriveRawKeyOptions): Promise<Uint8Array>;
56
+ /** Imports raw 256-bit key bytes as a non-extractable AES-GCM CryptoKey. */
57
+ declare function importAesGcmKey(keyBytes: Uint8Array | BufferSource): Promise<CryptoKey>;
58
+ /**
59
+ * Derives a non-extractable AES-GCM key from a password. Raw key bytes are
60
+ * wiped as soon as the CryptoKey is imported.
61
+ */
62
+ declare function deriveAesGcmKey(password: string, saltBase64: string, options?: DeriveRawKeyOptions): Promise<CryptoKey>;
63
+ /** Explicit Argon2id parameters for a single ad-hoc derivation. */
64
+ interface Argon2idRawParams {
65
+ readonly password: string;
66
+ readonly salt: Uint8Array;
67
+ /** Memory cost in KiB. */
68
+ readonly memorySize: number;
69
+ readonly iterations: number;
70
+ readonly parallelism: number;
71
+ readonly hashLength: number;
72
+ }
73
+ /**
74
+ * Low-level Argon2id derivation returning raw key bytes. This is the audited
75
+ * `hash-wasm` Argon2id with caller-chosen parameters and a raw byte salt — for
76
+ * call sites that derive a key with a context-specific salt/param set (device
77
+ * key transfer wrapping, integrity HMAC key) rather than the versioned account
78
+ * KDF registry used by {@link deriveRawKey}.
79
+ */
80
+ declare function argon2idRaw(params: Argon2idRawParams): Promise<Uint8Array>;
81
+ /**
82
+ * HKDF-SHA-256 expand/extract producing `lengthBits` of key material.
83
+ *
84
+ * `ikm` is the input keying material, `salt` defaults to the empty salt (the
85
+ * op-log record/snapshot derivations use an empty salt and put all context in
86
+ * `info`; the device-key derivation uses the device key as salt).
87
+ */
88
+ declare function deriveHkdfSha256Bits(ikm: Uint8Array, options: {
89
+ info: Uint8Array;
90
+ salt?: Uint8Array;
91
+ lengthBits?: number;
92
+ }): Promise<Uint8Array>;
93
+ /**
94
+ * HKDF-SHA-256 deriving directly into a non-extractable AES-256-GCM key,
95
+ * mirroring `crypto.subtle.deriveKey` (used by passkey PRF wrapping and the
96
+ * legacy device-key wrapping path).
97
+ */
98
+ declare function deriveHkdfAesGcmKey(ikm: Uint8Array, options: {
99
+ info: Uint8Array;
100
+ salt?: Uint8Array;
101
+ usages?: KeyUsage[];
102
+ }): Promise<CryptoKey>;
103
+
104
+ export { type Argon2idRawParams, CURRENT_KDF_VERSION, DEFAULT_KDF_PARAMS, type DeriveRawKeyOptions, type KdfParams, type KdfStrengthenOptions, argon2idRaw, deriveAesGcmKey, deriveHkdfAesGcmKey, deriveHkdfSha256Bits, deriveRawKey, generateSalt, importAesGcmKey };
@@ -0,0 +1,7 @@
1
+ export { CURRENT_KDF_VERSION, DEFAULT_KDF_PARAMS, argon2idRaw, deriveAesGcmKey, deriveHkdfAesGcmKey, deriveHkdfSha256Bits, deriveRawKey, generateSalt, importAesGcmKey } from '../chunk-OPHN2B3N.js';
2
+ import '../chunk-BUFRR5PB.js';
3
+ import '../chunk-JSKIWIEC.js';
4
+ import '../chunk-CYIGDF63.js';
5
+ import '../chunk-MJO7IJZC.js';
6
+ //# sourceMappingURL=index.js.map
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,69 @@
1
+ export { importAesGcmKey } from '../kdf/index.js';
2
+
3
+ /**
4
+ * dis-key-management — key hierarchy, wrapping, and rotation.
5
+ *
6
+ * Implements the two-tier key model used by Singra Vault:
7
+ * - A high-entropy random *content key* (the "UserKey") encrypts vault data.
8
+ * - The content key is wrapped under a *key-encryption key* (KEK) that is
9
+ * derived from the KDF output via HKDF-Expand (domain-separated `info`).
10
+ *
11
+ * Because the content key is independent of the password, changing the master
12
+ * password only re-wraps the content key — no vault data is re-encrypted. This
13
+ * is what makes {@link rotateWrappedKey} cheap and safe.
14
+ *
15
+ * Wrapped keys carry a stable, versioned prefix. The default scheme is byte
16
+ * compatible with Singra's `usk-wrap-v2:` envelope.
17
+ */
18
+
19
+ /** Describes how a content key is wrapped: envelope prefix + HKDF domain. */
20
+ interface KeyWrapScheme {
21
+ /** Stable envelope prefix written for new wraps, e.g. `usk-wrap-v2:`. */
22
+ readonly prefix: string;
23
+ /** HKDF-Expand `info` for deriving the KEK from KDF output. */
24
+ readonly hkdfInfo: string;
25
+ }
26
+ /**
27
+ * Default wrap scheme. Byte-compatible with Singra Vault so existing
28
+ * `encrypted_user_key` values decrypt unchanged. The `info` label is part of
29
+ * the format contract and must not be renamed without a new scheme version.
30
+ */
31
+ declare const DEFAULT_KEY_WRAP_SCHEME: KeyWrapScheme;
32
+
33
+ interface UserKeyBundle {
34
+ /** Wrapped content key: `<prefix><base64(IV||CT||tag)>`. */
35
+ readonly encryptedUserKey: string;
36
+ /** Non-extractable AES-GCM content key, ready for vault operations. */
37
+ readonly userKey: CryptoKey;
38
+ }
39
+ /** Generates fresh random content-key bytes (caller must wipe). */
40
+ declare function generateContentKeyBytes(): Uint8Array;
41
+ /**
42
+ * Creates a new random content key and wraps it under the KEK derived from
43
+ * `kdfOutputBytes`. For new accounts. The caller still owns `kdfOutputBytes`.
44
+ */
45
+ declare function createWrappedUserKey(kdfOutputBytes: Uint8Array, scheme?: KeyWrapScheme): Promise<UserKeyBundle>;
46
+ /** Unwraps a wrapped content key to raw bytes (caller must wipe). */
47
+ declare function unwrapUserKeyBytes(encryptedUserKey: string, kdfOutputBytes: Uint8Array, scheme?: KeyWrapScheme): Promise<Uint8Array>;
48
+ /** Unwraps a wrapped content key and imports it as an AES-GCM CryptoKey. */
49
+ declare function unwrapUserKey(encryptedUserKey: string, kdfOutputBytes: Uint8Array, scheme?: KeyWrapScheme): Promise<CryptoKey>;
50
+ /**
51
+ * Wraps a *deterministic* content key derived directly from `kdfOutputBytes`,
52
+ * for EXISTING accounts migrating to the two-tier key model. The content key
53
+ * equals the raw KDF output, so vault data previously encrypted directly under
54
+ * that output remains readable without re-encryption. The KEK is still
55
+ * domain-separated (HKDF `info`), so the wrapper is independent of the key.
56
+ */
57
+ declare function createDeterministicWrappedUserKey(kdfOutputBytes: Uint8Array, scheme?: KeyWrapScheme): Promise<UserKeyBundle>;
58
+ /** Generates a fresh AES-256-GCM key and returns it as a JWK JSON string. */
59
+ declare function generateAesGcmKeyJwk(): Promise<string>;
60
+ /** Imports an AES-256-GCM key from a JWK JSON string for the given usages. */
61
+ declare function importAesGcmKeyFromJwk(jwkString: string, usages: ReadonlyArray<KeyUsage>): Promise<CryptoKey>;
62
+ /**
63
+ * Re-wraps an existing content key under a new KDF output (new master password
64
+ * / new salt). The content key itself is unchanged, so NO vault data is
65
+ * re-encrypted — only the wrapper string changes.
66
+ */
67
+ declare function rotateWrappedKey(encryptedUserKey: string, oldKdfOutputBytes: Uint8Array, newKdfOutputBytes: Uint8Array, scheme?: KeyWrapScheme): Promise<string>;
68
+
69
+ export { DEFAULT_KEY_WRAP_SCHEME, type KeyWrapScheme, type UserKeyBundle, createDeterministicWrappedUserKey, createWrappedUserKey, generateAesGcmKeyJwk, generateContentKeyBytes, importAesGcmKeyFromJwk, rotateWrappedKey, unwrapUserKey, unwrapUserKeyBytes };
@@ -0,0 +1,10 @@
1
+ export { DEFAULT_KEY_WRAP_SCHEME, createDeterministicWrappedUserKey, createWrappedUserKey, generateAesGcmKeyJwk, generateContentKeyBytes, importAesGcmKeyFromJwk, rotateWrappedKey, unwrapUserKey, unwrapUserKeyBytes } from '../chunk-3DQPQCAR.js';
2
+ import '../chunk-3HCT6A2P.js';
3
+ export { importAesGcmKey } from '../chunk-OPHN2B3N.js';
4
+ import '../chunk-U65A4HIY.js';
5
+ import '../chunk-BUFRR5PB.js';
6
+ import '../chunk-JSKIWIEC.js';
7
+ import '../chunk-CYIGDF63.js';
8
+ import '../chunk-MJO7IJZC.js';
9
+ //# sourceMappingURL=index.js.map
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}