Skip to content

thomasarmel/block_cipher_updatable_security

Repository files navigation

Post-quantum block cipher with key rotation and security level update

Update the security level of the cipher without decrypting


Description

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.

API Documentation

Generate random Initialization Vector (IV):

fn Iv::generate(security_level: usize) -> Iv

security_level: The security level of the cipher.

Generate random Key:

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.

Encrypt a message:

fn encrypt(plaintext: &[u8], key: &Key, iv: &Iv) -> Vec<u8>

plaintext: The plaintext to encrypt.

key: The key to use for encryption, its key_generation must be 0.

iv: The initialization vector to use for encryption. It should be unique for each encryption, in order to ensure IND-CCA security.

Decrypt a message:

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.

Increase security level of a ciphertext:

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. Its key_generation must 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.

Example

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);

Test

You can launch the tests with the command:

cargo test

Performance

You can test performance with the command:

cargo bench

Rerun the command after a code change to see how performance changed.

(Code inspired from https://github.com/lattice-based-cryptography/ring-lwe)

About

An almost key-homomorphic post-quantum block cipher with key rotation and security update for long-term secret storage

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published