/*****************************************************************************/
/*
                                      rc4.c

This module is essentially straight from the posting as reported by the file
attributed below with some minor reformatting and function names changes.  I
guess the original copyright resides with anonymous.


ATTRIBUTION
-----------
Original newsgroup source as report in [.openssl-0.9.8c.crypto.rc4]rrc4.doc

Newsgroups: sci.crypt,alt.security,comp.security.misc,alt.privacy
From: sterndark@netcom.com (David Sterndark)
Subject: RC4 Algorithm revealed.
Message-ID: <sternCvKL4B.Hyy@netcom.com>
Sender: sterndark@netcom.com 
Date: Wed, 14 Sep 1994 06:35:31 GMT


VERSION HISTORY
---------------
06-OCT-2006  MGD  initial
*/
/*****************************************************************************/

#include "rc4.h"

static void swap_byte (unsigned char *a, unsigned char *b);

void rc4_prepare_key
(
unsigned char *key_data_ptr,
int key_data_len,
rc4_key *key
)
{
   unsigned char swapByte;
   unsigned char index1;
   unsigned char index2;
   unsigned char* state;
   short counter;     
     
   state = &key->state[0];         
   for (counter = 0; counter < 256; counter++)              
   state[counter] = counter;               
   key->x = 0;     
   key->y = 0;     
   index1 = 0;     
   index2 = 0;             
   for (counter = 0; counter < 256; counter++)      
   {               
      index2 = (key_data_ptr[index1] + state[counter] + index2) % 256;
      swap_byte(&state[counter], &state[index2]);            
      index1 = (index1 + 1) % key_data_len;  
   }       
}
 
void rc4_crypt
(
unsigned char *buffer_ptr,
int buffer_len,
rc4_key *key
)
{ 
   unsigned char x;
   unsigned char y;
   unsigned char* state;
   unsigned char xorIndex;
   short counter;              
   
   x = key->x;     
   y = key->y;     
      
   state = &key->state[0];         
   for (counter = 0; counter < buffer_len; counter++)      
   {               
      x = (x + 1) % 256;                      
      y = (state[x] + y) % 256;               
      swap_byte (&state[x], &state[y]);                        
             
      xorIndex = (state[x] + state[y]) % 256;                 
      buffer_ptr[counter] ^= state[xorIndex];         
    }               
    key->x = x;     
    key->y = y;
}   
   
static void swap_byte
(
unsigned char *a,
unsigned char *b
)
{   
   unsigned char swapByte;

   swapByte = *a; 
   *a = *b;
   *b = swapByte;
}

/*****************************************************************************/
