Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

RC4 Encryption Class for 9.0/5.0

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • RC4 Encryption Class for 9.0/5.0

    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
    Attached Files
    Last edited by Greg Turgeon; 13 Aug 2008, 12:21 AM.

  • #2
    Code:
    '=====================================================================
    '                         RC4OBJ Test Bed code
    '             Compiles with either PBWIN 9.0 or PBCC 5.0
    '=====================================================================
    #COMPILE EXE
    #DIM ALL
    #INCLUDE "RC4UTIL.BAS"
    #INCLUDE "RC4OBJ.INC"
    
    '====================
    FUNCTION PBMain&()
    REGISTER i AS LONG
    LOCAL userkey$, plaintext$, cipher$, shouldbe$, t$
    LOCAL RC4 as RC4Interface, ctx AS ENCRYPTION_CONTEXT  'defined in RC4OBJ.INC
    
    EnterCC
    
    '-- Standard RC4 test vectors
    userkey$ = chr$(&h61, &h8a, &h63, &hd2, &hfb)
    plaintext= chr$(&hdc, &hee, &h4c, &hf9, &h2c)
    cipher   = nul$(len(plaintext))
    shouldbe = chr$(&hf1, &h38, &h29, &hc9, &hde)
    t = t + "Key length (bits):" + str$(len(userkey)*8) + eol
    t = t + "plaintext:    " + Hex2Show$(plaintext) + eol
    gosub DoEncrypt
    t = t + "cipher:   " + Hex2Show$(cipher) + eol
    t = t + "shouldbe: " + Hex2Show$(shouldbe) + eol
    '-- Be sure to reload key$
    userkey$ = chr$(&h61, &h8a, &h63, &hd2, &hfb)
    gosub DoDecrypt
    t = t + "plaintext:    " + Hex2Show$(plaintext) + eol + eol
    
    userkey$ = chr$(&h01, &h23, &h45, &h67, &h89, &hab, &hcd, &hef)
    plaintext= chr$(&h01, &h23, &h45, &h67, &h89, &hab, &hcd, &hef)
    cipher   = nul$(len(plaintext))
    shouldbe = chr$(&h75, &hb7, &h87, &h80, &h99, &he0, &hc5, &h96)
    t = t + "Key length (bits):" + str$(len(userkey)*8) + eol
    t = t + "plaintext:    " + Hex2Show$(plaintext) + eol
    gosub DoEncrypt
    t = t + "cipher:   " + Hex2Show$(cipher) + eol
    t = t + "shouldbe: " + Hex2Show$(shouldbe) + eol
    '-- Be sure to reload key$
    userkey$ = chr$(&h01, &h23, &h45, &h67, &h89, &hab, &hcd, &hef)
    gosub DoDecrypt
    t = t + "plaintext:    " + Hex2Show$(plaintext) + eol + eol
    
    userkey$ = chr$(&h01, &h23, &h45, &h67, &h89, &hab, &hcd, &hef)
    plaintext= string$(512,1)
    cipher   = nul$(len(plaintext))
    shouldbe = peek$(codeptr(OneBytesCipherText), len(plaintext))
    t = t + "Key length (bits):" + str$(len(userkey)*8) + eol
    t = t + "plaintext = string$(512,1)" + eol
    gosub DoEncrypt
    if cipher <> shouldbe then
       t = t + "cipher <> shouldbe"
       '-- Unrem to display mismatch
       'say(str$(len(cipher)) + " " + str$(len(shouldbe)))
       'for i = 1 to len(cipher)
       '   if mid$(cipher,i,1) <> mid$(shouldbe,i,1) then
       '      say(str$(i) + " " + mid$(cipher,i,1) + " " + mid$(shouldbe,i,1))
       '   end if
       'next i
    else
       t = t + "cipher output correct" + eol + eol
    end if
    
    '-- Additional test vectors
    userkey$ = "Key"
    plaintext= "Plaintext"
    cipher   = nul$(len(plaintext))
    shouldbe = chr$(&hbb, &hf3, &h16, &he8, &hd9, &h40, &haf, &h0a, &hd3)
    t = t + "Key length (bits):" + str$(len(userkey)*8) + eol
    t = t + "plaintext:    " + Hex2Show(plaintext) + eol
    gosub DoEncrypt
    t = t + "cipher:   " + Hex2Show$(cipher) + eol
    t = t + "shouldbe: " + Hex2Show(shouldbe) + eol
    '-- Be sure to reload key$
    userkey$ = "Key"
    gosub DoDecrypt
    t = t + "plaintext:    " + Hex2Show(plaintext) + eol + eol
    
    userkey$ = "Secret"
    plaintext= "Attack at dawn"
    cipher   = nul$(len(plaintext))
    shouldbe = chr$(&h45, &ha0, &h1f, &h64, &h5f, &hc3, &h5b, _
                    &h38, &h35, &h52, &h54, &h4b, &h9b, &hf5)
    t = t + "Key length (bits):" + str$(len(userkey)*8) + eol
    t = t + "plaintext:    " + Hex2Show(plaintext) + eol
    gosub DoEncrypt
    t = t + "cipher:   " + Hex2Show$(cipher) + eol
    t = t + "shouldbe: " + Hex2Show(shouldbe) + eol
    '-- Be sure to reload key$
    userkey$ = "Secret"
    gosub DoDecrypt
    t = t + "plaintext:    " + Hex2Show(plaintext) + eol + eol
    
    say(t)
    ExitMain:
    ExitCC
    EXIT FUNCTION
    
    '============
    DoEncrypt:
    RC4 = CLASS "RC4Class"
    
    ctx.UserKey       = strptr(userkey)
    ctx.UserKeyLength = len(userkey)
    ctx.InBlock       = strptr(plaintext)
    ctx.OutBlock      = strptr(cipher)
    ctx.BlockLength   = len(plaintext)
    RC4.Process(ctx)
    
    RC4 = nothing
    RETURN
    
    '============
    DoDecrypt:
    RC4 = CLASS "RC4Class"
    
    ctx.UserKey       = strptr(userkey)
    ctx.UserKeyLength = len(userkey)
    ctx.InBlock       = strptr(cipher)
    ctx.OutBlock      = strptr(plaintext)
    ctx.BlockLength   = len(plaintext)
    RC4.Process(ctx)
    
    RC4 = nothing
    RETURN
    
    OneBytesCipherText:
    ! DB &h75,&h95,&hc3,&he6,&h11,&h4a,&h09,&h78,&h0c,&h4a,&hd4
    ! DB &h52,&h33,&h8e,&h1f,&hfd,&h9a,&h1b,&he9,&h49,&h8f
    ! DB &h81,&h3d,&h76,&h53,&h34,&h49,&hb6,&h77,&h8d,&hca
    ! DB &hd8,&hc7,&h8a,&h8d,&h2b,&ha9,&hac,&h66,&h08,&h5d
    ! DB &h0e,&h53,&hd5,&h9c,&h26,&hc2,&hd1,&hc4,&h90,&hc1
    ! DB &heb,&hbe,&h0c,&he6,&h6d,&h1b,&h6b,&h1b,&h13,&hb6
    ! DB &hb9,&h19,&hb8,&h47,&hc2,&h5a,&h91,&h44,&h7a,&h95
    ! DB &he7,&h5e,&h4e,&hf1,&h67,&h79,&hcd,&he8,&hbf,&h0a
    ! DB &h95,&h85,&h0e,&h32,&haf,&h96,&h89,&h44,&h4f,&hd3
    ! DB &h77,&h10,&h8f,&h98,&hfd,&hcb,&hd4,&he7,&h26,&h56
    ! DB &h75,&h00,&h99,&h0b,&hcc,&h7e,&h0c,&ha3,&hc4,&haa
    ! DB &ha3,&h04,&ha3,&h87,&hd2,&h0f,&h3b,&h8f,&hbb,&hcd
    ! DB &h42,&ha1,&hbd,&h31,&h1d,&h7a,&h43,&h03,&hdd,&ha5
    ! DB &hab,&h07,&h88,&h96,&hae,&h80,&hc1,&h8b,&h0a,&hf6
    ! DB &h6d,&hff,&h31,&h96,&h16,&heb,&h78,&h4e,&h49,&h5a
    ! DB &hd2,&hce,&h90,&hd7,&hf7,&h72,&ha8,&h17,&h47,&hb6
    ! DB &h5f,&h62,&h09,&h3b,&h1e,&h0d,&hb9,&he5,&hba,&h53
    ! DB &h2f,&haf,&hec,&h47,&h50,&h83,&h23,&he6,&h71,&h32
    ! DB &h7d,&hf9,&h44,&h44,&h32,&hcb,&h73,&h67,&hce,&hc8
    ! DB &h2f,&h5d,&h44,&hc0,&hd0,&h0b,&h67,&hd6,&h50,&ha0
    ! DB &h75,&hcd,&h4b,&h70,&hde,&hdd,&h77,&heb,&h9b,&h10
    ! DB &h23,&h1b,&h6b,&h5b,&h74,&h13,&h47,&h39,&h6d,&h62
    ! DB &h89,&h74,&h21,&hd4,&h3d,&hf9,&hb4,&h2e,&h44,&h6e
    ! DB &h35,&h8e,&h9c,&h11,&ha9,&hb2,&h18,&h4e,&hcb,&hef
    ! DB &h0c,&hd8,&he7,&ha8,&h77,&hef,&h96,&h8f,&h13,&h90
    ! DB &hec,&h9b,&h3d,&h35,&ha5,&h58,&h5c,&hb0,&h09,&h29
    ! DB &h0e,&h2f,&hcd,&he7,&hb5,&hec,&h66,&hd9,&h08,&h4b
    ! DB &he4,&h40,&h55,&ha6,&h19,&hd9,&hdd,&h7f,&hc3,&h16
    ! DB &h6f,&h94,&h87,&hf7,&hcb,&h27,&h29,&h12,&h42,&h64
    ! DB &h45,&h99,&h85,&h14,&hc1,&h5d,&h53,&ha1,&h8c,&h86
    ! DB &h4c,&he3,&ha2,&hb7,&h55,&h57,&h93,&h98,&h81,&h26
    ! DB &h52,&h0e,&hac,&hf2,&he3,&h06,&h6e,&h23,&h0c,&h91
    ! DB &hbe,&he4,&hdd,&h53,&h04,&hf5,&hfd,&h04,&h05,&hb3
    ! DB &h5b,&hd9,&h9c,&h73,&h13,&h5d,&h3d,&h9b,&hc3,&h35
    ! DB &hee,&h04,&h9e,&hf6,&h9b,&h38,&h67,&hbf,&h2d,&h7b
    ! DB &hd1,&hea,&ha5,&h95,&hd8,&hbf,&hc0,&h06,&h6f,&hf8
    ! DB &hd3,&h15,&h09,&heb,&h0c,&h6c,&haa,&h00,&h6c,&h80
    ! DB &h7a,&h62,&h3e,&hf8,&h4c,&h3d,&h33,&hc1,&h95,&hd2
    ! DB &h3e,&he3,&h20,&hc4,&h0d,&he0,&h55,&h81,&h57,&hc8
    ! DB &h22,&hd4,&hb8,&hc5,&h69,&hd8,&h49,&hae,&hd5,&h9d
    ! DB &h4e,&h0f,&hd7,&hf3,&h79,&h58,&h6b,&h4b,&h7f,&hf6
    ! DB &h84,&hed,&h6a,&h18,&h9f,&h74,&h86,&hd4,&h9b,&h9c
    ! DB &h4b,&had,&h9b,&ha2,&h4b,&h96,&hab,&hf9,&h24,&h37
    ! DB &h2c,&h8a,&h8f,&hff,&hb1,&h0d,&h55,&h35,&h49,&h00
    ! DB &ha7,&h7a,&h3d,&hb5,&hf2,&h05,&he1,&hb9,&h9f,&hcd
    ! DB &h86,&h60,&h86,&h3a,&h15,&h9a,&hd4,&hab,&he4,&h0f
    ! DB &ha4,&h89,&h34,&h16,&h3d,&hdd,&he5,&h42,&ha6,&h58
    ! DB &h55,&h40,&hfd,&h68,&h3c,&hbf,&hd8,&hc0,&h0f,&h12
    ! DB &h12,&h9a,&h28,&h4d,&hea,&hcc,&h4c,&hde,&hfe,&h58
    ! DB &hbe,&h71,&h37,&h54,&h1c,&h04,&h71,&h26,&hc8,&hd4
    ! DB &h9e,&h27,&h55,&hab,&h18,&h1a,&hb7,&he9,&h40,&hb0,&hc0
    END FUNCTION
    '-- end RC4OBJ.BAS

    Comment


    • #3
      Code:
      '-- RC4UTIL.INC --
      
      #IF NOT %DEF(%WINAPI)
         %USEMACROS = 1
         #INCLUDE "WIN32API.INC"
      #ENDIF
      
      DECLARE FUNCTION Hex2Show$(Buffer$)
      
      #IF %def(%pb_win32)
         MACRO wait
         END MACRO
         MACRO eol=$CR
         MACRO say(t)
            MessageBox 0&, BYCOPY (t), " ", %MB_OK OR %MB_TASKMODAL
         END MACRO
      #ELSEIF %def(%pb_cc32)
         MACRO wait=waitkey$
         MACRO eol=$CRLF
         MACRO say(t)=stdout t
      #ENDIF
      
      '--------------------
      MACRO EnterCC
      #IF %def(%pb_cc32)
      LOCAL launched&
      if (cursory = 1) and (cursorx = 1) then launched = -1
      #ENDIF
      END MACRO
      
      '--------------------
      MACRO ExitCC
      #IF %def(%pb_cc32)
      if launched& then
         input flush
         stdout "Press any key to end"
         waitkey$
      end if
      #ENDIF
      END MACRO
      
      '====================
      FUNCTION Hex2Show$(Buffer$)
      LOCAL t$, i&, b AS BYTE PTR
      b = strptr(Buffer$)
      for i = 0 to len(Buffer$)-1
         t = t + hex$(@b[i],2) + " "
      next i
      function = t
      END FUNCTION
      '-- end RC4UTIL.BAS

      Comment

      Working...
      X