HC-256: A Fast and Secure Software Stream Cipher

Why should you just learn about the most common methods? As a researcher, you should never fully dismiss any method, as methods that might…

Photo by Mauro Sbicego on Unsplash

HC-256: A Fast and Secure Software Stream Cipher

Why should you just learn about the most common methods? As a researcher, you should never fully dismiss any method, as methods that might not be popular now may come back and be ready to take on new challenges. Also, a method will have been created for a purpose, and reading the paper will show how the authors have addressed the challenge. It’s basically a journey of discovery and will typically add your knowledge.

And, so, I’ve been reading this paper [here]:

The HC-256 method was created in 2004, and uses a 256-bit key (K) and a 256-bit nonce (IV) value. Internally it has two secret tables: P and Q, and where each table has 1,024 32-bit words. Basically, these represent state values, and each change of state will update one of the entries of the table, and which uses a non-linear update function. Thus, after 2,048 state changes, every element of the tables will have been updated. We then derive the final has by taking a SHA-256, but where we use the P and Q tables as S-boxes. Overall, it is a fast-stream cipher with just four CPU cycles per byte.

The basic functions that HC-256 uses are simple and involve either EX-OR, mod, add or bit shift operations:

As we have a stream cipher, we basically take the key and the IV, and expand into a key stream (s). The cipher is then:

c = p ^ s

and where we EX-OR each bit of the plaintext (p) with the bits in the keystream (s), and generate a cipher stream (c ). In order to recover the plaintext, we just EX-OR again with the key stream:

p = c ^ s

Key and IV setup

The initialization phase provides an expansion of the 256-bit key into the P and Q tables. With this, we take the key and the IV, and split them up into eight 32-bit values (K_0 … K_7, and IV_0 … IV_7). Next, we compute W_i and then use these values to fill the P and Q tables:

Figure [Ref]

Keystream expansion

In this stage, we generate the key stream (s). Each step will update one of the entries in either the P table or the Q table:

Figure [Ref]

This will then create the S-box values for the SHA-256 operation. Once generated, the plaintext and cipher stream is just EX-ORed with the expanded key stream.

Coding

The outline code using Rust is [here]:

use hc_256::Hc256;
use rand::thread_rng;
use rand::Rng;
use hc_256::cipher::{KeyIvInit, StreamCipher};
use std::str;
use std::env;
fn get_random_key32() ->  [u8; 32]{
let mut arr = [0u8; 32];
thread_rng().try_fill(&mut arr[..]).expect("Ooops!");
return arr;
}
fn main() {

let key = get_random_key32();
let nonce = get_random_key32();
let args: Vec<String> = env::args().collect();
let mut msg="Test";
if args.len() >1 {
    msg = args[1].as_str();
}
let message = String::from(msg);
let plaintext=message.as_bytes();
let len = plaintext.len();
let mut buffer = [0u8; 128];
buffer[..len].copy_from_slice(plaintext);

let mut cipher = Hc256::new(&key.into(), &nonce.into());

cipher.apply_keystream(&mut buffer);
println!("== HC256 ==");
println!("Message: {}",message);
println!("Key {}",hex::encode(&key));
println!("Nonce {}",hex::encode(&nonce));
println!("\nEncrypted: {}",hex::encode(&buffer[0..len]));
let mut cipher = Hc256::new(&key.into(), &nonce.into());
cipher.apply_keystream(&mut buffer);
println!("\nCiphertext: {:?}",str::from_utf8(&buffer[0..len]).unwrap());
}

and Cargo.toml [here]:

[package]
name = "hc256"
version = "0.1.0"
edition = "2021"

[dependencies]
hc-256 = "0.5.0"
hex="0.4.3"
hex-literal="0.3.3"
rand="0.8.3"

A test run is [here]:

== HC256 ==
Message: Hello
Key e01c659e77c0ef0b91abb3cd9b1e6172a0854b8417a2c7b36b999ee6d19f76cf
Nonce 0811c359c9498ff389960d0de31d2bf30a504c219862a028167197cdbf347767
Encrypted: cd896cd27a
Ciphertext: "Hello"

Conclusions

HC-256 is a great example of a fast and secure cipher. If you have time, please read more [here] and you can discover the practical implementation here:

https://asecuritysite.com/rust/rust_hc256