1use num::BigInt;
2
3use crate::{API, VariableIniter, variable::CircuitVariable};
4
5pub trait Circuit {
11 fn define(&self, api: &mut impl API);
12}
13
14pub trait CircuitWitness: CircuitPublicWitness {
23 type CircuitElement: CircuitElement<CircuitWitness = Self>;
24 type PublicWitness: CircuitPublicWitness;
26
27 #[doc(hidden)]
28 fn create_public(initer: &mut VariableIniter, is_private: bool) -> Self::CircuitElement;
29
30 #[doc(hidden)]
31 fn create_private(initer: &mut VariableIniter) -> Self::CircuitElement;
32
33 fn into_public_witness(self) -> Self::PublicWitness;
41
42 #[doc(hidden)]
43 fn append_witness(&self, public: &mut Vec<BigInt>, private: &mut Vec<BigInt>, is_private: bool);
44}
45
46pub trait CircuitElement {
56 type CircuitWitness: CircuitWitness;
58}
59
60pub trait CircuitPublicWitness {
66 fn append_public_witness(&self, witness: &mut Vec<BigInt>, is_private: bool);
67}
68
69pub type Witness<T> = <T as CircuitElement>::CircuitWitness;
71
72pub type PublicWitness<T> =
74 <<T as CircuitElement>::CircuitWitness as CircuitWitness>::PublicWitness;
75
76#[doc(hidden)]
77pub type CircuitElementInner<T> =
78 <<T as CircuitElement>::CircuitWitness as CircuitWitness>::CircuitElement;
79
80macro_rules! define_circuit_element_for_from_u256 {
81 ($t:ty) => {
82 impl CircuitWitness for $t {
83 type CircuitElement = CircuitVariable<$t>;
84 type PublicWitness = $t;
85
86 fn create_public(
87 initer: &mut VariableIniter,
88 is_private: bool,
89 ) -> Self::CircuitElement {
90 initer.new_public(is_private).into()
91 }
92
93 fn create_private(initer: &mut VariableIniter) -> Self::CircuitElement {
94 initer.new_private().into()
95 }
96
97 fn into_public_witness(self) -> Self::PublicWitness {
98 self
99 }
100
101 fn append_witness(
102 &self,
103 public: &mut Vec<BigInt>,
104 private: &mut Vec<BigInt>,
105 is_private: bool,
106 ) {
107 let x = BigInt::from(*self);
108 if is_private {
109 private.push(x);
110 } else {
111 public.push(x);
112 }
113 }
114 }
115
116 impl CircuitPublicWitness for $t {
117 fn append_public_witness(&self, witness: &mut Vec<BigInt>, is_private: bool) {
118 let x = BigInt::from(*self);
119 if !is_private {
120 witness.push(x);
121 }
122 }
123 }
124
125 impl CircuitElement for CircuitVariable<$t> {
126 type CircuitWitness = $t;
127 }
128
129 impl CircuitElement for $t {
130 type CircuitWitness = $t;
131 }
132 };
133}
134
135define_circuit_element_for_from_u256!(u128);
136define_circuit_element_for_from_u256!(u64);
137define_circuit_element_for_from_u256!(u32);
138define_circuit_element_for_from_u256!(u16);
139define_circuit_element_for_from_u256!(u8);
140define_circuit_element_for_from_u256!(i128);
141define_circuit_element_for_from_u256!(i64);
142define_circuit_element_for_from_u256!(i32);
143define_circuit_element_for_from_u256!(i16);
144define_circuit_element_for_from_u256!(i8);
145define_circuit_element_for_from_u256!(bool);