brillig/
black_box.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
use crate::{HeapArray, MemoryAddress, opcodes::HeapVector};
use serde::{Deserialize, Serialize};

/// These opcodes provide an equivalent of ACIR blackbox functions.
/// They are implemented as native functions in the VM.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash)]
#[cfg_attr(feature = "arb", derive(proptest_derive::Arbitrary))]
pub enum BlackBoxOp {
    /// Encrypts a message using AES128.
    AES128Encrypt { inputs: HeapVector, iv: HeapArray, key: HeapArray, outputs: HeapVector },
    /// Calculates the Blake2s hash of the inputs.
    Blake2s { message: HeapVector, output: HeapArray },
    /// Calculates the Blake3 hash of the inputs.
    Blake3 { message: HeapVector, output: HeapArray },
    /// Keccak Permutation function of 1600 width
    Keccakf1600 { input: HeapArray, output: HeapArray },
    /// Verifies a ECDSA signature over the secp256k1 curve.
    EcdsaSecp256k1 {
        hashed_msg: HeapVector,
        public_key_x: HeapArray,
        public_key_y: HeapArray,
        signature: HeapArray,
        result: MemoryAddress,
    },
    /// Verifies a ECDSA signature over the secp256r1 curve.
    EcdsaSecp256r1 {
        hashed_msg: HeapVector,
        public_key_x: HeapArray,
        public_key_y: HeapArray,
        signature: HeapArray,
        result: MemoryAddress,
    },
    /// Performs multi scalar multiplication over the embedded curve.
    MultiScalarMul { points: HeapVector, scalars: HeapVector, outputs: HeapArray },
    /// Performs addition over the embedded curve.
    EmbeddedCurveAdd {
        input1_x: MemoryAddress,
        input1_y: MemoryAddress,
        input1_infinite: MemoryAddress,
        input2_x: MemoryAddress,
        input2_y: MemoryAddress,
        input2_infinite: MemoryAddress,
        result: HeapArray,
    },
    /// Applies the Poseidon2 permutation function to the given state,
    /// outputting the permuted state.
    Poseidon2Permutation { message: HeapVector, output: HeapArray },
    /// Applies the SHA-256 compression function to the input message
    Sha256Compression { input: HeapArray, hash_values: HeapArray, output: HeapArray },
    /// Returns a decomposition in `num_limbs` limbs of the given input over the given radix.
    ///
    /// - The value stored in `radix` must be in the range [2, 256]
    /// - `num_limbs` must be at least one if the value stored in `input` is not zero.
    /// - The value stored in `output_bits` must have a `bit_size` of one.
    ///   That value specifies whether we should decompose into bits. The value stored in
    ///   the `radix` address must be two if the value stored in `output_bits` is equal to one.
    ///
    /// Native to the Brillig VM and not supported as an ACIR black box function.
    ToRadix {
        input: MemoryAddress,
        radix: MemoryAddress,
        output_pointer: MemoryAddress,
        num_limbs: MemoryAddress,
        output_bits: MemoryAddress,
    },
}

impl std::fmt::Display for BlackBoxOp {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            BlackBoxOp::AES128Encrypt { inputs, iv, key, outputs } => {
                write!(
                    f,
                    "aes_128_encrypt(inputs: {inputs}, iv: {iv}, key: {key}, outputs: {outputs})"
                )
            }
            BlackBoxOp::Blake2s { message, output } => {
                write!(f, "blake2s(message: {message}, output: {output})")
            }
            BlackBoxOp::Blake3 { message, output } => {
                write!(f, "blake3(message: {message}, output: {output})")
            }
            BlackBoxOp::Keccakf1600 { input, output } => {
                write!(f, "keccakf1600(input: {input}, output: {output})")
            }
            BlackBoxOp::EcdsaSecp256k1 {
                hashed_msg,
                public_key_x,
                public_key_y,
                signature,
                result,
            } => {
                write!(
                    f,
                    "ecdsa_secp256k1(hashed_msg: {hashed_msg}, public_key_x: {public_key_x}, public_key_y: {public_key_y}, signature: {signature}, result: {result})"
                )
            }
            BlackBoxOp::EcdsaSecp256r1 {
                hashed_msg,
                public_key_x,
                public_key_y,
                signature,
                result,
            } => {
                write!(
                    f,
                    "ecdsa_secp256r1(hashed_msg: {hashed_msg}, public_key_x: {public_key_x}, public_key_y: {public_key_y}, signature: {signature}, result: {result})"
                )
            }
            BlackBoxOp::MultiScalarMul { points, scalars, outputs } => {
                write!(
                    f,
                    "multi_scalar_mul(points: {points}, scalars: {scalars}, outputs: {outputs})"
                )
            }
            BlackBoxOp::EmbeddedCurveAdd {
                input1_x,
                input1_y,
                input1_infinite,
                input2_x,
                input2_y,
                input2_infinite,
                result,
            } => {
                write!(
                    f,
                    "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})"
                )
            }
            BlackBoxOp::Poseidon2Permutation { message, output } => {
                write!(f, "poseidon2_permutation(message: {message}, output: {output})")
            }
            BlackBoxOp::Sha256Compression { input, hash_values, output } => {
                write!(
                    f,
                    "sha256_compression(input: {input}, hash_values: {hash_values}, output: {output})"
                )
            }
            BlackBoxOp::ToRadix { input, radix, output_pointer, num_limbs, output_bits } => {
                write!(
                    f,
                    "to_radix(input: {input}, radix: {radix}, num_limbs: {num_limbs}, output_pointer: {output_pointer}, output_bits: {output_bits})"
                )
            }
        }
    }
}