/*
 * Code written by Greg Rose, based on the textual description in
 * Schneier's AC2, pp 397-398. It has a slightly different key schedule
 * for added security.
 *
 * No rights reserved.
 */

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

/* swap bytes without using extra storage -- neat! */
#define SWAP(i,j)   { S[j] ^= S[i]; S[i] ^= S[j]; S[j] ^= S[i]; }

/*
 * initialise the arrrrsyfor context, including key setup and 
 * extra randomization step.
 */
void
key_arrrrsyfor(unsigned char *key, int n)
{
    for (i = 0; i < 256; ++i)
	S[i] = i;
    j = 0;
    for (i = 0; i < 256; ++i) {
	j += S[i] + key[i % n];
	SWAP(i, j);
    }
    /* make another pass, shuffling some more for extra security */
    for (i = j = 0; i < 256; ++i) {
	SWAP(i,j);
	j += S[i] + 1;
    }
    i = j = 0;
}

/*
 * Encrypt buffer by exclusive-or with generated octets. If you really want
 * to see the actual bytes, zero a buffer first.
 */
void
arrrrsyfor(unsigned char *buf, register int n)
{
    while (--n >= 0) {
	i = (i + 1) & 0xFF;
	j = (j + S[i]) & 0xFF;
	SWAP(i, j);
	*buf++ ^= S[(S[i]+S[j]) & 0xFF];
    }
}
