stlab.adobe.com Adobe Systems Incorporated
sha.hpp
Go to the documentation of this file.
1 /*
2  Copyright 2005-2007 Adobe Systems Incorporated
3  Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
4  or a copy at http://stlab.adobe.com/licenses.html)
5 */
6 
7 /*************************************************************************************************/
8 
9 #ifndef ADOBE_SHA_HPP
10 #define ADOBE_SHA_HPP
11 
12 /*************************************************************************************************/
13 
14 #include <adobe/config.hpp>
15 
16 #include <boost/array.hpp>
17 #include <boost/cstdint.hpp>
18 #include <boost/static_assert.hpp>
19 
20 #include <stdexcept>
21 #include <limits>
22 #include <cstring>
23 
24 /*************************************************************************************************/
25 
26 namespace adobe {
27 
222 /*************************************************************************************************/
223 
224 class sha1_t;
225 class sha224_t;
226 class sha256_t;
227 class sha384_t;
228 class sha512_t;
229 
230 /*************************************************************************************************/
231 
232 namespace implementation {
233 
234 /*************************************************************************************************/
235 
236 #if !defined(ADOBE_NO_DOCUMENTATION)
237 
238 /*************************************************************************************************/
239 
240 template <typename HashT>
241 struct sha_traits;
242 
243 /*************************************************************************************************/
244 
245 template <typename I> // I models InputIterator
246 inline boost::uint64_t long_distance(I first, I last)
247 {
248  boost::uint64_t result(0);
249 
250  while (first != last)
251  {
252  ++result;
253 
254  ++first;
255  }
256 
257  return result;
258 }
259 
260 /*************************************************************************************************/
261 
262 template <typename I> // I models InputIterator
263 struct bit_packer
264 {
265  typedef typename std::iterator_traits<I>::value_type value_type;
266 
267  BOOST_STATIC_ASSERT((sizeof(value_type) == 1));
268 
269  bit_packer(I first, I last) :
270  first_m(first), bitsize_m(long_distance(first, last))
271  { }
272 
273  bit_packer(I first, boost::uint64_t bitsize) :
274  first_m(first), bitsize_m(bitsize)
275  { }
276 
277  template <typename T>
278  inline std::size_t operator () (T& result)
279  { return byte_pack(result); }
280 
281 private:
282  template <typename T>
283  std::size_t byte_pack(T& result)
284  {
285  std::size_t to_pack(sizeof(T));
286 
287  result = 0;
288 
289  while (to_pack != 0 && bitsize_m != 0)
290  {
291  std::size_t shift_count(8 * (to_pack - 1));
292  T mask(T(255) << shift_count);
293 
294  result |= (T(*first_m) << shift_count) & mask;
295 
296  if (bitsize_m >= 8)
297  {
298  bitsize_m -= 8;
299  }
300  else
301  {
302  std::size_t remaining(static_cast<std::size_t>(to_pack * 8 - bitsize_m));
303 
304  bitsize_m = 0;
305 
306  return remaining;
307  }
308 
309  ++first_m;
310  --to_pack;
311  }
312 
313  return to_pack * 8;
314  }
315 
316  I first_m;
317  boost::uint64_t bitsize_m;
318 };
319 
320 /*************************************************************************************************/
321 
322 template <typename T>
323 struct bitsizeof
324 { enum { value = sizeof(T) * 8 }; };
325 
326 /*************************************************************************************************/
327 
328 template <std::size_t N, typename T>
329 inline T shr(const T& x)
330 {
331  BOOST_STATIC_ASSERT((N < bitsizeof<T>::value));
332 
333  return x >> N;
334 }
335 
336 template <std::size_t N, typename T>
337 inline T rotr(const T& x)
338 {
339  BOOST_STATIC_ASSERT((N < bitsizeof<T>::value));
340 
341  enum { l_shift = bitsizeof<T>::value - N };
342 
343  return (x >> N) | (x << l_shift);
344 }
345 
346 template <std::size_t N, typename T>
347 inline T rotl(const T& x)
348 {
349  BOOST_STATIC_ASSERT((N < bitsizeof<T>::value));
350 
351  enum { r_shift = bitsizeof<T>::value - N };
352 
353  return (x << N) | (x >> r_shift);
354 }
355 
356 /*************************************************************************************************/
357 
358 template <typename T>
359 inline T ch(T x, T y, T z)
360  { return (x & y) ^ (~x & z); }
361 
362 template <typename T>
363 inline T parity(T x, T y, T z)
364  { return x ^ y ^ z; }
365 
366 template <typename T>
367 inline T maj(T x, T y, T z)
368  { return (x & y) ^ (x & z) ^ (y & z); }
369 
370 /*************************************************************************************************/
371 
372 template <bool UseMB14, typename HashTraits>
373 struct message_block_part_14_set_t
374 {
375  typedef HashTraits traits_type;
376  typedef typename traits_type::hash_type hash_type;
377  typedef typename traits_type::message_block_type message_block_type;
378  typedef typename message_block_type::value_type message_block_value_type;
379 
380  enum { half_max_message_bitsize_k = traits_type::max_message_bitsize_k / 2 };
381 
382  void operator () (message_block_value_type& mbp14, boost::uint64_t num_bits)
383  {
384  message_block_value_type message_block_value_type_max(std::numeric_limits<message_block_value_type>::max());
385 
386  mbp14 = static_cast<message_block_value_type>((num_bits >> (half_max_message_bitsize_k)) & message_block_value_type_max);
387  }
388 };
389 
390 /*************************************************************************************************/
391 
392 template <typename HashTraits>
393 struct message_block_part_14_set_t<false, HashTraits>
394 {
395  typedef HashTraits traits_type;
396  typedef typename traits_type::message_block_type message_block_type;
397  typedef typename message_block_type::value_type message_block_value_type;
398 
399  void operator () (message_block_value_type& mbp14, boost::uint64_t)
400  { mbp14 = 0; }
401 };
402 
403 /*************************************************************************************************/
404 
405 template <typename HashTraits, typename I>
406 void block_and_digest(typename HashTraits::digest_type& digest, I first, boost::uint64_t num_bits)
407 {
408  typedef HashTraits traits_type;
409  typedef typename traits_type::hash_type hash_type;
410  typedef typename traits_type::message_block_type message_block_type;
411  typedef typename message_block_type::value_type message_block_value_type;
412 
413  enum
414  {
415  max_message_bitsize_k = traits_type::max_message_bitsize_k,
416  half_max_message_bitsize_k = max_message_bitsize_k / 2,
417  message_blocksize_k = traits_type::message_blocksize_k,
418  use_mb_14 = half_max_message_bitsize_k < bitsizeof<boost::uint64_t>::value
419  };
420 
421  message_block_value_type message_block_value_type_max(std::numeric_limits<message_block_value_type>::max());
422  message_block_type message_block;
423  boost::uint64_t message_size(num_bits + max_message_bitsize_k);
424  boost::uint64_t num_blocks(message_size / message_blocksize_k + 1);
425  bool in_padding(false);
426  bit_packer<I> bits(first, num_bits);
427 
428  while (num_blocks != 0)
429  {
430  for (std::size_t i(0); i < 16; ++i)
431  {
432  if (!in_padding)
433  {
434  std::size_t unset_bits(bits(message_block[i]));
435 
436  if (unset_bits != 0)
437  {
438  message_block[i] |= message_block_value_type(1) << (unset_bits - 1);
439 
440  in_padding = true;
441  }
442  }
443  else
444  {
445  if (num_blocks == 1)
446  {
447  // REVISIT (fbrereto) : According to the SHA standard the message length in the
448  // 1024-block-size case can be up to 2^128 bits long,
449  // but we only support messages up to 2^64 in length. In
450  // all instances when padding in the generic case, block
451  // part 14 would be:
452  // mbp14 = (num_bits >> (half_max_message_bitsize_k)) &
453  // message_block_value_type_max
454  // But in the 1024-block-size case
455  // half_max_message_bitsize_k == num_bits, and we will get
456  // a compiler error basically saying "hey, you're
457  // overshifting this value to 0", which would be fine in
458  // this case because the number should be set to 0, but
459  // the compiler is still (rightfully) noisy about it. This
460  // workaround forces the right thing to do in that it sets
461  // message block part 14 to zero in this special
462  // 1024-block-size case, thus sliencing the compiler.
463 
464  if (i == 14)
465  message_block_part_14_set_t<use_mb_14, traits_type>()(message_block[i], num_bits);
466  else if (i == 15)
467  message_block[i] = static_cast<message_block_value_type>(num_bits & message_block_value_type_max);
468  else
469  message_block[i] = 0;
470  }
471  else
472  message_block[i] = 0;
473  }
474  }
475 
476  sha_traits<hash_type>().digest_message_block(digest, message_block);
477 
478  --num_blocks;
479  }
480 
481  // clears potentioally sensitive information
482  std::memset(&message_block, 0, sizeof(message_block));
483 }
484 
485 /*************************************************************************************************/
486 
487 template <typename HashTraits>
488 void sha_2_digest_message_block(typename HashTraits::digest_type& digest,
489  const typename HashTraits::message_block_type& message_block)
490 {
491  // The "sha_2" in the name of this function is in
492  // reference to the second generation of SHA algorithms
493  // (224, 256, 384, and 512), all of which have the same
494  // message block process implementation.
495 
496  typedef HashTraits traits_type;
497  typedef typename traits_type::hash_type hash_type;
498  typedef typename traits_type::message_block_type message_block_type;
499  typedef typename traits_type::schedule_type schedule_type;
500  typedef typename hash_type::digest_type::value_type digest_value_type;
501 
502  schedule_type schedule;
503 
504  adobe::copy(message_block, &schedule[0]);
505 
506  for (std::size_t t(message_block_type::static_size); t < schedule_type::static_size; ++t)
507  schedule[t] = traits_type::small_sigma_1(schedule[t - 2]) + schedule[t - 7] +
508  traits_type::small_sigma_0(schedule[t - 15]) + schedule[t - 16];
509 
510  digest_value_type a(digest[0]);
511  digest_value_type b(digest[1]);
512  digest_value_type c(digest[2]);
513  digest_value_type d(digest[3]);
514  digest_value_type e(digest[4]);
515  digest_value_type f(digest[5]);
516  digest_value_type g(digest[6]);
517  digest_value_type h(digest[7]);
518 
519  for (std::size_t t(0); t < schedule.size(); ++t)
520  {
521  digest_value_type T1 = h +
522  traits_type::big_sigma_1(e) +
523  implementation::ch(e, f, g) +
524  traits_type::k(t) +
525  schedule[t];
526  digest_value_type T2 = traits_type::big_sigma_0(a) +
527  implementation::maj(a, b, c);
528  h = g;
529  g = f;
530  f = e;
531  e = d + T1;
532  d = c;
533  c = b;
534  b = a;
535  a = T1 + T2;
536  }
537 
538  digest[0] += a;
539  digest[1] += b;
540  digest[2] += c;
541  digest[3] += d;
542  digest[4] += e;
543  digest[5] += f;
544  digest[6] += g;
545  digest[7] += h;
546 
547  // clears potentioally sensitive information
548  std::memset(&schedule, 0, sizeof(schedule));
549 }
550 
551 /*************************************************************************************************/
552 
553 template <>
554 struct sha_traits<sha1_t>
555 {
556  typedef class sha1_t hash_type;
557  typedef boost::array<boost::uint32_t, 5> digest_type;
558  typedef boost::array<boost::uint32_t, 16> message_block_type;
559  typedef boost::array<boost::uint32_t, 80> schedule_type;
560 
561  enum
562  {
563  max_message_bitsize_k = 64,
564  message_blocksize_k = 512
565  };
566 
567  static void reset_digest(digest_type& digest)
568  {
569  digest[0] = 0x67452301;
570  digest[1] = 0xefcdab89;
571  digest[2] = 0x98badcfe;
572  digest[3] = 0x10325476;
573  digest[4] = 0xc3d2e1f0;
574  }
575 
576  static void digest_message_block(digest_type& digest, const message_block_type& message_block)
577  {
578  schedule_type schedule;
579 
580  adobe::copy(message_block, &schedule[0]);
581 
582  for (std::size_t t(message_block_type::static_size); t < schedule_type::static_size; ++t)
583  schedule[t] = implementation::rotl<1>( schedule[t - 3] ^ schedule[t - 8] ^
584  schedule[t - 14] ^ schedule[t - 16]);
585 
586  boost::uint32_t a(digest[0]);
587  boost::uint32_t b(digest[1]);
588  boost::uint32_t c(digest[2]);
589  boost::uint32_t d(digest[3]);
590  boost::uint32_t e(digest[4]);
591 
592  for (std::size_t t(0); t < schedule.size(); ++t)
593  {
594  boost::uint32_t T = implementation::rotl<5>(a) +
595  f(t, b, c, d) +
596  e +
597  k(t) +
598  schedule[t];
599  e = d;
600  d = c;
601  c = implementation::rotl<30>(b);
602  b = a;
603  a = T;
604  }
605 
606  digest[0] += a;
607  digest[1] += b;
608  digest[2] += c;
609  digest[3] += d;
610  digest[4] += e;
611 
612  // clears potentioally sensitive information
613  std::memset(&schedule, 0, sizeof(schedule));
614  }
615 
616 private:
617  static boost::uint32_t f( std::size_t t,
618  boost::uint32_t x,
619  boost::uint32_t y,
620  boost::uint32_t z)
621  {
622  assert (t < 80);
623 
624  if (t <= 19) return implementation::ch(x, y, z);
625  else if (t <= 39) return implementation::parity(x, y, z);
626  else if (t <= 59) return implementation::maj(x, y, z);
627 
628  return implementation::parity(x, y, z);
629  }
630 
631  static boost::uint32_t k(std::size_t t)
632  {
633  assert(t < 80);
634 
635  if (t <= 19) return 0x5a827999;
636  else if (t <= 39) return 0x6ed9eba1;
637  else if (t <= 59) return 0x8f1bbcdc;
638 
639  return 0xca62c1d6;
640  }
641 };
642 
643 /*************************************************************************************************/
644 
645 template <>
646 struct sha_traits<sha256_t>
647 {
648  typedef class sha256_t hash_type;
649  typedef boost::array<boost::uint32_t, 8> digest_type;
650  typedef boost::array<boost::uint32_t, 16> message_block_type;
651  typedef boost::array<boost::uint32_t, 64> schedule_type;
652 
653  enum
654  {
655  max_message_bitsize_k = 64,
656  message_blocksize_k = 512
657  };
658 
659  static void reset_digest(digest_type& digest)
660  {
661  digest[0] = 0x6a09e667;
662  digest[1] = 0xbb67ae85;
663  digest[2] = 0x3c6ef372;
664  digest[3] = 0xa54ff53a;
665  digest[4] = 0x510e527f;
666  digest[5] = 0x9b05688c;
667  digest[6] = 0x1f83d9ab;
668  digest[7] = 0x5be0cd19;
669  }
670 
671  static void digest_message_block(digest_type& digest, const message_block_type& message_block)
672  { sha_2_digest_message_block<sha_traits<hash_type> >(digest, message_block); }
673 
674  static boost::uint32_t big_sigma_0(boost::uint32_t x)
675  { return implementation::rotr<2>(x) ^ implementation::rotr<13>(x) ^ implementation::rotr<22>(x); }
676 
677  static boost::uint32_t big_sigma_1(boost::uint32_t x)
678  { return implementation::rotr<6>(x) ^ implementation::rotr<11>(x) ^ implementation::rotr<25>(x); }
679 
680  static boost::uint32_t small_sigma_0(boost::uint32_t x)
681  { return implementation::rotr<7>(x) ^ implementation::rotr<18>(x) ^ implementation::shr<3>(x); }
682 
683  static boost::uint32_t small_sigma_1(boost::uint32_t x)
684  { return implementation::rotr<17>(x) ^ implementation::rotr<19>(x) ^ implementation::shr<10>(x); }
685 
686  static boost::uint32_t k(std::size_t t)
687  {
688  static const boost::uint32_t k_set[] =
689  {
690  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
691  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
692  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
693  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
694  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
695  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
696  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
697  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
698  };
699 
700  assert (t < 64);
701 
702  return k_set[t];
703  }
704 };
705 
706 /*************************************************************************************************/
707 
708 template <>
709 struct sha_traits<sha224_t>
710 {
711  typedef class sha224_t hash_type;
712  typedef sha_traits<sha256_t>::digest_type digest_type;
713  typedef sha_traits<sha256_t>::message_block_type message_block_type;
714  typedef sha_traits<sha256_t>::schedule_type schedule_type;
715 
716  enum
717  {
718  max_message_bitsize_k = sha_traits<sha256_t>::max_message_bitsize_k,
719  message_blocksize_k = sha_traits<sha256_t>::message_blocksize_k
720  };
721 
722  static void reset_digest(digest_type& digest)
723  {
724  digest[0] = 0xc1059ed8;
725  digest[1] = 0x367cd507;
726  digest[2] = 0x3070dd17;
727  digest[3] = 0xf70e5939;
728  digest[4] = 0xffc00b31;
729  digest[5] = 0x68581511;
730  digest[6] = 0x64f98fa7;
731  digest[7] = 0xbefa4fa4;
732  }
733 
734  static void digest_message_block(digest_type& digest, const message_block_type& message_block)
735  { sha_2_digest_message_block<sha_traits<hash_type> >(digest, message_block); }
736 
737  static boost::uint32_t big_sigma_0(boost::uint32_t x)
738  { return sha_traits<sha256_t>::big_sigma_0(x); }
739 
740  static boost::uint32_t big_sigma_1(boost::uint32_t x)
741  { return sha_traits<sha256_t>::big_sigma_1(x); }
742 
743  static boost::uint32_t small_sigma_0(boost::uint32_t x)
744  { return sha_traits<sha256_t>::small_sigma_0(x); }
745 
746  static boost::uint32_t small_sigma_1(boost::uint32_t x)
747  { return sha_traits<sha256_t>::small_sigma_1(x); }
748 
749  static boost::uint32_t k(std::size_t x)
750  { return sha_traits<sha256_t>::k(x); }
751 };
752 
753 /*************************************************************************************************/
754 
755 template <>
756 struct sha_traits<sha512_t>
757 {
758  typedef class sha512_t hash_type;
759  typedef boost::array<boost::uint64_t, 8> digest_type;
760  typedef boost::array<boost::uint64_t, 16> message_block_type;
761  typedef boost::array<boost::uint64_t, 80> schedule_type;
762 
763  enum
764  {
765  max_message_bitsize_k = 128,
766  message_blocksize_k = 1024
767  };
768 
769  static void reset_digest(digest_type& digest)
770  {
771  digest[0] = 0x6a09e667f3bcc908ULL;
772  digest[1] = 0xbb67ae8584caa73bULL;
773  digest[2] = 0x3c6ef372fe94f82bULL;
774  digest[3] = 0xa54ff53a5f1d36f1ULL;
775  digest[4] = 0x510e527fade682d1ULL;
776  digest[5] = 0x9b05688c2b3e6c1fULL;
777  digest[6] = 0x1f83d9abfb41bd6bULL;
778  digest[7] = 0x5be0cd19137e2179ULL;
779  }
780 
781  static void digest_message_block(digest_type& digest, const message_block_type& message_block)
782  { sha_2_digest_message_block<sha_traits<hash_type> >(digest, message_block); }
783 
784  static boost::uint64_t big_sigma_0(boost::uint64_t x)
785  { return implementation::rotr<28>(x) ^ implementation::rotr<34>(x) ^ implementation::rotr<39>(x); }
786 
787  static boost::uint64_t big_sigma_1(boost::uint64_t x)
788  { return implementation::rotr<14>(x) ^ implementation::rotr<18>(x) ^ implementation::rotr<41>(x); }
789 
790  static boost::uint64_t small_sigma_0(boost::uint64_t x)
791  { return implementation::rotr<1>(x) ^ implementation::rotr<8>(x) ^ implementation::shr<7>(x); }
792 
793  static boost::uint64_t small_sigma_1(boost::uint64_t x)
794  { return implementation::rotr<19>(x) ^ implementation::rotr<61>(x) ^ implementation::shr<6>(x); }
795 
796  static boost::uint64_t k(std::size_t t)
797  {
798  static const boost::uint64_t k_set[] =
799  {
800  0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
801  0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
802  0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
803  0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
804  0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
805  0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
806  0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
807  0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
808  0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
809  0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
810  0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
811  0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
812  0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
813  0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
814  0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
815  0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
816  0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
817  0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
818  0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
819  0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
820  };
821 
822  assert (t < 80);
823 
824  return k_set[t];
825  }
826 };
827 
828 /*************************************************************************************************/
829 
830 template <>
831 struct sha_traits<sha384_t>
832 {
833  typedef class sha384_t hash_type;
834  typedef sha_traits<sha512_t>::digest_type digest_type;
835  typedef sha_traits<sha512_t>::message_block_type message_block_type;
836  typedef sha_traits<sha512_t>::schedule_type schedule_type;
837 
838  enum
839  {
840  max_message_bitsize_k = sha_traits<sha512_t>::max_message_bitsize_k,
841  message_blocksize_k = sha_traits<sha512_t>::message_blocksize_k
842  };
843 
844  static void reset_digest(digest_type& digest)
845  {
846  digest[0] = 0xcbbb9d5dc1059ed8ULL;
847  digest[1] = 0x629a292a367cd507ULL;
848  digest[2] = 0x9159015a3070dd17ULL;
849  digest[3] = 0x152fecd8f70e5939ULL;
850  digest[4] = 0x67332667ffc00b31ULL;
851  digest[5] = 0x8eb44a8768581511ULL;
852  digest[6] = 0xdb0c2e0d64f98fa7ULL;
853  digest[7] = 0x47b5481dbefa4fa4ULL;
854  }
855 
856  static void digest_message_block(digest_type& digest, const message_block_type& message_block)
857  { sha_2_digest_message_block<sha_traits<hash_type> >(digest, message_block); }
858 
859  static boost::uint64_t big_sigma_0(boost::uint64_t x)
860  { return sha_traits<sha512_t>::big_sigma_0(x); }
861 
862  static boost::uint64_t big_sigma_1(boost::uint64_t x)
863  { return sha_traits<sha512_t>::big_sigma_1(x); }
864 
865  static boost::uint64_t small_sigma_0(boost::uint64_t x)
866  { return sha_traits<sha512_t>::small_sigma_0(x); }
867 
868  static boost::uint64_t small_sigma_1(boost::uint64_t x)
869  { return sha_traits<sha512_t>::small_sigma_1(x); }
870 
871  static boost::uint64_t k(std::size_t x)
872  { return sha_traits<sha512_t>::k(x); }
873 };
874 
875 /*************************************************************************************************/
876 
877 #endif
878 
879 /*************************************************************************************************/
880 
881 } // namespace implementation
882 
883 /*************************************************************************************************/
884 
885 class sha1_t
886 {
887 public:
888 #if !defined(ADOBE_NO_DOCUMENTATION)
889  typedef implementation::sha_traits<sha1_t> traits_type;
890 #endif
891  typedef traits_type::digest_type digest_type;
892 
893  template <typename I>
894  inline digest_type digest(I first, I last)
895  {
896  enum { ibits_k = implementation::bitsizeof<typename std::iterator_traits<I>::value_type>::value };
897 
898  return digest(first, implementation::long_distance(first, last) * ibits_k);
899  }
900 
901  template <typename I>
902  inline digest_type digest(I first, boost::uint64_t num_bits)
903  {
904  traits_type().reset_digest(digest_m);
905 
906  implementation::block_and_digest<traits_type>(digest_m, first, num_bits);
907 
908  return digest_m;
909  }
910 
911 private:
912  digest_type digest_m;
913 };
914 
915 /*************************************************************************************************/
916 
917 class sha224_t
918 {
919 public:
920 #if !defined(ADOBE_NO_DOCUMENTATION)
921  typedef implementation::sha_traits<sha224_t> traits_type;
922 #endif
923  typedef boost::array<boost::uint32_t, 7> digest_type;
924 
925  template <typename I>
926  inline digest_type digest(I first, I last)
927  {
928  enum { ibits_k = implementation::bitsizeof<typename std::iterator_traits<I>::value_type>::value };
929 
930  return digest(first, implementation::long_distance(first, last) * ibits_k);
931  }
932 
933  template <typename I>
934  inline digest_type digest(I first, boost::uint64_t num_bits)
935  {
936  traits_type().reset_digest(digest_m);
937 
938  implementation::block_and_digest<traits_type>(digest_m, first, num_bits);
939 
940  return crop_digest(digest_m);
941  }
942 
943 private:
944  inline digest_type crop_digest(traits_type::digest_type& digest)
945  {
946  digest_type result;
947 
948  std::copy(digest.begin(), digest.begin() + digest_type::static_size, &result[0]);
949 
950  return result;
951  }
952 
953  traits_type::digest_type digest_m;
954 };
955 
956 /*************************************************************************************************/
957 
958 class sha256_t
959 {
960 public:
961 #if !defined(ADOBE_NO_DOCUMENTATION)
962  typedef implementation::sha_traits<sha256_t> traits_type;
963 #endif
964  typedef traits_type::digest_type digest_type;
965 
966  template <typename I>
967  inline digest_type digest(I first, I last)
968  {
969  enum { ibits_k = implementation::bitsizeof<typename std::iterator_traits<I>::value_type>::value };
970 
971  return digest(first, implementation::long_distance(first, last) * ibits_k);
972  }
973 
974  template <typename I>
975  inline digest_type digest(I first, boost::uint64_t num_bits)
976  {
977  traits_type().reset_digest(digest_m);
978 
979  implementation::block_and_digest<traits_type>(digest_m, first, num_bits);
980 
981  return digest_m;
982  }
983 
984 private:
985  digest_type digest_m;
986 };
987 
988 /*************************************************************************************************/
989 
990 class sha512_t
991 {
992 public:
993 #if !defined(ADOBE_NO_DOCUMENTATION)
994  typedef implementation::sha_traits<sha512_t> traits_type;
995 #endif
996  typedef traits_type::digest_type digest_type;
997 
998  template <typename I>
999  inline digest_type digest(I first, I last)
1000  {
1001  enum { ibits_k = implementation::bitsizeof<typename std::iterator_traits<I>::value_type>::value };
1002 
1003  return digest(first, implementation::long_distance(first, last) * ibits_k);
1004  }
1005 
1006  template <typename I>
1007  inline digest_type digest(I first, boost::uint64_t num_bits)
1008  {
1009  traits_type().reset_digest(digest_m);
1010 
1011  implementation::block_and_digest<traits_type>(digest_m, first, num_bits);
1012 
1013  return digest_m;
1014  }
1015 
1016 private:
1017  digest_type digest_m;
1018 };
1019 
1020 /*************************************************************************************************/
1021 
1023 {
1024 public:
1025 #if !defined(ADOBE_NO_DOCUMENTATION)
1026  typedef implementation::sha_traits<sha384_t> traits_type;
1027 #endif
1028  typedef boost::array<boost::uint64_t, 6> digest_type;
1029 
1030  template <typename I>
1031  inline digest_type digest(I first, I last)
1032  {
1033  enum { ibits_k = implementation::bitsizeof<typename std::iterator_traits<I>::value_type>::value };
1034 
1035  return digest(first, implementation::long_distance(first, last) * ibits_k);
1036  }
1037 
1038  template <typename I>
1039  inline digest_type digest(I first, boost::uint64_t num_bits)
1040  {
1041  traits_type().reset_digest(digest_m);
1042 
1043  implementation::block_and_digest<traits_type>(digest_m, first, num_bits);
1044 
1045  return crop_digest(digest_m);
1046  }
1047 
1048 private:
1049  inline digest_type crop_digest(traits_type::digest_type& digest)
1050  {
1051  digest_type result;
1052 
1053  std::copy(digest.begin(), digest.begin() + digest_type::static_size, &result[0]);
1054 
1055  return result;
1056  }
1057 
1058  traits_type::digest_type digest_m;
1059 };
1060 
1061 /*************************************************************************************************/
1062 
1063 } // namespace adobe
1064 
1065 /*************************************************************************************************/
1066 
1067 #endif
1068 
1069 /*************************************************************************************************/

Copyright © 2006-2007 Adobe Systems Incorporated.

Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy.

Search powered by Google