The ISAAC cipher: Difference between revisions

Line 3,068:
XOR : 1C0636190B1260233B35125F1E1D0E2F4C5422
XOR dcr: a Top Secret secret
</pre>
 
=={{header|Phix}}==
{{trans|Pascal}}
<lang Phix>-- demo\rosetta\ISAAC_Cipher.exw
 
sequence randrsl = repeat(0,256)
integer randcnt
 
sequence mm
atom aa,bb,cc
function r32(object a)
if sequence(a) then
for i=1 to length(a) do
a[i] = r32(a[i])
end for
return a
end if
if a<0 then a+=#100000000 end if
return remainder(a,#100000000)
end function
 
function shl(atom word, integer bits)
return r32(word*power(2,bits))
end function
 
function shr(atom v, integer bits)
return floor(v/power(2,bits))
end function
 
procedure Isaac()
cc += 1; -- cc just gets incremented once per 256 results
bb += cc; -- then combined with bb
for i=1 to 256 do
atom x = mm[i]
switch mod(i-1,4) do
case 0: aa := xor_bits(aa,shl(aa,13))
case 1: aa := xor_bits(aa,shr(aa, 6))
case 2: aa := xor_bits(aa,shl(aa, 2))
case 3: aa := xor_bits(aa,shr(aa,16))
end switch
aa = r32(mm[xor_bits(i-1,#80)+1]+aa)
atom y := mm[and_bits(shr(x,2),#FF)+1]+aa+bb
mm[i] := y;
bb := r32(mm[and_bits(shr(y,10),#FF)+1] + x)
randrsl[i]:= bb;
end for
randcnt = 1
end procedure
function mix(sequence a8)
atom {a,b,c,d,e,f,g,h} = a8
a = xor_bits(a,shl(b,11)); {d,b} = r32({d+a,b+c});
b = xor_bits(b,shr(c, 2)); {e,c} = r32({e+b,c+d});
c = xor_bits(c,shl(d, 8)); {f,d} = r32({f+c,d+e});
d = xor_bits(d,shr(e,16)); {g,e} = r32({g+d,e+f});
e = xor_bits(e,shl(f,10)); {h,f} = r32({h+e,f+g});
f = xor_bits(f,shr(g, 4)); {a,g} = r32({a+f,g+h});
g = xor_bits(g,shl(h, 8)); {b,h} = r32({b+g,h+a});
h = xor_bits(h,shr(a, 9)); {c,a} = r32({c+h,a+b});
a8 = {a,b,c,d,e,f,g,h}
return a8
end function
 
procedure iRandInit()
{aa,bb,cc} = {0,0,0}
sequence a8 = repeat(#9e3779b9,8) -- the golden ratio
for i=1 to 4 do -- scramble it
a8 = mix(a8)
end for
for i=1 to 255 by 8 do
a8 = mix(sq_add(a8,randrsl[i..i+7]))
mm[i..i+7] = a8
end for
for i=1 to 255 by 8 do
a8 = mix(r32(sq_add(a8,mm[i..i+7])))
mm[i..i+7] = a8
end for
Isaac() -- fill in the first set of results
end procedure
procedure iSeed(string seed)
mm = repeat(0,256)
randrsl = repeat(0,256)
randrsl[1..min(length(seed),256)] = seed
iRandInit()
end procedure
function randch()
atom res = mod(randrsl[randcnt],95)+32
randcnt += 1
if randcnt>256 then
Isaac()
end if
return res
end function
function Vernam(string msg)
string res = ""
for i=1 to length(msg) do
res &= xor_bits(msg[i],randch())
end for
return res
end function
 
function Caesar(integer ch, shift)
return ' '+mod(ch-' '+shift,95)
end function
enum ENCRYPT = +1,
DECRYPT = -1
 
function Vigenere(string msg, integer mode)
string res = ""
for i=1 to length(msg) do
res &= Caesar(msg[i],randch()*mode)
end for
return res
end function
constant string msg = "a Top Secret secret",
key = "this is my secret key"
 
iSeed(key)
string xctx := Vernam(msg),
mctx := Vigenere(msg,ENCRYPT)
 
iSeed(key)
string xptx := Vernam(xctx),
mptx := Vigenere(mctx,DECRYPT)
 
function ascii2hex(string s)
string res = ""
for i=1 to length(s) do
res &= sprintf("%02x",s[i])
end for
return res
end function
 
printf(1,"Message: %s\n",{msg})
printf(1,"Key : %s\n",{key})
printf(1,"XOR : %s\n",{ascii2hex(xctx)})
printf(1,"MOD : %s\n",{ascii2hex(mctx)})
printf(1,"XOR dcr: %s\n",{xptx})
printf(1,"MOD dcr: %s\n",{mptx})</lang>
{{out}}
<pre>
Message: a Top Secret secret
Key : this is my secret key
XOR : 1C0636190B1260233B35125F1E1D0E2F4C5422
MOD : 734270227D36772A783B4F2A5F206266236978
XOR dcr: a Top Secret secret
MOD dcr: a Top Secret secret
</pre>
 
7,795

edits