brillig/
black_box.rs

1use crate::{HeapArray, MemoryAddress};
2use serde::{Deserialize, Serialize};
3
4/// These opcodes provide an equivalent of ACIR blackbox functions.
5/// They are implemented as native functions in the VM.
6/// For more information, see the ACIR blackbox functions in acir::circuit::opcodes::BlackBoxFuncCall
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash)]
8#[cfg_attr(feature = "arb", derive(proptest_derive::Arbitrary))]
9pub enum BlackBoxOp {
10    /// Encrypts a message using AES-128.
11    AES128Encrypt { inputs: HeapArray, iv: HeapArray, key: HeapArray, outputs: HeapArray },
12    /// Calculates the Blake2s hash of the inputs.
13    Blake2s { message: HeapArray, output: HeapArray },
14    /// Calculates the Blake3 hash of the inputs.
15    Blake3 { message: HeapArray, output: HeapArray },
16    /// Keccak permutation function of 1600 width.
17    Keccakf1600 { input: HeapArray, output: HeapArray },
18    /// Verifies an ECDSA signature over the secp256k1 curve.
19    EcdsaSecp256k1 {
20        hashed_msg: HeapArray,
21        public_key_x: HeapArray,
22        public_key_y: HeapArray,
23        signature: HeapArray,
24        result: MemoryAddress,
25    },
26    /// Verifies an ECDSA signature over the secp256r1 curve.
27    EcdsaSecp256r1 {
28        hashed_msg: HeapArray,
29        public_key_x: HeapArray,
30        public_key_y: HeapArray,
31        signature: HeapArray,
32        result: MemoryAddress,
33    },
34    /// Performs multi scalar multiplication over the embedded curve.
35    MultiScalarMul { points: HeapArray, scalars: HeapArray, outputs: HeapArray },
36    /// Performs addition over the embedded curve.
37    EmbeddedCurveAdd {
38        input1_x: MemoryAddress,
39        input1_y: MemoryAddress,
40        input1_infinite: MemoryAddress,
41        input2_x: MemoryAddress,
42        input2_y: MemoryAddress,
43        input2_infinite: MemoryAddress,
44        result: HeapArray,
45    },
46    /// Applies the Poseidon2 permutation function to the given state,
47    /// outputting the permuted state.
48    Poseidon2Permutation { message: HeapArray, output: HeapArray },
49    /// Applies the SHA-256 compression function to the input message
50    Sha256Compression { input: HeapArray, hash_values: HeapArray, output: HeapArray },
51    /// Returns a decomposition in `num_limbs` limbs of the given input over the given radix.
52    ///
53    /// - The value stored in `radix` must be in the range [2, 256]
54    /// - `num_limbs` must be at least one if the value stored in `input` is not zero.
55    /// - The value stored in `output_bits` must have a `bit_size` of one.
56    ///   That value specifies whether we should decompose into bits. The value stored in
57    ///   the `radix` address must be two if the value stored in `output_bits` is equal to one.
58    ///
59    /// Native to the Brillig VM and not supported as an ACIR black box function.
60    ToRadix {
61        input: MemoryAddress,
62        radix: MemoryAddress,
63        output_pointer: MemoryAddress,
64        num_limbs: MemoryAddress,
65        output_bits: MemoryAddress,
66    },
67}
68
69impl std::fmt::Display for BlackBoxOp {
70    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71        match self {
72            BlackBoxOp::AES128Encrypt { inputs, iv, key, outputs } => {
73                write!(
74                    f,
75                    "aes_128_encrypt(inputs: {inputs}, iv: {iv}, key: {key}, outputs: {outputs})"
76                )
77            }
78            BlackBoxOp::Blake2s { message, output } => {
79                write!(f, "blake2s(message: {message}, output: {output})")
80            }
81            BlackBoxOp::Blake3 { message, output } => {
82                write!(f, "blake3(message: {message}, output: {output})")
83            }
84            BlackBoxOp::Keccakf1600 { input, output } => {
85                write!(f, "keccakf1600(input: {input}, output: {output})")
86            }
87            BlackBoxOp::EcdsaSecp256k1 {
88                hashed_msg,
89                public_key_x,
90                public_key_y,
91                signature,
92                result,
93            } => {
94                write!(
95                    f,
96                    "ecdsa_secp256k1(hashed_msg: {hashed_msg}, public_key_x: {public_key_x}, public_key_y: {public_key_y}, signature: {signature}, result: {result})"
97                )
98            }
99            BlackBoxOp::EcdsaSecp256r1 {
100                hashed_msg,
101                public_key_x,
102                public_key_y,
103                signature,
104                result,
105            } => {
106                write!(
107                    f,
108                    "ecdsa_secp256r1(hashed_msg: {hashed_msg}, public_key_x: {public_key_x}, public_key_y: {public_key_y}, signature: {signature}, result: {result})"
109                )
110            }
111            BlackBoxOp::MultiScalarMul { points, scalars, outputs } => {
112                write!(
113                    f,
114                    "multi_scalar_mul(points: {points}, scalars: {scalars}, outputs: {outputs})"
115                )
116            }
117            BlackBoxOp::EmbeddedCurveAdd {
118                input1_x,
119                input1_y,
120                input1_infinite,
121                input2_x,
122                input2_y,
123                input2_infinite,
124                result,
125            } => {
126                write!(
127                    f,
128                    "embedded_curve_add(input1_x: {input1_x}, input1_y: {input1_y}, input1_infinite: {input1_infinite}, input2_x: {input2_x}, input2_y: {input2_y}, input2_infinite: {input2_infinite}, result: {result})"
129                )
130            }
131            BlackBoxOp::Poseidon2Permutation { message, output } => {
132                write!(f, "poseidon2_permutation(message: {message}, output: {output})")
133            }
134            BlackBoxOp::Sha256Compression { input, hash_values, output } => {
135                write!(
136                    f,
137                    "sha256_compression(input: {input}, hash_values: {hash_values}, output: {output})"
138                )
139            }
140            BlackBoxOp::ToRadix { input, radix, output_pointer, num_limbs, output_bits } => {
141                write!(
142                    f,
143                    "to_radix(input: {input}, radix: {radix}, num_limbs: {num_limbs}, output_pointer: {output_pointer}, output_bits: {output_bits})"
144                )
145            }
146        }
147    }
148}