Very minor things:
- A few renames
- Instead of having two constructors call a third constructor, just have one constructor call the other.
- Invoke FFT with the option that specifies the inputs are mostly zero, as a (minor) optimization
- Remove unused field
* Bit of refactoring in FRI code
- Inline `OpeningSet[Target]` and their `verify` methods, as they had become fairly trivial wrappers
- Have the challenger observe the openings and generate alpha inside `verify_fri_proof`. Conceptually I think of it as part of the batch-FRI protocol, and it minimizes redundancy.
* Fix tests
* Add a reduce_polys_base
Reducing the polynomials in `open_plonk` was taking ~100ms on my machine. It was converting BF polynomials to the EF early on; by doing more work in the BF we can reduce it to ~20ms.
* PR feedback
* Add a tree of scopes for proving times
To replace the old `timed!` macro, which had no hierarchy.
It's similar to `ContextTree`, which tracks gate counts of circuit operations.
This gives a more organized output, with indentation levels based on scope depth, parent durations listed before child durations, etc.
* PR feedback
No functional changes here. The biggest change was moving certain files into new directories like `plonk` and `iop` (for things like `Challenger` that could be used in STARKs or other IOPs). I also split a few files, renames, etc, but again nothing functional, so I don't think a careful review is necessary (just a sanity check).
We have two division methods: one "unsafe" one, which permits 0/0 = anything, and one "safe" one, for which 0/0 results in an unsatisfiable instance. The latter is slightly more expensive.
I switched a few calls over to safe division, where unsafe division didn't seem sound (or at least it wasn't obvious). For calls where unsafe division did seem sound, I added comments explaining why.
Closes#97.
* Tree of scopes
This is an extension of the context concept.
Earlier I was planning to store a simple stack of contexts, but I ended up storing the whole history, in a tree structure. This gives us more control over the output, i.e. we can print the gate count of a parent scope before those of its child scopes, which seems more user-friendly.
Sample gate count output:
[2021-07-19T18:09:24Z INFO plonky2::circuit_builder] 27829 gates to root
[2021-07-19T18:09:24Z INFO plonky2::circuit_builder] | 2373 gates to evaluate the vanishing polynomial at our challenge point, zeta.
[2021-07-19T18:09:24Z INFO plonky2::circuit_builder] | | 1284 gates to evaluate gate constraints
[2021-07-19T18:09:24Z INFO plonky2::circuit_builder] | 25312 gates to verify FRI proof
[2021-07-19T18:09:24Z INFO plonky2::circuit_builder] | | 650 gates to verify 0'th FRI query
[2021-07-19T18:09:24Z INFO plonky2::circuit_builder] | | | 96 gates to check FRI initial proof
[2021-07-19T18:09:24Z INFO plonky2::circuit_builder] | | | 65 gates to compute x from its index
[2021-07-19T18:09:24Z INFO plonky2::circuit_builder] | | | 233 gates to combine initial oracles
...
Sample copy constraint failure:
Error: Copy constraint 'root > verify FRI proof > verify 0'th FRI query > check FRI initial proof > verify 0'th initial Merkle proof > check Merkle root: 0-th hash element' between wire 12 of gate #2550 [...] and wire 0 of gate #0 [...] is not satisfied. Got values of 6861386743364621393 and 0 respectively.
* No min
* info -> debug
* Move to its own file
* Make ZK optional
* Remove rate from FriConfig
Seems redundant, and we've had some tests break due to the two fields not matching.
* zero_knowledge: false in bench