SHA-3 Speed Improvement
#https://gist.github.com/back-seat-driver/b2f81929741cd94b1ff17086fdaad0bd | |
def bin_n_bit(dec,n): | |
return(str(format(dec,'0'+n+'b'))) | |
def hex_n_bit(dec,n): | |
return(str(format(dec,'0'+n+'x'))) | |
def xo_set(ip_0,ip_1): | |
to_return=[] | |
for i in range(len(ip_0)): | |
to_return.append(ip_0[i] ^ ip_1[i]) | |
return(to_return) | |
def L_P(SET,n): | |
to_return = [] ; j = 0 | |
while j + n <= len(SET): | |
to_return.append(SET[j:j+n]) | |
j += n | |
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 flip_string(a_string): | |
to_return='' | |
for i in range(1,len(a_string)+1): | |
to_return+=a_string[-i] | |
return(to_return) | |
def rot(x,n,l): | |
n = n%l | |
return((x>>(l-n))+(x<<n))%(1<<l) | |
def theta(ip): | |
c_xz=[] | |
for i in range(5): | |
c_xz.append(ip[i] ^ ip[i+5] ^ ip[i+10] ^ ip[i+15] ^ ip[i+20]) | |
for i in range(5): | |
d_xz = c_xz[(i-1)%5] ^ rot(c_xz[(i+1)%5],1,64) | |
for x in range(0,25,5): | |
ip[i+x] = ip[i+x] ^ d_xz | |
return(ip) | |
def rho(ip): | |
fast_rot=[0,1,62,28,27, | |
36,44,6,55,20, | |
3,10,43,25,39, | |
41,45,15,21,8, | |
18,2,61,56,14] | |
for i in range(25): | |
ip[i] = rot(ip[i], fast_rot[i], 64) | |
return(ip) | |
def pi(ip): | |
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(25): | |
for x in range(25): | |
if index[i]==x: | |
to_return.append(ip[x]) | |
return(to_return) | |
def chi(ip): | |
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(ip[i] ^ ~ip[sf([(sm[i][0]+1)%5,sm[i][1]],sm)] & | |
ip[sf([(sm[i][0]+2)%5,sm[i][1]],sm)]) | |
return(to_return) | |
def iota(ip,i_r): | |
RC=[0x0000000000000001, | |
0x0000000000008082, | |
0x800000000000808A, | |
0x8000000080008000, | |
0x000000000000808B, | |
0x0000000080000001, | |
0x8000000080008081, | |
0x8000000000008009, | |
0x000000000000008A, | |
0x0000000000000088, | |
0x0000000080008009, | |
0x000000008000000A, | |
0x000000008000808B, | |
0x800000000000008B, | |
0x8000000000008089, | |
0x8000000000008003, | |
0x8000000000008002, | |
0x8000000000000080, | |
0x000000000000800A, | |
0x800000008000000A, | |
0x8000000080008081, | |
0x8000000000008080, | |
0x0000000080000001, | |
0x8000000080008008] | |
ip[0]=ip[0] ^ RC[i_r] | |
return(ip) | |
def boost(ip): | |
to_return=[] | |
for i in range(25): | |
to_return.append(int(ip[i],2)) | |
return(to_return) | |
def booster(op): | |
to_return=[] | |
for i in range(25): | |
to_return.append(bin_n_bit(op[i],'64')) | |
return(to_return) | |
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 message_processing(bit_string,digest_len): | |
## if len(bit_string)!=sha_3_rate(digest_len): | |
## msg_bs = bit_string + '01' | |
## 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_n_bit(int(flip_string(to_split[i]),2),'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))) | |
## print(to_return) | |
## return(to_return) | |
def message_processing(bit_string,digest_len): | |
if len(bit_string)!=sha_3_rate(digest_len): | |
msg_bs = bit_string + '01' | |
p = msg_bs + pad(sha_3_rate(digest_len),len(msg_bs)) | |
if len(bit_string)==sha_3_rate(digest_len): | |
p=bit_string | |
state_fill = L_P(bit_string + '0'*(1600-len(bit_string)),64) | |
print(state_fill) | |
to_split = L_P(p,8) | |
new_hex=[] | |
for i in range(len(to_split)): | |
new_hex.append(hex_n_bit(int(flip_string(to_split[i]),2),'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))) | |
print(to_return) | |
return(to_return) | |
def message_expansion(hex_list): | |
to_convert='' | |
for i in range(len(hex_list)): | |
to_convert+=bin_n_bit(int(hex_list[i],16),'8') | |
return(to_convert) | |
def message_bit_return(string_input): | |
bit_list='' | |
for i in range(len(string_input)): | |
bit_list+=bin_n_bit(ord(string_input[i]),'8') | |
return(bit_list) | |
def main_bit_set(bit_string,digest_len): | |
#All this function does is take the primary sha_3 seed | |
#and return the block chain to be iterated to hashing. | |
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 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_n_bit(int(hex_string[i],16),'4') | |
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_n_bit(int(hex_string[i],16),'4') | |
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(int(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_n_bit(int(bin_list[i],2),'1')) | |
to_return=str_concat(to_return) | |
if digest_len!=224: | |
return(to_return) | |
return(to_return[0:56]) | |
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) | |
stat_test=[] | |
for i in range(24): | |
x = booster(iota(chi(pi(rho(theta(boost(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) | |
x=L_P(message_expansion(L_P(str_concat(message_processing(set_main[0],digest_len)),2)),64) | |
for i in range(24): | |
x = booster(iota(chi(pi(rho(theta(boost(x))))),i)) | |
for c in range(len(set_main)-1): | |
var_0=edian_bit_convert(x) | |
var_1=set_convert(edian_byte_convert(message_processing(set_main[c+1],digest_len))) | |
var_2=edian_bit_convert(booster(xo_set(boost(var_0),boost(var_1)))) | |
for i in range(24): | |
var_2 = booster(iota(chi(pi(rho(theta(boost(var_2))))),i)) | |
x=var_2 | |
return(output_final(x,digest_len)) | |
def s3(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)) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment