The ISAAC cipher: Difference between revisions
Content added Content deleted
No edit summary |
|||
Line 2,753: | Line 2,753: | ||
MOD : 734270227D36772A783B4F2A5F206266236978 |
MOD : 734270227D36772A783B4F2A5F206266236978 |
||
MOD dcr : a Top Secret secret |
MOD dcr : a Top Secret secret |
||
</pre> |
|||
=={{header|Lua}}== |
|||
<lang lua> |
|||
#!/usr/bin/env lua |
|||
-- ISAAC - Lua 5.3 |
|||
-- External Results |
|||
local randRsl = {}; |
|||
local randCnt = 0; |
|||
-- Internal State |
|||
local mm = {}; |
|||
local aa,bb,cc = 0,0,0; |
|||
-- Cap to maintain 32 bit maths |
|||
local cap = 0x100000000; |
|||
-- CipherMode |
|||
local ENCRYPT = 1; |
|||
local DECRYPT = 2; |
|||
function isaac() |
|||
cc = ( cc + 1 ) % cap; -- cc just gets incremented once per 256 results |
|||
bb = ( bb + cc ) % cap; -- then combined with bb |
|||
for i = 0,255 do |
|||
local x = mm[i]; |
|||
local y; |
|||
local imod = i % 4; |
|||
if imod == 0 then aa = aa ~ (aa << 13); |
|||
elseif imod == 1 then aa = aa ~ (aa >> 6); |
|||
elseif imod == 2 then aa = aa ~ (aa << 2); |
|||
elseif imod == 3 then aa = aa ~ (aa >> 16); |
|||
end |
|||
aa = ( mm[(i+128)%256] + aa ) % cap; |
|||
y = ( mm[(x>>2) % 256] + aa + bb ) % cap; |
|||
mm[i] = y; |
|||
bb = ( mm[(y>>10)%256] + x ) % cap; |
|||
randRsl[i] = bb; |
|||
end |
|||
randCnt = 0; -- Prepare to use the first set of results. |
|||
end |
|||
function mix(a) |
|||
a[0] = ( a[0] ~ ( a[1] << 11 ) ) % cap; a[3] = ( a[3] + a[0] ) % cap; a[1] = ( a[1] + a[2] ) % cap; |
|||
a[1] = ( a[1] ~ ( a[2] >> 2 ) ) % cap; a[4] = ( a[4] + a[1] ) % cap; a[2] = ( a[2] + a[3] ) % cap; |
|||
a[2] = ( a[2] ~ ( a[3] << 8 ) ) % cap; a[5] = ( a[5] + a[2] ) % cap; a[3] = ( a[3] + a[4] ) % cap; |
|||
a[3] = ( a[3] ~ ( a[4] >> 16 ) ) % cap; a[6] = ( a[6] + a[3] ) % cap; a[4] = ( a[4] + a[5] ) % cap; |
|||
a[4] = ( a[4] ~ ( a[5] << 10 ) ) % cap; a[7] = ( a[7] + a[4] ) % cap; a[5] = ( a[5] + a[6] ) % cap; |
|||
a[5] = ( a[5] ~ ( a[6] >> 4 ) ) % cap; a[0] = ( a[0] + a[5] ) % cap; a[6] = ( a[6] + a[7] ) % cap; |
|||
a[6] = ( a[6] ~ ( a[7] << 8 ) ) % cap; a[1] = ( a[1] + a[6] ) % cap; a[7] = ( a[7] + a[0] ) % cap; |
|||
a[7] = ( a[7] ~ ( a[0] >> 9 ) ) % cap; a[2] = ( a[2] + a[7] ) % cap; a[0] = ( a[0] + a[1] ) % cap; |
|||
end |
|||
function randInit(flag) |
|||
-- The golden ratio in 32 bit |
|||
-- math.floor((((math.sqrt(5)+1)/2)%1)*2^32) == 2654435769 == 0x9e3779b9 |
|||
local a = { [0] = 0x9e3779b9, 0x9e3779b9, 0x9e3779b9, 0x9e3779b9, 0x9e3779b9, 0x9e3779b9, 0x9e3779b9, 0x9e3779b9, }; |
|||
aa,bb,cc = 0,0,0; |
|||
for i = 1,4 do mix(a) end -- Scramble it. |
|||
for i = 0,255,8 do -- Fill in mm[] with messy stuff. |
|||
if flag then -- Use all the information in the seed. |
|||
for j = 0,7 do |
|||
a[j] = ( a[j] + randRsl[i+j] ) % cap; |
|||
end |
|||
end |
|||
mix(a); |
|||
for j = 0,7 do |
|||
mm[i+j] = a[j]; |
|||
end |
|||
end |
|||
if flag then |
|||
-- Do a second pass to make all of the seed affect all of mm. |
|||
for i = 0,255,8 do |
|||
for j = 0,7 do |
|||
a[j] = ( a[j] + mm[i+j] ) % cap; |
|||
end |
|||
mix(a); |
|||
for j = 0,7 do |
|||
mm[i+j] = a[j]; |
|||
end |
|||
end |
|||
end |
|||
isaac(); -- Fill in the first set of results. |
|||
randCnt = 0; -- Prepare to use the first set of results. |
|||
end |
|||
-- Seed ISAAC with a given string. |
|||
-- The string can be any size. The first 256 values will be used. |
|||
function seedIsaac(seed,flag) |
|||
local seedLength = #seed; |
|||
for i = 0,255 do mm[i] = 0; end |
|||
for i = 0,255 do randRsl[i] = seed:byte(i+1,i+1) or 0; end |
|||
randInit(flag); |
|||
end |
|||
-- Get a random 32-bit value 0..MAXINT |
|||
function getRandom32Bit() |
|||
local result = randRsl[randCnt]; |
|||
randCnt = randCnt + 1; |
|||
if randCnt > 255 then |
|||
isaac(); |
|||
randCnt = 0; |
|||
end |
|||
return result; |
|||
end |
|||
-- Get a random character in printable ASCII range |
|||
function getRandomChar() |
|||
return getRandom32Bit() % 95 + 32; |
|||
end |
|||
-- Convert an ASCII string to a hexadecimal string. |
|||
function ascii2hex(source) |
|||
local ss = ""; |
|||
for i = 1,#source do |
|||
ss = ss..string.format("%02X",source:byte(i,i)); |
|||
end |
|||
return ss |
|||
end |
|||
-- XOR encrypt on random stream. |
|||
function vernam(msg) |
|||
local msgLength = #msg; |
|||
local destination = {}; |
|||
for i = 1, msgLength do |
|||
destination[i] = string.char(getRandomChar() ~ msg:byte(i,i)); |
|||
end |
|||
return table.concat(destination); |
|||
end |
|||
-- Caesar-shift a character <shift> places: Generalized Vigenere |
|||
function caesar(m, ch, shift, modulo, start) |
|||
local n |
|||
local si = 1 |
|||
if m == DECRYPT then shift = shift*-1 ; end |
|||
n = (ch - start) + shift; |
|||
if n < 0 then si,n = -1,n*-1 ; end |
|||
n = ( n % modulo ) * si; |
|||
if n < 0 then n = n + modulo ; end |
|||
return start + n; |
|||
end |
|||
-- Vigenere mod 95 encryption & decryption. |
|||
function vigenere(msg,m) |
|||
local msgLength = #msg; |
|||
local destination = {}; |
|||
for i = 1,msgLength do |
|||
destination[i] = string.char( caesar(m, msg:byte(i,i), getRandomChar(), 95, 32) ); |
|||
end |
|||
return table.concat(destination); |
|||
end |
|||
function main(noprint) |
|||
local msg = "a Top Secret secret"; |
|||
local key = "this is my secret key"; |
|||
local xorCipherText, modCipherText, xorPlainText, modPlainText; |
|||
-- (1) Seed ISAAC with the key |
|||
seedIsaac(key, true); |
|||
-- (2) Encryption |
|||
-- (a) XOR (Vernam) |
|||
xorCipherText = vernam(msg); |
|||
-- (b) MOD (Vigenere) |
|||
modCipherText = vigenere(msg, ENCRYPT); |
|||
-- (3) Decryption |
|||
seedIsaac(key, true); |
|||
-- (a) XOR (Vernam) |
|||
xorPlainText = vernam(xorCipherText); |
|||
-- (b) MOD (Vigenere) |
|||
modPlainText = vigenere(modCipherText, DECRYPT); |
|||
-- Program output |
|||
if not noprint then |
|||
print("Message: " .. msg); |
|||
print("Key : " .. key); |
|||
print("XOR : " .. ascii2hex(xorCipherText)); |
|||
print("XOR dcr: " .. xorPlainText); |
|||
print("MOD : " .. ascii2hex(modCipherText)); |
|||
print("MOD dcr: " .. modPlainText); |
|||
end |
|||
end |
|||
</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> |
</pre> |
||