I am translating simple ciphers into quantum implementation in order to create oracle for Grover algorithm. I have started the task with a light weight SPECK cipher (got both classical and quantum implementation). Now Speck cipher uses Addition modulo 2 and its quantum implementation is hard to grasp for me at least at this level. Can anyone suggest the starting point of classical code translation into quantum or help mapping below implementations, then it will be really helpful.
SPECK classical Implementation Encrypt Function is here:
def encrypt(self, plaintext):
try:
b = (plaintext >> self.word_size) & self.mod_mask
a = plaintext & self.mod_mask
except TypeError:
print('Invalid plaintext!')
print('Please provide plaintext as int')
raise
if self.mode == 'ECB':
b, a = self.encrypt_function(b, a)
The encrypt_function is
def encrypt_function(self, upper_word, lower_word):
x = upper_word
y = lower_word
# Run Encryption Steps For Appropriate Number of Rounds
for k in self.key_schedule:
rs_x = ((x << (self.word_size - self.alpha_shift)) + (x >> self.alpha_shift)) & self.mod_mask
add_sxy = (rs_x + y) & self.mod_mask
x = k ^ add_sxy
ls_y = ((y >> (self.word_size - self.beta_shift)) + (y << self.beta_shift)) & self.mod_mask
y = x ^ ls_y
return x,y
Now the quantum implementation of Encrypt function provided is:
def Encryption(eng, x, y, k0, k1, c0, c1):
constant = 0
for i in range(3):
# Round function(1/2)
S_minus_a(eng, x, 2) #Right Rotation
improved_adder(eng, y, x, c0, 3)
# Key expansion(1/2)
S_minus_a(eng, k1, 2)
improved_adder(eng, k0, k1, c1, 3)
# Round function(2/2)
CNOT4(eng, k0, x)
S_plus_b(eng, y, 1) # Left Rotation
CNOT4(eng, x, y)
# Key expansion(2/2)
Constant_XOR(eng, k1, constant)
constant = constant + 1
S_plus_b(eng, k0, 1)
CNOT4(eng, k1, k0)
# Last Round
# Round function(1/2)
S_minus_a(eng, x, 2)
improved_adder(eng, y, x, c0, 3)
# Round function(2/2)
CNOT4(eng, k0, x)
S_plus_b(eng, y, 1)
CNOT4(eng, x, y)
and the function I am not able to corelate with addition modulo 2 is:
def improved_adder(eng, a, b, c, n): # n = n-1
for i in range(n - 1):
CNOT | (a[i + 1], b[i + 1])
CNOT | (a[1], c)
Toffoli | (a[0], b[0], c)
CNOT | (a[2], a[1])
Toffoli | (c, b[1], a[1])
CNOT | (a[3], a[2])
for i in range(n - 4): #i=2 to n-3$
Toffoli | (a[i + 1], b[i + 2], a[i + 2])
CNOT | (a[i + 4], a[i + 3])
Toffoli | (a[n - 3], b[n - 2], a[n - 2])
CNOT | (a[n - 1], b[n])
CNOT | (a[n], b[n])
Toffoli | (a[n - 2], b[n - 1], b[n])
for i in range(n - 2):
X | b[i + 1]
CNOT | (c, b[1])
for i in range(n - 2):
CNOT | (a[i + 1], b[i + 2])
Toffoli | (a[n - 3], b[n - 2], a[n - 2])
for i in range(n - 4):
Toffoli | (a[n - 4 - i], b[n - 3 - i], a[n - 3 - i])
CNOT | (a[n - 1 - i], a[n - 2 - i])
X | (b[n - 2 - i])
Toffoli | (c, b[1], a[1])
CNOT | (a[3], a[2])
X | b[2]
Toffoli | (a[0], b[0], c)
CNOT | (a[2], a[1])
X | b[1]
CNOT | (a[1], c)
for i in range(n):
CNOT | (a[i], b[i])
def S_minus_a(eng, x, n): # R-rotation
for j in range(n):
for i in range(3):
Swap | (x[i], x[i+1])
def S_plus_b(eng, y, n): # L-rotation
for j in range(n):
for i in range(3):
Swap | (y[3-i], y[2-i])
def CNOT4(eng, a, b):
for i in range(4):
CNOT | (a[i], b[i])