Skip to content

Commit

Permalink
WIP: ProverV2 implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
ed255 committed Dec 13, 2023
1 parent d318a9d commit a601925
Show file tree
Hide file tree
Showing 2 changed files with 139 additions and 3 deletions.
25 changes: 25 additions & 0 deletions halo2_proofs/src/plonk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,16 @@ impl<C: CurveAffine> VerifyingKeyV2<C> {

vk
}

/// Hashes a verification key into a transcript.
pub fn hash_into<E: EncodedChallenge<C>, T: Transcript<C, E>>(
&self,
transcript: &mut T,
) -> io::Result<()> {
transcript.common_scalar(self.transcript_repr)?;

Ok(())
}
}

/// This is a verifying key which allows for the verification of proofs for a
Expand Down Expand Up @@ -389,6 +399,21 @@ pub struct ProvingKeyV2<C: CurveAffine> {
ev: Evaluator<C>,
}

// impl<C: CurveAffine> ProvingKeyV2<C>
// where
// C::Scalar: FromUniformBytes<64>,
// {
// /// Hashes a verification key into a transcript.
// pub fn hash_into<E: EncodedChallenge<C>, T: Transcript<C, E>>(
// &self,
// transcript: &mut T,
// ) -> io::Result<()> {
// transcript.common_scalar(self.transcript_repr)?;
//
// Ok(())
// }
// }

/// This is a proving key which allows for the creation of proofs for a
/// particular circuit.
#[derive(Clone, Debug)]
Expand Down
117 changes: 114 additions & 3 deletions halo2_proofs/src/plonk/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ use std::{collections::HashMap, iter};
use super::{
circuit::{
sealed::{self},
Advice, Any, Assignment, Challenge, Circuit, Column, ConstraintSystem, Fixed, FloorPlanner,
Instance, Selector,
Advice, Any, Assignment, Challenge, Circuit, Column, CompiledCircuitV2, ConstraintSystem,
Fixed, FloorPlanner, Instance, Selector,
},
lookup, permutation, shuffle, vanishing, ChallengeBeta, ChallengeGamma, ChallengeTheta,
ChallengeX, ChallengeY, Error, ProvingKey,
ChallengeX, ChallengeY, Error, ProvingKey, ProvingKeyV2,
};

use crate::{
Expand All @@ -30,6 +30,117 @@ use crate::{
};
use group::prime::PrimeCurveAffine;

struct InstanceSingle<C: CurveAffine> {
pub instance_values: Vec<Polynomial<C::Scalar, LagrangeCoeff>>,

Check warning on line 34 in halo2_proofs/src/plonk/prover.rs

View workflow job for this annotation

GitHub Actions / Clippy (beta)

fields `instance_values` and `instance_polys` are never read

warning: fields `instance_values` and `instance_polys` are never read --> halo2_proofs/src/plonk/prover.rs:34:9 | 33 | struct InstanceSingle<C: CurveAffine> { | -------------- fields in this struct 34 | pub instance_values: Vec<Polynomial<C::Scalar, LagrangeCoeff>>, | ^^^^^^^^^^^^^^^ 35 | pub instance_polys: Vec<Polynomial<C::Scalar, Coeff>>, | ^^^^^^^^^^^^^^
pub instance_polys: Vec<Polynomial<C::Scalar, Coeff>>,
}

pub struct ProverV2<
'params,
Scheme: CommitmentScheme,
P: Prover<'params, Scheme>,
E: EncodedChallenge<Scheme::Curve>,
R: RngCore,
T: TranscriptWrite<Scheme::Curve, E>,
> {

Check failure on line 45 in halo2_proofs/src/plonk/prover.rs

View workflow job for this annotation

GitHub Actions / Clippy (beta)

missing documentation for a struct

error: missing documentation for a struct --> halo2_proofs/src/plonk/prover.rs:38:1 | 38 | / pub struct ProverV2< 39 | | 'params, 40 | | Scheme: CommitmentScheme, 41 | | P: Prover<'params, Scheme>, ... | 44 | | T: TranscriptWrite<Scheme::Curve, E>, 45 | | > { | |_^ | note: the lint level is defined here --> halo2_proofs/src/lib.rs:8:9 | 8 | #![deny(missing_docs)] | ^^^^^^^^^^^^
params: &'params Scheme::ParamsProver,

Check warning on line 46 in halo2_proofs/src/plonk/prover.rs

View workflow job for this annotation

GitHub Actions / Clippy (beta)

fields `params` and `instance` are never read

warning: fields `params` and `instance` are never read --> halo2_proofs/src/plonk/prover.rs:46:5 | 38 | pub struct ProverV2< | -------- fields in this struct ... 46 | params: &'params Scheme::ParamsProver, | ^^^^^^ 47 | instance: Vec<InstanceSingle<Scheme::Curve>>, | ^^^^^^^^
instance: Vec<InstanceSingle<Scheme::Curve>>,
_marker: std::marker::PhantomData<(Scheme, P, E, R, T)>,
}

Check failure on line 49 in halo2_proofs/src/plonk/prover.rs

View workflow job for this annotation

GitHub Actions / Clippy (beta)

type does not implement `std::fmt::Debug`; consider adding `#[derive(Debug)]` or a manual implementation

error: type does not implement `std::fmt::Debug`; consider adding `#[derive(Debug)]` or a manual implementation --> halo2_proofs/src/plonk/prover.rs:38:1 | 38 | / pub struct ProverV2< 39 | | 'params, 40 | | Scheme: CommitmentScheme, 41 | | P: Prover<'params, Scheme>, ... | 48 | | _marker: std::marker::PhantomData<(Scheme, P, E, R, T)>, 49 | | } | |_^ | note: the lint level is defined here --> halo2_proofs/src/lib.rs:7:9 | 7 | #![deny(missing_debug_implementations)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

impl<
'params,
Scheme: CommitmentScheme,
P: Prover<'params, Scheme>,
E: EncodedChallenge<Scheme::Curve>,
R: RngCore,
T: TranscriptWrite<Scheme::Curve, E>,
> ProverV2<'params, Scheme, P, E, R, T>
{
pub fn new(
params: &'params Scheme::ParamsProver,
pk: &ProvingKeyV2<Scheme::Curve>,
circuit: &CompiledCircuitV2<Scheme::Scalar>,
instance: &[&[Scheme::Scalar]],
mut rng: R,

Check warning on line 65 in halo2_proofs/src/plonk/prover.rs

View workflow job for this annotation

GitHub Actions / Clippy (beta)

variable does not need to be mutable

warning: variable does not need to be mutable --> halo2_proofs/src/plonk/prover.rs:65:9 | 65 | mut rng: R, | ----^^^ | | | help: remove this `mut` | = note: `#[warn(unused_mut)]` on by default

Check warning on line 65 in halo2_proofs/src/plonk/prover.rs

View workflow job for this annotation

GitHub Actions / Clippy (beta)

unused variable: `rng`

warning: unused variable: `rng` --> halo2_proofs/src/plonk/prover.rs:65:13 | 65 | mut rng: R, | ^^^ help: if this is intentional, prefix it with an underscore: `_rng` | = note: `#[warn(unused_variables)]` on by default
mut transcript: T,
) -> Result<Self, Error>
where
Scheme::Scalar: WithSmallOrderMulGroup<3> + FromUniformBytes<64>,

Check failure on line 69 in halo2_proofs/src/plonk/prover.rs

View workflow job for this annotation

GitHub Actions / Clippy (beta)

missing documentation for an associated function

error: missing documentation for an associated function --> halo2_proofs/src/plonk/prover.rs:60:5 | 60 | / pub fn new( 61 | | params: &'params Scheme::ParamsProver, 62 | | pk: &ProvingKeyV2<Scheme::Curve>, 63 | | circuit: &CompiledCircuitV2<Scheme::Scalar>, ... | 68 | | where 69 | | Scheme::Scalar: WithSmallOrderMulGroup<3> + FromUniformBytes<64>, | |_________________________________________________________________________^
{
if instance.len() != pk.vk.cs.num_instance_columns {
return Err(Error::InvalidInstances);
}

// Hash verification key into transcript
pk.vk.hash_into(&mut transcript)?;

let meta = &circuit.cs;

let domain = &pk.vk.domain;

let instance: Vec<InstanceSingle<Scheme::Curve>> = iter::once(instance)
.map(|instance| -> Result<InstanceSingle<Scheme::Curve>, Error> {
let instance_values = instance
.iter()
.map(|values| {
let mut poly = domain.empty_lagrange();
assert_eq!(poly.len(), params.n() as usize);
if values.len() > (poly.len() - (meta.blinding_factors() + 1)) {
return Err(Error::InstanceTooLarge);
}
for (poly, value) in poly.iter_mut().zip(values.iter()) {
if !P::QUERY_INSTANCE {
transcript.common_scalar(*value)?;
}
*poly = *value;
}
Ok(poly)
})
.collect::<Result<Vec<_>, _>>()?;

if P::QUERY_INSTANCE {
let instance_commitments_projective: Vec<_> = instance_values
.iter()
.map(|poly| params.commit_lagrange(poly, Blind::default()))
.collect();
let mut instance_commitments =
vec![Scheme::Curve::identity(); instance_commitments_projective.len()];
<Scheme::Curve as CurveAffine>::CurveExt::batch_normalize(
&instance_commitments_projective,
&mut instance_commitments,
);
let instance_commitments = instance_commitments;
drop(instance_commitments_projective);

for commitment in &instance_commitments {
transcript.common_point(*commitment)?;
}
}

let instance_polys: Vec<_> = instance_values
.iter()
.map(|poly| {
let lagrange_vec = domain.lagrange_from_vec(poly.to_vec());
domain.lagrange_to_coeff(lagrange_vec)
})
.collect();

Ok(InstanceSingle {
instance_values,
instance_polys,
})
})
.collect::<Result<Vec<_>, _>>()?;

Ok(ProverV2 {
params,
instance,
_marker: std::marker::PhantomData {},
})
}
}

/// This creates a proof for the provided `circuit` when given the public
/// parameters `params` and the proving key [`ProvingKey`] that was
/// generated previously for the same circuit. The provided `instances`
Expand Down

0 comments on commit a601925

Please sign in to comment.