arnaucube
arnaucube/snarkjsPublic Self-hosted repository
snarkjs/src/f2field.js
src/f2field.jsRaw
  1const bigInt = require("big-integer");
  2
  3class F2Field {
  4    constructor(F, nonResidue) {
  5        this.F = F;
  6        this.zero = [this.F.zero, this.F.zero];
  7        this.one = [this.F.one, this.F.zero];
  8        this.nonResidue = nonResidue;
  9    }
 10
 11    e(c0, c1) {
 12        return [bigInt(c0), bigInt(c1)];
 13    }
 14
 15    copy(a) {
 16        return [this.F.copy(a[0]), this.F.copy(a[1])];
 17    }
 18
 19    add(a, b) {
 20        return [
 21            this.F.add(a[0], b[0]),
 22            this.F.add(a[1], b[1])
 23        ];
 24    }
 25
 26    sub(a, b) {
 27        return [
 28            this.F.sub(a[0], b[0]),
 29            this.F.sub(a[1], b[1])
 30        ];
 31    }
 32
 33    neg(a) {
 34        return this.sub(this.zero, a);
 35    }
 36
 37    mul(a, b) {
 38        const aA = this.F.mul(a[0] , b[0]);
 39        const bB = this.F.mul(a[1] , b[1]);
 40
 41        return [
 42            this.F.add( aA , this.F.mul(this.nonResidue , bB)),
 43            this.F.sub(
 44                this.F.mul(
 45                    this.F.add(a[0], a[1]),
 46                    this.F.add(b[0], b[1])),
 47                this.F.add(aA, bB))];
 48    }
 49
 50    inverse(a) {
 51        const t0 = this.F.square(a[0]);
 52        const t1 = this.F.square(a[1]);
 53        const t2 = this.F.sub(t0, this.F.mul(this.nonResidue, t1));
 54        const t3 = this.F.inverse(t2);
 55        return [
 56            this.F.mul(a[0], t3),
 57            this.F.neg(this.F.mul( a[1], t3)) ];
 58    }
 59
 60    div(a, b) {
 61        return this.mul(a, this.inverse(b));
 62    }
 63
 64    square(a) {
 65        const ab = this.F.mul(a[0] , a[1]);
 66
 67        /*
 68        [
 69            (a + b) * (a + non_residue * b) - ab - non_residue * ab,
 70            ab + ab
 71        ];
 72        */
 73
 74        return [
 75            this.F.sub(
 76                this.F.mul(
 77                    this.F.add(a[0], a[1]) ,
 78                    this.F.add(
 79                        a[0] ,
 80                        this.F.mul(this.nonResidue , a[1]))),
 81                this.F.add(
 82                    ab,
 83                    this.F.mul(this.nonResidue, ab))),
 84            this.F.add(ab, ab)
 85        ];
 86    }
 87
 88    isZero(a) {
 89        return this.F.isZero(a[0]) && this.F.isZero(a[1]);
 90    }
 91
 92    equals(a, b) {
 93        return this.F.equals(a[0], b[0]) && this.F.equals(a[1], b[1]);
 94    }
 95
 96    affine(a) {
 97        return [this.F.affine(a[0]), this.F.affine(a[1])];
 98    }
 99
100    toString(a) {
101        const cp = this.affine(a);
102        return `[ ${this.F.toString(cp[0])} , ${this.F.toString(cp[1])} ]`;
103    }
104}
105
106module.exports = F2Field;