diff --git a/ipcl/include/ipcl/utils/util.hpp b/ipcl/include/ipcl/utils/util.hpp index 17c6c4e..f564c8b 100644 --- a/ipcl/include/ipcl/utils/util.hpp +++ b/ipcl/include/ipcl/utils/util.hpp @@ -43,6 +43,8 @@ inline void vec_size_check(const std::vector& v, const char* file, #define VEC_SIZE_CHECK(v) vec_size_check(v, __FILE__, __LINE__) +enum class RNGenType { RDSEED = 1, RDRAND = 2, PSEUDO = 3 }; + #ifdef IPCL_RUNTIME_DETECT_CPU_FEATURES static const bool disable_avx512ifma = (std::getenv("IPCL_DISABLE_AVX512IFMA") != nullptr); @@ -53,10 +55,22 @@ static const bool prefer_ipp_prng = static const cpu_features::X86Features features = cpu_features::GetX86Info().features; static const bool has_avx512ifma = features.avx512ifma && !disable_avx512ifma; -static const bool has_rdseed = +static const bool use_rdseed = features.rdseed && !prefer_rdrand && !prefer_ipp_prng; -static const bool has_rdrand = features.rdrnd && prefer_rdrand; +static const bool use_rdrand = features.rdrnd && prefer_rdrand; + +static const RNGenType kRNGenType = use_rdseed ? RNGenType::RDSEED + : use_rdrand ? RNGenType::RDRAND + : RNGenType::PSEUDO; +#else // compile time detection of cpu feature +#ifdef IPCL_RNG_INSTR_RDSEED +static const RNGenType kRNGenType = RNGenType::RDSEED; +#elif defined(IPCL_RNG_INSTR_RDRAND) +static const RNGenType kRNGenType = RNGenType::RDRAND; +#else +static const RNGenType kRNGenType = RNGenType::PSEUDO; +#endif #endif // IPCL_RUNTIME_DETECT_CPU_FEATURES #ifdef IPCL_USE_OMP diff --git a/ipcl/keygen.cpp b/ipcl/keygen.cpp index 45e24d0..754c8dc 100644 --- a/ipcl/keygen.cpp +++ b/ipcl/keygen.cpp @@ -26,19 +26,18 @@ BigNumber getPrimeBN(int max_bits) { auto prime_ctx = std::vector(prime_size); ippsPrimeInit(max_bits, reinterpret_cast(prime_ctx.data())); -#if defined(IPCL_RNG_INSTR_RDSEED) || defined(IPCL_RNG_INSTR_RDRAND) Ipp8u* rand_param = NULL; -#else constexpr int seed_size = 160; auto buff = std::vector(prime_size); - auto rand_param = buff.data(); - ippsPRNGInit(seed_size, reinterpret_cast(rand_param)); - - auto seed = std::vector(seed_size); - rand32u(seed); - BigNumber seed_bn(seed.data(), seed_size, IppsBigNumPOS); - ippsPRNGSetSeed(BN(seed_bn), reinterpret_cast(rand_param)); -#endif + if (kRNGenType == RNGenType::PSEUDO) { + rand_param = buff.data(); + ippsPRNGInit(seed_size, reinterpret_cast(rand_param)); + + auto seed = std::vector(seed_size); + rand32u(seed); + BigNumber seed_bn(seed.data(), seed_size, IppsBigNumPOS); + ippsPRNGSetSeed(BN(seed_bn), reinterpret_cast(rand_param)); + } BigNumber prime_bn(0, max_bits / 8); while (ippStsNoErr != diff --git a/ipcl/utils/common.cpp b/ipcl/utils/common.cpp index 780304e..06e5c11 100644 --- a/ipcl/utils/common.cpp +++ b/ipcl/utils/common.cpp @@ -9,46 +9,31 @@ namespace ipcl { IppStatus ippGenRandom(Ipp32u* rand, int bits, void* ctx) { -#ifdef IPCL_RUNTIME_DETECT_CPU_FEATURES - if (has_rdseed) + if (kRNGenType == RNGenType::RDSEED) return ippsTRNGenRDSEED(rand, bits, ctx); - else if (has_rdrand) + else if (kRNGenType == RNGenType::RDRAND) return ippsPRNGenRDRAND(rand, bits, ctx); - else + else if (kRNGenType == RNGenType::PSEUDO) return ippsPRNGen(rand, bits, ctx); -#else -#ifdef IPCL_RNG_INSTR_RDSEED - return ippsTRNGenRDSEED(rand, bits, ctx); -#elif defined(IPCL_RNG_INSTR_RDRAND) - return ippsPRNGenRDRAND(rand, bits, ctx); -#else - return ippsPRNGen(rand, bits, ctx); -#endif -#endif // IPCL_RUNTIME_IPP_RNG + else + ERROR_CHECK(false, "ippGenRandom: RNGenType does not exist."); } IppStatus ippGenRandomBN(IppsBigNumState* rand, int bits, void* ctx) { -#ifdef IPCL_RUNTIME_DETECT_CPU_FEATURES - if (has_rdseed) + if (kRNGenType == RNGenType::RDSEED) { return ippsTRNGenRDSEED_BN(rand, bits, ctx); - else if (has_rdrand) + } else if (kRNGenType == RNGenType::RDRAND) { return ippsPRNGenRDRAND_BN(rand, bits, ctx); - else - return ippsPRNGen_BN(rand, bits, ctx); -#else -#ifdef IPCL_RNG_INSTR_RDSEED - return ippsTRNGenRDSEED_BN(rand, bits, ctx); -#elif defined(IPCL_RNG_INSTR_RDRAND) - return ippsPRNGenRDRAND_BN(rand, bits, ctx); -#else - int size; - ippsPRNGGetSize(&size); - auto prng = std::vector(size); - ippsPRNGInit(160, reinterpret_cast(prng.data())); - return ippsPRNGen_BN(rand, bits, - reinterpret_cast(prng.data())); -#endif -#endif // IPCL_RUNTIME_IPP_RNG + } else if (kRNGenType == RNGenType::PSEUDO) { + int size; + ippsPRNGGetSize(&size); + auto prng = std::vector(size); + ippsPRNGInit(160, reinterpret_cast(prng.data())); + return ippsPRNGen_BN(rand, bits, + reinterpret_cast(prng.data())); + } else { + ERROR_CHECK(false, "ippGenRandomBN: RNGenType does not exist."); + } } BigNumber getRandomBN(int bits) {