Skip to content

Commit

Permalink
chore(code/starknet): Change signature scheme from ECDSA to Ed25519 (#…
Browse files Browse the repository at this point in the history
…871)

* chore(code/starknet): Change signature scheme from ECDSA to Ed25519

* Fix MBT test

* Remove dead code
  • Loading branch information
romac authored Feb 21, 2025
1 parent 486f9cf commit 52ee8df
Show file tree
Hide file tree
Showing 14 changed files with 160 additions and 245 deletions.
1 change: 1 addition & 0 deletions code/Cargo.lock

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

7 changes: 2 additions & 5 deletions code/crates/network/test/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use core::fmt;
use std::time::{Duration, SystemTime, UNIX_EPOCH};

use libp2p_identity::{ecdsa, PeerId};
use libp2p_identity::PeerId;
use malachitebft_config::TransportProtocol;
use malachitebft_metrics::SharedRegistry;
use malachitebft_network::{
Expand Down Expand Up @@ -139,10 +139,7 @@ impl<const N: usize> Test<N> {
);
std::array::from_fn(|_| {
let privkey = PrivateKey::generate(&mut rng);
let pk_bytes = privkey.inner().to_bytes_be();
let secret_key = ecdsa::SecretKey::try_from_bytes(pk_bytes).unwrap();
let ecdsa_keypair = ecdsa::Keypair::from(secret_key);
Keypair::from(ecdsa_keypair)
Keypair::ed25519_from_bytes(privkey.inner().to_bytes()).unwrap()
})
}

Expand Down
6 changes: 5 additions & 1 deletion code/crates/signing-ed25519/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ impl Keypair for PrivateKey {
}
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct PublicKey(
Expand All @@ -174,6 +174,10 @@ impl PublicKey {
self.0.as_bytes()
}

pub fn from_bytes(bytes: [u8; 32]) -> Self {
Self(ed25519_consensus::VerificationKey::try_from(bytes).unwrap())
}

pub fn verify(&self, msg: &[u8], signature: &Signature) -> Result<(), signature::Error> {
self.0
.verify(signature.inner(), msg)
Expand Down
21 changes: 16 additions & 5 deletions code/crates/starknet/host/src/codec.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use bytes::Bytes;
use malachitebft_app::streaming::StreamId;
use malachitebft_starknet_p2p_types::Signature;
use malachitebft_starknet_p2p_types::{Felt, FeltExt, Signature};
use prost::Message;

use malachitebft_codec::Codec;
Expand Down Expand Up @@ -350,7 +350,7 @@ pub fn decode_consensus_message(
proto: proto::Vote,
) -> Result<SignedConsensusMsg<MockContext>, ProtoError> {
let vote = Vote::from_proto(proto)?;
let signature = p2p::Signature::dummy();
let signature = p2p::Signature::test();

Ok(SignedConsensusMsg::Vote(SignedVote::new(vote, signature)))
}
Expand Down Expand Up @@ -418,6 +418,17 @@ where
}
}

pub fn encode_signature(_signature: &Signature) -> Result<proto::ConsensusSignature, ProtoError> {
Ok(proto::ConsensusSignature {
r: Some(Felt::ONE.to_proto()?),
s: Some(Felt::ONE.to_proto()?),
})
}

pub fn decode_signature(_signature: proto::ConsensusSignature) -> Result<Signature, ProtoError> {
Ok(Signature::test())
}

pub fn decode_aggregated_signature(
signature: proto::sync::AggregatedSignature,
) -> Result<AggregatedSignature<MockContext>, ProtoError> {
Expand All @@ -430,7 +441,7 @@ pub fn decode_aggregated_signature(
.ok_or_else(|| {
ProtoError::missing_field::<proto::sync::CommitSignature>("signature")
})
.and_then(p2p::Signature::from_proto)?;
.and_then(decode_signature)?;

let address = s
.validator_address
Expand All @@ -454,7 +465,7 @@ pub fn encode_aggregate_signature(
.iter()
.map(|s| {
let validator_address = s.address.to_proto()?;
let signature = s.signature.to_proto()?;
let signature = encode_signature(&s.signature)?;

Ok(proto::sync::CommitSignature {
validator_address: Some(validator_address),
Expand Down Expand Up @@ -601,7 +612,7 @@ pub(crate) fn encode_vote(vote: &SignedVote<MockContext>) -> Result<proto::Vote,
}

pub(crate) fn decode_vote(msg: proto::Vote) -> Option<SignedVote<MockContext>> {
let signature = Signature::dummy();
let signature = Signature::test();
let vote = Vote::from_proto(msg).ok()?;
Some(SignedVote::new(vote, signature))
}
8 changes: 5 additions & 3 deletions code/crates/starknet/host/src/host/starknet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ impl Host for StarknetHost {
height,
round,
self.address,
self.private_key,
self.private_key.clone(),
self.params,
deadline,
self.mempool.clone(),
Expand Down Expand Up @@ -151,7 +151,7 @@ impl Host for StarknetHost {

/// Sign a message hash
async fn sign(&self, message: Self::MessageHash) -> Self::Signature {
self.private_key.sign(&message.as_felt())
self.private_key.sign(message.as_bytes().as_slice())
}

/// Validates the signature field of a message. If None returns false.
Expand All @@ -161,7 +161,9 @@ impl Host for StarknetHost {
signature: &Self::Signature,
public_key: &Self::PublicKey,
) -> bool {
public_key.verify(&hash.as_felt(), signature)
public_key
.verify(hash.as_bytes().as_slice(), signature)
.is_ok()
}

/// Update the Context about which decision has been made. It is responsible for pinging any
Expand Down
14 changes: 5 additions & 9 deletions code/crates/starknet/host/src/node.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::path::PathBuf;

use libp2p_identity::ecdsa;
use ractor::async_trait;
use rand::{CryptoRng, RngCore};
use serde::{Deserialize, Serialize};
Expand All @@ -12,7 +11,7 @@ use malachitebft_app::{Node, NodeHandle};
use malachitebft_config::Config;
use malachitebft_core_types::VotingPower;
use malachitebft_engine::node::NodeRef;
use malachitebft_starknet_p2p_types::EcdsaProvider;
use malachitebft_starknet_p2p_types::Ed25519Provider;

use crate::spawn::spawn_node_actor;
use crate::types::{Address, Height, MockContext, PrivateKey, PublicKey, Validator, ValidatorSet};
Expand Down Expand Up @@ -83,7 +82,7 @@ impl Node for StarknetNode {
type Context = MockContext;
type Genesis = Genesis;
type PrivateKeyFile = PrivateKeyFile;
type SigningProvider = EcdsaProvider;
type SigningProvider = Ed25519Provider;
type NodeHandle = Handle;

fn get_home_dir(&self) -> PathBuf {
Expand All @@ -106,10 +105,7 @@ impl Node for StarknetNode {
}

fn get_keypair(&self, pk: PrivateKey) -> Keypair {
let pk_bytes = pk.inner().to_bytes_be();
let secret_key = ecdsa::SecretKey::try_from_bytes(pk_bytes).unwrap();
let ecdsa_keypair = ecdsa::Keypair::from(secret_key);
Keypair::from(ecdsa_keypair)
Keypair::ed25519_from_bytes(pk.inner().to_bytes()).unwrap()
}

fn load_private_key(&self, file: Self::PrivateKeyFile) -> PrivateKey {
Expand All @@ -126,7 +122,7 @@ impl Node for StarknetNode {
}

fn get_signing_provider(&self, private_key: PrivateKey) -> Self::SigningProvider {
EcdsaProvider::new(private_key)
Self::SigningProvider::new(private_key)
}

fn load_genesis(&self) -> std::io::Result<Self::Genesis> {
Expand Down Expand Up @@ -213,7 +209,7 @@ fn test_starknet_node() {
file::save_priv_validator_key(
&node,
&node.private_key_file(),
&PrivateKeyFile::from(priv_keys[0]),
&PrivateKeyFile::from(priv_keys[0].clone()),
)
.unwrap();

Expand Down
16 changes: 6 additions & 10 deletions code/crates/starknet/host/src/spawn.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::path::{Path, PathBuf};
use std::time::Duration;

use libp2p_identity::ecdsa;
use tokio::task::JoinHandle;
use tracing::warn;

Expand All @@ -18,7 +17,7 @@ use malachitebft_engine::util::events::TxEvent;
use malachitebft_engine::wal::{Wal, WalRef};
use malachitebft_metrics::{Metrics, SharedRegistry};
use malachitebft_network::Keypair;
use malachitebft_starknet_p2p_types::EcdsaProvider;
use malachitebft_starknet_p2p_types::Ed25519Provider;
use malachitebft_sync as sync;
use malachitebft_test_mempool::Config as MempoolNetworkConfig;

Expand Down Expand Up @@ -46,7 +45,7 @@ pub async fn spawn_node_actor(
let registry = SharedRegistry::global().with_moniker(cfg.moniker.as_str());
let metrics = Metrics::register(&registry);
let address = Address::from_public_key(private_key.public_key());
let signing_provider = EcdsaProvider::new(private_key);
let signing_provider = Ed25519Provider::new(private_key.clone());

// Spawn mempool and its gossip layer
let mempool_network = spawn_mempool_network_actor(&cfg, &private_key, &registry, &span).await;
Expand Down Expand Up @@ -156,7 +155,7 @@ async fn spawn_consensus_actor(
address: Address,
ctx: MockContext,
cfg: NodeConfig,
signing_provider: EcdsaProvider,
signing_provider: Ed25519Provider,
network: NetworkRef<MockContext>,
host: HostRef<MockContext>,
wal: WalRef<MockContext>,
Expand Down Expand Up @@ -256,11 +255,8 @@ async fn spawn_network_actor(
.unwrap()
}

fn make_keypair(private_key: &PrivateKey) -> Keypair {
let pk_bytes = private_key.inner().to_bytes_be();
let secret_key = ecdsa::SecretKey::try_from_bytes(pk_bytes).unwrap();
let ecdsa_keypair = ecdsa::Keypair::from(secret_key);
Keypair::from(ecdsa_keypair)
fn make_keypair(pk: &PrivateKey) -> Keypair {
Keypair::ed25519_from_bytes(pk.inner().to_bytes()).unwrap()
}

async fn spawn_mempool_actor(
Expand Down Expand Up @@ -335,7 +331,7 @@ async fn spawn_host_actor(
mock_params,
mempool.clone(),
*address,
*private_key,
private_key.clone(),
initial_validator_set.clone(),
);

Expand Down
1 change: 1 addition & 0 deletions code/crates/starknet/p2p-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ publish = false
malachitebft-core-types.workspace = true
malachitebft-proto.workspace = true
malachitebft-starknet-p2p-proto.workspace = true
malachitebft-signing-ed25519 = { workspace = true, features = ["serde", "rand"] }

starknet-core.workspace = true
starknet-crypto.workspace = true
Expand Down
7 changes: 5 additions & 2 deletions code/crates/starknet/p2p-types/src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ impl Address {
impl fmt::Display for Address {
#[cfg_attr(coverage_nightly, coverage(off))]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
for byte in self.0.as_bytes().iter() {
write!(f, "{:02X}", byte)?;
}
Ok(())
}
}

Expand Down Expand Up @@ -57,7 +60,7 @@ impl Protobuf for Address {

fn to_proto(&self) -> Result<Self::Proto, ProtoError> {
Ok(p2p_proto::Address {
elements: Bytes::copy_from_slice(&self.0.as_bytes()),
elements: Bytes::copy_from_slice(self.0.as_bytes().as_slice()),
})
}
}
6 changes: 4 additions & 2 deletions code/crates/starknet/p2p-types/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ use bytes::Bytes;

use malachitebft_core_types::{Context, NilOrVal, Round, ValidatorSet as _};

use crate::{Address, Ecdsa, Hash, Height, Proposal, ProposalPart, Validator, ValidatorSet, Vote};
use crate::{
Address, Ed25519, Hash, Height, Proposal, ProposalPart, Validator, ValidatorSet, Vote,
};

mod impls;

Expand All @@ -25,7 +27,7 @@ impl Context for MockContext {
type Value = Hash;
type Vote = Vote;
type Extension = Bytes;
type SigningScheme = Ecdsa;
type SigningScheme = Ed25519;

fn select_proposer<'a>(
&self,
Expand Down
4 changes: 2 additions & 2 deletions code/crates/starknet/p2p-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ mod context;
pub use context::MockContext;

mod felt;
pub use felt::Felt;
pub use felt::{Felt, FeltExt};

mod address;
pub use address::Address;
Expand Down Expand Up @@ -49,4 +49,4 @@ mod streaming;
pub use streaming::{StreamContent, StreamMessage};

mod signing;
pub use signing::{Ecdsa, EcdsaProvider, PrivateKey, PublicKey, Signature};
pub use signing::{Ed25519, Ed25519Provider, PrivateKey, PublicKey, Signature};
Loading

0 comments on commit 52ee8df

Please sign in to comment.