I was using the following code to generate sequence of pseudo-random numbers that was used for cryptographic purposes, but then I read somewhere that it may not be very secure. Can someone give me C implementation of a better generator -- the main goal is for this method to be fast. For instance, I did some research and came across Blum Blum Shub method, which would totally kill performance by doing pow(N) calculations.
PS. And please don't quote Wikipedia articles w/o C/C++ code. I'm looking for C or C++ code sample of what I'm showing below.
#define ROL(v, shift) ((((v) >> ((sizeof(v) * 8) - (shift))) | ((v) << (shift))))
ULONGLONG uiPSN = doSeed(); //64-bit unsigned integer
for(int i = 0; i < sizeOfArray; i++)
{
uiPSN = uiPSN * 214013L + 2531011L;
uiPSN = ROL(uiPSN, 16);
//Apply 'uiPSN'
}
ISAAC (http://www.burtleburtle.net/bob/rand/isaacafa.html) is probably one of the fastest cryptographically secure PRNGs (code at site). Another approach is to use a block cipher in counter mode. Something like TwoFish, which is reasonably fast and freely available, would be effective.
If you don't need a lot of numbers, all modern operating systems have built-in RNGs suitable for cryptographic use, though they typically can't produce lots of numbers because they rely on accumulating entropy from sources like input timings. Unix-like systems (Linux, OSX) have /dev/random, Windows has CryptGenRandom. Even if these aren't suitable for your needs, you probably should use them to seed the PRNG you do end up using.
Look at (or use) the random number generator in the OpenSSL library.
The hard part with any secure random number generator is the seeding.
If you are on Windows, consider using rand_s().
On Linux look at /dev/urand.
Some seeding methods suffer from not being very random soon after a reboot.
You can make a file with random bytes.
Use the file and the OS method for seeding.
Periodically use your random number generator to write a new file.
Don't "roll your own" cryptography. Use a certified library instead.
For speed, try using a library that can run on the GPU, which has far more computing power.
I would recommend the Mersenne-Twister, which I have used time and again.
The C code is here.
If you use C++11, you have mersenne twister as a part of the library itself. Mersenne Twister is currently one of the best algorithms out there.
Here is how I would implement in C++11, as a function. It is very straightforward. the mt19937 is th built in Mersenne Twister in C++11.
std::vector<double> classname::mersennetwister(const int& My,const int& Mz,const int& Ny,const int& Nz)
{
int ysize = (My + 2*Ny + 1);
int zsize = (Mz + 2*Nz + 1);
int matsize = ysize*zsize;
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::mt19937_64 generator (seed);
std::uniform_real_distribution<double> distribution(0,1);
std::vector<double> randarray = f.array1dgen(matsize,0);
for (int i=0;i<matsize;++i)
{
randarray[i] = distribution(generator);
}
return(randarray);
}