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 }