rsnark_core/
circuit.rs

1use ruint::aliases::U256;
2
3use crate::{API, VariableIniter, variable::CircuitVariable};
4
5/// Defines the logic of an arithmetic circuit for zero-knowledge proofs.
6///
7/// This trait should be implemented by circuit structures to define their
8/// constraint system. The circuit logic is expressed using the provided API
9/// operations to build the constraint graph.
10pub trait Circuit {
11    fn define(&self, api: &mut impl API);
12}
13
14/// Defines a circuit with witness data structure.
15///
16/// This trait should not be implemented manually. Instead, use the
17/// `#[derive(Circuit)]` macro to automatically generate the implementation.
18/// It provides methods for creating circuit variables and handling witness data.
19pub trait CircuitWitness: CircuitPublicWitness {
20    #[doc(hidden)]
21    type PrivateElement;
22    #[doc(hidden)]
23    type PublicElement;
24
25    /// The type representing the public witness for this circuit.
26    type PublicWitness: CircuitPublicWitness;
27
28    #[doc(hidden)]
29    fn create_public(initer: &mut VariableIniter, is_private: bool) -> Self::PublicElement;
30
31    #[doc(hidden)]
32    fn create_private(initer: &mut VariableIniter) -> Self::PrivateElement;
33
34    /// Converts this circuit witness into its public witness representation.
35    ///
36    /// This extracts only the public portion of the witness, which is
37    /// needed for verification in zero-knowledge proof systems.
38    ///
39    /// # Returns
40    /// The public witness containing only public inputs
41    fn into_public_witness(self) -> Self::PublicWitness;
42
43    #[doc(hidden)]
44    fn append_witness(&self, public: &mut Vec<U256>, private: &mut Vec<U256>, is_private: bool);
45}
46
47/// Represents the public witness portion of a circuit.
48///
49/// This trait should not be implemented manually. Instead, use the
50/// `#[derive(Circuit)]` macro to automatically generate the implementation.
51/// It handles serialization of public inputs for the circuit.
52pub trait CircuitPublicWitness {
53    fn append_public_witness(&self, witness: &mut Vec<U256>, is_private: bool);
54}
55
56#[doc(hidden)]
57pub type PrivateCircuitElement<T> = <T as CircuitWitness>::PrivateElement;
58#[doc(hidden)]
59pub type PublicCircuitElement<T> = <T as CircuitWitness>::PublicElement;
60
61/// Type alias for the circuit definition structure.
62///
63/// This represents the private element structure used during circuit construction,
64/// containing all the private variables and intermediate computations.
65pub type CircuitDefine<T> = <T as CircuitWitness>::PrivateElement;
66
67/// Type alias for the public witness of a circuit.
68///
69/// This represents the public inputs that are visible to the verifier
70/// in a zero-knowledge proof system.
71pub type PublicWitness<T> = <T as CircuitWitness>::PublicWitness;
72
73macro_rules! define_circuit_element_for_from_u256 {
74    ($t:ty) => {
75        impl CircuitWitness for $t {
76            type PrivateElement = CircuitVariable;
77            type PublicElement = CircuitVariable;
78            type PublicWitness = $t;
79
80            fn create_public(initer: &mut VariableIniter, is_private: bool) -> Self::PublicElement {
81                initer.new_public(is_private)
82            }
83
84            fn create_private(initer: &mut VariableIniter) -> Self::PrivateElement {
85                initer.new_private()
86            }
87
88            fn append_witness(
89                &self,
90                public: &mut Vec<U256>,
91                private: &mut Vec<U256>,
92                is_private: bool,
93            ) {
94                let x = U256::from(*self);
95                if is_private {
96                    private.push(x);
97                } else {
98                    public.push(x);
99                }
100            }
101
102            fn into_public_witness(self) -> Self::PublicWitness {
103                self
104            }
105        }
106
107        impl CircuitPublicWitness for $t {
108            fn append_public_witness(&self, witness: &mut Vec<U256>, is_private: bool) {
109                let x = U256::from(*self);
110                if !is_private {
111                    witness.push(x);
112                }
113            }
114        }
115    };
116}
117
118define_circuit_element_for_from_u256!(U256);
119define_circuit_element_for_from_u256!(u128);
120define_circuit_element_for_from_u256!(u64);
121define_circuit_element_for_from_u256!(u32);
122define_circuit_element_for_from_u256!(u16);
123define_circuit_element_for_from_u256!(u8);
124define_circuit_element_for_from_u256!(i128);
125define_circuit_element_for_from_u256!(i64);
126define_circuit_element_for_from_u256!(i32);
127define_circuit_element_for_from_u256!(i16);
128define_circuit_element_for_from_u256!(i8);
129define_circuit_element_for_from_u256!(bool);