/ src / tests.rs
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  }