internxt-crypto 0.0.9-alpha → 0.0.10-alpha
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/asymmetric-crypto.d.mts +41 -0
- package/dist/asymmetric-crypto.d.ts +41 -0
- package/dist/asymmetric-crypto.js +92 -0
- package/dist/asymmetric-crypto.js.map +1 -0
- package/dist/asymmetric-crypto.mjs +85 -0
- package/dist/asymmetric-crypto.mjs.map +1 -0
- package/dist/constants.d.mts +39 -0
- package/dist/constants.d.ts +39 -0
- package/dist/constants.js +80 -0
- package/dist/constants.js.map +1 -0
- package/dist/constants.mjs +42 -0
- package/dist/constants.mjs.map +1 -0
- package/dist/derive-key.d.mts +91 -0
- package/dist/derive-key.d.ts +91 -0
- package/dist/derive-key.js +795 -0
- package/dist/derive-key.js.map +1 -0
- package/dist/derive-key.mjs +784 -0
- package/dist/derive-key.mjs.map +1 -0
- package/dist/email-crypto.d.mts +106 -0
- package/dist/email-crypto.d.ts +106 -0
- package/dist/email-crypto.js +1409 -0
- package/dist/email-crypto.js.map +1 -0
- package/dist/email-crypto.mjs +1381 -0
- package/dist/email-crypto.mjs.map +1 -0
- package/dist/email-search.d.mts +228 -0
- package/dist/email-search.d.ts +228 -0
- package/dist/email-search.js +605 -0
- package/dist/email-search.js.map +1 -0
- package/dist/email-search.mjs +580 -0
- package/dist/email-search.mjs.map +1 -0
- package/dist/email-service.d.mts +38 -0
- package/dist/email-service.d.ts +38 -0
- package/dist/email-service.js +154 -0
- package/dist/email-service.js.map +1 -0
- package/dist/email-service.mjs +147 -0
- package/dist/email-service.mjs.map +1 -0
- package/dist/hash.d.mts +59 -0
- package/dist/hash.d.ts +59 -0
- package/dist/hash.js +95 -0
- package/dist/hash.js.map +1 -0
- package/dist/hash.mjs +85 -0
- package/dist/hash.mjs.map +1 -0
- package/dist/index.d.mts +35 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.js +2697 -2054
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2073 -8247
- package/dist/index.mjs.map +1 -1
- package/dist/keystore-crypto.d.mts +66 -0
- package/dist/keystore-crypto.d.ts +66 -0
- package/dist/keystore-crypto.js +530 -0
- package/dist/keystore-crypto.js.map +1 -0
- package/dist/keystore-crypto.mjs +501 -0
- package/dist/keystore-crypto.mjs.map +1 -0
- package/dist/keystore-service.d.mts +82 -0
- package/dist/keystore-service.d.ts +82 -0
- package/dist/keystore-service.js +349 -0
- package/dist/keystore-service.js.map +1 -0
- package/dist/keystore-service.mjs +342 -0
- package/dist/keystore-service.mjs.map +1 -0
- package/dist/kyber768-B87rMQ7u.d.mts +30 -0
- package/dist/kyber768-B87rMQ7u.d.ts +30 -0
- package/dist/post-quantum-crypto.d.mts +72 -0
- package/dist/post-quantum-crypto.d.ts +72 -0
- package/dist/post-quantum-crypto.js +96 -0
- package/dist/post-quantum-crypto.js.map +1 -0
- package/dist/post-quantum-crypto.mjs +90 -0
- package/dist/post-quantum-crypto.mjs.map +1 -0
- package/dist/storage-service.d.mts +53 -0
- package/dist/storage-service.d.ts +53 -0
- package/dist/storage-service.js +70 -0
- package/dist/storage-service.js.map +1 -0
- package/dist/storage-service.mjs +67 -0
- package/dist/storage-service.mjs.map +1 -0
- package/dist/symmetric-crypto.d.mts +56 -0
- package/dist/symmetric-crypto.d.ts +56 -0
- package/dist/symmetric-crypto.js +142 -0
- package/dist/symmetric-crypto.js.map +1 -0
- package/dist/symmetric-crypto.mjs +134 -0
- package/dist/symmetric-crypto.mjs.map +1 -0
- package/dist/types.d.mts +102 -0
- package/dist/types.d.ts +102 -0
- package/dist/types.js +14 -0
- package/dist/types.js.map +1 -0
- package/dist/types.mjs +12 -0
- package/dist/types.mjs.map +1 -0
- package/dist/utils-BDaK_d6T.d.ts +114 -0
- package/dist/utils-v34IRTIx.d.mts +114 -0
- package/dist/utils.d.mts +140 -0
- package/dist/utils.d.ts +140 -0
- package/dist/utils.js +313 -0
- package/dist/utils.js.map +1 -0
- package/dist/utils.mjs +273 -0
- package/dist/utils.mjs.map +1 -0
- package/package.json +83 -7
- package/dist/__vite-browser-external-Dyvby5gX.js +0 -2
- package/dist/__vite-browser-external-Dyvby5gX.js.map +0 -1
- package/dist/__vite-browser-external-l0sNRNKZ.mjs +0 -2
- package/dist/__vite-browser-external-l0sNRNKZ.mjs.map +0 -1
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { EncryptionKeys, EncryptedKeystore, IdentityKeys } from './types.mjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Generates recovery codes
|
|
5
|
+
*
|
|
6
|
+
* @returns The generated recovery codes
|
|
7
|
+
*/
|
|
8
|
+
declare function generateRecoveryCodes(): string;
|
|
9
|
+
/**
|
|
10
|
+
* Generates encryption keys
|
|
11
|
+
*
|
|
12
|
+
* @returns The generated encryption keys
|
|
13
|
+
*/
|
|
14
|
+
declare function generateEncryptionKeys(): Promise<EncryptionKeys>;
|
|
15
|
+
/**
|
|
16
|
+
* Generates email encryption keys and creates encrypted encryption and recovery keystores
|
|
17
|
+
* The encryption key is derived from the base key (stored in session storage)
|
|
18
|
+
*
|
|
19
|
+
* @returns The encryption and recovery keystores
|
|
20
|
+
*/
|
|
21
|
+
declare function createEncryptionAndRecoveryKeystores(): Promise<{
|
|
22
|
+
encryptionKeystore: EncryptedKeystore;
|
|
23
|
+
recoveryKeystore: EncryptedKeystore;
|
|
24
|
+
recoveryCodes: string;
|
|
25
|
+
}>;
|
|
26
|
+
/**
|
|
27
|
+
* Opens the encryption keystore and returns the email encryption keys
|
|
28
|
+
* The decryption key is derived from the base key (stored in session storage)
|
|
29
|
+
*
|
|
30
|
+
* @param encryptedKeystore - The encrypted keystore containing encryption keys
|
|
31
|
+
* @returns The encryption keys
|
|
32
|
+
*/
|
|
33
|
+
declare function openEncryptionKeystore(encryptedKeystore: EncryptedKeystore): Promise<EncryptionKeys>;
|
|
34
|
+
/**
|
|
35
|
+
* Opens the recovery keystore and returns the email encryption keys
|
|
36
|
+
* The decryption key is derived from the base key (stored in session storage)
|
|
37
|
+
*
|
|
38
|
+
* @param recoveryCodes - The user's recovery codes
|
|
39
|
+
* @param encryptedKeystore - The encrypted keystore containing encryption keys
|
|
40
|
+
* @returns The encryption keys
|
|
41
|
+
*/
|
|
42
|
+
declare function openRecoveryKeystore(recoveryCodes: string, encryptedKeystore: EncryptedKeystore): Promise<EncryptionKeys>;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Generates user idenity keys
|
|
46
|
+
*
|
|
47
|
+
* @returns The user identity keys
|
|
48
|
+
*/
|
|
49
|
+
declare function generateIdentityKeys(): Promise<IdentityKeys>;
|
|
50
|
+
/**
|
|
51
|
+
* Generates user identity keys and creates an encrypted identity keystore
|
|
52
|
+
* The encryption key is derived from the base key (stored in session storage)
|
|
53
|
+
*
|
|
54
|
+
* @returns The encrypted idenity keystore
|
|
55
|
+
*/
|
|
56
|
+
declare function createIdentityKeystore(): Promise<EncryptedKeystore>;
|
|
57
|
+
/**
|
|
58
|
+
* Opens the encrypted identity keystore
|
|
59
|
+
* The decryption key is derived from the base key (stored in session storage)
|
|
60
|
+
*
|
|
61
|
+
* @param encryptedKeystore - The encrypted identity keystore
|
|
62
|
+
* @returns The identity keys
|
|
63
|
+
*/
|
|
64
|
+
declare function openIdentityKeystore(encryptedKeystore: EncryptedKeystore): Promise<IdentityKeys>;
|
|
65
|
+
|
|
66
|
+
export { createEncryptionAndRecoveryKeystores, createIdentityKeystore, generateEncryptionKeys, generateIdentityKeys, generateRecoveryCodes, openEncryptionKeystore, openIdentityKeystore, openRecoveryKeystore };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { EncryptionKeys, EncryptedKeystore, IdentityKeys } from './types.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Generates recovery codes
|
|
5
|
+
*
|
|
6
|
+
* @returns The generated recovery codes
|
|
7
|
+
*/
|
|
8
|
+
declare function generateRecoveryCodes(): string;
|
|
9
|
+
/**
|
|
10
|
+
* Generates encryption keys
|
|
11
|
+
*
|
|
12
|
+
* @returns The generated encryption keys
|
|
13
|
+
*/
|
|
14
|
+
declare function generateEncryptionKeys(): Promise<EncryptionKeys>;
|
|
15
|
+
/**
|
|
16
|
+
* Generates email encryption keys and creates encrypted encryption and recovery keystores
|
|
17
|
+
* The encryption key is derived from the base key (stored in session storage)
|
|
18
|
+
*
|
|
19
|
+
* @returns The encryption and recovery keystores
|
|
20
|
+
*/
|
|
21
|
+
declare function createEncryptionAndRecoveryKeystores(): Promise<{
|
|
22
|
+
encryptionKeystore: EncryptedKeystore;
|
|
23
|
+
recoveryKeystore: EncryptedKeystore;
|
|
24
|
+
recoveryCodes: string;
|
|
25
|
+
}>;
|
|
26
|
+
/**
|
|
27
|
+
* Opens the encryption keystore and returns the email encryption keys
|
|
28
|
+
* The decryption key is derived from the base key (stored in session storage)
|
|
29
|
+
*
|
|
30
|
+
* @param encryptedKeystore - The encrypted keystore containing encryption keys
|
|
31
|
+
* @returns The encryption keys
|
|
32
|
+
*/
|
|
33
|
+
declare function openEncryptionKeystore(encryptedKeystore: EncryptedKeystore): Promise<EncryptionKeys>;
|
|
34
|
+
/**
|
|
35
|
+
* Opens the recovery keystore and returns the email encryption keys
|
|
36
|
+
* The decryption key is derived from the base key (stored in session storage)
|
|
37
|
+
*
|
|
38
|
+
* @param recoveryCodes - The user's recovery codes
|
|
39
|
+
* @param encryptedKeystore - The encrypted keystore containing encryption keys
|
|
40
|
+
* @returns The encryption keys
|
|
41
|
+
*/
|
|
42
|
+
declare function openRecoveryKeystore(recoveryCodes: string, encryptedKeystore: EncryptedKeystore): Promise<EncryptionKeys>;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Generates user idenity keys
|
|
46
|
+
*
|
|
47
|
+
* @returns The user identity keys
|
|
48
|
+
*/
|
|
49
|
+
declare function generateIdentityKeys(): Promise<IdentityKeys>;
|
|
50
|
+
/**
|
|
51
|
+
* Generates user identity keys and creates an encrypted identity keystore
|
|
52
|
+
* The encryption key is derived from the base key (stored in session storage)
|
|
53
|
+
*
|
|
54
|
+
* @returns The encrypted idenity keystore
|
|
55
|
+
*/
|
|
56
|
+
declare function createIdentityKeystore(): Promise<EncryptedKeystore>;
|
|
57
|
+
/**
|
|
58
|
+
* Opens the encrypted identity keystore
|
|
59
|
+
* The decryption key is derived from the base key (stored in session storage)
|
|
60
|
+
*
|
|
61
|
+
* @param encryptedKeystore - The encrypted identity keystore
|
|
62
|
+
* @returns The identity keys
|
|
63
|
+
*/
|
|
64
|
+
declare function openIdentityKeystore(encryptedKeystore: EncryptedKeystore): Promise<IdentityKeys>;
|
|
65
|
+
|
|
66
|
+
export { createEncryptionAndRecoveryKeystores, createIdentityKeystore, generateEncryptionKeys, generateIdentityKeys, generateRecoveryCodes, openEncryptionKeystore, openIdentityKeystore, openRecoveryKeystore };
|
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var utils_js = require('@noble/hashes/utils.js');
|
|
4
|
+
var bip39 = require('@scure/bip39');
|
|
5
|
+
var english = require('@scure/bip39/wordlists/english');
|
|
6
|
+
var blake3_js = require('@noble/hashes/blake3.js');
|
|
7
|
+
var utils_js$1 = require('@noble/post-quantum/utils.js');
|
|
8
|
+
var mlKem_js = require('@noble/post-quantum/ml-kem.js');
|
|
9
|
+
|
|
10
|
+
function _interopNamespace(e) {
|
|
11
|
+
if (e && e.__esModule) return e;
|
|
12
|
+
var n = Object.create(null);
|
|
13
|
+
if (e) {
|
|
14
|
+
Object.keys(e).forEach(function (k) {
|
|
15
|
+
if (k !== 'default') {
|
|
16
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
17
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
get: function () { return e[k]; }
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
n.default = e;
|
|
25
|
+
return Object.freeze(n);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
var bip39__namespace = /*#__PURE__*/_interopNamespace(bip39);
|
|
29
|
+
|
|
30
|
+
// src/utils/converters.ts
|
|
31
|
+
function UTF8ToUint8(str) {
|
|
32
|
+
return new TextEncoder().encode(str);
|
|
33
|
+
}
|
|
34
|
+
function uint8ArrayToBase64(buffer) {
|
|
35
|
+
const array = Uint16Array.from(buffer);
|
|
36
|
+
const binaryString = new TextDecoder("UTF-16").decode(array);
|
|
37
|
+
return btoa(binaryString);
|
|
38
|
+
}
|
|
39
|
+
function base64ToUint8Array(str) {
|
|
40
|
+
const binaryString = atob(str);
|
|
41
|
+
const len = binaryString.length;
|
|
42
|
+
const array = new Uint8Array(len);
|
|
43
|
+
for (let i = 0; i < len; i++) {
|
|
44
|
+
array[i] = binaryString.charCodeAt(i);
|
|
45
|
+
}
|
|
46
|
+
return new Uint8Array(array.buffer);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/constants.ts
|
|
50
|
+
var AES_ALGORITHM = "AES-GCM";
|
|
51
|
+
var AES_KEY_BIT_LENGTH = 256;
|
|
52
|
+
var AUX_LEN = 128;
|
|
53
|
+
var IV_LEN_BYTES = 16;
|
|
54
|
+
var KEY_FORMAT = "raw";
|
|
55
|
+
var ECC_ALGORITHM = "X25519";
|
|
56
|
+
var CONTEXT_LOGIN = "CRYPTO library 2025-07-26 16:18:03 key for opening identity keystore";
|
|
57
|
+
var CONTEXT_ENC_KEYSTORE = "CRYPTO library 2025-07-30 16:18:03 key for opening encryption keys keystore";
|
|
58
|
+
var CONTEXT_RECOVERY = "CRYPTO library 2025-07-30 16:20:00 key for account recovery";
|
|
59
|
+
var IDENTITY_KEYSTORE_TAG = "Identity keystore";
|
|
60
|
+
var ENCRYPTION_KEYSTORE_TAG = "Encryption keystore";
|
|
61
|
+
var RECOVERY_KEYSTORE_TAG = "Key recovery keystroe";
|
|
62
|
+
|
|
63
|
+
// src/asymmetric-crypto/keys.ts
|
|
64
|
+
async function generateEccKeys() {
|
|
65
|
+
try {
|
|
66
|
+
return await crypto.subtle.generateKey(
|
|
67
|
+
{
|
|
68
|
+
name: ECC_ALGORITHM
|
|
69
|
+
},
|
|
70
|
+
true,
|
|
71
|
+
["deriveBits"]
|
|
72
|
+
);
|
|
73
|
+
} catch (error) {
|
|
74
|
+
throw new Error("Failed to generate elliptic curve key pair", { cause: error });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async function exportPublicKey(key) {
|
|
78
|
+
try {
|
|
79
|
+
const result = await crypto.subtle.exportKey("spki", key);
|
|
80
|
+
return new Uint8Array(result);
|
|
81
|
+
} catch (error) {
|
|
82
|
+
throw new Error("Failed to export public key", { cause: error });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async function importPublicKey(spkiKeyData) {
|
|
86
|
+
try {
|
|
87
|
+
return await crypto.subtle.importKey(
|
|
88
|
+
"spki",
|
|
89
|
+
spkiKeyData,
|
|
90
|
+
{
|
|
91
|
+
name: ECC_ALGORITHM
|
|
92
|
+
},
|
|
93
|
+
true,
|
|
94
|
+
[]
|
|
95
|
+
);
|
|
96
|
+
} catch (error) {
|
|
97
|
+
throw new Error("Failed to import public key", { cause: error });
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async function exportPrivateKey(key) {
|
|
101
|
+
try {
|
|
102
|
+
const result = await crypto.subtle.exportKey("pkcs8", key);
|
|
103
|
+
return new Uint8Array(result);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
throw new Error("Failed to export private key", { cause: error });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async function importPrivateKey(pkcs8KeyData) {
|
|
109
|
+
try {
|
|
110
|
+
return await crypto.subtle.importKey(
|
|
111
|
+
"pkcs8",
|
|
112
|
+
pkcs8KeyData,
|
|
113
|
+
{
|
|
114
|
+
name: ECC_ALGORITHM
|
|
115
|
+
},
|
|
116
|
+
true,
|
|
117
|
+
["deriveBits"]
|
|
118
|
+
);
|
|
119
|
+
} catch (error) {
|
|
120
|
+
throw new Error("Failed to import private key", { cause: error });
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// src/utils/keyConverters.ts
|
|
125
|
+
async function identityKeysToBase64(keys) {
|
|
126
|
+
try {
|
|
127
|
+
const pkArray = await exportPublicKey(keys.userPublicKey);
|
|
128
|
+
const skArray = await exportPrivateKey(keys.userPrivateKey);
|
|
129
|
+
const json = JSON.stringify({
|
|
130
|
+
userPublicKey: uint8ArrayToBase64(pkArray),
|
|
131
|
+
userPrivateKey: uint8ArrayToBase64(skArray)
|
|
132
|
+
});
|
|
133
|
+
const base64 = btoa(json);
|
|
134
|
+
return base64;
|
|
135
|
+
} catch (error) {
|
|
136
|
+
throw new Error("Failed to convert identity keys to base64", { cause: error });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
async function encryptionKeysToBase64(keys) {
|
|
140
|
+
try {
|
|
141
|
+
const pkArray = await exportPublicKey(keys.userPublicKey);
|
|
142
|
+
const skArray = await exportPrivateKey(keys.userPrivateKey);
|
|
143
|
+
const json = JSON.stringify({
|
|
144
|
+
userPublicKey: uint8ArrayToBase64(pkArray),
|
|
145
|
+
userPrivateKey: uint8ArrayToBase64(skArray),
|
|
146
|
+
userPublicKyberKey: uint8ArrayToBase64(keys.userPublicKyberKey),
|
|
147
|
+
userPrivateKyberKey: uint8ArrayToBase64(keys.userPrivateKyberKey)
|
|
148
|
+
});
|
|
149
|
+
const base64 = btoa(json);
|
|
150
|
+
return base64;
|
|
151
|
+
} catch (error) {
|
|
152
|
+
throw new Error("Failed to convert identity keys to base64", { cause: error });
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async function base64ToIdentityKeys(base64) {
|
|
156
|
+
try {
|
|
157
|
+
const json = atob(base64);
|
|
158
|
+
const obj = JSON.parse(json);
|
|
159
|
+
const pkArray = base64ToUint8Array(obj.userPublicKey);
|
|
160
|
+
const skArray = base64ToUint8Array(obj.userPrivateKey);
|
|
161
|
+
const pkCryptoKey = await importPublicKey(pkArray);
|
|
162
|
+
const skCryptoKey = await importPrivateKey(skArray);
|
|
163
|
+
const result = {
|
|
164
|
+
userPublicKey: pkCryptoKey,
|
|
165
|
+
userPrivateKey: skCryptoKey
|
|
166
|
+
};
|
|
167
|
+
return result;
|
|
168
|
+
} catch (error) {
|
|
169
|
+
throw new Error("Failed convert base64 to idenity key", { cause: error });
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async function base64ToEncryptionKeys(base64) {
|
|
173
|
+
try {
|
|
174
|
+
const json = atob(base64);
|
|
175
|
+
const obj = JSON.parse(json);
|
|
176
|
+
const pkArray = base64ToUint8Array(obj.userPublicKey);
|
|
177
|
+
const skArray = base64ToUint8Array(obj.userPrivateKey);
|
|
178
|
+
const pkCryptoKey = await importPublicKey(pkArray);
|
|
179
|
+
const skCryptoKey = await importPrivateKey(skArray);
|
|
180
|
+
const pkKyber = base64ToUint8Array(obj.userPublicKyberKey);
|
|
181
|
+
const skKyber = base64ToUint8Array(obj.userPrivateKyberKey);
|
|
182
|
+
const result = {
|
|
183
|
+
userPublicKey: pkCryptoKey,
|
|
184
|
+
userPrivateKey: skCryptoKey,
|
|
185
|
+
userPublicKyberKey: pkKyber,
|
|
186
|
+
userPrivateKyberKey: skKyber
|
|
187
|
+
};
|
|
188
|
+
return result;
|
|
189
|
+
} catch (error) {
|
|
190
|
+
throw new Error("Failed to convert base64 to encryption key", { cause: error });
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
function genMnemonic(bits) {
|
|
194
|
+
return bip39__namespace.generateMnemonic(english.wordlist, bits);
|
|
195
|
+
}
|
|
196
|
+
function getBytesFromString(bytes, value) {
|
|
197
|
+
return blake3_js.blake3(utils_js.utf8ToBytes(value), { dkLen: bytes });
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// src/symmetric-crypto/keys.ts
|
|
201
|
+
async function importSymmetricCryptoKey(keyData) {
|
|
202
|
+
return crypto.subtle.importKey(
|
|
203
|
+
KEY_FORMAT,
|
|
204
|
+
new Uint8Array(keyData),
|
|
205
|
+
{
|
|
206
|
+
name: AES_ALGORITHM,
|
|
207
|
+
length: AES_KEY_BIT_LENGTH
|
|
208
|
+
},
|
|
209
|
+
true,
|
|
210
|
+
["encrypt", "decrypt"]
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
async function createNISTbasedIV(freeField) {
|
|
214
|
+
try {
|
|
215
|
+
if (!freeField) {
|
|
216
|
+
return utils_js$1.randomBytes(IV_LEN_BYTES);
|
|
217
|
+
}
|
|
218
|
+
const iv = new Uint8Array(16);
|
|
219
|
+
const randFiled = utils_js$1.randomBytes(12);
|
|
220
|
+
iv.set(randFiled, 0);
|
|
221
|
+
const freeFiledFixedLength = await getBytesFromString(4, freeField);
|
|
222
|
+
iv.set(freeFiledFixedLength, 12);
|
|
223
|
+
return iv;
|
|
224
|
+
} catch (error) {
|
|
225
|
+
throw new Error("Failed to create IV", { cause: error });
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
async function makeAuxFixedLength(aux) {
|
|
229
|
+
return getBytesFromString(AUX_LEN / 8, aux);
|
|
230
|
+
}
|
|
231
|
+
async function encryptMessage(message, encryptionKey, iv, additionalData) {
|
|
232
|
+
try {
|
|
233
|
+
const encrypted = await crypto.subtle.encrypt(
|
|
234
|
+
{ name: AES_ALGORITHM, iv, additionalData },
|
|
235
|
+
encryptionKey,
|
|
236
|
+
message
|
|
237
|
+
);
|
|
238
|
+
return new Uint8Array(encrypted);
|
|
239
|
+
} catch (error) {
|
|
240
|
+
throw new Error("Failed to encrypt symmetrically", { cause: error });
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
async function decryptMessage(ciphertext, iv, encryptionKey, additionalData) {
|
|
244
|
+
try {
|
|
245
|
+
const decrypted = await crypto.subtle.decrypt(
|
|
246
|
+
{ name: AES_ALGORITHM, iv, additionalData },
|
|
247
|
+
encryptionKey,
|
|
248
|
+
ciphertext
|
|
249
|
+
);
|
|
250
|
+
return new Uint8Array(decrypted);
|
|
251
|
+
} catch (error) {
|
|
252
|
+
throw new Error("Failed to decrypt symmetrically", { cause: error });
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// src/symmetric-crypto/aes.ts
|
|
257
|
+
async function encryptSymmetrically(encryptionKey, message, aux, freeField) {
|
|
258
|
+
try {
|
|
259
|
+
const iv = await createNISTbasedIV(freeField);
|
|
260
|
+
const additionalData = await makeAuxFixedLength(aux);
|
|
261
|
+
const ciphertext = await encryptMessage(message, encryptionKey, iv, additionalData);
|
|
262
|
+
return { ciphertext, iv };
|
|
263
|
+
} catch (error) {
|
|
264
|
+
throw new Error("Failed to encrypt symmetrically", { cause: error });
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
async function decryptSymmetrically(encryptionKey, encryptedMessage, aux) {
|
|
268
|
+
try {
|
|
269
|
+
const additionalData = await makeAuxFixedLength(aux);
|
|
270
|
+
const result = await decryptMessage(
|
|
271
|
+
encryptedMessage.ciphertext,
|
|
272
|
+
encryptedMessage.iv,
|
|
273
|
+
encryptionKey,
|
|
274
|
+
additionalData
|
|
275
|
+
);
|
|
276
|
+
return result;
|
|
277
|
+
} catch (error) {
|
|
278
|
+
throw new Error("Failed to decrypt symmetrically", { cause: error });
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// src/storage-service/sessionStorageService.ts
|
|
283
|
+
function get(key) {
|
|
284
|
+
return sessionStorage.getItem(key);
|
|
285
|
+
}
|
|
286
|
+
function set(key, value) {
|
|
287
|
+
return sessionStorage.setItem(key, value);
|
|
288
|
+
}
|
|
289
|
+
function removeItem(key) {
|
|
290
|
+
sessionStorage.removeItem(key);
|
|
291
|
+
}
|
|
292
|
+
function exists(key) {
|
|
293
|
+
return !!sessionStorage.getItem(key);
|
|
294
|
+
}
|
|
295
|
+
function clear() {
|
|
296
|
+
sessionStorage.clear();
|
|
297
|
+
}
|
|
298
|
+
var sessionStorageService = {
|
|
299
|
+
set,
|
|
300
|
+
get,
|
|
301
|
+
removeItem,
|
|
302
|
+
exists,
|
|
303
|
+
clear
|
|
304
|
+
};
|
|
305
|
+
var sessionStorageService_default = sessionStorageService;
|
|
306
|
+
function deriveSymmetricKeyFromContext(context, baseKey) {
|
|
307
|
+
return blake3_js.blake3(baseKey, { context: UTF8ToUint8(context) });
|
|
308
|
+
}
|
|
309
|
+
async function deriveSymmetricCryptoKeyFromContext(context, baseKey) {
|
|
310
|
+
try {
|
|
311
|
+
if (baseKey.length != AES_KEY_BIT_LENGTH / 8) {
|
|
312
|
+
throw new Error(`Base key length must be exactly ${AES_KEY_BIT_LENGTH / 8} bytes`);
|
|
313
|
+
}
|
|
314
|
+
if (!context) {
|
|
315
|
+
throw new Error("Context is empry");
|
|
316
|
+
}
|
|
317
|
+
const keyBytes = deriveSymmetricKeyFromContext(context, baseKey);
|
|
318
|
+
const key = await importSymmetricCryptoKey(keyBytes);
|
|
319
|
+
return key;
|
|
320
|
+
} catch (error) {
|
|
321
|
+
throw new Error("Failed to derive CryptoKey from base key and context", { cause: error });
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// src/keystore-crypto/core.ts
|
|
326
|
+
async function encryptKeystoreContent(secretKey, content, userID, tag) {
|
|
327
|
+
try {
|
|
328
|
+
const aux = userID + tag;
|
|
329
|
+
const message = base64ToUint8Array(content);
|
|
330
|
+
const result = await encryptSymmetrically(secretKey, message, aux);
|
|
331
|
+
return result;
|
|
332
|
+
} catch (error) {
|
|
333
|
+
throw new Error("Failed to encrypt keystore content", { cause: error });
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
async function decryptKeystoreContent(secretKey, encryptedKeys, userID, tag) {
|
|
337
|
+
try {
|
|
338
|
+
const aux = userID + tag;
|
|
339
|
+
const content = await decryptSymmetrically(secretKey, encryptedKeys, aux);
|
|
340
|
+
const result = uint8ArrayToBase64(content);
|
|
341
|
+
return result;
|
|
342
|
+
} catch (error) {
|
|
343
|
+
throw new Error("Failed to decrypt keystore content", { cause: error });
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
function getUserID() {
|
|
347
|
+
try {
|
|
348
|
+
const userID = sessionStorageService_default.get("userID");
|
|
349
|
+
if (!userID) {
|
|
350
|
+
throw new Error("No UserID");
|
|
351
|
+
}
|
|
352
|
+
return userID;
|
|
353
|
+
} catch (error) {
|
|
354
|
+
throw new Error("Failed to get UserID from session storage", { cause: error });
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
function getBaseKey() {
|
|
358
|
+
try {
|
|
359
|
+
const baseKeyBase64 = sessionStorageService_default.get("baseKey");
|
|
360
|
+
if (!baseKeyBase64) {
|
|
361
|
+
throw new Error("No base key");
|
|
362
|
+
}
|
|
363
|
+
return base64ToUint8Array(baseKeyBase64);
|
|
364
|
+
} catch (error) {
|
|
365
|
+
throw new Error("Failed to get base key from session storage", { cause: error });
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
async function deriveIdentityKeystoreKey(baseKey) {
|
|
369
|
+
return deriveSymmetricCryptoKeyFromContext(CONTEXT_LOGIN, baseKey);
|
|
370
|
+
}
|
|
371
|
+
async function deriveRecoveryKey(recoveryCodes) {
|
|
372
|
+
const recoveryCodesBuffer = await getBytesFromString(AES_KEY_BIT_LENGTH / 8, recoveryCodes);
|
|
373
|
+
return deriveSymmetricCryptoKeyFromContext(CONTEXT_RECOVERY, recoveryCodesBuffer);
|
|
374
|
+
}
|
|
375
|
+
async function deriveEncryptionKeystoreKey(baseKey) {
|
|
376
|
+
return deriveSymmetricCryptoKeyFromContext(CONTEXT_ENC_KEYSTORE, baseKey);
|
|
377
|
+
}
|
|
378
|
+
function generateKyberKeys(seed) {
|
|
379
|
+
try {
|
|
380
|
+
return mlKem_js.ml_kem768.keygen(seed);
|
|
381
|
+
} catch (error) {
|
|
382
|
+
throw new Error("Failed to generate Kyber keys", { cause: error });
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// src/keystore-crypto/emailEncryptionKey.ts
|
|
387
|
+
function generateRecoveryCodes() {
|
|
388
|
+
return genMnemonic(AES_KEY_BIT_LENGTH);
|
|
389
|
+
}
|
|
390
|
+
async function generateEncryptionKeys() {
|
|
391
|
+
try {
|
|
392
|
+
const keyPair = await generateEccKeys();
|
|
393
|
+
const keyPairKyber = generateKyberKeys();
|
|
394
|
+
const result = {
|
|
395
|
+
userPrivateKey: keyPair.privateKey,
|
|
396
|
+
userPublicKey: keyPair.publicKey,
|
|
397
|
+
userPublicKyberKey: keyPairKyber.publicKey,
|
|
398
|
+
userPrivateKyberKey: keyPairKyber.secretKey
|
|
399
|
+
};
|
|
400
|
+
return result;
|
|
401
|
+
} catch (error) {
|
|
402
|
+
throw new Error("Failed to generate encryption keys", { cause: error });
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
async function createEncryptionAndRecoveryKeystores() {
|
|
406
|
+
try {
|
|
407
|
+
const userID = getUserID();
|
|
408
|
+
const baseKey = getBaseKey();
|
|
409
|
+
const keys = await generateEncryptionKeys();
|
|
410
|
+
const content = await encryptionKeysToBase64(keys);
|
|
411
|
+
const secretKey = await deriveEncryptionKeystoreKey(baseKey);
|
|
412
|
+
const ciphertext = await encryptKeystoreContent(secretKey, content, userID, ENCRYPTION_KEYSTORE_TAG);
|
|
413
|
+
const encryptionKeystore = {
|
|
414
|
+
userID,
|
|
415
|
+
type: "encryption" /* ENCRYPTION */,
|
|
416
|
+
encryptedKeys: ciphertext
|
|
417
|
+
};
|
|
418
|
+
const recoveryCodes = generateRecoveryCodes();
|
|
419
|
+
const recoveryKey = await deriveRecoveryKey(recoveryCodes);
|
|
420
|
+
const encKeys = await encryptKeystoreContent(recoveryKey, content, userID, RECOVERY_KEYSTORE_TAG);
|
|
421
|
+
const recoveryKeystore = {
|
|
422
|
+
userID,
|
|
423
|
+
type: "recovery" /* RECOVERY */,
|
|
424
|
+
encryptedKeys: encKeys
|
|
425
|
+
};
|
|
426
|
+
return { encryptionKeystore, recoveryKeystore, recoveryCodes };
|
|
427
|
+
} catch (error) {
|
|
428
|
+
throw new Error("Failed to create encryption and recovery keystores", { cause: error });
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
async function openEncryptionKeystore(encryptedKeystore) {
|
|
432
|
+
try {
|
|
433
|
+
if (encryptedKeystore.type != "encryption" /* ENCRYPTION */) {
|
|
434
|
+
throw new Error("Input is invalid");
|
|
435
|
+
}
|
|
436
|
+
const baseKey = getBaseKey();
|
|
437
|
+
const secretKey = await deriveEncryptionKeystoreKey(baseKey);
|
|
438
|
+
const json = await decryptKeystoreContent(
|
|
439
|
+
secretKey,
|
|
440
|
+
encryptedKeystore.encryptedKeys,
|
|
441
|
+
encryptedKeystore.userID,
|
|
442
|
+
ENCRYPTION_KEYSTORE_TAG
|
|
443
|
+
);
|
|
444
|
+
const keys = await base64ToEncryptionKeys(json);
|
|
445
|
+
return keys;
|
|
446
|
+
} catch (error) {
|
|
447
|
+
throw new Error("Failed to open encryption keystore", { cause: error });
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
async function openRecoveryKeystore(recoveryCodes, encryptedKeystore) {
|
|
451
|
+
try {
|
|
452
|
+
if (encryptedKeystore.type != "recovery" /* RECOVERY */) {
|
|
453
|
+
throw new Error("Input is invalid");
|
|
454
|
+
}
|
|
455
|
+
const recoveryKey = await deriveRecoveryKey(recoveryCodes);
|
|
456
|
+
const json = await decryptKeystoreContent(
|
|
457
|
+
recoveryKey,
|
|
458
|
+
encryptedKeystore.encryptedKeys,
|
|
459
|
+
encryptedKeystore.userID,
|
|
460
|
+
RECOVERY_KEYSTORE_TAG
|
|
461
|
+
);
|
|
462
|
+
const keys = await base64ToEncryptionKeys(json);
|
|
463
|
+
return keys;
|
|
464
|
+
} catch (error) {
|
|
465
|
+
throw new Error("Failed to open recovery keystore", { cause: error });
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// src/keystore-crypto/userIdenityKey.ts
|
|
470
|
+
async function generateIdentityKeys() {
|
|
471
|
+
try {
|
|
472
|
+
const keyPair = await generateEccKeys();
|
|
473
|
+
const result = {
|
|
474
|
+
userPrivateKey: keyPair.privateKey,
|
|
475
|
+
userPublicKey: keyPair.publicKey
|
|
476
|
+
};
|
|
477
|
+
return result;
|
|
478
|
+
} catch (error) {
|
|
479
|
+
throw new Error("Failed to generate idenity keys", { cause: error });
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
async function createIdentityKeystore() {
|
|
483
|
+
try {
|
|
484
|
+
const type = "identity" /* IDENTITY */;
|
|
485
|
+
const userID = getUserID();
|
|
486
|
+
const baseKey = getBaseKey();
|
|
487
|
+
const keys = await generateIdentityKeys();
|
|
488
|
+
const content = await identityKeysToBase64(keys);
|
|
489
|
+
const secretKey = await deriveIdentityKeystoreKey(baseKey);
|
|
490
|
+
const encryptedKeys = await encryptKeystoreContent(secretKey, content, userID, IDENTITY_KEYSTORE_TAG);
|
|
491
|
+
const result = {
|
|
492
|
+
userID,
|
|
493
|
+
type,
|
|
494
|
+
encryptedKeys
|
|
495
|
+
};
|
|
496
|
+
return result;
|
|
497
|
+
} catch (error) {
|
|
498
|
+
throw new Error("Failed to create identity keystore", { cause: error });
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
async function openIdentityKeystore(encryptedKeystore) {
|
|
502
|
+
try {
|
|
503
|
+
if (encryptedKeystore.type != "identity" /* IDENTITY */) {
|
|
504
|
+
throw new Error("Input is invalid");
|
|
505
|
+
}
|
|
506
|
+
const baseKey = getBaseKey();
|
|
507
|
+
const secretKey = await deriveIdentityKeystoreKey(baseKey);
|
|
508
|
+
const json = await decryptKeystoreContent(
|
|
509
|
+
secretKey,
|
|
510
|
+
encryptedKeystore.encryptedKeys,
|
|
511
|
+
encryptedKeystore.userID,
|
|
512
|
+
IDENTITY_KEYSTORE_TAG
|
|
513
|
+
);
|
|
514
|
+
const keys = await base64ToIdentityKeys(json);
|
|
515
|
+
return keys;
|
|
516
|
+
} catch (error) {
|
|
517
|
+
throw new Error("Failed to open identity keystore", { cause: error });
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
exports.createEncryptionAndRecoveryKeystores = createEncryptionAndRecoveryKeystores;
|
|
522
|
+
exports.createIdentityKeystore = createIdentityKeystore;
|
|
523
|
+
exports.generateEncryptionKeys = generateEncryptionKeys;
|
|
524
|
+
exports.generateIdentityKeys = generateIdentityKeys;
|
|
525
|
+
exports.generateRecoveryCodes = generateRecoveryCodes;
|
|
526
|
+
exports.openEncryptionKeystore = openEncryptionKeystore;
|
|
527
|
+
exports.openIdentityKeystore = openIdentityKeystore;
|
|
528
|
+
exports.openRecoveryKeystore = openRecoveryKeystore;
|
|
529
|
+
//# sourceMappingURL=keystore-crypto.js.map
|
|
530
|
+
//# sourceMappingURL=keystore-crypto.js.map
|