Last active
October 4, 2017 02:42
-
-
Save back-seat-driver/b2f81929741cd94b1ff17086fdaad0bd to your computer and use it in GitHub Desktop.
SHA-3 Speed Improvement
This file contains hidden or 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
#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