Skip to content

Commit

Permalink
<4s
Browse files Browse the repository at this point in the history
  • Loading branch information
pompon0 committed Oct 31, 2023
1 parent e23724f commit 43f4dec
Show file tree
Hide file tree
Showing 9 changed files with 41 additions and 53 deletions.
1 change: 1 addition & 0 deletions node/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions node/actors/consensus/src/replica/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use roles::validator::{self, ViewNumber};

#[tokio::test]
async fn start_new_view_not_leader() {
concurrency::testonly::abort_on_panic();
let ctx = &ctx::test_root(&ctx::ManualClock::new());
let rng = &mut ctx.rng();

Expand Down
2 changes: 1 addition & 1 deletion node/actors/network/src/consensus/handshake/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{frame, noise};
use anyhow::Context as _;
use concurrency::{ctx, time};
use crypto::{ByteFmt};
use crypto::ByteFmt;
use roles::{node, validator};
use schema::{proto::network::consensus as proto, read_required, ProtoFmt};

Expand Down
3 changes: 2 additions & 1 deletion node/libs/crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ hex.workspace = true
rand.workspace = true
sha2.workspace = true
thiserror.workspace = true
tracing.workspace = true

[dev-dependencies]
criterion = "0.5.1"

[[bench]]
name = "bench"
harness = false
harness = false
2 changes: 2 additions & 0 deletions node/libs/crypto/src/bn254/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
use ark_bn254::{G1Affine, G1Projective};
use ark_ec::AffineRepr as _;
use sha2::Digest as _;
use tracing::instrument;

/// Hashes an arbitrary message and maps it to an elliptic curve point in G1.
#[instrument(level = "trace", skip_all)]
pub(crate) fn hash_to_g1(msg: &[u8]) -> G1Projective {
for i in 0..100 {
// Hash the message with the index as suffix.
Expand Down
65 changes: 26 additions & 39 deletions node/libs/crypto/src/bn254/mod.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
//! BLS signature scheme for the BN254 curve.
use std::collections::BTreeMap;
use std::fmt::Debug;
use std::hash::Hasher;

use crate::ByteFmt;
use anyhow::anyhow;
use ark_bn254::{Bn254, Fr, G1Projective as G1, G2Projective as G2};
use ark_ec::pairing::Pairing as _;
use ark_ec::pairing::PairingOutput;
use ark_ec::Group as _;
use ark_ec::{
pairing::{Pairing as _, PairingOutput},
Group as _,
};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
use num_traits::Zero as _;

pub use error::Error;

use crate::ByteFmt;
use num_traits::Zero as _;
use std::{collections::HashMap, fmt::Debug, hash::Hasher};

#[doc(hidden)]
pub mod error;
Expand Down Expand Up @@ -99,6 +95,7 @@ pub struct Signature(pub G1);

impl Signature {
/// Verifies a signature against the provided public key
#[inline(never)]
pub fn verify(&self, msg: &[u8], pk: &PublicKey) -> Result<(), Error> {
let hash_point = hash::hash_to_g1(msg);

Expand Down Expand Up @@ -154,23 +151,21 @@ impl AggregateSignature {
AggregateSignature(agg)
}

/// Verifies an aggregated signature for multiple messages against the provided list of public keys.
/// This method expects one public key per message, otherwise it will fail. Note however that
/// If there are any duplicate messages, the public keys will be aggregated before verification.
pub fn verify<'a>(
&self,
msgs_and_pks: impl Iterator<Item = (&'a [u8], &'a PublicKey)>,
) -> Result<(), Error> {
let msgs_and_pks = Self::aggregate_pk(msgs_and_pks);

#[inline(never)]
fn verify_raw(&self, msgs_and_pks: &[(&[u8], &PublicKey)]) -> Result<(), Error> {
// Aggregate public keys if they are signing the same hash. Each public key aggregated
// is one fewer pairing to calculate.
let mut pairs: HashMap<&[u8], G2> = HashMap::new();
for (msg, pk) in msgs_and_pks {
*pairs.entry(msg).or_default() += pk.0;
}
// First pair: e(sig: G1, generator: G2)
let a = Bn254::pairing(self.0, G2::generator());

// Second pair: e(H(m1): G1, pk1: G2) * ... * (H(m1000): G1, pk1000: G2)
// Second pair: e(H(m1): G1, pk1: G2) * ... * e(H(m1000): G1, pk1000: G2)
let mut b = PairingOutput::zero();
for (msg, pk) in msgs_and_pks {
let hash_point = hash::hash_to_g1(msg);
b += Bn254::pairing(hash_point, pk.0);
for (msg, pk) in pairs {
b += Bn254::pairing(hash::hash_to_g1(msg), pk);
}

if a == b {
Expand All @@ -180,22 +175,14 @@ impl AggregateSignature {
}
}

fn aggregate_pk<'a>(
/// Verifies an aggregated signature for multiple messages against the provided list of public keys.
/// This method expects one public key per message, otherwise it will fail. Note however that
/// If there are any duplicate messages, the public keys will be aggregated before verification.
pub fn verify<'a>(
&self,
msgs_and_pks: impl Iterator<Item = (&'a [u8], &'a PublicKey)>,
) -> impl Iterator<Item = (&'a [u8], PublicKey)> {
// Aggregate public keys if they are signing the same hash. Each public key aggregated
// is one fewer pairing to calculate.
let mut tree_map: BTreeMap<&[u8], PublicKey> = BTreeMap::new();

for (msg, pk) in msgs_and_pks {
if let Some(existing_pk) = tree_map.get_mut(msg) {
existing_pk.0 += pk.0;
} else {
tree_map.insert(msg, pk.clone());
}
}

tree_map.into_iter()
) -> Result<(), Error> {
self.verify_raw(&msgs_and_pks.collect::<Vec<_>>()[..])
}
}

Expand Down
9 changes: 4 additions & 5 deletions node/libs/crypto/src/bn254/testonly.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
//! Random key generation, intended for use in testing
use rand::{distributions::Standard, prelude::Distribution, Rng};

use super::{AggregateSignature, PublicKey, SecretKey, Signature};
use rand::{distributions::Standard, prelude::Distribution, Rng};

/// Generates a random SecretKey. This is meant for testing purposes.
impl Distribution<SecretKey> for Standard {
Expand All @@ -15,20 +14,20 @@ impl Distribution<SecretKey> for Standard {
/// Generates a random PublicKey. This is meant for testing purposes.
impl Distribution<PublicKey> for Standard {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> PublicKey {
rng.gen()
PublicKey(rng.gen())
}
}

/// Generates a random Signature. This is meant for testing purposes.
impl Distribution<Signature> for Standard {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Signature {
rng.gen()
Signature(rng.gen())
}
}

/// Generates a random AggregateSignature. This is meant for testing purposes.
impl Distribution<AggregateSignature> for Standard {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> AggregateSignature {
rng.gen()
AggregateSignature(rng.gen())
}
}
9 changes: 3 additions & 6 deletions node/libs/roles/src/validator/keys/aggregate_signature.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
use std::fmt;

use super::{Error, PublicKey, Signature};
use crate::validator::messages::{Msg, MsgHash};
use crypto::{bn254, ByteFmt, Text, TextFmt};
use std::fmt;
use utils::enum_util::Variant;

use crate::validator::messages::{Msg, MsgHash};

use super::{Error, PublicKey, Signature};

/// An aggregate signature from a validator.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct AggregateSignature(pub(crate) bn254::AggregateSignature);
Expand Down
2 changes: 1 addition & 1 deletion node/libs/roles/src/validator/messages/msg.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Generic message types.
use super::{ConsensusMsg, NetAddress};
use crate::{validator::Error, node::SessionId, validator};
use crate::{node::SessionId, validator, validator::Error};
use crypto::{sha256, ByteFmt, Text, TextFmt};
use std::fmt;
use utils::enum_util::{BadVariantError, Variant};
Expand Down

0 comments on commit 43f4dec

Please sign in to comment.