tests.rs
1 extern crate test; 2 use crate::dinoxor::*; 3 use test::Bencher; 4 use test::black_box; 5 use std::arch::asm; 6 7 #[quickcheck] 8 fn test_dinoxor(x: u8, y: u8) { 9 assert_eq!(dinoxor(x, y), x ^ y); 10 } 11 12 #[quickcheck] 13 fn test_spread_bits_to_bytes_registers(x: u8) { 14 let mut res: u8; 15 16 unsafe { 17 asm!( 18 "eor v0.16b, v0.16b, v0.16b", 19 "bl {spread_bits_to_bytes}", 20 "bl {compress_bytes_to_bits}", // This test looks like it will become a lie. Use the debugger. 21 "mov {res:w}, w0", 22 in("w0") x, 23 res = out(reg) res, 24 spread_bits_to_bytes = sym spread_bits_to_bytes, 25 compress_bytes_to_bits = sym _compress_bytes_to_bits, 26 ); 27 } 28 29 assert_eq!(x, res); 30 } 31 32 #[test] 33 fn test_prepare_xor_truth_table() { 34 let expected: u64 = 0x01_01_00_00_01_01_00; 35 let mut lower: u64; 36 let mut upper: u64; 37 38 unsafe { 39 asm!( 40 "bl {prepare_xor_truth_table}", 41 "umov {lower:x}, v0.d[0]", 42 "umov {upper:x}, v0.d[1]", 43 lower = out(reg) lower, 44 upper = out(reg) upper, 45 prepare_xor_truth_table = sym prepare_xor_truth_table 46 ); 47 } 48 49 assert_eq!(lower, expected); 50 assert_eq!(upper, expected); 51 } 52 53 #[test] 54 fn test_prepare_multiplication_table() { 55 let expected_lower: u64 = 0x02_02_02_02_02_02_02_02; 56 let expected_upper: u64 = 0x01_01_01_01_01_01_01_01; 57 let mut lower: u64; 58 let mut upper: u64; 59 60 unsafe { 61 asm!( 62 "bl {prepare_multiplication_table}", 63 "umov {lower:x}, v1.d[0]", 64 "umov {upper:x}, v1.d[1]", 65 lower = out(reg) lower, 66 upper = out(reg) upper, 67 prepare_multiplication_table = sym prepare_multiplication_table 68 ); 69 } 70 71 assert_eq!(lower, expected_lower); 72 assert_eq!(upper, expected_upper); 73 } 74 75 #[quickcheck] 76 fn test_calculate_xor_result(x: u8, y: u8) { 77 let expected_result = x ^ y; 78 79 unsafe { 80 // Preparing v2 with x and y 81 asm!( 82 "eor v2.16b, v2.16b, v2.16b", // Clear v2 83 "mov w0, {x_val:w}", // Load x into w0 84 "bl {spread_bits_to_bytes}", // Spread x bits into bytes in v2 85 "mov w0, {y_val:w}", // Load y into w0 86 "bl {spread_bits_to_bytes}", // Spread y bits into bytes in v2 87 88 x_val = in(reg) x, 89 y_val = in(reg) y, 90 spread_bits_to_bytes = sym spread_bits_to_bytes 91 ); 92 93 // Prepare XOR truth table in v0 94 asm!( 95 "bl {prepare_xor_truth_table}", 96 prepare_xor_truth_table = sym prepare_xor_truth_table 97 ); 98 99 // Prepare multiplication table in v1 100 asm!( 101 "bl {prepare_multiplication_table}", 102 prepare_multiplication_table = sym prepare_multiplication_table 103 ); 104 105 // Calculate XOR result 106 let mut result: u8; 107 asm!( 108 "bl {calculate_xor_result}", 109 "mov {result_res:w}, w0", // Move the result from w0 to the result variable 110 111 calculate_xor_result = sym calculate_xor_result, 112 result_res = out(reg) result 113 ); 114 115 assert_eq!(result, expected_result); 116 } 117 118 } 119 120 #[bench] 121 fn bench_xor(b: &mut Bencher) { 122 123 b.iter(|| { 124 let n = black_box(0xFF); 125 126 (0x00..n).fold(0, |old: u8, new| old ^ new) 127 }); 128 } 129 #[bench] 130 fn bench_dinoxor(b: &mut Bencher) { 131 b.iter(|| { 132 let n = black_box(0xFF); 133 134 (0x00..n).fold(0, |old: u8, new| dinoxor(old, new)) 135 }); 136 } 137 138 use crate::chacha20::*; 139 140 #[test] 141 fn test_chacha_known_vector() { 142 let key = [ 143 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 144 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 145 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 146 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 147 ]; 148 let nonce = [ 149 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x4a, 150 0x00, 0x00, 0x00, 0x00, 151 ]; 152 153 let counter: u32 = 1; 154 let mut state = ChaCha20State::new(&key, &nonce, counter); 155 156 let plaintext = [0u8; 64]; // Use zeroed plaintext for simplicity. 157 let mut ciphertext = [0u8; 64]; 158 let mut decrypted_text = [0u8; 64]; 159 160 unsafe { 161 state.process(&plaintext, &mut ciphertext); 162 state.reset(&key, &nonce, counter); // Reset state or reinitialize if needed. 163 state.process(&ciphertext, &mut decrypted_text); 164 } 165 166 assert_eq!(plaintext, decrypted_text, "Decryption failed to revert ciphertext to original plaintext"); 167 } 168 169 #[quickcheck] 170 fn test_chacha_properties(key: Key, nonce: Nonce, counter: u32, plaintext: Block) { 171 let Key(key) = key; 172 let Nonce(nonce) = nonce; 173 let Block(plaintext) = plaintext; 174 175 let mut state = ChaCha20State::new(&key, &nonce, counter); 176 177 //let plaintext = [0u8; 64]; // Use zeroed plaintext for simplicity. 178 let mut ciphertext = [0u8; 64]; 179 let mut decrypted_text = [0u8; 64]; 180 181 unsafe { 182 state.process(&plaintext, &mut ciphertext); 183 state.reset(&key, &nonce, counter); // Reset state or reinitialize if needed. 184 state.process(&ciphertext, &mut decrypted_text); 185 } 186 187 assert_eq!(plaintext, decrypted_text, "Decryption failed to revert ciphertext to original plaintext"); 188 }