@@ -578,17 +578,21 @@ namespace http
578578 return (x << s) | (x >> (32 - s));
579579 }
580580
581- const auto process_sha1_block = []( auto & hash, const auto & block, auto & words )
581+ static constexpr void process_sha1_block ( uint32_t (& hash)[5] , const uint8_t (&block)[64] )
582582 {
583583 // Initialise buffer
584+ uint32_t w[80 ] = {};
585+
584586 for (size_t i = 0 ; i < 16 ; ++i)
585587 {
586- std::memcpy (&words[i], &block[i*4 ], 4 );
587- words[i] = htobe32 (words[i]);
588+ w[i] = (block[i*4 + 0 ] << 24 );
589+ w[i] |= (block[i*4 + 1 ] << 16 );
590+ w[i] |= (block[i*4 + 2 ] << 8 );
591+ w[i] |= (block[i*4 + 3 ]);
588592 }
589593
590594 for (size_t i = 16 ; i < 80 ; ++i)
591- words [i] = rotl (words [i-3 ] ^ words [i-8 ] ^ words [i-14 ] ^ words [i-16 ], 1 );
595+ w [i] = rotl (w [i-3 ] ^ w [i-8 ] ^ w [i-14 ] ^ w [i-16 ], 1 );
592596
593597 // Initialize
594598 uint32_t a = hash[0 ];
@@ -600,7 +604,7 @@ namespace http
600604
601605 const auto fin = [&](const size_t i, const uint32_t k, const uint32_t f)
602606 {
603- const unsigned temp = rotl (a, 5 ) + f + e + k + words [i];
607+ const unsigned temp = rotl (a, 5 ) + f + e + k + w [i];
604608 e = d;
605609 d = c;
606610 c = rotl (b, 30 );
@@ -626,7 +630,7 @@ namespace http
626630 hash[2 ] += c;
627631 hash[3 ] += d;
628632 hash[4 ] += e;
629- };
633+ }
630634
631635 sha1& sha1::push (size_t ndata, const uint8_t * data)
632636 {
@@ -639,7 +643,7 @@ namespace http
639643 if (off == std::size (block))
640644 {
641645 off = 0 ;
642- process_sha1_block (hash, block, words );
646+ process_sha1_block (hash, block);
643647 }
644648 }
645649
@@ -649,42 +653,43 @@ namespace http
649653 sha1::digest sha1::finish ()
650654 {
651655 // number of bits
652- const uint64_t ml = htobe64 ( total*8 ) ;
656+ const uint64_t ml = total*8 ;
653657
654658 // Add 0x80
655659 block[off++] = 0x80 ;
656660 if (off == std::size (block))
657661 {
662+ process_sha1_block (hash, block);
658663 off = 0 ;
659- process_sha1_block (hash, block, words);
660664 }
661665
662666 // Add remaining 0 bits
663- const size_t end = off <= 56 ? 56 : 56 + 64 ;
664- for (size_t i = off ; i < end ; ++i)
667+ if (off > 56 )
665668 {
666- block[off++] = 0 ;
667- if (off == std::size (block))
668- {
669- off = 0 ;
670- process_sha1_block (hash, block, words);
671- }
669+ for (size_t i = off ; i < 64 ; ++i)
670+ block[off++] = 0 ;
671+ process_sha1_block (hash, block);
672+ off = 0 ;
672673 }
673- assert (off == 56 );
674+
675+ for (size_t i = off ; i < 56 ; ++i)
676+ block[off++] = 0 ;
674677
675678 // Add message length
676- uint8_t tmp[8 ];
677- memcpy (tmp, &ml, 8 );
678- for (size_t i = 0 ; i < 8 ; ++i)
679- block[off++] = tmp[i];
679+ for (int i = 7 ; i >= 0 ; --i)
680+ block[off++] = static_cast <uint8_t >((ml >> i*8 ) & 0xFF );
680681 assert (off == std::size (block));
681- process_sha1_block (hash, block, words );
682+ process_sha1_block (hash, block);
682683
683684 // Get final hash
684- sha1::digest h;
685- for (size_t i = 0 ; i < std::size (hash) ; ++i)
686- hash[i] = htobe32 (hash[i]);
687- std::memcpy (&h[0 ], &hash[0 ], h.size ());
685+ digest h = {};
686+ for (size_t i = 0 ; i < 5 ; ++i)
687+ {
688+ h[i*4 +0 ] = static_cast <uint8_t >((hash[i] >> 24 ) & 0xFF );
689+ h[i*4 +1 ] = static_cast <uint8_t >((hash[i] >> 16 ) & 0xFF );
690+ h[i*4 +2 ] = static_cast <uint8_t >((hash[i] >> 8 ) & 0xFF );
691+ h[i*4 +3 ] = static_cast <uint8_t >(hash[i] & 0xFF );
692+ }
688693 return h;
689694 }
690695
0 commit comments