Hello Dan and/or others...
Some questions and remarks below.
I spent (wasted?) a lot of time yesterday and again today, looking
at mix and the rest of the stuff about Isaac, both at Rosetta, and
at the author's, Rob Jenkins', site:
http://www.burtleburtle.net/bob/rand/isaacafa.html
The author's own listing of his 32-bit "readable C" code is similar to
the first part of the Rosetta C listing, although the Rosetta listing
has several extras, from iSeed() downwards, including a different
main().
The core of the whole thing is described as algorithm 1.1 in Amasson:
http://eprint.iacr.org/2006/438.pdf,
and is quite concisely coded (as isaac()) in both listings. Amasson
doesn't
mention mix.
Jenkins' site also includes a presumably non-readable C listing, and
a 64-bit version.
Q0 What is the difference between 32 b. , 33 b. and 34 b. for left
shift, ie with positive x?
Q1 Is mix truly a part of the encoding or not?
Q2 Is it sufficient, in J, to start of with
256 {.a. i. <string message> ?
I think that means that each byte becomes a word with 4 (or 8) bytes,
although this encoding should leave the upper 3 (or 7) bytes at zero.
I decode the results with output { a. . I don't understand C (nor the
other languages) well enough to see how they're doing it.
Q3 My pc's are 64-bit. The implementation appears to work with
characters encoded into (computer) words. Correct?
Q4 I've achieved a working version in the sense that a verb
can encipher and decipher the message, but the ciphers are
apparently wrong. I'm just printing them as integers, but
they seem to have no relation to the samples:
isaacrosetta'' NB.my usual apologies re word-wrap, LF etc
Message: a Top Secret secret
Key: this is my secret key
XOR encr:3 66 54 13 18 66 49 7 1 16 7 22 66 17 7 1 16 7 22
XOR decr:a Top Secret secret
MOD encr:68 98 55 82 83 98 54 72 70 85 72 87 98 86 72 70 85 72 87
MOD decr:a Top Secret secret
The message has 19 characters, while the required encryptions each
have 38 hex-digits, ie 2 per byte. The hex sample for MOD is
734270227D36772A783B4F2A5F206266236978
My version of mix is ok, but not worth reproducing here and trying your
patience. It produces the same results on simple input as Raul's
explicit
verb, so I'll assume it's not at fault.
I suspect the problem is associated with my Q2 above, but it might
easily
be that I've got the core Isaac code wrong, or am doing the wrong
number
of mixes, etc. It can't be all wrong though, as the plaintext is
recovered
correctly, both for the example, and for much longer inputs.
I could provide the script, but it's pretty long, though not as long as
the C code.
Any ideas?
Mike
On 05/09/2015 03:55, Dan Bron wrote:
Periodically I review the list of open J tasks on RosettaCode [1].
Today I came across an obscure but (if you believe the task
description) meritorious cipher, called ISAAC ("Indirection, Shift,
Accumulate, Add, and Count”).
I understand the basic concepts of cryptography, but am generally
unversed in the practical details of implementation. In other words:
at the moment, I’m blindly transliterating the C implementation
(marked as canonical) to J, hewing as closely to the source material
as possible, loops and all.
Which, of course, results in some damn ugly J. Take, for example,
this C preprocessor macro, which I’ve dutifully transliterated as in
the post-script.
#define mix(a,b,c,d,e,f,g,h) \
{ \
a^=b<<11; d+=a; b+=c; \
b^=c>>2; e+=b; c+=d; \
c^=d<<8; f+=c; d+=e; \
d^=e>>16; g+=d; e+=f; \
e^=f<<10; h+=e; f+=g; \
f^=g>>4; a+=f; g+=h; \
g^=h<<8; b+=g; h+=a; \
h^=a>>9; c+=h; a+=b; \
}
Can you write this function in idiomatic, perhaps even elegant, J?
Extra brownie points for something along the lines of f/
a,b,c,d,e,f,g,h ,
If it gives you a jumpstart, here is the pattern of variable names,
as well as the bitshift direction and degree:
abdabc < 11
bcebcd > 2
cdfcde < 8
degdef > 16
efhefg < 10
fgafgh > 4
ghbgha < 8
hachab > 9
Expressed as left-hand arguments to |.!.0, the bitshifts are 11 _2 8
_16 10 _4 8 _9 .
And the variable name matrix, expressed as indices into ‘abcdefgh’ is:
0 1 3 0 1 2
1 2 4 1 2 3
2 3 5 2 3 4
3 4 6 3 4 5
4 5 7 4 5 6
5 6 0 5 6 7
6 7 1 6 7 0
7 0 2 7 0 1
Which pattern can be expressed as 0 1 3 0 1 2 (|."0 1) i.8 if you
conceive of it column-wise, or 0 1 3 0 1 2 (8 | +/~) i.8 if
row-wise. Either way, the salient structure appears to be 0 1 3 0
1 2 .
-Dan
[1] Tasks on RosettaCode with no J implementation:
http://rosettacode.org/wiki/Reports:Tasks_not_implemented_in_J
<http://rosettacode.org/wiki/Reports:Tasks_not_implemented_in_J>
[2] The “wash shuffle” (which Wikipedia calls the “Corgi shuffle”)
is that basic, no-frills move you see at the cheap tables in
Atlantic City: the dealer simply spreads all the cards face down on
the table and slides them all around and over each other. Not
pretty, but effective, and less susceptible to sleight-of-hand
cheating.
https://en.wikipedia.org/wiki/Shuffling#Corgi_shuffle
<https://en.wikipedia.org/wiki/Shuffling#Corgi_shuffle>
PS: Here is a direct transliteration, but be WARNED: I haven’t
gotten the overall ISAAC cypher to produce the correct outputs yet,
so this is untested and may be incorrect.
NB. ISAAC operates on 32-bit ints, meaning b. will break it on
64-bit systems
bww =: (32#2)&#:
hlfUnd =: 2 : 'v^:_1@:(u v)’
bwXor =: ~:&.bww
bwShift =: |.!.0 hlfUnd bww
mix =: verb define
'a b c d e f g h'=.y
NB. a^=b<<11; d+=a; b+=c;
a =. a bwXor 11 bwShift b
d =. d + a
b =. b + c
NB. b^=c>>2; e+=b; c+=d;
b =. b bwXor _2 bwShift c
e =. e + b
c =. c + d
NB. c^=d<<8; f+=c; d+=e;
c =. c bwXor 8 bwShift d
f =. f + c
d =. d + e
NB. d^=e>>16; g+=d; e+=f;
d =. d bwXor _16 bwShift e
g =. g + d
e =. e + f
NB. e^=f<<10; h+=e; f+=g;
e =. e bwXor 10 bwShift f
h =. h + e
f =. f + g
NB. f^=g>>4; a+=f; g+=h;
f =. f bwXor _4 bwShift g
a =. a + f
g =. g + h
NB. g^=h<<8; b+=g; h+=a;
g =. g bwXor 8 bwShift h
b =. b + g
h =. h + a
NB. h^=a>>9; c+=h; a+=b;
h =. h bwXor _9 bwShift a
c =. c + h
a =. a + b
".&> ;: 'a b c d e f g h'
)