From 5ead91a03acd1aa5b7835d2eb9ffc8010b7d9e45 Mon Sep 17 00:00:00 2001 From: Bogdan Opanchuk Date: Wed, 30 Oct 2024 11:15:26 -0700 Subject: [PATCH] Don't serialize the already serialized payload when signing messages --- manul/src/protocol/message.rs | 6 ++++++ manul/src/session/message.rs | 33 ++++++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/manul/src/protocol/message.rs b/manul/src/protocol/message.rs index ccbacee..b0cd694 100644 --- a/manul/src/protocol/message.rs +++ b/manul/src/protocol/message.rs @@ -15,6 +15,12 @@ mod private { #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct MessagePayload(#[serde(with = "SliceLike::")] pub Box<[u8]>); + impl AsRef<[u8]> for MessagePayload { + fn as_ref(&self) -> &[u8] { + &self.0 + } + } + pub trait ProtocolMessageWrapper: Sized { fn new_inner(maybe_message: Option) -> Self; fn maybe_message(&self) -> &Option; diff --git a/manul/src/session/message.rs b/manul/src/session/message.rs index 3a1c35f..210cfee 100644 --- a/manul/src/session/message.rs +++ b/manul/src/session/message.rs @@ -11,7 +11,9 @@ use super::{ wire_format::WireFormat, LocalError, }; -use crate::protocol::{DeserializationError, DirectMessage, EchoBroadcast, NormalBroadcast, RoundId}; +use crate::protocol::{ + DeserializationError, DirectMessage, EchoBroadcast, NormalBroadcast, ProtocolMessagePart, RoundId, +}; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub(crate) struct SerializedSignature(#[serde(with = "SliceLike::")] Box<[u8]>); @@ -76,9 +78,26 @@ pub struct MessageWithMetadata { message: M, } +impl MessageWithMetadata { + fn digest(&self) -> Result + where + SP: SessionParameters, + { + let digest = + SP::Digest::new_with_prefix(b"SignedMessage").chain_update(SP::WireFormat::serialize(&self.metadata)?); + + let digest = match self.message.maybe_message().as_ref() { + None => digest.chain_update([0u8]), + Some(payload) => digest.chain_update([1u8]).chain_update(payload), + }; + + Ok(digest) + } +} + impl SignedMessage where - M: Serialize, + M: ProtocolMessagePart, { pub fn new( rng: &mut impl CryptoRngCore, @@ -92,8 +111,7 @@ where { let metadata = MessageMetadata::new(session_id, round_id); let message_with_metadata = MessageWithMetadata { metadata, message }; - let message_bytes = SP::WireFormat::serialize(&message_with_metadata)?; - let digest = SP::Digest::new_with_prefix(b"SignedMessage").chain_update(message_bytes); + let digest = message_with_metadata.digest::()?; let signature = signer .try_sign_digest_with_rng(rng, digest) .map_err(|err| LocalError::new(format!("Failed to sign: {:?}", err)))?; @@ -115,9 +133,10 @@ where where SP: SessionParameters, { - let message_bytes = - SP::WireFormat::serialize(&self.message_with_metadata).map_err(MessageVerificationError::Local)?; - let digest = SP::Digest::new_with_prefix(b"SignedMessage").chain_update(message_bytes); + let digest = self + .message_with_metadata + .digest::() + .map_err(MessageVerificationError::Local)?; let signature = self .signature .deserialize::()