snarkvm_console_program/id/
to_bits.rs

1// Copyright 2024 Aleo Network Foundation
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> ToBits for ProgramID<N> {
19    /// Returns the little-endian bits of the program ID.
20    fn write_bits_le(&self, vec: &mut Vec<bool>) {
21        (&self).write_bits_le(vec);
22    }
23
24    /// Returns the big-endian bits of the program ID.
25    fn write_bits_be(&self, vec: &mut Vec<bool>) {
26        (&self).write_bits_be(vec);
27    }
28}
29
30impl<N: Network> ToBits for &ProgramID<N> {
31    /// Returns the little-endian bits of the program ID.
32    fn write_bits_le(&self, vec: &mut Vec<bool>) {
33        self.name().write_bits_le(vec);
34        self.network().write_bits_le(vec);
35    }
36
37    /// Returns the big-endian bits of the program ID.
38    fn write_bits_be(&self, vec: &mut Vec<bool>) {
39        self.name().write_bits_be(vec);
40        self.network().write_bits_be(vec);
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47    use crate::data::identifier::tests::sample_lowercase_identifier_as_string;
48    use snarkvm_console_network::MainnetV0;
49
50    type CurrentNetwork = MainnetV0;
51
52    const ITERATIONS: usize = 100;
53
54    #[test]
55    fn test_to_bits_le() -> Result<()> {
56        let mut rng = TestRng::default();
57
58        for _ in 0..ITERATIONS {
59            // Sample a random fixed-length alphanumeric string, that always starts with an alphabetic character.
60            let expected_name_string = sample_lowercase_identifier_as_string::<CurrentNetwork>(&mut rng)?;
61            // Recover the field element from the bits.
62            let expected_name_field = Field::<CurrentNetwork>::from_bits_le(&expected_name_string.to_bits_le())?;
63            let expected_network_field = Field::<CurrentNetwork>::from_bits_le(&"aleo".to_string().to_bits_le())?;
64            // Compute the expected bits.
65            let mut expected_bits = expected_name_field.to_bits_le()[..expected_name_string.len() * 8].to_vec();
66            expected_bits.extend(&expected_network_field.to_bits_le()[..4 * 8]);
67
68            let candidate = ProgramID::<CurrentNetwork>::from_str(&format!("{expected_name_string}.aleo"))?;
69            assert_eq!(
70                expected_name_field.to_bits_le()[..expected_name_string.len() * 8],
71                candidate.name().to_bits_le()
72            );
73            assert_eq!(expected_network_field.to_bits_le()[..4 * 8], candidate.network().to_bits_le());
74            assert_eq!(expected_bits, candidate.to_bits_le());
75        }
76        Ok(())
77    }
78
79    #[test]
80    fn test_to_bits_be() -> Result<()> {
81        let mut rng = TestRng::default();
82
83        for _ in 0..ITERATIONS {
84            // Sample a random fixed-length alphanumeric string, that always starts with an alphabetic character.
85            let expected_name_string = sample_lowercase_identifier_as_string::<CurrentNetwork>(&mut rng)?;
86            // Recover the field element from the bits.
87            let expected_name_field = Field::<CurrentNetwork>::from_bits_le(&expected_name_string.to_bits_le())?;
88            let expected_network_field = Field::<CurrentNetwork>::from_bits_le(&"aleo".to_string().to_bits_le())?;
89            // Compute the expected bits.
90            let mut expected_bits = expected_name_field.to_bits_le()[..expected_name_string.len() * 8]
91                .iter()
92                .rev()
93                .copied()
94                .collect::<Vec<_>>();
95            expected_bits.extend(expected_network_field.to_bits_le()[..4 * 8].iter().rev().copied());
96
97            let candidate = ProgramID::<CurrentNetwork>::from_str(&format!("{expected_name_string}.aleo"))?;
98            assert_eq!(
99                expected_name_field.to_bits_le()[..expected_name_string.len() * 8]
100                    .iter()
101                    .rev()
102                    .copied()
103                    .collect::<Vec<_>>(),
104                candidate.name().to_bits_be()
105            );
106            assert_eq!(
107                expected_network_field.to_bits_le()[..4 * 8].iter().rev().copied().collect::<Vec<_>>(),
108                candidate.network().to_bits_be()
109            );
110            assert_eq!(expected_bits, candidate.to_bits_be());
111        }
112        Ok(())
113    }
114}