mod.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 mod boolean; 20 mod field; 21 mod integer; 22 mod scalar; 23 24 use crate::{Literal, LiteralType}; 25 use alphavm_console_network::Network; 26 use alphavm_console_types::{integers::Integer, prelude::*, Boolean}; 27 28 /// Unary operator for casting values of one type to another. 29 pub trait Cast<T: Sized = Self> { 30 /// Casts the value of `self` into a value of type `T`. 31 /// 32 /// This method checks that the cast does not lose any bits of information, 33 /// and returns an error if it does. 34 fn cast(&self) -> Result<T>; 35 } 36 37 impl<N: Network> Literal<N> { 38 /// Casts the literal to the given literal type. 39 /// 40 /// This method checks that the cast does not lose any bits of information, 41 /// and returns an error if it does. 42 /// 43 /// The hierarchy of casting is as follows: 44 /// - (`Address`, `Group`) <-> `Field` <-> `Scalar` <-> `Integer` <-> `Boolean` 45 /// - `Signature` (not supported) 46 /// - `String` (not supported) 47 /// 48 /// Note that casting to left along the hierarchy always preserves information. 49 pub fn cast(&self, to_type: LiteralType) -> Result<Self> { 50 match self { 51 Self::Address(address) => cast_group_to_type(address.to_group(), to_type), 52 Self::Boolean(boolean) => cast_boolean_to_type(boolean, to_type), 53 Self::Field(field) => cast_field_to_type(field, to_type), 54 Self::Group(group) => cast_group_to_type(group, to_type), 55 Self::I8(integer) => cast_integer_to_type(integer, to_type), 56 Self::I16(integer) => cast_integer_to_type(integer, to_type), 57 Self::I32(integer) => cast_integer_to_type(integer, to_type), 58 Self::I64(integer) => cast_integer_to_type(integer, to_type), 59 Self::I128(integer) => cast_integer_to_type(integer, to_type), 60 Self::U8(integer) => cast_integer_to_type(integer, to_type), 61 Self::U16(integer) => cast_integer_to_type(integer, to_type), 62 Self::U32(integer) => cast_integer_to_type(integer, to_type), 63 Self::U64(integer) => cast_integer_to_type(integer, to_type), 64 Self::U128(integer) => cast_integer_to_type(integer, to_type), 65 Self::Scalar(scalar) => cast_scalar_to_type(scalar, to_type), 66 Self::Signature(..) => bail!("Cannot cast a signature literal to another type."), 67 Self::String(..) => bail!("Cannot cast a string literal to another type."), 68 } 69 } 70 } 71 72 /// A helper macro to implement the body of the `cast` methods. 73 macro_rules! impl_cast_body { 74 ($type_name:ident, $cast:ident, $input:expr, $to_type:expr) => { 75 match $to_type { 76 LiteralType::Address => Ok(Literal::Address($input.$cast()?)), 77 LiteralType::Boolean => Ok(Literal::Boolean($input.$cast()?)), 78 LiteralType::Field => Ok(Literal::Field($input.$cast()?)), 79 LiteralType::Group => Ok(Literal::Group($input.$cast()?)), 80 LiteralType::I8 => Ok(Literal::I8($input.$cast()?)), 81 LiteralType::I16 => Ok(Literal::I16($input.$cast()?)), 82 LiteralType::I32 => Ok(Literal::I32($input.$cast()?)), 83 LiteralType::I64 => Ok(Literal::I64($input.$cast()?)), 84 LiteralType::I128 => Ok(Literal::I128($input.$cast()?)), 85 LiteralType::U8 => Ok(Literal::U8($input.$cast()?)), 86 LiteralType::U16 => Ok(Literal::U16($input.$cast()?)), 87 LiteralType::U32 => Ok(Literal::U32($input.$cast()?)), 88 LiteralType::U64 => Ok(Literal::U64($input.$cast()?)), 89 LiteralType::U128 => Ok(Literal::U128($input.$cast()?)), 90 LiteralType::Scalar => Ok(Literal::Scalar($input.$cast()?)), 91 LiteralType::Signature => { 92 bail!(concat!("Cannot cast a ", stringify!($type_name), " literal to a signature type.")) 93 } 94 LiteralType::String => { 95 bail!(concat!("Cannot cast a ", stringify!($type_name), " literal to a string type.")) 96 } 97 } 98 }; 99 } 100 101 /// Casts a boolean literal to the given literal type. 102 fn cast_boolean_to_type<N: Network>(input: &Boolean<N>, to_type: LiteralType) -> Result<Literal<N>> { 103 impl_cast_body!(boolean, cast, input, to_type) 104 } 105 106 /// Casts a field literal to the given literal type. 107 fn cast_field_to_type<N: Network>(input: &Field<N>, to_type: LiteralType) -> Result<Literal<N>> { 108 impl_cast_body!(field, cast, input, to_type) 109 } 110 111 /// Casts a group literal to the given literal type. 112 fn cast_group_to_type<N: Network>(input: &Group<N>, to_type: LiteralType) -> Result<Literal<N>> { 113 match to_type { 114 LiteralType::Address => Ok(Literal::Address(Address::new(*input))), 115 LiteralType::Group => Ok(Literal::Group(*input)), 116 _ => cast_field_to_type(&input.to_x_coordinate(), to_type), 117 } 118 } 119 120 /// Casts an integer literal to the given literal type. 121 fn cast_integer_to_type<N: Network, I: IntegerType>( 122 input: &integers::Integer<N, I>, 123 to_type: LiteralType, 124 ) -> Result<Literal<N>> 125 where 126 i8: TryFrom<I>, 127 i16: TryFrom<I>, 128 i32: TryFrom<I>, 129 i64: TryFrom<I>, 130 i128: TryFrom<I>, 131 u8: TryFrom<I>, 132 u16: TryFrom<I>, 133 u32: TryFrom<I>, 134 u64: TryFrom<I>, 135 u128: TryFrom<I>, 136 { 137 impl_cast_body!(integer, cast, input, to_type) 138 } 139 140 /// Casts a scalar literal to the given literal type. 141 fn cast_scalar_to_type<N: Network>(input: &Scalar<N>, to_type: LiteralType) -> Result<Literal<N>> { 142 impl_cast_body!(scalar, cast, input, to_type) 143 }