00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef __Random123_aes_dot_hpp__
00033 #define __Random123_aes_dot_hpp__
00034
00035 #include "features/compilerfeatures.h"
00036 #include "array.h"
00037
00038
00039
00040 #if R123_USE_AES_NI
00041
00043 typedef struct r123array1xm128i aesni1xm128i_ctr_t;
00045 typedef struct r123array1xm128i aesni1xm128i_ukey_t;
00047 typedef struct r123array4x32 aesni4x32_ukey_t;
00049 enum { aesni1xm128i_rounds = 10 };
00050
00052 R123_STATIC_INLINE __m128i AES_128_ASSIST (__m128i temp1, __m128i temp2) {
00053 __m128i temp3;
00054 temp2 = _mm_shuffle_epi32 (temp2 ,0xff);
00055 temp3 = _mm_slli_si128 (temp1, 0x4);
00056 temp1 = _mm_xor_si128 (temp1, temp3);
00057 temp3 = _mm_slli_si128 (temp3, 0x4);
00058 temp1 = _mm_xor_si128 (temp1, temp3);
00059 temp3 = _mm_slli_si128 (temp3, 0x4);
00060 temp1 = _mm_xor_si128 (temp1, temp3);
00061 temp1 = _mm_xor_si128 (temp1, temp2);
00062 return temp1;
00063 }
00064
00065 R123_STATIC_INLINE void aesni1xm128iexpand(aesni1xm128i_ukey_t uk, __m128i ret[11])
00066 {
00067 __m128i rkey = uk.v[0].m;
00068 __m128i tmp2;
00069
00070 ret[0] = rkey;
00071 tmp2 = _mm_aeskeygenassist_si128(rkey, 0x1);
00072 rkey = AES_128_ASSIST(rkey, tmp2);
00073 ret[1] = rkey;
00074
00075 tmp2 = _mm_aeskeygenassist_si128(rkey, 0x2);
00076 rkey = AES_128_ASSIST(rkey, tmp2);
00077 ret[2] = rkey;
00078
00079 tmp2 = _mm_aeskeygenassist_si128(rkey, 0x4);
00080 rkey = AES_128_ASSIST(rkey, tmp2);
00081 ret[3] = rkey;
00082
00083 tmp2 = _mm_aeskeygenassist_si128(rkey, 0x8);
00084 rkey = AES_128_ASSIST(rkey, tmp2);
00085 ret[4] = rkey;
00086
00087 tmp2 = _mm_aeskeygenassist_si128(rkey, 0x10);
00088 rkey = AES_128_ASSIST(rkey, tmp2);
00089 ret[5] = rkey;
00090
00091 tmp2 = _mm_aeskeygenassist_si128(rkey, 0x20);
00092 rkey = AES_128_ASSIST(rkey, tmp2);
00093 ret[6] = rkey;
00094
00095 tmp2 = _mm_aeskeygenassist_si128(rkey, 0x40);
00096 rkey = AES_128_ASSIST(rkey, tmp2);
00097 ret[7] = rkey;
00098
00099 tmp2 = _mm_aeskeygenassist_si128(rkey, 0x80);
00100 rkey = AES_128_ASSIST(rkey, tmp2);
00101 ret[8] = rkey;
00102
00103 tmp2 = _mm_aeskeygenassist_si128(rkey, 0x1b);
00104 rkey = AES_128_ASSIST(rkey, tmp2);
00105 ret[9] = rkey;
00106
00107 tmp2 = _mm_aeskeygenassist_si128(rkey, 0x36);
00108 rkey = AES_128_ASSIST(rkey, tmp2);
00109 ret[10] = rkey;
00110 }
00113 #ifdef __cplusplus
00114
00115 struct aesni1xm128i_key_t{
00116 __m128i k[11];
00117 aesni1xm128i_key_t(){
00118 aesni1xm128i_ukey_t uk;
00119 uk.v[0].m = _mm_setzero_si128();
00120 aesni1xm128iexpand(uk, k);
00121 }
00122 aesni1xm128i_key_t(const aesni1xm128i_ukey_t& uk){
00123 aesni1xm128iexpand(uk, k);
00124 }
00125 aesni1xm128i_key_t(const aesni4x32_ukey_t& uk){
00126 aesni1xm128i_ukey_t uk128;
00127 uk128.v[0].m = _mm_set_epi32(uk.v[3], uk.v[2], uk.v[1], uk.v[0]);
00128 aesni1xm128iexpand(uk128, k);
00129 }
00130 aesni1xm128i_key_t& operator=(const aesni1xm128i_ukey_t& uk){
00131 aesni1xm128iexpand(uk, k);
00132 return *this;
00133 }
00134 aesni1xm128i_key_t& operator=(const aesni4x32_ukey_t& uk){
00135 aesni1xm128i_ukey_t uk128;
00136 uk128.v[0].m = _mm_set_epi32(uk.v[3], uk.v[2], uk.v[1], uk.v[0]);
00137 aesni1xm128iexpand(uk128, k);
00138 return *this;
00139 }
00140 };
00141 #else
00142 typedef struct {
00143 __m128i k[11];
00144 }aesni1xm128i_key_t;
00145
00147 R123_STATIC_INLINE aesni1xm128i_key_t aesni1xm128ikeyinit(aesni1xm128i_ukey_t uk){
00148 aesni1xm128i_key_t ret;
00149 aesni1xm128iexpand(uk, ret.k);
00150 return ret;
00151 }
00152 #endif
00153
00155 R123_STATIC_INLINE aesni1xm128i_ctr_t aesni1xm128i(aesni1xm128i_ctr_t in, aesni1xm128i_key_t k) {
00156 __m128i x = _mm_xor_si128(k.k[0], in.v[0].m);
00157 x = _mm_aesenc_si128(x, k.k[1]);
00158 x = _mm_aesenc_si128(x, k.k[2]);
00159 x = _mm_aesenc_si128(x, k.k[3]);
00160 x = _mm_aesenc_si128(x, k.k[4]);
00161 x = _mm_aesenc_si128(x, k.k[5]);
00162 x = _mm_aesenc_si128(x, k.k[6]);
00163 x = _mm_aesenc_si128(x, k.k[7]);
00164 x = _mm_aesenc_si128(x, k.k[8]);
00165 x = _mm_aesenc_si128(x, k.k[9]);
00166 x = _mm_aesenclast_si128(x, k.k[10]);
00167 {
00168 aesni1xm128i_ctr_t ret;
00169 ret.v[0].m = x;
00170 return ret;
00171 }
00172 }
00173
00175 R123_STATIC_INLINE aesni1xm128i_ctr_t aesni1xm128i_R(unsigned R, aesni1xm128i_ctr_t in, aesni1xm128i_key_t k){
00176 R123_ASSERT(R==10);
00177 return aesni1xm128i(in, k);
00178 }
00179
00180
00182 typedef struct r123array4x32 aesni4x32_ctr_t;
00184 typedef aesni1xm128i_key_t aesni4x32_key_t;
00186 enum { aesni4x32_rounds = 10 };
00188 R123_STATIC_INLINE aesni4x32_key_t aesni4x32keyinit(aesni4x32_ukey_t uk){
00189 aesni1xm128i_ukey_t uk128;
00190 aesni4x32_key_t ret;
00191 uk128.v[0].m = _mm_set_epi32(uk.v[3], uk.v[2], uk.v[1], uk.v[0]);
00192 aesni1xm128iexpand(uk128, ret.k);
00193 return ret;
00194 }
00195
00198 R123_STATIC_INLINE aesni4x32_ctr_t aesni4x32_R(unsigned int Nrounds, aesni4x32_ctr_t c, aesni4x32_key_t k){
00199 aesni1xm128i_ctr_t c128;
00200 c128.v[0].m = _mm_set_epi32(c.v[3], c.v[2], c.v[1], c.v[0]);
00201 c128 = aesni1xm128i_R(Nrounds, c128, k);
00202 _mm_storeu_si128((__m128i*)&c.v[0], c128.v[0].m);
00203 return c;
00204 }
00205
00206 #define aesni4x32_rounds aesni1xm128i_rounds
00207
00210 #define aesni4x32(c,k) aesni4x32_R(aesni4x32_rounds, c, k)
00211
00212 #ifdef __cplusplus
00213 namespace r123{
00245 struct AESNI1xm128i{
00246 typedef aesni1xm128i_ctr_t ctr_type;
00247 typedef aesni1xm128i_ukey_t ukey_type;
00248 typedef aesni1xm128i_key_t key_type;
00249 static const unsigned int rounds=10;
00250 ctr_type operator()(ctr_type ctr, key_type key) const{
00251 return aesni1xm128i(ctr, key);
00252 }
00253 };
00254
00255
00256 struct AESNI4x32{
00257 typedef aesni4x32_ctr_t ctr_type;
00258 typedef aesni4x32_ukey_t ukey_type;
00259 typedef aesni4x32_key_t key_type;
00260 static const unsigned int rounds=10;
00261 ctr_type operator()(ctr_type ctr, key_type key) const{
00262 return aesni4x32(ctr, key);
00263 }
00264 };
00265
00271 template <unsigned ROUNDS=10>
00272 struct AESNI1xm128i_R : public AESNI1xm128i{
00273 R123_STATIC_ASSERT(ROUNDS==10, "AESNI1xm128i_R<R> is only valid with R=10");
00274 };
00275
00277 template <unsigned ROUNDS=10>
00278 struct AESNI4x32_R : public AESNI4x32{
00279 R123_STATIC_ASSERT(ROUNDS==10, "AESNI4x32_R<R> is only valid with R=10");
00280 };
00281 }
00282 #endif
00283
00284 #endif
00285
00286 #if R123_USE_AES_OPENSSL
00287 #include <openssl/aes.h>
00288 typedef struct r123array16x8 aesopenssl16x8_ctr_t;
00289 typedef struct r123array16x8 aesopenssl16x8_ukey_t;
00290 #ifdef __cplusplus
00291 struct aesopenssl16x8_key_t{
00292 AES_KEY k;
00293 aesopenssl16x8_key_t(){
00294 aesopenssl16x8_ukey_t ukey={{}};
00295 AES_set_encrypt_key((const unsigned char *)&ukey.v[0], 128, &k);
00296 }
00297 aesopenssl16x8_key_t(const aesopenssl16x8_ukey_t& ukey){
00298 AES_set_encrypt_key((const unsigned char *)&ukey.v[0], 128, &k);
00299 }
00300 aesopenssl16x8_key_t& operator=(const aesopenssl16x8_ukey_t& ukey){
00301 AES_set_encrypt_key((const unsigned char *)&ukey.v[0], 128, &k);
00302 return *this;
00303 }
00304 };
00305 #else
00306 typedef struct aesopenssl16x8_key_t{
00307 AES_KEY k;
00308 }aesopenssl16x8_key_t;
00309 R123_STATIC_INLINE struct aesopenssl16x8_key_t aesopenssl16x8keyinit(aesopenssl16x8_ukey_t uk){
00310 aesopenssl16x8_key_t ret;
00311 AES_set_encrypt_key((const unsigned char *)&uk.v[0], 128, &ret.k);
00312 return ret;
00313 }
00314 #endif
00315
00316 R123_STATIC_INLINE R123_FORCE_INLINE(aesopenssl16x8_ctr_t aesopenssl16x8_R(aesopenssl16x8_ctr_t ctr, aesopenssl16x8_key_t key));
00317 R123_STATIC_INLINE
00318 aesopenssl16x8_ctr_t aesopenssl16x8_R(aesopenssl16x8_ctr_t ctr, aesopenssl16x8_key_t key){
00319 aesopenssl16x8_ctr_t ret;
00320 AES_encrypt((const unsigned char*)&ctr.v[0], (unsigned char *)&ret.v[0], &key.k);
00321 return ret;
00322 }
00323
00324 #define aesopenssl16x8_rounds aesni4x32_rounds
00325 #define aesopenssl16x8(c,k) aesopenssl16x8_R(aesopenssl16x8_rounds)
00326
00327 #ifdef __cplusplus
00328 namespace r123{
00329 struct AESOpenSSL16x8{
00330 typedef aesopenssl16x8_ctr_t ctr_type;
00331 typedef aesopenssl16x8_key_t key_type;
00332 typedef aesopenssl16x8_ukey_t ukey_type;
00333 static const unsigned int rounds=10;
00334 ctr_type operator()(const ctr_type& in, const key_type& k){
00335 ctr_type out;
00336 AES_encrypt((const unsigned char *)&in[0], (unsigned char *)&out[0], &k.k);
00337 return out;
00338 }
00339 };
00340 }
00341 #endif
00342 #endif
00343
00344 #endif