2 sha1.cpp - source code of
11 -- Steve Reid <steve@edmweb.com>
12 Small changes to fit into bglibs
13 -- Bruce Guenter <bruce@untroubled.org>
14 Translation to simpler C++ Code
15 -- Volker Grabsch <vog@notjusthosting.com>
16 Fixing bugs and improving style
17 -- Eugene Hopkinson <slowriot at voxelstorm dot com>
26 #define SHA1_ROL(value, bits) (((value) << (bits)) | (((value) & 0xffffffff) >> (32 - (bits))))
27 #define SHA1_BLK(i) (block[i&15] = SHA1_ROL(block[(i+13)&15] ^ block[(i+8)&15] ^ block[(i+2)&15] ^ block[i&15],1))
29 /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
30 #define SHA1_R0(v,w,x,y,z,i) z += ((w&(x^y))^y) + block[i] + 0x5a827999 + SHA1_ROL(v,5); w=SHA1_ROL(w,30);
31 #define SHA1_R1(v,w,x,y,z,i) z += ((w&(x^y))^y) + SHA1_BLK(i) + 0x5a827999 + SHA1_ROL(v,5); w=SHA1_ROL(w,30);
32 #define SHA1_R2(v,w,x,y,z,i) z += (w^x^y) + SHA1_BLK(i) + 0x6ed9eba1 + SHA1_ROL(v,5); w=SHA1_ROL(w,30);
33 #define SHA1_R3(v,w,x,y,z,i) z += (((w|x)&y)|(w&x)) + SHA1_BLK(i) + 0x8f1bbcdc + SHA1_ROL(v,5); w=SHA1_ROL(w,30);
34 #define SHA1_R4(v,w,x,y,z,i) z += (w^x^y) + SHA1_BLK(i) + 0xca62c1d6 + SHA1_ROL(v,5); w=SHA1_ROL(w,30);
42 void SHA1::update(const std::string
&s
)
44 std::istringstream
is(s
);
49 void SHA1::update(std::istream
&is
)
51 std::string rest_of_buffer
;
52 read(is
, rest_of_buffer
, BLOCK_BYTES
- buffer
.size());
53 buffer
+= rest_of_buffer
;
57 uint32_t block
[BLOCK_INTS
];
58 buffer_to_block(buffer
, block
);
60 read(is
, buffer
, BLOCK_BYTES
);
66 * Add padding and return the message digest.
69 std::string
SHA1::final()
71 /* Total number of hashed bits */
72 uint64_t total_bits
= (transforms
*BLOCK_BYTES
+ buffer
.size()) * 8;
76 unsigned int orig_size
= buffer
.size();
77 while (buffer
.size() < BLOCK_BYTES
)
82 uint32_t block
[BLOCK_INTS
];
83 buffer_to_block(buffer
, block
);
85 if (orig_size
> BLOCK_BYTES
- 8)
88 for (unsigned int i
= 0; i
< BLOCK_INTS
- 2; i
++)
94 /* Append total_bits, split this uint64_t into two uint32_t */
95 block
[BLOCK_INTS
- 1] = total_bits
;
96 block
[BLOCK_INTS
- 2] = (total_bits
>> 32);
100 std::ostringstream result
;
101 for (unsigned int i
= 0; i
< DIGEST_INTS
; i
++)
103 result
<< std::hex
<< std::setfill('0') << std::setw(8);
104 result
<< (digest
[i
] & 0xffffffff);
107 /* Reset for next run */
114 std::string
SHA1::from_file(const std::string
&filename
)
116 std::ifstream
stream(filename
.c_str(), std::ios::binary
);
118 checksum
.update(stream
);
119 return checksum
.final();
125 /* SHA1 initialization constants */
126 digest
[0] = 0x67452301;
127 digest
[1] = 0xefcdab89;
128 digest
[2] = 0x98badcfe;
129 digest
[3] = 0x10325476;
130 digest
[4] = 0xc3d2e1f0;
139 * Hash a single 512-bit block. This is the core of the algorithm.
142 void SHA1::transform(uint32_t block
[BLOCK_BYTES
])
144 /* Copy digest[] to working vars */
145 uint32_t a
= digest
[0];
146 uint32_t b
= digest
[1];
147 uint32_t c
= digest
[2];
148 uint32_t d
= digest
[3];
149 uint32_t e
= digest
[4];
152 /* 4 rounds of 20 operations each. Loop unrolled. */
153 SHA1_R0(a
,b
,c
,d
,e
, 0);
154 SHA1_R0(e
,a
,b
,c
,d
, 1);
155 SHA1_R0(d
,e
,a
,b
,c
, 2);
156 SHA1_R0(c
,d
,e
,a
,b
, 3);
157 SHA1_R0(b
,c
,d
,e
,a
, 4);
158 SHA1_R0(a
,b
,c
,d
,e
, 5);
159 SHA1_R0(e
,a
,b
,c
,d
, 6);
160 SHA1_R0(d
,e
,a
,b
,c
, 7);
161 SHA1_R0(c
,d
,e
,a
,b
, 8);
162 SHA1_R0(b
,c
,d
,e
,a
, 9);
163 SHA1_R0(a
,b
,c
,d
,e
,10);
164 SHA1_R0(e
,a
,b
,c
,d
,11);
165 SHA1_R0(d
,e
,a
,b
,c
,12);
166 SHA1_R0(c
,d
,e
,a
,b
,13);
167 SHA1_R0(b
,c
,d
,e
,a
,14);
168 SHA1_R0(a
,b
,c
,d
,e
,15);
169 SHA1_R1(e
,a
,b
,c
,d
,16);
170 SHA1_R1(d
,e
,a
,b
,c
,17);
171 SHA1_R1(c
,d
,e
,a
,b
,18);
172 SHA1_R1(b
,c
,d
,e
,a
,19);
173 SHA1_R2(a
,b
,c
,d
,e
,20);
174 SHA1_R2(e
,a
,b
,c
,d
,21);
175 SHA1_R2(d
,e
,a
,b
,c
,22);
176 SHA1_R2(c
,d
,e
,a
,b
,23);
177 SHA1_R2(b
,c
,d
,e
,a
,24);
178 SHA1_R2(a
,b
,c
,d
,e
,25);
179 SHA1_R2(e
,a
,b
,c
,d
,26);
180 SHA1_R2(d
,e
,a
,b
,c
,27);
181 SHA1_R2(c
,d
,e
,a
,b
,28);
182 SHA1_R2(b
,c
,d
,e
,a
,29);
183 SHA1_R2(a
,b
,c
,d
,e
,30);
184 SHA1_R2(e
,a
,b
,c
,d
,31);
185 SHA1_R2(d
,e
,a
,b
,c
,32);
186 SHA1_R2(c
,d
,e
,a
,b
,33);
187 SHA1_R2(b
,c
,d
,e
,a
,34);
188 SHA1_R2(a
,b
,c
,d
,e
,35);
189 SHA1_R2(e
,a
,b
,c
,d
,36);
190 SHA1_R2(d
,e
,a
,b
,c
,37);
191 SHA1_R2(c
,d
,e
,a
,b
,38);
192 SHA1_R2(b
,c
,d
,e
,a
,39);
193 SHA1_R3(a
,b
,c
,d
,e
,40);
194 SHA1_R3(e
,a
,b
,c
,d
,41);
195 SHA1_R3(d
,e
,a
,b
,c
,42);
196 SHA1_R3(c
,d
,e
,a
,b
,43);
197 SHA1_R3(b
,c
,d
,e
,a
,44);
198 SHA1_R3(a
,b
,c
,d
,e
,45);
199 SHA1_R3(e
,a
,b
,c
,d
,46);
200 SHA1_R3(d
,e
,a
,b
,c
,47);
201 SHA1_R3(c
,d
,e
,a
,b
,48);
202 SHA1_R3(b
,c
,d
,e
,a
,49);
203 SHA1_R3(a
,b
,c
,d
,e
,50);
204 SHA1_R3(e
,a
,b
,c
,d
,51);
205 SHA1_R3(d
,e
,a
,b
,c
,52);
206 SHA1_R3(c
,d
,e
,a
,b
,53);
207 SHA1_R3(b
,c
,d
,e
,a
,54);
208 SHA1_R3(a
,b
,c
,d
,e
,55);
209 SHA1_R3(e
,a
,b
,c
,d
,56);
210 SHA1_R3(d
,e
,a
,b
,c
,57);
211 SHA1_R3(c
,d
,e
,a
,b
,58);
212 SHA1_R3(b
,c
,d
,e
,a
,59);
213 SHA1_R4(a
,b
,c
,d
,e
,60);
214 SHA1_R4(e
,a
,b
,c
,d
,61);
215 SHA1_R4(d
,e
,a
,b
,c
,62);
216 SHA1_R4(c
,d
,e
,a
,b
,63);
217 SHA1_R4(b
,c
,d
,e
,a
,64);
218 SHA1_R4(a
,b
,c
,d
,e
,65);
219 SHA1_R4(e
,a
,b
,c
,d
,66);
220 SHA1_R4(d
,e
,a
,b
,c
,67);
221 SHA1_R4(c
,d
,e
,a
,b
,68);
222 SHA1_R4(b
,c
,d
,e
,a
,69);
223 SHA1_R4(a
,b
,c
,d
,e
,70);
224 SHA1_R4(e
,a
,b
,c
,d
,71);
225 SHA1_R4(d
,e
,a
,b
,c
,72);
226 SHA1_R4(c
,d
,e
,a
,b
,73);
227 SHA1_R4(b
,c
,d
,e
,a
,74);
228 SHA1_R4(a
,b
,c
,d
,e
,75);
229 SHA1_R4(e
,a
,b
,c
,d
,76);
230 SHA1_R4(d
,e
,a
,b
,c
,77);
231 SHA1_R4(c
,d
,e
,a
,b
,78);
232 SHA1_R4(b
,c
,d
,e
,a
,79);
234 /* Add the working vars back into digest[] */
241 /* Count the number of transformations */
246 void SHA1::buffer_to_block(const std::string
&buffer
, uint32_t block
[BLOCK_INTS
])
248 /* Convert the std::string (byte buffer) to a uint32_t array (MSB) */
249 for (unsigned int i
= 0; i
< BLOCK_INTS
; i
++)
251 block
[i
] = (buffer
[4*i
+3] & 0xff)
252 | (buffer
[4*i
+2] & 0xff)<<8
253 | (buffer
[4*i
+1] & 0xff)<<16
254 | (buffer
[4*i
+0] & 0xff)<<24;
259 void SHA1::read(std::istream
&is
, std::string
&s
, size_t max
)
261 char* sbuf
= new char[max
];
264 s
.assign(sbuf
, is
.gcount());
270 std::string
sha1(const std::string
&string
)
273 checksum
.update(string
);
274 return checksum
.final();