The ISAAC cipher: Difference between revisions

m
no edit summary
(Added Kotlin)
mNo edit summary
Line 2,163:
}
}</lang>
 
=={{header|Julia}}==
<lang Julia>
"""
Julia translation of code from the following:
------------------------------------------------------------------------------
readable.c: My random number generator, ISAAC.
(c) Bob Jenkins, March 1996, Public Domain
You may use this code in any way you wish, and it is free. No warrantee.
------------------------------------------------------------------------------
"""
# maximum length of message here is set to 4096
const MAXMSG = 4096
 
# cipher modes for encryption versus decryption modes
@enum CipherMode mEncipher mDecipher mNone
 
# external results
mutable struct IState
randrsl::Array{UInt32, 1}
randcnt::UInt32
mm::Array{UInt32, 1}
aa::UInt32
bb::UInt32
cc::UInt32
function IState()
this = new()
this.randrsl = zeros(UInt32, 256)
this.randcnt = UInt32(0)
this.mm = zeros(UInt32, 256)
this.aa = this.bb = this.cc = UInt32(0)
this
end
end
 
"""
isaac
Randomize the pool
"""
function isaac(istate)
istate.cc += 1 # cc gets incremented once per 256 results
istate.bb += istate.cc # then combined with bb
 
for (j, c) in enumerate(istate.mm) # Julia NB: indexing ahead so use i for c indexing
i = j - 1
xmod4 = i % 4
if(xmod4 == 0)
istate.aa ⊻= istate.aa << 13
elseif(xmod4 == 1)
istate.aa ⊻= istate.aa >> 6
elseif(xmod4 == 2)
istate.aa ⊻= istate.aa << 2
else
istate.aa ⊻= istate.aa >> 16
end
istate.aa += istate.mm[(i + 128) % 256 + 1]
y = istate.mm[(c >> 2) % 256 + 1] + istate.aa + istate.bb
istate.mm[j] = y
istate.bb = istate.mm[(y >> 10) % 256 + 1] + c
istate.randrsl[j] = istate.bb
end
# not in original readable.c
istate.randcnt = 0
end
 
 
function mix(arr) # Julia NB: use E for e in c code here
(a,b,c,d,E,f,g,h) = arr
a⊻=b<<11; d+=a; b+=c;
b⊻=c>>2; E+=b; c+=d;
c⊻=d<<8; f+=c; d+=E;
d⊻=E>>16; g+=d; E+=f;
E⊻=f<<10; h+=E; f+=g;
f⊻=g>>4; a+=f; g+=h;
g⊻=h<<8; b+=g; h+=a;
h⊻=a>>9; c+=h; a+=b;
(a,b,c,d,E,f,g,h)
end
 
 
"""
randinit
Make a random UInt32 array.
If flag is true, use the contents of randrsl[] to initialize mm[].
"""
function randinit(istate, flag::Bool)
istate.aa = istate.bb = istate.cc = 0
mixer = Array{UInt32,1}(8)
fill!(mixer, 0x9e3779b9) # the golden ratio
for i in 1:4 # scramble it
mixer = mix(mixer)
end
for i in 0:8:255 # fill in mm[] with messy stuff
if(flag) # use all the information in the seed
mixer = [mixer[j] + istate.randrsl[i+j] for j in 1:8]
end
mixer = mix(mixer)
istate.mm[i+1:i+8] .= mixer
end
if(flag) # do a second pass to seed all of mm
for i in 0:8:255
mixer = [mixer[j] + istate.mm[i+j] for j in 1:8]
mixer = mix(mixer)
istate.mm[i+1:i+8] .= mixer
end
end
isaac(istate) # fill in the first set of results
istate.randcnt = 0
end
 
 
"""
Get a random 32-bit value 0..MAXINT
"""
function irandom(istate)
retval::UInt32 = istate.randrsl[istate.randcnt+1]
istate.randcnt += 1
if(istate.randcnt > 255)
isaac(istate)
istate.randcnt = 0
end
retval
end
 
 
"""
Get a random character in printable ASCII range
"""
iranda(istate) = UInt8(irandom(istate) % 95 + 32)
 
 
"""
Do XOR cipher on random stream.
Output: UInt8 array
"""
vernam(istate, msg) = [UInt8(iranda(istate) ⊻ c) for c in msg]
 
 
"""
Seed ISAAC with a string
"""
function iseed(istate, seed, flag)
fill!(istate.mm, 0)
fill!(istate.randrsl, 0)
len = min(length(seed), length(istate.randrsl))
istate.randrsl[1:len] .= seed[1:len]
randinit(istate, flag) # initialize ISAAC with seed
end
 
 
tohexstring(arr::Array{UInt8,1}) = join([hex(i, 2) for i in arr])
 
 
function test(istate, msg, key)
# Vernam ciphertext & plaintext
vctx = zeros(UInt8, MAXMSG)
vptx = zeros(UInt8, MAXMSG)
# Encrypt: Vernam XOR
iseed(istate, Vector{UInt8}(key), true)
vctx = vernam(istate, Vector{UInt8}(msg))
# Decrypt: Vernam XOR
iseed(istate, Vector{UInt8}(key), true)
vptx = vernam(istate, vctx)
# Program output
println("Message: $msg")
println("Key : $key")
println("XOR : $(tohexstring(vctx))")
# Output Vernam decrypted plaintext
println("XOR dcr: $(join(map(c -> Char(c), vptx)))")
0
end
 
"""
Test the above.
"""
const msg = "a Top Secret secret"
const key = "this is my secret key"
test(IState(), msg, key)
</lang>
{{output}}<pre>
Message: a Top Secret secret
Key : this is my secret key
XOR : 1c0636190b1260233b35125f1e1d0e2f4c5422
XOR dcr: a Top Secret secret
</pre>
 
=={{header|Kotlin}}==
4,102

edits