MODULE CryptoARC4;
IMPORT
Ciphers := CryptoCiphers, BIT;
TYPE
Cipher* = OBJECT (Ciphers.Cipher)
VAR
s: ARRAY 256 OF CHAR;
i, j: LONGINT;
PROCEDURE &Init*;
BEGIN
SetNameAndBlocksize( "arc4", 1 );
isKeyInitialized := FALSE
END Init;
PROCEDURE InitKey*( CONST src: ARRAY OF CHAR; pos, keybits: LONGINT);
VAR
keydata: ARRAY 256 OF CHAR;
keybytes: LONGINT;
temp: CHAR;
BEGIN
ASSERT( keybits MOD 8 = 0 ); ASSERT( keybits > 7); ASSERT( keybits < 2049 );
InitKey^( src, pos, keybits );
keybytes:= keybits DIV 8;
i := 0; j := 0;
FOR i := 0 TO 255 DO s[ i ] := CHR( i ) END;
FOR i := 0 TO 255 DO keydata[ i ] := src[pos + (i MOD keybytes)] END;
FOR i := 0 TO 255 DO
j := ( j + ORD( s[i] ) + ORD( keydata[i] ) ) MOD 256;
temp := s[ i ];
s[ i ] := s[ j ];
s[ j ] := temp
END;
isKeyInitialized := TRUE;
FOR i := 0 TO 255 DO keydata[ i ] := CHR( 0 ) END;
i := 0; j := 0;
END InitKey;
PROCEDURE Encrypt*( VAR buf: ARRAY OF CHAR; ofs, len: LONGINT );
VAR
k, t: LONGINT;
ch, temp: CHAR;
BEGIN
ASSERT( isKeyInitialized );
FOR k := 0 TO len-1 DO
i := ( i+1 ) MOD 256;
j := ( j + ORD( s[ i ] ) ) MOD 256;
temp := s[ i ];
s[ i ] := s[ j ];
s[ j ] := temp;
t := (ORD( s[i] ) + ORD( s[j] )) MOD 256;
ch := s[ t ];
buf[ ofs + k ] := BIT.CXOR( buf[ ofs + k ], ch );
END
END Encrypt;
PROCEDURE Decrypt*( VAR buf: ARRAY OF CHAR; ofs, len: LONGINT );
BEGIN
ASSERT( isKeyInitialized );
Encrypt( buf, ofs, len )
END Decrypt;
END Cipher;
PROCEDURE NewCipher*() : Ciphers.Cipher;
VAR c: Cipher;
BEGIN
NEW( c ); RETURN c
END NewCipher;
END CryptoARC4.