#![cfg(feature = "poseidon")]
use light_hasher::{
hash_chain::{create_hash_chain_from_slice, create_two_inputs_hash_chain},
Hasher, HasherError, Poseidon,
};
#[test]
fn test_create_hash_chain_from_slice() {
{
let inputs: [[u8; 32]; 3] = [[1u8; 32], [2u8; 32], [3u8; 32]];
let intermediate_hash_1 = Poseidon::hashv(&[&inputs[0], &inputs[1]]).unwrap();
let expected_hash = Poseidon::hashv(&[&intermediate_hash_1, &inputs[2]]).unwrap();
let result = create_hash_chain_from_slice(&inputs).unwrap();
assert_eq!(
result, expected_hash,
"Functional test with hardcoded values failed."
);
}
{
let inputs: [[u8; 32]; 2] = [[4u8; 32], [5u8; 32]];
let expected_hash = Poseidon::hashv(&[&inputs[0], &inputs[1]]).unwrap();
let hard_coded_expected_hash = [
13, 250, 206, 124, 182, 159, 160, 87, 57, 23, 80, 155, 25, 43, 40, 136, 228, 255, 201,
1, 22, 168, 211, 220, 176, 187, 23, 176, 46, 198, 140, 211,
];
let result = create_hash_chain_from_slice(&inputs).unwrap();
assert_eq!(
result, expected_hash,
"Functional test with manual hash comparison failed."
);
assert_eq!(result, hard_coded_expected_hash);
}
{
let inputs = [[4u8; 32], [5u8; 32], [6u8; 32]];
let expected_hash = Poseidon::hashv(&[&inputs[0], &inputs[1]]).unwrap();
let expected_hash = Poseidon::hashv(&[&expected_hash, &inputs[2]]).unwrap();
let hard_coded_expected_hash = [
12, 74, 32, 81, 132, 82, 10, 115, 75, 248, 169, 125, 228, 230, 140, 167, 149, 181, 244,
194, 63, 201, 26, 150, 142, 4, 60, 16, 77, 145, 194, 152,
];
let result = create_hash_chain_from_slice(&inputs).unwrap();
assert_eq!(
result, expected_hash,
"Functional test with manual hash comparison failed."
);
assert_eq!(result, hard_coded_expected_hash);
}
{
let inputs: [[u8; 32]; 2] = [[6u8; 32], [7u8; 32]];
let first_hash = create_hash_chain_from_slice(&inputs).unwrap();
let second_hash = create_hash_chain_from_slice(&inputs).unwrap();
assert_eq!(
first_hash, second_hash,
"Determinism test failed: Hashes do not match."
);
}
{
let inputs: [[u8; 32]; 0] = [];
let result = create_hash_chain_from_slice(&inputs).unwrap();
assert_eq!(result, [0u8; 32], "Empty input should return zero hash");
}
#[cfg(feature = "poseidon")]
{
use ark_ff::PrimeField;
use light_hasher::bigint::bigint_to_be_bytes_array;
use light_poseidon::PoseidonError;
use num_bigint::BigUint;
let modulus: BigUint = ark_bn254::Fr::MODULUS.into();
let modulus_bytes: [u8; 32] = bigint_to_be_bytes_array(&modulus).unwrap();
let huge_input = vec![modulus_bytes, modulus_bytes];
let result = create_hash_chain_from_slice(&huge_input);
assert!(
matches!(result, Err(HasherError::Poseidon(error)) if error == PoseidonError::InputLargerThanModulus),
);
}
}
#[test]
fn test_create_two_inputs_hash_chain() {
{
let hashes_first: &[[u8; 32]] = &[];
let hashes_second: &[[u8; 32]] = &[];
let result = create_two_inputs_hash_chain(hashes_first, hashes_second).unwrap();
assert_eq!(result, [0u8; 32], "Empty input should return zero hash");
}
{
let hashes_first: &[[u8; 32]] = &[[1u8; 32]];
let hashes_second: &[[u8; 32]] = &[[2u8; 32]];
let expected_hash = Poseidon::hashv(&[&hashes_first[0], &hashes_second[0]]).unwrap();
let result = create_two_inputs_hash_chain(hashes_first, hashes_second).unwrap();
assert_eq!(result, expected_hash, "Single input each test failed");
}
{
let hashes_first: &[[u8; 32]] = &[[1u8; 32], [2u8; 32]];
let hashes_second: &[[u8; 32]] = &[[3u8; 32], [4u8; 32]];
let intermediate_hash = Poseidon::hashv(&[&hashes_first[0], &hashes_second[0]]).unwrap();
let expected_hash =
Poseidon::hashv(&[&intermediate_hash, &hashes_first[1], &hashes_second[1]]).unwrap();
let result = create_two_inputs_hash_chain(hashes_first, hashes_second).unwrap();
assert_eq!(result, expected_hash, "Two inputs each test failed");
}
{
let hashes_first: &[[u8; 32]] = &[[1u8; 32]];
let hashes_second: &[[u8; 32]] = &[[2u8; 32], [3u8; 32]];
let result = create_two_inputs_hash_chain(hashes_first, hashes_second);
assert!(
matches!(result, Err(HasherError::InvalidInputLength(1, 2))),
"Invalid input length for hashes_first test failed"
);
}
{
let hashes_first: &[[u8; 32]] = &[[1u8; 32], [2u8; 32]];
let hashes_second: &[[u8; 32]] = &[[3u8; 32]];
let result = create_two_inputs_hash_chain(hashes_first, hashes_second);
assert!(
matches!(result, Err(HasherError::InvalidInputLength(2, 1))),
"Invalid input length for hashes_second test failed"
);
}
}