英特尔安全密钥(RDRAND)可能是奇怪的行为

时间:2018-11-11 20:49:14

标签: random cryptography visual-studio-2017 c++-cli rdrand

一段时间以来,我一直在使用英特尔提供的RNG功能,通过自己编写的C ++ / CLI程序为自己提供一些随机性。

但是,过了一段时间,有些事情让我感到特别可疑。在其他用途​​中,我要求输入1到4之间的一个随机数,然后每次将结果记录在纸上。结果如下:

2、3、3、2、1、3、4、2、3、2、3、1、3、2、3、1、2、4、2、2、1、2、1、1、3 ,1、3、3、3、3。

1的个数:6 2秒数:9 3秒数:12 4s数:2 总计:29

我实际上是在想英特尔的RNG,我的算法,方法论还是其他问题?还是您认为偏差还不够大?

我正在使用Windows 10 Pro,我的CPU是Intel Core i7-4710MQ。 与VS2017一起编译。

方法:

  1. 启动Powershell命令提示符
  2. 使用Add-Type -Path <mydll>加载我的程序集
  3. 调用[rdrw.Random]::Next(4)
  4. 在结果中添加一个

一个可能很重要的细节:我并不经常要求这个数字,所以两次抽奖之间会有一段时间,通常是RNG一段时间没有使用(至少一个小时)。

是的,这是一个惰性算法,我不想因异常而困扰自己。

算法如下:

#include <immintrin.h>

namespace rdrw {

#pragma managed(push,off)
    unsigned long long getRdRand() {
        unsigned long long val = 0;

        while (!_rdrand64_step(&val));
        return val;
    }
#pragma managed(pop)

    public ref class Random abstract sealed
    {
    public:
        // Returns a random 64 bit unsigned integer
        static unsigned long long Next() {
            return getRdRand();
        }

        // Return a random unsigned integer between 0 and max-1 (inclusive)
        static unsigned long long Next(unsigned long long max) {
            unsigned long long nb = max - 1;
            unsigned long long mask = 1;
            unsigned long long draw = 0;

            if (max <= 1)
                return 0;

            // Create a bitmask that's at least as big as the biggest acceptable value
            while ((nb&mask) != nb)
            {
                mask <<= 1;
                mask |= 1;
            }

            do
            {
                // Throw unnecessary bits
                draw = Next() & mask;
            } while (draw>nb);
            return draw;
        }

        // return a random unsigned integer between min and max-1 inclusive
        static unsigned long long Next(unsigned long long min, unsigned long long max) {

            if (max == min)
                return min;
            if (max < min)
                return 0;
            unsigned long long diff = max - min;
            return Next(diff) + min;
        }
    };
}

感谢您的见解!

0 个答案:

没有答案