Having Fun With Ciphers: Bitwise Rotations and the Rotate Cipher

I love cryptography — and which is the art of scrambling and unscrambling. Sometimes you just need the method of the scrambling to…

Photo by Nick Fewings on Unsplash

Having Fun With Ciphers: Bitwise Rotations and the Rotate Cipher

I love cryptography — and which is the art of scrambling and unscrambling. Sometimes we just need the method of scrambling to unscramble, and sometimes we need to add a secret key to make the process work. To hide a message, we might just simply hide it by encoding it in a certain way, and the just keep the method of encoding secret.

Two of the most basic operations that we have in cryptography are rotate and EX-OR (Exclusive-OR), and the great thing about these two operators is that when we apply them, we can easily reverse them without losing any information. It should be noted that the rotate operation is not the bit shift operation, as a bit shift will lose bits as they fall off the start or end of the byte value. In this case, we will look at a rotate right and rotate left bitwise operation.

The Rotate Cipher

Ciphers are typically used in love and war. While ciphers have typically been replaced by encryption, they are excellent ways to learn how we can encode messages with different methods of processing. Let me start with a puzzle:

A cipher takes each of the characters in a message, and 
rotates them one bit position to the right. If the encoded hex
pattern is 2ab2b93ab437b3, what is the message?

With the Rotate Cipher, we take the bits in each of the letters and rotate them by a number of positions to the left or the right. It should be noted that this is done on a byte wise approach, where we take each character at a time, and then rotate the bits by a given number of positions. As we will possibly generate non-printing ASCII characters, we will represent the cipher as a hexadecimal value. Now let’s create some Python code that does this rotating (either left or right) [here]:

import sys
n=1
message="Testing"

if (len(sys.argv)>1):
n=int(sys.argv[1])
if (len(sys.argv)>2):
message=str(sys.argv[2])

def rotater(text, n=1):
r = ""
for c in text:
b =bin(ord(c))[2:].zfill(8)
r += hex(int(b[-n:] + b[:-n],2))[2:]
return r

def rotatel(text, n=1):
r = ""
for c in text:
b =bin(ord(c))[2:].zfill(8)
r += hex(int(b[n:] + b[:n],2))[2:]
return r
print (f"Message:\t[{message}]")
print(f"\nRotate right by {n}")
rtn=rotater(message,n)
print(f"\nEncoding: {rtn}")
print(f"\nRotate left by {n}")
rtn=rotatel(message,n)
print(f"\nEncoding: {rtn}")

For “Testing”, we have hexadecimal representation of 0x54, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67. These give:

Char Hex  Binary
------------------

T 0x54 01010100
e 0x65 01100101
s 0x73 01110011
t 0x74 01110100
i 0x69 01101001
n 0x6e 01101110
g 0x67 01100111

If we do a right rotate by one position, we get:

00101010 -> 0x2a
10110010 -> 0xb2
10111001 -> 0xb9
00111010 -> 0x3a
10110100 -> 0xb4
00110111 -> 0x37
10110011 -> 0xb3

Notice that the bit that come off the left-hand side, is added onto the right-hand side. This is a rotate operation, and there is no operator for this in Python. The only one we have is the shift left (<<) or shift right (>>) operation. For a right rotation of two, we get:

00010101 -> 0x15
01011001 -> 0x59
11011100 -> 0xdc
00011101 -> 0x1d
01011010 -> 0x5a
10011011 -> 0x9b
11011001 -> 0xd9

If we rotate left by one position, we get:

Char Hex  Binary
------------------
10101000 -> 0xa8
11001010 -> 0xca
11100110 -> 0xe6
11101000 -> 0xe8
11010010 -> 0xd2
11011100 -> 0xdc
11001110 -> 0xce

A sample run for one-bit position shift gives [here]:

Message:	[Testing]
Rotate right by 1
Encoding: 2ab2b93ab437b3
Rotate left by 1
Encoding: a8cae6e8d2dcce

Conclusions

Want a few more ciphers, try here:

https://asecuritysite.com/cipher

or go and take a cipher challenge:

https://asecuritysite.com/challenge