// tiny rc4 implementation
// by randomdude999
// public domain

// Usage: since RC4 is a stream cipher, encrypt and decrypt are the same
// operation. Pass the key in `k`, key length in bytes in `K`, and data to
// encrypt in `o` with data length in `O`. The data is modified in place.

// rc4, dropping first 768 bytes of keystream. (makes it a bit more secure.)
// 202 bytes excluding function name
void rc4_drop768(char*k,int K,char*o,int O){unsigned char s[256],i=0,j=0,t;for(;s[i]=i,++i;);for(;t=s[i],s[i]=s[j+=t+k[i%K]],s[j]=t,++i;);for(K=-769,j=0;++K<O;K>=0?o[K]^=s[t+=s[i]]:0)t=s[++i],s[i]=s[j+=t],s[j]=t;}

// plain rc4. 190 bytes excluding function name
void rc4(char*k,int K,char*o,int O){unsigned char s[256],i=0,j=0,t;for(;s[i]=i,++i;);for(;t=s[i],s[i]=s[j+=t+k[i%K]],s[j]=t,++i;);for(K=j=0;K<O;o[K++]^=s[t+=s[i]])t=s[++i],s[i]=s[j+=t],s[j]=t;}

// small test program - should output 128 null bytes
#include <stdio.h>
int main(){
	char out[64] = {0xe8,0xc9,0xb1,0xd3,0x99,0x40,0x23,0x78,
	                0xa1,0xcf,0x96,0xd0,0x83,0x1b,0xd1,0xe9,
	                0x34,0xc3,0x87,0x7d,0xbf,0x18,0x52,0x0f,
	                0x9a,0x5f,0xcb,0x90,0x06,0xa7,0xfc,0xb6,
	                0xef,0x5d,0x69,0x10,0x68,0x25,0x16,0x0b,
	                0x04,0x34,0x15,0x6f,0xd3,0xc8,0xe9,0x62,
	                0x2a,0x47,0x1a,0xab,0x1a,0x5b,0x3d,0x37,
	                0x79,0xd5,0x71,0x2c,0xf1,0xf3,0xe7,0x0c};
	rc4_drop768("Hello", 5, out, 64);
	for(int i=0; i<64; i++) putchar(out[i]);

	char out2[64] = {0x6e,0x8e,0x4f,0xf5,0x6c,0x6b,0x5b,0x3c,
	                 0x77,0x1f,0x2b,0x68,0xb2,0x32,0x3b,0x11,
	                 0xc7,0x63,0xa7,0x28,0x0c,0x8c,0xb7,0x92,
	                 0x6a,0x31,0x7b,0xaf,0x3b,0x37,0x81,0x50,
	                 0x1e,0xdc,0x25,0x06,0x21,0xf2,0x1f,0x75,
	                 0xa7,0x87,0x26,0xf8,0x0d,0xae,0x0b,0x8f,
	                 0xdf,0x92,0x21,0x9c,0x1b,0x50,0xca,0x18,
	                 0x10,0x77,0xfc,0x50,0x96,0xee,0x2b,0x65};
	rc4("Hello", 5, out2, 64);
	for(int i=0; i<64; i++) putchar(out2[i]);
}
