Embedded systems coursework 2.
Fork of Crypto_light by
SHA1.cpp
- Committer:
- feb11
- Date:
- 2013-09-09
- Revision:
- 1:14a7cea431aa
- Parent:
- 0:7a1237bd2d13
- Child:
- 2:473bac39ae7c
File content as of revision 1:14a7cea431aa:
#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 h0 = H0, h1 = H1, h2 = H2, h3 = H3, h4 = H4; uint32_t offset = 0; while(length - offset >= 64) { computeBlock(&h0,&h1,&h2,&h3,&h4, &in[offset]); offset += 64; } uint8_t bufferLength = length - offset; uint8_t buffer[64]; memcpy(buffer, &in[offset], bufferLength); buffer[bufferLength++] = 0x80; padding--; while(padding > 0) { if(bufferLength == 64) { computeBlock(&h0,&h1,&h2,&h3,&h4, buffer); bufferLength++; } buffer[bufferLength++] = 0; padding--; } 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[60], l, 4); l[0] = lengthBitHigh >> 24; l[1] = lengthBitHigh >> 16; l[2] = lengthBitHigh >> 8; l[3] = lengthBitHigh; memcpy(&buffer[56], l, 4); computeBlock(&h0,&h1,&h2,&h3,&h4, 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; }