to_bits.rs
1 // Copyright (c) 2025-2026 ACDC Network 2 // This file is part of the alphavm library. 3 // 4 // Alpha Chain | Delta Chain Protocol 5 // International Monetary Graphite. 6 // 7 // Derived from Aleo (https://aleo.org) and ProvableHQ (https://provable.com). 8 // They built world-class ZK infrastructure. We installed the EASY button. 9 // Their cryptography: elegant. Our modifications: bureaucracy-compatible. 10 // Original brilliance: theirs. Robert's Rules: ours. Bugs: definitely ours. 11 // 12 // Original Aleo/ProvableHQ code subject to Apache 2.0 https://www.apache.org/licenses/LICENSE-2.0 13 // All modifications and new work: CC0 1.0 Universal Public Domain Dedication. 14 // No rights reserved. No permission required. No warranty. No refunds. 15 // 16 // https://creativecommons.org/publicdomain/zero/1.0/ 17 // SPDX-License-Identifier: CC0-1.0 18 19 use super::*; 20 21 impl<N: Network> ToBits for Record<N, Plaintext<N>> { 22 /// Returns this data as a list of **little-endian** bits. 23 fn write_bits_le(&self, vec: &mut Vec<bool>) { 24 // Construct the owner visibility bit. 25 vec.push(self.owner.is_private()); 26 27 // Construct the owner bits. 28 match &self.owner { 29 Owner::Public(public) => public.write_bits_le(vec), 30 Owner::Private(Plaintext::Literal(Literal::Address(address), ..)) => address.write_bits_le(vec), 31 _ => N::halt("Internal error: plaintext to_bits_le corrupted in record owner"), 32 }; 33 34 // Compute the data bits. 35 let mut data_bits_le = vec![]; 36 for (identifier, entry) in &self.data { 37 identifier.write_bits_le(&mut data_bits_le); 38 entry.write_bits_le(&mut data_bits_le); 39 } 40 41 // Ensure the data length is less than 2^31 bits. 42 if data_bits_le.len() >= (1 << 31) { 43 N::halt("Record data exceeds (1 << 31) bits") 44 } 45 46 // Write the first 31 bits of the data length (as we know it is less than 2^31). 47 // Note: In order to introduce a hiding bitflag, we repurpose the last bit as the hiding bit. 48 let data_bits_len = u32::try_from(data_bits_le.len()).or_halt_with::<N>("Record data exceeds u32::MAX bits"); 49 vec.extend_from_slice(&data_bits_len.to_bits_le()[..31]); 50 51 // Construct the hiding bit. 52 // Note: While this bitflag is redundant, it is necessary for backwards compatibility. 53 vec.push(self.is_hiding()); 54 55 // Construct the data bits. 56 vec.extend_from_slice(&data_bits_le); 57 58 // Construct the nonce bits. 59 self.nonce.write_bits_le(vec); 60 61 // Construct the version bits. 62 self.version.write_bits_le(vec); 63 } 64 65 /// Returns this data as a list of **big-endian** bits. 66 fn write_bits_be(&self, vec: &mut Vec<bool>) { 67 // Construct the owner visibility bit. 68 vec.push(self.owner.is_private()); 69 70 // Construct the owner bits. 71 match &self.owner { 72 Owner::Public(public) => public.write_bits_be(vec), 73 Owner::Private(Plaintext::Literal(Literal::Address(address), ..)) => address.write_bits_be(vec), 74 _ => N::halt("Internal error: plaintext to_bits_be corrupted in record owner"), 75 }; 76 77 // Compute the data bits. 78 let mut data_bits_be = vec![]; 79 for (identifier, entry) in &self.data { 80 identifier.write_bits_be(&mut data_bits_be); 81 entry.write_bits_be(&mut data_bits_be); 82 } 83 84 // Ensure the data length is less than 2^31 bits. 85 if data_bits_be.len() >= (1 << 31) { 86 N::halt("Record data exceeds (1 << 31) bits") 87 } 88 89 // Construct the hiding bit. 90 // Note: While this bitflag is redundant, it is necessary for backwards compatibility. 91 vec.push(self.is_hiding()); 92 93 // Write the last 31 bits of the data length (as we know it is less than 2^31). 94 // Note: In order to introduce a hiding bitflag, we repurpose the first bit as the hiding bit. 95 let data_bits_len = u32::try_from(data_bits_be.len()).or_halt_with::<N>("Record data exceeds u32::MAX bits"); 96 vec.extend_from_slice(&data_bits_len.to_bits_be()[1..]); 97 98 // Construct the data bits. 99 vec.extend_from_slice(&data_bits_be); 100 101 // Construct the nonce bits. 102 self.nonce.write_bits_be(vec); 103 104 // Construct the version bits. 105 self.version.write_bits_be(vec); 106 } 107 } 108 109 impl<N: Network> ToBits for Record<N, Ciphertext<N>> { 110 /// Returns this data as a list of **little-endian** bits. 111 fn write_bits_le(&self, vec: &mut Vec<bool>) { 112 // Construct the owner visibility bit. 113 vec.push(self.owner.is_private()); 114 115 // Construct the owner bits. 116 match &self.owner { 117 Owner::Public(public) => public.write_bits_le(vec), 118 Owner::Private(ciphertext) => { 119 // Ensure there is exactly one field element in the ciphertext. 120 match ciphertext.len() == 1 { 121 true => ciphertext[0].write_bits_le(vec), 122 false => N::halt("Internal error: ciphertext to_bits_le corrupted in record owner"), 123 } 124 } 125 }; 126 127 // Compute the data bits. 128 let mut data_bits_le = vec![]; 129 for (identifier, entry) in &self.data { 130 identifier.write_bits_le(&mut data_bits_le); 131 entry.write_bits_le(&mut data_bits_le); 132 } 133 134 // Ensure the data length is less than 2^31 bits. 135 if data_bits_le.len() >= (1 << 31) { 136 N::halt("Record data exceeds (1 << 31) bits") 137 } 138 139 // Write the first 31 bits of the data length (as we know it is less than 2^31). 140 // Note: In order to introduce a hiding bitflag, we repurpose the last bit as the hiding bit. 141 let data_bits_len = u32::try_from(data_bits_le.len()).or_halt_with::<N>("Record data exceeds u32::MAX bits"); 142 vec.extend_from_slice(&data_bits_len.to_bits_le()[..31]); 143 144 // Construct the hiding bit. 145 // Note: While this bitflag is redundant, it is necessary for backwards compatibility. 146 vec.push(self.is_hiding()); 147 148 // Construct the data bits. 149 vec.extend_from_slice(&data_bits_le); 150 151 // Construct the nonce bits. 152 self.nonce.write_bits_le(vec); 153 154 // Construct the version bits. 155 self.version.write_bits_le(vec); 156 } 157 158 /// Returns this data as a list of **big-endian** bits. 159 fn write_bits_be(&self, vec: &mut Vec<bool>) { 160 // Construct the owner visibility bit. 161 vec.push(self.owner.is_private()); 162 163 // Construct the owner bits. 164 match &self.owner { 165 Owner::Public(public) => public.write_bits_be(vec), 166 Owner::Private(ciphertext) => { 167 // Ensure there is exactly one field element in the ciphertext. 168 match ciphertext.len() == 1 { 169 true => ciphertext[0].write_bits_be(vec), 170 false => N::halt("Internal error: ciphertext to_bits_be corrupted in record owner"), 171 } 172 } 173 }; 174 175 // Compute the data bits. 176 let mut data_bits_be = vec![]; 177 for (identifier, entry) in &self.data { 178 identifier.write_bits_be(&mut data_bits_be); 179 entry.write_bits_be(&mut data_bits_be); 180 } 181 182 // Ensure the data length is less than 2^31 bits. 183 if data_bits_be.len() >= (1 << 31) { 184 N::halt("Record data exceeds (1 << 31) bits") 185 } 186 187 // Construct the hiding bit. 188 // Note: While this bitflag is redundant, it is necessary for backwards compatibility. 189 vec.push(self.is_hiding()); 190 191 // Write the last 31 bits of the data length (as we know it is less than 2^31). 192 // Note: In order to introduce a hiding bitflag, we repurpose the first bit as the hiding bit. 193 let data_bits_len = u32::try_from(data_bits_be.len()).or_halt_with::<N>("Record data exceeds u32::MAX bits"); 194 vec.extend_from_slice(&data_bits_len.to_bits_be()[1..]); 195 196 // Construct the data bits. 197 vec.extend_from_slice(&data_bits_be); 198 199 // Construct the nonce bits. 200 self.nonce.write_bits_be(vec); 201 202 // Construct the version bits. 203 self.version.write_bits_be(vec); 204 } 205 }