PoseidonGate's recursive evaluations were using a lot of gates, and the MDS layer was the main culprit.
The other issue is that `constant_layer_recursive` creates a bunch of `ArithmeticGate`s with unique constants. We could either change `ArithmeticGate` to support different constants per operation, or wire in constants from `ConstantGate`, and change `ConstantGate` to support several constants per gate.
This won't really help anything near term since we're still between 2^12 and 2^13, but could have some benefits later, depending on what recursion arities and security settings we end up using.
`PoseidonMdsGate` needs `2 * D * WIDTH = 48` routed wires, and the combination of adding a gate and increasing routed wires slows down the prover a bit. So for now, I kept it at 28 wires, and the old code path is still used.
* Replace `CrandallQuarticField` with a more generic `QuarticExtension`
And likewise for `CrandallQuadraticField`.
There are a few parameters which we can't automatically derive (in const Rust), so I specified them in a `AutoExtendable` trait.
This would make it fairly easy to add extension fields for `GoldilocksField` and any future fields.
* Attempt to derive 2-adicity, see Hamish's feedback
* Simplify TWO_ADICITY based on chat with Hamish
* PR feedback
* Merge AutoExtendable into Extendable (#235)
* 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.
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).