diff --git a/manul/src/protocol/round.rs b/manul/src/protocol/round.rs index 27bc785..6420a6d 100644 --- a/manul/src/protocol/round.rs +++ b/manul/src/protocol/round.rs @@ -84,6 +84,11 @@ impl RoundId { } } + /// Returns `true` if this is an ID of an echo broadcast round. + pub(crate) fn is_echo(&self) -> bool { + self.is_echo + } + /// Returns the identifier of the echo round corresponding to the given non-echo round. /// /// Panics if `self` is already an echo round identifier. @@ -161,6 +166,7 @@ pub trait Protocol: 'static + Sized { /// /// Normally one would use [`EchoBroadcast::verify_is_not`] when implementing this. fn verify_normal_broadcast_is_invalid( + #[allow(unused_variables)] deserializer: &Deserializer, round_id: RoundId, #[allow(unused_variables)] message: &NormalBroadcast, ) -> Result<(), MessageValidationError> { diff --git a/manul/src/session/echo.rs b/manul/src/session/echo.rs index ad8a92d..95bb12d 100644 --- a/manul/src/session/echo.rs +++ b/manul/src/session/echo.rs @@ -17,8 +17,9 @@ use super::{ }; use crate::{ protocol::{ - Artifact, Deserializer, DirectMessage, EchoBroadcast, FinalizeError, FinalizeOutcome, NormalBroadcast, - ObjectSafeRound, Payload, Protocol, ProtocolMessagePart, ReceiveError, Round, RoundId, Serializer, + Artifact, Deserializer, DirectMessage, EchoBroadcast, FinalizeError, FinalizeOutcome, MessageValidationError, + NormalBroadcast, ObjectSafeRound, Payload, Protocol, ProtocolMessagePart, ReceiveError, Round, RoundId, + Serializer, }, utils::SerializableMap, }; @@ -55,7 +56,7 @@ pub(crate) enum MismatchedBroadcastsError { #[derive(Debug, Clone, Serialize, Deserialize)] pub(crate) struct EchoRoundMessage { - pub(crate) echo_broadcasts: SerializableMap>, + pub(super) echo_broadcasts: SerializableMap>, } /// Each protocol round can contain one `EchoRound` with "echo messages" that are sent to all @@ -105,6 +106,25 @@ where artifacts, } } + + // Since the echo round doesn't have its own `Protocol`, these methods live here. + + pub fn verify_direct_message_is_invalid(message: &DirectMessage) -> Result<(), MessageValidationError> { + // We don't send any direct messages in the echo round + message.verify_is_some() + } + + pub fn verify_echo_broadcast_is_invalid(message: &EchoBroadcast) -> Result<(), MessageValidationError> { + // We don't send any echo broadcasts in the echo round + message.verify_is_some() + } + + pub fn verify_normal_broadcast_is_invalid( + deserializer: &Deserializer, + message: &NormalBroadcast, + ) -> Result<(), MessageValidationError> { + message.verify_is_not::>(deserializer) + } } impl Round for EchoRound diff --git a/manul/src/session/evidence.rs b/manul/src/session/evidence.rs index 819e0e6..79c2750 100644 --- a/manul/src/session/evidence.rs +++ b/manul/src/session/evidence.rs @@ -4,7 +4,7 @@ use core::fmt::Debug; use serde::{Deserialize, Serialize}; use super::{ - echo::{EchoRoundError, EchoRoundMessage, MismatchedBroadcastsError}, + echo::{EchoRound, EchoRoundError, EchoRoundMessage, MismatchedBroadcastsError}, message::{MessageVerificationError, MissingMessage, SignedMessage}, session::SessionParameters, transcript::Transcript, @@ -254,7 +254,7 @@ where EvidenceEnum::Protocol(evidence) => evidence.verify::(party, &deserializer), EvidenceEnum::InvalidDirectMessage(evidence) => evidence.verify::(party, &deserializer), EvidenceEnum::InvalidEchoBroadcast(evidence) => evidence.verify::(party, &deserializer), - EvidenceEnum::InvalidNormalBroadcast(evidence) => evidence.verify::(party), + EvidenceEnum::InvalidNormalBroadcast(evidence) => evidence.verify::(party, &deserializer), EvidenceEnum::InvalidEchoPack(evidence) => evidence.verify(party, &deserializer), EvidenceEnum::MismatchedBroadcasts(evidence) => evidence.verify::(party), } @@ -368,11 +368,17 @@ where SP: SessionParameters, { 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(), - )?) + let payload = verified_direct_message.payload(); + + if self.direct_message.metadata().round_id().is_echo() { + Ok(EchoRound::::verify_direct_message_is_invalid(payload)?) + } else { + Ok(P::verify_direct_message_is_invalid( + deserializer, + self.direct_message.metadata().round_id(), + payload, + )?) + } } } @@ -392,11 +398,17 @@ where SP: SessionParameters, { 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(), - )?) + let payload = verified_echo_broadcast.payload(); + + if self.echo_broadcast.metadata().round_id().is_echo() { + Ok(EchoRound::::verify_echo_broadcast_is_invalid(payload)?) + } else { + Ok(P::verify_echo_broadcast_is_invalid( + deserializer, + self.echo_broadcast.metadata().round_id(), + payload, + )?) + } } } @@ -411,15 +423,25 @@ impl

InvalidNormalBroadcastEvidence

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_normal_broadcast = self.normal_broadcast.clone().verify::(verifier)?; - Ok(P::verify_normal_broadcast_is_invalid( - self.normal_broadcast.metadata().round_id(), - verified_normal_broadcast.payload(), - )?) + let payload = verified_normal_broadcast.payload(); + + if self.normal_broadcast.metadata().round_id().is_echo() { + Ok(EchoRound::::verify_normal_broadcast_is_invalid( + deserializer, + payload, + )?) + } else { + Ok(P::verify_normal_broadcast_is_invalid( + deserializer, + self.normal_broadcast.metadata().round_id(), + payload, + )?) + } } }