1use crate::{
4 FancyArithmetic, FancyBinary,
5 errors::FancyError,
6 fancy::{Fancy, FancyInput, FancyReveal, HasModulus},
7};
8use std::cmp::max;
9
10#[derive(Clone, Debug)]
12pub struct DepthItem {
13 modulus: u16,
14 depth: usize,
15}
16
17impl HasModulus for DepthItem {
18 fn modulus(&self) -> u16 {
19 self.modulus
20 }
21}
22
23#[derive(Debug)]
25pub enum DepthError {
26 ProjUnsupported,
28 Underlying(FancyError),
30}
31
32impl From<FancyError> for DepthError {
33 fn from(e: FancyError) -> Self {
34 DepthError::Underlying(e)
35 }
36}
37
38impl std::fmt::Display for DepthError {
39 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
40 match self {
41 Self::ProjUnsupported => writeln!(f, "Projection unsupported"),
42 Self::Underlying(e) => writeln!(f, "Fancy error: {}", e),
43 }
44 }
45}
46
47#[derive(Clone, Debug)]
49pub struct DepthInformer {
50 ninputs: usize,
51 nconstants: usize,
52 nadds: usize,
53 nsubs: usize,
54 ncmuls: usize,
55 nmuls: usize,
56 mul_depth: usize,
57}
58
59impl std::fmt::Display for DepthInformer {
60 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
61 writeln!(f, "computation info:")?;
62 writeln!(f, " inputs: {:16}", self.ninputs)?;
63 writeln!(f, " constants: {:16}", self.nconstants)?;
64 writeln!(f, " additions: {:16}", self.nadds)?;
65 writeln!(f, " subtractions: {:16}", self.nsubs)?;
66 writeln!(f, " cmuls: {:16}", self.ncmuls)?;
67 writeln!(f, " muls: {:16}", self.nmuls)?;
68 writeln!(
69 f,
70 " total gates: {:16}",
71 self.nadds + self.nsubs + self.ncmuls + self.nmuls
72 )?;
73 writeln!(f, " mul depth: {:16}", self.mul_depth)?;
74 Ok(())
75 }
76}
77
78impl DepthInformer {
79 pub fn new() -> DepthInformer {
81 DepthInformer {
82 ninputs: 0,
83 nconstants: 0,
84 nadds: 0,
85 nsubs: 0,
86 ncmuls: 0,
87 nmuls: 0,
88 mul_depth: 0,
89 }
90 }
91}
92
93impl FancyInput for DepthInformer {
94 type Item = DepthItem;
95 type Error = DepthError;
96
97 fn receive_many(&mut self, moduli: &[u16]) -> Result<Vec<Self::Item>, Self::Error> {
98 self.ninputs += moduli.len();
99 Ok(moduli
100 .iter()
101 .map(|q| DepthItem {
102 modulus: *q,
103 depth: 0,
104 })
105 .collect())
106 }
107
108 fn encode_many(
109 &mut self,
110 _values: &[u16],
111 moduli: &[u16],
112 ) -> Result<Vec<Self::Item>, Self::Error> {
113 self.receive_many(moduli)
114 }
115}
116
117impl FancyBinary for DepthInformer {
118 fn xor(&mut self, x: &Self::Item, y: &Self::Item) -> Result<Self::Item, Self::Error> {
119 FancyArithmetic::add(self, x, y)
120 }
121
122 fn and(&mut self, x: &Self::Item, y: &Self::Item) -> Result<Self::Item, Self::Error> {
123 FancyArithmetic::mul(self, x, y)
124 }
125
126 fn negate(&mut self, x: &Self::Item) -> Result<Self::Item, Self::Error> {
127 self.nadds += 1;
128 Ok(DepthItem {
129 modulus: x.modulus,
130 depth: x.depth,
131 })
132 }
133}
134
135impl FancyArithmetic for DepthInformer {
136 fn add(&mut self, x: &Self::Item, y: &Self::Item) -> Result<Self::Item, Self::Error> {
137 self.nadds += 1;
138 Ok(DepthItem {
139 modulus: x.modulus,
140 depth: max(x.depth, y.depth),
141 })
142 }
143
144 fn sub(&mut self, x: &Self::Item, y: &Self::Item) -> Result<Self::Item, Self::Error> {
145 self.nsubs += 1;
146 Ok(DepthItem {
147 modulus: x.modulus,
148 depth: max(x.depth, y.depth),
149 })
150 }
151
152 fn cmul(&mut self, x: &Self::Item, _y: u16) -> Result<Self::Item, Self::Error> {
153 self.ncmuls += 1;
154 Ok(DepthItem {
155 modulus: x.modulus,
156 depth: x.depth + 1,
157 })
158 }
159
160 fn mul(&mut self, x: &Self::Item, y: &Self::Item) -> Result<Self::Item, Self::Error> {
161 self.nmuls += 1;
162 Ok(DepthItem {
163 modulus: x.modulus,
164 depth: max(x.depth, y.depth) + 1,
165 })
166 }
167
168 fn proj(
169 &mut self,
170 _x: &Self::Item,
171 _q: u16,
172 _tt: Option<Vec<u16>>,
173 ) -> Result<Self::Item, Self::Error> {
174 Err(DepthError::ProjUnsupported)
175 }
176}
177
178impl Fancy for DepthInformer {
179 type Item = DepthItem;
180 type Error = DepthError;
181
182 fn constant(&mut self, _val: u16, q: u16) -> Result<Self::Item, Self::Error> {
183 self.nconstants += 1;
184 Ok(DepthItem {
185 modulus: q,
186 depth: 0,
187 })
188 }
189
190 fn output(&mut self, x: &Self::Item) -> Result<Option<u16>, Self::Error> {
191 self.mul_depth = max(self.mul_depth, x.depth);
192 Ok(None)
193 }
194}
195
196impl FancyReveal for DepthInformer {
197 fn reveal(&mut self, _x: &Self::Item) -> Result<u16, Self::Error> {
198 Ok(0)
199 }
200}