Implementing the ChaCha Pseudo-Random Number Generator (PNRG) in Julia

Implementation

Preliminary functions

In [30]:
2 ^ 32, 1 << 32, 2 << 31
Out[30]:
(4294967296, 4294967296, 4294967296)
In [10]:
@time 1 << 31
@time 2 ^ 31
  0.000010 seconds (5 allocations: 176 bytes)
  0.000127 seconds (5 allocations: 176 bytes)
Out[10]:
2147483648
In [37]:
function roll(x, n)
    return (x << n) % (1 << 32) + (x >> (32 - n))
end
Out[37]:
roll (generic function with 1 method)

We can test our operation:

In [39]:
a = 0x11111111
b = 0x01020304
c = 0x77777777
d = 0x01234567
println(c + d)
println(0x789abcde)
c = c + d
println(xor(b, c))
println(0x7998bfda)
b = xor(b, c)
println(roll(b, 7))
println(0xcc5fed3c)
2023406814
2023406814
2040053722
2040053722
3428838716
3428838716

Now the "quarter round" is implemented like this:

In [48]:
function quarter_round(a, b, c, d)
    a = (a + b) % (1 << 32)
    d = roll(xor(d, a), 16)
    c = (c + d) % (1 << 32)
    b = roll(xor(b, c), 12)
    a = (a + b) % (1 << 32)
    d = roll(xor(d, a),  8)
    c = (c + d) % (1 << 32)
    b = roll(xor(b, c),  7)
    return a, b, c, d
end
Out[48]:
quarter_round (generic function with 2 methods)
In [49]:
a = 0x11111111
b = 0x01020304
c = 0x9b8d6f43
d = 0x01234567

quarter_round(a, b, c, d)
Out[49]:
(0x00000000ea2a92f4, 0x00000000cb1cf8ce, 0x000000004581472e, 0x000000005881c4bb)
In [50]:
typeof(a)
Out[50]:
UInt32
In [51]:
0xea2a92f4, 0xcb1cf8ce, 0x4581472e, 0x5881c4bb
Out[51]:
(0xea2a92f4, 0xcb1cf8ce, 0x4581472e, 0x5881c4bb)

Examples

In [ ]:

In [ ]:

In [ ]:

Tests

In [ ]:

In [ ]:

In [ ]: