or.rs
1 // Copyright (c) 2019-2025 Alpha-Delta Network Inc. 2 // This file is part of the alphavm library. 3 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at: 7 8 // http://www.apache.org/licenses/LICENSE-2.0 9 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 use super::*; 17 18 impl<E: Environment> BitOr<Boolean<E>> for Boolean<E> { 19 type Output = Boolean<E>; 20 21 /// Returns `(self OR other)`. 22 fn bitor(self, other: Boolean<E>) -> Self::Output { 23 self | &other 24 } 25 } 26 27 impl<E: Environment> BitOr<Boolean<E>> for &Boolean<E> { 28 type Output = Boolean<E>; 29 30 /// Returns `(self OR other)`. 31 fn bitor(self, other: Boolean<E>) -> Self::Output { 32 self | &other 33 } 34 } 35 36 impl<E: Environment> BitOr<&Boolean<E>> for Boolean<E> { 37 type Output = Boolean<E>; 38 39 /// Returns `(self OR other)`. 40 fn bitor(self, other: &Boolean<E>) -> Self::Output { 41 &self | other 42 } 43 } 44 45 impl<E: Environment> BitOr<&Boolean<E>> for &Boolean<E> { 46 type Output = Boolean<E>; 47 48 /// Returns `(self OR other)`. 49 fn bitor(self, other: &Boolean<E>) -> Self::Output { 50 let mut output = self.clone(); 51 output |= other; 52 output 53 } 54 } 55 56 impl<E: Environment> BitOrAssign<Boolean<E>> for Boolean<E> { 57 /// Sets `self` as `(self OR other)`. 58 fn bitor_assign(&mut self, other: Boolean<E>) { 59 *self |= &other; 60 } 61 } 62 63 #[allow(clippy::suspicious_op_assign_impl)] 64 impl<E: Environment> BitOrAssign<&Boolean<E>> for Boolean<E> { 65 /// Sets `self` as `(self OR other)`. 66 fn bitor_assign(&mut self, other: &Boolean<E>) { 67 // Stores the bitwise OR of `self` and `other` in `self`. 68 *self = 69 // Constant `self` 70 if self.is_constant() { 71 match self.eject_value() { 72 true => self.clone(), 73 false => other.clone(), 74 } 75 } 76 // Constant `other` 77 else if other.is_constant() { 78 match other.eject_value() { 79 true => other.clone(), 80 false => self.clone(), 81 } 82 } 83 // Variable OR Variable 84 else { 85 // Declare a new variable with the expected output as witness. 86 // Note: The constraint below will ensure `output` is either 0 or 1, 87 // assuming `self` and `other` are well-formed (they are either 0 or 1). 88 let output = Boolean( 89 E::new_variable(Mode::Private, match self.eject_value() | other.eject_value() { 90 true => E::BaseField::one(), 91 false => E::BaseField::zero(), 92 }) 93 .into(), 94 ); 95 96 // Ensure (1 - `self`) * (1 - `other`) = (1 - `output`) 97 // `output` is `1` iff `self` OR `other` is `1`. 98 E::enforce(|| (E::one() - &self.0, E::one() - &other.0, E::one() - &output.0)); 99 100 output 101 } 102 } 103 } 104 105 #[cfg(test)] 106 mod tests { 107 use super::*; 108 use alphavm_circuit_environment::Circuit; 109 110 fn check_or( 111 name: &str, 112 expected: bool, 113 a: Boolean<Circuit>, 114 b: Boolean<Circuit>, 115 num_constants: u64, 116 num_public: u64, 117 num_private: u64, 118 num_constraints: u64, 119 ) { 120 Circuit::scope(name, || { 121 let candidate = &a | &b; 122 assert_eq!(expected, candidate.eject_value(), "({} OR {})", a.eject_value(), b.eject_value()); 123 assert_scope!(num_constants, num_public, num_private, num_constraints); 124 }); 125 } 126 127 #[test] 128 fn test_constant_or_constant() { 129 // false OR false 130 let expected = false; 131 let a = Boolean::<Circuit>::new(Mode::Constant, false); 132 let b = Boolean::<Circuit>::new(Mode::Constant, false); 133 check_or("false OR false", expected, a, b, 0, 0, 0, 0); 134 135 // false OR true 136 let expected = true; 137 let a = Boolean::<Circuit>::new(Mode::Constant, false); 138 let b = Boolean::<Circuit>::new(Mode::Constant, true); 139 check_or("false OR true", expected, a, b, 0, 0, 0, 0); 140 141 // true OR false 142 let expected = true; 143 let a = Boolean::<Circuit>::new(Mode::Constant, true); 144 let b = Boolean::<Circuit>::new(Mode::Constant, false); 145 check_or("true OR false", expected, a, b, 0, 0, 0, 0); 146 147 // true OR true 148 let expected = true; 149 let a = Boolean::<Circuit>::new(Mode::Constant, true); 150 let b = Boolean::<Circuit>::new(Mode::Constant, true); 151 check_or("true OR true", expected, a, b, 0, 0, 0, 0); 152 } 153 154 #[test] 155 fn test_constant_or_public() { 156 // false OR false 157 let expected = false; 158 let a = Boolean::<Circuit>::new(Mode::Constant, false); 159 let b = Boolean::<Circuit>::new(Mode::Public, false); 160 check_or("false OR false", expected, a, b, 0, 0, 0, 0); 161 162 // false OR true 163 let expected = true; 164 let a = Boolean::<Circuit>::new(Mode::Constant, false); 165 let b = Boolean::<Circuit>::new(Mode::Public, true); 166 check_or("false OR true", expected, a, b, 0, 0, 0, 0); 167 168 // true OR false 169 let expected = true; 170 let a = Boolean::<Circuit>::new(Mode::Constant, true); 171 let b = Boolean::<Circuit>::new(Mode::Public, false); 172 check_or("true OR false", expected, a, b, 0, 0, 0, 0); 173 174 // true OR true 175 let expected = true; 176 let a = Boolean::<Circuit>::new(Mode::Constant, true); 177 let b = Boolean::<Circuit>::new(Mode::Public, true); 178 check_or("true OR true", expected, a, b, 0, 0, 0, 0); 179 } 180 181 #[test] 182 fn test_constant_or_private() { 183 // false OR false 184 let expected = false; 185 let a = Boolean::<Circuit>::new(Mode::Constant, false); 186 let b = Boolean::<Circuit>::new(Mode::Private, false); 187 check_or("false OR false", expected, a, b, 0, 0, 0, 0); 188 189 // false OR true 190 let expected = true; 191 let a = Boolean::<Circuit>::new(Mode::Constant, false); 192 let b = Boolean::<Circuit>::new(Mode::Private, true); 193 check_or("false OR true", expected, a, b, 0, 0, 0, 0); 194 195 // true OR false 196 let expected = true; 197 let a = Boolean::<Circuit>::new(Mode::Constant, true); 198 let b = Boolean::<Circuit>::new(Mode::Private, false); 199 check_or("true OR false", expected, a, b, 0, 0, 0, 0); 200 201 // true OR true 202 let expected = true; 203 let a = Boolean::<Circuit>::new(Mode::Constant, true); 204 let b = Boolean::<Circuit>::new(Mode::Private, true); 205 check_or("true OR true", expected, a, b, 0, 0, 0, 0); 206 } 207 208 #[test] 209 fn test_public_or_constant() { 210 // false OR false 211 let expected = false; 212 let a = Boolean::<Circuit>::new(Mode::Public, false); 213 let b = Boolean::<Circuit>::new(Mode::Constant, false); 214 check_or("false OR false", expected, a, b, 0, 0, 0, 0); 215 216 // false OR true 217 let expected = true; 218 let a = Boolean::<Circuit>::new(Mode::Public, false); 219 let b = Boolean::<Circuit>::new(Mode::Constant, true); 220 check_or("false OR true", expected, a, b, 0, 0, 0, 0); 221 222 // true OR false 223 let expected = true; 224 let a = Boolean::<Circuit>::new(Mode::Public, true); 225 let b = Boolean::<Circuit>::new(Mode::Constant, false); 226 check_or("true OR false", expected, a, b, 0, 0, 0, 0); 227 228 // true OR true 229 let expected = true; 230 let a = Boolean::<Circuit>::new(Mode::Public, true); 231 let b = Boolean::<Circuit>::new(Mode::Constant, true); 232 check_or("true OR true", expected, a, b, 0, 0, 0, 0); 233 } 234 235 #[test] 236 fn test_public_or_public() { 237 // false OR false 238 let expected = false; 239 let a = Boolean::<Circuit>::new(Mode::Public, false); 240 let b = Boolean::<Circuit>::new(Mode::Public, false); 241 check_or("false OR false", expected, a, b, 0, 0, 1, 1); 242 243 // false OR true 244 let expected = true; 245 let a = Boolean::<Circuit>::new(Mode::Public, false); 246 let b = Boolean::<Circuit>::new(Mode::Public, true); 247 check_or("false OR true", expected, a, b, 0, 0, 1, 1); 248 249 // true OR false 250 let expected = true; 251 let a = Boolean::<Circuit>::new(Mode::Public, true); 252 let b = Boolean::<Circuit>::new(Mode::Public, false); 253 check_or("true OR false", expected, a, b, 0, 0, 1, 1); 254 255 // true OR true 256 let expected = true; 257 let a = Boolean::<Circuit>::new(Mode::Public, true); 258 let b = Boolean::<Circuit>::new(Mode::Public, true); 259 check_or("true OR true", expected, a, b, 0, 0, 1, 1); 260 } 261 262 #[test] 263 fn test_public_or_private() { 264 // false OR false 265 let expected = false; 266 let a = Boolean::<Circuit>::new(Mode::Public, false); 267 let b = Boolean::<Circuit>::new(Mode::Private, false); 268 check_or("false OR false", expected, a, b, 0, 0, 1, 1); 269 270 // false OR true 271 let expected = true; 272 let a = Boolean::<Circuit>::new(Mode::Public, false); 273 let b = Boolean::<Circuit>::new(Mode::Private, true); 274 check_or("false OR true", expected, a, b, 0, 0, 1, 1); 275 276 // true OR false 277 let expected = true; 278 let a = Boolean::<Circuit>::new(Mode::Public, true); 279 let b = Boolean::<Circuit>::new(Mode::Private, false); 280 check_or("true OR false", expected, a, b, 0, 0, 1, 1); 281 282 // true OR true 283 let expected = true; 284 let a = Boolean::<Circuit>::new(Mode::Public, true); 285 let b = Boolean::<Circuit>::new(Mode::Private, true); 286 check_or("true OR true", expected, a, b, 0, 0, 1, 1); 287 } 288 289 #[test] 290 fn test_private_or_constant() { 291 // false OR false 292 let expected = false; 293 let a = Boolean::<Circuit>::new(Mode::Private, false); 294 let b = Boolean::<Circuit>::new(Mode::Constant, false); 295 check_or("false OR false", expected, a, b, 0, 0, 0, 0); 296 297 // false OR true 298 let expected = true; 299 let a = Boolean::<Circuit>::new(Mode::Private, false); 300 let b = Boolean::<Circuit>::new(Mode::Constant, true); 301 check_or("false OR true", expected, a, b, 0, 0, 0, 0); 302 303 // true OR false 304 let expected = true; 305 let a = Boolean::<Circuit>::new(Mode::Private, true); 306 let b = Boolean::<Circuit>::new(Mode::Constant, false); 307 check_or("true OR false", expected, a, b, 0, 0, 0, 0); 308 309 // true OR true 310 let expected = true; 311 let a = Boolean::<Circuit>::new(Mode::Private, true); 312 let b = Boolean::<Circuit>::new(Mode::Constant, true); 313 check_or("true OR true", expected, a, b, 0, 0, 0, 0); 314 } 315 316 #[test] 317 fn test_private_or_public() { 318 // false OR false 319 let expected = false; 320 let a = Boolean::<Circuit>::new(Mode::Private, false); 321 let b = Boolean::<Circuit>::new(Mode::Public, false); 322 check_or("false OR false", expected, a, b, 0, 0, 1, 1); 323 324 // false OR true 325 let expected = true; 326 let a = Boolean::<Circuit>::new(Mode::Private, false); 327 let b = Boolean::<Circuit>::new(Mode::Public, true); 328 check_or("false OR true", expected, a, b, 0, 0, 1, 1); 329 330 // true OR false 331 let expected = true; 332 let a = Boolean::<Circuit>::new(Mode::Private, true); 333 let b = Boolean::<Circuit>::new(Mode::Public, false); 334 check_or("true OR false", expected, a, b, 0, 0, 1, 1); 335 336 // true OR true 337 let expected = true; 338 let a = Boolean::<Circuit>::new(Mode::Private, true); 339 let b = Boolean::<Circuit>::new(Mode::Public, true); 340 check_or("true OR true", expected, a, b, 0, 0, 1, 1); 341 } 342 343 #[test] 344 fn test_private_or_private() { 345 // false OR false 346 let expected = false; 347 let a = Boolean::<Circuit>::new(Mode::Private, false); 348 let b = Boolean::<Circuit>::new(Mode::Private, false); 349 check_or("false OR false", expected, a, b, 0, 0, 1, 1); 350 351 // false OR true 352 let expected = true; 353 let a = Boolean::<Circuit>::new(Mode::Private, false); 354 let b = Boolean::<Circuit>::new(Mode::Private, true); 355 check_or("false OR true", expected, a, b, 0, 0, 1, 1); 356 357 // true OR false 358 let expected = true; 359 let a = Boolean::<Circuit>::new(Mode::Private, true); 360 let b = Boolean::<Circuit>::new(Mode::Private, false); 361 check_or("true OR false", expected, a, b, 0, 0, 1, 1); 362 363 // true OR true 364 let expected = true; 365 let a = Boolean::<Circuit>::new(Mode::Private, true); 366 let b = Boolean::<Circuit>::new(Mode::Private, true); 367 check_or("true OR true", expected, a, b, 0, 0, 1, 1); 368 } 369 }