/ console / program / src / data / literal / cast_lossy / boolean.rs
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  }