Skip to content

Commit

Permalink
Write serialization regression tests for poly-commitment and parts of…
Browse files Browse the repository at this point in the history
… kimchi
  • Loading branch information
volhovm committed Sep 24, 2024
1 parent 4b11acf commit d48799c
Show file tree
Hide file tree
Showing 14 changed files with 769 additions and 74 deletions.
25 changes: 12 additions & 13 deletions book/src/specs/kimchi.md
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ Similarly to the generic gate, each values taking part in a lookup can be scaled
The lookup functionality is an opt-in feature of kimchi that can be used by custom gates.
From the user's perspective, not using any gates that make use of lookups means that the feature will be disabled and there will be no overhead to the protocol.

Refer to the [lookup RFC](../kimchi/lookup.md) for an overview of the lookup feature.
Refer to the [lookup RFC](../rfcs/3-lookup.md) for an overview of the lookup feature.

In this section, we describe the tables kimchi supports, as well as the different lookup selectors (and their associated queries)

Expand Down Expand Up @@ -908,10 +908,10 @@ v_1$ and $v_2$) of up to 88 bits each.

Values can be copied as inputs to the multi range check gadget in two ways:

* (Standard mode) With 3 copies, by copying $v_0, v_1$ and $v_2$ to the first
* [Standard mode] With 3 copies, by copying $v_0, v_1$ and $v_2$ to the first
cells of the first 3 rows of the gadget. In this mode the first gate
coefficient is set to `0`.
* (Compact mode) With 2 copies, by copying $v_2$ to the first cell of the first
* [Compact mode] With 2 copies, by copying $v_2$ to the first cell of the first
row and copying $v_{10} = v_0 + 2^{\ell} \cdot v_1$ to the 2nd cell of row 2.
In this mode the first gate coefficient is set to `1`.

Expand Down Expand Up @@ -1097,7 +1097,7 @@ left_input +/- right_input = field_overflow * foreign_modulus + result

##### Documentation

For more details please see the [Foreign Field Addition](../kimchi/foreign_field_add.md) chapter.
For more details please see the [Foreign Field Addition RFC](../rfcs/foreign_field_add.md)

##### Mapping

Expand Down Expand Up @@ -1218,8 +1218,7 @@ left_input * right_input = quotient * foreign_field_modulus + remainder

##### Documentation

For more details please see the [Foreign Field Multiplication](../kimchi/foreign_field_add.md)
chapter or the original [Foreign Field Multiplication RFC](https://github.com/o1-labs/rfcs/blob/main/0006-ffmul-revised.md).
For more details please see the [Foreign Field Multiplication RFC](../rfcs/foreign_field_mul.md)

##### Notations

Expand Down Expand Up @@ -1940,7 +1939,7 @@ A proof consists of the following data structures:
```rs
/// Evaluations of a polynomial at 2 points
#[serde_as]
#[derive(Copy, Clone, Serialize, Deserialize, Default, Debug)]
#[derive(Copy, Clone, Serialize, Deserialize, Default, Debug, PartialEq)]
#[cfg_attr(
feature = "ocaml_types",
derive(ocaml::IntoValue, ocaml::FromValue, ocaml_gen::Struct)
Expand All @@ -1963,7 +1962,7 @@ pub struct PointEvaluations<Evals> {
/// - **Chunked evaluations** `Field` is instantiated with vectors with a length that equals the length of the chunk
/// - **Non chunked evaluations** `Field` is instantiated with a field, so they are single-sized#[serde_as]
#[serde_as]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ProofEvaluations<Evals> {
/// public input polynomials
pub public: Option<Evals>,
Expand Down Expand Up @@ -2028,7 +2027,7 @@ pub struct ProofEvaluations<Evals> {

/// Commitments linked to the lookup feature
#[serde_as]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(bound = "G: ark_serialize::CanonicalDeserialize + ark_serialize::CanonicalSerialize")]
pub struct LookupCommitments<G: AffineRepr> {
/// Commitments to the sorted lookup table polynomial (may have chunks)
Expand All @@ -2041,7 +2040,7 @@ pub struct LookupCommitments<G: AffineRepr> {

/// All the commitments that the prover creates as part of the proof.
#[serde_as]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(bound = "G: ark_serialize::CanonicalDeserialize + ark_serialize::CanonicalSerialize")]
pub struct ProverCommitments<G: AffineRepr> {
/// The commitments to the witness (execution trace)
Expand All @@ -2056,7 +2055,7 @@ pub struct ProverCommitments<G: AffineRepr> {

/// The proof that the prover creates from a [ProverIndex](super::prover_index::ProverIndex) and a `witness`.
#[serde_as]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(bound = "G: ark_serialize::CanonicalDeserialize + ark_serialize::CanonicalSerialize")]
pub struct ProverProof<G: AffineRepr, OpeningProof> {
/// All the polynomial commitments required in the proof
Expand All @@ -2082,7 +2081,7 @@ pub struct ProverProof<G: AffineRepr, OpeningProof> {

/// A struct to store the challenges inside a `ProverProof`
#[serde_as]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
#[serde(bound = "G: ark_serialize::CanonicalDeserialize + ark_serialize::CanonicalSerialize")]
pub struct RecursionChallenge<G>
where
Expand Down Expand Up @@ -2338,7 +2337,7 @@ Essentially, this steps verifies that $f(\zeta) = t(\zeta) * Z_H(\zeta)$.
unless a polynomial has its evaluation provided by the proof
in which case the evaluation should be used in place of the commitment.
1. Compute the (chuncked) commitment of $ft$
(see [Maller's optimization](../kimchi/maller_15.md)).
(see [Maller's optimization](../crypto/plonk/maller_15.html)).
1. List the polynomial commitments, and their associated evaluations,
that are associated to the aggregated evaluation proof in the proof:
* recursion
Expand Down
3 changes: 2 additions & 1 deletion kimchi/src/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,12 @@ impl BenchmarkCtx {

// add the proof to the batch
(
ProverProof::create::<BaseSponge, ScalarSponge>(
ProverProof::create::<BaseSponge, ScalarSponge, _>(
&self.group_map,
witness,
&[],
&self.index,
&mut rand::rngs::OsRng,
)
.unwrap(),
public_input,
Expand Down
12 changes: 6 additions & 6 deletions kimchi/src/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use std::array;
//~ spec:startcode
/// Evaluations of a polynomial at 2 points
#[serde_as]
#[derive(Copy, Clone, Serialize, Deserialize, Default, Debug)]
#[derive(Copy, Clone, Serialize, Deserialize, Default, Debug, PartialEq)]
#[cfg_attr(
feature = "ocaml_types",
derive(ocaml::IntoValue, ocaml::FromValue, ocaml_gen::Struct)
Expand All @@ -41,7 +41,7 @@ pub struct PointEvaluations<Evals> {
/// - **Chunked evaluations** `Field` is instantiated with vectors with a length that equals the length of the chunk
/// - **Non chunked evaluations** `Field` is instantiated with a field, so they are single-sized#[serde_as]
#[serde_as]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ProofEvaluations<Evals> {
/// public input polynomials
pub public: Option<Evals>,
Expand Down Expand Up @@ -106,7 +106,7 @@ pub struct ProofEvaluations<Evals> {

/// Commitments linked to the lookup feature
#[serde_as]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(bound = "G: ark_serialize::CanonicalDeserialize + ark_serialize::CanonicalSerialize")]
pub struct LookupCommitments<G: AffineRepr> {
/// Commitments to the sorted lookup table polynomial (may have chunks)
Expand All @@ -119,7 +119,7 @@ pub struct LookupCommitments<G: AffineRepr> {

/// All the commitments that the prover creates as part of the proof.
#[serde_as]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(bound = "G: ark_serialize::CanonicalDeserialize + ark_serialize::CanonicalSerialize")]
pub struct ProverCommitments<G: AffineRepr> {
/// The commitments to the witness (execution trace)
Expand All @@ -134,7 +134,7 @@ pub struct ProverCommitments<G: AffineRepr> {

/// The proof that the prover creates from a [ProverIndex](super::prover_index::ProverIndex) and a `witness`.
#[serde_as]
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(bound = "G: ark_serialize::CanonicalDeserialize + ark_serialize::CanonicalSerialize")]
pub struct ProverProof<G: AffineRepr, OpeningProof> {
/// All the polynomial commitments required in the proof
Expand All @@ -160,7 +160,7 @@ pub struct ProverProof<G: AffineRepr, OpeningProof> {

/// A struct to store the challenges inside a `ProverProof`
#[serde_as]
#[derive(Debug, Clone, Deserialize, Serialize)]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
#[serde(bound = "G: ark_serialize::CanonicalDeserialize + ark_serialize::CanonicalSerialize")]
pub struct RecursionChallenge<G>
where
Expand Down
11 changes: 8 additions & 3 deletions kimchi/src/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ use poly_commitment::{
evaluation_proof::DensePolynomialOrEvaluations,
OpenProof, SRS as _,
};
use rand_core::{CryptoRng, RngCore};
use rayon::prelude::*;
use std::array;
use std::collections::HashMap;
Expand Down Expand Up @@ -134,22 +135,25 @@ where
pub fn create<
EFqSponge: Clone + FqSponge<G::BaseField, G, G::ScalarField>,
EFrSponge: FrSponge<G::ScalarField>,
RNG: RngCore + CryptoRng,
>(
groupmap: &G::Map,
witness: [Vec<G::ScalarField>; COLUMNS],
runtime_tables: &[RuntimeTable<G::ScalarField>],
index: &ProverIndex<G, OpeningProof>,
rng: &mut RNG,
) -> Result<Self>
where
VerifierIndex<G, OpeningProof>: Clone,
{
Self::create_recursive::<EFqSponge, EFrSponge>(
Self::create_recursive::<EFqSponge, EFrSponge, RNG>(
groupmap,
witness,
runtime_tables,
index,
Vec::new(),
None,
rng,
)
}

Expand All @@ -165,13 +169,15 @@ where
pub fn create_recursive<
EFqSponge: Clone + FqSponge<G::BaseField, G, G::ScalarField>,
EFrSponge: FrSponge<G::ScalarField>,
RNG: RngCore + CryptoRng,
>(
group_map: &G::Map,
mut witness: [Vec<G::ScalarField>; COLUMNS],
runtime_tables: &[RuntimeTable<G::ScalarField>],
index: &ProverIndex<G, OpeningProof>,
prev_challenges: Vec<RecursionChallenge<G>>,
blinders: Option<[Option<PolyComm<G::ScalarField>>; COLUMNS]>,
rng: &mut RNG,
) -> Result<Self>
where
VerifierIndex<G, OpeningProof>: Clone,
Expand All @@ -187,8 +193,7 @@ where
d1_size / index.max_poly_size
};

// TODO: rng should be passed as arg
let rng = &mut rand::rngs::OsRng;
//let rng = &mut rand::rngs::OsRng;

// Verify the circuit satisfiability by the computed witness (baring plookup constraints)
// Catch mistakes before proof generation.
Expand Down
Loading

0 comments on commit d48799c

Please sign in to comment.