refactor(alg): smaller alg changes for testing and qol
This commit is contained in:
parent
1e827d6b8a
commit
347e752e37
8 changed files with 141 additions and 65 deletions
20
Cargo.lock
generated
20
Cargo.lock
generated
|
@ -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"
|
||||
|
|
|
@ -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"]
|
||||
|
|
0
crates/algorithms/src/bin/crc32sum.rs
Normal file
0
crates/algorithms/src/bin/crc32sum.rs
Normal file
27
crates/algorithms/src/bin/sha256sum.rs
Normal file
27
crates/algorithms/src/bin/sha256sum.rs
Normal 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)
|
||||
}
|
|
@ -1,5 +1,3 @@
|
|||
use core::ffi::c_void;
|
||||
|
||||
unsafe extern "C" {
|
||||
fn algorithms_c_is_loaded() -> i32;
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue