AES-256-GCM Authenticated Encryption (Rust)
Topics: symmetric encryption, AEAD, AES-GCM, nonces
Problem
Implement authenticated encryption with AES-256-GCM using the aes-gcm
crate. GCM gives you confidentiality and integrity: a tampered ciphertext fails to decrypt rather
than returning garbage.
Requirements:
encrypt(key, plaintext) -> Result<Vec<u8>, AesError> — AES-256-GCM. Generate a fresh random
12-byte nonce per call and return nonce || ciphertext || tag as one blob. key must be 32 bytes.
decrypt(key, data) -> Result<Vec<u8>, AesError> — split off the nonce, verify the tag, and
return the plaintext.
- Errors:
AesError::InvalidKeySize (key ≠ 32 bytes), AesError::Malformed (data shorter than a
nonce), AesError::Authentication (tag mismatch — tampered data or wrong key).
pub enum AesError { InvalidKeySize, Malformed, Authentication }
pub fn encrypt(key: &[u8], plaintext: &[u8]) -> Result<Vec<u8>, AesError>;
pub fn decrypt(key: &[u8], data: &[u8]) -> Result<Vec<u8>, AesError>;
Key concepts
- AEAD: GCM produces ciphertext plus an authentication tag; decryption recomputes the tag
and refuses to return plaintext if it doesn't match, so bit-flips are detected.
- Nonce uniqueness is critical: reusing a
(key, nonce) pair in GCM is catastrophic. Generate a
fresh random nonce per message (Aes256Gcm::generate_nonce(&mut OsRng)) and store it alongside
the ciphertext — it isn't secret.
aes-gcm crate: Aes256Gcm::new(key) then cipher.encrypt(&nonce, plaintext) /
cipher.decrypt(&nonce, ciphertext); both return Result, with Err on a tag mismatch.
Grading
Your solution.rs is the crate library; it's compiled with the dependencies in Cargo.toml and run
against the trusted tests.rs via cargo test. Only solution.rs is yours to edit.
Sign in to submit your solution.