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

WIP: Modularize backends #30

Closed
wants to merge 2 commits into from
Closed

Conversation

katat
Copy link
Collaborator

@katat katat commented Mar 28, 2024

for #18

  • Refactor with ark_ff::Field
  • Modularize backends
  • Existing tests passed
  • Add R1CS backend

@katat katat changed the title WIP: refactor using ark_ff::Field WIP: Modularize backends Mar 28, 2024
@katat
Copy link
Collaborator Author

katat commented Mar 28, 2024

The changes from the actual pallas field type to trait ark_ff::Field propagate to the variables such as:

These variables are const or static, so they won't be able to support using generic type without make some complex tricks using keywords such as Box or dyn.

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.

Copy link
Contributor

@mimoo mimoo left a 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:

  1. can you create a separate PR that we can merge first for the refactor of the builtins?
  2. 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 :)
  3. 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;
Copy link
Contributor

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 {
Copy link
Contributor

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>
Copy link
Contributor

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?

Copy link
Collaborator Author

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.

Copy link
Contributor

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

Copy link
Contributor

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 {
Copy link
Contributor

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(
Copy link
Contributor

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] {
Copy link
Contributor

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<_>>();
Copy link
Contributor

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>,
Copy link
Contributor

Choose a reason for hiding this comment

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

need documentation

Copy link
Contributor

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 :)

Copy link
Contributor

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)
Copy link
Contributor

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

Copy link
Contributor

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)
}
Copy link
Contributor

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)?;
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 this is the right approach, we can have another PR later to introduce different choices of backend 👍

@katat
Copy link
Collaborator Author

katat commented Apr 17, 2024

The other PR with same purpose was merged.

@katat katat closed this Apr 17, 2024
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.

2 participants