The ISAAC cipher: Difference between revisions

m
(Added a Forth implementation)
m (→‎{{header|Wren}}: Minor tidy)
 
(8 intermediate revisions by 5 users not shown)
Line 1:
{{draft task|Encryption}}
ISAAC is a cryptographically secure pseudo-random number generator (CSPRNG) and stream cipher. It was developed by Bob Jenkins from 1993 (http://burtleburtle.net/bob/rand/isaac.html) and placed in the Public Domain. ISAAC is fast - especially when optimised - and portable to most architectures in nearly all programming and scripting languages.
It is also simple and succinct, using as it does just two 256-word arrays for its state.
Line 59:
But building a strong and simple ISAAC-based stream cipher - replacing the irreparably broken RC4 - is our goal here: ISAAC's intended purpose.
<br><br>
 
=={{header|BASIC}}==
==={{header|FreeBASIC}}===
{{trans|C}}
<syntaxhighlight lang="freebasic">' version 03-11-2016
' compile with: fbc -s console
 
Dim Shared As UInteger<32> randrsl(256), randcnt
Static Shared As UInteger<32> mm(256)
Static Shared As UInteger<32> aa, bb ,cc
 
Sub ISAAC()
Dim As UInteger<32> i, x, y
cc = cc + 1
bb = bb + cc
For i = 0 To 256 -1
x = mm(i)
Select Case (i Mod 4)
Case 0 : aa = aa Xor (aa Shl 13)
Case 1 : aa = aa Xor (aa Shr 6)
Case 2 : aa = aa Xor (aa Shl 2)
Case 3 : aa = aa Xor (aa Shr 16)
End Select
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
Next
randcnt = 0
End Sub
 
#Macro mix(a, b, c, d, e, f, g, h)
a Xor= b Shl 11 : d += a : b += c
b Xor= c Shr 2 : e += b : c += d
c Xor= d Shl 8 : f += c : d += e
d Xor= e Shr 16 : g += d : e += f
e Xor= f Shl 10 : h += e : f += g
f Xor= g Shr 4 : a += f : g += h
g Xor= h Shl 8 : b += g : h += a
h Xor= a Shr 9 : c += h : a += b
#EndMacro
 
Sub randinit(flag As Long)
Dim As Long i
Dim As UInteger<32> a = &H9e3779b9 '/* the golden ratio *
Dim As UInteger<32> b = &H9e3779b9
Dim As UInteger<32> c = &H9e3779b9
Dim As UInteger<32> d = &H9e3779b9
Dim As UInteger<32> e = &H9e3779b9
Dim As UInteger<32> f = &H9e3779b9
Dim As UInteger<32> g = &H9e3779b9
Dim As UInteger<32> h = &H9e3779b9
aa = 0 : bb = 0 : cc = 0
For i = 0 To 3
mix(a, b, c, d, e, f, g, h)
Next
For i = 0 To 255 Step 8
If flag = 1 Then
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)
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
End If
Next
If flag = 1 Then
For i = 0 To 255 Step 8
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
Next
End If
ISAAC()
randcnt = 0
End Sub
 
' // Get a random 32-bit value 0..MAXINT
Function iRandom() As UInteger<32>
Dim As UInteger<32> r = randrsl(randcnt)
randcnt += 1
If randcnt > 255 Then
ISAAC()
randcnt = 0
End If
Return r
End Function
 
' // Get a random character in printable ASCII range
Function iRandA() As UByte
Return iRandom() Mod 95 +32
End Function
 
' // Seed ISAAC with a string
Sub iSeed(seed As String, flag As Long)
Dim As ULong i, m = Len(seed) -1
For i = 0 To 255
mm(i) = 0
Next
For i = 0 To 255
If i > m Then
randrsl(i) = 0
Else
randrsl(i) = seed[i]
End If
Next
randinit(flag)
End Sub
 
' // maximum length of message
'#define MAXMSG 4096
#Define _MOD_ 95 ' mod is FreeBASIC keyword
#Define _START_ 32 ' start is used as variable name
 
' // cipher modes for Caesar
Enum ciphermode
mEncipher
mDecipher
mNone
End Enum
 
' // XOR cipher on random stream. Output: ASCII string
' no maximum lenght for input and output string
Function Vernam(msg As String) As String
Dim As ULong i
Dim As String v
For i = 0 To Len(msg) -1
v += Chr(iRandA() Xor msg[i])
Next
Return v
End Function
 
' // Caesar-shift a printable character
Function Ceasar(m As ciphermode, ch As UByte, shift As UByte, modulo As UByte, _
start As UByte) As UByte
' FreeBASIC Mod does not handle negative numbers correctly
' also there is litte problem with shift (declared UByte)
' the IIF() statement helps with shift
' to avoid a negative n a 8 times modulo is added
' modulo * 8 get translateted by FreeBASIC to modulo shl 3
Dim As Long n = (ch - start) + IIf(m = mDecipher, -shift, shift) + modulo * 8
n = n Mod modulo
Return start + n
End Function
 
' // Caesar-shift a string on a pseudo-random stream
Function CeasarStr(m As ciphermode, msg As String, modulo As UByte, _
start As UByte) As String
Dim As Long i
Dim As String v
For i = 0 To Len(msg) -1
v += Chr(Ceasar(m, msg[i], iRandA(), modulo, start))
Next
Return v
End Function
 
' ------=< MAIN >=------
 
Dim As Long n, l
Dim As String msg = "a Top Secret secret"
Dim As String key = "this is my secret key"
 
Dim As String vctx, vptx
Dim As String cctx, cptx
 
l = Len(msg)
' // Encrypt: Vernam XOR
iSeed(key, 1)
vctx = Vernam(msg)
' // Encrypt: Caesar
cctx = CeasarStr(mEncipher, msg, _mod_, _start_)
' // Decrypt: Vernam XOR
iSeed(key, 1)
vptx = Vernam(vctx)
' // Decrypt: Caesar
cptx = CeasarStr(mDecipher, cctx, _mod_, _start_)
Print "message: "; msg
Print " key: "; key
Print " XOR: ";
' // Output Vernam ciphertext as a string of hex digits
For n = 0 To l -1
Print Hex(vctx[n], 2);
Next
Print
' // Output Vernam decrypted plaintext
Print "XOR dcr: "; vptx
' // Caesar
Print " MOD: ";
' // Output Caesar ciphertext as a string of hex digits
For n= 0 To l -1
Print Hex(cctx[n], 2);
Next
Print
' // Output Caesar decrypted plaintext
Print "MOD dcr: " ; cptx
 
' empty keyboard buffer
While InKey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End</syntaxhighlight>
{{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|C}}==
At the top is Bob Jenkins' reference code for ISAAC.
Below and in main() is the task's complete solution for XOR and MOD.
<syntaxhighlight lang="c">
<lang C>
/* Known to compile and work with tcc in win32 & gcc on Linux (with warnings)
------------------------------------------------------------------------------
Line 295 ⟶ 507:
return 0;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 308 ⟶ 520:
=={{header|C sharp}}==
XOR with decryption check.
<langsyntaxhighlight Clang="c sharp">
using System;
 
Line 468 ⟶ 680:
}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 479 ⟶ 691:
=={{header|C++}}==
{{trans|Modula-2}}
<langsyntaxhighlight lang="cpp">
#include <iomanip>
#include <iostream>
Line 682 ⟶ 894:
cout << "MOD dcr: " << modPlainText << endl;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 694 ⟶ 906:
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defpackage isaac
(:use cl))
 
Line 936 ⟶ 1,148:
(terpri)
(format t "MOD dcr: ~a~%" cptx))))
(values))</langsyntaxhighlight>
{{out}}
<pre>ISAAC> (main-test)
Line 948 ⟶ 1,160:
=={{header|D}}==
Improved from the C# version. XOR with decryption check.
<langsyntaxhighlight lang="d">import std.algorithm: min;
import std.algorithm: copy;
import std.typetuple: TypeTuple;
Line 1,112 ⟶ 1,324:
 
writeln("Decrypted: ", decrypted.assumeUTF);
}</langsyntaxhighlight>
{{out}}
<pre>Message : a Top Secret secret
Line 1,121 ⟶ 1,333:
=={{header|Delphi}}==
Translation of Pascal.
<syntaxhighlight lang="delphi">
<lang Delphi>
{$apptype console}
PROGRAM RosettaIsaac;
Line 1,320 ⟶ 1,532:
Writeln('MOD : ',mctx);
END.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,332 ⟶ 1,544:
{{works with|node.js|0.10.32}}
{{trans|C#}}
<langsyntaxhighlight lang="ecmascript">randrsl = new Uint32Array(256);
randcnt = 0;
mm = new Uint32Array(256);
Line 1,447 ⟶ 1,659:
xptx = z[1];
console.log('xor: '+printable_hex(xctx))
console.log('decrypted: '+xptx)</langsyntaxhighlight>
{{out}}
<pre>
Line 1,456 ⟶ 1,668:
</pre>
=={{header|Forth}}==
<langsyntaxhighlight lang="forth">
Tested for VFX Forth and GForth 64bit in Linux
The code was based on and debugged v python
Line 1,681 ⟶ 1,893:
caesar>in decode caesar
CR ." Caesar decoded : " caesar-out buff. ;
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,710 ⟶ 1,922:
Caesar decoded : a Top Secret secret ok
</pre>
=={{header|FreeBASIC}}==
{{trans|C}}
<lang freebasic>' version 03-11-2016
' compile with: fbc -s console
 
Dim Shared As UInteger<32> randrsl(256), randcnt
Static Shared As UInteger<32> mm(256)
Static Shared As UInteger<32> aa, bb ,cc
 
Sub ISAAC()
 
Dim As UInteger<32> i, x, y
 
cc = cc + 1
bb = bb + cc
 
For i = 0 To 256 -1
x = mm(i)
Select Case (i Mod 4)
Case 0 : aa = aa Xor (aa Shl 13)
Case 1 : aa = aa Xor (aa Shr 6)
Case 2 : aa = aa Xor (aa Shl 2)
Case 3 : aa = aa Xor (aa Shr 16)
End Select
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
Next
 
randcnt = 0
 
End Sub
 
 
#Macro mix(a, b, c, d, e, f, g, h)
 
a Xor= b Shl 11 : d += a : b += c
b Xor= c Shr 2 : e += b : c += d
c Xor= d Shl 8 : f += c : d += e
d Xor= e Shr 16 : g += d : e += f
e Xor= f Shl 10 : h += e : f += g
f Xor= g Shr 4 : a += f : g += h
g Xor= h Shl 8 : b += g : h += a
h Xor= a Shr 9 : c += h : a += b
 
#EndMacro
 
Sub randinit(flag As Long)
 
Dim As Long i
Dim As UInteger<32> a = &H9e3779b9 '/* the golden ratio *
Dim As UInteger<32> b = &H9e3779b9
Dim As UInteger<32> c = &H9e3779b9
Dim As UInteger<32> d = &H9e3779b9
Dim As UInteger<32> e = &H9e3779b9
Dim As UInteger<32> f = &H9e3779b9
Dim As UInteger<32> g = &H9e3779b9
Dim As UInteger<32> h = &H9e3779b9
aa = 0 : bb = 0 : cc = 0
 
For i = 0 To 3
mix(a, b, c, d, e, f, g, h)
Next
 
For i = 0 To 255 Step 8
If flag = 1 Then
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)
 
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
End If
Next
 
If flag = 1 Then
For i = 0 To 255 Step 8
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
Next
End If
 
ISAAC()
randcnt = 0
 
End Sub
 
' // Get a random 32-bit value 0..MAXINT
Function iRandom() As UInteger<32>
 
Dim As UInteger<32> r = randrsl(randcnt)
randcnt += 1
If randcnt > 255 Then
ISAAC()
randcnt = 0
End If
 
Return r
 
End Function
 
' // Get a random character in printable ASCII range
Function iRandA() As UByte
 
Return iRandom() Mod 95 +32
 
End Function
 
' // Seed ISAAC with a string
Sub iSeed(seed As String, flag As Long)
 
Dim As ULong i, m = Len(seed) -1
 
For i = 0 To 255
mm(i) = 0
Next
 
For i = 0 To 255
 
If i > m Then
randrsl(i) = 0
Else
randrsl(i) = seed[i]
End If
 
Next
 
randinit(flag)
 
End Sub
 
' // maximum length of message
'#define MAXMSG 4096
#Define _MOD_ 95 ' mod is FreeBASIC keyword
#Define _START_ 32 ' start is used as variable name
 
' // cipher modes for Caesar
Enum ciphermode
mEncipher
mDecipher
mNone
End Enum
 
' // XOR cipher on random stream. Output: ASCII string
' no maximum lenght for input and output string
Function Vernam(msg As String) As String
 
Dim As ULong i
Dim As String v
 
For i = 0 To Len(msg) -1
v += Chr(iRandA() Xor msg[i])
Next
 
Return v
 
End Function
 
' // Caesar-shift a printable character
Function Ceasar(m As ciphermode, ch As UByte, shift As UByte, modulo As UByte, _
start As UByte) As UByte
 
' FreeBASIC Mod does not handle negative numbers correctly
' also there is litte problem with shift (declared UByte)
' the IIF() statement helps with shift
' to avoid a negative n a 8 times modulo is added
' modulo * 8 get translateted by FreeBASIC to modulo shl 3
Dim As Long n = (ch - start) + IIf(m = mDecipher, -shift, shift) + modulo * 8
n = n Mod modulo
Return start + n
 
End Function
 
' // Caesar-shift a string on a pseudo-random stream
Function CeasarStr(m As ciphermode, msg As String, modulo As UByte, _
start As UByte) As String
 
Dim As Long i
Dim As String v
 
For i = 0 To Len(msg) -1
v += Chr(Ceasar(m, msg[i], iRandA(), modulo, start))
Next
 
Return v
 
End Function
 
' ------=< MAIN >=------
 
Dim As Long n, l
Dim As String msg = "a Top Secret secret"
Dim As String key = "this is my secret key"
 
Dim As String vctx, vptx
Dim As String cctx, cptx
 
l = Len(msg)
' // Encrypt: Vernam XOR
iSeed(key, 1)
vctx = Vernam(msg)
' // Encrypt: Caesar
cctx = CeasarStr(mEncipher, msg, _mod_, _start_)
' // Decrypt: Vernam XOR
iSeed(key, 1)
vptx = Vernam(vctx)
' // Decrypt: Caesar
cptx = CeasarStr(mDecipher, cctx, _mod_, _start_)
Print "message: "; msg
Print " key: "; key
Print " XOR: ";
' // Output Vernam ciphertext as a string of hex digits
For n = 0 To l -1
Print Hex(vctx[n], 2);
Next
Print
' // Output Vernam decrypted plaintext
Print "XOR dcr: "; vptx
' // Caesar
Print " MOD: ";
' // Output Caesar ciphertext as a string of hex digits
For n= 0 To l -1
Print Hex(cctx[n], 2);
Next
Print
' // Output Caesar decrypted plaintext
Print "MOD dcr: " ; cptx
 
' empty keyboard buffer
While InKey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End</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|Go}}==
XOR version
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 2,079 ⟶ 2,043:
}
return fmt.Sprintf("%X", b)
}</langsyntaxhighlight>
{{out}}
<pre>
Line 2,088 ⟶ 2,052:
 
=={{header|Haskell}}==
<langsyntaxhighlight Haskelllang="haskell">import Data.Array (Array, (!), (//), array, elems)
import Data.Word (Word, Word32)
import Data.Bits (shift, xor)
Line 2,222 ⟶ 2,186:
putStrLn $ "Key : " ++ key
putStrLn $ "XOR : " ++ hexify ver
putStrLn $ "XOR dcr: " ++ unver</langsyntaxhighlight>
{{out}}
<pre>Message: a Top Secret secret
Line 2,236 ⟶ 2,200:
It is possible in Haxe to create your own 32bit unsigned type,
but that is outside this exercise.
<syntaxhighlight lang="haxe">
<lang Haxe>
package src ;
import haxe.Int32;
Line 2,398 ⟶ 2,362:
}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,408 ⟶ 2,372:
MOD dcr: a Top Secret secret
</pre>
 
=={{header|J}}==
{{trans|C}}
In this draft, only the XOR implementation (vernam) is implemented:
<syntaxhighlight lang="j">NB. bitwise logic on 32 bit unsigned values
ub4=: (#.33{.1)&|
xor=: ub4@(2b10110 b.)
shl=: ub4@(33 b.~)
add=: ub4@+
 
isaac=: {{
cc=: cc add 1
bb=: bb add cc
for_i.i.256 do.
aa=. aa xor aa shl 13 _6 2 _16{~4|i
X=. i{mm
aa=. aa add mm{~ 256| i+128
y=. aa add bb add mm{~ 256| X shl _2
randrsl=: randrsl i}~ bb=. X add mm{~ 256| y shl _10
end.
randcnt=: 0
}}
mix=: {{
b=: b add c [ d=: d add a=: a xor b shl 11
c=: c add d [ e=: e add b=: b xor c shl _2
d=: d add e [ f=: f add c=: c xor d shl 8
e=: e add f [ g=: g add d=: d xor e shl _16
f=: f add g [ h=: h add e=: e xor f shl 10
g=: g add h [ a=: a add f=: f xor g shl _4
h=: h add a [ b=: b add g=: g xor h shl 8
a=: a add b [ c=: c add h=: h xor a shl _9
}}
 
randinit=: {{
aa=: bb=: cc=: 0
a=: b=: c=: d=: e=: f=: g=: h=: 16b9e3779b9
mix^:4''
if. y do.
for_i. _8]\i.256 do.
mix 'a b c d e f g h'=: (a,b,c,d,e,f,g,h) add i{randrsl
mm=: mm i}~ a,b,c,d,e,f,g,h
end.
for_i. _8]\i.256 do.
mix 'a b c d e f g h'=: (a,b,c,d,e,f,g,h) add i{mm
mm=: mm i}~ a,b,c,d,e,f,g,h
end.
else.
for_i. _8]\i.256 do.
mix ''
mm=: mm i}~ a,b,c,d,e,f,g,h
end.
end.
isaac''
}}
 
iRandom=: {{
r=. randcnt { randrsl
if. 255 < randcnt=: randcnt+1 do. isaac'' end.
r
}}
 
iRandA=: {{ 7 u: 32+95|iRandom^:(1+i.y)'' }}
 
iSeed=: {{ NB. y: seed, x: flag
0 iSeed y
:
mm=: 256#0
randrsl=: 256{.3 u: y
randinit x
}}
 
vernam=: {{ y xor&.(3&u:) iRandA #y }}</syntaxhighlight>
 
Task example:<syntaxhighlight lang="j"> ,hfd 3 u:E=: vernam 'a Top Secret secret' [ 1 iSeed 'this is my secret key'
1c0636190b1260233b35125f1e1d0e2f4c5422
vernam E [ 1 iSeed 'this is my secret key'
a Top Secret secret</syntaxhighlight>
 
=={{header|Java}}==
Line 2,417 ⟶ 2,459:
This implementation extends the java.util.Random class, so it inherits methods that generate booleans, floats, doubles and longs, and can also generate numbers with Gaussian and uniform distribution. It can also be plugged in to standard library methods that receive a Random instance as a source of randomness. The toHexString() and main() methods are for demo purposes only and can be removed without changing main functionality.
 
<langsyntaxhighlight Javalang="java">import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.Random;
Line 2,641 ⟶ 2,683:
System.out.printf("MOD dcr: %s\n", caesarDecrypted);
}
}</langsyntaxhighlight>
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">
<lang Julia>
"""
Julia translation of code from the following:
Line 2,825 ⟶ 2,867:
const key = "this is my secret key"
test(IState(), msg, key)
</syntaxhighlight>
</lang>
{{output}}<pre>
Message: a Top Secret secret
Line 2,835 ⟶ 2,877:
=={{header|Kotlin}}==
{{trans|C}}
<langsyntaxhighlight lang="scala">// version 1.1.3
 
/* external results */
Line 2,997 ⟶ 3,039:
println("MOD : ${cctx.toHexByteString()}")
println("MOD dcr : $cptx")
}</langsyntaxhighlight>
 
{{out}}
Line 3,010 ⟶ 3,052:
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">#!/usr/bin/env lua
-- ISAAC - Lua 5.3
 
Line 3,199 ⟶ 3,241:
 
main()
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 3,214 ⟶ 3,256:
{{works with|ADW Modula-2|any (Compile with the linker option ''Console Application'').}}
I changed the identifiers to clearer ones and I changed the variables <code>a</code>, <code>b</code>, ..., <code>h</code> to an array, because they made my blood boil.
<langsyntaxhighlight lang="modula2">
MODULE RosettaIsaac;
 
Line 3,230 ⟶ 3,272:
TMode = (iEncrypt, iDecrypt);
TString = ARRAY [0 .. MaxStrLength - 1] OF CHAR;
THexString = ARRAY [0 .. 2 * MaxStrLength - 1] OF CHAR;
TCardIndexedFrom0To7 = ARRAY [0 .. 7] OF CARDINAL;
 
Line 3,240 ⟶ 3,283:
XorPlainText: TString = '';
ModPlainText: TString = '';
HexText: THexString;
Mode: TMode = iEncrypt;
HexText: TString;
 
(* ISAAC globals *)
(* external results *)
RandRsl: ARRAY [0 .. 256255] OF CARDINAL;
RandCnt: CARDINAL;
 
(* internal state *)
MM: ARRAY [0 .. 256255] OF CARDINAL;
AA: CARDINAL = 0;
BB: CARDINAL = 0;
Line 3,336 ⟶ 3,378:
PROCEDURE SeedIsaac(Seed: ARRAY OF CHAR; Flag: BOOLEAN);
VAR
I, MSeedLength: CARDINAL;
BEGIN
FOR I := 0 TO 255 DO
MM[I] := 0;
END;
MSeedLength := Length(Seed);
FOR I := 0 TO 255 DO
(* In case seed has less than 256 elements *)
IF I > MSeedLength THEN
RandRsl[I] := 0
ELSE
Line 3,397 ⟶ 3,439:
OrdMsgI: SHORTCARD;
BEGIN
Assign(''Msg, Destination);
FOR I := 0 TO Length(Msg) - 1 DO
OrdMsgI := ORD(Msg[I]);
Append(Destination[I] := CHR(GetRandomChar() BXOR OrdMsgI), Destination);
END;
END Vernam;
Line 3,433 ⟶ 3,475:
I: CARDINAL;
BEGIN
Assign(''Msg, Destination);
FOR I := 0 TO Length(Msg) - 1 DO
Append(Destination[I] := Caesar(M, Msg[I], GetRandomChar(), 95, ' '), Destination);
END;
END Vigenere;
Line 3,443 ⟶ 3,485:
SeedIsaac(Key, TRUE);
(* (2) Encryption *)
Mode := iEncrypt;
(* (a) XOR (Vernam) *)
Vernam(Msg, XorCipherText);
(* (b) MOD (Vigenere) *)
Vigenere(Msg, ModeiEncrypt, ModCipherText);
(* (3) Decryption *)
Mode := iDecrypt;
SeedIsaac(Key, TRUE);
(* (a) XOR (Vernam) *)
Vernam(XorCipherText, XorPlainText);
(* (b) MOD (Vigenere) *)
Vigenere(ModCipherText, ModeiDecrypt, ModPlainText);
(* program output *)
WriteString('Message: '); WriteString(Msg); WriteLn;
Line 3,465 ⟶ 3,505:
WriteString('MOD dcr: '); WriteString(ModPlainText); WriteLn;
END RosettaIsaac.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 3,479 ⟶ 3,519:
{{trans|Pascal}}
We choose the translate the Pascal version as the it’s easier to translate to Nim from Pascal rather than from C.
This is not an exact transationtranslation: the more important difference is the use of a global state record rather than a list of global variables. This global state is transmitted to each procedure. This way, it is possible to run several PRNG concurrently.
 
We have also replaced the eight variables "a" to "h" with an array. This allows to simplify the code at several places by using a loop. And we changed the "mod" to "and", even if the compiler will likely optimize the modulo when the second operand is a power of two.
 
Note that the "mix" procedure could possibly be transformed in a template or be marked as "inline" (in the C version, it is a "define"). But as we are not in a procedure whose performance is critical, expanding the code rather than calling a procedure is not very useful.
 
<langsyntaxhighlight Nimlang="nim">import strutils
 
type
Line 3,641 ⟶ 3,681:
echo " MOD: ", mctx.toHex
echo "XOR dcr: ", xptx
echo "MOD dcr: ", mptx</langsyntaxhighlight>
 
{{out}}
Line 3,653 ⟶ 3,693:
=={{header|Pascal}}==
Free Pascal. A fully functional and complete reference solution of the task.
<syntaxhighlight lang="pascal">
<lang Pascal>
PROGRAM RosettaIsaac;
USES
Line 3,875 ⟶ 3,915:
Writeln('MOD dcr: ', mptx);
END.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 3,893 ⟶ 3,933:
as well as additional convenience functions.
 
<langsyntaxhighlight lang="perl">use warnings;
use strict;
use Math::Random::ISAAC;
Line 3,923 ⟶ 3,963:
map { ord($_) ^ shift(@iranda) } # xor it with rand char
split "", $msg; # Take each character
}</langsyntaxhighlight>
{{out}}
<pre>
Line 3,935 ⟶ 3,975:
{{trans|Pascal}}
We need the r32() function to convert our common sense maths into the needed unsigned_and_throw_away_any_high_bits maths.
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\ISAAC_Cipher.exw
Line 4,083 ⟶ 4,123:
<span style="color: #0000FF;">?</span><span style="color: #008000;">"done"</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 4,095 ⟶ 4,135:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de add32 @
(mod32 (pass +)) )
 
Line 4,199 ⟶ 4,239:
95 ) ) ) ) ) ) ) ) ) )
 
(bye)</langsyntaxhighlight>
 
=={{header|Python}}==
Line 4,209 ⟶ 4,249:
This implementation extends the Random class of the built-in random module, so it automatically inherits methods for generating several distributions, as well as support for shuffling and sampling collections.
 
<langsyntaxhighlight Pythonlang="python">import random
import collections
 
Line 4,405 ⟶ 4,445:
print('MOD :', hexify(caesar_encoded))
print('MOD dcr:', caesar_decoded)
</syntaxhighlight>
</lang>
 
=={{header|Racket}}==
Line 4,417 ⟶ 4,457:
left from after the XOR, and one with a cleanly reseeded state engine.
 
<langsyntaxhighlight lang="racket">#lang racket
;; Imperative version: Translation of C
;; Vigenère: Translation of Pascal
Line 4,671 ⟶ 4,711:
(randctx-b C) => #x902c0691
(randctx-c C) => 10))
}</langsyntaxhighlight>
 
{{out}}
Line 4,692 ⟶ 4,732:
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" perl6line>my uint32 (@mm, @randrsl, $randcnt, $aa, $bb, $cc);
my \ϕ := 2654435769; constant MOD = 95; constant START = 32;
 
Line 4,805 ⟶ 4,845:
say "MOD : ", $cctx2hex;
say "MOD dcr : ", $cptx;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 4,818 ⟶ 4,858:
=={{header|REXX}}==
===version 1===
<langsyntaxhighlight lang="rexx">/* REXX ---------------------------------------------------------------
* 24.07.2014 Walter Pachl translated from Pascal
* extend with decryption (following Pascal)
Line 5,025 ⟶ 5,065:
If arg(3)<>'' Then
res=res+arg(3)
return res//4294967296</langsyntaxhighlight>
{{out}}
<pre>Message: a Top Secret secret
Line 5,036 ⟶ 5,076:
===version 2===
This can be used to encrypt a file and thereafter decrypt it.
<langsyntaxhighlight lang="rexx">/* REXX ---------------------------------------------------------------
* 25.07.2014 Walter Pachl framing version 1 for processing a file
*--------------------------------------------------------------------*/
Line 5,274 ⟶ 5,314:
parse Arg fid
Parse Var fid fn '.' ft
Return fn</langsyntaxhighlight>
{{out}}
<pre>Please enter a key
Line 5,288 ⟶ 5,328:
 
=={{header|Rust}}==
<langsyntaxhighlight lang="rust">
//! includes the XOR version of the encryption scheme
 
Line 5,459 ⟶ 5,499:
}
 
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 5,470 ⟶ 5,510:
=={{header|Sidef}}==
{{trans|Perl}}
<langsyntaxhighlight lang="ruby">require('Math::Random::ISAAC')
 
func xor_isaac(key, msg) {
Line 5,489 ⟶ 5,529:
say "Key : #{key}"
say "XOR : #{enc}"
say "XOR dcr: #{pack('H*', dec)}"</langsyntaxhighlight>
{{out}}
<pre>
Line 5,501 ⟶ 5,541:
{{works with|Tcl|8.6}}
{{trans|Go}}
<langsyntaxhighlight lang="tcl">package require Tcl 8.6
 
oo::class create ISAAC {
Line 5,610 ⟶ 5,650:
return [binary encode hex [binary format c* $b]]
}
}</langsyntaxhighlight>
Demonstrating:
<langsyntaxhighlight lang="tcl">set key "this is my secret key"
set msg "a Top Secret secret"
ISAAC create demo $key
puts "Message: $msg"
puts "Key : $key"
puts "XOR : [demo vernam $msg]"</langsyntaxhighlight>
{{out}}
<pre>
Line 5,627 ⟶ 5,667:
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-traititerate}}
{{libheader|Wren-dynamic}}
{{libheader|Wren-fmt}}
<langsyntaxhighlight ecmascriptlang="wren">import "./traititerate" for Stepped
import "./dynamic" for Enum
import "./fmt" for Fmt
 
/* external results */
Line 5,809 ⟶ 5,849:
System.print("XOR dcr : %(vptx)")
System.print("MOD : %(toHexByteString.call(cctx))")
System.print("MOD dcr : %(cptx)")</langsyntaxhighlight>
 
{{out}}
9,476

edits