prg.hpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #ifndef __PRG_HPP__
  2. #define __PRG_HPP__
  3. #include <array>
  4. #include "bitutils.hpp"
  5. #include "aes.hpp"
  6. static const struct PRGkey {
  7. AESkey k;
  8. PRGkey(__m128i key) {
  9. AES_128_Key_Expansion(k, key);
  10. }
  11. }
  12. // Digits of e
  13. prgkey(
  14. _mm_set_epi64x(2718281828459045235ULL, 3602874713526624977ULL)
  15. ),
  16. // Digits of pi
  17. leafprgkeys[3] = {
  18. _mm_set_epi64x(3141592653589793238ULL, 4626433832795028841ULL),
  19. _mm_set_epi64x(9716939937510582097ULL, 4944592307816406286ULL),
  20. _mm_set_epi64x(2089986280348253421ULL, 1706798214808651328ULL)
  21. };
  22. // Compute one of the children of node seed; whichchild=0 for
  23. // the left child, 1 for the right child
  24. static inline void prg(__m128i &out, __m128i seed, bool whichchild,
  25. size_t &aes_ops)
  26. {
  27. __m128i in = set_lsb(seed, whichchild);
  28. __m128i mid;
  29. AES_ECB_encrypt(mid, set_lsb(seed, whichchild), prgkey.k, aes_ops);
  30. out = mid ^ in;
  31. }
  32. // Compute both children of node seed
  33. static inline void prgboth(__m128i &left, __m128i &right, __m128i seed,
  34. size_t &aes_ops)
  35. {
  36. __m128i inl = set_lsb(seed, 0);
  37. __m128i inr = set_lsb(seed, 1);
  38. __m128i midl, midr;
  39. AES_ECB_encrypt(midl, inl, prgkey.k, aes_ops);
  40. AES_ECB_encrypt(midr, inr, prgkey.k, aes_ops);
  41. left = midl ^ inl;
  42. right = midr ^ inr;
  43. }
  44. // Compute one of the leaf children of node seed; whichchild=0 for
  45. // the left child, 1 for the right child
  46. template <size_t LWIDTH>
  47. static inline void prg(std::array<__m128i,LWIDTH> &out,
  48. __m128i seed, bool whichchild, size_t &aes_ops)
  49. {
  50. __m128i in = set_lsb(seed, whichchild);
  51. __m128i mid0, mid1, mid2;
  52. AES_ECB_encrypt(mid0, set_lsb(seed, whichchild), leafprgkeys[0].k, aes_ops);
  53. if (LWIDTH > 1) {
  54. AES_ECB_encrypt(mid1, set_lsb(seed, whichchild), leafprgkeys[1].k, aes_ops);
  55. }
  56. if (LWIDTH > 2) {
  57. AES_ECB_encrypt(mid2, set_lsb(seed, whichchild), leafprgkeys[2].k, aes_ops);
  58. }
  59. out[0] = mid0 ^ in;
  60. if (LWIDTH > 1) {
  61. out[1] = mid1 ^ in;
  62. }
  63. if (LWIDTH > 2) {
  64. out[2] = mid2 ^ in;
  65. }
  66. }
  67. // Compute both of the leaf children of node seed
  68. template <size_t LWIDTH>
  69. static inline void prgboth(std::array<__m128i,LWIDTH> &left,
  70. std::array<__m128i,LWIDTH> &right, __m128i seed, size_t &aes_ops)
  71. {
  72. __m128i inl = set_lsb(seed, 0);
  73. __m128i inr = set_lsb(seed, 1);
  74. __m128i midl0, midl1, midl2;
  75. __m128i midr0, midr1, midr2;
  76. AES_ECB_encrypt(midl0, inl, leafprgkeys[0].k, aes_ops);
  77. AES_ECB_encrypt(midr0, inr, leafprgkeys[0].k, aes_ops);
  78. if (LWIDTH > 1) {
  79. AES_ECB_encrypt(midl1, inl, leafprgkeys[1].k, aes_ops);
  80. AES_ECB_encrypt(midr1, inr, leafprgkeys[1].k, aes_ops);
  81. }
  82. if (LWIDTH > 2) {
  83. AES_ECB_encrypt(midl2, inl, leafprgkeys[2].k, aes_ops);
  84. AES_ECB_encrypt(midr2, inr, leafprgkeys[2].k, aes_ops);
  85. }
  86. left[0] = midl0 ^ inl;
  87. right[0] = midr0 ^ inr;
  88. if (LWIDTH > 1) {
  89. left[1] = midl1 ^ inl;
  90. right[1] = midr1 ^ inr;
  91. }
  92. if (LWIDTH > 2) {
  93. left[2] = midl2 ^ inl;
  94. right[2] = midr2 ^ inr;
  95. }
  96. }
  97. #endif