I need to communicate in PHP with a client that is using the ISAAC stream cipher. As far as I can tell, none of the crypto libraries available for PHP implement this cipher. How could one implement the ISAAC cipher in a PHP application?
(I have found a Java implementation of ISAAC, and have almost succeeded in porting it over to PHP. The only issue is unsigned right shifting in PHP. I wrote a method to do it, but the method fails when the number in the shift is negative.)
The ISAAC cipher is fairly simple, and since it's written in C, it shouldn't be too hard to port it to PHP. The only real complication is that ISAAC uses 32-bit unsigned integers with wrap-around, whereas PHP's integers may be 32 or 64 bits and get auto-converted to floats on overflow. This isn't that big an issue, though, since we can easily work around it by applying bitmasks where needed to force intermediate values down to 32 bits.
Anyway, here's a fairly direct port of the ISAAC reference code to PHP:
The
ISAAC
class constructor takes an optional$seed
parameter, which should be either a 256-element array of 32-bit integers, a string of up to 1024 bytes (which is converted to an array usingunpack()
; see the code) ornull
(the default). If the seed is null or omitted, the shorter single-pass initialization is used, which corresponds to callingrandinit()
withflag == FALSE
in the C reference implementation; otherwise, the two-pass initialization corresponding toflag == TRUE
is used.The class provides a
rand()
method that returns a single 32-bit number, just like therand()
macro defined in Jenkins'rand.h
. Alternatively, I've left the coreisaac()
method and its internal result buffer$r
public, so that those preferring more direct access to the generator can just callisaac()
themselves and grab the output that way. Note that the constructor already callsisaac()
once, just likerandinit()
in the reference implementation, so you only need to call it again after exhausting the first 256 output values.Here are two test programs, the first corresponding to the test code included inside rand.c:
and the second randtest.c from the ISAAC challenge:
The outputs of these programs should match randvect.txt and randseed.txt respectively.