@ -1,260 +0,0 @@ |
|||
/* |
|||
This library do operations on polinomials where their coefficients are in field F |
|||
|
|||
The polynomial P(x) = p0 + p1 * x + p2 * x^2 + p3 * x^3, ... |
|||
is represented by the array [ p0, p1, p2, p3, ... ] |
|||
*/ |
|||
|
|||
const bigInt = require("./bigInt"); |
|||
const ZqField = require("./zqfield"); |
|||
|
|||
class PolFieldZq { |
|||
constructor (q) { |
|||
this.F = new ZqField(q); |
|||
|
|||
let rem = q.sub(bigInt(1)); |
|||
let s = 0; |
|||
while (!rem.isOdd()) { |
|||
s ++; |
|||
rem = rem.shiftRight(1); |
|||
} |
|||
|
|||
this.w = new Array(s+1); |
|||
this.wi = new Array(s+1); |
|||
this.w[s] = this.F.exp(bigInt(5), rem); |
|||
this.wi[s] = this.F.inverse(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--; |
|||
} |
|||
|
|||
} |
|||
|
|||
add(a, b) { |
|||
const m = Math.max(a.length, b.length); |
|||
const res = new Array(m); |
|||
for (let i=0; i<m; i++) { |
|||
res[i] = this.F.add(a[i] || this.F.zero, b[i] || this.F.zero); |
|||
} |
|||
return this.reduce(res); |
|||
} |
|||
|
|||
double(a) { |
|||
return this.add(a,a); |
|||
} |
|||
|
|||
sub(a, b) { |
|||
const m = Math.max(a.length, b.length); |
|||
const res = new Array(m); |
|||
for (let i=0; i<m; i++) { |
|||
res[i] = this.F.sub(a[i] || this.F.zero, b[i] || this.F.zero); |
|||
} |
|||
return this.reduce(res); |
|||
} |
|||
|
|||
mulScalar(a, b) { |
|||
if (this.F.isZero(b)) return []; |
|||
const res = new Array(a.length); |
|||
for (let i=0; i<a.length; i++) { |
|||
res[i] = this.F.mul(a[i], b); |
|||
} |
|||
return res; |
|||
} |
|||
|
|||
mul(a, b) { |
|||
if (a.length == 0) return []; |
|||
if (b.length == 0) return []; |
|||
if (a.length == 1) return this.mulScalar(b, a[0]); |
|||
if (b.length == 1) return this.mulScalar(a, b[0]); |
|||
|
|||
const longestN = Math.max(a.length, b.length); |
|||
const bitsResult = log2(longestN-1)+2; |
|||
const m = 1 << bitsResult; |
|||
const ea = this.extend(a,m); |
|||
const eb = this.extend(b,m); |
|||
|
|||
const ta = this._fft(ea, bitsResult, 0, 1, false); |
|||
const tb = this._fft(eb, bitsResult, 0, 1, false); |
|||
|
|||
const tres = new Array(m); |
|||
|
|||
for (let i=0; i<m; i++) { |
|||
tres[i] = this.F.mul(ta[i], tb[i]); |
|||
} |
|||
|
|||
const res = this._fft(tres, bitsResult, 0, 1, true); |
|||
|
|||
const twoinvm = this.F.inverse(bigInt(m)); |
|||
const resn = new Array(m); |
|||
for (let i=0; i<m; i++) { |
|||
resn[i] = this.F.mul(res[(m-i)%m], twoinvm); |
|||
} |
|||
|
|||
return this.reduce(this.affine(resn)); |
|||
} |
|||
|
|||
square(a) { |
|||
return this.mul(a,a); |
|||
} |
|||
|
|||
scaleX(p, n) { |
|||
if (n==0) { |
|||
return p; |
|||
} else if (n>0) { |
|||
const z = new Array(n).fill(this.F.zero); |
|||
return z.concat(p); |
|||
} else { |
|||
return p.slice(-n); |
|||
} |
|||
} |
|||
|
|||
div(a, b) { |
|||
throw new Error("Not Implementted"); |
|||
} |
|||
|
|||
eval(p, x) { |
|||
let v = this.F.zero; |
|||
let ix = this.F.one; |
|||
for (let i=0; i<p.length; i++) { |
|||
v = this.F.add(v, this.F.mul(p[i], ix)); |
|||
ix = this.F.mul(ix, x); |
|||
} |
|||
return v; |
|||
} |
|||
|
|||
lagrange(points) { |
|||
throw new Error("Not Implementted"); |
|||
} |
|||
|
|||
_fft(pall, bits, offset, step) { |
|||
|
|||
const n = 1 << bits; |
|||
if (n==1) { |
|||
return [ pall[offset] ]; |
|||
} |
|||
|
|||
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); |
|||
|
|||
const out = new Array(n); |
|||
|
|||
let m= bigInt(1); |
|||
for (let i=0; i<ndiv2; i++) { |
|||
out[i] = this.F.add(p1[i], this.F.mul(m, p2[i])); |
|||
out[i+ndiv2] = this.F.sub(p1[i], this.F.mul(m, p2[i])); |
|||
m = this.F.mul(m, this.w[bits]); |
|||
} |
|||
|
|||
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); |
|||
} |
|||
|
|||
reduce(p) { |
|||
if (p.length == 0) return p; |
|||
if (! this.F.isZero(p[p.length-1]) ) return p; |
|||
let i=p.length-1; |
|||
while( i>0 && this.F.isZero(p[i]) ) i--; |
|||
return p.slice(0, i+1); |
|||
} |
|||
|
|||
affine(p) { |
|||
for (let i=0; i<p.length; i++) { |
|||
p[i] = this.F.affine(p[i]); |
|||
} |
|||
return p; |
|||
} |
|||
|
|||
equals(a, b) { |
|||
const pa = this.reduce(this.affine(a)); |
|||
const pb = this.reduce(this.affine(b)); |
|||
|
|||
if (pa.length != pb.length) return false; |
|||
for (let i=0; i<pb.length; i++) { |
|||
if (!this.F.equals(pa[i], pb[i])) return false; |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
|
|||
_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.affine(p); |
|||
let S = ""; |
|||
for (let i=ap.length-1; i>=0; i--) { |
|||
if (!this.F.isZero(p[i])) { |
|||
if (S!="") S += " + "; |
|||
S = S + p[i].toString(10); |
|||
if (i>0) { |
|||
S = S + "x"; |
|||
if (i>1) { |
|||
S = S + "^" +i; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return S; |
|||
} |
|||
|
|||
|
|||
_reciprocal(p, bits) { |
|||
const k = 1 << bits; |
|||
if (k==1) { |
|||
return [ this.F.inverse(p[0]) ]; |
|||
} |
|||
const np = this.scaleX(p, -k/2); |
|||
const q = this._reciprocal(np, bits-1); |
|||
const a = this.scaleX(this.double(q), 3*k/2-2); |
|||
const b = this.mul( this.square(q), p); |
|||
|
|||
return this.scaleX(this.sub(a,b), -(k-2)); |
|||
} |
|||
|
|||
// divides x^m / v
|
|||
_div2(m, v) { |
|||
const kbits = log2(v.length-1)+1; |
|||
const k = 1 << kbits; |
|||
|
|||
const scaleV = k - v.length; |
|||
|
|||
// rec = x^(k - 2) / v* x^scaleV =>
|
|||
// rec = x^(k-2-scaleV)/ v
|
|||
//
|
|||
// res = x^m/v = x^(m +(2k-2-scaleV) -(2k-2-scaleV)) /v =>
|
|||
// res = rec * x^(m - (2k-2-scaleV)) =>
|
|||
// res = rec * x^(m - 2k +2 + scaleV)
|
|||
|
|||
const rec = this._reciprocal(this.scaleX(v, scaleV), kbits); |
|||
const res = this.scaleX(rec, m - k*2 +2+scaleV); |
|||
|
|||
return 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 ) ); |
|||
} |
|||
|
|||
module.exports = PolFieldZq; |
@ -1 +1 @@ |
|||
{"nPublic":2,"A":[["0","1","0"],["0","1","0"],["0","1","0"]],"vk_a":[["10910302893854256300335313159192947444388132687074523434871198422054676751347","7128911999163755080071576365381312078199150810378083348330952764137111826309"],["18631850238317279011886579705479432506796416675676074259923090354119752710032","11613125271011748641588689311610150724463404115865535933368983811438235418330"],["1","0"]],"vk_b":["14021005419725675778621050747090735283429719877068464218769467811976154477903","13400327218680122582347155709033494654797979408389561950304209881074672567956","1"],"vk_c":[["3096051994409557504719773510360462097114704303646108617318273214347944304327","21060178932557065464613441158524747948458716806166605021180362439829514495363"],["13711469505507426929293229841903695489923719718740047084134989818704335937579","16689306268247690470861364441748198782838298216373469479699367433528545900642"],["1","0"]],"vk_gb_1":["6323076061844787963801699179984388237278671131058334789970950232032140773376","1289442623160734848462556712373448525459100416297212719395950333399658173112","1"],"vk_gb_2":[["14738403669696391106523308033989669531459082697567002658683173458264070358472","7115351592298265627577071367133297887460251153742186717064165044604072075208"],["5684452168257595880393745672144928966665179424697978770339950828964351397925","16005652883870491274891326398599328665806046577140362628567012925774147115231"],["1","0"]],"vk_g":[["13057967944664071939530697379611124014113572609236714070685841838860689079766","4921285704318374954421284662839198492272478322335189504342768676294475453825"],["16821731243154385058674189668904278548308574642868092417486261078313511500423","14329710484989081757569399730710287771777297111484092478685760712065088557056"],["1","0"]],"vk_z":[["9830782349217318574531840014041507435528173882006141768847850813321843762209","908701408738093737682928637200323566556898851221230193697915803980061312337"],["18420854262130852746249857908832658786725598484918874058527841900342812415992","11905336095877065527602013373361492354917686666454749599264218906638347950295"],["1","0"]]} |
|||
{"nPublic":2,"A":[["0","1","0"],["0","1","0"],["0","1","0"]],"vk_a":[["1114178395252120380395835212597801981089399905319368502910322038327297636405","5033894282647920143094588130989706038816118666385188297428164028250802121541"],["11204369287866566481790440577452570863155384959741708497053387501206022041196","5804122404011709706164213043421176877293761551268564612957682946191385948083"],["1","0"]],"vk_b":["21502216352809485080540484588657130416201550918596561744135679102208461442666","2868090884426856501439409534931120005724644305621622228858085860168686686429","1"],"vk_c":[["6132826916796173784201732531285327915041466217971374202416165094662772918168","21745292514182636990945632198433440675390812739972912576130340262689749324094"],["771505583294284223449947888751235336787816998120918568114562783124678603668","3393096609476927450002720393920165677184260635403434210470312068614019743097"],["1","0"]],"vk_gb_1":["12719499470261599561309259431682387098359700522807496275922119401706283527128","16621363578670067280062291944220200497396193306084620768371306905372731356597","1"],"vk_gb_2":[["10964959780919004944755595440619126945893196497479441585015855710878271674269","2128708169016642077859536709142486990439502854897055565299822951071887976085"],["2388598870284376494192851636260646163256895248220461084487594797988889825261","20110295053122713144819603341600445626597656441687959152080135372786154275292"],["1","0"]],"vk_g":[["12255811247188042732673820469397127953046292441028573933507149762907917860381","7279942967825808009089038706789890489125264289371774766033392871666671678200"],["7190249513755559992931891810866588807891969433945206422275821065594394539722","21314329220359655301619987728101583897798145529926111725521967279053488865751"],["1","0"]],"vk_z":[["17586236151988045592673833893440158242030817616966567700538296220528189715389","3551310632722212929105681060373481610723584194504089389345599320999381324165"],["9267522905249404702171212401947711344560303757795853174593820034048921438294","6158557086581678490843952132823078409925994557584598523494082907032631181314"],["1","0"]]} |