I was trying out Julia for the first time and did not seem to find a CSPRNG 
available. Below is a port of Isaac64 
(http://burtleburtle.net/bob/rand/isaacafa.html). My runtime meassurements 
seem to be very poor - reading a little bit about Julia prior to trying the 
language, and especially looking at the benchmarks I was under the 
impression that run times should be relatively comparable with C. Would 
appreciate some feedback, thanks. 


function main(randrsl::Array{Uint64}=Uint64[]) #takes Uint64 array as a seed
#wrap everything to pass variables into sub-scopes implicitly
    function isaac64()
        function ind(mm,x)                #nesting ind() into rngstep makes 
it another 2-3 times slower -!
            return mm[int((x & ((RANDSIZ-1)<<3))/8)+1]
        end
        function rngstep(a_mix,m1,m2,r)
            x = mm[m1+i]
            a = (a_mix) + mm[m2+i]
            mm[m1+i] = y = (ind(mm, x) + a + b)
            randrsl[r+i] = b = (ind(mm, y>>RANDSIZL) + x)
            i+=1
        end
        a=aa; cc+=1; b=bb+cc; x=0x0000000000::Uint64; 
        m1=r=0;mid=m2=int(RANDSIZ/2); i=1;
        while (i < (mid-2)) #do it without pointers
            rngstep(~(a$(a<<21)), m1, m2, r) #sub-indexing an array creates 
a new object, pass indexes as variables
            rngstep(a$(a>>5), m1, m2, r)
            rngstep(a$(a<<12), m1, m2, r)
            rngstep(a$(a>>33), m1, m2, r)
        end
        i=1; m2=0; r=m1=(RANDSIZ/2);
        while (i<(mid-2))
            rngstep(~(a$(a<<21)),m1, m2, r)
            rngstep(a$(a>>5), m1, m2, r)
            rngstep(a$(a<<12), m1, m2, r)
            rngstep(a$(a>>33), m1, m2, r)
        end
        bb = b; aa=a;
    end

    function randinit(flag=false)
        function mix!()
            a-=e; f$=h>>9; h+=a;    #$ for bitwise xor
            b-=f; g$=a<<9;  a+=b;    #glad they didn't remove semi-columns
            c-=g; h$=b>>23; b+=c;
            d-=h; a$=c<<15; c+=d;
            e-=a; b$=d>>14; d+=e;
            f-=b; c$=e<<20; e+=f;
            g-=c; d$=f>>17; f+=g;
            h-=d; e$=g<<14; g+=h;
        end
        a=b=c=d=e=f=g=h= 0x9e3779b97f4a7c13::Uint64
        for i in range(1,4)
            mix!()
        end
        for i in range(1,8, int(RANDSIZ/8)) #dividing 256/8 produced a float
            if flag
                a+= randrsl[i ]; b+=randrsl[i+1]; c+=randrsl[i+2]; 
d+=randrsl[i+3];
                e+=randrsl[i+4]; f+=randrsl[i+5]; g+=randrsl[i+6]; 
h+=randrsl[i+7];
            end
            mix!()
            mm[i  ]=a; mm[i+1]=b; mm[i+2]=c; mm[i+3]=d;
            mm[i+4]=e; mm[i+5]=f; mm[i+6]=g; mm[i+7]=h;
        end
        if flag
            for i in range(1,8, int(RANDSIZ/8))
                a+=mm[i  ]; b+=mm[i+1]; c+=mm[i+2]; d+=mm[i+3];
                e+=mm[i+4]; f+=mm[i+5]; g+=mm[i+6]; h+=mm[i+7];
            mix!()
                mm[i  ]=a; mm[i+1]=b; mm[i+2]=c; mm[i+3]=d;
                mm[i+4]=e; mm[i+5]=f; mm[i+6]=g; mm[i+7]=h;
            end
        end
            isaac64()
            randcnt=RANDSIZ
    end
    #main scope variables
    RANDSIZL=8; RANDSIZ = length(randrsl); #add a function to allow 32byte 
input array
    if RANDSIZ == 0
        RANDSIZ = 256
        for i in range(1,RANDSIZ)
            push!(randrsl, 0)
        end                    #end statement for each conditional
    elseif RANDSIZ % 8 != 0            # would have prefered elif
        error("dimension of seeding array must be a factor of 8")
    end
    aa=bb=cc=0x0000000000::Uint64  #really won't take 0::Uint64 ?
    mm=Uint64[]
    for i in range(1,RANDSIZ) #indexes start with 1
        push!(mm, 0)
    end
    randinit(true)
    for i in range(1,2)
        isaac64()
        for j in range(1,RANDSIZ)
            @printf("%llx",randrsl[j]) #@printf for c string formatting
        end
    end
end
function timeit(f, n=10^4)
    t = time()
    for i in range(1,n)
        f()
    end
    @printf("avg running time: %llf \n", ((time() -t) / n ))
    end
timeit(main)

Reply via email to