babyjub.js adapted

This commit is contained in:
Jordi Baylina 2019-12-12 19:46:07 +01:00
parent 30c6cf55b9
commit b4cd3889b6
No known key found for this signature in database
GPG Key ID: 7480C80C1BE43112
4 changed files with 92 additions and 60 deletions

15
package-lock.json generated

@ -1529,6 +1529,21 @@
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
}, },
"fflib": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/fflib/-/fflib-0.0.1.tgz",
"integrity": "sha512-bWTudSfCjkNkOOeSNQf8DmBidxxuzqyjeIdZBfY38T7R+jt381sdx1SYpyve5MQdDlQg1k7UHeb0L/J8WWFWYA==",
"requires": {
"big-integer": "^1.6.48"
},
"dependencies": {
"big-integer": {
"version": "1.6.48",
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz",
"integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w=="
}
}
},
"figures": { "figures": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",

@ -27,6 +27,7 @@
"blake-hash": "^1.1.0", "blake-hash": "^1.1.0",
"blake2b": "^2.1.3", "blake2b": "^2.1.3",
"circom": "0.0.35", "circom": "0.0.35",
"fflib": "0.0.1",
"snarkjs": "^0.1.20", "snarkjs": "^0.1.20",
"typedarray-to-buffer": "^3.1.5", "typedarray-to-buffer": "^3.1.5",
"web3": "^1.0.0-beta.55" "web3": "^1.0.0-beta.55"

@ -1,5 +1,6 @@
const bn128 = require("snarkjs").bn128; const bigInt = require("big-integer");
const bigInt = require("snarkjs").bigInt; const ZqField = require("fflib").ZqField;
const utils = require("./utils.js");
exports.addPoint = addPoint; exports.addPoint = addPoint;
exports.mulPointEscalar = mulPointEscalar; exports.mulPointEscalar = mulPointEscalar;
@ -16,14 +17,14 @@ exports.Base8 = [
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203") bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")
]; ];
exports.order = bigInt("21888242871839275222246405745257275088614511777268538073601725287587578984328"); exports.order = bigInt("21888242871839275222246405745257275088614511777268538073601725287587578984328");
exports.subOrder = exports.order.shr(3); exports.subOrder = exports.order.shiftRight(3);
exports.p = bn128.r; exports.p = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
exports.A = bigInt("168700"); exports.A = bigInt("168700");
exports.D = bigInt("168696"); exports.D = bigInt("168696");
function addPoint(a,b) { function addPoint(a,b) {
const q = bn128.r; const F = new ZqField(exports.p);
const res = []; const res = [];
@ -31,8 +32,25 @@ function addPoint(a,b) {
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); 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);
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); 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);
*/ */
res[0] = bigInt((bigInt(a[0]).mul(b[1]).add(bigInt(b[0]).mul(a[1]))).mul(bigInt(bigInt("1").add(exports.D.mul(a[0]).mul(b[0]).mul(a[1]).mul(b[1]))).inverse(q))).affine(q);
res[1] = bigInt((bigInt(a[1]).mul(b[1]).sub(exports.A.mul(a[0]).mul(b[0]))).mul(bigInt(bigInt("1").sub(exports.D.mul(a[0]).mul(b[0]).mul(a[1]).mul(b[1]))).inverse(q))).affine(q); const beta = F.mul(a[0],b[1]);
const gamma = F.mul(a[1],b[0]);
const delta = F.mul(
F.sub(a[1], F.mul(exports.A, a[0])),
F.add(b[0], b[1])
);
const tau = F.mul(beta, gamma);
const dtau = F.mul(exports.D, tau);
res[0] = F.div(
F.add(beta, gamma),
F.add(bigInt.one, dtau)
);
res[1] = F.div(
F.add(delta, F.sub(F.mul(exports.A,beta), gamma)),
F.sub(bigInt.one, dtau)
);
return res; return res;
} }
@ -47,7 +65,7 @@ function mulPointEscalar(base, e) {
res = addPoint(res, exp); res = addPoint(res, exp);
} }
exp = addPoint(exp, exp); exp = addPoint(exp, exp);
rem = rem.shr(1); rem = rem.shiftRight(1);
} }
return res; return res;
@ -60,12 +78,12 @@ function inSubgroup(P) {
} }
function inCurve(P) { function inCurve(P) {
const F = bn128.Fr; const F = new ZqField(exports.p);
const x2 = F.square(P[0]); const x2 = F.square(P[0]);
const y2 = F.square(P[1]); const y2 = F.square(P[1]);
if (!F.equals( if (!F.eq(
F.add(F.mul(exports.A, x2), y2), F.add(F.mul(exports.A, x2), y2),
F.add(F.one, F.mul(F.mul(x2, y2), exports.D)))) return false; F.add(F.one, F.mul(F.mul(x2, y2), exports.D)))) return false;
@ -73,15 +91,15 @@ function inCurve(P) {
} }
function packPoint(P) { function packPoint(P) {
const buff = bigInt.leInt2Buff(P[1], 32); const buff = utils.leInt2Buff(P[1], 32);
if (P[0].greater(exports.p.shr(1))) { if (P[0].greater(exports.p.shiftRight(1))) {
buff[31] = buff[31] | 0x80; buff[31] = buff[31] | 0x80;
} }
return buff; return buff;
} }
function unpackPoint(_buff) { function unpackPoint(_buff) {
const F = bn128.Fr; const F = new ZqField(exports.p);
const buff = Buffer.from(_buff); const buff = Buffer.from(_buff);
let sign = false; let sign = false;
@ -90,7 +108,7 @@ function unpackPoint(_buff) {
sign = true; sign = true;
buff[31] = buff[31] & 0x7F; buff[31] = buff[31] & 0x7F;
} }
P[1] = bigInt.leBuff2int(buff); P[1] = utils.leBuff2int(buff);
if (P[1].greaterOrEquals(exports.p)) return null; if (P[1].greaterOrEquals(exports.p)) return null;
const y2 = F.square(P[1]); const y2 = F.square(P[1]);
@ -103,7 +121,7 @@ function unpackPoint(_buff) {
if (sign) x = F.neg(x); if (sign) x = F.neg(x);
P[0] = F.affine(x); P[0] = x;
return P; return P;
} }

@ -1,7 +1,5 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const bigInt = require("big-integer");
const snarkjs = require("snarkjs");
const compiler = require("circom");
const babyjub = require("../src/babyjub.js"); const babyjub = require("../src/babyjub.js");
const assert = chai.assert; const assert = chai.assert;
@ -16,14 +14,14 @@ describe("Baby Jub js test", function () {
it("Should add point (0,1) and (0,1)", () => { it("Should add point (0,1) and (0,1)", () => {
const p1 = [ const p1 = [
snarkjs.bigInt(0), bigInt(0),
snarkjs.bigInt(1)]; bigInt(1)];
const p2 = [ const p2 = [
snarkjs.bigInt(0), bigInt(0),
snarkjs.bigInt(1) bigInt(1)
]; ];
const out = babyjub.addPoint(p1, p2) const out = babyjub.addPoint(p1, p2);
assert(out[0].equals(0)); assert(out[0].equals(0));
assert(out[1].equals(1)); assert(out[1].equals(1));
}); });
@ -41,43 +39,43 @@ describe("Baby Jub js test", function () {
it("Should add 2 same numbers", () => { it("Should add 2 same numbers", () => {
const p1 = [ const p1 = [
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"), bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"), bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
]; ];
const p2 = [ const p2 = [
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"), bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"), bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
]; ];
const out = babyjub.addPoint(p1, p2) const out = babyjub.addPoint(p1, p2);
assert(out[0].equals(snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"))); assert(out[0].equals(bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365")));
assert(out[1].equals(snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"))); assert(out[1].equals(bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889")));
}); });
it("Should add 2 different numbers", () => { it("Should add 2 different numbers", () => {
const p1 = [ const p1 = [
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"), bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"), bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
]; ];
const p2 = [ const p2 = [
snarkjs.bigInt("16540640123574156134436876038791482806971768689494387082833631921987005038935"), bigInt("16540640123574156134436876038791482806971768689494387082833631921987005038935"),
snarkjs.bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311"), bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311"),
]; ];
const out = babyjub.addPoint(p1, p2) const out = babyjub.addPoint(p1, p2);
assert(out[0].equals(snarkjs.bigInt("7916061937171219682591368294088513039687205273691143098332585753343424131937"))); assert(out[0].equals(bigInt("7916061937171219682591368294088513039687205273691143098332585753343424131937")));
assert(out[1].equals(snarkjs.bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499"))); assert(out[1].equals(bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499")));
}); });
it("should mulPointEscalar 0", () => { it("should mulPointEscalar 0", () => {
const p = [ const p = [
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"), bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"), bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
]; ];
const r = babyjub.mulPointEscalar(p, snarkjs.bigInt("3")); const r = babyjub.mulPointEscalar(p, bigInt("3"));
let r2 = babyjub.addPoint(p, p); let r2 = babyjub.addPoint(p, p);
r2 = babyjub.addPoint(r2, p); r2 = babyjub.addPoint(r2, p);
assert.equal(r2[0].toString(), r[0].toString()); assert.equal(r2[0].toString(), r[0].toString());
@ -88,65 +86,65 @@ describe("Baby Jub js test", function () {
it("should mulPointEscalar 1", () => { it("should mulPointEscalar 1", () => {
const p = [ const p = [
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"), bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"), bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
]; ];
const r = babyjub.mulPointEscalar(p, snarkjs.bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499")); const r = babyjub.mulPointEscalar(p, bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499"));
assert.equal(r[0].toString(), "17070357974431721403481313912716834497662307308519659060910483826664480189605"); assert.equal(r[0].toString(), "17070357974431721403481313912716834497662307308519659060910483826664480189605");
assert.equal(r[1].toString(), "4014745322800118607127020275658861516666525056516280575712425373174125159339"); assert.equal(r[1].toString(), "4014745322800118607127020275658861516666525056516280575712425373174125159339");
}); });
it("should mulPointEscalar 2", () => { it("should mulPointEscalar 2", () => {
const p = [ const p = [
snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"), bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"), bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
]; ];
const r = babyjub.mulPointEscalar(p, snarkjs.bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311")); const r = babyjub.mulPointEscalar(p, bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311"));
assert.equal(r[0].toString(), "13563888653650925984868671744672725781658357821216877865297235725727006259983"); assert.equal(r[0].toString(), "13563888653650925984868671744672725781658357821216877865297235725727006259983");
assert.equal(r[1].toString(), "8442587202676550862664528699803615547505326611544120184665036919364004251662"); assert.equal(r[1].toString(), "8442587202676550862664528699803615547505326611544120184665036919364004251662");
}); });
it("should inCurve 1", () => { it("should inCurve 1", () => {
const p = [ const p = [
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"), bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"), bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
]; ];
assert(babyjub.inCurve(p)); assert(babyjub.inCurve(p));
}); });
it("should inCurve 2", () => { it("should inCurve 2", () => {
const p = [ const p = [
snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"), bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"), bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
]; ];
assert(babyjub.inCurve(p)); assert(babyjub.inCurve(p));
}); });
it("should inSubgroup 1", () => { it("should inSubgroup 1", () => {
const p = [ const p = [
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"), bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"), bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
]; ];
assert(babyjub.inSubgroup(p)); assert(babyjub.inSubgroup(p));
}); });
it("should inSubgroup 2", () => { it("should inSubgroup 2", () => {
const p = [ const p = [
snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"), bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"), bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
]; ];
assert(babyjub.inSubgroup(p)); assert(babyjub.inSubgroup(p));
}); });
it("should packPoint - unpackPoint 1", () => { it("should packPoint - unpackPoint 1", () => {
const p = [ const p = [
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"), bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"), bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
]; ];
const buf = babyjub.packPoint(p); const buf = babyjub.packPoint(p);
assert.equal(buf.toString('hex'), '53b81ed5bffe9545b54016234682e7b2f699bd42a5e9eae27ff4051bc698ce85'); assert.equal(buf.toString("hex"), "53b81ed5bffe9545b54016234682e7b2f699bd42a5e9eae27ff4051bc698ce85");
const p2 = babyjub.unpackPoint(buf); const p2 = babyjub.unpackPoint(buf);
assert.equal(p2[0].toString(), "17777552123799933955779906779655732241715742912184938656739573121738514868268"); assert.equal(p2[0].toString(), "17777552123799933955779906779655732241715742912184938656739573121738514868268");
assert.equal(p2[1].toString(), "2626589144620713026669568689430873010625803728049924121243784502389097019475"); assert.equal(p2[1].toString(), "2626589144620713026669568689430873010625803728049924121243784502389097019475");
@ -154,11 +152,11 @@ describe("Baby Jub js test", function () {
it("should packPoint - unpackPoint 2", () => { it("should packPoint - unpackPoint 2", () => {
const p = [ const p = [
snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"), bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"), bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
]; ];
const buf = babyjub.packPoint(p); const buf = babyjub.packPoint(p);
assert.equal(buf.toString('hex'), 'e114eb17eddf794f063a68fecac515e3620e131976108555735c8b0773929709'); assert.equal(buf.toString("hex"), "e114eb17eddf794f063a68fecac515e3620e131976108555735c8b0773929709");
const p2 = babyjub.unpackPoint(buf); const p2 = babyjub.unpackPoint(buf);
assert.equal(p2[0].toString(), "6890855772600357754907169075114257697580319025794532037257385534741338397365"); assert.equal(p2[0].toString(), "6890855772600357754907169075114257697580319025794532037257385534741338397365");
assert.equal(p2[1].toString(), "4338620300185947561074059802482547481416142213883829469920100239455078257889"); assert.equal(p2[1].toString(), "4338620300185947561074059802482547481416142213883829469920100239455078257889");