p2panda_encryption/message_scheme/
message.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3use crate::crypto::aead::{AeadError, aead_decrypt, aead_encrypt};
4use crate::message_scheme::ratchet::RatchetKeyMaterial;
5
6pub fn encrypt_message(
7    plaintext: &[u8],
8    ratchet_secrets: RatchetKeyMaterial,
9) -> Result<Vec<u8>, AeadError> {
10    let (key, nonce) = ratchet_secrets;
11    let ciphertext = aead_encrypt(key.as_bytes(), plaintext, nonce, None)?;
12    Ok(ciphertext)
13}
14
15pub fn decrypt_message(
16    ciphertext: &[u8],
17    ratchet_secrets: RatchetKeyMaterial,
18) -> Result<Vec<u8>, AeadError> {
19    let (key, nonce) = ratchet_secrets;
20    let plaintext = aead_decrypt(key.as_bytes(), ciphertext, nonce, None)?;
21    Ok(plaintext)
22}
23
24#[cfg(test)]
25mod tests {
26    use crate::Rng;
27    use crate::crypto::Secret;
28    use crate::message_scheme::{DecryptionRatchet, MESSAGE_KEY_SIZE, RatchetSecret};
29
30    use super::{decrypt_message, encrypt_message};
31
32    #[test]
33    fn message_ratcheting() {
34        let rng = Rng::from_seed([1; 32]);
35
36        let update_secret = Secret::from_bytes(rng.random_array::<MESSAGE_KEY_SIZE>().unwrap());
37
38        let ooo_tolerance = 4;
39        let max_forward = 10;
40
41        let alice = RatchetSecret::init(update_secret.clone());
42        let bob = DecryptionRatchet::init(update_secret);
43
44        let (alice, generation_0, alice_secret_0) = RatchetSecret::ratchet_forward(alice).unwrap();
45        let message_0 = encrypt_message(b"I scream, you scream!", alice_secret_0).unwrap();
46
47        let (bob, bob_secret_0) =
48            DecryptionRatchet::secret_for_decryption(bob, generation_0, max_forward, ooo_tolerance)
49                .unwrap();
50        let receive_0 = decrypt_message(&message_0, bob_secret_0).unwrap();
51        assert_eq!(receive_0, b"I scream, you scream!");
52
53        let (_alice, generation_1, alice_secret_1) = RatchetSecret::ratchet_forward(alice).unwrap();
54        let message_1 = encrypt_message(b"We all scream for ice-cream!", alice_secret_1).unwrap();
55
56        let (_bob, bob_secret_1) =
57            DecryptionRatchet::secret_for_decryption(bob, generation_1, max_forward, ooo_tolerance)
58                .unwrap();
59        let receive_1 = decrypt_message(&message_1, bob_secret_1).unwrap();
60        assert_eq!(receive_1, b"We all scream for ice-cream!");
61    }
62}