cuprate/cryptonight/src/util.rs
Dmitry Holodov 00bdd6ffaa
cryptonight in pure Rust (#271)
* removed FORCE_USE_HEAP to from c code

* removed unused headers

* simplifying C code to better understand it

* more c code simplifications

* removed conditional code for the v4 register size

* got one version of keccak working

* not so important hash_process unwound

* got keccak working using the sha3 lib

* hash state unions created

* slow hash through VARIANT1_PORTABLE_INIT is working

* variant 2 init working

* ported version of random_math_init compiling, but not yet passing tests

* fixed hash algorithm, tests working

* formatting

* more macro reduction

* monero AES working in Rust

* fixed AES key expansion expected key size

* first 75% of slow hash converted and working correctly

* adjusted key format for aesb_single_round

* converted some macros to functions

* variant2_integer_math working with test cases

* broke sqrt out of variant2_integer_math for code coverage

* variant2_portable_shuffle_add working with unit tests

* added skein and jh hashes

* 524287 iteration loop producing correct results

* all tests working in Rust

* subarray macros added

* aes simplifications

* code cleanups

* code cleanups part 2

* removed unused blake C code as prep for port to rust

* original blake algorithm in pure rust is working

* converted macro in compress to a lamda

* added module documentation for blake256

* Gave Blake256 a Digest trait

* adding more documentation

* more documentation and cleanup

* more slow hash tests

* removed C code

* misc refactoring

* fix

* lint fix

* additional linting

* downgraded deps to latest stable versions

* made thiserror a workspace dep

* removed commented dead code

* lint fixes

* fixed lint issues in test code

* limited util macro scopes to the crate

* Reformatted dependencies using:
group_imports = "StdExternalCrate"
reorder_modules = true
reorder_impl_items = true
imports_granularity = "crate"

* converted util macros to inline functions

* hex dep comes from workspace

Co-authored-by: hinto-janai <hinto.janai@protonmail.com>

* panic subarray tests

Co-authored-by: hinto-janai <hinto.janai@protonmail.com>

* updates to doc comments

* removes extra parens in hash_v4.rs

Co-authored-by: hinto-janai <hinto.janai@protonmail.com>

* early return to remove indentation in hash_v2.rs

Co-authored-by: hinto-janai <hinto.janai@protonmail.com>

* gropuing expect annotations in hash_v2.rs

Co-authored-by: hinto-janai <hinto.janai@protonmail.com>

* use matches macro to simplify code hash_v4.rs

Co-authored-by: hinto-janai <hinto.janai@protonmail.com>

* remove extra paren in hash_v4.rs

Co-authored-by: hinto-janai <hinto.janai@protonmail.com>

* eary return to remove indentation in hash_v2.rs

Co-authored-by: hinto-janai <hinto.janai@protonmail.com>

* minor comment fixes

* early loop continue to remove indentation in hash_v4.rs

Co-authored-by: hinto-janai <hinto.janai@protonmail.com>

* convert non-capturing llamda to fn in hash_v2.rs

Co-authored-by: hinto-janai <hinto.janai@protonmail.com>

* another lamda to fn conversion in hash_v2.rs

Co-authored-by: hinto-janai <hinto.janai@protonmail.com>

* llamda to fn conversion in cnaes.rs

Co-authored-by: hinto-janai <hinto.janai@protonmail.com>

* 2nd llamda to fn conversion in cnaes.rs

Co-authored-by: hinto-janai <hinto.janai@protonmail.com>

* test lamdas in lib.rs are now functions

* round_fwd optimized

* added myself as an author

* fixed place that needed wrapping_add

* clippy allow->expect change needed after merging master

* moving state to u128

* round_fwd changes sped up fuzzer by 10%

* 1st working version using u128 for long state

* text converted to u128 array

* removed LongState union

* simplified long_state's initialization

* aes round keys now use u128

* CRYPTONIGHT_SBOX is now u32 instead of u8

* cleaner hash_v4 loop unrolling semantics (same peformance)

* switched to a better maintained loop unrolling macro
2024-10-08 16:03:56 +01:00

122 lines
3.5 KiB
Rust

/// Extracts a fixed-size subarray from an array, slice, or vector of any type.
/// No copy is made.
///
/// # Parameters
/// - `array`: Input array, slice, or vector of values.
/// - `start`: Starting index of the subarray.
///
/// # Returns
/// A reference to a fixed-size subarray of type `[U; LEN]`.
///
/// # Panics
/// Panics if `start + LEN > array.as_ref().len()`.
#[inline]
pub(crate) fn subarray<T: AsRef<[U]> + ?Sized, U, const LEN: usize>(
array: &T,
start: usize,
) -> &[U; LEN] {
array.as_ref()[start..start + LEN].try_into().unwrap()
}
/// Creates a new fixed-size array copying the elements from the specified subarray
/// of a parent array, slice, or vector.
///
/// # Parameters
/// - `array`: Input array, slice, or vector of copyable values.
/// - `start`: Starting index of the subarray.
///
/// # Returns
/// A new fixed-size array of type `[u8; LEN]`.
///
/// # Panics
/// Panics if `start + LEN > array.as_ref().len()`.
#[inline]
pub(crate) fn subarray_copy<T: AsRef<[U]> + ?Sized, U: Copy, const LEN: usize>(
array: &T,
start: usize,
) -> [U; LEN] {
array.as_ref()[start..start + LEN].try_into().unwrap()
}
/// Extracts a mutable subarray from an array, slice, or vector of any type.
/// Changes to the subarray will be reflected in the original array.
///
/// # Parameters
/// - `array`: Input array, slice, or vector of values.
/// - `start`: Starting index of the subarray.
///
/// # Returns
/// A mutable reference to a fixed-size subarray of type `[U; LEN]`.
///
/// # Panics
/// Panics if `start + LEN > array.as_ref().len()`.
#[inline]
pub(crate) fn subarray_mut<T: AsMut<[U]> + ?Sized, U, const LEN: usize>(
array: &mut T,
start: usize,
) -> &mut [U; LEN] {
(&mut array.as_mut()[start..start + LEN])
.try_into()
.unwrap()
}
#[cfg(test)]
pub(crate) fn hex_to_array<const N: usize>(hex: &str) -> [u8; N] {
assert_eq!(
hex.len(),
N * 2,
"Hex string length must be twice the array size"
);
hex::decode(hex).unwrap().try_into().unwrap()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_subarray() {
let array = [1_u8, 2, 3, 4, 5];
let sub: &[u8; 3] = subarray(&array, 1);
assert_eq!(sub, &[2, 3, 4]);
assert!(std::ptr::eq(&array[1], &sub[0])); // same memory, not copy
}
#[test]
fn test_subarray_copy() {
let mut array = [1_u8, 2, 3, 4, 5];
let sub_copied: [u8; 3] = subarray_copy(&array, 1);
assert_eq!(sub_copied, [2, 3, 4]);
array[1] = 10;
assert_eq!(sub_copied, [2, 3, 4]); // copy, not affected
}
#[test]
fn test_subarray_mut() {
let mut array = [1_u8, 2, 3, 4, 5];
let sub: &mut [u8; 2] = subarray_mut(&mut array, 1);
assert_eq!(sub, &[2_u8, 3]);
sub[0] = 10;
assert_eq!(array, [1_u8, 10, 3, 4, 5]); // original array modified
}
#[test]
#[should_panic(expected = "range end index 4 out of range for slice of length 1")]
fn subarray_panic() {
let array = [1_u8];
let _: &[u8; 3] = subarray(&array, 1);
}
#[test]
#[should_panic(expected = "range end index 4 out of range for slice of length 1")]
fn subarray_copy_panic() {
let array = [1_u8];
let _: [u8; 3] = subarray_copy(&array, 1);
}
#[test]
#[should_panic(expected = "range end index 4 out of range for slice of length 1")]
fn subarray_mut_panic() {
let mut array = [1_u8];
let _: &mut [u8; 3] = subarray_mut(&mut array, 1);
}
}