Misc:arcfour

From Amar
Revision as of 00:41, 15 May 2007 by Lax (talk | contribs) (Arcfour)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

crypt.c

#include "crypt.h"

/* key is the state that should be allocated by the caller */
#define STATE key->state
#define I key->i
#define J key->j

int rc4_set_key(arcfour_key * key, byte * key_data, int key_len) {
        register int tmp, j, i;
        byte *state = STATE;
        int ivindex;

        for (i = 0; i < 256; i++)
                state[i] = i;

        I = 0;
        J = 0;
        ivindex = 0;

        for (j = i = 0; i < 256; i++) {
                j += state[i] + key_data[i % key_len];
                j &= 0xff;
                swap_byte(state[i], state[j]);
        }

        return 0;
}


void rc4_encrypt(arcfour_key * key, byte * buffer_ptr, int buffer_len) {
        register int tmp;
        register int counter;
        register int i = I, j = J;
        byte *state = STATE;


        for (counter = 0; counter < buffer_len; counter++) {
                i++;
                i &= 0xff;
                j += state[i];
                j &= 0xff;

                /* swap state[i] and state[j] */
                swap_byte(state[i], state[j]);
                buffer_ptr[counter] ^= state[(state[i] + tmp) & 0xff];
        }
        J = j;
        I = i;
}


void arcfour_init(ArcfourContext *ctx, const unsigned char *key, unsigned int key_len) { 
  unsigned int t, u; 
  unsigned int keyindex;
  unsigned int stateindex;
  unsigned char* state;
  unsigned int counter;

  
  state = &ctx->state[0];
  ctx->x = 0;
  ctx->y = 0;
  for (counter = 0; counter < 256; counter++)
    state[counter] = counter;
  keyindex = 0;
  stateindex = 0;
  for (counter = 0; counter < 256; counter++) {
      t = state[counter];
      stateindex = (stateindex + key[keyindex] + t) & 0xff;
      u = state[stateindex];
      state[stateindex] = t;
      state[counter] = u;
      if (++keyindex >= key_len)
        keyindex = 0;
  }
}

unsigned int arcfour_byte(ArcfourContext *ctx) {
  unsigned int x;
  unsigned int y;
  unsigned int sx, sy;
  unsigned char *state;

  state = ctx->state;
  x = (ctx->x + 1) & 0xff;
  sx = state[x];
  y = (sx + ctx->y) & 0xff;
  sy = state[y];
  ctx->x = x;
  ctx->y = y;
  state[y] = sx;
  ctx->y = y;
  state[y] = sx;
  state[x] = sy;
  return state[(sx + sy) & 0xff];
}


void arcfour_encrypt(ArcfourContext *ctx, unsigned char *dest, const unsigned char *src, unsigned int len) {
  register unsigned int i;
  for (i = 0; i < len; i++)
    dest[i] = src[i] ^ arcfour_byte(ctx);
}

void arcfour_decrypt(ArcfourContext *ctx, unsigned char *dest, const unsigned char *src, unsigned int len) {
  arcfour_encrypt(ctx, dest, src, len);
}

crypt.h

// arc4 header...

typedef unsigned char byte;

typedef struct
{
   unsigned int x;
   unsigned int y;
   unsigned char state[256];
} ArcfourContext;

typedef struct arcfour_key
{
   byte state[256];
   byte i;
   byte j;
} arcfour_key;


#define swap_byte(x,y) tmp = (x); (x) = (y); (y) = tmp



void arcfour_init(ArcfourContext *, const unsigned char *, unsigned int);
unsigned int arcfour_byte(ArcfourContext *);
void arcfour_encrypt(ArcfourContext *, unsigned char *, const unsigned char *, unsigned int);
void arcfour_decrypt(ArcfourContext *, unsigned char *, const unsigned char *, unsigned int);

int rc4_set_key(arcfour_key *, byte *, int);
void rc4_encrypt(arcfour_key *, byte *, int);