@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.
Files changed (71) hide show
  1. package/dist/src/tss/dkls-vrf/dkg.d.ts +91 -0
  2. package/dist/src/tss/dkls-vrf/dkg.d.ts.map +1 -0
  3. package/dist/src/tss/dkls-vrf/dkg.js +278 -0
  4. package/dist/src/tss/dkls-vrf/index.d.ts +4 -0
  5. package/dist/src/tss/dkls-vrf/index.d.ts.map +1 -0
  6. package/dist/src/tss/dkls-vrf/index.js +40 -0
  7. package/dist/src/tss/dkls-vrf/types.d.ts +28 -0
  8. package/dist/src/tss/dkls-vrf/types.d.ts.map +1 -0
  9. package/dist/src/tss/dkls-vrf/types.js +23 -0
  10. package/dist/src/tss/dkls-vrf/util.d.ts +29 -0
  11. package/dist/src/tss/dkls-vrf/util.d.ts.map +1 -0
  12. package/dist/src/tss/dkls-vrf/util.js +113 -0
  13. package/dist/src/tss/ecdsa-dkls/derive.d.ts +111 -0
  14. package/dist/src/tss/ecdsa-dkls/derive.d.ts.map +1 -0
  15. package/dist/src/tss/ecdsa-dkls/derive.js +329 -0
  16. package/dist/src/tss/ecdsa-dkls/dkg.d.ts +3 -1
  17. package/dist/src/tss/ecdsa-dkls/dkg.d.ts.map +1 -1
  18. package/dist/src/tss/ecdsa-dkls/dkg.js +1 -1
  19. package/dist/src/tss/ecdsa-dkls/index.d.ts +1 -0
  20. package/dist/src/tss/ecdsa-dkls/index.d.ts.map +1 -1
  21. package/dist/src/tss/ecdsa-dkls/index.js +3 -2
  22. package/dist/src/tss/eddsa-mps/derive.d.ts +34 -0
  23. package/dist/src/tss/eddsa-mps/derive.d.ts.map +1 -0
  24. package/dist/src/tss/eddsa-mps/derive.js +198 -0
  25. package/dist/src/tss/eddsa-mps/dkg.d.ts +7 -2
  26. package/dist/src/tss/eddsa-mps/dkg.d.ts.map +1 -1
  27. package/dist/src/tss/eddsa-mps/dkg.js +13 -3
  28. package/dist/src/tss/eddsa-mps/index.d.ts +2 -0
  29. package/dist/src/tss/eddsa-mps/index.d.ts.map +1 -1
  30. package/dist/src/tss/eddsa-mps/index.js +3 -2
  31. package/dist/src/tss/eddsa-mps/types.d.ts +13 -0
  32. package/dist/src/tss/eddsa-mps/types.d.ts.map +1 -1
  33. package/dist/src/tss/eddsa-mps/types.js +1 -1
  34. package/dist/src/tss/eddsa-mps/util.d.ts +2 -2
  35. package/dist/src/tss/eddsa-mps/util.d.ts.map +1 -1
  36. package/dist/src/tss/eddsa-mps/util.js +5 -5
  37. package/dist/src/tss/eddsa-mps-vrf/dkg.d.ts +65 -0
  38. package/dist/src/tss/eddsa-mps-vrf/dkg.d.ts.map +1 -0
  39. package/dist/src/tss/eddsa-mps-vrf/dkg.js +246 -0
  40. package/dist/src/tss/eddsa-mps-vrf/index.d.ts +4 -0
  41. package/dist/src/tss/eddsa-mps-vrf/index.d.ts.map +1 -0
  42. package/dist/src/tss/eddsa-mps-vrf/index.js +40 -0
  43. package/dist/src/tss/eddsa-mps-vrf/types.d.ts +31 -0
  44. package/dist/src/tss/eddsa-mps-vrf/types.d.ts.map +1 -0
  45. package/dist/src/tss/eddsa-mps-vrf/types.js +97 -0
  46. package/dist/src/tss/eddsa-mps-vrf/util.d.ts +9 -0
  47. package/dist/src/tss/eddsa-mps-vrf/util.d.ts.map +1 -0
  48. package/dist/src/tss/eddsa-mps-vrf/util.js +36 -0
  49. package/dist/src/tss/index.d.ts +3 -0
  50. package/dist/src/tss/index.d.ts.map +1 -1
  51. package/dist/src/tss/index.js +4 -1
  52. package/dist/src/tss/redpallas-mps/commsLayer.d.ts +34 -0
  53. package/dist/src/tss/redpallas-mps/commsLayer.d.ts.map +1 -0
  54. package/dist/src/tss/redpallas-mps/commsLayer.js +100 -0
  55. package/dist/src/tss/redpallas-mps/dkg.d.ts +103 -0
  56. package/dist/src/tss/redpallas-mps/dkg.d.ts.map +1 -0
  57. package/dist/src/tss/redpallas-mps/dkg.js +285 -0
  58. package/dist/src/tss/redpallas-mps/dsg.d.ts +108 -0
  59. package/dist/src/tss/redpallas-mps/dsg.d.ts.map +1 -0
  60. package/dist/src/tss/redpallas-mps/dsg.js +355 -0
  61. package/dist/src/tss/redpallas-mps/index.d.ts +7 -0
  62. package/dist/src/tss/redpallas-mps/index.d.ts.map +1 -0
  63. package/dist/src/tss/redpallas-mps/index.js +42 -0
  64. package/dist/src/tss/redpallas-mps/types.d.ts +85 -0
  65. package/dist/src/tss/redpallas-mps/types.d.ts.map +1 -0
  66. package/dist/src/tss/redpallas-mps/types.js +112 -0
  67. package/dist/src/tss/redpallas-mps/util.d.ts +43 -0
  68. package/dist/src/tss/redpallas-mps/util.d.ts.map +1 -0
  69. package/dist/src/tss/redpallas-mps/util.js +147 -0
  70. package/dist/tsconfig.tsbuildinfo +1 -1
  71. 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy90c3MvZGtscy12cmYvdXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQVNBLDBEQThDQztBQWNELG9FQTREQztBQWhJRCxpREFBOEM7QUFDOUMsK0JBQStCO0FBRS9COzs7O0dBSUc7QUFDSSxLQUFLLFVBQVUsdUJBQXVCLENBQzNDLFFBQWlCLEVBQ2pCLFVBQW1CLEVBQ25CLFNBQWtCO0lBRWxCLE1BQU0sSUFBSSxHQUFHLElBQUksWUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzNDLE1BQU0sTUFBTSxHQUFHLElBQUksWUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQy9DLE1BQU0sS0FBSyxHQUFHLElBQUksWUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQzdDLGtCQUFrQjtJQUNsQixNQUFNLGtCQUFrQixHQUFHLE1BQU0sSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2hELE1BQU0sb0JBQW9CLEdBQUcsTUFBTSxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDcEQsTUFBTSxtQkFBbUIsR0FBRyxNQUFNLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUNsRCxNQUFNLG1CQUFtQixHQUFHLE1BQU0sS0FBSyxDQUFDLHNCQUFzQixDQUFDO1FBQzdELFdBQVcsRUFBRSxFQUFFO1FBQ2YsaUJBQWlCLEVBQUUsQ0FBQyxHQUFHLGtCQUFrQixDQUFDLGlCQUFpQixFQUFFLEdBQUcsb0JBQW9CLENBQUMsaUJBQWlCLENBQUM7S0FDeEcsQ0FBQyxDQUFDO0lBQ0gsYUFBYTtJQUViLGtCQUFrQjtJQUNsQixNQUFNLGtCQUFrQixHQUFHLE1BQU0sSUFBSSxDQUFDLHNCQUFzQixDQUFDO1FBQzNELFdBQVcsRUFBRSxFQUFFO1FBQ2YsaUJBQWlCLEVBQUUsQ0FBQyxHQUFHLG1CQUFtQixDQUFDLGlCQUFpQixFQUFFLEdBQUcsb0JBQW9CLENBQUMsaUJBQWlCLENBQUM7S0FDekcsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxvQkFBb0IsR0FBRyxNQUFNLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQztRQUMvRCxXQUFXLEVBQUUsRUFBRTtRQUNmLGlCQUFpQixFQUFFLENBQUMsR0FBRyxrQkFBa0IsQ0FBQyxpQkFBaUIsRUFBRSxHQUFHLG1CQUFtQixDQUFDLGlCQUFpQixDQUFDO0tBQ3ZHLENBQUMsQ0FBQztJQUNILE1BQU0sS0FBSyxDQUFDLHNCQUFzQixDQUFDO1FBQ2pDLFdBQVcsRUFBRSxDQUFDLG1CQUFtQixFQUFFLGtCQUFrQixFQUFFLG9CQUFvQixDQUFDO2FBQ3pFLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQzthQUM3QixNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzVCLGlCQUFpQixFQUFFLEVBQUU7S0FDdEIsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxJQUFJLENBQUMsc0JBQXNCLENBQUM7UUFDaEMsV0FBVyxFQUFFLENBQUMsbUJBQW1CLEVBQUUsa0JBQWtCLEVBQUUsb0JBQW9CLENBQUM7YUFDekUsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDO2FBQzdCLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDNUIsaUJBQWlCLEVBQUUsRUFBRTtLQUN0QixDQUFDLENBQUM7SUFDSCxNQUFNLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQztRQUNsQyxXQUFXLEVBQUUsQ0FBQyxtQkFBbUIsRUFBRSxrQkFBa0IsRUFBRSxvQkFBb0IsQ0FBQzthQUN6RSxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUM7YUFDN0IsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUM1QixpQkFBaUIsRUFBRSxFQUFFO0tBQ3RCLENBQUMsQ0FBQztJQUNILE9BQU8sQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQy9CLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7R0FXRztBQUNJLEtBQUssVUFBVSw0QkFBNEIsQ0FDaEQsUUFBbUMsRUFDbkMsVUFBcUMsRUFDckMsU0FBb0MsRUFDcEMsT0FBZSxFQUNmLFNBQWlCLEVBQ2pCLFFBQWdCLEVBQ2hCLElBQWdCLEVBQ2hCLFFBQWlCLEVBQ2pCLFVBQW1CO0lBRW5CLE1BQU0sSUFBSSxHQUFHLElBQUksZUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxXQUFXLEVBQUUsRUFBRSxPQUFPLENBQUMsV0FBVyxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ2hHLE1BQU0sTUFBTSxHQUFHLElBQUksZUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxXQUFXLEVBQUUsRUFBRSxTQUFTLENBQUMsV0FBVyxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ3hHLE1BQU0sYUFBYSxHQUFHLElBQUksZUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxXQUFXLEVBQUUsRUFBRSxRQUFRLENBQUMsV0FBVyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDakcsTUFBTSxlQUFlLEdBQUcsSUFBSSxlQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsU0FBUyxDQUFDLFdBQVcsRUFBRSxFQUFFLFFBQVEsQ0FBQyxXQUFXLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUVuRyxrQkFBa0I7SUFDbEIsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDekMsTUFBTSxVQUFVLEdBQUcsTUFBTSxNQUFNLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDN0MsTUFBTSxpQkFBaUIsR0FBRyxNQUFNLGFBQWEsQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUMzRCxNQUFNLG1CQUFtQixHQUFHLE1BQU0sZUFBZSxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBRS9ELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQztRQUMzQyxXQUFXLEVBQUUsRUFBRTtRQUNmLGlCQUFpQixFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsaUJBQWlCLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsQ0FBQztLQUMxRixDQUFDLENBQUM7SUFDSCxNQUFNLGlCQUFpQixHQUFHLGFBQWEsQ0FBQyxzQkFBc0IsQ0FBQztRQUM3RCxXQUFXLEVBQUUsRUFBRTtRQUNmLGlCQUFpQixFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO0tBQ3hFLENBQUMsQ0FBQztJQUNILE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQztRQUMvQyxXQUFXLEVBQUUsRUFBRTtRQUNmLGlCQUFpQixFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsbUJBQW1CLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxtQkFBbUIsQ0FBQyxJQUFJLEVBQUUsQ0FBQztLQUM5RixDQUFDLENBQUM7SUFDSCxNQUFNLG1CQUFtQixHQUFHLGVBQWUsQ0FBQyxzQkFBc0IsQ0FBQztRQUNqRSxXQUFXLEVBQUUsRUFBRTtRQUNmLGlCQUFpQixFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsVUFBVSxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDO0tBQzVFLENBQUMsQ0FBQztJQUNILGFBQWE7SUFFYixrQkFBa0I7SUFDbEIsSUFBSSxDQUFDLHNCQUFzQixDQUFDO1FBQzFCLFdBQVcsRUFBRSxFQUFFO1FBQ2YsaUJBQWlCLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxpQkFBaUIsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDO0tBQzFGLENBQUMsQ0FBQztJQUNILGFBQWEsQ0FBQyxzQkFBc0IsQ0FBQztRQUNuQyxXQUFXLEVBQUUsRUFBRTtRQUNmLGlCQUFpQixFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUM7S0FDakYsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxDQUFDLHNCQUFzQixDQUFDO1FBQzVCLFdBQVcsRUFBRSxFQUFFO1FBQ2YsaUJBQWlCLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxtQkFBbUIsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDO0tBQzVGLENBQUMsQ0FBQztJQUNILGVBQWUsQ0FBQyxzQkFBc0IsQ0FBQztRQUNyQyxXQUFXLEVBQUUsRUFBRTtRQUNmLGlCQUFpQixFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsVUFBVSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUM7S0FDbkYsQ0FBQyxDQUFDO0lBQ0gsYUFBYTtJQUViLE9BQU8sQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLGFBQWEsRUFBRSxlQUFlLENBQUMsQ0FBQztBQUN4RCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQnVmZmVyIH0gZnJvbSAnYnVmZmVyJztcbmltcG9ydCB7IERlcml2ZSB9IGZyb20gJy4uL2VjZHNhLWRrbHMvZGVyaXZlJztcbmltcG9ydCB7IFZyZkRrZyB9IGZyb20gJy4vZGtnJztcblxuLyoqXG4gKiBSdW5zIGEgbG9jYWwgMi1vZi0zIFZSRiBES0cgYWNyb3NzIHVzZXIgKDApLCBiYWNrdXAgKDEpIGFuZCBiaXRnbyAoMikgcGFydGllcyBhbmRcbiAqIHJldHVybnMgdGhlIHRocmVlIGNvbXBsZXRlZCBWcmZEa2cgc2Vzc2lvbnMsIG1pcnJvcmluZyBgZ2VuZXJhdGVES0dLZXlTaGFyZXNgIGZyb21cbiAqIGBlY2RzYS1ka2xzL3V0aWwudHNgIHNvIFZSRiB0ZXN0cyByZWFkIGxpa2UgdGhlIGV4aXN0aW5nIERLTFMgb25lcy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlVnJmREtHS2V5U2hhcmVzKFxuICBzZWVkVXNlcj86IEJ1ZmZlcixcbiAgc2VlZEJhY2t1cD86IEJ1ZmZlcixcbiAgc2VlZEJpdGdvPzogQnVmZmVyXG4pOiBQcm9taXNlPFtWcmZEa2csIFZyZkRrZywgVnJmRGtnXT4ge1xuICBjb25zdCB1c2VyID0gbmV3IFZyZkRrZygzLCAyLCAwLCBzZWVkVXNlcik7XG4gIGNvbnN0IGJhY2t1cCA9IG5ldyBWcmZEa2coMywgMiwgMSwgc2VlZEJhY2t1cCk7XG4gIGNvbnN0IGJpdGdvID0gbmV3IFZyZkRrZygzLCAyLCAyLCBzZWVkQml0Z28pO1xuICAvLyAjcmVnaW9uIHJvdW5kIDFcbiAgY29uc3QgdXNlclJvdW5kMU1lc3NhZ2VzID0gYXdhaXQgdXNlci5pbml0RGtnKCk7XG4gIGNvbnN0IGJhY2t1cFJvdW5kMU1lc3NhZ2VzID0gYXdhaXQgYmFja3VwLmluaXREa2coKTtcbiAgY29uc3QgYml0Z29Sb3VuZDFNZXNzYWdlcyA9IGF3YWl0IGJpdGdvLmluaXREa2coKTtcbiAgY29uc3QgYml0Z29Sb3VuZDJNZXNzYWdlcyA9IGF3YWl0IGJpdGdvLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgIHAycE1lc3NhZ2VzOiBbXSxcbiAgICBicm9hZGNhc3RNZXNzYWdlczogWy4uLnVzZXJSb3VuZDFNZXNzYWdlcy5icm9hZGNhc3RNZXNzYWdlcywgLi4uYmFja3VwUm91bmQxTWVzc2FnZXMuYnJvYWRjYXN0TWVzc2FnZXNdLFxuICB9KTtcbiAgLy8gI2VuZHJlZ2lvblxuXG4gIC8vICNyZWdpb24gcm91bmQgMlxuICBjb25zdCB1c2VyUm91bmQyTWVzc2FnZXMgPSBhd2FpdCB1c2VyLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgIHAycE1lc3NhZ2VzOiBbXSxcbiAgICBicm9hZGNhc3RNZXNzYWdlczogWy4uLmJpdGdvUm91bmQxTWVzc2FnZXMuYnJvYWRjYXN0TWVzc2FnZXMsIC4uLmJhY2t1cFJvdW5kMU1lc3NhZ2VzLmJyb2FkY2FzdE1lc3NhZ2VzXSxcbiAgfSk7XG4gIGNvbnN0IGJhY2t1cFJvdW5kMk1lc3NhZ2VzID0gYXdhaXQgYmFja3VwLmhhbmRsZUluY29taW5nTWVzc2FnZXMoe1xuICAgIHAycE1lc3NhZ2VzOiBbXSxcbiAgICBicm9hZGNhc3RNZXNzYWdlczogWy4uLnVzZXJSb3VuZDFNZXNzYWdlcy5icm9hZGNhc3RNZXNzYWdlcywgLi4uYml0Z29Sb3VuZDFNZXNzYWdlcy5icm9hZGNhc3RNZXNzYWdlc10sXG4gIH0pO1xuICBhd2FpdCBiaXRnby5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKHtcbiAgICBwMnBNZXNzYWdlczogW2JpdGdvUm91bmQyTWVzc2FnZXMsIHVzZXJSb3VuZDJNZXNzYWdlcywgYmFja3VwUm91bmQyTWVzc2FnZXNdXG4gICAgICAuZmxhdE1hcCgobSkgPT4gbS5wMnBNZXNzYWdlcylcbiAgICAgIC5maWx0ZXIoKG0pID0+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=