The ISAAC cipher: Difference between revisions

Content added Content deleted
(→‎{{header|Haskell}}: Adjusted names to avoid wiki display glitch, specified imports, applied hlint hindent.)
(→‎{{header|Pascal}}: [0 .. 255] instead of [0..256]; unnecessary variables removed)
Line 3,034: Line 3,034:
xptx: STRING = ''; // XOR decryption (plaintext)
xptx: STRING = ''; // XOR decryption (plaintext)
mptx: STRING = ''; // MOD decryption (plaintext)
mptx: STRING = ''; // MOD decryption (plaintext)

mode: iMode = iEncrypt;
// ISAAC globals
// ISAAC globals
// external results
// external results
VAR randrsl: ARRAY[0..256] OF CARDINAL;
VAR randrsl: ARRAY[0 .. 255] OF CARDINAL;
randcnt: cardinal;
randcnt: CARDINAL;
// internal state
// internal state
VAR mm: ARRAY[0..256] OF CARDINAL;
VAR mm: ARRAY[0 .. 255] OF CARDINAL;
aa: CARDINAL=0; bb: CARDINAL=0; cc: CARDINAL=0;
aa: CARDINAL = 0; bb: CARDINAL = 0; cc: CARDINAL = 0;




Line 3,048: Line 3,047:
VAR i,x,y: CARDINAL;
VAR i,x,y: CARDINAL;
BEGIN
BEGIN
cc := cc + 1; // cc just gets incremented once per 256 results
cc := cc + 1; // cc just gets incremented once per 256 results
bb := bb + cc; // then combined with bb
bb := bb + cc; // then combined with bb


FOR i := 0 TO 255 DO BEGIN
FOR i := 0 TO 255 DO BEGIN
Line 3,061: Line 3,060:
aa := mm[(i+128) mod 256] + aa;
aa := mm[(i+128) mod 256] + aa;
y := mm[(x shr 2) mod 256] + aa + bb;
y := mm[(x shr 2) mod 256] + aa + bb;
mm[i] := y;
mm[i] := y;
bb := mm[(y shr 10) mod 256] + x;
bb := mm[(y shr 10) mod 256] + x;
randrsl[i]:= bb;
randrsl[i]:= bb;
END;
END;
// this reset was not in the original readable.c
// this reset was not in the original readable.c
randcnt:=0; // prepare to use the first set of results
randcnt:=0; // prepare to use the first set of results
END; {Isaac}
END; {Isaac}




// if (flag==TRUE), then use the contents of randrsl[] to initialize mm[].
// if (flag==TRUE), then use the contents of randrsl[] to initialize mm[].
PROCEDURE mix(VAR a,b,c,d,e,f,g,h: CARDINAL);
PROCEDURE mix(VAR a,b,c,d,e,f,g,h: CARDINAL);
BEGIN
BEGIN
Line 3,089: Line 3,088:
aa:=0; bb:=0; cc:=0;
aa:=0; bb:=0; cc:=0;
a:=$9e3779b9; // the golden ratio
a:=$9e3779b9; // the golden ratio
b:=a; c:=a; d:=a; e:=a; f:=a; g:=a; h:=a;
b:=a; c:=a; d:=a; e:=a; f:=a; g:=a; h:=a;


FOR i := 0 TO 3 DO // scramble it
FOR i := 0 TO 3 DO // scramble it
mix(a,b,c,d,e,f,g,h);
mix(a,b,c,d,e,f,g,h);

i:=0;
i:=0;
REPEAT // fill in mm[] with messy stuff
REPEAT // fill in mm[] with messy stuff
IF flag THEN BEGIN // use all the information in the seed
IF flag THEN BEGIN // use all the information in the seed
a+=randrsl[i ]; b+=randrsl[i+1]; c+=randrsl[i+2]; d+=randrsl[i+3];
a+=randrsl[i ]; b+=randrsl[i+1]; c+=randrsl[i+2]; d+=randrsl[i+3];
e+=randrsl[i+4]; f+=randrsl[i+5]; g+=randrsl[i+6]; h+=randrsl[i+7];
e+=randrsl[i+4]; f+=randrsl[i+5]; g+=randrsl[i+6]; h+=randrsl[i+7];
END;
END;

mix(a,b,c,d,e,f,g,h);
mix(a,b,c,d,e,f,g,h);
mm[i ]:=a; mm[i+1]:=b; mm[i+2]:=c; mm[i+3]:=d;
mm[i ]:=a; mm[i+1]:=b; mm[i+2]:=c; mm[i+3]:=d;
Line 3,109: Line 3,108:


IF (flag) THEN BEGIN
IF (flag) THEN BEGIN
// do a second pass to make all of the seed affect all of mm
// do a second pass to make all of the seed affect all of mm
i:=0;
i:=0;
REPEAT
REPEAT
Line 3,118: Line 3,117:
mm[i+4]:=e; mm[i+5]:=f; mm[i+6]:=g; mm[i+7]:=h;
mm[i+4]:=e; mm[i+5]:=f; mm[i+6]:=g; mm[i+7]:=h;
i+=8;
i+=8;
UNTIL i>255;
UNTIL i>255;
END;
END;
isaac(); // fill in the first set of results
isaac(); // fill in the first set of results
randcnt:=0; // prepare to use the first set of results
randcnt:=0; // prepare to use the first set of results
END; {randinit}
END; {randinit}


Line 3,134: Line 3,133:
FOR i:= 0 TO 255 DO BEGIN
FOR i:= 0 TO 255 DO BEGIN
// in case seed has less than 256 elements
// in case seed has less than 256 elements
IF i>m THEN randrsl[i]:=0
IF i>m THEN randrsl[i]:=0
// Pascal strings are 1-based
// Pascal strings are 1-based
ELSE randrsl[i]:=ord(seed[i+1]);
ELSE randrsl[i]:=ord(seed[i+1]);
Line 3,144: Line 3,143:


{ Get a random 32-bit value 0..MAXINT }
{ Get a random 32-bit value 0..MAXINT }
FUNCTION iRandom : Cardinal;
FUNCTION iRandom : CARDINAL;
BEGIN
BEGIN
iRandom := randrsl[randcnt];
iRandom := randrsl[randcnt];
Line 3,157: Line 3,156:
{ Get a random character in printable ASCII range }
{ Get a random character in printable ASCII range }
FUNCTION iRandA: BYTE;
FUNCTION iRandA: BYTE;
BEGIN
BEGIN
iRandA := iRandom mod 95 + 32;
iRandA := iRandom mod 95 + 32;
END;
END;




{ convert an ASCII string to a hexadecimal string }
{ convert an ASCII string to a hexadecimal string }
FUNCTION ascii2hex(s: STRING): STRING;
FUNCTION ascii2hex(s: STRING): STRING;
VAR i,l: CARDINAL;
VAR i: CARDINAL;
BEGIN
BEGIN
ascii2hex := '';
ascii2hex := '';
l := Length(s);
FOR i := 1 TO Length(s) DO
FOR i := 1 TO l DO
ascii2hex += Dec2Numb(ord(s[i]),2,16);
ascii2hex += Dec2Numb(ord(s[i]),2,16);
END;
END;
Line 3,182: Line 3,180:
END;
END;



{ Get position of the letter in chosen alphabet }
{ Get position of the letter in chosen alphabet }
FUNCTION letternum(letter, start: CHAR): byte;
FUNCTION letternum(letter, start: CHAR): byte;
Line 3,211: Line 3,209:
END;
END;



BEGIN
BEGIN
// 1) seed ISAAC with the key
// 1) seed ISAAC with the key
iSeed(key,true);
iSeed(key,true);
// 2) Encryption
// 2) Encryption
mode := iEncrypt;
// a) XOR (Vernam)
// a) XOR (Vernam)
xctx := Vernam(msg);
xctx := Vernam(msg);
// b) MOD (Vigenere)
// b) MOD (Vigenere)
mctx := Vigenere(msg,mode);
mctx := Vigenere(msg, iEncrypt);
// 3) Decryption
// 3) Decryption
mode := iDecrypt;
iSeed(key,true);
iSeed(key,true);
// a) XOR (Vernam)
// a) XOR (Vernam)
xptx:= Vernam(xctx);
xptx:= Vernam(xctx);
// b) MOD (Vigenere)
// b) MOD (Vigenere)
mptx:=Vigenere(mctx,mode);
mptx:=Vigenere(mctx, iDecrypt);
// program output
// program output
Writeln('Message: ',msg);
Writeln('Message: ',msg);
Line 3,236: Line 3,232:
Writeln('MOD dcr: ',mptx);
Writeln('MOD dcr: ',mptx);
END.
END.

</lang>
</lang>
{{out}}
{{out}}