arnaucube
arnaucube/snarkjsPublic Self-hosted repository
snarkjs/src/g1curve.js
src/g1curve.jsRaw
  1const bigInt = require("big-integer");
  2
  3const q = new bigInt("21888242871839275222246405745257275088696311157297823662689037894645226208583");
  4
  5module.eports = class G1Curve {
  6
  7    constructor() {
  8        this.g = [ bigInt(1), bigInt(2), bigInt(1) ];
  9        this.zero = [ bigInt(0), bigInt(1), bigInt(0) ];
 10    }
 11
 12    isZero(p) {
 13        return p[2].isZero();
 14    }
 15    add(p1, p2) {
 16
 17        if (this.isZero(p1)) return p2;
 18        if (this.isZero(p2)) return p1;
 19
 20        const res = new Array(3);
 21
 22        const Z1Z1 = p1[2].square().mod(q);
 23        const Z2Z2 = p2[2].square().mod(q);
 24
 25        const U1 = p1[0].times(Z2Z2).mod(q);
 26        const U2 = p2[0].times(Z1Z1).mod(q);
 27
 28        const Z1_cubed = p1[2].times(Z1Z1).mod(q);
 29        const Z2_cubed = p2[2].times(Z2Z2).mod(q);
 30
 31        const S1 = p1[1].times(Z2_cubed).mod(q);
 32        const S2 = p2[1].times(Z1_cubed).mod(q);
 33
 34        if (U1.equals(U2) && (S1.equals(S2))) {
 35            return this.double(p1);
 36        }
 37
 38        let H = U2.minus(U1);
 39        if (H.isNegative()) H = H.add(q);
 40
 41        let S2_minus_S1 = S2.minus(S1);
 42        if (S2_minus_S1.isNegative()) S2_minus_S1 = S2_minus_S1.add(q);
 43
 44        const I = H.add(H).square().mod(q);
 45        const J = H.times(I).mod(q);
 46
 47        const r = S2_minus_S1.add(S2_minus_S1);
 48        const V = U1.times(I).mod(q);
 49
 50        res[0] = r.square().minus(J).minus(V).minus(V).mod(q);
 51        if (res[0].isNegative()) res[0] = res[0].add(q);
 52
 53        const S1_J = S1.times(J).mod(q);
 54
 55        res[1] = r.times(V.minus(res[0])).minus(S1_J).minus(S1_J).mod(q);
 56        if (res[1].isNegative()) res[1] = res[1].add(q);
 57
 58        res[2] = p1[2].add(p2[2]).square().minus(Z1Z1).minus(Z2Z2).mod(q);
 59        res[2] = res[2].times(H).mod(q);
 60        if (res[2].isNegative()) res[2] = res[2].add(q);
 61
 62        return res;
 63    }
 64
 65    double(p) {
 66        const res = new Array(3);
 67
 68        if (this.isZero(p)) return p;
 69
 70        const A = p[0].square().mod(q);
 71        const B = p[1].square().mod(q);
 72        const C = B.square().mod(q);
 73
 74        let D = p[0].add(B).square().minus(A).minus(C);
 75        D = D.add(D);
 76
 77        const E = A.times(3);
 78        const F = E.square();
 79
 80        res[0] = F.minus(D).minus(D).mod(q);
 81        if (res[0].isNegative()) res[0] = res[0].add(q);
 82
 83        const eightC = C.times(8);
 84
 85        res[1] = E.times(D.minus(res[0])).minus(eightC).mod(q);
 86        if (res[1].isNegative()) res[1] = res[1].add(q);
 87
 88        const Y1Z1 = p[1].times(p[2]);
 89        res[2] = Y1Z1.add(Y1Z1).mod(q);
 90
 91        return res;
 92    }
 93
 94    toAffineCoordinates(p) {
 95        if (this.isZero(p)) {
 96            return this.zero;
 97        } else {
 98            const Z_inv = p[2].modInv(q);
 99            const Z2_inv = Z_inv.square().mod(q);
100            const Z3_inv = Z2_inv.times(Z_inv).mod(q);
101
102            const res = new Array(3);
103            res[0] = p[0].times(Z2_inv).mod(q);
104            res[1] = p[1].times(Z3_inv).mod(q);
105            res[2] = bigInt(1);
106
107            return res;
108        }
109    }
110
111    mulEscalar(base, e) {
112        let res = this.zero;
113        let rem = e;
114        let exp = base;
115
116        while (! rem.isZero()) {
117            if (rem.isOdd()) {
118                res = this.add(res, exp);
119            }
120            exp = this.double(exp);
121            rem = rem.shiftRight(1);
122        }
123
124        return res;
125    }
126
127};
128
129const G1 = new module.eports();
130
131
132const r = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
133// const np = G1.mulEscalar(G1.g, bigInt(2));
134
135const np = G1.mulEscalar(G1.g, r.add(1));
136const p = G1.toAffineCoordinates(np);
137
138/*
139const np2 = G1.add(G1.g, G1.g);
140const np3 = G1.add(G1.g, np2);
141
142const p = G1.toAffineCoordinates(np3);
143*/
144
145console.log(p[0].toString() + ", " + p[1].toString() + ", " + p[2].toString());
146
147