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 = [
|
dependencies = [
|
||||||
"assert_hex",
|
"assert_hex",
|
||||||
"criterion",
|
"criterion",
|
||||||
|
"getopts",
|
||||||
"iai",
|
"iai",
|
||||||
"pretty_assertions",
|
"pretty_assertions",
|
||||||
]
|
]
|
||||||
|
@ -115,7 +116,7 @@ checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"textwrap",
|
"textwrap",
|
||||||
"unicode-width",
|
"unicode-width 0.1.14",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -321,6 +322,15 @@ dependencies = [
|
||||||
"num",
|
"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]]
|
[[package]]
|
||||||
name = "half"
|
name = "half"
|
||||||
version = "1.8.3"
|
version = "1.8.3"
|
||||||
|
@ -779,7 +789,7 @@ version = "0.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-width",
|
"unicode-width 0.1.14",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -824,6 +834,12 @@ version = "0.1.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
|
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-width"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vcell"
|
name = "vcell"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
|
|
|
@ -4,6 +4,7 @@ version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
getopts = { version = "0.2.23", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
assert_hex = "0.4.1"
|
assert_hex = "0.4.1"
|
||||||
|
@ -23,3 +24,14 @@ harness = false
|
||||||
default = []
|
default = []
|
||||||
std = []
|
std = []
|
||||||
show_internals = ["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" {
|
unsafe extern "C" {
|
||||||
fn algorithms_c_is_loaded() -> i32;
|
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 {
|
mod test {
|
||||||
use crate::hash::Digest256;
|
use crate::hash::Digest256;
|
||||||
use crate::hash::ffi::sha2_256_oneshot;
|
use crate::hash::ffi::sha2_256_oneshot;
|
||||||
|
use crate::hash::test::TEST_VALUES;
|
||||||
const TEST_VALUES: &[(&str, Digest256)] = &[
|
|
||||||
(
|
|
||||||
"AAAA",
|
|
||||||
[
|
|
||||||
0x63c1dd95, 0x1ffedf6f, 0x7fd968ad, 0x4efa39b8, 0xed584f16, 0x2f46e715, 0x114ee184,
|
|
||||||
0xf8de9201,
|
|
||||||
],
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"BAAA",
|
|
||||||
[
|
|
||||||
0x49e3cd45, 0x27c96cdc, 0x010160ff, 0x08520e0c, 0xb63c6ef8, 0xc4e7d486, 0x08995343,
|
|
||||||
0x7f83a159,
|
|
||||||
],
|
|
||||||
),
|
|
||||||
];
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_check() {
|
fn test_sha2_ffi_check() {
|
||||||
for (input, expected_output) in TEST_VALUES.iter().copied() {
|
for (input, expected_output) in TEST_VALUES.iter().copied() {
|
||||||
assert_eq!(sha2_256_oneshot(input.as_bytes()), Ok(expected_output))
|
assert_eq!(sha2_256_oneshot(input.as_bytes()), Ok(expected_output))
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,3 +4,76 @@ mod sha2;
|
||||||
pub use sha2::*;
|
pub use sha2::*;
|
||||||
|
|
||||||
pub const HASH_EXAMPLE_DATA: &[u8] = b"lalilolela";
|
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) {
|
pub fn clear(&mut self) {
|
||||||
*self = Self::new();
|
*self = Self::new();
|
||||||
}
|
}
|
||||||
|
@ -206,6 +207,7 @@ impl Sha2_256Context {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn finalize(&mut self) {
|
fn finalize(&mut self) {
|
||||||
self.pad_block();
|
self.pad_block();
|
||||||
}
|
}
|
||||||
|
@ -260,20 +262,24 @@ impl Sha2_256Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is a different function for W
|
/// This is a different function for W
|
||||||
|
#[inline]
|
||||||
fn sha256_sigma0_w(word: u32) -> u32 {
|
fn sha256_sigma0_w(word: u32) -> u32 {
|
||||||
Self::sha256_rotr(7, word) ^ Self::sha256_rotr(18, word) ^ Self::sha256_shr(3, word)
|
Self::sha256_rotr(7, word) ^ Self::sha256_rotr(18, word) ^ Self::sha256_shr(3, word)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is a different function for W
|
/// This is a different function for W
|
||||||
|
#[inline]
|
||||||
fn sha256_sigma1_w(word: u32) -> u32 {
|
fn sha256_sigma1_w(word: u32) -> u32 {
|
||||||
Self::sha256_rotr(17, word) ^ Self::sha256_rotr(19, word) ^ Self::sha256_shr(10, word)
|
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!
|
// NOTE: these do not use shift right for the last internal variable!
|
||||||
|
#[inline]
|
||||||
fn sha256_sigma0(word: u32) -> u32 {
|
fn sha256_sigma0(word: u32) -> u32 {
|
||||||
Self::sha256_rotr(2, word) ^ Self::sha256_rotr(13, word) ^ Self::sha256_rotr(22, word)
|
Self::sha256_rotr(2, word) ^ Self::sha256_rotr(13, word) ^ Self::sha256_rotr(22, word)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn sha256_sigma1(word: u32) -> u32 {
|
fn sha256_sigma1(word: u32) -> u32 {
|
||||||
Self::sha256_rotr(6, word) ^ Self::sha256_rotr(11, word) ^ Self::sha256_rotr(25, word)
|
Self::sha256_rotr(6, word) ^ Self::sha256_rotr(11, word) ^ Self::sha256_rotr(25, word)
|
||||||
}
|
}
|
||||||
|
@ -285,7 +291,7 @@ impl Sha2_256Context {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sha_maj(x: u32, y: u32, z: u32) -> u32 {
|
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)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::assert_eq_bin;
|
||||||
|
use crate::hash::test::TEST_VALUES;
|
||||||
use assert_hex::*;
|
use assert_hex::*;
|
||||||
use pretty_assertions::{assert_eq, assert_ne};
|
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]
|
#[test]
|
||||||
fn test_sha256_check() {
|
fn test_sha256_check() {
|
||||||
let mut dig;
|
let mut dig;
|
||||||
|
|
Loading…
Add table
Reference in a new issue