On Tue, 20 Dec 2005 21:25:47 +0000, Bryan Olson wrote:
> Andrew Pogrebennyk wrote:
>> Feel really good when everything is implemented right :) Or, at least,
>> there are no obvious bugs this time.
>
> Now that you've gotten numerically correct output, you should
> look at some subtler issues.
>
> Your code seems to confuse pass-phrase / key / state. An RC4
> key is sequence of octets no more than 256 octets long. For
> security reasons, each new message requires a new key. An RC4
> encryption state consists of a permutation of the integers
> [0..255] and two integers in that same range. RC4 itself has
> no notion of pass-phrase.
>
> For practical reasons, crypto code should not assume that
> the entire input message is available in memory. The usual
> method is to process one piece, while updating the encryption
> state to be ready to handle the next piece.
>
> Reasonable (untested) declarations might be:
>
> typedef struct
> {
> unsigned char s[256];
> unsigned char i;
> unsigned char j;
> } RC4_State;
>
> void set_key(
> RC4_State* state,
> const unsigned char* session_key,
> size_t session_key_size);
>
> void rc4(
> RC4_State* state,
> const unsigned char* in,
> unsigned char* out,
> size_t inout_size);
Thanks for pointing that. After finishing my semester I returned to
crypto, so the first step was to name variables appropriately. There's my
current code in the end of the message.
I am still not sure if ARCFOUR will be used in a project I'm working on,
but if I return to ARCFOUR, I'll use it as a basis for implementing
CipherSaber and probably will enhance it with multi-roung initiation or by
using "2-byte RC4". Would be very grateful for instructions on those
techniques.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SIZEOF(buf) (sizeof(buf)/sizeof(buf[0]))
typedef struct
{
unsigned char session_key[256];
unsigned char index[2];
}
RC4_State;
void swap (unsigned char *a, unsigned char *b)
{
unsigned char temp;
temp = *a;
*a = *b;
*b = temp;
}
void set_key (unsigned char *key_text, size_t key_text_size, unsigned char *K, RC4_State *state)
{
unsigned char i, j;
short int counter;
unsigned char *S = &state->session_key[0];
state->index[0] = 0;
state->index[1] = 0;
for (counter = 0; counter < 256; counter++)
S [counter] = counter;
for (counter = 0; counter < 256; counter++)
K [counter] = key_text [counter % key_text_size ];
i = j = 0;
for (counter = 0; counter < 256; counter++) /* initialize the S-box */
{
j = (j + S [counter] + K [i]) % 256;
swap (&S [counter], &S [j]);
i = (i + 1) % 256;
}
}
void rc4(unsigned char *plain, size_t plain_size, unsigned char *cipher, RC4_State *state)
{
unsigned char i, j;
short int counter;
unsigned char *S = &state->session_key[0];
unsigned char xor_index;
i = state->index[0];
j = state->index[1];
for(counter = 0; counter < plain_size; counter ++)
{
i = (i + 1) % 256;
j = (j + S [i]) % 256;
swap (&S [i], &S [j]);
xor_index = (S[i] + S[j]) % 256;
cipher [counter] = plain [counter] ^ S[xor_index];
}
}
int main()
{
unsigned char K [256];
unsigned char key_text [] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
unsigned char plain [] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
unsigned char *cipher;
short int i;
RC4_State state;
set_key (key_text, SIZEOF(key_text), K, &state);
memset (K, 0x0, SIZEOF(K));
memset (key_text, 0x0, SIZEOF(key_text));
printf("\nSize(plain): %d\n", SIZEOF(plain));
for (i = 0; i < SIZEOF(plain); i++)
printf ("%x ", plain [i]);
cipher = calloc (SIZEOF(plain), sizeof(plain[0]));
rc4 (plain, SIZEOF(plain), cipher, &state);
printf("\n\nSize(cipher): %d\n", SIZEOF(plain));
for (i = 0; i < SIZEOF(plain); i++)
printf ("%x ", cipher [i]);
free (cipher);
printf("\n\n");
return 0;
}
Received on Tue Jan 3 03:41:37 2006