- Random123-1.09 Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

# Random123/aes.h

Go to the documentation of this file.

    00001 /*
    00002 Copyright 2010-2011, D. E. Shaw Research.
    00003 All rights reserved.
    00004
    00005 Redistribution and use in source and binary forms, with or without
    00006 modification, are permitted provided that the following conditions are
    00007 met:
    00008
    00009 * Redistributions of source code must retain the above copyright
    00010   notice, this list of conditions, and the following disclaimer.
    00011
    00012 * Redistributions in binary form must reproduce the above copyright
    00013   notice, this list of conditions, and the following disclaimer in the
    00014   documentation and/or other materials provided with the distribution.
    00015
    00016 * Neither the name of D. E. Shaw Research nor the names of its
    00017   contributors may be used to endorse or promote products derived from
    00018   this software without specific prior written permission.
    00019
    00020 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    00021 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    00022 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    00023 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    00024 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    00025 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    00026 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    00027 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    00028 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    00029 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    00030 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    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 /* Implement a bona fide AES block cipher.  It's minimally
    00039 // checked against the test vector in FIPS-197 in ut_aes.cpp. */
    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 r123_enum_aesni1xm128i { 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 r123_enum_aesni4x32 { 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 /* @class AESNI4x32 */
    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 } // namespace r123
    00282 #endif /* __cplusplus */
    00283
    00284 #endif /* R123_USE_AES_NI */
    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 } // namespace r123
    00341 #endif /* __cplusplus */
    00342 #endif /* R123_USE_AES_OPENSSL */
    00343
    00344 #endif

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines