pub mod bigint;
pub mod blake2b;
pub mod bls381;
pub mod bn254;
pub mod keccak256;
pub mod kzg;
pub mod ripemd160;
pub mod secp256k1;
pub mod secp256r1;
pub mod sha256;
pub mod uint256;
#[macro_export]
macro_rules! hint_fields {
($($name:ident: $size:expr),+ $(,)?) => {
paste::paste! {
$(
#[allow(dead_code)]
const [<$name _SIZE>]: usize = $size;
)+
}
hint_fields!(@offsets 0, $($name: $size),+);
#[allow(unused)]
const EXPECTED_LEN: usize = hint_fields!(@sum $($size),+);
};
(@offsets $offset:expr, $name:ident: $size:expr) => {
paste::paste! {
#[allow(dead_code)]
const [<$name _OFFSET>]: usize = $offset;
}
};
(@offsets $offset:expr, $name:ident: $size:expr, $($rest_name:ident: $rest_size:expr),+) => {
paste::paste! {
const [<$name _OFFSET>]: usize = $offset;
}
hint_fields!(@offsets $offset + $size, $($rest_name: $rest_size),+);
};
(@sum $size:expr) => { $size };
(@sum $size:expr, $($rest:expr),+) => {
$size + hint_fields!(@sum $($rest),+)
};
}
#[inline]
fn read_field_bytes<'a>(data: &'a [u64], pos: &mut usize) -> anyhow::Result<(&'a [u8], usize)> {
let byte_data: &[u8] = unsafe {
std::slice::from_raw_parts(data.as_ptr() as *const u8, std::mem::size_of_val(data))
};
if *pos + 8 > byte_data.len() {
anyhow::bail!("MODEXP hint data too short to read length");
}
let len_bytes =
u64::from_le_bytes(byte_data[*pos..*pos + 8].try_into().expect("slice length checked"))
as usize;
*pos += 8;
if *pos + len_bytes > byte_data.len() {
anyhow::bail!("MODEXP hint data too short for field");
}
let field = &byte_data[*pos..*pos + len_bytes];
*pos += len_bytes;
Ok((field, len_bytes))
}
#[inline]
fn validate_hint_length<T>(data: &[T], expected_len: usize, hint_name: &str) -> anyhow::Result<()> {
if data.len() != expected_len {
anyhow::bail!(
"Invalid {} hint length: expected {}, got {}",
hint_name,
expected_len,
data.len(),
);
}
Ok(())
}