Bump version & use snarkjs dependency from self-hosted tornado git registry

This commit is contained in:
Theo 2023-07-21 03:10:01 -07:00
parent 3b492f9801
commit 14314b6bbb
45 changed files with 1056 additions and 1188 deletions

1
.npmrc Normal file

@ -0,0 +1 @@
@tornado:registry=https://git.tornado.ws/api/packages/tornado-packages/npm/

@ -1,5 +1,5 @@
const bn128 = require("snarkjs").bn128; const bn128 = require("@tornado/snarkjs").bn128;
const bigInt = require("snarkjs").bigInt; const bigInt = require("@tornado/snarkjs").bigInt;
const createBlakeHash = require("blake-hash"); const createBlakeHash = require("blake-hash");
const babyJub = require("../src/babyjub"); const babyJub = require("../src/babyjub");
@ -8,17 +8,17 @@ function getPoint(S) {
const h = createBlakeHash("blake256").update(S).digest(); const h = createBlakeHash("blake256").update(S).digest();
if (h.length != 32) { if (h.length != 32) {
throw new Error("Invalid length") throw new Error("Invalid length");
} }
let sign = false; let sign = false;
if (h[31] & 0x80) { if (h[31] & 0x80) {
h[31] = h[31] & 0x7F; h[31] = h[31] & 0x7f;
sign = true; sign = true;
} }
let y = bigInt(0); let y = bigInt(0);
for (let i=0; i<32; i++) { for (let i = 0; i < 32; i++) {
y = y.shl(8); y = y.shl(8);
y = y.add(bigInt(h[i])); y = y.add(bigInt(h[i]));
} }
@ -28,9 +28,7 @@ function getPoint(S) {
const y2 = F.square(y); const y2 = F.square(y);
let x = F.sqrt(F.div( let x = F.sqrt(F.div(F.sub(F.one, y2), F.sub(a, F.mul(d, y2))));
F.sub(F.one, y2),
F.sub(a, F.mul(d, y2))));
if (x == null) return null; if (x == null) return null;
@ -43,41 +41,34 @@ function getPoint(S) {
return p8; return p8;
} }
function generatePoint(S) { function generatePoint(S) {
let p= null; let p = null;
let idx = 0; let idx = 0;
while (p==null) { while (p == null) {
let sidx = "" + idx; let sidx = "" + idx;
while (sidx.length<16) sidx = "0"+sidx; while (sidx.length < 16) sidx = "0" + sidx;
p = getPoint(S+"_"+sidx); p = getPoint(S + "_" + sidx);
idx++; idx++;
} }
if (!babyJub.inCurve(p)){ if (!babyJub.inCurve(p)) {
throw new Error("Point not in curve"); throw new Error("Point not in curve");
} }
return p; return p;
} }
const g = [ const g = [
bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"), bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")]; bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203"),
];
// Sanity check // Sanity check
if (!babyJub.inCurve(g)) { if (!babyJub.inCurve(g)) {
throw new Error("Generator not In curve -> Some thing goes wrong..."); throw new Error("Generator not In curve -> Some thing goes wrong...");
} }
for (let i=0; i<25; i++) { for (let i = 0; i < 25; i++) {
let S = "" +i; let S = "" + i;
while (S.length<16) S = "0"+S; while (S.length < 16) S = "0" + S;
const P = generatePoint("Iden3_PedersenGenerator_"+S); const P = generatePoint("Iden3_PedersenGenerator_" + S);
console.log(`[${P[0].toString()}, ${P[1].toString()}]`); console.log(`[${P[0].toString()}, ${P[1].toString()}]`);
} }

@ -1,6 +1,6 @@
{ {
"name": "circomlib", "name": "@tornado/circomlib",
"version": "0.0.20", "version": "0.0.21",
"description": "Basic circuits library for Circom", "description": "Basic circuits library for Circom",
"main": "index.js", "main": "index.js",
"directories": { "directories": {
@ -19,14 +19,14 @@
], ],
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/iden3/circomlib.git" "url": "https://git.tornado.ws/tornado-packages/circomlib.git"
}, },
"author": "0Kims", "author": "0Kims",
"license": "GPL-3.0", "license": "GPL-3.0",
"dependencies": { "dependencies": {
"blake-hash": "^1.1.0", "blake-hash": "^1.1.0",
"blake2b": "^2.1.3", "blake2b": "^2.1.3",
"snarkjs": "git+https://github.com/tornadocash/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5", "@tornado/snarkjs": "0.1.20",
"typedarray-to-buffer": "^3.1.5", "typedarray-to-buffer": "^3.1.5",
"web3": "^1.2.11" "web3": "^1.2.11"
}, },

@ -1,5 +1,5 @@
const bn128 = require("snarkjs").bn128; const bn128 = require("@tornado/snarkjs").bn128;
const bigInt = require("snarkjs").bigInt; const bigInt = require("@tornado/snarkjs").bigInt;
exports.addPoint = addPoint; exports.addPoint = addPoint;
exports.mulPointEscalar = mulPointEscalar; exports.mulPointEscalar = mulPointEscalar;
@ -9,11 +9,11 @@ exports.packPoint = packPoint;
exports.unpackPoint = unpackPoint; exports.unpackPoint = unpackPoint;
exports.Generator = [ exports.Generator = [
bigInt("995203441582195749578291179787384436505546430278305826713579947235728471134"), bigInt("995203441582195749578291179787384436505546430278305826713579947235728471134"),
bigInt("5472060717959818805561601436314318772137091100104008585924551046643952123905") bigInt("5472060717959818805561601436314318772137091100104008585924551046643952123905"),
]; ];
exports.Base8 = [ exports.Base8 = [
bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"), bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203") bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203"),
]; ];
exports.order = bigInt("21888242871839275222246405745257275088614511777268538073601725287587578984328"); exports.order = bigInt("21888242871839275222246405745257275088614511777268538073601725287587578984328");
exports.subOrder = exports.order.shr(3); exports.subOrder = exports.order.shr(3);
@ -21,8 +21,7 @@ exports.p = bn128.r;
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 q = bn128.r;
const res = []; const res = [];
@ -31,18 +30,28 @@ 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[0] = bigInt(
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); 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);
return res; return res;
} }
function mulPointEscalar(base, e) { function mulPointEscalar(base, e) {
let res = [bigInt("0"),bigInt("1")]; let res = [bigInt("0"), bigInt("1")];
let rem = bigInt(e); let rem = bigInt(e);
let exp = base; let exp = base;
while (! rem.isZero()) { while (!rem.isZero()) {
if (rem.isOdd()) { if (rem.isOdd()) {
res = addPoint(res, exp); res = addPoint(res, exp);
} }
@ -55,8 +64,8 @@ function mulPointEscalar(base, e) {
function inSubgroup(P) { function inSubgroup(P) {
if (!inCurve(P)) return false; if (!inCurve(P)) return false;
const res= mulPointEscalar(P, exports.subOrder); const res = mulPointEscalar(P, exports.subOrder);
return (res[0].equals(bigInt(0))) && (res[1].equals(bigInt(1))); return res[0].equals(bigInt(0)) && res[1].equals(bigInt(1));
} }
function inCurve(P) { function inCurve(P) {
@ -65,9 +74,7 @@ function inCurve(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.equals(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.mul(exports.A, x2), y2),
F.add(F.one, F.mul(F.mul(x2, y2), exports.D)))) return false;
return true; return true;
} }
@ -88,16 +95,14 @@ function unpackPoint(_buff) {
const P = new Array(2); const P = new Array(2);
if (buff[31] & 0x80) { if (buff[31] & 0x80) {
sign = true; sign = true;
buff[31] = buff[31] & 0x7F; buff[31] = buff[31] & 0x7f;
} }
P[1] = bigInt.leBuff2int(buff); P[1] = bigInt.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]);
let x = F.sqrt(F.div( let x = F.sqrt(F.div(F.sub(F.one, y2), F.sub(exports.A, F.mul(exports.D, y2))));
F.sub(F.one, y2),
F.sub(exports.A, F.mul(exports.D, y2))));
if (x == null) return null; if (x == null) return null;

@ -1,12 +1,12 @@
const createBlakeHash = require("blake-hash"); const createBlakeHash = require("blake-hash");
const bigInt = require("snarkjs").bigInt; const bigInt = require("@tornado/snarkjs").bigInt;
const babyJub = require("./babyjub"); const babyJub = require("./babyjub");
const pedersenHash = require("./pedersenHash").hash; const pedersenHash = require("./pedersenHash").hash;
const mimc7 = require("./mimc7"); const mimc7 = require("./mimc7");
const poseidon = require("./poseidon.js"); const poseidon = require("./poseidon.js");
const mimcsponge = require("./mimcsponge"); const mimcsponge = require("./mimcsponge");
exports.prv2pub= prv2pub; exports.prv2pub = prv2pub;
exports.sign = sign; exports.sign = sign;
exports.signMiMC = signMiMC; exports.signMiMC = signMiMC;
exports.signPoseidon = signPoseidon; exports.signPoseidon = signPoseidon;
@ -19,17 +19,16 @@ exports.packSignature = packSignature;
exports.unpackSignature = unpackSignature; exports.unpackSignature = unpackSignature;
exports.pruneBuffer = pruneBuffer; exports.pruneBuffer = pruneBuffer;
function pruneBuffer(_buff) { function pruneBuffer(_buff) {
const buff = Buffer.from(_buff); const buff = Buffer.from(_buff);
buff[0] = buff[0] & 0xF8; buff[0] = buff[0] & 0xf8;
buff[31] = buff[31] & 0x7F; buff[31] = buff[31] & 0x7f;
buff[31] = buff[31] | 0x40; buff[31] = buff[31] | 0x40;
return buff; return buff;
} }
function prv2pub(prv) { function prv2pub(prv) {
const sBuff = pruneBuffer(createBlakeHash("blake512").update(prv).digest().slice(0,32)); const sBuff = pruneBuffer(createBlakeHash("blake512").update(prv).digest().slice(0, 32));
let s = bigInt.leBuff2int(sBuff); let s = bigInt.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3)); const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
return A; return A;
@ -37,11 +36,13 @@ function prv2pub(prv) {
function sign(prv, msg) { function sign(prv, msg) {
const h1 = createBlakeHash("blake512").update(prv).digest(); const h1 = createBlakeHash("blake512").update(prv).digest();
const sBuff = pruneBuffer(h1.slice(0,32)); const sBuff = pruneBuffer(h1.slice(0, 32));
const s = bigInt.leBuff2int(sBuff); const s = bigInt.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3)); const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msg])).digest(); const rBuff = createBlakeHash("blake512")
.update(Buffer.concat([h1.slice(32, 64), msg]))
.digest();
let r = bigInt.leBuff2int(rBuff); let r = bigInt.leBuff2int(rBuff);
r = r.mod(babyJub.subOrder); r = r.mod(babyJub.subOrder);
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r); const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
@ -52,18 +53,20 @@ function sign(prv, msg) {
const S = r.add(hm.mul(s)).mod(babyJub.subOrder); const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
return { return {
R8: R8, R8: R8,
S: S S: S,
}; };
} }
function signMiMC(prv, msg) { function signMiMC(prv, msg) {
const h1 = createBlakeHash("blake512").update(prv).digest(); const h1 = createBlakeHash("blake512").update(prv).digest();
const sBuff = pruneBuffer(h1.slice(0,32)); const sBuff = pruneBuffer(h1.slice(0, 32));
const s = bigInt.leBuff2int(sBuff); const s = bigInt.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3)); const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
const msgBuff = bigInt.leInt2Buff(msg, 32); const msgBuff = bigInt.leInt2Buff(msg, 32);
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest(); const rBuff = createBlakeHash("blake512")
.update(Buffer.concat([h1.slice(32, 64), msgBuff]))
.digest();
let r = bigInt.leBuff2int(rBuff); let r = bigInt.leBuff2int(rBuff);
r = r.mod(babyJub.subOrder); r = r.mod(babyJub.subOrder);
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r); const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
@ -71,18 +74,20 @@ function signMiMC(prv, msg) {
const S = r.add(hm.mul(s)).mod(babyJub.subOrder); const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
return { return {
R8: R8, R8: R8,
S: S S: S,
}; };
} }
function signMiMCSponge(prv, msg) { function signMiMCSponge(prv, msg) {
const h1 = createBlakeHash("blake512").update(prv).digest(); const h1 = createBlakeHash("blake512").update(prv).digest();
const sBuff = pruneBuffer(h1.slice(0,32)); const sBuff = pruneBuffer(h1.slice(0, 32));
const s = bigInt.leBuff2int(sBuff); const s = bigInt.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3)); const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
const msgBuff = bigInt.leInt2Buff(msg, 32); const msgBuff = bigInt.leInt2Buff(msg, 32);
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest(); const rBuff = createBlakeHash("blake512")
.update(Buffer.concat([h1.slice(32, 64), msgBuff]))
.digest();
let r = bigInt.leBuff2int(rBuff); let r = bigInt.leBuff2int(rBuff);
r = r.mod(babyJub.subOrder); r = r.mod(babyJub.subOrder);
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r); const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
@ -90,18 +95,20 @@ function signMiMCSponge(prv, msg) {
const S = r.add(hm.mul(s)).mod(babyJub.subOrder); const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
return { return {
R8: R8, R8: R8,
S: S S: S,
}; };
} }
function signPoseidon(prv, msg) { function signPoseidon(prv, msg) {
const h1 = createBlakeHash("blake512").update(prv).digest(); const h1 = createBlakeHash("blake512").update(prv).digest();
const sBuff = pruneBuffer(h1.slice(0,32)); const sBuff = pruneBuffer(h1.slice(0, 32));
const s = bigInt.leBuff2int(sBuff); const s = bigInt.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3)); const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
const msgBuff = bigInt.leInt2Buff(msg, 32); const msgBuff = bigInt.leInt2Buff(msg, 32);
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest(); const rBuff = createBlakeHash("blake512")
.update(Buffer.concat([h1.slice(32, 64), msgBuff]))
.digest();
let r = bigInt.leBuff2int(rBuff); let r = bigInt.leBuff2int(rBuff);
r = r.mod(babyJub.subOrder); r = r.mod(babyJub.subOrder);
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r); const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
@ -109,7 +116,7 @@ function signPoseidon(prv, msg) {
const S = r.add(hm.mul(s)).mod(babyJub.subOrder); const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
return { return {
R8: R8, R8: R8,
S: S S: S,
}; };
} }
@ -117,12 +124,12 @@ function verify(msg, sig, A) {
// Check parameters // Check parameters
if (typeof sig != "object") return false; if (typeof sig != "object") return false;
if (!Array.isArray(sig.R8)) return false; if (!Array.isArray(sig.R8)) return false;
if (sig.R8.length!= 2) return false; if (sig.R8.length != 2) return false;
if (!babyJub.inCurve(sig.R8)) return false; if (!babyJub.inCurve(sig.R8)) return false;
if (!Array.isArray(A)) return false; if (!Array.isArray(A)) return false;
if (A.length!= 2) return false; if (A.length != 2) return false;
if (!babyJub.inCurve(A)) return false; if (!babyJub.inCurve(A)) return false;
if (sig.S>= babyJub.subOrder) return false; if (sig.S >= babyJub.subOrder) return false;
const R8p = babyJub.packPoint(sig.R8); const R8p = babyJub.packPoint(sig.R8);
const Ap = babyJub.packPoint(A); const Ap = babyJub.packPoint(A);
@ -142,12 +149,12 @@ function verifyMiMC(msg, sig, A) {
// Check parameters // Check parameters
if (typeof sig != "object") return false; if (typeof sig != "object") return false;
if (!Array.isArray(sig.R8)) return false; if (!Array.isArray(sig.R8)) return false;
if (sig.R8.length!= 2) return false; if (sig.R8.length != 2) return false;
if (!babyJub.inCurve(sig.R8)) return false; if (!babyJub.inCurve(sig.R8)) return false;
if (!Array.isArray(A)) return false; if (!Array.isArray(A)) return false;
if (A.length!= 2) return false; if (A.length != 2) return false;
if (!babyJub.inCurve(A)) return false; if (!babyJub.inCurve(A)) return false;
if (sig.S>= babyJub.subOrder) return false; if (sig.S >= babyJub.subOrder) return false;
const hm = mimc7.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]); const hm = mimc7.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
@ -160,17 +167,16 @@ function verifyMiMC(msg, sig, A) {
return true; return true;
} }
function verifyPoseidon(msg, sig, A) { function verifyPoseidon(msg, sig, A) {
// Check parameters // Check parameters
if (typeof sig != "object") return false; if (typeof sig != "object") return false;
if (!Array.isArray(sig.R8)) return false; if (!Array.isArray(sig.R8)) return false;
if (sig.R8.length!= 2) return false; if (sig.R8.length != 2) return false;
if (!babyJub.inCurve(sig.R8)) return false; if (!babyJub.inCurve(sig.R8)) return false;
if (!Array.isArray(A)) return false; if (!Array.isArray(A)) return false;
if (A.length!= 2) return false; if (A.length != 2) return false;
if (!babyJub.inCurve(A)) return false; if (!babyJub.inCurve(A)) return false;
if (sig.S>= babyJub.subOrder) return false; if (sig.S >= babyJub.subOrder) return false;
const hm = poseidon([sig.R8[0], sig.R8[1], A[0], A[1], msg]); const hm = poseidon([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
@ -187,12 +193,12 @@ function verifyMiMCSponge(msg, sig, A) {
// Check parameters // Check parameters
if (typeof sig != "object") return false; if (typeof sig != "object") return false;
if (!Array.isArray(sig.R8)) return false; if (!Array.isArray(sig.R8)) return false;
if (sig.R8.length!= 2) return false; if (sig.R8.length != 2) return false;
if (!babyJub.inCurve(sig.R8)) return false; if (!babyJub.inCurve(sig.R8)) return false;
if (!Array.isArray(A)) return false; if (!Array.isArray(A)) return false;
if (A.length!= 2) return false; if (A.length != 2) return false;
if (!babyJub.inCurve(A)) return false; if (!babyJub.inCurve(A)) return false;
if (sig.S>= babyJub.subOrder) return false; if (sig.S >= babyJub.subOrder) return false;
const hm = mimcsponge.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]); const hm = mimcsponge.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
@ -213,9 +219,7 @@ function packSignature(sig) {
function unpackSignature(sigBuff) { function unpackSignature(sigBuff) {
return { return {
R8: babyJub.unpackPoint(sigBuff.slice(0,32)), R8: babyJub.unpackPoint(sigBuff.slice(0, 32)),
S: bigInt.leBuff2int(sigBuff.slice(32,64)) S: bigInt.leBuff2int(sigBuff.slice(32, 64)),
}; };
} }

@ -3,24 +3,22 @@
// //
const Contract = require("./evmasm"); const Contract = require("./evmasm");
const G2 = require("snarkjs").bn128.G2; const G2 = require("@tornado/snarkjs").bn128.G2;
const bigInt = require("snarkjs").bigInt; const bigInt = require("@tornado/snarkjs").bigInt;
function toHex256(a) { function toHex256(a) {
let S = a.toString(16); let S = a.toString(16);
while (S.length < 64) S="0"+S; while (S.length < 64) S = "0" + S;
return "0x" + S; return "0x" + S;
} }
function createCode(P, w) { function createCode(P, w) {
const C = new Contract(); const C = new Contract();
const NPOINTS = 1 << (w-1); const NPOINTS = 1 << (w - 1);
const VAR_POS = C.allocMem(32); const VAR_POS = C.allocMem(32);
const VAR_POINTS = C.allocMem( (NPOINTS)*4*32); const VAR_POINTS = C.allocMem(NPOINTS * 4 * 32);
const savedP = C.allocMem(32); const savedP = C.allocMem(32);
const savedZ3 = C.allocMem(32); const savedZ3 = C.allocMem(32);
@ -38,7 +36,7 @@ function createCode(P, w) {
storeVals(); storeVals();
C.push( Math.floor(255/w)*w ); // pos := 255 C.push(Math.floor(255 / w) * w); // pos := 255
C.push(VAR_POS); C.push(VAR_POS);
C.mstore(); C.mstore();
@ -62,7 +60,7 @@ function createCode(P, w) {
C.mload(); // pos e ACC_X ACC_Y ACC_Z q C.mload(); // pos e ACC_X ACC_Y ACC_Z q
C.shr(); C.shr();
C.push(NPOINTS-1); C.push(NPOINTS - 1);
C.and(); // g ACC_X ACC_Y ACC_Z q C.and(); // g ACC_X ACC_Y ACC_Z q
C.internalCall("add"); // acc_x acc_y acc_z C.internalCall("add"); // acc_x acc_y acc_z
@ -96,17 +94,16 @@ function createCode(P, w) {
C.push("0x00"); C.push("0x00");
C.return(); C.return();
double(); double();
addPoint(); addPoint();
affine(); affine();
return C.createTxData(); return C.createTxData();
function add(a,b,q) { function add(a, b, q) {
C.dup(q); C.dup(q);
C.dup(a+1 + 1); C.dup(a + 1 + 1);
C.dup(b+1 + 2); C.dup(b + 1 + 2);
C.addmod(); C.addmod();
C.dup(q + 1); C.dup(q + 1);
C.dup(a + 2); C.dup(a + 2);
@ -114,11 +111,11 @@ function createCode(P, w) {
C.addmod(); C.addmod();
} }
function sub(a,b,q) { function sub(a, b, q) {
C.dup(q); // q C.dup(q); // q
C.dup(a+1 + 1); // ai q C.dup(a + 1 + 1); // ai q
C.dub(q + 2); // q ai q C.dub(q + 2); // q ai q
C.dup(b+1 + 3); // bi q ai q C.dup(b + 1 + 3); // bi q ai q
C.sub(); // -bi ai q C.sub(); // -bi ai q
C.addmod(); // ci C.addmod(); // ci
C.dup(q + 1); // q ci C.dup(q + 1); // q ci
@ -133,18 +130,18 @@ function createCode(P, w) {
C.dup(q); // q C.dup(q); // q
C.dup(q + 1); // q q C.dup(q + 1); // q q
C.dup(a + 2); // ar q q C.dup(a + 2); // ar q q
C.dup(b+1 + 3); // bi ar q q C.dup(b + 1 + 3); // bi ar q q
C.mulmod(); // ci1 q C.mulmod(); // ci1 q
C.dup(q + 2); // q ci1 q C.dup(q + 2); // q ci1 q
C.dup(a+1 + 3); // ai q ci1 q C.dup(a + 1 + 3); // ai q ci1 q
C.dup(b + 4); // ar ai q ci1 q C.dup(b + 4); // ar ai q ci1 q
C.mulmod(); // ci2 ci1 q C.mulmod(); // ci2 ci1 q
C.addmod(); // ci C.addmod(); // ci
C.dup(q + 1); // q ci C.dup(q + 1); // q ci
C.dup(q + 2); // q q ci C.dup(q + 2); // q q ci
C.dup(q + 3); // q q q ci C.dup(q + 3); // q q q ci
C.dup(a+1 + 4); // ai q q ci C.dup(a + 1 + 4); // ai q q ci
C.dup(b+1 + 5); // bi ai q q ci C.dup(b + 1 + 5); // bi ai q q ci
C.mulmod(); // cr2 q q ci C.mulmod(); // cr2 q q ci
C.sub(); // -cr2 q ci C.sub(); // -cr2 q ci
C.dup(q + 3); // q -cr2 q ci C.dup(q + 3); // q -cr2 q ci
@ -158,15 +155,15 @@ function createCode(P, w) {
C.dup(q); // q C.dup(q); // q
C.dup(q + 1); // q q C.dup(q + 1); // q q
C.dup(a + 2); // ar q q C.dup(a + 2); // ar q q
C.dup(a+1 + 3); // ai ar q q C.dup(a + 1 + 3); // ai ar q q
C.mulmod(); // arai q C.mulmod(); // arai q
C.dup(0); // arai arai q C.dup(0); // arai arai q
C.addmod(); // ci C.addmod(); // ci
C.dup(q + 1); // q ci C.dup(q + 1); // q ci
C.dup(q + 2); // q q ci C.dup(q + 2); // q q ci
C.dup(q + 3); // q q q ci C.dup(q + 3); // q q q ci
C.dup(a+1 + 4); // ai q q ci C.dup(a + 1 + 4); // ai q q ci
C.dup(a+1 + 5); // ai ai q q ci C.dup(a + 1 + 5); // ai ai q q ci
C.mulmod(); // cr2 q q ci C.mulmod(); // cr2 q q ci
C.sub(); // -cr2 q ci C.sub(); // -cr2 q ci
C.dup(q + 3); // q -cr2 q ci C.dup(q + 3); // q -cr2 q ci
@ -177,7 +174,7 @@ function createCode(P, w) {
} }
function add1(a, q) { function add1(a, q) {
C.dup(a+1); // im C.dup(a + 1); // im
C.dup(1 + q); // q C.dup(1 + q); // q
C.dup(2 + a); // re q im C.dup(2 + a); // re q im
C.push(1); // 1 re q im C.push(1); // 1 re q im
@ -188,15 +185,15 @@ function createCode(P, w) {
C.dup(a); C.dup(a);
C.dup(b); C.dup(b);
C.eq(); C.eq();
C.dup(a+1); C.dup(a + 1);
C.dup(a+1); C.dup(a + 1);
C.and(); C.and();
} }
function rm(a) { function rm(a) {
if (a>0) C.swap(a); if (a > 0) C.swap(a);
C.pop(); C.pop();
if (a>0) C.swap(a); if (a > 0) C.swap(a);
C.pop(); C.pop();
} }
@ -210,7 +207,6 @@ function createCode(P, w) {
C.and(); C.and();
C.jumpi("enddouble"); // X Y Z q C.jumpi("enddouble"); // X Y Z q
// Z3 = 2*Y*Z // Remove Z // Z3 = 2*Y*Z // Remove Z
mul(2, 4, 6); // yz X Y Z q mul(2, 4, 6); // yz X Y Z q
rm(6); // X Y yz q rm(6); // X Y yz q
@ -219,20 +215,20 @@ function createCode(P, w) {
rm(6); // X Y Z3 q rm(6); // X Y Z3 q
// A = X^2 // A = X^2
square(0,6); // A X Y Z3 q square(0, 6); // A X Y Z3 q
// B = Y^2 // Remove Y // B = Y^2 // Remove Y
square(4,8); // B A X Y Z3 q square(4, 8); // B A X Y Z3 q
rm(6); // A X B Z3 q rm(6); // A X B Z3 q
// C = B^2 // C = B^2
square(4,8); // C A X B Z3 q square(4, 8); // C A X B Z3 q
// D = (X+B)^2-A-C // Remove X, Remove B // D = (X+B)^2-A-C // Remove X, Remove B
add(4,6, 10); // X+B C A X B Z3 q add(4, 6, 10); // X+B C A X B Z3 q
rm(6); // C A X+B B Z3 q rm(6); // C A X+B B Z3 q
rm(6); // A X+B C Z3 q rm(6); // A X+B C Z3 q
square(2,8); // (X+B)^2 A X+B C Z3 q square(2, 8); // (X+B)^2 A X+B C Z3 q
rm(4); // A (X+B)^2 C Z3 q rm(4); // A (X+B)^2 C Z3 q
sub(2, 0, 8); // (X+B)^2-A A (X+B)^2 C Z3 q sub(2, 0, 8); // (X+B)^2-A A (X+B)^2 C Z3 q
rm(4); // A (X+B)^2-A C Z3 q rm(4); // A (X+B)^2-A C Z3 q
@ -240,7 +236,7 @@ function createCode(P, w) {
rm(4); // A D C Z3 q rm(4); // A D C Z3 q
// D = D+D // D = D+D
add(2,2, 8); // D+D A D C Z3 q add(2, 2, 8); // D+D A D C Z3 q
rm(4); // A D C Z3 q rm(4); // A D C Z3 q
// E=A+A+A // E=A+A+A
@ -279,8 +275,8 @@ function createCode(P, w) {
C.returnCall(); C.returnCall();
} }
function addPoint() { // p, xR, xI, yR, yI, zR zI, q function addPoint() {
// p, xR, xI, yR, yI, zR zI, q
C.dup(0); // p p X2 Y2 Z2 q C.dup(0); // p p X2 Y2 Z2 q
@ -290,7 +286,6 @@ function createCode(P, w) {
C.iszero(); // X2 Y2 Z2 q C.iszero(); // X2 Y2 Z2 q
C.jumpi("endpadd"); C.jumpi("endpadd");
C.dup(4); C.dup(4);
C.iszero(); C.iszero();
C.dup(6); C.dup(6);
@ -298,15 +293,12 @@ function createCode(P, w) {
C.and(); C.and();
C.jumpi("returnP"); // X2 Y2 Z2 q C.jumpi("returnP"); // X2 Y2 Z2 q
// lastZ3 = (Z2+1)^2 - Z2^2 // lastZ3 = (Z2+1)^2 - Z2^2
add1(4, 6); // Z2+1 X2 Y2 Z2 q add1(4, 6); // Z2+1 X2 Y2 Z2 q
square(0, 8); // (Z2+1)^2 Z2+1 X2 Y2 Z2 q square(0, 8); // (Z2+1)^2 Z2+1 X2 Y2 Z2 q
rm(2); // (Z2+1)^2 X2 Y2 Z2 q rm(2); // (Z2+1)^2 X2 Y2 Z2 q
square(6, 8); // Z2^2 (Z2+1)^2 X2 Y2 Z2 q square(6, 8); // Z2^2 (Z2+1)^2 X2 Y2 Z2 q
sub(2, 0, 10); // (Z2+1)^2-Z2^2 Z2^2 (Z2+1)^2 X2 Y2 Z2 q sub(2, 0, 10); // (Z2+1)^2-Z2^2 Z2^2 (Z2+1)^2 X2 Y2 Z2 q
saveZ3(); // Z2^2 (Z2+1)^2 X2 Y2 Z2 q saveZ3(); // Z2^2 (Z2+1)^2 X2 Y2 Z2 q
@ -315,13 +307,11 @@ function createCode(P, w) {
// U2 = X2 // U2 = X2
// S2 = Y2 // Z2^2 U2 S2 Z2 q // S2 = Y2 // Z2^2 U2 S2 Z2 q
// U1 = X1 * Z2^2 // U1 = X1 * Z2^2
loadX(); // X1 Z2^2 U2 S2 Z2 q loadX(); // X1 Z2^2 U2 S2 Z2 q
mul(0, 2, 10); // X1*Z2^2 X1 Z2^2 U2 S2 Z2 q mul(0, 2, 10); // X1*Z2^2 X1 Z2^2 U2 S2 Z2 q
rm(2); // X1*Z2^2 Z2^2 U2 S2 Z2 q rm(2); // X1*Z2^2 Z2^2 U2 S2 Z2 q
mul(2, 8, 10); // Z2^3 U1 Z2^2 U2 S2 Z2 q mul(2, 8, 10); // Z2^3 U1 Z2^2 U2 S2 Z2 q
rm(4); // U1 Z2^3 U2 S2 Z2 q rm(4); // U1 Z2^3 U2 S2 Z2 q
rm(8); // Z2^3 U2 S2 U1 q rm(8); // Z2^3 U2 S2 U1 q
@ -337,7 +327,6 @@ function createCode(P, w) {
C.and(); // c2&c1 S1 U2 S2 U1 q C.and(); // c2&c1 S1 U2 S2 U1 q
C.jumpi("double1"); // S1 U2 S2 U1 q C.jumpi("double1"); // S1 U2 S2 U1 q
// Returns the double // Returns the double
// H = U2-U1 // Remove U2 // H = U2-U1 // Remove U2
@ -368,7 +357,7 @@ function createCode(P, w) {
// S1J2 = (S1*J)*2 // Remove S1 // S1J2 = (S1*J)*2 // Remove S1
mul(2, 0, 10); // S1*J J S1 H r V q mul(2, 0, 10); // S1*J J S1 H r V q
rm(4); // J S1*J H r V q rm(4); // J S1*J H r V q
add(2,2, 10); // (S1*J)*2 J S1*J H r V q add(2, 2, 10); // (S1*J)*2 J S1*J H r V q
rm(4); // J S1J2 H r V q rm(4); // J S1J2 H r V q
// X3 = r^2 - J - 2 * V // X3 = r^2 - J - 2 * V
@ -433,7 +422,7 @@ function createCode(P, w) {
C.mload(); // p C.mload(); // p
C.push(32); C.push(32);
C.mul(); // P*32 C.mul(); // P*32
C.push(VAR_POINTS+32); C.push(VAR_POINTS + 32);
C.add(); // P*32+32 C.add(); // P*32+32
C.dup(); // P*32+32 P*32+32 C.dup(); // P*32+32 P*32+32
C.mload(); // im P*32+32 C.mload(); // im P*32+32
@ -448,7 +437,7 @@ function createCode(P, w) {
C.mload(); // p C.mload(); // p
C.push(32); C.push(32);
C.mul(); // P*32 C.mul(); // P*32
C.push(VAR_POINTS+32*3); C.push(VAR_POINTS + 32 * 3);
C.add(); // P*32+32 C.add(); // P*32+32
C.dup(); // P*32+32 P*32+32 C.dup(); // P*32+32 P*32+32
C.mload(); // im P*32+32 C.mload(); // im P*32+32
@ -459,7 +448,7 @@ function createCode(P, w) {
} }
function loadZ3() { function loadZ3() {
C.push(savedZ3+32); C.push(savedZ3 + 32);
C.mload(); // p C.mload(); // p
C.push(savedZ3); C.push(savedZ3);
C.mload(); C.mload();
@ -468,12 +457,13 @@ function createCode(P, w) {
function saveZ3() { function saveZ3() {
C.push(savedZ3); C.push(savedZ3);
C.mstore(); C.mstore();
C.push(savedZ3+32); C.push(savedZ3 + 32);
C.mstore(); C.mstore();
} }
} }
function affine() { // X Y Z q function affine() {
// X Y Z q
// If Z2=0 return 0 // If Z2=0 return 0
C.label("affine"); C.label("affine");
C.dup(4); C.dup(4);
@ -488,7 +478,7 @@ function createCode(P, w) {
C.jmp("endAffine"); C.jmp("endAffine");
C.label("notZero"); C.label("notZero");
inverse2(4,6); // Z_inv X Y Z q inverse2(4, 6); // Z_inv X Y Z q
square(2, 8); // Z2_inv Z_inv X Y Z q square(2, 8); // Z2_inv Z_inv X Y Z q
mul(0, 2, 10); // Z3_inv Z2_inv Z_inv X Y Z q mul(0, 2, 10); // Z3_inv Z2_inv Z_inv X Y Z q
rm(4); // Z2_inv Z3_inv X Y Z q rm(4); // Z2_inv Z3_inv X Y Z q
@ -517,8 +507,8 @@ function createCode(P, w) {
C.mulmod(); // t0 q q-2 q C.mulmod(); // t0 q q-2 q
C.dup(q + 4); // q t0 q q-2 q C.dup(q + 4); // q t0 q q-2 q
C.dup(a+1 + 5); // ai q t0 q q-2 q C.dup(a + 1 + 5); // ai q t0 q q-2 q
C.dup(a+1 + 6); // ai ai q t0 q q-2 q C.dup(a + 1 + 6); // ai ai q t0 q q-2 q
C.mulmod(); // t1 t0 q q-2 q C.mulmod(); // t1 t0 q q-2 q
C.addmod(); // t2 q-2 q C.addmod(); // t2 q-2 q
@ -529,7 +519,7 @@ function createCode(P, w) {
C.dup(q + 3); // q q q t3 C.dup(q + 3); // q q q t3
C.dup(1); // t3 q q q t3 C.dup(1); // t3 q q q t3
C.sub(); // -t3 q q t3 C.sub(); // -t3 q q t3
C.dup(a+1 + 3); // ai -t3 q q t3 C.dup(a + 1 + 3); // ai -t3 q q t3
C.mulmod(); // ii q t3 C.mulmod(); // ii q t3
C.swap(2); // t3 q ii C.swap(2); // t3 q ii
C.dup(a + 3); // ar t3 q ii C.dup(a + 3); // ar t3 q ii
@ -538,10 +528,10 @@ function createCode(P, w) {
function storeVals() { function storeVals() {
C.push(VAR_POINTS); // p C.push(VAR_POINTS); // p
for (let i=0; i<NPOINTS; i++) { for (let i = 0; i < NPOINTS; i++) {
const MP = G2.affine(G2.mulScalar(P, bigInt(i))); const MP = G2.affine(G2.mulScalar(P, bigInt(i)));
for (let j=0; j<2; j++) { for (let j = 0; j < 2; j++) {
for (let k=0; k<2; k++) { for (let k = 0; k < 2; k++) {
C.push(toHex256(MP[j][k])); // MP[0][0] p C.push(toHex256(MP[j][k])); // MP[0][0] p
C.dup(1); // p MP[0][0] p C.dup(1); // p MP[0][0] p
C.mstore(); // p C.mstore(); // p
@ -551,33 +541,32 @@ function createCode(P, w) {
} }
} }
} }
} }
module.exports.abi = [ module.exports.abi = [
{ {
"constant": true, constant: true,
"inputs": [ inputs: [
{ {
"name": "escalar", name: "escalar",
"type": "uint256" type: "uint256",
} },
], ],
"name": "mulexp", name: "mulexp",
"outputs": [ outputs: [
{ {
"name": "", name: "",
"type": "uint256" type: "uint256",
}, },
{ {
"name": "", name: "",
"type": "uint256" type: "uint256",
} },
], ],
"payable": false, payable: false,
"stateMutability": "pure", stateMutability: "pure",
"type": "function" type: "function",
} },
]; ];
module.exports.createCode = createCode; module.exports.createCode = createCode;

@ -1,5 +1,5 @@
const bn128 = require("snarkjs").bn128; const bn128 = require("@tornado/snarkjs").bn128;
const bigInt = require("snarkjs").bigInt; const bigInt = require("@tornado/snarkjs").bigInt;
const Web3Utils = require("web3-utils"); const Web3Utils = require("web3-utils");
const F = bn128.Fr; const F = bn128.Fr;
@ -8,7 +8,7 @@ const NROUNDS = 91;
exports.getIV = (seed) => { exports.getIV = (seed) => {
if (typeof seed === "undefined") seed = SEED; if (typeof seed === "undefined") seed = SEED;
const c = Web3Utils.keccak256(seed+"_iv"); const c = Web3Utils.keccak256(seed + "_iv");
const cn = bigInt(Web3Utils.toBN(c).toString()); const cn = bigInt(Web3Utils.toBN(c).toString());
const iv = cn.mod(F.q); const iv = cn.mod(F.q);
return iv; return iv;
@ -19,7 +19,7 @@ exports.getConstants = (seed, nRounds) => {
if (typeof nRounds === "undefined") nRounds = NROUNDS; if (typeof nRounds === "undefined") nRounds = NROUNDS;
const cts = new Array(nRounds); const cts = new Array(nRounds);
let c = Web3Utils.keccak256(SEED); let c = Web3Utils.keccak256(SEED);
for (let i=1; i<nRounds; i++) { for (let i = 1; i < nRounds; i++) {
c = Web3Utils.keccak256(c); c = Web3Utils.keccak256(c);
const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.q.toString())); const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.q.toString()));
@ -32,13 +32,13 @@ exports.getConstants = (seed, nRounds) => {
const cts = exports.getConstants(SEED, 91); const cts = exports.getConstants(SEED, 91);
exports.hash = (_x_in, _k) =>{ exports.hash = (_x_in, _k) => {
const x_in = bigInt(_x_in); const x_in = bigInt(_x_in);
const k = bigInt(_k); const k = bigInt(_k);
let r; let r;
for (let i=0; i<NROUNDS; i++) { for (let i = 0; i < NROUNDS; i++) {
const c = cts[i]; const c = cts[i];
const t = (i==0) ? F.add(x_in, k) : F.add(F.add(r, k), c); const t = i == 0 ? F.add(x_in, k) : F.add(F.add(r, k), c);
r = F.exp(t, 7); r = F.exp(t, 7);
} }
return F.affine(F.add(r, k)); return F.affine(F.add(r, k));
@ -46,19 +46,13 @@ exports.hash = (_x_in, _k) =>{
exports.multiHash = (arr, key) => { exports.multiHash = (arr, key) => {
let r; let r;
if (typeof(key) === "undefined") { if (typeof key === "undefined") {
r = F.zero; r = F.zero;
} else { } else {
r = key; r = key;
} }
for (let i=0; i<arr.length; i++) { for (let i = 0; i < arr.length; i++) {
r = F.add( r = F.add(F.add(r, arr[i]), exports.hash(bigInt(arr[i]), r));
F.add(
r,
arr[i]
),
exports.hash(bigInt(arr[i]), r)
);
} }
return F.affine(r); return F.affine(r);
}; };

@ -1,5 +1,5 @@
const bn128 = require("snarkjs").bn128; const bn128 = require("@tornado/snarkjs").bn128;
const bigInt = require("snarkjs").bigInt; const bigInt = require("@tornado/snarkjs").bigInt;
const Web3Utils = require("web3-utils"); const Web3Utils = require("web3-utils");
const F = bn128.Fr; const F = bn128.Fr;
@ -8,7 +8,7 @@ const NROUNDS = 220;
exports.getIV = (seed) => { exports.getIV = (seed) => {
if (typeof seed === "undefined") seed = SEED; if (typeof seed === "undefined") seed = SEED;
const c = Web3Utils.keccak256(seed+"_iv"); const c = Web3Utils.keccak256(seed + "_iv");
const cn = bigInt(Web3Utils.toBN(c).toString()); const cn = bigInt(Web3Utils.toBN(c).toString());
const iv = cn.mod(F.q); const iv = cn.mod(F.q);
return iv; return iv;
@ -19,7 +19,7 @@ exports.getConstants = (seed, nRounds) => {
if (typeof nRounds === "undefined") nRounds = NROUNDS; if (typeof nRounds === "undefined") nRounds = NROUNDS;
const cts = new Array(nRounds); const cts = new Array(nRounds);
let c = Web3Utils.keccak256(SEED); let c = Web3Utils.keccak256(SEED);
for (let i=1; i<nRounds; i++) { for (let i = 1; i < nRounds; i++) {
c = Web3Utils.keccak256(c); c = Web3Utils.keccak256(c);
const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.q.toString())); const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.q.toString()));
@ -33,15 +33,15 @@ exports.getConstants = (seed, nRounds) => {
const cts = exports.getConstants(SEED, NROUNDS); const cts = exports.getConstants(SEED, NROUNDS);
exports.hash = (_xL_in, _xR_in, _k) =>{ exports.hash = (_xL_in, _xR_in, _k) => {
let xL = bigInt(_xL_in); let xL = bigInt(_xL_in);
let xR = bigInt(_xR_in); let xR = bigInt(_xR_in);
const k = bigInt(_k); const k = bigInt(_k);
for (let i=0; i<NROUNDS; i++) { for (let i = 0; i < NROUNDS; i++) {
const c = cts[i]; const c = cts[i];
const t = (i==0) ? F.add(xL, k) : F.add(F.add(xL, k), c); const t = i == 0 ? F.add(xL, k) : F.add(F.add(xL, k), c);
const xR_tmp = bigInt(xR); const xR_tmp = bigInt(xR);
if (i < (NROUNDS - 1)) { if (i < NROUNDS - 1) {
xR = xL; xR = xL;
xL = F.add(xR_tmp, F.exp(t, 5)); xL = F.add(xR_tmp, F.exp(t, 5));
} else { } else {
@ -55,24 +55,24 @@ exports.hash = (_xL_in, _xR_in, _k) =>{
}; };
exports.multiHash = (arr, key, numOutputs) => { exports.multiHash = (arr, key, numOutputs) => {
if (typeof(numOutputs) === "undefined") { if (typeof numOutputs === "undefined") {
numOutputs = 1; numOutputs = 1;
} }
if (typeof(key) === "undefined") { if (typeof key === "undefined") {
key = F.zero; key = F.zero;
} }
let R = F.zero; let R = F.zero;
let C = F.zero; let C = F.zero;
for (let i=0; i<arr.length; i++) { for (let i = 0; i < arr.length; i++) {
R = F.add(R, bigInt(arr[i])); R = F.add(R, bigInt(arr[i]));
const S = exports.hash(R, C, key); const S = exports.hash(R, C, key);
R = S.xL; R = S.xL;
C = S.xR; C = S.xR;
} }
let outputs = [R]; let outputs = [R];
for (let i=1; i < numOutputs; i++) { for (let i = 1; i < numOutputs; i++) {
const S = exports.hash(R, C, key); const S = exports.hash(R, C, key);
R = S.xL; R = S.xL;
C = S.xR; C = S.xR;
@ -81,6 +81,6 @@ exports.multiHash = (arr, key, numOutputs) => {
if (numOutputs == 1) { if (numOutputs == 1) {
return F.affine(outputs[0]); return F.affine(outputs[0]);
} else { } else {
return outputs.map(x => F.affine(x)); return outputs.map((x) => F.affine(x));
} }
}; };

@ -1,5 +1,5 @@
const bn128 = require("snarkjs").bn128; const bn128 = require("@tornado/snarkjs").bn128;
const bigInt = require("snarkjs").bigInt; const bigInt = require("@tornado/snarkjs").bigInt;
const babyJub = require("./babyjub"); const babyJub = require("./babyjub");
const createBlakeHash = require("blake-hash"); const createBlakeHash = require("blake-hash");
@ -11,39 +11,39 @@ exports.hash = pedersenHash;
exports.getBasePoint = getBasePoint; exports.getBasePoint = getBasePoint;
function pedersenHash(msg) { function pedersenHash(msg) {
const bitsPerSegment = windowSize*nWindowsPerSegment; const bitsPerSegment = windowSize * nWindowsPerSegment;
const bits = buffer2bits(msg); const bits = buffer2bits(msg);
const nSegments = Math.floor((bits.length - 1)/(windowSize*nWindowsPerSegment)) +1; const nSegments = Math.floor((bits.length - 1) / (windowSize * nWindowsPerSegment)) + 1;
let accP = [bigInt.zero,bigInt.one]; let accP = [bigInt.zero, bigInt.one];
for (let s=0; s<nSegments; s++) { for (let s = 0; s < nSegments; s++) {
let nWindows; let nWindows;
if (s == nSegments-1) { if (s == nSegments - 1) {
nWindows = Math.floor(((bits.length - (nSegments - 1)*bitsPerSegment) - 1) / windowSize) +1; nWindows = Math.floor((bits.length - (nSegments - 1) * bitsPerSegment - 1) / windowSize) + 1;
} else { } else {
nWindows = nWindowsPerSegment; nWindows = nWindowsPerSegment;
} }
let escalar = bigInt.zero; let escalar = bigInt.zero;
let exp = bigInt.one; let exp = bigInt.one;
for (let w=0; w<nWindows; w++) { for (let w = 0; w < nWindows; w++) {
let o = s*bitsPerSegment + w*windowSize; let o = s * bitsPerSegment + w * windowSize;
let acc = bigInt.one; let acc = bigInt.one;
for (let b=0; ((b<windowSize-1)&&(o<bits.length)) ; b++) { for (let b = 0; b < windowSize - 1 && o < bits.length; b++) {
if (bits[o]) { if (bits[o]) {
acc = acc.add( bigInt.one.shl(b) ); acc = acc.add(bigInt.one.shl(b));
} }
o++; o++;
} }
if (o<bits.length) { if (o < bits.length) {
if (bits[o]) { if (bits[o]) {
acc = acc.neg(); acc = acc.neg();
} }
o++; o++;
} }
escalar = escalar.add(acc.mul(exp)); escalar = escalar.add(acc.mul(exp));
exp = exp.shl(windowSize+1); exp = exp.shl(windowSize + 1);
} }
if (escalar.lesser(bigInt.zero)) { if (escalar.lesser(bigInt.zero)) {
@ -59,13 +59,13 @@ function pedersenHash(msg) {
let bases = []; let bases = [];
function getBasePoint(pointIdx) { function getBasePoint(pointIdx) {
if (pointIdx<bases.length) return bases[pointIdx]; if (pointIdx < bases.length) return bases[pointIdx];
let p= null; let p = null;
let tryIdx = 0; let tryIdx = 0;
while (p==null) { while (p == null) {
const S = GENPOINT_PREFIX + "_" + padLeftZeros(pointIdx, 32) + "_" + padLeftZeros(tryIdx, 32); const S = GENPOINT_PREFIX + "_" + padLeftZeros(pointIdx, 32) + "_" + padLeftZeros(tryIdx, 32);
const h = createBlakeHash("blake256").update(S).digest(); const h = createBlakeHash("blake256").update(S).digest();
h[31] = h[31] & 0xBF; // Set 255th bit to 0 (256th is the signal and 254th is the last possible bit to 1) h[31] = h[31] & 0xbf; // Set 255th bit to 0 (256th is the signal and 254th is the last possible bit to 1)
p = babyJub.unpackPoint(h); p = babyJub.unpackPoint(h);
tryIdx++; tryIdx++;
} }
@ -82,7 +82,7 @@ function getBasePoint(pointIdx) {
function padLeftZeros(idx, n) { function padLeftZeros(idx, n) {
let sidx = "" + idx; let sidx = "" + idx;
while (sidx.length<n) sidx = "0"+sidx; while (sidx.length < n) sidx = "0" + sidx;
return sidx; return sidx;
} }
@ -91,21 +91,17 @@ Input a buffer
Returns an array of booleans. 0 is LSB of first byte and so on. Returns an array of booleans. 0 is LSB of first byte and so on.
*/ */
function buffer2bits(buff) { function buffer2bits(buff) {
const res = new Array(buff.length*8); const res = new Array(buff.length * 8);
for (let i=0; i<buff.length; i++) { for (let i = 0; i < buff.length; i++) {
const b = buff[i]; const b = buff[i];
res[i*8] = b & 0x01; res[i * 8] = b & 0x01;
res[i*8+1] = b & 0x02; res[i * 8 + 1] = b & 0x02;
res[i*8+2] = b & 0x04; res[i * 8 + 2] = b & 0x04;
res[i*8+3] = b & 0x08; res[i * 8 + 3] = b & 0x08;
res[i*8+4] = b & 0x10; res[i * 8 + 4] = b & 0x10;
res[i*8+5] = b & 0x20; res[i * 8 + 5] = b & 0x20;
res[i*8+6] = b & 0x40; res[i * 8 + 6] = b & 0x40;
res[i*8+7] = b & 0x80; res[i * 8 + 7] = b & 0x80;
} }
return res; return res;
} }

@ -1,8 +1,8 @@
const assert = require("assert"); const assert = require("assert");
const bn128 = require("snarkjs").bn128; const bn128 = require("@tornado/snarkjs").bn128;
const bigInt = require("snarkjs").bigInt; const bigInt = require("@tornado/snarkjs").bigInt;
const F = bn128.Fr; const F = bn128.Fr;
const { unstringifyBigInts } = require("snarkjs"); const { unstringifyBigInts } = require("@tornado/snarkjs");
// Prime 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 // Prime 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
// const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617")); // const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
@ -17,7 +17,7 @@ const { C, M } = unstringifyBigInts(require("./poseidon_constants.json"));
const N_ROUNDS_F = 8; const N_ROUNDS_F = 8;
const N_ROUNDS_P = 35; const N_ROUNDS_P = 35;
const pow5 = a => F.mul(a, F.square(F.square(a, a))); const pow5 = (a) => F.mul(a, F.square(F.square(a, a)));
function poseidon(inputs) { function poseidon(inputs) {
assert(inputs.length > 0); assert(inputs.length > 0);
@ -27,21 +27,19 @@ function poseidon(inputs) {
const nRoundsF = N_ROUNDS_F; const nRoundsF = N_ROUNDS_F;
const nRoundsP = N_ROUNDS_P; const nRoundsP = N_ROUNDS_P;
let state = [...inputs.map(a => bigInt(a)), F.zero]; let state = [...inputs.map((a) => bigInt(a)), F.zero];
for (let r = 0; r < nRoundsF + nRoundsP; r++) { for (let r = 0; r < nRoundsF + nRoundsP; r++) {
state = state.map((a, i) => F.add(a, bigInt(C[t - 2][r * t + i]))); state = state.map((a, i) => F.add(a, bigInt(C[t - 2][r * t + i])));
if (r < nRoundsF / 2 || r >= nRoundsF / 2 + nRoundsP) { if (r < nRoundsF / 2 || r >= nRoundsF / 2 + nRoundsP) {
state = state.map(a => pow5(a)); state = state.map((a) => pow5(a));
} else { } else {
state[0] = pow5(state[0]); state[0] = pow5(state[0]);
} }
// no matrix multiplication in the last round // no matrix multiplication in the last round
if (r < nRoundsF + nRoundsP - 1) { if (r < nRoundsF + nRoundsP - 1) {
state = state.map((_, i) => state = state.map((_, i) => state.reduce((acc, a, j) => F.add(acc, F.mul(bigInt(M[t - 2][j][i]), a)), F.zero));
state.reduce((acc, a, j) => F.add(acc, F.mul(bigInt(M[t - 2][j][i]), a)), F.zero)
);
} }
} }
return F.affine(state[0]); return F.affine(state[0]);

@ -3,10 +3,10 @@
// //
const Contract = require("./evmasm"); const Contract = require("./evmasm");
const { unstringifyBigInts } = require("snarkjs"); const { unstringifyBigInts } = require("@tornado/snarkjs");
const Web3Utils = require("web3-utils"); const Web3Utils = require("web3-utils");
const { C:K, M } = unstringifyBigInts(require("./poseidon_constants.json")); const { C: K, M } = unstringifyBigInts(require("./poseidon_constants.json"));
const N_ROUNDS_F = 8; const N_ROUNDS_F = 8;
const N_ROUNDS_P = 35; const N_ROUNDS_P = 35;
@ -16,13 +16,12 @@ function toHex256(a) {
return a; return a;
} }
let S = a.toString(16); let S = a.toString(16);
while (S.length < 64) S="0"+S; while (S.length < 64) S = "0" + S;
return "0x" + S; return "0x" + S;
} }
function createCode(nInputs) { function createCode(nInputs) {
if (nInputs < 1 || nInputs > 4) throw new Error("Invalid number of inputs. Must be 1<=nInputs<=8");
if (( nInputs<1) || (nInputs>4)) throw new Error("Invalid number of inputs. Must be 1<=nInputs<=8");
const t = nInputs + 1; const t = nInputs + 1;
const nRoundsF = N_ROUNDS_F; const nRoundsF = N_ROUNDS_F;
const nRoundsP = N_ROUNDS_P; const nRoundsP = N_ROUNDS_P;
@ -30,20 +29,21 @@ function createCode(nInputs) {
const C = new Contract(); const C = new Contract();
function saveM() { function saveM() {
for (let i=0; i<t; i++) { for (let i = 0; i < t; i++) {
for (let j=0; j<t; j++) { for (let j = 0; j < t; j++) {
C.push(toHex256(M[t-2][j][i])); C.push(toHex256(M[t - 2][j][i]));
C.push((1+i*t+j)*32); C.push((1 + i * t + j) * 32);
C.mstore(); C.mstore();
} }
} }
} }
function ark(r) { // st, q function ark(r) {
for (let i=0; i<t; i++) { // st, q
for (let i = 0; i < t; i++) {
C.dup(t); // q, st, q C.dup(t); // q, st, q
C.push(toHex256(K[t-2][r*t+i])); // K, q, st, q C.push(toHex256(K[t - 2][r * t + i])); // K, q, st, q
C.dup(2+i); // st[i], K, q, st, q C.dup(2 + i); // st[i], K, q, st, q
C.addmod(); // newSt[i], st, q C.addmod(); // newSt[i], st, q
C.swap(1 + i); // xx, st, q C.swap(1 + i); // xx, st, q
C.pop(); C.pop();
@ -53,7 +53,7 @@ function createCode(nInputs) {
function sigma(p) { function sigma(p) {
// sq, q // sq, q
C.dup(t); // q, st, q C.dup(t); // q, st, q
C.dup(1+p); // st[p] , q , st, q C.dup(1 + p); // st[p] , q , st, q
C.dup(1); // q, st[p] , q , st, q C.dup(1); // q, st[p] , q , st, q
C.dup(0); // q, q, st[p] , q , st, q C.dup(0); // q, q, st[p] , q , st, q
C.dup(2); // st[p] , q, q, st[p] , q , st, q C.dup(2); // st[p] , q, q, st[p] , q , st, q
@ -62,34 +62,34 @@ function createCode(nInputs) {
C.dup(0); // st2[p], st2[p], q, st[p] , q , st, q C.dup(0); // st2[p], st2[p], q, st[p] , q , st, q
C.mulmod(); // st4[p], st[p] , q , st, q C.mulmod(); // st4[p], st[p] , q , st, q
C.mulmod(); // st5[p], st, q C.mulmod(); // st5[p], st, q
C.swap(1+p); C.swap(1 + p);
C.pop(); // newst, q C.pop(); // newst, q
} }
function mix() { function mix() {
C.label("mix"); C.label("mix");
for (let i=0; i<t; i++) { for (let i = 0; i < t; i++) {
for (let j=0; j<t; j++) { for (let j = 0; j < t; j++) {
if (j==0) { if (j == 0) {
C.dup(i+t); // q, newSt, oldSt, q C.dup(i + t); // q, newSt, oldSt, q
C.push((1+i*t+j)*32); C.push((1 + i * t + j) * 32);
C.mload(); // M, q, newSt, oldSt, q C.mload(); // M, q, newSt, oldSt, q
C.dup(2+i+j); // oldSt[j], M, q, newSt, oldSt, q C.dup(2 + i + j); // oldSt[j], M, q, newSt, oldSt, q
C.mulmod(); // acc, newSt, oldSt, q C.mulmod(); // acc, newSt, oldSt, q
} else { } else {
C.dup(1+i+t); // q, acc, newSt, oldSt, q C.dup(1 + i + t); // q, acc, newSt, oldSt, q
C.push((1+i*t+j)*32); C.push((1 + i * t + j) * 32);
C.mload(); // M, q, acc, newSt, oldSt, q C.mload(); // M, q, acc, newSt, oldSt, q
C.dup(3+i+j); // oldSt[j], M, q, acc, newSt, oldSt, q C.dup(3 + i + j); // oldSt[j], M, q, acc, newSt, oldSt, q
C.mulmod(); // aux, acc, newSt, oldSt, q C.mulmod(); // aux, acc, newSt, oldSt, q
C.dup(2+i+t); // q, aux, acc, newSt, oldSt, q C.dup(2 + i + t); // q, aux, acc, newSt, oldSt, q
C.swap(2); // acc, aux, q, newSt, oldSt, q C.swap(2); // acc, aux, q, newSt, oldSt, q
C.addmod(); // acc, newSt, oldSt, q C.addmod(); // acc, newSt, oldSt, q
} }
} }
} }
for (let i=0; i<t; i++) { for (let i = 0; i < t; i++) {
C.swap((t -i) + (t -i-1)); C.swap(t - i + (t - i - 1));
C.pop(); C.pop();
} }
C.push(0); C.push(0);
@ -97,7 +97,6 @@ function createCode(nInputs) {
C.jmp(); C.jmp();
} }
// Check selector // Check selector
C.push("0x0100000000000000000000000000000000000000000000000000000000"); C.push("0x0100000000000000000000000000000000000000000000000000000000");
C.push(0); C.push(0);
@ -123,21 +122,21 @@ function createCode(nInputs) {
// The function has a single array param param // The function has a single array param param
// [Selector (4)] [item1 (32)] [item2 (32)] .... // [Selector (4)] [item1 (32)] [item2 (32)] ....
// Stack positions 0-nInputs. // Stack positions 0-nInputs.
for (let i=0; i<t; i++) { for (let i = 0; i < t; i++) {
C.push(0x04+(0x20*(nInputs-i))); C.push(0x04 + 0x20 * (nInputs - i));
C.calldataload(); C.calldataload();
} }
for (let i=0; i<nRoundsF+nRoundsP-1; i++) { for (let i = 0; i < nRoundsF + nRoundsP - 1; i++) {
ark(i); ark(i);
if ((i<nRoundsF/2) || (i>=nRoundsP+nRoundsF/2)) { if (i < nRoundsF / 2 || i >= nRoundsP + nRoundsF / 2) {
for (let j=0; j<t; j++) { for (let j = 0; j < t; j++) {
sigma(j); sigma(j);
} }
} else { } else {
sigma(0); sigma(0);
} }
const strLabel = "aferMix"+i; const strLabel = "aferMix" + i;
C._pushLabel(strLabel); C._pushLabel(strLabel);
C.push(0); C.push(0);
C.mstore(); C.mstore();
@ -145,8 +144,8 @@ function createCode(nInputs) {
C.label(strLabel); C.label(strLabel);
} }
C.push(toHex256(K[t-2][(nRoundsF+nRoundsP-1)*t])); // K, st, q C.push(toHex256(K[t - 2][(nRoundsF + nRoundsP - 1) * t])); // K, st, q
C.dup(t+1); // q, K, st, q C.dup(t + 1); // q, K, st, q
C.swap(2); // st[0], K, q, st\st[0] C.swap(2); // st[0], K, q, st\st[0]
C.addmod(); // st q C.addmod(); // st q
@ -166,51 +165,49 @@ function createCode(nInputs) {
function generateABI(nInputs) { function generateABI(nInputs) {
return [ return [
{ {
"constant": true, constant: true,
"inputs": [ inputs: [
{ {
"internalType": `bytes32[${nInputs}]`, internalType: `bytes32[${nInputs}]`,
"name": "input", name: "input",
"type": `bytes32[${nInputs}]` type: `bytes32[${nInputs}]`,
} },
], ],
"name": "poseidon", name: "poseidon",
"outputs": [ outputs: [
{ {
"internalType": "bytes32", internalType: "bytes32",
"name": "", name: "",
"type": "bytes32" type: "bytes32",
} },
], ],
"payable": false, payable: false,
"stateMutability": "pure", stateMutability: "pure",
"type": "function" type: "function",
}, },
{ {
"constant": true, constant: true,
"inputs": [ inputs: [
{ {
"internalType": `uint256[${nInputs}]`, internalType: `uint256[${nInputs}]`,
"name": "input", name: "input",
"type": `uint256[${nInputs}]` type: `uint256[${nInputs}]`,
} },
], ],
"name": "poseidon", name: "poseidon",
"outputs": [ outputs: [
{ {
"internalType": "uint256", internalType: "uint256",
"name": "", name: "",
"type": "uint256" type: "uint256",
} },
], ],
"payable": false, payable: false,
"stateMutability": "pure", stateMutability: "pure",
"type": "function" type: "function",
} },
]; ];
} }
module.exports.generateABI = generateABI; module.exports.generateABI = generateABI;
module.exports.createCode = createCode; module.exports.createCode = createCode;

@ -1,17 +1,15 @@
const bigInt = require("snarkjs").bigInt; const bigInt = require("@tornado/snarkjs").bigInt;
const SMTMemDB = require("./smt_memdb"); const SMTMemDB = require("./smt_memdb");
const {hash0, hash1} = require("./smt_hashes_poseidon"); const { hash0, hash1 } = require("./smt_hashes_poseidon");
class SMT { class SMT {
constructor(db, root) { constructor(db, root) {
this.db = db; this.db = db;
this.root = root; this.root = root;
} }
_splitBits(_key) { _splitBits(_key) {
let k = bigInt(_key); let k = bigInt(_key);
const res = []; const res = [];
@ -24,7 +22,7 @@ class SMT {
k = k.shr(1); k = k.shr(1);
} }
while (res.length<256) res.push(false); while (res.length < 256) res.push(false);
return res; return res;
} }
@ -33,7 +31,6 @@ class SMT {
const key = bigInt(_key); const key = bigInt(_key);
const newValue = bigInt(_newValue); const newValue = bigInt(_newValue);
const resFind = await this.find(key); const resFind = await this.find(key);
const res = {}; const res = {};
res.oldRoot = this.root; res.oldRoot = this.root;
@ -48,11 +45,11 @@ class SMT {
let rtOld = hash1(key, resFind.foundValue); let rtOld = hash1(key, resFind.foundValue);
let rtNew = hash1(key, newValue); let rtNew = hash1(key, newValue);
ins.push([rtNew, [1, key, newValue ]]); ins.push([rtNew, [1, key, newValue]]);
dels.push(rtOld); dels.push(rtOld);
const keyBits = this._splitBits(key); const keyBits = this._splitBits(key);
for (let level = resFind.siblings.length-1; level >=0; level--) { for (let level = resFind.siblings.length - 1; level >= 0; level--) {
let oldNode, newNode; let oldNode, newNode;
const sibling = resFind.siblings[level]; const sibling = resFind.siblings[level];
if (keyBits[level]) { if (keyBits[level]) {
@ -87,7 +84,7 @@ class SMT {
const res = { const res = {
siblings: [], siblings: [],
delKey: key, delKey: key,
delValue: resFind.foundValue delValue: resFind.foundValue,
}; };
const dels = []; const dels = [];
@ -99,7 +96,7 @@ class SMT {
let mixed; let mixed;
if (resFind.siblings.length > 0) { if (resFind.siblings.length > 0) {
const record = await this.db.get(resFind.siblings[resFind.siblings.length - 1]); const record = await this.db.get(resFind.siblings[resFind.siblings.length - 1]);
if ((record.length == 3)&&(record[0].equals(bigInt.one))) { if (record.length == 3 && record[0].equals(bigInt.one)) {
mixed = false; mixed = false;
res.oldKey = record[1]; res.oldKey = record[1];
res.oldValue = record[2]; res.oldValue = record[2];
@ -123,9 +120,9 @@ class SMT {
const keyBits = this._splitBits(key); const keyBits = this._splitBits(key);
for (let level = resFind.siblings.length-1; level >=0; level--) { for (let level = resFind.siblings.length - 1; level >= 0; level--) {
let newSibling = resFind.siblings[level]; let newSibling = resFind.siblings[level];
if ((level == resFind.siblings.length-1)&&(!res.isOld0)) { if (level == resFind.siblings.length - 1 && !res.isOld0) {
newSibling = bigInt.zero; newSibling = bigInt.zero;
} }
const oldSibling = resFind.siblings[level]; const oldSibling = resFind.siblings[level];
@ -182,14 +179,14 @@ class SMT {
if (!resFind.isOld0) { if (!resFind.isOld0) {
const oldKeyits = this._splitBits(resFind.notFoundKey); const oldKeyits = this._splitBits(resFind.notFoundKey);
for (let i= res.siblings.length; oldKeyits[i] == newKeyBits[i]; i++) { for (let i = res.siblings.length; oldKeyits[i] == newKeyBits[i]; i++) {
res.siblings.push(bigInt.zero); res.siblings.push(bigInt.zero);
} }
rtOld = hash1(resFind.notFoundKey, resFind.notFoundValue); rtOld = hash1(resFind.notFoundKey, resFind.notFoundValue);
res.siblings.push(rtOld); res.siblings.push(rtOld);
addedOne = true; addedOne = true;
mixed = false; mixed = false;
} else if (res.siblings.length >0) { } else if (res.siblings.length > 0) {
mixed = true; mixed = true;
rtOld = bigInt.zero; rtOld = bigInt.zero;
} }
@ -198,10 +195,10 @@ class SMT {
const dels = []; const dels = [];
let rt = hash1(key, value); let rt = hash1(key, value);
inserts.push([rt,[1, key, value]] ); inserts.push([rt, [1, key, value]]);
for (let i=res.siblings.length-1; i>=0; i--) { for (let i = res.siblings.length - 1; i >= 0; i--) {
if ((i<res.siblings.length-1)&&(!res.siblings[i].isZero())) { if (i < res.siblings.length - 1 && !res.siblings[i].isZero()) {
mixed = true; mixed = true;
} }
if (mixed) { if (mixed) {
@ -214,20 +211,19 @@ class SMT {
dels.push(rtOld); dels.push(rtOld);
} }
let newRt; let newRt;
if (newKeyBits[i]) { if (newKeyBits[i]) {
newRt = hash0(res.siblings[i], rt); newRt = hash0(res.siblings[i], rt);
inserts.push([newRt,[res.siblings[i], rt]] ); inserts.push([newRt, [res.siblings[i], rt]]);
} else { } else {
newRt = hash0(rt, res.siblings[i]); newRt = hash0(rt, res.siblings[i]);
inserts.push([newRt,[rt, res.siblings[i]]] ); inserts.push([newRt, [rt, res.siblings[i]]]);
} }
rt = newRt; rt = newRt;
} }
if (addedOne) res.siblings.pop(); if (addedOne) res.siblings.pop();
while ((res.siblings.length>0) && (res.siblings[res.siblings.length-1].isZero())) { while (res.siblings.length > 0 && res.siblings[res.siblings.length - 1].isZero()) {
res.siblings.pop(); res.siblings.pop();
} }
res.oldKey = resFind.notFoundKey; res.oldKey = resFind.notFoundKey;
@ -235,7 +231,6 @@ class SMT {
res.newRoot = rt; res.newRoot = rt;
res.isOld0 = resFind.isOld0; res.isOld0 = resFind.isOld0;
await this.db.multiIns(inserts); await this.db.multiIns(inserts);
await this.db.setRoot(rt); await this.db.setRoot(rt);
this.root = rt; this.root = rt;
@ -259,20 +254,20 @@ class SMT {
siblings: [], siblings: [],
notFoundKey: key, notFoundKey: key,
notFoundValue: bigInt.zero, notFoundValue: bigInt.zero,
isOld0: true isOld0: true,
}; };
return res; return res;
} }
const record = await this.db.get(root); const record = await this.db.get(root);
if ((record.length==3)&&(record[0].equals(bigInt.one))) { if (record.length == 3 && record[0].equals(bigInt.one)) {
if (record[1].equals(key)) { if (record[1].equals(key)) {
res = { res = {
found: true, found: true,
siblings: [], siblings: [],
foundValue: record[2], foundValue: record[2],
isOld0: false isOld0: false,
}; };
} else { } else {
res = { res = {
@ -280,15 +275,15 @@ class SMT {
siblings: [], siblings: [],
notFoundKey: record[1], notFoundKey: record[1],
notFoundValue: record[2], notFoundValue: record[2],
isOld0: false isOld0: false,
}; };
} }
} else { } else {
if (keyBits[level] == 0) { if (keyBits[level] == 0) {
res = await this._find(key, keyBits, record[0], level+1); res = await this._find(key, keyBits, record[0], level + 1);
res.siblings.unshift(record[1]); res.siblings.unshift(record[1]);
} else { } else {
res = await this._find(key, keyBits, record[1], level+1); res = await this._find(key, keyBits, record[1], level + 1);
res.siblings.unshift(record[0]); res.siblings.unshift(record[0]);
} }
} }
@ -296,9 +291,7 @@ class SMT {
} }
} }
async function loadFromFile(fileName) { async function loadFromFile(fileName) {}
}
async function newMemEmptyTrie() { async function newMemEmptyTrie() {
const db = new SMTMemDB(); const db = new SMTMemDB();

@ -1,10 +1,10 @@
const mimc7 = require("./mimc7"); const mimc7 = require("./mimc7");
const bigInt = require("snarkjs").bigInt; const bigInt = require("@tornado/snarkjs").bigInt;
exports.hash0 = function (left, right) { exports.hash0 = function (left, right) {
return mimc7.multiHash(left, right); return mimc7.multiHash(left, right);
}; };
exports.hash1 = function(key, value) { exports.hash1 = function (key, value) {
return mimc7.multiHash([key, value], bigInt.one); return mimc7.multiHash([key, value], bigInt.one);
}; };

@ -1,10 +1,10 @@
const poseidon = require("./poseidon"); const poseidon = require("./poseidon");
const bigInt = require("snarkjs").bigInt; const bigInt = require("@tornado/snarkjs").bigInt;
exports.hash0 = function (left, right) { exports.hash0 = function (left, right) {
return poseidon([left, right]); return poseidon([left, right]);
}; };
exports.hash1 = function(key, value) { exports.hash1 = function (key, value) {
return poseidon([key, value, bigInt.one]); return poseidon([key, value, bigInt.one]);
}; };

@ -1,4 +1,4 @@
const bigInt = require("snarkjs").bigInt; const bigInt = require("@tornado/snarkjs").bigInt;
class SMTMemDb { class SMTMemDb {
constructor() { constructor() {
@ -17,7 +17,7 @@ class SMTMemDb {
} }
_normalize(n) { _normalize(n) {
for (let i=0; i<n.length; i++) { for (let i = 0; i < n.length; i++) {
n[i] = bigInt(n[i]); n[i] = bigInt(n[i]);
} }
} }
@ -29,7 +29,7 @@ class SMTMemDb {
async multiGet(keys) { async multiGet(keys) {
const promises = []; const promises = [];
for (let i=0; i<keys.length; i++) { for (let i = 0; i < keys.length; i++) {
promises.push(this.get(keys[i])); promises.push(this.get(keys[i]));
} }
return await Promise.all(promises); return await Promise.all(promises);
@ -40,7 +40,7 @@ class SMTMemDb {
} }
async multiIns(inserts) { async multiIns(inserts) {
for (let i=0; i<inserts.length; i++) { for (let i = 0; i < inserts.length; i++) {
const keyS = this._key2str(inserts[i][0]); const keyS = this._key2str(inserts[i][0]);
this._normalize(inserts[i][1]); this._normalize(inserts[i][1]);
this.nodes[keyS] = inserts[i][1]; this.nodes[keyS] = inserts[i][1];
@ -48,7 +48,7 @@ class SMTMemDb {
} }
async multiDel(dels) { async multiDel(dels) {
for (let i=0; i<dels.length; i++) { for (let i = 0; i < dels.length; i++) {
const keyS = this._key2str(dels[i]); const keyS = this._key2str(dels[i]);
delete this.nodes[keyS]; delete this.nodes[keyS];
} }

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const assert = chai.assert; const assert = chai.assert;
@ -13,7 +13,7 @@ function print(circuit, w, s) {
function getBits(v, n) { function getBits(v, n) {
const res = []; const res = [];
for (let i=0; i<n; i++) { for (let i = 0; i < n; i++) {
if (v.shr(i).isOdd()) { if (v.shr(i).isOdd()) {
res.push(bigInt.one); res.push(bigInt.one);
} else { } else {
@ -27,7 +27,7 @@ const q = bigInt("21888242871839275222246405745257275088548364400416034343698204
describe("Aliascheck test", () => { describe("Aliascheck test", () => {
let circuit; let circuit;
before( async() => { before(async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "aliascheck_test.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "aliascheck_test.circom"));
circuit = new snarkjs.Circuit(cirDef); circuit = new snarkjs.Circuit(cirDef);
@ -37,40 +37,38 @@ describe("Aliascheck test", () => {
it("Satisfy the aliastest 0", async () => { it("Satisfy the aliastest 0", async () => {
const inp = getBits(bigInt.zero, 254); const inp = getBits(bigInt.zero, 254);
circuit.calculateWitness({in: inp}); circuit.calculateWitness({ in: inp });
}); });
it("Satisfy the aliastest 3", async () => { it("Satisfy the aliastest 3", async () => {
const inp = getBits(bigInt(3), 254); const inp = getBits(bigInt(3), 254);
circuit.calculateWitness({in: inp}); circuit.calculateWitness({ in: inp });
}); });
it("Satisfy the aliastest q-1", async () => { it("Satisfy the aliastest q-1", async () => {
const inp = getBits(q.sub(bigInt.one), 254); const inp = getBits(q.sub(bigInt.one), 254);
circuit.calculateWitness({in: inp}); circuit.calculateWitness({ in: inp });
}); });
it("Nhot not satisfy an input of q", async () => { it("Nhot not satisfy an input of q", async () => {
const inp = getBits(q, 254); const inp = getBits(q, 254);
try { try {
circuit.calculateWitness({in: inp}); circuit.calculateWitness({ in: inp });
assert(false); assert(false);
} catch(err) { } catch (err) {
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) ); assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message));
assert(err.message.indexOf("1 != 0") >= 0); assert(err.message.indexOf("1 != 0") >= 0);
} }
}); });
it("Nhot not satisfy all ones", async () => { it("Nhot not satisfy all ones", async () => {
const inp = getBits(bigInt(1).shl(254).sub(bigInt(1)), 254); const inp = getBits(bigInt(1).shl(254).sub(bigInt(1)), 254);
try { try {
circuit.calculateWitness({in: inp}); circuit.calculateWitness({ in: inp });
assert(false); assert(false);
} catch(err) { } catch (err) {
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) ); assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message));
assert(err.message.indexOf("1 != 0") >= 0); assert(err.message.indexOf("1 != 0") >= 0);
} }
}); });
}); });

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const assert = chai.assert; const assert = chai.assert;
@ -13,7 +13,7 @@ function print(circuit, w, s) {
function getBits(v, n) { function getBits(v, n) {
const res = []; const res = [];
for (let i=0; i<n; i++) { for (let i = 0; i < n; i++) {
if (v.shr(i).isOdd()) { if (v.shr(i).isOdd()) {
res.push(bigInt.one); res.push(bigInt.one);
} else { } else {
@ -27,7 +27,7 @@ const r = bigInt("27360303589799094027808007181571593860768139721585672592002156
describe("Aliascheck test", () => { describe("Aliascheck test", () => {
let circuit; let circuit;
before( async() => { before(async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "aliascheckbabyjub_test.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "aliascheckbabyjub_test.circom"));
circuit = new snarkjs.Circuit(cirDef); circuit = new snarkjs.Circuit(cirDef);
@ -37,25 +37,25 @@ describe("Aliascheck test", () => {
it("Satisfy the aliastest 0", async () => { it("Satisfy the aliastest 0", async () => {
const inp = getBits(bigInt.zero, 251); const inp = getBits(bigInt.zero, 251);
circuit.calculateWitness({in: inp}); circuit.calculateWitness({ in: inp });
}); });
it("Satisfy the aliastest 3", async () => { it("Satisfy the aliastest 3", async () => {
const inp = getBits(bigInt(3), 251); const inp = getBits(bigInt(3), 251);
circuit.calculateWitness({in: inp}); circuit.calculateWitness({ in: inp });
}); });
it("Satisfy the aliastest r-1", async () => { it("Satisfy the aliastest r-1", async () => {
const inp = getBits(r.sub(bigInt.one), 251); const inp = getBits(r.sub(bigInt.one), 251);
circuit.calculateWitness({in: inp}); circuit.calculateWitness({ in: inp });
}); });
it("Nhot not satisfy an input of r", async () => { it("Nhot not satisfy an input of r", async () => {
const inp = getBits(r, 251); const inp = getBits(r, 251);
try { try {
circuit.calculateWitness({in: inp}); circuit.calculateWitness({ in: inp });
assert(false); assert(false);
} catch(err) { } catch (err) {
assert(err.message.indexOf("Constraint doesn't match") >= 0); assert(err.message.indexOf("Constraint doesn't match") >= 0);
assert(err.message.indexOf("1 != 0") >= 0); assert(err.message.indexOf("1 != 0") >= 0);
} }
@ -64,12 +64,11 @@ describe("Aliascheck test", () => {
it("Nhot not satisfy all ones", async () => { it("Nhot not satisfy all ones", async () => {
const inp = getBits(bigInt(1).shl(251).sub(bigInt(1)), 251); const inp = getBits(bigInt(1).shl(251).sub(bigInt(1)), 251);
try { try {
circuit.calculateWitness({in: inp}); circuit.calculateWitness({ in: inp });
assert(false); assert(false);
} catch(err) { } catch (err) {
assert(err.message.indexOf("Constraint doesn't match") >= 0); assert(err.message.indexOf("Constraint doesn't match") >= 0);
assert(err.message.indexOf("1 != 0") >= 0); assert(err.message.indexOf("1 != 0") >= 0);
} }
}); });
}); });

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const createBlakeHash = require("blake-hash"); const createBlakeHash = require("blake-hash");
@ -8,7 +8,7 @@ const eddsa = require("../src/eddsa.js");
const assert = chai.assert; const assert = chai.assert;
const bigInt = require("snarkjs").bigInt; const bigInt = require("@tornado/snarkjs").bigInt;
describe("Baby Jub test", function () { describe("Baby Jub test", function () {
let circuitAdd; let circuitAdd;
@ -16,7 +16,7 @@ describe("Baby Jub test", function () {
this.timeout(100000); this.timeout(100000);
before( async() => { before(async () => {
const cirDefAdd = await compiler(path.join(__dirname, "circuits", "babyadd_tester.circom")); const cirDefAdd = await compiler(path.join(__dirname, "circuits", "babyadd_tester.circom"));
circuitAdd = new snarkjs.Circuit(cirDefAdd); circuitAdd = new snarkjs.Circuit(cirDefAdd);
console.log("NConstrains BabyAdd: " + circuitAdd.nConstraints); console.log("NConstrains BabyAdd: " + circuitAdd.nConstraints);
@ -28,16 +28,14 @@ describe("Baby Jub test", function () {
const cirDefPbk = await compiler(path.join(__dirname, "circuits", "babypbk_test.circom")); const cirDefPbk = await compiler(path.join(__dirname, "circuits", "babypbk_test.circom"));
circuitPbk = new snarkjs.Circuit(cirDefPbk); circuitPbk = new snarkjs.Circuit(cirDefPbk);
console.log("NConstrains BabyPbk: " + circuitPbk.nConstraints); console.log("NConstrains BabyPbk: " + circuitPbk.nConstraints);
}); });
it("Should add point (0,1) and (0,1)", async () => { it("Should add point (0,1) and (0,1)", async () => {
const input = {
const input={
x1: snarkjs.bigInt(0), x1: snarkjs.bigInt(0),
y1: snarkjs.bigInt(1), y1: snarkjs.bigInt(1),
x2: snarkjs.bigInt(0), x2: snarkjs.bigInt(0),
y2: snarkjs.bigInt(1) y2: snarkjs.bigInt(1),
}; };
const w = circuitAdd.calculateWitness(input); const w = circuitAdd.calculateWitness(input);
@ -50,12 +48,11 @@ describe("Baby Jub test", function () {
}); });
it("Should add 2 same numbers", async () => { it("Should add 2 same numbers", async () => {
const input = {
const input={
x1: snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"), x1: snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
y1: snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"), y1: snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
x2: snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"), x2: snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
y2: snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475") y2: snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
}; };
const w = circuitAdd.calculateWitness(input); const w = circuitAdd.calculateWitness(input);
@ -68,12 +65,11 @@ describe("Baby Jub test", function () {
}); });
it("Should add 2 different numbers", async () => { it("Should add 2 different numbers", async () => {
const input = {
const input={
x1: snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"), x1: snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
y1: snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"), y1: snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
x2: snarkjs.bigInt("16540640123574156134436876038791482806971768689494387082833631921987005038935"), x2: snarkjs.bigInt("16540640123574156134436876038791482806971768689494387082833631921987005038935"),
y2: snarkjs.bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311") y2: snarkjs.bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311"),
}; };
const w = circuitAdd.calculateWitness(input); const w = circuitAdd.calculateWitness(input);
@ -90,37 +86,35 @@ describe("Baby Jub test", function () {
assert(yout.equals(snarkjs.bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499"))); assert(yout.equals(snarkjs.bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499")));
}); });
it("Should check 0 is a valid poiny", async() => { it("Should check 0 is a valid poiny", async () => {
const w = circuitTest.calculateWitness({x: 0, y:1}); const w = circuitTest.calculateWitness({ x: 0, y: 1 });
assert(circuitTest.checkWitness(w)); assert(circuitTest.checkWitness(w));
}); });
it("Should check 0 is an invalid poiny", async() => { it("Should check 0 is an invalid poiny", async () => {
try { try {
circuitTest.calculateWitness({x: 1, y: 0}); circuitTest.calculateWitness({ x: 1, y: 0 });
assert(false, "Should be a valid point"); assert(false, "Should be a valid point");
} catch(err) { } catch (err) {
assert(/Constraint\sdoesn't\smatch(.*)168700\s!=\s1/.test(err.message) ); assert(/Constraint\sdoesn't\smatch(.*)168700\s!=\s1/.test(err.message));
assert(err.message.indexOf("168700 != 1") >= 0); assert(err.message.indexOf("168700 != 1") >= 0);
} }
}); });
it("Should extract the public key from the private one", async () => { it("Should extract the public key from the private one", async () => {
const rawpvk = Buffer.from("0001020304050607080900010203040506070809000102030405060708090021", "hex"); const rawpvk = Buffer.from("0001020304050607080900010203040506070809000102030405060708090021", "hex");
const pvk = eddsa.pruneBuffer(createBlakeHash("blake512").update(rawpvk).digest().slice(0,32)); const pvk = eddsa.pruneBuffer(createBlakeHash("blake512").update(rawpvk).digest().slice(0, 32));
const S = bigInt.leBuff2int(pvk).shr(3); const S = bigInt.leBuff2int(pvk).shr(3);
const A = eddsa.prv2pub(rawpvk); const A = eddsa.prv2pub(rawpvk);
const input = { const input = {
in : S, in: S,
Ax : A[0], Ax: A[0],
Ay : A[1] Ay: A[1],
} };
const w = circuitPbk.calculateWitness(input); const w = circuitPbk.calculateWitness(input);
assert(circuitPbk.checkWitness(w)); assert(circuitPbk.checkWitness(w));
}); });
}); });

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const babyjub = require("../src/babyjub.js"); const babyjub = require("../src/babyjub.js");
@ -8,22 +8,14 @@ const assert = chai.assert;
// const bigInt = require("big-integer"); // const bigInt = require("big-integer");
describe("Baby Jub js test", function () { describe("Baby Jub js test", function () {
this.timeout(100000); this.timeout(100000);
it("Should add point (0,1) and (0,1)", () => { it("Should add point (0,1) and (0,1)", () => {
const p1 = [snarkjs.bigInt(0), snarkjs.bigInt(1)];
const p2 = [snarkjs.bigInt(0), snarkjs.bigInt(1)];
const p1 = [ const out = babyjub.addPoint(p1, p2);
snarkjs.bigInt(0),
snarkjs.bigInt(1)];
const p2 = [
snarkjs.bigInt(0),
snarkjs.bigInt(1)
];
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));
}); });
@ -39,7 +31,6 @@ 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"), snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"), snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
@ -49,13 +40,12 @@ describe("Baby Jub js test", function () {
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"), snarkjs.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(snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365")));
assert(out[1].equals(snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"))); assert(out[1].equals(snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889")));
}); });
it("Should add 2 different numbers", () => { it("Should add 2 different numbers", () => {
const p1 = [ const p1 = [
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"), snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"), snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
@ -65,7 +55,7 @@ describe("Baby Jub js test", function () {
snarkjs.bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311"), snarkjs.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(snarkjs.bigInt("7916061937171219682591368294088513039687205273691143098332585753343424131937")));
assert(out[1].equals(snarkjs.bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499"))); assert(out[1].equals(snarkjs.bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499")));
@ -92,7 +82,10 @@ describe("Baby Jub js test", function () {
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"), snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
]; ];
const r = babyjub.mulPointEscalar(p, snarkjs.bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499")); const r = babyjub.mulPointEscalar(
p,
snarkjs.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");
}); });
@ -103,7 +96,10 @@ describe("Baby Jub js test", function () {
snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"), snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
]; ];
const r = babyjub.mulPointEscalar(p, snarkjs.bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311")); const r = babyjub.mulPointEscalar(
p,
snarkjs.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");
}); });
@ -146,7 +142,7 @@ describe("Baby Jub js test", function () {
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"), snarkjs.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");
@ -158,7 +154,7 @@ describe("Baby Jub js test", function () {
snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"), snarkjs.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");

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const assert = chai.assert; const assert = chai.assert;
@ -11,21 +11,21 @@ function print(circuit, w, s) {
console.log(s + ": " + w[circuit.getSignalIdx(s)]); console.log(s + ": " + w[circuit.getSignalIdx(s)]);
} }
function checkSub(_a,_b, circuit) { function checkSub(_a, _b, circuit) {
let a=bigInt(_a); let a = bigInt(_a);
let b=bigInt(_b); let b = bigInt(_b);
if (a.lesser(bigInt.zero)) a = a.add(bigInt.one.shl(16)); if (a.lesser(bigInt.zero)) a = a.add(bigInt.one.shl(16));
if (b.lesser(bigInt.zero)) b = b.add(bigInt.one.shl(16)); if (b.lesser(bigInt.zero)) b = b.add(bigInt.one.shl(16));
const w = circuit.calculateWitness({a: a, b: b}); const w = circuit.calculateWitness({ a: a, b: b });
let res = a.sub(b); let res = a.sub(b);
if (res.lesser(bigInt.zero)) res = res.add(bigInt.one.shl(16)); if (res.lesser(bigInt.zero)) res = res.add(bigInt.one.shl(16));
assert( w[circuit.getSignalIdx("main.out")].equals(bigInt(res)) ); assert(w[circuit.getSignalIdx("main.out")].equals(bigInt(res)));
} }
describe("BinSub test", () => { describe("BinSub test", () => {
let circuit; let circuit;
before( async() => { before(async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "binsub_test.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "binsub_test.circom"));
circuit = new snarkjs.Circuit(cirDef); circuit = new snarkjs.Circuit(cirDef);
@ -34,23 +34,21 @@ describe("BinSub test", () => {
}); });
it("Should check variuos ege cases", async () => { it("Should check variuos ege cases", async () => {
checkSub(0,0, circuit); checkSub(0, 0, circuit);
checkSub(1,0, circuit); checkSub(1, 0, circuit);
checkSub(-1,0, circuit); checkSub(-1, 0, circuit);
checkSub(2,1, circuit); checkSub(2, 1, circuit);
checkSub(2,2, circuit); checkSub(2, 2, circuit);
checkSub(2,3, circuit); checkSub(2, 3, circuit);
checkSub(2,-1, circuit); checkSub(2, -1, circuit);
checkSub(2,-2, circuit); checkSub(2, -2, circuit);
checkSub(2,-3, circuit); checkSub(2, -3, circuit);
checkSub(-2,-3, circuit); checkSub(-2, -3, circuit);
checkSub(-2,-2, circuit); checkSub(-2, -2, circuit);
checkSub(-2,-1, circuit); checkSub(-2, -1, circuit);
checkSub(-2,0, circuit); checkSub(-2, 0, circuit);
checkSub(-2,1, circuit); checkSub(-2, 1, circuit);
checkSub(-2,2, circuit); checkSub(-2, 2, circuit);
checkSub(-2,3, circuit); checkSub(-2, 3, circuit);
}); });
}); });

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const crypto = require("crypto"); const crypto = require("crypto");
const compiler = require("circom"); const compiler = require("circom");
@ -9,25 +9,23 @@ const assert = chai.assert;
describe("Sum test", () => { describe("Sum test", () => {
it("Should create a constant circuit", async () => { it("Should create a constant circuit", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "constants_test.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "constants_test.circom"));
assert.equal(cirDef.nVars, 2); assert.equal(cirDef.nVars, 2);
const circuit = new snarkjs.Circuit(cirDef); const circuit = new snarkjs.Circuit(cirDef);
const witness = circuit.calculateWitness({ "in": "0xd807aa98" }); const witness = circuit.calculateWitness({ in: "0xd807aa98" });
assert(witness[0].equals(snarkjs.bigInt(1))); assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt("0xd807aa98"))); assert(witness[1].equals(snarkjs.bigInt("0xd807aa98")));
}); });
it("Should create a sum circuit", async () => { it("Should create a sum circuit", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "sum_test.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "sum_test.circom"));
assert.equal(cirDef.nVars, 97); // 32 (in1) + 32(in2) + 32(out) + 1 (carry) assert.equal(cirDef.nVars, 97); // 32 (in1) + 32(in2) + 32(out) + 1 (carry)
const circuit = new snarkjs.Circuit(cirDef); const circuit = new snarkjs.Circuit(cirDef);
const witness = circuit.calculateWitness({ "a": "111", "b": "222" }); const witness = circuit.calculateWitness({ a: "111", b: "222" });
assert(witness[0].equals(snarkjs.bigInt(1))); assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt("333"))); assert(witness[1].equals(snarkjs.bigInt("333")));

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const crypto = require("crypto"); const crypto = require("crypto");
const compiler = require("circom"); const compiler = require("circom");
@ -8,21 +8,21 @@ const compiler = require("circom");
const assert = chai.assert; const assert = chai.assert;
describe("Sum test", () => { describe("Sum test", () => {
it("Should create a iszero circuit", async() => { it("Should create a iszero circuit", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "iszero.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "iszero.circom"));
const circuit = new snarkjs.Circuit(cirDef); const circuit = new snarkjs.Circuit(cirDef);
let witness; let witness;
witness = circuit.calculateWitness({ "in": 111}); witness = circuit.calculateWitness({ in: 111 });
assert(witness[0].equals(snarkjs.bigInt(1))); assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0))); assert(witness[1].equals(snarkjs.bigInt(0)));
witness = circuit.calculateWitness({ "in": 0 }); witness = circuit.calculateWitness({ in: 0 });
assert(witness[0].equals(snarkjs.bigInt(1))); assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1))); assert(witness[1].equals(snarkjs.bigInt(1)));
}); });
it("Should create a isequal circuit", async() => { it("Should create a isequal circuit", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "isequal.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "isequal.circom"));
const circuit = new snarkjs.Circuit(cirDef); const circuit = new snarkjs.Circuit(cirDef);
@ -36,7 +36,7 @@ describe("Sum test", () => {
assert(witness[0].equals(snarkjs.bigInt(1))); assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1))); assert(witness[1].equals(snarkjs.bigInt(1)));
}); });
it("Should create a comparison lessthan", async() => { it("Should create a comparison lessthan", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "lessthan.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "lessthan.circom"));
const circuit = new snarkjs.Circuit(cirDef); const circuit = new snarkjs.Circuit(cirDef);
@ -74,7 +74,7 @@ describe("Sum test", () => {
assert(witness[0].equals(snarkjs.bigInt(1))); assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0))); assert(witness[1].equals(snarkjs.bigInt(0)));
}); });
it("Should create a comparison lesseqthan", async() => { it("Should create a comparison lesseqthan", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "lesseqthan.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "lesseqthan.circom"));
const circuit = new snarkjs.Circuit(cirDef); const circuit = new snarkjs.Circuit(cirDef);
@ -112,7 +112,7 @@ describe("Sum test", () => {
assert(witness[0].equals(snarkjs.bigInt(1))); assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1))); assert(witness[1].equals(snarkjs.bigInt(1)));
}); });
it("Should create a comparison greaterthan", async() => { it("Should create a comparison greaterthan", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "greaterthan.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "greaterthan.circom"));
const circuit = new snarkjs.Circuit(cirDef); const circuit = new snarkjs.Circuit(cirDef);
@ -150,7 +150,7 @@ describe("Sum test", () => {
assert(witness[0].equals(snarkjs.bigInt(1))); assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0))); assert(witness[1].equals(snarkjs.bigInt(0)));
}); });
it("Should create a comparison greatereqthan", async() => { it("Should create a comparison greatereqthan", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "greatereqthan.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "greatereqthan.circom"));
const circuit = new snarkjs.Circuit(cirDef); const circuit = new snarkjs.Circuit(cirDef);

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
// const crypto = require("crypto"); // const crypto = require("crypto");
@ -17,9 +17,9 @@ function print(circuit, w, s) {
function buffer2bits(buff) { function buffer2bits(buff) {
const res = []; const res = [];
for (let i=0; i<buff.length; i++) { for (let i = 0; i < buff.length; i++) {
for (let j=0; j<8; j++) { for (let j = 0; j < 8; j++) {
if ((buff[i]>>j)&1) { if ((buff[i] >> j) & 1) {
res.push(bigInt.one); res.push(bigInt.one);
} else { } else {
res.push(bigInt.zero); res.push(bigInt.zero);
@ -29,13 +29,12 @@ function buffer2bits(buff) {
return res; return res;
} }
describe("EdDSA test", function () { describe("EdDSA test", function () {
let circuit; let circuit;
this.timeout(100000); this.timeout(100000);
before( async () => { before(async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "eddsa_test.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "eddsa_test.circom"));
circuit = new snarkjs.Circuit(cirDef); circuit = new snarkjs.Circuit(cirDef);
@ -46,7 +45,7 @@ describe("EdDSA test", function () {
it("Sign a single 10 bytes from 0 to 9", async () => { it("Sign a single 10 bytes from 0 to 9", async () => {
const msg = Buffer.from("00010203040506070809", "hex"); const msg = Buffer.from("00010203040506070809", "hex");
// const prvKey = crypto.randomBytes(32); // const prvKey = crypto.randomBytes(32);
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
@ -66,9 +65,8 @@ describe("EdDSA test", function () {
const sBits = buffer2bits(pSignature.slice(32, 64)); const sBits = buffer2bits(pSignature.slice(32, 64));
const aBits = buffer2bits(pPubKey); const aBits = buffer2bits(pPubKey);
const w = circuit.calculateWitness({A: aBits, R8: r8Bits, S: sBits, msg: msgBits}); const w = circuit.calculateWitness({ A: aBits, R8: r8Bits, S: sBits, msg: msgBits });
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
}); });
}); });

@ -1,5 +1,5 @@
const chai = require("chai"); const chai = require("chai");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const eddsa = require("../src/eddsa.js"); const eddsa = require("../src/eddsa.js");
const babyJub = require("../src/babyjub.js"); const babyJub = require("../src/babyjub.js");
@ -9,7 +9,6 @@ const assert = chai.assert;
const bigInt = snarkjs.bigInt; const bigInt = snarkjs.bigInt;
describe("EdDSA js test", function () { describe("EdDSA js test", function () {
this.timeout(100000); this.timeout(100000);
it("Sign (using Mimc7) a single 10 bytes from 0 to 9", () => { it("Sign (using Mimc7) a single 10 bytes from 0 to 9", () => {
@ -22,29 +21,26 @@ describe("EdDSA js test", function () {
const pubKey = eddsa.prv2pub(prvKey); const pubKey = eddsa.prv2pub(prvKey);
assert.equal(pubKey[0].toString(), assert.equal(pubKey[0].toString(), "13277427435165878497778222415993513565335242147425444199013288855685581939618");
"13277427435165878497778222415993513565335242147425444199013288855685581939618"); assert.equal(pubKey[1].toString(), "13622229784656158136036771217484571176836296686641868549125388198837476602820");
assert.equal(pubKey[1].toString(),
"13622229784656158136036771217484571176836296686641868549125388198837476602820");
const pPubKey = babyJub.packPoint(pubKey); const pPubKey = babyJub.packPoint(pubKey);
const signature = eddsa.signMiMC(prvKey, msg); const signature = eddsa.signMiMC(prvKey, msg);
assert.equal(signature.R8[0].toString(), assert.equal(signature.R8[0].toString(), "11384336176656855268977457483345535180380036354188103142384839473266348197733");
"11384336176656855268977457483345535180380036354188103142384839473266348197733"); assert.equal(signature.R8[1].toString(), "15383486972088797283337779941324724402501462225528836549661220478783371668959");
assert.equal(signature.R8[1].toString(), assert.equal(signature.S.toString(), "2523202440825208709475937830811065542425109372212752003460238913256192595070");
"15383486972088797283337779941324724402501462225528836549661220478783371668959");
assert.equal(signature.S.toString(),
"2523202440825208709475937830811065542425109372212752003460238913256192595070");
const pSignature = eddsa.packSignature(signature); const pSignature = eddsa.packSignature(signature);
assert.equal(pSignature.toString("hex"), ""+ assert.equal(
"dfedb4315d3f2eb4de2d3c510d7a987dcab67089c8ace06308827bf5bcbe02a2"+ pSignature.toString("hex"),
"7ed40dab29bf993c928e789d007387998901a24913d44fddb64b1f21fc149405"); "" +
"dfedb4315d3f2eb4de2d3c510d7a987dcab67089c8ace06308827bf5bcbe02a2" +
"7ed40dab29bf993c928e789d007387998901a24913d44fddb64b1f21fc149405"
);
const uSignature = eddsa.unpackSignature(pSignature); const uSignature = eddsa.unpackSignature(pSignature);
assert(eddsa.verifyMiMC(msg, uSignature, pubKey)); assert(eddsa.verifyMiMC(msg, uSignature, pubKey));
}); });
it("Sign (using Poseidon) a single 10 bytes from 0 to 9", () => { it("Sign (using Poseidon) a single 10 bytes from 0 to 9", () => {
@ -55,28 +51,25 @@ describe("EdDSA js test", function () {
const pubKey = eddsa.prv2pub(prvKey); const pubKey = eddsa.prv2pub(prvKey);
assert.equal(pubKey[0].toString(), assert.equal(pubKey[0].toString(), "13277427435165878497778222415993513565335242147425444199013288855685581939618");
"13277427435165878497778222415993513565335242147425444199013288855685581939618"); assert.equal(pubKey[1].toString(), "13622229784656158136036771217484571176836296686641868549125388198837476602820");
assert.equal(pubKey[1].toString(),
"13622229784656158136036771217484571176836296686641868549125388198837476602820");
const pPubKey = babyJub.packPoint(pubKey); const pPubKey = babyJub.packPoint(pubKey);
const signature = eddsa.signPoseidon(prvKey, msg); const signature = eddsa.signPoseidon(prvKey, msg);
assert.equal(signature.R8[0].toString(), assert.equal(signature.R8[0].toString(), "11384336176656855268977457483345535180380036354188103142384839473266348197733");
"11384336176656855268977457483345535180380036354188103142384839473266348197733"); assert.equal(signature.R8[1].toString(), "15383486972088797283337779941324724402501462225528836549661220478783371668959");
assert.equal(signature.R8[1].toString(), assert.equal(signature.S.toString(), "1398758333392199195742243841591064350253744445503462896781493968760929513778");
"15383486972088797283337779941324724402501462225528836549661220478783371668959");
assert.equal(signature.S.toString(),
"1398758333392199195742243841591064350253744445503462896781493968760929513778");
const pSignature = eddsa.packSignature(signature); const pSignature = eddsa.packSignature(signature);
assert.equal(pSignature.toString("hex"), ""+ assert.equal(
"dfedb4315d3f2eb4de2d3c510d7a987dcab67089c8ace06308827bf5bcbe02a2"+ pSignature.toString("hex"),
"32f16b0f2f4c4e1169aa59685637e1429b6581a9531d058d65f4ab224eab1703"); "" +
"dfedb4315d3f2eb4de2d3c510d7a987dcab67089c8ace06308827bf5bcbe02a2" +
"32f16b0f2f4c4e1169aa59685637e1429b6581a9531d058d65f4ab224eab1703"
);
const uSignature = eddsa.unpackSignature(pSignature); const uSignature = eddsa.unpackSignature(pSignature);
assert(eddsa.verifyPoseidon(msg, uSignature, pubKey)); assert(eddsa.verifyPoseidon(msg, uSignature, pubKey));
}); });
}); });

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const eddsa = require("../src/eddsa.js"); const eddsa = require("../src/eddsa.js");
@ -14,7 +14,7 @@ describe("EdDSA MiMC test", function () {
this.timeout(100000); this.timeout(100000);
before( async () => { before(async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "eddsamimc_test.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "eddsamimc_test.circom"));
circuit = new snarkjs.Circuit(cirDef); circuit = new snarkjs.Circuit(cirDef);
@ -40,7 +40,8 @@ describe("EdDSA MiMC test", function () {
R8x: signature.R8[0], R8x: signature.R8[0],
R8y: signature.R8[1], R8y: signature.R8[1],
S: signature.S, S: signature.S,
M: msg}); M: msg,
});
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
}); });
@ -52,7 +53,6 @@ describe("EdDSA MiMC test", function () {
const pubKey = eddsa.prv2pub(prvKey); const pubKey = eddsa.prv2pub(prvKey);
const signature = eddsa.signMiMC(prvKey, msg); const signature = eddsa.signMiMC(prvKey, msg);
assert(eddsa.verifyMiMC(msg, signature, pubKey)); assert(eddsa.verifyMiMC(msg, signature, pubKey));
@ -64,14 +64,14 @@ describe("EdDSA MiMC test", function () {
R8x: signature.R8[0].add(bigInt(1)), R8x: signature.R8[0].add(bigInt(1)),
R8y: signature.R8[1], R8y: signature.R8[1],
S: signature.S, S: signature.S,
M: msg}); M: msg,
});
assert(false); assert(false);
} catch(err) { } catch (err) {
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) ); assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message));
} }
}); });
it("Test a dissabled circuit with a bad signature", async () => { it("Test a dissabled circuit with a bad signature", async () => {
const msg = bigInt(1234); const msg = bigInt(1234);
@ -79,7 +79,6 @@ describe("EdDSA MiMC test", function () {
const pubKey = eddsa.prv2pub(prvKey); const pubKey = eddsa.prv2pub(prvKey);
const signature = eddsa.signMiMC(prvKey, msg); const signature = eddsa.signMiMC(prvKey, msg);
assert(eddsa.verifyMiMC(msg, signature, pubKey)); assert(eddsa.verifyMiMC(msg, signature, pubKey));
@ -91,7 +90,8 @@ describe("EdDSA MiMC test", function () {
R8x: signature.R8[0].add(bigInt(1)), R8x: signature.R8[0].add(bigInt(1)),
R8y: signature.R8[1], R8y: signature.R8[1],
S: signature.S, S: signature.S,
M: msg}); M: msg,
});
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
}); });

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const eddsa = require("../src/eddsa.js"); const eddsa = require("../src/eddsa.js");
@ -14,7 +14,7 @@ describe("EdDSA MiMCSponge test", function () {
this.timeout(100000); this.timeout(100000);
before( async () => { before(async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "eddsamimcsponge_test.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "eddsamimcsponge_test.circom"));
circuit = new snarkjs.Circuit(cirDef); circuit = new snarkjs.Circuit(cirDef);
@ -40,7 +40,8 @@ describe("EdDSA MiMCSponge test", function () {
R8x: signature.R8[0], R8x: signature.R8[0],
R8y: signature.R8[1], R8y: signature.R8[1],
S: signature.S, S: signature.S,
M: msg}); M: msg,
});
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
}); });
@ -52,7 +53,6 @@ describe("EdDSA MiMCSponge test", function () {
const pubKey = eddsa.prv2pub(prvKey); const pubKey = eddsa.prv2pub(prvKey);
const signature = eddsa.signMiMCSponge(prvKey, msg); const signature = eddsa.signMiMCSponge(prvKey, msg);
assert(eddsa.verifyMiMCSponge(msg, signature, pubKey)); assert(eddsa.verifyMiMCSponge(msg, signature, pubKey));
@ -64,15 +64,15 @@ describe("EdDSA MiMCSponge test", function () {
R8x: signature.R8[0].add(bigInt(1)), R8x: signature.R8[0].add(bigInt(1)),
R8y: signature.R8[1], R8y: signature.R8[1],
S: signature.S, S: signature.S,
M: msg}); M: msg,
});
assert(false); assert(false);
} catch(err) { } catch (err) {
assert(err.message.indexOf("Constraint doesn't match") >= 0); assert(err.message.indexOf("Constraint doesn't match") >= 0);
assert(err.message.indexOf("1 != 0") >= 0); assert(err.message.indexOf("1 != 0") >= 0);
} }
}); });
it("Test a dissabled circuit with a bad signature", async () => { it("Test a dissabled circuit with a bad signature", async () => {
const msg = bigInt(1234); const msg = bigInt(1234);
@ -80,7 +80,6 @@ describe("EdDSA MiMCSponge test", function () {
const pubKey = eddsa.prv2pub(prvKey); const pubKey = eddsa.prv2pub(prvKey);
const signature = eddsa.signMiMCSponge(prvKey, msg); const signature = eddsa.signMiMCSponge(prvKey, msg);
assert(eddsa.verifyMiMCSponge(msg, signature, pubKey)); assert(eddsa.verifyMiMCSponge(msg, signature, pubKey));
@ -92,7 +91,8 @@ describe("EdDSA MiMCSponge test", function () {
R8x: signature.R8[0].add(bigInt(1)), R8x: signature.R8[0].add(bigInt(1)),
R8y: signature.R8[1], R8y: signature.R8[1],
S: signature.S, S: signature.S,
M: msg}); M: msg,
});
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
}); });

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const eddsa = require("../src/eddsa.js"); const eddsa = require("../src/eddsa.js");
@ -14,7 +14,7 @@ describe("EdDSA Poseidon test", function () {
this.timeout(100000); this.timeout(100000);
before( async () => { before(async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "eddsaposeidon_test.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "eddsaposeidon_test.circom"));
circuit = new snarkjs.Circuit(cirDef); circuit = new snarkjs.Circuit(cirDef);
@ -40,7 +40,8 @@ describe("EdDSA Poseidon test", function () {
R8x: signature.R8[0], R8x: signature.R8[0],
R8y: signature.R8[1], R8y: signature.R8[1],
S: signature.S, S: signature.S,
M: msg}); M: msg,
});
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
}); });
@ -52,7 +53,6 @@ describe("EdDSA Poseidon test", function () {
const pubKey = eddsa.prv2pub(prvKey); const pubKey = eddsa.prv2pub(prvKey);
const signature = eddsa.signPoseidon(prvKey, msg); const signature = eddsa.signPoseidon(prvKey, msg);
assert(eddsa.verifyPoseidon(msg, signature, pubKey)); assert(eddsa.verifyPoseidon(msg, signature, pubKey));
@ -64,14 +64,14 @@ describe("EdDSA Poseidon test", function () {
R8x: signature.R8[0].add(bigInt(1)), R8x: signature.R8[0].add(bigInt(1)),
R8y: signature.R8[1], R8y: signature.R8[1],
S: signature.S, S: signature.S,
M: msg}); M: msg,
});
assert(false); assert(false);
} catch(err) { } catch (err) {
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) ); assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message));
} }
}); });
it("Test a dissabled circuit with a bad signature", async () => { it("Test a dissabled circuit with a bad signature", async () => {
const msg = bigInt(1234); const msg = bigInt(1234);
@ -79,7 +79,6 @@ describe("EdDSA Poseidon test", function () {
const pubKey = eddsa.prv2pub(prvKey); const pubKey = eddsa.prv2pub(prvKey);
const signature = eddsa.signPoseidon(prvKey, msg); const signature = eddsa.signPoseidon(prvKey, msg);
assert(eddsa.verifyPoseidon(msg, signature, pubKey)); assert(eddsa.verifyPoseidon(msg, signature, pubKey));
@ -91,7 +90,8 @@ describe("EdDSA Poseidon test", function () {
R8x: signature.R8[0].add(bigInt(1)), R8x: signature.R8[0].add(bigInt(1)),
R8y: signature.R8[1], R8y: signature.R8[1],
S: signature.S, S: signature.S,
M: msg}); M: msg,
});
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
}); });

@ -1,21 +1,20 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const assert = chai.assert; const assert = chai.assert;
const bigInt = snarkjs.bigInt; const bigInt = snarkjs.bigInt;
const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
const q=bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); function addPoint(a, b) {
function addPoint(a,b) {
const cta = bigInt("168700"); const cta = bigInt("168700");
const d = bigInt("168696"); const d = bigInt("168696");
const res = []; const res = [];
res[0] = bigInt((a[0]*b[1] + b[0]*a[1]) * bigInt(bigInt.one + 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.one + 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.one - 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.one - d * a[0] * b[0] * a[1] * b[1]).inverse(q)).affine(q);
return res; return res;
} }
@ -25,27 +24,28 @@ function print(circuit, w, s) {
describe("Exponentioation test", () => { describe("Exponentioation test", () => {
it("Should generate the Exponentiation table in k=0", async () => { it("Should generate the Exponentiation table in k=0", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmulw4table_test.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmulw4table_test.circom"));
// console.log(JSON.stringify(cirDef, null, 1)); // console.log(JSON.stringify(cirDef, null, 1));
// assert.equal(cirDef.nVars, 2); // assert.equal(cirDef.nVars, 2);
const circuit = new snarkjs.Circuit(cirDef); const circuit = new snarkjs.Circuit(cirDef);
console.log("NConstrains: " + circuit.nConstraints); console.log("NConstrains: " + circuit.nConstraints);
const w = circuit.calculateWitness({in: 1}); const w = circuit.calculateWitness({ in: 1 });
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
let g = [bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"), let g = [
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")] bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203"),
];
dbl= [bigInt("0"), snarkjs.bigInt("1")]; dbl = [bigInt("0"), snarkjs.bigInt("1")];
for (let i=0; i<16; i++) { for (let i = 0; i < 16; i++) {
const xout1 = w[circuit.getSignalIdx(`main.out[${i}][0]`)]; const xout1 = w[circuit.getSignalIdx(`main.out[${i}][0]`)];
const yout1 = w[circuit.getSignalIdx(`main.out[${i}][1]`)]; const yout1 = w[circuit.getSignalIdx(`main.out[${i}][1]`)];
@ -57,41 +57,40 @@ describe("Exponentioation test", () => {
assert(xout1.equals(dbl[0])); assert(xout1.equals(dbl[0]));
assert(yout1.equals(dbl[1])); assert(yout1.equals(dbl[1]));
dbl = addPoint([xout1, yout1],g); dbl = addPoint([xout1, yout1], g);
} }
}); });
it("Should generate the Exponentiation table in k=3", async () => { it("Should generate the Exponentiation table in k=3", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmulw4table_test3.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmulw4table_test3.circom"));
// console.log(JSON.stringify(cirDef, null, 1)); // console.log(JSON.stringify(cirDef, null, 1));
// assert.equal(cirDef.nVars, 2); // assert.equal(cirDef.nVars, 2);
const circuit = new snarkjs.Circuit(cirDef); const circuit = new snarkjs.Circuit(cirDef);
console.log("NConstrains: " + circuit.nConstraints); console.log("NConstrains: " + circuit.nConstraints);
const w = circuit.calculateWitness({in: 1}); const w = circuit.calculateWitness({ in: 1 });
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
let g = [snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"), let g = [
snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")] snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203"),
];
for (let i=0; i<12;i++) { for (let i = 0; i < 12; i++) {
g = addPoint(g,g); g = addPoint(g, g);
} }
dbl= [snarkjs.bigInt("0"), snarkjs.bigInt("1")]; dbl = [snarkjs.bigInt("0"), snarkjs.bigInt("1")];
for (let i=0; i<16; i++) { for (let i = 0; i < 16; i++) {
const xout1 = w[circuit.getSignalIdx(`main.out[${i}][0]`)]; const xout1 = w[circuit.getSignalIdx(`main.out[${i}][0]`)];
const yout1 = w[circuit.getSignalIdx(`main.out[${i}][1]`)]; const yout1 = w[circuit.getSignalIdx(`main.out[${i}][1]`)];
// console.log(xout1.toString()); // console.log(xout1.toString());
// console.log(yout1.toString()); // console.log(yout1.toString());
// console.log(dbl[0]); // console.log(dbl[0]);
@ -100,56 +99,57 @@ describe("Exponentioation test", () => {
assert(xout1.equals(dbl[0])); assert(xout1.equals(dbl[0]));
assert(yout1.equals(dbl[1])); assert(yout1.equals(dbl[1]));
dbl = addPoint([xout1, yout1],g); dbl = addPoint([xout1, yout1], g);
} }
}); });
it("Should exponentiate g^31", async () => { it("Should exponentiate g^31", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmul_test.circom"), {reduceConstraints: true}); const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmul_test.circom"), { reduceConstraints: true });
// console.log(JSON.stringify(cirDef, null, 1)); // console.log(JSON.stringify(cirDef, null, 1));
// assert.equal(cirDef.nVars, 2); // assert.equal(cirDef.nVars, 2);
const circuit = new snarkjs.Circuit(cirDef); const circuit = new snarkjs.Circuit(cirDef);
console.log("NConstrains: " + circuit.nConstraints); console.log("NConstrains: " + circuit.nConstraints);
const w = circuit.calculateWitness({"in": 31}); const w = circuit.calculateWitness({ in: 31 });
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
let g = [snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"), let g = [
snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")] snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203"),
];
let c = [0n, 1n]; let c = [0n, 1n];
for (let i=0; i<31;i++) { for (let i = 0; i < 31; i++) {
c = addPoint(c,g); c = addPoint(c, g);
} }
const xout = w[circuit.getSignalIdx(`main.out[0]`)]; const xout = w[circuit.getSignalIdx(`main.out[0]`)];
const yout = w[circuit.getSignalIdx(`main.out[1]`)]; const yout = w[circuit.getSignalIdx(`main.out[1]`)];
/* /*
console.log(xout.toString()); console.log(xout.toString());
console.log(yout.toString()); console.log(yout.toString());
*/ */
assert(xout.equals(c[0])); assert(xout.equals(c[0]));
assert(yout.equals(c[1])); assert(yout.equals(c[1]));
console.log("-------") console.log("-------");
const w2 = circuit.calculateWitness({"in": (1n<<252n)+1n}); const w2 = circuit.calculateWitness({ in: (1n << 252n) + 1n });
const xout2 = w2[circuit.getSignalIdx(`main.out[0]`)]; const xout2 = w2[circuit.getSignalIdx(`main.out[0]`)];
const yout2 = w2[circuit.getSignalIdx(`main.out[1]`)]; const yout2 = w2[circuit.getSignalIdx(`main.out[1]`)];
c = [g[0], g[1]]; c = [g[0], g[1]];
for (let i=0; i<252;i++) { for (let i = 0; i < 252; i++) {
c = addPoint(c,c); c = addPoint(c, c);
} }
c = addPoint(c,g); c = addPoint(c, g);
// console.log(xout2.toString()); // console.log(xout2.toString());
// console.log(yout2.toString()); // console.log(yout2.toString());
@ -158,7 +158,6 @@ describe("Exponentioation test", () => {
assert(xout2.equals(c[0])); assert(xout2.equals(c[0]));
assert(yout2.equals(c[1])); assert(yout2.equals(c[1]));
}).timeout(10000000); }).timeout(10000000);
it("Number of constrains for 256 bits", async () => { it("Number of constrains for 256 bits", async () => {
@ -168,5 +167,4 @@ describe("Exponentioation test", () => {
console.log("NConstrains: " + circuit.nConstraints); console.log("NConstrains: " + circuit.nConstraints);
}).timeout(10000000); }).timeout(10000000);
}); });

@ -1,13 +1,12 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const assert = chai.assert; const assert = chai.assert;
const bigInt = snarkjs.bigInt; const bigInt = snarkjs.bigInt;
function print(circuit, w, s) { function print(circuit, w, s) {
console.log(s + ": " + w[circuit.getSignalIdx(s)]); console.log(s + ": " + w[circuit.getSignalIdx(s)]);
} }
@ -19,18 +18,17 @@ describe("Escalarmul test", function () {
let g = [ let g = [
snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"), snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203") snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203"),
]; ];
before( async() => { before(async () => {
const cirDefEMulAny = await compiler(path.join(__dirname, "circuits", "escalarmulany_test.circom")); const cirDefEMulAny = await compiler(path.join(__dirname, "circuits", "escalarmulany_test.circom"));
circuitEMulAny = new snarkjs.Circuit(cirDefEMulAny); circuitEMulAny = new snarkjs.Circuit(cirDefEMulAny);
console.log("NConstrains Escalarmul any: " + circuitEMulAny.nConstraints); console.log("NConstrains Escalarmul any: " + circuitEMulAny.nConstraints);
}); });
it("Should generate Same escalar mul", async () => { it("Should generate Same escalar mul", async () => {
const w = circuitEMulAny.calculateWitness({ e: 1, p: g });
const w = circuitEMulAny.calculateWitness({"e": 1, "p": g});
assert(circuitEMulAny.checkWitness(w)); assert(circuitEMulAny.checkWitness(w));
@ -42,9 +40,8 @@ describe("Escalarmul test", function () {
}); });
it("If multiply by order should return 0", async () => { it("If multiply by order should return 0", async () => {
const r = bigInt("2736030358979909402780800718157159386076813972158567259200215660948447373041"); const r = bigInt("2736030358979909402780800718157159386076813972158567259200215660948447373041");
const w = circuitEMulAny.calculateWitness({"e": r, "p": g}); const w = circuitEMulAny.calculateWitness({ e: r, p: g });
assert(circuitEMulAny.checkWitness(w)); assert(circuitEMulAny.checkWitness(w));
@ -54,6 +51,4 @@ describe("Escalarmul test", function () {
assert(xout.equals(bigInt.zero)); assert(xout.equals(bigInt.zero));
assert(yout.equals(bigInt.one)); assert(yout.equals(bigInt.one));
}); });
}); });

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const babyjub = require("../src/babyjub"); const babyjub = require("../src/babyjub");
@ -8,7 +8,6 @@ const assert = chai.assert;
const bigInt = snarkjs.bigInt; const bigInt = snarkjs.bigInt;
function print(circuit, w, s) { function print(circuit, w, s) {
console.log(s + ": " + w[circuit.getSignalIdx(s)]); console.log(s + ": " + w[circuit.getSignalIdx(s)]);
} }
@ -18,15 +17,14 @@ describe("Escalarmul test", function () {
this.timeout(100000); this.timeout(100000);
before( async() => { before(async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmulfix_test.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmulfix_test.circom"));
circuit = new snarkjs.Circuit(cirDef); circuit = new snarkjs.Circuit(cirDef);
console.log("NConstrains Escalarmul fix: " + circuit.nConstraints); console.log("NConstrains Escalarmul fix: " + circuit.nConstraints);
}); });
it("Should generate Same escalar mul", async () => { it("Should generate Same escalar mul", async () => {
const w = circuit.calculateWitness({ e: 0 });
const w = circuit.calculateWitness({"e": 0});
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
@ -38,8 +36,7 @@ describe("Escalarmul test", function () {
}); });
it("Should generate Same escalar mul", async () => { it("Should generate Same escalar mul", async () => {
const w = circuit.calculateWitness({ e: 1 });
const w = circuit.calculateWitness({"e": 1});
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
@ -51,14 +48,13 @@ describe("Escalarmul test", function () {
}); });
it("Should generate scalar mul of a specific constant", async () => { it("Should generate scalar mul of a specific constant", async () => {
const s = bigInt("2351960337287830298912035165133676222414898052661454064215017316447594616519"); const s = bigInt("2351960337287830298912035165133676222414898052661454064215017316447594616519");
const base8 = [ const base8 = [
bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"), bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203") bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203"),
]; ];
const w = circuit.calculateWitness({"e": s}); const w = circuit.calculateWitness({ e: s });
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
@ -72,16 +68,15 @@ describe("Escalarmul test", function () {
}); });
it("Should generate scalar mul of the firsts 50 elements", async () => { it("Should generate scalar mul of the firsts 50 elements", async () => {
const base8 = [ const base8 = [
bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"), bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203") bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203"),
]; ];
for (let i=0; i<50; i++) { for (let i = 0; i < 50; i++) {
const s = bigInt(i); const s = bigInt(i);
const w = circuit.calculateWitness({"e": s}); const w = circuit.calculateWitness({ e: s });
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
@ -96,8 +91,7 @@ describe("Escalarmul test", function () {
}); });
it("If multiply by order should return 0", async () => { it("If multiply by order should return 0", async () => {
const w = circuit.calculateWitness({ e: babyjub.subOrder });
const w = circuit.calculateWitness({"e": babyjub.subOrder });
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
@ -107,6 +101,4 @@ describe("Escalarmul test", function () {
assert(xout.equals(bigInt.zero)); assert(xout.equals(bigInt.zero));
assert(yout.equals(bigInt.one)); assert(yout.equals(bigInt.one));
}); });
}); });

@ -1,13 +1,12 @@
const snarkjs = require("@tornado/snarkjs");
const snarkjs = require("snarkjs");
const bigInt = snarkjs.bigInt; const bigInt = snarkjs.bigInt;
module.exports = function hexBits(cir, witness, sig, nBits) { module.exports = function hexBits(cir, witness, sig, nBits) {
let v = bigInt(0); let v = bigInt(0);
for (let i=nBits-1; i>=0; i--) { for (let i = nBits - 1; i >= 0; i--) {
v = v.shiftLeft(1); v = v.shiftLeft(1);
const name = sig+"["+i+"]"; const name = sig + "[" + i + "]";
const idx = cir.getSignalIdx(name); const idx = cir.getSignalIdx(name);
const vbit = bigInt(witness[idx].toString()); const vbit = bigInt(witness[idx].toString());
if (vbit.equals(bigInt(1))) { if (vbit.equals(bigInt(1))) {
@ -15,7 +14,7 @@ module.exports = function hexBits(cir, witness, sig, nBits) {
} else if (vbit.equals(bigInt(0))) { } else if (vbit.equals(bigInt(0))) {
v; v;
} else { } else {
console.log("Not Binary: "+name); console.log("Not Binary: " + name);
} }
} }
return v.toString(16); return v.toString(16);

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const mimcjs = require("../src/mimc7.js"); const mimcjs = require("../src/mimc7.js");
@ -12,7 +12,7 @@ describe("MiMC Circuit test", function () {
this.timeout(100000); this.timeout(100000);
before( async () => { before(async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "mimc_test.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "mimc_test.circom"));
circuit = new snarkjs.Circuit(cirDef); circuit = new snarkjs.Circuit(cirDef);
@ -21,15 +21,14 @@ describe("MiMC Circuit test", function () {
}); });
it("Should check constrain", async () => { it("Should check constrain", async () => {
const w = circuit.calculateWitness({x_in: 1, k: 2}); const w = circuit.calculateWitness({ x_in: 1, k: 2 });
const res = w[circuit.getSignalIdx("main.out")]; const res = w[circuit.getSignalIdx("main.out")];
const res2 = mimcjs.hash(1,2,91); const res2 = mimcjs.hash(1, 2, 91);
assert.equal(res.toString(), res2.toString()); assert.equal(res.toString(), res2.toString());
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
}); });
}); });

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const mimcjs = require("../src/mimcsponge.js"); const mimcjs = require("../src/mimcsponge.js");
@ -19,18 +19,17 @@ describe("MiMC Sponge Circuit test", function () {
console.log("MiMC Feistel constraints: " + circuit.nConstraints); console.log("MiMC Feistel constraints: " + circuit.nConstraints);
const w = circuit.calculateWitness({xL_in: 1, xR_in: 2, k: 3}); const w = circuit.calculateWitness({ xL_in: 1, xR_in: 2, k: 3 });
const xLout = w[circuit.getSignalIdx("main.xL_out")]; const xLout = w[circuit.getSignalIdx("main.xL_out")];
const xRout = w[circuit.getSignalIdx("main.xR_out")]; const xRout = w[circuit.getSignalIdx("main.xR_out")];
const out2 = mimcjs.hash(1,2,3); const out2 = mimcjs.hash(1, 2, 3);
assert.equal(xLout.toString(), out2.xL.toString()); assert.equal(xLout.toString(), out2.xL.toString());
assert.equal(xRout.toString(), out2.xR.toString()); assert.equal(xRout.toString(), out2.xR.toString());
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
}); });
it("Should check hash", async () => { it("Should check hash", async () => {
@ -40,19 +39,18 @@ describe("MiMC Sponge Circuit test", function () {
console.log("MiMC Sponge constraints: " + circuit.nConstraints); console.log("MiMC Sponge constraints: " + circuit.nConstraints);
const w = circuit.calculateWitness({ins: [1, 2], k: 0}); const w = circuit.calculateWitness({ ins: [1, 2], k: 0 });
const o1 = w[circuit.getSignalIdx("main.outs[0]")]; const o1 = w[circuit.getSignalIdx("main.outs[0]")];
const o2 = w[circuit.getSignalIdx("main.outs[1]")]; const o2 = w[circuit.getSignalIdx("main.outs[1]")];
const o3 = w[circuit.getSignalIdx("main.outs[2]")]; const o3 = w[circuit.getSignalIdx("main.outs[2]")];
const out2 = mimcjs.multiHash([1,2], 0, 3); const out2 = mimcjs.multiHash([1, 2], 0, 3);
assert.equal(o1.toString(), out2[0].toString()); assert.equal(o1.toString(), out2[0].toString());
assert.equal(o2.toString(), out2[1].toString()); assert.equal(o2.toString(), out2[1].toString());
assert.equal(o3.toString(), out2[2].toString()); assert.equal(o3.toString(), out2[2].toString());
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
}); });
}); });

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const babyJub = require("../src/babyjub.js"); const babyJub = require("../src/babyjub.js");
@ -16,12 +16,13 @@ describe("Montgomery test", function () {
let g = [ let g = [
snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"), snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")]; snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203"),
];
let mg, mg2, g2, g3, mg3; let mg, mg2, g2, g3, mg3;
this.timeout(100000); this.timeout(100000);
before( async() => { before(async () => {
const cirDefE2M = await compiler(path.join(__dirname, "circuits", "edwards2montgomery.circom")); const cirDefE2M = await compiler(path.join(__dirname, "circuits", "edwards2montgomery.circom"));
circuitE2M = new snarkjs.Circuit(cirDefE2M); circuitE2M = new snarkjs.Circuit(cirDefE2M);
console.log("NConstrains Edwards -> Montgomery: " + circuitE2M.nConstraints); console.log("NConstrains Edwards -> Montgomery: " + circuitE2M.nConstraints);
@ -41,14 +42,14 @@ describe("Montgomery test", function () {
it("Convert Edwards to Montgomery and back again", async () => { it("Convert Edwards to Montgomery and back again", async () => {
let w, xout, yout; let w, xout, yout;
w = circuitE2M.calculateWitness({ in: g}); w = circuitE2M.calculateWitness({ in: g });
xout = w[circuitE2M.getSignalIdx("main.out[0]")]; xout = w[circuitE2M.getSignalIdx("main.out[0]")];
yout = w[circuitE2M.getSignalIdx("main.out[1]")]; yout = w[circuitE2M.getSignalIdx("main.out[1]")];
mg = [xout, yout]; mg = [xout, yout];
w = circuitM2E.calculateWitness({ in: [xout, yout]}); w = circuitM2E.calculateWitness({ in: [xout, yout] });
xout = w[circuitM2E.getSignalIdx("main.out[0]")]; xout = w[circuitM2E.getSignalIdx("main.out[0]")];
yout = w[circuitM2E.getSignalIdx("main.out[1]")]; yout = w[circuitM2E.getSignalIdx("main.out[1]")];
@ -59,16 +60,16 @@ describe("Montgomery test", function () {
it("Should double a point", async () => { it("Should double a point", async () => {
let w, xout, yout; let w, xout, yout;
g2 = babyJub.addPoint(g,g); g2 = babyJub.addPoint(g, g);
w = circuitMDouble.calculateWitness({ in: mg}); w = circuitMDouble.calculateWitness({ in: mg });
xout = w[circuitE2M.getSignalIdx("main.out[0]")]; xout = w[circuitE2M.getSignalIdx("main.out[0]")];
yout = w[circuitE2M.getSignalIdx("main.out[1]")]; yout = w[circuitE2M.getSignalIdx("main.out[1]")];
mg2 = [xout, yout]; mg2 = [xout, yout];
w = circuitM2E.calculateWitness({ in: mg2}); w = circuitM2E.calculateWitness({ in: mg2 });
xout = w[circuitM2E.getSignalIdx("main.out[0]")]; xout = w[circuitM2E.getSignalIdx("main.out[0]")];
yout = w[circuitM2E.getSignalIdx("main.out[1]")]; yout = w[circuitM2E.getSignalIdx("main.out[1]")];
@ -79,16 +80,16 @@ describe("Montgomery test", function () {
it("Should add a point", async () => { it("Should add a point", async () => {
let w, xout, yout; let w, xout, yout;
g3 = babyJub.addPoint(g,g2); g3 = babyJub.addPoint(g, g2);
w = circuitMAdd.calculateWitness({ in1: mg, in2: mg2}); w = circuitMAdd.calculateWitness({ in1: mg, in2: mg2 });
xout = w[circuitMAdd.getSignalIdx("main.out[0]")]; xout = w[circuitMAdd.getSignalIdx("main.out[0]")];
yout = w[circuitMAdd.getSignalIdx("main.out[1]")]; yout = w[circuitMAdd.getSignalIdx("main.out[1]")];
mg3 = [xout, yout]; mg3 = [xout, yout];
w = circuitM2E.calculateWitness({ in: mg3}); w = circuitM2E.calculateWitness({ in: mg3 });
xout = w[circuitM2E.getSignalIdx("main.out[0]")]; xout = w[circuitM2E.getSignalIdx("main.out[0]")];
yout = w[circuitM2E.getSignalIdx("main.out[1]")]; yout = w[circuitM2E.getSignalIdx("main.out[1]")];

@ -1,21 +1,19 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const assert = chai.assert; const assert = chai.assert;
const bigInt = snarkjs.bigInt; const bigInt = snarkjs.bigInt;
describe("Mux4 test", () => { describe("Mux4 test", () => {
it("Should create a constant multiplexer 4", async () => { it("Should create a constant multiplexer 4", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "mux4_1.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "mux4_1.circom"));
// console.log(JSON.stringify(cirDef, null, 1)); // console.log(JSON.stringify(cirDef, null, 1));
// assert.equal(cirDef.nVars, 2); // assert.equal(cirDef.nVars, 2);
const circuit = new snarkjs.Circuit(cirDef); const circuit = new snarkjs.Circuit(cirDef);
@ -37,11 +35,11 @@ describe("Mux4 test", () => {
bigInt("1223"), bigInt("1223"),
bigInt("4546"), bigInt("4546"),
bigInt("4256"), bigInt("4256"),
bigInt("4456") bigInt("4456"),
]; ];
for (let i=0; i<16; i++) { for (let i = 0; i < 16; i++) {
const w = circuit.calculateWitness({ "selector": i }); const w = circuit.calculateWitness({ selector: i });
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
@ -53,26 +51,16 @@ describe("Mux4 test", () => {
}); });
it("Should create a constant multiplexer 3", async () => { it("Should create a constant multiplexer 3", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "mux3_1.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "mux3_1.circom"));
const circuit = new snarkjs.Circuit(cirDef); const circuit = new snarkjs.Circuit(cirDef);
console.log("NConstrains Mux3: " + circuit.nConstraints); console.log("NConstrains Mux3: " + circuit.nConstraints);
const ct8 = [ const ct8 = [bigInt("37"), bigInt("47"), bigInt("53"), bigInt("71"), bigInt("89"), bigInt("107"), bigInt("163"), bigInt("191")];
bigInt("37"),
bigInt("47"),
bigInt("53"),
bigInt("71"),
bigInt("89"),
bigInt("107"),
bigInt("163"),
bigInt("191")
];
for (let i=0; i<8; i++) { for (let i = 0; i < 8; i++) {
const w = circuit.calculateWitness({ "selector": i }); const w = circuit.calculateWitness({ selector: i });
assert(w[0].equals(bigInt(1))); assert(w[0].equals(bigInt(1)));
@ -81,22 +69,16 @@ describe("Mux4 test", () => {
} }
}); });
it("Should create a constant multiplexer 2", async () => { it("Should create a constant multiplexer 2", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "mux2_1.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "mux2_1.circom"));
const circuit = new snarkjs.Circuit(cirDef); const circuit = new snarkjs.Circuit(cirDef);
console.log("NConstrains Mux2: " + circuit.nConstraints); console.log("NConstrains Mux2: " + circuit.nConstraints);
const ct8 = [ const ct8 = [bigInt("37"), bigInt("47"), bigInt("53"), bigInt("71")];
bigInt("37"),
bigInt("47"),
bigInt("53"),
bigInt("71"),
];
for (let i=0; i<4; i++) { for (let i = 0; i < 4; i++) {
const w = circuit.calculateWitness({ "selector": i }); const w = circuit.calculateWitness({ selector: i });
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
@ -107,20 +89,16 @@ describe("Mux4 test", () => {
} }
}); });
it("Should create a constant multiplexer 1", async () => { it("Should create a constant multiplexer 1", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "mux1_1.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "mux1_1.circom"));
const circuit = new snarkjs.Circuit(cirDef); const circuit = new snarkjs.Circuit(cirDef);
console.log("NConstrains Mux1: " + circuit.nConstraints); console.log("NConstrains Mux1: " + circuit.nConstraints);
const ct8 = [ const ct8 = [bigInt("37"), bigInt("47")];
bigInt("37"),
bigInt("47"),
];
for (let i=0; i<2; i++) { for (let i = 0; i < 2; i++) {
const w = circuit.calculateWitness({ "selector": i }); const w = circuit.calculateWitness({ selector: i });
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const assert = chai.assert; const assert = chai.assert;
@ -9,19 +9,33 @@ const bigInt = snarkjs.bigInt;
const babyJub = require("../src/babyjub.js"); const babyJub = require("../src/babyjub.js");
const PBASE = const PBASE = [
[ [
[bigInt("10457101036533406547632367118273992217979173478358440826365724437999023779287"),bigInt("19824078218392094440610104313265183977899662750282163392862422243483260492317")], bigInt("10457101036533406547632367118273992217979173478358440826365724437999023779287"),
[bigInt("2671756056509184035029146175565761955751135805354291559563293617232983272177"),bigInt("2663205510731142763556352975002641716101654201788071096152948830924149045094")], bigInt("19824078218392094440610104313265183977899662750282163392862422243483260492317"),
[bigInt("5802099305472655231388284418920769829666717045250560929368476121199858275951"),bigInt("5980429700218124965372158798884772646841287887664001482443826541541529227896")], ],
[bigInt("7107336197374528537877327281242680114152313102022415488494307685842428166594"),bigInt("2857869773864086953506483169737724679646433914307247183624878062391496185654")], [
[bigInt("20265828622013100949498132415626198973119240347465898028410217039057588424236"),bigInt("1160461593266035632937973507065134938065359936056410650153315956301179689506")] bigInt("2671756056509184035029146175565761955751135805354291559563293617232983272177"),
]; bigInt("2663205510731142763556352975002641716101654201788071096152948830924149045094"),
],
[
bigInt("5802099305472655231388284418920769829666717045250560929368476121199858275951"),
bigInt("5980429700218124965372158798884772646841287887664001482443826541541529227896"),
],
[
bigInt("7107336197374528537877327281242680114152313102022415488494307685842428166594"),
bigInt("2857869773864086953506483169737724679646433914307247183624878062391496185654"),
],
[
bigInt("20265828622013100949498132415626198973119240347465898028410217039057588424236"),
bigInt("1160461593266035632937973507065134938065359936056410650153315956301179689506"),
],
];
describe("Double Pedersen test", function() { describe("Double Pedersen test", function () {
let circuit; let circuit;
this.timeout(100000); this.timeout(100000);
before( async() => { before(async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "pedersen_test.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "pedersen_test.circom"));
circuit = new snarkjs.Circuit(cirDef); circuit = new snarkjs.Circuit(cirDef);
@ -29,10 +43,9 @@ describe("Double Pedersen test", function() {
console.log("NConstrains: " + circuit.nConstraints); console.log("NConstrains: " + circuit.nConstraints);
}); });
it("Should pedersen at zero", async () => { it("Should pedersen at zero", async () => {
let w, xout, yout; let w, xout, yout;
w = circuit.calculateWitness({ in: ["0", "0"]}); w = circuit.calculateWitness({ in: ["0", "0"] });
xout = w[circuit.getSignalIdx("main.out[0]")]; xout = w[circuit.getSignalIdx("main.out[0]")];
yout = w[circuit.getSignalIdx("main.out[1]")]; yout = w[circuit.getSignalIdx("main.out[1]")];
@ -43,7 +56,7 @@ describe("Double Pedersen test", function() {
it("Should pedersen at one first generator", async () => { it("Should pedersen at one first generator", async () => {
let w, xout, yout; let w, xout, yout;
w = circuit.calculateWitness({ in: ["1", "0"]}); w = circuit.calculateWitness({ in: ["1", "0"] });
xout = bigInt(w[circuit.getSignalIdx("main.out[0]")]); xout = bigInt(w[circuit.getSignalIdx("main.out[0]")]);
yout = bigInt(w[circuit.getSignalIdx("main.out[1]")]); yout = bigInt(w[circuit.getSignalIdx("main.out[1]")]);
@ -54,45 +67,36 @@ describe("Double Pedersen test", function() {
it("Should pedersen at one second generator", async () => { it("Should pedersen at one second generator", async () => {
let w, xout, yout; let w, xout, yout;
w = circuit.calculateWitness({ in: ["0", "1"]}); w = circuit.calculateWitness({ in: ["0", "1"] });
xout = w[circuit.getSignalIdx("main.out[0]")]; xout = w[circuit.getSignalIdx("main.out[0]")];
yout = w[circuit.getSignalIdx("main.out[1]")]; yout = w[circuit.getSignalIdx("main.out[1]")];
assert(xout.equals(PBASE[1][0])); assert(xout.equals(PBASE[1][0]));
assert(yout.equals(PBASE[1][1])); assert(yout.equals(PBASE[1][1]));
}); });
it("Should pedersen at mixed generators", async () => { it("Should pedersen at mixed generators", async () => {
let w, xout, yout; let w, xout, yout;
w = circuit.calculateWitness({ in: ["3", "7"]}); w = circuit.calculateWitness({ in: ["3", "7"] });
xout = w[circuit.getSignalIdx("main.out[0]")]; xout = w[circuit.getSignalIdx("main.out[0]")];
yout = w[circuit.getSignalIdx("main.out[1]")]; yout = w[circuit.getSignalIdx("main.out[1]")];
const r = babyJub.addPoint(babyJub.mulPointEscalar(PBASE[0], 3), babyJub.mulPointEscalar(PBASE[1], 7));
const r = babyJub.addPoint(
babyJub.mulPointEscalar(PBASE[0], 3),
babyJub.mulPointEscalar(PBASE[1], 7)
);
assert(xout.equals(r[0])); assert(xout.equals(r[0]));
assert(yout.equals(r[1])); assert(yout.equals(r[1]));
}); });
it("Should pedersen all ones", async () => { it("Should pedersen all ones", async () => {
let w, xout, yout; let w, xout, yout;
const allOnes = bigInt("1").shl(250).sub(bigInt("1")); const allOnes = bigInt("1").shl(250).sub(bigInt("1"));
w = circuit.calculateWitness({ in: [allOnes, allOnes]}); w = circuit.calculateWitness({ in: [allOnes, allOnes] });
xout = w[circuit.getSignalIdx("main.out[0]")]; xout = w[circuit.getSignalIdx("main.out[0]")];
yout = w[circuit.getSignalIdx("main.out[1]")]; yout = w[circuit.getSignalIdx("main.out[1]")];
const r2 = babyJub.addPoint( const r2 = babyJub.addPoint(babyJub.mulPointEscalar(PBASE[0], allOnes), babyJub.mulPointEscalar(PBASE[1], allOnes));
babyJub.mulPointEscalar(PBASE[0], allOnes),
babyJub.mulPointEscalar(PBASE[1], allOnes)
);
assert(xout.equals(r2[0])); assert(xout.equals(r2[0]));
assert(yout.equals(r2[1])); assert(yout.equals(r2[1]));

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const assert = chai.assert; const assert = chai.assert;
@ -10,11 +10,10 @@ const bigInt = snarkjs.bigInt;
const babyJub = require("../src/babyjub.js"); const babyJub = require("../src/babyjub.js");
const pedersen = require("../src/pedersenHash.js"); const pedersen = require("../src/pedersenHash.js");
describe("Pedersen test", function () {
describe("Pedersen test", function() {
let circuit; let circuit;
this.timeout(100000); this.timeout(100000);
before( async() => { before(async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "pedersen2_test.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "pedersen2_test.circom"));
circuit = new snarkjs.Circuit(cirDef); circuit = new snarkjs.Circuit(cirDef);
@ -22,10 +21,9 @@ describe("Pedersen test", function() {
console.log("NConstrains Pedersen2: " + circuit.nConstraints); console.log("NConstrains Pedersen2: " + circuit.nConstraints);
}); });
it("Should pedersen at zero", async () => { it("Should pedersen at zero", async () => {
let w, xout, yout; let w, xout, yout;
w = circuit.calculateWitness({ in: 0}); w = circuit.calculateWitness({ in: 0 });
xout = w[circuit.getSignalIdx("main.out[0]")]; xout = w[circuit.getSignalIdx("main.out[0]")];
yout = w[circuit.getSignalIdx("main.out[1]")]; yout = w[circuit.getSignalIdx("main.out[1]")];
@ -44,21 +42,19 @@ describe("Pedersen test", function() {
assert(yout.equals(hP[1])); assert(yout.equals(hP[1]));
}); });
it("Should pedersen with 253 ones", async () => { it("Should pedersen with 253 ones", async () => {
let w, xout, yout; let w, xout, yout;
const n = bigInt.one.shl(253).sub(bigInt.one); const n = bigInt.one.shl(253).sub(bigInt.one);
console.log(n.toString(16)); console.log(n.toString(16));
w = circuit.calculateWitness({ in: n}); w = circuit.calculateWitness({ in: n });
xout = w[circuit.getSignalIdx("main.out[0]")]; xout = w[circuit.getSignalIdx("main.out[0]")];
yout = w[circuit.getSignalIdx("main.out[1]")]; yout = w[circuit.getSignalIdx("main.out[1]")];
const b = Buffer.alloc(32); const b = Buffer.alloc(32);
for (let i=0; i<31; i++) b[i] = 0xFF; for (let i = 0; i < 31; i++) b[i] = 0xff;
b[31] = 0x1F; b[31] = 0x1f;
const h = pedersen.hash(b); const h = pedersen.hash(b);
const hP = babyJub.unpackPoint(h); const hP = babyJub.unpackPoint(h);

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const assert = chai.assert; const assert = chai.assert;
@ -9,11 +9,10 @@ const bigInt = snarkjs.bigInt;
const babyJub = require("../src/babyjub.js"); const babyJub = require("../src/babyjub.js");
describe("Point 2 bits test", function () {
describe("Point 2 bits test", function() {
let circuit; let circuit;
this.timeout(100000); this.timeout(100000);
before( async() => { before(async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "pointbits_loopback.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "pointbits_loopback.circom"));
circuit = new snarkjs.Circuit(cirDef); circuit = new snarkjs.Circuit(cirDef);
@ -21,12 +20,12 @@ describe("Point 2 bits test", function() {
console.log("NConstrains Point2Bits loopback: " + circuit.nConstraints); console.log("NConstrains Point2Bits loopback: " + circuit.nConstraints);
}); });
it("Should do the both convertions for 8Base", async () => { it("Should do the both convertions for 8Base", async () => {
const w = circuit.calculateWitness({ in: babyJub.Base8}); const w = circuit.calculateWitness({ in: babyJub.Base8 });
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
}); });
it("Should do the both convertions for Zero point", async () => { it("Should do the both convertions for Zero point", async () => {
const w = circuit.calculateWitness({ in: [0, 1]}); const w = circuit.calculateWitness({ in: [0, 1] });
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
}); });

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const poseidon = require("../src/poseidon.js"); const poseidon = require("../src/poseidon.js");
@ -13,7 +13,7 @@ describe("Poseidon Circuit test", function () {
this.timeout(100000); this.timeout(100000);
before( async () => { before(async () => {
const cirDef2 = await compiler(path.join(__dirname, "circuits", "poseidon2_test.circom")); const cirDef2 = await compiler(path.join(__dirname, "circuits", "poseidon2_test.circom"));
const cirDef4 = await compiler(path.join(__dirname, "circuits", "poseidon4_test.circom")); const cirDef4 = await compiler(path.join(__dirname, "circuits", "poseidon4_test.circom"));
@ -24,7 +24,7 @@ describe("Poseidon Circuit test", function () {
it("Should check constrain of hash([1, 2])", async () => { it("Should check constrain of hash([1, 2])", async () => {
const hash = poseidon([1, 2]); const hash = poseidon([1, 2]);
assert.equal("0x11ad302b36a2d7e09653c8e90618f00c06cd0a7348e52cdf2ccced3c3abec679", "0x" + hash.toString(16)); assert.equal("0x11ad302b36a2d7e09653c8e90618f00c06cd0a7348e52cdf2ccced3c3abec679", "0x" + hash.toString(16));
const w = await circuit2.calculateWitness({inputs: [1, 2]}, true); const w = await circuit2.calculateWitness({ inputs: [1, 2] }, true);
const res = w[circuit2.getSignalIdx("main.out")]; const res = w[circuit2.getSignalIdx("main.out")];
assert.equal(res.toString(), hash.toString()); assert.equal(res.toString(), hash.toString());
await circuit2.checkWitness(w); await circuit2.checkWitness(w);
@ -33,17 +33,16 @@ describe("Poseidon Circuit test", function () {
it("Should check constrain of hash([3, 4])", async () => { it("Should check constrain of hash([3, 4])", async () => {
const hash = poseidon([3, 4]); const hash = poseidon([3, 4]);
assert.equal("0x23939f0972e764d6e252060279aabaca8ec650ab30b17d2c13551bec2a66bcef", "0x" + hash.toString(16)); assert.equal("0x23939f0972e764d6e252060279aabaca8ec650ab30b17d2c13551bec2a66bcef", "0x" + hash.toString(16));
const w = await circuit2.calculateWitness({inputs: [3, 4]}); const w = await circuit2.calculateWitness({ inputs: [3, 4] });
const res = w[circuit2.getSignalIdx("main.out")]; const res = w[circuit2.getSignalIdx("main.out")];
assert.equal(res.toString(), hash.toString()); assert.equal(res.toString(), hash.toString());
await circuit2.checkWitness(w); await circuit2.checkWitness(w);
}); });
it("Should check constrain of hash([1, 2, 3, 4])", async () => { it("Should check constrain of hash([1, 2, 3, 4])", async () => {
const hash = poseidon([1, 2, 3, 4]); const hash = poseidon([1, 2, 3, 4]);
assert.equal("0x2e4fb80ce74868b0d33f4acb22071d8d8f8da7d30ebf972e6e4f72a64bb0633f", "0x" + hash.toString(16)); assert.equal("0x2e4fb80ce74868b0d33f4acb22071d8d8f8da7d30ebf972e6e4f72a64bb0633f", "0x" + hash.toString(16));
const w = await circuit4.calculateWitness({inputs: [1, 2, 3, 4]}); const w = await circuit4.calculateWitness({ inputs: [1, 2, 3, 4] });
const res = w[circuit4.getSignalIdx("main.out")]; const res = w[circuit4.getSignalIdx("main.out")];
assert.equal(res.toString(), hash.toString()); assert.equal(res.toString(), hash.toString());
await circuit4.checkWitness(w); await circuit4.checkWitness(w);
@ -52,7 +51,7 @@ describe("Poseidon Circuit test", function () {
it("Should check constrain of hash([5, 6, 7, 8])", async () => { it("Should check constrain of hash([5, 6, 7, 8])", async () => {
const hash = poseidon([5, 6, 7, 8]); const hash = poseidon([5, 6, 7, 8]);
assert.equal("0x2a3fc67aa97766917ee06e927f35fd70f4655ad6c1f2e7bcd5c5c85aa3a8a974", "0x" + hash.toString(16)); assert.equal("0x2a3fc67aa97766917ee06e927f35fd70f4655ad6c1f2e7bcd5c5c85aa3a8a974", "0x" + hash.toString(16));
const w = await circuit4.calculateWitness({inputs: [5, 6, 7, 8]}); const w = await circuit4.calculateWitness({ inputs: [5, 6, 7, 8] });
const res = w[circuit4.getSignalIdx("main.out")]; const res = w[circuit4.getSignalIdx("main.out")];
assert.equal(res.toString(), hash.toString()); assert.equal(res.toString(), hash.toString());
await circuit4.checkWitness(w); await circuit4.checkWitness(w);

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const crypto = require("crypto"); const crypto = require("crypto");
const compiler = require("circom"); const compiler = require("circom");
@ -11,36 +11,32 @@ const sha256 = require("./helpers/sha256");
// const printSignal = require("./helpers/printsignal"); // const printSignal = require("./helpers/printsignal");
function buffer2bitArray(b) { function buffer2bitArray(b) {
const res = []; const res = [];
for (let i=0; i<b.length; i++) { for (let i = 0; i < b.length; i++) {
for (let j=0; j<8; j++) { for (let j = 0; j < 8; j++) {
res.push((b[i] >> (7-j) &1)); res.push((b[i] >> (7 - j)) & 1);
} }
} }
return res; return res;
} }
function bitArray2buffer(a) { function bitArray2buffer(a) {
const len = Math.floor((a.length -1 )/8)+1; const len = Math.floor((a.length - 1) / 8) + 1;
const b = new Buffer.alloc(len); const b = new Buffer.alloc(len);
for (let i=0; i<a.length; i++) { for (let i = 0; i < a.length; i++) {
const p = Math.floor(i/8); const p = Math.floor(i / 8);
b[p] = b[p] | (Number(a[i]) << ( 7 - (i%8) )); b[p] = b[p] | (Number(a[i]) << (7 - (i % 8)));
} }
return b; return b;
} }
describe("SHA256 test", () => { describe("SHA256 test", () => {
it("Should work bits to array and array to bits", async () => { it("Should work bits to array and array to bits", async () => {
const b = new Buffer.alloc(64); const b = new Buffer.alloc(64);
for (let i=0; i<64; i++) { for (let i = 0; i < 64; i++) {
b[i] = i+1; b[i] = i + 1;
} }
const a = buffer2bitArray(b); const a = buffer2bitArray(b);
const b2 = bitArray2buffer(a); const b2 = bitArray2buffer(a);
@ -52,21 +48,19 @@ describe("SHA256 test", () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "sha256_2_test.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "sha256_2_test.circom"));
const circuit = new snarkjs.Circuit(cirDef); const circuit = new snarkjs.Circuit(cirDef);
console.log("Vars: "+circuit.nVars); console.log("Vars: " + circuit.nVars);
console.log("Constraints: "+circuit.nConstraints); console.log("Constraints: " + circuit.nConstraints);
const witness = circuit.calculateWitness({ "a": "1", "b": "2" }); const witness = circuit.calculateWitness({ a: "1", b: "2" });
const b = new Buffer.alloc(54); const b = new Buffer.alloc(54);
b[26] = 1; b[26] = 1;
b[53] = 2; b[53] = 2;
const hash = crypto.createHash("sha256") const hash = crypto.createHash("sha256").update(b).digest("hex");
.update(b)
.digest("hex");
const r = "0x" + hash.slice(10); const r = "0x" + hash.slice(10);
const hash2 = sha256.hash(b.toString("hex"), {msgFormat: "hex-bytes"}); const hash2 = sha256.hash(b.toString("hex"), { msgFormat: "hex-bytes" });
assert.equal(hash, hash2); assert.equal(hash, hash2);
@ -74,63 +68,55 @@ describe("SHA256 test", () => {
}).timeout(1000000); }).timeout(1000000);
it("Should calculate a hash of 2 compressor", async () => { it("Should calculate a hash of 2 compressor", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "sha256_test512.circom"), {reduceConstraints:false} ); const cirDef = await compiler(path.join(__dirname, "circuits", "sha256_test512.circom"), { reduceConstraints: false });
const circuit = new snarkjs.Circuit(cirDef); const circuit = new snarkjs.Circuit(cirDef);
console.log("Vars: "+circuit.nVars); console.log("Vars: " + circuit.nVars);
console.log("Constraints: "+circuit.nConstraints); console.log("Constraints: " + circuit.nConstraints);
/* /*
const testStr = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; const testStr = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
const b = Buffer.from(testStr, 'utf8'); const b = Buffer.from(testStr, 'utf8');
*/ */
const b = new Buffer.alloc(64); const b = new Buffer.alloc(64);
for (let i=0; i<64; i++) { for (let i = 0; i < 64; i++) {
b[i] = i+1; b[i] = i + 1;
} }
const hash = crypto.createHash("sha256") const hash = crypto.createHash("sha256").update(b).digest("hex");
.update(b)
.digest("hex");
const arrIn = buffer2bitArray(b); const arrIn = buffer2bitArray(b);
const witness = circuit.calculateWitness({ "in": arrIn } /*, {logOutput: true} */); const witness = circuit.calculateWitness({ in: arrIn } /*, {logOutput: true} */);
const arrOut = witness.slice(1, 257); const arrOut = witness.slice(1, 257);
const hash2 = bitArray2buffer(arrOut).toString("hex"); const hash2 = bitArray2buffer(arrOut).toString("hex");
assert.equal(hash, hash2); assert.equal(hash, hash2);
}).timeout(1000000); }).timeout(1000000);
it("Should calculate a hash of 2 compressor", async () => { it("Should calculate a hash of 2 compressor", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "sha256_test448.circom"), {reduceConstraints:false} ); const cirDef = await compiler(path.join(__dirname, "circuits", "sha256_test448.circom"), { reduceConstraints: false });
const circuit = new snarkjs.Circuit(cirDef); const circuit = new snarkjs.Circuit(cirDef);
console.log("Vars: "+circuit.nVars); console.log("Vars: " + circuit.nVars);
console.log("Constraints: "+circuit.nConstraints); console.log("Constraints: " + circuit.nConstraints);
const testStr = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; const testStr = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
const b = Buffer.from(testStr, 'utf8'); const b = Buffer.from(testStr, "utf8");
for (let i=0; i<64; i++) { for (let i = 0; i < 64; i++) {
b[i] = i+1; b[i] = i + 1;
} }
const hash = crypto.createHash("sha256") const hash = crypto.createHash("sha256").update(b).digest("hex");
.update(b)
.digest("hex");
const arrIn = buffer2bitArray(b); const arrIn = buffer2bitArray(b);
const witness = circuit.calculateWitness({ "in": arrIn } /*, {logOutput: true} */); const witness = circuit.calculateWitness({ in: arrIn } /*, {logOutput: true} */);
const arrOut = witness.slice(1, 257); const arrOut = witness.slice(1, 257);
const hash2 = bitArray2buffer(arrOut).toString("hex"); const hash2 = bitArray2buffer(arrOut).toString("hex");
assert.equal(hash, hash2); assert.equal(hash, hash2);
}).timeout(1000000); }).timeout(1000000);
}); });

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const assert = chai.assert; const assert = chai.assert;
@ -13,7 +13,7 @@ function print(circuit, w, s) {
function getBits(v, n) { function getBits(v, n) {
const res = []; const res = [];
for (let i=0; i<n; i++) { for (let i = 0; i < n; i++) {
if (v.shr(i).isOdd()) { if (v.shr(i).isOdd()) {
res.push(bigInt.one); res.push(bigInt.one);
} else { } else {
@ -27,7 +27,7 @@ const q = bigInt("21888242871839275222246405745257275088548364400416034343698204
describe("Sign test", () => { describe("Sign test", () => {
let circuit; let circuit;
before( async() => { before(async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "sign_test.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "sign_test.circom"));
circuit = new snarkjs.Circuit(cirDef); circuit = new snarkjs.Circuit(cirDef);
@ -37,52 +37,50 @@ describe("Sign test", () => {
it("Sign of 0", async () => { it("Sign of 0", async () => {
const inp = getBits(bigInt.zero, 254); const inp = getBits(bigInt.zero, 254);
const w = circuit.calculateWitness({in: inp}); const w = circuit.calculateWitness({ in: inp });
assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(0)) ); assert(w[circuit.getSignalIdx("main.sign")].equals(bigInt(0)));
}); });
it("Sign of 3", async () => { it("Sign of 3", async () => {
const inp = getBits(bigInt(3), 254); const inp = getBits(bigInt(3), 254);
const w = circuit.calculateWitness({in: inp}); const w = circuit.calculateWitness({ in: inp });
assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(0)) ); assert(w[circuit.getSignalIdx("main.sign")].equals(bigInt(0)));
}); });
it("Sign of q/2", async () => { it("Sign of q/2", async () => {
const inp = getBits(q.shr(bigInt.one), 254); const inp = getBits(q.shr(bigInt.one), 254);
const w = circuit.calculateWitness({in: inp}); const w = circuit.calculateWitness({ in: inp });
assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(0)) ); assert(w[circuit.getSignalIdx("main.sign")].equals(bigInt(0)));
}); });
it("Sign of q/2+1", async () => { it("Sign of q/2+1", async () => {
const inp = getBits(q.shr(bigInt.one).add(bigInt.one), 254); const inp = getBits(q.shr(bigInt.one).add(bigInt.one), 254);
const w = circuit.calculateWitness({in: inp}); const w = circuit.calculateWitness({ in: inp });
assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)) ); assert(w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)));
}); });
it("Sign of q-1", async () => { it("Sign of q-1", async () => {
const inp = getBits(q.sub(bigInt.one), 254); const inp = getBits(q.sub(bigInt.one), 254);
const w = circuit.calculateWitness({in: inp}); const w = circuit.calculateWitness({ in: inp });
assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)) ); assert(w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)));
}); });
it("Sign of q", async () => { it("Sign of q", async () => {
const inp = getBits(q, 254); const inp = getBits(q, 254);
const w = circuit.calculateWitness({in: inp}); const w = circuit.calculateWitness({ in: inp });
assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)) ); assert(w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)));
}); });
it("Sign of all ones", async () => { it("Sign of all ones", async () => {
const inp = getBits(bigInt(1).shl(254).sub(bigInt(1)), 254); const inp = getBits(bigInt(1).shl(254).sub(bigInt(1)), 254);
const w = circuit.calculateWitness({in: inp}); const w = circuit.calculateWitness({ in: inp });
assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)) ); assert(w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)));
}); });
}); });

@ -1,5 +1,5 @@
const chai = require("chai"); const chai = require("chai");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const smt = require("../src/smt.js"); const smt = require("../src/smt.js");
@ -7,9 +7,8 @@ const assert = chai.assert;
const bigInt = snarkjs.bigInt; const bigInt = snarkjs.bigInt;
function stringifyBigInts(o) { function stringifyBigInts(o) {
if ((typeof(o) == "bigint") || (o instanceof bigInt)) { if (typeof o == "bigint" || o instanceof bigInt) {
return o.toString(10); return o.toString(10);
} else if (Array.isArray(o)) { } else if (Array.isArray(o)) {
return o.map(stringifyBigInts); return o.map(stringifyBigInts);
@ -26,8 +25,7 @@ function stringifyBigInts(o) {
describe("SMT Javascript test", function () { describe("SMT Javascript test", function () {
this.timeout(100000); this.timeout(100000);
before( async () => { before(async () => {});
});
it("Should insert 2 elements and empty them", async () => { it("Should insert 2 elements and empty them", async () => {
const tree = await smt.newMemEmptyTrie(); const tree = await smt.newMemEmptyTrie();
@ -36,8 +34,8 @@ describe("SMT Javascript test", function () {
const key2 = bigInt(333); const key2 = bigInt(333);
const value2 = bigInt(444); const value2 = bigInt(444);
await tree.insert(key1,value1); await tree.insert(key1, value1);
await tree.insert(key2,value2); await tree.insert(key2, value2);
await tree.delete(key2); await tree.delete(key2);
await tree.delete(key1); await tree.delete(key1);
@ -54,29 +52,29 @@ describe("SMT Javascript test", function () {
const tree5 = await smt.newMemEmptyTrie(); const tree5 = await smt.newMemEmptyTrie();
const tree6 = await smt.newMemEmptyTrie(); const tree6 = await smt.newMemEmptyTrie();
await tree1.insert(keys[0],values[0]); await tree1.insert(keys[0], values[0]);
await tree1.insert(keys[1],values[1]); await tree1.insert(keys[1], values[1]);
await tree1.insert(keys[2],values[2]); await tree1.insert(keys[2], values[2]);
await tree2.insert(keys[0],values[0]); await tree2.insert(keys[0], values[0]);
await tree2.insert(keys[2],values[2]); await tree2.insert(keys[2], values[2]);
await tree2.insert(keys[1],values[1]); await tree2.insert(keys[1], values[1]);
await tree3.insert(keys[1],values[1]); await tree3.insert(keys[1], values[1]);
await tree3.insert(keys[0],values[0]); await tree3.insert(keys[0], values[0]);
await tree3.insert(keys[2],values[2]); await tree3.insert(keys[2], values[2]);
await tree4.insert(keys[1],values[1]); await tree4.insert(keys[1], values[1]);
await tree4.insert(keys[2],values[2]); await tree4.insert(keys[2], values[2]);
await tree4.insert(keys[0],values[0]); await tree4.insert(keys[0], values[0]);
await tree5.insert(keys[2],values[2]); await tree5.insert(keys[2], values[2]);
await tree5.insert(keys[0],values[0]); await tree5.insert(keys[0], values[0]);
await tree5.insert(keys[1],values[1]); await tree5.insert(keys[1], values[1]);
await tree6.insert(keys[2],values[2]); await tree6.insert(keys[2], values[2]);
await tree6.insert(keys[1],values[1]); await tree6.insert(keys[1], values[1]);
await tree6.insert(keys[0],values[0]); await tree6.insert(keys[0], values[0]);
assert(tree1.root.equals(tree2.root)); assert(tree1.root.equals(tree2.root));
assert(tree2.root.equals(tree3.root)); assert(tree2.root.equals(tree3.root));
@ -134,7 +132,7 @@ describe("SMT Javascript test", function () {
function perm(a) { function perm(a) {
const arr = a.slice(); const arr = a.slice();
const rArr = []; const rArr = [];
for (let i=0; i<arr.length; i++) { for (let i = 0; i < arr.length; i++) {
let rIdx = Math.floor(Math.random() * (arr.length - i)); let rIdx = Math.floor(Math.random() * (arr.length - i));
rArr.push(arr[rIdx]); rArr.push(arr[rIdx]);
arr[rIdx] = arr[arr.length - i - 1]; arr[rIdx] = arr[arr.length - i - 1];
@ -144,15 +142,15 @@ describe("SMT Javascript test", function () {
const tree = await smt.newMemEmptyTrie(); const tree = await smt.newMemEmptyTrie();
const arr = []; const arr = [];
const N = 100; const N = 100;
for (let i=0; i<N; i++) { for (let i = 0; i < N; i++) {
arr.push(bigInt(i)); arr.push(bigInt(i));
} }
const insArr = perm(arr); const insArr = perm(arr);
for (let i=0; i<N; i++) { for (let i = 0; i < N; i++) {
await tree.insert(insArr[i], i); await tree.insert(insArr[i], i);
} }
const delArr = perm(insArr); const delArr = perm(insArr);
for (let i=0; i<N; i++) { for (let i = 0; i < N; i++) {
await tree.delete(delArr[i]); await tree.delete(delArr[i]);
} }
@ -164,13 +162,13 @@ describe("SMT Javascript test", function () {
const tree1 = await smt.newMemEmptyTrie(); const tree1 = await smt.newMemEmptyTrie();
const tree2 = await smt.newMemEmptyTrie(); const tree2 = await smt.newMemEmptyTrie();
await tree1.insert(8,88); await tree1.insert(8, 88);
await tree1.insert(9,99,); await tree1.insert(9, 99);
await tree1.insert(32,3232); await tree1.insert(32, 3232);
await tree2.insert(8,888); await tree2.insert(8, 888);
await tree2.insert(9,999); await tree2.insert(9, 999);
await tree2.insert(32,323232); await tree2.insert(32, 323232);
await tree1.update(8, 888); await tree1.update(8, 888);
await tree1.update(9, 999); await tree1.update(9, 999);
@ -178,5 +176,4 @@ describe("SMT Javascript test", function () {
assert(tree1.root.equals(tree2.root)); assert(tree1.root.equals(tree2.root));
}); });
}); });

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const smt = require("../src/smt.js"); const smt = require("../src/smt.js");
@ -13,22 +13,24 @@ function print(circuit, w, s) {
console.log(s + ": " + w[circuit.getSignalIdx(s)]); console.log(s + ": " + w[circuit.getSignalIdx(s)]);
} }
async function testInsert(tree, key, value, circuit, log ) { async function testInsert(tree, key, value, circuit, log) {
const res = await tree.insert(key, value);
const res = await tree.insert(key,value);
let siblings = res.siblings; let siblings = res.siblings;
while (siblings.length<10) siblings.push(bigInt(0)); while (siblings.length < 10) siblings.push(bigInt(0));
const w = circuit.calculateWitness({ const w = circuit.calculateWitness(
fnc: [1,0], {
fnc: [1, 0],
oldRoot: res.oldRoot, oldRoot: res.oldRoot,
siblings: siblings, siblings: siblings,
oldKey: res.isOld0 ? 0 : res.oldKey, oldKey: res.isOld0 ? 0 : res.oldKey,
oldValue: res.isOld0 ? 0 : res.oldValue, oldValue: res.isOld0 ? 0 : res.oldValue,
isOld0: res.isOld0 ? 1 : 0, isOld0: res.isOld0 ? 1 : 0,
newKey: key, newKey: key,
newValue: value newValue: value,
}, log); },
log
);
const root1 = w[circuit.getSignalIdx("main.newRoot")]; const root1 = w[circuit.getSignalIdx("main.newRoot")];
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
@ -38,17 +40,17 @@ async function testInsert(tree, key, value, circuit, log ) {
async function testDelete(tree, key, circuit) { async function testDelete(tree, key, circuit) {
const res = await tree.delete(key); const res = await tree.delete(key);
let siblings = res.siblings; let siblings = res.siblings;
while (siblings.length<10) siblings.push(bigInt(0)); while (siblings.length < 10) siblings.push(bigInt(0));
const w = circuit.calculateWitness({ const w = circuit.calculateWitness({
fnc: [1,1], fnc: [1, 1],
oldRoot: res.oldRoot, oldRoot: res.oldRoot,
siblings: siblings, siblings: siblings,
oldKey: res.isOld0 ? 0 : res.oldKey, oldKey: res.isOld0 ? 0 : res.oldKey,
oldValue: res.isOld0 ? 0 : res.oldValue, oldValue: res.isOld0 ? 0 : res.oldValue,
isOld0: res.isOld0 ? 1 : 0, isOld0: res.isOld0 ? 1 : 0,
newKey: res.delKey, newKey: res.delKey,
newValue: res.delValue newValue: res.delValue,
}); });
const root1 = w[circuit.getSignalIdx("main.newRoot")]; const root1 = w[circuit.getSignalIdx("main.newRoot")];
@ -60,17 +62,17 @@ async function testDelete(tree, key, circuit) {
async function testUpdate(tree, key, newValue, circuit) { async function testUpdate(tree, key, newValue, circuit) {
const res = await tree.update(key, newValue); const res = await tree.update(key, newValue);
let siblings = res.siblings; let siblings = res.siblings;
while (siblings.length<10) siblings.push(bigInt(0)); while (siblings.length < 10) siblings.push(bigInt(0));
const w = circuit.calculateWitness({ const w = circuit.calculateWitness({
fnc: [0,1], fnc: [0, 1],
oldRoot: res.oldRoot, oldRoot: res.oldRoot,
siblings: siblings, siblings: siblings,
oldKey: res.oldKey, oldKey: res.oldKey,
oldValue: res.oldValue, oldValue: res.oldValue,
isOld0: 0, isOld0: 0,
newKey: res.newKey, newKey: res.newKey,
newValue: res.newValue newValue: res.newValue,
}); });
const root1 = w[circuit.getSignalIdx("main.newRoot")]; const root1 = w[circuit.getSignalIdx("main.newRoot")];
@ -79,14 +81,13 @@ async function testUpdate(tree, key, newValue, circuit) {
assert(root1.equals(res.newRoot)); assert(root1.equals(res.newRoot));
} }
describe("SMT test", function () { describe("SMT test", function () {
let circuit; let circuit;
let tree; let tree;
this.timeout(10000000); this.timeout(10000000);
before( async () => { before(async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "smtprocessor10_test.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "smtprocessor10_test.circom"));
circuit = new snarkjs.Circuit(cirDef); circuit = new snarkjs.Circuit(cirDef);
@ -110,8 +111,6 @@ describe("SMT test", function () {
await testInsert(tree, key, value, circuit); await testInsert(tree, key, value, circuit);
}); });
it("Should remove an element", async () => { it("Should remove an element", async () => {
await testDelete(tree, 111, circuit); await testDelete(tree, 111, circuit);
await testDelete(tree, 333, circuit); await testDelete(tree, 333, circuit);
@ -127,30 +126,29 @@ describe("SMT test", function () {
const tree5 = await smt.newMemEmptyTrie(); const tree5 = await smt.newMemEmptyTrie();
const tree6 = await smt.newMemEmptyTrie(); const tree6 = await smt.newMemEmptyTrie();
await testInsert(tree1,keys[0],values[0], circuit); await testInsert(tree1, keys[0], values[0], circuit);
await testInsert(tree1,keys[1],values[1], circuit); await testInsert(tree1, keys[1], values[1], circuit);
await testInsert(tree1,keys[2],values[2], circuit); await testInsert(tree1, keys[2], values[2], circuit);
await testInsert(tree2,keys[0],values[0], circuit); await testInsert(tree2, keys[0], values[0], circuit);
await testInsert(tree2,keys[2],values[2], circuit); await testInsert(tree2, keys[2], values[2], circuit);
await testInsert(tree2,keys[1],values[1], circuit); await testInsert(tree2, keys[1], values[1], circuit);
await testInsert(tree3,keys[1],values[1], circuit); await testInsert(tree3, keys[1], values[1], circuit);
await testInsert(tree3,keys[0],values[0], circuit); await testInsert(tree3, keys[0], values[0], circuit);
await testInsert(tree3,keys[2],values[2], circuit); await testInsert(tree3, keys[2], values[2], circuit);
await testInsert(tree4,keys[1],values[1], circuit); await testInsert(tree4, keys[1], values[1], circuit);
await testInsert(tree4,keys[2],values[2], circuit); await testInsert(tree4, keys[2], values[2], circuit);
await testInsert(tree4,keys[0],values[0], circuit); await testInsert(tree4, keys[0], values[0], circuit);
await testInsert(tree5,keys[2],values[2], circuit); await testInsert(tree5, keys[2], values[2], circuit);
await testInsert(tree5,keys[0],values[0], circuit); await testInsert(tree5, keys[0], values[0], circuit);
await testInsert(tree5,keys[1],values[1], circuit); await testInsert(tree5, keys[1], values[1], circuit);
await testInsert(tree6,keys[2],values[2], circuit);
await testInsert(tree6,keys[1],values[1], circuit);
await testInsert(tree6,keys[0],values[0], circuit);
await testInsert(tree6, keys[2], values[2], circuit);
await testInsert(tree6, keys[1], values[1], circuit);
await testInsert(tree6, keys[0], values[0], circuit);
await testDelete(tree1, keys[0], circuit); await testDelete(tree1, keys[0], circuit);
await testDelete(tree1, keys[1], circuit); await testDelete(tree1, keys[1], circuit);
@ -162,7 +160,6 @@ describe("SMT test", function () {
await testDelete(tree4, keys[2], circuit); await testDelete(tree4, keys[2], circuit);
await testDelete(tree4, keys[0], circuit); await testDelete(tree4, keys[0], circuit);
await testDelete(tree5, keys[1], circuit); await testDelete(tree5, keys[1], circuit);
await testDelete(tree5, keys[2], circuit); await testDelete(tree5, keys[2], circuit);
await testDelete(tree6, keys[2], circuit); await testDelete(tree6, keys[2], circuit);
@ -178,16 +175,16 @@ describe("SMT test", function () {
it("Should match a NOp with random vals", async () => { it("Should match a NOp with random vals", async () => {
let siblings = []; let siblings = [];
while (siblings.length<10) siblings.push(bigInt(88)); while (siblings.length < 10) siblings.push(bigInt(88));
const w = circuit.calculateWitness({ const w = circuit.calculateWitness({
fnc: [0,0], fnc: [0, 0],
oldRoot: 11, oldRoot: 11,
siblings: siblings, siblings: siblings,
oldKey: 33, oldKey: 33,
oldValue: 44, oldValue: 44,
isOld0: 55, isOld0: 55,
newKey: 66, newKey: 66,
newValue: 77 newValue: 77,
}); });
const root1 = w[circuit.getSignalIdx("main.oldRoot")]; const root1 = w[circuit.getSignalIdx("main.oldRoot")];
@ -195,23 +192,21 @@ describe("SMT test", function () {
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
assert(root1.equals(root2)); assert(root1.equals(root2));
}); });
it("Should update an element", async () => { it("Should update an element", async () => {
const tree1 = await smt.newMemEmptyTrie(); const tree1 = await smt.newMemEmptyTrie();
const tree2 = await smt.newMemEmptyTrie(); const tree2 = await smt.newMemEmptyTrie();
await testInsert(tree1,8,88, circuit); await testInsert(tree1, 8, 88, circuit);
await testInsert(tree1,9,99, circuit); await testInsert(tree1, 9, 99, circuit);
await testInsert(tree1,32,3232, circuit); await testInsert(tree1, 32, 3232, circuit);
await testInsert(tree2,8,888, circuit); await testInsert(tree2, 8, 888, circuit);
await testInsert(tree2,9,999, circuit); await testInsert(tree2, 9, 999, circuit);
await testInsert(tree2,32,323232, circuit); await testInsert(tree2, 32, 323232, circuit);
await testUpdate(tree1, 8, 888, circuit); await testUpdate(tree1, 8, 888, circuit);
await testUpdate(tree1, 9, 999, circuit); await testUpdate(tree1, 9, 999, circuit);
await testUpdate(tree1, 32, 323232, circuit); await testUpdate(tree1, 32, 323232, circuit);
}); });
}); });

@ -1,6 +1,6 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const smt = require("../src/smt.js"); const smt = require("../src/smt.js");
@ -14,12 +14,11 @@ function print(circuit, w, s) {
} }
async function testInclusion(tree, key, circuit) { async function testInclusion(tree, key, circuit) {
const res = await tree.find(key); const res = await tree.find(key);
assert(res.found); assert(res.found);
let siblings = res.siblings; let siblings = res.siblings;
while (siblings.length<10) siblings.push(bigInt(0)); while (siblings.length < 10) siblings.push(bigInt(0));
const w = circuit.calculateWitness({ const w = circuit.calculateWitness({
enabled: 1, enabled: 1,
@ -30,7 +29,7 @@ async function testInclusion(tree, key, circuit) {
oldValue: 0, oldValue: 0,
isOld0: 0, isOld0: 0,
key: key, key: key,
value: res.foundValue value: res.foundValue,
}); });
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
@ -41,7 +40,7 @@ async function testExclusion(tree, key, circuit) {
assert(!res.found); assert(!res.found);
let siblings = res.siblings; let siblings = res.siblings;
while (siblings.length<10) siblings.push(bigInt(0)); while (siblings.length < 10) siblings.push(bigInt(0));
const w = circuit.calculateWitness({ const w = circuit.calculateWitness({
enabled: 1, enabled: 1,
@ -52,7 +51,7 @@ async function testExclusion(tree, key, circuit) {
oldValue: res.isOld0 ? 0 : res.notFoundValue, oldValue: res.isOld0 ? 0 : res.notFoundValue,
isOld0: res.isOld0 ? 1 : 0, isOld0: res.isOld0 ? 1 : 0,
key: key, key: key,
value: 0 value: 0,
}); });
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
@ -64,7 +63,7 @@ describe("SMT test", function () {
this.timeout(100000); this.timeout(100000);
before( async () => { before(async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "smtverifier10_test.circom")); const cirDef = await compiler(path.join(__dirname, "circuits", "smtverifier10_test.circom"));
circuit = new snarkjs.Circuit(cirDef); circuit = new snarkjs.Circuit(cirDef);
@ -72,9 +71,9 @@ describe("SMT test", function () {
console.log("NConstrains SMTVerifier: " + circuit.nConstraints); console.log("NConstrains SMTVerifier: " + circuit.nConstraints);
tree = await smt.newMemEmptyTrie(); tree = await smt.newMemEmptyTrie();
await tree.insert(7,77); await tree.insert(7, 77);
await tree.insert(8,88); await tree.insert(8, 88);
await tree.insert(32,3232); await tree.insert(32, 3232);
}); });
it("Check inclussion in a tree of 3", async () => { it("Check inclussion in a tree of 3", async () => {
@ -95,7 +94,7 @@ describe("SMT test", function () {
it("Check not enabled accepts any thing", async () => { it("Check not enabled accepts any thing", async () => {
let siblings = []; let siblings = [];
for (let i=0; i<10; i++) siblings.push(i); for (let i = 0; i < 10; i++) siblings.push(i);
const w = circuit.calculateWitness({ const w = circuit.calculateWitness({
enabled: 0, enabled: 0,
@ -106,33 +105,31 @@ describe("SMT test", function () {
oldValue: 33, oldValue: 33,
isOld0: 0, isOld0: 0,
key: 44, key: 44,
value: 0 value: 0,
}); });
assert(circuit.checkWitness(w)); assert(circuit.checkWitness(w));
}); });
it("Check inclussion Adria case", async () => { it("Check inclussion Adria case", async () => {
const e1_hi= bigInt("17124152697573569611556136390143205198134245887034837071647643529178599000839"); const e1_hi = bigInt("17124152697573569611556136390143205198134245887034837071647643529178599000839");
const e1_hv= bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179"); const e1_hv = bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179");
const e2ok_hi= bigInt("16498254692537945203721083102154618658340563351558973077349594629411025251262"); const e2ok_hi = bigInt("16498254692537945203721083102154618658340563351558973077349594629411025251262");
const e2ok_hv= bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179"); const e2ok_hv = bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179");
const e2fail_hi= bigInt("17195092312975762537892237130737365903429674363577646686847513978084990105579"); const e2fail_hi = bigInt("17195092312975762537892237130737365903429674363577646686847513978084990105579");
const e2fail_hv= bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179"); const e2fail_hv = bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179");
const tree1 = await smt.newMemEmptyTrie(); const tree1 = await smt.newMemEmptyTrie();
await tree1.insert(e1_hi,e1_hv); await tree1.insert(e1_hi, e1_hv);
await tree1.insert(e2ok_hi,e2ok_hv); await tree1.insert(e2ok_hi, e2ok_hv);
await testInclusion(tree1, e2ok_hi, circuit); await testInclusion(tree1, e2ok_hi, circuit);
const tree2 = await smt.newMemEmptyTrie(); const tree2 = await smt.newMemEmptyTrie();
await tree2.insert(e1_hi,e1_hv); await tree2.insert(e1_hi, e1_hv);
await tree2.insert(e2fail_hi,e2fail_hv); await tree2.insert(e2fail_hi, e2fail_hv);
await testInclusion(tree2, e2fail_hi, circuit); await testInclusion(tree2, e2fail_hi, circuit);
}); });
}); });

@ -1,7 +1,7 @@
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("@tornado/snarkjs");
const compiler = require("circom"); const compiler = require("circom");
const fs = require("fs") const fs = require("fs");
const bigInt = snarkjs.bigInt; const bigInt = snarkjs.bigInt;
const smt = require("../src/smt.js"); const smt = require("../src/smt.js");
@ -36,9 +36,9 @@ describe("smt3test", function () {
let circuitFileName; let circuitFileName;
before( async () => { before(async () => {
circuitFileName = path.join(__dirname, ".", "rawsmt3.circom"); circuitFileName = path.join(__dirname, ".", "rawsmt3.circom");
fs.writeFileSync(circuitFileName,circuitSource); fs.writeFileSync(circuitFileName, circuitSource);
}); });
const levels = 4; const levels = 4;
@ -61,10 +61,7 @@ describe("smt3test", function () {
hv: e1.hv, hv: e1.hv,
}; };
const compiledCircuit = await compiler( const compiledCircuit = await compiler(circuitFileName, { reduceConstraints: false });
circuitFileName,
{ reduceConstraints: false }
);
const circuit = new snarkjs.Circuit(compiledCircuit); const circuit = new snarkjs.Circuit(compiledCircuit);
const witness = circuit.calculateWitness(input); const witness = circuit.calculateWitness(input);
@ -72,7 +69,6 @@ describe("smt3test", function () {
} }
it("TestSmts", async () => { it("TestSmts", async () => {
const e1 = { const e1 = {
hi: bigInt("17124152697573569611556136390143205198134245887034837071647643529178599000839"), hi: bigInt("17124152697573569611556136390143205198134245887034837071647643529178599000839"),
hv: bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179"), hv: bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179"),
@ -95,4 +91,3 @@ describe("smt3test", function () {
await testsmt3(e1, e2fail); await testsmt3(e1, e2fail);
}); });
}); });