Blake to Blake2b and use of native big num

This commit is contained in:
Jordi Baylina
2020-04-18 22:33:59 +02:00
parent 6df6e9cb1c
commit b2ac4daaa7
42 changed files with 572 additions and 1191 deletions

View File

@@ -1,6 +1,6 @@
const bigInt = require("big-integer");
const ZqField = require("ffjavascript").ZqField;
const utils = require("./utils.js");
const F1Field = require("ffjavascript").F1Field;
const Scalar = require("ffjavascript").Scalar;
const utils = require("ffjavascript").utils;
exports.addPoint = addPoint;
exports.mulPointEscalar = mulPointEscalar;
@@ -8,23 +8,27 @@ exports.inCurve = inCurve;
exports.inSubgroup = inSubgroup;
exports.packPoint = packPoint;
exports.unpackPoint = unpackPoint;
exports.p = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
const F = new F1Field(exports.p);
exports.F = F;
exports.Generator = [
bigInt("995203441582195749578291179787384436505546430278305826713579947235728471134"),
bigInt("5472060717959818805561601436314318772137091100104008585924551046643952123905")
F.e("995203441582195749578291179787384436505546430278305826713579947235728471134"),
F.e("5472060717959818805561601436314318772137091100104008585924551046643952123905")
];
exports.Base8 = [
bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")
F.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
F.e("16950150798460657717958625567821834550301663161624707787222815936182638968203")
];
exports.order = bigInt("21888242871839275222246405745257275088614511777268538073601725287587578984328");
exports.subOrder = exports.order.shiftRight(3);
exports.p = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
exports.A = bigInt("168700");
exports.D = bigInt("168696");
exports.order = Scalar.fromString("21888242871839275222246405745257275088614511777268538073601725287587578984328");
exports.subOrder = Scalar.shiftRight(exports.order, 3);
exports.A = F.e("168700");
exports.D = F.e("168696");
function addPoint(a,b) {
const F = new ZqField(exports.p);
const res = [];
@@ -44,28 +48,28 @@ function addPoint(a,b) {
res[0] = F.div(
F.add(beta, gamma),
F.add(bigInt.one, dtau)
F.add(F.one, dtau)
);
res[1] = F.div(
F.add(delta, F.sub(F.mul(exports.A,beta), gamma)),
F.sub(bigInt.one, dtau)
F.sub(F.one, dtau)
);
return res;
}
function mulPointEscalar(base, e) {
let res = [bigInt("0"),bigInt("1")];
let rem = bigInt(e);
let res = [F.e("0"),F.e("1")];
let rem = e;
let exp = base;
while (! rem.isZero()) {
if (rem.isOdd()) {
while (! Scalar.isZero(rem)) {
if (Scalar.isOdd(rem)) {
res = addPoint(res, exp);
}
exp = addPoint(exp, exp);
rem = rem.shiftRight(1);
rem = Scalar.shiftRight(rem, 1);
}
return res;
@@ -74,11 +78,10 @@ function mulPointEscalar(base, e) {
function inSubgroup(P) {
if (!inCurve(P)) return false;
const res= mulPointEscalar(P, exports.subOrder);
return (res[0].equals(bigInt(0))) && (res[1].equals(bigInt(1)));
return (F.isZero(res[0]) && F.eq(res[1], F.one));
}
function inCurve(P) {
const F = new ZqField(exports.p);
const x2 = F.square(P[0]);
const y2 = F.square(P[1]);
@@ -92,15 +95,13 @@ function inCurve(P) {
function packPoint(P) {
const buff = utils.leInt2Buff(P[1], 32);
if (P[0].greater(exports.p.shiftRight(1))) {
if (F.lt(P[0], F.zero)) {
buff[31] = buff[31] | 0x80;
}
return buff;
}
function unpackPoint(_buff) {
const F = new ZqField(exports.p);
const buff = Buffer.from(_buff);
let sign = false;
const P = new Array(2);
@@ -109,7 +110,7 @@ function unpackPoint(_buff) {
buff[31] = buff[31] & 0x7F;
}
P[1] = utils.leBuff2int(buff);
if (P[1].greaterOrEquals(exports.p)) return null;
if (Scalar.gt(P[1], exports.p)) return null;
const y2 = F.square(P[1]);

View File

@@ -1,7 +1,8 @@
const createBlakeHash = require("blake-hash");
const bigInt = require("big-integer");
const blake2b = require("blake2b");
const Scalar = require("ffjavascript").Scalar;
const F1Field = require("ffjavascript").F1Field;
const babyJub = require("./babyjub");
const utils = require("./utils");
const utils = require("ffjavascript").utils;
const pedersenHash = require("./pedersenHash").hash;
const mimc7 = require("./mimc7");
const poseidon = require("./poseidon.js");
@@ -31,27 +32,28 @@ function pruneBuffer(_buff) {
}
function prv2pub(prv) {
const sBuff = pruneBuffer(createBlakeHash("blake512").update(prv).digest().slice(0,32));
const sBuff = pruneBuffer(blake2b(64).update(prv).digest().slice(0,32));
let s = utils.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shiftRight(3));
const A = babyJub.mulPointEscalar(babyJub.Base8, Scalar.shr(s,3));
return A;
}
function sign(prv, msg) {
const h1 = createBlakeHash("blake512").update(prv).digest();
const h1 = Buffer.from(blake2b(64).update(prv).digest());
const sBuff = pruneBuffer(h1.slice(0,32));
const s = utils.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shiftRight(3));
const A = babyJub.mulPointEscalar(babyJub.Base8, Scalar.shr(s, 3));
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msg])).digest();
const rBuff = Buffer.from(blake2b(64).update(Buffer.concat([h1.slice(32,64), msg])).digest());
let r = utils.leBuff2int(rBuff);
r = r.mod(babyJub.subOrder);
const Fr = new F1Field(babyJub.subOrder);
r = Fr.e(r);
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 = utils.leBuff2int(hmBuff);
const S = r.add(hm.times(s)).mod(babyJub.subOrder);
const S = Fr.add(r , Fr.mul(hm, s));
return {
R8: R8,
S: S
@@ -59,18 +61,19 @@ function sign(prv, msg) {
}
function signMiMC(prv, msg) {
const h1 = createBlakeHash("blake512").update(prv).digest();
const h1 = Buffer.from(blake2b(64).update(prv).digest());
const sBuff = pruneBuffer(h1.slice(0,32));
const s = utils.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shiftRight(3));
const A = babyJub.mulPointEscalar(babyJub.Base8, Scalar.shr(s, 3));
const msgBuff = utils.leInt2Buff(msg, 32);
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
const rBuff = Buffer.from(blake2b(64).update(Buffer.concat([h1.slice(32,64), msgBuff])).digest());
let r = utils.leBuff2int(rBuff);
r = r.mod(babyJub.subOrder);
const Fr = new F1Field(babyJub.subOrder);
r = Fr.e(r);
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.times(s)).mod(babyJub.subOrder);
const S = Fr.add(r , Fr.mul(hm, s));
return {
R8: R8,
S: S
@@ -78,18 +81,19 @@ function signMiMC(prv, msg) {
}
function signMiMCSponge(prv, msg) {
const h1 = createBlakeHash("blake512").update(prv).digest();
const h1 = Buffer.from(blake2b(64).update(prv).digest());
const sBuff = pruneBuffer(h1.slice(0,32));
const s = utils.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shiftRight(3));
const A = babyJub.mulPointEscalar(babyJub.Base8, Scalar.shr(s, 3));
const msgBuff = utils.leInt2Buff(msg, 32);
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
const rBuff = Buffer.from(blake2b(64).update(Buffer.concat([h1.slice(32,64), msgBuff])).digest());
let r = utils.leBuff2int(rBuff);
r = r.mod(babyJub.subOrder);
const Fr = new F1Field(babyJub.subOrder);
r = Fr.e(r);
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.times(s)).mod(babyJub.subOrder);
const S = Fr.add(r , Fr.mul(hm, s));
return {
R8: R8,
S: S
@@ -97,19 +101,20 @@ function signMiMCSponge(prv, msg) {
}
function signPoseidon(prv, msg) {
const h1 = createBlakeHash("blake512").update(prv).digest();
const h1 = Buffer.from(blake2b(64).update(prv).digest());
const sBuff = pruneBuffer(h1.slice(0,32));
const s = utils.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shiftRight(3));
const A = babyJub.mulPointEscalar(babyJub.Base8, Scalar.shr(s, 3));
const msgBuff = utils.leInt2Buff(msg, 32);
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
const rBuff = Buffer.from(blake2b(64).update(Buffer.concat([h1.slice(32,64), msgBuff])).digest());
let r = utils.leBuff2int(rBuff);
r = r.mod(babyJub.subOrder);
const Fr = new F1Field(babyJub.subOrder);
r = Fr.e(r);
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.times(s)).mod(babyJub.subOrder);
const S = Fr.add(r , Fr.mul(hm, s));
return {
R8: R8,
S: S
@@ -133,11 +138,11 @@ function verify(msg, sig, A) {
const hm = utils.leBuff2int(hmBuff);
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
let Pright = babyJub.mulPointEscalar(A, hm.times(bigInt("8")));
let Pright = babyJub.mulPointEscalar(A, Scalar.mul(hm,8));
Pright = babyJub.addPoint(sig.R8, Pright);
if (!Pleft[0].equals(Pright[0])) return false;
if (!Pleft[1].equals(Pright[1])) return false;
if (!babyJub.F.eq(Pleft[0],Pright[0])) return false;
if (!babyJub.F.eq(Pleft[1],Pright[1])) return false;
return true;
}
@@ -155,11 +160,11 @@ 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.times(bigInt("8")));
let Pright = babyJub.mulPointEscalar(A, Scalar.mul(hm, 8));
Pright = babyJub.addPoint(sig.R8, Pright);
if (!Pleft[0].equals(Pright[0])) return false;
if (!Pleft[1].equals(Pright[1])) return false;
if (!babyJub.F.eq(Pleft[0],Pright[0])) return false;
if (!babyJub.F.eq(Pleft[1],Pright[1])) return false;
return true;
}
@@ -179,11 +184,11 @@ 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.times(bigInt("8")));
let Pright = babyJub.mulPointEscalar(A, Scalar.mul(hm, 8));
Pright = babyJub.addPoint(sig.R8, Pright);
if (!Pleft[0].equals(Pright[0])) return false;
if (!Pleft[1].equals(Pright[1])) return false;
if (!babyJub.F.eq(Pleft[0],Pright[0])) return false;
if (!babyJub.F.eq(Pleft[1],Pright[1])) return false;
return true;
}
@@ -204,8 +209,8 @@ function verifyMiMCSponge(msg, sig, A) {
let Pright = babyJub.mulPointEscalar(A, hm.times(bigInt("8")));
Pright = babyJub.addPoint(sig.R8, Pright);
if (!Pleft[0].equals(Pright[0])) return false;
if (!Pleft[1].equals(Pright[1])) return false;
if (!babyJub.F.eq(Pleft[0],Pright[0])) return false;
if (!babyJub.F.eq(Pleft[1],Pright[1])) return false;
return true;
}

View File

@@ -4,7 +4,6 @@
const Contract = require("./evmasm");
const G2 = require("snarkjs").bn128.G2;
const bigInt = require("snarkjs").bigInt;
function toHex256(a) {
@@ -539,7 +538,7 @@ function createCode(P, w) {
function storeVals() {
C.push(VAR_POINTS); // p
for (let i=0; i<NPOINTS; i++) {
const MP = G2.affine(G2.mulScalar(P, bigInt(i)));
const MP = G2.affine(G2.mulScalar(P, i));
for (let j=0; j<2; j++) {
for (let k=0; k<2; k++) {
C.push(toHex256(MP[j][k])); // MP[0][0] p

View File

@@ -1,8 +1,9 @@
const bigInt = require("big-integer");
const Scalar = require("ffjavascript").Scalar;
const ZqField = require("ffjavascript").ZqField;
const Web3Utils = require("web3-utils");
const F = new ZqField(bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
exports.F = F;
const SEED = "mimc";
const NROUNDS = 91;
@@ -10,7 +11,7 @@ const NROUNDS = 91;
exports.getIV = (seed) => {
if (typeof seed === "undefined") seed = SEED;
const c = Web3Utils.keccak256(seed+"_iv");
const cn = bigInt(Web3Utils.toBN(c).toString());
const cn = Scalar.FromString(Web3Utils.toBN(c).toString());
const iv = cn.mod(F.p);
return iv;
};
@@ -25,17 +26,17 @@ exports.getConstants = (seed, nRounds) => {
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());
cts[i] = Scalar.fromString(Web3Utils.toBN(c2).toString());
}
cts[0] = bigInt(0);
cts[0] = F.e(0);
return cts;
};
const cts = exports.getConstants(SEED, 91);
exports.hash = (_x_in, _k) =>{
const x_in = bigInt(_x_in);
const k = bigInt(_k);
const x_in = F.e(_x_in);
const k = F.e(_k);
let r;
for (let i=0; i<NROUNDS; i++) {
const c = cts[i];
@@ -58,7 +59,7 @@ exports.multiHash = (arr, key) => {
r,
arr[i]
),
exports.hash(bigInt(arr[i]), r)
exports.hash(F.e(arr[i]), r)
);
}
return r;

View File

@@ -1,7 +1,7 @@
const bigInt = require("big-integer");
const Scalar = require("ffjavascript").Scalar
const Web3Utils = require("web3-utils");
const ZqField = require("ffjavascript").ZqField;
const F = new ZqField(bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
const SEED = "mimcsponge";
const NROUNDS = 220;
@@ -9,7 +9,7 @@ const NROUNDS = 220;
exports.getIV = (seed) => {
if (typeof seed === "undefined") seed = SEED;
const c = Web3Utils.keccak256(seed+"_iv");
const cn = bigInt(Web3Utils.toBN(c).toString());
const cn = Scalar.fromString(Web3Utils.toBN(c).toString());
const iv = cn.mod(F.p);
return iv;
};
@@ -24,23 +24,23 @@ exports.getConstants = (seed, nRounds) => {
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());
cts[i] = F.e(Web3Utils.toBN(c2).toString());
}
cts[0] = bigInt(0);
cts[cts.length - 1] = bigInt(0);
cts[0] = F.e(0);
cts[cts.length - 1] = F.e(0);
return cts;
};
const cts = exports.getConstants(SEED, NROUNDS);
exports.hash = (_xL_in, _xR_in, _k) =>{
let xL = bigInt(_xL_in);
let xR = bigInt(_xR_in);
const k = bigInt(_k);
let xL = F.e(_xL_in);
let xR = F.e(_xR_in);
const k = F.e(_k);
for (let i=0; i<NROUNDS; i++) {
const c = cts[i];
const t = (i==0) ? F.add(xL, k) : F.add(F.add(xL, k), c);
const xR_tmp = bigInt(xR);
const xR_tmp = F.e(xR);
if (i < (NROUNDS - 1)) {
xR = xL;
xL = F.add(xR_tmp, F.pow(t, 5));
@@ -66,7 +66,7 @@ exports.multiHash = (arr, key, numOutputs) => {
let C = F.zero;
for (let i=0; i<arr.length; i++) {
R = F.add(R, bigInt(arr[i]));
R = F.add(R, F.e(arr[i]));
const S = exports.hash(R, C, key);
R = S.xL;
C = S.xR;

View File

@@ -1,6 +1,6 @@
const bigInt = require("big-integer");
const babyJub = require("./babyjub");
const createBlakeHash = require("blake-hash");
const blake2b = require("blake2b");
const Scalar = require("ffjavascript").Scalar;
const GENPOINT_PREFIX = "PedersenGenerator";
const windowSize = 4;
@@ -15,7 +15,7 @@ function pedersenHash(msg) {
const nSegments = Math.floor((bits.length - 1)/(windowSize*nWindowsPerSegment)) +1;
let accP = [bigInt.zero,bigInt.one];
let accP = [babyJub.F.zero,babyJub.F.one];
for (let s=0; s<nSegments; s++) {
let nWindows;
@@ -24,29 +24,29 @@ function pedersenHash(msg) {
} else {
nWindows = nWindowsPerSegment;
}
let escalar = bigInt.zero;
let exp = bigInt.one;
let escalar = Scalar.e(0);
let exp = Scalar.e(1);
for (let w=0; w<nWindows; w++) {
let o = s*bitsPerSegment + w*windowSize;
let acc = bigInt.one;
let acc = Scalar.e(1);
for (let b=0; ((b<windowSize-1)&&(o<bits.length)) ; b++) {
if (bits[o]) {
acc = acc.add( bigInt.one.shiftLeft(b) );
acc = Scalar.add(acc, Scalar.shl(Scalar.e(1), b) );
}
o++;
}
if (o<bits.length) {
if (bits[o]) {
acc = bigInt.zero.minus(acc);
acc = Scalar.neg(acc);
}
o++;
}
escalar = escalar.add(acc.times(exp));
exp = exp.shiftLeft(windowSize+1);
escalar = Scalar.add(escalar, Scalar.mul(acc, exp));
exp = Scalar.shl(exp, windowSize+1);
}
if (escalar.lesser(bigInt.zero)) {
escalar = babyJub.subOrder.add(escalar);
if (Scalar.lt(escalar, 0)) {
escalar = Scalar.add( escalar, babyJub.subOrder);
}
accP = babyJub.addPoint(accP, babyJub.mulPointEscalar(getBasePoint(s), escalar));
@@ -63,7 +63,7 @@ function getBasePoint(pointIdx) {
let tryIdx = 0;
while (p==null) {
const S = GENPOINT_PREFIX + "_" + padLeftZeros(pointIdx, 32) + "_" + padLeftZeros(tryIdx, 32);
const h = createBlakeHash("blake256").update(S).digest();
const h = Buffer.from(blake2b(32).update(Buffer.from(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)
p = babyJub.unpackPoint(h);
tryIdx++;

View File

@@ -1,10 +1,11 @@
const bigInt = require("big-integer");
const Scalar = require("ffjavascript").Scalar;
const blake2b = require("blake2b");
const assert = require("assert");
const ZqField = require("ffjavascript").ZqField;
const utils = require("./utils");
const utils = require("ffjavascript").utils;
const F = new ZqField(bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
exports.F = F;
const SEED = "poseidon";
const NROUNDSF = 8;
@@ -16,7 +17,7 @@ function getPseudoRandom(seed, n) {
let input = Buffer.from(seed);
let h = blake2b(32).update(input).digest();
while (res.length<n) {
const n = F.normalize(utils.leBuff2int(h));
const n = F.normalize(utils.leBuff2int(Buffer.from(h)));
res.push(n);
h = blake2b(32).update(h).digest();
}
@@ -26,9 +27,9 @@ function getPseudoRandom(seed, n) {
function allDifferent(v) {
for (let i=0; i<v.length; i++) {
if (v[i].isZero()) return false;
if (F.isZero(v[i])) return false;
for (let j=i+1; j<v.length; j++) {
if (v[i].equals(v[j])) return false;
if (F.eq(v[i],v[j])) return false;
}
}
return true;
@@ -101,7 +102,7 @@ exports.createHash = (t, nRoundsF, nRoundsP, seed) => {
let state = [];
assert(inputs.length <= t);
assert(inputs.length > 0);
for (let i=0; i<inputs.length; i++) state[i] = bigInt(inputs[i]);
for (let i=0; i<inputs.length; i++) state[i] = F.e(inputs[i]);
for (let i=inputs.length; i<t; i++) state[i] = F.zero;
for (let i=0; i< nRoundsF + nRoundsP; i++) {

View File

@@ -1,7 +1,6 @@
const bigInt = require("big-integer");
const Scalar = require("ffjavascript").Scalar;
const SMTMemDB = require("./smt_memdb");
const {hash0, hash1} = require("./smt_hashes_poseidon");
const {hash0, hash1, F} = require("./smt_hashes_poseidon");
class SMT {
@@ -11,18 +10,7 @@ class SMT {
}
_splitBits(_key) {
let k = bigInt(_key);
const res = [];
while (!k.isZero()) {
if (k.isOdd()) {
res.push(true);
} else {
res.push(false);
}
k = k.shiftRight(1);
}
const res = Scalar.bits(_key);
while (res.length<256) res.push(false);
@@ -30,8 +18,8 @@ class SMT {
}
async update(_key, _newValue) {
const key = bigInt(_key);
const newValue = bigInt(_newValue);
const key = Scalar.e(_key);
const newValue = F.e(_newValue);
const resFind = await this.find(key);
@@ -79,7 +67,7 @@ class SMT {
}
async delete(_key) {
const key = bigInt(_key);
const key = Scalar.e(_key);
const resFind = await this.find(key);
if (!resFind.found) throw new Error("Key does not exists");
@@ -99,7 +87,7 @@ class SMT {
let mixed;
if (resFind.siblings.length > 0) {
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)&&(F.eq(record[0], F.one))) {
mixed = false;
res.oldKey = record[1];
res.oldValue = record[2];
@@ -108,16 +96,16 @@ class SMT {
} else if (record.length == 2) {
mixed = true;
res.oldKey = key;
res.oldValue = bigInt(0);
res.oldValue = F.zero;
res.isOld0 = true;
rtNew = bigInt.zero;
rtNew = F.zero;
} else {
throw new Error("Invalid node. Database corrupted");
}
} else {
rtNew = bigInt.zero;
rtNew = F.zero;
res.oldKey = key;
res.oldValue = bigInt(0);
res.oldValue = F.zero;
res.isOld0 = true;
}
@@ -126,7 +114,7 @@ class SMT {
for (let level = resFind.siblings.length-1; level >=0; level--) {
let newSibling = resFind.siblings[level];
if ((level == resFind.siblings.length-1)&&(!res.isOld0)) {
newSibling = bigInt.zero;
newSibling = F.zero;
}
const oldSibling = resFind.siblings[level];
if (keyBits[level]) {
@@ -135,7 +123,7 @@ class SMT {
rtOld = hash0(rtOld, oldSibling);
}
dels.push(rtOld);
if (!newSibling.isZero()) {
if (!F.isZero(newSibling)) {
mixed = true;
}
@@ -164,8 +152,8 @@ class SMT {
}
async insert(_key, _value) {
const key = bigInt(_key);
const value = bigInt(_value);
const key = Scalar.e(_key);
const value = F.e(_value);
let addedOne = false;
const res = {};
res.oldRoot = this.root;
@@ -183,7 +171,7 @@ class SMT {
if (!resFind.isOld0) {
const oldKeyits = this._splitBits(resFind.notFoundKey);
for (let i= res.siblings.length; oldKeyits[i] == newKeyBits[i]; i++) {
res.siblings.push(bigInt.zero);
res.siblings.push(F.zero);
}
rtOld = hash1(resFind.notFoundKey, resFind.notFoundValue);
res.siblings.push(rtOld);
@@ -191,7 +179,7 @@ class SMT {
mixed = false;
} else if (res.siblings.length >0) {
mixed = true;
rtOld = bigInt.zero;
rtOld = F.zero;
}
const inserts = [];
@@ -201,7 +189,7 @@ class SMT {
inserts.push([rt,[1, key, value]] );
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)&&(!F.isZero(res.siblings[i]))) {
mixed = true;
}
if (mixed) {
@@ -227,7 +215,7 @@ class SMT {
}
if (addedOne) res.siblings.pop();
while ((res.siblings.length>0) && (res.siblings[res.siblings.length-1].isZero())) {
while ((res.siblings.length>0) && (F.isZero(res.siblings[res.siblings.length-1]))) {
res.siblings.pop();
}
res.oldKey = resFind.notFoundKey;
@@ -253,12 +241,12 @@ class SMT {
if (typeof root === "undefined") root = this.root;
let res;
if (root.isZero()) {
if (F.isZero(root)) {
res = {
found: false,
siblings: [],
notFoundKey: key,
notFoundValue: bigInt.zero,
notFoundValue: F.zero,
isOld0: true
};
return res;
@@ -266,8 +254,8 @@ class SMT {
const record = await this.db.get(root);
if ((record.length==3)&&(record[0].equals(bigInt.one))) {
if (record[1].equals(key)) {
if ((record.length==3)&&(F.eq(record[0],F.one))) {
if (F.eq(record[1],key)) {
res = {
found: true,
siblings: [],

View File

@@ -8,3 +8,5 @@ exports.hash0 = function (left, right) {
exports.hash1 = function(key, value) {
return mimc7.multiHash([key, value], bigInt.one);
};
exports.F = mimc7.F;

View File

@@ -1,5 +1,4 @@
const Poseidon = require("./poseidon");
const bigInt = require("big-integer");
const hash = Poseidon.createHash(6, 8, 57);
@@ -8,5 +7,7 @@ exports.hash0 = function (left, right) {
};
exports.hash1 = function(key, value) {
return hash([key, value, bigInt.one]);
return hash([key, value, Poseidon.F.one]);
};
exports.F = Poseidon.F;

View File

@@ -1,9 +1,11 @@
const bigInt = require("big-integer");
const F = require("./poseidon.js").F;
const Scalar = require("ffjavascript").Scalar;
class SMTMemDb {
constructor() {
this.nodes = {};
this.root = bigInt(0);
this.root = F.zero;
}
async getRoot() {
@@ -12,13 +14,13 @@ class SMTMemDb {
_key2str(k) {
// const keyS = bigInt(key).leInt2Buff(32).toString("hex");
const keyS = bigInt(k).toString();
const keyS = Scalar.e(k);
return keyS;
}
_normalize(n) {
for (let i=0; i<n.length; i++) {
n[i] = bigInt(n[i]);
n[i] = F.e(n[i]);
}
}

View File

@@ -1,87 +0,0 @@
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;
}
}