sha256.cpp
Go to the documentation of this file.
1 
11 #include "sha256.hpp"
12 
13 using namespace cryptoTools;
14 
15 
16 // =========================== Standard functions of the specification
17 
18 // Macros are used instead of functions for better performances
19 
20 #define ROTR(n,x) ( ((x)>>(n)) | ((x)<<(32-(n))) )
21 #define SHR(n,x) ((x)>>(n))
22 #define CH(x,y,z) ( ((x)&(y)) ^ ((~x)&(z)) )
23 #define MAJ(x,y,z) ( ((x)&(y)) ^ ((x)&(z)) ^ ((y)&(z)) )
24 #define BIGSIGMA0(x) ( ROTR(2,(x)) ^ ROTR(13,(x)) ^ ROTR(22,(x)) )
25 #define BIGSIGMA1(x) ( ROTR(6,(x)) ^ ROTR(11,(x)) ^ ROTR(25,(x)) )
26 #define SMALLSIGMA0(x) ( ROTR(7,(x)) ^ ROTR(18,(x)) ^ SHR(3,(x)) )
27 #define SMALLSIGMA1(x) ( ROTR(17,(x)) ^ ROTR(19,(x)) ^ SHR(10,(x)) )
28 
29 
30 // ================================================= Constants
31 
32 // The constants to which the internal state must be initialised.
33 uint32_t init256[8] =
34 {
35  0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
36  0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
37 };
38 
39 
40 // The constants to use in each step of the main loop of a round.
41 uint32_t K256[64] =
42 {
43  0x428a2f98 , 0x71374491 , 0xb5c0fbcf , 0xe9b5dba5 ,
44  0x3956c25b , 0x59f111f1 , 0x923f82a4 , 0xab1c5ed5 ,
45  0xd807aa98 , 0x12835b01 , 0x243185be , 0x550c7dc3 ,
46  0x72be5d74 , 0x80deb1fe , 0x9bdc06a7 , 0xc19bf174 ,
47  0xe49b69c1 , 0xefbe4786 , 0x0fc19dc6 , 0x240ca1cc ,
48  0x2de92c6f , 0x4a7484aa , 0x5cb0a9dc , 0x76f988da ,
49  0x983e5152 , 0xa831c66d , 0xb00327c8 , 0xbf597fc7 ,
50  0xc6e00bf3 , 0xd5a79147 , 0x06ca6351 , 0x14292967 ,
51  0x27b70a85 , 0x2e1b2138 , 0x4d2c6dfc , 0x53380d13 ,
52  0x650a7354 , 0x766a0abb , 0x81c2c92e , 0x92722c85 ,
53  0xa2bfe8a1 , 0xa81a664b , 0xc24b8b70 , 0xc76c51a3 ,
54  0xd192e819 , 0xd6990624 , 0xf40e3585 , 0x106aa070 ,
55  0x19a4c116 , 0x1e376c08 , 0x2748774c , 0x34b0bcb5 ,
56  0x391c0cb3 , 0x4ed8aa4a , 0x5b9cca4f , 0x682e6ff3 ,
57  0x748f82ee , 0x78a5636f , 0x84c87814 , 0x8cc70208 ,
58  0x90befffa , 0xa4506ceb , 0xbef9a3f7 , 0xc67178f2
59 };
60 
61 
62 
63 // ================================================== public functions
64 
65 
66 void SHA256::preprocess(std::vector<unsigned char> initialMessage)
67 {
68  // padding the initial message by...
69  l = initialMessage.size()*8;
70  // ... adding 10000000
71  initialMessage.push_back(0x80);
72  // ... adding the correct amount of zeroes
73  unsigned int k = ( (448-(l+8))%512 >= 0) ? (448-(l+8))%512 : 512+(448-(l+8))%512;
74  for (unsigned int i=0; i<k; i+=8)
75  initialMessage.push_back(0x00);
76  // ... and appending the length of the input.
77  initialMessage.push_back((l>>56)%0x100);
78  initialMessage.push_back((l>>48)%0x100);
79  initialMessage.push_back((l>>40)%0x100);
80  initialMessage.push_back((l>>32)%0x100);
81  initialMessage.push_back((l>>24)%0x100);
82  initialMessage.push_back((l>>16)%0x100);
83  initialMessage.push_back((l>>8 )%0x100);
84  initialMessage.push_back(l%0x100);
85  // Turning the initial byte message into a 32words one
86  M.clear();
87  for (unsigned int i=0; i<initialMessage.size() ; i+=4)
88  M.push_back( (initialMessage[i] << 24)
89  | (initialMessage[i+1] << 16)
90  | (initialMessage[i+2] << 8)
91  | initialMessage[i+3] );
92  // initialising the hash values H_i
93  for (unsigned int i=0; i<8; i++)
94  H[i] = init256[i];
95 }
96 
97 
98 
99 void SHA256::round(unsigned int counter)
100 {
101  uint32_t W[64], T1, T2;
102  // initializing the working variables
103  a = H[0]; b = H[1];
104  c = H[2]; d = H[3];
105  e = H[4]; f = H[5];
106  g = H[6]; h = H[7];
107  // loop over the currently processed hash
108  for (unsigned int t=0; t<64; t++)
109  {
110  // preparing the message schedule
111  W[t] = (t<=15) ? M[counter+t] : SMALLSIGMA1(W[t-2]) + W[t-7] + SMALLSIGMA0(W[t-15]) + W[t-16];
112  // Re-assigning the temporary variables
113  T1 = h + BIGSIGMA1(e) + CH(e,f,g) + K256[t] + W[t];
114  T2 = BIGSIGMA0(a) + MAJ(a,b,c) ;
115  h = g; g = f; f = e;
116  e = d + T1;
117  d = c; c = b; b = a;
118  a = T1 + T2;
119  }
120  // computing the ith hash value H[8]
121  H[0] += a; H[1] += b;
122  H[2] += c; H[3] += d;
123  H[4] += e; H[5] += f;
124  H[6] += g; H[7] += h;
125 }
126 
127 
128 void SHA256::hash(std::vector<unsigned char> initialMessage)
129 {
130  preprocess(initialMessage);
131  for (unsigned int counter=0; counter<M.size(); counter+=16)
132  round(counter);
133 }
134 
135 
136 std::vector<uint8_t> SHA256::getHash()
137 {
138  std::vector<uint8_t> digest;
139  for (unsigned int i=0; i<8; i++)
140  {
141  digest.push_back( (H[i]>>24) % 0x100);
142  digest.push_back( (H[i]>>16) % 0x100);
143  digest.push_back( (H[i]>>8) % 0x100);
144  digest.push_back( H[i] % 0x100);
145  }
146  return digest;
147 }
148 
149 
150 std::string SHA256::getType()
151 {
152  return "SHA-256";
153 }
154 
155 
157 {
158  return 256;
159 }
160 
161 #undef ROTR
162 #undef SHR
163 #undef CH
164 #undef MAJ
165 #undef BIGSIGMA0
166 #undef BIGSIGMA1
167 #undef SMALLSIGMA0
168 #undef SMALLSIGMA1