@bitgo-beta/sdk-lib-mpc 8.2.1-alpha.36 → 8.2.1-alpha.38

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.
@@ -1,157 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.verify = exports.prove = void 0;
4
- /**
5
- * Implementation of No Small Factors ($\Pi^\text{fac}).
6
- * https://eprint.iacr.org/2020/492.pdf Section B.4
7
- */
8
- const crypto_1 = require("crypto");
9
- const bigint_crypto_utils_1 = require("bigint-crypto-utils");
10
- const bigint_mod_arith_1 = require("bigint-mod-arith");
11
- const util_1 = require("../../util");
12
- const ORDER = BigInt('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141');
13
- const ELL = BigInt(256);
14
- const EPSILON = BigInt(BigInt(2) * ELL);
15
- function hash(N, w, nonce) {
16
- // NOTE: there's a bug in node type file for crypto that prevents us from using Hash.copy({ outputLength: ... })
17
- // outputLength must be specified on the copy() for a shake256 hash to behave correctly.
18
- return crypto_1.createHash('shake256', { outputLength: 1 + Math.floor((bigint_crypto_utils_1.bitLength(ORDER) + 7) / 8) })
19
- .update(util_1.bigIntToBufferBE(N))
20
- .update('$')
21
- .update(util_1.bigIntToBufferBE(w))
22
- .update('$')
23
- .update(nonce)
24
- .digest();
25
- }
26
- /**
27
- * Generate pseudo-random challenge value $e$ and associated $nonce$ for $(N, w)$.
28
- * @param N - the prime number to verify is a product of two large primes.
29
- * @param w - a random number with the same bitLength as N, that satisfies the Jacobi of w is -1 wrt N.
30
- * @returns {nonce, e} - challenge value $e$ and associated $nonce$ that makes $e$ uniformly random from $(-order, order)$.
31
- */
32
- function generateEforProve(N, w) {
33
- let nonce, e, digest;
34
- do {
35
- nonce = crypto_1.randomBytes(33);
36
- digest = hash(N, w, nonce);
37
- e = util_1.bigIntFromBufferBE(digest.subarray(1));
38
- } while (e >= ORDER);
39
- if (digest[0] & 1) {
40
- return { nonce, e: -e };
41
- }
42
- return { nonce, e };
43
- }
44
- /**
45
- * Generate pseudo-random challenge value $e$ for $(N, w)$ and associated $nonce$.
46
- * @param N - the prime number to verify is a product of two large primes.
47
- * @param w - a random number with the same bitLength as N, that satisfies the Jacobi of w is -1 wrt N.
48
- * @param nonce - a random nonce.
49
- * @returns {bigint} - challenge value $e$.
50
- */
51
- function generateEforVerify(N, w, nonce) {
52
- const digest = hash(N, w, nonce);
53
- const e = util_1.bigIntFromBufferBE(digest.subarray(1));
54
- if (digest[0] & 1) {
55
- return -e;
56
- }
57
- return e;
58
- }
59
- /**
60
- * Calculate the closest integer square root of $n$.
61
- * @param n - the number to calculate the square root of.
62
- * @returns {bigint} - $n$'s closest integer square root.
63
- */
64
- function isqrt(n) {
65
- if (n < BigInt(0)) {
66
- throw new Error();
67
- }
68
- if (n < BigInt(2)) {
69
- return n;
70
- }
71
- function newtonIteration(n, x0) {
72
- const x1 = (n / x0 + x0) >> BigInt(1);
73
- if (x0 === x1 || x0 === x1 - BigInt(1)) {
74
- return x0;
75
- }
76
- return newtonIteration(n, x1);
77
- }
78
- return newtonIteration(n, BigInt(1));
79
- }
80
- /**
81
- * Prove that $n0$ has no small factors, where $n0$ is the product of two large primes.
82
- * @param p - a large prime.
83
- * @param q - a large prime.
84
- * @param w - a random number with the same bitLength as $p * q$, that satisfies the Jacobi of w is -1 wrt $n0$.
85
- * @param nHat - a safe bi-prime, such as that returned from rangeProof.generateNTilde.
86
- * @param s - security parameters for $nHat$ such as the $h1$ value returned from rangeProof.generateNTilde.
87
- * @param t - security parameters for $nHat$ such as the $h2$ value returned from rangeProof.generateNTilde.
88
- * @returns proof that the product of $p * q$ has no small factors.
89
- */
90
- function prove(p, q, w, nHat, s, t) {
91
- const n0 = p * q;
92
- const { nonce, e } = generateEforProve(n0, w);
93
- const sqrtN0 = isqrt(n0);
94
- const alpha = bigint_crypto_utils_1.randBetween(sqrtN0 << (ELL + EPSILON), -sqrtN0 << (ELL + EPSILON));
95
- const beta = bigint_crypto_utils_1.randBetween(sqrtN0 << (ELL + EPSILON), -sqrtN0 << (ELL + EPSILON));
96
- const rho = bigint_crypto_utils_1.randBetween((nHat * n0) << ELL, -(nHat * n0) << ELL);
97
- // Commit to p.
98
- const mu = bigint_crypto_utils_1.randBetween(BigInt(1) << ELL, BigInt(-1) << ELL);
99
- const P = (bigint_mod_arith_1.modPow(s, p, nHat) * bigint_mod_arith_1.modPow(t, mu, nHat)) % nHat;
100
- // Commit to q.
101
- const nu = bigint_crypto_utils_1.randBetween(BigInt(1) << ELL, BigInt(-1) << ELL);
102
- const Q = (bigint_mod_arith_1.modPow(s, q, nHat) * bigint_mod_arith_1.modPow(t, nu, nHat)) % nHat;
103
- // Commit to alpha.
104
- const x = bigint_crypto_utils_1.randBetween(BigInt(1) << (ELL + EPSILON), BigInt(-1) << (ELL + EPSILON));
105
- const A = (bigint_mod_arith_1.modPow(s, alpha, nHat) * bigint_mod_arith_1.modPow(t, x, nHat)) % nHat;
106
- // Commit to beta.
107
- const y = bigint_crypto_utils_1.randBetween(BigInt(1) << (ELL + EPSILON), BigInt(-1) << (ELL + EPSILON));
108
- const B = (bigint_mod_arith_1.modPow(s, beta, nHat) * bigint_mod_arith_1.modPow(t, y, nHat)) % nHat;
109
- // Commit to Q and alpha.
110
- const r = bigint_crypto_utils_1.randBetween((nHat * n0) << (ELL + EPSILON), -(nHat * n0) << (ELL + EPSILON));
111
- const T = (bigint_mod_arith_1.modPow(Q, alpha, nHat) * bigint_mod_arith_1.modPow(t, r, nHat)) % nHat;
112
- const rhoHat = rho - nu * p;
113
- const z1 = alpha + e * p;
114
- const z2 = beta + e * q;
115
- const w1 = x + e * mu;
116
- const w2 = y + e * nu;
117
- const v = r + e * rhoHat;
118
- return { P, Q, A, B, T, rho, z1, z2, w1, w2, v, nonce: util_1.bigIntFromBufferBE(nonce) };
119
- }
120
- exports.prove = prove;
121
- /**
122
- * Verify that $n0$ is not the product of any small factors.
123
- * @param n0 - a modulus that is the product of $p$ and $q$.
124
- * @param w - a random number with the same bitLength as $n0$, that satisfies the Jacobi of w is -1 wrt $n0$.
125
- * @param nHat - a safe bi-prime, such as that returned from rangeProof.generateNTilde.
126
- * @param s - security parameters for $nHat$ such as the $h1$ value returned from rangeProof.generateNTilde.
127
- * @param t - security parameters for $nHat$ such as the $h2$ value returned from rangeProof.generateNTilde.
128
- * @param proof - a proof generated by noSmallFactors.prove.
129
- * @returns true if verification successful.
130
- */
131
- function verify(n0, w, nHat, s, t, proof) {
132
- const { P, Q, A, B, T, rho, z1, z2, w1, w2, v, nonce } = proof;
133
- const e = generateEforVerify(n0, w, util_1.bigIntToBufferBE(nonce, 33));
134
- if (e < -ORDER || e > ORDER) {
135
- throw new Error('Could not verify no small factors proof');
136
- }
137
- const sqrtN0 = isqrt(n0);
138
- const R = (bigint_mod_arith_1.modPow(s, n0, nHat) * bigint_mod_arith_1.modPow(t, rho, nHat)) % nHat;
139
- if ((bigint_mod_arith_1.modPow(s, z1, nHat) * bigint_mod_arith_1.modPow(t, w1, nHat)) % nHat !== (A * bigint_mod_arith_1.modPow(P, e, nHat)) % nHat) {
140
- throw new Error('Could not verify no small factors proof');
141
- }
142
- if ((bigint_mod_arith_1.modPow(s, z2, nHat) * bigint_mod_arith_1.modPow(t, w2, nHat)) % nHat !== (B * bigint_mod_arith_1.modPow(Q, e, nHat)) % nHat) {
143
- throw new Error('Could not verify no small factors proof');
144
- }
145
- if ((bigint_mod_arith_1.modPow(Q, z1, nHat) * bigint_mod_arith_1.modPow(t, v, nHat)) % nHat !== (T * bigint_mod_arith_1.modPow(R, e, nHat)) % nHat) {
146
- throw new Error('Could not verify no small factors proof');
147
- }
148
- if (z1 < -sqrtN0 << (ELL + EPSILON) || z1 > sqrtN0 << (ELL + EPSILON)) {
149
- throw new Error('Could not verify no small factors proof');
150
- }
151
- if (z2 < -sqrtN0 << (ELL + EPSILON) || z2 > sqrtN0 << (ELL + EPSILON)) {
152
- throw new Error('Could not verify no small factors proof');
153
- }
154
- return true;
155
- }
156
- exports.verify = verify;
157
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9TbWFsbEZhY3RvcnNQcm9vZi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy90c3MvZWNkc2Evbm9TbWFsbEZhY3RvcnNQcm9vZi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQTs7O0dBR0c7QUFDSCxtQ0FBaUQ7QUFDakQsNkRBQTZEO0FBQzdELHVEQUEwQztBQUMxQyxxQ0FBa0U7QUFHbEUsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLG9FQUFvRSxDQUFDLENBQUM7QUFDM0YsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3hCLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7QUFFeEMsU0FBUyxJQUFJLENBQUMsQ0FBUyxFQUFFLENBQVMsRUFBRSxLQUFhO0lBQy9DLGdIQUFnSDtJQUNoSCw4RkFBOEY7SUFDOUYsT0FBTyxtQkFBVSxDQUFDLFVBQVUsRUFBRSxFQUFFLFlBQVksRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLCtCQUFTLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztTQUN4RixNQUFNLENBQUMsdUJBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDM0IsTUFBTSxDQUFDLEdBQUcsQ0FBQztTQUNYLE1BQU0sQ0FBQyx1QkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUMzQixNQUFNLENBQUMsR0FBRyxDQUFDO1NBQ1gsTUFBTSxDQUFDLEtBQUssQ0FBQztTQUNiLE1BQU0sRUFBRSxDQUFDO0FBQ2QsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBUyxpQkFBaUIsQ0FBQyxDQUFTLEVBQUUsQ0FBUztJQUM3QyxJQUFJLEtBQWEsRUFBRSxDQUFTLEVBQUUsTUFBYyxDQUFDO0lBQzdDLEdBQUc7UUFDRCxLQUFLLEdB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SyxDQUFDLHlDQUF5QyxDQUFDLENBQUM7S0FDNUQ7SUFDRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUEvQkQsd0JBK0JDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBJbXBsZW1lbnRhdGlvbiBvZiBObyBTbWFsbCBGYWN0b3JzICgkXFxQaV5cXHRleHR7ZmFjfSkuXG4gKiBodHRwczovL2VwcmludC5pYWNyLm9yZy8yMDIwLzQ5Mi5wZGYgU2VjdGlvbiBCLjRcbiAqL1xuaW1wb3J0IHsgY3JlYXRlSGFzaCwgcmFuZG9tQnl0ZXMgfSBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IHsgYml0TGVuZ3RoLCByYW5kQmV0d2VlbiB9IGZyb20gJ2JpZ2ludC1jcnlwdG8tdXRpbHMnO1xuaW1wb3J0IHsgbW9kUG93IH0gZnJvbSAnYmlnaW50LW1vZC1hcml0aCc7XG5pbXBvcnQgeyBiaWdJbnRGcm9tQnVmZmVyQkUsIGJpZ0ludFRvQnVmZmVyQkUgfSBmcm9tICcuLi8uLi91dGlsJztcbmltcG9ydCB7IERlc2VyaWFsaXplZE5vU21hbGxGYWN0b3JzUHJvb2YgfSBmcm9tICcuL3R5cGVzJztcblxuY29uc3QgT1JERVIgPSBCaWdJbnQoJzB4ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmViYWFlZGNlNmFmNDhhMDNiYmZkMjVlOGNkMDM2NDE0MScpO1xuY29uc3QgRUxMID0gQmlnSW50KDI1Nik7XG5jb25zdCBFUFNJTE9OID0gQmlnSW50KEJpZ0ludCgyKSAqIEVMTCk7XG5cbmZ1bmN0aW9uIGhhc2goTjogYmlnaW50LCB3OiBiaWdpbnQsIG5vbmNlOiBCdWZmZXIpOiBCdWZmZXIge1xuICAvLyBOT1RFOiB0aGVyZSdzIGEgYnVnIGluIG5vZGUgdHlwZSBmaWxlIGZvciBjcnlwdG8gdGhhdCBwcmV2ZW50cyB1cyBmcm9tIHVzaW5nIEhhc2guY29weSh7IG91dHB1dExlbmd0aDogLi4uIH0pXG4gIC8vICAgICAgIG91dHB1dExlbmd0aCBtdXN0IGJlIHNwZWNpZmllZCBvbiB0aGUgY29weSgpIGZvciBhIHNoYWtlMjU2IGhhc2ggdG8gYmVoYXZlIGNvcnJlY3RseS5cbiAgcmV0dXJuIGNyZWF0ZUhhc2goJ3NoYWtlMjU2JywgeyBvdXRwdXRMZW5ndGg6IDEgKyBNYXRoLmZsb29yKChiaXRMZW5ndGgoT1JERVIpICsgNykgLyA4KSB9KVxuICAgIC51cGRhdGUoYmlnSW50VG9CdWZmZXJCRShOKSlcbiAgICAudXBkYXRlKCckJylcbiAgICAudXBkYXRlKGJpZ0ludFRvQnVmZmVyQkUodykpXG4gICAgLnVwZGF0ZSgnJCcpXG4gICAgLnVwZGF0ZShub25jZSlcbiAgICAuZGlnZXN0KCk7XG59XG5cbi8qKlxuICogR2VuZXJhdGUgcHNldWRvLXJhbmRvbSBjaGFsbGVuZ2UgdmFsdWUgJGUkIGFuZCBhc3NvY2lhdGVkICRub25jZSQgZm9yICQoTiwgdykkLlxuICogQHBhcmFtIE4gLSB0aGUgcHJpbWUgbnVtYmVyIHRvIHZlcmlmeSBpcyBhIHByb2R1Y3Qgb2YgdHdvIGxhcmdlIHByaW1lcy5cbiAqIEBwYXJhbSB3IC0gYSByYW5kb20gbnVtYmVyIHdpdGggdGhlIHNhbWUgYml0TGVuZ3RoIGFzIE4sIHRoYXQgc2F0aXNmaWVzIHRoZSBKYWNvYmkgb2YgdyBpcyAtMSB3cnQgTi5cbiAqIEByZXR1cm5zIHtub25jZSwgZX0gLSBjaGFsbGVuZ2UgdmFsdWUgJGUkIGFuZCBhc3NvY2lhdGVkICRub25jZSQgdGhhdCBtYWtlcyAkZSQgdW5pZm9ybWx5IHJhbmRvbSBmcm9tICQoLW9yZGVyLCBvcmRlcikkLlxuICovXG5mdW5jdGlvbiBnZW5lcmF0ZUVmb3JQcm92ZShOOiBiaWdpbnQsIHc6IGJpZ2ludCk6IHsgbm9uY2U6IEJ1ZmZlcjsgZTogYmlnaW50IH0ge1xuICBsZXQgbm9uY2U6IEJ1ZmZlciwgZTogYmlnaW50LCBkaWdlc3Q6IEJ1ZmZlcjtcbiAgZG8ge1xuICAgIG5vbmNlID0gcmFuZG9tQnl0ZXMoMzMpO1xuICAgIGRpZ2VzdCA9IGhhc2goTiwgdywgbm9uY2UpO1xuICAgIGUgPSBiaWdJbnRGcm9tQnVmZmVyQkUoZGlnZXN0LnN1YmFycmF5KDEpKTtcbiAgfSB3aGlsZSAoZSA+PSBPUkRFUik7XG4gIGlmIChkaWdlc3RbMF0gJiAxKSB7XG4gICAgcmV0dXJuIHsgbm9uY2UsIGU6IC1lIH07XG4gIH1cbiAgcmV0dXJuIHsgbm9uY2UsIGUgfTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBwc2V1ZG8tcmFuZG9tIGNoYWxsZW5nZSB2YWx1ZSAkZSQgZm9yICQoTiwgdykkIGFuZCBhc3NvY2lhdGVkICRub25jZSQuXG4gKiBAcGFyYW0gTiAtIHRoZSBwcmltZSBudW1iZXIgdG8gdmVyaWZ5IGlzIGEgcHJvZHVjdCBvZiB0d28gbGFyZ2UgcHJpbWVzLlxuICogQHBhcmFtIHcgLSBhIHJhbmRvbSBudW1iZXIgd2l0aCB0aGUgc2FtZSBiaXRMZW5ndGggYXMgTiwgdGhhdCBzYXRpc2ZpZXMgdGhlIEphY29iaSBvZiB3IGlzIC0xIHdydCBOLlxuICogQHBhcmFtIG5vbmNlIC0gYSByYW5kb20gbm9uY2UuXG4gKiBAcmV0dXJucyB7YmlnaW50fSAtIGNoYWxsZW5nZSB2YWx1ZSAkZSQuXG4gKi9cbmZ1bmN0aW9uIGdlbmVyYXRlRWZvclZlcmlmeShOOiBiaWdpbnQsIHc6IGJpZ2ludCwgbm9uY2U6IEJ1ZmZlcik6IGJpZ2ludCB7XG4gIGNvbnN0IGRpZ2VzdCA9IGhhc2goTiwgdywgbm9uY2UpO1xuICBjb25zdCBlID0gYmlnSW50RnJvbUJ1ZmZlckJFKGRpZ2VzdC5zdWJhcnJheSgxKSk7XG4gIGlmIChkaWdlc3RbMF0gJiAxKSB7XG4gICAgcmV0dXJuIC1lO1xuICB9XG4gIHJldHVybiBlO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSB0aGUgY2xvc2VzdCBpbnRlZ2VyIHNxdWFyZSByb290IG9mICRuJC5cbiAqIEBwYXJhbSBuIC0gdGhlIG51bWJlciB0byBjYWxjdWxhdGUgdGhlIHNxdWFyZSByb290IG9mLlxuICogQHJldHVybnMge2JpZ2ludH0gLSAkbiQncyBjbG9zZXN0IGludGVnZXIgc3F1YXJlIHJvb3QuXG4gKi9cbmZ1bmN0aW9uIGlzcXJ0KG46IGJpZ2ludCk6IGJpZ2ludCB7XG4gIGlmIChuIDwgQmlnSW50KDApKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCk7XG4gIH1cbiAgaWYgKG4gPCBCaWdJbnQoMikpIHtcbiAgICByZXR1cm4gbjtcbiAgfVxuICBmdW5jdGlvbiBuZXd0b25JdGVyYXRpb24objogYmlnaW50LCB4MDogYmlnaW50KSB7XG4gICAgY29uc3QgeDEgPSAobiAvIHgwICsgeDApID4+IEJpZ0ludCgxKTtcbiAgICBpZiAoeDAgPT09IHgxIHx8IHgwID09PSB4MSAtIEJpZ0ludCgxKSkge1xuICAgICAgcmV0dXJuIHgwO1xuICAgIH1cbiAgICByZXR1cm4gbmV3dG9uSXRlcmF0aW9uKG4sIHgxKTtcbiAgfVxuICByZXR1cm4gbmV3dG9uSXRlcmF0aW9uKG4sIEJpZ0ludCgxKSk7XG59XG5cbi8qKlxuICogUHJvdmUgdGhhdCAkbjAkIGhhcyBubyBzbWFsbCBmYWN0b3JzLCB3aGVyZSAkbjAkIGlzIHRoZSBwcm9kdWN0IG9mIHR3byBsYXJnZSBwcmltZXMuXG4gKiBAcGFyYW0gcCAtIGEgbGFyZ2UgcHJpbWUuXG4gKiBAcGFyYW0gcSAtIGEgbGFyZ2UgcHJpbWUuXG4gKiBAcGFyYW0gdyAtIGEgcmFuZG9tIG51bWJlciB3aXRoIHRoZSBzYW1lIGJpdExlbmd0aCBhcyAkcCAqIHEkLCB0aGF0IHNhdGlzZmllcyB0aGUgSmFjb2JpIG9mIHcgaXMgLTEgd3J0ICRuMCQuXG4gKiBAcGFyYW0gbkhhdCAtIGEgc2FmZSBiaS1wcmltZSwgc3VjaCBhcyB0aGF0IHJldHVybmVkIGZyb20gcmFuZ2VQcm9vZi5nZW5lcmF0ZU5UaWxkZS5cbiAqIEBwYXJhbSBzIC0gc2VjdXJpdHkgcGFyYW1ldGVycyBmb3IgJG5IYXQkIHN1Y2ggYXMgdGhlICRoMSQgdmFsdWUgcmV0dXJuZWQgZnJvbSByYW5nZVByb29mLmdlbmVyYXRlTlRpbGRlLlxuICogQHBhcmFtIHQgLSBzZWN1cml0eSBwYXJhbWV0ZXJzIGZvciAkbkhhdCQgc3VjaCBhcyB0aGUgJGgyJCB2YWx1ZSByZXR1cm5lZCBmcm9tIHJhbmdlUHJvb2YuZ2VuZXJhdGVOVGlsZGUuXG4gKiBAcmV0dXJucyBwcm9vZiB0aGF0IHRoZSBwcm9kdWN0IG9mICRwICogcSQgaGFzIG5vIHNtYWxsIGZhY3RvcnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcm92ZShcbiAgcDogYmlnaW50LFxuICBxOiBiaWdpbnQsXG4gIHc6IGJpZ2ludCxcbiAgbkhhdDogYmlnaW50LFxuICBzOiBiaWdpbnQsXG4gIHQ6IGJpZ2ludFxuKTogRGVzZXJpYWxpemVkTm9TbWFsbEZhY3RvcnNQcm9vZiB7XG4gIGNvbnN0IG4wID0gcCAqIHE7XG4gIGNvbnN0IHsgbm9uY2UsIGUgfSA9IGdlbmVyYXRlRWZvclByb3ZlKG4wLCB3KTtcbiAgY29uc3Qgc3FydE4wID0gaXNxcnQobjApO1xuICBjb25zdCBhbHBoYSA9IHJhbmRCZXR3ZWVuKHNxcnROMCA8PCAoRUxMICsgRVBTSUxPTiksIC1zcXJ0TjAgPDwgKEVMTCArIEVQU0lMT04pKTtcbiAgY29uc3QgYmV0YSA9IHJhbmRCZXR3ZWVuKHNxcnROMCA8PCAoRUxMICsgRVBTSUxPTiksIC1zcXJ0TjAgPDwgKEVMTCArIEVQU0lMT04pKTtcbiAgY29uc3QgcmhvID0gcmFuZEJldHdlZW4oKG5IYXQgKiBuMCkgPDwgRUxMLCAtKG5IYXQgKiBuMCkgPDwgRUxMKTtcbiAgLy8gQ29tbWl0IHRvIHAuXG4gIGNvbnN0IG11ID0gcmFuZEJldHdlZW4oQmlnSW50KDEpIDw8IEVMTCwgQmlnSW50KC0xKSA8PCBFTEwpO1xuICBjb25zdCBQID0gKG1vZFBvdyhzLCBwLCBuSGF0KSAqIG1vZFBvdyh0LCBtdSwgbkhhdCkpICUgbkhhdDtcbiAgLy8gQ29tbWl0IHRvIHEuXG4gIGNvbnN0IG51ID0gcmFuZEJldHdlZW4oQmlnSW50KDEpIDw8IEVMTCwgQmlnSW50KC0xKSA8PCBFTEwpO1xuICBjb25zdCBRID0gKG1vZFBvdyhzLCBxLCBuSGF0KSAqIG1vZFBvdyh0LCBudSwgbkhhdCkpICUgbkhhdDtcbiAgLy8gQ29tbWl0IHRvIGFscGhhLlxuICBjb25zdCB4ID0gcmFuZEJldHdlZW4oQmlnSW50KDEpIDw8IChFTEwgKyBFUFNJTE9OKSwgQmlnSW50KC0xKSA8PCAoRUxMICsgRVBTSUxPTikpO1xuICBjb25zdCBBID0gKG1vZFBvdyhzLCBhbHBoYSwgbkhhdCkgKiBtb2RQb3codCwgeCwgbkhhdCkpICUgbkhhdDtcbiAgLy8gQ29tbWl0IHRvIGJldGEuXG4gIGNvbnN0IHkgPSByYW5kQmV0d2VlbihCaWdJbnQoMSkgPDwgKEVMTCArIEVQU0lMT04pLCBCaWdJbnQoLTEpIDw8IChFTEwgKyBFUFNJTE9OKSk7XG4gIGNvbnN0IEIgPSAobW9kUG93KHMsIGJldGEsIG5IYXQpICogbW9kUG93KHQsIHksIG5IYXQpKSAlIG5IYXQ7XG4gIC8vIENvbW1pdCB0byBRIGFuZCBhbHBoYS5cbiAgY29uc3QgciA9IHJhbmRCZXR3ZWVuKChuSGF0ICogbjApIDw8IChFTEwgKyBFUFNJTE9OKSwgLShuSGF0ICogbjApIDw8IChFTEwgKyBFUFNJTE9OKSk7XG4gIGNvbnN0IFQgPSAobW9kUG93KFEsIGFscGhhLCBuSGF0KSAqIG1vZFBvdyh0LCByLCBuSGF0KSkgJSBuSGF0O1xuXG4gIGNvbnN0IHJob0hhdCA9IHJobyAtIG51ICogcDtcbiAgY29uc3QgejEgPSBhbHBoYSArIGUgKiBwO1xuICBjb25zdCB6MiA9IGJldGEgKyBlICogcTtcbiAgY29uc3QgdzEgPSB4ICsgZSAqIG11O1xuICBjb25zdCB3MiA9IHkgKyBlICogbnU7XG4gIGNvbnN0IHYgPSByICsgZSAqIHJob0hhdDtcblxuICByZXR1cm4geyBQLCBRLCBBLCBCLCBULCByaG8sIHoxLCB6MiwgdzEsIHcyLCB2LCBub25jZTogYmlnSW50RnJvbUJ1ZmZlckJFKG5vbmNlKSB9O1xufVxuXG4vKipcbiAqIFZlcmlmeSB0aGF0ICRuMCQgaXMgbm90IHRoZSBwcm9kdWN0IG9mIGFueSBzbWFsbCBmYWN0b3JzLlxuICogQHBhcmFtIG4wIC0gYSBtb2R1bHVzIHRoYXQgaXMgdGhlIHByb2R1Y3Qgb2YgJHAkIGFuZCAkcSQuXG4gKiBAcGFyYW0gdyAtIGEgcmFuZG9tIG51bWJlciB3aXRoIHRoZSBzYW1lIGJpdExlbmd0aCBhcyAkbjAkLCB0aGF0IHNhdGlzZmllcyB0aGUgSmFjb2JpIG9mIHcgaXMgLTEgd3J0ICRuMCQuXG4gKiBAcGFyYW0gbkhhdCAtIGEgc2FmZSBiaS1wcmltZSwgc3VjaCBhcyB0aGF0IHJldHVybmVkIGZyb20gcmFuZ2VQcm9vZi5nZW5lcmF0ZU5UaWxkZS5cbiAqIEBwYXJhbSBzIC0gc2VjdXJpdHkgcGFyYW1ldGVycyBmb3IgJG5IYXQkIHN1Y2ggYXMgdGhlICRoMSQgdmFsdWUgcmV0dXJuZWQgZnJvbSByYW5nZVByb29mLmdlbmVyYXRlTlRpbGRlLlxuICogQHBhcmFtIHQgLSBzZWN1cml0eSBwYXJhbWV0ZXJzIGZvciAkbkhhdCQgc3VjaCBhcyB0aGUgJGgyJCB2YWx1ZSByZXR1cm5lZCBmcm9tIHJhbmdlUHJvb2YuZ2VuZXJhdGVOVGlsZGUuXG4gKiBAcGFyYW0gcHJvb2YgLSBhIHByb29mIGdlbmVyYXRlZCBieSBub1NtYWxsRmFjdG9ycy5wcm92ZS5cbiAqIEByZXR1cm5zIHRydWUgaWYgdmVyaWZpY2F0aW9uIHN1Y2Nlc3NmdWwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJpZnkoXG4gIG4wOiBiaWdpbnQsXG4gIHc6IGJpZ2ludCxcbiAgbkhhdDogYmlnaW50LFxuICBzOiBiaWdpbnQsXG4gIHQ6IGJpZ2ludCxcbiAgcHJvb2Y6IERlc2VyaWFsaXplZE5vU21hbGxGYWN0b3JzUHJvb2Zcbik6IGJvb2xlYW4ge1xuICBjb25zdCB7IFAsIFEsIEEsIEIsIFQsIHJobywgejEsIHoyLCB3MSwgdzIsIHYsIG5vbmNlIH0gPSBwcm9vZjtcbiAgY29uc3QgZSA9IGdlbmVyYXRlRWZvclZlcmlmeShuMCwgdywgYmlnSW50VG9CdWZmZXJCRShub25jZSwgMzMpKTtcbiAgaWYgKGUgPCAtT1JERVIgfHwgZSA+IE9SREVSKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgdmVyaWZ5IG5vIHNtYWxsIGZhY3RvcnMgcHJvb2YnKTtcbiAgfVxuICBjb25zdCBzcXJ0TjAgPSBpc3FydChuMCk7XG4gIGNvbnN0IFIgPSAobW9kUG93KHMsIG4wLCBuSGF0KSAqIG1vZFBvdyh0LCByaG8sIG5IYXQpKSAlIG5IYXQ7XG4gIGlmICgobW9kUG93KHMsIHoxLCBuSGF0KSAqIG1vZFBvdyh0LCB3MSwgbkhhdCkpICUgbkhhdCAhPT0gKEEgKiBtb2RQb3coUCwgZSwgbkhhdCkpICUgbkhhdCkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IHZlcmlmeSBubyBzbWFsbCBmYWN0b3JzIHByb29mJyk7XG4gIH1cbiAgaWYgKChtb2RQb3cocywgejIsIG5IYXQpICogbW9kUG93KHQsIHcyLCBuSGF0KSkgJSBuSGF0ICE9PSAoQiAqIG1vZFBvdyhRLCBlLCBuSGF0KSkgJSBuSGF0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgdmVyaWZ5IG5vIHNtYWxsIGZhY3RvcnMgcHJvb2YnKTtcbiAgfVxuICBpZiAoKG1vZFBvdyhRLCB6MSwgbkhhdCkgKiBtb2RQb3codCwgdiwgbkhhdCkpICUgbkhhdCAhPT0gKFQgKiBtb2RQb3coUiwgZSwgbkhhdCkpICUgbkhhdCkge1xuICAgIHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IHZlcmlmeSBubyBzbWFsbCBmYWN0b3JzIHByb29mJyk7XG4gIH1cbiAgaWYgKHoxIDwgLXNxcnROMCA8PCAoRUxMICsgRVBTSUxPTikgfHwgejEgPiBzcXJ0TjAgPDwgKEVMTCArIEVQU0lMT04pKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgdmVyaWZ5IG5vIHNtYWxsIGZhY3RvcnMgcHJvb2YnKTtcbiAgfVxuICBpZiAoejIgPCAtc3FydE4wIDw8IChFTEwgKyBFUFNJTE9OKSB8fCB6MiA+IHNxcnROMCA8PCAoRUxMICsgRVBTSUxPTikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCB2ZXJpZnkgbm8gc21hbGwgZmFjdG9ycyBwcm9vZicpO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuIl19
@@ -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;AA6ExD;;;;;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,148 +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
- let counter = 0;
20
- return Array(m)
21
- .fill(null)
22
- .map((_) => {
23
- while (true) {
24
- let h = util_1.bigIntFromBufferBE(
25
- // TypeScript doesn't like us using `outputLength` in the transform options,
26
- // but it is required for shake256.
27
- crypto_1.createHash('shake256', { outputLength: Math.floor((bigint_crypto_utils_1.bitLength(N) + 7) / 8) })
28
- .update(Buffer.from([counter++]))
29
- .update('$')
30
- .update(NBuf)
31
- .update('$')
32
- .update(wBuf)
33
- .update('$')
34
- .digest());
35
- h = (h * h) % N;
36
- if (bigint_mod_arith_1.gcd(h, N) === BigInt(1)) {
37
- return h;
38
- }
39
- }
40
- });
41
- }
42
- // https://en.wikipedia.org/wiki/Jacobi_symbol#Implementation_in_C++
43
- function jacobi(a, n) {
44
- // a/n is represented as (a,n)
45
- if (n <= BigInt(0)) {
46
- throw new Error('n must greater than 0');
47
- }
48
- if (n % BigInt(2) !== BigInt(1)) {
49
- throw new Error('n must be odd');
50
- }
51
- // step 1
52
- a = a % n;
53
- let t = BigInt(1);
54
- let r;
55
- // step 3
56
- while (a !== BigInt(0)) {
57
- // step 2
58
- while (a % BigInt(2) === BigInt(0)) {
59
- a /= BigInt(2);
60
- r = n % BigInt(8);
61
- if (r === BigInt(3) || r === BigInt(5)) {
62
- t = -t;
63
- }
64
- }
65
- // step 4
66
- r = n;
67
- n = a;
68
- a = r;
69
- if (a % BigInt(4) === BigInt(3) && n % BigInt(4) === BigInt(3)) {
70
- t = -t;
71
- }
72
- a = a % n;
73
- }
74
- if (n === BigInt(1)) {
75
- return t;
76
- }
77
- return BigInt(0);
78
- }
79
- /**
80
- * Prove that a modulus (p*q) is the product of two large safe primes (p and q).
81
- * @param {bigint} p The larger prime factor of the modulus
82
- * @param {bigint} q The smaller prime factor of the modulus.
83
- * @returns {DeserializedPaillierBlumProof} The proof that the modulus is the product of two large primes.
84
- */
85
- async function prove(p, q) {
86
- // Prover selects random w with Jacobi symbol 1 wrt N.
87
- const N = p * q;
88
- const l = (p - BigInt(1)) * (q - BigInt(1));
89
- const d = bigint_mod_arith_1.modInv(N, l);
90
- let w;
91
- while (true) {
92
- w = util_1.bigIntFromBufferBE(Buffer.from(await bigint_crypto_utils_1.randBits(bigint_crypto_utils_1.bitLength(N))));
93
- if (jacobi(w, N) === BigInt(-1)) {
94
- break;
95
- }
96
- }
97
- // This is calculating the inverse of the function y^4 mod N,
98
- // i.e.y ^ (1 / 4), where N = pq is a blum integer using HOC - Fact 2.160
99
- // from cacr.uwaterloo.ca / hac / about / chap2.pdf
100
- // Prover generates y_i.
101
- const y = generateY(N, w);
102
- // Prover calculates z_i = y_i ^ d mod N
103
- const z = y.map((y_i) => bigint_mod_arith_1.modPow(y_i, d, N));
104
- // Prover calculates x_i = y_i ^ 1/4 mod N using [HOC - Fact 2.160]
105
- const e = ((l + BigInt(4)) / BigInt(8)) ** BigInt(2);
106
- const x = y.map((y_i) => bigint_mod_arith_1.modPow(y_i, e, N));
107
- return { w, x, z };
108
- }
109
- exports.prove = prove;
110
- /**
111
- * Verify that N is the product of two large primes.
112
- * @param {bigint} N The prime number being verified.
113
- * @param {DeserializedPaillierBlumProof} The proof to verify N is a product of two large primes.
114
- * @returns {boolean} True if N is a product of two large primes, and false otherwise.
115
- */
116
- async function verify(N, { w, x, z }) {
117
- // Verifier checks N > 1.
118
- if (N <= 1) {
119
- throw new Error('N must be greater than 1');
120
- }
121
- // Verifier checks N is odd.
122
- if (N % BigInt(2) !== BigInt(1)) {
123
- throw new Error('N must be an odd number');
124
- }
125
- // Verifier checks N is not prime.
126
- if (await bigint_crypto_utils_1.isProbablyPrime(N, 24)) {
127
- throw new Error('N must be a composite number');
128
- }
129
- // Verifier checks that the Jacobi symbol for w is 1 wrt N.
130
- if (jacobi(w, N) !== BigInt(-1)) {
131
- throw new Error('Jacobi symbol of w must be -1 wrt to N');
132
- }
133
- // Verifier generates y_i.
134
- const y = generateY(N, w);
135
- for (let i = 0; i < m; i++) {
136
- // Verifier checks z_i ^ N mod N == y_i.
137
- if (bigint_mod_arith_1.modPow(z[i], N, N) !== y[i]) {
138
- throw new Error(`Paillier verification of z[${i}] failed`);
139
- }
140
- // Verifier checks x_i ^ 4 mod N == y_i.
141
- if (bigint_mod_arith_1.modPow(x[i], 4, N) !== y[i]) {
142
- throw new Error(`Paillier verification of x[${i}] failed`);
143
- }
144
- }
145
- return true;
146
- }
147
- exports.verify = verify;
148
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFpbGxpZXJCbHVtUHJvb2YuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdHNzL2VjZHNhL3BhaWxsaWVyQmx1bVByb29mLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG1DQUFvQztBQUNwQyw2REFBMkU7QUFDM0UsdURBQXVEO0FBQ3ZELHFDQUFrRTtBQUdsRSxzQkFBc0I7QUFDdEIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBRWI7Ozs7O0dBS0c7QUFDSCxTQUFTLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUNyQixNQUFNLElBQUksR0FBRyx1QkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNqQyxNQUFNLElBQUksR0FBRyx1QkFBZ0IsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzlDLElBQUksT0FBTyxHQUFHLENBQUMsQ0FBQztJQUNoQixPQUFPLEtBQUssQ0FBQyxDQUFDLENBQUM7U0FDWixJQUFJLENBQUMsSUFBSSxDQUFDO1NBQ1YsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7UUFDVCxPQUFPLElBQUksRUFBRTtZQUNYLElBQUksQ0FBQyxHQUFHLHlCQUFrQjtZQUN4Qiw0RUFBNEU7WUFDNUUsbUNBQW1DO1lBQ25DLG1CQUFVLENBQUMsVUFBVSxFQUFFLEVBQUUsWUFBWSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQywrQkFBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7aUJBQ3pFLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO2lCQUNoQyxNQUFNLENBQUMsR0FBRyxDQUFDO2lCQUNYLE1BQU0sQ0FBQyxJQUFJLENBQUM7aUJBQ1osTUFBTSxDQUFDLEdBQUcsQ0FBQztpQkFDWCxNQUFNLENBQUMsSUFBSSxDQUFD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J2NyeXB0byc7XG5pbXBvcnQgeyBiaXRMZW5ndGgsIHJhbmRCaXRzLCBpc1Byb2JhYmx5UHJpbWUgfSBmcm9tICdiaWdpbnQtY3J5cHRvLXV0aWxzJztcbmltcG9ydCB7IGdjZCwgbW9kSW52LCBtb2RQb3cgfSBmcm9tICdiaWdpbnQtbW9kLWFyaXRoJztcbmltcG9ydCB7IGJpZ0ludEZyb21CdWZmZXJCRSwgYmlnSW50VG9CdWZmZXJCRSB9IGZyb20gJy4uLy4uL3V0aWwnO1xuaW1wb3J0IHsgRGVzZXJpYWxpemVkUGFpbGxpZXJCbHVtUHJvb2YgfSBmcm9tICcuL3R5cGVzJztcblxuLy8gU2VjdXJpdHkgcGFyYW1ldGVyLlxuY29uc3QgbSA9IDgwO1xuXG4vKipcbiAqIEdlbmVyYXRlIHBzdWVkby1yYW5kb20gcXVhZHJhdGljIHJlc2lkdWUgZm9yIChOLCB3LCBpKS5cbiAqIEBwYXJhbSBOIC0gdGhlIHByaW1lIG51bWJlciB0byB2ZXJpZnkgaXMgYSBwcm9kdWN0IG9mIHR3byBsYXJnZSBwcmltZXMuXG4gKiBAcGFyYW0gdyAtIGEgcmFuZG9tIG51bWJlciB3aXRoIHRoZSBzYW1lIGJpdExlbmd0aCBhcyBOLCB0aGF0IHNhdGlzZmllcyB0aGUgSmFjb2JpIG9mIHcgaXMgLTEgd3J0IE4uXG4gKiBAcmV0dXJucyB7YmlnaW50W119IC0gc2V0IG9mIGNoYWxsZW5nZXMgZm9yIE5cbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVZKE4sIHcpOiBiaWdpbnRbXSB7XG4gIGNvbnN0IE5CdWYgPSBiaWdJbnRUb0J1ZmZlckJFKE4pO1xuICBjb25zdCB3QnVmID0gYmlnSW50VG9CdWZmZXJCRSh3LCBOQnVmLmxlbmd0aCk7XG4gIGxldCBjb3VudGVyID0gMDtcbiAgcmV0dXJuIEFycmF5KG0pXG4gICAgLmZpbGwobnVsbClcbiAgICAubWFwKChfKSA9PiB7XG4gICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICBsZXQgaCA9IGJpZ0ludEZyb21CdWZmZXJCRShcbiAgICAgICAgICAvLyBUeXBlU2NyaXB0IGRvZXNuJ3QgbGlrZSB1cyB1c2luZyBgb3V0cHV0TGVuZ3RoYCBpbiB0aGUgdHJhbnNmb3JtIG9wdGlvbnMsXG4gICAgICAgICAgLy8gYnV0IGl0IGlzIHJlcXVpcmVkIGZvciBzaGFrZTI1Ni5cbiAgICAgICAgICBjcmVhdGVIYXNoKCdzaGFrZTI1NicsIHsgb3V0cHV0TGVuZ3RoOiBNYXRoLmZsb29yKChiaXRMZW5ndGgoTikgKyA3KSAvIDgpIH0pXG4gICAgICAgICAgICAudXBkYXRlKEJ1ZmZlci5mcm9tKFtjb3VudGVyKytdKSlcbiAgICAgICAgICAgIC51cGRhdGUoJyQnKVxuICAgICAgICAgICAgLnVwZGF0ZShOQnVmKVxuICAgICAgICAgICAgLnVwZGF0ZSgnJCcpXG4gICAgICAgICAgICAudXBkYXRlKHdCdWYpXG4gICAgICAgICAgICAudXBkYXRlKCckJylcbiAgICAgICAgICAgIC5kaWdlc3QoKVxuICAgICAgICApO1xuICAgICAgICBoID0gKGggKiBoKSAlIE47XG4gICAgICAgIGlmIChnY2QoaCwgTikgPT09IEJpZ0ludCgxKSkge1xuICAgICAgICAgIHJldHVybiBoO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG59XG5cbi8vIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0phY29iaV9zeW1ib2wjSW1wbGVtZW50YXRpb25faW5fQysrXG5mdW5jdGlvbiBqYWNvYmkoYSwgbik6IGJpZ2ludCB7XG4gIC8vIGEvbiBpcyByZXByZXNlbnRlZCBhcyAoYSxuKVxuICBpZiAobiA8PSBCaWdJbnQoMCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ24gbXVzdCBncmVhdGVyIHRoYW4gMCcpO1xuICB9XG4gIGlmIChuICUgQmlnSW50KDIpICE9PSBCaWdJbnQoMSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ24gbXVzdCBiZSBvZGQnKTtcbiAgfVxuICAvLyBzdGVwIDFcbiAgYSA9IGEgJSBuO1xuICBsZXQgdCA9IEJpZ0ludCgxKTtcbiAgbGV0IHI7XG4gIC8vIHN0ZXAgM1xuICB3aGlsZSAoYSAhPT0gQmlnSW50KDApKSB7XG4gICAgLy8gc3RlcCAyXG4gICAgd2hpbGUgKGEgJSBCaWdJbnQoMikgPT09IEJpZ0ludCgwKSkge1xuICAgICAgYSAvPSBCaWdJbnQoMik7XG4gICAgICByID0gbiAlIEJpZ0ludCg4KTtcbiAgICAgIGlmIChyID09PSBCaWdJbnQoMykgfHwgciA9PT0gQmlnSW50KDUpKSB7XG4gICAgICAgIHQgPSAtdDtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gc3RlcCA0XG4gICAgciA9IG47XG4gICAgbiA9IGE7XG4gICAgYSA9IHI7XG4gICAgaWYgKGEgJSBCaWdJbnQoNCkgPT09IEJpZ0ludCgzKSAmJiBuICUgQmlnSW50KDQpID09PSBCaWdJbnQoMykpIHtcbiAgICAgIHQgPSAtdDtcbiAgICB9XG4gICAgYSA9IGEgJSBuO1xuICB9XG4gIGlmIChuID09PSBCaWdJbnQoMSkpIHtcbiAgICByZXR1cm4gdDtcbiAgfVxuICByZXR1cm4gQmlnSW50KDApO1xufVxuXG4vKipcbiAqIFByb3ZlIHRoYXQgYSBtb2R1bHVzIChwKnEpIGlzIHRoZSBwcm9kdWN0IG9mIHR3byBsYXJnZSBzYWZlIHByaW1lcyAocCBhbmQgcSkuXG4gKiBAcGFyYW0ge2JpZ2ludH0gcCBUaGUgbGFyZ2VyIHByaW1lIGZhY3RvciBvZiB0aGUgbW9kdWx1c1xuICogQHBhcmFtIHtiaWdpbnR9IHEgVGhlIHNtYWxsZXIgcHJpbWUgZmFjdG9yIG9mIHRoZSBtb2R1bHVzLlxuICogQHJldHVybnMge0Rlc2VyaWFsaXplZFBhaWxsaWVyQmx1bVByb29mfSBUaGUgcHJvb2YgdGhhdCB0aGUgbW9kdWx1cyBpcyB0aGUgcHJvZHVjdCBvZiB0d28gbGFyZ2UgcHJpbWVzLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcHJvdmUocDogYmlnaW50LCBxOiBiaWdpbnQpOiBQcm9taXNlPERlc2VyaWFsaXplZFBhaWxsaWVyQmx1bVByb29mPiB7XG4gIC8vIFByb3ZlciBzZWxlY3RzIHJhbmRvbSB3IHdpdGggSmFjb2JpIHN5bWJvbCAxIHdydCBOLlxuICBjb25zdCBOID0gcCAqIHE7XG4gIGNvbnN0IGwgPSAocCAtIEJpZ0ludCgxKSkgKiAocSAtIEJpZ0ludCgxKSk7XG4gIGNvbnN0IGQgPSBtb2RJbnYoTiwgbCk7XG4gIGxldCB3O1xuICB3aGlsZSAodHJ1ZSkge1xuICAgIHcgPSBiaWdJbnRGcm9tQnVmZmVyQkUoQnVmZmVyLmZyb20oYXdhaXQgcmFuZEJpdHMoYml0TGVuZ3RoKE4pKSkpO1xuICAgIGlmIChqYWNvYmkodywgTikgPT09IEJpZ0ludCgtMSkpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICAvLyBUaGlzIGlzIGNhbGN1bGF0aW5nIHRoZSBpbnZlcnNlIG9mIHRoZSBmdW5jdGlvbiB5XjQgbW9kIE4sXG4gIC8vIGkuZS55IF4gKDEgLyA0KSwgd2hlcmUgTiA9IHBxIGlzIGEgYmx1bSBpbnRlZ2VyIHVzaW5nIEhPQyAtIEZhY3QgMi4xNjBcbiAgLy8gZnJvbSBjYWNyLnV3YXRlcmxvby5jYSAvIGhhYyAvIGFib3V0IC8gY2hhcDIucGRmXG4gIC8vIFByb3ZlciBnZW5lcmF0ZXMgeV9pLlxuICBjb25zdCB5ID0gZ2VuZXJhdGVZKE4sIHcpO1xuICAvLyBQcm92ZXIgY2FsY3VsYXRlcyB6X2kgPSB5X2kgXiBkIG1vZCBOXG4gIGNvbnN0IHogPSB5Lm1hcCgoeV9pKSA9PiBtb2RQb3coeV9pLCBkLCBOKSk7XG4gIC8vIFByb3ZlciBjYWxjdWxhdGVzIHhfaSA9IHlfaSBeIDEvNCBtb2QgTiB1c2luZyBbSE9DIC0gRmFjdCAyLjE2MF1cbiAgY29uc3QgZSA9ICgobCArIEJpZ0ludCg0KSkgLyBCaWdJbnQoOCkpICoqIEJpZ0ludCgyKTtcbiAgY29uc3QgeCA9IHkubWFwKCh5X2kpID0+IG1vZFBvdyh5X2ksIGUsIE4pKTtcbiAgcmV0dXJuIHsgdywgeCwgeiB9O1xufVxuXG4vKipcbiAqIFZlcmlmeSB0aGF0IE4gaXMgdGhlIHByb2R1Y3Qgb2YgdHdvIGxhcmdlIHByaW1lcy5cbiAqIEBwYXJhbSB7YmlnaW50fSBOIFRoZSBwcmltZSBudW1iZXIgYmVpbmcgdmVyaWZpZWQuXG4gKiBAcGFyYW0ge0Rlc2VyaWFsaXplZFBhaWxsaWVyQmx1bVByb29mfSBUaGUgcHJvb2YgdG8gdmVyaWZ5IE4gaXMgYSBwcm9kdWN0IG9mIHR3byBsYXJnZSBwcmltZXMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBOIGlzIGEgcHJvZHVjdCBvZiB0d28gbGFyZ2UgcHJpbWVzLCBhbmQgZmFsc2Ugb3RoZXJ3aXNlLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdmVyaWZ5KE46IGJpZ2ludCwgeyB3LCB4LCB6IH06IERlc2VyaWFsaXplZFBhaWxsaWVyQmx1bVByb29mKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIC8vIFZlcmlmaWVyIGNoZWNrcyBOID4gMS5cbiAgaWYgKE4gPD0gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcignTiBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAxJyk7XG4gIH1cbiAgLy8gVmVyaWZpZXIgY2hlY2tzIE4gaXMgb2RkLlxuICBpZiAoTiAlIEJpZ0ludCgyKSAhPT0gQmlnSW50KDEpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdOIG11c3QgYmUgYW4gb2RkIG51bWJlcicpO1xuICB9XG4gIC8vIFZlcmlmaWVyIGNoZWNrcyBOIGlzIG5vdCBwcmltZS5cbiAgaWYgKGF3YWl0IGlzUHJvYmFibHlQcmltZShOLCAyNCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ04gbXVzdCBiZSBhIGNvbXBvc2l0ZSBudW1iZXInKTtcbiAgfVxuICAvLyBWZXJpZmllciBjaGVja3MgdGhhdCB0aGUgSmFjb2JpIHN5bWJvbCBmb3IgdyBpcyAxIHdydCBOLlxuICBpZiAoamFjb2JpKHcsIE4pICE9PSBCaWdJbnQoLTEpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdKYWNvYmkgc3ltYm9sIG9mIHcgbXVzdCBiZSAtMSB3cnQgdG8gTicpO1xuICB9XG4gIC8vIFZlcmlmaWVyIGdlbmVyYXRlcyB5X2kuXG4gIGNvbnN0IHkgPSBnZW5lcmF0ZVkoTiwgdyk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbTsgaSsrKSB7XG4gICAgLy8gVmVyaWZpZXIgY2hlY2tzIHpfaSBeIE4gbW9kIE4gPT0geV9pLlxuICAgIGlmIChtb2RQb3coeltpXSwgTiwgTikgIT09IHlbaV0pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgUGFpbGxpZXIgdmVyaWZpY2F0aW9uIG9mIHpbJHtpfV0gZmFpbGVkYCk7XG4gICAgfVxuICAgIC8vIFZlcmlmaWVyIGNoZWNrcyB4X2kgXiA0IG1vZCBOID09IHlfaS5cbiAgICBpZiAobW9kUG93KHhbaV0sIDQsIE4pICE9PSB5W2ldKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFBhaWxsaWVyIHZlcmlmaWNhdGlvbiBvZiB4WyR7aX1dIGZhaWxlZGApO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cbiJdfQ==