Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
12 changes: 6 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ sha3 = { version = "0.10", default-features = false }
sha2 = { version = "0.10", default-features = false }
digest = { version = "0.10", default-features = false }

ark-ff = { version = "0.4.0", default-features = false }
ark-ec = { version = "0.4.0", default-features = false }
ark-serialize = { version = "0.4.0", default-features = false, features = [ "derive" ] }
ark-serialize-derive = { version = "0.4.0", default-features = false }
ark-ff = { version = "0.5.0", default-features = false }
ark-ec = { version = "0.5.0", default-features = false }
ark-serialize = { version = "0.5.0", default-features = false, features = [ "derive" ] }
ark-serialize-derive = { version = "0.5.0", default-features = false }

ark-bls12-381 = { version = "0.4.0", default-features = false, features = [ "curve" ] }
ark-bls12-377 = { version = "0.4.0", default-features = false, features = [ "curve" ] }
ark-bls12-381 = { version = "0.5.0", default-features = false, features = [ "curve" ] }
ark-bls12-377 = { version = "0.5.0", default-features = false, features = [ "curve" ] }

zeroize = { version = "1.0", default-features = false, features = [ "zeroize_derive" ] }
serde = { version = "1.0", default-features = false, optional = true }
Expand Down
39 changes: 20 additions & 19 deletions src/chaum_pedersen_signature.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use alloc::vec::Vec;

use ark_ec::Group;
use ark_ec::PrimeGroup;
use ark_ff::field_hashers::{DefaultFieldHasher, HashToField};

use digest::DynDigest;
use digest::{DynDigest, FixedOutputReset};

use crate::double::{DoublePublicKeyScheme, PublicKeyInSignatureGroup};
use crate::engine::EngineBLS;
Expand All @@ -15,7 +14,7 @@ use crate::{Message, SecretKeyVT};
pub type ChaumPedersenSignature<E> = (Signature<E>, SchnorrProof<E>);

/// ProofOfPossion trait which should be implemented by secret
pub trait ChaumPedersenSigner<E: EngineBLS, H: DynDigest + Default + Clone> {
pub trait ChaumPedersenSigner<E: EngineBLS, H: DynDigest + FixedOutputReset + Default + Clone> {
/// The proof of possession generator is supposed to
/// to produce a schnoor signature of the message using
/// the secret key which it claim to possess.
Expand All @@ -24,7 +23,7 @@ pub trait ChaumPedersenSigner<E: EngineBLS, H: DynDigest + Default + Clone> {
fn generate_witness_scaler(
&self,
message_point_as_bytes: &Vec<u8>,
) -> <<E as EngineBLS>::PublicKeyGroup as Group>::ScalarField;
) -> <<E as EngineBLS>::PublicKeyGroup as PrimeGroup>::ScalarField;

fn generate_dleq_proof(
&mut self,
Expand All @@ -34,15 +33,17 @@ pub trait ChaumPedersenSigner<E: EngineBLS, H: DynDigest + Default + Clone> {
}

/// This should be implemented by public key
pub trait ChaumPedersenVerifier<E: EngineBLS, H: DynDigest + Default + Clone> {
pub trait ChaumPedersenVerifier<E: EngineBLS, H: DynDigest + FixedOutputReset + Default + Clone> {
fn verify_cp_signature(
&self,
message: &Message,
signature_proof: ChaumPedersenSignature<E>,
) -> bool;
}

impl<E: EngineBLS, H: DynDigest + Default + Clone> ChaumPedersenSigner<E, H> for SecretKeyVT<E> {
impl<E: EngineBLS, H: DynDigest + FixedOutputReset + Default + Clone> ChaumPedersenSigner<E, H>
for SecretKeyVT<E>
{
fn generate_cp_signature(&mut self, message: &Message) -> ChaumPedersenSignature<E> {
//First we generate a vanila BLS Signature;
let bls_signature = SecretKeyVT::sign(self, message);
Expand Down Expand Up @@ -76,7 +77,7 @@ impl<E: EngineBLS, H: DynDigest + Default + Clone> ChaumPedersenSigner<E, H> for
&message_point_as_bytes,
);

let A_point = <<E as EngineBLS>::SignatureGroup as Group>::generator() * k;
let A_point = <<E as EngineBLS>::SignatureGroup as PrimeGroup>::generator() * k;
let B_point = message_point * k;

let A_point_as_bytes = E::signature_point_to_byte(&A_point);
Expand All @@ -92,10 +93,10 @@ impl<E: EngineBLS, H: DynDigest + Default + Clone> ChaumPedersenSigner<E, H> for
.concat();

let hasher = <DefaultFieldHasher<H> as HashToField<
<<E as EngineBLS>::PublicKeyGroup as Group>::ScalarField,
<<E as EngineBLS>::PublicKeyGroup as PrimeGroup>::ScalarField,
>>::new(&[]);

let c = hasher.hash_to_field(proof_basis.as_slice(), 1)[0];
let c = hasher.hash_to_field::<1>(proof_basis.as_slice())[0];

let s = k - c * self.0;

Expand All @@ -107,32 +108,32 @@ impl<E: EngineBLS, H: DynDigest + Default + Clone> ChaumPedersenSigner<E, H> for
fn generate_witness_scaler(
&self,
message_point_as_bytes: &Vec<u8>,
) -> <<E as EngineBLS>::PublicKeyGroup as Group>::ScalarField {
) -> <<E as EngineBLS>::PublicKeyGroup as PrimeGroup>::ScalarField {
let secret_key_as_bytes = self.to_bytes();

let mut secret_key_hasher = H::default();
secret_key_hasher.update(secret_key_as_bytes.as_slice());
DynDigest::update(&mut secret_key_hasher, secret_key_as_bytes.as_slice());
let hashed_secret_key = secret_key_hasher.finalize_reset().to_vec();

let hasher = <DefaultFieldHasher<H> as HashToField<
<<E as EngineBLS>::PublicKeyGroup as Group>::ScalarField,
<<E as EngineBLS>::PublicKeyGroup as PrimeGroup>::ScalarField,
>>::new(&[]);
let scalar_seed = [hashed_secret_key, message_point_as_bytes.clone()].concat();
hasher.hash_to_field(scalar_seed.as_slice(), 1)[0]
hasher.hash_to_field::<1>(scalar_seed.as_slice())[0]
}
}

/// This should be implemented by public key
#[allow(non_snake_case)]
impl<E: EngineBLS, H: DynDigest + Default + Clone> ChaumPedersenVerifier<E, H>
impl<E: EngineBLS, H: DynDigest + FixedOutputReset + Default + Clone> ChaumPedersenVerifier<E, H>
for PublicKeyInSignatureGroup<E>
{
fn verify_cp_signature(
&self,
message: &Message,
signature_proof: ChaumPedersenSignature<E>,
) -> bool {
let A_check_point = <<E as EngineBLS>::SignatureGroup as Group>::generator()
let A_check_point = <<E as EngineBLS>::SignatureGroup as PrimeGroup>::generator()
* signature_proof.1 .1
+ self.0 * signature_proof.1 .0;

Expand All @@ -157,10 +158,10 @@ impl<E: EngineBLS, H: DynDigest + Default + Clone> ChaumPedersenVerifier<E, H>
.concat();

let hasher = <DefaultFieldHasher<H> as HashToField<
<<E as EngineBLS>::PublicKeyGroup as Group>::ScalarField,
<<E as EngineBLS>::PublicKeyGroup as PrimeGroup>::ScalarField,
>>::new(&[]);
let c_check: <<E as EngineBLS>::PublicKeyGroup as Group>::ScalarField =
hasher.hash_to_field(resulting_proof_basis.as_slice(), 1)[0];
let c_check: <<E as EngineBLS>::PublicKeyGroup as PrimeGroup>::ScalarField =
hasher.hash_to_field::<1>(resulting_proof_basis.as_slice())[0];

c_check == signature_proof.1 .0
}
Expand Down
20 changes: 10 additions & 10 deletions src/double_pop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ use crate::serialize::SerializableToBytes;
use crate::single::{Keypair, PublicKey};

use alloc::vec::Vec;
use digest::DynDigest;
use digest::{DynDigest, FixedOutputReset};

use ark_ec::Group;
use ark_ec::PrimeGroup;
use ark_ff::field_hashers::{DefaultFieldHasher, HashToField};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};

Expand All @@ -23,7 +23,7 @@ use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
pub struct NuggetBLSPoP<E: EngineBLS>(pub E::SignatureGroup);

//The bls proof of possession for single or double public key schemes are the same
impl<E: EngineBLS, H: DynDigest + Default + Clone>
impl<E: EngineBLS, H: DynDigest + FixedOutputReset + Default + Clone>
ProofOfPossessionGenerator<E, H, DoublePublicKey<E>, NuggetBLSPoP<E>> for Keypair<E>
{
fn generate_pok(&mut self) -> NuggetBLSPoP<E> {
Expand All @@ -40,8 +40,8 @@ impl<E: EngineBLS> SerializableToBytes for NuggetBLSPoP<E> {

/// The verification process for verifying both possession of one secret key
/// for two public key is different.
impl<E: EngineBLS, H: DynDigest + Default + Clone> ProofOfPossession<E, H, DoublePublicKey<E>>
for NuggetBLSPoP<E>
impl<E: EngineBLS, H: DynDigest + FixedOutputReset + Default + Clone>
ProofOfPossession<E, H, DoublePublicKey<E>> for NuggetBLSPoP<E>
{
/// verify the validity of PoP by performing the following Pairing
/// e(H_pop(pk_2) + t.g_1, pk_2) = e(sign(H_pop(pk_2))+ t.pk_1, g_2)
Expand Down Expand Up @@ -70,11 +70,11 @@ impl<E: EngineBLS, H: DynDigest + Default + Clone> ProofOfPossession<E, H, Doubl
.concat();

let hasher = <DefaultFieldHasher<H> as HashToField<
<<E as EngineBLS>::PublicKeyGroup as Group>::ScalarField,
<<E as EngineBLS>::PublicKeyGroup as PrimeGroup>::ScalarField,
>>::new(&[]);

let randomization_coefficient: E::Scalar =
hasher.hash_to_field(random_oracle_seed.as_slice(), 1)[0];
hasher.hash_to_field::<1>(random_oracle_seed.as_slice())[0];

let mut randomized_pub_in_g1 = public_key_in_signature_group;
randomized_pub_in_g1 *= randomization_coefficient;
Expand All @@ -101,7 +101,7 @@ impl<E: EngineBLS, H: DynDigest + Default + Clone> ProofOfPossession<E, H, Doubl
pub struct NuggetBLSnCPPoP<E: EngineBLS>(pub DoubleSignature<E>);

//The implement the generation of bls proof of possession including chaum-pederesno PoP for double public key schemes
impl<E: EngineBLS, H: DynDigest + Default + Clone>
impl<E: EngineBLS, H: DynDigest + FixedOutputReset + Default + Clone>
ProofOfPossessionGenerator<E, H, DoublePublicKey<E>, NuggetBLSnCPPoP<E>> for Keypair<E>
{
fn generate_pok(&mut self) -> NuggetBLSnCPPoP<E> {
Expand All @@ -123,8 +123,8 @@ impl<E: EngineBLS> SerializableToBytes for NuggetBLSnCPPoP<E> {
}

/// The verification process for verifying both nugget BLS and CP
impl<E: EngineBLS, H: DynDigest + Default + Clone> ProofOfPossession<E, H, DoublePublicKey<E>>
for NuggetBLSnCPPoP<E>
impl<E: EngineBLS, H: DynDigest + FixedOutputReset + Default + Clone>
ProofOfPossession<E, H, DoublePublicKey<E>> for NuggetBLSnCPPoP<E>
{
/// verify the validity of PoP by verifying nugget PoP and the CP
/// signature
Expand Down
39 changes: 21 additions & 18 deletions src/schnorr_pop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ use crate::serialize::SerializableToBytes;
use crate::single::{Keypair, PublicKey};

use alloc::vec::Vec;
use ark_ec::PrimeGroup;
use digest::DynDigest;

use ark_ec::Group;
use digest::FixedOutputReset;

pub type SchnorrProof<E> = (<E as EngineBLS>::Scalar, <E as EngineBLS>::Scalar);

Expand All @@ -26,36 +26,38 @@ impl<E: EngineBLS> Clone for SchnorrPoP<E> {
}

/// Generate Schnorr Signature for an arbitrary message using a key ment to use in BLS scheme
trait BLSSchnorrPoPGenerator<E: EngineBLS, H: DynDigest + Default + Clone>:
trait BLSSchnorrPoPGenerator<E: EngineBLS, H: DynDigest + FixedOutputReset + Default + Clone>:
ProofOfPossessionGenerator<E, H, PublicKey<E>, SchnorrPoP<E>>
{
/// Produce a secret witness scalar `k`, aka nonce, from hash of
/// H( H(s) | H(public_key)) because our key does not have the
/// randomness redundacy exists in EdDSA secret key.
fn witness_scalar(&self) -> <<E as EngineBLS>::PublicKeyGroup as Group>::ScalarField;
fn witness_scalar(&self) -> <<E as EngineBLS>::PublicKeyGroup as PrimeGroup>::ScalarField;
}

impl<E: EngineBLS, H: DynDigest + Default + Clone> BLSSchnorrPoPGenerator<E, H> for Keypair<E> {
impl<E: EngineBLS, H: DynDigest + FixedOutputReset + Default + Clone> BLSSchnorrPoPGenerator<E, H>
for Keypair<E>
{
//The pseudo random witness is generated similar to eddsa witness
//hash(secret_key|publick_key)
fn witness_scalar(&self) -> <<E as EngineBLS>::PublicKeyGroup as Group>::ScalarField {
fn witness_scalar(&self) -> <<E as EngineBLS>::PublicKeyGroup as PrimeGroup>::ScalarField {
let secret_key_as_bytes = self.secret.to_bytes();
let public_key_as_bytes = <E as EngineBLS>::public_key_point_to_byte(&self.public.0);

let mut secret_key_hasher = H::default();
secret_key_hasher.update(secret_key_as_bytes.as_slice());
DynDigest::update(&mut secret_key_hasher, secret_key_as_bytes.as_slice());
let hashed_secret_key = secret_key_hasher.finalize_reset().to_vec();

let hasher = <DefaultFieldHasher<H> as HashToField<
<<E as EngineBLS>::PublicKeyGroup as Group>::ScalarField,
<<E as EngineBLS>::PublicKeyGroup as PrimeGroup>::ScalarField,
>>::new(&[]);

let scalar_seed = [hashed_secret_key, public_key_as_bytes].concat();
hasher.hash_to_field(scalar_seed.as_slice(), 1)[0]
hasher.hash_to_field::<1>(scalar_seed.as_slice())[0]
}
}

impl<E: EngineBLS, H: DynDigest + Default + Clone>
impl<E: EngineBLS, H: DynDigest + FixedOutputReset + Default + Clone>
ProofOfPossessionGenerator<E, H, PublicKey<E>, SchnorrPoP<E>> for Keypair<E>
{
//TODO: Message must be equal to public key.
Expand All @@ -77,17 +79,17 @@ impl<E: EngineBLS, H: DynDigest + Default + Clone>
// avoiding one curve addition (or two field divisions) in expense of a hash.
let mut r = <dyn BLSSchnorrPoPGenerator<E, H>>::witness_scalar(self);

let mut r_point = <<E as EngineBLS>::PublicKeyGroup as Group>::generator();
let mut r_point = <<E as EngineBLS>::PublicKeyGroup as PrimeGroup>::generator();
r_point *= r; //todo perhaps we need to mandate E to have a hard coded point

let r_point_as_bytes = <E as EngineBLS>::public_key_point_to_byte(&r_point);
let public_key_as_bytes = <E as EngineBLS>::public_key_point_to_byte(&self.public.0); //it *must* be the public key (fixed) otherwise secret key can be recovered from the two different proves

let proof_basis = [r_point_as_bytes, public_key_as_bytes].concat();
let hasher = <DefaultFieldHasher<H> as HashToField<
<<E as EngineBLS>::PublicKeyGroup as Group>::ScalarField,
<<E as EngineBLS>::PublicKeyGroup as PrimeGroup>::ScalarField,
>>::new(&[]);
let k = hasher.hash_to_field(proof_basis.as_slice(), 1)[0];
let k = hasher.hash_to_field::<1>(proof_basis.as_slice())[0];

let s = (k * self.secret.into_vartime().0) + r;

Expand All @@ -97,14 +99,14 @@ impl<E: EngineBLS, H: DynDigest + Default + Clone>
}
}

impl<E: EngineBLS, H: DynDigest + Default + Clone> ProofOfPossession<E, H, PublicKey<E>>
for SchnorrPoP<E>
impl<E: EngineBLS, H: DynDigest + FixedOutputReset + Default + Clone>
ProofOfPossession<E, H, PublicKey<E>> for SchnorrPoP<E>
{
/// verify the validity of schnoor proof for a given publick key by
/// making sure this is equal to zero
/// H(+s*G - k*Publkey|M) == k
fn verify(&self, public_key_of_prover: &PublicKey<E>) -> bool {
let mut schnorr_point = <<E as EngineBLS>::PublicKeyGroup as Group>::generator();
let mut schnorr_point = <<E as EngineBLS>::PublicKeyGroup as PrimeGroup>::generator();
schnorr_point *= self.0 .0;
let mut k_public_key = public_key_of_prover.0;
k_public_key *= -self.0 .1;
Expand All @@ -117,9 +119,10 @@ impl<E: EngineBLS, H: DynDigest + Default + Clone> ProofOfPossession<E, H, Publi
let resulting_proof_basis = [schnorr_point_as_bytes, public_key_as_bytes].concat();

let hasher = <DefaultFieldHasher<H> as HashToField<
<<E as EngineBLS>::PublicKeyGroup as Group>::ScalarField,
<<E as EngineBLS>::PublicKeyGroup as PrimeGroup>::ScalarField,
>>::new(&[]);
let random_scalar: E::Scalar = hasher.hash_to_field(resulting_proof_basis.as_slice(), 1)[0];
let random_scalar: E::Scalar =
hasher.hash_to_field::<1>(resulting_proof_basis.as_slice())[0];
random_scalar == self.0 .1
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/single.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ impl<E: EngineBLS> SecretKeyVT<E> {

pub fn from_seed(seed: &[u8]) -> Self {
let hasher = <DefaultFieldHasher<Sha256> as HashToField<E::Scalar>>::new(&[]);
return SecretKeyVT(hasher.hash_to_field(seed, 1)[0]);
return SecretKeyVT(hasher.hash_to_field::<1>(seed)[0]);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/single_pop_aggregator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use super::verifiers::{
};
use super::*;

use digest::DynDigest;
use digest::{DynDigest, FixedOutputReset};

/// Batch or aggregate BLS signatures with attached messages and
/// signers, for whom we previously checked proofs-of-possession.
Expand Down Expand Up @@ -148,7 +148,7 @@ impl<E: EngineBLS> SignatureAggregatorAssumingPoP<E> {
// }

pub fn verify_using_aggregated_auxiliary_public_keys<
RandomOracle: DynDigest + Default + Clone,
RandomOracle: DynDigest + FixedOutputReset + Default + Clone,
>(
&self,
) -> bool {
Expand Down
6 changes: 4 additions & 2 deletions src/verifiers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ use ark_ff::field_hashers::{DefaultFieldHasher, HashToField};
use ark_serialize::CanonicalSerialize;
#[cfg(feature = "std")]
use digest::DynDigest;
#[cfg(feature = "std")]
use digest::FixedOutputReset;

use ark_ec::CurveGroup;

Expand Down Expand Up @@ -204,7 +206,7 @@ pub fn verify_with_distinct_messages<S: Signed>(signed: S, normalize_public_keys
#[cfg(feature = "std")]
pub fn verify_using_aggregated_auxiliary_public_keys<
E: EngineBLS,
H: DynDigest + Default + Clone,
H: DynDigest + FixedOutputReset + Default + Clone,
>(
signed: &single_pop_aggregator::SignatureAggregatorAssumingPoP<E>,
normalize_public_keys: bool,
Expand Down Expand Up @@ -259,7 +261,7 @@ pub fn verify_using_aggregated_auxiliary_public_keys<

let hasher = <DefaultFieldHasher<H> as HashToField<E::Scalar>>::new(&[]);
let pseudo_random_scalar: E::Scalar =
hasher.hash_to_field(&pseudo_random_scalar_seed[..], 1)[0];
hasher.hash_to_field::<1>(&pseudo_random_scalar_seed[..])[0];

let signature = signature + aggregated_aux_pub_key * pseudo_random_scalar;

Expand Down