UNPKG

js-ecutils

Version:

JavaScript Library for Elliptic Curve Cryptography: key exchanges (Diffie-Hellman, Massey-Omura), ECDSA signatures, and Koblitz encoding. Suitable for crypto education and secure systems.

163 lines (149 loc) 25.9 kB
"use strict"; var _globals = require("@jest/globals"); var _math = require("./utils/math"); function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } // --------------------------------------------------------------------------- // Modular arithmetic basics // --------------------------------------------------------------------------- (0, _globals.describe)('Modular arithmetic utilities', function () { (0, _globals.test)('modulus returns non-negative result for negative dividends', function () { (0, _globals.expect)((0, _math.modulus)(-5n, 3n)).toBe(1n); (0, _globals.expect)((0, _math.modulus)(-1n, 7n)).toBe(6n); (0, _globals.expect)((0, _math.modulus)(5n, 3n)).toBe(2n); }); (0, _globals.test)('modPow with m = 1 returns 0', function () { (0, _globals.expect)((0, _math.modPow)(5n, 3n, 1n)).toBe(0n); }); (0, _globals.test)('modPow computes base^exp mod m correctly', function () { // 2^10 = 1024, 1024 mod 100 = 24 (0, _globals.expect)((0, _math.modPow)(2n, 10n, 100n)).toBe(24n); // 3^0 = 1 (0, _globals.expect)((0, _math.modPow)(3n, 0n, 7n)).toBe(1n); }); (0, _globals.test)('extendedGcd returns correct Bezout coefficients', function () { var _extendedGcd = (0, _math.extendedGcd)(35n, 15n), _extendedGcd2 = _slicedToArray(_extendedGcd, 3), g = _extendedGcd2[0], x = _extendedGcd2[1], y = _extendedGcd2[2]; (0, _globals.expect)(g).toBe(5n); (0, _globals.expect)(35n * x + 15n * y).toBe(g); }); (0, _globals.test)('modInverse returns correct inverse', function () { // 3 * 5 = 15 ≡ 1 (mod 7) (0, _globals.expect)((0, _math.modInverse)(3n, 7n)).toBe(5n); // Verify: a * a⁻¹ ≡ 1 (mod p) var inv = (0, _math.modInverse)(17n, 23n); (0, _globals.expect)(17n * inv % 23n).toBe(1n); }); (0, _globals.test)('modInverse throws for non-coprime inputs', function () { (0, _globals.expect)(function () { return (0, _math.modInverse)(6n, 3n); }).toThrow('Modular inverse does not exist'); }); }); // --------------------------------------------------------------------------- // Quadratic residue testing — Euler's criterion // // A non-zero integer a is a quadratic residue mod p (odd prime) iff: // a^((p-1)/2) ≡ 1 (mod p) // // If a ≡ 0 (mod p), then a is not considered a QR. // --------------------------------------------------------------------------- (0, _globals.describe)('Quadratic residue (Euler criterion)', function () { (0, _globals.test)('1 is always a QR mod any prime', function () { (0, _globals.expect)((0, _math.isQuadraticResidue)(1n, 7n)).toBe(true); (0, _globals.expect)((0, _math.isQuadraticResidue)(1n, 23n)).toBe(true); }); // 3^((7-1)/2) = 3³ = 27 ≡ 6 (mod 7) ≠ 1 (0, _globals.test)('3 is not a QR mod 7', function () { (0, _globals.expect)((0, _math.isQuadraticResidue)(3n, 7n)).toBe(false); }); (0, _globals.test)('0 ≡ 0 (mod p) returns false', function () { (0, _globals.expect)((0, _math.isQuadraticResidue)(0n, 7n)).toBe(false); (0, _globals.expect)((0, _math.isQuadraticResidue)(7n, 7n)).toBe(false); }); // QR mod 23 = {1, 2, 3, 4, 6, 8, 9, 12, 13, 16, 18} (0, _globals.test)('complete QR set mod 23', function () { var qrSet = new Set([1n, 2n, 3n, 4n, 6n, 8n, 9n, 12n, 13n, 16n, 18n]); for (var a = 1n; a < 23n; a++) { (0, _globals.expect)((0, _math.isQuadraticResidue)(a, 23n)).toBe(qrSet.has(a)); } }); // 25 ≡ 2 (mod 23), and 2 ∈ QR(23) (0, _globals.test)('values larger than p are reduced before testing', function () { (0, _globals.expect)((0, _math.isQuadraticResidue)(25n, 23n)).toBe(true); }); }); // --------------------------------------------------------------------------- // Modular square root // // For p ≡ 3 (mod 4): √a = a^((p+1)/4) mod p (direct formula) // For p ≡ 1 (mod 4): Tonelli-Shanks algorithm // // Returns null if a is not a quadratic residue mod p. // --------------------------------------------------------------------------- (0, _globals.describe)('Modular square root', function () { // p = 23 ≡ 3 (mod 4) → direct formula: r = a^((p+1)/4) mod p (0, _globals.test)('direct formula for p ≡ 3 (mod 4): √16 mod 23', function () { var r = (0, _math.modularSqrt)(16n, 23n); (0, _globals.expect)(r).not.toBe(null); (0, _globals.expect)((0, _math.modPow)(r, 2n, 23n)).toBe(16n); }); // p = 13 ≡ 1 (mod 4) → Tonelli-Shanks: 4² = 16 ≡ 3 (mod 13) (0, _globals.test)('Tonelli-Shanks for p ≡ 1 (mod 4): √3 mod 13', function () { var r = (0, _math.modularSqrt)(3n, 13n); (0, _globals.expect)(r).not.toBe(null); (0, _globals.expect)((0, _math.modPow)(r, 2n, 13n)).toBe(3n); }); (0, _globals.test)('non-QR returns null: √5 mod 7', function () { (0, _globals.expect)((0, _math.modularSqrt)(5n, 7n)).toBe(null); }); (0, _globals.test)('√0 = 0', function () { (0, _globals.expect)((0, _math.modularSqrt)(0n, 7n)).toBe(0n); }); // Verify r² ≡ a (mod p) for every QR mod 23 (0, _globals.test)('roundtrip for all QR mod 23', function () { for (var a = 1n; a < 23n; a++) { var r = (0, _math.modularSqrt)(a, 23n); if (r !== null) { (0, _globals.expect)((0, _math.modPow)(r, 2n, 23n)).toBe(a); } } }); // p = 17 ≡ 1 (mod 4): QR(17) = {1, 2, 4, 8, 9, 13, 15, 16} (0, _globals.test)('Tonelli-Shanks for all QR mod 17', function () { for (var _i = 0, _arr = [1n, 2n, 4n, 8n, 9n, 13n, 15n, 16n]; _i < _arr.length; _i++) { var a = _arr[_i]; var r = (0, _math.modularSqrt)(a, 17n); (0, _globals.expect)(r).not.toBe(null); (0, _globals.expect)((0, _math.modPow)(r, 2n, 17n)).toBe(a); } }); (0, _globals.test)('non-QR mod 17 return null', function () { for (var _i2 = 0, _arr2 = [3n, 5n, 6n, 7n, 10n, 11n, 12n, 14n]; _i2 < _arr2.length; _i2++) { var a = _arr2[_i2]; (0, _globals.expect)((0, _math.modularSqrt)(a, 17n)).toBe(null); } }); // p = 41 ≡ 1 (mod 8): higher power of 2 in p-1 factorization // 17² = 289 ≡ 2 (mod 41) (0, _globals.test)('Tonelli-Shanks for p ≡ 1 (mod 8): √2 mod 41', function () { var r = (0, _math.modularSqrt)(2n, 41n); (0, _globals.expect)(r).not.toBe(null); (0, _globals.expect)((0, _math.modPow)(r, 2n, 41n)).toBe(2n); }); // √a where a > p (should reduce mod p first) (0, _globals.test)('modularSqrt with a > p reduces correctly', function () { // 27 ≡ 4 (mod 23), and √4 exists var r = (0, _math.modularSqrt)(27n, 23n); (0, _globals.expect)(r).not.toBe(null); (0, _globals.expect)((0, _math.modPow)(r, 2n, 23n)).toBe(4n); }); }); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZ2xvYmFscyIsInJlcXVpcmUiLCJfbWF0aCIsIl9zbGljZWRUb0FycmF5IiwiciIsImUiLCJfYXJyYXlXaXRoSG9sZXMiLCJfaXRlcmFibGVUb0FycmF5TGltaXQiLCJfdW5zdXBwb3J0ZWRJdGVyYWJsZVRvQXJyYXkiLCJfbm9uSXRlcmFibGVSZXN0IiwiVHlwZUVycm9yIiwiYSIsIl9hcnJheUxpa2VUb0FycmF5IiwidCIsInRvU3RyaW5nIiwiY2FsbCIsInNsaWNlIiwiY29uc3RydWN0b3IiLCJuYW1lIiwiQXJyYXkiLCJmcm9tIiwidGVzdCIsImxlbmd0aCIsIm4iLCJsIiwiU3ltYm9sIiwiaXRlcmF0b3IiLCJpIiwidSIsImYiLCJvIiwibmV4dCIsIk9iamVjdCIsImRvbmUiLCJwdXNoIiwidmFsdWUiLCJpc0FycmF5IiwiZGVzY3JpYmUiLCJleHBlY3QiLCJtb2R1bHVzIiwidG9CZSIsIm1vZFBvdyIsIl9leHRlbmRlZEdjZCIsImV4dGVuZGVkR2NkIiwiX2V4dGVuZGVkR2NkMiIsImciLCJ4IiwieSIsIm1vZEludmVyc2UiLCJpbnYiLCJ0b1Rocm93IiwiaXNRdWFkcmF0aWNSZXNpZHVlIiwicXJTZXQiLCJTZXQiLCJoYXMiLCJtb2R1bGFyU3FydCIsIm5vdCIsIl9pIiwiX2FyciIsIl9pMiIsIl9hcnIyIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL21hdGgudGVzdC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyB0ZXN0LCBleHBlY3QsIGRlc2NyaWJlIH0gZnJvbSAnQGplc3QvZ2xvYmFscydcbmltcG9ydCB7XG4gIGlzUXVhZHJhdGljUmVzaWR1ZSxcbiAgbW9kdWxhclNxcnQsXG4gIG1vZFBvdyxcbiAgbW9kdWx1cyxcbiAgbW9kSW52ZXJzZSxcbiAgZXh0ZW5kZWRHY2QsXG59IGZyb20gJy4vdXRpbHMvbWF0aCdcblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBNb2R1bGFyIGFyaXRobWV0aWMgYmFzaWNzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuZGVzY3JpYmUoJ01vZHVsYXIgYXJpdGhtZXRpYyB1dGlsaXRpZXMnLCAoKSA9PiB7XG4gIHRlc3QoJ21vZHVsdXMgcmV0dXJucyBub24tbmVnYXRpdmUgcmVzdWx0IGZvciBuZWdhdGl2ZSBkaXZpZGVuZHMnLCAoKSA9PiB7XG4gICAgZXhwZWN0KG1vZHVsdXMoLTVuLCAzbikpLnRvQmUoMW4pXG4gICAgZXhwZWN0KG1vZHVsdXMoLTFuLCA3bikpLnRvQmUoNm4pXG4gICAgZXhwZWN0KG1vZHVsdXMoNW4sIDNuKSkudG9CZSgybilcbiAgfSlcblxuICB0ZXN0KCdtb2RQb3cgd2l0aCBtID0gMSByZXR1cm5zIDAnLCAoKSA9PiB7XG4gICAgZXhwZWN0KG1vZFBvdyg1biwgM24sIDFuKSkudG9CZSgwbilcbiAgfSlcblxuICB0ZXN0KCdtb2RQb3cgY29tcHV0ZXMgYmFzZV5leHAgbW9kIG0gY29ycmVjdGx5JywgKCkgPT4ge1xuICAgIC8vIDJeMTAgPSAxMDI0LCAxMDI0IG1vZCAxMDAgPSAyNFxuICAgIGV4cGVjdChtb2RQb3coMm4sIDEwbiwgMTAwbikpLnRvQmUoMjRuKVxuICAgIC8vIDNeMCA9IDFcbiAgICBleHBlY3QobW9kUG93KDNuLCAwbiwgN24pKS50b0JlKDFuKVxuICB9KVxuXG4gIHRlc3QoJ2V4dGVuZGVkR2NkIHJldHVybnMgY29ycmVjdCBCZXpvdXQgY29lZmZpY2llbnRzJywgKCkgPT4ge1xuICAgIGNvbnN0IFtnLCB4LCB5XSA9IGV4dGVuZGVkR2NkKDM1biwgMTVuKVxuICAgIGV4cGVjdChnKS50b0JlKDVuKVxuICAgIGV4cGVjdCgzNW4gKiB4ICsgMTVuICogeSkudG9CZShnKVxuICB9KVxuXG4gIHRlc3QoJ21vZEludmVyc2UgcmV0dXJucyBjb3JyZWN0IGludmVyc2UnLCAoKSA9PiB7XG4gICAgLy8gMyAqIDUgPSAxNSDiiaEgMSAobW9kIDcpXG4gICAgZXhwZWN0KG1vZEludmVyc2UoM24sIDduKSkudG9CZSg1bilcbiAgICAvLyBWZXJpZnk6IGEgKiBh4oG7wrkg4omhIDEgKG1vZCBwKVxuICAgIGNvbnN0IGludiA9IG1vZEludmVyc2UoMTduLCAyM24pXG4gICAgZXhwZWN0KCgxN24gKiBpbnYpICUgMjNuKS50b0JlKDFuKVxuICB9KVxuXG4gIHRlc3QoJ21vZEludmVyc2UgdGhyb3dzIGZvciBub24tY29wcmltZSBpbnB1dHMnLCAoKSA9PiB7XG4gICAgZXhwZWN0KCgpID0+IG1vZEludmVyc2UoNm4sIDNuKSkudG9UaHJvdygnTW9kdWxhciBpbnZlcnNlIGRvZXMgbm90IGV4aXN0JylcbiAgfSlcbn0pXG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUXVhZHJhdGljIHJlc2lkdWUgdGVzdGluZyDigJQgRXVsZXIncyBjcml0ZXJpb25cbi8vXG4vLyBBIG5vbi16ZXJvIGludGVnZXIgYSBpcyBhIHF1YWRyYXRpYyByZXNpZHVlIG1vZCBwIChvZGQgcHJpbWUpIGlmZjpcbi8vICAgYV4oKHAtMSkvMikg4omhIDEgIChtb2QgcClcbi8vXG4vLyBJZiBhIOKJoSAwIChtb2QgcCksIHRoZW4gYSBpcyBub3QgY29uc2lkZXJlZCBhIFFSLlxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmRlc2NyaWJlKCdRdWFkcmF0aWMgcmVzaWR1ZSAoRXVsZXIgY3JpdGVyaW9uKScsICgpID0+IHtcbiAgdGVzdCgnMSBpcyBhbHdheXMgYSBRUiBtb2QgYW55IHByaW1lJywgKCkgPT4ge1xuICAgIGV4cGVjdChpc1F1YWRyYXRpY1Jlc2lkdWUoMW4sIDduKSkudG9CZSh0cnVlKVxuICAgIGV4cGVjdChpc1F1YWRyYXRpY1Jlc2lkdWUoMW4sIDIzbikpLnRvQmUodHJ1ZSlcbiAgfSlcblxuICAvLyAzXigoNy0xKS8yKSA9IDPCsyA9IDI3IOKJoSA2IChtb2QgNykg4omgIDFcbiAgdGVzdCgnMyBpcyBub3QgYSBRUiBtb2QgNycsICgpID0+IHtcbiAgICBleHBlY3QoaXNRdWFkcmF0aWNSZXNpZHVlKDNuLCA3bikpLnRvQmUoZmFsc2UpXG4gIH0pXG5cbiAgdGVzdCgnMCDiiaEgMCAobW9kIHApIHJldHVybnMgZmFsc2UnLCAoKSA9PiB7XG4gICAgZXhwZWN0KGlzUXVhZHJhdGljUmVzaWR1ZSgwbiwgN24pKS50b0JlKGZhbHNlKVxuICAgIGV4cGVjdChpc1F1YWRyYXRpY1Jlc2lkdWUoN24sIDduKSkudG9CZShmYWxzZSlcbiAgfSlcblxuICAvLyBRUiBtb2QgMjMgPSB7MSwgMiwgMywgNCwgNiwgOCwgOSwgMTIsIDEzLCAxNiwgMTh9XG4gIHRlc3QoJ2NvbXBsZXRlIFFSIHNldCBtb2QgMjMnLCAoKSA9PiB7XG4gICAgY29uc3QgcXJTZXQgPSBuZXcgU2V0KFsxbiwgMm4sIDNuLCA0biwgNm4sIDhuLCA5biwgMTJuLCAxM24sIDE2biwgMThuXSlcbiAgICBmb3IgKGxldCBhID0gMW47IGEgPCAyM247IGErKykge1xuICAgICAgZXhwZWN0KGlzUXVhZHJhdGljUmVzaWR1ZShhLCAyM24pKS50b0JlKHFyU2V0LmhhcyhhKSlcbiAgICB9XG4gIH0pXG5cbiAgLy8gMjUg4omhIDIgKG1vZCAyMyksIGFuZCAyIOKIiCBRUigyMylcbiAgdGVzdCgndmFsdWVzIGxhcmdlciB0aGFuIHAgYXJlIHJlZHVjZWQgYmVmb3JlIHRlc3RpbmcnLCAoKSA9PiB7XG4gICAgZXhwZWN0KGlzUXVhZHJhdGljUmVzaWR1ZSgyNW4sIDIzbikpLnRvQmUodHJ1ZSlcbiAgfSlcbn0pXG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gTW9kdWxhciBzcXVhcmUgcm9vdFxuLy9cbi8vIEZvciBwIOKJoSAzIChtb2QgNCk6ICDiiJphID0gYV4oKHArMSkvNCkgbW9kIHAgICAoZGlyZWN0IGZvcm11bGEpXG4vLyBGb3IgcCDiiaEgMSAobW9kIDQpOiAgVG9uZWxsaS1TaGFua3MgYWxnb3JpdGhtXG4vL1xuLy8gUmV0dXJucyBudWxsIGlmIGEgaXMgbm90IGEgcXVhZHJhdGljIHJlc2lkdWUgbW9kIHAuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuZGVzY3JpYmUoJ01vZHVsYXIgc3F1YXJlIHJvb3QnLCAoKSA9PiB7XG4gIC8vIHAgPSAyMyDiiaEgMyAobW9kIDQpIOKGkiBkaXJlY3QgZm9ybXVsYTogciA9IGFeKChwKzEpLzQpIG1vZCBwXG4gIHRlc3QoJ2RpcmVjdCBmb3JtdWxhIGZvciBwIOKJoSAzIChtb2QgNCk6IOKImjE2IG1vZCAyMycsICgpID0+IHtcbiAgICBjb25zdCByID0gbW9kdWxhclNxcnQoMTZuLCAyM24pXG4gICAgZXhwZWN0KHIpLm5vdC50b0JlKG51bGwpXG4gICAgZXhwZWN0KG1vZFBvdyhyLCAybiwgMjNuKSkudG9CZSgxNm4pXG4gIH0pXG5cbiAgLy8gcCA9IDEzIOKJoSAxIChtb2QgNCkg4oaSIFRvbmVsbGktU2hhbmtzOiA0wrIgPSAxNiDiiaEgMyAobW9kIDEzKVxuICB0ZXN0KCdUb25lbGxpLVNoYW5rcyBmb3IgcCDiiaEgMSAobW9kIDQpOiDiiJozIG1vZCAxMycsICgpID0+IHtcbiAgICBjb25zdCByID0gbW9kdWxhclNxcnQoM24sIDEzbilcbiAgICBleHBlY3Qocikubm90LnRvQmUobnVsbClcbiAgICBleHBlY3QobW9kUG93KHIsIDJuLCAxM24pKS50b0JlKDNuKVxuICB9KVxuXG4gIHRlc3QoJ25vbi1RUiByZXR1cm5zIG51bGw6IOKImjUgbW9kIDcnLCAoKSA9PiB7XG4gICAgZXhwZWN0KG1vZHVsYXJTcXJ0KDVuLCA3bikpLnRvQmUobnVsbClcbiAgfSlcblxuICB0ZXN0KCfiiJowID0gMCcsICgpID0+IHtcbiAgICBleHBlY3QobW9kdWxhclNxcnQoMG4sIDduKSkudG9CZSgwbilcbiAgfSlcblxuICAvLyBWZXJpZnkgcsKyIOKJoSBhIChtb2QgcCkgZm9yIGV2ZXJ5IFFSIG1vZCAyM1xuICB0ZXN0KCdyb3VuZHRyaXAgZm9yIGFsbCBRUiBtb2QgMjMnLCAoKSA9PiB7XG4gICAgZm9yIChsZXQgYSA9IDFuOyBhIDwgMjNuOyBhKyspIHtcbiAgICAgIGNvbnN0IHIgPSBtb2R1bGFyU3FydChhLCAyM24pXG4gICAgICBpZiAociAhPT0gbnVsbCkge1xuICAgICAgICBleHBlY3QobW9kUG93KHIsIDJuLCAyM24pKS50b0JlKGEpXG4gICAgICB9XG4gICAgfVxuICB9KVxuXG4gIC8vIHAgPSAxNyDiiaEgMSAobW9kIDQpOiBRUigxNykgPSB7MSwgMiwgNCwgOCwgOSwgMTMsIDE1LCAxNn1cbiAgdGVzdCgnVG9uZWxsaS1TaGFua3MgZm9yIGFsbCBRUiBtb2QgMTcnLCAoKSA9PiB7XG4gICAgZm9yIChjb25zdCBhIG9mIFsxbiwgMm4sIDRuLCA4biwgOW4sIDEzbiwgMTVuLCAxNm5dKSB7XG4gICAgICBjb25zdCByID0gbW9kdWxhclNxcnQoYSwgMTduKVxuICAgICAgZXhwZWN0KHIpLm5vdC50b0JlKG51bGwpXG4gICAgICBleHBlY3QobW9kUG93KHIsIDJuLCAxN24pKS50b0JlKGEpXG4gICAgfVxuICB9KVxuXG4gIHRlc3QoJ25vbi1RUiBtb2QgMTcgcmV0dXJuIG51bGwnLCAoKSA9PiB7XG4gICAgZm9yIChjb25zdCBhIG9mIFszbiwgNW4sIDZuLCA3biwgMTBuLCAxMW4sIDEybiwgMTRuXSkge1xuICAgICAgZXhwZWN0KG1vZHVsYXJTcXJ0KGEsIDE3bikpLnRvQmUobnVsbClcbiAgICB9XG4gIH0pXG5cbiAgLy8gcCA9IDQxIOKJoSAxIChtb2QgOCk6IGhpZ2hlciBwb3dlciBvZiAyIGluIHAtMSBmYWN0b3JpemF0aW9uXG4gIC8vIDE3wrIgPSAyODkg4omhIDIgKG1vZCA0MSlcbiAgdGVzdCgnVG9uZWxsaS1TaGFua3MgZm9yIHAg4omhIDEgKG1vZCA4KTog4oiaMiBtb2QgNDEnLCAoKSA9PiB7XG4gICAgY29uc3QgciA9IG1vZHVsYXJTcXJ0KDJuLCA0MW4pXG4gICAgZXhwZWN0KHIpLm5vdC50b0JlKG51bGwpXG4gICAgZXhwZWN0KG1vZFBvdyhyLCAybiwgNDFuKSkudG9CZSgybilcbiAgfSlcblxuICAvLyDiiJphIHdoZXJlIGEgPiBwIChzaG91bGQgcmVkdWNlIG1vZCBwIGZpcnN0KVxuICB0ZXN0KCdtb2R1bGFyU3FydCB3aXRoIGEgPiBwIHJlZHVjZXMgY29ycmVjdGx5JywgKCkgPT4ge1xuICAgIC8vIDI3IOKJoSA0IChtb2QgMjMpLCBhbmQg4oiaNCBleGlzdHNcbiAgICBjb25zdCByID0gbW9kdWxhclNxcnQoMjduLCAyM24pXG4gICAgZXhwZWN0KHIpLm5vdC50b0JlKG51bGwpXG4gICAgZXhwZWN0KG1vZFBvdyhyLCAybiwgMjNuKSkudG9CZSg0bilcbiAgfSlcbn0pXG4iXSwibWFwcGluZ3MiOiI7O0FBQUEsSUFBQUEsUUFBQSxHQUFBQyxPQUFBO0FBQ0EsSUFBQUMsS0FBQSxHQUFBRCxPQUFBO0FBT3FCLFNBQUFFLGVBQUFDLENBQUEsRUFBQUMsQ0FBQSxXQUFBQyxlQUFBLENBQUFGLENBQUEsS0FBQUcscUJBQUEsQ0FBQUgsQ0FBQSxFQUFBQyxDQUFBLEtBQUFHLDJCQUFBLENBQUFKLENBQUEsRUFBQUMsQ0FBQSxLQUFBSSxnQkFBQTtBQUFBLFNBQUFBLGlCQUFBLGNBQUFDLFNBQUE7QUFBQSxTQUFBRiw0QkFBQUosQ0FBQSxFQUFBTyxDQUFBLFFBQUFQLENBQUEsMkJBQUFBLENBQUEsU0FBQVEsaUJBQUEsQ0FBQVIsQ0FBQSxFQUFBTyxDQUFBLE9BQUFFLENBQUEsTUFBQUMsUUFBQSxDQUFBQyxJQUFBLENBQUFY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