snarkjs/src/f2field.js

138 lines
3.3 KiB
JavaScript
Raw Permalink Normal View History

2018-09-05 04:56:49 +02:00
/*
2018-09-10 11:53:09 +02:00
Copyright 2018 0kims association.
2018-09-05 04:56:49 +02:00
2018-10-21 19:41:44 +02:00
This file is part of snarkjs.
2018-09-05 04:56:49 +02:00
2018-10-21 19:41:44 +02:00
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)
2018-09-10 11:53:09 +02:00
any later version.
2018-09-05 04:56:49 +02:00
2018-10-21 19:41:44 +02:00
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
2018-09-10 11:53:09 +02:00
more details.
2018-09-05 04:56:49 +02:00
2018-10-21 19:41:44 +02:00
You should have received a copy of the GNU General Public License along with
snarkjs. If not, see <https://www.gnu.org/licenses/>.
2018-09-05 04:56:49 +02:00
*/
2018-09-10 11:53:09 +02:00
2018-08-14 09:06:00 +02:00
const fUtils = require("./futils.js");
2018-08-09 08:16:34 +02:00
2018-08-12 20:37:43 +02:00
class F2Field {
2018-08-12 22:11:42 +02:00
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;
}
2018-08-14 09:06:00 +02:00
_mulByNonResidue(a) {
return this.F.mul(this.nonResidue, a);
2018-08-12 22:11:42 +02:00
}
copy(a) {
return [this.F.copy(a[0]), this.F.copy(a[1])];
2018-08-09 08:16:34 +02:00
}
add(a, b) {
2018-08-12 22:11:42 +02:00
return [
this.F.add(a[0], b[0]),
this.F.add(a[1], b[1])
];
2018-08-09 08:16:34 +02:00
}
2018-08-14 09:06:00 +02:00
double(a) {
return this.add(a,a);
}
2018-08-09 08:16:34 +02:00
sub(a, b) {
2018-08-12 22:11:42 +02:00
return [
this.F.sub(a[0], b[0]),
this.F.sub(a[1], b[1])
];
2018-08-09 08:16:34 +02:00
}
2018-08-09 15:31:16 +02:00
neg(a) {
2018-08-12 22:11:42 +02:00
return this.sub(this.zero, a);
2018-08-09 15:31:16 +02:00
}
2018-08-09 08:16:34 +02:00
mul(a, b) {
2018-08-12 22:11:42 +02:00
const aA = this.F.mul(a[0] , b[0]);
const bB = this.F.mul(a[1] , b[1]);
return [
2018-08-14 09:06:00 +02:00
this.F.add( aA , this._mulByNonResidue(bB)),
2018-08-12 22:11:42 +02:00
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))];
2018-08-09 08:16:34 +02:00
}
2018-08-12 22:11:42 +02:00
inverse(a) {
const t0 = this.F.square(a[0]);
const t1 = this.F.square(a[1]);
2018-08-14 09:06:00 +02:00
const t2 = this.F.sub(t0, this._mulByNonResidue(t1));
2018-08-12 22:11:42 +02:00
const t3 = this.F.inverse(t2);
return [
this.F.mul(a[0], t3),
this.F.neg(this.F.mul( a[1], t3)) ];
2018-08-09 08:16:34 +02:00
}
div(a, b) {
2018-08-12 22:11:42 +02:00
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] ,
2018-08-14 09:06:00 +02:00
this._mulByNonResidue(a[1]))),
2018-08-12 22:11:42 +02:00
this.F.add(
ab,
2018-08-14 09:06:00 +02:00
this._mulByNonResidue(ab))),
2018-08-12 22:11:42 +02:00
this.F.add(ab, ab)
];
2018-08-09 08:16:34 +02:00
}
2018-08-09 15:31:16 +02:00
isZero(a) {
2018-08-12 22:11:42 +02:00
return this.F.isZero(a[0]) && this.F.isZero(a[1]);
2018-08-09 15:31:16 +02:00
}
2018-08-12 22:11:42 +02:00
equals(a, b) {
return this.F.equals(a[0], b[0]) && this.F.equals(a[1], b[1]);
2018-08-09 15:31:16 +02:00
}
2018-08-12 22:11:42 +02:00
affine(a) {
return [this.F.affine(a[0]), this.F.affine(a[1])];
}
2018-08-25 00:16:12 +02:00
mulScalar(base, e) {
return fUtils.mulScalar(this, base, e);
2018-08-14 09:06:00 +02:00
}
exp(base, e) {
return fUtils.exp(this, base, e);
}
2018-08-12 22:11:42 +02:00
toString(a) {
const cp = this.affine(a);
return `[ ${this.F.toString(cp[0])} , ${this.F.toString(cp[1])} ]`;
}
2018-08-09 08:16:34 +02:00
}
2018-08-12 20:37:43 +02:00
module.exports = F2Field;