* * *

Author Topic: True hard random generator  (Read 4018 times)

sam707

  • Guest
True hard random generator
« on: December 14, 2017, 04:11:26 am »
As i read wiki I understood FPC uses Mersenne Twister algo to get pseudo random numbers.
While I was looking for alternate algorithms, I found out that some processors have an inbuilt hardware (true) random number generator.
My question is simple :
Will FPC use this feature in a near future, or should I make ASMs functions and procedure to use it?
namely RdSeed and RdRand ASM instructions described on following link

https://en.wikipedia.org/wiki/RdRand

these ASM instructions are quiet slow compared to Mersenne Twister, as explained in the above article, BUT, they exist to give TRUE random, giving high level cryptographic compliance. So, in many projects, it should be USEFUL
« Last Edit: December 14, 2017, 04:16:32 am by sam707 »

sam707

  • Guest
Re: True hard random generator
« Reply #1 on: December 14, 2017, 04:18:25 am »
making asm proc/func is not big deal tho, I'm still investigating algoritms, even will try to mix some  ;D

Eugene Loza

  • Hero Member
  • *****
  • Posts: 561
    • My "almost daily" development blog
Re: True hard random generator
« Reply #2 on: December 14, 2017, 04:32:51 am »
You may try this one: http://wiki.freepascal.org/Dev_random (Linux-only)
Lazarus 1.9 + FPC 3.1.1 Debian Jessie 64 bit.

My Free and Open Source games in Lazarus/FreePascal/CastleGameEngine:
https://decoherence.itch.io/
(and some ancient games in Turbo Pascal too)
Sources are here: https://github.com/eugeneloza?tab=repositories

Thaddy

  • Hero Member
  • *****
  • Posts: 6898
Re: True hard random generator
« Reply #3 on: December 14, 2017, 08:16:10 am »
I will add or add to/modify the following three randoms to the wiki, I already have such code including code that uses rdseed/rdrand or hwrng to seed the standard random:

/dev/random, /dev/urandom  that take entropy from several sources on nixes. Including the use of hwrng if available. There is already an entry.
https://en.wikipedia.org/wiki//dev/random
Microsoft's cryptgenrandom that take entropy from several sources on nixes. Including the use of hwrng if available.
https://en.wikipedia.org/wiki/CryptGenRandom
hwrng if availabale on a system (e.g. Raspberry Pi, modern intel. This is true hardware random that takes entropy from physics behavior on the chip
e.g. https://sites.google.com/site/astudyofentropy/project-definition/raspberry-pi-internal-hardware-random-number-generator
I have an article ready but my health failed badly and I needed to add a few more examples.

Note the standard random functions will always be a PRNG and possible always the mersenne twister. This is because its purpose also lies in statstics and must be reproducable:
Given the same seed it *must* produce the same random series.
True random is available through other means already and is not repeatable. Its purpose lies e.g. in cryptography.
I already added a number of alternative PRNG's to the wiki for e.g. Delphi compatible random and e.g. superfast prng's for gaming etc.
I also provided a patch in trunk for a generic version of RandomFrom

Further note the the OS, both Windows and nixes (IIRC except BSD), already use hwrng/rdrand/rdseed as a source of entropy for resp. CryptGenRandom and /dev/random /dev/urandom so to some extend a separate function is not required.
Also note hwrnd/rdrand/rdseed are slow, hence if some speed is required it is best to use them just to seed a quality PRNG like the mersenne twister or KISS.

A simple example for linux:
Code: Pascal  [Select]
  1. program hwrndtest;
  2. {takes a hwrng value if present and seeds Randseed with it.}
  3. {$ifdef fpc}{$mode delphi}{$H+}{$I-}{$endif}
  4. uses sysutils,classes;
  5. var
  6. L:TFilestream;
  7. begin
  8.   if fileexists('/dev/hwrng') then
  9.   begin
  10.     L:= TFilestream.create('/dev/hwrng', fmOpenread);
  11.     try
  12.       RandSeed:=L.ReadDword;
  13.     finally
  14.       writeln(RandSeed);
  15.       L.Free;
  16.     end;
  17.    end else
  18.       writeln('no hardware rng present');
  19. end.
  20.  
« Last Edit: December 14, 2017, 09:37:24 am by Thaddy »
Ada's daddy wrote this:"Fools are my theme, let satire be my song."

sam707

  • Guest
Re: True hard random generator
« Reply #4 on: December 14, 2017, 09:32:26 am »
Big  thank you @thaddy, your answer was very accurate this time.
After reading plenty of stuffs, I found that article of interest for my purpose and I'm going to give it a try (because i'ma crossplatfarm moron ya kno  :D )

https://en.wikipedia.org/wiki/Blum_Blum_Shub

sam707

  • Guest
Re: True hard random generator
« Reply #5 on: December 14, 2017, 09:36:31 am »
I read on internet that blumblumshub (niggurath??) is cryptographically secure. OMG it reminds Lovecraft foolish writer LOL ... shub niggurath
« Last Edit: December 14, 2017, 09:38:36 am by sam707 »

sam707

  • Guest
Re: True hard random generator
« Reply #6 on: December 14, 2017, 09:40:24 am »
https://github.com/foolean/blum-blum-shub
should be easy to transpose in pascal  ;)

Thaddy

  • Hero Member
  • *****
  • Posts: 6898
Re: True hard random generator
« Reply #7 on: December 14, 2017, 09:55:46 am »
Yes I already have it. Note it is only cryptographically secure because it uses the systems random functionality as seed.
Ada's daddy wrote this:"Fools are my theme, let satire be my song."

bigeno

  • Full Member
  • ***
  • Posts: 211
Re: True hard random generator
« Reply #8 on: December 14, 2017, 10:09:29 am »
if someone need here some quick examples for CryptGenRandom and RdRand for windows.
based on https://github.com/alexpmorris/WebSocketUpgrade/blob/master/crandom.pas
Code: Pascal  [Select]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Windows, Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,dynlibs;
  9.  
  10. type
  11.   fWCCryptAcquireContextA = Function (phProv: Pointer; pszContainer: LPCSTR; pszProvider: LPCSTR; dwProvType: DWORD; dwFlags: DWORD): BOOL; stdcall;
  12.   fWCCryptReleaseContext = Function (hProv: Pointer; dwFlags: DWORD): BOOL; stdcall;
  13.   fWCCryptGenRandom = Function (hProv: ULONG; dwLen: DWORD; pbBuffer: PBYTE): BOOL; stdcall;
  14.  
  15. type
  16.   TForm1 = class(TForm)
  17.     WinCryptGenRandom: TButton;
  18.     IntelDrng: TButton;
  19.     procedure WinCryptGenRandomClick(Sender: TObject);
  20.     procedure IntelDrngClick(Sender: TObject);
  21.   private
  22.   public
  23.   end;
  24.  
  25. var
  26.   Form1: TForm1;
  27.  
  28. implementation
  29.  
  30. {$R *.lfm}
  31. function TryRdRand(out Value: Cardinal): Boolean;
  32. begin
  33.   {$ASMMODE intel}
  34.   asm
  35.   db   $0f
  36.   db   $c7
  37.   db   $f1
  38.   jc   @success
  39.   xor  eax,eax
  40.   ret
  41.   @success:
  42.   mov  [eax],ecx
  43.   mov  eax,1
  44.   end;
  45. end;
  46.  
  47. procedure TForm1.WinCryptGenRandomClick(Sender: TObject);
  48. var
  49.   hProvider: ULONG = 0;
  50.   WinCryptHndl: THandle = 0;
  51.   WCCryptAcquireContextA: fWCCryptAcquireContextA;
  52.   WCCryptReleaseContext: fWCCryptReleaseContext;
  53.   WCCryptGenRandom: fWCCryptGenRandom;
  54.   res: boolean;
  55.   dwLength: DWORD;
  56.   bBuffer: array[0..7] of byte;
  57.   outr: string;
  58.   i: integer;
  59. begin
  60.   outr:='';
  61.   WinCryptHndl := LoadLibrary('advapi32.dll');
  62.   if WinCryptHndl = 0 then exit;
  63.   WCCryptAcquireContextA := fWCCryptAcquireContextA(GetProcAddress(WinCryptHndl,'CryptAcquireContextA'));
  64.   WCCryptReleaseContext := fWCCryptReleaseContext(GetProcAddress(WinCryptHndl,'CryptReleaseContext'));
  65.   WCCryptGenRandom := fWCCryptGenRandom(GetProcAddress(WinCryptHndl,'CryptGenRandom'));
  66.   if WCCryptAcquireContextA = nil then exit;
  67.   if WCCryptReleaseContext = nil  then exit;
  68.   if WCCryptGenRandom = nil       then exit;
  69.  
  70.   WCCryptAcquireContextA(@hProvider, Nil, Nil, 1, $F0000000);
  71.   dwLength:=8;
  72.   res:=WCCryptGenRandom(hProvider, dwLength, @bBuffer[0]);
  73.   if res then begin
  74.      for i:=0 to 7 do
  75.         outr:=outr+' '+IntToStr(bBuffer[i]);
  76.      showmessage(outr);
  77.   end;
  78.   WCCryptReleaseContext(@hProvider, 0);
  79. end;
  80.  
  81. procedure TForm1.IntelDrngClick(Sender: TObject);
  82. var
  83.   rnd: Cardinal;
  84. begin
  85.   if TryRdRand(rnd) then
  86.     showmessage(inttostr(rnd));
  87. end;
  88. end.  

sam707

  • Guest
Re: True hard random generator
« Reply #9 on: December 19, 2017, 12:03:02 am »
source code attached  :D
upon PCG algo I translated quickly from C
http://www.pcg-random.org

Code: Pascal  [Select]
  1. function QuickRand(IncSeed: QWord = 1): DWord;
  2. var
  3.   oldstate: QWord;
  4.   tmp0, tmp1: DWord;
  5. begin
  6.   oldstate := RndRec.state;
  7.   RndRec.Inc := IncSeed;
  8.   RndRec.state := oldstate * 6364.......
  9.  
download attached zip, compile the demo app,
ENJOY

sam707

  • Guest
Re: True hard random generator
« Reply #10 on: December 19, 2017, 12:09:35 am »
SO!
for my encryption problem I guess I'm going to use a table of 1024 bytes mersenne twister generated by standard SLOW fpc random gen, and a double shuffle by selecting indices inside the renewable table, with panquakes FAST (pgcRandom that i'm going to modify a little bit to my taste).
 :D
should be cryptosafe enough for one or two decades
Eventually change mersennelly the SeedIncrement for PCG  :-X
« Last Edit: December 19, 2017, 12:19:55 am by sam707 »

sam707

  • Guest
Re: True hard random generator
« Reply #11 on: December 19, 2017, 12:21:34 am »
I guess I will only need to transmit Seed and table  of Seeds' increments for the receiver to retreive passkeys  :o I can also encrypt these data by another way
« Last Edit: December 19, 2017, 12:23:40 am by sam707 »

sam707

  • Guest
Re: True hard random generator
« Reply #12 on: December 22, 2017, 11:00:05 am »
a littel noisy patch to apply to my simple source code in the zip above
(adjustable pseudoNoise, see comments)
well, this should be cryptosafe  bytes generator ;D
(panquakes twoaster*mersenne²/(1/sqrt(-sausage)))=myShakedAss happy for 2 decades (until quantum processors rise from kangaroos' pockets)
hehehe
Code: Pascal  [Select]
  1. function QuickRand(IncSeed: QWord = 1): DWord;
  2. var
  3.   oldstate: QWord;
  4.   tmp0, tmp1: DWord;
  5. begin
  6.   oldstate := RndRec.state;
  7.   RndRec.Inc := IncSeed;
  8.   RndRec.state := oldstate * 6364136223846793005 + (RndRec.Inc or 1);
  9.   tmp0 := ((oldstate shr 18) xor oldstate) shr 27;
  10.   tmp1 := oldstate shr 59;
  11.   Result := (tmp0 shr tmp1) or (tmp0 shl ((-tmp1) and 31));
  12. end;
  13.  
  14. { TForm1 }
  15.  
  16. (* pseudoNoisy sausage follows *)
  17.  
  18. procedure TForm1.Button1Click(Sender: TObject);
  19. var
  20.   r: DWord;
  21.   s: cardinal;
  22. begin
  23. { following if..then breaks the 'period' by random jumps ahead }
  24.   if random(1023)< 321 then { adjustable }
  25.     s := 1
  26.   else
  27.     s := succ(random(14));
  28.   if random(255) > (15+random(17)) then { adjustable }
  29.     r := QuickRand
  30.   else
  31.     r := QuickRand(s);
  32.   Edit1.Text := Format('%U', [r]);
  33. end;
  34.  
  35. initialization
  36.   Randomize;
  37.   RndRec.state := RandSeed + 6364136223846793005;
  38. { RandSeed is the value to pass to client for that
  39.   last to retrieve same panquakes twoaster random values }
  40.  
  41. end.
  42.  

« Last Edit: December 22, 2017, 02:03:47 pm by sam707 »

sam707

  • Guest
Re: True hard random generator
« Reply #13 on: December 22, 2017, 02:12:07 pm »
where 6364136223846793005 comes from?
https://en.wikipedia.org/wiki/Linear_congruential_generator
see table of parameters commonly used
lines
- MMIX by Donald Knuth
- Newlib, Musl
uncongrulethal load... sumthing  :o
it's not that magic LOL
achording to wiki, Seed Increment can be from 1 to 1442695040888963407 (even numbers 1..3...5...7...in PCG algo. ok im tired and lazy lol) make your own choices
« Last Edit: December 22, 2017, 02:21:53 pm by sam707 »

sam707

  • Guest
Re: True hard random generator
« Reply #14 on: December 22, 2017, 02:18:39 pm »
i'm done with random  ;D my 12.629 IQ hurts
as I don't want to work on the chaos equation  at the moment :D :D :D
im not drunk enough, I ain't a Edward Lorenz fan so far
take care you all,
have fun!!!
https://en.wikipedia.org/wiki/Lorenz_system
https://en.wikipedia.org/wiki/Chaos_theory
« Last Edit: December 22, 2017, 02:31:20 pm by sam707 »

 

Recent

Get Lazarus at SourceForge.net. Fast, secure and Free Open Source software downloads Open Hub project report for Lazarus