Code:
#IF 0 Code appears below for the following three files: RC4OBJ.INC Class implementation of the RC4 encryption algorithm RC4OBJ.BAS Test bed program illustrating use of RC4OBJ.INC RC4UTIL.BAS Utility macros and functions [b]Note: See the test bed code (RC4OBJ.BAS) for examples illustrating use of the code in RC4OBJ.INC.[/b] Although the stream cipher RC4 is today often treated as obsolete for long-term, high security purposes, it still remains extremely useful, especially for short-term encryption of strings whose length is varied or unpredictable. This PB implementation of RC4 is hereby placed in the public domain. Use it as you wish. Greg Turgeon 8/2008 #ENDIF '===================================================================== '-- RC4OBJ.INC '-- WIN32 API not required '-- Uses no global data '-- Compiles with either PBWIN 9.0 or PBCC 5.0 '===================================================================== %SUBKEY_SIZE = 256 TYPE ENCRYPTION_CONTEXT UserKeyLength AS LONG UserKey AS BYTE PTR InBlock AS BYTE PTR OutBlock AS BYTE PTR BlockLength AS LONG END TYPE '=========================================================== CLASS RC4Class '=========================================================== INSTANCE UserKeyLength, BlockLength, RC4X, RC4Y AS LONG INSTANCE UserKey, InBlock, OutBlock, RC4State AS BYTE PTR INSTANCE State_Buffer AS STRING * %SUBKEY_SIZE '<-- encryption subkey buffer '==================== CLASS METHOD CREATE State_Buffer = nul$(%SUBKEY_SIZE) RC4State = varptr(State_Buffer) RC4X = 0 : RC4Y = 0 END METHOD '==================== CLASS METHOD Init(Ctx AS ENCRYPTION_CONTEXT) AS LONG LOCAL keydata$, pkeydata, tmp AS BYTE PTR LOCAL i, index1, index2, passlen AS LONG passlen = Ctx.UserKeyLength keydata = nul$(passlen) pkeydata = strptr(keydata) poke$ pkeydata, peek$(Ctx.UserKey, passlen) InBlock = Ctx.InBlock OutBlock = Ctx.OutBlock BlockLength = Ctx.BlockLength tmp = (RC4State+%SUBKEY_SIZE)-1 ! push esi ! mov esi, tmp ! mov ecx, %SUBKEY_SIZE-1 LoopTop: ! mov [esi], cl ! dec ecx ! js LoopDone ! dec esi ! jmp LoopTop LoopDone: ! pop esi tmp = RC4State for i = 0 to %SUBKEY_SIZE-1 index2 = (@pkeydata[index1] + @tmp[i] + index2) AND 255 swap @tmp[i], @tmp[index2] index1 = (index1 + 1) mod passlen next i END METHOD '==================== CLASS METHOD DESTROY poke$ RC4State, nul$(%SUBKEY_SIZE) RC4X = 0 : RC4Y = 0 END METHOD '======================================= INTERFACE RC4Interface '======================================= INHERIT iUnknown '==================== METHOD Process(Ctx AS ENCRYPTION_CONTEXT) AS LONG REGISTER i AS LONG, xorindex AS LONG LOCAL pin, pout AS BYTE PTR Me.Init(Ctx) pin = InBlock pout = OutBlock for i = 1 to BlockLength RC4X = (RC4X + 1) AND 255 RC4Y = (@RC4State[RC4X] + RC4Y) AND 255 swap @RC4State[RC4X], @RC4State[RC4Y] xorindex = (@RC4State[RC4X] + @RC4State[RC4Y]) AND 255 @pout = @pin XOR @RC4State[xorindex] incr pin : incr pout next i END METHOD END INTERFACE END CLASS '-- end RC4OBJ.INC
Comment