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}