mirror of
https://github.com/arnaucube/circomlib.git
synced 2026-02-06 18:56:43 +01:00
fix: makes mimcsponge usable
This commit is contained in:
123
circuits/eddsamimcsponge.circom
Normal file
123
circuits/eddsamimcsponge.circom
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
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 "mimcsponge.circom";
|
||||||
|
include "bitify.circom";
|
||||||
|
include "escalarmulany.circom";
|
||||||
|
include "escalarmulfix.circom";
|
||||||
|
|
||||||
|
template EdDSAMiMCSpongeVerifier() {
|
||||||
|
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 = MiMCSponge(5, 220, 1);
|
||||||
|
hash.ins[0] <== R8x;
|
||||||
|
hash.ins[1] <== R8y;
|
||||||
|
hash.ins[2] <== Ax;
|
||||||
|
hash.ins[3] <== Ay;
|
||||||
|
hash.ins[4] <== M;
|
||||||
|
hash.k <== 0;
|
||||||
|
|
||||||
|
component h2bits = Num2Bits_strict();
|
||||||
|
h2bits.in <== hash.outs[0];
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
1
index.js
1
index.js
@@ -1,4 +1,5 @@
|
|||||||
exports.smt = require("./src/smt");
|
exports.smt = require("./src/smt");
|
||||||
exports.eddsa = require("./src/eddsa");
|
exports.eddsa = require("./src/eddsa");
|
||||||
exports.mimc7 = require("./src/mimc7");
|
exports.mimc7 = require("./src/mimc7");
|
||||||
|
exports.mimcsponge = require("./src/mimcsponge");
|
||||||
exports.babyJub = require("./src/babyjub");
|
exports.babyJub = require("./src/babyjub");
|
||||||
|
|||||||
44
src/eddsa.js
44
src/eddsa.js
@@ -3,12 +3,15 @@ const bigInt = require("snarkjs").bigInt;
|
|||||||
const babyJub = require("./babyjub");
|
const babyJub = require("./babyjub");
|
||||||
const pedersenHash = require("./pedersenHash").hash;
|
const pedersenHash = require("./pedersenHash").hash;
|
||||||
const mimc7 = require("./mimc7");
|
const mimc7 = require("./mimc7");
|
||||||
|
const mimcsponge = require("./mimcsponge");
|
||||||
|
|
||||||
exports.prv2pub= prv2pub;
|
exports.prv2pub= prv2pub;
|
||||||
exports.sign = sign;
|
exports.sign = sign;
|
||||||
exports.signMiMC = signMiMC;
|
exports.signMiMC = signMiMC;
|
||||||
|
exports.signMiMCSponge = signMiMCSponge;
|
||||||
exports.verify = verify;
|
exports.verify = verify;
|
||||||
exports.verifyMiMC = verifyMiMC;
|
exports.verifyMiMC = verifyMiMC;
|
||||||
|
exports.verifyMiMCSponge = verifyMiMCSponge;
|
||||||
exports.packSignature = packSignature;
|
exports.packSignature = packSignature;
|
||||||
exports.unpackSignature = unpackSignature;
|
exports.unpackSignature = unpackSignature;
|
||||||
exports.pruneBuffer = pruneBuffer;
|
exports.pruneBuffer = pruneBuffer;
|
||||||
@@ -69,6 +72,25 @@ 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 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 = mimcsponge.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) {
|
function verify(msg, sig, A) {
|
||||||
// Check parameters
|
// Check parameters
|
||||||
if (typeof sig != "object") return false;
|
if (typeof sig != "object") return false;
|
||||||
@@ -116,6 +138,28 @@ function verifyMiMC(msg, sig, A) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function verifyMiMCSponge(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 = 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")));
|
||||||
|
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) {
|
function packSignature(sig) {
|
||||||
const R8p = babyJub.packPoint(sig.R8);
|
const R8p = babyJub.packPoint(sig.R8);
|
||||||
const Sp = bigInt.leInt2Buff(sig.S, 32);
|
const Sp = bigInt.leInt2Buff(sig.S, 32);
|
||||||
|
|||||||
@@ -53,6 +53,10 @@ exports.multiHash = (arr, key, numOutputs) => {
|
|||||||
if (typeof(numOutputs) === "undefined") {
|
if (typeof(numOutputs) === "undefined") {
|
||||||
numOutputs = 1;
|
numOutputs = 1;
|
||||||
}
|
}
|
||||||
|
if (typeof(key) === "undefined") {
|
||||||
|
key = F.zero;
|
||||||
|
}
|
||||||
|
|
||||||
let R = F.zero;
|
let R = F.zero;
|
||||||
let C = F.zero;
|
let C = F.zero;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user