diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index 7b1de4e..0000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1,30 +0,0 @@ -module.exports = { - "env": { - "es6": true, - "node": true, - "mocha": true - }, - "parserOptions": { - "ecmaVersion": 2020, - "sourceType": "module" - }, - "extends": "eslint:recommended", - "rules": { - "indent": [ - "error", - 4 - ], - "linebreak-style": [ - "error", - "unix" - ], - "quotes": [ - "error", - "double" - ], - "semi": [ - "error", - "always" - ] - } -}; diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..daedf7f --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "env": { + "es6": true, + "node": true, + "mocha": true + }, + "parserOptions": { + "ecmaVersion": 2020, + "sourceType": "module" + }, + "extends": "eslint:recommended", + "rules": { + "indent": ["error", 4], + "linebreak-style": ["error", "unix"], + "quotes": ["error", "double"], + "semi": ["error", "always"] + } +} diff --git a/.gitignore b/.gitignore index 9e7d574..a139930 100644 --- a/.gitignore +++ b/.gitignore @@ -66,4 +66,3 @@ tmp # Workspace files are user-specific *.sublime-workspace - diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ca61b5b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,20 @@ +{ + "eslint.options": { + "env": { + "es6": true, + "node": true, + "mocha": true + }, + "parserOptions": { + "ecmaVersion": 2020, + "sourceType": "module" + }, + "extends": "eslint:recommended", + "rules": { + "indent": ["error", 4], + "linebreak-style": ["error", "unix"], + "quotes": ["error", "double"], + "semi": ["error", "always"] + } + } +} diff --git a/build/main.cjs b/build/main.cjs index c8dd822..b252d9f 100644 --- a/build/main.cjs +++ b/build/main.cjs @@ -4,22 +4,16 @@ Object.defineProperty(exports, '__esModule', { value: true }); var bigInt = require('big-integer'); var crypto = require('crypto'); -var wasmcurves = require('wasmcurves'); -var os = require('os'); -var Worker = require('web-worker'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var bigInt__default = /*#__PURE__*/_interopDefaultLegacy(bigInt); var crypto__default = /*#__PURE__*/_interopDefaultLegacy(crypto); -var wasmcurves__default = /*#__PURE__*/_interopDefaultLegacy(wasmcurves); -var os__default = /*#__PURE__*/_interopDefaultLegacy(os); -var Worker__default = /*#__PURE__*/_interopDefaultLegacy(Worker); /* global BigInt */ const hexLen = [ 0, 1, 2, 2, 3, 3, 3, 3, 4 ,4 ,4 ,4 ,4 ,4 ,4 ,4]; -function fromString(s, radix) { +function fromString$2(s, radix) { if ((!radix)||(radix==10)) { return BigInt(s); } else if (radix==16) { @@ -31,10 +25,10 @@ function fromString(s, radix) { } } -const e = fromString; +const e$2 = fromString$2; -function fromArray(a, radix) { - let acc =0n; +function fromArray$2(a, radix) { + let acc =BigInt(0); radix = BigInt(radix); for (let i=0; i> BigInt(n); } -const shl = shiftLeft; -const shr = shiftRight; +const shl$2 = shiftLeft$2; +const shr$2 = shiftRight$2; -function isOdd(a) { - return (BigInt(a) & 1n) == 1n; +function isOdd$2(a) { + return (BigInt(a) & BigInt(1)) == BigInt(1); } -function naf(n) { +function naf$2(n) { let E = BigInt(n); const res = []; while (E) { - if (E & 1n) { - const z = 2 - Number(E % 4n); + if (E & BigInt(1)) { + const z = 2 - Number(E % BigInt(4)); res.push( z ); E = E - BigInt(z); } else { res.push( 0 ); } - E = E >> 1n; + E = E >> BigInt(1); } return res; } -function bits(n) { +function bits$2(n) { let E = BigInt(n); const res = []; while (E) { - if (E & 1n) { + if (E & BigInt(1)) { res.push(1); } else { res.push( 0 ); } - E = E >> 1n; + E = E >> BigInt(1); } return res; } -function toNumber(s) { +function toNumber$2(s) { if (s>BigInt(Number.MAX_SAFE_INTEGER )) { throw new Error("Number too big"); } return Number(s); } -function toArray(s, radix) { +function toArray$2(s, radix) { const res = []; let rem = BigInt(s); radix = BigInt(radix); @@ -121,133 +115,133 @@ function toArray(s, radix) { } -function add(a, b) { +function add$2(a, b) { return BigInt(a) + BigInt(b); } -function sub(a, b) { +function sub$2(a, b) { return BigInt(a) - BigInt(b); } -function neg(a) { +function neg$2(a) { return -BigInt(a); } -function mul(a, b) { +function mul$2(a, b) { return BigInt(a) * BigInt(b); } -function square(a) { +function square$2(a) { return BigInt(a) * BigInt(a); } -function pow(a, b) { +function pow$2(a, b) { return BigInt(a) ** BigInt(b); } -function exp(a, b) { +function exp$3(a, b) { return BigInt(a) ** BigInt(b); } -function abs(a) { +function abs$2(a) { return BigInt(a) >= 0 ? BigInt(a) : -BigInt(a); } -function div(a, b) { +function div$2(a, b) { return BigInt(a) / BigInt(b); } -function mod(a, b) { +function mod$2(a, b) { return BigInt(a) % BigInt(b); } -function eq(a, b) { +function eq$2(a, b) { return BigInt(a) == BigInt(b); } -function neq(a, b) { +function neq$2(a, b) { return BigInt(a) != BigInt(b); } -function lt(a, b) { +function lt$2(a, b) { return BigInt(a) < BigInt(b); } -function gt(a, b) { +function gt$2(a, b) { return BigInt(a) > BigInt(b); } -function leq(a, b) { +function leq$2(a, b) { return BigInt(a) <= BigInt(b); } -function geq(a, b) { +function geq$2(a, b) { return BigInt(a) >= BigInt(b); } -function band(a, b) { +function band$2(a, b) { return BigInt(a) & BigInt(b); } -function bor(a, b) { +function bor$2(a, b) { return BigInt(a) | BigInt(b); } -function bxor(a, b) { +function bxor$2(a, b) { return BigInt(a) ^ BigInt(b); } -function land(a, b) { +function land$2(a, b) { return BigInt(a) && BigInt(b); } -function lor(a, b) { +function lor$2(a, b) { return BigInt(a) || BigInt(b); } -function lnot(a) { +function lnot$2(a) { return !BigInt(a); } var Scalar_native = /*#__PURE__*/Object.freeze({ __proto__: null, - fromString: fromString, - e: e, - fromArray: fromArray, - bitLength: bitLength, - isNegative: isNegative, - isZero: isZero, - shiftLeft: shiftLeft, - shiftRight: shiftRight, - shl: shl, - shr: shr, - isOdd: isOdd, - naf: naf, - bits: bits, - toNumber: toNumber, - toArray: toArray, - add: add, - sub: sub, - neg: neg, - mul: mul, - square: square, - pow: pow, - exp: exp, - abs: abs, - div: div, - mod: mod, - eq: eq, - neq: neq, - lt: lt, - gt: gt, - leq: leq, - geq: geq, - band: band, - bor: bor, - bxor: bxor, - land: land, - lor: lor, - lnot: lnot + fromString: fromString$2, + e: e$2, + fromArray: fromArray$2, + bitLength: bitLength$2, + isNegative: isNegative$2, + isZero: isZero$2, + shiftLeft: shiftLeft$2, + shiftRight: shiftRight$2, + shl: shl$2, + shr: shr$2, + isOdd: isOdd$2, + naf: naf$2, + bits: bits$2, + toNumber: toNumber$2, + toArray: toArray$2, + add: add$2, + sub: sub$2, + neg: neg$2, + mul: mul$2, + square: square$2, + pow: pow$2, + exp: exp$3, + abs: abs$2, + div: div$2, + mod: mod$2, + eq: eq$2, + neq: neq$2, + lt: lt$2, + gt: gt$2, + leq: leq$2, + geq: geq$2, + band: band$2, + bor: bor$2, + bxor: bxor$2, + land: land$2, + lor: lor$2, + lnot: lnot$2 }); function fromString$1(s, radix) { @@ -361,7 +355,7 @@ function pow$1(a, b) { return bigInt__default['default'](a).pow(bigInt__default['default'](b)); } -function exp$1(a, b) { +function exp$2(a, b) { return bigInt__default['default'](a).pow(bigInt__default['default'](b)); } @@ -448,7 +442,7 @@ var Scalar_bigint = /*#__PURE__*/Object.freeze({ mul: mul$1, square: square$1, pow: pow$1, - exp: exp$1, + exp: exp$2, abs: abs$1, div: div$1, mod: mod$1, @@ -466,28 +460,28 @@ var Scalar_bigint = /*#__PURE__*/Object.freeze({ lnot: lnot$1 }); -const supportsNativeBigInt = typeof BigInt === "function"; +const supportsNativeBigInt$2 = typeof BigInt === "function"; -let Scalar = {}; -if (supportsNativeBigInt) { - Object.assign(Scalar, Scalar_native); +let Scalar$1 = {}; +if (supportsNativeBigInt$2) { + Object.assign(Scalar$1, Scalar_native); } else { - Object.assign(Scalar, Scalar_bigint); + Object.assign(Scalar$1, Scalar_bigint); } // Returns a buffer with Little Endian Representation -Scalar.toRprLE = function rprBE(buff, o, e, n8) { +Scalar$1.toRprLE = function rprBE(buff, o, e, n8) { const s = "0000000" + e.toString(16); const v = new Uint32Array(buff.buffer, o, n8/4); const l = (((s.length-7)*4 - 1) >> 5)+1; // Number of 32bit words; for (let i=0; i> 5)+1; // Number of 32bit words; @@ -496,38 +490,38 @@ Scalar.toRprBE = function rprLEM(buff, o, e, n8) { }; // Pases a buffer with Little Endian Representation -Scalar.fromRprLE = function rprLEM(buff, o, n8) { +Scalar$1.fromRprLE = function rprLEM(buff, o, n8) { n8 = n8 || buff.byteLength; const v = new Uint32Array(buff.buffer, o, n8/4); const a = new Array(n8/4); v.forEach( (ch,i) => a[a.length-i-1] = ch.toString(16).padStart(8,"0") ); - return Scalar.fromString(a.join(""), 16); + return Scalar$1.fromString(a.join(""), 16); }; // Pases a buffer with Big Endian Representation -Scalar.fromRprBE = function rprLEM(buff, o, n8) { +Scalar$1.fromRprBE = function rprLEM(buff, o, n8) { n8 = n8 || buff.byteLength; const v = new DataView(buff.buffer, buff.byteOffset + o, n8); const a = new Array(n8/4); for (let i=0; i. */ + /* - This library does operations on polynomials with coefficients in a field F. +exports.mulScalar = (F, base, e) =>{ + let res = F.zero; + let rem = bigInt(e); + let exp = base; - A polynomial P(x) = p0 + p1 * x + p2 * x^2 + ... + pn * x^n is represented - by the array [ p0, p1, p2, ... , pn ]. - */ + while (! rem.eq(bigInt.zero)) { + if (rem.and(bigInt.one).eq(bigInt.one)) { + res = F.add(res, exp); + } + exp = F.double(exp); + rem = rem.shiftRight(1); + } -class PolField { - constructor (F) { - this.F = F; + return res; +}; +*/ - let rem = F.sqrt_t; - let s = F.sqrt_s; - const five = this.F.add(this.F.add(this.F.two, this.F.two), this.F.one); +function exp(F, base, e) { - this.w = new Array(s+1); - this.wi = new Array(s+1); - this.w[s] = this.F.pow(five, rem); - this.wi[s] = this.F.inv(this.w[s]); + if (isZero(e)) return F.one; - let n=s-1; - while (n>=0) { - this.w[n] = this.F.square(this.w[n+1]); - this.wi[n] = this.F.square(this.wi[n+1]); - n--; - } + const n = bits(e); + if (n.legth==0) return F.one; - this.roots = []; -/* for (let i=0; i<16; i++) { - let r = this.F.one; - n = 1 << i; - const rootsi = new Array(n); - for (let j=0; j=0; i--) { - _setRoots(n) { - if (n > this.F.sqrt_s) n = this.s; - for (let i=n; (i>=0) && (!this.roots[i]); i--) { - let r = this.F.one; - const nroots = 1 << i; - const rootsi = new Array(nroots); - for (let j=0; j a.length) { - [b, a] = [a, b]; - } + while (!isOdd(F.sqrt_t)) { + F.sqrt_s = F.sqrt_s + 1; + F.sqrt_t = div(F.sqrt_t, 2); + } - if ((b.length <= 2) || (b.length < log2(a.length))) { - return this.mulNormal(a,b); - } else { - return this.mulFFT(a,b); - } - } + let c0 = F.one; - mulNormal(a, b) { - let res = []; - for (let i=0; i0) { - const z = new Array(n).fill(this.F.zero); - return z.concat(p); - } else { - if (-n >= p.length) return []; - return p.slice(-n); - } - } + F.sqrt = function(a) { + if (this.isZero(a)) return this.zero; - eval2(p, x) { - let v = this.F.zero; - let ix = this.F.one; - for (let i=0; i> 1), - F.mul( - x, - _eval(p, newX, offset+step , step << 1, n >> 1))); - return res; - } - } + const a0 = this.mul(this.square(a1), a); - lagrange(points) { - let roots = [this.F.one]; - for (let i=0; i>>0; + } } - - return resn; - } + else { // NodeJS + crypto__default['default'].randomFillSync(array); + } + return array; +} +/* global BigInt */ - ifft2(p) { +class ZqField$1 { + constructor(p) { + this.type="F1"; + this.one = BigInt(1); + this.zero = BigInt(0); + this.p = BigInt(p); + this.m = 1; + this.negone = this.p-this.one; + this.two = BigInt(2); + this.half = this.p >> this.one; + this.bitLength = bitLength(this.p); + this.mask = (this.one << BigInt(this.bitLength)) - this.one; - if (p.length <= 1) return p; - const bits = log2(p.length-1)+1; - this._setRoots(bits); - const m = 1 << bits; - const ep = this.extend(p, m); - __bitReverse(ep, bits); - const res = __fft2(this, ep, bits); + this.n64 = Math.floor((this.bitLength - 1) / 64)+1; + this.n32 = this.n64*2; + this.n8 = this.n64*8; + this.R = this.e(this.one << BigInt(this.n64*64)); + this.Ri = this.inv(this.R); - const twoinvm = this.F.inv( this.F.mulScalar(this.F.one, m) ); - const resn = new Array(m); - for (let i=0; i> this.one; + this.nqr = this.two; + let r = this.pow(this.nqr, e); + while (!this.eq(r, this.negone)) { + this.nqr = this.nqr + this.one; + r = this.pow(this.nqr, e); } - return resn; - - } - _fft(pall, bits, offset, step) { + this.s = 0; + this.t = this.negone; - const n = 1 << bits; - if (n==1) { - return [ pall[offset] ]; + while ((this.t & this.one) == this.zero) { + this.s = this.s + 1; + this.t = this.t >> this.one; } - const ndiv2 = n >> 1; - const p1 = this._fft(pall, bits-1, offset, step*2); - const p2 = this._fft(pall, bits-1, offset+step, step*2); + this.nqr_to_t = this.pow(this.nqr, this.t); - const out = new Array(n); + buildSqrt(this); + } - let m= this.F.one; - for (let i=0; i= this.p) nres = nres % this.p; + return this.p - nres; + } else { + return (res>= this.p) ? res%this.p : res; } - return out; } - extend(p, e) { - if (e == p.length) return p; - const z = new Array(e-p.length).fill(this.F.zero); - - return p.concat(z); + add(a, b) { + const res = a + b; + return res >= this.p ? res-this.p : res; } - reduce(p) { - if (p.length == 0) return p; - if (! this.F.eq(p[p.length-1], this.F.zero) ) return p; - let i=p.length-1; - while( i>0 && this.F.eq(p[i], this.F.zero) ) i--; - return p.slice(0, i+1); + sub(a, b) { + return (a >= b) ? a-b : this.p-b+a; } - eq(a, b) { - const pa = this.reduce(a); - const pb = this.reduce(b); - - if (pa.length != pb.length) return false; - for (let i=0; i=0; i--) { - res[i] = this.F.add(this.F.mul(res[i+1], r), p[i+1]); - } - return res; + mul(a, b) { + return (a*b)%this.p; } - _next2Power(v) { - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v++; - return v; + mulScalar(base, s) { + return (base * this.e(s)) % this.p; } - toString(p) { - const ap = this.normalize(p); - let S = ""; - for (let i=ap.length-1; i>=0; i--) { - if (!this.F.eq(p[i], this.F.zero)) { - if (S!="") S += " + "; - S = S + p[i].toString(10); - if (i>0) { - S = S + "x"; - if (i>1) { - S = S + "^" +i; - } - } - } - } - return S; + square(a) { + return (a*a) % this.p; } - normalize(p) { - const res = new Array(p.length); - for (let i=0; i - // rec = x^(k-2-scaleV)/ v - // - // res = x^m/v = x^(m + (2*k-2 - scaleV) - (2*k-2 - scaleV)) /v => - // res = rec * x^(m - (2*k-2 - scaleV)) => - // res = rec * x^(m - 2*k + 2 + scaleV) - - const rec = this._reciprocal(this.scaleX(v, scaleV), kbits); - const res = this.scaleX(rec, m - 2*k + 2 + scaleV); - - return res; + lt(a, b) { + const aa = (a > this.half) ? a - this.p : a; + const bb = (b > this.half) ? b - this.p : b; + return aa < bb; } - div(_u, _v) { - if (_u.length < _v.length) return []; - const kbits = log2(_v.length-1)+1; - const k = 1 << kbits; + gt(a, b) { + const aa = (a > this.half) ? a - this.p : a; + const bb = (b > this.half) ? b - this.p : b; + return aa > bb; + } - const u = this.scaleX(_u, k-_v.length); - const v = this.scaleX(_v, k-_v.length); + leq(a, b) { + const aa = (a > this.half) ? a - this.p : a; + const bb = (b > this.half) ? b - this.p : b; + return aa <= bb; + } - const n = v.length-1; - let m = u.length-1; + geq(a, b) { + const aa = (a > this.half) ? a - this.p : a; + const bb = (b > this.half) ? b - this.p : b; + return aa >= bb; + } - const s = this._reciprocal(v, kbits); - let t; - if (m>2*n) { - t = this.sub(this.scaleX([this.F.one], 2*n), this.mul(s, v)); - } + div(a, b) { + return this.mul(a, this.inv(b)); + } - let q = []; - let rem = u; - let us, ut; - let finish = false; + idiv(a, b) { + if (!b) throw new Error("Division by zero"); + return a / b; + } - while (!finish) { - us = this.mul(rem, s); - q = this.add(q, this.scaleX(us, -2*n)); + inv(a) { + if (!a) throw new Error("Division by zero"); - if ( m > 2*n ) { - ut = this.mul(rem, t); - rem = this.scaleX(ut, -2*n); - m = rem.length-1; - } else { - finish = true; - } + let t = this.zero; + let r = this.p; + let newt = this.one; + let newr = a % this.p; + while (newr) { + let q = r/newr; + [t, newt] = [newt, t-q*newt]; + [r, newr] = [newr, r-q*newr]; } - - return q; + if (t=n) { - throw new Error("Given 'i' should be lower than 'n'"); - } - else if (1<0) { - if (r & 1 == 1) { - res = this.F.mul(res, this.w[nbits]); - } - r = r >> 1; - nbits --; - } - return res; + pow(b, e) { + return exp(this, b, e); } - computeVanishingPolinomial(bits, t) { - const m = 1 << bits; - return this.F.sub(this.F.pow(t, m), this.F.one); + exp(b, e) { + return exp(this, b, e); } - evaluateLagrangePolynomials(bits, t) { - const m= 1 << bits; - const tm = this.F.pow(t, m); - const u= new Array(m).fill(this.F.zero); - this._setRoots(bits); - const omega = this.w[bits]; - - if (this.F.eq(tm, this.F.one)) { - for (let i = 0; i < m; i++) { - if (this.F.eq(this.roots[bits][0],t)) { // i.e., t equals omega^i - u[i] = this.F.one; - return u; - } - } - } + band(a, b) { + const res = ((a & b) & this.mask); + return res >= this.p ? res-this.p : res; + } - const z = this.F.sub(tm, this.F.one); - // let l = this.F.mul(z, this.F.pow(this.F.twoinv, m)); - let l = this.F.mul(z, this.F.inv(this.F.e(m))); - for (let i = 0; i < m; i++) { - u[i] = this.F.mul(l, this.F.inv(this.F.sub(t,this.roots[bits][i]))); - l = this.F.mul(l, omega); - } + bor(a, b) { + const res = ((a | b) & this.mask); + return res >= this.p ? res-this.p : res; + } - return u; + bxor(a, b) { + const res = ((a ^ b) & this.mask); + return res >= this.p ? res-this.p : res; } - log2(V) { - return log2(V); + bnot(a) { + const res = a ^ this.mask; + return res >= this.p ? res-this.p : res; } -} -function log2( V ) -{ - return( ( ( V & 0xFFFF0000 ) !== 0 ? ( V &= 0xFFFF0000, 16 ) : 0 ) | ( ( V & 0xFF00FF00 ) !== 0 ? ( V &= 0xFF00FF00, 8 ) : 0 ) | ( ( V & 0xF0F0F0F0 ) !== 0 ? ( V &= 0xF0F0F0F0, 4 ) : 0 ) | ( ( V & 0xCCCCCCCC ) !== 0 ? ( V &= 0xCCCCCCCC, 2 ) : 0 ) | ( ( V & 0xAAAAAAAA ) !== 0 ) ); -} + shl(a, b) { + if (Number(b) < this.bitLength) { + const res = (a << b) & this.mask; + return res >= this.p ? res-this.p : res; + } else { + const nb = this.p - b; + if (Number(nb) < this.bitLength) { + return a >> nb; + } else { + return this.zero; + } + } + } + shr(a, b) { + if (Number(b) < this.bitLength) { + return a >> b; + } else { + const nb = this.p - b; + if (Number(nb) < this.bitLength) { + const res = (a << nb) & this.mask; + return res >= this.p ? res-this.p : res; + } else { + return 0; + } + } + } -function __fft(PF, pall, bits, offset, step) { + land(a, b) { + return (a && b) ? this.one : this.zero; + } - const n = 1 << bits; - if (n==1) { - return [ pall[offset] ]; - } else if (n==2) { - return [ - PF.F.add(pall[offset], pall[offset + step]), - PF.F.sub(pall[offset], pall[offset + step])]; + lor(a, b) { + return (a || b) ? this.one : this.zero; } - const ndiv2 = n >> 1; - const p1 = __fft(PF, pall, bits-1, offset, step*2); - const p2 = __fft(PF, pall, bits-1, offset+step, step*2); + lnot(a) { + return (a) ? this.zero : this.one; + } - const out = new Array(n); + sqrt_old(n) { - for (let i=0; i> this.one); + if ( res != this.one ) return null; + let m = this.s; + let c = this.nqr_to_t; + let t = this.pow(n, this.t); + let r = this.pow(n, this.add(this.t, this.one) >> this.one ); -function __fft2(PF, pall, bits) { + while ( t != this.one ) { + let sq = this.square(t); + let i = 1; + while (sq != this.one ) { + i++; + sq = this.square(sq); + } - const n = 1 << bits; - if (n==1) { - return [ pall[0] ]; - } + // b = c ^ m-i-1 + let b = c; + for (let j=0; j< m-i-1; j ++) b = this.square(b); - const ndiv2 = n >> 1; - const p1 = __fft2(PF, pall.slice(0, ndiv2), bits-1); - const p2 = __fft2(PF, pall.slice(ndiv2), bits-1); + m = i; + c = this.square(b); + t = this.mul(t, c); + r = this.mul(r, b); + } - const out = new Array(n); + if (r > (this.p >> this.one)) { + r = this.neg(r); + } - for (let i=0; i= this.p) na = na % this.p; + return this.p - na; + } else { + return (a>= this.p) ? a%this.p : a; + } + } -const _revTable = []; -for (let i=0; i<256; i++) { - _revTable[i] = _revSlow(i, 8); -} + random() { + const nBytes = (this.bitLength*2 / 8); + let res =this.zero; + for (let i=0; i>=1; + toString(a, base) { + let vs; + if (a > this.half) { + const v = this.p-a; + vs = "-"+v.toString(base); + } else { + vs = a.toString(base); + } + return vs; } - return res; -} -function rev(idx, bits) { - return ( - _revTable[idx >>> 24] | - (_revTable[(idx >>> 16) & 0xFF] << 8) | - (_revTable[(idx >>> 8) & 0xFF] << 16) | - (_revTable[idx & 0xFF] << 24) - ) >>> (32-bits); -} + isZero(a) { + return a == this.zero; + } -function __bitReverse(p, bits) { - for (let k=0; kk) { - const tmp= p[k]; - p[k] = p[r]; - p[r] = tmp; - } + fromRng(rng) { + let v; + do { + v=this.zero; + for (let i=0; i= this.p); + v = (v * this.Ri) % this.p; // Convert from montgomery + return v; } } -/* - Copyright 2018 0kims association. - - This file is part of snarkjs. +class ZqField { + constructor(p) { + this.type="F1"; + this.one = bigInt__default['default'].one; + this.zero = bigInt__default['default'].zero; + this.p = bigInt__default['default'](p); + this.m = 1; + this.negone = this.p.minus(bigInt__default['default'].one); + this.two = bigInt__default['default'](2); + this.half = this.p.shiftRight(1); + this.bitLength = this.p.bitLength(); + this.mask = bigInt__default['default'].one.shiftLeft(this.bitLength).minus(bigInt__default['default'].one); - snarkjs is a free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as published by the - Free Software Foundation, either version 3 of the License, or (at your option) - any later version. + this.n64 = Math.floor((this.bitLength - 1) / 64)+1; + this.n32 = this.n64*2; + this.n8 = this.n64*8; + this.R = bigInt__default['default'].one.shiftLeft(this.n64*64); + this.Ri = this.inv(this.R); - snarkjs is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. + const e = this.negone.shiftRight(this.one); + this.nqr = this.two; + let r = this.pow(this.nqr, e); + while (!r.equals(this.negone)) { + this.nqr = this.nqr.add(this.one); + r = this.pow(this.nqr, e); + } - You should have received a copy of the GNU General Public License along with - snarkjs. If not, see . -*/ + this.s = this.zero; + this.t = this.negone; + while (!this.t.isOdd()) { + this.s = this.s.add(this.one); + this.t = this.t.shiftRight(this.one); + } -function mulScalar(F, base, e) { - let res; + this.nqr_to_t = this.pow(this.nqr, this.t); - if (isZero$2(e)) return F.zero; + buildSqrt(this); + } - const n = naf$2(e); + e(a,b) { - if (n[n.length-1] == 1) { - res = base; - } else if (n[n.length-1] == -1) { - res = F.neg(base); - } else { - throw new Error("invlaud NAF"); - } + const res = bigInt__default['default'](a,b); - for (let i=n.length-2; i>=0; i--) { + return this.normalize(res); - res = F.double(res); + } - if (n[i] == 1) { - res = F.add(res, base); - } else if (n[i] == -1) { - res = F.sub(res, base); + add(a, b) { + let res = a.add(b); + if (res.geq(this.p)) { + res = res.minus(this.p); } + return res; } - return res; -} - - -/* -exports.mulScalar = (F, base, e) =>{ - let res = F.zero; - let rem = bigInt(e); - let exp = base; - - while (! rem.eq(bigInt.zero)) { - if (rem.and(bigInt.one).eq(bigInt.one)) { - res = F.add(res, exp); + sub(a, b) { + if (a.geq(b)) { + return a.minus(b); + } else { + return this.p.minus(b.minus(a)); } - exp = F.double(exp); - rem = rem.shiftRight(1); } - return res; -}; -*/ - - -function exp$3(F, base, e) { + neg(a) { + if (a.isZero()) return a; + return this.p.minus(a); + } - if (isZero$2(e)) return F.one; + mul(a, b) { + return a.times(b).mod(this.p); + } - const n = bits$2(e); + mulScalar(base, s) { + return base.times(bigInt__default['default'](s)).mod(this.p); + } - if (n.legth==0) return F.one; + square(a) { + return a.square().mod(this.p); + } - let res = base; + eq(a, b) { + return a.eq(b); + } - for (let i=n.length-2; i>=0; i--) { + neq(a, b) { + return a.neq(b); + } - res = F.square(res); + lt(a, b) { + const aa = a.gt(this.half) ? a.minus(this.p) : a; + const bb = b.gt(this.half) ? b.minus(this.p) : b; + return aa.lt(bb); + } - if (n[i]) { - res = F.mul(res, base); - } + gt(a, b) { + const aa = a.gt(this.half) ? a.minus(this.p) : a; + const bb = b.gt(this.half) ? b.minus(this.p) : b; + return aa.gt(bb); } - return res; -} + leq(a, b) { + const aa = a.gt(this.half) ? a.minus(this.p) : a; + const bb = b.gt(this.half) ? b.minus(this.p) : b; + return aa.leq(bb); + } -// Check here: https://eprint.iacr.org/2012/685.pdf + geq(a, b) { + const aa = a.gt(this.half) ? a.minus(this.p) : a; + const bb = b.gt(this.half) ? b.minus(this.p) : b; + return aa.geq(bb); + } -function buildSqrt (F) { - if ((F.m % 2) == 1) { - if (eq$2(mod$2(F.p, 4), 1 )) { - if (eq$2(mod$2(F.p, 8), 1 )) { - if (eq$2(mod$2(F.p, 16), 1 )) { - // alg7_muller(F); - alg5_tonelliShanks(F); - } else if (eq$2(mod$2(F.p, 16), 9 )) { - alg4_kong(F); - } else { - throw new Error("Field withot sqrt"); - } - } else if (eq$2(mod$2(F.p, 8), 5 )) { - alg3_atkin(F); - } else { - throw new Error("Field withot sqrt"); - } - } else if (eq$2(mod$2(F.p, 4), 3 )) { - alg2_shanks(F); - } - } else { - const pm2mod4 = mod$2(pow$2(F.p, F.m/2), 4); - if (pm2mod4 == 1) { - alg10_adj(F); - } else if (pm2mod4 == 3) { - alg9_adj(F); - } else { - alg8_complex(F); - } + div(a, b) { + if (b.isZero()) throw new Error("Division by zero"); + return a.times(b.modInv(this.p)).mod(this.p); + } + idiv(a, b) { + if (b.isZero()) throw new Error("Division by zero"); + return a.divide(b); } -} + inv(a) { + if (a.isZero()) throw new Error("Division by zero"); + return a.modInv(this.p); + } -function alg5_tonelliShanks(F) { - F.sqrt_q = pow$2(F.p, F.m); + mod(a, b) { + return a.mod(b); + } - F.sqrt_s = 0; - F.sqrt_t = sub$2(F.sqrt_q, 1); + pow(a, b) { + return a.modPow(b, this.p); + } - while (!isOdd$2(F.sqrt_t)) { - F.sqrt_s = F.sqrt_s + 1; - F.sqrt_t = div$2(F.sqrt_t, 2); + exp(a, b) { + return a.modPow(b, this.p); } - let c0 = F.one; + band(a, b) { + return a.and(b).and(this.mask).mod(this.p); + } - while (F.eq(c0, F.one)) { - const c = F.random(); - F.sqrt_z = F.pow(c, F.sqrt_t); - c0 = F.pow(F.sqrt_z, 2 ** (F.sqrt_s-1) ); + bor(a, b) { + return a.or(b).and(this.mask).mod(this.p); } - F.sqrt_tm1d2 = div$2(sub$2(F.sqrt_t, 1),2); + bxor(a, b) { + return a.xor(b).and(this.mask).mod(this.p); + } - F.sqrt = function(a) { - const F=this; - if (F.isZero(a)) return F.zero; - let w = F.pow(a, F.sqrt_tm1d2); - const a0 = F.pow( F.mul(F.square(w), a), 2 ** (F.sqrt_s-1) ); - if (F.eq(a0, F.negone)) return null; + bnot(a) { + return a.xor(this.mask).mod(this.p); + } - let v = F.sqrt_s; - let x = F.mul(a, w); - let b = F.mul(x, w); - let z = F.sqrt_z; - while (!F.eq(b, F.one)) { - let b2k = F.square(b); - let k=1; - while (!F.eq(b2k, F.one)) { - b2k = F.square(b2k); - k++; + shl(a, b) { + if (b.lt(this.bitLength)) { + return a.shiftLeft(b).and(this.mask).mod(this.p); + } else { + const nb = this.p.minus(b); + if (nb.lt(this.bitLength)) { + return this.shr(a, nb); + } else { + return bigInt__default['default'].zero; } + } + } - w = z; - for (let i=0; i>> 0; - st[d] = (st[d] ^ st[a]) >>> 0; - st[d] = ((st[d] << 16) | ((st[d]>>>16) & 0xFFFF)) >>> 0; + fromRng(rng) { + let v; + do { + v = bigInt__default['default'](0); + for (let i=0; i>> 0; - st[b] = (st[b] ^ st[c]) >>> 0; - st[b] = ((st[b] << 12) | ((st[b]>>>20) & 0xFFF)) >>> 0; - st[a] = (st[a] + st[b]) >>> 0; - st[d] = (st[d] ^ st[a]) >>> 0; - st[d] = ((st[d] << 8) | ((st[d]>>>24) & 0xFF)) >>> 0; +} - st[c] = (st[c] + st[d]) >>> 0; - st[b] = (st[b] ^ st[c]) >>> 0; - st[b] = ((st[b] << 7) | ((st[b]>>>25) & 0x7F)) >>> 0; +const supportsNativeBigInt$1 = typeof BigInt === "function"; +let _F1Field; +if (supportsNativeBigInt$1) { + _F1Field = ZqField$1; +} else { + _F1Field = ZqField; } -function doubleRound(st) { - quarterRound(st, 0, 4, 8,12); - quarterRound(st, 1, 5, 9,13); - quarterRound(st, 2, 6,10,14); - quarterRound(st, 3, 7,11,15); - - quarterRound(st, 0, 5,10,15); - quarterRound(st, 1, 6,11,12); - quarterRound(st, 2, 7, 8,13); - quarterRound(st, 3, 4, 9,14); -} +class F1Field extends _F1Field { -class ChaCha { - - constructor(seed) { - seed = seed || [0,0,0,0,0,0,0,0]; - this.state = [ - 0x61707865, - 0x3320646E, - 0x79622D32, - 0x6B206574, - seed[0], - seed[1], - seed[2], - seed[3], - seed[4], - seed[5], - seed[6], - seed[7], - 0, - 0, - 0, - 0 - ]; - this.idx = 16; - this.buff = new Array(16); + // Returns a buffer with Little Endian Representation + toRprLE(buff, o, e) { + toRprLE(buff, o, e, this.n64*8); } - nextU32() { - if (this.idx == 16) this.update(); - return this.buff[this.idx++]; + // Returns a buffer with Big Endian Representation + toRprBE(buff, o, e) { + toRprBE(buff, o, e, this.n64*8); } - nextU64() { - return add$2(mul$2(this.nextU32(), 0x100000000), this.nextU32()); + // Returns a buffer with Big Endian Montgomery Representation + toRprBEM(buff, o, e) { + return this.toRprBE(buff, o, this.mul(this.R, e)); } - nextBool() { - return (this.nextU32() & 1) == 1; + toRprLEM(buff, o, e) { + return this.toRprLE(buff, o, this.mul(this.R, e)); } - update() { - // Copy the state - for (let i=0; i<16; i++) this.buff[i] = this.state[i]; - // Apply the rounds - for (let i=0; i<10; i++) doubleRound(this.buff); + // Pases a buffer with Little Endian Representation + fromRprLE(buff, o) { + return fromRprLE(buff, o, this.n8); + } - // Add to the initial - for (let i=0; i<16; i++) this.buff[i] = (this.buff[i] + this.state[i]) >>> 0; + // Pases a buffer with Big Endian Representation + fromRprBE(buff, o) { + return fromRprBE(buff, o, this.n8); + } - this.idx = 0; + fromRprLEM(buff, o) { + return this.mul(this.fromRprLE(buff, o), this.Ri); + } - this.state[12] = (this.state[12] + 1) >>> 0; - if (this.state[12] != 0) return; - this.state[13] = (this.state[13] + 1) >>> 0; - if (this.state[13] != 0) return; - this.state[14] = (this.state[14] + 1) >>> 0; - if (this.state[14] != 0) return; - this.state[15] = (this.state[15] + 1) >>> 0; + fromRprBEM(buff, o) { + return this.mul(this.fromRprBE(buff, o), this.Ri); } + } -/* global window */ +/* global BigInt */ -function getRandomBytes(n) { - let array = new Uint8Array(n); - if (typeof window !== "undefined") { // Browser - if (typeof window.crypto !== "undefined") { // Supported - window.crypto.getRandomValues(array); - } else { // fallback - for (let i=0; i>>0; - } - } - } - else { // NodeJS - crypto__default['default'].randomFillSync(array); +function stringifyBigInts$2(o) { + if ((typeof(o) == "bigint") || o.eq !== undefined) { + return o.toString(10); + } else if (o instanceof Uint8Array) { + return fromRprLE(o, 0); + } else if (Array.isArray(o)) { + return o.map(stringifyBigInts$2); + } else if (typeof o == "object") { + const res = {}; + const keys = Object.keys(o); + keys.forEach( (k) => { + res[k] = stringifyBigInts$2(o[k]); + }); + return res; + } else { + return o; } - return array; } -function getRandomSeed() { - const arr = getRandomBytes(32); - const arrV = new Uint32Array(arr.buffer); - const seed = []; - for (let i=0; i<8; i++) { - seed.push(arrV[i]); +function unstringifyBigInts$2(o) { + if ((typeof(o) == "string") && (/^[0-9]+$/.test(o) )) { + return BigInt(o); + } else if (Array.isArray(o)) { + return o.map(unstringifyBigInts$2); + } else if (typeof o == "object") { + if (o===null) return null; + const res = {}; + const keys = Object.keys(o); + keys.forEach( (k) => { + res[k] = unstringifyBigInts$2(o[k]); + }); + return res; + } else { + return o; } - return seed; } -let threadRng = null; - -function getThreadRng() { - if (threadRng) return threadRng; - threadRng = new ChaCha(getRandomSeed()); - return threadRng; +function beBuff2int$2(buff) { + let res = BigInt(0); + let i = buff.length; + let offset = 0; + const buffV = new DataView(buff.buffer, buff.byteOffset, buff.byteLength); + while (i>0) { + if (i >= 4) { + i -= 4; + res += BigInt(buffV.getUint32(i)) << BigInt(offset*8); + offset += 4; + } else if (i >= 2) { + i -= 2; + res += BigInt(buffV.getUint16(i)) << BigInt(offset*8); + offset += 2; + } else { + i -= 1; + res += BigInt(buffV.getUint8(i)) << BigInt(offset*8); + offset += 1; + } + } + return res; } -/* global BigInt */ - -class ZqField { - constructor(p) { - this.type="F1"; - this.one = 1n; - this.zero = 0n; - this.p = BigInt(p); - this.m = 1; - this.negone = this.p-1n; - this.two = 2n; - this.half = this.p >> 1n; - this.bitLength = bitLength$2(this.p); - this.mask = (1n << BigInt(this.bitLength)) - 1n; - - this.n64 = Math.floor((this.bitLength - 1) / 64)+1; - this.n32 = this.n64*2; - this.n8 = this.n64*8; - this.R = this.e(1n << BigInt(this.n64*64)); - this.Ri = this.inv(this.R); - - const e = this.negone >> 1n; - this.nqr = this.two; - let r = this.pow(this.nqr, e); - while (!this.eq(r, this.negone)) { - this.nqr = this.nqr + 1n; - r = this.pow(this.nqr, e); +function beInt2Buff$2(n, len) { + let r = n; + const buff = new Uint8Array(len); + const buffV = new DataView(buff.buffer); + let o = len; + while (o > 0) { + if (o-4 >= 0) { + o -= 4; + buffV.setUint32(o, Number(r & BigInt(0xFFFFFFFF))); + r = r >> BigInt(32); + } else if (o-2 >= 0) { + o -= 2; + buffV.setUint16(o, Number(r & BigInt(0xFFFF))); + r = r >> BigInt(16); + } else { + o -= 1; + buffV.setUint8(o, Number(r & BigInt(0xFF))); + r = r >> BigInt(8); } + } + if (r) { + throw new Error("Number does not fit in this length"); + } + return buff; +} - this.s = 0; - this.t = this.negone; - - while ((this.t & 1n) == 0n) { - this.s = this.s + 1; - this.t = this.t >> 1n; +function leBuff2int$2(buff) { + let res = BigInt(0); + let i = 0; + const buffV = new DataView(buff.buffer, buff.byteOffset, buff.byteLength); + while (i= this.p) nres = nres % this.p; - return this.p - nres; +function leInt2Buff$2(n, len) { + let r = n; + if (typeof len === "undefined") { + len = Math.floor((bitLength(n) - 1) / 8) +1; + if (len==0) len = 1; + } + const buff = new Uint8Array(len); + const buffV = new DataView(buff.buffer); + let o = 0; + while (o < len) { + if (o+4 <= len) { + buffV.setUint32(o, Number(r & BigInt(0xFFFFFFFF)), true ); + o += 4; + r = r >> BigInt(32); + } else if (o+2 <= len) { + buffV.setUint16(Number(o, r & BigInt(0xFFFF)), true ); + o += 2; + r = r >> BigInt(16); } else { - return (res>= this.p) ? res%this.p : res; + buffV.setUint8(Number(o, r & BigInt(0xFF)), true ); + o += 1; + r = r >> BigInt(8); } - } - - add(a, b) { - const res = a + b; - return res >= this.p ? res-this.p : res; + if (r) { + throw new Error("Number does not fit in this length"); } + return buff; +} - sub(a, b) { - return (a >= b) ? a-b : this.p-b+a; - } +var utils_native = /*#__PURE__*/Object.freeze({ + __proto__: null, + stringifyBigInts: stringifyBigInts$2, + unstringifyBigInts: unstringifyBigInts$2, + beBuff2int: beBuff2int$2, + beInt2Buff: beInt2Buff$2, + leBuff2int: leBuff2int$2, + leInt2Buff: leInt2Buff$2 +}); - neg(a) { - return a ? this.p-a : a; +function stringifyBigInts$1(o) { + if ((typeof(o) == "bigint") || o.eq !== undefined) { + return o.toString(10); + } else if (Array.isArray(o)) { + return o.map(stringifyBigInts$1); + } else if (typeof o == "object") { + const res = {}; + const keys = Object.keys(o); + keys.forEach( (k) => { + res[k] = stringifyBigInts$1(o[k]); + }); + return res; + } else { + return o; } +} - mul(a, b) { - return (a*b)%this.p; +function unstringifyBigInts$1(o) { + if ((typeof(o) == "string") && (/^[0-9]+$/.test(o) )) { + return bigInt__default['default'](o); + } else if (Array.isArray(o)) { + return o.map(unstringifyBigInts$1); + } else if (typeof o == "object") { + const res = {}; + const keys = Object.keys(o); + keys.forEach( (k) => { + res[k] = unstringifyBigInts$1(o[k]); + }); + return res; + } else { + return o; } +} - mulScalar(base, s) { - return (base * this.e(s)) % this.p; +function beBuff2int$1(buff) { + let res = bigInt__default['default'].zero; + for (let i=0; i=0)) { + let c = Number(r.and(bigInt__default['default']("255"))); + buff[o] = c; + o--; + r = r.shiftRight(8); } - - eq(a, b) { - return a==b; + if (!r.eq(bigInt__default['default'].zero)) { + throw new Error("Number does not fit in this length"); } + return buff; +} - neq(a, b) { - return a!=b; - } - lt(a, b) { - const aa = (a > this.half) ? a - this.p : a; - const bb = (b > this.half) ? b - this.p : b; - return aa < bb; - } - - gt(a, b) { - const aa = (a > this.half) ? a - this.p : a; - const bb = (b > this.half) ? b - this.p : b; - return aa > bb; - } - - leq(a, b) { - const aa = (a > this.half) ? a - this.p : a; - const bb = (b > this.half) ? b - this.p : b; - return aa <= bb; - } - - geq(a, b) { - const aa = (a > this.half) ? a - this.p : a; - const bb = (b > this.half) ? b - this.p : b; - return aa >= bb; - } - - div(a, b) { - return this.mul(a, this.inv(b)); - } - - idiv(a, b) { - if (!b) throw new Error("Division by zero"); - return a / b; - } - - inv(a) { - if (!a) throw new Error("Division by zero"); - - let t = 0n; - let r = this.p; - let newt = 1n; - let newr = a % this.p; - while (newr) { - let q = r/newr; - [t, newt] = [newt, t-q*newt]; - [r, newr] = [newr, r-q*newr]; - } - if (t<0n) t += this.p; - return t; - } - - mod(a, b) { - return a % b; - } - - pow(b, e) { - return exp$3(this, b, e); - } - - exp(b, e) { - return exp$3(this, b, e); - } - - band(a, b) { - const res = ((a & b) & this.mask); - return res >= this.p ? res-this.p : res; - } - - bor(a, b) { - const res = ((a | b) & this.mask); - return res >= this.p ? res-this.p : res; - } - - bxor(a, b) { - const res = ((a ^ b) & this.mask); - return res >= this.p ? res-this.p : res; - } - - bnot(a) { - const res = a ^ this.mask; - return res >= this.p ? res-this.p : res; - } - - shl(a, b) { - if (Number(b) < this.bitLength) { - const res = (a << b) & this.mask; - return res >= this.p ? res-this.p : res; - } else { - const nb = this.p - b; - if (Number(nb) < this.bitLength) { - return a >> nb; - } else { - return 0n; - } - } - } - - shr(a, b) { - if (Number(b) < this.bitLength) { - return a >> b; - } else { - const nb = this.p - b; - if (Number(nb) < this.bitLength) { - const res = (a << nb) & this.mask; - return res >= this.p ? res-this.p : res; - } else { - return 0; - } - } - } - - land(a, b) { - return (a && b) ? 1n : 0n; - } - - lor(a, b) { - return (a || b) ? 1n : 0n; - } - - lnot(a) { - return (a) ? 0n : 1n; - } - - sqrt_old(n) { - - if (n == 0n) return this.zero; - - // Test that have solution - const res = this.pow(n, this.negone >> this.one); - if ( res != 1n ) return null; - - let m = this.s; - let c = this.nqr_to_t; - let t = this.pow(n, this.t); - let r = this.pow(n, this.add(this.t, this.one) >> 1n ); - - while ( t != 1n ) { - let sq = this.square(t); - let i = 1; - while (sq != 1n ) { - i++; - sq = this.square(sq); - } - - // b = c ^ m-i-1 - let b = c; - for (let j=0; j< m-i-1; j ++) b = this.square(b); - - m = i; - c = this.square(b); - t = this.mul(t, c); - r = this.mul(r, b); - } - - if (r > (this.p >> 1n)) { - r = this.neg(r); - } - - return r; - } - - normalize(a, b) { - a = BigInt(a,b); - if (a < 0) { - let na = -a; - if (na >= this.p) na = na % this.p; - return this.p - na; - } else { - return (a>= this.p) ? a%this.p : a; - } - } - - random() { - const nBytes = (this.bitLength*2 / 8); - let res =0n; - for (let i=0; i this.half) { - const v = this.p-a; - vs = "-"+v.toString(base); - } else { - vs = a.toString(base); - } - return vs; - } - - isZero(a) { - return a == 0n; - } - - fromRng(rng) { - let v; - do { - v=0n; - for (let i=0; i= this.p); - v = (v * this.Ri) % this.p; // Convert from montgomery - return v; - } - -} - -class ZqField$1 { - constructor(p) { - this.type="F1"; - this.one = bigInt__default['default'].one; - this.zero = bigInt__default['default'].zero; - this.p = bigInt__default['default'](p); - this.m = 1; - this.negone = this.p.minus(bigInt__default['default'].one); - this.two = bigInt__default['default'](2); - this.half = this.p.shiftRight(1); - this.bitLength = this.p.bitLength(); - this.mask = bigInt__default['default'].one.shiftLeft(this.bitLength).minus(bigInt__default['default'].one); - - this.n64 = Math.floor((this.bitLength - 1) / 64)+1; - this.n32 = this.n64*2; - this.n8 = this.n64*8; - this.R = bigInt__default['default'].one.shiftLeft(this.n64*64); - this.Ri = this.inv(this.R); - - const e = this.negone.shiftRight(this.one); - this.nqr = this.two; - let r = this.pow(this.nqr, e); - while (!r.equals(this.negone)) { - this.nqr = this.nqr.add(this.one); - r = this.pow(this.nqr, e); - } - - this.s = this.zero; - this.t = this.negone; - - while (!this.t.isOdd()) { - this.s = this.s.add(this.one); - this.t = this.t.shiftRight(this.one); - } - - this.nqr_to_t = this.pow(this.nqr, this.t); - - buildSqrt(this); - } - - e(a,b) { - - const res = bigInt__default['default'](a,b); - - return this.normalize(res); - - } - - add(a, b) { - let res = a.add(b); - if (res.geq(this.p)) { - res = res.minus(this.p); - } - return res; - } - - sub(a, b) { - if (a.geq(b)) { - return a.minus(b); - } else { - return this.p.minus(b.minus(a)); - } - } - - neg(a) { - if (a.isZero()) return a; - return this.p.minus(a); - } - - mul(a, b) { - return a.times(b).mod(this.p); - } - - mulScalar(base, s) { - return base.times(bigInt__default['default'](s)).mod(this.p); - } - - square(a) { - return a.square().mod(this.p); - } - - eq(a, b) { - return a.eq(b); - } - - neq(a, b) { - return a.neq(b); - } - - lt(a, b) { - const aa = a.gt(this.half) ? a.minus(this.p) : a; - const bb = b.gt(this.half) ? b.minus(this.p) : b; - return aa.lt(bb); - } - - gt(a, b) { - const aa = a.gt(this.half) ? a.minus(this.p) : a; - const bb = b.gt(this.half) ? b.minus(this.p) : b; - return aa.gt(bb); - } - - leq(a, b) { - const aa = a.gt(this.half) ? a.minus(this.p) : a; - const bb = b.gt(this.half) ? b.minus(this.p) : b; - return aa.leq(bb); - } - - geq(a, b) { - const aa = a.gt(this.half) ? a.minus(this.p) : a; - const bb = b.gt(this.half) ? b.minus(this.p) : b; - return aa.geq(bb); - } - - div(a, b) { - if (b.isZero()) throw new Error("Division by zero"); - return a.times(b.modInv(this.p)).mod(this.p); - } - - idiv(a, b) { - if (b.isZero()) throw new Error("Division by zero"); - return a.divide(b); - } - - inv(a) { - if (a.isZero()) throw new Error("Division by zero"); - return a.modInv(this.p); - } - - mod(a, b) { - return a.mod(b); - } - - pow(a, b) { - return a.modPow(b, this.p); - } - - exp(a, b) { - return a.modPow(b, this.p); - } - - band(a, b) { - return a.and(b).and(this.mask).mod(this.p); - } - - bor(a, b) { - return a.or(b).and(this.mask).mod(this.p); - } - - bxor(a, b) { - return a.xor(b).and(this.mask).mod(this.p); - } - - bnot(a) { - return a.xor(this.mask).mod(this.p); - } - - shl(a, b) { - if (b.lt(this.bitLength)) { - return a.shiftLeft(b).and(this.mask).mod(this.p); - } else { - const nb = this.p.minus(b); - if (nb.lt(this.bitLength)) { - return this.shr(a, nb); - } else { - return bigInt__default['default'].zero; - } - } - } - - shr(a, b) { - if (b.lt(this.bitLength)) { - return a.shiftRight(b); - } else { - const nb = this.p.minus(b); - if (nb.lt(this.bitLength)) { - return this.shl(a, nb); - } else { - return bigInt__default['default'].zero; - } - } - } - - land(a, b) { - return (a.isZero() || b.isZero()) ? bigInt__default['default'].zero : bigInt__default['default'].one; - } - - lor(a, b) { - return (a.isZero() && b.isZero()) ? bigInt__default['default'].zero : bigInt__default['default'].one; - } - - lnot(a) { - return a.isZero() ? bigInt__default['default'].one : bigInt__default['default'].zero; - } - - sqrt_old(n) { - - if (n.equals(this.zero)) return this.zero; - - // Test that have solution - const res = this.pow(n, this.negone.shiftRight(this.one)); - if (!res.equals(this.one)) return null; - - let m = parseInt(this.s); - let c = this.nqr_to_t; - let t = this.pow(n, this.t); - let r = this.pow(n, this.add(this.t, this.one).shiftRight(this.one) ); - - while (!t.equals(this.one)) { - let sq = this.square(t); - let i = 1; - while (!sq.equals(this.one)) { - i++; - sq = this.square(sq); - } - - // b = c ^ m-i-1 - let b = c; - for (let j=0; j< m-i-1; j ++) b = this.square(b); - - m = i; - c = this.square(b); - t = this.mul(t, c); - r = this.mul(r, b); - } - - if (r.greater(this.p.shiftRight(this.one))) { - r = this.neg(r); - } - - return r; - } - - normalize(a) { - a = bigInt__default['default'](a); - if (a.isNegative()) { - return this.p.minus(a.abs().mod(this.p)); - } else { - return a.mod(this.p); - } - } - - random() { - let res = bigInt__default['default'](0); - let n = bigInt__default['default'](this.p.square()); - while (!n.isZero()) { - res = res.shiftLeft(8).add(bigInt__default['default'](getRandomBytes(1)[0])); - n = n.shiftRight(8); - } - return res.mod(this.p); - } - - toString(a, base) { - let vs; - if (!a.lesserOrEquals(this.p.shiftRight(bigInt__default['default'](1)))) { - const v = this.p.minus(a); - vs = "-"+v.toString(base); - } else { - vs = a.toString(base); - } - - return vs; - } - - isZero(a) { - return a.isZero(); - } - - fromRng(rng) { - let v; - do { - v = bigInt__default['default'](0); - for (let i=0; i. -*/ - -class F2Field { - constructor(F, nonResidue) { - this.type="F2"; - this.F = F; - this.zero = [this.F.zero, this.F.zero]; - this.one = [this.F.one, this.F.zero]; - this.negone = this.neg(this.one); - this.nonResidue = nonResidue; - this.m = F.m*2; - this.p = F.p; - this.n64 = F.n64*2; - this.n32 = this.n64*2; - this.n8 = this.n64*8; - - buildSqrt(this); - } - - _mulByNonResidue(a) { - return this.F.mul(this.nonResidue, a); - } - - copy(a) { - return [this.F.copy(a[0]), this.F.copy(a[1])]; - } - - add(a, b) { - return [ - this.F.add(a[0], b[0]), - this.F.add(a[1], b[1]) - ]; - } - - double(a) { - return this.add(a,a); - } - - sub(a, b) { - return [ - this.F.sub(a[0], b[0]), - this.F.sub(a[1], b[1]) - ]; - } - - neg(a) { - return this.sub(this.zero, a); - } - - conjugate(a) { - return [ - a[0], - this.F.neg(a[1]) - ]; - } - - mul(a, b) { - const aA = this.F.mul(a[0] , b[0]); - const bB = this.F.mul(a[1] , b[1]); - - return [ - this.F.add( aA , this._mulByNonResidue(bB)), - this.F.sub( - this.F.mul( - this.F.add(a[0], a[1]), - this.F.add(b[0], b[1])), - this.F.add(aA, bB))]; - } - - inv(a) { - const t0 = this.F.square(a[0]); - const t1 = this.F.square(a[1]); - const t2 = this.F.sub(t0, this._mulByNonResidue(t1)); - const t3 = this.F.inv(t2); - return [ - this.F.mul(a[0], t3), - this.F.neg(this.F.mul( a[1], t3)) ]; - } - - div(a, b) { - return this.mul(a, this.inv(b)); - } - - square(a) { - const ab = this.F.mul(a[0] , a[1]); - - /* - [ - (a + b) * (a + non_residue * b) - ab - non_residue * ab, - ab + ab - ]; - */ - - return [ - this.F.sub( - this.F.mul( - this.F.add(a[0], a[1]) , - this.F.add( - a[0] , - this._mulByNonResidue(a[1]))), - this.F.add( - ab, - this._mulByNonResidue(ab))), - this.F.add(ab, ab) - ]; - } - - isZero(a) { - return this.F.isZero(a[0]) && this.F.isZero(a[1]); - } - - eq(a, b) { - return this.F.eq(a[0], b[0]) && this.F.eq(a[1], b[1]); - } - - mulScalar(base, e) { - return mulScalar(this, base, e); - } - - pow(base, e) { - return exp$3(this, base, e); - } - - exp(base, e) { - return exp$3(this, base, e); - } - - toString(a) { - return `[ ${this.F.toString(a[0])} , ${this.F.toString(a[1])} ]`; - } - - fromRng(rng) { - const c0 = this.F.fromRng(rng); - const c1 = this.F.fromRng(rng); - return [c0, c1]; - } - - gt(a, b) { - if (this.F.gt(a[0], b[0])) return true; - if (this.F.gt(b[0], a[0])) return false; - if (this.F.gt(a[1], b[1])) return true; - return false; - } - - geq(a, b) { - return this.gt(a, b) || this.eq(a, b); - } - - lt(a, b) { - return !this.geq(a,b); - } - - leq(a, b) { - return !this.gt(a,b); - } - - neq(a, b) { - return !this.eq(a,b); - } - - random() { - return [this.F.random(), this.F.random()]; - } - - - toRprLE(buff, o, e) { - this.F.toRprLE(buff, o, e[0]); - this.F.toRprLE(buff, o+this.F.n8, e[1]); - } - - toRprBE(buff, o, e) { - this.F.toRprBE(buff, o, e[1]); - this.F.toRprBE(buff, o+this.F.n8, e[0]); - } - - toRprLEM(buff, o, e) { - this.F.toRprLEM(buff, o, e[0]); - this.F.toRprLEM(buff, o+this.F.n8, e[1]); - } - - - toRprBEM(buff, o, e) { - this.F.toRprBEM(buff, o, e[1]); - this.F.toRprBEM(buff, o+this.F.n8, e[0]); - } - - fromRprLE(buff, o) { - o = o || 0; - const c0 = this.F.fromRprLE(buff, o); - const c1 = this.F.fromRprLE(buff, o+this.F.n8); - return [c0, c1]; - } - - fromRprBE(buff, o) { - o = o || 0; - const c1 = this.F.fromRprBE(buff, o); - const c0 = this.F.fromRprBE(buff, o+this.F.n8); - return [c0, c1]; - } - - fromRprLEM(buff, o) { - o = o || 0; - const c0 = this.F.fromRprLEM(buff, o); - const c1 = this.F.fromRprLEM(buff, o+this.F.n8); - return [c0, c1]; - } - - fromRprBEM(buff, o) { - o = o || 0; - const c1 = this.F.fromRprBEM(buff, o); - const c0 = this.F.fromRprBEM(buff, o+this.F.n8); - return [c0, c1]; - } - -} - -/* - Copyright 2018 0kims association. - - This file is part of snarkjs. - - snarkjs is a free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as published by the - Free Software Foundation, either version 3 of the License, or (at your option) - any later version. - - snarkjs is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - snarkjs. If not, see . -*/ - -class F3Field { - constructor(F, nonResidue) { - this.type="F3"; - this.F = F; - this.zero = [this.F.zero, this.F.zero, this.F.zero]; - this.one = [this.F.one, this.F.zero, this.F.zero]; - this.negone = this.neg(this.one); - this.nonResidue = nonResidue; - this.m = F.m*3; - this.p = F.p; - this.n64 = F.n64*3; - this.n32 = this.n64*2; - this.n8 = this.n64*8; - } - - _mulByNonResidue(a) { - return this.F.mul(this.nonResidue, a); - } - - copy(a) { - return [this.F.copy(a[0]), this.F.copy(a[1]), this.F.copy(a[2])]; - } - - add(a, b) { - return [ - this.F.add(a[0], b[0]), - this.F.add(a[1], b[1]), - this.F.add(a[2], b[2]) - ]; - } - - double(a) { - return this.add(a,a); - } - - sub(a, b) { - return [ - this.F.sub(a[0], b[0]), - this.F.sub(a[1], b[1]), - this.F.sub(a[2], b[2]) - ]; - } - - neg(a) { - return this.sub(this.zero, a); - } - - mul(a, b) { - - const aA = this.F.mul(a[0] , b[0]); - const bB = this.F.mul(a[1] , b[1]); - const cC = this.F.mul(a[2] , b[2]); - - return [ - this.F.add( - aA, - this._mulByNonResidue( - this.F.sub( - this.F.mul( - this.F.add(a[1], a[2]), - this.F.add(b[1], b[2])), - this.F.add(bB, cC)))), // aA + non_residue*((b+c)*(B+C)-bB-cC), - - this.F.add( - this.F.sub( - this.F.mul( - this.F.add(a[0], a[1]), - this.F.add(b[0], b[1])), - this.F.add(aA, bB)), - this._mulByNonResidue( cC)), // (a+b)*(A+B)-aA-bB+non_residue*cC - - this.F.add( - this.F.sub( - this.F.mul( - this.F.add(a[0], a[2]), - this.F.add(b[0], b[2])), - this.F.add(aA, cC)), - bB)]; // (a+c)*(A+C)-aA+bB-cC) - } - - inv(a) { - const t0 = this.F.square(a[0]); // t0 = a^2 ; - const t1 = this.F.square(a[1]); // t1 = b^2 ; - const t2 = this.F.square(a[2]); // t2 = c^2; - const t3 = this.F.mul(a[0],a[1]); // t3 = ab - const t4 = this.F.mul(a[0],a[2]); // t4 = ac - const t5 = this.F.mul(a[1],a[2]); // t5 = bc; - // c0 = t0 - non_residue * t5; - const c0 = this.F.sub(t0, this._mulByNonResidue(t5)); - // c1 = non_residue * t2 - t3; - const c1 = this.F.sub(this._mulByNonResidue(t2), t3); - const c2 = this.F.sub(t1, t4); // c2 = t1-t4 - - // t6 = (a * c0 + non_residue * (c * c1 + b * c2)).inv(); - const t6 = - this.F.inv( - this.F.add( - this.F.mul(a[0], c0), - this._mulByNonResidue( - this.F.add( - this.F.mul(a[2], c1), - this.F.mul(a[1], c2))))); - - return [ - this.F.mul(t6, c0), // t6*c0 - this.F.mul(t6, c1), // t6*c1 - this.F.mul(t6, c2)]; // t6*c2 - } - - div(a, b) { - return this.mul(a, this.inv(b)); - } - - square(a) { - const s0 = this.F.square(a[0]); // s0 = a^2 - const ab = this.F.mul(a[0], a[1]); // ab = a*b - const s1 = this.F.add(ab, ab); // s1 = 2ab; - const s2 = this.F.square( - this.F.add(this.F.sub(a[0],a[1]), a[2])); // s2 = (a - b + c)^2; - const bc = this.F.mul(a[1],a[2]); // bc = b*c - const s3 = this.F.add(bc, bc); // s3 = 2*bc - const s4 = this.F.square(a[2]); // s4 = c^2 - - - return [ - this.F.add( - s0, - this._mulByNonResidue(s3)), // s0 + non_residue * s3, - this.F.add( - s1, - this._mulByNonResidue(s4)), // s1 + non_residue * s4, - this.F.sub( - this.F.add( this.F.add(s1, s2) , s3 ), - this.F.add(s0, s4))]; // s1 + s2 + s3 - s0 - s4 - } - - isZero(a) { - return this.F.isZero(a[0]) && this.F.isZero(a[1]) && this.F.isZero(a[2]); - } - - eq(a, b) { - return this.F.eq(a[0], b[0]) && this.F.eq(a[1], b[1]) && this.F.eq(a[2], b[2]); - } - - affine(a) { - return [this.F.affine(a[0]), this.F.affine(a[1]), this.F.affine(a[2])]; - } - - mulScalar(base, e) { - return mulScalar(this, base, e); - } - - pow(base, e) { - return exp$3(this, base, e); - } - - exp(base, e) { - return exp$3(this, base, e); - } - - toString(a) { - return `[ ${this.F.toString(a[0])} , ${this.F.toString(a[1])}, ${this.F.toString(a[2])} ]`; - } - - fromRng(rng) { - const c0 = this.F.fromRng(rng); - const c1 = this.F.fromRng(rng); - const c2 = this.F.fromRng(rng); - return [c0, c1, c2]; - } - - gt(a, b) { - if (this.F.gt(a[0], b[0])) return true; - if (this.F.gt(b[0], a[0])) return false; - if (this.F.gt(a[1], b[1])) return true; - if (this.F.gt(b[1], a[1])) return false; - if (this.F.gt(a[2], b[2])) return true; - return false; - } - - - geq(a, b) { - return this.gt(a, b) || this.eq(a, b); - } - - lt(a, b) { - return !this.geq(a,b); - } - - leq(a, b) { - return !this.gt(a,b); - } - - neq(a, b) { - return !this.eq(a,b); - } - - random() { - return [this.F.random(), this.F.random(), this.F.random()]; - } - - - toRprLE(buff, o, e) { - this.F.toRprLE(buff, o, e[0]); - this.F.toRprLE(buff, o+this.F.n8, e[1]); - this.F.toRprLE(buff, o+this.F.n8*2, e[2]); - } - - toRprBE(buff, o, e) { - this.F.toRprBE(buff, o, e[2]); - this.F.toRprBE(buff, o+this.F.n8, e[1]); - this.F.toRprBE(buff, o+this.F.n8*2, e[0]); - } - - toRprLEM(buff, o, e) { - this.F.toRprLEM(buff, o, e[0]); - this.F.toRprLEM(buff, o+this.F.n8, e[1]); - this.F.toRprLEM(buff, o+this.F.n8*2, e[2]); - } - - - toRprBEM(buff, o, e) { - this.F.toRprBEM(buff, o, e[2]); - this.F.toRprBEM(buff, o+this.F.n8, e[1]); - this.F.toRprBEM(buff, o+this.F.n8*2, e[0]); - } - - fromRprLE(buff, o) { - o = o || 0; - const c0 = this.F.fromRprLE(buff, o); - const c1 = this.F.fromRprLE(buff, o+this.n8); - const c2 = this.F.fromRprLE(buff, o+this.n8*2); - return [c0, c1, c2]; - } - - fromRprBE(buff, o) { - o = o || 0; - const c2 = this.F.fromRprBE(buff, o); - const c1 = this.F.fromRprBE(buff, o+this.n8); - const c0 = this.F.fromRprBE(buff, o+this.n8*2); - return [c0, c1, c2]; - } - - fromRprLEM(buff, o) { - o = o || 0; - const c0 = this.F.fromRprLEM(buff, o); - const c1 = this.F.fromRprLEM(buff, o+this.n8); - const c2 = this.F.fromRprLEM(buff, o+this.n8*2); - return [c0, c1, c2]; - } - - fromRprBEM(buff, o) { - o = o || 0; - const c2 = this.F.fromRprBEM(buff, o); - const c1 = this.F.fromRprBEM(buff, o+this.n8); - const c0 = this.F.fromRprBEM(buff, o+this.n8*2); - return [c0, c1, c2]; - } - -} - -/* - Copyright 2018 0kims association. - - This file is part of snarkjs. - - snarkjs is a free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as published by the - Free Software Foundation, either version 3 of the License, or (at your option) - any later version. - - snarkjs is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - snarkjs. If not, see . -*/ - - -function isGreatest(F, a) { - if (Array.isArray(a)) { - for (let i=a.length-1; i>=0; i--) { - if (!F.F.isZero(a[i])) { - return isGreatest(F.F, a[i]); - } - } - return 0; - } else { - const na = F.neg(a); - return gt$2(a, na); - } -} - - -class EC { - - constructor(F, g) { - this.F = F; - this.g = g; - if (this.g.length == 2) this.g[2] = this.F.one; - this.zero = [this.F.zero, this.F.one, this.F.zero]; - } - - add(p1, p2) { - - const F = this.F; - - if (this.eq(p1, this.zero)) return p2; - if (this.eq(p2, this.zero)) return p1; - - const res = new Array(3); - - const Z1Z1 = F.square( p1[2] ); - const Z2Z2 = F.square( p2[2] ); - - const U1 = F.mul( p1[0] , Z2Z2 ); // U1 = X1 * Z2Z2 - const U2 = F.mul( p2[0] , Z1Z1 ); // U2 = X2 * Z1Z1 - - const Z1_cubed = F.mul( p1[2] , Z1Z1); - const Z2_cubed = F.mul( p2[2] , Z2Z2); - - const S1 = F.mul( p1[1] , Z2_cubed); // S1 = Y1 * Z2 * Z2Z2 - const S2 = F.mul( p2[1] , Z1_cubed); // S2 = Y2 * Z1 * Z1Z1 - - if (F.eq(U1,U2) && F.eq(S1,S2)) { - return this.double(p1); - } - - const H = F.sub( U2 , U1 ); // H = U2-U1 - - const S2_minus_S1 = F.sub( S2 , S1 ); - - const I = F.square( F.add(H,H) ); // I = (2 * H)^2 - const J = F.mul( H , I ); // J = H * I - - const r = F.add( S2_minus_S1 , S2_minus_S1 ); // r = 2 * (S2-S1) - const V = F.mul( U1 , I ); // V = U1 * I - - res[0] = - F.sub( - F.sub( F.square(r) , J ), - F.add( V , V )); // X3 = r^2 - J - 2 * V - - const S1_J = F.mul( S1 , J ); - - res[1] = - F.sub( - F.mul( r , F.sub(V,res[0])), - F.add( S1_J,S1_J )); // Y3 = r * (V-X3)-2 S1 J - - res[2] = - F.mul( - H, - F.sub( - F.square( F.add(p1[2],p2[2]) ), - F.add( Z1Z1 , Z2Z2 ))); // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2) * H - - return res; - } - - neg(p) { - return [p[0], this.F.neg(p[1]), p[2]]; - } - - sub(a, b) { - return this.add(a, this.neg(b)); - } - - double(p) { - const F = this.F; - - const res = new Array(3); - - if (this.eq(p, this.zero)) return p; - - const A = F.square( p[0] ); // A = X1^2 - const B = F.square( p[1] ); // B = Y1^2 - const C = F.square( B ); // C = B^2 - - let D = - F.sub( - F.square( F.add(p[0] , B )), - F.add( A , C)); - D = F.add(D,D); // D = 2 * ((X1 + B)^2 - A - C) - - const E = F.add( F.add(A,A), A); // E = 3 * A - const FF =F.square( E ); // F = E^2 - - res[0] = F.sub( FF , F.add(D,D) ); // X3 = F - 2 D - - let eightC = F.add( C , C ); - eightC = F.add( eightC , eightC ); - eightC = F.add( eightC , eightC ); - - res[1] = - F.sub( - F.mul( - E, - F.sub( D, res[0] )), - eightC); // Y3 = E * (D - X3) - 8 * C - - const Y1Z1 = F.mul( p[1] , p[2] ); - res[2] = F.add( Y1Z1 , Y1Z1 ); // Z3 = 2 * Y1 * Z1 - - return res; - } - - timesScalar(base, e) { - return mulScalar(this, base, e); - } - - mulScalar(base, e) { - return mulScalar(this, base, e); - } - - affine(p) { - const F = this.F; - if (this.isZero(p)) { - return this.zero; - } else if (F.eq(p[2], F.one)) { - return p; - } else { - const Z_inv = F.inv(p[2]); - const Z2_inv = F.square(Z_inv); - const Z3_inv = F.mul(Z2_inv, Z_inv); - - const res = new Array(3); - res[0] = F.mul(p[0],Z2_inv); - res[1] = F.mul(p[1],Z3_inv); - res[2] = F.one; - - return res; - } - } - - multiAffine(arr) { - const keys = Object.keys(arr); - const F = this.F; - const accMul = new Array(keys.length+1); - accMul[0] = F.one; - for (let i = 0; i< keys.length; i++) { - if (F.eq(arr[keys[i]][2], F.zero)) { - accMul[i+1] = accMul[i]; - } else { - accMul[i+1] = F.mul(accMul[i], arr[keys[i]][2]); - } - } - - accMul[keys.length] = F.inv(accMul[keys.length]); - - for (let i = keys.length-1; i>=0; i--) { - if (F.eq(arr[keys[i]][2], F.zero)) { - accMul[i] = accMul[i+1]; - arr[keys[i]] = this.zero; - } else { - const Z_inv = F.mul(accMul[i], accMul[i+1]); - accMul[i] = F.mul(arr[keys[i]][2], accMul[i+1]); - - const Z2_inv = F.square(Z_inv); - const Z3_inv = F.mul(Z2_inv, Z_inv); - - arr[keys[i]][0] = F.mul(arr[keys[i]][0],Z2_inv); - arr[keys[i]][1] = F.mul(arr[keys[i]][1],Z3_inv); - arr[keys[i]][2] = F.one; - } - } - - } - - eq(p1, p2) { - const F = this.F; - - if (this.F.eq(p1[2], this.F.zero)) return this.F.eq(p2[2], this.F.zero); - if (this.F.eq(p2[2], this.F.zero)) return false; - - const Z1Z1 = F.square( p1[2] ); - const Z2Z2 = F.square( p2[2] ); - - const U1 = F.mul( p1[0] , Z2Z2 ); - const U2 = F.mul( p2[0] , Z1Z1 ); - - const Z1_cubed = F.mul( p1[2] , Z1Z1); - const Z2_cubed = F.mul( p2[2] , Z2Z2); - - const S1 = F.mul( p1[1] , Z2_cubed); - const S2 = F.mul( p2[1] , Z1_cubed); - - return (F.eq(U1,U2) && F.eq(S1,S2)); - } - - isZero(p) { - return this.F.isZero(p[2]); - } - - toString(p) { - const cp = this.affine(p); - return `[ ${this.F.toString(cp[0])} , ${this.F.toString(cp[1])} ]`; - } - - fromRng(rng) { - const F = this.F; - let P = []; - let greatest; - do { - P[0] = F.fromRng(rng); - greatest = rng.nextBool(); - const x3b = F.add(F.mul(F.square(P[0]), P[0]), this.b); - P[1] = F.sqrt(x3b); - } while ((P[1] == null)||(F.isZero[P])); - - const s = isGreatest(F, P[1]); - if (greatest ^ s) P[1] = F.neg(P[1]); - P[2] = F.one; - - if (this.cofactor) { - P = this.mulScalar(P, this.cofactor); - } - - P = this.affine(P); - - return P; - - } - - toRprLE(buff, o, p) { - p = this.affine(p); - if (this.isZero(p)) { - const BuffV = new Uint8Array(buff, o, this.F.n8*2); - BuffV.fill(0); - return; - } - this.F.toRprLE(buff, o, p[0]); - this.F.toRprLE(buff, o+this.F.n8, p[1]); - } - - toRprBE(buff, o, p) { - p = this.affine(p); - if (this.isZero(p)) { - const BuffV = new Uint8Array(buff, o, this.F.n8*2); - BuffV.fill(0); - return; - } - this.F.toRprBE(buff, o, p[0]); - this.F.toRprBE(buff, o+this.F.n8, p[1]); - } - - toRprLEM(buff, o, p) { - p = this.affine(p); - if (this.isZero(p)) { - const BuffV = new Uint8Array(buff, o, this.F.n8*2); - BuffV.fill(0); - return; - } - this.F.toRprLEM(buff, o, p[0]); - this.F.toRprLEM(buff, o+this.F.n8, p[1]); - } - - toRprLEJM(buff, o, p) { - p = this.affine(p); - if (this.isZero(p)) { - const BuffV = new Uint8Array(buff, o, this.F.n8*2); - BuffV.fill(0); - return; - } - this.F.toRprLEM(buff, o, p[0]); - this.F.toRprLEM(buff, o+this.F.n8, p[1]); - this.F.toRprLEM(buff, o+2*this.F.n8, p[2]); - } - - - toRprBEM(buff, o, p) { - p = this.affine(p); - if (this.isZero(p)) { - const BuffV = new Uint8Array(buff, o, this.F.n8*2); - BuffV.fill(0); - return; - } - this.F.toRprBEM(buff, o, p[0]); - this.F.toRprBEM(buff, o+this.F.n8, p[1]); - } - - fromRprLE(buff, o) { - o = o || 0; - const x = this.F.fromRprLE(buff, o); - const y = this.F.fromRprLE(buff, o+this.F.n8); - if (this.F.isZero(x) && this.F.isZero(y)) { - return this.zero; - } - return [x, y, this.F.one]; - } - - fromRprBE(buff, o) { - o = o || 0; - const x = this.F.fromRprBE(buff, o); - const y = this.F.fromRprBE(buff, o+this.F.n8); - if (this.F.isZero(x) && this.F.isZero(y)) { - return this.zero; - } - return [x, y, this.F.one]; - } - - fromRprLEM(buff, o) { - o = o || 0; - const x = this.F.fromRprLEM(buff, o); - const y = this.F.fromRprLEM(buff, o+this.F.n8); - if (this.F.isZero(x) && this.F.isZero(y)) { - return this.zero; - } - return [x, y, this.F.one]; - } - - fromRprLEJM(buff, o) { - o = o || 0; - const x = this.F.fromRprLEM(buff, o); - const y = this.F.fromRprLEM(buff, o+this.F.n8); - const z = this.F.fromRprLEM(buff, o+this.F.n8*2); - if (this.F.isZero(x) && this.F.isZero(y)) { - return this.zero; - } - return [x, y, z]; - } - - fromRprBEM(buff, o) { - o = o || 0; - const x = this.F.fromRprBEM(buff, o); - const y = this.F.fromRprBEM(buff, o+this.F.n8); - if (this.F.isZero(x) && this.F.isZero(y)) { - return this.zero; - } - return [x, y, this.F.one]; - } - - fromRprCompressed(buff, o) { - const F = this.F; - const v = new Uint8Array(buff.buffer, o, F.n8); - if (v[0] & 0x40) return this.zero; - const P = new Array(3); - - const greatest = ((v[0] & 0x80) != 0); - v[0] = v[0] & 0x7F; - P[0] = F.fromRprBE(buff, o); - if (greatest) v[0] = v[0] | 0x80; // set back again the old value - - const x3b = F.add(F.mul(F.square(P[0]), P[0]), this.b); - P[1] = F.sqrt(x3b); - - if (P[1] === null) { - throw new Error("Invalid Point!"); - } - - const s = isGreatest(F, P[1]); - if (greatest ^ s) P[1] = F.neg(P[1]); - P[2] = F.one; - - return P; - } - - toRprCompressed(buff, o, p) { - p = this.affine(p); - const v = new Uint8Array(buff.buffer, o, this.F.n8); - if (this.isZero(p)) { - v.fill(0); - v[0] = 0x40; - return; - } - this.F.toRprBE(buff, o, p[0]); - - if (isGreatest(this.F, p[1])) { - v[0] = v[0] | 0x80; - } - } - - - fromRprUncompressed(buff, o) { - if (buff[0] & 0x40) return this.zero; - - return this.fromRprBE(buff, o); - } - - toRprUncompressed(buff, o, p) { - this.toRprBE(buff, o, p); - - if (this.isZero(p)) { - buff[o] = buff[o] | 0x40; - } - } - - -} - -/* global BigInt */ - -function stringifyBigInts(o) { - if ((typeof(o) == "bigint") || o.eq !== undefined) { - return o.toString(10); - } else if (o instanceof Uint8Array) { - return fromRprLE(o, 0); - } else if (Array.isArray(o)) { - return o.map(stringifyBigInts); - } else if (typeof o == "object") { - const res = {}; - const keys = Object.keys(o); - keys.forEach( (k) => { - res[k] = stringifyBigInts(o[k]); - }); - return res; - } else { - return o; - } -} - -function unstringifyBigInts(o) { - if ((typeof(o) == "string") && (/^[0-9]+$/.test(o) )) { - return BigInt(o); - } else if (Array.isArray(o)) { - return o.map(unstringifyBigInts); - } else if (typeof o == "object") { - if (o===null) return null; - const res = {}; - const keys = Object.keys(o); - keys.forEach( (k) => { - res[k] = unstringifyBigInts(o[k]); - }); - return res; - } else { - return o; - } -} - -function beBuff2int(buff) { - let res = 0n; - let i = buff.length; - let offset = 0; - const buffV = new DataView(buff.buffer, buff.byteOffset, buff.byteLength); - while (i>0) { - if (i >= 4) { - i -= 4; - res += BigInt(buffV.getUint32(i)) << BigInt(offset*8); - offset += 4; - } else if (i >= 2) { - i -= 2; - res += BigInt(buffV.getUint16(i)) << BigInt(offset*8); - offset += 2; - } else { - i -= 1; - res += BigInt(buffV.getUint8(i)) << BigInt(offset*8); - offset += 1; - } - } - return res; -} - -function beInt2Buff(n, len) { - let r = n; - const buff = new Uint8Array(len); - const buffV = new DataView(buff.buffer); - let o = len; - while (o > 0) { - if (o-4 >= 0) { - o -= 4; - buffV.setUint32(o, Number(r & 0xFFFFFFFFn)); - r = r >> 32n; - } else if (o-2 >= 0) { - o -= 2; - buffV.setUint16(o, Number(r & 0xFFFFn)); - r = r >> 16n; - } else { - o -= 1; - buffV.setUint8(o, Number(r & 0xFFn)); - r = r >> 8n; - } - } - if (r) { - throw new Error("Number does not fit in this length"); - } - return buff; -} - - -function leBuff2int(buff) { - let res = 0n; - let i = 0; - const buffV = new DataView(buff.buffer, buff.byteOffset, buff.byteLength); - while (i> 32n; - } else if (o+2 <= len) { - buffV.setUint16(Number(o, r & 0xFFFFn), true ); - o += 2; - r = r >> 16n; - } else { - buffV.setUint8(Number(o, r & 0xFFn), true ); - o += 1; - r = r >> 8n; - } - } - if (r) { - throw new Error("Number does not fit in this length"); - } - return buff; -} - -var utils_native = /*#__PURE__*/Object.freeze({ - __proto__: null, - stringifyBigInts: stringifyBigInts, - unstringifyBigInts: unstringifyBigInts, - beBuff2int: beBuff2int, - beInt2Buff: beInt2Buff, - leBuff2int: leBuff2int, - leInt2Buff: leInt2Buff -}); - -function stringifyBigInts$1(o) { - if ((typeof(o) == "bigint") || o.eq !== undefined) { - return o.toString(10); - } else if (Array.isArray(o)) { - return o.map(stringifyBigInts$1); - } else if (typeof o == "object") { - const res = {}; - const keys = Object.keys(o); - keys.forEach( (k) => { - res[k] = stringifyBigInts$1(o[k]); - }); - return res; - } else { - return o; - } -} - -function unstringifyBigInts$1(o) { - if ((typeof(o) == "string") && (/^[0-9]+$/.test(o) )) { - return bigInt__default['default'](o); - } else if (Array.isArray(o)) { - return o.map(unstringifyBigInts$1); - } else if (typeof o == "object") { - const res = {}; - const keys = Object.keys(o); - keys.forEach( (k) => { - res[k] = unstringifyBigInts$1(o[k]); - }); - return res; - } else { - return o; - } -} - -function beBuff2int$1(buff) { - let res = bigInt__default['default'].zero; - for (let i=0; i=0)) { - let c = Number(r.and(bigInt__default['default']("255"))); - buff[o] = c; - o--; - r = r.shiftRight(8); - } - if (!r.eq(bigInt__default['default'].zero)) { - throw new Error("Number does not fit in this length"); - } - return buff; -} - - -function leBuff2int$1 (buff) { - let res = bigInt__default['default'].zero; - for (let i=0; i>=1; - } - return res; -} - -utils.bitReverse = function bitReverse(idx, bits) { - return ( - _revTable$1[idx >>> 24] | - (_revTable$1[(idx >>> 16) & 0xFF] << 8) | - (_revTable$1[(idx >>> 8) & 0xFF] << 16) | - (_revTable$1[idx & 0xFF] << 24) - ) >>> (32-bits); -}; - - -utils.log2 = function log2( V ) -{ - return( ( ( V & 0xFFFF0000 ) !== 0 ? ( V &= 0xFFFF0000, 16 ) : 0 ) | ( ( V & 0xFF00FF00 ) !== 0 ? ( V &= 0xFF00FF00, 8 ) : 0 ) | ( ( V & 0xF0F0F0F0 ) !== 0 ? ( V &= 0xF0F0F0F0, 4 ) : 0 ) | ( ( V & 0xCCCCCCCC ) !== 0 ? ( V &= 0xCCCCCCCC, 2 ) : 0 ) | ( ( V & 0xAAAAAAAA ) !== 0 ) ); -}; - -utils.buffReverseBits = function buffReverseBits(buff, eSize) { - const n = buff.byteLength /eSize; - const bits = utils.log2(n); - if (n != (1 << bits)) { - throw new Error("Invalid number of pointers"); - } - for (let i=0; ir) { - const tmp = buff.slice(i*eSize, (i+1)*eSize); - buff.set( buff.slice(r*eSize, (r+1)*eSize), i*eSize); - buff.set(tmp, r*eSize); - } - } -}; - -let { - bitReverse, - log2: log2$1, - buffReverseBits, - stringifyBigInts: stringifyBigInts$2, - unstringifyBigInts: unstringifyBigInts$2, - beBuff2int: beBuff2int$2, - beInt2Buff: beInt2Buff$2, - leBuff2int: leBuff2int$2, - leInt2Buff: leInt2Buff$2, -} = utils; - -var _utils = /*#__PURE__*/Object.freeze({ - __proto__: null, - bitReverse: bitReverse, - log2: log2$1, - buffReverseBits: buffReverseBits, - stringifyBigInts: stringifyBigInts$2, - unstringifyBigInts: unstringifyBigInts$2, - beBuff2int: beBuff2int$2, - beInt2Buff: beInt2Buff$2, - leBuff2int: leBuff2int$2, - leInt2Buff: leInt2Buff$2 -}); - -const PAGE_SIZE = 1<<30; - -class BigBuffer { - - constructor(size) { - this.buffers = []; - this.byteLength = size; - for (let i=0; i0) { - // bytes to copy from this page - const l = (o+r > PAGE_SIZE) ? (PAGE_SIZE -o) : r; - const srcView = new Uint8Array(this.buffers[p].buffer, this.buffers[p].byteOffset+o, l); - if (l == len) return srcView.slice(); - if (!buff) { - if (len <= PAGE_SIZE) { - buff = new Uint8Array(len); - } else { - buff = new BigBuffer(len); - } - } - buff.set(srcView, len-r); - r = r-l; - p ++; - o = 0; - } - - return buff; - } - - set(buff, offset) { - if (offset === undefined) offset = 0; - - const len = buff.byteLength; - - if (len==0) return; - - const firstPage = Math.floor(offset / PAGE_SIZE); - const lastPage = Math.floor((offset+len-1) / PAGE_SIZE); - - if (firstPage == lastPage) - return this.buffers[firstPage].set(buff, offset % PAGE_SIZE); - - - let p = firstPage; - let o = offset % PAGE_SIZE; - let r = len; - while (r>0) { - const l = (o+r > PAGE_SIZE) ? (PAGE_SIZE -o) : r; - const srcView = buff.slice( len -r, len -r+l); - const dstView = new Uint8Array(this.buffers[p].buffer, this.buffers[p].byteOffset + o, l); - dstView.set(srcView); - r = r-l; - p ++; - o = 0; - } - - } -} - -function buildBatchConvert(tm, fnName, sIn, sOut) { - return async function batchConvert(buffIn) { - const nPoints = Math.floor(buffIn.byteLength / sIn); - if ( nPoints * sIn !== buffIn.byteLength) { - throw new Error("Invalid buffer size"); - } - const pointsPerChunk = Math.floor(nPoints/tm.concurrency); - const opPromises = []; - for (let i=0; i=0; i--) { - this.w[i] = this.square(this.w[i+1]); - } - - if (!this.eq(this.w[0], this.one)) { - throw new Error("Error calculating roots of unity"); - } - - this.batchToMontgomery = buildBatchConvert(tm, prefix + "_batchToMontgomery", this.n8, this.n8); - this.batchFromMontgomery = buildBatchConvert(tm, prefix + "_batchFromMontgomery", this.n8, this.n8); - } - - - op2(opName, a, b) { - this.tm.setBuff(this.pOp1, a); - this.tm.setBuff(this.pOp2, b); - this.tm.instance.exports[this.prefix + opName](this.pOp1, this.pOp2, this.pOp3); - return this.tm.getBuff(this.pOp3, this.n8); - } - - op2Bool(opName, a, b) { - this.tm.setBuff(this.pOp1, a); - this.tm.setBuff(this.pOp2, b); - return !!this.tm.instance.exports[this.prefix + opName](this.pOp1, this.pOp2); - } - - op1(opName, a) { - this.tm.setBuff(this.pOp1, a); - this.tm.instance.exports[this.prefix + opName](this.pOp1, this.pOp3); - return this.tm.getBuff(this.pOp3, this.n8); - } - - op1Bool(opName, a) { - this.tm.setBuff(this.pOp1, a); - return !!this.tm.instance.exports[this.prefix + opName](this.pOp1, this.pOp3); - } - - add(a,b) { - return this.op2("_add", a, b); - } - - - eq(a,b) { - return this.op2Bool("_eq", a, b); - } - - isZero(a) { - return this.op1Bool("_isZero", a); - } - - sub(a,b) { - return this.op2("_sub", a, b); - } - - neg(a) { - return this.op1("_neg", a); - } - - inv(a) { - return this.op1("_inverse", a); - } - - toMontgomery(a) { - return this.op1("_toMontgomery", a); - } - - fromMontgomery(a) { - return this.op1("_fromMontgomery", a); - } - - mul(a,b) { - return this.op2("_mul", a, b); - } - - div(a, b) { - this.tm.setBuff(this.pOp1, a); - this.tm.setBuff(this.pOp2, b); - this.tm.instance.exports[this.prefix + "_inverse"](this.pOp2, this.pOp2); - this.tm.instance.exports[this.prefix + "_mul"](this.pOp1, this.pOp2, this.pOp3); - return this.tm.getBuff(this.pOp3, this.n8); - } - - square(a) { - return this.op1("_square", a); - } - - isSquare(a) { - return this.op1Bool("_isSquare", a); - } - - sqrt(a) { - return this.op1("_sqrt", a); - } - - exp(a, b) { - if (!(b instanceof Uint8Array)) { - b = toLEBuff(e$2(b)); - } - this.tm.setBuff(this.pOp1, a); - this.tm.setBuff(this.pOp2, b); - this.tm.instance.exports[this.prefix + "_exp"](this.pOp1, this.pOp2, b.byteLength, this.pOp3); - return this.tm.getBuff(this.pOp3, this.n8); - } - - isNegative(a) { - return this.op1Bool("_isNegative", a); - } - - e(a, b) { - if (a instanceof Uint8Array) return a; - let ra = e$2(a, b); - if (isNegative$2(ra)) { - ra = neg$2(ra); - if (gt$2(ra, this.p)) { - ra = mod$2(ra, this.p); - } - ra = sub$2(this.p, ra); - } else { - if (gt$2(ra, this.p)) { - ra = mod$2(ra, this.p); - } - } - const buff = leInt2Buff$2(ra, this.n8); - return this.toMontgomery(buff); - } - - toString(a, radix) { - const an = this.fromMontgomery(a); - const s = fromRprLE(an, 0); - return toString(s, radix); - } - - fromRng(rng) { - let v; - const buff = new Uint8Array(this.n8); - do { - v = zero; - for (let i=0; i memory.buffer.byteLength) { - const currentPages = memory.buffer.byteLength / 0x10000; - let requiredPages = Math.floor((u32[0] + length) / 0x10000)+1; - if (requiredPages>MAXMEM) requiredPages=MAXMEM; - memory.grow(requiredPages-currentPages); - } - return res; - } - - function allocBuffer(buffer) { - const p = alloc(buffer.byteLength); - setBuffer(p, buffer); - return p; - } - - function getBuffer(pointer, length) { - const u8 = new Uint8Array(memory.buffer); - return new Uint8Array(u8.buffer, u8.byteOffset + pointer, length); - } - - function setBuffer(pointer, buffer) { - const u8 = new Uint8Array(memory.buffer); - u8.set(new Uint8Array(buffer), pointer); - } - - function runTask(task) { - if (task[0].cmd == "INIT") { - return init(task[0]); - } - const ctx = { - vars: [], - out: [] - }; - const u32a = new Uint32Array(memory.buffer, 0, 1); - const oldAlloc = u32a[0]; - for (let i=0; i. -*/ - -// const MEM_SIZE = 1000; // Memory size in 64K Pakes (512Mb) -const MEM_SIZE = 25; // Memory size in 64K Pakes (1600Kb) - -class Deferred { - constructor() { - this.promise = new Promise((resolve, reject)=> { - this.reject = reject; - this.resolve = resolve; - }); - } -} - -function sleep(ms) { - return new Promise(resolve => setTimeout(resolve, ms)); -} - -function base64ToArrayBuffer(base64) { - if (process.browser) { - var binary_string = window.atob(base64); - var len = binary_string.length; - var bytes = new Uint8Array(len); - for (var i = 0; i < len; i++) { - bytes[i] = binary_string.charCodeAt(i); - } - return bytes; - } else { - return new Uint8Array(Buffer.from(base64, "base64")); - } -} - -function stringToBase64(str) { - if (process.browser) { - return window.btoa(str); - } else { - return Buffer.from(str).toString("base64"); - } -} - -const threadSource = stringToBase64("(" + thread.toString() + ")(self)"); -const workerSource = "data:application/javascript;base64," + threadSource; - - - -async function buildThreadManager(wasm, singleThread) { - const tm = new ThreadManager(); - - tm.memory = new WebAssembly.Memory({initial:MEM_SIZE}); - tm.u8 = new Uint8Array(tm.memory.buffer); - tm.u32 = new Uint32Array(tm.memory.buffer); - - const wasmModule = await WebAssembly.compile(base64ToArrayBuffer(wasm.code)); - - tm.instance = await WebAssembly.instantiate(wasmModule, { - env: { - "memory": tm.memory - } - }); - - tm.singleThread = singleThread; - tm.initalPFree = tm.u32[0]; // Save the Pointer to free space. - tm.pq = wasm.pq; - tm.pr = wasm.pr; - tm.pG1gen = wasm.pG1gen; - tm.pG1zero = wasm.pG1zero; - tm.pG2gen = wasm.pG2gen; - tm.pG2zero = wasm.pG2zero; - tm.pOneT = wasm.pOneT; - - // tm.pTmp0 = tm.alloc(curve.G2.F.n8*3); - // tm.pTmp1 = tm.alloc(curve.G2.F.n8*3); - - - if (singleThread) { - tm.code = base64ToArrayBuffer(wasm.code); - tm.taskManager = thread(); - await tm.taskManager([{ - cmd: "INIT", - init: MEM_SIZE, - code: tm.code.slice() - }]); - tm.concurrency = 1; - } else { - tm.workers = []; - tm.pendingDeferreds = []; - tm.working = []; - - let concurrency; - - if ((typeof(navigator) === "object") && navigator.hardwareConcurrency) { - concurrency = navigator.hardwareConcurrency; - } else { - concurrency = os__default['default'].cpus().length; - } - // Limit to 64 threads for memory reasons. - if (concurrency>64) concurrency=64; - tm.concurrency = concurrency; - - for (let i = 0; i 0); i++) { - if (this.working[i] == false) { - const work = this.actionQueue.shift(); - this.postAction(i, work.data, work.transfers, work.deferred); - } - } - } - - queueAction(actionData, transfers) { - const d = new Deferred(); - - if (this.singleThread) { - const res = this.taskManager(actionData); - d.resolve(res); - } else { - this.actionQueue.push({ - data: actionData, - transfers: transfers, - deferred: d - }); - this.processWorks(); - } - return d.promise; - } - - resetMemory() { - this.u32[0] = this.initalPFree; - } - - allocBuff(buff) { - const pointer = this.alloc(buff.byteLength); - this.setBuff(pointer, buff); - return pointer; - } - - getBuff(pointer, length) { - return this.u8.slice(pointer, pointer+ length); - } - - setBuff(pointer, buffer) { - this.u8.set(new Uint8Array(buffer), pointer); - } - - alloc(length) { - while (this.u32[0] & 3) this.u32[0]++; // Return always aligned pointers - const res = this.u32[0]; - this.u32[0] += length; - return res; - } - - async terminate() { - for (let i=0; i=0; i--) { - if (!G.isZero(res)) { - for (let j=0; jMAX_CHUNK_SIZE) chunkSize = MAX_CHUNK_SIZE; - if (chunkSize { - if (logger) logger.debug(`Multiexp end: ${logText}: ${i}/${nPoints}`); - return r; - })); - } - - const result = await Promise.all(opPromises); - - let res = G.zero; - for (let i=result.length-1; i>=0; i--) { - res = G.add(res, result[i]); - } - - return res; - } - - G.multiExp = async function multiExpAffine(buffBases, buffScalars, logger, logText) { - return await _multiExp(buffBases, buffScalars, "jacobian", logger, logText); - }; - G.multiExpAffine = async function multiExpAffine(buffBases, buffScalars, logger, logText) { - return await _multiExp(buffBases, buffScalars, "affine", logger, logText); - }; -} - -function buildFFT(curve, groupName) { - const G = curve[groupName]; - const Fr = curve.Fr; - const tm = G.tm; - async function _fft(buff, inverse, inType, outType, logger, loggerTxt) { - - inType = inType || "affine"; - outType = outType || "affine"; - const MAX_BITS_THREAD = 14; - - let sIn, sMid, sOut, fnIn2Mid, fnMid2Out, fnFFTMix, fnFFTJoin, fnFFTFinal; - if (groupName == "G1") { - if (inType == "affine") { - sIn = G.F.n8*2; - fnIn2Mid = "g1m_batchToJacobian"; - } else { - sIn = G.F.n8*3; - } - sMid = G.F.n8*3; - if (inverse) { - fnFFTFinal = "g1m_fftFinal"; - } - fnFFTJoin = "g1m_fftJoin"; - fnFFTMix = "g1m_fftMix"; - - if (outType == "affine") { - sOut = G.F.n8*2; - fnMid2Out = "g1m_batchToAffine"; - } else { - sOut = G.F.n8*3; - } - - } else if (groupName == "G2") { - if (inType == "affine") { - sIn = G.F.n8*2; - fnIn2Mid = "g2m_batchToJacobian"; - } else { - sIn = G.F.n8*3; - } - sMid = G.F.n8*3; - if (inverse) { - fnFFTFinal = "g2m_fftFinal"; - } - fnFFTJoin = "g2m_fftJoin"; - fnFFTMix = "g2m_fftMix"; - if (outType == "affine") { - sOut = G.F.n8*2; - fnMid2Out = "g2m_batchToAffine"; - } else { - sOut = G.F.n8*3; - } - } else if (groupName == "Fr") { - sIn = G.n8; - sMid = G.n8; - sOut = G.n8; - if (inverse) { - fnFFTFinal = "frm_fftFinal"; - } - fnFFTMix = "frm_fftMix"; - fnFFTJoin = "frm_fftJoin"; - } - - - let returnArray = false; - if (Array.isArray(buff)) { - buff = curve.array2buffer(buff, sIn); - returnArray = true; - } - - const nPoints = buff.byteLength / sIn; - const bits = log2$1(nPoints); - - if ((1 << bits) != nPoints) { - throw new Error("fft must be multiple of 2" ); - } - - if (bits == Fr.s +1) { - let buffOut; - - if (inverse) { - buffOut = await _fftExtInv(buff, inType, outType, logger, loggerTxt); - } else { - buffOut = await _fftExt(buff, inType, outType, logger, loggerTxt); - } - - if (returnArray) { - return curve.buffer2array(buffOut, sOut); - } else { - return buffOut; - } - } - - let inv; - if (inverse) { - inv = Fr.inv(Fr.e(nPoints)); - } - - let buffOut; - - buffReverseBits(buff, sIn); - - let chunks; - let pointsInChunk = Math.min(1 << MAX_BITS_THREAD, nPoints); - let nChunks = nPoints / pointsInChunk; - - while ((nChunks < tm.concurrency)&&(pointsInChunk>=16)) { - nChunks *= 2; - pointsInChunk /= 2; - } - - const l2Chunk = log2$1(pointsInChunk); - - const promises = []; - for (let i = 0; i< nChunks; i++) { - if (logger) logger.debug(`${loggerTxt}: fft ${bits} mix start: ${i}/${nChunks}`); - const task = []; - task.push({cmd: "ALLOC", var: 0, len: sMid*pointsInChunk}); - const buffChunk = buff.slice( (pointsInChunk * i)*sIn, (pointsInChunk * (i+1))*sIn); - task.push({cmd: "SET", var: 0, buff: buffChunk}); - if (fnIn2Mid) { - task.push({cmd: "CALL", fnName:fnIn2Mid, params: [{var:0}, {val: pointsInChunk}, {var: 0}]}); - } - for (let j=1; j<=l2Chunk;j++) { - task.push({cmd: "CALL", fnName:fnFFTMix, params: [{var:0}, {val: pointsInChunk}, {val: j}]}); - } - - if (l2Chunk==bits) { - if (fnFFTFinal) { - task.push({cmd: "ALLOCSET", var: 1, buff: inv}); - task.push({cmd: "CALL", fnName: fnFFTFinal, params:[ - {var: 0}, - {val: pointsInChunk}, - {var: 1}, - ]}); - } - if (fnMid2Out) { - task.push({cmd: "CALL", fnName:fnMid2Out, params: [{var:0}, {val: pointsInChunk}, {var: 0}]}); - } - task.push({cmd: "GET", out: 0, var: 0, len: pointsInChunk*sOut}); - } else { - task.push({cmd: "GET", out:0, var: 0, len: sMid*pointsInChunk}); - } - promises.push(tm.queueAction(task).then( (r) => { - if (logger) logger.debug(`${loggerTxt}: fft ${bits} mix end: ${i}/${nChunks}`); - return r; - })); - } - - chunks = await Promise.all(promises); - for (let i = 0; i< nChunks; i++) chunks[i] = chunks[i][0]; - - for (let i = l2Chunk+1; i<=bits; i++) { - if (logger) logger.debug(`${loggerTxt}: fft ${bits} join: ${i}/${bits}`); - const nGroups = 1 << (bits - i); - const nChunksPerGroup = nChunks / nGroups; - const opPromises = []; - for (let j=0; j { - if (logger) logger.debug(`${loggerTxt}: fft ${bits} join ${i}/${bits} ${j+1}/${nGroups} ${k}/${nChunksPerGroup/2}`); - return r; - })); - } - } - - const res = await Promise.all(opPromises); - for (let j=0; j0; i--) { - buffOut.set(chunks[i], p); - p += pointsInChunk*sOut; - delete chunks[i]; // Liberate mem - } - buffOut.set(chunks[0].slice(0, (pointsInChunk-1)*sOut), p); - delete chunks[0]; - } else { - for (let i=0; i (1<<28)) { - buffOut = new BigBuffer(res1[0].byteLength*2); - } else { - buffOut = new Uint8Array(res1[0].byteLength*2); - } - - buffOut.set(res1[0]); - buffOut.set(res1[1], res1[0].byteLength); - - return buffOut; +function leBuff2int$1 (buff) { + let res = bigInt__default['default'].zero; + for (let i=0; i (1<<28)) { - buffOut = new BigBuffer(res1[0].byteLength*2); - } else { - buffOut = new Uint8Array(res1[0].byteLength*2); - } - - buffOut.set(res1[0]); - buffOut.set(res1[1], res1[0].byteLength); - - return buffOut; +function leInt2Buff$1(n, len) { + let r = n; + let o =0; + const buff = new Uint8Array(len); + while ((r.gt(bigInt__default['default'].zero))&&(o MAX_CHUNK_SIZE) chunkSize = MAX_CHUNK_SIZE; - - const opPromises = []; - - for (let i=0; i { - if (logger) logger.debug(`${loggerTxt}: fftJoinExt End: ${i}/${nPoints}`); - return r; - }) - ); - } - - const result = await Promise.all(opPromises); - - let fullBuffOut1; - let fullBuffOut2; - if (nPoints * sOut > 1<<28) { - fullBuffOut1 = new BigBuffer(nPoints*sOut); - fullBuffOut2 = new BigBuffer(nPoints*sOut); - } else { - fullBuffOut1 = new Uint8Array(nPoints*sOut); - fullBuffOut2 = new Uint8Array(nPoints*sOut); - } - - let p =0; - for (let i=0; i Fr.s+1) { - if (logger) logger.error("lagrangeEvaluations input too big"); - throw new Error("lagrangeEvaluations input too big"); - } - - let t0 = buff.slice(0, buff.byteLength/2); - let t1 = buff.slice(buff.byteLength/2, buff.byteLength); - - - const shiftToSmallM = Fr.exp(Fr.shift, nPoints/2); - const sConst = Fr.inv( Fr.sub(Fr.one, shiftToSmallM)); - - [t0, t1] = await _fftJoinExt(t0, t1, "prepareLagrangeEvaluation", sConst, Fr.shiftInv, inType, "jacobian", logger, loggerTxt + " prep"); - - const promises = []; - - promises.push( _fft(t0, true, "jacobian", outType, logger, loggerTxt + " t0")); - promises.push( _fft(t1, true, "jacobian", outType, logger, loggerTxt + " t1")); - - [t0, t1] = await Promise.all(promises); - - let buffOut; - if (t0.byteLength > (1<<28)) { - buffOut = new BigBuffer(t0.byteLength*2); - } else { - buffOut = new Uint8Array(t0.byteLength*2); - } - - buffOut.set(t0); - buffOut.set(t1, t0.byteLength); - - return buffOut; - }; - - G.fftMix = async function fftMix(buff) { - const sG = G.F.n8*3; - let fnName, fnFFTJoin; - if (groupName == "G1") { - fnName = "g1m_fftMix"; - fnFFTJoin = "g1m_fftJoin"; - } else if (groupName == "G2") { - fnName = "g2m_fftMix"; - fnFFTJoin = "g2m_fftJoin"; - } else if (groupName == "Fr") { - fnName = "frm_fftMix"; - fnFFTJoin = "frm_fftJoin"; - } else { - throw new Error("Invalid group"); - } - - const nPoints = Math.floor(buff.byteLength / sG); - const power = log2$1(nPoints); - - let nChunks = 1 << log2$1(tm.concurrency); - - if (nPoints <= nChunks*2) nChunks = 1; - - const pointsPerChunk = nPoints / nChunks; - - const powerChunk = log2$1(pointsPerChunk); - - const opPromises = []; - for (let i=0; i=0; i--) { - fullBuffOut.set(result[i][0], p); - p+=result[i][0].byteLength; - } - - return fullBuffOut; - }; + return buff; } -async function buildEngine(params) { - - const tm = await buildThreadManager(params.wasm, params.singleThread); - - - const curve = {}; - - curve.q = e$2(params.wasm.q); - curve.r = e$2(params.wasm.r); - curve.name = params.name; - curve.tm = tm; - curve.prePSize = params.wasm.prePSize; - curve.preQSize = params.wasm.preQSize; - curve.Fr = new WasmField1(tm, "frm", params.n8r, params.r); - curve.F1 = new WasmField1(tm, "f1m", params.n8q, params.q); - curve.F2 = new WasmField2(tm, "f2m", curve.F1); - curve.G1 = new WasmCurve(tm, "g1m", curve.F1, params.wasm.pG1gen, params.wasm.pG1b, params.cofactorG1); - curve.G2 = new WasmCurve(tm, "g2m", curve.F2, params.wasm.pG2gen, params.wasm.pG2b, params.cofactorG2); - curve.F6 = new WasmField3(tm, "f6m", curve.F2); - curve.F12 = new WasmField2(tm, "ftm", curve.F6); - - curve.Gt = curve.F12; - - buildBatchApplyKey(curve, "G1"); - buildBatchApplyKey(curve, "G2"); - buildBatchApplyKey(curve, "Fr"); - - buildMultiexp(curve, "G1"); - buildMultiexp(curve, "G2"); - - buildFFT(curve, "G1"); - buildFFT(curve, "G2"); - buildFFT(curve, "Fr"); - - buildPairing(curve); - - curve.array2buffer = function(arr, sG) { - const buff = new Uint8Array(sG*arr.length); - - for (let i=0; i>=1; } - - return curve; + return res; } -global.curve_bls12381 = null; - -async function buildBls12381(singleThread) { - - if ((!singleThread)&&(global.curve_bls12381)) return global.curve_bls12381; - const params = { - name: "bls12381", - wasm: wasmcurves__default['default'].bls12381_wasm, - q: e$2("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", 16), - r: e$2("73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001", 16), - n8q: 48, - n8r: 32, - cofactorG1: e$2("0x396c8c005555e1568c00aaab0000aaab", 16), - cofactorG2: e$2("0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5", 16), - singleThread: singleThread ? true : false - }; - - const curve = await buildEngine(params); - curve.terminate = async function() { - if (!params.singleThread) { - global.curve_bls12381 = null; - await this.tm.terminate(); - } - }; - - return curve; -} +utils$1.bitReverse = function bitReverse(idx, bits) { + return ( + _revTable[idx >>> 24] | + (_revTable[(idx >>> 16) & 0xFF] << 8) | + (_revTable[(idx >>> 8) & 0xFF] << 16) | + (_revTable[idx & 0xFF] << 24) + ) >>> (32-bits); +}; -const bls12381r = e$2("73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001", 16); -const bn128r = e$2("21888242871839275222246405745257275088548364400416034343698204186575808495617"); -const bls12381q = e$2("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", 16); -const bn128q = e$2("21888242871839275222246405745257275088696311157297823662689037894645226208583"); +utils$1.log2 = function log2( V ) +{ + return( ( ( V & 0xFFFF0000 ) !== 0 ? ( V &= 0xFFFF0000, 16 ) : 0 ) | ( ( V & 0xFF00FF00 ) !== 0 ? ( V &= 0xFF00FF00, 8 ) : 0 ) | ( ( V & 0xF0F0F0F0 ) !== 0 ? ( V &= 0xF0F0F0F0, 4 ) : 0 ) | ( ( V & 0xCCCCCCCC ) !== 0 ? ( V &= 0xCCCCCCCC, 2 ) : 0 ) | ( ( V & 0xAAAAAAAA ) !== 0 ) ); +}; -async function getCurveFromR(r, singleThread) { - let curve; - if (eq$2(r, bn128r)) { - curve = await buildBn128(singleThread); - } else if (eq$2(r, bls12381r)) { - curve = await buildBn128(singleThread); - } else { - throw new Error(`Curve not supported: ${toString(r)}`); +utils$1.buffReverseBits = function buffReverseBits(buff, eSize) { + const n = buff.byteLength /eSize; + const bits = utils$1.log2(n); + if (n != (1 << bits)) { + throw new Error("Invalid number of pointers"); } - return curve; -} - -async function getCurveFromQ(q, singleThread) { - let curve; - if (eq$2(q, bn128q)) { - curve = await buildBn128(singleThread); - } else if (eq$2(q, bls12381q)) { - curve = await buildBn128(singleThread); - } else { - throw new Error(`Curve not supported: ${toString(q)}`); + for (let i=0; ir) { + const tmp = buff.slice(i*eSize, (i+1)*eSize); + buff.set( buff.slice(r*eSize, (r+1)*eSize), i*eSize); + buff.set(tmp, r*eSize); + } } - return curve; -} +}; -async function getCurveFromName(name, singleThread) { - let curve; - const normName = normalizeName(name); - if (["BN128", "BN254", "ALTBN128"].indexOf(normName) >= 0) { - curve = await buildBn128(singleThread); - } else if (["BLS12381"].indexOf(normName) >= 0) { - curve = await buildBn128(singleThread); - } else { - throw new Error(`Curve not supported: ${name}`); - } - return curve; +let { + bitReverse, + log2, + buffReverseBits, + stringifyBigInts, + unstringifyBigInts, + beBuff2int, + beInt2Buff, + leBuff2int, + leInt2Buff, +} = utils$1; - function normalizeName(n) { - return n.toUpperCase().match(/[A-Za-z0-9]+/g).join(""); - } +var _utils = /*#__PURE__*/Object.freeze({ + __proto__: null, + bitReverse: bitReverse, + log2: log2, + buffReverseBits: buffReverseBits, + stringifyBigInts: stringifyBigInts, + unstringifyBigInts: unstringifyBigInts, + beBuff2int: beBuff2int, + beInt2Buff: beInt2Buff, + leBuff2int: leBuff2int, + leInt2Buff: leInt2Buff +}); -} +const Scalar = _Scalar; +const utils = _utils; -const Scalar$1=_Scalar; -const utils$1 = _utils; - -exports.BigBuffer = BigBuffer; -exports.ChaCha = ChaCha; -exports.EC = EC; -exports.F1Field = F1Field; -exports.F2Field = F2Field; -exports.F3Field = F3Field; -exports.PolField = PolField; -exports.Scalar = Scalar$1; +exports.Scalar = Scalar; exports.ZqField = F1Field; -exports.buildBls12381 = buildBls12381; -exports.buildBn128 = buildBn128; -exports.getCurveFromName = getCurveFromName; -exports.getCurveFromQ = getCurveFromQ; -exports.getCurveFromR = getCurveFromR; -exports.utils = utils$1; +exports.utils = utils; diff --git a/main.js b/main.js index 1981557..3b24310 100644 --- a/main.js +++ b/main.js @@ -1,24 +1,7 @@ +import * as _Scalar from "./src/scalar.js"; +export const Scalar = _Scalar; -import * as _Scalar from "./src/scalar.js"; -export const Scalar=_Scalar; - -export {default as PolField} from "./src/polfield.js"; -export {default as F1Field} from "./src/f1field.js"; -export {default as F2Field} from "./src/f2field.js"; -export {default as F3Field} from "./src/f3field.js"; - -export {default as ZqField} from "./src/f1field.js"; - -export {default as EC} from "./src/ec.js"; - -export {default as buildBn128} from "./src/bn128.js"; -export {default as buildBls12381} from "./src/bls12381.js"; +export { default as ZqField } from "./src/f1field.js"; import * as _utils from "./src/utils.js"; export const utils = _utils; -export {default as ChaCha} from "./src/chacha.js"; - -export {default as BigBuffer} from "./src/bigbuffer.js"; - -export {getCurveFromR, getCurveFromQ, getCurveFromName} from "./src/curves.js"; - diff --git a/package-lock.json b/package-lock.json index f4ceb2e..891ec2d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,2387 +1,8 @@ { - "name": "ffjavascript", - "version": "0.2.35", - "lockfileVersion": 2, + "name": "@toruslabs/ffjavascript", + "version": "0.2.40", + "lockfileVersion": 1, "requires": true, - "packages": { - "": { - "version": "0.2.35", - "license": "GPL-3.0", - "dependencies": { - "big-integer": "^1.6.48", - "wasmcurves": "0.0.14", - "web-worker": "^1.0.0" - }, - "devDependencies": { - "blake2b": "^2.1.3", - "chai": "^4.2.0", - "eslint": "^6.8.0", - "mocha": "^8.2.1", - "rollup": "^2.38.5" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.12.13" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true - }, - "node_modules/@babel/highlight": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz", - "integrity": "sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.12.11", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "node_modules/@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", - "dev": true - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", - "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", - "dev": true, - "dependencies": { - "type-fest": "^0.11.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "node_modules/big-integer": { - "version": "1.6.48", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", - "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/blake2b": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/blake2b/-/blake2b-2.1.3.tgz", - "integrity": "sha512-pkDss4xFVbMb4270aCyGD3qLv92314Et+FsKzilCLxDz5DuZ2/1g3w4nmBbu6nKApPspnjG7JcwTjGZnduB1yg==", - "dev": true, - "dependencies": { - "blake2b-wasm": "^1.1.0", - "nanoassert": "^1.0.0" - } - }, - "node_modules/blake2b-wasm": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/blake2b-wasm/-/blake2b-wasm-1.1.7.tgz", - "integrity": "sha512-oFIHvXhlz/DUgF0kq5B1CqxIDjIJwh9iDeUUGQUcvgiGz7Wdw03McEO7CfLBy7QKGdsydcMCgO9jFNBAFCtFcA==", - "dev": true, - "dependencies": { - "nanoassert": "^1.0.0" - } - }, - "node_modules/blakejs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/chai": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.0.tgz", - "integrity": "sha512-/BFd2J30EcOwmdOgXvVsmM48l0Br0nmZPlO0uOW4XKh6kpsUumRXBgPV+IlaqFaqr9cYbeoZAM1Npx0i4A+aiA==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.0", - "type-detect": "^4.0.5" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", - "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", - "dev": true, - "dependencies": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.2", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.5.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.1.2" - } - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/cross-spawn/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.3", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", - "dev": true, - "dependencies": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, - "dependencies": { - "flat-cache": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "dependencies": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "dev": true, - "dependencies": { - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "engines": { - "node": ">=4.x" - } - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/inquirer": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", - "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.19", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.6.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/inquirer/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/inquirer/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/inquirer/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/inquirer/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", - "dev": true - }, - "node_modules/log-symbols": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", - "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/log-symbols/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/log-symbols/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/log-symbols/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/log-symbols/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/log-symbols/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mocha": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz", - "integrity": "sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w==", - "dev": true, - "dependencies": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.4.3", - "debug": "4.2.0", - "diff": "4.0.2", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.6", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.14.0", - "log-symbols": "4.0.0", - "minimatch": "3.0.4", - "ms": "2.1.2", - "nanoid": "3.1.12", - "serialize-javascript": "5.0.1", - "strip-json-comments": "3.1.1", - "supports-color": "7.2.0", - "which": "2.0.2", - "wide-align": "1.1.3", - "workerpool": "6.0.2", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 10.12.0" - } - }, - "node_modules/mocha/node_modules/debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/mocha/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, - "node_modules/nanoassert": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-1.1.0.tgz", - "integrity": "sha1-TzFS4JVA/eKMdvRLGbvNHVpCR40=", - "dev": true - }, - "node_modules/nanoid": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", - "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || >=13.7" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/readdirp": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", - "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true, - "engines": { - "node": ">=6.5.0" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/rollup": { - "version": "2.38.5", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.38.5.tgz", - "integrity": "sha512-VoWt8DysFGDVRGWuHTqZzT02J0ASgjVq/hPs9QcBOGMd7B+jfTr/iqMVEyOi901rE3xq+Deq66GzIT1yt7sGwQ==", - "dev": true, - "dependencies": { - "fsevents": "~2.3.1" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=10.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.1" - } - }, - "node_modules/rollup/node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/rxjs": { - "version": "6.6.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz", - "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true - }, - "node_modules/slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "node_modules/string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "dependencies": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/table/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/table/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/table/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/v8-compile-cache": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", - "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", - "dev": true - }, - "node_modules/wasmcurves": { - "version": "0.0.14", - "resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.0.14.tgz", - "integrity": "sha512-G1iMkxlRaQSdqQ1JrwHcU+awLmwyH6kFKfT8g9obd8MWe+u5oSdFXrODB0zmSI5aGGvJPG+4cAmqCGYv9R+7qg==", - "dependencies": { - "big-integer": "^1.6.42", - "blakejs": "^1.1.0" - } - }, - "node_modules/web-worker": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.0.0.tgz", - "integrity": "sha512-BzuMqeKVkKKwHV6tJuwePFcxYMxvC97D448mXTgh/CxXAB4sRtoV26gRPN+JDxsXRR7QZyioMV9O6NzQaASf7Q==" - }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "node_modules/wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "dependencies": { - "string-width": "^1.0.2 || 2" - } - }, - "node_modules/wide-align/node_modules/ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "dependencies": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/wide-align/node_modules/strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "dependencies": { - "ansi-regex": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/workerpool": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", - "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "node_modules/write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "dependencies": { - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", - "dev": true - }, - "node_modules/yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "dependencies": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "node_modules/yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser/node_modules/camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser/node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/yargs/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/yargs/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - } - } - }, "dependencies": { "@babel/code-frame": { "version": "7.12.13", @@ -2478,9 +99,9 @@ } }, "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -2581,22 +202,22 @@ "dev": true }, "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true }, "chai": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.0.tgz", - "integrity": "sha512-/BFd2J30EcOwmdOgXvVsmM48l0Br0nmZPlO0uOW4XKh6kpsUumRXBgPV+IlaqFaqr9cYbeoZAM1Npx0i4A+aiA==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", + "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", "dev": true, "requires": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", "deep-eql": "^3.0.1", "get-func-name": "^2.0.0", - "pathval": "^1.1.0", + "pathval": "^1.1.1", "type-detect": "^4.0.5" } }, @@ -2624,14 +245,14 @@ "dev": true }, "chokidar": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", - "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", "dev": true, "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", - "fsevents": "~2.1.2", + "fsevents": "~2.3.1", "glob-parent": "~5.1.0", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", @@ -2655,37 +276,23 @@ "dev": true }, "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" }, "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "ansi-regex": "^5.0.0" } } } @@ -2742,9 +349,9 @@ } }, "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true }, "deep-eql": { @@ -2763,9 +370,9 @@ "dev": true }, "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, "doctrine": { @@ -2783,6 +390,12 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -2834,6 +447,15 @@ "v8-compile-cache": "^2.0.3" } }, + "eslint-plugin-prettier": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz", + "integrity": "sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -2939,6 +561,12 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -3018,9 +646,9 @@ "dev": true }, "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "optional": true }, @@ -3397,9 +1025,9 @@ } }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true }, "mkdirp": { @@ -3412,46 +1040,43 @@ } }, "mocha": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz", - "integrity": "sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.3.2.tgz", + "integrity": "sha512-UdmISwr/5w+uXLPKspgoV7/RXZwKRTiTjJ2/AC5ZiEztIoOYdfKb19+9jNmEInzx5pBsCyJQzarAxqIGBNYJhg==", "dev": true, "requires": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.4.3", - "debug": "4.2.0", - "diff": "4.0.2", + "chokidar": "3.5.1", + "debug": "4.3.1", + "diff": "5.0.0", "escape-string-regexp": "4.0.0", "find-up": "5.0.0", "glob": "7.1.6", "growl": "1.10.5", "he": "1.2.0", - "js-yaml": "3.14.0", + "js-yaml": "4.0.0", "log-symbols": "4.0.0", "minimatch": "3.0.4", - "ms": "2.1.2", - "nanoid": "3.1.12", + "ms": "2.1.3", + "nanoid": "3.1.20", "serialize-javascript": "5.0.1", "strip-json-comments": "3.1.1", - "supports-color": "7.2.0", + "supports-color": "8.1.1", "which": "2.0.2", "wide-align": "1.1.3", - "workerpool": "6.0.2", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", + "workerpool": "6.1.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", "yargs-unparser": "2.0.0" }, "dependencies": { - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "dev": true, - "requires": { - "ms": "2.1.2" - } + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "escape-string-regexp": { "version": "4.0.0", @@ -3466,19 +1091,24 @@ "dev": true }, "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" } }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -3514,9 +1144,9 @@ "dev": true }, "nanoid": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", - "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", "dev": true }, "natural-compare": { @@ -3593,12 +1223,6 @@ "p-limit": "^3.0.2" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -3633,9 +1257,9 @@ "dev": true }, "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", "dev": true }, "prelude-ls": { @@ -3644,6 +1268,15 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -3686,12 +1319,6 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -3718,21 +1345,12 @@ } }, "rollup": { - "version": "2.38.5", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.38.5.tgz", - "integrity": "sha512-VoWt8DysFGDVRGWuHTqZzT02J0ASgjVq/hPs9QcBOGMd7B+jfTr/iqMVEyOi901rE3xq+Deq66GzIT1yt7sGwQ==", + "version": "2.45.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.45.2.tgz", + "integrity": "sha512-kRRU7wXzFHUzBIv0GfoFFIN3m9oteY4uAsKllIpQDId5cfnkWF2J130l+27dzDju0E6MScKiV0ZM5Bw8m4blYQ==", "dev": true, "requires": { "fsevents": "~2.3.1" - }, - "dependencies": { - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - } } }, "run-async": { @@ -3777,12 +1395,6 @@ "randombytes": "^2.1.0" } }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -4015,12 +1627,6 @@ "isexe": "^2.0.0" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, "wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", @@ -4070,43 +1676,53 @@ "dev": true }, "workerpool": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", - "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", "dev": true }, "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "ansi-regex": "^5.0.0" } } } @@ -4127,106 +1743,31 @@ } }, "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - }, - "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - } + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" } }, "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true }, "yargs-unparser": { "version": "2.0.0", @@ -4238,20 +1779,6 @@ "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" - }, - "dependencies": { - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - } } }, "yocto-queue": { diff --git a/package.json b/package.json index baf9dd7..a269708 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "ffjavascript", + "name": "@toruslabs/ffjavascript", "type": "module", - "version": "0.2.35", + "version": "0.2.40", "description": "Finite Field Library in Javascript", "main": "./build/main.cjs", "module": "./main.js", @@ -38,9 +38,10 @@ }, "devDependencies": { "blake2b": "^2.1.3", - "chai": "^4.2.0", + "chai": "^4.3.4", "eslint": "^6.8.0", - "mocha": "^8.2.1", - "rollup": "^2.38.5" + "eslint-plugin-prettier": "^3.4.0", + "mocha": "^8.3.2", + "rollup": "^2.45.2" } } diff --git a/src/bigbuffer.js b/src/bigbuffer.js deleted file mode 100644 index 91fb93b..0000000 --- a/src/bigbuffer.js +++ /dev/null @@ -1,82 +0,0 @@ - -const PAGE_SIZE = 1<<30; - -export default class BigBuffer { - - constructor(size) { - this.buffers = []; - this.byteLength = size; - for (let i=0; i0) { - // bytes to copy from this page - const l = (o+r > PAGE_SIZE) ? (PAGE_SIZE -o) : r; - const srcView = new Uint8Array(this.buffers[p].buffer, this.buffers[p].byteOffset+o, l); - if (l == len) return srcView.slice(); - if (!buff) { - if (len <= PAGE_SIZE) { - buff = new Uint8Array(len); - } else { - buff = new BigBuffer(len); - } - } - buff.set(srcView, len-r); - r = r-l; - p ++; - o = 0; - } - - return buff; - } - - set(buff, offset) { - if (offset === undefined) offset = 0; - - const len = buff.byteLength; - - if (len==0) return; - - const firstPage = Math.floor(offset / PAGE_SIZE); - const lastPage = Math.floor((offset+len-1) / PAGE_SIZE); - - if (firstPage == lastPage) - return this.buffers[firstPage].set(buff, offset % PAGE_SIZE); - - - let p = firstPage; - let o = offset % PAGE_SIZE; - let r = len; - while (r>0) { - const l = (o+r > PAGE_SIZE) ? (PAGE_SIZE -o) : r; - const srcView = buff.slice( len -r, len -r+l); - const dstView = new Uint8Array(this.buffers[p].buffer, this.buffers[p].byteOffset + o, l); - dstView.set(srcView); - r = r-l; - p ++; - o = 0; - } - - } -} diff --git a/src/bls12381.js b/src/bls12381.js deleted file mode 100644 index f7a8e27..0000000 --- a/src/bls12381.js +++ /dev/null @@ -1,32 +0,0 @@ -import wasmcurves from "wasmcurves"; -import buildEngine from "./engine.js"; -import * as Scalar from "./scalar.js"; - -global.curve_bls12381 = null; - -export default async function buildBls12381(singleThread) { - - if ((!singleThread)&&(global.curve_bls12381)) return global.curve_bls12381; - const params = { - name: "bls12381", - wasm: wasmcurves.bls12381_wasm, - q: Scalar.e("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", 16), - r: Scalar.e("73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001", 16), - n8q: 48, - n8r: 32, - cofactorG1: Scalar.e("0x396c8c005555e1568c00aaab0000aaab", 16), - cofactorG2: Scalar.e("0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5", 16), - singleThread: singleThread ? true : false - }; - - const curve = await buildEngine(params); - curve.terminate = async function() { - if (!params.singleThread) { - global.curve_bls12381 = null; - await this.tm.terminate(); - } - }; - - return curve; -} - diff --git a/src/bn128.js b/src/bn128.js deleted file mode 100644 index 90888bf..0000000 --- a/src/bn128.js +++ /dev/null @@ -1,35 +0,0 @@ -import wasmcurves from "wasmcurves"; -import buildEngine from "./engine.js"; -import * as Scalar from "./scalar.js"; - -global.curve_bn128 = null; - -export default async function buildBn128(singleThread) { - - if ((!singleThread)&&(global.curve_bn128)) return global.curve_bn128; - const params = { - name: "bn128", - wasm: wasmcurves.bn128_wasm, - q: Scalar.e("21888242871839275222246405745257275088696311157297823662689037894645226208583"), - r: Scalar.e("21888242871839275222246405745257275088548364400416034343698204186575808495617"), - n8q: 32, - n8r: 32, - cofactorG2: Scalar.e("30644e72e131a029b85045b68181585e06ceecda572a2489345f2299c0f9fa8d", 16), - singleThread: singleThread ? true : false - }; - - const curve = await buildEngine(params); - curve.terminate = async function() { - if (!params.singleThread) { - global.curve_bn128 = null; - await this.tm.terminate(); - } - }; - - if (!singleThread) { - global.curve_bn128 = curve; - } - - return curve; -} - diff --git a/src/curves.js b/src/curves.js deleted file mode 100644 index 806d01f..0000000 --- a/src/curves.js +++ /dev/null @@ -1,51 +0,0 @@ -import * as Scalar from "./scalar.js"; -import {default as buildBn128} from "./bn128.js"; -import {default as buildBls12381} from "./bn128.js"; - -const bls12381r = Scalar.e("73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001", 16); -const bn128r = Scalar.e("21888242871839275222246405745257275088548364400416034343698204186575808495617"); - -const bls12381q = Scalar.e("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", 16); -const bn128q = Scalar.e("21888242871839275222246405745257275088696311157297823662689037894645226208583"); - -export async function getCurveFromR(r, singleThread) { - let curve; - if (Scalar.eq(r, bn128r)) { - curve = await buildBn128(singleThread); - } else if (Scalar.eq(r, bls12381r)) { - curve = await buildBls12381(singleThread); - } else { - throw new Error(`Curve not supported: ${Scalar.toString(r)}`); - } - return curve; -} - -export async function getCurveFromQ(q, singleThread) { - let curve; - if (Scalar.eq(q, bn128q)) { - curve = await buildBn128(singleThread); - } else if (Scalar.eq(q, bls12381q)) { - curve = await buildBls12381(singleThread); - } else { - throw new Error(`Curve not supported: ${Scalar.toString(q)}`); - } - return curve; -} - -export async function getCurveFromName(name, singleThread) { - let curve; - const normName = normalizeName(name); - if (["BN128", "BN254", "ALTBN128"].indexOf(normName) >= 0) { - curve = await buildBn128(singleThread); - } else if (["BLS12381"].indexOf(normName) >= 0) { - curve = await buildBls12381(singleThread); - } else { - throw new Error(`Curve not supported: ${name}`); - } - return curve; - - function normalizeName(n) { - return n.toUpperCase().match(/[A-Za-z0-9]+/g).join(""); - } - -} diff --git a/src/ec.js b/src/ec.js deleted file mode 100644 index 0559006..0000000 --- a/src/ec.js +++ /dev/null @@ -1,437 +0,0 @@ -/* - Copyright 2018 0kims association. - - This file is part of snarkjs. - - snarkjs is a free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as published by the - Free Software Foundation, either version 3 of the License, or (at your option) - any later version. - - snarkjs is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - snarkjs. If not, see . -*/ - - - -import * as fUtils from "./futils.js"; -import * as Scalar from "./scalar.js"; - - -function isGreatest(F, a) { - if (Array.isArray(a)) { - for (let i=a.length-1; i>=0; i--) { - if (!F.F.isZero(a[i])) { - return isGreatest(F.F, a[i]); - } - } - return 0; - } else { - const na = F.neg(a); - return Scalar.gt(a, na); - } -} - - -export default class EC { - - constructor(F, g) { - this.F = F; - this.g = g; - if (this.g.length == 2) this.g[2] = this.F.one; - this.zero = [this.F.zero, this.F.one, this.F.zero]; - } - - add(p1, p2) { - - const F = this.F; - - if (this.eq(p1, this.zero)) return p2; - if (this.eq(p2, this.zero)) return p1; - - const res = new Array(3); - - const Z1Z1 = F.square( p1[2] ); - const Z2Z2 = F.square( p2[2] ); - - const U1 = F.mul( p1[0] , Z2Z2 ); // U1 = X1 * Z2Z2 - const U2 = F.mul( p2[0] , Z1Z1 ); // U2 = X2 * Z1Z1 - - const Z1_cubed = F.mul( p1[2] , Z1Z1); - const Z2_cubed = F.mul( p2[2] , Z2Z2); - - const S1 = F.mul( p1[1] , Z2_cubed); // S1 = Y1 * Z2 * Z2Z2 - const S2 = F.mul( p2[1] , Z1_cubed); // S2 = Y2 * Z1 * Z1Z1 - - if (F.eq(U1,U2) && F.eq(S1,S2)) { - return this.double(p1); - } - - const H = F.sub( U2 , U1 ); // H = U2-U1 - - const S2_minus_S1 = F.sub( S2 , S1 ); - - const I = F.square( F.add(H,H) ); // I = (2 * H)^2 - const J = F.mul( H , I ); // J = H * I - - const r = F.add( S2_minus_S1 , S2_minus_S1 ); // r = 2 * (S2-S1) - const V = F.mul( U1 , I ); // V = U1 * I - - res[0] = - F.sub( - F.sub( F.square(r) , J ), - F.add( V , V )); // X3 = r^2 - J - 2 * V - - const S1_J = F.mul( S1 , J ); - - res[1] = - F.sub( - F.mul( r , F.sub(V,res[0])), - F.add( S1_J,S1_J )); // Y3 = r * (V-X3)-2 S1 J - - res[2] = - F.mul( - H, - F.sub( - F.square( F.add(p1[2],p2[2]) ), - F.add( Z1Z1 , Z2Z2 ))); // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2) * H - - return res; - } - - neg(p) { - return [p[0], this.F.neg(p[1]), p[2]]; - } - - sub(a, b) { - return this.add(a, this.neg(b)); - } - - double(p) { - const F = this.F; - - const res = new Array(3); - - if (this.eq(p, this.zero)) return p; - - const A = F.square( p[0] ); // A = X1^2 - const B = F.square( p[1] ); // B = Y1^2 - const C = F.square( B ); // C = B^2 - - let D = - F.sub( - F.square( F.add(p[0] , B )), - F.add( A , C)); - D = F.add(D,D); // D = 2 * ((X1 + B)^2 - A - C) - - const E = F.add( F.add(A,A), A); // E = 3 * A - const FF =F.square( E ); // F = E^2 - - res[0] = F.sub( FF , F.add(D,D) ); // X3 = F - 2 D - - let eightC = F.add( C , C ); - eightC = F.add( eightC , eightC ); - eightC = F.add( eightC , eightC ); - - res[1] = - F.sub( - F.mul( - E, - F.sub( D, res[0] )), - eightC); // Y3 = E * (D - X3) - 8 * C - - const Y1Z1 = F.mul( p[1] , p[2] ); - res[2] = F.add( Y1Z1 , Y1Z1 ); // Z3 = 2 * Y1 * Z1 - - return res; - } - - timesScalar(base, e) { - return fUtils.mulScalar(this, base, e); - } - - mulScalar(base, e) { - return fUtils.mulScalar(this, base, e); - } - - affine(p) { - const F = this.F; - if (this.isZero(p)) { - return this.zero; - } else if (F.eq(p[2], F.one)) { - return p; - } else { - const Z_inv = F.inv(p[2]); - const Z2_inv = F.square(Z_inv); - const Z3_inv = F.mul(Z2_inv, Z_inv); - - const res = new Array(3); - res[0] = F.mul(p[0],Z2_inv); - res[1] = F.mul(p[1],Z3_inv); - res[2] = F.one; - - return res; - } - } - - multiAffine(arr) { - const keys = Object.keys(arr); - const F = this.F; - const accMul = new Array(keys.length+1); - accMul[0] = F.one; - for (let i = 0; i< keys.length; i++) { - if (F.eq(arr[keys[i]][2], F.zero)) { - accMul[i+1] = accMul[i]; - } else { - accMul[i+1] = F.mul(accMul[i], arr[keys[i]][2]); - } - } - - accMul[keys.length] = F.inv(accMul[keys.length]); - - for (let i = keys.length-1; i>=0; i--) { - if (F.eq(arr[keys[i]][2], F.zero)) { - accMul[i] = accMul[i+1]; - arr[keys[i]] = this.zero; - } else { - const Z_inv = F.mul(accMul[i], accMul[i+1]); - accMul[i] = F.mul(arr[keys[i]][2], accMul[i+1]); - - const Z2_inv = F.square(Z_inv); - const Z3_inv = F.mul(Z2_inv, Z_inv); - - arr[keys[i]][0] = F.mul(arr[keys[i]][0],Z2_inv); - arr[keys[i]][1] = F.mul(arr[keys[i]][1],Z3_inv); - arr[keys[i]][2] = F.one; - } - } - - } - - eq(p1, p2) { - const F = this.F; - - if (this.F.eq(p1[2], this.F.zero)) return this.F.eq(p2[2], this.F.zero); - if (this.F.eq(p2[2], this.F.zero)) return false; - - const Z1Z1 = F.square( p1[2] ); - const Z2Z2 = F.square( p2[2] ); - - const U1 = F.mul( p1[0] , Z2Z2 ); - const U2 = F.mul( p2[0] , Z1Z1 ); - - const Z1_cubed = F.mul( p1[2] , Z1Z1); - const Z2_cubed = F.mul( p2[2] , Z2Z2); - - const S1 = F.mul( p1[1] , Z2_cubed); - const S2 = F.mul( p2[1] , Z1_cubed); - - return (F.eq(U1,U2) && F.eq(S1,S2)); - } - - isZero(p) { - return this.F.isZero(p[2]); - } - - toString(p) { - const cp = this.affine(p); - return `[ ${this.F.toString(cp[0])} , ${this.F.toString(cp[1])} ]`; - } - - fromRng(rng) { - const F = this.F; - let P = []; - let greatest; - do { - P[0] = F.fromRng(rng); - greatest = rng.nextBool(); - const x3b = F.add(F.mul(F.square(P[0]), P[0]), this.b); - P[1] = F.sqrt(x3b); - } while ((P[1] == null)||(F.isZero[P])); - - const s = isGreatest(F, P[1]); - if (greatest ^ s) P[1] = F.neg(P[1]); - P[2] = F.one; - - if (this.cofactor) { - P = this.mulScalar(P, this.cofactor); - } - - P = this.affine(P); - - return P; - - } - - toRprLE(buff, o, p) { - p = this.affine(p); - if (this.isZero(p)) { - const BuffV = new Uint8Array(buff, o, this.F.n8*2); - BuffV.fill(0); - return; - } - this.F.toRprLE(buff, o, p[0]); - this.F.toRprLE(buff, o+this.F.n8, p[1]); - } - - toRprBE(buff, o, p) { - p = this.affine(p); - if (this.isZero(p)) { - const BuffV = new Uint8Array(buff, o, this.F.n8*2); - BuffV.fill(0); - return; - } - this.F.toRprBE(buff, o, p[0]); - this.F.toRprBE(buff, o+this.F.n8, p[1]); - } - - toRprLEM(buff, o, p) { - p = this.affine(p); - if (this.isZero(p)) { - const BuffV = new Uint8Array(buff, o, this.F.n8*2); - BuffV.fill(0); - return; - } - this.F.toRprLEM(buff, o, p[0]); - this.F.toRprLEM(buff, o+this.F.n8, p[1]); - } - - toRprLEJM(buff, o, p) { - p = this.affine(p); - if (this.isZero(p)) { - const BuffV = new Uint8Array(buff, o, this.F.n8*2); - BuffV.fill(0); - return; - } - this.F.toRprLEM(buff, o, p[0]); - this.F.toRprLEM(buff, o+this.F.n8, p[1]); - this.F.toRprLEM(buff, o+2*this.F.n8, p[2]); - } - - - toRprBEM(buff, o, p) { - p = this.affine(p); - if (this.isZero(p)) { - const BuffV = new Uint8Array(buff, o, this.F.n8*2); - BuffV.fill(0); - return; - } - this.F.toRprBEM(buff, o, p[0]); - this.F.toRprBEM(buff, o+this.F.n8, p[1]); - } - - fromRprLE(buff, o) { - o = o || 0; - const x = this.F.fromRprLE(buff, o); - const y = this.F.fromRprLE(buff, o+this.F.n8); - if (this.F.isZero(x) && this.F.isZero(y)) { - return this.zero; - } - return [x, y, this.F.one]; - } - - fromRprBE(buff, o) { - o = o || 0; - const x = this.F.fromRprBE(buff, o); - const y = this.F.fromRprBE(buff, o+this.F.n8); - if (this.F.isZero(x) && this.F.isZero(y)) { - return this.zero; - } - return [x, y, this.F.one]; - } - - fromRprLEM(buff, o) { - o = o || 0; - const x = this.F.fromRprLEM(buff, o); - const y = this.F.fromRprLEM(buff, o+this.F.n8); - if (this.F.isZero(x) && this.F.isZero(y)) { - return this.zero; - } - return [x, y, this.F.one]; - } - - fromRprLEJM(buff, o) { - o = o || 0; - const x = this.F.fromRprLEM(buff, o); - const y = this.F.fromRprLEM(buff, o+this.F.n8); - const z = this.F.fromRprLEM(buff, o+this.F.n8*2); - if (this.F.isZero(x) && this.F.isZero(y)) { - return this.zero; - } - return [x, y, z]; - } - - fromRprBEM(buff, o) { - o = o || 0; - const x = this.F.fromRprBEM(buff, o); - const y = this.F.fromRprBEM(buff, o+this.F.n8); - if (this.F.isZero(x) && this.F.isZero(y)) { - return this.zero; - } - return [x, y, this.F.one]; - } - - fromRprCompressed(buff, o) { - const F = this.F; - const v = new Uint8Array(buff.buffer, o, F.n8); - if (v[0] & 0x40) return this.zero; - const P = new Array(3); - - const greatest = ((v[0] & 0x80) != 0); - v[0] = v[0] & 0x7F; - P[0] = F.fromRprBE(buff, o); - if (greatest) v[0] = v[0] | 0x80; // set back again the old value - - const x3b = F.add(F.mul(F.square(P[0]), P[0]), this.b); - P[1] = F.sqrt(x3b); - - if (P[1] === null) { - throw new Error("Invalid Point!"); - } - - const s = isGreatest(F, P[1]); - if (greatest ^ s) P[1] = F.neg(P[1]); - P[2] = F.one; - - return P; - } - - toRprCompressed(buff, o, p) { - p = this.affine(p); - const v = new Uint8Array(buff.buffer, o, this.F.n8); - if (this.isZero(p)) { - v.fill(0); - v[0] = 0x40; - return; - } - this.F.toRprBE(buff, o, p[0]); - - if (isGreatest(this.F, p[1])) { - v[0] = v[0] | 0x80; - } - } - - - fromRprUncompressed(buff, o) { - if (buff[0] & 0x40) return this.zero; - - return this.fromRprBE(buff, o); - } - - toRprUncompressed(buff, o, p) { - this.toRprBE(buff, o, p); - - if (this.isZero(p)) { - buff[o] = buff[o] | 0x40; - } - } - - -} - - diff --git a/src/engine.js b/src/engine.js deleted file mode 100644 index 1f8a25c..0000000 --- a/src/engine.js +++ /dev/null @@ -1,70 +0,0 @@ -import WasmField1 from "./wasm_field1.js"; -import WasmField2 from "./wasm_field2.js"; -import WasmField3 from "./wasm_field3.js"; -import WasmCurve from "./wasm_curve.js"; -import buildThreadManager from "./threadman.js"; -import * as Scalar from "./scalar.js"; -import buildBatchApplyKey from "./engine_applykey.js"; -import buildPairing from "./engine_pairing.js"; -import buildMultiExp from "./engine_multiexp.js"; -import buildFFT from "./engine_fft.js"; - -export default async function buildEngine(params) { - - const tm = await buildThreadManager(params.wasm, params.singleThread); - - - const curve = {}; - - curve.q = Scalar.e(params.wasm.q); - curve.r = Scalar.e(params.wasm.r); - curve.name = params.name; - curve.tm = tm; - curve.prePSize = params.wasm.prePSize; - curve.preQSize = params.wasm.preQSize; - curve.Fr = new WasmField1(tm, "frm", params.n8r, params.r); - curve.F1 = new WasmField1(tm, "f1m", params.n8q, params.q); - curve.F2 = new WasmField2(tm, "f2m", curve.F1); - curve.G1 = new WasmCurve(tm, "g1m", curve.F1, params.wasm.pG1gen, params.wasm.pG1b, params.cofactorG1); - curve.G2 = new WasmCurve(tm, "g2m", curve.F2, params.wasm.pG2gen, params.wasm.pG2b, params.cofactorG2); - curve.F6 = new WasmField3(tm, "f6m", curve.F2); - curve.F12 = new WasmField2(tm, "ftm", curve.F6); - - curve.Gt = curve.F12; - - buildBatchApplyKey(curve, "G1"); - buildBatchApplyKey(curve, "G2"); - buildBatchApplyKey(curve, "Fr"); - - buildMultiExp(curve, "G1"); - buildMultiExp(curve, "G2"); - - buildFFT(curve, "G1"); - buildFFT(curve, "G2"); - buildFFT(curve, "Fr"); - - buildPairing(curve); - - curve.array2buffer = function(arr, sG) { - const buff = new Uint8Array(sG*arr.length); - - for (let i=0; i=16)) { - nChunks *= 2; - pointsInChunk /= 2; - } - - const l2Chunk = log2(pointsInChunk); - - const promises = []; - for (let i = 0; i< nChunks; i++) { - if (logger) logger.debug(`${loggerTxt}: fft ${bits} mix start: ${i}/${nChunks}`); - const task = []; - task.push({cmd: "ALLOC", var: 0, len: sMid*pointsInChunk}); - const buffChunk = buff.slice( (pointsInChunk * i)*sIn, (pointsInChunk * (i+1))*sIn); - task.push({cmd: "SET", var: 0, buff: buffChunk}); - if (fnIn2Mid) { - task.push({cmd: "CALL", fnName:fnIn2Mid, params: [{var:0}, {val: pointsInChunk}, {var: 0}]}); - } - for (let j=1; j<=l2Chunk;j++) { - task.push({cmd: "CALL", fnName:fnFFTMix, params: [{var:0}, {val: pointsInChunk}, {val: j}]}); - } - - if (l2Chunk==bits) { - if (fnFFTFinal) { - task.push({cmd: "ALLOCSET", var: 1, buff: inv}); - task.push({cmd: "CALL", fnName: fnFFTFinal, params:[ - {var: 0}, - {val: pointsInChunk}, - {var: 1}, - ]}); - } - if (fnMid2Out) { - task.push({cmd: "CALL", fnName:fnMid2Out, params: [{var:0}, {val: pointsInChunk}, {var: 0}]}); - } - task.push({cmd: "GET", out: 0, var: 0, len: pointsInChunk*sOut}); - } else { - task.push({cmd: "GET", out:0, var: 0, len: sMid*pointsInChunk}); - } - promises.push(tm.queueAction(task).then( (r) => { - if (logger) logger.debug(`${loggerTxt}: fft ${bits} mix end: ${i}/${nChunks}`); - return r; - })); - } - - chunks = await Promise.all(promises); - for (let i = 0; i< nChunks; i++) chunks[i] = chunks[i][0]; - - for (let i = l2Chunk+1; i<=bits; i++) { - if (logger) logger.debug(`${loggerTxt}: fft ${bits} join: ${i}/${bits}`); - const nGroups = 1 << (bits - i); - const nChunksPerGroup = nChunks / nGroups; - const opPromises = []; - for (let j=0; j { - if (logger) logger.debug(`${loggerTxt}: fft ${bits} join ${i}/${bits} ${j+1}/${nGroups} ${k}/${nChunksPerGroup/2}`); - return r; - })); - } - } - - const res = await Promise.all(opPromises); - for (let j=0; j0; i--) { - buffOut.set(chunks[i], p); - p += pointsInChunk*sOut; - delete chunks[i]; // Liberate mem - } - buffOut.set(chunks[0].slice(0, (pointsInChunk-1)*sOut), p); - delete chunks[0]; - } else { - for (let i=0; i (1<<28)) { - buffOut = new BigBuffer(res1[0].byteLength*2); - } else { - buffOut = new Uint8Array(res1[0].byteLength*2); - } - - buffOut.set(res1[0]); - buffOut.set(res1[1], res1[0].byteLength); - - return buffOut; - } - - async function _fftExtInv(buff, inType, outType, logger, loggerTxt) { - let b1, b2; - b1 = buff.slice( 0 , buff.byteLength/2); - b2 = buff.slice( buff.byteLength/2, buff.byteLength); - - const promises = []; - - promises.push( _fft(b1, true, inType, "jacobian", logger, loggerTxt)); - promises.push( _fft(b2, true, inType, "jacobian", logger, loggerTxt)); - - [b1, b2] = await Promise.all(promises); - - const res1 = await _fftJoinExt(b1, b2, "fftJoinExtInv", Fr.one, Fr.shiftInv, "jacobian", outType, logger, loggerTxt); - - let buffOut; - if (res1[0].byteLength > (1<<28)) { - buffOut = new BigBuffer(res1[0].byteLength*2); - } else { - buffOut = new Uint8Array(res1[0].byteLength*2); - } - - buffOut.set(res1[0]); - buffOut.set(res1[1], res1[0].byteLength); - - return buffOut; - } - - - async function _fftJoinExt(buff1, buff2, fn, first, inc, inType, outType, logger, loggerTxt) { - const MAX_CHUNK_SIZE = 1<<16; - const MIN_CHUNK_SIZE = 1<<4; - - let fnName; - let fnIn2Mid, fnMid2Out; - let sOut, sIn, sMid; - - if (groupName == "G1") { - if (inType == "affine") { - sIn = G.F.n8*2; - fnIn2Mid = "g1m_batchToJacobian"; - } else { - sIn = G.F.n8*3; - } - sMid = G.F.n8*3; - fnName = "g1m_"+fn; - if (outType == "affine") { - fnMid2Out = "g1m_batchToAffine"; - sOut = G.F.n8*2; - } else { - sOut = G.F.n8*3; - } - } else if (groupName == "G2") { - if (inType == "affine") { - sIn = G.F.n8*2; - fnIn2Mid = "g2m_batchToJacobian"; - } else { - sIn = G.F.n8*3; - } - fnName = "g2m_"+fn; - sMid = G.F.n8*3; - if (outType == "affine") { - fnMid2Out = "g2m_batchToAffine"; - sOut = G.F.n8*2; - } else { - sOut = G.F.n8*3; - } - } else if (groupName == "Fr") { - sIn = Fr.n8; - sOut = Fr.n8; - sMid = Fr.n8; - fnName = "frm_" + fn; - } else { - throw new Error("Invalid group"); - } - - if (buff1.byteLength != buff2.byteLength) { - throw new Error("Invalid buffer size"); - } - const nPoints = Math.floor(buff1.byteLength / sIn); - if (nPoints != 1 << log2(nPoints)) { - throw new Error("Invalid number of points"); - } - - let chunkSize = Math.floor(nPoints /tm.concurrency); - if (chunkSize < MIN_CHUNK_SIZE) chunkSize = MIN_CHUNK_SIZE; - if (chunkSize > MAX_CHUNK_SIZE) chunkSize = MAX_CHUNK_SIZE; - - const opPromises = []; - - for (let i=0; i { - if (logger) logger.debug(`${loggerTxt}: fftJoinExt End: ${i}/${nPoints}`); - return r; - }) - ); - } - - const result = await Promise.all(opPromises); - - let fullBuffOut1; - let fullBuffOut2; - if (nPoints * sOut > 1<<28) { - fullBuffOut1 = new BigBuffer(nPoints*sOut); - fullBuffOut2 = new BigBuffer(nPoints*sOut); - } else { - fullBuffOut1 = new Uint8Array(nPoints*sOut); - fullBuffOut2 = new Uint8Array(nPoints*sOut); - } - - let p =0; - for (let i=0; i Fr.s+1) { - if (logger) logger.error("lagrangeEvaluations input too big"); - throw new Error("lagrangeEvaluations input too big"); - } - - let t0 = buff.slice(0, buff.byteLength/2); - let t1 = buff.slice(buff.byteLength/2, buff.byteLength); - - - const shiftToSmallM = Fr.exp(Fr.shift, nPoints/2); - const sConst = Fr.inv( Fr.sub(Fr.one, shiftToSmallM)); - - [t0, t1] = await _fftJoinExt(t0, t1, "prepareLagrangeEvaluation", sConst, Fr.shiftInv, inType, "jacobian", logger, loggerTxt + " prep"); - - const promises = []; - - promises.push( _fft(t0, true, "jacobian", outType, logger, loggerTxt + " t0")); - promises.push( _fft(t1, true, "jacobian", outType, logger, loggerTxt + " t1")); - - [t0, t1] = await Promise.all(promises); - - let buffOut; - if (t0.byteLength > (1<<28)) { - buffOut = new BigBuffer(t0.byteLength*2); - } else { - buffOut = new Uint8Array(t0.byteLength*2); - } - - buffOut.set(t0); - buffOut.set(t1, t0.byteLength); - - return buffOut; - }; - - G.fftMix = async function fftMix(buff) { - const sG = G.F.n8*3; - let fnName, fnFFTJoin; - if (groupName == "G1") { - fnName = "g1m_fftMix"; - fnFFTJoin = "g1m_fftJoin"; - } else if (groupName == "G2") { - fnName = "g2m_fftMix"; - fnFFTJoin = "g2m_fftJoin"; - } else if (groupName == "Fr") { - fnName = "frm_fftMix"; - fnFFTJoin = "frm_fftJoin"; - } else { - throw new Error("Invalid group"); - } - - const nPoints = Math.floor(buff.byteLength / sG); - const power = log2(nPoints); - - let nChunks = 1 << log2(tm.concurrency); - - if (nPoints <= nChunks*2) nChunks = 1; - - const pointsPerChunk = nPoints / nChunks; - - const powerChunk = log2(pointsPerChunk); - - const opPromises = []; - for (let i=0; i=0; i--) { - fullBuffOut.set(result[i][0], p); - p+=result[i][0].byteLength; - } - - return fullBuffOut; - }; -} diff --git a/src/engine_multiexp.js b/src/engine_multiexp.js deleted file mode 100644 index 3db5ac4..0000000 --- a/src/engine_multiexp.js +++ /dev/null @@ -1,154 +0,0 @@ -import { log2 } from "./utils.js"; - -const pTSizes = [ - 1 , 1, 1, 1, 2, 3, 4, 5, - 6 , 7, 7, 8, 9, 10, 11, 12, - 13, 13, 14, 15, 16, 16, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17 -]; - -export default function buildMultiexp(curve, groupName) { - const G = curve[groupName]; - const tm = G.tm; - async function _multiExpChunk(buffBases, buffScalars, inType, logger, logText) { - if ( ! (buffBases instanceof Uint8Array) ) { - if (logger) logger.error(`${logText} _multiExpChunk buffBases is not Uint8Array`); - throw new Error(`${logText} _multiExpChunk buffBases is not Uint8Array`); - } - if ( ! (buffScalars instanceof Uint8Array) ) { - if (logger) logger.error(`${logText} _multiExpChunk buffScalars is not Uint8Array`); - throw new Error(`${logText} _multiExpChunk buffScalars is not Uint8Array`); - } - inType = inType || "affine"; - - let sGIn; - let fnName; - if (groupName == "G1") { - if (inType == "affine") { - fnName = "g1m_multiexpAffine_chunk"; - sGIn = G.F.n8*2; - } else { - fnName = "g1m_multiexp_chunk"; - sGIn = G.F.n8*3; - } - } else if (groupName == "G2") { - if (inType == "affine") { - fnName = "g2m_multiexpAffine_chunk"; - sGIn = G.F.n8*2; - } else { - fnName = "g2m_multiexp_chunk"; - sGIn = G.F.n8*3; - } - } else { - throw new Error("Invalid group"); - } - const nPoints = Math.floor(buffBases.byteLength / sGIn); - - if (nPoints == 0) return G.zero; - const sScalar = Math.floor(buffScalars.byteLength / nPoints); - if( sScalar * nPoints != buffScalars.byteLength) { - throw new Error("Scalar size does not match"); - } - - const bitChunkSize = pTSizes[log2(nPoints)]; - const nChunks = Math.floor((sScalar*8 - 1) / bitChunkSize) +1; - - const opPromises = []; - for (let i=0; i=0; i--) { - if (!G.isZero(res)) { - for (let j=0; jMAX_CHUNK_SIZE) chunkSize = MAX_CHUNK_SIZE; - if (chunkSize { - if (logger) logger.debug(`Multiexp end: ${logText}: ${i}/${nPoints}`); - return r; - })); - } - - const result = await Promise.all(opPromises); - - let res = G.zero; - for (let i=result.length-1; i>=0; i--) { - res = G.add(res, result[i]); - } - - return res; - } - - G.multiExp = async function multiExpAffine(buffBases, buffScalars, logger, logText) { - return await _multiExp(buffBases, buffScalars, "jacobian", logger, logText); - }; - G.multiExpAffine = async function multiExpAffine(buffBases, buffScalars, logger, logText) { - return await _multiExp(buffBases, buffScalars, "affine", logger, logText); - }; -} diff --git a/src/engine_pairing.js b/src/engine_pairing.js deleted file mode 100644 index 5a802ce..0000000 --- a/src/engine_pairing.js +++ /dev/null @@ -1,130 +0,0 @@ - -export default function buildPairing(curve) { - const tm = curve.tm; - curve.pairing = function pairing(a, b) { - - tm.startSyncOp(); - const pA = tm.allocBuff(curve.G1.toJacobian(a)); - const pB = tm.allocBuff(curve.G2.toJacobian(b)); - const pRes = tm.alloc(curve.Gt.n8); - tm.instance.exports[curve.name + "_pairing"](pA, pB, pRes); - - const res = tm.getBuff(pRes, curve.Gt.n8); - - tm.endSyncOp(); - return res; - }; - - curve.pairingEq = async function pairingEq() { - let buffCt; - let nEqs; - if ((arguments.length % 2) == 1) { - buffCt = arguments[arguments.length-1]; - nEqs = (arguments.length -1) /2; - } else { - buffCt = curve.Gt.one; - nEqs = arguments.length /2; - } - - const opPromises = []; - for (let i=0; i> 1n; + this.negone = this.p-this.one; + this.two = BigInt(2); + this.half = this.p >> this.one; this.bitLength = Scalar.bitLength(this.p); - this.mask = (1n << BigInt(this.bitLength)) - 1n; + this.mask = (this.one << BigInt(this.bitLength)) - this.one; this.n64 = Math.floor((this.bitLength - 1) / 64)+1; this.n32 = this.n64*2; this.n8 = this.n64*8; - this.R = this.e(1n << BigInt(this.n64*64)); + this.R = this.e(this.one << BigInt(this.n64*64)); this.Ri = this.inv(this.R); - const e = this.negone >> 1n; + const e = this.negone >> this.one; this.nqr = this.two; let r = this.pow(this.nqr, e); while (!this.eq(r, this.negone)) { - this.nqr = this.nqr + 1n; + this.nqr = this.nqr + this.one; r = this.pow(this.nqr, e); } @@ -35,9 +35,9 @@ export default class ZqField { this.s = 0; this.t = this.negone; - while ((this.t & 1n) == 0n) { + while ((this.t & this.one) == this.zero) { this.s = this.s + 1; - this.t = this.t >> 1n; + this.t = this.t >> this.one; } this.nqr_to_t = this.pow(this.nqr, this.t); @@ -131,16 +131,16 @@ export default class ZqField { inv(a) { if (!a) throw new Error("Division by zero"); - let t = 0n; + let t = this.zero; let r = this.p; - let newt = 1n; + let newt = this.one; let newr = a % this.p; while (newr) { let q = r/newr; [t, newt] = [newt, t-q*newt]; [r, newr] = [newr, r-q*newr]; } - if (t<0n) t += this.p; + if (t> nb; } else { - return 0n; + return this.zero; } } } @@ -205,34 +205,34 @@ export default class ZqField { } land(a, b) { - return (a && b) ? 1n : 0n; + return (a && b) ? this.one : this.zero; } lor(a, b) { - return (a || b) ? 1n : 0n; + return (a || b) ? this.one : this.zero; } lnot(a) { - return (a) ? 0n : 1n; + return (a) ? this.zero : this.one; } sqrt_old(n) { - if (n == 0n) return this.zero; + if (n == this.zero) return this.zero; // Test that have solution const res = this.pow(n, this.negone >> this.one); - if ( res != 1n ) return null; + if ( res != this.one ) return null; let m = this.s; let c = this.nqr_to_t; let t = this.pow(n, this.t); - let r = this.pow(n, this.add(this.t, this.one) >> 1n ); + let r = this.pow(n, this.add(this.t, this.one) >> this.one ); - while ( t != 1n ) { + while ( t != this.one ) { let sq = this.square(t); let i = 1; - while (sq != 1n ) { + while (sq != this.one ) { i++; sq = this.square(sq); } @@ -247,7 +247,7 @@ export default class ZqField { r = this.mul(r, b); } - if (r > (this.p >> 1n)) { + if (r > (this.p >> this.one)) { r = this.neg(r); } @@ -267,9 +267,9 @@ export default class ZqField { random() { const nBytes = (this.bitLength*2 / 8); - let res =0n; + let res =this.zero; for (let i=0; i. -*/ - -import * as fUtils from "./futils.js"; -import buildSqrt from "./fsqrt.js"; - -export default class F2Field { - constructor(F, nonResidue) { - this.type="F2"; - this.F = F; - this.zero = [this.F.zero, this.F.zero]; - this.one = [this.F.one, this.F.zero]; - this.negone = this.neg(this.one); - this.nonResidue = nonResidue; - this.m = F.m*2; - this.p = F.p; - this.n64 = F.n64*2; - this.n32 = this.n64*2; - this.n8 = this.n64*8; - - buildSqrt(this); - } - - _mulByNonResidue(a) { - return this.F.mul(this.nonResidue, a); - } - - copy(a) { - return [this.F.copy(a[0]), this.F.copy(a[1])]; - } - - add(a, b) { - return [ - this.F.add(a[0], b[0]), - this.F.add(a[1], b[1]) - ]; - } - - double(a) { - return this.add(a,a); - } - - sub(a, b) { - return [ - this.F.sub(a[0], b[0]), - this.F.sub(a[1], b[1]) - ]; - } - - neg(a) { - return this.sub(this.zero, a); - } - - conjugate(a) { - return [ - a[0], - this.F.neg(a[1]) - ]; - } - - mul(a, b) { - const aA = this.F.mul(a[0] , b[0]); - const bB = this.F.mul(a[1] , b[1]); - - return [ - this.F.add( aA , this._mulByNonResidue(bB)), - this.F.sub( - this.F.mul( - this.F.add(a[0], a[1]), - this.F.add(b[0], b[1])), - this.F.add(aA, bB))]; - } - - inv(a) { - const t0 = this.F.square(a[0]); - const t1 = this.F.square(a[1]); - const t2 = this.F.sub(t0, this._mulByNonResidue(t1)); - const t3 = this.F.inv(t2); - return [ - this.F.mul(a[0], t3), - this.F.neg(this.F.mul( a[1], t3)) ]; - } - - div(a, b) { - return this.mul(a, this.inv(b)); - } - - square(a) { - const ab = this.F.mul(a[0] , a[1]); - - /* - [ - (a + b) * (a + non_residue * b) - ab - non_residue * ab, - ab + ab - ]; - */ - - return [ - this.F.sub( - this.F.mul( - this.F.add(a[0], a[1]) , - this.F.add( - a[0] , - this._mulByNonResidue(a[1]))), - this.F.add( - ab, - this._mulByNonResidue(ab))), - this.F.add(ab, ab) - ]; - } - - isZero(a) { - return this.F.isZero(a[0]) && this.F.isZero(a[1]); - } - - eq(a, b) { - return this.F.eq(a[0], b[0]) && this.F.eq(a[1], b[1]); - } - - mulScalar(base, e) { - return fUtils.mulScalar(this, base, e); - } - - pow(base, e) { - return fUtils.exp(this, base, e); - } - - exp(base, e) { - return fUtils.exp(this, base, e); - } - - toString(a) { - return `[ ${this.F.toString(a[0])} , ${this.F.toString(a[1])} ]`; - } - - fromRng(rng) { - const c0 = this.F.fromRng(rng); - const c1 = this.F.fromRng(rng); - return [c0, c1]; - } - - gt(a, b) { - if (this.F.gt(a[0], b[0])) return true; - if (this.F.gt(b[0], a[0])) return false; - if (this.F.gt(a[1], b[1])) return true; - return false; - } - - geq(a, b) { - return this.gt(a, b) || this.eq(a, b); - } - - lt(a, b) { - return !this.geq(a,b); - } - - leq(a, b) { - return !this.gt(a,b); - } - - neq(a, b) { - return !this.eq(a,b); - } - - random() { - return [this.F.random(), this.F.random()]; - } - - - toRprLE(buff, o, e) { - this.F.toRprLE(buff, o, e[0]); - this.F.toRprLE(buff, o+this.F.n8, e[1]); - } - - toRprBE(buff, o, e) { - this.F.toRprBE(buff, o, e[1]); - this.F.toRprBE(buff, o+this.F.n8, e[0]); - } - - toRprLEM(buff, o, e) { - this.F.toRprLEM(buff, o, e[0]); - this.F.toRprLEM(buff, o+this.F.n8, e[1]); - } - - - toRprBEM(buff, o, e) { - this.F.toRprBEM(buff, o, e[1]); - this.F.toRprBEM(buff, o+this.F.n8, e[0]); - } - - fromRprLE(buff, o) { - o = o || 0; - const c0 = this.F.fromRprLE(buff, o); - const c1 = this.F.fromRprLE(buff, o+this.F.n8); - return [c0, c1]; - } - - fromRprBE(buff, o) { - o = o || 0; - const c1 = this.F.fromRprBE(buff, o); - const c0 = this.F.fromRprBE(buff, o+this.F.n8); - return [c0, c1]; - } - - fromRprLEM(buff, o) { - o = o || 0; - const c0 = this.F.fromRprLEM(buff, o); - const c1 = this.F.fromRprLEM(buff, o+this.F.n8); - return [c0, c1]; - } - - fromRprBEM(buff, o) { - o = o || 0; - const c1 = this.F.fromRprBEM(buff, o); - const c0 = this.F.fromRprBEM(buff, o+this.F.n8); - return [c0, c1]; - } - -} - diff --git a/src/f3field.js b/src/f3field.js deleted file mode 100644 index 3df2435..0000000 --- a/src/f3field.js +++ /dev/null @@ -1,281 +0,0 @@ -/* - Copyright 2018 0kims association. - - This file is part of snarkjs. - - snarkjs is a free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as published by the - Free Software Foundation, either version 3 of the License, or (at your option) - any later version. - - snarkjs is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - snarkjs. If not, see . -*/ - -import * as fUtils from "./futils.js"; - -export default class F3Field { - constructor(F, nonResidue) { - this.type="F3"; - this.F = F; - this.zero = [this.F.zero, this.F.zero, this.F.zero]; - this.one = [this.F.one, this.F.zero, this.F.zero]; - this.negone = this.neg(this.one); - this.nonResidue = nonResidue; - this.m = F.m*3; - this.p = F.p; - this.n64 = F.n64*3; - this.n32 = this.n64*2; - this.n8 = this.n64*8; - } - - _mulByNonResidue(a) { - return this.F.mul(this.nonResidue, a); - } - - copy(a) { - return [this.F.copy(a[0]), this.F.copy(a[1]), this.F.copy(a[2])]; - } - - add(a, b) { - return [ - this.F.add(a[0], b[0]), - this.F.add(a[1], b[1]), - this.F.add(a[2], b[2]) - ]; - } - - double(a) { - return this.add(a,a); - } - - sub(a, b) { - return [ - this.F.sub(a[0], b[0]), - this.F.sub(a[1], b[1]), - this.F.sub(a[2], b[2]) - ]; - } - - neg(a) { - return this.sub(this.zero, a); - } - - mul(a, b) { - - const aA = this.F.mul(a[0] , b[0]); - const bB = this.F.mul(a[1] , b[1]); - const cC = this.F.mul(a[2] , b[2]); - - return [ - this.F.add( - aA, - this._mulByNonResidue( - this.F.sub( - this.F.mul( - this.F.add(a[1], a[2]), - this.F.add(b[1], b[2])), - this.F.add(bB, cC)))), // aA + non_residue*((b+c)*(B+C)-bB-cC), - - this.F.add( - this.F.sub( - this.F.mul( - this.F.add(a[0], a[1]), - this.F.add(b[0], b[1])), - this.F.add(aA, bB)), - this._mulByNonResidue( cC)), // (a+b)*(A+B)-aA-bB+non_residue*cC - - this.F.add( - this.F.sub( - this.F.mul( - this.F.add(a[0], a[2]), - this.F.add(b[0], b[2])), - this.F.add(aA, cC)), - bB)]; // (a+c)*(A+C)-aA+bB-cC) - } - - inv(a) { - const t0 = this.F.square(a[0]); // t0 = a^2 ; - const t1 = this.F.square(a[1]); // t1 = b^2 ; - const t2 = this.F.square(a[2]); // t2 = c^2; - const t3 = this.F.mul(a[0],a[1]); // t3 = ab - const t4 = this.F.mul(a[0],a[2]); // t4 = ac - const t5 = this.F.mul(a[1],a[2]); // t5 = bc; - // c0 = t0 - non_residue * t5; - const c0 = this.F.sub(t0, this._mulByNonResidue(t5)); - // c1 = non_residue * t2 - t3; - const c1 = this.F.sub(this._mulByNonResidue(t2), t3); - const c2 = this.F.sub(t1, t4); // c2 = t1-t4 - - // t6 = (a * c0 + non_residue * (c * c1 + b * c2)).inv(); - const t6 = - this.F.inv( - this.F.add( - this.F.mul(a[0], c0), - this._mulByNonResidue( - this.F.add( - this.F.mul(a[2], c1), - this.F.mul(a[1], c2))))); - - return [ - this.F.mul(t6, c0), // t6*c0 - this.F.mul(t6, c1), // t6*c1 - this.F.mul(t6, c2)]; // t6*c2 - } - - div(a, b) { - return this.mul(a, this.inv(b)); - } - - square(a) { - const s0 = this.F.square(a[0]); // s0 = a^2 - const ab = this.F.mul(a[0], a[1]); // ab = a*b - const s1 = this.F.add(ab, ab); // s1 = 2ab; - const s2 = this.F.square( - this.F.add(this.F.sub(a[0],a[1]), a[2])); // s2 = (a - b + c)^2; - const bc = this.F.mul(a[1],a[2]); // bc = b*c - const s3 = this.F.add(bc, bc); // s3 = 2*bc - const s4 = this.F.square(a[2]); // s4 = c^2 - - - return [ - this.F.add( - s0, - this._mulByNonResidue(s3)), // s0 + non_residue * s3, - this.F.add( - s1, - this._mulByNonResidue(s4)), // s1 + non_residue * s4, - this.F.sub( - this.F.add( this.F.add(s1, s2) , s3 ), - this.F.add(s0, s4))]; // s1 + s2 + s3 - s0 - s4 - } - - isZero(a) { - return this.F.isZero(a[0]) && this.F.isZero(a[1]) && this.F.isZero(a[2]); - } - - eq(a, b) { - return this.F.eq(a[0], b[0]) && this.F.eq(a[1], b[1]) && this.F.eq(a[2], b[2]); - } - - affine(a) { - return [this.F.affine(a[0]), this.F.affine(a[1]), this.F.affine(a[2])]; - } - - mulScalar(base, e) { - return fUtils.mulScalar(this, base, e); - } - - pow(base, e) { - return fUtils.exp(this, base, e); - } - - exp(base, e) { - return fUtils.exp(this, base, e); - } - - toString(a) { - return `[ ${this.F.toString(a[0])} , ${this.F.toString(a[1])}, ${this.F.toString(a[2])} ]`; - } - - fromRng(rng) { - const c0 = this.F.fromRng(rng); - const c1 = this.F.fromRng(rng); - const c2 = this.F.fromRng(rng); - return [c0, c1, c2]; - } - - gt(a, b) { - if (this.F.gt(a[0], b[0])) return true; - if (this.F.gt(b[0], a[0])) return false; - if (this.F.gt(a[1], b[1])) return true; - if (this.F.gt(b[1], a[1])) return false; - if (this.F.gt(a[2], b[2])) return true; - return false; - } - - - geq(a, b) { - return this.gt(a, b) || this.eq(a, b); - } - - lt(a, b) { - return !this.geq(a,b); - } - - leq(a, b) { - return !this.gt(a,b); - } - - neq(a, b) { - return !this.eq(a,b); - } - - random() { - return [this.F.random(), this.F.random(), this.F.random()]; - } - - - toRprLE(buff, o, e) { - this.F.toRprLE(buff, o, e[0]); - this.F.toRprLE(buff, o+this.F.n8, e[1]); - this.F.toRprLE(buff, o+this.F.n8*2, e[2]); - } - - toRprBE(buff, o, e) { - this.F.toRprBE(buff, o, e[2]); - this.F.toRprBE(buff, o+this.F.n8, e[1]); - this.F.toRprBE(buff, o+this.F.n8*2, e[0]); - } - - toRprLEM(buff, o, e) { - this.F.toRprLEM(buff, o, e[0]); - this.F.toRprLEM(buff, o+this.F.n8, e[1]); - this.F.toRprLEM(buff, o+this.F.n8*2, e[2]); - } - - - toRprBEM(buff, o, e) { - this.F.toRprBEM(buff, o, e[2]); - this.F.toRprBEM(buff, o+this.F.n8, e[1]); - this.F.toRprBEM(buff, o+this.F.n8*2, e[0]); - } - - fromRprLE(buff, o) { - o = o || 0; - const c0 = this.F.fromRprLE(buff, o); - const c1 = this.F.fromRprLE(buff, o+this.n8); - const c2 = this.F.fromRprLE(buff, o+this.n8*2); - return [c0, c1, c2]; - } - - fromRprBE(buff, o) { - o = o || 0; - const c2 = this.F.fromRprBE(buff, o); - const c1 = this.F.fromRprBE(buff, o+this.n8); - const c0 = this.F.fromRprBE(buff, o+this.n8*2); - return [c0, c1, c2]; - } - - fromRprLEM(buff, o) { - o = o || 0; - const c0 = this.F.fromRprLEM(buff, o); - const c1 = this.F.fromRprLEM(buff, o+this.n8); - const c2 = this.F.fromRprLEM(buff, o+this.n8*2); - return [c0, c1, c2]; - } - - fromRprBEM(buff, o) { - o = o || 0; - const c2 = this.F.fromRprBEM(buff, o); - const c1 = this.F.fromRprBEM(buff, o+this.n8); - const c0 = this.F.fromRprBEM(buff, o+this.n8*2); - return [c0, c1, c2]; - } - -} diff --git a/src/fft.js b/src/fft.js deleted file mode 100644 index 7e9f8af..0000000 --- a/src/fft.js +++ /dev/null @@ -1,148 +0,0 @@ -/* - Copyright 2018 0kims association. - - This file is part of snarkjs. - - snarkjs is a free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as published by the - Free Software Foundation, either version 3 of the License, or (at your option) - any later version. - - snarkjs is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - snarkjs. If not, see . -*/ - -/* - This library does operations on polynomials with coefficients in a field F. - - A polynomial P(x) = p0 + p1 * x + p2 * x^2 + ... + pn * x^n is represented - by the array [ p0, p1, p2, ... , pn ]. - */ - -export default class FFT { - constructor (G, F, opMulGF) { - this.F = F; - this.G = G; - this.opMulGF = opMulGF; - - let rem = F.sqrt_t; - let s = F.sqrt_s; - - let nqr = F.one; - while (F.eq(F.pow(nqr, F.half), F.one)) nqr = F.add(nqr, F.one); - - this.w = new Array(s+1); - this.wi = new Array(s+1); - this.w[s] = this.F.pow(nqr, rem); - this.wi[s] = this.F.inv(this.w[s]); - - let n=s-1; - while (n>=0) { - this.w[n] = this.F.square(this.w[n+1]); - this.wi[n] = this.F.square(this.wi[n+1]); - n--; - } - - - this.roots = []; - /* - for (let i=0; i<16; i++) { - let r = this.F.one; - n = 1 << i; - const rootsi = new Array(n); - for (let j=0; j=0) && (!this.roots[i]); i--) { - let r = this.F.one; - const nroots = 1 << i; - const rootsi = new Array(nroots); - for (let j=0; j> 1; - const p1 = __fft(PF, pall, bits-1, offset, step*2); - const p2 = __fft(PF, pall, bits-1, offset+step, step*2); - - const out = new Array(n); - - for (let i=0; i. -*/ - -/* - This library does operations on polynomials with coefficients in a field F. - - A polynomial P(x) = p0 + p1 * x + p2 * x^2 + ... + pn * x^n is represented - by the array [ p0, p1, p2, ... , pn ]. - */ - -export default class PolField { - constructor (F) { - this.F = F; - - let rem = F.sqrt_t; - let s = F.sqrt_s; - - const five = this.F.add(this.F.add(this.F.two, this.F.two), this.F.one); - - this.w = new Array(s+1); - this.wi = new Array(s+1); - this.w[s] = this.F.pow(five, rem); - this.wi[s] = this.F.inv(this.w[s]); - - let n=s-1; - while (n>=0) { - this.w[n] = this.F.square(this.w[n+1]); - this.wi[n] = this.F.square(this.wi[n+1]); - n--; - } - - - this.roots = []; -/* for (let i=0; i<16; i++) { - let r = this.F.one; - n = 1 << i; - const rootsi = new Array(n); - for (let j=0; j this.F.sqrt_s) n = this.s; - for (let i=n; (i>=0) && (!this.roots[i]); i--) { - let r = this.F.one; - const nroots = 1 << i; - const rootsi = new Array(nroots); - for (let j=0; j a.length) { - [b, a] = [a, b]; - } - - if ((b.length <= 2) || (b.length < log2(a.length))) { - return this.mulNormal(a,b); - } else { - return this.mulFFT(a,b); - } - } - - mulNormal(a, b) { - let res = []; - for (let i=0; i0) { - const z = new Array(n).fill(this.F.zero); - return z.concat(p); - } else { - if (-n >= p.length) return []; - return p.slice(-n); - } - } - - eval2(p, x) { - let v = this.F.zero; - let ix = this.F.one; - for (let i=0; i> 1), - F.mul( - x, - _eval(p, newX, offset+step , step << 1, n >> 1))); - return res; - } - } - - lagrange(points) { - let roots = [this.F.one]; - for (let i=0; i> 1; - const p1 = this._fft(pall, bits-1, offset, step*2); - const p2 = this._fft(pall, bits-1, offset+step, step*2); - - const out = new Array(n); - - let m= this.F.one; - for (let i=0; i0 && this.F.eq(p[i], this.F.zero) ) i--; - return p.slice(0, i+1); - } - - eq(a, b) { - const pa = this.reduce(a); - const pb = this.reduce(b); - - if (pa.length != pb.length) return false; - for (let i=0; i=0; i--) { - res[i] = this.F.add(this.F.mul(res[i+1], r), p[i+1]); - } - return res; - } - - _next2Power(v) { - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v++; - return v; - } - - toString(p) { - const ap = this.normalize(p); - let S = ""; - for (let i=ap.length-1; i>=0; i--) { - if (!this.F.eq(p[i], this.F.zero)) { - if (S!="") S += " + "; - S = S + p[i].toString(10); - if (i>0) { - S = S + "x"; - if (i>1) { - S = S + "^" +i; - } - } - } - } - return S; - } - - normalize(p) { - const res = new Array(p.length); - for (let i=0; i - // rec = x^(k-2-scaleV)/ v - // - // res = x^m/v = x^(m + (2*k-2 - scaleV) - (2*k-2 - scaleV)) /v => - // res = rec * x^(m - (2*k-2 - scaleV)) => - // res = rec * x^(m - 2*k + 2 + scaleV) - - const rec = this._reciprocal(this.scaleX(v, scaleV), kbits); - const res = this.scaleX(rec, m - 2*k + 2 + scaleV); - - return res; - } - - div(_u, _v) { - if (_u.length < _v.length) return []; - const kbits = log2(_v.length-1)+1; - const k = 1 << kbits; - - const u = this.scaleX(_u, k-_v.length); - const v = this.scaleX(_v, k-_v.length); - - const n = v.length-1; - let m = u.length-1; - - const s = this._reciprocal(v, kbits); - let t; - if (m>2*n) { - t = this.sub(this.scaleX([this.F.one], 2*n), this.mul(s, v)); - } - - let q = []; - let rem = u; - let us, ut; - let finish = false; - - while (!finish) { - us = this.mul(rem, s); - q = this.add(q, this.scaleX(us, -2*n)); - - if ( m > 2*n ) { - ut = this.mul(rem, t); - rem = this.scaleX(ut, -2*n); - m = rem.length-1; - } else { - finish = true; - } - } - - return q; - } - - - // returns the ith nth-root of one - oneRoot(n, i) { - let nbits = log2(n-1)+1; - let res = this.F.one; - let r = i; - - if(i>=n) { - throw new Error("Given 'i' should be lower than 'n'"); - } - else if (1<0) { - if (r & 1 == 1) { - res = this.F.mul(res, this.w[nbits]); - } - r = r >> 1; - nbits --; - } - return res; - } - - computeVanishingPolinomial(bits, t) { - const m = 1 << bits; - return this.F.sub(this.F.pow(t, m), this.F.one); - } - - evaluateLagrangePolynomials(bits, t) { - const m= 1 << bits; - const tm = this.F.pow(t, m); - const u= new Array(m).fill(this.F.zero); - this._setRoots(bits); - const omega = this.w[bits]; - - if (this.F.eq(tm, this.F.one)) { - for (let i = 0; i < m; i++) { - if (this.F.eq(this.roots[bits][0],t)) { // i.e., t equals omega^i - u[i] = this.F.one; - return u; - } - } - } - - const z = this.F.sub(tm, this.F.one); - // let l = this.F.mul(z, this.F.pow(this.F.twoinv, m)); - let l = this.F.mul(z, this.F.inv(this.F.e(m))); - for (let i = 0; i < m; i++) { - u[i] = this.F.mul(l, this.F.inv(this.F.sub(t,this.roots[bits][i]))); - l = this.F.mul(l, omega); - } - - return u; - } - - log2(V) { - return log2(V); - } -} - -function log2( V ) -{ - return( ( ( V & 0xFFFF0000 ) !== 0 ? ( V &= 0xFFFF0000, 16 ) : 0 ) | ( ( V & 0xFF00FF00 ) !== 0 ? ( V &= 0xFF00FF00, 8 ) : 0 ) | ( ( V & 0xF0F0F0F0 ) !== 0 ? ( V &= 0xF0F0F0F0, 4 ) : 0 ) | ( ( V & 0xCCCCCCCC ) !== 0 ? ( V &= 0xCCCCCCCC, 2 ) : 0 ) | ( ( V & 0xAAAAAAAA ) !== 0 ) ); -} - - -function __fft(PF, pall, bits, offset, step) { - - const n = 1 << bits; - if (n==1) { - return [ pall[offset] ]; - } else if (n==2) { - return [ - PF.F.add(pall[offset], pall[offset + step]), - PF.F.sub(pall[offset], pall[offset + step])]; - } - - const ndiv2 = n >> 1; - const p1 = __fft(PF, pall, bits-1, offset, step*2); - const p2 = __fft(PF, pall, bits-1, offset+step, step*2); - - const out = new Array(n); - - for (let i=0; i> 1; - const p1 = __fft2(PF, pall.slice(0, ndiv2), bits-1); - const p2 = __fft2(PF, pall.slice(ndiv2), bits-1); - - const out = new Array(n); - - for (let i=0; i>=1; - } - return res; -} - -function rev(idx, bits) { - return ( - _revTable[idx >>> 24] | - (_revTable[(idx >>> 16) & 0xFF] << 8) | - (_revTable[(idx >>> 8) & 0xFF] << 16) | - (_revTable[idx & 0xFF] << 24) - ) >>> (32-bits); -} - -function __bitReverse(p, bits) { - for (let k=0; kk) { - const tmp= p[k]; - p[k] = p[r]; - p[r] = tmp; - } - } - -} - - diff --git a/src/ratfield.js b/src/ratfield.js deleted file mode 100644 index 512396c..0000000 --- a/src/ratfield.js +++ /dev/null @@ -1,125 +0,0 @@ -/* - Copyright 2018 0kims association. - - This file is part of snarkjs. - - snarkjs is a free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as published by the - Free Software Foundation, either version 3 of the License, or (at your option) - any later version. - - snarkjs is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - snarkjs. If not, see . -*/ - -import * as fUtils from "./futils.js"; - -export default class RatField { - constructor(F) { - this.F = F; - this.zero = [F.zero, F.one]; - this.one = [F.one, F.one]; - this.two = [F.two, F.one]; - this.twoinv = [F.one, F.two]; - this.q = F.q; - } - - add(a,b) { - return [ - this.F.add( - this.F.mul(a[0], b[1]), - this.F.mul(a[1], b[0])), - this.F.mul(a[1], b[1])]; - } - - double(a) { - return [this.F.add(a[0], a[0]), a[1]]; - } - - sub(a,b) { - return [ - this.F.sub( - this.F.mul(a[0], b[1]), - this.F.mul(a[1], b[0])), - this.F.mul(a[1], b[1])]; - } - - neg(a) { - return [this.F.neg(a[0]), a[1]]; - } - - mul(a,b) { - return [ - this.F.mul(a[0], b[0]), - this.F.mul(a[1], b[1]), - ]; - } - - copy(a) { - return [a[0], a[1]]; - } - - div(a, b) { - return [ - this.F.mul(a[0], b[1]), - this.F.mul(a[1], b[0]), - ]; - } - - inv(a) { - return [a[1], a[0]]; - } - - square(a) { - return [ - this.F.square(a[0]), - this.F.square(a[1]) - ]; - } - - mulScalar(base, e) { - return [this.F.mulScalar(base[0], e) , base[1]]; - } - - exp(base, e) { - return fUtils.exp(this, base, e); - } - - eq(a, b) { - return this.F.eq( - this.F.mul(a[0], b[1]), - this.F.mul(a[1], b[0]) - ); - } - - isZero(a) { - return this.F.isZero(a[0]); - } - - affine(a) { - return [this.F.div(a[0], a[1]), this.F.one]; - } - - toString(a) { - const ca = this.affine(a); - return `"0x${ca[0].toString(16)}"`; - } - - random() { - return [this.F.random(), this.F.one]; - } - - fromF(a) { - return [a, this.F.one]; - } - - toF(a) { - return this.affine(a)[0]; - } -} - diff --git a/src/scalar_native.js b/src/scalar_native.js index 304a0a8..49bc5b6 100644 --- a/src/scalar_native.js +++ b/src/scalar_native.js @@ -16,7 +16,7 @@ export function fromString(s, radix) { export const e = fromString; export function fromArray(a, radix) { - let acc =0n; + let acc =BigInt(0); radix = BigInt(radix); for (let i=0; i> 1n; + E = E >> BigInt(1); } return res; } @@ -74,12 +74,12 @@ export function bits(n) { let E = BigInt(n); const res = []; while (E) { - if (E & 1n) { + if (E & BigInt(1)) { res.push(1); } else { res.push( 0 ); } - E = E >> 1n; + E = E >> BigInt(1); } return res; } diff --git a/src/threadman.js b/src/threadman.js deleted file mode 100644 index e8ac5bc..0000000 --- a/src/threadman.js +++ /dev/null @@ -1,251 +0,0 @@ -/* global window, navigator, Blob, Worker, WebAssembly */ -/* - Copyright 2019 0KIMS association. - - This file is part of wasmsnark (Web Assembly zkSnark Prover). - - wasmsnark is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - wasmsnark is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with wasmsnark. If not, see . -*/ - -// const MEM_SIZE = 1000; // Memory size in 64K Pakes (512Mb) -const MEM_SIZE = 25; // Memory size in 64K Pakes (1600Kb) - - -import thread from "./threadman_thread.js"; -import os from "os"; -import Worker from "web-worker"; - -class Deferred { - constructor() { - this.promise = new Promise((resolve, reject)=> { - this.reject = reject; - this.resolve = resolve; - }); - } -} - -function sleep(ms) { - return new Promise(resolve => setTimeout(resolve, ms)); -} - -function base64ToArrayBuffer(base64) { - if (process.browser) { - var binary_string = window.atob(base64); - var len = binary_string.length; - var bytes = new Uint8Array(len); - for (var i = 0; i < len; i++) { - bytes[i] = binary_string.charCodeAt(i); - } - return bytes; - } else { - return new Uint8Array(Buffer.from(base64, "base64")); - } -} - -function stringToBase64(str) { - if (process.browser) { - return window.btoa(str); - } else { - return Buffer.from(str).toString("base64"); - } -} - -const threadSource = stringToBase64("(" + thread.toString() + ")(self)"); -const workerSource = "data:application/javascript;base64," + threadSource; - - - -export default async function buildThreadManager(wasm, singleThread) { - const tm = new ThreadManager(); - - tm.memory = new WebAssembly.Memory({initial:MEM_SIZE}); - tm.u8 = new Uint8Array(tm.memory.buffer); - tm.u32 = new Uint32Array(tm.memory.buffer); - - const wasmModule = await WebAssembly.compile(base64ToArrayBuffer(wasm.code)); - - tm.instance = await WebAssembly.instantiate(wasmModule, { - env: { - "memory": tm.memory - } - }); - - tm.singleThread = singleThread; - tm.initalPFree = tm.u32[0]; // Save the Pointer to free space. - tm.pq = wasm.pq; - tm.pr = wasm.pr; - tm.pG1gen = wasm.pG1gen; - tm.pG1zero = wasm.pG1zero; - tm.pG2gen = wasm.pG2gen; - tm.pG2zero = wasm.pG2zero; - tm.pOneT = wasm.pOneT; - - // tm.pTmp0 = tm.alloc(curve.G2.F.n8*3); - // tm.pTmp1 = tm.alloc(curve.G2.F.n8*3); - - - if (singleThread) { - tm.code = base64ToArrayBuffer(wasm.code); - tm.taskManager = thread(); - await tm.taskManager([{ - cmd: "INIT", - init: MEM_SIZE, - code: tm.code.slice() - }]); - tm.concurrency = 1; - } else { - tm.workers = []; - tm.pendingDeferreds = []; - tm.working = []; - - let concurrency; - - if ((typeof(navigator) === "object") && navigator.hardwareConcurrency) { - concurrency = navigator.hardwareConcurrency; - } else { - concurrency = os.cpus().length; - } - // Limit to 64 threads for memory reasons. - if (concurrency>64) concurrency=64; - tm.concurrency = concurrency; - - for (let i = 0; i 0); i++) { - if (this.working[i] == false) { - const work = this.actionQueue.shift(); - this.postAction(i, work.data, work.transfers, work.deferred); - } - } - } - - queueAction(actionData, transfers) { - const d = new Deferred(); - - if (this.singleThread) { - const res = this.taskManager(actionData); - d.resolve(res); - } else { - this.actionQueue.push({ - data: actionData, - transfers: transfers, - deferred: d - }); - this.processWorks(); - } - return d.promise; - } - - resetMemory() { - this.u32[0] = this.initalPFree; - } - - allocBuff(buff) { - const pointer = this.alloc(buff.byteLength); - this.setBuff(pointer, buff); - return pointer; - } - - getBuff(pointer, length) { - return this.u8.slice(pointer, pointer+ length); - } - - setBuff(pointer, buffer) { - this.u8.set(new Uint8Array(buffer), pointer); - } - - alloc(length) { - while (this.u32[0] & 3) this.u32[0]++; // Return always aligned pointers - const res = this.u32[0]; - this.u32[0] += length; - return res; - } - - async terminate() { - for (let i=0; i memory.buffer.byteLength) { - const currentPages = memory.buffer.byteLength / 0x10000; - let requiredPages = Math.floor((u32[0] + length) / 0x10000)+1; - if (requiredPages>MAXMEM) requiredPages=MAXMEM; - memory.grow(requiredPages-currentPages); - } - return res; - } - - function allocBuffer(buffer) { - const p = alloc(buffer.byteLength); - setBuffer(p, buffer); - return p; - } - - function getBuffer(pointer, length) { - const u8 = new Uint8Array(memory.buffer); - return new Uint8Array(u8.buffer, u8.byteOffset + pointer, length); - } - - function setBuffer(pointer, buffer) { - const u8 = new Uint8Array(memory.buffer); - u8.set(new Uint8Array(buffer), pointer); - } - - function runTask(task) { - if (task[0].cmd == "INIT") { - return init(task[0]); - } - const ctx = { - vars: [], - out: [] - }; - const u32a = new Uint32Array(memory.buffer, 0, 1); - const oldAlloc = u32a[0]; - for (let i=0; i 0) { if (o-4 >= 0) { o -= 4; - buffV.setUint32(o, Number(r & 0xFFFFFFFFn)); - r = r >> 32n; + buffV.setUint32(o, Number(r & BigInt(0xFFFFFFFF))); + r = r >> BigInt(32); } else if (o-2 >= 0) { o -= 2; - buffV.setUint16(o, Number(r & 0xFFFFn)); - r = r >> 16n; + buffV.setUint16(o, Number(r & BigInt(0xFFFF))); + r = r >> BigInt(16); } else { o -= 1; - buffV.setUint8(o, Number(r & 0xFFn)); - r = r >> 8n; + buffV.setUint8(o, Number(r & BigInt(0xFF))); + r = r >> BigInt(8); } } if (r) { @@ -89,7 +89,7 @@ export function beInt2Buff(n, len) { export function leBuff2int(buff) { - let res = 0n; + let res = BigInt(0); let i = 0; const buffV = new DataView(buff.buffer, buff.byteOffset, buff.byteLength); while (i> 32n; + r = r >> BigInt(32); } else if (o+2 <= len) { - buffV.setUint16(Number(o, r & 0xFFFFn), true ); + buffV.setUint16(Number(o, r & BigInt(0xFFFF)), true ); o += 2; - r = r >> 16n; + r = r >> BigInt(16); } else { - buffV.setUint8(Number(o, r & 0xFFn), true ); + buffV.setUint8(Number(o, r & BigInt(0xFF)), true ); o += 1; - r = r >> 8n; + r = r >> BigInt(8); } } if (r) { diff --git a/src/wasm_curve.js b/src/wasm_curve.js deleted file mode 100644 index dcb27c7..0000000 --- a/src/wasm_curve.js +++ /dev/null @@ -1,389 +0,0 @@ - - -import * as Scalar from "./scalar.js"; -import buildBatchConvert from "./engine_batchconvert.js"; - -export default class WasmCurve { - - constructor(tm, prefix, F, pGen, pGb, cofactor) { - this.tm = tm; - this.prefix = prefix; - this.F = F; - - this.pOp1 = tm.alloc(F.n8*3); - this.pOp2 = tm.alloc(F.n8*3); - this.pOp3 = tm.alloc(F.n8*3); - this.tm.instance.exports[prefix + "_zero"](this.pOp1); - this.zero = this.tm.getBuff(this.pOp1, F.n8*3); - this.tm.instance.exports[prefix + "_zeroAffine"](this.pOp1); - this.zeroAffine = this.tm.getBuff(this.pOp1, F.n8*2); - this.one = this.tm.getBuff(pGen, F.n8*3); - this.g = this.one; - this.oneAffine = this.tm.getBuff(pGen, F.n8*2); - this.gAffine = this.oneAffine; - this.b = this.tm.getBuff(pGb, F.n8); - - if (cofactor) { - this.cofactor = Scalar.toLEBuff(cofactor); - } - - this.negone = this.neg(this.one); - this.two = this.add(this.one, this.one); - - this.batchLEMtoC = buildBatchConvert(tm, prefix + "_batchLEMtoC", F.n8*2, F.n8); - this.batchLEMtoU = buildBatchConvert(tm, prefix + "_batchLEMtoU", F.n8*2, F.n8*2); - this.batchCtoLEM = buildBatchConvert(tm, prefix + "_batchCtoLEM", F.n8, F.n8*2); - this.batchUtoLEM = buildBatchConvert(tm, prefix + "_batchUtoLEM", F.n8*2, F.n8*2); - this.batchToJacobian = buildBatchConvert(tm, prefix + "_batchToJacobian", F.n8*2, F.n8*3); - this.batchToAffine = buildBatchConvert(tm, prefix + "_batchToAffine", F.n8*3, F.n8*2); - } - - op2(opName, a, b) { - this.tm.setBuff(this.pOp1, a); - this.tm.setBuff(this.pOp2, b); - this.tm.instance.exports[this.prefix + opName](this.pOp1, this.pOp2, this.pOp3); - return this.tm.getBuff(this.pOp3, this.F.n8*3); - } - - op2bool(opName, a, b) { - this.tm.setBuff(this.pOp1, a); - this.tm.setBuff(this.pOp2, b); - return !!this.tm.instance.exports[this.prefix + opName](this.pOp1, this.pOp2, this.pOp3); - } - - op1(opName, a) { - this.tm.setBuff(this.pOp1, a); - this.tm.instance.exports[this.prefix + opName](this.pOp1, this.pOp3); - return this.tm.getBuff(this.pOp3, this.F.n8*3); - } - - op1Affine(opName, a) { - this.tm.setBuff(this.pOp1, a); - this.tm.instance.exports[this.prefix + opName](this.pOp1, this.pOp3); - return this.tm.getBuff(this.pOp3, this.F.n8*2); - } - - op1Bool(opName, a) { - this.tm.setBuff(this.pOp1, a); - return !!this.tm.instance.exports[this.prefix + opName](this.pOp1, this.pOp3); - } - - add(a,b) { - if (a.byteLength == this.F.n8*3) { - if (b.byteLength == this.F.n8*3) { - return this.op2("_add", a, b); - } else if (b.byteLength == this.F.n8*2) { - return this.op2("_addMixed", a, b); - } else { - throw new Error("invalid point size"); - } - } else if (a.byteLength == this.F.n8*2) { - if (b.byteLength == this.F.n8*3) { - return this.op2("_addMixed", b, a); - } else if (b.byteLength == this.F.n8*2) { - return this.op2("_addAffine", a, b); - } else { - throw new Error("invalid point size"); - } - } else { - throw new Error("invalid point size"); - } - } - - sub(a,b) { - if (a.byteLength == this.F.n8*3) { - if (b.byteLength == this.F.n8*3) { - return this.op2("_sub", a, b); - } else if (b.byteLength == this.F.n8*2) { - return this.op2("_subMixed", a, b); - } else { - throw new Error("invalid point size"); - } - } else if (a.byteLength == this.F.n8*2) { - if (b.byteLength == this.F.n8*3) { - return this.op2("_subMixed", b, a); - } else if (b.byteLength == this.F.n8*2) { - return this.op2("_subAffine", a, b); - } else { - throw new Error("invalid point size"); - } - } else { - throw new Error("invalid point size"); - } - } - - neg(a) { - if (a.byteLength == this.F.n8*3) { - return this.op1("_neg", a); - } else if (a.byteLength == this.F.n8*2) { - return this.op1Affine("_negAffine", a); - } else { - throw new Error("invalid point size"); - } - } - - double(a) { - if (a.byteLength == this.F.n8*3) { - return this.op1("_double", a); - } else if (a.byteLength == this.F.n8*2) { - return this.op1("_doubleAffine", a); - } else { - throw new Error("invalid point size"); - } - } - - isZero(a) { - if (a.byteLength == this.F.n8*3) { - return this.op1Bool("_isZero", a); - } else if (a.byteLength == this.F.n8*2) { - return this.op1Bool("_isZeroAffine", a); - } else { - throw new Error("invalid point size"); - } - } - - timesScalar(a, s) { - if (!(s instanceof Uint8Array)) { - s = Scalar.toLEBuff(Scalar.e(s)); - } - let fnName; - if (a.byteLength == this.F.n8*3) { - fnName = this.prefix + "_timesScalar"; - } else if (a.byteLength == this.F.n8*2) { - fnName = this.prefix + "_timesScalarAffine"; - } else { - throw new Error("invalid point size"); - } - this.tm.setBuff(this.pOp1, a); - this.tm.setBuff(this.pOp2, s); - this.tm.instance.exports[fnName](this.pOp1, this.pOp2, s.byteLength, this.pOp3); - return this.tm.getBuff(this.pOp3, this.F.n8*3); - } - - timesFr(a, s) { - let fnName; - if (a.byteLength == this.F.n8*3) { - fnName = this.prefix + "_timesFr"; - } else if (a.byteLength == this.F.n8*2) { - fnName = this.prefix + "_timesFrAffine"; - } else { - throw new Error("invalid point size"); - } - this.tm.setBuff(this.pOp1, a); - this.tm.setBuff(this.pOp2, s); - this.tm.instance.exports[fnName](this.pOp1, this.pOp2, this.pOp3); - return this.tm.getBuff(this.pOp3, this.F.n8*3); - } - - eq(a,b) { - if (a.byteLength == this.F.n8*3) { - if (b.byteLength == this.F.n8*3) { - return this.op2bool("_eq", a, b); - } else if (b.byteLength == this.F.n8*2) { - return this.op2bool("_eqMixed", a, b); - } else { - throw new Error("invalid point size"); - } - } else if (a.byteLength == this.F.n8*2) { - if (b.byteLength == this.F.n8*3) { - return this.op2bool("_eqMixed", b, a); - } else if (b.byteLength == this.F.n8*2) { - return this.op2bool("_eqAffine", a, b); - } else { - throw new Error("invalid point size"); - } - } else { - throw new Error("invalid point size"); - } - } - - toAffine(a) { - if (a.byteLength == this.F.n8*3) { - return this.op1Affine("_toAffine", a); - } else if (a.byteLength == this.F.n8*2) { - return a; - } else { - throw new Error("invalid point size"); - } - } - - toJacobian(a) { - if (a.byteLength == this.F.n8*3) { - return a; - } else if (a.byteLength == this.F.n8*2) { - return this.op1("_toJacobian", a); - } else { - throw new Error("invalid point size"); - } - } - - toRprUncompressed(arr, offset, a) { - this.tm.setBuff(this.pOp1, a); - if (a.byteLength == this.F.n8*3) { - this.tm.instance.exports[this.prefix + "_toAffine"](this.pOp1, this.pOp1); - } else if (a.byteLength != this.F.n8*2) { - throw new Error("invalid point size"); - } - this.tm.instance.exports[this.prefix + "_LEMtoU"](this.pOp1, this.pOp1); - const res = this.tm.getBuff(this.pOp1, this.F.n8*2); - arr.set(res, offset); - } - - fromRprUncompressed(arr, offset) { - const buff = arr.slice(offset, offset + this.F.n8*2); - this.tm.setBuff(this.pOp1, buff); - this.tm.instance.exports[this.prefix + "_UtoLEM"](this.pOp1, this.pOp1); - return this.tm.getBuff(this.pOp1, this.F.n8*2); - } - - toRprCompressed(arr, offset, a) { - this.tm.setBuff(this.pOp1, a); - if (a.byteLength == this.F.n8*3) { - this.tm.instance.exports[this.prefix + "_toAffine"](this.pOp1, this.pOp1); - } else if (a.byteLength != this.F.n8*2) { - throw new Error("invalid point size"); - } - this.tm.instance.exports[this.prefix + "_LEMtoC"](this.pOp1, this.pOp1); - const res = this.tm.getBuff(this.pOp1, this.F.n8); - arr.set(res, offset); - } - - fromRprCompressed(arr, offset) { - const buff = arr.slice(offset, offset + this.F.n8); - this.tm.setBuff(this.pOp1, buff); - this.tm.instance.exports[this.prefix + "_CtoLEM"](this.pOp1, this.pOp2); - return this.tm.getBuff(this.pOp2, this.F.n8*2); - } - - toUncompressed(a) { - const buff = new Uint8Array(this.F.n8*2); - this.toRprUncompressed(buff, 0, a); - return buff; - } - - toRprLEM(arr, offset, a) { - if (a.byteLength == this.F.n8*2) { - arr.set(a, offset); - return; - } else if (a.byteLength == this.F.n8*3) { - this.tm.setBuff(this.pOp1, a); - this.tm.instance.exports[this.prefix + "_toAffine"](this.pOp1, this.pOp1); - const res = this.tm.getBuff(this.pOp1, this.F.n8*2); - arr.set(res, offset); - } else { - throw new Error("invalid point size"); - } - } - - fromRprLEM(arr, offset) { - offset = offset || 0; - return arr.slice(offset, offset+this.F.n8*2); - } - - toString(a, radix) { - if (a.byteLength == this.F.n8*3) { - const x = this.F.toString(a.slice(0, this.F.n8), radix); - const y = this.F.toString(a.slice(this.F.n8, this.F.n8*2), radix); - const z = this.F.toString(a.slice(this.F.n8*2), radix); - return `[ ${x}, ${y}, ${z} ]`; - } else if (a.byteLength == this.F.n8*2) { - const x = this.F.toString(a.slice(0, this.F.n8), radix); - const y = this.F.toString(a.slice(this.F.n8), radix); - return `[ ${x}, ${y} ]`; - } else { - throw new Error("invalid point size"); - } - } - - - fromRng(rng) { - const F = this.F; - let P = []; - let greatest; - let x3b; - do { - P[0] = F.fromRng(rng); - greatest = rng.nextBool(); - x3b = F.add(F.mul(F.square(P[0]), P[0]), this.b); - } while (!F.isSquare(x3b)); - - P[1] = F.sqrt(x3b); - - const s = F.isNegative(P[1]); - if (greatest ^ s) P[1] = F.neg(P[1]); - - let Pbuff = new Uint8Array(this.F.n8*2); - Pbuff.set(P[0]); - Pbuff.set(P[1], this.F.n8); - - if (this.cofactor) { - Pbuff = this.timesScalar(Pbuff, this.cofactor); - } - - return Pbuff; - } - - - - toObject(a) { - if (this.isZero(a)) { - return [ - this.F.toObject(this.F.zero), - this.F.toObject(this.F.one), - this.F.toObject(this.F.zero), - ]; - } - const x = this.F.toObject(a.slice(0, this.F.n8)); - const y = this.F.toObject(a.slice(this.F.n8, this.F.n8*2)); - let z; - if (a.byteLength == this.F.n8*3) { - z = this.F.toObject(a.slice(this.F.n8*2, this.F.n8*3)); - } else { - z = this.F.toObject(this.F.one); - } - return [x, y, z]; - } - - fromObject(a) { - const x = this.F.fromObject(a[0]); - const y = this.F.fromObject(a[1]); - let z; - if (a.length==3) { - z = this.F.fromObject(a[2]); - } else { - z = this.F.one; - } - if (this.F.isZero(z, this.F.one)) { - return this.zeroAffine; - } else if (this.F.eq(z, this.F.one)) { - const buff = new Uint8Array(this.F.n8*2); - buff.set(x); - buff.set(y, this.F.n8); - return buff; - } else { - const buff = new Uint8Array(this.F.n8*3); - buff.set(x); - buff.set(y, this.F.n8); - buff.set(z, this.F.n8*2); - return buff; - } - } - - e(a) { - if (a instanceof Uint8Array) return a; - return this.fromObject(a); - } - - x(a) { - const tmp = this.toAffine(a); - return tmp.slice(0, this.F.n8); - } - - y(a) { - const tmp = this.toAffine(a); - return tmp.slice(this.F.n8); - } - -} - - diff --git a/src/wasm_field1.js b/src/wasm_field1.js deleted file mode 100644 index df7fdf6..0000000 --- a/src/wasm_field1.js +++ /dev/null @@ -1,238 +0,0 @@ - - -import * as Scalar from "./scalar.js"; -import * as utils from "./utils.js"; -import { getThreadRng } from "./random.js"; -import buildBatchConvert from "./engine_batchconvert.js"; - - -export default class WasmField1 { - - constructor(tm, prefix, n8, p) { - this.tm = tm; - this.prefix = prefix; - - this.p = p; - this.n8 = n8; - this.type = "F1"; - this.m = 1; - - this.half = Scalar.shiftRight(p, Scalar.one); - this.bitLength = Scalar.bitLength(p); - this.mask = Scalar.sub(Scalar.shiftLeft(Scalar.one, this.bitLength), Scalar.one); - - this.pOp1 = tm.alloc(n8); - this.pOp2 = tm.alloc(n8); - this.pOp3 = tm.alloc(n8); - this.tm.instance.exports[prefix + "_zero"](this.pOp1); - this.zero = this.tm.getBuff(this.pOp1, this.n8); - this.tm.instance.exports[prefix + "_one"](this.pOp1); - this.one = this.tm.getBuff(this.pOp1, this.n8); - - this.negone = this.neg(this.one); - this.two = this.add(this.one, this.one); - - this.n64 = Math.floor(n8/8); - this.n32 = Math.floor(n8/4); - - if(this.n64*8 != this.n8) { - throw new Error("n8 must be a multiple of 8"); - } - - this.half = Scalar.shiftRight(this.p, Scalar.one); - this.nqr = this.two; - let r = this.exp(this.nqr, this.half); - while (!this.eq(r, this.negone)) { - this.nqr = this.add(this.nqr, this.one); - r = this.exp(this.nqr, this.half); - } - - this.shift = this.mul(this.nqr, this.nqr); - this.shiftInv = this.inv(this.shift); - - this.s = 0; - let t = Scalar.sub(this.p, Scalar.one); - - while ( !Scalar.isOdd(t) ) { - this.s = this.s + 1; - t = Scalar.shiftRight(t, Scalar.one); - } - - this.w = []; - this.w[this.s] = this.exp(this.nqr, t); - - for (let i= this.s-1; i>=0; i--) { - this.w[i] = this.square(this.w[i+1]); - } - - if (!this.eq(this.w[0], this.one)) { - throw new Error("Error calculating roots of unity"); - } - - this.batchToMontgomery = buildBatchConvert(tm, prefix + "_batchToMontgomery", this.n8, this.n8); - this.batchFromMontgomery = buildBatchConvert(tm, prefix + "_batchFromMontgomery", this.n8, this.n8); - } - - - op2(opName, a, b) { - this.tm.setBuff(this.pOp1, a); - this.tm.setBuff(this.pOp2, b); - this.tm.instance.exports[this.prefix + opName](this.pOp1, this.pOp2, this.pOp3); - return this.tm.getBuff(this.pOp3, this.n8); - } - - op2Bool(opName, a, b) { - this.tm.setBuff(this.pOp1, a); - this.tm.setBuff(this.pOp2, b); - return !!this.tm.instance.exports[this.prefix + opName](this.pOp1, this.pOp2); - } - - op1(opName, a) { - this.tm.setBuff(this.pOp1, a); - this.tm.instance.exports[this.prefix + opName](this.pOp1, this.pOp3); - return this.tm.getBuff(this.pOp3, this.n8); - } - - op1Bool(opName, a) { - this.tm.setBuff(this.pOp1, a); - return !!this.tm.instance.exports[this.prefix + opName](this.pOp1, this.pOp3); - } - - add(a,b) { - return this.op2("_add", a, b); - } - - - eq(a,b) { - return this.op2Bool("_eq", a, b); - } - - isZero(a) { - return this.op1Bool("_isZero", a); - } - - sub(a,b) { - return this.op2("_sub", a, b); - } - - neg(a) { - return this.op1("_neg", a); - } - - inv(a) { - return this.op1("_inverse", a); - } - - toMontgomery(a) { - return this.op1("_toMontgomery", a); - } - - fromMontgomery(a) { - return this.op1("_fromMontgomery", a); - } - - mul(a,b) { - return this.op2("_mul", a, b); - } - - div(a, b) { - this.tm.setBuff(this.pOp1, a); - this.tm.setBuff(this.pOp2, b); - this.tm.instance.exports[this.prefix + "_inverse"](this.pOp2, this.pOp2); - this.tm.instance.exports[this.prefix + "_mul"](this.pOp1, this.pOp2, this.pOp3); - return this.tm.getBuff(this.pOp3, this.n8); - } - - square(a) { - return this.op1("_square", a); - } - - isSquare(a) { - return this.op1Bool("_isSquare", a); - } - - sqrt(a) { - return this.op1("_sqrt", a); - } - - exp(a, b) { - if (!(b instanceof Uint8Array)) { - b = Scalar.toLEBuff(Scalar.e(b)); - } - this.tm.setBuff(this.pOp1, a); - this.tm.setBuff(this.pOp2, b); - this.tm.instance.exports[this.prefix + "_exp"](this.pOp1, this.pOp2, b.byteLength, this.pOp3); - return this.tm.getBuff(this.pOp3, this.n8); - } - - isNegative(a) { - return this.op1Bool("_isNegative", a); - } - - e(a, b) { - if (a instanceof Uint8Array) return a; - let ra = Scalar.e(a, b); - if (Scalar.isNegative(ra)) { - ra = Scalar.neg(ra); - if (Scalar.gt(ra, this.p)) { - ra = Scalar.mod(ra, this.p); - } - ra = Scalar.sub(this.p, ra); - } else { - if (Scalar.gt(ra, this.p)) { - ra = Scalar.mod(ra, this.p); - } - } - const buff = utils.leInt2Buff(ra, this.n8); - return this.toMontgomery(buff); - } - - toString(a, radix) { - const an = this.fromMontgomery(a); - const s = Scalar.fromRprLE(an, 0); - return Scalar.toString(s, radix); - } - - fromRng(rng) { - let v; - const buff = new Uint8Array(this.n8); - do { - v = Scalar.zero; - for (let i=0; i. -*/ - -import chai from "chai"; - -import * as Scalar from "../src/scalar.js"; -import buildBn128 from "../src/bn128.js"; -import F1Field from "../src/f1field.js"; - -const assert = chai.assert; - - -describe("F1 testing", () => { - let bn128; - before( async() => { - bn128 = await buildBn128(); - }); - after( async() => { - bn128.terminate(); - }); - - it("Should compute euclidean", () => { - const F = new F1Field(Scalar.fromString("7")); - const res = F.inv(F.e(4)); - - assert(F.eq(res, F.e(2))); - }); - - it("Should multiply and divide in F1", () => { - const a = bn128.F1.e("1"); - const b = bn128.F1.e("-1"); - const c = bn128.F1.mul(a,b); - const d = bn128.F1.div(c,b); - - assert(bn128.F1.eq(a, d)); - }); - - it("Should compute sqrts", () => { - const F = new F1Field(bn128.r); - const a = F.e("4"); - let b = F.sqrt(a); - assert(F.eq(F.e(0), F.sqrt(F.e("0")))); - assert(F.eq(b, F.e("2"))); - // assert(F.sqrt(F.nqr) === null); - }); - - it("Should compute sqrt of 100 random numbers", () => { - const F = new F1Field(bn128.r); - for (let j=0;j<100; j++) { - let a = F.random(); - let s = F.sqrt(a); - if (s != null) { - assert(F.eq(F.square(s), a)); - } - } - }); -}); - -describe("Curve G1 Test", () => { - let bn128; - before( async() => { - bn128 = await buildBn128(); - }); - after( async() => { - bn128.terminate(); - }); - - it("r*one == 0", () => { - const res = bn128.G1.timesScalar(bn128.G1.g, bn128.r); - - assert(bn128.G1.eq(res, bn128.G1.zero), "G1 does not have range r"); - }); - - it("Should add match in various in G1", () => { - - const r1 = bn128.Fr.e(33); - const r2 = bn128.Fr.e(44); - - const gr1 = bn128.G1.timesFr(bn128.G1.g, r1); - const gr2 = bn128.G1.timesFr(bn128.G1.g, r2); - - const grsum1 = bn128.G1.add(gr1, gr2); - - const grsum2 = bn128.G1.timesFr(bn128.G1.g, bn128.Fr.add(r1, r2)); - - assert(bn128.G1.eq(grsum1, grsum2)); - }); -}); - -describe("Curve G2 Test", () => { - let bn128; - before( async() => { - bn128 = await buildBn128(); - }); - after( async() => { - bn128.terminate(); - }); - - it ("r*one == 0", () => { - const res = bn128.G2.timesScalar(bn128.G2.g, bn128.r); - - assert(bn128.G2.eq(res, bn128.G2.zero), "G2 does not have range r"); - }); - - it("Should add match in various in G2", () => { - const r1 = bn128.Fr.e(33); - const r2 = bn128.Fr.e(44); - - const gr1 = bn128.G2.timesFr(bn128.G2.g, r1); - const gr2 = bn128.G2.timesFr(bn128.G2.g, r2); - - const grsum1 = bn128.G2.add(gr1, gr2); - - const grsum2 = bn128.G2.timesFr(bn128.G2.g, bn128.Fr.add(r1, r2)); - - /* - console.log(G2.toString(grsum1)); - console.log(G2.toString(grsum2)); - */ - - assert(bn128.G2.eq(grsum1, grsum2)); - }); -}); - -describe("F6 testing", () => { - let bn128; - before( async() => { - bn128 = await buildBn128(); - }); - after( async() => { - bn128.terminate(); - }); - - it("Should multiply and divide in F6", () => { - - const a = bn128.F6.fromObject([ - [Scalar.e("1"), Scalar.e("2")], - [Scalar.e("3"), Scalar.e("4")], - [Scalar.e("5"), Scalar.e("6")] - ]); - const b = bn128.F6.fromObject([ - [Scalar.e("12"), Scalar.e("11")], - [Scalar.e("10"), Scalar.e("9")], - [Scalar.e("8"), Scalar.e("7")] - ]); - const c = bn128.F6.mul(a,b); - const d = bn128.F6.div(c,b); - - assert(bn128.F6.eq(a, d)); - }); -}); - -describe("F12 testing", () => { - let bn128; - before( async() => { - bn128 = await buildBn128(); - }); - after( async() => { - bn128.terminate(); - }); - - it("Should multiply and divide in F12", () => { - const a = bn128.Gt.fromObject([ - [ - [Scalar.e("1"), Scalar.e("2")], - [Scalar.e("3"), Scalar.e("4")], - [Scalar.e("5"), Scalar.e("6")] - ], - [ - [Scalar.e("7"), Scalar.e("8")], - [Scalar.e("9"), Scalar.e("10")], - [Scalar.e("11"), Scalar.e("12")] - ] - ]); - const b = bn128.Gt.fromObject([ - [ - [Scalar.e("12"), Scalar.e("11")], - [Scalar.e("10"), Scalar.e("9")], - [Scalar.e("8"), Scalar.e("7")] - ], - [ - [Scalar.e("6"), Scalar.e("5")], - [Scalar.e("4"), Scalar.e("3")], - [Scalar.e("2"), Scalar.e("1")] - ] - ]); - const c = bn128.F12.mul(a,b); - const d = bn128.F12.div(c,b); - - assert(bn128.F12.eq(a, d)); - }); -}); - -describe("Pairing", () => { - let bn128; - before( async() => { - bn128 = await buildBn128(); - }); - after( async() => { - bn128.terminate(); - }); - - /* - it("Should match pairing", () => { - for (let i=0; i<1; i++) { - const bn128 = new BN128(); - - const g1a = bn128.G1.mulScalar(bn128.G1.g, 25); - const g2a = bn128.G2.mulScalar(bn128.G2.g, 30); - - const g1b = bn128.G1.mulScalar(bn128.G1.g, 30); - const g2b = bn128.G2.mulScalar(bn128.G2.g, 25); - - const pre1a = bn128.prepareG1(g1a); - const pre2a = bn128.prepareG2(g2a); - const pre1b = bn128.prepareG1(g1b); - const pre2b = bn128.prepareG2(g2b); - - const r1 = bn128.millerLoop(pre1a, pre2a); - const r2 = bn128.millerLoop(pre1b, pre2b); - - const rbe = bn128.F12.mul(r1, bn128.F12.inverse(r2)); - - const res = bn128.finalExponentiation(rbe); - - assert(bn128.F12.eq(res, bn128.F12.one)); - } - }).timeout(10000); - */ - it("Should generate another pairing pairing", () => { - for (let i=0; i<1; i++) { - const g1a = bn128.G1.timesScalar(bn128.G1.g, 10); - const g2a = bn128.G2.timesScalar(bn128.G2.g, 1); - - const g1b = bn128.G1.timesScalar(bn128.G1.g, 1); - const g2b = bn128.G2.timesScalar(bn128.G2.g, 10); - - const pre1a = bn128.prepareG1(g1a); - const pre2a = bn128.prepareG2(g2a); - const pre1b = bn128.prepareG1(g1b); - const pre2b = bn128.prepareG2(g2b); - - const r1 = bn128.millerLoop(pre1a, pre2a); - const r2 = bn128.finalExponentiation(r1); - - const r3 = bn128.millerLoop(pre1b, pre2b); - - const r4 = bn128.finalExponentiation(r3); - - /* - console.log("ML1: " ,bn128.F12.toString(r1)); - console.log("FE1: " ,bn128.F12.toString(r2)); - console.log("ML2: " ,bn128.F12.toString(r3)); - console.log("FE2: " ,bn128.F12.toString(r4)); - */ - - assert(bn128.F12.eq(r2, r4)); - - - /* - const r2 = bn128.millerLoop(pre1b, pre2b); - - const rbe = bn128.F12.mul(r1, bn128.F12.inverse(r2)); - - const res = bn128.finalExponentiation(rbe); - - assert(bn128.F12.eq(res, bn128.F12.one)); - */ - } - }).timeout(10000); -}); - -describe("Compressed Form", () => { - let bn128; - before( async() => { - bn128 = await buildBn128(); - }); - after( async() => { - bn128.terminate(); - }); - - it("Should test rpr of G2", () => { - const P1 = bn128.G2.fromObject([ - [ - Scalar.e("1b2327ce7815d3358fe89fd8e5695305ed23682db29569f549ab8f48cae1f1c4",16), - Scalar.e("1ed41ca6b3edc06237af648f845c270ff83bcde333f17863c1b71a43b271b46d",16) - ], - [ - Scalar.e("122057912ab892abcf2e729f0f342baea3fe1b484840eb97c7d78cd7530f4ab5",16), - Scalar.e("2cb317fd40d56eeb17b0c1ff9443661a42ec00cea060012873b3f643f1a5bff8",16) - ], - [ - Scalar.one, - Scalar.zero - ] - ]); - const buff = new Uint8Array(64); - bn128.G2.toRprCompressed(buff, 0, P1); - - const P2 = bn128.G2.fromRprCompressed(buff, 0); - - /* - console.log(bn128.G2.toString(P1, 16)); - console.log(bn128.G2.toString(P2, 16)); - */ - - assert(bn128.G2.eq(P1,P2)); - }).timeout(10000); -}); diff --git a/test/bn128.js b/test/bn128.js deleted file mode 100644 index 79d0a74..0000000 --- a/test/bn128.js +++ /dev/null @@ -1,181 +0,0 @@ -import assert from "assert"; -import buildBn128 from "../src/bn128.js"; -import {log2} from "../src/utils.js"; -import BigBuffer from "../src/bigbuffer.js"; - -describe("bn128", async function () { - this.timeout(10000000); - - const logger = { - error: (msg) => { console.log("ERROR: "+msg); }, - warning: (msg) => { console.log("WARNING: "+msg); }, - info: (msg) => { console.log("INFO: "+msg); }, - debug: (msg) => { console.log("DEBUG: "+msg); }, - }; - - let bn128; - before( async() => { - bn128 = await buildBn128(); - }); - after( async() => { - bn128.terminate(); - }); - - it("It shoud do an inverse FFT in G1", async () => { - const Fr = bn128.Fr; - const G1 = bn128.G1; - - const a = []; - for (let i=0; i<8; i++) a[i] = Fr.e(i+1); - - const aG_expected = []; - for (let i=0; i<8; i++) aG_expected[i] = G1.timesFr(G1.g, a[i]); - - const A = await bn128.Fr.fft(a); - - - const AG = []; - for (let i=0; i<8; i++) AG[i] = G1.timesFr(G1.g, A[i]); - - const aG_calculated = await G1.ifft(AG, "jacobian", "jacobian"); - - for (let i=0; i<8; i++) { - assert(G1.eq(aG_calculated[i], aG_expected[i])); - } - }); - - - it("It shoud do a big FFT/IFFT in Fr", async () => { - const Fr = bn128.Fr; - - const N = 1<<10; - - const a = new BigBuffer(N*bn128.Fr.n8); - for (let i=0; i { - const Fr = bn128.Fr; - const N = 8192*16; - - const a = []; - for (let i=0; i { - const Fr = bn128.Fr; - const N = 16; - - const oldS = Fr.s; - Fr.s = log2(N)-1; // Force ext - - const a = []; - for (let i=0; i { - const Fr = bn128.Fr; - const G1 = bn128.G1; - const N = 512; - - const a = []; - for (let i=0; i { - const Fr = bn128.Fr; - const G1 = bn128.G1; - const N = 1<<13; - - const oldS = Fr.s; - Fr.s = log2(N)-1; - - const a = []; - for (let i=0; i { - const Fr = bn128.Fr; - const G1 = bn128.G1; - const N = 1 << 10; - - const scalars = new BigBuffer(N*bn128.Fr.n8); - const bases = new BigBuffer(N*G1.F.n8*2); - let acc = Fr.zero; - for (let i=0; i. -*/ - -import chai from "chai"; - -import * as Scalar from "../src/scalar.js"; -import PolField from "../src/polfield.js"; -import ZqField from "../src/f1field.js"; - -const assert = chai.assert; - -const r = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"); - -describe("Polynomial field", () => { - it("Should compute a multiplication", () => { - const PF = new PolField(new ZqField(r)); - - const a = [PF.F.e(1), PF.F.e(2), PF.F.e(3)]; - const b = [PF.F.e(1), PF.F.e(2), PF.F.e(3)]; - const res = PF.mul(a,b); - - assert(PF.eq(res, [PF.F.e(1), PF.F.e(4), PF.F.e(10), PF.F.e(12), PF.F.e(9)])); - }); - it("Should compute a multiplication 2", () => { - const PF = new PolField(new ZqField(r)); - - const a = [PF.F.e(5), PF.F.e(1)]; - const b = [PF.F.e(-5), PF.F.e(1)]; - const res = PF.mul(a,b); - - assert(PF.eq(res, [PF.F.e(-25), PF.F.e(0), PF.F.e(1)])); - }); - it("Should compute an addition", () => { - const PF = new PolField(new ZqField(r)); - - const a = [PF.F.e(5), PF.F.e(1)]; - const b = [PF.F.e(-5), PF.F.e(1)]; - const res = PF.add(a,b); - - assert(PF.eq(res, [PF.F.e(0), PF.F.e(2)])); - }); - it("Should compute a substraction", () => { - const PF = new PolField(new ZqField(r)); - - const a = [PF.F.e(5), PF.F.e(3), PF.F.e(4)]; - const b = [PF.F.e(5), PF.F.e(1)]; - const res = PF.sub(a,b); - - assert(PF.eq(res, [PF.F.e(0), PF.F.e(2), PF.F.e(4)])); - }); - it("Should compute reciprocal", () => { - const PF = new PolField(new ZqField(r)); - - const a = PF.normalize([PF.F.e(4), PF.F.e(1), PF.F.e(-3), PF.F.e(-1), PF.F.e(2),PF.F.e(1), PF.F.e(-1), PF.F.e(1)]); - const res = PF._reciprocal(a, 3, 0); - - assert(PF.eq(res, PF.normalize([PF.F.e(12), PF.F.e(15), PF.F.e(3), PF.F.e(-4), PF.F.e(-3), PF.F.e(0), PF.F.e(1), PF.F.e(1)]))); - }); - it("Should div2", () => { - const PF = new PolField(new ZqField(r)); - - // x^6 - const a = [PF.F.e(0), PF.F.e(0), PF.F.e(0), PF.F.e(0), PF.F.e(0),PF.F.e(0), PF.F.e(1)]; - // x^5 - const b = [PF.F.e(0), PF.F.e(0), PF.F.e(0), PF.F.e(0), PF.F.e(0), PF.F.e(1)]; - - const res = PF._div2(6, b); - assert(PF.eq(res, [PF.F.e(0), PF.F.e(1)])); - - const res2 = PF.div(a,b); - assert(PF.eq(res2, [PF.F.e(0), PF.F.e(1)])); - }); - it("Should div", () => { - const PF = new PolField(new ZqField(r)); - - const a = [PF.F.e(1), PF.F.e(2), PF.F.e(3), PF.F.e(4), PF.F.e(5),PF.F.e(6), PF.F.e(7)]; - const b = [PF.F.e(8), PF.F.e(9), PF.F.e(10), PF.F.e(11), PF.F.e(12), PF.F.e(13)]; - - const c = PF.mul(a,b); - const d = PF.div(c,b); - - assert(PF.eq(a, d)); - }); - it("Should div big/small", () => { - const PF = new PolField(new ZqField(r)); - - const a = [PF.F.e(1), PF.F.e(2), PF.F.e(3), PF.F.e(4), PF.F.e(5),PF.F.e(6), PF.F.e(7)]; - const b = [PF.F.e(8), PF.F.e(9)]; - - const c = PF.mul(a,b); - const d = PF.div(c,b); - - assert(PF.eq(a, d)); - }); - it("Should div random big", () => { - const PF = new PolField(new ZqField(r)); - - let a = []; - let b = []; - for (let i=0; i<1000; i++) a.push(PF.F.e(Math.floor(Math.random()*100000) -500000)); - for (let i=0; i<900; i++) b.push(PF.F.e(Math.floor(Math.random()*100000) -500000)); - - a = PF.normalize(a); - b = PF.normalize(a); - - const c = PF.mul(a,b); - - const d = PF.div(c,b); - - assert(PF.eq(a, d)); - }).timeout(10000); - it("Should evaluate and zero", () => { - const PF = new PolField(new ZqField(r)); - const p = [PF.F.neg(PF.F.e(2)), PF.F.e(1)]; - const v = PF.eval(p, PF.F.e(2)); - assert(PF.F.eq(v, PF.F.e(0))); - }); - it("Should evaluate bigger number", () => { - const PF = new PolField(new ZqField(r)); - const p = [PF.F.e(1), PF.F.e(2), PF.F.e(3)]; - const v = PF.eval(p, PF.F.e(2)); - assert(PF.F.eq(v, PF.F.e(17))); - }); - it("Should create lagrange polynomial minmal", () => { - const PF = new PolField(new ZqField(r)); - - const points=[]; - points.push([PF.F.e(1), PF.F.e(1)]); - points.push([PF.F.e(2), PF.F.e(2)]); - points.push([PF.F.e(3), PF.F.e(5)]); - - const p=PF.lagrange(points); - - for (let i=0; i { - const PF = new PolField(new ZqField(r)); - - const points=[]; - points.push([PF.F.e(1), PF.F.e(2)]); - points.push([PF.F.e(2), PF.F.e(-2)]); - points.push([PF.F.e(3), PF.F.e(0)]); - points.push([PF.F.e(4), PF.F.e(453345)]); - - const p=PF.lagrange(points); - - for (let i=0; i { - const PF = new PolField(new ZqField(r)); - const a = [PF.F.e(1), PF.F.e(2), PF.F.e(3), PF.F.e(4), PF.F.e(5),PF.F.e(6), PF.F.e(7)]; - - const b = PF.mul(a, [PF.F.e(-7), PF.F.e(1)]); - const c = PF.ruffini(b, PF.F.e(7)); - - assert(PF.eq(a, c)); - }); - it("Should test roots", () => { - const PF = new PolField(new ZqField(r)); - let rt; - - - rt = PF.oneRoot(256, 16); - for (let i=0; i<8; i++) { - rt = PF.F.mul(rt, rt); - } - assert(PF.F.eq(rt, PF.F.one)); - - rt = PF.oneRoot(256, 15); - for (let i=0; i<8; i++) { - rt = PF.F.mul(rt, rt); - } - assert(PF.F.eq(rt, PF.F.one)); - - rt = PF.oneRoot(8, 3); - for (let i=0; i<3; i++) { - rt = PF.F.mul(rt, rt); - } - assert(PF.F.eq(rt, PF.F.one)); - - rt = PF.oneRoot(8, 0); - assert(PF.F.eq(rt, PF.F.one)); - - }); - it("Should create a polynomial with values at roots with fft", () => { - const PF = new PolField(new ZqField(r)); - const a = [PF.F.e(1), PF.F.e(2), PF.F.e(3), PF.F.e(4), PF.F.e(5),PF.F.e(6), PF.F.e(7)]; - - const p = PF.ifft(a); - - for (let i=0; i. -*/ - -import chai from "chai"; - -import * as Scalar from "../src/scalar.js"; -import ZqField from "../src/f1field.js"; -import RatField from "../src/ratfield.js"; - -const q = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"); -const Z = new ZqField(q); -const R = new RatField(Z); - -const assert = chai.assert; - -function r(a,b) { - return [Z.e(a), Z.e(b)]; -} - - -describe("Rational zq Field", () => { - it("Should compare correctly", () => { - assert( R.eq(r(3,5), r(6,10))); - assert(!R.eq(r(3,5), r(6,11))); - }); - it("Should add correctly", () => { - const a = r(7,4); - const b = r(5,12); - - assert(R.eq( R.add(a,b), r(13, 6))); - }); - it("Should substract", () => { - const a = r(7,4); - const b = r(5,12); - - assert(R.eq( R.sub(a,b), r(4, 3))); - }); - it("Should multiply", () => { - const a = r(7,4); - const b = r(5,12); - - assert(R.eq( R.mul(a,b), r(35, 48))); - }); - it("Should div", () => { - const a = r(7,4); - const b = r(5,12); - - assert(R.eq( R.div(a,b), r(7*12, 5*4))); - }); - it("Should square", () => { - const a = r(7,4); - - assert(R.eq( R.square(a), r(49, 16))); - }); - it("Should affine", () => { - const a = r(12,4); - const aa = R.affine(a); - assert(Z.eq( aa[0], Z.e(3))); - assert(Z.eq( aa[1], Z.one)); - }); - it("Should convert from Z to R", () => { - const vz = Z.e(34); - const vr = R.fromF(vz); - - assert(R.eq( vr, r(34,1))); - }); - it("Should convert from R to Z", () => { - const vr = r(32, 2); - const vz = R.toF(vr); - - assert(Z.eq( vz, Z.e(16))); - }); -}); diff --git a/test/sqrt.js b/test/sqrt.js deleted file mode 100644 index 7cb25fc..0000000 --- a/test/sqrt.js +++ /dev/null @@ -1,95 +0,0 @@ -/* - Copyright 2018 0kims association. - - This file is part of zksnark JavaScript library. - - zksnark JavaScript library is a free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License as published by the - Free Software Foundation, either version 3 of the License, or (at your option) - any later version. - - zksnark JavaScript library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - zksnark JavaScript library. If not, see . -*/ - -import chai from "chai"; - -import * as Scalar from "../src/scalar.js"; -import buildBn128 from "../src/bn128.js"; -import F1Field from "../src/f1field.js"; - -const assert = chai.assert; - - -describe("Sqrt testing", () => { - let bn128; - before( async() => { - bn128 = await buildBn128(); - }); - after( async() => { - bn128.terminate(); - }); - -/* - it("Should compute sqrts", () => { - const F = new F1Field(bn128.r); - const a = F.e(2); - const b = F.sqrt_v(a); - console.log(F.toString(b)); - }); -*/ - it("Should compute basic sqrts", () => { - const F = new F1Field(bn128.r); - assert(F.eq(F.e(0), F.sqrt(F.e("0")))); - const a = F.e("9"); - let b = F.sqrt(a); - assert(F.eq(b, F.e("3"))); - assert(F.sqrt(F.sqrt_z) === null); - }); - it("Should compute sqrt p%4 = 1", () => { - const F = new F1Field(bn128.r); - const e = Scalar.div(Scalar.pow(F.p, F.m), 2); - for (let i=0; i<100; i++) { - const x2 = F.random(); - const x = F.sqrt(x2); - if (x==null) { - assert(F.eq( F.pow(x2, e), F.negone)); - } else { - assert(F.eq(F.square(x), x2)); - } - } - }); - it("Should compute sqrt p%4 = 3", () => { - const F = new F1Field(bn128.q); - const e = Scalar.div(Scalar.pow(F.p, F.m), 2); - for (let i=0; i<100; i++) { - const x2 = F.random(); - const x = F.sqrt(x2); - if (x==null) { - assert(F.eq( F.pow(x2, e), F.negone)); - } else { - assert(F.eq(F.square(x), x2)); - } - } - }); - it("Should compute sqrt m=2 p%4 = 3", () => { - const F = bn128.F2; - const e = Scalar.div(Scalar.exp(F.F.p, F.m), 2); - for (let i=0; i<100; i++) { - const x2 = F.random(); - if (!F.isSquare(x2)) { - assert(F.eq( F.exp(x2, e), F.negone)); - } else { - const x = F.sqrt(x2); - assert(F.eq(F.square(x), x2)); - } - } - }); - -}); -