Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions circuit/src/voterollup.circom
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ template VoteRollup(nBatchSize, nLevels) {

/// check votes --------------------------------------------------------------

var computedResult = 0;
signal computedResult[nBatchSize+1];
computedResult[0] <== 0;

component sigVerification[nBatchSize];
component processor[nBatchSize];
Expand Down Expand Up @@ -144,9 +145,8 @@ template VoteRollup(nBatchSize, nLevels) {
lastRootEqual[i].in[0] <== processor[i].newRoot;
lastRootEqual[i].in[1] <== newNullifiersRoot;

computedResult = computedResult + voteValue[i];
computedResult[i+1] <== computedResult[i] + voteValue[i] * verify[i].out;
}

result === computedResult;

result === computedResult[nBatchSize];
}
58 changes: 47 additions & 11 deletions circuit/test/rollup.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@ describe("Test rollup", function () {

before( async() => {
const circuitCode = `
include "../src/voterollup.circom";
component main = VoteRollup(2,2);
`;

fs.writeFileSync(circuitPath, circuitCode, "utf8");
circuit = await tester(circuitPath, {reduceConstraints:false});
await circuit.loadConstraints();
console.log("Constraints: " + circuit.constraints.length + "\n");
include "../src/voterollup.circom";
component main = VoteRollup(2,2);
`;

fs.writeFileSync(circuitPath, circuitCode, "utf8");
circuit = await tester(circuitPath, {reduceConstraints:false});
await circuit.loadConstraints();
console.log("Constraints: " + circuit.constraints.length + "\n");
});

after( async() => {
fs.unlinkSync(circuitPath);
fs.unlinkSync(circuitPath);
});

it("1 batch, 1 vote, batchSize 2", async () => {
Expand Down Expand Up @@ -63,10 +63,46 @@ describe("Test rollup", function () {
let input2 = await rollup.rollup([
await V3.vote(1n,30000n),
]);

const w2 = await circuit.calculateWitness(input2, { logTrigger:false, logOutput: false, logSet: false });
await circuit.checkConstraints(w2);
});

it("Ensure that voteValues that don't have their signature are not counted", async () => {
// The circuit should not allow a prover to generate a valid proof
// without real votes (real votes = voteValue + valid signature), as
// then, it would be possible to present a proof that would pass
// verifications, claiming a result that has no real votes. Meaning
// that a prover could provide a valid zk-proof claiming a result
// without real votes behind it, and the verification would accept it.
//
// If this test fails, means that a prover could provide a valid
// zk-proof claiming a result without real votes behind it.

let rollup = new Rollup(1n,2,2);
let input = await rollup.rollup([
await V1.vote(1n,10000n),
]);

// add the extra non-valid vote (without any signature)
input.voteValue[1] = 30000n;

// result should still be 10000, without counting that extra 30000
// voteValue that does not have any signature. Set the result to 40000
// simulating a malicious prover, to check if the circuit does not
// accept it.
input.result = 40000n;

try {
const w = await circuit.calculateWitness(input, { logTrigger:false, logOutput: false, logSet: false });
await circuit.checkConstraints(w);

// The line will only be reached if no error is thrown above
throw new Error(`If this line is reached, means that the circuit`+
`counted in the result invalid votes that don't have signatures.`);
} catch(err) {
// the fake vote with value 30000 should not be included in the result
expect(err.message).to.not.contain("If this line is reached, means that");
}
});
});