* 2 challenges, 28 routed wires
2 challenges gives certain checks approximately (field_bits - degree_bits) * 2 bits of security, so we maintain our target of 100 bits for circuits with 2^14 gates or fewer.
28 routed wires is the min for `InterpolationGate`. A lower number helps reduce proof sizes. We can go back to a high number if there's any strong reason to reduce our gate count (e.g. if we were trying to hit 2^12).
* Check FRI conjectured security
* Fix
* Automatically select FRI reduction arities
This way when a proof's degree changes, we won't need to manually update the `FriConfig`s of any recursive proofs on top of it.
For now I've added two methods of selecting arities. The first, `ConstantArityBits`, just applies a fixed reduciton arity until the degree has shrunk below a certain threshold. The second, `MinSize`, searches for the sequence of arities that minimizes proof size.
Note that this optimization is approximate -- e.g. it doesn't account for the effect of compression, and doesn't count some minor contributions to proof size, like the Merkle roots from the commit phase. It also assumes we're not using Merkle caps in serialized proofs, and that we're inferring one of the evaluations, even though we haven't made those changes yet.
I think we should generally use `ConstantArityBits` for proofs that we will recurse on, since using a single arity tends to be more recursion-friendly. We could use `MinSize` for generating final bridge proofs, since we won't do further recursion on top of those.
* Fix tests
* Feedback
* Split up `PartitionWitness` data
This addresses two minor inefficiencies:
- Some preprocessed forest data was being cloned during proving.
- Some of the `ForestNode` data (like node sizes) is only needed in preprocessing, not proving. It was taking up cache space during proving because it was interleaved with data that is used during proving (parents, values).
Now `Forest` contains the disjoint-set forest. `PartitionWitness` is now mainly a Vec of target values; it also holds a reference to the (preprocessed) representative map.
On my laptop, this speeds up witness generation ~12%, resulting in an overall ~0.5% speedup.
* Feedback
* No size data (#278)
* No size data
* feedback
* Some changes to generator_indices_by_watches
- Index generators by the representatives (in disjoint-set forest terminology) of their watched targets, rather than the watched targets themselves. Enqueuing generators based on their watch lists then works correctly, so we no longer need the step where we reenqueue all generators.
- In #195, it was pointed out that this slows down witness generation a bit. I moved the indexing code to preprocessing, so the prover is a bit faster (~7ms for me).
* Outdated comment
* Panic instead of infinite loop if we get stuck
* BTree
* fmt
* Refactor GMiMC code
Adds a sub-trait of `Field` called `GMiMCInterface`, which is similar to `PoseidonInterface`.
This lets us have different fields with different GMiMC constants in a type-safe way.
* Remove `Interface`
* Const generic for width
* Move some Field members to a Field64 subtrait
I.e. move anything specific to 64-bit fields.
Also, relatedly,
- Tweak a bunch of prover code to require `Field64`, since 64-bit stuff is used in a couple places, like the FRI proof-of-work
- Remove `bits()`, which was unused and assumed a 64-bit field
- Rename a couple methods to reflect that they're u64 variants
There are no functional changes.
* Field64 -> PrimeField
* Remove `exp_u32`, `kth_root_u32`
* PrimeField: PrimeField
* Move `to_canonical_biguint` as well
* Add back from_noncanonical_u128
It's just a wrapper around `Target`, which signifies that the wrapped `Target` has already been range checked. Should make it easier to audit code that expects bools.