-
Notifications
You must be signed in to change notification settings - Fork 118
[kimchi][doc] update readme example with circuit-construction API #555
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
Changes from all commits
acec78f
6e092df
03ab234
31e1b8f
a0c945e
a653e30
4dd34ca
f3b93ee
1090390
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,54 +11,104 @@ You can read more about this project on the [Kimchi book](https://o1-labs.github | |
|
||
## Example | ||
|
||
We assume that you already have: | ||
|
||
* `gates`: a circuit, which can be expressed as a vector of [CircuitGate](https://o1-labs.github.io/proof-systems/rustdoc/kimchi/circuits/gate/struct.CircuitGate.html) | ||
* a way to produce a `witness`, which can be expressed as a `[Vec<F>; COLUMNS]` (for `F` some field of your chosing) | ||
* `public_size`: the size of the public input | ||
|
||
Then, you can create an URS for your circuit in the following way: | ||
|
||
```rust,ignore | ||
use kimchi::{circuits::constraints, verifier::verify}; | ||
use mina_curves::pasta::{fp::Fp, vesta::{Affine, VestaParameters}, pallas::Affine as Other}; | ||
use oracle::{ | ||
constants::PlonkSpongeConstantsKimchi, | ||
sponge::{DefaultFqSponge, DefaultFrSponge}, | ||
The following is an example to demonstrate a full cycle workflow using circuit-construction: | ||
|
||
1. Specify a circuit | ||
2. Create SRS | ||
3. Generate prover index | ||
4. Generate a proof | ||
5. Verify the proof | ||
|
||
```rust | ||
use std::sync::Arc; | ||
use ark_ff::{FftField, PrimeField}; | ||
use ark_poly::{EvaluationDomain, Radix2EvaluationDomain}; | ||
use circuit_construction::{ | ||
*, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should avoid importing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here is an attempt to use a prologue. It does simplify the import a lot, just use one line. But I am not sure if there are any potential issues when it comes to practice :D |
||
oracle::{ | ||
constants::*, | ||
poseidon::{Sponge}, | ||
sponge::{DefaultFqSponge, DefaultFrSponge}, | ||
}, | ||
kimchi::verifier::verify, | ||
commitment_dlog::{commitment::CommitmentCurve, srs::SRS}, | ||
groupmap::GroupMap, | ||
mina_curves::pasta::{ | ||
fp::Fp, | ||
vesta::{Affine, VestaParameters}, | ||
} | ||
}; | ||
use commitment_dlog::commitment::{b_poly_coefficients, ceil_log2, CommitmentCurve}; | ||
|
||
type SpongeParams = PlonkSpongeConstantsKimchi; | ||
type BaseSponge = DefaultFqSponge<VestaParameters, SpongeParams>; | ||
type ScalarSponge = DefaultFrSponge<Fp, SpongeParams>; | ||
|
||
// compile the circuit | ||
let fp_sponge_params = oracle::pasta::fp_kimchi::params(); | ||
let cs = ConstraintSystem::<Fp>::create(gates, vec![], fp_sponge_params, public_size).unwrap(); | ||
|
||
// create an URS | ||
let mut urs = SRS::<Affine>::create(cs.domain.d1.size as usize); | ||
srs.add_lagrange_basis(cs.domain.d1); | ||
|
||
// obtain a prover index | ||
let prover_index = { | ||
let fq_sponge_params = oracle::pasta::fq_kimchi::params(); | ||
let (endo_q, _endo_r) = endos::<Other>(); | ||
Index::<Affine>::create(cs, fq_sponge_params, endo_q, srs) | ||
type SpongeQ = DefaultFqSponge<VestaParameters, PlonkSpongeConstantsKimchi>; | ||
type SpongeR = DefaultFrSponge<Fp, PlonkSpongeConstantsKimchi>; | ||
|
||
// a callback function to specify constraint gates for a circuit | ||
pub fn circuit< | ||
F: PrimeField + FftField, | ||
Sys: Cs<F>, | ||
>( | ||
witness: Option<F>, | ||
sys: &mut Sys, | ||
public_input: Vec<Var<F>>, | ||
) { | ||
// add a constant gate | ||
let three = sys.constant(3u32.into()); | ||
// read the first public input | ||
let first_public_input = public_input[0]; | ||
// create a free variable to hold a witness value | ||
let witness = sys.var(|| witness.unwrap()); | ||
|
||
// create a free variable to hold a calculation result | ||
let result = sys.var(|| { | ||
first_public_input.val() + witness.val() | ||
}); | ||
|
||
// add a gate to assert the calculation equals to a constant constraint | ||
sys.assert_eq(result, three); | ||
} | ||
|
||
// create SRS | ||
let srs = { | ||
let mut srs = SRS::<Affine>::create(1 << 3); // 2^3 = 8 | ||
srs.add_lagrange_basis(Radix2EvaluationDomain::new(srs.g.len()).unwrap()); | ||
Arc::new(srs) | ||
katat marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}; | ||
|
||
// obtain a verifier index | ||
let verifier_index = prover_index.verifier_index(); | ||
|
||
// create a proof | ||
let public_inputs = vec![1i32.into()]; | ||
let group_map = <Affine as CommitmentCurve>::Map::setup(); | ||
let proof = ProverProof::create::<BaseSponge, ScalarSponge>( | ||
&group_map, witness, &prover_index); | ||
|
||
// verify a proof | ||
verify::<Affine, BaseSponge, ScalarSponge>(&group_map, verifier_index, proof).unwrap(); | ||
// generate circuit and index | ||
let prover_index = generate_prover_index::<FpInner, _>( | ||
srs, | ||
&fp_constants(), | ||
&oracle::pasta::fq_kimchi::params(), | ||
// to determine how many placeholders to generate for public inputs | ||
public_inputs.len(), | ||
// use the circuit callback to generate gate constraints | ||
// with placeholders for the witness and public inputs | ||
|sys, p| circuit::<_, _>(None, sys, p), | ||
); | ||
katat marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// create witness | ||
let witness = 2i32; | ||
|
||
// generate proof | ||
let proof = prove::<Affine, _, SpongeQ, SpongeR>( | ||
&prover_index, | ||
&group_map, | ||
None, | ||
public_inputs, | ||
// use the same circuit callbacb | ||
// but with values for witness and public inputs | ||
|sys, p| circuit::<Fp, _>(Some(witness.into()), sys, p), | ||
); | ||
|
||
// verify proof | ||
let verifier_index = prover_index.verifier_index(); | ||
verify::<_, SpongeQ, SpongeR>(&group_map, &verifier_index, &proof).unwrap(); | ||
``` | ||
|
||
For the other examples, please refer to the [tests](./circuit-construction/tests/). | ||
|
||
Note that kimchi is specifically designed for use in a recursion proof system, like [pickles](https://medium.com/minaprotocol/meet-pickles-snark-enabling-smart-contract-on-coda-protocol-7ede3b54c250), but can also be used a stand alone for normal proofs. | ||
|
||
## Organization | ||
|
@@ -71,6 +121,7 @@ The project is organized in the following way: | |
* [groupmap/](https://github.com/o1-labs/proof-systems/tree/master/groupmap). Used to convert elliptic curve elements to field elements. | ||
* [hasher/](https://github.com/o1-labs/proof-systems/tree/master/hasher). Interfaces for mina hashing. | ||
* [kimchi/](https://github.com/o1-labs/proof-systems/tree/master/kimchi). Our proof system. | ||
* [circuit-construction/](https://github.com/o1-labs/proof-systems/tree/master/circuit-construction). Circuit writer. | ||
* [ocaml/](https://github.com/o1-labs/proof-systems/tree/master/ocaml). Ocaml bindings generator tool. | ||
* [oracle/](https://github.com/o1-labs/proof-systems/tree/master/oracle). Implementation of the poseidon hash function. | ||
* [poly-commitment/](https://github.com/o1-labs/proof-systems/tree/master/poly-commitment). Polynomial commitment code. | ||
|
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 guess the description above the example could be updated
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.
Updated to outline the workflow and try to explain the code with a bit more comments. Please have a check.
Note I still use the name
circuit-construction
and the namekimchi
still remains. I guess they can remain until a new name forcircuit-construction
is determined.