I've managed to port RC4 implementation from PolarSSL to delphi, since I need an encrypted communication between 2 applications (C and Delphi), but the problem is, the encrypted data is never the same, both codes encrypt and decrypt data on their own successfully but not the data encrypted by the other.
Here are both codes:
C Code (Taken from PolarSSL)
typedef struct
{
int x; /*!< permutation index */
int y; /*!< permutation index */
unsigned char m[256]; /*!< permutation table */
}
arc4_context;
void arc4_setup(arc4_context *ctx, unsigned char *key, int keylen)
{
int i, j, k, a;
ctx->x = 0;
ctx->y = 0;
for( i = 0; i < 256; i++ ) ctx->m[i] = (unsigned char) i;
j = k = 0;
for( i = 0; i < 256; i++, k++ )
{
if( k >= keylen ) k = 0;
a = ctx->m[i];
j = ( j + a + key[k] ) & 0xFF;
ctx->m[i] = ctx->m[j];
ctx->m[j] = (unsigned char) a;
}
return;
}
void arc4_crypt( arc4_context *ctx, unsigned char *buf, int buflen )
{
int i, x, y, a, b;
unsigned char m[256];
x = ctx->x;
y = ctx->y;
for (i = 0; i < 256; i++) m[i] = ctx->m[i];
for( i = 0; i < buflen; i++ )
{
x = ( x + 1 ) & 0xFF; a = m[x];
y = ( y + a ) & 0xFF; b = m[y];
m[x] = (unsigned char) b;
m[y] = (unsigned char) a;
buf[i] = (unsigned char)
( buf[i] ^ m[(unsigned char)( a + b )] );
}
return;
}
My Delphi Code:
type
arc4_context = packed record
x, y: integer;
m: array[0..255] of byte;
end;
procedure arc4_setup(var ctx: arc4_context; key: PChar; keylen: Integer);
var
i, j, k, a: Integer;
begin
ctx.x := 0;
ctx.y := 0;
for i := 0 to 255 do ctx.m[i] := Byte(i);
j := 0;
k := 0;
for i := 0 to 255 do
begin
if (k >= keylen) then k := 0;
a := ctx.m[i];
j := (j + a + Byte(key[k])) and $FF;
ctx.m[i] := ctx.m[j];
ctx.m[j] := a;
Inc(k);
end;
end;
procedure arc4_crypt(ctx:arc4_context; var buf:string; buflen:integer);
var
i, x, y, a, b: Integer;
m: array [0..255] of byte;
begin
x := ctx.x;
y := ctx.y;
for i := 0 to 255 do m[i] := ctx.m[i];
i := 0;
while (i < buflen) do
begin
x := (x + 1) and $FF;
a := m[x];
y := (y + a) and $FF;
b := m[y];
m[x] := b;
m[y] := a;
buf[i+1] := Char(Byte(buf[i+1]) xor Byte(m[a + b]));
inc(i);
end
end;