The ISAAC cipher: Difference between revisions

Rename Perl 6 -> Raku, alphabetize, minor clean-up
(→‎{{header|Pascal}}: Spaces and indenting according to coding guidelines. The logic remained unchanged.)
(Rename Perl 6 -> Raku, alphabetize, minor clean-up)
Line 304:
MOD : 734270227D36772A783B4F2A5F206266236978
MOD dcr: a Top Secret secret
</pre>
 
=={{header|C sharp}}==
XOR with decryption check.
<lang C sharp>
using System;
 
namespace cipher {
 
static class Cipher {
 
// external results
static uint[] randrsl = new uint[256];
static uint randcnt;
// internal state
static uint[] mm = new uint[256];
static uint aa=0, bb=0, cc=0;
 
 
static void isaac() {
uint i,x,y;
cc++; // cc just gets incremented once per 256 results
bb+=cc; // then combined with bb
 
for (i=0; i<=255; i++) {
x = mm[i];
switch (i & 3) {
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) & 255] + aa;
y = mm[(x >> 2) & 255] + aa + bb;
mm[i] = y;
bb = mm[(y >> 10) & 255] + x;
randrsl[i]= bb;
}
}
 
 
// if (flag==TRUE), then use the contents of randrsl[] to initialize mm[].
static void mix(ref uint a, ref uint b, ref uint c, ref uint d, ref uint e, ref uint f, ref uint g, ref uint h) {
a = a ^ b << 11; d+=a; b+=c;
b = b ^ c >> 2; e+=b; c+=d;
c = c ^ d << 8; f+=c; d+=e;
d = d ^ e >> 16; g+=d; e+=f;
e = e ^ f << 10; h+=e; f+=g;
f = f ^ g >> 4; a+=f; g+=h;
g = g ^ h << 8; b+=g; h+=a;
h = h ^ a >> 9; c+=h; a+=b;
}
 
 
static void Init(bool flag) {
short i; uint a,b,c,d,e,f,g,h;
 
aa=0; bb=0; cc=0;
a=0x9e3779b9; b=a; c=a; d=a;
e=a; f=a; g=a; h=a;
 
for (i=0; i<=3; i++) // scramble it
mix(ref a,ref b,ref c,ref d,ref e,ref f,ref g,ref h);
i=0;
do { // fill in mm[] with messy stuff
if (flag) { // 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];
} // if flag
mix(ref a,ref b,ref c,ref d,ref e,ref f,ref g,ref 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;
}
while (i<255);
 
if (flag) {
// do a second pass to make all of the seed affect all of mm
i=0;
do {
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(ref a,ref b,ref c,ref d,ref e,ref f,ref g,ref 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;
}
while (i<255);
}
isaac(); // fill in the first set of results
randcnt=0; // prepare to use the first set of results
}
 
 
// Seed ISAAC with a string
static void Seed(string seed, bool flag) {
for (int i=0; i<256; i++) mm[i]=0;
for (int i=0; i<256; i++) randrsl[i]=0;
int m = seed.Length;
for (int i=0; i<m; i++) {
randrsl[i] = seed[i];
}
// initialize ISAAC with seed
Init(flag);
}
 
 
// Get a random 32-bit value
static uint Random() {
uint result = randrsl[randcnt];
randcnt++;
if (randcnt>255) {
isaac(); randcnt=0;
}
return result;
}
 
 
// Get a random character in printable ASCII range
static byte RandA() {
return (byte)(Random() % 95 + 32);
}
 
 
// XOR encrypt on random stream. Output: ASCII byte array
static byte[] Vernam(string msg)
{
int n,l;
byte[] v = new byte[msg.Length];
l = msg.Length;
// XOR message
for (n=0; n<l; n++) {
v[n] = (byte) (RandA() ^ (byte)msg[n]);
}
return v;
}
 
public static void Main() {
string msg = "a Top Secret secret";
string key = "this is my secret key";
byte[] xctx= new byte[msg.Length];
byte[] xptx= new byte[msg.Length];
string xtcx= "*******************";
string xtpx= "*******************";
Seed(key,true);
// XOR encrypt
xctx = Vernam(msg);
xtcx = System.Text.Encoding.ASCII.GetString(xctx);
// XOR decrypt
Seed(key,true);
xptx = Vernam(xtcx);
xtpx = System.Text.Encoding.ASCII.GetString(xptx);
Console.WriteLine("Message: "+msg);
Console.WriteLine("Key : "+key);
Console.Write ("XOR : ");
// output ciphertext as a string of hexadecimal digits
for (int n=0; n<xctx.Length; n++) Console.Write("{0:X2}", xctx[n]);
Console.WriteLine("\nXOR dcr: "+xtpx);
}
}
}
</lang>
{{out}}
<pre>
Message: a Top Secret secret
Key : this is my secret key
XOR : 1C0636190B1260233B35125F1E1D0E2F4C5422
XOR dcr: a Top Secret secret
</pre>
 
Line 520 ⟶ 691:
XOR dcr: a Top Secret secret
MOD dcr: a Top Secret secret
</pre>
 
=={{header|C sharp}}==
XOR with decryption check.
<lang C sharp>
using System;
 
namespace cipher {
 
static class Cipher {
 
// external results
static uint[] randrsl = new uint[256];
static uint randcnt;
// internal state
static uint[] mm = new uint[256];
static uint aa=0, bb=0, cc=0;
 
 
static void isaac() {
uint i,x,y;
cc++; // cc just gets incremented once per 256 results
bb+=cc; // then combined with bb
 
for (i=0; i<=255; i++) {
x = mm[i];
switch (i & 3) {
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) & 255] + aa;
y = mm[(x >> 2) & 255] + aa + bb;
mm[i] = y;
bb = mm[(y >> 10) & 255] + x;
randrsl[i]= bb;
}
}
 
 
// if (flag==TRUE), then use the contents of randrsl[] to initialize mm[].
static void mix(ref uint a, ref uint b, ref uint c, ref uint d, ref uint e, ref uint f, ref uint g, ref uint h) {
a = a ^ b << 11; d+=a; b+=c;
b = b ^ c >> 2; e+=b; c+=d;
c = c ^ d << 8; f+=c; d+=e;
d = d ^ e >> 16; g+=d; e+=f;
e = e ^ f << 10; h+=e; f+=g;
f = f ^ g >> 4; a+=f; g+=h;
g = g ^ h << 8; b+=g; h+=a;
h = h ^ a >> 9; c+=h; a+=b;
}
 
 
static void Init(bool flag) {
short i; uint a,b,c,d,e,f,g,h;
 
aa=0; bb=0; cc=0;
a=0x9e3779b9; b=a; c=a; d=a;
e=a; f=a; g=a; h=a;
 
for (i=0; i<=3; i++) // scramble it
mix(ref a,ref b,ref c,ref d,ref e,ref f,ref g,ref h);
i=0;
do { // fill in mm[] with messy stuff
if (flag) { // 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];
} // if flag
mix(ref a,ref b,ref c,ref d,ref e,ref f,ref g,ref 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;
}
while (i<255);
 
if (flag) {
// do a second pass to make all of the seed affect all of mm
i=0;
do {
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(ref a,ref b,ref c,ref d,ref e,ref f,ref g,ref 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;
}
while (i<255);
}
isaac(); // fill in the first set of results
randcnt=0; // prepare to use the first set of results
}
 
 
// Seed ISAAC with a string
static void Seed(string seed, bool flag) {
for (int i=0; i<256; i++) mm[i]=0;
for (int i=0; i<256; i++) randrsl[i]=0;
int m = seed.Length;
for (int i=0; i<m; i++) {
randrsl[i] = seed[i];
}
// initialize ISAAC with seed
Init(flag);
}
 
 
// Get a random 32-bit value
static uint Random() {
uint result = randrsl[randcnt];
randcnt++;
if (randcnt>255) {
isaac(); randcnt=0;
}
return result;
}
 
 
// Get a random character in printable ASCII range
static byte RandA() {
return (byte)(Random() % 95 + 32);
}
 
 
// XOR encrypt on random stream. Output: ASCII byte array
static byte[] Vernam(string msg)
{
int n,l;
byte[] v = new byte[msg.Length];
l = msg.Length;
// XOR message
for (n=0; n<l; n++) {
v[n] = (byte) (RandA() ^ (byte)msg[n]);
}
return v;
}
 
public static void Main() {
string msg = "a Top Secret secret";
string key = "this is my secret key";
byte[] xctx= new byte[msg.Length];
byte[] xptx= new byte[msg.Length];
string xtcx= "*******************";
string xtpx= "*******************";
Seed(key,true);
// XOR encrypt
xctx = Vernam(msg);
xtcx = System.Text.Encoding.ASCII.GetString(xctx);
// XOR decrypt
Seed(key,true);
xptx = Vernam(xtcx);
xtpx = System.Text.Encoding.ASCII.GetString(xptx);
Console.WriteLine("Message: "+msg);
Console.WriteLine("Key : "+key);
Console.Write ("XOR : ");
// output ciphertext as a string of hexadecimal digits
for (int n=0; n<xctx.Length; n++) Console.Write("{0:X2}", xctx[n]);
Console.WriteLine("\nXOR dcr: "+xtpx);
}
}
}
</lang>
{{out}}
<pre>
Message: a Top Secret secret
Key : this is my secret key
XOR : 1C0636190B1260233B35125F1E1D0E2F4C5422
XOR dcr: a Top Secret secret
</pre>
 
Line 1,455:
decrypted: a Top Secret secret
</pre>
 
=={{header|FreeBASIC}}==
{{trans|C}}
Line 3,299 ⟶ 3,300:
XOR : 1C0636190B1260233B35125F1E1D0E2F4C5422
XOR dcr: a Top Secret secret
</pre>
 
=={{header|Perl 6}}==
<lang perl6>#!/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;
}</lang>
{{out}}
<pre>
Message : a Top Secret secret
Key : this is my secret key
XOR : 1C0636190B1260233B35125F1E1D0E2F4C5422
XOR dcr : a Top Secret secret
MOD : 734270227D36772A783B4F2A5F206266236978
MOD dcr : a Top Secret secret
</pre>
 
Line 4,180 ⟶ 4,052:
< context reseeded
Vigenère (-MOD): [6120546f702053656372657420736563726574 "a Top Secret secret"]</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
<lang perl6>#!/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;
}</lang>
{{out}}
<pre>
Message : a Top Secret secret
Key : this is my secret key
XOR : 1C0636190B1260233B35125F1E1D0E2F4C5422
XOR dcr : a Top Secret secret
MOD : 734270227D36772A783B4F2A5F206266236978
MOD dcr : a Top Secret secret
</pre>
 
=={{header|REXX}}==
10,327

edits