@ -1,54 +1,106 @@ |
|||||
|
|
||||
|
const bigInt = require("big-integer"); |
||||
|
|
||||
class F2Field { |
class F2Field { |
||||
constructor(p) { |
|
||||
this.p = n; |
|
||||
|
constructor(F, nonResidue) { |
||||
|
this.F = F; |
||||
|
this.zero = [this.F.zero, this.F.zero]; |
||||
|
this.one = [this.F.one, this.F.zero]; |
||||
|
this.nonResidue = nonResidue; |
||||
|
} |
||||
|
|
||||
|
e(c0, c1) { |
||||
|
return [bigInt(c0), bigInt(c1)]; |
||||
|
} |
||||
|
|
||||
|
copy(a) { |
||||
|
return [this.F.copy(a[0]), this.F.copy(a[1])]; |
||||
} |
} |
||||
|
|
||||
add(a, b) { |
add(a, b) { |
||||
const maxGrade = Math.max(a.length, b.length); |
|
||||
const res = new Array(maxGrade); |
|
||||
for (let i=0; i<maxGrade; i++) { |
|
||||
res[i] = this.F.add(a[i], b[i]); |
|
||||
} |
|
||||
return this._reduce(res); |
|
||||
|
return [ |
||||
|
this.F.add(a[0], b[0]), |
||||
|
this.F.add(a[1], b[1]) |
||||
|
]; |
||||
} |
} |
||||
|
|
||||
sub(a, b) { |
sub(a, b) { |
||||
// TODO
|
|
||||
throw new Error("Not Implementted"); |
|
||||
|
return [ |
||||
|
this.F.sub(a[0], b[0]), |
||||
|
this.F.sub(a[1], b[1]) |
||||
|
]; |
||||
} |
} |
||||
|
|
||||
neg(a) { |
neg(a) { |
||||
// TODO
|
|
||||
throw new Error("Not Implementted"); |
|
||||
|
return this.sub(this.zero, a); |
||||
} |
} |
||||
|
|
||||
mul(a, b) { |
mul(a, b) { |
||||
// TODO
|
|
||||
throw new Error("Not Implementted"); |
|
||||
|
const aA = this.F.mul(a[0] , b[0]); |
||||
|
const bB = this.F.mul(a[1] , b[1]); |
||||
|
|
||||
|
return [ |
||||
|
this.F.add( aA , this.F.mul(this.nonResidue , 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))]; |
||||
} |
} |
||||
|
|
||||
inverse(a, b) { |
|
||||
// TODO
|
|
||||
throw new Error("Not Implementted"); |
|
||||
|
inverse(a) { |
||||
|
const t0 = this.F.square(a[0]); |
||||
|
const t1 = this.F.square(a[1]); |
||||
|
const t2 = this.F.sub(t0, this.F.mul(this.nonResidue, t1)); |
||||
|
const t3 = this.F.inverse(t2); |
||||
|
return [ |
||||
|
this.F.mul(a[0], t3), |
||||
|
this.F.neg(this.F.mul( a[1], t3)) ]; |
||||
} |
} |
||||
|
|
||||
div(a, b) { |
div(a, b) { |
||||
// TODO
|
|
||||
throw new Error("Not Implementted"); |
|
||||
|
return this.mul(a, this.inverse(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.F.mul(this.nonResidue , a[1]))), |
||||
|
this.F.add( |
||||
|
ab, |
||||
|
this.F.mul(this.nonResidue, ab))), |
||||
|
this.F.add(ab, ab) |
||||
|
]; |
||||
} |
} |
||||
|
|
||||
isZero(a) { |
isZero(a) { |
||||
// TODO
|
|
||||
throw new Error("Not Implementted"); |
|
||||
|
return this.F.isZero(a[0]) && this.F.isZero(a[1]); |
||||
} |
} |
||||
|
|
||||
random() { |
|
||||
// TODO
|
|
||||
throw new Error("Not Implementted"); |
|
||||
|
equals(a, b) { |
||||
|
return this.F.equals(a[0], b[0]) && this.F.equals(a[1], b[1]); |
||||
} |
} |
||||
|
|
||||
|
affine(a) { |
||||
|
return [this.F.affine(a[0]), this.F.affine(a[1])]; |
||||
|
} |
||||
|
|
||||
|
toString(a) { |
||||
|
const cp = this.affine(a); |
||||
|
return `[ ${this.F.toString(cp[0])} , ${this.F.toString(cp[1])} ]`; |
||||
|
} |
||||
} |
} |
||||
|
|
||||
module.exports = F2Field; |
module.exports = F2Field; |