diff --git a/Cargo.toml b/Cargo.toml index b7878ae843..255a70d2b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,3 +4,6 @@ members = [ "halo2_gadgets", "halo2_proofs", ] + +[patch."https://github.com/privacy-scaling-explorations/halo2curves"] +halo2curves = { path = "../halo2curves" } \ No newline at end of file diff --git a/halo2_proofs/benches/arithmetic.rs b/halo2_proofs/benches/arithmetic.rs index 4ae88af137..659caa10da 100644 --- a/halo2_proofs/benches/arithmetic.rs +++ b/halo2_proofs/benches/arithmetic.rs @@ -1,10 +1,10 @@ #[macro_use] extern crate criterion; -use crate::arithmetic::small_multiexp; -use crate::halo2curves::pasta::{EqAffine, Fp}; use group::ff::Field; use halo2_proofs::*; +use halo2curves::pasta::{EqAffine, Fp}; +use halo2curves::zal::{H2cEngine, MsmAccel}; use halo2_proofs::poly::{commitment::ParamsProver, ipa::commitment::ParamsIPA}; @@ -16,6 +16,7 @@ fn criterion_benchmark(c: &mut Criterion) { // small multiexp { + let engine = H2cEngine::new(); let params: ParamsIPA = ParamsIPA::new(5); let g = &mut params.get_g().to_vec(); let len = g.len() / 2; @@ -27,7 +28,7 @@ fn criterion_benchmark(c: &mut Criterion) { c.bench_function("double-and-add", |b| { b.iter(|| { for (g_lo, g_hi) in g_lo.iter().zip(g_hi.iter()) { - small_multiexp(&[black_box(coeff_1), black_box(coeff_2)], &[*g_lo, *g_hi]); + engine.msm(&[black_box(coeff_1), black_box(coeff_2)], &[*g_lo, *g_hi]); } }) }); diff --git a/halo2_proofs/examples/cost-model.rs b/halo2_proofs/examples/cost-model.rs index 100f047fac..d15b86028a 100644 --- a/halo2_proofs/examples/cost-model.rs +++ b/halo2_proofs/examples/cost-model.rs @@ -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. @@ -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) } } diff --git a/halo2_proofs/src/arithmetic.rs b/halo2_proofs/src/arithmetic.rs index 04abc20fb0..76ab1dc446 100644 --- a/halo2_proofs/src/arithmetic.rs +++ b/halo2_proofs/src/arithmetic.rs @@ -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(coeffs: &[C::Scalar], bases: &[C], acc: &mut C::Curve) { let coeffs: Vec<_> = coeffs.iter().map(|a| a.to_repr()).collect(); @@ -130,6 +131,7 @@ fn multiexp_serial(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(coeffs: &[C::Scalar], bases: &[C]) -> C::Curve { let coeffs: Vec<_> = coeffs.iter().map(|a| a.to_repr()).collect(); let mut acc = C::Curve::identity(); @@ -157,6 +159,10 @@ pub fn small_multiexp(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(coeffs: &[C::Scalar], bases: &[C]) -> C::Curve { assert_eq!(coeffs.len(), bases.len()); @@ -177,6 +183,7 @@ pub fn best_multiexp(coeffs: &[C::Scalar], bases: &[C]) -> C::Cu .zip(results.iter_mut()) { scope.spawn(move |_| { + #[allow(deprecated)] multiexp_serial(coeffs, bases, acc); }); } @@ -184,6 +191,7 @@ pub fn best_multiexp(coeffs: &[C::Scalar], bases: &[C]) -> C::Cu 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 }; diff --git a/halo2_proofs/src/poly/ipa/commitment.rs b/halo2_proofs/src/poly/ipa/commitment.rs index f9b4ad059b..9936dd42e1 100644 --- a/halo2_proofs/src/poly/ipa/commitment.rs +++ b/halo2_proofs/src/poly/ipa/commitment.rs @@ -3,9 +3,7 @@ //! //! [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; @@ -13,6 +11,7 @@ use crate::poly::{Coeff, LagrangeCoeff, Polynomial}; use ff::{Field, PrimeField}; use group::{prime::PrimeCurveAffine, Curve, Group}; +use halo2curves::zal::{H2cEngine, MsmAccel}; use std::marker::PhantomData; use std::ops::{Add, AddAssign, Mul, MulAssign}; @@ -103,7 +102,8 @@ impl<'params, C: CurveAffine> Params<'params, C> for ParamsIPA { tmp_bases.extend(self.g_lagrange.iter()); tmp_bases.push(self.w); - best_multiexp::(&tmp_scalars, &tmp_bases) + let engine = H2cEngine::new(); + engine.msm(&tmp_scalars, &tmp_bases) } /// Writes params to a buffer. @@ -223,7 +223,8 @@ impl<'params, C: CurveAffine> ParamsProver<'params, C> for ParamsIPA { tmp_bases.extend(self.g.iter()); tmp_bases.push(self.w); - best_multiexp::(&tmp_scalars, &tmp_bases) + let engine = H2cEngine::new(); + engine.msm(&tmp_scalars, &tmp_bases) } fn get_g(&self) -> &[C] { @@ -234,7 +235,7 @@ impl<'params, C: CurveAffine> ParamsProver<'params, C> for ParamsIPA { #[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}; diff --git a/halo2_proofs/src/poly/ipa/commitment/prover.rs b/halo2_proofs/src/poly/ipa/commitment/prover.rs index d176987c96..18d6d53dd4 100644 --- a/halo2_proofs/src/poly/ipa/commitment/prover.rs +++ b/halo2_proofs/src/poly/ipa/commitment/prover.rs @@ -1,10 +1,9 @@ use ff::Field; +use halo2curves::zal::{H2cEngine, MsmAccel}; use rand_core::RngCore; use super::{Params, ParamsIPA}; -use crate::arithmetic::{ - best_multiexp, compute_inner_product, eval_polynomial, parallelize, CurveAffine, -}; +use crate::arithmetic::{compute_inner_product, eval_polynomial, parallelize, CurveAffine}; use crate::poly::commitment::ParamsProver; use crate::poly::{commitment::Blind, Coeff, Polynomial}; @@ -98,6 +97,7 @@ pub fn create_proof< // this vector into smaller and smaller vectors until it is of length 1. let mut g_prime = params.g.clone(); + let engine = H2cEngine::new(); // Perform the inner product argument, round by round. for j in 0..params.k { let half = 1 << (params.k - j - 1); // half the length of `p_prime`, `b`, `G'` @@ -106,14 +106,14 @@ pub fn create_proof< // // TODO: If we modify multiexp to take "extra" bases, we could speed // this piece up a bit by combining the multiexps. - let l_j = best_multiexp(&p_prime[half..], &g_prime[0..half]); - let r_j = best_multiexp(&p_prime[0..half], &g_prime[half..]); + let l_j = engine.msm(&p_prime[half..], &g_prime[0..half]); + let r_j = engine.msm(&p_prime[0..half], &g_prime[half..]); let value_l_j = compute_inner_product(&p_prime[half..], &b[0..half]); let value_r_j = compute_inner_product(&p_prime[0..half], &b[half..]); let l_j_randomness = C::Scalar::random(&mut rng); let r_j_randomness = C::Scalar::random(&mut rng); - let l_j = l_j + &best_multiexp(&[value_l_j * &z, l_j_randomness], &[params.u, params.w]); - let r_j = r_j + &best_multiexp(&[value_r_j * &z, r_j_randomness], &[params.u, params.w]); + let l_j = l_j + &engine.msm(&[value_l_j * &z, l_j_randomness], &[params.u, params.w]); + let r_j = r_j + &engine.msm(&[value_r_j * &z, r_j_randomness], &[params.u, params.w]); let l_j = l_j.to_affine(); let r_j = r_j.to_affine(); diff --git a/halo2_proofs/src/poly/ipa/commitment/verifier.rs b/halo2_proofs/src/poly/ipa/commitment/verifier.rs index 0b60842899..d8a329b411 100644 --- a/halo2_proofs/src/poly/ipa/commitment/verifier.rs +++ b/halo2_proofs/src/poly/ipa/commitment/verifier.rs @@ -7,10 +7,7 @@ use group::{ use super::ParamsIPA; use crate::poly::ipa::commitment::{IPACommitmentScheme, ParamsVerifierIPA}; -use crate::{ - arithmetic::{best_multiexp, CurveAffine}, - poly::ipa::strategy::GuardIPA, -}; +use crate::{arithmetic::CurveAffine, poly::ipa::strategy::GuardIPA}; use crate::{ poly::{commitment::MSM, ipa::msm::MSMIPA, strategy::Guard, Error}, transcript::{EncodedChallenge, TranscriptRead}, diff --git a/halo2_proofs/src/poly/ipa/msm.rs b/halo2_proofs/src/poly/ipa/msm.rs index 3316e25337..33acd340b4 100644 --- a/halo2_proofs/src/poly/ipa/msm.rs +++ b/halo2_proofs/src/poly/ipa/msm.rs @@ -1,11 +1,12 @@ use super::commitment::{IPACommitmentScheme, ParamsIPA}; -use crate::arithmetic::{best_multiexp, parallelize, CurveAffine}; +use crate::arithmetic::{parallelize, CurveAffine}; use crate::poly::{ commitment::{CommitmentScheme, Params, MSM}, ipa::commitment::ParamsVerifierIPA, }; use ff::Field; use group::Group; +use halo2curves::zal::{H2cEngine, MsmAccel}; use std::collections::BTreeMap; /// A multiscalar multiplication in the polynomial commitment scheme @@ -170,7 +171,8 @@ impl<'a, C: CurveAffine> MSM for MSMIPA<'a, C> { assert_eq!(scalars.len(), len); - best_multiexp(&scalars, &bases) + let engine = H2cEngine::new(); + engine.msm(&scalars, &bases) } fn bases(&self) -> Vec { diff --git a/halo2_proofs/src/poly/ipa/strategy.rs b/halo2_proofs/src/poly/ipa/strategy.rs index c8d385f90c..8cea6f339f 100644 --- a/halo2_proofs/src/poly/ipa/strategy.rs +++ b/halo2_proofs/src/poly/ipa/strategy.rs @@ -6,7 +6,6 @@ use super::multiopen::VerifierIPA; use crate::poly::commitment::CommitmentScheme; use crate::transcript::TranscriptRead; use crate::{ - arithmetic::best_multiexp, plonk::Error, poly::{ commitment::MSM, @@ -16,6 +15,7 @@ use crate::{ }; use ff::Field; use group::Curve; +use halo2curves::zal::{H2cEngine, MsmAccel}; use halo2curves::CurveAffine; use rand_core::{OsRng, RngCore}; @@ -72,7 +72,8 @@ impl<'params, C: CurveAffine> GuardIPA<'params, C> { pub fn compute_g(&self) -> C { let s = compute_s(&self.u, C::Scalar::ONE); - best_multiexp(&s, &self.msm.params.g).to_affine() + let engine = H2cEngine::new(); + engine.msm(&s, &self.msm.params.g).to_affine() } } diff --git a/halo2_proofs/src/poly/kzg/commitment.rs b/halo2_proofs/src/poly/kzg/commitment.rs index 51f0c660d0..c8120309f2 100644 --- a/halo2_proofs/src/poly/kzg/commitment.rs +++ b/halo2_proofs/src/poly/kzg/commitment.rs @@ -1,6 +1,4 @@ -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::SerdeCurveAffine; use crate::poly::commitment::{Blind, CommitmentScheme, Params, ParamsProver, ParamsVerifier, MSM}; use crate::poly::{Coeff, LagrangeCoeff, Polynomial}; @@ -9,6 +7,7 @@ use crate::SerdeFormat; use ff::{Field, PrimeField}; use group::{prime::PrimeCurveAffine, Curve, Group}; use halo2curves::pairing::Engine; +use halo2curves::zal::{H2cEngine, MsmAccel}; use rand_core::{OsRng, RngCore}; use std::fmt::Debug; use std::marker::PhantomData; @@ -317,7 +316,8 @@ where let bases = &self.g_lagrange; let size = scalars.len(); assert!(bases.len() >= size); - best_multiexp(&scalars, &bases[0..size]) + let engine = H2cEngine::new(); + engine.msm(&scalars, &bases[0..size]) } /// Writes params to a buffer. @@ -361,7 +361,8 @@ where let bases = &self.g; let size = scalars.len(); assert!(bases.len() >= size); - best_multiexp(&scalars, &bases[0..size]) + let engine = H2cEngine::new(); + engine.msm(&scalars, &bases[0..size]) } fn get_g(&self) -> &[E::G1Affine] { @@ -371,7 +372,7 @@ where #[cfg(test)] mod test { - use crate::arithmetic::{best_fft, best_multiexp, parallelize, CurveAffine, CurveExt}; + use crate::arithmetic::{best_fft, parallelize, CurveAffine, CurveExt}; use crate::poly::commitment::ParamsProver; use crate::poly::commitment::{Blind, CommitmentScheme, Params, MSM}; use crate::poly::kzg::commitment::{ParamsKZG, ParamsVerifierKZG}; diff --git a/halo2_proofs/src/poly/kzg/msm.rs b/halo2_proofs/src/poly/kzg/msm.rs index 667a5c3614..f6115f5f3a 100644 --- a/halo2_proofs/src/poly/kzg/msm.rs +++ b/halo2_proofs/src/poly/kzg/msm.rs @@ -2,11 +2,14 @@ use std::fmt::Debug; use super::commitment::{KZGCommitmentScheme, ParamsKZG}; use crate::{ - arithmetic::{best_multiexp, parallelize, CurveAffine}, + arithmetic::{parallelize, CurveAffine}, poly::commitment::MSM, }; use group::{Curve, Group}; -use halo2curves::pairing::{Engine, MillerLoopResult, MultiMillerLoop}; +use halo2curves::{ + pairing::{Engine, MillerLoopResult, MultiMillerLoop}, + zal::{H2cEngine, MsmAccel}, +}; /// A multiscalar multiplication in the polynomial commitment scheme #[derive(Clone, Default, Debug)] @@ -66,7 +69,8 @@ impl MSM for MSMKZG { use group::prime::PrimeCurveAffine; let mut bases = vec![E::G1Affine::identity(); self.scalars.len()]; E::G1::batch_normalize(&self.bases, &mut bases); - best_multiexp(&self.scalars, &bases) + let engine = H2cEngine::new(); + engine.msm(&self.scalars, &bases) } fn bases(&self) -> Vec {