RC4 stream cipher in C. User is able to enter any key that is 5 bytes to 32 bytes long
Explanation:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 256 // 2^8
void swap(unsigned char *a, unsigned char *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
int KSA(char *key, unsigned char *S) {
int len = strlen(key);
int j = 0;
for(int i = 0; i < N; i++)
S[i] = i;
for(int i = 0; i < N; i++) {
j = (j + S[i] + key[i % len]) % N;
swap(&S[i], &S[j]);
}
return 0;
}
int PRGA(unsigned char *S, char *plaintext, unsigned char *ciphertext) {
int i = 0;
int j = 0;
for(size_t n = 0, len = strlen(plaintext); n < len; n++) {
i = (i + 1) % N;
j = (j + S[i]) % N;
swap(&S[i], &S[j]);
int rnd = S[(S[i] + S[j]) % N];
ciphertext[n] = rnd ^ plaintext[n];
}
return 0;
}
int RC4(char *key, char *plaintext, unsigned char *ciphertext) {
unsigned char S[N];
KSA(key, S);
PRGA(S, plaintext, ciphertext);
return 0;
}
int main(int argc, char *argv[]) {
if(argc < 3) {
printf("Usage: %s <key> <plaintext>", argv[0]);
return -1;
}
unsigned char *ciphertext = malloc(sizeof(int) * strlen(argv[2]));
RC4(argv[1], argv[2], ciphertext);
for(size_t i = 0, len = strlen(argv[2]); i < len; i++)
printf("%02hhX", ciphertext[i]);
return 0;
}