CryptoCSPRNG.Mod 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. MODULE CryptoCSPRNG; (** AUTHOR "GF"; PURPOSE "Cryptographically Secure Pseudo-Random Generator."*)
  2. IMPORT Machine, Clock, Heaps, SHA3 := CryptoSHA3(*, Out := KernelLog*);
  3. PROCEDURE CSRand*( VAR rand: ARRAY OF CHAR; bits: LONGINT );
  4. VAR
  5. seed: HUGEINT; i, j, len: LONGINT;
  6. h: SHA3.Hash;
  7. buf: ARRAY 64 OF CHAR;
  8. BEGIN
  9. ASSERT( (bits MOD 8 = 0) & (bits DIV 8 <= LEN( rand )) );
  10. seed := Noise();
  11. FOR i := 0 TO 7 DO
  12. buf[i] := CHR( seed MOD 100H ); seed := seed DIV 100H
  13. END;
  14. NEW( h ); h.SetNameAndSize( "", 64 );
  15. h.Update( buf, 0, 8 );
  16. h.GetHash( buf, 0 );
  17. i := 0; j := 0; len := bits DIV 8;
  18. WHILE j < len DO
  19. IF i = 64 THEN
  20. h.Initialize;
  21. h.Update( buf, 0, 64 );
  22. h.GetHash( buf, 0 );
  23. i := 0
  24. END;
  25. rand[j] := buf[i]; INC( j ); INC( i )
  26. END
  27. END CSRand;
  28. PROCEDURE Noise( ): HUGEINT;
  29. VAR tm, dt: HUGEINT; t, d: LONGINT; total, free, largest: SIZE;
  30. BEGIN
  31. tm := Machine.GetTimer( );
  32. Clock.Get( t, d );
  33. dt := LONG( d ) * 1000000H + t;
  34. Heaps.GetHeapInfo( total, free, largest );
  35. RETURN (tm + 4*dt + Heaps.Nmark) * (Heaps.Ngc + 1) + (total - free + largest )
  36. END Noise;
  37. (*
  38. PROCEDURE Test*;
  39. CONST HT = 09X;
  40. VAR rand: ARRAY 512 OF CHAR; i: LONGINT;
  41. BEGIN
  42. CSRand( rand, 2048 );
  43. Out.Ln;
  44. FOR i := 0 TO 255 DO
  45. Out.Hex( ORD( rand[i] ), -2 );
  46. IF (i+1) MOD 4 = 0 THEN Out.Char( HT ) END;
  47. IF (i+1) MOD 32 = 0 THEN Out.Ln END
  48. END;
  49. Out.Ln
  50. END Test;
  51. *)
  52. END CryptoCSPRNG.
  53. CryptoCSPRNG.Test ~
  54. System.Free CryptoCSPRNG ~