nor.rs
1 // Copyright (c) 2025 ADnet Contributors 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> Nor<Self> for Boolean<E> { 19 type Output = Boolean<E>; 20 21 /// Returns `(NOT a) AND (NOT b)`. 22 fn nor(&self, other: &Self) -> Self::Output { 23 // Constant `self` 24 if self.is_constant() { 25 match self.eject_value() { 26 true => !self.clone(), 27 false => !other.clone(), 28 } 29 } 30 // Constant `other` 31 else if other.is_constant() { 32 match other.eject_value() { 33 true => !other.clone(), 34 false => !self.clone(), 35 } 36 } 37 // Variable NOR Variable 38 else { 39 // Declare a new variable with the expected output as witness. 40 // Note: The constraint below will ensure `output` is either 0 or 1, 41 // assuming `self` and `other` are well-formed (they are either 0 or 1). 42 let output = Boolean( 43 E::new_variable( 44 Mode::Private, 45 match !self.eject_value() & !other.eject_value() { 46 true => E::BaseField::one(), 47 false => E::BaseField::zero(), 48 }, 49 ) 50 .into(), 51 ); 52 53 // Ensure (1 - `self`) * (1 - `other`) = `output` 54 // `output` is `1` iff `self` and `other` are both `0`, otherwise `output` is `0`. 55 E::enforce(|| (E::one() - &self.0, E::one() - &other.0, &output)); 56 57 output 58 } 59 } 60 } 61 62 impl<E: Environment> Metrics<dyn Nor<Boolean<E>, Output = Boolean<E>>> for Boolean<E> { 63 type Case = (Mode, Mode); 64 65 fn count(case: &Self::Case) -> Count { 66 match case.0.is_constant() || case.1.is_constant() { 67 true => Count::is(0, 0, 0, 0), 68 false => Count::is(0, 0, 1, 1), 69 } 70 } 71 } 72 73 impl<E: Environment> OutputMode<dyn Nor<Boolean<E>, Output = Boolean<E>>> for Boolean<E> { 74 type Case = (CircuitType<Boolean<E>>, CircuitType<Boolean<E>>); 75 76 fn output_mode(case: &Self::Case) -> Mode { 77 match (case.0.mode(), case.1.mode()) { 78 (Mode::Constant, Mode::Constant) => Mode::Constant, 79 (_, Mode::Constant) => match &case.1 { 80 CircuitType::Constant(constant) => match constant.eject_value() { 81 true => Mode::Constant, 82 false => Mode::Private, 83 }, 84 _ => E::halt("The constant is required to determine the output mode of Public NOR Constant"), 85 }, 86 (Mode::Constant, _) => match &case.0 { 87 CircuitType::Constant(constant) => match constant.eject_value() { 88 true => Mode::Constant, 89 false => Mode::Private, 90 }, 91 _ => E::halt("The constant is required to determine the output mode of Constant NOR Public"), 92 }, 93 (_, _) => Mode::Private, 94 } 95 } 96 } 97 98 #[cfg(test)] 99 mod tests { 100 use super::*; 101 use alphavm_circuit_environment::Circuit; 102 103 fn check_nor(name: &str, expected: bool, a: Boolean<Circuit>, b: Boolean<Circuit>) { 104 Circuit::scope(name, || { 105 let candidate = a.nor(&b); 106 assert_eq!(expected, candidate.eject_value(), "({} NOR {})", a.eject_value(), b.eject_value()); 107 assert_count!(Nor(Boolean, Boolean) => Boolean, &(a.eject_mode(), b.eject_mode())); 108 assert_output_mode!(Nor(Boolean, Boolean) => Boolean, &(CircuitType::from(&a), CircuitType::from(&b)), candidate); 109 }); 110 Circuit::reset(); 111 } 112 113 #[test] 114 fn test_constant_nor_constant() { 115 // false NOR false 116 let expected = true; 117 let a = Boolean::<Circuit>::new(Mode::Constant, false); 118 let b = Boolean::<Circuit>::new(Mode::Constant, false); 119 check_nor("false NOR false", expected, a, b); 120 121 // false NOR true 122 let expected = false; 123 let a = Boolean::<Circuit>::new(Mode::Constant, false); 124 let b = Boolean::<Circuit>::new(Mode::Constant, true); 125 check_nor("false NOR true", expected, a, b); 126 127 // true NOR false 128 let expected = false; 129 let a = Boolean::<Circuit>::new(Mode::Constant, true); 130 let b = Boolean::<Circuit>::new(Mode::Constant, false); 131 check_nor("true NOR false", expected, a, b); 132 133 // true NOR true 134 let expected = false; 135 let a = Boolean::<Circuit>::new(Mode::Constant, true); 136 let b = Boolean::<Circuit>::new(Mode::Constant, true); 137 check_nor("true NOR true", expected, a, b); 138 } 139 140 #[test] 141 fn test_constant_nor_public() { 142 // false NOR false 143 let expected = true; 144 let a = Boolean::<Circuit>::new(Mode::Constant, false); 145 let b = Boolean::<Circuit>::new(Mode::Public, false); 146 check_nor("false NOR false", expected, a, b); 147 148 // false NOR true 149 let expected = false; 150 let a = Boolean::<Circuit>::new(Mode::Constant, false); 151 let b = Boolean::<Circuit>::new(Mode::Public, true); 152 check_nor("false NOR true", expected, a, b); 153 154 // true NOR false 155 let expected = false; 156 let a = Boolean::<Circuit>::new(Mode::Constant, true); 157 let b = Boolean::<Circuit>::new(Mode::Public, false); 158 check_nor("true NOR false", expected, a, b); 159 160 // true NOR true 161 let expected = false; 162 let a = Boolean::<Circuit>::new(Mode::Constant, true); 163 let b = Boolean::<Circuit>::new(Mode::Public, true); 164 check_nor("true NOR true", expected, a, b); 165 } 166 167 #[test] 168 fn test_constant_nor_private() { 169 // false NOR false 170 let expected = true; 171 let a = Boolean::<Circuit>::new(Mode::Constant, false); 172 let b = Boolean::<Circuit>::new(Mode::Private, false); 173 check_nor("false NOR false", expected, a, b); 174 175 // false NOR true 176 let expected = false; 177 let a = Boolean::<Circuit>::new(Mode::Constant, false); 178 let b = Boolean::<Circuit>::new(Mode::Private, true); 179 check_nor("false NOR true", expected, a, b); 180 181 // true NOR false 182 let expected = false; 183 let a = Boolean::<Circuit>::new(Mode::Constant, true); 184 let b = Boolean::<Circuit>::new(Mode::Private, false); 185 check_nor("true NOR false", expected, a, b); 186 187 // true NOR true 188 let expected = false; 189 let a = Boolean::<Circuit>::new(Mode::Constant, true); 190 let b = Boolean::<Circuit>::new(Mode::Private, true); 191 check_nor("true NOR true", expected, a, b); 192 } 193 194 #[test] 195 fn test_public_nor_constant() { 196 // false NOR false 197 let expected = true; 198 let a = Boolean::<Circuit>::new(Mode::Public, false); 199 let b = Boolean::<Circuit>::new(Mode::Constant, false); 200 check_nor("false NOR false", expected, a, b); 201 202 // false NOR true 203 let expected = false; 204 let a = Boolean::<Circuit>::new(Mode::Public, false); 205 let b = Boolean::<Circuit>::new(Mode::Constant, true); 206 check_nor("false NOR true", expected, a, b); 207 208 // true NOR false 209 let expected = false; 210 let a = Boolean::<Circuit>::new(Mode::Public, true); 211 let b = Boolean::<Circuit>::new(Mode::Constant, false); 212 check_nor("true NOR false", expected, a, b); 213 214 // true NOR true 215 let expected = false; 216 let a = Boolean::<Circuit>::new(Mode::Public, true); 217 let b = Boolean::<Circuit>::new(Mode::Constant, true); 218 check_nor("true NOR true", expected, a, b); 219 } 220 221 #[test] 222 fn test_public_nor_public() { 223 // false NOR false 224 let expected = true; 225 let a = Boolean::<Circuit>::new(Mode::Public, false); 226 let b = Boolean::<Circuit>::new(Mode::Public, false); 227 check_nor("false NOR false", expected, a, b); 228 229 // false NOR true 230 let expected = false; 231 let a = Boolean::<Circuit>::new(Mode::Public, false); 232 let b = Boolean::<Circuit>::new(Mode::Public, true); 233 check_nor("false NOR true", expected, a, b); 234 235 // true NOR false 236 let expected = false; 237 let a = Boolean::<Circuit>::new(Mode::Public, true); 238 let b = Boolean::<Circuit>::new(Mode::Public, false); 239 check_nor("true NOR false", expected, a, b); 240 241 // true NOR true 242 let expected = false; 243 let a = Boolean::<Circuit>::new(Mode::Public, true); 244 let b = Boolean::<Circuit>::new(Mode::Public, true); 245 check_nor("true NOR true", expected, a, b); 246 } 247 248 #[test] 249 fn test_public_nor_private() { 250 // false NOR false 251 let expected = true; 252 let a = Boolean::<Circuit>::new(Mode::Public, false); 253 let b = Boolean::<Circuit>::new(Mode::Private, false); 254 check_nor("false NOR false", expected, a, b); 255 256 // false NOR true 257 let expected = false; 258 let a = Boolean::<Circuit>::new(Mode::Public, false); 259 let b = Boolean::<Circuit>::new(Mode::Private, true); 260 check_nor("false NOR true", expected, a, b); 261 262 // true NOR false 263 let expected = false; 264 let a = Boolean::<Circuit>::new(Mode::Public, true); 265 let b = Boolean::<Circuit>::new(Mode::Private, false); 266 check_nor("true NOR false", expected, a, b); 267 268 // true NOR true 269 let expected = false; 270 let a = Boolean::<Circuit>::new(Mode::Public, true); 271 let b = Boolean::<Circuit>::new(Mode::Private, true); 272 check_nor("true NOR true", expected, a, b); 273 } 274 275 #[test] 276 fn test_private_nor_constant() { 277 // false NOR false 278 let expected = true; 279 let a = Boolean::<Circuit>::new(Mode::Private, false); 280 let b = Boolean::<Circuit>::new(Mode::Constant, false); 281 check_nor("false NOR false", expected, a, b); 282 283 // false NOR true 284 let expected = false; 285 let a = Boolean::<Circuit>::new(Mode::Private, false); 286 let b = Boolean::<Circuit>::new(Mode::Constant, true); 287 check_nor("false NOR true", expected, a, b); 288 289 // true NOR false 290 let expected = false; 291 let a = Boolean::<Circuit>::new(Mode::Private, true); 292 let b = Boolean::<Circuit>::new(Mode::Constant, false); 293 check_nor("true NOR false", expected, a, b); 294 295 // true NOR true 296 let expected = false; 297 let a = Boolean::<Circuit>::new(Mode::Private, true); 298 let b = Boolean::<Circuit>::new(Mode::Constant, true); 299 check_nor("true NOR true", expected, a, b); 300 } 301 302 #[test] 303 fn test_private_nor_public() { 304 // false NOR false 305 let expected = true; 306 let a = Boolean::<Circuit>::new(Mode::Private, false); 307 let b = Boolean::<Circuit>::new(Mode::Public, false); 308 check_nor("false NOR false", expected, a, b); 309 310 // false NOR true 311 let expected = false; 312 let a = Boolean::<Circuit>::new(Mode::Private, false); 313 let b = Boolean::<Circuit>::new(Mode::Public, true); 314 check_nor("false NOR true", expected, a, b); 315 316 // true NOR false 317 let expected = false; 318 let a = Boolean::<Circuit>::new(Mode::Private, true); 319 let b = Boolean::<Circuit>::new(Mode::Public, false); 320 check_nor("true NOR false", expected, a, b); 321 322 // true NOR true 323 let expected = false; 324 let a = Boolean::<Circuit>::new(Mode::Private, true); 325 let b = Boolean::<Circuit>::new(Mode::Public, true); 326 check_nor("true NOR true", expected, a, b); 327 } 328 329 #[test] 330 fn test_private_nor_private() { 331 // false NOR false 332 let expected = true; 333 let a = Boolean::<Circuit>::new(Mode::Private, false); 334 let b = Boolean::<Circuit>::new(Mode::Private, false); 335 check_nor("false NOR false", expected, a, b); 336 337 // false NOR true 338 let expected = false; 339 let a = Boolean::<Circuit>::new(Mode::Private, false); 340 let b = Boolean::<Circuit>::new(Mode::Private, true); 341 check_nor("false NOR true", expected, a, b); 342 343 // true NOR false 344 let expected = false; 345 let a = Boolean::<Circuit>::new(Mode::Private, true); 346 let b = Boolean::<Circuit>::new(Mode::Private, false); 347 check_nor("true NOR false", expected, a, b); 348 349 // true NOR true 350 let expected = false; 351 let a = Boolean::<Circuit>::new(Mode::Private, true); 352 let b = Boolean::<Circuit>::new(Mode::Private, true); 353 check_nor("true NOR true", expected, a, b); 354 } 355 }