Lockstitch is an incremental, stateful cryptographic primitive for symmetric-key cryptographic operations (e.g. hashing, encryption, message authentication codes, and authenticated encryption) in complex protocols. Inspired by TupleHash, STROBE, Noise Protocol's stateful objects, and Xoodyak's Cyclist mode, Lockstitch combines BLAKE3 and AEGIS128L to provide GiB/sec performance on modern processors at a 128-bit security level.
Neither the design nor the implementation of this library have been independently evaluated.
A Lockstitch protocol is a stateful object which has five different operations:
Mix
: Mixes a piece of data into the protocol's state, making all future outputs dependent on it.Derive
: Outputs bytes of pseudo-random data dependent on the protocol's prior state.Encrypt
/Decrypt
: Encrypts and decrypts data using the protocol's state as the key.Seal
/Open
: Similar to Encrypt
/Decrypt
but uses a MAC to ensure authenticity.Ratchet
: Irreversibly modifies the protocol's state, preventing rollback.Using these operations, one can construct a wide variety of symmetric-key constructions.
Lockstitch is used to compose cryptographic protocols.
For example, we can create message digests:
```rust fn digest(data: &[u8]) -> [u8; 32] { let mut md = lockstitch::Protocol::new("com.example.md"); md.mix(data); md.derive_array() }
asserteq!(digest(b"this is a message"), digest(b"this is a message")); assertne!(digest(b"this is a message"), digest(b"this is another message")); ```
We can create message authentication codes:
```rust fn mac(key: &[u8], data: &[u8]) -> [u8; 16] { let mut mac = lockstitch::Protocol::new("com.example.mac"); mac.mix(key); mac.mix(data); mac.derive_array() }
asserteq!(mac(b"a key", b"a message"), mac(b"a key", b"a message")); assertne!(mac(b"a key", b"a message"), mac(b"another key", b"a message")); assert_ne!(mac(b"a key", b"a message"), mac(b"a key", b"another message")); ```
We can even create authenticated encryption:
```rust
fn aeadencrypt(key: &[u8], nonce: &[u8], ad: &[u8], plaintext: &[u8]) -> Vec
let mut aead = lockstitch::Protocol::new("com.example.aead"); aead.mix(key); aead.mix(nonce); aead.mix(ad); aead.seal(&mut out);
out }
fn aeaddecrypt(key: &[u8], nonce: &[u8], ad: &[u8], ciphertext: &[u8]) -> Option
let mut aead = lockstitch::Protocol::new("com.example.aead"); aead.mix(key); aead.mix(nonce); aead.mix(ad); aead.open(&mut ciphertext).map(|p| p.to_vec()) }
let plaintext = b"a message".tovec(); let ciphertext = aeadencrypt(b"a key", b"a nonce", b"some data", &plaintext); asserteq!(aeaddecrypt(b"a key", b"a nonce", b"some data", &ciphertext), Some(plaintext)); asserteq!(aeaddecrypt(b"another key", b"a nonce", b"some data", &ciphertext), None); asserteq!(aeaddecrypt(b"a key", b"another nonce", b"some data", &ciphertext), None); asserteq!(aeaddecrypt(b"a key", b"a nonce", b"some other data", &ciphertext), None);
let mut badciphertext = ciphertext.tovec(); badciphertext[5] ^= 1; // flip one bit asserteq!(aeaddecrypt(b"a key", b"a nonce", b"some data", &badciphertext), None); ```
std
: Enables features based on the Rust standard library. Enabled by default.hedge
: Enables hedged random value generation with rand_core
. Enabled by default.Both BLAKE3 and AEGIS128L benefit significantly from the use of specific CPU instructions.
x86_64
On x86_64
CPUs, Lockstitch achieves its best performance with the aes
and ssse3
CPU features
enabled and the std
crate feature enabled. This allows the blake3
create to detect CPU features
at runtime, ensures AEGIS128L benefits from the AES-NI instructions, and prevents interference
between AES-NI and AVX2 in the AEGIS128L implementation.
To compile a x86_64
binary with support for these features, create a .cargo/config.toml
file
with the following:
toml
[build]
rustflags = ["-C", "target-feature=+aes,+ssse3"]
Or use the following RUSTFLAGS
environment variable:
sh
export RUSTFLAGS="-C target-feature=+aes,+ssse3"
aarch64
Lockstitch includes a NEON-optimized AEGIS128L implementation and the blake3
crate includes NEON
optimizations, so no Rust-specific settings are required.
For more information on the design of Lockstitch, see design.md
.
For more information on performance, see perf.md
.
Copyright © 2022 Coda Hale, Frank Denis
AEGIS128L implementation copied from rust-aegis with some modifications.
Distributed under the MIT License.