Jump to content

ISAAC Crytpographic Random Number Generator


Recommended Posts

I've managed to find a very interesting, Cryptographic Random Number Generator after a few hours of browsing, ISAAC.

I managed to locate a Visual Basic implementation of it, and i tried my hand at converting (i have about 5 minutes experience in VB :)) and ended up with a whole bunch of errors and warnings :)

If anyone is willing to translate it into AutoIT code, feel free! (There's a virtual cookie in it for you :) )

Visual Basic source: http://www.burtleburtle.net/bob/rand/basISAAC.txt

ISAAC Website: http://www.burtleburtle.net/bob/rand/isaacafa.html

My scripts:AppLauncherTRAY - Awesome app launcher that runs from the system tray NEW VERSION! | Run Length Encoding - VERY simple compression in pure autoit | Simple Minesweeper Game - Fun little game :)My website

Link to comment
Share on other sites

  • 4 weeks later...

I don't know if your still wanting this or not, but I finally had some time to play with it and this is what I have. It's just a straight translation from the file you linked to. I'll play with it more later and see if I can make it better suited for AutoIt.

; ISAAC Random Number Generator

Global $VB_Name = "basISAAC"

Global Const $MODULE_NAME = "clsISAAC"
Global Const $MAXDBL = 4292967296
Global Const $MAXDBL_MINUS1 = 4292967295
Global Const $MAXLONG = 2147483647
Global Const $MAXLONG_NEG = -2147483648

; GetTickCount == TimeInit()

Global $malngRand[257]
Global $malngMem[257]
Global $malngPower2[31]
Global $mlngSeed1
Global $mlngSeed2
Global $mlngSeed3

Main()

Func ISAAC_Prng($lngArraySize = 1, $blnReturnFloat = True)
    Local $lngIndex
    Local $lngRand
    Local $lngLoop
    Local $lngCount = 0
    Local $alngData[$lngArraySize]
    Local $adblData[$lngArraySize]
    Local $vReturn
    
    ; Only used to clear the memory out of these arrays
    Global $malngRand[256]
    Global $malngMem[256]
    
    LoadPower2()        ; Load the Power2 Array
    RandomInit(True)    ; full seeding and calculations
    
    For $lngIndex = 0 To $lngArraySize - 1
        ISAAC_Calc()
        
        For $lngLoop = 0 To 255
            $lngRand = $malngRand[$lngLoop]
            If $blnReturnFloat Then
                $adblData[$lngCount] = $lngRand / $MAXLONG
            Else
                $alngData[$lngCount] = $lngRand
            EndIf
            
            $lngCount += 1
            
            If $lngCount = $lngArraySize Then
                ExitLoop
            EndIf
        Next
        
        If $lngCount = $lngArraySize Then
            ExitLoop
        EndIf
        
        RandomInit(False)
    Next
    
    ; Clean_Up
    If $blnReturnFloat Then
        $vReturn = $adblData
    Else
        $vReturn = $alngData
    EndIf
    
    ; Empty the arrays
    Global $malngRand[256]
    Global $malngMem[256]

    Return $vReturn
EndFunc

Func ISAAC_Calc()
    Local $intIndex
    Local $intSwitch
    Local $XX
    Local $YY
    
    $mlngSeed3 += 1
    $mlngSeed2 = uAdd($mlngSeed2, $mlngSeed3)
    
    For $intIndex = 0 To 252 Step 4
        $XX = $malngMem[$intIndex]
        $mlngSeed1 = BitXOR($mlngSeed1,ShiftLong($mlngSeed1, 13))
        $mlngSeed1 = uAdd($malngMem[Mod(($intIndex+128),256)], $mlngSeed1)
        $YY = uAdd(uAdd($malngMem[Mod(Abs(ShiftLong($XX, 2, False)),256)], $mlngSeed1), $mlngSeed2)
        $malngMem[$intIndex] = $YY
        $mlngSeed2 = uAdd($malngMem[Mod(Abs(ShiftLong($YY, 10, False)), 256)], $XX)
        $malngRand[$intIndex] = $mlngSeed2
        
        $XX = $malngMem[$intIndex + 1]
        $mlngSeed1 = BitXOR($mlngSeed1,ShiftLong($mlngSeed1, 6, False))
        $mlngSeed1 = uAdd($malngMem[Mod(($intIndex + 128 + 1), 256)], $mlngSeed1)
        $YY = uAdd(uAdd($malngMem[Mod(Abs(ShiftLong($XX, 2, False)), 256)], $mlngSeed1), $mlngSeed2)
        $malngMem[$intIndex + 1] = $YY
        $mlngSeed2 = uAdd($malngMem[Mod(Abs(ShiftLong($YY, 10, False)), 256)], $XX)
        $malngRand[$intIndex + 1] = $mlngSeed2
        
        $XX = $malngMem[$intIndex + 2]
        $mlngSeed1 = BitXOR($mlngSeed1,ShiftLong($mlngSeed1, 2))
        $mlngSeed1 = uAdd($malngMem[Mod(($intIndex + 128 + 2), 256)], $mlngSeed1)
        $YY = uAdd(uAdd($malngMem[Mod(Abs(ShiftLong($XX, 2, False)), 256)], $mlngSeed1), $mlngSeed2)
        $malngMem[$intIndex + 2] = $YY
        $mlngSeed2 = uAdd($malngMem[Mod(Abs(ShiftLong($YY, 10, False)), 256)], $XX)
        $malngRand[$intIndex + 2] = $mlngSeed2
        
        $XX = $malngMem[$intIndex + 3]
        $mlngSeed1 = BitXOR($mlngSeed1,ShiftLong($mlngSeed1, 16, False))
        $mlngSeed1 = uAdd($malngMem[Mod(($intIndex + 128 + 3), 256)], $mlngSeed1)
        $YY = uAdd(uAdd($malngMem[Mod(Abs(ShiftLong($XX, 2, False)), 256)], $mlngSeed1), $mlngSeed2)
        $malngMem[$intIndex + 3] = $YY
        $mlngSeed2 = uAdd($malngMem[Mod(Abs(ShiftLong($YY, 10, False)), 256)], $XX)
        $malngRand[$intIndex + 3] = $mlngSeed2
    Next
EndFunc

Func RandomInit($blnSeed)
    Local $AA, $BB, $CC, $DD
    Local $EE, $FF, $GG, $HH
    Local $intIndex
    
    If $blnSeed Then
        CreateSeed()
    EndIf
    
    $AA = 0xDFD5A9EA
    $BB = 0x3B122602
    $CC = 0x110FF1A8
    $DD = 0xFB44EDF1
    $EE = 0xEF3C10FD
    $FF = 0x1CEB6088
    $GG = 0x1D670408
    $HH = 0x3E01C8CE
    
    For $intIndex = 0 To 248 Step 8
        If $blnSeed Then
            $AA = uAdd($AA, $malngRand[$intIndex])
            $BB = uAdd($BB, $malngRand[$intIndex + 1])
            $CC = uAdd($CC, $malngRand[$intIndex + 2])
            $DD = uAdd($DD, $malngRand[$intIndex + 3])
            $EE = uAdd($EE, $malngRand[$intIndex + 4])
            $FF = uAdd($FF, $malngRand[$intIndex + 5])
            $GG = uAdd($GG, $malngRand[$intIndex + 6])
            $HH = uAdd($HH, $malngRand[$intIndex + 7])
        EndIf
        
        Mix($AA, $BB, $CC, $DD, $EE, $FF, $GG, $HH)
        
        $malngMem[$intIndex] = $AA
        $malngMem[$intIndex + 1] = $BB
        $malngMem[$intIndex + 2] = $CC
        $malngMem[$intIndex + 3] = $DD
        $malngMem[$intIndex + 4] = $EE
        $malngMem[$intIndex + 5] = $FF
        $malngMem[$intIndex + 6] = $GG
        $malngMem[$intIndex + 7] = $HH
    Next
    
    If $blnSeed Then
        For $intIndex = 0 To 248 Step 8
            $AA = uAdd($AA, $malngMem[$intIndex])
            $BB = uAdd($BB, $malngMem[$intIndex + 1])
            $CC = uAdd($CC, $malngMem[$intIndex + 2])
            $DD = uAdd($DD, $malngMem[$intIndex + 3])
            $EE = uAdd($EE, $malngMem[$intIndex + 4])
            $FF = uAdd($FF, $malngMem[$intIndex + 5])
            $GG = uAdd($GG, $malngMem[$intIndex + 6])
            $HH = uAdd($HH, $malngMem[$intIndex + 7])

            Mix($AA, $BB, $CC, $DD, $EE, $FF, $GG, $HH)
            
            $malngMem[$intIndex] = $AA
            $malngMem[$intIndex + 1] = $BB
            $malngMem[$intIndex + 2] = $CC
            $malngMem[$intIndex + 3] = $DD
            $malngMem[$intIndex + 4] = $EE
            $malngMem[$intIndex + 5] = $FF
            $malngMem[$intIndex + 6] = $GG
            $malngMem[$intIndex + 7] = $HH
        Next
    EndIf
    ISAAC_Calc()
EndFunc

Func Mix(ByRef $AA, ByRef $BB, ByRef $CC, ByRef $DD, ByRef $EE, ByRef $FF, ByRef $GG, ByRef $HH)
    $AA = BitXOR($AA, ShiftLong($BB, 11))
        $DD = uAdd($DD, $AA)
            $BB = uAdd($BB, $CC)
    $BB = BitXOR($BB, ShiftLong($CC, 2, False))
        $EE = uAdd($EE, $BB)
            $CC = uAdd($CC, $DD)
    $CC = BitXOR($CC, ShiftLong($DD, 8))
        $FF= uAdd($FF, $CC)
            $DD = uAdd($DD, $EE)
    $DD = BitXOR($DD, ShiftLong($EE, 16, False))
        $GG = uAdd($GG, $DD)
            $EE = uAdd($EE, $FF)
    $EE = BitXOR($EE, ShiftLong($FF, 10))
        $HH = uAdd($HH, $EE)
            $FF = uAdd($FF, $GG)
    $FF = BitXOR($FF, ShiftLong($GG, 4, False))
        $AA = uAdd($AA, $FF)
            $GG = uAdd($GG, $HH)
    $GG = BitXOR($GG, ShiftLong($HH, 8))
        $BB = uAdd($BB, $GG)
            $HH = uAdd($HH, $AA)
    $HH = BitXOR($HH, ShiftLong($AA, 9, False))
        $CC = uAdd($CC, $HH)
            $AA = uAdd($AA, $BB)
EndFunc

Func CreateSeed()
    $mlngSeed1 = 0
    $mlngSeed2 = 0
    $mlngSeed3 = 0
EndFunc

Func uAdd($lngValue1, $lngValue2)
    Local $dblTemp
    
    $dblTemp = $lngValue1 + $lngValue2
    
    If $dblTemp < $MAXLONG_NEG Then
        Return $MAXDBL + $dblTemp
    Else
        If $dblTemp > $MAXLONG Then
            Return $dblTemp - $MAXDBL
        Else
            Return $dblTemp
        EndIf
    EndIf
EndFunc

Func ShiftLong($lngValue, $intShiftCount, $blnShiftLeft = True)
    Local $lngMask
    Local $lngIndex
    Local $lngSignBit
    Local $ShiftLong
    
    If $intShiftCount <= 0 Then
        Return $lngValue
    EndIf
    
    If $intShiftCount > 31 Then
        Return
    EndIf
    
    If $blnShiftLeft Then
        $lngMask = $malngPower2[31 - $intShiftCount]
        
        If BitAND($lngValue, $lngMask) Then
            $ShiftLong = BitOR((BitAND($lngValue, $lngMask - 1) * $malngPower2[$intShiftCount]), 0x80000000)
        Else
            $ShiftLong = BitAND($lngValue, $lngMask - 1) * $malngPower2[$intShiftCount]
        EndIf
    Else
        If $intShiftCount < 31 Then
            If BitAND($lngValue, 0x80000000) Then
                $ShiftLong = Int($lngValue / $malngPower2[$intShiftCount])
                
                If $ShiftLong * $malngPower2[$intShiftCount] <> $lngValue Then
                    $ShiftLong -= 1
                EndIf
            Else
                $ShiftLong = Int($lngValue / $malngPower2[$intShiftCount])
            EndIf
        Else
            If BitAND($lngValue, 0x80000000) Then
                $ShiftLong = -1
            Else
                $ShiftLong = 0
            EndIf
        EndIf
    EndIf
    Return $ShiftLong
EndFunc

Func LoadPower2()
    Global $malngPower2[31]
    
    $malngPower2[0] = 1            ; 00000000000000000000000000000001
    $malngPower2[1] = 2            ; 00000000000000000000000000000010
    $malngPower2[2] = 4            ; 00000000000000000000000000000100
    $malngPower2[3] = 8            ; 00000000000000000000000000001000
    $malngPower2[4] = 16           ; 00000000000000000000000000010000
    $malngPower2[5] = 32           ; 00000000000000000000000000100000
    $malngPower2[6] = 64           ; 00000000000000000000000001000000
    $malngPower2[7] = 128          ; 00000000000000000000000010000000
    $malngPower2[8] = 256          ; 00000000000000000000000100000000
    $malngPower2[9] = 512          ; 00000000000000000000001000000000
    $malngPower2[10] = 1024        ; 00000000000000000000010000000000
    $malngPower2[11] = 2048        ; 00000000000000000000100000000000
    $malngPower2[12] = 4096        ; 00000000000000000001000000000000
    $malngPower2[13] = 8192        ; 00000000000000000010000000000000
    $malngPower2[14] = 16384       ; 00000000000000000100000000000000
    $malngPower2[15] = 32768       ; 00000000000000001000000000000000
    $malngPower2[16] = 65536       ; 00000000000000010000000000000000
    $malngPower2[17] = 131072      ; 00000000000000100000000000000000
    $malngPower2[18] = 262144      ; 00000000000001000000000000000000
    $malngPower2[19] = 524288      ; 00000000000010000000000000000000
    $malngPower2[20] = 1048576     ; 00000000000100000000000000000000
    $malngPower2[21] = 2097152     ; 00000000001000000000000000000000
    $malngPower2[22] = 4194304     ; 00000000010000000000000000000000
    $malngPower2[23] = 8388608     ; 00000000100000000000000000000000
    $malngPower2[24] = 16777216    ; 00000001000000000000000000000000
    $malngPower2[25] = 33554432    ; 00000010000000000000000000000000
    $malngPower2[26] = 67108864    ; 00000100000000000000000000000000
    $malngPower2[27] = 134217728   ; 00001000000000000000000000000000
    $malngPower2[28] = 268435456   ; 00010000000000000000000000000000
    $malngPower2[29] = 536870912   ; 00100000000000000000000000000000
    $malngPower2[30] = 1073741824  ; 01000000000000000000000000000000
EndFunc

Func Main()
    Local $hFile
    Local $lngIndex
    Local $lngColCount = 0
    Local $lngCount = 0
    Local $dblTotal = 0
    Local $dblLow = 1
    Local $dblHigh = 0
    Local $strFmt = "@@@@@@@@@@@@@@@"
    Local $strTemp
    Local $alngData
    Local $adblData
    Local $lngStart
    Local $strElapsed
    
    Local Const $FN_DBL = "Isaac_Dbl.txt"
    Local Const $FN_LNG = "Isaac_Lng.txt"
    Local Const $FCOUNT = 100000
    Local Const $SAMPLE = 100
    
    Local $strTitle = "ISAAC Double precision values" & @CRLF & _
                      $FCOUNT & " random generated numbers" & @CRLF & _
                      "Saving every " & $SAMPLE & "th value for this display"

    
    $lngStart = TimerInit()
    $adblData = ISAAC_Prng($FCOUNT, True)
    $strElapsed = TimerDiff($lngStart)
    
    For $lngIndex = 0 To $FCOUNT - 1
        $dblTotal = $dblTotal + $adblData[$lngIndex]
        
        If $dblLow > $adblData[$lngIndex] Then
            $dblLow = $adblData[$lngIndex]
        ElseIf $adblData[$lngIndex] > $dblHigh Then
            $dblHigh = $adblData[$lngIndex]
        EndIf
    Next
    
    $hFile = FileOpen($FN_DBL, 2)
    FileWrite($hFile, $strTitle & @CRLF)
    FileWrite($hFile, "Elapsed: " & $strElapsed & @CRLF)
    
    FileWrite($hFile, " Lowest: " & $dblLow & @CRLF)
    FileWrite($hFile, "Highest: " & $dblHigh & @CRLF)
    FileWrite($hFile, @CRLF)
    
    For $lngIndex = 0 To $FCOUNT - 1
        If Mod($lngCount, $SAMPLE) = 0 Then
            FileWrite($hFile, $adblData[$lngIndex] & @TAB)
            $lngColCount += 1
        EndIf
        
        If $lngColCount = 5 Then
            FileWrite($hFile, @CRLF)
            $lngColCount = 0
        EndIf
        
        $lngCount+= 1
    Next
    
    FileClose($hFile)
    
    MsgBox(0, "ISAAC Float Values", $FN_DBL & @CRLF & "Elapsed: " & $strElapsed)
    
    $lngColCount = 0
    $lngCount = 0
    
    $dblLow = $MAXLONG
    $dblHigh = 0
    $dblTotal = 0
    
    $strTitle = "ISAAC Long Integer values" & @CRLF & _
                $FCOUNT & " random generated numbers" & @CRLF & _
                "Saving every " & $SAMPLE & "th value for this display"
                
    $lngStart = TimerInit()
    $alngData = ISAAC_Prng($FCOUNT, False)
    $strElapsed = TimerDiff($lngStart)
    
    For $lngIndex = 0 To $FCOUNT - 1
        $dblTotal += $alngData[$lngIndex]
        
        If $dblLow > $alngData[$lngIndex] Then
            $dblLow = $alngData[$lngIndex]
        ElseIf $alngData[$lngIndex] > $dblHigh Then
            $dblHigh = $alngData[$lngIndex]
        EndIf
    Next
    
    $hFile = FileOpen($FN_LNG, 2)
    FileWrite($hFile, $strTitle & @CRLF)
    FileWrite($hFile, "Elapsed: " & $strElapsed & @CRLF)
    
    FileWrite($hFile, " Lowest: " & $dblLow & @CRLF)
    FileWrite($hFile, "Highest: " & $dblHigh & @CRLF)
    FileWrite($hFile, @CRLF)
    
    For $lngIndex = 0 To $FCOUNT - 1
        If Mod($lngCount, $SAMPLE) = 0 Then
            FileWrite($hFile, $alngData[$lngIndex] & @TAB)
            $lngColCount += 1
        EndIf

        If $lngColCount = 6 Then
            FileWrite($hFile, @CRLF)
            $lngColCount = 0
        EndIf
        $lngCount += 1
    Next
    
    FileClose($hFile)
    
    MsgBox(0, "ISAAC Long Integers", $FN_LNG & @CRLF & "Elapsed:  " & $strElapsed & @CRLF & @CRLF & _
        "TESTING COMPLETE!")
        
EndFunc
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...