sha512.cpp
Go to the documentation of this file.
1 
11 #include "sha512.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)<<(64-(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(28,(x)) ^ ROTR(34,(x)) ^ ROTR(39,(x)) )
25 #define BIGSIGMA1(x) ( ROTR(14,(x)) ^ ROTR(18,(x)) ^ ROTR(41,(x)) )
26 #define SMALLSIGMA0(x) ( ROTR(1,(x)) ^ ROTR(8,(x)) ^ SHR(7,(x)) )
27 #define SMALLSIGMA1(x) ( ROTR(19,(x)) ^ ROTR(61,(x)) ^ SHR(6,(x)) )
28 
29 
30 // ================================================= Constants
31 
32 // The constants to which the internal state must be initialised.
33 uint64_t init512[8] =
34 {
35  0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b,
36  0xa54ff53a5f1d36f1, 0x510e527fade682d1, 0x9b05688c2b3e6c1f,
37  0x1f83d9abfb41bd6b, 0x5be0cd19137e2179
38 };
39 
40 
41 // The constants to use in each step of the main loop of a round.
42 uint64_t K512[80] =
43 {
44  0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
45  0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
46  0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
47  0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
48  0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
49  0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
50  0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275,
51  0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
52  0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f,
53  0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
54  0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc,
55  0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
56  0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6,
57  0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001,
58  0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
59  0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
60  0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99,
61  0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
62  0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc,
63  0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
64  0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915,
65  0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207,
66  0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba,
67  0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
68  0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
69  0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
70  0x5fcb6fab3ad6faec, 0x6c44198c4a475817
71 };
72 
73 
74 
75 // ================================================== public functions
76 
77 
78 void SHA512::preprocess(std::vector<unsigned char> initialMessage)
79 {
80  // padding the initial message by...
81  l = initialMessage.size()*8;
82  // ... adding 10000000
83  initialMessage.push_back(0x80);
84  // ... adding the correct amount of zeroes
85  unsigned int k = ( (896-(l+8))%1024 >= 0) ? (896-(l+8))%1024 :1024+(960-(l+8))%1024;
86  k += 64; // Adding 64 bits to zero: we don't treat cases where l>2^64
87  for (unsigned int i=0; i<k; i+=8)
88  initialMessage.push_back(0x00);
89  // ... and appending the length of the input.
90  initialMessage.push_back((l>>56)%0x100);
91  initialMessage.push_back((l>>48)%0x100);
92  initialMessage.push_back((l>>40)%0x100);
93  initialMessage.push_back((l>>32)%0x100);
94  initialMessage.push_back((l>>24)%0x100);
95  initialMessage.push_back((l>>16)%0x100);
96  initialMessage.push_back((l>>8 )%0x100);
97  initialMessage.push_back(l%0x100);
98  // Turning the initial byte message into a 32words one
99  M.clear();
100  for (unsigned int i=0; i<initialMessage.size() ; i+=8)
101  M.push_back( ((uint64_t)initialMessage[i] << 56)
102  | ((uint64_t)initialMessage[i+1] << 48)
103  | ((uint64_t)initialMessage[i+2] << 40)
104  | ((uint64_t)initialMessage[i+3] << 32)
105  | ((uint64_t)initialMessage[i+4] << 24)
106  | ((uint64_t)initialMessage[i+5] << 16)
107  | ((uint64_t)initialMessage[i+6] << 8)
108  | (uint64_t)initialMessage[i+7] );
109  // initialising the hash values H_i
110  for (unsigned int i=0; i<8; i++)
111  H[i] = init512[i];
112 }
113 
114 
115 
116 void SHA512::round(unsigned int counter)
117 {
118  uint64_t W[80], T1, T2;
119  // initializing the working variables
120  a = H[0]; b = H[1];
121  c = H[2]; d = H[3];
122  e = H[4]; f = H[5];
123  g = H[6]; h = H[7];
124  // loop over the currently processed hash
125  for (unsigned int t=0; t<80; t++)
126  {
127  // preparing the message schedule
128  W[t] = (t<=15) ? M[counter+t] : SMALLSIGMA1(W[t-2]) + W[t-7] + SMALLSIGMA0(W[t-15]) + W[t-16];
129  // Re-assigning the temporary variables
130  T1 = h + BIGSIGMA1(e) + CH(e,f,g) + K512[t] + W[t];
131  T2 = BIGSIGMA0(a) + MAJ(a,b,c) ;
132  h = g; g = f; f = e;
133  e = d + T1;
134  d = c; c = b; b = a;
135  a = T1 + T2;
136  }
137  // computing the ith hash value H[8]
138  H[0] += a; H[1] += b;
139  H[2] += c; H[3] += d;
140  H[4] += e; H[5] += f;
141  H[6] += g; H[7] += h;
142 }
143 
144 
145 void SHA512::hash(std::vector<unsigned char> initialMessage)
146 {
147  preprocess(initialMessage);
148  for (unsigned int counter=0; counter<M.size(); counter+=16)
149  round(counter);
150 }
151 
152 
153 std::vector<uint8_t> SHA512::getHash()
154 {
155  std::vector<uint8_t> digest;
156  for (unsigned int i=0; i<8; i++)
157  {
158  digest.push_back( (H[i]>>56) % 0x100);
159  digest.push_back( (H[i]>>48) % 0x100);
160  digest.push_back( (H[i]>>40) % 0x100);
161  digest.push_back( (H[i]>>32) % 0x100);
162  digest.push_back( (H[i]>>24) % 0x100);
163  digest.push_back( (H[i]>>16) % 0x100);
164  digest.push_back( (H[i]>>8) % 0x100);
165  digest.push_back( H[i] % 0x100);
166  }
167  return digest;
168 }
169 
170 
171 std::string SHA512::getType()
172 {
173  return "SHA-512";
174 }
175 
176 
178 {
179  return 512;
180 }
181 
182 #undef ROTR
183 #undef SHR
184 #undef CH
185 #undef MAJ
186 #undef BIGSIGMA0
187 #undef BIGSIGMA1
188 #undef SMALLSIGMA0
189 #undef SMALLSIGMA1