-
Notifications
You must be signed in to change notification settings - Fork 112
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
Conversation
3fb8773
to
6f6b200
Compare
fe4bfbb
to
91e856a
Compare
317305b
to
d8cca45
Compare
Starting having a look now. |
ivc/src/ivc/columns.rs
Outdated
IVCColumn::Block3PhiPowR2 => Column::Relation(4), | ||
IVCColumn::Block3PhiPowR3 => Column::Relation(5), | ||
IVCColumn::Block3ConstPhi => Column::Relation(N_BLOCKS), | ||
IVCColumn::Block3ConstR => Column::Relation(N_BLOCKS + 1), |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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...
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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...?
@@ -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>( |
There was a problem hiding this comment.
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). |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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....
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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...
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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))), |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added!
Before:
ivc_circuit
was building all /witness/ wires, but /constraints/, e.g.c_{b0,i}
, were available for every block separately. This meansc_{b0,i}
for block 0 would not work on rows of block 1.Now:
sel0 * c_{b0,i}
.Offtop:
ID
lens because I wanted to generalise circuit generator to work for two tables simultaneously. This proved to /not/ be useful. But theID
lens is useful I think so I keep it.Next step: