@bitgo/sdk-lib-mpc 8.7.0 → 8.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/src/tss/ecdsa/rangeproof.d.ts.map +1 -1
  3. package/dist/src/tss/ecdsa/rangeproof.js +4 -1
  4. package/dist/tsconfig.tsbuildinfo +1 -1
  5. package/package.json +3 -4
  6. package/dist/src/curves/baseCurve.d.ts +0 -19
  7. package/dist/src/curves/baseCurve.d.ts.map +0 -1
  8. package/dist/src/curves/baseCurve.js +0 -6
  9. package/dist/src/curves/bip32.d.ts +0 -8
  10. package/dist/src/curves/bip32.d.ts.map +0 -1
  11. package/dist/src/curves/bip32.js +0 -54
  12. package/dist/src/curves/bip32HdTree.d.ts +0 -8
  13. package/dist/src/curves/bip32HdTree.d.ts.map +0 -1
  14. package/dist/src/curves/bip32HdTree.js +0 -54
  15. package/dist/src/curves/hdTree.d.ts +0 -2
  16. package/dist/src/curves/hdTree.d.ts.map +0 -1
  17. package/dist/src/curves/hdTree.js +0 -11
  18. package/dist/src/curves/nobleEcc.d.ts +0 -10
  19. package/dist/src/curves/nobleEcc.d.ts.map +0 -1
  20. package/dist/src/curves/nobleEcc.js +0 -194
  21. package/dist/src/curves/shamir.d.ts +0 -37
  22. package/dist/src/curves/shamir.d.ts.map +0 -1
  23. package/dist/src/curves/shamir.js +0 -136
  24. package/dist/src/tss/ecdsa/generatePaillierKey.d.ts +0 -6
  25. package/dist/src/tss/ecdsa/generatePaillierKey.d.ts.map +0 -1
  26. package/dist/src/tss/ecdsa/generatePaillierKey.js +0 -52
  27. package/dist/src/tss/ecdsa/mpc.d.ts +0 -129
  28. package/dist/src/tss/ecdsa/mpc.d.ts.map +0 -1
  29. package/dist/src/tss/ecdsa/mpc.js +0 -1095
  30. package/dist/src/tss/ecdsa/paillierBlumProof.d.ts +0 -16
  31. package/dist/src/tss/ecdsa/paillierBlumProof.d.ts.map +0 -1
  32. package/dist/src/tss/ecdsa/paillierBlumProof.js +0 -135
@@ -1,16 +0,0 @@
1
- import { DeserializedPaillierBlumProof } from './types';
2
- /**
3
- * Prove that a modulus (p*q) is the product of two large safe primes (p and q).
4
- * @param {bigint} p The larger prime factor of the modulus
5
- * @param {bigint} q The smaller prime factor of the modulus.
6
- * @returns {DeserializedPaillierBlumProof} The proof that the modulus is the product of two large primes.
7
- */
8
- export declare function prove(p: bigint, q: bigint): Promise<DeserializedPaillierBlumProof>;
9
- /**
10
- * Verify that N is the product of two large primes.
11
- * @param {bigint} N The prime number being verified.
12
- * @param {DeserializedPaillierBlumProof} The proof to verify N is a product of two large primes.
13
- * @returns {boolean} True if N is a product of two large primes, and false otherwise.
14
- */
15
- export declare function verify(N: bigint, { w, x, z }: DeserializedPaillierBlumProof): Promise<boolean>;
16
- //# sourceMappingURL=paillierBlumProof.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"paillierBlumProof.d.ts","sourceRoot":"","sources":["../../../../src/tss/ecdsa/paillierBlumProof.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,6BAA6B,EAAE,MAAM,SAAS,CAAC;AAiExD;;;;;GAKG;AACH,wBAAsB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,6BAA6B,CAAC,CAuBxF;AAED;;;;;GAKG;AACH,wBAAsB,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,6BAA6B,GAAG,OAAO,CAAC,OAAO,CAAC,CA8BpG"}
@@ -1,135 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.verify = exports.prove = void 0;
4
- const crypto_1 = require("crypto");
5
- const bigint_crypto_utils_1 = require("bigint-crypto-utils");
6
- const bigint_mod_arith_1 = require("bigint-mod-arith");
7
- const util_1 = require("../../util");
8
- // Security parameter.
9
- const m = 80;
10
- /**
11
- * Generate psuedo-random quadratic residue for (N, w, i).
12
- * @param N - the prime number to verify is a product of two large primes.
13
- * @param w - a random number with the same bitLength as N, that satisfies the Jacobi of w is -1 wrt N.
14
- * @returns {bigint[]} - set of challenges for N
15
- */
16
- function generateY(N, w) {
17
- const NBuf = util_1.bigIntToBufferBE(N);
18
- const wBuf = util_1.bigIntToBufferBE(w, NBuf.length);
19
- return Array(m)
20
- .fill(null)
21
- .map((_, i) => {
22
- const h = util_1.bigIntFromBufferBE(crypto_1.createHmac('sha256', Buffer.from([i]))
23
- .update(NBuf)
24
- .update(wBuf)
25
- .digest());
26
- return h * h;
27
- });
28
- }
29
- // https://en.wikipedia.org/wiki/Jacobi_symbol#Implementation_in_C++
30
- function jacobi(a, n) {
31
- // a/n is represented as (a,n)
32
- if (n <= BigInt(0)) {
33
- throw new Error('n must greater than 0');
34
- }
35
- if (n % BigInt(2) !== BigInt(1)) {
36
- throw new Error('n must be odd');
37
- }
38
- // step 1
39
- a = a % n;
40
- let t = BigInt(1);
41
- let r;
42
- // step 3
43
- while (a !== BigInt(0)) {
44
- // step 2
45
- while (a % BigInt(2) === BigInt(0)) {
46
- a /= BigInt(2);
47
- r = n % BigInt(8);
48
- if (r === BigInt(3) || r === BigInt(5)) {
49
- t = -t;
50
- }
51
- }
52
- // step 4
53
- r = n;
54
- n = a;
55
- a = r;
56
- if (a % BigInt(4) === BigInt(3) && n % BigInt(4) === BigInt(3)) {
57
- t = -t;
58
- }
59
- a = a % n;
60
- }
61
- if (n === BigInt(1)) {
62
- return t;
63
- }
64
- return BigInt(0);
65
- }
66
- /**
67
- * Prove that a modulus (p*q) is the product of two large safe primes (p and q).
68
- * @param {bigint} p The larger prime factor of the modulus
69
- * @param {bigint} q The smaller prime factor of the modulus.
70
- * @returns {DeserializedPaillierBlumProof} The proof that the modulus is the product of two large primes.
71
- */
72
- async function prove(p, q) {
73
- // Prover selects random w with Jacobi symbol 1 wrt N.
74
- const N = p * q;
75
- const l = (p - BigInt(1)) * (q - BigInt(1));
76
- const d = bigint_mod_arith_1.modInv(N, l);
77
- let w;
78
- while (true) {
79
- w = util_1.bigIntFromBufferBE(Buffer.from(await bigint_crypto_utils_1.randBits(bigint_crypto_utils_1.bitLength(N))));
80
- if (jacobi(w, N) === BigInt(-1)) {
81
- break;
82
- }
83
- }
84
- // This is calculating the inverse of the function y^4 mod N,
85
- // i.e.y ^ (1 / 4), where N = pq is a blum integer using HOC - Fact 2.160
86
- // from cacr.uwaterloo.ca / hac / about / chap2.pdf
87
- // Prover generates y_i.
88
- const y = generateY(N, w);
89
- // Prover calculates z_i = y_i ^ d mod N
90
- const z = y.map((y_i) => bigint_mod_arith_1.modPow(y_i, d, N));
91
- // Prover calculates x_i = y_i ^ 1/4 mod N using [HOC - Fact 2.160]
92
- const e = ((l + BigInt(4)) / BigInt(8)) ** BigInt(2);
93
- const x = y.map((y_i) => bigint_mod_arith_1.modPow(y_i, e, N));
94
- return { w, x, z };
95
- }
96
- exports.prove = prove;
97
- /**
98
- * Verify that N is the product of two large primes.
99
- * @param {bigint} N The prime number being verified.
100
- * @param {DeserializedPaillierBlumProof} The proof to verify N is a product of two large primes.
101
- * @returns {boolean} True if N is a product of two large primes, and false otherwise.
102
- */
103
- async function verify(N, { w, x, z }) {
104
- // Verifier checks N > 1.
105
- if (N <= 1) {
106
- throw new Error('N must be greater than 1');
107
- }
108
- // Verifier checks N is odd.
109
- if (N % BigInt(2) !== BigInt(1)) {
110
- throw new Error('N must be an odd number');
111
- }
112
- // Verifier checks N is not prime.
113
- if (await bigint_crypto_utils_1.isProbablyPrime(N, 24)) {
114
- throw new Error('N must be a composite number');
115
- }
116
- // Verifier checks that the Jacobi symbol for w is 1 wrt N.
117
- if (jacobi(w, N) !== BigInt(-1)) {
118
- throw new Error('Jacobi symbol of w must be -1 wrt to N');
119
- }
120
- // Verifier generates y_i.
121
- const y = generateY(N, w);
122
- for (let i = 0; i < m; i++) {
123
- // Verifier checks z_i ^ N mod N == y_i.
124
- if (bigint_mod_arith_1.modPow(z[i], N, N) !== y[i]) {
125
- throw new Error(`Paillier verification of z[${i}] failed`);
126
- }
127
- // Verifier checks x_i ^ 4 mod N == y_i.
128
- if (bigint_mod_arith_1.modPow(x[i], 4, N) !== y[i]) {
129
- throw new Error(`Paillier verification of x[${i}] failed`);
130
- }
131
- }
132
- return true;
133
- }
134
- exports.verify = verify;
135
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFpbGxpZXJCbHVtUHJvb2YuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdHNzL2VjZHNhL3BhaWxsaWVyQmx1bVByb29mLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG1DQUFvQztBQUNwQyw2REFBMkU7QUFDM0UsdURBQWtEO0FBQ2xELHFDQUFrRTtBQUdsRSxzQkFBc0I7QUFDdEIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBRWI7Ozs7O0dBS0c7QUFDSCxTQUFTLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUNyQixNQUFNLElBQUksR0FBRyx1QkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNqQyxNQUFNLElBQUksR0FBRyx1QkFBZ0IsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzlDLE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQztTQUNaLElBQUksQ0FBQyxJQUFJLENBQUM7U0FDVixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDWixNQUFNLENBQUMsR0FBRyx5QkFBa0IsQ0FDMUIsbUJBQVUsQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDbkMsTUFBTSxDQUFDLElBQUksQ0FBQzthQUNaLE1BQU0sQ0FBQyxJQUFJLENBQUM7YUFDWixNQUFNLEVBQUUsQ0FDWixDQUFDO1FBQ0YsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2YsQ0FBQyxDQUFDLENBQUM7QUFDUCxDQUFDO0FBRUQsb0VBQW9FO0FBQ3BFLFNBQVMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQ2xCLDhCQUE4QjtJQUM5QixJQUFJLENBQUMsSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUU7UUFDbEIsTUFBTSxJQUFJLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0tBQzFDO0lB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MUIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUMxQix3Q0FBd0M7UUFDeEMsSUFBSSx5QkFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQy9CLE1BQU0sSUFBSSxLQUFLLENBQUMsOEJBQThCLENBQUMsVUFBVSxDQUFDLENBQUM7U0FDNUQ7UUFDRCx3Q0FBd0M7UUFDeEMsSUFBSSx5QkFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQy9CLE1BQU0sSUFBSSxLQUFLLENBQUMsOEJBQThCLENBQUMsVUFBVSxDQUFDLENBQUM7U0FDNUQ7S0FDRjtJQUNELE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQTlCRCx3QkE4QkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjcmVhdGVIbWFjIH0gZnJvbSAnY3J5cHRvJztcbmltcG9ydCB7IGJpdExlbmd0aCwgcmFuZEJpdHMsIGlzUHJvYmFibHlQcmltZSB9IGZyb20gJ2JpZ2ludC1jcnlwdG8tdXRpbHMnO1xuaW1wb3J0IHsgbW9kSW52LCBtb2RQb3cgfSBmcm9tICdiaWdpbnQtbW9kLWFyaXRoJztcbmltcG9ydCB7IGJpZ0ludEZyb21CdWZmZXJCRSwgYmlnSW50VG9CdWZmZXJCRSB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgRGVzZXJpYWxpemVkUGFpbGxpZXJCbHVtUHJvb2YgfSBmcm9tICcuL3R5cGVzJztcblxuLy8gU2VjdXJpdHkgcGFyYW1ldGVyLlxuY29uc3QgbSA9IDgwO1xuXG4vKipcbiAqIEdlbmVyYXRlIHBzdWVkby1yYW5kb20gcXVhZHJhdGljIHJlc2lkdWUgZm9yIChOLCB3LCBpKS5cbiAqIEBwYXJhbSBOIC0gdGhlIHByaW1lIG51bWJlciB0byB2ZXJpZnkgaXMgYSBwcm9kdWN0IG9mIHR3byBsYXJnZSBwcmltZXMuXG4gKiBAcGFyYW0gdyAtIGEgcmFuZG9tIG51bWJlciB3aXRoIHRoZSBzYW1lIGJpdExlbmd0aCBhcyBOLCB0aGF0IHNhdGlzZmllcyB0aGUgSmFjb2JpIG9mIHcgaXMgLTEgd3J0IE4uXG4gKiBAcmV0dXJucyB7YmlnaW50W119IC0gc2V0IG9mIGNoYWxsZW5nZXMgZm9yIE5cbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVZKE4sIHcpOiBiaWdpbnRbXSB7XG4gIGNvbnN0IE5CdWYgPSBiaWdJbnRUb0J1ZmZlckJFKE4pO1xuICBjb25zdCB3QnVmID0gYmlnSW50VG9CdWZmZXJCRSh3LCBOQnVmLmxlbmd0aCk7XG4gIHJldHVybiBBcnJheShtKVxuICAgIC5maWxsKG51bGwpXG4gICAgLm1hcCgoXywgaSkgPT4ge1xuICAgICAgY29uc3QgaCA9IGJpZ0ludEZyb21CdWZmZXJCRShcbiAgICAgICAgY3JlYXRlSG1hYygnc2hhMjU2JywgQnVmZmVyLmZyb20oW2ldKSlcbiAgICAgICAgICAudXBkYXRlKE5CdWYpXG4gICAgICAgICAgLnVwZGF0ZSh3QnVmKVxuICAgICAgICAgIC5kaWdlc3QoKVxuICAgICAgKTtcbiAgICAgIHJldHVybiBoICogaDtcbiAgICB9KTtcbn1cblxuLy8gaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSmFjb2JpX3N5bWJvbCNJbXBsZW1lbnRhdGlvbl9pbl9DKytcbmZ1bmN0aW9uIGphY29iaShhLCBuKTogYmlnaW50IHtcbiAgLy8gYS9uIGlzIHJlcHJlc2VudGVkIGFzIChhLG4pXG4gIGlmIChuIDw9IEJpZ0ludCgwKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignbiBtdXN0IGdyZWF0ZXIgdGhhbiAwJyk7XG4gIH1cbiAgaWYgKG4gJSBCaWdJbnQoMikgIT09IEJpZ0ludCgxKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignbiBtdXN0IGJlIG9kZCcpO1xuICB9XG4gIC8vIHN0ZXAgMVxuICBhID0gYSAlIG47XG4gIGxldCB0ID0gQmlnSW50KDEpO1xuICBsZXQgcjtcbiAgLy8gc3RlcCAzXG4gIHdoaWxlIChhICE9PSBCaWdJbnQoMCkpIHtcbiAgICAvLyBzdGVwIDJcbiAgICB3aGlsZSAoYSAlIEJpZ0ludCgyKSA9PT0gQmlnSW50KDApKSB7XG4gICAgICBhIC89IEJpZ0ludCgyKTtcbiAgICAgIHIgPSBuICUgQmlnSW50KDgpO1xuICAgICAgaWYgKHIgPT09IEJpZ0ludCgzKSB8fCByID09PSBCaWdJbnQoNSkpIHtcbiAgICAgICAgdCA9IC10O1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBzdGVwIDRcbiAgICByID0gbjtcbiAgICBuID0gYTtcbiAgICBhID0gcjtcbiAgICBpZiAoYSAlIEJpZ0ludCg0KSA9PT0gQmlnSW50KDMpICYmIG4gJSBCaWdJbnQoNCkgPT09IEJpZ0ludCgzKSkge1xuICAgICAgdCA9IC10O1xuICAgIH1cbiAgICBhID0gYSAlIG47XG4gIH1cbiAgaWYgKG4gPT09IEJpZ0ludCgxKSkge1xuICAgIHJldHVybiB0O1xuICB9XG4gIHJldHVybiBCaWdJbnQoMCk7XG59XG5cbi8qKlxuICogUHJvdmUgdGhhdCBhIG1vZHVsdXMgKHAqcSkgaXMgdGhlIHByb2R1Y3Qgb2YgdHdvIGxhcmdlIHNhZmUgcHJpbWVzIChwIGFuZCBxKS5cbiAqIEBwYXJhbSB7YmlnaW50fSBwIFRoZSBsYXJnZXIgcHJpbWUgZmFjdG9yIG9mIHRoZSBtb2R1bHVzXG4gKiBAcGFyYW0ge2JpZ2ludH0gcSBUaGUgc21hbGxlciBwcmltZSBmYWN0b3Igb2YgdGhlIG1vZHVsdXMuXG4gKiBAcmV0dXJucyB7RGVzZXJpYWxpemVkUGFpbGxpZXJCbHVtUHJvb2Z9IFRoZSBwcm9vZiB0aGF0IHRoZSBtb2R1bHVzIGlzIHRoZSBwcm9kdWN0IG9mIHR3byBsYXJnZSBwcmltZXMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwcm92ZShwOiBiaWdpbnQsIHE6IGJpZ2ludCk6IFByb21pc2U8RGVzZXJpYWxpemVkUGFpbGxpZXJCbHVtUHJvb2Y+IHtcbiAgLy8gUHJvdmVyIHNlbGVjdHMgcmFuZG9tIHcgd2l0aCBKYWNvYmkgc3ltYm9sIDEgd3J0IE4uXG4gIGNvbnN0IE4gPSBwICogcTtcbiAgY29uc3QgbCA9IChwIC0gQmlnSW50KDEpKSAqIChxIC0gQmlnSW50KDEpKTtcbiAgY29uc3QgZCA9IG1vZEludihOLCBsKTtcbiAgbGV0IHc7XG4gIHdoaWxlICh0cnVlKSB7XG4gICAgdyA9IGJpZ0ludEZyb21CdWZmZXJCRShCdWZmZXIuZnJvbShhd2FpdCByYW5kQml0cyhiaXRMZW5ndGgoTikpKSk7XG4gICAgaWYgKGphY29iaSh3LCBOKSA9PT0gQmlnSW50KC0xKSkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIC8vIFRoaXMgaXMgY2FsY3VsYXRpbmcgdGhlIGludmVyc2Ugb2YgdGhlIGZ1bmN0aW9uIHleNCBtb2QgTixcbiAgLy8gaS5lLnkgXiAoMSAvIDQpLCB3aGVyZSBOID0gcHEgaXMgYSBibHVtIGludGVnZXIgdXNpbmcgSE9DIC0gRmFjdCAyLjE2MFxuICAvLyBmcm9tIGNhY3IudXdhdGVybG9vLmNhIC8gaGFjIC8gYWJvdXQgLyBjaGFwMi5wZGZcbiAgLy8gUHJvdmVyIGdlbmVyYXRlcyB5X2kuXG4gIGNvbnN0IHkgPSBnZW5lcmF0ZVkoTiwgdyk7XG4gIC8vIFByb3ZlciBjYWxjdWxhdGVzIHpfaSA9IHlfaSBeIGQgbW9kIE5cbiAgY29uc3QgeiA9IHkubWFwKCh5X2kpID0+IG1vZFBvdyh5X2ksIGQsIE4pKTtcbiAgLy8gUHJvdmVyIGNhbGN1bGF0ZXMgeF9pID0geV9pIF4gMS80IG1vZCBOIHVzaW5nIFtIT0MgLSBGYWN0IDIuMTYwXVxuICBjb25zdCBlID0gKChsICsgQmlnSW50KDQpKSAvIEJpZ0ludCg4KSkgKiogQmlnSW50KDIpO1xuICBjb25zdCB4ID0geS5tYXAoKHlfaSkgPT4gbW9kUG93KHlfaSwgZSwgTikpO1xuICByZXR1cm4geyB3LCB4LCB6IH07XG59XG5cbi8qKlxuICogVmVyaWZ5IHRoYXQgTiBpcyB0aGUgcHJvZHVjdCBvZiB0d28gbGFyZ2UgcHJpbWVzLlxuICogQHBhcmFtIHtiaWdpbnR9IE4gVGhlIHByaW1lIG51bWJlciBiZWluZyB2ZXJpZmllZC5cbiAqIEBwYXJhbSB7RGVzZXJpYWxpemVkUGFpbGxpZXJCbHVtUHJvb2Z9IFRoZSBwcm9vZiB0byB2ZXJpZnkgTiBpcyBhIHByb2R1Y3Qgb2YgdHdvIGxhcmdlIHByaW1lcy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIE4gaXMgYSBwcm9kdWN0IG9mIHR3byBsYXJnZSBwcmltZXMsIGFuZCBmYWxzZSBvdGhlcndpc2UuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB2ZXJpZnkoTjogYmlnaW50LCB7IHcsIHgsIHogfTogRGVzZXJpYWxpemVkUGFpbGxpZXJCbHVtUHJvb2YpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgLy8gVmVyaWZpZXIgY2hlY2tzIE4gPiAxLlxuICBpZiAoTiA8PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdOIG11c3QgYmUgZ3JlYXRlciB0aGFuIDEnKTtcbiAgfVxuICAvLyBWZXJpZmllciBjaGVja3MgTiBpcyBvZGQuXG4gIGlmIChOICUgQmlnSW50KDIpICE9PSBCaWdJbnQoMSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ04gbXVzdCBiZSBhbiBvZGQgbnVtYmVyJyk7XG4gIH1cbiAgLy8gVmVyaWZpZXIgY2hlY2tzIE4gaXMgbm90IHByaW1lLlxuICBpZiAoYXdhaXQgaXNQcm9iYWJseVByaW1lKE4sIDI0KSkge1xuICAgIHRocm93IG5ldyBFcnJvcignTiBtdXN0IGJlIGEgY29tcG9zaXRlIG51bWJlcicpO1xuICB9XG4gIC8vIFZlcmlmaWVyIGNoZWNrcyB0aGF0IHRoZSBKYWNvYmkgc3ltYm9sIGZvciB3IGlzIDEgd3J0IE4uXG4gIGlmIChqYWNvYmkodywgTikgIT09IEJpZ0ludCgtMSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0phY29iaSBzeW1ib2wgb2YgdyBtdXN0IGJlIC0xIHdydCB0byBOJyk7XG4gIH1cbiAgLy8gVmVyaWZpZXIgZ2VuZXJhdGVzIHlfaS5cbiAgY29uc3QgeSA9IGdlbmVyYXRlWShOLCB3KTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBtOyBpKyspIHtcbiAgICAvLyBWZXJpZmllciBjaGVja3Mgel9pIF4gTiBtb2QgTiA9PSB5X2kuXG4gICAgaWYgKG1vZFBvdyh6W2ldLCBOLCBOKSAhPT0geVtpXSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBQYWlsbGllciB2ZXJpZmljYXRpb24gb2Ygelske2l9XSBmYWlsZWRgKTtcbiAgICB9XG4gICAgLy8gVmVyaWZpZXIgY2hlY2tzIHhfaSBeIDQgbW9kIE4gPT0geV9pLlxuICAgIGlmIChtb2RQb3coeFtpXSwgNCwgTikgIT09IHlbaV0pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgUGFpbGxpZXIgdmVyaWZpY2F0aW9uIG9mIHhbJHtpfV0gZmFpbGVkYCk7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuIl19