mirror of
https://github.com/logos-storage/lioness_blockcipher.git
synced 2026-05-18 18:49:28 +00:00
74 lines
2.6 KiB
Markdown
74 lines
2.6 KiB
Markdown
|
|
### 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](https://www.cl.cam.ac.uk/~rja14/Papers/bear-lion.pdf) 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:
|
|
- [rustcrypto streamciphers](https://github.com/RustCrypto/stream-ciphers)
|
|
- [rustcrypto hashes](https://github.com/RustCrypto/hashes/tree/master)
|
|
|
|
The security of lioness reduce to the security of the underlying stream cipher or
|
|
the hash function.
|
|
See the [paper](https://www.cl.cam.ac.uk/~rja14/Papers/bear-lion.pdf) 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:
|
|
|
|
```rust
|
|
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](./examples/auth)
|
|
|
|
### TODO
|
|
- [x] Add more tests, examples, and benchmarks ...
|
|
- [x] Make it generic for any compatible cipher, keyed_hash, and KDF.
|
|
- [x] Compare with existing Haskel implementation.
|
|
- [x] Add authenticated encryption and decryption which prepend the plaintext with k-zeros and checks authenticity after decryption.
|