yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
sha1.cpp
Go to the documentation of this file.
1 /*
2  sha1.cpp - source code of
3 
4  ============
5  SHA-1 in C++
6  ============
7 
8  100% Public Domain.
9 
10  Original C Code
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>
18 */
19 
20 #include "sha1.h"
21 #include <sstream>
22 #include <iomanip>
23 #include <fstream>
24 
25 /* Help macros */
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))
28 
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);
35 
37 {
38  reset();
39 }
40 
41 
42 void SHA1::update(const std::string &s)
43 {
44  std::istringstream is(s);
45  update(is);
46 }
47 
48 
49 void SHA1::update(std::istream &is)
50 {
51  std::string rest_of_buffer;
52  read(is, rest_of_buffer, BLOCK_BYTES - buffer.size());
53  buffer += rest_of_buffer;
54 
55  while (is)
56  {
57  uint32_t block[BLOCK_INTS];
58  buffer_to_block(buffer, block);
59  transform(block);
60  read(is, buffer, BLOCK_BYTES);
61  }
62 }
63 
64 
65 /*
66  * Add padding and return the message digest.
67  */
68 
69 std::string SHA1::final()
70 {
71  /* Total number of hashed bits */
72  uint64_t total_bits = (transforms*BLOCK_BYTES + buffer.size()) * 8;
73 
74  /* Padding */
75  buffer += 0x80;
76  unsigned int orig_size = buffer.size();
77  while (buffer.size() < BLOCK_BYTES)
78  {
79  buffer += (char)0x00;
80  }
81 
82  uint32_t block[BLOCK_INTS];
83  buffer_to_block(buffer, block);
84 
85  if (orig_size > BLOCK_BYTES - 8)
86  {
87  transform(block);
88  for (unsigned int i = 0; i < BLOCK_INTS - 2; i++)
89  {
90  block[i] = 0;
91  }
92  }
93 
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);
97  transform(block);
98 
99  /* Hex std::string */
100  std::ostringstream result;
101  for (unsigned int i = 0; i < DIGEST_INTS; i++)
102  {
103  result << std::hex << std::setfill('0') << std::setw(8);
104  result << (digest[i] & 0xffffffff);
105  }
106 
107  /* Reset for next run */
108  reset();
109 
110  return result.str();
111 }
112 
113 
114 std::string SHA1::from_file(const std::string &filename)
115 {
116  std::ifstream stream(filename.c_str(), std::ios::binary);
117  SHA1 checksum;
118  checksum.update(stream);
119  return checksum.final();
120 }
121 
122 
124 {
125  /* SHA1 initialization constants */
126  digest[0] = 0x67452301;
127  digest[1] = 0xefcdab89;
128  digest[2] = 0x98badcfe;
129  digest[3] = 0x10325476;
130  digest[4] = 0xc3d2e1f0;
131 
132  /* Reset counters */
133  transforms = 0;
134  buffer = "";
135 }
136 
137 
138 /*
139  * Hash a single 512-bit block. This is the core of the algorithm.
140  */
141 
142 void SHA1::transform(uint32_t block[BLOCK_BYTES])
143 {
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];
150 
151 
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);
233 
234  /* Add the working vars back into digest[] */
235  digest[0] += a;
236  digest[1] += b;
237  digest[2] += c;
238  digest[3] += d;
239  digest[4] += e;
240 
241  /* Count the number of transformations */
242  transforms++;
243 }
244 
245 
246 void SHA1::buffer_to_block(const std::string &buffer, uint32_t block[BLOCK_INTS])
247 {
248  /* Convert the std::string (byte buffer) to a uint32_t array (MSB) */
249  for (unsigned int i = 0; i < BLOCK_INTS; i++)
250  {
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;
255  }
256 }
257 
258 
259 void SHA1::read(std::istream &is, std::string &s, size_t max)
260 {
261  char* sbuf = new char[max];
262 
263  is.read(sbuf, max);
264  s.assign(sbuf, is.gcount());
265 
266  delete[] sbuf;
267 }
268 
269 
270 std::string sha1(const std::string &string)
271 {
272  SHA1 checksum;
273  checksum.update(string);
274  return checksum.final();
275 }
#define SHA1_R4(v, w, x, y, z, i)
Definition: sha1.cpp:34
void transform(uint32_t block[BLOCK_BYTES])
Definition: sha1.cpp:142
void reset()
Definition: sha1.cpp:123
static void read(std::istream &is, std::string &s, size_t max)
Definition: sha1.cpp:259
Definition: sha1.h:28
uint32_t digest[DIGEST_INTS]
Definition: sha1.h:42
#define SHA1_R1(v, w, x, y, z, i)
Definition: sha1.cpp:31
static const unsigned int BLOCK_INTS
Definition: sha1.h:39
static const unsigned int DIGEST_INTS
Definition: sha1.h:38
static std::string from_file(const std::string &filename)
Definition: sha1.cpp:114
std::string sha1(const std::string &string)
Definition: sha1.cpp:270
static const unsigned int BLOCK_BYTES
Definition: sha1.h:40
#define SHA1_R0(v, w, x, y, z, i)
Definition: sha1.cpp:30
static void buffer_to_block(const std::string &buffer, uint32_t block[BLOCK_INTS])
Definition: sha1.cpp:246
uint64_t transforms
Definition: sha1.h:44
std::string buffer
Definition: sha1.h:43
std::string final()
Definition: sha1.cpp:69
#define SHA1_R2(v, w, x, y, z, i)
Definition: sha1.cpp:32
SHA1()
Definition: sha1.cpp:36
void update(const std::string &s)
Definition: sha1.cpp:42
#define SHA1_R3(v, w, x, y, z, i)
Definition: sha1.cpp:33