Skip to content

Commit

Permalink
pedersen working
Browse files Browse the repository at this point in the history
  • Loading branch information
jbaylina committed Dec 13, 2019
1 parent b4cd388 commit 4117ebc
Show file tree
Hide file tree
Showing 20 changed files with 70,521 additions and 292 deletions.
6 changes: 4 additions & 2 deletions circuits/binsub.circom
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,14 @@ template BinSub(n) {
var lin = 2**n;
var lout = 0;

for (var i=0; i<n; i++) {
var i;

for (i=0; i<n; i++) {
lin = lin + in[0][i]*(2**i);
lin = lin - in[1][i]*(2**i);
}

for (var i=0; i<n; i++) {
for (i=0; i<n; i++) {
out[i] <-- (lin >> i) & 1;

// Ensure out is binary
Expand Down
62 changes: 32 additions & 30 deletions src/eddsa.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
const createBlakeHash = require("blake-hash");
const bigInt = require("snarkjs").bigInt;
const bigInt = require("big-integer");
const babyJub = require("./babyjub");
const utils = require("./utils");
const pedersenHash = require("./pedersenHash").hash;
const mimc7 = require("./mimc7");
const poseidon = require("./poseidon.js");
const mimcsponge = require("./mimcsponge");


exports.prv2pub= prv2pub;
exports.sign = sign;
exports.signMiMC = signMiMC;
Expand All @@ -30,26 +32,26 @@ function pruneBuffer(_buff) {

function prv2pub(prv) {
const sBuff = pruneBuffer(createBlakeHash("blake512").update(prv).digest().slice(0,32));
let s = bigInt.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
let s = utils.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shiftRight(3));
return A;
}

function sign(prv, msg) {
const h1 = createBlakeHash("blake512").update(prv).digest();
const sBuff = pruneBuffer(h1.slice(0,32));
const s = bigInt.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
const s = utils.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shiftRight(3));

const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msg])).digest();
let r = bigInt.leBuff2int(rBuff);
let r = utils.leBuff2int(rBuff);
r = r.mod(babyJub.subOrder);
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
const R8p = babyJub.packPoint(R8);
const Ap = babyJub.packPoint(A);
const hmBuff = pedersenHash(Buffer.concat([R8p, Ap, msg]));
const hm = bigInt.leBuff2int(hmBuff);
const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
const hm = utils.leBuff2int(hmBuff);
const S = r.add(hm.times(s)).mod(babyJub.subOrder);
return {
R8: R8,
S: S
Expand All @@ -59,16 +61,16 @@ function sign(prv, msg) {
function signMiMC(prv, msg) {
const h1 = createBlakeHash("blake512").update(prv).digest();
const sBuff = pruneBuffer(h1.slice(0,32));
const s = bigInt.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
const s = utils.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shiftRight(3));

const msgBuff = bigInt.leInt2Buff(msg, 32);
const msgBuff = utils.leInt2Buff(msg, 32);
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
let r = bigInt.leBuff2int(rBuff);
let r = utils.leBuff2int(rBuff);
r = r.mod(babyJub.subOrder);
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
const hm = mimc7.multiHash([R8[0], R8[1], A[0], A[1], msg]);
const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
const S = r.add(hm.times(s)).mod(babyJub.subOrder);
return {
R8: R8,
S: S
Expand All @@ -78,16 +80,16 @@ function signMiMC(prv, msg) {
function signMiMCSponge(prv, msg) {
const h1 = createBlakeHash("blake512").update(prv).digest();
const sBuff = pruneBuffer(h1.slice(0,32));
const s = bigInt.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
const s = utils.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shiftRight(3));

const msgBuff = bigInt.leInt2Buff(msg, 32);
const msgBuff = utils.leInt2Buff(msg, 32);
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
let r = bigInt.leBuff2int(rBuff);
let r = utils.leBuff2int(rBuff);
r = r.mod(babyJub.subOrder);
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
const hm = mimcsponge.multiHash([R8[0], R8[1], A[0], A[1], msg]);
const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
const S = r.add(hm.times(s)).mod(babyJub.subOrder);
return {
R8: R8,
S: S
Expand All @@ -97,17 +99,17 @@ function signMiMCSponge(prv, msg) {
function signPoseidon(prv, msg) {
const h1 = createBlakeHash("blake512").update(prv).digest();
const sBuff = pruneBuffer(h1.slice(0,32));
const s = bigInt.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
const s = utils.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shiftRight(3));

const msgBuff = bigInt.leInt2Buff(msg, 32);
const msgBuff = utils.leInt2Buff(msg, 32);
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
let r = bigInt.leBuff2int(rBuff);
let r = utils.leBuff2int(rBuff);
r = r.mod(babyJub.subOrder);
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
const hash = poseidon.createHash(6, 8, 57);
const hm = hash([R8[0], R8[1], A[0], A[1], msg]);
const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
const S = r.add(hm.times(s)).mod(babyJub.subOrder);
return {
R8: R8,
S: S
Expand All @@ -128,10 +130,10 @@ function verify(msg, sig, A) {
const R8p = babyJub.packPoint(sig.R8);
const Ap = babyJub.packPoint(A);
const hmBuff = pedersenHash(Buffer.concat([R8p, Ap, msg]));
const hm = bigInt.leBuff2int(hmBuff);
const hm = utils.leBuff2int(hmBuff);

const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
let Pright = babyJub.mulPointEscalar(A, hm.times(bigInt("8")));
Pright = babyJub.addPoint(sig.R8, Pright);

if (!Pleft[0].equals(Pright[0])) return false;
Expand All @@ -153,7 +155,7 @@ function verifyMiMC(msg, sig, A) {
const hm = mimc7.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);

const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
let Pright = babyJub.mulPointEscalar(A, hm.times(bigInt("8")));
Pright = babyJub.addPoint(sig.R8, Pright);

if (!Pleft[0].equals(Pright[0])) return false;
Expand All @@ -177,7 +179,7 @@ function verifyPoseidon(msg, sig, A) {
const hm = hash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);

const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
let Pright = babyJub.mulPointEscalar(A, hm.times(bigInt("8")));
Pright = babyJub.addPoint(sig.R8, Pright);

if (!Pleft[0].equals(Pright[0])) return false;
Expand All @@ -199,7 +201,7 @@ function verifyMiMCSponge(msg, sig, A) {
const hm = mimcsponge.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);

const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
let Pright = babyJub.mulPointEscalar(A, hm.times(bigInt("8")));
Pright = babyJub.addPoint(sig.R8, Pright);

if (!Pleft[0].equals(Pright[0])) return false;
Expand All @@ -209,14 +211,14 @@ function verifyMiMCSponge(msg, sig, A) {

function packSignature(sig) {
const R8p = babyJub.packPoint(sig.R8);
const Sp = bigInt.leInt2Buff(sig.S, 32);
const Sp = utils.leInt2Buff(sig.S, 32);
return Buffer.concat([R8p, Sp]);
}

function unpackSignature(sigBuff) {
return {
R8: babyJub.unpackPoint(sigBuff.slice(0,32)),
S: bigInt.leBuff2int(sigBuff.slice(32,64))
S: utils.leBuff2int(sigBuff.slice(32,64))
};
}

Expand Down
17 changes: 9 additions & 8 deletions src/mimc7.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const bn128 = require("snarkjs").bn128;
const bigInt = require("snarkjs").bigInt;
const bigInt = require("big-integer");
const ZqField = require("fflib").ZqField;

const Web3Utils = require("web3-utils");
const F = bn128.Fr;
const F = new ZqField(bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"));

const SEED = "mimc";
const NROUNDS = 91;
Expand All @@ -10,7 +11,7 @@ exports.getIV = (seed) => {
if (typeof seed === "undefined") seed = SEED;
const c = Web3Utils.keccak256(seed+"_iv");
const cn = bigInt(Web3Utils.toBN(c).toString());
const iv = cn.mod(F.q);
const iv = cn.mod(F.p);
return iv;
};

Expand All @@ -22,7 +23,7 @@ exports.getConstants = (seed, nRounds) => {
for (let i=1; i<nRounds; i++) {
c = Web3Utils.keccak256(c);

const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.q.toString()));
const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.p.toString()));
const c2 = Web3Utils.padLeft(Web3Utils.toHex(n1), 64);
cts[i] = bigInt(Web3Utils.toBN(c2).toString());
}
Expand All @@ -39,9 +40,9 @@ exports.hash = (_x_in, _k) =>{
for (let i=0; i<NROUNDS; i++) {
const c = cts[i];
const t = (i==0) ? F.add(x_in, k) : F.add(F.add(r, k), c);
r = F.exp(t, 7);
r = F.pow(t, 7);
}
return F.affine(F.add(r, k));
return F.add(r, k);
};

exports.multiHash = (arr, key) => {
Expand All @@ -60,5 +61,5 @@ exports.multiHash = (arr, key) => {
exports.hash(bigInt(arr[i]), r)
);
}
return F.affine(r);
return r;
};
3 changes: 1 addition & 2 deletions src/pedersenHash.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const bn128 = require("snarkjs").bn128;
const bigInt = require("snarkjs").bigInt;
const bigInt = require("big-integer");
const babyJub = require("./babyjub");
const createBlakeHash = require("blake-hash");

Expand Down
20 changes: 11 additions & 9 deletions src/poseidon.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
const bn128 = require("snarkjs").bn128;
const bigInt = require("snarkjs").bigInt;
const blake2b = require('blake2b');
const bigInt = require("big-integer");
const blake2b = require("blake2b");
const assert = require("assert");
const F = bn128.Fr;
const ZqField = require("fflib").ZqField;
const utils = require("./utils");

const F = new ZqField(bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"));

const SEED = "poseidon";
const NROUNDSF = 8;
Expand All @@ -12,11 +14,11 @@ const T = 6;
function getPseudoRandom(seed, n) {
const res = [];
let input = Buffer.from(seed);
let h = blake2b(32).update(input).digest()
let h = blake2b(32).update(input).digest();
while (res.length<n) {
const n = F.affine(bigInt.leBuff2int(h));
const n = F.normalize(utils.leBuff2int(h));
res.push(n);
h = blake2b(32).update(h).digest()
h = blake2b(32).update(h).digest();
}

return res;
Expand Down Expand Up @@ -48,7 +50,7 @@ exports.getMatrix = (t, seed, nRounds) => {
for (let i=0; i<t; i++) {
M[i] = new Array(t);
for (let j=0; j<t; j++) {
M[i][j] = F.affine(F.inverse(F.sub(cmatrix[i], cmatrix[t+j])));
M[i][j] = F.normalize(F.inverse(F.sub(cmatrix[i], cmatrix[t+j])));
}
}
return M;
Expand Down Expand Up @@ -109,7 +111,7 @@ exports.createHash = (t, nRoundsF, nRoundsP, seed) => {
}
mix(state, M);
}
return F.affine(state[0]);
return F.normalize(state[0]);
};
};

Expand Down
62 changes: 30 additions & 32 deletions test/binsub.js
Original file line number Diff line number Diff line change
@@ -1,55 +1,53 @@
const chai = require("chai");
const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");

const assert = chai.assert;

const bigInt = snarkjs.bigInt;
const bigInt = require("big-integer");
const tester = require("circom").tester;

function print(circuit, w, s) {
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
}

function checkSub(_a,_b, circuit) {
async function checkSub(_a,_b, circuit) {
let a=bigInt(_a);
let b=bigInt(_b);
if (a.lesser(bigInt.zero)) a = a.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});
if (a.lesser(bigInt.zero)) a = a.add(bigInt.one.shiftLeft(16));
if (b.lesser(bigInt.zero)) b = b.add(bigInt.one.shiftLeft(16));
const w = await circuit.calculateWitness({a: a, b: b});

let res = a.sub(b);
if (res.lesser(bigInt.zero)) res = res.add(bigInt.one.shl(16));
assert( w[circuit.getSignalIdx("main.out")].equals(bigInt(res)) );
let res = a.minus(b);
if (res.lesser(bigInt.zero)) res = res.add(bigInt.one.shiftLeft(16));
await circuit.assertOut(w, {out: bigInt(res)});
}

describe("BinSub test", () => {
let circuit;
before( async() => {
const cirDef = await compiler(path.join(__dirname, "circuits", "binsub_test.circom"));
describe("BinSub test", function () {

circuit = new snarkjs.Circuit(cirDef);
this.timeout(100000);

console.log("NConstrains BinSub: " + circuit.nConstraints);
let circuit;
before( async() => {
circuit = await tester(path.join(__dirname, "circuits", "binsub_test.circom"));
});

it("Should check variuos ege cases", async () => {
checkSub(0,0, circuit);
checkSub(1,0, circuit);
checkSub(-1,0, circuit);
checkSub(2,1, circuit);
checkSub(2,2, circuit);
checkSub(2,3, circuit);
checkSub(2,-1, circuit);
checkSub(2,-2, circuit);
checkSub(2,-3, circuit);
checkSub(-2,-3, circuit);
checkSub(-2,-2, circuit);
checkSub(-2,-1, circuit);
checkSub(-2,0, circuit);
checkSub(-2,1, circuit);
checkSub(-2,2, circuit);
checkSub(-2,3, circuit);
await checkSub(0,0, circuit);
await checkSub(1,0, circuit);
await checkSub(-1,0, circuit);
await checkSub(2,1, circuit);
await checkSub(2,2, circuit);
await checkSub(2,3, circuit);
await checkSub(2,-1, circuit);
await checkSub(2,-2, circuit);
await checkSub(2,-3, circuit);
await checkSub(-2,-3, circuit);
await checkSub(-2,-2, circuit);
await checkSub(-2,-1, circuit);
await checkSub(-2,0, circuit);
await checkSub(-2,1, circuit);
await checkSub(-2,2, circuit);
await checkSub(-2,3, circuit);
});


Expand Down
Loading

0 comments on commit 4117ebc

Please sign in to comment.