internxt-crypto 1.1.1 → 1.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 (62) hide show
  1. package/README.md +11 -7
  2. package/dist/constants.d.mts +4 -3
  3. package/dist/constants.d.mts.map +1 -1
  4. package/dist/constants.d.ts +4 -3
  5. package/dist/constants.d.ts.map +1 -1
  6. package/dist/constants.js +6 -4
  7. package/dist/constants.js.map +1 -1
  8. package/dist/constants.mjs +4 -3
  9. package/dist/constants.mjs.map +1 -1
  10. package/dist/derive-key.d.mts +8 -4
  11. package/dist/derive-key.d.mts.map +1 -1
  12. package/dist/derive-key.d.ts +8 -4
  13. package/dist/derive-key.d.ts.map +1 -1
  14. package/dist/derive-key.js +4 -4
  15. package/dist/derive-key.mjs +2 -2
  16. package/dist/derive-password.d.mts +7 -1
  17. package/dist/derive-password.d.mts.map +1 -1
  18. package/dist/derive-password.d.ts +7 -1
  19. package/dist/derive-password.d.ts.map +1 -1
  20. package/dist/derive-password.js +2 -1
  21. package/dist/derive-password.mjs +2 -2
  22. package/dist/deriveKeysFromMnemonic-DB0UHE-y.mjs +49 -0
  23. package/dist/deriveKeysFromMnemonic-DB0UHE-y.mjs.map +1 -0
  24. package/dist/{deriveKeysFromKey-GTRMuxDj.js → deriveKeysFromMnemonic-Dbx7VSBQ.js} +14 -9
  25. package/dist/deriveKeysFromMnemonic-Dbx7VSBQ.js.map +1 -0
  26. package/dist/{deriveKeysFromPassword-DXgSvTNC.mjs → deriveKeysFromPassword-DFzo2OII.mjs} +7 -7
  27. package/dist/{deriveKeysFromPassword-DXgSvTNC.mjs.map → deriveKeysFromPassword-DFzo2OII.mjs.map} +1 -1
  28. package/dist/{deriveKeysFromPassword-C7xAGGsh.js → deriveKeysFromPassword-iMHv-tIA.js} +12 -6
  29. package/dist/{deriveKeysFromPassword-C7xAGGsh.js.map → deriveKeysFromPassword-iMHv-tIA.js.map} +1 -1
  30. package/dist/email-crypto.d.mts +15 -1
  31. package/dist/email-crypto.d.mts.map +1 -1
  32. package/dist/email-crypto.d.ts +15 -1
  33. package/dist/email-crypto.d.ts.map +1 -1
  34. package/dist/email-crypto.js +3 -1
  35. package/dist/email-crypto.mjs +2 -2
  36. package/dist/emailEncryptionKey-Cw-vW_Oq.js +248 -0
  37. package/dist/emailEncryptionKey-Cw-vW_Oq.js.map +1 -0
  38. package/dist/emailEncryptionKey-D9sk_WKj.mjs +201 -0
  39. package/dist/emailEncryptionKey-D9sk_WKj.mjs.map +1 -0
  40. package/dist/{emailKeys-DWvKANTZ.js → emailKeys-BFI-paQq.js} +34 -2
  41. package/dist/emailKeys-BFI-paQq.js.map +1 -0
  42. package/dist/{emailKeys-nzn7U7HQ.mjs → emailKeys-BjIeINfC.mjs} +23 -3
  43. package/dist/{emailKeys-nzn7U7HQ.mjs.map → emailKeys-BjIeINfC.mjs.map} +1 -1
  44. package/dist/index.d.mts +6 -6
  45. package/dist/index.d.ts +6 -6
  46. package/dist/index.js +18 -9
  47. package/dist/index.mjs +6 -6
  48. package/dist/keystore-crypto.d.mts +42 -7
  49. package/dist/keystore-crypto.d.mts.map +1 -1
  50. package/dist/keystore-crypto.d.ts +42 -7
  51. package/dist/keystore-crypto.d.ts.map +1 -1
  52. package/dist/keystore-crypto.js +6 -1
  53. package/dist/keystore-crypto.mjs +2 -2
  54. package/package.json +1 -1
  55. package/dist/deriveKeysFromKey-CseBjg0n.mjs +0 -44
  56. package/dist/deriveKeysFromKey-CseBjg0n.mjs.map +0 -1
  57. package/dist/deriveKeysFromKey-GTRMuxDj.js.map +0 -1
  58. package/dist/emailEncryptionKey-F_YuJu1H.js +0 -144
  59. package/dist/emailEncryptionKey-F_YuJu1H.js.map +0 -1
  60. package/dist/emailEncryptionKey-kIsseFo6.mjs +0 -127
  61. package/dist/emailEncryptionKey-kIsseFo6.mjs.map +0 -1
  62. package/dist/emailKeys-DWvKANTZ.js.map +0 -1
package/README.md CHANGED
@@ -131,19 +131,19 @@ expect(decryptedEmail).toStrictEqual(email);
131
131
 
132
132
  // keystore
133
133
  const userEmail = 'user email';
134
- const secretKey = genSymmetricKey();
135
- const { encryptionKeystore, recoveryKeystore, recoveryCodes } = await createEncryptionAndRecoveryKeystores(
134
+ const password = 'user password';
135
+ const { encryptionKeystore, recoveryKeystore, recoveryCodes, salt } = await createEncryptionAndRecoveryKeystores(
136
136
  userEmail,
137
- secretKey,
137
+ password
138
138
  );
139
- const resultEnc = await openEncryptionKeystore(encryptionKeystore, secretKey);
139
+ const resultEnc = await openEncryptionKeystore(encryptionKeystore, password, salt);
140
140
  const resultRec = await openRecoveryKeystore(recoveryCodes, recoveryKeystore);
141
141
 
142
142
  expect(resultEnc).toStrictEqual(resultRec);
143
143
 
144
144
  // Email storage and search
145
145
 
146
- // Between sessions emails are stored encrypted in IndexedDB. The encryption key is derived from user's baseKey
146
+ // Between sessions emails are stored encrypted in IndexedDB. The encryption key is derived from user's mnemonic
147
147
  // During the session, all emails are decrypted and stored in the cache (up to 600 MB, if excides - we delete oldests emails)
148
148
  // For search, we build a search index from cache, then use Flexsearch for the search.
149
149
  // The search is doen separately for email content, subject, sender and recivers.
@@ -151,9 +151,13 @@ expect(resultEnc).toStrictEqual(resultRec);
151
151
  // Open IndexedDB database
152
152
  const userID = 'user ID';
153
153
  const db = await openDatabase(userID);
154
+ const mnemonic = genMnemonic();
154
155
 
155
- // Derive database key
156
- const key = await deriveDatabaseKey(baseKey);
156
+ // Derive key for encrypting emails before storing them in a local database
157
+ const key = await deriveDatabaseKey(mnemonic);
158
+
159
+ // Derive key for encrypting email draft
160
+ const key = await deriveDatabaseKey(mnemonic);
157
161
 
158
162
  // Encrypt and store one or several emails
159
163
  await encryptAndStoreEmail(email, key, db);
@@ -3,8 +3,9 @@ declare const AES_KEY_BYTE_LENGTH = 32;
3
3
  declare const IV_LEN_BYTES = 12;
4
4
  declare const CONTEXT_ENC_KEYSTORE = "CRYPTO library 2025-07-30 16:18:03 key for opening encryption keys keystore";
5
5
  declare const CONTEXT_RECOVERY = "CRYPTO library 2025-07-30 16:20:00 key for account recovery";
6
- declare const CONTEXT_INDEX = "CRYPTO library 2025-07-30 17:20:00 key for protecting current search indices";
7
- declare const CONTEXT_DERIVE = "CRYPTO library 2025-08-27 17:08:00 derive one key from two keys";
6
+ declare const CONTEXT_DATABASE = "CRYPTO library 2025-07-30 17:20:00 key for protecting current search indices";
7
+ declare const CONTEXT_DRAFT = "CRYPTO library 2026-04-23 10:56:00 key for protecting email drafts";
8
+ declare const CONTEXT_TWO_KEYS = "CRYPTO library 2025-08-27 17:08:00 derive one key from two keys";
8
9
  declare const ARGON2ID_PARALLELISM = 3;
9
10
  declare const ARGON2ID_ITERATIONS = 4;
10
11
  declare const ARGON2ID_MEMORY_SIZE = 65536;
@@ -22,5 +23,5 @@ declare const XWING_SECRET_KEY_LENGTH = 32;
22
23
  declare const XWING_SEED_BYTE_LENGTH = 32;
23
24
  declare const XWING_CIPHERTEXT_BYTE_LENGTH = 1120;
24
25
  //#endregion
25
- export { AES_KEY_BYTE_LENGTH, ARGON2ID_ITERATIONS, ARGON2ID_MEMORY_SIZE, ARGON2ID_OUTPUT_BYTE_LENGTH, ARGON2ID_PARALLELISM, ARGON2ID_SALT_BYTE_LENGTH, CONTEXT_DERIVE, CONTEXT_ENC_KEYSTORE, CONTEXT_INDEX, CONTEXT_RECOVERY, DB_LABEL, DB_VERSION, IV_LEN_BYTES, KYBER768_PUBLIC_KEY_LENGTH, KYBER768_SECRET_KEY_LENGTH, KYBER_SEED_LENGTH, MAX_CACHE_SIZE, MAX_EMAIL_PER_BATCH, XWING_CIPHERTEXT_BYTE_LENGTH, XWING_PUBLIC_KEY_LENGTH, XWING_SECRET_KEY_LENGTH, XWING_SEED_BYTE_LENGTH };
26
+ export { AES_KEY_BYTE_LENGTH, ARGON2ID_ITERATIONS, ARGON2ID_MEMORY_SIZE, ARGON2ID_OUTPUT_BYTE_LENGTH, ARGON2ID_PARALLELISM, ARGON2ID_SALT_BYTE_LENGTH, CONTEXT_DATABASE, CONTEXT_DRAFT, CONTEXT_ENC_KEYSTORE, CONTEXT_RECOVERY, CONTEXT_TWO_KEYS, DB_LABEL, DB_VERSION, IV_LEN_BYTES, KYBER768_PUBLIC_KEY_LENGTH, KYBER768_SECRET_KEY_LENGTH, KYBER_SEED_LENGTH, MAX_CACHE_SIZE, MAX_EMAIL_PER_BATCH, XWING_CIPHERTEXT_BYTE_LENGTH, XWING_PUBLIC_KEY_LENGTH, XWING_SECRET_KEY_LENGTH, XWING_SEED_BYTE_LENGTH };
26
27
  //# sourceMappingURL=constants.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.mts","names":[],"sources":["../src/constants.ts"],"mappings":";cAAa,mBAAA;AAAA,cACA,YAAA;AAAA,cAEA,oBAAA;AAAA,cACA,gBAAA;AAAA,cACA,aAAA;AAAA,cACA,cAAA;AAAA,cAGA,oBAAA;AAAA,cACA,mBAAA;AAAA,cACA,oBAAA;AAAA,cACA,yBAAA;AAAA,cACA,2BAAA;AAAA,cAEA,0BAAA;AAAA,cACA,0BAAA;AAAA,cACA,iBAAA;AAAA,cAEA,cAAA;AAAA,cACA,mBAAA;AAAA,cACA,QAAA;AAAA,cACA,UAAA;AAAA,cAEA,uBAAA;AAAA,cACA,uBAAA;AAAA,cACA,sBAAA;AAAA,cACA,4BAAA"}
1
+ {"version":3,"file":"constants.d.mts","names":[],"sources":["../src/constants.ts"],"mappings":";cAAa,mBAAA;AAAA,cACA,YAAA;AAAA,cAEA,oBAAA;AAAA,cACA,gBAAA;AAAA,cACA,gBAAA;AAAA,cACA,aAAA;AAAA,cACA,gBAAA;AAAA,cAGA,oBAAA;AAAA,cACA,mBAAA;AAAA,cACA,oBAAA;AAAA,cACA,yBAAA;AAAA,cACA,2BAAA;AAAA,cAEA,0BAAA;AAAA,cACA,0BAAA;AAAA,cACA,iBAAA;AAAA,cAEA,cAAA;AAAA,cACA,mBAAA;AAAA,cACA,QAAA;AAAA,cACA,UAAA;AAAA,cAEA,uBAAA;AAAA,cACA,uBAAA;AAAA,cACA,sBAAA;AAAA,cACA,4BAAA"}
@@ -3,8 +3,9 @@ declare const AES_KEY_BYTE_LENGTH = 32;
3
3
  declare const IV_LEN_BYTES = 12;
4
4
  declare const CONTEXT_ENC_KEYSTORE = "CRYPTO library 2025-07-30 16:18:03 key for opening encryption keys keystore";
5
5
  declare const CONTEXT_RECOVERY = "CRYPTO library 2025-07-30 16:20:00 key for account recovery";
6
- declare const CONTEXT_INDEX = "CRYPTO library 2025-07-30 17:20:00 key for protecting current search indices";
7
- declare const CONTEXT_DERIVE = "CRYPTO library 2025-08-27 17:08:00 derive one key from two keys";
6
+ declare const CONTEXT_DATABASE = "CRYPTO library 2025-07-30 17:20:00 key for protecting current search indices";
7
+ declare const CONTEXT_DRAFT = "CRYPTO library 2026-04-23 10:56:00 key for protecting email drafts";
8
+ declare const CONTEXT_TWO_KEYS = "CRYPTO library 2025-08-27 17:08:00 derive one key from two keys";
8
9
  declare const ARGON2ID_PARALLELISM = 3;
9
10
  declare const ARGON2ID_ITERATIONS = 4;
10
11
  declare const ARGON2ID_MEMORY_SIZE = 65536;
@@ -22,5 +23,5 @@ declare const XWING_SECRET_KEY_LENGTH = 32;
22
23
  declare const XWING_SEED_BYTE_LENGTH = 32;
23
24
  declare const XWING_CIPHERTEXT_BYTE_LENGTH = 1120;
24
25
  //#endregion
25
- export { AES_KEY_BYTE_LENGTH, ARGON2ID_ITERATIONS, ARGON2ID_MEMORY_SIZE, ARGON2ID_OUTPUT_BYTE_LENGTH, ARGON2ID_PARALLELISM, ARGON2ID_SALT_BYTE_LENGTH, CONTEXT_DERIVE, CONTEXT_ENC_KEYSTORE, CONTEXT_INDEX, CONTEXT_RECOVERY, DB_LABEL, DB_VERSION, IV_LEN_BYTES, KYBER768_PUBLIC_KEY_LENGTH, KYBER768_SECRET_KEY_LENGTH, KYBER_SEED_LENGTH, MAX_CACHE_SIZE, MAX_EMAIL_PER_BATCH, XWING_CIPHERTEXT_BYTE_LENGTH, XWING_PUBLIC_KEY_LENGTH, XWING_SECRET_KEY_LENGTH, XWING_SEED_BYTE_LENGTH };
26
+ export { AES_KEY_BYTE_LENGTH, ARGON2ID_ITERATIONS, ARGON2ID_MEMORY_SIZE, ARGON2ID_OUTPUT_BYTE_LENGTH, ARGON2ID_PARALLELISM, ARGON2ID_SALT_BYTE_LENGTH, CONTEXT_DATABASE, CONTEXT_DRAFT, CONTEXT_ENC_KEYSTORE, CONTEXT_RECOVERY, CONTEXT_TWO_KEYS, DB_LABEL, DB_VERSION, IV_LEN_BYTES, KYBER768_PUBLIC_KEY_LENGTH, KYBER768_SECRET_KEY_LENGTH, KYBER_SEED_LENGTH, MAX_CACHE_SIZE, MAX_EMAIL_PER_BATCH, XWING_CIPHERTEXT_BYTE_LENGTH, XWING_PUBLIC_KEY_LENGTH, XWING_SECRET_KEY_LENGTH, XWING_SEED_BYTE_LENGTH };
26
27
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","names":[],"sources":["../src/constants.ts"],"mappings":";cAAa,mBAAA;AAAA,cACA,YAAA;AAAA,cAEA,oBAAA;AAAA,cACA,gBAAA;AAAA,cACA,aAAA;AAAA,cACA,cAAA;AAAA,cAGA,oBAAA;AAAA,cACA,mBAAA;AAAA,cACA,oBAAA;AAAA,cACA,yBAAA;AAAA,cACA,2BAAA;AAAA,cAEA,0BAAA;AAAA,cACA,0BAAA;AAAA,cACA,iBAAA;AAAA,cAEA,cAAA;AAAA,cACA,mBAAA;AAAA,cACA,QAAA;AAAA,cACA,UAAA;AAAA,cAEA,uBAAA;AAAA,cACA,uBAAA;AAAA,cACA,sBAAA;AAAA,cACA,4BAAA"}
1
+ {"version":3,"file":"constants.d.ts","names":[],"sources":["../src/constants.ts"],"mappings":";cAAa,mBAAA;AAAA,cACA,YAAA;AAAA,cAEA,oBAAA;AAAA,cACA,gBAAA;AAAA,cACA,gBAAA;AAAA,cACA,aAAA;AAAA,cACA,gBAAA;AAAA,cAGA,oBAAA;AAAA,cACA,mBAAA;AAAA,cACA,oBAAA;AAAA,cACA,yBAAA;AAAA,cACA,2BAAA;AAAA,cAEA,0BAAA;AAAA,cACA,0BAAA;AAAA,cACA,iBAAA;AAAA,cAEA,cAAA;AAAA,cACA,mBAAA;AAAA,cACA,QAAA;AAAA,cACA,UAAA;AAAA,cAEA,uBAAA;AAAA,cACA,uBAAA;AAAA,cACA,sBAAA;AAAA,cACA,4BAAA"}
package/dist/constants.js CHANGED
@@ -5,8 +5,9 @@ const AES_KEY_BYTE_LENGTH = 32;
5
5
  const IV_LEN_BYTES = 12;
6
6
  const CONTEXT_ENC_KEYSTORE = "CRYPTO library 2025-07-30 16:18:03 key for opening encryption keys keystore";
7
7
  const CONTEXT_RECOVERY = "CRYPTO library 2025-07-30 16:20:00 key for account recovery";
8
- const CONTEXT_INDEX = "CRYPTO library 2025-07-30 17:20:00 key for protecting current search indices";
9
- const CONTEXT_DERIVE = "CRYPTO library 2025-08-27 17:08:00 derive one key from two keys";
8
+ const CONTEXT_DATABASE = "CRYPTO library 2025-07-30 17:20:00 key for protecting current search indices";
9
+ const CONTEXT_DRAFT = "CRYPTO library 2026-04-23 10:56:00 key for protecting email drafts";
10
+ const CONTEXT_TWO_KEYS = "CRYPTO library 2025-08-27 17:08:00 derive one key from two keys";
10
11
  const ARGON2ID_PARALLELISM = 3;
11
12
  const ARGON2ID_ITERATIONS = 4;
12
13
  const ARGON2ID_MEMORY_SIZE = 65536;
@@ -31,10 +32,11 @@ exports.ARGON2ID_MEMORY_SIZE = ARGON2ID_MEMORY_SIZE;
31
32
  exports.ARGON2ID_OUTPUT_BYTE_LENGTH = ARGON2ID_OUTPUT_BYTE_LENGTH;
32
33
  exports.ARGON2ID_PARALLELISM = ARGON2ID_PARALLELISM;
33
34
  exports.ARGON2ID_SALT_BYTE_LENGTH = ARGON2ID_SALT_BYTE_LENGTH;
34
- exports.CONTEXT_DERIVE = CONTEXT_DERIVE;
35
+ exports.CONTEXT_DATABASE = CONTEXT_DATABASE;
36
+ exports.CONTEXT_DRAFT = CONTEXT_DRAFT;
35
37
  exports.CONTEXT_ENC_KEYSTORE = CONTEXT_ENC_KEYSTORE;
36
- exports.CONTEXT_INDEX = CONTEXT_INDEX;
37
38
  exports.CONTEXT_RECOVERY = CONTEXT_RECOVERY;
39
+ exports.CONTEXT_TWO_KEYS = CONTEXT_TWO_KEYS;
38
40
  exports.DB_LABEL = DB_LABEL;
39
41
  exports.DB_VERSION = DB_VERSION;
40
42
  exports.IV_LEN_BYTES = IV_LEN_BYTES;
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","names":[],"sources":["../src/constants.ts"],"sourcesContent":["export const AES_KEY_BYTE_LENGTH = 32;\nexport const IV_LEN_BYTES = 12;\n\nexport const CONTEXT_ENC_KEYSTORE = 'CRYPTO library 2025-07-30 16:18:03 key for opening encryption keys keystore';\nexport const CONTEXT_RECOVERY = 'CRYPTO library 2025-07-30 16:20:00 key for account recovery';\nexport const CONTEXT_INDEX = 'CRYPTO library 2025-07-30 17:20:00 key for protecting current search indices';\nexport const CONTEXT_DERIVE = 'CRYPTO library 2025-08-27 17:08:00 derive one key from two keys';\n\n// Second recommended parameter set from RFC 9106\nexport const ARGON2ID_PARALLELISM = 3;\nexport const ARGON2ID_ITERATIONS = 4;\nexport const ARGON2ID_MEMORY_SIZE = 65536;\nexport const ARGON2ID_SALT_BYTE_LENGTH = 16;\nexport const ARGON2ID_OUTPUT_BYTE_LENGTH = 32;\n\nexport const KYBER768_PUBLIC_KEY_LENGTH = 1184;\nexport const KYBER768_SECRET_KEY_LENGTH = 2400;\nexport const KYBER_SEED_LENGTH = 64;\n\nexport const MAX_CACHE_SIZE = 600000000; // 600 MB\nexport const MAX_EMAIL_PER_BATCH = 100;\nexport const DB_LABEL = 'email';\nexport const DB_VERSION = 1;\n\nexport const XWING_PUBLIC_KEY_LENGTH = 1216;\nexport const XWING_SECRET_KEY_LENGTH = 32;\nexport const XWING_SEED_BYTE_LENGTH = 32;\nexport const XWING_CIPHERTEXT_BYTE_LENGTH = 1120;\n"],"mappings":";;;AAAA,MAAa,sBAAsB;AACnC,MAAa,eAAe;AAE5B,MAAa,uBAAuB;AACpC,MAAa,mBAAmB;AAChC,MAAa,gBAAgB;AAC7B,MAAa,iBAAiB;AAG9B,MAAa,uBAAuB;AACpC,MAAa,sBAAsB;AACnC,MAAa,uBAAuB;AACpC,MAAa,4BAA4B;AACzC,MAAa,8BAA8B;AAE3C,MAAa,6BAA6B;AAC1C,MAAa,6BAA6B;AAC1C,MAAa,oBAAoB;AAEjC,MAAa,iBAAiB;AAC9B,MAAa,sBAAsB;AACnC,MAAa,WAAW;AACxB,MAAa,aAAa;AAE1B,MAAa,0BAA0B;AACvC,MAAa,0BAA0B;AACvC,MAAa,yBAAyB;AACtC,MAAa,+BAA+B"}
1
+ {"version":3,"file":"constants.js","names":[],"sources":["../src/constants.ts"],"sourcesContent":["export const AES_KEY_BYTE_LENGTH = 32;\nexport const IV_LEN_BYTES = 12;\n\nexport const CONTEXT_ENC_KEYSTORE = 'CRYPTO library 2025-07-30 16:18:03 key for opening encryption keys keystore';\nexport const CONTEXT_RECOVERY = 'CRYPTO library 2025-07-30 16:20:00 key for account recovery';\nexport const CONTEXT_DATABASE = 'CRYPTO library 2025-07-30 17:20:00 key for protecting current search indices';\nexport const CONTEXT_DRAFT = 'CRYPTO library 2026-04-23 10:56:00 key for protecting email drafts';\nexport const CONTEXT_TWO_KEYS = 'CRYPTO library 2025-08-27 17:08:00 derive one key from two keys';\n\n// Second recommended parameter set from RFC 9106\nexport const ARGON2ID_PARALLELISM = 3;\nexport const ARGON2ID_ITERATIONS = 4;\nexport const ARGON2ID_MEMORY_SIZE = 65536;\nexport const ARGON2ID_SALT_BYTE_LENGTH = 16;\nexport const ARGON2ID_OUTPUT_BYTE_LENGTH = 32;\n\nexport const KYBER768_PUBLIC_KEY_LENGTH = 1184;\nexport const KYBER768_SECRET_KEY_LENGTH = 2400;\nexport const KYBER_SEED_LENGTH = 64;\n\nexport const MAX_CACHE_SIZE = 600000000; // 600 MB\nexport const MAX_EMAIL_PER_BATCH = 100;\nexport const DB_LABEL = 'email';\nexport const DB_VERSION = 1;\n\nexport const XWING_PUBLIC_KEY_LENGTH = 1216;\nexport const XWING_SECRET_KEY_LENGTH = 32;\nexport const XWING_SEED_BYTE_LENGTH = 32;\nexport const XWING_CIPHERTEXT_BYTE_LENGTH = 1120;\n"],"mappings":";;;AAAA,MAAa,sBAAsB;AACnC,MAAa,eAAe;AAE5B,MAAa,uBAAuB;AACpC,MAAa,mBAAmB;AAChC,MAAa,mBAAmB;AAChC,MAAa,gBAAgB;AAC7B,MAAa,mBAAmB;AAGhC,MAAa,uBAAuB;AACpC,MAAa,sBAAsB;AACnC,MAAa,uBAAuB;AACpC,MAAa,4BAA4B;AACzC,MAAa,8BAA8B;AAE3C,MAAa,6BAA6B;AAC1C,MAAa,6BAA6B;AAC1C,MAAa,oBAAoB;AAEjC,MAAa,iBAAiB;AAC9B,MAAa,sBAAsB;AACnC,MAAa,WAAW;AACxB,MAAa,aAAa;AAE1B,MAAa,0BAA0B;AACvC,MAAa,0BAA0B;AACvC,MAAa,yBAAyB;AACtC,MAAa,+BAA+B"}
@@ -3,8 +3,9 @@ const AES_KEY_BYTE_LENGTH = 32;
3
3
  const IV_LEN_BYTES = 12;
4
4
  const CONTEXT_ENC_KEYSTORE = "CRYPTO library 2025-07-30 16:18:03 key for opening encryption keys keystore";
5
5
  const CONTEXT_RECOVERY = "CRYPTO library 2025-07-30 16:20:00 key for account recovery";
6
- const CONTEXT_INDEX = "CRYPTO library 2025-07-30 17:20:00 key for protecting current search indices";
7
- const CONTEXT_DERIVE = "CRYPTO library 2025-08-27 17:08:00 derive one key from two keys";
6
+ const CONTEXT_DATABASE = "CRYPTO library 2025-07-30 17:20:00 key for protecting current search indices";
7
+ const CONTEXT_DRAFT = "CRYPTO library 2026-04-23 10:56:00 key for protecting email drafts";
8
+ const CONTEXT_TWO_KEYS = "CRYPTO library 2025-08-27 17:08:00 derive one key from two keys";
8
9
  const ARGON2ID_PARALLELISM = 3;
9
10
  const ARGON2ID_ITERATIONS = 4;
10
11
  const ARGON2ID_MEMORY_SIZE = 65536;
@@ -23,5 +24,5 @@ const XWING_SEED_BYTE_LENGTH = 32;
23
24
  const XWING_CIPHERTEXT_BYTE_LENGTH = 1120;
24
25
 
25
26
  //#endregion
26
- export { AES_KEY_BYTE_LENGTH, ARGON2ID_ITERATIONS, ARGON2ID_MEMORY_SIZE, ARGON2ID_OUTPUT_BYTE_LENGTH, ARGON2ID_PARALLELISM, ARGON2ID_SALT_BYTE_LENGTH, CONTEXT_DERIVE, CONTEXT_ENC_KEYSTORE, CONTEXT_INDEX, CONTEXT_RECOVERY, DB_LABEL, DB_VERSION, IV_LEN_BYTES, KYBER768_PUBLIC_KEY_LENGTH, KYBER768_SECRET_KEY_LENGTH, KYBER_SEED_LENGTH, MAX_CACHE_SIZE, MAX_EMAIL_PER_BATCH, XWING_CIPHERTEXT_BYTE_LENGTH, XWING_PUBLIC_KEY_LENGTH, XWING_SECRET_KEY_LENGTH, XWING_SEED_BYTE_LENGTH };
27
+ export { AES_KEY_BYTE_LENGTH, ARGON2ID_ITERATIONS, ARGON2ID_MEMORY_SIZE, ARGON2ID_OUTPUT_BYTE_LENGTH, ARGON2ID_PARALLELISM, ARGON2ID_SALT_BYTE_LENGTH, CONTEXT_DATABASE, CONTEXT_DRAFT, CONTEXT_ENC_KEYSTORE, CONTEXT_RECOVERY, CONTEXT_TWO_KEYS, DB_LABEL, DB_VERSION, IV_LEN_BYTES, KYBER768_PUBLIC_KEY_LENGTH, KYBER768_SECRET_KEY_LENGTH, KYBER_SEED_LENGTH, MAX_CACHE_SIZE, MAX_EMAIL_PER_BATCH, XWING_CIPHERTEXT_BYTE_LENGTH, XWING_PUBLIC_KEY_LENGTH, XWING_SECRET_KEY_LENGTH, XWING_SEED_BYTE_LENGTH };
27
28
  //# sourceMappingURL=constants.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.mjs","names":[],"sources":["../src/constants.ts"],"sourcesContent":["export const AES_KEY_BYTE_LENGTH = 32;\nexport const IV_LEN_BYTES = 12;\n\nexport const CONTEXT_ENC_KEYSTORE = 'CRYPTO library 2025-07-30 16:18:03 key for opening encryption keys keystore';\nexport const CONTEXT_RECOVERY = 'CRYPTO library 2025-07-30 16:20:00 key for account recovery';\nexport const CONTEXT_INDEX = 'CRYPTO library 2025-07-30 17:20:00 key for protecting current search indices';\nexport const CONTEXT_DERIVE = 'CRYPTO library 2025-08-27 17:08:00 derive one key from two keys';\n\n// Second recommended parameter set from RFC 9106\nexport const ARGON2ID_PARALLELISM = 3;\nexport const ARGON2ID_ITERATIONS = 4;\nexport const ARGON2ID_MEMORY_SIZE = 65536;\nexport const ARGON2ID_SALT_BYTE_LENGTH = 16;\nexport const ARGON2ID_OUTPUT_BYTE_LENGTH = 32;\n\nexport const KYBER768_PUBLIC_KEY_LENGTH = 1184;\nexport const KYBER768_SECRET_KEY_LENGTH = 2400;\nexport const KYBER_SEED_LENGTH = 64;\n\nexport const MAX_CACHE_SIZE = 600000000; // 600 MB\nexport const MAX_EMAIL_PER_BATCH = 100;\nexport const DB_LABEL = 'email';\nexport const DB_VERSION = 1;\n\nexport const XWING_PUBLIC_KEY_LENGTH = 1216;\nexport const XWING_SECRET_KEY_LENGTH = 32;\nexport const XWING_SEED_BYTE_LENGTH = 32;\nexport const XWING_CIPHERTEXT_BYTE_LENGTH = 1120;\n"],"mappings":";AAAA,MAAa,sBAAsB;AACnC,MAAa,eAAe;AAE5B,MAAa,uBAAuB;AACpC,MAAa,mBAAmB;AAChC,MAAa,gBAAgB;AAC7B,MAAa,iBAAiB;AAG9B,MAAa,uBAAuB;AACpC,MAAa,sBAAsB;AACnC,MAAa,uBAAuB;AACpC,MAAa,4BAA4B;AACzC,MAAa,8BAA8B;AAE3C,MAAa,6BAA6B;AAC1C,MAAa,6BAA6B;AAC1C,MAAa,oBAAoB;AAEjC,MAAa,iBAAiB;AAC9B,MAAa,sBAAsB;AACnC,MAAa,WAAW;AACxB,MAAa,aAAa;AAE1B,MAAa,0BAA0B;AACvC,MAAa,0BAA0B;AACvC,MAAa,yBAAyB;AACtC,MAAa,+BAA+B"}
1
+ {"version":3,"file":"constants.mjs","names":[],"sources":["../src/constants.ts"],"sourcesContent":["export const AES_KEY_BYTE_LENGTH = 32;\nexport const IV_LEN_BYTES = 12;\n\nexport const CONTEXT_ENC_KEYSTORE = 'CRYPTO library 2025-07-30 16:18:03 key for opening encryption keys keystore';\nexport const CONTEXT_RECOVERY = 'CRYPTO library 2025-07-30 16:20:00 key for account recovery';\nexport const CONTEXT_DATABASE = 'CRYPTO library 2025-07-30 17:20:00 key for protecting current search indices';\nexport const CONTEXT_DRAFT = 'CRYPTO library 2026-04-23 10:56:00 key for protecting email drafts';\nexport const CONTEXT_TWO_KEYS = 'CRYPTO library 2025-08-27 17:08:00 derive one key from two keys';\n\n// Second recommended parameter set from RFC 9106\nexport const ARGON2ID_PARALLELISM = 3;\nexport const ARGON2ID_ITERATIONS = 4;\nexport const ARGON2ID_MEMORY_SIZE = 65536;\nexport const ARGON2ID_SALT_BYTE_LENGTH = 16;\nexport const ARGON2ID_OUTPUT_BYTE_LENGTH = 32;\n\nexport const KYBER768_PUBLIC_KEY_LENGTH = 1184;\nexport const KYBER768_SECRET_KEY_LENGTH = 2400;\nexport const KYBER_SEED_LENGTH = 64;\n\nexport const MAX_CACHE_SIZE = 600000000; // 600 MB\nexport const MAX_EMAIL_PER_BATCH = 100;\nexport const DB_LABEL = 'email';\nexport const DB_VERSION = 1;\n\nexport const XWING_PUBLIC_KEY_LENGTH = 1216;\nexport const XWING_SECRET_KEY_LENGTH = 32;\nexport const XWING_SEED_BYTE_LENGTH = 32;\nexport const XWING_CIPHERTEXT_BYTE_LENGTH = 1120;\n"],"mappings":";AAAA,MAAa,sBAAsB;AACnC,MAAa,eAAe;AAE5B,MAAa,uBAAuB;AACpC,MAAa,mBAAmB;AAChC,MAAa,mBAAmB;AAChC,MAAa,gBAAgB;AAC7B,MAAa,mBAAmB;AAGhC,MAAa,uBAAuB;AACpC,MAAa,sBAAsB;AACnC,MAAa,uBAAuB;AACpC,MAAa,4BAA4B;AACzC,MAAa,8BAA8B;AAE3C,MAAa,6BAA6B;AAC1C,MAAa,6BAA6B;AAC1C,MAAa,oBAAoB;AAEjC,MAAa,iBAAiB;AAC9B,MAAa,sBAAsB;AACnC,MAAa,WAAW;AACxB,MAAa,aAAa;AAE1B,MAAa,0BAA0B;AACvC,MAAa,0BAA0B;AACvC,MAAa,yBAAyB;AACtC,MAAa,+BAA+B"}
@@ -16,13 +16,17 @@ declare function deriveSymmetricKeyFromContext(context: string, baseKey: Uint8Ar
16
16
  * @returns The derived secret key
17
17
  */
18
18
  declare function deriveSymmetricKeyFromTwoKeys(key1: Uint8Array, key2: Uint8Array): Uint8Array;
19
+ //#endregion
20
+ //#region src/derive-key/deriveKeysFromMnemonic.d.ts
19
21
  /**
20
- * Derives database encryption key for the given user
22
+ * Derives encryption key from the user's mnemonic and context string
21
23
  *
22
- * @param baseKey - The base key (NOT PASSWORD!)
24
+ * @param mnemonic - The user's mnemonic (machine-generated with secure PRNG)
25
+ * @param context - The context string.
26
+ * The context string should be hardcoded, globally unique, and application-specific.
23
27
  * @returns The symmetric key for protecting database
24
28
  */
25
- declare const deriveDatabaseKey: (baseKey: Uint8Array) => Promise<Uint8Array>;
29
+ declare const deriveKeyFromMnemonic: (mnemonic: string, context: string) => Promise<Uint8Array>;
26
30
  //#endregion
27
- export { deriveDatabaseKey, deriveSymmetricKeyFromContext, deriveSymmetricKeyFromTwoKeys };
31
+ export { deriveKeyFromMnemonic, deriveSymmetricKeyFromContext, deriveSymmetricKeyFromTwoKeys };
28
32
  //# sourceMappingURL=derive-key.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"derive-key.d.mts","names":[],"sources":["../src/derive-key/deriveKeysFromKey.ts"],"mappings":";;AAYA;;;;;;;iBAAgB,6BAAA,CAA8B,OAAA,UAAiB,OAAA,EAAS,UAAA,GAAa,UAAA;;;AAWrF;;;;;iBAAgB,6BAAA,CAA8B,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,UAAA,GAAa,UAAA;;;;;;;cAkBtE,iBAAA,GAA2B,OAAA,EAAS,UAAA,KAAa,OAAA,CAAQ,UAAA"}
1
+ {"version":3,"file":"derive-key.d.mts","names":[],"sources":["../src/derive-key/deriveKeysFromKey.ts","../src/derive-key/deriveKeysFromMnemonic.ts"],"mappings":";;AAYA;;;;;;;iBAAgB,6BAAA,CAA8B,OAAA,UAAiB,OAAA,EAAS,UAAA,GAAa,UAAA;;;AAWrF;;;;;iBAAgB,6BAAA,CAA8B,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,UAAA,GAAa,UAAA;;;;AAXnF;;;;;;;cCDa,qBAAA,GAA+B,QAAA,UAAkB,OAAA,aAAkB,OAAA,CAAQ,UAAA"}
@@ -16,13 +16,17 @@ declare function deriveSymmetricKeyFromContext(context: string, baseKey: Uint8Ar
16
16
  * @returns The derived secret key
17
17
  */
18
18
  declare function deriveSymmetricKeyFromTwoKeys(key1: Uint8Array, key2: Uint8Array): Uint8Array;
19
+ //#endregion
20
+ //#region src/derive-key/deriveKeysFromMnemonic.d.ts
19
21
  /**
20
- * Derives database encryption key for the given user
22
+ * Derives encryption key from the user's mnemonic and context string
21
23
  *
22
- * @param baseKey - The base key (NOT PASSWORD!)
24
+ * @param mnemonic - The user's mnemonic (machine-generated with secure PRNG)
25
+ * @param context - The context string.
26
+ * The context string should be hardcoded, globally unique, and application-specific.
23
27
  * @returns The symmetric key for protecting database
24
28
  */
25
- declare const deriveDatabaseKey: (baseKey: Uint8Array) => Promise<Uint8Array>;
29
+ declare const deriveKeyFromMnemonic: (mnemonic: string, context: string) => Promise<Uint8Array>;
26
30
  //#endregion
27
- export { deriveDatabaseKey, deriveSymmetricKeyFromContext, deriveSymmetricKeyFromTwoKeys };
31
+ export { deriveKeyFromMnemonic, deriveSymmetricKeyFromContext, deriveSymmetricKeyFromTwoKeys };
28
32
  //# sourceMappingURL=derive-key.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"derive-key.d.ts","names":[],"sources":["../src/derive-key/deriveKeysFromKey.ts"],"mappings":";;AAYA;;;;;;;iBAAgB,6BAAA,CAA8B,OAAA,UAAiB,OAAA,EAAS,UAAA,GAAa,UAAA;;;AAWrF;;;;;iBAAgB,6BAAA,CAA8B,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,UAAA,GAAa,UAAA;;;;;;;cAkBtE,iBAAA,GAA2B,OAAA,EAAS,UAAA,KAAa,OAAA,CAAQ,UAAA"}
1
+ {"version":3,"file":"derive-key.d.ts","names":[],"sources":["../src/derive-key/deriveKeysFromKey.ts","../src/derive-key/deriveKeysFromMnemonic.ts"],"mappings":";;AAYA;;;;;;;iBAAgB,6BAAA,CAA8B,OAAA,UAAiB,OAAA,EAAS,UAAA,GAAa,UAAA;;;AAWrF;;;;;iBAAgB,6BAAA,CAA8B,IAAA,EAAM,UAAA,EAAY,IAAA,EAAM,UAAA,GAAa,UAAA;;;;AAXnF;;;;;;;cCDa,qBAAA,GAA+B,QAAA,UAAkB,OAAA,aAAkB,OAAA,CAAQ,UAAA"}
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_deriveKeysFromKey = require('./deriveKeysFromKey-GTRMuxDj.js');
2
+ const require_deriveKeysFromMnemonic = require('./deriveKeysFromMnemonic-Dbx7VSBQ.js');
3
3
 
4
- exports.deriveDatabaseKey = require_deriveKeysFromKey.deriveDatabaseKey;
5
- exports.deriveSymmetricKeyFromContext = require_deriveKeysFromKey.deriveSymmetricKeyFromContext;
6
- exports.deriveSymmetricKeyFromTwoKeys = require_deriveKeysFromKey.deriveSymmetricKeyFromTwoKeys;
4
+ exports.deriveKeyFromMnemonic = require_deriveKeysFromMnemonic.deriveKeyFromMnemonic;
5
+ exports.deriveSymmetricKeyFromContext = require_deriveKeysFromMnemonic.deriveSymmetricKeyFromContext;
6
+ exports.deriveSymmetricKeyFromTwoKeys = require_deriveKeysFromMnemonic.deriveSymmetricKeyFromTwoKeys;
@@ -1,3 +1,3 @@
1
- import { n as deriveSymmetricKeyFromContext, r as deriveSymmetricKeyFromTwoKeys, t as deriveDatabaseKey } from "./deriveKeysFromKey-CseBjg0n.mjs";
1
+ import { n as deriveSymmetricKeyFromContext, r as deriveSymmetricKeyFromTwoKeys, t as deriveKeyFromMnemonic } from "./deriveKeysFromMnemonic-DB0UHE-y.mjs";
2
2
 
3
- export { deriveDatabaseKey, deriveSymmetricKeyFromContext, deriveSymmetricKeyFromTwoKeys };
3
+ export { deriveKeyFromMnemonic, deriveSymmetricKeyFromContext, deriveSymmetricKeyFromTwoKeys };
@@ -1,4 +1,10 @@
1
1
  //#region src/derive-password/deriveKeysFromPassword.d.ts
2
+ /**
3
+ * Samples a salt
4
+ *
5
+ * @returns The salt
6
+ */
7
+ declare function generateSalt(): Uint8Array;
2
8
  /**
3
9
  * Derives a symmetric key from a user's password with a randomly sampled salt
4
10
  *
@@ -18,5 +24,5 @@ declare function getKeyFromPassword(password: string): Promise<{
18
24
  */
19
25
  declare function getKeyFromPasswordAndSalt(password: string, salt: Uint8Array): Promise<Uint8Array>;
20
26
  //#endregion
21
- export { getKeyFromPassword, getKeyFromPasswordAndSalt };
27
+ export { generateSalt, getKeyFromPassword, getKeyFromPasswordAndSalt };
22
28
  //# sourceMappingURL=derive-password.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"derive-password.d.mts","names":[],"sources":["../src/derive-password/deriveKeysFromPassword.ts"],"mappings":";;AAQA;;;;;iBAAsB,kBAAA,CAAmB,QAAA,WAAmB,OAAA;EAAU,GAAA,EAAK,UAAA;EAAY,IAAA,EAAM,UAAA;AAAA;;;;;;;;iBAiBvE,yBAAA,CAA0B,QAAA,UAAkB,IAAA,EAAM,UAAA,GAAa,OAAA,CAAQ,UAAA"}
1
+ {"version":3,"file":"derive-password.d.mts","names":[],"sources":["../src/derive-password/deriveKeysFromPassword.ts"],"mappings":";;AASA;;;;iBAAgB,YAAA,CAAA,GAAgB,UAAA;AAUhC;;;;;;AAAA,iBAAsB,kBAAA,CAAmB,QAAA,WAAmB,OAAA;EAAU,GAAA,EAAK,UAAA;EAAY,IAAA,EAAM,UAAA;AAAA;;;;;;;AAiB7F;iBAAsB,yBAAA,CAA0B,QAAA,UAAkB,IAAA,EAAM,UAAA,GAAa,OAAA,CAAQ,UAAA"}
@@ -1,4 +1,10 @@
1
1
  //#region src/derive-password/deriveKeysFromPassword.d.ts
2
+ /**
3
+ * Samples a salt
4
+ *
5
+ * @returns The salt
6
+ */
7
+ declare function generateSalt(): Uint8Array;
2
8
  /**
3
9
  * Derives a symmetric key from a user's password with a randomly sampled salt
4
10
  *
@@ -18,5 +24,5 @@ declare function getKeyFromPassword(password: string): Promise<{
18
24
  */
19
25
  declare function getKeyFromPasswordAndSalt(password: string, salt: Uint8Array): Promise<Uint8Array>;
20
26
  //#endregion
21
- export { getKeyFromPassword, getKeyFromPasswordAndSalt };
27
+ export { generateSalt, getKeyFromPassword, getKeyFromPasswordAndSalt };
22
28
  //# sourceMappingURL=derive-password.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"derive-password.d.ts","names":[],"sources":["../src/derive-password/deriveKeysFromPassword.ts"],"mappings":";;AAQA;;;;;iBAAsB,kBAAA,CAAmB,QAAA,WAAmB,OAAA;EAAU,GAAA,EAAK,UAAA;EAAY,IAAA,EAAM,UAAA;AAAA;;;;;;;;iBAiBvE,yBAAA,CAA0B,QAAA,UAAkB,IAAA,EAAM,UAAA,GAAa,OAAA,CAAQ,UAAA"}
1
+ {"version":3,"file":"derive-password.d.ts","names":[],"sources":["../src/derive-password/deriveKeysFromPassword.ts"],"mappings":";;AASA;;;;iBAAgB,YAAA,CAAA,GAAgB,UAAA;AAUhC;;;;;;AAAA,iBAAsB,kBAAA,CAAmB,QAAA,WAAmB,OAAA;EAAU,GAAA,EAAK,UAAA;EAAY,IAAA,EAAM,UAAA;AAAA;;;;;;;AAiB7F;iBAAsB,yBAAA,CAA0B,QAAA,UAAkB,IAAA,EAAM,UAAA,GAAa,OAAA,CAAQ,UAAA"}
@@ -1,5 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_deriveKeysFromPassword = require('./deriveKeysFromPassword-C7xAGGsh.js');
2
+ const require_deriveKeysFromPassword = require('./deriveKeysFromPassword-iMHv-tIA.js');
3
3
 
4
+ exports.generateSalt = require_deriveKeysFromPassword.generateSalt;
4
5
  exports.getKeyFromPassword = require_deriveKeysFromPassword.getKeyFromPassword;
5
6
  exports.getKeyFromPasswordAndSalt = require_deriveKeysFromPassword.getKeyFromPasswordAndSalt;
@@ -1,3 +1,3 @@
1
- import { n as getKeyFromPasswordAndSalt, t as getKeyFromPassword } from "./deriveKeysFromPassword-DXgSvTNC.mjs";
1
+ import { n as getKeyFromPassword, r as getKeyFromPasswordAndSalt, t as generateSalt } from "./deriveKeysFromPassword-DFzo2OII.mjs";
2
2
 
3
- export { getKeyFromPassword, getKeyFromPasswordAndSalt };
3
+ export { generateSalt, getKeyFromPassword, getKeyFromPasswordAndSalt };
@@ -0,0 +1,49 @@
1
+ import { AES_KEY_BYTE_LENGTH, CONTEXT_TWO_KEYS } from "./constants.mjs";
2
+ import { o as mnemonicToBytes, s as UTF8ToUint8 } from "./genID-D08K7JPr.mjs";
3
+ import { blake3 } from "@noble/hashes/blake3.js";
4
+
5
+ //#region src/derive-key/deriveKeysFromKey.ts
6
+ /**
7
+ * Derives a symmetric key from the base key and context string
8
+ *
9
+ * @param context - The context string.
10
+ * The context string should be hardcoded, globally unique, and application-specific.
11
+ * @param baseKey - The base key (NOT PASSWORD!)
12
+ * @returns The derived secret key
13
+ */
14
+ function deriveSymmetricKeyFromContext(context, baseKey) {
15
+ return blake3(baseKey, { context: UTF8ToUint8(context) });
16
+ }
17
+ /**
18
+ * Derives a symmetric key from two keys
19
+ *
20
+ * @param key1 - The 32-bytes key
21
+ * @param key2 - The 32-bytes key
22
+ * @returns The derived secret key
23
+ */
24
+ function deriveSymmetricKeyFromTwoKeys(key1, key2) {
25
+ try {
26
+ if (key2.length !== AES_KEY_BYTE_LENGTH || key1.length !== AES_KEY_BYTE_LENGTH) throw new Error(`Input key length must be exactly ${AES_KEY_BYTE_LENGTH} bytes`);
27
+ return deriveSymmetricKeyFromContext(CONTEXT_TWO_KEYS, blake3(key1, { key: key2 }));
28
+ } catch (error) {
29
+ throw new Error("Failed to derive symmetric key from two keys and context", { cause: error });
30
+ }
31
+ }
32
+
33
+ //#endregion
34
+ //#region src/derive-key/deriveKeysFromMnemonic.ts
35
+ /**
36
+ * Derives encryption key from the user's mnemonic and context string
37
+ *
38
+ * @param mnemonic - The user's mnemonic (machine-generated with secure PRNG)
39
+ * @param context - The context string.
40
+ * The context string should be hardcoded, globally unique, and application-specific.
41
+ * @returns The symmetric key for protecting database
42
+ */
43
+ const deriveKeyFromMnemonic = async (mnemonic, context) => {
44
+ return deriveSymmetricKeyFromContext(context, mnemonicToBytes(mnemonic));
45
+ };
46
+
47
+ //#endregion
48
+ export { deriveSymmetricKeyFromContext as n, deriveSymmetricKeyFromTwoKeys as r, deriveKeyFromMnemonic as t };
49
+ //# sourceMappingURL=deriveKeysFromMnemonic-DB0UHE-y.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deriveKeysFromMnemonic-DB0UHE-y.mjs","names":[],"sources":["../src/derive-key/deriveKeysFromKey.ts","../src/derive-key/deriveKeysFromMnemonic.ts"],"sourcesContent":["import { blake3 } from '@noble/hashes/blake3.js';\nimport { AES_KEY_BYTE_LENGTH, CONTEXT_TWO_KEYS } from '../constants';\nimport { UTF8ToUint8 } from '../utils';\n\n/**\n * Derives a symmetric key from the base key and context string\n *\n * @param context - The context string.\n * The context string should be hardcoded, globally unique, and application-specific.\n * @param baseKey - The base key (NOT PASSWORD!)\n * @returns The derived secret key\n */\nexport function deriveSymmetricKeyFromContext(context: string, baseKey: Uint8Array): Uint8Array {\n return blake3(baseKey, { context: UTF8ToUint8(context) });\n}\n\n/**\n * Derives a symmetric key from two keys\n *\n * @param key1 - The 32-bytes key\n * @param key2 - The 32-bytes key\n * @returns The derived secret key\n */\nexport function deriveSymmetricKeyFromTwoKeys(key1: Uint8Array, key2: Uint8Array): Uint8Array {\n try {\n if (key2.length !== AES_KEY_BYTE_LENGTH || key1.length !== AES_KEY_BYTE_LENGTH) {\n throw new Error(`Input key length must be exactly ${AES_KEY_BYTE_LENGTH} bytes`);\n }\n const key = blake3(key1, { key: key2 });\n return deriveSymmetricKeyFromContext(CONTEXT_TWO_KEYS, key);\n } catch (error) {\n throw new Error('Failed to derive symmetric key from two keys and context', { cause: error });\n }\n}\n","import { mnemonicToBytes } from '../utils';\nimport { deriveSymmetricKeyFromContext } from './deriveKeysFromKey';\n\n/**\n * Derives encryption key from the user's mnemonic and context string\n *\n * @param mnemonic - The user's mnemonic (machine-generated with secure PRNG)\n * @param context - The context string.\n * The context string should be hardcoded, globally unique, and application-specific.\n * @returns The symmetric key for protecting database\n */\nexport const deriveKeyFromMnemonic = async (mnemonic: string, context: string): Promise<Uint8Array> => {\n // mnemonic is always machine-generated with secure PRNG, so it is safe to convert it to bytes without additional processing\n const entropy = mnemonicToBytes(mnemonic);\n return deriveSymmetricKeyFromContext(context, entropy);\n};\n"],"mappings":";;;;;;;;;;;;;AAYA,SAAgB,8BAA8B,SAAiB,SAAiC;AAC9F,QAAO,OAAO,SAAS,EAAE,SAAS,YAAY,QAAQ,EAAE,CAAC;;;;;;;;;AAU3D,SAAgB,8BAA8B,MAAkB,MAA8B;AAC5F,KAAI;AACF,MAAI,KAAK,WAAW,uBAAuB,KAAK,WAAW,oBACzD,OAAM,IAAI,MAAM,oCAAoC,oBAAoB,QAAQ;AAGlF,SAAO,8BAA8B,kBADzB,OAAO,MAAM,EAAE,KAAK,MAAM,CAAC,CACoB;UACpD,OAAO;AACd,QAAM,IAAI,MAAM,4DAA4D,EAAE,OAAO,OAAO,CAAC;;;;;;;;;;;;;;ACpBjG,MAAa,wBAAwB,OAAO,UAAkB,YAAyC;AAGrG,QAAO,8BAA8B,SADrB,gBAAgB,SAAS,CACa"}
@@ -24,27 +24,32 @@ function deriveSymmetricKeyFromContext(context, baseKey) {
24
24
  */
25
25
  function deriveSymmetricKeyFromTwoKeys(key1, key2) {
26
26
  try {
27
- if (key2.length != require_constants.AES_KEY_BYTE_LENGTH || key1.length != require_constants.AES_KEY_BYTE_LENGTH) throw new Error(`Input key length must be exactly ${require_constants.AES_KEY_BYTE_LENGTH} bytes`);
28
- return deriveSymmetricKeyFromContext(require_constants.CONTEXT_DERIVE, (0, _noble_hashes_blake3_js.blake3)(key1, { key: key2 }));
27
+ if (key2.length !== require_constants.AES_KEY_BYTE_LENGTH || key1.length !== require_constants.AES_KEY_BYTE_LENGTH) throw new Error(`Input key length must be exactly ${require_constants.AES_KEY_BYTE_LENGTH} bytes`);
28
+ return deriveSymmetricKeyFromContext(require_constants.CONTEXT_TWO_KEYS, (0, _noble_hashes_blake3_js.blake3)(key1, { key: key2 }));
29
29
  } catch (error) {
30
30
  throw new Error("Failed to derive symmetric key from two keys and context", { cause: error });
31
31
  }
32
32
  }
33
+
34
+ //#endregion
35
+ //#region src/derive-key/deriveKeysFromMnemonic.ts
33
36
  /**
34
- * Derives database encryption key for the given user
37
+ * Derives encryption key from the user's mnemonic and context string
35
38
  *
36
- * @param baseKey - The base key (NOT PASSWORD!)
39
+ * @param mnemonic - The user's mnemonic (machine-generated with secure PRNG)
40
+ * @param context - The context string.
41
+ * The context string should be hardcoded, globally unique, and application-specific.
37
42
  * @returns The symmetric key for protecting database
38
43
  */
39
- const deriveDatabaseKey = async (baseKey) => {
40
- return deriveSymmetricKeyFromContext(require_constants.CONTEXT_INDEX, baseKey);
44
+ const deriveKeyFromMnemonic = async (mnemonic, context) => {
45
+ return deriveSymmetricKeyFromContext(context, require_genID.mnemonicToBytes(mnemonic));
41
46
  };
42
47
 
43
48
  //#endregion
44
- Object.defineProperty(exports, 'deriveDatabaseKey', {
49
+ Object.defineProperty(exports, 'deriveKeyFromMnemonic', {
45
50
  enumerable: true,
46
51
  get: function () {
47
- return deriveDatabaseKey;
52
+ return deriveKeyFromMnemonic;
48
53
  }
49
54
  });
50
55
  Object.defineProperty(exports, 'deriveSymmetricKeyFromContext', {
@@ -59,4 +64,4 @@ Object.defineProperty(exports, 'deriveSymmetricKeyFromTwoKeys', {
59
64
  return deriveSymmetricKeyFromTwoKeys;
60
65
  }
61
66
  });
62
- //# sourceMappingURL=deriveKeysFromKey-GTRMuxDj.js.map
67
+ //# sourceMappingURL=deriveKeysFromMnemonic-Dbx7VSBQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deriveKeysFromMnemonic-Dbx7VSBQ.js","names":["UTF8ToUint8","AES_KEY_BYTE_LENGTH","CONTEXT_TWO_KEYS","mnemonicToBytes"],"sources":["../src/derive-key/deriveKeysFromKey.ts","../src/derive-key/deriveKeysFromMnemonic.ts"],"sourcesContent":["import { blake3 } from '@noble/hashes/blake3.js';\nimport { AES_KEY_BYTE_LENGTH, CONTEXT_TWO_KEYS } from '../constants';\nimport { UTF8ToUint8 } from '../utils';\n\n/**\n * Derives a symmetric key from the base key and context string\n *\n * @param context - The context string.\n * The context string should be hardcoded, globally unique, and application-specific.\n * @param baseKey - The base key (NOT PASSWORD!)\n * @returns The derived secret key\n */\nexport function deriveSymmetricKeyFromContext(context: string, baseKey: Uint8Array): Uint8Array {\n return blake3(baseKey, { context: UTF8ToUint8(context) });\n}\n\n/**\n * Derives a symmetric key from two keys\n *\n * @param key1 - The 32-bytes key\n * @param key2 - The 32-bytes key\n * @returns The derived secret key\n */\nexport function deriveSymmetricKeyFromTwoKeys(key1: Uint8Array, key2: Uint8Array): Uint8Array {\n try {\n if (key2.length !== AES_KEY_BYTE_LENGTH || key1.length !== AES_KEY_BYTE_LENGTH) {\n throw new Error(`Input key length must be exactly ${AES_KEY_BYTE_LENGTH} bytes`);\n }\n const key = blake3(key1, { key: key2 });\n return deriveSymmetricKeyFromContext(CONTEXT_TWO_KEYS, key);\n } catch (error) {\n throw new Error('Failed to derive symmetric key from two keys and context', { cause: error });\n }\n}\n","import { mnemonicToBytes } from '../utils';\nimport { deriveSymmetricKeyFromContext } from './deriveKeysFromKey';\n\n/**\n * Derives encryption key from the user's mnemonic and context string\n *\n * @param mnemonic - The user's mnemonic (machine-generated with secure PRNG)\n * @param context - The context string.\n * The context string should be hardcoded, globally unique, and application-specific.\n * @returns The symmetric key for protecting database\n */\nexport const deriveKeyFromMnemonic = async (mnemonic: string, context: string): Promise<Uint8Array> => {\n // mnemonic is always machine-generated with secure PRNG, so it is safe to convert it to bytes without additional processing\n const entropy = mnemonicToBytes(mnemonic);\n return deriveSymmetricKeyFromContext(context, entropy);\n};\n"],"mappings":";;;;;;;;;;;;;;AAYA,SAAgB,8BAA8B,SAAiB,SAAiC;AAC9F,4CAAc,SAAS,EAAE,SAASA,0BAAY,QAAQ,EAAE,CAAC;;;;;;;;;AAU3D,SAAgB,8BAA8B,MAAkB,MAA8B;AAC5F,KAAI;AACF,MAAI,KAAK,WAAWC,yCAAuB,KAAK,WAAWA,sCACzD,OAAM,IAAI,MAAM,oCAAoCA,sCAAoB,QAAQ;AAGlF,SAAO,8BAA8BC,wEADlB,MAAM,EAAE,KAAK,MAAM,CAAC,CACoB;UACpD,OAAO;AACd,QAAM,IAAI,MAAM,4DAA4D,EAAE,OAAO,OAAO,CAAC;;;;;;;;;;;;;;ACpBjG,MAAa,wBAAwB,OAAO,UAAkB,YAAyC;AAGrG,QAAO,8BAA8B,SADrBC,8BAAgB,SAAS,CACa"}
@@ -563,17 +563,17 @@ async function argon2(password, salt, parallelism = ARGON2ID_PARALLELISM, iterat
563
563
  outputType: "binary"
564
564
  });
565
565
  }
566
+
567
+ //#endregion
568
+ //#region src/derive-password/deriveKeysFromPassword.ts
566
569
  /**
567
570
  * Samples a salt
568
571
  *
569
572
  * @returns The salt
570
573
  */
571
- function sampleSalt() {
574
+ function generateSalt() {
572
575
  return randomBytes(ARGON2ID_SALT_BYTE_LENGTH);
573
576
  }
574
-
575
- //#endregion
576
- //#region src/derive-password/deriveKeysFromPassword.ts
577
577
  /**
578
578
  * Derives a symmetric key from a user's password with a randomly sampled salt
579
579
  *
@@ -582,7 +582,7 @@ function sampleSalt() {
582
582
  */
583
583
  async function getKeyFromPassword(password) {
584
584
  try {
585
- const salt = sampleSalt();
585
+ const salt = generateSalt();
586
586
  return {
587
587
  key: await argon2(password, salt),
588
588
  salt
@@ -607,5 +607,5 @@ async function getKeyFromPasswordAndSalt(password, salt) {
607
607
  }
608
608
 
609
609
  //#endregion
610
- export { getKeyFromPasswordAndSalt as n, getKeyFromPassword as t };
611
- //# sourceMappingURL=deriveKeysFromPassword-DXgSvTNC.mjs.map
610
+ export { getKeyFromPassword as n, getKeyFromPasswordAndSalt as r, generateSalt as t };
611
+ //# sourceMappingURL=deriveKeysFromPassword-DFzo2OII.mjs.map