* 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
* Simplify and refactor GMiMC benchmark.
* Refactor/combine GMiMC and Rescue hash benchmarks.
* Remove old Rescue bench; rename GMiMC bench.
* Add from_canonical_u128 for fields.
* Initial version of Poseidon.
* Partial implementation of fast Poseidon.
* Complete (but broken) implementation of fast partial rounds.
* Fix index calculation.
* Add basic tests.
* Fix constants; fix bugs in fast partial round calculation.
* Rename main functions.
* Add test vectors.
* Use x^7 for s-box monomial.
* Fix s-box application in fast version.
* Make WIDTH a parameter.
* Working version with both widths.
* Updated the constants so they use x^3; added test vectors.
* Expand bench_hash to cover both widths and report relative slowdown.
* Remove references to MaybeUninit.
* First draft of refactoring the two Poseidon widths.
* Tidy up use of conversion to/from raw data.
* Add some comments.
* Refactor tests.
* Apply cargo fmt changes.
* Have `Field`s implement `PoseidonInterface` (#209)
* Have `Field`s implement `PoseidonInterface`
Rather than having a sort of "dummy struct" implement `PoseidonInterface` with the field as a generic param. I think this seems more natural and type-safe.
The type safety does come at a price -- it would be harder to do dynamic things such as taking `WIDTH` as a command line option -- but I think that's alright.
* Fix missed conflicts.
* cargo fmt fixes.
* Fix to accommodate changes in latest nightly.
Co-authored-by: Hamish Ivey-Law <426294+unzvfu@users.noreply.github.com>
Co-authored-by: Hamish Ivey-Law <hamish@ivey-law.name>
* Sanity check number of rounds.
Co-authored-by: Daniel Lubarov <daniel@lubarov.com>
* Disable ZK in large_config
Speeds up the tests from ~6m to ~1m (debug mode). `large_config` is crate-private so I don't think we need to worry about real users forgetting ZK, and I don't think ZK seems important in these tests, though we should probably have ZK enabled for a couple tests.
A couple tests need ZK or they fail; I added a TODO to look later.
This led to a few other changes:
- Fixed a bug where `trim` could truncate the final poly to a non-power-of-two length. This was improbable when ZK is on due to randomization.
- Gave a few methods access to the whole `CircuitConfig` vs `FriConfig` -- sort of necessary for the above fix, and I don't think there's much downside.
- Remove `cap_height` from `FriConfig` -- didn't really need it any more after giving more methods access to `CircuitConfig`, and having a single copy of the param feels cleaner/safer to me.
* 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).
With this approach, we don't need `Target::PublicInput`; any routable `Target` can be marked as a public input via `register_public_input`. The circuit itself hashes these targets, and routes the hash output to the first four wires of a `PublicInputGate`, which is placed at an arbitrary location in the circuit.
All gates have direct access to the purported hash of public inputs. We could think of them as accessing `PI_hash_i(x)` (as in Plonk), but these are now (four) constant functions, so they effectively have direct access to the hash itself.
`PublicInputGate` checks that its first four wires match this purported public input hash. The other gates ignore the hash.
Resolves#64.
* More routed wires for recursion
For the insertion gate, which (with a FRI arity of 4) uses 1 wire for the insertion index, D for the elemnet to insert, 3D for the original list, and 4D for the output list.
* import
* 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
Using `serde_cbor` for now. It's probably far from optimal, as we have many `Vec`s which I assume it will prefix with their lengths, but it's a nice and easy method for now.
- Configure FRI with a list of arities that's more appropriate for a 2^14 instance. The previous config resulted in a huge final polynomial.
- Log the blinding factors, and other logging tweaks.
- `self.gates` -> `self.gate_instances`
- Some tests were using a single binary FRI reduction, which doesn't provide enough succinctness for our blinding scheme to work. This caused `blinding_counts` to continue until it overflowed.
* Draw challenge points from the extension field
* Now building
* Misc
* Default eval_unfiltered_base
* fmt
* A few field settings
* Add to Sage
* Display tweak
* eval_filtered_base
* Quartic in bench
* Missing methods
* Fix tests
* PR feedback
... by switching to Rescue Prime (which has a smaller security margin), and precomputing an addition chain for the exponent used in the cubic root calculation. Also adds a benchmark.