@bitgo-beta/sdk-lib-mpc 8.2.1-alpha.468 → 8.2.1-alpha.469
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/src/tss/dkls-vrf/dkg.d.ts +91 -0
- package/dist/src/tss/dkls-vrf/dkg.d.ts.map +1 -0
- package/dist/src/tss/dkls-vrf/dkg.js +278 -0
- package/dist/src/tss/dkls-vrf/index.d.ts +4 -0
- package/dist/src/tss/dkls-vrf/index.d.ts.map +1 -0
- package/dist/src/tss/dkls-vrf/index.js +40 -0
- package/dist/src/tss/dkls-vrf/types.d.ts +28 -0
- package/dist/src/tss/dkls-vrf/types.d.ts.map +1 -0
- package/dist/src/tss/dkls-vrf/types.js +23 -0
- package/dist/src/tss/dkls-vrf/util.d.ts +29 -0
- package/dist/src/tss/dkls-vrf/util.d.ts.map +1 -0
- package/dist/src/tss/dkls-vrf/util.js +113 -0
- package/dist/src/tss/ecdsa-dkls/derive.d.ts +111 -0
- package/dist/src/tss/ecdsa-dkls/derive.d.ts.map +1 -0
- package/dist/src/tss/ecdsa-dkls/derive.js +329 -0
- package/dist/src/tss/ecdsa-dkls/dkg.d.ts +3 -1
- package/dist/src/tss/ecdsa-dkls/dkg.d.ts.map +1 -1
- package/dist/src/tss/ecdsa-dkls/dkg.js +1 -1
- package/dist/src/tss/ecdsa-dkls/index.d.ts +1 -0
- package/dist/src/tss/ecdsa-dkls/index.d.ts.map +1 -1
- package/dist/src/tss/ecdsa-dkls/index.js +3 -2
- package/dist/src/tss/eddsa-mps/derive.d.ts +34 -0
- package/dist/src/tss/eddsa-mps/derive.d.ts.map +1 -0
- package/dist/src/tss/eddsa-mps/derive.js +198 -0
- package/dist/src/tss/eddsa-mps/dkg.d.ts +7 -2
- package/dist/src/tss/eddsa-mps/dkg.d.ts.map +1 -1
- package/dist/src/tss/eddsa-mps/dkg.js +13 -3
- package/dist/src/tss/eddsa-mps/index.d.ts +2 -0
- package/dist/src/tss/eddsa-mps/index.d.ts.map +1 -1
- package/dist/src/tss/eddsa-mps/index.js +3 -2
- package/dist/src/tss/eddsa-mps/types.d.ts +13 -0
- package/dist/src/tss/eddsa-mps/types.d.ts.map +1 -1
- package/dist/src/tss/eddsa-mps/types.js +1 -1
- package/dist/src/tss/eddsa-mps/util.d.ts +2 -2
- package/dist/src/tss/eddsa-mps/util.d.ts.map +1 -1
- package/dist/src/tss/eddsa-mps/util.js +5 -5
- package/dist/src/tss/eddsa-mps-vrf/dkg.d.ts +65 -0
- package/dist/src/tss/eddsa-mps-vrf/dkg.d.ts.map +1 -0
- package/dist/src/tss/eddsa-mps-vrf/dkg.js +246 -0
- package/dist/src/tss/eddsa-mps-vrf/index.d.ts +4 -0
- package/dist/src/tss/eddsa-mps-vrf/index.d.ts.map +1 -0
- package/dist/src/tss/eddsa-mps-vrf/index.js +40 -0
- package/dist/src/tss/eddsa-mps-vrf/types.d.ts +31 -0
- package/dist/src/tss/eddsa-mps-vrf/types.d.ts.map +1 -0
- package/dist/src/tss/eddsa-mps-vrf/types.js +97 -0
- package/dist/src/tss/eddsa-mps-vrf/util.d.ts +9 -0
- package/dist/src/tss/eddsa-mps-vrf/util.d.ts.map +1 -0
- package/dist/src/tss/eddsa-mps-vrf/util.js +36 -0
- package/dist/src/tss/index.d.ts +3 -0
- package/dist/src/tss/index.d.ts.map +1 -1
- package/dist/src/tss/index.js +4 -1
- package/dist/src/tss/redpallas-mps/commsLayer.d.ts +34 -0
- package/dist/src/tss/redpallas-mps/commsLayer.d.ts.map +1 -0
- package/dist/src/tss/redpallas-mps/commsLayer.js +100 -0
- package/dist/src/tss/redpallas-mps/dkg.d.ts +103 -0
- package/dist/src/tss/redpallas-mps/dkg.d.ts.map +1 -0
- package/dist/src/tss/redpallas-mps/dkg.js +285 -0
- package/dist/src/tss/redpallas-mps/dsg.d.ts +108 -0
- package/dist/src/tss/redpallas-mps/dsg.d.ts.map +1 -0
- package/dist/src/tss/redpallas-mps/dsg.js +355 -0
- package/dist/src/tss/redpallas-mps/index.d.ts +7 -0
- package/dist/src/tss/redpallas-mps/index.d.ts.map +1 -0
- package/dist/src/tss/redpallas-mps/index.js +42 -0
- package/dist/src/tss/redpallas-mps/types.d.ts +85 -0
- package/dist/src/tss/redpallas-mps/types.d.ts.map +1 -0
- package/dist/src/tss/redpallas-mps/types.js +112 -0
- package/dist/src/tss/redpallas-mps/util.d.ts +43 -0
- package/dist/src/tss/redpallas-mps/util.d.ts.map +1 -0
- package/dist/src/tss/redpallas-mps/util.js +147 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +20 -6
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateVrfDKGKeyShares = generateVrfDKGKeyShares;
|
|
4
|
+
exports.generateHardDerivedKeyShares = generateHardDerivedKeyShares;
|
|
5
|
+
const derive_1 = require("../ecdsa-dkls/derive");
|
|
6
|
+
const dkg_1 = require("./dkg");
|
|
7
|
+
/**
|
|
8
|
+
* Runs a local 2-of-3 VRF DKG across user (0), backup (1) and bitgo (2) parties and
|
|
9
|
+
* returns the three completed VrfDkg sessions, mirroring `generateDKGKeyShares` from
|
|
10
|
+
* `ecdsa-dkls/util.ts` so VRF tests read like the existing DKLS ones.
|
|
11
|
+
*/
|
|
12
|
+
async function generateVrfDKGKeyShares(seedUser, seedBackup, seedBitgo) {
|
|
13
|
+
const user = new dkg_1.VrfDkg(3, 2, 0, seedUser);
|
|
14
|
+
const backup = new dkg_1.VrfDkg(3, 2, 1, seedBackup);
|
|
15
|
+
const bitgo = new dkg_1.VrfDkg(3, 2, 2, seedBitgo);
|
|
16
|
+
// #region round 1
|
|
17
|
+
const userRound1Messages = await user.initDkg();
|
|
18
|
+
const backupRound1Messages = await backup.initDkg();
|
|
19
|
+
const bitgoRound1Messages = await bitgo.initDkg();
|
|
20
|
+
const bitgoRound2Messages = await bitgo.handleIncomingMessages({
|
|
21
|
+
p2pMessages: [],
|
|
22
|
+
broadcastMessages: [...userRound1Messages.broadcastMessages, ...backupRound1Messages.broadcastMessages],
|
|
23
|
+
});
|
|
24
|
+
// #endregion
|
|
25
|
+
// #region round 2
|
|
26
|
+
const userRound2Messages = await user.handleIncomingMessages({
|
|
27
|
+
p2pMessages: [],
|
|
28
|
+
broadcastMessages: [...bitgoRound1Messages.broadcastMessages, ...backupRound1Messages.broadcastMessages],
|
|
29
|
+
});
|
|
30
|
+
const backupRound2Messages = await backup.handleIncomingMessages({
|
|
31
|
+
p2pMessages: [],
|
|
32
|
+
broadcastMessages: [...userRound1Messages.broadcastMessages, ...bitgoRound1Messages.broadcastMessages],
|
|
33
|
+
});
|
|
34
|
+
await bitgo.handleIncomingMessages({
|
|
35
|
+
p2pMessages: [bitgoRound2Messages, userRound2Messages, backupRound2Messages]
|
|
36
|
+
.flatMap((m) => m.p2pMessages)
|
|
37
|
+
.filter((m) => m.to === 2),
|
|
38
|
+
broadcastMessages: [],
|
|
39
|
+
});
|
|
40
|
+
await user.handleIncomingMessages({
|
|
41
|
+
p2pMessages: [bitgoRound2Messages, userRound2Messages, backupRound2Messages]
|
|
42
|
+
.flatMap((m) => m.p2pMessages)
|
|
43
|
+
.filter((m) => m.to === 0),
|
|
44
|
+
broadcastMessages: [],
|
|
45
|
+
});
|
|
46
|
+
await backup.handleIncomingMessages({
|
|
47
|
+
p2pMessages: [bitgoRound2Messages, userRound2Messages, backupRound2Messages]
|
|
48
|
+
.flatMap((m) => m.p2pMessages)
|
|
49
|
+
.filter((m) => m.to === 1),
|
|
50
|
+
broadcastMessages: [],
|
|
51
|
+
});
|
|
52
|
+
return [user, backup, bitgo];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Runs the hard-derivation ceremony on top of completed root sessions: the user (0)
|
|
56
|
+
* hard-derive session pairs with a fresh BitGo (2) session, and the backup (1)
|
|
57
|
+
* session with a second fresh BitGo session. The hard-derive wasm session is a
|
|
58
|
+
* 2-party threshold protocol per instance, so the BitGo server side runs two
|
|
59
|
+
* sessions — one per SDK party. All four derived keyshares agree on the child
|
|
60
|
+
* public key; the two BitGo shares are distinct private shares of that same key.
|
|
61
|
+
*
|
|
62
|
+
* @param path hardened derivation path bytes (e.g. `m/0'` as a 4-byte big-endian
|
|
63
|
+
* index with the hardened bit set)
|
|
64
|
+
* @returns [user, backup, bitgoUserPair, bitgoBackupPair] completed Derive sessions
|
|
65
|
+
*/
|
|
66
|
+
async function generateHardDerivedKeyShares(userRoot, backupRoot, bitgoRoot, userVrf, backupVrf, bitgoVrf, path, seedUser, seedBackup) {
|
|
67
|
+
const user = new derive_1.Derive(3, 2, 0, userRoot.getKeyShare(), userVrf.getKeyShare(), path, seedUser);
|
|
68
|
+
const backup = new derive_1.Derive(3, 2, 1, backupRoot.getKeyShare(), backupVrf.getKeyShare(), path, seedBackup);
|
|
69
|
+
const bitgoUserPair = new derive_1.Derive(3, 2, 2, bitgoRoot.getKeyShare(), bitgoVrf.getKeyShare(), path);
|
|
70
|
+
const bitgoBackupPair = new derive_1.Derive(3, 2, 2, bitgoRoot.getKeyShare(), bitgoVrf.getKeyShare(), path);
|
|
71
|
+
// #region round 1
|
|
72
|
+
const userMsg1 = await user.initDerive();
|
|
73
|
+
const backupMsg1 = await backup.initDerive();
|
|
74
|
+
const bitgoUserPairMsg1 = await bitgoUserPair.initDerive();
|
|
75
|
+
const bitgoBackupPairMsg1 = await bitgoBackupPair.initDerive();
|
|
76
|
+
const userMsg2 = user.handleIncomingMessages({
|
|
77
|
+
p2pMessages: [],
|
|
78
|
+
broadcastMessages: [{ payload: bitgoUserPairMsg1.payload, from: bitgoUserPairMsg1.from }],
|
|
79
|
+
});
|
|
80
|
+
const bitgoUserPairMsg2 = bitgoUserPair.handleIncomingMessages({
|
|
81
|
+
p2pMessages: [],
|
|
82
|
+
broadcastMessages: [{ payload: userMsg1.payload, from: userMsg1.from }],
|
|
83
|
+
});
|
|
84
|
+
const backupMsg2 = backup.handleIncomingMessages({
|
|
85
|
+
p2pMessages: [],
|
|
86
|
+
broadcastMessages: [{ payload: bitgoBackupPairMsg1.payload, from: bitgoBackupPairMsg1.from }],
|
|
87
|
+
});
|
|
88
|
+
const bitgoBackupPairMsg2 = bitgoBackupPair.handleIncomingMessages({
|
|
89
|
+
p2pMessages: [],
|
|
90
|
+
broadcastMessages: [{ payload: backupMsg1.payload, from: backupMsg1.from }],
|
|
91
|
+
});
|
|
92
|
+
// #endregion
|
|
93
|
+
// #region round 2
|
|
94
|
+
user.handleIncomingMessages({
|
|
95
|
+
p2pMessages: [],
|
|
96
|
+
broadcastMessages: [{ payload: bitgoUserPairMsg2.broadcastMessages[0].payload, from: 2 }],
|
|
97
|
+
});
|
|
98
|
+
bitgoUserPair.handleIncomingMessages({
|
|
99
|
+
p2pMessages: [],
|
|
100
|
+
broadcastMessages: [{ payload: userMsg2.broadcastMessages[0].payload, from: 0 }],
|
|
101
|
+
});
|
|
102
|
+
backup.handleIncomingMessages({
|
|
103
|
+
p2pMessages: [],
|
|
104
|
+
broadcastMessages: [{ payload: bitgoBackupPairMsg2.broadcastMessages[0].payload, from: 2 }],
|
|
105
|
+
});
|
|
106
|
+
bitgoBackupPair.handleIncomingMessages({
|
|
107
|
+
p2pMessages: [],
|
|
108
|
+
broadcastMessages: [{ payload: backupMsg2.broadcastMessages[0].payload, from: 1 }],
|
|
109
|
+
});
|
|
110
|
+
// #endregion
|
|
111
|
+
return [user, backup, bitgoUserPair, bitgoBackupPair];
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy90c3MvZGtscy12cmYvdXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQVNBLDBEQThDQztBQWNELG9FQTREQztBQWhJRCxpREFBOEM7QUFDOUMsK0JBQStCO0FBRS9COzs7O0dBSUc7QUFDSSxLQUFLLFVBQVUsdUJBQXVCLENBQzNDLFFBQWlCLEVBQ2pCLFVBQW1CLEVBQ25CLFNBQWtCO0lBRWxCLE1BQU0sSUFBSSxHQUFHLElBQUksWUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzNDLE1BQU0sTUFBTSxHQUFHLElBQUksWUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQy9DLE1BQU0sS0FBSyxHQUFHLElBQUksWUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQzdDLGtCQUFrQjtJQUNsQixNQUFNLGtCQUFrQixHQUFHLE1BQU0sSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2hELE1BQU0sb0JBQW9CLEdBQUcsTUFBTSxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDcEQsTUFBTSxtQkFBbUIsR0FBRyxNQUFNLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNsRCxNQUFNLG1CQUFtQixHQUFHLE1BQU0sS0FBSyxDQUFDLHNCQUFzQixDQUFDO1FBQzdELFdBQVcsRUFBRSxFQUFFO1FBQ2YsaUJBQWlCLEVBQUUsQ0FBQyxHQUFHLGtCQUFrQixDQUFDLGlCQUFpQixFQUFFLEdBQUcsb0JBQW9CLENBQUMsaUJBQWlCLENBQUM7S0FDeEcsQ0FBQyxDQUFDO0lBQ0gsYUFBYTtJQUViLGtCQUFrQjtJQUNsQixNQUFNLGtCQUFrQixHQUFHLE1BQU0sSUFBSSxDQUFDLHNCQUFzQixDQUFDO1FB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ZSB9IGZyb20gJy4uL2VjZHNhLWRrbHMvZGVyaXZlJztcbmltcG9ydCB7IFZyZkRrZyB9IGZyb20gJy4vZGtnJztcblxuLyoqXG4gKiBSdW5zIGEgbG9jYWwgMi1vZi0zIFZSRiBES0cgYWNyb3NzIHVzZXIgKDApLCBiYWNrdXAgKDEpIGFuZCBiaXRnbyAoMikgcGFydGllcyBhbmRcbiAqIHJldHVybnMgdGhlIHRocmVlIGNvbXBsZXRlZCBWcmZEa2cgc2Vzc2lvbnMsIG1pcnJvcmluZyBgZ2VuZXJhdGVES0dLZXlTaGFyZXNgIGZyb21cbiAqIGBlY2RzYS1ka2xzL3V0aWwudHNgIHNvIFZSRiB0ZXN0cyByZWFkIGxpa2UgdGhlIGV4aXN0aW5nIERLTFMgb25lcy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlVnJmREtHS2V5U2hhcmVzKFxuICBzZWVkVXNlcj86IEJ1ZmZlcixcbiAgc2VlZEJhY2t1cD86IEJ1ZmZlcixcbiAgc2VlZEJpdGdvPzogQnVmZmVyXG4pOiBQcm9taXNlPFtWcmZEa2csIFZyZkRrZywgVnJmRGtnXT4ge1xuICBjb25zdCB1c2VyID0gbmV3IFZyZkRrZygzLCAyLCAwLCBzZWVkVXNlcik7XG4gIGNvbnN0IGJhY2t1cCA9IG5ldyBWcmZEa2coMywgMiwgMSwgc2VlZEJhY2t1cCk7XG4gIGNvbnN0IGJpdGdvID0gbmV3IFZyZkRrZygzLCAyLCAyLCBzZWVkQml0Z28pO1xuICAvLyAjcmVnaW9uIHJvdW5kIDFcbiAgY29uc3QgdXNlclJvdW5kMU1lc3NhZ2VzID0gYXdhaXQgdXNlci5pbml0RGtnKCk7XG4gIGNvbnN0IGJhY2t1cFJvdW5kMU1lc3NhZ2VzID0gYXdhaXQgYmFja3VwLmluaXREa2coKTtcbiAgY29uc3QgYml0Z29Sb3VuZDFNZXNzYWdlcyA9IGF3YWl0IGJpdGdvLmluaXREa2coKTtcbiAgY29uc3QgYml0Z29Sb3VuZDJNZXNzYWdlcyA9IGF3YWl0IGJpdGdvLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgIHAycE1lc3NhZ2VzOiBbXSxcbiAgICBicm9hZGNhc3RNZXNzYWdlczogWy4uLnVzZXJSb3VuZDFNZXNzYWdlcy5icm9hZGNhc3RNZXNzYWdlcywgLi4uYmFja3VwUm91bmQxTWVzc2FnZXMuYnJvYWRjYXN0TWVzc2FnZXNdLFxuICB9KTtcbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gcm91bmQgMlxuICBjb25zdCB1c2VyUm91bmQyTWVzc2FnZXMgPSBhd2FpdCB1c2VyLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgIHAycE1lc3NhZ2VzOiBbXSxcbiAgICBicm9hZGNhc3RNZXNzYWdlczogWy4uLmJpdGdvUm91bmQxTWVzc2FnZXMuYnJvYWRjYXN0TWVzc2FnZXMsIC4uLmJhY2t1cFJvdW5kMU1lc3NhZ2VzLmJyb2FkY2FzdE1lc3NhZ2VzXSxcbiAgfSk7XG4gIGNvbnN0IGJhY2t1cFJvdW5kMk1lc3NhZ2VzID0gYXdhaXQgYmFja3VwLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgIHAycE1lc3NhZ2VzOiBbXSxcbiAgICBicm9hZGNhc3RNZXNzYWdlczogWy4uLnVzZXJSb3VuZDFNZXNzYWdlcy5icm9hZGNhc3RNZXNzYWdlcywgLi4uYml0Z29Sb3VuZDFNZXNzYWdlcy5icm9hZGNhc3RNZXNzYWdlc10sXG4gIH0pO1xuICBhd2FpdCBiaXRnby5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKHtcbiAgICBwMnBNZXNzYWdlczogW2JpdGdvUm91bmQyTWVzc2FnZXMsIHVzZXJSb3VuZDJNZXNzYWdlcywgYmFja3VwUm91bmQyTWVzc2FnZXNdXG4gICAgICAuZmxhdE1hcCgobSkgPT4gbS5wMnBNZXNzYWdlcylcbiAgICAgIC5maWx0ZXIoKG0pID0+IG0udG8gPT09IDIpLFxuICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbXSxcbiAgfSk7XG4gIGF3YWl0IHVzZXIuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgcDJwTWVzc2FnZXM6IFtiaXRnb1JvdW5kMk1lc3NhZ2VzLCB1c2VyUm91bmQyTWVzc2FnZXMsIGJhY2t1cFJvdW5kMk1lc3NhZ2VzXVxuICAgICAgLmZsYXRNYXAoKG0pID0+IG0ucDJwTWVzc2FnZXMpXG4gICAgICAuZmlsdGVyKChtKSA9PiBtLnRvID09PSAwKSxcbiAgICBicm9hZGNhc3RNZXNzYWdlczogW10sXG4gIH0pO1xuICBhd2FpdCBiYWNrdXAuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgcDJwTWVzc2FnZXM6IFtiaXRnb1JvdW5kMk1lc3NhZ2VzLCB1c2VyUm91bmQyTWVzc2FnZXMsIGJhY2t1cFJvdW5kMk1lc3NhZ2VzXVxuICAgICAgLmZsYXRNYXAoKG0pID0+IG0ucDJwTWVzc2FnZXMpXG4gICAgICAuZmlsdGVyKChtKSA9PiBtLnRvID09PSAxKSxcbiAgICBicm9hZGNhc3RNZXNzYWdlczogW10sXG4gIH0pO1xuICByZXR1cm4gW3VzZXIsIGJhY2t1cCwgYml0Z29dO1xufVxuXG4vKipcbiAqIFJ1bnMgdGhlIGhhcmQtZGVyaXZhdGlvbiBjZXJlbW9ueSBvbiB0b3Agb2YgY29tcGxldGVkIHJvb3Qgc2Vzc2lvbnM6IHRoZSB1c2VyICgwKVxuICogaGFyZC1kZXJpdmUgc2Vzc2lvbiBwYWlycyB3aXRoIGEgZnJlc2ggQml0R28gKDIpIHNlc3Npb24sIGFuZCB0aGUgYmFja3VwICgxKVxuICogc2Vzc2lvbiB3aXRoIGEgc2Vjb25kIGZyZXNoIEJpdEdvIHNlc3Npb24uIFRoZSBoYXJkLWRlcml2ZSB3YXNtIHNlc3Npb24gaXMgYVxuICogMi1wYXJ0eSB0aHJlc2hvbGQgcHJvdG9jb2wgcGVyIGluc3RhbmNlLCBzbyB0aGUgQml0R28gc2VydmVyIHNpZGUgcnVucyB0d29cbiAqIHNlc3Npb25zIOKAlCBvbmUgcGVyIFNESyBwYXJ0eS4gQWxsIGZvdXIgZGVyaXZlZCBrZXlzaGFyZXMgYWdyZWUgb24gdGhlIGNoaWxkXG4gKiBwdWJsaWMga2V5OyB0aGUgdHdvIEJpdEdvIHNoYXJlcyBhcmUgZGlzdGluY3QgcHJpdmF0ZSBzaGFyZXMgb2YgdGhhdCBzYW1lIGtleS5cbiAqXG4gKiBAcGFyYW0gcGF0aCBoYXJkZW5lZCBkZXJpdmF0aW9uIHBhdGggYnl0ZXMgKGUuZy4gYG0vMCdgIGFzIGEgNC1ieXRlIGJpZy1lbmRpYW5cbiAqICAgaW5kZXggd2l0aCB0aGUgaGFyZGVuZWQgYml0IHNldClcbiAqIEByZXR1cm5zIFt1c2VyLCBiYWNrdXAsIGJpdGdvVXNlclBhaXIsIGJpdGdvQmFja3VwUGFpcl0gY29tcGxldGVkIERlcml2ZSBzZXNzaW9uc1xuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGVIYXJkRGVyaXZlZEtleVNoYXJlcyhcbiAgdXNlclJvb3Q6IHsgZ2V0S2V5U2hhcmUoKTogQnVmZmVyIH0sXG4gIGJhY2t1cFJvb3Q6IHsgZ2V0S2V5U2hhcmUoKTogQnVmZmVyIH0sXG4gIGJpdGdvUm9vdDogeyBnZXRLZXlTaGFyZSgpOiBCdWZmZXIgfSxcbiAgdXNlclZyZjogVnJmRGtnLFxuICBiYWNrdXBWcmY6IFZyZkRrZyxcbiAgYml0Z29WcmY6IFZyZkRrZyxcbiAgcGF0aDogVWludDhBcnJheSxcbiAgc2VlZFVzZXI/OiBCdWZmZXIsXG4gIHNlZWRCYWNrdXA/OiBCdWZmZXJcbik6IFByb21pc2U8W0Rlcml2ZSwgRGVyaXZlLCBEZXJpdmUsIERlcml2ZV0+IHtcbiAgY29uc3QgdXNlciA9IG5ldyBEZXJpdmUoMywgMiwgMCwgdXNlclJvb3QuZ2V0S2V5U2hhcmUoKSwgdXNlclZyZi5nZXRLZXlTaGFyZSgpLCBwYXRoLCBzZWVkVXNlcik7XG4gIGNvbnN0IGJhY2t1cCA9IG5ldyBEZXJpdmUoMywgMiwgMSwgYmFja3VwUm9vdC5nZXRLZXlTaGFyZSgpLCBiYWNrdXBWcmYuZ2V0S2V5U2hhcmUoKSwgcGF0aCwgc2VlZEJhY2t1cCk7XG4gIGNvbnN0IGJpdGdvVXNlclBhaXIgPSBuZXcgRGVyaXZlKDMsIDIsIDIsIGJpdGdvUm9vdC5nZXRLZXlTaGFyZSgpLCBiaXRnb1ZyZi5nZXRLZXlTaGFyZSgpLCBwYXRoKTtcbiAgY29uc3QgYml0Z29CYWNrdXBQYWlyID0gbmV3IERlcml2ZSgzLCAyLCAyLCBiaXRnb1Jvb3QuZ2V0S2V5U2hhcmUoKSwgYml0Z29WcmYuZ2V0S2V5U2hhcmUoKSwgcGF0aCk7XG5cbiAgLy8gI3JlZ2lvbiByb3VuZCAxXG4gIGNvbnN0IHVzZXJNc2cxID0gYXdhaXQgdXNlci5pbml0RGVyaXZlKCk7XG4gIGNvbnN0IGJhY2t1cE1zZzEgPSBhd2FpdCBiYWNrdXAuaW5pdERlcml2ZSgpO1xuICBjb25zdCBiaXRnb1VzZXJQYWlyTXNnMSA9IGF3YWl0IGJpdGdvVXNlclBhaXIuaW5pdERlcml2ZSgpO1xuICBjb25zdCBiaXRnb0JhY2t1cFBhaXJNc2cxID0gYXdhaXQgYml0Z29CYWNrdXBQYWlyLmluaXREZXJpdmUoKTtcblxuICBjb25zdCB1c2VyTXNnMiA9IHVzZXIuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgcDJwTWVzc2FnZXM6IFtdLFxuICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbeyBwYXlsb2FkOiBiaXRnb1VzZXJQYWlyTXNnMS5wYXlsb2FkLCBmcm9tOiBiaXRnb1VzZXJQYWlyTXNnMS5mcm9tIH1dLFxuICB9KTtcbiAgY29uc3QgYml0Z29Vc2VyUGFpck1zZzIgPSBiaXRnb1VzZXJQYWlyLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgIHAycE1lc3NhZ2VzOiBbXSxcbiAgICBicm9hZGNhc3RNZXNzYWdlczogW3sgcGF5bG9hZDogdXNlck1zZzEucGF5bG9hZCwgZnJvbTogdXNlck1zZzEuZnJvbSB9XSxcbiAgfSk7XG4gIGNvbnN0IGJhY2t1cE1zZzIgPSBiYWNrdXAuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgcDJwTWVzc2FnZXM6IFtdLFxuICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbeyBwYXlsb2FkOiBiaXRnb0JhY2t1cFBhaXJNc2cxLnBheWxvYWQsIGZyb206IGJpdGdvQmFja3VwUGFpck1zZzEuZnJvbSB9XSxcbiAgfSk7XG4gIGNvbnN0IGJpdGdvQmFja3VwUGFpck1zZzIgPSBiaXRnb0JhY2t1cFBhaXIuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyh7XG4gICAgcDJwTWVzc2FnZXM6IFtdLFxuICAgIGJyb2FkY2FzdE1lc3NhZ2VzOiBbeyBwYXlsb2FkOiBiYWNrdXBNc2cxLnBheWxvYWQsIGZyb206IGJhY2t1cE1zZzEuZnJvbSB9XSxcbiAgfSk7XG4gIC8vICNlbmRyZWdpb25cblxuICAvLyAjcmVnaW9uIHJvdW5kIDJcbiAgdXNlci5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKHtcbiAgICBwMnBNZXNzYWdlczogW10sXG4gICAgYnJvYWRjYXN0TWVzc2FnZXM6IFt7IHBheWxvYWQ6IGJpdGdvVXNlclBhaXJNc2cyLmJyb2FkY2FzdE1lc3NhZ2VzWzBdLnBheWxvYWQsIGZyb206IDIgfV0sXG4gIH0pO1xuICBiaXRnb1VzZXJQYWlyLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgIHAycE1lc3NhZ2VzOiBbXSxcbiAgICBicm9hZGNhc3RNZXNzYWdlczogW3sgcGF5bG9hZDogdXNlck1zZzIuYnJvYWRjYXN0TWVzc2FnZXNbMF0ucGF5bG9hZCwgZnJvbTogMCB9XSxcbiAgfSk7XG4gIGJhY2t1cC5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKHtcbiAgICBwMnBNZXNzYWdlczogW10sXG4gICAgYnJvYWRjYXN0TWVzc2FnZXM6IFt7IHBheWxvYWQ6IGJpdGdvQmFja3VwUGFpck1zZzIuYnJvYWRjYXN0TWVzc2FnZXNbMF0ucGF5bG9hZCwgZnJvbTogMiB9XSxcbiAgfSk7XG4gIGJpdGdvQmFja3VwUGFpci5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKHtcbiAgICBwMnBNZXNzYWdlczogW10sXG4gICAgYnJvYWRjYXN0TWVzc2FnZXM6IFt7IHBheWxvYWQ6IGJhY2t1cE1zZzIuYnJvYWRjYXN0TWVzc2FnZXNbMF0ucGF5bG9hZCwgZnJvbTogMSB9XSxcbiAgfSk7XG4gIC8vICNlbmRyZWdpb25cblxuICByZXR1cm4gW3VzZXIsIGJhY2t1cCwgYml0Z29Vc2VyUGFpciwgYml0Z29CYWNrdXBQYWlyXTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import type { HardDeriveSession as DklsHardDeriveSession, VrfKeygenSession as DklsVrfKeygenSession } from '@silencelaboratories/dkls-wasm-ll-vrf-node';
|
|
2
|
+
import type { HardDeriveSession as DklsVrfWebHardDeriveSession, VrfKeygenSession as DklsVrfWebKeygenSession } from '@silencelaboratories/dkls-wasm-ll-vrf-web';
|
|
3
|
+
import { Buffer } from 'buffer';
|
|
4
|
+
import { DeserializedBroadcastMessage, DeserializedMessages } from './types';
|
|
5
|
+
type NodeVrfWasmer = typeof import('@silencelaboratories/dkls-wasm-ll-vrf-node');
|
|
6
|
+
type WebVrfWasmer = typeof import('@silencelaboratories/dkls-wasm-ll-vrf-web');
|
|
7
|
+
type BundlerVrfWasmer = typeof import('@silencelaboratories/dkls-wasm-ll-vrf-bundler');
|
|
8
|
+
type VrfWasm = NodeVrfWasmer | WebVrfWasmer | BundlerVrfWasmer;
|
|
9
|
+
export type { DklsHardDeriveSession, DklsVrfWebHardDeriveSession, DklsVrfKeygenSession, DklsVrfWebKeygenSession };
|
|
10
|
+
export declare enum DeriveState {
|
|
11
|
+
Uninitialized = 0,
|
|
12
|
+
Round1 = 1,
|
|
13
|
+
Round2 = 2,
|
|
14
|
+
Complete = 3,
|
|
15
|
+
InvalidState = 4
|
|
16
|
+
}
|
|
17
|
+
export interface DeriveSessionData {
|
|
18
|
+
deriveSessionBytes: Uint8Array;
|
|
19
|
+
deriveState: DeriveState;
|
|
20
|
+
keyShareBuff?: Buffer;
|
|
21
|
+
ownMsg1?: Uint8Array;
|
|
22
|
+
ownMsg2?: Uint8Array;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Round driver for the DKLS23 hard-derivation protocol (Ristretto VRF backed),
|
|
26
|
+
* which derives a child signing keyshare from a root keyshare and its VRF keyshare.
|
|
27
|
+
*
|
|
28
|
+
* Each session is a 2-party threshold protocol between this party and one partner:
|
|
29
|
+
* every round accepts exactly two broadcast messages — this party's own (created by
|
|
30
|
+
* `initDerive()` and re-fed automatically) and the partner's. A ceremony runs one
|
|
31
|
+
* `Derive` per SDK party, each paired with the BitGo party:
|
|
32
|
+
*
|
|
33
|
+
* - Round 1 (`WaitMsg1`): consume `{own msg1, partner msg1}`, emit own broadcast msg2.
|
|
34
|
+
* - Round 2 (`WaitMsg2`): consume `{own msg2, partner msg2}`, finalize the session
|
|
35
|
+
* and extract the derived DKLS `Keyshare`.
|
|
36
|
+
*
|
|
37
|
+
* The session is seeded from the decrypted root blob: the DKLS signing keyshare and
|
|
38
|
+
* the Ristretto VRF keyshare produced by root keygen, plus the child's hardened
|
|
39
|
+
* derivation path.
|
|
40
|
+
*
|
|
41
|
+
* Party indices follow the MPCv2 convention: 0 = user, 1 = backup, 2 = bitgo.
|
|
42
|
+
*/
|
|
43
|
+
export declare class Derive {
|
|
44
|
+
protected deriveSession: DklsHardDeriveSession | DklsVrfWebHardDeriveSession | undefined;
|
|
45
|
+
protected deriveSessionBytes: Uint8Array;
|
|
46
|
+
protected keyShareBuff: Buffer | undefined;
|
|
47
|
+
protected n: number;
|
|
48
|
+
protected t: number;
|
|
49
|
+
protected partyIdx: number;
|
|
50
|
+
protected rootKeyShare: Buffer;
|
|
51
|
+
protected vrfKeyShare: Buffer;
|
|
52
|
+
protected path: Uint8Array;
|
|
53
|
+
protected seed: Buffer | undefined;
|
|
54
|
+
protected deriveState: DeriveState;
|
|
55
|
+
protected vrfWasm: VrfWasm | null;
|
|
56
|
+
protected ownMsg1: Uint8Array | undefined;
|
|
57
|
+
protected ownMsg2: Uint8Array | undefined;
|
|
58
|
+
constructor(n: number, t: number, partyIdx: number, rootKeyShare: Buffer, vrfKeyShare: Buffer, path: Uint8Array, seed?: Buffer, vrfWasm?: BundlerVrfWasmer);
|
|
59
|
+
private loadVrfWasm;
|
|
60
|
+
private getVrfWasm;
|
|
61
|
+
private _restoreSession;
|
|
62
|
+
/**
|
|
63
|
+
* Re-derive the round state from the wasm session bytes instead of trusting a
|
|
64
|
+
* caller-supplied enum. The wasm embeds the round tag (`WaitMsg1`/`WaitMsg2`,
|
|
65
|
+
* then a `Share` payload once finalized) for exactly this reason.
|
|
66
|
+
*/
|
|
67
|
+
private _deserializeState;
|
|
68
|
+
/**
|
|
69
|
+
* Create this party's first hard-derive message (broadcast). Seeds the wasm
|
|
70
|
+
* session from the root keyshare, VRF keyshare and derivation path.
|
|
71
|
+
*/
|
|
72
|
+
initDerive(): Promise<DeserializedBroadcastMessage>;
|
|
73
|
+
/**
|
|
74
|
+
* Process the messages this party holds for the current round and return this
|
|
75
|
+
* party's messages for the next round. Callers pass the partner's broadcast
|
|
76
|
+
* message only; this party's own message is re-fed automatically because the
|
|
77
|
+
* wasm session validates the sender set as `{self, partner}`.
|
|
78
|
+
*
|
|
79
|
+
* - Round 1 (WaitMsg1): consumes `{own msg1, partner msg1}` and emits this
|
|
80
|
+
* party's broadcast msg2.
|
|
81
|
+
* - Round 2 (WaitMsg2): consumes `{own msg2, partner msg2}` and finalizes the
|
|
82
|
+
* session, returning no messages.
|
|
83
|
+
*/
|
|
84
|
+
handleIncomingMessages(messagesForIthRound: DeserializedMessages): DeserializedMessages;
|
|
85
|
+
/**
|
|
86
|
+
* Get the derived DKLS keyshare bytes (CBOR `Keyshare`) once the derive is
|
|
87
|
+
* complete. This buffer is private key material.
|
|
88
|
+
*/
|
|
89
|
+
getKeyShare(): Buffer;
|
|
90
|
+
/**
|
|
91
|
+
* Returns a CBOR-encoded ReducedKeyShare buffer containing the derived party's
|
|
92
|
+
* private scalar (s_i) in the `prv` field. This buffer is private key material;
|
|
93
|
+
* the caller encrypts it as `reducedEncryptedPrv`, matching `Dkg.getReducedKeyShare`.
|
|
94
|
+
*/
|
|
95
|
+
getReducedKeyShare(): Buffer;
|
|
96
|
+
/**
|
|
97
|
+
* Get the current session data that can be used to restore the session later.
|
|
98
|
+
*
|
|
99
|
+
* The returned session bytes are secret key material — they carry this party's
|
|
100
|
+
* root keyshares. They must never be logged or persisted in the clear; the
|
|
101
|
+
* caller encrypts them exactly like the key share itself.
|
|
102
|
+
*/
|
|
103
|
+
getSessionData(): DeriveSessionData;
|
|
104
|
+
/**
|
|
105
|
+
* Restore a session snapshot captured after initDerive() or round 1 processing.
|
|
106
|
+
* Do not call this before initDerive() has created session bytes.
|
|
107
|
+
* The round state is re-derived from the wasm session bytes, not the caller enum.
|
|
108
|
+
*/
|
|
109
|
+
static restoreSession(n: number, t: number, partyIdx: number, rootKeyShare: Buffer, vrfKeyShare: Buffer, path: Uint8Array, sessionData: DeriveSessionData, seed?: Buffer, vrfWasm?: BundlerVrfWasmer): Promise<Derive>;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=derive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derive.d.ts","sourceRoot":"","sources":["../../../../src/tss/ecdsa-dkls/derive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,329 @@
|
|
|
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.Derive = exports.DeriveState = void 0;
|
|
37
|
+
const cbor_x_1 = require("cbor-x");
|
|
38
|
+
const buffer_1 = require("buffer");
|
|
39
|
+
const DERIVE_SEED_LENGTH = 32;
|
|
40
|
+
var DeriveState;
|
|
41
|
+
(function (DeriveState) {
|
|
42
|
+
DeriveState[DeriveState["Uninitialized"] = 0] = "Uninitialized";
|
|
43
|
+
DeriveState[DeriveState["Round1"] = 1] = "Round1";
|
|
44
|
+
DeriveState[DeriveState["Round2"] = 2] = "Round2";
|
|
45
|
+
DeriveState[DeriveState["Complete"] = 3] = "Complete";
|
|
46
|
+
DeriveState[DeriveState["InvalidState"] = 4] = "InvalidState";
|
|
47
|
+
})(DeriveState || (exports.DeriveState = DeriveState = {}));
|
|
48
|
+
/**
|
|
49
|
+
* Round driver for the DKLS23 hard-derivation protocol (Ristretto VRF backed),
|
|
50
|
+
* which derives a child signing keyshare from a root keyshare and its VRF keyshare.
|
|
51
|
+
*
|
|
52
|
+
* Each session is a 2-party threshold protocol between this party and one partner:
|
|
53
|
+
* every round accepts exactly two broadcast messages — this party's own (created by
|
|
54
|
+
* `initDerive()` and re-fed automatically) and the partner's. A ceremony runs one
|
|
55
|
+
* `Derive` per SDK party, each paired with the BitGo party:
|
|
56
|
+
*
|
|
57
|
+
* - Round 1 (`WaitMsg1`): consume `{own msg1, partner msg1}`, emit own broadcast msg2.
|
|
58
|
+
* - Round 2 (`WaitMsg2`): consume `{own msg2, partner msg2}`, finalize the session
|
|
59
|
+
* and extract the derived DKLS `Keyshare`.
|
|
60
|
+
*
|
|
61
|
+
* The session is seeded from the decrypted root blob: the DKLS signing keyshare and
|
|
62
|
+
* the Ristretto VRF keyshare produced by root keygen, plus the child's hardened
|
|
63
|
+
* derivation path.
|
|
64
|
+
*
|
|
65
|
+
* Party indices follow the MPCv2 convention: 0 = user, 1 = backup, 2 = bitgo.
|
|
66
|
+
*/
|
|
67
|
+
class Derive {
|
|
68
|
+
constructor(n, t, partyIdx, rootKeyShare, vrfKeyShare, path, seed, vrfWasm) {
|
|
69
|
+
this.deriveState = DeriveState.Uninitialized;
|
|
70
|
+
this.n = n;
|
|
71
|
+
this.t = t;
|
|
72
|
+
this.partyIdx = partyIdx;
|
|
73
|
+
this.rootKeyShare = rootKeyShare;
|
|
74
|
+
this.vrfKeyShare = vrfKeyShare;
|
|
75
|
+
this.path = path;
|
|
76
|
+
this.seed = seed;
|
|
77
|
+
this.vrfWasm = vrfWasm ?? null;
|
|
78
|
+
this.deriveSessionBytes = new Uint8Array(0);
|
|
79
|
+
}
|
|
80
|
+
async loadVrfWasm() {
|
|
81
|
+
if (!this.vrfWasm) {
|
|
82
|
+
this.vrfWasm = await Promise.resolve().then(() => __importStar(require('@silencelaboratories/dkls-wasm-ll-vrf-node')));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
getVrfWasm() {
|
|
86
|
+
if (!this.vrfWasm) {
|
|
87
|
+
throw Error('VRF wasm not loaded');
|
|
88
|
+
}
|
|
89
|
+
return this.vrfWasm;
|
|
90
|
+
}
|
|
91
|
+
_restoreSession() {
|
|
92
|
+
if (!this.deriveSession) {
|
|
93
|
+
this.deriveSession = this.getVrfWasm().HardDeriveSession.fromBytes(this.deriveSessionBytes);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Re-derive the round state from the wasm session bytes instead of trusting a
|
|
98
|
+
* caller-supplied enum. The wasm embeds the round tag (`WaitMsg1`/`WaitMsg2`,
|
|
99
|
+
* then a `Share` payload once finalized) for exactly this reason.
|
|
100
|
+
*/
|
|
101
|
+
_deserializeState() {
|
|
102
|
+
if (!this.deriveSession) {
|
|
103
|
+
throw Error('Session not initialized');
|
|
104
|
+
}
|
|
105
|
+
const decoded = (0, cbor_x_1.decode)(this.deriveSession.toBytes());
|
|
106
|
+
const round = decoded?.inner?.round;
|
|
107
|
+
if (round === 'WaitMsg1') {
|
|
108
|
+
this.deriveState = DeriveState.Round1;
|
|
109
|
+
}
|
|
110
|
+
else if (round === 'WaitMsg2') {
|
|
111
|
+
this.deriveState = DeriveState.Round2;
|
|
112
|
+
}
|
|
113
|
+
else if (decoded?.inner?.state?.Share !== undefined || this.deriveSession.isFinished()) {
|
|
114
|
+
this.deriveState = DeriveState.Complete;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
this.deriveState = DeriveState.InvalidState;
|
|
118
|
+
throw Error(`Invalid State: ${JSON.stringify(round)}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Create this party's first hard-derive message (broadcast). Seeds the wasm
|
|
123
|
+
* session from the root keyshare, VRF keyshare and derivation path.
|
|
124
|
+
*/
|
|
125
|
+
async initDerive() {
|
|
126
|
+
if (!this.vrfWasm) {
|
|
127
|
+
await this.loadVrfWasm();
|
|
128
|
+
}
|
|
129
|
+
if (this.t > this.n || this.partyIdx >= this.n) {
|
|
130
|
+
throw Error('Invalid parameters for hard derive');
|
|
131
|
+
}
|
|
132
|
+
if (this.deriveState !== DeriveState.Uninitialized) {
|
|
133
|
+
throw Error('Hard derive session already initialized');
|
|
134
|
+
}
|
|
135
|
+
if (this.seed && this.seed.length !== DERIVE_SEED_LENGTH) {
|
|
136
|
+
throw Error(`Seed should be ${DERIVE_SEED_LENGTH} bytes, got ${this.seed.length}.`);
|
|
137
|
+
}
|
|
138
|
+
if (typeof window !== 'undefined' &&
|
|
139
|
+
/* checks for electron processes */
|
|
140
|
+
!window.process &&
|
|
141
|
+
!window.process?.['type']) {
|
|
142
|
+
/* This is only needed for browsers/web because it uses fetch to resolve the wasm asset for the web */
|
|
143
|
+
const initVrf = await Promise.resolve().then(() => __importStar(require('@silencelaboratories/dkls-wasm-ll-vrf-web')));
|
|
144
|
+
await initVrf.default();
|
|
145
|
+
}
|
|
146
|
+
const { HardDeriveSession, Keyshare, VrfKeyshare } = this.getVrfWasm();
|
|
147
|
+
const rootKeyShare = Keyshare.fromBytes(this.rootKeyShare);
|
|
148
|
+
if (rootKeyShare.partyId !== this.partyIdx) {
|
|
149
|
+
throw Error(`Party index: ${this.partyIdx} does not match root key share partyId: ${rootKeyShare.partyId}`);
|
|
150
|
+
}
|
|
151
|
+
const vrfKeyShare = VrfKeyshare.fromBytes(this.vrfKeyShare);
|
|
152
|
+
if (vrfKeyShare.partyId !== this.partyIdx) {
|
|
153
|
+
throw Error(`Party index: ${this.partyIdx} does not match VRF key share partyId: ${vrfKeyShare.partyId}`);
|
|
154
|
+
}
|
|
155
|
+
this.deriveSession = this.seed
|
|
156
|
+
? new HardDeriveSession(rootKeyShare, vrfKeyShare, this.path, new Uint8Array(this.seed))
|
|
157
|
+
: new HardDeriveSession(rootKeyShare, vrfKeyShare, this.path);
|
|
158
|
+
try {
|
|
159
|
+
const message = this.deriveSession.createFirstMessage();
|
|
160
|
+
// Copy the payload out before freeing the wasm message object.
|
|
161
|
+
const payload = new Uint8Array(message.payload);
|
|
162
|
+
const from = message.from_id;
|
|
163
|
+
message.free();
|
|
164
|
+
this.ownMsg1 = payload;
|
|
165
|
+
this.deriveSessionBytes = this.deriveSession.toBytes();
|
|
166
|
+
this._deserializeState();
|
|
167
|
+
return { payload, from };
|
|
168
|
+
}
|
|
169
|
+
catch (e) {
|
|
170
|
+
throw Error(`Error while creating the first hard-derive message from party ${this.partyIdx}: ${e}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Process the messages this party holds for the current round and return this
|
|
175
|
+
* party's messages for the next round. Callers pass the partner's broadcast
|
|
176
|
+
* message only; this party's own message is re-fed automatically because the
|
|
177
|
+
* wasm session validates the sender set as `{self, partner}`.
|
|
178
|
+
*
|
|
179
|
+
* - Round 1 (WaitMsg1): consumes `{own msg1, partner msg1}` and emits this
|
|
180
|
+
* party's broadcast msg2.
|
|
181
|
+
* - Round 2 (WaitMsg2): consumes `{own msg2, partner msg2}` and finalizes the
|
|
182
|
+
* session, returning no messages.
|
|
183
|
+
*/
|
|
184
|
+
handleIncomingMessages(messagesForIthRound) {
|
|
185
|
+
this._restoreSession();
|
|
186
|
+
if (!this.deriveSession) {
|
|
187
|
+
throw Error('Session not initialized');
|
|
188
|
+
}
|
|
189
|
+
const { Message } = this.getVrfWasm();
|
|
190
|
+
let nextRoundMessages = [];
|
|
191
|
+
const nextRoundDeserializedMessages = { broadcastMessages: [], p2pMessages: [] };
|
|
192
|
+
try {
|
|
193
|
+
switch (this.deriveState) {
|
|
194
|
+
case DeriveState.Round1: {
|
|
195
|
+
const partnerMessages = messagesForIthRound.broadcastMessages.filter((m) => m.from !== this.partyIdx);
|
|
196
|
+
if (partnerMessages.length !== 1 || !this.ownMsg1) {
|
|
197
|
+
throw Error('Expected exactly one broadcast message from the derive partner in round 1');
|
|
198
|
+
}
|
|
199
|
+
nextRoundMessages = this.deriveSession.handleMessages([
|
|
200
|
+
new Message(this.ownMsg1, this.partyIdx),
|
|
201
|
+
new Message(partnerMessages[0].payload, partnerMessages[0].from),
|
|
202
|
+
]);
|
|
203
|
+
this._deserializeState();
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
case DeriveState.Round2: {
|
|
207
|
+
const partnerMessages = messagesForIthRound.broadcastMessages.filter((m) => m.from !== this.partyIdx);
|
|
208
|
+
if (partnerMessages.length !== 1 || !this.ownMsg2) {
|
|
209
|
+
throw Error('Expected exactly one broadcast message from the derive partner in round 2');
|
|
210
|
+
}
|
|
211
|
+
nextRoundMessages = this.deriveSession.handleMessages([
|
|
212
|
+
new Message(this.ownMsg2, this.partyIdx),
|
|
213
|
+
new Message(partnerMessages[0].payload, partnerMessages[0].from),
|
|
214
|
+
]);
|
|
215
|
+
// handleMessages() consumes the session; keyshare() extracts the derived share.
|
|
216
|
+
const keyShare = this.deriveSession.keyshare();
|
|
217
|
+
this.keyShareBuff = buffer_1.Buffer.from(keyShare.toBytes());
|
|
218
|
+
keyShare.free();
|
|
219
|
+
this.deriveState = DeriveState.Complete;
|
|
220
|
+
return nextRoundDeserializedMessages;
|
|
221
|
+
}
|
|
222
|
+
default:
|
|
223
|
+
throw Error(`Invalid hard-derive state: ${this.deriveState}`);
|
|
224
|
+
}
|
|
225
|
+
nextRoundDeserializedMessages.broadcastMessages = nextRoundMessages
|
|
226
|
+
.filter((m) => m.to_id === undefined)
|
|
227
|
+
.map((m) => ({ payload: new Uint8Array(m.payload), from: m.from_id }));
|
|
228
|
+
nextRoundDeserializedMessages.p2pMessages = nextRoundMessages
|
|
229
|
+
.filter((m) => m.to_id !== undefined)
|
|
230
|
+
.map((m) => ({ payload: new Uint8Array(m.payload), from: m.from_id, to: m.to_id }));
|
|
231
|
+
// The round-1 output is this party's msg2, re-fed into the session on round 2.
|
|
232
|
+
const ownMsg2 = nextRoundDeserializedMessages.broadcastMessages.find((m) => m.from === this.partyIdx);
|
|
233
|
+
if (ownMsg2) {
|
|
234
|
+
this.ownMsg2 = ownMsg2.payload;
|
|
235
|
+
}
|
|
236
|
+
return nextRoundDeserializedMessages;
|
|
237
|
+
}
|
|
238
|
+
catch (e) {
|
|
239
|
+
throw Error(`Error while creating hard-derive messages from party ${this.partyIdx}, state ${this.deriveState}: ${e}`);
|
|
240
|
+
}
|
|
241
|
+
finally {
|
|
242
|
+
nextRoundMessages.forEach((m) => m.free());
|
|
243
|
+
// keyshare() consumed (and deallocated) the session on round 2; only persist
|
|
244
|
+
// mid-protocol session bytes while the session object still exists.
|
|
245
|
+
if (this.deriveState !== DeriveState.Complete && this.deriveSession) {
|
|
246
|
+
this.deriveSessionBytes = this.deriveSession.toBytes();
|
|
247
|
+
}
|
|
248
|
+
this.deriveSession = undefined;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Get the derived DKLS keyshare bytes (CBOR `Keyshare`) once the derive is
|
|
253
|
+
* complete. This buffer is private key material.
|
|
254
|
+
*/
|
|
255
|
+
getKeyShare() {
|
|
256
|
+
if (!this.keyShareBuff) {
|
|
257
|
+
throw Error('Can not get key share, hard derive is not complete yet.');
|
|
258
|
+
}
|
|
259
|
+
return this.keyShareBuff;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Returns a CBOR-encoded ReducedKeyShare buffer containing the derived party's
|
|
263
|
+
* private scalar (s_i) in the `prv` field. This buffer is private key material;
|
|
264
|
+
* the caller encrypts it as `reducedEncryptedPrv`, matching `Dkg.getReducedKeyShare`.
|
|
265
|
+
*/
|
|
266
|
+
getReducedKeyShare() {
|
|
267
|
+
if (!this.keyShareBuff) {
|
|
268
|
+
throw Error('Can not get key share, hard derive is not complete yet.');
|
|
269
|
+
}
|
|
270
|
+
const decodedKeyshare = (0, cbor_x_1.decode)(this.keyShareBuff);
|
|
271
|
+
const reducedKeyShare = {
|
|
272
|
+
bigSList: decodedKeyshare.big_s_list,
|
|
273
|
+
xList: decodedKeyshare.x_i_list,
|
|
274
|
+
rootChainCode: decodedKeyshare.root_chain_code,
|
|
275
|
+
prv: decodedKeyshare.s_i,
|
|
276
|
+
pub: decodedKeyshare.public_key,
|
|
277
|
+
};
|
|
278
|
+
return buffer_1.Buffer.from((0, cbor_x_1.encode)(reducedKeyShare));
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Get the current session data that can be used to restore the session later.
|
|
282
|
+
*
|
|
283
|
+
* The returned session bytes are secret key material — they carry this party's
|
|
284
|
+
* root keyshares. They must never be logged or persisted in the clear; the
|
|
285
|
+
* caller encrypts them exactly like the key share itself.
|
|
286
|
+
*/
|
|
287
|
+
getSessionData() {
|
|
288
|
+
const sessionData = {
|
|
289
|
+
deriveSessionBytes: this.deriveSessionBytes,
|
|
290
|
+
deriveState: this.deriveState,
|
|
291
|
+
};
|
|
292
|
+
if (this.keyShareBuff) {
|
|
293
|
+
sessionData.keyShareBuff = this.keyShareBuff;
|
|
294
|
+
}
|
|
295
|
+
if (this.ownMsg1) {
|
|
296
|
+
sessionData.ownMsg1 = this.ownMsg1;
|
|
297
|
+
}
|
|
298
|
+
if (this.ownMsg2) {
|
|
299
|
+
sessionData.ownMsg2 = this.ownMsg2;
|
|
300
|
+
}
|
|
301
|
+
return sessionData;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Restore a session snapshot captured after initDerive() or round 1 processing.
|
|
305
|
+
* Do not call this before initDerive() has created session bytes.
|
|
306
|
+
* The round state is re-derived from the wasm session bytes, not the caller enum.
|
|
307
|
+
*/
|
|
308
|
+
static async restoreSession(n, t, partyIdx, rootKeyShare, vrfKeyShare, path, sessionData, seed, vrfWasm) {
|
|
309
|
+
const derive = new Derive(n, t, partyIdx, rootKeyShare, vrfKeyShare, path, seed, vrfWasm);
|
|
310
|
+
if (!derive.vrfWasm) {
|
|
311
|
+
await derive.loadVrfWasm();
|
|
312
|
+
}
|
|
313
|
+
derive.deriveSessionBytes = sessionData.deriveSessionBytes;
|
|
314
|
+
if (sessionData.keyShareBuff) {
|
|
315
|
+
derive.keyShareBuff = sessionData.keyShareBuff;
|
|
316
|
+
}
|
|
317
|
+
if (sessionData.ownMsg1) {
|
|
318
|
+
derive.ownMsg1 = sessionData.ownMsg1;
|
|
319
|
+
}
|
|
320
|
+
if (sessionData.ownMsg2) {
|
|
321
|
+
derive.ownMsg2 = sessionData.ownMsg2;
|
|
322
|
+
}
|
|
323
|
+
derive._restoreSession();
|
|
324
|
+
derive._deserializeState();
|
|
325
|
+
return derive;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
exports.Derive = Derive;
|
|
329
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVyaXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3Rzcy9lY2RzYS1ka2xzL2Rlcml2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFTQSxtQ0FBd0M7QUFDeEMsbUNBQWdDO0FBWWhDLE1BQU0sa0JBQWtCLEdBQUcsRUFBRSxDQUFDO0FBSTlCLElBQVksV0FNWDtBQU5ELFdBQVksV0FBVztJQUNyQiwrREFBYSxDQUFBO0lBQ2IsaURBQU0sQ0FBQTtJQUNOLGlEQUFNLENBQUE7SUFDTixxREFBUSxDQUFBO0lBQ1IsNkRBQVksQ0FBQTtBQUNkLENBQUMsRUFOVyxXQUFXLDJCQUFYLFdBQVcsUUFNdEI7QUFZRDs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBQ0gsTUFBYSxNQUFNO0lBa0JqQixZQUNFLENBQVMsRUFDVCxDQUFTLEVBQ1QsUUFBZ0IsRUFDaEIsWUFBb0IsRUFDcEIsV0FBbUIsRUFDbkIsSUFBZ0IsRUFDaEIsSUFBYSxFQUNiLE9BQTBCO1FBZmxCLGdCQUFXLEdBQWdCLFdBQVcsQ0FBQyxhQUFhLENBQUM7UUFpQjdELElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ1gsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDWCxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUN6QixJQUFJLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQztRQUNqQyxJQUFJLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztRQUMvQixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sSUFBSSxJQUFJLENBQUM7UUFDL0IsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFD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b24gYXMgRGtsc0hhcmREZXJpdmVTZXNzaW9uLFxuICBNZXNzYWdlIGFzIFZyZldhc21NZXNzYWdlLFxuICBWcmZLZXlnZW5TZXNzaW9uIGFzIERrbHNWcmZLZXlnZW5TZXNzaW9uLFxufSBmcm9tICdAc2lsZW5jZWxhYm9yYXRvcmllcy9ka2xzLXdhc20tbGwtdnJmLW5vZGUnO1xuaW1wb3J0IHR5cGUge1xuICBIYXJkRGVyaXZlU2Vzc2lvbiBhcyBEa2xzVnJmV2ViSGFyZERlcml2ZVNlc3Npb24sXG4gIFZyZktleWdlblNlc3Npb24gYXMgRGtsc1ZyZldlYktleWdlblNlc3Npb24sXG59IGZyb20gJ0BzaWxlbmNlbGFib3JhdG9yaWVzL2RrbHMtd2FzbS1sbC12cmYtd2ViJztcbmltcG9ydCB7IGRlY29kZSwgZW5jb2RlIH0gZnJvbSAnY2Jvci14JztcbmltcG9ydCB7IEJ1ZmZlciB9IGZyb20gJ2J1ZmZlcic7XG5pbXBvcnQgeyBEZXNlcmlhbGl6ZWRCcm9hZGNhc3RNZXNzYWdlLCBEZXNlcmlhbGl6ZWRNZXNzYWdlcywgUmVkdWNlZEtleVNoYXJlIH0gZnJvbSAnLi90eXBlcyc7XG5cbi8vIFBsYXRmb3JtLXNwZWNpZmljIG1vZHVsZXMgdGhhdCBkbyBub3QgZXhpc3QgZXZlcnl3aGVyZTogdGhlIG5vZGUvd2ViL2J1bmRsZXIgd2FzbVxuLy8gdmFyaWFudHMgYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZSBhbmQgc2VsZWN0ZWQgYXQgcnVudGltZSAobm9kZSBwcm9jZXNzIHZzIGJyb3dzZXIgdnNcbi8vIGJ1bmRsZXIpLiBTdGF0aWMgaW1wb3J0cyB3b3VsZCBsb2FkIHRoZSB3cm9uZyBwbGF0Zm9ybSdzIHdhc20gYmluZGluZywgc28gYm90aCB0aGVcbi8vIHR5cGUgYWxpYXNlcyBiZWxvdyBhbmQgdGhlIGxhenkgYGF3YWl0IGltcG9ydCgpYCBjYWxscyBhcmUgZGVsaWJlcmF0ZS5cbnR5cGUgTm9kZVZyZldhc21lciA9IHR5cGVvZiBpbXBvcnQoJ0BzaWxlbmNlbGFib3JhdG9yaWVzL2RrbHMtd2FzbS1sbC12cmYtbm9kZScpO1xudHlwZSBXZWJWcmZXYXNtZXIgPSB0eXBlb2YgaW1wb3J0KCdAc2lsZW5jZWxhYm9yYXRvcmllcy9ka2xzLXdhc20tbGwtdnJmLXdlYicpO1xudHlwZSBCdW5kbGVyVnJmV2FzbWVyID0gdHlwZW9mIGltcG9ydCgnQHNpbGVuY2VsYWJvcmF0b3JpZXMvZGtscy13YXNtLWxsLXZyZi1idW5kbGVyJyk7XG5cbnR5cGUgVnJmV2FzbSA9IE5vZGVWcmZXYXNtZXIgfCBXZWJWcmZXYXNtZXIgfCBCdW5kbGVyVnJmV2FzbWVyO1xuY29uc3QgREVSSVZFX1NFRURfTEVOR1RIID0gMzI7XG5cbmV4cG9ydCB0eXBlIHsgRGtsc0hhcmREZXJpdmVTZXNzaW9uLCBEa2xzVnJmV2ViSGFyZERlcml2ZVNlc3Npb24sIERrbHNWcmZLZXlnZW5TZXNzaW9uLCBEa2xzVnJmV2ViS2V5Z2VuU2Vzc2lvbiB9O1xuXG5leHBvcnQgZW51bSBEZXJpdmVTdGF0ZSB7XG4gIFVuaW5pdGlhbGl6ZWQsXG4gIFJvdW5kMSxcbiAgUm91bmQyLFxuICBDb21wbGV0ZSxcbiAgSW52YWxpZFN0YXRlLFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIERlcml2ZVNlc3Npb25EYXRhIHtcbiAgZGVyaXZlU2Vzc2lvbkJ5dGVzOiBVaW50OEFycmF5O1xuICBkZXJpdmVTdGF0ZTogRGVyaXZlU3RhdGU7XG4gIGtleVNoYXJlQnVmZj86IEJ1ZmZlcjtcbiAgLy8gVGhpcyBwYXJ0eSdzIG93biBwcm90b2NvbCBtZXNzYWdlcywgcmUtZmVkIGludG8gdGhlIHNlc3Npb24gb24gdGhlIG5leHQgcm91bmRcbiAgLy8gYmVjYXVzZSB0aGUgd2FzbSBzZXNzaW9uIHZhbGlkYXRlcyB0aGUgc2VuZGVyIHNldCBhZ2FpbnN0IHtzZWxmLCBwYXJ0bmVyfS5cbiAgb3duTXNnMT86IFVpbnQ4QXJyYXk7XG4gIG93bk1zZzI/OiBVaW50OEFycmF5O1xufVxuXG4vKipcbiAqIFJvdW5kIGRyaXZlciBmb3IgdGhlIERLTFMyMyBoYXJkLWRlcml2YXRpb24gcHJvdG9jb2wgKFJpc3RyZXR0byBWUkYgYmFja2VkKSxcbiAqIHdoaWNoIGRlcml2ZXMgYSBjaGlsZCBzaWduaW5nIGtleXNoYXJlIGZyb20gYSByb290IGtleXNoYXJlIGFuZCBpdHMgVlJGIGtleXNoYXJlLlxuICpcbiAqIEVhY2ggc2Vzc2lvbiBpcyBhIDItcGFydHkgdGhyZXNob2xkIHByb3RvY29sIGJldHdlZW4gdGhpcyBwYXJ0eSBhbmQgb25lIHBhcnRuZXI6XG4gKiBldmVyeSByb3VuZCBhY2NlcHRzIGV4YWN0bHkgdHdvIGJyb2FkY2FzdCBtZXNzYWdlcyDigJQgdGhpcyBwYXJ0eSdzIG93biAoY3JlYXRlZCBieVxuICogYGluaXREZXJpdmUoKWAgYW5kIHJlLWZlZCBhdXRvbWF0aWNhbGx5KSBhbmQgdGhlIHBhcnRuZXIncy4gQSBjZXJlbW9ueSBydW5zIG9uZVxuICogYERlcml2ZWAgcGVyIFNESyBwYXJ0eSwgZWFjaCBwYWlyZWQgd2l0aCB0aGUgQml0R28gcGFydHk6XG4gKlxuICogLSBSb3VuZCAxIChgV2FpdE1zZzFgKTogY29uc3VtZSBge293biBtc2cxLCBwYXJ0bmVyIG1zZzF9YCwgZW1pdCBvd24gYnJvYWRjYXN0IG1zZzIuXG4gKiAtIFJvdW5kIDIgKGBXYWl0TXNnMmApOiBjb25zdW1lIGB7b3duIG1zZzIsIHBhcnRuZXIgbXNnMn1gLCBmaW5hbGl6ZSB0aGUgc2Vzc2lvblxuICogICBhbmQgZXh0cmFjdCB0aGUgZGVyaXZlZCBES0xTIGBLZXlzaGFyZWAuXG4gKlxuICogVGhlIHNlc3Npb24gaXMgc2VlZGVkIGZyb20gdGhlIGRlY3J5cHRlZCByb290IGJsb2I6IHRoZSBES0xTIHNpZ25pbmcga2V5c2hhcmUgYW5kXG4gKiB0aGUgUmlzdHJldHRvIFZSRiBrZXlzaGFyZSBwcm9kdWNlZCBieSByb290IGtleWdlbiwgcGx1cyB0aGUgY2hpbGQncyBoYXJkZW5lZFxuICogZGVyaXZhdGlvbiBwYXRoLlxuICpcbiAqIFBhcnR5IGluZGljZXMgZm9sbG93IHRoZSBNUEN2MiBjb252ZW50aW9uOiAwID0gdXNlciwgMSA9IGJhY2t1cCwgMiA9IGJpdGdvLlxuICovXG5leHBvcnQgY2xhc3MgRGVyaXZlIHtcbiAgcHJvdGVjdGVkIGRlcml2ZVNlc3Npb246IERrbHNIYXJkRGVyaXZlU2Vzc2lvbiB8IERrbHNWcmZXZWJIYXJkRGVyaXZlU2Vzc2lvbiB8IHVuZGVmaW5lZDtcbiAgcHJvdGVjdGVkIGRlcml2ZVNlc3Npb25CeXRlczogVWludDhBcnJheTtcbiAgcHJvdGVjdGVkIGtleVNoYXJlQnVmZjogQnVmZmVyIHwgdW5kZWZpbmVkO1xuICBwcm90ZWN0ZWQgbjogbnVtYmVyO1xuICBwcm90ZWN0ZWQgdDogbnVtYmVyO1xuICBwcm90ZWN0ZWQgcGFydHlJZHg6IG51bWJlcjtcbiAgcHJvdGVjdGVkIHJvb3RLZXlTaGFyZTogQnVmZmVyO1xuICBwcm90ZWN0ZWQgdnJmS2V5U2hhcmU6IEJ1ZmZlcjtcbiAgcHJvdGVjdGVkIHBhdGg6IFVpbnQ4QXJyYXk7XG4gIHByb3RlY3RlZCBzZWVkOiBCdWZmZXIgfCB1bmRlZmluZWQ7XG4gIHByb3RlY3RlZCBkZXJpdmVTdGF0ZTogRGVyaXZlU3RhdGUgPSBEZXJpdmVTdGF0ZS5VbmluaXRpYWxpemVkO1xuICBwcm90ZWN0ZWQgdnJmV2FzbTogVnJmV2FzbSB8IG51bGw7XG4gIC8vIFRoaXMgcGFydHkncyBvd24gcHJvdG9jb2wgbWVzc2FnZXMsIHJlLWZlZCBpbnRvIHRoZSBzZXNzaW9uIG9uIHRoZSBuZXh0IHJvdW5kOlxuICAvLyB0aGUgd2FzbSBoYXJkLWRlcml2ZSBzZXNzaW9uIHZhbGlkYXRlcyB0aGUgc2VuZGVyIHNldCBhZ2FpbnN0IHtzZWxmLCBwYXJ0bmVyfS5cbiAgcHJvdGVjdGVkIG93bk1zZzE6IFVpbnQ4QXJyYXkgfCB1bmRlZmluZWQ7XG4gIHByb3RlY3RlZCBvd25Nc2cyOiBVaW50OEFycmF5IHwgdW5kZWZpbmVkO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIG46IG51bWJlcixcbiAgICB0OiBudW1iZXIsXG4gICAgcGFydHlJZHg6IG51bWJlcixcbiAgICByb290S2V5U2hhcmU6IEJ1ZmZlcixcbiAgICB2cmZLZXlTaGFyZTogQnVmZmVyLFxuICAgIHBhdGg6IFVpbnQ4QXJyYXksXG4gICAgc2VlZD86IEJ1ZmZlcixcbiAgICB2cmZXYXNtPzogQnVuZGxlclZyZldhc21lclxuICApIHtcbiAgICB0aGlzLm4gPSBuO1xuICAgIHRoaXMudCA9IHQ7XG4gICAgdGhpcy5wYXJ0eUlkeCA9IHBhcnR5SWR4O1xuICAgIHRoaXMucm9vdEtleVNoYXJlID0gcm9vdEtleVNoYXJlO1xuICAgIHRoaXMudnJmS2V5U2hhcmUgPSB2cmZLZXlTaGFyZTtcbiAgICB0aGlzLnBhdGggPSBwYXRoO1xuICAgIHRoaXMuc2VlZCA9IHNlZWQ7XG4gICAgdGhpcy52cmZXYXNtID0gdnJmV2FzbSA/PyBudWxsO1xuICAgIHRoaXMuZGVyaXZlU2Vzc2lvbkJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoMCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGxvYWRWcmZXYXNtKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghdGhpcy52cmZXYXNtKSB7XG4gICAgICB0aGlzLnZyZldhc20gPSBhd2FpdCBpbXBvcnQoJ0BzaWxlbmNlbGFib3JhdG9yaWVzL2RrbHMtd2FzbS1sbC12cmYtbm9kZScpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0VnJmV2FzbSgpIHtcbiAgICBpZiAoIXRoaXMudnJmV2FzbSkge1xuICAgICAgdGhyb3cgRXJyb3IoJ1ZSRiB3YXNtIG5vdCBsb2FkZWQnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudnJmV2FzbTtcbiAgfVxuXG4gIHByaXZhdGUgX3Jlc3RvcmVTZXNzaW9uKCkge1xuICAgIGlmICghdGhpcy5kZXJpdmVTZXNzaW9uKSB7XG4gICAgICB0aGlzLmRlcml2ZVNlc3Npb24gPSB0aGlzLmdldFZyZldhc20oKS5IYXJkRGVyaXZlU2Vzc2lvbi5mcm9tQnl0ZXModGhpcy5kZXJpdmVTZXNzaW9uQnl0ZXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZS1kZXJpdmUgdGhlIHJvdW5kIHN0YXRlIGZyb20gdGhlIHdhc20gc2Vzc2lvbiBieXRlcyBpbnN0ZWFkIG9mIHRydXN0aW5nIGFcbiAgICogY2FsbGVyLXN1cHBsaWVkIGVudW0uIFRoZSB3YXNtIGVtYmVkcyB0aGUgcm91bmQgdGFnIChgV2FpdE1zZzFgL2BXYWl0TXNnMmAsXG4gICAqIHRoZW4gYSBgU2hhcmVgIHBheWxvYWQgb25jZSBmaW5hbGl6ZWQpIGZvciBleGFjdGx5IHRoaXMgcmVhc29uLlxuICAgKi9cbiAgcHJpdmF0ZSBfZGVzZXJpYWxpemVTdGF0ZSgpIHtcbiAgICBpZiAoIXRoaXMuZGVyaXZlU2Vzc2lvbikge1xuICAgICAgdGhyb3cgRXJyb3IoJ1Nlc3Npb24gbm90IGluaXRpYWxpemVkJyk7XG4gICAgfVxuICAgIGNvbnN0IGRlY29kZWQgPSBkZWNvZGUodGhpcy5kZXJpdmVTZXNzaW9uLnRvQnl0ZXMoKSk7XG4gICAgY29uc3Qgcm91bmQgPSBkZWNvZGVkPy5pbm5lcj8ucm91bmQ7XG4gICAgaWYgKHJvdW5kID09PSAnV2FpdE1zZzEnKSB7XG4gICAgICB0aGlzLmRlcml2ZVN0YXRlID0gRGVyaXZlU3RhdGUuUm91bmQxO1xuICAgIH0gZWxzZSBpZiAocm91bmQgPT09ICdXYWl0TXNnMicpIHtcbiAgICAgIHRoaXMuZGVyaXZlU3RhdGUgPSBEZXJpdmVTdGF0ZS5Sb3VuZDI7XG4gICAgfSBlbHNlIGlmIChkZWNvZGVkPy5pbm5lcj8uc3RhdGU/LlNoYXJlICE9PSB1bmRlZmluZWQgfHwgdGhpcy5kZXJpdmVTZXNzaW9uLmlzRmluaXNoZWQoKSkge1xuICAgICAgdGhpcy5kZXJpdmVTdGF0ZSA9IERlcml2ZVN0YXRlLkNvbXBsZXRlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRlcml2ZVN0YXRlID0gRGVyaXZlU3RhdGUuSW52YWxpZFN0YXRlO1xuICAgICAgdGhyb3cgRXJyb3IoYEludmFsaWQgU3RhdGU6ICR7SlNPTi5zdHJpbmdpZnkocm91bmQpfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgdGhpcyBwYXJ0eSdzIGZpcnN0IGhhcmQtZGVyaXZlIG1lc3NhZ2UgKGJyb2FkY2FzdCkuIFNlZWRzIHRoZSB3YXNtXG4gICAqIHNlc3Npb24gZnJvbSB0aGUgcm9vdCBrZXlzaGFyZSwgVlJGIGtleXNoYXJlIGFuZCBkZXJpdmF0aW9uIHBhdGguXG4gICAqL1xuICBhc3luYyBpbml0RGVyaXZlKCk6IFByb21pc2U8RGVzZXJpYWxpemVkQnJvYWRjYXN0TWVzc2FnZT4ge1xuICAgIGlmICghdGhpcy52cmZXYXNtKSB7XG4gICAgICBhd2FpdCB0aGlzLmxvYWRWcmZXYXNtKCk7XG4gICAgfVxuICAgIGlmICh0aGlzLnQgPiB0aGlzLm4gfHwgdGhpcy5wYXJ0eUlkeCA+PSB0aGlzLm4pIHtcbiAgICAgIHRocm93IEVycm9yKCdJbnZhbGlkIHBhcmFtZXRlcnMgZm9yIGhhcmQgZGVyaXZlJyk7XG4gICAgfVxuICAgIGlmICh0aGlzLmRlcml2ZVN0YXRlICE9PSBEZXJpdmVTdGF0ZS5VbmluaXRpYWxpemVkKSB7XG4gICAgICB0aHJvdyBFcnJvcignSGFyZCBkZXJpdmUgc2Vzc2lvbiBhbHJlYWR5IGluaXRpYWxpemVkJyk7XG4gICAgfVxuICAgIGlmICh0aGlzLnNlZWQgJiYgdGhpcy5zZWVkLmxlbmd0aCAhPT0gREVSSVZFX1NFRURfTEVOR1RIKSB7XG4gICAgICB0aHJvdyBFcnJvcihgU2VlZCBzaG91bGQgYmUgJHtERVJJVkVfU0VFRF9MRU5HVEh9IGJ5dGVzLCBnb3QgJHt0aGlzLnNlZWQubGVuZ3RofS5gKTtcbiAgICB9XG4gICAgaWYgKFxuICAgICAgdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgIC8qIGNoZWNrcyBmb3IgZWxlY3Ryb24gcHJvY2Vzc2VzICovXG4gICAgICAhd2luZG93LnByb2Nlc3MgJiZcbiAgICAgICF3aW5kb3cucHJvY2Vzcz8uWyd0eXBlJ11cbiAgICApIHtcbiAgICAgIC8qIFRoaXMgaXMgb25seSBuZWVkZWQgZm9yIGJyb3dzZXJzL3dlYiBiZWNhdXNlIGl0IHVzZXMgZmV0Y2ggdG8gcmVzb2x2ZSB0aGUgd2FzbSBhc3NldCBmb3IgdGhlIHdlYiAqL1xuICAgICAgY29uc3QgaW5pdFZyZiA9IGF3YWl0IGltcG9ydCgnQHNpbGVuY2VsYWJvcmF0b3JpZXMvZGtscy13YXNtLWxsLXZyZi13ZWInKTtcbiAgICAgIGF3YWl0IGluaXRWcmYuZGVmYXVsdCgpO1xuICAgIH1cbiAgICBjb25zdCB7IEhhcmREZXJpdmVTZXNzaW9uLCBLZXlzaGFyZSwgVnJmS2V5c2hhcmUgfSA9IHRoaXMuZ2V0VnJmV2FzbSgpO1xuICAgIGNvbnN0IHJvb3RLZXlTaGFyZSA9IEtleXNoYXJlLmZyb21CeXRlcyh0aGlzLnJvb3RLZXlTaGFyZSk7XG4gICAgaWYgKHJvb3RLZXlTaGFyZS5wYXJ0eUlkICE9PSB0aGlzLnBhcnR5SWR4KSB7XG4gICAgICB0aHJvdyBFcnJvcihgUGFydHkgaW5kZXg6ICR7dGhpcy5wYXJ0eUlkeH0gZG9lcyBub3QgbWF0Y2ggcm9vdCBrZXkgc2hhcmUgcGFydHlJZDogJHtyb290S2V5U2hhcmUucGFydHlJZH1gKTtcbiAgICB9XG4gICAgY29uc3QgdnJmS2V5U2hhcmUgPSBWcmZLZXlzaGFyZS5mcm9tQnl0ZXModGhpcy52cmZLZXlTaGFyZSk7XG4gICAgaWYgKHZyZktleVNoYXJlLnBhcnR5SWQgIT09IHRoaXMucGFydHlJZHgpIHtcbiAgICAgIHRocm93IEVycm9yKGBQYXJ0eSBpbmRleDogJHt0aGlzLnBhcnR5SWR4fSBkb2VzIG5vdCBtYXRjaCBWUkYga2V5IHNoYXJlIHBhcnR5SWQ6ICR7dnJmS2V5U2hhcmUucGFydHlJZH1gKTtcbiAgICB9XG4gICAgdGhpcy5kZXJpdmVTZXNzaW9uID0gdGhpcy5zZWVkXG4gICAgICA/IG5ldyBIYXJkRGVyaXZlU2Vzc2lvbihyb290S2V5U2hhcmUsIHZyZktleVNoYXJlLCB0aGlzLnBhdGgsIG5ldyBVaW50OEFycmF5KHRoaXMuc2VlZCkpXG4gICAgICA6IG5ldyBIYXJkRGVyaXZlU2Vzc2lvbihyb290S2V5U2hhcmUsIHZyZktleVNoYXJlLCB0aGlzLnBhdGgpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gdGhpcy5kZXJpdmVTZXNzaW9uLmNyZWF0ZUZpcnN0TWVzc2FnZSgpO1xuICAgICAgLy8gQ29weSB0aGUgcGF5bG9hZCBvdXQgYmVmb3JlIGZyZWVpbmcgdGhlIHdhc20gbWVzc2FnZSBvYmplY3QuXG4gICAgICBjb25zdCBwYXlsb2FkID0gbmV3IFVpbnQ4QXJyYXkobWVzc2FnZS5wYXlsb2FkKTtcbiAgICAgIGNvbnN0IGZyb20gPSBtZXNzYWdlLmZyb21faWQ7XG4gICAgICBtZXNzYWdlLmZyZWUoKTtcbiAgICAgIHRoaXMub3duTXNnMSA9IHBheWxvYWQ7XG4gICAgICB0aGlzLmRlcml2ZVNlc3Npb25CeXRlcyA9IHRoaXMuZGVyaXZlU2Vzc2lvbi50b0J5dGVzKCk7XG4gICAgICB0aGlzLl9kZXNlcmlhbGl6ZVN0YXRlKCk7XG4gICAgICByZXR1cm4geyBwYXlsb2FkLCBmcm9tIH07XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhyb3cgRXJyb3IoYEVycm9yIHdoaWxlIGNyZWF0aW5nIHRoZSBmaXJzdCBoYXJkLWRlcml2ZSBtZXNzYWdlIGZyb20gcGFydHkgJHt0aGlzLnBhcnR5SWR4fTogJHtlfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9jZXNzIHRoZSBtZXNzYWdlcyB0aGlzIHBhcnR5IGhvbGRzIGZvciB0aGUgY3VycmVudCByb3VuZCBhbmQgcmV0dXJuIHRoaXNcbiAgICogcGFydHkncyBtZXNzYWdlcyBmb3IgdGhlIG5leHQgcm91bmQuIENhbGxlcnMgcGFzcyB0aGUgcGFydG5lcidzIGJyb2FkY2FzdFxuICAgKiBtZXNzYWdlIG9ubHk7IHRoaXMgcGFydHkncyBvd24gbWVzc2FnZSBpcyByZS1mZWQgYXV0b21hdGljYWxseSBiZWNhdXNlIHRoZVxuICAgKiB3YXNtIHNlc3Npb24gdmFsaWRhdGVzIHRoZSBzZW5kZXIgc2V0IGFzIGB7c2VsZiwgcGFydG5lcn1gLlxuICAgKlxuICAgKiAtIFJvdW5kIDEgKFdhaXRNc2cxKTogY29uc3VtZXMgYHtvd24gbXNnMSwgcGFydG5lciBtc2cxfWAgYW5kIGVtaXRzIHRoaXNcbiAgICogICBwYXJ0eSdzIGJyb2FkY2FzdCBtc2cyLlxuICAgKiAtIFJvdW5kIDIgKFdhaXRNc2cyKTogY29uc3VtZXMgYHtvd24gbXNnMiwgcGFydG5lciBtc2cyfWAgYW5kIGZpbmFsaXplcyB0aGVcbiAgICogICBzZXNzaW9uLCByZXR1cm5pbmcgbm8gbWVzc2FnZXMuXG4gICAqL1xuICBoYW5kbGVJbmNvbWluZ01lc3NhZ2VzKG1lc3NhZ2VzRm9ySXRoUm91bmQ6IERlc2VyaWFsaXplZE1lc3NhZ2VzKTogRGVzZXJpYWxpemVkTWVzc2FnZXMge1xuICAgIHRoaXMuX3Jlc3RvcmVTZXNzaW9uKCk7XG4gICAgaWYgKCF0aGlzLmRlcml2ZVNlc3Npb24pIHtcbiAgICAgIHRocm93IEVycm9yKCdTZXNzaW9uIG5vdCBpbml0aWFsaXplZCcpO1xuICAgIH1cbiAgICBjb25zdCB7IE1lc3NhZ2UgfSA9IHRoaXMuZ2V0VnJmV2FzbSgpO1xuICAgIGxldCBuZXh0Um91bmRNZXNzYWdlczogVnJmV2FzbU1lc3NhZ2VbXSA9IFtdO1xuICAgIGNvbnN0IG5leHRSb3VuZERlc2VyaWFsaXplZE1lc3NhZ2VzOiBEZXNlcmlhbGl6ZWRNZXNzYWdlcyA9IHsgYnJvYWRjYXN0TWVzc2FnZXM6IFtdLCBwMnBNZXNzYWdlczogW10gfTtcbiAgICB0cnkge1xuICAgICAgc3dpdGNoICh0aGlzLmRlcml2ZVN0YXRlKSB7XG4gICAgICAgIGNhc2UgRGVyaXZlU3RhdGUuUm91bmQxOiB7XG4gICAgICAgICAgY29uc3QgcGFydG5lck1lc3NhZ2VzID0gbWVzc2FnZXNGb3JJdGhSb3VuZC5icm9hZGNhc3RNZXNzYWdlcy5maWx0ZXIoKG0pID0+IG0uZnJvbSAhPT0gdGhpcy5wYXJ0eUlkeCk7XG4gICAgICAgICAgaWYgKHBhcnRuZXJNZXNzYWdlcy5sZW5ndGggIT09IDEgfHwgIXRoaXMub3duTXNnMSkge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ0V4cGVjdGVkIGV4YWN0bHkgb25lIGJyb2FkY2FzdCBtZXNzYWdlIGZyb20gdGhlIGRlcml2ZSBwYXJ0bmVyIGluIHJvdW5kIDEnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbmV4dFJvdW5kTWVzc2FnZXMgPSB0aGlzLmRlcml2ZVNlc3Npb24uaGFuZGxlTWVzc2FnZXMoW1xuICAgICAgICAgICAgbmV3IE1lc3NhZ2UodGhpcy5vd25Nc2cxLCB0aGlzLnBhcnR5SWR4KSxcbiAgICAgICAgICAgIG5ldyBNZXNzYWdlKHBhcnRuZXJNZXNzYWdlc1swXS5wYXlsb2FkLCBwYXJ0bmVyTWVzc2FnZXNbMF0uZnJvbSksXG4gICAgICAgICAgXSk7XG4gICAgICAgICAgdGhpcy5fZGVzZXJpYWxpemVTdGF0ZSgpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgRGVyaXZlU3RhdGUuUm91bmQyOiB7XG4gICAgICAgICAgY29uc3QgcGFydG5lck1lc3NhZ2VzID0gbWVzc2FnZXNGb3JJdGhSb3VuZC5icm9hZGNhc3RNZXNzYWdlcy5maWx0ZXIoKG0pID0+IG0uZnJvbSAhPT0gdGhpcy5wYXJ0eUlkeCk7XG4gICAgICAgICAgaWYgKHBhcnRuZXJNZXNzYWdlcy5sZW5ndGggIT09IDEgfHwgIXRoaXMub3duTXNnMikge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ0V4cGVjdGVkIGV4YWN0bHkgb25lIGJyb2FkY2FzdCBtZXNzYWdlIGZyb20gdGhlIGRlcml2ZSBwYXJ0bmVyIGluIHJvdW5kIDInKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbmV4dFJvdW5kTWVzc2FnZXMgPSB0aGlzLmRlcml2ZVNlc3Npb24uaGFuZGxlTWVzc2FnZXMoW1xuICAgICAgICAgICAgbmV3IE1lc3NhZ2UodGhpcy5vd25Nc2cyLCB0aGlzLnBhcnR5SWR4KSxcbiAgICAgICAgICAgIG5ldyBNZXNzYWdlKHBhcnRuZXJNZXNzYWdlc1swXS5wYXlsb2FkLCBwYXJ0bmVyTWVzc2FnZXNbMF0uZnJvbSksXG4gICAgICAgICAgXSk7XG4gICAgICAgICAgLy8gaGFuZGxlTWVzc2FnZXMoKSBjb25zdW1lcyB0aGUgc2Vzc2lvbjsga2V5c2hhcmUoKSBleHRyYWN0cyB0aGUgZGVyaXZlZCBzaGFyZS5cbiAgICAgICAgICBjb25zdCBrZXlTaGFyZSA9IHRoaXMuZGVyaXZlU2Vzc2lvbi5rZXlzaGFyZSgpO1xuICAgICAgICAgIHRoaXMua2V5U2hhcmVCdWZmID0gQnVmZmVyLmZyb20oa2V5U2hhcmUudG9CeXRlcygpKTtcbiAgICAgICAgICBrZXlTaGFyZS5mcmVlKCk7XG4gICAgICAgICAgdGhpcy5kZXJpdmVTdGF0ZSA9IERlcml2ZVN0YXRlLkNvbXBsZXRlO1xuICAgICAgICAgIHJldHVybiBuZXh0Um91bmREZXNlcmlhbGl6ZWRNZXNzYWdlcztcbiAgICAgICAgfVxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IEVycm9yKGBJbnZhbGlkIGhhcmQtZGVyaXZlIHN0YXRlOiAke3RoaXMuZGVyaXZlU3RhdGV9YCk7XG4gICAgICB9XG5cbiAgICAgIG5leHRSb3VuZERlc2VyaWFsaXplZE1lc3NhZ2VzLmJyb2FkY2FzdE1lc3NhZ2VzID0gbmV4dFJvdW5kTWVzc2FnZXNcbiAgICAgICAgLmZpbHRlcigobSkgPT4gbS50b19pZCA9PT0gdW5kZWZpbmVkKVxuICAgICAgICAubWFwKChtKSA9PiAoeyBwYXlsb2FkOiBuZXcgVWludDhBcnJheShtLnBheWxvYWQpLCBmcm9tOiBtLmZyb21faWQgfSkpO1xuICAgICAgbmV4dFJvdW5kRGVzZXJpYWxpemVkTWVzc2FnZXMucDJwTWVzc2FnZXMgPSBuZXh0Um91bmRNZXNzYWdlc1xuICAgICAgICAuZmlsdGVyKChtKTogbSBpcyBWcmZXYXNtTWVzc2FnZSAmIHsgdG9faWQ6IG51bWJlciB9ID0+IG0udG9faWQgIT09IHVuZGVmaW5lZClcbiAgICAgICAgLm1hcCgobSkgPT4gKHsgcGF5bG9hZDogbmV3IFVpbnQ4QXJyYXkobS5wYXlsb2FkKSwgZnJvbTogbS5mcm9tX2lkLCB0bzogbS50b19pZCB9KSk7XG4gICAgICAvLyBUaGUgcm91bmQtMSBvdXRwdXQgaXMgdGhpcyBwYXJ0eSdzIG1zZzIsIHJlLWZlZCBpbnRvIHRoZSBzZXNzaW9uIG9uIHJvdW5kIDIuXG4gICAgICBjb25zdCBvd25Nc2cyID0gbmV4dFJvdW5kRGVzZXJpYWxpemVkTWVzc2FnZXMuYnJvYWRjYXN0TWVzc2FnZXMuZmluZCgobSkgPT4gbS5mcm9tID09PSB0aGlzLnBhcnR5SWR4KTtcbiAgICAgIGlmIChvd25Nc2cyKSB7XG4gICAgICAgIHRoaXMub3duTXNnMiA9IG93bk1zZzIucGF5bG9hZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXh0Um91bmREZXNlcmlhbGl6ZWRNZXNzYWdlcztcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aHJvdyBFcnJvcihcbiAgICAgICAgYEVycm9yIHdoaWxlIGNyZWF0aW5nIGhhcmQtZGVyaXZlIG1lc3NhZ2VzIGZyb20gcGFydHkgJHt0aGlzLnBhcnR5SWR4fSwgc3RhdGUgJHt0aGlzLmRlcml2ZVN0YXRlfTogJHtlfWBcbiAgICAgICk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIG5leHRSb3VuZE1lc3NhZ2VzLmZvckVhY2goKG0pID0+IG0uZnJlZSgpKTtcbiAgICAgIC8vIGtleXNoYXJlKCkgY29uc3VtZWQgKGFuZCBkZWFsbG9jYXRlZCkgdGhlIHNlc3Npb24gb24gcm91bmQgMjsgb25seSBwZXJzaXN0XG4gICAgICAvLyBtaWQtcHJvdG9jb2wgc2Vzc2lvbiBieXRlcyB3aGlsZSB0aGUgc2Vzc2lvbiBvYmplY3Qgc3RpbGwgZXhpc3RzLlxuICAgICAgaWYgKHRoaXMuZGVyaXZlU3RhdGUgIT09IERlcml2ZVN0YXRlLkNvbXBsZXRlICYmIHRoaXMuZGVyaXZlU2Vzc2lvbikge1xuICAgICAgICB0aGlzLmRlcml2ZVNlc3Npb25CeXRlcyA9IHRoaXMuZGVyaXZlU2Vzc2lvbi50b0J5dGVzKCk7XG4gICAgICB9XG4gICAgICB0aGlzLmRlcml2ZVNlc3Npb24gPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgZGVyaXZlZCBES0xTIGtleXNoYXJlIGJ5dGVzIChDQk9SIGBLZXlzaGFyZWApIG9uY2UgdGhlIGRlcml2ZSBpc1xuICAgKiBjb21wbGV0ZS4gVGhpcyBidWZmZXIgaXMgcHJpdmF0ZSBrZXkgbWF0ZXJpYWwuXG4gICAqL1xuICBnZXRLZXlTaGFyZSgpOiBCdWZmZXIge1xuICAgIGlmICghdGhpcy5rZXlTaGFyZUJ1ZmYpIHtcbiAgICAgIHRocm93IEVycm9yKCdDYW4gbm90IGdldCBrZXkgc2hhcmUsIGhhcmQgZGVyaXZlIGlzIG5vdCBjb21wbGV0ZSB5ZXQuJyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmtleVNoYXJlQnVmZjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgQ0JPUi1lbmNvZGVkIFJlZHVjZWRLZXlTaGFyZSBidWZmZXIgY29udGFpbmluZyB0aGUgZGVyaXZlZCBwYXJ0eSdzXG4gICAqIHByaXZhdGUgc2NhbGFyIChzX2kpIGluIHRoZSBgcHJ2YCBmaWVsZC4gVGhpcyBidWZmZXIgaXMgcHJpdmF0ZSBrZXkgbWF0ZXJpYWw7XG4gICAqIHRoZSBjYWxsZXIgZW5jcnlwdHMgaXQgYXMgYHJlZHVjZWRFbmNyeXB0ZWRQcnZgLCBtYXRjaGluZyBgRGtnLmdldFJlZHVjZWRLZXlTaGFyZWAuXG4gICAqL1xuICBnZXRSZWR1Y2VkS2V5U2hhcmUoKTogQnVmZmVyIHtcbiAgICBpZiAoIXRoaXMua2V5U2hhcmVCdWZmKSB7XG4gICAgICB0aHJvdyBFcnJvcignQ2FuIG5vdCBnZXQga2V5IHNoYXJlLCBoYXJkIGRlcml2ZSBpcyBub3QgY29tcGxldGUgeWV0LicpO1xuICAgIH1cbiAgICBjb25zdCBkZWNvZGVkS2V5c2hhcmUgPSBkZWNvZGUodGhpcy5rZXlTaGFyZUJ1ZmYpO1xuICAgIGNvbnN0IHJlZHVjZWRLZXlTaGFyZTogUmVkdWNlZEtleVNoYXJlID0ge1xuICAgICAgYmlnU0xpc3Q6IGRlY29kZWRLZXlzaGFyZS5iaWdfc19saXN0LFxuICAgICAgeExpc3Q6IGRlY29kZWRLZXlzaGFyZS54X2lfbGlzdCxcbiAgICAgIHJvb3RDaGFpbkNvZGU6IGRlY29kZWRLZXlzaGFyZS5yb290X2NoYWluX2NvZGUsXG4gICAgICBwcnY6IGRlY29kZWRLZXlzaGFyZS5zX2ksXG4gICAgICBwdWI6IGRlY29kZWRLZXlzaGFyZS5wdWJsaWNfa2V5LFxuICAgIH07XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGVuY29kZShyZWR1Y2VkS2V5U2hhcmUpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGN1cnJlbnQgc2Vzc2lvbiBkYXRhIHRoYXQgY2FuIGJlIHVzZWQgdG8gcmVzdG9yZSB0aGUgc2Vzc2lvbiBsYXRlci5cbiAgICpcbiAgICogVGhlIHJldHVybmVkIHNlc3Npb24gYnl0ZXMgYXJlIHNlY3JldCBrZXkgbWF0ZXJpYWwg4oCUIHRoZXkgY2FycnkgdGhpcyBwYXJ0eSdzXG4gICAqIHJvb3Qga2V5c2hhcmVzLiBUaGV5IG11c3QgbmV2ZXIgYmUgbG9nZ2VkIG9yIHBlcnNpc3RlZCBpbiB0aGUgY2xlYXI7IHRoZVxuICAgKiBjYWxsZXIgZW5jcnlwdHMgdGhlbSBleGFjdGx5IGxpa2UgdGhlIGtleSBzaGFyZSBpdHNlbGYuXG4gICAqL1xuICBnZXRTZXNzaW9uRGF0YSgpOiBEZXJpdmVTZXNzaW9uRGF0YSB7XG4gICAgY29uc3Qgc2Vzc2lvbkRhdGE6IERlcml2ZVNlc3Npb25EYXRhID0ge1xuICAgICAgZGVyaXZlU2Vzc2lvbkJ5dGVzOiB0aGlzLmRlcml2ZVNlc3Npb25CeXRlcyxcbiAgICAgIGRlcml2ZVN0YXRlOiB0aGlzLmRlcml2ZVN0YXRlLFxuICAgIH07XG4gICAgaWYgKHRoaXMua2V5U2hhcmVCdWZmKSB7XG4gICAgICBzZXNzaW9uRGF0YS5rZXlTaGFyZUJ1ZmYgPSB0aGlzLmtleVNoYXJlQnVmZjtcbiAgICB9XG4gICAgaWYgKHRoaXMub3duTXNnMSkge1xuICAgICAgc2Vzc2lvbkRhdGEub3duTXNnMSA9IHRoaXMub3duTXNnMTtcbiAgICB9XG4gICAgaWYgKHRoaXMub3duTXNnMikge1xuICAgICAgc2Vzc2lvbkRhdGEub3duTXNnMiA9IHRoaXMub3duTXNnMjtcbiAgICB9XG4gICAgcmV0dXJuIHNlc3Npb25EYXRhO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc3RvcmUgYSBzZXNzaW9uIHNuYXBzaG90IGNhcHR1cmVkIGFmdGVyIGluaXREZXJpdmUoKSBvciByb3VuZCAxIHByb2Nlc3NpbmcuXG4gICAqIERvIG5vdCBjYWxsIHRoaXMgYmVmb3JlIGluaXREZXJpdmUoKSBoYXMgY3JlYXRlZCBzZXNzaW9uIGJ5dGVzLlxuICAgKiBUaGUgcm91bmQgc3RhdGUgaXMgcmUtZGVyaXZlZCBmcm9tIHRoZSB3YXNtIHNlc3Npb24gYnl0ZXMsIG5vdCB0aGUgY2FsbGVyIGVudW0uXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgcmVzdG9yZVNlc3Npb24oXG4gICAgbjogbnVtYmVyLFxuICAgIHQ6IG51bWJlcixcbiAgICBwYXJ0eUlkeDogbnVtYmVyLFxuICAgIHJvb3RLZXlTaGFyZTogQnVmZmVyLFxuICAgIHZyZktleVNoYXJlOiBCdWZmZXIsXG4gICAgcGF0aDogVWludDhBcnJheSxcbiAgICBzZXNzaW9uRGF0YTogRGVyaXZlU2Vzc2lvbkRhdGEsXG4gICAgc2VlZD86IEJ1ZmZlcixcbiAgICB2cmZXYXNtPzogQnVuZGxlclZyZldhc21lclxuICApOiBQcm9taXNlPERlcml2ZT4ge1xuICAgIGNvbnN0IGRlcml2ZSA9IG5ldyBEZXJpdmUobiwgdCwgcGFydHlJZHgsIHJvb3RLZXlTaGFyZSwgdnJmS2V5U2hhcmUsIHBhdGgsIHNlZWQsIHZyZldhc20pO1xuICAgIGlmICghZGVyaXZlLnZyZldhc20pIHtcbiAgICAgIGF3YWl0IGRlcml2ZS5sb2FkVnJmV2FzbSgpO1xuICAgIH1cbiAgICBkZXJpdmUuZGVyaXZlU2Vzc2lvbkJ5dGVzID0gc2Vzc2lvbkRhdGEuZGVyaXZlU2Vzc2lvbkJ5dGVzO1xuICAgIGlmIChzZXNzaW9uRGF0YS5rZXlTaGFyZUJ1ZmYpIHtcbiAgICAgIGRlcml2ZS5rZXlTaGFyZUJ1ZmYgPSBzZXNzaW9uRGF0YS5rZXlTaGFyZUJ1ZmY7XG4gICAgfVxuICAgIGlmIChzZXNzaW9uRGF0YS5vd25Nc2cxKSB7XG4gICAgICBkZXJpdmUub3duTXNnMSA9IHNlc3Npb25EYXRhLm93bk1zZzE7XG4gICAgfVxuICAgIGlmIChzZXNzaW9uRGF0YS5vd25Nc2cyKSB7XG4gICAgICBkZXJpdmUub3duTXNnMiA9IHNlc3Npb25EYXRhLm93bk1zZzI7XG4gICAgfVxuICAgIGRlcml2ZS5fcmVzdG9yZVNlc3Npb24oKTtcbiAgICBkZXJpdmUuX2Rlc2VyaWFsaXplU3RhdGUoKTtcbiAgICByZXR1cm4gZGVyaXZlO1xuICB9XG59XG4iXX0=
|