snarkvm_console_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<N: Network> ToBits for Record<N, Plaintext<N>> {
19    /// Returns this data as a list of **little-endian** bits.
20    fn write_bits_le(&self, vec: &mut Vec<bool>) {
21        // Construct the owner visibility bit.
22        vec.push(self.owner.is_private());
23
24        // Construct the owner bits.
25        match &self.owner {
26            Owner::Public(public) => public.write_bits_le(vec),
27            Owner::Private(Plaintext::Literal(Literal::Address(address), ..)) => address.write_bits_le(vec),
28            _ => N::halt("Internal error: plaintext to_bits_le corrupted in record owner"),
29        };
30
31        // Compute the data bits.
32        let mut data_bits_le = vec![];
33        for (identifier, entry) in &self.data {
34            identifier.write_bits_le(&mut data_bits_le);
35            entry.write_bits_le(&mut data_bits_le);
36        }
37
38        // Ensure the data length is less than 2^31 bits.
39        if data_bits_le.len() >= (1 << 31) {
40            N::halt("Record data exceeds (1 << 31) bits")
41        }
42
43        // Write the first 31 bits of the data length (as we know it is less than 2^31).
44        // Note: In order to introduce a hiding bitflag, we repurpose the last bit as the hiding bit.
45        let data_bits_len = u32::try_from(data_bits_le.len()).or_halt_with::<N>("Record data exceeds u32::MAX bits");
46        vec.extend_from_slice(&data_bits_len.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<bool>) {
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            _ => N::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
81        // Ensure the data length is less than 2^31 bits.
82        if data_bits_be.len() >= (1 << 31) {
83            N::halt("Record data exceeds (1 << 31) bits")
84        }
85
86        // Construct the hiding bit.
87        // Note: While this bitflag is redundant, it is necessary for backwards compatibility.
88        vec.push(self.is_hiding());
89
90        // Write the last 31 bits of the data length (as we know it is less than 2^31).
91        // Note: In order to introduce a hiding bitflag, we repurpose the first bit as the hiding bit.
92        let data_bits_len = u32::try_from(data_bits_be.len()).or_halt_with::<N>("Record data exceeds u32::MAX bits");
93        vec.extend_from_slice(&data_bits_len.to_bits_be()[1..]);
94
95        // Construct the data bits.
96        vec.extend_from_slice(&data_bits_be);
97
98        // Construct the nonce bits.
99        self.nonce.write_bits_be(vec);
100
101        // Construct the version bits.
102        self.version.write_bits_be(vec);
103    }
104}
105
106impl<N: Network> ToBits for Record<N, Ciphertext<N>> {
107    /// Returns this data as a list of **little-endian** bits.
108    fn write_bits_le(&self, vec: &mut Vec<bool>) {
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 => N::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
131        // Ensure the data length is less than 2^31 bits.
132        if data_bits_le.len() >= (1 << 31) {
133            N::halt("Record data exceeds (1 << 31) bits")
134        }
135
136        // Write the first 31 bits of the data length (as we know it is less than 2^31).
137        // Note: In order to introduce a hiding bitflag, we repurpose the last bit as the hiding bit.
138        let data_bits_len = u32::try_from(data_bits_le.len()).or_halt_with::<N>("Record data exceeds u32::MAX bits");
139        vec.extend_from_slice(&data_bits_len.to_bits_le()[..31]);
140
141        // Construct the hiding bit.
142        // Note: While this bitflag is redundant, it is necessary for backwards compatibility.
143        vec.push(self.is_hiding());
144
145        // Construct the data bits.
146        vec.extend_from_slice(&data_bits_le);
147
148        // Construct the nonce bits.
149        self.nonce.write_bits_le(vec);
150
151        // Construct the version bits.
152        self.version.write_bits_le(vec);
153    }
154
155    /// Returns this data as a list of **big-endian** bits.
156    fn write_bits_be(&self, vec: &mut Vec<bool>) {
157        // Construct the owner visibility bit.
158        vec.push(self.owner.is_private());
159
160        // Construct the owner bits.
161        match &self.owner {
162            Owner::Public(public) => public.write_bits_be(vec),
163            Owner::Private(ciphertext) => {
164                // Ensure there is exactly one field element in the ciphertext.
165                match ciphertext.len() == 1 {
166                    true => ciphertext[0].write_bits_be(vec),
167                    false => N::halt("Internal error: ciphertext to_bits_be corrupted in record owner"),
168                }
169            }
170        };
171
172        // Compute the data bits.
173        let mut data_bits_be = vec![];
174        for (identifier, entry) in &self.data {
175            identifier.write_bits_be(&mut data_bits_be);
176            entry.write_bits_be(&mut data_bits_be);
177        }
178
179        // Ensure the data length is less than 2^31 bits.
180        if data_bits_be.len() >= (1 << 31) {
181            N::halt("Record data exceeds (1 << 31) bits")
182        }
183
184        // Construct the hiding bit.
185        // Note: While this bitflag is redundant, it is necessary for backwards compatibility.
186        vec.push(self.is_hiding());
187
188        // Write the last 31 bits of the data length (as we know it is less than 2^31).
189        // Note: In order to introduce a hiding bitflag, we repurpose the first bit as the hiding bit.
190        let data_bits_len = u32::try_from(data_bits_be.len()).or_halt_with::<N>("Record data exceeds u32::MAX bits");
191        vec.extend_from_slice(&data_bits_len.to_bits_be()[1..]);
192
193        // Construct the data bits.
194        vec.extend_from_slice(&data_bits_be);
195
196        // Construct the nonce bits.
197        self.nonce.write_bits_be(vec);
198
199        // Construct the version bits.
200        self.version.write_bits_be(vec);
201    }
202}