Use switcher from circomlib

This commit is contained in:
poma 2021-08-24 19:19:26 +03:00
parent 454adf3720
commit d93a6d6298
No known key found for this signature in database
GPG Key ID: BA20CB01FE165657
2 changed files with 15 additions and 39 deletions

View File

@ -1,28 +1,5 @@
include "../node_modules/circomlib/circuits/poseidon.circom"; include "../node_modules/circomlib/circuits/poseidon.circom";
include "../node_modules/circomlib/circuits/switcher.circom";
// Computes MiMC([left, right])
template HashLeftRight() {
signal input left;
signal input right;
signal output hash;
component hasher = Poseidon(2);
hasher.inputs[0] <== left;
hasher.inputs[1] <== right;
hash <== hasher.out;
}
// if s == 0 returns [in[0], in[1]]
// if s == 1 returns [in[1], in[0]]
template DualMux() {
signal input in[2];
signal input s;
signal output out[2];
s * (1 - s) === 0
out[0] <== (in[1] - in[0])*s + in[0];
out[1] <== (in[0] - in[1])*s + in[1];
}
// Verifies that merkle proof is correct for given merkle root and a leaf // Verifies that merkle proof is correct for given merkle root and a leaf
// pathIndices input is an array of 0/1 selectors telling whether given pathElement is on the left or right side of merkle path // pathIndices input is an array of 0/1 selectors telling whether given pathElement is on the left or right side of merkle path
@ -30,25 +7,24 @@ template MerkleTree(levels) {
signal input leaf; signal input leaf;
signal input pathElements[levels]; signal input pathElements[levels];
signal input pathIndices; signal input pathIndices;
signal output root; signal output root;
component selectors[levels]; component switcher[levels];
component hashers[levels]; component hasher[levels];
component indexBits = Num2Bits(levels); component indexBits = Num2Bits(levels);
indexBits.in <== pathIndices; indexBits.in <== pathIndices;
for (var i = 0; i < levels; i++) { for (var i = 0; i < levels; i++) {
selectors[i] = DualMux(); switcher[i] = Switcher();
selectors[i].in[0] <== i == 0 ? leaf : hashers[i - 1].hash; switcher[i].L <== i == 0 ? leaf : hasher[i - 1].out;
selectors[i].in[1] <== pathElements[i]; switcher[i].R <== pathElements[i];
selectors[i].s <== indexBits.out[i]; switcher[i].sel <== indexBits.out[i];
hashers[i] = HashLeftRight(); hasher[i] = Poseidon(2);
hashers[i].left <== selectors[i].out[0]; hasher[i].inputs[0] <== switcher[i].outL;
hashers[i].right <== selectors[i].out[1]; hasher[i].inputs[1] <== switcher[i].outR;
} }
root <== hashers[levels - 1].hash; root <== hasher[levels - 1].out;
} }

View File

@ -17,9 +17,9 @@ template TreeUpdater(levels, subtreeLevels, zeroSubtreeRoot) {
// calculate subtree root // calculate subtree root
// todo: make it work with arbitrary subtree levels // todo: make it work with arbitrary subtree levels
// currently it works only with 1-level subtrees // currently it works only with 1-level subtrees
component leafPair = HashLeftRight(); component leafPair = Poseidon(2);
leafPair.left <== leaf[0]; leafPair.inputs[0] <== leaf[0];
leafPair.right <== leaf[1]; leafPair.inputs[1] <== leaf[1];
component treeBefore = MerkleTree(remainingLevels); component treeBefore = MerkleTree(remainingLevels);
for(var i = 0; i < remainingLevels; i++) { for(var i = 0; i < remainingLevels; i++) {
@ -34,6 +34,6 @@ template TreeUpdater(levels, subtreeLevels, zeroSubtreeRoot) {
treeAfter.pathElements[i] <== pathElements[i]; treeAfter.pathElements[i] <== pathElements[i];
} }
treeAfter.pathIndices <== pathIndices; treeAfter.pathIndices <== pathIndices;
treeAfter.leaf <== leafPair.hash; treeAfter.leaf <== leafPair.out;
treeAfter.root === newRoot; treeAfter.root === newRoot;
} }