/ console / program / src / data / record / to_bits.rs
to_bits.rs
  1  // Copyright (c) 2019-2025 Alpha-Delta Network Inc.
  2  // This file is part of the alphavm 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  
 16  use super::*;
 17  
 18  impl<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  
106  impl<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  }