20 #ifndef _ANCH_CRYPTO_SHA2_H_ 21 #define _ANCH_CRYPTO_SHA2_H_ 23 #include "crypto/hash/hash.hpp" 24 #include "endianness.hpp" 50 template<std::
size_t O, std::
size_t B,
typename W, u
int32_t R, const std::array<W,8>& I>
61 uint8_t bytes[B *
sizeof(W)];
72 template<const std::array<W,8>& Init>
75 std::array<W,8> state;
84 std::array<uint8_t,O>
digest;
136 virtual const std::array<uint8_t,O>&
digest()
const override {
137 return _context.digest;
148 return (word >> bits);
158 return ((word << bits) | (word >> (
sizeof(W) * 8 - bits)));
168 return ((word >> bits) | (word << (
sizeof(W) * 8 - bits)));
175 virtual void reset()
override {
185 virtual void addData(
const uint8_t* data, std::size_t len)
override {
186 uint32_t rest =
static_cast<uint32_t
>(_context.size &
static_cast<uint64_t
>(B - 1));
188 uint64_t availableData =
static_cast<uint64_t
>(len) + static_cast<uint64_t>(rest);
189 _context.size += len;
191 if(availableData < static_cast<uint64_t>(B)) {
192 std::memcpy(&_context.buffer[rest], &data[0], len);
195 uint64_t i =
static_cast<uint64_t
>(B - rest);
196 std::memcpy(&_context.buffer[rest], &data[0], static_cast<uint32_t>(i));
197 transform(_context.buffer);
199 uint64_t lastI = len - ((len + rest) & static_cast<uint64_t>(B - 1));
200 for( ; i < lastI ; i += B) {
204 std::memcpy(&_context.buffer[0], &data[i], len - i);
211 virtual void finalize()
override {
212 uint64_t messageSize = _context.size;
213 uint8_t sizeInBits[
sizeof(W) * 2];
217 uint64_t tmp = messageSize << 3;
218 std::memcpy(sizeInBits, &tmp,
sizeof(W) * 2);
221 addData((
const uint8_t*)
"\200", 1);
224 std::memset(zero, 0, B);
225 if(static_cast<int>(messageSize & (B - 1)) > (B -
sizeof(W) * 2 - 1)) {
226 addData(zero, B - 1 - static_cast<size_t>(messageSize & (B - 1)));
227 addData(zero, B - 8);
229 addData(zero, B - 1 - 8 - static_cast<size_t>(messageSize & (B - 1)));
232 addData(sizeInBits, 8);
235 for(std::size_t i = 0 ; i < 8 ; i++) {
236 anch::byteSwap(_context.state[i], _context.digest.data() + (i *
sizeof(W)));
239 std::memcpy(_context.digest.data(),
240 _context.state.data(),
250 virtual const std::array<W,R>& getTranslationArray()
const = 0;
257 void transform(
const uint8_t* buffer) {
258 uint8_t chunkBuffer[B *
sizeof(W)];
259 std::memcpy(chunkBuffer, buffer, B *
sizeof(W));
261 Chunk* chunk =
reinterpret_cast<Chunk*
>(&chunkBuffer);
262 bytesSwap(chunk->words, B);
263 for(std::size_t i = 16 ; i < B ; i++) {
264 chunk->words[i] = sigma1(chunk->words[i-2]) + chunk->words[i-7]
265 + sigma0(chunk->words[i-15]) + chunk->words[i-16];
269 W a = _context.state[0];
270 W b = _context.state[1];
271 W c = _context.state[2];
272 W d = _context.state[3];
273 W e = _context.state[4];
274 W f = _context.state[5];
275 W g = _context.state[6];
276 W h = _context.state[7];
278 const std::array<W,R>& trArray = getTranslationArray();
279 for(uint32_t i = 0 ; i < R ; i++) {
280 W temp1 = h + SIGMA1(e) + ch(e, f, g) + trArray[i] + chunk->words[i];
281 W temp2 = SIGMA0(a) + maj(a, b, c);
293 _context.state[0] += a;
294 _context.state[1] += b;
295 _context.state[2] += c;
296 _context.state[3] += d;
297 _context.state[4] += e;
298 _context.state[5] += f;
299 _context.state[6] += g;
300 _context.state[7] += h;
309 static inline void bytesSwap(W* buf, uint8_t count) {
311 uint8_t* words =
reinterpret_cast<uint8_t*
>(buf);
327 static inline W ch(W x, W y, W z) {
328 return ((x & (y ^ z)) ^ z);
338 static inline W maj(W x, W y, W z) {
339 return ((x & (y | z)) | (y & z));
347 virtual W SIGMA0(W word)
const = 0;
354 virtual W SIGMA1(W word)
const = 0;
361 virtual W sigma0(W word)
const = 0;
368 virtual W sigma1(W word)
const = 0;
376 #endif // _ANCH_CRYPTO_SHA2_H_ virtual const std::array< uint8_t, O > & digest() const override
Definition: sha2.hpp:136
SHA2 abstract class.
Definition: sha2.hpp:51
AnCH framework base namespace.
Definition: base64.hpp:28
SHA2()
Definition: sha2.hpp:113
static constexpr W rotateLeft(uint8_t bits, W word)
Definition: sha2.hpp:157
void byteSwap(T src, uint8_t *dest)
Definition: endianness.hpp:39
Hash algorithm abstract class.
Definition: hash.hpp:41
virtual ~SHA2()
Definition: sha2.hpp:123
static constexpr W shiftRight(uint8_t bits, W word)
Definition: sha2.hpp:147
bool isLittleEndian()
Definition: endianness.hpp:70
static constexpr W rotateRight(uint8_t bits, W word)
Definition: sha2.hpp:167