Lioness wide-block cipher.

Warning

This code has not been formally audited, Use at your own risk or ask a cryptographers before use.

Overview

Lioness is a wide block cipher built from

  • S: Stream cipher,
  • H: Keyed-Hash function,
  • K: Key derivation function (KDF) to derive the 4 internal round keys

Any secure compatible options and their combinations can work, in this crate we have the following options:

  • S: AES-CTR-128, Chacha20
  • H: keyed-Blake2b, HMAC-SHA-256, SHA-256 (with key prepend)
  • K: TURBOSHAKE-128, SHAKE-128, HKDF-SHA-256, domain-seperated SHA-256

These primitives are imported from:

The security of lioness reduce to the security of the underlying stream cipher or the hash function.
See the paper for more information.

How to use

Here is an example of how to use the Lioness_blockcipher create. Use a 32-byte master key and encrypt or decrypt a block in place:

use rand_core::{OsRng, RngCore};
use lioness_blockcipher::prelude::*;
type TestLioness = Lioness::<
    Aes128CtrStreamCipher,
    Sha256PrependKey,
    DomSepSha256Kdf,
>;

fn main() -> anyhow::Result<()> {
    let mut key: Key256 = Default::default();
    OsRng.fill_bytes(&mut key);

    let cipher: TestLioness = Lioness::new(&key)?;

    // Blocks must be at >64 bytes long
    let mut block = vec![0x84u8; 65];
    let original = block.clone();

    cipher.encrypt_in_place(&mut block)?;

    cipher.decrypt_in_place(&mut block)?;

    assert_eq!(block, original);
    println!("success!");

    Ok(())
}

Some notes:

  • Encryption and decryption are both in-place for now.
  • The block length need to be at least 64 bytes because Lioness splits the block into two where the left part is 32-byte, and the right part needs at least 16 bytes. might support small blocks in the future, but for Sphinx use-case, this should work.
  • If you need authenticity, make sure to use encrypt_auth which prepends the plaintext with 128-bits zeros. Also use decrypt_auth to check the zeros after decryption. see authentication example

TODO

  • Add more tests, examples, and benchmarks ...
  • Make it generic for any compatible cipher, keyed_hash, and KDF.
  • Compare with existing Haskel implementation.
  • Add authenticated encryption and decryption which prepend the plaintext with k-zeros and checks authenticity after decryption.
Description
Rust implementation of LIONESS, a wide-block cipher
Readme
Languages
Rust 100%