use crate::{
precompiles::{BuiltinAddressMatcher, Error, Ext, PrimitivePrecompile},
vm::RuntimeCosts,
Config, U256,
};
use alloc::vec::Vec;
use core::{marker::PhantomData, num::NonZero};
pub struct P256Verify<T>(PhantomData<T>);
impl<T: Config> PrimitivePrecompile for P256Verify<T> {
type T = T;
const MATCHER: BuiltinAddressMatcher =
BuiltinAddressMatcher::Fixed(NonZero::new(0x100).unwrap());
const HAS_CONTRACT_INFO: bool = false;
fn call(
_address: &[u8; 20],
input: Vec<u8>,
env: &mut impl Ext<T = Self::T>,
) -> Result<Vec<u8>, Error> {
env.frame_meter_mut().charge_weight_token(RuntimeCosts::P256Verify)?;
if revm::precompile::secp256r1::verify_impl(&input).is_some() {
Ok(U256::one().to_big_endian().to_vec())
} else {
Ok(Default::default())
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{precompiles::tests::run_test_vectors, tests::Test};
#[test]
fn test_p256_verify() {
run_test_vectors::<P256Verify<Test>>(include_str!("./testdata/256-p256_verify.json"));
}
#[test]
fn test_p256_verify_address_match() {
assert_eq!(
<P256Verify<Test> as PrimitivePrecompile>::MATCHER.base_address(),
hex_literal::hex!("0000000000000000000000000000000000000100")
);
}
}