Merge branch 'c_build'

This commit is contained in:
Jordi Baylina
2020-03-26 19:52:34 +01:00
79 changed files with 4069 additions and 4581 deletions

View File

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

View File

@@ -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;
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
@@ -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;
@@ -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;
@@ -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;
@@ -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))
};
}

View File

@@ -1,7 +1,8 @@
const bn128 = require("snarkjs").bn128;
const bigInt = require("snarkjs").bigInt;
const bigInt = require("big-integer");
const ZqField = require("ffjavascript").ZqField;
const Web3Utils = require("web3-utils");
const F = bn128.Fr;
const F = new ZqField(bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
const SEED = "mimc";
const NROUNDS = 91;
@@ -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;
};
@@ -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());
}
@@ -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) => {
@@ -60,5 +61,5 @@ exports.multiHash = (arr, key) => {
exports.hash(bigInt(arr[i]), r)
);
}
return F.affine(r);
return r;
};

View File

@@ -1,7 +1,7 @@
const bn128 = require("snarkjs").bn128;
const bigInt = require("snarkjs").bigInt;
const bigInt = require("big-integer");
const Web3Utils = require("web3-utils");
const F = bn128.Fr;
const ZqField = require("ffjavascript").ZqField;
const F = new ZqField(bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
const SEED = "mimcsponge";
const NROUNDS = 220;
@@ -10,7 +10,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;
};
@@ -22,7 +22,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());
}
@@ -42,21 +42,21 @@ exports.hash = (_xL_in, _xR_in, _k) =>{
const t = (i==0) ? F.add(xL, k) : F.add(F.add(xL, k), c);
const xR_tmp = bigInt(xR);
if (i < (NROUNDS - 1)) {
xR = xL;
xL = F.add(xR_tmp, F.exp(t, 5));
xR = xL;
xL = F.add(xR_tmp, F.pow(t, 5));
} else {
xR = F.add(xR_tmp, F.exp(t, 5));
xR = F.add(xR_tmp, F.pow(t, 5));
}
}
return {
xL: F.affine(xL),
xR: F.affine(xR),
xL: F.normalize(xL),
xR: F.normalize(xR),
};
};
exports.multiHash = (arr, key, numOutputs) => {
if (typeof(numOutputs) === "undefined") {
numOutputs = 1;
numOutputs = 1;
}
if (typeof(key) === "undefined") {
key = F.zero;
@@ -66,21 +66,21 @@ exports.multiHash = (arr, key, numOutputs) => {
let C = F.zero;
for (let i=0; i<arr.length; i++) {
R = F.add(R, bigInt(arr[i]));
const S = exports.hash(R, C, key);
R = S.xL;
C = S.xR;
R = F.add(R, bigInt(arr[i]));
const S = exports.hash(R, C, key);
R = S.xL;
C = S.xR;
}
let outputs = [R];
for (let i=1; i < numOutputs; i++) {
const S = exports.hash(R, C, key);
R = S.xL;
C = S.xR;
outputs.push(R);
const S = exports.hash(R, C, key);
R = S.xL;
C = S.xR;
outputs.push(R);
}
if (numOutputs == 1) {
return F.affine(outputs[0]);
return F.normalize(outputs[0]);
} else {
return outputs.map(x => F.affine(x));
return outputs.map(x => F.normalize(x));
}
};

View File

@@ -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");
@@ -32,18 +31,18 @@ function pedersenHash(msg) {
let acc = bigInt.one;
for (let b=0; ((b<windowSize-1)&&(o<bits.length)) ; b++) {
if (bits[o]) {
acc = acc.add( bigInt.one.shl(b) );
acc = acc.add( bigInt.one.shiftLeft(b) );
}
o++;
}
if (o<bits.length) {
if (bits[o]) {
acc = acc.neg();
acc = bigInt.zero.minus(acc);
}
o++;
}
escalar = escalar.add(acc.mul(exp));
exp = exp.shl(windowSize+1);
escalar = escalar.add(acc.times(exp));
exp = exp.shiftLeft(windowSize+1);
}
if (escalar.lesser(bigInt.zero)) {

View File

@@ -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("ffjavascript").ZqField;
const utils = require("./utils");
const F = new ZqField(bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
const SEED = "poseidon";
const NROUNDSF = 8;
@@ -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;
@@ -50,7 +52,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.inv(F.sub(cmatrix[i], cmatrix[t+j])));
}
}
return M;
@@ -111,7 +113,7 @@ exports.createHash = (t, nRoundsF, nRoundsP, seed) => {
}
mix(state, M);
}
return F.affine(state[0]);
return F.normalize(state[0]);
};
};

View File

@@ -1,4 +1,4 @@
const bigInt = require("snarkjs").bigInt;
const bigInt = require("big-integer");
const SMTMemDB = require("./smt_memdb");
const {hash0, hash1} = require("./smt_hashes_poseidon");
@@ -21,7 +21,7 @@ class SMT {
} else {
res.push(false);
}
k = k.shr(1);
k = k.shiftRight(1);
}
while (res.length<256) res.push(false);

View File

@@ -1,5 +1,5 @@
const mimc7 = require("./mimc7");
const bigInt = require("snarkjs").bigInt;
const bigInt = require("big-integer");
exports.hash0 = function (left, right) {
return mimc7.multiHash(left, right);

View File

@@ -1,5 +1,5 @@
const Poseidon = require("./poseidon");
const bigInt = require("snarkjs").bigInt;
const bigInt = require("big-integer");
const hash = Poseidon.createHash(6, 8, 57);

View File

@@ -1,4 +1,4 @@
const bigInt = require("snarkjs").bigInt;
const bigInt = require("big-integer");
class SMTMemDb {
constructor() {

87
src/utils.js Normal file
View File

@@ -0,0 +1,87 @@
const bigInt = require("big-integer");
module.exports.leBuff2int = leBuff2int;
module.exports.leInt2Buff = leInt2Buff;
module.exports.beBuff2int = beBuff2int;
module.exports.beInt2Buff = beInt2Buff;
module.exports.stringifyBigInts = stringifyBigInts;
module.exports.unstringifyBigInts = unstringifyBigInts;
function leBuff2int (buff) {
let res = bigInt.zero;
for (let i=0; i<buff.length; i++) {
const n = bigInt(buff[i]);
res = res.add(n.shiftLeft(i*8));
}
return res;
}
function leInt2Buff(n, len) {
let r = n;
let o =0;
const buff = Buffer.alloc(len);
while ((r.gt(bigInt.zero))&&(o<buff.length)) {
let c = Number(r.and(bigInt(255)));
buff[o] = c;
o++;
r = r.shiftRight(8);
}
if (r.gt(bigInt.zero)) throw new Error("Number does not feed in buffer");
return buff;
}
function beBuff2int (buff) {
let res = bigInt.zero;
for (let i=0; i<buff.length; i++) {
const n = bigInt(buff[buff.length - i - 1]);
res = res.add(n.shiftLeft(i*8));
}
return res;
}
function beInt2Buff(n, len) {
let r = n;
let o =len-1;
const buff = Buffer.alloc(len);
while ((r.greater(bigInt.zero))&&(o>=0)) {
let c = Number(r.and(bigInt(255)));
buff[o] = c;
o--;
r = r.shiftRight(8);
}
if (r.gt(bigInt.zero)) throw new Error("Number does not feed in buffer");
return buff;
}
function stringifyBigInts(o) {
if ((typeof(o) == "bigint") || o.isZero !== undefined) {
return o.toString(10);
} else if (Array.isArray(o)) {
return o.map(stringifyBigInts);
} else if (typeof o == "object") {
const res = {};
for (let k in o) {
res[k] = stringifyBigInts(o[k]);
}
return res;
} else {
return o;
}
}
function unstringifyBigInts(o) {
if ((typeof(o) == "string") && (/^[0-9]+$/.test(o) )) {
return bigInt(o);
} else if (Array.isArray(o)) {
return o.map(unstringifyBigInts);
} else if (typeof o == "object") {
const res = {};
for (let k in o) {
res[k] = unstringifyBigInts(o[k]);
}
return res;
} else {
return o;
}
}