From b486c6e81020d0df19832b2d968ce847289d41ba Mon Sep 17 00:00:00 2001 From: Bogdan Opanchuk Date: Sun, 20 Oct 2024 22:15:16 -0700 Subject: [PATCH] Supply the format from the session level --- examples/src/format.rs | 20 ++++++++ examples/src/lib.rs | 3 ++ examples/src/simple.rs | 52 ++++++++++---------- examples/src/simple_malicious.rs | 25 ++++++---- examples/tests/async.rs | 14 ++++-- manul/Cargo.toml | 1 + manul/benches/empty_rounds.rs | 35 +++++++++----- manul/src/protocol.rs | 2 +- manul/src/protocol/object_safe.rs | 23 +++++++-- manul/src/protocol/round.rs | 66 +++++++++++++------------- manul/src/session.rs | 5 +- manul/src/session/echo.rs | 10 ++-- manul/src/session/evidence.rs | 74 ++++++++++++++--------------- manul/src/session/message.rs | 41 +++++++--------- manul/src/session/session.rs | 79 +++++++++++++++++++++++++------ manul/src/testing/identity.rs | 7 +-- manul/src/testing/macros.rs | 21 +++++--- 17 files changed, 301 insertions(+), 177 deletions(-) create mode 100644 examples/src/format.rs diff --git a/examples/src/format.rs b/examples/src/format.rs new file mode 100644 index 0000000..2c9d6ae --- /dev/null +++ b/examples/src/format.rs @@ -0,0 +1,20 @@ +use manul::{ + protocol::{DeserializationError, LocalError}, + session::Format, +}; +use serde::{Deserialize, Serialize}; + +pub struct Bincode; + +impl Format for Bincode { + fn serialize(value: T) -> Result, LocalError> { + bincode::serde::encode_to_vec(value, bincode::config::standard()) + .map(|vec| vec.into()) + .map_err(|err| LocalError::new(err.to_string())) + } + + fn deserialize<'de, T: Deserialize<'de>>(bytes: &'de [u8]) -> Result { + bincode::serde::decode_borrowed_from_slice(bytes, bincode::config::standard()) + .map_err(|err| DeserializationError::new(err.to_string())) + } +} diff --git a/examples/src/lib.rs b/examples/src/lib.rs index c3aff76..066da06 100644 --- a/examples/src/lib.rs +++ b/examples/src/lib.rs @@ -1,6 +1,9 @@ extern crate alloc; +mod format; pub mod simple; #[cfg(test)] mod simple_malicious; + +pub use format::Bincode; diff --git a/examples/src/simple.rs b/examples/src/simple.rs index 51f1cfc..e07c443 100644 --- a/examples/src/simple.rs +++ b/examples/src/simple.rs @@ -36,6 +36,7 @@ impl ProtocolError for SimpleProtocolError { fn verify_messages_constitute_error( &self, + deserializer: &Deserializer, _echo_broadcast: &Option, direct_message: &DirectMessage, _echo_broadcasts: &BTreeMap, @@ -44,12 +45,12 @@ impl ProtocolError for SimpleProtocolError { ) -> Result<(), ProtocolValidationError> { match self { SimpleProtocolError::Round1InvalidPosition => { - let _message = direct_message.deserialize::()?; + let _message = direct_message.deserialize::(deserializer)?; // Message contents would be checked here Ok(()) } SimpleProtocolError::Round2InvalidPosition => { - let _r1_message = direct_message.deserialize::()?; + let _r1_message = direct_message.deserialize::(deserializer)?; let r1_echos_serialized = combined_echos .get(&RoundId::new(1)) .ok_or_else(|| LocalError::new("Could not find combined echos for Round 1"))?; @@ -57,7 +58,7 @@ impl ProtocolError for SimpleProtocolError { // Deserialize the echos let _r1_echos = r1_echos_serialized .iter() - .map(|echo| echo.deserialize::()) + .map(|echo| echo.deserialize::(deserializer)) .collect::, _>>()?; // Message contents would be checked here @@ -72,23 +73,13 @@ impl Protocol for SimpleProtocol { type ProtocolError = SimpleProtocolError; type CorrectnessProof = (); - fn serialize(value: T) -> Result, LocalError> { - bincode::serde::encode_to_vec(value, bincode::config::standard()) - .map(|vec| vec.into()) - .map_err(|err| LocalError::new(err.to_string())) - } - - fn deserialize<'de, T: Deserialize<'de>>(bytes: &'de [u8]) -> Result { - bincode::serde::decode_borrowed_from_slice(bytes, bincode::config::standard()) - .map_err(|err| DeserializationError::new(err.to_string())) - } - fn verify_direct_message_is_invalid( + deserializer: &Deserializer, round_id: RoundId, message: &DirectMessage, ) -> Result<(), MessageValidationError> { if round_id == RoundId::new(1) { - return message.verify_is_invalid::(); + return message.verify_is_invalid::(deserializer); } Err(MessageValidationError::InvalidEvidence("Invalid round number".into()))? } @@ -169,19 +160,24 @@ impl Round for Round1 { &self.context.other_ids } - fn make_echo_broadcast(&self, _rng: &mut impl CryptoRngCore) -> Option> { + fn make_echo_broadcast( + &self, + _rng: &mut impl CryptoRngCore, + serializer: &Serializer, + ) -> Option> { debug!("{:?}: making echo broadcast", self.context.id); let message = Round1Echo { my_position: self.context.ids_to_positions[&self.context.id], }; - Some(Self::serialize_echo_broadcast(message)) + Some(EchoBroadcast::new(serializer, message)) } fn make_direct_message( &self, _rng: &mut impl CryptoRngCore, + serializer: &Serializer, destination: &Id, ) -> Result<(DirectMessage, Artifact), LocalError> { debug!("{:?}: making direct message for {:?}", self.context.id, destination); @@ -190,7 +186,7 @@ impl Round for Round1 { my_position: self.context.ids_to_positions[&self.context.id], your_position: self.context.ids_to_positions[destination], }; - let dm = Self::serialize_direct_message(message)?; + let dm = DirectMessage::new(serializer, message)?; let artifact = Artifact::empty(); Ok((dm, artifact)) } @@ -198,13 +194,14 @@ impl Round for Round1 { fn receive_message( &self, _rng: &mut impl CryptoRngCore, + deserializer: &Deserializer, from: &Id, _echo_broadcast: Option, direct_message: DirectMessage, ) -> Result> { debug!("{:?}: receiving message from {:?}", self.context.id, from); - let message = direct_message.deserialize::()?; + let message = direct_message.deserialize::(deserializer)?; debug!("{:?}: received message: {:?}", self.context.id, message); @@ -272,19 +269,24 @@ impl Round for Round2 { &self.context.other_ids } - fn make_echo_broadcast(&self, _rng: &mut impl CryptoRngCore) -> Option> { + fn make_echo_broadcast( + &self, + _rng: &mut impl CryptoRngCore, + serializer: &Serializer, + ) -> Option> { debug!("{:?}: making echo broadcast", self.context.id); let message = Round1Echo { my_position: self.context.ids_to_positions[&self.context.id], }; - Some(Self::serialize_echo_broadcast(message)) + Some(EchoBroadcast::new(serializer, message)) } fn make_direct_message( &self, _rng: &mut impl CryptoRngCore, + serializer: &Serializer, destination: &Id, ) -> Result<(DirectMessage, Artifact), LocalError> { debug!("{:?}: making direct message for {:?}", self.context.id, destination); @@ -293,7 +295,7 @@ impl Round for Round2 { my_position: self.context.ids_to_positions[&self.context.id], your_position: self.context.ids_to_positions[destination], }; - let dm = Self::serialize_direct_message(message)?; + let dm = DirectMessage::new(serializer, message)?; let artifact = Artifact::empty(); Ok((dm, artifact)) } @@ -301,13 +303,14 @@ impl Round for Round2 { fn receive_message( &self, _rng: &mut impl CryptoRngCore, + deserializer: &Deserializer, from: &Id, _echo_broadcast: Option, direct_message: DirectMessage, ) -> Result> { debug!("{:?}: receiving message from {:?}", self.context.id, from); - let message = direct_message.deserialize::()?; + let message = direct_message.deserialize::(deserializer)?; debug!("{:?}: received message: {:?}", self.context.id, message); @@ -362,6 +365,7 @@ mod tests { use tracing_subscriber::EnvFilter; use super::{Inputs, Round1}; + use crate::Bincode; #[test] fn round() { @@ -386,7 +390,7 @@ mod tests { .with_env_filter(EnvFilter::from_default_env()) .finish(); let reports = tracing::subscriber::with_default(my_subscriber, || { - run_sync::, TestingSessionParams>(&mut OsRng, inputs).unwrap() + run_sync::, TestingSessionParams>(&mut OsRng, inputs).unwrap() }); for (_id, report) in reports { diff --git a/examples/src/simple_malicious.rs b/examples/src/simple_malicious.rs index e7e73da..4f48e71 100644 --- a/examples/src/simple_malicious.rs +++ b/examples/src/simple_malicious.rs @@ -5,13 +5,16 @@ use manul::{ protocol::{ Artifact, DirectMessage, FinalizeError, FinalizeOutcome, FirstRound, LocalError, Payload, Round, SessionId, }, - session::signature::Keypair, + session::{signature::Keypair, Serializer}, testing::{round_override, run_sync, RoundOverride, RoundWrapper, Signer, TestingSessionParams, Verifier}, }; use rand_core::{CryptoRngCore, OsRng}; use tracing_subscriber::EnvFilter; -use crate::simple::{Inputs, Round1, Round1Message, Round2, Round2Message}; +use crate::{ + simple::{Inputs, Round1, Round1Message, Round2, Round2Message}, + Bincode, +}; #[derive(Debug, Clone, Copy)] enum Behavior { @@ -61,20 +64,21 @@ impl RoundOverride for Mali fn make_direct_message( &self, rng: &mut impl CryptoRngCore, + serializer: &Serializer, destination: &Id, ) -> Result<(DirectMessage, Artifact), LocalError> { if matches!(self.behavior, Behavior::SerializedGarbage) { - let dm = DirectMessage::new::<>::Protocol, _>(&[99u8]).unwrap(); + let dm = DirectMessage::new(serializer, [99u8]).unwrap(); Ok((dm, Artifact::empty())) } else if matches!(self.behavior, Behavior::AttributableFailure) { let message = Round1Message { my_position: self.round.context.ids_to_positions[&self.round.context.id], your_position: self.round.context.ids_to_positions[&self.round.context.id], }; - let dm = DirectMessage::new::<>::Protocol, _>(&message)?; + let dm = DirectMessage::new(serializer, &message)?; Ok((dm, Artifact::empty())) } else { - self.inner_round_ref().make_direct_message(rng, destination) + self.inner_round_ref().make_direct_message(rng, serializer, destination) } } @@ -124,6 +128,7 @@ impl RoundOverride for Mali fn make_direct_message( &self, rng: &mut impl CryptoRngCore, + serializer: &Serializer, destination: &Id, ) -> Result<(DirectMessage, Artifact), LocalError> { if matches!(self.behavior, Behavior::AttributableFailureRound2) { @@ -131,10 +136,10 @@ impl RoundOverride for Mali my_position: self.round.context.ids_to_positions[&self.round.context.id], your_position: self.round.context.ids_to_positions[&self.round.context.id], }; - let dm = DirectMessage::new::<>::Protocol, _>(&message)?; + let dm = DirectMessage::new(serializer, &message)?; Ok((dm, Artifact::empty())) } else { - self.inner_round_ref().make_direct_message(rng, destination) + self.inner_round_ref().make_direct_message(rng, serializer, destination) } } } @@ -172,7 +177,7 @@ fn serialized_garbage() { .with_env_filter(EnvFilter::from_default_env()) .finish(); let mut reports = tracing::subscriber::with_default(my_subscriber, || { - run_sync::, TestingSessionParams>(&mut OsRng, run_inputs).unwrap() + run_sync::, TestingSessionParams>(&mut OsRng, run_inputs).unwrap() }); let v0 = signers[0].verifying_key(); @@ -218,7 +223,7 @@ fn attributable_failure() { .with_env_filter(EnvFilter::from_default_env()) .finish(); let mut reports = tracing::subscriber::with_default(my_subscriber, || { - run_sync::, TestingSessionParams>(&mut OsRng, run_inputs).unwrap() + run_sync::, TestingSessionParams>(&mut OsRng, run_inputs).unwrap() }); let v0 = signers[0].verifying_key(); @@ -264,7 +269,7 @@ fn attributable_failure_round2() { .with_env_filter(EnvFilter::from_default_env()) .finish(); let mut reports = tracing::subscriber::with_default(my_subscriber, || { - run_sync::, TestingSessionParams>(&mut OsRng, run_inputs).unwrap() + run_sync::, TestingSessionParams>(&mut OsRng, run_inputs).unwrap() }); let v0 = signers[0].verifying_key(); diff --git a/examples/tests/async.rs b/examples/tests/async.rs index 9a95552..5f58cdc 100644 --- a/examples/tests/async.rs +++ b/examples/tests/async.rs @@ -10,7 +10,10 @@ use manul::{ }, testing::{Signer, TestingSessionParams, Verifier}, }; -use manul_example::simple::{Inputs, Round1}; +use manul_example::{ + simple::{Inputs, Round1}, + Bincode, +}; use rand::Rng; use rand_core::OsRng; use tokio::{ @@ -231,8 +234,13 @@ async fn async_run() { let inputs = Inputs { all_ids: all_ids.clone(), }; - Session::<_, TestingSessionParams>::new::>(&mut OsRng, session_id.clone(), signer, inputs) - .unwrap() + Session::<_, TestingSessionParams>::new::>( + &mut OsRng, + session_id.clone(), + signer, + inputs, + ) + .unwrap() }) .collect::>(); diff --git a/manul/Cargo.toml b/manul/Cargo.toml index 7f1c8f2..a181f28 100644 --- a/manul/Cargo.toml +++ b/manul/Cargo.toml @@ -19,6 +19,7 @@ rand_core = { version = "0.6.4", default-features = false } tracing = { version = "0.1", default-features = false } displaydoc = { version = "0.2", default-features = false } rand = { version = "0.8", default-features = false, optional = true } +bincode = { version = "2.0.0-rc.3", default-features = false, features = ["alloc", "serde"] } [dev-dependencies] impls = "1" diff --git a/manul/benches/empty_rounds.rs b/manul/benches/empty_rounds.rs index f0612b2..6182000 100644 --- a/manul/benches/empty_rounds.rs +++ b/manul/benches/empty_rounds.rs @@ -9,7 +9,7 @@ use manul::{ Artifact, DeserializationError, DirectMessage, EchoBroadcast, FinalizeError, FinalizeOutcome, FirstRound, LocalError, Payload, Protocol, ProtocolError, ProtocolValidationError, ReceiveError, Round, RoundId, }, - session::{signature::Keypair, SessionId, SessionOutcome}, + session::{signature::Keypair, Deserializer, Format, Serializer, SessionId, SessionOutcome}, testing::{run_sync, Signer, TestingSessionParams, Verifier}, }; use rand_core::{CryptoRngCore, OsRng}; @@ -24,6 +24,7 @@ pub struct EmptyProtocolError; impl ProtocolError for EmptyProtocolError { fn verify_messages_constitute_error( &self, + _deserializer: &Deserializer, _echo_broadcast: &Option, _direct_message: &DirectMessage, _echo_broadcasts: &BTreeMap, @@ -34,11 +35,9 @@ impl ProtocolError for EmptyProtocolError { } } -impl Protocol for EmptyProtocol { - type Result = (); - type ProtocolError = EmptyProtocolError; - type CorrectnessProof = (); +pub struct Bincode; +impl Format for Bincode { fn serialize(value: T) -> Result, LocalError> { bincode::serde::encode_to_vec(value, bincode::config::standard()) .map(|vec| vec.into()) @@ -51,6 +50,12 @@ impl Protocol for EmptyProtocol { } } +impl Protocol for EmptyProtocol { + type Result = (); + type ProtocolError = EmptyProtocolError; + type CorrectnessProof = (); +} + struct EmptyRound { round_counter: u8, inputs: Inputs, @@ -107,9 +112,13 @@ impl Round for EmptyRound Option> { + fn make_echo_broadcast( + &self, + _rng: &mut impl CryptoRngCore, + serializer: &Serializer, + ) -> Option> { if self.inputs.echo { - Some(Self::serialize_echo_broadcast(Round1EchoBroadcast)) + Some(EchoBroadcast::new(serializer, Round1EchoBroadcast)) } else { None } @@ -118,9 +127,10 @@ impl Round for EmptyRound Result<(DirectMessage, Artifact), LocalError> { - let dm = Self::serialize_direct_message(Round1DirectMessage)?; + let dm = DirectMessage::new(serializer, Round1DirectMessage)?; let artifact = Artifact::new(Round1Artifact); Ok((dm, artifact)) } @@ -128,14 +138,15 @@ impl Round for EmptyRound, direct_message: DirectMessage, ) -> Result> { let _echo_broadcast = echo_broadcast - .map(|echo| echo.deserialize::()) + .map(|echo| echo.deserialize::(deserializer)) .transpose()?; - let _direct_message = direct_message.deserialize::()?; + let _direct_message = direct_message.deserialize::(deserializer)?; Ok(Payload::new(Round1Payload)) } @@ -204,7 +215,7 @@ fn bench_empty_rounds(c: &mut Criterion) { group.bench_function("25 nodes, 5 rounds, no echo", |b| { b.iter(|| { assert!( - run_sync::, TestingSessionParams>(&mut OsRng, inputs_no_echo.clone()) + run_sync::, TestingSessionParams>(&mut OsRng, inputs_no_echo.clone()) .unwrap() .values() .all(|report| matches!(report.outcome, SessionOutcome::Result(_))) @@ -234,7 +245,7 @@ fn bench_empty_rounds(c: &mut Criterion) { group.bench_function("25 nodes, 5 rounds, echo each round", |b| { b.iter(|| { assert!( - run_sync::, TestingSessionParams>(&mut OsRng, inputs_echo.clone()) + run_sync::, TestingSessionParams>(&mut OsRng, inputs_echo.clone()) .unwrap() .values() .all(|report| matches!(report.outcome, SessionOutcome::Result(_))) diff --git a/manul/src/protocol.rs b/manul/src/protocol.rs index ab12a48..d227531 100644 --- a/manul/src/protocol.rs +++ b/manul/src/protocol.rs @@ -15,7 +15,7 @@ mod errors; mod object_safe; mod round; -pub use crate::session::SessionId; +pub use crate::session::{Deserializer, Serializer, SessionId}; pub use errors::{ DeserializationError, DirectMessageError, EchoBroadcastError, FinalizeError, LocalError, MessageValidationError, ProtocolValidationError, ReceiveError, RemoteError, diff --git a/manul/src/protocol/object_safe.rs b/manul/src/protocol/object_safe.rs index b5c8f48..27ff614 100644 --- a/manul/src/protocol/object_safe.rs +++ b/manul/src/protocol/object_safe.rs @@ -11,6 +11,7 @@ use super::{ errors::{FinalizeError, LocalError, ReceiveError}, round::{Artifact, DirectMessage, EchoBroadcast, FinalizeOutcome, Payload, Protocol, Round, RoundId}, }; +use crate::session::{Deserializer, Serializer}; /// Since object-safe trait methods cannot take `impl CryptoRngCore` arguments, /// this structure wraps the dynamic object and exposes a `CryptoRngCore` interface, @@ -49,14 +50,20 @@ pub(crate) trait ObjectSafeRound: 'static + Send + Sync { fn make_direct_message( &self, rng: &mut dyn CryptoRngCore, + serializer: &Serializer, destination: &Id, ) -> Result<(DirectMessage, Artifact), LocalError>; - fn make_echo_broadcast(&self, rng: &mut dyn CryptoRngCore) -> Option>; + fn make_echo_broadcast( + &self, + rng: &mut dyn CryptoRngCore, + serializer: &Serializer, + ) -> Option>; fn receive_message( &self, rng: &mut dyn CryptoRngCore, + deserializer: &Deserializer, from: &Id, echo_broadcast: Option, direct_message: DirectMessage, @@ -112,27 +119,33 @@ where fn make_direct_message( &self, rng: &mut dyn CryptoRngCore, + serializer: &Serializer, destination: &Id, ) -> Result<(DirectMessage, Artifact), LocalError> { let mut boxed_rng = BoxedRng(rng); - self.round.make_direct_message(&mut boxed_rng, destination) + self.round.make_direct_message(&mut boxed_rng, serializer, destination) } - fn make_echo_broadcast(&self, rng: &mut dyn CryptoRngCore) -> Option> { + fn make_echo_broadcast( + &self, + rng: &mut dyn CryptoRngCore, + serializer: &Serializer, + ) -> Option> { let mut boxed_rng = BoxedRng(rng); - self.round.make_echo_broadcast(&mut boxed_rng) + self.round.make_echo_broadcast(&mut boxed_rng, serializer) } fn receive_message( &self, rng: &mut dyn CryptoRngCore, + deserializer: &Deserializer, from: &Id, echo_broadcast: Option, direct_message: DirectMessage, ) -> Result> { let mut boxed_rng = BoxedRng(rng); self.round - .receive_message(&mut boxed_rng, from, echo_broadcast, direct_message) + .receive_message(&mut boxed_rng, deserializer, from, echo_broadcast, direct_message) } fn finalize( diff --git a/manul/src/protocol/round.rs b/manul/src/protocol/round.rs index 37b752b..0837fbe 100644 --- a/manul/src/protocol/round.rs +++ b/manul/src/protocol/round.rs @@ -12,12 +12,12 @@ use serde_encoded_bytes::{Base64, SliceLike}; use super::{ errors::{ - DeserializationError, DirectMessageError, EchoBroadcastError, FinalizeError, LocalError, - MessageValidationError, ProtocolValidationError, ReceiveError, + DirectMessageError, EchoBroadcastError, FinalizeError, LocalError, MessageValidationError, + ProtocolValidationError, ReceiveError, }, object_safe::{ObjectSafeRound, ObjectSafeRoundWrapper}, }; -use crate::session::SessionId; +use crate::session::{Deserializer, Serializer, SessionId}; /// Possible successful outcomes of [`Round::finalize`]. pub enum FinalizeOutcome { @@ -129,17 +129,12 @@ pub trait Protocol: Debug + Sized { /// It proves that the node did its job correctly, to be adjudicated by a third party. type CorrectnessProof: Send + Serialize + for<'de> Deserialize<'de>; - /// Serializes the given object into a bytestring. - fn serialize(value: T) -> Result, LocalError>; - - /// Tries to deserialize the given bytestring as an object of type `T`. - fn deserialize<'de, T: Deserialize<'de>>(bytes: &'de [u8]) -> Result; - /// Returns `Ok(())` if the given direct message cannot be deserialized /// assuming it is a direct message from the round `round_id`. /// /// Normally one would use [`DirectMessage::verify_is_invalid`] when implementing this. fn verify_direct_message_is_invalid( + #[allow(unused_variables)] deserializer: &Deserializer, round_id: RoundId, #[allow(unused_variables)] message: &DirectMessage, ) -> Result<(), MessageValidationError> { @@ -153,6 +148,7 @@ pub trait Protocol: Debug + Sized { /// /// Normally one would use [`EchoBroadcast::verify_is_invalid`] when implementing this. fn verify_echo_broadcast_is_invalid( + #[allow(unused_variables)] deserializer: &Deserializer, round_id: RoundId, #[allow(unused_variables)] message: &EchoBroadcast, ) -> Result<(), MessageValidationError> { @@ -205,6 +201,7 @@ pub trait ProtocolError: Debug + Clone + Send { /// as requested by [`required_combined_echos`](`Self::required_combined_echos`). fn verify_messages_constitute_error( &self, + deserializer: &Deserializer, echo_broadcast: &Option, direct_message: &DirectMessage, echo_broadcasts: &BTreeMap, @@ -219,15 +216,18 @@ pub struct DirectMessage(#[serde(with = "SliceLike::")] Box<[u8]>); impl DirectMessage { /// Creates a new serialized direct message. - pub fn new(message: T) -> Result { - P::serialize(message).map(Self) + pub fn new(serializer: &Serializer, message: T) -> Result { + serializer.serialize(message).map(Self) } /// Returns `Ok(())` if the message cannot be deserialized into `T`. /// /// This is intended to be used in the implementations of [`Protocol::verify_direct_message_is_invalid`]. - pub fn verify_is_invalid Deserialize<'de>>(&self) -> Result<(), MessageValidationError> { - if self.deserialize::().is_err() { + pub fn verify_is_invalid Deserialize<'de>>( + &self, + deserializer: &Deserializer, + ) -> Result<(), MessageValidationError> { + if self.deserialize::(deserializer).is_err() { Ok(()) } else { Err(MessageValidationError::InvalidEvidence( @@ -237,8 +237,11 @@ impl DirectMessage { } /// Deserializes the direct message. - pub fn deserialize Deserialize<'de>>(&self) -> Result { - P::deserialize(&self.0).map_err(DirectMessageError::new) + pub fn deserialize Deserialize<'de>>( + &self, + deserializer: &Deserializer, + ) -> Result { + deserializer.deserialize(&self.0).map_err(DirectMessageError::new) } } @@ -248,15 +251,18 @@ pub struct EchoBroadcast(#[serde(with = "SliceLike::")] Box<[u8]>); impl EchoBroadcast { /// Creates a new serialized echo broadcast. - pub fn new(message: T) -> Result { - P::serialize(message).map(Self) + pub fn new(serializer: &Serializer, message: T) -> Result { + serializer.serialize(message).map(Self) } /// Returns `Ok(())` if the message cannot be deserialized into `T`. /// /// This is intended to be used in the implementations of [`Protocol::verify_direct_message_is_invalid`]. - pub fn verify_is_invalid Deserialize<'de>>(&self) -> Result<(), MessageValidationError> { - if self.deserialize::().is_err() { + pub fn verify_is_invalid Deserialize<'de>>( + &self, + deserializer: &Deserializer, + ) -> Result<(), MessageValidationError> { + if self.deserialize::(deserializer).is_err() { Ok(()) } else { Err(MessageValidationError::InvalidEvidence( @@ -266,8 +272,11 @@ impl EchoBroadcast { } /// Deserializes the echo broadcast. - pub fn deserialize Deserialize<'de>>(&self) -> Result { - P::deserialize(&self.0).map_err(EchoBroadcastError::new) + pub fn deserialize Deserialize<'de>>( + &self, + deserializer: &Deserializer, + ) -> Result { + deserializer.deserialize(&self.0).map_err(EchoBroadcastError::new) } } @@ -389,6 +398,7 @@ pub trait Round: 'static + Send + Sync { fn make_direct_message( &self, rng: &mut impl CryptoRngCore, + serializer: &Serializer, destination: &Id, ) -> Result<(DirectMessage, Artifact), LocalError>; @@ -402,6 +412,7 @@ pub trait Round: 'static + Send + Sync { fn make_echo_broadcast( &self, #[allow(unused_variables)] rng: &mut impl CryptoRngCore, + #[allow(unused_variables)] serializer: &Serializer, ) -> Option> { None } @@ -413,6 +424,7 @@ pub trait Round: 'static + Send + Sync { fn receive_message( &self, rng: &mut impl CryptoRngCore, + deserializer: &Deserializer, from: &Id, echo_broadcast: Option, direct_message: DirectMessage, @@ -434,16 +446,4 @@ pub trait Round: 'static + Send + Sync { /// The execution layer will not call [`finalize`](`Self::finalize`) until all these nodes have responded /// (and the corresponding [`receive_message`](`Self::receive_message`) finished successfully). fn expecting_messages_from(&self) -> &BTreeSet; - - /// A convenience method to create an [`EchoBroadcast`] object - /// to return in [`make_echo_broadcast`](`Self::make_echo_broadcast`). - fn serialize_echo_broadcast(message: impl Serialize) -> Result { - EchoBroadcast::new::(message) - } - - /// A convenience method to create a [`DirectMessage`] object - /// to return in [`make_direct_message`](`Self::make_direct_message`). - fn serialize_direct_message(message: impl Serialize) -> Result { - DirectMessage::new::(message) - } } diff --git a/manul/src/session.rs b/manul/src/session.rs index 44f4cf8..08a0587 100644 --- a/manul/src/session.rs +++ b/manul/src/session.rs @@ -13,7 +13,10 @@ mod transcript; pub use crate::protocol::{LocalError, RemoteError}; pub use message::MessageBundle; -pub use session::{CanFinalize, RoundAccumulator, RoundOutcome, Session, SessionId, SessionParameters}; +pub use session::{ + CanFinalize, Deserializer, Format, RoundAccumulator, RoundOutcome, Serializer, Session, SessionId, + SessionParameters, +}; pub use transcript::{SessionOutcome, SessionReport}; pub(crate) use echo::EchoRoundError; diff --git a/manul/src/session/echo.rs b/manul/src/session/echo.rs index 649abf2..ce9fbee 100644 --- a/manul/src/session/echo.rs +++ b/manul/src/session/echo.rs @@ -12,7 +12,7 @@ use tracing::debug; use super::{ message::{MessageVerificationError, SignedMessage}, - session::SessionParameters, + session::{Deserializer, Serializer, SessionParameters}, LocalError, }; use crate::{ @@ -101,6 +101,7 @@ where fn make_direct_message( &self, _rng: &mut impl CryptoRngCore, + serializer: &Serializer, destination: &SP::Verifier, ) -> Result<(DirectMessage, Artifact), LocalError> { debug!("{:?}: making echo round message for {:?}", self.verifier, destination); @@ -117,7 +118,7 @@ where let message = EchoRoundMessage:: { echo_messages: echo_messages.into(), }; - let dm = DirectMessage::new::(&message)?; + let dm = DirectMessage::new(serializer, &message)?; Ok((dm, Artifact::empty())) } @@ -128,13 +129,14 @@ where fn receive_message( &self, _rng: &mut impl CryptoRngCore, + deserializer: &Deserializer, from: &SP::Verifier, _echo_broadcast: Option, direct_message: DirectMessage, ) -> Result> { debug!("{:?}: received an echo message from {:?}", self.verifier, from); - let message = direct_message.deserialize::>()?; + let message = direct_message.deserialize::>(deserializer)?; // Check that the received message contains entries from `destinations` sans `from` // It is an unprovable fault. @@ -181,7 +183,7 @@ where continue; } - let verified_echo = match echo.clone().verify::(sender) { + let verified_echo = match echo.clone().verify::(sender) { Ok(echo) => echo, Err(MessageVerificationError::Local(error)) => return Err(error.into()), // This means `from` sent us an incorrectly signed message. diff --git a/manul/src/session/evidence.rs b/manul/src/session/evidence.rs index 3ff13bc..ec21e1c 100644 --- a/manul/src/session/evidence.rs +++ b/manul/src/session/evidence.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; use super::{ echo::{EchoRoundError, EchoRoundMessage}, message::{MessageVerificationError, SignedMessage}, - session::SessionParameters, + session::{Deserializer, SessionParameters}, transcript::Transcript, LocalError, }; @@ -127,6 +127,7 @@ where pub(crate) fn new_echo_round_error( verifier: &SP::Verifier, + deserializer: &Deserializer, direct_message: SignedMessage, error: EchoRoundError, transcript: &Transcript, @@ -139,7 +140,6 @@ where evidence: EvidenceEnum::InvalidEchoPack(InvalidEchoPackEvidence { direct_message, invalid_echo_sender: from, - phantom: core::marker::PhantomData, }), }), EchoRoundError::InvalidBroadcast(from) => { @@ -151,7 +151,7 @@ where let deserialized = direct_message .payload() - .deserialize::>() + .deserialize::>(deserializer) .map_err(|error| { LocalError::new(format!("Failed to deserialize the given direct message: {:?}", error)) })?; @@ -167,7 +167,6 @@ where evidence: EvidenceEnum::MismatchedBroadcasts(MismatchedBroadcastsEvidence { we_received, echoed_to_us: echoed_to_us.clone(), - phantom: core::marker::PhantomData, }), }) } @@ -214,10 +213,10 @@ where pub fn verify(&self, party: &SP::Verifier) -> Result<(), EvidenceError> { match &self.evidence { - EvidenceEnum::Protocol(evidence) => evidence.verify::(party), - EvidenceEnum::InvalidDirectMessage(evidence) => evidence.verify::(party), - EvidenceEnum::InvalidEchoBroadcast(evidence) => evidence.verify::(party), - EvidenceEnum::InvalidEchoPack(evidence) => evidence.verify(party), + EvidenceEnum::Protocol(evidence) => evidence.verify::(party, &Deserializer), + EvidenceEnum::InvalidDirectMessage(evidence) => evidence.verify::(party, &Deserializer), + EvidenceEnum::InvalidEchoBroadcast(evidence) => evidence.verify::(party, &Deserializer), + EvidenceEnum::InvalidEchoPack(evidence) => evidence.verify(party, &Deserializer), EvidenceEnum::MismatchedBroadcasts(evidence) => evidence.verify::(party), } } @@ -228,25 +227,23 @@ enum EvidenceEnum { Protocol(ProtocolEvidence

), InvalidDirectMessage(InvalidDirectMessageEvidence

), InvalidEchoBroadcast(InvalidEchoBroadcastEvidence

), - InvalidEchoPack(InvalidEchoPackEvidence), - MismatchedBroadcasts(MismatchedBroadcastsEvidence

), + InvalidEchoPack(InvalidEchoPackEvidence), + MismatchedBroadcasts(MismatchedBroadcastsEvidence), } #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct InvalidEchoPackEvidence { +pub struct InvalidEchoPackEvidence { direct_message: SignedMessage, invalid_echo_sender: SP::Verifier, - phantom: core::marker::PhantomData

, } -impl InvalidEchoPackEvidence +impl InvalidEchoPackEvidence where - P: Protocol, SP: SessionParameters, { - fn verify(&self, verifier: &SP::Verifier) -> Result<(), EvidenceError> { - let verified = self.direct_message.clone().verify::(verifier)?; - let deserialized = verified.payload().deserialize::>()?; + fn verify(&self, verifier: &SP::Verifier, deserializer: &Deserializer) -> Result<(), EvidenceError> { + let verified = self.direct_message.clone().verify::(verifier)?; + let deserialized = verified.payload().deserialize::>(deserializer)?; let invalid_echo = deserialized .echo_messages .get(&self.invalid_echo_sender) @@ -257,7 +254,7 @@ where )) })?; - let verified_echo = match invalid_echo.clone().verify::(&self.invalid_echo_sender) { + let verified_echo = match invalid_echo.clone().verify::(&self.invalid_echo_sender) { Ok(echo) => echo, Err(MessageVerificationError::Local(error)) => return Err(EvidenceError::Local(error)), // The message was indeed incorrectly signed - fault proven @@ -278,22 +275,18 @@ where } #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct MismatchedBroadcastsEvidence { +pub struct MismatchedBroadcastsEvidence { we_received: SignedMessage, echoed_to_us: SignedMessage, - phantom: core::marker::PhantomData

, } -impl

MismatchedBroadcastsEvidence

-where - P: Protocol, -{ +impl MismatchedBroadcastsEvidence { fn verify(&self, verifier: &SP::Verifier) -> Result<(), EvidenceError> where SP: SessionParameters, { - let we_received = self.we_received.clone().verify::(verifier)?; - let echoed_to_us = self.echoed_to_us.clone().verify::(verifier)?; + let we_received = self.we_received.clone().verify::(verifier)?; + let echoed_to_us = self.echoed_to_us.clone().verify::(verifier)?; if we_received.metadata() == echoed_to_us.metadata() && we_received.payload() != echoed_to_us.payload() { return Ok(()); @@ -315,12 +308,13 @@ impl

InvalidDirectMessageEvidence

where P: Protocol, { - fn verify(&self, verifier: &SP::Verifier) -> Result<(), EvidenceError> + fn verify(&self, verifier: &SP::Verifier, deserializer: &Deserializer) -> Result<(), EvidenceError> where SP: SessionParameters, { - let verified_direct_message = self.direct_message.clone().verify::(verifier)?; + let verified_direct_message = self.direct_message.clone().verify::(verifier)?; Ok(P::verify_direct_message_is_invalid( + deserializer, self.direct_message.metadata().round_id(), verified_direct_message.payload(), )?) @@ -337,12 +331,13 @@ impl

InvalidEchoBroadcastEvidence

where P: Protocol, { - fn verify(&self, verifier: &SP::Verifier) -> Result<(), EvidenceError> + fn verify(&self, verifier: &SP::Verifier, deserializer: &Deserializer) -> Result<(), EvidenceError> where SP: SessionParameters, { - let verified_echo_broadcast = self.echo_broadcast.clone().verify::(verifier)?; + let verified_echo_broadcast = self.echo_broadcast.clone().verify::(verifier)?; Ok(P::verify_echo_broadcast_is_invalid( + deserializer, self.echo_broadcast.metadata().round_id(), verified_echo_broadcast.payload(), )?) @@ -363,17 +358,17 @@ impl

ProtocolEvidence

where P: Protocol, { - fn verify(&self, verifier: &SP::Verifier) -> Result<(), EvidenceError> + fn verify(&self, verifier: &SP::Verifier, deserializer: &Deserializer) -> Result<(), EvidenceError> where SP: SessionParameters, { let session_id = self.direct_message.metadata().session_id(); - let verified_direct_message = self.direct_message.clone().verify::(verifier)?.payload().clone(); + let verified_direct_message = self.direct_message.clone().verify::(verifier)?.payload().clone(); let mut verified_direct_messages = BTreeMap::new(); for (round_id, direct_message) in self.direct_messages.iter() { - let verified_direct_message = direct_message.clone().verify::(verifier)?; + let verified_direct_message = direct_message.clone().verify::(verifier)?; let metadata = verified_direct_message.metadata(); if metadata.session_id() != session_id || metadata.round_id() != *round_id { return Err(EvidenceError::InvalidEvidence( @@ -390,14 +385,14 @@ where "Invalid attached message metadata".into(), )); } - Some(echo.clone().verify::(verifier)?.payload().clone()) + Some(echo.clone().verify::(verifier)?.payload().clone()) } else { None }; let mut verified_echo_broadcasts = BTreeMap::new(); for (round_id, echo_broadcast) in self.echo_broadcasts.iter() { - let verified_echo_broadcast = echo_broadcast.clone().verify::(verifier)?; + let verified_echo_broadcast = echo_broadcast.clone().verify::(verifier)?; let metadata = verified_echo_broadcast.metadata(); if metadata.session_id() != session_id || metadata.round_id() != *round_id { return Err(EvidenceError::InvalidEvidence( @@ -409,18 +404,20 @@ where let mut combined_echos = BTreeMap::new(); for (round_id, combined_echo) in self.combined_echos.iter() { - let verified_combined_echo = combined_echo.clone().verify::(verifier)?; + let verified_combined_echo = combined_echo.clone().verify::(verifier)?; let metadata = verified_combined_echo.metadata(); if metadata.session_id() != session_id || metadata.round_id().non_echo() != *round_id { return Err(EvidenceError::InvalidEvidence( "Invalid attached message metadata".into(), )); } - let echo_set = DirectMessage::deserialize::>(verified_combined_echo.payload())?; + let echo_set = verified_combined_echo + .payload() + .deserialize::>(deserializer)?; let mut verified_echo_set = Vec::new(); for (other_verifier, echo_broadcast) in echo_set.echo_messages.iter() { - let verified_echo_broadcast = echo_broadcast.clone().verify::(other_verifier)?; + let verified_echo_broadcast = echo_broadcast.clone().verify::(other_verifier)?; let metadata = verified_echo_broadcast.metadata(); if metadata.session_id() != session_id || metadata.round_id() != *round_id { return Err(EvidenceError::InvalidEvidence( @@ -433,6 +430,7 @@ where } Ok(self.error.verify_messages_constitute_error( + deserializer, &verified_echo_broadcast, &verified_direct_message, &verified_echo_broadcasts, diff --git a/manul/src/session/message.rs b/manul/src/session/message.rs index 2358748..1f849f6 100644 --- a/manul/src/session/message.rs +++ b/manul/src/session/message.rs @@ -7,29 +7,27 @@ use serde_encoded_bytes::{Hex, SliceLike}; use signature::{DigestVerifier, RandomizedDigestSigner}; use super::{ - session::{SessionId, SessionParameters}, + session::{Format, SessionId, SessionParameters}, LocalError, }; -use crate::protocol::{DeserializationError, DirectMessage, EchoBroadcast, Protocol, RoundId}; +use crate::protocol::{DeserializationError, DirectMessage, EchoBroadcast, RoundId}; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub(crate) struct SerializedSignature(#[serde(with = "SliceLike::")] Box<[u8]>); impl SerializedSignature { - pub fn new(signature: &SP::Signature) -> Result + pub fn new(signature: &SP::Signature) -> Result where - P: Protocol, SP: SessionParameters, { - P::serialize(signature).map(Self) + SP::Format::serialize(signature).map(Self) } - pub fn deserialize(&self) -> Result + pub fn deserialize(&self) -> Result where - P: Protocol, SP: SessionParameters, { - P::deserialize::(&self.0) + SP::Format::deserialize::(&self.0) } } @@ -81,7 +79,7 @@ impl SignedMessage where M: Serialize, { - pub fn new( + pub fn new( rng: &mut impl CryptoRngCore, signer: &SP::Signer, session_id: &SessionId, @@ -89,18 +87,17 @@ where message: M, ) -> Result where - P: Protocol, SP: SessionParameters, { let metadata = MessageMetadata::new(session_id, round_id); let message_with_metadata = MessageWithMetadata { metadata, message }; - let message_bytes = P::serialize(&message_with_metadata)?; + let message_bytes = SP::Format::serialize(&message_with_metadata)?; let digest = SP::Digest::new_with_prefix(b"SignedMessage").chain_update(message_bytes); let signature = signer .try_sign_digest_with_rng(rng, digest) .map_err(|err| LocalError::new(format!("Failed to sign: {:?}", err)))?; Ok(Self { - signature: SerializedSignature::new::(&signature)?, + signature: SerializedSignature::new::(&signature)?, message_with_metadata, }) } @@ -113,16 +110,16 @@ where &self.message_with_metadata.message } - pub(crate) fn verify(self, verifier: &SP::Verifier) -> Result, MessageVerificationError> + pub(crate) fn verify(self, verifier: &SP::Verifier) -> Result, MessageVerificationError> where - P: Protocol, SP: SessionParameters, { - let message_bytes = P::serialize(&self.message_with_metadata).map_err(MessageVerificationError::Local)?; + let message_bytes = + SP::Format::serialize(&self.message_with_metadata).map_err(MessageVerificationError::Local)?; let digest = SP::Digest::new_with_prefix(b"SignedMessage").chain_update(message_bytes); let signature = self .signature - .deserialize::() + .deserialize::() .map_err(|_| MessageVerificationError::InvalidSignature)?; if verifier.verify_digest(digest, &signature).is_ok() { Ok(VerifiedMessage { @@ -168,7 +165,7 @@ pub struct MessageBundle { } impl MessageBundle { - pub(crate) fn new( + pub(crate) fn new( rng: &mut impl CryptoRngCore, signer: &SP::Signer, session_id: &SessionId, @@ -177,10 +174,9 @@ impl MessageBundle { echo_broadcast: Option>, ) -> Result where - P: Protocol, SP: SessionParameters, { - let direct_message = SignedMessage::new::(rng, signer, session_id, round_id, direct_message)?; + let direct_message = SignedMessage::new::(rng, signer, session_id, round_id, direct_message)?; Ok(Self { direct_message, echo_broadcast, @@ -218,15 +214,14 @@ impl CheckedMessageBundle { &self.metadata } - pub fn verify(self, verifier: &SP::Verifier) -> Result, MessageVerificationError> + pub fn verify(self, verifier: &SP::Verifier) -> Result, MessageVerificationError> where - P: Protocol, SP: SessionParameters, { - let direct_message = self.direct_message.verify::(verifier)?; + let direct_message = self.direct_message.verify::(verifier)?; let echo_broadcast = self .echo_broadcast - .map(|echo| echo.verify::(verifier)) + .map(|echo| echo.verify::(verifier)) .transpose()?; Ok(VerifiedMessageBundle { from: verifier.clone(), diff --git a/manul/src/session/session.rs b/manul/src/session/session.rs index b954f44..0a0b2f0 100644 --- a/manul/src/session/session.rs +++ b/manul/src/session/session.rs @@ -2,6 +2,7 @@ use alloc::{ boxed::Box, collections::{BTreeMap, BTreeSet}, format, + string::ToString, vec::Vec, }; use core::fmt::Debug; @@ -21,10 +22,46 @@ use super::{ LocalError, RemoteError, }; use crate::protocol::{ - Artifact, DirectMessage, EchoBroadcast, FinalizeError, FinalizeOutcome, FirstRound, ObjectSafeRound, - ObjectSafeRoundWrapper, Payload, Protocol, ReceiveError, ReceiveErrorType, Round, RoundId, + Artifact, DeserializationError, DirectMessage, EchoBroadcast, FinalizeError, FinalizeOutcome, FirstRound, + ObjectSafeRound, ObjectSafeRoundWrapper, Payload, Protocol, ReceiveError, ReceiveErrorType, Round, RoundId, }; +/// A (de)serializer that will be used for the protocol messages. +pub trait Format { + /// Serializes the given object into a bytestring. + fn serialize(value: T) -> Result, LocalError>; + + /// Tries to deserialize the given bytestring as an object of type `T`. + fn deserialize<'de, T: Deserialize<'de>>(bytes: &'de [u8]) -> Result; +} + +/// [temporary serializer] +#[derive(Debug, Clone, Copy)] +pub struct Serializer; + +impl Serializer { + // TODO: temporary implementation, should be made via `erased_serde` + /// Serializes the given object into a bytestring. + pub fn serialize(&self, value: T) -> Result, LocalError> { + bincode::serde::encode_to_vec(value, bincode::config::standard()) + .map(|vec| vec.into()) + .map_err(|err| LocalError::new(err.to_string())) + } +} + +/// [temporary deserializer] +#[derive(Debug, Clone, Copy)] +pub struct Deserializer; + +impl Deserializer { + // TODO: temporary implementation, should be made via `erased_serde` + /// Tries to deserialize the given bytestring as an object of type `T`. + pub fn deserialize<'de, T: Deserialize<'de>>(&self, bytes: &'de [u8]) -> Result { + bincode::serde::decode_borrowed_from_slice(bytes, bincode::config::standard()) + .map_err(|err| DeserializationError::new(err.to_string())) + } +} + /// A set of types needed to execute a session. /// /// These will be generally determined by the user, depending on what signature type @@ -48,6 +85,9 @@ pub trait SessionParameters { /// The signature type corresponding to [`Signer`](`Self::Signer`) and [`Verifier`](`Self::Verifier`). type Signature: Serialize + for<'de> Deserialize<'de>; + + /// The type used to (de)serialize messages. + type Format: Format; } /// A session identifier shared between the parties. @@ -139,9 +179,9 @@ where ) -> Result { let verifier = signer.verifying_key(); let echo_message = round - .make_echo_broadcast(rng) + .make_echo_broadcast(rng, &Serializer) .transpose()? - .map(|echo| SignedMessage::new::(rng, &signer, &session_id, round.id(), echo)) + .map(|echo| SignedMessage::new::(rng, &signer, &session_id, round.id(), echo)) .transpose()?; let message_destinations = round.message_destinations().clone(); @@ -186,9 +226,9 @@ where rng: &mut impl CryptoRngCore, destination: &SP::Verifier, ) -> Result<(MessageBundle, ProcessedArtifact), LocalError> { - let (direct_message, artifact) = self.round.make_direct_message(rng, destination)?; + let (direct_message, artifact) = self.round.make_direct_message(rng, &Serializer, destination)?; - let bundle = MessageBundle::new::( + let bundle = MessageBundle::new::( rng, &self.signer, &self.session_id, @@ -276,7 +316,7 @@ where // Verify the signature now - let verified_message = match checked_message.verify::(from) { + let verified_message = match checked_message.verify::(from) { Ok(verified_message) => verified_message, Err(MessageVerificationError::InvalidSignature) => { accum.register_unprovable_error(from, RemoteError::new("The signature could not be deserialized"))?; @@ -322,6 +362,7 @@ where ) -> ProcessedMessage { let processed = self.round.receive_message( rng, + &Deserializer, message.from(), message.echo_broadcast().cloned(), message.direct_message().clone(), @@ -620,7 +661,7 @@ where } ReceiveErrorType::Echo(error) => { let (_echo_broadcast, direct_message) = processed.message.into_unverified(); - let evidence = Evidence::new_echo_round_error(&from, direct_message, error, transcript)?; + let evidence = Evidence::new_echo_round_error(&from, &Deserializer, direct_message, error, transcript)?; self.register_provable_error(&from, evidence) } ReceiveErrorType::Local(error) => Err(error), @@ -668,7 +709,9 @@ mod tests { use impls::impls; use serde::{Deserialize, Serialize}; - use super::{MessageBundle, ProcessedArtifact, ProcessedMessage, Session, VerifiedMessageBundle}; + use super::{ + Deserializer, Format, MessageBundle, ProcessedArtifact, ProcessedMessage, Session, VerifiedMessageBundle, + }; use crate::{ protocol::{ DeserializationError, DirectMessage, EchoBroadcast, LocalError, Protocol, ProtocolError, @@ -696,6 +739,7 @@ mod tests { impl ProtocolError for DummyProtocolError { fn verify_messages_constitute_error( &self, + _deserializer: &Deserializer, _echo_broadcast: &Option, _direct_message: &DirectMessage, _echo_broadcasts: &BTreeMap, @@ -710,6 +754,11 @@ mod tests { type Result = (); type ProtocolError = DummyProtocolError; type CorrectnessProof = (); + } + + struct DummyFormat; + + impl Format for DummyFormat { fn serialize(_: T) -> Result, LocalError> where T: Serialize, @@ -724,17 +773,19 @@ mod tests { } } + type SP = TestingSessionParams; + // We need `Session` to be `Send` so that we send a `Session` object to a task // to run the loop there. - assert!(impls!(Session: Send)); + assert!(impls!(Session: Send)); // This is needed so that message processing offloaded to a task could use `&Session`. - assert!(impls!(Session: Sync)); + assert!(impls!(Session: Sync)); // These objects are sent to/from message processing tasks assert!(impls!(MessageBundle: Send)); - assert!(impls!(ProcessedArtifact: Send)); - assert!(impls!(VerifiedMessageBundle: Send)); - assert!(impls!(ProcessedMessage: Send)); + assert!(impls!(ProcessedArtifact: Send)); + assert!(impls!(VerifiedMessageBundle: Send)); + assert!(impls!(ProcessedMessage: Send)); } } diff --git a/manul/src/testing/identity.rs b/manul/src/testing/identity.rs index 4220ca2..fb7a814 100644 --- a/manul/src/testing/identity.rs +++ b/manul/src/testing/identity.rs @@ -2,7 +2,7 @@ use digest::generic_array::typenum; use rand_core::CryptoRngCore; use serde::{Deserialize, Serialize}; -use crate::session::SessionParameters; +use crate::session::{Format, SessionParameters}; /// A simple signer for testing purposes. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] @@ -89,13 +89,14 @@ impl digest::OutputSizeUser for Hasher { /// An implementation of [`SessionParameters`] using the testing signer/verifier types. #[derive(Debug, Clone, Copy)] -pub struct TestingSessionParams; +pub struct TestingSessionParams(core::marker::PhantomData); -impl SessionParameters for TestingSessionParams { +impl SessionParameters for TestingSessionParams { type Signer = Signer; type Verifier = Verifier; type Signature = Signature; type Digest = Hasher; + type Format = F; } #[cfg(test)] diff --git a/manul/src/testing/macros.rs b/manul/src/testing/macros.rs index 9ce75c2..a8d3253 100644 --- a/manul/src/testing/macros.rs +++ b/manul/src/testing/macros.rs @@ -5,6 +5,7 @@ use rand_core::CryptoRngCore; use crate::protocol::{ Artifact, DirectMessage, EchoBroadcast, FinalizeError, FinalizeOutcome, LocalError, Payload, Round, }; +use crate::session::Serializer; /// A trait defining a wrapper around an existing type implementing [`Round`]. pub trait RoundWrapper: 'static + Sized + Send + Sync { @@ -28,14 +29,19 @@ pub trait RoundOverride: RoundWrapper { fn make_direct_message( &self, rng: &mut impl CryptoRngCore, + serializer: &Serializer, destination: &Id, ) -> Result<(DirectMessage, Artifact), LocalError> { - self.inner_round_ref().make_direct_message(rng, destination) + self.inner_round_ref().make_direct_message(rng, serializer, destination) } /// An override for [`Round::make_echo_broadcast`]. - fn make_echo_broadcast(&self, rng: &mut impl CryptoRngCore) -> Option> { - self.inner_round_ref().make_echo_broadcast(rng) + fn make_echo_broadcast( + &self, + rng: &mut impl CryptoRngCore, + serializer: &Serializer, + ) -> Option> { + self.inner_round_ref().make_echo_broadcast(rng, serializer) } /// An override for [`Round::finalize`]. @@ -84,27 +90,30 @@ macro_rules! round_override { fn make_direct_message( &self, rng: &mut impl CryptoRngCore, + serializer: &$crate::session::Serializer, destination: &Id, ) -> Result<($crate::protocol::DirectMessage, $crate::protocol::Artifact), $crate::protocol::LocalError> { - >::make_direct_message(self, rng, destination) + >::make_direct_message(self, rng, serializer, destination) } fn make_echo_broadcast( &self, rng: &mut impl CryptoRngCore, + serializer: &$crate::session::Serializer, ) -> Option> { - >::make_echo_broadcast(self, rng) + >::make_echo_broadcast(self, rng, serializer) } fn receive_message( &self, rng: &mut impl CryptoRngCore, + deserializer: &$crate::session::Deserializer, from: &Id, echo_broadcast: Option<$crate::protocol::EchoBroadcast>, direct_message: $crate::protocol::DirectMessage, ) -> Result<$crate::protocol::Payload, $crate::protocol::ReceiveError> { self.inner_round_ref() - .receive_message(rng, from, echo_broadcast, direct_message) + .receive_message(rng, deserializer, from, echo_broadcast, direct_message) } fn finalize(