Chacha20 is a stream cipher which uses a 128-bit or 256-bit key and a 96-bit nonce [paper]. Currently AES has a virtual monopoly on secret key encryption. There would be major problems, though, if this was cracked. Along with this AES has been shown to be weak around cache-collision attacks. Google thus propose ChaCha20 as an alternative, and actively use it within TLS connections. Currently it is three times faster than software-enabled AES, and is not sensitive to timing attacks. It operates by creating a key stream which is then X-ORed with the plaintext. It has been standardised with RFC 7539
ChaCha20 in Rust |
An outline of the Rust code is:
extern crate base64; extern crate hex; extern crate crypto; use crypto::{symmetriccipher::{ SynchronousStreamCipher}}; use rustc_serialize::hex::FromHex; use std::env; use core::str; use std::iter::repeat; fn hex_to_bytes(s: &str) -> Vec<u8> { s.from_hex().unwrap() } fn main() { let mut mykey="0000000000000000000000000000000000000000000000000000000000000000"; let mut msg="Hello"; let mut myiv="000000000000000000000000"; let args: Vec= env::args().collect(); if args.len() >1 { msg = args[1].as_str();} if args.len() >2 { mykey = args[2].as_str();} if args.len() >3 { myiv = args[3].as_str();} println!("== ChaCha20 =="); println!("Message: {:?}",msg); println!("Key: {:?}",mykey); println!("IV: {:?}",myiv); let key=&hex_to_bytes( mykey)[..]; let iv=&hex_to_bytes( myiv)[..]; let plain=msg.as_bytes(); // Encrypting let mut c = crypto::chacha20::ChaCha20::new(&key, iv); let mut output: Vec = repeat(0).take(plain.len()).collect(); c.process(&plain[..], &mut output[..]); println!("\nEncrypted: {}",hex::encode(output.clone())); // Decrypting let mut c = crypto::chacha20::ChaCha20::new(&key, iv); let mut newoutput: Vec = repeat(0).take(output.len()).collect(); c.process(&mut output[..], &mut newoutput[..]); println!("\nDecrypted: {}",str::from_utf8(&newoutput[..]).unwrap()); }
Finally we simply build with:
cargo build
A sample run is:
== ChaCha20 == Message: "Hello" Key: "0000000000000000000000000000000000000000000000000000000000000000" IV: "000000000000000000000000" Encrypted: 3edd8cc1cf Decrypted: Hello