2024-04-29

Navigation

Skip Navigation Links

Hash algorithms

Asymmetric Algorithms

Symmetric Cipher Algorithms

Encoding Algorithms

Compression Algorithms

Pseudo Random Number Algorithms

Steganography

Library Wrappers

String Comparison

Others

Syntax highlighting by Prism
PBCrypto.com Mirror

RC4

Algorithm creator(s)

Ron Rivest / RSA Laboratories


PB author(s)

Scott Slater


Description

RC4 is a variable key-size stream cipher with byte-oriented operations. The algorithm is based on the use of a random permutation.


Note

Susceptible to bit-flipping attacks; RC4 has no error detection and changing 1 byte in the ciphertext doesn't affect any other data except that byte


Source

https://forum.powerbasic.com/forum/user-to-user-discussions/source-code/23907-asm-encryption-base64-routines


See also

n/a


Source Code

Download source code file rc4.bas (Right-click -> "Save as ...")

' ---------------------------------------------------------
' RC4 Encrypt/Decrypt Routine: Returns 1 on Error,
'                                      0 for Success
'
'  nLen = Input String Len. NOTE: Buffer Lengths Must Be
'  equal to or greater than this size.  We want To be able
'  to encrypt Ascii Zero's so we can't look for These for
'  the end of the string mark as you normally would with
'  this type of data.
'
' NOTE: If you are calling from PB you are better off using
' the wrapper function below to use BASIC Strings.
' ---------------------------------------------------------
Function EnDeCrypt Alias "EnDeCrypt"(InString As Asciiz, Passwd As Asciiz, _
                   OutString As Asciiz, ByVal nLen As Dword) Export As Long

   Local S   As Asciiz * 256
   Local K   As Asciiz * 256
   Local rtn As Long

   ! push ebx                 ; save ebx
   ! push esi                 ; save esi
   ! push edi                 ; save edi
   ! mov esi, InString        ; Input String Address
   ! and esi, esi             ; null pointer check
   ! jz EnDeCryptDone         ; exit function
   ! mov edi, OutString       ; Output String Address
   ! and edi, edi             ; null pointer check
   ! jz EnDeCryptDone         ; exit function
   ! mov edx, Passwd          ; Password String Address
   ! and edx, edx             ; null pointer check
   ! jz EnDeCryptDone         ; exit function

   ! push esi                 ; save it for temp use
   ! push edi                 ; save it for temp use
   ! push edx                 ; save original pw address
   ! xor eax, eax             ; zero eax
   ! lea esi, S               ; address of S
   ! lea edi, K               ; address of K

   EnDeCryptInitS:
   ! mov [esi+eax], al        ; store char in S
   ! mov bl, [edx]            ; get byte from password
   ! cmp bl, 0                ; see if its a null terminator
   ! je EnDeCryptFixPw        ; if so adjust it
   ! mov [edi+eax], bl        ; store char in K
   ! inc edx                  ; increment pw pointer
   ! inc eax                  ; increment ascii pointer
   ! cmp eax, 256             ; see if we're done
   ! jl EnDeCryptInitS        ; get next character
   ! jmp EnDeCryptCreateTable ; go to next step

   EnDeCryptFixPw:
   ! pop edx                  ; get starting address of pw
   ! push edx                 ; save it again
   ! mov bl, [edx]            ; get first char again
   ! mov [edi+eax], bl        ; store it in K
   ! inc edx                  ; increment pw pointer
   ! inc eax                  ; increment ascii pointer
   ! cmp eax, 256             ; see if we're done
   ! jl EnDeCryptInitS        ; get next character

   EnDeCryptCreateTable:
   ! xor ecx, ecx             ; zero ecx
   ! xor edx, edx             ; zero edx

   EnDeCryptTableLoop:
   ! mov al, [esi+ecx]        ; get S char into al
   ! mov ah, [edi+ecx]        ; get K char into ah
   ! add al, ah               ; add them together
   ! mov ah, dl               ; dl to ah
   ! add al, ah               ; add them together
   ! mov edx, eax             ; save it to edx
   ! and edx, 255             ; filter off high bits
   ! mov bl, [esi+ecx]        ; get S char to bl
   ! mov al, [esi+edx]        ; get K char to al
   ! mov [esi+ecx], al        ; swap the values
   ! mov [esi+edx], bl        ; swap the values
   ! inc ecx                  ; increment counter
   ! cmp ecx, 256             ; see if we're done
   ! jl EnDeCryptTableLoop    ; get next character

   ! pop edx                  ; restore password address
   ! pop edi                  ; restore Output address
   ! pop esi                  ; restore Input address
   ! xor eax, eax             ; zero eax
   ! xor ebx, ebx             ; zero ebx
   ! xor ecx, ecx             ; zero ecx
   ! xor edx, edx             ; zero edx

   EnDeCryptMainLoop:
   ! mov eax, 1234            ; normal exit code checked on exit
   ! cmp edx, nLen            ; See if we've reached the end yet
   ! jge EnDeCryptDone        ; if so we're done
   ! mov al, [esi+edx]        ; get char from input
   ! inc ch                   ; increment ch
   ! and ch, 255              ; range 0-255
   ! push esi                 ; save esi
   ! lea esi, S               ; address of S
   ! push eax                 ; save eax
   ! push ebx                 ; save ebx
   ! xor eax, eax             ; zero eax
   ! mov ah, ch               ; get ch
   ! shr eax, 8               ; move to al
   ! mov ebx, eax             ; copy it to ebx
   ! mov al, [esi+ebx]        ; get byte
   ! add cl, al               ; add them up
   ! and cl, 255              ; range 0-255
   ! pop ebx                  ; restore ebx
   ! xor eax, eax             ; zero eax
   ! mov al, cl               ; cl to al
   ! mov bl, [esi+eax]        ; swap table bytes
   ! mov al, ch               ; ch to al
   ! mov bh, [esi+eax]        ; swap table bytes
   ! mov [esi+eax], bl        ; swap table bytes
   ! mov al, cl               ; cl to al
   ! mov [esi+eax], bh        ; swap table bytes
   ! pop eax                  ; restore eax
   ! add bl, bh               ; add the bytes together
   ! and ebx, 255             ; range 0-255
   ! mov bh, [esi+ebx]        ; get xor Var
   ! shr ebx, 8               ; move it to bl
   ! xor al, bl               ; xor the value
   ! mov [edi+edx], al        ; store the encrypted char
   ! pop esi                  ; restore input address
   ! inc edx                  ; increment character counter
   ! jmp EnDeCryptMainLoop    ; get next character

   EnDeCryptDone:
   ! cmp eax, 1234            ; see if our normal exit code
   ! je EnDeCryptExitLab      ; got us here, if so exit
   ! mov eax, 1               ; if not return error code
   ! mov rtn, eax             ; to caller

   EnDeCryptExitLab:
   ! pop edi                  ; restore edi
   ! pop esi                  ; restore esi
   ! pop ebx                  ; restore ebx

   Function = rtn

End Function


' ---------------------------------------------------------
' Wrapper Function that Calls EnDeCrypt and handles
' Conversions of Input And output to regular basic
' style strings instead of Asciiz.
'
'                     Returns:  String on Success
'                               Empty String on Error
' ---------------------------------------------------------
Function CryptStr Alias "CryptStr" (StringIn As String, Pw As String) _
                  Export As String

   Local pBuff As String
   Local oBuff As String

   pBuff = Pw & Chr$(0)              ' pad pw with a chr 0
   oBuff  = Space$(Len(StringIn))    ' set outbuff len

   ! push ebx                ; save ebx
   ! mov eax, StringIn       ; Get Input Buffer Handle to eax
   ! mov eax, [eax]          ; get address of data
   ! and eax, eax            ; null pointer check
   ! jz CryptStrDone         ; leave the function

   ! lea ebx, pBuff          ; pBuff's handle to ebx
   ! mov ebx, [ebx]          ; pBuff's address to ebx
   ! lea ecx, oBuff          ; oBuff's handle to ecx
   ! mov ecx, [ecx]          ; oBuff's address to ecx
   ! mov edx, [eax-4]        ; StringIn's Length to edx

   ! push edx                ; last parameter for call
   ! push ecx                ; 3rd parameter for call
   ! push ebx                ; 2nd parameter for call
   ! push eax                ; 1st paramter for call
   ! call EnDeCrypt          ; call the master function

   ! cmp eax, 0              ; make sure there were no errors
   ! jne CryptStrDone        ; if so then exit

   Function = oBuff          ' set output

   CryptStrDone:
   ! pop ebx                 ; restore ebx

End Function

Mirror provided by Knuth Konrad