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