internxt-crypto 0.0.11 → 0.0.14
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.
- package/dist/{symmetric-crypto-CrdS1Che.mjs → aes-DCb9dJqb.mjs} +10 -46
- package/dist/aes-DCb9dJqb.mjs.map +1 -0
- package/dist/{symmetric-crypto-D65zB396.js → aes-DQo1MyCz.js} +13 -54
- package/dist/aes-DQo1MyCz.js.map +1 -0
- package/dist/asymmetric-crypto.d.mts +1 -4
- package/dist/asymmetric-crypto.d.mts.map +1 -0
- package/dist/asymmetric-crypto.d.ts +1 -4
- package/dist/asymmetric-crypto.d.ts.map +1 -0
- package/dist/asymmetric-crypto.js +8 -7
- package/dist/asymmetric-crypto.mjs +1 -1
- package/dist/{chunk-DWirmd9C.mjs → chunk-DQk6qfdC.mjs} +3 -3
- package/dist/{chunk-Dt-PWiN7.js → chunk-EbLFQX5m.js} +3 -3
- package/dist/constants.d.mts +5 -5
- package/dist/constants.d.mts.map +1 -0
- package/dist/constants.d.ts +5 -5
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +63 -30
- package/dist/constants.js.map +1 -0
- package/dist/constants.mjs +33 -2
- package/dist/constants.mjs.map +1 -0
- package/dist/derive-key.d.mts +1 -4
- package/dist/derive-key.d.mts.map +1 -0
- package/dist/derive-key.d.ts +1 -4
- package/dist/derive-key.d.ts.map +1 -0
- package/dist/derive-key.js +12 -14
- package/dist/derive-key.mjs +1 -4
- package/dist/{derive-key-CBf2WxJd.js → deriveKeysFromPassword-BYaiSGKL.js} +26 -52
- package/dist/deriveKeysFromPassword-BYaiSGKL.js.map +1 -0
- package/dist/{derive-key-Be7hS-cN.mjs → deriveKeysFromPassword-XIwzErlL.mjs} +7 -28
- package/dist/deriveKeysFromPassword-XIwzErlL.mjs.map +1 -0
- package/dist/email-crypto.d.mts +2 -5
- package/dist/email-crypto.d.mts.map +1 -0
- package/dist/email-crypto.d.ts +2 -5
- package/dist/email-crypto.d.ts.map +1 -0
- package/dist/email-crypto.js +12 -16
- package/dist/email-crypto.mjs +1 -6
- package/dist/email-search.d.mts +20 -23
- package/dist/email-search.d.mts.map +1 -0
- package/dist/email-search.d.ts +20 -23
- package/dist/email-search.d.ts.map +1 -0
- package/dist/email-search.js +25 -63
- package/dist/email-search.js.map +1 -1
- package/dist/email-search.mjs +17 -51
- package/dist/email-search.mjs.map +1 -1
- package/dist/{keystore-crypto-Bjgriq9h.mjs → emailEncryptionKey-B9xHw1h_.mjs} +12 -21
- package/dist/emailEncryptionKey-B9xHw1h_.mjs.map +1 -0
- package/dist/{keystore-crypto-B4yCVo9l.js → emailEncryptionKey-CQNe5W_T.js} +25 -40
- package/dist/emailEncryptionKey-CQNe5W_T.js.map +1 -0
- package/dist/{email-crypto-BrT98taw.js → emailKeys-C0KhtfNP.js} +67 -112
- package/dist/emailKeys-C0KhtfNP.js.map +1 -0
- package/dist/{email-crypto-DJUEjTxA.mjs → emailKeys-D4lp9NRv.mjs} +29 -75
- package/dist/emailKeys-D4lp9NRv.mjs.map +1 -0
- package/dist/{utils-DS04iUcX.mjs → genID-3Er5IowC.mjs} +4 -24
- package/dist/genID-3Er5IowC.mjs.map +1 -0
- package/dist/{utils-CNs3cyDj.js → genID-YJSl3YhL.js} +6 -31
- package/dist/genID-YJSl3YhL.js.map +1 -0
- package/dist/hash.d.mts +1 -4
- package/dist/hash.d.mts.map +1 -0
- package/dist/hash.d.ts +1 -4
- package/dist/hash.d.ts.map +1 -0
- package/dist/hash.js +11 -10
- package/dist/hash.mjs +1 -1
- package/dist/index.d.mts +19 -39
- package/dist/index.d.mts.map +1 -0
- package/dist/index.d.ts +19 -39
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +97 -88
- package/dist/index.mjs +12 -14
- package/dist/{asymmetric-crypto-CyXsV4XT.mjs → keys-BfcaiAOv.mjs} +3 -15
- package/dist/keys-BfcaiAOv.mjs.map +1 -0
- package/dist/{asymmetric-crypto-BORmLhnx.js → keys-CinT7kEY.js} +2 -20
- package/dist/keys-CinT7kEY.js.map +1 -0
- package/dist/keystore-crypto.d.mts +2 -5
- package/dist/keystore-crypto.d.mts.map +1 -0
- package/dist/keystore-crypto.d.ts +2 -5
- package/dist/keystore-crypto.d.ts.map +1 -0
- package/dist/keystore-crypto.js +5 -10
- package/dist/keystore-crypto.mjs +1 -7
- package/dist/kyber768-SXnIo-Nw.mjs +47 -0
- package/dist/kyber768-SXnIo-Nw.mjs.map +1 -0
- package/dist/kyber768-WUVc2fIR.js +65 -0
- package/dist/kyber768-WUVc2fIR.js.map +1 -0
- package/dist/{hash-BoqwNkcd.js → mac-BMb1F0dN.js} +3 -23
- package/dist/mac-BMb1F0dN.js.map +1 -0
- package/dist/{hash-CXeGAwai.mjs → mac-ZpRlx8Fs.mjs} +3 -18
- package/dist/mac-ZpRlx8Fs.mjs.map +1 -0
- package/dist/post-quantum-crypto.d.mts +32 -2
- package/dist/post-quantum-crypto.d.mts.map +1 -0
- package/dist/post-quantum-crypto.d.ts +32 -2
- package/dist/post-quantum-crypto.d.ts.map +1 -0
- package/dist/post-quantum-crypto.js +5 -16
- package/dist/post-quantum-crypto.mjs +2 -2
- package/dist/storage-service.d.mts +47 -2
- package/dist/storage-service.d.mts.map +1 -0
- package/dist/storage-service.d.ts +47 -2
- package/dist/storage-service.d.ts.map +1 -0
- package/dist/storage-service.js +58 -4
- package/dist/storage-service.js.map +1 -0
- package/dist/storage-service.mjs +55 -2
- package/dist/storage-service.mjs.map +1 -0
- package/dist/symmetric-crypto.d.mts +5 -8
- package/dist/symmetric-crypto.d.mts.map +1 -0
- package/dist/symmetric-crypto.d.ts +5 -8
- package/dist/symmetric-crypto.d.ts.map +1 -0
- package/dist/symmetric-crypto.js +9 -9
- package/dist/symmetric-crypto.mjs +1 -2
- package/dist/types.d.mts +108 -2
- package/dist/types.d.mts.map +1 -0
- package/dist/types.d.ts +108 -2
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -2
- package/dist/types.js.map +1 -0
- package/dist/types.mjs +9 -2
- package/dist/types.mjs.map +1 -0
- package/dist/utils.d.mts +2 -5
- package/dist/utils.d.mts.map +1 -0
- package/dist/utils.d.ts +2 -5
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +16 -15
- package/dist/utils.mjs +1 -1
- package/package.json +24 -14
- package/dist/asymmetric-crypto-BORmLhnx.js.map +0 -1
- package/dist/asymmetric-crypto-CyXsV4XT.mjs.map +0 -1
- package/dist/constants-Ccp21E03.js +0 -208
- package/dist/constants-Ccp21E03.js.map +0 -1
- package/dist/constants-kTeX-2T0.mjs +0 -34
- package/dist/constants-kTeX-2T0.mjs.map +0 -1
- package/dist/derive-key-Be7hS-cN.mjs.map +0 -1
- package/dist/derive-key-CBf2WxJd.js.map +0 -1
- package/dist/email-crypto-BrT98taw.js.map +0 -1
- package/dist/email-crypto-DJUEjTxA.mjs.map +0 -1
- package/dist/hash-BoqwNkcd.js.map +0 -1
- package/dist/hash-CXeGAwai.mjs.map +0 -1
- package/dist/index-CQqgKsbX.d.ts +0 -50
- package/dist/index-CintVUbp.d.ts +0 -97
- package/dist/index-D5pBU_A5.d.mts +0 -50
- package/dist/index-MaOov-ag.d.mts +0 -97
- package/dist/keystore-crypto-B4yCVo9l.js.map +0 -1
- package/dist/keystore-crypto-Bjgriq9h.mjs.map +0 -1
- package/dist/keystore-service.d.mts +0 -48
- package/dist/keystore-service.d.ts +0 -48
- package/dist/keystore-service.js +0 -122
- package/dist/keystore-service.js.map +0 -1
- package/dist/keystore-service.mjs +0 -114
- package/dist/keystore-service.mjs.map +0 -1
- package/dist/post-quantum-crypto-CAi-cEkV.js +0 -189
- package/dist/post-quantum-crypto-CAi-cEkV.js.map +0 -1
- package/dist/post-quantum-crypto-Vv34t6gX.mjs +0 -154
- package/dist/post-quantum-crypto-Vv34t6gX.mjs.map +0 -1
- package/dist/storage-service-BgIK2aYZ.js +0 -82
- package/dist/storage-service-BgIK2aYZ.js.map +0 -1
- package/dist/storage-service-CubCbhY2.mjs +0 -65
- package/dist/storage-service-CubCbhY2.mjs.map +0 -1
- package/dist/symmetric-crypto-CrdS1Che.mjs.map +0 -1
- package/dist/symmetric-crypto-D65zB396.js.map +0 -1
- package/dist/types-52g887Zi.js +0 -16
- package/dist/types-52g887Zi.js.map +0 -1
- package/dist/types-BiEoleqw.mjs +0 -10
- package/dist/types-BiEoleqw.mjs.map +0 -1
- package/dist/types-Ds3ivE9W.d.ts +0 -104
- package/dist/types-DwQJtrTx.d.mts +0 -104
- package/dist/utils-CNs3cyDj.js.map +0 -1
- package/dist/utils-DS04iUcX.mjs.map +0 -1
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const require_types = require('./types-52g887Zi.js');
|
|
1
|
+
const require_constants = require('./constants.js');
|
|
2
|
+
const require_keys = require('./keys-CinT7kEY.js');
|
|
3
|
+
const require_genID = require('./genID-YJSl3YhL.js');
|
|
4
|
+
const require_mac = require('./mac-BMb1F0dN.js');
|
|
5
|
+
const require_aes = require('./aes-DQo1MyCz.js');
|
|
6
|
+
const require_deriveKeysFromPassword = require('./deriveKeysFromPassword-BYaiSGKL.js');
|
|
7
|
+
const require_emailKeys = require('./emailKeys-C0KhtfNP.js');
|
|
8
|
+
const require_types = require('./types.js');
|
|
10
9
|
|
|
11
10
|
//#region src/keystore-crypto/core.ts
|
|
12
11
|
/**
|
|
@@ -20,18 +19,18 @@ const require_types = require('./types-52g887Zi.js');
|
|
|
20
19
|
*/
|
|
21
20
|
async function encryptKeystoreContent(secretKey, keys, userEmail, type) {
|
|
22
21
|
try {
|
|
23
|
-
const aux =
|
|
24
|
-
const publicKeys = await
|
|
25
|
-
const kyberPrivateKeyEnc = await
|
|
26
|
-
const eccPrivateKeyEnc = await
|
|
22
|
+
const aux = require_genID.UTF8ToUint8(userEmail + type);
|
|
23
|
+
const publicKeys = await require_genID.publicKeyToBase64(keys.publicKeys);
|
|
24
|
+
const kyberPrivateKeyEnc = await require_aes.encryptSymmetrically(secretKey, keys.privateKeys.kyberPrivateKey, aux);
|
|
25
|
+
const eccPrivateKeyEnc = await require_aes.encryptSymmetrically(secretKey, await require_keys.exportPrivateKey(keys.privateKeys.eccPrivateKey), aux);
|
|
27
26
|
return {
|
|
28
27
|
userEmail,
|
|
29
28
|
type,
|
|
30
29
|
encryptedKeys: {
|
|
31
30
|
publicKeys,
|
|
32
31
|
privateKeys: {
|
|
33
|
-
kyberPrivateKeyBase64:
|
|
34
|
-
eccPrivateKeyBase64:
|
|
32
|
+
kyberPrivateKeyBase64: require_genID.uint8ArrayToBase64(kyberPrivateKeyEnc),
|
|
33
|
+
eccPrivateKeyBase64: require_genID.uint8ArrayToBase64(eccPrivateKeyEnc)
|
|
35
34
|
}
|
|
36
35
|
}
|
|
37
36
|
};
|
|
@@ -50,11 +49,11 @@ async function encryptKeystoreContent(secretKey, keys, userEmail, type) {
|
|
|
50
49
|
*/
|
|
51
50
|
async function decryptKeystoreContent(secretKey, encryptedKeystore) {
|
|
52
51
|
try {
|
|
53
|
-
const aux =
|
|
54
|
-
const kyberPublicKey =
|
|
55
|
-
const eccPublicKey = await
|
|
56
|
-
const kyberPrivateKey = await
|
|
57
|
-
const eccPrivateKey = await
|
|
52
|
+
const aux = require_genID.UTF8ToUint8(encryptedKeystore.userEmail + encryptedKeystore.type);
|
|
53
|
+
const kyberPublicKey = require_genID.base64ToUint8Array(encryptedKeystore.encryptedKeys.publicKeys.kyberPublicKeyBase64);
|
|
54
|
+
const eccPublicKey = await require_keys.importPublicKey(require_genID.base64ToUint8Array(encryptedKeystore.encryptedKeys.publicKeys.eccPublicKeyBase64));
|
|
55
|
+
const kyberPrivateKey = await require_aes.decryptSymmetrically(secretKey, require_genID.base64ToUint8Array(encryptedKeystore.encryptedKeys.privateKeys.kyberPrivateKeyBase64), aux);
|
|
56
|
+
const eccPrivateKey = await require_keys.importPrivateKey(await require_aes.decryptSymmetrically(secretKey, require_genID.base64ToUint8Array(encryptedKeystore.encryptedKeys.privateKeys.eccPrivateKeyBase64), aux));
|
|
58
57
|
return {
|
|
59
58
|
publicKeys: {
|
|
60
59
|
kyberPublicKey,
|
|
@@ -76,8 +75,8 @@ async function decryptKeystoreContent(secretKey, encryptedKeystore) {
|
|
|
76
75
|
* @returns The derived secret key for protecting the recovery keystore
|
|
77
76
|
*/
|
|
78
77
|
async function deriveRecoveryKey(recoveryCodes) {
|
|
79
|
-
const recoverCodesArray =
|
|
80
|
-
return
|
|
78
|
+
const recoverCodesArray = require_genID.mnemonicToBytes(recoveryCodes);
|
|
79
|
+
return require_deriveKeysFromPassword.deriveSymmetricKeyFromContext(require_constants.CONTEXT_RECOVERY, require_mac.getBytesFromData(require_constants.AES_KEY_BIT_LENGTH / 8, recoverCodesArray));
|
|
81
80
|
}
|
|
82
81
|
/**
|
|
83
82
|
* Derives a secret key for protecting the encryption keystore
|
|
@@ -86,7 +85,7 @@ async function deriveRecoveryKey(recoveryCodes) {
|
|
|
86
85
|
* @returns The derived secret key for protecting the encryption keystore
|
|
87
86
|
*/
|
|
88
87
|
async function deriveEncryptionKeystoreKey(baseKey) {
|
|
89
|
-
return
|
|
88
|
+
return require_deriveKeysFromPassword.deriveSymmetricKeyFromContext(require_constants.CONTEXT_ENC_KEYSTORE, baseKey);
|
|
90
89
|
}
|
|
91
90
|
|
|
92
91
|
//#endregion
|
|
@@ -100,9 +99,9 @@ async function deriveEncryptionKeystoreKey(baseKey) {
|
|
|
100
99
|
*/
|
|
101
100
|
async function createEncryptionAndRecoveryKeystores(userEmail, baseKey) {
|
|
102
101
|
try {
|
|
103
|
-
const keys = await
|
|
102
|
+
const keys = await require_emailKeys.generateEmailKeys();
|
|
104
103
|
const encryptionKeystore = await encryptKeystoreContent(await deriveEncryptionKeystoreKey(baseKey), keys, userEmail, require_types.KeystoreType.ENCRYPTION);
|
|
105
|
-
const recoveryCodes =
|
|
104
|
+
const recoveryCodes = require_genID.genMnemonic();
|
|
106
105
|
return {
|
|
107
106
|
encryptionKeystore,
|
|
108
107
|
recoveryKeystore: await encryptKeystoreContent(await deriveRecoveryKey(recoveryCodes), keys, userEmail, require_types.KeystoreType.RECOVERY),
|
|
@@ -146,14 +145,6 @@ async function openRecoveryKeystore(recoveryCodes, encryptedKeystore) {
|
|
|
146
145
|
}
|
|
147
146
|
}
|
|
148
147
|
|
|
149
|
-
//#endregion
|
|
150
|
-
//#region src/keystore-crypto/index.ts
|
|
151
|
-
var keystore_crypto_exports = /* @__PURE__ */ require_chunk.__exportAll({
|
|
152
|
-
createEncryptionAndRecoveryKeystores: () => createEncryptionAndRecoveryKeystores,
|
|
153
|
-
openEncryptionKeystore: () => openEncryptionKeystore,
|
|
154
|
-
openRecoveryKeystore: () => openRecoveryKeystore
|
|
155
|
-
});
|
|
156
|
-
|
|
157
148
|
//#endregion
|
|
158
149
|
Object.defineProperty(exports, 'createEncryptionAndRecoveryKeystores', {
|
|
159
150
|
enumerable: true,
|
|
@@ -161,12 +152,6 @@ Object.defineProperty(exports, 'createEncryptionAndRecoveryKeystores', {
|
|
|
161
152
|
return createEncryptionAndRecoveryKeystores;
|
|
162
153
|
}
|
|
163
154
|
});
|
|
164
|
-
Object.defineProperty(exports, 'keystore_crypto_exports', {
|
|
165
|
-
enumerable: true,
|
|
166
|
-
get: function () {
|
|
167
|
-
return keystore_crypto_exports;
|
|
168
|
-
}
|
|
169
|
-
});
|
|
170
155
|
Object.defineProperty(exports, 'openEncryptionKeystore', {
|
|
171
156
|
enumerable: true,
|
|
172
157
|
get: function () {
|
|
@@ -179,4 +164,4 @@ Object.defineProperty(exports, 'openRecoveryKeystore', {
|
|
|
179
164
|
return openRecoveryKeystore;
|
|
180
165
|
}
|
|
181
166
|
});
|
|
182
|
-
//# sourceMappingURL=
|
|
167
|
+
//# sourceMappingURL=emailEncryptionKey-CQNe5W_T.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emailEncryptionKey-CQNe5W_T.js","names":["UTF8ToUint8","publicKeyToBase64","encryptSymmetrically","exportPrivateKey","uint8ArrayToBase64","base64ToUint8Array","importPublicKey","decryptSymmetrically","importPrivateKey","mnemonicToBytes","deriveSymmetricKeyFromContext","CONTEXT_RECOVERY","getBytesFromData","AES_KEY_BIT_LENGTH","CONTEXT_ENC_KEYSTORE","generateEmailKeys","KeystoreType","genMnemonic"],"sources":["../src/keystore-crypto/core.ts","../src/keystore-crypto/emailEncryptionKey.ts"],"sourcesContent":["import { encryptSymmetrically, decryptSymmetrically } from '../symmetric-crypto';\nimport { base64ToUint8Array, uint8ArrayToBase64, UTF8ToUint8, mnemonicToBytes, publicKeyToBase64 } from '../utils';\nimport { deriveSymmetricKeyFromContext } from '../derive-key';\nimport { CONTEXT_ENC_KEYSTORE, AES_KEY_BIT_LENGTH, CONTEXT_RECOVERY } from '../constants';\nimport { getBytesFromData } from '../hash';\nimport { EmailKeys, EncryptedKeystore, KeystoreType } from '../types';\nimport { exportPrivateKey, importPrivateKey, importPublicKey } from '../asymmetric-crypto';\n\n/**\n * Encrypts the keystore content using symmetric encryption\n *\n * @param secretKey - The symmetric key to encrypt the keystore content\n * @param content - The content of the keystore\n * @param userID - The ID of the user\n * @param tag - The keystore type-specific tag string\n * @returns The encrypted keystore content\n */\nexport async function encryptKeystoreContent(\n secretKey: Uint8Array,\n keys: EmailKeys,\n userEmail: string,\n type: KeystoreType,\n): Promise<EncryptedKeystore> {\n try {\n const aux = UTF8ToUint8(userEmail + type);\n const publicKeys = await publicKeyToBase64(keys.publicKeys);\n const kyberPrivateKeyEnc = await encryptSymmetrically(secretKey, keys.privateKeys.kyberPrivateKey, aux);\n const eccPrivateKey = await exportPrivateKey(keys.privateKeys.eccPrivateKey);\n const eccPrivateKeyEnc = await encryptSymmetrically(secretKey, eccPrivateKey, aux);\n const encryptedKeys = {\n publicKeys,\n privateKeys: {\n kyberPrivateKeyBase64: uint8ArrayToBase64(kyberPrivateKeyEnc),\n eccPrivateKeyBase64: uint8ArrayToBase64(eccPrivateKeyEnc),\n },\n };\n\n const keystore: EncryptedKeystore = {\n userEmail,\n type,\n encryptedKeys,\n };\n return keystore;\n } catch (error) {\n throw new Error('Failed to encrypt keystore content', { cause: error });\n }\n}\n\n/**\n * Decrypts the keystore content using symmetric encryption\n *\n * @param secretKey - The symmetric key to decrypt the keystore content\n * @param encryptedKeys - The encrypted keystore content\n * @param userEmail - The ID of the user\n * @param tag - The keystore type-specific tag string\n * @returns The decrypted keystore content\n */\nexport async function decryptKeystoreContent(\n secretKey: Uint8Array,\n encryptedKeystore: EncryptedKeystore,\n): Promise<EmailKeys> {\n try {\n const aux = UTF8ToUint8(encryptedKeystore.userEmail + encryptedKeystore.type);\n const kyberPublicKey = base64ToUint8Array(encryptedKeystore.encryptedKeys.publicKeys.kyberPublicKeyBase64);\n const eccPublicArray = base64ToUint8Array(encryptedKeystore.encryptedKeys.publicKeys.eccPublicKeyBase64);\n const eccPublicKey = await importPublicKey(eccPublicArray);\n const encKyberPrivateKey = base64ToUint8Array(encryptedKeystore.encryptedKeys.privateKeys.kyberPrivateKeyBase64);\n const kyberPrivateKey = await decryptSymmetrically(secretKey, encKyberPrivateKey, aux);\n const eccEncArray = base64ToUint8Array(encryptedKeystore.encryptedKeys.privateKeys.eccPrivateKeyBase64);\n const eccKey = await decryptSymmetrically(secretKey, eccEncArray, aux);\n const eccPrivateKey = await importPrivateKey(eccKey);\n const keys = {\n publicKeys: {\n kyberPublicKey,\n eccPublicKey,\n },\n privateKeys: {\n kyberPrivateKey,\n eccPrivateKey,\n },\n };\n return keys;\n } catch (error) {\n throw new Error('Failed to decrypt keystore content', { cause: error });\n }\n}\n\n/**\n * Derives a secret key for protecting the recovery keystore\n *\n * @param recoveryCodes - The recovery codes\n * @returns The derived secret key for protecting the recovery keystore\n */\nexport async function deriveRecoveryKey(recoveryCodes: string): Promise<Uint8Array> {\n const recoverCodesArray = mnemonicToBytes(recoveryCodes);\n const recoveryCodesBuffer = getBytesFromData(AES_KEY_BIT_LENGTH / 8, recoverCodesArray);\n return deriveSymmetricKeyFromContext(CONTEXT_RECOVERY, recoveryCodesBuffer);\n}\n\n/**\n * Derives a secret key for protecting the encryption keystore\n *\n * @param baseKey - The base secret key from which a new key secret will be derived\n * @returns The derived secret key for protecting the encryption keystore\n */\nexport async function deriveEncryptionKeystoreKey(baseKey: Uint8Array): Promise<Uint8Array> {\n return deriveSymmetricKeyFromContext(CONTEXT_ENC_KEYSTORE, baseKey);\n}\n","import { EmailKeys, EncryptedKeystore, KeystoreType } from '../types';\nimport { genMnemonic } from '../utils';\nimport { encryptKeystoreContent, decryptKeystoreContent, deriveEncryptionKeystoreKey, deriveRecoveryKey } from './core';\nimport { generateEmailKeys } from '../email-crypto';\n\n/**\n * Generates email keys and creates encrypted main and recovery keystores\n * The main keystore encryption key is derived from the base key (stored in session storage)\n * The recovery keystore encryption key is derived from the recovery codes\n *\n * @returns The encryption and recovery keystores, recovery codes and email keys\n */\nexport async function createEncryptionAndRecoveryKeystores(\n userEmail: string,\n baseKey: Uint8Array,\n): Promise<{\n encryptionKeystore: EncryptedKeystore;\n recoveryKeystore: EncryptedKeystore;\n recoveryCodes: string;\n keys: EmailKeys;\n}> {\n try {\n const keys = await generateEmailKeys();\n\n const secretKey = await deriveEncryptionKeystoreKey(baseKey);\n const encryptionKeystore = await encryptKeystoreContent(secretKey, keys, userEmail, KeystoreType.ENCRYPTION);\n\n const recoveryCodes = genMnemonic();\n const recoveryKey = await deriveRecoveryKey(recoveryCodes);\n const recoveryKeystore = await encryptKeystoreContent(recoveryKey, keys, userEmail, KeystoreType.RECOVERY);\n\n return { encryptionKeystore, recoveryKeystore, recoveryCodes, keys };\n } catch (error) {\n throw new Error('Failed to create encryption and recovery keystores', { cause: error });\n }\n}\n\n/**\n * Opens the encryption keystore and returns the email encryption keys\n * The decryption key is derived from the base key (stored in session storage)\n *\n * @param encryptedKeystore - The encrypted keystore containing encryption keys\n * @param baseKey - The base key from which the decryption key will be derived\n * @returns The encryption keys\n */\nexport async function openEncryptionKeystore(\n encryptedKeystore: EncryptedKeystore,\n baseKey: Uint8Array,\n): Promise<EmailKeys> {\n try {\n if (encryptedKeystore.type != KeystoreType.ENCRYPTION) {\n throw new Error('Input is invalid');\n }\n const secretKey = await deriveEncryptionKeystoreKey(baseKey);\n const keys = await decryptKeystoreContent(secretKey, encryptedKeystore);\n return keys;\n } catch (error) {\n throw new Error('Failed to open encryption keystore', { cause: error });\n }\n}\n\n/**\n * Opens the recovery keystore and returns the email encryption keys\n * The decryption key is derived from the base key (stored in session storage)\n *\n * @param recoveryCodes - The user's recovery codes\n * @param encryptedKeystore - The encrypted keystore containing encryption keys\n * @returns The encryption keys\n */\nexport async function openRecoveryKeystore(\n recoveryCodes: string,\n encryptedKeystore: EncryptedKeystore,\n): Promise<EmailKeys> {\n try {\n if (encryptedKeystore.type != KeystoreType.RECOVERY) {\n throw new Error('Input is invalid');\n }\n const recoveryKey = await deriveRecoveryKey(recoveryCodes);\n const keys = await decryptKeystoreContent(recoveryKey, encryptedKeystore);\n return keys;\n } catch (error) {\n throw new Error('Failed to open recovery keystore', { cause: error });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAiBA,eAAsB,uBACpB,WACA,MACA,WACA,MAC4B;AAC5B,KAAI;EACF,MAAM,MAAMA,0BAAY,YAAY,KAAK;EACzC,MAAM,aAAa,MAAMC,gCAAkB,KAAK,WAAW;EAC3D,MAAM,qBAAqB,MAAMC,iCAAqB,WAAW,KAAK,YAAY,iBAAiB,IAAI;EAEvG,MAAM,mBAAmB,MAAMA,iCAAqB,WAD9B,MAAMC,8BAAiB,KAAK,YAAY,cAAc,EACE,IAAI;AAclF,SALoC;GAClC;GACA;GACA,eAXoB;IACpB;IACA,aAAa;KACX,uBAAuBC,iCAAmB,mBAAmB;KAC7D,qBAAqBA,iCAAmB,iBAAiB;KAC1D;IACF;GAMA;UAEM,OAAO;AACd,QAAM,IAAI,MAAM,sCAAsC,EAAE,OAAO,OAAO,CAAC;;;;;;;;;;;;AAa3E,eAAsB,uBACpB,WACA,mBACoB;AACpB,KAAI;EACF,MAAM,MAAMJ,0BAAY,kBAAkB,YAAY,kBAAkB,KAAK;EAC7E,MAAM,iBAAiBK,iCAAmB,kBAAkB,cAAc,WAAW,qBAAqB;EAE1G,MAAM,eAAe,MAAMC,6BADJD,iCAAmB,kBAAkB,cAAc,WAAW,mBAAmB,CAC9C;EAE1D,MAAM,kBAAkB,MAAME,iCAAqB,WADxBF,iCAAmB,kBAAkB,cAAc,YAAY,sBAAsB,EAC9B,IAAI;EAGtF,MAAM,gBAAgB,MAAMG,8BADb,MAAMD,iCAAqB,WADtBF,iCAAmB,kBAAkB,cAAc,YAAY,oBAAoB,EACrC,IAAI,CAClB;AAWpD,SAVa;GACX,YAAY;IACV;IACA;IACD;GACD,aAAa;IACX;IACA;IACD;GACF;UAEM,OAAO;AACd,QAAM,IAAI,MAAM,sCAAsC,EAAE,OAAO,OAAO,CAAC;;;;;;;;;AAU3E,eAAsB,kBAAkB,eAA4C;CAClF,MAAM,oBAAoBI,8BAAgB,cAAc;AAExD,QAAOC,6DAA8BC,oCADTC,6BAAiBC,uCAAqB,GAAG,kBAAkB,CACZ;;;;;;;;AAS7E,eAAsB,4BAA4B,SAA0C;AAC1F,QAAOH,6DAA8BI,wCAAsB,QAAQ;;;;;;;;;;;;AC9FrE,eAAsB,qCACpB,WACA,SAMC;AACD,KAAI;EACF,MAAM,OAAO,MAAMC,qCAAmB;EAGtC,MAAM,qBAAqB,MAAM,uBADf,MAAM,4BAA4B,QAAQ,EACO,MAAM,WAAWC,2BAAa,WAAW;EAE5G,MAAM,gBAAgBC,2BAAa;AAInC,SAAO;GAAE;GAAoB,kBAFJ,MAAM,uBADX,MAAM,kBAAkB,cAAc,EACS,MAAM,WAAWD,2BAAa,SAAS;GAE3D;GAAe;GAAM;UAC7D,OAAO;AACd,QAAM,IAAI,MAAM,sDAAsD,EAAE,OAAO,OAAO,CAAC;;;;;;;;;;;AAY3F,eAAsB,uBACpB,mBACA,SACoB;AACpB,KAAI;AACF,MAAI,kBAAkB,QAAQA,2BAAa,WACzC,OAAM,IAAI,MAAM,mBAAmB;AAIrC,SADa,MAAM,uBADD,MAAM,4BAA4B,QAAQ,EACP,kBAAkB;UAEhE,OAAO;AACd,QAAM,IAAI,MAAM,sCAAsC,EAAE,OAAO,OAAO,CAAC;;;;;;;;;;;AAY3E,eAAsB,qBACpB,eACA,mBACoB;AACpB,KAAI;AACF,MAAI,kBAAkB,QAAQA,2BAAa,SACzC,OAAM,IAAI,MAAM,mBAAmB;AAIrC,SADa,MAAM,uBADC,MAAM,kBAAkB,cAAc,EACH,kBAAkB;UAElE,OAAO;AACd,QAAM,IAAI,MAAM,oCAAoC,EAAE,OAAO,OAAO,CAAC"}
|
|
@@ -1,37 +1,25 @@
|
|
|
1
|
-
const require_chunk = require('./chunk-
|
|
2
|
-
const require_constants = require('./constants
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
1
|
+
const require_chunk = require('./chunk-EbLFQX5m.js');
|
|
2
|
+
const require_constants = require('./constants.js');
|
|
3
|
+
const require_keys = require('./keys-CinT7kEY.js');
|
|
4
|
+
const require_genID = require('./genID-YJSl3YhL.js');
|
|
5
|
+
const require_aes = require('./aes-DQo1MyCz.js');
|
|
6
|
+
const require_deriveKeysFromPassword = require('./deriveKeysFromPassword-BYaiSGKL.js');
|
|
7
|
+
const require_kyber768 = require('./kyber768-WUVc2fIR.js');
|
|
8
8
|
let _noble_hashes_utils_js = require("@noble/hashes/utils.js");
|
|
9
|
+
let _noble_ciphers_aes_js = require("@noble/ciphers/aes.js");
|
|
9
10
|
|
|
10
11
|
//#region src/key-wrapper/aesWrapper.ts
|
|
11
12
|
/**
|
|
12
|
-
* Converts wrapping key in Uint8Array into CryptoKey
|
|
13
|
-
*
|
|
14
|
-
* @param key - The wrapping key in Uint8Array representation
|
|
15
|
-
* @returns The resulting CryptoKey
|
|
16
|
-
*/
|
|
17
|
-
async function importWrappingKey(key) {
|
|
18
|
-
try {
|
|
19
|
-
return await crypto.subtle.importKey(require_constants.KEY_FORMAT, key, require_constants.KEY_WRAPPING_ALGORITHM, false, ["wrapKey", "unwrapKey"]);
|
|
20
|
-
} catch (error) {
|
|
21
|
-
throw new Error("Failed to import wrapping key", { cause: error });
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
13
|
* Derives wrapping key from two secrets
|
|
26
14
|
*
|
|
27
15
|
* @param eccSecret - The secret exchanged via elliptic curves
|
|
28
16
|
* @param kyberSecret - The secret exchanged via Kyber KEM
|
|
29
|
-
* @returns The resulting wrapping
|
|
17
|
+
* @returns The resulting wrapping key
|
|
30
18
|
*/
|
|
31
19
|
async function deriveWrappingKey(eccSecret, kyberSecret) {
|
|
32
20
|
try {
|
|
33
21
|
if (eccSecret.length !== kyberSecret.length) throw new Error("secrets must have equal length");
|
|
34
|
-
return
|
|
22
|
+
return require_deriveKeysFromPassword.deriveSymmetricKeyFromTwoKeysAndContext(eccSecret, kyberSecret, require_constants.CONTEXT_WRAPPING);
|
|
35
23
|
} catch (error) {
|
|
36
24
|
throw new Error("Failed to derive wrapping key", { cause: error });
|
|
37
25
|
}
|
|
@@ -39,47 +27,29 @@ async function deriveWrappingKey(eccSecret, kyberSecret) {
|
|
|
39
27
|
/**
|
|
40
28
|
* Unwraps the given wrapped key
|
|
41
29
|
*
|
|
42
|
-
* @param encryptedKey - The
|
|
43
|
-
* @param wrappingKey - The secret key used for
|
|
44
|
-
* @returns The resulting
|
|
30
|
+
* @param encryptedKey - The wrapped key
|
|
31
|
+
* @param wrappingKey - The secret key used for unwrapping
|
|
32
|
+
* @returns The resulting key
|
|
45
33
|
*/
|
|
46
34
|
async function unwrapKey(encryptedKey, wrappingKey) {
|
|
47
|
-
|
|
48
|
-
return await crypto.subtle.unwrapKey(require_constants.KEY_FORMAT, encryptedKey, wrappingKey, require_constants.KEY_WRAPPING_ALGORITHM, require_constants.AES_ALGORITHM, false, ["encrypt", "decrypt"]);
|
|
49
|
-
} catch (error) {
|
|
50
|
-
throw new Error("Failed to unwrap key", { cause: error });
|
|
51
|
-
}
|
|
35
|
+
return (0, _noble_ciphers_aes_js.aeskw)(wrappingKey).decrypt(encryptedKey);
|
|
52
36
|
}
|
|
53
37
|
/**
|
|
54
|
-
* Wraps the given
|
|
38
|
+
* Wraps the given key
|
|
55
39
|
*
|
|
56
|
-
* @param
|
|
40
|
+
* @param key - The key to be wrapped
|
|
57
41
|
* @param wrappingKey - The secret key used for wrapping
|
|
58
42
|
* @returns The resulting ciphertext
|
|
59
43
|
*/
|
|
60
|
-
async function wrapKey(
|
|
61
|
-
|
|
62
|
-
const result = await crypto.subtle.wrapKey(require_constants.KEY_FORMAT, encryptionKey, wrappingKey, require_constants.KEY_WRAPPING_ALGORITHM);
|
|
63
|
-
return new Uint8Array(result);
|
|
64
|
-
} catch (error) {
|
|
65
|
-
throw new Error("Failed to wrap key", { cause: error });
|
|
66
|
-
}
|
|
44
|
+
async function wrapKey(key, wrappingKey) {
|
|
45
|
+
return (0, _noble_ciphers_aes_js.aeskw)(wrappingKey).encrypt(key);
|
|
67
46
|
}
|
|
68
47
|
|
|
69
|
-
//#endregion
|
|
70
|
-
//#region src/key-wrapper/index.ts
|
|
71
|
-
var key_wrapper_exports = /* @__PURE__ */ require_chunk.__exportAll({
|
|
72
|
-
deriveWrappingKey: () => deriveWrappingKey,
|
|
73
|
-
importWrappingKey: () => importWrappingKey,
|
|
74
|
-
unwrapKey: () => unwrapKey,
|
|
75
|
-
wrapKey: () => wrapKey
|
|
76
|
-
});
|
|
77
|
-
|
|
78
48
|
//#endregion
|
|
79
49
|
//#region src/email-crypto/converters.ts
|
|
80
50
|
function userToBytes(user) {
|
|
81
51
|
try {
|
|
82
|
-
return
|
|
52
|
+
return require_genID.UTF8ToUint8(JSON.stringify(user));
|
|
83
53
|
} catch (error) {
|
|
84
54
|
throw new Error("Failed to convert User to bytes", { cause: error });
|
|
85
55
|
}
|
|
@@ -99,7 +69,7 @@ function recipientsToBytes(recipients) {
|
|
|
99
69
|
*/
|
|
100
70
|
function emailToBinary(email) {
|
|
101
71
|
try {
|
|
102
|
-
return
|
|
72
|
+
return require_genID.UTF8ToUint8(JSON.stringify(email));
|
|
103
73
|
} catch (error) {
|
|
104
74
|
throw new Error("Failed to convert EmailBody to Uint8Array", { cause: error });
|
|
105
75
|
}
|
|
@@ -117,12 +87,12 @@ function emailToBinary(email) {
|
|
|
117
87
|
function getAux(params, isSubjectEncrypted) {
|
|
118
88
|
try {
|
|
119
89
|
const { subject, replyToEmailID, sender, recipient, recipients } = params;
|
|
120
|
-
const replyBytes = replyToEmailID ?
|
|
90
|
+
const replyBytes = replyToEmailID ? require_genID.uuidToBytes(replyToEmailID) : new Uint8Array();
|
|
121
91
|
const senderBytes = userToBytes(sender);
|
|
122
92
|
const recipientBytes = userToBytes(recipient);
|
|
123
93
|
const recipientsBytes = recipients ? recipientsToBytes(recipients) : new Uint8Array();
|
|
124
94
|
if (isSubjectEncrypted) return (0, _noble_hashes_utils_js.concatBytes)(replyBytes, senderBytes, recipientBytes, recipientsBytes);
|
|
125
|
-
else return (0, _noble_hashes_utils_js.concatBytes)(
|
|
95
|
+
else return (0, _noble_hashes_utils_js.concatBytes)(require_genID.UTF8ToUint8(subject), replyBytes, senderBytes, recipientBytes, recipientsBytes);
|
|
126
96
|
} catch (error) {
|
|
127
97
|
throw new Error("Failed to create aux", { cause: error });
|
|
128
98
|
}
|
|
@@ -190,7 +160,7 @@ async function decryptEmailBody(enc, encParams, encryptionKey, isSubjectEncrypte
|
|
|
190
160
|
async function encryptEmailContentSymmetrically(email, aux, emailID) {
|
|
191
161
|
try {
|
|
192
162
|
if (!email.text) throw new Error("Invalid input");
|
|
193
|
-
const encryptionKey =
|
|
163
|
+
const encryptionKey = require_aes.genSymmetricKey();
|
|
194
164
|
return {
|
|
195
165
|
enc: await encryptEmailContentSymmetricallyWithKey(email, encryptionKey, aux, emailID),
|
|
196
166
|
encryptionKey
|
|
@@ -211,10 +181,10 @@ async function encryptEmailContentSymmetrically(email, aux, emailID) {
|
|
|
211
181
|
async function encryptEmailContentAndSubjectSymmetrically(email, subject, aux, emailID) {
|
|
212
182
|
try {
|
|
213
183
|
if (!subject || !email.text) throw new Error("Invalid input");
|
|
214
|
-
const encryptionKey =
|
|
184
|
+
const encryptionKey = require_aes.genSymmetricKey();
|
|
215
185
|
return {
|
|
216
186
|
enc: await encryptEmailContentSymmetricallyWithKey(email, encryptionKey, aux, emailID),
|
|
217
|
-
encSubject:
|
|
187
|
+
encSubject: require_genID.uint8ArrayToBase64(await require_aes.encryptSymmetrically(encryptionKey, require_genID.UTF8ToUint8(subject), aux)),
|
|
218
188
|
encryptionKey
|
|
219
189
|
};
|
|
220
190
|
} catch (error) {
|
|
@@ -225,15 +195,15 @@ async function encryptEmailContentAndSubjectSymmetrically(email, subject, aux, e
|
|
|
225
195
|
* Decrypts symmetrically encrypted email.
|
|
226
196
|
*
|
|
227
197
|
* @param encryptedEmail - The email to decrypt.
|
|
228
|
-
* @param encryptionKey - The symmetric
|
|
198
|
+
* @param encryptionKey - The symmetric key.
|
|
229
199
|
* @returns The decrypted email
|
|
230
200
|
*/
|
|
231
201
|
async function decryptEmailAndSubjectSymmetrically(encryptionKey, aux, encSubject, enc) {
|
|
232
202
|
try {
|
|
233
|
-
const subjectArray = await
|
|
203
|
+
const subjectArray = await require_aes.decryptSymmetrically(encryptionKey, require_genID.base64ToUint8Array(encSubject), aux);
|
|
234
204
|
return {
|
|
235
205
|
body: await decryptEmailSymmetrically(encryptionKey, aux, enc),
|
|
236
|
-
subject:
|
|
206
|
+
subject: require_genID.uint8ToUTF8(subjectArray)
|
|
237
207
|
};
|
|
238
208
|
} catch (error) {
|
|
239
209
|
throw new Error("Failed to symmetrically decrypt email and subject", { cause: error });
|
|
@@ -247,9 +217,9 @@ async function decryptEmailAndSubjectSymmetrically(encryptionKey, aux, encSubjec
|
|
|
247
217
|
*/
|
|
248
218
|
async function encryptEmailContentSymmetricallyWithKey(emailBody, encryptionKey, aux, emailID) {
|
|
249
219
|
try {
|
|
250
|
-
const freeField =
|
|
251
|
-
const result = { encText:
|
|
252
|
-
if (emailBody.attachments) result.encAttachments = (await encryptEmailAttachements(emailBody.attachments, encryptionKey, aux, emailID))?.map(
|
|
220
|
+
const freeField = require_genID.uuidToBytes(emailID);
|
|
221
|
+
const result = { encText: require_genID.uint8ArrayToBase64(await require_aes.encryptSymmetrically(encryptionKey, require_genID.UTF8ToUint8(emailBody.text), aux, freeField)) };
|
|
222
|
+
if (emailBody.attachments) result.encAttachments = (await encryptEmailAttachements(emailBody.attachments, encryptionKey, aux, emailID))?.map(require_genID.uint8ArrayToBase64);
|
|
253
223
|
return result;
|
|
254
224
|
} catch (error) {
|
|
255
225
|
throw new Error("Failed to symmetrically encrypt email with the given key", { cause: error });
|
|
@@ -257,9 +227,9 @@ async function encryptEmailContentSymmetricallyWithKey(emailBody, encryptionKey,
|
|
|
257
227
|
}
|
|
258
228
|
async function encryptEmailAttachements(attachments, encryptionKey, aux, emailID) {
|
|
259
229
|
try {
|
|
260
|
-
const freeField =
|
|
230
|
+
const freeField = require_genID.uuidToBytes(emailID);
|
|
261
231
|
return await Promise.all(attachments.map((attachment) => {
|
|
262
|
-
return
|
|
232
|
+
return require_aes.encryptSymmetrically(encryptionKey, require_genID.UTF8ToUint8(attachment), aux, freeField);
|
|
263
233
|
}));
|
|
264
234
|
} catch (error) {
|
|
265
235
|
throw new Error("Failed to symmetrically encrypt email attachements", { cause: error });
|
|
@@ -268,7 +238,7 @@ async function encryptEmailAttachements(attachments, encryptionKey, aux, emailID
|
|
|
268
238
|
async function decryptEmailAttachements(encryptedAttachments, encryptionKey, aux) {
|
|
269
239
|
try {
|
|
270
240
|
return await Promise.all(encryptedAttachments.map((attachment) => {
|
|
271
|
-
return
|
|
241
|
+
return require_aes.decryptSymmetrically(encryptionKey, attachment, aux);
|
|
272
242
|
}));
|
|
273
243
|
} catch (error) {
|
|
274
244
|
throw new Error("Failed to symmetrically decrypt email attachements", { cause: error });
|
|
@@ -278,15 +248,15 @@ async function decryptEmailAttachements(encryptedAttachments, encryptionKey, aux
|
|
|
278
248
|
* Decrypts symmetrically encrypted email.
|
|
279
249
|
*
|
|
280
250
|
* @param encryptedEmail - The email to decrypt.
|
|
281
|
-
* @param encryptionKey - The symmetric
|
|
251
|
+
* @param encryptionKey - The symmetric key.
|
|
282
252
|
* @returns The decrypted email
|
|
283
253
|
*/
|
|
284
254
|
async function decryptEmailSymmetrically(encryptionKey, aux, enc) {
|
|
285
255
|
try {
|
|
286
|
-
const result = { text:
|
|
256
|
+
const result = { text: require_genID.uint8ToUTF8(await require_aes.decryptSymmetrically(encryptionKey, require_genID.base64ToUint8Array(enc.encText), aux)) };
|
|
287
257
|
if (enc.encAttachments) {
|
|
288
|
-
const encAttachements = enc.encAttachments?.map(
|
|
289
|
-
result.attachments = (await decryptEmailAttachements(encAttachements, encryptionKey, aux))?.map((att) =>
|
|
258
|
+
const encAttachements = enc.encAttachments?.map(require_genID.base64ToUint8Array);
|
|
259
|
+
result.attachments = (await decryptEmailAttachements(encAttachements, encryptionKey, aux))?.map((att) => require_genID.uint8ToUTF8(att));
|
|
290
260
|
}
|
|
291
261
|
return result;
|
|
292
262
|
} catch (error) {
|
|
@@ -296,18 +266,18 @@ async function decryptEmailSymmetrically(encryptionKey, aux, enc) {
|
|
|
296
266
|
/**
|
|
297
267
|
* Encrypts the email symmetric key using hybrid encryption.
|
|
298
268
|
*
|
|
299
|
-
* @param emailEncryptionKey - The symmetric
|
|
269
|
+
* @param emailEncryptionKey - The symmetric key used for email encryption.
|
|
300
270
|
* @param recipientPublicKey - The public key of the recipient.
|
|
301
271
|
* @param senderPrivateKey - The private key of the sender.
|
|
302
272
|
* @returns The encrypted email symmetric key
|
|
303
273
|
*/
|
|
304
274
|
async function encryptKeysHybrid(emailEncryptionKey, recipientPublicKey, senderPrivateKey) {
|
|
305
275
|
try {
|
|
306
|
-
const eccSecret = await
|
|
307
|
-
const { cipherText: kyberCiphertext, sharedSecret: kyberSecret } =
|
|
276
|
+
const eccSecret = await require_keys.deriveSecretKey(recipientPublicKey.eccPublicKey, senderPrivateKey.eccPrivateKey);
|
|
277
|
+
const { cipherText: kyberCiphertext, sharedSecret: kyberSecret } = require_kyber768.encapsulateKyber(recipientPublicKey.kyberPublicKey);
|
|
308
278
|
return {
|
|
309
|
-
encryptedKey:
|
|
310
|
-
kyberCiphertext:
|
|
279
|
+
encryptedKey: require_genID.uint8ArrayToBase64(await wrapKey(emailEncryptionKey, await deriveWrappingKey(eccSecret, kyberSecret))),
|
|
280
|
+
kyberCiphertext: require_genID.uint8ArrayToBase64(kyberCiphertext)
|
|
311
281
|
};
|
|
312
282
|
} catch (error) {
|
|
313
283
|
throw new Error("Failed to encrypt email key using hybrid encryption", { cause: error });
|
|
@@ -319,12 +289,12 @@ async function encryptKeysHybrid(emailEncryptionKey, recipientPublicKey, senderP
|
|
|
319
289
|
* @param encryptedKey - The encrypted email key.
|
|
320
290
|
* @param senderPublicKey - The public key of the sender.
|
|
321
291
|
* @param recipientPrivateKey - The private key of the recipient.
|
|
322
|
-
* @returns The email encryption
|
|
292
|
+
* @returns The email encryption key
|
|
323
293
|
*/
|
|
324
294
|
async function decryptKeysHybrid(encryptedKey, senderPublicKey, recipientPrivateKey) {
|
|
325
295
|
try {
|
|
326
|
-
const kyberCiphertext =
|
|
327
|
-
return await unwrapKey(
|
|
296
|
+
const kyberCiphertext = require_genID.base64ToUint8Array(encryptedKey.kyberCiphertext);
|
|
297
|
+
return await unwrapKey(require_genID.base64ToUint8Array(encryptedKey.encryptedKey), await deriveWrappingKey(await require_keys.deriveSecretKey(senderPublicKey.eccPublicKey, recipientPrivateKey.eccPrivateKey), require_kyber768.decapsulateKyber(kyberCiphertext, recipientPrivateKey.kyberPrivateKey)));
|
|
328
298
|
} catch (error) {
|
|
329
299
|
throw new Error("Failed to decrypt email key encrypted via hybrid encryption", { cause: error });
|
|
330
300
|
}
|
|
@@ -332,17 +302,17 @@ async function decryptKeysHybrid(encryptedKey, senderPublicKey, recipientPrivate
|
|
|
332
302
|
/**
|
|
333
303
|
* Password-protects the email symmetric key.
|
|
334
304
|
*
|
|
335
|
-
* @param emailEncryptionKey - The symmetric
|
|
305
|
+
* @param emailEncryptionKey - The symmetric key used for email encryption.
|
|
336
306
|
* @param password - The secret password for key protection.
|
|
337
307
|
* @returns The password-protected email symmetric key
|
|
338
308
|
*/
|
|
339
309
|
async function passwordProtectKey(emailEncryptionKey, password) {
|
|
340
310
|
try {
|
|
341
|
-
const { key, salt } = await
|
|
342
|
-
const encryptedKey = await wrapKey(emailEncryptionKey,
|
|
343
|
-
const saltStr =
|
|
311
|
+
const { key, salt } = await require_deriveKeysFromPassword.getKeyFromPassword(password);
|
|
312
|
+
const encryptedKey = await wrapKey(emailEncryptionKey, key);
|
|
313
|
+
const saltStr = require_genID.uint8ArrayToBase64(salt);
|
|
344
314
|
return {
|
|
345
|
-
encryptedKey:
|
|
315
|
+
encryptedKey: require_genID.uint8ArrayToBase64(encryptedKey),
|
|
346
316
|
salt: saltStr
|
|
347
317
|
};
|
|
348
318
|
} catch (error) {
|
|
@@ -354,12 +324,12 @@ async function passwordProtectKey(emailEncryptionKey, password) {
|
|
|
354
324
|
*
|
|
355
325
|
* @param emailEncryptionKey - The password-protected email key.
|
|
356
326
|
* @param password - The secret password for key protection.
|
|
357
|
-
* @returns The email encryption
|
|
327
|
+
* @returns The email encryption key
|
|
358
328
|
*/
|
|
359
329
|
async function removePasswordProtection(emailEncryptionKey, password) {
|
|
360
330
|
try {
|
|
361
|
-
const salt =
|
|
362
|
-
return await unwrapKey(
|
|
331
|
+
const salt = require_genID.base64ToUint8Array(emailEncryptionKey.salt);
|
|
332
|
+
return await unwrapKey(require_genID.base64ToUint8Array(emailEncryptionKey.encryptedKey), await require_deriveKeysFromPassword.getKeyFromPasswordAndSalt(password, salt));
|
|
363
333
|
} catch (error) {
|
|
364
334
|
throw new Error("Failed to remove password-protection from email key", { cause: error });
|
|
365
335
|
}
|
|
@@ -497,8 +467,8 @@ async function decryptPwdProtectedEmail(encryptedEmail, password) {
|
|
|
497
467
|
*/
|
|
498
468
|
async function generateEmailKeys() {
|
|
499
469
|
try {
|
|
500
|
-
const kyberKeys =
|
|
501
|
-
const keys = await
|
|
470
|
+
const kyberKeys = require_kyber768.generateKyberKeys();
|
|
471
|
+
const keys = await require_keys.generateEccKeys();
|
|
502
472
|
return {
|
|
503
473
|
publicKeys: {
|
|
504
474
|
eccPublicKey: keys.publicKey,
|
|
@@ -514,21 +484,6 @@ async function generateEmailKeys() {
|
|
|
514
484
|
}
|
|
515
485
|
}
|
|
516
486
|
|
|
517
|
-
//#endregion
|
|
518
|
-
//#region src/email-crypto/index.ts
|
|
519
|
-
var email_crypto_exports = /* @__PURE__ */ require_chunk.__exportAll({
|
|
520
|
-
createPwdProtectedEmail: () => createPwdProtectedEmail,
|
|
521
|
-
decryptEmailHybrid: () => decryptEmailHybrid,
|
|
522
|
-
decryptPwdProtectedEmail: () => decryptPwdProtectedEmail,
|
|
523
|
-
emailToBinary: () => emailToBinary,
|
|
524
|
-
encryptEmailHybrid: () => encryptEmailHybrid,
|
|
525
|
-
encryptEmailHybridForMultipleRecipients: () => encryptEmailHybridForMultipleRecipients,
|
|
526
|
-
generateEmailKeys: () => generateEmailKeys,
|
|
527
|
-
getAux: () => getAux,
|
|
528
|
-
recipientsToBytes: () => recipientsToBytes,
|
|
529
|
-
userToBytes: () => userToBytes
|
|
530
|
-
});
|
|
531
|
-
|
|
532
487
|
//#endregion
|
|
533
488
|
Object.defineProperty(exports, 'createPwdProtectedEmail', {
|
|
534
489
|
enumerable: true,
|
|
@@ -560,12 +515,6 @@ Object.defineProperty(exports, 'emailToBinary', {
|
|
|
560
515
|
return emailToBinary;
|
|
561
516
|
}
|
|
562
517
|
});
|
|
563
|
-
Object.defineProperty(exports, 'email_crypto_exports', {
|
|
564
|
-
enumerable: true,
|
|
565
|
-
get: function () {
|
|
566
|
-
return email_crypto_exports;
|
|
567
|
-
}
|
|
568
|
-
});
|
|
569
518
|
Object.defineProperty(exports, 'encryptEmailContentSymmetricallyWithKey', {
|
|
570
519
|
enumerable: true,
|
|
571
520
|
get: function () {
|
|
@@ -596,16 +545,16 @@ Object.defineProperty(exports, 'getAux', {
|
|
|
596
545
|
return getAux;
|
|
597
546
|
}
|
|
598
547
|
});
|
|
599
|
-
Object.defineProperty(exports, '
|
|
548
|
+
Object.defineProperty(exports, 'recipientsToBytes', {
|
|
600
549
|
enumerable: true,
|
|
601
550
|
get: function () {
|
|
602
|
-
return
|
|
551
|
+
return recipientsToBytes;
|
|
603
552
|
}
|
|
604
553
|
});
|
|
605
|
-
Object.defineProperty(exports, '
|
|
554
|
+
Object.defineProperty(exports, 'unwrapKey', {
|
|
606
555
|
enumerable: true,
|
|
607
556
|
get: function () {
|
|
608
|
-
return
|
|
557
|
+
return unwrapKey;
|
|
609
558
|
}
|
|
610
559
|
});
|
|
611
560
|
Object.defineProperty(exports, 'userToBytes', {
|
|
@@ -614,4 +563,10 @@ Object.defineProperty(exports, 'userToBytes', {
|
|
|
614
563
|
return userToBytes;
|
|
615
564
|
}
|
|
616
565
|
});
|
|
617
|
-
|
|
566
|
+
Object.defineProperty(exports, 'wrapKey', {
|
|
567
|
+
enumerable: true,
|
|
568
|
+
get: function () {
|
|
569
|
+
return wrapKey;
|
|
570
|
+
}
|
|
571
|
+
});
|
|
572
|
+
//# sourceMappingURL=emailKeys-C0KhtfNP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emailKeys-C0KhtfNP.js","names":["deriveSymmetricKeyFromTwoKeysAndContext","CONTEXT_WRAPPING","UTF8ToUint8","uuidToBytes","UTF8ToUint8","genSymmetricKey","uint8ArrayToBase64","encryptSymmetrically","UTF8ToUint8","decryptSymmetrically","base64ToUint8Array","uint8ToUTF8","uuidToBytes","deriveSecretKey","encapsulateKyber","decapsulateKyber","getKeyFromPassword","getKeyFromPasswordAndSalt","generateKyberKeys","generateEccKeys"],"sources":["../src/key-wrapper/aesWrapper.ts","../src/email-crypto/converters.ts","../src/email-crypto/utils.ts","../src/email-crypto/core.ts","../src/email-crypto/hybridEncyptedEmail.ts","../src/email-crypto/pwdProtectedEmail.ts","../src/email-crypto/emailKeys.ts"],"sourcesContent":["import { CONTEXT_WRAPPING } from '../constants';\nimport { deriveSymmetricKeyFromTwoKeysAndContext } from '../derive-key';\nimport { aeskw } from '@noble/ciphers/aes.js';\n\n/**\n * Derives wrapping key from two secrets\n *\n * @param eccSecret - The secret exchanged via elliptic curves\n * @param kyberSecret - The secret exchanged via Kyber KEM\n * @returns The resulting wrapping key\n */\nexport async function deriveWrappingKey(eccSecret: Uint8Array, kyberSecret: Uint8Array): Promise<Uint8Array> {\n try {\n if (eccSecret.length !== kyberSecret.length) {\n throw new Error('secrets must have equal length');\n }\n return deriveSymmetricKeyFromTwoKeysAndContext(eccSecret, kyberSecret, CONTEXT_WRAPPING);\n } catch (error) {\n throw new Error('Failed to derive wrapping key', { cause: error });\n }\n}\n\n/**\n * Unwraps the given wrapped key\n *\n * @param encryptedKey - The wrapped key\n * @param wrappingKey - The secret key used for unwrapping\n * @returns The resulting key\n */\nexport async function unwrapKey(encryptedKey: Uint8Array, wrappingKey: Uint8Array): Promise<Uint8Array> {\n return aeskw(wrappingKey).decrypt(encryptedKey);\n}\n\n/**\n * Wraps the given key\n *\n * @param key - The key to be wrapped\n * @param wrappingKey - The secret key used for wrapping\n * @returns The resulting ciphertext\n */\nexport async function wrapKey(key: Uint8Array, wrappingKey: Uint8Array): Promise<Uint8Array> {\n return aeskw(wrappingKey).encrypt(key);\n}\n","import { UTF8ToUint8 } from '../utils';\nimport { User, Email } from '../types';\nimport { concatBytes } from '@noble/hashes/utils.js';\n\nexport function userToBytes(user: User): Uint8Array {\n try {\n const json = JSON.stringify(user);\n return UTF8ToUint8(json);\n } catch (error) {\n throw new Error('Failed to convert User to bytes', { cause: error });\n }\n}\n\nexport function recipientsToBytes(recipients: User[]): Uint8Array {\n try {\n const array = recipients.map((user) => userToBytes(user));\n return concatBytes(...array);\n } catch (error) {\n throw new Error('Failed to convert recipients to bytes', { cause: error });\n }\n}\n\n/**\n * Converts an Email type into a Uint8Array array.\n *\n * @param email - The email.\n * @returns The Uint8Array array representation of the Email type.\n */\nexport function emailToBinary(email: Email): Uint8Array {\n try {\n const json = JSON.stringify(email);\n return UTF8ToUint8(json);\n } catch (error) {\n throw new Error('Failed to convert EmailBody to Uint8Array', { cause: error });\n }\n}\n","import { concatBytes } from '@noble/hashes/utils.js';\nimport { EmailPublicParameters } from '../types';\nimport { UTF8ToUint8, uuidToBytes } from '../utils';\nimport { userToBytes, recipientsToBytes } from './converters';\n\n/**\n * Creates an auxiliary string from public fields of the email.\n *\n * @param params - The email public parameters.\n * @param isSubjectEncrypted - Indicates if the email subject field should be encrypted\n * @returns The resulting auxiliary string\n */\nexport function getAux(params: EmailPublicParameters, isSubjectEncrypted: boolean): Uint8Array {\n try {\n const { subject, replyToEmailID, sender, recipient, recipients } = params;\n const replyBytes = replyToEmailID ? uuidToBytes(replyToEmailID) : new Uint8Array();\n const senderBytes = userToBytes(sender);\n const recipientBytes = userToBytes(recipient);\n const recipientsBytes = recipients ? recipientsToBytes(recipients) : new Uint8Array();\n\n if (isSubjectEncrypted) {\n return concatBytes(replyBytes, senderBytes, recipientBytes, recipientsBytes);\n } else {\n const subjectBytes = UTF8ToUint8(subject);\n return concatBytes(subjectBytes, replyBytes, senderBytes, recipientBytes, recipientsBytes);\n }\n } catch (error) {\n throw new Error('Failed to create aux', { cause: error });\n }\n}\n","import {\n HybridEncKey,\n PwdProtectedKey,\n PublicKeys,\n PrivateKeys,\n EmailBody,\n EmailBodyEncrypted,\n Email,\n EmailPublicParameters,\n} from '../types';\nimport { encryptSymmetrically, decryptSymmetrically, genSymmetricKey } from '../symmetric-crypto';\nimport { encapsulateKyber, decapsulateKyber } from '../post-quantum-crypto';\nimport { deriveWrappingKey, wrapKey, unwrapKey } from '../key-wrapper';\nimport { deriveSecretKey } from '../asymmetric-crypto';\nimport { getKeyFromPassword, getKeyFromPasswordAndSalt } from '../derive-key';\nimport { UTF8ToUint8, base64ToUint8Array, uint8ArrayToBase64, uint8ToUTF8, uuidToBytes } from '../utils';\nimport { getAux } from './utils';\n\nexport async function encryptEmailBody(\n email: Email,\n isSubjectEncrypted: boolean,\n): Promise<{\n enc: EmailBodyEncrypted;\n params: EmailPublicParameters;\n encryptionKey: Uint8Array;\n}> {\n try {\n const aux = getAux(email.params, isSubjectEncrypted);\n\n let enc: EmailBodyEncrypted;\n let encryptionKey: Uint8Array;\n let params = email.params;\n\n if (isSubjectEncrypted) {\n const result = await encryptEmailContentAndSubjectSymmetrically(email.body, email.params.subject, aux, email.id);\n enc = result.enc;\n encryptionKey = result.encryptionKey;\n params = { ...email.params, subject: result.encSubject };\n } else {\n const result = await encryptEmailContentSymmetrically(email.body, aux, email.id);\n enc = result.enc;\n encryptionKey = result.encryptionKey;\n }\n\n return { encryptionKey, enc, params };\n } catch (error) {\n throw new Error('Failed to encrypt email body', { cause: error });\n }\n}\n\nexport async function decryptEmailBody(\n enc: EmailBodyEncrypted,\n encParams: EmailPublicParameters,\n encryptionKey: Uint8Array,\n isSubjectEncrypted: boolean,\n): Promise<{\n params: EmailPublicParameters;\n body: EmailBody;\n}> {\n try {\n const aux = getAux(encParams, isSubjectEncrypted);\n let body: EmailBody;\n let params = encParams;\n if (isSubjectEncrypted) {\n const result = await decryptEmailAndSubjectSymmetrically(encryptionKey, aux, encParams.subject, enc);\n body = result.body;\n params = { ...encParams, subject: result.subject };\n } else {\n body = await decryptEmailSymmetrically(encryptionKey, aux, enc);\n }\n\n return { body, params };\n } catch (error) {\n throw new Error('Failed to encrypt email body', { cause: error });\n }\n}\n\n/**\n * Symmetrically encrypts an email with a randomly sampled key.\n *\n * @param email - The email to encrypt.\n * @param aux - The auxiliary data (e.g., email ID or timestamp) for AEAD.\n * @param emailID - The unique identifier of the email.\n * @returns The resulting ciphertext and the used symmetric key\n */\nexport async function encryptEmailContentSymmetrically(\n email: EmailBody,\n aux: Uint8Array,\n emailID: string,\n): Promise<{ enc: EmailBodyEncrypted; encryptionKey: Uint8Array }> {\n try {\n if (!email.text) {\n throw new Error('Invalid input');\n }\n const encryptionKey = genSymmetricKey();\n const enc = await encryptEmailContentSymmetricallyWithKey(email, encryptionKey, aux, emailID);\n return { enc, encryptionKey };\n } catch (error) {\n throw new Error('Failed to symmetrically encrypt email', { cause: error });\n }\n}\n\n/**\n * Symmetrically encrypts an email with a randomly sampled key.\n *\n * @param email - The email to encrypt.\n * @param subject - The email subject to encrypt.\n * @param aux - The auxiliary data (e.g., email ID or timestamp) for AEAD.\n * @param emailID - The unique identifier of the email.\n * @returns The resulting ciphertext and the used symmetric key\n */\nexport async function encryptEmailContentAndSubjectSymmetrically(\n email: EmailBody,\n subject: string,\n aux: Uint8Array,\n emailID: string,\n): Promise<{ enc: EmailBodyEncrypted; encSubject: string; encryptionKey: Uint8Array }> {\n try {\n if (!subject || !email.text) {\n throw new Error('Invalid input');\n }\n const encryptionKey = genSymmetricKey();\n const enc = await encryptEmailContentSymmetricallyWithKey(email, encryptionKey, aux, emailID);\n const subjectBuff = UTF8ToUint8(subject);\n const subjectEnc = await encryptSymmetrically(encryptionKey, subjectBuff, aux);\n const encSubject = uint8ArrayToBase64(subjectEnc);\n return { enc, encSubject, encryptionKey };\n } catch (error) {\n throw new Error('Failed to symmetrically encrypt email and subject', { cause: error });\n }\n}\n\n/**\n * Decrypts symmetrically encrypted email.\n *\n * @param encryptedEmail - The email to decrypt.\n * @param encryptionKey - The symmetric key.\n * @returns The decrypted email\n */\nexport async function decryptEmailAndSubjectSymmetrically(\n encryptionKey: Uint8Array,\n aux: Uint8Array,\n encSubject: string,\n enc: EmailBodyEncrypted,\n): Promise<{ body: EmailBody; subject: string }> {\n try {\n const array = base64ToUint8Array(encSubject);\n const subjectArray = await decryptSymmetrically(encryptionKey, array, aux);\n const body = await decryptEmailSymmetrically(encryptionKey, aux, enc);\n const subject = uint8ToUTF8(subjectArray);\n return { body, subject };\n } catch (error) {\n throw new Error('Failed to symmetrically decrypt email and subject', { cause: error });\n }\n}\n\n/**\n * Symmetrically encrypts an email with a randomly sampled key.\n *\n * @param email - The email to encrypt.\n * @returns The resulting ciphertext and the used symmetric key\n */\nexport async function encryptEmailContentSymmetricallyWithKey(\n emailBody: EmailBody,\n encryptionKey: Uint8Array,\n aux: Uint8Array,\n emailID: string,\n): Promise<EmailBodyEncrypted> {\n try {\n const freeField = uuidToBytes(emailID);\n const text = UTF8ToUint8(emailBody.text);\n const encryptedText = await encryptSymmetrically(encryptionKey, text, aux, freeField);\n const encText = uint8ArrayToBase64(encryptedText);\n const result: EmailBodyEncrypted = { encText };\n\n if (emailBody.attachments) {\n const encryptedAttachements = await encryptEmailAttachements(emailBody.attachments, encryptionKey, aux, emailID);\n result.encAttachments = encryptedAttachements?.map(uint8ArrayToBase64);\n }\n return result;\n } catch (error) {\n throw new Error('Failed to symmetrically encrypt email with the given key', { cause: error });\n }\n}\n\nasync function encryptEmailAttachements(\n attachments: string[],\n encryptionKey: Uint8Array,\n aux: Uint8Array,\n emailID: string,\n): Promise<Uint8Array[]> {\n try {\n const freeField = uuidToBytes(emailID);\n const encryptedAttachments = await Promise.all(\n attachments.map((attachment) => {\n const binaryAttachment = UTF8ToUint8(attachment);\n return encryptSymmetrically(encryptionKey, binaryAttachment, aux, freeField);\n }),\n );\n return encryptedAttachments;\n } catch (error) {\n throw new Error('Failed to symmetrically encrypt email attachements', { cause: error });\n }\n}\n\nasync function decryptEmailAttachements(\n encryptedAttachments: Uint8Array[],\n encryptionKey: Uint8Array,\n aux: Uint8Array,\n): Promise<Uint8Array[]> {\n try {\n const decryptedAttachments = await Promise.all(\n encryptedAttachments.map((attachment) => {\n return decryptSymmetrically(encryptionKey, attachment, aux);\n }),\n );\n return decryptedAttachments;\n } catch (error) {\n throw new Error('Failed to symmetrically decrypt email attachements', { cause: error });\n }\n}\n\n/**\n * Decrypts symmetrically encrypted email.\n *\n * @param encryptedEmail - The email to decrypt.\n * @param encryptionKey - The symmetric key.\n * @returns The decrypted email\n */\nexport async function decryptEmailSymmetrically(\n encryptionKey: Uint8Array,\n aux: Uint8Array,\n enc: EmailBodyEncrypted,\n): Promise<EmailBody> {\n try {\n const cipher = base64ToUint8Array(enc.encText);\n const textArray = await decryptSymmetrically(encryptionKey, cipher, aux);\n const text = uint8ToUTF8(textArray);\n const result: EmailBody = { text };\n\n if (enc.encAttachments) {\n const encAttachements = enc.encAttachments?.map(base64ToUint8Array);\n const attachmentsArray = await decryptEmailAttachements(encAttachements, encryptionKey, aux);\n result.attachments = attachmentsArray?.map((att) => uint8ToUTF8(att));\n }\n return result;\n } catch (error) {\n throw new Error('Failed to symmetrically decrypt email', { cause: error });\n }\n}\n\n/**\n * Encrypts the email symmetric key using hybrid encryption.\n *\n * @param emailEncryptionKey - The symmetric key used for email encryption.\n * @param recipientPublicKey - The public key of the recipient.\n * @param senderPrivateKey - The private key of the sender.\n * @returns The encrypted email symmetric key\n */\nexport async function encryptKeysHybrid(\n emailEncryptionKey: Uint8Array,\n recipientPublicKey: PublicKeys,\n senderPrivateKey: PrivateKeys,\n): Promise<HybridEncKey> {\n try {\n const eccSecret = await deriveSecretKey(recipientPublicKey.eccPublicKey, senderPrivateKey.eccPrivateKey);\n const { cipherText: kyberCiphertext, sharedSecret: kyberSecret } = encapsulateKyber(\n recipientPublicKey.kyberPublicKey,\n );\n const wrappingKey = await deriveWrappingKey(eccSecret, kyberSecret);\n const encryptedKey = await wrapKey(emailEncryptionKey, wrappingKey);\n const encryptedKeyBase64 = uint8ArrayToBase64(encryptedKey);\n const kyberCiphertextBase64 = uint8ArrayToBase64(kyberCiphertext);\n\n return { encryptedKey: encryptedKeyBase64, kyberCiphertext: kyberCiphertextBase64 };\n } catch (error) {\n throw new Error('Failed to encrypt email key using hybrid encryption', { cause: error });\n }\n}\n\n/**\n * Decrypts the email symmetric key encrypted via hybrid encryption.\n *\n * @param encryptedKey - The encrypted email key.\n * @param senderPublicKey - The public key of the sender.\n * @param recipientPrivateKey - The private key of the recipient.\n * @returns The email encryption key\n */\nexport async function decryptKeysHybrid(\n encryptedKey: HybridEncKey,\n senderPublicKey: PublicKeys,\n recipientPrivateKey: PrivateKeys,\n): Promise<Uint8Array> {\n try {\n const kyberCiphertext = base64ToUint8Array(encryptedKey.kyberCiphertext);\n const encKey = base64ToUint8Array(encryptedKey.encryptedKey);\n const eccSecret = await deriveSecretKey(senderPublicKey.eccPublicKey, recipientPrivateKey.eccPrivateKey);\n const kyberSecret = decapsulateKyber(kyberCiphertext, recipientPrivateKey.kyberPrivateKey);\n const wrappingKey = await deriveWrappingKey(eccSecret, kyberSecret);\n const encryptionKey = await unwrapKey(encKey, wrappingKey);\n return encryptionKey;\n } catch (error) {\n throw new Error('Failed to decrypt email key encrypted via hybrid encryption', { cause: error });\n }\n}\n\n/**\n * Password-protects the email symmetric key.\n *\n * @param emailEncryptionKey - The symmetric key used for email encryption.\n * @param password - The secret password for key protection.\n * @returns The password-protected email symmetric key\n */\nexport async function passwordProtectKey(emailEncryptionKey: Uint8Array, password: string): Promise<PwdProtectedKey> {\n try {\n const { key, salt } = await getKeyFromPassword(password);\n const encryptedKey = await wrapKey(emailEncryptionKey, key);\n const saltStr = uint8ArrayToBase64(salt);\n const encryptedKeyStr = uint8ArrayToBase64(encryptedKey);\n return { encryptedKey: encryptedKeyStr, salt: saltStr };\n } catch (error) {\n throw new Error('Failed to password-protect email key', { cause: error });\n }\n}\n\n/**\n * Removes passoword-protection and exposes the email symmetric key.\n *\n * @param emailEncryptionKey - The password-protected email key.\n * @param password - The secret password for key protection.\n * @returns The email encryption key\n */\nexport async function removePasswordProtection(\n emailEncryptionKey: PwdProtectedKey,\n password: string,\n): Promise<Uint8Array> {\n try {\n const salt = base64ToUint8Array(emailEncryptionKey.salt);\n const encryptedKey = base64ToUint8Array(emailEncryptionKey.encryptedKey);\n const key = await getKeyFromPasswordAndSalt(password, salt);\n const encryptionKey = await unwrapKey(encryptedKey, key);\n return encryptionKey;\n } catch (error) {\n throw new Error('Failed to remove password-protection from email key', { cause: error });\n }\n}\n","import { PublicKeys, PrivateKeys, HybridEncryptedEmail, Email, UserWithPublicKeys } from '../types';\nimport { decryptEmailBody, encryptKeysHybrid, decryptKeysHybrid, encryptEmailBody } from './core';\n\n/**\n * Encrypts the email using hybrid encryption.\n *\n * @param email - The email to encrypt.\n * @param recipientPublicKeys - The public keys of the recipient.\n * @param senderPrivateKey - The private key of the sender.\n * @param isSubjectEncrypted - Indicates if the email subject field should be encrypted\n * @returns The encrypted email\n */\nexport async function encryptEmailHybrid(\n email: Email,\n recipient: UserWithPublicKeys,\n senderPrivateKey: PrivateKeys,\n isSubjectEncrypted: boolean = false,\n): Promise<HybridEncryptedEmail> {\n try {\n const { encryptionKey, params, enc } = await encryptEmailBody(email, isSubjectEncrypted);\n const encryptedKey = await encryptKeysHybrid(encryptionKey, recipient.publicKeys, senderPrivateKey);\n return { enc, encryptedKey, recipientEmail: recipient.email, params, isSubjectEncrypted, id: email.id };\n } catch (error) {\n throw new Error('Failed to encrypt email with hybrid encryption', { cause: error });\n }\n}\n\n/**\n * Encrypts the email using hybrid encryption for multiple recipients.\n *\n * @param email - The email to encrypt.\n * @param recipients - The recipients with corresponding public keys.\n * @param senderPrivateKey - The private key of the sender.\n * @param isSubjectEncrypted - Indicates if the email subject field should be encrypted\n * @returns The set of encrypted email\n */\nexport async function encryptEmailHybridForMultipleRecipients(\n email: Email,\n recipients: UserWithPublicKeys[],\n senderPrivateKey: PrivateKeys,\n isSubjectEncrypted: boolean = false,\n): Promise<HybridEncryptedEmail[]> {\n try {\n const { encryptionKey, params, enc } = await encryptEmailBody(email, isSubjectEncrypted);\n\n const encryptedEmails: HybridEncryptedEmail[] = [];\n for (const recipient of recipients) {\n const encryptedKey = await encryptKeysHybrid(encryptionKey, recipient.publicKeys, senderPrivateKey);\n encryptedEmails.push({\n enc,\n encryptedKey,\n recipientEmail: recipient.email,\n params,\n isSubjectEncrypted,\n id: email.id,\n });\n }\n return encryptedEmails;\n } catch (error) {\n throw new Error('Failed to encrypt email to multiple recipients with hybrid encryption', { cause: error });\n }\n}\n\n/**\n * Decrypts the email using hybrid encryption.\n *\n * @param encryptedEmail - The encrypted email.\n * @param senderPublicKeys - The public key of the sender.\n * @param recipientPrivateKeys - The private key of the recipient.\n * @returns The decrypted email\n */\nexport async function decryptEmailHybrid(\n encryptedEmail: HybridEncryptedEmail,\n senderPublicKeys: PublicKeys,\n recipientPrivateKeys: PrivateKeys,\n): Promise<Email> {\n try {\n const { isSubjectEncrypted, params: encParams, enc, encryptedKey, id } = encryptedEmail;\n const encryptionKey = await decryptKeysHybrid(encryptedKey, senderPublicKeys, recipientPrivateKeys);\n const { body, params } = await decryptEmailBody(enc, encParams, encryptionKey, isSubjectEncrypted);\n return { body, params, id };\n } catch (error) {\n throw new Error('Failed to decrypt email with hybrid encryption', { cause: error });\n }\n}\n","import { PwdProtectedEmail, Email } from '../types';\nimport { decryptEmailBody, passwordProtectKey, removePasswordProtection, encryptEmailBody } from './core';\n\n/**\n * Creates a password-protected email.\n *\n * @param email - The email to password-protect\n * @param password - The secret password shared among recipients\n * @param isSubjectEncrypted - Indicates if the email subject field should be encrypted\n * @returns The password-protected email\n */\nexport async function createPwdProtectedEmail(\n email: Email,\n password: string,\n isSubjectEncrypted: boolean = false,\n): Promise<PwdProtectedEmail> {\n try {\n if (!email?.body || !email.params) {\n throw new Error('Failed to password-protect email: Invalid email structure');\n }\n const { encryptionKey, params, enc } = await encryptEmailBody(email, isSubjectEncrypted);\n const encryptedKey = await passwordProtectKey(encryptionKey, password);\n\n return { enc, encryptedKey, params, id: email.id, isSubjectEncrypted };\n } catch (error) {\n throw new Error('Failed to password-protect email', { cause: error });\n }\n}\n\n/**\n * Opens a password-protected email.\n *\n * @param encryptedEmail - The encrypted email\n * @param password - The secret password shared among recipients.\n * @returns The decrypted email\n */\nexport async function decryptPwdProtectedEmail(encryptedEmail: PwdProtectedEmail, password: string): Promise<Email> {\n try {\n const { isSubjectEncrypted, params: encParams, enc, id } = encryptedEmail;\n const encryptionKey = await removePasswordProtection(encryptedEmail.encryptedKey, password);\n const { body, params } = await decryptEmailBody(enc, encParams, encryptionKey, isSubjectEncrypted);\n return { body, params, id };\n } catch (error) {\n throw new Error('Failed to decrypt password-protect email', { cause: error });\n }\n}\n","import { generateEccKeys } from '../asymmetric-crypto';\nimport { generateKyberKeys } from '../post-quantum-crypto';\nimport { EmailKeys } from '../types';\n\n/**\n * Generates public and private keys for email service.\n *\n * @returns The user's private and public keys\n */\nexport async function generateEmailKeys(): Promise<EmailKeys> {\n try {\n const kyberKeys = generateKyberKeys();\n const keys = await generateEccKeys();\n\n const emailKeys: EmailKeys = {\n publicKeys: {\n eccPublicKey: keys.publicKey,\n kyberPublicKey: kyberKeys.publicKey,\n },\n privateKeys: {\n eccPrivateKey: keys.privateKey,\n kyberPrivateKey: kyberKeys.secretKey,\n },\n };\n\n return emailKeys;\n } catch (error) {\n throw new Error('Failed to generate keys for email service', { cause: error });\n }\n}\n"],"mappings":"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"}
|