Fix MACI 1.0 ProcessMessages circuit to prevent message censorship by the coordinator
weijiekoh opened this issue · 0 comments
weijiekoh commented
This new design iterates through each message and checks a Merkle path to an intermediate state root. This way, we ensure that no state leaves can be manipulated by the coordinator.
// in this example, batchSize = 4
// The decrypted messages
signal commands[batchSize];
// These are leaves targeted by the commands
signal private input leavesToOperateOn[batchSize];
/*
Note that leavesToOperateOn = [
stateLeavesInTree[command[0].stateIndex]]
stateLeavesInTree[command[1].stateIndex]]
stateLeavesInTree[command[2].stateIndex]]
stateLeavesInTree[command[3].stateIndex]]
]
stateLeavesInTree refers to the actual state leaves. e.g. in a tree of depth 2 and arity 2, stateLeavesInTree = [leaf0, leaf1, leaf2, leaf3].
*/
// The state root before it is processed. Actually, this value is from the
// contract.
signal private input currentStateRoot;
// The intermediate state roots
signal input updatedRoots[batchSize]
// The Merkle proofs per leavesToOperateOn
signal private input pathElements[batchSize][arity];
1. CHECK that leavesToOperateOn[0] **is a member of** currentStateRoot
- use pathElements[0] to reconstruct a root and then compare it with currentStateRoot
2. APPLY commands[0] to leavesToOperateOn[0] AND SET IT AS updatedRoot[0]
- use pathElements[0] to construct the root and set it as updatedRoot[0]
3. CHECK that leavesToOperateOn[1] **is a member of** updatedRoot[0]
- use pathElements[1] to reconstruct a root and then compare it with updatedRoot[0]
4. APPLY commands[1] to leavesToOperateOn[1] AND SET IT AS updatedRoot[1]
- use pathElements[1] to construct the root and set it as updatedRoot[1]
5. CHECK that leavesToOperateOn[2] **is a member of** updatedRoot[1]
6. APPLY commands[2] to leavesToOperateOn[2] AND SET IT AS updatedRoot[2]
7. CHECK that leavesToOperateOn[3] **is a member of** updatedRoot[2]
8. APPLY commands[3] to leavesToOperateOn[3] AND SET IT AS final state root