-
Notifications
You must be signed in to change notification settings - Fork 59
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
WIP: Modularize backends #30
Conversation
The changes from the actual pallas field type to trait
These variables are I am wondering if it makes more sense to have the NAST struct to encapsulate these variables, so they can inherit the generic type from their container. |
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.
First of all this looks great, I think this is a great step towards what we want to achieve. I've left a number of comments, and I will continue to do so, but I wanted to get the big ones now rather than later. To summarize:
- can you create a separate PR that we can merge first for the refactor of the builtins?
- there's a number of changes that are unrelated to this PR, could you also move them to another PR? This would make reviewing this PR easier as I can focus on the main changes :)
- I've noted a number of places where I think things should be moved to the backend, let me know if these make sense, otherwise we can have a convo on that :o
@@ -5,7 +5,8 @@ | |||
use serde::{Deserialize, Serialize}; | |||
|
|||
/// We use the scalar field of Vesta as our circuit field. | |||
pub type Field = kimchi::mina_curves::pasta::Fp; | |||
// pub type Field = kimchi::mina_curves::pasta::Fp; | |||
pub use ark_ff::Field; |
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.
(in the final PR this should be imported in relevant file instead, but great trick to avoid too many changes now!)
|
||
impl CircuitWriter { |
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.
so, now I'm wondering if the ASM functions should be implemented directly on each specific Backend
, or each specific Backend::CompileCircuit
type. I don't think it makes sense to have a generic implementation here
|
||
use std::str::FromStr; | ||
|
||
pub fn params<F>() -> ArithmeticSpongeParams<F> |
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.
can't we just import the one from mina?
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.
This is used by the generic poseidon function, that forces this params function to have generic field.
So looks like this poseidon builtin function should be implemented for each backend, then we can just import the params from the kimchi.
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.
my question was, why not import https://github.com/o1-labs/proof-systems/blob/master/poseidon/src/pasta/fp_kimchi.rs#L9
but I guess the problem here is that this crate is not published on crates.io :D
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.
oh and yeah this should not have a generic parameter here, it should be specific for a backend that has a specific field.
pub const NUM_REGISTERS: usize = kimchi::circuits::wires::COLUMNS; | ||
|
||
#[derive(Debug, Clone, Default)] | ||
pub struct Kimchi { |
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.
perhaps we should call this backend kimchi_vesta
and KimchiVesta
respectively (as it is defined on the scalar field of Vesta)
} | ||
} | ||
|
||
fn add_constraint( |
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 would suggest keeping add_generic_gate
for now so you don't have to rename it everywhere else
/// kimchi uses a transposed witness | ||
pub fn to_kimchi_witness(&self) -> [Vec<Field>; NUM_REGISTERS] { | ||
let transposed = vec![Vec::with_capacity(self.0.len()); NUM_REGISTERS]; | ||
pub fn to_kimchi_witness(&self) -> [Vec<F>; NUM_REGISTERS] { |
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.
sounds like this should be moved to the kimchi backend module as well
pub fn to_kimchi_witness(&self) -> [Vec<F>; NUM_REGISTERS] { | ||
let transposed = (0..NUM_REGISTERS) | ||
.map(|_| Vec::with_capacity(self.0.len())) | ||
.collect::<Vec<_>>(); |
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.
why this change?
pub struct GeneratedWitness<B: Backend> { | ||
pub all_witness: Witness<B::Field>, | ||
pub full_public_inputs: Vec<B::Field>, | ||
pub public_outputs: Vec<B::Field>, |
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.
need documentation
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_witness is the entire witness vector, comprising the public input and the private input
- full_public_inputs is the public input part of the previous vector, including the public output at the end
- public_outputs is only the public output part of the previous vector
to be honest I don't remember why I returned 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.
(seems kinda inefficient)
@@ -196,12 +201,15 @@ impl CompiledCircuit { | |||
// compute each rows' vars, except for the deferred ones (public output) |
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.
so I think what comes after should be part of the backend as well, this is very specific to kimchi/plonk
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.
so perhaps the backend should have a fn generate_witness()
which we could call at this point
|
||
pub fn has_builtin_fn(name: &str) -> bool { | ||
BUILTIN_FNS_SIGS.iter().any(|(_, s)| s.name.value == name) | ||
} |
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.
can you create a PR that we could merge first that refactors the builtins? This would simplify this PR :o
// produce all TASTs and stop here | ||
produce_all_asts(&curr_dir)?; | ||
produce_all_asts::<Kimchi>(&curr_dir)?; |
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 this is the right approach, we can have another PR later to introduce different choices of backend 👍
The other PR with same purpose was merged. |
for #18