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
2 changes: 1 addition & 1 deletion Cargo.lock

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

2 changes: 1 addition & 1 deletion bin/ethlambda/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ use cli::CliOptions;
use ethlambda_blockchain::MILLISECONDS_PER_SLOT;
use ethlambda_blockchain::block_builder::ProposerConfig;
use ethlambda_blockchain::key_manager::ValidatorKeyPair;
use ethlambda_crypto::signature::ValidatorSecretKey;
use ethlambda_network_api::{InitBlockChain, InitP2P, ToBlockChainToP2PRef, ToP2PToBlockChainRef};
use ethlambda_p2p::{
Bootnode, P2P, PeerId, SwarmConfig, attestation_subscription_subnets, build_swarm, parse_enrs,
Expand All @@ -44,7 +45,6 @@ use ethlambda_types::primitives::{H256, HashTreeRoot as _};
use ethlambda_types::{
aggregator::AggregatorController,
genesis::GenesisConfig,
signature::ValidatorSecretKey,
state::{State, ValidatorPubkeyBytes},
};
use eyre::WrapErr;
Expand Down
11 changes: 7 additions & 4 deletions crates/blockchain/src/aggregation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ use std::collections::{HashMap, HashSet};
use std::time::{Duration, Instant, SystemTime};

use ethlambda_crypto::aggregate_mixed;
use ethlambda_crypto::signature::{ValidatorPublicKey, ValidatorSignature};
use ethlambda_storage::Store;
use ethlambda_types::{
ShortRoot,
attestation::{AggregationBits, AttestationData, HashedAttestationData},
block::{ByteList512KiB, SingleMessageAggregate},
primitives::H256,
signature::{ValidatorPublicKey, ValidatorSignature},
state::Validator,
};
use spawned_concurrency::message::Message;
Expand Down Expand Up @@ -425,7 +425,7 @@ fn resolve_job(
let Some(validator) = validators.get(*vid as usize) else {
continue;
};
let Ok(pubkey) = validator.get_attestation_pubkey() else {
let Ok(pubkey) = ValidatorPublicKey::from_bytes(&validator.attestation_pubkey) else {
continue;
};
raw_by_id.insert(*vid, (pubkey, sig.clone()));
Expand Down Expand Up @@ -492,7 +492,10 @@ fn resolve_child_pubkeys(
let participant_ids: Vec<u64> = proof.participant_indices().collect();
let child_pubkeys: Vec<ValidatorPublicKey> = participant_ids
.iter()
.filter_map(|&vid| validators.get(vid as usize)?.get_attestation_pubkey().ok())
.filter_map(|&vid| {
let v = validators.get(vid as usize)?;
ValidatorPublicKey::from_bytes(&v.attestation_pubkey).ok()
})
.collect();
if child_pubkeys.len() != participant_ids.len() {
warn!(
Expand Down Expand Up @@ -796,7 +799,7 @@ mod tests {
/// never checks signature validity, only that it clones and carries a
/// resolvable id — mirrors `ethlambda_storage::store::tests::make_dummy_sig`.
fn dummy_sig() -> ValidatorSignature {
use ethlambda_types::signature::LeanSignatureScheme;
use ethlambda_crypto::signature::LeanSignatureScheme;
use leansig::{serialization::Serializable, signature::SignatureScheme};
use rand::{SeedableRng, rngs::StdRng};

Expand Down
8 changes: 4 additions & 4 deletions crates/blockchain/src/block_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use std::{
time::Instant,
};

use ethlambda_crypto::aggregate_proofs;
use ethlambda_crypto::{aggregate_proofs, signature::ValidatorPublicKey};
use ethlambda_state_transition::{
attestation_data_matches_chain, justified_slots_ops, process_block, process_slots,
slot_is_justifiable_after,
Expand Down Expand Up @@ -657,11 +657,11 @@ fn compact_attestations(
let pubkeys = proof
.participant_indices()
.map(|vid| {
head_state
let validator = head_state
.validators
.get(vid as usize)
.ok_or(StoreError::InvalidValidatorIndex)?
.get_attestation_pubkey()
.ok_or(StoreError::InvalidValidatorIndex)?;
ValidatorPublicKey::from_bytes(&validator.attestation_pubkey)
.map_err(|_| StoreError::PubkeyDecodingFailed(vid))
})
.collect::<Result<Vec<_>, _>>()?;
Expand Down
2 changes: 1 addition & 1 deletion crates/blockchain/src/key_manager.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::collections::HashMap;
use std::time::Instant;

use ethlambda_crypto::signature::{ValidatorSecretKey, ValidatorSignature};
use ethlambda_types::{
attestation::{AttestationData, XmssSignature},
primitives::{H256, HashTreeRoot as _},
signature::{ValidatorSecretKey, ValidatorSignature},
};
use tracing::{info, warn};

Expand Down
9 changes: 6 additions & 3 deletions crates/blockchain/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::collections::{HashMap, HashSet, VecDeque};
use std::time::{Duration, Instant, SystemTime};

use ethlambda_crypto::signature::{ValidatorPublicKey, ValidatorSignature};
use ethlambda_network_api::{BlockChainToP2PRef, InitP2P};
use ethlambda_state_transition::is_proposer;
use ethlambda_storage::{ALL_TABLES, Store};
Expand All @@ -10,7 +11,6 @@ use ethlambda_types::{
attestation::{SignedAggregatedAttestation, SignedAttestation},
block::{ByteList512KiB, MultiMessageAggregate, SignedBlock},
primitives::{H256, HashTreeRoot as _},
signature::{ValidatorPublicKey, ValidatorSignature},
};

use crate::aggregation::{
Expand Down Expand Up @@ -763,7 +763,10 @@ impl BlockChainServer {
// Decode the proposer's proposal pubkey once and reuse it both for the
// singleton single-message aggregate wrap and for the multi-message
// aggregate merge inputs.
let Ok(proposer_pubkey) = proposer_validator.get_proposal_pubkey().inspect_err(
let Ok(proposer_pubkey) = ValidatorPublicKey::from_bytes(
&proposer_validator.proposal_pubkey,
)
.inspect_err(
|err| error!(%slot, %validator_id, %err, "Failed to decode proposer proposal pubkey"),
) else {
metrics::inc_block_building_failures();
Expand Down Expand Up @@ -802,7 +805,7 @@ impl BlockChainServer {
resolve_failed = true;
break;
};
match validator.get_attestation_pubkey() {
match ValidatorPublicKey::from_bytes(&validator.attestation_pubkey) {
Ok(pk) => pubkeys.push(pk),
Err(err) => {
error!(%slot, %validator_id, vid, %err, "Failed to decode attestation pubkey");
Expand Down
13 changes: 9 additions & 4 deletions crates/blockchain/src/reaggregate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

use std::collections::HashSet;

use ethlambda_crypto::signature::ValidatorPublicKey;
use ethlambda_storage::Store;
use ethlambda_types::{
attestation::{
Expand All @@ -32,7 +33,6 @@ use ethlambda_types::{
},
block::{SignedBlock, SingleMessageAggregate},
primitives::{H256, HashTreeRoot as _},
signature::ValidatorPublicKey,
};
use tracing::{debug, warn};

Expand Down Expand Up @@ -83,7 +83,9 @@ pub fn reaggregate_from_block(
warn!(vid, "Reaggregation aborted: participant out of range");
return Vec::new();
}
let Ok(pk) = validators[vid as usize].get_attestation_pubkey() else {
let Ok(pk) =
ValidatorPublicKey::from_bytes(&validators[vid as usize].attestation_pubkey)
else {
warn!(vid, "Reaggregation aborted: bad attestation pubkey");
return Vec::new();
};
Expand All @@ -94,7 +96,8 @@ pub fn reaggregate_from_block(
if block.proposer_index >= num_validators {
return Vec::new();
}
let Ok(proposer_pubkey) = validators[block.proposer_index as usize].get_proposal_pubkey()
let Ok(proposer_pubkey) =
ValidatorPublicKey::from_bytes(&validators[block.proposer_index as usize].proposal_pubkey)
else {
return Vec::new();
};
Expand Down Expand Up @@ -161,7 +164,9 @@ pub fn reaggregate_from_block(
bad = true;
break;
}
match validators[vid as usize].get_attestation_pubkey() {
match ValidatorPublicKey::from_bytes(
&validators[vid as usize].attestation_pubkey,
) {
Ok(pk) => pubkeys.push(pk),
Err(_) => {
bad = true;
Expand Down
18 changes: 8 additions & 10 deletions crates/blockchain/src/store.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::collections::{HashMap, HashSet};

use ethlambda_crypto::signature::{ValidatorPublicKey, ValidatorSignature};
use ethlambda_state_transition::{is_proposer, slot_is_justifiable_after};
use ethlambda_storage::{ForkCheckpoints, Store};
use ethlambda_types::{
Expand All @@ -11,7 +12,6 @@ use ethlambda_types::{
block::{Block, BlockHeader, SignedBlock, SingleMessageAggregate},
checkpoint::Checkpoint,
primitives::{H256, HashTreeRoot as _},
signature::{ValidatorPublicKey, ValidatorSignature},
state::{HISTORICAL_ROOTS_LIMIT, State},
};
use tracing::{info, trace, warn};
Expand Down Expand Up @@ -418,9 +418,10 @@ pub fn on_gossip_attestation(
if validator_id >= target_state.validators.len() as u64 {
return Err(StoreError::InvalidValidatorIndex);
}
let validator_pubkey = target_state.validators[validator_id as usize]
.get_attestation_pubkey()
.map_err(|_| StoreError::PubkeyDecodingFailed(validator_id))?;
let validator_pubkey = ValidatorPublicKey::from_bytes(
&target_state.validators[validator_id as usize].attestation_pubkey,
)
.map_err(|_| StoreError::PubkeyDecodingFailed(validator_id))?;

// Verify the validator's XMSS signature
let slot: u32 = attestation.data.slot.try_into().expect("slot exceeds u32");
Expand Down Expand Up @@ -513,8 +514,7 @@ fn on_gossip_aggregated_attestation_core(
let pubkeys: Vec<_> = participant_indices
.iter()
.map(|&vid| {
validators[vid as usize]
.get_attestation_pubkey()
ValidatorPublicKey::from_bytes(&validators[vid as usize].attestation_pubkey)
.map_err(|_| StoreError::PubkeyDecodingFailed(vid))
})
.collect::<Result<_, _>>()?;
Expand Down Expand Up @@ -1142,8 +1142,7 @@ pub fn verify_block_signatures(
let validator = validators
.get(vid as usize)
.ok_or(StoreError::InvalidValidatorIndex)?;
let pk = validator
.get_attestation_pubkey()
let pk = ValidatorPublicKey::from_bytes(&validator.attestation_pubkey)
.map_err(|_| StoreError::PubkeyDecodingFailed(vid))?;
pubkeys.push(pk);
}
Expand All @@ -1156,8 +1155,7 @@ pub fn verify_block_signatures(
let proposer_validator = validators
.get(block.proposer_index as usize)
.ok_or(StoreError::InvalidValidatorIndex)?;
let proposer_pubkey = proposer_validator
.get_proposal_pubkey()
let proposer_pubkey = ValidatorPublicKey::from_bytes(&proposer_validator.proposal_pubkey)
.map_err(|_| StoreError::PubkeyDecodingFailed(block.proposer_index))?;
pubkeys_per_component.push(vec![proposer_pubkey]);
let block_slot_u32 =
Expand Down
12 changes: 6 additions & 6 deletions crates/common/crypto/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
use std::sync::Once;

use ethlambda_types::{
block::ByteList512KiB,
primitives::H256,
signature::{ValidatorPublicKey, ValidatorSignature},
};
use ethlambda_types::{block::ByteList512KiB, primitives::H256};

use crate::signature::{ValidatorPublicKey, ValidatorSignature};
use lean_multisig::{
MultiMessageAggregateSignature as LMType2, ProofError,
SingleMessageAggregateSignature as LMType1, aggregate_single_message_signatures,
Expand All @@ -14,6 +12,8 @@ use lean_multisig::{
use leansig_wrapper::{XmssPublicKey as LeanSigPubKey, XmssSignature as LeanSigSignature};
use thiserror::Error;

pub mod signature;

#[cfg(feature = "shadow-integration")]
pub mod shadow_cost;

Expand Down Expand Up @@ -508,7 +508,7 @@ pub fn split_type_2_by_message(
#[cfg(test)]
mod tests {
use super::*;
use ethlambda_types::signature::LeanSignatureScheme;
use crate::signature::LeanSignatureScheme;
use leansig::{serialization::Serializable, signature::SignatureScheme};
use rand::{SeedableRng, rngs::StdRng};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
//! Validator XMSS signatures, public/secret keys, and the leansig-backed
//! primitives behind them.

use std::ops::Range;

use ethlambda_types::primitives::H256;
use leansig::{
serialization::Serializable,
signature::{SignatureScheme, SignatureSchemeSecretKey as _, SigningError},
};

use crate::primitives::H256;

/// The XMSS signature scheme used for validator signatures.
///
/// This is a post-quantum secure signature scheme based on hash functions.
Expand All @@ -25,11 +27,6 @@ pub type LeanSigSecretKey = <LeanSignatureScheme as SignatureScheme>::SecretKey;

pub type Signature = LeanSigSignature;

/// Size of an XMSS signature in bytes.
///
/// Computed from: path(32*8*4) + rho(7*4) + hashes(46*8*4) + ssz_offsets(3*4) = 2536
pub const SIGNATURE_SIZE: usize = 2536;

/// Error returned when parsing signature or key bytes fails.
#[derive(Debug, Clone, thiserror::Error)]
#[error("signature parse error: {0}")]
Expand Down
3 changes: 1 addition & 2 deletions crates/common/test-fixtures/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ use ethlambda_types::{
attestation::{
AggregatedAttestation as DomainAggregatedAttestation,
AggregationBits as DomainAggregationBits, AttestationData as DomainAttestationData,
XmssSignature,
SIGNATURE_SIZE, XmssSignature,
},
block::{Block as DomainBlock, BlockBody as DomainBlockBody},
checkpoint::Checkpoint as DomainCheckpoint,
primitives::H256,
signature::SIGNATURE_SIZE,
state::{
ChainConfig, JustificationValidators, JustifiedSlots, State, Validator as DomainValidator,
ValidatorPubkeyBytes,
Expand Down
2 changes: 0 additions & 2 deletions crates/common/types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ thiserror.workspace = true
serde.workspace = true
hex.workspace = true

leansig.workspace = true

libssz.workspace = true
libssz-derive.workspace = true
libssz-merkle.workspace = true
Expand Down
8 changes: 7 additions & 1 deletion crates/common/types/src/attestation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use crate::{
block::SingleMessageAggregate,
checkpoint::Checkpoint,
primitives::{H256, HashTreeRoot as _},
signature::SIGNATURE_SIZE,
};

/// Validator specific attestation wrapping shared attestation data.
Expand Down Expand Up @@ -55,6 +54,13 @@ pub struct SignedAttestation {
pub signature: XmssSignature,
}

/// Size of an XMSS signature in bytes.
///
/// Computed from: path(32*8*4) + rho(7*4) + hashes(46*8*4) + ssz_offsets(3*4) = 2536.
/// This is the SSZ wire size, independent of the `leansig` scheme itself, so it
/// lives here (leansig-free) rather than in `ethlambda-crypto`.
pub const SIGNATURE_SIZE: usize = 2536;

/// XMSS signature as a fixed-length byte vector (`SIGNATURE_SIZE` bytes).
pub type XmssSignature = SszVector<u8, SIGNATURE_SIZE>;

Expand Down
1 change: 0 additions & 1 deletion crates/common/types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ pub mod checkpoint;
pub mod constants;
pub mod genesis;
pub mod primitives;
pub mod signature;
pub mod state;

/// Display helper for truncated root hashes (8 hex chars)
Expand Down
11 changes: 0 additions & 11 deletions crates/common/types/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use crate::{
block::{Block, BlockBody, BlockHeader},
checkpoint::Checkpoint,
primitives::{self, H256},
signature::{SignatureParseError, ValidatorPublicKey},
};

// Convenience trait for calling hash_tree_root() without a hasher argument
Expand Down Expand Up @@ -85,16 +84,6 @@ where
serializer.serialize_str(&hex::encode(pubkey))
}

impl Validator {
pub fn get_attestation_pubkey(&self) -> Result<ValidatorPublicKey, SignatureParseError> {
ValidatorPublicKey::from_bytes(&self.attestation_pubkey)
}

pub fn get_proposal_pubkey(&self) -> Result<ValidatorPublicKey, SignatureParseError> {
ValidatorPublicKey::from_bytes(&self.proposal_pubkey)
}
}

pub type ValidatorPubkeyBytes = [u8; 52];

impl State {
Expand Down
Loading