arnaucube
arnaucube/circomlibPublic Self-hosted repository
circomlib/src/babyjub.js
src/babyjub.jsRaw
 1const bn128 = require("snarkjs").bn128;
 2const bigInt = require("snarkjs").bigInt;
 3
 4exports.addPoint = addPoint;
 5exports.mulPointEscalar = mulPointEscalar;
 6exports.inCurve = inCurve;
 7
 8function addPoint(a,b) {
 9    const q = bn128.r;
10    const cta = bigInt("168700");
11    const d = bigInt("168696");
12
13    const res = [];
14    res[0] = bigInt((a[0]*b[1] + b[0]*a[1]) *  bigInt(bigInt("1") + d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
15    res[1] = bigInt((a[1]*b[1] - cta*a[0]*b[0]) * bigInt(bigInt("1") - d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
16    return res;
17}
18
19function mulPointEscalar(base, e) {
20    let res = [bigInt("0"),bigInt("1")];
21    let rem = bigInt(e);
22    let exp = base;
23
24    while (! rem.isZero()) {
25        if (rem.isOdd()) {
26            res = addPoint(res, exp);
27        }
28        exp = addPoint(exp, exp);
29        rem = rem.shr(1);
30    }
31
32    return res;
33}
34
35function isLowGrade(p) {
36    const r = bigInt("21888242871839275222246405745257275088614511777268538073601725287587578984328").shr(3);
37    const res= mulPointEscalar(p, r);
38    return (res[0].equals(bigInt(0))) && (res[1].equals(bigInt(1)));
39}
40
41function inCurve(p) {
42    const F = bn128.Fr;
43
44    const a = bigInt("168700");
45    const d = bigInt("168696");
46
47    const x2 = F.square(p[0]);
48    const y2 = F.square(p[1]);
49
50    if (!F.equals(
51        F.add(F.mul(a, x2), y2),
52        F.add(F.one, F.mul(F.mul(x2, y2), d)))) return false;
53
54    if (!isLowGrade(p)) return false;
55
56    return true;
57}