September Morn Update

This commit is contained in:
Ingy döt Net 2019-09-12 10:33:56 -07:00
parent 4e2d22a71d
commit aac6731f2c
6856 changed files with 141342 additions and 21127 deletions

View file

@ -0,0 +1,202 @@
#include <iomanip>
#include <iostream>
#include <sstream>
using namespace std;
enum CipherMode {ENCRYPT, DECRYPT};
// External results
uint32_t randRsl[256];
uint32_t randCnt;
// Internal state
uint32_t mm[256];
uint32_t aa = 0, bb = 0, cc = 0;
void isaac()
{
++cc; // cc just gets incremented once per 256 results
bb += cc; // then combined with bb
for (uint32_t i = 0; i < 256; ++i)
{
uint32_t x, y;
x = mm[i];
switch (i % 4)
{
case 0:
aa = aa ^ (aa << 13);
break;
case 1:
aa = aa ^ (aa >> 6);
break;
case 2:
aa = aa ^ (aa << 2);
break;
case 3:
aa = aa ^ (aa >> 16);
break;
}
aa = mm[(i + 128) % 256] + aa;
y = mm[(x >> 2) % 256] + aa + bb;
mm[i] = y;
bb = mm[(y >> 10) % 256] + x;
randRsl[i] = bb;
}
randCnt = 0; // Prepare to use the first set of results.
}
void mix(uint32_t a[])
{
a[0] = a[0] ^ a[1] << 11; a[3] += a[0]; a[1] += a[2];
a[1] = a[1] ^ a[2] >> 2; a[4] += a[1]; a[2] += a[3];
a[2] = a[2] ^ a[3] << 8; a[5] += a[2]; a[3] += a[4];
a[3] = a[3] ^ a[4] >> 16; a[6] += a[3]; a[4] += a[5];
a[4] = a[4] ^ a[5] << 10; a[7] += a[4]; a[5] += a[6];
a[5] = a[5] ^ a[6] >> 4; a[0] += a[5]; a[6] += a[7];
a[6] = a[6] ^ a[7] << 8; a[1] += a[6]; a[7] += a[0];
a[7] = a[7] ^ a[0] >> 9; a[2] += a[7]; a[0] += a[1];
}
void randInit(bool flag)
{
uint32_t a[8];
aa = bb = cc = 0;
a[0] = 2654435769UL; // 0x9e3779b9: the golden ratio
for (uint32_t j = 1; j < 8; ++j)
a[j] = a[0];
for (uint32_t i = 0; i < 4; ++i) // Scramble it.
mix(a);
for (uint32_t i = 0; i < 256; i += 8) // Fill in mm[] with messy stuff.
{
if (flag) // Use all the information in the seed.
for (uint32_t j = 0; j < 8; ++j)
a[j] += randRsl[i + j];
mix(a);
for (uint32_t j = 0; j < 8; ++j)
mm[i + j] = a[j];
}
if (flag)
{ // Do a second pass to make all of the seed affect all of mm.
for (uint32_t i = 0; i < 256; i += 8)
{
for (uint32_t j = 0; j < 8; ++j)
a[j] += mm[i + j];
mix(a);
for (uint32_t j = 0; j < 8; ++j)
mm[i + j] = a[j];
}
}
isaac(); // Fill in the first set of results.
randCnt = 0; // Prepare to use the first set of results.
}
// Seed ISAAC with a given string.
// The string can be any size. The first 256 values will be used.
void seedIsaac(string seed, bool flag)
{
uint32_t seedLength = seed.length();
for (uint32_t i = 0; i < 256; i++)
mm[i] = 0;
for (uint32_t i = 0; i < 256; i++)
// In case seed has less than 256 elements
randRsl[i] = i > seedLength ? 0 : seed[i];
// Initialize ISAAC with seed
randInit(flag);
}
// Get a random 32-bit value 0..MAXINT
uint32_t getRandom32Bit()
{
uint32_t result = randRsl[randCnt];
++randCnt;
if (randCnt > 255)
{
isaac();
randCnt = 0;
}
return result;
}
// Get a random character in printable ASCII range
char getRandomChar()
{
return getRandom32Bit() % 95 + 32;
}
// Convert an ASCII string to a hexadecimal string.
string ascii2hex(string source)
{
uint32_t sourceLength = source.length();
stringstream ss;
for (uint32_t i = 0; i < sourceLength; i++)
ss << setfill ('0') << setw(2) << hex << (int) source[i];
return ss.str();
}
// XOR encrypt on random stream.
string vernam(string msg)
{
uint32_t msgLength = msg.length();
string destination = msg;
for (uint32_t i = 0; i < msgLength; i++)
destination[i] = getRandomChar() ^ msg[i];
return destination;
}
// Caesar-shift a character <shift> places: Generalized Vigenere
char caesar(CipherMode m, char ch, char shift, char modulo, char start)
{
int n;
if (m == DECRYPT)
shift = -shift;
n = (ch - start) + shift;
n %= modulo;
if (n < 0)
n += modulo;
return start + n;
}
// Vigenere mod 95 encryption & decryption.
string vigenere(string msg, CipherMode m)
{
uint32_t msgLength = msg.length();
string destination = msg;
// Caesar-shift message
for (uint32_t i = 0; i < msgLength; ++i)
destination[i] = caesar(m, msg[i], getRandomChar(), 95, ' ');
return destination;
}
int main()
{
// TASK globals
string msg = "a Top Secret secret";
string key = "this is my secret key";
string 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
cout << "Message: " << msg << endl;
cout << "Key : " << key << endl;
cout << "XOR : " << ascii2hex(xorCipherText) << endl;
cout << "MOD : " << ascii2hex(modCipherText) << endl;
cout << "XOR dcr: " << xorPlainText << endl;
cout << "MOD dcr: " << modPlainText << endl;
}

View file

@ -1,23 +1,24 @@
import Data.Array
import Data.Bits
import Data.Char
import Data.Word
import Data.List
import Numeric
import Data.Array (Array, (!), (//), array, elems)
import Data.Word (Word, Word32)
import Data.Bits (shift, xor)
import Data.Char (toUpper)
import Data.List (unfoldr)
import Numeric (showHex)
type IArray = Array Word32 Word32
data IsaacState = IState
{ randrsl :: IArray
, randcnt :: Word32
, mm :: IArray
, aa :: Word32
, bb :: Word32
, cc :: Word32
, mm :: IArray
, aa :: Word32
, bb :: Word32
, cc :: Word32
}
instance Show IsaacState where
show (IState _ cnt _ a b c) = show cnt ++ " " ++ show a ++ " " ++ show b ++ " " ++ show c
show (IState _ cnt _ a b c) =
show cnt ++ " " ++ show a ++ " " ++ show b ++ " " ++ show c
toHex :: Char -> String
toHex c = showHex (fromEnum c) ""
@ -38,59 +39,66 @@ golden = 0x9e3779b9
mix :: [Word32] -> [Word32]
mix set = foldl aux set [11, -2, 8, -16, 10, -4, 8, -9]
where
aux [a,b,c,d,e,f,g,h] x = [b + c, c, d + a', e, f, g, h, a']
where a' = a `xor` (b `shift` x)
aux [a, b, c, d, e, f, g, h] x = [b + c, c, d + a_, e, f, g, h, a_]
where
a_ = a `xor` (b `shift` x)
-- Generate the next 256 words.
isaac :: IsaacState -> IsaacState
isaac (IState rsl _ m a b c) = IState rsl' 0 m' a' b' c'
isaac (IState rsl _ m a b c) = IState rsl_ 0 m_ a_ b_ c_
where
c' = c + 1
(rsl', m', a', b') = foldl aux (rsl, m, a, b) $ zip [0..255] $ cycle [13, -6, 2, -16]
aux (rsl, m, a, b) (i, s) = (rsl', m', a', b')
where x = m ! i
a' = (a `xor` (a `shift` s)) + m ! ((i + 128) `mod` 256)
y = a' + b + m ! ((x `shift` (-2)) `mod` 256)
m' = m // [(i,y)]
b' = x + m' ! ((y `shift` (-10)) `mod` 256)
rsl' = rsl // [(i,b')]
c_ = c + 1
(rsl_, m_, a_, b_) =
foldl aux (rsl, m, a, b) $ zip [0 .. 255] $ cycle [13, -6, 2, -16]
aux (rsl, m, a, b) (i, s) = (rsl_, m_, a_, b_)
where
x = m ! i
a_ = (a `xor` (a `shift` s)) + m ! ((i + 128) `mod` 256)
y = a_ + b + m ! ((x `shift` (-2)) `mod` 256)
m_ = m // [(i, y)]
b_ = x + m_ ! ((y `shift` (-10)) `mod` 256)
rsl_ = rsl // [(i, b_)]
-- Given a seed value in randrsl, initialize/mixup the state.
randinit :: IsaacState -> Bool -> IsaacState
randinit state flag = isaac (IState randrsl' 0 m 0 0 0)
randinit state flag = isaac (IState randrsl_ 0 m 0 0 0)
where
firstSet = (iterate mix $ replicate 8 golden) !! 4
iter _ _ [] = []
firstSet = iterate mix (replicate 8 golden) !! 4
iter _ _ [] = []
iter flag set rsl =
let (rslH, rslT) = splitAt 8 rsl
set' = mix $ if flag
then zipWith (+) set rslH
else set
in set' ++ iter flag set' rslT
randrsl' = randrsl state
firstPass = iter flag firstSet $ elems randrsl'
set' = drop (256 - 8) firstPass
secondPass = if flag
then iter True set' firstPass
else firstPass
m = array (0, 255) $ zip [0..] secondPass
set_ =
mix $
if flag
then zipWith (+) set rslH
else set
in set_ ++ iter flag set_ rslT
randrsl_ = randrsl state
firstPass = iter flag firstSet $ elems randrsl_
set_ = drop (256 - 8) firstPass
secondPass =
if flag
then iter True set_ firstPass
else firstPass
m = array (0, 255) $ zip [0 ..] secondPass
-- Given a string seed, optionaly use it to generate a new state.
seed :: String -> Bool -> IsaacState
seed key flag =
let m = array (0, 255) $ zip [0..255] $ repeat 0
rsl = m // zip [0..] (map toNum key)
let m = array (0, 255) $ zip [0 .. 255] $ repeat 0
rsl = m // zip [0 ..] (map toNum key)
state = IState rsl 0 m 0 0 0
in randinit state flag
-- Produce a random word and the next state from the given state.
random :: IsaacState -> (Word32, IsaacState)
random state@(IState rsl cnt m a b c) =
let r = rsl ! cnt
state' = if cnt + 1 > 255
then isaac $ IState rsl 0 m a b c
else IState rsl (cnt + 1) m a b c
in (r, state')
let r = rsl ! cnt
state_ =
if cnt + 1 > 255
then isaac $ IState rsl 0 m a b c
else IState rsl (cnt + 1) m a b c
in (r, state_)
-- Produce a stream of random words from the given state.
randoms :: IsaacState -> [Word32]
@ -100,8 +108,8 @@ randoms = unfoldr $ Just . random
-- and the next state from the given state.
randA :: IsaacState -> (Char, IsaacState)
randA state =
let (r, state') = random state
in (toEnum $ fromIntegral $ (r `mod` 95) + 32, state')
let (r, state_) = random state
in (toEnum $ fromIntegral $ (r `mod` 95) + 32, state_)
-- Produce a stream of printable characters from the given state.
randAs :: IsaacState -> String
@ -109,17 +117,17 @@ randAs = unfoldr $ Just . randA
-- Vernam encode/decode a string with the given state.
vernam :: IsaacState -> String -> String
vernam state msg = map toChar $ zipWith xor msg' randAs'
vernam state msg = map toChar $ zipWith xor msg_ randAs_
where
msg' = map toNum msg
randAs' = map toNum $ randAs state
msg_ = map toNum msg
randAs_ = map toNum $ randAs state
main :: IO ()
main = do
let msg = "a Top Secret secret"
key = "this is my secret key"
st = seed key True
ver = vernam st msg
let msg = "a Top Secret secret"
key = "this is my secret key"
st = seed key True
ver = vernam st msg
unver = vernam st ver
putStrLn $ "Message: " ++ msg
putStrLn $ "Key : " ++ key

View file

@ -19,12 +19,12 @@ VAR
(* TASK globals *)
Msg: TString = 'a Top Secret secret';
Key: TString = 'this is my secret key';
XCTxt: TString = ''; (* XOR ciphertext *)
MCTxt: TString = ''; (* MOD ciphertext *)
XPTxt: TString = ''; (* XOR decryption (plaintext) *)
MPTxt: TString = ''; (* MOD decryption (plaintext) *)
XorCipherText: TString = '';
ModCipherText: TString = '';
XorPlainText: TString = '';
ModPlainText: TString = '';
Mode: TMode = iEncrypt;
HexTxt: TString;
HexText: TString;
(* ISAAC globals *)
(* external results *)
@ -228,23 +228,23 @@ BEGIN
(* (2) Encryption *)
Mode := iEncrypt;
(* (a) XOR (Vernam) *)
Vernam(Msg, XCTxt);
Vernam(Msg, XorCipherText);
(* (b) MOD (Vigenere) *)
Vigenere(Msg, Mode, MCTxt);
Vigenere(Msg, Mode, ModCipherText);
(* (3) Decryption *)
Mode := iDecrypt;
SeedIsaac(Key, TRUE);
(* (a) XOR (Vernam) *)
Vernam(XCTxt, XPTxt);
Vernam(XorCipherText, XorPlainText);
(* (b) MOD (Vigenere) *)
Vigenere(MCTxt, Mode, MPTxt);
Vigenere(ModCipherText, Mode, ModPlainText);
(* program output *)
WriteString('Message: '); WriteString(Msg); WriteLn;
WriteString('Key : '); WriteString(Key); WriteLn;
ASCII2Hex(XCTxt, HexTxt);
WriteString('XOR : '); WriteString(HexTxt); WriteLn;
ASCII2Hex(MCTxt, HexTxt);
WriteString('MOD : '); WriteString(HexTxt); WriteLn;
WriteString('XOR dcr: '); WriteString(XPTxt); WriteLn;
WriteString('MOD dcr: '); WriteString(MPTxt); WriteLn;
ASCII2Hex(XorCipherText, HexText);
WriteString('XOR : '); WriteString(HexText); WriteLn;
ASCII2Hex(ModCipherText, HexText);
WriteString('MOD : '); WriteString(HexText); WriteLn;
WriteString('XOR dcr: '); WriteString(XorPlainText); WriteLn;
WriteString('MOD dcr: '); WriteString(ModPlainText); WriteLn;
END RosettaIsaac.

View file

@ -1,213 +1,221 @@
PROGRAM RosettaIsaac;
USES StrUtils;
USES
StrUtils;
TYPE
iMode = (iEncrypt, iDecrypt);
TYPE iMode = (iEncrypt,iDecrypt);
// TASK globals
VAR msg : STRING = 'a Top Secret secret';
key : STRING = 'this is my secret key';
xctx: STRING = ''; // XOR ciphertext
mctx: STRING = ''; // MOD ciphertext
xptx: STRING = ''; // XOR decryption (plaintext)
mptx: STRING = ''; // MOD decryption (plaintext)
mode: iMode = iEncrypt;
// ISAAC globals
// external results
VAR randrsl: ARRAY[0..256] OF CARDINAL;
randcnt: cardinal;
// internal state
VAR mm: ARRAY[0..256] OF CARDINAL;
aa: CARDINAL=0; bb: CARDINAL=0; cc: CARDINAL=0;
VAR
msg : String = 'a Top Secret secret';
key : String = 'this is my secret key';
xctx: String = ''; // XOR ciphertext
mctx: String = ''; // MOD ciphertext
xptx: String = ''; // XOR decryption (plaintext)
mptx: String = ''; // MOD decryption (plaintext)
// ISAAC globals
VAR
// external results
randrsl: ARRAY[0 .. 255] OF Cardinal;
randcnt: Cardinal;
// internal state
mm: ARRAY[0 .. 255] OF Cardinal;
aa: Cardinal = 0;
bb: Cardinal = 0;
cc: Cardinal = 0;
PROCEDURE Isaac;
VAR i,x,y: CARDINAL;
VAR
i, x, y: Cardinal;
BEGIN
cc := cc + 1; // cc just gets incremented once per 256 results
bb := bb + cc; // then combined with bb
cc := cc + 1; // cc just gets incremented once per 256 results
bb := bb + cc; // then combined with bb
FOR i := 0 TO 255 DO BEGIN
x := mm[i];
CASE (i mod 4) OF
0: aa := aa xor (aa shl 13);
1: aa := aa xor (aa shr 6);
2: aa := aa xor (aa shl 2);
3: aa := aa xor (aa shr 16);
END;
aa := mm[(i+128) mod 256] + aa;
y := mm[(x shr 2) mod 256] + aa + bb;
mm[i] := y;
bb := mm[(y shr 10) mod 256] + x;
randrsl[i]:= bb;
END;
// this reset was not in the original readable.c
randcnt:=0; // prepare to use the first set of results
END; {Isaac}
FOR i := 0 TO 255 DO
BEGIN
x := mm[i];
CASE (i MOD 4) OF
0: aa := aa XOR (aa SHL 13);
1: aa := aa XOR (aa SHR 6);
2: aa := aa XOR (aa SHL 2);
3: aa := aa XOR (aa SHR 16);
END;
aa := mm[(i + 128) MOD 256] + aa;
y := mm[(x SHR 2) MOD 256] + aa + bb;
mm[i] := y;
bb := mm[(y SHR 10) MOD 256] + x;
randrsl[i] := bb;
END;
randcnt := 0; // prepare to use the first set of results
END; // Isaac
// 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
a := a xor b shl 11; d:=d+a; b:=b+c;
b := b xor c shr 2; e:=e+b; c:=c+d;
c := c xor d shl 8; f:=f+c; d:=d+e;
d := d xor e shr 16; g:=g+d; e:=e+f;
e := e xor f shl 10; h:=h+e; f:=f+g;
f := f xor g shr 4; a:=a+f; g:=g+h;
g := g xor h shl 8; b:=b+g; h:=h+a;
h := h xor a shr 9; c:=c+h; a:=a+b;
END; {mix}
a := a XOR b SHL 11; d := d + a; b := b + c;
b := b XOR c SHR 2; e := e + b; c := c + d;
c := c XOR d SHL 8; f := f + c; d := d + e;
d := d XOR e SHR 16; g := g + d; e := e + f;
e := e XOR f SHL 10; h := h + e; f := f + g;
f := f XOR g SHR 4; a := a + f; g := g + h;
g := g XOR h SHL 8; b := b + g; h := h + a;
h := h XOR a SHR 9; c := c + h; a := a + b;
END; // Mix
PROCEDURE iRandInit(flag: BOOLEAN);
VAR i,a,b,c,d,e,f,g,h: CARDINAL;
PROCEDURE iRandInit(flag: Boolean);
VAR
i, a, b, c, d, e, f, g, h: Cardinal;
BEGIN
aa:=0; bb:=0; cc:=0;
a:=$9e3779b9; // the golden ratio
aa := 0; bb := 0; cc := 0;
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
Mix(a, b, c, d, e, f, g, h);
FOR i := 0 TO 3 DO // scramble it
mix(a,b,c,d,e,f,g,h);
i:=0;
REPEAT // fill in mm[] with messy stuff
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];
e+=randrsl[i+4]; f+=randrsl[i+5]; g+=randrsl[i+6]; h+=randrsl[i+7];
i := 0;
REPEAT // fill in mm[] with messy stuff
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];
e += randrsl[i + 4]; f += randrsl[i + 5];
g += randrsl[i + 6]; h += randrsl[i + 7];
END;
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+4]:=e; mm[i+5]:=f; mm[i+6]:=g; mm[i+7]:=h;
i+=8;
UNTIL i>255;
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 + 4] := e; mm[i + 5] := f; mm[i + 6] := g; mm[i + 7] := h;
i += 8;
UNTIL i > 255;
IF (flag) THEN BEGIN
// do a second pass to make all of the seed affect all of mm
i:=0;
REPEAT
a+=mm[i ]; b+=mm[i+1]; c+=mm[i+2]; d+=mm[i+3];
e+=mm[i+4]; f+=mm[i+5]; g+=mm[i+6]; h+=mm[i+7];
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+4]:=e; mm[i+5]:=f; mm[i+6]:=g; mm[i+7]:=h;
i+=8;
UNTIL i>255;
END;
isaac(); // fill in the first set of results
randcnt:=0; // prepare to use the first set of results
END; {randinit}
IF flag THEN
BEGIN
// do a second pass to make all of the seed affect all of mm
i := 0;
REPEAT
a += mm[i ]; b += mm[i + 1]; c += mm[i + 2]; d += mm[i + 3];
e += mm[i + 4]; f += mm[i + 5]; g += mm[i + 6]; h += mm[i + 7];
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 + 4] := e; mm[i + 5] := f; mm[i + 6] := g; mm[i + 7] := h;
i += 8;
UNTIL i > 255;
END;
Isaac(); // fill in the first set of results
randcnt := 0; // prepare to use the first set of results
END; // iRandInit
{ Seed ISAAC with a given string.
The string can be any size. The first 256 values will be used.}
PROCEDURE iSeed(seed: STRING; flag: BOOLEAN);
VAR i,m: CARDINAL;
// Seed ISAAC with a given string.
// The string can be any size. The first 256 values will be used.
PROCEDURE iSeed(seed: String; flag: Boolean);
VAR
i, m: Cardinal;
BEGIN
FOR i:= 0 TO 255 DO mm[i]:=0;
m := Length(seed)-1;
FOR i:= 0 TO 255 DO BEGIN
// in case seed has less than 256 elements
IF i>m THEN randrsl[i]:=0
// Pascal strings are 1-based
ELSE randrsl[i]:=ord(seed[i+1]);
END;
// initialize ISAAC with seed
iRandInit(flag);
END; {iSeed}
FOR i := 0 TO 255 DO
mm[i] := 0;
m := Length(seed) - 1;
FOR i := 0 TO 255 DO
BEGIN
// in case seed has less than 256 elements
IF i > m THEN
randrsl[i] := 0
// Pascal strings are 1-based
ELSE
randrsl[i] := Ord(seed[i + 1]);
END;
// initialize ISAAC with seed
iRandInit(flag);
END; // iSeed
{ Get a random 32-bit value 0..MAXINT }
FUNCTION iRandom : Cardinal;
// Get a random 32-bit value 0..MAXINT
FUNCTION iRandom: Cardinal;
BEGIN
iRandom := randrsl[randcnt];
inc(randcnt);
IF (randcnt >255) THEN BEGIN
Isaac();
randcnt := 0;
END;
END; {iRandom}
iRandom := randrsl[randcnt];
inc(randcnt);
IF (randcnt > 255) THEN
BEGIN
Isaac;
randcnt := 0;
END;
END; // iRandom
{ Get a random character in printable ASCII range }
FUNCTION iRandA: BYTE;
BEGIN
iRandA := iRandom mod 95 + 32;
END;
{ convert an ASCII string to a hexadecimal string }
FUNCTION ascii2hex(s: STRING): STRING;
VAR i,l: CARDINAL;
BEGIN
ascii2hex := '';
l := Length(s);
FOR i := 1 TO l DO
ascii2hex += Dec2Numb(ord(s[i]),2,16);
END;
{ XOR encrypt on random stream. Output: ASCII string }
FUNCTION Vernam(msg: STRING): STRING;
VAR i: CARDINAL;
BEGIN
Vernam := '';
FOR i := 1 to length(msg) DO
Vernam += chr(iRandA xor ord(msg[i]));
END;
{ Get position of the letter in chosen alphabet }
FUNCTION letternum(letter, start: CHAR): byte;
BEGIN
letternum := (ord(letter)-ord(start));
END;
{ Caesar-shift a character <shift> places: Generalized Vigenere }
FUNCTION Caesar(m: iMode; ch: CHAR; shift, modulo: INTEGER; start: CHAR): CHAR;
VAR n: INTEGER;
BEGIN
IF m = iDecrypt THEN shift := -shift;
n := letternum(ch,start) + shift;
n := n MOD modulo;
IF n<0 THEN n += modulo;
Caesar := chr(ord(start)+n);
END;
{ Vigenere mod 95 encryption & decryption. Output: ASCII string }
FUNCTION Vigenere(msg: STRING; m: iMode): STRING;
VAR i: CARDINAL;
BEGIN
Vigenere := '';
FOR i := 1 to length(msg) DO
Vigenere += Caesar(m,msg[i],iRandA,95,' ');
END;
// Get a random character in printable ASCII range
FUNCTION iRandA: Byte;
BEGIN
// 1) seed ISAAC with the key
iSeed(key,true);
// 2) Encryption
mode := iEncrypt;
// a) XOR (Vernam)
xctx := Vernam(msg);
// b) MOD (Vigenere)
mctx := Vigenere(msg,mode);
// 3) Decryption
mode := iDecrypt;
iSeed(key,true);
// a) XOR (Vernam)
xptx:= Vernam(xctx);
// b) MOD (Vigenere)
mptx:=Vigenere(mctx,mode);
// program output
Writeln('Message: ',msg);
Writeln('Key : ',key);
Writeln('XOR : ',ascii2hex(xctx));
Writeln('MOD : ',ascii2hex(mctx));
Writeln('XOR dcr: ',xptx);
Writeln('MOD dcr: ',mptx);
iRandA := iRandom MOD 95 + 32;
END;
// Convert an ASCII string to a hexadecimal string
FUNCTION Ascii2Hex(s: String): String;
VAR
i: Cardinal;
BEGIN
Ascii2Hex := '';
FOR i := 1 TO Length(s) DO
Ascii2Hex += Dec2Numb(Ord(s[i]), 2, 16);
END; // Ascii2Hex
// XOR encrypt on random stream. Output: ASCII string
FUNCTION Vernam(msg: String): String;
VAR
i: Cardinal;
BEGIN
Vernam := '';
FOR i := 1 to Length(msg) DO
Vernam += Chr(iRandA XOR Ord(msg[i]));
END; // Vernam
// Get position of the letter in chosen alphabet
FUNCTION LetterNum(letter, start: Char): Byte;
BEGIN
LetterNum := (Ord(letter) - Ord(start));
END; // LetterNum
// Caesar-shift a character <shift> places: Generalized Vigenere
FUNCTION Caesar(m: iMode; ch: Char; shift, modulo: Integer; start: Char): Char;
VAR
n: Integer;
BEGIN
IF m = iDecrypt THEN
shift := -shift;
n := LetterNum(ch, start) + shift;
n := n MOD modulo;
IF n < 0 THEN
n += modulo;
Caesar := Chr(Ord(start) + n);
END; // Caesar
// Vigenere MOD 95 encryption & decryption. Output: ASCII string
FUNCTION Vigenere(msg: String; m: iMode): String;
VAR
i: Cardinal;
BEGIN
Vigenere := '';
FOR i := 1 to Length(msg) DO
Vigenere += Caesar(m, msg[i], iRandA, 95, ' ');
END; // Vigenere
BEGIN
// 1) seed ISAAC with the key
iSeed(key, true);
// 2) Encryption
// a) XOR (Vernam)
xctx := Vernam(msg);
// b) MOD (Vigenere)
mctx := Vigenere(msg, iEncrypt);
// 3) Decryption
iSeed(key, true);
// a) XOR (Vernam)
xptx := Vernam(xctx);
// b) MOD (Vigenere)
mptx := Vigenere(mctx, iDecrypt);
// program output
Writeln('Message: ', msg);
Writeln('Key : ', key);
Writeln('XOR : ', Ascii2Hex(xctx));
Writeln('MOD : ', Ascii2Hex(mctx));
Writeln('XOR dcr: ', xptx);
Writeln('MOD dcr: ', mptx);
END.

View file

@ -0,0 +1,118 @@
#!/usr/bin/env perl6
use v6.d;
my uint32 (@mm, @randrsl, $randcnt, $aa, $bb, $cc);
my := 2654435769; constant MOD = 95; constant START = 32;
constant MAXINT = uint.Range.max;
enum CipherMode < ENCIPHER DECIPHER NONE >;
sub mix (\n) {
sub mix1 (\i, \v) {
n[i] +^= v;
n[(i+3)%8] += n[i];
n[(i+1)%8] += n[(i+2)%8];
}
mix1 0, n[1]+<11; mix1 1, n[2]+>2; mix1 2, n[3]+<8; mix1 3, n[4]+>16;
mix1 4, n[5]+<10; mix1 5, n[6]+>4; mix1 6, n[7]+<8; mix1 7, n[0]+>9 ;
}
sub randinit(\flag) {
$aa = $bb = $cc = 0;
my uint32 @n = [^8].map({ ϕ });
for ^4 { mix @n };
for 0,8 255 -> $i {
{ for (0..7) { @n[$^j] += @randrsl[$i + $^j] } } if flag;
mix @n;
for (0..7) { @mm[$i + $^j] = @n[$^j] }
}
if flag {
for 0,8 255 -> $i {
for ^8 { @n[$^j] += @mm[$i + $^j] };
mix @n;
for ^8 { @mm[$i + $^j] = @n[$^j] };
}
}
isaac;
$randcnt = 0;
}
sub isaac() {
$cc++;
$bb += $cc;
for ^256 -> $i {
my $x = @mm[$i];
given ($i % 4) {
when 0 { $aa +^= ($aa +< 13) }
when 1 { $aa +^= (($aa +& MAXINT) +> 6) }
when 2 { $aa +^= ($aa +< 2) }
when 3 { $aa +^= (($aa +& MAXINT) +> 16) }
}
$aa += @mm[($i + 128) % 256];
my $y = @mm[(($x +& MAXINT) +> 2) % 256] + $aa + $bb;
@mm[$i] = $y;
$bb = @mm[(($y +& MAXINT) +> 10) % 256] + $x;
@randrsl[$i] = $bb;
}
$randcnt = 0;
}
sub iRandom {
my $result = @randrsl[$randcnt++];
if ($randcnt > 255) {
isaac;
$randcnt = 0;
}
return $result;
}
sub iSeed(\seed, \flag) {
@mm = [^256].race.map({0});
my \m = seed.chars;
@randrsl = [^256].hyper.map({ $^i m ?? 0 !! seed.substr($^i,1).ord });
randinit(flag);
}
sub iRandA { return iRandom() % MOD + START };
sub vernam(\M) { ( map { (iRandA() +^ .ord ).chr }, M.comb ).join };
sub caesar(CipherMode \m, \ch, $shift is copy, \Modulo, \Start) {
$shift = -$shift if m == DECIPHER;
my $n = (ch.ord - Start) + $shift;
$n %= Modulo;
$n += Modulo if $n < 0;
return (Start + $n).chr;
}
sub caesarStr(CipherMode \m, \msg, \Modulo, \Start) {
my $sb = '';
for msg.comb {
$sb ~= caesar m, $^c, iRandA(), Modulo, Start;
}
return $sb;
}
multi MAIN () {
my \msg = "a Top Secret secret";
my \key = "this is my secret key";
iSeed key, True ;
my $vctx = vernam msg;
my $cctx = caesarStr ENCIPHER, msg, MOD, START;
iSeed key, True ;
my $vptx = vernam $vctx;
my $cptx = caesarStr DECIPHER, $cctx, MOD, START;
my $vctx2hex = ( map { .ord.fmt('%02X') }, $vctx.comb ).join('');
my $cctx2hex = ( map { .ord.fmt('%02X') }, $cctx.comb ).join('');
say "Message : ", msg;
say "Key : ", key;
say "XOR : ", $vctx2hex;
say "XOR dcr : ", $vptx;
say "MOD : ", $cctx2hex;
say "MOD dcr : ", $cptx;
}

View file

@ -0,0 +1,142 @@
-- 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})