AztecProtocol / barretenberg

Apache License 2.0
138 stars 87 forks source link

Merge subtlety in ClientIvc #993

Open ledwards2225 opened 4 months ago

ledwards2225 commented 4 months ago

TLDR: the op queue and the interactions around it are a mess.

As part of the "avoid zero commitments" issue, we add "mock" (arbitrary) ecc ops to GU circuits in two places, both in the proverInstance constructor: 1) Via call to method ECCOpQueue::append_nonzero_ops() (see issue and comments here) and 2) via some ops added in GoblinUltraCircuitBuilder::add_gates_to_ensure_all_polys_are_non_zero(). Ok, fine. Now, in ClientIvc::accumulate(circuit) we call goblin.merge(circuit) prior to constructing an instance. So if no genuine ecc ops were added to the circuit during its construction, the merge protocol will try to 'merge' nothing, and this will lead to the commitment C_t_shift being the point at infinity.

One option would be to simply not run the merge prover if there are no ops to merge, but this leads to some icky issues because we ARE adding ecc ops to EVERY circuit, just sometimes not until after we've run the merge prover.

Possibly the right thing involves two updates: 1) split up the functionality in goblin.merge() into two: recursive merge verification of the previous merge proof, and construction of a new merge proof. Run the former prior to constructing an instance (since it adds gates) and run the latter AFTER. 2) Only run the merge prover if the circuit has ops to merge. (Right now they all have ops to avoid zero commitments but eventually some won't).