1

I'm fairly new to programming in python and have been tasked with creating a RC4 cipher in python. This implementation utilizes numpy. If someone could help me resolve this error in the cipher code it'd be greatly appreciated.

RC4 Program

def KSA(key):
    key_length = len(key)
    S = list(range(256))
    j = 0
    for i in range(256):
        j = (j + S[i] + key[i % key_length]) % 256
        S[i], S[j] = S[j], S[i] #swap
    return S

def PRGA (S, n) :
    i = 0
    j = 0
    key =[]

    while n>0:
        n = n-1
        i = (i + 1) % 256
        j = (j + S[i]) % 256
        S[i], S[j] = S[j], S[i]
        K = S[(S[i]) + S[j] % 256]
        key.append(K)
    return key


key = 'KAREEM'
plaintext = 'Mission Accomplished'

def preparing_key_array(s):
    return [ord(c) for c in s]

key = preparing_key_array(key)

import numpy as np
S = KSA(key)

keystream = np.array(PRGA(S, len(plaintext)))
print(keystream)

paintext = np.array([ord(i) for i in plaintext])

cipher = keystream ^ plaintext #xor two numpy arrays

print ( cipher.astype(np.uint8).data.hex()) #print cipher codes
print ([chr(c) for c in cipher]) #print unicode

Output

================ RESTART: C:\Users\Admin\Desktop\Project\RC4.py ================
Traceback (most recent call last):
  File "C:\Users\Admin\Desktop\Project\RC4.py", line 36, in <module>
    keystream = np.array(PRGA(S, len(plaintext)))
  File "C:\Users\Admin\Desktop\Project\RC4.py", line 20, in PRGA
    K = S[(S[i]) + S[j] % 256]
IndexError: list index out of range
Dror Av.
  • 1,184
  • 5
  • 14
  • Should it be `S[ ( (S[i]) + S[j] ) % 256]` or `S[ (S[i]) + ( S[j] % 256 ) ]`? (Note the parentheses locations) – GPhilo May 18 '20 at 13:44
  • I received the same error after altering the parenthesis @GPhilo – novellnovell May 18 '20 at 13:48
  • My comment did not ask whether it solves the problem (as it doesn't), but what is the intended semantic of your index. Assuming `S` is 256 bytes, I guess what you tried to do was get the modulo-256 of the sum of `S[i]` and `S[j]`. Your code, however, is badly parenthesized, so you're doing the equivalent of my second option above, which likely gives you a number >= 256 and thus the indexerror. – GPhilo May 18 '20 at 13:51
  • 1
    @GPhilo Yes it was badly parenthesized. I corrected the problem by altering the code to ```S[ (S[i] + S[j]) % 256 ] ``` – novellnovell May 18 '20 at 13:55
  • Now having the error ```================ RESTART: C:\Users\Admin\Desktop\Project\RC4.py ================ [226 180 10 72 56 102 9 237 17 204 224 75 209 129 240 90 41 184 35 136] Traceback (most recent call last): File "C:\Users\Admin\Desktop\Project\RC4.py", line 41, in cipher = keystream ^ plaintext TypeError: ufunc 'bitwise_xor' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''``` – novellnovell May 18 '20 at 13:56
  • That's a different error, google the error code (it's a fairly common numpy-related error, there's several resources explaining the why and how to fx it) – GPhilo May 18 '20 at 13:58
  • Ok, attempting to resolve the error @GPhilo – novellnovell May 18 '20 at 14:07
  • I could seriously use some help on this. I imagine I need to convert keystream and plaintext to supported input types but whatever I try based on the fixes that I'm finding is not working. – novellnovell May 18 '20 at 14:48
  • What are the types of `keystream` and `plaintext`? They must have the same dtype for numpy to allow bitwise-xor – GPhilo May 18 '20 at 14:50
  • 1
    Oh cool I figured it out by converting keystream and plaintext. ```cipher = keystream.astype(numpy.uint8) ^ plaintext.astype(numpy.uint8)``` – novellnovell May 18 '20 at 15:20

1 Answers1

0

The first error in your code was in line K = S[(S[i]) + S[j] % 256] in PRGA function.

But I see from your later comment that you corrected it.

The second error is a typo: you wrote paintext instead of plaintext.

So later you attempt to count XOR on a string as one of arguments (still containing 'Mission Accomplished') and the second argument is a Numpy array.

Valdi_Bo
  • 30,023
  • 4
  • 23
  • 41