No description
  • C 65.2%
  • Rust 34.8%
Find a file
Daniel Schadt 7218598a96
All checks were successful
ci/woodpecker/push/tests Pipeline was successful
adjust types of e()
Taking j as i32 was a weird choice (only for the -1), and technically
caused issues for invocations with more than u16::MAX tweaks (not that
people might use that many tweaks, but just in case...)
2025-09-04 22:36:33 +02:00
.woodpecker add CI 2025-08-20 23:57:33 +02:00
aezref fuzz against slow aez-ref, not fast aez-ni 2025-04-17 12:56:44 +02:00
benches add benchmarks for primitives 2025-09-04 21:47:55 +02:00
fuzz bump version to 0.2.1 2025-06-14 10:49:53 +02:00
src adjust types of e() 2025-09-04 22:36:33 +02:00
.gitignore first working version! 2025-04-04 23:24:11 +02:00
Cargo.lock bump version to 0.2.1 2025-06-14 10:49:53 +02:00
Cargo.toml add benchmarks for primitives 2025-09-04 21:47:55 +02:00
CHANGELOG add CHANGELOG 2025-06-14 10:47:18 +02:00
LICENSE add documentation 2025-04-08 22:08:05 +02:00
README.md add notes about fuzzing to readme 2025-04-22 21:43:03 +02:00
Spec.pdf add documentation 2025-04-08 22:08:05 +02:00

zears

Crates.io Version Crates.io License docs.rs

Implementation of AEZ v5 in Rust. Works without hardware AES support.

☣️ Cryptographic hazmat ☣️

This crate is not battle tested and not audited. It exists as a learning exercise. Use it at your own risk.

AEZ encryption

From the AEZ website:

AEZ is an authenticated-encryption (AE) scheme optimized for ease of correct use ("AE made EZ"). It was invented by Viet Tung Hoang, Ted Krovetz, and Phillip Rogaway. The algorithm encrypts a plaintext by appending to it a fixed authentication block (some zero bits) and then enciphering the resulting string with an arbitrary-input-length blockcipher, this tweaked by the nonce, AD, and authenticator length. The approach results in strong security and usability properties, including nonce-reuse misuse resistance, automatic exploitation of decryption-verified redundancy, and arbitrary, user-selectable length expansion.

Example use

This crate provides an easy-to-use interface for AEZ:

use zears::Aez;
let aez = Aez::new(b"my key");
let ciphertext = aez.encrypt(b"nonce", &[b"associated data"], 16, b"message");
let plaintext = aez.decrypt(b"nonce", &["associated data"], 16, &ciphertext);
assert_eq!(plaintext.unwrap(), b"message");

Correctness

We cannot guarantee that this implementation implements the AEZ specification correctly. However, we increase our confidence that it does in two ways:

Test vectors

The normal unit tests test the encryption (and its parts) based on reference test vectors generated by the reference C code. The vectors are generated via Nick Mathewson's tool and included in src/testvectors.rs.

You check the implementation against the test vectors by running cargo test.

Fuzzing

We use cargo-fuzz and include a fuzz target zears_vs_aez that takes random inputs and runs them through both, zears and the reference AEZ implementation. You can start fuzzing by running cargo fuzz run zers_vs_aez.

Note that this builds the aezref crate, which is a thin wrapper around the reference implementation. This requires a working C compiler.

The aezref (sub)crate is not meant for actual encryption work! Its underlying implementation is slow and has side channels.

License

This crate is licensed under the terms of the MIT license. You can find the full license text in LICENSE.