diff --git a/ipcl/include/ipcl/utils/common.hpp b/ipcl/include/ipcl/utils/common.hpp index 5fdb14e..e0c9e42 100644 --- a/ipcl/include/ipcl/utils/common.hpp +++ b/ipcl/include/ipcl/utils/common.hpp @@ -22,6 +22,8 @@ constexpr float IPCL_HYBRID_MODEXP_RATIO_ENCRYPT = 0.25; constexpr float IPCL_HYBRID_MODEXP_RATIO_DECRYPT = 0.12; constexpr float IPCL_HYBRID_MODEXP_RATIO_MULTIPLY = 0.18; +constexpr int IPCL_RDRAND_RETRIES = 3; + /** * Generate random number with std mt19937 * @param[in,out] addr Location used to store the generated random number diff --git a/ipcl/utils/common.cpp b/ipcl/utils/common.cpp index 4a0830f..3ed3a0d 100644 --- a/ipcl/utils/common.cpp +++ b/ipcl/utils/common.cpp @@ -16,37 +16,64 @@ void rand32u(std::vector& addr) { } IppStatus ippGenRandom(Ipp32u* rand, int bits, void* ctx) { - if (kRNGenType == RNGenType::RDSEED) - return ippsTRNGenRDSEED(rand, bits, ctx); - else if (kRNGenType == RNGenType::RDRAND) - return ippsPRNGenRDRAND(rand, bits, ctx); - else if (kRNGenType == RNGenType::PSEUDO) - return ippsPRNGen(rand, bits, ctx); - else - ERROR_CHECK(false, "ippGenRandom: RNGenType does not exist."); + IppStatus stat; + switch (kRNGenType) { + case RNGenType::RDSEED: + stat = ippsTRNGenRDSEED(rand, bits, ctx); + if (stat == ippStsNoErr) break; + case RNGenType::RDRAND: { + int count = 0; + do { + stat = ippsPRNGenRDRAND(rand, bits, ctx); + count++; + } while ((stat != ippStsNoErr) && (count < IPCL_RDRAND_RETRIES)); + break; + } + case RNGenType::PSEUDO: + stat = ippsPRNGen(rand, bits, ctx); + break; + default: + ERROR_CHECK(false, "ippGenRandom: RNGenType does not exist."); + } + + return stat; } IppStatus ippGenRandomBN(IppsBigNumState* rand, int bits, void* ctx) { - if (kRNGenType == RNGenType::RDSEED) { - return ippsTRNGenRDSEED_BN(rand, bits, ctx); - } else if (kRNGenType == RNGenType::RDRAND) { - return ippsPRNGenRDRAND_BN(rand, bits, ctx); - } else if (kRNGenType == RNGenType::PSEUDO) { - int seed_size = 160; - int size; - ippsPRNGGetSize(&size); - auto prng = std::vector(size); - ippsPRNGInit(seed_size, reinterpret_cast(prng.data())); - - auto seed = std::vector(seed_size); - rand32u(seed); - BigNumber seed_bn(seed.data(), seed_size, IppsBigNumPOS); - ippsPRNGSetSeed(BN(seed_bn), reinterpret_cast(prng.data())); - return ippsPRNGen_BN(rand, bits, - reinterpret_cast(prng.data())); - } else { - ERROR_CHECK(false, "ippGenRandomBN: RNGenType does not exist."); + IppStatus stat; + switch (kRNGenType) { + case RNGenType::RDSEED: + stat = ippsTRNGenRDSEED_BN(rand, bits, ctx); + if (stat == ippStsNoErr) break; + case RNGenType::RDRAND: { + int count = 0; + do { + stat = ippsPRNGenRDRAND_BN(rand, bits, ctx); + count++; + } while ((stat != ippStsNoErr) && (count < IPCL_RDRAND_RETRIES)); + break; + } + case RNGenType::PSEUDO: { + int seed_size = 160; + int size; + ippsPRNGGetSize(&size); + auto prng = std::vector(size); + ippsPRNGInit(seed_size, reinterpret_cast(prng.data())); + + auto seed = std::vector(seed_size); + rand32u(seed); + BigNumber seed_bn(seed.data(), seed_size, IppsBigNumPOS); + ippsPRNGSetSeed(BN(seed_bn), + reinterpret_cast(prng.data())); + stat = ippsPRNGen_BN(rand, bits, + reinterpret_cast(prng.data())); + break; + } + default: + ERROR_CHECK(false, "ippGenRandomBN: RNGenType does not exist."); } + + return stat; } BigNumber getRandomBN(int bits) {