@majikah/majik-key 0.1.1 → 0.1.3
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/README.md +80 -55
- package/dist/core/crypto/constants.d.ts +50 -0
- package/dist/core/crypto/constants.js +48 -0
- package/dist/core/crypto/crypto-provider.d.ts +97 -0
- package/dist/core/crypto/crypto-provider.js +112 -0
- package/dist/core/crypto/encryption-engine.d.ts +21 -3
- package/dist/core/crypto/encryption-engine.js +40 -13
- package/dist/core/database/system/identity.d.ts +1 -0
- package/dist/core/types.d.ts +12 -0
- package/dist/majik-key.d.ts +71 -171
- package/dist/majik-key.js +370 -476
- package/package.json +4 -2
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
import { mnemonicToSeedSync } from "@scure/bip39";
|
|
2
2
|
import * as ed25519 from "@stablelib/ed25519";
|
|
3
3
|
import ed2curve from "ed2curve";
|
|
4
|
-
import { fingerprintFromPublicRaw, } from "./crypto-provider";
|
|
4
|
+
import { deriveMlKemKeypairFromSeed, fingerprintFromPublicRaw, } from "./crypto-provider";
|
|
5
5
|
/**
|
|
6
6
|
* EncryptionEngine
|
|
7
7
|
* ----------------
|
|
8
8
|
* Core cryptographic engine.
|
|
9
9
|
*/
|
|
10
10
|
export class EncryptionEngine {
|
|
11
|
+
/* ================================
|
|
12
|
+
* Identity
|
|
13
|
+
* ================================ */
|
|
11
14
|
/* ================================
|
|
12
15
|
* Identity
|
|
13
16
|
* ================================ */
|
|
14
17
|
/**
|
|
15
|
-
* Generates a long-term
|
|
18
|
+
* Generates a random long-term identity keypair (X25519 only).
|
|
19
|
+
* ML-KEM keys are not generated here since random identities
|
|
20
|
+
* cannot be deterministically recovered from a mnemonic.
|
|
16
21
|
*/
|
|
17
22
|
static async generateIdentity() {
|
|
18
23
|
try {
|
|
19
|
-
// Generate an Ed25519 keypair (stablelib) and convert to Curve25519
|
|
20
24
|
const ed = ed25519.generateKeyPair();
|
|
21
25
|
const skCurve = ed2curve.convertSecretKey(ed.secretKey);
|
|
22
26
|
const pkCurve = ed2curve.convertPublicKey(ed.publicKey);
|
|
@@ -25,7 +29,6 @@ export class EncryptionEngine {
|
|
|
25
29
|
}
|
|
26
30
|
const pkBytes = new Uint8Array(pkCurve);
|
|
27
31
|
const skBytes = new Uint8Array(skCurve);
|
|
28
|
-
// Use raw key wrappers (Stablelib-backed) to avoid WebCrypto import variability
|
|
29
32
|
const publicKey = { type: "public", raw: pkBytes };
|
|
30
33
|
const privateKey = { type: "private", raw: skBytes };
|
|
31
34
|
const fingerprint = fingerprintFromPublicRaw(pkBytes);
|
|
@@ -36,32 +39,56 @@ export class EncryptionEngine {
|
|
|
36
39
|
}
|
|
37
40
|
}
|
|
38
41
|
/**
|
|
39
|
-
* Derive
|
|
40
|
-
*
|
|
42
|
+
* Derive a complete identity from a BIP-39 mnemonic.
|
|
43
|
+
*
|
|
44
|
+
* Seed derivation:
|
|
45
|
+
* mnemonicToSeedSync(mnemonic) → 64-byte BIP-39 seed
|
|
46
|
+
*
|
|
47
|
+
* X25519 derivation (unchanged from before):
|
|
48
|
+
* seed[0..32] → Ed25519 keypair via generateKeyPairFromSeed
|
|
49
|
+
* → X25519 via ed2curve conversion
|
|
50
|
+
*
|
|
51
|
+
* ML-KEM-768 derivation (new):
|
|
52
|
+
* seed[0..64] → ml_kem768.keygen(seed)
|
|
53
|
+
* → { publicKey: 1184 bytes, secretKey: 2400 bytes }
|
|
54
|
+
*
|
|
55
|
+
* The noble library accepts the full 64-byte BIP-39 seed directly.
|
|
56
|
+
* Internally it uses seed[0..32] for the lattice key matrix and
|
|
57
|
+
* seed[32..64] for the implicit rejection parameter `z`.
|
|
41
58
|
*/
|
|
42
59
|
static async deriveIdentityFromMnemonic(mnemonic) {
|
|
43
60
|
try {
|
|
44
61
|
if (typeof mnemonic !== "string" || mnemonic.trim().length === 0) {
|
|
45
62
|
throw new CryptoError("Mnemonic must be a non-empty string");
|
|
46
63
|
}
|
|
47
|
-
//
|
|
48
|
-
const seed = mnemonicToSeedSync(mnemonic); // Buffer
|
|
49
|
-
const
|
|
50
|
-
//
|
|
64
|
+
// Step 1: BIP-39 seed → 64 bytes
|
|
65
|
+
const seed = mnemonicToSeedSync(mnemonic); // returns Buffer (Node) or Uint8Array
|
|
66
|
+
const seed64 = new Uint8Array(seed); // normalize to Uint8Array
|
|
67
|
+
// Step 2: X25519 identity from first 32 bytes (existing path)
|
|
68
|
+
const seed32 = seed64.subarray(0, 32);
|
|
51
69
|
const ed = ed25519.generateKeyPairFromSeed(seed32);
|
|
52
|
-
// Convert Ed25519 keys to X25519 (curve25519)
|
|
53
70
|
const skCurve = ed2curve.convertSecretKey(ed.secretKey);
|
|
54
71
|
const pkCurve = ed2curve.convertPublicKey(ed.publicKey);
|
|
55
72
|
if (!skCurve || !pkCurve) {
|
|
56
73
|
throw new CryptoError("Failed to convert derived Ed25519 keys to Curve25519");
|
|
57
74
|
}
|
|
58
|
-
// Ensure plain Uint8Array
|
|
59
75
|
const pkCurveBytes = new Uint8Array(pkCurve);
|
|
60
76
|
const skCurveBytes = new Uint8Array(skCurve);
|
|
61
77
|
const publicKey = { type: "public", raw: pkCurveBytes };
|
|
62
78
|
const privateKey = { type: "private", raw: skCurveBytes };
|
|
63
79
|
const fingerprint = fingerprintFromPublicRaw(pkCurveBytes);
|
|
64
|
-
|
|
80
|
+
// Step 3: ML-KEM-768 keypair from FULL 64-byte seed (new)
|
|
81
|
+
// ml_kem768.keygen() accepts a 64-byte seed directly.
|
|
82
|
+
// seed[0..32] → lattice key matrix expansion (K-PKE keygen)
|
|
83
|
+
// seed[32..64] → implicit rejection parameter z (stored in secretKey)
|
|
84
|
+
const mlKemKeypair = deriveMlKemKeypairFromSeed(seed64);
|
|
85
|
+
return {
|
|
86
|
+
publicKey,
|
|
87
|
+
privateKey,
|
|
88
|
+
fingerprint,
|
|
89
|
+
mlKemPublicKey: mlKemKeypair.publicKey, // 1184 bytes
|
|
90
|
+
mlKemSecretKey: mlKemKeypair.secretKey, // 2400 bytes
|
|
91
|
+
};
|
|
65
92
|
}
|
|
66
93
|
catch (err) {
|
|
67
94
|
throw new CryptoError("Failed to derive identity from mnemonic", err);
|
package/dist/core/types.d.ts
CHANGED
|
@@ -11,6 +11,18 @@ export interface MajikKeyJSON {
|
|
|
11
11
|
salt: string;
|
|
12
12
|
backup: string;
|
|
13
13
|
timestamp: string;
|
|
14
|
+
kdfVersion?: number;
|
|
15
|
+
mlKemPublicKey?: string;
|
|
16
|
+
encryptedMlKemSecretKey?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface MajikKeyMetadata {
|
|
19
|
+
id: string;
|
|
20
|
+
fingerprint: string;
|
|
21
|
+
label: string;
|
|
22
|
+
timestamp: Date;
|
|
23
|
+
isLocked: boolean;
|
|
24
|
+
kdfVersion: number;
|
|
25
|
+
hasMlKem: boolean;
|
|
14
26
|
}
|
|
15
27
|
export interface MnemonicJSON {
|
|
16
28
|
seed: string[];
|
package/dist/majik-key.d.ts
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MajikKey.ts
|
|
3
|
+
*
|
|
4
|
+
* Seed phrase account library for Majik Message.
|
|
5
|
+
*
|
|
6
|
+
* Every account stores TWO keypairs derived deterministically from the mnemonic:
|
|
7
|
+
* 1. X25519 (Curve25519) — fingerprint, contact identity, legacy message compat
|
|
8
|
+
* 2. ML-KEM-768 (FIPS-203) — post-quantum key encapsulation for v3 envelopes
|
|
9
|
+
*
|
|
10
|
+
* Both are derived from the 64-byte BIP-39 seed:
|
|
11
|
+
* seed[0..32] → Ed25519 → X25519 via ed2curve
|
|
12
|
+
* seed[0..64] → ml_kem768.keygen(seed) — full seed, deterministic
|
|
13
|
+
*
|
|
14
|
+
* KDF versioning (passphrase encryption at rest):
|
|
15
|
+
* v1 — PBKDF2-SHA256, 250k iterations (legacy read-only)
|
|
16
|
+
* v2 — Argon2id, 128 MB / 4t / 4p (all new accounts)
|
|
17
|
+
*
|
|
18
|
+
* Migration policy:
|
|
19
|
+
* Old accounts (v1, no ML-KEM keys) are fully upgraded on first import
|
|
20
|
+
* via importFromMnemonicBackup(). The mnemonic is always available at that
|
|
21
|
+
* point, so ML-KEM keys can be deterministically re-derived and stored.
|
|
22
|
+
* No partial migration — either fully upgraded or not upgraded yet.
|
|
23
|
+
*/
|
|
1
24
|
import { MajikContact } from "./core/majik-contact";
|
|
2
|
-
import {
|
|
25
|
+
import { KDF_VERSION } from "./core/crypto/constants";
|
|
26
|
+
import type { MajikKeyJSON, MajikKeyMetadata, MnemonicJSON } from "./core/types";
|
|
3
27
|
import { MajikMessageIdentity } from "./core/database/system/identity";
|
|
4
28
|
import { MajikUser } from "@thezelijah/majik-user";
|
|
5
29
|
export interface MajikKeyIdentity {
|
|
@@ -13,6 +37,9 @@ export interface MajikKeyIdentity {
|
|
|
13
37
|
};
|
|
14
38
|
encryptedPrivateKey: ArrayBuffer;
|
|
15
39
|
salt: string;
|
|
40
|
+
kdfVersion: KDF_VERSION;
|
|
41
|
+
mlKemPublicKey?: Uint8Array;
|
|
42
|
+
mlKemSecretKey?: Uint8Array;
|
|
16
43
|
}
|
|
17
44
|
export interface SerializedIdentity {
|
|
18
45
|
id: string;
|
|
@@ -34,24 +61,16 @@ export interface MajikKeyConstructorOptions {
|
|
|
34
61
|
backup: string;
|
|
35
62
|
label?: string;
|
|
36
63
|
timestamp?: Date;
|
|
64
|
+
kdfVersion?: KDF_VERSION;
|
|
65
|
+
mlKemPublicKey?: Uint8Array;
|
|
66
|
+
mlKemSecretKey?: Uint8Array;
|
|
67
|
+
encryptedMlKemSecretKey?: ArrayBuffer;
|
|
68
|
+
encryptedMlKemSecretKeyBase64?: string;
|
|
37
69
|
privateKey?: CryptoKey | {
|
|
38
70
|
raw: Uint8Array;
|
|
39
71
|
};
|
|
40
72
|
privateKeyBase64?: string;
|
|
41
73
|
}
|
|
42
|
-
export interface MajikKeyMetadata {
|
|
43
|
-
id: string;
|
|
44
|
-
fingerprint: string;
|
|
45
|
-
label: string;
|
|
46
|
-
timestamp: Date;
|
|
47
|
-
isLocked: boolean;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* MajikKey
|
|
51
|
-
* ----------------
|
|
52
|
-
* A seed phrase account library for creating, managing, and parsing mnemonic-based cryptographic accounts (Majik Keys).
|
|
53
|
-
* Generate deterministic key pairs from BIP39 seed phrases with simple, developer-friendly APIs.
|
|
54
|
-
*/
|
|
55
74
|
export declare class MajikKey {
|
|
56
75
|
private readonly _id;
|
|
57
76
|
private readonly _publicKey;
|
|
@@ -63,6 +82,11 @@ export declare class MajikKey {
|
|
|
63
82
|
private _encryptedPrivateKeyBase64;
|
|
64
83
|
private _salt;
|
|
65
84
|
private _label;
|
|
85
|
+
private _kdfVersion;
|
|
86
|
+
private _mlKemPublicKey?;
|
|
87
|
+
private _mlKemSecretKey?;
|
|
88
|
+
private _encryptedMlKemSecretKey?;
|
|
89
|
+
private _encryptedMlKemSecretKeyBase64?;
|
|
66
90
|
private _privateKey?;
|
|
67
91
|
private _privateKeyBase64?;
|
|
68
92
|
private constructor();
|
|
@@ -75,195 +99,71 @@ export declare class MajikKey {
|
|
|
75
99
|
get label(): string;
|
|
76
100
|
get backup(): string;
|
|
77
101
|
get timestamp(): Date;
|
|
102
|
+
get kdfVersion(): KDF_VERSION;
|
|
103
|
+
get isArgon2id(): boolean;
|
|
78
104
|
get isLocked(): boolean;
|
|
79
105
|
get isUnlocked(): boolean;
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
106
|
+
get mlKemPublicKey(): Uint8Array | undefined;
|
|
107
|
+
get mlKemSecretKey(): Uint8Array | undefined;
|
|
108
|
+
get hasMlKem(): boolean;
|
|
109
|
+
get isFullyUpgraded(): boolean;
|
|
83
110
|
get metadata(): MajikKeyMetadata;
|
|
84
|
-
/**
|
|
85
|
-
* CREATE: Generate a new MajikKey from a mnemonic phrase.
|
|
86
|
-
* The key is created in an unlocked state with private keys available.
|
|
87
|
-
*
|
|
88
|
-
* @param mnemonic - BIP39 mnemonic phrase (12-24 words)
|
|
89
|
-
* @param passphrase - Passphrase to encrypt the private key at rest
|
|
90
|
-
* @param label - Optional label for the key
|
|
91
|
-
* @returns A new unlocked MajikKey instance
|
|
92
|
-
*/
|
|
93
111
|
static create(mnemonic: string, passphrase: string, label?: string): Promise<MajikKey>;
|
|
94
|
-
|
|
95
|
-
* Export this MajikKey to MnemonicJSON format.
|
|
96
|
-
* This format is useful for storing mnemonic data with an optional passphrase.
|
|
97
|
-
*
|
|
98
|
-
* @param mnemonic - The BIP39 mnemonic phrase
|
|
99
|
-
* @param passphrase - Optional passphrase (encryption password, not BIP39 passphrase)
|
|
100
|
-
* @returns MnemonicJSON object
|
|
101
|
-
*/
|
|
112
|
+
static fromJSON(json: MajikKeyJSON | string): MajikKey;
|
|
102
113
|
toMnemonicJSON(mnemonic: string, passphrase?: string): MnemonicJSON;
|
|
103
|
-
/**
|
|
104
|
-
* Create a MajikKey from MnemonicJSON format.
|
|
105
|
-
*
|
|
106
|
-
* @param mnemonicJson - MnemonicJSON object or string
|
|
107
|
-
* @param passphrase - Passphrase to encrypt the key at rest
|
|
108
|
-
* @param label - Optional label for the key
|
|
109
|
-
* @returns A new unlocked MajikKey instance
|
|
110
|
-
*/
|
|
111
114
|
static fromMnemonicJSON(mnemonicJson: MnemonicJSON | string, passphrase: string, label?: string): Promise<MajikKey>;
|
|
112
|
-
/**
|
|
113
|
-
* READ: Load a MajikKey from JSON (locked state).
|
|
114
|
-
* The key must be unlocked with the unlock() method before accessing private keys.
|
|
115
|
-
*
|
|
116
|
-
* @param json - JSON string or object
|
|
117
|
-
* @returns A locked MajikKey instance
|
|
118
|
-
*/
|
|
119
|
-
static fromJSON(json: MajikKeyJSON | string): MajikKey;
|
|
120
|
-
/**
|
|
121
|
-
* UPDATE: Change the label of this MajikKey.
|
|
122
|
-
*
|
|
123
|
-
* @param newLabel - New label value
|
|
124
|
-
* @returns This instance for chaining
|
|
125
|
-
*/
|
|
126
115
|
updateLabel(newLabel: string): this;
|
|
127
|
-
/**
|
|
128
|
-
* UPDATE: Change the passphrase used to encrypt the private key.
|
|
129
|
-
* Requires the current passphrase for verification.
|
|
130
|
-
*
|
|
131
|
-
* @param currentPassphrase - Current passphrase
|
|
132
|
-
* @param newPassphrase - New passphrase
|
|
133
|
-
* @returns This instance for chaining
|
|
134
|
-
*/
|
|
135
116
|
updatePassphrase(currentPassphrase: string, newPassphrase: string): Promise<this>;
|
|
136
117
|
/**
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
* @returns This instance for chaining
|
|
118
|
+
* Migrate KDF from PBKDF2 to Argon2id without changing passphrase.
|
|
119
|
+
* NOTE: Does not add ML-KEM keys — use importFromMnemonicBackup() for full upgrade.
|
|
141
120
|
*/
|
|
121
|
+
migrate(passphrase: string): Promise<this>;
|
|
142
122
|
lock(): this;
|
|
143
|
-
/**
|
|
144
|
-
* Unlock this MajikKey by decrypting the private key with the passphrase.
|
|
145
|
-
* Sets the private key in memory for cryptographic operations.
|
|
146
|
-
*
|
|
147
|
-
* @param passphrase - Passphrase to decrypt the private key
|
|
148
|
-
* @returns This instance for chaining
|
|
149
|
-
* @throws MajikKeyError if passphrase is incorrect or key is already unlocked
|
|
150
|
-
*/
|
|
151
123
|
unlock(passphrase: string): Promise<this>;
|
|
152
|
-
/**
|
|
153
|
-
* Verify that the encrypted private key can be decrypted with passphrase
|
|
154
|
-
*/
|
|
155
124
|
verify(passphrase: string): Promise<boolean>;
|
|
156
|
-
/**
|
|
157
|
-
* Get the private key (only available when unlocked).
|
|
158
|
-
*
|
|
159
|
-
* @returns The private key
|
|
160
|
-
* @throws MajikKeyError if the key is locked
|
|
161
|
-
*/
|
|
162
125
|
getPrivateKey(): CryptoKey | {
|
|
163
126
|
raw: Uint8Array;
|
|
164
127
|
};
|
|
165
|
-
/**
|
|
166
|
-
* Get the private key as base64 (only available when unlocked).
|
|
167
|
-
*
|
|
168
|
-
* @returns The private key in base64 format
|
|
169
|
-
* @throws MajikKeyError if the key is locked
|
|
170
|
-
*/
|
|
171
128
|
getPrivateKeyBase64(): string;
|
|
172
|
-
|
|
173
|
-
* Export this MajikKey to JSON format (safe for storage).
|
|
174
|
-
* Private keys are never included in the JSON output.
|
|
175
|
-
*
|
|
176
|
-
* @returns JSON representation of this MajikKey
|
|
177
|
-
*/
|
|
129
|
+
getMlKemSecretKey(): Uint8Array;
|
|
178
130
|
toJSON(): MajikKeyJSON;
|
|
179
|
-
/**
|
|
180
|
-
* Export this MajikKey to a JSON string.
|
|
181
|
-
*
|
|
182
|
-
* @param pretty - Whether to pretty-print the JSON
|
|
183
|
-
* @returns JSON string representation
|
|
184
|
-
*/
|
|
185
131
|
toString(pretty?: boolean): string;
|
|
186
|
-
/**
|
|
187
|
-
* Generate a new BIP39 mnemonic phrase.
|
|
188
|
-
*
|
|
189
|
-
* @param strength - Entropy strength in bits (128 = 12 words, 256 = 24 words)
|
|
190
|
-
* @returns A new mnemonic phrase
|
|
191
|
-
*/
|
|
192
132
|
static generateMnemonic(strength?: 128 | 256): string;
|
|
193
|
-
/**
|
|
194
|
-
* Validate a BIP39 mnemonic phrase.
|
|
195
|
-
*
|
|
196
|
-
* @param mnemonic - Mnemonic phrase to validate
|
|
197
|
-
* @returns true if valid, false otherwise
|
|
198
|
-
*/
|
|
199
133
|
static validateMnemonic(mnemonic: string): boolean;
|
|
200
|
-
/**
|
|
201
|
-
* Create a MajikContact from this MajikKey.
|
|
202
|
-
*
|
|
203
|
-
* @returns A MajikContact instance
|
|
204
|
-
*/
|
|
205
134
|
toContact(): MajikContact;
|
|
206
|
-
/**
|
|
207
|
-
* Convert to internal MajikKeyIdentity format (for backward compatibility).
|
|
208
|
-
* Note: Only includes privateKey if unlocked.
|
|
209
|
-
*
|
|
210
|
-
* @returns MajikKeyIdentity object
|
|
211
|
-
*/
|
|
212
135
|
toKeyIdentity(): MajikKeyIdentity;
|
|
213
|
-
/**
|
|
214
|
-
* Convert to internal SerializedIdentity format (for Majik Message).
|
|
215
|
-
*
|
|
216
|
-
* @returns SerializedIdentity object
|
|
217
|
-
*/
|
|
218
136
|
toSerializedIdentity(): SerializedIdentity;
|
|
219
137
|
toMajikMessageIdentity(user: MajikUser, options?: {
|
|
220
138
|
label?: string;
|
|
221
139
|
restricted?: boolean;
|
|
222
140
|
}): Promise<MajikMessageIdentity>;
|
|
223
|
-
/**
|
|
224
|
-
* Export a mnemonic-encrypted backup for this MajikKey.
|
|
225
|
-
* Requires the key to be unlocked.
|
|
226
|
-
*
|
|
227
|
-
* @param mnemonic - The original mnemonic phrase
|
|
228
|
-
* @returns Base64-encoded backup string
|
|
229
|
-
*/
|
|
230
141
|
exportMnemonicBackup(mnemonic: string): Promise<string>;
|
|
231
142
|
/**
|
|
232
143
|
* Import a MajikKey from a mnemonic-encrypted backup.
|
|
233
144
|
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
*
|
|
145
|
+
* This is the FULL MIGRATION PATH for old accounts — Argon2id + ML-KEM in one step:
|
|
146
|
+
* 1. Verify the backup decrypts correctly (proves mnemonic is correct)
|
|
147
|
+
* 2. Re-derive the complete identity from the mnemonic (X25519 + ML-KEM-768)
|
|
148
|
+
* 3. Encrypt both private keys with Argon2id (v2) + fresh 32-byte salt
|
|
149
|
+
* 4. Return a fully-upgraded MajikKey with hasMlKem: true, isArgon2id: true
|
|
150
|
+
*
|
|
151
|
+
* Old accounts without ML-KEM keys become fully post-quantum capable
|
|
152
|
+
* automatically — no extra user steps. The mnemonic is the source of truth.
|
|
239
153
|
*/
|
|
240
154
|
static importFromMnemonicBackup(backup: string, mnemonic: string, passphrase: string, label?: string): Promise<MajikKey>;
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
private static
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
private static
|
|
255
|
-
/**
|
|
256
|
-
* Decrypt a private key with a passphrase.
|
|
257
|
-
*/
|
|
258
|
-
private static decryptPrivateKey;
|
|
259
|
-
private static deriveKeyFromMnemonic;
|
|
260
|
-
/**
|
|
261
|
-
* Validate whether a passphrase can decrypt the stored private key.
|
|
262
|
-
* Does NOT unlock or mutate any in-memory state.
|
|
263
|
-
*/
|
|
264
|
-
private static isPassphraseValid;
|
|
265
|
-
/**
|
|
266
|
-
* Export a CryptoKey to base64 string.
|
|
267
|
-
*/
|
|
268
|
-
private static exportKeyToBase64;
|
|
155
|
+
private static _deriveAndEncryptFromMnemonic;
|
|
156
|
+
private static _encryptPrivateKey;
|
|
157
|
+
/**
|
|
158
|
+
* Encrypt the ML-KEM secret key using the same Argon2id-derived key as X25519
|
|
159
|
+
* (same passphrase + same salt) but a DIFFERENT random IV. One Argon2id
|
|
160
|
+
* computation → two independently encrypted blobs.
|
|
161
|
+
*/
|
|
162
|
+
private static _encryptMlKemSecretKey;
|
|
163
|
+
private static _decryptPrivateKey;
|
|
164
|
+
private static _decryptMlKemSecretKey;
|
|
165
|
+
private static _verifyBackupDecryption;
|
|
166
|
+
private static _exportMnemonicBackup;
|
|
167
|
+
private static _deriveLegacyMnemonicKey;
|
|
168
|
+
private static _exportKeyToBase64;
|
|
269
169
|
}
|