0

I am implementing a RC4 algorithm in C# for my WPF app.

I followed this pdf stating the algorithm.

The thing is, in the KSA, we ought to do : j = (j + S[i] + (int)key[i % keyLengthInBits]) % 256;.

That being said, I do not understand how this would work because the key ought to be from 5 characters long to 32 characters long (40bits up to 256bits).

So let's take an example with a 5 characters key ( I'll use the same as in the pdf I linked above) : pwd12. You go fetch the character of the key at the position i % 40 (5 characters long is 40 bits). It's fine for the first 5 times because from i = 0 to i=4, we have a value in the key (pwd12). Though here is the problem (from how I see it) : when we are at i=5, we do not have any characters left in the key. Therefore we will get an ÒutOfBounds Exception.

How is it possible to works if we try to fetch a character in the key where there is none? Obviously there is something I do not see in the algorithm because it does work otherwise it would not be used...

Marks
  • 165
  • 4
  • 19

1 Answers1

1

The phrase key[i % keyLengthInBits] is a way of saying "the i'th bit of the key". It does not mean the i'th entry in the key expressed as an array of bytes, each holding 8 bits of the key.

The equivalent C code would be something like:

int bit = i & keyLengthInBits;
((key[bit / 8] >> (bit % 8)) & 1)
David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • Ok then `((key[bit / 8] >> (bit % 8)) & 1)` ,which I am not quite sure with, would be that : From what I understand of it, let's say we are at `i=5` and the key is still *pwd12* (40bits). it would be `bit = 5 & 40` which would give 0 and therefore `key[0/8] = 'p'`. From what I get of the `>>` operator, it does a right shift on the bit of 0 since `(bit % 8 = 0)` so p stays from 01110000. The `&1` makes it become 00000000. (From here I'm lost about why we would make it become 0...) I guess I'm wrong but from what I understand, this is how it goes in your two lines. @David Schwartz – Marks May 16 '16 at 16:23
  • @Marks You have it right. If `i` is 5, the code extracts the fifth bit of the key. – David Schwartz May 16 '16 at 16:30
  • Then what if we are at the 52th iteration ( `i = 52` ). It goes 52 (00110100) & 40 (00101000) which gives 00100000 so `bit = 32`. `key[32/8] = key[4]` which gives 2 (still considering the key being *pwd12*). Right shift of 0 since `32 % 8 = 0`. So it ends up being 00000010 & 00000001 which gives 0. Therefore here again it would become `j = (j + S[k] + (int)key[0]) % 256;` ) being the result we have from the i % ketLengthInBits using the two lines you provided. Is that correct ? @David Schwartz – Marks May 16 '16 at 16:43
  • If `key[4]` is `00000010`, then as `i` goes from 32 to 39, it reads off the 32nd to 39th bits from right to left, outputting 0, 1, 0, 0, 0, 0, 0, 0. – David Schwartz May 16 '16 at 16:51
  • Reading from right to left is because of the `>>` right shift I'm assuming ? Even though it does not shift since it's `>> 0`, it does read it from the right. Considering that, we still would go to 0 doing the `&1` since 01000000 & 00000001 gives 00000000. No ? @David Schwartz – Marks May 16 '16 at 17:02
  • Right. When `bit%8` is zero, we extract the rightmost bit by ANDing with 1. When `bit%8` is 1, we extract the second bit from the right by shifting right once and then ANDing with 1. – David Schwartz May 16 '16 at 17:12
  • If `(key[32/8] >> (32 % 8)) & 1` (using again `i = 52` and the key *pwd12* ), then it becomes `(key[4] >> (0)) & 1`. `key[4]` being 2 becomes `(00000010 >> 0) & 1`. Right shift of 0 gives us `01000000 & 1` which leads us to `00000000` (let's say `int result = Convert.ToInt32("00000000",2);`). Then we can see it as `j = (j + S[i] + (int)key[result]) % 256;`. Because the way I understands it is that what we just did is to make the result of `key[i % keyLengthInBits]`. *Above code being in C#.* @David Schwartz – Marks May 16 '16 at 17:32