arnaucube
arnaucube/snarkjsPublic Self-hosted repository
snarkjs/src/f2field.js
src/f2field.jsRaw
  1/*
  2    Copyright 2018 0kims association
  3
  4    This file is part of zksnark javascript library.
  5
  6    zksnark javascript library is free software: you can redistribute it and/or modify
  7    it under the terms of the GNU General Public License as published by
  8    the Free Software Foundation, either version 3 of the License, or
  9    (at your option) any later version.
 10
 11    zksnark javascript library is distributed in the hope that it will be useful,
 12    but WITHOUT ANY WARRANTY; without even the implied warranty of
 13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14    GNU General Public License for more details.
 15
 16    You should have received a copy of the GNU General Public License
 17    along with zksnark javascript library.  If not, see <https://www.gnu.org/licenses/>.
 18*/
 19const fUtils = require("./futils.js");
 20
 21class F2Field {
 22    constructor(F, nonResidue) {
 23        this.F = F;
 24        this.zero = [this.F.zero, this.F.zero];
 25        this.one = [this.F.one, this.F.zero];
 26        this.nonResidue = nonResidue;
 27    }
 28
 29    _mulByNonResidue(a) {
 30        return this.F.mul(this.nonResidue, a);
 31    }
 32
 33    copy(a) {
 34        return [this.F.copy(a[0]), this.F.copy(a[1])];
 35    }
 36
 37    add(a, b) {
 38        return [
 39            this.F.add(a[0], b[0]),
 40            this.F.add(a[1], b[1])
 41        ];
 42    }
 43
 44    double(a) {
 45        return this.add(a,a);
 46    }
 47
 48    sub(a, b) {
 49        return [
 50            this.F.sub(a[0], b[0]),
 51            this.F.sub(a[1], b[1])
 52        ];
 53    }
 54
 55    neg(a) {
 56        return this.sub(this.zero, a);
 57    }
 58
 59    mul(a, b) {
 60        const aA = this.F.mul(a[0] , b[0]);
 61        const bB = this.F.mul(a[1] , b[1]);
 62
 63        return [
 64            this.F.add( aA , this._mulByNonResidue(bB)),
 65            this.F.sub(
 66                this.F.mul(
 67                    this.F.add(a[0], a[1]),
 68                    this.F.add(b[0], b[1])),
 69                this.F.add(aA, bB))];
 70    }
 71
 72    inverse(a) {
 73        const t0 = this.F.square(a[0]);
 74        const t1 = this.F.square(a[1]);
 75        const t2 = this.F.sub(t0, this._mulByNonResidue(t1));
 76        const t3 = this.F.inverse(t2);
 77        return [
 78            this.F.mul(a[0], t3),
 79            this.F.neg(this.F.mul( a[1], t3)) ];
 80    }
 81
 82    div(a, b) {
 83        return this.mul(a, this.inverse(b));
 84    }
 85
 86    square(a) {
 87        const ab = this.F.mul(a[0] , a[1]);
 88
 89        /*
 90        [
 91            (a + b) * (a + non_residue * b) - ab - non_residue * ab,
 92            ab + ab
 93        ];
 94        */
 95
 96        return [
 97            this.F.sub(
 98                this.F.mul(
 99                    this.F.add(a[0], a[1]) ,
100                    this.F.add(
101                        a[0] ,
102                        this._mulByNonResidue(a[1]))),
103                this.F.add(
104                    ab,
105                    this._mulByNonResidue(ab))),
106            this.F.add(ab, ab)
107        ];
108    }
109
110    isZero(a) {
111        return this.F.isZero(a[0]) && this.F.isZero(a[1]);
112    }
113
114    equals(a, b) {
115        return this.F.equals(a[0], b[0]) && this.F.equals(a[1], b[1]);
116    }
117
118    affine(a) {
119        return [this.F.affine(a[0]), this.F.affine(a[1])];
120    }
121
122    mulScalar(base, e) {
123        return fUtils.mulScalar(this, base, e);
124    }
125
126    exp(base, e) {
127        return fUtils.exp(this, base, e);
128    }
129
130    toString(a) {
131        const cp = this.affine(a);
132        return `[ ${this.F.toString(cp[0])} , ${this.F.toString(cp[1])} ]`;
133    }
134}
135
136module.exports = F2Field;