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
680 changes: 185 additions & 495 deletions Cargo.lock

Large diffs are not rendered by default.

15 changes: 13 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,19 @@ prometheus = "0.14"

clap = { version = "4.3", features = ["derive", "env"] }

# XMSS signatures
leansig = { git = "https://github.com/leanEthereum/leanSig", branch = "devnet4" }
# XMSS signatures + recursive aggregation (leanVM).
# leanVM's `main` internalized XMSS (dropping the external leanSig dependency)
# and reworked the aggregation API (see "Xmss api rework").
# Pinned to the current `main` HEAD (branch `main`, commit a73ab11) for
# reproducible builds; bump the rev to track main forward.
xmss = { git = "https://github.com/leanEthereum/leanVM.git", rev = "a73ab114721441aa833384e791f3b83801257456" }
rec_aggregation = { git = "https://github.com/leanEthereum/leanVM.git", rev = "a73ab114721441aa833384e791f3b83801257456" }

# SSZ codec used by leanVM's xmss pubkey/signature types (ethereum_ssz, not libssz).
ssz = { package = "ethereum_ssz", version = "0.10" }

# Secret-key (de)serialization for the leanVM xmss key format.
postcard = { version = "1.1.3", features = ["alloc"] }

# SSZ implementation
libssz = "0.2.2"
Expand Down
12 changes: 6 additions & 6 deletions bin/ethlambda/src/checkpoint_sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,25 +415,25 @@ mod tests {

fn create_test_validator() -> Validator {
Validator {
attestation_pubkey: [1u8; 52],
proposal_pubkey: [11u8; 52],
attestation_pubkey: [1u8; 32],
proposal_pubkey: [11u8; 32],
index: 0,
}
}

fn create_different_validator() -> Validator {
Validator {
attestation_pubkey: [2u8; 52],
proposal_pubkey: [22u8; 52],
attestation_pubkey: [2u8; 32],
proposal_pubkey: [22u8; 32],
index: 0,
}
}

fn create_validators_with_indices(count: usize) -> Vec<Validator> {
(0..count)
.map(|i| Validator {
attestation_pubkey: [i as u8 + 1; 52],
proposal_pubkey: [i as u8 + 101; 52],
attestation_pubkey: [i as u8 + 1; 32],
proposal_pubkey: [i as u8 + 101; 32],
index: i as u64,
})
.collect()
Expand Down
11 changes: 8 additions & 3 deletions bin/ethlambda/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -479,8 +479,8 @@ fn read_bootnodes(bootnodes_path: impl AsRef<Path>) -> eyre::Result<Vec<Bootnode
#[derive(Debug, Deserialize, Clone)]
struct AnnotatedValidator {
index: u64,
/// Parsed for hex-format validation only; not cross-checked against the
/// loaded secret key since leansig doesn't expose any pk getters.
/// Parsed for hex-format validation only; not currently cross-checked
/// against the loaded secret key's derived public key.
#[serde(rename = "pubkey_hex", deserialize_with = "deser_pubkey_hex")]
_pubkey_hex: ValidatorPubkeyBytes,
privkey_file: PathBuf,
Expand All @@ -496,7 +496,12 @@ where
let pubkey: ValidatorPubkeyBytes = hex::decode(&value)
.map_err(|_| D::Error::custom("ValidatorPubkey value is not valid hex"))?
.try_into()
.map_err(|_| D::Error::custom("ValidatorPubkey length != 52"))?;
.map_err(|_| {
D::Error::custom(format!(
"ValidatorPubkey length != {}",
ethlambda_types::signature::PUBLIC_KEY_SIZE
))
})?;
Ok(pubkey)
}

Expand Down
1 change: 0 additions & 1 deletion crates/blockchain/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ hex = { workspace = true }
libssz.workspace = true
libssz-types.workspace = true
datatest-stable = "0.3.3"
leansig.workspace = true
rand.workspace = true

[[test]]
Expand Down
29 changes: 10 additions & 19 deletions crates/blockchain/src/aggregation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -784,31 +784,22 @@ mod tests {
fn make_validators(n: usize) -> Vec<Validator> {
(0..n)
.map(|i| Validator {
attestation_pubkey: [i as u8; 52],
proposal_pubkey: [i as u8; 52],
attestation_pubkey: [i as u8; 32],
proposal_pubkey: [i as u8; 32],
index: i as u64,
})
.collect()
}

/// A cheap-but-real XMSS signature (tiny lifetime, cached) for tests that
/// only need `ValidatorSignature::from_bytes` to succeed. `resolve_job`
/// never checks signature validity, only that it clones and carries a
/// resolvable id — mirrors `ethlambda_storage::store::tests::make_dummy_sig`.
/// A structurally valid XMSS signature for tests that only need
/// `ValidatorSignature::from_bytes` to succeed. `resolve_job` never checks
/// signature validity, only that it clones and carries a resolvable id —
/// mirrors `ethlambda_storage::store::tests::make_dummy_sig`. An all-zero
/// blob decodes as a valid (unverifiable) signature.
fn dummy_sig() -> ValidatorSignature {
use ethlambda_types::signature::LeanSignatureScheme;
use leansig::{serialization::Serializable, signature::SignatureScheme};
use rand::{SeedableRng, rngs::StdRng};

static CACHED_SIG: std::sync::LazyLock<Vec<u8>> = std::sync::LazyLock::new(|| {
let mut rng = StdRng::seed_from_u64(42);
let lifetime = 1 << 5; // small for speed
let (_pk, sk) = LeanSignatureScheme::key_gen(&mut rng, 0, lifetime);
let sig = LeanSignatureScheme::sign(&sk, 0, &[0u8; 32]).unwrap();
sig.to_bytes()
});

ValidatorSignature::from_bytes(&CACHED_SIG).expect("cached test signature")
use ethlambda_types::signature::SIGNATURE_SIZE;
ValidatorSignature::from_bytes(&vec![0u8; SIGNATURE_SIZE])
.expect("all-zero test signature decodes")
}

/// A `HashedAttestationData` over default (all-zero) data for `resolve_job`
Expand Down
20 changes: 10 additions & 10 deletions crates/blockchain/src/block_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -973,8 +973,8 @@ mod tests {

let validators: Vec<_> = (0..NUM_VALIDATORS)
.map(|i| ethlambda_types::state::Validator {
attestation_pubkey: [i as u8; 52],
proposal_pubkey: [i as u8; 52],
attestation_pubkey: [i as u8; 32],
proposal_pubkey: [i as u8; 32],
index: i as u64,
})
.collect();
Expand Down Expand Up @@ -1133,8 +1133,8 @@ mod tests {

let validators: Vec<_> = (0..NUM_VALIDATORS)
.map(|i| ethlambda_types::state::Validator {
attestation_pubkey: [i as u8; 52],
proposal_pubkey: [i as u8; 52],
attestation_pubkey: [i as u8; 32],
proposal_pubkey: [i as u8; 32],
index: i as u64,
})
.collect();
Expand Down Expand Up @@ -1262,8 +1262,8 @@ mod tests {

let validators: Vec<_> = (0..NUM_VALIDATORS)
.map(|i| ethlambda_types::state::Validator {
attestation_pubkey: [i as u8; 52],
proposal_pubkey: [i as u8; 52],
attestation_pubkey: [i as u8; 32],
proposal_pubkey: [i as u8; 32],
index: i as u64,
})
.collect();
Expand Down Expand Up @@ -1566,8 +1566,8 @@ mod tests {

let validators: Vec<_> = (0..NUM_VALIDATORS)
.map(|i| ethlambda_types::state::Validator {
attestation_pubkey: [i as u8; 52],
proposal_pubkey: [i as u8; 52],
attestation_pubkey: [i as u8; 32],
proposal_pubkey: [i as u8; 32],
index: i as u64,
})
.collect();
Expand Down Expand Up @@ -1693,8 +1693,8 @@ mod tests {

let validators: Vec<_> = (0..NUM_VALIDATORS)
.map(|i| ethlambda_types::state::Validator {
attestation_pubkey: [i as u8; 52],
proposal_pubkey: [i as u8; 52],
attestation_pubkey: [i as u8; 32],
proposal_pubkey: [i as u8; 32],
index: i as u64,
})
.collect();
Expand Down
7 changes: 2 additions & 5 deletions crates/blockchain/src/reaggregate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,8 @@ pub fn reaggregate_from_block(
// Step 1: SNARK-split this attestation's component out of the block's
// merged multi-message aggregate proof.
let merged_bytes = signed_block.proof.proof_bytes();
let split_bytes = match ethlambda_crypto::split_type_2_by_message(
merged_bytes,
pubkeys_per_component.clone(),
&data_root,
) {
let split_bytes = match ethlambda_crypto::split_type_2_by_message(merged_bytes, &data_root)
{
Ok(bytes) => bytes,
Err(err) => {
debug!(%err, data_root = %ethlambda_types::ShortRoot(&data_root.0),
Expand Down
4 changes: 2 additions & 2 deletions crates/blockchain/state_transition/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -623,8 +623,8 @@ mod tests {
fn make_validators(n: usize) -> Vec<Validator> {
(0..n)
.map(|i| Validator {
attestation_pubkey: [i as u8; 52],
proposal_pubkey: [i as u8; 52],
attestation_pubkey: [i as u8; 32],
proposal_pubkey: [i as u8; 32],
index: i as u64,
})
.collect()
Expand Down
10 changes: 5 additions & 5 deletions crates/common/crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ version.workspace = true
[dependencies]
ethlambda-types.workspace = true

# rec_aggregation is leanVM's recursive XMSS aggregation prover/verifier;
# xmss provides the public-key/signature types its API consumes.
rec_aggregation.workspace = true
xmss.workspace = true

lean-multisig = { git = "https://github.com/leanEthereum/leanVM.git", rev = "e2592df" }
# leansig_wrapper provides XmssPublicKey/XmssSignature types used by lean-multisig's public API
leansig_wrapper = { git = "https://github.com/leanEthereum/leanVM.git", rev = "e2592df" }

leansig.workspace = true
thiserror.workspace = true
rand.workspace = true

Expand All @@ -26,3 +25,4 @@ shadow-integration = []

[dev-dependencies]
hex.workspace = true
ssz.workspace = true
Loading
Loading