Lesson 3, Topic 1
In Progress

Cryptography with Python! XOR

digitalscotland September 5, 2021
Lesson Progress
0% Complete

In this video Arian Dolinay who is a professional person for being the finance geek and advises other people for getting wealthy by his videos. 

He has discussed the exclusive or operation commonly known as XOR within python and its use in cryptography and also discusses some of the packages he uses. 

Exclusive or (XOR) Operation

The exclusive or XOR is a bitwise operation. The main information about the bitwise XOR operation is that the result would show (1) only when the input bits would be different and if the inputs are same the result comes out to be (0).

XOR Truth Table 
x1 Input x2 Input XOR Output
0 0 0
0 1 1
1 0 1
1 1 0

Logical Vs Bitwise Operators

There is a difference between bitwise XOR and logical XOR. These both types of operators are included in the IDL.

Bitwise Operators

The bitwise operator monitors the bits that are expressed based on logic that is explained in the operator function. These bits would be compared with each other individually and will be always evaluated by the IDL. The operators include:

  • AND
  • OR
  • NOT
  • XOR

Logical Operators

The logical operator is similar to that of the bitwise operator but it monitors and evaluates the two conditions. The IDL’s logical operators include:

  • &&
  • II

The difference between the logical and bitwise operators is based on two conditions:

  1. he logical operator would result in 1 as true and 0 as false always
  2. A logical operator will perform the short circuit logics such as if the outcome of first condition is required to be known than the second condition would be automatically ignored. 

XOR Operation

Within python the XOR operation is denoted as caret () but according to some other mathematicians and some scientists also use a plus sign with a circle around it in order to indicate the XOR symbol such as (). 

If we look at the XOR truth table it shows that the output would always be (0) if the inputs are same such as if we add 1in both inputs the output would be 0 while if the inputs are added in two different numbers such as 1 and 0 then the output will be (1).

For example if “i is taken in range (2) and “j” is taken in range (2) then the printed result would become (i, j, i j):

for i in range (2)

for j in range (2)

print (i, j, i j)

XOR Involution (Bijection)

In order to explain the bijection the coding can be shown by taking two variables and it is also said that the ordering in XOR does not matter when the XOR is being taken for two variables. The following coding is shown for clear guidance:

num_1 = 22

num_2 = 7

print [(num_1 num_2) = = (num_2 num_1)]

Another cool property for explaining actual bijection could be explained as:

xor_num = num_1 num_2

print (xor_num)

print (xor_num num_1)

print (xor_num num_2)

It could be explained as we would take xor_num as the XOR and the output of this input would be explained as 17 and if the output of xor_num is taken and XOR it by 22 then then 7 would be the output similarly the out of xor_num by 7 would be 22. In order to get the bijection the outputs would be 17, 7 and 22 as shown in figure.

ASCII and XOR

ASCII also known as American Standard Code for Information Interchange and it is a standard for encoding characters in electronic communication.

If we search out the website www.sciencebuddies.org it would show a lot of string characters being shown there including 128 ASCII characters and that’s the way in which the strings can be seen within the computers. The string representation could be done by 0 and there are various symbols as well including the (@) and (?) signs. Actual characters as well including the uppercase and the lower case letters could represent the ASCII. 

In the two columns of representation one would be the decimal value that would somehow be taken as integer value as well. As shown in the following table the value of 0 could be represented in decimal as 048 and it would also map as 0011 0000 as a binary value shown in the following table as an example.

Decimal Octal Hex Binary Value Description
048 060 30 0011 0000 0 zero

In coding language it could be illustrated as:

full_ascii = [char for char in ‘ ‘ . join(chr(i) for i in range(128)]

It could also be represented by different symbols that could not be printed so if the output of such characters in ASCII is requested the error appears as shown in the following coding:

print (full_ascii[0])

Some coding are discussed below that would be explained through dictionary of data and it will show the Unicode values and the binary values. The output of these values will consist of string characters that are printable. The coding is illustrated as follows.  

data = {String : [char for char in string printable]

Unicode values: [ord(char) for char in string.printable]

Binary Values: [bin(ord(char)) for char in string.printable]}

In the above coding the (ord) is known as ordinal value and (bin) is known to be binary. 

Now these values could be taken to work upon and XOR could be applied to the ordinal and binary function. If we take 0 and e as two different values then take out their XOR output the following coding would be done. 

int1, int2 = ord(‘e’), ord(‘0’)

xor_num = int1 int2

xor_num  = xor_num.to_bytes[(xor.nit_length () + 7) // 8, byteorder = ‘big)

Output: 85

If the ascii_char is applied for both the values then the output comes out to be ‘U’. 

int1, int2 = ord(‘e’), ord(‘0’)

xor_num = int1 int2

asci_char = xor_num.to_bytes[(xor.nit_length () + 7) // 8, byteorder = ‘big)

Output: U

XORing Given Binary String Values

Suppose there are two variables of binary function known to be binary1 and binary2 variables. As shown below the first binary variable is for the character ‘A’ and the second variable is for string number ‘1’. 

binary_1 = 01000001

binary_2 = 00110001

The reason for it would be a string and cannot be an integer is that the leading zero cannot be taken as integer and if it would be tried to run the error would be occurred in the output.

Now if both XOR is required to be carried out for both the values written above it would be represented as bit string as bit_str and the coding would be saved with other inputs to carry out output as 00111000. In the same way if the ASCII character is taken out the output comes out to be ‘p’. The following coding would be done:

bit_str = ‘ ‘ .join [(str(int(let1 int(let2)) for let1, let2 in zip(binary1, binary 2)]

bit_str = ‘00111000’

ascii_char =chr(int(bit_str, 2))

asci_char =’p’

Simple XOR Encryption and Decryption

The XOR encryption and decryption could be done in a simple way. It is basically not secure cryptographically while it is a quick demonstration of how to use XOR in order to create super simple encryption and decryption function as it is just a message for the programming so it would be represented as a plain text.

Next a variable would be created that is called a num list and a list comprehension would be used in it. The ord function would be used for the character in message and for illustration. In the following coding it is shown that the each of the alphabets in message have their own numerical values that would be shown in the output to convey the messages. Even the numerical representation of the space is also known to be 32 while coding.

 xor-encrypt(message):

num_list = [ord(char) for char in message]

message = hello world

num_list = [ord(char) for char in message]

num_list = 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33]

Now the XOR would be taken for each of these numbers including any ASCII characters. For this the variable key is used ad the secret package would be applied on it for dot choice. The numbers would be added for the range of 128 as there are a total of 128 ASCII characters. The following coding would be done:

key = secrets.choice(range(128))

key = 42

The encrypt list could also be carried out in the similar ways as follows:

encrypt_list = [num key for num in num_list]

encrypt_list = [120, 117, 124, 124, 127, 48, 103, 127, 98, 124, 116, 49]

return [‘’ .join([num.to_bytes((num.bit_length( ) + 7) / /8, ‘big’) .decode ( ) for num in encrupt_list]), key]

Now let suppose another message is conveyed with xor_encrypt and named it cipher. If we return the cipher it would give the output as the first part as object in the list is the message that was encrypted and the second is the key that we would need to decipher the code. 

If we safe the safer text into variable called ‘ct’ and also safe the key separately from the cipher  and carry out the decryption function it would take two messages  this time as the cipher text and then the key that would be required to decode . It would be known as bit shorter where the number list and also the list comprehension would be used. Now the XOR would be applied to the cipher and the each character in the cipher text by key. 

cipher = xor_encrypt (‘ I love coding!!!!’)

cipher = [‘\xlas?<%6s0<7:=4rrrr; , 83]

ct = cipher [0]

key = vipher [1]

def xor_encrypt (cipher_text. key):

num_list = [ord(char) key for char in cipher text]

return [‘’ .join([num.to_bytes((num.bit_length( ) + 7) / /8, ‘big’) .decode ( ) for num in num_list])

Now if we do xor_encrypt (ct, key) it would give the output as ‘I love coding!!!!’ 

This process is considered as not secure cryptographically as it could be cracked easily with frequency analysis. If the hacker would crack the coding the repeated objects in the output would show them the frequency of some words that would popped up more than others and they can use frequency analysis easily to crack and open it. So it is not secure at all cryptographically, it is shown just as a demonstration to know how cipher works.

Features of XOR in Cryptography

So just to highlight some other features of using XOR in cryptography. The reason of XOR being valuable is because it is bijective and invertible in other words it means that it is easy to conduct the XOR operations on the sequence of bits and also the reverse of operation is easy as well. It is a useful tool due to the above feature for encryption and decryption 

A list of algorithms used in XOR encryption are listed as follows:

  • 3DES
  • Blowfish
  • AES
  • Serpent

XOR can also be used for pseudo random number generation that is also very important in cryptography so the linear feedback shift registers and their various different types that rely on the XOR operation as a process to generate pseudorandom numbers.