Skip to content

Commit

Permalink
Merge branch 'unstable' into handle-self-messages
Browse files Browse the repository at this point in the history
  • Loading branch information
dknopik committed Mar 6, 2025
2 parents a5aac99 + f030b75 commit 120fd23
Show file tree
Hide file tree
Showing 30 changed files with 1,293 additions and 463 deletions.
28 changes: 23 additions & 5 deletions Cargo.lock

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

7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ members = [
"anchor/http_api",
"anchor/http_metrics",
"anchor/message_sender",
"anchor/message_validator",
"anchor/network",
"anchor/processor",
"anchor/qbft_manager",
Expand All @@ -35,6 +36,7 @@ eth = { path = "anchor/eth" }
http_api = { path = "anchor/http_api" }
http_metrics = { path = "anchor/http_metrics" }
message_sender = { path = "anchor/message_sender" }
message_validator = { path = "anchor/message_validator" }
network = { path = "anchor/network" }
processor = { path = "anchor/processor" }
qbft = { path = "anchor/common/qbft" }
Expand Down Expand Up @@ -79,7 +81,7 @@ alloy = { version = "0.11.0", features = [
async-channel = "1.9"
axum = "0.8.1"
base64 = "0.22.1"
blst = { git = "https://github.com/dknopik/blst", branch = "sk-conversion" }
blst = "0.3.14"
# the custom repo is needed because they fix to a specific version of blst, which conflicts with the line above
blstrs_plus = { git = "https://github.com/dknopik/blstrs", branch = "pls" }
clap = { version = "4.5.15", features = ["derive", "wrap_help"] }
Expand All @@ -106,6 +108,7 @@ serde = { version = "1.0.208", features = ["derive"] }
serde_yaml = "0.9"
sha2 = "0.10.8"
strum = { version = "0.26.3", features = ["derive"] }
thiserror = "2.0.11"
tokio = { version = "1.39.2", features = [
"rt",
"rt-multi-thread",
Expand All @@ -122,8 +125,6 @@ vsss-rs = "5.1.0"
zeroize = "1.8.1"

[patch.crates-io]
# todo: remove when https://github.com/supranational/blst/pull/248 is merged
blst = { git = "https://github.com/dknopik/blst", branch = "sk-conversion" }
# todo: remove when libp2p versions are aligned again. this is only needed because cargo audit crashes otherwise
libp2p = { git = "https://github.com/libp2p/rust-libp2p.git", rev = "082eb16" }
libp2p-mplex = { git = "https://github.com/libp2p/rust-libp2p.git", rev = "082eb16" }
Expand Down
1 change: 1 addition & 0 deletions anchor/client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ http_api = { workspace = true }
http_metrics = { workspace = true }
hyper = { workspace = true }
message_sender = { workspace = true }
message_validator = { workspace = true }
multiaddr = { workspace = true }
network = { workspace = true }
openssl = { workspace = true }
Expand Down
6 changes: 6 additions & 0 deletions anchor/client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use database::NetworkDatabase;
use eth2::reqwest::{Certificate, ClientBuilder};
use eth2::{BeaconNodeHttpClient, Timeouts};
use message_sender::NetworkMessageSender;
use message_validator::Validator;
use network::Network;
use openssl::pkey::Private;
use openssl::rsa::Rsa;
Expand Down Expand Up @@ -354,11 +355,16 @@ impl Client {
network::SUBNET_COUNT,
)?;

let (results_tx, results_rx) = mpsc::channel::<message_validator::Outcome>(9000);
let message_validator = Validator::new(processor_senders.clone(), results_tx);

// Start the p2p network
let network = Network::try_new(
&config.network,
subnet_tracker,
network_rx,
message_validator,
results_rx,
executor.clone(),
)
.await
Expand Down
6 changes: 3 additions & 3 deletions anchor/common/bls_lagrange/src/blsful.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl From<KeyId> for u64 {
}

pub fn split_with_rng(
key: bls::SecretKey,
key: &bls::SecretKey,
threshold: u64,
ids: impl IntoIterator<Item = KeyId>,
rng: &mut (impl CryptoRng + Rng),
Expand All @@ -55,7 +55,7 @@ pub fn split_with_rng(
.map_err(|_| Error::InternalError)?,
);
let key = if result.is_some().into() {
IdentifierPrimeField(result.unwrap())
Zeroizing::new(IdentifierPrimeField(result.unwrap()))
} else {
return Err(Error::InternalError);
};
Expand All @@ -66,7 +66,7 @@ pub fn split_with_rng(
shamir::split_secret_with_participant_generator(
threshold as usize,
ids.len(),
&key,
&*key,
rng,
&[ParticipantIdGeneratorType::List { list: &ids }],
)
Expand Down
117 changes: 49 additions & 68 deletions anchor/common/bls_lagrange/src/blst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ use blst::min_pk::SecretKey;
use blst::*;
use rand::prelude::*;
use std::iter::{once, repeat_with};
use std::mem::MaybeUninit;
use std::mem;
use std::num::NonZeroU64;
use std::sync::LazyLock;
use zeroize::Zeroizing;

static WARNING: LazyLock<()> = LazyLock::new(|| {
eprintln!(
Expand All @@ -25,7 +24,8 @@ static WARNING: LazyLock<()> = LazyLock::new(|| {
#[derive(Debug, Clone)]
pub struct KeyId {
num: u64,
fr: blst_fr,
// note: while blst_scalar is also used for bls keys, the scalars used in key ids are NOT secret
scalar: blst_scalar,
}

impl TryFrom<u64> for KeyId {
Expand All @@ -34,11 +34,11 @@ impl TryFrom<u64> for KeyId {
fn try_from(value: u64) -> Result<Self, Error> {
if value != 0 {
unsafe {
let mut id = MaybeUninit::<blst_fr>::uninit();
blst_fr_from_uint64(id.as_mut_ptr(), &value);
let mut id = blst_scalar::default();
blst_scalar_from_uint64(&mut id, &value);
Ok(KeyId {
num: value,
fr: id.assume_init(),
scalar: id,
})
}
} else {
Expand All @@ -49,11 +49,11 @@ impl TryFrom<u64> for KeyId {
impl From<NonZeroU64> for KeyId {
fn from(value: NonZeroU64) -> Self {
unsafe {
let mut id = MaybeUninit::<blst_fr>::uninit();
blst_fr_from_uint64(id.as_mut_ptr(), &value.get());
let mut id = blst_scalar::default();
blst_scalar_from_uint64(&mut id, &value.get());
KeyId {
num: value.get(),
fr: id.assume_init(),
scalar: id,
}
}
}
Expand All @@ -65,57 +65,40 @@ impl From<KeyId> for u64 {
}
}

#[inline]
fn key_to_fr(key: &SecretKey) -> blst_fr {
let mut key_fr = MaybeUninit::<blst_fr>::uninit();
unsafe {
blst_fr_from_scalar(key_fr.as_mut_ptr(), <&blst_scalar>::from(key));
key_fr.assume_init()
}
}

pub fn split_with_rng(
key: bls::SecretKey,
key: &bls::SecretKey,
threshold: u64,
ids: impl IntoIterator<Item = KeyId>,
rng: &mut (impl CryptoRng + Rng),
) -> Result<Vec<(KeyId, bls::SecretKey)>, Error> {
LazyLock::force(&WARNING);
let key = key.point();

if threshold <= 1 {
return Err(Error::InvalidThreshold);
}

// MaybeUninit needed to make `Zeroizing` work
let msk = Zeroizing::new(
once(Ok(MaybeUninit::new(key_to_fr(key))))
.chain(
repeat_with(|| random_key(rng).map(|sk| MaybeUninit::new(key_to_fr(sk.point()))))
.take((threshold - 1) as usize),
)
.collect::<Result<Vec<_>, _>>()?,
);
// `bls::SecretKey` contains a blst `SecretKey`, which zeroizes on drop.
let keys = repeat_with(|| random_key(rng))
.take((threshold - 1) as usize)
.collect::<Result<Vec<_>, _>>()?;

let msk = once(key)
.chain(keys.iter())
.map(|key| <&blst_scalar>::from(key.point()))
.collect::<Vec<_>>();

ids.into_iter()
.map(|id| {
let mut intermediate = MaybeUninit::<blst_fr>::uninit();
unsafe {
let mut y = (*msk).last().copied().unwrap();
for i in (0..=(threshold - 2)).rev() {
blst_fr_mul(intermediate.as_mut_ptr(), y.as_ptr(), &id.fr);
blst_fr_add(
y.as_mut_ptr(),
intermediate.as_ptr(),
msk[i as usize].as_ptr(),
);
.map(|id| unsafe {
let mut y = (*msk.last().expect("at least one element is present (key)")).clone();
for i in (0..=(threshold - 2)).rev() {
if !blst_sk_mul_n_check(&mut y, &y, &id.scalar) {
return Err(Error::ZeroId);
}
let mut scalar = blst_scalar::default();
blst_scalar_from_fr(&mut scalar, y.as_ptr());
Ok((
id,
bls::SecretKey::from_point(SecretKey::from_scalar_unchecked(scalar)),
))
assert!(blst_sk_add_n_check(&mut y, &y, msk[i as usize]));
}
Ok((
id,
bls::SecretKey::from_point(mem::transmute::<blst_scalar, SecretKey>(y)),
))
})
.collect()
}
Expand All @@ -134,42 +117,40 @@ pub fn combine_signatures(signatures: &[Signature], ids: &[KeyId]) -> Result<Sig
.map(|sig| sig.point().cloned().ok_or(Error::InvalidSignature))
.collect::<Result<Vec<_>, _>>()?;

// intermediates.
let mut ifr = blst_fr::default();
let mut is = blst_scalar::default();
let mut intermediate = blst_scalar::default();

let zero = unsafe {
blst_fr_from_uint64(&mut ifr, &0);
ifr
};

let mut numerator = ids[0].clone().fr;
let mut numerator = ids[0].clone().scalar;
unsafe {
for id in &ids[1..] {
blst_fr_mul(&mut numerator, &numerator, &id.fr);
if !blst_sk_mul_n_check(&mut numerator, &numerator, &id.scalar) {
return Err(Error::ZeroId);
}
}
}
if numerator == zero {
return Err(Error::ZeroId);
}

let mut d = Vec::with_capacity(ids.len() * 32);
unsafe {
for id_i in ids {
let mut denominator = id_i.fr;
let mut denominator = id_i.scalar.clone();
for id_j in ids.iter() {
if id_i as *const KeyId != id_j as *const KeyId {
blst_fr_sub(&mut ifr, &id_j.fr, &id_i.fr);
if ifr == zero {
if !blst_sk_sub_n_check(&mut intermediate, &id_j.scalar, &id_i.scalar) {
return Err(Error::RepeatedId);
}
blst_fr_mul(&mut denominator, &denominator, &ifr);
assert!(blst_sk_mul_n_check(
&mut denominator,
&denominator,
&intermediate
));
}
}
blst_fr_inverse(&mut denominator, &denominator);
blst_fr_mul(&mut ifr, &denominator, &numerator);
blst_scalar_from_fr(&mut is, &ifr);
d.extend(is.b);
blst_sk_inverse(&mut denominator, &denominator);
assert!(blst_sk_mul_n_check(
&mut intermediate,
&denominator,
&numerator
));
d.extend(&intermediate.b);
}
}

Expand Down
Loading

0 comments on commit 120fd23

Please sign in to comment.