tornado-trees/circuits/TreeUpdateArgsHasher.circom

72 lines
2.4 KiB
Plaintext
Raw Normal View History

2021-02-01 14:40:32 +01:00
include "../node_modules/circomlib/circuits/bitify.circom";
include "../node_modules/circomlib/circuits/sha256/sha256.circom";
2021-03-20 21:48:26 +01:00
// Computes a SHA256 hash of all inputs packed into a byte array
// Field elements are padded to 256 bits with zeroes
2021-02-01 14:40:32 +01:00
template TreeUpdateArgsHasher(nLeaves) {
2021-03-20 21:48:26 +01:00
signal input oldRoot;
signal input newRoot;
signal input pathIndices;
signal input instances[nLeaves];
signal input hashes[nLeaves];
signal input blocks[nLeaves];
2021-02-01 14:40:32 +01:00
signal output out;
var header = 256 + 256 + 32;
2021-03-19 21:08:46 +01:00
var bitsPerLeaf = 256 + 160 + 32;
2021-02-01 14:40:32 +01:00
component hasher = Sha256(header + nLeaves * bitsPerLeaf);
2021-02-24 11:39:14 +01:00
// the range check on old root is optional, it's enforced by smart contract anyway
2021-02-23 10:13:51 +01:00
component bitsOldRoot = Num2Bits_strict();
component bitsNewRoot = Num2Bits_strict();
2021-02-01 14:40:32 +01:00
component bitsPathIndices = Num2Bits(32);
component bitsInstance[nLeaves];
component bitsHash[nLeaves];
component bitsBlock[nLeaves];
2021-02-23 10:13:51 +01:00
2021-02-01 14:40:32 +01:00
bitsOldRoot.in <== oldRoot;
bitsNewRoot.in <== newRoot;
bitsPathIndices.in <== pathIndices;
2021-02-23 10:13:51 +01:00
var index = 0;
hasher.in[index++] <== 0;
hasher.in[index++] <== 0;
2021-02-23 10:13:51 +01:00
for(var i = 0; i < 254; i++) {
hasher.in[index++] <== bitsOldRoot.out[253 - i];
2021-02-01 14:40:32 +01:00
}
hasher.in[index++] <== 0;
hasher.in[index++] <== 0;
2021-02-23 10:13:51 +01:00
for(var i = 0; i < 254; i++) {
hasher.in[index++] <== bitsNewRoot.out[253 - i];
2021-02-01 14:40:32 +01:00
}
for(var i = 0; i < 32; i++) {
hasher.in[index++] <== bitsPathIndices.out[31 - i];
2021-02-01 14:40:32 +01:00
}
for(var leaf = 0; leaf < nLeaves; leaf++) {
2021-02-24 11:39:14 +01:00
// the range check on hash is optional, it's enforced by the smart contract anyway
bitsHash[leaf] = Num2Bits_strict();
2021-02-01 14:40:32 +01:00
bitsInstance[leaf] = Num2Bits(160);
bitsBlock[leaf] = Num2Bits(32);
bitsHash[leaf].in <== hashes[leaf];
bitsInstance[leaf].in <== instances[leaf];
bitsBlock[leaf].in <== blocks[leaf];
hasher.in[index++] <== 0;
hasher.in[index++] <== 0;
2021-02-24 11:39:14 +01:00
for(var i = 0; i < 254; i++) {
hasher.in[index++] <== bitsHash[leaf].out[253 - i];
2021-02-01 14:40:32 +01:00
}
for(var i = 0; i < 160; i++) {
hasher.in[index++] <== bitsInstance[leaf].out[159 - i];
2021-02-01 14:40:32 +01:00
}
for(var i = 0; i < 32; i++) {
hasher.in[index++] <== bitsBlock[leaf].out[31 - i];
2021-02-01 14:40:32 +01:00
}
}
component b2n = Bits2Num(256);
for (var i = 0; i < 256; i++) {
b2n.in[i] <== hasher.out[255 - i];
}
out <== b2n.out;
2021-02-23 10:13:51 +01:00
}