从python使用硬件rng [英] using the hardware rng from python

查看:202
本文介绍了从python使用硬件rng的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有现成的库,以便numpy程序可以使用intel硬件prng(rdrand)来填充随机数的缓冲区?

Are there any ready made libraries so that the intel hardware prng (rdrand) can be used by numpy programs to fill buffers of random numbers?

如果失败,则有人可以为我指出一些我可以改编或使用的C代码的正确方向(我将CPython和Cython与numpy结合使用,因此最小的包装程序就足够了.)

Failing this can someone point me in the right direction for some C code that I could adapt or use (I use CPython and Cython with numpy so the bare minimum wrapper shd be enough).

我想要的随机发生器是[0,1)之间的统一随机数.

The random generators I want are uniform random numbers between [0,1).

推荐答案

此代码将使用/dev/urandom(Unix)或CryptGenRandom API(Windows).使用哪种RNG(硬件还是软件)取决于操作系统.

This code will use /dev/urandom (Unix) or CryptGenRandom APIs (Windows). Which RNG is used, hardware or software, is dependent on the operating system.

如果要精确控制使用哪个生成器,则必须通过其硬件驱动程序或库对其进行查询.当您将随机位作为字符串使用时,使用np.fromstring类似于此代码进行处理.

If you want to control exactly which generator is used, you must query it through its hardware driver or library. When you have the random bits as a string, you proceeed similarly to this code, using np.fromstring.

通常,我们可以信任操作系统为其加密服务(包括随机位生成器)使用最佳的熵源.如果有硬件RNG,则很可能会使用它,通常将其与其他熵源结合使用.

Normally we can trust the operating system to use the best entropy sources for its cryptographic services, including the random bit generator. If there is a hardware RNG it is likely to be used, usually combination with other entropy sources.

import os
import numpy as np

def cryptorand(n):
    a = np.fromstring(os.urandom(n*4), dtype=np.uint32) >> 5
    b = np.fromstring(os.urandom(n*4), dtype=np.uint32) >> 6
    return (a * 67108864.0 + b) / 9007199254740992.0

这是在Mac OS X上使用此方法生成的1,000,000个随机偏差的分布.如您所见,它在[0,1)上非常均匀:

Here is the distribution of 1,000,000 random deviates generated with this method on Mac OS X. As you can see it is quite uniform on [0,1):

如果您需要真正强大的加密随机偏差,则可以使用/dev/random而不是/dev/urandom.这仅适用于类似Unix的系统,不适用于Windows:

If you need really strong cryptographic random deviates, you can use /dev/random instead of /dev/urandom. This applies only to Unix-like systems, not Windows:

import numpy as np

def cryptorand(n):
    with open('/dev/random','rb') as rnd:
        a = np.fromstring(rnd.read(n*4), dtype=np.uint32) >> 5
        b = np.fromstring(rnd.read(n*4), dtype=np.uint32) >> 6
        return (a * 67108864.0 + b) / 9007199254740992.0

请注意,与使用os.urandom作为熵源的版本不同,此功能可能会阻止.

Note that this function might block, unlike the version that uses os.urandom as entropy source.

(更新了归一化以使其等于NumPy)

( Updated normalization to equate that of NumPy)

注释表明问题的原因是速度,而不是密码强度.硬件RNG的目的不是速度而是强度,因此使该问题无效.但是,乔治·玛格萨利亚(George Marsaglia)的乘载发生器是一种快速,优质的PRNG,可以替代梅森·Twister.这是Cython中的一个简单实现:

Edit 2: The comments indicates the reason for the question was speed, not cryptographic strength. The purpose of hardware RNG is not speed but strength, so it makes the question invalid. However, a fast and good PRNG which can be an alternative to the Mersenne Twister is George Marsaglia's multiply-with-carry generator. Here is a simple implementation in Cython:

import numpy as np
cimport numpy as cnp

cdef cnp.uint32_t gw = 152315241 # any number except 0 or 0x464fffff
cdef cnp.uint32_t gz = 273283728 # any number except 0 or 0x9068ffff

def rand(cnp.intp_t n):
    """Generate n random numbers using George Marsaglia's 
    multiply-with-carry method."""
    global gw, gz
    cdef cnp.uint32_t w, z, a, b
    cdef cnp.intp_t i
    cdef cnp.ndarray x = cnp.PyArray_SimpleNew(1, &n, cnp.NPY_FLOAT64)
    cdef cnp.float64_t *r = <cnp.float64_t*> cnp.PyArray_DATA(x)
    w,z = gw,gz
    for i in range(n): 
        z = 36969 * (z & 65535) + (z >> 16)
        w = 18000 * (w & 65535) + (w >> 16)
        a = (z << 16) + w
        z = 36969 * (z & 65535) + (z >> 16)
        w = 18000 * (w & 65535) + (w >> 16)
        b = (z << 16) + w
        r[i] = (a * 67108864.0 + b) / 9007199254740992.0
    gw,gz = w,z
    return x

请注意,梅森·扭曲者(Mersenne Twister)和随身携带都没有密码强度.

Beware that neither Mersenne Twister nor multiply-with-carry have cryptographic strength.

这篇关于从python使用硬件rng的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆