1use 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#[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
41pub(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 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 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 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#[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}