acir/circuit/
black_box_functions.rs1use serde::{Deserialize, Serialize};
7use strum_macros::EnumIter;
8
9#[allow(clippy::upper_case_acronyms)]
13#[derive(Clone, Debug, Hash, Copy, PartialEq, Eq, Serialize, Deserialize, EnumIter)]
14pub enum BlackBoxFunc {
15 AES128Encrypt,
17 AND,
19 XOR,
21 RANGE,
23 Blake2s,
25 Blake3,
27 EcdsaSecp256k1,
29 EcdsaSecp256r1,
31 MultiScalarMul,
33 Keccakf1600,
35 RecursiveAggregation,
37 EmbeddedCurveAdd,
39 Poseidon2Permutation,
41 Sha256Compression,
43}
44
45impl std::fmt::Display for BlackBoxFunc {
46 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47 write!(f, "{}", self.name())
48 }
49}
50
51impl BlackBoxFunc {
52 pub fn name(&self) -> &'static str {
53 match self {
54 BlackBoxFunc::AES128Encrypt => "aes128_encrypt",
55 BlackBoxFunc::Blake2s => "blake2s",
56 BlackBoxFunc::Blake3 => "blake3",
57 BlackBoxFunc::EcdsaSecp256k1 => "ecdsa_secp256k1",
58 BlackBoxFunc::MultiScalarMul => "multi_scalar_mul",
59 BlackBoxFunc::EmbeddedCurveAdd => "embedded_curve_add",
60 BlackBoxFunc::AND => "and",
61 BlackBoxFunc::XOR => "xor",
62 BlackBoxFunc::RANGE => "range",
63 BlackBoxFunc::Keccakf1600 => "keccakf1600",
64 BlackBoxFunc::RecursiveAggregation => "recursive_aggregation",
65 BlackBoxFunc::EcdsaSecp256r1 => "ecdsa_secp256r1",
66 BlackBoxFunc::Poseidon2Permutation => "poseidon2_permutation",
67 BlackBoxFunc::Sha256Compression => "sha256_compression",
68 }
69 }
70
71 pub fn lookup(op_name: &str) -> Option<BlackBoxFunc> {
72 match op_name {
73 "aes128_encrypt" => Some(BlackBoxFunc::AES128Encrypt),
74 "blake2s" => Some(BlackBoxFunc::Blake2s),
75 "blake3" => Some(BlackBoxFunc::Blake3),
76 "ecdsa_secp256k1" => Some(BlackBoxFunc::EcdsaSecp256k1),
77 "ecdsa_secp256r1" => Some(BlackBoxFunc::EcdsaSecp256r1),
78 "multi_scalar_mul" => Some(BlackBoxFunc::MultiScalarMul),
79 "embedded_curve_add" => Some(BlackBoxFunc::EmbeddedCurveAdd),
80 "and" => Some(BlackBoxFunc::AND),
81 "xor" => Some(BlackBoxFunc::XOR),
82 "range" => Some(BlackBoxFunc::RANGE),
83 "keccakf1600" => Some(BlackBoxFunc::Keccakf1600),
84 "recursive_aggregation" => Some(BlackBoxFunc::RecursiveAggregation),
85 "poseidon2_permutation" => Some(BlackBoxFunc::Poseidon2Permutation),
86 "sha256_compression" => Some(BlackBoxFunc::Sha256Compression),
87 _ => None,
88 }
89 }
90
91 pub fn has_side_effects(&self) -> bool {
92 match self {
93 BlackBoxFunc::RecursiveAggregation
94 | BlackBoxFunc::MultiScalarMul
95 | BlackBoxFunc::EmbeddedCurveAdd
96 | BlackBoxFunc::EcdsaSecp256k1
97 | BlackBoxFunc::EcdsaSecp256r1
98 | BlackBoxFunc::RANGE => true,
99
100 BlackBoxFunc::AES128Encrypt
101 | BlackBoxFunc::AND
102 | BlackBoxFunc::XOR
103 | BlackBoxFunc::Blake2s
104 | BlackBoxFunc::Blake3
105 | BlackBoxFunc::Keccakf1600
106 | BlackBoxFunc::Poseidon2Permutation
107 | BlackBoxFunc::Sha256Compression => false,
108 }
109 }
110}
111
112#[cfg(test)]
113mod tests {
114 use strum::IntoEnumIterator;
115
116 use crate::BlackBoxFunc;
117
118 #[test]
119 fn consistent_function_names() {
120 for bb_func in BlackBoxFunc::iter() {
121 let resolved_func = BlackBoxFunc::lookup(bb_func.name()).unwrap_or_else(|| {
122 panic!("BlackBoxFunc::lookup couldn't find black box function {bb_func}")
123 });
124 assert_eq!(
125 resolved_func, bb_func,
126 "BlackBoxFunc::lookup returns unexpected BlackBoxFunc"
127 );
128 }
129 }
130}