Skip to content
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

[Design Discussion] Zk Accel API via trait object [skip ci - Don't merge] #13

Draft
wants to merge 2 commits into
base: taiko/unstable
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion halo2_gadgets/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ ff = { version = "0.13", features = ["bits"] }
group = "0.13"
halo2_proofs = { version = "0.2", path = "../halo2_proofs" }
lazy_static = "1"
halo2curves = { git = 'https://github.com/privacy-scaling-explorations/halo2curves', tag = "0.3.2" }
halo2curves = { git = 'https://github.com/taikoxyz/halo2curves', branch = "zal-on-0.3.2" }
proptest = { version = "1.0.0", optional = true }
rand = "0.8"
subtle = "2.3"
Expand Down
6 changes: 1 addition & 5 deletions halo2_proofs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ keywords = ["halo", "proofs", "zkp", "zkSNARKs"]
all-features = true
rustdoc-args = ["--cfg", "docsrs", "--html-in-header", "katex-header.html"]

[[bench]]
name = "arithmetic"
harness = false

[[bench]]
name = "commit_zk"
harness = false
Expand All @@ -53,7 +49,7 @@ backtrace = { version = "0.3", optional = true }
rayon = "1.5.1"
ff = "0.13"
group = "0.13"
halo2curves = { git = 'https://github.com/privacy-scaling-explorations/halo2curves', tag = "0.3.2" }
halo2curves = { git = 'https://github.com/taikoxyz/halo2curves', branch = "zal-on-0.3.2" }
rand_core = { version = "0.6", default-features = false }
tracing = "0.1"
blake2b_simd = "1"
Expand Down
38 changes: 0 additions & 38 deletions halo2_proofs/benches/arithmetic.rs

This file was deleted.

9 changes: 6 additions & 3 deletions halo2_proofs/examples/cost-model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ use std::{
use ff::Field;
use group::{Curve, Group};
use gumdrop::Options;
use halo2_proofs::arithmetic::best_multiexp;
use halo2curves::pasta::pallas;
use halo2curves::{
pasta::pallas,
zal::{H2cEngine, MsmAccel},
};

struct Estimator {
/// Scalars for estimating multiexp performance.
Expand Down Expand Up @@ -41,7 +43,8 @@ impl Estimator {

fn multiexp(&self, size: usize) -> Duration {
let start = Instant::now();
best_multiexp(&self.multiexp_scalars[..size], &self.multiexp_bases[..size]);
let engine = H2cEngine::new();
engine.msm(&self.multiexp_scalars[..size], &self.multiexp_bases[..size]);
Instant::now().duration_since(start)
}
}
Expand Down
8 changes: 8 additions & 0 deletions halo2_proofs/src/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ where
/// TEMP
pub static mut MULTIEXP_TOTAL_TIME: usize = 0;

#[deprecated(since="0.3.2", note="please use ZAL api engine instead,\nsee: https://github.com/privacy-scaling-explorations/halo2/issues/216")]
fn multiexp_serial<C: CurveAffine>(coeffs: &[C::Scalar], bases: &[C], acc: &mut C::Curve) {
let coeffs: Vec<_> = coeffs.iter().map(|a| a.to_repr()).collect();

Expand Down Expand Up @@ -130,6 +131,7 @@ fn multiexp_serial<C: CurveAffine>(coeffs: &[C::Scalar], bases: &[C], acc: &mut

/// Performs a small multi-exponentiation operation.
/// Uses the double-and-add algorithm with doublings shared across points.
#[deprecated(since="0.3.2", note="please use ZAL api engine instead,\nsee: https://github.com/privacy-scaling-explorations/halo2/issues/216")]
pub fn small_multiexp<C: CurveAffine>(coeffs: &[C::Scalar], bases: &[C]) -> C::Curve {
let coeffs: Vec<_> = coeffs.iter().map(|a| a.to_repr()).collect();
let mut acc = C::Curve::identity();
Expand Down Expand Up @@ -157,6 +159,10 @@ pub fn small_multiexp<C: CurveAffine>(coeffs: &[C::Scalar], bases: &[C]) -> C::C
/// This function will panic if coeffs and bases have a different length.
///
/// This will use multithreading if beneficial.
#[deprecated(
since = "0.3.2",
note = "please use ZAL api engine instead,\nsee: https://github.com/privacy-scaling-explorations/halo2/issues/216"
)]
pub fn best_multiexp<C: CurveAffine>(coeffs: &[C::Scalar], bases: &[C]) -> C::Curve {
assert_eq!(coeffs.len(), bases.len());

Expand All @@ -177,13 +183,15 @@ pub fn best_multiexp<C: CurveAffine>(coeffs: &[C::Scalar], bases: &[C]) -> C::Cu
.zip(results.iter_mut())
{
scope.spawn(move |_| {
#[allow(deprecated)]
multiexp_serial(coeffs, bases, acc);
});
}
});
results.iter().fold(C::Curve::identity(), |a, b| a + b)
} else {
let mut acc = C::Curve::identity();
#[allow(deprecated)]
multiexp_serial(coeffs, bases, &mut acc);
acc
};
Expand Down
2 changes: 1 addition & 1 deletion halo2_proofs/src/plonk/verifier/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ struct BatchStrategy<'params, C: CurveAffine> {
}

impl<'params, C: CurveAffine>
VerificationStrategy<'params, IPACommitmentScheme<C>, VerifierIPA<'params, C>>
VerificationStrategy<'params, IPACommitmentScheme<'params, C>, VerifierIPA<'params, C>>
for BatchStrategy<'params, C>
{
type Output = MSMIPA<'params, C>;
Expand Down
11 changes: 6 additions & 5 deletions halo2_proofs/src/poly/commitment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::transcript::{EncodedChallenge, TranscriptRead, TranscriptWrite};
use ff::Field;
use group::{Curve, Group};
use halo2curves::{CurveAffine, CurveExt};
use halo2curves::zal::MsmAccel;
use rand_core::RngCore;
use std::{
fmt::Debug,
Expand All @@ -34,10 +35,10 @@ pub trait CommitmentScheme {
type ParamsVerifier: for<'params> ParamsVerifier<'params, Self::Curve>;

/// Wrapper for parameter generator
fn new_params(k: u32) -> Self::ParamsProver;
fn new_params<'zal>(k: u32, engine: &'zal dyn MsmAccel<Self::Curve>) -> Self::ParamsProver;

/// Wrapper for parameter reader
fn read_params<R: io::Read>(reader: &mut R) -> io::Result<Self::ParamsProver>;
fn read_params<'zal, R: io::Read>(reader: &mut R, engine: &'zal dyn MsmAccel<Self::Curve>) -> io::Result<Self::ParamsProver>;
}

/// Parameters for circuit sysnthesis and prover parameters.
Expand Down Expand Up @@ -71,7 +72,7 @@ pub trait Params<'params, C: CurveAffine>: Sized + Clone {
fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()>;

/// Reads params from a buffer.
fn read<R: io::Read>(reader: &mut R) -> io::Result<Self>;
fn read<R: io::Read>(reader: &mut R, engine: &'params dyn MsmAccel<C>) -> io::Result<Self>;
}

/// Parameters for circuit sysnthesis and prover parameters.
Expand All @@ -80,7 +81,7 @@ pub trait ParamsProver<'params, C: CurveAffine>: Params<'params, C> {
type ParamsVerifier: ParamsVerifier<'params, C>;

/// Returns new instance of parameters
fn new(k: u32) -> Self;
fn new(k: u32, engine: &'params dyn MsmAccel<C>) -> Self;

/// This computes a commitment to a polynomial described by the provided
/// slice of coefficients. The commitment may be blinded by the blinding
Expand All @@ -99,7 +100,7 @@ pub trait ParamsProver<'params, C: CurveAffine>: Params<'params, C> {
pub trait ParamsVerifier<'params, C: CurveAffine>: Params<'params, C> {}

/// Multi scalar multiplication engine
pub trait MSM<C: CurveAffine>: Clone + Debug + Send + Sync {
pub trait MSM<C: CurveAffine>: Clone + Debug {
/// Add arbitrary term (the scalar and the point)
fn append_term(&mut self, scalar: C::Scalar, point: C::CurveExt);

Expand Down
62 changes: 35 additions & 27 deletions halo2_proofs/src/poly/ipa/commitment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@
//!
//! [halo]: https://eprint.iacr.org/2019/1021

use crate::arithmetic::{
best_fft, best_multiexp, g_to_lagrange, parallelize, CurveAffine, CurveExt,
};
use crate::arithmetic::{best_fft, g_to_lagrange, parallelize, CurveAffine, CurveExt};
use crate::helpers::CurveRead;
use crate::poly::commitment::{Blind, CommitmentScheme, Params, ParamsProver, ParamsVerifier, MSM};
use crate::poly::ipa::msm::MSMIPA;
use crate::poly::{Coeff, LagrangeCoeff, Polynomial};

use ff::{Field, PrimeField};
use group::{prime::PrimeCurveAffine, Curve, Group};
use halo2curves::zal::MsmAccel;
use std::marker::PhantomData;
use std::ops::{Add, AddAssign, Mul, MulAssign};

Expand All @@ -26,7 +25,8 @@ use std::io;

/// Public parameters for IPA commitment scheme
#[derive(Debug, Clone)]
pub struct ParamsIPA<C: CurveAffine> {
pub struct ParamsIPA<'zal, C: CurveAffine> {
pub(crate) engine: &'zal dyn MsmAccel<C>,
pub(crate) k: u32,
pub(crate) n: u64,
pub(crate) g: Vec<C>,
Expand All @@ -37,32 +37,32 @@ pub struct ParamsIPA<C: CurveAffine> {

/// Concrete IPA commitment scheme
#[derive(Debug)]
pub struct IPACommitmentScheme<C: CurveAffine> {
_marker: PhantomData<C>,
pub struct IPACommitmentScheme<'zal, C: CurveAffine> {
_marker: PhantomData<&'zal C>,
}

impl<C: CurveAffine> CommitmentScheme for IPACommitmentScheme<C> {
impl<'zal, C: CurveAffine> CommitmentScheme for IPACommitmentScheme<'zal, C> {
type Scalar = C::ScalarExt;
type Curve = C;

type ParamsProver = ParamsIPA<C>;
type ParamsVerifier = ParamsVerifierIPA<C>;
type ParamsProver = ParamsIPA<'zal, C>;
type ParamsVerifier = ParamsVerifierIPA<'zal, C>;

fn new_params(k: u32) -> Self::ParamsProver {
ParamsIPA::new(k)
fn new_params(k: u32, engine: &'zal dyn MsmAccel<C>) -> Self::ParamsProver {
ParamsIPA::new(k, engine)
}

fn read_params<R: io::Read>(reader: &mut R) -> io::Result<Self::ParamsProver> {
ParamsIPA::read(reader)
fn read_params<R: io::Read>(reader: &mut R, engine: &'zal dyn MsmAccel<C>) -> io::Result<Self::ParamsProver> {
ParamsIPA::read(reader, engine)
}
}

/// Verifier parameters
pub type ParamsVerifierIPA<C> = ParamsIPA<C>;
pub type ParamsVerifierIPA<'zal, C> = ParamsIPA<'zal, C>;

impl<'params, C: CurveAffine> ParamsVerifier<'params, C> for ParamsIPA<C> {}
impl<'params, C: CurveAffine> ParamsVerifier<'params, C> for ParamsIPA<'params, C> {}

impl<'params, C: CurveAffine> Params<'params, C> for ParamsIPA<C> {
impl<'params, C: CurveAffine> Params<'params, C> for ParamsIPA<'params, C> {
type MSM = MSMIPA<'params, C>;

fn k(&self) -> u32 {
Expand Down Expand Up @@ -103,7 +103,7 @@ impl<'params, C: CurveAffine> Params<'params, C> for ParamsIPA<C> {
tmp_bases.extend(self.g_lagrange.iter());
tmp_bases.push(self.w);

best_multiexp::<C>(&tmp_scalars, &tmp_bases)
self.engine.msm(&tmp_scalars, &tmp_bases)
}

/// Writes params to a buffer.
Expand All @@ -122,7 +122,7 @@ impl<'params, C: CurveAffine> Params<'params, C> for ParamsIPA<C> {
}

/// Reads params from a buffer.
fn read<R: io::Read>(reader: &mut R) -> io::Result<Self> {
fn read<R: io::Read>(reader: &mut R, engine: &'params dyn MsmAccel<C>) -> io::Result<Self> {
let mut k = [0u8; 4];
reader.read_exact(&mut k[..])?;
let k = u32::from_le_bytes(k);
Expand All @@ -136,6 +136,7 @@ impl<'params, C: CurveAffine> Params<'params, C> for ParamsIPA<C> {
let u = C::read(reader)?;

Ok(Self {
engine,
k,
n,
g,
Expand All @@ -146,16 +147,16 @@ impl<'params, C: CurveAffine> Params<'params, C> for ParamsIPA<C> {
}
}

impl<'params, C: CurveAffine> ParamsProver<'params, C> for ParamsIPA<C> {
type ParamsVerifier = ParamsVerifierIPA<C>;
impl<'params, C: CurveAffine> ParamsProver<'params, C> for ParamsIPA<'params, C> {
type ParamsVerifier = ParamsVerifierIPA<'params, C>;

fn verifier_params(&'params self) -> &'params Self::ParamsVerifier {
self
}

/// Initializes parameters for the curve, given a random oracle to draw
/// points from.
fn new(k: u32) -> Self {
fn new(k: u32, engine: &'params dyn MsmAccel<C>) -> Self {
// This is usually a limitation on the curve, but we also want 32-bit
// architectures to be supported.
assert!(k < 32);
Expand Down Expand Up @@ -201,6 +202,7 @@ impl<'params, C: CurveAffine> ParamsProver<'params, C> for ParamsIPA<C> {
let u = hasher(&[2]).to_affine();

ParamsIPA {
engine,
k,
n,
g,
Expand All @@ -223,7 +225,7 @@ impl<'params, C: CurveAffine> ParamsProver<'params, C> for ParamsIPA<C> {
tmp_bases.extend(self.g.iter());
tmp_bases.push(self.w);

best_multiexp::<C>(&tmp_scalars, &tmp_bases)
self.engine.msm(&tmp_scalars, &tmp_bases)
}

fn get_g(&self) -> &[C] {
Expand All @@ -234,7 +236,7 @@ impl<'params, C: CurveAffine> ParamsProver<'params, C> for ParamsIPA<C> {
#[cfg(test)]
mod test {

use crate::arithmetic::{best_fft, best_multiexp, parallelize, CurveAffine, CurveExt};
use crate::arithmetic::{best_fft, parallelize, CurveAffine, CurveExt};
use crate::helpers::CurveRead;
use crate::poly::commitment::ParamsProver;
use crate::poly::commitment::{Blind, CommitmentScheme, Params, MSM};
Expand All @@ -257,8 +259,10 @@ mod test {

use crate::poly::EvaluationDomain;
use halo2curves::pasta::{EpAffine, Fq};
use halo2curves::zal::H2cEngine;

let params = ParamsIPA::<EpAffine>::new(K);
let engine = H2cEngine::new();
let params = ParamsIPA::<EpAffine>::new(K, &engine);
let domain = EvaluationDomain::new(1, K);

let mut a = domain.empty_lagrange();
Expand All @@ -282,8 +286,10 @@ mod test {

use crate::poly::EvaluationDomain;
use halo2curves::pasta::{EqAffine, Fp};
use crate::halo2curves::zal::H2cEngine;

let params: ParamsIPA<EqAffine> = ParamsIPA::<EqAffine>::new(K);
let engine = H2cEngine::new();
let params: ParamsIPA<EqAffine> = ParamsIPA::<EqAffine>::new(K, &engine);
let domain = EvaluationDomain::new(1, K);

let mut a = domain.empty_lagrange();
Expand All @@ -309,6 +315,7 @@ mod test {
use super::super::commitment::{Blind, Params};
use crate::arithmetic::eval_polynomial;
use crate::halo2curves::pasta::{EpAffine, Fq};
use crate::halo2curves::zal::H2cEngine;
use crate::poly::EvaluationDomain;
use crate::transcript::{
Blake2bRead, Blake2bWrite, Challenge255, Transcript, TranscriptRead, TranscriptWrite,
Expand All @@ -319,10 +326,11 @@ mod test {

let rng = OsRng;

let params = ParamsIPA::<EpAffine>::new(K);
let engine = H2cEngine::new();
let params = ParamsIPA::<EpAffine>::new(K, &engine);
let mut params_buffer = vec![];
<ParamsIPA<_> as Params<_>>::write(&params, &mut params_buffer).unwrap();
let params: ParamsIPA<EpAffine> = Params::read::<_>(&mut &params_buffer[..]).unwrap();
let params: ParamsIPA<EpAffine> = Params::read::<_>(&mut &params_buffer[..], &engine).unwrap();

let domain = EvaluationDomain::new(1, K);

Expand Down
Loading