Can anyone recommend a cryptographically-secure pseudo random number generator library for Delphi (Win32)?
Can be free or commercial, but will ideally be an active project. I'd like it to include source code.
You can use Windows CryptoAPI:
uses Wcrypt2;
function GenerateRandom(Len: Cardinal): TBytes;
var
hProv : HCRYPTPROV;
begin
if not CryptAcquireContext(@hProv,
nil,
MS_ENHANCED_PROV,
PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT) then
CryptAcquireContext(@hProv,
nil,
MS_ENHANCED_PROV,
PROV_RSA_FULL,
CRYPT_NEWKEYSET + CRYPT_VERIFYCONTEXT);
if hProv > 0 then
try
SetLength(Result,Len);
CryptGenRandom(hProv,Len,@Result[0]);
finally
CryptReleaseContext(hProv,0);
end;
end;
Example of using the above code:
function BytesToHex(const Bytes: TBytes): string;
var
i : integer;
begin
for i := 0 to Length(Bytes)-1 do
Result := Result + IntToHex(Bytes[i],2);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(BytesToHex(GenerateRandom(16)));
end;
The Delphi Encryption Compendium (which is famous-ish in the German speaking Delphi community, but nowhere else - presumably since it isn't officially promoted) contains a cryptographically secure Yarrow RNG.
Just include the unit DECRandom
(and maybe DECUtils
) and use it like this (this example uses IInteger
but that isn't mandatory):
function generateRandomNumber: IInteger;
var
A: IInteger;
begin
NRnd(A, 512); // generate 512 Bit random number, 2^512 <= A < 2^513
Result := A;
end;
initialization
// Method 1: uses system timer to initialize the RNG (seed)
RandomSeed;
// Method 2: use own seed
randomSeed(Data, SizeOf(Data));
Check out ISAAC (Indirection, Shift, Accumulate, Add, and Count), a fast PRNG and also cryptographically secure ( burtleburtle.net/bob/rand/isaacafa.html ). Probably ISAAC is as fast as the famous Mersenne Twister PRNG.
Wolfgang Ehrhardt has done the pascal/delphi port for ISAAC and is available at http://www.wolfgang-ehrhardt.de/misc_en.html#prng (free and source available). There is also a link to another delphi port provided on the author's site, but I would go with the "Wolfgang Ehrhardt" version. I know his site (http://www.wolfgang-ehrhardt.de/index.html) for many years, and he has been updating with the pascal/delphi routines since then. Surely should be an expert on this!
You could use the existing Win32 CryptGenRandom()
API.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With