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<SHA256Constants>::SHA2();
43 template SHA2<SHA512Constants>::SHA2();
46 SHA2<C>::SHA2(const char *data, unsigned len)
49 BlockHash<Constants::BLOCK_SIZE>::update(data, len);
51 template SHA2<SHA256Constants>::SHA2(const char *, unsigned);
52 template SHA2<SHA512Constants>::SHA2(const char *, unsigned);
55 SHA2<C>::SHA2(const string &str)
58 BlockHash<Constants::BLOCK_SIZE>::update(str);
60 template SHA2<SHA256Constants>::SHA2(const string &);
61 template SHA2<SHA512Constants>::SHA2(const string &);
66 copy(Constants::initial, Constants::initial+8, buffer);
69 template void SHA2<SHA256Constants>::init();
70 template void SHA2<SHA512Constants>::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<SHA256Constants>::process_block(const char *);
114 template void SHA2<SHA512Constants>::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+Constants::MIN_PADDING)%Constants::BLOCK_SIZE);
127 padded.update(padding+1, Constants::MIN_PADDING-8);
128 UInt64 message_length = (processed_bytes+this->unprocessed_bytes)*8;
129 write_word(message_length, padding);
130 padded.update(padding, 8);
132 for(unsigned i=0; i<8; ++i)
133 write_word(padded.buffer[i], digest+i*Constants::WORD_SIZE);
135 return Constants::DIGEST_SIZE;
137 template unsigned SHA2<SHA256Constants>::get_digest(char *, unsigned) const;
138 template unsigned SHA2<SHA512Constants>::get_digest(char *, unsigned) const;
141 const SHA256Constants::WordType SHA256Constants::initial[8] =
143 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
146 const SHA256Constants::WordType SHA256Constants::round_constants[SHA256Constants::N_ROUNDS] =
148 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
149 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
150 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
151 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
152 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
153 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
154 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
155 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
158 const unsigned SHA256Constants::sigma_constants[12] =
166 const SHA512Constants::WordType SHA512Constants::initial[8] =
168 0x6A09E667F3BCC908, 0xBB67AE8584CAA73B, 0x3C6EF372FE94F82B, 0xA54FF53A5F1D36F1,
169 0x510E527FADE682D1, 0x9B05688C2B3E6C1F, 0x1F83D9ABFB41BD6B, 0x5BE0CD19137E2179,
172 const SHA512Constants::WordType SHA512Constants::round_constants[SHA512Constants::N_ROUNDS] =
174 0x428A2F98D728AE22, 0x7137449123EF65CD, 0xB5C0FBCFEC4D3B2F, 0xE9B5DBA58189DBBC,
175 0x3956C25BF348B538, 0x59F111F1B605D019, 0x923F82A4AF194F9B, 0xAB1C5ED5DA6D8118,
176 0xD807AA98A3030242, 0x12835B0145706FBE, 0x243185BE4EE4B28C, 0x550C7DC3D5FFB4E2,
177 0x72BE5D74F27B896F, 0x80DEB1FE3B1696B1, 0x9BDC06A725C71235, 0xC19BF174CF692694,
178 0xE49B69C19EF14AD2, 0xEFBE4786384F25E3, 0x0FC19DC68B8CD5B5, 0x240CA1CC77AC9C65,
179 0x2DE92C6F592B0275, 0x4A7484AA6EA6E483, 0x5CB0A9DCBD41FBD4, 0x76F988DA831153B5,
180 0x983E5152EE66DFAB, 0xA831C66D2DB43210, 0xB00327C898FB213F, 0xBF597FC7BEEF0EE4,
181 0xC6E00BF33DA88FC2, 0xD5A79147930AA725, 0x06CA6351E003826F, 0x142929670A0E6E70,
182 0x27B70A8546D22FFC, 0x2E1B21385C26C926, 0x4D2C6DFC5AC42AED, 0x53380D139D95B3DF,
183 0x650A73548BAF63DE, 0x766A0ABB3C77B2A8, 0x81C2C92E47EDAEE6, 0x92722C851482353B,
184 0xA2BFE8A14CF10364, 0xA81A664BBC423001, 0xC24B8B70D0F89791, 0xC76C51A30654BE30,
185 0xD192E819D6EF5218, 0xD69906245565A910, 0xF40E35855771202A, 0x106AA07032BBD1B8,
186 0x19A4C116B8D2D0C8, 0x1E376C085141AB53, 0x2748774CDF8EEB99, 0x34B0BCB5E19B48A8,
187 0x391C0CB3C5C95A63, 0x4ED8AA4AE3418ACB, 0x5B9CCA4F7763E373, 0x682E6FF3D6B2B8A3,
188 0x748F82EE5DEFB2FC, 0x78A5636F43172F60, 0x84C87814A1F0AB72, 0x8CC702081A6439EC,
189 0x90BEFFFA23631E28, 0xA4506CEBDE82BDE9, 0xBEF9A3F7B2C67915, 0xC67178F2E372532B,
190 0xCA273ECEEA26619C, 0xD186B8C721C0C207, 0xEADA7DD6CDE0EB1E, 0xF57D4F7FEE6ED178,
191 0x06F067AA72176FBA, 0x0A637DC5A2C898A6, 0x113F9804BEF90DAE, 0x1B710B35131C471B,
192 0x28DB77F523047D84, 0x32CAAB7B40C72493, 0x3C9EBE0A15C9BEBC, 0x431D67C49C100D4C,
193 0x4CC5D4BECB3E42B6, 0x597F299CFC657E2A, 0x5FCB6FAB3AD6FAEC, 0x6C44198C4A475817
195 const unsigned SHA512Constants::sigma_constants[12] =
197 28, 34, 39, // For Σ₀
198 14, 18, 41, // For Σ₁
203 } // namespace Crypto