use alloc::vec::Vec;
use miden_crypto::WORD_SIZE;
use proptest::prelude::*;
use winter_math::FieldElement;
use winter_rand_utils::prng_array;
use crate::{
Felt, Kernel, ProgramInfo, Word,
chiplets::hasher,
mast::{DynNode, MastNodeExt},
utils::{Deserializable, Serializable},
};
#[test]
fn dyn_hash_is_correct() {
let expected_constant =
hasher::merge_in_domain(&[Word::default(), Word::default()], DynNode::DYN_DOMAIN);
assert_eq!(expected_constant, DynNode::new_dyn().digest());
}
proptest! {
#[test]
fn arbitrary_program_info_serialization_works(
kernel_count in prop::num::u8::ANY,
ref seed in any::<[u8; 32]>()
) {
let program_hash = digest_from_seed(*seed);
let kernel: Vec<Word> = (0..kernel_count)
.scan(*seed, |seed, _| {
*seed = prng_array(*seed);
Some(digest_from_seed(*seed))
})
.collect();
let kernel = Kernel::new(&kernel).unwrap();
let program_info = ProgramInfo::new(program_hash, kernel);
let bytes = program_info.to_bytes();
let deser = ProgramInfo::read_from_bytes(&bytes).unwrap();
assert_eq!(program_info, deser);
}
}
fn digest_from_seed(seed: [u8; 32]) -> Word {
let mut digest = [Felt::ZERO; WORD_SIZE];
digest.iter_mut().enumerate().for_each(|(i, d)| {
*d = <[u8; 8]>::try_from(&seed[i * 8..(i + 1) * 8])
.map(u64::from_le_bytes)
.map(Felt::new)
.unwrap()
});
digest.into()
}