fixed_key_aes.rs 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. use aes::cipher::crypto_common::Block;
  2. use aes::cipher::{BlockEncrypt, KeyInit};
  3. use aes::Aes128;
  4. use rand::{thread_rng, Rng};
  5. /// Fixed-key AES implementation. Implements the ((tweakable) circular) correlation robust hash
  6. /// functions from Guo et al. eprint 2019/074
  7. #[derive(Clone, Debug)]
  8. pub struct FixedKeyAes {
  9. /// AES object including expanded key.
  10. aes: Aes128,
  11. }
  12. impl FixedKeyAes {
  13. pub fn new(key: [u8; 16]) -> Self {
  14. Self {
  15. aes: Aes128::new_from_slice(&key).expect("does not fail since key has the right size"),
  16. }
  17. }
  18. pub fn sample() -> Self {
  19. let key: [u8; 16] = thread_rng().gen();
  20. Self::new(key)
  21. }
  22. /// Permutation sigma(x) = (x.high64 ^ x.low64, x.high64).
  23. fn sigma(x: u128) -> u128 {
  24. let low = x & 0xffffffffffffffff;
  25. let high = x >> 64;
  26. ((high ^ low) << 64) | high
  27. }
  28. /// Random permutation pi(x) = AES(k, x)
  29. pub fn pi(&self, x: u128) -> u128 {
  30. let mut block = Block::<Aes128>::clone_from_slice(&x.to_le_bytes());
  31. self.aes.encrypt_block(&mut block);
  32. u128::from_le_bytes(
  33. block
  34. .as_slice()
  35. .try_into()
  36. .expect("does not fail since block is 16 bytes long"),
  37. )
  38. }
  39. /// MMO function pi(x) ^ x
  40. pub fn hash_cr(&self, x: u128) -> u128 {
  41. self.pi(x) ^ x
  42. }
  43. /// MMO-hat function pi(sigma(x)) ^ sigma(x)
  44. pub fn hash_ccr(&self, x: u128) -> u128 {
  45. let sigma_x = Self::sigma(x);
  46. self.pi(sigma_x) ^ sigma_x
  47. }
  48. /// TMMO function pi(pi(x) ^ i) ^ pi(x)
  49. pub fn hash_tccr(&self, x: u128, tweak: u128) -> u128 {
  50. let pi_x = self.pi(x);
  51. self.pi(pi_x ^ tweak) ^ pi_x
  52. }
  53. }