A Better Random Number Generator

Started by MrBcx, April 25, 2025, 09:03:54 PM

Previous topic - Next topic

MrBcx

Thanks Robert.  Using RND_S() as a seed is clever beyond words.

I also enjoyed learning about Cloudflare's use of Lava Lamps.

Robert

To generate a cryptographically secure seed for your BCX RANDOMIZE function, you don't need a wall of LavaLamps


MrBcx's CryptoSeed will protect you from any attacker trying to figure out your key and decrypt your data.

DIM AS DOUBLE Random
DIM AS DOUBLE TheSeed
DIM AS INTEGER i, j
TheSeed = CryptoSeed()

PUSHCOLORS

CLS
COLOR 2, 0 : LOCATE 12, 25, 0
INPUT "Hit [Enter] to see a sample", i : COLOR 7, 0
CLS
RANDOMIZE(TheSeed)
FOR i = 1 TO 23
  FOR j = 1 TO 70 STEP 20
    Random = RND
    LOCATE i, j, 0
    COLOR MOD(i, 4.0) + 10, 0
    PRINT Random
  NEXT
NEXT
LOCATE i, j
COLOR 7, j

FUNCTION CryptoSeed AS DOUBLE

  STATIC AS HCRYPTPROV hProv
  STATIC AS INTEGER isInit
  DIM AS UINT n
  DIM AS INTEGER ok

  IF isInit = 0 THEN
    ok = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)
    IF ok = FALSE  THEN FUNCTION = -1
    isInit = 1
  END IF

  ' Cast &n to BYTE* so it works with CryptGenRandom
  ok = CryptGenRandom(hProv, SIZEOF(n), (BYTE*)&n)
  IF ok = FALSE THEN FUNCTION = -1

  FUNCTION = CAST(DOUBLE, n / 4294967296.0)
END FUNCTION

POPCOLORS

PAUSE

Quin

Works well here, thanks a ton for sharing! :)

jbk


MrBcx

#1
This isn't my area of expertise but I thought someone might find this useful:
It compiles (console mode demo) and runs correctly using all the compilers:
Lcc-Win32, Pelles C, MSVC, Mingw, Clang


DIM r AS DOUBLE
DO
    r = RND_S()
    PRINT r
LOOP UNTIL INSTAT
PAUSE

FUNCTION RND_S AS DOUBLE
    '***************************************************************************
    ' Random values are uniformly distributed across the full [0.0, 1.0) range.
    ' No truncation, underflow, or casting issues.
    ' It's cryptographically secure thanks to CryptGenRandom.
    '***************************************************************************
    ' Can be considered FIPS-compliant when run on a properly configured system
    ' with a validated provider.  On Windows, enabled via Local Security Policy
    ' or: HKLM\System\CurrentControlSet\Control\Lsa\FIPSAlgorithmPolicy
    '***************************************************************************

    #include <wincrypt.h>

    STATIC hProv AS HCRYPTPROV
    STATIC isInit AS INT
    DIM n AS UINT
    DIM ok AS INT

    IF isInit = 0 THEN
        ok = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)
        IF ok = FALSE  THEN FUNCTION = -1
        isInit = 1
    END IF

    ' Cast &n to BYTE* so it works with CryptGenRandom
    ok = CryptGenRandom(hProv, SIZEOF(n), (BYTE*)&n)
    IF ok = FALSE THEN FUNCTION = -1

    FUNCTION = CAST(DOUBLE, n / 4294967296.0)
END FUNCTION