/search.css" rel="stylesheet" type="text/css"/> /search.js">
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
aes.h
Go to the documentation of this file.
1 /*
2 Copyright 2010-2011, D. E. Shaw Research.
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8 
9 * Redistributions of source code must retain the above copyright
10  notice, this list of conditions, and the following disclaimer.
11 
12 * Redistributions in binary form must reproduce the above copyright
13  notice, this list of conditions, and the following disclaimer in the
14  documentation and/or other materials provided with the distribution.
15 
16 * Neither the name of D. E. Shaw Research nor the names of its
17  contributors may be used to endorse or promote products derived from
18  this software without specific prior written permission.
19 
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 #ifndef __Random123_aes_dot_hpp__
33 #define __Random123_aes_dot_hpp__
34 
36 #include "array.h"
37 #include "string.h"
38 
39 /* Implement a bona fide AES block cipher. It's minimally
40 // checked against the test vector in FIPS-197 in ut_aes.cpp. */
41 #if R123_USE_AES_NI
42 
44 typedef struct r123array1xm128i aesni1xm128i_ctr_t;
46 typedef struct r123array1xm128i aesni1xm128i_ukey_t;
48 typedef struct r123array4x32 aesni4x32_ukey_t;
51 
53 R123_STATIC_INLINE __m128i AES_128_ASSIST (__m128i temp1, __m128i temp2) {
54  __m128i temp3;
55  temp2 = _mm_shuffle_epi32 (temp2 ,0xff);
56  temp3 = _mm_slli_si128 (temp1, 0x4);
57  temp1 = _mm_xor_si128 (temp1, temp3);
58  temp3 = _mm_slli_si128 (temp3, 0x4);
59  temp1 = _mm_xor_si128 (temp1, temp3);
60  temp3 = _mm_slli_si128 (temp3, 0x4);
61  temp1 = _mm_xor_si128 (temp1, temp3);
62  temp1 = _mm_xor_si128 (temp1, temp2);
63  return temp1;
64 }
65 
66 R123_STATIC_INLINE void aesni1xm128iexpand(aesni1xm128i_ukey_t uk, __m128i ret[11])
67 {
68  __m128i rkey = uk.v[0].m;
69  __m128i tmp2;
70 
71  ret[0] = rkey;
72  tmp2 = _mm_aeskeygenassist_si128(rkey, 0x1);
73  rkey = AES_128_ASSIST(rkey, tmp2);
74  ret[1] = rkey;
75 
76  tmp2 = _mm_aeskeygenassist_si128(rkey, 0x2);
77  rkey = AES_128_ASSIST(rkey, tmp2);
78  ret[2] = rkey;
79 
80  tmp2 = _mm_aeskeygenassist_si128(rkey, 0x4);
81  rkey = AES_128_ASSIST(rkey, tmp2);
82  ret[3] = rkey;
83 
84  tmp2 = _mm_aeskeygenassist_si128(rkey, 0x8);
85  rkey = AES_128_ASSIST(rkey, tmp2);
86  ret[4] = rkey;
87 
88  tmp2 = _mm_aeskeygenassist_si128(rkey, 0x10);
89  rkey = AES_128_ASSIST(rkey, tmp2);
90  ret[5] = rkey;
91 
92  tmp2 = _mm_aeskeygenassist_si128(rkey, 0x20);
93  rkey = AES_128_ASSIST(rkey, tmp2);
94  ret[6] = rkey;
95 
96  tmp2 = _mm_aeskeygenassist_si128(rkey, 0x40);
97  rkey = AES_128_ASSIST(rkey, tmp2);
98  ret[7] = rkey;
99 
100  tmp2 = _mm_aeskeygenassist_si128(rkey, 0x80);
101  rkey = AES_128_ASSIST(rkey, tmp2);
102  ret[8] = rkey;
103 
104  tmp2 = _mm_aeskeygenassist_si128(rkey, 0x1b);
105  rkey = AES_128_ASSIST(rkey, tmp2);
106  ret[9] = rkey;
107 
108  tmp2 = _mm_aeskeygenassist_si128(rkey, 0x36);
109  rkey = AES_128_ASSIST(rkey, tmp2);
110  ret[10] = rkey;
111 }
114 #ifdef __cplusplus
115 
117  __m128i k[11];
120  uk.v[0].m = _mm_setzero_si128();
121  aesni1xm128iexpand(uk, k);
122  }
124  aesni1xm128iexpand(uk, k);
125  }
127  aesni1xm128i_ukey_t uk128;
128  uk128.v[0].m = _mm_set_epi32(uk.v[3], uk.v[2], uk.v[1], uk.v[0]);
129  aesni1xm128iexpand(uk128, k);
130  }
132  aesni1xm128iexpand(uk, k);
133  return *this;
134  }
136  aesni1xm128i_ukey_t uk128;
137  uk128.v[0].m = _mm_set_epi32(uk.v[3], uk.v[2], uk.v[1], uk.v[0]);
138  aesni1xm128iexpand(uk128, k);
139  return *this;
140  }
141  bool operator==(const aesni1xm128i_key_t& rhs) const{
142  for(int i=0; i<11; ++i){
143  // Sigh... No r123m128i(__m128i) constructor!
144  r123m128i li; li.m = k[i];
145  r123m128i ri; ri.m = rhs.k[i];
146  if( li != ri ) return false;
147  }
148  return true;
149  }
150  bool operator!=(const aesni1xm128i_key_t& rhs) const{
151  return !(*this == rhs);
152  }
153  friend std::ostream& operator<<(std::ostream& os, const aesni1xm128i_key_t& v){
154  r123m128i ki;
155  for(int i=0; i<10; ++i){
156  ki.m = v.k[i];
157  os << ki << " ";
158  }
159  ki.m = v.k[10];
160  return os << ki;
161  }
162  friend std::istream& operator>>(std::istream& is, aesni1xm128i_key_t& v){
163  r123m128i ki;
164  for(int i=0; i<11; ++i){
165  is >> ki;
166  v.k[i] = ki;
167  }
168  return is;
169  }
170 };
171 #else
172 typedef struct {
173  __m128i k[11];
175 
177 R123_STATIC_INLINE aesni1xm128i_key_t aesni1xm128ikeyinit(aesni1xm128i_ukey_t uk){
178  aesni1xm128i_key_t ret;
179  aesni1xm128iexpand(uk, ret.k);
180  return ret;
181 }
182 #endif
183 
186  __m128i x = _mm_xor_si128(k.k[0], in.v[0].m);
187  x = _mm_aesenc_si128(x, k.k[1]);
188  x = _mm_aesenc_si128(x, k.k[2]);
189  x = _mm_aesenc_si128(x, k.k[3]);
190  x = _mm_aesenc_si128(x, k.k[4]);
191  x = _mm_aesenc_si128(x, k.k[5]);
192  x = _mm_aesenc_si128(x, k.k[6]);
193  x = _mm_aesenc_si128(x, k.k[7]);
194  x = _mm_aesenc_si128(x, k.k[8]);
195  x = _mm_aesenc_si128(x, k.k[9]);
196  x = _mm_aesenclast_si128(x, k.k[10]);
197  {
198  aesni1xm128i_ctr_t ret;
199  ret.v[0].m = x;
200  return ret;
201  }
202 }
203 
206  R123_ASSERT(R==10);
207  return aesni1xm128i(in, k);
208 }
209 
210 
212 typedef struct r123array4x32 aesni4x32_ctr_t;
219  aesni1xm128i_ukey_t uk128;
220  aesni4x32_key_t ret;
221  uk128.v[0].m = _mm_set_epi32(uk.v[3], uk.v[2], uk.v[1], uk.v[0]);
222  aesni1xm128iexpand(uk128, ret.k);
223  return ret;
224 }
225 
228 R123_STATIC_INLINE aesni4x32_ctr_t aesni4x32_R(unsigned int Nrounds, aesni4x32_ctr_t c, aesni4x32_key_t k){
229  aesni1xm128i_ctr_t c128;
230  c128.v[0].m = _mm_set_epi32(c.v[3], c.v[2], c.v[1], c.v[0]);
231  c128 = aesni1xm128i_R(Nrounds, c128, k);
232  _mm_storeu_si128((__m128i*)&c.v[0], c128.v[0].m);
233  return c;
234 }
235 
236 #define aesni4x32_rounds aesni1xm128i_rounds
237 
240 #define aesni4x32(c,k) aesni4x32_R(aesni4x32_rounds, c, k)
241 
242 #ifdef __cplusplus
243 namespace r123{
279  static const unsigned int rounds=10;
281  return aesni1xm128i(ctr, key);
282  }
283 };
284 
285 /* @class AESNI4x32 */
286 struct AESNI4x32{
290  static const unsigned int rounds=10;
292  return aesni4x32(ctr, key);
293  }
294 };
295 
301 template <unsigned ROUNDS=10>
302 struct AESNI1xm128i_R : public AESNI1xm128i{
303  R123_STATIC_ASSERT(ROUNDS==10, "AESNI1xm128i_R<R> is only valid with R=10");
304 };
305 
307 template <unsigned ROUNDS=10>
308 struct AESNI4x32_R : public AESNI4x32{
309  R123_STATIC_ASSERT(ROUNDS==10, "AESNI4x32_R<R> is only valid with R=10");
310 };
311 } // namespace r123
312 #endif /* __cplusplus */
313 
314 #endif /* R123_USE_AES_NI */
315 
316 #if R123_USE_AES_OPENSSL
317 #include <openssl/aes.h>
318 typedef struct r123array16x8 aesopenssl16x8_ctr_t;
319 typedef struct r123array16x8 aesopenssl16x8_ukey_t;
320 #ifdef __cplusplus
321 struct aesopenssl16x8_key_t{
322  AES_KEY k;
323  aesopenssl16x8_key_t(){
324  aesopenssl16x8_ukey_t ukey={{}};
325  AES_set_encrypt_key((const unsigned char *)&ukey.v[0], 128, &k);
326  }
327  aesopenssl16x8_key_t(const aesopenssl16x8_ukey_t& ukey){
328  AES_set_encrypt_key((const unsigned char *)&ukey.v[0], 128, &k);
329  }
330  aesopenssl16x8_key_t& operator=(const aesopenssl16x8_ukey_t& ukey){
331  AES_set_encrypt_key((const unsigned char *)&ukey.v[0], 128, &k);
332  return *this;
333  }
334  bool operator==(const aesopenssl16x8_key_t& rhs) const{
335  return (k.rounds == rhs.k.rounds) && 0==::memcmp(&k.rd_key[0], &rhs.k.rd_key[0], (k.rounds+1) * 4 * sizeof(uint32_t));
336  }
337  bool operator!=(const aesopenssl16x8_key_t& rhs) const{
338  return !(*this == rhs);
339  }
340  friend std::ostream& operator<<(std::ostream& os, const aesopenssl16x8_key_t& v){
341  os << v.k.rounds;
342  const unsigned int *p = &v.k.rd_key[0];
343  for(int i=0; i<(v.k.rounds+1); ++i){
344  os << " " << p[0] << " " << p[1] << " " << p[2] << " " << p[3];
345  p += 4;
346  }
347  return os;
348  }
349  friend std::istream& operator>>(std::istream& is, aesopenssl16x8_key_t& v){
350  is >> v.k.rounds;
351  unsigned int *p = &v.k.rd_key[0];
352  for(int i=0; i<(v.k.rounds+1); ++i){
353  is >> p[0] >> p[1] >> p[2] >> p[3];
354  p += 4;
355  }
356  return is;
357  }
358 };
359 #else
360 typedef struct aesopenssl16x8_key_t{
361  AES_KEY k;
362 }aesopenssl16x8_key_t;
363 R123_STATIC_INLINE struct aesopenssl16x8_key_t aesopenssl16x8keyinit(aesopenssl16x8_ukey_t uk){
364  aesopenssl16x8_key_t ret;
365  AES_set_encrypt_key((const unsigned char *)&uk.v[0], 128, &ret.k);
366  return ret;
367 }
368 #endif
369 
370 R123_STATIC_INLINE R123_FORCE_INLINE(aesopenssl16x8_ctr_t aesopenssl16x8_R(aesopenssl16x8_ctr_t ctr, aesopenssl16x8_key_t key));
371 R123_STATIC_INLINE
372 aesopenssl16x8_ctr_t aesopenssl16x8_R(aesopenssl16x8_ctr_t ctr, aesopenssl16x8_key_t key){
373  aesopenssl16x8_ctr_t ret;
374  AES_encrypt((const unsigned char*)&ctr.v[0], (unsigned char *)&ret.v[0], &key.k);
375  return ret;
376 }
377 
378 #define aesopenssl16x8_rounds aesni4x32_rounds
379 #define aesopenssl16x8(c,k) aesopenssl16x8_R(aesopenssl16x8_rounds)
380 
381 #ifdef __cplusplus
382 namespace r123{
383 struct AESOpenSSL16x8{
384  typedef aesopenssl16x8_ctr_t ctr_type;
385  typedef aesopenssl16x8_key_t key_type;
386  typedef aesopenssl16x8_ukey_t ukey_type;
387  static const unsigned int rounds=10;
388  ctr_type operator()(const ctr_type& in, const key_type& k){
389  ctr_type out;
390  AES_encrypt((const unsigned char *)&in[0], (unsigned char *)&out[0], &k.k);
391  return out;
392  }
393 };
394 } // namespace r123
395 #endif /* __cplusplus */
396 #endif /* R123_USE_AES_OPENSSL */
397 
398 #endif
static std::ostream & operator<<(std::ostream &os, const r123m128i &m)
Definition: sse.h:241
r123_enum_aesni4x32
Definition: aes.h:216
aesni1xm128i_key_t & operator=(const aesni1xm128i_ukey_t &uk)
Definition: aes.h:131
__m128i k[11]
Definition: aes.h:117
static bool operator==(const r123m128i &lhs, const r123m128i &rhs)
Definition: sse.h:233
Definition: aes.h:116
struct r123array4x32 aesni4x32_ukey_t
Definition: aes.h:48
static aesni1xm128i_ctr_t aesni1xm128i(aesni1xm128i_ctr_t in, aesni1xm128i_key_t k)
Definition: aes.h:185
aesni1xm128i_key_t aesni4x32_key_t
Definition: aes.h:214
#define aesni4x32_rounds
Definition: aes.h:236
bool operator!=(const aesni1xm128i_key_t &rhs) const
Definition: aes.h:150
aesni4x32_key_t key_type
Definition: aes.h:289
aesni1xm128i_key_t(const aesni1xm128i_ukey_t &uk)
Definition: aes.h:123
static bool operator!=(const r123m128i &lhs, const r123m128i &rhs)
Definition: sse.h:235
static std::istream & operator>>(std::istream &is, r123m128i &m)
Definition: sse.h:250
Definition: sse.h:148
Definition: aes.h:302
aesni1xm128i_key_t & operator=(const aesni4x32_ukey_t &uk)
Definition: aes.h:135
static const unsigned int rounds
Definition: aes.h:290
aesni4x32_ctr_t ctr_type
Definition: aes.h:287
static aesni4x32_key_t aesni4x32keyinit(aesni4x32_ukey_t uk)
Definition: aes.h:218
aesni1xm128i_key_t key_type
Definition: aes.h:278
ctr_type operator()(ctr_type ctr, key_type key) const
Definition: aes.h:291
friend std::ostream & operator<<(std::ostream &os, const aesni1xm128i_key_t &v)
Definition: aes.h:153
struct r123array1xm128i aesni1xm128i_ukey_t
Definition: aes.h:46
bool operator==(const aesni1xm128i_key_t &rhs) const
Definition: aes.h:141
struct r123array4x32 aesni4x32_ctr_t
Definition: aes.h:212
Definition: aes.h:308
struct r123array1xm128i aesni1xm128i_ctr_t
Definition: aes.h:44
static aesni1xm128i_ctr_t aesni1xm128i_R(unsigned R, aesni1xm128i_ctr_t in, aesni1xm128i_key_t k)
Definition: aes.h:205
aesni1xm128i_ukey_t ukey_type
Definition: aes.h:277
aesni1xm128i_ctr_t ctr_type
Definition: aes.h:276
Definition: aes.h:50
friend std::istream & operator>>(std::istream &is, aesni1xm128i_key_t &v)
Definition: aes.h:162
aesni1xm128i_key_t(const aesni4x32_ukey_t &uk)
Definition: aes.h:126
#define aesni4x32(c, k)
Definition: aes.h:240
Definition: aes.h:286
ctr_type operator()(ctr_type ctr, key_type key) const
Definition: aes.h:280
static const unsigned int rounds
Definition: aes.h:279
aesni1xm128i_key_t()
Definition: aes.h:118
static aesni4x32_ctr_t aesni4x32_R(unsigned int Nrounds, aesni4x32_ctr_t c, aesni4x32_key_t k)
Definition: aes.h:228
aesni4x32_ukey_t ukey_type
Definition: aes.h:288
Definition: aes.h:275
r123_enum_aesni1xm128i
Definition: aes.h:50
__m128i m
Definition: sse.h:149