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

IVC: Add selector columns #2233

Merged
merged 9 commits into from
May 28, 2024
Merged

Conversation

volhovm
Copy link
Member

@volhovm volhovm commented May 16, 2024

Before: ivc_circuit was building all /witness/ wires, but /constraints/, e.g. c_{b0,i}, were available for every block separately. This means c_{b0,i} for block 0 would not work on rows of block 1.

Now:

  • There are selectors for each block.
  • Every constraint is now working for the /whole circuit/, since it's now multiplied by selector: sel0 * c_{b0,i}.
  • Completeness test is added with lookups disabled.

Offtop:

  • I added the ID lens because I wanted to generalise circuit generator to work for two tables simultaneously. This proved to /not/ be useful. But the ID lens is useful I think so I keep it.

Next step:

@volhovm volhovm marked this pull request as draft May 16, 2024 16:26
@volhovm volhovm force-pushed the volhovm/2231-ivc-selector-columns branch from 3fb8773 to 6f6b200 Compare May 17, 2024 13:49
@volhovm volhovm marked this pull request as ready for review May 17, 2024 13:49
@volhovm volhovm force-pushed the volhovm/2231-ivc-selector-columns branch 3 times, most recently from fe4bfbb to 91e856a Compare May 17, 2024 16:52
@volhovm volhovm requested review from dannywillems, querolita and fabrizio-m and removed request for querolita May 18, 2024 09:54
@volhovm volhovm force-pushed the volhovm/2231-ivc-selector-columns branch 2 times, most recently from 317305b to d8cca45 Compare May 20, 2024 13:39
@dannywillems
Copy link
Member

Starting having a look now.

ivc/src/ivc/columns.rs Show resolved Hide resolved
ivc/src/ivc/columns.rs Show resolved Hide resolved
ivc/src/ivc/columns.rs Outdated Show resolved Hide resolved
IVCColumn::Block3PhiPowR2 => Column::Relation(4),
IVCColumn::Block3PhiPowR3 => Column::Relation(5),
IVCColumn::Block3ConstPhi => Column::Relation(N_BLOCKS),
IVCColumn::Block3ConstR => Column::Relation(N_BLOCKS + 1),
Copy link
Member

Choose a reason for hiding this comment

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

To me it looks like IVCColumn::Block1Input(i) and IVCColumn::Block3ConstR could collide for example when i=1, no?

Copy link
Member

@dannywillems dannywillems May 28, 2024

Choose a reason for hiding this comment

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

It makes sense to collide. It is like selectors q_l, q_r, q_m in vanilla plonk. The columns are shared.

Copy link
Member

Choose a reason for hiding this comment

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

I am not sure I understand why you want redundant definitions of the same column. Like, it is not as if you could access multiple rows for each constraint no? Like, at most the current row and the next, but not 4 rows ahead...

Copy link
Member

Choose a reason for hiding this comment

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

I don't understand. We can talk about it in a call, easier.

Copy link
Member Author

Choose a reason for hiding this comment

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

All the blocks share most columns. The whole point of the column indexer is to semantically separate which columns have which meaning. The opposite approach would be to just use integers for column indexing, which is inconvenient and has zero type-safety. Maybe I don't understand what you mean...?

ivc/src/ivc/interpreter.rs Outdated Show resolved Hide resolved
ivc/src/ivc/interpreter.rs Outdated Show resolved Hide resolved
ivc/src/ivc/interpreter.rs Outdated Show resolved Hide resolved
ivc/src/ivc/interpreter.rs Show resolved Hide resolved
msm/src/circuit_design/capabilities.rs Outdated Show resolved Hide resolved
msm/src/circuit_design/composition.rs Show resolved Hide resolved
@@ -913,15 +920,101 @@ where
{
}

/// Builds selectors for the IVC circuit.
pub fn build_selectors<F, const N_COL_TOTAL: usize, const N_CHALS: usize>(
Copy link
Member

@dannywillems dannywillems May 28, 2024

Choose a reason for hiding this comment

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

@@ -212,6 +218,9 @@ pub type IVCPoseidonColumn = PoseidonColumn<IVC_POSEIDON_STATE_SIZE, IVC_POSEIDO
// TODO: Can we pass just one coordinate and sign (x, sign) instead of (x,y) for hashing?
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum IVCColumn {
/// Selector for blocks. Inner usize is ∈ [0,#blocks).
Copy link
Member

Choose a reason for hiding this comment

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

I cannot find the up-to-date description of each different block. Is it the ones at the top of file?
My question is related to the function build_selectors, to verify the selectors are populated according to the spec.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, the general description of each block is in the top of columns.rs. I don't know how to create const usize definitions for block sizes, because they depend on N_COL_TOTAL and N_CHALS and generic consts in rust are not supported....

Copy link
Member Author

Choose a reason for hiding this comment

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

I fixed this by adding block_height function... but I see it's merged? heh

F: PrimeField,
Env: ColAccessCap<F, IVCColumn>,
{
for i in 0..N_BLOCKS {
Copy link
Member

@dannywillems dannywillems May 28, 2024

Choose a reason for hiding this comment

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

If selectors are public values, i.e. part of the setup, I think we do not need to add constraints. Constraints are only required for variables the prover performs computations with.

Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe, but I'm not entirely convinced -- it seems to me that when we're folding the circuit we'll have to constrain these values. For just regular proofs -- yes, it makes sense. I suggest we keep it just in case (it's cheap), and can remove it later. I added a comment above this function. OK with you?

Copy link
Member

Choose a reason for hiding this comment

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

Ok to merge like this, but not needed. I would merge the PR, and we can move from there.

type Variable: Clone
+ std::ops::Add<Self::Variable, Output = Self::Variable>
+ std::ops::Sub<Self::Variable, Output = Self::Variable>
+ std::ops::Mul<Self::Variable, Output = Self::Variable>
+ std::ops::Neg<Output = Self::Variable>
+ From<u64>
+ std::fmt::Debug;
+ std::fmt::Debug
+ 'static;
Copy link
Member

@dannywillems dannywillems May 28, 2024

Choose a reason for hiding this comment

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

🤔 not sure I like this, but let's see. What will have 'static lifetime?
A value with 'static lifetime will be embedded in the read-only data segment of the binary. Wondering what will be embedded in this segment for all programs...

Copy link
Member

Choose a reason for hiding this comment

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

I think it will be a reference to the function.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm also not 100% sure, but this type-level 'static is different from a variable static. The type-level static just means the datatype does not embed non-static references. We can change in the future if necessary, I couldn't find another way :(

@@ -352,6 +362,15 @@ impl<
witness.cols[N_REL + N_DSEL + i] = self.fixed_selectors[i].clone();
Copy link
Member

Choose a reason for hiding this comment

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

Maybe it is modified later in https://github.com/o1-labs/proof-systems/pull/2249/files, but we should be sure that set_fixed_selectors has been called before.

Copy link
Member Author

Choose a reason for hiding this comment

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

Agreed. I want to rework the design later on to remove set_fixed_selectors altogether and take selectors from some trait for the column.

Copy link
Member

Choose a reason for hiding this comment

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

Opened #2255

let domain_size: usize = domain.d1.size as usize;

// Boxing to avoid stack overflow
let mut witness: Box<Witness<N_COL, Vec<F>>> = Box::new(Witness {
cols: Box::new(std::array::from_fn(|_| Vec::with_capacity(domain_size))),
Copy link
Member

@dannywillems dannywillems May 28, 2024

Choose a reason for hiding this comment

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

Nit: I would always add an assertion at the end of the function, checking that the size of the vector is exactly domain_size. with_capacity does not enforce that.

Copy link
Member Author

Choose a reason for hiding this comment

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

Added!

@dannywillems dannywillems merged commit fef00e3 into master May 28, 2024
6 checks passed
@dannywillems dannywillems deleted the volhovm/2231-ivc-selector-columns branch May 28, 2024 13: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.

3 participants