boolean.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<E: Environment> CastLossy<Address<E>> for Boolean<E> { 22 /// Casts a `Boolean` to an `Address`. 23 /// This is safe because casting from a boolean to any other type is **always** lossless. 24 /// 25 /// If the boolean is true, the address is the generator of the prime-order subgroup. 26 /// If the boolean is false, the address is the zero group element. 27 #[inline] 28 fn cast_lossy(&self) -> Address<E> { 29 match **self { 30 true => Address::new(Group::generator()), 31 false => Address::zero(), 32 } 33 } 34 } 35 36 impl<E: Environment> CastLossy<Boolean<E>> for Boolean<E> { 37 /// Casts a `Boolean` to a `Boolean`. 38 /// This is an identity cast, so it is **always** lossless. 39 #[inline] 40 fn cast_lossy(&self) -> Boolean<E> { 41 *self 42 } 43 } 44 45 impl<E: Environment> CastLossy<Field<E>> for Boolean<E> { 46 /// Casts a `Boolean` to a `Field`. 47 /// This is safe because casting from a boolean to any other type is **always** lossless. 48 #[inline] 49 fn cast_lossy(&self) -> Field<E> { 50 match **self { 51 true => Field::one(), 52 false => Field::zero(), 53 } 54 } 55 } 56 57 impl<E: Environment> CastLossy<Group<E>> for Boolean<E> { 58 /// Casts a `Boolean` to a `Group`. 59 /// This is safe because casting from a boolean to any other type is **always** lossless. 60 /// 61 /// If the boolean is true, the group element is the generator of the prime-order subgroup. 62 /// If the boolean is false, the group element is the zero group element. 63 #[inline] 64 fn cast_lossy(&self) -> Group<E> { 65 match **self { 66 true => Group::generator(), 67 false => Group::zero(), 68 } 69 } 70 } 71 72 impl<E: Environment, I: IntegerType> CastLossy<Integer<E, I>> for Boolean<E> { 73 /// Casts a `Boolean` to an `Integer`. 74 #[inline] 75 fn cast_lossy(&self) -> Integer<E, I> { 76 match **self { 77 true => Integer::one(), 78 false => Integer::zero(), 79 } 80 } 81 } 82 83 impl<E: Environment> CastLossy<Scalar<E>> for Boolean<E> { 84 /// Casts a `Boolean` to a `Scalar`. 85 /// This is safe because casting from a boolean to any other type is **always** lossless. 86 #[inline] 87 fn cast_lossy(&self) -> Scalar<E> { 88 match **self { 89 true => Scalar::one(), 90 false => Scalar::zero(), 91 } 92 } 93 } 94 95 #[cfg(test)] 96 mod tests { 97 use super::*; 98 99 type CurrentEnvironment = alphavm_console_network::Console; 100 101 #[test] 102 fn test_boolean_to_address() { 103 let boolean = Boolean::<CurrentEnvironment>::new(true); 104 let address: Address<CurrentEnvironment> = boolean.cast_lossy(); 105 assert_eq!(address, Address::new(Group::generator())); 106 assert_eq!(address.to_group(), &Group::generator()); 107 108 let boolean = Boolean::<CurrentEnvironment>::new(false); 109 let address: Address<CurrentEnvironment> = boolean.cast_lossy(); 110 assert_eq!(address, Address::zero()); 111 assert_eq!(address.to_group(), &Group::zero()); 112 } 113 114 #[test] 115 fn test_boolean_to_boolean() { 116 let boolean = Boolean::<CurrentEnvironment>::new(true); 117 let boolean: Boolean<CurrentEnvironment> = boolean.cast_lossy(); 118 assert_eq!(boolean, Boolean::new(true)); 119 120 let boolean = Boolean::<CurrentEnvironment>::new(false); 121 let boolean: Boolean<CurrentEnvironment> = boolean.cast_lossy(); 122 assert_eq!(boolean, Boolean::new(false)); 123 } 124 125 #[test] 126 fn test_boolean_to_field() { 127 let boolean = Boolean::<CurrentEnvironment>::new(true); 128 let field: Field<CurrentEnvironment> = boolean.cast_lossy(); 129 assert_eq!(field, Field::one()); 130 131 let boolean = Boolean::<CurrentEnvironment>::new(false); 132 let field: Field<CurrentEnvironment> = boolean.cast_lossy(); 133 assert_eq!(field, Field::zero()); 134 } 135 136 #[test] 137 fn test_boolean_to_group() { 138 let boolean = Boolean::<CurrentEnvironment>::new(true); 139 let group: Group<CurrentEnvironment> = boolean.cast_lossy(); 140 assert_eq!(group, Group::generator()); 141 142 let boolean = Boolean::<CurrentEnvironment>::new(false); 143 let group: Group<CurrentEnvironment> = boolean.cast_lossy(); 144 assert_eq!(group, Group::zero()); 145 } 146 147 #[test] 148 fn test_boolean_to_scalar() { 149 let boolean = Boolean::<CurrentEnvironment>::new(true); 150 let scalar: Scalar<CurrentEnvironment> = boolean.cast_lossy(); 151 assert_eq!(scalar, Scalar::one()); 152 153 let boolean = Boolean::<CurrentEnvironment>::new(false); 154 let scalar: Scalar<CurrentEnvironment> = boolean.cast_lossy(); 155 assert_eq!(scalar, Scalar::zero()); 156 } 157 158 macro_rules! check_boolean_to_integer { 159 ($type:ty) => { 160 let boolean = Boolean::<CurrentEnvironment>::new(true); 161 let integer: $type = boolean.cast_lossy(); 162 assert_eq!(integer, <$type>::one()); 163 164 let boolean = Boolean::<CurrentEnvironment>::new(false); 165 let integer: $type = boolean.cast_lossy(); 166 assert_eq!(integer, <$type>::zero()); 167 }; 168 } 169 170 #[test] 171 fn test_boolean_to_i8() { 172 check_boolean_to_integer!(I8<CurrentEnvironment>); 173 } 174 175 #[test] 176 fn test_boolean_to_i16() { 177 check_boolean_to_integer!(I16<CurrentEnvironment>); 178 } 179 180 #[test] 181 fn test_boolean_to_i32() { 182 check_boolean_to_integer!(I32<CurrentEnvironment>); 183 } 184 185 #[test] 186 fn test_boolean_to_i64() { 187 check_boolean_to_integer!(I64<CurrentEnvironment>); 188 } 189 190 #[test] 191 fn test_boolean_to_i128() { 192 check_boolean_to_integer!(I128<CurrentEnvironment>); 193 } 194 195 #[test] 196 fn test_boolean_to_u8() { 197 check_boolean_to_integer!(U8<CurrentEnvironment>); 198 } 199 200 #[test] 201 fn test_boolean_to_u16() { 202 check_boolean_to_integer!(U16<CurrentEnvironment>); 203 } 204 205 #[test] 206 fn test_boolean_to_u32() { 207 check_boolean_to_integer!(U32<CurrentEnvironment>); 208 } 209 210 #[test] 211 fn test_boolean_to_u64() { 212 check_boolean_to_integer!(U64<CurrentEnvironment>); 213 } 214 215 #[test] 216 fn test_boolean_to_u128() { 217 check_boolean_to_integer!(U128<CurrentEnvironment>); 218 } 219 }