snarkvm_circuit_program/data/record/
to_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<A: Aleo> ToBits for Record<A, Plaintext<A>> {
19    type Boolean = Boolean<A>;
20
21    /// Returns this data as a list of **little-endian** bits.
22    fn write_bits_le(&self, vec: &mut Vec<Self::Boolean>) {
23        // Construct the owner visibility bit.
24        vec.push(self.owner.is_private());
25
26        // Construct the owner bits.
27        match &self.owner {
28            Owner::Public(public) => public.write_bits_le(vec),
29            Owner::Private(Plaintext::Literal(Literal::Address(address), ..)) => address.write_bits_le(vec),
30            _ => A::halt("Internal error: plaintext to_bits_le corrupted in record owner"),
31        };
32
33        // Compute the data bits.
34        let mut data_bits_le = vec![];
35        for (identifier, entry) in &self.data {
36            identifier.write_bits_le(&mut data_bits_le);
37            entry.write_bits_le(&mut data_bits_le);
38        }
39        // Ensure the data length is less than 2^31 bits.
40        if data_bits_le.len() >= (1 << 31) {
41            A::halt("Record data exceeds (1 << 31) bits")
42        }
43
44        // Write the first 31 bits of the data length (as we know it is less than 2^31).
45        // Note: In order to introduce a hiding bitflag, we repurpose the last bit as the hiding bit.
46        vec.extend_from_slice(&U32::constant(console::U32::new(data_bits_le.len() as u32)).to_bits_le()[..31]);
47
48        // Construct the hiding bit.
49        // Note: While this bitflag is redundant, it is necessary for backwards compatibility.
50        vec.push(self.is_hiding());
51
52        // Construct the data bits.
53        vec.extend_from_slice(&data_bits_le);
54
55        // Construct the nonce bits.
56        self.nonce.write_bits_le(vec);
57
58        // Construct the version bits.
59        self.version.write_bits_le(vec);
60    }
61
62    /// Returns this data as a list of **big-endian** bits.
63    fn write_bits_be(&self, vec: &mut Vec<Self::Boolean>) {
64        // Construct the owner visibility bit.
65        vec.push(self.owner.is_private());
66
67        // Construct the owner bits.
68        match &self.owner {
69            Owner::Public(public) => public.write_bits_be(vec),
70            Owner::Private(Plaintext::Literal(Literal::Address(address), ..)) => address.write_bits_be(vec),
71            _ => A::halt("Internal error: plaintext to_bits_be corrupted in record owner"),
72        };
73
74        // Compute the data bits.
75        let mut data_bits_be = vec![];
76        for (identifier, entry) in &self.data {
77            identifier.write_bits_be(&mut data_bits_be);
78            entry.write_bits_be(&mut data_bits_be);
79        }
80        // Ensure the data length is less than 2^31 bits.
81        if data_bits_be.len() >= (1 << 31) {
82            A::halt("Record data exceeds (1 << 31) bits")
83        }
84
85        // Construct the hiding bit.
86        // Note: While this bitflag is redundant, it is necessary for backwards compatibility.
87        vec.push(self.is_hiding());
88
89        // Write the last 31 bits of the data length (as we know it is less than 2^31).
90        // Note: In order to introduce a hiding bitflag, we repurpose the first bit as the hiding bit.
91        vec.extend_from_slice(&U32::constant(console::U32::new(data_bits_be.len() as u32)).to_bits_be()[1..]);
92
93        // Construct the data bits.
94        vec.extend_from_slice(&data_bits_be);
95
96        // Construct the nonce bits.
97        self.nonce.write_bits_be(vec);
98
99        // Construct the version bits.
100        self.version.write_bits_be(vec);
101    }
102}
103
104impl<A: Aleo> ToBits for Record<A, Ciphertext<A>> {
105    type Boolean = Boolean<A>;
106
107    /// Returns this data as a list of **little-endian** bits.
108    fn write_bits_le(&self, vec: &mut Vec<Self::Boolean>) {
109        // Construct the owner visibility bit.
110        vec.push(self.owner.is_private());
111
112        // Construct the owner bits.
113        match &self.owner {
114            Owner::Public(public) => public.write_bits_le(vec),
115            Owner::Private(ciphertext) => {
116                // Ensure there is exactly one field element in the ciphertext.
117                match ciphertext.len() == 1 {
118                    true => ciphertext[0].write_bits_le(vec),
119                    false => A::halt("Internal error: ciphertext to_bits_le corrupted in record owner"),
120                }
121            }
122        };
123
124        // Compute the data bits.
125        let mut data_bits_le = vec![];
126        for (identifier, entry) in &self.data {
127            identifier.write_bits_le(&mut data_bits_le);
128            entry.write_bits_le(&mut data_bits_le);
129        }
130        // Ensure the data length is less than 2^31 bits.
131        if data_bits_le.len() >= (1 << 31) {
132            A::halt("Record data exceeds (1 << 31) bits")
133        }
134
135        // Write the first 31 bits of the data length (as we know it is less than 2^31).
136        // Note: In order to introduce a hiding bitflag, we repurpose the last bit as the hiding bit.
137        vec.extend_from_slice(&U32::constant(console::U32::new(data_bits_le.len() as u32)).to_bits_le()[..31]);
138
139        // Construct the hiding bit.
140        // Note: While this bitflag is redundant, it is necessary for backwards compatibility.
141        vec.push(self.is_hiding());
142
143        // Construct the data bits.
144        vec.extend_from_slice(&data_bits_le);
145
146        // Construct the nonce bits.
147        self.nonce.write_bits_le(vec);
148
149        // Construct the version bits.
150        self.version.write_bits_le(vec);
151    }
152
153    /// Returns this data as a list of **big-endian** bits.
154    fn write_bits_be(&self, vec: &mut Vec<Self::Boolean>) {
155        // Construct the owner visibility bit.
156        vec.push(self.owner.is_private());
157
158        // Construct the owner bits.
159        match &self.owner {
160            Owner::Public(public) => public.write_bits_be(vec),
161            Owner::Private(ciphertext) => {
162                // Ensure there is exactly one field element in the ciphertext.
163                match ciphertext.len() == 1 {
164                    true => ciphertext[0].write_bits_be(vec),
165                    false => A::halt("Internal error: ciphertext to_bits_be corrupted in record owner"),
166                }
167            }
168        };
169
170        // Compute the data bits.
171        let mut data_bits_be = vec![];
172        for (identifier, entry) in &self.data {
173            identifier.write_bits_be(&mut data_bits_be);
174            entry.write_bits_be(&mut data_bits_be);
175        }
176
177        // Ensure the data length is less than 2^31 bits.
178        if data_bits_be.len() >= (1 << 31) {
179            A::halt("Record data exceeds (1 << 31) bits")
180        }
181
182        // Construct the hiding bit.
183        // Note: While this bitflag is redundant, it is necessary for backwards compatibility.
184        vec.push(self.is_hiding());
185
186        // Write the last 31 bits of the data length (as we know it is less than 2^31).
187        // Note: In order to introduce a hiding bitflag, we repurpose the first bit as the hiding bit.
188        vec.extend_from_slice(&U32::constant(console::U32::new(data_bits_be.len() as u32)).to_bits_be()[1..]);
189
190        // Construct the data bits.
191        vec.extend_from_slice(&data_bits_be);
192
193        // Construct the nonce bits.
194        self.nonce.write_bits_be(vec);
195
196        // Construct the version bits.
197        self.version.write_bits_be(vec);
198    }
199}