-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
742 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
Oops, something went wrong.