]> git.tdb.fi Git - libs/crypto.git/blobdiff - source/sha2.cpp
Avoid shuffling the data around in memory so much
[libs/crypto.git] / source / sha2.cpp
index c7f51a5bb00cffeecc9147e6d1dff116401e1534..c0cb1a172be384c80a12146eb66f21fd80004f4c 100644 (file)
@@ -39,8 +39,8 @@ SHA2<C>::SHA2()
 {
        init();
 }
-template SHA2<SHA2_256Constants>::SHA2();
-template SHA2<SHA2_512Constants>::SHA2();
+template SHA2<SHA256Constants>::SHA2();
+template SHA2<SHA512Constants>::SHA2();
 
 template<typename C>
 SHA2<C>::SHA2(const char *data, unsigned len)
@@ -48,8 +48,8 @@ SHA2<C>::SHA2(const char *data, unsigned len)
        init();
        BlockHash<Constants::BLOCK_SIZE>::update(data, len);
 }
-template SHA2<SHA2_256Constants>::SHA2(const char *, unsigned);
-template SHA2<SHA2_512Constants>::SHA2(const char *, unsigned);
+template SHA2<SHA256Constants>::SHA2(const char *, unsigned);
+template SHA2<SHA512Constants>::SHA2(const char *, unsigned);
 
 template<typename C>
 SHA2<C>::SHA2(const string &str)
@@ -57,8 +57,8 @@ SHA2<C>::SHA2(const string &str)
        init();
        BlockHash<Constants::BLOCK_SIZE>::update(str);
 }
-template SHA2<SHA2_256Constants>::SHA2(const string &);
-template SHA2<SHA2_512Constants>::SHA2(const string &);
+template SHA2<SHA256Constants>::SHA2(const string &);
+template SHA2<SHA512Constants>::SHA2(const string &);
 
 template<typename C>
 void SHA2<C>::init()
@@ -66,8 +66,8 @@ void SHA2<C>::init()
        copy(Constants::initial, Constants::initial+8, buffer);
        processed_bytes = 0;
 }
-template void SHA2<SHA2_256Constants>::init();
-template void SHA2<SHA2_512Constants>::init();
+template void SHA2<SHA256Constants>::init();
+template void SHA2<SHA512Constants>::init();
 
 template<typename C>
 void SHA2<C>::process_block(const char *data)
@@ -79,8 +79,8 @@ void SHA2<C>::process_block(const char *data)
        for(unsigned i=16; i<Constants::N_ROUNDS; ++i)
        {
                WordType *block = message_blocks+i;
-               WordType s1 = (rotate_right(block[-2], sigma[9]) ^ rotate_right(block[-2], sigma[10]) ^ (block[-2]>>sigma[11]));
-               WordType s0 = (rotate_right(block[-15], sigma[6]) ^ rotate_right(block[-15], sigma[7]) ^ (block[-15]>>sigma[8]));
+               WordType s1 = rotate_right(block[-2], sigma[9]) ^ rotate_right(block[-2], sigma[10]) ^ (block[-2]>>sigma[11]);
+               WordType s0 = rotate_right(block[-15], sigma[6]) ^ rotate_right(block[-15], sigma[7]) ^ (block[-15]>>sigma[8]);
                *block =  s1+block[-7]+s0+block[-16];
        }
 
@@ -89,20 +89,24 @@ void SHA2<C>::process_block(const char *data)
 
        for(unsigned i=0; i<Constants::N_ROUNDS; ++i)
        {
-               WordType s1 = (rotate_right(values[4], sigma[3]) ^ rotate_right(values[4], sigma[4]) ^ rotate_right(values[4], sigma[5]));
-               WordType ch = ((values[4]&values[5]) ^ (~values[4]&values[6]));
-               WordType temp1 = values[7]+s1+ch+Constants::round_constants[i]+message_blocks[i];
-               WordType s0 = (rotate_right(values[0], sigma[0]) ^ rotate_right(values[0], sigma[1]) ^ rotate_right(values[0], sigma[2]));
-               WordType maj = ((values[0]&values[1]) ^ (values[0]&values[2]) ^ (values[1]&values[2]));
+               const WordType &a = values[(88-i)&7];
+               const WordType &b = values[(89-i)&7];
+               const WordType &c = values[(90-i)&7];
+               WordType &d = values[(91-i)&7];
+               const WordType &e = values[(92-i)&7];
+               const WordType &f = values[(93-i)&7];
+               const WordType &g = values[(94-i)&7];
+               WordType &h = values[(95-i)&7];
+
+               WordType s1 = rotate_right(e, sigma[3]) ^ rotate_right(e, sigma[4]) ^ rotate_right(e, sigma[5]);
+               WordType ch = (e&f) ^ (~e&g);
+               WordType temp1 = h+s1+ch+Constants::round_constants[i]+message_blocks[i];
+               WordType s0 = rotate_right(a, sigma[0]) ^ rotate_right(a, sigma[1]) ^ rotate_right(a, sigma[2]);
+               WordType maj = (a&b) ^ (a&c) ^ (b&c);
                WordType temp2 = s0+maj;
-               values[7] = values[6];
-               values[6] = values[5];
-               values[5] = values[4];
-               values[4] = values[3]+temp1;
-               values[3] = values[2];
-               values[2] = values[1];
-               values[1] = values[0];
-               values[0] = temp1+temp2;
+
+               d += temp1;       // Will be e next round
+               h = temp1+temp2;  // Will be a next round
        }
 
        for(unsigned i=0; i<8; ++i)
@@ -110,8 +114,8 @@ void SHA2<C>::process_block(const char *data)
 
        processed_bytes += Constants::BLOCK_SIZE;
 }
-template void SHA2<SHA2_256Constants>::process_block(const char *);
-template void SHA2<SHA2_512Constants>::process_block(const char *);
+template void SHA2<SHA256Constants>::process_block(const char *);
+template void SHA2<SHA512Constants>::process_block(const char *);
 
 template<typename C>
 unsigned SHA2<C>::get_digest(char *digest, unsigned len) const
@@ -134,16 +138,16 @@ unsigned SHA2<C>::get_digest(char *digest, unsigned len) const
 
        return Constants::DIGEST_SIZE;
 }
-template unsigned SHA2<SHA2_256Constants>::get_digest(char *, unsigned) const;
-template unsigned SHA2<SHA2_512Constants>::get_digest(char *, unsigned) const;
+template unsigned SHA2<SHA256Constants>::get_digest(char *, unsigned) const;
+template unsigned SHA2<SHA512Constants>::get_digest(char *, unsigned) const;
 
 
-const SHA2_256Constants::WordType SHA2_256Constants::initial[8] =
+const SHA256Constants::WordType SHA256Constants::initial[8] =
 {
        0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
 };
 
-const SHA2_256Constants::WordType SHA2_256Constants::round_constants[SHA2_256Constants::N_ROUNDS] =
+const SHA256Constants::WordType SHA256Constants::round_constants[SHA256Constants::N_ROUNDS] =
 {
        0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
        0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
@@ -155,7 +159,7 @@ const SHA2_256Constants::WordType SHA2_256Constants::round_constants[SHA2_256Con
        0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
 };
 
-const unsigned SHA2_256Constants::sigma_constants[12] =
+const unsigned SHA256Constants::sigma_constants[12] =
 {
        2, 13, 22,  // For Σ₀
        6, 11, 25,  // For Σ₁
@@ -163,13 +167,13 @@ const unsigned SHA2_256Constants::sigma_constants[12] =
        17, 19, 10  // For σ₁
 };
 
-const SHA2_512Constants::WordType SHA2_512Constants::initial[8] =
+const SHA512Constants::WordType SHA512Constants::initial[8] =
 {
        0x6A09E667F3BCC908, 0xBB67AE8584CAA73B, 0x3C6EF372FE94F82B, 0xA54FF53A5F1D36F1,
        0x510E527FADE682D1, 0x9B05688C2B3E6C1F, 0x1F83D9ABFB41BD6B, 0x5BE0CD19137E2179,
 };
 
-const SHA2_512Constants::WordType SHA2_512Constants::round_constants[SHA2_512Constants::N_ROUNDS] =
+const SHA512Constants::WordType SHA512Constants::round_constants[SHA512Constants::N_ROUNDS] =
 {
        0x428A2F98D728AE22, 0x7137449123EF65CD, 0xB5C0FBCFEC4D3B2F, 0xE9B5DBA58189DBBC,
        0x3956C25BF348B538, 0x59F111F1B605D019, 0x923F82A4AF194F9B, 0xAB1C5ED5DA6D8118,
@@ -192,7 +196,7 @@ const SHA2_512Constants::WordType SHA2_512Constants::round_constants[SHA2_512Con
        0x28DB77F523047D84, 0x32CAAB7B40C72493, 0x3C9EBE0A15C9BEBC, 0x431D67C49C100D4C,
        0x4CC5D4BECB3E42B6, 0x597F299CFC657E2A, 0x5FCB6FAB3AD6FAEC, 0x6C44198C4A475817
 };
-const unsigned SHA2_512Constants::sigma_constants[12] =
+const unsigned SHA512Constants::sigma_constants[12] =
 {
        28, 34, 39,  // For Σ₀
        14, 18, 41,  // For Σ₁