stlab.adobe.com Adobe Systems Incorporated

sha.hpp

Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2007 Adobe Systems Incorporated
00003     Distributed under the MIT License (see accompanying file LICENSE_1_0_0.txt
00004     or a copy at http://stlab.adobe.com/licenses.html)
00005 */
00006 
00007 /*************************************************************************************************/
00008 
00009 #ifndef ADOBE_SHA_HPP
00010 #define ADOBE_SHA_HPP
00011 
00012 /*************************************************************************************************/
00013 
00014 #include <adobe/config.hpp>
00015 
00016 #include <boost/array.hpp>
00017 #include <boost/cstdint.hpp>
00018 #include <boost/static_assert.hpp>
00019 
00020 #include <stdexcept>
00021 #include <limits>
00022 #include <cstring>
00023 
00024 /*************************************************************************************************/
00025 
00026 namespace adobe {
00027 
00222 /*************************************************************************************************/
00223 
00224 class sha1_t;
00225 class sha224_t;
00226 class sha256_t;
00227 class sha384_t;
00228 class sha512_t;
00229 
00230 /*************************************************************************************************/
00231 
00232 namespace implementation {
00233 
00234 /*************************************************************************************************/
00235 
00236 #if !defined(ADOBE_NO_DOCUMENTATION)
00237 
00238 /*************************************************************************************************/
00239 
00240 template <typename HashT>
00241 struct sha_traits;
00242 
00243 /*************************************************************************************************/
00244 
00245 template <typename I> // I models InputIterator
00246 inline boost::uint64_t long_distance(I first, I last)
00247 {
00248     boost::uint64_t result(0);
00249 
00250     while (first != last)
00251     {
00252         ++result;
00253 
00254         ++first;
00255     }
00256 
00257     return result;
00258 }
00259 
00260 /*************************************************************************************************/
00261 
00262 template <typename I> // I models InputIterator
00263 struct bit_packer
00264 {
00265     typedef typename std::iterator_traits<I>::value_type value_type;
00266 
00267     BOOST_STATIC_ASSERT((sizeof(value_type) == 1));
00268 
00269     bit_packer(I first, I last) :
00270         first_m(first), bitsize_m(long_distance(first, last))
00271     { }
00272 
00273     bit_packer(I first, boost::uint64_t bitsize) :
00274         first_m(first), bitsize_m(bitsize)
00275     { }
00276 
00277     template <typename T>
00278     inline std::size_t operator () (T& result)
00279     { return byte_pack(result); }
00280 
00281 private:
00282     template <typename T>
00283     std::size_t byte_pack(T& result)
00284     {
00285         std::size_t to_pack(sizeof(T));
00286 
00287         result = 0;
00288 
00289         while (to_pack != 0 && bitsize_m != 0)
00290         {
00291             std::size_t shift_count(8 * (to_pack - 1));
00292             T           mask(T(255) << shift_count);
00293 
00294             result |= (T(*first_m) << shift_count) & mask;
00295 
00296             if (bitsize_m >= 8)
00297             {
00298                 bitsize_m -= 8;
00299             }
00300             else
00301             {
00302                 std::size_t remaining(static_cast<std::size_t>(to_pack * 8 - bitsize_m));
00303 
00304                 bitsize_m = 0;
00305 
00306                 return remaining;
00307             }
00308 
00309             ++first_m;
00310             --to_pack;
00311         }
00312 
00313         return to_pack * 8;
00314     }
00315 
00316     I               first_m;
00317     boost::uint64_t bitsize_m;
00318 };
00319 
00320 /*************************************************************************************************/
00321 
00322 template <typename T>
00323 struct bitsizeof
00324 { enum { value = sizeof(T) * 8 }; };
00325 
00326 /*************************************************************************************************/
00327 
00328 template <std::size_t N, typename T>
00329 inline T shr(const T& x)
00330 {
00331     BOOST_STATIC_ASSERT((N < bitsizeof<T>::value));
00332 
00333     return x >> N;
00334 }
00335 
00336 template <std::size_t N, typename T>
00337 inline T rotr(const T& x)
00338 {
00339     BOOST_STATIC_ASSERT((N < bitsizeof<T>::value));
00340 
00341     enum { l_shift = bitsizeof<T>::value - N };
00342 
00343     return (x >> N) | (x << l_shift);
00344 }
00345 
00346 template <std::size_t N, typename T>
00347 inline T rotl(const T& x)
00348 {
00349     BOOST_STATIC_ASSERT((N < bitsizeof<T>::value));
00350 
00351     enum { r_shift = bitsizeof<T>::value - N };
00352 
00353     return (x << N) | (x >> r_shift);
00354 }
00355 
00356 /*************************************************************************************************/
00357 
00358 template <typename T>
00359 inline T ch(T x, T y, T z)
00360     { return (x & y) ^ (~x & z); }
00361 
00362 template <typename T>
00363 inline T parity(T x, T y, T z)
00364     { return x ^ y ^ z; }
00365 
00366 template <typename T>
00367 inline T maj(T x, T y, T z)
00368     { return (x & y) ^ (x & z) ^ (y & z); }
00369 
00370 /*************************************************************************************************/
00371 
00372 template <bool UseMB14, typename HashTraits>
00373 struct message_block_part_14_set_t
00374 {
00375     typedef HashTraits                                  traits_type;
00376     typedef typename traits_type::hash_type             hash_type;
00377     typedef typename traits_type::message_block_type    message_block_type;
00378     typedef typename message_block_type::value_type     message_block_value_type;
00379 
00380     enum { half_max_message_bitsize_k = traits_type::max_message_bitsize_k / 2 };
00381 
00382     void operator () (message_block_value_type& mbp14, boost::uint64_t num_bits)
00383     {
00384         message_block_value_type message_block_value_type_max(std::numeric_limits<message_block_value_type>::max());
00385 
00386         mbp14 = static_cast<message_block_value_type>((num_bits >> (half_max_message_bitsize_k)) & message_block_value_type_max);
00387     }
00388 };
00389 
00390 /*************************************************************************************************/
00391 
00392 template <typename HashTraits>
00393 struct message_block_part_14_set_t<false, HashTraits>
00394 {
00395     typedef HashTraits                                  traits_type;
00396     typedef typename traits_type::message_block_type    message_block_type;
00397     typedef typename message_block_type::value_type     message_block_value_type;
00398 
00399     void operator () (message_block_value_type& mbp14, boost::uint64_t)
00400     { mbp14 = 0; }
00401 };
00402 
00403 /*************************************************************************************************/
00404 
00405 template <typename HashTraits, typename I>
00406 void block_and_digest(typename HashTraits::digest_type& digest, I first, boost::uint64_t num_bits)
00407 {
00408     typedef HashTraits                                  traits_type;
00409     typedef typename traits_type::hash_type             hash_type;
00410     typedef typename traits_type::message_block_type    message_block_type;
00411     typedef typename message_block_type::value_type     message_block_value_type;
00412 
00413     enum
00414     {
00415         max_message_bitsize_k = traits_type::max_message_bitsize_k,
00416         half_max_message_bitsize_k = max_message_bitsize_k / 2,
00417         message_blocksize_k = traits_type::message_blocksize_k,
00418         use_mb_14 = half_max_message_bitsize_k < bitsizeof<boost::uint64_t>::value
00419     };
00420 
00421     message_block_value_type    message_block_value_type_max(std::numeric_limits<message_block_value_type>::max());
00422     message_block_type          message_block;
00423     boost::uint64_t             message_size(num_bits + max_message_bitsize_k);
00424     boost::uint64_t             num_blocks(message_size / message_blocksize_k + 1);
00425     bool                        in_padding(false);
00426     bit_packer<I>               bits(first, num_bits);
00427 
00428     while (num_blocks != 0)
00429     {
00430         for (std::size_t i(0); i < 16; ++i)
00431         {
00432             if (!in_padding)
00433             {
00434                 std::size_t unset_bits(bits(message_block[i]));
00435 
00436                 if (unset_bits != 0)
00437                 {
00438                     message_block[i] |= message_block_value_type(1) << (unset_bits - 1);
00439 
00440                     in_padding = true;
00441                 }
00442             }
00443             else
00444             {
00445                 if (num_blocks == 1)
00446                 {
00447                     // REVISIT (fbrereto) : According to the SHA standard the message length in the
00448                     //                      1024-block-size case can be up to 2^128 bits long,
00449                     //                      but we only support messages up to 2^64 in length. In
00450                     //                      all instances when padding in the generic case, block
00451                     //                      part 14 would be:
00452                     //                          mbp14 = (num_bits >> (half_max_message_bitsize_k)) &
00453                     //                              message_block_value_type_max
00454                     //                      But in the 1024-block-size case
00455                     //                      half_max_message_bitsize_k == num_bits, and we will get
00456                     //                      a compiler error basically saying "hey, you're
00457                     //                      overshifting this value to 0", which would be fine in
00458                     //                      this case because the number should be set to 0, but
00459                     //                      the compiler is still (rightfully) noisy about it. This
00460                     //                      workaround forces the right thing to do in that it sets
00461                     //                      message block part 14 to zero in this special
00462                     //                      1024-block-size case, thus sliencing the compiler.
00463 
00464                     if (i == 14)
00465                         message_block_part_14_set_t<use_mb_14, traits_type>()(message_block[i], num_bits);
00466                     else if (i == 15)
00467                         message_block[i] = static_cast<message_block_value_type>(num_bits & message_block_value_type_max);
00468                     else
00469                         message_block[i] = 0;
00470                 }
00471                 else
00472                     message_block[i] = 0;
00473             }
00474         }
00475 
00476         sha_traits<hash_type>().digest_message_block(digest, message_block);
00477 
00478         --num_blocks;
00479     }
00480 
00481     // clears potentioally sensitive information
00482     std::memset(&message_block, 0, sizeof(message_block));
00483 }
00484 
00485 /*************************************************************************************************/
00486 
00487 template <typename HashTraits>
00488 void sha_2_digest_message_block(typename HashTraits::digest_type&               digest,
00489                                 const typename HashTraits::message_block_type&  message_block)
00490 {
00491     //  The "sha_2" in the name of this function is in
00492     //  reference to the second generation of SHA algorithms
00493     //  (224, 256, 384, and 512), all of which have the same
00494     //  message block process implementation.
00495 
00496     typedef HashTraits                                  traits_type;
00497     typedef typename traits_type::hash_type             hash_type;
00498     typedef typename traits_type::message_block_type    message_block_type;
00499     typedef typename traits_type::schedule_type         schedule_type;
00500     typedef typename hash_type::digest_type::value_type digest_value_type;
00501 
00502     schedule_type schedule;
00503 
00504     adobe::copy(message_block, &schedule[0]);
00505 
00506     for (std::size_t t(message_block_type::static_size); t < schedule_type::static_size; ++t)
00507         schedule[t] =   traits_type::small_sigma_1(schedule[t - 2]) + schedule[t - 7] +
00508                         traits_type::small_sigma_0(schedule[t - 15]) + schedule[t - 16];
00509 
00510     digest_value_type a(digest[0]);
00511     digest_value_type b(digest[1]);
00512     digest_value_type c(digest[2]);
00513     digest_value_type d(digest[3]);
00514     digest_value_type e(digest[4]);
00515     digest_value_type f(digest[5]);
00516     digest_value_type g(digest[6]);
00517     digest_value_type h(digest[7]);
00518 
00519     for (std::size_t t(0); t < schedule.size(); ++t)
00520     {
00521         digest_value_type T1 =  h                           +
00522                                 traits_type::big_sigma_1(e) +
00523                                 implementation::ch(e, f, g) +
00524                                 traits_type::k(t)           +
00525                                 schedule[t];
00526         digest_value_type T2 =  traits_type::big_sigma_0(a) +
00527                                 implementation::maj(a, b, c);
00528         h = g;
00529         g = f;
00530         f = e;
00531         e = d + T1;
00532         d = c;
00533         c = b;
00534         b = a;
00535         a = T1 + T2;
00536     }
00537 
00538     digest[0] += a;
00539     digest[1] += b;
00540     digest[2] += c;
00541     digest[3] += d;
00542     digest[4] += e;
00543     digest[5] += f;
00544     digest[6] += g;
00545     digest[7] += h;
00546 
00547     // clears potentioally sensitive information
00548     std::memset(&schedule, 0, sizeof(schedule));
00549 }
00550 
00551 /*************************************************************************************************/
00552 
00553 template <>
00554 struct sha_traits<sha1_t>
00555 {
00556     typedef class sha1_t                 hash_type;
00557     typedef boost::array<boost::uint32_t, 5>    digest_type;
00558     typedef boost::array<boost::uint32_t, 16>   message_block_type;
00559     typedef boost::array<boost::uint32_t, 80>   schedule_type;
00560 
00561     enum
00562     {
00563         max_message_bitsize_k = 64,
00564         message_blocksize_k = 512
00565     };
00566 
00567     static void reset_digest(digest_type& digest)
00568     {
00569         digest[0] = 0x67452301;
00570         digest[1] = 0xefcdab89;
00571         digest[2] = 0x98badcfe;
00572         digest[3] = 0x10325476;
00573         digest[4] = 0xc3d2e1f0;
00574     }
00575 
00576     static void digest_message_block(digest_type& digest, const message_block_type& message_block)
00577     {   
00578         schedule_type schedule;
00579 
00580         adobe::copy(message_block, &schedule[0]);
00581 
00582         for (std::size_t t(message_block_type::static_size); t < schedule_type::static_size; ++t)
00583             schedule[t] = implementation::rotl<1>(  schedule[t - 3] ^ schedule[t - 8] ^
00584                                                     schedule[t - 14] ^ schedule[t - 16]);
00585 
00586         boost::uint32_t a(digest[0]);
00587         boost::uint32_t b(digest[1]);
00588         boost::uint32_t c(digest[2]);
00589         boost::uint32_t d(digest[3]);
00590         boost::uint32_t e(digest[4]);
00591 
00592         for (std::size_t t(0); t < schedule.size(); ++t)
00593         {
00594             boost::uint32_t T = implementation::rotl<5>(a)  +
00595                                 f(t, b, c, d)               +
00596                                 e                           +
00597                                 k(t)                        +
00598                                 schedule[t];
00599             e = d;
00600             d = c;
00601             c = implementation::rotl<30>(b);
00602             b = a;
00603             a = T;
00604         }
00605 
00606         digest[0] += a;
00607         digest[1] += b;
00608         digest[2] += c;
00609         digest[3] += d;
00610         digest[4] += e;
00611 
00612         // clears potentioally sensitive information
00613         std::memset(&schedule, 0, sizeof(schedule));
00614     }
00615 
00616 private:
00617     static boost::uint32_t f(   std::size_t     t,
00618                                 boost::uint32_t x,
00619                                 boost::uint32_t y,
00620                                 boost::uint32_t z)
00621     {
00622         assert (t < 80);
00623     
00624         if (t <= 19)        return implementation::ch(x, y, z);
00625         else if (t <= 39)   return implementation::parity(x, y, z);
00626         else if (t <= 59)   return implementation::maj(x, y, z);
00627     
00628         return implementation::parity(x, y, z);
00629     }
00630 
00631     static boost::uint32_t k(std::size_t t)
00632     {
00633         assert(t < 80);
00634     
00635         if (t <= 19)        return 0x5a827999;
00636         else if (t <= 39)   return 0x6ed9eba1;
00637         else if (t <= 59)   return 0x8f1bbcdc;
00638     
00639         return 0xca62c1d6;
00640     }
00641 };
00642 
00643 /*************************************************************************************************/
00644 
00645 template <>
00646 struct sha_traits<sha256_t>
00647 {
00648     typedef class sha256_t               hash_type;
00649     typedef boost::array<boost::uint32_t, 8>    digest_type;
00650     typedef boost::array<boost::uint32_t, 16>   message_block_type;
00651     typedef boost::array<boost::uint32_t, 64>   schedule_type;
00652 
00653     enum
00654     {
00655         max_message_bitsize_k = 64,
00656         message_blocksize_k = 512
00657     };
00658 
00659     static void reset_digest(digest_type& digest)
00660     {
00661         digest[0] = 0x6a09e667;
00662         digest[1] = 0xbb67ae85;
00663         digest[2] = 0x3c6ef372;
00664         digest[3] = 0xa54ff53a;
00665         digest[4] = 0x510e527f;
00666         digest[5] = 0x9b05688c;
00667         digest[6] = 0x1f83d9ab;
00668         digest[7] = 0x5be0cd19;
00669     }
00670 
00671     static void digest_message_block(digest_type& digest, const message_block_type& message_block)
00672         { sha_2_digest_message_block<sha_traits<hash_type> >(digest, message_block); }
00673 
00674     static boost::uint32_t big_sigma_0(boost::uint32_t x)
00675         { return implementation::rotr<2>(x) ^ implementation::rotr<13>(x) ^ implementation::rotr<22>(x); }
00676 
00677     static boost::uint32_t big_sigma_1(boost::uint32_t x)
00678         { return implementation::rotr<6>(x) ^ implementation::rotr<11>(x) ^ implementation::rotr<25>(x); }
00679 
00680     static boost::uint32_t small_sigma_0(boost::uint32_t x)
00681         { return implementation::rotr<7>(x) ^ implementation::rotr<18>(x) ^ implementation::shr<3>(x); }
00682 
00683     static boost::uint32_t small_sigma_1(boost::uint32_t x)
00684         { return implementation::rotr<17>(x) ^ implementation::rotr<19>(x) ^ implementation::shr<10>(x); }
00685 
00686     static boost::uint32_t k(std::size_t t)
00687     {
00688         static const boost::uint32_t k_set[] =
00689         {
00690             0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
00691             0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
00692             0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
00693             0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
00694             0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
00695             0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
00696             0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
00697             0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
00698         };
00699 
00700         assert (t < 64);
00701 
00702         return k_set[t];
00703     }
00704 };
00705 
00706 /*************************************************************************************************/
00707 
00708 template <>
00709 struct sha_traits<sha224_t>
00710 {
00711     typedef class sha224_t                           hash_type;
00712     typedef sha_traits<sha256_t>::digest_type        digest_type;
00713     typedef sha_traits<sha256_t>::message_block_type message_block_type;
00714     typedef sha_traits<sha256_t>::schedule_type      schedule_type;
00715 
00716     enum
00717     {
00718         max_message_bitsize_k = sha_traits<sha256_t>::max_message_bitsize_k,
00719         message_blocksize_k = sha_traits<sha256_t>::message_blocksize_k
00720     };
00721 
00722     static void reset_digest(digest_type& digest)
00723     {
00724         digest[0] = 0xc1059ed8;
00725         digest[1] = 0x367cd507;
00726         digest[2] = 0x3070dd17;
00727         digest[3] = 0xf70e5939;
00728         digest[4] = 0xffc00b31;
00729         digest[5] = 0x68581511;
00730         digest[6] = 0x64f98fa7;
00731         digest[7] = 0xbefa4fa4;
00732     }
00733 
00734     static void digest_message_block(digest_type& digest, const message_block_type& message_block)
00735         { sha_2_digest_message_block<sha_traits<hash_type> >(digest, message_block); }
00736 
00737     static boost::uint32_t big_sigma_0(boost::uint32_t x)
00738         { return sha_traits<sha256_t>::big_sigma_0(x); }
00739 
00740     static boost::uint32_t big_sigma_1(boost::uint32_t x)
00741         { return sha_traits<sha256_t>::big_sigma_1(x); }
00742 
00743     static boost::uint32_t small_sigma_0(boost::uint32_t x)
00744         { return sha_traits<sha256_t>::small_sigma_0(x); }
00745 
00746     static boost::uint32_t small_sigma_1(boost::uint32_t x)
00747         { return sha_traits<sha256_t>::small_sigma_1(x); }
00748 
00749     static boost::uint32_t k(std::size_t x)
00750         { return sha_traits<sha256_t>::k(x); }
00751 };
00752 
00753 /*************************************************************************************************/
00754 
00755 template <>
00756 struct sha_traits<sha512_t>
00757 {
00758     typedef class sha512_t               hash_type;
00759     typedef boost::array<boost::uint64_t, 8>    digest_type;
00760     typedef boost::array<boost::uint64_t, 16>   message_block_type;
00761     typedef boost::array<boost::uint64_t, 80>   schedule_type;
00762 
00763     enum
00764     {
00765         max_message_bitsize_k = 128,
00766         message_blocksize_k = 1024
00767     };
00768 
00769     static void reset_digest(digest_type& digest)
00770     {
00771         digest[0] = 0x6a09e667f3bcc908ULL;
00772         digest[1] = 0xbb67ae8584caa73bULL;
00773         digest[2] = 0x3c6ef372fe94f82bULL;
00774         digest[3] = 0xa54ff53a5f1d36f1ULL;
00775         digest[4] = 0x510e527fade682d1ULL;
00776         digest[5] = 0x9b05688c2b3e6c1fULL;
00777         digest[6] = 0x1f83d9abfb41bd6bULL;
00778         digest[7] = 0x5be0cd19137e2179ULL;
00779     }
00780 
00781     static void digest_message_block(digest_type& digest, const message_block_type& message_block)
00782         { sha_2_digest_message_block<sha_traits<hash_type> >(digest, message_block); }
00783 
00784     static boost::uint64_t big_sigma_0(boost::uint64_t x)
00785         { return implementation::rotr<28>(x) ^ implementation::rotr<34>(x) ^ implementation::rotr<39>(x); }
00786 
00787     static boost::uint64_t big_sigma_1(boost::uint64_t x)
00788         { return implementation::rotr<14>(x) ^ implementation::rotr<18>(x) ^ implementation::rotr<41>(x); }
00789 
00790     static boost::uint64_t small_sigma_0(boost::uint64_t x)
00791         { return implementation::rotr<1>(x) ^ implementation::rotr<8>(x) ^ implementation::shr<7>(x); }
00792 
00793     static boost::uint64_t small_sigma_1(boost::uint64_t x)
00794         { return implementation::rotr<19>(x) ^ implementation::rotr<61>(x) ^ implementation::shr<6>(x); }
00795 
00796     static boost::uint64_t k(std::size_t t)
00797     {
00798         static const boost::uint64_t k_set[] =
00799         {
00800             0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
00801             0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
00802             0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
00803             0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
00804             0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
00805             0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
00806             0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
00807             0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
00808             0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
00809             0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
00810             0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
00811             0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
00812             0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
00813             0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
00814             0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
00815             0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
00816             0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
00817             0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
00818             0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
00819             0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
00820         };
00821 
00822         assert (t < 80);
00823 
00824         return k_set[t];
00825     }
00826 };
00827 
00828 /*************************************************************************************************/
00829 
00830 template <>
00831 struct sha_traits<sha384_t>
00832 {
00833     typedef class sha384_t                           hash_type;
00834     typedef sha_traits<sha512_t>::digest_type        digest_type;
00835     typedef sha_traits<sha512_t>::message_block_type message_block_type;
00836     typedef sha_traits<sha512_t>::schedule_type      schedule_type;
00837 
00838     enum
00839     {
00840         max_message_bitsize_k = sha_traits<sha512_t>::max_message_bitsize_k,
00841         message_blocksize_k = sha_traits<sha512_t>::message_blocksize_k
00842     };
00843 
00844     static void reset_digest(digest_type& digest)
00845     {
00846         digest[0] = 0xcbbb9d5dc1059ed8ULL;
00847         digest[1] = 0x629a292a367cd507ULL;
00848         digest[2] = 0x9159015a3070dd17ULL;
00849         digest[3] = 0x152fecd8f70e5939ULL;
00850         digest[4] = 0x67332667ffc00b31ULL;
00851         digest[5] = 0x8eb44a8768581511ULL;
00852         digest[6] = 0xdb0c2e0d64f98fa7ULL;
00853         digest[7] = 0x47b5481dbefa4fa4ULL;
00854     }
00855 
00856     static void digest_message_block(digest_type& digest, const message_block_type& message_block)
00857         { sha_2_digest_message_block<sha_traits<hash_type> >(digest, message_block); }
00858 
00859     static boost::uint64_t big_sigma_0(boost::uint64_t x)
00860         { return sha_traits<sha512_t>::big_sigma_0(x); }
00861 
00862     static boost::uint64_t big_sigma_1(boost::uint64_t x)
00863         { return sha_traits<sha512_t>::big_sigma_1(x); }
00864 
00865     static boost::uint64_t small_sigma_0(boost::uint64_t x)
00866         { return sha_traits<sha512_t>::small_sigma_0(x); }
00867 
00868     static boost::uint64_t small_sigma_1(boost::uint64_t x)
00869         { return sha_traits<sha512_t>::small_sigma_1(x); }
00870 
00871     static boost::uint64_t k(std::size_t x)
00872         { return sha_traits<sha512_t>::k(x); }
00873 };
00874 
00875 /*************************************************************************************************/
00876 
00877 #endif
00878 
00879 /*************************************************************************************************/
00880 
00881 } // namespace implementation
00882 
00883 /*************************************************************************************************/
00884 
00885 class sha1_t
00886 {
00887 public:
00888 #if !defined(ADOBE_NO_DOCUMENTATION)
00889     typedef implementation::sha_traits<sha1_t>   traits_type;
00890 #endif
00891     typedef traits_type::digest_type                    digest_type;
00892 
00893     template <typename I>
00894     inline digest_type digest(I first, I last)
00895     {
00896         enum { ibits_k = implementation::bitsizeof<typename std::iterator_traits<I>::value_type>::value };
00897 
00898         return digest(first, implementation::long_distance(first, last) * ibits_k);
00899     }
00900 
00901     template <typename I>
00902     inline digest_type digest(I first, boost::uint64_t num_bits)
00903     {
00904         traits_type().reset_digest(digest_m);
00905 
00906         implementation::block_and_digest<traits_type>(digest_m, first, num_bits);
00907 
00908         return digest_m;
00909     }
00910 
00911 private:
00912     digest_type digest_m;
00913 };
00914 
00915 /*************************************************************************************************/
00916 
00917 class sha224_t
00918 {
00919 public:
00920 #if !defined(ADOBE_NO_DOCUMENTATION)
00921     typedef implementation::sha_traits<sha224_t> traits_type;
00922 #endif
00923     typedef boost::array<boost::uint32_t, 7>            digest_type;
00924 
00925     template <typename I>
00926     inline digest_type digest(I first, I last)
00927     {
00928         enum { ibits_k = implementation::bitsizeof<typename std::iterator_traits<I>::value_type>::value };
00929 
00930         return digest(first, implementation::long_distance(first, last) * ibits_k);
00931     }
00932 
00933     template <typename I>
00934     inline digest_type digest(I first, boost::uint64_t num_bits)
00935     {
00936         traits_type().reset_digest(digest_m);
00937 
00938         implementation::block_and_digest<traits_type>(digest_m, first, num_bits);
00939 
00940         return crop_digest(digest_m);
00941     }
00942 
00943 private:
00944     inline digest_type crop_digest(traits_type::digest_type& digest)
00945     {
00946         digest_type result;
00947 
00948         std::copy(digest.begin(), digest.begin() + digest_type::static_size, &result[0]);
00949 
00950         return result;
00951     }
00952 
00953     traits_type::digest_type digest_m;
00954 };
00955 
00956 /*************************************************************************************************/
00957 
00958 class sha256_t
00959 {
00960 public:
00961 #if !defined(ADOBE_NO_DOCUMENTATION)
00962     typedef implementation::sha_traits<sha256_t> traits_type;
00963 #endif
00964     typedef traits_type::digest_type                    digest_type;
00965 
00966     template <typename I>
00967     inline digest_type digest(I first, I last)
00968     {
00969         enum { ibits_k = implementation::bitsizeof<typename std::iterator_traits<I>::value_type>::value };
00970 
00971         return digest(first, implementation::long_distance(first, last) * ibits_k);
00972     }
00973 
00974     template <typename I>
00975     inline digest_type digest(I first, boost::uint64_t num_bits)
00976     {
00977         traits_type().reset_digest(digest_m);
00978 
00979         implementation::block_and_digest<traits_type>(digest_m, first, num_bits);
00980 
00981         return digest_m;
00982     }
00983 
00984 private:
00985     digest_type digest_m;
00986 };
00987 
00988 /*************************************************************************************************/
00989 
00990 class sha512_t
00991 {
00992 public:
00993 #if !defined(ADOBE_NO_DOCUMENTATION)
00994     typedef implementation::sha_traits<sha512_t> traits_type;
00995 #endif
00996     typedef traits_type::digest_type                    digest_type;
00997 
00998     template <typename I>
00999     inline digest_type digest(I first, I last)
01000     {
01001         enum { ibits_k = implementation::bitsizeof<typename std::iterator_traits<I>::value_type>::value };
01002 
01003         return digest(first, implementation::long_distance(first, last) * ibits_k);
01004     }
01005 
01006     template <typename I>
01007     inline digest_type digest(I first, boost::uint64_t num_bits)
01008     {
01009         traits_type().reset_digest(digest_m);
01010 
01011         implementation::block_and_digest<traits_type>(digest_m, first, num_bits);
01012 
01013         return digest_m;
01014     }
01015 
01016 private:
01017     digest_type digest_m;
01018 };
01019 
01020 /*************************************************************************************************/
01021 
01022 class sha384_t
01023 {
01024 public:
01025 #if !defined(ADOBE_NO_DOCUMENTATION)
01026     typedef implementation::sha_traits<sha384_t> traits_type;
01027 #endif
01028     typedef boost::array<boost::uint64_t, 6>            digest_type;
01029 
01030     template <typename I>
01031     inline digest_type digest(I first, I last)
01032     {
01033         enum { ibits_k = implementation::bitsizeof<typename std::iterator_traits<I>::value_type>::value };
01034 
01035         return digest(first, implementation::long_distance(first, last) * ibits_k);
01036     }
01037 
01038     template <typename I>
01039     inline digest_type digest(I first, boost::uint64_t num_bits)
01040     {
01041         traits_type().reset_digest(digest_m);
01042 
01043         implementation::block_and_digest<traits_type>(digest_m, first, num_bits);
01044 
01045         return crop_digest(digest_m);
01046     }
01047 
01048 private:
01049     inline digest_type crop_digest(traits_type::digest_type& digest)
01050     {
01051         digest_type result;
01052 
01053         std::copy(digest.begin(), digest.begin() + digest_type::static_size, &result[0]);
01054 
01055         return result;
01056     }
01057 
01058     traits_type::digest_type digest_m;
01059 };
01060 
01061 /*************************************************************************************************/
01062 
01063 } // namespace adobe
01064 
01065 /*************************************************************************************************/
01066 
01067 #endif
01068 
01069 /*************************************************************************************************/

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