@bitgo/sdk-lib-mpc 10.14.1 → 10.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/tss/eddsa-mps/index.d.ts +0 -1
- package/dist/src/tss/eddsa-mps/index.d.ts.map +1 -1
- package/dist/src/tss/eddsa-mps/index.js +2 -4
- 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/index.d.ts +1 -0
- package/dist/src/tss/index.d.ts.map +1 -1
- package/dist/src/tss/index.js +2 -1
- package/dist/src/tss/redpallas-mps/dkg.d.ts +105 -0
- package/dist/src/tss/redpallas-mps/dkg.d.ts.map +1 -0
- package/dist/src/tss/redpallas-mps/dkg.js +290 -0
- package/dist/src/tss/redpallas-mps/index.d.ts +4 -0
- package/dist/src/tss/redpallas-mps/index.d.ts.map +1 -0
- package/dist/src/tss/redpallas-mps/index.js +40 -0
- package/dist/src/tss/redpallas-mps/types.d.ts +40 -0
- package/dist/src/tss/redpallas-mps/types.d.ts.map +1 -0
- package/dist/src/tss/redpallas-mps/types.js +89 -0
- package/dist/src/tss/redpallas-mps/util.d.ts +18 -0
- package/dist/src/tss/redpallas-mps/util.d.ts.map +1 -0
- package/dist/src/tss/redpallas-mps/util.js +56 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/dist/src/tss/eddsa-mps/derive.d.ts +0 -18
- package/dist/src/tss/eddsa-mps/derive.d.ts.map +0 -1
- package/dist/src/tss/eddsa-mps/derive.js +0 -51
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as t from 'io-ts';
|
|
2
|
+
export declare const RedPallasReducedKeyShareType: t.TypeC<{
|
|
3
|
+
keyShare: t.ArrayC<t.NumberC>;
|
|
4
|
+
pub: t.ArrayC<t.NumberC>;
|
|
5
|
+
}>;
|
|
6
|
+
export type RedPallasReducedKeyShare = t.TypeOf<typeof RedPallasReducedKeyShareType>;
|
|
7
|
+
/**
|
|
8
|
+
* Represents the state of a RedPallas DKG (Distributed Key Generation) session.
|
|
9
|
+
*
|
|
10
|
+
* Unlike the EdDSA MPS `DkgState`, there is no `Share` state: `redpallas_dkg_round2_process`
|
|
11
|
+
* returns a `MsgDerivationInit` (msg/pk/share/state) directly, completing the DKG session in
|
|
12
|
+
* one step. Key derivation (ask/nk/rivk/ivks) is a separate, subsequent, platform-side-only
|
|
13
|
+
* process (`redpallas_derivation_process`) not modelled here.
|
|
14
|
+
*/
|
|
15
|
+
export declare enum RedPallasDkgState {
|
|
16
|
+
/** DKG session has not been initialized */
|
|
17
|
+
Uninitialized = "Uninitialized",
|
|
18
|
+
/** DKG session has been initialized (Init state in WASM) */
|
|
19
|
+
Init = "Init",
|
|
20
|
+
/** DKG session is waiting for first message (WaitMsg1 state in WASM) */
|
|
21
|
+
WaitMsg1 = "WaitMsg1",
|
|
22
|
+
/** DKG session is waiting for second message (WaitMsg2 state in WASM) */
|
|
23
|
+
WaitMsg2 = "WaitMsg2",
|
|
24
|
+
/** DKG session has completed successfully and key shares are available */
|
|
25
|
+
Complete = "Complete"
|
|
26
|
+
}
|
|
27
|
+
export interface Message<T> {
|
|
28
|
+
payload: T;
|
|
29
|
+
from: number;
|
|
30
|
+
}
|
|
31
|
+
export type SerializedMessage = Message<string>;
|
|
32
|
+
export type SerializedMessages = Message<string>[];
|
|
33
|
+
export type DeserializedMessage = Message<Uint8Array>;
|
|
34
|
+
export type DeserializedMessages = Message<Uint8Array>[];
|
|
35
|
+
export declare function serializeMessage(msg: DeserializedMessage): SerializedMessage;
|
|
36
|
+
export declare function deserializeMessage(msg: SerializedMessage): DeserializedMessage;
|
|
37
|
+
export declare function serializeMessages(msgs: DeserializedMessages): SerializedMessages;
|
|
38
|
+
export declare function deserializeMessages(msgs: SerializedMessages): DeserializedMessages;
|
|
39
|
+
export declare function getDecodedReducedKeyShare(reducedKeyShare: Buffer | Uint8Array): RedPallasReducedKeyShare;
|
|
40
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/tss/redpallas-mps/types.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,CAAC,MAAM,OAAO,CAAC;AAE3B,eAAO,MAAM,4BAA4B;;;EAGvC,CAAC;AAEH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAErF;;;;;;;GAOG;AACH,oBAAY,iBAAiB;IAC3B,2CAA2C;IAC3C,aAAa,kBAAkB;IAC/B,4DAA4D;IAC5D,IAAI,SAAS;IACb,wEAAwE;IACxE,QAAQ,aAAa;IACrB,yEAAyE;IACzE,QAAQ,aAAa;IACrB,0EAA0E;IAC1E,QAAQ,aAAa;CACtB;AAED,MAAM,WAAW,OAAO,CAAC,CAAC;IACxB,OAAO,EAAE,CAAC,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAEhD,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;AAEnD,MAAM,MAAM,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtD,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;AAEzD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,mBAAmB,GAAG,iBAAiB,CAE5E;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,iBAAiB,GAAG,mBAAmB,CAE9E;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,oBAAoB,GAAG,kBAAkB,CAEhF;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,kBAAkB,GAAG,oBAAoB,CAElF;AAED,wBAAgB,yBAAyB,CAAC,eAAe,EAAE,MAAM,GAAG,UAAU,GAAG,wBAAwB,CAMxG"}
|
|
@@ -0,0 +1,89 @@
|
|
|
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.RedPallasDkgState = exports.RedPallasReducedKeyShareType = void 0;
|
|
37
|
+
exports.serializeMessage = serializeMessage;
|
|
38
|
+
exports.deserializeMessage = deserializeMessage;
|
|
39
|
+
exports.serializeMessages = serializeMessages;
|
|
40
|
+
exports.deserializeMessages = deserializeMessages;
|
|
41
|
+
exports.getDecodedReducedKeyShare = getDecodedReducedKeyShare;
|
|
42
|
+
const cbor_x_1 = require("cbor-x");
|
|
43
|
+
const Either_1 = require("fp-ts/Either");
|
|
44
|
+
const t = __importStar(require("io-ts"));
|
|
45
|
+
exports.RedPallasReducedKeyShareType = t.type({
|
|
46
|
+
keyShare: t.array(t.number),
|
|
47
|
+
pub: t.array(t.number),
|
|
48
|
+
});
|
|
49
|
+
/**
|
|
50
|
+
* Represents the state of a RedPallas DKG (Distributed Key Generation) session.
|
|
51
|
+
*
|
|
52
|
+
* Unlike the EdDSA MPS `DkgState`, there is no `Share` state: `redpallas_dkg_round2_process`
|
|
53
|
+
* returns a `MsgDerivationInit` (msg/pk/share/state) directly, completing the DKG session in
|
|
54
|
+
* one step. Key derivation (ask/nk/rivk/ivks) is a separate, subsequent, platform-side-only
|
|
55
|
+
* process (`redpallas_derivation_process`) not modelled here.
|
|
56
|
+
*/
|
|
57
|
+
var RedPallasDkgState;
|
|
58
|
+
(function (RedPallasDkgState) {
|
|
59
|
+
/** DKG session has not been initialized */
|
|
60
|
+
RedPallasDkgState["Uninitialized"] = "Uninitialized";
|
|
61
|
+
/** DKG session has been initialized (Init state in WASM) */
|
|
62
|
+
RedPallasDkgState["Init"] = "Init";
|
|
63
|
+
/** DKG session is waiting for first message (WaitMsg1 state in WASM) */
|
|
64
|
+
RedPallasDkgState["WaitMsg1"] = "WaitMsg1";
|
|
65
|
+
/** DKG session is waiting for second message (WaitMsg2 state in WASM) */
|
|
66
|
+
RedPallasDkgState["WaitMsg2"] = "WaitMsg2";
|
|
67
|
+
/** DKG session has completed successfully and key shares are available */
|
|
68
|
+
RedPallasDkgState["Complete"] = "Complete";
|
|
69
|
+
})(RedPallasDkgState || (exports.RedPallasDkgState = RedPallasDkgState = {}));
|
|
70
|
+
function serializeMessage(msg) {
|
|
71
|
+
return { from: msg.from, payload: Buffer.from(msg.payload).toString('base64') };
|
|
72
|
+
}
|
|
73
|
+
function deserializeMessage(msg) {
|
|
74
|
+
return { from: msg.from, payload: Buffer.from(msg.payload, 'base64') };
|
|
75
|
+
}
|
|
76
|
+
function serializeMessages(msgs) {
|
|
77
|
+
return msgs.map(serializeMessage);
|
|
78
|
+
}
|
|
79
|
+
function deserializeMessages(msgs) {
|
|
80
|
+
return msgs.map(deserializeMessage);
|
|
81
|
+
}
|
|
82
|
+
function getDecodedReducedKeyShare(reducedKeyShare) {
|
|
83
|
+
const decoded = exports.RedPallasReducedKeyShareType.decode((0, cbor_x_1.decode)(reducedKeyShare));
|
|
84
|
+
if ((0, Either_1.isLeft)(decoded)) {
|
|
85
|
+
throw new Error(`Unable to parse reducedKeyShare: ${decoded.left}`);
|
|
86
|
+
}
|
|
87
|
+
return decoded.right;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdHNzL3JlZHBhbGxhcy1tcHMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBNkNBLDRDQUVDO0FBRUQsZ0RBRUM7QUFFRCw4Q0FFQztBQUVELGtEQUVDO0FBRUQsOERBTUM7QUFuRUQsbUNBQWdDO0FBQ2hDLHlDQUFzQztBQUN0Qyx5Q0FBMkI7QUFFZCxRQUFBLDRCQUE0QixHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDakQsUUFBUSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUMzQixHQUFHLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDO0NBQ3ZCLENBQUMsQ0FBQztBQUlIOzs7Ozs7O0dBT0c7QUFDSCxJQUFZLGlCQVdYO0FBWEQsV0FBWSxpQkFBaUI7SUFDM0IsMkNBQTJDO0lBQzNDLG9EQUErQixDQUFBO0lBQy9CLDREQUE0RDtJQUM1RCxrQ0FBYSxDQUFBO0lBQ2Isd0VBQXdFO0lBQ3hFLDBDQUFxQixDQUFBO0lBQ3JCLHlFQUF5RTtJQUN6RSwwQ0FBcUIsQ0FBQTtJQUNyQiwwRUFBMEU7SUFDMUUsMENBQXFCLENBQUE7QUFDdkIsQ0FBQyxFQVhXLGlCQUFpQixpQ0FBakIsaUJBQWlCLFFBVzVCO0FBZUQsU0FBZ0IsZ0JBQWdCLENBQUMsR0FBd0I7SUFDdkQsT0FBTyxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztBQUNsRixDQUFDO0FBRUQsU0FBZ0Isa0JBQWtCLENBQUMsR0FBc0I7SUFDdkQsT0FBTyxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLEVBQUUsQ0FBQztBQUN6RSxDQUFDO0FBRUQsU0FBZ0IsaUJBQWlCLENBQUMsSUFBMEI7SUFDMUQsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLENBQUM7QUFDcEMsQ0FBQztBQUVELFNBQWdCLG1CQUFtQixDQUFDLElBQXdCO0lBQzFELE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0FBQ3RDLENBQUM7QUFFRCxTQUFnQix5QkFBeUIsQ0FBQyxlQUFvQztJQUM1RSxNQUFNLE9BQU8sR0FBRyxvQ0FBNEIsQ0FBQyxNQUFNLENBQUMsSUFBQSxlQUFNLEVBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQztJQUM3RSxJQUFJLElBQUEsZUFBTSxFQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDcEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxvQ0FBb0MsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFDdEUsQ0FBQztJQUNELE9BQU8sT0FBTyxDQUFDLEtBQUssQ0FBQztBQUN2QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZGVjb2RlIH0gZnJvbSAnY2Jvci14JztcbmltcG9ydCB7IGlzTGVmdCB9IGZyb20gJ2ZwLXRzL0VpdGhlcic7XG5pbXBvcnQgKiBhcyB0IGZyb20gJ2lvLXRzJztcblxuZXhwb3J0IGNvbnN0IFJlZFBhbGxhc1JlZHVjZWRLZXlTaGFyZVR5cGUgPSB0LnR5cGUoe1xuICBrZXlTaGFyZTogdC5hcnJheSh0Lm51bWJlciksXG4gIHB1YjogdC5hcnJheSh0Lm51bWJlciksXG59KTtcblxuZXhwb3J0IHR5cGUgUmVkUGFsbGFzUmVkdWNlZEtleVNoYXJlID0gdC5UeXBlT2Y8dHlwZW9mIFJlZFBhbGxhc1JlZHVjZWRLZXlTaGFyZVR5cGU+O1xuXG4vKipcbiAqIFJlcHJlc2VudHMgdGhlIHN0YXRlIG9mIGEgUmVkUGFsbGFzIERLRyAoRGlzdHJpYnV0ZWQgS2V5IEdlbmVyYXRpb24pIHNlc3Npb24uXG4gKlxuICogVW5saWtlIHRoZSBFZERTQSBNUFMgYERrZ1N0YXRlYCwgdGhlcmUgaXMgbm8gYFNoYXJlYCBzdGF0ZTogYHJlZHBhbGxhc19ka2dfcm91bmQyX3Byb2Nlc3NgXG4gKiByZXR1cm5zIGEgYE1zZ0Rlcml2YXRpb25Jbml0YCAobXNnL3BrL3NoYXJlL3N0YXRlKSBkaXJlY3RseSwgY29tcGxldGluZyB0aGUgREtHIHNlc3Npb24gaW5cbiAqIG9uZSBzdGVwLiBLZXkgZGVyaXZhdGlvbiAoYXNrL25rL3JpdmsvaXZrcykgaXMgYSBzZXBhcmF0ZSwgc3Vic2VxdWVudCwgcGxhdGZvcm0tc2lkZS1vbmx5XG4gKiBwcm9jZXNzIChgcmVkcGFsbGFzX2Rlcml2YXRpb25fcHJvY2Vzc2ApIG5vdCBtb2RlbGxlZCBoZXJlLlxuICovXG5leHBvcnQgZW51bSBSZWRQYWxsYXNEa2dTdGF0ZSB7XG4gIC8qKiBES0cgc2Vzc2lvbiBoYXMgbm90IGJlZW4gaW5pdGlhbGl6ZWQgKi9cbiAgVW5pbml0aWFsaXplZCA9ICdVbmluaXRpYWxpemVkJyxcbiAgLyoqIERLRyBzZXNzaW9uIGhhcyBiZWVuIGluaXRpYWxpemVkIChJbml0IHN0YXRlIGluIFdBU00pICovXG4gIEluaXQgPSAnSW5pdCcsXG4gIC8qKiBES0cgc2Vzc2lvbiBpcyB3YWl0aW5nIGZvciBmaXJzdCBtZXNzYWdlIChXYWl0TXNnMSBzdGF0ZSBpbiBXQVNNKSAqL1xuICBXYWl0TXNnMSA9ICdXYWl0TXNnMScsXG4gIC8qKiBES0cgc2Vzc2lvbiBpcyB3YWl0aW5nIGZvciBzZWNvbmQgbWVzc2FnZSAoV2FpdE1zZzIgc3RhdGUgaW4gV0FTTSkgKi9cbiAgV2FpdE1zZzIgPSAnV2FpdE1zZzInLFxuICAvKiogREtHIHNlc3Npb24gaGFzIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHkgYW5kIGtleSBzaGFyZXMgYXJlIGF2YWlsYWJsZSAqL1xuICBDb21wbGV0ZSA9ICdDb21wbGV0ZScsXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTWVzc2FnZTxUPiB7XG4gIHBheWxvYWQ6IFQ7XG4gIGZyb206IG51bWJlcjtcbn1cblxuZXhwb3J0IHR5cGUgU2VyaWFsaXplZE1lc3NhZ2UgPSBNZXNzYWdlPHN0cmluZz47XG5cbmV4cG9ydCB0eXBlIFNlcmlhbGl6ZWRNZXNzYWdlcyA9IE1lc3NhZ2U8c3RyaW5nPltdO1xuXG5leHBvcnQgdHlwZSBEZXNlcmlhbGl6ZWRNZXNzYWdlID0gTWVzc2FnZTxVaW50OEFycmF5PjtcblxuZXhwb3J0IHR5cGUgRGVzZXJpYWxpemVkTWVzc2FnZXMgPSBNZXNzYWdlPFVpbnQ4QXJyYXk+W107XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXJpYWxpemVNZXNzYWdlKG1zZzogRGVzZXJpYWxpemVkTWVzc2FnZSk6IFNlcmlhbGl6ZWRNZXNzYWdlIHtcbiAgcmV0dXJuIHsgZnJvbTogbXNnLmZyb20sIHBheWxvYWQ6IEJ1ZmZlci5mcm9tKG1zZy5wYXlsb2FkKS50b1N0cmluZygnYmFzZTY0JykgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlc2VyaWFsaXplTWVzc2FnZShtc2c6IFNlcmlhbGl6ZWRNZXNzYWdlKTogRGVzZXJpYWxpemVkTWVzc2FnZSB7XG4gIHJldHVybiB7IGZyb206IG1zZy5mcm9tLCBwYXlsb2FkOiBCdWZmZXIuZnJvbShtc2cucGF5bG9hZCwgJ2Jhc2U2NCcpIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXJpYWxpemVNZXNzYWdlcyhtc2dzOiBEZXNlcmlhbGl6ZWRNZXNzYWdlcyk6IFNlcmlhbGl6ZWRNZXNzYWdlcyB7XG4gIHJldHVybiBtc2dzLm1hcChzZXJpYWxpemVNZXNzYWdlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlc2VyaWFsaXplTWVzc2FnZXMobXNnczogU2VyaWFsaXplZE1lc3NhZ2VzKTogRGVzZXJpYWxpemVkTWVzc2FnZXMge1xuICByZXR1cm4gbXNncy5tYXAoZGVzZXJpYWxpemVNZXNzYWdlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERlY29kZWRSZWR1Y2VkS2V5U2hhcmUocmVkdWNlZEtleVNoYXJlOiBCdWZmZXIgfCBVaW50OEFycmF5KTogUmVkUGFsbGFzUmVkdWNlZEtleVNoYXJlIHtcbiAgY29uc3QgZGVjb2RlZCA9IFJlZFBhbGxhc1JlZHVjZWRLZXlTaGFyZVR5cGUuZGVjb2RlKGRlY29kZShyZWR1Y2VkS2V5U2hhcmUpKTtcbiAgaWYgKGlzTGVmdChkZWNvZGVkKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIHBhcnNlIHJlZHVjZWRLZXlTaGFyZTogJHtkZWNvZGVkLmxlZnR9YCk7XG4gIH1cbiAgcmV0dXJuIGRlY29kZWQucmlnaHQ7XG59XG4iXX0=
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { RedPallasDKG } from './dkg';
|
|
2
|
+
/**
|
|
3
|
+
* Per-party deterministic seed material. To use the same seed for both, pass it as both fields.
|
|
4
|
+
* `encKey` seeds the X25519 encryption key; `dkgSeed` seeds DKG round 0.
|
|
5
|
+
*/
|
|
6
|
+
export interface RedPallasDKGPartySeed {
|
|
7
|
+
encKey?: Buffer;
|
|
8
|
+
dkgSeed?: Buffer;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Runs a full 3-party (2-of-3) RedPallas DKG in-process. See `RedPallasDKGPartySeed`.
|
|
12
|
+
* Mirrors `generateEdDsaDKGKeyShares` in `../eddsa-mps/util.ts`.
|
|
13
|
+
*
|
|
14
|
+
* @param derivationSeed - 32-byte seed consumed by round2 for the (platform-side-only)
|
|
15
|
+
* subsequent derivation process. Must be the same value across all three parties.
|
|
16
|
+
*/
|
|
17
|
+
export declare function generateRedPallasDKGKeyShares(derivationSeed: Buffer, seedUser?: RedPallasDKGPartySeed, seedBackup?: RedPallasDKGPartySeed, seedBitgo?: RedPallasDKGPartySeed): Promise<[RedPallasDKG, RedPallasDKG, RedPallasDKG]>;
|
|
18
|
+
//# sourceMappingURL=util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../../src/tss/redpallas-mps/util.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAQrC;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAQD;;;;;;GAMG;AACH,wBAAsB,6BAA6B,CACjD,cAAc,EAAE,MAAM,EACtB,QAAQ,CAAC,EAAE,qBAAqB,EAChC,UAAU,CAAC,EAAE,qBAAqB,EAClC,SAAS,CAAC,EAAE,qBAAqB,GAChC,OAAO,CAAC,CAAC,YAAY,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC,CAkCrD"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.generateRedPallasDKGKeyShares = generateRedPallasDKGKeyShares;
|
|
7
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
8
|
+
const assert_1 = __importDefault(require("assert"));
|
|
9
|
+
const ed25519_1 = require("@noble/curves/ed25519");
|
|
10
|
+
const dkg_1 = require("./dkg");
|
|
11
|
+
function generateX25519Keypair(seed) {
|
|
12
|
+
const privKey = seed ? seed.subarray(0, 32) : crypto_1.default.randomBytes(32);
|
|
13
|
+
const pubKey = Buffer.from(ed25519_1.x25519.getPublicKey(privKey));
|
|
14
|
+
return { privKey: Buffer.from(privKey), pubKey };
|
|
15
|
+
}
|
|
16
|
+
function validateSeed(seed) {
|
|
17
|
+
(0, assert_1.default)(!seed?.encKey || seed.encKey.length >= 32, 'encKey must be at least 32 bytes');
|
|
18
|
+
(0, assert_1.default)(!seed?.dkgSeed || seed.dkgSeed.length >= 32, 'dkgSeed must be at least 32 bytes');
|
|
19
|
+
return seed ?? {};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Runs a full 3-party (2-of-3) RedPallas DKG in-process. See `RedPallasDKGPartySeed`.
|
|
23
|
+
* Mirrors `generateEdDsaDKGKeyShares` in `../eddsa-mps/util.ts`.
|
|
24
|
+
*
|
|
25
|
+
* @param derivationSeed - 32-byte seed consumed by round2 for the (platform-side-only)
|
|
26
|
+
* subsequent derivation process. Must be the same value across all three parties.
|
|
27
|
+
*/
|
|
28
|
+
async function generateRedPallasDKGKeyShares(derivationSeed, seedUser, seedBackup, seedBitgo) {
|
|
29
|
+
const { encKey: userEncKey, dkgSeed: userDkgSeed } = validateSeed(seedUser);
|
|
30
|
+
const { encKey: backupEncKey, dkgSeed: backupDkgSeed } = validateSeed(seedBackup);
|
|
31
|
+
const { encKey: bitgoEncKey, dkgSeed: bitgoDkgSeed } = validateSeed(seedBitgo);
|
|
32
|
+
const user = new dkg_1.RedPallasDKG(3, 2, 0);
|
|
33
|
+
const backup = new dkg_1.RedPallasDKG(3, 2, 1);
|
|
34
|
+
const bitgo = new dkg_1.RedPallasDKG(3, 2, 2);
|
|
35
|
+
const userKP = generateX25519Keypair(userEncKey);
|
|
36
|
+
const backupKP = generateX25519Keypair(backupEncKey);
|
|
37
|
+
const bitgoKP = generateX25519Keypair(bitgoEncKey);
|
|
38
|
+
await user.initDkg(userKP.privKey, [backupKP.pubKey, bitgoKP.pubKey]);
|
|
39
|
+
await backup.initDkg(backupKP.privKey, [userKP.pubKey, bitgoKP.pubKey]);
|
|
40
|
+
await bitgo.initDkg(bitgoKP.privKey, [userKP.pubKey, backupKP.pubKey]);
|
|
41
|
+
const r1Messages = [
|
|
42
|
+
user.getFirstMessage(userDkgSeed),
|
|
43
|
+
backup.getFirstMessage(backupDkgSeed),
|
|
44
|
+
bitgo.getFirstMessage(bitgoDkgSeed),
|
|
45
|
+
];
|
|
46
|
+
const r2Messages = [
|
|
47
|
+
...user.handleIncomingMessages(r1Messages),
|
|
48
|
+
...backup.handleIncomingMessages(r1Messages),
|
|
49
|
+
...bitgo.handleIncomingMessages(r1Messages),
|
|
50
|
+
];
|
|
51
|
+
user.handleIncomingMessages(r2Messages, derivationSeed);
|
|
52
|
+
backup.handleIncomingMessages(r2Messages, derivationSeed);
|
|
53
|
+
bitgo.handleIncomingMessages(r2Messages, derivationSeed);
|
|
54
|
+
return [user, backup, bitgo];
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy90c3MvcmVkcGFsbGFzLW1wcy91dGlsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBaUNBLHNFQXVDQztBQXhFRCxvREFBNEI7QUFDNUIsb0RBQTRCO0FBQzVCLG1EQUErQztBQUMvQywrQkFBcUM7QUFFckMsU0FBUyxxQkFBcUIsQ0FBQyxJQUFhO0lBQzFDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLGdCQUFNLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ3JFLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsZ0JBQU0sQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztJQUN6RCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUM7QUFDbkQsQ0FBQztBQVdELFNBQVMsWUFBWSxDQUFDLElBQTRCO0lBQ2hELElBQUEsZ0JBQU0sRUFBQyxDQUFDLElBQUksRUFBRSxNQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLElBQUksRUFBRSxFQUFFLGtDQUFrQyxDQUFDLENBQUM7SUFDdEYsSUFBQSxnQkFBTSxFQUFDLENBQUMsSUFBSSxFQUFFLE9BQU8sSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sSUFBSSxFQUFFLEVBQUUsbUNBQW1DLENBQUMsQ0FBQztJQUN6RixPQUFPLElBQUksSUFBSSxFQUFFLENBQUM7QUFDcEIsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNJLEtBQUssVUFBVSw2QkFBNkIsQ0FDakQsY0FBc0IsRUFDdEIsUUFBZ0MsRUFDaEMsVUFBa0MsRUFDbEMsU0FBaUM7SUFFakMsTUFBTSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxHQUFHLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM1RSxNQUFNLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUFFLEdBQUcsWUFBWSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ2xGLE1BQU0sRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsR0FBRyxZQUFZLENBQUMsU0FBUyxDQUFDLENBQUM7SUFFL0UsTUFBTSxJQUFJLEdBQUcsSUFBSSxrQkFBWSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDdkMsTUFBTSxNQUFNLEdBQUcsSUFBSSxrQkFBWSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDekMsTUFBTSxLQUFLLEdBQUcsSUFBSSxrQkFBWSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFeEMsTUFBTSxNQUFNLEdBQUcscUJBQXFCLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDakQsTUFBTSxRQUFRLEdBQUcscUJBQXFCLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDckQsTUFBTSxPQUFPLEdBQUcscUJBQXFCLENBQUMsV0FBVyxDQUFDLENBQUM7SUFFbkQsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQ3RFLE1BQU0sTUFBTSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUN4RSxNQUFNLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFFdkUsTUFBTSxVQUFVLEdBQUc7UUFDakIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxXQUFXLENBQUM7UUFDakMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxhQUFhLENBQUM7UUFDckMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUM7S0FDcEMsQ0FBQztJQUVGLE1BQU0sVUFBVSxHQUFHO1FBQ2pCLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUFDLFVBQVUsQ0FBQztRQUMxQyxHQUFHLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxVQUFVLENBQUM7UUFDNUMsR0FBRyxLQUFLLENBQUMsc0JBQXNCLENBQUMsVUFBVSxDQUFDO0tBQzVDLENBQUM7SUFFRixJQUFJLENBQUMsc0JBQXNCLENBQUMsVUFBVSxFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBQ3hELE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxVQUFVLEVBQUUsY0FBYyxDQUFDLENBQUM7SUFDMUQsS0FBSyxDQUFDLHNCQUFzQixDQUFDLFVBQVUsRUFBRSxjQUFjLENBQUMsQ0FBQztJQUV6RCxPQUFPLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQztBQUMvQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGNyeXB0byBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnO1xuaW1wb3J0IHsgeDI1NTE5IH0gZnJvbSAnQG5vYmxlL2N1cnZlcy9lZDI1NTE5JztcbmltcG9ydCB7IFJlZFBhbGxhc0RLRyB9IGZyb20gJy4vZGtnJztcblxuZnVuY3Rpb24gZ2VuZXJhdGVYMjU1MTlLZXlwYWlyKHNlZWQ/OiBCdWZmZXIpOiB7IHByaXZLZXk6IEJ1ZmZlcjsgcHViS2V5OiBCdWZmZXIgfSB7XG4gIGNvbnN0IHByaXZLZXkgPSBzZWVkID8gc2VlZC5zdWJhcnJheSgwLCAzMikgOiBjcnlwdG8ucmFuZG9tQnl0ZXMoMzIpO1xuICBjb25zdCBwdWJLZXkgPSBCdWZmZXIuZnJvbSh4MjU1MTkuZ2V0UHVibGljS2V5KHByaXZLZXkpKTtcbiAgcmV0dXJuIHsgcHJpdktleTogQnVmZmVyLmZyb20ocHJpdktleSksIHB1YktleSB9O1xufVxuXG4vKipcbiAqIFBlci1wYXJ0eSBkZXRlcm1pbmlzdGljIHNlZWQgbWF0ZXJpYWwuIFRvIHVzZSB0aGUgc2FtZSBzZWVkIGZvciBib3RoLCBwYXNzIGl0IGFzIGJvdGggZmllbGRzLlxuICogYGVuY0tleWAgc2VlZHMgdGhlIFgyNTUxOSBlbmNyeXB0aW9uIGtleTsgYGRrZ1NlZWRgIHNlZWRzIERLRyByb3VuZCAwLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlZFBhbGxhc0RLR1BhcnR5U2VlZCB7XG4gIGVuY0tleT86IEJ1ZmZlcjtcbiAgZGtnU2VlZD86IEJ1ZmZlcjtcbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVTZWVkKHNlZWQ/OiBSZWRQYWxsYXNES0dQYXJ0eVNlZWQpOiBSZWRQYWxsYXNES0dQYXJ0eVNlZWQge1xuICBhc3NlcnQoIXNlZWQ/LmVuY0tleSB8fCBzZWVkLmVuY0tleS5sZW5ndGggPj0gMzIsICdlbmNLZXkgbXVzdCBiZSBhdCBsZWFzdCAzMiBieXRlcycpO1xuICBhc3NlcnQoIXNlZWQ/LmRrZ1NlZWQgfHwgc2VlZC5ka2dTZWVkLmxlbmd0aCA+PSAzMiwgJ2RrZ1NlZWQgbXVzdCBiZSBhdCBsZWFzdCAzMiBieXRlcycpO1xuICByZXR1cm4gc2VlZCA/PyB7fTtcbn1cblxuLyoqXG4gKiBSdW5zIGEgZnVsbCAzLXBhcnR5ICgyLW9mLTMpIFJlZFBhbGxhcyBES0cgaW4tcHJvY2Vzcy4gU2VlIGBSZWRQYWxsYXNES0dQYXJ0eVNlZWRgLlxuICogTWlycm9ycyBgZ2VuZXJhdGVFZERzYURLR0tleVNoYXJlc2AgaW4gYC4uL2VkZHNhLW1wcy91dGlsLnRzYC5cbiAqXG4gKiBAcGFyYW0gZGVyaXZhdGlvblNlZWQgLSAzMi1ieXRlIHNlZWQgY29uc3VtZWQgYnkgcm91bmQyIGZvciB0aGUgKHBsYXRmb3JtLXNpZGUtb25seSlcbiAqICAgc3Vic2VxdWVudCBkZXJpdmF0aW9uIHByb2Nlc3MuIE11c3QgYmUgdGhlIHNhbWUgdmFsdWUgYWNyb3NzIGFsbCB0aHJlZSBwYXJ0aWVzLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGVSZWRQYWxsYXNES0dLZXlTaGFyZXMoXG4gIGRlcml2YXRpb25TZWVkOiBCdWZmZXIsXG4gIHNlZWRVc2VyPzogUmVkUGFsbGFzREtHUGFydHlTZWVkLFxuICBzZWVkQmFja3VwPzogUmVkUGFsbGFzREtHUGFydHlTZWVkLFxuICBzZWVkQml0Z28/OiBSZWRQYWxsYXNES0dQYXJ0eVNlZWRcbik6IFByb21pc2U8W1JlZFBhbGxhc0RLRywgUmVkUGFsbGFzREtHLCBSZWRQYWxsYXNES0ddPiB7XG4gIGNvbnN0IHsgZW5jS2V5OiB1c2VyRW5jS2V5LCBka2dTZWVkOiB1c2VyRGtnU2VlZCB9ID0gdmFsaWRhdGVTZWVkKHNlZWRVc2VyKTtcbiAgY29uc3QgeyBlbmNLZXk6IGJhY2t1cEVuY0tleSwgZGtnU2VlZDogYmFja3VwRGtnU2VlZCB9ID0gdmFsaWRhdGVTZWVkKHNlZWRCYWNrdXApO1xuICBjb25zdCB7IGVuY0tleTogYml0Z29FbmNLZXksIGRrZ1NlZWQ6IGJpdGdvRGtnU2VlZCB9ID0gdmFsaWRhdGVTZWVkKHNlZWRCaXRnbyk7XG5cbiAgY29uc3QgdXNlciA9IG5ldyBSZWRQYWxsYXNES0coMywgMiwgMCk7XG4gIGNvbnN0IGJhY2t1cCA9IG5ldyBSZWRQYWxsYXNES0coMywgMiwgMSk7XG4gIGNvbnN0IGJpdGdvID0gbmV3IFJlZFBhbGxhc0RLRygzLCAyLCAyKTtcblxuICBjb25zdCB1c2VyS1AgPSBnZW5lcmF0ZVgyNTUxOUtleXBhaXIodXNlckVuY0tleSk7XG4gIGNvbnN0IGJhY2t1cEtQID0gZ2VuZXJhdGVYMjU1MTlLZXlwYWlyKGJhY2t1cEVuY0tleSk7XG4gIGNvbnN0IGJpdGdvS1AgPSBnZW5lcmF0ZVgyNTUxOUtleXBhaXIoYml0Z29FbmNLZXkpO1xuXG4gIGF3YWl0IHVzZXIuaW5pdERrZyh1c2VyS1AucHJpdktleSwgW2JhY2t1cEtQLnB1YktleSwgYml0Z29LUC5wdWJLZXldKTtcbiAgYXdhaXQgYmFja3VwLmluaXREa2coYmFja3VwS1AucHJpdktleSwgW3VzZXJLUC5wdWJLZXksIGJpdGdvS1AucHViS2V5XSk7XG4gIGF3YWl0IGJpdGdvLmluaXREa2coYml0Z29LUC5wcml2S2V5LCBbdXNlcktQLnB1YktleSwgYmFja3VwS1AucHViS2V5XSk7XG5cbiAgY29uc3QgcjFNZXNzYWdlcyA9IFtcbiAgICB1c2VyLmdldEZpcnN0TWVzc2FnZSh1c2VyRGtnU2VlZCksXG4gICAgYmFja3VwLmdldEZpcnN0TWVzc2FnZShiYWNrdXBEa2dTZWVkKSxcbiAgICBiaXRnby5nZXRGaXJzdE1lc3NhZ2UoYml0Z29Ea2dTZWVkKSxcbiAgXTtcblxuICBjb25zdCByMk1lc3NhZ2VzID0gW1xuICAgIC4uLnVzZXIuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhyMU1lc3NhZ2VzKSxcbiAgICAuLi5iYWNrdXAuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhyMU1lc3NhZ2VzKSxcbiAgICAuLi5iaXRnby5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKHIxTWVzc2FnZXMpLFxuICBdO1xuXG4gIHVzZXIuaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhyMk1lc3NhZ2VzLCBkZXJpdmF0aW9uU2VlZCk7XG4gIGJhY2t1cC5oYW5kbGVJbmNvbWluZ01lc3NhZ2VzKHIyTWVzc2FnZXMsIGRlcml2YXRpb25TZWVkKTtcbiAgYml0Z28uaGFuZGxlSW5jb21pbmdNZXNzYWdlcyhyMk1lc3NhZ2VzLCBkZXJpdmF0aW9uU2VlZCk7XG5cbiAgcmV0dXJuIFt1c2VyLCBiYWNrdXAsIGJpdGdvXTtcbn1cbiJdfQ==
|