1#![doc = include_str!("../README.md")]
4#![forbid(unsafe_code, unused_must_use)]
5#![forbid(
6 missing_docs,
7 unreachable_pub,
8 unused_import_braces,
9 unused_extern_crates
10)]
11
12pub mod affine_equivalence_classes;
13mod anf_polynom;
14mod big_boolean_function;
15mod boolean_function_error;
16mod iterator;
17mod small_boolean_function;
18mod utils;
19
20pub use crate::anf_polynom::AnfPolynomial;
21use crate::boolean_function_error::{AND_DIFFERENT_VAR_COUNT_PANIC_MSG, XOR_DIFFERENT_VAR_COUNT_PANIC_MSG};
22pub use crate::iterator::BooleanFunctionIterator;
23use crate::BooleanFunctionError::{
24 StringHexParseError, UnexpectedError, WrongStringHexTruthTableLength,
25};
26pub use big_boolean_function::BigBooleanFunction;
27pub use boolean_function_error::BooleanFunctionError;
28use enum_dispatch::enum_dispatch;
29use gen_combinations::CombinationIterator;
30use num_bigint::BigUint;
31use num_traits::{Num, ToPrimitive};
32pub use small_boolean_function::SmallBooleanFunction;
33use std::collections::{HashMap, HashSet};
34use std::fmt::Debug;
35use std::ops::{Add, AddAssign, BitAnd, BitAndAssign, BitXor, BitXorAssign, Mul, MulAssign, Not};
36use hackfn::hackfn;
37use crate::iterator::CloseBalancedFunctionIterator;
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq)]
41pub enum BooleanFunctionType {
42 Small,
44 Big,
46}
47
48#[enum_dispatch]
53pub trait BooleanFunctionImpl: Debug {
54 fn variables_count(&self) -> usize;
56
57 fn get_boolean_function_type(&self) -> BooleanFunctionType;
63
64 fn get_max_input_value(&self) -> u32 {
68 (1 << self.variables_count()) - 1
69 }
70
71 fn is_balanced(&self) -> bool;
73
74 fn compute_cellular_automata_rule(&self, input_bits: u32) -> bool;
97
98 fn walsh_hadamard_transform(&self, w: u32) -> i32 {
115 let max_input_value = self.get_max_input_value();
116 #[cfg(not(feature = "unsafe_disable_safety_checks"))]
117 if w > max_input_value {
118 panic!(
119 "Too big Walsh parameter point, must be <= {}",
120 max_input_value
121 );
122 }
123 (0..=max_input_value)
124 .map(|x| {
125 if (self.compute_cellular_automata_rule(x) as u32
126 + utils::fast_binary_dot_product(w, x))
127 & 1
128 == 0
129 {
130 1
132 } else {
133 -1
134 }
135 })
136 .sum()
137 }
138
139 fn walsh_hadamard_values(&self) -> Vec<i32> {
144 (0..=self.get_max_input_value())
145 .map(|w| self.walsh_hadamard_transform(w))
146 .collect()
147 }
148
149 fn absolute_walsh_hadamard_spectrum(&self) -> HashMap<u32, usize> {
156 let mut absolute_walsh_value_count_map: HashMap<u32, usize> = HashMap::new();
157 (0..=self.get_max_input_value()).for_each(|w| {
158 let absolute_walsh_value = self.walsh_hadamard_transform(w).unsigned_abs();
159 if !absolute_walsh_value_count_map.contains_key(&absolute_walsh_value) {
160 absolute_walsh_value_count_map.insert(absolute_walsh_value, 1);
161 } else {
162 let count = absolute_walsh_value_count_map
163 .get_mut(&absolute_walsh_value)
164 .unwrap();
165 *count += 1;
166 }
167 });
168 absolute_walsh_value_count_map
169 }
170
171 fn walsh_fourier_transform(&self, w: u32) -> i32 {
188 let max_input_value = self.get_max_input_value();
189 #[cfg(not(feature = "unsafe_disable_safety_checks"))]
190 if w > max_input_value {
191 panic!(
192 "Too big Walsh parameter point, must be <= {}",
193 max_input_value
194 );
195 }
196 (0..=max_input_value)
197 .map(|x| {
198 if !self.compute_cellular_automata_rule(x) {
199 0
200 } else {
201 if utils::fast_binary_dot_product(w, x) & 1 == 0 {
202 1
203 } else {
204 -1
205 }
206 }
207 })
208 .sum()
209 }
210
211 fn walsh_fourier_values(&self) -> Vec<i32> {
216 (0..=self.get_max_input_value())
217 .map(|w| self.walsh_fourier_transform(w))
218 .collect()
219 }
220
221 fn auto_correlation_transform(&self, w: u32) -> i32 {
237 let max_input_value = self.get_max_input_value();
238 #[cfg(not(feature = "unsafe_disable_safety_checks"))]
239 if w > max_input_value {
240 panic!(
241 "Too big auto-correlation parameter point, must be <= {}",
242 max_input_value
243 );
244 }
245 (0..=max_input_value)
246 .map(|x| {
247 if self.compute_cellular_automata_rule(x)
248 ^ self.compute_cellular_automata_rule(x ^ w)
249 {
250 -1
251 } else {
252 1
253 }
254 })
255 .sum()
256 }
257
258 fn absolute_autocorrelation(&self) -> HashMap<u32, usize> {
265 let mut absolute_autocorrelation_value_count_map: HashMap<u32, usize> = HashMap::new();
266 (0..=self.get_max_input_value()).for_each(|w| {
267 let absolute_autocorrelation_value = self.auto_correlation_transform(w).unsigned_abs();
268 if !absolute_autocorrelation_value_count_map
269 .contains_key(&absolute_autocorrelation_value)
270 {
271 absolute_autocorrelation_value_count_map.insert(absolute_autocorrelation_value, 1);
272 } else {
273 let count = absolute_autocorrelation_value_count_map
274 .get_mut(&absolute_autocorrelation_value)
275 .unwrap();
276 *count += 1;
277 }
278 });
279 absolute_autocorrelation_value_count_map
280 }
281
282 fn absolute_indicator(&self) -> u32 {
288 (1..=self.get_max_input_value())
289 .map(|w| self.auto_correlation_transform(w).unsigned_abs())
290 .max()
291 .unwrap_or(0)
292 }
293
294 fn derivative(&self, direction: u32) -> Result<BooleanFunction, BooleanFunctionError>;
308
309 fn is_linear(&self) -> bool;
311
312 fn reverse(&self) -> BooleanFunction;
319
320 fn algebraic_normal_form(&self) -> AnfPolynomial;
338
339 fn algebraic_degree(&self) -> usize {
348 self.algebraic_normal_form().get_degree()
349 }
350
351 fn is_symmetric(&self) -> bool {
357 let variables_count = self.variables_count() as u32;
358 let precomputed_hamming_weights = (0..(variables_count + 1))
359 .map(|i| self.compute_cellular_automata_rule(u32::MAX.checked_shr(32 - i).unwrap_or(0)))
360 .collect::<Vec<bool>>();
361
362 (0u32..(1 << variables_count)).all(|i| {
363 precomputed_hamming_weights[i.count_ones() as usize]
364 == self.compute_cellular_automata_rule(i)
365 })
366 }
367
368 fn nonlinearity(&self) -> u32 {
376 ((1 << self.variables_count())
377 - (0..=self.get_max_input_value())
378 .map(|x| self.walsh_hadamard_transform(x).unsigned_abs())
379 .max()
380 .unwrap_or(0))
381 >> 1
382 }
383
384 fn is_bent(&self) -> bool {
396 if self.variables_count() & 1 != 0 {
397 return false;
398 }
399 self.nonlinearity()
400 == ((1 << self.variables_count()) - (1 << (self.variables_count() >> 1))) >> 1
401 }
402
403 fn is_near_bent(&self) -> bool {
408 if self.variables_count() & 1 == 0 {
409 return false;
410 }
411 let absolute_walsh_allowed_value = 1 << ((self.variables_count() + 1) >> 1);
412 let walsh_hadamard_spectrum = (0..=self.get_max_input_value())
413 .map(|x| self.walsh_hadamard_transform(x))
414 .collect::<HashSet<_>>();
415
416 walsh_hadamard_spectrum.len() == 3 && walsh_hadamard_spectrum.iter().all(|w| {
417 *w == 0 || *w == absolute_walsh_allowed_value || *w == -absolute_walsh_allowed_value
418 })
419 }
420
421 fn annihilator(&self, max_degree: Option<usize>) -> Option<(BooleanFunction, usize, usize)>;
439
440 fn algebraic_immunity(&self) -> usize {
447 match self.annihilator(Some(self.variables_count())) {
448 None => 0,
449 Some(annihilator) => annihilator.1,
450 }
451 }
452
453 fn is_plateaued(&self) -> bool {
457 let absolute_walsh_hadamard_spectrum = self.absolute_walsh_hadamard_spectrum();
458 absolute_walsh_hadamard_spectrum.len() == 1
459 || (absolute_walsh_hadamard_spectrum.len() == 2
460 && absolute_walsh_hadamard_spectrum.contains_key(&0))
461 }
462
463 fn sum_of_square_indicator(&self) -> usize {
474 (0..=self.get_max_input_value())
475 .map(|w| self.auto_correlation_transform(w))
476 .map(|value| (value as i64 * value as i64) as usize)
477 .sum()
478 }
479
480 fn has_linear_structure(&self) -> bool {
487 (1..=self.get_max_input_value()).any(|x| {
488 self.auto_correlation_transform(x).unsigned_abs() == 1 << self.variables_count()
489 })
490 }
491
492 fn is_linear_structure(&self, value: u32) -> bool {
506 #[cfg(not(feature = "unsafe_disable_safety_checks"))]
507 {
508 let max_input_value = self.get_max_input_value();
509 if value > max_input_value {
510 panic!("Too big value parameter, must be <= {}", max_input_value);
511 }
512 }
513 self.auto_correlation_transform(value).unsigned_abs() == 1 << self.variables_count()
514 }
515
516 fn linear_structures(&self) -> Vec<u32> {
524 (0..=self.get_max_input_value())
525 .filter(|x| {
526 self.auto_correlation_transform(*x).unsigned_abs() == 1 << self.variables_count()
527 })
528 .collect()
529 }
530
531 fn correlation_immunity(&self) -> usize {
541 (1..=self.get_max_input_value())
542 .filter(|x| self.walsh_hadamard_transform(*x) != 0)
543 .map(|x| x.count_ones() as usize)
544 .min()
545 .unwrap_or(self.variables_count() + 1)
546 - 1
547 }
548
549 fn resiliency_order(&self) -> Option<usize> {
556 if !self.is_balanced() {
557 return None;
558 }
559 Some(self.correlation_immunity())
560 }
561
562 fn support(&self) -> HashSet<u32> {
569 (0..=self.get_max_input_value())
570 .filter(|x| self.compute_cellular_automata_rule(*x))
571 .collect()
572 }
573
574 fn propagation_criterion(&self) -> usize {
582 let num_variables = self.variables_count();
583 let max_input_value = self.get_max_input_value();
584 let possible_reversable_bit_position =
585 (0..num_variables).into_iter().collect::<Vec<usize>>();
586 (1..=num_variables)
587 .into_iter()
588 .take_while(|criterion_degree| {
589 CombinationIterator::new(&possible_reversable_bit_position, *criterion_degree).all(
590 |combination| {
591 let mut bit_mask = 0;
592 for &bit_position in combination {
593 bit_mask |= (1 << bit_position) as u32;
594 }
595 let function_equal_mask_count = (0..=max_input_value)
596 .into_iter()
597 .filter(|&x| {
598 let x_prime = x ^ bit_mask;
599 self.compute_cellular_automata_rule(x)
600 == self.compute_cellular_automata_rule(x_prime)
601 })
602 .count();
603 function_equal_mask_count == (1 << (num_variables - 1))
604 },
605 )
606 })
607 .count()
608 }
609
610 fn get_1_local_neighbor(&self, position: u32) -> BooleanFunction;
630
631 fn iter(&self) -> BooleanFunctionIterator;
647
648 fn printable_hex_truth_table(&self) -> String;
662
663 fn biguint_truth_table(&self) -> BigUint;
668
669 fn try_u64_truth_table(&self) -> Option<u64> {
674 self.biguint_truth_table().to_u64()
675 }
676
677 fn close_balanced_functions_iterator(&self) -> Result<CloseBalancedFunctionIterator, BooleanFunctionError>;
707}
708
709#[enum_dispatch(BooleanFunctionImpl)]
715#[derive(Debug, Clone, PartialEq, Eq)]
716pub enum BooleanFunction {
717 Small(pub SmallBooleanFunction),
719 Big(pub BigBooleanFunction),
721}
722
723impl BitXorAssign for BooleanFunction {
728 fn bitxor_assign(&mut self, rhs: Self) {
729 let self_num_variables = self.variables_count();
730 let rhs_num_variables = rhs.variables_count();
731 if self_num_variables != rhs_num_variables {
732 panic!("{}", XOR_DIFFERENT_VAR_COUNT_PANIC_MSG);
733 }
734 match (
735 self,
736 rhs,
737 ) {
738 (BooleanFunction::Small(self_small_boolean_function), BooleanFunction::Small(rhs_small_boolean_function)) => {
739 *self_small_boolean_function ^= rhs_small_boolean_function;
740 },
741 (BooleanFunction::Small(self_small_boolean_function), BooleanFunction::Big(rhs_big_boolean_function)) => {
742 let rhs_small_boolean_function = SmallBooleanFunction::from_truth_table(
743 rhs_big_boolean_function
744 .biguint_truth_table()
745 .to_u64()
746 .unwrap(),
747 self_num_variables,
748 )
749 .unwrap();
750 *self_small_boolean_function ^= rhs_small_boolean_function;
751 },
752 (BooleanFunction::Big(self_big_boolean_function), BooleanFunction::Small(rhs_small_boolean_function)) => {
753 let rhs_big_boolean_function = BigBooleanFunction::from_truth_table(
754 rhs_small_boolean_function.biguint_truth_table(),
755 rhs_num_variables,
756 );
757 *self_big_boolean_function ^= rhs_big_boolean_function;
758 },
759 (BooleanFunction::Big(self_big_boolean_function), BooleanFunction::Big(rhs_big_boolean_function)) => {
760 *self_big_boolean_function ^= rhs_big_boolean_function;
761 }
762 }
763 }
764}
765
766impl BitXor for BooleanFunction {
771 type Output = Self;
772
773 fn bitxor(mut self, rhs: Self) -> Self::Output {
774 self ^= rhs;
775 self
776 }
777}
778
779impl Add for BooleanFunction {
786 type Output = Self;
787
788 fn add(self, rhs: Self) -> Self::Output {
789 self ^ rhs
790 }
791}
792
793impl AddAssign for BooleanFunction {
800 fn add_assign(&mut self, rhs: Self) {
801 *self ^= rhs;
802 }
803}
804
805impl BitAndAssign for BooleanFunction {
810 fn bitand_assign(&mut self, rhs: Self) {
811 let self_num_variables = self.variables_count();
812 let rhs_num_variables = rhs.variables_count();
813 if self_num_variables != rhs_num_variables {
814 panic!("{}", AND_DIFFERENT_VAR_COUNT_PANIC_MSG);
815 }
816 match (
817 self,
818 rhs,
819 ) {
820 (BooleanFunction::Small(self_small_boolean_function), BooleanFunction::Small(rhs_small_boolean_function)) => {
821 *self_small_boolean_function &= rhs_small_boolean_function;
822 },
823 (BooleanFunction::Small(self_small_boolean_function), BooleanFunction::Big(rhs_big_boolean_function)) => {
824 let rhs_small_boolean_function = SmallBooleanFunction::from_truth_table(
825 rhs_big_boolean_function
826 .biguint_truth_table()
827 .to_u64()
828 .unwrap(),
829 self_num_variables,
830 )
831 .unwrap();
832 *self_small_boolean_function &= rhs_small_boolean_function;
833 },
834 (BooleanFunction::Big(self_big_boolean_function), BooleanFunction::Small(rhs_small_boolean_function)) => {
835 let rhs_big_boolean_function = BigBooleanFunction::from_truth_table(
836 rhs_small_boolean_function.biguint_truth_table(),
837 rhs_num_variables,
838 );
839 *self_big_boolean_function &= rhs_big_boolean_function;
840 },
841 (BooleanFunction::Big(self_big_boolean_function), BooleanFunction::Big(rhs_big_boolean_function)) => {
842 *self_big_boolean_function &= rhs_big_boolean_function;
843 }
844 }
845 }
846}
847
848impl BitAnd for BooleanFunction {
853 type Output = Self;
854
855 fn bitand(mut self, rhs: Self) -> Self::Output {
856 self &= rhs;
857 self
858 }
859}
860
861impl Mul for BooleanFunction {
868 type Output = Self;
869 fn mul(self, rhs: Self) -> Self::Output {
870 self & rhs
871 }
872}
873
874impl MulAssign for BooleanFunction {
881 fn mul_assign(&mut self, rhs: Self) {
882 *self &= rhs;
883 }
884}
885
886impl Not for BooleanFunction {
890 type Output = Self;
891
892 fn not(self) -> Self::Output {
893 self.reverse()
894 }
895}
896
897impl TryFrom<&str> for BooleanFunction {
899 type Error = BooleanFunctionError;
900
901 fn try_from(value: &str) -> Result<Self, Self::Error> {
902 Self::from_hex_string_truth_table(value)
903 }
904}
905
906#[hackfn]
907impl BooleanFunction {
908 fn call(&self, input_bits: u32) -> bool {
909 self.compute_cellular_automata_rule(input_bits)
910 }
911}
912
913impl BooleanFunction {
914 pub fn from_hex_string_truth_table(
932 hex_truth_table: &str,
933 ) -> Result<Self, BooleanFunctionError> {
934 if hex_truth_table.len().count_ones() != 1 {
935 return Err(WrongStringHexTruthTableLength);
936 }
937 let num_variables = (hex_truth_table.len() << 2).trailing_zeros() as usize;
938 if num_variables <= 6 {
939 Ok(SmallBooleanFunction::from_truth_table(
940 u64::from_str_radix(hex_truth_table, 16).map_err(|_| StringHexParseError)?,
941 num_variables,
942 )
943 .map_err(|_| UnexpectedError)?
944 .into())
945 } else {
946 Ok(BigBooleanFunction::from_truth_table(
947 BigUint::from_str_radix(hex_truth_table, 16).map_err(|_| StringHexParseError)?,
948 num_variables,
949 )
950 .into())
951 }
952 }
953
954 pub fn from_reverse_walsh_hadamard_transform(
966 walsh_hadamard_values: &[i32],
967 ) -> Result<Self, BooleanFunctionError> {
968 const MAX_WALSH_VALUES_SMALL: usize = 64; if walsh_hadamard_values.len() > MAX_WALSH_VALUES_SMALL {
970 return Ok(BigBooleanFunction::from_walsh_hadamard_values(walsh_hadamard_values)?.into());
971 }
973 Ok(SmallBooleanFunction::from_walsh_hadamard_values(walsh_hadamard_values)?.into())
974 }
975
976 pub fn from_reverse_walsh_fourier_transform(
988 walsh_fourier_values: &[i32],
989 ) -> Result<Self, BooleanFunctionError> {
990 const MAX_WALSH_VALUES_SMALL: usize = 64; if walsh_fourier_values.len() > MAX_WALSH_VALUES_SMALL {
992 return Ok(BigBooleanFunction::from_walsh_fourier_values(walsh_fourier_values)?.into());
993 }
995 Ok(SmallBooleanFunction::from_walsh_fourier_values(walsh_fourier_values)?.into())
996 }
997
998 pub fn from_u64_truth_table(
1013 truth_table: u64,
1014 num_variables: usize,
1015 ) -> Result<Self, BooleanFunctionError> {
1016 Ok(SmallBooleanFunction::from_truth_table(truth_table, num_variables)?.into())
1017 }
1018
1019 pub fn from_biguint_truth_table(
1034 truth_table: &BigUint,
1035 num_variables: usize,
1036 ) -> Result<Self, BooleanFunctionError> {
1037 #[cfg(not(feature = "unsafe_disable_safety_checks"))]
1038 if truth_table.bits() > (1 << num_variables) {
1039 return Err(BooleanFunctionError::TooBigTruthTableForVarCount);
1040 }
1041 #[cfg(not(feature = "unsafe_disable_safety_checks"))]
1042 if num_variables > 31 {
1043 return Err(BooleanFunctionError::TooBigVariableCount(31));
1044 }
1045 if num_variables <= 6 {
1046 return Ok(SmallBooleanFunction::from_truth_table(
1047 truth_table.to_u64().unwrap(),
1048 num_variables,
1049 )?
1050 .into());
1051 }
1052 Ok(BigBooleanFunction::from_truth_table(truth_table.clone(), num_variables).into())
1053 }
1054
1055 pub fn from_anf_polynomial_str(anf_polynomial: &str, num_variables: usize) -> Result<Self, BooleanFunctionError> {
1076 Ok(AnfPolynomial::from_str(anf_polynomial, num_variables)?.to_boolean_function())
1077 }
1078
1079 pub fn from_anf_polynomial(anf_polynomial: &AnfPolynomial) -> Self {
1087 anf_polynomial.to_boolean_function()
1088 }
1089}
1090
1091#[cfg(test)]
1092mod tests {
1093 use crate::BooleanFunctionError::InvalidWalshValuesCount;
1094 use crate::{AnfPolynomial, BooleanFunction, BooleanFunctionImpl, BooleanFunctionType};
1095 use num_bigint::BigUint;
1096 use num_traits::Num;
1097 use std::collections::HashMap;
1098
1099 #[test]
1100 fn test_boolean_function_from_hex_string_truth_table() {
1101 let boolean_function =
1102 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD");
1103 assert!(boolean_function.is_err());
1104
1105 let boolean_function = BooleanFunction::from_hex_string_truth_table("");
1106 assert!(boolean_function.is_err());
1107
1108 let boolean_function = BooleanFunction::from_hex_string_truth_table("fe1z");
1109 assert!(boolean_function.is_err());
1110
1111 let boolean_function = BooleanFunction::from_hex_string_truth_table("fe12").unwrap();
1112 assert_eq!(boolean_function.variables_count(), 4);
1113
1114 let boolean_function =
1115 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1116 .unwrap();
1117 assert_eq!(boolean_function.variables_count(), 7);
1118 }
1119
1120 #[test]
1121 fn test_variables_count() {
1122 let boolean_function =
1123 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1124 .unwrap();
1125 assert_eq!(boolean_function.variables_count(), 7);
1126
1127 let boolean_function = BooleanFunction::from_hex_string_truth_table("fe12").unwrap();
1128 assert_eq!(boolean_function.variables_count(), 4);
1129 }
1130
1131 #[test]
1132 fn test_get_boolean_function_type() {
1133 let boolean_function =
1134 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1135 .unwrap();
1136 assert_eq!(
1137 boolean_function.get_boolean_function_type(),
1138 BooleanFunctionType::Big
1139 );
1140
1141 let boolean_function =
1142 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6").unwrap();
1143 assert_eq!(
1144 boolean_function.get_boolean_function_type(),
1145 BooleanFunctionType::Small
1146 );
1147 }
1148
1149 #[test]
1150 fn test_get_max_input_value() {
1151 let boolean_function =
1152 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1153 .unwrap();
1154 assert_eq!(boolean_function.get_max_input_value(), 127);
1155
1156 let boolean_function = BooleanFunction::from_hex_string_truth_table("fe12").unwrap();
1157 assert_eq!(boolean_function.get_max_input_value(), 15);
1158 }
1159
1160 #[test]
1161 fn test_is_balanced() {
1162 let boolean_function =
1163 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1164 .unwrap();
1165 assert!(boolean_function.is_balanced());
1166
1167 let boolean_function =
1168 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD1")
1169 .unwrap();
1170 assert!(!boolean_function.is_balanced());
1171
1172 let boolean_function =
1173 BooleanFunction::from_hex_string_truth_table("aa55aa55").unwrap();
1174 assert!(boolean_function.is_balanced());
1175
1176 let boolean_function =
1177 BooleanFunction::from_hex_string_truth_table("abce1234").unwrap();
1178 assert!(!boolean_function.is_balanced());
1179 }
1180
1181 #[test]
1182 fn test_compute_cellular_automata_rule() {
1183 let boolean_function =
1184 BooleanFunction::from_hex_string_truth_table("abce1234").unwrap();
1185 assert_eq!(boolean_function.compute_cellular_automata_rule(0), false);
1186 assert_eq!(boolean_function.compute_cellular_automata_rule(1), false);
1187 assert_eq!(boolean_function.compute_cellular_automata_rule(4), true);
1188 assert_eq!(boolean_function.compute_cellular_automata_rule(8), false);
1189 assert_eq!(boolean_function.compute_cellular_automata_rule(23), true);
1190
1191 assert_eq!(boolean_function(0), false);
1192 assert_eq!(boolean_function(1), false);
1193 assert_eq!(boolean_function(4), true);
1194 assert_eq!(boolean_function(8), false);
1195 assert_eq!(boolean_function(23), true);
1196
1197 let boolean_function =
1198 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1199 .unwrap();
1200 assert_eq!(boolean_function.compute_cellular_automata_rule(13), false);
1201 assert_eq!(boolean_function.compute_cellular_automata_rule(62), false);
1202 assert_eq!(boolean_function.compute_cellular_automata_rule(64), false);
1203 assert_eq!(boolean_function.compute_cellular_automata_rule(80), true);
1204 assert_eq!(boolean_function.compute_cellular_automata_rule(100), true);
1205
1206 assert_eq!(boolean_function(13), false);
1207 assert_eq!(boolean_function(62), false);
1208 assert_eq!(boolean_function(64), false);
1209 assert_eq!(boolean_function(80), true);
1210 assert_eq!(boolean_function(100), true);
1211 }
1212
1213 #[test]
1214 fn test_walsh_hadamard_transform() {
1215 let boolean_function =
1216 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1217 .unwrap();
1218 assert_eq!(boolean_function.walsh_hadamard_transform(0), 0);
1219 assert_eq!(boolean_function.walsh_hadamard_transform(1), 0);
1220 assert_eq!(boolean_function.walsh_hadamard_transform(7), -16);
1221 assert_eq!(boolean_function.walsh_hadamard_transform(15), 16);
1222 assert_eq!(boolean_function.walsh_hadamard_transform(126), 16);
1223 assert_eq!(boolean_function.walsh_hadamard_transform(127), -16);
1224
1225 let boolean_function =
1226 BooleanFunction::from_hex_string_truth_table("aa55aa55").unwrap();
1227 assert_eq!(boolean_function.walsh_hadamard_transform(0), 0);
1228 assert_eq!(boolean_function.walsh_hadamard_transform(1), 0);
1229 assert_eq!(boolean_function.walsh_hadamard_transform(9), -32);
1230 assert_eq!(boolean_function.walsh_hadamard_transform(31), 0);
1231
1232 let boolean_function =
1233 BooleanFunction::from_hex_string_truth_table("abce1234").unwrap();
1234 assert_eq!(boolean_function.walsh_hadamard_transform(0), 2);
1235 assert_eq!(boolean_function.walsh_hadamard_transform(1), 6);
1236 assert_eq!(boolean_function.walsh_hadamard_transform(2), -2);
1237 assert_eq!(boolean_function.walsh_hadamard_transform(31), -6);
1238 }
1239
1240 #[test]
1241 fn test_absolute_walsh_hadamard_spectrum() {
1242 let boolean_function =
1243 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1244 .unwrap();
1245 assert_eq!(
1246 boolean_function.absolute_walsh_hadamard_spectrum(),
1247 HashMap::from([(0, 64), (16, 64)])
1248 );
1249
1250 let boolean_function =
1251 BooleanFunction::from_hex_string_truth_table("abce1234").unwrap();
1252 assert_eq!(
1253 boolean_function.absolute_walsh_hadamard_spectrum(),
1254 HashMap::from([(6, 10), (10, 6), (2, 16)])
1255 );
1256 }
1257
1258 #[test]
1259 fn test_auto_correlation_transform() {
1260 let boolean_function =
1261 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1262 .unwrap();
1263 assert_eq!(boolean_function.auto_correlation_transform(0), 128);
1264 assert_eq!(boolean_function.auto_correlation_transform(1), -24);
1265 assert_eq!(boolean_function.auto_correlation_transform(126), -8);
1266 assert_eq!(boolean_function.auto_correlation_transform(127), -32);
1267
1268 let boolean_function = BooleanFunction::from_hex_string_truth_table("03").unwrap();
1269 assert_eq!(boolean_function.auto_correlation_transform(0), 8);
1270 assert_eq!(boolean_function.auto_correlation_transform(1), 8);
1271 assert_eq!(boolean_function.auto_correlation_transform(2), 0);
1272 assert_eq!(boolean_function.auto_correlation_transform(3), 0);
1273 assert_eq!(boolean_function.auto_correlation_transform(4), 0);
1274 assert_eq!(boolean_function.auto_correlation_transform(5), 0);
1275 assert_eq!(boolean_function.auto_correlation_transform(6), 0);
1276 assert_eq!(boolean_function.auto_correlation_transform(7), 0);
1277 }
1278
1279 #[test]
1280 fn test_absolute_autocorrelation_spectrum() {
1281 let boolean_function =
1282 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1283 .unwrap();
1284 assert_eq!(
1285 boolean_function.absolute_autocorrelation(),
1286 HashMap::from([(0, 33), (8, 58), (16, 28), (24, 6), (32, 2), (128, 1)])
1287 );
1288
1289 let boolean_function =
1290 BooleanFunction::from_hex_string_truth_table("abce1234").unwrap();
1291 assert_eq!(
1292 boolean_function.absolute_autocorrelation(),
1293 HashMap::from([(4, 25), (12, 6), (32, 1)])
1294 );
1295 }
1296
1297 #[test]
1298 fn test_derivative() {
1299 let boolean_function =
1300 BooleanFunction::from_hex_string_truth_table("aa55aa55").unwrap();
1301 let derivative = boolean_function.derivative(1).unwrap();
1302 assert_eq!(derivative.variables_count(), 5);
1303 assert_eq!(derivative.printable_hex_truth_table(), "ffffffff");
1304
1305 let boolean_function =
1306 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1307 .unwrap();
1308 let derivative = boolean_function.derivative(1).unwrap();
1309 assert_eq!(derivative.variables_count(), 7);
1310 assert_eq!(
1311 derivative.printable_hex_truth_table(),
1312 "cfffc3c00fcf0cfff003f3ccf3f0ff30"
1313 );
1314 }
1315
1316 #[test]
1317 fn test_algebraic_normal_form() {
1318 let boolean_function =
1319 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1320 .unwrap();
1321 assert_eq!(boolean_function.algebraic_normal_form().to_string(), "x0*x1*x2*x3 + x0*x1*x2*x4 + x0*x1*x3*x4 + x1*x2*x3*x4 + x0*x1*x2*x5 + x0*x2*x3*x5 + x1*x2*x3*x5 + x0*x2*x4*x5 + x1*x2*x4*x5 + x1*x3*x4*x5 + x2*x3*x4*x5 + x0*x1*x2*x6 + x0*x1*x3*x6 + x0*x2*x3*x6 + x1*x2*x3*x6 + x0*x2*x4*x6 + x1*x2*x4*x6 + x0*x3*x4*x6 + x2*x3*x4*x6 + x0*x1*x5*x6 + x0*x2*x5*x6 + x1*x2*x5*x6 + x1*x3*x5*x6 + x2*x3*x5*x6 + x3*x4*x5*x6 + x0*x1*x2 + x0*x2*x3 + x1*x2*x4 + x1*x3*x4 + x2*x3*x4 + x0*x1*x5 + x0*x2*x5 + x1*x2*x5 + x1*x3*x5 + x2*x3*x5 + x0*x4*x5 + x2*x4*x5 + x3*x4*x5 + x0*x2*x6 + x1*x2*x6 + x3*x4*x6 + x0*x5*x6 + x2*x5*x6 + x3*x5*x6 + x0*x2 + x0*x3 + x2*x4 + x3*x5 + x0*x6 + x1*x6 + x2*x6 + x3*x6 + x5*x6 + x2 + x4 + x5");
1322
1323 let boolean_function =
1324 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD1")
1325 .unwrap();
1326 assert_eq!(boolean_function.algebraic_normal_form().to_string(), "x0*x1*x2*x3*x4*x5*x6 + x0*x1*x2*x3*x4*x5 + x0*x1*x2*x3*x4*x6 + x0*x1*x2*x3*x5*x6 + x0*x1*x2*x4*x5*x6 + x0*x1*x3*x4*x5*x6 + x0*x2*x3*x4*x5*x6 + x1*x2*x3*x4*x5*x6 + x0*x1*x2*x3*x4 + x0*x1*x2*x3*x5 + x0*x1*x2*x4*x5 + x0*x1*x3*x4*x5 + x0*x2*x3*x4*x5 + x1*x2*x3*x4*x5 + x0*x1*x2*x3*x6 + x0*x1*x2*x4*x6 + x0*x1*x3*x4*x6 + x0*x2*x3*x4*x6 + x1*x2*x3*x4*x6 + x0*x1*x2*x5*x6 + x0*x1*x3*x5*x6 + x0*x2*x3*x5*x6 + x1*x2*x3*x5*x6 + x0*x1*x4*x5*x6 + x0*x2*x4*x5*x6 + x1*x2*x4*x5*x6 + x0*x3*x4*x5*x6 + x1*x3*x4*x5*x6 + x2*x3*x4*x5*x6 + x0*x2*x3*x4 + x0*x1*x3*x5 + x0*x1*x4*x5 + x0*x3*x4*x5 + x0*x1*x4*x6 + x1*x3*x4*x6 + x0*x3*x5*x6 + x0*x4*x5*x6 + x1*x4*x5*x6 + x2*x4*x5*x6 + x0*x1*x3 + x1*x2*x3 + x0*x1*x4 + x0*x2*x4 + x0*x3*x4 + x0*x3*x5 + x1*x4*x5 + x0*x1*x6 + x0*x3*x6 + x1*x3*x6 + x2*x3*x6 + x0*x4*x6 + x1*x4*x6 + x2*x4*x6 + x1*x5*x6 + x4*x5*x6 + x0*x1 + x1*x2 + x1*x3 + x2*x3 + x0*x4 + x1*x4 + x3*x4 + x0*x5 + x1*x5 + x2*x5 + x4*x5 + x4*x6 + x0 + x1 + x3 + x6 + 1");
1327
1328 let boolean_function = BooleanFunction::from_hex_string_truth_table("1e").unwrap();
1329 assert_eq!(
1330 boolean_function.algebraic_normal_form().to_string(),
1331 "x0*x1 + x0 + x1 + x2"
1332 );
1333
1334 let boolean_function = BooleanFunction::from_hex_string_truth_table("00").unwrap();
1335 assert_eq!(boolean_function.algebraic_normal_form().to_string(), "0");
1336
1337 let boolean_function = BooleanFunction::from_hex_string_truth_table("ff").unwrap();
1338 assert_eq!(boolean_function.algebraic_normal_form().to_string(), "1");
1339
1340 let boolean_function = BooleanFunction::from_hex_string_truth_table("6e").unwrap();
1341 assert_eq!(
1342 boolean_function.algebraic_normal_form().to_string(),
1343 "x0*x1*x2 + x0*x1 + x0 + x1"
1344 );
1345
1346 let boolean_function = BooleanFunction::from_hex_string_truth_table("7b").unwrap();
1347 assert_eq!(
1348 boolean_function.algebraic_normal_form().to_string(),
1349 "x0*x1 + x1*x2 + x1 + 1"
1350 );
1351 }
1352
1353 #[test]
1354 fn test_algebraic_degree() {
1355 let boolean_function =
1356 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1357 .unwrap();
1358 assert_eq!(boolean_function.algebraic_degree(), 4);
1359
1360 let boolean_function =
1361 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD1")
1362 .unwrap();
1363 assert_eq!(boolean_function.algebraic_degree(), 7);
1364
1365 let boolean_function =
1366 BooleanFunction::from_hex_string_truth_table("00000000000000000000000000000000")
1367 .unwrap();
1368 assert_eq!(boolean_function.algebraic_degree(), 0);
1369
1370 let boolean_function =
1371 BooleanFunction::from_hex_string_truth_table("ffffffffffffffffffffffffffffffff")
1372 .unwrap();
1373 assert_eq!(boolean_function.algebraic_degree(), 0);
1374
1375 let boolean_function = BooleanFunction::from_hex_string_truth_table("1e").unwrap();
1376 assert_eq!(boolean_function.algebraic_degree(), 2);
1377
1378 let boolean_function = BooleanFunction::from_hex_string_truth_table("00").unwrap();
1379 assert_eq!(boolean_function.algebraic_degree(), 0);
1380
1381 let boolean_function = BooleanFunction::from_hex_string_truth_table("0f").unwrap();
1382 assert_eq!(boolean_function.algebraic_degree(), 1);
1383
1384 let boolean_function = BooleanFunction::from_hex_string_truth_table("ff").unwrap();
1385 assert_eq!(boolean_function.algebraic_degree(), 0);
1386
1387 let boolean_function = BooleanFunction::from_hex_string_truth_table("6e").unwrap();
1388 assert_eq!(boolean_function.algebraic_degree(), 3);
1389
1390 let boolean_function = BooleanFunction::from_hex_string_truth_table("7b").unwrap();
1391 assert_eq!(boolean_function.algebraic_degree(), 2);
1392 }
1393
1394 #[test]
1395 fn test_printable_hex_truth_table() {
1396 let boolean_function =
1397 BooleanFunction::from_hex_string_truth_table("0069817CC5893BA6AC326E47619F5AD0")
1398 .unwrap();
1399 assert_eq!(
1400 boolean_function.printable_hex_truth_table(),
1401 "0069817cc5893ba6ac326e47619f5ad0"
1402 );
1403
1404 let boolean_function = BooleanFunction::from_hex_string_truth_table("fe12").unwrap();
1405 assert_eq!(boolean_function.printable_hex_truth_table(), "fe12");
1406 }
1407
1408 #[test]
1409 fn test_clone() {
1410 let boolean_function =
1411 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1412 .unwrap();
1413 let cloned_boolean_function = boolean_function.clone();
1414 assert_eq!(&boolean_function, &cloned_boolean_function);
1415
1416 let boolean_function = BooleanFunction::from_hex_string_truth_table("fe12").unwrap();
1417 let cloned_boolean_function = boolean_function.clone();
1418 assert_eq!(&boolean_function, &cloned_boolean_function);
1419 }
1420
1421 #[test]
1422 fn test_eq() {
1423 let boolean_function =
1424 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1425 .unwrap();
1426 assert_eq!(&boolean_function, &boolean_function);
1427
1428 let boolean_function2 =
1429 BooleanFunction::from_hex_string_truth_table("fe12").unwrap();
1430 assert_eq!(&boolean_function2, &boolean_function2);
1431
1432 assert_ne!(&boolean_function2, &boolean_function);
1433
1434 let boolean_function3 =
1435 BooleanFunction::from_hex_string_truth_table("0000fe12").unwrap();
1436 assert_ne!(&boolean_function3, &boolean_function2);
1437
1438 let boolean_function4 =
1439 BooleanFunction::from_hex_string_truth_table("0969817CC5893BA6AC326E47619F5AD0")
1440 .unwrap();
1441 assert_ne!(&boolean_function, &boolean_function4);
1442 }
1443
1444 #[test]
1445 fn test_reverse() {
1446 let boolean_function =
1447 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1448 .unwrap();
1449 let reversed_boolean_function = boolean_function.reverse();
1450 assert_eq!(reversed_boolean_function.variables_count(), 7);
1451 assert_eq!(
1452 reversed_boolean_function.printable_hex_truth_table(),
1453 "86967e833a76c45953cd91b89e60a52f"
1454 );
1455
1456 let reversed_boolean_function = !boolean_function;
1457 assert_eq!(reversed_boolean_function.variables_count(), 7);
1458 assert_eq!(
1459 reversed_boolean_function.printable_hex_truth_table(),
1460 "86967e833a76c45953cd91b89e60a52f"
1461 );
1462
1463 let boolean_function = BooleanFunction::from_hex_string_truth_table("fe12").unwrap();
1464 let reversed_boolean_function = boolean_function.reverse();
1465 assert_eq!(reversed_boolean_function.variables_count(), 4);
1466 assert_eq!(
1467 reversed_boolean_function.printable_hex_truth_table(),
1468 "01ed"
1469 );
1470
1471 let reversed_boolean_function = !boolean_function;
1472 assert_eq!(reversed_boolean_function.variables_count(), 4);
1473 assert_eq!(
1474 reversed_boolean_function.printable_hex_truth_table(),
1475 "01ed"
1476 );
1477 }
1478
1479 #[test]
1480 fn test_is_linear() {
1481 let boolean_function =
1482 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1483 .unwrap();
1484 assert!(!boolean_function.is_linear());
1485
1486 let boolean_function =
1487 BooleanFunction::from_hex_string_truth_table("0000000000000000ffffffffffffffff")
1488 .unwrap();
1489 assert!(boolean_function.is_linear());
1490
1491 let boolean_function =
1492 BooleanFunction::from_hex_string_truth_table("abcdef0123456789").unwrap();
1493 assert!(!boolean_function.is_linear());
1494
1495 let boolean_function =
1496 BooleanFunction::from_hex_string_truth_table("00000000ffffffff").unwrap();
1497 assert!(boolean_function.is_linear());
1498 }
1499
1500 #[test]
1501 fn test_is_symmetric() {
1502 let boolean_function = BooleanFunction::from_hex_string_truth_table("00").unwrap();
1503 assert!(boolean_function.is_symmetric());
1504
1505 let boolean_function = BooleanFunction::from_hex_string_truth_table("ff").unwrap();
1506 assert!(boolean_function.is_symmetric());
1507
1508 let boolean_function = BooleanFunction::from_hex_string_truth_table("80").unwrap();
1509 assert!(boolean_function.is_symmetric());
1510
1511 let boolean_function = BooleanFunction::from_hex_string_truth_table("1e").unwrap();
1512 assert!(!boolean_function.is_symmetric());
1513
1514 let boolean_function =
1515 BooleanFunction::from_hex_string_truth_table("00000008").unwrap();
1516 assert!(!boolean_function.is_symmetric());
1517
1518 let boolean_function =
1519 BooleanFunction::from_hex_string_truth_table("ffffffffffffffffffffffffffffffff")
1520 .unwrap();
1521 assert!(boolean_function.is_symmetric());
1522 }
1523
1524 #[test]
1525 fn test_nonlinearity() {
1526 let boolean_function =
1527 BooleanFunction::from_hex_string_truth_table("00000000").unwrap();
1528 assert_eq!(boolean_function.nonlinearity(), 0);
1529
1530 let boolean_function =
1531 BooleanFunction::from_hex_string_truth_table("ffffffff").unwrap();
1532 assert_eq!(boolean_function.nonlinearity(), 0);
1533
1534 let boolean_function =
1535 BooleanFunction::from_hex_string_truth_table("0000000a").unwrap();
1536 assert_eq!(boolean_function.nonlinearity(), 2);
1537
1538 let boolean_function =
1539 BooleanFunction::from_hex_string_truth_table("0113077C165E76A8").unwrap();
1540 assert_eq!(boolean_function.nonlinearity(), 28);
1541 }
1542
1543 #[test]
1544 fn test_is_bent() {
1545 let boolean_function =
1546 BooleanFunction::try_from("00000000").unwrap();
1547 assert!(!boolean_function.is_bent());
1548
1549 let boolean_function =
1550 BooleanFunction::from_hex_string_truth_table("0113077C165E76A8").unwrap();
1551 assert!(boolean_function.is_bent());
1552
1553 let boolean_function =
1554 BooleanFunction::from_hex_string_truth_table("00000000ffffffff").unwrap();
1555 assert!(!boolean_function.is_bent());
1556 }
1557
1558 #[test]
1559 fn test_is_near_bent() {
1560 let boolean_function = BooleanFunction::from_hex_string_truth_table("f9")
1561 .unwrap();
1562 assert!(boolean_function.is_near_bent());
1563
1564 let boolean_function = BooleanFunction::from_hex_string_truth_table("ff")
1565 .unwrap();
1566 assert!(!boolean_function.is_near_bent());
1567
1568 let boolean_function = BooleanFunction::from_hex_string_truth_table("f9f9")
1570 .unwrap();
1571 assert!(!boolean_function.is_near_bent());
1572 }
1573
1574 #[test]
1575 fn test_annihilator() {
1576 let boolean_function =
1577 BooleanFunction::from_hex_string_truth_table("00000000").unwrap();
1578 let annihilator = boolean_function.annihilator(Some(0)).unwrap();
1579 assert_eq!(annihilator.0.printable_hex_truth_table(), "ffffffff");
1580 assert_eq!(annihilator.1, 0);
1581 assert_eq!(annihilator.2, 1);
1582
1583 let boolean_function =
1584 BooleanFunction::from_hex_string_truth_table("abcdef0123456789").unwrap();
1585 let annihilator = boolean_function.annihilator(Some(4)).unwrap();
1586 assert_eq!(
1587 annihilator.0.printable_hex_truth_table(),
1588 "1010101010101010"
1589 );
1590 assert_eq!(annihilator.1, 3);
1591 assert_eq!(annihilator.2, 25);
1592
1593 let boolean_function = BooleanFunction::from_hex_string_truth_table(
1594 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1595 )
1596 .unwrap();
1597 let annihilator = boolean_function.annihilator(Some(4));
1598 assert!(annihilator.is_none());
1599
1600 let boolean_function = BooleanFunction::from_hex_string_truth_table(
1601 "0000000000000000000000000000000000000000000000000000000000000000",
1602 )
1603 .unwrap();
1604 let annihilator = boolean_function.annihilator(Some(4)).unwrap();
1605 assert_eq!(
1606 annihilator.0.printable_hex_truth_table(),
1607 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1608 );
1609 assert_eq!(annihilator.1, 0);
1610 assert_eq!(annihilator.2, 163);
1611
1612 let boolean_function = BooleanFunction::from_hex_string_truth_table(
1613 "80921c010276c44224422441188118822442244118811880400810a80e200425",
1614 )
1615 .unwrap();
1616 let annihilator = boolean_function.annihilator(Some(1));
1617 assert!(annihilator.is_none());
1618 let annihilator = boolean_function.annihilator(Some(5)).unwrap();
1619 assert_eq!(
1620 annihilator.0.printable_hex_truth_table(),
1621 "2244224411881188d2b4d2b4e178e178d2b4d2b4e178e1782244224411881188"
1622 );
1623 assert_eq!(annihilator.1, 2);
1624 assert_eq!(annihilator.2, 155);
1625 }
1626
1627 #[test]
1628 fn test_algebraic_immunity() {
1629 let boolean_function = BooleanFunction::from_hex_string_truth_table(
1630 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1631 )
1632 .unwrap();
1633 assert_eq!(boolean_function.algebraic_immunity(), 0);
1634
1635 let boolean_function = BooleanFunction::from_hex_string_truth_table(
1636 "0000000000000000000000000000000000000000000000000000000000000000",
1637 )
1638 .unwrap();
1639 assert_eq!(boolean_function.algebraic_immunity(), 0);
1640
1641 let boolean_function = BooleanFunction::from_hex_string_truth_table("ffff").unwrap();
1642 assert_eq!(boolean_function.algebraic_immunity(), 0);
1643
1644 let boolean_function = BooleanFunction::from_hex_string_truth_table("0000").unwrap();
1645 assert_eq!(boolean_function.algebraic_immunity(), 0);
1646
1647 let boolean_function = BooleanFunction::from_hex_string_truth_table(
1648 "80921c010276c44224422441188118822442244118811880400810a80e200425",
1649 )
1650 .unwrap();
1651 assert_eq!(boolean_function.algebraic_immunity(), 2);
1652
1653 let boolean_function = BooleanFunction::from_hex_string_truth_table(
1654 "2244224411881188d2b4d2b4e178e178d2b4d2b4e178e1782244224411881188",
1655 )
1656 .unwrap();
1657 assert_eq!(boolean_function.algebraic_immunity(), 2);
1658
1659 let boolean_function =
1660 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1661 .unwrap();
1662 assert_eq!(boolean_function.algebraic_immunity(), 3);
1663
1664 let boolean_function =
1665 BooleanFunction::from_hex_string_truth_table("0113077C165E76A8").unwrap();
1666 assert_eq!(boolean_function.algebraic_immunity(), 2);
1667
1668 let boolean_function = BooleanFunction::from_hex_string_truth_table("1e").unwrap();
1669 assert_eq!(boolean_function.algebraic_immunity(), 2);
1670 }
1671
1672 #[test]
1673 fn test_is_plateaued() {
1674 let boolean_function = BooleanFunction::from_hex_string_truth_table(
1675 "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1676 )
1677 .unwrap();
1678 assert!(boolean_function.is_plateaued());
1679
1680 let boolean_function = BooleanFunction::from_hex_string_truth_table("8778").unwrap();
1681 assert!(boolean_function.is_plateaued());
1682
1683 let boolean_function = BooleanFunction::from_hex_string_truth_table("1e").unwrap();
1684 assert!(boolean_function.is_plateaued());
1685
1686 let boolean_function =
1687 BooleanFunction::from_hex_string_truth_table("abcdef1234567890").unwrap();
1688 assert!(!boolean_function.is_plateaued());
1689 }
1690
1691 #[test]
1692 fn test_sum_of_square_indicator() {
1693 let boolean_function =
1694 BooleanFunction::from_hex_string_truth_table("ffffffff").unwrap();
1695 assert_eq!(boolean_function.sum_of_square_indicator(), 32768);
1696
1697 let boolean_function = BooleanFunction::from_hex_string_truth_table("0000").unwrap();
1698 assert_eq!(boolean_function.sum_of_square_indicator(), 4096);
1699
1700 let boolean_function =
1701 BooleanFunction::from_hex_string_truth_table("abcdef1234567890abcdef1234567890")
1702 .unwrap();
1703 assert_eq!(boolean_function.sum_of_square_indicator(), 84992);
1704
1705 let boolean_function =
1706 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1707 .unwrap();
1708 assert_eq!(boolean_function.sum_of_square_indicator(), 32768);
1709 }
1710
1711 #[test]
1712 fn test_absolute_indicator() {
1713 let boolean_function = BooleanFunction::from_hex_string_truth_table("1e").unwrap();
1714 assert_eq!(boolean_function.absolute_indicator(), 8);
1715
1716 let boolean_function =
1717 BooleanFunction::from_hex_string_truth_table("ffffffff").unwrap();
1718 assert_eq!(boolean_function.absolute_indicator(), 32);
1719
1720 let boolean_function = BooleanFunction::from_hex_string_truth_table("0000").unwrap();
1721 assert_eq!(boolean_function.absolute_indicator(), 16);
1722
1723 let boolean_function =
1724 BooleanFunction::from_hex_string_truth_table("abcdef1234567890abcdef1234567890")
1725 .unwrap();
1726 assert_eq!(boolean_function.absolute_indicator(), 128);
1727
1728 let boolean_function =
1729 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1730 .unwrap();
1731 assert_eq!(boolean_function.absolute_indicator(), 32);
1732
1733 let boolean_function =
1734 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1735 .unwrap();
1736 assert_eq!(boolean_function.absolute_indicator(), 32);
1737 }
1738
1739 #[test]
1740 fn test_linear_structures() {
1741 let boolean_function = BooleanFunction::from_hex_string_truth_table("1e").unwrap();
1742 assert_eq!(boolean_function.linear_structures(), [0, 4]);
1743
1744 let boolean_function =
1745 BooleanFunction::from_hex_string_truth_table("abcdef1234567890abcdef1234567890")
1746 .unwrap();
1747 assert_eq!(boolean_function.linear_structures(), [0, 64]);
1748
1749 let boolean_function =
1750 BooleanFunction::from_hex_string_truth_table("0113077C165E76A8").unwrap();
1751 assert_eq!(boolean_function.linear_structures(), [0]);
1752
1753 let boolean_function =
1754 BooleanFunction::from_hex_string_truth_table("00000000ffffffff").unwrap();
1755 assert_eq!(
1756 boolean_function.linear_structures(),
1757 [
1758 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
1759 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
1760 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63
1761 ]
1762 );
1763
1764 let boolean_function =
1765 BooleanFunction::from_hex_string_truth_table("00000000").unwrap();
1766 assert_eq!(
1767 boolean_function.linear_structures(),
1768 [
1769 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
1770 23, 24, 25, 26, 27, 28, 29, 30, 31
1771 ]
1772 );
1773
1774 let boolean_function =
1775 BooleanFunction::from_hex_string_truth_table("ffffffff").unwrap();
1776 assert_eq!(
1777 boolean_function.linear_structures(),
1778 [
1779 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
1780 23, 24, 25, 26, 27, 28, 29, 30, 31
1781 ]
1782 );
1783 }
1784
1785 #[test]
1786 fn test_has_linear_structure() {
1787 let boolean_function = BooleanFunction::from_hex_string_truth_table("659a").unwrap();
1788 assert!(boolean_function.has_linear_structure());
1789
1790 let boolean_function = BooleanFunction::from_hex_string_truth_table("dd0e").unwrap();
1791 assert!(!boolean_function.has_linear_structure());
1792
1793 let boolean_function =
1794 BooleanFunction::from_hex_string_truth_table("00000000").unwrap();
1795 assert!(boolean_function.has_linear_structure());
1796
1797 let boolean_function =
1798 BooleanFunction::from_hex_string_truth_table("ffffffff").unwrap();
1799 assert!(boolean_function.has_linear_structure());
1800
1801 let boolean_function =
1802 BooleanFunction::from_hex_string_truth_table("0113077C165E76A8").unwrap();
1803 assert!(!boolean_function.has_linear_structure());
1804 }
1805
1806 #[test]
1807 fn test_is_linear_structure() {
1808 let boolean_function = BooleanFunction::from_hex_string_truth_table("659a").unwrap();
1809 assert!(boolean_function.is_linear_structure(1));
1810 assert!(!boolean_function.is_linear_structure(7));
1811 assert!(boolean_function.is_linear_structure(9));
1812 }
1813
1814 #[test]
1815 fn test_walsh_hadamard_values() {
1816 let boolean_function = BooleanFunction::from_hex_string_truth_table("dd0e").unwrap();
1817 assert_eq!(
1818 boolean_function.walsh_hadamard_values(),
1819 [-2, -2, 6, -2, -6, 2, 2, 2, 6, 6, -2, 6, -6, 2, 2, 2]
1820 );
1821
1822 let boolean_function = BooleanFunction::from_hex_string_truth_table("0000").unwrap();
1823 assert_eq!(
1824 boolean_function.walsh_hadamard_values(),
1825 [16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
1826 );
1827
1828 let boolean_function = BooleanFunction::from_hex_string_truth_table("ffff").unwrap();
1829 assert_eq!(
1830 boolean_function.walsh_hadamard_values(),
1831 [-16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
1832 );
1833 }
1834
1835 #[test]
1836 fn test_boolean_function_from_reverse_walsh_transform() {
1837 let boolean_function = BooleanFunction::from_reverse_walsh_hadamard_transform(&[
1838 -2, -2, 6, -2, -6, 2, 2, 2, 6, 6, -2, 6, -6, 2, 2, 2,
1839 ])
1840 .unwrap();
1841 assert_eq!(boolean_function.printable_hex_truth_table(), "dd0e");
1842 assert_eq!(
1843 boolean_function.get_boolean_function_type(),
1844 BooleanFunctionType::Small
1845 );
1846
1847 let boolean_function = BooleanFunction::from_reverse_walsh_hadamard_transform(&[
1848 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1849 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1850 0, 0, 0, 0, 0, 0,
1851 ])
1852 .unwrap();
1853 assert_eq!(
1854 boolean_function.printable_hex_truth_table(),
1855 "ffffffff00000000"
1856 );
1857 assert_eq!(
1858 boolean_function.get_boolean_function_type(),
1859 BooleanFunctionType::Small
1860 );
1861
1862 let boolean_function = BooleanFunction::from_reverse_walsh_hadamard_transform(&[
1863 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1864 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1865 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1866 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1867 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1868 ])
1869 .unwrap();
1870 assert_eq!(
1871 boolean_function.printable_hex_truth_table(),
1872 "ffffffffffffffff0000000000000000"
1873 );
1874 assert_eq!(
1875 boolean_function.get_boolean_function_type(),
1876 BooleanFunctionType::Big
1877 );
1878
1879 let boolean_function = BooleanFunction::from_reverse_walsh_hadamard_transform(&[
1880 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1881 ])
1882 .unwrap();
1883 assert_eq!(boolean_function.printable_hex_truth_table(), "0000");
1884
1885 let boolean_function = BooleanFunction::from_reverse_walsh_hadamard_transform(&[
1886 128, 0, 8, 8, 0, 0, 8, 8, -8, 8, -16, 0, 8, -8, -64, -16, 0, -16, 8, -8, 0, -16, 8, -8,
1887 8, 8, 0, 0, -8, -8, -16, -16, -8, 8, 0, -16, -8, 8, 0, 16, 0, 0, -8, 24, 16, -48, 8, 8,
1888 8, 8, 16, 16, 8, 8, -16, 16, 0, 16, -8, 8, -16, 32, 8, 24, 8, 8, 0, 0, -8, -8, 16, -16,
1889 0, 16, 8, -8, 0, -16, 8, -8, -8, 8, -16, 0, 8, -8, 0, 16, -32, 0, 8, 8, 0, 0, 8, 8, 0,
1890 0, -8, -8, -16, -16, 8, 8, 8, -8, -16, 0, 8, -8, -16, 0, 0, -16, -8, 8, -16, 0, 8, -8,
1891 -8, -8, 0, 0, -8, -8, 0, 0, 12, 4, 4, -4, -4, -12, 20, -20, 4, 12, 12, -12, 4, -20, 12,
1892 -12, -4, 4, -12, -4, 12, -12, 4, 12, -28, -4, 12, 4, 4, -4, 12, 4, 4, -4, -4, -12, -12,
1893 -20, 12, 4, 12, -12, -12, -4, 12, -12, -12, -4, 4, -20, -4, 4, -12, -4, 12, -12, -4,
1894 -12, 4, -4, -4, -12, 4, -4, -4, 4, 4, 12, -4, 4, 4, 12, -12, 12, -20, 4, 4, -4, 60,
1895 -12, -4, -12, 4, -4, -4, -12, 4, -4, 4, 12, -4, 4, -12, -4, -20, -12, -12, -20, -4, 84,
1896 -12, -20, -4, -12, -4, -28, -12, -4, 12, 52, 4, -20, 4, -20, 12, -12, 4, -20, -20, -12,
1897 -4, -12, -12, -20, -20, 4, 4, -4,
1898 ])
1899 .unwrap();
1900 assert_eq!(
1901 boolean_function.printable_hex_truth_table(),
1902 "80921c010276c44224422441188118822442244118811880400810a80e200425"
1903 );
1904 assert_eq!(
1905 boolean_function.get_boolean_function_type(),
1906 BooleanFunctionType::Big
1907 );
1908
1909 let boolean_function = BooleanFunction::from_reverse_walsh_hadamard_transform(&[
1910 128, 0, 8, 8, 0, 0, 8, 8, -8, 8, -16, 0, 8, -8, -64, -16, 0, -16, 8, -8, 0, -16, 8, -8,
1911 8, 8, 0, 0, -8, -8, -16, -16, -8, 8, 0, -16, -8, 8, 0, 16, 0, 0, -8, 24, 16, -48, 8, 8,
1912 8, 8, 16, 16, 8, 8, -16, 16, 0, 16, -8, 8, -16, 32, 8, 24, 8, 8, 0, 0, -8, -8, 16, -16,
1913 0, 16, 8, -8, 0, -16, 8, -8, -8, 8, -16, 0, 8, -8, 0, 16, -32, 0, 8, 8, 0, 0, 8, 8, 0,
1914 0, -8, -8, -16, -16, 8, 8, 8, -8, -16, 0, 8, -8, -16, 0, 0, -16, -8, 8, -16, 0, 8, -8,
1915 -8, -8, 0, 0, -8, -8, 0, 0, 12, 4, 4, -4, -4, -12, 20, -20, 4, 12, 12, -12, 4, -20, 12,
1916 -12, -4, 4, -12, -4, 12, -12, 4, 12, -28, -4, 12, 4, 4, -4, 12, 4, 4, -4, -4, -12, -12,
1917 -20, 12, 4, 12, -12, -12, -4, 12, -12, -12, -4, 4, -20, -4, 4, -12, -4, 12, -12, -4,
1918 -12, 4, -4, -4, -12, 4, -4, -4, 4, 4, 12, -4, 4, 4, 12, -12, 12, -20, 4, 4, -4, 60,
1919 -12, -4, -12, 4, -4, -4, -12, 4, -4, 4, 12, -4, 4, -12, -4, -20, -12, -12, -20, -4, 84,
1920 -12, -20, -4, -12, -4, -28, -12, -4, 12, 52, 4, -20, 4, -20, 12, -12, 4, -20, -20, -12,
1921 -4, -12, -12, -20, -20, 4, 4,
1922 ]);
1923 assert!(boolean_function.is_err());
1924 assert_eq!(boolean_function.unwrap_err(), InvalidWalshValuesCount(255));
1925
1926 let boolean_function =
1927 BooleanFunction::from_reverse_walsh_hadamard_transform(&[128]);
1928 assert!(boolean_function.is_err());
1929 assert_eq!(boolean_function.unwrap_err(), InvalidWalshValuesCount(1));
1930 }
1931
1932 #[test]
1933 fn test_correlation_immunity() {
1934 let boolean_function = BooleanFunction::from_hex_string_truth_table("dd0e").unwrap();
1935 assert_eq!(boolean_function.correlation_immunity(), 0);
1936
1937 let boolean_function =
1938 BooleanFunction::from_hex_string_truth_table("55C3AAC3").unwrap();
1939 assert_eq!(boolean_function.correlation_immunity(), 1);
1940
1941 let boolean_function = BooleanFunction::from_hex_string_truth_table("1f").unwrap();
1942 assert_eq!(boolean_function.correlation_immunity(), 0);
1943
1944 let boolean_function = BooleanFunction::from_hex_string_truth_table("ffff").unwrap();
1945 assert_eq!(boolean_function.correlation_immunity(), 4);
1946
1947 let boolean_function =
1948 BooleanFunction::from_hex_string_truth_table("00000000000000000000000000000000")
1949 .unwrap();
1950 assert_eq!(boolean_function.correlation_immunity(), 7);
1951
1952 let boolean_function =
1953 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1954 .unwrap();
1955 assert_eq!(boolean_function.correlation_immunity(), 2);
1956 }
1957
1958 #[test]
1959 fn test_resiliency_order() {
1960 let boolean_function = BooleanFunction::from_hex_string_truth_table("dd0e").unwrap();
1961 assert_eq!(boolean_function.resiliency_order(), None);
1962
1963 let boolean_function =
1964 BooleanFunction::from_hex_string_truth_table("55C3AAC3").unwrap();
1965 assert_eq!(boolean_function.resiliency_order(), Some(1));
1966
1967 let boolean_function = BooleanFunction::from_hex_string_truth_table("1f").unwrap();
1968 assert_eq!(boolean_function.resiliency_order(), None);
1969
1970 let boolean_function = BooleanFunction::from_hex_string_truth_table("ffff").unwrap();
1971 assert_eq!(boolean_function.resiliency_order(), None);
1972
1973 let boolean_function =
1974 BooleanFunction::from_hex_string_truth_table("00000000000000000000000000000000")
1975 .unwrap();
1976 assert_eq!(boolean_function.resiliency_order(), None);
1977
1978 let boolean_function =
1979 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1980 .unwrap();
1981 assert_eq!(boolean_function.resiliency_order(), Some(2));
1982 }
1983
1984 #[test]
1985 fn test_biguint_truth_table() {
1986 let boolean_function =
1987 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
1988 .unwrap();
1989 assert_eq!(
1990 boolean_function.biguint_truth_table().to_str_radix(16),
1991 "7969817cc5893ba6ac326e47619f5ad0"
1992 );
1993
1994 let boolean_function = BooleanFunction::from_hex_string_truth_table("1e").unwrap();
1995 assert_eq!(
1996 boolean_function.biguint_truth_table().to_str_radix(16),
1997 "1e"
1998 );
1999 }
2000
2001 #[test]
2002 fn test_try_u64_truth_table() {
2003 let boolean_function =
2004 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
2005 .unwrap();
2006 assert_eq!(boolean_function.try_u64_truth_table(), None);
2007
2008 let boolean_function = BooleanFunction::from_hex_string_truth_table("1e").unwrap();
2009 assert_eq!(boolean_function.try_u64_truth_table(), Some(30));
2010 }
2011
2012 #[test]
2013 fn test_xor() {
2014 let mut boolean_function =
2015 BooleanFunction::from_hex_string_truth_table("80921c010276c440400810a80e200425")
2016 .unwrap();
2017 let boolean_function2 =
2018 BooleanFunction::from_hex_string_truth_table("22442244118811882244224411881188")
2019 .unwrap();
2020 let boolean_function3 = boolean_function.clone() ^ boolean_function2.clone();
2021 boolean_function ^= boolean_function2.clone();
2022 assert_eq!(&boolean_function, &boolean_function3);
2023 assert_eq!(
2024 boolean_function.printable_hex_truth_table(),
2025 "a2d63e4513fed5c8624c32ec1fa815ad"
2026 );
2027 assert_eq!(boolean_function.variables_count(), 7);
2028 assert_eq!(
2029 boolean_function.get_boolean_function_type(),
2030 BooleanFunctionType::Big
2031 );
2032 assert_eq!(
2033 boolean_function3.get_boolean_function_type(),
2034 BooleanFunctionType::Big
2035 );
2036
2037 let mut boolean_function =
2038 BooleanFunction::from_hex_string_truth_table("1e").unwrap();
2039 let boolean_function2 = BooleanFunction::from_hex_string_truth_table("ab").unwrap();
2040 let boolean_function3 = boolean_function.clone() ^ boolean_function2.clone();
2041 boolean_function ^= boolean_function2.clone();
2042 assert_eq!(&boolean_function, &boolean_function3);
2043 assert_eq!(boolean_function.printable_hex_truth_table(), "b5");
2044 assert_eq!(boolean_function.variables_count(), 3);
2045 assert_eq!(
2046 boolean_function.get_boolean_function_type(),
2047 BooleanFunctionType::Small
2048 );
2049 assert_eq!(
2050 boolean_function3.get_boolean_function_type(),
2051 BooleanFunctionType::Small
2052 );
2053
2054 let mut boolean_function =
2055 BooleanFunction::from_hex_string_truth_table("1e").unwrap();
2056 let boolean_function2: BooleanFunction = super::BigBooleanFunction::from_truth_table(
2057 BigUint::from_str_radix("ab", 16).unwrap(),
2058 3,
2059 ).into();
2060 let boolean_function3 = boolean_function.clone() ^ boolean_function2.clone();
2061 boolean_function ^= boolean_function2.clone();
2062 assert_eq!(&boolean_function, &boolean_function3);
2063 assert_eq!(boolean_function.printable_hex_truth_table(), "b5");
2064 assert_eq!(boolean_function.variables_count(), 3);
2065 assert_eq!(
2066 boolean_function.get_boolean_function_type(),
2067 BooleanFunctionType::Small
2068 );
2069 assert_eq!(
2070 boolean_function2.get_boolean_function_type(),
2071 BooleanFunctionType::Big
2072 );
2073 assert_eq!(
2074 boolean_function3.get_boolean_function_type(),
2075 BooleanFunctionType::Small
2076 );
2077
2078 let mut boolean_function: BooleanFunction = super::BigBooleanFunction::from_truth_table(
2079 BigUint::from_str_radix("ab", 16).unwrap(),
2080 3,
2081 ).into();
2082 let boolean_function2 = BooleanFunction::from_hex_string_truth_table("1e").unwrap();
2083 let boolean_function3 = boolean_function.clone() ^ boolean_function2.clone();
2084 boolean_function ^= boolean_function2.clone();
2085 assert_eq!(&boolean_function, &boolean_function3);
2086 assert_eq!(boolean_function.printable_hex_truth_table(), "b5");
2087 assert_eq!(boolean_function.variables_count(), 3);
2088 assert_eq!(
2089 boolean_function.get_boolean_function_type(),
2090 BooleanFunctionType::Big
2091 );
2092 assert_eq!(
2093 boolean_function2.get_boolean_function_type(),
2094 BooleanFunctionType::Small
2095 );
2096 assert_eq!(
2097 boolean_function3.get_boolean_function_type(),
2098 BooleanFunctionType::Big
2099 );
2100 }
2101
2102 #[test]
2103 fn test_add() {
2104 let mut boolean_function =
2105 BooleanFunction::from_hex_string_truth_table("80921c010276c440400810a80e200425")
2106 .unwrap();
2107 let boolean_function2 =
2108 BooleanFunction::from_hex_string_truth_table("22442244118811882244224411881188")
2109 .unwrap();
2110 let boolean_function3 = boolean_function.clone() + boolean_function2.clone();
2111 boolean_function += boolean_function2.clone();
2112 assert_eq!(&boolean_function, &boolean_function3);
2113 assert_eq!(
2114 boolean_function.printable_hex_truth_table(),
2115 "a2d63e4513fed5c8624c32ec1fa815ad"
2116 );
2117 assert_eq!(boolean_function.variables_count(), 7);
2118 assert_eq!(
2119 boolean_function.get_boolean_function_type(),
2120 BooleanFunctionType::Big
2121 );
2122 assert_eq!(
2123 boolean_function3.get_boolean_function_type(),
2124 BooleanFunctionType::Big
2125 );
2126
2127 let mut boolean_function =
2128 BooleanFunction::from_hex_string_truth_table("1e").unwrap();
2129 let boolean_function2 = BooleanFunction::from_hex_string_truth_table("ab").unwrap();
2130 let boolean_function3 = boolean_function.clone() + boolean_function2.clone();
2131 boolean_function += boolean_function2.clone();
2132 assert_eq!(&boolean_function, &boolean_function3);
2133 assert_eq!(boolean_function.printable_hex_truth_table(), "b5");
2134 assert_eq!(boolean_function.variables_count(), 3);
2135 assert_eq!(
2136 boolean_function.get_boolean_function_type(),
2137 BooleanFunctionType::Small
2138 );
2139 assert_eq!(
2140 boolean_function3.get_boolean_function_type(),
2141 BooleanFunctionType::Small
2142 );
2143
2144 let mut boolean_function =
2145 BooleanFunction::from_hex_string_truth_table("1e").unwrap();
2146 let boolean_function2: BooleanFunction = super::BigBooleanFunction::from_truth_table(
2147 BigUint::from_str_radix("ab", 16).unwrap(),
2148 3,
2149 ).into();
2150 let boolean_function3 = boolean_function.clone() + boolean_function2.clone();
2151 boolean_function += boolean_function2.clone();
2152 assert_eq!(&boolean_function, &boolean_function3);
2153 assert_eq!(boolean_function.printable_hex_truth_table(), "b5");
2154 assert_eq!(boolean_function.variables_count(), 3);
2155 assert_eq!(
2156 boolean_function.get_boolean_function_type(),
2157 BooleanFunctionType::Small
2158 );
2159 assert_eq!(
2160 boolean_function2.get_boolean_function_type(),
2161 BooleanFunctionType::Big
2162 );
2163 assert_eq!(
2164 boolean_function3.get_boolean_function_type(),
2165 BooleanFunctionType::Small
2166 );
2167
2168 let mut boolean_function: BooleanFunction = super::BigBooleanFunction::from_truth_table(
2169 BigUint::from_str_radix("ab", 16).unwrap(),
2170 3,
2171 ).into();
2172 let boolean_function2 = BooleanFunction::from_hex_string_truth_table("1e").unwrap();
2173 let boolean_function3 = boolean_function.clone() + boolean_function2.clone();
2174 boolean_function += boolean_function2.clone();
2175 assert_eq!(&boolean_function, &boolean_function3);
2176 assert_eq!(boolean_function.printable_hex_truth_table(), "b5");
2177 assert_eq!(boolean_function.variables_count(), 3);
2178 assert_eq!(
2179 boolean_function.get_boolean_function_type(),
2180 BooleanFunctionType::Big
2181 );
2182 assert_eq!(
2183 boolean_function2.get_boolean_function_type(),
2184 BooleanFunctionType::Small
2185 );
2186 assert_eq!(
2187 boolean_function3.get_boolean_function_type(),
2188 BooleanFunctionType::Big
2189 );
2190 }
2191
2192 #[test]
2193 fn test_and() {
2194 let mut boolean_function =
2195 BooleanFunction::from_hex_string_truth_table("4f1ead396f247a0410bdb210c006eab568ab4bfa8acb7a13b14ede67096c6eed")
2196 .unwrap();
2197 let boolean_function2 =
2198 BooleanFunction::from_hex_string_truth_table("c870974094ead8a96a450b2ef33486b4e61a4c5e97816f7a7bae007d4c53fc7d")
2199 .unwrap();
2200 let boolean_function3 = boolean_function.clone() & boolean_function2.clone();
2201 boolean_function &= boolean_function2.clone();
2202 assert_eq!(&boolean_function, &boolean_function3);
2203 assert_eq!(
2204 boolean_function.printable_hex_truth_table(),
2205 "481085000420580000050200c00482b4600a485a82816a12310e006508406c6d"
2206 );
2207 assert_eq!(boolean_function.variables_count(), 8);
2208 assert_eq!(
2209 boolean_function.get_boolean_function_type(),
2210 BooleanFunctionType::Big
2211 );
2212 assert_eq!(
2213 boolean_function3.get_boolean_function_type(),
2214 BooleanFunctionType::Big
2215 );
2216
2217 let mut boolean_function =
2218 BooleanFunction::from_hex_string_truth_table("1e").unwrap();
2219 let boolean_function2 = BooleanFunction::from_hex_string_truth_table("ab").unwrap();
2220 let boolean_function3 = boolean_function.clone() & boolean_function2.clone();
2221 boolean_function &= boolean_function2.clone();
2222 assert_eq!(&boolean_function, &boolean_function3);
2223 assert_eq!(boolean_function.printable_hex_truth_table(), "0a");
2224 assert_eq!(boolean_function.variables_count(), 3);
2225 assert_eq!(
2226 boolean_function.get_boolean_function_type(),
2227 BooleanFunctionType::Small
2228 );
2229 assert_eq!(
2230 boolean_function3.get_boolean_function_type(),
2231 BooleanFunctionType::Small
2232 );
2233
2234 let mut boolean_function =
2235 BooleanFunction::from_hex_string_truth_table("1e").unwrap();
2236 let boolean_function2: BooleanFunction = super::BigBooleanFunction::from_truth_table(
2237 BigUint::from_str_radix("ab", 16).unwrap(),
2238 3,
2239 ).into();
2240 let boolean_function3 = boolean_function.clone() & boolean_function2.clone();
2241 boolean_function &= boolean_function2.clone();
2242 assert_eq!(&boolean_function, &boolean_function3);
2243 assert_eq!(boolean_function.printable_hex_truth_table(), "0a");
2244 assert_eq!(boolean_function.variables_count(), 3);
2245 assert_eq!(
2246 boolean_function.get_boolean_function_type(),
2247 BooleanFunctionType::Small
2248 );
2249 assert_eq!(
2250 boolean_function2.get_boolean_function_type(),
2251 BooleanFunctionType::Big
2252 );
2253 assert_eq!(
2254 boolean_function3.get_boolean_function_type(),
2255 BooleanFunctionType::Small
2256 );
2257
2258 let mut boolean_function: BooleanFunction = super::BigBooleanFunction::from_truth_table(
2259 BigUint::from_str_radix("ab", 16).unwrap(),
2260 3,
2261 ).into();
2262 let boolean_function2 = BooleanFunction::from_hex_string_truth_table("1e").unwrap();
2263 let boolean_function3 = boolean_function.clone() & boolean_function2.clone();
2264 boolean_function &= boolean_function2.clone();
2265 assert_eq!(&boolean_function, &boolean_function3);
2266 assert_eq!(boolean_function.printable_hex_truth_table(), "0a");
2267 assert_eq!(boolean_function.variables_count(), 3);
2268 assert_eq!(
2269 boolean_function.get_boolean_function_type(),
2270 BooleanFunctionType::Big
2271 );
2272 assert_eq!(
2273 boolean_function2.get_boolean_function_type(),
2274 BooleanFunctionType::Small
2275 );
2276 assert_eq!(
2277 boolean_function3.get_boolean_function_type(),
2278 BooleanFunctionType::Big
2279 );
2280 }
2281
2282 #[test]
2283 fn test_mul() {
2284 let mut boolean_function =
2285 BooleanFunction::from_hex_string_truth_table("4f1ead396f247a0410bdb210c006eab568ab4bfa8acb7a13b14ede67096c6eed")
2286 .unwrap();
2287 let boolean_function2 =
2288 BooleanFunction::from_hex_string_truth_table("c870974094ead8a96a450b2ef33486b4e61a4c5e97816f7a7bae007d4c53fc7d")
2289 .unwrap();
2290 let boolean_function3 = boolean_function.clone() & boolean_function2.clone();
2291 boolean_function &= boolean_function2.clone();
2292 assert_eq!(&boolean_function, &boolean_function3);
2293 assert_eq!(
2294 boolean_function.printable_hex_truth_table(),
2295 "481085000420580000050200c00482b4600a485a82816a12310e006508406c6d"
2296 );
2297 assert_eq!(boolean_function.variables_count(), 8);
2298 assert_eq!(
2299 boolean_function.get_boolean_function_type(),
2300 BooleanFunctionType::Big
2301 );
2302 assert_eq!(
2303 boolean_function3.get_boolean_function_type(),
2304 BooleanFunctionType::Big
2305 );
2306
2307 let mut boolean_function =
2308 BooleanFunction::from_hex_string_truth_table("1e").unwrap();
2309 let boolean_function2 = BooleanFunction::from_hex_string_truth_table("ab").unwrap();
2310 let boolean_function3 = boolean_function.clone() * boolean_function2.clone();
2311 boolean_function *= boolean_function2.clone();
2312 assert_eq!(&boolean_function, &boolean_function3);
2313 assert_eq!(boolean_function.printable_hex_truth_table(), "0a");
2314 assert_eq!(boolean_function.variables_count(), 3);
2315 assert_eq!(
2316 boolean_function.get_boolean_function_type(),
2317 BooleanFunctionType::Small
2318 );
2319 assert_eq!(
2320 boolean_function3.get_boolean_function_type(),
2321 BooleanFunctionType::Small
2322 );
2323
2324 let mut boolean_function =
2325 BooleanFunction::from_hex_string_truth_table("1e").unwrap();
2326 let boolean_function2: BooleanFunction = super::BigBooleanFunction::from_truth_table(
2327 BigUint::from_str_radix("ab", 16).unwrap(),
2328 3,
2329 ).into();
2330 let boolean_function3 = boolean_function.clone() * boolean_function2.clone();
2331 boolean_function *= boolean_function2.clone();
2332 assert_eq!(&boolean_function, &boolean_function3);
2333 assert_eq!(boolean_function.printable_hex_truth_table(), "0a");
2334 assert_eq!(boolean_function.variables_count(), 3);
2335 assert_eq!(
2336 boolean_function.get_boolean_function_type(),
2337 BooleanFunctionType::Small
2338 );
2339 assert_eq!(
2340 boolean_function2.get_boolean_function_type(),
2341 BooleanFunctionType::Big
2342 );
2343 assert_eq!(
2344 boolean_function3.get_boolean_function_type(),
2345 BooleanFunctionType::Small
2346 );
2347
2348 let mut boolean_function: BooleanFunction = super::BigBooleanFunction::from_truth_table(
2349 BigUint::from_str_radix("ab", 16).unwrap(),
2350 3,
2351 ).into();
2352 let boolean_function2 = BooleanFunction::from_hex_string_truth_table("1e").unwrap();
2353 let boolean_function3 = boolean_function.clone() * boolean_function2.clone();
2354 boolean_function *= boolean_function2.clone();
2355 assert_eq!(&boolean_function, &boolean_function3);
2356 assert_eq!(boolean_function.printable_hex_truth_table(), "0a");
2357 assert_eq!(boolean_function.variables_count(), 3);
2358 assert_eq!(
2359 boolean_function.get_boolean_function_type(),
2360 BooleanFunctionType::Big
2361 );
2362 assert_eq!(
2363 boolean_function2.get_boolean_function_type(),
2364 BooleanFunctionType::Small
2365 );
2366 assert_eq!(
2367 boolean_function3.get_boolean_function_type(),
2368 BooleanFunctionType::Big
2369 );
2370 }
2371
2372 #[test]
2373 fn test_walsh_fourier_values() {
2374 let boolean_function = BooleanFunction::from_hex_string_truth_table("ff").unwrap();
2375 assert_eq!(
2376 boolean_function.walsh_fourier_values(),
2377 [8, 0, 0, 0, 0, 0, 0, 0]
2378 );
2379
2380 let boolean_function = BooleanFunction::from_hex_string_truth_table("00").unwrap();
2381 assert_eq!(
2382 boolean_function.walsh_fourier_values(),
2383 [0, 0, 0, 0, 0, 0, 0, 0]
2384 );
2385
2386 let boolean_function = BooleanFunction::from_hex_string_truth_table("0f").unwrap();
2387 assert_eq!(
2388 boolean_function.walsh_fourier_values(),
2389 [4, 0, 0, 0, 4, 0, 0, 0]
2390 );
2391
2392 let boolean_function = BooleanFunction::from_hex_string_truth_table("55").unwrap();
2393 assert_eq!(
2394 boolean_function.walsh_fourier_values(),
2395 [4, 4, 0, 0, 0, 0, 0, 0]
2396 );
2397
2398 let boolean_function = BooleanFunction::from_hex_string_truth_table("aa").unwrap();
2399 assert_eq!(
2400 boolean_function.walsh_fourier_values(),
2401 [4, -4, 0, 0, 0, 0, 0, 0]
2402 );
2403
2404 let boolean_function = BooleanFunction::from_hex_string_truth_table("8001").unwrap();
2405 assert_eq!(
2406 boolean_function.walsh_fourier_values(),
2407 [2, 0, 0, 2, 0, 2, 2, 0, 0, 2, 2, 0, 2, 0, 0, 2]
2408 );
2409 }
2410
2411 #[test]
2412 fn test_boolean_function_from_reverse_walsh_fourier_transform() {
2413 let boolean_function =
2414 BooleanFunction::from_reverse_walsh_fourier_transform(&[8, 0, 0, 0, 0, 0, 0, 0])
2415 .unwrap();
2416 assert_eq!(boolean_function.printable_hex_truth_table(), "ff");
2417
2418 let boolean_function =
2419 BooleanFunction::from_reverse_walsh_fourier_transform(&[0, 0, 0, 0, 0, 0, 0, 0])
2420 .unwrap();
2421 assert_eq!(boolean_function.printable_hex_truth_table(), "00");
2422
2423 let boolean_function = BooleanFunction::from_reverse_walsh_fourier_transform(&[
2424 2, 0, 0, 2, 0, 2, 2, 0, 0, 2, 2, 0, 2, 0, 0, 2,
2425 ])
2426 .unwrap();
2427 assert_eq!(boolean_function.printable_hex_truth_table(), "8001");
2428 assert_eq!(
2429 boolean_function.get_boolean_function_type(),
2430 BooleanFunctionType::Small
2431 );
2432
2433 let boolean_function = BooleanFunction::from_hex_string_truth_table(
2434 "80921c010276c44224422441188118822442244118811880400810a80e200425",
2435 )
2436 .unwrap();
2437 let walsh_fourier_values = boolean_function.walsh_fourier_values();
2438 let boolean_function2 =
2439 BooleanFunction::from_reverse_walsh_fourier_transform(&walsh_fourier_values)
2440 .unwrap();
2441 assert_eq!(
2442 boolean_function2.printable_hex_truth_table(),
2443 "80921c010276c44224422441188118822442244118811880400810a80e200425"
2444 );
2445
2446 let boolean_function = BooleanFunction::from_hex_string_truth_table("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap();
2447 let walsh_fourier_values = boolean_function.walsh_fourier_values();
2448 let boolean_function2 =
2449 BooleanFunction::from_reverse_walsh_fourier_transform(&walsh_fourier_values)
2450 .unwrap();
2451 assert_eq!(boolean_function2.printable_hex_truth_table(), "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
2452 assert_eq!(
2453 boolean_function2.get_boolean_function_type(),
2454 BooleanFunctionType::Big
2455 );
2456 assert_eq!(boolean_function2.variables_count(), 9);
2457 }
2458
2459 #[test]
2460 fn test_support() {
2461 let boolean_function = BooleanFunction::from_hex_string_truth_table("00").unwrap();
2462 assert_eq!(boolean_function.support().len(), 0);
2463
2464 let boolean_function = BooleanFunction::from_hex_string_truth_table("ff").unwrap();
2465 assert_eq!(boolean_function.support().len(), 8);
2466
2467 let boolean_function = BooleanFunction::from_hex_string_truth_table("1e").unwrap();
2468 assert_eq!(boolean_function.support().len(), 4);
2469 }
2470
2471 #[test]
2472 fn test_propagation_criterion() {
2473 let boolean_function = BooleanFunction::from_hex_string_truth_table("00").unwrap();
2474 assert_eq!(boolean_function.propagation_criterion(), 0);
2475
2476 let boolean_function = BooleanFunction::from_hex_string_truth_table("ff").unwrap();
2477 assert_eq!(boolean_function.propagation_criterion(), 0);
2478
2479 let boolean_function =
2480 BooleanFunction::from_hex_string_truth_table("288d1b41").unwrap();
2481 assert_eq!(boolean_function.propagation_criterion(), 3);
2482 }
2483
2484 #[test]
2485 fn test_iter() {
2486 let boolean_function = BooleanFunction::from_hex_string_truth_table("1e").unwrap();
2487 let mut iter = boolean_function.iter();
2488 assert_eq!(iter.next().unwrap(), false);
2489 assert_eq!(iter.next().unwrap(), true);
2490 assert_eq!(iter.next().unwrap(), true);
2491 assert_eq!(iter.next().unwrap(), true);
2492 assert_eq!(iter.next().unwrap(), true);
2493 assert_eq!(iter.next().unwrap(), false);
2494 assert_eq!(iter.next().unwrap(), false);
2495 assert_eq!(iter.next().unwrap(), false);
2496 assert!(iter.next().is_none());
2497
2498 let iter = boolean_function.iter();
2499 assert_eq!(iter.count(), 8);
2500
2501 let boolean_function =
2502 BooleanFunction::from_hex_string_truth_table("7969817CC5893BA6AC326E47619F5AD0")
2503 .unwrap();
2504 let mut iter = boolean_function.iter();
2505 assert_eq!(iter.next(), Some(false));
2506 assert_eq!(iter.next(), Some(false));
2507 assert_eq!(iter.next(), Some(false));
2508 assert_eq!(iter.next(), Some(false));
2509 assert_eq!(iter.next(), Some(true));
2510
2511 let iter = boolean_function.iter();
2512 assert_eq!(iter.count(), 128);
2513 }
2514
2515 #[test]
2516 fn test_boolean_function_from_u64_truth_table() {
2517 let boolean_function = BooleanFunction::from_u64_truth_table(30, 3).unwrap();
2518 assert_eq!(boolean_function.printable_hex_truth_table(), "1e");
2519 assert_eq!(boolean_function.variables_count(), 3);
2520 assert_eq!(
2521 boolean_function.get_boolean_function_type(),
2522 BooleanFunctionType::Small
2523 );
2524
2525 let boolean_function = BooleanFunction::from_u64_truth_table(30, 7);
2526 assert!(boolean_function.is_err());
2527
2528 let boolean_function = BooleanFunction::from_u64_truth_table(300, 3);
2529 assert!(boolean_function.is_err());
2530 }
2531
2532 #[test]
2533 fn test_boolean_function_from_biguint_truth_table() {
2534 let boolean_function =
2535 BooleanFunction::from_biguint_truth_table(&BigUint::from(30u32), 3).unwrap();
2536 assert_eq!(boolean_function.printable_hex_truth_table(), "1e");
2537 assert_eq!(boolean_function.variables_count(), 3);
2538 assert_eq!(
2539 boolean_function.get_boolean_function_type(),
2540 BooleanFunctionType::Small
2541 );
2542
2543 let boolean_function =
2544 BooleanFunction::from_biguint_truth_table(&BigUint::from(30u32), 7).unwrap();
2545 assert_eq!(
2546 boolean_function.printable_hex_truth_table(),
2547 "0000000000000000000000000000001e"
2548 );
2549 assert_eq!(boolean_function.variables_count(), 7);
2550 assert_eq!(
2551 boolean_function.get_boolean_function_type(),
2552 BooleanFunctionType::Big
2553 );
2554
2555 let boolean_function = BooleanFunction::from_u64_truth_table(300, 3);
2556 assert!(boolean_function.is_err());
2557
2558 let boolean_function = BooleanFunction::from_u64_truth_table(300, 32);
2559 assert!(boolean_function.is_err());
2560 }
2561
2562 #[test]
2563 fn test_get_1_local_neighbor() {
2564 let boolean_function = BooleanFunction::from_hex_string_truth_table("1e").unwrap();
2565 let neighbor = boolean_function.get_1_local_neighbor(1);
2566 assert_eq!(neighbor.printable_hex_truth_table(), "1c");
2567
2568 let boolean_function = BooleanFunction::from_hex_string_truth_table("80921c010276c440400810a80e200425").unwrap();
2569 let neighbor = boolean_function.get_1_local_neighbor(0);
2570 assert_eq!(neighbor.printable_hex_truth_table(), "80921c010276c440400810a80e200424");
2571 }
2572
2573 #[test]
2574 fn test_close_balanced_functions_iterator() {
2575 let balanced_function = BooleanFunction::from_hex_string_truth_table("aaaa").unwrap();
2576 assert!(balanced_function.close_balanced_functions_iterator().is_err());
2577
2578 let bent_function = BooleanFunction::from_hex_string_truth_table("ac90").unwrap();
2579 let close_balanced_iterator = bent_function.close_balanced_functions_iterator();
2580 assert!(close_balanced_iterator.is_ok());
2581 let close_balanced_iterator = close_balanced_iterator.unwrap();
2582 assert_eq!(close_balanced_iterator.into_iter().count(), 45); let mut close_balanced_iterator = bent_function.close_balanced_functions_iterator().unwrap();
2585 assert!(close_balanced_iterator.all(|f| f.is_balanced()));
2586
2587
2588 let balanced_function = BooleanFunction::from_hex_string_truth_table(
2589 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
2590 ).unwrap();
2591 assert!(balanced_function.close_balanced_functions_iterator().is_err());
2592
2593 let bent_function = BooleanFunction::from_hex_string_truth_table(
2594 "80329780469d0b85cd2ad63e1a6ba42adbd83c9a0c55e4e8c99f227b0ffc1418"
2595 ).unwrap();
2596 let close_balanced_iterator = bent_function.close_balanced_functions_iterator();
2597 assert!(close_balanced_iterator.is_ok());
2598 let mut close_balanced_iterator = close_balanced_iterator.unwrap();
2599 for _ in 0..10 {
2600 assert!(close_balanced_iterator.next().unwrap().is_balanced());
2601 }
2602 }
2603
2604 #[test]
2605 fn test_from_anf_polynomial_str() {
2606 let rule_30_anf_str = "x0*x1 + x0 + x1 + x2";
2607 let rule_30_function = BooleanFunction::from_anf_polynomial_str(rule_30_anf_str, 3).unwrap();
2608 assert_eq!(rule_30_function.printable_hex_truth_table(), "1e");
2609
2610 let anf_str = "x0*x1*x2*x3*x4*x5*x6 + x7";
2611 let boolean_function = BooleanFunction::from_anf_polynomial_str(anf_str, 8).unwrap();
2612 assert_eq!(boolean_function.printable_hex_truth_table(), "7fffffffffffffffffffffffffffffff80000000000000000000000000000000");
2613 }
2614
2615 #[test]
2616 fn test_from_anf_polynomial() {
2617 let rule_30_anf = AnfPolynomial::from_str("x0*x1 + x0 + x1 + x2", 3).unwrap();
2618 let rule_30_function = BooleanFunction::from_anf_polynomial(&rule_30_anf);
2619 assert_eq!(rule_30_function.printable_hex_truth_table(), "1e");
2620
2621 let anf = AnfPolynomial::from_str("x0*x1*x2*x3*x4*x5*x6 + x7", 8).unwrap();
2622 let boolean_function = BooleanFunction::from_anf_polynomial(&anf);
2623 assert_eq!(boolean_function.printable_hex_truth_table(), "7fffffffffffffffffffffffffffffff80000000000000000000000000000000");
2624 }
2625}