Skip to main content

miden_crypto/aead/
mod.rs

1//! AEAD (authenticated encryption with associated data) schemes.
2
3use alloc::{
4    string::{String, ToString},
5    vec::Vec,
6};
7
8use thiserror::Error;
9
10use crate::{
11    Felt,
12    utils::{
13        Deserializable,
14        zeroize::{Zeroize, ZeroizeOnDrop},
15    },
16};
17
18pub mod aead_poseidon2;
19pub mod xchacha;
20
21/// Indicates whether encrypted data originated from field elements or raw bytes.
22#[repr(u8)]
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24pub enum DataType {
25    Elements = 0,
26    Bytes = 1,
27}
28
29impl TryFrom<u8> for DataType {
30    type Error = String;
31
32    fn try_from(value: u8) -> Result<Self, Self::Error> {
33        match value {
34            0 => Ok(DataType::Elements),
35            1 => Ok(DataType::Bytes),
36            _ => Err("invalid data type value: expected 0 for Elements or 1 for Bytes".to_string()),
37        }
38    }
39}
40
41// AEAD TRAIT
42// ================================================================================================
43
44/// Authenticated encryption with associated data (AEAD) scheme
45pub(crate) trait AeadScheme {
46    const KEY_SIZE: usize;
47
48    type Key: Deserializable + Zeroize + ZeroizeOnDrop;
49
50    fn key_from_bytes(bytes: &[u8]) -> Result<Self::Key, EncryptionError>;
51
52    // BYTE METHODS
53    // ================================================================================================
54
55    fn encrypt_bytes<R: rand::CryptoRng + rand::RngCore>(
56        key: &Self::Key,
57        rng: &mut R,
58        plaintext: &[u8],
59        associated_data: &[u8],
60    ) -> Result<Vec<u8>, EncryptionError>;
61
62    fn decrypt_bytes_with_associated_data(
63        key: &Self::Key,
64        ciphertext: &[u8],
65        associated_data: &[u8],
66    ) -> Result<Vec<u8>, EncryptionError>;
67
68    // FELT METHODS
69    // ================================================================================================
70
71    /// Encrypts field elements with associated data. Default implementation converts to bytes.
72    fn encrypt_elements<R: rand::CryptoRng + rand::RngCore>(
73        key: &Self::Key,
74        rng: &mut R,
75        plaintext: &[Felt],
76        associated_data: &[Felt],
77    ) -> Result<Vec<u8>, EncryptionError> {
78        let plaintext_bytes = crate::utils::elements_to_bytes(plaintext);
79        let ad_bytes = crate::utils::elements_to_bytes(associated_data);
80
81        Self::encrypt_bytes(key, rng, &plaintext_bytes, &ad_bytes)
82    }
83
84    /// Decrypts field elements with associated data. Default implementation uses byte decryption.
85    fn decrypt_elements_with_associated_data(
86        key: &Self::Key,
87        ciphertext: &[u8],
88        associated_data: &[Felt],
89    ) -> Result<Vec<Felt>, EncryptionError> {
90        let ad_bytes = crate::utils::elements_to_bytes(associated_data);
91        let plaintext_bytes = Self::decrypt_bytes_with_associated_data(key, ciphertext, &ad_bytes)?;
92
93        match crate::utils::bytes_to_elements_exact(&plaintext_bytes) {
94            Some(elements) => Ok(elements),
95            None => Err(EncryptionError::FailedBytesToElementsConversion),
96        }
97    }
98}
99
100// ERROR TYPES
101// ================================================================================================
102
103/// Errors that can occur during encryption/decryption operations
104#[derive(Debug, Error)]
105pub enum EncryptionError {
106    #[error("authentication tag verification failed")]
107    InvalidAuthTag,
108    #[error("peration failed")]
109    FailedOperation,
110    #[error("malformed padding")]
111    MalformedPadding,
112    #[error("ciphertext length, in field elements, is not a multiple of `RATE_WIDTH`")]
113    CiphertextLenNotMultipleRate,
114    #[error("invalid data type: expected {expected:?}, found {found:?}")]
115    InvalidDataType { expected: DataType, found: DataType },
116    #[error(
117        "failed to convert bytes, that are supposed to originate from field elements, back to field elements"
118    )]
119    FailedBytesToElementsConversion,
120}