diff --git a/zuc_128.py b/zuc_128.py new file mode 100644 index 0000000..b704c38 --- /dev/null +++ b/zuc_128.py @@ -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() \ No newline at end of file diff --git a/zuc_256.py b/zuc_256.py new file mode 100644 index 0000000..555c6ce --- /dev/null +++ b/zuc_256.py @@ -0,0 +1,495 @@ +# -*- coding: utf-8 -*- +"""ZUC 256.ipynb + +Automatically generated by Colab. + +Original file is located at + https://colab.research.google.com/drive/1hp8AV6hZguPe0T4Id3p9988Q-qVc8h-D +""" + +import random + +#Input key and iv +# key -> 256 bits +# iv -> 184 bits +key1 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +iv1 = 0xffffffffffffffffffffffffffffffffffffffffffffff +key0 = 0x0 +iv0 = 0x0 + +#Make lists from key and ivs +# binary_key = bin(key)[2:].zfill(256) +# binary_iv = bin(iv)[2:].zfill(184) +# key_list = key_list = [binary_key[i:i+8] for i in range(0, len(binary_key), 8)] +# iv_list_8 = [binary_iv[i:i+8] for i in range(0, 136, 8)] +# iv_list_6 = [binary_iv[i:i+6] for i in range(136, len(binary_iv), 6)] +# iv_list = iv_list_8 + iv_list_6 + +# #Input keys and ivs + +# key_list = [] +# iv_list = [] +# for i in range(32) : +# key_list.append('11111111') +# for i in range(25) : +# iv_list.append('11111111') +# # for i in range(8) : +# # iv.append('111111') + +#constants +d = ['0100010', '0101111', '0100100', '0101010','1101101','1000000','1000000','1000000','1000000','1000000','1000000','1000000','1000000','1010010','0010000','0110000'] + +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'} +} + +#defining cell +# s_list = [None] * 16 +# x_list = ['0','0','0','0'] +# r_list = ['0', '0', '0'] + +def OR_operator(a,b) : + a = int(a,2) + b = int(b,2) + result = a | b + result = bin(result)[2:].zfill(7) + + return result + +# # LFSR cells loading +# # s0 = key_list0 ‖ d0 ‖ key_list21 ‖ key_list16 +# s_list[0] = key_list[0] + d[0] + key_list[21] + key_list[16] + +# # s1 = key_list1 ‖ d1 ‖ key_list22 ‖ key_list17 +# s_list[1] = key_list[1] + d[1] + key_list[22] + key_list[17] + +# # s2 = key_list2 ‖ d2 ‖ key_list23 ‖ key_list18 +# s_list[2] = key_list[2] + d[2] + key_list[23] + key_list[18] + +# # s3 = key_list3 ‖ d3 ‖ key_list24 ‖ key_list19 +# s_list[3] = key_list[3] + d[3] + key_list[24] + key_list[19] + +# # s4 = key_list4 ‖ d4 ‖ key_list25 ‖ key_list20 +# s_list[4] = key_list[4] + d[4] + key_list[25] + key_list[20] + +# # s5 = IV0 ‖ (d5 | IV17) ‖ key_list5 ‖ key_list26 +# s_list[5] = iv_list[0] + OR_operator(d[5], iv_list[17]) + key_list[5] + key_list[26] + +# # s6 = IV1 ‖ (d6 | IV18) ‖ key_list6 ‖ key_list27 +# s_list[6] = iv_list[1] + OR_operator(d[6],iv_list[18]) + key_list[6] + key_list[27] + +# # s7 = IV10 ‖ (d7 | IV19) ‖ key_list7 ‖ IV2 +# s_list[7] = iv_list[10] + OR_operator(d[7],iv_list[19]) + key_list[7] + iv_list[2] + +# # s8 = key_list8 ‖ (d8 | IV20) ‖ IV3 ‖ IV11 +# s_list[8] = key_list[8] + OR_operator(d[8], iv_list[20]) + iv_list[3] + iv_list[11] + +# # s9 = key_list9 ‖ (d9 | IV21) ‖ IV12 ‖ IV4 +# s_list[9] = key_list[9] + OR_operator(d[9],iv_list[21]) + iv_list[12] + iv_list[4] + +# # s10 = IV5 ‖ (d10 | IV22) ‖ key_list10 ‖ key_list28 +# s_list[10] = iv_list[5] + OR_operator(d[10], iv_list[22]) + key_list[10] + key_list[28] + +# # s11 = key_list11 ‖ (d11 | IV23) ‖ IV6 ‖ IV13 +# s_list[11] = key_list[11] + OR_operator(d[11], iv_list[23]) + iv_list[6] + iv_list[13] + +# # s12 = key_list12 ‖ (d12 | IV24) ‖ IV7 ‖ IV14 +# s_list[12] = key_list[12] + OR_operator(d[12], iv_list[24]) + iv_list[7] + iv_list[14] + +# # s13 = key_list13 ‖ d13 ‖ IV15 ‖ IV8 +# s_list[13] = key_list[13] + d[13] + iv_list[15] + iv_list[8] + +# # s14 = key_list14 ‖ (d14 | (key_list31)4H ) ‖ IV16 ‖ IV9 +# s_list[14] = key_list[14] + OR_operator(d[14], key_list[31][:4]) + iv_list[16] + iv_list[9] + +# # s15 = key_list15 ‖ (d15 | (key_list31)4L) ‖ key_list30 ‖ key_list29 +# s_list[15] = key_list[15] + OR_operator(d[15], key_list[31][4:]) + key_list[30] + key_list[29] + +#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_initialization(hex_output_from_non_linear_function) : +# s16_32bits = bin(int(hex_output_from_non_linear_function[2:],16))[2:] +# s16 = s16_32bits[:31].zfill(31) +# # 215 · s15 + 217 · s13 + 221 · s10 + 220 · s4 + (1 + 28) · s0 mod(231 − 1) +# # (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 + + +# # LFSR WOrk Mode +# def LFSR_work() : + +# # (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) +# s16 = 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]) +# ) +# ) +# ) +# ) + +# 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 + +# 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 key_loading(key, iv) : + cells = [None] * 16 + #Make lists from key and ivs + binary_key = bin(key)[2:].zfill(256) + binary_iv = bin(iv)[2:].zfill(184) + key_list = key_list = [binary_key[i:i+8] for i in range(0, len(binary_key), 8)] + iv_list_8 = [binary_iv[i:i+8] for i in range(0, 136, 8)] + iv_list_6 = [binary_iv[i:i+6] for i in range(136, len(binary_iv), 6)] + iv_list = iv_list_8 + iv_list_6 + + # LFSR cells loading + # s0 = key_list0 ‖ d0 ‖ key_list21 ‖ key_list16 + cells[0] = key_list[0] + d[0] + key_list[21] + key_list[16] + + # s1 = key_list1 ‖ d1 ‖ key_list22 ‖ key_list17 + cells[1] = key_list[1] + d[1] + key_list[22] + key_list[17] + + # s2 = key_list2 ‖ d2 ‖ key_list23 ‖ key_list18 + cells[2] = key_list[2] + d[2] + key_list[23] + key_list[18] + + # s3 = key_list3 ‖ d3 ‖ key_list24 ‖ key_list19 + cells[3] = key_list[3] + d[3] + key_list[24] + key_list[19] + + # s4 = key_list4 ‖ d4 ‖ key_list25 ‖ key_list20 + cells[4] = key_list[4] + d[4] + key_list[25] + key_list[20] + + # s5 = IV0 ‖ (d5 | IV17) ‖ key_list5 ‖ key_list26 + cells[5] = iv_list[0] + OR_operator(d[5], iv_list[17]) + key_list[5] + key_list[26] + + # s6 = IV1 ‖ (d6 | IV18) ‖ key_list6 ‖ key_list27 + cells[6] = iv_list[1] + OR_operator(d[6],iv_list[18]) + key_list[6] + key_list[27] + + # s7 = IV10 ‖ (d7 | IV19) ‖ key_list7 ‖ IV2 + cells[7] = iv_list[10] + OR_operator(d[7],iv_list[19]) + key_list[7] + iv_list[2] + + # s8 = key_list8 ‖ (d8 | IV20) ‖ IV3 ‖ IV11 + cells[8] = key_list[8] + OR_operator(d[8], iv_list[20]) + iv_list[3] + iv_list[11] + + # s9 = key_list9 ‖ (d9 | IV21) ‖ IV12 ‖ IV4 + cells[9] = key_list[9] + OR_operator(d[9],iv_list[21]) + iv_list[12] + iv_list[4] + + # s10 = IV5 ‖ (d10 | IV22) ‖ key_list10 ‖ key_list28 + cells[10] = iv_list[5] + OR_operator(d[10], iv_list[22]) + key_list[10] + key_list[28] + + # s11 = key_list11 ‖ (d11 | IV23) ‖ IV6 ‖ IV13 + cells[11] = key_list[11] + OR_operator(d[11], iv_list[23]) + iv_list[6] + iv_list[13] + + # s12 = key_list12 ‖ (d12 | IV24) ‖ IV7 ‖ IV14 + cells[12] = key_list[12] + OR_operator(d[12], iv_list[24]) + iv_list[7] + iv_list[14] + + # s13 = key_list13 ‖ d13 ‖ IV15 ‖ IV8 + cells[13] = key_list[13] + d[13] + iv_list[15] + iv_list[8] + + # s14 = key_list14 ‖ (d14 | (key_list31)4H ) ‖ IV16 ‖ IV9 + cells[14] = key_list[14] + OR_operator(d[14], key_list[31][:4]) + iv_list[16] + iv_list[9] + + # s15 = key_list15 ‖ (d15 | (key_list31)4L) ‖ key_list30 ‖ key_list29 + cells[15] = key_list[15] + OR_operator(d[15], key_list[31][4:]) + key_list[30] + key_list[29] + + return cells + +def zuc(key, iv) : + global s_list + global x_list + global r_list + + s_list = key_loading(key, iv) + x_list = ['0','0','0','0'] + r_list = ['0', '0', '0'] + + output = '' + final_keystream = [] + keystream_length = 20 + 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("for key ",key, "the keystream is : ") + for keystream in final_keystream : + print(keystream) + # print(key_list) + +def main() : + zuc(key0,iv0) + zuc(key1,iv1) + zuc(key0,iv0) + zuc(key1,iv1) + zuc(key0,iv0) + zuc(key1,iv1) +if __name__ == "__main__": + main() + +# def main() : +# output = '' +# final_keystream = [] +# keystream_length = 20 +# 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) +# for keystream in final_keystream : +# print(keystream) +# # print(key_list) + +# if __name__ == "__main__": +# main() \ No newline at end of file