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 const WordType &a = values[(88-i)&7];
93 const WordType &b = values[(89-i)&7];
94 const WordType &c = values[(90-i)&7];
95 WordType &d = values[(91-i)&7];
96 const WordType &e = values[(92-i)&7];
97 const WordType &f = values[(93-i)&7];
98 const WordType &g = values[(94-i)&7];
99 WordType &h = values[(95-i)&7];
101 WordType s1 = rotate_right(e, sigma[3]) ^ rotate_right(e, sigma[4]) ^ rotate_right(e, sigma[5]);
102 WordType ch = (e&f) ^ (~e&g);
103 WordType temp1 = h+s1+ch+Constants::round_constants[i]+message_blocks[i];
104 WordType s0 = rotate_right(a, sigma[0]) ^ rotate_right(a, sigma[1]) ^ rotate_right(a, sigma[2]);
105 WordType maj = (a&b) ^ (a&c) ^ (b&c);
106 WordType temp2 = s0+maj;
108 d += temp1; // Will be e next round
109 h = temp1+temp2; // Will be a next round
112 for(unsigned i=0; i<8; ++i)
113 buffer[i] += values[i];
115 processed_bytes += Constants::BLOCK_SIZE;
117 template void SHA2<SHA256Constants>::process_block(const char *);
118 template void SHA2<SHA512Constants>::process_block(const char *);
121 unsigned SHA2<C>::get_digest(char *digest, unsigned len) const
123 if(len<Constants::DIGEST_SIZE)
124 throw invalid_argument("SHA2::get_digest");
126 SHA2<Constants> padded = *this;
128 char padding[Constants::BLOCK_SIZE] = { static_cast<char>(0x80) };
129 padded.update(padding, Constants::BLOCK_SIZE-(this->unprocessed_bytes+Constants::MIN_PADDING)%Constants::BLOCK_SIZE);
131 padded.update(padding+1, Constants::MIN_PADDING-8);
132 UInt64 message_length = (processed_bytes+this->unprocessed_bytes)*8;
133 write_word(message_length, padding);
134 padded.update(padding, 8);
136 for(unsigned i=0; i<8; ++i)
137 write_word(padded.buffer[i], digest+i*Constants::WORD_SIZE);
139 return Constants::DIGEST_SIZE;
141 template unsigned SHA2<SHA256Constants>::get_digest(char *, unsigned) const;
142 template unsigned SHA2<SHA512Constants>::get_digest(char *, unsigned) const;
145 const SHA256Constants::WordType SHA256Constants::initial[8] =
147 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
150 const SHA256Constants::WordType SHA256Constants::round_constants[SHA256Constants::N_ROUNDS] =
152 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
153 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
154 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
155 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
156 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
157 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
158 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
159 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
162 const unsigned SHA256Constants::sigma_constants[12] =
170 const SHA512Constants::WordType SHA512Constants::initial[8] =
172 0x6A09E667F3BCC908, 0xBB67AE8584CAA73B, 0x3C6EF372FE94F82B, 0xA54FF53A5F1D36F1,
173 0x510E527FADE682D1, 0x9B05688C2B3E6C1F, 0x1F83D9ABFB41BD6B, 0x5BE0CD19137E2179,
176 const SHA512Constants::WordType SHA512Constants::round_constants[SHA512Constants::N_ROUNDS] =
178 0x428A2F98D728AE22, 0x7137449123EF65CD, 0xB5C0FBCFEC4D3B2F, 0xE9B5DBA58189DBBC,
179 0x3956C25BF348B538, 0x59F111F1B605D019, 0x923F82A4AF194F9B, 0xAB1C5ED5DA6D8118,
180 0xD807AA98A3030242, 0x12835B0145706FBE, 0x243185BE4EE4B28C, 0x550C7DC3D5FFB4E2,
181 0x72BE5D74F27B896F, 0x80DEB1FE3B1696B1, 0x9BDC06A725C71235, 0xC19BF174CF692694,
182 0xE49B69C19EF14AD2, 0xEFBE4786384F25E3, 0x0FC19DC68B8CD5B5, 0x240CA1CC77AC9C65,
183 0x2DE92C6F592B0275, 0x4A7484AA6EA6E483, 0x5CB0A9DCBD41FBD4, 0x76F988DA831153B5,
184 0x983E5152EE66DFAB, 0xA831C66D2DB43210, 0xB00327C898FB213F, 0xBF597FC7BEEF0EE4,
185 0xC6E00BF33DA88FC2, 0xD5A79147930AA725, 0x06CA6351E003826F, 0x142929670A0E6E70,
186 0x27B70A8546D22FFC, 0x2E1B21385C26C926, 0x4D2C6DFC5AC42AED, 0x53380D139D95B3DF,
187 0x650A73548BAF63DE, 0x766A0ABB3C77B2A8, 0x81C2C92E47EDAEE6, 0x92722C851482353B,
188 0xA2BFE8A14CF10364, 0xA81A664BBC423001, 0xC24B8B70D0F89791, 0xC76C51A30654BE30,
189 0xD192E819D6EF5218, 0xD69906245565A910, 0xF40E35855771202A, 0x106AA07032BBD1B8,
190 0x19A4C116B8D2D0C8, 0x1E376C085141AB53, 0x2748774CDF8EEB99, 0x34B0BCB5E19B48A8,
191 0x391C0CB3C5C95A63, 0x4ED8AA4AE3418ACB, 0x5B9CCA4F7763E373, 0x682E6FF3D6B2B8A3,
192 0x748F82EE5DEFB2FC, 0x78A5636F43172F60, 0x84C87814A1F0AB72, 0x8CC702081A6439EC,
193 0x90BEFFFA23631E28, 0xA4506CEBDE82BDE9, 0xBEF9A3F7B2C67915, 0xC67178F2E372532B,
194 0xCA273ECEEA26619C, 0xD186B8C721C0C207, 0xEADA7DD6CDE0EB1E, 0xF57D4F7FEE6ED178,
195 0x06F067AA72176FBA, 0x0A637DC5A2C898A6, 0x113F9804BEF90DAE, 0x1B710B35131C471B,
196 0x28DB77F523047D84, 0x32CAAB7B40C72493, 0x3C9EBE0A15C9BEBC, 0x431D67C49C100D4C,
197 0x4CC5D4BECB3E42B6, 0x597F299CFC657E2A, 0x5FCB6FAB3AD6FAEC, 0x6C44198C4A475817
199 const unsigned SHA512Constants::sigma_constants[12] =
201 28, 34, 39, // For Σ₀
202 14, 18, 41, // For Σ₁
207 } // namespace Crypto