from_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> Literal<N> { 22 /// Initializes a new literal from a list of little-endian bits *without* trailing zeros. 23 pub fn from_bits_le(variant: u8, bits_le: &[bool]) -> Result<Self> { 24 let literal = bits_le; 25 let literal = match variant { 26 0 => Literal::Address(Address::new(Group::from_x_coordinate(Field::<N>::from_bits_le(literal)?)?)), 27 1 => match bits_le.len() { 28 1 => Literal::Boolean(Boolean::new(literal[0])), 29 _ => bail!("Expected a boolean literal, but found a list of {} bits.", bits_le.len()), 30 }, 31 2 => Literal::Field(Field::from_bits_le(literal)?), 32 3 => Literal::Group(Group::from_bits_le(literal)?), 33 4 => Literal::I8(I8::from_bits_le(literal)?), 34 5 => Literal::I16(I16::from_bits_le(literal)?), 35 6 => Literal::I32(I32::from_bits_le(literal)?), 36 7 => Literal::I64(I64::from_bits_le(literal)?), 37 8 => Literal::I128(I128::from_bits_le(literal)?), 38 9 => Literal::U8(U8::from_bits_le(literal)?), 39 10 => Literal::U16(U16::from_bits_le(literal)?), 40 11 => Literal::U32(U32::from_bits_le(literal)?), 41 12 => Literal::U64(U64::from_bits_le(literal)?), 42 13 => Literal::U128(U128::from_bits_le(literal)?), 43 14 => Literal::Scalar(Scalar::from_bits_le(literal)?), 44 15 => Literal::Signature(Box::new(Signature::from_bits_le(literal)?)), 45 16 => { 46 let buffer = Vec::<u8>::from_bits_le(literal)?; 47 match buffer.len() <= N::MAX_STRING_BYTES as usize { 48 true => { 49 let string = String::from_utf8(buffer).map_err(|e| error(format!("{e}")))?; 50 Self::String(StringType::new(&string)) 51 } 52 false => bail!("String literal exceeds maximum length of {} bytes.", N::MAX_STRING_BYTES), 53 } 54 } 55 17.. => bail!("Failed to initialize literal variant {variant} from bits (LE)"), 56 }; 57 Ok(literal) 58 } 59 60 /// Initializes a new literal from a list of big-endian bits *without* leading zeros. 61 pub fn from_bits_be(variant: u8, bits_be: &[bool]) -> Result<Self> { 62 let literal = bits_be; 63 let literal = match variant { 64 0 => Literal::Address(Address::new(Group::from_x_coordinate(Field::from_bits_be(literal)?)?)), 65 1 => match bits_be.len() { 66 1 => Literal::Boolean(Boolean::new(literal[0])), 67 _ => bail!("Expected a boolean literal, but found a list of {} bits.", bits_be.len()), 68 }, 69 2 => Literal::Field(Field::from_bits_be(literal)?), 70 3 => Literal::Group(Group::from_bits_be(literal)?), 71 4 => Literal::I8(I8::from_bits_be(literal)?), 72 5 => Literal::I16(I16::from_bits_be(literal)?), 73 6 => Literal::I32(I32::from_bits_be(literal)?), 74 7 => Literal::I64(I64::from_bits_be(literal)?), 75 8 => Literal::I128(I128::from_bits_be(literal)?), 76 9 => Literal::U8(U8::from_bits_be(literal)?), 77 10 => Literal::U16(U16::from_bits_be(literal)?), 78 11 => Literal::U32(U32::from_bits_be(literal)?), 79 12 => Literal::U64(U64::from_bits_be(literal)?), 80 13 => Literal::U128(U128::from_bits_be(literal)?), 81 14 => Literal::Scalar(Scalar::from_bits_be(literal)?), 82 15 => Literal::Signature(Box::new(Signature::from_bits_be(literal)?)), 83 16 => { 84 let buffer = Vec::<u8>::from_bits_be(literal)?; 85 match buffer.len() <= N::MAX_STRING_BYTES as usize { 86 true => { 87 let string = String::from_utf8(buffer).map_err(|e| error(format!("{e}")))?; 88 Self::String(StringType::new(&string)) 89 } 90 false => bail!("String literal exceeds maximum length of {} bytes.", N::MAX_STRING_BYTES), 91 } 92 } 93 17.. => bail!("Failed to initialize literal variant {variant} from bits (BE)"), 94 }; 95 Ok(literal) 96 } 97 } 98 99 #[cfg(test)] 100 mod tests { 101 use super::*; 102 use alphavm_console_network::MainnetV0; 103 104 type CurrentNetwork = MainnetV0; 105 106 const ITERATIONS: u32 = 1000; 107 108 fn check_serialization(expected: Literal<CurrentNetwork>) -> Result<()> { 109 println!("{expected}"); 110 assert_eq!(expected, Literal::from_bits_le(expected.variant(), &expected.to_bits_le())?); 111 assert_eq!(expected, Literal::from_bits_be(expected.variant(), &expected.to_bits_be())?); 112 Ok(()) 113 } 114 115 #[test] 116 fn test_from_bits() -> Result<()> { 117 let rng = &mut TestRng::default(); 118 119 for _ in 0..ITERATIONS { 120 let private_key = alphavm_console_account::PrivateKey::<CurrentNetwork>::new(rng)?; 121 122 // Address 123 check_serialization(Literal::<CurrentNetwork>::Address(Address::try_from(private_key)?))?; 124 // Boolean 125 check_serialization(Literal::<CurrentNetwork>::Boolean(Boolean::new(Uniform::rand(rng))))?; 126 // Field 127 check_serialization(Literal::<CurrentNetwork>::Field(Uniform::rand(rng)))?; 128 // Group 129 check_serialization(Literal::<CurrentNetwork>::Group(Uniform::rand(rng)))?; 130 // I8 131 check_serialization(Literal::<CurrentNetwork>::I8(I8::new(Uniform::rand(rng))))?; 132 // I16 133 check_serialization(Literal::<CurrentNetwork>::I16(I16::new(Uniform::rand(rng))))?; 134 // I32 135 check_serialization(Literal::<CurrentNetwork>::I32(I32::new(Uniform::rand(rng))))?; 136 // I64 137 check_serialization(Literal::<CurrentNetwork>::I64(I64::new(Uniform::rand(rng))))?; 138 // I128 139 check_serialization(Literal::<CurrentNetwork>::I128(I128::new(Uniform::rand(rng))))?; 140 // U8 141 check_serialization(Literal::<CurrentNetwork>::U8(U8::new(Uniform::rand(rng))))?; 142 // U16 143 check_serialization(Literal::<CurrentNetwork>::U16(U16::new(Uniform::rand(rng))))?; 144 // U32 145 check_serialization(Literal::<CurrentNetwork>::U32(U32::new(Uniform::rand(rng))))?; 146 // U64 147 check_serialization(Literal::<CurrentNetwork>::U64(U64::new(Uniform::rand(rng))))?; 148 // U128 149 check_serialization(Literal::<CurrentNetwork>::U128(U128::new(Uniform::rand(rng))))?; 150 // Scalar 151 check_serialization(Literal::<CurrentNetwork>::Scalar(Uniform::rand(rng)))?; 152 // Signature 153 check_serialization(Literal::sample(LiteralType::Signature, rng))?; 154 // String 155 // Sample a random string. Take 1/4th to ensure we fit for all code points. 156 let string = rng.next_string(CurrentNetwork::MAX_STRING_BYTES / 4, false); 157 check_serialization(Literal::<CurrentNetwork>::String(StringType::new(&string)))?; 158 } 159 Ok(()) 160 } 161 }