I need to create cryptographically secure pseudorandomness in JavaScript. However, when I googled for PRGs, all I found was very sketchy.
My idea is as follows (in pseudocode):
seed = "0x1a29fd..." // long number I always get passed (impossible to guess but used in a different context as well)
hashedAndSaltedSeed = sha256sum("seed: " + seed)
purpose = "..." // my current function's name (no spaces)
usageIndex = 1; // will increment this each time
randomness = myPrg(hashedAndSaltedSeed, purpose, usageIndex)
function myPrg(hashedAndSaltedSeed, purpose, usageIndex, numberOfBytes) {
if(numberOfBytes > 32) {
fail()
}
input = purpose + " " + usageIndex + " " + hashedAndSaltedSeed
return sha256sum(input).binary2hex().slice(0, 2*numberOfBytes).hex2binary()
}
I only need a small amount of randomness (at most 32 Byte at a time, very few times), so the speed difference won't matter. But is there anything else wrong with this approach?
The randomness I need doesn't need to be distributed perfectly randomly but it needs to be infeasible to guess the resulting randomness when only given purpose and usageIndex but not seed nor hashedAndSaltedSeed.
Edit: I'm sorry that I forgot to mention an important requirement. I'm sure it was in my question at some point as I wrote it but I seem to have deleted that part accidentally. I need to be able to reproduce the same randomness when given the same seed. That's why I can't just use something that gives me randomness but doesn't let me control the seed.
seedis secret drawn uniformly at random from $2^{256}$ possibilities, that's fine, but your naming is a little confusing: what is the salt inhashedAndSaltedSeed? This also, of course, begs the question of whereseedcomes from, but if your present goal is just to have a pseudorandom function family for which it is the caller's responsibility to choose a seed uniformly at random, then that's fine. – Squeamish Ossifrage Aug 26 '19 at 21:16hashedAndSaltedSeedaround, no one can do anything with it that it's not intended for. It's not technically a salt because it's constant. Maybe I should find a better name. – UTF-8 Aug 26 '19 at 23:48purpose="hello world"andusageIndex="foobar", I'll get the same key as if I pass inpurpose="hello"andusageIndex="world foobar"even though the inputs are distinct. – Squeamish Ossifrage Aug 27 '19 at 12:29