Search code examples
pythonxor

python xor renders only zero?


im trying to implement a repeating key xor encryption scheme in python.

I have this implementation:

from binascii import hexlify


def repeat_to_length(string_to_expand, length):
    return (string_to_expand * (int(length/len(string_to_expand))+1))[:length]

def Enc(plaintext,k):
    ciphertext = b''
    s1 = str.encode(plaintext)
    key =  str.encode(repeat_to_length(k, len(s1)))

    i = 0

    for s11,k1 in zip(s1,key):
        tmp =  bytes(s11^k1)
        ciphertext += tmp 

    return ciphertext

key = "ICE"

m1 = "Burning 'em, if you ain't quick and nimble"
m2 = "I go crazy when I hear a cymbal"

c = Enc(m1,key)

print(str(hexlify(c), "utf-8"))

I use the function repeat_to_length to extend the key length to the same length as the plaintext, just for ease of use. I then convert the two strings to bytes objects such that I am able to do xor on them.

The strange thing here is that when I run my code here, this is the output I get:

b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

What is happening? why is the xor only rendering zero?


Solution

  • As stated in the comments, bytes(int) creates a zero-filled bytestring int elements long. Try changing this line

    tmp = bytes(s11^k1)
    

    to this:

    tmp = bytes([s11^k1])
    

    The documentation for bytes describes the different ways it works depending on the arguments passed:

    >>> help(bytes)
    Help on class bytes in module builtins:
    
    class bytes(object)
     |  bytes(iterable_of_ints) -> bytes
     |  bytes(string, encoding[, errors]) -> bytes
     |  bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer
     |  bytes(int) -> bytes object of size given by the parameter initialized with null bytes
     |  bytes() -> empty bytes object
     |  
     |  Construct an immutable array of bytes from:
     |    - an iterable yielding integers in range(256)
     |    - a text string encoded using the specified encoding
     |    - any object implementing the buffer API.
     |    - an integer
    ...