@bitgo/sdk-api 1.78.0 → 1.79.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +3 -3
- package/dist/src/encrypt.d.ts +5 -35
- package/dist/src/encrypt.d.ts.map +1 -1
- package/dist/src/encrypt.js +15 -126
- package/dist/src/encryptV2.d.ts +65 -0
- package/dist/src/encryptV2.d.ts.map +1 -0
- package/dist/src/encryptV2.js +187 -0
- package/dist/src/encryptionSession.d.ts +34 -0
- package/dist/src/encryptionSession.d.ts.map +1 -0
- package/dist/src/encryptionSession.js +90 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -1
- package/dist/test/unit/encrypt.js +99 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bitgo/sdk-api",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.79.0",
|
|
4
4
|
"description": "REST wrapper for BitGoJS",
|
|
5
5
|
"main": "./dist/src/index.js",
|
|
6
6
|
"types": "./dist/src/index.d.ts",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@bitgo/argon2": "^1.1.0",
|
|
44
|
-
"@bitgo/sdk-core": "^36.
|
|
44
|
+
"@bitgo/sdk-core": "^36.42.0",
|
|
45
45
|
"@bitgo/sdk-hmac": "^1.9.0",
|
|
46
46
|
"@bitgo/sjcl": "^1.1.0",
|
|
47
47
|
"@bitgo/unspents": "^0.51.3",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"resolutions": {
|
|
65
65
|
"degenerator": "5.0.0"
|
|
66
66
|
},
|
|
67
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "36fbed6cae5b00e695b22164d66f5be6e242343f",
|
|
68
68
|
"files": [
|
|
69
69
|
"dist"
|
|
70
70
|
]
|
package/dist/src/encrypt.d.ts
CHANGED
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
import * as t from 'io-ts';
|
|
2
|
-
declare const V2EnvelopeCodec: t.TypeC<{
|
|
3
|
-
v: t.LiteralC<2>;
|
|
4
|
-
m: t.Type<number, number, unknown>;
|
|
5
|
-
t: t.Type<number, number, unknown>;
|
|
6
|
-
p: t.Type<number, number, unknown>;
|
|
7
|
-
salt: t.Type<string, string, unknown>;
|
|
8
|
-
iv: t.Type<string, string, unknown>;
|
|
9
|
-
ct: t.Type<string, string, unknown>;
|
|
10
|
-
}>;
|
|
11
|
-
export type V2Envelope = t.TypeOf<typeof V2EnvelopeCodec>;
|
|
12
1
|
/**
|
|
13
2
|
* convert a 4 element Uint8Array to a 4 byte Number
|
|
14
3
|
*
|
|
@@ -16,38 +5,19 @@ export type V2Envelope = t.TypeOf<typeof V2EnvelopeCodec>;
|
|
|
16
5
|
* @return 4 byte number
|
|
17
6
|
*/
|
|
18
7
|
export declare function bytesToWord(bytes?: Uint8Array | number[]): number;
|
|
8
|
+
/** Encrypt using legacy v1 SJCL (PBKDF2-SHA256 + AES-256-CCM). */
|
|
19
9
|
export declare function encrypt(password: string, plaintext: string, options?: {
|
|
20
10
|
salt?: Buffer;
|
|
21
11
|
iv?: Buffer;
|
|
22
12
|
adata?: string;
|
|
23
13
|
}): string;
|
|
14
|
+
/** Decrypt a v1 SJCL envelope. */
|
|
24
15
|
export declare function decrypt(password: string, ciphertext: string): string;
|
|
25
16
|
/**
|
|
26
|
-
*
|
|
27
|
-
* from the JSON envelope's `v` field.
|
|
17
|
+
* Auto-detect v1 (SJCL) or v2 (Argon2id + AES-256-GCM) from the envelope `v` field and decrypt.
|
|
28
18
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
19
|
+
* Migration path from sync `decrypt()`. Move call sites to `decryptAsync()` before
|
|
20
|
+
* the breaking release that flips the default to v2.
|
|
31
21
|
*/
|
|
32
22
|
export declare function decryptAsync(password: string, ciphertext: string): Promise<string>;
|
|
33
|
-
/**
|
|
34
|
-
* Encrypt plaintext using Argon2id KDF + AES-256-GCM.
|
|
35
|
-
*
|
|
36
|
-
* Returns a JSON string containing a self-describing v2 envelope
|
|
37
|
-
* with Argon2id parameters, salt, IV, and ciphertext.
|
|
38
|
-
*/
|
|
39
|
-
export declare function encryptV2(password: string, plaintext: string, options?: {
|
|
40
|
-
salt?: Uint8Array;
|
|
41
|
-
iv?: Uint8Array;
|
|
42
|
-
memorySize?: number;
|
|
43
|
-
iterations?: number;
|
|
44
|
-
parallelism?: number;
|
|
45
|
-
}): Promise<string>;
|
|
46
|
-
/**
|
|
47
|
-
* Decrypt a v2 envelope (Argon2id KDF + AES-256-GCM).
|
|
48
|
-
*
|
|
49
|
-
* The envelope must contain: v, m, t, p, salt, iv, ct.
|
|
50
|
-
*/
|
|
51
|
-
export declare function decryptV2(password: string, ciphertext: string): Promise<string>;
|
|
52
|
-
export {};
|
|
53
23
|
//# sourceMappingURL=encrypt.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encrypt.d.ts","sourceRoot":"","sources":["../../src/encrypt.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"encrypt.d.ts","sourceRoot":"","sources":["../../src/encrypt.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,EAAE,GAAG,MAAM,CAKjE;AAED,kEAAkE;AAClE,wBAAgB,OAAO,CACrB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACvD,MAAM,CAmBR;AAED,kCAAkC;AAClC,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAaxF"}
|
package/dist/src/encrypt.js
CHANGED
|
@@ -37,43 +37,9 @@ exports.bytesToWord = bytesToWord;
|
|
|
37
37
|
exports.encrypt = encrypt;
|
|
38
38
|
exports.decrypt = decrypt;
|
|
39
39
|
exports.decryptAsync = decryptAsync;
|
|
40
|
-
exports.encryptV2 = encryptV2;
|
|
41
|
-
exports.decryptV2 = decryptV2;
|
|
42
|
-
const sdk_core_1 = require("@bitgo/sdk-core");
|
|
43
40
|
const sjcl = __importStar(require("@bitgo/sjcl"));
|
|
44
41
|
const crypto_1 = require("crypto");
|
|
45
|
-
const
|
|
46
|
-
/** Default Argon2id parameters per RFC 9106 second recommendation
|
|
47
|
-
* @see https://www.rfc-editor.org/rfc/rfc9106#section-4
|
|
48
|
-
*/
|
|
49
|
-
const ARGON2_DEFAULTS = {
|
|
50
|
-
memorySize: 65536, // 64 MiB in KiB
|
|
51
|
-
iterations: 3,
|
|
52
|
-
parallelism: 4,
|
|
53
|
-
hashLength: 32, // 256-bit key
|
|
54
|
-
saltLength: 16, // 128-bit salt
|
|
55
|
-
};
|
|
56
|
-
/** Maximum allowed Argon2id parameters to prevent DoS via crafted envelopes.
|
|
57
|
-
* memorySize: 256 MiB (4x default) -- caps memory allocation on untrusted input.
|
|
58
|
-
* iterations: 16 -- caps CPU time.
|
|
59
|
-
* parallelism: 16 -- caps thread count.
|
|
60
|
-
*/
|
|
61
|
-
const ARGON2_MAX = {
|
|
62
|
-
memorySize: 262144,
|
|
63
|
-
iterations: 16,
|
|
64
|
-
parallelism: 16,
|
|
65
|
-
};
|
|
66
|
-
/** AES-256-GCM IV length in bytes */
|
|
67
|
-
const GCM_IV_LENGTH = 12;
|
|
68
|
-
const V2EnvelopeCodec = t.type({
|
|
69
|
-
v: t.literal(2),
|
|
70
|
-
m: (0, sdk_core_1.boundedInt)(1, ARGON2_MAX.memorySize, 'memorySize'),
|
|
71
|
-
t: (0, sdk_core_1.boundedInt)(1, ARGON2_MAX.iterations, 'iterations'),
|
|
72
|
-
p: (0, sdk_core_1.boundedInt)(1, ARGON2_MAX.parallelism, 'parallelism'),
|
|
73
|
-
salt: sdk_core_1.base64String,
|
|
74
|
-
iv: sdk_core_1.base64String,
|
|
75
|
-
ct: sdk_core_1.base64String,
|
|
76
|
-
});
|
|
42
|
+
const encryptV2_1 = require("./encryptV2");
|
|
77
43
|
/**
|
|
78
44
|
* convert a 4 element Uint8Array to a 4 byte Number
|
|
79
45
|
*
|
|
@@ -86,15 +52,14 @@ function bytesToWord(bytes) {
|
|
|
86
52
|
}
|
|
87
53
|
return bytes.reduce((num, byte) => num * 0x100 + byte, 0);
|
|
88
54
|
}
|
|
55
|
+
/** Encrypt using legacy v1 SJCL (PBKDF2-SHA256 + AES-256-CCM). */
|
|
89
56
|
function encrypt(password, plaintext, options) {
|
|
90
57
|
const salt = options?.salt || (0, crypto_1.randomBytes)(8);
|
|
91
|
-
if (salt.length !== 8)
|
|
92
|
-
throw new Error(
|
|
93
|
-
}
|
|
58
|
+
if (salt.length !== 8)
|
|
59
|
+
throw new Error('salt must be 8 bytes');
|
|
94
60
|
const iv = options?.iv || (0, crypto_1.randomBytes)(16);
|
|
95
|
-
if (iv.length !== 16)
|
|
96
|
-
throw new Error(
|
|
97
|
-
}
|
|
61
|
+
if (iv.length !== 16)
|
|
62
|
+
throw new Error('iv must be 16 bytes');
|
|
98
63
|
const encryptOptions = {
|
|
99
64
|
iter: 10000,
|
|
100
65
|
ks: 256,
|
|
@@ -106,109 +71,33 @@ function encrypt(password, plaintext, options) {
|
|
|
106
71
|
bytesToWord(iv.slice(12, 16)),
|
|
107
72
|
],
|
|
108
73
|
};
|
|
109
|
-
if (options?.adata)
|
|
74
|
+
if (options?.adata)
|
|
110
75
|
encryptOptions.adata = options.adata;
|
|
111
|
-
}
|
|
112
76
|
return sjcl.encrypt(password, plaintext, encryptOptions);
|
|
113
77
|
}
|
|
78
|
+
/** Decrypt a v1 SJCL envelope. */
|
|
114
79
|
function decrypt(password, ciphertext) {
|
|
115
80
|
return sjcl.decrypt(password, ciphertext);
|
|
116
81
|
}
|
|
117
82
|
/**
|
|
118
|
-
*
|
|
119
|
-
* from the JSON envelope's `v` field.
|
|
83
|
+
* Auto-detect v1 (SJCL) or v2 (Argon2id + AES-256-GCM) from the envelope `v` field and decrypt.
|
|
120
84
|
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
85
|
+
* Migration path from sync `decrypt()`. Move call sites to `decryptAsync()` before
|
|
86
|
+
* the breaking release that flips the default to v2.
|
|
123
87
|
*/
|
|
124
88
|
async function decryptAsync(password, ciphertext) {
|
|
125
89
|
let isV2 = false;
|
|
126
90
|
try {
|
|
127
|
-
// Only peeking at the v field to route; this is an internal format we produce, not external input.
|
|
128
91
|
const envelope = JSON.parse(ciphertext);
|
|
129
92
|
isV2 = envelope.v === 2;
|
|
130
93
|
}
|
|
131
94
|
catch {
|
|
132
|
-
|
|
95
|
+
throw new Error('decrypt: ciphertext is not valid JSON');
|
|
133
96
|
}
|
|
134
97
|
if (isV2) {
|
|
135
|
-
// Do not catch
|
|
136
|
-
|
|
137
|
-
return decryptV2(password, ciphertext);
|
|
98
|
+
// Do not catch: wrong password on v2 must not silently fall through to v1.
|
|
99
|
+
return (0, encryptV2_1.decryptV2)(password, ciphertext);
|
|
138
100
|
}
|
|
139
101
|
return sjcl.decrypt(password, ciphertext);
|
|
140
102
|
}
|
|
141
|
-
|
|
142
|
-
* Derive a 256-bit key from a password using Argon2id.
|
|
143
|
-
*/
|
|
144
|
-
async function deriveKeyV2(password, salt, params) {
|
|
145
|
-
const { argon2id } = await Promise.resolve().then(() => __importStar(require('@bitgo/argon2')));
|
|
146
|
-
const keyBytes = await argon2id({
|
|
147
|
-
password,
|
|
148
|
-
salt,
|
|
149
|
-
memorySize: params.memorySize,
|
|
150
|
-
iterations: params.iterations,
|
|
151
|
-
parallelism: params.parallelism,
|
|
152
|
-
hashLength: ARGON2_DEFAULTS.hashLength,
|
|
153
|
-
outputType: 'binary',
|
|
154
|
-
});
|
|
155
|
-
return crypto.subtle.importKey('raw', keyBytes, { name: 'AES-GCM' }, false, ['encrypt', 'decrypt']);
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Encrypt plaintext using Argon2id KDF + AES-256-GCM.
|
|
159
|
-
*
|
|
160
|
-
* Returns a JSON string containing a self-describing v2 envelope
|
|
161
|
-
* with Argon2id parameters, salt, IV, and ciphertext.
|
|
162
|
-
*/
|
|
163
|
-
async function encryptV2(password, plaintext, options) {
|
|
164
|
-
const memorySize = options?.memorySize ?? ARGON2_DEFAULTS.memorySize;
|
|
165
|
-
const iterations = options?.iterations ?? ARGON2_DEFAULTS.iterations;
|
|
166
|
-
const parallelism = options?.parallelism ?? ARGON2_DEFAULTS.parallelism;
|
|
167
|
-
const salt = options?.salt ?? new Uint8Array((0, crypto_1.randomBytes)(ARGON2_DEFAULTS.saltLength));
|
|
168
|
-
if (salt.length !== ARGON2_DEFAULTS.saltLength) {
|
|
169
|
-
throw new Error(`salt must be ${ARGON2_DEFAULTS.saltLength} bytes`);
|
|
170
|
-
}
|
|
171
|
-
const iv = options?.iv ?? new Uint8Array((0, crypto_1.randomBytes)(GCM_IV_LENGTH));
|
|
172
|
-
if (iv.length !== GCM_IV_LENGTH) {
|
|
173
|
-
throw new Error(`iv must be ${GCM_IV_LENGTH} bytes`);
|
|
174
|
-
}
|
|
175
|
-
const key = await deriveKeyV2(password, salt, { memorySize, iterations, parallelism });
|
|
176
|
-
const plaintextBytes = new TextEncoder().encode(plaintext);
|
|
177
|
-
const ctBuffer = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, plaintextBytes);
|
|
178
|
-
const envelope = {
|
|
179
|
-
v: 2,
|
|
180
|
-
m: memorySize,
|
|
181
|
-
t: iterations,
|
|
182
|
-
p: parallelism,
|
|
183
|
-
salt: Buffer.from(salt).toString('base64'),
|
|
184
|
-
iv: Buffer.from(iv).toString('base64'),
|
|
185
|
-
ct: Buffer.from(ctBuffer).toString('base64'),
|
|
186
|
-
};
|
|
187
|
-
return JSON.stringify(envelope);
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Decrypt a v2 envelope (Argon2id KDF + AES-256-GCM).
|
|
191
|
-
*
|
|
192
|
-
* The envelope must contain: v, m, t, p, salt, iv, ct.
|
|
193
|
-
*/
|
|
194
|
-
async function decryptV2(password, ciphertext) {
|
|
195
|
-
let parsed;
|
|
196
|
-
try {
|
|
197
|
-
parsed = JSON.parse(ciphertext);
|
|
198
|
-
}
|
|
199
|
-
catch {
|
|
200
|
-
throw new Error('v2 decrypt: invalid JSON envelope');
|
|
201
|
-
}
|
|
202
|
-
const envelope = (0, sdk_core_1.decodeWithCodec)(V2EnvelopeCodec, parsed, 'v2 decrypt: invalid envelope');
|
|
203
|
-
const salt = new Uint8Array(Buffer.from(envelope.salt, 'base64'));
|
|
204
|
-
const iv = new Uint8Array(Buffer.from(envelope.iv, 'base64'));
|
|
205
|
-
const ct = new Uint8Array(Buffer.from(envelope.ct, 'base64'));
|
|
206
|
-
const key = await deriveKeyV2(password, salt, {
|
|
207
|
-
memorySize: envelope.m,
|
|
208
|
-
iterations: envelope.t,
|
|
209
|
-
parallelism: envelope.p,
|
|
210
|
-
});
|
|
211
|
-
const plaintextBuffer = await crypto.subtle.decrypt({ name: 'AES-GCM', iv }, key, ct);
|
|
212
|
-
return new TextDecoder().decode(plaintextBuffer);
|
|
213
|
-
}
|
|
214
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jcnlwdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9lbmNyeXB0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBZ0RBLGtDQU1DO0FBRUQsMEJBd0NDO0FBRUQsMEJBRUM7QUFTRCxvQ0FlQztBQThCRCw4QkF5Q0M7QUFPRCw4QkF1QkM7QUFqT0QsOENBQTRFO0FBQzVFLGtEQUFvQztBQUNwQyxtQ0FBcUM7QUFDckMseUNBQTJCO0FBRTNCOztHQUVHO0FBQ0gsTUFBTSxlQUFlLEdBQUc7SUFDdEIsVUFBVSxFQUFFLEtBQUssRUFBRSxnQkFBZ0I7SUFDbkMsVUFBVSxFQUFFLENBQUM7SUFDYixXQUFXLEVBQUUsQ0FBQztJQUNkLFVBQVUsRUFBRSxFQUFFLEVBQUUsY0FBYztJQUM5QixVQUFVLEVBQUUsRUFBRSxFQUFFLGVBQWU7Q0FDdkIsQ0FBQztBQUVYOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsR0FBRztJQUNqQixVQUFVLEVBQUUsTUFBTTtJQUNsQixVQUFVLEVBQUUsRUFBRTtJQUNkLFdBQVcsRUFBRSxFQUFFO0NBQ1AsQ0FBQztBQUVYLHFDQUFxQztBQUNyQyxNQUFNLGFBQWEsR0FBRyxFQUFFLENBQUM7QUFFekIsTUFBTSxlQUFlLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUM3QixDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDZixDQUFDLEVBQUUsSUFBQSxxQkFBVSxFQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsVUFBVSxFQUFFLFlBQVksQ0FBQztJQUNyRCxDQUFDLEVBQUUsSUFBQSxxQkFBVSxFQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsVUFBVSxFQUFFLFlBQVksQ0FBQztJQUNyRCxDQUFDLEVBQUUsSUFBQSxxQkFBVSxFQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsV0FBVyxFQUFFLGFBQWEsQ0FBQztJQUN2RCxJ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QyxDQUFDO0tBQ3hCLENBQUMsQ0FBQztJQUVILE1BQU0sZUFBZSxHQUFHLE1BQU0sTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUV0RixPQUFPLElBQUksV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0FBQ25ELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBiYXNlNjRTdHJpbmcsIGJvdW5kZWRJbnQsIGRlY29kZVdpdGhDb2RlYyB9IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgKiBhcyBzamNsIGZyb20gJ0BiaXRnby9zamNsJztcbmltcG9ydCB7IHJhbmRvbUJ5dGVzIH0gZnJvbSAnY3J5cHRvJztcbmltcG9ydCAqIGFzIHQgZnJvbSAnaW8tdHMnO1xuXG4vKiogRGVmYXVsdCBBcmdvbjJpZCBwYXJhbWV0ZXJzIHBlciBSRkMgOTEwNiBzZWNvbmQgcmVjb21tZW5kYXRpb25cbiAqIEBzZWUgaHR0cHM6Ly93d3cucmZjLWVkaXRvci5vcmcvcmZjL3JmYzkxMDYjc2VjdGlvbi00XG4gKi9cbmNvbnN0IEFSR09OMl9ERUZBVUxUUyA9IHtcbiAgbWVtb3J5U2l6ZTogNjU1MzYsIC8vIDY0IE1pQiBpbiBLaUJcbiAgaXRlcmF0aW9uczogMyxcbiAgcGFyYWxsZWxpc206IDQsXG4gIGhhc2hMZW5ndGg6IDMyLCAvLyAyNTYtYml0IGtleVxuICBzYWx0TGVuZ3RoOiAxNiwgLy8gMTI4LWJpdCBzYWx0XG59IGFzIGNvbnN0O1xuXG4vKiogTWF4aW11bSBhbGxvd2VkIEFyZ29uMmlkIHBhcmFtZXRlcnMgdG8gcHJldmVudCBEb1MgdmlhIGNyYWZ0ZWQgZW52ZWxvcGVzLlxuICogbWVtb3J5U2l6ZTogMjU2IE1pQiAoNHggZGVmYXVsdCkgLS0gY2FwcyBtZW1vcnkgYWxsb2NhdGlvbiBvbiB1bnRydXN0ZWQgaW5wdXQuXG4gKiBpdGVyYXRpb25zOiAxNiAtLSBjYXBzIENQVSB0aW1lLlxuICogcGFyYWxsZWxpc206IDE2IC0tIGNhcHMgdGhyZWFkIGNvdW50LlxuICovXG5jb25zdCBBUkdPTjJfTUFYID0ge1xuICBtZW1vcnlTaXplOiAyNjIxNDQsXG4gIGl0ZXJhdGlvbnM6IDE2LFxuICBwYXJhbGxlbGlzbTogMTYsXG59IGFzIGNvbnN0O1xuXG4vKiogQUVTLTI1Ni1HQ00gSVYgbGVuZ3RoIGluIGJ5dGVzICovXG5jb25zdCBHQ01fSVZfTEVOR1RIID0gMTI7XG5cbmNvbnN0IFYyRW52ZWxvcGVDb2RlYyA9IHQudHlwZSh7XG4gIHY6IHQubGl0ZXJhbCgyKSxcbiAgbTogYm91bmRlZEludCgxLCBBUkdPTjJfTUFYLm1lbW9yeVNpemUsICdtZW1vcnlTaXplJyksXG4gIHQ6IGJvdW5kZWRJbnQoMSwgQVJHT04yX01BWC5pdGVyYXRpb25zLCAnaXRlcmF0aW9ucycpLFxuICBwOiBib3VuZGVkSW50KDEsIEFSR09OMl9NQVgucGFyYWxsZWxpc20sICdwYXJhbGxlbGlzbScpLFxuICBzYWx0OiBiYXNlNjRTdHJpbmcsXG4gIGl2OiBiYXNlNjRTdHJpbmcsXG4gIGN0OiBiYXNlNjRTdHJpbmcsXG59KTtcblxuZXhwb3J0IHR5cGUgVjJFbnZlbG9wZSA9IHQuVHlwZU9mPHR5cGVvZiBWMkVudmVsb3BlQ29kZWM+O1xuXG4vKipcbiAqIGNvbnZlcnQgYSA0IGVsZW1lbnQgVWludDhBcnJheSB0byBhIDQgYnl0ZSBOdW1iZXJcbiAqXG4gKiBAcGFyYW0gYnl0ZXNcbiAqIEByZXR1cm4gNCBieXRlIG51bWJlclxuICovXG5leHBvcnQgZnVuY3Rpb24gYnl0ZXNUb1dvcmQoYnl0ZXM/OiBVaW50OEFycmF5IHwgbnVtYmVyW10pOiBudW1iZXIge1xuICBpZiAoIShieXRlcyBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHx8IGJ5dGVzLmxlbmd0aCAhPT0gNCkge1xuICAgIHRocm93IG5ldyBFcnJvcignYnl0ZXMgbXVzdCBiZSBhIFVpbnQ4QXJyYXkgd2l0aCBsZW5ndGggNCcpO1xuICB9XG5cbiAgcmV0dXJuIGJ5dGVzLnJlZHVjZSgobnVtLCBieXRlKSA9PiBudW0gKiAweDEwMCArIGJ5dGUsIDApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZW5jcnlwdChcbiAgcGFzc3dvcmQ6IHN0cmluZyxcbiAgcGxhaW50ZXh0OiBzdHJpbmcsXG4gIG9wdGlvbnM/OiB7XG4gICAgc2FsdD86IEJ1ZmZlcjtcbiAgICBpdj86IEJ1ZmZlcjtcbiAgICBhZGF0YT86IHN0cmluZztcbiAgfVxuKTogc3RyaW5nIHtcbiAgY29uc3Qgc2FsdCA9IG9wdGlvbnM/LnNhbHQgfHwgcmFuZG9tQnl0ZXMoOCk7XG4gIGlmIChzYWx0Lmxlbmd0aCAhPT0gOCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgc2FsdCBtdXN0IGJlIDggYnl0ZXNgKTtcbiAgfVxuICBjb25zdCBpdiA9IG9wdGlvbnM/Lml2IHx8IHJhbmRvbUJ5dGVzKDE2KTtcbiAgaWYgKGl2Lmxlbmd0aCAhPT0gMTYpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGl2IG11c3QgYmUgMTYgYnl0ZXNgKTtcbiAgfVxuICBjb25zdCBlbmNyeXB0T3B0aW9uczoge1xuICAgIGl0ZXI6IG51bWJlcjtcbiAgICBrczogbnVtYmVyO1xuICAgIHNhbHQ6IG51bWJlcltdO1xuICAgIGl2OiBudW1iZXJbXTtcbiAgICBhZGF0YT86IHN0cmluZztcbiAgfSA9IHtcbiAgICBpdGVyOiAxMDAwMCxcbiAgICBrczogMjU2LFxuICAgIHNhbHQ6IFtieXRlc1RvV29yZChzYWx0LnNsaWNlKDAsIDQpKSwgYnl0ZXNUb1dvcmQoc2FsdC5zbGljZSg0KSldLFxuICAgIGl2OiBbXG4gICAgICBieXRlc1RvV29yZChpdi5zbGljZSgwLCA0KSksXG4gICAgICBieXRlc1RvV29yZChpdi5zbGljZSg0LCA4KSksXG4gICAgICBieXRlc1RvV29yZChpdi5zbGljZSg4LCAxMikpLFxuICAgICAgYnl0ZXNUb1dvcmQoaXYuc2xpY2UoMTIsIDE2KSksXG4gICAgXSxcbiAgfTtcblxuICBpZiAob3B0aW9ucz8uYWRhdGEpIHtcbiAgICBlbmNyeXB0T3B0aW9ucy5hZGF0YSA9IG9wdGlvbnMuYWRhdGE7XG4gIH1cblxuICByZXR1cm4gc2pjbC5lbmNyeXB0KHBhc3N3b3JkLCBwbGFpbnRleHQsIGVuY3J5cHRPcHRpb25zKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlY3J5cHQocGFzc3dvcmQ6IHN0cmluZywgY2lwaGVydGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHNqY2wuZGVjcnlwdChwYXNzd29yZCwgY2lwaGVydGV4dCk7XG59XG5cbi8qKlxuICogQXN5bmMgZGVjcnlwdCB0aGF0IGF1dG8tZGV0ZWN0cyB2MSAoU0pDTCkgb3IgdjIgKEFyZ29uMmlkICsgQUVTLTI1Ni1HQ00pXG4gKiBmcm9tIHRoZSBKU09OIGVudmVsb3BlJ3MgYHZgIGZpZWxkLlxuICpcbiAqIFRoaXMgaXMgdGhlIG1pZ3JhdGlvbiBwYXRoIGZyb20gc3luYyBgZGVjcnlwdCgpYC4gQ2xpZW50cyBzaG91bGQgbW92ZSB0b1xuICogYGF3YWl0IGRlY3J5cHRBc3luYygpYCBiZWZvcmUgdGhlIGJyZWFraW5nIHJlbGVhc2UgdGhhdCBtYWtlcyBgZGVjcnlwdCgpYCBhc3luYy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRlY3J5cHRBc3luYyhwYXNzd29yZDogc3RyaW5nLCBjaXBoZXJ0ZXh0OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICBsZXQgaXNWMiA9IGZhbHNlO1xuICB0cnkge1xuICAgIC8vIE9ubHkgcGVla2luZyBhdCB0aGUgdiBmaWVsZCB0byByb3V0ZTsgdGhpcyBpcyBhbiBpbnRlcm5hbCBmb3JtYXQgd2UgcHJvZHVjZSwgbm90IGV4dGVybmFsIGlucHV0LlxuICAgIGNvbnN0IGVudmVsb3BlID0gSlNPTi5wYXJzZShjaXBoZXJ0ZXh0KTtcbiAgICBpc1YyID0gZW52ZWxvcGUudiA9PT0gMjtcbiAgfSBjYXRjaCB7XG4gICAgLy8gTm90IHZhbGlkIEpTT04gLS0gZmFsbCB0aHJvdWdoIHRvIHYxXG4gIH1cbiAgaWYgKGlzVjIpIHtcbiAgICAvLyBEbyBub3QgY2F0Y2ggZXJyb3JzIGhlcmU6IGEgd3JvbmcgcGFzc3dvcmQgb3IgY29ycnVwdCBlbnZlbG9wZSBvbiB2MiBkYXRhXG4gICAgLy8gc2hvdWxkIHByb3BhZ2F0ZSwgbm90IHNpbGVudGx5IGZhbGwgdGhyb3VnaCB0byBhIHYxIGRlY3J5cHQgYXR0ZW1wdC5cbiAgICByZXR1cm4gZGVjcnlwdFYyKHBhc3N3b3JkLCBjaXBoZXJ0ZXh0KTtcbiAgfVxuICByZXR1cm4gc2pjbC5kZWNyeXB0KHBhc3N3b3JkLCBjaXBoZXJ0ZXh0KTtcbn1cblxuLyoqXG4gKiBEZXJpdmUgYSAyNTYtYml0IGtleSBmcm9tIGEgcGFzc3dvcmQgdXNpbmcgQXJnb24yaWQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGRlcml2ZUtleVYyKFxuICBwYXNzd29yZDogc3RyaW5nLFxuICBzYWx0OiBVaW50OEFycmF5LFxuICBwYXJhbXM6IHsgbWVtb3J5U2l6ZTogbnVtYmVyOyBpdGVyYXRpb25zOiBudW1iZXI7IHBhcmFsbGVsaXNtOiBudW1iZXIgfVxuKTogUHJvbWlzZTxDcnlwdG9LZXk+IHtcbiAgY29uc3QgeyBhcmdvbjJpZCB9ID0gYXdhaXQgaW1wb3J0KCdAYml0Z28vYXJnb24yJyk7XG4gIGNvbnN0IGtleUJ5dGVzID0gYXdhaXQgYXJnb24yaWQoe1xuICAgIHBhc3N3b3JkLFxuICAgIHNhbHQsXG4gICAgbWVtb3J5U2l6ZTogcGFyYW1zLm1lbW9yeVNpemUsXG4gICAgaXRlcmF0aW9uczogcGFyYW1zLml0ZXJhdGlvbnMsXG4gICAgcGFyYWxsZWxpc206IHBhcmFtcy5wYXJhbGxlbGlzbSxcbiAgICBoYXNoTGVuZ3RoOiBBUkdPTjJfREVGQVVMVFMuaGFzaExlbmd0aCxcbiAgICBvdXRwdXRUeXBlOiAnYmluYXJ5JyxcbiAgfSk7XG5cbiAgcmV0dXJuIGNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KCdyYXcnLCBrZXlCeXRlcywgeyBuYW1lOiAnQUVTLUdDTScgfSwgZmFsc2UsIFsnZW5jcnlwdCcsICdkZWNyeXB0J10pO1xufVxuXG4vKipcbiAqIEVuY3J5cHQgcGxhaW50ZXh0IHVzaW5nIEFyZ29uMmlkIEtERiArIEFFUy0yNTYtR0NNLlxuICpcbiAqIFJldHVybnMgYSBKU09OIHN0cmluZyBjb250YWluaW5nIGEgc2VsZi1kZXNjcmliaW5nIHYyIGVudmVsb3BlXG4gKiB3aXRoIEFyZ29uMmlkIHBhcmFtZXRlcnMsIHNhbHQsIElWLCBhbmQgY2lwaGVydGV4dC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGVuY3J5cHRWMihcbiAgcGFzc3dvcmQ6IHN0cmluZyxcbiAgcGxhaW50ZXh0OiBzdHJpbmcsXG4gIG9wdGlvbnM/OiB7XG4gICAgc2FsdD86IFVpbnQ4QXJyYXk7XG4gICAgaXY/OiBVaW50OEFycmF5O1xuICAgIG1lbW9yeVNpemU/OiBudW1iZXI7XG4gICAgaXRlcmF0aW9ucz86IG51bWJlcjtcbiAgICBwYXJhbGxlbGlzbT86IG51bWJlcjtcbiAgfVxuKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgbWVtb3J5U2l6ZSA9IG9wdGlvbnM/Lm1lbW9yeVNpemUgPz8gQVJHT04yX0RFRkFVTFRTLm1lbW9yeVNpemU7XG4gIGNvbnN0IGl0ZXJhdGlvbnMgPSBvcHRpb25zPy5pdGVyYXRpb25zID8/IEFSR09OMl9ERUZBVUxUUy5pdGVyYXRpb25zO1xuICBjb25zdCBwYXJhbGxlbGlzbSA9IG9wdGlvbnM/LnBhcmFsbGVsaXNtID8/IEFSR09OMl9ERUZBVUxUUy5wYXJhbGxlbGlzbTtcblxuICBjb25zdCBzYWx0ID0gb3B0aW9ucz8uc2FsdCA/PyBuZXcgVWludDhBcnJheShyYW5kb21CeXRlcyhBUkdPTjJfREVGQVVMVFMuc2FsdExlbmd0aCkpO1xuICBpZiAoc2FsdC5sZW5ndGggIT09IEFSR09OMl9ERUZBVUxUUy5zYWx0TGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBzYWx0IG11c3QgYmUgJHtBUkdPTjJfREVGQVVMVFMuc2FsdExlbmd0aH0gYnl0ZXNgKTtcbiAgfVxuXG4gIGNvbnN0IGl2ID0gb3B0aW9ucz8uaXYgPz8gbmV3IFVpbnQ4QXJyYXkocmFuZG9tQnl0ZXMoR0NNX0lWX0xFTkdUSCkpO1xuICBpZiAoaXYubGVuZ3RoICE9PSBHQ01fSVZfTEVOR1RIKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBpdiBtdXN0IGJlICR7R0NNX0lWX0xFTkdUSH0gYnl0ZXNgKTtcbiAgfVxuXG4gIGNvbnN0IGtleSA9IGF3YWl0IGRlcml2ZUtleVYyKHBhc3N3b3JkLCBzYWx0LCB7IG1lbW9yeVNpemUsIGl0ZXJhdGlvbnMsIHBhcmFsbGVsaXNtIH0pO1xuXG4gIGNvbnN0IHBsYWludGV4dEJ5dGVzID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHBsYWludGV4dCk7XG4gIGNvbnN0IGN0QnVmZmVyID0gYXdhaXQgY3J5cHRvLnN1YnRsZS5lbmNyeXB0KHsgbmFtZTogJ0FFUy1HQ00nLCBpdiB9LCBrZXksIHBsYWludGV4dEJ5dGVzKTtcblxuICBjb25zdCBlbnZlbG9wZTogVjJFbnZlbG9wZSA9IHtcbiAgICB2OiAyLFxuICAgIG06IG1lbW9yeVNpemUsXG4gICAgdDogaXRlcmF0aW9ucyxcbiAgICBwOiBwYXJhbGxlbGlzbSxcbiAgICBzYWx0OiBCdWZmZXIuZnJvbShzYWx0KS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgaXY6IEJ1ZmZlci5mcm9tKGl2KS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgY3Q6IEJ1ZmZlci5mcm9tKGN0QnVmZmVyKS50b1N0cmluZygnYmFzZTY0JyksXG4gIH07XG5cbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGVudmVsb3BlKTtcbn1cblxuLyoqXG4gKiBEZWNyeXB0IGEgdjIgZW52ZWxvcGUgKEFyZ29uMmlkIEtERiArIEFFUy0yNTYtR0NNKS5cbiAqXG4gKiBUaGUgZW52ZWxvcGUgbXVzdCBjb250YWluOiB2LCBtLCB0LCBwLCBzYWx0LCBpdiwgY3QuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWNyeXB0VjIocGFzc3dvcmQ6IHN0cmluZywgY2lwaGVydGV4dDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgbGV0IHBhcnNlZDogdW5rbm93bjtcbiAgdHJ5IHtcbiAgICBwYXJzZWQgPSBKU09OLnBhcnNlKGNpcGhlcnRleHQpO1xuICB9IGNhdGNoIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3YyIGRlY3J5cHQ6IGludmFsaWQgSlNPTiBlbnZlbG9wZScpO1xuICB9XG5cbiAgY29uc3QgZW52ZWxvcGUgPSBkZWNvZGVXaXRoQ29kZWMoVjJFbnZlbG9wZUNvZGVjLCBwYXJzZWQsICd2MiBkZWNyeXB0OiBpbnZhbGlkIGVudmVsb3BlJyk7XG5cbiAgY29uc3Qgc2FsdCA9IG5ldyBVaW50OEFycmF5KEJ1ZmZlci5mcm9tKGVudmVsb3BlLnNhbHQsICdiYXNlNjQnKSk7XG4gIGNvbnN0IGl2ID0gbmV3IFVpbnQ4QXJyYXkoQnVmZmVyLmZyb20oZW52ZWxvcGUuaXYsICdiYXNlNjQnKSk7XG4gIGNvbnN0IGN0ID0gbmV3IFVpbnQ4QXJyYXkoQnVmZmVyLmZyb20oZW52ZWxvcGUuY3QsICdiYXNlNjQnKSk7XG5cbiAgY29uc3Qga2V5ID0gYXdhaXQgZGVyaXZlS2V5VjIocGFzc3dvcmQsIHNhbHQsIHtcbiAgICBtZW1vcnlTaXplOiBlbnZlbG9wZS5tLFxuICAgIGl0ZXJhdGlvbnM6IGVudmVsb3BlLnQsXG4gICAgcGFyYWxsZWxpc206IGVudmVsb3BlLnAsXG4gIH0pO1xuXG4gIGNvbnN0IHBsYWludGV4dEJ1ZmZlciA9IGF3YWl0IGNyeXB0by5zdWJ0bGUuZGVjcnlwdCh7IG5hbWU6ICdBRVMtR0NNJywgaXYgfSwga2V5LCBjdCk7XG5cbiAgcmV0dXJuIG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShwbGFpbnRleHRCdWZmZXIpO1xufVxuIl19
|
|
103
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jcnlwdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9lbmNyeXB0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBV0Esa0NBS0M7QUFHRCwwQkF1QkM7QUFHRCwwQkFFQztBQVFELG9DQWFDO0FBcEVELGtEQUFvQztBQUNwQyxtQ0FBcUM7QUFFckMsMkNBQXdDO0FBRXhDOzs7OztHQUtHO0FBQ0gsU0FBZ0IsV0FBVyxDQUFDLEtBQTZCO0lBQ3ZELElBQUksQ0FBQyxDQUFDLEtBQUssWUFBWSxVQUFVLENBQUMsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3pELE1BQU0sSUFBSSxLQUFLLENBQUMsMENBQTBDLENBQUMsQ0FBQztJQUM5RCxDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLEtBQUssR0FBRyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDNUQsQ0FBQztBQUVELGtFQUFrRTtBQUNsRSxTQUFnQixPQUFPLENBQ3JCLFFBQWdCLEVBQ2hCLFNBQWlCLEVBQ2pCLE9BQXdEO0lBRXhELE1BQU0sSUFBSSxHQUFHLE9BQU8sRUFBRSxJQUFJLElBQUksSUFBQSxvQkFBVyxFQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzdDLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO0lBQy9ELE1BQU0sRUFBRSxHQUFHLE9BQU8sRUFBRSxFQUFFLElBQUksSUFBQSxvQkFBVyxFQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzFDLElBQUksRUFBRSxDQUFDLE1BQU0sS0FBSyxFQUFFO1FBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO0lBRTdELE1BQU0sY0FBYyxHQUErRTtRQUNqRyxJQUFJLEVBQUUsS0FBSztRQUNYLEVBQUUsRUFBRSxHQUFHO1FBQ1AsSUFBSSxFQUFFLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNqRSxFQUFFLEVBQUU7WUFDRixXQUFXLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDM0IsV0FBVyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzNCLFdBQVcsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUM1QixXQUFXLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7U0FDOUI7S0FDRixDQUFDO0lBQ0YsSUFBSSxPQUFPLEVBQUUsS0FBSztRQUFFLGNBQWMsQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQztJQUN6RCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLFNBQVMsRUFBRSxjQUFjLENBQUMsQ0FBQztBQUMzRCxDQUFDO0FBRUQsa0NBQWtDO0FBQ2xDLFNBQWdCLE9BQU8sQ0FBQyxRQUFnQixFQUFFLFVBQWtCO0lBQzFELE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLENBQUM7QUFDNUMsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0ksS0FBSyxVQUFVLFlBQVksQ0FBQyxRQUFnQixFQUFFLFVBQWtCO0lBQ3JFLElBQUksSUFBSSxHQUFHLEtBQUssQ0FBQztJQUNqQixJQUFJLENBQUM7UUFDSCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3hDLElBQUksR0FBRyxRQUFRLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMxQixDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsTUFBTSxJQUFJLEtBQUssQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFDRCxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ1QsMkVBQTJFO1FBQzNFLE9BQU8sSUFBQSxxQkFBUyxFQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztBQUM1QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgc2pjbCBmcm9tICdAYml0Z28vc2pjbCc7XG5pbXBvcnQgeyByYW5kb21CeXRlcyB9IGZyb20gJ2NyeXB0byc7XG5cbmltcG9ydCB7IGRlY3J5cHRWMiB9IGZyb20gJy4vZW5jcnlwdFYyJztcblxuLyoqXG4gKiBjb252ZXJ0IGEgNCBlbGVtZW50IFVpbnQ4QXJyYXkgdG8gYSA0IGJ5dGUgTnVtYmVyXG4gKlxuICogQHBhcmFtIGJ5dGVzXG4gKiBAcmV0dXJuIDQgYnl0ZSBudW1iZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ5dGVzVG9Xb3JkKGJ5dGVzPzogVWludDhBcnJheSB8IG51bWJlcltdKTogbnVtYmVyIHtcbiAgaWYgKCEoYnl0ZXMgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB8fCBieXRlcy5sZW5ndGggIT09IDQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2J5dGVzIG11c3QgYmUgYSBVaW50OEFycmF5IHdpdGggbGVuZ3RoIDQnKTtcbiAgfVxuICByZXR1cm4gYnl0ZXMucmVkdWNlKChudW0sIGJ5dGUpID0+IG51bSAqIDB4MTAwICsgYnl0ZSwgMCk7XG59XG5cbi8qKiBFbmNyeXB0IHVzaW5nIGxlZ2FjeSB2MSBTSkNMIChQQktERjItU0hBMjU2ICsgQUVTLTI1Ni1DQ00pLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVuY3J5cHQoXG4gIHBhc3N3b3JkOiBzdHJpbmcsXG4gIHBsYWludGV4dDogc3RyaW5nLFxuICBvcHRpb25zPzogeyBzYWx0PzogQnVmZmVyOyBpdj86IEJ1ZmZlcjsgYWRhdGE/OiBzdHJpbmcgfVxuKTogc3RyaW5nIHtcbiAgY29uc3Qgc2FsdCA9IG9wdGlvbnM/LnNhbHQgfHwgcmFuZG9tQnl0ZXMoOCk7XG4gIGlmIChzYWx0Lmxlbmd0aCAhPT0gOCkgdGhyb3cgbmV3IEVycm9yKCdzYWx0IG11c3QgYmUgOCBieXRlcycpO1xuICBjb25zdCBpdiA9IG9wdGlvbnM/Lml2IHx8IHJhbmRvbUJ5dGVzKDE2KTtcbiAgaWYgKGl2Lmxlbmd0aCAhPT0gMTYpIHRocm93IG5ldyBFcnJvcignaXYgbXVzdCBiZSAxNiBieXRlcycpO1xuXG4gIGNvbnN0IGVuY3J5cHRPcHRpb25zOiB7IGl0ZXI6IG51bWJlcjsga3M6IG51bWJlcjsgc2FsdDogbnVtYmVyW107IGl2OiBudW1iZXJbXTsgYWRhdGE/OiBzdHJpbmcgfSA9IHtcbiAgICBpdGVyOiAxMDAwMCxcbiAgICBrczogMjU2LFxuICAgIHNhbHQ6IFtieXRlc1RvV29yZChzYWx0LnNsaWNlKDAsIDQpKSwgYnl0ZXNUb1dvcmQoc2FsdC5zbGljZSg0KSldLFxuICAgIGl2OiBbXG4gICAgICBieXRlc1RvV29yZChpdi5zbGljZSgwLCA0KSksXG4gICAgICBieXRlc1RvV29yZChpdi5zbGljZSg0LCA4KSksXG4gICAgICBieXRlc1RvV29yZChpdi5zbGljZSg4LCAxMikpLFxuICAgICAgYnl0ZXNUb1dvcmQoaXYuc2xpY2UoMTIsIDE2KSksXG4gICAgXSxcbiAgfTtcbiAgaWYgKG9wdGlvbnM/LmFkYXRhKSBlbmNyeXB0T3B0aW9ucy5hZGF0YSA9IG9wdGlvbnMuYWRhdGE7XG4gIHJldHVybiBzamNsLmVuY3J5cHQocGFzc3dvcmQsIHBsYWludGV4dCwgZW5jcnlwdE9wdGlvbnMpO1xufVxuXG4vKiogRGVjcnlwdCBhIHYxIFNKQ0wgZW52ZWxvcGUuICovXG5leHBvcnQgZnVuY3Rpb24gZGVjcnlwdChwYXNzd29yZDogc3RyaW5nLCBjaXBoZXJ0ZXh0OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gc2pjbC5kZWNyeXB0KHBhc3N3b3JkLCBjaXBoZXJ0ZXh0KTtcbn1cblxuLyoqXG4gKiBBdXRvLWRldGVjdCB2MSAoU0pDTCkgb3IgdjIgKEFyZ29uMmlkICsgQUVTLTI1Ni1HQ00pIGZyb20gdGhlIGVudmVsb3BlIGB2YCBmaWVsZCBhbmQgZGVjcnlwdC5cbiAqXG4gKiBNaWdyYXRpb24gcGF0aCBmcm9tIHN5bmMgYGRlY3J5cHQoKWAuIE1vdmUgY2FsbCBzaXRlcyB0byBgZGVjcnlwdEFzeW5jKClgIGJlZm9yZVxuICogdGhlIGJyZWFraW5nIHJlbGVhc2UgdGhhdCBmbGlwcyB0aGUgZGVmYXVsdCB0byB2Mi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRlY3J5cHRBc3luYyhwYXNzd29yZDogc3RyaW5nLCBjaXBoZXJ0ZXh0OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICBsZXQgaXNWMiA9IGZhbHNlO1xuICB0cnkge1xuICAgIGNvbnN0IGVudmVsb3BlID0gSlNPTi5wYXJzZShjaXBoZXJ0ZXh0KTtcbiAgICBpc1YyID0gZW52ZWxvcGUudiA9PT0gMjtcbiAgfSBjYXRjaCB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdkZWNyeXB0OiBjaXBoZXJ0ZXh0IGlzIG5vdCB2YWxpZCBKU09OJyk7XG4gIH1cbiAgaWYgKGlzVjIpIHtcbiAgICAvLyBEbyBub3QgY2F0Y2g6IHdyb25nIHBhc3N3b3JkIG9uIHYyIG11c3Qgbm90IHNpbGVudGx5IGZhbGwgdGhyb3VnaCB0byB2MS5cbiAgICByZXR1cm4gZGVjcnlwdFYyKHBhc3N3b3JkLCBjaXBoZXJ0ZXh0KTtcbiAgfVxuICByZXR1cm4gc2pjbC5kZWNyeXB0KHBhc3N3b3JkLCBjaXBoZXJ0ZXh0KTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import * as t from 'io-ts';
|
|
2
|
+
/** Default Argon2id parameters per RFC 9106 second recommendation
|
|
3
|
+
* @see https://www.rfc-editor.org/rfc/rfc9106#section-4
|
|
4
|
+
*/
|
|
5
|
+
export declare const ARGON2_DEFAULTS: {
|
|
6
|
+
readonly memorySize: 65536;
|
|
7
|
+
readonly iterations: 3;
|
|
8
|
+
readonly parallelism: 4;
|
|
9
|
+
readonly hashLength: 32;
|
|
10
|
+
readonly saltLength: 16;
|
|
11
|
+
};
|
|
12
|
+
/** AES-256-GCM IV length in bytes */
|
|
13
|
+
export declare const GCM_IV_LENGTH = 12;
|
|
14
|
+
/** HKDF per-call salt length in bytes */
|
|
15
|
+
export declare const HKDF_SALT_LENGTH = 32;
|
|
16
|
+
declare const V2EnvelopeCodec: t.IntersectionC<[t.TypeC<{
|
|
17
|
+
v: t.LiteralC<2>;
|
|
18
|
+
m: t.Type<number, number, unknown>;
|
|
19
|
+
t: t.Type<number, number, unknown>;
|
|
20
|
+
p: t.Type<number, number, unknown>;
|
|
21
|
+
salt: t.Type<string, string, unknown>;
|
|
22
|
+
iv: t.Type<string, string, unknown>;
|
|
23
|
+
ct: t.Type<string, string, unknown>;
|
|
24
|
+
}>, t.PartialC<{
|
|
25
|
+
/** Base64-encoded per-call HKDF salt -- present only in session-produced envelopes */
|
|
26
|
+
hkdfSalt: t.Type<string, string, unknown>;
|
|
27
|
+
}>]>;
|
|
28
|
+
export type V2Envelope = t.TypeOf<typeof V2EnvelopeCodec>;
|
|
29
|
+
export declare function argon2ToHkdfKey(password: string, salt: Uint8Array, params: {
|
|
30
|
+
memorySize: number;
|
|
31
|
+
iterations: number;
|
|
32
|
+
parallelism: number;
|
|
33
|
+
}): Promise<CryptoKey>;
|
|
34
|
+
export declare function hkdfDeriveAesKey(hkdfKey: CryptoKey, hkdfSalt: Uint8Array, usage: KeyUsage): Promise<CryptoKey>;
|
|
35
|
+
export declare function aesGcmEncrypt(key: CryptoKey, iv: Uint8Array, plaintext: string): Promise<Uint8Array>;
|
|
36
|
+
export declare function aesGcmDecrypt(key: CryptoKey, iv: Uint8Array, ct: Uint8Array): Promise<string>;
|
|
37
|
+
export declare function parseV2Envelope(ciphertext: string): V2Envelope;
|
|
38
|
+
/**
|
|
39
|
+
* Encrypt plaintext using Argon2id KDF + AES-256-GCM.
|
|
40
|
+
*
|
|
41
|
+
* Returns a self-describing JSON v2 envelope containing all Argon2id parameters,
|
|
42
|
+
* salt, IV, and ciphertext -- fully standalone for decryption.
|
|
43
|
+
*
|
|
44
|
+
* For multi-call operations (MPC signing, wallet creation), prefer
|
|
45
|
+
* createEncryptionSession to run Argon2id once and derive per-call keys via HKDF.
|
|
46
|
+
*/
|
|
47
|
+
export declare function encryptV2(password: string, plaintext: string, options?: {
|
|
48
|
+
salt?: Uint8Array;
|
|
49
|
+
iv?: Uint8Array;
|
|
50
|
+
memorySize?: number;
|
|
51
|
+
iterations?: number;
|
|
52
|
+
parallelism?: number;
|
|
53
|
+
}): Promise<string>;
|
|
54
|
+
/**
|
|
55
|
+
* Decrypt a v2 envelope (Argon2id + AES-256-GCM).
|
|
56
|
+
*
|
|
57
|
+
* Handles both envelope types automatically:
|
|
58
|
+
* - Standard (no hkdfSalt): Argon2id -> AES-GCM
|
|
59
|
+
* - Session (hkdfSalt present): Argon2id -> HKDF -> AES-GCM
|
|
60
|
+
*
|
|
61
|
+
* All parameters are stored in the envelope -- no session context required.
|
|
62
|
+
*/
|
|
63
|
+
export declare function decryptV2(password: string, ciphertext: string): Promise<string>;
|
|
64
|
+
export {};
|
|
65
|
+
//# sourceMappingURL=encryptV2.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryptV2.d.ts","sourceRoot":"","sources":["../../src/encryptV2.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,CAAC,MAAM,OAAO,CAAC;AAE3B;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;CAMlB,CAAC;AAaX,qCAAqC;AACrC,eAAO,MAAM,aAAa,KAAK,CAAC;AAEhC,yCAAyC;AACzC,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAOnC,QAAA,MAAM,eAAe;;;;;;;;;IAWjB,sFAAsF;;IAGxF,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,eAAe,CAAC,CAAC;AA6B1D,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACtE,OAAO,CAAC,SAAS,CAAC,CAGpB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,CAQ9G;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAO1G;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAGnG;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAQ9D;AAID;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,UAAU,CAAC;IAAC,EAAE,CAAC,EAAE,UAAU,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/G,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAED;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgBrF"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.HKDF_SALT_LENGTH = exports.GCM_IV_LENGTH = exports.ARGON2_DEFAULTS = void 0;
|
|
37
|
+
exports.argon2ToHkdfKey = argon2ToHkdfKey;
|
|
38
|
+
exports.hkdfDeriveAesKey = hkdfDeriveAesKey;
|
|
39
|
+
exports.aesGcmEncrypt = aesGcmEncrypt;
|
|
40
|
+
exports.aesGcmDecrypt = aesGcmDecrypt;
|
|
41
|
+
exports.parseV2Envelope = parseV2Envelope;
|
|
42
|
+
exports.encryptV2 = encryptV2;
|
|
43
|
+
exports.decryptV2 = decryptV2;
|
|
44
|
+
const argon2_1 = require("@bitgo/argon2");
|
|
45
|
+
const sdk_core_1 = require("@bitgo/sdk-core");
|
|
46
|
+
const crypto_1 = require("crypto");
|
|
47
|
+
const t = __importStar(require("io-ts"));
|
|
48
|
+
/** Default Argon2id parameters per RFC 9106 second recommendation
|
|
49
|
+
* @see https://www.rfc-editor.org/rfc/rfc9106#section-4
|
|
50
|
+
*/
|
|
51
|
+
exports.ARGON2_DEFAULTS = {
|
|
52
|
+
memorySize: 65536, // 64 MiB in KiB
|
|
53
|
+
iterations: 3,
|
|
54
|
+
parallelism: 4,
|
|
55
|
+
hashLength: 32, // 256-bit key
|
|
56
|
+
saltLength: 16, // 128-bit salt
|
|
57
|
+
};
|
|
58
|
+
/** Maximum allowed Argon2id parameters to prevent DoS via crafted envelopes.
|
|
59
|
+
* memorySize: 256 MiB (4x default) -- caps memory allocation on untrusted input.
|
|
60
|
+
* iterations: 16 -- caps CPU time.
|
|
61
|
+
* parallelism: 16 -- caps thread count.
|
|
62
|
+
*/
|
|
63
|
+
const ARGON2_MAX = {
|
|
64
|
+
memorySize: 262144,
|
|
65
|
+
iterations: 16,
|
|
66
|
+
parallelism: 16,
|
|
67
|
+
};
|
|
68
|
+
/** AES-256-GCM IV length in bytes */
|
|
69
|
+
exports.GCM_IV_LENGTH = 12;
|
|
70
|
+
/** HKDF per-call salt length in bytes */
|
|
71
|
+
exports.HKDF_SALT_LENGTH = 32;
|
|
72
|
+
/** Fixed HKDF info string for domain separation across BitGo v2 session keys */
|
|
73
|
+
const HKDF_INFO = new TextEncoder().encode('bitgo-v2-session');
|
|
74
|
+
// Envelope codec
|
|
75
|
+
const V2EnvelopeCodec = t.intersection([
|
|
76
|
+
t.type({
|
|
77
|
+
v: t.literal(2),
|
|
78
|
+
m: (0, sdk_core_1.boundedInt)(1, ARGON2_MAX.memorySize, 'memorySize'),
|
|
79
|
+
t: (0, sdk_core_1.boundedInt)(1, ARGON2_MAX.iterations, 'iterations'),
|
|
80
|
+
p: (0, sdk_core_1.boundedInt)(1, ARGON2_MAX.parallelism, 'parallelism'),
|
|
81
|
+
salt: sdk_core_1.base64String,
|
|
82
|
+
iv: sdk_core_1.base64String,
|
|
83
|
+
ct: sdk_core_1.base64String,
|
|
84
|
+
}),
|
|
85
|
+
t.partial({
|
|
86
|
+
/** Base64-encoded per-call HKDF salt -- present only in session-produced envelopes */
|
|
87
|
+
hkdfSalt: sdk_core_1.base64String,
|
|
88
|
+
}),
|
|
89
|
+
]);
|
|
90
|
+
// Crypto helpers
|
|
91
|
+
async function argon2Hash(password, salt, params) {
|
|
92
|
+
return (0, argon2_1.argon2id)({
|
|
93
|
+
password,
|
|
94
|
+
salt,
|
|
95
|
+
memorySize: params.memorySize,
|
|
96
|
+
iterations: params.iterations,
|
|
97
|
+
parallelism: params.parallelism,
|
|
98
|
+
hashLength: exports.ARGON2_DEFAULTS.hashLength,
|
|
99
|
+
outputType: 'binary',
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
async function argon2ToAesKey(password, salt, params) {
|
|
103
|
+
const keyBytes = await argon2Hash(password, salt, params);
|
|
104
|
+
return crypto.subtle.importKey('raw', keyBytes, { name: 'AES-GCM' }, false, ['encrypt', 'decrypt']);
|
|
105
|
+
}
|
|
106
|
+
async function argon2ToHkdfKey(password, salt, params) {
|
|
107
|
+
const keyBytes = await argon2Hash(password, salt, params);
|
|
108
|
+
return crypto.subtle.importKey('raw', keyBytes, 'HKDF', false, ['deriveKey']);
|
|
109
|
+
}
|
|
110
|
+
function hkdfDeriveAesKey(hkdfKey, hkdfSalt, usage) {
|
|
111
|
+
return crypto.subtle.deriveKey({ name: 'HKDF', hash: 'SHA-256', salt: hkdfSalt, info: HKDF_INFO }, hkdfKey, { name: 'AES-GCM', length: 256 }, false, [usage]);
|
|
112
|
+
}
|
|
113
|
+
async function aesGcmEncrypt(key, iv, plaintext) {
|
|
114
|
+
const ct = await crypto.subtle.encrypt({ name: 'AES-GCM', iv, tagLength: 128 }, key, new TextEncoder().encode(plaintext));
|
|
115
|
+
return new Uint8Array(ct);
|
|
116
|
+
}
|
|
117
|
+
async function aesGcmDecrypt(key, iv, ct) {
|
|
118
|
+
const plaintext = await crypto.subtle.decrypt({ name: 'AES-GCM', iv, tagLength: 128 }, key, ct);
|
|
119
|
+
return new TextDecoder().decode(plaintext);
|
|
120
|
+
}
|
|
121
|
+
function parseV2Envelope(ciphertext) {
|
|
122
|
+
let parsed;
|
|
123
|
+
try {
|
|
124
|
+
parsed = JSON.parse(ciphertext);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
throw new Error('v2 decrypt: invalid JSON envelope');
|
|
128
|
+
}
|
|
129
|
+
return (0, sdk_core_1.decodeWithCodec)(V2EnvelopeCodec, parsed, 'v2 decrypt: invalid envelope');
|
|
130
|
+
}
|
|
131
|
+
// Public API
|
|
132
|
+
/**
|
|
133
|
+
* Encrypt plaintext using Argon2id KDF + AES-256-GCM.
|
|
134
|
+
*
|
|
135
|
+
* Returns a self-describing JSON v2 envelope containing all Argon2id parameters,
|
|
136
|
+
* salt, IV, and ciphertext -- fully standalone for decryption.
|
|
137
|
+
*
|
|
138
|
+
* For multi-call operations (MPC signing, wallet creation), prefer
|
|
139
|
+
* createEncryptionSession to run Argon2id once and derive per-call keys via HKDF.
|
|
140
|
+
*/
|
|
141
|
+
async function encryptV2(password, plaintext, options) {
|
|
142
|
+
const memorySize = options?.memorySize ?? exports.ARGON2_DEFAULTS.memorySize;
|
|
143
|
+
const iterations = options?.iterations ?? exports.ARGON2_DEFAULTS.iterations;
|
|
144
|
+
const parallelism = options?.parallelism ?? exports.ARGON2_DEFAULTS.parallelism;
|
|
145
|
+
const salt = options?.salt ?? new Uint8Array((0, crypto_1.randomBytes)(exports.ARGON2_DEFAULTS.saltLength));
|
|
146
|
+
if (salt.length !== exports.ARGON2_DEFAULTS.saltLength)
|
|
147
|
+
throw new Error(`salt must be ${exports.ARGON2_DEFAULTS.saltLength} bytes`);
|
|
148
|
+
const iv = options?.iv ?? new Uint8Array((0, crypto_1.randomBytes)(exports.GCM_IV_LENGTH));
|
|
149
|
+
if (iv.length !== exports.GCM_IV_LENGTH)
|
|
150
|
+
throw new Error(`iv must be ${exports.GCM_IV_LENGTH} bytes`);
|
|
151
|
+
const key = await argon2ToAesKey(password, salt, { memorySize, iterations, parallelism });
|
|
152
|
+
const ct = await aesGcmEncrypt(key, iv, plaintext);
|
|
153
|
+
return JSON.stringify({
|
|
154
|
+
v: 2,
|
|
155
|
+
m: memorySize,
|
|
156
|
+
t: iterations,
|
|
157
|
+
p: parallelism,
|
|
158
|
+
salt: Buffer.from(salt).toString('base64'),
|
|
159
|
+
iv: Buffer.from(iv).toString('base64'),
|
|
160
|
+
ct: Buffer.from(ct).toString('base64'),
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Decrypt a v2 envelope (Argon2id + AES-256-GCM).
|
|
165
|
+
*
|
|
166
|
+
* Handles both envelope types automatically:
|
|
167
|
+
* - Standard (no hkdfSalt): Argon2id -> AES-GCM
|
|
168
|
+
* - Session (hkdfSalt present): Argon2id -> HKDF -> AES-GCM
|
|
169
|
+
*
|
|
170
|
+
* All parameters are stored in the envelope -- no session context required.
|
|
171
|
+
*/
|
|
172
|
+
async function decryptV2(password, ciphertext) {
|
|
173
|
+
const envelope = parseV2Envelope(ciphertext);
|
|
174
|
+
const salt = new Uint8Array(Buffer.from(envelope.salt, 'base64'));
|
|
175
|
+
const iv = new Uint8Array(Buffer.from(envelope.iv, 'base64'));
|
|
176
|
+
const ct = new Uint8Array(Buffer.from(envelope.ct, 'base64'));
|
|
177
|
+
const params = { memorySize: envelope.m, iterations: envelope.t, parallelism: envelope.p };
|
|
178
|
+
if (envelope.hkdfSalt) {
|
|
179
|
+
const hkdfKey = await argon2ToHkdfKey(password, salt, params);
|
|
180
|
+
const hkdfSalt = new Uint8Array(Buffer.from(envelope.hkdfSalt, 'base64'));
|
|
181
|
+
const aesKey = await hkdfDeriveAesKey(hkdfKey, hkdfSalt, 'decrypt');
|
|
182
|
+
return aesGcmDecrypt(aesKey, iv, ct);
|
|
183
|
+
}
|
|
184
|
+
const key = await argon2ToAesKey(password, salt, params);
|
|
185
|
+
return aesGcmDecrypt(key, iv, ct);
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jcnlwdFYyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2VuY3J5cHRWMi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFtRkEsMENBT0M7QUFFRCw0Q0FRQztBQUVELHNDQU9DO0FBRUQsc0NBR0M7QUFFRCwwQ0FRQztBQWFELDhCQTJCQztBQVdELDhCQWdCQztBQS9MRCwwQ0FBeUM7QUFDekMsOENBQTRFO0FBQzVFLG1DQUFxQztBQUNyQyx5Q0FBMkI7QUFFM0I7O0dBRUc7QUFDVSxRQUFBLGVBQWUsR0FBRztJQUM3QixVQUFVLEVBQUUsS0FBSyxFQUFFLGdCQUFnQjtJQUNuQyxVQUFVLEVBQUUsQ0FBQztJQUNiLFdBQVcsRUFBRSxDQUFDO0lBQ2QsVUFBVSxFQUFFLEVBQUUsRUFBRSxjQUFjO0lBQzlCLFVBQVUsRUFBRSxFQUFFLEVBQUUsZUFBZTtDQUN2QixDQUFDO0FBRVg7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxHQUFHO0lBQ2pCLFVBQVUsRUFBRSxNQUFNO0lBQ2xCLFVBQVUsRUFBRSxFQUFFO0lBQ2QsV0FBVyxFQUFFLEVBQUU7Q0FDUCxDQUFDO0FBRVgscUNBQXFDO0FBQ3hCLFFBQUEsYUFBYSxHQUFHLEVBQUUsQ0FBQztBQUVoQyx5Q0FBeUM7QUFDNUIsUUFBQSxnQkFBZ0IsR0FBRyxFQUFFLENBQUM7QUFFbkMsZ0ZBQWdGO0FBQ2hGLE1BQU0sU0FBUyxHQUFHLElBQUksV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLENBQUM7QUFFL0QsaUJBQWlCO0FBRWpCLE1BQU0sZUFBZSxHQUFHLENBQUMsQ0FBQyxZQUFZLENBQUM7SUFDckMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUNMLENBQUMsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUNmLENBQUMsRUFBRSxJQUFBLHFCQUFVLEVBQUMsQ0FBQyxFQUFFLFVB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LFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDbEUsTUFBTSxFQUFFLEdBQUcsSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDOUQsTUFBTSxFQUFFLEdBQUcsSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDOUQsTUFBTSxNQUFNLEdBQUcsRUFBRSxVQUFVLEVBQUUsUUFBUSxDQUFDLENBQUMsRUFBRSxVQUFVLEVBQUUsUUFBUSxDQUFDLENBQUMsRUFBRSxXQUFXLEVBQUUsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDO0lBRTNGLElBQUksUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ3RCLE1BQU0sT0FBTyxHQUFHLE1BQU0sZUFBZSxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDOUQsTUFBTSxRQUFRLEdBQUcsSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDMUUsTUFBTSxNQUFNLEdBQUcsTUFBTSxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3BFLE9BQU8sYUFBYSxDQUFDLE1BQU0sRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVELE1BQU0sR0FBRyxHQUFHLE1BQU0sY0FBYyxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDekQsT0FBTyxhQUFhLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNwQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgYXJnb24yaWQgfSBmcm9tICdAYml0Z28vYXJnb24yJztcbmltcG9ydCB7IGJhc2U2NFN0cmluZywgYm91bmRlZEludCwgZGVjb2RlV2l0aENvZGVjIH0gZnJvbSAnQGJpdGdvL3Nkay1jb3JlJztcbmltcG9ydCB7IHJhbmRvbUJ5dGVzIH0gZnJvbSAnY3J5cHRvJztcbmltcG9ydCAqIGFzIHQgZnJvbSAnaW8tdHMnO1xuXG4vKiogRGVmYXVsdCBBcmdvbjJpZCBwYXJhbWV0ZXJzIHBlciBSRkMgOTEwNiBzZWNvbmQgcmVjb21tZW5kYXRpb25cbiAqIEBzZWUgaHR0cHM6Ly93d3cucmZjLWVkaXRvci5vcmcvcmZjL3JmYzkxMDYjc2VjdGlvbi00XG4gKi9cbmV4cG9ydCBjb25zdCBBUkdPTjJfREVGQVVMVFMgPSB7XG4gIG1lbW9yeVNpemU6IDY1NTM2LCAvLyA2NCBNaUIgaW4gS2lCXG4gIGl0ZXJhdGlvbnM6IDMsXG4gIHBhcmFsbGVsaXNtOiA0LFxuICBoYXNoTGVuZ3RoOiAzMiwgLy8gMjU2LWJpdCBrZXlcbiAgc2FsdExlbmd0aDogMTYsIC8vIDEyOC1iaXQgc2FsdFxufSBhcyBjb25zdDtcblxuLyoqIE1heGltdW0gYWxsb3dlZCBBcmdvbjJpZCBwYXJhbWV0ZXJzIHRvIHByZXZlbnQgRG9TIHZpYSBjcmFmdGVkIGVudmVsb3Blcy5cbiAqIG1lbW9yeVNpemU6IDI1NiBNaUIgKDR4IGRlZmF1bHQpIC0tIGNhcHMgbWVtb3J5IGFsbG9jYXRpb24gb24gdW50cnVzdGVkIGlucHV0LlxuICogaXRlcmF0aW9uczogMTYgLS0gY2FwcyBDUFUgdGltZS5cbiAqIHBhcmFsbGVsaXNtOiAxNiAtLSBjYXBzIHRocmVhZCBjb3VudC5cbiAqL1xuY29uc3QgQVJHT04yX01BWCA9IHtcbiAgbWVtb3J5U2l6ZTogMjYyMTQ0LFxuICBpdGVyYXRpb25zOiAxNixcbiAgcGFyYWxsZWxpc206IDE2LFxufSBhcyBjb25zdDtcblxuLyoqIEFFUy0yNTYtR0NNIElWIGxlbmd0aCBpbiBieXRlcyAqL1xuZXhwb3J0IGNvbnN0IEdDTV9JVl9MRU5HVEggPSAxMjtcblxuLyoqIEhLREYgcGVyLWNhbGwgc2FsdCBsZW5ndGggaW4gYnl0ZXMgKi9cbmV4cG9ydCBjb25zdCBIS0RGX1NBTFRfTEVOR1RIID0gMzI7XG5cbi8qKiBGaXhlZCBIS0RGIGluZm8gc3RyaW5nIGZvciBkb21haW4gc2VwYXJhdGlvbiBhY3Jvc3MgQml0R28gdjIgc2Vzc2lvbiBrZXlzICovXG5jb25zdCBIS0RGX0lORk8gPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoJ2JpdGdvLXYyLXNlc3Npb24nKTtcblxuLy8gRW52ZWxvcGUgY29kZWNcblxuY29uc3QgVjJFbnZlbG9wZUNvZGVjID0gdC5pbnRlcnNlY3Rpb24oW1xuICB0LnR5cGUoe1xuICAgIHY6IHQubGl0ZXJhbCgyKSxcbiAgICBtOiBib3VuZGVkSW50KDEsIEFSR09OMl9NQVgubWVtb3J5U2l6ZSwgJ21lbW9yeVNpemUnKSxcbiAgICB0OiBib3VuZGVkSW50KDEsIEFSR09OMl9NQVguaXRlcmF0aW9ucywgJ2l0ZXJhdGlvbnMnKSxcbiAgICBwOiBib3VuZGVkSW50KDEsIEFSR09OMl9NQVgucGFyYWxsZWxpc20sICdwYXJhbGxlbGlzbScpLFxuICAgIHNhbHQ6IGJhc2U2NFN0cmluZyxcbiAgICBpdjogYmFzZTY0U3RyaW5nLFxuICAgIGN0OiBiYXNlNjRTdHJpbmcsXG4gIH0pLFxuICB0LnBhcnRpYWwoe1xuICAgIC8qKiBCYXNlNjQtZW5jb2RlZCBwZXItY2FsbCBIS0RGIHNhbHQgLS0gcHJlc2VudCBvbmx5IGluIHNlc3Npb24tcHJvZHVjZWQgZW52ZWxvcGVzICovXG4gICAgaGtkZlNhbHQ6IGJhc2U2NFN0cmluZyxcbiAgfSksXG5dKTtcblxuZXhwb3J0IHR5cGUgVjJFbnZlbG9wZSA9IHQuVHlwZU9mPHR5cGVvZiBWMkVudmVsb3BlQ29kZWM+O1xuXG4vLyBDcnlwdG8gaGVscGVyc1xuXG5hc3luYyBmdW5jdGlvbiBhcmdvbjJIYXNoKFxuICBwYXNzd29yZDogc3RyaW5nLFxuICBzYWx0OiBVaW50OEFycmF5LFxuICBwYXJhbXM6IHsgbWVtb3J5U2l6ZTogbnVtYmVyOyBpdGVyYXRpb25zOiBudW1iZXI7IHBhcmFsbGVsaXNtOiBudW1iZXIgfVxuKTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gIHJldHVybiBhcmdvbjJpZCh7XG4gICAgcGFzc3dvcmQsXG4gICAgc2FsdCxcbiAgICBtZW1vcnlTaXplOiBwYXJhbXMubWVtb3J5U2l6ZSxcbiAgICBpdGVyYXRpb25zOiBwYXJhbXMuaXRlcmF0aW9ucyxcbiAgICBwYXJhbGxlbGlzbTogcGFyYW1zLnBhcmFsbGVsaXNtLFxuICAgIGhhc2hMZW5ndGg6IEFSR09OMl9ERUZBVUxUUy5oYXNoTGVuZ3RoLFxuICAgIG91dHB1dFR5cGU6ICdiaW5hcnknLFxuICB9KTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gYXJnb24yVG9BZXNLZXkoXG4gIHBhc3N3b3JkOiBzdHJpbmcsXG4gIHNhbHQ6IFVpbnQ4QXJyYXksXG4gIHBhcmFtczogeyBtZW1vcnlTaXplOiBudW1iZXI7IGl0ZXJhdGlvbnM6IG51bWJlcjsgcGFyYWxsZWxpc206IG51bWJlciB9XG4pOiBQcm9taXNlPENyeXB0b0tleT4ge1xuICBjb25zdCBrZXlCeXRlcyA9IGF3YWl0IGFyZ29uMkhhc2gocGFzc3dvcmQsIHNhbHQsIHBhcmFtcyk7XG4gIHJldHVybiBjcnlwdG8uc3VidGxlLmltcG9ydEtleSgncmF3Jywga2V5Qnl0ZXMsIHsgbmFtZTogJ0FFUy1HQ00nIH0sIGZhbHNlLCBbJ2VuY3J5cHQnLCAnZGVjcnlwdCddKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFyZ29uMlRvSGtkZktleShcbiAgcGFzc3dvcmQ6IHN0cmluZyxcbiAgc2FsdDogVWludDhBcnJheSxcbiAgcGFyYW1zOiB7IG1lbW9yeVNpemU6IG51bWJlcjsgaXRlcmF0aW9uczogbnVtYmVyOyBwYXJhbGxlbGlzbTogbnVtYmVyIH1cbik6IFByb21pc2U8Q3J5cHRvS2V5PiB7XG4gIGNvbnN0IGtleUJ5dGVzID0gYXdhaXQgYXJnb24ySGFzaChwYXNzd29yZCwgc2FsdCwgcGFyYW1zKTtcbiAgcmV0dXJuIGNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KCdyYXcnLCBrZXlCeXRlcywgJ0hLREYnLCBmYWxzZSwgWydkZXJpdmVLZXknXSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoa2RmRGVyaXZlQWVzS2V5KGhrZGZLZXk6IENyeXB0b0tleSwgaGtkZlNhbHQ6IFVpbnQ4QXJyYXksIHVzYWdlOiBLZXlVc2FnZSk6IFByb21pc2U8Q3J5cHRvS2V5PiB7XG4gIHJldHVybiBjcnlwdG8uc3VidGxlLmRlcml2ZUtleShcbiAgICB7IG5hbWU6ICdIS0RGJywgaGFzaDogJ1NIQS0yNTYnLCBzYWx0OiBoa2RmU2FsdCwgaW5mbzogSEtERl9JTkZPIH0sXG4gICAgaGtkZktleSxcbiAgICB7IG5hbWU6ICdBRVMtR0NNJywgbGVuZ3RoOiAyNTYgfSxcbiAgICBmYWxzZSxcbiAgICBbdXNhZ2VdXG4gICk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhZXNHY21FbmNyeXB0KGtleTogQ3J5cHRvS2V5LCBpdjogVWludDhBcnJheSwgcGxhaW50ZXh0OiBzdHJpbmcpOiBQcm9taXNlPFVpbnQ4QXJyYXk+IHtcbiAgY29uc3QgY3QgPSBhd2FpdCBjcnlwdG8uc3VidGxlLmVuY3J5cHQoXG4gICAgeyBuYW1lOiAnQUVTLUdDTScsIGl2LCB0YWdMZW5ndGg6IDEyOCB9LFxuICAgIGtleSxcbiAgICBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUocGxhaW50ZXh0KVxuICApO1xuICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoY3QpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYWVzR2NtRGVjcnlwdChrZXk6IENyeXB0b0tleSwgaXY6IFVpbnQ4QXJyYXksIGN0OiBVaW50OEFycmF5KTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgcGxhaW50ZXh0ID0gYXdhaXQgY3J5cHRvLnN1YnRsZS5kZWNyeXB0KHsgbmFtZTogJ0FFUy1HQ00nLCBpdiwgdGFnTGVuZ3RoOiAxMjggfSwga2V5LCBjdCk7XG4gIHJldHVybiBuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUocGxhaW50ZXh0KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlVjJFbnZlbG9wZShjaXBoZXJ0ZXh0OiBzdHJpbmcpOiBWMkVudmVsb3BlIHtcbiAgbGV0IHBhcnNlZDogdW5rbm93bjtcbiAgdHJ5IHtcbiAgICBwYXJzZWQgPSBKU09OLnBhcnNlKGNpcGhlcnRleHQpO1xuICB9IGNhdGNoIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3YyIGRlY3J5cHQ6IGludmFsaWQgSlNPTiBlbnZlbG9wZScpO1xuICB9XG4gIHJldHVybiBkZWNvZGVXaXRoQ29kZWMoVjJFbnZlbG9wZUNvZGVjLCBwYXJzZWQsICd2MiBkZWNyeXB0OiBpbnZhbGlkIGVudmVsb3BlJyk7XG59XG5cbi8vIFB1YmxpYyBBUElcblxuLyoqXG4gKiBFbmNyeXB0IHBsYWludGV4dCB1c2luZyBBcmdvbjJpZCBLREYgKyBBRVMtMjU2LUdDTS5cbiAqXG4gKiBSZXR1cm5zIGEgc2VsZi1kZXNjcmliaW5nIEpTT04gdjIgZW52ZWxvcGUgY29udGFpbmluZyBhbGwgQXJnb24yaWQgcGFyYW1ldGVycyxcbiAqIHNhbHQsIElWLCBhbmQgY2lwaGVydGV4dCAtLSBmdWxseSBzdGFuZGFsb25lIGZvciBkZWNyeXB0aW9uLlxuICpcbiAqIEZvciBtdWx0aS1jYWxsIG9wZXJhdGlvbnMgKE1QQyBzaWduaW5nLCB3YWxsZXQgY3JlYXRpb24pLCBwcmVmZXJcbiAqIGNyZWF0ZUVuY3J5cHRpb25TZXNzaW9uIHRvIHJ1biBBcmdvbjJpZCBvbmNlIGFuZCBkZXJpdmUgcGVyLWNhbGwga2V5cyB2aWEgSEtERi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGVuY3J5cHRWMihcbiAgcGFzc3dvcmQ6IHN0cmluZyxcbiAgcGxhaW50ZXh0OiBzdHJpbmcsXG4gIG9wdGlvbnM/OiB7IHNhbHQ/OiBVaW50OEFycmF5OyBpdj86IFVpbnQ4QXJyYXk7IG1lbW9yeVNpemU/OiBudW1iZXI7IGl0ZXJhdGlvbnM/OiBudW1iZXI7IHBhcmFsbGVsaXNtPzogbnVtYmVyIH1cbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IG1lbW9yeVNpemUgPSBvcHRpb25zPy5tZW1vcnlTaXplID8/IEFSR09OMl9ERUZBVUxUUy5tZW1vcnlTaXplO1xuICBjb25zdCBpdGVyYXRpb25zID0gb3B0aW9ucz8uaXRlcmF0aW9ucyA/PyBBUkdPTjJfREVGQVVMVFMuaXRlcmF0aW9ucztcbiAgY29uc3QgcGFyYWxsZWxpc20gPSBvcHRpb25zPy5wYXJhbGxlbGlzbSA/PyBBUkdPTjJfREVGQVVMVFMucGFyYWxsZWxpc207XG5cbiAgY29uc3Qgc2FsdCA9IG9wdGlvbnM/LnNhbHQgPz8gbmV3IFVpbnQ4QXJyYXkocmFuZG9tQnl0ZXMoQVJHT04yX0RFRkFVTFRTLnNhbHRMZW5ndGgpKTtcbiAgaWYgKHNhbHQubGVuZ3RoICE9PSBBUkdPTjJfREVGQVVMVFMuc2FsdExlbmd0aCkgdGhyb3cgbmV3IEVycm9yKGBzYWx0IG11c3QgYmUgJHtBUkdPTjJfREVGQVVMVFMuc2FsdExlbmd0aH0gYnl0ZXNgKTtcblxuICBjb25zdCBpdiA9IG9wdGlvbnM/Lml2ID8/IG5ldyBVaW50OEFycmF5KHJhbmRvbUJ5dGVzKEdDTV9JVl9MRU5HVEgpKTtcbiAgaWYgKGl2Lmxlbmd0aCAhPT0gR0NNX0lWX0xFTkdUSCkgdGhyb3cgbmV3IEVycm9yKGBpdiBtdXN0IGJlICR7R0NNX0lWX0xFTkdUSH0gYnl0ZXNgKTtcblxuICBjb25zdCBrZXkgPSBhd2FpdCBhcmdvbjJUb0Flc0tleShwYXNzd29yZCwgc2FsdCwgeyBtZW1vcnlTaXplLCBpdGVyYXRpb25zLCBwYXJhbGxlbGlzbSB9KTtcbiAgY29uc3QgY3QgPSBhd2FpdCBhZXNHY21FbmNyeXB0KGtleSwgaXYsIHBsYWludGV4dCk7XG5cbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHtcbiAgICB2OiAyLFxuICAgIG06IG1lbW9yeVNpemUsXG4gICAgdDogaXRlcmF0aW9ucyxcbiAgICBwOiBwYXJhbGxlbGlzbSxcbiAgICBzYWx0OiBCdWZmZXIuZnJvbShzYWx0KS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgaXY6IEJ1ZmZlci5mcm9tKGl2KS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgY3Q6IEJ1ZmZlci5mcm9tKGN0KS50b1N0cmluZygnYmFzZTY0JyksXG4gIH0gc2F0aXNmaWVzIFYyRW52ZWxvcGUpO1xufVxuXG4vKipcbiAqIERlY3J5cHQgYSB2MiBlbnZlbG9wZSAoQXJnb24yaWQgKyBBRVMtMjU2LUdDTSkuXG4gKlxuICogSGFuZGxlcyBib3RoIGVudmVsb3BlIHR5cGVzIGF1dG9tYXRpY2FsbHk6XG4gKiAgIC0gU3RhbmRhcmQgIChubyBoa2RmU2FsdCk6IEFyZ29uMmlkIC0+IEFFUy1HQ01cbiAqICAgLSBTZXNzaW9uICAgKGhrZGZTYWx0IHByZXNlbnQpOiBBcmdvbjJpZCAtPiBIS0RGIC0+IEFFUy1HQ01cbiAqXG4gKiBBbGwgcGFyYW1ldGVycyBhcmUgc3RvcmVkIGluIHRoZSBlbnZlbG9wZSAtLSBubyBzZXNzaW9uIGNvbnRleHQgcmVxdWlyZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWNyeXB0VjIocGFzc3dvcmQ6IHN0cmluZywgY2lwaGVydGV4dDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgZW52ZWxvcGUgPSBwYXJzZVYyRW52ZWxvcGUoY2lwaGVydGV4dCk7XG4gIGNvbnN0IHNhbHQgPSBuZXcgVWludDhBcnJheShCdWZmZXIuZnJvbShlbnZlbG9wZS5zYWx0LCAnYmFzZTY0JykpO1xuICBjb25zdCBpdiA9IG5ldyBVaW50OEFycmF5KEJ1ZmZlci5mcm9tKGVudmVsb3BlLml2LCAnYmFzZTY0JykpO1xuICBjb25zdCBjdCA9IG5ldyBVaW50OEFycmF5KEJ1ZmZlci5mcm9tKGVudmVsb3BlLmN0LCAnYmFzZTY0JykpO1xuICBjb25zdCBwYXJhbXMgPSB7IG1lbW9yeVNpemU6IGVudmVsb3BlLm0sIGl0ZXJhdGlvbnM6IGVudmVsb3BlLnQsIHBhcmFsbGVsaXNtOiBlbnZlbG9wZS5wIH07XG5cbiAgaWYgKGVudmVsb3BlLmhrZGZTYWx0KSB7XG4gICAgY29uc3QgaGtkZktleSA9IGF3YWl0IGFyZ29uMlRvSGtkZktleShwYXNzd29yZCwgc2FsdCwgcGFyYW1zKTtcbiAgICBjb25zdCBoa2RmU2FsdCA9IG5ldyBVaW50OEFycmF5KEJ1ZmZlci5mcm9tKGVudmVsb3BlLmhrZGZTYWx0LCAnYmFzZTY0JykpO1xuICAgIGNvbnN0IGFlc0tleSA9IGF3YWl0IGhrZGZEZXJpdmVBZXNLZXkoaGtkZktleSwgaGtkZlNhbHQsICdkZWNyeXB0Jyk7XG4gICAgcmV0dXJuIGFlc0djbURlY3J5cHQoYWVzS2V5LCBpdiwgY3QpO1xuICB9XG5cbiAgY29uc3Qga2V5ID0gYXdhaXQgYXJnb24yVG9BZXNLZXkocGFzc3dvcmQsIHNhbHQsIHBhcmFtcyk7XG4gIHJldHVybiBhZXNHY21EZWNyeXB0KGtleSwgaXYsIGN0KTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runs Argon2id once on creation, then derives per-call AES-256-GCM keys via HKDF.
|
|
3
|
+
* Use when encrypting or decrypting multiple values with the same password.
|
|
4
|
+
*
|
|
5
|
+
* Session envelopes are self-describing and can be decrypted standalone via decryptV2.
|
|
6
|
+
* Call destroy() when done to clear the cached key from memory.
|
|
7
|
+
*/
|
|
8
|
+
export declare class EncryptionSession {
|
|
9
|
+
private hkdfKey;
|
|
10
|
+
private argon2SaltB64;
|
|
11
|
+
private readonly memorySize;
|
|
12
|
+
private readonly iterations;
|
|
13
|
+
private readonly parallelism;
|
|
14
|
+
/** Use createEncryptionSession() instead of calling this directly. */
|
|
15
|
+
constructor(hkdfKey: CryptoKey, argon2SaltB64: string, params: {
|
|
16
|
+
memorySize: number;
|
|
17
|
+
iterations: number;
|
|
18
|
+
parallelism: number;
|
|
19
|
+
});
|
|
20
|
+
encrypt(plaintext: string): Promise<string>;
|
|
21
|
+
decrypt(ciphertext: string): Promise<string>;
|
|
22
|
+
destroy(): void;
|
|
23
|
+
private getKeyOrThrow;
|
|
24
|
+
private getSaltOrThrow;
|
|
25
|
+
private buildEnvelope;
|
|
26
|
+
}
|
|
27
|
+
/** Create an EncryptionSession. Runs Argon2id once; all subsequent calls derive keys via HKDF. */
|
|
28
|
+
export declare function createEncryptionSession(password: string, options?: {
|
|
29
|
+
memorySize?: number;
|
|
30
|
+
iterations?: number;
|
|
31
|
+
parallelism?: number;
|
|
32
|
+
salt?: Uint8Array;
|
|
33
|
+
}): Promise<EncryptionSession>;
|
|
34
|
+
//# sourceMappingURL=encryptionSession.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryptionSession.d.ts","sourceRoot":"","sources":["../../src/encryptionSession.ts"],"names":[],"mappings":"AAcA;;;;;;GAMG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,sEAAsE;gBAEpE,OAAO,EAAE,SAAS,EAClB,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE;IASnE,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAS3C,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAgBlD,OAAO,IAAI,IAAI;IAKf,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,cAAc;IAOtB,OAAO,CAAC,aAAa;CAYtB;AAED,kGAAkG;AAClG,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,UAAU,CAAA;CAAE,GAC9F,OAAO,CAAC,iBAAiB,CAAC,CAe5B"}
|