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

relax requirements on the size of public IO and add a note about NIFS #294

Merged
merged 2 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/nifs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ impl<E: Engine> NIFS<E> {
/// a folded Relaxed R1CS instance-witness tuple `(U, W)` of the same shape `shape`,
/// with the guarantee that the folded witness `W` satisfies the folded instance `U`
/// if and only if `W1` satisfies `U1` and `W2` satisfies `U2`.
///
/// Note that this code is tailored for use with Nova's IVC scheme, which enforces
/// certain requirements between the two instances that are folded.
/// In particular, it requires that `U1` and `U2` are such that the hash of `U1` is stored in the public IO of `U2`.
/// In this particular setting, this means that if `U2` is absorbed in the RO, it implicitly absorbs `U1` as well.
/// So the code below avoids absorbing `U1` in the RO.
pub fn prove(
ck: &CommitmentKey<E>,
ro_consts: &ROConstants<E>,
Expand Down
15 changes: 7 additions & 8 deletions src/r1cs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,14 +156,13 @@ impl<E: Engine> R1CSShape<E> {
}

// Checks regularity conditions on the R1CSShape, required in Spartan-class SNARKs
// Returns false if num_cons, num_vars, or num_io are not powers of two, or if num_io > num_vars
// Returns false if num_cons or num_vars are not powers of two, or if num_io > num_vars
#[inline]
pub(crate) fn is_regular_shape(&self) -> bool {
let cons_valid = self.num_cons.next_power_of_two() == self.num_cons;
let vars_valid = self.num_vars.next_power_of_two() == self.num_vars;
let io_valid = self.num_io.next_power_of_two() == self.num_io;
let io_lt_vars = self.num_io < self.num_vars;
cons_valid && vars_valid && io_valid && io_lt_vars
cons_valid && vars_valid && io_lt_vars
}

pub fn multiply_vec(
Expand Down Expand Up @@ -302,17 +301,17 @@ impl<E: Engine> R1CSShape<E> {
Ok((T, comm_T))
}

/// Pads the `R1CSShape` so that the number of variables is a power of two
/// Pads the `R1CSShape` so that the shape passes `is_regular_shape`
/// Renumbers variables to accommodate padded variables
pub fn pad(&self) -> Self {
// equalize the number of variables and constraints
let m = max(self.num_vars, self.num_cons).next_power_of_two();

// check if the provided R1CSShape is already as required
if self.num_vars == m && self.num_cons == m {
if self.is_regular_shape() {
return self.clone();
}

// equalize the number of variables, constraints, and public IO
let m = max(max(self.num_vars, self.num_cons), self.num_io).next_power_of_two();

// check if the number of variables are as expected, then
// we simply set the number of constraints to the next power of two
if self.num_vars == m {
Expand Down
Loading