acir/circuit/black_box_functions.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
//! Black box functions are ACIR opcodes which rely on backends implementing
//! support for specialized constraints.
//! This makes certain zk-snark unfriendly computations cheaper than if they were
//! implemented in more basic constraints.
use serde::{Deserialize, Serialize};
use strum_macros::EnumIter;
/// Representation of available black box function names.
/// This enum should be used to represent a black box before we have set up the
/// appropriate inputs and outputs. At which point it should be converted to a [crate::circuit::opcodes::BlackBoxFuncCall]
#[allow(clippy::upper_case_acronyms)]
#[derive(Clone, Debug, Hash, Copy, PartialEq, Eq, Serialize, Deserialize, EnumIter)]
pub enum BlackBoxFunc {
/// More details can be found at [crate::circuit::opcodes::BlackBoxFuncCall::AES128Encrypt]
AES128Encrypt,
/// More details can be found at [crate::circuit::opcodes::BlackBoxFuncCall::AND]
AND,
/// More details can be found at [crate::circuit::opcodes::BlackBoxFuncCall::XOR]
XOR,
/// More details can be found at [crate::circuit::opcodes::BlackBoxFuncCall::RANGE]
RANGE,
/// More details can be found at [crate::circuit::opcodes::BlackBoxFuncCall::Blake2s]
Blake2s,
/// More details can be found at [crate::circuit::opcodes::BlackBoxFuncCall::Blake3]
Blake3,
/// More details can be found at [crate::circuit::opcodes::BlackBoxFuncCall::EcdsaSecp256k1]
EcdsaSecp256k1,
/// More details can be found at [crate::circuit::opcodes::BlackBoxFuncCall::EcdsaSecp256r1]
EcdsaSecp256r1,
/// More details can be found at [crate::circuit::opcodes::BlackBoxFuncCall::MultiScalarMul]
MultiScalarMul,
/// More details can be found at [crate::circuit::opcodes::BlackBoxFuncCall::Keccakf1600]
Keccakf1600,
/// More details can be found at [crate::circuit::opcodes::BlackBoxFuncCall::RecursiveAggregation]
RecursiveAggregation,
/// More details can be found at [crate::circuit::opcodes::BlackBoxFuncCall::EmbeddedCurveAdd]
EmbeddedCurveAdd,
/// More details can be found at [crate::circuit::opcodes::BlackBoxFuncCall::BigIntAdd]
BigIntAdd,
/// More details can be found at [crate::circuit::opcodes::BlackBoxFuncCall::BigIntSub]
BigIntSub,
/// More details can be found at [crate::circuit::opcodes::BlackBoxFuncCall::BigIntMul]
BigIntMul,
/// More details can be found at [crate::circuit::opcodes::BlackBoxFuncCall::BigIntDiv]
BigIntDiv,
/// More details can be found at [crate::circuit::opcodes::BlackBoxFuncCall::BigIntFromLeBytes]
BigIntFromLeBytes,
/// More details can be found at [crate::circuit::opcodes::BlackBoxFuncCall::BigIntToLeBytes]
BigIntToLeBytes,
/// More details can be found at [crate::circuit::opcodes::BlackBoxFuncCall::Poseidon2Permutation]
Poseidon2Permutation,
/// More details can be found at [crate::circuit::opcodes::BlackBoxFuncCall::Sha256Compression]
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::Blake2s => "blake2s",
BlackBoxFunc::Blake3 => "blake3",
BlackBoxFunc::EcdsaSecp256k1 => "ecdsa_secp256k1",
BlackBoxFunc::MultiScalarMul => "multi_scalar_mul",
BlackBoxFunc::EmbeddedCurveAdd => "embedded_curve_add",
BlackBoxFunc::AND => "and",
BlackBoxFunc::XOR => "xor",
BlackBoxFunc::RANGE => "range",
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),
"blake2s" => Some(BlackBoxFunc::Blake2s),
"blake3" => Some(BlackBoxFunc::Blake3),
"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),
"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 has_side_effects(&self) -> bool {
match self {
BlackBoxFunc::RecursiveAggregation
| BlackBoxFunc::MultiScalarMul
| BlackBoxFunc::EmbeddedCurveAdd => true,
BlackBoxFunc::AES128Encrypt
| BlackBoxFunc::AND
| BlackBoxFunc::XOR
| BlackBoxFunc::RANGE
| BlackBoxFunc::Blake2s
| BlackBoxFunc::Blake3
| BlackBoxFunc::EcdsaSecp256k1
| BlackBoxFunc::EcdsaSecp256r1
| BlackBoxFunc::Keccakf1600
| BlackBoxFunc::BigIntAdd
| BlackBoxFunc::BigIntSub
| BlackBoxFunc::BigIntMul
| BlackBoxFunc::BigIntDiv
| BlackBoxFunc::BigIntFromLeBytes
| BlackBoxFunc::BigIntToLeBytes
| BlackBoxFunc::Poseidon2Permutation
| BlackBoxFunc::Sha256Compression => false,
}
}
}
#[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"
);
}
}
}