From 889180bb03c7eedc99928e6d2f9e2be83a0369ad Mon Sep 17 00:00:00 2001 From: zhenfei Date: Sat, 14 May 2022 00:36:01 -0400 Subject: [PATCH] impl H2G for TE curves (#65) * impl H2G for TE curves Co-authored-by: Alex Xiong --- CHANGELOG.md | 1 + primitives/Cargo.toml | 7 +- primitives/src/hash_to_group/mod.rs | 78 ++---------------- .../src/hash_to_group/short_weierstrass.rs | 81 +++++++++++++++++++ .../src/hash_to_group/twisted_edwards.rs | 81 +++++++++++++++++++ primitives/src/signatures/bls.rs | 10 ++- primitives/src/vrf/blsvrf.rs | 4 +- 7 files changed, 180 insertions(+), 82 deletions(-) create mode 100644 primitives/src/hash_to_group/short_weierstrass.rs create mode 100644 primitives/src/hash_to_group/twisted_edwards.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index d378b2068..b6dd5f731 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - Derive `Debug`, `Snafu` on `enum TaggedBlobError` - Updated `tagged-base64` reference url to reflect the Espresso Systems name change +- Add `HashToGroup` support for both SW and TE curves ### Bugfixes diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 83e7a751f..899769aaf 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -13,9 +13,12 @@ ark-ff = { version = "0.3.0", default-features = false } ark-std = { version = "0.3.0", default-features = false } ark-ec = { version = "0.3.0", default-features = false } ark-serialize = { version = "0.3.0", default-features = false } + +# ark curves ark-bls12-381 = { version = "0.3.0", default-features = false, features = ["curve"] } ark-bls12-377 = { git = "https://github.com/arkworks-rs/curves", default-features = false, features = ["curve"], rev = "677b4ae751a274037880ede86e9b6f30f62635af" } - +ark-ed-on-bls12-377 = { git = "https://github.com/arkworks-rs/curves", default-features = false, rev = "677b4ae751a274037880ede86e9b6f30f62635af"} +ark-ed-on-bls12-381 = { version = "0.3.0", default-features = false } # jellyfish jf-plonk = { path = "../plonk" } @@ -42,8 +45,6 @@ quickcheck = "1.0.0" criterion = "0.3.1" # ark curves -ark-ed-on-bls12-377 = { git = "https://github.com/arkworks-rs/curves", default-features = false, rev = "677b4ae751a274037880ede86e9b6f30f62635af"} -ark-ed-on-bls12-381 = { version = "0.3.0", default-features = false } ark-ed-on-bls12-381-bandersnatch = { git = "https://github.com/arkworks-rs/curves", default-features = false, rev = "677b4ae751a274037880ede86e9b6f30f62635af" } ark-ed-on-bn254 = { version = "0.3.0", default-features = false } ark-bn254 = { version = "0.3.0", default-features = false, features = ["curve"] } diff --git a/primitives/src/hash_to_group/mod.rs b/primitives/src/hash_to_group/mod.rs index f935f11e9..0bb3dfda4 100644 --- a/primitives/src/hash_to_group/mod.rs +++ b/primitives/src/hash_to_group/mod.rs @@ -4,78 +4,10 @@ // You should have received a copy of the MIT License // along with the Jellyfish library. If not, see . -//! Hash to Elliptic Curve implementation of +//! Module for hash to various elliptic curve groups -use ark_ec::{ - short_weierstrass_jacobian::{GroupAffine, GroupProjective}, - AffineCurve, SWModelParameters, -}; -use ark_std::{ - rand::{Rng, SeedableRng}, - UniformRand, -}; -use digest::Digest; -use rand_chacha::ChaCha20Rng; -use sha2::Sha256; +mod short_weierstrass; +mod twisted_edwards; -use crate::errors::PrimitivesError; - -/// Trait definition and default implementation for hash to group functions. -pub trait HashToGroup: SWModelParameters + Sized { - /// Hash to Group point, using sha2-512 function - /// hashing to G1 point of `C: ProjectiveCurve`. - // Default implementation implements a naive solution via rejection sampling. - // Slow, and non-constant time. - // - // For specific curves we may want to overload it with a more efficient - // algorithm, such as IETF BLS draft. - fn hash_to_group>( - data: B, - cs_id: B, - ) -> Result, PrimitivesError> { - let mut hasher = Sha256::new(); - hasher.update([cs_id.as_ref(), data.as_ref()].concat()); - let mut seed = [0u8; 32]; - seed.copy_from_slice(hasher.finalize().as_ref()); - let mut rng = ChaCha20Rng::from_seed(seed); - loop { - let x = Self::BaseField::rand(&mut rng); - // a boolean flag to decide if y is positive or not - let y_flag = rng.gen(); - if let Some(p) = GroupAffine::::get_point_from_x(x, y_flag) { - return Ok(p.mul_by_cofactor_to_projective()); - } - } - } -} - -impl HashToGroup for ark_bls12_381::g1::Parameters { - // TODO: - // overload hash to group with the method in - // -} - -impl HashToGroup for ark_bls12_377::g1::Parameters { - // TODO: - // overload hash to group with the method in - // -} - -#[cfg(test)] -mod test { - use super::*; - use ark_std::vec; - - #[test] - fn test_hash_to_group() { - test_hash_to_group_helper::(); - test_hash_to_group_helper::(); - } - - fn test_hash_to_group_helper() { - let data = vec![1u8, 2, 3, 4, 5]; - let _g1 = -

::hash_to_group::<&[u8]>(data.as_ref(), "bls signature".as_ref()) - .unwrap(); - } -} +pub use short_weierstrass::SWHashToGroup; +pub use twisted_edwards::TEHashToGroup; diff --git a/primitives/src/hash_to_group/short_weierstrass.rs b/primitives/src/hash_to_group/short_weierstrass.rs new file mode 100644 index 000000000..20f75a0cf --- /dev/null +++ b/primitives/src/hash_to_group/short_weierstrass.rs @@ -0,0 +1,81 @@ +// Copyright (c) 2022 Espresso Systems (espressosys.com) +// This file is part of the Jellyfish library. + +// You should have received a copy of the MIT License +// along with the Jellyfish library. If not, see . + +//! Hash to Elliptic Curve implementation of + +use crate::errors::PrimitivesError; +use ark_ec::{ + short_weierstrass_jacobian::{GroupAffine, GroupProjective}, + AffineCurve, SWModelParameters, +}; +use ark_std::{ + rand::{Rng, SeedableRng}, + UniformRand, +}; +use digest::Digest; +use rand_chacha::ChaCha20Rng; +use sha2::Sha256; + +/// Trait definition and default implementation for hash to group functions for +/// Short Weierstrass Curves. +pub trait SWHashToGroup: SWModelParameters + Sized { + /// Hash to Group point, using sha2-512 function + /// hashing to G1 point of `C: ProjectiveCurve`. + // Default implementation implements a naive solution via rejection sampling. + // Slow, and non-constant time. + // + // For specific curves we may want to overload it with a more efficient + // algorithm, such as IETF BLS draft. + fn hash_to_group>( + data: B, + cs_id: B, + ) -> Result, PrimitivesError> { + let mut hasher = Sha256::new(); + hasher.update([cs_id.as_ref(), data.as_ref()].concat()); + let mut seed = [0u8; 32]; + seed.copy_from_slice(hasher.finalize().as_ref()); + let mut rng = ChaCha20Rng::from_seed(seed); + loop { + let x = Self::BaseField::rand(&mut rng); + // a boolean flag to decide if y is positive or not + let y_flag = rng.gen(); + if let Some(p) = GroupAffine::::get_point_from_x(x, y_flag) { + return Ok(p.mul_by_cofactor_to_projective()); + } + } + } +} + +impl SWHashToGroup for ark_bls12_381::g1::Parameters { + // TODO: + // overload hash to group with the method in + // +} + +impl SWHashToGroup for ark_bls12_377::g1::Parameters { + // TODO: + // overload hash to group with the method in + // +} + +#[cfg(test)] +mod test { + use super::*; + use ark_std::vec; + + #[test] + fn test_hash_to_group() { + test_hash_to_group_helper::(); + test_hash_to_group_helper::(); + } + + fn test_hash_to_group_helper() { + let data = vec![1u8, 2, 3, 4, 5]; + let _g1 = +

::hash_to_group::<&[u8]>(data.as_ref(), "bls signature".as_ref()) + .unwrap(); + } +} diff --git a/primitives/src/hash_to_group/twisted_edwards.rs b/primitives/src/hash_to_group/twisted_edwards.rs new file mode 100644 index 000000000..09b32c589 --- /dev/null +++ b/primitives/src/hash_to_group/twisted_edwards.rs @@ -0,0 +1,81 @@ +// Copyright (c) 2022 Espresso Systems (espressosys.com) +// This file is part of the Jellyfish library. + +// You should have received a copy of the MIT License +// along with the Jellyfish library. If not, see . + +//! Hash to Elliptic Curve implementation of + +use crate::errors::PrimitivesError; +use ark_ec::{ + twisted_edwards_extended::{GroupAffine, GroupProjective}, + AffineCurve, TEModelParameters, +}; +use ark_std::{ + rand::{Rng, SeedableRng}, + UniformRand, +}; +use digest::Digest; +use rand_chacha::ChaCha20Rng; +use sha2::Sha256; + +/// Trait definition and default implementation for hash to group functions for +/// Twisted Edwards Curves. +pub trait TEHashToGroup: TEModelParameters + Sized { + /// Hash to Group point, using sha2-512 function + /// hashing to G1 point of `C: ProjectiveCurve`. + // Default implementation implements a naive solution via rejection sampling. + // Slow, and non-constant time. + // + // For specific curves we may want to overload it with a more efficient + // algorithm, such as IETF BLS draft. + fn hash_to_group>( + data: B, + cs_id: B, + ) -> Result, PrimitivesError> { + let mut hasher = Sha256::new(); + hasher.update([cs_id.as_ref(), data.as_ref()].concat()); + let mut seed = [0u8; 32]; + seed.copy_from_slice(hasher.finalize().as_ref()); + let mut rng = ChaCha20Rng::from_seed(seed); + loop { + let x = Self::BaseField::rand(&mut rng); + // a boolean flag to decide if y is positive or not + let y_flag = rng.gen(); + if let Some(p) = GroupAffine::::get_point_from_x(x, y_flag) { + return Ok(p.mul_by_cofactor_to_projective()); + } + } + } +} + +impl TEHashToGroup for ark_ed_on_bls12_377::EdwardsParameters { + // TODO: + // overload hash to group with the method in + // +} + +impl TEHashToGroup for ark_ed_on_bls12_381::EdwardsParameters { + // TODO: + // overload hash to group with the method in + // +} + +#[cfg(test)] +mod test { + use super::*; + use ark_std::vec; + + #[test] + fn test_hash_to_group() { + test_hash_to_group_helper::(); + test_hash_to_group_helper::(); + } + + fn test_hash_to_group_helper() { + let data = vec![1u8, 2, 3, 4, 5]; + let _g1 = +

::hash_to_group::<&[u8]>(data.as_ref(), "Jubjub curves".as_ref()) + .unwrap(); + } +} diff --git a/primitives/src/signatures/bls.rs b/primitives/src/signatures/bls.rs index ce3bd801b..5fda9b4f8 100644 --- a/primitives/src/signatures/bls.rs +++ b/primitives/src/signatures/bls.rs @@ -1,7 +1,9 @@ //! Placeholder for BLS signature. use super::SignatureScheme; -use crate::{constants::CS_ID_BLS_SIG_NAIVE, errors::PrimitivesError, hash_to_group::HashToGroup}; +use crate::{ + constants::CS_ID_BLS_SIG_NAIVE, errors::PrimitivesError, hash_to_group::SWHashToGroup, +}; use ark_ec::{ bls12::{Bls12, Bls12Parameters}, short_weierstrass_jacobian::GroupAffine, @@ -51,7 +53,7 @@ pub struct BLSSignature(pub(crate) GroupAffine SignatureScheme for BLSSignatureScheme

where P: Bls12Parameters, - P::G1Parameters: HashToGroup, + P::G1Parameters: SWHashToGroup, { const CS_ID: &'static str = CS_ID_BLS_SIG_NAIVE; @@ -105,7 +107,7 @@ where msg: M, _prng: &mut R, ) -> Result { - let hm = ::hash_to_group( + let hm = ::hash_to_group( msg.as_ref(), CS_ID_BLS_SIG_NAIVE.as_ref(), )?; @@ -119,7 +121,7 @@ where msg: M, sig: &Self::Signature, ) -> Result<(), PrimitivesError> { - let hm = ::hash_to_group( + let hm = ::hash_to_group( msg.as_ref(), CS_ID_BLS_SIG_NAIVE.as_ref(), )?; diff --git a/primitives/src/vrf/blsvrf.rs b/primitives/src/vrf/blsvrf.rs index 500810f1a..04c7ed2ef 100644 --- a/primitives/src/vrf/blsvrf.rs +++ b/primitives/src/vrf/blsvrf.rs @@ -4,7 +4,7 @@ use super::Vrf; use crate::{ constants::CS_ID_BLS_VRF_NAIVE, errors::PrimitivesError, - hash_to_group::HashToGroup, + hash_to_group::SWHashToGroup, signatures::{ bls::{BLSSignKey, BLSSignature, BLSVerKey}, BLSSignatureScheme, SignatureScheme, @@ -29,7 +29,7 @@ impl Vrf for BLSVRFScheme

where H: Digest, P: Bls12Parameters, - P::G1Parameters: HashToGroup, + P::G1Parameters: SWHashToGroup, { const CS_ID: &'static str = CS_ID_BLS_VRF_NAIVE;