'===========================================================================
' Subject: RC4 ENCRYPTION ALGORITHM           Date: 08-13-98 (08:48)       
'  Author: Scott Spiker                       Code: QB, QBasic, PDS        
'  Origin: scott_spiker@hypercom.com        Packet: ALGOR.ABC
'===========================================================================
DEFINT A-Z

'This is a set of routines to support encryption and decryption using the
'RC4 algorithm. To use it, the key is passed to the initialization routine,
'RC4INIT before doing either encryption or decryption. The key may be up to
'255 bytes long, longer keys are simpy ignored pass the 255th byte.
'This algorithm is easy, fast and secure


DECLARE FUNCTION Rc4$ (s$)              'String encryption routine
DECLARE FUNCTION Rc4K% (InitFlag%)      'Get next cipher byte
DECLARE SUB Rc4Init (Key$)              'Initialize the key

DIM SHARED s(0 TO 255)                  'S-Box table
DIM SHARED k(0 TO 255)                  'Key schedule

Key$ = "TEST KEY"                       'Set a key, of course this should be
                                        '  changed to get the key (password)
                                        '  from the user

Rc4Init (Key$)                          'Initialize the key schedule

Clear$ = "1234567890"                   'Set a sample clear text string
Encrypted$ = Rc4$(Clear$)               'Encrypt the string

Rc4Init (Key$)                          're-Initialize the key
Clear$ = Rc4$(Encrypted$)               'Decrypt the string

PRINT Clear$

FUNCTION Rc4$ (s$)
     'This routine encrypts the string S$.

     StringLen = LEN(s$)
     FOR x = 1 TO StringLen
          c = ASC(MID$(s$, x, 1))
          k = Rc4K(0)
          r$ = r$ + CHR$(c XOR k)
     NEXT x
     Rc4$ = r$
END FUNCTION

SUB Rc4Init (Key$)
     KeyLen = LEN(Key$)

     FOR i = 0 TO 255
          s(i) = i
          KeyPtr = KeyPtr + 1
          k(i) = ASC(MID$(Key$, KeyPtr, 1))
          IF KeyPtr = KeyLen THEN
               KeyPtr = 0
          END IF
     NEXT i

     FOR i = 0 TO 255
          j = (j + s(i) + k(i)) MOD 256
          SWAP s(i), s(j)
     NEXT i
     i = Rc4K(1)                                  'Reset key schedule
END SUB

FUNCTION Rc4K% (InitFlag%)
     STATIC i, j

     IF InitFlag THEN                   'Reset key schedule
          i = 0
          j = 0
     ELSE
          i = (i + 1) MOD 256
          j = (j + s(i)) MOD 256
          SWAP s(i), s(j)
          t = (s(i) + s(j)) MOD 256
          Rc4K = s(t)
     END IF
END FUNCTION
