Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CycleFold #273

Merged
merged 77 commits into from
Mar 22, 2024
Merged

CycleFold #273

merged 77 commits into from
Mar 22, 2024

Conversation

mpenciak
Copy link
Contributor

@mpenciak mpenciak commented Jan 19, 2024

This PR is a WIP for CycleFolding with Nova IVC.

TODO:

huitseeker added a commit to huitseeker/arecibo that referenced this pull request Jan 22, 2024
…ims (Arecibo backport) (argumentcomputer#273)

* `snark.rs`: factor out batch evaluation Sumcheck (argumentcomputer#106)

* Factor batch eval

* Comments

* refactor: Remove nedless pass-by-value instances, turn on clippy (argumentcomputer#122)

* refactor: Remove nedless pass-by-value instances, turn on the corresponding clippy lint

- Updated function parameters in `ppsnark.rs` and `snark.rs` from `Vec<G::Scalar>` to `&[G::Scalar]` (introduced in argumentcomputer#106),
- Modified the `prove` function in `ppsnark.rs` to also convert `T_row`, `W_row`, `T_col`, and `W_col` from `Vec` to slices (`&[G::Scalar]`).
- Enhanced the `xclippy` alias in `.cargo/config` by adding `-Wclippy::checked_conversions`, `-Wclippy::needless_pass_by_value`, and `-Wclippy::unnecessary_mut_passed` and reorganizing its elements.

* `PolyEval{Instance, Witness}::pad`
Accept `Vec` rather that `&[T]` to avoid copies

Co-authored-by: Francois Garillot <[email protected]>

---------

Co-authored-by: Adrian Hamelink <[email protected]>

---------

Co-authored-by: Adrian Hamelink <[email protected]>
Co-authored-by: Adrian Hamelink <[email protected]>
src/cyclefold/circuit.rs Outdated Show resolved Hide resolved
src/cyclefold/circuit.rs Outdated Show resolved Hide resolved
src/cyclefold/circuit.rs Outdated Show resolved Hide resolved
src/cyclefold/gadgets.rs Outdated Show resolved Hide resolved
src/cyclefold/gadgets.rs Outdated Show resolved Hide resolved
src/cyclefold/gadgets.rs Outdated Show resolved Hide resolved
src/cyclefold/gadgets.rs Outdated Show resolved Hide resolved
src/cyclefold/gadgets.rs Outdated Show resolved Hide resolved
src/cyclefold/gadgets.rs Outdated Show resolved Hide resolved
@huitseeker huitseeker force-pushed the cyclefold_new branch 4 times, most recently from 3e61d81 to 2c02ddb Compare February 11, 2024 22:06
Copy link
Contributor

@adr1anh adr1anh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First batch of comments

src/cyclefold/circuit.rs Outdated Show resolved Hide resolved
src/cyclefold/circuit.rs Outdated Show resolved Hide resolved
src/cyclefold/gadgets.rs Outdated Show resolved Hide resolved
src/cyclefold/gadgets.rs Show resolved Hide resolved
src/cyclefold/gadgets.rs Outdated Show resolved Hide resolved
use ff::Field;

#[derive(Clone)]
pub struct AllocatedPoint<E>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should avoid the is_infinity bit here. In order to properly constrain it, we need to evaluate the curve equation non-natively which will be very expensive. Instead, (and if the properties of the curve allow), we could define (0,0) as the identity and let the CycleFold circuit check that this holds.

src/gadgets/nonnative/bignat.rs Outdated Show resolved Hide resolved
src/cyclefold/nova_circuit.rs Outdated Show resolved Hide resolved
src/cyclefold/circuit.rs Show resolved Hide resolved
@mpenciak mpenciak force-pushed the cyclefold_new branch 2 times, most recently from e36efdb to b050e3f Compare February 14, 2024 18:57
src/cyclefold/circuit.rs Outdated Show resolved Hide resolved
src/cyclefold/gadgets.rs Show resolved Hide resolved
src/cyclefold/circuit.rs Show resolved Hide resolved
src/cyclefold/circuit.rs Outdated Show resolved Hide resolved
src/cyclefold/gadgets.rs Show resolved Hide resolved
src/cyclefold/gadgets.rs Outdated Show resolved Hide resolved
src/cyclefold/circuit.rs Outdated Show resolved Hide resolved
src/cyclefold/circuit.rs Outdated Show resolved Hide resolved
src/cyclefold/circuit.rs Outdated Show resolved Hide resolved
src/cyclefold/gadgets.rs Show resolved Hide resolved
@mpenciak mpenciak force-pushed the cyclefold_new branch 2 times, most recently from 836aedd to 696cf65 Compare March 3, 2024 22:56
@wyattbenno777
Copy link
Contributor

What would you say the best test against this would be for Nova vs ParaNova?

test_ivc_nontrivial_with vs test_trivial_cyclefold_prove_verify_with?

@mpenciak
Copy link
Contributor Author

mpenciak commented Mar 6, 2024

What would you say the best test against this would be for Nova vs ParaNova?

test_ivc_nontrivial_with vs test_trivial_cyclefold_prove_verify_with?

I would say those two tests are the most comparable.

But a word of warning: The current folding circuit is not in its final state. I'm nearing the end of a re-work for the way the public IO for the CycleFold circuit is dealt with. Right now the primary folding circuit has ~80k constraints, which is largely coming from the fact that the CycleFold IO has arity 16 (5 per commitment + 1 scalar). This will make the CycleFold circuit moderately larger (up to ~2k constraints), but significantly reduce the size of the folding circuit (numbers TBD soon).

Hopefully in the next day or so these updates will be pushed and there can be a more fair comparison.

@mpenciak mpenciak changed the title [WIP] CycleFold CycleFold Mar 7, 2024
@mpenciak mpenciak marked this pull request as ready for review March 7, 2024 21:59
@mpenciak
Copy link
Contributor Author

mpenciak commented Mar 8, 2024

What would you say the best test against this would be for Nova vs ParaNova?

test_ivc_nontrivial_with vs test_trivial_cyclefold_prove_verify_with?

Just a quick update: I just finished the IO refactor, so the comparison should be more fair now.

src/gadgets/nonnative/util.rs Outdated Show resolved Hide resolved
src/gadgets/r1cs.rs Outdated Show resolved Hide resolved
src/nifs.rs Outdated Show resolved Hide resolved
src/circuit.rs Outdated Show resolved Hide resolved
src/supernova/circuit.rs Outdated Show resolved Hide resolved
Comment on lines +130 to +139
pub fn apply_fold<CS>(
&self,
mut cs: CS,
params: &AllocatedNum<E::Base>,
ro_consts: ROConstantsCircuit<E>,
limb_width: usize,
n_limbs: usize,
) -> Result<AllocatedRelaxedR1CSInstance<E, NIO_CYCLE_FOLD>, SynthesisError>
where
CS: ConstraintSystem<E::Base>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This really looks like crate::gadgets::r1cs::fold_with_r1cs with a different RO setup.
It would be good to refactor the common part in an auxiliary function and call it from both places.

impl<E: Engine> CycleFoldNIFS<E> {
/// Folds an R1CS instance/witness pair (U2, W2) into a relaxed R1CS instance/witness (U1, W1)
/// returning the new folded accumulator and a commitment to the cross-term.
pub fn prove(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. This really looks, like crate::nifs::NIFS::prove with a different RO setup and internal fold function. Would it be possible to have a trait implemented differently for NIFS / CycleFoldNIFS for the RO setup & fold, and then have prove defined in a general way as an extension method which code should be shared between the two instances of the trait?
  2. We don't have an instance of prove_mut here, which is key to performance (see Acceleration of SpMVM in folding #75). It would be good to implement it, and solving (1.) above would be key to doing this without too much extra work.

Ok((U_c, U_p, checks_pass))
}

pub fn synthesize<CS: ConstraintSystem<<E1 as Engine>::Base>>(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This really looks like crate::circuit::NovaAugmentedCircuit::synthesize, perhaps unsurprisingly because most of the differences are in some setup functions, as well as in the auxiliary functions (alloc_witnesses, synthesize_base_case, synthesize_non_base_case).

Here the reason you're duplicating most of the synthesize code is because in one case you want to route to the CycleFold methods, and in the other you want to route to the Nova methods.

You could instead put those three method signatures in a trait, have them implemented in different ways in each of the Nova/CycleFold circuit, and then have the top-level synthesize defined generically for all implementers of the trait?

@huitseeker huitseeker mentioned this pull request Mar 22, 2024
3 tasks
Copy link
Member

@huitseeker huitseeker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've created #375 for the code duplication. THis looks great, thank you so much!

@mpenciak
Copy link
Contributor Author

I've created #375 for the code duplication. THis looks great, thank you so much!

Thanks!

@mpenciak mpenciak added this pull request to the merge queue Mar 22, 2024
Merged via the queue into argumentcomputer:dev with commit 5268c20 Mar 22, 2024
10 checks passed
@mpenciak mpenciak deleted the cyclefold_new branch March 22, 2024 19:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants