use serde::{Deserialize, Serialize};
#[cfg(test)]
use strum_macros::EnumIter;
#[allow(clippy::upper_case_acronyms)]
#[derive(Clone, Debug, Hash, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(test, derive(EnumIter))]
pub enum BlackBoxFunc {
AES128Encrypt,
AND,
XOR,
RANGE,
SHA256,
Blake2s,
Blake3,
SchnorrVerify,
PedersenCommitment,
PedersenHash,
EcdsaSecp256k1,
EcdsaSecp256r1,
MultiScalarMul,
Keccak256,
Keccakf1600,
RecursiveAggregation,
EmbeddedCurveAdd,
BigIntAdd,
BigIntSub,
BigIntMul,
BigIntDiv,
BigIntFromLeBytes,
BigIntToLeBytes,
Poseidon2Permutation,
Sha256Compression,
}
impl std::fmt::Display for BlackBoxFunc {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.name())
}
}
impl BlackBoxFunc {
pub fn name(&self) -> &'static str {
match self {
BlackBoxFunc::AES128Encrypt => "aes128_encrypt",
BlackBoxFunc::SHA256 => "sha256",
BlackBoxFunc::SchnorrVerify => "schnorr_verify",
BlackBoxFunc::Blake2s => "blake2s",
BlackBoxFunc::Blake3 => "blake3",
BlackBoxFunc::PedersenCommitment => "pedersen_commitment",
BlackBoxFunc::PedersenHash => "pedersen_hash",
BlackBoxFunc::EcdsaSecp256k1 => "ecdsa_secp256k1",
BlackBoxFunc::MultiScalarMul => "multi_scalar_mul",
BlackBoxFunc::EmbeddedCurveAdd => "embedded_curve_add",
BlackBoxFunc::AND => "and",
BlackBoxFunc::XOR => "xor",
BlackBoxFunc::RANGE => "range",
BlackBoxFunc::Keccak256 => "keccak256",
BlackBoxFunc::Keccakf1600 => "keccakf1600",
BlackBoxFunc::RecursiveAggregation => "recursive_aggregation",
BlackBoxFunc::EcdsaSecp256r1 => "ecdsa_secp256r1",
BlackBoxFunc::BigIntAdd => "bigint_add",
BlackBoxFunc::BigIntSub => "bigint_sub",
BlackBoxFunc::BigIntMul => "bigint_mul",
BlackBoxFunc::BigIntDiv => "bigint_div",
BlackBoxFunc::BigIntFromLeBytes => "bigint_from_le_bytes",
BlackBoxFunc::BigIntToLeBytes => "bigint_to_le_bytes",
BlackBoxFunc::Poseidon2Permutation => "poseidon2_permutation",
BlackBoxFunc::Sha256Compression => "sha256_compression",
}
}
pub fn lookup(op_name: &str) -> Option<BlackBoxFunc> {
match op_name {
"aes128_encrypt" => Some(BlackBoxFunc::AES128Encrypt),
"sha256" => Some(BlackBoxFunc::SHA256),
"schnorr_verify" => Some(BlackBoxFunc::SchnorrVerify),
"blake2s" => Some(BlackBoxFunc::Blake2s),
"blake3" => Some(BlackBoxFunc::Blake3),
"pedersen_commitment" => Some(BlackBoxFunc::PedersenCommitment),
"pedersen_hash" => Some(BlackBoxFunc::PedersenHash),
"ecdsa_secp256k1" => Some(BlackBoxFunc::EcdsaSecp256k1),
"ecdsa_secp256r1" => Some(BlackBoxFunc::EcdsaSecp256r1),
"multi_scalar_mul" => Some(BlackBoxFunc::MultiScalarMul),
"embedded_curve_add" => Some(BlackBoxFunc::EmbeddedCurveAdd),
"and" => Some(BlackBoxFunc::AND),
"xor" => Some(BlackBoxFunc::XOR),
"range" => Some(BlackBoxFunc::RANGE),
"keccak256" => Some(BlackBoxFunc::Keccak256),
"keccakf1600" => Some(BlackBoxFunc::Keccakf1600),
"recursive_aggregation" => Some(BlackBoxFunc::RecursiveAggregation),
"bigint_add" => Some(BlackBoxFunc::BigIntAdd),
"bigint_sub" => Some(BlackBoxFunc::BigIntSub),
"bigint_mul" => Some(BlackBoxFunc::BigIntMul),
"bigint_div" => Some(BlackBoxFunc::BigIntDiv),
"bigint_from_le_bytes" => Some(BlackBoxFunc::BigIntFromLeBytes),
"bigint_to_le_bytes" => Some(BlackBoxFunc::BigIntToLeBytes),
"poseidon2_permutation" => Some(BlackBoxFunc::Poseidon2Permutation),
"sha256_compression" => Some(BlackBoxFunc::Sha256Compression),
_ => None,
}
}
pub fn is_valid_black_box_func_name(op_name: &str) -> bool {
BlackBoxFunc::lookup(op_name).is_some()
}
}
#[cfg(test)]
mod tests {
use strum::IntoEnumIterator;
use crate::BlackBoxFunc;
#[test]
fn consistent_function_names() {
for bb_func in BlackBoxFunc::iter() {
let resolved_func = BlackBoxFunc::lookup(bb_func.name()).unwrap_or_else(|| {
panic!("BlackBoxFunc::lookup couldn't find black box function {bb_func}")
});
assert_eq!(
resolved_func, bb_func,
"BlackBoxFunc::lookup returns unexpected BlackBoxFunc"
);
}
}
}