-
Notifications
You must be signed in to change notification settings - Fork 0
/
SHA-1.py
190 lines (174 loc) · 6.54 KB
/
SHA-1.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
import math
import cmath
import numpy as np
from cmath import exp, pi
import random
#####################################################################################################
def f1(B,C,D): #function for 1-20 rounds
b1=int(B,2)
c1=int(C,2)
d1=int(D,2)
S=(b1 & c1) | (~b1 & d1)
return '{:032b}'.format(S)
#####################################################################################################
def f2(B,C,D): #function for 21-40 rounds
b1=int(B,2)
c1=int(C,2)
d1=int(D,2)
S=b1^c1^d1
return '{:032b}'.format(S)
#####################################################################################################
def f3(B,C,D): #function for 41-60 rounds
b1=int(B,2)
c1=int(C,2)
d1=int(D,2)
S= (b1 & c1) | (c1 & d1) | (b1 & d1)
return '{:032b}'.format(S)
#####################################################################################################
def f4(B,C,D): #function for 61-80 rounds
b1=int(B,2)
c1=int(C,2)
d1=int(D,2)
S=b1^c1^d1
return '{:032b}'.format(S)
#####################################################################################################
if __name__=='__main__':
x=input("Enter the message to be hashed: ")
#########################################################################################################
res = ''.join(format(ord(i), '08b') for i in x) #converting the message to binary format
A=str(res)
#########################################################################################################
n=len(A)
bin_A="" #stores the 64 bit binary of the length of input
while n>0:
if n%2==1:
bin_A='1'+bin_A
else:
bin_A='0'+bin_A
n=int(n/2)
while len(bin_A)!=64:
bin_A='0'+bin_A
########################################################################################################
if len(A)%448!=0:
A=A+'1'
while len(A)%448!=0:
A=A+'0'
message=[]
a=int(len(A)/448) #no of 448-bit blocks , we then have 64+448=512 block size input where 64 bits come from the size
for j in range(a):
block=A[j*448:(j+1)*448]+bin_A
message.append(block)
for j in range(len(message)):
m=message[j]
words=[]
for i in range(16):
words.append(m[i*32:(i+1)*32]) #the block provides the first 16 words
for i in range(16,80): # recursive function to get all the 80 words
W=int(words[i-3],2)^int(words[i-8],2)^int(words[i-16])^int(words[i-14])
w='{:032b}'.format(W)
w=w[1:32]+w[0]
words.append(w)
A_a=""
B_b=""
C_c=""
D_d=""
E_e=""
A_i=""
B_i=""
C_i=""
D_i=""
E_i=""
for j in range(32): #initialising the 160-bit random key, which is divided into 5 32-bit blocks A,B,C,D,E
n=random.randint(0,1)
A_a=A_a+str(n)
A_i=A_i+str(n)
n=random.randint(0,1)
B_b=B_b+str(n)
B_i=B_i+str(n)
n=random.randint(0,1)
C_c=C_c+str(n)
C_i=C_i+str(n)
n=random.randint(0,1)
D_d=D_d+str(n)
D_i=D_i+str(n)
n=random.randint(0,1)
E_e=E_e+str(n)
E_i=E_i+str(n)
K_0="01011010100000100111100110011001" # constant for 1-20 rounds
K_1="01101110110110011110101110100001" # constant for 21-40 rounds
K_2="10001111000110111011110011011100" # constant for 41-60 rounds
K_3="11001010011000101100000111010110" # constant for 61-80 rounds
for j in range(20): #recursive function for 1-20 rounds
TEMP=int(words[j],2)^int(K_0,2)^int(E_e,2)^int(f1(B_b,C_c,D_d),2)^int((A_a[5:32]+A_a[0:4]),2)
temp='{:032b}'.format(TEMP)
E_e=D_d
D_d=C_c
C_c=B_b[30:32]+B_b[0:30]
B_b=A_a
A_a=temp
A_I=int(A_a,2)^int(A_i,2)
A_i='{:032b}'.format(A_I)
B_I=int(B_b,2)^int(B_i,2)
B_i='{:032b}'.format(B_I)
C_I=int(C_c,2)^int(C_i,2)
C_i='{:032b}'.format(C_I)
D_I=int(D_d,2)^int(D_i,2)
D_i='{:032b}'.format(D_I)
E_I=int(E_e,2)^int(E_i,2)
E_i='{:032b}'.format(E_I)
for j in range(20): #recursive function for 21-40 rounds
TEMP=int(words[j],2)^int(K_1,2)^int(E_e,2)^int(f2(B_b,C_c,D_d),2)^int((A_a[5:32]+A_a[0:4]),2)
temp='{:032b}'.format(TEMP)
E_e=D_d
D_d=C_c
C_c=B_b[30:32]+B_b[0:30]
B_b=A_a
A_a=temp
A_I=int(A_a,2)^int(A_i,2)
A_i='{:032b}'.format(A_I)
B_I=int(B_b,2)^int(B_i,2)
B_i='{:032b}'.format(B_I)
C_I=int(C_c,2)^int(C_i,2)
C_i='{:032b}'.format(C_I)
D_I=int(D_d,2)^int(D_i,2)
D_i='{:032b}'.format(D_I)
E_I=int(E_e,2)^int(E_i,2)
E_i='{:032b}'.format(E_I)
for j in range(20): #recursive function for 41-60 rounds
TEMP=int(words[j],2)^int(K_2,2)^int(E_e,2)^int(f3(B_b,C_c,D_d),2)^int((A_a[5:32]+A_a[0:4]),2)
temp='{:032b}'.format(TEMP)
E_e=D_d
D_d=C_c
C_c=B_b[30:32]+B_b[0:30]
B_b=A_a
A_a=temp
A_I=int(A_a,2)^int(A_i,2)
A_i='{:032b}'.format(A_I)
B_I=int(B_b,2)^int(B_i,2)
B_i='{:032b}'.format(B_I)
C_I=int(C_c,2)^int(C_i,2)
C_i='{:032b}'.format(C_I)
D_I=int(D_d,2)^int(D_i,2)
D_i='{:032b}'.format(D_I)
E_I=int(E_e,2)^int(E_i,2)
E_i='{:032b}'.format(E_I)
for j in range(20): #recursive function for 61-80 rounds
TEMP=int(words[j],2)^int(K_3,2)^int(E_e,2)^int(f4(B_b,C_c,D_d),2)^int((A_a[5:32]+A_a[0:4]),2)
temp='{:032b}'.format(TEMP)
E_e=D_d
D_d=C_c
C_c=B_b[30:32]+B_b[0:30]
B_b=A_a
A_a=temp
A_I=int(A_a,2)^int(A_i,2)
A_i='{:032b}'.format(A_I)
B_I=int(B_b,2)^int(B_i,2)
B_i='{:032b}'.format(B_I)
C_I=int(C_c,2)^int(C_i,2)
C_i='{:032b}'.format(C_I)
D_I=int(D_d,2)^int(D_i,2)
D_i='{:032b}'.format(D_I)
E_I=int(E_e,2)^int(E_i,2)
E_i='{:032b}'.format(E_I)
hash=A_i+B_i+C_i+D_i+E_i #total 5*32=160 bits
print("Hash: ",hash)