From cadbf842d22781126e5760261778108ee5bdd381 Mon Sep 17 00:00:00 2001 From: hieu-w Date: Wed, 15 Jan 2025 00:00:11 +0700 Subject: [PATCH] Lint --- build/lib.cjs/src/f1field.js | 6 +- build/lib.esm/src/f1field.js | 6 +- build/main.cjs.js | 292 +++++++++++++++++------------------ build/main.esm.js | 292 +++++++++++++++++------------------ build/main.umd.min.js | 2 +- eslint.config.mjs | 10 +- package.json | 1 + rollup.config.mjs | 2 +- src/f1field.js | 6 +- 9 files changed, 313 insertions(+), 304 deletions(-) diff --git a/build/lib.cjs/src/f1field.js b/build/lib.cjs/src/f1field.js index 4dad3d8..93edd62 100644 --- a/build/lib.cjs/src/f1field.js +++ b/build/lib.cjs/src/f1field.js @@ -1,10 +1,10 @@ 'use strict'; -var scalar = require('./scalar.js'); -var futils = require('./futils.js'); +var fft = require('./fft.js'); var fsqrt = require('./fsqrt.js'); +var futils = require('./futils.js'); var random = require('./random.js'); -var fft = require('./fft.js'); +var scalar = require('./scalar.js'); /* global BigInt */ diff --git a/build/lib.esm/src/f1field.js b/build/lib.esm/src/f1field.js index 7aa0f3e..3a150d0 100644 --- a/build/lib.esm/src/f1field.js +++ b/build/lib.esm/src/f1field.js @@ -1,8 +1,8 @@ -import { bitLength, toRprLE, toRprBE, fromRprLE, fromRprBE } from './scalar.js'; -import { exp } from './futils.js'; +import FFT from './fft.js'; import buildSqrt from './fsqrt.js'; +import { exp } from './futils.js'; import { getRandomBytes } from './random.js'; -import FFT from './fft.js'; +import { bitLength, toRprLE, toRprBE, fromRprLE, fromRprBE } from './scalar.js'; /* global BigInt */ diff --git a/build/main.cjs.js b/build/main.cjs.js index c0a0c92..5fc41b6 100644 --- a/build/main.cjs.js +++ b/build/main.cjs.js @@ -315,43 +315,130 @@ var _Scalar = /*#__PURE__*/Object.freeze({ snarkjs. If not, see . */ - /* -exports.mulScalar = (F, base, e) =>{ - let res = F.zero; - let rem = bigInt(e); - let exp = base; + This library does operations on polynomials with coefficients in a field F. - while (! rem.eq(bigInt.zero)) { - if (rem.and(bigInt.one).eq(bigInt.one)) { - res = F.add(res, exp); + A polynomial P(x) = p0 + p1 * x + p2 * x^2 + ... + pn * x^n is represented + by the array [ p0, p1, p2, ... , pn ]. + */ + +class FFT { + constructor(G, F, opMulGF) { + this.F = F; + this.G = G; + this.opMulGF = opMulGF; + + let rem = F.sqrt_t || F.t; + let s = F.sqrt_s || F.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 < nroots; j++) { + rootsi[j] = r; + r = this.F.mul(r, this.w[i]); + } + + this.roots[i] = rootsi; } + } + fft(p) { + if (p.length <= 1) return p; + const bits = log2(p.length - 1) + 1; + this._setRoots(bits); + + const m = 1 << bits; + if (p.length != m) { + throw new Error("Size must be multiple of 2"); + } + const res = __fft(this, p, bits, 0, 1); return res; -}; -*/ + } -function exp(F, base, e) { - if (isZero(e)) return F.one; + ifft(p) { + if (p.length <= 1) return p; + const bits = log2(p.length - 1) + 1; + this._setRoots(bits); + const m = 1 << bits; + if (p.length != m) { + throw new Error("Size must be multiple of 2"); + } + const res = __fft(this, p, bits, 0, 1); + const twoinvm = this.F.inv(this.F.mulScalar(this.F.one, m)); + const resn = new Array(m); + for (let i = 0; i < m; i++) { + resn[i] = this.opMulGF(res[(m - i) % m], twoinvm); + } - const n = bits(e); + return resn; + } +} - if (n.length == 0) return F.one; +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) + ); +} - let res = base; +function __fft(PF, pall, bits, offset, step) { + const n = 1 << bits; + if (n == 1) { + return [pall[offset]]; + } else if (n == 2) { + return [PF.G.add(pall[offset], pall[offset + step]), PF.G.sub(pall[offset], pall[offset + step])]; + } - for (let i = n.length - 2; i >= 0; i--) { - res = F.square(res); + 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); - if (n[i]) { - res = F.mul(res, base); - } + const out = new Array(n); + + for (let i = 0; i < ndiv2; i++) { + out[i] = PF.G.add(p1[i], PF.opMulGF(p2[i], PF.roots[bits][i])); + out[i + ndiv2] = PF.G.sub(p1[i], PF.opMulGF(p2[i], PF.roots[bits][i])); } - return res; + return out; } // Check here: https://eprint.iacr.org/2012/685.pdf @@ -516,21 +603,6 @@ function alg8_complex(F) { }; } -function getRandomBytes(n) { - let array = new Uint8Array(n); - // Browser & Node - if (typeof globalThis.crypto !== "undefined") { - // Supported - globalThis.crypto.getRandomValues(array); - } else { - // fallback - for (let i = 0; i < n; i++) { - array[i] = (Math.random() * 4294967296) >>> 0; - } - } - return array; -} - /* Copyright 2018 0kims association. @@ -550,130 +622,58 @@ function getRandomBytes(n) { 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 ]. - */ -class FFT { - constructor(G, F, opMulGF) { - this.F = F; - this.G = G; - this.opMulGF = opMulGF; - - let rem = F.sqrt_t || F.t; - let s = F.sqrt_s || F.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]); +/* +exports.mulScalar = (F, base, e) =>{ + let res = F.zero; + let rem = bigInt(e); + let exp = base; - 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--; + 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); } - 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 < nroots; j++) { - rootsi[j] = r; - r = this.F.mul(r, this.w[i]); - } + const n = bits(e); - this.roots[i] = rootsi; - } - } + if (n.length == 0) return F.one; - fft(p) { - if (p.length <= 1) return p; - const bits = log2(p.length - 1) + 1; - this._setRoots(bits); + let res = base; - const m = 1 << bits; - if (p.length != m) { - throw new Error("Size must be multiple of 2"); - } - const res = __fft(this, p, bits, 0, 1); - return res; - } + for (let i = n.length - 2; i >= 0; i--) { + res = F.square(res); - ifft(p) { - if (p.length <= 1) return p; - const bits = log2(p.length - 1) + 1; - this._setRoots(bits); - const m = 1 << bits; - if (p.length != m) { - throw new Error("Size must be multiple of 2"); - } - const res = __fft(this, p, bits, 0, 1); - const twoinvm = this.F.inv(this.F.mulScalar(this.F.one, m)); - const resn = new Array(m); - for (let i = 0; i < m; i++) { - resn[i] = this.opMulGF(res[(m - i) % m], twoinvm); + if (n[i]) { + res = F.mul(res, base); } - - return resn; } -} -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) - ); + return res; } -function __fft(PF, pall, bits, offset, step) { - const n = 1 << bits; - if (n == 1) { - return [pall[offset]]; - } else if (n == 2) { - return [PF.G.add(pall[offset], pall[offset + step]), PF.G.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 < ndiv2; i++) { - out[i] = PF.G.add(p1[i], PF.opMulGF(p2[i], PF.roots[bits][i])); - out[i + ndiv2] = PF.G.sub(p1[i], PF.opMulGF(p2[i], PF.roots[bits][i])); +function getRandomBytes(n) { + let array = new Uint8Array(n); + // Browser & Node + if (typeof globalThis.crypto !== "undefined") { + // Supported + globalThis.crypto.getRandomValues(array); + } else { + // fallback + for (let i = 0; i < n; i++) { + array[i] = (Math.random() * 4294967296) >>> 0; + } } - - return out; + return array; } /* global BigInt */ diff --git a/build/main.esm.js b/build/main.esm.js index 4fb647f..958ea9b 100644 --- a/build/main.esm.js +++ b/build/main.esm.js @@ -313,43 +313,130 @@ var _Scalar = /*#__PURE__*/Object.freeze({ snarkjs. If not, see . */ - /* -exports.mulScalar = (F, base, e) =>{ - let res = F.zero; - let rem = bigInt(e); - let exp = base; + This library does operations on polynomials with coefficients in a field F. - while (! rem.eq(bigInt.zero)) { - if (rem.and(bigInt.one).eq(bigInt.one)) { - res = F.add(res, exp); + A polynomial P(x) = p0 + p1 * x + p2 * x^2 + ... + pn * x^n is represented + by the array [ p0, p1, p2, ... , pn ]. + */ + +class FFT { + constructor(G, F, opMulGF) { + this.F = F; + this.G = G; + this.opMulGF = opMulGF; + + let rem = F.sqrt_t || F.t; + let s = F.sqrt_s || F.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 < nroots; j++) { + rootsi[j] = r; + r = this.F.mul(r, this.w[i]); + } + + this.roots[i] = rootsi; } + } + fft(p) { + if (p.length <= 1) return p; + const bits = log2(p.length - 1) + 1; + this._setRoots(bits); + + const m = 1 << bits; + if (p.length != m) { + throw new Error("Size must be multiple of 2"); + } + const res = __fft(this, p, bits, 0, 1); return res; -}; -*/ + } -function exp(F, base, e) { - if (isZero(e)) return F.one; + ifft(p) { + if (p.length <= 1) return p; + const bits = log2(p.length - 1) + 1; + this._setRoots(bits); + const m = 1 << bits; + if (p.length != m) { + throw new Error("Size must be multiple of 2"); + } + const res = __fft(this, p, bits, 0, 1); + const twoinvm = this.F.inv(this.F.mulScalar(this.F.one, m)); + const resn = new Array(m); + for (let i = 0; i < m; i++) { + resn[i] = this.opMulGF(res[(m - i) % m], twoinvm); + } - const n = bits(e); + return resn; + } +} - if (n.length == 0) return F.one; +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) + ); +} - let res = base; +function __fft(PF, pall, bits, offset, step) { + const n = 1 << bits; + if (n == 1) { + return [pall[offset]]; + } else if (n == 2) { + return [PF.G.add(pall[offset], pall[offset + step]), PF.G.sub(pall[offset], pall[offset + step])]; + } - for (let i = n.length - 2; i >= 0; i--) { - res = F.square(res); + 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); - if (n[i]) { - res = F.mul(res, base); - } + const out = new Array(n); + + for (let i = 0; i < ndiv2; i++) { + out[i] = PF.G.add(p1[i], PF.opMulGF(p2[i], PF.roots[bits][i])); + out[i + ndiv2] = PF.G.sub(p1[i], PF.opMulGF(p2[i], PF.roots[bits][i])); } - return res; + return out; } // Check here: https://eprint.iacr.org/2012/685.pdf @@ -514,21 +601,6 @@ function alg8_complex(F) { }; } -function getRandomBytes(n) { - let array = new Uint8Array(n); - // Browser & Node - if (typeof globalThis.crypto !== "undefined") { - // Supported - globalThis.crypto.getRandomValues(array); - } else { - // fallback - for (let i = 0; i < n; i++) { - array[i] = (Math.random() * 4294967296) >>> 0; - } - } - return array; -} - /* Copyright 2018 0kims association. @@ -548,130 +620,58 @@ function getRandomBytes(n) { 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 ]. - */ -class FFT { - constructor(G, F, opMulGF) { - this.F = F; - this.G = G; - this.opMulGF = opMulGF; - - let rem = F.sqrt_t || F.t; - let s = F.sqrt_s || F.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]); +/* +exports.mulScalar = (F, base, e) =>{ + let res = F.zero; + let rem = bigInt(e); + let exp = base; - 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--; + 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); } - 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 < nroots; j++) { - rootsi[j] = r; - r = this.F.mul(r, this.w[i]); - } + const n = bits(e); - this.roots[i] = rootsi; - } - } + if (n.length == 0) return F.one; - fft(p) { - if (p.length <= 1) return p; - const bits = log2(p.length - 1) + 1; - this._setRoots(bits); + let res = base; - const m = 1 << bits; - if (p.length != m) { - throw new Error("Size must be multiple of 2"); - } - const res = __fft(this, p, bits, 0, 1); - return res; - } + for (let i = n.length - 2; i >= 0; i--) { + res = F.square(res); - ifft(p) { - if (p.length <= 1) return p; - const bits = log2(p.length - 1) + 1; - this._setRoots(bits); - const m = 1 << bits; - if (p.length != m) { - throw new Error("Size must be multiple of 2"); - } - const res = __fft(this, p, bits, 0, 1); - const twoinvm = this.F.inv(this.F.mulScalar(this.F.one, m)); - const resn = new Array(m); - for (let i = 0; i < m; i++) { - resn[i] = this.opMulGF(res[(m - i) % m], twoinvm); + if (n[i]) { + res = F.mul(res, base); } - - return resn; } -} -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) - ); + return res; } -function __fft(PF, pall, bits, offset, step) { - const n = 1 << bits; - if (n == 1) { - return [pall[offset]]; - } else if (n == 2) { - return [PF.G.add(pall[offset], pall[offset + step]), PF.G.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 < ndiv2; i++) { - out[i] = PF.G.add(p1[i], PF.opMulGF(p2[i], PF.roots[bits][i])); - out[i + ndiv2] = PF.G.sub(p1[i], PF.opMulGF(p2[i], PF.roots[bits][i])); +function getRandomBytes(n) { + let array = new Uint8Array(n); + // Browser & Node + if (typeof globalThis.crypto !== "undefined") { + // Supported + globalThis.crypto.getRandomValues(array); + } else { + // fallback + for (let i = 0; i < n; i++) { + array[i] = (Math.random() * 4294967296) >>> 0; + } } - - return out; + return array; } /* global BigInt */ diff --git a/build/main.umd.min.js b/build/main.umd.min.js index ad0c5ff..f25dfbf 100644 --- a/build/main.umd.min.js +++ b/build/main.umd.min.js @@ -1 +1 @@ -!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self).Ffjavascript={})}(this,(function(t){"use strict";const n=[0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4];function i(t,n){return n&&10!=n?16==n?"0x"==t.slice(0,2)?BigInt(t):BigInt("0x"+t):void 0:BigInt(t)}const r=i;function s(t){const i=t.toString(16);return 4*(i.length-1)+n[parseInt(i[0],16)]}function e(t){return!t}function o(t,n){return BigInt(t)<>BigInt(n)}const u=o,f=h;function l(t){return(BigInt(t)&BigInt(1))==BigInt(1)}function g(t){let n=BigInt(t);const i=[];for(;n;)n&BigInt(1)?i.push(1):i.push(0),n>>=BigInt(1);return i}function p(t){if(t>BigInt(Number.MAX_SAFE_INTEGER))throw new Error("Number too big");return Number(t)}function c(t,n){return BigInt(t)-BigInt(n)}function a(t,n){return BigInt(t)**BigInt(n)}function q(t,n){return BigInt(t)/BigInt(n)}function B(t,n){return BigInt(t)%BigInt(n)}function m(t,n){return BigInt(t)==BigInt(n)}function I(t,n){return BigInt(t)&BigInt(n)}function w(t,n,i,r){const s="0000000"+i.toString(16),e=new Uint32Array(t.buffer,n,r/4),o=1+(4*(s.length-7)-1>>5);for(let t=0;t>5);for(let t=0;te[e.length-n-1]=t.toString(16).padStart(8,"0"))),i(e.join(""),16)}function _(t,n,r){r=r||t.byteLength,n=n||0;const s=new DataView(t.buffer,t.byteOffset+n,r),e=new Array(r/4);for(let t=0;t=0?BigInt(t):-BigInt(t)},add:function(t,n){return BigInt(t)+BigInt(n)},band:I,bitLength:s,bits:g,bor:function(t,n){return BigInt(t)|BigInt(n)},bxor:function(t,n){return BigInt(t)^BigInt(n)},div:q,e:r,eq:m,exp:function(t,n){return BigInt(t)**BigInt(n)},fromArray:function(t,n){let i=BigInt(0);n=BigInt(n);for(let r=0;r=BigInt(n)},gt:function(t,n){return BigInt(t)>BigInt(n)},isNegative:function(t){return BigInt(t)>=BigInt(1)}return i},neg:function(t){return-BigInt(t)},neq:function(t,n){return BigInt(t)!=BigInt(n)},one:E,pow:a,shiftLeft:o,shiftRight:h,shl:u,shr:f,square:function(t){return BigInt(t)*BigInt(t)},sub:c,toArray:function(t,n){const i=[];let r=BigInt(t);for(n=BigInt(n);r;)i.unshift(Number(r%n)),r/=n;return i},toLEBuff:function(t){const n=new Uint8Array(Math.floor((s(t)-1)/8)+1);return w(n,0,t,n.byteLength),n},toNumber:p,toRprBE:b,toRprLE:w,toString:function(t,n){return t.toString(n)},zero:F});function z(t,n,i){if(e(i))return t.one;const r=g(i);if(0==r.length)return t.one;let s=n;for(let i=r.length-2;i>=0;i--)s=t.square(s),r[i]&&(s=t.mul(s,n));return s}function y(t){if(t.m%2==1)if(m(B(t.p,4),1))if(m(B(t.p,8),1))if(m(B(t.p,16),1))!function(t){t.sqrt_q=a(t.p,t.m),t.sqrt_s=0,t.sqrt_t=c(t.sqrt_q,1);for(;!l(t.sqrt_t);)t.sqrt_s=t.sqrt_s+1,t.sqrt_t=q(t.sqrt_t,2);let n=t.one;for(;t.eq(n,t.one);){const i=t.random();t.sqrt_z=t.pow(i,t.sqrt_t),n=t.pow(t.sqrt_z,2**(t.sqrt_s-1))}t.sqrt_tm1d2=q(c(t.sqrt_t,1),2),t.sqrt=function(t){const n=this;if(n.isZero(t))return n.zero;let i=n.pow(t,n.sqrt_tm1d2);const r=n.pow(n.mul(n.square(i),t),2**(n.sqrt_s-1));if(n.eq(r,n.negone))return null;let s=n.sqrt_s,e=n.mul(t,i),o=n.mul(e,i),h=n.sqrt_z;for(;!n.eq(o,n.one);){let t=n.square(o),r=1;for(;!n.eq(t,n.one);)t=n.square(t),r++;i=h;for(let t=0;t>>0;return n}class L{constructor(t,n,i){this.F=n,this.G=t,this.opMulGF=i;let r=n.sqrt_t||n.t,s=n.sqrt_s||n.s,e=n.one;for(;n.eq(n.pow(e,n.half),n.one);)e=n.add(e,n.one);this.w=new Array(s+1),this.wi=new Array(s+1),this.w[s]=this.F.pow(e,r),this.wi[s]=this.F.inv(this.w[s]);let o=s-1;for(;o>=0;)this.w[o]=this.F.square(this.w[o+1]),this.wi[o]=this.F.square(this.wi[o+1]),o--;this.roots=[],this._setRoots(Math.min(s,15))}_setRoots(t){for(let n=t;n>=0&&!this.roots[n];n--){let t=this.F.one;const i=1<>1,h=A(t,n,i-1,r,2*s),u=A(t,n,i-1,r+s,2*s),f=new Array(e);for(let n=0;n>this.one,this.bitLength=s(this.p),this.mask=(this.one<>this.one;this.nqr=this.two;let i=this.pow(this.nqr,n);for(;!this.eq(i,this.negone);)this.nqr=this.nqr+this.one,i=this.pow(this.nqr,n);for(this.s=0,this.t=this.negone;(this.t&this.one)==this.zero;)this.s=this.s+1,this.t=this.t>>this.one;this.nqr_to_t=this.pow(this.nqr,this.t),y(this),this.FFT=new L(this,this,this.mul.bind(this)),this.fft=this.FFT.fft.bind(this.FFT),this.ifft=this.FFT.ifft.bind(this.FFT),this.w=this.FFT.w,this.wi=this.FFT.wi,this.shift=this.square(this.nqr),this.k=this.exp(this.nqr,2**this.s)}e(t,n){let i;if(n?16==n&&(i=BigInt("0x"+t)):i=BigInt(t),i<0){let t=-i;return t>=this.p&&(t%=this.p),this.p-t}return i>=this.p?i%this.p:i}add(t,n){const i=t+n;return i>=this.p?i-this.p:i}sub(t,n){return t>=n?t-n:this.p-n+t}neg(t){return t?this.p-t:t}mul(t,n){return t*n%this.p}mulScalar(t,n){return t*this.e(n)%this.p}square(t){return t*t%this.p}eq(t,n){return t==n}neq(t,n){return t!=n}lt(t,n){return(t>this.half?t-this.p:t)<(n>this.half?n-this.p:n)}gt(t,n){return(t>this.half?t-this.p:t)>(n>this.half?n-this.p:n)}leq(t,n){return(t>this.half?t-this.p:t)<=(n>this.half?n-this.p:n)}geq(t,n){return(t>this.half?t-this.p:t)>=(n>this.half?n-this.p:n)}div(t,n){return this.mul(t,this.inv(n))}idiv(t,n){if(!n)throw new Error("Division by zero");return t/n}inv(t){if(!t)throw new Error("Division by zero");let n=this.zero,i=this.p,r=this.one,s=t%this.p;for(;s;){let t=i/s;[n,r]=[r,n-t*r],[i,s]=[s,i-t*s]}return n=this.p?i-this.p:i}bor(t,n){const i=(t|n)&this.mask;return i>=this.p?i-this.p:i}bxor(t,n){const i=(t^n)&this.mask;return i>=this.p?i-this.p:i}bnot(t){const n=t^this.mask;return n>=this.p?n-this.p:n}shl(t,n){if(Number(n)=this.p?i-this.p:i}{const i=this.p-n;return Number(i)>i:this.zero}}shr(t,n){if(Number(n)>n;{const i=this.p-n;if(Number(i)=this.p?n-this.p:n}return 0}}land(t,n){return t&&n?this.one:this.zero}lor(t,n){return t||n?this.one:this.zero}lnot(t){return t?this.zero:this.one}sqrt_old(t){if(t==this.zero)return this.zero;if(this.pow(t,this.negone>>this.one)!=this.one)return null;let n=this.s,i=this.nqr_to_t,r=this.pow(t,this.t),s=this.pow(t,this.add(this.t,this.one)>>this.one);for(;r!=this.one;){let t=this.square(r),e=1;for(;t!=this.one;)e++,t=this.square(t);let o=i;for(let t=0;tthis.p>>this.one&&(s=this.neg(s)),s}normalize(t,n){if((t=BigInt(t,n))<0){let n=-t;return n>=this.p&&(n%=this.p),this.p-n}return t>=this.p?t%this.p:t}random(){const t=2*this.bitLength/8;let n=this.zero;for(let i=0;ithis.half&&10==n){i="-"+(this.p-t).toString(n)}else i=t.toString(n);return i}isZero(t){return t==this.zero}fromRng(t){let n;do{n=this.zero;for(let i=0;i=this.p);return n=n*this.Ri%this.p,n}fft(t){return this.FFT.fft(t)}ifft(t){return this.FFT.ifft(t)}toRprLE(t,n,i){w(t,n,i,8*this.n64)}toRprBE(t,n,i){b(t,n,i,8*this.n64)}toRprBEM(t,n,i){return this.toRprBE(t,n,this.mul(this.R,i))}toRprLEM(t,n,i){return this.toRprLE(t,n,this.mul(this.R,i))}fromRprLE(t,n){return d(t,n,this.n8)}fromRprBE(t,n){return _(t,n,this.n8)}fromRprLEM(t,n){return this.mul(this.fromRprLE(t,n),this.Ri)}fromRprBEM(t,n){return this.mul(this.fromRprBE(t,n),this.Ri)}toObject(t){return t}}const M=R;t.F1Field=T,t.Scalar=M,t.ZqField=T})); +!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self).Ffjavascript={})}(this,(function(t){"use strict";const n=[0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4];function i(t,n){return n&&10!=n?16==n?"0x"==t.slice(0,2)?BigInt(t):BigInt("0x"+t):void 0:BigInt(t)}const r=i;function s(t){const i=t.toString(16);return 4*(i.length-1)+n[parseInt(i[0],16)]}function e(t){return!t}function o(t,n){return BigInt(t)<>BigInt(n)}const u=o,f=h;function l(t){return(BigInt(t)&BigInt(1))==BigInt(1)}function g(t){let n=BigInt(t);const i=[];for(;n;)n&BigInt(1)?i.push(1):i.push(0),n>>=BigInt(1);return i}function p(t){if(t>BigInt(Number.MAX_SAFE_INTEGER))throw new Error("Number too big");return Number(t)}function c(t,n){return BigInt(t)-BigInt(n)}function a(t,n){return BigInt(t)**BigInt(n)}function q(t,n){return BigInt(t)/BigInt(n)}function B(t,n){return BigInt(t)%BigInt(n)}function m(t,n){return BigInt(t)==BigInt(n)}function I(t,n){return BigInt(t)&BigInt(n)}function w(t,n,i,r){const s="0000000"+i.toString(16),e=new Uint32Array(t.buffer,n,r/4),o=1+(4*(s.length-7)-1>>5);for(let t=0;t>5);for(let t=0;te[e.length-n-1]=t.toString(16).padStart(8,"0"))),i(e.join(""),16)}function _(t,n,r){r=r||t.byteLength,n=n||0;const s=new DataView(t.buffer,t.byteOffset+n,r),e=new Array(r/4);for(let t=0;t=0?BigInt(t):-BigInt(t)},add:function(t,n){return BigInt(t)+BigInt(n)},band:I,bitLength:s,bits:g,bor:function(t,n){return BigInt(t)|BigInt(n)},bxor:function(t,n){return BigInt(t)^BigInt(n)},div:q,e:r,eq:m,exp:function(t,n){return BigInt(t)**BigInt(n)},fromArray:function(t,n){let i=BigInt(0);n=BigInt(n);for(let r=0;r=BigInt(n)},gt:function(t,n){return BigInt(t)>BigInt(n)},isNegative:function(t){return BigInt(t)>=BigInt(1)}return i},neg:function(t){return-BigInt(t)},neq:function(t,n){return BigInt(t)!=BigInt(n)},one:E,pow:a,shiftLeft:o,shiftRight:h,shl:u,shr:f,square:function(t){return BigInt(t)*BigInt(t)},sub:c,toArray:function(t,n){const i=[];let r=BigInt(t);for(n=BigInt(n);r;)i.unshift(Number(r%n)),r/=n;return i},toLEBuff:function(t){const n=new Uint8Array(Math.floor((s(t)-1)/8)+1);return w(n,0,t,n.byteLength),n},toNumber:p,toRprBE:b,toRprLE:w,toString:function(t,n){return t.toString(n)},zero:F});class z{constructor(t,n,i){this.F=n,this.G=t,this.opMulGF=i;let r=n.sqrt_t||n.t,s=n.sqrt_s||n.s,e=n.one;for(;n.eq(n.pow(e,n.half),n.one);)e=n.add(e,n.one);this.w=new Array(s+1),this.wi=new Array(s+1),this.w[s]=this.F.pow(e,r),this.wi[s]=this.F.inv(this.w[s]);let o=s-1;for(;o>=0;)this.w[o]=this.F.square(this.w[o+1]),this.wi[o]=this.F.square(this.wi[o+1]),o--;this.roots=[],this._setRoots(Math.min(s,15))}_setRoots(t){for(let n=t;n>=0&&!this.roots[n];n--){let t=this.F.one;const i=1<>1,h=S(t,n,i-1,r,2*s),u=S(t,n,i-1,r+s,2*s),f=new Array(e);for(let n=0;n=0;i--)s=t.square(s),r[i]&&(s=t.mul(s,n));return s}function A(t){let n=new Uint8Array(t);if(void 0!==globalThis.crypto)globalThis.crypto.getRandomValues(n);else for(let i=0;i>>0;return n}class T{constructor(t){this.type="F1",this.one=BigInt(1),this.zero=BigInt(0),this.p=BigInt(t),this.m=1,this.negone=this.p-this.one,this.two=BigInt(2),this.half=this.p>>this.one,this.bitLength=s(this.p),this.mask=(this.one<>this.one;this.nqr=this.two;let i=this.pow(this.nqr,n);for(;!this.eq(i,this.negone);)this.nqr=this.nqr+this.one,i=this.pow(this.nqr,n);for(this.s=0,this.t=this.negone;(this.t&this.one)==this.zero;)this.s=this.s+1,this.t=this.t>>this.one;this.nqr_to_t=this.pow(this.nqr,this.t),L(this),this.FFT=new z(this,this,this.mul.bind(this)),this.fft=this.FFT.fft.bind(this.FFT),this.ifft=this.FFT.ifft.bind(this.FFT),this.w=this.FFT.w,this.wi=this.FFT.wi,this.shift=this.square(this.nqr),this.k=this.exp(this.nqr,2**this.s)}e(t,n){let i;if(n?16==n&&(i=BigInt("0x"+t)):i=BigInt(t),i<0){let t=-i;return t>=this.p&&(t%=this.p),this.p-t}return i>=this.p?i%this.p:i}add(t,n){const i=t+n;return i>=this.p?i-this.p:i}sub(t,n){return t>=n?t-n:this.p-n+t}neg(t){return t?this.p-t:t}mul(t,n){return t*n%this.p}mulScalar(t,n){return t*this.e(n)%this.p}square(t){return t*t%this.p}eq(t,n){return t==n}neq(t,n){return t!=n}lt(t,n){return(t>this.half?t-this.p:t)<(n>this.half?n-this.p:n)}gt(t,n){return(t>this.half?t-this.p:t)>(n>this.half?n-this.p:n)}leq(t,n){return(t>this.half?t-this.p:t)<=(n>this.half?n-this.p:n)}geq(t,n){return(t>this.half?t-this.p:t)>=(n>this.half?n-this.p:n)}div(t,n){return this.mul(t,this.inv(n))}idiv(t,n){if(!n)throw new Error("Division by zero");return t/n}inv(t){if(!t)throw new Error("Division by zero");let n=this.zero,i=this.p,r=this.one,s=t%this.p;for(;s;){let t=i/s;[n,r]=[r,n-t*r],[i,s]=[s,i-t*s]}return n=this.p?i-this.p:i}bor(t,n){const i=(t|n)&this.mask;return i>=this.p?i-this.p:i}bxor(t,n){const i=(t^n)&this.mask;return i>=this.p?i-this.p:i}bnot(t){const n=t^this.mask;return n>=this.p?n-this.p:n}shl(t,n){if(Number(n)=this.p?i-this.p:i}{const i=this.p-n;return Number(i)>i:this.zero}}shr(t,n){if(Number(n)>n;{const i=this.p-n;if(Number(i)=this.p?n-this.p:n}return 0}}land(t,n){return t&&n?this.one:this.zero}lor(t,n){return t||n?this.one:this.zero}lnot(t){return t?this.zero:this.one}sqrt_old(t){if(t==this.zero)return this.zero;if(this.pow(t,this.negone>>this.one)!=this.one)return null;let n=this.s,i=this.nqr_to_t,r=this.pow(t,this.t),s=this.pow(t,this.add(this.t,this.one)>>this.one);for(;r!=this.one;){let t=this.square(r),e=1;for(;t!=this.one;)e++,t=this.square(t);let o=i;for(let t=0;tthis.p>>this.one&&(s=this.neg(s)),s}normalize(t,n){if((t=BigInt(t,n))<0){let n=-t;return n>=this.p&&(n%=this.p),this.p-n}return t>=this.p?t%this.p:t}random(){const t=2*this.bitLength/8;let n=this.zero;for(let i=0;ithis.half&&10==n){i="-"+(this.p-t).toString(n)}else i=t.toString(n);return i}isZero(t){return t==this.zero}fromRng(t){let n;do{n=this.zero;for(let i=0;i=this.p);return n=n*this.Ri%this.p,n}fft(t){return this.FFT.fft(t)}ifft(t){return this.FFT.ifft(t)}toRprLE(t,n,i){w(t,n,i,8*this.n64)}toRprBE(t,n,i){b(t,n,i,8*this.n64)}toRprBEM(t,n,i){return this.toRprBE(t,n,this.mul(this.R,i))}toRprLEM(t,n,i){return this.toRprLE(t,n,this.mul(this.R,i))}fromRprLE(t,n){return d(t,n,this.n8)}fromRprBE(t,n){return _(t,n,this.n8)}fromRprLEM(t,n){return this.mul(this.fromRprLE(t,n),this.Ri)}fromRprBEM(t,n){return this.mul(this.fromRprBE(t,n),this.Ri)}toObject(t){return t}}const M=R;t.F1Field=T,t.Scalar=M,t.ZqField=T})); diff --git a/eslint.config.mjs b/eslint.config.mjs index 951509d..d021544 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,3 +1,11 @@ import toruslabsJavascript from "@toruslabs/eslint-config-javascript"; -export default [...toruslabsJavascript]; +export default [ + ...toruslabsJavascript, + { + ignores: ["build/"], + rules: { + "no-redeclare": ["error", { builtinGlobals: false }], + }, + }, +]; diff --git a/package.json b/package.json index a2b7214..9ed60f5 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ ], "sideEffects": false, "scripts": { + "lint": "eslint --fix 'src/**/*.js'", "test": "npm run test:node && npm run test:browsers", "test:node": "vitest run --config test/configs/node.config.mts --coverage", "test:chrome": "vitest run --config test/configs/chrome.config.mts", diff --git a/rollup.config.mjs b/rollup.config.mjs index ef12955..3c796e2 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -1,5 +1,5 @@ -import fs from "fs"; import terser from "@rollup/plugin-terser"; +import fs from "fs"; function firstLetterUpperCase(str) { return str.charAt(0).toUpperCase() + str.slice(1); diff --git a/src/f1field.js b/src/f1field.js index ab53883..3fc5a56 100644 --- a/src/f1field.js +++ b/src/f1field.js @@ -1,9 +1,9 @@ /* global BigInt */ -import * as Scalar from "./scalar.js"; -import * as futils from "./futils.js"; +import FFFT from "./fft.js"; import buildSqrt from "./fsqrt.js"; +import * as futils from "./futils.js"; import { getRandomBytes } from "./random.js"; -import FFFT from "./fft.js"; +import * as Scalar from "./scalar.js"; export default class ZqField { constructor(p) {