WIP: ProverV2 implementation

This commit is contained in:
Eduard S. 2023-12-13 19:06:12 +01:00
parent d318a9d03d
commit a60192577f
2 changed files with 139 additions and 3 deletions

View File

@ -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
@ -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)]

View File

@ -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::{
@ -30,6 +30,117 @@ use crate::{
};
use group::prime::PrimeCurveAffine;
struct InstanceSingle<C: CurveAffine> {
pub instance_values: Vec<Polynomial<C::Scalar, LagrangeCoeff>>,
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>,
> {
params: &'params Scheme::ParamsProver,
instance: Vec<InstanceSingle<Scheme::Curve>>,
_marker: std::marker::PhantomData<(Scheme, P, E, R, T)>,
}
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,
mut transcript: T,
) -> Result<Self, Error>
where
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`