vodozemac/ecies/
messages.rs1use thiserror::Error;
16
17#[cfg(doc)]
18use super::EstablishedEcies;
19use crate::{Curve25519PublicKey, KeyError, base64_decode, base64_encode};
20
21#[derive(Debug, Error)]
23pub enum MessageDecodeError {
24 #[error("The initial message is missing the | separator")]
27 MissingSeparator,
28 #[error("The embedded ephemeral Curve25519 key could not have been decoded: {0:?}")]
31 KeyError(#[from] KeyError),
32 #[error("The ciphertext could not have been decoded from a base64 string: {0:?}")]
34 Base64(#[from] base64::DecodeError),
35}
36
37#[derive(Debug, PartialEq, Eq)]
45pub struct InitialMessage {
46 pub public_key: Curve25519PublicKey,
48 pub ciphertext: Vec<u8>,
50}
51
52impl InitialMessage {
53 pub fn encode(&self) -> String {
58 let ciphertext = base64_encode(&self.ciphertext);
59 let key = self.public_key.to_base64();
60
61 format!("{ciphertext}|{key}")
62 }
63
64 pub fn decode(message: &str) -> Result<Self, MessageDecodeError> {
66 match message.split_once('|') {
67 Some((ciphertext, key)) => {
68 let public_key = Curve25519PublicKey::from_base64(key)?;
69 let ciphertext = base64_decode(ciphertext)?;
70
71 Ok(Self { ciphertext, public_key })
72 }
73 None => Err(MessageDecodeError::MissingSeparator),
74 }
75 }
76}
77
78#[derive(Debug)]
80pub struct Message {
81 pub ciphertext: Vec<u8>,
83}
84
85impl Message {
86 pub fn encode(&self) -> String {
90 base64_encode(&self.ciphertext)
91 }
92
93 pub fn decode(message: &str) -> Result<Self, MessageDecodeError> {
95 Ok(Self { ciphertext: base64_decode(message)? })
96 }
97}
98
99#[cfg(test)]
100mod test {
101 use super::*;
102
103 const INITIAL_MESSAGE: &str = "3On7QFJyLQMAErua9K/yIOcJALvuMYax1AW0iWgf64AwtSMZXwAA012Q|9yA/CX8pJKF02Prd75ZyBQHg3fGTVVGDNl86q1z17Us";
104 const MESSAGE: &str = "ZmtSLdzMcyjC5eV6L8xBI6amsq7gDNbCjz1W5OjX4Z8W";
105 const PUBLIC_KEY: &str = "9yA/CX8pJKF02Prd75ZyBQHg3fGTVVGDNl86q1z17Us";
106
107 #[test]
108 fn initial_message() {
109 let message = InitialMessage::decode(INITIAL_MESSAGE)
110 .expect("We should be able to decode our known-valid initial message");
111
112 assert_eq!(
113 message.public_key.to_base64(),
114 PUBLIC_KEY,
115 "The decoded public key should match the expected one"
116 );
117
118 let encoded = message.encode();
119 assert_eq!(INITIAL_MESSAGE, encoded);
120 }
121
122 #[test]
123 fn message() {
124 let message = Message::decode(MESSAGE)
125 .expect("We should be able to decode our known-valid initial message");
126
127 let encoded = message.encode();
128 assert_eq!(MESSAGE, encoded);
129 }
130}