9 inline T read_word(const char *data)
11 const Msp::UInt8 *u8data = reinterpret_cast<const Msp::UInt8 *>(data);
13 for(unsigned i=0; i<sizeof(T); ++i)
14 result |= static_cast<T>(u8data[i])<<((sizeof(T)-1-i)*8);
19 inline void write_word(T w, char *buf)
21 for(unsigned i=0; i<sizeof(T); ++i)
22 buf[i] = w>>((sizeof(T)-1-i)*8);
26 inline T rotate_right(T x, unsigned b)
28 return (x>>b) | (x<<(sizeof(T)*8-b));
42 template SHA2<SHA2_256Constants>::SHA2();
43 template SHA2<SHA2_512Constants>::SHA2();
46 SHA2<C>::SHA2(const char *data, unsigned len)
49 BlockHash<Constants::BLOCK_SIZE>::update(data, len);
51 template SHA2<SHA2_256Constants>::SHA2(const char *, unsigned);
52 template SHA2<SHA2_512Constants>::SHA2(const char *, unsigned);
55 SHA2<C>::SHA2(const string &str)
58 BlockHash<Constants::BLOCK_SIZE>::update(str);
60 template SHA2<SHA2_256Constants>::SHA2(const string &);
61 template SHA2<SHA2_512Constants>::SHA2(const string &);
66 copy(Constants::initial, Constants::initial+8, buffer);
69 template void SHA2<SHA2_256Constants>::init();
70 template void SHA2<SHA2_512Constants>::init();
73 void SHA2<C>::process_block(const char *data)
75 WordType message_blocks[Constants::N_ROUNDS];
76 for(unsigned i=0; i<Constants::BLOCK_SIZE/Constants::WORD_SIZE; ++i)
77 message_blocks[i] = read_word<WordType>(data+i*Constants::WORD_SIZE);
78 const unsigned *const sigma = Constants::sigma_constants;
79 for(unsigned i=16; i<Constants::N_ROUNDS; ++i)
81 WordType *block = message_blocks+i;
82 WordType s1 = (rotate_right(block[-2], sigma[9]) ^ rotate_right(block[-2], sigma[10]) ^ (block[-2]>>sigma[11]));
83 WordType s0 = (rotate_right(block[-15], sigma[6]) ^ rotate_right(block[-15], sigma[7]) ^ (block[-15]>>sigma[8]));
84 *block = s1+block[-7]+s0+block[-16];
88 copy(buffer, buffer+8, values);
90 for(unsigned i=0; i<Constants::N_ROUNDS; ++i)
92 WordType s1 = (rotate_right(values[4], sigma[3]) ^ rotate_right(values[4], sigma[4]) ^ rotate_right(values[4], sigma[5]));
93 WordType ch = ((values[4]&values[5]) ^ (~values[4]&values[6]));
94 WordType temp1 = values[7]+s1+ch+Constants::round_constants[i]+message_blocks[i];
95 WordType s0 = (rotate_right(values[0], sigma[0]) ^ rotate_right(values[0], sigma[1]) ^ rotate_right(values[0], sigma[2]));
96 WordType maj = ((values[0]&values[1]) ^ (values[0]&values[2]) ^ (values[1]&values[2]));
97 WordType temp2 = s0+maj;
98 values[7] = values[6];
99 values[6] = values[5];
100 values[5] = values[4];
101 values[4] = values[3]+temp1;
102 values[3] = values[2];
103 values[2] = values[1];
104 values[1] = values[0];
105 values[0] = temp1+temp2;
108 for(unsigned i=0; i<8; ++i)
109 buffer[i] += values[i];
111 processed_bytes += Constants::BLOCK_SIZE;
113 template void SHA2<SHA2_256Constants>::process_block(const char *);
114 template void SHA2<SHA2_512Constants>::process_block(const char *);
117 unsigned SHA2<C>::get_digest(char *digest, unsigned len) const
119 if(len<Constants::DIGEST_SIZE)
120 throw invalid_argument("SHA2::get_digest");
122 SHA2<Constants> padded = *this;
124 char padding[Constants::BLOCK_SIZE] = { static_cast<char>(0x80) };
125 padded.update(padding, Constants::BLOCK_SIZE-(this->unprocessed_bytes+8)%Constants::BLOCK_SIZE);
127 UInt64 message_length = (processed_bytes+this->unprocessed_bytes)*8;
128 write_word(message_length, padding);
129 padded.update(padding, 8);
131 for(unsigned i=0; i<8; ++i)
132 write_word(padded.buffer[i], digest+i*Constants::WORD_SIZE);
134 return Constants::DIGEST_SIZE;
136 template unsigned SHA2<SHA2_256Constants>::get_digest(char *, unsigned) const;
137 template unsigned SHA2<SHA2_512Constants>::get_digest(char *, unsigned) const;
140 const SHA2_256Constants::WordType SHA2_256Constants::initial[8] =
142 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
145 const SHA2_256Constants::WordType SHA2_256Constants::round_constants[SHA2_256Constants::N_ROUNDS] =
147 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
148 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
149 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
150 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
151 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
152 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
153 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
154 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
157 const unsigned SHA2_256Constants::sigma_constants[12] =
165 const SHA2_512Constants::WordType SHA2_512Constants::initial[8] =
167 0x6A09E667F3BCC908, 0xBB67AE8584CAA73B, 0x3C6EF372FE94F82B, 0xA54FF53A5F1D36F1,
168 0x510E527FADE682D1, 0x9B05688C2B3E6C1F, 0x1F83D9ABFB41BD6B, 0x5BE0CD19137E2179,
171 const SHA2_512Constants::WordType SHA2_512Constants::round_constants[SHA2_512Constants::N_ROUNDS] =
173 0x428A2F98D728AE22, 0x7137449123EF65CD, 0xB5C0FBCFEC4D3B2F, 0xE9B5DBA58189DBBC,
174 0x3956C25BF348B538, 0x59F111F1B605D019, 0x923F82A4AF194F9B, 0xAB1C5ED5DA6D8118,
175 0xD807AA98A3030242, 0x12835B0145706FBE, 0x243185BE4EE4B28C, 0x550C7DC3D5FFB4E2,
176 0x72BE5D74F27B896F, 0x80DEB1FE3B1696B1, 0x9BDC06A725C71235, 0xC19BF174CF692694,
177 0xE49B69C19EF14AD2, 0xEFBE4786384F25E3, 0x0FC19DC68B8CD5B5, 0x240CA1CC77AC9C65,
178 0x2DE92C6F592B0275, 0x4A7484AA6EA6E483, 0x5CB0A9DCBD41FBD4, 0x76F988DA831153B5,
179 0x983E5152EE66DFAB, 0xA831C66D2DB43210, 0xB00327C898FB213F, 0xBF597FC7BEEF0EE4,
180 0xC6E00BF33DA88FC2, 0xD5A79147930AA725, 0x06CA6351E003826F, 0x142929670A0E6E70,
181 0x27B70A8546D22FFC, 0x2E1B21385C26C926, 0x4D2C6DFC5AC42AED, 0x53380D139D95B3DF,
182 0x650A73548BAF63DE, 0x766A0ABB3C77B2A8, 0x81C2C92E47EDAEE6, 0x92722C851482353B,
183 0xA2BFE8A14CF10364, 0xA81A664BBC423001, 0xC24B8B70D0F89791, 0xC76C51A30654BE30,
184 0xD192E819D6EF5218, 0xD69906245565A910, 0xF40E35855771202A, 0x106AA07032BBD1B8,
185 0x19A4C116B8D2D0C8, 0x1E376C085141AB53, 0x2748774CDF8EEB99, 0x34B0BCB5E19B48A8,
186 0x391C0CB3C5C95A63, 0x4ED8AA4AE3418ACB, 0x5B9CCA4F7763E373, 0x682E6FF3D6B2B8A3,
187 0x748F82EE5DEFB2FC, 0x78A5636F43172F60, 0x84C87814A1F0AB72, 0x8CC702081A6439EC,
188 0x90BEFFFA23631E28, 0xA4506CEBDE82BDE9, 0xBEF9A3F7B2C67915, 0xC67178F2E372532B,
189 0xCA273ECEEA26619C, 0xD186B8C721C0C207, 0xEADA7DD6CDE0EB1E, 0xF57D4F7FEE6ED178,
190 0x06F067AA72176FBA, 0x0A637DC5A2C898A6, 0x113F9804BEF90DAE, 0x1B710B35131C471B,
191 0x28DB77F523047D84, 0x32CAAB7B40C72493, 0x3C9EBE0A15C9BEBC, 0x431D67C49C100D4C,
192 0x4CC5D4BECB3E42B6, 0x597F299CFC657E2A, 0x5FCB6FAB3AD6FAEC, 0x6C44198C4A475817
194 const unsigned SHA2_512Constants::sigma_constants[12] =
196 28, 34, 39, // For Σ₀
197 14, 18, 41, // For Σ₁
202 } // namespace Crypto