/ crates / equix / tests / tor_equix_vectors.rs
tor_equix_vectors.rs
  1  //! The original Equi-X unit tests don't contain full test vectors.
  2  //! These are from the C tor implementation's test_crypto_equix().
  3  
  4  use equix::{EquiX, Error, HashError, Solution, SolutionItemArray};
  5  use std::iter;
  6  
  7  #[test]
  8  fn verify_only() {
  9      // Quick verify test that doesn't use the solver at all
 10  
 11      assert!(matches!(
 12          equix::verify_array(
 13              b"a",
 14              &[0x2227, 0xa173, 0x365a, 0xb47d, 0x1bb2, 0xa077, 0x0d5e, 0xf25f]
 15          ),
 16          Ok(())
 17      ));
 18      assert!(matches!(
 19          equix::verify_array(
 20              b"a",
 21              &[0x1bb2, 0xa077, 0x0d5e, 0xf25f, 0x2220, 0xa173, 0x365a, 0xb47d]
 22          ),
 23          Err(Error::Order)
 24      ));
 25      assert!(matches!(
 26          equix::verify_array(
 27              b"a",
 28              &[0x2220, 0xa173, 0x365a, 0xb47d, 0x1bb2, 0xa077, 0x0d5e, 0xf25f]
 29          ),
 30          Err(Error::HashSum)
 31      ));
 32  }
 33  
 34  #[test]
 35  fn tor_equix_vectors() {
 36      // Solve and verify test with permutations
 37  
 38      solve_and_verify(b"bsipdp", None);
 39      solve_and_verify(b"espceob", None);
 40      solve_and_verify(
 41          b"zzz",
 42          Some(&[[
 43              0xae21, 0xd392, 0x3215, 0xdd9c, 0x2f08, 0x93df, 0x232c, 0xe5dc,
 44          ]]),
 45      );
 46      solve_and_verify(
 47          b"rrr",
 48          Some(&[[
 49              0x0873, 0x57a8, 0x73e0, 0x912e, 0x1ca8, 0xad96, 0x9abd, 0xd7de,
 50          ]]),
 51      );
 52      solve_and_verify(b"qqq", Some(&[]));
 53      solve_and_verify(b"0123456789", Some(&[]));
 54      solve_and_verify(b"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", Some(&[]));
 55      solve_and_verify(
 56          b"",
 57          Some(&[
 58              [
 59                  0x0098, 0x3a4d, 0xc489, 0xcfba, 0x7ef3, 0xa498, 0xa00f, 0xec20,
 60              ],
 61              [
 62                  0x78d8, 0x8611, 0xa4df, 0xec19, 0x0927, 0xa729, 0x842f, 0xf771,
 63              ],
 64              [
 65                  0x54b5, 0xcc11, 0x1593, 0xe624, 0x9357, 0xb339, 0xb138, 0xed99,
 66              ],
 67          ]),
 68      );
 69      solve_and_verify(
 70          b"a",
 71          Some(&[
 72              [
 73                  0x4b38, 0x8c81, 0x9255, 0xad99, 0x5ce7, 0xeb3e, 0xc635, 0xee38,
 74              ],
 75              [
 76                  0x3f9e, 0x659b, 0x9ae6, 0xb891, 0x63ae, 0x777c, 0x06ca, 0xc593,
 77              ],
 78              [
 79                  0x2227, 0xa173, 0x365a, 0xb47d, 0x1bb2, 0xa077, 0x0d5e, 0xf25f,
 80              ],
 81          ]),
 82      );
 83      solve_and_verify(
 84          b"abc",
 85          Some(&[
 86              [
 87                  0x371f, 0x8865, 0x8189, 0xfbc3, 0x26df, 0xe4c0, 0xab39, 0xfe5a,
 88              ],
 89              [
 90                  0x2101, 0xb88f, 0xc525, 0xccb3, 0x5785, 0xa41e, 0x4fba, 0xed18,
 91              ],
 92          ]),
 93      );
 94      solve_and_verify(
 95          b"abce",
 96          Some(&[
 97              [
 98                  0x4fca, 0x72eb, 0x101f, 0xafab, 0x1add, 0x2d71, 0x75a3, 0xc978,
 99              ],
100              [
101                  0x17f1, 0x7aa6, 0x23e3, 0xab00, 0x7e2f, 0x917e, 0x16da, 0xda9e,
102              ],
103              [
104                  0x70ee, 0x7757, 0x8a54, 0xbd2b, 0x90e4, 0xe31e, 0x2085, 0xe47e,
105              ],
106              [
107                  0x62c5, 0x86d1, 0x5752, 0xe1f0, 0x12da, 0x8f33, 0x7336, 0xf161,
108              ],
109          ]),
110      );
111      solve_and_verify(
112          b"01234567890123456789",
113          Some(&[
114              [
115                  0x4803, 0x6775, 0xc5c9, 0xd1b0, 0x1bc3, 0xe4f6, 0x4027, 0xf5ad,
116              ],
117              [
118                  0x5a8a, 0x9542, 0xef99, 0xf0b9, 0x4905, 0x4e29, 0x2da5, 0xfbd5,
119              ],
120              [
121                  0x4c79, 0xc935, 0x2bcb, 0xcd0f, 0x0362, 0x9fa9, 0xa62e, 0xf83a,
122              ],
123              [
124                  0x5878, 0x6edf, 0x1e00, 0xf5e3, 0x43de, 0x9212, 0xd01e, 0xfd11,
125              ],
126              [
127                  0x0b69, 0x2d17, 0x01be, 0x6cb4, 0x0fba, 0x4a9e, 0x8d75, 0xa50f,
128              ],
129          ]),
130      );
131  }
132  
133  fn solve_and_verify(challenge: &[u8], expected: Option<&[[u16; 8]]>) {
134      match EquiX::new(challenge) {
135          // Some constructions are expected to fail
136          Err(Error::Hash(HashError::ProgramConstraints)) => assert_eq!(expected, None),
137          Err(_) => unreachable!(),
138  
139          // Check each solution itself and a few variations, when the solve succeeds
140          Ok(equix) => {
141              let expected = expected.unwrap();
142              let solutions = equix.solve();
143              assert_eq!(solutions.len(), expected.len());
144  
145              for (solution, expected) in iter::zip(solutions, expected) {
146                  let solution = solution.into();
147  
148                  assert_eq!(&solution, expected);
149                  verify_expect_success(&equix, &solution);
150                  verify_with_order_error(&solution);
151                  verify_with_hash_error(&equix, &solution);
152              }
153          }
154      }
155  }
156  
157  fn verify_expect_success(equix: &EquiX, solution: &SolutionItemArray) {
158      let solution = Solution::try_from_array(solution).unwrap();
159      assert!(equix.verify(&solution).is_ok());
160  }
161  
162  fn verify_with_hash_error(equix: &EquiX, solution: &SolutionItemArray) {
163      let mut solution = *solution;
164      solution[0] += 1;
165      let solution = Solution::try_from_array(&solution).unwrap();
166      assert!(matches!(equix.verify(&solution), Err(Error::HashSum)));
167  }
168  
169  fn verify_with_order_error(solution: &SolutionItemArray) {
170      let mut solution = *solution;
171      solution.swap(0, 1);
172      assert!(matches!(
173          Solution::try_from_array(&solution),
174          Err(Error::Order)
175      ));
176  }