refactor(alg): smaller alg changes for testing and qol

This commit is contained in:
cscherr 2025-07-22 13:26:57 +02:00
parent 1e827d6b8a
commit 347e752e37
Signed by: cscherrNT
GPG key ID: 8E2B45BC51A27EA7
8 changed files with 141 additions and 65 deletions

20
Cargo.lock generated
View file

@ -17,6 +17,7 @@ version = "0.1.0"
dependencies = [
"assert_hex",
"criterion",
"getopts",
"iai",
"pretty_assertions",
]
@ -115,7 +116,7 @@ checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
dependencies = [
"bitflags",
"textwrap",
"unicode-width",
"unicode-width 0.1.14",
]
[[package]]
@ -321,6 +322,15 @@ dependencies = [
"num",
]
[[package]]
name = "getopts"
version = "0.2.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cba6ae63eb948698e300f645f87c70f76630d505f23b8907cf1e193ee85048c1"
dependencies = [
"unicode-width 0.2.1",
]
[[package]]
name = "half"
version = "1.8.3"
@ -779,7 +789,7 @@ version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
"unicode-width 0.1.14",
]
[[package]]
@ -824,6 +834,12 @@ version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
[[package]]
name = "unicode-width"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c"
[[package]]
name = "vcell"
version = "0.1.3"

View file

@ -4,6 +4,7 @@ version = "0.1.0"
edition = "2024"
[dependencies]
getopts = { version = "0.2.23", optional = true }
[dev-dependencies]
assert_hex = "0.4.1"
@ -23,3 +24,14 @@ harness = false
default = []
std = []
show_internals = ["std"]
getopts = ["dep:getopts"]
[[bin]]
path = "src/bin/crc32sum.rs"
name = "crc32sum"
required-features = ["std"]
[[bin]]
path = "src/bin/sha256sum.rs"
name = "sha256sum"
required-features = ["std"]

View file

View file

@ -0,0 +1,27 @@
use algorithms::hash::format_digest;
fn main() {
let args: Vec<String> = std::env::args().collect();
let use_ffi = args.contains(&"-c".to_string());
if args.len() < 2 {
usage(&args[0], 1)
}
let input = &args[1];
println!("{:x?}", input.as_bytes());
let raw_in = input.as_bytes();
let hash = if use_ffi {
algorithms::hash::ffi::sha2_256_oneshot(raw_in).expect("could not hash your input data")
} else {
algorithms::hash::sha2_256_oneshot(raw_in).expect("could not hash your input data")
};
println!("{}", format_digest(&bytes(&hash)));
}
fn bytes(data: &[u32]) -> Vec<u8> {
data.iter().flat_map(|x| x.to_ne_bytes()).collect()
}
fn usage(call: &str, code: i32) -> ! {
println!("USAGE: {call} INPUT [-c]");
std::process::exit(code)
}

View file

@ -1,5 +1,3 @@
use core::ffi::c_void;
unsafe extern "C" {
fn algorithms_c_is_loaded() -> i32;
}

View file

@ -105,26 +105,10 @@ pub(crate) fn to_res<T>(if_ok: T, res: SHA2Outcome) -> Result<T, SHA2Outcome> {
mod test {
use crate::hash::Digest256;
use crate::hash::ffi::sha2_256_oneshot;
const TEST_VALUES: &[(&str, Digest256)] = &[
(
"AAAA",
[
0x63c1dd95, 0x1ffedf6f, 0x7fd968ad, 0x4efa39b8, 0xed584f16, 0x2f46e715, 0x114ee184,
0xf8de9201,
],
),
(
"BAAA",
[
0x49e3cd45, 0x27c96cdc, 0x010160ff, 0x08520e0c, 0xb63c6ef8, 0xc4e7d486, 0x08995343,
0x7f83a159,
],
),
];
use crate::hash::test::TEST_VALUES;
#[test]
fn test_check() {
fn test_sha2_ffi_check() {
for (input, expected_output) in TEST_VALUES.iter().copied() {
assert_eq!(sha2_256_oneshot(input.as_bytes()), Ok(expected_output))
}

View file

@ -4,3 +4,76 @@ mod sha2;
pub use sha2::*;
pub const HASH_EXAMPLE_DATA: &[u8] = b"lalilolela";
#[cfg(feature = "std")]
pub fn format_digest(digest: &[u8]) -> String {
digest
.iter()
.map(|b| format!("{b:02x}"))
.collect::<String>()
}
#[cfg(test)]
pub(crate) mod test {
use super::*;
use assert_hex::*;
use pretty_assertions::{assert_eq, assert_ne};
#[macro_export]
macro_rules! assert_eq_bin {
($left:expr, $right:expr $(,)?) => ({
match (&$left, &$right) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
panic!(r#"assertion `left == right` failed
left: {:b}
right: {:b}"#, &*left_val, &*right_val)
}
}
}
});
($left:expr, $right:expr, $($arg:tt)+) => ({
match (&($left), &($right)) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
panic!(r#"assertion `left == right` failed: {}
left: {:b}
right: {:b}"#, format_args!($($arg)+), &*left_val, &*right_val)
}
}
}
});
}
pub(crate) const TEST_VALUES: &[(&str, Digest256)] = &[
(
"AAAA",
[
0x63c1dd95, 0x1ffedf6f, 0x7fd968ad, 0x4efa39b8, 0xed584f16, 0x2f46e715, 0x114ee184,
0xf8de9201,
],
),
(
"BAAA",
[
0x49e3cd45, 0x27c96cdc, 0x010160ff, 0x08520e0c, 0xb63c6ef8, 0xc4e7d486, 0x08995343,
0x7f83a159,
],
),
];
#[test]
fn test_sha2_ffi_same_as_native() {
let mut dig_native;
let mut dig_ffi;
for (input, expected_output) in TEST_VALUES.iter().copied() {
dig_native = sha2_256_oneshot(input.as_bytes()).unwrap();
dig_ffi = ffi::sha2_256_oneshot(input.as_bytes()).unwrap();
assert_eq_hex!(
dig_native,
dig_ffi,
"ffi does not return the same result as native"
)
}
}
}

View file

@ -53,6 +53,7 @@ impl Sha2_256Context {
}
}
#[inline]
pub fn clear(&mut self) {
*self = Self::new();
}
@ -206,6 +207,7 @@ impl Sha2_256Context {
Ok(())
}
#[inline]
fn finalize(&mut self) {
self.pad_block();
}
@ -260,20 +262,24 @@ impl Sha2_256Context {
}
/// This is a different function for W
#[inline]
fn sha256_sigma0_w(word: u32) -> u32 {
Self::sha256_rotr(7, word) ^ Self::sha256_rotr(18, word) ^ Self::sha256_shr(3, word)
}
/// This is a different function for W
#[inline]
fn sha256_sigma1_w(word: u32) -> u32 {
Self::sha256_rotr(17, word) ^ Self::sha256_rotr(19, word) ^ Self::sha256_shr(10, word)
}
// NOTE: these do not use shift right for the last internal variable!
#[inline]
fn sha256_sigma0(word: u32) -> u32 {
Self::sha256_rotr(2, word) ^ Self::sha256_rotr(13, word) ^ Self::sha256_rotr(22, word)
}
#[inline]
fn sha256_sigma1(word: u32) -> u32 {
Self::sha256_rotr(6, word) ^ Self::sha256_rotr(11, word) ^ Self::sha256_rotr(25, word)
}
@ -285,7 +291,7 @@ impl Sha2_256Context {
#[inline]
fn sha_maj(x: u32, y: u32, z: u32) -> u32 {
(x & (y | z)) | (y & z)
(x & y) ^ (x & z) ^ (y & z)
}
}
@ -347,51 +353,11 @@ use debug::*;
#[cfg(test)]
mod test {
use super::*;
use crate::assert_eq_bin;
use crate::hash::test::TEST_VALUES;
use assert_hex::*;
use pretty_assertions::{assert_eq, assert_ne};
macro_rules! assert_eq_bin {
($left:expr, $right:expr $(,)?) => ({
match (&$left, &$right) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
panic!(r#"assertion `left == right` failed
left: {:b}
right: {:b}"#, &*left_val, &*right_val)
}
}
}
});
($left:expr, $right:expr, $($arg:tt)+) => ({
match (&($left), &($right)) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
panic!(r#"assertion `left == right` failed: {}
left: {:b}
right: {:b}"#, format_args!($($arg)+), &*left_val, &*right_val)
}
}
}
});
}
const TEST_VALUES: &[(&str, Digest256)] = &[
(
"AAAA",
[
0x63c1dd95, 0x1ffedf6f, 0x7fd968ad, 0x4efa39b8, 0xed584f16, 0x2f46e715, 0x114ee184,
0xf8de9201,
],
),
(
"BAAA",
[
0x49e3cd45, 0x27c96cdc, 0x010160ff, 0x08520e0c, 0xb63c6ef8, 0xc4e7d486, 0x08995343,
0x7f83a159,
],
),
];
#[test]
fn test_sha256_check() {
let mut dig;