Embedded systems coursework 2.
Fork of Crypto_light by
Diff: SHA1.cpp
- Revision:
- 3:85c6ee25cf3e
- Parent:
- 2:473bac39ae7c
- Child:
- 4:0da19393bd57
--- a/SHA1.cpp Mon Sep 09 16:16:24 2013 +0000 +++ b/SHA1.cpp Wed Sep 11 17:22:40 2013 +0000 @@ -1,47 +1,41 @@ #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; -} +#include <stdio.h> +#include <stdlib.h> -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; -} +#define F0(B,C,D) ((B & C) | ((~B) & D)) +#define F1(B,C,D) (B ^ C ^ D) +#define F2(B,C,D) ((B & C) | (B & D) | (C & D)) +#define ROTL(W,N) (((W) << N) | ((W) >> (32-N))) + +static const uint32_t K0 = 0x5A827999; +static const uint32_t K1 = 0x6ED9EBA1; +static const uint32_t K2 = 0x8F1BBCDC; +static const uint32_t K3 = 0xCA62C1D6; -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; + +static const uint32_t MASK = 0xF; + +#define W(s) ( w[s] = ROTL(w[((s) + 13) & MASK] ^ w[((s) + 8) & MASK] ^ w[((s) + 2) & MASK] ^ w[s],1)) +#define R0(A,B,C,D,E,T) E += ROTL(A, 5) + F0(B, C, D) + w[T] + K0; \ + B = ROTL(B,30); +#define R1(A,B,C,D,E,T) E += ROTL(A, 5) + F0(B, C, D) + W(T & MASK) + K0; \ + B = ROTL(B,30); +#define R2(A,B,C,D,E,T) E += ROTL(A, 5) + F1(B, C, D) + W(T & MASK) + K1; \ + B = ROTL(B,30); +#define R3(A,B,C,D,E,T) E += ROTL(A, 5) + F2(B, C, D) + W(T & MASK) + K2; \ + B = ROTL(B,30); +#define R4(A,B,C,D,E,T) E += ROTL(A, 5) + F1(B, C, D) + W(T & MASK) + K3; \ + B = ROTL(B,30); + SHA1::SHA1(): HashAlgorithm(), h0(H0), @@ -87,53 +81,38 @@ void SHA1::computeDigest(uint8_t *digest) { + uint32_t *digest2 = (uint32_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; + + buffer[bufferLength++] = 0x80; + padding--; + if(padding+bufferLength == 56) + memset(&buffer[bufferLength], 0, padding); + else + { + memset(&buffer[bufferLength], 0, 64-bufferLength); + computeBlock(&h0,&h1,&h2,&h3,&h4, buffer); + memset(buffer, 0, 48); + } + + uint64_t lengthBit = totalBufferLength << 3; 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; + lengthBitLow = __rev(lengthBitLow); + lengthBitHigh = __rev(lengthBitHigh); + memcpy(&buffer[56], &lengthBitHigh, 4); + memcpy(&buffer[60], &lengthBitLow, 4); + computeBlock(&h0,&h1,&h2,&h3,&h4, buffer); + + digest2[0] = __rev(h0); + digest2[1] = __rev(h1); + digest2[2] = __rev(h2); + digest2[3] = __rev(h3); + digest2[4] = __rev(h4); // reset state h0 = H0; @@ -147,27 +126,39 @@ void SHA1::computeBlock(uint32_t *h02, uint32_t *h12, uint32_t *h22, uint32_t *h32, uint32_t *h42, uint8_t *buffer) { + uint32_t *buffer2 = (uint32_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]; + for(int t = 0; t < 16; ++t) + w[t] = __rev(buffer2[t]); 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); - } + + R0(a,b,c,d,e, 0) R0(e,a,b,c,d, 1) R0(d,e,a,b,c, 2) R0(c,d,e,a,b, 3) + R0(b,c,d,e,a, 4) R0(a,b,c,d,e, 5) R0(e,a,b,c,d, 6) R0(d,e,a,b,c, 7) + R0(c,d,e,a,b, 8) R0(b,c,d,e,a, 9) R0(a,b,c,d,e,10) R0(e,a,b,c,d,11) + R0(d,e,a,b,c,12) R0(c,d,e,a,b,13) R0(b,c,d,e,a,14) R0(a,b,c,d,e,15) + R1(e,a,b,c,d,16) R1(d,e,a,b,c,17) R1(c,d,e,a,b,18) R1(b,c,d,e,a,19) + + + R2(a,b,c,d,e,20) R2(e,a,b,c,d,21) R2(d,e,a,b,c,22) R2(c,d,e,a,b,23) + R2(b,c,d,e,a,24) R2(a,b,c,d,e,25) R2(e,a,b,c,d,26) R2(d,e,a,b,c,27) + R2(c,d,e,a,b,28) R2(b,c,d,e,a,29) R2(a,b,c,d,e,30) R2(e,a,b,c,d,31) + R2(d,e,a,b,c,32) R2(c,d,e,a,b,33) R2(b,c,d,e,a,34) R2(a,b,c,d,e,35) + R2(e,a,b,c,d,36) R2(d,e,a,b,c,37) R2(c,d,e,a,b,38) R2(b,c,d,e,a,39) + + R3(a,b,c,d,e,40) R3(e,a,b,c,d,41) R3(d,e,a,b,c,42) R3(c,d,e,a,b,43) + R3(b,c,d,e,a,44) R3(a,b,c,d,e,45) R3(e,a,b,c,d,46) R3(d,e,a,b,c,47) + R3(c,d,e,a,b,48) R3(b,c,d,e,a,49) R3(a,b,c,d,e,50) R3(e,a,b,c,d,51) + R3(d,e,a,b,c,52) R3(c,d,e,a,b,53) R3(b,c,d,e,a,54) R3(a,b,c,d,e,55) + R3(e,a,b,c,d,56) R3(d,e,a,b,c,57) R3(c,d,e,a,b,58) R3(b,c,d,e,a,59) + + + R4(a,b,c,d,e,60) R4(e,a,b,c,d,61) R4(d,e,a,b,c,62) R4(c,d,e,a,b,63) + R4(b,c,d,e,a,64) R4(a,b,c,d,e,65) R4(e,a,b,c,d,66) R4(d,e,a,b,c,67) + R4(c,d,e,a,b,68) R4(b,c,d,e,a,69) R4(a,b,c,d,e,70) R4(e,a,b,c,d,71) + R4(d,e,a,b,c,72) R4(c,d,e,a,b,73) R4(b,c,d,e,a,74) R4(a,b,c,d,e,75) + R4(e,a,b,c,d,76) R4(d,e,a,b,c,77) R4(c,d,e,a,b,78) R4(b,c,d,e,a,79) - 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; @@ -177,39 +168,37 @@ -/* method 2 */ +/* method 1 */ void SHA1::computeDigest(uint8_t *digest, uint8_t *in, uint32_t length) { - uint16_t padding; + uint64_t lengthBit = length << 3; + uint32_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) + while(length >= 64) { - computeBlock(&h0,&h1,&h2,&h3,&h4, &in[offset]); - offset += 64; + computeBlock(&h0,&h1,&h2,&h3,&h4, in); + length -= 64; + in += 64; + } + + uint8_t buffer[64]; + memcpy(buffer, in, length); + buffer[length++] = 0x80; + padding--; + if(padding+length+8 == 64) + memset(&buffer[length], 0, padding); + else + { + memset(&buffer[length], 0, 64-length); + computeBlock(&h0,&h1,&h2,&h3,&h4, buffer); + memset(buffer, 0, length); } - uint8_t bufferLength = length - offset; - uint8_t buffer[64]; - memcpy(buffer, &in[offset], bufferLength); - buffer[bufferLength++] = 0x80; - padding--; - if(padding+bufferLength+8 == 64) - memset(&buffer[bufferLength], 0, padding); - else - { - memset(&buffer[bufferLength], 0, 64-bufferLength); - padding -= 64-bufferLength; - computeBlock(&h0,&h1,&h2,&h3,&h4, buffer); - memset(buffer, 0, 48); - } - - uint64_t lengthBit = length * 8; uint32_t lengthBitLow = lengthBit; uint32_t lengthBitHigh = lengthBit >> 32; lengthBitLow = __rev(lengthBitLow);