Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
shiwwamm authored May 30, 2024
1 parent b6bf141 commit f86c01f
Show file tree
Hide file tree
Showing 2 changed files with 742 additions and 0 deletions.
247 changes: 247 additions & 0 deletions zuc_128.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
# -*- coding: utf-8 -*-
"""ZUC 128.ipynb
Automatically generated by Colab.
Original file is located at
https://colab.research.google.com/drive/1aqenxoY0MepBTZ3pZSYgSycAK6s0vjx9
"""

import random

#constants
constants_list = ['100010011010111', '010011010111100', '110001001101011', '001001101011110', '101011110001001', '011010111100010', '111000100110101', '000100110101111', '100110101111000', '010111100010011', '110101111000100', '001101011110001', '101111000100110', '011110001001101', '111100010011010', '100011110101100']

#defining cell
s_list = []
x_list = ['0','0','0','0']
r_list = ['0', '0', '0']

S0 = {
"0": {"0": '3e', "1": '72', "2": '5b', "3": '47', "4": 'ca', "5": 'e0', "6": '00', "7": '33', "8": '04', "9": 'd1', "a": '54', "b": '98', "c": '09', "d": 'b9', "e": '6d', "f": 'cb'},
"1": {"0": '7b', "1": '1b', "2": 'f9', "3": '32', "4": 'af', "5": '9d', "6": '6a', "7": 'a5', "8": 'b8', "9": '2d', "a": 'fc', "b": '1d', "c": '08', "d": '53', "e": '03', "f": '90'},
"2": {"0": '4d', "1": '4e', "2": '84', "3": '99', "4": 'e4', "5": 'ce', "6": 'd9', "7": '91', "8": 'dd', "9": 'b6', "a": '85', "b": '48', "c": '8b', "d": '29', "e": '6e', "f": 'ac'},
"3": {"0": 'cd', "1": 'c1', "2": 'f8', "3": '1e', "4": '73', "5": '43', "6": '69', "7": 'c6', "8": 'b5', "9": 'bd', "a": 'fd', "b": '39', "c": '63', "d": '20', "e": 'd4', "f": '38'},
"4": {"0": '76', "1": '7d', "2": 'b2', "3": 'a7', "4": 'cf', "5": 'ed', "6": '57', "7": 'c5', "8": 'f3', "9": '2c', "a": 'bb', "b": '14', "c": '21', "d": '06', "e": '55', "f": '9b'},
"5": {"0": 'e3', "1": 'ef', "2": '5e', "3": '31', "4": '4f', "5": '7f', "6": '5a', "7": 'a4', "8": '0d', "9": '82', "a": '51', "b": '49', "c": '5f', "d": 'ba', "e": '58', "f": '1c'},
"6": {"0": '4a', "1": '16', "2": 'd5', "3": '17', "4": 'a8', "5": '92', "6": '24', "7": '1f', "8": '8c', "9": 'ff', "a": 'd8', "b": 'ae', "c": '2e', "d": '01', "e": 'd3', "f": 'ad'},
"7": {"0": '3b', "1": '4b', "2": 'da', "3": '46', "4": 'eb', "5": 'c9', "6": 'de', "7": '9a', "8": '8f', "9": '87', "a": 'd7', "b": '3a', "c": '80', "d": '6f', "e": '2f', "f": 'c8'},
"8": {"0": 'b1', "1": 'b4', "2": '37', "3": 'f7', "4": '0a', "5": '22', "6": '13', "7": '28', "8": '7c', "9": 'cc', "a": '3c', "b": '89', "c": 'c7', "d": 'c3', "e": '96', "f": '56'},
"9": {"0": '07', "1": 'bf', "2": '7e', "3": 'f0', "4": '0b', "5": '2b', "6": '97', "7": '52', "8": '35', "9": '41', "a": '79', "b": '61', "c": 'a6', "d": '4c', "e": '10', "f": 'fe'},
"a": {"0": 'bc', "1": '26', "2": '95', "3": '88', "4": '8a', "5": 'b0', "6": 'a3', "7": 'fb', "8": 'c0', "9": '18', "a": '94', "b": 'f2', "c": 'e1', "d": 'e5', "e": 'e9', "f": '5d'},
"b": {"0": 'd0', "1": 'dc', "2": '11', "3": '66', "4": '64', "5": '5c', "6": 'ec', "7": '59', "8": '42', "9": '75', "a": '12', "b": 'f5', "c": '74', "d": '9c', "e": 'aa', "f": '23'},
"c": {"0": '0e', "1": '86', "2": 'ab', "3": 'be', "4": '2a', "5": '02', "6": 'e7', "7": '67', "8": 'e6', "9": '44', "a": 'a2', "b": '6c', "c": 'c2', "d": '93', "e": '9f', "f": 'f1'},
"d": {"0": 'f6', "1": 'fa', "2": '36', "3": 'd2', "4": '50', "5": '68', "6": '9e', "7": '62', "8": '71', "9": '15', "a": '3d', "b": 'd6', "c": '40', "d": 'c4', "e": 'e2', "f": '0f'},
"e": {"0": '8e', "1": '83', "2": '77', "3": '6b', "4": '25', "5": '05', "6": '3f', "7": '0c', "8": '30', "9": 'ea', "a": '70', "b": 'b7', "c": 'a1', "d": 'e8', "e": 'a9', "f": '65'},
"f": {"0": '8d', "1": '27', "2": '1a', "3": 'db', "4": '81', "5": 'b3', "6": 'a0', "7": 'f4', "8": '45', "9": '7a', "a": '19', "b": 'df', "c": 'ee', "d": '78', "e": '34', "f": '60'}
}

S1 = {
"0": {"0": '55', "1": 'c2', "2": '63', "3": '71', "4": '3b', "5": 'c8', "6": '47', "7": '86', "8": '9f', "9": '3c', "a": 'da', "b": '5b', "c": '29', "d": 'aa', "e": 'fd', "f": '77'},
"1": {"0": '8c', "1": 'c5', "2": '94', "3": '0c', "4": 'a6', "5": '1a', "6": '13', "7": '00', "8": 'e3', "9": 'a8', "a": '16', "b": '72', "c": '40', "d": 'f9', "e": 'f8', "f": '42'},
"2": {"0": '44', "1": '26', "2": '68', "3": '96', "4": '81', "5": 'd9', "6": '45', "7": '3e', "8": '10', "9": '76', "a": 'c6', "b": 'a7', "c": '8b', "d": '39', "e": '43', "f": 'e1'},
"3": {"0": '3a', "1": 'b5', "2": '56', "3": '2a', "4": 'c0', "5": '6d', "6": 'b3', "7": '05', "8": '22', "9": '66', "a": 'bf', "b": 'dc', "c": '0b', "d": 'fa', "e": '62', "f": '48'},
"4": {"0": 'dd', "1": '20', "2": '11', "3": '06', "4": '36', "5": 'c9', "6": 'c1', "7": 'cf', "8": 'f6', "9": '27', "a": '52', "b": 'bb', "c": '69', "d": 'f5', "e": 'd4', "f": '87'},
"5": {"0": '7f', "1": '84', "2": '4c', "3": 'd2', "4": '9c', "5": '57', "6": 'a4', "7": 'bc', "8": '4f', "9": '9a', "a": 'df', "b": 'fe', "c": 'd6', "d": '8d', "e": '7a', "f": 'eb'},
"6": {"0": '2b', "1": '53', "2": 'd8', "3": '5c', "4": 'a1', "5": '14', "6": '17', "7": 'fb', "8": '23', "9": 'd5', "a": '7d', "b": '30', "c": '67', "d": '73', "e": '08', "f": '09'},
"7": {"0": 'ee', "1": 'b7', "2": '70', "3": '3f', "4": '61', "5": 'b2', "6": '19', "7": '8e', "8": '4e', "9": 'e5', "a": '4b', "b": '93', "c": '8f', "d": '5d', "e": 'db', "f": 'a9'},
"8": {"0": 'ad', "1": 'f1', "2": 'ae', "3": '2e', "4": 'cb', "5": '0d', "6": 'fc', "7": 'f4', "8": '2d', "9": '46', "a": '6e', "b": '1d', "c": '97', "d": 'e8', "e": 'd1', "f": 'e9'},
"9": {"0": '4d', "1": '37', "2": 'a5', "3": '75', "4": '5e', "5": '83', "6": '9e', "7": 'ab', "8": '82', "9": '9d', "a": 'b9', "b": '1c', "c": 'e0', "d": 'cd', "e": '49', "f": '89'},
"a": {"0": '01', "1": 'b6', "2": 'bd', "3": '58', "4": '24', "5": 'a2', "6": '5f', "7": '38', "8": '78', "9": '99', "a": '15', "b": '90', "c": '50', "d": 'b8', "e": '95', "f": 'e4'},
"b": {"0": 'd0', "1": '91', "2": 'c7', "3": 'ce', "4": 'ed', "5": '0f', "6": 'b4', "7": '6f', "8": 'a0', "9": 'cc', "a": 'f0', "b": '02', "c": '4a', "d": '79', "e": 'c3', "f": 'de'},
"c": {"0": 'a3', "1": 'ef', "2": 'ea', "3": '51', "4": 'e6', "5": '6b', "6": '18', "7": 'ec', "8": '1b', "9": '2c', "a": '80', "b": 'f7', "c": '74', "d": 'e7', "e": 'ff', "f": '21'},
"d": {"0": '5a', "1": '6a', "2": '54', "3": '1e', "4": '41', "5": '31', "6": '92', "7": '35', "8": 'c4', "9": '33', "a": '07', "b": '0a', "c": 'ba', "d": '7e', "e": '0e', "f": '34'},
"e": {"0": '88', "1": 'b1', "2": '98', "3": '7c', "4": 'f3', "5": '3d', "6": '60', "7": '6c', "8": '7b', "9": 'ca', "a": 'd3', "b": '1f', "c": '32', "d": '65', "e": '04', "f": '28'},
"f": {"0": '64', "1": 'be', "2": '85', "3": '9b', "4": '2f', "5": '59', "6": '8a', "7": 'd7', "8": 'b0', "9": '25', "a": 'ac', "b": 'af', "c": '12', "d": '03', "e": 'e2', "f": 'f2'}
}

#Generate keys and ivs
random_bits_for_keys = random.getrandbits(128)
random_bits_for_iv = random.getrandbits(128)
binary_key = bin(random_bits_for_keys)[2:].zfill(128)
binary_iv = bin(random_bits_for_iv)[2:].zfill(128)
key_list = [binary_key[i:i+8] for i in range(0, len(binary_key), 8)]
iv_list = [binary_iv[i:i+8] for i in range(0, len(binary_iv), 8)]

# LFSR cells loading
for i in range(16) :
s_value = key_list[i] + constants_list[i] + iv_list[i]
s_list.append(s_value)

#Bit reorganization
def bit_reorganization() :
x_list[0] = s_list[15][:16] + s_list[14][15:]
x_list[1] = s_list[11][15:] + s_list[9][:16]
x_list[2] = s_list[7][15:] + s_list[5][:16]
x_list[3] = s_list[2][15:] + s_list[0][:16]

#XOR
def xor(a, b) :
a = int(a, 2)
b = int(b, 2)
result = a ^ b
result = bin(result)[2:]
return result.zfill(32)

#Modulo 2^32 addition
def mod_2_32_addition(a, b) :
a = int(a,2)
b = int(b,2)
result = (a + b) & 0xFFFFFFFF
result = bin(result)[2:]
return result.zfill(32)

#Modulo 2^31 - 1 addition
def mod_2_31_addition(a, b) :
a = int(a,2)
b = int(b,2)
c = a + b
result = (c & 0x7FFFFFFF) + (c >> 31)
result = bin(result)[2:]
return result.zfill(31)

# k-bit cyclic shift of a binary string of 32 bits to the left
def shift(input, k):
k = k % 32
substr1 = input[k:]
substr2 = input[:k]
result = substr1 + substr2

return result

# Shift and xor output

# # L1(X)=X⊕ (X<<<2)⊕ (X<<<10)⊕ (X<<<18)⊕ (X<<<24), X == L1_input
def shift_and_xor_L1(L) :
L_shift2 = shift(L, 2)
L_shift10 = shift(L, 10)
L_shift18 = shift(L, 18)
L_shift24 = shift(L, 24)

L_output_binary = xor(L,
xor(L_shift2,
xor(L_shift10,
xor(L_shift18, L_shift24))))
L_hex_string = hex(int(L_output_binary,2))[2:]
L_hex_string = L_hex_string.zfill(8)
L_list = [L_hex_string[i:i+2] for i in range(0, len(L_hex_string), 2)]

return L_list


# # L2(X)=X⊕ (X<<<8)⊕ (X<<<14)⊕ (X<<<22)⊕ (X<<<30).
def shift_and_xor_L2(L) :
L_shift8 = shift(L, 8)
L_shift14 = shift(L, 14)
L_shift22 = shift(L, 22)
L_shift30 = shift(L, 30)

L_output_binary = xor(L,
xor(L_shift8,
xor(L_shift14,
xor(L_shift22, L_shift30))))
L_hex_string = hex(int(L_output_binary,2))[2:]
L_hex_string = L_hex_string.zfill(8)
L_list = [L_hex_string[i:i+2] for i in range(0, len(L_hex_string), 2)]

return L_list

# Use S-Box to return hex string

def s_output(L) :
output = ''
for i in range(len(L)) :
val = L[i]
if(i%2 == 0) :
output += S0[val[0]][val[1]]
else :
output += S1[val[0]][val[1]]

output = int(output, 16)

return bin(output)[2:]

#Non Linear Function
def non_linear_function(x) :
# # W=( X0⊕ R1) ⊞ R2;
xor_output = xor(x[0],r_list[1])
binary_string_output = mod_2_32_addition(xor_output, r_list[2])
integer_output = int(binary_string_output,2)
hex_output = hex(integer_output)
# # W1= X1 ⊞ R1;
w1 = mod_2_32_addition(x[1], r_list[1])
# # W2= X2 ⊕ R2;
w2 = xor(x[2], r_list[2])
# # R1=S(L1(W1L||W2H))
L1_input = w1[16:] + w2[:16]
L1_list = shift_and_xor_L1(L1_input)
r_list[1] = s_output(L1_list)

# # R2=S(L2(W2L||W1H))
L2_input = w2[16:] + w1[:16]
L2_list = shift_and_xor_L2(L2_input)
r_list[2] = s_output(L2_list)
return hex_output

# LFSR initialization mode

def LFSR(hex_output_from_non_linear_function = '0x0') :
s16_32bits = bin(int(hex_output_from_non_linear_function[2:],16))[2:]
s16 = s16_32bits[:31].zfill(31)

# (s15<<<15)+(s13<<<17)+(s10<<<21)+(s4<<<20)+(s0 <<<8)+s0 mod (2^31-1)
shift_by_15 = shift(s_list[15],15)
shift_by_17 = shift(s_list[13],17)
shift_by_21 = shift(s_list[10],21)
shift_by_20 = shift(s_list[4],20)
shift_by_8 = shift(s_list[0],8)
sum = mod_2_31_addition(shift_by_15,
mod_2_31_addition(shift_by_17,
mod_2_31_addition(shift_by_21,
mod_2_31_addition(shift_by_20,
mod_2_31_addition(shift_by_8, s_list[0])
)
)
)
)
s16 = mod_2_31_addition(sum, s16)

if(int(s16,2) == 0) :
s16 = '1111111111111111111111111111111'

#update cells of lfsr
for i in range(15) :
s_list[i] = s_list[i+1]

s_list[15] = s16

def main() :
output = ''
final_keystream = []
keystream_length = 10
num = 0
for i in range(32) :
bit_reorganization()
output = non_linear_function(x_list)
num = int(output, 16)
num = num >> 1
input_for_lfsr = hex(num)
LFSR(input_for_lfsr)
bit_reorganization()
output = non_linear_function(x_list)
LFSR()

for i in range(keystream_length) :
bit_reorganization()
hex_output = non_linear_function(x_list)
binary_output = bin(int(hex_output[2:], 16))[2:]
output = xor(binary_output, x_list[3])
output = hex(int(output,2))
final_keystream.append(output)
LFSR()

print("keystream = ",final_keystream)
# print(key_list)

if __name__ == "__main__":
main()
Loading

0 comments on commit f86c01f

Please sign in to comment.