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

Switch from bls12_381 to bn254 #11

Merged
merged 36 commits into from
Nov 6, 2023
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
5c7c527
Implement bn254
moshababo Oct 23, 2023
cae1291
Replace bls12_381
moshababo Oct 23, 2023
b35e202
[WIP] Use ark_bn254
moshababo Oct 27, 2023
972b7d6
Don't use multi pairing on non-aggregated verify
moshababo Oct 27, 2023
47b624f
Implement signatures aggregation
moshababo Oct 29, 2023
7071f2e
Merge branch 'main' into bn254
moshababo Oct 29, 2023
1cfbeb3
Post-merge fixes
moshababo Oct 29, 2023
e9f04e8
Downgrade multiple-versions "deny" to "warn"
moshababo Oct 29, 2023
cbb9737
cargo fmt
moshababo Oct 29, 2023
540c4f2
cargo cranky
moshababo Oct 29, 2023
a462c6a
Update node/Cargo.toml
moshababo Oct 30, 2023
59602fd
Skip hashbrown version discrepancy
moshababo Oct 30, 2023
09dc83e
Finalize removal of bn254 crate dep
moshababo Oct 30, 2023
8e70127
Update node/libs/crypto/src/bn254/hash.rs
moshababo Oct 30, 2023
6127656
Update node/libs/crypto/src/bn254/hash.rs
moshababo Oct 30, 2023
ba5823f
Derive PartialEq, Eq
moshababo Oct 30, 2023
d262d81
AggregateSignature to store G1 directly
moshababo Oct 30, 2023
2345e62
Generate random G1/G2 points directly
moshababo Oct 31, 2023
cf0a547
Undo bls12_381 mod removal
moshababo Oct 31, 2023
7f66642
Merge branch 'main' into bn254
moshababo Oct 31, 2023
d7c8bb2
Add benches
moshababo Oct 31, 2023
e23724f
opt=3 for crypto
pompon0 Oct 31, 2023
43f4dec
<4s
pompon0 Oct 31, 2023
efd701a
removed clock speedup
pompon0 Oct 31, 2023
69352b4
Merge branch 'main' into bn254
pompon0 Oct 31, 2023
71a1f76
Remove bls12_381 from protobuf schemas
moshababo Nov 1, 2023
96f1cba
Make wrapped scalar/group elements private
moshababo Nov 1, 2023
40faa1f
PublicKey to derive Hash
moshababo Nov 1, 2023
93999ce
Remove unused import
moshababo Nov 1, 2023
c352cc8
cargo fmt
moshababo Nov 2, 2023
8c3aa70
Increase range
moshababo Nov 2, 2023
e89656f
Remove instrumentation
moshababo Nov 2, 2023
91b4f64
Use anyhow::Context
moshababo Nov 2, 2023
28526fd
Add comment about non-generic no-inline functions
moshababo Nov 2, 2023
4959dd5
Add disclaimer regarding side-channel attacks
moshababo Nov 3, 2023
89646d6
Merge branch 'main' into bn254
moshababo Nov 6, 2023
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
542 changes: 519 additions & 23 deletions node/Cargo.lock

Large diffs are not rendered by default.

11 changes: 9 additions & 2 deletions node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,21 @@ assert_matches = "1.5.0"
async-trait = "0.1.71"
bit-vec = "0.6"
blst = "0.3.10"
ark-bn254 = "0.4.0"
ark-ec = "0.4.2"
ark-serialize = "0.4.2"
num-traits = "0.2.17"
clap = { version = "4.3.3", features = ["derive"] }
ed25519-dalek = { version = "2.0.0", features = ["serde", "rand_core"] }
futures = "0.3.28"
hex = "0.4.3"
hyper = { version = "0.14.27", features = ["http1", "http2","server","tcp"] }
hyper = { version = "0.14.27", features = ["http1", "http2", "server", "tcp"] }
im = "15.1.0"
once_cell = "1.17.1"
pin-project = "1.1.0"
prost = "0.11.0"
prost-build = "0.11.0"
prost-reflect = { version = "0.11.0", features = ["derive","serde"] }
prost-reflect = { version = "0.11.0", features = ["derive", "serde"] }
prost-reflect-build = "0.11.0"
protoc-bin-vendored = "3.0.0"
prettyplease = "0.2.6"
Expand Down Expand Up @@ -76,6 +80,9 @@ panic = 'abort'
[profile.release]
panic = 'abort'

[profile.dev.package.crypto]
opt-level = 3

# Compile all the external dependencies with optimizations, because
# some of them (especially the cryptographic primitives) are extremely
# slow when compiled without optimizations, and make the tests run slow.
Expand Down
2 changes: 1 addition & 1 deletion node/actors/consensus/src/leader/replica_commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub(crate) enum Error {
},
/// Invalid message signature.
#[error("invalid signature: {0:#}")]
InvalidSignature(#[source] crypto::bls12_381::Error),
InvalidSignature(#[source] validator::Error),
}

impl StateMachine {
Expand Down
2 changes: 1 addition & 1 deletion node/actors/consensus/src/leader/replica_prepare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ pub(crate) enum Error {
},
/// Invalid message signature.
#[error("invalid signature: {0:#}")]
InvalidSignature(#[source] crypto::bls12_381::Error),
InvalidSignature(#[source] validator::Error),
/// Invalid `HighQC` message.
#[error("invalid high QC: {0:#}")]
InvalidHighQC(#[source] anyhow::Error),
Expand Down
2 changes: 1 addition & 1 deletion node/actors/consensus/src/replica/leader_commit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub(crate) enum Error {
},
/// Invalid message signature.
#[error("invalid signature: {0:#}")]
InvalidSignature(#[source] crypto::bls12_381::Error),
InvalidSignature(#[source] validator::Error),
/// Invalid justification for the message.
#[error("invalid justification: {0:#}")]
InvalidJustification(#[source] anyhow::Error),
Expand Down
2 changes: 1 addition & 1 deletion node/actors/consensus/src/replica/leader_prepare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub(crate) enum Error {
},
/// Invalid message signature.
#[error("invalid signature: {0:#}")]
InvalidSignature(#[source] crypto::bls12_381::Error),
InvalidSignature(#[source] validator::Error),
/// Invalid `PrepareQC` message.
#[error("invalid PrepareQC: {0:#}")]
InvalidPrepareQC(#[source] anyhow::Error),
Expand Down
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/consensus/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use concurrency::ctx;

async fn run_test(behavior: Behavior, network: Network) {
concurrency::testonly::abort_on_panic();
let ctx = &ctx::test_root(&ctx::AffineClock::new(4.));
let ctx = &ctx::test_root(&ctx::AffineClock::new(1.));

const NODES: usize = 11;
let mut nodes = vec![behavior; NODES];
Expand Down
4 changes: 2 additions & 2 deletions 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::{bls12_381, ByteFmt};
use crypto::ByteFmt;
use roles::{node, validator};
use schema::{proto::network::consensus as proto, read_required, ProtoFmt};

Expand Down Expand Up @@ -43,7 +43,7 @@ pub(super) enum Error {
#[error("unexpected peer")]
PeerMismatch,
#[error("validator signature {0}")]
Signature(#[from] bls12_381::Error),
Signature(#[from] validator::Error),
#[error("stream {0}")]
Stream(#[source] anyhow::Error),
}
Expand Down
1 change: 1 addition & 0 deletions node/deny.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ skip = [

# Old versions required by hyper.
{ name = "socket2", version = "=0.4.9" },
{ name = "hashbrown", version = "=0.12.3" }, # (hyper -> h2 -> indexmap -> hashbrown)
]

[sources]
Expand Down
12 changes: 12 additions & 0 deletions node/libs/crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,20 @@ license.workspace = true
[dependencies]
anyhow.workspace = true
blst.workspace = true
ark-bn254.workspace = true
ark-ec.workspace = true
ark-serialize.workspace = true
num-traits.workspace = true
ed25519-dalek.workspace = true
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
48 changes: 48 additions & 0 deletions node/libs/crypto/benches/bench.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#![allow(clippy::missing_docs_in_private_items)]
#![allow(missing_docs)]

extern crate crypto;

use criterion::{criterion_group, criterion_main, Criterion};
use rand::Rng;
use std::iter::repeat_with;

fn bench_bn254(c: &mut Criterion) {
use crypto::bn254::{AggregateSignature, PublicKey, SecretKey, Signature};
let mut rng = rand::thread_rng();
let mut group = c.benchmark_group("bn254");
group.bench_function("100 sig aggregation", |b| {
b.iter(|| {
let sks: Vec<SecretKey> = repeat_with(|| rng.gen::<SecretKey>()).take(100).collect();
let pks: Vec<PublicKey> = sks.iter().map(|k| k.public()).collect();
let msg = rng.gen::<[u8; 32]>();
let sigs: Vec<Signature> = sks.iter().map(|k| k.sign(&msg)).collect();
let agg = AggregateSignature::aggregate(&sigs);
agg.verify(pks.iter().map(|pk| (&msg[..], pk))).unwrap()
});
});

group.finish();
}

#[allow(missing_docs)]
fn bench_bls12_381(c: &mut Criterion) {
use crypto::bls12_381::{AggregateSignature, PublicKey, SecretKey, Signature};
let mut rng = rand::thread_rng();
let mut group = c.benchmark_group("bls12_381");
group.bench_function("100 sig aggregation", |b| {
b.iter(|| {
let sks: Vec<SecretKey> = repeat_with(|| rng.gen::<SecretKey>()).take(100).collect();
let pks: Vec<PublicKey> = sks.iter().map(|k| k.public()).collect();
let msg = rng.gen::<[u8; 32]>();
let sigs: Vec<Signature> = sks.iter().map(|k| k.sign(&msg)).collect();
let agg = AggregateSignature::aggregate(&sigs)?;
agg.verify(pks.iter().map(|pk| (&msg[..], pk)))
});
});

group.finish();
}

criterion_group!(benches, bench_bls12_381, bench_bn254);
criterion_main!(benches);
9 changes: 9 additions & 0 deletions node/libs/crypto/src/bn254/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/// Error type for generating and interacting with bn254.
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
#[error("Signature verification failure")]
SignatureVerificationFailure,
#[error("Aggregate signature verification failure")]
AggregateSignatureVerificationFailure,
}
28 changes: 28 additions & 0 deletions node/libs/crypto/src/bn254/hash.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//! Hash operations.

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)]
moshababo marked this conversation as resolved.
Show resolved Hide resolved
pub(crate) fn hash_to_g1(msg: &[u8]) -> G1Projective {
for i in 0..256 {
// Hash the message with the index as suffix.
let bytes: [u8; 32] = sha2::Sha256::new()
.chain_update(msg)
.chain_update((i as u32).to_be_bytes())
.finalize()
.into();

// Try to get a G1 point from the hash. The probability that this works is around 1/8.
let p = G1Affine::from_random_bytes(&bytes);

if let Some(p) = p {
return p.into();
}
}
// It should be statistically infeasible to finish the loop without finding a point.
unreachable!()
}
Loading
Loading