pub fn verify_zisk_proof(
zisk_proof: &[u64],
expected_setup_vk: &[u64],
expected_program_vk: &[u64],
) -> bool {
const TAIL: usize = zisk_verifier::VADCOP_VK_LEN_WORDS + zisk_verifier::HASH_TAG_LEN_WORDS;
if zisk_proof.len() < TAIL {
return false;
}
let (proof, tail) = zisk_proof.split_at(zisk_proof.len() - TAIL);
let Some(hash) = zisk_verifier::hash_id_from_tag(tail[zisk_verifier::VADCOP_VK_LEN_WORDS])
else {
return false;
};
match zisk_verifier::committed_program_vk(proof) {
Some(vk) if vk == expected_program_vk => {}
_ => return false,
}
if zisk_verifier::committed_is_aggregate(proof) == Some(true)
&& expected_program_vk != expected_setup_vk
{
return false;
}
zisk_verifier::verify_vadcop_final_proof(proof, expected_setup_vk, hash)
}
#[cfg_attr(not(feature = "hints"), no_mangle)]
#[cfg_attr(feature = "hints", export_name = "hints_verify_zisk_proof_c")]
pub unsafe extern "C" fn verify_zisk_proof_c(
zisk_proof: *const u8,
zisk_proof_len: usize,
expected_setup_vk: *const u8,
expected_setup_vk_len: usize,
expected_program_vk: *const u8,
expected_program_vk_len: usize,
) -> bool {
if zisk_proof.is_null() || expected_setup_vk.is_null() || expected_program_vk.is_null() {
return false;
}
let proof_bytes = core::slice::from_raw_parts(zisk_proof, zisk_proof_len);
let setup_vk_bytes = core::slice::from_raw_parts(expected_setup_vk, expected_setup_vk_len);
let program_vk_bytes =
core::slice::from_raw_parts(expected_program_vk, expected_program_vk_len);
let (proof_prefix, proof_words, proof_suffix) = proof_bytes.align_to::<u64>();
let (setup_prefix, setup_words, setup_suffix) = setup_vk_bytes.align_to::<u64>();
let (program_prefix, program_words, program_suffix) = program_vk_bytes.align_to::<u64>();
if !proof_prefix.is_empty()
|| !proof_suffix.is_empty()
|| !setup_prefix.is_empty()
|| !setup_suffix.is_empty()
|| !program_prefix.is_empty()
|| !program_suffix.is_empty()
{
return false;
}
verify_zisk_proof(proof_words, setup_words, program_words)
}