'
' RC4crypt.inc
' (C) 2003-10-04 Martin Wehner
'
' Contact: mailto:martin.wehner@firemail.de
' Homepage: http://mitglied.lycos.de/maweso/
'
' RC4 is a stream cipher symmetric key algorithm. It was
' developed in 1987 by Ronald Rivest and kept as a trade
' secret by RSA Data Security. On September 9, 1994, the
' RC4 algorithm was anonymously posted on the Internet on
' the Cyperpunks' Anonymous Remailers List.
' RC4 uses a variable length key from 1 to 256 bytes to
' initialize a 256-byte state table. The state table is
' used for subsequent generation of pseudo-random bytes
' and then to generate a pseudo-random stream which is
' XORed with the plaintext to give the ciphertext. Each
' element in the state table is swapped at least once. The
' RC4 key is often limited to 40 bits, because of export
' restrictions but it is sometimes used as a 128 bit key.
' It has the capability of using keys between 1 and 2048
' bits.
' Analysis shows that the period of the cipher is
' overwhelmingly likely to be greater than 10^100. Eight
' to sixteen machine operations are required per output
' byte, and the cipher can be expected to run very quickly
' in software. Independent analysts have scrutinized the
' algorithm and it is considered secure. RC4 is used in
' many commercial software packages.
'
' The type definition below is an adaptation of the RC4
' algorithm to RapidQ Basic. If you want to use this
' component then you must first create an object of type
' QRC4. After that you must call the procedure Init() to
' initialize the object with the key. If you now call the
' function Pipe() with a string then the string is encoded
' and returned by the function.
' If you want to decode then simply execute the same steps
' again but call the function Pipe() with the encoded
' string.
' This component can process data streams. Encode or
' decode data streams by calling the function Pipe() for
' each stream element. You are free with the size of the
' data packets because (Pipe(s) & Pipe(t)) is always equal
' to Pipe(s & t).
'
' Example:
' $INCLUDE "RC4crypt.inc"
' DEFSTR k = "1234567890" ' This is the key
' DEFSTR s = "abcdefghijklmnopqrstuvwxyz"
' DEFSTR t = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
' DIM rc4 AS QRC4
' rc4.Init(k) ' Initialize RC4 object with the key
' s = rc4.Pipe(s) ' Encode stream element s
' t = rc4.Pipe(t) ' Encode stream element t
' rc4.Init(k) ' Initialize RC4 object with the key again
' ShowMessage(rc4.Pipe(s & t)) ' Concatenate and decode
'
' DISCLAIMER: ABSOLUTELY NO WARRANTY IS GIVEN FOR THIS
' COMPONENT! USE THIS TYPE DEFINITION AT YOUR OWN RISK!
'
TYPE QRC4 EXTENDS QOBJECT
PRIVATE:
stateTable(256) AS BYTE
randomIndex AS BYTE
i AS LONG
j AS LONG
k AS LONG
n AS LONG
PUBLIC:
SUB Reset
FOR QRC4.i = 0 TO 255
QRC4.stateTable(QRC4.i) = QRC4.i
NEXT
QRC4.i = 0
QRC4.j = 0
END SUB
SUB Init (key AS STRING)
QRC4.Reset
QRC4.n = LEN(key)
IF 0 < QRC4.n THEN
FOR QRC4.i = 0 TO 255
QRC4.k = (QRC4.i MOD QRC4.n) + 1
QRC4.j = (QRC4.j + QRC4.stateTable(QRC4.i) + ASC(key[QRC4.k])) AND 255
SWAP QRC4.stateTable(QRC4.i), QRC4.stateTable(QRC4.j)
NEXT
QRC4.i = 0
QRC4.j = 0
END IF
END SUB
FUNCTION Pipe (str AS STRING) AS STRING
result = ""
QRC4.n = LEN(str)
FOR QRC4.k = 1 TO QRC4.n
QRC4.i = (QRC4.i + 1) AND 255
QRC4.j = (QRC4.j + QRC4.stateTable(QRC4.i)) AND 255
QRC4.randomIndex = (QRC4.stateTable(QRC4.i) + QRC4.stateTable(QRC4.j)) AND 255
SWAP QRC4.stateTable(QRC4.i), QRC4.stateTable(QRC4.j)
result = result & CHR$(ASC(str[QRC4.k]) XOR QRC4.stateTable(QRC4.randomIndex))
NEXT
END FUNCTION
CONSTRUCTOR
Reset
END CONSTRUCTOR
END TYPE