blamka-round-avx512f.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #ifndef blamka_round_avx512f_H
  2. #define blamka_round_avx512f_H
  3. #include "private/common.h"
  4. #include "private/sse2_64_32.h"
  5. #define ror64(x, n) _mm512_ror_epi64((x), (n))
  6. static inline __m512i
  7. muladd(__m512i x, __m512i y)
  8. {
  9. __m512i z = _mm512_mul_epu32(x, y);
  10. return _mm512_add_epi64(_mm512_add_epi64(x, y), _mm512_add_epi64(z, z));
  11. }
  12. #define G1_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1) \
  13. do { \
  14. A0 = muladd(A0, B0); \
  15. A1 = muladd(A1, B1); \
  16. \
  17. D0 = _mm512_xor_si512(D0, A0); \
  18. D1 = _mm512_xor_si512(D1, A1); \
  19. \
  20. D0 = ror64(D0, 32); \
  21. D1 = ror64(D1, 32); \
  22. \
  23. C0 = muladd(C0, D0); \
  24. C1 = muladd(C1, D1); \
  25. \
  26. B0 = _mm512_xor_si512(B0, C0); \
  27. B1 = _mm512_xor_si512(B1, C1); \
  28. \
  29. B0 = ror64(B0, 24); \
  30. B1 = ror64(B1, 24); \
  31. } while ((void)0, 0)
  32. #define G2_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1) \
  33. do { \
  34. A0 = muladd(A0, B0); \
  35. A1 = muladd(A1, B1); \
  36. \
  37. D0 = _mm512_xor_si512(D0, A0); \
  38. D1 = _mm512_xor_si512(D1, A1); \
  39. \
  40. D0 = ror64(D0, 16); \
  41. D1 = ror64(D1, 16); \
  42. \
  43. C0 = muladd(C0, D0); \
  44. C1 = muladd(C1, D1); \
  45. \
  46. B0 = _mm512_xor_si512(B0, C0); \
  47. B1 = _mm512_xor_si512(B1, C1); \
  48. \
  49. B0 = ror64(B0, 63); \
  50. B1 = ror64(B1, 63); \
  51. } while ((void)0, 0)
  52. #define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
  53. do { \
  54. B0 = _mm512_permutex_epi64(B0, _MM_SHUFFLE(0, 3, 2, 1)); \
  55. B1 = _mm512_permutex_epi64(B1, _MM_SHUFFLE(0, 3, 2, 1)); \
  56. \
  57. C0 = _mm512_permutex_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \
  58. C1 = _mm512_permutex_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \
  59. \
  60. D0 = _mm512_permutex_epi64(D0, _MM_SHUFFLE(2, 1, 0, 3)); \
  61. D1 = _mm512_permutex_epi64(D1, _MM_SHUFFLE(2, 1, 0, 3)); \
  62. } while ((void)0, 0)
  63. #define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
  64. do { \
  65. B0 = _mm512_permutex_epi64(B0, _MM_SHUFFLE(2, 1, 0, 3)); \
  66. B1 = _mm512_permutex_epi64(B1, _MM_SHUFFLE(2, 1, 0, 3)); \
  67. \
  68. C0 = _mm512_permutex_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \
  69. C1 = _mm512_permutex_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \
  70. \
  71. D0 = _mm512_permutex_epi64(D0, _MM_SHUFFLE(0, 3, 2, 1)); \
  72. D1 = _mm512_permutex_epi64(D1, _MM_SHUFFLE(0, 3, 2, 1)); \
  73. } while ((void)0, 0)
  74. #define BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1) \
  75. do { \
  76. G1_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1); \
  77. G2_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1); \
  78. \
  79. DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
  80. \
  81. G1_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1); \
  82. G2_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1); \
  83. \
  84. UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \
  85. } while ((void)0, 0)
  86. #define SWAP_HALVES(A0, A1) \
  87. do { \
  88. __m512i t0, t1; \
  89. t0 = _mm512_shuffle_i64x2(A0, A1, _MM_SHUFFLE(1, 0, 1, 0)); \
  90. t1 = _mm512_shuffle_i64x2(A0, A1, _MM_SHUFFLE(3, 2, 3, 2)); \
  91. A0 = t0; \
  92. A1 = t1; \
  93. } while((void)0, 0)
  94. #define SWAP_QUARTERS(A0, A1) \
  95. do { \
  96. SWAP_HALVES(A0, A1); \
  97. A0 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A0); \
  98. A1 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A1); \
  99. } while((void)0, 0)
  100. #define UNSWAP_QUARTERS(A0, A1) \
  101. do { \
  102. A0 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A0); \
  103. A1 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A1); \
  104. SWAP_HALVES(A0, A1); \
  105. } while((void)0, 0)
  106. #define BLAKE2_ROUND_1(A0, C0, B0, D0, A1, C1, B1, D1) \
  107. do { \
  108. SWAP_HALVES(A0, B0); \
  109. SWAP_HALVES(C0, D0); \
  110. SWAP_HALVES(A1, B1); \
  111. SWAP_HALVES(C1, D1); \
  112. BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1); \
  113. SWAP_HALVES(A0, B0); \
  114. SWAP_HALVES(C0, D0); \
  115. SWAP_HALVES(A1, B1); \
  116. SWAP_HALVES(C1, D1); \
  117. } while ((void)0, 0)
  118. #define BLAKE2_ROUND_2(A0, A1, B0, B1, C0, C1, D0, D1) \
  119. do { \
  120. SWAP_QUARTERS(A0, A1); \
  121. SWAP_QUARTERS(B0, B1); \
  122. SWAP_QUARTERS(C0, C1); \
  123. SWAP_QUARTERS(D0, D1); \
  124. BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1); \
  125. UNSWAP_QUARTERS(A0, A1); \
  126. UNSWAP_QUARTERS(B0, B1); \
  127. UNSWAP_QUARTERS(C0, C1); \
  128. UNSWAP_QUARTERS(D0, D1); \
  129. } while ((void)0, 0)
  130. #endif