salsa20_xmm6int-avx2.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. #include <stdint.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "crypto_stream_salsa20.h"
  5. #include "private/common.h"
  6. #include "private/sse2_64_32.h"
  7. #include "utils.h"
  8. #if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \
  9. defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H)
  10. # ifdef __GNUC__
  11. # pragma GCC target("sse2")
  12. # pragma GCC target("ssse3")
  13. # pragma GCC target("sse4.1")
  14. # pragma GCC target("avx2")
  15. # endif
  16. #include <emmintrin.h>
  17. #include <immintrin.h>
  18. #include <smmintrin.h>
  19. #include <tmmintrin.h>
  20. # include "../stream_salsa20.h"
  21. # include "salsa20_xmm6int-avx2.h"
  22. # define ROUNDS 20
  23. typedef struct salsa_ctx {
  24. uint32_t input[16];
  25. } salsa_ctx;
  26. static const int TR[16] = {
  27. 0, 5, 10, 15, 12, 1, 6, 11, 8, 13, 2, 7, 4, 9, 14, 3
  28. };
  29. static void
  30. salsa_keysetup(salsa_ctx *ctx, const uint8_t *k)
  31. {
  32. ctx->input[TR[1]] = LOAD32_LE(k + 0);
  33. ctx->input[TR[2]] = LOAD32_LE(k + 4);
  34. ctx->input[TR[3]] = LOAD32_LE(k + 8);
  35. ctx->input[TR[4]] = LOAD32_LE(k + 12);
  36. ctx->input[TR[11]] = LOAD32_LE(k + 16);
  37. ctx->input[TR[12]] = LOAD32_LE(k + 20);
  38. ctx->input[TR[13]] = LOAD32_LE(k + 24);
  39. ctx->input[TR[14]] = LOAD32_LE(k + 28);
  40. ctx->input[TR[0]] = 0x61707865;
  41. ctx->input[TR[5]] = 0x3320646e;
  42. ctx->input[TR[10]] = 0x79622d32;
  43. ctx->input[TR[15]] = 0x6b206574;
  44. }
  45. static void
  46. salsa_ivsetup(salsa_ctx *ctx, const uint8_t *iv, const uint8_t *counter)
  47. {
  48. ctx->input[TR[6]] = LOAD32_LE(iv + 0);
  49. ctx->input[TR[7]] = LOAD32_LE(iv + 4);
  50. ctx->input[TR[8]] = counter == NULL ? 0 : LOAD32_LE(counter + 0);
  51. ctx->input[TR[9]] = counter == NULL ? 0 : LOAD32_LE(counter + 4);
  52. }
  53. static void
  54. salsa20_encrypt_bytes(salsa_ctx *ctx, const uint8_t *m, uint8_t *c,
  55. unsigned long long bytes)
  56. {
  57. uint32_t * const x = &ctx->input[0];
  58. if (!bytes) {
  59. return; /* LCOV_EXCL_LINE */
  60. }
  61. #include "u8.h"
  62. #include "u4.h"
  63. #include "u1.h"
  64. #include "u0.h"
  65. }
  66. static int
  67. stream_avx2(unsigned char *c, unsigned long long clen, const unsigned char *n,
  68. const unsigned char *k)
  69. {
  70. struct salsa_ctx ctx;
  71. if (!clen) {
  72. return 0;
  73. }
  74. COMPILER_ASSERT(crypto_stream_salsa20_KEYBYTES == 256 / 8);
  75. salsa_keysetup(&ctx, k);
  76. salsa_ivsetup(&ctx, n, NULL);
  77. memset(c, 0, clen);
  78. salsa20_encrypt_bytes(&ctx, c, c, clen);
  79. sodium_memzero(&ctx, sizeof ctx);
  80. return 0;
  81. }
  82. static int
  83. stream_avx2_xor_ic(unsigned char *c, const unsigned char *m,
  84. unsigned long long mlen, const unsigned char *n, uint64_t ic,
  85. const unsigned char *k)
  86. {
  87. struct salsa_ctx ctx;
  88. uint8_t ic_bytes[8];
  89. uint32_t ic_high;
  90. uint32_t ic_low;
  91. if (!mlen) {
  92. return 0;
  93. }
  94. ic_high = (uint32_t) (ic >> 32);
  95. ic_low = (uint32_t) ic;
  96. STORE32_LE(&ic_bytes[0], ic_low);
  97. STORE32_LE(&ic_bytes[4], ic_high);
  98. salsa_keysetup(&ctx, k);
  99. salsa_ivsetup(&ctx, n, ic_bytes);
  100. salsa20_encrypt_bytes(&ctx, m, c, mlen);
  101. sodium_memzero(&ctx, sizeof ctx);
  102. return 0;
  103. }
  104. struct crypto_stream_salsa20_implementation
  105. crypto_stream_salsa20_xmm6int_avx2_implementation = {
  106. SODIUM_C99(.stream =) stream_avx2,
  107. SODIUM_C99(.stream_xor_ic =) stream_avx2_xor_ic
  108. };
  109. #endif