libcrux_traits/aead/
arrayref.rs

1//! This module contains the trait and related errors for an Authenticated
2//! Encryption with Associated Data (AEAD) scheme that takes array references
3//! as arguments and writes outputs to mutable array references.
4
5use libcrux_secrets::U8;
6
7/// An Authenticated Encryption with Associated Data (AEAD) scheme. This trait
8/// is low-level and is mostly used for implementing other, more usable APIs.
9///
10/// Some implementors of this trait may impose stronger restrictions on the inputs than described
11/// here. Check the documentation of the types implementing this trait to make sure which inputs
12/// are valid.
13pub trait Aead<const KEY_LEN: usize, const TAG_LEN: usize, const NONCE_LEN: usize> {
14    /// Generate a new key. Consumes the entire randomnes.
15    fn keygen(key: &mut [U8; KEY_LEN], rand: &[U8; KEY_LEN]) -> Result<(), KeyGenError>;
16
17    /// Encrypt a plaintext message, producing a ciphertext and an authentication tag.
18    /// The arguments `plaintext` and `ciphertext` must have the same length.
19    fn encrypt(
20        ciphertext: &mut [u8],
21        tag: &mut [U8; TAG_LEN],
22        key: &[U8; KEY_LEN],
23        nonce: &[U8; NONCE_LEN],
24        aad: &[u8],
25        plaintext: &[U8],
26    ) -> Result<(), EncryptError>;
27
28    /// Decrypt a ciphertext, verifying its authenticity.
29    /// The arguments `plaintext` and `ciphertext` must have the same length.
30    fn decrypt(
31        plaintext: &mut [U8],
32        key: &[U8; KEY_LEN],
33        nonce: &[U8; NONCE_LEN],
34        aad: &[u8],
35        ciphertext: &[u8],
36        tag: &[U8; TAG_LEN],
37    ) -> Result<(), DecryptError>;
38}
39
40/// An error occurred during key generation
41pub struct KeyGenError;
42
43/// Error that can occur during encryption.
44#[derive(Debug, PartialEq, Eq)]
45pub enum EncryptError {
46    /// The ciphertext buffer has the wrong length.
47    WrongCiphertextLength,
48
49    /// The plaintext is too long for this algorithm or implementation.
50    PlaintextTooLong,
51
52    /// The AAD is too long for this algorithm or implementation.
53    AadTooLong,
54
55    /// An unknown error occurred during encryption.
56    Unknown,
57}
58
59/// Error that can occur during decryption.
60#[derive(Debug, PartialEq, Eq)]
61pub enum DecryptError {
62    /// The authentication tag is invalid; the ciphertext has been tampered with
63    /// or the key/nonce/aad is incorrect.
64    InvalidTag,
65
66    /// The plaintext buffer has the wrong length.
67    WrongPlaintextLength,
68
69    /// The plaintext is too long for this algorithm or implementation.
70    PlaintextTooLong,
71
72    /// The AAD is too long for this algorithm or implementation.
73    AadTooLong,
74
75    /// An unknown error occurred during decryption.
76    Unknown,
77}
78
79impl core::fmt::Display for EncryptError {
80    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
81        let text = match self {
82            EncryptError::WrongCiphertextLength => "ciphertext buffer has wrong length",
83            EncryptError::PlaintextTooLong => {
84                "plaintext is too long for algorithm or implementation"
85            }
86            EncryptError::AadTooLong => "aad is too long for algorithm or implementation",
87            EncryptError::Unknown => "an unknown error occurred",
88        };
89
90        f.write_str(text)
91    }
92}
93
94impl core::fmt::Display for DecryptError {
95    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
96        let text = match self {
97            DecryptError::InvalidTag => "invalid authentication tag",
98            DecryptError::WrongPlaintextLength => "plaintext buffer has wrong length",
99            DecryptError::PlaintextTooLong => {
100                "plaintext is too long for algorithm or implementation"
101            }
102            DecryptError::AadTooLong => "aad is too long for algorithm or implementation",
103            DecryptError::Unknown => "an unknown error occurred",
104        };
105
106        f.write_str(text)
107    }
108}
109
110#[cfg(feature = "error-in-core")]
111mod error_in_core {
112    impl core::error::Error for super::EncryptError {}
113    impl core::error::Error for super::DecryptError {}
114}