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/