mirror of
https://github.com/arnaucube/circomlib.git
synced 2026-02-06 18:56:43 +01:00
Small patches
This commit is contained in:
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user