Skip to content

Commit

Permalink
Implement ZAL API (Zk Acceleration Layer)
Browse files Browse the repository at this point in the history
  • Loading branch information
mratsim committed Mar 29, 2024
1 parent 720ba51 commit 07fe228
Show file tree
Hide file tree
Showing 28 changed files with 737 additions and 117 deletions.
2 changes: 2 additions & 0 deletions halo2_backend/src/plonk/keygen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use group::Curve;
use halo2_middleware::ff::{Field, FromUniformBytes};
use halo2_middleware::zal::impls::H2cEngine;

use super::{evaluation::Evaluator, permutation, Polynomial, ProvingKey, VerifyingKey};
use crate::{
Expand Down Expand Up @@ -70,6 +71,7 @@ where
.map(|poly| {
params
.commit_lagrange(
&H2cEngine::new(),
&Polynomial::new_lagrange_from_vec(poly.clone()),
Blind::default(),
)
Expand Down
14 changes: 12 additions & 2 deletions halo2_backend/src/plonk/lookup/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use group::{
};
use halo2_middleware::ff::WithSmallOrderMulGroup;
use halo2_middleware::poly::Rotation;
use halo2_middleware::zal::{impls::PlonkEngine, traits::MsmAccel};
use rand_core::RngCore;
use std::{
collections::BTreeMap,
Expand Down Expand Up @@ -69,7 +70,9 @@ pub(in crate::plonk) fn lookup_commit_permuted<
E: EncodedChallenge<C>,
R: RngCore,
T: TranscriptWrite<C, E>,
M: MsmAccel<C>,
>(
engine: &PlonkEngine<C, M>,
arg: &Argument<F>,
pk: &ProvingKey<C>,
params: &P,
Expand Down Expand Up @@ -127,7 +130,9 @@ where
let mut commit_values = |values: &Polynomial<C::Scalar, LagrangeCoeff>| {
let poly = pk.vk.domain.lagrange_to_coeff(values.clone());
let blind = Blind(C::Scalar::random(&mut rng));
let commitment = params.commit_lagrange(values, blind).to_affine();
let commitment = params
.commit_lagrange(&engine.msm_backend, values, blind)
.to_affine();
(poly, blind, commitment)
};

Expand Down Expand Up @@ -163,14 +168,17 @@ impl<C: CurveAffine> Permuted<C> {
/// grand product polynomial over the lookup. The grand product polynomial
/// is used to populate the [`Committed<C>`] struct. The [`Committed<C>`] struct is
/// added to the Lookup and finally returned by the method.
#[allow(clippy::too_many_arguments)]
pub(in crate::plonk) fn commit_product<
'params,
P: Params<'params, C>,
E: EncodedChallenge<C>,
R: RngCore,
T: TranscriptWrite<C, E>,
M: MsmAccel<C>,
>(
self,
engine: &PlonkEngine<C, M>,
pk: &ProvingKey<C>,
params: &P,
beta: ChallengeBeta<C>,
Expand Down Expand Up @@ -287,7 +295,9 @@ impl<C: CurveAffine> Permuted<C> {
}

let product_blind = Blind(C::Scalar::random(rng));
let product_commitment = params.commit_lagrange(&z, product_blind).to_affine();
let product_commitment = params
.commit_lagrange(&engine.msm_backend, &z, product_blind)
.to_affine();
let z = pk.vk.domain.lagrange_to_coeff(z);

// Hash product commitment
Expand Down
3 changes: 2 additions & 1 deletion halo2_backend/src/plonk/permutation/keygen.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use group::Curve;
use halo2_middleware::ff::{Field, PrimeField};
use halo2_middleware::zal::impls::H2cEngine;

use super::{Argument, ProvingKey, VerifyingKey};
use crate::{
Expand Down Expand Up @@ -265,7 +266,7 @@ pub(crate) fn build_vk<'params, C: CurveAffine, P: Params<'params, C>>(
// Compute commitment to permutation polynomial
commitments.push(
params
.commit_lagrange(permutation, Blind::default())
.commit_lagrange(&H2cEngine::new(), permutation, Blind::default())
.to_affine(),
);
}
Expand Down
8 changes: 6 additions & 2 deletions halo2_backend/src/plonk/permutation/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use group::{
ff::{BatchInvert, Field},
Curve,
};
use halo2_middleware::ff::PrimeField;
use halo2_middleware::zal::traits::MsmAccel;
use halo2_middleware::{ff::PrimeField, zal::impls::PlonkEngine};
use rand_core::RngCore;
use std::iter::{self, ExactSizeIterator};

Expand Down Expand Up @@ -53,7 +54,9 @@ pub(in crate::plonk) fn permutation_commit<
E: EncodedChallenge<C>,
R: RngCore,
T: TranscriptWrite<C, E>,
M: MsmAccel<C>,
>(
engine: &PlonkEngine<C, M>,
arg: &Argument,
params: &P,
pk: &plonk::ProvingKey<C>,
Expand Down Expand Up @@ -171,7 +174,8 @@ pub(in crate::plonk) fn permutation_commit<

let blind = Blind(C::Scalar::random(&mut rng));

let permutation_product_commitment_projective = params.commit_lagrange(&z, blind);
let permutation_product_commitment_projective =
params.commit_lagrange(&engine.msm_backend, &z, blind);
let permutation_product_blind = blind;
let z = domain.lagrange_to_coeff(z);
let permutation_product_poly = z.clone();
Expand Down
85 changes: 72 additions & 13 deletions halo2_backend/src/plonk/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ use crate::poly::{
};
use crate::transcript::{EncodedChallenge, TranscriptWrite};
use halo2_middleware::ff::{Field, FromUniformBytes, WithSmallOrderMulGroup};
use halo2_middleware::zal::{
impls::{H2cEngine, PlonkEngine, PlonkEngineConfig},
traits::MsmAccel,
};

/// Collection of instance data used during proving for a single circuit proof.
#[derive(Debug)]
Expand All @@ -45,7 +49,8 @@ pub struct ProverV2Single<
E: EncodedChallenge<Scheme::Curve>,
R: RngCore,
T: TranscriptWrite<Scheme::Curve, E>,
>(ProverV2<'a, 'params, Scheme, P, E, R, T>);
M: MsmAccel<Scheme::Curve>,
>(ProverV2<'a, 'params, Scheme, P, E, R, T, M>);

impl<
'a,
Expand All @@ -55,10 +60,12 @@ impl<
E: EncodedChallenge<Scheme::Curve>,
R: RngCore,
T: TranscriptWrite<Scheme::Curve, E>,
> ProverV2Single<'a, 'params, Scheme, P, E, R, T>
M: MsmAccel<Scheme::Curve>,
> ProverV2Single<'a, 'params, Scheme, P, E, R, T, M>
{
/// Create a new prover object
pub fn new(
pub fn new_with_engine(
engine: PlonkEngine<Scheme::Curve, M>,
params: &'params Scheme::ParamsProver,
pk: &'a ProvingKey<Scheme::Curve>,
// TODO: If this was a vector the usage would be simpler
Expand All @@ -70,7 +77,8 @@ impl<
where
Scheme::Scalar: WithSmallOrderMulGroup<3> + FromUniformBytes<64>,
{
Ok(Self(ProverV2::new(
Ok(Self(ProverV2::new_with_engine(
engine,
params,
pk,
&[instance],
Expand All @@ -79,6 +87,22 @@ impl<
)?))
}

pub fn new(
params: &'params Scheme::ParamsProver,
pk: &'a ProvingKey<Scheme::Curve>,
// TODO: If this was a vector the usage would be simpler
// https://github.com/privacy-scaling-explorations/halo2/issues/265
instance: &[&[Scheme::Scalar]],
rng: R,
transcript: &'a mut T,
) -> Result<ProverV2Single<'a, 'params, Scheme, P, E, R, T, H2cEngine>, Error>
where
Scheme::Scalar: WithSmallOrderMulGroup<3> + FromUniformBytes<64>,
{
let engine = PlonkEngineConfig::build_default();
ProverV2Single::new_with_engine(engine, params, pk, instance, rng, transcript)
}

/// Commit the `witness` at `phase` and return the challenges after `phase`.
pub fn commit_phase(
&mut self,
Expand Down Expand Up @@ -111,7 +135,9 @@ pub struct ProverV2<
E: EncodedChallenge<Scheme::Curve>,
R: RngCore,
T: TranscriptWrite<Scheme::Curve, E>,
M: MsmAccel<Scheme::Curve>,
> {
engine: PlonkEngine<Scheme::Curve, M>,
// Circuit and setup fields
params: &'params Scheme::ParamsProver,
// Plonk proving key
Expand Down Expand Up @@ -141,10 +167,12 @@ impl<
E: EncodedChallenge<Scheme::Curve>,
R: RngCore,
T: TranscriptWrite<Scheme::Curve, E>,
> ProverV2<'a, 'params, Scheme, P, E, R, T>
M: MsmAccel<Scheme::Curve>,
> ProverV2<'a, 'params, Scheme, P, E, R, T, M>
{
/// Create a new prover object
pub fn new(
pub fn new_with_engine(
engine: PlonkEngine<Scheme::Curve, M>,
params: &'params Scheme::ParamsProver,
pk: &'a ProvingKey<Scheme::Curve>,
// TODO: If this was a vector the usage would be simpler.
Expand Down Expand Up @@ -200,7 +228,9 @@ impl<

let instance_commitments_projective: Vec<_> = instance_values
.iter()
.map(|poly| params.commit_lagrange(poly, Blind::default()))
.map(|poly| {
params.commit_lagrange(&engine.msm_backend, poly, Blind::default())
})
.collect();
let mut instance_commitments =
vec![Scheme::Curve::identity(); instance_commitments_projective.len()];
Expand Down Expand Up @@ -260,6 +290,7 @@ impl<
let challenges = HashMap::<usize, Scheme::Scalar>::with_capacity(meta.num_challenges);

Ok(ProverV2 {
engine,
params,
pk,
phases,
Expand Down Expand Up @@ -404,7 +435,7 @@ impl<
let advice_commitments_projective: Vec<_> = advice_values
.iter()
.zip(blinds.iter())
.map(|(poly, blind)| params.commit_lagrange(poly, *blind))
.map(|(poly, blind)| params.commit_lagrange(&self.engine.msm_backend, poly, *blind))
.collect();
let mut advice_commitments_affine =
vec![Scheme::Curve::identity(); advice_commitments_projective.len()];
Expand Down Expand Up @@ -476,7 +507,7 @@ impl<
/// - 11. Compute and hash fixed evals
/// - 12. Evaluate permutation, lookups and shuffles at x
/// - 13. Generate all queries ([`ProverQuery`])
/// - 14. Send the queries to the [`Prover`]
/// - 14. Send the queries to the [`Prover`]
pub fn create_proof(mut self) -> Result<(), Error>
where
Scheme::Scalar: WithSmallOrderMulGroup<3> + FromUniformBytes<64>,
Expand Down Expand Up @@ -515,6 +546,7 @@ impl<
.iter()
.map(|lookup| {
lookup_commit_permuted(
&self.engine,
lookup,
pk,
params,
Expand Down Expand Up @@ -554,6 +586,7 @@ impl<
.zip(advices.iter())
.map(|(instance, advice)| {
permutation_commit(
&self.engine,
&cs.permutation,
params,
pk,
Expand All @@ -579,7 +612,15 @@ impl<
lookups
.into_iter()
.map(|lookup| {
lookup.commit_product(pk, params, beta, gamma, &mut rng, self.transcript)
lookup.commit_product(
&self.engine,
pk,
params,
beta,
gamma,
&mut rng,
self.transcript,
)
})
.collect::<Result<Vec<_>, _>>()
})
Expand All @@ -597,6 +638,7 @@ impl<
.iter()
.map(|shuffle| {
shuffle_commit_product(
&self.engine,
shuffle,
pk,
params,
Expand All @@ -617,7 +659,7 @@ impl<

// 5. Commit to the vanishing argument's random polynomial for blinding h(x_3) -------------------
// [TRANSCRIPT-12]
let vanishing = vanishing::Argument::commit(params, domain, &mut rng, self.transcript)?;
let vanishing = vanishing::Argument::commit(&self.engine.msm_backend, params, domain, &mut rng, self.transcript)?;

// 6. Generate the advice polys ------------------------------------------------------------------

Expand Down Expand Up @@ -667,7 +709,7 @@ impl<

// 8. Construct the vanishing argument's h(X) commitments --------------------------------------
// [TRANSCRIPT-14]
let vanishing = vanishing.construct(params, domain, h_poly, &mut rng, self.transcript)?;
let vanishing = vanishing.construct(&self.engine, params, domain, h_poly, &mut rng, self.transcript)?;

// 9. Compute x --------------------------------------------------------------------------------
// [TRANSCRIPT-15]
Expand Down Expand Up @@ -836,7 +878,7 @@ impl<

let prover = P::new(params);
prover
.create_proof(rng, self.transcript, queries)
.create_proof_with_engine(&self.engine.msm_backend, rng, self.transcript, queries)
.map_err(|_| Error::ConstraintSystemFailure)?;

Ok(())
Expand All @@ -846,4 +888,21 @@ impl<
pub fn phases(&self) -> &[u8] {
self.phases.as_slice()
}

/// Create a new prover object
pub fn new(
params: &'params Scheme::ParamsProver,
pk: &'a ProvingKey<Scheme::Curve>,
// TODO: If this was a vector the usage would be simpler.
// https://github.com/privacy-scaling-explorations/halo2/issues/265
circuits_instances: &[&[&[Scheme::Scalar]]],
rng: R,
transcript: &'a mut T,
) -> Result<ProverV2<'a, 'params, Scheme, P, E, R, T, H2cEngine>, Error>
where
Scheme::Scalar: WithSmallOrderMulGroup<3> + FromUniformBytes<64>,
{
let engine = PlonkEngineConfig::build_default();
ProverV2::new_with_engine(engine, params, pk, circuits_instances, rng, transcript)
}
}
7 changes: 6 additions & 1 deletion halo2_backend/src/plonk/shuffle/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::{
};
use group::{ff::BatchInvert, ff::WithSmallOrderMulGroup, Curve};
use halo2_middleware::poly::Rotation;
use halo2_middleware::zal::{impls::PlonkEngine, traits::MsmAccel};
use rand_core::RngCore;
use std::{
iter,
Expand Down Expand Up @@ -102,7 +103,9 @@ pub(in crate::plonk) fn shuffle_commit_product<
E: EncodedChallenge<C>,
R: RngCore,
T: TranscriptWrite<C, E>,
M: MsmAccel<C>,
>(
engine: &PlonkEngine<C, M>,
arg: &Argument<F>,
pk: &ProvingKey<C>,
params: &P,
Expand Down Expand Up @@ -188,7 +191,9 @@ where
}

let product_blind = Blind(C::Scalar::random(rng));
let product_commitment = params.commit_lagrange(&z, product_blind).to_affine();
let product_commitment = params
.commit_lagrange(&engine.msm_backend, &z, product_blind)
.to_affine();
let z = pk.vk.domain.lagrange_to_coeff(z);

// Hash product commitment
Expand Down
Loading

0 comments on commit 07fe228

Please sign in to comment.