mirror of
https://github.com/BLAKE3-team/BLAKE3
synced 2024-06-07 07:06:05 +02:00
move compression function tests
This commit is contained in:
parent
5ee3d75afa
commit
41ebf95fe2
|
@ -11,3 +11,6 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
cfg-if = "1.0.0"
|
||||
|
||||
[dev-dependencies]
|
||||
reference_impl = { path = "../../reference_impl" }
|
||||
|
|
|
@ -6,6 +6,10 @@ use core::sync::atomic::{AtomicPtr, Ordering::Relaxed};
|
|||
|
||||
mod portable;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
pub const OUT_LEN: usize = 32;
|
||||
pub const BLOCK_LEN: usize = 64;
|
||||
pub const CHUNK_LEN: usize = 1024;
|
||||
pub const WORD_LEN: usize = 4;
|
||||
|
|
|
@ -189,3 +189,19 @@ pub unsafe extern "C" fn universal_hash(
|
|||
) {
|
||||
crate::universal_hash_using_compress(compress, input, input_len, key, counter, out)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
// This is circular but do it anyway.
|
||||
#[test]
|
||||
fn test_compress_vs_portable() {
|
||||
crate::test::test_compress_vs_portable(compress);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_compress_vs_reference() {
|
||||
crate::test::test_compress_vs_reference(compress);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
use crate::*;
|
||||
|
||||
pub const TEST_KEY: CVBytes = *b"whats the Elvish word for friend";
|
||||
|
||||
// Test a few different initial counter values.
|
||||
// - 0: The base case.
|
||||
// - i32::MAX: *No* overflow. But carry bugs in tricky SIMD code can screw this up, if you XOR when
|
||||
// you're supposed to ANDNOT.
|
||||
// - u32::MAX: The low word of the counter overflows for all inputs except the first.
|
||||
// - (42 << 32) + u32::MAX: Same but with a non-zero value in the high word.
|
||||
const INITIAL_COUNTERS: [u64; 4] = [
|
||||
0,
|
||||
i32::MAX as u64,
|
||||
u32::MAX as u64,
|
||||
(42u64 << 32) + u32::MAX as u64,
|
||||
];
|
||||
|
||||
const BLOCK_LENGTHS: [usize; 4] = [0, 1, 63, 64];
|
||||
|
||||
pub fn paint_test_input(buf: &mut [u8]) {
|
||||
for (i, b) in buf.iter_mut().enumerate() {
|
||||
*b = (i % 251) as u8;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn test_compress_vs_portable(compress_fn: CompressFn) {
|
||||
let flags = KEYED_HASH;
|
||||
for block_len in BLOCK_LENGTHS {
|
||||
dbg!(block_len);
|
||||
let mut block = [0; BLOCK_LEN];
|
||||
paint_test_input(&mut block[..block_len]);
|
||||
for counter in INITIAL_COUNTERS {
|
||||
dbg!(counter);
|
||||
let portable_cv = Implementation::portable().compress(
|
||||
&block,
|
||||
block_len as u32,
|
||||
&TEST_KEY,
|
||||
counter,
|
||||
flags,
|
||||
);
|
||||
|
||||
let mut test_cv = TEST_KEY;
|
||||
unsafe {
|
||||
let test_cv_ptr: *mut CVBytes = &mut test_cv;
|
||||
compress_fn(
|
||||
&block,
|
||||
block_len as u32,
|
||||
test_cv_ptr,
|
||||
counter,
|
||||
flags,
|
||||
test_cv_ptr,
|
||||
);
|
||||
}
|
||||
|
||||
assert_eq!(portable_cv, test_cv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn test_compress_vs_reference(compress_fn: CompressFn) {
|
||||
let flags = CHUNK_START | CHUNK_END | ROOT | KEYED_HASH;
|
||||
for block_len in BLOCK_LENGTHS {
|
||||
dbg!(block_len);
|
||||
let mut block = [0; BLOCK_LEN];
|
||||
paint_test_input(&mut block[..block_len]);
|
||||
|
||||
let mut ref_hasher = reference_impl::Hasher::new_keyed(&TEST_KEY);
|
||||
ref_hasher.update(&block[..block_len]);
|
||||
let mut ref_hash = [0u8; 32];
|
||||
ref_hasher.finalize(&mut ref_hash);
|
||||
|
||||
let mut test_cv = TEST_KEY;
|
||||
unsafe {
|
||||
let test_cv_ptr: *mut CVBytes = &mut test_cv;
|
||||
compress_fn(&block, block_len as u32, test_cv_ptr, 0, flags, test_cv_ptr);
|
||||
}
|
||||
|
||||
assert_eq!(ref_hash, test_cv);
|
||||
}
|
||||
}
|
45
src/test.rs
45
src/test.rs
|
@ -1,9 +1,6 @@
|
|||
use crate::platform::{ParentInOut, TransposedVectors, MAX_SIMD_DEGREE};
|
||||
use crate::{
|
||||
CVBytes, CVWords, IncrementCounter, BLOCK_LEN, CHUNK_LEN, OUT_LEN, UNIVERSAL_HASH_LEN,
|
||||
};
|
||||
use blake3_guts as guts;
|
||||
use guts::{CVBytes, CVWords, BLOCK_LEN, CHUNK_LEN, OUT_LEN, UNIVERSAL_HASH_LEN};
|
||||
|
||||
use arrayref::array_ref;
|
||||
use arrayvec::ArrayVec;
|
||||
use core::cmp;
|
||||
use core::usize;
|
||||
|
@ -52,9 +49,7 @@ pub const TEST_CASES_MAX: usize = 100 * CHUNK_LEN;
|
|||
|
||||
// There's a test to make sure these two are equal below.
|
||||
pub const TEST_KEY: &CVBytes = b"whats the Elvish word for friend";
|
||||
pub const TEST_KEY_WORDS: &CVWords = &[
|
||||
1952540791, 1752440947, 1816469605, 1752394102, 1919907616, 1868963940, 1919295602, 1684956521,
|
||||
];
|
||||
pub const TEST_KEY_WORDS: &CVWords = &guts::words_from_le_bytes_32(TEST_KEY);
|
||||
|
||||
// Test a few different initial counter values.
|
||||
// - 0: The base case.
|
||||
|
@ -73,40 +68,6 @@ pub fn paint_test_input(buf: &mut [u8]) {
|
|||
}
|
||||
}
|
||||
|
||||
type CompressInPlaceFn =
|
||||
unsafe fn(cv: &mut CVWords, block: &[u8; BLOCK_LEN], block_len: u8, counter: u64, flags: u8);
|
||||
|
||||
type CompressXofFn = unsafe fn(
|
||||
cv: &CVWords,
|
||||
block: &[u8; BLOCK_LEN],
|
||||
block_len: u8,
|
||||
counter: u64,
|
||||
flags: u8,
|
||||
) -> [u8; 64];
|
||||
|
||||
// A shared helper function for platform-specific tests.
|
||||
pub fn test_compress_fn(compress_in_place_fn: CompressInPlaceFn, compress_xof_fn: CompressXofFn) {
|
||||
let initial_state = *TEST_KEY_WORDS;
|
||||
let block_len: u8 = 61;
|
||||
let mut block = [0; BLOCK_LEN];
|
||||
paint_test_input(&mut block[..block_len as usize]);
|
||||
// Use a counter with set bits in both 32-bit words.
|
||||
let counter = (5u64 << 32) + 6;
|
||||
let flags = crate::CHUNK_END | crate::ROOT | crate::KEYED_HASH;
|
||||
|
||||
let portable_out =
|
||||
crate::portable::compress_xof(&initial_state, &block, block_len, counter as u64, flags);
|
||||
|
||||
let mut test_state = initial_state;
|
||||
unsafe { compress_in_place_fn(&mut test_state, &block, block_len, counter as u64, flags) };
|
||||
let test_state_bytes = crate::platform::le_bytes_from_words_32(&test_state);
|
||||
let test_xof =
|
||||
unsafe { compress_xof_fn(&initial_state, &block, block_len, counter as u64, flags) };
|
||||
|
||||
assert_eq!(&portable_out[..32], &test_state_bytes[..]);
|
||||
assert_eq!(&portable_out[..], &test_xof[..]);
|
||||
}
|
||||
|
||||
type HashManyFn<A> = unsafe fn(
|
||||
inputs: &[&A],
|
||||
key: &CVWords,
|
||||
|
|
Loading…
Reference in New Issue