#![cfg(feature = "sha2")]
use bolero::check;
use evidence::codec::Encode;
use evidence::digest::{Digest, DigestPrimitive, DigestUnchecked, sha2::Sha256};
use hybrid_array::Array;
enum Identity {}
impl Encode<Vec<u8>> for Identity {
type Error = core::convert::Infallible;
fn encode(value: &Vec<u8>) -> Result<Vec<u8>, Self::Error> {
Ok(value.clone())
}
}
impl Encode<[u8; 32]> for Identity {
type Error = core::convert::Infallible;
fn encode(value: &[u8; 32]) -> Result<Vec<u8>, Self::Error> {
Ok(value.to_vec())
}
}
#[test]
fn digest_deterministic() {
check!().with_type::<Vec<u8>>().for_each(|data| {
let d1: Digest<Vec<u8>, Sha256, Identity> = Digest::hash(data);
let d2: Digest<Vec<u8>, Sha256, Identity> = Digest::hash(data);
assert_eq!(d1, d2, "same input must produce same digest");
});
}
#[test]
fn digest_roundtrip_array() {
check!().with_type::<[u8; 32]>().for_each(|bytes| {
let array: Array<u8, <Sha256 as DigestPrimitive>::Size> = Array::from(*bytes);
let digest: Digest<(), Sha256, Identity> = Digest::from_unchecked_array(array);
let recovered = digest.into_array();
assert_eq!(array, recovered, "roundtrip must preserve bytes");
});
}
#[test]
fn different_inputs_different_digests() {
check!()
.with_type::<(Vec<u8>, Vec<u8>)>()
.filter(|(a, b)| a != b)
.for_each(|(a, b)| {
let da: Digest<Vec<u8>, Sha256, Identity> = Digest::hash(a);
let db: Digest<Vec<u8>, Sha256, Identity> = Digest::hash(b);
assert_ne!(da, db, "different inputs should produce different digests");
});
}