Small patches
This commit is contained in:
parent
345f040b41
commit
0639963bea
@ -44,6 +44,17 @@ template IsEqual() {
|
||||
isz.out ==> out;
|
||||
}
|
||||
|
||||
template ForceEqualIfEnabled() {
|
||||
signal input enabled;
|
||||
signal input in[2];
|
||||
|
||||
component isz = IsZero();
|
||||
|
||||
in[1] - in[0] ==> isz.in;
|
||||
|
||||
(1 - isz.out)*enabled === 0;
|
||||
}
|
||||
|
||||
|
||||
// N is the number of bits the input have.
|
||||
// The MSF is the sign bit.
|
||||
|
122
circuits/eddsamimc.circom
Normal file
122
circuits/eddsamimc.circom
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "compconstant.circom";
|
||||
include "pointbits.circom";
|
||||
include "mimc.circom";
|
||||
include "bitify.circom";
|
||||
include "escalarmulany.circom";
|
||||
include "escalarmulfix.circom";
|
||||
|
||||
template EdDSAMiMCVerifier() {
|
||||
signal input enabled;
|
||||
signal input Ax;
|
||||
signal input Ay;
|
||||
|
||||
signal input S;
|
||||
signal input R8x;
|
||||
signal input R8y;
|
||||
|
||||
signal input M;
|
||||
|
||||
var i;
|
||||
|
||||
// Ensure S<Subgroup Order
|
||||
|
||||
component snum2bits = Num2Bits(253);
|
||||
snum2bits.in <== S;
|
||||
|
||||
component compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040);
|
||||
|
||||
for (i=0; i<253; i++) {
|
||||
snum2bits.out[i] ==> compConstant.in[i];
|
||||
}
|
||||
compConstant.in[253] <== 0;
|
||||
compConstant.out === 0;
|
||||
|
||||
// Calculate the h = H(R,A, msg)
|
||||
|
||||
component hash = MultiMiMC7(5, 91);
|
||||
hash.in[0] <== R8x;
|
||||
hash.in[1] <== R8y;
|
||||
hash.in[2] <== Ax;
|
||||
hash.in[3] <== Ay;
|
||||
hash.in[4] <== M;
|
||||
|
||||
component h2bits = Num2Bits_strict();
|
||||
h2bits.in <== hash.out;
|
||||
|
||||
// Calculate second part of the right side: right2 = h*8*A
|
||||
|
||||
// Multiply by 8 by adding it 3 times. This also ensure that the result is in
|
||||
// the subgroup.
|
||||
component dbl1 = BabyDbl();
|
||||
dbl1.x <== Ax;
|
||||
dbl1.y <== Ay;
|
||||
component dbl2 = BabyDbl();
|
||||
dbl2.x <== dbl1.xout;
|
||||
dbl2.y <== dbl1.yout;
|
||||
component dbl3 = BabyDbl();
|
||||
dbl3.x <== dbl2.xout;
|
||||
dbl3.y <== dbl2.yout;
|
||||
|
||||
// We check that A is not zero.
|
||||
component isZero = IsZero();
|
||||
isZero.in <== dbl3.x;
|
||||
isZero.out === 0;
|
||||
|
||||
component mulAny = EscalarMulAny(254);
|
||||
for (i=0; i<254; i++) {
|
||||
mulAny.e[i] <== h2bits.out[i];
|
||||
}
|
||||
mulAny.p[0] <== dbl3.xout;
|
||||
mulAny.p[1] <== dbl3.yout;
|
||||
|
||||
|
||||
// Compute the right side: right = R8 + right2
|
||||
|
||||
component addRight = BabyAdd();
|
||||
addRight.x1 <== R8x;
|
||||
addRight.y1 <== R8y;
|
||||
addRight.x2 <== mulAny.out[0];
|
||||
addRight.y2 <== mulAny.out[1];
|
||||
|
||||
// Calculate left side of equation left = S*B8
|
||||
|
||||
var BASE8 = [
|
||||
17777552123799933955779906779655732241715742912184938656739573121738514868268,
|
||||
2626589144620713026669568689430873010625803728049924121243784502389097019475
|
||||
];
|
||||
component mulFix = EscalarMulFix(253, BASE8);
|
||||
for (i=0; i<253; i++) {
|
||||
mulFix.e[i] <== snum2bits.out[i];
|
||||
}
|
||||
|
||||
// Do the comparation left == right if enabled;
|
||||
|
||||
component eqCheckX = ForceEqualIfEnabled();
|
||||
eqCheckX.enabled <== enabled;
|
||||
eqCheckX.in[0] <== mulFix.out[0];
|
||||
eqCheckX.in[1] <== addRight.xout;
|
||||
|
||||
component eqCheckY = ForceEqualIfEnabled();
|
||||
eqCheckY.enabled <== enabled;
|
||||
eqCheckY.in[0] <== mulFix.out[1];
|
||||
eqCheckY.in[1] <== addRight.yout;
|
||||
}
|
@ -134,3 +134,21 @@ template MiMC7(nrounds) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template MultiMiMC7(nInputs, nRounds) {
|
||||
signal input in[nInputs];
|
||||
signal output out;
|
||||
|
||||
component mims[nInputs];
|
||||
for (var i=0; i<nInputs; i++) {
|
||||
mims[i] = MiMC7(nRounds);
|
||||
if (i==0) {
|
||||
mims[i].x_in <== 15021630795539610737508582392395901278341266317943626182700664337106830745361;
|
||||
} else {
|
||||
mims[i].x_in <== mims[i-1].out;
|
||||
}
|
||||
mims[i].k <== in[i];
|
||||
}
|
||||
|
||||
out <== mims[nInputs-1].out;
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ template SMTLevIns(nLevels) {
|
||||
signal input enabled;
|
||||
signal input siblings[nLevels];
|
||||
signal output levIns[nLevels];
|
||||
signal done[nLevels-1]; // Indicates if the insLevel has aready been detecetd.
|
||||
signal done[nLevels-1]; // Indicates if the insLevel has aready been detected.
|
||||
|
||||
component isZero[nLevels];
|
||||
|
||||
@ -87,7 +87,7 @@ template SMTLevIns(nLevels) {
|
||||
}
|
||||
|
||||
// The last level must always have a sibling of 0. If not, then it cannot be inserted.
|
||||
(isZero[nLevels-2].out - 1) * enabled === 0;
|
||||
(isZero[nLevels-1].out - 1) * enabled === 0;
|
||||
|
||||
levIns[nLevels-1] <== (1-isZero[nLevels-2].out);
|
||||
done[nLevels-2] <== levIns[nLevels-1];
|
||||
|
@ -139,7 +139,7 @@ include "smthash.circom";
|
||||
|
||||
template SMTProcessor(nLevels) {
|
||||
signal input oldRoot;
|
||||
signal input newRoot;
|
||||
signal output newRoot;
|
||||
signal input siblings[nLevels];
|
||||
signal input oldKey;
|
||||
signal input oldValue;
|
||||
@ -201,7 +201,7 @@ template SMTProcessor(nLevels) {
|
||||
sm[i].fnc[1] <== fnc[1];
|
||||
sm[i].levIns <== smtLevIns.levIns[i];
|
||||
}
|
||||
sm[nLevels-1].st_na === 1;
|
||||
sm[nLevels-1].st_na + sm[nLevels-1].st_new1 + sm[nLevels-1].st_old0 +sm[nLevels-1].st_upd === 1;
|
||||
|
||||
component levels[nLevels];
|
||||
for (var i=nLevels-1; i != -1; i--) {
|
||||
@ -234,8 +234,15 @@ template SMTProcessor(nLevels) {
|
||||
topSwitcher.L <== levels[0].oldRoot;
|
||||
topSwitcher.R <== levels[0].newRoot;
|
||||
|
||||
topSwitcher.outL === oldRoot*enabled;
|
||||
topSwitcher.outR === newRoot*enabled;
|
||||
component checkOldInput = ForceEqualIfEnabled();
|
||||
checkOldInput.enabled <== enabled;
|
||||
checkOldInput.in[0] <== oldRoot;
|
||||
checkOldInput.in[1] <== topSwitcher.outL;
|
||||
|
||||
newRoot <== enabled * (topSwitcher.outR - oldRoot) + oldRoot;
|
||||
|
||||
// topSwitcher.outL === oldRoot*enabled;
|
||||
// topSwitcher.outR === newRoot*enabled;
|
||||
|
||||
// Ckeck keys are equal if updating
|
||||
component areKeyEquals = IsEqual();
|
||||
|
@ -38,6 +38,7 @@ include "smtverifiersm.circom";
|
||||
include "smthash.circom";
|
||||
|
||||
template SMTVerifier(nLevels) {
|
||||
signal input enabled;
|
||||
signal input root;
|
||||
signal input siblings[nLevels];
|
||||
signal input oldKey;
|
||||
@ -63,17 +64,17 @@ template SMTVerifier(nLevels) {
|
||||
|
||||
component smtLevIns = SMTLevIns(nLevels);
|
||||
for (var i=0; i<nLevels; i++) smtLevIns.siblings[i] <== siblings[i];
|
||||
smtLevIns.enabled <== 1;
|
||||
smtLevIns.enabled <== enabled;
|
||||
|
||||
component sm[nLevels];
|
||||
for (var i=0; i<nLevels; i++) {
|
||||
sm[i] = SMTVerifierSM();
|
||||
if (i==0) {
|
||||
sm[i].prev_top <== 1;
|
||||
sm[i].prev_top <== enabled;
|
||||
sm[i].prev_i0 <== 0;
|
||||
sm[i].prev_inew <== 0;
|
||||
sm[i].prev_iold <== 0;
|
||||
sm[i].prev_na <== 0;
|
||||
sm[i].prev_na <== 1-enabled;
|
||||
} else {
|
||||
sm[i].prev_top <== sm[i-1].st_top;
|
||||
sm[i].prev_i0 <== sm[i-1].st_i0;
|
||||
@ -85,7 +86,7 @@ template SMTVerifier(nLevels) {
|
||||
sm[i].fnc <== fnc;
|
||||
sm[i].levIns <== smtLevIns.levIns[i];
|
||||
}
|
||||
sm[nLevels-1].st_na === 1;
|
||||
sm[nLevels-1].st_na + sm[nLevels-1].st_iold + sm[nLevels-1].st_inew + sm[nLevels-1].st_i0 === 1;
|
||||
|
||||
component levels[nLevels];
|
||||
for (var i=nLevels-1; i != -1; i--) {
|
||||
@ -115,14 +116,20 @@ template SMTVerifier(nLevels) {
|
||||
areKeyEquals.in[0] <== oldKey;
|
||||
areKeyEquals.in[1] <== key;
|
||||
|
||||
component keysOk = MultiAND(3);
|
||||
component keysOk = MultiAND(4);
|
||||
keysOk.in[0] <== fnc;
|
||||
keysOk.in[1] <== 1-isOld0;
|
||||
keysOk.in[2] <== areKeyEquals.out;
|
||||
keysOk.in[3] <== enabled;
|
||||
|
||||
keysOk.out === 0;
|
||||
|
||||
// Check the roots
|
||||
levels[0].root === root;
|
||||
// Check the root
|
||||
component checkRoot = ForceEqualIfEnabled();
|
||||
checkRoot.enabled <== enabled;
|
||||
checkRoot.in[0] <== levels[0].root;
|
||||
checkRoot.in[1] <== root;
|
||||
|
||||
// levels[0].root === root;
|
||||
|
||||
}
|
||||
|
3
index.js
Normal file
3
index.js
Normal file
@ -0,0 +1,3 @@
|
||||
exports.smt = require("./src/smt");
|
||||
exports.eddsa = require("./src/eddsa");
|
||||
exports.mimc7 = require("./src/mimc7");
|
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cirpedersen",
|
||||
"version": "0.0.3",
|
||||
"name": "circomlib",
|
||||
"version": "0.0.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
@ -25,10 +25,10 @@
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"blake-hash": "^1.1.0",
|
||||
"snarkjs": "0.1.7"
|
||||
"snarkjs": "0.1.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"circom": "0.0.22",
|
||||
"circom": "0.0.23",
|
||||
"eslint-plugin-mocha": "^5.2.0",
|
||||
"ganache-cli": "^6.2.3",
|
||||
"mocha": "^5.2.0",
|
||||
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
fnc[0] fn[1] Function S1 S2 S3 S4
|
||||
0 0 NOP 0 0 0 0
|
||||
0 1 TRANSFER 0 1 0 1
|
||||
1 0 ENTRY 0 1 0 1
|
||||
1 1 EXIT 1 0 1 1
|
||||
|
||||
*/
|
||||
|
||||
template rollupTx(nLevels) {
|
||||
signal input fromIdx; // 24
|
||||
signal input toIdx; // 24
|
||||
signal input fpTxAmount; // 24
|
||||
|
||||
signal input fnc[2]; // 2
|
||||
|
||||
signal oldRoot;
|
||||
signal newRoot;
|
||||
|
||||
signal input sigR8;
|
||||
signal input sigS;
|
||||
|
||||
// State 1
|
||||
signal input Ax1;
|
||||
signal input Ay1;
|
||||
signal input St1;
|
||||
signal input siblings1[nlevels];
|
||||
|
||||
// Required for inserts and delete
|
||||
signal input isOld0_1; // 1
|
||||
signal input oldKey;
|
||||
signal input oldValue;
|
||||
|
||||
// State 2
|
||||
signal input Ax2;
|
||||
signal input Ay2;
|
||||
signal input St2;
|
||||
signal input siblings2[nlevels];
|
||||
signal input isOld0_1; // 1
|
||||
signal input oldKey;
|
||||
signal input oldValue;
|
||||
|
||||
}
|
44
src/eddsa.js
44
src/eddsa.js
@ -2,12 +2,15 @@ const createBlakeHash = require("blake-hash");
|
||||
const bigInt = require("snarkjs").bigInt;
|
||||
const babyJub = require("./babyjub");
|
||||
const pedersenHash = require("./pedersenHash").hash;
|
||||
const mimc7 = require("./mimc7");
|
||||
const crypto = require("crypto");
|
||||
|
||||
exports.cratePrvKey = cratePrvKey;
|
||||
exports.prv2pub= prv2pub;
|
||||
exports.sign = sign;
|
||||
exports.signMiMC = signMiMC;
|
||||
exports.verify = verify;
|
||||
exports.verifyMiMC = verifyMiMC;
|
||||
exports.packSignature = packSignature;
|
||||
exports.unpackSignature = unpackSignature;
|
||||
|
||||
@ -52,6 +55,25 @@ 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 msgBuff = bigInt.leInt2Buff(msg, 32);
|
||||
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
|
||||
let r = bigInt.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);
|
||||
return {
|
||||
R8: R8,
|
||||
S: S
|
||||
};
|
||||
}
|
||||
|
||||
function verify(msg, sig, A) {
|
||||
// Check parameters
|
||||
if (typeof sig != "object") return false;
|
||||
@ -77,6 +99,28 @@ function verify(msg, sig, A) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function verifyMiMC(msg, sig, A) {
|
||||
// Check parameters
|
||||
if (typeof sig != "object") return false;
|
||||
if (!Array.isArray(sig.R8)) return false;
|
||||
if (sig.R8.length!= 2) return false;
|
||||
if (!babyJub.inCurve(sig.R8)) return false;
|
||||
if (!Array.isArray(A)) return false;
|
||||
if (A.length!= 2) return false;
|
||||
if (!babyJub.inCurve(A)) 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 Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
|
||||
let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
|
||||
Pright = babyJub.addPoint(sig.R8, Pright);
|
||||
|
||||
if (!Pleft[0].equals(Pright[0])) return false;
|
||||
if (!Pleft[1].equals(Pright[1])) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function packSignature(sig) {
|
||||
const R8p = babyJub.packPoint(sig.R8);
|
||||
const Sp = bigInt.leInt2Buff(sig.S, 32);
|
||||
|
@ -43,3 +43,11 @@ exports.hash = (_x_in, _k) =>{
|
||||
}
|
||||
return F.affine(F.add(r, k));
|
||||
};
|
||||
|
||||
exports.multiHash = (arr) => {
|
||||
let r = exports.getIV();
|
||||
for (let i=0; i<arr.length; i++) {
|
||||
r = exports.hash(r, bigInt(arr[i]));
|
||||
}
|
||||
return r;
|
||||
};
|
||||
|
36
src/smt.js
36
src/smt.js
@ -3,14 +3,6 @@ const bigInt = require("snarkjs").bigInt;
|
||||
const SMTMemDB = require("./smt_memdb");
|
||||
const mimc7 = require("./mimc7");
|
||||
|
||||
function smtHash(arr) {
|
||||
let r = mimc7.getIV();
|
||||
for (let i=0; i<arr.length; i++) {
|
||||
r = mimc7.hash(r, bigInt(arr[i]));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
class SMT {
|
||||
|
||||
constructor(db, root) {
|
||||
@ -54,8 +46,8 @@ class SMT {
|
||||
const ins = [];
|
||||
const dels = [];
|
||||
|
||||
let rtOld = smtHash([1, key, resFind.foundValue]);
|
||||
let rtNew = smtHash([1, key, newValue]);
|
||||
let rtOld = mimc7.multiHash([1, key, resFind.foundValue]);
|
||||
let rtNew = mimc7.multiHash([1, key, newValue]);
|
||||
ins.push([rtNew, [1, key, newValue ]]);
|
||||
dels.push(rtOld);
|
||||
|
||||
@ -70,8 +62,8 @@ class SMT {
|
||||
oldNode = [rtOld, sibling, ];
|
||||
newNode = [rtNew, sibling, ];
|
||||
}
|
||||
rtOld = smtHash(oldNode);
|
||||
rtNew = smtHash(newNode);
|
||||
rtOld = mimc7.multiHash(oldNode);
|
||||
rtNew = mimc7.multiHash(newNode);
|
||||
dels.push(rtOld);
|
||||
ins.push([rtNew, newNode]);
|
||||
}
|
||||
@ -100,7 +92,7 @@ class SMT {
|
||||
|
||||
const dels = [];
|
||||
const ins = [];
|
||||
let rtOld = smtHash([1, key, resFind.foundValue]);
|
||||
let rtOld = mimc7.multiHash([1, key, resFind.foundValue]);
|
||||
let rtNew;
|
||||
dels.push(rtOld);
|
||||
|
||||
@ -138,9 +130,9 @@ class SMT {
|
||||
}
|
||||
const oldSibling = resFind.siblings[level];
|
||||
if (keyBits[level]) {
|
||||
rtOld = smtHash([oldSibling, rtOld]);
|
||||
rtOld = mimc7.multiHash([oldSibling, rtOld]);
|
||||
} else {
|
||||
rtOld = smtHash([rtOld, oldSibling]);
|
||||
rtOld = mimc7.multiHash([rtOld, oldSibling]);
|
||||
}
|
||||
dels.push(rtOld);
|
||||
if (!newSibling.isZero()) {
|
||||
@ -155,7 +147,7 @@ class SMT {
|
||||
} else {
|
||||
newNode = [rtNew, newSibling];
|
||||
}
|
||||
rtNew = smtHash(newNode);
|
||||
rtNew = mimc7.multiHash(newNode);
|
||||
ins.push([rtNew, newNode]);
|
||||
}
|
||||
}
|
||||
@ -193,7 +185,7 @@ class SMT {
|
||||
for (let i= res.siblings.length; oldKeyits[i] == newKeyBits[i]; i++) {
|
||||
res.siblings.push(bigInt.zero);
|
||||
}
|
||||
rtOld = smtHash([1, resFind.notFoundKey, resFind.notFoundValue]);
|
||||
rtOld = mimc7.multiHash([1, resFind.notFoundKey, resFind.notFoundValue]);
|
||||
res.siblings.push(rtOld);
|
||||
addedOne = true;
|
||||
mixed = false;
|
||||
@ -205,7 +197,7 @@ class SMT {
|
||||
const inserts = [];
|
||||
const dels = [];
|
||||
|
||||
let rt = smtHash([1, key, value]);
|
||||
let rt = mimc7.multiHash([1, key, value]);
|
||||
inserts.push([rt,[1, key, value]] );
|
||||
|
||||
for (let i=res.siblings.length-1; i>=0; i--) {
|
||||
@ -215,9 +207,9 @@ class SMT {
|
||||
if (mixed) {
|
||||
const oldSibling = resFind.siblings[i];
|
||||
if (newKeyBits[i]) {
|
||||
rtOld = smtHash([oldSibling, rtOld]);
|
||||
rtOld = mimc7.multiHash([oldSibling, rtOld]);
|
||||
} else {
|
||||
rtOld = smtHash([rtOld, oldSibling]);
|
||||
rtOld = mimc7.multiHash([rtOld, oldSibling]);
|
||||
}
|
||||
dels.push(rtOld);
|
||||
}
|
||||
@ -225,10 +217,10 @@ class SMT {
|
||||
|
||||
let newRt;
|
||||
if (newKeyBits[i]) {
|
||||
newRt = smtHash([res.siblings[i], rt]);
|
||||
newRt = mimc7.multiHash([res.siblings[i], rt]);
|
||||
inserts.push([newRt,[res.siblings[i], rt]] );
|
||||
} else {
|
||||
newRt = smtHash([rt, res.siblings[i]]);
|
||||
newRt = mimc7.multiHash([rt, res.siblings[i]]);
|
||||
inserts.push([newRt,[rt, res.siblings[i]]] );
|
||||
}
|
||||
rt = newRt;
|
||||
|
3
test/circuits/eddsamimc_test.circom
Normal file
3
test/circuits/eddsamimc_test.circom
Normal file
@ -0,0 +1,3 @@
|
||||
include "../../circuits/eddsamimc.circom";
|
||||
|
||||
component main = EdDSAMiMCVerifier();
|
98
test/eddsamimc.js
Normal file
98
test/eddsamimc.js
Normal file
@ -0,0 +1,98 @@
|
||||
const chai = require("chai");
|
||||
const path = require("path");
|
||||
const snarkjs = require("snarkjs");
|
||||
const compiler = require("circom");
|
||||
|
||||
const eddsa = require("../src/eddsa.js");
|
||||
|
||||
const assert = chai.assert;
|
||||
|
||||
const bigInt = snarkjs.bigInt;
|
||||
|
||||
describe("EdDSA test", function () {
|
||||
let circuit;
|
||||
|
||||
this.timeout(100000);
|
||||
|
||||
before( async () => {
|
||||
const cirDef = await compiler(path.join(__dirname, "circuits", "eddsamimc_test.circom"));
|
||||
|
||||
circuit = new snarkjs.Circuit(cirDef);
|
||||
|
||||
console.log("NConstrains EdDSA: " + circuit.nConstraints);
|
||||
});
|
||||
|
||||
it("Sign a single number", async () => {
|
||||
const msg = bigInt(1234);
|
||||
|
||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||
|
||||
const pubKey = eddsa.prv2pub(prvKey);
|
||||
|
||||
const signature = eddsa.signMiMC(prvKey, msg);
|
||||
|
||||
assert(eddsa.verifyMiMC(msg, signature, pubKey));
|
||||
|
||||
const w = circuit.calculateWitness({
|
||||
enabled: 1,
|
||||
Ax: pubKey[0],
|
||||
Ay: pubKey[1],
|
||||
R8x: signature.R8[0],
|
||||
R8y: signature.R8[1],
|
||||
S: signature.S,
|
||||
M: msg});
|
||||
|
||||
assert(circuit.checkWitness(w));
|
||||
});
|
||||
|
||||
it("Detect Invalid signature", async () => {
|
||||
const msg = bigInt(1234);
|
||||
|
||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||
|
||||
const pubKey = eddsa.prv2pub(prvKey);
|
||||
|
||||
|
||||
const signature = eddsa.signMiMC(prvKey, msg);
|
||||
|
||||
assert(eddsa.verifyMiMC(msg, signature, pubKey));
|
||||
try {
|
||||
const w = circuit.calculateWitness({
|
||||
enabled: 1,
|
||||
Ax: pubKey[0],
|
||||
Ay: pubKey[1],
|
||||
R8x: signature.R8[0].add(bigInt(1)),
|
||||
R8y: signature.R8[1],
|
||||
S: signature.S,
|
||||
M: msg});
|
||||
assert(false);
|
||||
} catch(err) {
|
||||
assert.equal(err.message, "Constraint doesn't match: 1 != 0");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
it("Test a dissabled circuit with a bad signature", async () => {
|
||||
const msg = bigInt(1234);
|
||||
|
||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||
|
||||
const pubKey = eddsa.prv2pub(prvKey);
|
||||
|
||||
|
||||
const signature = eddsa.signMiMC(prvKey, msg);
|
||||
|
||||
assert(eddsa.verifyMiMC(msg, signature, pubKey));
|
||||
|
||||
const w = circuit.calculateWitness({
|
||||
enabled: 0,
|
||||
Ax: pubKey[0],
|
||||
Ay: pubKey[1],
|
||||
R8x: signature.R8[0].add(bigInt(1)),
|
||||
R8y: signature.R8[1],
|
||||
S: signature.S,
|
||||
M: msg});
|
||||
|
||||
assert(circuit.checkWitness(w));
|
||||
});
|
||||
});
|
@ -22,7 +22,6 @@ async function testInsert(tree, key, value, circuit, log ) {
|
||||
const w = circuit.calculateWitness({
|
||||
fnc: [1,0],
|
||||
oldRoot: res.oldRoot,
|
||||
newRoot: res.newRoot,
|
||||
siblings: siblings,
|
||||
oldKey: res.isOld0 ? 0 : res.oldKey,
|
||||
oldValue: res.isOld0 ? 0 : res.oldValue,
|
||||
@ -31,7 +30,7 @@ async function testInsert(tree, key, value, circuit, log ) {
|
||||
newValue: value
|
||||
}, log);
|
||||
|
||||
const root1 = w[circuit.getSignalIdx("main.topSwitcher.outR")];
|
||||
const root1 = w[circuit.getSignalIdx("main.newRoot")];
|
||||
assert(circuit.checkWitness(w));
|
||||
assert(root1.equals(res.newRoot));
|
||||
}
|
||||
@ -44,7 +43,6 @@ async function testDelete(tree, key, circuit) {
|
||||
const w = circuit.calculateWitness({
|
||||
fnc: [1,1],
|
||||
oldRoot: res.oldRoot,
|
||||
newRoot: res.newRoot,
|
||||
siblings: siblings,
|
||||
oldKey: res.isOld0 ? 0 : res.oldKey,
|
||||
oldValue: res.isOld0 ? 0 : res.oldValue,
|
||||
@ -53,7 +51,7 @@ async function testDelete(tree, key, circuit) {
|
||||
newValue: res.delValue
|
||||
});
|
||||
|
||||
const root1 = w[circuit.getSignalIdx("main.topSwitcher.outR")];
|
||||
const root1 = w[circuit.getSignalIdx("main.newRoot")];
|
||||
|
||||
assert(circuit.checkWitness(w));
|
||||
assert(root1.equals(res.newRoot));
|
||||
@ -67,7 +65,6 @@ async function testUpdate(tree, key, newValue, circuit) {
|
||||
const w = circuit.calculateWitness({
|
||||
fnc: [0,1],
|
||||
oldRoot: res.oldRoot,
|
||||
newRoot: res.newRoot,
|
||||
siblings: siblings,
|
||||
oldKey: res.oldKey,
|
||||
oldValue: res.oldValue,
|
||||
@ -76,7 +73,7 @@ async function testUpdate(tree, key, newValue, circuit) {
|
||||
newValue: res.newValue
|
||||
});
|
||||
|
||||
const root1 = w[circuit.getSignalIdx("main.topSwitcher.outR")];
|
||||
const root1 = w[circuit.getSignalIdx("main.newRoot")];
|
||||
|
||||
assert(circuit.checkWitness(w));
|
||||
assert(root1.equals(res.newRoot));
|
||||
@ -185,7 +182,6 @@ describe("SMT test", function () {
|
||||
const w = circuit.calculateWitness({
|
||||
fnc: [0,0],
|
||||
oldRoot: 11,
|
||||
newRoot: 22,
|
||||
siblings: siblings,
|
||||
oldKey: 33,
|
||||
oldValue: 44,
|
||||
@ -194,7 +190,11 @@ describe("SMT test", function () {
|
||||
newValue: 77
|
||||
});
|
||||
|
||||
const root1 = w[circuit.getSignalIdx("main.oldRoot")];
|
||||
const root2 = w[circuit.getSignalIdx("main.newRoot")];
|
||||
|
||||
assert(circuit.checkWitness(w));
|
||||
assert(root1.equals(root2));
|
||||
|
||||
});
|
||||
it("Should update an element", async () => {
|
||||
|
@ -22,6 +22,7 @@ async function testInclusion(tree, key, circuit) {
|
||||
while (siblings.length<10) siblings.push(bigInt(0));
|
||||
|
||||
const w = circuit.calculateWitness({
|
||||
enabled: 1,
|
||||
fnc: 0,
|
||||
root: tree.root,
|
||||
siblings: siblings,
|
||||
@ -43,6 +44,7 @@ async function testExclusion(tree, key, circuit) {
|
||||
while (siblings.length<10) siblings.push(bigInt(0));
|
||||
|
||||
const w = circuit.calculateWitness({
|
||||
enabled: 1,
|
||||
fnc: 1,
|
||||
root: tree.root,
|
||||
siblings: siblings,
|
||||
@ -91,5 +93,23 @@ describe("SMT test", function () {
|
||||
await testExclusion(tree, 64, circuit);
|
||||
});
|
||||
|
||||
it("Check not enabled accepts any thing", async () => {
|
||||
let siblings = [];
|
||||
for (let i=0; i<10; i++) siblings.push(i);
|
||||
|
||||
const w = circuit.calculateWitness({
|
||||
enabled: 0,
|
||||
fnc: 0,
|
||||
root: 1,
|
||||
siblings: siblings,
|
||||
oldKey: 22,
|
||||
oldValue: 33,
|
||||
isOld0: 0,
|
||||
key: 44,
|
||||
value: 0
|
||||
});
|
||||
assert(circuit.checkWitness(w));
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user