tests.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 crate::{ 17 biginteger::*, 18 rand::{TestRng, Uniform}, 19 }; 20 21 #[allow(clippy::eq_op)] 22 fn biginteger_arithmetic_test<B: BigInteger>(a: B, b: B, zero: B) { 23 // zero == zero 24 assert!(zero == zero); 25 26 // zero.is_zero() == true 27 assert!(zero.is_zero()); 28 29 // a == a 30 assert!(a == a); 31 32 // a + 0 = a 33 let mut a0_add = a; 34 a0_add.add_nocarry(&zero); 35 assert_eq!(a0_add, a); 36 37 // a - 0 = a 38 let mut a0_sub = a; 39 a0_sub.sub_noborrow(&zero); 40 assert_eq!(a0_sub, a); 41 42 // a - a = 0 43 let mut aa_sub = a; 44 aa_sub.sub_noborrow(&a); 45 assert_eq!(aa_sub, zero); 46 47 // a + b = b + a 48 let mut ab_add = a; 49 ab_add.add_nocarry(&b); 50 let mut ba_add = b; 51 ba_add.add_nocarry(&a); 52 assert_eq!(ab_add, ba_add); 53 } 54 55 fn biginteger_bits_test<B: BigInteger>() { 56 let mut one = B::from(1u64); 57 assert!(one.get_bit(0)); 58 assert!(!one.get_bit(1)); 59 one.muln(5); 60 61 let thirty_two = one; 62 assert!(!thirty_two.get_bit(0)); 63 assert!(!thirty_two.get_bit(1)); 64 assert!(!thirty_two.get_bit(2)); 65 assert!(!thirty_two.get_bit(3)); 66 assert!(!thirty_two.get_bit(4)); 67 assert!(thirty_two.get_bit(5), "{thirty_two:?}"); 68 } 69 70 fn biginteger_bytes_test<B: BigInteger>(rng: &mut TestRng) { 71 let mut bytes = [0u8; 256]; 72 let x: B = Uniform::rand(rng); 73 x.write_le(bytes.as_mut()).unwrap(); 74 let y = B::read_le(bytes.as_ref()).unwrap(); 75 assert_eq!(x, y); 76 } 77 78 fn biginteger_to_string_test<B: BigInteger>(rng: &mut TestRng) { 79 const ITERATIONS: u64 = 1_000_000; 80 81 // Sanity check the integers starting from 0 to ITERATIONS. 82 for integer in 0..ITERATIONS { 83 assert_eq!(format!("{integer}"), B::from(integer).to_string()); 84 } 85 86 // If the BigInteger has more than one limb, sanity check 87 // that the second limb conversion is also correct. 88 if B::NUM_LIMBS > 1 { 89 let start = u64::MAX as u128; 90 for integer in start..(start + ITERATIONS as u128) { 91 let mut buffer = vec![0u8; 8 * B::NUM_LIMBS]; 92 buffer.iter_mut().zip(&integer.to_le_bytes()).for_each(|(buf, val)| { 93 *buf = *val; 94 }); 95 assert_eq!(format!("{integer}"), B::read_le(&*buffer).unwrap().to_string()); 96 } 97 } 98 99 // Sample random integers and check they match against num-bigint. 100 for _ in 0..ITERATIONS { 101 let candidate: B = Uniform::rand(rng); 102 let candidate_hex = format!("{candidate:?}"); 103 let reference = num_bigint::BigUint::parse_bytes(candidate_hex.as_bytes(), 16).unwrap(); 104 assert_eq!(reference.to_str_radix(10), candidate.to_string()); 105 } 106 } 107 108 fn test_biginteger<B: BigInteger>(zero: B) { 109 let mut rng = TestRng::default(); 110 111 let a: B = Uniform::rand(&mut rng); 112 let b: B = Uniform::rand(&mut rng); 113 biginteger_arithmetic_test(a, b, zero); 114 biginteger_bytes_test::<B>(&mut rng); 115 biginteger_bits_test::<B>(); 116 biginteger_to_string_test::<B>(&mut rng); 117 } 118 119 #[test] 120 fn test_biginteger256() { 121 test_biginteger(BigInteger256::new([0u64; 4])); 122 } 123 124 #[test] 125 fn test_biginteger384() { 126 test_biginteger(BigInteger384::new([0u64; 6])); 127 }