Skip to content

Commit

Permalink
impl H2G for TE curves (#65)
Browse files Browse the repository at this point in the history
* impl H2G for TE curves

Co-authored-by: Alex Xiong <[email protected]>
  • Loading branch information
zhenfeizhang and alxiong authored May 14, 2022
1 parent af03aa6 commit 889180b
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 82 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
7 changes: 4 additions & 3 deletions primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand All @@ -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"] }
Expand Down
78 changes: 5 additions & 73 deletions primitives/src/hash_to_group/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,78 +4,10 @@
// You should have received a copy of the MIT License
// along with the Jellyfish library. If not, see <https://mit-license.org/>.

//! Hash to Elliptic Curve implementation of <https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/>
//! 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<B: AsRef<[u8]>>(
data: B,
cs_id: B,
) -> Result<GroupProjective<Self>, 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::<Self>::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
// <https://github.com/algorand/pairing-plus/blob/7ec2ae03aae4ba2fc5210810211478171ccededf/src/bls12_381/osswu_map/g1.rs#L47>
}

impl HashToGroup for ark_bls12_377::g1::Parameters {
// TODO:
// overload hash to group with the method in
// <https://github.com/algorand/pairing-plus/blob/7ec2ae03aae4ba2fc5210810211478171ccededf/src/bls12_381/osswu_map/g1.rs#L47>
}

#[cfg(test)]
mod test {
use super::*;
use ark_std::vec;

#[test]
fn test_hash_to_group() {
test_hash_to_group_helper::<ark_bls12_381::g1::Parameters>();
test_hash_to_group_helper::<ark_bls12_377::g1::Parameters>();
}

fn test_hash_to_group_helper<P: HashToGroup>() {
let data = vec![1u8, 2, 3, 4, 5];
let _g1 =
<P as HashToGroup>::hash_to_group::<&[u8]>(data.as_ref(), "bls signature".as_ref())
.unwrap();
}
}
pub use short_weierstrass::SWHashToGroup;
pub use twisted_edwards::TEHashToGroup;
81 changes: 81 additions & 0 deletions primitives/src/hash_to_group/short_weierstrass.rs
Original file line number Diff line number Diff line change
@@ -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 <https://mit-license.org/>.

//! Hash to Elliptic Curve implementation of <https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/>
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<B: AsRef<[u8]>>(
data: B,
cs_id: B,
) -> Result<GroupProjective<Self>, 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::<Self>::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
// <https://github.com/algorand/pairing-plus/blob/7ec2ae03aae4ba2fc5210810211478171ccededf/src/bls12_381/osswu_map/g1.rs#L47>
}

impl SWHashToGroup for ark_bls12_377::g1::Parameters {
// TODO:
// overload hash to group with the method in
// <https://github.com/algorand/pairing-plus/blob/7ec2ae03aae4ba2fc5210810211478171ccededf/src/bls12_381/osswu_map/g1.rs#L47>
}

#[cfg(test)]
mod test {
use super::*;
use ark_std::vec;

#[test]
fn test_hash_to_group() {
test_hash_to_group_helper::<ark_bls12_381::g1::Parameters>();
test_hash_to_group_helper::<ark_bls12_377::g1::Parameters>();
}

fn test_hash_to_group_helper<P: SWHashToGroup>() {
let data = vec![1u8, 2, 3, 4, 5];
let _g1 =
<P as SWHashToGroup>::hash_to_group::<&[u8]>(data.as_ref(), "bls signature".as_ref())
.unwrap();
}
}
81 changes: 81 additions & 0 deletions primitives/src/hash_to_group/twisted_edwards.rs
Original file line number Diff line number Diff line change
@@ -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 <https://mit-license.org/>.

//! Hash to Elliptic Curve implementation of <https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/>
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<B: AsRef<[u8]>>(
data: B,
cs_id: B,
) -> Result<GroupProjective<Self>, 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::<Self>::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
// <https://github.com/algorand/pairing-plus/blob/7ec2ae03aae4ba2fc5210810211478171ccededf/src/bls12_381/osswu_map/g1.rs#L47>
}

impl TEHashToGroup for ark_ed_on_bls12_381::EdwardsParameters {
// TODO:
// overload hash to group with the method in
// <https://github.com/algorand/pairing-plus/blob/7ec2ae03aae4ba2fc5210810211478171ccededf/src/bls12_381/osswu_map/g1.rs#L47>
}

#[cfg(test)]
mod test {
use super::*;
use ark_std::vec;

#[test]
fn test_hash_to_group() {
test_hash_to_group_helper::<ark_ed_on_bls12_377::EdwardsParameters>();
test_hash_to_group_helper::<ark_ed_on_bls12_381::EdwardsParameters>();
}

fn test_hash_to_group_helper<P: TEHashToGroup>() {
let data = vec![1u8, 2, 3, 4, 5];
let _g1 =
<P as TEHashToGroup>::hash_to_group::<&[u8]>(data.as_ref(), "Jubjub curves".as_ref())
.unwrap();
}
}
10 changes: 6 additions & 4 deletions primitives/src/signatures/bls.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -51,7 +53,7 @@ pub struct BLSSignature<P: Bls12Parameters>(pub(crate) GroupAffine<P::G1Paramete
impl<P> SignatureScheme for BLSSignatureScheme<P>
where
P: Bls12Parameters,
P::G1Parameters: HashToGroup,
P::G1Parameters: SWHashToGroup,
{
const CS_ID: &'static str = CS_ID_BLS_SIG_NAIVE;

Expand Down Expand Up @@ -105,7 +107,7 @@ where
msg: M,
_prng: &mut R,
) -> Result<Self::Signature, PrimitivesError> {
let hm = <P::G1Parameters as HashToGroup>::hash_to_group(
let hm = <P::G1Parameters as SWHashToGroup>::hash_to_group(
msg.as_ref(),
CS_ID_BLS_SIG_NAIVE.as_ref(),
)?;
Expand All @@ -119,7 +121,7 @@ where
msg: M,
sig: &Self::Signature,
) -> Result<(), PrimitivesError> {
let hm = <P::G1Parameters as HashToGroup>::hash_to_group(
let hm = <P::G1Parameters as SWHashToGroup>::hash_to_group(
msg.as_ref(),
CS_ID_BLS_SIG_NAIVE.as_ref(),
)?;
Expand Down
4 changes: 2 additions & 2 deletions primitives/src/vrf/blsvrf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -29,7 +29,7 @@ impl<H, P> Vrf<H, P> for BLSVRFScheme<P>
where
H: Digest,
P: Bls12Parameters,
P::G1Parameters: HashToGroup,
P::G1Parameters: SWHashToGroup,
{
const CS_ID: &'static str = CS_ID_BLS_VRF_NAIVE;

Expand Down

0 comments on commit 889180b

Please sign in to comment.