MCKL
Monte Carlo Kernel Library
aes_aesni_common.hpp
Go to the documentation of this file.
1 //============================================================================
2 // MCKL/include/mckl/random/internal/aes_aesni_common.hpp
3 //----------------------------------------------------------------------------
4 // MCKL: Monte Carlo Kernel Library
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013-2018, Yan Zhou
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // Redistributions of source code must retain the above copyright notice,
13 // this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright notice,
16 // this list of conditions and the following disclaimer in the documentation
17 // and/or other materials provided with the distribution.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 // POSSIBILITY OF SUCH DAMAGE.
30 //============================================================================
31 
32 #ifndef MCKL_RANDOM_INTERNAL_AES_AESNI_COMMON_HPP
33 #define MCKL_RANDOM_INTERNAL_AES_AESNI_COMMON_HPP
34 
35 #define MCKL_RANDOM_INTERNAL_AES_AESNI_ENCFIRST(xmmk) \
36  xmm0 = _mm_xor_si128(xmm0, xmmk); \
37  xmm1 = _mm_xor_si128(xmm1, xmmk); \
38  xmm2 = _mm_xor_si128(xmm2, xmmk); \
39  xmm3 = _mm_xor_si128(xmm3, xmmk); \
40  xmm4 = _mm_xor_si128(xmm4, xmmk); \
41  xmm5 = _mm_xor_si128(xmm5, xmmk); \
42  xmm6 = _mm_xor_si128(xmm6, xmmk); \
43  xmm7 = _mm_xor_si128(xmm7, xmmk);
44 
45 #define MCKL_RANDOM_INTERNAL_AES_AESNI_ENC(xmmk) \
46  xmm0 = _mm_aesenc_si128(xmm0, xmmk); \
47  xmm1 = _mm_aesenc_si128(xmm1, xmmk); \
48  xmm2 = _mm_aesenc_si128(xmm2, xmmk); \
49  xmm3 = _mm_aesenc_si128(xmm3, xmmk); \
50  xmm4 = _mm_aesenc_si128(xmm4, xmmk); \
51  xmm5 = _mm_aesenc_si128(xmm5, xmmk); \
52  xmm6 = _mm_aesenc_si128(xmm6, xmmk); \
53  xmm7 = _mm_aesenc_si128(xmm7, xmmk);
54 
55 #define MCKL_RANDOM_INTERNAL_AES_AESNI_ENCLAST(xmmk) \
56  xmm0 = _mm_aesenclast_si128(xmm0, xmmk); \
57  xmm1 = _mm_aesenclast_si128(xmm1, xmmk); \
58  xmm2 = _mm_aesenclast_si128(xmm2, xmmk); \
59  xmm3 = _mm_aesenclast_si128(xmm3, xmmk); \
60  xmm4 = _mm_aesenclast_si128(xmm4, xmmk); \
61  xmm5 = _mm_aesenclast_si128(xmm5, xmmk); \
62  xmm6 = _mm_aesenclast_si128(xmm6, xmmk); \
63  xmm7 = _mm_aesenclast_si128(xmm7, xmmk);
64 
65 #define MCKL_RANDOM_INTERNAL_AES_AESNI_ENCFIRST_MEM(k) \
66  { \
67  const __m128i xmmk = k; \
68  xmm0 = _mm_xor_si128(xmm0, xmmk); \
69  xmm1 = _mm_xor_si128(xmm1, xmmk); \
70  xmm2 = _mm_xor_si128(xmm2, xmmk); \
71  xmm3 = _mm_xor_si128(xmm3, xmmk); \
72  xmm4 = _mm_xor_si128(xmm4, xmmk); \
73  xmm5 = _mm_xor_si128(xmm5, xmmk); \
74  xmm6 = _mm_xor_si128(xmm6, xmmk); \
75  xmm7 = _mm_xor_si128(xmm7, xmmk); \
76  }
77 
78 #define MCKL_RANDOM_INTERNAL_AES_AESNI_ENC_MEM(k) \
79  { \
80  const __m128i xmmk = k; \
81  xmm0 = _mm_aesenc_si128(xmm0, xmmk); \
82  xmm1 = _mm_aesenc_si128(xmm1, xmmk); \
83  xmm2 = _mm_aesenc_si128(xmm2, xmmk); \
84  xmm3 = _mm_aesenc_si128(xmm3, xmmk); \
85  xmm4 = _mm_aesenc_si128(xmm4, xmmk); \
86  xmm5 = _mm_aesenc_si128(xmm5, xmmk); \
87  xmm6 = _mm_aesenc_si128(xmm6, xmmk); \
88  xmm7 = _mm_aesenc_si128(xmm7, xmmk); \
89  }
90 
91 #define MCKL_RANDOM_INTERNAL_AES_AESNI_ENCLAST_MEM(k) \
92  { \
93  const __m128i xmmk = k; \
94  xmm0 = _mm_aesenclast_si128(xmm0, xmmk); \
95  xmm1 = _mm_aesenclast_si128(xmm1, xmmk); \
96  xmm2 = _mm_aesenclast_si128(xmm2, xmmk); \
97  xmm3 = _mm_aesenclast_si128(xmm3, xmmk); \
98  xmm4 = _mm_aesenclast_si128(xmm4, xmmk); \
99  xmm5 = _mm_aesenclast_si128(xmm5, xmmk); \
100  xmm6 = _mm_aesenclast_si128(xmm6, xmmk); \
101  xmm7 = _mm_aesenclast_si128(xmm7, xmmk); \
102  }
103 
104 #define MCKL_RANDOM_INTERNAL_AES_AESNI_EVAL \
105  template <typename ResultType> \
106  static void eval(std::array<std::uint64_t, 2> &ctr, std::size_t n, \
107  ResultType *r, const KeySeqType &ks) \
108  { \
109  constexpr std::size_t R = sizeof(__m128i) / sizeof(ResultType); \
110  \
111  const std::size_t n0 = \
112  static_cast<std::size_t>(std::min(static_cast<std::uint64_t>(n), \
113  std::numeric_limits<std::uint64_t>::max() - ctr.front())); \
114  \
115  eval_kernel(ctr, n0, r, ks); \
116  n -= n0; \
117  r += n0 * R; \
118  \
119  if (n != 0) { \
120  eval(ctr, r, ks); \
121  n -= 1; \
122  r += R; \
123  } \
124  \
125  eval_kernel(ctr, n, r, ks); \
126  }
127 
128 #define MCKL_RANDOM_INTERNAL_AES_AESNI_STORE(n, N, rptr) \
129  if (n >= N) { \
130  n -= N; \
131  _mm_storeu_si128(rptr++, xmm0); \
132  _mm_storeu_si128(rptr++, xmm1); \
133  _mm_storeu_si128(rptr++, xmm2); \
134  _mm_storeu_si128(rptr++, xmm3); \
135  _mm_storeu_si128(rptr++, xmm4); \
136  _mm_storeu_si128(rptr++, xmm5); \
137  _mm_storeu_si128(rptr++, xmm6); \
138  _mm_storeu_si128(rptr++, xmm7); \
139  } else { \
140  std::array<__m128i, S> s; \
141  std::get<0>(s) = xmm0; \
142  std::get<1>(s) = xmm1; \
143  std::get<2>(s) = xmm2; \
144  std::get<3>(s) = xmm3; \
145  std::get<4>(s) = xmm4; \
146  std::get<5>(s) = xmm5; \
147  std::get<6>(s) = xmm6; \
148  std::get<7>(s) = xmm7; \
149  std::memcpy(rptr, s.data(), n * sizeof(__m128i)); \
150  break; \
151  }
152 
153 #endif // MCKL_RANDOM_INTERNAL_AES_AESNI_COMMON_HPP