kaspa_txscript/zk_precompiles/
mod.rs1mod error;
2mod fields;
3pub mod groth16;
4pub mod risc0;
5pub mod tags;
6pub mod tests;
7use crate::{
8 data_stack::Stack,
9 runtime_resource_meter::RuntimeResourceMeter,
10 zk_precompiles::{error::ZkIntegrityError, groth16::Groth16Precompile, risc0::R0SuccinctPrecompile, tags::ZkTag},
11};
12use kaspa_consensus_core::mass::ScriptUnits;
13use kaspa_txscript_errors::TxScriptError;
14
15trait ZkPrecompile {
16 type Error: Into<ZkIntegrityError> + std::fmt::Display;
17 fn verify_zk(dstack: &mut Stack, meter: &mut RuntimeResourceMeter) -> Result<(), Self::Error>;
18}
19
20pub(crate) fn parse_tag(dstack: &mut Stack) -> Result<ZkTag, TxScriptError> {
21 let tag_bytes = dstack.pop()?;
22 match tag_bytes.as_slice() {
23 [tag_byte] => ZkTag::try_from(*tag_byte).map_err(|e| TxScriptError::ZkIntegrity(e.to_string())),
24 [] => Err(TxScriptError::ZkIntegrity("Tag byte is missing".to_string())),
25 _ => Err(TxScriptError::ZkIntegrity(format!("Tag byte length {} is invalid", tag_bytes.len()))),
26 }
27}
28
29pub(crate) fn verify_zk(tag: ZkTag, dstack: &mut Stack, meter: &mut RuntimeResourceMeter) -> Result<(), TxScriptError> {
34 match tag {
36 ZkTag::Groth16 => Groth16Precompile::verify_zk(dstack, meter).map_err(|e| TxScriptError::ZkIntegrity(e.to_string())),
37 ZkTag::R0Succinct => R0SuccinctPrecompile::verify_zk(dstack, meter).map_err(|e| TxScriptError::ZkIntegrity(e.to_string())),
38 }
39}
40
41pub fn compute_zk_cost(tag: u8) -> ScriptUnits {
45 ZkTag::try_from(tag).map(|t| t.cost()).unwrap_or(ZkTag::max_cost()) }