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

naive impl bls signature and vrf #55

Merged
merged 6 commits into from
May 9, 2022
Merged
Show file tree
Hide file tree
Changes from 4 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
8 changes: 6 additions & 2 deletions primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ 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-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" }


# jellyfish
jf-plonk = { path = "../plonk" }
Expand All @@ -28,6 +31,9 @@ generic-array = { version = "^0.14", default-features = false }
crypto_box = { version = "0.7.1", default-features = false, features = [ "u64_backend", "alloc" ] }
displaydoc = { version = "0.2.3", default-features = false }
derivative = { version = "2", features = ["use_core"] }
rand_chacha = { version = "0.3.1", default-features = false }
sha2 = { version = "0.10.1", default-features = false }
digest = { version = "0.10.1", default-features = false }

[dev-dependencies]
rand_chacha = "^0.3"
Expand All @@ -40,8 +46,6 @@ ark-ed-on-bls12-377 = { git = "https://github.com/arkworks-rs/curves", default-f
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-bls12-377 = { git = "https://github.com/arkworks-rs/curves", default-features = false, features = ["curve"], rev = "677b4ae751a274037880ede86e9b6f30f62635af" }
ark-bls12-381 = { version = "0.3.0", default-features = false, features = ["curve"] }
ark-bn254 = { version = "0.3.0", default-features = false, features = ["curve"] }
ark-bw6-761 = { git = "https://github.com/arkworks-rs/curves", default-features = false, rev = "677b4ae751a274037880ede86e9b6f30f62635af" }

Expand Down
2 changes: 1 addition & 1 deletion primitives/src/circuit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ pub mod commitment;
pub mod elgamal;
pub mod merkle_tree;
pub mod prf;
pub mod schnorr_dsa;
pub mod signature;
10 changes: 10 additions & 0 deletions primitives/src/circuit/signature/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// 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/>.

//! Circuit implementation of a signature schemes.
//! Currently this module only implements Schnorr signature scheme over EC.

pub mod schnorr;
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
//! Circuit implementation of a Schnorr signature scheme.

use crate::{
constants::{challenge_bit_len, field_bit_len},
signatures::schnorr::{Signature, VerKey, DOMAIN_SEPARATION},
constants::CS_ID_SCHNORR,
signatures::schnorr::{Signature, VerKey},
utils::{challenge_bit_len, field_bit_len},
};
use ark_ec::{twisted_edwards_extended::GroupAffine, AffineCurve, TEModelParameters as Parameters};
use ark_ff::PrimeField;
Expand Down Expand Up @@ -172,7 +173,7 @@ where
sig_point: &PointVariable,
msg: &[Variable],
) -> Result<Vec<Variable>, PlonkError> {
let instance_description = F::from_be_bytes_mod_order(DOMAIN_SEPARATION);
let instance_description = F::from_be_bytes_mod_order(CS_ID_SCHNORR.as_ref());
// TODO: create `inst_desc_var` and the constant gate *only once* during the
// entire circuit construction.
let inst_desc_var = self.create_variable(instance_description)?;
Expand All @@ -194,10 +195,8 @@ where

#[cfg(test)]
mod tests {
use crate::{
circuit::schnorr_dsa::*,
signatures::schnorr::{KeyPair, Signature, VerKey},
};
use super::*;
use crate::signatures::schnorr::{KeyPair, Signature, VerKey};
use ark_ed_on_bls12_377::EdwardsParameters as Param377;
use ark_ed_on_bls12_381::EdwardsParameters as Param381;
use ark_ed_on_bls12_381_bandersnatch::EdwardsParameters as Param381b;
Expand Down Expand Up @@ -227,9 +226,9 @@ mod tests {
let msg: Vec<F> = (0..20).map(|i| F::from(i as u64)).collect();
let mut msg_bad = msg.clone();
msg_bad[0] = F::from(2 as u64);
let sig = keypair.sign(&msg);
let sig_bad = keypair.sign(&msg_bad);
vk.verify(&msg, &sig).unwrap();
let sig = keypair.sign(&msg, CS_ID_SCHNORR);
let sig_bad = keypair.sign(&msg_bad, CS_ID_SCHNORR);
vk.verify(&msg, &sig, CS_ID_SCHNORR).unwrap();

// Test `verify_signature()`
// Good path
Expand Down
28 changes: 6 additions & 22 deletions primitives/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,11 @@

//! Constants for curve specific parameters.

use ark_ec::models::TEModelParameters;
use ark_ff::{FpParameters, PrimeField};
/// ciphersuite identifier for schnorr signature
pub const CS_ID_SCHNORR: &str = "SCHNORR_WITH_RESCUE_HASH_v01";

#[inline]
pub(crate) fn field_byte_len<F: PrimeField>() -> usize {
((F::Params::MODULUS_BITS + 7) / 8) as usize
}
/// ciphersuite identifier for BLS signature
pub const CS_ID_BLS_SIG_NAIVE: &str = "BLS_SIG_WITH_NAIVE_HtG_v01";

#[inline]
pub(crate) fn field_bit_len<F: PrimeField>() -> usize {
F::Params::MODULUS_BITS as usize
}

#[inline]
pub(crate) fn challenge_bit_len<F: PrimeField>() -> usize {
// Our challenge is of size 248 bits
// This is enough for a soundness error of 2^-128
(field_byte_len::<F>() - 1) << 3
}

#[inline]
pub(crate) fn curve_cofactor<P: TEModelParameters>() -> u64 {
P::COFACTOR[0]
}
/// ciphersuite identifier for BLS VRF
pub const CS_ID_BLS_VRF_NAIVE: &str = "BLS_VRF_WITH_NAIVE_HtG_v01";
11 changes: 9 additions & 2 deletions primitives/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@

//! Error types.

use ark_serialize::SerializationError;
use ark_std::string::String;
use displaydoc::Display;
use jf_rescue::errors::RescueError;

/// A `enum` specifying the possible failure modes of the primitives.
#[derive(Debug, Display, PartialEq)]
#[derive(Debug, Display)]
pub enum PrimitivesError {
/// Unsuccessful verification for proof or signature, {0}
VerificationError(String),
Expand All @@ -21,7 +22,7 @@ pub enum PrimitivesError {
/// ‼ ️Internal error! Please report to Crypto Team immediately!\nMessage: {0}
InternalError(String),
/// Deserialization failed: {0}
DeserializationError(String),
DeserializationError(SerializationError),
/// Decryption failed: {0}
FailedDecryption(String),
/// Rescue Error: {0}
Expand All @@ -36,5 +37,11 @@ impl From<RescueError> for PrimitivesError {
}
}

impl From<SerializationError> for PrimitivesError {
fn from(e: SerializationError) -> Self {
Self::DeserializationError(e)
}
}

#[cfg(feature = "std")]
impl std::error::Error for PrimitivesError {}
81 changes: 81 additions & 0 deletions primitives/src/hash_to_group/mod.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 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;

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);
let greatest = rng.gen();

if let Some(p) = GroupAffine::<Self>::get_point_from_x(x, greatest) {
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();
}
}
2 changes: 2 additions & 0 deletions primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ pub mod commitment;
pub mod constants;
pub mod elgamal;
pub mod errors;
pub mod hash_to_group;
pub mod merkle_tree;
pub mod prf;
pub mod signatures;
pub mod vrf;

pub(crate) mod utils;
Loading