@bitgo-beta/sdk-api 1.10.1-beta.1712 → 1.10.1-beta.1714
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 +8 -8
- 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 +8 -8
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bitgo-beta/sdk-api",
|
|
3
|
-
"version": "1.10.1-beta.
|
|
3
|
+
"version": "1.10.1-beta.1714",
|
|
4
4
|
"description": "REST wrapper for BitGoJS",
|
|
5
5
|
"main": "./dist/src/index.js",
|
|
6
6
|
"types": "./dist/src/index.d.ts",
|
|
@@ -40,12 +40,12 @@
|
|
|
40
40
|
]
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@bitgo-beta/argon2": "0.0.1-beta.
|
|
44
|
-
"@bitgo-beta/sdk-core": "8.2.1-beta.
|
|
45
|
-
"@bitgo-beta/sdk-hmac": "1.0.1-beta.
|
|
46
|
-
"@bitgo-beta/sjcl": "1.0.2-beta.
|
|
47
|
-
"@bitgo-beta/unspents": "0.13.2-beta.
|
|
48
|
-
"@bitgo-beta/utxo-lib": "8.0.3-beta.
|
|
43
|
+
"@bitgo-beta/argon2": "0.0.1-beta.25",
|
|
44
|
+
"@bitgo-beta/sdk-core": "8.2.1-beta.1715",
|
|
45
|
+
"@bitgo-beta/sdk-hmac": "1.0.1-beta.1085",
|
|
46
|
+
"@bitgo-beta/sjcl": "1.0.2-beta.1957",
|
|
47
|
+
"@bitgo-beta/unspents": "0.13.2-beta.1716",
|
|
48
|
+
"@bitgo-beta/utxo-lib": "8.0.3-beta.1717",
|
|
49
49
|
"@types/superagent": "4.1.15",
|
|
50
50
|
"bitcoinjs-message": "npm:@bitgo-forks/bitcoinjs-message@1.0.0-master.3",
|
|
51
51
|
"debug": "3.1.0",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"resolutions": {
|
|
65
65
|
"degenerator": "5.0.0"
|
|
66
66
|
},
|
|
67
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "df5f8904f962e3af6a63dd36597d174930b549a2",
|
|
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-beta/sdk-core");
|
|
43
40
|
const sjcl = __importStar(require("@bitgo-beta/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-beta/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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jcnlwdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9lbmNyeXB0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBZ0RBLGtDQU1DO0FBRUQsMEJBd0NDO0FBRUQsMEJBRUM7QUFTRCxvQ0FlQztBQThCRCw4QkF5Q0M7QUFPRCw4QkF1QkM7QUFqT0QsbURBQWlGO0FBQ2pGLHVEQUF5QztBQUN6QyxtQ0FBcUM7QUFDckMseUNBQTJCO0FBRTNCOztHQUVHO0FBQ0gsTUFBTSxlQUFlLEdBQUc7SUFDdEIsVUFBVSxFQUFFLEtBQUssRUFBRSxnQkFBZ0I7SUFDbkMsVUFBVSxFQUFFLENBQUM7SUFDYixXQUFXLEVBQUUsQ0FBQztJQUNkLFVBQVUsRUFBRSxFQUFFLEVBQUUsY0FBYztJQUM5QixVQUFVLEVBQUUsRUFBRSxFQUFFLGVBQWU7Q0FDdkIsQ0FBQztBQUVYOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsR0FBRztJQUNqQixVQUFVLEVBQUUsTUFBTTtJQUNsQixVQUFVLEVBQUUsRUFBRTtJQUNkLFdBQVcsRUFBRSxFQUFFO0NBQ1AsQ0FBQztBQUVYLHFDQUFxQztBQUNyQyxNQUFNLGFBQWEsR0FBRyxFQUFFLENBQUM7QUFFekIsTUFBTSxlQUFlLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUM3QixDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDZixDQUFDLEVBQUUsSUFBQSxxQkFBVSxFQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsVUFBVSxFQUFFLFlBQVksQ0FBQztJQUNyRCxDQUFDLEVBQUUsSUFBQSxxQkFBVSxFQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsVUFBVSxFQUFFLFlBQVksQ0FBQztJQUNyRCxDQUFDLEVBQUUsSUFBQSxxQkFBVSxFQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsV0FBVyxFQUFFLGFBQWEsQ0FBQztJQUN2RCxJ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QUFDLENBQUM7S0FDeEIsQ0FBQyxDQUFDO0lBRUgsTUFBTSxlQUFlLEdBQUcsTUFBTSxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBRXRGLE9BQU8sSUFBSSxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7QUFDbkQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGJhc2U2NFN0cmluZywgYm91bmRlZEludCwgZGVjb2RlV2l0aENvZGVjIH0gZnJvbSAnQGJpdGdvLWJldGEvc2RrLWNvcmUnO1xuaW1wb3J0ICogYXMgc2pjbCBmcm9tICdAYml0Z28tYmV0YS9zamNsJztcbmltcG9ydCB7IHJhbmRvbUJ5dGVzIH0gZnJvbSAnY3J5cHRvJztcbmltcG9ydCAqIGFzIHQgZnJvbSAnaW8tdHMnO1xuXG4vKiogRGVmYXVsdCBBcmdvbjJpZCBwYXJhbWV0ZXJzIHBlciBSRkMgOTEwNiBzZWNvbmQgcmVjb21tZW5kYXRpb25cbiAqIEBzZWUgaHR0cHM6Ly93d3cucmZjLWVkaXRvci5vcmcvcmZjL3JmYzkxMDYjc2VjdGlvbi00XG4gKi9cbmNvbnN0IEFSR09OMl9ERUZBVUxUUyA9IHtcbiAgbWVtb3J5U2l6ZTogNjU1MzYsIC8vIDY0IE1pQiBpbiBLaUJcbiAgaXRlcmF0aW9uczogMyxcbiAgcGFyYWxsZWxpc206IDQsXG4gIGhhc2hMZW5ndGg6IDMyLCAvLyAyNTYtYml0IGtleVxuICBzYWx0TGVuZ3RoOiAxNiwgLy8gMTI4LWJpdCBzYWx0XG59IGFzIGNvbnN0O1xuXG4vKiogTWF4aW11bSBhbGxvd2VkIEFyZ29uMmlkIHBhcmFtZXRlcnMgdG8gcHJldmVudCBEb1MgdmlhIGNyYWZ0ZWQgZW52ZWxvcGVzLlxuICogbWVtb3J5U2l6ZTogMjU2IE1pQiAoNHggZGVmYXVsdCkgLS0gY2FwcyBtZW1vcnkgYWxsb2NhdGlvbiBvbiB1bnRydXN0ZWQgaW5wdXQuXG4gKiBpdGVyYXRpb25zOiAxNiAtLSBjYXBzIENQVSB0aW1lLlxuICogcGFyYWxsZWxpc206IDE2IC0tIGNhcHMgdGhyZWFkIGNvdW50LlxuICovXG5jb25zdCBBUkdPTjJfTUFYID0ge1xuICBtZW1vcnlTaXplOiAyNjIxNDQsXG4gIGl0ZXJhdGlvbnM6IDE2LFxuICBwYXJhbGxlbGlzbTogMTYsXG59IGFzIGNvbnN0O1xuXG4vKiogQUVTLTI1Ni1HQ00gSVYgbGVuZ3RoIGluIGJ5dGVzICovXG5jb25zdCBHQ01fSVZfTEVOR1RIID0gMTI7XG5cbmNvbnN0IFYyRW52ZWxvcGVDb2RlYyA9IHQudHlwZSh7XG4gIHY6IHQubGl0ZXJhbCgyKSxcbiAgbTogYm91bmRlZEludCgxLCBBUkdPTjJfTUFYLm1lbW9yeVNpemUsICdtZW1vcnlTaXplJyksXG4gIHQ6IGJvdW5kZWRJbnQoMSwgQVJHT04yX01BWC5pdGVyYXRpb25zLCAnaXRlcmF0aW9ucycpLFxuICBwOiBib3VuZGVkSW50KDEsIEFSR09OMl9NQVgucGFyYWxsZWxpc20sICdwYXJhbGxlbGlzbScpLFxuICBzYWx0OiBiYXNlNjRTdHJpbmcsXG4gIGl2OiBiYXNlNjRTdHJpbmcsXG4gIGN0OiBiYXNlNjRTdHJpbmcsXG59KTtcblxuZXhwb3J0IHR5cGUgVjJFbnZlbG9wZSA9IHQuVHlwZU9mPHR5cGVvZiBWMkVudmVsb3BlQ29kZWM+O1xuXG4vKipcbiAqIGNvbnZlcnQgYSA0IGVsZW1lbnQgVWludDhBcnJheSB0byBhIDQgYnl0ZSBOdW1iZXJcbiAqXG4gKiBAcGFyYW0gYnl0ZXNcbiAqIEByZXR1cm4gNCBieXRlIG51bWJlclxuICovXG5leHBvcnQgZnVuY3Rpb24gYnl0ZXNUb1dvcmQoYnl0ZXM/OiBVaW50OEFycmF5IHwgbnVtYmVyW10pOiBudW1iZXIge1xuICBpZiAoIShieXRlcyBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHx8IGJ5dGVzLmxlbmd0aCAhPT0gNCkge1xuICAgIHRocm93IG5ldyBFcnJvcignYnl0ZXMgbXVzdCBiZSBhIFVpbnQ4QXJyYXkgd2l0aCBsZW5ndGggNCcpO1xuICB9XG5cbiAgcmV0dXJuIGJ5dGVzLnJlZHVjZSgobnVtLCBieXRlKSA9PiBudW0gKiAweDEwMCArIGJ5dGUsIDApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZW5jcnlwdChcbiAgcGFzc3dvcmQ6IHN0cmluZyxcbiAgcGxhaW50ZXh0OiBzdHJpbmcsXG4gIG9wdGlvbnM/OiB7XG4gICAgc2FsdD86IEJ1ZmZlcjtcbiAgICBpdj86IEJ1ZmZlcjtcbiAgICBhZGF0YT86IHN0cmluZztcbiAgfVxuKTogc3RyaW5nIHtcbiAgY29uc3Qgc2FsdCA9IG9wdGlvbnM/LnNhbHQgfHwgcmFuZG9tQnl0ZXMoOCk7XG4gIGlmIChzYWx0Lmxlbmd0aCAhPT0gOCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgc2FsdCBtdXN0IGJlIDggYnl0ZXNgKTtcbiAgfVxuICBjb25zdCBpdiA9IG9wdGlvbnM/Lml2IHx8IHJhbmRvbUJ5dGVzKDE2KTtcbiAgaWYgKGl2Lmxlbmd0aCAhPT0gMTYpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGl2IG11c3QgYmUgMTYgYnl0ZXNgKTtcbiAgfVxuICBjb25zdCBlbmNyeXB0T3B0aW9uczoge1xuICAgIGl0ZXI6IG51bWJlcjtcbiAgICBrczogbnVtYmVyO1xuICAgIHNhbHQ6IG51bWJlcltdO1xuICAgIGl2OiBudW1iZXJbXTtcbiAgICBhZGF0YT86IHN0cmluZztcbiAgfSA9IHtcbiAgICBpdGVyOiAxMDAwMCxcbiAgICBrczogMjU2LFxuICAgIHNhbHQ6IFtieXRlc1RvV29yZChzYWx0LnNsaWNlKDAsIDQpKSwgYnl0ZXNUb1dvcmQoc2FsdC5zbGljZSg0KSldLFxuICAgIGl2OiBbXG4gICAgICBieXRlc1RvV29yZChpdi5zbGljZSgwLCA0KSksXG4gICAgICBieXRlc1RvV29yZChpdi5zbGljZSg0LCA4KSksXG4gICAgICBieXRlc1RvV29yZChpdi5zbGljZSg4LCAxMikpLFxuICAgICAgYnl0ZXNUb1dvcmQoaXYuc2xpY2UoMTIsIDE2KSksXG4gICAgXSxcbiAgfTtcblxuICBpZiAob3B0aW9ucz8uYWRhdGEpIHtcbiAgICBlbmNyeXB0T3B0aW9ucy5hZGF0YSA9IG9wdGlvbnMuYWRhdGE7XG4gIH1cblxuICByZXR1cm4gc2pjbC5lbmNyeXB0KHBhc3N3b3JkLCBwbGFpbnRleHQsIGVuY3J5cHRPcHRpb25zKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlY3J5cHQocGFzc3dvcmQ6IHN0cmluZywgY2lwaGVydGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHNqY2wuZGVjcnlwdChwYXNzd29yZCwgY2lwaGVydGV4dCk7XG59XG5cbi8qKlxuICogQXN5bmMgZGVjcnlwdCB0aGF0IGF1dG8tZGV0ZWN0cyB2MSAoU0pDTCkgb3IgdjIgKEFyZ29uMmlkICsgQUVTLTI1Ni1HQ00pXG4gKiBmcm9tIHRoZSBKU09OIGVudmVsb3BlJ3MgYHZgIGZpZWxkLlxuICpcbiAqIFRoaXMgaXMgdGhlIG1pZ3JhdGlvbiBwYXRoIGZyb20gc3luYyBgZGVjcnlwdCgpYC4gQ2xpZW50cyBzaG91bGQgbW92ZSB0b1xuICogYGF3YWl0IGRlY3J5cHRBc3luYygpYCBiZWZvcmUgdGhlIGJyZWFraW5nIHJlbGVhc2UgdGhhdCBtYWtlcyBgZGVjcnlwdCgpYCBhc3luYy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRlY3J5cHRBc3luYyhwYXNzd29yZDogc3RyaW5nLCBjaXBoZXJ0ZXh0OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICBsZXQgaXNWMiA9IGZhbHNlO1xuICB0cnkge1xuICAgIC8vIE9ubHkgcGVla2luZyBhdCB0aGUgdiBmaWVsZCB0byByb3V0ZTsgdGhpcyBpcyBhbiBpbnRlcm5hbCBmb3JtYXQgd2UgcHJvZHVjZSwgbm90IGV4dGVybmFsIGlucHV0LlxuICAgIGNvbnN0IGVudmVsb3BlID0gSlNPTi5wYXJzZShjaXBoZXJ0ZXh0KTtcbiAgICBpc1YyID0gZW52ZWxvcGUudiA9PT0gMjtcbiAgfSBjYXRjaCB7XG4gICAgLy8gTm90IHZhbGlkIEpTT04gLS0gZmFsbCB0aHJvdWdoIHRvIHYxXG4gIH1cbiAgaWYgKGlzVjIpIHtcbiAgICAvLyBEbyBub3QgY2F0Y2ggZXJyb3JzIGhlcmU6IGEgd3JvbmcgcGFzc3dvcmQgb3IgY29ycnVwdCBlbnZlbG9wZSBvbiB2MiBkYXRhXG4gICAgLy8gc2hvdWxkIHByb3BhZ2F0ZSwgbm90IHNpbGVudGx5IGZhbGwgdGhyb3VnaCB0byBhIHYxIGRlY3J5cHQgYXR0ZW1wdC5cbiAgICByZXR1cm4gZGVjcnlwdFYyKHBhc3N3b3JkLCBjaXBoZXJ0ZXh0KTtcbiAgfVxuICByZXR1cm4gc2pjbC5kZWNyeXB0KHBhc3N3b3JkLCBjaXBoZXJ0ZXh0KTtcbn1cblxuLyoqXG4gKiBEZXJpdmUgYSAyNTYtYml0IGtleSBmcm9tIGEgcGFzc3dvcmQgdXNpbmcgQXJnb24yaWQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGRlcml2ZUtleVYyKFxuICBwYXNzd29yZDogc3RyaW5nLFxuICBzYWx0OiBVaW50OEFycmF5LFxuICBwYXJhbXM6IHsgbWVtb3J5U2l6ZTogbnVtYmVyOyBpdGVyYXRpb25zOiBudW1iZXI7IHBhcmFsbGVsaXNtOiBudW1iZXIgfVxuKTogUHJvbWlzZTxDcnlwdG9LZXk+IHtcbiAgY29uc3QgeyBhcmdvbjJpZCB9ID0gYXdhaXQgaW1wb3J0KCdAYml0Z28tYmV0YS9hcmdvbjInKTtcbiAgY29uc3Qga2V5Qnl0ZXMgPSBhd2FpdCBhcmdvbjJpZCh7XG4gICAgcGFzc3dvcmQsXG4gICAgc2FsdCxcbiAgICBtZW1vcnlTaXplOiBwYXJhbXMubWVtb3J5U2l6ZSxcbiAgICBpdGVyYXRpb25zOiBwYXJhbXMuaXRlcmF0aW9ucyxcbiAgICBwYXJhbGxlbGlzbTogcGFyYW1zLnBhcmFsbGVsaXNtLFxuICAgIGhhc2hMZW5ndGg6IEFSR09OMl9ERUZBVUxUUy5oYXNoTGVuZ3RoLFxuICAgIG91dHB1dFR5cGU6ICdiaW5hcnknLFxuICB9KTtcblxuICByZXR1cm4gY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoJ3JhdycsIGtleUJ5dGVzLCB7IG5hbWU6ICdBRVMtR0NNJyB9LCBmYWxzZSwgWydlbmNyeXB0JywgJ2RlY3J5cHQnXSk7XG59XG5cbi8qKlxuICogRW5jcnlwdCBwbGFpbnRleHQgdXNpbmcgQXJnb24yaWQgS0RGICsgQUVTLTI1Ni1HQ00uXG4gKlxuICogUmV0dXJucyBhIEpTT04gc3RyaW5nIGNvbnRhaW5pbmcgYSBzZWxmLWRlc2NyaWJpbmcgdjIgZW52ZWxvcGVcbiAqIHdpdGggQXJnb24yaWQgcGFyYW1ldGVycywgc2FsdCwgSVYsIGFuZCBjaXBoZXJ0ZXh0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZW5jcnlwdFYyKFxuICBwYXNzd29yZDogc3RyaW5nLFxuICBwbGFpbnRleHQ6IHN0cmluZyxcbiAgb3B0aW9ucz86IHtcbiAgICBzYWx0PzogVWludDhBcnJheTtcbiAgICBpdj86IFVpbnQ4QXJyYXk7XG4gICAgbWVtb3J5U2l6ZT86IG51bWJlcjtcbiAgICBpdGVyYXRpb25zPzogbnVtYmVyO1xuICAgIHBhcmFsbGVsaXNtPzogbnVtYmVyO1xuICB9XG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCBtZW1vcnlTaXplID0gb3B0aW9ucz8ubWVtb3J5U2l6ZSA/PyBBUkdPTjJfREVGQVVMVFMubWVtb3J5U2l6ZTtcbiAgY29uc3QgaXRlcmF0aW9ucyA9IG9wdGlvbnM/Lml0ZXJhdGlvbnMgPz8gQVJHT04yX0RFRkFVTFRTLml0ZXJhdGlvbnM7XG4gIGNvbnN0IHBhcmFsbGVsaXNtID0gb3B0aW9ucz8ucGFyYWxsZWxpc20gPz8gQVJHT04yX0RFRkFVTFRTLnBhcmFsbGVsaXNtO1xuXG4gIGNvbnN0IHNhbHQgPSBvcHRpb25zPy5zYWx0ID8/IG5ldyBVaW50OEFycmF5KHJhbmRvbUJ5dGVzKEFSR09OMl9ERUZBVUxUUy5zYWx0TGVuZ3RoKSk7XG4gIGlmIChzYWx0Lmxlbmd0aCAhPT0gQVJHT04yX0RFRkFVTFRTLnNhbHRMZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYHNhbHQgbXVzdCBiZSAke0FSR09OMl9ERUZBVUxUUy5zYWx0TGVuZ3RofSBieXRlc2ApO1xuICB9XG5cbiAgY29uc3QgaXYgPSBvcHRpb25zPy5pdiA/PyBuZXcgVWludDhBcnJheShyYW5kb21CeXRlcyhHQ01fSVZfTEVOR1RIKSk7XG4gIGlmIChpdi5sZW5ndGggIT09IEdDTV9JVl9MRU5HVEgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGl2IG11c3QgYmUgJHtHQ01fSVZfTEVOR1RIfSBieXRlc2ApO1xuICB9XG5cbiAgY29uc3Qga2V5ID0gYXdhaXQgZGVyaXZlS2V5VjIocGFzc3dvcmQsIHNhbHQsIHsgbWVtb3J5U2l6ZSwgaXRlcmF0aW9ucywgcGFyYWxsZWxpc20gfSk7XG5cbiAgY29uc3QgcGxhaW50ZXh0Qnl0ZXMgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUocGxhaW50ZXh0KTtcbiAgY29uc3QgY3RCdWZmZXIgPSBhd2FpdCBjcnlwdG8uc3VidGxlLmVuY3J5cHQoeyBuYW1lOiAnQUVTLUdDTScsIGl2IH0sIGtleSwgcGxhaW50ZXh0Qnl0ZXMpO1xuXG4gIGNvbnN0IGVudmVsb3BlOiBWMkVudmVsb3BlID0ge1xuICAgIHY6IDIsXG4gICAgbTogbWVtb3J5U2l6ZSxcbiAgICB0OiBpdGVyYXRpb25zLFxuICAgIHA6IHBhcmFsbGVsaXNtLFxuICAgIHNhbHQ6IEJ1ZmZlci5mcm9tKHNhbHQpLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICBpdjogQnVmZmVyLmZyb20oaXYpLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICBjdDogQnVmZmVyLmZyb20oY3RCdWZmZXIpLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgfTtcblxuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoZW52ZWxvcGUpO1xufVxuXG4vKipcbiAqIERlY3J5cHQgYSB2MiBlbnZlbG9wZSAoQXJnb24yaWQgS0RGICsgQUVTLTI1Ni1HQ00pLlxuICpcbiAqIFRoZSBlbnZlbG9wZSBtdXN0IGNvbnRhaW46IHYsIG0sIHQsIHAsIHNhbHQsIGl2LCBjdC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRlY3J5cHRWMihwYXNzd29yZDogc3RyaW5nLCBjaXBoZXJ0ZXh0OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICBsZXQgcGFyc2VkOiB1bmtub3duO1xuICB0cnkge1xuICAgIHBhcnNlZCA9IEpTT04ucGFyc2UoY2lwaGVydGV4dCk7XG4gIH0gY2F0Y2gge1xuICAgIHRocm93IG5ldyBFcnJvcigndjIgZGVjcnlwdDogaW52YWxpZCBKU09OIGVudmVsb3BlJyk7XG4gIH1cblxuICBjb25zdCBlbnZlbG9wZSA9IGRlY29kZVdpdGhDb2RlYyhWMkVudmVsb3BlQ29kZWMsIHBhcnNlZCwgJ3YyIGRlY3J5cHQ6IGludmFsaWQgZW52ZWxvcGUnKTtcblxuICBjb25zdCBzYWx0ID0gbmV3IFVpbnQ4QXJyYXkoQnVmZmVyLmZyb20oZW52ZWxvcGUuc2FsdCwgJ2Jhc2U2NCcpKTtcbiAgY29uc3QgaXYgPSBuZXcgVWludDhBcnJheShCdWZmZXIuZnJvbShlbnZlbG9wZS5pdiwgJ2Jhc2U2NCcpKTtcbiAgY29uc3QgY3QgPSBuZXcgVWludDhBcnJheShCdWZmZXIuZnJvbShlbnZlbG9wZS5jdCwgJ2Jhc2U2NCcpKTtcblxuICBjb25zdCBrZXkgPSBhd2FpdCBkZXJpdmVLZXlWMihwYXNzd29yZCwgc2FsdCwge1xuICAgIG1lbW9yeVNpemU6IGVudmVsb3BlLm0sXG4gICAgaXRlcmF0aW9uczogZW52ZWxvcGUudCxcbiAgICBwYXJhbGxlbGlzbTogZW52ZWxvcGUucCxcbiAgfSk7XG5cbiAgY29uc3QgcGxhaW50ZXh0QnVmZmVyID0gYXdhaXQgY3J5cHRvLnN1YnRsZS5kZWNyeXB0KHsgbmFtZTogJ0FFUy1HQ00nLCBpdiB9LCBrZXksIGN0KTtcblxuICByZXR1cm4gbmV3IFRleHREZWNvZGVyKCkuZGVjb2RlKHBsYWludGV4dEJ1ZmZlcik7XG59XG4iXX0=
|
|
103
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jcnlwdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9lbmNyeXB0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBV0Esa0NBS0M7QUFHRCwwQkF1QkM7QUFHRCwwQkFFQztBQVFELG9DQWFDO0FBcEVELHVEQUF5QztBQUN6QyxtQ0FBcUM7QUFFckMsMkNBQXdDO0FBRXhDOzs7OztHQUtHO0FBQ0gsU0FBZ0IsV0FBVyxDQUFDLEtBQTZCO0lBQ3ZELElBQUksQ0FBQyxDQUFDLEtBQUssWUFBWSxVQUFVLENBQUMsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3pELE1BQU0sSUFBSSxLQUFLLENBQUMsMENBQTBDLENBQUMsQ0FBQztJQUM5RCxDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLEtBQUssR0FBRyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDNUQsQ0FBQztBQUVELGtFQUFrRTtBQUNsRSxTQUFnQixPQUFPLENBQ3JCLFFBQWdCLEVBQ2hCLFNBQWlCLEVBQ2pCLE9BQXdEO0lBRXhELE1BQU0sSUFBSSxHQUFHLE9BQU8sRUFBRSxJQUFJLElBQUksSUFBQSxvQkFBVyxFQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzdDLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO0lBQy9ELE1BQU0sRUFBRSxHQUFHLE9BQU8sRUFBRSxFQUFFLElBQUksSUFBQSxvQkFBVyxFQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzFDLElBQUksRUFBRSxDQUFDLE1BQU0sS0FBSyxFQUFFO1FBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO0lBRTdELE1BQU0sY0FBYyxHQUErRTtRQUNqRyxJQUFJLEVBQUUsS0FBSztRQUNYLEVBQUUsRUFBRSxHQUFHO1FBQ1AsSUFBSSxFQUFFLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNqRSxFQUFFLEVBQUU7WUFDRixXQUFXLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDM0IsV0FBVyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzNCLFdBQVcsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUM1QixXQUFXLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7U0FDOUI7S0FDRixDQUFDO0lBQ0YsSUFBSSxPQUFPLEVBQUUsS0FBSztRQUFFLGNBQWMsQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQztJQUN6RCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLFNBQVMsRUFBRSxjQUFjLENBQUMsQ0FBQztBQUMzRCxDQUFDO0FBRUQsa0NBQWtDO0FBQ2xDLFNBQWdCLE9BQU8sQ0FBQyxRQUFnQixFQUFFLFVBQWtCO0lBQzFELE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLENBQUM7QUFDNUMsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0ksS0FBSyxVQUFVLFlBQVksQ0FBQyxRQUFnQixFQUFFLFVBQWtCO0lBQ3JFLElBQUksSUFBSSxHQUFHLEtBQUssQ0FBQztJQUNqQixJQUFJLENBQUM7UUFDSCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3hDLElBQUksR0FBRyxRQUFRLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMxQixDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsTUFBTSxJQUFJLEtBQUssQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFDRCxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ1QsMkVBQTJFO1FBQzNFLE9BQU8sSUFBQSxxQkFBUyxFQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQztBQUM1QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgc2pjbCBmcm9tICdAYml0Z28tYmV0YS9zamNsJztcbmltcG9ydCB7IHJhbmRvbUJ5dGVzIH0gZnJvbSAnY3J5cHRvJztcblxuaW1wb3J0IHsgZGVjcnlwdFYyIH0gZnJvbSAnLi9lbmNyeXB0VjInO1xuXG4vKipcbiAqIGNvbnZlcnQgYSA0IGVsZW1lbnQgVWludDhBcnJheSB0byBhIDQgYnl0ZSBOdW1iZXJcbiAqXG4gKiBAcGFyYW0gYnl0ZXNcbiAqIEByZXR1cm4gNCBieXRlIG51bWJlclxuICovXG5leHBvcnQgZnVuY3Rpb24gYnl0ZXNUb1dvcmQoYnl0ZXM/OiBVaW50OEFycmF5IHwgbnVtYmVyW10pOiBudW1iZXIge1xuICBpZiAoIShieXRlcyBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHx8IGJ5dGVzLmxlbmd0aCAhPT0gNCkge1xuICAgIHRocm93IG5ldyBFcnJvcignYnl0ZXMgbXVzdCBiZSBhIFVpbnQ4QXJyYXkgd2l0aCBsZW5ndGggNCcpO1xuICB9XG4gIHJldHVybiBieXRlcy5yZWR1Y2UoKG51bSwgYnl0ZSkgPT4gbnVtICogMHgxMDAgKyBieXRlLCAwKTtcbn1cblxuLyoqIEVuY3J5cHQgdXNpbmcgbGVnYWN5IHYxIFNKQ0wgKFBCS0RGMi1TSEEyNTYgKyBBRVMtMjU2LUNDTSkuICovXG5leHBvcnQgZnVuY3Rpb24gZW5jcnlwdChcbiAgcGFzc3dvcmQ6IHN0cmluZyxcbiAgcGxhaW50ZXh0OiBzdHJpbmcsXG4gIG9wdGlvbnM/OiB7IHNhbHQ/OiBCdWZmZXI7IGl2PzogQnVmZmVyOyBhZGF0YT86IHN0cmluZyB9XG4pOiBzdHJpbmcge1xuICBjb25zdCBzYWx0ID0gb3B0aW9ucz8uc2FsdCB8fCByYW5kb21CeXRlcyg4KTtcbiAgaWYgKHNhbHQubGVuZ3RoICE9PSA4KSB0aHJvdyBuZXcgRXJyb3IoJ3NhbHQgbXVzdCBiZSA4IGJ5dGVzJyk7XG4gIGNvbnN0IGl2ID0gb3B0aW9ucz8uaXYgfHwgcmFuZG9tQnl0ZXMoMTYpO1xuICBpZiAoaXYubGVuZ3RoICE9PSAxNikgdGhyb3cgbmV3IEVycm9yKCdpdiBtdXN0IGJlIDE2IGJ5dGVzJyk7XG5cbiAgY29uc3QgZW5jcnlwdE9wdGlvbnM6IHsgaXRlcjogbnVtYmVyOyBrczogbnVtYmVyOyBzYWx0OiBudW1iZXJbXTsgaXY6IG51bWJlcltdOyBhZGF0YT86IHN0cmluZyB9ID0ge1xuICAgIGl0ZXI6IDEwMDAwLFxuICAgIGtzOiAyNTYsXG4gICAgc2FsdDogW2J5dGVzVG9Xb3JkKHNhbHQuc2xpY2UoMCwgNCkpLCBieXRlc1RvV29yZChzYWx0LnNsaWNlKDQpKV0sXG4gICAgaXY6IFtcbiAgICAgIGJ5dGVzVG9Xb3JkKGl2LnNsaWNlKDAsIDQpKSxcbiAgICAgIGJ5dGVzVG9Xb3JkKGl2LnNsaWNlKDQsIDgpKSxcbiAgICAgIGJ5dGVzVG9Xb3JkKGl2LnNsaWNlKDgsIDEyKSksXG4gICAgICBieXRlc1RvV29yZChpdi5zbGljZSgxMiwgMTYpKSxcbiAgICBdLFxuICB9O1xuICBpZiAob3B0aW9ucz8uYWRhdGEpIGVuY3J5cHRPcHRpb25zLmFkYXRhID0gb3B0aW9ucy5hZGF0YTtcbiAgcmV0dXJuIHNqY2wuZW5jcnlwdChwYXNzd29yZCwgcGxhaW50ZXh0LCBlbmNyeXB0T3B0aW9ucyk7XG59XG5cbi8qKiBEZWNyeXB0IGEgdjEgU0pDTCBlbnZlbG9wZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWNyeXB0KHBhc3N3b3JkOiBzdHJpbmcsIGNpcGhlcnRleHQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBzamNsLmRlY3J5cHQocGFzc3dvcmQsIGNpcGhlcnRleHQpO1xufVxuXG4vKipcbiAqIEF1dG8tZGV0ZWN0IHYxIChTSkNMKSBvciB2MiAoQXJnb24yaWQgKyBBRVMtMjU2LUdDTSkgZnJvbSB0aGUgZW52ZWxvcGUgYHZgIGZpZWxkIGFuZCBkZWNyeXB0LlxuICpcbiAqIE1pZ3JhdGlvbiBwYXRoIGZyb20gc3luYyBgZGVjcnlwdCgpYC4gTW92ZSBjYWxsIHNpdGVzIHRvIGBkZWNyeXB0QXN5bmMoKWAgYmVmb3JlXG4gKiB0aGUgYnJlYWtpbmcgcmVsZWFzZSB0aGF0IGZsaXBzIHRoZSBkZWZhdWx0IHRvIHYyLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVjcnlwdEFzeW5jKHBhc3N3b3JkOiBzdHJpbmcsIGNpcGhlcnRleHQ6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGxldCBpc1YyID0gZmFsc2U7XG4gIHRyeSB7XG4gICAgY29uc3QgZW52ZWxvcGUgPSBKU09OLnBhcnNlKGNpcGhlcnRleHQpO1xuICAgIGlzVjIgPSBlbnZlbG9wZS52ID09PSAyO1xuICB9IGNhdGNoIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2RlY3J5cHQ6IGNpcGhlcnRleHQgaXMgbm90IHZhbGlkIEpTT04nKTtcbiAgfVxuICBpZiAoaXNWMikge1xuICAgIC8vIERvIG5vdCBjYXRjaDogd3JvbmcgcGFzc3dvcmQgb24gdjIgbXVzdCBub3Qgc2lsZW50bHkgZmFsbCB0aHJvdWdoIHRvIHYxLlxuICAgIHJldHVybiBkZWNyeXB0VjIocGFzc3dvcmQsIGNpcGhlcnRleHQpO1xuICB9XG4gIHJldHVybiBzamNsLmRlY3J5cHQocGFzc3dvcmQsIGNpcGhlcnRleHQpO1xufVxuIl19
|
|
@@ -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-beta/argon2");
|
|
45
|
+
const sdk_core_1 = require("@bitgo-beta/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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jcnlwdFYyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2VuY3J5cHRWMi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFtRkEsMENBT0M7QUFFRCw0Q0FRQztBQUVELHNDQU9DO0FBRUQsc0NBR0M7QUFFRCwwQ0FRQztBQWFELDhCQTJCQztBQVdELDhCQWdCQztBQS9MRCwrQ0FBOEM7QUFDOUMsbURBQWlGO0FBQ2pGLG1DQUFxQztBQUNyQyx5Q0FBMkI7QUFFM0I7O0dBRUc7QUFDVSxRQUFBLGVBQWUsR0FBRztJQUM3QixVQUFVLEVBQUUsS0FBSyxFQUFFLGdCQUFnQjtJQUNuQyxVQUFVLEVBQUUsQ0FBQztJQUNiLFdBQVcsRUFBRSxDQUFDO0lBQ2QsVUFBVSxFQUFFLEVBQUUsRUFBRSxjQUFjO0lBQzlCLFVBQVUsRUFBRSxFQUFFLEVBQUUsZUFBZTtDQUN2QixDQUFDO0FBRVg7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxHQUFHO0lBQ2pCLFVBQVUsRUFBRSxNQUFNO0lBQ2xCLFVBQVUsRUFBRSxFQUFFO0lBQ2QsV0FBVyxFQUFFLEVBQUU7Q0FDUCxDQUFDO0FBRVgscUNBQXFDO0FBQ3hCLFFBQUEsYUFBYSxHQUFHLEVBQUUsQ0FBQztBQUVoQyx5Q0FBeUM7QUFDNUIsUUFBQSxnQkFBZ0IsR0FBRyxFQUFFLENBQUM7QUFFbkMsZ0ZBQWdGO0FBQ2hGLE1BQU0sU0FBUyxHQUFHLElBQUksV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLENBQUM7QUFFL0QsaUJBQWlCO0FBRWpCLE1BQU0sZUFBZSxHQUFHLENBQUMsQ0FBQyxZQUFZLENBQUM7SUFDckMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUNMLENBQUMsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUNmLENBQUMsRUFBRSxJQUFBLHFCQUFVLEVBQUMsQ0FBQyxFQUFFLFVB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LFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDbEUsTUFBTSxFQUFFLEdBQUcsSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDOUQsTUFBTSxFQUFFLEdBQUcsSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDOUQsTUFBTSxNQUFNLEdBQUcsRUFBRSxVQUFVLEVBQUUsUUFBUSxDQUFDLENBQUMsRUFBRSxVQUFVLEVBQUUsUUFBUSxDQUFDLENBQUMsRUFBRSxXQUFXLEVBQUUsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDO0lBRTNGLElBQUksUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ3RCLE1BQU0sT0FBTyxHQUFHLE1BQU0sZUFBZSxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDOUQsTUFBTSxRQUFRLEdBQUcsSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDMUUsTUFBTSxNQUFNLEdBQUcsTUFBTSxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3BFLE9BQU8sYUFBYSxDQUFDLE1BQU0sRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVELE1BQU0sR0FBRyxHQUFHLE1BQU0sY0FBYyxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDekQsT0FBTyxhQUFhLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNwQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgYXJnb24yaWQgfSBmcm9tICdAYml0Z28tYmV0YS9hcmdvbjInO1xuaW1wb3J0IHsgYmFzZTY0U3RyaW5nLCBib3VuZGVkSW50LCBkZWNvZGVXaXRoQ29kZWMgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyByYW5kb21CeXRlcyB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgKiBhcyB0IGZyb20gJ2lvLXRzJztcblxuLyoqIERlZmF1bHQgQXJnb24yaWQgcGFyYW1ldGVycyBwZXIgUkZDIDkxMDYgc2Vjb25kIHJlY29tbWVuZGF0aW9uXG4gKiBAc2VlIGh0dHBzOi8vd3d3LnJmYy1lZGl0b3Iub3JnL3JmYy9yZmM5MTA2I3NlY3Rpb24tNFxuICovXG5leHBvcnQgY29uc3QgQVJHT04yX0RFRkFVTFRTID0ge1xuICBtZW1vcnlTaXplOiA2NTUzNiwgLy8gNjQgTWlCIGluIEtpQlxuICBpdGVyYXRpb25zOiAzLFxuICBwYXJhbGxlbGlzbTogNCxcbiAgaGFzaExlbmd0aDogMzIsIC8vIDI1Ni1iaXQga2V5XG4gIHNhbHRMZW5ndGg6IDE2LCAvLyAxMjgtYml0IHNhbHRcbn0gYXMgY29uc3Q7XG5cbi8qKiBNYXhpbXVtIGFsbG93ZWQgQXJnb24yaWQgcGFyYW1ldGVycyB0byBwcmV2ZW50IERvUyB2aWEgY3JhZnRlZCBlbnZlbG9wZXMuXG4gKiBtZW1vcnlTaXplOiAyNTYgTWlCICg0eCBkZWZhdWx0KSAtLSBjYXBzIG1lbW9yeSBhbGxvY2F0aW9uIG9uIHVudHJ1c3RlZCBpbnB1dC5cbiAqIGl0ZXJhdGlvbnM6IDE2IC0tIGNhcHMgQ1BVIHRpbWUuXG4gKiBwYXJhbGxlbGlzbTogMTYgLS0gY2FwcyB0aHJlYWQgY291bnQuXG4gKi9cbmNvbnN0IEFSR09OMl9NQVggPSB7XG4gIG1lbW9yeVNpemU6IDI2MjE0NCxcbiAgaXRlcmF0aW9uczogMTYsXG4gIHBhcmFsbGVsaXNtOiAxNixcbn0gYXMgY29uc3Q7XG5cbi8qKiBBRVMtMjU2LUdDTSBJViBsZW5ndGggaW4gYnl0ZXMgKi9cbmV4cG9ydCBjb25zdCBHQ01fSVZfTEVOR1RIID0gMTI7XG5cbi8qKiBIS0RGIHBlci1jYWxsIHNhbHQgbGVuZ3RoIGluIGJ5dGVzICovXG5leHBvcnQgY29uc3QgSEtERl9TQUxUX0xFTkdUSCA9IDMyO1xuXG4vKiogRml4ZWQgSEtERiBpbmZvIHN0cmluZyBmb3IgZG9tYWluIHNlcGFyYXRpb24gYWNyb3NzIEJpdEdvIHYyIHNlc3Npb24ga2V5cyAqL1xuY29uc3QgSEtERl9JTkZPID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCdiaXRnby12Mi1zZXNzaW9uJyk7XG5cbi8vIEVudmVsb3BlIGNvZGVjXG5cbmNvbnN0IFYyRW52ZWxvcGVDb2RlYyA9IHQuaW50ZXJzZWN0aW9uKFtcbiAgdC50eXBlKHtcbiAgICB2OiB0LmxpdGVyYWwoMiksXG4gICAgbTogYm91bmRlZEludCgxLCBBUkdPTjJfTUFYLm1lbW9yeVNpemUsICdtZW1vcnlTaXplJyksXG4gICAgdDogYm91bmRlZEludCgxLCBBUkdPTjJfTUFYLml0ZXJhdGlvbnMsICdpdGVyYXRpb25zJyksXG4gICAgcDogYm91bmRlZEludCgxLCBBUkdPTjJfTUFYLnBhcmFsbGVsaXNtLCAncGFyYWxsZWxpc20nKSxcbiAgICBzYWx0OiBiYXNlNjRTdHJpbmcsXG4gICAgaXY6IGJhc2U2NFN0cmluZyxcbiAgICBjdDogYmFzZTY0U3RyaW5nLFxuICB9KSxcbiAgdC5wYXJ0aWFsKHtcbiAgICAvKiogQmFzZTY0LWVuY29kZWQgcGVyLWNhbGwgSEtERiBzYWx0IC0tIHByZXNlbnQgb25seSBpbiBzZXNzaW9uLXByb2R1Y2VkIGVudmVsb3BlcyAqL1xuICAgIGhrZGZTYWx0OiBiYXNlNjRTdHJpbmcsXG4gIH0pLFxuXSk7XG5cbmV4cG9ydCB0eXBlIFYyRW52ZWxvcGUgPSB0LlR5cGVPZjx0eXBlb2YgVjJFbnZlbG9wZUNvZGVjPjtcblxuLy8gQ3J5cHRvIGhlbHBlcnNcblxuYXN5bmMgZnVuY3Rpb24gYXJnb24ySGFzaChcbiAgcGFzc3dvcmQ6IHN0cmluZyxcbiAgc2FsdDogVWludDhBcnJheSxcbiAgcGFyYW1zOiB7IG1lbW9yeVNpemU6IG51bWJlcjsgaXRlcmF0aW9uczogbnVtYmVyOyBwYXJhbGxlbGlzbTogbnVtYmVyIH1cbik6IFByb21pc2U8VWludDhBcnJheT4ge1xuICByZXR1cm4gYXJnb24yaWQoe1xuICAgIHBhc3N3b3JkLFxuICAgIHNhbHQsXG4gICAgbWVtb3J5U2l6ZTogcGFyYW1zLm1lbW9yeVNpemUsXG4gICAgaXRlcmF0aW9uczogcGFyYW1zLml0ZXJhdGlvbnMsXG4gICAgcGFyYWxsZWxpc206IHBhcmFtcy5wYXJhbGxlbGlzbSxcbiAgICBoYXNoTGVuZ3RoOiBBUkdPTjJfREVGQVVMVFMuaGFzaExlbmd0aCxcbiAgICBvdXRwdXRUeXBlOiAnYmluYXJ5JyxcbiAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGFyZ29uMlRvQWVzS2V5KFxuICBwYXNzd29yZDogc3RyaW5nLFxuICBzYWx0OiBVaW50OEFycmF5LFxuICBwYXJhbXM6IHsgbWVtb3J5U2l6ZTogbnVtYmVyOyBpdGVyYXRpb25zOiBudW1iZXI7IHBhcmFsbGVsaXNtOiBudW1iZXIgfVxuKTogUHJvbWlzZTxDcnlwdG9LZXk+IHtcbiAgY29uc3Qga2V5Qnl0ZXMgPSBhd2FpdCBhcmdvbjJIYXNoKHBhc3N3b3JkLCBzYWx0LCBwYXJhbXMpO1xuICByZXR1cm4gY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoJ3JhdycsIGtleUJ5dGVzLCB7IG5hbWU6ICdBRVMtR0NNJyB9LCBmYWxzZSwgWydlbmNyeXB0JywgJ2RlY3J5cHQnXSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhcmdvbjJUb0hrZGZLZXkoXG4gIHBhc3N3b3JkOiBzdHJpbmcsXG4gIHNhbHQ6IFVpbnQ4QXJyYXksXG4gIHBhcmFtczogeyBtZW1vcnlTaXplOiBudW1iZXI7IGl0ZXJhdGlvbnM6IG51bWJlcjsgcGFyYWxsZWxpc206IG51bWJlciB9XG4pOiBQcm9taXNlPENyeXB0b0tleT4ge1xuICBjb25zdCBrZXlCeXRlcyA9IGF3YWl0IGFyZ29uMkhhc2gocGFzc3dvcmQsIHNhbHQsIHBhcmFtcyk7XG4gIHJldHVybiBjcnlwdG8uc3VidGxlLmltcG9ydEtleSgncmF3Jywga2V5Qnl0ZXMsICdIS0RGJywgZmFsc2UsIFsnZGVyaXZlS2V5J10pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGtkZkRlcml2ZUFlc0tleShoa2RmS2V5OiBDcnlwdG9LZXksIGhrZGZTYWx0OiBVaW50OEFycmF5LCB1c2FnZTogS2V5VXNhZ2UpOiBQcm9taXNlPENyeXB0b0tleT4ge1xuICByZXR1cm4gY3J5cHRvLnN1YnRsZS5kZXJpdmVLZXkoXG4gICAgeyBuYW1lOiAnSEtERicsIGhhc2g6ICdTSEEtMjU2Jywgc2FsdDogaGtkZlNhbHQsIGluZm86IEhLREZfSU5GTyB9LFxuICAgIGhrZGZLZXksXG4gICAgeyBuYW1lOiAnQUVTLUdDTScsIGxlbmd0aDogMjU2IH0sXG4gICAgZmFsc2UsXG4gICAgW3VzYWdlXVxuICApO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYWVzR2NtRW5jcnlwdChrZXk6IENyeXB0b0tleSwgaXY6IFVpbnQ4QXJyYXksIHBsYWludGV4dDogc3RyaW5nKTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gIGNvbnN0IGN0ID0gYXdhaXQgY3J5cHRvLnN1YnRsZS5lbmNyeXB0KFxuICAgIHsgbmFtZTogJ0FFUy1HQ00nLCBpdiwgdGFnTGVuZ3RoOiAxMjggfSxcbiAgICBrZXksXG4gICAgbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHBsYWludGV4dClcbiAgKTtcbiAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGN0KTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFlc0djbURlY3J5cHQoa2V5OiBDcnlwdG9LZXksIGl2OiBVaW50OEFycmF5LCBjdDogVWludDhBcnJheSk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IHBsYWludGV4dCA9IGF3YWl0IGNyeXB0by5zdWJ0bGUuZGVjcnlwdCh7IG5hbWU6ICdBRVMtR0NNJywgaXYsIHRhZ0xlbmd0aDogMTI4IH0sIGtleSwgY3QpO1xuICByZXR1cm4gbmV3IFRleHREZWNvZGVyKCkuZGVjb2RlKHBsYWludGV4dCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVYyRW52ZWxvcGUoY2lwaGVydGV4dDogc3RyaW5nKTogVjJFbnZlbG9wZSB7XG4gIGxldCBwYXJzZWQ6IHVua25vd247XG4gIHRyeSB7XG4gICAgcGFyc2VkID0gSlNPTi5wYXJzZShjaXBoZXJ0ZXh0KTtcbiAgfSBjYXRjaCB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd2MiBkZWNyeXB0OiBpbnZhbGlkIEpTT04gZW52ZWxvcGUnKTtcbiAgfVxuICByZXR1cm4gZGVjb2RlV2l0aENvZGVjKFYyRW52ZWxvcGVDb2RlYywgcGFyc2VkLCAndjIgZGVjcnlwdDogaW52YWxpZCBlbnZlbG9wZScpO1xufVxuXG4vLyBQdWJsaWMgQVBJXG5cbi8qKlxuICogRW5jcnlwdCBwbGFpbnRleHQgdXNpbmcgQXJnb24yaWQgS0RGICsgQUVTLTI1Ni1HQ00uXG4gKlxuICogUmV0dXJucyBhIHNlbGYtZGVzY3JpYmluZyBKU09OIHYyIGVudmVsb3BlIGNvbnRhaW5pbmcgYWxsIEFyZ29uMmlkIHBhcmFtZXRlcnMsXG4gKiBzYWx0LCBJViwgYW5kIGNpcGhlcnRleHQgLS0gZnVsbHkgc3RhbmRhbG9uZSBmb3IgZGVjcnlwdGlvbi5cbiAqXG4gKiBGb3IgbXVsdGktY2FsbCBvcGVyYXRpb25zIChNUEMgc2lnbmluZywgd2FsbGV0IGNyZWF0aW9uKSwgcHJlZmVyXG4gKiBjcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbiB0byBydW4gQXJnb24yaWQgb25jZSBhbmQgZGVyaXZlIHBlci1jYWxsIGtleXMgdmlhIEhLREYuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBlbmNyeXB0VjIoXG4gIHBhc3N3b3JkOiBzdHJpbmcsXG4gIHBsYWludGV4dDogc3RyaW5nLFxuICBvcHRpb25zPzogeyBzYWx0PzogVWludDhBcnJheTsgaXY/OiBVaW50OEFycmF5OyBtZW1vcnlTaXplPzogbnVtYmVyOyBpdGVyYXRpb25zPzogbnVtYmVyOyBwYXJhbGxlbGlzbT86IG51bWJlciB9XG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCBtZW1vcnlTaXplID0gb3B0aW9ucz8ubWVtb3J5U2l6ZSA/PyBBUkdPTjJfREVGQVVMVFMubWVtb3J5U2l6ZTtcbiAgY29uc3QgaXRlcmF0aW9ucyA9IG9wdGlvbnM/Lml0ZXJhdGlvbnMgPz8gQVJHT04yX0RFRkFVTFRTLml0ZXJhdGlvbnM7XG4gIGNvbnN0IHBhcmFsbGVsaXNtID0gb3B0aW9ucz8ucGFyYWxsZWxpc20gPz8gQVJHT04yX0RFRkFVTFRTLnBhcmFsbGVsaXNtO1xuXG4gIGNvbnN0IHNhbHQgPSBvcHRpb25zPy5zYWx0ID8/IG5ldyBVaW50OEFycmF5KHJhbmRvbUJ5dGVzKEFSR09OMl9ERUZBVUxUUy5zYWx0TGVuZ3RoKSk7XG4gIGlmIChzYWx0Lmxlbmd0aCAhPT0gQVJHT04yX0RFRkFVTFRTLnNhbHRMZW5ndGgpIHRocm93IG5ldyBFcnJvcihgc2FsdCBtdXN0IGJlICR7QVJHT04yX0RFRkFVTFRTLnNhbHRMZW5ndGh9IGJ5dGVzYCk7XG5cbiAgY29uc3QgaXYgPSBvcHRpb25zPy5pdiA/PyBuZXcgVWludDhBcnJheShyYW5kb21CeXRlcyhHQ01fSVZfTEVOR1RIKSk7XG4gIGlmIChpdi5sZW5ndGggIT09IEdDTV9JVl9MRU5HVEgpIHRocm93IG5ldyBFcnJvcihgaXYgbXVzdCBiZSAke0dDTV9JVl9MRU5HVEh9IGJ5dGVzYCk7XG5cbiAgY29uc3Qga2V5ID0gYXdhaXQgYXJnb24yVG9BZXNLZXkocGFzc3dvcmQsIHNhbHQsIHsgbWVtb3J5U2l6ZSwgaXRlcmF0aW9ucywgcGFyYWxsZWxpc20gfSk7XG4gIGNvbnN0IGN0ID0gYXdhaXQgYWVzR2NtRW5jcnlwdChrZXksIGl2LCBwbGFpbnRleHQpO1xuXG4gIHJldHVybiBKU09OLnN0cmluZ2lmeSh7XG4gICAgdjogMixcbiAgICBtOiBtZW1vcnlTaXplLFxuICAgIHQ6IGl0ZXJhdGlvbnMsXG4gICAgcDogcGFyYWxsZWxpc20sXG4gICAgc2FsdDogQnVmZmVyLmZyb20oc2FsdCkudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgIGl2OiBCdWZmZXIuZnJvbShpdikudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgIGN0OiBCdWZmZXIuZnJvbShjdCkudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICB9IHNhdGlzZmllcyBWMkVudmVsb3BlKTtcbn1cblxuLyoqXG4gKiBEZWNyeXB0IGEgdjIgZW52ZWxvcGUgKEFyZ29uMmlkICsgQUVTLTI1Ni1HQ00pLlxuICpcbiAqIEhhbmRsZXMgYm90aCBlbnZlbG9wZSB0eXBlcyBhdXRvbWF0aWNhbGx5OlxuICogICAtIFN0YW5kYXJkICAobm8gaGtkZlNhbHQpOiBBcmdvbjJpZCAtPiBBRVMtR0NNXG4gKiAgIC0gU2Vzc2lvbiAgIChoa2RmU2FsdCBwcmVzZW50KTogQXJnb24yaWQgLT4gSEtERiAtPiBBRVMtR0NNXG4gKlxuICogQWxsIHBhcmFtZXRlcnMgYXJlIHN0b3JlZCBpbiB0aGUgZW52ZWxvcGUgLS0gbm8gc2Vzc2lvbiBjb250ZXh0IHJlcXVpcmVkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVjcnlwdFYyKHBhc3N3b3JkOiBzdHJpbmcsIGNpcGhlcnRleHQ6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IGVudmVsb3BlID0gcGFyc2VWMkVudmVsb3BlKGNpcGhlcnRleHQpO1xuICBjb25zdCBzYWx0ID0gbmV3IFVpbnQ4QXJyYXkoQnVmZmVyLmZyb20oZW52ZWxvcGUuc2FsdCwgJ2Jhc2U2NCcpKTtcbiAgY29uc3QgaXYgPSBuZXcgVWludDhBcnJheShCdWZmZXIuZnJvbShlbnZlbG9wZS5pdiwgJ2Jhc2U2NCcpKTtcbiAgY29uc3QgY3QgPSBuZXcgVWludDhBcnJheShCdWZmZXIuZnJvbShlbnZlbG9wZS5jdCwgJ2Jhc2U2NCcpKTtcbiAgY29uc3QgcGFyYW1zID0geyBtZW1vcnlTaXplOiBlbnZlbG9wZS5tLCBpdGVyYXRpb25zOiBlbnZlbG9wZS50LCBwYXJhbGxlbGlzbTogZW52ZWxvcGUucCB9O1xuXG4gIGlmIChlbnZlbG9wZS5oa2RmU2FsdCkge1xuICAgIGNvbnN0IGhrZGZLZXkgPSBhd2FpdCBhcmdvbjJUb0hrZGZLZXkocGFzc3dvcmQsIHNhbHQsIHBhcmFtcyk7XG4gICAgY29uc3QgaGtkZlNhbHQgPSBuZXcgVWludDhBcnJheShCdWZmZXIuZnJvbShlbnZlbG9wZS5oa2RmU2FsdCwgJ2Jhc2U2NCcpKTtcbiAgICBjb25zdCBhZXNLZXkgPSBhd2FpdCBoa2RmRGVyaXZlQWVzS2V5KGhrZGZLZXksIGhrZGZTYWx0LCAnZGVjcnlwdCcpO1xuICAgIHJldHVybiBhZXNHY21EZWNyeXB0KGFlc0tleSwgaXYsIGN0KTtcbiAgfVxuXG4gIGNvbnN0IGtleSA9IGF3YWl0IGFyZ29uMlRvQWVzS2V5KHBhc3N3b3JkLCBzYWx0LCBwYXJhbXMpO1xuICByZXR1cm4gYWVzR2NtRGVjcnlwdChrZXksIGl2LCBjdCk7XG59XG4iXX0=
|