@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitgo-beta/sdk-api",
3
- "version": "1.10.1-beta.1712",
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.23",
44
- "@bitgo-beta/sdk-core": "8.2.1-beta.1713",
45
- "@bitgo-beta/sdk-hmac": "1.0.1-beta.1083",
46
- "@bitgo-beta/sjcl": "1.0.2-beta.1955",
47
- "@bitgo-beta/unspents": "0.13.2-beta.1714",
48
- "@bitgo-beta/utxo-lib": "8.0.3-beta.1715",
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": "d9071a58d4d244ae5bafa2a0fa020721570ec290",
67
+ "gitHead": "df5f8904f962e3af6a63dd36597d174930b549a2",
68
68
  "files": [
69
69
  "dist"
70
70
  ]
@@ -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
- * Async decrypt that auto-detects v1 (SJCL) or v2 (Argon2id + AES-256-GCM)
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
- * This is the migration path from sync `decrypt()`. Clients should move to
30
- * `await decryptAsync()` before the breaking release that makes `decrypt()` async.
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":"AAGA,OAAO,KAAK,CAAC,MAAM,OAAO,CAAC;AA2B3B,QAAA,MAAM,eAAe;;;;;;;;EAQnB,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,eAAe,CAAC,CAAC;AAE1D;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,EAAE,GAAG,MAAM,CAMjE;AAED,wBAAgB,OAAO,CACrB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;IACR,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GACA,MAAM,CAgCR;AAED,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAEpE;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAexF;AAwBD;;;;;GAKG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;IACR,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GACA,OAAO,CAAC,MAAM,CAAC,CA+BjB;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBrF"}
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"}
@@ -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 t = __importStar(require("io-ts"));
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(`salt must be 8 bytes`);
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(`iv must be 16 bytes`);
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
- * Async decrypt that auto-detects v1 (SJCL) or v2 (Argon2id + AES-256-GCM)
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
- * This is the migration path from sync `decrypt()`. Clients should move to
122
- * `await decryptAsync()` before the breaking release that makes `decrypt()` async.
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
- // Not valid JSON -- fall through to v1
95
+ throw new Error('decrypt: ciphertext is not valid JSON');
133
96
  }
134
97
  if (isV2) {
135
- // Do not catch errors here: a wrong password or corrupt envelope on v2 data
136
- // should propagate, not silently fall through to a v1 decrypt attempt.
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5jcnlwdFYyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2VuY3J5cHRWMi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFtRkEsMENBT0M7QUFFRCw0Q0FRQztBQUVELHNDQU9DO0FBRUQsc0NBR0M7QUFFRCwwQ0FRQztBQWFELDhCQTJCQztBQVdELDhCQWdCQztBQS9MRCwrQ0FBOEM7QUFDOUMsbURBQWlGO0FBQ2pGLG1DQUFxQztBQUNyQyx5Q0FBMkI7QUFFM0I7O0dBRUc7QUFDVSxRQUFBLGVBQWUsR0FBRztJQUM3QixVQUFVLEVBQUUsS0FBSyxFQUFFLGdCQUFnQjtJQUNuQyxVQUFVLEVBQUUsQ0FBQztJQUNiLFdBQVcsRUFBRSxDQUFDO0lBQ2QsVUFBVSxFQUFFLEVBQUUsRUFBRSxjQUFjO0lBQzlCLFVBQVUsRUFBRSxFQUFFLEVBQUUsZUFBZTtDQUN2QixDQUFDO0FBRVg7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxHQUFHO0lBQ2pCLFVBQVUsRUFBRSxNQUFNO0lBQ2xCLFVBQVUsRUFBRSxFQUFFO0lBQ2QsV0FBVyxFQUFFLEVBQUU7Q0FDUCxDQUFDO0FBRVgscUNBQXFDO0FBQ3hCLFFBQUEsYUFBYSxHQUFHLEVBQUUsQ0FBQztBQUVoQyx5Q0FBeUM7QUFDNUIsUUFBQSxnQkFBZ0IsR0FBRyxFQUFFLENBQUM7QUFFbkMsZ0ZBQWdGO0FBQ2hGLE1BQU0sU0FBUyxHQUFHLElBQUksV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDLGtCQUFrQixDQUFDLENBQUM7QUFFL0QsaUJBQWlCO0FBRWpCLE1BQU0sZUFBZSxHQUFHLENBQUMsQ0FBQyxZQUFZLENBQUM7SUFDckMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUNMLENBQUMsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUNmLENBQUMsRUFBRSxJQUFBLHFCQUFVLEVBQUMsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxVQUFVLEVBQUUsWUFBWSxDQUFDO1FBQ3JELENBQUMsRUFBRSxJQUFBLHFCQUFVLEVBQUMsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxVQUFVLEVBQUUsWUFBWSxDQUFDO1FBQ3JELENBQUMsRUFBRSxJQUFBLHFCQUFVLEVBQUMsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxXQUFXLEVBQUUsYUFBYSxDQUFDO1FBQ3ZELElBQUksRUFBRSx1QkFBWTtRQUNsQixFQUFFLEVBQUUsdUJBQVk7UUFDaEIsRUFBRSxFQUFFLHVCQUFZO0tBQ2pCLENBQUM7SUFDRixDQUFDLENBQUMsT0FBTyxDQUFDO1FBQ1Isc0ZBQXNGO1FBQ3RGLFFBQVEsRUFBRSx1QkFBWTtLQUN2QixDQUFDO0NBQ0gsQ0FBQyxDQUFDO0FBSUgsaUJBQWlCO0FBRWpCLEtBQUssVUFBVSxVQUFVLENBQ3ZCLFFBQWdCLEVBQ2hCLElBQWdCLEVBQ2hCLE1BQXVFO0lBRXZFLE9BQU8sSUFBQSxpQkFBUSxFQUFDO1FBQ2QsUUFBUTtRQUNSLElBQUk7UUFDSixVQUFVLEVBQUUsTUFBTSxDQUFDLFVBQVU7UUFDN0IsVUFBVSxFQUFFLE1BQU0sQ0FBQyxVQUFVO1FBQzdCLFdBQVcsRUFBRSxNQUFNLENBQUMsV0FBVztRQUMvQixVQUFVLEVBQUUsdUJBQWUsQ0FBQyxVQUFVO1FBQ3RDLFVBQVUsRUFBRSxRQUFRO0tBQ3JCLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRCxLQUFLLFVBQVUsY0FBYyxDQUMzQixRQUFnQixFQUNoQixJQUFnQixFQUNoQixNQUF1RTtJQUV2RSxNQUFNLFFBQVEsR0FBRyxNQUFNLFVBQVUsQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQzFELE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsRUFBRSxLQUFLLEVBQUUsQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQztBQUN0RyxDQUFDO0FBRU0sS0FBSyxVQUFVLGVBQWUsQ0FDbkMsUUFBZ0IsRUFDaEIsSUFBZ0IsRUFDaEIsTUFBdUU7SUFFdkUsTUFBTSxRQUFRLEdBQUcsTUFBTSxVQUFVLENBQUMsUUFBUSxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQztJQUMxRCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7QUFDaEYsQ0FBQztBQUVELFNBQWdCLGdCQUFnQixDQUFDLE9BQWtCLEVBQUUsUUFBb0IsRUFBRSxLQUFlO0lBQ3hGLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQzVCLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxFQUNsRSxPQUFPLEVBQ1AsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsRUFDaEMsS0FBSyxFQUNMLENBQUMsS0FBSyxDQUFDLENBQ1IsQ0FBQztBQUNKLENBQUM7QUFFTSxLQUFLLFVBQVUsYUFBYSxDQUFDLEdBQWMsRUFBRSxFQUFjLEVBQUUsU0FBaUI7SUFDbkYsTUFBTSxFQUFFLEdBQUcsTUFBTSxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FDcEMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLEVBQ3ZDLEdBQUcsRUFDSCxJQUFJLFdBQVcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FDcEMsQ0FBQztJQUNGLE9BQU8sSUFBSSxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDNUIsQ0FBQztBQUVNLEtBQUssVUFBVSxhQUFhLENBQUMsR0FBYyxFQUFFLEVBQWMsRUFBRSxFQUFjO0lBQ2hGLE1BQU0sU0FBUyxHQUFHLE1BQU0sTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ2hHLE9BQU8sSUFBSSxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDN0MsQ0FBQztBQUVELFNBQWdCLGVBQWUsQ0FBQyxVQUFrQjtJQUNoRCxJQUFJLE1BQWUsQ0FBQztJQUNwQixJQUFJLENBQUM7UUFDSCxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNsQyxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDO0lBQ3ZELENBQUM7SUFDRCxPQUFPLElBQUEsMEJBQWUsRUFBQyxlQUFlLEVBQUUsTUFBTSxFQUFFLDhCQUE4QixDQUFDLENBQUM7QUFDbEYsQ0FBQztBQUVELGFBQWE7QUFFYjs7Ozs7Ozs7R0FRRztBQUNJLEtBQUssVUFBVSxTQUFTLENBQzdCLFFBQWdCLEVBQ2hCLFNBQWlCLEVBQ2pCLE9BQWdIO0lBRWhILE1BQU0sVUFBVSxHQUFHLE9BQU8sRUFBRSxVQUFVLElBQUksdUJBQWUsQ0FBQyxVQUFVLENBQUM7SUFDckUsTUFBTSxVQUFVLEdBQUcsT0FBTyxFQUFFLFVBQVUsSUFBSSx1QkFBZSxDQUFDLFVBQVUsQ0FBQztJQUNyRSxNQUFNLFdBQVcsR0FBRyxPQUFPLEVBQUUsV0FBVyxJQUFJLHVCQUFlLENBQUMsV0FBVyxDQUFDO0lBRXhFLE1BQU0sSUFBSSxHQUFHLE9BQU8sRUFBRSxJQUFJLElBQUksSUFBSSxVQUFVLENBQUMsSUFBQSxvQkFBVyxFQUFDLHVCQUFlLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztJQUN0RixJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssdUJBQWUsQ0FBQyxVQUFVO1FBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxnQkFBZ0IsdUJBQWUsQ0FBQyxVQUFVLFFBQVEsQ0FBQyxDQUFDO0lBRXBILE1BQU0sRUFBRSxHQUFHLE9BQU8sRUFBRSxFQUFFLElBQUksSUFBSSxVQUFVLENBQUMsSUFBQSxvQkFBVyxFQUFDLHFCQUFhLENBQUMsQ0FBQyxDQUFDO0lBQ3JFLElBQUksRUFBRSxDQUFDLE1BQU0sS0FBSyxxQkFBYTtRQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsY0FBYyxxQkFBYSxRQUFRLENBQUMsQ0FBQztJQUV0RixNQUFNLEdBQUcsR0FBRyxNQUFNLGNBQWMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQzFGLE1BQU0sRUFBRSxHQUFHLE1BQU0sYUFBYSxDQUFDLEdBQUcsRUFBRSxFQUFFLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFFbkQsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO1FBQ3BCLENBQUMsRUFBRSxDQUFDO1FBQ0osQ0FBQyxFQUFFLFVBQVU7UUFDYixDQUFDLEVBQUUsVUFBVTtRQUNiLENBQUMsRUFBRSxXQUFXO1FBQ2QsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQztRQUMxQyxFQUFFLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDO1FBQ3RDLEVBQUUsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUM7S0FDbEIsQ0FBQyxDQUFDO0FBQzFCLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNJLEtBQUssVUFBVSxTQUFTLENBQUMsUUFBZ0IsRUFBRSxVQUFrQjtJQUNsRSxNQUFNLFFBQVEsR0FBRyxlQUFlLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDN0MsTUFBTSxJQUFJLEdBQUcsSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDbEUsTUFBTSxFQUFFLEdBQUcsSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDOUQsTUFBTSxFQUFFLEdBQUcsSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDOUQsTUFBTSxNQUFNLEdBQUcsRUFBRSxVQUFVLEVBQUUsUUFBUSxDQUFDLENBQUMsRUFBRSxVQUFVLEVBQUUsUUFBUSxDQUFDLENBQUMsRUFBRSxXQUFXLEVBQUUsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDO0lBRTNGLElBQUksUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ3RCLE1BQU0sT0FBTyxHQUFHLE1BQU0sZUFBZSxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDOUQsTUFBTSxRQUFRLEdBQUcsSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDMUUsTUFBTSxNQUFNLEdBQUcsTUFBTSxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3BFLE9BQU8sYUFBYSxDQUFDLE1BQU0sRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVELE1BQU0sR0FBRyxHQUFHLE1BQU0sY0FBYyxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDekQsT0FBTyxhQUFhLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNwQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgYXJnb24yaWQgfSBmcm9tICdAYml0Z28tYmV0YS9hcmdvbjInO1xuaW1wb3J0IHsgYmFzZTY0U3RyaW5nLCBib3VuZGVkSW50LCBkZWNvZGVXaXRoQ29kZWMgfSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyByYW5kb21CeXRlcyB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgKiBhcyB0IGZyb20gJ2lvLXRzJztcblxuLyoqIERlZmF1bHQgQXJnb24yaWQgcGFyYW1ldGVycyBwZXIgUkZDIDkxMDYgc2Vjb25kIHJlY29tbWVuZGF0aW9uXG4gKiBAc2VlIGh0dHBzOi8vd3d3LnJmYy1lZGl0b3Iub3JnL3JmYy9yZmM5MTA2I3NlY3Rpb24tNFxuICovXG5leHBvcnQgY29uc3QgQVJHT04yX0RFRkFVTFRTID0ge1xuICBtZW1vcnlTaXplOiA2NTUzNiwgLy8gNjQgTWlCIGluIEtpQlxuICBpdGVyYXRpb25zOiAzLFxuICBwYXJhbGxlbGlzbTogNCxcbiAgaGFzaExlbmd0aDogMzIsIC8vIDI1Ni1iaXQga2V5XG4gIHNhbHRMZW5ndGg6IDE2LCAvLyAxMjgtYml0IHNhbHRcbn0gYXMgY29uc3Q7XG5cbi8qKiBNYXhpbXVtIGFsbG93ZWQgQXJnb24yaWQgcGFyYW1ldGVycyB0byBwcmV2ZW50IERvUyB2aWEgY3JhZnRlZCBlbnZlbG9wZXMuXG4gKiBtZW1vcnlTaXplOiAyNTYgTWlCICg0eCBkZWZhdWx0KSAtLSBjYXBzIG1lbW9yeSBhbGxvY2F0aW9uIG9uIHVudHJ1c3RlZCBpbnB1dC5cbiAqIGl0ZXJhdGlvbnM6IDE2IC0tIGNhcHMgQ1BVIHRpbWUuXG4gKiBwYXJhbGxlbGlzbTogMTYgLS0gY2FwcyB0aHJlYWQgY291bnQuXG4gKi9cbmNvbnN0IEFSR09OMl9NQVggPSB7XG4gIG1lbW9yeVNpemU6IDI2MjE0NCxcbiAgaXRlcmF0aW9uczogMTYsXG4gIHBhcmFsbGVsaXNtOiAxNixcbn0gYXMgY29uc3Q7XG5cbi8qKiBBRVMtMjU2LUdDTSBJViBsZW5ndGggaW4gYnl0ZXMgKi9cbmV4cG9ydCBjb25zdCBHQ01fSVZfTEVOR1RIID0gMTI7XG5cbi8qKiBIS0RGIHBlci1jYWxsIHNhbHQgbGVuZ3RoIGluIGJ5dGVzICovXG5leHBvcnQgY29uc3QgSEtERl9TQUxUX0xFTkdUSCA9IDMyO1xuXG4vKiogRml4ZWQgSEtERiBpbmZvIHN0cmluZyBmb3IgZG9tYWluIHNlcGFyYXRpb24gYWNyb3NzIEJpdEdvIHYyIHNlc3Npb24ga2V5cyAqL1xuY29uc3QgSEtERl9JTkZPID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCdiaXRnby12Mi1zZXNzaW9uJyk7XG5cbi8vIEVudmVsb3BlIGNvZGVjXG5cbmNvbnN0IFYyRW52ZWxvcGVDb2RlYyA9IHQuaW50ZXJzZWN0aW9uKFtcbiAgdC50eXBlKHtcbiAgICB2OiB0LmxpdGVyYWwoMiksXG4gICAgbTogYm91bmRlZEludCgxLCBBUkdPTjJfTUFYLm1lbW9yeVNpemUsICdtZW1vcnlTaXplJyksXG4gICAgdDogYm91bmRlZEludCgxLCBBUkdPTjJfTUFYLml0ZXJhdGlvbnMsICdpdGVyYXRpb25zJyksXG4gICAgcDogYm91bmRlZEludCgxLCBBUkdPTjJfTUFYLnBhcmFsbGVsaXNtLCAncGFyYWxsZWxpc20nKSxcbiAgICBzYWx0OiBiYXNlNjRTdHJpbmcsXG4gICAgaXY6IGJhc2U2NFN0cmluZyxcbiAgICBjdDogYmFzZTY0U3RyaW5nLFxuICB9KSxcbiAgdC5wYXJ0aWFsKHtcbiAgICAvKiogQmFzZTY0LWVuY29kZWQgcGVyLWNhbGwgSEtERiBzYWx0IC0tIHByZXNlbnQgb25seSBpbiBzZXNzaW9uLXByb2R1Y2VkIGVudmVsb3BlcyAqL1xuICAgIGhrZGZTYWx0OiBiYXNlNjRTdHJpbmcsXG4gIH0pLFxuXSk7XG5cbmV4cG9ydCB0eXBlIFYyRW52ZWxvcGUgPSB0LlR5cGVPZjx0eXBlb2YgVjJFbnZlbG9wZUNvZGVjPjtcblxuLy8gQ3J5cHRvIGhlbHBlcnNcblxuYXN5bmMgZnVuY3Rpb24gYXJnb24ySGFzaChcbiAgcGFzc3dvcmQ6IHN0cmluZyxcbiAgc2FsdDogVWludDhBcnJheSxcbiAgcGFyYW1zOiB7IG1lbW9yeVNpemU6IG51bWJlcjsgaXRlcmF0aW9uczogbnVtYmVyOyBwYXJhbGxlbGlzbTogbnVtYmVyIH1cbik6IFByb21pc2U8VWludDhBcnJheT4ge1xuICByZXR1cm4gYXJnb24yaWQoe1xuICAgIHBhc3N3b3JkLFxuICAgIHNhbHQsXG4gICAgbWVtb3J5U2l6ZTogcGFyYW1zLm1lbW9yeVNpemUsXG4gICAgaXRlcmF0aW9uczogcGFyYW1zLml0ZXJhdGlvbnMsXG4gICAgcGFyYWxsZWxpc206IHBhcmFtcy5wYXJhbGxlbGlzbSxcbiAgICBoYXNoTGVuZ3RoOiBBUkdPTjJfREVGQVVMVFMuaGFzaExlbmd0aCxcbiAgICBvdXRwdXRUeXBlOiAnYmluYXJ5JyxcbiAgfSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGFyZ29uMlRvQWVzS2V5KFxuICBwYXNzd29yZDogc3RyaW5nLFxuICBzYWx0OiBVaW50OEFycmF5LFxuICBwYXJhbXM6IHsgbWVtb3J5U2l6ZTogbnVtYmVyOyBpdGVyYXRpb25zOiBudW1iZXI7IHBhcmFsbGVsaXNtOiBudW1iZXIgfVxuKTogUHJvbWlzZTxDcnlwdG9LZXk+IHtcbiAgY29uc3Qga2V5Qnl0ZXMgPSBhd2FpdCBhcmdvbjJIYXNoKHBhc3N3b3JkLCBzYWx0LCBwYXJhbXMpO1xuICByZXR1cm4gY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoJ3JhdycsIGtleUJ5dGVzLCB7IG5hbWU6ICdBRVMtR0NNJyB9LCBmYWxzZSwgWydlbmNyeXB0JywgJ2RlY3J5cHQnXSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhcmdvbjJUb0hrZGZLZXkoXG4gIHBhc3N3b3JkOiBzdHJpbmcsXG4gIHNhbHQ6IFVpbnQ4QXJyYXksXG4gIHBhcmFtczogeyBtZW1vcnlTaXplOiBudW1iZXI7IGl0ZXJhdGlvbnM6IG51bWJlcjsgcGFyYWxsZWxpc206IG51bWJlciB9XG4pOiBQcm9taXNlPENyeXB0b0tleT4ge1xuICBjb25zdCBrZXlCeXRlcyA9IGF3YWl0IGFyZ29uMkhhc2gocGFzc3dvcmQsIHNhbHQsIHBhcmFtcyk7XG4gIHJldHVybiBjcnlwdG8uc3VidGxlLmltcG9ydEtleSgncmF3Jywga2V5Qnl0ZXMsICdIS0RGJywgZmFsc2UsIFsnZGVyaXZlS2V5J10pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGtkZkRlcml2ZUFlc0tleShoa2RmS2V5OiBDcnlwdG9LZXksIGhrZGZTYWx0OiBVaW50OEFycmF5LCB1c2FnZTogS2V5VXNhZ2UpOiBQcm9taXNlPENyeXB0b0tleT4ge1xuICByZXR1cm4gY3J5cHRvLnN1YnRsZS5kZXJpdmVLZXkoXG4gICAgeyBuYW1lOiAnSEtERicsIGhhc2g6ICdTSEEtMjU2Jywgc2FsdDogaGtkZlNhbHQsIGluZm86IEhLREZfSU5GTyB9LFxuICAgIGhrZGZLZXksXG4gICAgeyBuYW1lOiAnQUVTLUdDTScsIGxlbmd0aDogMjU2IH0sXG4gICAgZmFsc2UsXG4gICAgW3VzYWdlXVxuICApO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYWVzR2NtRW5jcnlwdChrZXk6IENyeXB0b0tleSwgaXY6IFVpbnQ4QXJyYXksIHBsYWludGV4dDogc3RyaW5nKTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gIGNvbnN0IGN0ID0gYXdhaXQgY3J5cHRvLnN1YnRsZS5lbmNyeXB0KFxuICAgIHsgbmFtZTogJ0FFUy1HQ00nLCBpdiwgdGFnTGVuZ3RoOiAxMjggfSxcbiAgICBrZXksXG4gICAgbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHBsYWludGV4dClcbiAgKTtcbiAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGN0KTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFlc0djbURlY3J5cHQoa2V5OiBDcnlwdG9LZXksIGl2OiBVaW50OEFycmF5LCBjdDogVWludDhBcnJheSk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IHBsYWludGV4dCA9IGF3YWl0IGNyeXB0by5zdWJ0bGUuZGVjcnlwdCh7IG5hbWU6ICdBRVMtR0NNJywgaXYsIHRhZ0xlbmd0aDogMTI4IH0sIGtleSwgY3QpO1xuICByZXR1cm4gbmV3IFRleHREZWNvZGVyKCkuZGVjb2RlKHBsYWludGV4dCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVYyRW52ZWxvcGUoY2lwaGVydGV4dDogc3RyaW5nKTogVjJFbnZlbG9wZSB7XG4gIGxldCBwYXJzZWQ6IHVua25vd247XG4gIHRyeSB7XG4gICAgcGFyc2VkID0gSlNPTi5wYXJzZShjaXBoZXJ0ZXh0KTtcbiAgfSBjYXRjaCB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd2MiBkZWNyeXB0OiBpbnZhbGlkIEpTT04gZW52ZWxvcGUnKTtcbiAgfVxuICByZXR1cm4gZGVjb2RlV2l0aENvZGVjKFYyRW52ZWxvcGVDb2RlYywgcGFyc2VkLCAndjIgZGVjcnlwdDogaW52YWxpZCBlbnZlbG9wZScpO1xufVxuXG4vLyBQdWJsaWMgQVBJXG5cbi8qKlxuICogRW5jcnlwdCBwbGFpbnRleHQgdXNpbmcgQXJnb24yaWQgS0RGICsgQUVTLTI1Ni1HQ00uXG4gKlxuICogUmV0dXJucyBhIHNlbGYtZGVzY3JpYmluZyBKU09OIHYyIGVudmVsb3BlIGNvbnRhaW5pbmcgYWxsIEFyZ29uMmlkIHBhcmFtZXRlcnMsXG4gKiBzYWx0LCBJViwgYW5kIGNpcGhlcnRleHQgLS0gZnVsbHkgc3RhbmRhbG9uZSBmb3IgZGVjcnlwdGlvbi5cbiAqXG4gKiBGb3IgbXVsdGktY2FsbCBvcGVyYXRpb25zIChNUEMgc2lnbmluZywgd2FsbGV0IGNyZWF0aW9uKSwgcHJlZmVyXG4gKiBjcmVhdGVFbmNyeXB0aW9uU2Vzc2lvbiB0byBydW4gQXJnb24yaWQgb25jZSBhbmQgZGVyaXZlIHBlci1jYWxsIGtleXMgdmlhIEhLREYuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBlbmNyeXB0VjIoXG4gIHBhc3N3b3JkOiBzdHJpbmcsXG4gIHBsYWludGV4dDogc3RyaW5nLFxuICBvcHRpb25zPzogeyBzYWx0PzogVWludDhBcnJheTsgaXY/OiBVaW50OEFycmF5OyBtZW1vcnlTaXplPzogbnVtYmVyOyBpdGVyYXRpb25zPzogbnVtYmVyOyBwYXJhbGxlbGlzbT86IG51bWJlciB9XG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCBtZW1vcnlTaXplID0gb3B0aW9ucz8ubWVtb3J5U2l6ZSA/PyBBUkdPTjJfREVGQVVMVFMubWVtb3J5U2l6ZTtcbiAgY29uc3QgaXRlcmF0aW9ucyA9IG9wdGlvbnM/Lml0ZXJhdGlvbnMgPz8gQVJHT04yX0RFRkFVTFRTLml0ZXJhdGlvbnM7XG4gIGNvbnN0IHBhcmFsbGVsaXNtID0gb3B0aW9ucz8ucGFyYWxsZWxpc20gPz8gQVJHT04yX0RFRkFVTFRTLnBhcmFsbGVsaXNtO1xuXG4gIGNvbnN0IHNhbHQgPSBvcHRpb25zPy5zYWx0ID8/IG5ldyBVaW50OEFycmF5KHJhbmRvbUJ5dGVzKEFSR09OMl9ERUZBVUxUUy5zYWx0TGVuZ3RoKSk7XG4gIGlmIChzYWx0Lmxlbmd0aCAhPT0gQVJHT04yX0RFRkFVTFRTLnNhbHRMZW5ndGgpIHRocm93IG5ldyBFcnJvcihgc2FsdCBtdXN0IGJlICR7QVJHT04yX0RFRkFVTFRTLnNhbHRMZW5ndGh9IGJ5dGVzYCk7XG5cbiAgY29uc3QgaXYgPSBvcHRpb25zPy5pdiA/PyBuZXcgVWludDhBcnJheShyYW5kb21CeXRlcyhHQ01fSVZfTEVOR1RIKSk7XG4gIGlmIChpdi5sZW5ndGggIT09IEdDTV9JVl9MRU5HVEgpIHRocm93IG5ldyBFcnJvcihgaXYgbXVzdCBiZSAke0dDTV9JVl9MRU5HVEh9IGJ5dGVzYCk7XG5cbiAgY29uc3Qga2V5ID0gYXdhaXQgYXJnb24yVG9BZXNLZXkocGFzc3dvcmQsIHNhbHQsIHsgbWVtb3J5U2l6ZSwgaXRlcmF0aW9ucywgcGFyYWxsZWxpc20gfSk7XG4gIGNvbnN0IGN0ID0gYXdhaXQgYWVzR2NtRW5jcnlwdChrZXksIGl2LCBwbGFpbnRleHQpO1xuXG4gIHJldHVybiBKU09OLnN0cmluZ2lmeSh7XG4gICAgdjogMixcbiAgICBtOiBtZW1vcnlTaXplLFxuICAgIHQ6IGl0ZXJhdGlvbnMsXG4gICAgcDogcGFyYWxsZWxpc20sXG4gICAgc2FsdDogQnVmZmVyLmZyb20oc2FsdCkudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgIGl2OiBCdWZmZXIuZnJvbShpdikudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgIGN0OiBCdWZmZXIuZnJvbShjdCkudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICB9IHNhdGlzZmllcyBWMkVudmVsb3BlKTtcbn1cblxuLyoqXG4gKiBEZWNyeXB0IGEgdjIgZW52ZWxvcGUgKEFyZ29uMmlkICsgQUVTLTI1Ni1HQ00pLlxuICpcbiAqIEhhbmRsZXMgYm90aCBlbnZlbG9wZSB0eXBlcyBhdXRvbWF0aWNhbGx5OlxuICogICAtIFN0YW5kYXJkICAobm8gaGtkZlNhbHQpOiBBcmdvbjJpZCAtPiBBRVMtR0NNXG4gKiAgIC0gU2Vzc2lvbiAgIChoa2RmU2FsdCBwcmVzZW50KTogQXJnb24yaWQgLT4gSEtERiAtPiBBRVMtR0NNXG4gKlxuICogQWxsIHBhcmFtZXRlcnMgYXJlIHN0b3JlZCBpbiB0aGUgZW52ZWxvcGUgLS0gbm8gc2Vzc2lvbiBjb250ZXh0IHJlcXVpcmVkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVjcnlwdFYyKHBhc3N3b3JkOiBzdHJpbmcsIGNpcGhlcnRleHQ6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IGVudmVsb3BlID0gcGFyc2VWMkVudmVsb3BlKGNpcGhlcnRleHQpO1xuICBjb25zdCBzYWx0ID0gbmV3IFVpbnQ4QXJyYXkoQnVmZmVyLmZyb20oZW52ZWxvcGUuc2FsdCwgJ2Jhc2U2NCcpKTtcbiAgY29uc3QgaXYgPSBuZXcgVWludDhBcnJheShCdWZmZXIuZnJvbShlbnZlbG9wZS5pdiwgJ2Jhc2U2NCcpKTtcbiAgY29uc3QgY3QgPSBuZXcgVWludDhBcnJheShCdWZmZXIuZnJvbShlbnZlbG9wZS5jdCwgJ2Jhc2U2NCcpKTtcbiAgY29uc3QgcGFyYW1zID0geyBtZW1vcnlTaXplOiBlbnZlbG9wZS5tLCBpdGVyYXRpb25zOiBlbnZlbG9wZS50LCBwYXJhbGxlbGlzbTogZW52ZWxvcGUucCB9O1xuXG4gIGlmIChlbnZlbG9wZS5oa2RmU2FsdCkge1xuICAgIGNvbnN0IGhrZGZLZXkgPSBhd2FpdCBhcmdvbjJUb0hrZGZLZXkocGFzc3dvcmQsIHNhbHQsIHBhcmFtcyk7XG4gICAgY29uc3QgaGtkZlNhbHQgPSBuZXcgVWludDhBcnJheShCdWZmZXIuZnJvbShlbnZlbG9wZS5oa2RmU2FsdCwgJ2Jhc2U2NCcpKTtcbiAgICBjb25zdCBhZXNLZXkgPSBhd2FpdCBoa2RmRGVyaXZlQWVzS2V5KGhrZGZLZXksIGhrZGZTYWx0LCAnZGVjcnlwdCcpO1xuICAgIHJldHVybiBhZXNHY21EZWNyeXB0KGFlc0tleSwgaXYsIGN0KTtcbiAgfVxuXG4gIGNvbnN0IGtleSA9IGF3YWl0IGFyZ29uMlRvQWVzS2V5KHBhc3N3b3JkLCBzYWx0LCBwYXJhbXMpO1xuICByZXR1cm4gYWVzR2NtRGVjcnlwdChrZXksIGl2LCBjdCk7XG59XG4iXX0=