@bitgo/sdk-core 38.13.0 → 38.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/dist/src/api/types.d.ts +6 -0
  2. package/dist/src/api/types.d.ts.map +1 -1
  3. package/dist/src/api/types.js +8 -1
  4. package/dist/src/bitgo/baseCoin/iBaseCoin.d.ts +17 -7
  5. package/dist/src/bitgo/baseCoin/iBaseCoin.d.ts.map +1 -1
  6. package/dist/src/bitgo/baseCoin/iBaseCoin.js +1 -1
  7. package/dist/src/bitgo/defi/defiVault.d.ts +42 -8
  8. package/dist/src/bitgo/defi/defiVault.d.ts.map +1 -1
  9. package/dist/src/bitgo/defi/defiVault.js +76 -10
  10. package/dist/src/bitgo/defi/iDefiVault.d.ts +22 -2
  11. package/dist/src/bitgo/defi/iDefiVault.d.ts.map +1 -1
  12. package/dist/src/bitgo/defi/iDefiVault.js +1 -1
  13. package/dist/src/bitgo/environments.js +3 -3
  14. package/dist/src/bitgo/internal/keycard.d.ts +2 -1
  15. package/dist/src/bitgo/internal/keycard.d.ts.map +1 -1
  16. package/dist/src/bitgo/internal/keycard.js +6 -3
  17. package/dist/src/bitgo/keychain/iKeychains.d.ts +6 -2
  18. package/dist/src/bitgo/keychain/iKeychains.d.ts.map +1 -1
  19. package/dist/src/bitgo/keychain/iKeychains.js +1 -1
  20. package/dist/src/bitgo/keychain/keychains.d.ts.map +1 -1
  21. package/dist/src/bitgo/keychain/keychains.js +24 -10
  22. package/dist/src/bitgo/safe/iSafe.d.ts +5 -2
  23. package/dist/src/bitgo/safe/iSafe.d.ts.map +1 -1
  24. package/dist/src/bitgo/safe/iSafe.js +1 -1
  25. package/dist/src/bitgo/safe/safe.d.ts +14 -7
  26. package/dist/src/bitgo/safe/safe.d.ts.map +1 -1
  27. package/dist/src/bitgo/safe/safe.js +105 -29
  28. package/dist/src/bitgo/staking/iStakingWallet.d.ts +13 -5
  29. package/dist/src/bitgo/staking/iStakingWallet.d.ts.map +1 -1
  30. package/dist/src/bitgo/staking/iStakingWallet.js +1 -1
  31. package/dist/src/bitgo/staking/stakingWallet.d.ts +2 -2
  32. package/dist/src/bitgo/staking/stakingWallet.d.ts.map +1 -1
  33. package/dist/src/bitgo/staking/stakingWallet.js +14 -1
  34. package/dist/src/bitgo/tss/common.d.ts.map +1 -1
  35. package/dist/src/bitgo/tss/common.js +4 -1
  36. package/dist/src/bitgo/tss/redpallas/redpallasMPCv2.d.ts +50 -0
  37. package/dist/src/bitgo/tss/redpallas/redpallasMPCv2.d.ts.map +1 -0
  38. package/dist/src/bitgo/tss/redpallas/redpallasMPCv2.js +112 -0
  39. package/dist/src/bitgo/utils/mpcUtils.d.ts.map +1 -1
  40. package/dist/src/bitgo/utils/mpcUtils.js +15 -1
  41. package/dist/src/bitgo/utils/tss/baseTypes.d.ts +1 -1
  42. package/dist/src/bitgo/utils/tss/baseTypes.d.ts.map +1 -1
  43. package/dist/src/bitgo/utils/tss/baseTypes.js +1 -1
  44. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts +4 -1
  45. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.d.ts.map +1 -1
  46. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2.js +18 -6
  47. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.d.ts +9 -1
  48. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.d.ts.map +1 -1
  49. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaMPCv2KeyGenSender.js +24 -3
  50. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaVrfMPCv2.d.ts +88 -0
  51. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaVrfMPCv2.d.ts.map +1 -0
  52. package/dist/src/bitgo/utils/tss/ecdsa/ecdsaVrfMPCv2.js +494 -0
  53. package/dist/src/bitgo/utils/tss/ecdsa/index.d.ts +1 -0
  54. package/dist/src/bitgo/utils/tss/ecdsa/index.d.ts.map +1 -1
  55. package/dist/src/bitgo/utils/tss/ecdsa/index.js +2 -1
  56. package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.d.ts +20 -2
  57. package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.d.ts.map +1 -1
  58. package/dist/src/bitgo/utils/tss/ecdsa/typesMPCv2.js +1 -1
  59. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2.d.ts +8 -5
  60. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2.d.ts.map +1 -1
  61. package/dist/src/bitgo/utils/tss/eddsa/eddsaMPCv2.js +1 -1
  62. package/dist/src/bitgo/utils/tss/eddsa/eddsaVrfMPCv2.d.ts +33 -0
  63. package/dist/src/bitgo/utils/tss/eddsa/eddsaVrfMPCv2.d.ts.map +1 -0
  64. package/dist/src/bitgo/utils/tss/eddsa/eddsaVrfMPCv2.js +260 -0
  65. package/dist/src/bitgo/utils/tss/eddsa/index.d.ts +1 -0
  66. package/dist/src/bitgo/utils/tss/eddsa/index.d.ts.map +1 -1
  67. package/dist/src/bitgo/utils/tss/eddsa/index.js +2 -1
  68. package/dist/src/bitgo/utils/tss/eddsa/typesEddsaMPCv2.d.ts +15 -2
  69. package/dist/src/bitgo/utils/tss/eddsa/typesEddsaMPCv2.d.ts.map +1 -1
  70. package/dist/src/bitgo/utils/tss/eddsa/typesEddsaMPCv2.js +13 -2
  71. package/dist/src/bitgo/utils/tss/recipientUtils.d.ts.map +1 -1
  72. package/dist/src/bitgo/utils/tss/recipientUtils.js +13 -1
  73. package/dist/src/bitgo/wallet/BuildParams.d.ts +8 -0
  74. package/dist/src/bitgo/wallet/BuildParams.d.ts.map +1 -1
  75. package/dist/src/bitgo/wallet/BuildParams.js +6 -1
  76. package/dist/src/bitgo/wallet/iWallet.d.ts +7 -1
  77. package/dist/src/bitgo/wallet/iWallet.d.ts.map +1 -1
  78. package/dist/src/bitgo/wallet/iWallet.js +1 -1
  79. package/dist/src/bitgo/wallet/safeKeychain.d.ts +25 -2
  80. package/dist/src/bitgo/wallet/safeKeychain.d.ts.map +1 -1
  81. package/dist/src/bitgo/wallet/safeKeychain.js +72 -18
  82. package/dist/src/bitgo/wallet/wallet.d.ts +12 -4
  83. package/dist/src/bitgo/wallet/wallet.d.ts.map +1 -1
  84. package/dist/src/bitgo/wallet/wallet.js +82 -17
  85. package/dist/src/bitgo/wallet/wallets.d.ts +6 -0
  86. package/dist/src/bitgo/wallet/wallets.d.ts.map +1 -1
  87. package/dist/src/bitgo/wallet/wallets.js +35 -36
  88. package/dist/test/unit/bitgo/defi/defiVault.js +264 -1
  89. package/dist/test/unit/bitgo/keychain/keychains.js +43 -1
  90. package/dist/test/unit/bitgo/safe/safe.js +53 -22
  91. package/dist/test/unit/bitgo/tss/common.d.ts +2 -0
  92. package/dist/test/unit/bitgo/tss/common.d.ts.map +1 -0
  93. package/dist/test/unit/bitgo/tss/common.js +77 -0
  94. package/dist/test/unit/bitgo/tss/redpallas/redpallasMPCv2.d.ts +2 -0
  95. package/dist/test/unit/bitgo/tss/redpallas/redpallasMPCv2.d.ts.map +1 -0
  96. package/dist/test/unit/bitgo/tss/redpallas/redpallasMPCv2.js +181 -0
  97. package/dist/test/unit/bitgo/utils/tss/ecdsa/ecdsaMPCv2.js +70 -1
  98. package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaVrfMPCv2.d.ts +2 -0
  99. package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaVrfMPCv2.d.ts.map +1 -0
  100. package/dist/test/unit/bitgo/utils/tss/eddsa/eddsaVrfMPCv2.js +173 -0
  101. package/dist/test/unit/bitgo/utils/tss/recipientUtils.js +33 -1
  102. package/dist/test/unit/bitgo/wallet/safeGetUserPrv.js +10 -10
  103. package/dist/test/unit/bitgo/wallet/safeShareWallet.d.ts +9 -0
  104. package/dist/test/unit/bitgo/wallet/safeShareWallet.d.ts.map +1 -0
  105. package/dist/test/unit/bitgo/wallet/safeShareWallet.js +303 -0
  106. package/dist/test/unit/bitgo/wallet/walletsEncryptionVersion.js +51 -40
  107. package/dist/tsconfig.tsbuildinfo +1 -1
  108. package/package.json +6 -5
@@ -0,0 +1,494 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.EcdsaVrfMPCv2Utils = void 0;
7
+ exports.buildVrfKeyEnvelopes = buildVrfKeyEnvelopes;
8
+ exports.parseVrfKeyEnvelopes = parseVrfKeyEnvelopes;
9
+ exports.hardenedDerivationPath = hardenedDerivationPath;
10
+ const sdk_lib_mpc_1 = require("@bitgo/sdk-lib-mpc");
11
+ const cbor_x_1 = require("cbor-x");
12
+ const assert_1 = __importDefault(require("assert"));
13
+ const io_ts_types_1 = require("io-ts-types");
14
+ const public_types_1 = require("@bitgo/public-types");
15
+ const opengpgUtils_1 = require("../../opengpgUtils");
16
+ const bitgoPubKeys_1 = require("../../../tss/bitgoPubKeys");
17
+ const ecdsaMPCv2_1 = require("./ecdsaMPCv2");
18
+ const ecdsaMPCv2KeyGenSender_1 = require("./ecdsaMPCv2KeyGenSender");
19
+ const typesMPCv2_1 = require("./typesMPCv2");
20
+ /**
21
+ * Version field of the `encryptedPrv` envelope used when a ceremony produces both a
22
+ * signing keyshare and a VRF keyshare. The plaintext handed to encrypt() is
23
+ * `base64(cborEncode(envelope))`, keeping it a single opaque base64 token exactly as
24
+ * the ordinary MPCv2 format does.
25
+ */
26
+ const VRF_KEY_ENVELOPE_VERSION = 1;
27
+ function isVrfKeyEnvelope(value) {
28
+ return typeof value === 'object' && value !== null && 'version' in value && 'prvKeyShare' in value && 'vrf' in value;
29
+ }
30
+ function serializeVrfMessages(messages) {
31
+ const transfers = [
32
+ ...messages.broadcastMessages.map((m) => ({ from: m.from, payload: Buffer.from(m.payload).toString('base64') })),
33
+ ...messages.p2pMessages.map((m) => ({
34
+ from: m.from,
35
+ to: m.to,
36
+ payload: Buffer.from(m.payload).toString('base64'),
37
+ })),
38
+ ];
39
+ return Buffer.from(JSON.stringify(transfers)).toString('base64');
40
+ }
41
+ function deserializeVrfMessages(blob, forParty) {
42
+ const transfers = JSON.parse(Buffer.from(blob, 'base64').toString());
43
+ return {
44
+ broadcastMessages: transfers
45
+ .filter((t) => t.to === undefined)
46
+ .map((t) => ({ from: t.from, payload: new Uint8Array(Buffer.from(t.payload, 'base64')) })),
47
+ p2pMessages: transfers
48
+ .filter((t) => t.to === forParty)
49
+ .map((t) => ({ from: t.from, to: t.to, payload: new Uint8Array(Buffer.from(t.payload, 'base64')) })),
50
+ };
51
+ }
52
+ /**
53
+ * Combines the signing keyshare with the VRF keyshare into the `encryptedPrv` envelope
54
+ * (`base64(cborEncode({version, prvKeyShare, vrf}))` once the caller base64-encodes the
55
+ * returned buffers). The same container wraps the reduced signing share for
56
+ * `reducedEncryptedPrv`.
57
+ */
58
+ function buildVrfKeyEnvelopes(privateMaterial, reducedPrivateMaterial, vrfKeyShare) {
59
+ const envelope = (0, cbor_x_1.encode)({
60
+ version: VRF_KEY_ENVELOPE_VERSION,
61
+ prvKeyShare: new Uint8Array(privateMaterial),
62
+ vrf: new Uint8Array(vrfKeyShare),
63
+ });
64
+ const reducedEnvelope = (0, cbor_x_1.encode)({
65
+ version: VRF_KEY_ENVELOPE_VERSION,
66
+ prvKeyShare: new Uint8Array(reducedPrivateMaterial),
67
+ vrf: new Uint8Array(vrfKeyShare),
68
+ });
69
+ return { envelope: Buffer.from(envelope), reducedEnvelope: Buffer.from(reducedEnvelope) };
70
+ }
71
+ /**
72
+ * Parses a decrypted root blob produced by {@link buildVrfKeyEnvelopes}: a CBOR
73
+ * envelope `{version: 1, prvKeyShare, vrf}`. Returns the signing and VRF keyshares
74
+ * as Buffers. Throws if the blob is not a valid VRF key envelope.
75
+ */
76
+ function parseVrfKeyEnvelopes(decryptedBlob) {
77
+ let envelope;
78
+ try {
79
+ envelope = (0, cbor_x_1.decode)(Buffer.from(decryptedBlob, 'base64'));
80
+ }
81
+ catch (e) {
82
+ const message = e instanceof Error ? e.message : String(e);
83
+ throw new Error(`Failed to decode safe MPC root key envelope: ${message}`);
84
+ }
85
+ if (!isVrfKeyEnvelope(envelope)) {
86
+ throw new Error('Invalid safe MPC root key envelope: expected version, signing keyshare, and VRF keyshare');
87
+ }
88
+ const { version, prvKeyShare, vrf } = envelope;
89
+ if (version !== VRF_KEY_ENVELOPE_VERSION) {
90
+ throw new Error(`Unsupported safe MPC root key envelope version: ${String(version)}`);
91
+ }
92
+ if (!(prvKeyShare instanceof Uint8Array) || prvKeyShare.length === 0) {
93
+ throw new Error('Safe MPC root key envelope is missing a signing keyshare');
94
+ }
95
+ if (!(vrf instanceof Uint8Array) || vrf.length === 0) {
96
+ throw new Error('Safe MPC root key envelope is missing a VRF keyshare');
97
+ }
98
+ return { signing: Buffer.from(prvKeyShare), vrf: Buffer.from(vrf) };
99
+ }
100
+ /**
101
+ * Encodes a hardened derivation index as the byte path the DKLS hard-derive wasm
102
+ * expects: one big-endian u32 with the hardened bit (0x80000000) set — i.e. the
103
+ * child path `m/<index>'`. The server derives the same hardened path from the
104
+ * `derivationIndex` it receives on round 1.
105
+ */
106
+ function hardenedDerivationPath(index) {
107
+ if (!Number.isInteger(index) || index < 0 || index > 0x7fffffff) {
108
+ throw new Error(`Invalid derivation index: ${index}`);
109
+ }
110
+ return new Uint8Array([0x80 | (index >>> 24), (index >>> 16) & 0xff, (index >>> 8) & 0xff, index & 0xff]);
111
+ }
112
+ /**
113
+ * EcdsaMPCv2Utils variant that runs the Ristretto VRF DKG alongside the signing DKLS
114
+ * DKG inside the same MPCv2 keygen rounds, for safe MPC root creation.
115
+ *
116
+ * The round enum is unchanged: the VRF commitment rides MPCv2-R1, the opening rides
117
+ * MPCv2-R2, and the VRF DKG finalizes locally before MPCv2-R3. VRF messages travel as
118
+ * opaque base64 fields on the round payloads, never through the DKLS broadcast/p2p slots.
119
+ * At the end, the signing and VRF keyshares are combined into a single CBOR envelope
120
+ * before encryption.
121
+ */
122
+ class EcdsaVrfMPCv2Utils extends ecdsaMPCv2_1.EcdsaMPCv2Utils {
123
+ /** @inheritdoc */
124
+ async createKeychains(params) {
125
+ const { userSession, backupSession } = this.createSigningDkgSessions(params.retrofit);
126
+ const userVrfSession = new sdk_lib_mpc_1.DklsVrf.VrfDkg(3, 2, typesMPCv2_1.MPCv2PartiesEnum.USER);
127
+ const backupVrfSession = new sdk_lib_mpc_1.DklsVrf.VrfDkg(3, 2, typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
128
+ const userGpgKey = await (0, opengpgUtils_1.generateGPGKeyPair)('secp256k1');
129
+ const backupGpgKey = await (0, opengpgUtils_1.generateGPGKeyPair)('secp256k1');
130
+ // Get the BitGo public key based on user/enterprise feature flags
131
+ // If it doesn't work, use the default public key from the constants
132
+ const { mpcv2PublicKey } = await this.getBitgoGpgPubkeyBasedOnFeatureFlags(params.enterprise, true);
133
+ const mpcv2Key = mpcv2PublicKey ?? this.bitgoMPCv2PublicGpgKey;
134
+ (0, assert_1.default)(mpcv2Key, 'Failed to get BitGo MPCv2 GPG public key');
135
+ const bitgoPublicGpgKey = mpcv2Key.armor();
136
+ if ((0, bitgoPubKeys_1.envRequiresBitgoPubGpgKeyConfig)(this.bitgo.getEnv())) {
137
+ // Ensure the public key is one of the expected BitGo public keys when in test or prod.
138
+ (0, assert_1.default)((0, bitgoPubKeys_1.isBitgoMpcPubKey)(bitgoPublicGpgKey, 'mpcv2'), 'Invalid BitGo GPG public key');
139
+ }
140
+ const userGpgPrvKey = {
141
+ partyId: typesMPCv2_1.MPCv2PartiesEnum.USER,
142
+ gpgKey: userGpgKey.privateKey,
143
+ };
144
+ const backupGpgPrvKey = {
145
+ partyId: typesMPCv2_1.MPCv2PartiesEnum.BACKUP,
146
+ gpgKey: backupGpgKey.privateKey,
147
+ };
148
+ const bitgoGpgPubKey = {
149
+ partyId: typesMPCv2_1.MPCv2PartiesEnum.BITGO,
150
+ gpgKey: bitgoPublicGpgKey,
151
+ };
152
+ // #region round 1
153
+ const userRound1BroadcastMsg = await userSession.initDkg();
154
+ const backupRound1BroadcastMsg = await backupSession.initDkg();
155
+ const userVrfRound1Msg = await userVrfSession.initDkg();
156
+ const backupVrfRound1Msg = await backupVrfSession.initDkg();
157
+ const round1SerializedMessages = sdk_lib_mpc_1.DklsTypes.serializeMessages({
158
+ broadcastMessages: [userRound1BroadcastMsg, backupRound1BroadcastMsg],
159
+ p2pMessages: [],
160
+ });
161
+ const round1Messages = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages(round1SerializedMessages, [bitgoGpgPubKey], [userGpgPrvKey, backupGpgPrvKey]);
162
+ const userMsg1 = round1Messages.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER)?.payload;
163
+ const backupMsg1 = round1Messages.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP)?.payload;
164
+ (0, assert_1.default)(userMsg1, 'User message 1 not found in broadcast messages');
165
+ (0, assert_1.default)(backupMsg1, 'Backup message 1 not found in broadcast messages');
166
+ const userGpgPublicKey = userGpgKey.publicKey;
167
+ const backupGpgPublicKey = backupGpgKey.publicKey;
168
+ (0, assert_1.default)(io_ts_types_1.NonEmptyString.is(userGpgPublicKey), 'User GPG public key is required');
169
+ (0, assert_1.default)(io_ts_types_1.NonEmptyString.is(backupGpgPublicKey), 'Backup GPG public key is required');
170
+ // Keep VRF messages opaque on the key-generation request.
171
+ const round1Sender = (0, ecdsaMPCv2KeyGenSender_1.KeyGenSenderForEnterprise)(this.bitgo, params.enterprise, params.safeId);
172
+ const { sessionId, bitgoMsg1, bitgoToBackupMsg2, bitgoToUserMsg2, bitgoVrfMsg1 } = await round1Sender(public_types_1.MPCv2KeyGenStateEnum['MPCv2-R1'], {
173
+ userMsg1: { from: typesMPCv2_1.MPCv2PartiesEnum.USER, ...userMsg1 },
174
+ backupMsg1: { from: typesMPCv2_1.MPCv2PartiesEnum.BACKUP, ...backupMsg1 },
175
+ userGpgPublicKey,
176
+ backupGpgPublicKey,
177
+ userVrfMsg1: serializeVrfMessages(userVrfRound1Msg),
178
+ backupVrfMsg1: serializeVrfMessages(backupVrfRound1Msg),
179
+ walletId: params.retrofit?.walletId,
180
+ });
181
+ (0, assert_1.default)(bitgoVrfMsg1, 'BitGo VRF message 1 not found in round 1 response');
182
+ // #endregion
183
+ // #region round 2
184
+ const bitgoRound1BroadcastMessages = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({ p2pMessages: [], broadcastMessages: [this.formatBitgoBroadcastMessage(bitgoMsg1)] }, [bitgoGpgPubKey], [userGpgPrvKey, backupGpgPrvKey]);
185
+ const bitgoRound1BroadcastMsg = bitgoRound1BroadcastMessages.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
186
+ (0, assert_1.default)(bitgoRound1BroadcastMsg, 'BitGo message 1 not found in broadcast messages');
187
+ const userRound2P2PMessages = userSession.handleIncomingMessages({
188
+ p2pMessages: [],
189
+ broadcastMessages: [sdk_lib_mpc_1.DklsTypes.deserializeBroadcastMessage(bitgoRound1BroadcastMsg), backupRound1BroadcastMsg],
190
+ });
191
+ const userToBitgoMsg2 = userRound2P2PMessages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER && m.to === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
192
+ (0, assert_1.default)(userToBitgoMsg2, 'User message 2 not found in P2P messages');
193
+ const serializedUserToBitgoMsg2 = sdk_lib_mpc_1.DklsTypes.serializeP2PMessage(userToBitgoMsg2);
194
+ const backupRound2P2PMessages = backupSession.handleIncomingMessages({
195
+ p2pMessages: [],
196
+ broadcastMessages: [userRound1BroadcastMsg, sdk_lib_mpc_1.DklsTypes.deserializeBroadcastMessage(bitgoRound1BroadcastMsg)],
197
+ });
198
+ const serializedBackupToBitgoMsg2 = sdk_lib_mpc_1.DklsTypes.serializeMessages(backupRound2P2PMessages).p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP && m.to === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
199
+ (0, assert_1.default)(serializedBackupToBitgoMsg2, 'Backup message 2 not found in P2P messages');
200
+ // VRF: consume BitGo's and the counterparty's commitments, emit this party's openings.
201
+ // Openings come back as p2p messages addressed to each party (including the sender).
202
+ const userVrfRound2Messages = await userVrfSession.handleIncomingMessages({
203
+ broadcastMessages: [
204
+ ...backupVrfRound1Msg.broadcastMessages,
205
+ ...deserializeVrfMessages(bitgoVrfMsg1, typesMPCv2_1.MPCv2PartiesEnum.USER).broadcastMessages,
206
+ ],
207
+ p2pMessages: [],
208
+ });
209
+ const backupVrfRound2Messages = await backupVrfSession.handleIncomingMessages({
210
+ broadcastMessages: [
211
+ ...userVrfRound1Msg.broadcastMessages,
212
+ ...deserializeVrfMessages(bitgoVrfMsg1, typesMPCv2_1.MPCv2PartiesEnum.BACKUP).broadcastMessages,
213
+ ],
214
+ p2pMessages: [],
215
+ });
216
+ const round2Messages = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages({ p2pMessages: [serializedUserToBitgoMsg2, serializedBackupToBitgoMsg2], broadcastMessages: [] }, [bitgoGpgPubKey], [userGpgPrvKey, backupGpgPrvKey]);
217
+ const userRound2Msg = round2Messages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER && m.to === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
218
+ const backupRound2Msg = round2Messages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP && m.to === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
219
+ (0, assert_1.default)(userRound2Msg, 'User to Bitgo message 2 not found in P2P messages');
220
+ (0, assert_1.default)(userRound2Msg.commitment, 'User to Bitgo commitment not found in P2P messages');
221
+ (0, assert_1.default)(backupRound2Msg, 'Backup to Bitgo message 2 not found in P2P messages');
222
+ (0, assert_1.default)(backupRound2Msg.commitment, 'Backup to Bitgo commitment not found in P2P messages');
223
+ (0, assert_1.default)(io_ts_types_1.NonEmptyString.is(userRound2Msg.commitment), 'User to Bitgo commitment is required');
224
+ (0, assert_1.default)(io_ts_types_1.NonEmptyString.is(backupRound2Msg.commitment), 'Backup to Bitgo commitment is required');
225
+ const round2Sender = (0, ecdsaMPCv2KeyGenSender_1.KeyGenSenderForEnterprise)(this.bitgo, params.enterprise);
226
+ const { sessionId: sessionIdRound2, bitgoCommitment2, bitgoToUserMsg3, bitgoToBackupMsg3, bitgoVrfMsg2, } = await round2Sender(public_types_1.MPCv2KeyGenStateEnum['MPCv2-R2'], {
227
+ sessionId,
228
+ userMsg2: {
229
+ from: typesMPCv2_1.MPCv2PartiesEnum.USER,
230
+ to: typesMPCv2_1.MPCv2PartiesEnum.BITGO,
231
+ signature: userRound2Msg.payload.signature,
232
+ encryptedMessage: userRound2Msg.payload.encryptedMessage,
233
+ },
234
+ userCommitment2: userRound2Msg.commitment,
235
+ backupMsg2: {
236
+ from: typesMPCv2_1.MPCv2PartiesEnum.BACKUP,
237
+ to: typesMPCv2_1.MPCv2PartiesEnum.BITGO,
238
+ signature: backupRound2Msg.payload.signature,
239
+ encryptedMessage: backupRound2Msg.payload.encryptedMessage,
240
+ },
241
+ backupCommitment2: backupRound2Msg.commitment,
242
+ userVrfMsg2: serializeVrfMessages(userVrfRound2Messages),
243
+ backupVrfMsg2: serializeVrfMessages(backupVrfRound2Messages),
244
+ });
245
+ // #endregion
246
+ // #region round 3
247
+ assert_1.default.equal(sessionId, sessionIdRound2, 'Round 1 and 2 Session IDs do not match');
248
+ (0, assert_1.default)(bitgoVrfMsg2, 'BitGo VRF message 2 not found in round 2 response');
249
+ // VRF: finalize both DKGs locally by consuming the opening messages addressed to each
250
+ // party (including each party's own) from the R2 exchanges. The VRF DKG completes here,
251
+ // a full round of slack before MPCv2-R3.
252
+ await userVrfSession.handleIncomingMessages({
253
+ broadcastMessages: [],
254
+ p2pMessages: [
255
+ ...userVrfRound2Messages.p2pMessages.filter((m) => m.to === typesMPCv2_1.MPCv2PartiesEnum.USER),
256
+ ...backupVrfRound2Messages.p2pMessages.filter((m) => m.to === typesMPCv2_1.MPCv2PartiesEnum.USER),
257
+ ...deserializeVrfMessages(bitgoVrfMsg2, typesMPCv2_1.MPCv2PartiesEnum.USER).p2pMessages,
258
+ ],
259
+ });
260
+ await backupVrfSession.handleIncomingMessages({
261
+ broadcastMessages: [],
262
+ p2pMessages: [
263
+ ...userVrfRound2Messages.p2pMessages.filter((m) => m.to === typesMPCv2_1.MPCv2PartiesEnum.BACKUP),
264
+ ...backupVrfRound2Messages.p2pMessages.filter((m) => m.to === typesMPCv2_1.MPCv2PartiesEnum.BACKUP),
265
+ ...deserializeVrfMessages(bitgoVrfMsg2, typesMPCv2_1.MPCv2PartiesEnum.BACKUP).p2pMessages,
266
+ ],
267
+ });
268
+ const decryptedBitgoToUserRound2Msgs = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({ p2pMessages: [this.formatP2PMessage(bitgoToUserMsg2)], broadcastMessages: [] }, [bitgoGpgPubKey], [userGpgPrvKey]);
269
+ const serializedBitgoToUserRound2Msg = decryptedBitgoToUserRound2Msgs.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BITGO && m.to === typesMPCv2_1.MPCv2PartiesEnum.USER);
270
+ (0, assert_1.default)(serializedBitgoToUserRound2Msg, 'BitGo to User message 2 not found in P2P messages');
271
+ const bitgoToUserRound2Msg = sdk_lib_mpc_1.DklsTypes.deserializeP2PMessage(serializedBitgoToUserRound2Msg);
272
+ const decryptedBitgoToBackupRound2Msg = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({ p2pMessages: [this.formatP2PMessage(bitgoToBackupMsg2)], broadcastMessages: [] }, [bitgoGpgPubKey], [backupGpgPrvKey]);
273
+ const serializedBitgoToBackupRound2Msg = decryptedBitgoToBackupRound2Msg.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BITGO && m.to === typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
274
+ (0, assert_1.default)(serializedBitgoToBackupRound2Msg, 'BitGo to Backup message 2 not found in P2P messages');
275
+ const bitgoToBackupRound2Msg = sdk_lib_mpc_1.DklsTypes.deserializeP2PMessage(serializedBitgoToBackupRound2Msg);
276
+ const userToBackupMsg2 = userRound2P2PMessages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER && m.to === typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
277
+ (0, assert_1.default)(userToBackupMsg2, 'User to Backup message 2 not found in P2P messages');
278
+ const backupToUserMsg2 = backupRound2P2PMessages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP && m.to === typesMPCv2_1.MPCv2PartiesEnum.USER);
279
+ (0, assert_1.default)(backupToUserMsg2, 'Backup to User message 2 not found in P2P messages');
280
+ const userRound3Messages = userSession.handleIncomingMessages({
281
+ broadcastMessages: [],
282
+ p2pMessages: [bitgoToUserRound2Msg, backupToUserMsg2],
283
+ });
284
+ const userToBackupMsg3 = userRound3Messages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER && m.to === typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
285
+ (0, assert_1.default)(userToBackupMsg3, 'User to Backup message 3 not found in P2P messages');
286
+ const userToBitgoMsg3 = userRound3Messages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER && m.to === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
287
+ (0, assert_1.default)(userToBitgoMsg3, 'User to Bitgo message 3 not found in P2P messages');
288
+ const serializedUserToBitgoMsg3 = sdk_lib_mpc_1.DklsTypes.serializeP2PMessage(userToBitgoMsg3);
289
+ const backupRound3Messages = backupSession.handleIncomingMessages({
290
+ broadcastMessages: [],
291
+ p2pMessages: [bitgoToBackupRound2Msg, userToBackupMsg2],
292
+ });
293
+ const backupToUserMsg3 = backupRound3Messages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP && m.to === typesMPCv2_1.MPCv2PartiesEnum.USER);
294
+ (0, assert_1.default)(backupToUserMsg3, 'Backup to User message 3 not found in P2P messages');
295
+ const backupToBitgoMsg3 = backupRound3Messages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP && m.to === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
296
+ (0, assert_1.default)(backupToBitgoMsg3, 'Backup to Bitgo message 3 not found in P2P messages');
297
+ const serializedBackupToBitgoMsg3 = sdk_lib_mpc_1.DklsTypes.serializeP2PMessage(backupToBitgoMsg3);
298
+ const decryptedBitgoToUserRound3Messages = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({ broadcastMessages: [], p2pMessages: [this.formatP2PMessage(bitgoToUserMsg3, bitgoCommitment2)] }, [bitgoGpgPubKey], [userGpgPrvKey]);
299
+ const serializedBitgoToUserRound3Msg = decryptedBitgoToUserRound3Messages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BITGO && m.to === typesMPCv2_1.MPCv2PartiesEnum.USER);
300
+ (0, assert_1.default)(serializedBitgoToUserRound3Msg, 'BitGo to User message 3 not found in P2P messages');
301
+ const bitgoToUserRound3Msg = sdk_lib_mpc_1.DklsTypes.deserializeP2PMessage(serializedBitgoToUserRound3Msg);
302
+ const decryptedBitgoToBackupRound3Messages = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({ broadcastMessages: [], p2pMessages: [this.formatP2PMessage(bitgoToBackupMsg3, bitgoCommitment2)] }, [bitgoGpgPubKey], [backupGpgPrvKey]);
303
+ const serializedBitgoToBackupRound3Msg = decryptedBitgoToBackupRound3Messages.p2pMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BITGO && m.to === typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
304
+ (0, assert_1.default)(serializedBitgoToBackupRound3Msg, 'BitGo to Backup message 3 not found in P2P messages');
305
+ const bitgoToBackupRound3Msg = sdk_lib_mpc_1.DklsTypes.deserializeP2PMessage(serializedBitgoToBackupRound3Msg);
306
+ const userRound4Messages = userSession.handleIncomingMessages({
307
+ p2pMessages: [backupToUserMsg3, bitgoToUserRound3Msg],
308
+ broadcastMessages: [],
309
+ });
310
+ const userRound4BroadcastMsg = userRound4Messages.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER);
311
+ (0, assert_1.default)(userRound4BroadcastMsg, 'User message 4 not found in broadcast messages');
312
+ const serializedUserRound4BroadcastMsg = sdk_lib_mpc_1.DklsTypes.serializeBroadcastMessage(userRound4BroadcastMsg);
313
+ const backupRound4Messages = backupSession.handleIncomingMessages({
314
+ p2pMessages: [userToBackupMsg3, bitgoToBackupRound3Msg],
315
+ broadcastMessages: [],
316
+ });
317
+ const backupRound4BroadcastMsg = backupRound4Messages.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BACKUP);
318
+ (0, assert_1.default)(backupRound4BroadcastMsg, 'Backup message 4 not found in broadcast messages');
319
+ const serializedBackupRound4BroadcastMsg = sdk_lib_mpc_1.DklsTypes.serializeBroadcastMessage(backupRound4BroadcastMsg);
320
+ const round3Messages = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages({
321
+ p2pMessages: [serializedUserToBitgoMsg3, serializedBackupToBitgoMsg3],
322
+ broadcastMessages: [serializedUserRound4BroadcastMsg, serializedBackupRound4BroadcastMsg],
323
+ }, [bitgoGpgPubKey], [userGpgPrvKey, backupGpgPrvKey]);
324
+ const { sessionId: sessionIdRound3, bitgoMsg4, commonKeychain: bitgoCommonKeychain, } = await this.sendKeyGenerationRound3(params.enterprise, sessionId, round3Messages);
325
+ // #endregion
326
+ // #region keychain creation
327
+ assert_1.default.equal(sessionId, sessionIdRound3, 'Round 1 and 3 Session IDs do not match');
328
+ const bitgoRound4BroadcastMessages = sdk_lib_mpc_1.DklsTypes.deserializeMessages(await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({ p2pMessages: [], broadcastMessages: [this.formatBitgoBroadcastMessage(bitgoMsg4)] }, [bitgoGpgPubKey], [])).broadcastMessages;
329
+ const bitgoRound4BroadcastMsg = bitgoRound4BroadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
330
+ (0, assert_1.default)(bitgoRound4BroadcastMsg, 'BitGo message 4 not found in broadcast messages');
331
+ userSession.handleIncomingMessages({
332
+ p2pMessages: [],
333
+ broadcastMessages: [bitgoRound4BroadcastMsg, backupRound4BroadcastMsg],
334
+ });
335
+ backupSession.handleIncomingMessages({
336
+ p2pMessages: [],
337
+ broadcastMessages: [bitgoRound4BroadcastMsg, userRound4BroadcastMsg],
338
+ });
339
+ const userPrivateMaterial = userSession.getKeyShare();
340
+ const backupPrivateMaterial = backupSession.getKeyShare();
341
+ const userReducedPrivateMaterial = userSession.getReducedKeyShare();
342
+ const backupReducedPrivateMaterial = backupSession.getReducedKeyShare();
343
+ const userVrfKeyShare = userVrfSession.getKeyShare();
344
+ const backupVrfKeyShare = backupVrfSession.getKeyShare();
345
+ const userCommonKeychain = sdk_lib_mpc_1.DklsTypes.getCommonKeychain(userPrivateMaterial);
346
+ const backupCommonKeychain = sdk_lib_mpc_1.DklsTypes.getCommonKeychain(backupPrivateMaterial);
347
+ assert_1.default.equal(bitgoCommonKeychain, userCommonKeychain, 'User and Bitgo Common keychains do not match');
348
+ assert_1.default.equal(bitgoCommonKeychain, backupCommonKeychain, 'Backup and Bitgo Common keychains do not match');
349
+ const { envelope: userEnvelope, reducedEnvelope: userReducedEnvelope } = buildVrfKeyEnvelopes(userPrivateMaterial, userReducedPrivateMaterial, userVrfKeyShare);
350
+ const { envelope: backupEnvelope, reducedEnvelope: backupReducedEnvelope } = buildVrfKeyEnvelopes(backupPrivateMaterial, backupReducedPrivateMaterial, backupVrfKeyShare);
351
+ const encryptionSession = params.encryptionVersion === 2 ? await this.bitgo.createEncryptionSession(params.passphrase) : undefined;
352
+ try {
353
+ const userKeychainPromise = this.createParticipantKeychain(typesMPCv2_1.MPCv2PartiesEnum.USER, bitgoCommonKeychain, userEnvelope, userReducedEnvelope, params.passphrase, params.originalPasscodeEncryptionCode, params.webauthnInfo, encryptionSession, params.encryptionVersion, params.enterprise, params.safeId);
354
+ const backupKeychainPromise = this.createParticipantKeychain(typesMPCv2_1.MPCv2PartiesEnum.BACKUP, bitgoCommonKeychain, backupEnvelope, backupReducedEnvelope, params.passphrase, params.originalPasscodeEncryptionCode, undefined, encryptionSession, params.encryptionVersion, undefined, params.safeId);
355
+ const bitgoKeychainPromise = this.createParticipantKeychain(typesMPCv2_1.MPCv2PartiesEnum.BITGO, bitgoCommonKeychain, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, params.safeId);
356
+ const [userKeychain, backupKeychain, bitgoKeychain] = await Promise.all([
357
+ userKeychainPromise,
358
+ backupKeychainPromise,
359
+ bitgoKeychainPromise,
360
+ ]);
361
+ // #endregion
362
+ return {
363
+ userKeychain,
364
+ backupKeychain,
365
+ bitgoKeychain,
366
+ };
367
+ }
368
+ finally {
369
+ encryptionSession?.destroy();
370
+ }
371
+ }
372
+ /**
373
+ * Sends round 1 for the user/BitGo hard-derive ceremony.
374
+ */
375
+ async sendDerivationRound1BySender(senderFn, userGpgPublicKey, payload, parentKeyId, derivationIndex) {
376
+ (0, assert_1.default)(io_ts_types_1.NonEmptyString.is(userGpgPublicKey), 'User GPG public key is required');
377
+ (0, assert_1.default)(io_ts_types_1.NonEmptyString.is(parentKeyId), 'Parent key id is required');
378
+ const userMsg1 = payload.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER)?.payload;
379
+ (0, assert_1.default)(userMsg1, 'User message 1 not found in broadcast messages');
380
+ (0, assert_1.default)(public_types_1.MPCv2DeriveRound1Request.props.derivationIndex.is(derivationIndex), 'Derivation index must be a non-negative safe integer');
381
+ const request = {
382
+ userGpgPublicKey,
383
+ userMsg1: { from: typesMPCv2_1.MPCv2PartiesEnum.USER, ...userMsg1 },
384
+ parentKeyId,
385
+ derivationIndex,
386
+ };
387
+ return senderFn(public_types_1.MPCv2KeyGenStateEnum['MPCv2Derive-R1'], request);
388
+ }
389
+ /**
390
+ * Sends round 2 for the user/BitGo hard-derive ceremony.
391
+ */
392
+ async sendDerivationRound2BySender(senderFn, sessionId, payload) {
393
+ (0, assert_1.default)(io_ts_types_1.NonEmptyString.is(sessionId), 'Session ID is required');
394
+ const userMsg2 = payload.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.USER)?.payload;
395
+ (0, assert_1.default)(userMsg2, 'User message 2 not found in broadcast messages');
396
+ const request = {
397
+ sessionId,
398
+ userMsg2: { from: typesMPCv2_1.MPCv2PartiesEnum.USER, ...userMsg2 },
399
+ };
400
+ return senderFn(public_types_1.MPCv2KeyGenStateEnum['MPCv2Derive-R2'], request);
401
+ }
402
+ /**
403
+ * Completes round 3 and returns the child common keychain.
404
+ */
405
+ async sendDerivationRound3BySender(senderFn, sessionId) {
406
+ (0, assert_1.default)(io_ts_types_1.NonEmptyString.is(sessionId), 'Session ID is required');
407
+ return senderFn(public_types_1.MPCv2KeyGenStateEnum['MPCv2Derive-R3'], { sessionId });
408
+ }
409
+ /**
410
+ * Runs the safe child hard-derive ceremony and registers child key documents.
411
+ */
412
+ async createSafeChildKeychains(params) {
413
+ const userGpgKey = await (0, opengpgUtils_1.generateGPGKeyPair)('secp256k1');
414
+ const { mpcv2PublicKey } = await this.getBitgoGpgPubkeyBasedOnFeatureFlags(params.enterprise, true);
415
+ const mpcv2Key = mpcv2PublicKey ?? this.bitgoMPCv2PublicGpgKey;
416
+ (0, assert_1.default)(mpcv2Key, 'Failed to get BitGo MPCv2 GPG public key');
417
+ const bitgoPublicGpgKey = mpcv2Key.armor();
418
+ if ((0, bitgoPubKeys_1.envRequiresBitgoPubGpgKeyConfig)(this.bitgo.getEnv())) {
419
+ (0, assert_1.default)((0, bitgoPubKeys_1.isBitgoMpcPubKey)(bitgoPublicGpgKey, 'mpcv2'), 'Invalid BitGo GPG public key');
420
+ }
421
+ const userGpgPrvKey = {
422
+ partyId: typesMPCv2_1.MPCv2PartiesEnum.USER,
423
+ gpgKey: userGpgKey.privateKey,
424
+ };
425
+ const bitgoGpgPubKey = {
426
+ partyId: typesMPCv2_1.MPCv2PartiesEnum.BITGO,
427
+ gpgKey: bitgoPublicGpgKey,
428
+ };
429
+ const path = hardenedDerivationPath(params.derivationIndex);
430
+ const userDeriveSession = new sdk_lib_mpc_1.DklsDrv.Derive(3, 2, typesMPCv2_1.MPCv2PartiesEnum.USER, params.userRootKeyShare, params.userRootVrfKeyShare, path);
431
+ // Round 1: send the user's first message.
432
+ const userRound1Msg = await userDeriveSession.initDerive();
433
+ const round1Messages = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages({
434
+ broadcastMessages: [sdk_lib_mpc_1.DklsTypes.serializeBroadcastMessage(userRound1Msg)],
435
+ p2pMessages: [],
436
+ }, [bitgoGpgPubKey], [userGpgPrvKey]);
437
+ (0, assert_1.default)(io_ts_types_1.NonEmptyString.is(userGpgKey.publicKey), 'User GPG public key is required');
438
+ const { sessionId, bitgoMsg1 } = await this.sendDerivationRound1BySender((0, ecdsaMPCv2KeyGenSender_1.KeyGenSenderForSafeChild)(this.bitgo, params.enterprise, params.safeId), userGpgKey.publicKey, round1Messages, params.parentKeyId, params.derivationIndex);
439
+ // Round 2: process the peer's first message and return the user's second.
440
+ const decryptedBitgoRound1 = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({ p2pMessages: [], broadcastMessages: [this.formatBitgoBroadcastMessage(bitgoMsg1)] }, [bitgoGpgPubKey], []);
441
+ const bitgoRound1Msg = decryptedBitgoRound1.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
442
+ (0, assert_1.default)(bitgoRound1Msg, 'BitGo derive message 1 not found in broadcast messages');
443
+ const userRound2Messages = userDeriveSession.handleIncomingMessages({
444
+ p2pMessages: [],
445
+ broadcastMessages: [sdk_lib_mpc_1.DklsTypes.deserializeBroadcastMessage(bitgoRound1Msg)],
446
+ });
447
+ const round2Messages = await sdk_lib_mpc_1.DklsComms.encryptAndAuthOutgoingMessages(sdk_lib_mpc_1.DklsTypes.serializeMessages(userRound2Messages), [bitgoGpgPubKey], [userGpgPrvKey]);
448
+ const { sessionId: sessionIdRound2, bitgoMsg2 } = await this.sendDerivationRound2BySender((0, ecdsaMPCv2KeyGenSender_1.KeyGenSenderForSafeChild)(this.bitgo, params.enterprise, params.safeId), sessionId, round2Messages);
449
+ assert_1.default.equal(sessionId, sessionIdRound2, 'Round 1 and 2 Session IDs do not match');
450
+ // Process the peer response to finalize the local child share.
451
+ const decryptedBitgoRound2 = await sdk_lib_mpc_1.DklsComms.decryptAndVerifyIncomingMessages({ p2pMessages: [], broadcastMessages: [this.formatBitgoBroadcastMessage(bitgoMsg2)] }, [bitgoGpgPubKey], []);
452
+ const bitgoRound2Msg = decryptedBitgoRound2.broadcastMessages.find((m) => m.from === typesMPCv2_1.MPCv2PartiesEnum.BITGO);
453
+ (0, assert_1.default)(bitgoRound2Msg, 'BitGo derive message 2 not found in broadcast messages');
454
+ userDeriveSession.handleIncomingMessages({
455
+ p2pMessages: [],
456
+ broadcastMessages: [sdk_lib_mpc_1.DklsTypes.deserializeBroadcastMessage(bitgoRound2Msg)],
457
+ });
458
+ // Round 3: obtain the child common-keychain metadata.
459
+ const { sessionId: sessionIdRound3, commonKeychain } = await this.sendDerivationRound3BySender((0, ecdsaMPCv2KeyGenSender_1.KeyGenSenderForSafeChild)(this.bitgo, params.enterprise, params.safeId), sessionId);
460
+ assert_1.default.equal(sessionId, sessionIdRound3, 'Round 1 and 3 Session IDs do not match');
461
+ const userPrivateMaterial = userDeriveSession.getKeyShare();
462
+ const userReducedPrivateMaterial = userDeriveSession.getReducedKeyShare();
463
+ const userCommonKeychain = sdk_lib_mpc_1.DklsTypes.getCommonKeychain(userPrivateMaterial);
464
+ assert_1.default.equal(commonKeychain, userCommonKeychain, 'User and BitGo common keychains do not match');
465
+ const encryptionSession = params.encryptionVersion === 2 ? await this.bitgo.createEncryptionSession(params.passphrase) : undefined;
466
+ try {
467
+ const userKeychainPromise = this.createParticipantKeychain(typesMPCv2_1.MPCv2PartiesEnum.USER, commonKeychain, userPrivateMaterial, userReducedPrivateMaterial, params.passphrase, params.originalPasscodeEncryptionCode, params.webauthnInfo, encryptionSession, params.encryptionVersion, params.enterprise, params.safeId, { parentKeyId: params.userRootKeyId, index: params.derivationIndex });
468
+ const backupKeychainPromise = this.createParticipantKeychain(typesMPCv2_1.MPCv2PartiesEnum.BACKUP, commonKeychain, undefined, undefined, params.passphrase, params.originalPasscodeEncryptionCode, undefined, encryptionSession, params.encryptionVersion, undefined, params.safeId, { parentKeyId: params.backupRootKeyId, index: params.derivationIndex });
469
+ const [userKeychain, backupKeychain] = await Promise.all([userKeychainPromise, backupKeychainPromise]);
470
+ return { userKeychain, backupKeychain };
471
+ }
472
+ finally {
473
+ encryptionSession?.destroy();
474
+ }
475
+ }
476
+ createSigningDkgSessions(retrofit) {
477
+ if (retrofit) {
478
+ const retrofitData = this.getMpcV2RetrofitDataFromMpcV1Keys({
479
+ mpcv1UserKeyShare: retrofit.decryptedUserKey,
480
+ mpcv1BackupKeyShare: retrofit.decryptedBackupKey,
481
+ });
482
+ return {
483
+ userSession: new sdk_lib_mpc_1.DklsDkg.Dkg(3, 2, typesMPCv2_1.MPCv2PartiesEnum.USER, undefined, retrofitData.mpcv2UserKeyShare),
484
+ backupSession: new sdk_lib_mpc_1.DklsDkg.Dkg(3, 2, typesMPCv2_1.MPCv2PartiesEnum.BACKUP, undefined, retrofitData.mpcv2BackupKeyShare),
485
+ };
486
+ }
487
+ return {
488
+ userSession: new sdk_lib_mpc_1.DklsDkg.Dkg(3, 2, typesMPCv2_1.MPCv2PartiesEnum.USER),
489
+ backupSession: new sdk_lib_mpc_1.DklsDkg.Dkg(3, 2, typesMPCv2_1.MPCv2PartiesEnum.BACKUP),
490
+ };
491
+ }
492
+ }
493
+ exports.EcdsaVrfMPCv2Utils = EcdsaVrfMPCv2Utils;
494
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWNkc2FWcmZNUEN2Mi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9iaXRnby91dGlscy90c3MvZWNkc2EvZWNkc2FWcmZNUEN2Mi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUF3RkEsb0RBZ0JDO0FBT0Qsb0RBc0JDO0FBUUQsd0RBS0M7QUFsSkQsb0RBQXFGO0FBQ3JGLG1DQUF3QztBQUN4QyxvREFBNEI7QUFDNUIsNkNBQTZDO0FBQzdDLHNEQVM2QjtBQUk3QixxREFBd0Q7QUFFeEQsNERBQThGO0FBQzlGLDZDQUErQztBQUMvQyxxRUFJa0M7QUFDbEMsNkNBQThFO0FBRTlFOzs7OztHQUtHO0FBQ0gsTUFBTSx3QkFBd0IsR0FBRyxDQUFDLENBQUM7QUFPbkMsU0FBUyxnQkFBZ0IsQ0FBQyxLQUFjO0lBQ3RDLE9BQU8sT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksU0FBUyxJQUFJLEtBQUssSUFBSSxhQUFhLElBQUksS0FBSyxJQUFJLEtBQUssSUFBSSxLQUFLLENBQUM7QUFDdkgsQ0FBQztBQWVELFNBQVMsb0JBQW9CLENBQUMsUUFBd0M7SUFDcEUsTUFBTSxTQUFTLEdBQXlCO1FBQ3RDLEdBQUcsUUFBUSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2hILEdBQUcsUUFBUSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDbEMsSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJO1lBQ1osRUFBRSxFQUFFLENBQUMsQ0FB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QUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxZQUFZLENBQUMsaUJBQWlCLENBQUM7Z0JBQ3BHLGFBQWEsRUFBRSxJQUFJLHFCQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsNkJBQWdCLENBQUMsTUFBTSxFQUFFLFNBQVMsRUFBRSxZQUFZLENBQUMsbUJBQW1CLENBQUM7YUFDM0csQ0FBQztRQUNKLENBQUM7UUFDRCxPQUFPO1lBQ0wsV0FBVyxFQUFFLElBQUkscUJBQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSw2QkFBZ0IsQ0FBQyxJQUFJLENBQUM7WUFDekQsYUFBYSxFQUFFLElBQUkscUJBQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSw2QkFBZ0IsQ0FBQyxNQUFNLENBQUM7U0FDOUQsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQXZwQkQsZ0RBdXBCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERrbHNDb21tcywgRGtsc0RrZywgRGtsc0RydiwgRGtsc1R5cGVzLCBEa2xzVnJmIH0gZnJvbSAnQGJpdGdvL3Nkay1saWItbXBjJztcbmltcG9ydCB7IGRlY29kZSwgZW5jb2RlIH0gZnJvbSAnY2Jvci14JztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCB7IE5vbkVtcHR5U3RyaW5nIH0gZnJvbSAnaW8tdHMtdHlwZXMnO1xuaW1wb3J0IHtcbiAgTVBDdjJEZXJpdmVSb3VuZDFSZXF1ZXN0LFxuICBNUEN2MkRlcml2ZVJvdW5kMVJlc3BvbnNlLFxuICBNUEN2MkRlcml2ZVJvdW5kMlJlcXVlc3QsXG4gIE1QQ3YyRGVyaXZlUm91bmQyUmVzcG9uc2UsXG4gIE1QQ3YyRGVyaXZlUm91bmQzUmVzcG9uc2UsXG4gIE1QQ3YyS2V5R2VuUm91bmQxUmVzcG9uc2UsXG4gIE1QQ3YyS2V5R2VuUm91bmQyUmVzcG9uc2UsXG4gIE1QQ3YyS2V5R2VuU3RhdGVFbnVtLFxufSBmcm9tICdAYml0Z28vcHVibGljLXR5cGVzJztcbmltcG9ydCB7IEtleWNoYWluc1RyaXBsZXQgfSBmcm9tICcuLi8uLi8uLi9iYXNlQ29pbic7XG5pbXBvcnQgeyBEZWNyeXB0ZWRSZXRyb2ZpdFBheWxvYWQgfSBmcm9tICcuLi8uLi8uLi9rZXljaGFpbi9pS2V5Y2hhaW5zJztcbmltcG9ydCB7IEVuY3J5cHRpb25WZXJzaW9uIH0gZnJvbSAnLi4vLi4vLi4vLi4vYXBpJztcbmltcG9ydCB7IGdlbmVyYXRlR1BHS2V5UGFpciB9IGZyb20gJy4uLy4uL29wZW5ncGdVdGlscyc7XG5pbXBvcnQgeyBXZWJhdXRobktleUVuY3J5cHRpb25JbmZvIH0gZnJvbSAnLi4vLi4vLi4va2V5Y2hhaW4nO1xuaW1wb3J0IHsgZW52UmVxdWlyZXNCaXRnb1B1YkdwZ0tleUNvbmZpZywgaXNCaXRnb01wY1B1YktleSB9IGZyb20gJy4uLy4uLy4uL3Rzcy9iaXRnb1B1YktleXMnO1xuaW1wb3J0IHsgRWNkc2FNUEN2MlV0aWxzIH0gZnJvbSAnLi9lY2RzYU1QQ3YyJztcbmltcG9ydCB7XG4gIEVjZHNhTVBDdjJEZXJpdmVLZXlTZW5kRm4sXG4gIEtleUdlblNlbmRlckZvckVudGVycHJpc2UsXG4gIEtleUdlblNlbmRlckZvclNhZmVDaGlsZCxcbn0gZnJvbSAnLi9lY2RzYU1QQ3YyS2V5R2VuU2VuZGVyJztcbmltcG9ydCB7IE1QQ3YyUGFydGllc0VudW0sIE1wY1YyVnJmS2V5R2VuUmVzcG9uc2VGaWVsZHMgfSBmcm9tICcuL3R5cGVzTVBDdjInO1xuXG4vKipcbiAqIFZlcnNpb24gZmllbGQgb2YgdGhlIGBlbmNyeXB0ZWRQcnZgIGVudmVsb3BlIHVzZWQgd2hlbiBhIGNlcmVtb255IHByb2R1Y2VzIGJvdGggYVxuICogc2lnbmluZyBrZXlzaGFyZSBhbmQgYSBWUkYga2V5c2hhcmUuIFRoZSBwbGFpbnRleHQgaGFuZGVkIHRvIGVuY3J5cHQoKSBpc1xuICogYGJhc2U2NChjYm9yRW5jb2RlKGVudmVsb3BlKSlgLCBrZWVwaW5nIGl0IGEgc2luZ2xlIG9wYXF1ZSBiYXNlNjQgdG9rZW4gZXhhY3RseSBhc1xuICogdGhlIG9yZGluYXJ5IE1QQ3YyIGZvcm1hdCBkb2VzLlxuICovXG5jb25zdCBWUkZfS0VZX0VOVkVMT1BFX1ZFUlNJT04gPSAxO1xudHlwZSBWcmZLZXlFbnZlbG9wZSA9IHtcbiAgdmVyc2lvbjogdW5rbm93bjtcbiAgcHJ2S2V5U2hhcmU6IHVua25vd247XG4gIHZyZjogdW5rbm93bjtcbn07XG5cbmZ1bmN0aW9uIGlzVnJmS2V5RW52ZWxvcGUodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBWcmZLZXlFbnZlbG9wZSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmICd2ZXJzaW9uJyBpbiB2YWx1ZSAmJiAncHJ2S2V5U2hhcmUnIGluIHZhbHVlICYmICd2cmYnIGluIHZhbHVlO1xufVxuXG4vKipcbiAqIFdpcmUgZm9ybWF0IGZvciBWUkYgREtHIG1lc3NhZ2VzIHJpZGluZyB0aGUgTVBDdjItUjEvUjIgcGF5bG9hZHM6IGFuIG9wYXF1ZSBibG9iLFxuICogYGJhc2U2NChKU09OLnN0cmluZ2lmeShWcmZNZXNzYWdlVHJhbnNmZXJbXSkpYCwgY2FycnlpbmcgdGhlIHBhcnR5J3MgZnVsbCBiYXRjaCBvZlxuICogZW1pdHRlZCBtZXNzYWdlcy4gVGhlIFZSRiBES0cgZW1pdHMgYnJvYWRjYXN0IGNvbW1pdG1lbnRzIChSMSkgYW5kIHBlci1yZWNpcGllbnRcbiAqIG9wZW5pbmcgbWVzc2FnZXMgYWRkcmVzc2VkIHRvIGVhY2ggcGFydHkgaW5jbHVkaW5nIHRoZSBzZW5kZXIgKFIyKSwgc28gdGhlIHJlY2VpdmluZ1xuICogc2lkZSByb3V0ZXMgYnkgYHRvYCBhbmQga2VlcHMgbWVzc2FnZXMgYWRkcmVzc2VkIHRvIGl0c2VsZi5cbiAqL1xuaW50ZXJmYWNlIFZyZk1lc3NhZ2VUcmFuc2ZlciB7XG4gIGZyb206IG51bWJlcjtcbiAgdG8/OiBudW1iZXI7XG4gIHBheWxvYWQ6IHN0cmluZzsgLy8gYmFzZTY0XG59XG5cbmZ1bmN0aW9uIHNlcmlhbGl6ZVZyZk1lc3NhZ2VzKG1lc3NhZ2VzOiBEa2xzVHlwZXMuRGVzZXJpYWxpemVkTWVzc2FnZXMpOiBzdHJpbmcge1xuICBjb25zdCB0cmFuc2ZlcnM6IFZyZk1lc3NhZ2VUcmFuc2ZlcltdID0gW1xuICAgIC4uLm1lc3NhZ2VzLmJyb2FkY2FzdE1lc3NhZ2VzLm1hcCgobSkgPT4gKHsgZnJvbTogbS5mcm9tLCBwYXlsb2FkOiBCdWZmZXIuZnJvbShtLnBheWxvYWQpLnRvU3RyaW5nKCdiYXNlNjQnKSB9KSksXG4gICAgLi4ubWVzc2FnZXMucDJwTWVzc2FnZXMubWFwKChtKSA9PiAoe1xuICAgICAgZnJvbTogbS5mcm9tLFxuICAgICAgdG86IG0udG8sXG4gICAgICBwYXlsb2FkOiBCdWZmZXIuZnJvbShtLnBheWxvYWQpLnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICB9KSksXG4gIF07XG4gIHJldHVybiBCdWZmZXIuZnJvbShKU09OLnN0cmluZ2lmeSh0cmFuc2ZlcnMpKS50b1N0cmluZygnYmFzZTY0Jyk7XG59XG5cbmZ1bmN0aW9uIGRlc2VyaWFsaXplVnJmTWVzc2FnZXMoYmxvYjogc3RyaW5nLCBmb3JQYXJ0eTogbnVtYmVyKTogRGtsc1R5cGVzLkRlc2VyaWFsaXplZE1lc3NhZ2VzIHtcbiAgY29uc3QgdHJhbnNmZXJzOiBWcmZNZXNzYWdlVHJhbnNmZXJbXSA9IEpTT04ucGFyc2UoQnVmZmVyLmZyb20oYmxvYiwgJ2Jhc2U2NCcpLnRvU3RyaW5nKCkpO1xuICByZXR1cm4ge1xuICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiB0cmFuc2ZlcnNcbiAgICAgIC5maWx0ZXIoKHQpID0+IHQudG8gPT09IHVuZGVmaW5lZClcbiAgICAgIC5tYXAoKHQpID0+ICh7IGZyb206IHQuZnJvbSwgcGF5bG9hZDogbmV3IFVpbnQ4QXJyYXkoQnVmZmVyLmZyb20odC5wYXlsb2FkLCAnYmFzZTY0JykpIH0pKSxcbiAgICBwMnBNZXNzYWdlczogdHJhbnNmZXJzXG4gICAgICAuZmlsdGVyKCh0KTogdCBpcyBWcmZNZXNzYWdlVHJhbnNmZXIgJiB7IHRvOiBudW1iZXIgfSA9PiB0LnRvID09PSBmb3JQYXJ0eSlcbiAgICAgIC5tYXAoKHQpID0+ICh7IGZyb206IHQuZnJvbSwgdG86IHQudG8sIHBheWxvYWQ6IG5ldyBVaW50OEFycmF5KEJ1ZmZlci5mcm9tKHQucGF5bG9hZCwgJ2Jhc2U2NCcpKSB9KSksXG4gIH07XG59XG5cbi8qKlxuICogQ29tYmluZXMgdGhlIHNpZ25pbmcga2V5c2hhcmUgd2l0aCB0aGUgVlJGIGtleXNoYXJlIGludG8gdGhlIGBlbmNyeXB0ZWRQcnZgIGVudmVsb3BlXG4gKiAoYGJhc2U2NChjYm9yRW5jb2RlKHt2ZXJzaW9uLCBwcnZLZXlTaGFyZSwgdnJmfSkpYCBvbmNlIHRoZSBjYWxsZXIgYmFzZTY0LWVuY29kZXMgdGhlXG4gKiByZXR1cm5lZCBidWZmZXJzKS4gVGhlIHNhbWUgY29udGFpbmVyIHdyYXBzIHRoZSByZWR1Y2VkIHNpZ25pbmcgc2hhcmUgZm9yXG4gKiBgcmVkdWNlZEVuY3J5cHRlZFBydmAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFZyZktleUVudmVsb3BlcyhcbiAgcHJpdmF0ZU1hdGVyaWFsOiBCdWZmZXIsXG4gIHJlZHVjZWRQcml2YXRlTWF0ZXJpYWw6IEJ1ZmZlcixcbiAgdnJmS2V5U2hhcmU6IEJ1ZmZlclxuKTogeyBlbnZlbG9wZTogQnVmZmVyOyByZWR1Y2VkRW52ZWxvcGU6IEJ1ZmZlciB9IHtcbiAgY29uc3QgZW52ZWxvcGUgPSBlbmNvZGUoe1xuICAgIHZlcnNpb246IFZSRl9LRVlfRU5WRUxPUEVfVkVSU0lPTixcbiAgICBwcnZLZXlTaGFyZTogbmV3IFVpbnQ4QXJyYXkocHJpdmF0ZU1hdGVyaWFsKSxcbiAgICB2cmY6IG5ldyBVaW50OEFycmF5KHZyZktleVNoYXJlKSxcbiAgfSk7XG4gIGNvbnN0IHJlZHVjZWRFbnZlbG9wZSA9IGVuY29kZSh7XG4gICAgdmVyc2lvbjogVlJGX0tFWV9FTlZFTE9QRV9WRVJTSU9OLFxuICAgIHBydktleVNoYXJlOiBuZXcgVWludDhBcnJheShyZWR1Y2VkUHJpdmF0ZU1hdGVyaWFsKSxcbiAgICB2cmY6IG5ldyBVaW50OEFycmF5KHZyZktleVNoYXJlKSxcbiAgfSk7XG4gIHJldHVybiB7IGVudmVsb3BlOiBCdWZmZXIuZnJvbShlbnZlbG9wZSksIHJlZHVjZWRFbnZlbG9wZTogQnVmZmVyLmZyb20ocmVkdWNlZEVudmVsb3BlKSB9O1xufVxuXG4vKipcbiAqIFBhcnNlcyBhIGRlY3J5cHRlZCByb290IGJsb2IgcHJvZHVjZWQgYnkge0BsaW5rIGJ1aWxkVnJmS2V5RW52ZWxvcGVzfTogYSBDQk9SXG4gKiBlbnZlbG9wZSBge3ZlcnNpb246IDEsIHBydktleVNoYXJlLCB2cmZ9YC4gUmV0dXJucyB0aGUgc2lnbmluZyBhbmQgVlJGIGtleXNoYXJlc1xuICogYXMgQnVmZmVycy4gVGhyb3dzIGlmIHRoZSBibG9iIGlzIG5vdCBhIHZhbGlkIFZSRiBrZXkgZW52ZWxvcGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVZyZktleUVudmVsb3BlcyhkZWNyeXB0ZWRCbG9iOiBzdHJpbmcpOiB7IHNpZ25pbmc6IEJ1ZmZlcjsgdnJmOiBCdWZmZXIgfSB7XG4gIGxldCBlbnZlbG9wZTogdW5rbm93bjtcbiAgdHJ5IHtcbiAgICBlbnZlbG9wZSA9IGRlY29kZShCdWZmZXIuZnJvbShkZWNyeXB0ZWRCbG9iLCAnYmFzZTY0JykpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc3QgbWVzc2FnZSA9IGUgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IFN0cmluZyhlKTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBkZWNvZGUgc2FmZSBNUEMgcm9vdCBrZXkgZW52ZWxvcGU6ICR7bWVzc2FnZX1gKTtcbiAgfVxuICBpZiAoIWlzVnJmS2V5RW52ZWxvcGUoZW52ZWxvcGUpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHNhZmUgTVBDIHJvb3Qga2V5IGVudmVsb3BlOiBleHBlY3RlZCB2ZXJzaW9uLCBzaWduaW5nIGtleXNoYXJlLCBhbmQgVlJGIGtleXNoYXJlJyk7XG4gIH1cbiAgY29uc3QgeyB2ZXJzaW9uLCBwcnZLZXlTaGFyZSwgdnJmIH0gPSBlbnZlbG9wZTtcbiAgaWYgKHZlcnNpb24gIT09IFZSRl9LRVlfRU5WRUxPUEVfVkVSU0lPTikge1xuICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgc2FmZSBNUEMgcm9vdCBrZXkgZW52ZWxvcGUgdmVyc2lvbjogJHtTdHJpbmcodmVyc2lvbil9YCk7XG4gIH1cbiAgaWYgKCEocHJ2S2V5U2hhcmUgaW5zdGFuY2VvZiBVaW50OEFycmF5KSB8fCBwcnZLZXlTaGFyZS5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1NhZmUgTVBDIHJvb3Qga2V5IGVudmVsb3BlIGlzIG1pc3NpbmcgYSBzaWduaW5nIGtleXNoYXJlJyk7XG4gIH1cbiAgaWYgKCEodnJmIGluc3RhbmNlb2YgVWludDhBcnJheSkgfHwgdnJmLmxlbmd0aCA9PT0gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2FmZSBNUEMgcm9vdCBrZXkgZW52ZWxvcGUgaXMgbWlzc2luZyBhIFZSRiBrZXlzaGFyZScpO1xuICB9XG4gIHJldHVybiB7IHNpZ25pbmc6IEJ1ZmZlci5mcm9tKHBydktleVNoYXJlKSwgdnJmOiBCdWZmZXIuZnJvbSh2cmYpIH07XG59XG5cbi8qKlxuICogRW5jb2RlcyBhIGhhcmRlbmVkIGRlcml2YXRpb24gaW5kZXggYXMgdGhlIGJ5dGUgcGF0aCB0aGUgREtMUyBoYXJkLWRlcml2ZSB3YXNtXG4gKiBleHBlY3RzOiBvbmUgYmlnLWVuZGlhbiB1MzIgd2l0aCB0aGUgaGFyZGVuZWQgYml0ICgweDgwMDAwMDAwKSBzZXQg4oCUIGkuZS4gdGhlXG4gKiBjaGlsZCBwYXRoIGBtLzxpbmRleD4nYC4gVGhlIHNlcnZlciBkZXJpdmVzIHRoZSBzYW1lIGhhcmRlbmVkIHBhdGggZnJvbSB0aGVcbiAqIGBkZXJpdmF0aW9uSW5kZXhgIGl0IHJlY2VpdmVzIG9uIHJvdW5kIDEuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXJkZW5lZERlcml2YXRpb25QYXRoKGluZGV4OiBudW1iZXIpOiBVaW50OEFycmF5IHtcbiAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKGluZGV4KSB8fCBpbmRleCA8IDAgfHwgaW5kZXggPiAweDdmZmZmZmZmKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGRlcml2YXRpb24gaW5kZXg6ICR7aW5kZXh9YCk7XG4gIH1cbiAgcmV0dXJuIG5ldyBVaW50OEFycmF5KFsweDgwIHwgKGluZGV4ID4+PiAyNCksIChpbmRleCA+Pj4gMTYpICYgMHhmZiwgKGluZGV4ID4+PiA4KSAmIDB4ZmYsIGluZGV4ICYgMHhmZl0pO1xufVxuXG4vKipcbiAqIEVjZHNhTVBDdjJVdGlscyB2YXJpYW50IHRoYXQgcnVucyB0aGUgUmlzdHJldHRvIFZSRiBES0cgYWxvbmdzaWRlIHRoZSBzaWduaW5nIERLTFNcbiAqIERLRyBpbnNpZGUgdGhlIHNhbWUgTVBDdjIga2V5Z2VuIHJvdW5kcywgZm9yIHNhZmUgTVBDIHJvb3QgY3JlYXRpb24uXG4gKlxuICogVGhlIHJvdW5kIGVudW0gaXMgdW5jaGFuZ2VkOiB0aGUgVlJGIGNvbW1pdG1lbnQgcmlkZXMgTVBDdjItUjEsIHRoZSBvcGVuaW5nIHJpZGVzXG4gKiBNUEN2Mi1SMiwgYW5kIHRoZSBWUkYgREtHIGZpbmFsaXplcyBsb2NhbGx5IGJlZm9yZSBNUEN2Mi1SMy4gVlJGIG1lc3NhZ2VzIHRyYXZlbCBhc1xuICogb3BhcXVlIGJhc2U2NCBmaWVsZHMgb24gdGhlIHJvdW5kIHBheWxvYWRzLCBuZXZlciB0aHJvdWdoIHRoZSBES0xTIGJyb2FkY2FzdC9wMnAgc2xvdHMuXG4gKiBBdCB0aGUgZW5kLCB0aGUgc2lnbmluZyBhbmQgVlJGIGtleXNoYXJlcyBhcmUgY29tYmluZWQgaW50byBhIHNpbmdsZSBDQk9SIGVudmVsb3BlXG4gKiBiZWZvcmUgZW5jcnlwdGlvbi5cbiAqL1xuZXhwb3J0IGNsYXNzIEVjZHNhVnJmTVBDdjJVdGlscyBleHRlbmRzIEVjZHNhTVBDdjJVdGlscyB7XG4gIC8qKiBAaW5oZXJpdGRvYyAqL1xuICBhc3luYyBjcmVhdGVLZXljaGFpbnMocGFyYW1zOiB7XG4gICAgcGFzc3BocmFzZTogc3RyaW5nO1xuICAgIGVudGVycHJpc2U6IHN0cmluZztcbiAgICBvcmlnaW5hbFBhc3Njb2RlRW5jcnlwdGlvbkNvZGU/OiBzdHJpbmc7XG4gICAgcmV0cm9maXQ/OiBEZWNyeXB0ZWRSZXRyb2ZpdFBheWxvYWQ7XG4gICAgd2ViYXV0aG5JbmZvPzogV2ViYXV0aG5LZXlFbmNyeXB0aW9uSW5mbztcbiAgICBlbmNyeXB0aW9uVmVyc2lvbj86IEVuY3J5cHRpb25WZXJzaW9uO1xuICAgIC8vIFRhZ3MgdGhlIHJlc3VsdGluZyB1c2VyL2JhY2t1cC9iaXRnbyByb290IGtleXMgd2l0aCB0aGlzIHNhZmUuXG4gICAgc2FmZUlkOiBzdHJpbmc7XG4gIH0pOiBQcm9taXNlPEtleWNoYWluc1RyaXBsZXQ+IHtcbiAgICBjb25zdCB7IHVzZXJTZXNzaW9uLCBiYWNrdXBTZXNzaW9uIH0gPSB0aGlzLmNyZWF0ZVNpZ25pbmdEa2dTZXNzaW9ucyhwYXJhbXMucmV0cm9maXQpO1xuICAgIGNvbnN0IHVzZXJWcmZTZXNzaW9uID0gbmV3IERrbHNWcmYuVnJmRGtnKDMsIDIsIE1QQ3YyUGFydGllc0VudW0uVVNFUik7XG4gICAgY29uc3QgYmFja3VwVnJmU2Vzc2lvbiA9IG5ldyBEa2xzVnJmLlZyZkRrZygzLCAyLCBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCk7XG5cbiAgICBjb25zdCB1c2VyR3BnS2V5ID0gYXdhaXQgZ2VuZXJhdGVHUEdLZXlQYWlyKCdzZWNwMjU2azEnKTtcbiAgICBjb25zdCBiYWNrdXBHcGdLZXkgPSBhd2FpdCBnZW5lcmF0ZUdQR0tleVBhaXIoJ3NlY3AyNTZrMScpO1xuXG4gICAgLy8gR2V0IHRoZSBCaXRHbyBwdWJsaWMga2V5IGJhc2VkIG9uIHVzZXIvZW50ZXJwcmlzZSBmZWF0dXJlIGZsYWdzXG4gICAgLy8gSWYgaXQgZG9lc24ndCB3b3JrLCB1c2UgdGhlIGRlZmF1bHQgcHVibGljIGtleSBmcm9tIHRoZSBjb25zdGFudHNcbiAgICBjb25zdCB7IG1wY3YyUHVibGljS2V5IH0gPSBhd2FpdCB0aGlzLmdldEJpdGdvR3BnUHVia2V5QmFzZWRPbkZlYXR1cmVGbGFncyhwYXJhbXMuZW50ZXJwcmlzZSwgdHJ1ZSk7XG4gICAgY29uc3QgbXBjdjJLZXkgPSBtcGN2MlB1YmxpY0tleSA/PyB0aGlzLmJpdGdvTVBDdjJQdWJsaWNHcGdLZXk7XG4gICAgYXNzZXJ0KG1wY3YyS2V5LCAnRmFpbGVkIHRvIGdldCBCaXRHbyBNUEN2MiBHUEcgcHVibGljIGtleScpO1xuICAgIGNvbnN0IGJpdGdvUHVibGljR3BnS2V5ID0gbXBjdjJLZXkuYXJtb3IoKTtcblxuICAgIGlmIChlbnZSZXF1aXJlc0JpdGdvUHViR3BnS2V5Q29uZmlnKHRoaXMuYml0Z28uZ2V0RW52KCkpKSB7XG4gICAgICAvLyBFbnN1cmUgdGhlIHB1YmxpYyBrZXkgaXMgb25lIG9mIHRoZSBleHBlY3RlZCBCaXRHbyBwdWJsaWMga2V5cyB3aGVuIGluIHRlc3Qgb3IgcHJvZC5cbiAgICAgIGFzc2VydChpc0JpdGdvTXBjUHViS2V5KGJpdGdvUHVibGljR3BnS2V5LCAnbXBjdjInKSwgJ0ludmFsaWQgQml0R28gR1BHIHB1YmxpYyBrZXknKTtcbiAgICB9XG5cbiAgICBjb25zdCB1c2VyR3BnUHJ2S2V5OiBEa2xzVHlwZXMuUGFydHlHcGdLZXkgPSB7XG4gICAgICBwYXJ0eUlkOiBNUEN2MlBhcnRpZXNFbnVtLlVTRVIsXG4gICAgICBncGdLZXk6IHVzZXJHcGdLZXkucHJpdmF0ZUtleSxcbiAgICB9O1xuICAgIGNvbnN0IGJhY2t1cEdwZ1BydktleTogRGtsc1R5cGVzLlBhcnR5R3BnS2V5ID0ge1xuICAgICAgcGFydHlJZDogTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVAsXG4gICAgICBncGdLZXk6IGJhY2t1cEdwZ0tleS5wcml2YXRlS2V5LFxuICAgIH07XG4gICAgY29uc3QgYml0Z29HcGdQdWJLZXk6IERrbHNUeXBlcy5QYXJ0eUdwZ0tleSA9IHtcbiAgICAgIHBhcnR5SWQ6IE1QQ3YyUGFydGllc0VudW0uQklUR08sXG4gICAgICBncGdLZXk6IGJpdGdvUHVibGljR3BnS2V5LFxuICAgIH07XG5cbiAgICAvLyAjcmVnaW9uIHJvdW5kIDFcbiAgICBjb25zdCB1c2VyUm91bmQxQnJvYWRjYXN0TXNnID0gYXdhaXQgdXNlclNlc3Npb24uaW5pdERrZygpO1xuICAgIGNvbnN0IGJhY2t1cFJvdW5kMUJyb2FkY2FzdE1zZyA9IGF3YWl0IGJhY2t1cFNlc3Npb24uaW5pdERrZygpO1xuICAgIGNvbnN0IHVzZXJWcmZSb3VuZDFNc2cgPSBhd2FpdCB1c2VyVnJmU2Vzc2lvbi5pbml0RGtnKCk7XG4gICAgY29uc3QgYmFja3VwVnJmUm91bmQxTXNnID0gYXdhaXQgYmFja3VwVnJmU2Vzc2lvbi5pbml0RGtnKCk7XG5cbiAgICBjb25zdCByb3VuZDFTZXJpYWxpemVkTWVzc2FnZXMgPSBEa2xzVHlwZXMuc2VyaWFsaXplTWVzc2FnZXMoe1xuICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFt1c2VyUm91bmQxQnJvYWRjYXN0TXNnLCBiYWNrdXBSb3VuZDFCcm9hZGNhc3RNc2ddLFxuICAgICAgcDJwTWVzc2FnZXM6IFtdLFxuICAgIH0pO1xuICAgIGNvbnN0IHJvdW5kMU1lc3NhZ2VzID0gYXdhaXQgRGtsc0NvbW1zLmVuY3J5cHRBbmRBdXRoT3V0Z29pbmdNZXNzYWdlcyhcbiAgICAgIHJvdW5kMVNlcmlhbGl6ZWRNZXNzYWdlcyxcbiAgICAgIFtiaXRnb0dwZ1B1YktleV0sXG4gICAgICBbdXNlckdwZ1BydktleSwgYmFja3VwR3BnUHJ2S2V5XVxuICAgICk7XG4gICAgY29uc3QgdXNlck1zZzEgPSByb3VuZDFNZXNzYWdlcy5icm9hZGNhc3RNZXNzYWdlcy5maW5kKChtKSA9PiBtLmZyb20gPT09IE1QQ3YyUGFydGllc0VudW0uVVNFUik/LnBheWxvYWQ7XG4gICAgY29uc3QgYmFja3VwTXNnMSA9IHJvdW5kMU1lc3NhZ2VzLmJyb2FkY2FzdE1lc3NhZ2VzLmZpbmQoKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVApPy5wYXlsb2FkO1xuICAgIGFzc2VydCh1c2VyTXNnMSwgJ1VzZXIgbWVzc2FnZSAxIG5vdCBmb3VuZCBpbiBicm9hZGNhc3QgbWVzc2FnZXMnKTtcbiAgICBhc3NlcnQoYmFja3VwTXNnMSwgJ0JhY2t1cCBtZXNzYWdlIDEgbm90IGZvdW5kIGluIGJyb2FkY2FzdCBtZXNzYWdlcycpO1xuXG4gICAgY29uc3QgdXNlckdwZ1B1YmxpY0tleSA9IHVzZXJHcGdLZXkucHVibGljS2V5O1xuICAgIGNvbnN0IGJhY2t1cEdwZ1B1YmxpY0tleSA9IGJhY2t1cEdwZ0tleS5wdWJsaWNLZXk7XG4gICAgYXNzZXJ0KE5vbkVtcHR5U3RyaW5nLmlzKHVzZXJHcGdQdWJsaWNLZXkpLCAnVXNlciBHUEcgcHVibGljIGtleSBpcyByZXF1aXJlZCcpO1xuICAgIGFzc2VydChOb25FbXB0eVN0cmluZy5pcyhiYWNrdXBHcGdQdWJsaWNLZXkpLCAnQmFja3VwIEdQRyBwdWJsaWMga2V5IGlzIHJlcXVpcmVkJyk7XG4gICAgLy8gS2VlcCBWUkYgbWVzc2FnZXMgb3BhcXVlIG9uIHRoZSBrZXktZ2VuZXJhdGlvbiByZXF1ZXN0LlxuICAgIGNvbnN0IHJvdW5kMVNlbmRlciA9IEtleUdlblNlbmRlckZvckVudGVycHJpc2U8TVBDdjJLZXlHZW5Sb3VuZDFSZXNwb25zZSAmIE1wY1YyVnJmS2V5R2VuUmVzcG9uc2VGaWVsZHM+KFxuICAgICAgdGhpcy5iaXRnbyxcbiAgICAgIHBhcmFtcy5lbnRlcnByaXNlLFxuICAgICAgcGFyYW1zLnNhZmVJZFxuICAgICk7XG4gICAgY29uc3QgeyBzZXNzaW9uSWQsIGJpdGdvTXNnMSwgYml0Z29Ub0JhY2t1cE1zZzIsIGJpdGdvVG9Vc2VyTXNnMiwgYml0Z29WcmZNc2cxIH0gPSBhd2FpdCByb3VuZDFTZW5kZXIoXG4gICAgICBNUEN2MktleUdlblN0YXRlRW51bVsnTVBDdjItUjEnXSxcbiAgICAgIHtcbiAgICAgICAgdXNlck1zZzE6IHsgZnJvbTogTVBDdjJQYXJ0aWVzRW51bS5VU0VSLCAuLi51c2VyTXNnMSB9LFxuICAgICAgICBiYWNrdXBNc2cxOiB7IGZyb206IE1QQ3YyUGFydGllc0VudW0uQkFDS1VQLCAuLi5iYWNrdXBNc2cxIH0sXG4gICAgICAgIHVzZXJHcGdQdWJsaWNLZXksXG4gICAgICAgIGJhY2t1cEdwZ1B1YmxpY0tleSxcbiAgICAgICAgdXNlclZyZk1zZzE6IHNlcmlhbGl6ZVZyZk1lc3NhZ2VzKHVzZXJWcmZSb3VuZDFNc2cpLFxuICAgICAgICBiYWNrdXBWcmZNc2cxOiBzZXJpYWxpemVWcmZNZXNzYWdlcyhiYWNrdXBWcmZSb3VuZDFNc2cpLFxuICAgICAgICB3YWxsZXRJZDogcGFyYW1zLnJldHJvZml0Py53YWxsZXRJZCxcbiAgICAgIH1cbiAgICApO1xuICAgIGFzc2VydChiaXRnb1ZyZk1zZzEsICdCaXRHbyBWUkYgbWVzc2FnZSAxIG5vdCBmb3VuZCBpbiByb3VuZCAxIHJlc3BvbnNlJyk7XG4gICAgLy8gI2VuZHJlZ2lvblxuXG4gICAgLy8gI3JlZ2lvbiByb3VuZCAyXG4gICAgY29uc3QgYml0Z29Sb3VuZDFCcm9hZGNhc3RNZXNzYWdlcyA9IGF3YWl0IERrbHNDb21tcy5kZWNyeXB0QW5kVmVyaWZ5SW5jb21pbmdNZXNzYWdlcyhcbiAgICAgIHsgcDJwTWVzc2FnZXM6IFtdLCBicm9hZGNhc3RNZXNzYWdlczogW3RoaXMuZm9ybWF0Qml0Z29Ccm9hZGNhc3RNZXNzYWdlKGJpdGdvTXNnMSldIH0sXG4gICAgICBbYml0Z29HcGdQdWJLZXldLFxuICAgICAgW3VzZXJHcGdQcnZLZXksIGJhY2t1cEdwZ1BydktleV1cbiAgICApO1xuICAgIGNvbnN0IGJpdGdvUm91bmQxQnJvYWRjYXN0TXNnID0gYml0Z29Sb3VuZDFCcm9hZGNhc3RNZXNzYWdlcy5icm9hZGNhc3RNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CSVRHT1xuICAgICk7XG4gICAgYXNzZXJ0KGJpdGdvUm91bmQxQnJvYWRjYXN0TXNnLCAnQml0R28gbWVzc2FnZSAxIG5vdCBmb3VuZCBpbiBicm9hZGNhc3QgbWVzc2FnZXMnKTtcblxuICAgIGNvbnN0IHVzZXJSb3VuZDJQMlBNZXNzYWdlcyA9IHVzZXJTZXNzaW9uLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgICAgcDJwTWVzc2FnZXM6IFtdLFxuICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtEa2xzVHlwZXMuZGVzZXJpYWxpemVCcm9hZGNhc3RNZXNzYWdlKGJpdGdvUm91bmQxQnJvYWRjYXN0TXNnKSwgYmFja3VwUm91bmQxQnJvYWRjYXN0TXNnXSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHVzZXJUb0JpdGdvTXNnMiA9IHVzZXJSb3VuZDJQMlBNZXNzYWdlcy5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSICYmIG0udG8gPT09IE1QQ3YyUGFydGllc0VudW0uQklUR09cbiAgICApO1xuICAgIGFzc2VydCh1c2VyVG9CaXRnb01zZzIsICdVc2VyIG1lc3NhZ2UgMiBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG4gICAgY29uc3Qgc2VyaWFsaXplZFVzZXJUb0JpdGdvTXNnMiA9IERrbHNUeXBlcy5zZXJpYWxpemVQMlBNZXNzYWdlKHVzZXJUb0JpdGdvTXNnMik7XG5cbiAgICBjb25zdCBiYWNrdXBSb3VuZDJQMlBNZXNzYWdlcyA9IGJhY2t1cFNlc3Npb24uaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgICBwMnBNZXNzYWdlczogW10sXG4gICAgICBicm9hZGNhc3RNZXNzYWdlczogW3VzZXJSb3VuZDFCcm9hZGNhc3RNc2csIERrbHNUeXBlcy5kZXNlcmlhbGl6ZUJyb2FkY2FzdE1lc3NhZ2UoYml0Z29Sb3VuZDFCcm9hZGNhc3RNc2cpXSxcbiAgICB9KTtcbiAgICBjb25zdCBzZXJpYWxpemVkQmFja3VwVG9CaXRnb01zZzIgPSBEa2xzVHlwZXMuc2VyaWFsaXplTWVzc2FnZXMoYmFja3VwUm91bmQyUDJQTWVzc2FnZXMpLnAycE1lc3NhZ2VzLmZpbmQoXG4gICAgICAobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCAmJiBtLnRvID09PSBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPXG4gICAgKTtcbiAgICBhc3NlcnQoc2VyaWFsaXplZEJhY2t1cFRvQml0Z29Nc2cyLCAnQmFja3VwIG1lc3NhZ2UgMiBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG5cbiAgICAvLyBWUkY6IGNvbnN1bWUgQml0R28ncyBhbmQgdGhlIGNvdW50ZXJwYXJ0eSdzIGNvbW1pdG1lbnRzLCBlbWl0IHRoaXMgcGFydHkncyBvcGVuaW5ncy5cbiAgICAvLyBPcGVuaW5ncyBjb21lIGJhY2sgYXMgcDJwIG1lc3NhZ2VzIGFkZHJlc3NlZCB0byBlYWNoIHBhcnR5IChpbmNsdWRpbmcgdGhlIHNlbmRlcikuXG4gICAgY29uc3QgdXNlclZyZlJvdW5kMk1lc3NhZ2VzID0gYXdhaXQgdXNlclZyZlNlc3Npb24uaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgICBicm9hZGNhc3RNZXNzYWdlczogW1xuICAgICAgICAuLi5iYWNrdXBWcmZSb3VuZDFNc2cuYnJvYWRjYXN0TWVzc2FnZXMsXG4gICAgICAgIC4uLmRlc2VyaWFsaXplVnJmTWVzc2FnZXMoYml0Z29WcmZNc2cxLCBNUEN2MlBhcnRpZXNFbnVtLlVTRVIpLmJyb2FkY2FzdE1lc3NhZ2VzLFxuICAgICAgXSxcbiAgICAgIHAycE1lc3NhZ2VzOiBbXSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGJhY2t1cFZyZlJvdW5kMk1lc3NhZ2VzID0gYXdhaXQgYmFja3VwVnJmU2Vzc2lvbi5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKHtcbiAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbXG4gICAgICAgIC4uLnVzZXJWcmZSb3VuZDFNc2cuYnJvYWRjYXN0TWVzc2FnZXMsXG4gICAgICAgIC4uLmRlc2VyaWFsaXplVnJmTWVzc2FnZXMoYml0Z29WcmZNc2cxLCBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCkuYnJvYWRjYXN0TWVzc2FnZXMsXG4gICAgICBdLFxuICAgICAgcDJwTWVzc2FnZXM6IFtdLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgcm91bmQyTWVzc2FnZXMgPSBhd2FpdCBEa2xzQ29tbXMuZW5jcnlwdEFuZEF1dGhPdXRnb2luZ01lc3NhZ2VzKFxuICAgICAgeyBwMnBNZXNzYWdlczogW3NlcmlhbGl6ZWRVc2VyVG9CaXRnb01zZzIsIHNlcmlhbGl6ZWRCYWNrdXBUb0JpdGdvTXNnMl0sIGJyb2FkY2FzdE1lc3NhZ2VzOiBbXSB9LFxuICAgICAgW2JpdGdvR3BnUHViS2V5XSxcbiAgICAgIFt1c2VyR3BnUHJ2S2V5LCBiYWNrdXBHcGdQcnZLZXldXG4gICAgKTtcbiAgICBjb25zdCB1c2VyUm91bmQyTXNnID0gcm91bmQyTWVzc2FnZXMucDJwTWVzc2FnZXMuZmluZChcbiAgICAgIChtKSA9PiBtLmZyb20gPT09IE1QQ3YyUGFydGllc0VudW0uVVNFUiAmJiBtLnRvID09PSBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPXG4gICAgKTtcbiAgICBjb25zdCBiYWNrdXBSb3VuZDJNc2cgPSByb3VuZDJNZXNzYWdlcy5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVAgJiYgbS50byA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CSVRHT1xuICAgICk7XG4gICAgYXNzZXJ0KHVzZXJSb3VuZDJNc2csICdVc2VyIHRvIEJpdGdvIG1lc3NhZ2UgMiBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG4gICAgYXNzZXJ0KHVzZXJSb3VuZDJNc2cuY29tbWl0bWVudCwgJ1VzZXIgdG8gQml0Z28gY29tbWl0bWVudCBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG4gICAgYXNzZXJ0KGJhY2t1cFJvdW5kMk1zZywgJ0JhY2t1cCB0byBCaXRnbyBtZXNzYWdlIDIgbm90IGZvdW5kIGluIFAyUCBtZXNzYWdlcycpO1xuICAgIGFzc2VydChiYWNrdXBSb3VuZDJNc2cuY29tbWl0bWVudCwgJ0JhY2t1cCB0byBCaXRnbyBjb21taXRtZW50IG5vdCBmb3VuZCBpbiBQMlAgbWVzc2FnZXMnKTtcbiAgICBhc3NlcnQoTm9uRW1wdHlTdHJpbmcuaXModXNlclJvdW5kMk1zZy5jb21taXRtZW50KSwgJ1VzZXIgdG8gQml0Z28gY29tbWl0bWVudCBpcyByZXF1aXJlZCcpO1xuICAgIGFzc2VydChOb25FbXB0eVN0cmluZy5pcyhiYWNrdXBSb3VuZDJNc2cuY29tbWl0bWVudCksICdCYWNrdXAgdG8gQml0Z28gY29tbWl0bWVudCBpcyByZXF1aXJlZCcpO1xuICAgIGNvbnN0IHJvdW5kMlNlbmRlciA9IEtleUdlblNlbmRlckZvckVudGVycHJpc2U8TVBDdjJLZXlHZW5Sb3VuZDJSZXNwb25zZSAmIE1wY1YyVnJmS2V5R2VuUmVzcG9uc2VGaWVsZHM+KFxuICAgICAgdGhpcy5iaXRnbyxcbiAgICAgIHBhcmFtcy5lbnRlcnByaXNlXG4gICAgKTtcbiAgICBjb25zdCB7XG4gICAgICBzZXNzaW9uSWQ6IHNlc3Npb25JZFJvdW5kMixcbiAgICAgIGJpdGdvQ29tbWl0bWVudDIsXG4gICAgICBiaXRnb1RvVXNlck1zZzMsXG4gICAgICBiaXRnb1RvQmFja3VwTXNnMyxcbiAgICAgIGJpdGdvVnJmTXNnMixcbiAgICB9ID0gYXdhaXQgcm91bmQyU2VuZGVyKE1QQ3YyS2V5R2VuU3RhdGVFbnVtWydNUEN2Mi1SMiddLCB7XG4gICAgICBzZXNzaW9uSWQsXG4gICAgICB1c2VyTXNnMjoge1xuICAgICAgICBmcm9tOiBNUEN2MlBhcnRpZXNFbnVtLlVTRVIsXG4gICAgICAgIHRvOiBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPLFxuICAgICAgICBzaWduYXR1cmU6IHVzZXJSb3VuZDJNc2cucGF5bG9hZC5zaWduYXR1cmUsXG4gICAgICAgIGVuY3J5cHRlZE1lc3NhZ2U6IHVzZXJSb3VuZDJNc2cucGF5bG9hZC5lbmNyeXB0ZWRNZXNzYWdlLFxuICAgICAgfSxcbiAgICAgIHVzZXJDb21taXRtZW50MjogdXNlclJvdW5kMk1zZy5jb21taXRtZW50LFxuICAgICAgYmFja3VwTXNnMjoge1xuICAgICAgICBmcm9tOiBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCxcbiAgICAgICAgdG86IE1QQ3YyUGFydGllc0VudW0uQklUR08sXG4gICAgICAgIHNpZ25hdHVyZTogYmFja3VwUm91bmQyTXNnLnBheWxvYWQuc2lnbmF0dXJlLFxuICAgICAgICBlbmNyeXB0ZWRNZXNzYWdlOiBiYWNrdXBSb3VuZDJNc2cucGF5bG9hZC5lbmNyeXB0ZWRNZXNzYWdlLFxuICAgICAgfSxcbiAgICAgIGJhY2t1cENvbW1pdG1lbnQyOiBiYWNrdXBSb3VuZDJNc2cuY29tbWl0bWVudCxcbiAgICAgIHVzZXJWcmZNc2cyOiBzZXJpYWxpemVWcmZNZXNzYWdlcyh1c2VyVnJmUm91bmQyTWVzc2FnZXMpLFxuICAgICAgYmFja3VwVnJmTXNnMjogc2VyaWFsaXplVnJmTWVzc2FnZXMoYmFja3VwVnJmUm91bmQyTWVzc2FnZXMpLFxuICAgIH0pO1xuICAgIC8vICNlbmRyZWdpb25cblxuICAgIC8vICNyZWdpb24gcm91bmQgM1xuICAgIGFzc2VydC5lcXVhbChzZXNzaW9uSWQsIHNlc3Npb25JZFJvdW5kMiwgJ1JvdW5kIDEgYW5kIDIgU2Vzc2lvbiBJRHMgZG8gbm90IG1hdGNoJyk7XG4gICAgYXNzZXJ0KGJpdGdvVnJmTXNnMiwgJ0JpdEdvIFZSRiBtZXNzYWdlIDIgbm90IGZvdW5kIGluIHJvdW5kIDIgcmVzcG9uc2UnKTtcblxuICAgIC8vIFZSRjogZmluYWxpemUgYm90aCBES0dzIGxvY2FsbHkgYnkgY29uc3VtaW5nIHRoZSBvcGVuaW5nIG1lc3NhZ2VzIGFkZHJlc3NlZCB0byBlYWNoXG4gICAgLy8gcGFydHkgKGluY2x1ZGluZyBlYWNoIHBhcnR5J3Mgb3duKSBmcm9tIHRoZSBSMiBleGNoYW5nZXMuIFRoZSBWUkYgREtHIGNvbXBsZXRlcyBoZXJlLFxuICAgIC8vIGEgZnVsbCByb3VuZCBvZiBzbGFjayBiZWZvcmUgTVBDdjItUjMuXG4gICAgYXdhaXQgdXNlclZyZlNlc3Npb24uaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgICBicm9hZGNhc3RNZXNzYWdlczogW10sXG4gICAgICBwMnBNZXNzYWdlczogW1xuICAgICAgICAuLi51c2VyVnJmUm91bmQyTWVzc2FnZXMucDJwTWVzc2FnZXMuZmlsdGVyKChtKSA9PiBtLnRvID09PSBNUEN2MlBhcnRpZXNFbnVtLlVTRVIpLFxuICAgICAgICAuLi5iYWNrdXBWcmZSb3VuZDJNZXNzYWdlcy5wMnBNZXNzYWdlcy5maWx0ZXIoKG0pID0+IG0udG8gPT09IE1QQ3YyUGFydGllc0VudW0uVVNFUiksXG4gICAgICAgIC4uLmRlc2VyaWFsaXplVnJmTWVzc2FnZXMoYml0Z29WcmZNc2cyLCBNUEN2MlBhcnRpZXNFbnVtLlVTRVIpLnAycE1lc3NhZ2VzLFxuICAgICAgXSxcbiAgICB9KTtcbiAgICBhd2FpdCBiYWNrdXBWcmZTZXNzaW9uLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtdLFxuICAgICAgcDJwTWVzc2FnZXM6IFtcbiAgICAgICAgLi4udXNlclZyZlJvdW5kMk1lc3NhZ2VzLnAycE1lc3NhZ2VzLmZpbHRlcigobSkgPT4gbS50byA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVApLFxuICAgICAgICAuLi5iYWNrdXBWcmZSb3VuZDJNZXNzYWdlcy5wMnBNZXNzYWdlcy5maWx0ZXIoKG0pID0+IG0udG8gPT09IE1QQ3YyUGFydGllc0VudW0uQkFDS1VQKSxcbiAgICAgICAgLi4uZGVzZXJpYWxpemVWcmZNZXNzYWdlcyhiaXRnb1ZyZk1zZzIsIE1QQ3YyUGFydGllc0VudW0uQkFDS1VQKS5wMnBNZXNzYWdlcyxcbiAgICAgIF0sXG4gICAgfSk7XG5cbiAgICBjb25zdCBkZWNyeXB0ZWRCaXRnb1RvVXNlclJvdW5kMk1zZ3MgPSBhd2FpdCBEa2xzQ29tbXMuZGVjcnlwdEFuZFZlcmlmeUluY29taW5nTWVzc2FnZXMoXG4gICAgICB7IHAycE1lc3NhZ2VzOiBbdGhpcy5mb3JtYXRQMlBNZXNzYWdlKGJpdGdvVG9Vc2VyTXNnMildLCBicm9hZGNhc3RNZXNzYWdlczogW10gfSxcbiAgICAgIFtiaXRnb0dwZ1B1YktleV0sXG4gICAgICBbdXNlckdwZ1BydktleV1cbiAgICApO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRCaXRnb1RvVXNlclJvdW5kMk1zZyA9IGRlY3J5cHRlZEJpdGdvVG9Vc2VyUm91bmQyTXNncy5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyAmJiBtLnRvID09PSBNUEN2MlBhcnRpZXNFbnVtLlVTRVJcbiAgICApO1xuICAgIGFzc2VydChzZXJpYWxpemVkQml0Z29Ub1VzZXJSb3VuZDJNc2csICdCaXRHbyB0byBVc2VyIG1lc3NhZ2UgMiBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG4gICAgY29uc3QgYml0Z29Ub1VzZXJSb3VuZDJNc2cgPSBEa2xzVHlwZXMuZGVzZXJpYWxpemVQMlBNZXNzYWdlKHNlcmlhbGl6ZWRCaXRnb1RvVXNlclJvdW5kMk1zZyk7XG5cbiAgICBjb25zdCBkZWNyeXB0ZWRCaXRnb1RvQmFja3VwUm91bmQyTXNnID0gYXdhaXQgRGtsc0NvbW1zLmRlY3J5cHRBbmRWZXJpZnlJbmNvbWluZ01lc3NhZ2VzKFxuICAgICAgeyBwMnBNZXNzYWdlczogW3RoaXMuZm9ybWF0UDJQTWVzc2FnZShiaXRnb1RvQmFja3VwTXNnMildLCBicm9hZGNhc3RNZXNzYWdlczogW10gfSxcbiAgICAgIFtiaXRnb0dwZ1B1YktleV0sXG4gICAgICBbYmFja3VwR3BnUHJ2S2V5XVxuICAgICk7XG4gICAgY29uc3Qgc2VyaWFsaXplZEJpdGdvVG9CYWNrdXBSb3VuZDJNc2cgPSBkZWNyeXB0ZWRCaXRnb1RvQmFja3VwUm91bmQyTXNnLnAycE1lc3NhZ2VzLmZpbmQoXG4gICAgICAobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPICYmIG0udG8gPT09IE1QQ3YyUGFydGllc0VudW0uQkFDS1VQXG4gICAgKTtcbiAgICBhc3NlcnQoc2VyaWFsaXplZEJpdGdvVG9CYWNrdXBSb3VuZDJNc2csICdCaXRHbyB0byBCYWNrdXAgbWVzc2FnZSAyIG5vdCBmb3VuZCBpbiBQMlAgbWVzc2FnZXMnKTtcbiAgICBjb25zdCBiaXRnb1RvQmFja3VwUm91bmQyTXNnID0gRGtsc1R5cGVzLmRlc2VyaWFsaXplUDJQTWVzc2FnZShzZXJpYWxpemVkQml0Z29Ub0JhY2t1cFJvdW5kMk1zZyk7XG5cbiAgICBjb25zdCB1c2VyVG9CYWNrdXBNc2cyID0gdXNlclJvdW5kMlAyUE1lc3NhZ2VzLnAycE1lc3NhZ2VzLmZpbmQoXG4gICAgICAobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLlVTRVIgJiYgbS50byA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVBcbiAgICApO1xuICAgIGFzc2VydCh1c2VyVG9CYWNrdXBNc2cyLCAnVXNlciB0byBCYWNrdXAgbWVzc2FnZSAyIG5vdCBmb3VuZCBpbiBQMlAgbWVzc2FnZXMnKTtcblxuICAgIGNvbnN0IGJhY2t1cFRvVXNlck1zZzIgPSBiYWNrdXBSb3VuZDJQMlBNZXNzYWdlcy5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVAgJiYgbS50byA9PT0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSXG4gICAgKTtcbiAgICBhc3NlcnQoYmFja3VwVG9Vc2VyTXNnMiwgJ0JhY2t1cCB0byBVc2VyIG1lc3NhZ2UgMiBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG5cbiAgICBjb25zdCB1c2VyUm91bmQzTWVzc2FnZXMgPSB1c2VyU2Vzc2lvbi5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKHtcbiAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbXSxcbiAgICAgIHAycE1lc3NhZ2VzOiBbYml0Z29Ub1VzZXJSb3VuZDJNc2csIGJhY2t1cFRvVXNlck1zZzJdLFxuICAgIH0pO1xuICAgIGNvbnN0IHVzZXJUb0JhY2t1cE1zZzMgPSB1c2VyUm91bmQzTWVzc2FnZXMucDJwTWVzc2FnZXMuZmluZChcbiAgICAgIChtKSA9PiBtLmZyb20gPT09IE1QQ3YyUGFydGllc0VudW0uVVNFUiAmJiBtLnRvID09PSBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUFxuICAgICk7XG4gICAgYXNzZXJ0KHVzZXJUb0JhY2t1cE1zZzMsICdVc2VyIHRvIEJhY2t1cCBtZXNzYWdlIDMgbm90IGZvdW5kIGluIFAyUCBtZXNzYWdlcycpO1xuICAgIGNvbnN0IHVzZXJUb0JpdGdvTXNnMyA9IHVzZXJSb3VuZDNNZXNzYWdlcy5wMnBNZXNzYWdlcy5maW5kKFxuICAgICAgKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSICYmIG0udG8gPT09IE1QQ3YyUGFydGllc0VudW0uQklUR09cbiAgICApO1xuICAgIGFzc2VydCh1c2VyVG9CaXRnb01zZzMsICdVc2VyIHRvIEJpdGdvIG1lc3NhZ2UgMyBub3QgZm91bmQgaW4gUDJQIG1lc3NhZ2VzJyk7XG4gICAgY29uc3Qgc2VyaWFsaXplZFVzZXJUb0JpdGdvTXNnMyA9IERrbHNUeXBlcy5zZXJpYWxpemVQMlBNZXNzYWdlKHVzZXJUb0JpdGdvTXNnMyk7XG5cbiAgICBjb25zdCBiYWNrdXBSb3VuZDNNZXNzYWdlcyA9IGJhY2t1cFNlc3Npb24uaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgICBicm9hZGNhc3RNZXNzYWdlczogW10sXG4gICAgICBwMnBNZXNzYWdlczogW2JpdGdvVG9CYWNrdXBSb3VuZDJNc2csIHVzZXJUb0JhY2t1cE1zZzJdLFxuICAgIH0pO1xuXG4gICAgY29uc3QgYmFja3VwVG9Vc2VyTXNnMyA9IGJhY2t1cFJvdW5kM01lc3NhZ2VzLnAycE1lc3NhZ2VzLmZpbmQoXG4gICAgICAobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCAmJiBtLnRvID09PSBNUEN2MlBhcnRpZXNFbnVtLlVTRVJcbiAgICApO1xuICAgIGFzc2VydChiYWNrdXBUb1VzZXJNc2czLCAnQmFja3VwIHRvIFVzZXIgbWVzc2FnZSAzIG5vdCBmb3VuZCBpbiBQMlAgbWVzc2FnZXMnKTtcbiAgICBjb25zdCBiYWNrdXBUb0JpdGdvTXNnMyA9IGJhY2t1cFJvdW5kM01lc3NhZ2VzLnAycE1lc3NhZ2VzLmZpbmQoXG4gICAgICAobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCAmJiBtLnRvID09PSBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPXG4gICAgKTtcbiAgICBhc3NlcnQoYmFja3VwVG9CaXRnb01zZzMsICdCYWNrdXAgdG8gQml0Z28gbWVzc2FnZSAzIG5vdCBmb3VuZCBpbiBQMlAgbWVzc2FnZXMnKTtcbiAgICBjb25zdCBzZXJpYWxpemVkQmFja3VwVG9CaXRnb01zZzMgPSBEa2xzVHlwZXMuc2VyaWFsaXplUDJQTWVzc2FnZShiYWNrdXBUb0JpdGdvTXNnMyk7XG5cbiAgICBjb25zdCBkZWNyeXB0ZWRCaXRnb1RvVXNlclJvdW5kM01lc3NhZ2VzID0gYXdhaXQgRGtsc0NvbW1zLmRlY3J5cHRBbmRWZXJpZnlJbmNvbWluZ01lc3NhZ2VzKFxuICAgICAgeyBicm9hZGNhc3RNZXNzYWdlczogW10sIHAycE1lc3NhZ2VzOiBbdGhpcy5mb3JtYXRQMlBNZXNzYWdlKGJpdGdvVG9Vc2VyTXNnMywgYml0Z29Db21taXRtZW50MildIH0sXG4gICAgICBbYml0Z29HcGdQdWJLZXldLFxuICAgICAgW3VzZXJHcGdQcnZLZXldXG4gICAgKTtcbiAgICBjb25zdCBzZXJpYWxpemVkQml0Z29Ub1VzZXJSb3VuZDNNc2cgPSBkZWNyeXB0ZWRCaXRnb1RvVXNlclJvdW5kM01lc3NhZ2VzLnAycE1lc3NhZ2VzLmZpbmQoXG4gICAgICAobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPICYmIG0udG8gPT09IE1QQ3YyUGFydGllc0VudW0uVVNFUlxuICAgICk7XG4gICAgYXNzZXJ0KHNlcmlhbGl6ZWRCaXRnb1RvVXNlclJvdW5kM01zZywgJ0JpdEdvIHRvIFVzZXIgbWVzc2FnZSAzIG5vdCBmb3VuZCBpbiBQMlAgbWVzc2FnZXMnKTtcbiAgICBjb25zdCBiaXRnb1RvVXNlclJvdW5kM01zZyA9IERrbHNUeXBlcy5kZXNlcmlhbGl6ZVAyUE1lc3NhZ2Uoc2VyaWFsaXplZEJpdGdvVG9Vc2VyUm91bmQzTXNnKTtcblxuICAgIGNvbnN0IGRlY3J5cHRlZEJpdGdvVG9CYWNrdXBSb3VuZDNNZXNzYWdlcyA9IGF3YWl0IERrbHNDb21tcy5kZWNyeXB0QW5kVmVyaWZ5SW5jb21pbmdNZXNzYWdlcyhcbiAgICAgIHsgYnJvYWRjYXN0TWVzc2FnZXM6IFtdLCBwMnBNZXNzYWdlczogW3RoaXMuZm9ybWF0UDJQTWVzc2FnZShiaXRnb1RvQmFja3VwTXNnMywgYml0Z29Db21taXRtZW50MildIH0sXG4gICAgICBbYml0Z29HcGdQdWJLZXldLFxuICAgICAgW2JhY2t1cEdwZ1BydktleV1cbiAgICApO1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRCaXRnb1RvQmFja3VwUm91bmQzTXNnID0gZGVjcnlwdGVkQml0Z29Ub0JhY2t1cFJvdW5kM01lc3NhZ2VzLnAycE1lc3NhZ2VzLmZpbmQoXG4gICAgICAobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPICYmIG0udG8gPT09IE1QQ3YyUGFydGllc0VudW0uQkFDS1VQXG4gICAgKTtcbiAgICBhc3NlcnQoc2VyaWFsaXplZEJpdGdvVG9CYWNrdXBSb3VuZDNNc2csICdCaXRHbyB0byBCYWNrdXAgbWVzc2FnZSAzIG5vdCBmb3VuZCBpbiBQMlAgbWVzc2FnZXMnKTtcbiAgICBjb25zdCBiaXRnb1RvQmFja3VwUm91bmQzTXNnID0gRGtsc1R5cGVzLmRlc2VyaWFsaXplUDJQTWVzc2FnZShzZXJpYWxpemVkQml0Z29Ub0JhY2t1cFJvdW5kM01zZyk7XG5cbiAgICBjb25zdCB1c2VyUm91bmQ0TWVzc2FnZXMgPSB1c2VyU2Vzc2lvbi5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKHtcbiAgICAgIHAycE1lc3NhZ2VzOiBbYmFja3VwVG9Vc2VyTXNnMywgYml0Z29Ub1VzZXJSb3VuZDNNc2ddLFxuICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtdLFxuICAgIH0pO1xuXG4gICAgY29uc3QgdXNlclJvdW5kNEJyb2FkY2FzdE1zZyA9IHVzZXJSb3VuZDRNZXNzYWdlcy5icm9hZGNhc3RNZXNzYWdlcy5maW5kKChtKSA9PiBtLmZyb20gPT09IE1QQ3YyUGFydGllc0VudW0uVVNFUik7XG4gICAgYXNzZXJ0KHVzZXJSb3VuZDRCcm9hZGNhc3RNc2csICdVc2VyIG1lc3NhZ2UgNCBub3QgZm91bmQgaW4gYnJvYWRjYXN0IG1lc3NhZ2VzJyk7XG4gICAgY29uc3Qgc2VyaWFsaXplZFVzZXJSb3VuZDRCcm9hZGNhc3RNc2cgPSBEa2xzVHlwZXMuc2VyaWFsaXplQnJvYWRjYXN0TWVzc2FnZSh1c2VyUm91bmQ0QnJvYWRjYXN0TXNnKTtcblxuICAgIGNvbnN0IGJhY2t1cFJvdW5kNE1lc3NhZ2VzID0gYmFja3VwU2Vzc2lvbi5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKHtcbiAgICAgIHAycE1lc3NhZ2VzOiBbdXNlclRvQmFja3VwTXNnMywgYml0Z29Ub0JhY2t1cFJvdW5kM01zZ10sXG4gICAgICBicm9hZGNhc3RNZXNzYWdlczogW10sXG4gICAgfSk7XG4gICAgY29uc3QgYmFja3VwUm91bmQ0QnJvYWRjYXN0TXNnID0gYmFja3VwUm91bmQ0TWVzc2FnZXMuYnJvYWRjYXN0TWVzc2FnZXMuZmluZChcbiAgICAgIChtKSA9PiBtLmZyb20gPT09IE1QQ3YyUGFydGllc0VudW0uQkFDS1VQXG4gICAgKTtcbiAgICBhc3NlcnQoYmFja3VwUm91bmQ0QnJvYWRjYXN0TXNnLCAnQmFja3VwIG1lc3NhZ2UgNCBub3QgZm91bmQgaW4gYnJvYWRjYXN0IG1lc3NhZ2VzJyk7XG4gICAgY29uc3Qgc2VyaWFsaXplZEJhY2t1cFJvdW5kNEJyb2FkY2FzdE1zZyA9IERrbHNUeXBlcy5zZXJpYWxpemVCcm9hZGNhc3RNZXNzYWdlKGJhY2t1cFJvdW5kNEJyb2FkY2FzdE1zZyk7XG5cbiAgICBjb25zdCByb3VuZDNNZXNzYWdlcyA9IGF3YWl0IERrbHNDb21tcy5lbmNyeXB0QW5kQXV0aE91dGdvaW5nTWVzc2FnZXMoXG4gICAgICB7XG4gICAgICAgIHAycE1lc3NhZ2VzOiBbc2VyaWFsaXplZFVzZXJUb0JpdGdvTXNnMywgc2VyaWFsaXplZEJhY2t1cFRvQml0Z29Nc2czXSxcbiAgICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtzZXJpYWxpemVkVXNlclJvdW5kNEJyb2FkY2FzdE1zZywgc2VyaWFsaXplZEJhY2t1cFJvdW5kNEJyb2FkY2FzdE1zZ10sXG4gICAgICB9LFxuICAgICAgW2JpdGdvR3BnUHViS2V5XSxcbiAgICAgIFt1c2VyR3BnUHJ2S2V5LCBiYWNrdXBHcGdQcnZLZXldXG4gICAgKTtcblxuICAgIGNvbnN0IHtcbiAgICAgIHNlc3Npb25JZDogc2Vzc2lvbklkUm91bmQzLFxuICAgICAgYml0Z29Nc2c0LFxuICAgICAgY29tbW9uS2V5Y2hhaW46IGJpdGdvQ29tbW9uS2V5Y2hhaW4sXG4gICAgfSA9IGF3YWl0IHRoaXMuc2VuZEtleUdlbmVyYXRpb25Sb3VuZDMocGFyYW1zLmVudGVycHJpc2UsIHNlc3Npb25JZCwgcm91bmQzTWVzc2FnZXMpO1xuXG4gICAgLy8gI2VuZHJlZ2lvblxuXG4gICAgLy8gI3JlZ2lvbiBrZXljaGFpbiBjcmVhdGlvblxuICAgIGFzc2VydC5lcXVhbChzZXNzaW9uSWQsIHNlc3Npb25JZFJvdW5kMywgJ1JvdW5kIDEgYW5kIDMgU2Vzc2lvbiBJRHMgZG8gbm90IG1hdGNoJyk7XG4gICAgY29uc3QgYml0Z29Sb3VuZDRCcm9hZGNhc3RNZXNzYWdlcyA9IERrbHNUeXBlcy5kZXNlcmlhbGl6ZU1lc3NhZ2VzKFxuICAgICAgYXdhaXQgRGtsc0NvbW1zLmRlY3J5cHRBbmRWZXJpZnlJbmNvbWluZ01lc3NhZ2VzKFxuICAgICAgICB7IHAycE1lc3NhZ2VzOiBbXSwgYnJvYWRjYXN0TWVzc2FnZXM6IFt0aGlzLmZvcm1hdEJpdGdvQnJvYWRjYXN0TWVzc2FnZShiaXRnb01zZzQpXSB9LFxuICAgICAgICBbYml0Z29HcGdQdWJLZXldLFxuICAgICAgICBbXVxuICAgICAgKVxuICAgICkuYnJvYWRjYXN0TWVzc2FnZXM7XG4gICAgY29uc3QgYml0Z29Sb3VuZDRCcm9hZGNhc3RNc2cgPSBiaXRnb1JvdW5kNEJyb2FkY2FzdE1lc3NhZ2VzLmZpbmQoKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5CSVRHTyk7XG5cbiAgICBhc3NlcnQoYml0Z29Sb3VuZDRCcm9hZGNhc3RNc2csICdCaXRHbyBtZXNzYWdlIDQgbm90IGZvdW5kIGluIGJyb2FkY2FzdCBtZXNzYWdlcycpO1xuICAgIHVzZXJTZXNzaW9uLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgICAgcDJwTWVzc2FnZXM6IFtdLFxuICAgICAgYnJvYWRjYXN0TWVzc2FnZXM6IFtiaXRnb1JvdW5kNEJyb2FkY2FzdE1zZywgYmFja3VwUm91bmQ0QnJvYWRjYXN0TXNnXSxcbiAgICB9KTtcblxuICAgIGJhY2t1cFNlc3Npb24uaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgICBwMnBNZXNzYWdlczogW10sXG4gICAgICBicm9hZGNhc3RNZXNzYWdlczogW2JpdGdvUm91bmQ0QnJvYWRjYXN0TXNnLCB1c2VyUm91bmQ0QnJvYWRjYXN0TXNnXSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHVzZXJQcml2YXRlTWF0ZXJpYWwgPSB1c2VyU2Vzc2lvbi5nZXRLZXlTaGFyZSgpO1xuICAgIGNvbnN0IGJhY2t1cFByaXZhdGVNYXRlcmlhbCA9IGJhY2t1cFNlc3Npb24uZ2V0S2V5U2hhcmUoKTtcbiAgICBjb25zdCB1c2VyUmVkdWNlZFByaXZhdGVNYXRlcmlhbCA9IHVzZXJTZXNzaW9uLmdldFJlZHVjZWRLZXlTaGFyZSgpO1xuICAgIGNvbnN0IGJhY2t1cFJlZHVjZWRQcml2YXRlTWF0ZXJpYWwgPSBiYWNrdXBTZXNzaW9uLmdldFJlZHVjZWRLZXlTaGFyZSgpO1xuICAgIGNvbnN0IHVzZXJWcmZLZXlTaGFyZSA9IHVzZXJWcmZTZXNzaW9uLmdldEtleVNoYXJlKCk7XG4gICAgY29uc3QgYmFja3VwVnJmS2V5U2hhcmUgPSBiYWNrdXBWcmZTZXNzaW9uLmdldEtleVNoYXJlKCk7XG5cbiAgICBjb25zdCB1c2VyQ29tbW9uS2V5Y2hhaW4gPSBEa2xzVHlwZXMuZ2V0Q29tbW9uS2V5Y2hhaW4odXNlclByaXZhdGVNYXRlcmlhbCk7XG4gICAgY29uc3QgYmFja3VwQ29tbW9uS2V5Y2hhaW4gPSBEa2xzVHlwZXMuZ2V0Q29tbW9uS2V5Y2hhaW4oYmFja3VwUHJpdmF0ZU1hdGVyaWFsKTtcblxuICAgIGFzc2VydC5lcXVhbChiaXRnb0NvbW1vbktleWNoYWluLCB1c2VyQ29tbW9uS2V5Y2hhaW4sICdVc2VyIGFuZCBCaXRnbyBDb21tb24ga2V5Y2hhaW5zIGRvIG5vdCBtYXRjaCcpO1xuICAgIGFzc2VydC5lcXVhbChiaXRnb0NvbW1vbktleWNoYWluLCBiYWNrdXBDb21tb25LZXljaGFpbiwgJ0JhY2t1cCBhbmQgQml0Z28gQ29tbW9uIGtleWNoYWlucyBkbyBub3QgbWF0Y2gnKTtcblxuICAgIGNvbnN0IHsgZW52ZWxvcGU6IHVzZXJFbnZlbG9wZSwgcmVkdWNlZEVudmVsb3BlOiB1c2VyUmVkdWNlZEVudmVsb3BlIH0gPSBidWlsZFZyZktleUVudmVsb3BlcyhcbiAgICAgIHVzZXJQcml2YXRlTWF0ZXJpYWwsXG4gICAgICB1c2VyUmVkdWNlZFByaXZhdGVNYXRlcmlhbCxcbiAgICAgIHVzZXJWcmZLZXlTaGFyZVxuICAgICk7XG4gICAgY29uc3QgeyBlbnZlbG9wZTogYmFja3VwRW52ZWxvcGUsIHJlZHVjZWRFbnZlbG9wZTogYmFja3VwUmVkdWNlZEVudmVsb3BlIH0gPSBidWlsZFZyZktleUVudmVsb3BlcyhcbiAgICAgIGJhY2t1cFByaXZhdGVNYXRlcmlhbCxcbiAgICAgIGJhY2t1cFJlZHVjZWRQcml2YXRlTWF0ZXJpYWwsXG4gICAgICBiYWNrdXBWcmZLZXlTaGFyZVxuICAgICk7XG5cbiAgICBjb25zdCBlbmNyeXB0aW9uU2Vzc2lvbiA9XG4gICAgICBwYXJhbXMuZW5jcnlwdGlvblZlcnNpb24gPT09IDIgPyBhd2FpdCB0aGlzLmJpdGdvLmNyZWF0ZUVuY3J5cHRpb25TZXNzaW9uKHBhcmFtcy5wYXNzcGhyYXNlKSA6IHVuZGVmaW5lZDtcbiAgICB0cnkge1xuICAgICAgY29uc3QgdXNlcktleWNoYWluUHJvbWlzZSA9IHRoaXMuY3JlYXRlUGFydGljaXBhbnRLZXljaGFpbihcbiAgICAgICAgTVBDdjJQYXJ0aWVzRW51bS5VU0VSLFxuICAgICAgICBiaXRnb0NvbW1vbktleWNoYWluLFxuICAgICAgICB1c2VyRW52ZWxvcGUsXG4gICAgICAgIHVzZXJSZWR1Y2VkRW52ZWxvcGUsXG4gICAgICAgIHBhcmFtcy5wYXNzcGhyYXNlLFxuICAgICAgICBwYXJhbXMub3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlLFxuICAgICAgICBwYXJhbXMud2ViYXV0aG5JbmZvLFxuICAgICAgICBlbmNyeXB0aW9uU2Vzc2lvbixcbiAgICAgICAgcGFyYW1zLmVuY3J5cHRpb25WZXJzaW9uLFxuICAgICAgICBwYXJhbXMuZW50ZXJwcmlzZSxcbiAgICAgICAgcGFyYW1zLnNhZmVJZFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGJhY2t1cEtleWNoYWluUHJvbWlzZSA9IHRoaXMuY3JlYXRlUGFydGljaXBhbnRLZXljaGFpbihcbiAgICAgICAgTVBDdjJQYXJ0aWVzRW51bS5CQUNLVVAsXG4gICAgICAgIGJpdGdvQ29tbW9uS2V5Y2hhaW4sXG4gICAgICAgIGJhY2t1cEVudmVsb3BlLFxuICAgICAgICBiYWNrdXBSZWR1Y2VkRW52ZWxvcGUsXG4gICAgICAgIHBhcmFtcy5wYXNzcGhyYXNlLFxuICAgICAgICBwYXJhbXMub3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlLFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIGVuY3J5cHRpb25TZXNzaW9uLFxuICAgICAgICBwYXJhbXMuZW5jcnlwdGlvblZlcnNpb24sXG4gICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgcGFyYW1zLnNhZmVJZFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGJpdGdvS2V5Y2hhaW5Qcm9taXNlID0gdGhpcy5jcmVhdGVQYXJ0aWNpcGFudEtleWNoYWluKFxuICAgICAgICBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPLFxuICAgICAgICBiaXRnb0NvbW1vbktleWNoYWluLFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgcGFyYW1zLnNhZmVJZFxuICAgICAgKTtcblxuICAgICAgY29uc3QgW3VzZXJLZXljaGFpbiwgYmFja3VwS2V5Y2hhaW4sIGJpdGdvS2V5Y2hhaW5dID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICB1c2VyS2V5Y2hhaW5Qcm9taXNlLFxuICAgICAgICBiYWNrdXBLZXljaGFpblByb21pc2UsXG4gICAgICAgIGJpdGdvS2V5Y2hhaW5Qcm9taXNlLFxuICAgICAgXSk7XG4gICAgICAvLyAjZW5kcmVnaW9uXG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHVzZXJLZXljaGFpbixcbiAgICAgICAgYmFja3VwS2V5Y2hhaW4sXG4gICAgICAgIGJpdGdvS2V5Y2hhaW4sXG4gICAgICB9O1xuICAgIH0gZmluYWxseSB7XG4gICAgICBlbmNyeXB0aW9uU2Vzc2lvbj8uZGVzdHJveSgpO1xuICAgIH1cbiAgfVxuICAvKipcbiAgICogU2VuZHMgcm91bmQgMSBmb3IgdGhlIHVzZXIvQml0R28gaGFyZC1kZXJpdmUgY2VyZW1vbnkuXG4gICAqL1xuICBhc3luYyBzZW5kRGVyaXZhdGlvblJvdW5kMUJ5U2VuZGVyKFxuICAgIHNlbmRlckZuOiBFY2RzYU1QQ3YyRGVyaXZlS2V5U2VuZEZuPE1QQ3YyRGVyaXZlUm91bmQxUmVzcG9uc2U+LFxuICAgIHVzZXJHcGdQdWJsaWNLZXk6IHN0cmluZyxcbiAgICBwYXlsb2FkOiBEa2xzVHlwZXMuQXV0aEVuY01lc3NhZ2VzLFxuICAgIHBhcmVudEtleUlkOiBzdHJpbmcsXG4gICAgZGVyaXZhdGlvbkluZGV4OiBudW1iZXJcbiAgKTogUHJvbWlzZTxNUEN2MkRlcml2ZVJvdW5kMVJlc3BvbnNlPiB7XG4gICAgYXNzZXJ0KE5vbkVtcHR5U3RyaW5nLmlzKHVzZXJHcGdQdWJsaWNLZXkpLCAnVXNlciBHUEcgcHVibGljIGtleSBpcyByZXF1aXJlZCcpO1xuICAgIGFzc2VydChOb25FbXB0eVN0cmluZy5pcyhwYXJlbnRLZXlJZCksICdQYXJlbnQga2V5IGlkIGlzIHJlcXVpcmVkJyk7XG4gICAgY29uc3QgdXNlck1zZzEgPSBwYXlsb2FkLmJyb2FkY2FzdE1lc3NhZ2VzLmZpbmQoKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSKT8ucGF5bG9hZDtcbiAgICBhc3NlcnQodXNlck1zZzEsICdVc2VyIG1lc3NhZ2UgMSBub3QgZm91bmQgaW4gYnJvYWRjYXN0IG1lc3NhZ2VzJyk7XG5cbiAgICBhc3NlcnQoXG4gICAgICBNUEN2MkRlcml2ZVJvdW5kMVJlcXVlc3QucHJvcHMuZGVyaXZhdGlvbkluZGV4LmlzKGRlcml2YXRpb25JbmRleCksXG4gICAgICAnRGVyaXZhdGlvbiBpbmRleCBtdXN0IGJlIGEgbm9uLW5lZ2F0aXZlIHNhZmUgaW50ZWdlcidcbiAgICApO1xuICAgIGNvbnN0IHJlcXVlc3Q6IE1QQ3YyRGVyaXZlUm91bmQxUmVxdWVzdCA9IHtcbiAgICAgIHVzZXJHcGdQdWJsaWNLZXksXG4gICAgICB1c2VyTXNnMTogeyBmcm9tOiBNUEN2MlBhcnRpZXNFbnVtLlVTRVIsIC4uLnVzZXJNc2cxIH0sXG4gICAgICBwYXJlbnRLZXlJZCxcbiAgICAgIGRlcml2YXRpb25JbmRleCxcbiAgICB9O1xuICAgIHJldHVybiBzZW5kZXJGbihNUEN2MktleUdlblN0YXRlRW51bVsnTVBDdjJEZXJpdmUtUjEnXSwgcmVxdWVzdCk7XG4gIH1cblxuICAvKipcbiAgICogU2VuZHMgcm91bmQgMiBmb3IgdGhlIHVzZXIvQml0R28gaGFyZC1kZXJpdmUgY2VyZW1vbnkuXG4gICAqL1xuICBhc3luYyBzZW5kRGVyaXZhdGlvblJvdW5kMkJ5U2VuZGVyKFxuICAgIHNlbmRlckZuOiBFY2RzYU1QQ3YyRGVyaXZlS2V5U2VuZEZuPE1QQ3YyRGVyaXZlUm91bmQyUmVzcG9uc2U+LFxuICAgIHNlc3Npb25JZDogc3RyaW5nLFxuICAgIHBheWxvYWQ6IERrbHNUeXBlcy5BdXRoRW5jTWVzc2FnZXNcbiAgKTogUHJvbWlzZTxNUEN2MkRlcml2ZVJvdW5kMlJlc3BvbnNlPiB7XG4gICAgYXNzZXJ0KE5vbkVtcHR5U3RyaW5nLmlzKHNlc3Npb25JZCksICdTZXNzaW9uIElEIGlzIHJlcXVpcmVkJyk7XG4gICAgY29uc3QgdXNlck1zZzIgPSBwYXlsb2FkLmJyb2FkY2FzdE1lc3NhZ2VzLmZpbmQoKG0pID0+IG0uZnJvbSA9PT0gTVBDdjJQYXJ0aWVzRW51bS5VU0VSKT8ucGF5bG9hZDtcbiAgICBhc3NlcnQodXNlck1zZzIsICdVc2VyIG1lc3NhZ2UgMiBub3QgZm91bmQgaW4gYnJvYWRjYXN0IG1lc3NhZ2VzJyk7XG5cbiAgICBjb25zdCByZXF1ZXN0OiBNUEN2MkRlcml2ZVJvdW5kMlJlcXVlc3QgPSB7XG4gICAgICBzZXNzaW9uSWQsXG4gICAgICB1c2VyTXNnMjogeyBmcm9tOiBNUEN2MlBhcnRpZXNFbnVtLlVTRVIsIC4uLnVzZXJNc2cyIH0sXG4gICAgfTtcbiAgICByZXR1cm4gc2VuZGVyRm4oTVBDdjJLZXlHZW5TdGF0ZUVudW1bJ01QQ3YyRGVyaXZlLVIyJ10sIHJlcXVlc3QpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbXBsZXRlcyByb3VuZCAzIGFuZCByZXR1cm5zIHRoZSBjaGlsZCBjb21tb24ga2V5Y2hhaW4uXG4gICAqL1xuICBhc3luYyBzZW5kRGVyaXZhdGlvblJvdW5kM0J5U2VuZGVyKFxuICAgIHNlbmRlckZuOiBFY2RzYU1QQ3YyRGVyaXZlS2V5U2VuZEZuPE1QQ3YyRGVyaXZlUm91bmQzUmVzcG9uc2U+LFxuICAgIHNlc3Npb25JZDogc3RyaW5nXG4gICk6IFByb21pc2U8TVBDdjJEZXJpdmVSb3VuZDNSZXNwb25zZT4ge1xuICAgIGFzc2VydChOb25FbXB0eVN0cmluZy5pcyhzZXNzaW9uSWQpLCAnU2Vzc2lvbiBJRCBpcyByZXF1aXJlZCcpO1xuICAgIHJldHVybiBzZW5kZXJGbihNUEN2MktleUdlblN0YXRlRW51bVsnTVBDdjJEZXJpdmUtUjMnXSwgeyBzZXNzaW9uSWQgfSk7XG4gIH1cblxuICAvKipcbiAgICogUnVucyB0aGUgc2FmZSBjaGlsZCBoYXJkLWRlcml2ZSBjZXJlbW9ueSBhbmQgcmVnaXN0ZXJzIGNoaWxkIGtleSBkb2N1bWVudHMuXG4gICAqL1xuICBhc3luYyBjcmVhdGVTYWZlQ2hpbGRLZXljaGFpbnMocGFyYW1zOiB7XG4gICAgcGFzc3BocmFzZTogc3RyaW5nO1xuICAgIGVudGVycHJpc2U6IHN0cmluZztcbiAgICBzYWZlSWQ6IHN0cmluZztcbiAgICAvKiogUm9vdCBrZXkgSUQgdXNlZCBmb3IgdGhlIGRlcml2ZS4gKi9cbiAgICBwYXJlbnRLZXlJZDogc3RyaW5nO1xuICAgIGRlcml2YXRpb25JbmRleDogbnVtYmVyO1xuICAgIHVzZXJSb290S2V5SWQ6IHN0cmluZztcbiAgICBiYWNrdXBSb290S2V5SWQ6IHN0cmluZztcbiAgICB1c2VyUm9vdEtleVNoYXJlOiBCdWZmZXI7XG4gICAgdXNlclJvb3RWcmZLZXlTaGFyZTogQnVmZmVyO1xuICAgIG9yaWdpbmFsUGFzc2NvZGVFbmNyeXB0aW9uQ29kZT86IHN0cmluZztcbiAgICB3ZWJhdXRobkluZm8/OiBXZWJhdXRobktleUVuY3J5cHRpb25JbmZvO1xuICAgIGVuY3J5cHRpb25WZXJzaW9uPzogRW5jcnlwdGlvblZlcnNpb247XG4gIH0pOiBQcm9taXNlPFBpY2s8S2V5Y2hhaW5zVHJpcGxldCwgJ3VzZXJLZXljaGFpbicgfCAnYmFja3VwS2V5Y2hhaW4nPj4ge1xuICAgIGNvbnN0IHVzZXJHcGdLZXkgPSBhd2FpdCBnZW5lcmF0ZUdQR0tleVBhaXIoJ3NlY3AyNTZrMScpO1xuXG4gICAgY29uc3QgeyBtcGN2MlB1YmxpY0tleSB9ID0gYXdhaXQgdGhpcy5nZXRCaXRnb0dwZ1B1YmtleUJhc2VkT25GZWF0dXJlRmxhZ3MocGFyYW1zLmVudGVycHJpc2UsIHRydWUpO1xuICAgIGNvbnN0IG1wY3YyS2V5ID0gbXBjdjJQdWJsaWNLZXkgPz8gdGhpcy5iaXRnb01QQ3YyUHVibGljR3BnS2V5O1xuICAgIGFzc2VydChtcGN2MktleSwgJ0ZhaWxlZCB0byBnZXQgQml0R28gTVBDdjIgR1BHIHB1YmxpYyBrZXknKTtcbiAgICBjb25zdCBiaXRnb1B1YmxpY0dwZ0tleSA9IG1wY3YyS2V5LmFybW9yKCk7XG5cbiAgICBpZiAoZW52UmVxdWlyZXNCaXRnb1B1YkdwZ0tleUNvbmZpZyh0aGlzLmJpdGdvLmdldEVudigpKSkge1xuICAgICAgYXNzZXJ0KGlzQml0Z29NcGNQdWJLZXkoYml0Z29QdWJsaWNHcGdLZXksICdtcGN2MicpLCAnSW52YWxpZCBCaXRHbyBHUEcgcHVibGljIGtleScpO1xuICAgIH1cblxuICAgIGNvbnN0IHVzZXJHcGdQcnZLZXk6IERrbHNUeXBlcy5QYXJ0eUdwZ0tleSA9IHtcbiAgICAgIHBhcnR5SWQ6IE1QQ3YyUGFydGllc0VudW0uVVNFUixcbiAgICAgIGdwZ0tleTogdXNlckdwZ0tleS5wcml2YXRlS2V5LFxuICAgIH07XG4gICAgY29uc3QgYml0Z29HcGdQdWJLZXk6IERrbHNUeXBlcy5QYXJ0eUdwZ0tleSA9IHtcbiAgICAgIHBhcnR5SWQ6IE1QQ3YyUGFydGllc0VudW0uQklUR08sXG4gICAgICBncGdLZXk6IGJpdGdvUHVibGljR3BnS2V5LFxuICAgIH07XG5cbiAgICBjb25zdCBwYXRoID0gaGFyZGVuZWREZXJpdmF0aW9uUGF0aChwYXJhbXMuZGVyaXZhdGlvbkluZGV4KTtcbiAgICBjb25zdCB1c2VyRGVyaXZlU2Vzc2lvbiA9IG5ldyBEa2xzRHJ2LkRlcml2ZShcbiAgICAgIDMsXG4gICAgICAyLFxuICAgICAgTVBDdjJQYXJ0aWVzRW51bS5VU0VSLFxuICAgICAgcGFyYW1zLnVzZXJSb290S2V5U2hhcmUsXG4gICAgICBwYXJhbXMudXNlclJvb3RWcmZLZXlTaGFyZSxcbiAgICAgIHBhdGhcbiAgICApO1xuXG4gICAgLy8gUm91bmQgMTogc2VuZCB0aGUgdXNlcidzIGZpcnN0IG1lc3NhZ2UuXG4gICAgY29uc3QgdXNlclJvdW5kMU1zZyA9IGF3YWl0IHVzZXJEZXJpdmVTZXNzaW9uLmluaXREZXJpdmUoKTtcbiAgICBjb25zdCByb3VuZDFNZXNzYWdlcyA9IGF3YWl0IERrbHNDb21tcy5lbmNyeXB0QW5kQXV0aE91dGdvaW5nTWVzc2FnZXMoXG4gICAgICB7XG4gICAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbRGtsc1R5cGVzLnNlcmlhbGl6ZUJyb2FkY2FzdE1lc3NhZ2UodXNlclJvdW5kMU1zZyldLFxuICAgICAgICBwMnBNZXNzYWdlczogW10sXG4gICAgICB9LFxuICAgICAgW2JpdGdvR3BnUHViS2V5XSxcbiAgICAgIFt1c2VyR3BnUHJ2S2V5XVxuICAgICk7XG4gICAgYXNzZXJ0KE5vbkVtcHR5U3RyaW5nLmlzKHVzZXJHcGdLZXkucHVibGljS2V5KSwgJ1VzZXIgR1BHIHB1YmxpYyBrZXkgaXMgcmVxdWlyZWQnKTtcbiAgICBjb25zdCB7IHNlc3Npb25JZCwgYml0Z29Nc2cxIH0gPSBhd2FpdCB0aGlzLnNlbmREZXJpdmF0aW9uUm91bmQxQnlTZW5kZXIoXG4gICAgICBLZXlHZW5TZW5kZXJGb3JTYWZlQ2hpbGQ8TVBDdjJEZXJpdmVSb3VuZDFSZXNwb25zZT4odGhpcy5iaXRnbywgcGFyYW1zLmVudGVycHJpc2UsIHBhcmFtcy5zYWZlSWQpLFxuICAgICAgdXNlckdwZ0tleS5wdWJsaWNLZXksXG4gICAgICByb3VuZDFNZXNzYWdlcyxcbiAgICAgIHBhcmFtcy5wYXJlbnRLZXlJZCxcbiAgICAgIHBhcmFtcy5kZXJpdmF0aW9uSW5kZXhcbiAgICApO1xuXG4gICAgLy8gUm91bmQgMjogcHJvY2VzcyB0aGUgcGVlcidzIGZpcnN0IG1lc3NhZ2UgYW5kIHJldHVybiB0aGUgdXNlcidzIHNlY29uZC5cbiAgICBjb25zdCBkZWNyeXB0ZWRCaXRnb1JvdW5kMSA9IGF3YWl0IERrbHNDb21tcy5kZWNyeXB0QW5kVmVyaWZ5SW5jb21pbmdNZXNzYWdlcyhcbiAgICAgIHsgcDJwTWVzc2FnZXM6IFtdLCBicm9hZGNhc3RNZXNzYWdlczogW3RoaXMuZm9ybWF0Qml0Z29Ccm9hZGNhc3RNZXNzYWdlKGJpdGdvTXNnMSldIH0sXG4gICAgICBbYml0Z29HcGdQdWJLZXldLFxuICAgICAgW11cbiAgICApO1xuICAgIGNvbnN0IGJpdGdvUm91bmQxTXNnID0gZGVjcnlwdGVkQml0Z29Sb3VuZDEuYnJvYWRjYXN0TWVzc2FnZXMuZmluZCgobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBhc3NlcnQoYml0Z29Sb3VuZDFNc2csICdCaXRHbyBkZXJpdmUgbWVzc2FnZSAxIG5vdCBmb3VuZCBpbiBicm9hZGNhc3QgbWVzc2FnZXMnKTtcbiAgICBjb25zdCB1c2VyUm91bmQyTWVzc2FnZXMgPSB1c2VyRGVyaXZlU2Vzc2lvbi5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKHtcbiAgICAgIHAycE1lc3NhZ2VzOiBbXSxcbiAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbRGtsc1R5cGVzLmRlc2VyaWFsaXplQnJvYWRjYXN0TWVzc2FnZShiaXRnb1JvdW5kMU1zZyldLFxuICAgIH0pO1xuICAgIGNvbnN0IHJvdW5kMk1lc3NhZ2VzID0gYXdhaXQgRGtsc0NvbW1zLmVuY3J5cHRBbmRBdXRoT3V0Z29pbmdNZXNzYWdlcyhcbiAgICAgIERrbHNUeXBlcy5zZXJpYWxpemVNZXNzYWdlcyh1c2VyUm91bmQyTWVzc2FnZXMpLFxuICAgICAgW2JpdGdvR3BnUHViS2V5XSxcbiAgICAgIFt1c2VyR3BnUHJ2S2V5XVxuICAgICk7XG4gICAgY29uc3QgeyBzZXNzaW9uSWQ6IHNlc3Npb25JZFJvdW5kMiwgYml0Z29Nc2cyIH0gPSBhd2FpdCB0aGlzLnNlbmREZXJpdmF0aW9uUm91bmQyQnlTZW5kZXIoXG4gICAgICBLZXlHZW5TZW5kZXJGb3JTYWZlQ2hpbGQ8TVBDdjJEZXJpdmVSb3VuZDJSZXNwb25zZT4odGhpcy5iaXRnbywgcGFyYW1zLmVudGVycHJpc2UsIHBhcmFtcy5zYWZlSWQpLFxuICAgICAgc2Vzc2lvbklkLFxuICAgICAgcm91bmQyTWVzc2FnZXNcbiAgICApO1xuICAgIGFzc2VydC5lcXVhbChzZXNzaW9uSWQsIHNlc3Npb25JZFJvdW5kMiwgJ1JvdW5kIDEgYW5kIDIgU2Vzc2lvbiBJRHMgZG8gbm90IG1hdGNoJyk7XG5cbiAgICAvLyBQcm9jZXNzIHRoZSBwZWVyIHJlc3BvbnNlIHRvIGZpbmFsaXplIHRoZSBsb2NhbCBjaGlsZCBzaGFyZS5cbiAgICBjb25zdCBkZWNyeXB0ZWRCaXRnb1JvdW5kMiA9IGF3YWl0IERrbHNDb21tcy5kZWNyeXB0QW5kVmVyaWZ5SW5jb21pbmdNZXNzYWdlcyhcbiAgICAgIHsgcDJwTWVzc2FnZXM6IFtdLCBicm9hZGNhc3RNZXNzYWdlczogW3RoaXMuZm9ybWF0Qml0Z29Ccm9hZGNhc3RNZXNzYWdlKGJpdGdvTXNnMildIH0sXG4gICAgICBbYml0Z29HcGdQdWJLZXldLFxuICAgICAgW11cbiAgICApO1xuICAgIGNvbnN0IGJpdGdvUm91bmQyTXNnID0gZGVjcnlwdGVkQml0Z29Sb3VuZDIuYnJvYWRjYXN0TWVzc2FnZXMuZmluZCgobSkgPT4gbS5mcm9tID09PSBNUEN2MlBhcnRpZXNFbnVtLkJJVEdPKTtcbiAgICBhc3NlcnQoYml0Z29Sb3VuZDJNc2csICdCaXRHbyBkZXJpdmUgbWVzc2FnZSAyIG5vdCBmb3VuZCBpbiBicm9hZGNhc3QgbWVzc2FnZXMnKTtcbiAgICB1c2VyRGVyaXZlU2Vzc2lvbi5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKHtcbiAgICAgIHAycE1lc3NhZ2VzOiBbXSxcbiAgICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbRGtsc1R5cGVzLmRlc2VyaWFsaXplQnJvYWRjYXN0TWVzc2FnZShiaXRnb1JvdW5kMk1zZyldLFxuICAgIH0pO1xuXG4gICAgLy8gUm91bmQgMzogb2J0YWluIHRoZSBjaGlsZCBjb21tb24ta2V5Y2hhaW4gbWV0YWRhdGEuXG4gICAgY29uc3QgeyBzZXNzaW9uSWQ6IHNlc3Npb25JZFJvdW5kMywgY29tbW9uS2V5Y2hhaW4gfSA9IGF3YWl0IHRoaXMuc2VuZERlcml2YXRpb25Sb3VuZDNCeVNlbmRlcihcbiAgICAgIEtleUdlblNlbmRlckZvclNhZmVDaGlsZDxNUEN2MkRlcml2ZVJvdW5kM1Jlc3BvbnNlPih0aGlzLmJpdGdvLCBwYXJhbXMuZW50ZXJwcmlzZSwgcGFyYW1zLnNhZmVJZCksXG4gICAgICBzZXNzaW9uSWRcbiAgICApO1xuICAgIGFzc2VydC5lcXVhbChzZXNzaW9uSWQsIHNlc3Npb25JZFJvdW5kMywgJ1JvdW5kIDEgYW5kIDMgU2Vzc2lvbiBJRHMgZG8gbm90IG1hdGNoJyk7XG5cbiAgICBjb25zdCB1c2VyUHJpdmF0ZU1hdGVyaWFsID0gdXNlckRlcml2ZVNlc3Npb24uZ2V0S2V5U2hhcmUoKTtcbiAgICBjb25zdCB1c2VyUmVkdWNlZFByaXZhdGVNYXRlcmlhbCA9IHVzZXJEZXJpdmVTZXNzaW9uLmdldFJlZHVjZWRLZXlTaGFyZSgpO1xuICAgIGNvbnN0IHVzZXJDb21tb25LZXljaGFpbiA9IERrbHNUeXBlcy5nZXRDb21tb25LZXljaGFpbih1c2VyUHJpdmF0ZU1hdGVyaWFsKTtcbiAgICBhc3NlcnQuZXF1YWwoY29tbW9uS2V5Y2hhaW4sIHVzZXJDb21tb25LZXljaGFpbiwgJ1VzZXIgYW5kIEJpdEdvIGNvbW1vbiBrZXljaGFpbnMgZG8gbm90IG1hdGNoJyk7XG5cbiAgICBjb25zdCBlbmNyeXB0aW9uU2Vzc2lvbiA9XG4gICAgICBwYXJhbXMuZW5jcnlwdGlvblZlcnNpb24gPT09IDIgPyBhd2FpdCB0aGlzLmJpdGdvLmNyZWF0ZUVuY3J5cHRpb25TZXNzaW9uKHBhcmFtcy5wYXNzcGhyYXNlKSA6IHVuZGVmaW5lZDtcbiAgICB0cnkge1xuICAgICAgY29uc3QgdXNlcktleWNoYWluUHJvbWlzZSA9IHRoaXMuY3JlYXRlUGFydGljaXBhbnRLZXljaGFpbihcbiAgICAgICAgTVBDdjJQYXJ0aWVzRW51bS5VU0VSLFxuICAgICAgICBjb21tb25LZXljaGFpbixcbiAgICAgICAgdXNlclByaXZhdGVNYXRlcmlhbCxcbiAgICAgICAgdXNlclJlZHVjZWRQcml2YXRlTWF0ZXJpYWwsXG4gICAgICAgIHBhcmFtcy5wYXNzcGhyYXNlLFxuICAgICAgICBwYXJhbXMub3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlLFxuICAgICAgICBwYXJhbXMud2ViYXV0aG5JbmZvLFxuICAgICAgICBlbmNyeXB0aW9uU2Vzc2lvbixcbiAgICAgICAgcGFyYW1zLmVuY3J5cHRpb25WZXJzaW9uLFxuICAgICAgICBwYXJhbXMuZW50ZXJwcmlzZSxcbiAgICAgICAgcGFyYW1zLnNhZmVJZCxcbiAgICAgICAgeyBwYXJlbnRLZXlJZDogcGFyYW1zLnVzZXJSb290S2V5SWQsIGluZGV4OiBwYXJhbXMuZGVyaXZhdGlvbkluZGV4IH1cbiAgICAgICk7XG4gICAgICBjb25zdCBiYWNrdXBLZXljaGFpblByb21pc2UgPSB0aGlzLmNyZWF0ZVBhcnRpY2lwYW50S2V5Y2hhaW4oXG4gICAgICAgIE1QQ3YyUGFydGllc0VudW0uQkFDS1VQLFxuICAgICAgICBjb21tb25LZXljaGFpbixcbiAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIHBhcmFtcy5wYXNzcGhyYXNlLFxuICAgICAgICBwYXJhbXMub3JpZ2luYWxQYXNzY29kZUVuY3J5cHRpb25Db2RlLFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIGVuY3J5cHRpb25TZXNzaW9uLFxuICAgICAgICBwYXJhbXMuZW5jcnlwdGlvblZlcnNpb24sXG4gICAgICAgIHVuZGVmaW5lZCxcbiAgICAgICAgcGFyYW1zLnNhZmVJZCxcbiAgICAgICAgeyBwYXJlbnRLZXlJZDogcGFyYW1zLmJhY2t1cFJvb3RLZXlJZCwgaW5kZXg6IHBhcmFtcy5kZXJpdmF0aW9uSW5kZXggfVxuICAgICAgKTtcblxuICAgICAgY29uc3QgW3VzZXJLZXljaGFpbiwgYmFja3VwS2V5Y2hhaW5dID0gYXdhaXQgUHJvbWlzZS5hbGwoW3VzZXJLZXljaGFpblByb21pc2UsIGJhY2t1cEtleWNoYWluUHJvbWlzZV0pO1xuICAgICAgcmV0dXJuIHsgdXNlcktleWNoYWluLCBiYWNrdXBLZXljaGFpbiB9O1xuICAgIH0gZmluYWxseSB7XG4gICAgICBlbmNyeXB0aW9uU2Vzc2lvbj8uZGVzdHJveSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlU2lnbmluZ0RrZ1Nlc3Npb25zKHJldHJvZml0PzogRGVjcnlwdGVkUmV0cm9maXRQYXlsb2FkKSB7XG4gICAgaWYgKHJldHJvZml0KSB7XG4gICAgICBjb25zdCByZXRyb2ZpdERhdGEgPSB0aGlzLmdldE1wY1YyUmV0cm9maXREYXRhRnJvbU1wY1YxS2V5cyh7XG4gICAgICAgIG1wY3YxVXNlcktleVNoYXJlOiByZXRyb2ZpdC5kZWNyeXB0ZWRVc2VyS2V5LFxuICAgICAgICBtcGN2MUJhY2t1cEtleVNoYXJlOiByZXRyb2ZpdC5kZWNyeXB0ZWRCYWNrdXBLZXksXG4gICAgICB9KTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHVzZXJTZXNzaW9uOiBuZXcgRGtsc0RrZy5Ea2coMywgMiwgTVBDdjJQYXJ0aWVzRW51bS5VU0VSLCB1bmRlZmluZWQsIHJldHJvZml0RGF0YS5tcGN2MlVzZXJLZXlTaGFyZSksXG4gICAgICAgIGJhY2t1cFNlc3Npb246IG5ldyBEa2xzRGtnLkRrZygzLCAyLCBNUEN2MlBhcnRpZXNFbnVtLkJBQ0tVUCwgdW5kZWZpbmVkLCByZXRyb2ZpdERhdGEubXBjdjJCYWNrdXBLZXlTaGFyZSksXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgdXNlclNlc3Npb246IG5ldyBEa2xzRGtnLkRrZygzLCAyLCBNUEN2MlBhcnRpZXNFbnVtLlVTRVIpLFxuICAgICAgYmFja3VwU2Vzc2lvbjogbmV3IERrbHNEa2cuRGtnKDMsIDIsIE1QQ3YyUGFydGllc0VudW0uQkFDS1VQKSxcbiAgICB9O1xuICB9XG59XG4iXX0=