def bin_8bit(dec):
return(str(format(dec,'08b')))
def bin_32bit(dec):
return(str(format(dec,'032b')))
def bin_4bit(dec):
return(str(format(dec,'04b')))
def bin_64bit(dec):
return(str(format(dec,'064b')))
def hex_return(dec):
return(str(format(dec,'08x')))
def hex_double(dec):
return(str(format(dec,'02x')))
def hex_single(dec):
return(str(format(dec,'01x')))
def dec_return_bin(bin_string):
return(int(bin_string,2))
def dec_return_hex(hex_string):
return(int(hex_string,16))
def L_P(SET,n):
to_return=[]
j=0
k=n
while k<len(SET)+1:
to_return.append(SET[j:k])
j=k
k+=n
return(to_return)
def s_l(bit_string):
bit_list=[]
for i in range(len(bit_string)):
bit_list.append(bit_string[i])
return(bit_list)
def l_s(bit_list):
bit_string=''
for i in range(len(bit_list)):
bit_string+=bit_list[i]
return(bit_string)
def rotate_left(bit_string,n):
if n==0:
return(bit_string)
bit_list = s_l(bit_string)
count=0
while count <= n-1:
list_main=list(bit_list)
var_0=list_main.pop(0)
list_main=list(list_main+[var_0])
bit_list=list(list_main)
count+=1
return(l_s(list_main))
def rotate_right(bit_string,n):
if n==0:
return(bit_string)
bit_list = s_l(bit_string)
count=0
while count <= n-1:
list_main=list(bit_list)
var_0=list_main.pop(-1)
list_main=list([var_0]+list_main)
bit_list=list(list_main)
count+=1
return(l_s(list_main))
def shift_right(bit_string,n):
bit_list=s_l(bit_string)
count=0
while count <= n-1:
bit_list.pop(-1)
count+=1
front_append=['0']*n
return(l_s(front_append+bit_list))
def mod_32_addition(input_set):
value=0
for i in range(len(input_set)):
value+=input_set[i]
mod_32 = 4294967296
return(value%mod_32)
def xo(bit_string_1,bit_string_2):
xor_list=[]
for i in range(len(bit_string_1)):
if bit_string_1[i]=='0' and bit_string_2[i]=='0':
xor_list.append('0')
if bit_string_1[i]=='1' and bit_string_2[i]=='1':
xor_list.append('0')
if bit_string_1[i]=='0' and bit_string_2[i]=='1':
xor_list.append('1')
if bit_string_1[i]=='1' and bit_string_2[i]=='0':
xor_list.append('1')
return(l_s(xor_list))
def and_2str(bit_string_1,bit_string_2):
and_list=[]
for i in range(len(bit_string_1)):
if bit_string_1[i]=='1' and bit_string_2[i]=='1':
and_list.append('1')
else:
and_list.append('0')
return(l_s(and_list))
def or_2str(bit_string_1,bit_string_2):
or_list=[]
for i in range(len(bit_string_1)):
if bit_string_1[i]=='0' and bit_string_2[i]=='0':
or_list.append('0')
else:
or_list.append('1')
return(l_s(or_list))
def not_str(bit_string):
not_list=[]
for i in range(len(bit_string)):
if bit_string[i]=='0':
not_list.append('1')
else:
not_list.append('0')
return(l_s(not_list))
def init_array():
int_bits = L_P(L_P('0'*1600,64),5)
return(int_bits)
def sub_str_concat(list_of_lists):
to_return=[]
for i in range(len(list_of_lists)):
insert=''
for x in range(len(list_of_lists[i])):
insert+=list_of_lists[i][x]
to_return.append(insert)
return(to_return)
def str_concat(list_of_strings):
to_return=''
for i in range(len(list_of_strings)):
to_return+=list_of_strings[i]
return(to_return)
def list_concat(list_of_lists):
to_return=[]
for i in range(len(list_of_lists)):
to_return+=list_of_lists[i]
return(to_return)
def flip_string(a_string):
to_return=''
for i in range(1,len(a_string)+1):
to_return+=a_string[-i]
return(to_return)
def theta(s):
c_xz=[]
for i in range(5):
c_xz.append(xo(xo(xo(xo(s[i],s[i+5]),s[i+10]),s[i+15]),s[i+20]))
d_xz=[]
for i in range(5):
d_xz.append(xo(c_xz[(i-1)%5],rotate_left(c_xz[(i+1)%5],1)))
a_xyz=[]
for i in range(5):
a_xyz.append([xo(s[i],d_xz[i]),
xo(s[i+5],d_xz[i]),
xo(s[i+10],d_xz[i]),
xo(s[i+15],d_xz[i]),
xo(s[i+20],d_xz[i])])
a_xyz=list_concat(a_xyz)
order_return=[]
for i in range(5):
order_return.append([a_xyz[i],a_xyz[i+5],a_xyz[i+10],a_xyz[i+15],a_xyz[i+20]])
return(list_concat(order_return))
def _theta(input_list):
def access_function(index):
a_list = [
[[1], [1, 2, 5, 7, 10, 12, 15, 17, 20, 22, 25], ['00101010101']],
[[2], [1, 2, 3, 6, 8, 11, 13, 16, 18, 21, 23], ['10010101010']],
[[3], [2, 3, 4, 7, 9, 12, 14, 17, 19, 22, 24], ['10010101010']],
[[4], [3, 4, 5, 8, 10, 13, 15, 18, 20, 23, 25], ['10010101010']],
[[5], [1, 4, 5, 6, 9, 11, 14, 16, 19, 21, 24], ['01001010101']],
[[6], [2, 5, 6, 7, 10, 12, 15, 17, 20, 22, 25], ['01001010101']],
[[7], [1, 3, 6, 7, 8, 11, 13, 16, 18, 21, 23], ['10100101010']],
[[8], [2, 4, 7, 8, 9, 12, 14, 17, 19, 22, 24], ['10100101010']],
[[9], [3, 5, 8, 9, 10, 13, 15, 18, 20, 23, 25], ['10100101010']],
[[10], [1, 4, 6, 9, 10, 11, 14, 16, 19, 21, 24], ['01010010101']],
[[11], [2, 5, 7, 10, 11, 12, 15, 17, 20, 22, 25], ['01010010101']],
[[12], [1, 3, 6, 8, 11, 12, 13, 16, 18, 21, 23], ['10101001010']],
[[13], [2, 4, 7, 9, 12, 13, 14, 17, 19, 22, 24], ['10101001010']],
[[14], [3, 5, 8, 10, 13, 14, 15, 18, 20, 23, 25], ['10101001010']],
[[15], [1, 4, 6, 9, 11, 14, 15, 16, 19, 21, 24], ['01010100101']],
[[16], [2, 5, 7, 10, 12, 15, 16, 17, 20, 22, 25], ['01010100101']],
[[17], [1, 3, 6, 8, 11, 13, 16, 17, 18, 21, 23], ['10101010010']],
[[18], [2, 4, 7, 9, 12, 14, 17, 18, 19, 22, 24], ['10101010010']],
[[19], [3, 5, 8, 10, 13, 15, 18, 19, 20, 23, 25], ['10101010010']],
[[20], [1, 4, 6, 9, 11, 14, 16, 19, 20, 21, 24], ['01010101001']],
[[21], [2, 5, 7, 10, 12, 15, 17, 20, 21, 22, 25], ['01010101001']],
[[22], [1, 3, 6, 8, 11, 13, 16, 18, 21, 22, 23], ['10101010100']],
[[23], [2, 4, 7, 9, 12, 14, 17, 19, 22, 23, 24], ['10101010100']],
[[24], [3, 5, 8, 10, 13, 15, 18, 20, 23, 24, 25], ['10101010100']],
[[25], [1, 4, 6, 9, 11, 14, 16, 19, 21, 24, 25], ['01010101010']]
]
to_return=[]
for i in range(len(a_list)):
for x in range(len(a_list[i][1])):
if a_list[i][1][x]==index:
to_return.append([a_list[i][0][0],a_list[i][2][0][a_list[i][1].index(index)]])
return(to_return)
to_return=[]
for i in range(25):
init='0'*64
insert = access_function(i+1)
for x in range(len(insert)):
if insert[x][-1]=='0':
init=xo(init,input_list[insert[x][0]-1])
if insert[x][-1]=='1':
init=xo(init,rotate_left(input_list[insert[x][0]-1],1))
to_return.append(init)
return(to_return)
def rho(s):
off_set=[0,1,190,28,91,
36,300,6,55,276,
3,10,171,153,231,
105,45,15,21,136,
210,66,253,120,78]
to_return=[]
for i in range(len(s)):
to_return.append(rotate_left(s[i],off_set[i]))
return(to_return)
def pi(s):
index=[0,6,12,18,24,
3,9,10,16,22,
1,7,13,19,20,
4,5,11,17,23,
2,8,14,15,21]
to_return=[]
for i in range(len(index)):
for x in range(len(s)):
if index[i]==x:
to_return.append(s[x])
return(to_return)
def chi(s):
def sf(find_list,set_main):
return(set_main.index(find_list))
sm=[[0,0],[1,0],[2,0],[3,0],[4,0],
[0,1],[1,1],[2,1],[3,1],[4,1],
[0,2],[1,2],[2,2],[3,2],[4,2],
[0,3],[1,3],[2,3],[3,3],[4,3],
[0,4],[1,4],[2,4],[3,4],[4,4]]
to_return=[]
for i in range(25):
to_return.append(xo(s[i],and_2str(not_str(s[sf([(sm[i][0]+1)%5,sm[i][1]],sm)]),s[sf([(sm[i][0]+2)%5,sm[i][1]],sm)])))
return(to_return)
def _chi(s):
set_0=['00000','00101','01011','01010',
'10110','10111','10001','10100',
'01101','01000','01110','01111',
'00011','00010','01100','01001',
'11010','11101','10011','10000',
'11100','11111','11001','11110',
'00110','00001','00111','00100',
'11000','11011','10101','10010']
set_1=['00000','00001','00011','00010',
'00110','00111','00101','00100',
'01100','01101','01111','01110',
'01010','01011','01001','01000',
'11000','11001','11011','11010',
'11110','11111','11101','11100',
'10100','10101','10111','10110',
'10010','10011','10001','10000']
def list_concat(list_of_lists):
to_return=[]
for i in range(len(list_of_lists)):
to_return+=list_of_lists[i]
return(to_return)
def L_P(SET,n):
to_return=[]
j=0
k=n
while k<len(SET)+1:
to_return.append(SET[j:k])
j=k
k+=n
return(to_return)
def rc_con(sub_set):
to_return=[]
for i in range(len(sub_set[0])):
insert=''
for x in range(len(sub_set)):
insert+=sub_set[x][i]
to_return.append(insert)
return(to_return)
to_return=[]
to_iter=L_P(s,5)
for i in range(len(to_iter)):
insert=[]
convert=rc_con(to_iter[i])
for x in range(len(convert)):
insert.append(set_0[set_1.index(convert[x])])
insert=rc_con(insert)
to_return.append(insert)
return(list_concat(to_return))
def iota(s,i_r):
def rc(t):
def xor_bit(a,b):
return('1' if ((a == '1') ^ (b == '1')) else '0')
if t%255==0:
return('1')
r=['1','0','0','0','0','0','0','0']
for i in range(1,(t%255)+1):
r = ['0'] + r
r[0] = xor_bit(r[0],r[8])
r[4] = xor_bit(r[4],r[8])
r[5] = xor_bit(r[5],r[8])
r[6] = xor_bit(r[6],r[8])
r = trunc(r,8)
return(r[0])
to_index=[]
for x in range(24):
to_check=''
RC = ['0']*64
for i in range(7):
RC[(2**i)-1]=rc(i+(7*x))
to_index.append(flip_string(str_concat(RC)))
s[0]=xo(s[0],to_index[i_r])
return(s)
def message_append(str_msg):
return(str_msg+'01')
def sha_3_hack_rate(output_len):
if output_len==224:
return(18)
if output_len==256:
return(17)
if output_len==384:
return(13)
if output_len==512:
return(9)
def sha_3_rate(output_len):
if output_len==224:
return(1152)
if output_len==256:
return(1088)
if output_len==384:
return(832)
if output_len==512:
return(576)
def pad(x,m):
j=(-m-2)%x
return('1'+'0'*j+'1')
def trunc(string,index):
return(string[0:index])
def message_processing(bit_string,digest_len):
if len(bit_string)!=sha_3_rate(digest_len):
msg_bs = message_append(bit_string)
p = msg_bs + pad(sha_3_rate(digest_len),len(msg_bs))
if len(bit_string)==sha_3_rate(digest_len):
p=bit_string
to_split = L_P(p,8)
new_hex=[]
for i in range(len(to_split)):
new_hex.append(hex_double(int(flip_string(to_split[i]),2)))
back_append = 200-len(new_hex)
new_hex = new_hex+['00']*back_append
total_string=''
for i in range(len(new_hex)):
total_string+=new_hex[i]
to_insert = L_P(total_string,16)
to_return=[]
for i in range(len(to_insert)):
to_return.append(flip_string(L_P(to_insert[i],2)))
return(to_return)
def message_expansion(hex_list):
to_convert=''
for i in range(len(hex_list)):
to_convert+=bin_8bit(int(hex_list[i],16))
return(to_convert)
def message_bit_return(string_input):
bit_list=[]
for i in range(len(string_input)):
bit_list.append(bin_8bit(ord(string_input[i])))
return(l_s(bit_list))
def processing(message_string):
to_invert=L_P(message_bit_return(message_string),8)
to_return=[]
for i in range(len(to_invert)):
to_return.append(flip_string(to_invert[i]))
return(str_concat(to_return))
def main_bit_set(bit_string,digest_len):
front_append=L_P(bit_string,sha_3_rate(digest_len))
back_string=''
for i in range(len(bit_string)%sha_3_rate(digest_len)):
back_string+=bit_string[-(i+1)]
back_string=flip_string(back_string)
return(front_append+[back_string])
def xo_set(list_string_0,list_string_1):
to_return=[]
for i in range(len(list_string_0)):
to_return.append(xo(list_string_0[i],list_string_1[i]))
return(to_return)
def zero_pad(bit_string):
while len(bit_string)!=1600:
bit_string+='0'
return(L_P(bit_string,64))
def edian_bit_convert(list_of_strings):
to_return=[]
for i in range(len(list_of_strings)):
inter=L_P(list_of_strings[i],8)
insert=''
for x in range(1,len(inter)+1):
insert+=inter[-x]
to_return.append(insert)
return(to_return)
def edian_byte_convert(list_strings):
to_return=[]
for i in range(len(list_strings)):
inter=L_P(list_strings[i],2)
insert=''
for x in range(1,len(inter)+1):
insert+=inter[-x]
to_return.append(insert)
return(to_return)
def hex_bin_convert(hex_string):
to_return=''
for i in range(len(hex_string)):
to_return+=bin_4bit(int(hex_string[i],16))
return(to_return)
def set_convert(list_hex_string):
to_return=[]
def hex_bin_convert(hex_string):
to_return=''
for i in range(len(hex_string)):
to_return+=bin_4bit(int(hex_string[i],16))
return(to_return)
for i in range(len(list_hex_string)):
to_return.append(hex_bin_convert(list_hex_string[i]))
return(to_return)
def output_final(input_set,digest_len):
to_flip=[]
if digest_len!=224:
for i in range(digest_len/64):
to_flip.append(input_set[i])
if digest_len==224:
for i in range((digest_len//64)+1):
to_flip.append(input_set[i])
to_convert=[]
for i in range(len(to_flip)):
to_convert.append(L_P(to_flip[i],8))
bin_list=[]
for i in range(len(to_convert)):
bin_list.append(flip_string(to_convert[i]))
bin_list=L_P(str_concat(bin_list),4)
to_return=[]
for i in range(len(bin_list)):
to_return.append(hex_single(int(bin_list[i],2)))
to_return=str_concat(to_return)
if digest_len!=224:
return(to_return)
return(to_return[0:56])
def set_invert(list_bin_string):
to_return=[]
for i in range(len(list_bin_string)):
inter=L_P(list_bin_string[i],4)
insert=''
for x in range(len(inter)):
insert+=hex_single(int(inter[x],2))
to_return.append(insert)
return(to_return)
def message_processing_invert(a_input,digest_len):
invert_0=edian_byte_convert(a_input)
invert_1=[]
for i in range(sha_3_hack_rate(digest_len)):
invert_1.append(invert_0[i])
invert_2=L_P(str_concat(invert_1),2)
invert_3=''
for i in range(len(invert_2)):
insert=''
for x in range(1,len(invert_2[i])+1):
insert+=flip_string(bin_4bit(int(invert_2[i][-x],16)))
invert_3+=insert
return(invert_3)
def s3b(bit_string,digest_len):
if len(bit_string) < sha_3_rate(digest_len):
x = L_P(message_expansion(L_P(str_concat(message_processing(bit_string,digest_len)),2)),64)
for i in range(24):
x = iota(_chi(pi(rho(_theta(x)))),i)
return(output_final(x,digest_len))
if len(bit_string) >= sha_3_rate(digest_len):
#
#
#
#
set_main=main_bit_set(bit_string,digest_len)
print(set_main)
#
#
#
#
x=L_P(message_expansion(L_P(str_concat(message_processing(set_main[0],digest_len)),2)),64)
for i in range(24):
x = iota(_chi(pi(rho(_theta(x)))),i)
for c in range(len(set_main)-1):
var_0=edian_bit_convert(x)
#print(var_0)
#XOR var_0 pass through invert then execute
var_1=set_convert(edian_byte_convert(message_processing(set_main[c+1],digest_len)))
#print(var_1)
#print(message_processing_invert(edian_byte_convert(set_invert(var_1)),digest_len))
var_2=edian_bit_convert(xo_set(var_0,var_1))
#return(var_2)
#break
for i in range(24):
var_2=iota(_chi(pi(rho(_theta(var_2)))),i)
x=var_2
return(output_final(x,digest_len))
def tv_bit_return(tv_string,len_str):
tv_string=hex_bin_convert(tv_string)
tv_string=edian_bit_convert(L_P(tv_string,8))
for i in range(len(tv_string)):
tv_string[i]=flip_string(tv_string[i])
total=''
for i in range(len(tv_string)):
total+=tv_string[i]
return(total[0:len_str])
def nist_test_vector(digest_len,test_vector_string,tl):
return(s3b(tv_bit_return(test_vector_string,tl),digest_len))
def online_convert(a_string,digest_len):
#Online convert will match sha_3 implementation provided
#by python 3.6 distribution. And online sha_3 generators.
#It's a one for one string conversions. s3b is a bit aligned
#sha_3 implementations.
to_return=''
for i in range(len(a_string)):
to_return+=flip_string(message_bit_return(a_string[i]))
return(s3b(to_return,digest_len))
def str_build(a_list):
to_return=''
for i in range(len(a_list)):
to_return+=str(a_list[i])
return(to_return)
def set_main_build(size):
import numpy
to_return=[]
for i in range(1):
to_return.append(str_build(list(numpy.random.randint(2,size=(size,)))))
return(to_return)