src
值。种子将是密钥和nonce,可以使用crypto/rand生成。
编辑
作为我所追求的例子,cryptonite是主要的Haskell加密库,它有一个函数drgNewSeed
,可以使用种子生成一个随机生成器。src
值。种子将是密钥和nonce,可以使用crypto/rand生成。
编辑
作为我所追求的例子,cryptonite是主要的Haskell加密库,它有一个函数drgNewSeed
,可以使用种子生成一个随机生成器。是的,XORKeyStream对于这个问题来说是可以的,而且是一个很好的CSPRNG设计。流密码的整个重点在于它生成一串"有效随机"的值,给定一个种子(密钥和IV)。然后将这些流值与明文进行异或运算。在这个背景下,“有效随机”意味着没有“高效算法”(即多项式时间内运行的算法)能够区分这个序列和“真正随机”的序列。而这就是你想要的。
不过,没有必要引入ChaCha20。您可以使用内置的AES密钥。任何块密码都可以使用几种模式之一转换为流密码,例如CTR、OFB或CFB。这些模式之间的区别对于这个问题并不重要。
// Defining some seed, split across a "key" and an "iv"
key, _ := hex.DecodeString("6368616e676520746869732070617373")
iv, _ := hex.DecodeString("0123456789abcdef0123456789abcdef")
// We can turn a block cipher into a stream cipher, and AES is handy
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
// Convert block cipher into a stream cipher using a streaming mode like CTR
// OFB or CFB would work, too
stream := cipher.NewCTR(block, iv)
for x := 0; x < 10; x++ {
// Create a fixed value of the size you want
value := []byte{0}
// Transform it to a random value
stream.XORKeyStream(value, value)
fmt.Printf("%d\n", value)
}
在这里,你可以使用几种不同的方法。你可以使用安全散列函数,比如SHA-256,来哈希计数器(选择一个随机的128位数,并不断递增它,每个值都要进行哈希)。或者你可以对上一个结果进行哈希运算(我听说过一些争议,关于重复哈希是否会影响哈希的安全性。请参见https://crypto.stackexchange.com/questions/19392/any-weakness-when-performing-sha-256-repeatedly和https://crypto.stackexchange.com/questions/15481/will-repeated-rounds-of-sha-512-provide-random-numbers/15488以获取更多信息)。
你也可以使用块密码来完成相同的操作,通过加密计数器或上一个输出值。这与流密码模式非常接近。你也可以手动完成这个过程。
如果你想深入了解这个问题,可以在crypto.stackexchange.com上搜索"csprng stream cipher"。那是一个更好的地方,可以寻求加密建议,但是在我看来,这是一个编程特定的问题,因此应该放在这里讨论。
然后,可以使用像Hash-DRGB、HMAC-DRGB和CTR-DRGB这样的可能良好的确定性RBG,如NIST 800-90中所定义的。
您可以使用x/crypto/chacha20
生成长的确定性随机序列。 保持密钥和nonce不变且保密,那么您将拥有一个确定性DRGB。 它非常快速,也是可寻址的。