32 #ifndef VSMC_RNG_AES_HPP
33 #define VSMC_RNG_AES_HPP
38 #define VSMC_DEFINE_RNG_AES_ROUND_CONSTANT(N, val) \
39 template <> struct AESRoundConstantValue< N > : \
40 public cxx11::integral_constant<int, val > {};
44 #ifndef VSMC_RNG_AES_BLOCKS
45 #define VSMC_RNG_AES_BLOCKS 1
313 template <std::size_t Offset, std::size_t N,
314 typename T, std::size_t KeySize, std::size_t Rp1>
318 key_init_xmm<Offset, N>(key, key_seq, xmm,
324 template <std::size_t, std::size_t,
325 typename T, std::size_t KeySize, std::size_t Rp1>
329 template <std::size_t Offset, std::size_t N,
330 typename T, std::size_t KeySize,
335 m128i_pack<Offset>(key, xmm);
344 template <
typename ResultType>
351 template <std::
size_t Rp1>
354 internal::AESKeyInit::key_init<0, 0>(key, key_seq, xmm1_);
364 template <std::
size_t, std::
size_t Rp1>
367 template <std::
size_t N, std::
size_t Rp1>
370 xmm2_ = _mm_aeskeygenassist_si128(xmm1_,
371 internal::AESRoundConstantValue<N>::value);
373 key_seq[Position<N>()] = xmm1_;
374 generate_seq<N + 1>(key_seq,
375 cxx11::integral_constant<bool, N + 1 < Rp1>());
380 xmm2_ = _mm_shuffle_epi32(xmm2_, 0xFF);
381 xmm3_ = _mm_slli_si128 (xmm1_, 0x04);
382 xmm1_ = _mm_xor_si128 (xmm1_, xmm3_);
383 xmm3_ = _mm_slli_si128 (xmm3_, 0x04);
384 xmm1_ = _mm_xor_si128 (xmm1_, xmm3_);
385 xmm3_ = _mm_slli_si128 (xmm3_, 0x04);
386 xmm1_ = _mm_xor_si128 (xmm1_, xmm3_);
387 xmm1_ = _mm_xor_si128 (xmm1_, xmm2_);
404 template <
typename ResultType, std::
size_t Blocks = VSMC_RNG_AES_BLOCKS>
406 public AESNIEngine<ResultType, AES128KeySeq<ResultType>, true, 10, Blocks>
416 template <
typename SeedSeq>
470 template <
typename ResultType>
477 template <std::
size_t Rp1>
482 internal::AESKeyInit::key_init<0, 0>(key_tmp, key_seq, xmm1_);
483 key_tmp.at<0>() = key_tmp.at<2>();
485 internal::AESKeyInit::key_init<0, 1>(key_tmp, key_seq, xmm7_);
487 xmm3_ = _mm_setzero_si128();
488 xmm6_ = _mm_setzero_si128();
489 xmm4_ = _mm_shuffle_epi32(xmm7_, 0x4F);
492 generate_seq<1, Rp1>(ks_tmp.
data(),
494 copy_key(key_seq, ks_tmp.
data(),
508 template <std::
size_t, std::
size_t>
511 template <std::
size_t N, std::
size_t Rp1>
514 generate_key<N>(ks_ptr);
515 complete_key<N>(ks_ptr,
516 cxx11::integral_constant<bool, N * 24 + 16 < Rp1 * 16>());
517 generate_seq<N + 1, Rp1>(ks_ptr,
518 cxx11::integral_constant<bool, N * 24 + 24 < Rp1 * 16>());
521 template <std::
size_t N>
522 void generate_key (
unsigned char *ks_ptr)
527 xmm2_ = _mm_aeskeygenassist_si128(xmm4_,
528 internal::AESRoundConstantValue<N>::value);
529 generate_key_expansion();
530 _mm_storeu_si128(reinterpret_cast<__m128i *>(
531 ks_ptr + N * 24), xmm1_);
534 template <std::
size_t>
537 template <std::
size_t N>
543 complete_key_expansion();
544 _mm_storeu_si128(reinterpret_cast<__m128i *>(
545 ks_ptr + N * 24 + 16), xmm7_);
548 void generate_key_expansion ()
550 xmm2_ = _mm_shuffle_epi32(xmm2_, 0xFF);
551 xmm3_ = _mm_castps_si128 (_mm_shuffle_ps(
552 _mm_castsi128_ps(xmm3_),
553 _mm_castsi128_ps(xmm1_), 0x10));
554 xmm1_ = _mm_xor_si128 (xmm1_, xmm3_);
555 xmm3_ = _mm_castps_si128(_mm_shuffle_ps(
556 _mm_castsi128_ps(xmm3_),
557 _mm_castsi128_ps(xmm1_), 0x8C));
558 xmm1_ = _mm_xor_si128 (xmm1_, xmm3_);
559 xmm1_ = _mm_xor_si128 (xmm1_, xmm2_);
562 void complete_key_expansion ()
564 xmm5_ = _mm_load_si128 (&xmm4_);
565 xmm5_ = _mm_slli_si128 (xmm5_, 0x04);
566 xmm6_ = _mm_castps_si128 (_mm_shuffle_ps(
567 _mm_castsi128_ps(xmm6_),
568 _mm_castsi128_ps(xmm1_), 0xF0));
569 xmm6_ = _mm_xor_si128 (xmm6_, xmm5_);
570 xmm4_ = _mm_xor_si128 (xmm4_, xmm6_);
571 xmm7_ = _mm_shuffle_epi32(xmm4_, 0x0E);
574 template <std::
size_t Rp1>
575 void copy_key (Array<__m128i, Rp1> &,
578 template <std::
size_t Rp1>
579 void copy_key (Array<__m128i, Rp1> &key_seq,
582 unsigned char *dst =
reinterpret_cast<unsigned char *
>(key_seq.data());
592 template <
typename ResultType, std::
size_t Blocks = VSMC_RNG_AES_BLOCKS>
594 public AESNIEngine<ResultType, AES192KeySeq<ResultType>, true, 12, Blocks>
604 template <
typename SeedSeq>
658 template <
typename ResultType>
665 template <std::
size_t Rp1>
668 internal::AESKeyInit::key_init<0, 0>(key, key_seq, xmm1_);
670 key, key_seq, xmm3_);
681 template <std::
size_t, std::
size_t Rp1>
684 template <std::
size_t N, std::
size_t Rp1>
687 generate_key<N>(key_seq, cxx11::integral_constant<bool, N % 2 == 0>());
688 generate_seq<N + 1>(key_seq,
689 cxx11::integral_constant<bool, N + 1 < Rp1>());
692 template <std::
size_t N, std::
size_t Rp1>
695 xmm2_ = _mm_aeskeygenassist_si128(xmm3_,
696 internal::AESRoundConstantValue<N / 2>::value);
698 key_seq[Position<N>()] = xmm1_;
701 template <std::
size_t N, std::
size_t Rp1>
704 xmm4_ = _mm_aeskeygenassist_si128(xmm1_, 0);
706 key_seq[Position<N>()] = xmm3_;
711 xmm2_ = _mm_shuffle_epi32(xmm2_, 0xFF);
712 xmm4_ = _mm_slli_si128 (xmm1_, 0x04);
713 xmm1_ = _mm_xor_si128 (xmm1_, xmm4_);
714 xmm4_ = _mm_slli_si128 (xmm4_, 0x04);
715 xmm1_ = _mm_xor_si128 (xmm1_, xmm4_);
716 xmm4_ = _mm_slli_si128 (xmm4_, 0x04);
717 xmm1_ = _mm_xor_si128 (xmm1_, xmm4_);
718 xmm1_ = _mm_xor_si128 (xmm1_, xmm2_);
723 xmm2_ = _mm_shuffle_epi32(xmm4_, 0xAA);
724 xmm4_ = _mm_slli_si128 (xmm3_, 0x04);
725 xmm3_ = _mm_xor_si128 (xmm3_, xmm4_);
726 xmm4_ = _mm_slli_si128 (xmm4_, 0x04);
727 xmm3_ = _mm_xor_si128 (xmm3_, xmm4_);
728 xmm4_ = _mm_slli_si128 (xmm4_, 0x04);
729 xmm3_ = _mm_xor_si128 (xmm3_, xmm4_);
730 xmm3_ = _mm_xor_si128 (xmm3_, xmm2_);
739 template <
typename ResultType, std::
size_t Blocks = VSMC_RNG_AES_BLOCKS>
741 public AESNIEngine<ResultType, AES256KeySeq<ResultType>, true, 14, Blocks>
751 template <
typename SeedSeq>
805 #endif // VSMC_RNG_AES_HPP
AES192Engine(ResultType s=0)
AES128Engine< uint32_t, 2 > AES128_2x32
AES-128 RNG engine with 32-bits integers output and 2 blocks.
AES192Engine< uint32_t, 8 > AES192_8x32
AES-192 RNG engine with 32-bits integers output and 8 blocks.
void generate(const key_type &key, Array< __m128i, Rp1 > &key_seq)
AES256Engine< uint64_t, 8 > AES256_8x64
AES-256 RNG engine with 64-bits integers output and 8 blocks.
AES128Engine< uint64_t, 2 > AES128_2x64
AES-128 RNG engine with 64-bits integers output and 2 blocks.
AES192Engine< uint64_t, 8 > AES192_8x64
AES-192 RNG engine with 64-bits integers output and 8 blocks.
AES256Engine< uint32_t, 1 > AES256_1x32
AES-256 RNG engine with 32-bits integers output and 1 block.
AES192Engine< uint64_t, 1 > AES192_1x64
AES-192 RNG engine with 64-bits integers output and 1 block.
AES128Engine(const typename base_eng_type::key_type &k)
AES128Engine< uint64_t > AES128_64
AES-128 RNG engine with 64-bits integers output and default blocks.
AES192Engine< uint32_t > AES192_32
AES-192 RNG engine with 32-bits integers output and default blocks.
AES128Engine< uint32_t, 1 > AES128_1x32
AES-128 RNG engine with 32-bits integers output and 1 block.
AESNIEngine< ResultType, AES256KeySeq< ResultType >, true, 14, Blocks > base_eng_type
AES128Engine< uint64_t, 1 > AES128_1x64
AES-128 RNG engine with 64-bits integers output and 1 block.
AES128Engine(SeedSeq &seq, typename cxx11::enable_if< internal::is_seed_seq< SeedSeq, typename base_eng_type::result_type, typename base_eng_type::key_type, AES128Engine< ResultType, Blocks > >::value >::type *=nullptr)
integral_constant< bool, false > false_type
Function template argument used for position.
AES256Engine< uint64_t > AES256_64
AES-256 RNG engine with 64-bits integers output and default blocks.
AES256Engine(const typename base_eng_type::key_type &k)
AES256Engine< uint32_t, 8 > AES256_8x32
AES-256 RNG engine with 32-bits integers output and 8 blocks.
AES256Engine< uint32_t > AES256_32
AES-256 RNG engine with 32-bits integers output and default blocks.
AES128Engine< uint32_t, 8 > AES128_8x32
AES-128 RNG engine with 32-bits integers output and 8 blocks.
AES256Engine< uint64_t, 1 > AES256_1x64
AES-256 RNG engine with 64-bits integers output and 1 block.
AES128Engine< uint32_t, 4 > AES128_4x32
AES-128 RNG engine with 32-bits integers output and 4 blocks.
AESNIEngine< ResultType, AES128KeySeq< ResultType >, true, 10, Blocks > base_eng_type
AES192Engine< uint32_t, 1 > AES192_1x32
AES-192 RNG engine with 32-bits integers output and 1 block.
void generate(const key_type &key, Array< __m128i, Rp1 > &key_seq)
RNG engine using AES-NI instructions.
#define VSMC_NULLPTR
nullptr
AES128Engine< uint32_t > AES128_32
AES-128 RNG engine with 32-bits integers output and default blocks.
integral_constant< bool, true > true_type
AES256Engine< uint32_t, 2 > AES256_2x32
AES-256 RNG engine with 32-bits integers output and 2 blocks.
AES128Engine(ResultType s=0)
AES256Engine(ResultType s=0)
void * memcpy(void *dst, const void *src, std::size_t n)
SIMD optimized memcpy with non-temporal store for large buffers.
AES128Engine< uint64_t, 4 > AES128_4x64
AES-128 RNG engine with 64-bits integers output and 4 blocks.
AES192Engine< uint32_t, 2 > AES192_2x32
AES-192 RNG engine with 32-bits integers output and 2 blocks.
AES192Engine(SeedSeq &seq, typename cxx11::enable_if< internal::is_seed_seq< SeedSeq, typename base_eng_type::result_type, typename base_eng_type::key_type, AES192Engine< ResultType, Blocks > >::value >::type *=nullptr)
AES256Engine< uint64_t, 4 > AES256_4x64
AES-256 RNG engine with 64-bits integers output and 4 blocks.
AES192Engine< uint64_t, 4 > AES192_4x64
AES-192 RNG engine with 64-bits integers output and 4 blocks.
void generate(const key_type &key, Array< __m128i, Rp1 > &key_seq)
AES192Engine< uint32_t, 4 > AES192_4x32
AES-192 RNG engine with 32-bits integers output and 4 blocks.
#define VSMC_DEFINE_RNG_AES_ROUND_CONSTANT(N, val)
AES128Engine key sequence generator.
AES256Engine< uint64_t, 2 > AES256_2x64
AES-256 RNG engine with 64-bits integers output and 2 blocks.
AES192Engine(const typename base_eng_type::key_type &k)
AES192Engine< uint64_t > AES192_64
AES-192 RNG engine with 64-bits integers output and default blocks.
static void key_init(const Array< T, KeySize > &key, Array< __m128i, Rp1 > &key_seq, __m128i &xmm)
AES128Engine< uint64_t, 8 > AES128_8x64
AES-128 RNG engine with 64-bits integers output and 8 blocks.
AES256Engine key sequence generator.
AES256Engine< uint32_t, 4 > AES256_4x32
AES-256 RNG engine with 32-bits integers output and 4 blocks.
AESNIEngine< ResultType, AES192KeySeq< ResultType >, true, 12, Blocks > base_eng_type
AES256Engine(SeedSeq &seq, typename cxx11::enable_if< internal::is_seed_seq< SeedSeq, typename base_eng_type::result_type, typename base_eng_type::key_type, AES256Engine< ResultType, Blocks > >::value >::type *=nullptr)
AES192Engine< uint64_t, 2 > AES192_2x64
AES-192 RNG engine with 64-bits integers output and 2 blocks.
AES192Engine key sequence generator.