use std::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
use clap::{Parser, ValueEnum};
#[derive(Debug, ValueEnum, Clone)]
pub enum HashingAlgo {
Sha512,
Sha256,
}
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
pub struct Args {
#[arg(short, long, value_enum)]
pub algo: HashingAlgo,
#[arg(short, long)]
pub file: Option<String>,
#[arg(short, long)]
pub time: bool,
}
pub(crate) fn sum_0<T>(x: T, (a, b, c): (usize, usize, usize)) -> T
where
T: Shr<usize, Output = T>
+ Shl<usize, Output = T>
+ BitOr<T, Output = T>
+ BitXor<T, Output = T>
+ Clone
+ Copy,
{
right_rotate(x, a) ^ right_rotate(x, b) ^ right_rotate(x, c)
}
pub(crate) fn sum_1<T>(x: T, (a, b, c): (usize, usize, usize)) -> T
where
T: Shr<usize, Output = T>
+ Shl<usize, Output = T>
+ BitOr<T, Output = T>
+ BitXor<T, Output = T>
+ Clone
+ Copy,
{
right_rotate(x, a) ^ right_rotate(x, b) ^ right_rotate(x, c)
}
pub(crate) fn sigma_0<T>(x: T, (a, b, c): (usize, usize, usize)) -> T
where
T: Shr<usize, Output = T>
+ Shl<usize, Output = T>
+ BitOr<T, Output = T>
+ BitXor<T, Output = T>
+ Clone
+ Copy,
{
right_rotate(x, a) ^ right_rotate(x, b) ^ right_shift(x, c)
}
pub(crate) fn sigma_1<T>(x: T, (a, b, c): (usize, usize, usize)) -> T
where
T: Shr<usize, Output = T>
+ Shl<usize, Output = T>
+ BitOr<T, Output = T>
+ BitXor<T, Output = T>
+ Clone
+ Copy,
{
right_rotate(x, a) ^ right_rotate(x, b) ^ right_shift(x, c)
}
pub(crate) fn right_rotate<T>(num: T, bits: usize) -> T
where
T: Shr<usize, Output = T> + Shl<usize, Output = T> + BitOr<T, Output = T> + Clone,
{
let bit_width = std::mem::size_of_val(&num) * 8;
let bits = bits % bit_width;
(num.clone() << (bit_width - bits)) | (num.clone() >> (bits))
}
pub(crate) fn right_shift<T>(num: T, bits: usize) -> T
where
T: Shr<usize, Output = T> + Shl<usize, Output = T> + BitOr<T, Output = T>,
{
let bits = bits % 32;
num >> (bits)
}
pub(crate) fn ch<T>(x: T, y: T, z: T) -> T
where
T: BitAnd<T, Output = T> + BitXor<T, Output = T> + Not<Output = T> + Copy,
{
(x & y) ^ (!x & z)
}
pub(crate) fn maj<T>(x: T, y: T, z: T) -> T
where
T: BitAnd<T, Output = T> + BitXor<T, Output = T> + Copy,
{
(x & y) ^ (x & z) ^ (y & z)
}
pub(crate) fn k_value(
l: usize,
one_bit: Option<usize>,
padding_size: usize,
buffer_size: usize,
) -> usize {
match one_bit {
None => (buffer_size - ((l + padding_size + 1) % buffer_size)) % buffer_size,
Some(v) => (buffer_size - ((l + padding_size + v) % buffer_size)) % buffer_size,
}
}