Fork of François Berder Crypto, fixed AES CBC and small rework
Dependents: AES_example shaun_larada Smartage
Fork of Crypto by
Diff: SHA1.cpp
- Revision:
- 0:7a1237bd2d13
- Child:
- 1:14a7cea431aa
diff -r 000000000000 -r 7a1237bd2d13 SHA1.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SHA1.cpp Sat Sep 07 23:47:28 2013 +0000 @@ -0,0 +1,235 @@ +#include "SHA1.h" +#include <string.h> + +static uint32_t f(uint8_t t, uint32_t B, uint32_t C, uint32_t D) +{ + if(t <= 19) + return (B & C) | ((~B) & D); + else if(t <= 39) + return B ^ C ^ D; + else if(t <= 59) + return (B & C) | (B & D) | (C & D); + else if(t <= 79) + return B ^ C ^ D; + + return 0; +} + +static uint32_t K(uint8_t t) +{ + if(t <= 19) + return 0x5A827999; + else if(t <= 39) + return 0x6ED9EBA1; + else if(t <= 59) + return 0x8F1BBCDC; + else if(t <= 79) + return 0xCA62C1D6; + + return 0; +} + +static uint32_t rotLeft(uint32_t w, uint8_t n) +{ + return (w << n) | (w >> (32-n)); +} + +static const uint32_t H0 = 0x67452301; +static const uint32_t H1 = 0xEFCDAB89; +static const uint32_t H2 = 0x98BADCFE; +static const uint32_t H3 = 0x10325476; +static const uint32_t H4 = 0xC3D2E1F0; +static const uint32_t MASK = 0x0000000F; + + +SHA1::SHA1(): +HashAlgorithm(), +h0(H0), +h1(H1), +h2(H2), +h3(H3), +h4(H4), +totalBufferLength(0), +buffer(), +bufferLength(0) +{ +} + +uint8_t SHA1::outputSize() const +{ + return 20; +} + +void SHA1::add(uint8_t *in, uint32_t length) +{ + if(length < 64-bufferLength) + { + memcpy(&buffer[bufferLength], in, length); + bufferLength += length; + totalBufferLength += length; + return; + } + int offset = 64-bufferLength; + memcpy(&buffer[bufferLength], in, offset); + computeBlock(&h0,&h1,&h2,&h3,&h4, buffer); + while(length-offset > 64) + { + memcpy(buffer, &in[offset], 64); + computeBlock(&h0,&h1,&h2,&h3,&h4, buffer); + offset += 64; + } + if(offset > length) + offset -= 64; + bufferLength = length - offset; + memcpy(buffer, &in[offset], bufferLength); + totalBufferLength += length; +} + +void SHA1::computeDigest(uint8_t *digest) +{ + uint16_t padding; + if(totalBufferLength % 64 < 56) + padding = 56 - (totalBufferLength % 64); + else + padding = 56 + (64 - (totalBufferLength % 64)); + uint8_t val = 0x80; + add(&val, 1); + val = 0; + for(int i = 0; i < padding-1; ++i) + add(&val,1); + totalBufferLength -= padding; + uint64_t lengthBit = totalBufferLength * 8; + uint32_t lengthBitLow = lengthBit; + uint32_t lengthBitHigh = lengthBit >> 32; + uint8_t l[4]; + + l[0] = lengthBitHigh >> 24; + l[1] = lengthBitHigh >> 16; + l[2] = lengthBitHigh >> 8; + l[3] = lengthBitHigh; + add(l, 4); + l[0] = lengthBitLow >> 24; + l[1] = lengthBitLow >> 16; + l[2] = lengthBitLow >> 8; + l[3] = lengthBitLow; + add(l, 4); + + digest[0] = h0 >> 24; + digest[1] = h0 >> 16; + digest[2] = h0 >> 8; + digest[3] = h0; + digest[4] = h1 >> 24; + digest[5] = h1 >> 16; + digest[6] = h1 >> 8; + digest[7] = h1; + digest[8] = h2 >> 24; + digest[9] = h2 >> 16; + digest[10] = h2 >> 8; + digest[11] = h2; + digest[12] = h3 >> 24; + digest[13] = h3 >> 16; + digest[14] = h3 >> 8; + digest[15] = h3; + digest[16] = h4 >> 24; + digest[17] = h4 >> 16; + digest[18] = h4 >> 8; + digest[19] = h4; + + // reset state + h0 = H0; + h1 = H1; + h2 = H2; + h3 = H3; + h4 = H4; + totalBufferLength = 0; + bufferLength = 0; +} + +void SHA1::computeBlock(uint32_t *h02, uint32_t *h12, uint32_t *h22, uint32_t *h32, uint32_t *h42, uint8_t *buffer) +{ + uint32_t w[16]; + for(int j = 0; j < 16; ++j) + w[j] = (buffer[j*4] << 24) | (buffer[j*4+1] << 16) | (buffer[j*4+2] << 8) | buffer[j*4+3]; + + uint32_t a = *h02, b = *h12, c = *h22, d = *h32, e = *h42; + for(uint8_t t = 0; t < 80; ++t) + { + uint32_t s = t & MASK; + if(t >= 16) + { + w[s%16] = w[((s + 13) & MASK)%16] ^ w[((s + 8) & MASK)%16] ^ w[((s + 2) & MASK)%16] ^ w[s%16]; + w[s%16] = rotLeft(w[s%16], 1); + } + + uint32_t temp = rotLeft(a, 5) + f(t, b, c, d) + e + w[s%16] + K(t); + e = d; + d = c; + c = rotLeft(b,30); + b = a; + a = temp; + } + *h02 += a; + *h12 += b; + *h22 += c; + *h32 += d; + *h42 += e; +} + + + +/* method 2 */ +void SHA1::computeDigest(uint8_t *digest, uint8_t *in, uint32_t length) +{ + uint16_t padding; + if(length % 64 < 56) + padding = 56 - (length % 64); + else + padding = 56 + (64 - (length % 64)); + uint32_t totalLength = length + padding + 8; + uint8_t *buffer = new uint8_t[totalLength]; + memcpy(buffer, in, length); + buffer[length] = 0x80; + memset(&buffer[length+1], 0, padding-1); + uint64_t lengthBit = length * 8; + uint32_t lengthBitLow = lengthBit; + uint32_t lengthBitHigh = lengthBit >> 32; + uint8_t l[4]; + l[0] = lengthBitLow >> 24; + l[1] = lengthBitLow >> 16; + l[2] = lengthBitLow >> 8; + l[3] = lengthBitLow; + memcpy(&buffer[length+padding+4], l, 4); + l[0] = lengthBitHigh >> 24; + l[1] = lengthBitHigh >> 16; + l[2] = lengthBitHigh >> 8; + l[3] = lengthBitHigh; + memcpy(&buffer[length+padding], l, 4); + + uint32_t h0 = H0, h1 = H1, h2 = H2, h3 = H3, h4 = H4; + for(int i = 0; i < totalLength/64; ++i) + computeBlock(&h0,&h1,&h2,&h3,&h4, &buffer[64*i]); + + delete[] buffer; + + digest[0] = h0 >> 24; + digest[1] = h0 >> 16; + digest[2] = h0 >> 8; + digest[3] = h0; + digest[4] = h1 >> 24; + digest[5] = h1 >> 16; + digest[6] = h1 >> 8; + digest[7] = h1; + digest[8] = h2 >> 24; + digest[9] = h2 >> 16; + digest[10] = h2 >> 8; + digest[11] = h2; + digest[12] = h3 >> 24; + digest[13] = h3 >> 16; + digest[14] = h3 >> 8; + digest[15] = h3; + digest[16] = h4 >> 24; + digest[17] = h4 >> 16; + digest[18] = h4 >> 8; + digest[19] = h4; +} +