Tuesday, September 3, 2013

Algorithm - RC4

The key-scheduling algorithm

RC4′s KSA uses a loop to iterate through the state and perform the following operation, which generates j and swaps State[i] and State[j]:

j = 0;
for(i=0; i<256; i++) {
    j = (j + State[i] + key[i%keylen]) % 256;
    swap(&State[i], &State[j]);
}

The pseudo-random number generation algorithm

In a loop, RC4′s PRNGA deterministically selects elements from the state and outputs them as a keystream with the following code:

i = j = 0;
for(k=0; k<msglength; k++) {
    i = (i+1) % 256;
    j = (j+State[i]) % 256;
 
    swap(&State[i], &State[j]);
 
    keystream[k] = State[(State[i]+State[j]) % 256];
} 

Sample Code


unsigned char S[256];
unsigned int i, j;

void swap(unsigned char *s, unsigned int i, unsigned int j) {
    unsigned char temp = s[i];
    s[i] = s[j];
    s[j] = temp;
}

/* KSA */
void rc4_init(unsigned char *key, unsigned int key_length) {
    for (i = 0; i < 256; i++)
        S[i] = i;

    for (i = j = 0; i < 256; i++) {
        j = (j + key[i % key_length] + S[i]) & 255;
        swap(S, i, j);
    }

    i = j = 0;
}

/* PRGA */
unsigned char rc4_output() {
    i = (i + 1) & 255;
    j = (j + S[i]) & 255;

    swap(S, i, j);

    return S[(S[i] + S[j]) & 255];
}

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))

int main() {
    unsigned char *test_vectors[][2] = 
    {
        {"Key", "Plaintext"},
        {"Wiki", "pedia"},
        {"Secret", "Attack at dawn"},
    {"nick", "Rowe"}
    };

    int x;
    for (x = 0; x < ARRAY_SIZE(test_vectors); x++) {
        int y;
        rc4_init(test_vectors[x][0], strlen((char*)test_vectors[x][0]));

        for (y = 0; y < strlen((char*)test_vectors[x][1]); y++)
            printf("%02X", test_vectors[x][1][y] ^ rc4_output());
        printf("\n");
    }
    return 0;
}

http://blog.markloiseau.com/2012/07/rc4-tutorial/
http://blog.dcxn.com/2010/09/14/26/