Adobe Source Libraries  1.43
sha.hpp
Go to the documentation of this file.
1 /*
2  Copyright 2013 Adobe
3  Distributed under the Boost Software License, Version 1.0.
4  (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 */
6 /**************************************************************************************************/
7 
8 #ifndef ADOBE_SHA_HPP
9 #define ADOBE_SHA_HPP
10 
11 /**************************************************************************************************/
12 
13 #include <array>
14 #include <cassert>
15 #include <cstring>
16 #include <cstdint>
17 #include <iterator>
18 
19 /**************************************************************************************************/
20 
21 namespace adobe {
22 
23 /**************************************************************************************************/
24 
25 namespace implementation {
26 
27 /**************************************************************************************************/
28 
29 #if !defined(ADOBE_NO_DOCUMENTATION)
30 
31 /**************************************************************************************************/
32 
33 template <typename T>
34 constexpr std::size_t bitsizeof() {
35  return sizeof(T) * 8;
36 }
37 
38 /**************************************************************************************************/
39 
40 template <std::size_t N, typename T>
41 inline T shr(T x) {
42  static_assert(N < bitsizeof<T>(), "shr size mismatch.");
43 
44  return x >> N;
45 }
46 
47 template <std::size_t N, typename T>
48 inline T rotr(T x) {
49  static_assert(N < bitsizeof<T>(), "rotr size mismatch.");
50 
51  constexpr std::size_t l_shift = bitsizeof<T>() - N;
52 
53  return (x >> N) | (x << l_shift);
54 }
55 
56 template <std::size_t N, typename T>
57 inline T rotl(T x) {
58  static_assert(N < bitsizeof<T>(), "rotl size mismatch.");
59 
60  constexpr std::size_t r_shift = bitsizeof<T>() - N;
61 
62  return (x << N) | (x >> r_shift);
63 }
64 
65 /**************************************************************************************************/
66 
67 template <typename T>
68 inline T ch(T x, T y, T z) {
69  return (x & y) ^ (~x & z);
70 }
71 
72 template <typename T>
73 inline T parity(T x, T y, T z) {
74  return x ^ y ^ z;
75 }
76 
77 template <typename T>
78 inline T maj(T x, T y, T z) {
79  return (x & y) ^ (x & z) ^ (y & z);
80 }
81 
82 /*
83 A source of bytes. The input is a range defined by two iterators. The length
84 of the range does not need to be known up front. This will work with
85 input iterators.
86 */
87 template <typename I>
88 class byte_source_iterators
89 {
90 public:
91  byte_source_iterators( I const& first, I const& last )
92  : first_( first )
93  , last_( last ) {
94  static_assert(sizeof(typename std::iterator_traits<I>::value_type) == sizeof(std::uint8_t), "Iterator must supply bytes.");
95  }
96 
97  // Note that this returns the number of *bits* available. Even though this
98  // class can only returns complete bytes we need consistency with
99  // byte_source_iterator_n.
100  // The number available is not necessarily the total number, it is just
101  // the number we can get hold of right now.
102  std::size_t bits_available() const {
103  return ( first_ == last_ ) ? 0 : 8;
104  }
105 
106  std::uint8_t operator *() const {
107  return *first_;
108  }
109 
110  // Prefix
111  byte_source_iterators& operator ++() {
112  ++first_;
113  return *this;
114  }
115 
116  // Postfix operator ++ does not work with input iterators so we
117  // do not provide it
118 
119  // Making copies does not work if we are using input iterators so forbid
120  // copy construction and assigment
121  byte_source_iterators( byte_source_iterators const& ) = delete;
122  byte_source_iterators& operator =( byte_source_iterators const& ) = delete;
123 
124 private:
125 
126  I first_;
127  I const last_;
128 };
129 
130 /*
131 A source of bytes. The input is an iterator and the number of *bits* the
132 source can provide. Unlike byte_source_iterators we know the length
133 up front
134 */
135 template <typename I>
136 class byte_source_iterator_n
137 {
138 public:
139  byte_source_iterator_n( I const& first, std::size_t num_bits )
140  : first_( first )
141  , num_bits_( num_bits ) {
142  static_assert(sizeof(typename std::iterator_traits<I>::value_type) == sizeof(std::uint8_t), "Iterator must supply bytes.");
143  }
144 
145  // The last byte might not be complete
146  std::size_t bits_available() const {
147  return ( num_bits_ > 8 ) ? 8 : num_bits_;
148  }
149 
150  std::uint8_t operator *() const {
151  return *first_;
152  }
153 
154  // Prefix
155  byte_source_iterator_n& operator ++() {
156  ++first_;
157  num_bits_ -= bits_available();
158  return *this;
159  }
160 
161  // Postfix operator ++ does not work with input iterators so we
162  // do not provide it
163 
164  // Making copies does not work if we are using input iterators so forbid
165  // copy construction and assigment
166  byte_source_iterator_n( byte_source_iterator_n const& ) = delete;
167  byte_source_iterator_n& operator =( byte_source_iterator_n const& ) = delete;
168 
169 private:
170 
171  I first_;
172  std::size_t num_bits_;
173 };
174 
175 /**************************************************************************************************/
176 
177 template <typename HashTraits, typename ByteSource>
178 std::uint64_t stuff_into_state(typename HashTraits::message_block_type& state,
179  std::uint16_t& stuff_bit_offset, std::size_t num_bits,
180  ByteSource& byte_source) {
181 
182  typedef HashTraits traits_type;
183  typedef typename traits_type::message_block_type::value_type value_type;
184 
185  constexpr std::size_t value_size_k = sizeof(value_type);
186  constexpr std::size_t value_bitsize_k = value_size_k * 8;
187 
188  /*
189  We are given the stuff bit offset in terms of the whole message block. From there we need to
190  derive which element of the array we are going to stuff into, and the shift within that element.
191  Then we stuff bytes from *first, decreasing the internal shift until we hit zero (stuffing from
192  most significant bit to least significant). Then we advance to the next element, reset the shift
193  to far-right, and keep going.
194 
195  For values that come in less than a byte the high bits are where the value is stored, not the
196  low bits.
197  */
198 
199  std::size_t element = stuff_bit_offset / value_bitsize_k;
200  std::size_t shift = value_bitsize_k - 8 - // most sig bit, less bitsizeof(*first)
201  stuff_bit_offset % value_bitsize_k; // bits already stuffed.
202  value_type* dst(&state[element]);
203 
204  /*
205  As soon as we've gone once through this loop, we'll be on a byte boundary. If we don't go
206  through the loop we'll be off a byte boundary and will have to shift the next byte appropriately
207  (it should shift 0 when we've been through this loop, effectively a nop.)
208  */
209 
210  std::uint64_t n_stuffed_bits = 0;
211 
212  while (num_bits >= 8 && byte_source.bits_available() >= 8) {
213  *dst |= (value_type(*byte_source) & value_type(0xff)) << shift;
214 
215  ++byte_source;
216 
217  if (shift == 0) {
218  ++dst;
219 
220  shift = value_bitsize_k - 8;
221  } else {
222  shift -= 8;
223  }
224 
225  stuff_bit_offset += 8;
226  n_stuffed_bits += 8;
227  num_bits -= 8;
228  }
229 
230  // sub-byte leftovers which need to be shifted into place.
231  if (num_bits && byte_source.bits_available()) {
232  num_bits = std::min(num_bits, byte_source.bits_available());
233  /*
234  dst is a window of size value_bitsize_k. The message ends somewhere in the window
235  [ value_bitsize_k .. 1 ], meaning our leftovers get their high order bit pushed to position
236  [ value_bitsize_k - 1 .. 0 ]. Since we know the value is in the low-8-bits of a
237  value_bitsize_k-sized window, we need to shift the value either up or down, depending on
238  where the message ended.
239 
240  message_end is the bit location of the last bit of the message. This can be value_bitsize_k,
241  implying the message ended on the value_type boundary.
242  */
243  std::size_t message_end(value_bitsize_k - (stuff_bit_offset % value_bitsize_k));
244  value_type v(*byte_source & 0xff); // our value in the low 8 bits.
245 
246  ++byte_source;
247 
248  if (message_end < 8) // shift down
249  v >>= 8 - message_end;
250  else if (message_end > 8) // shift up
251  v <<= message_end - 8;
252 
253  *dst |= v;
254  stuff_bit_offset += num_bits;
255  n_stuffed_bits += num_bits;
256  }
257  return n_stuffed_bits;
258 }
259 
260 /**************************************************************************************************/
261 /*
262 We keep a running message block as state, along with info about the total message length to this
263 point, as well as the number of bits stuffed in the current message block. Whenever the user wants
264 to update the message they pass in some data, which we use to stuff the current message block. When
265 that block fills to capacity we digest it and reset the state to prepare to digest the next message
266 block. In the end there is work to be done with whatever data might be left over. In finalize, then,
267 we add the spec'd 1-bit, zero-pad the message if need be, append the length of the message, and
268 digest that final block. The user gets whatever comes out.
269 
270 This routine expects whole-byte input until the end of the message, at which point the remainder of
271 the message can be a subset of 8 bytes. If you're going to be busting up a messages into chunks to
272 hash it, then you need to do so at the byte boundary until the last chunk.
273 */
274 template <typename HashTraits, typename ByteSource>
275 void block_and_digest(typename HashTraits::message_block_type& state, std::uint16_t& stuffed_size,
276  std::uint64_t& message_size, typename HashTraits::state_digest_type& digest,
277  ByteSource& byte_source ) {
278  typedef HashTraits traits_type;
279 
280  // The size of the message block in bits. Either 512 or 1024.
281  constexpr std::size_t message_blocksize_k = traits_type::message_blocksize_k;
282 
283  /*
284  The SHA description has three phases for preparing to digest a message:
285  - padding
286  - parsing (aka blocking)
287  - hash initialization
288 
289  All messages are composed of the following:
290  - the message (length: num_bits bits)
291  - a 1-bit (length: 1 bit)
292  - zero padding (varies)
293  - the number of bits of the message (max_message_bitsize_k bits)
294 
295  This is the padding and blocking phase. Pack the message into 512- or 1024-bit blocks for
296  digest, padding the message out with a varible number of zero bits such that the last message
297  block is also 512- or 1024-bits long. All blocks will be 100% message except for the last block
298  in the digest That last block, then, will be:
299  - zero-or-more bits of message
300  - the 1 bit
301  - zero-or-more bits of zero-bit padding
302  - the length of the message (max_message_bitsize_k bits)
303  */
304  std::size_t bits_available(message_blocksize_k - stuffed_size);
305 
306  while (byte_source.bits_available() > 0) {
307  std::uint64_t const bits_stuffed = stuff_into_state<traits_type>(state, stuffed_size, bits_available, byte_source);
308 
309  // If we have a full message block then digest it
310  if( bits_stuffed == bits_available ) {
311  traits_type::digest_message_block(digest, state, stuffed_size);
312  }
313 
314  message_size += bits_stuffed;
315  bits_available = message_blocksize_k;
316  }
317 }
318 
319 /**************************************************************************************************/
320 
321 template <typename HashTraits>
322 typename HashTraits::digest_type finalize(typename HashTraits::message_block_type& state,
323  std::uint16_t stuffed_size, std::uint64_t message_size,
324  typename HashTraits::state_digest_type& digest) {
325  /*
326  A couple things we have to do in this routine:
327  - add a single 1-bit to the end of the message
328  - pad out the final block to message_blocksize_k bits, less
329  the size of the message
330  - add the size of the message to the end.
331 
332  There are concessions we make for when these three elements cause us to cross over the block
333  boundary, requiring us to digest more than one block as we finalize.
334  */
335 
336  typedef HashTraits traits_type;
337  typedef typename traits_type::message_block_type message_block_type;
338  typedef typename message_block_type::value_type value_type;
339 
340  // Maximum length of message in bits (2^n); this is n. Either 64 or 128.
341  constexpr std::size_t max_message_bitsize_k = traits_type::max_message_bitsize_k;
342  // The size of the message block in bits. Either 512 or 1024.
343  constexpr std::size_t message_blocksize_k = traits_type::message_blocksize_k;
344 
345  constexpr std::size_t value_size_k = sizeof(value_type);
346  constexpr std::size_t value_bitsize_k = value_size_k * 8;
347 
348  /*
349  Stuff into state needs to operate from the assumption that it is taking the most significant
350  bits of a value and stuffing them into the message. As such our 1-bit here needs to be in the
351  MSB, hence 0x80 and not 1.
352  */
353  std::uint8_t one_bit(0x80);
354  std::uint8_t* one_bit_ptr(&one_bit);
355 
356  byte_source_iterator_n< std::uint8_t* > bit_source( one_bit_ptr, 1 );
357  stuff_into_state<traits_type>(state, stuffed_size, 1, bit_source);
358 
359  /*
360  If that one bit pushed us to the message block boundary, congratulations. Digest the message and
361  reset the machine. Do NOT update the message length - the end bit isn't counted as part of the
362  message.
363  */
364  if (stuffed_size == message_blocksize_k)
365  traits_type::digest_message_block(digest, state, stuffed_size);
366 
367  /*
368  Now that we have the last block with (maybe) enough space, find the end and insert the length of
369  the message. Fortunately we have a routine for that.
370 
371  Note that if there is not enough space to insert the length of the message (i.e., offset will be
372  less than stuffed_size) we need to digest the block and try again with an empty one.
373  */
374  constexpr std::size_t length_offset(message_blocksize_k - max_message_bitsize_k);
375 
376  /*
377  The length of the message will always go into message block elements 14 and/or 15. (i.e., the
378  last two.) State block 15 gets the first half of the size, and state block 14 gets the second
379  half.
380 
381  In the event we dont have enough room at the end of the message block to add the length of the
382  message, digest the block as-is (that is, with some amount of zero-padding at the end), then
383  clear it and process another block whose contents are just the length of the message.
384  */
385  if (stuffed_size > length_offset)
386  traits_type::digest_message_block(digest, state, stuffed_size);
387 
388  constexpr value_type value_type_mask = static_cast<value_type>(-1);
389 
390  /*
391  If the message length is longer than what will fit in the last element of the message block,
392  slice the high bits of the length off and stuff them into the next-to-last element. Note that
393  because of the checks above, we are guaranteed the space will be zero-padded, so we can write
394  over it OK.
395 
396  The 15th block requires a shift down of the message size, which in the SHA-512 case is a 64-bit
397  shift of a 64-bit value, which is undefined according to the C++ standard. (This step is were we
398  to store message_size as a 128-bit value, as is allowed by the SHA standard.) As such we derive
399  the overshift boolean and give the compiler the freedom to elide the overshift-and-assignment at
400  compile-time, eliminating the undefined behavior.
401  */
402  constexpr bool overshift = value_bitsize_k >= (sizeof(message_size) * 8);
403 
404  if (!overshift && message_size > value_type_mask)
405  state[14] = (message_size >> value_bitsize_k) & value_type_mask;
406 
407  state[15] = message_size & value_type_mask;
408 
409  // Digest the final block of this message.
410  traits_type::digest_message_block(digest, state, stuffed_size);
411 
412  /*
413  Once the finalized block(s) have been digested, copy the result to the digest type and get outta
414  here. Note that this could crop the number of bits between the state digest and the resulting
415  digest, depending on the requirements of the hash algorithm being used.
416  */
417  typedef typename HashTraits::digest_type digest_type;
418 
419  digest_type result = {{0}};
420 
421  std::memcpy(&result[0], &digest[0], sizeof(digest_type));
422 
423  return result;
424 }
425 
426 /**************************************************************************************************/
427 
428 template <typename HashTraits>
429 void sha_2_digest_message_block(typename HashTraits::state_digest_type& digest,
430  typename HashTraits::message_block_type& message_block,
431  std::uint16_t& stuffed_size) {
432  /*
433  The "sha_2" in the name of this function is in reference to the second generation of SHA
434  algorithms (224, 256, 384, and 512), all of which have the same message block process
435  implementation.
436  */
437 
438  typedef HashTraits traits_type;
439  typedef typename traits_type::message_block_type message_block_type;
440  typedef typename traits_type::schedule_type schedule_type;
441  typedef typename traits_type::state_digest_type::value_type digest_value_type;
442 
443  schedule_type schedule;
444 
445  std::copy(message_block.begin(), message_block.end(), &schedule[0]);
446 
447  for (std::size_t t(message_block.size()); t < schedule.size(); ++t)
448  schedule[t] = traits_type::small_sigma_1(schedule[t - 2]) + schedule[t - 7] +
449  traits_type::small_sigma_0(schedule[t - 15]) + schedule[t - 16];
450 
451  digest_value_type a(digest[0]);
452  digest_value_type b(digest[1]);
453  digest_value_type c(digest[2]);
454  digest_value_type d(digest[3]);
455  digest_value_type e(digest[4]);
456  digest_value_type f(digest[5]);
457  digest_value_type g(digest[6]);
458  digest_value_type h(digest[7]);
459 
460  for (std::size_t t(0); t < schedule.size(); ++t) {
461  digest_value_type T1 = h + traits_type::big_sigma_1(e) + implementation::ch(e, f, g) +
462  traits_type::k(t) + schedule[t];
463  digest_value_type T2 = traits_type::big_sigma_0(a) + implementation::maj(a, b, c);
464  h = g;
465  g = f;
466  f = e;
467  e = d + T1;
468  d = c;
469  c = b;
470  b = a;
471  a = T1 + T2;
472  }
473 
474  digest[0] += a;
475  digest[1] += b;
476  digest[2] += c;
477  digest[3] += d;
478  digest[4] += e;
479  digest[5] += f;
480  digest[6] += g;
481  digest[7] += h;
482 
483  // clears potentially sensitive information
484  schedule = {{0}};
485 
486  // reset the state machine to digest the upcoming block
487  message_block = {{0}};
488  stuffed_size = 0;
489 }
490 
491 /**************************************************************************************************/
492 
493 struct sha1_traits_t {
494  typedef std::array<std::uint32_t, 5> state_digest_type;
495  typedef std::array<std::uint32_t, 16> message_block_type;
496  typedef std::array<std::uint32_t, 80> schedule_type;
497  typedef state_digest_type digest_type;
498 
499  static constexpr std::size_t max_message_bitsize_k = 64;
500  static constexpr std::size_t message_blocksize_k = 512;
501 
502  static constexpr state_digest_type initial_state() {
503  return {{0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0}};
504  }
505 
506  static inline void digest_message_block(state_digest_type& digest,
507  message_block_type& message_block,
508  std::uint16_t& stuffed_size) {
509  typedef typename schedule_type::value_type schedule_word;
510 
511  schedule_type schedule;
512  constexpr std::uint_fast8_t schedule_size = schedule.size();
513 
514  std::memcpy(&schedule[0], &message_block[0], sizeof(message_block_type));
515 
516  for (std::size_t t(message_block.size()); t < schedule_size; ++t)
517  schedule[t] = implementation::rotl<1>(schedule[t - 3] ^ schedule[t - 8] ^
518  schedule[t - 14] ^ schedule[t - 16]);
519 
520  std::uint32_t a(digest[0]);
521  std::uint32_t b(digest[1]);
522  std::uint32_t c(digest[2]);
523  std::uint32_t d(digest[3]);
524  std::uint32_t e(digest[4]);
525  std::uint32_t T(0);
526 
527 // Manually unrolling the loop in this fasion
528 // improves the digest speed by about 20%.
529 
530 #define A_ROUND(t, F, k) \
531  T = implementation::rotl<5>(a) + F(b, c, d) + e + std::uint32_t(k) + schedule[t]; \
532  e = d; \
533  d = c; \
534  c = implementation::rotl<30>(b); \
535  b = a; \
536  a = T
537 
538 #define FIVE_ROUNDS(t, F, k) \
539  A_ROUND((t + 0), F, k); \
540  A_ROUND((t + 1), F, k); \
541  A_ROUND((t + 2), F, k); \
542  A_ROUND((t + 3), F, k); \
543  A_ROUND((t + 4), F, k)
544 
545 #define TWENTY_ROUNDS(t, F, k) \
546  FIVE_ROUNDS((t + 0), F, k); \
547  FIVE_ROUNDS((t + 5), F, k); \
548  FIVE_ROUNDS((t + 10), F, k); \
549  FIVE_ROUNDS((t + 15), F, k)
550 
551  TWENTY_ROUNDS(0, implementation::ch, 0x5a827999);
552  TWENTY_ROUNDS(20, implementation::parity, 0x6ed9eba1);
553  TWENTY_ROUNDS(40, implementation::maj, 0x8f1bbcdc);
554  TWENTY_ROUNDS(60, implementation::parity, 0xca62c1d6);
555 
556  digest[0] += a;
557  digest[1] += b;
558  digest[2] += c;
559  digest[3] += d;
560  digest[4] += e;
561 
562  // clears potentially sensitive information
563  schedule = {{0}};
564 
565  // reset the state machine to digest the upcoming block
566  message_block = {{0}};
567  stuffed_size = 0;
568  }
569 };
570 
571 /**************************************************************************************************/
572 
573 struct sha256_traits_t {
574  typedef std::array<std::uint32_t, 8> state_digest_type;
575  typedef std::array<std::uint32_t, 16> message_block_type;
576  typedef std::array<std::uint32_t, 64> schedule_type;
577  typedef state_digest_type digest_type;
578 
579  static constexpr std::size_t max_message_bitsize_k = 64;
580  static constexpr std::size_t message_blocksize_k = 512;
581 
582  static constexpr state_digest_type initial_state() {
583  return {{0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
584  0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}};
585  }
586 
587  static inline void digest_message_block(state_digest_type& digest,
588  message_block_type& message_block,
589  std::uint16_t& stuffed_size) {
590  sha_2_digest_message_block<sha256_traits_t>(digest, message_block, stuffed_size);
591  }
592 
593  static inline std::uint32_t big_sigma_0(std::uint32_t x) {
594  return implementation::rotr<2>(x) ^ implementation::rotr<13>(x) ^
595  implementation::rotr<22>(x);
596  }
597 
598  static inline std::uint32_t big_sigma_1(std::uint32_t x) {
599  return implementation::rotr<6>(x) ^ implementation::rotr<11>(x) ^
600  implementation::rotr<25>(x);
601  }
602 
603  static inline std::uint32_t small_sigma_0(std::uint32_t x) {
604  return implementation::rotr<7>(x) ^ implementation::rotr<18>(x) ^ implementation::shr<3>(x);
605  }
606 
607  static inline std::uint32_t small_sigma_1(std::uint32_t x) {
608  return implementation::rotr<17>(x) ^ implementation::rotr<19>(x) ^
609  implementation::shr<10>(x);
610  }
611 
612  static inline std::uint32_t k(std::size_t t) {
613  static const std::uint32_t k_set[] = {
614  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4,
615  0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe,
616  0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f,
617  0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
618  0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
619  0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
620  0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116,
621  0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
622  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7,
623  0xc67178f2};
624 
625  assert(t < 64);
626 
627  return k_set[t];
628  }
629 };
630 
631 /**************************************************************************************************/
632 
633 struct sha224_traits_t : public sha256_traits_t {
634  typedef std::array<std::uint32_t, 7> digest_type;
635 
636  static constexpr state_digest_type initial_state() {
637  return {{0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
638  0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4}};
639  }
640 };
641 
642 /**************************************************************************************************/
643 
644 struct sha512_traits_t {
645  typedef std::array<std::uint64_t, 8> state_digest_type;
646  typedef std::array<std::uint64_t, 16> message_block_type;
647  typedef std::array<std::uint64_t, 80> schedule_type;
648  typedef state_digest_type digest_type;
649 
650  static constexpr std::size_t max_message_bitsize_k = 128;
651  static constexpr std::size_t message_blocksize_k = 1024;
652 
653  static constexpr state_digest_type initial_state() {
654  return {{0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
655  0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
656  0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL}};
657  }
658 
659  static inline void digest_message_block(state_digest_type& digest,
660  message_block_type& message_block,
661  std::uint16_t& stuffed_size) {
662  sha_2_digest_message_block<sha512_traits_t>(digest, message_block, stuffed_size);
663  }
664 
665  static inline std::uint64_t big_sigma_0(std::uint64_t x) {
666  return implementation::rotr<28>(x) ^ implementation::rotr<34>(x) ^
667  implementation::rotr<39>(x);
668  }
669 
670  static inline std::uint64_t big_sigma_1(std::uint64_t x) {
671  return implementation::rotr<14>(x) ^ implementation::rotr<18>(x) ^
672  implementation::rotr<41>(x);
673  }
674 
675  static inline std::uint64_t small_sigma_0(std::uint64_t x) {
676  return implementation::rotr<1>(x) ^ implementation::rotr<8>(x) ^ implementation::shr<7>(x);
677  }
678 
679  static inline std::uint64_t small_sigma_1(std::uint64_t x) {
680  return implementation::rotr<19>(x) ^ implementation::rotr<61>(x) ^
681  implementation::shr<6>(x);
682  }
683 
684  static inline std::uint64_t k(std::size_t t) {
685  static const std::uint64_t k_set[] = {
686  0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
687  0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
688  0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
689  0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
690  0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
691  0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
692  0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
693  0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
694  0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
695  0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
696  0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
697  0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
698  0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
699  0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
700  0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
701  0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
702  0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
703  0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
704  0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
705  0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
706  0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
707  0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
708  0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
709  0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
710  0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
711  0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
712  0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL};
713 
714  assert(t < 80);
715 
716  return k_set[t];
717  }
718 };
719 
720 /**************************************************************************************************/
721 
722 struct sha384_traits_t : public sha512_traits_t {
723  typedef std::array<std::uint64_t, 6> digest_type;
724 
725  static constexpr state_digest_type initial_state() {
726  return {{0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL,
727  0x152fecd8f70e5939ULL, 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
728  0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL}};
729  }
730 };
731 
732 /**************************************************************************************************/
733 
734 #endif
735 
736 /**************************************************************************************************/
737 
738 } // namespace implementation
739 
740 /**************************************************************************************************/
756 template <class Traits>
757 class sha {
758 public:
759 #if !defined(ADOBE_NO_DOCUMENTATION)
760  typedef Traits traits_type;
761 #endif
762 
771  typedef typename traits_type::digest_type digest_type;
772 
778  sha()
779  : message_size_m(0), state_m({{0}}), state_digest_m(traits_type::initial_state()),
780  stuffed_size_m(0) {}
781 
800  template <typename I>
801  inline void update(I first, I last) {
802  // We can only update if the current state is byte aligned
803  assert(stuffed_size_m % 8 == 0);
804 
805  implementation::byte_source_iterators< I > byte_source(first, last);
806  implementation::block_and_digest<traits_type>(state_m, stuffed_size_m, message_size_m,
807  state_digest_m, byte_source);
808  }
809 
828  template <typename I>
829  inline void update(I first, std::uint64_t num_bits) {
830  // We can only update if the current state is byte aligned
831  assert(stuffed_size_m % 8 == 0);
832 
833  implementation::byte_source_iterator_n< I > byte_source(first, num_bits);
834  implementation::block_and_digest<traits_type>(state_m, stuffed_size_m, message_size_m,
835  state_digest_m, byte_source);
836  }
837 
843  inline digest_type finalize() {
844  std::uint64_t message_size(message_size_m);
845  typename traits_type::message_block_type state(state_m);
846  typename traits_type::state_digest_type state_digest(state_digest_m);
847  std::uint16_t stuffed_size(stuffed_size_m);
848 
849  return implementation::finalize<traits_type>(state, stuffed_size, message_size,
850  state_digest);
851  }
852 
868  template <typename I>
869  static inline digest_type digest(I first, I last) {
870  sha instance;
871 
872  instance.update(first, last);
873 
874  return instance.finalize();
875  }
876 
891  template <typename I>
892  static inline digest_type digest(I first, std::uint64_t num_bits) {
893  sha instance;
894 
895  instance.update(first, num_bits);
896 
897  return instance.finalize();
898  }
899 
907  static std::string to_string(const typename traits_type::digest_type& digest,
908  bool spaces = false) {
909  typedef typename traits_type::digest_type::value_type value_type;
910 
911  constexpr const char* lut_k = "0123456789abcdef";
912  constexpr std::size_t size_k = sizeof(value_type);
913  constexpr std::size_t bitsize_k = implementation::bitsizeof<value_type>();
914 
915  bool first(true);
916  std::string result;
917 
918  for (const auto& element : digest) {
919  if (!first && spaces)
920  result += ' ';
921 
922  first = false;
923 
924  for (std::size_t i(0); i < size_k; ++i) {
925  // shifting instead of a char* pointer walk avoids endian issues
926  char c((element >> (bitsize_k - (i + 1) * 8)) & 0xff);
927  char hi(lut_k[(c >> 4) & 0xf]);
928  char lo(lut_k[c & 0xf]);
929 
930  result += hi;
931  result += lo;
932  }
933  }
934 
935  return result;
936  }
937 
938  inline std::string to_string(bool spaces = false) { return to_string(finalize(), spaces); }
939 
940 #ifndef ADOBE_NO_DOCUMENTATION
941 private:
942  // ordered to try and maximize fastest cache alignment. This
943  // could be improved.
944  std::uint64_t message_size_m;
945  typename traits_type::message_block_type state_m;
946  typename traits_type::state_digest_type state_digest_m;
947  std::uint16_t stuffed_size_m;
948 #endif
949 };
950 
951 /**************************************************************************************************/
952 
960 
968 
976 
984 
992 
993 /**************************************************************************************************/
994 
995 } // namespace adobe
996 
997 /**************************************************************************************************/
998 
999 #endif
1000 
1001 /**************************************************************************************************/
static std::string to_string(const typename traits_type::digest_type &digest, bool spaces=false)
Definition: sha.hpp:907
sha< implementation::sha384_traits_t > sha384_t
A bit-oriented implementation of the SHA-384 Secure Hash Algorithm.
Definition: sha.hpp:983
void update(I first, std::uint64_t num_bits)
Definition: sha.hpp:829
sha< implementation::sha224_traits_t > sha224_t
A bit-oriented implementation of the SHA-224 Secure Hash Algorithm.
Definition: sha.hpp:967
traits_type::digest_type digest_type
Definition: sha.hpp:771
static digest_type digest(I first, std::uint64_t num_bits)
Definition: sha.hpp:892
digest_type finalize()
Definition: sha.hpp:843
sha< implementation::sha1_traits_t > sha1_t
A bit-oriented implementation of the SHA-1 Secure Hash Algorithm.
Definition: sha.hpp:959
std::string to_string(bool spaces=false)
Definition: sha.hpp:938
void update(I first, I last)
Definition: sha.hpp:801
sha< implementation::sha512_traits_t > sha512_t
A bit-oriented implementation of the SHA-512 Secure Hash Algorithm.
Definition: sha.hpp:991
sha< implementation::sha256_traits_t > sha256_t
A bit-oriented implementation of the SHA-256 Secure Hash Algorithm.
Definition: sha.hpp:975
static digest_type digest(I first, I last)
Definition: sha.hpp:869