Update the security level of the cipher without decrypting
This is a post-quantum block cipher that allows for key rotation and security level updates without the need to decrypt the data. The cipher is based on the Ring-LWE problem, which is believed to be secure against quantum attacks.
fn Iv::generate(security_level: usize) -> Iv
security_level: The security level of the cipher.
fn Key::generate(key_size_bits_security_level: usize, key_generation: usize) -> Key
key_size_bits_security_level: The security level of the key.
key_generation: The generation of the key: 0 if the key is used for first encryption of a cipher, then increment it for each key rotation.
fn encrypt(plaintext: &[u8], key: &Key, iv: &Iv) -> Vec<u8>
plaintext: The plaintext to encrypt.
key: The key to use for encryption, itskey_generationmust be 0.
iv: The initialization vector to use for encryption. It should be unique for each encryption, in order to ensure IND-CCA security.
fn decrypt(ciphertext: &[u8], key: &Key, iv: &Iv) -> Vec<u8>
ciphertext: The ciphertext to decrypt.
key: The key to use for decryption.
iv: The initialization vector to use for decryption.
fn increase_security_level(ciphertext: &[u8], iv: &Iv, old_key: &Key, new_key: &Key) -> Result<Vec<u8>, BlockCipherUpdatableSecurityError>
ciphertext: The ciphertext to update.
iv: The initialization vector that was used to encrypt the ciphertext.
old_key: The old key that was used to encrypt the ciphertext.
new_key: The new key to use for the updated ciphertext. Itskey_generationmust be incremented from the old key, and its security level must be greater than the old key.
Internally, the function will generate a security level upgrade token from the old key and the new key, and use it to update the ciphertext without decrypting it.
use block_cipher_updatable_security::{Iv, Key, decrypt, encrypt, increase_security_level};
const PLAINTEXT_TEXT: &'static str = "Hello, world!Hello, world!Hello, world!Hello, world!Hello, world!";
let plaintext = PLAINTEXT_TEXT.as_bytes();
println!("PLAIN: {}", PLAINTEXT_TEXT);
let iv = Iv::generate(256);
let key1 = Key::generate(128, 0).unwrap();
let encrypted = encrypt(plaintext, &key1, &iv);
let decrypted = decrypt(&encrypted, &key1, &iv);
let decrypted_text = std::str::from_utf8(&decrypted).unwrap()[..PLAINTEXT_TEXT.len()].to_string();
println!("Decrypted: {}", decrypted_text);
assert_eq!(PLAINTEXT_TEXT.to_string(), decrypted_text);
let key2 = Key::generate(256, 1).unwrap();
let encrypted2 = increase_security_level(&encrypted, &iv, &key1, &key2).unwrap();
let decrypted2 = decrypt(&encrypted2, &key2, &iv);
let decrypted2_text = std::str::from_utf8(&decrypted2).unwrap()[..PLAINTEXT_TEXT.len()].to_string();
println!("Decrypted2: {}", decrypted2_text);
assert_eq!(PLAINTEXT_TEXT.to_string(), decrypted2_text);
let key3 = Key::generate(512, 2).unwrap();
let encrypted3 = increase_security_level(&encrypted2, &iv, &key2, &key3).unwrap();
let decrypted3 = decrypt(&encrypted3, &key3, &iv);
let decrypted3_text = std::str::from_utf8(&decrypted3).unwrap()[..PLAINTEXT_TEXT.len()].to_string();
println!("Decrypted3: {}", decrypted3_text);
assert_eq!(PLAINTEXT_TEXT.to_string(), decrypted3_text);You can launch the tests with the command:
cargo testYou can test performance with the command:
cargo benchRerun the command after a code change to see how performance changed.
(Code inspired from https://github.com/lattice-based-cryptography/ring-lwe)