From fd7160f197ca11d05d9cf863af1cfd622ea0d32a Mon Sep 17 00:00:00 2001 From: Conghao Shen Date: Mon, 8 Aug 2022 14:30:47 -0700 Subject: [PATCH 01/14] wip: investigate --- manta-pay/src/crypto/ecc/arkworks.rs | 37 ++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/manta-pay/src/crypto/ecc/arkworks.rs b/manta-pay/src/crypto/ecc/arkworks.rs index 835d38e1f..ad9d57599 100644 --- a/manta-pay/src/crypto/ecc/arkworks.rs +++ b/manta-pay/src/crypto/ecc/arkworks.rs @@ -516,3 +516,40 @@ where ) } } + +#[cfg(test)] +mod test { + use super::*; + use crate::config::Bls12_381_Edwards; + use manta_crypto::{ + arkworks::r1cs_std::groups::curves::twisted_edwards::AffineVar, + constraint::measure::Measure, rand::OsRng, + }; + + /// Constraint Field Type + type ConstraintField = <::BaseField as Field>::BasePrimeField; + + /// Compiler Type + type Compiler = R1CS>; + + /// Scalar Field Element + pub type Scalar = Fp<::ScalarField>; + + #[test] + fn check_constraints() { + let mut cs = Compiler::::for_proofs(); + let group = Group(Bls12_381_Edwards::gen(&mut OsRng).into_affine()); + let group_var = + group.as_known::>>(&mut cs); + let scalar = Scalar::::gen(&mut OsRng); + let scalar_var = + scalar.as_known::>>(&mut cs); + let scalar_bits = scalar_var.0.to_bits_le().unwrap(); + println!("{:?}", scalar_bits.len()); + let bit_decomposition = cs.constraint_count(); + let _ = group_var.0.scalar_mul_le(scalar_bits.iter()); + let scalar_mul_constraints = cs.constraint_count() - bit_decomposition; + println!("num_constraints bit_decomposition: {:?}", bit_decomposition); + println!("num_constraints scalar_mul: {:?}", scalar_mul_constraints); + } +} From b25897e25fafb13761d833ba958170ae5fffa8ba Mon Sep 17 00:00:00 2001 From: Conghao Shen Date: Mon, 8 Aug 2022 15:37:33 -0700 Subject: [PATCH 02/14] feat: add fixed base scalar mul --- manta-crypto/src/algebra.rs | 17 +++++++ manta-pay/src/crypto/ecc/arkworks.rs | 73 +++++++++++++++++++++++----- workspace-hack/Cargo.toml | 11 +++-- 3 files changed, 83 insertions(+), 18 deletions(-) diff --git a/manta-crypto/src/algebra.rs b/manta-crypto/src/algebra.rs index f661f4aa5..dbd08b02f 100644 --- a/manta-crypto/src/algebra.rs +++ b/manta-crypto/src/algebra.rs @@ -48,6 +48,23 @@ pub trait Group { fn mul(&self, scalar: &Self::Scalar, compiler: &mut COM) -> Self; } +/// Fixed Base Scalar Multiplication using precomputed base points +pub trait FixedBaseScalarMul: Group { + /// Fixed Base Point + type Base; + + /// Multiply `precomputed_bases[0]` by `scalar` using precomputed base points, + /// where `precomputed_bases` are precomputed power-of-two multiples of the fixed base. + fn fixed_base_scalar_mul<'a, I>( + precomputed_bases: I, + scalar: &Self::Scalar, + compiler: &mut COM, + ) -> Self + where + I: IntoIterator, + Self::Base: 'a; +} + /// Diffie-Hellman Key Agreement Scheme #[cfg_attr( feature = "serde", diff --git a/manta-pay/src/crypto/ecc/arkworks.rs b/manta-pay/src/crypto/ecc/arkworks.rs index ad9d57599..e97bb7cc0 100644 --- a/manta-pay/src/crypto/ecc/arkworks.rs +++ b/manta-pay/src/crypto/ecc/arkworks.rs @@ -41,6 +41,7 @@ use manta_crypto::{ }; use manta_util::codec; +use manta_crypto::algebra::FixedBaseScalarMul; #[cfg(feature = "serde")] use { manta_crypto::arkworks::algebra::serialize_group_element, @@ -517,13 +518,47 @@ where } } +impl FixedBaseScalarMul> for GroupVar +where + C: ProjectiveCurve, + CV: CurveVar>, +{ + type Base = C; + + fn fixed_base_scalar_mul<'a, I>( + precomputed_bases: I, + scalar: &Self::Scalar, + compiler: &mut Compiler, + ) -> Self + where + I: IntoIterator, + Self::Base: 'a, + { + let _ = compiler; + let mut result = CV::zero(); + let scalar_bits = scalar + .0 + .to_bits_le() + .expect("Bit decomposition is not allowed to fail."); + for (bit, base) in scalar_bits.into_iter().zip(precomputed_bases.into_iter()) { + result = bit + .select(&(result.clone() + *base), &result) + .expect("Conditional select is not allowed to fail. "); + } + Self::new(result) + } +} + #[cfg(test)] mod test { use super::*; use crate::config::Bls12_381_Edwards; use manta_crypto::{ - arkworks::r1cs_std::groups::curves::twisted_edwards::AffineVar, - constraint::measure::Measure, rand::OsRng, + algebra::Group, + arkworks::{ec::group::Group as _, r1cs_std::groups::curves::twisted_edwards::AffineVar}, + constraint::measure::Measure, + eclair::bool::AssertEq, + rand::OsRng, }; /// Constraint Field Type @@ -536,20 +571,32 @@ mod test { pub type Scalar = Fp<::ScalarField>; #[test] - fn check_constraints() { + fn fixed_base_mul() { let mut cs = Compiler::::for_proofs(); - let group = Group(Bls12_381_Edwards::gen(&mut OsRng).into_affine()); - let group_var = - group.as_known::>>(&mut cs); let scalar = Scalar::::gen(&mut OsRng); + let base = Bls12_381_Edwards::prime_subgroup_generator(); + let mut curr = base; + let mut precomputed_table = Vec::new(); + for _ in 0..256 { + precomputed_table.push(curr); + curr = curr + curr; + } + let base_var = Group(base.into_affine()) + .as_known::>>(&mut cs); let scalar_var = scalar.as_known::>>(&mut cs); - let scalar_bits = scalar_var.0.to_bits_le().unwrap(); - println!("{:?}", scalar_bits.len()); - let bit_decomposition = cs.constraint_count(); - let _ = group_var.0.scalar_mul_le(scalar_bits.iter()); - let scalar_mul_constraints = cs.constraint_count() - bit_decomposition; - println!("num_constraints bit_decomposition: {:?}", bit_decomposition); - println!("num_constraints scalar_mul: {:?}", scalar_mul_constraints); + + let ctr1 = cs.constraint_count(); + let expected = base_var.mul(&scalar_var, &mut cs); + let ctr2 = cs.constraint_count(); + let actual = + GroupVar::fixed_base_scalar_mul(precomputed_table.iter(), &scalar_var, &mut cs); + let ctr3 = cs.constraint_count(); + + cs.assert_eq(&expected, &actual); + assert!(cs.is_satisfied()); + + println!("variable base mul constraint: {:?}", ctr2 - ctr1); + println!("fixed base mul constraint: {:?}", ctr3 - ctr2); } } diff --git a/workspace-hack/Cargo.toml b/workspace-hack/Cargo.toml index c76967708..f552fff37 100644 --- a/workspace-hack/Cargo.toml +++ b/workspace-hack/Cargo.toml @@ -14,13 +14,12 @@ publish = false ### BEGIN HAKARI SECTION [dependencies] -aes-gcm = { version = "0.9.4", features = ["aes", "alloc"] } anyhow = { version = "1.0.59", features = ["std"] } ark-serialize = { version = "0.3.0", default-features = false, features = ["ark-serialize-derive", "derive"] } bitflags = { version = "1.3.2" } blake3 = { version = "1.3.1", default-features = false, features = ["digest", "std"] } byteorder = { version = "1.4.3", features = ["std"] } -crypto-common = { version = "0.1.6", default-features = false, features = ["std"] } +crypto-common = { version = "0.1.6", default-features = false, features = ["getrandom", "rand_core", "std"] } digest-93f6ce9d446188ac = { package = "digest", version = "0.10.3", features = ["alloc", "block-buffer", "core-api", "mac", "std", "subtle"] } digest-274715c4dabd11b0 = { package = "digest", version = "0.9.0", default-features = false, features = ["alloc", "std"] } futures = { version = "0.3.21", features = ["alloc", "async-await", "executor", "futures-executor", "std"] } @@ -40,7 +39,7 @@ ppv-lite86 = { version = "0.2.16", default-features = false, features = ["simd", rand = { version = "0.8.5", features = ["alloc", "getrandom", "libc", "rand_chacha", "std", "std_rng"] } rand_chacha = { version = "0.3.1", default-features = false, features = ["std"] } rand_core = { version = "0.6.3", default-features = false, features = ["alloc", "getrandom", "std"] } -serde = { version = "1.0.141", features = ["alloc", "derive", "serde_derive", "std"] } +serde = { version = "1.0.142", features = ["alloc", "derive", "serde_derive", "std"] } serde_json = { version = "1.0.82", features = ["alloc", "std"] } sha2 = { version = "0.9.9", features = ["std"] } standback = { version = "0.2.17", default-features = false, features = ["std"] } @@ -54,12 +53,14 @@ zeroize = { version = "1.5.7", default-features = false, features = ["alloc", "z anyhow = { version = "1.0.59", features = ["std"] } blake3 = { version = "1.3.1", default-features = false, features = ["digest", "std"] } cc = { version = "1.0.73", default-features = false, features = ["jobserver", "parallel"] } -crypto-common = { version = "0.1.6", default-features = false, features = ["std"] } +crypto-common = { version = "0.1.6", default-features = false, features = ["getrandom", "rand_core", "std"] } digest-93f6ce9d446188ac = { package = "digest", version = "0.10.3", features = ["alloc", "block-buffer", "core-api", "mac", "std", "subtle"] } generic-array = { version = "0.14.6", default-features = false, features = ["more_lengths"] } +getrandom = { version = "0.2.7", default-features = false, features = ["js", "js-sys", "std", "wasm-bindgen"] } log = { version = "0.4.17", default-features = false, features = ["kv_unstable", "kv_unstable_std", "std", "value-bag"] } num-traits = { version = "0.2.15", features = ["i128", "libm", "std"] } -serde = { version = "1.0.141", features = ["alloc", "derive", "serde_derive", "std"] } +rand_core = { version = "0.6.3", default-features = false, features = ["alloc", "getrandom", "std"] } +serde = { version = "1.0.142", features = ["alloc", "derive", "serde_derive", "std"] } standback = { version = "0.2.17", default-features = false, features = ["std"] } subtle = { version = "2.4.1", default-features = false, features = ["i128"] } syn = { version = "1.0.98", features = ["clone-impls", "derive", "extra-traits", "fold", "full", "parsing", "printing", "proc-macro", "quote", "visit", "visit-mut"] } From a1eeb7a59b42a69771d7ee75eb66e14915a47e24 Mon Sep 17 00:00:00 2001 From: Conghao Shen Date: Tue, 9 Aug 2022 10:09:07 -0700 Subject: [PATCH 03/14] fix: nit --- manta-pay/src/crypto/ecc/arkworks.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/manta-pay/src/crypto/ecc/arkworks.rs b/manta-pay/src/crypto/ecc/arkworks.rs index e97bb7cc0..68c0e5d46 100644 --- a/manta-pay/src/crypto/ecc/arkworks.rs +++ b/manta-pay/src/crypto/ecc/arkworks.rs @@ -554,11 +554,8 @@ mod test { use super::*; use crate::config::Bls12_381_Edwards; use manta_crypto::{ - algebra::Group, - arkworks::{ec::group::Group as _, r1cs_std::groups::curves::twisted_edwards::AffineVar}, - constraint::measure::Measure, - eclair::bool::AssertEq, - rand::OsRng, + algebra::Group, arkworks::r1cs_std::groups::curves::twisted_edwards::AffineVar, + constraint::measure::Measure, eclair::bool::AssertEq, rand::OsRng, }; /// Constraint Field Type @@ -596,7 +593,10 @@ mod test { cs.assert_eq(&expected, &actual); assert!(cs.is_satisfied()); - println!("variable base mul constraint: {:?}", ctr2 - ctr1); - println!("fixed base mul constraint: {:?}", ctr3 - ctr2); + #[cfg(feature = "std")] + { + println!("variable base mul constraint: {:?}", ctr2 - ctr1); + println!("fixed base mul constraint: {:?}", ctr3 - ctr2); + } } } From fa655e9ef6bc7a79779e7b7fae73b71465b8c11f Mon Sep 17 00:00:00 2001 From: Conghao Shen Date: Tue, 9 Aug 2022 10:10:46 -0700 Subject: [PATCH 04/14] feat: update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 214f09119..34cbc2318 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] ### Added - [\#172](https://github.com/Manta-Network/manta-rs/pull/172) Add abstract Phase 2 for Groth16 trusted setup +- [\#196](https://github.com/Manta-Network/manta-rs/pull/172) Add fixed base scalar multiplication using precomputed bases ### Changed - [\#180](https://github.com/Manta-Network/manta-rs/pull/180) Start moving to new `arkworks` backend for `manta-crypto` From b32a13aa88389a1e51c0759a57f07c1e07f3b250 Mon Sep 17 00:00:00 2001 From: Conghao Shen Date: Tue, 9 Aug 2022 10:22:35 -0700 Subject: [PATCH 05/14] feat: simplify lifetime generic --- manta-crypto/src/algebra.rs | 8 ++++---- manta-crypto/src/lib.rs | 1 + manta-pay/src/crypto/ecc/arkworks.rs | 22 +++++++++------------- manta-pay/src/lib.rs | 1 + 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/manta-crypto/src/algebra.rs b/manta-crypto/src/algebra.rs index dbd08b02f..b1a944ff2 100644 --- a/manta-crypto/src/algebra.rs +++ b/manta-crypto/src/algebra.rs @@ -21,7 +21,7 @@ use crate::{ key, rand::{RngCore, Sample}, }; -use core::marker::PhantomData; +use core::{borrow::Borrow, marker::PhantomData}; use manta_util::codec::{Decode, DecodeError, Encode, Read, Write}; #[cfg(feature = "serde")] @@ -55,14 +55,14 @@ pub trait FixedBaseScalarMul: Group { /// Multiply `precomputed_bases[0]` by `scalar` using precomputed base points, /// where `precomputed_bases` are precomputed power-of-two multiples of the fixed base. - fn fixed_base_scalar_mul<'a, I>( + fn fixed_base_scalar_mul( precomputed_bases: I, scalar: &Self::Scalar, compiler: &mut COM, ) -> Self where - I: IntoIterator, - Self::Base: 'a; + I: IntoIterator, + T: Borrow; } /// Diffie-Hellman Key Agreement Scheme diff --git a/manta-crypto/src/lib.rs b/manta-crypto/src/lib.rs index 2b617b711..2299191c9 100644 --- a/manta-crypto/src/lib.rs +++ b/manta-crypto/src/lib.rs @@ -22,6 +22,7 @@ #![forbid(missing_docs)] extern crate alloc; +extern crate core; pub mod accumulator; pub mod algebra; diff --git a/manta-pay/src/crypto/ecc/arkworks.rs b/manta-pay/src/crypto/ecc/arkworks.rs index 68c0e5d46..d88a8364f 100644 --- a/manta-pay/src/crypto/ecc/arkworks.rs +++ b/manta-pay/src/crypto/ecc/arkworks.rs @@ -18,7 +18,7 @@ use crate::crypto::constraint::arkworks::{self, empty, full, Boolean, Fp, FpVar, R1CS}; use alloc::vec::Vec; -use core::marker::PhantomData; +use core::{borrow::Borrow, marker::PhantomData}; use manta_crypto::{ algebra, arkworks::{ @@ -525,14 +525,14 @@ where { type Base = C; - fn fixed_base_scalar_mul<'a, I>( + fn fixed_base_scalar_mul( precomputed_bases: I, scalar: &Self::Scalar, compiler: &mut Compiler, ) -> Self where - I: IntoIterator, - Self::Base: 'a, + I: IntoIterator, + T: Borrow, { let _ = compiler; let mut result = CV::zero(); @@ -542,7 +542,7 @@ where .expect("Bit decomposition is not allowed to fail."); for (bit, base) in scalar_bits.into_iter().zip(precomputed_bases.into_iter()) { result = bit - .select(&(result.clone() + *base), &result) + .select(&(result.clone() + *base.borrow()), &result) .expect("Conditional select is not allowed to fail. "); } Self::new(result) @@ -572,12 +572,9 @@ mod test { let mut cs = Compiler::::for_proofs(); let scalar = Scalar::::gen(&mut OsRng); let base = Bls12_381_Edwards::prime_subgroup_generator(); - let mut curr = base; - let mut precomputed_table = Vec::new(); - for _ in 0..256 { - precomputed_table.push(curr); - curr = curr + curr; - } + let precomputed_table = + core::iter::successors(Some(base), |base| Some(*base + *base)).take(256); + let base_var = Group(base.into_affine()) .as_known::>>(&mut cs); let scalar_var = @@ -586,8 +583,7 @@ mod test { let ctr1 = cs.constraint_count(); let expected = base_var.mul(&scalar_var, &mut cs); let ctr2 = cs.constraint_count(); - let actual = - GroupVar::fixed_base_scalar_mul(precomputed_table.iter(), &scalar_var, &mut cs); + let actual = GroupVar::fixed_base_scalar_mul(precomputed_table, &scalar_var, &mut cs); let ctr3 = cs.constraint_count(); cs.assert_eq(&expected, &actual); diff --git a/manta-pay/src/lib.rs b/manta-pay/src/lib.rs index 273691e3e..564d4eef8 100644 --- a/manta-pay/src/lib.rs +++ b/manta-pay/src/lib.rs @@ -22,6 +22,7 @@ #![forbid(missing_docs)] extern crate alloc; +extern crate core; pub mod crypto; pub mod util; From cf2c9234378b95b732861496179be89d2837e4c4 Mon Sep 17 00:00:00 2001 From: Conghao Shen Date: Tue, 9 Aug 2022 11:06:18 -0700 Subject: [PATCH 06/14] feat: address review comments --- manta-crypto/src/arkworks/algebra.rs | 21 +++++++++++++++++++++ manta-pay/src/crypto/ecc/arkworks.rs | 19 ++++++++++--------- manta-pay/src/lib.rs | 1 - 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/manta-crypto/src/arkworks/algebra.rs b/manta-crypto/src/arkworks/algebra.rs index 98dc69831..73e33aeda 100644 --- a/manta-crypto/src/arkworks/algebra.rs +++ b/manta-crypto/src/arkworks/algebra.rs @@ -104,3 +104,24 @@ where Self(scalar, PhantomData) } } + +/// Returns the power-of-two table of size `powers` such that entry at index `i` is `base * 2^i`. +#[inline] +pub fn precomputed_bases_custom(base: C, powers: usize) -> impl Iterator +where + C: ProjectiveCurve, +{ + core::iter::successors(Some(base), |base| Some(*base + *base)).take(powers) +} + +/// Returns the power-of-two table of whose size is modulus bits of [`ConstraintField`] such that entry at index `i` is [`C::prime_subgroup_generator()`] `* 2^i`. +#[inline] +pub fn precomputed_bases() -> impl Iterator +where + C: ProjectiveCurve, +{ + precomputed_bases_custom( + C::prime_subgroup_generator(), + as PrimeField>::size_in_bits(), + ) +} diff --git a/manta-pay/src/crypto/ecc/arkworks.rs b/manta-pay/src/crypto/ecc/arkworks.rs index d88a8364f..17e2219bd 100644 --- a/manta-pay/src/crypto/ecc/arkworks.rs +++ b/manta-pay/src/crypto/ecc/arkworks.rs @@ -554,8 +554,13 @@ mod test { use super::*; use crate::config::Bls12_381_Edwards; use manta_crypto::{ - algebra::Group, arkworks::r1cs_std::groups::curves::twisted_edwards::AffineVar, - constraint::measure::Measure, eclair::bool::AssertEq, rand::OsRng, + algebra::Group, + arkworks::{ + algebra::precomputed_bases, r1cs_std::groups::curves::twisted_edwards::AffineVar, + }, + constraint::measure::Measure, + eclair::bool::AssertEq, + rand::OsRng, }; /// Constraint Field Type @@ -572,8 +577,7 @@ mod test { let mut cs = Compiler::::for_proofs(); let scalar = Scalar::::gen(&mut OsRng); let base = Bls12_381_Edwards::prime_subgroup_generator(); - let precomputed_table = - core::iter::successors(Some(base), |base| Some(*base + *base)).take(256); + let precomputed_table = precomputed_bases::(); let base_var = Group(base.into_affine()) .as_known::>>(&mut cs); @@ -589,10 +593,7 @@ mod test { cs.assert_eq(&expected, &actual); assert!(cs.is_satisfied()); - #[cfg(feature = "std")] - { - println!("variable base mul constraint: {:?}", ctr2 - ctr1); - println!("fixed base mul constraint: {:?}", ctr3 - ctr2); - } + println!("variable base mul constraint: {:?}", ctr2 - ctr1); + println!("fixed base mul constraint: {:?}", ctr3 - ctr2); } } diff --git a/manta-pay/src/lib.rs b/manta-pay/src/lib.rs index 564d4eef8..273691e3e 100644 --- a/manta-pay/src/lib.rs +++ b/manta-pay/src/lib.rs @@ -22,7 +22,6 @@ #![forbid(missing_docs)] extern crate alloc; -extern crate core; pub mod crypto; pub mod util; From 7057043e60151263bb806c5d9b2155ba812d8210 Mon Sep 17 00:00:00 2001 From: Conghao Shen Date: Tue, 9 Aug 2022 11:07:03 -0700 Subject: [PATCH 07/14] feat: address review comments 2 --- manta-crypto/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/manta-crypto/src/lib.rs b/manta-crypto/src/lib.rs index 2299191c9..2b617b711 100644 --- a/manta-crypto/src/lib.rs +++ b/manta-crypto/src/lib.rs @@ -22,7 +22,6 @@ #![forbid(missing_docs)] extern crate alloc; -extern crate core; pub mod accumulator; pub mod algebra; From 59c44ea62069db241488b4669efd2302e0206162 Mon Sep 17 00:00:00 2001 From: Conghao Shen Date: Tue, 9 Aug 2022 11:12:43 -0700 Subject: [PATCH 08/14] fix: doc --- manta-crypto/src/arkworks/algebra.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manta-crypto/src/arkworks/algebra.rs b/manta-crypto/src/arkworks/algebra.rs index 73e33aeda..ae0649975 100644 --- a/manta-crypto/src/arkworks/algebra.rs +++ b/manta-crypto/src/arkworks/algebra.rs @@ -114,7 +114,7 @@ where core::iter::successors(Some(base), |base| Some(*base + *base)).take(powers) } -/// Returns the power-of-two table of whose size is modulus bits of [`ConstraintField`] such that entry at index `i` is [`C::prime_subgroup_generator()`] `* 2^i`. +/// Returns the power-of-two table of whose size is modulus bits of the constraint field of `C` such that entry at index `i` is `C::prime_subgroup_generator() * 2^i`. #[inline] pub fn precomputed_bases() -> impl Iterator where From d4103c13c1a2aad1636414576e3f4dcb034bd5d1 Mon Sep 17 00:00:00 2001 From: Conghao Shen Date: Wed, 10 Aug 2022 16:21:28 -0700 Subject: [PATCH 09/14] feat: address review comments --- manta-crypto/src/algebra.rs | 41 +++++++++++++++++++++++++--- manta-crypto/src/arkworks/algebra.rs | 19 ++----------- manta-pay/src/crypto/ecc/arkworks.rs | 34 ++++++++--------------- 3 files changed, 52 insertions(+), 42 deletions(-) diff --git a/manta-crypto/src/algebra.rs b/manta-crypto/src/algebra.rs index b1a944ff2..1b130cd4f 100644 --- a/manta-crypto/src/algebra.rs +++ b/manta-crypto/src/algebra.rs @@ -22,7 +22,10 @@ use crate::{ rand::{RngCore, Sample}, }; use core::{borrow::Borrow, marker::PhantomData}; -use manta_util::codec::{Decode, DecodeError, Encode, Read, Write}; +use manta_util::{ + codec::{Decode, DecodeError, Encode, Read, Write}, + into_array_unchecked, +}; #[cfg(feature = "serde")] use manta_util::serde::{Deserialize, Serialize}; @@ -55,14 +58,44 @@ pub trait FixedBaseScalarMul: Group { /// Multiply `precomputed_bases[0]` by `scalar` using precomputed base points, /// where `precomputed_bases` are precomputed power-of-two multiples of the fixed base. - fn fixed_base_scalar_mul( + fn fixed_base_scalar_mul( precomputed_bases: I, scalar: &Self::Scalar, compiler: &mut COM, ) -> Self where - I: IntoIterator, - T: Borrow; + I: IntoIterator, + I::Item: Borrow; +} + +/// Precomputed power-of-two Base for fixed-base scalar multiplication. Entry at index `i` is `base * 2^i`. +pub struct PrecomputedBaseTable { + table: [G; N], +} + +impl IntoIterator for PrecomputedBaseTable { + type Item = G; + type IntoIter = core::array::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.table.into_iter() + } +} + +impl PrecomputedBaseTable { + #[inline] + /// Builds a new [`PrecomputedBaseTable`] from a given `base`, such that `table[i] = base * 2^i`. + pub fn from_base(base: G, compiler: &mut COM) -> Self + where + G: Group, + { + let table = into_array_unchecked( + core::iter::successors(Some(base), |base| Some(base.add(base, compiler))) + .take(N) + .collect::>(), + ); + Self { table } + } } /// Diffie-Hellman Key Agreement Scheme diff --git a/manta-crypto/src/arkworks/algebra.rs b/manta-crypto/src/arkworks/algebra.rs index ae0649975..a0e8caf43 100644 --- a/manta-crypto/src/arkworks/algebra.rs +++ b/manta-crypto/src/arkworks/algebra.rs @@ -105,23 +105,10 @@ where } } -/// Returns the power-of-two table of size `powers` such that entry at index `i` is `base * 2^i`. -#[inline] -pub fn precomputed_bases_custom(base: C, powers: usize) -> impl Iterator -where - C: ProjectiveCurve, -{ - core::iter::successors(Some(base), |base| Some(*base + *base)).take(powers) -} - -/// Returns the power-of-two table of whose size is modulus bits of the constraint field of `C` such that entry at index `i` is `C::prime_subgroup_generator() * 2^i`. -#[inline] -pub fn precomputed_bases() -> impl Iterator +/// Returns the modulus bits of scalar field of a given curve `C`. +pub const fn scalar_bits() -> usize where C: ProjectiveCurve, { - precomputed_bases_custom( - C::prime_subgroup_generator(), - as PrimeField>::size_in_bits(), - ) + <::ScalarField as PrimeField>::Params::MODULUS_BITS as usize } diff --git a/manta-pay/src/crypto/ecc/arkworks.rs b/manta-pay/src/crypto/ecc/arkworks.rs index 17e2219bd..32082a405 100644 --- a/manta-pay/src/crypto/ecc/arkworks.rs +++ b/manta-pay/src/crypto/ecc/arkworks.rs @@ -523,16 +523,16 @@ where C: ProjectiveCurve, CV: CurveVar>, { - type Base = C; + type Base = Group; - fn fixed_base_scalar_mul( + fn fixed_base_scalar_mul( precomputed_bases: I, scalar: &Self::Scalar, compiler: &mut Compiler, ) -> Self where - I: IntoIterator, - T: Borrow, + I: IntoIterator, + I::Item: Borrow, { let _ = compiler; let mut result = CV::zero(); @@ -542,7 +542,7 @@ where .expect("Bit decomposition is not allowed to fail."); for (bit, base) in scalar_bits.into_iter().zip(precomputed_bases.into_iter()) { result = bit - .select(&(result.clone() + *base.borrow()), &result) + .select(&(result.clone() + base.borrow().0.into()), &result) .expect("Conditional select is not allowed to fail. "); } Self::new(result) @@ -554,33 +554,23 @@ mod test { use super::*; use crate::config::Bls12_381_Edwards; use manta_crypto::{ - algebra::Group, - arkworks::{ - algebra::precomputed_bases, r1cs_std::groups::curves::twisted_edwards::AffineVar, - }, + algebra::{Group as _, PrecomputedBaseTable}, + arkworks::{algebra::scalar_bits, r1cs_std::groups::curves::twisted_edwards::AffineVar}, constraint::measure::Measure, eclair::bool::AssertEq, rand::OsRng, }; - /// Constraint Field Type - type ConstraintField = <::BaseField as Field>::BasePrimeField; - - /// Compiler Type - type Compiler = R1CS>; - - /// Scalar Field Element - pub type Scalar = Fp<::ScalarField>; - #[test] fn fixed_base_mul() { let mut cs = Compiler::::for_proofs(); let scalar = Scalar::::gen(&mut OsRng); - let base = Bls12_381_Edwards::prime_subgroup_generator(); - let precomputed_table = precomputed_bases::(); + let base = Group::::sample((), &mut OsRng); + const SCALAR_BITS: usize = scalar_bits::(); + let precomputed_table = PrecomputedBaseTable::<_, SCALAR_BITS>::from_base(base, &mut ()); - let base_var = Group(base.into_affine()) - .as_known::>>(&mut cs); + let base_var = + base.as_known::>>(&mut cs); let scalar_var = scalar.as_known::>>(&mut cs); From c605395d52b04a4eee469327cb7fdbae490735a4 Mon Sep 17 00:00:00 2001 From: Conghao Shen Date: Wed, 10 Aug 2022 16:30:54 -0700 Subject: [PATCH 10/14] fix: nit --- manta-crypto/src/algebra.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/manta-crypto/src/algebra.rs b/manta-crypto/src/algebra.rs index 1b130cd4f..d178f3223 100644 --- a/manta-crypto/src/algebra.rs +++ b/manta-crypto/src/algebra.rs @@ -21,6 +21,7 @@ use crate::{ key, rand::{RngCore, Sample}, }; +use alloc::vec::Vec; use core::{borrow::Borrow, marker::PhantomData}; use manta_util::{ codec::{Decode, DecodeError, Encode, Read, Write}, From 871e76acda421250ed1bf60f0ff227a36569c62d Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Tue, 23 Aug 2022 12:23:21 -0400 Subject: [PATCH 11/14] chore: match new ScalarVar --- manta-crypto/src/algebra.rs | 25 +++++++++++++------------ manta-pay/src/crypto/ecc/arkworks.rs | 15 ++++++--------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/manta-crypto/src/algebra.rs b/manta-crypto/src/algebra.rs index 1605e79b0..fc4d6bc0d 100644 --- a/manta-crypto/src/algebra.rs +++ b/manta-crypto/src/algebra.rs @@ -70,15 +70,15 @@ where } /// Fixed Base Scalar Multiplication using precomputed base points -pub trait FixedBaseScalarMul: Group { +pub trait FixedBaseScalarMul: Group { /// Fixed Base Point type Base; - /// Multiply `precomputed_bases[0]` by `scalar` using precomputed base points, - /// where `precomputed_bases` are precomputed power-of-two multiples of the fixed base. + /// Multiplies `precomputed_bases[0]` by `scalar` using precomputed base points, + /// where `precomputed_bases` are precomputed power-of-two multiples of the fixed base. fn fixed_base_scalar_mul( precomputed_bases: I, - scalar: &Self::Scalar, + scalar: &S, compiler: &mut COM, ) -> Self where @@ -86,7 +86,7 @@ pub trait FixedBaseScalarMul: Group { I::Item: Borrow; } -/// Precomputed power-of-two Base for fixed-base scalar multiplication. Entry at index `i` is `base * 2^i`. +/// Precomputed power-of-two Bases for fixed-base scalar multiplication with entry at index `i` as `base * 2^i` pub struct PrecomputedBaseTable { table: [G; N], } @@ -101,18 +101,19 @@ impl IntoIterator for PrecomputedBaseTable { } impl PrecomputedBaseTable { - #[inline] /// Builds a new [`PrecomputedBaseTable`] from a given `base`, such that `table[i] = base * 2^i`. + #[inline] pub fn from_base(base: G, compiler: &mut COM) -> Self where G: Group, { - let table = into_array_unchecked( - core::iter::successors(Some(base), |base| Some(base.add(base, compiler))) - .take(N) - .collect::>(), - ); - Self { table } + Self { + table: into_array_unchecked( + core::iter::successors(Some(base), |base| Some(base.add(base, compiler))) + .take(N) + .collect::>(), + ), + } } } diff --git a/manta-pay/src/crypto/ecc/arkworks.rs b/manta-pay/src/crypto/ecc/arkworks.rs index 2f1e8a856..8e9e4661d 100644 --- a/manta-pay/src/crypto/ecc/arkworks.rs +++ b/manta-pay/src/crypto/ecc/arkworks.rs @@ -21,6 +21,7 @@ use alloc::vec::Vec; use core::{borrow::Borrow, marker::PhantomData}; use manta_crypto::{ algebra, + algebra::FixedBaseScalarMul, arkworks::{ algebra::{affine_point_as_bytes, modulus_is_smaller}, ec::{AffineCurve, ProjectiveCurve}, @@ -40,7 +41,6 @@ use manta_crypto::{ }; use manta_util::{codec, AsBytes}; -use manta_crypto::algebra::FixedBaseScalarMul; #[cfg(feature = "serde")] use { manta_crypto::arkworks::algebra::serialize_group_element, @@ -534,16 +534,17 @@ where } } -impl FixedBaseScalarMul> for GroupVar +impl FixedBaseScalarMul, Compiler> for GroupVar where C: ProjectiveCurve, CV: CurveVar>, { type Base = Group; + #[inline] fn fixed_base_scalar_mul( precomputed_bases: I, - scalar: &Self::Scalar, + scalar: &ScalarVar, compiler: &mut Compiler, ) -> Self where @@ -570,7 +571,7 @@ mod test { use super::*; use crate::config::Bls12_381_Edwards; use manta_crypto::{ - algebra::{Group as _, PrecomputedBaseTable}, + algebra::{PrecomputedBaseTable, ScalarMul}, arkworks::{algebra::scalar_bits, r1cs_std::groups::curves::twisted_edwards::AffineVar}, constraint::measure::Measure, eclair::bool::AssertEq, @@ -584,21 +585,17 @@ mod test { let base = Group::::sample((), &mut OsRng); const SCALAR_BITS: usize = scalar_bits::(); let precomputed_table = PrecomputedBaseTable::<_, SCALAR_BITS>::from_base(base, &mut ()); - let base_var = base.as_known::>>(&mut cs); let scalar_var = scalar.as_known::>>(&mut cs); - let ctr1 = cs.constraint_count(); - let expected = base_var.mul(&scalar_var, &mut cs); + let expected = base_var.scalar_mul(&scalar_var, &mut cs); let ctr2 = cs.constraint_count(); let actual = GroupVar::fixed_base_scalar_mul(precomputed_table, &scalar_var, &mut cs); let ctr3 = cs.constraint_count(); - cs.assert_eq(&expected, &actual); assert!(cs.is_satisfied()); - println!("variable base mul constraint: {:?}", ctr2 - ctr1); println!("fixed base mul constraint: {:?}", ctr3 - ctr2); } From 570d495cadd2137023e4340b47d7668b4525ec00 Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Tue, 23 Aug 2022 12:32:16 -0400 Subject: [PATCH 12/14] nit --- manta-crypto/src/algebra.rs | 6 +----- workspace-hack/Cargo.toml | 6 ++---- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/manta-crypto/src/algebra.rs b/manta-crypto/src/algebra.rs index fc4d6bc0d..5c6227b91 100644 --- a/manta-crypto/src/algebra.rs +++ b/manta-crypto/src/algebra.rs @@ -76,11 +76,7 @@ pub trait FixedBaseScalarMul: Group { /// Multiplies `precomputed_bases[0]` by `scalar` using precomputed base points, /// where `precomputed_bases` are precomputed power-of-two multiples of the fixed base. - fn fixed_base_scalar_mul( - precomputed_bases: I, - scalar: &S, - compiler: &mut COM, - ) -> Self + fn fixed_base_scalar_mul(precomputed_bases: I, scalar: &S, compiler: &mut COM) -> Self where I: IntoIterator, I::Item: Borrow; diff --git a/workspace-hack/Cargo.toml b/workspace-hack/Cargo.toml index be99be6fd..3c92e6620 100644 --- a/workspace-hack/Cargo.toml +++ b/workspace-hack/Cargo.toml @@ -21,7 +21,7 @@ bitflags = { version = "1.3.2" } blake3 = { version = "1.3.1", default-features = false, features = ["digest", "std"] } block-buffer = { version = "0.9.0", default-features = false, features = ["block-padding"] } byteorder = { version = "1.4.3", features = ["std"] } -crypto-common = { version = "0.1.6", default-features = false, features = ["getrandom", "rand_core", "std"] } +crypto-common = { version = "0.1.6", default-features = false, features = ["std"] } digest-93f6ce9d446188ac = { package = "digest", version = "0.10.3", features = ["alloc", "block-buffer", "core-api", "mac", "std", "subtle"] } digest-274715c4dabd11b0 = { package = "digest", version = "0.9.0", default-features = false, features = ["alloc", "std"] } futures = { version = "0.3.23", features = ["alloc", "async-await", "executor", "futures-executor", "std"] } @@ -56,13 +56,11 @@ zeroize = { version = "1.5.7", default-features = false, features = ["alloc", "z anyhow = { version = "1.0.62", features = ["std"] } blake3 = { version = "1.3.1", default-features = false, features = ["digest", "std"] } cc = { version = "1.0.73", default-features = false, features = ["jobserver", "parallel"] } -crypto-common = { version = "0.1.6", default-features = false, features = ["getrandom", "rand_core", "std"] } +crypto-common = { version = "0.1.6", default-features = false, features = ["std"] } digest-93f6ce9d446188ac = { package = "digest", version = "0.10.3", features = ["alloc", "block-buffer", "core-api", "mac", "std", "subtle"] } generic-array = { version = "0.14.6", default-features = false, features = ["more_lengths"] } -getrandom = { version = "0.2.7", default-features = false, features = ["js", "js-sys", "std", "wasm-bindgen"] } log = { version = "0.4.17", default-features = false, features = ["kv_unstable", "kv_unstable_std", "std", "value-bag"] } num-traits = { version = "0.2.15", features = ["i128", "libm", "std"] } -rand_core = { version = "0.6.3", default-features = false, features = ["alloc", "getrandom", "std"] } serde = { version = "1.0.144", features = ["alloc", "derive", "serde_derive", "std"] } standback = { version = "0.2.17", default-features = false, features = ["std"] } subtle = { version = "2.4.1", default-features = false, features = ["i128"] } From 380b1d6356d5526dead82c82fd470d119d3fec1e Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Tue, 23 Aug 2022 12:35:32 -0400 Subject: [PATCH 13/14] nit --- manta-pay/src/crypto/ecc/arkworks.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/manta-pay/src/crypto/ecc/arkworks.rs b/manta-pay/src/crypto/ecc/arkworks.rs index 8e9e4661d..64770e6b0 100644 --- a/manta-pay/src/crypto/ecc/arkworks.rs +++ b/manta-pay/src/crypto/ecc/arkworks.rs @@ -578,8 +578,9 @@ mod test { rand::OsRng, }; + /// Checks if the fixed base multiplcation is correct. #[test] - fn fixed_base_mul() { + fn fixed_base_mul_is_correct() { let mut cs = Compiler::::for_proofs(); let scalar = Scalar::::gen(&mut OsRng); let base = Group::::sample((), &mut OsRng); From 40926122b4d0522e99d807a7459cdb5260c136c3 Mon Sep 17 00:00:00 2001 From: Boyuan Feng Date: Tue, 23 Aug 2022 12:35:53 -0400 Subject: [PATCH 14/14] nit --- manta-pay/src/crypto/ecc/arkworks.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/manta-pay/src/crypto/ecc/arkworks.rs b/manta-pay/src/crypto/ecc/arkworks.rs index 64770e6b0..972e65cee 100644 --- a/manta-pay/src/crypto/ecc/arkworks.rs +++ b/manta-pay/src/crypto/ecc/arkworks.rs @@ -566,6 +566,7 @@ where } } +/// Testing Suite #[cfg(test)] mod test { use super::*;