Initial commit
This commit is contained in:
commit
f057e6f039
3 changed files with 441 additions and 0 deletions
276
Cargo.lock
generated
Normal file
276
Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"is_terminal_polyfill",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"once_cell_polyfill",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "chacha"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"clap-num",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap-num"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "822c4000301ac390e65995c62207501e3ef800a1fc441df913a5e8e4dc374816"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell_polyfill"
|
||||
version = "1.70.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.60.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.53.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
||||
8
Cargo.toml
Normal file
8
Cargo.toml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "chacha"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.5.47", features = ["derive"] }
|
||||
clap-num = "1.2.0"
|
||||
157
src/main.rs
Normal file
157
src/main.rs
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
#![feature(portable_simd)]
|
||||
#![feature(slice_as_array)]
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::{stdin, stdout, Read, Write};
|
||||
use std::simd::u32x16;
|
||||
use clap::Parser;
|
||||
use clap_num::maybe_hex;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(version, about, long_about = None)]
|
||||
struct Args {
|
||||
/// Where the key is stored
|
||||
#[arg(short, long)]
|
||||
key_file: String,
|
||||
|
||||
/// The amount of chacha rounds to do
|
||||
#[arg(short, long, default_value = "20")]
|
||||
rounds: usize,
|
||||
|
||||
/// The nonce in the initial key value
|
||||
#[arg(short, long, default_value = "0", value_parser=maybe_hex::<u64>)]
|
||||
nonce: u64,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = Args::parse();
|
||||
|
||||
let stdin = stdin();
|
||||
|
||||
let mut input = Vec::new();
|
||||
let mut inp = stdin.lock();
|
||||
inp.read_to_end(&mut input).expect("failed to read from stdin");
|
||||
|
||||
let mut f = File::open(args.key_file).expect("failed to open key file");
|
||||
let key_bytes = &mut [0u8; 32];
|
||||
f.read_exact(key_bytes).expect("couldn't read key file");
|
||||
|
||||
let mut key: [u32; 8] = [0u32; 8];
|
||||
for i in 0..8 {
|
||||
key[i] = u32::from_le_bytes(key_bytes[i * 4..(i + 1) * 4].try_into().unwrap());
|
||||
}
|
||||
|
||||
let mut cipher = make_chacha_block(&key, 0, args.nonce);
|
||||
|
||||
let mut output = Vec::new();
|
||||
let mut data_chunks = input.chunks_exact(64);
|
||||
for c in &mut data_chunks {
|
||||
cipher = chacha_rounds(cipher, args.rounds);
|
||||
let data = u32x16::from(many_u8_to_few_u32(c.try_into().unwrap()));
|
||||
cipher ^= data;
|
||||
output.push(cipher);
|
||||
}
|
||||
|
||||
let mut bytes: Vec<u8> = Vec::new();
|
||||
for d in output {
|
||||
bytes.extend_from_slice(few_u32_to_many_u8(d.as_array()).as_slice());
|
||||
}
|
||||
|
||||
let remainder = data_chunks.remainder();
|
||||
let remaining = remainder.len();
|
||||
if remaining != 0 {
|
||||
let mut padded = [0u8; 64];
|
||||
padded[0..remainder.len()].copy_from_slice(remainder);
|
||||
|
||||
cipher = chacha_rounds(cipher, 20);
|
||||
let data = u32x16::from(many_u8_to_few_u32(padded));
|
||||
cipher ^= data;
|
||||
bytes.extend_from_slice(&few_u32_to_many_u8(cipher.as_array())[..remaining]);
|
||||
}
|
||||
|
||||
let stdout = stdout();
|
||||
let mut out = stdout.lock();
|
||||
out.write_all(bytes.as_slice()).unwrap();
|
||||
}
|
||||
|
||||
fn many_u8_to_few_u32(data: [u8; 64]) -> [u32; 16] {
|
||||
let mut out = [0u32; 16];
|
||||
|
||||
for (i, c) in data.chunks_exact(4).enumerate() {
|
||||
out[i] = u32::from_ne_bytes(c.try_into().unwrap());
|
||||
}
|
||||
|
||||
out
|
||||
}
|
||||
|
||||
fn few_u32_to_many_u8(data: &[u32; 16]) -> [u8; 64] {
|
||||
let mut out = [0u8; 64];
|
||||
|
||||
for (i, c) in data.iter().enumerate() {
|
||||
out[i*4..][..4].copy_from_slice(&u32::to_ne_bytes(*c));
|
||||
}
|
||||
|
||||
out
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn make_chacha_block(key: &[u32; 8], counter: u64, nonce: u64) -> u32x16 {
|
||||
let [k1, k2, k3, k4, k5, k6, k7, k8] = key;
|
||||
|
||||
u32x16::from([
|
||||
u32::from_ne_bytes(*b"expa"),
|
||||
u32::from_ne_bytes(*b"nd 3"),
|
||||
u32::from_ne_bytes(*b"2-by"),
|
||||
u32::from_ne_bytes(*b"te k"),
|
||||
*k1, *k2, *k3, *k4, *k5, *k6, *k7, *k8,
|
||||
(counter >> 32) as u32, (counter & 0xFFFFFFFF) as u32,
|
||||
(nonce >> 32) as u32, (nonce & 0xFFFFFFFF) as u32
|
||||
])
|
||||
}
|
||||
|
||||
fn chacha_rounds(input: u32x16, rounds: usize) -> u32x16 {
|
||||
let x: u32x16 = input;
|
||||
|
||||
for i in 0..rounds {
|
||||
match i & 1 {
|
||||
// odd rounds
|
||||
0 => {
|
||||
chacha_quarter_round(x, 0, 4, 8, 12);
|
||||
chacha_quarter_round(x, 1, 5, 9, 13);
|
||||
chacha_quarter_round(x, 2, 6, 10, 14);
|
||||
chacha_quarter_round(x, 3, 7, 11, 15);
|
||||
}
|
||||
// even rounds
|
||||
1 => {
|
||||
chacha_quarter_round(x, 0, 5, 10, 15);
|
||||
chacha_quarter_round(x, 1, 6, 11, 12);
|
||||
chacha_quarter_round(x, 2, 7, 8, 13);
|
||||
chacha_quarter_round(x, 3, 4, 9, 14);
|
||||
}
|
||||
|
||||
_ => ()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
x + input
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn chacha_quarter_round(mut x: u32x16, a: usize, b: usize, c: usize, d: usize) {
|
||||
x[a] += x[b];
|
||||
x[d] ^= x[a];
|
||||
x[d] = x[d].rotate_left(16);
|
||||
|
||||
x[c] += x[d];
|
||||
x[b] ^= x[c];
|
||||
x[b] = x[b].rotate_left(12);
|
||||
|
||||
x[a] += x[b];
|
||||
x[d] ^= x[a];
|
||||
x[d] = x[d].rotate_left(8);
|
||||
|
||||
x[c] += x[d];
|
||||
x[b] ^= x[c];
|
||||
x[b] = x[b].rotate_left(7);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue