fixed_key_aes.rs 2.0 KB

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