snarkvm_synthesizer_program/logic/finalize_operation/bits.rs
1// Copyright (c) 2019-2025 Provable Inc.
2// This file is part of the snarkVM library.
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at:
7
8// http://www.apache.org/licenses/LICENSE-2.0
9
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use super::*;
17
18impl<N: Network> FromBits for FinalizeOperation<N> {
19 /// Reads `Self` from a boolean array in little-endian order.
20 fn from_bits_le(bits: &[bool]) -> Result<Self> {
21 let mut bits = bits.iter().cloned();
22
23 // Helper function to get the next n bits as a slice.
24 let mut next_bits = |n: usize| -> Result<Vec<bool>> {
25 let bits: Vec<_> = bits.by_ref().take(n).collect();
26 if bits.len() < n {
27 bail!("Insufficient bits");
28 }
29 Ok(bits)
30 };
31
32 // Read the variant.
33 let variant = u8::from_bits_le(&next_bits(8)?)?;
34
35 // Parse the operation.
36 match variant {
37 0 => {
38 // Read the mapping ID.
39 let mapping_id = Field::from_bits_le(&next_bits(Field::<N>::size_in_bits())?)?;
40 // Return the finalize operation.
41 Ok(Self::InitializeMapping(mapping_id))
42 }
43 1 => {
44 // Read the mapping ID.
45 let mapping_id = Field::from_bits_le(&next_bits(Field::<N>::size_in_bits())?)?;
46 // Read the key ID.
47 let key_id = Field::from_bits_le(&next_bits(Field::<N>::size_in_bits())?)?;
48 // Read the value ID.
49 let value_id = Field::from_bits_le(&next_bits(Field::<N>::size_in_bits())?)?;
50 // Return the finalize operation.
51 Ok(Self::InsertKeyValue(mapping_id, key_id, value_id))
52 }
53 2 => {
54 // Read the mapping ID.
55 let mapping_id = Field::from_bits_le(&next_bits(Field::<N>::size_in_bits())?)?;
56 // Read the key ID.
57 let key_id = Field::from_bits_le(&next_bits(Field::<N>::size_in_bits())?)?;
58 // Read the value ID.
59 let value_id = Field::from_bits_le(&next_bits(Field::<N>::size_in_bits())?)?;
60 // Return the finalize operation.
61 Ok(Self::UpdateKeyValue(mapping_id, key_id, value_id))
62 }
63 3 => {
64 // Read the mapping ID.
65 let mapping_id = Field::from_bits_le(&next_bits(Field::<N>::size_in_bits())?)?;
66 // Read the key ID.
67 let key_id = Field::from_bits_le(&next_bits(Field::<N>::size_in_bits())?)?;
68 // Return the finalize operation.
69 Ok(Self::RemoveKeyValue(mapping_id, key_id))
70 }
71 4 => {
72 // Read the mapping ID.
73 let mapping_id = Field::from_bits_le(&next_bits(Field::<N>::size_in_bits())?)?;
74 // Return the finalize operation.
75 Ok(Self::ReplaceMapping(mapping_id))
76 }
77 5 => {
78 // Read the mapping ID.
79 let mapping_id = Field::from_bits_le(&next_bits(Field::<N>::size_in_bits())?)?;
80 // Return the finalize operation.
81 Ok(Self::RemoveMapping(mapping_id))
82 }
83 6.. => bail!("Invalid finalize operation variant '{variant}'"),
84 }
85 }
86
87 /// Reads `Self` from a boolean array in big-endian order.
88 fn from_bits_be(bits: &[bool]) -> Result<Self> {
89 let mut bits = bits.iter().cloned();
90
91 // Helper function to get the next n bits as a slice.
92 let mut next_bits = |n: usize| -> Result<Vec<bool>> {
93 let bits: Vec<_> = bits.by_ref().take(n).collect();
94 if bits.len() < n {
95 bail!("Insufficient bits");
96 }
97 Ok(bits)
98 };
99
100 // Read the variant.
101 let variant = u8::from_bits_be(&next_bits(8)?)?;
102
103 // Parse the operation.
104 match variant {
105 0 => {
106 // Read the mapping ID.
107 let mapping_id = Field::from_bits_be(&next_bits(Field::<N>::size_in_bits())?)?;
108 // Return the finalize operation.
109 Ok(Self::InitializeMapping(mapping_id))
110 }
111 1 => {
112 // Read the mapping ID.
113 let mapping_id = Field::from_bits_be(&next_bits(Field::<N>::size_in_bits())?)?;
114 // Read the key ID.
115 let key_id = Field::from_bits_be(&next_bits(Field::<N>::size_in_bits())?)?;
116 // Read the value ID.
117 let value_id = Field::from_bits_be(&next_bits(Field::<N>::size_in_bits())?)?;
118 // Return the finalize operation.
119 Ok(Self::InsertKeyValue(mapping_id, key_id, value_id))
120 }
121 2 => {
122 // Read the mapping ID.
123 let mapping_id = Field::from_bits_be(&next_bits(Field::<N>::size_in_bits())?)?;
124 // Read the key ID.
125 let key_id = Field::from_bits_be(&next_bits(Field::<N>::size_in_bits())?)?;
126 // Read the value ID.
127 let value_id = Field::from_bits_be(&next_bits(Field::<N>::size_in_bits())?)?;
128 // Return the finalize operation.
129 Ok(Self::UpdateKeyValue(mapping_id, key_id, value_id))
130 }
131 3 => {
132 // Read the mapping ID.
133 let mapping_id = Field::from_bits_be(&next_bits(Field::<N>::size_in_bits())?)?;
134 // Read the key ID.
135 let key_id = Field::from_bits_be(&next_bits(Field::<N>::size_in_bits())?)?;
136 // Return the finalize operation.
137 Ok(Self::RemoveKeyValue(mapping_id, key_id))
138 }
139 4 => {
140 // Read the mapping ID.
141 let mapping_id = Field::from_bits_be(&next_bits(Field::<N>::size_in_bits())?)?;
142 // Return the finalize operation.
143 Ok(Self::ReplaceMapping(mapping_id))
144 }
145 5 => {
146 // Read the mapping ID.
147 let mapping_id = Field::from_bits_be(&next_bits(Field::<N>::size_in_bits())?)?;
148 // Return the finalize operation.
149 Ok(Self::RemoveMapping(mapping_id))
150 }
151 6.. => bail!("Invalid finalize operation variant '{variant}'"),
152 }
153 }
154}
155
156impl<N: Network> ToBits for FinalizeOperation<N> {
157 /// Returns the little-endian bits of the finalize operation.
158 fn write_bits_le(&self, vec: &mut Vec<bool>) {
159 match self {
160 Self::InitializeMapping(mapping_id) => {
161 // Write the variant.
162 0u8.write_bits_le(vec);
163 // Write the mapping ID.
164 mapping_id.write_bits_le(vec);
165 }
166 Self::InsertKeyValue(mapping_id, key_id, value_id) => {
167 // Write the variant.
168 1u8.write_bits_le(vec);
169 // Write the mapping ID.
170 mapping_id.write_bits_le(vec);
171 // Write the key ID.
172 key_id.write_bits_le(vec);
173 // Write the value ID.
174 value_id.write_bits_le(vec);
175 }
176 Self::UpdateKeyValue(mapping_id, key_id, value_id) => {
177 // Write the variant.
178 2u8.write_bits_le(vec);
179 // Write the mapping ID.
180 mapping_id.write_bits_le(vec);
181 // Write the key ID.
182 key_id.write_bits_le(vec);
183 // Write the value ID.
184 value_id.write_bits_le(vec);
185 }
186 Self::RemoveKeyValue(mapping_id, key_id) => {
187 // Write the variant.
188 3u8.write_bits_le(vec);
189 // Write the mapping ID.
190 mapping_id.write_bits_le(vec);
191 // Write the key ID.
192 key_id.write_bits_le(vec);
193 }
194 Self::ReplaceMapping(mapping_id) => {
195 // Write the variant.
196 4u8.write_bits_le(vec);
197 // Write the mapping ID.
198 mapping_id.write_bits_le(vec);
199 }
200 Self::RemoveMapping(mapping_id) => {
201 // Write the variant.
202 5u8.write_bits_le(vec);
203 // Write the mapping ID.
204 mapping_id.write_bits_le(vec);
205 }
206 }
207 }
208
209 /// Returns the big-endian bits of the finalize operation.
210 fn write_bits_be(&self, vec: &mut Vec<bool>) {
211 match self {
212 Self::InitializeMapping(mapping_id) => {
213 // Write the variant.
214 0u8.write_bits_be(vec);
215 // Write the mapping ID.
216 mapping_id.write_bits_be(vec);
217 }
218 Self::InsertKeyValue(mapping_id, key_id, value_id) => {
219 // Write the variant.
220 1u8.write_bits_be(vec);
221 // Write the mapping ID.
222 mapping_id.write_bits_be(vec);
223 // Write the key ID.
224 key_id.write_bits_be(vec);
225 // Write the value ID.
226 value_id.write_bits_be(vec);
227 }
228 Self::UpdateKeyValue(mapping_id, key_id, value_id) => {
229 // Write the variant.
230 2u8.write_bits_be(vec);
231 // Write the mapping ID.
232 mapping_id.write_bits_be(vec);
233 // Write the key ID.
234 key_id.write_bits_be(vec);
235 // Write the value ID.
236 value_id.write_bits_be(vec);
237 }
238 Self::RemoveKeyValue(mapping_id, key_id) => {
239 // Write the variant.
240 3u8.write_bits_be(vec);
241 // Write the mapping ID.
242 mapping_id.write_bits_be(vec);
243 // Write the key ID.
244 key_id.write_bits_be(vec);
245 }
246 Self::ReplaceMapping(mapping_id) => {
247 // Write the variant.
248 4u8.write_bits_be(vec);
249 // Write the mapping ID.
250 mapping_id.write_bits_be(vec);
251 }
252 Self::RemoveMapping(mapping_id) => {
253 // Write the variant.
254 5u8.write_bits_be(vec);
255 // Write the mapping ID.
256 mapping_id.write_bits_be(vec);
257 }
258 }
259 }
260}
261
262#[cfg(test)]
263mod tests {
264 use super::*;
265
266 #[test]
267 fn test_bits_le() {
268 for expected in crate::logic::finalize_operation::test_helpers::sample_finalize_operations() {
269 // Check the bit representation.
270 let expected_bits = expected.to_bits_le();
271 assert_eq!(expected, FinalizeOperation::from_bits_le(&expected_bits[..]).unwrap());
272 }
273 }
274
275 #[test]
276 fn test_bits_be() {
277 for expected in crate::logic::finalize_operation::test_helpers::sample_finalize_operations() {
278 // Check the bit representation.
279 let expected_bits = expected.to_bits_be();
280 assert_eq!(expected, FinalizeOperation::from_bits_be(&expected_bits[..]).unwrap());
281 }
282 }
283}