merkleTree.circom 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. include "../node_modules/circomlib/circuits/mimcsponge.circom";
  2. // Computes MiMC(left + right)
  3. template HashLeftRight(rounds) {
  4. signal input left;
  5. signal input right;
  6. signal output hash;
  7. component hasher = MiMCSponge(2, rounds, 1);
  8. hasher.ins[0] <== left;
  9. hasher.ins[1] <== right;
  10. hasher.k <== 0;
  11. hash <== hasher.outs[0];
  12. }
  13. // if pathIndex == 0 returns (left = inputElement, right = pathElement)
  14. // if pathIndex == 1 returns (left = pathElement, right = inputElement)
  15. template Selector() {
  16. signal input inputElement;
  17. signal input pathElement;
  18. signal input pathIndex;
  19. signal output left;
  20. signal output right;
  21. signal leftSelector1;
  22. signal leftSelector2;
  23. signal rightSelector1;
  24. signal rightSelector2;
  25. pathIndex * (1-pathIndex) === 0
  26. leftSelector1 <== (1 - pathIndex) * inputElement;
  27. leftSelector2 <== (pathIndex) * pathElement;
  28. rightSelector1 <== (pathIndex) * inputElement;
  29. rightSelector2 <== (1 - pathIndex) * pathElement;
  30. left <== leftSelector1 + leftSelector2;
  31. right <== rightSelector1 + rightSelector2;
  32. }
  33. // Verifies that merkle proof is correct for given merkle root and a leaf
  34. // pathIndex input is an array of 0/1 selectors telling whether given pathElement is on the left or right side of merkle path
  35. template MerkleTree(levels, rounds) {
  36. signal input leaf;
  37. signal input root;
  38. signal private input pathElements[levels];
  39. signal private input pathIndex[levels];
  40. component selectors[levels];
  41. component hashers[levels];
  42. for (var i = 0; i < levels; i++) {
  43. selectors[i] = Selector();
  44. hashers[i] = HashLeftRight(rounds);
  45. selectors[i].pathElement <== pathElements[i];
  46. selectors[i].pathIndex <== pathIndex[i];
  47. hashers[i].left <== selectors[i].left;
  48. hashers[i].right <== selectors[i].right;
  49. }
  50. selectors[0].inputElement <== leaf;
  51. for (var i = 1; i < levels; i++) {
  52. selectors[i].inputElement <== hashers[i-1].hash;
  53. }
  54. root === hashers[levels - 1].hash;
  55. }