This library implements some hash and cryptographic algorithms.
Dependents: ES_CW2_Starter_JIN EMBEDDED_CW2 EMBEDDED_CW2_Final Spinnybois ... more
Fork of Crypto by
SHA1.cpp@4:0da19393bd57, 2013-09-12 (annotated)
- Committer:
- feb11
- Date:
- Thu Sep 12 10:18:57 2013 +0000
- Revision:
- 4:0da19393bd57
- Parent:
- 3:85c6ee25cf3e
- Child:
- 5:06cd9c8afa0b
improved performance of SHA-2 (32 & 64bits)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
feb11 | 4:0da19393bd57 | 1 | /** |
feb11 | 4:0da19393bd57 | 2 | Implementation of SHA-1 as described here: |
feb11 | 4:0da19393bd57 | 3 | http://tools.ietf.org/html/rfc1319 |
feb11 | 4:0da19393bd57 | 4 | */ |
feb11 | 4:0da19393bd57 | 5 | |
feb11 | 0:7a1237bd2d13 | 6 | #include "SHA1.h" |
feb11 | 0:7a1237bd2d13 | 7 | #include <string.h> |
feb11 | 3:85c6ee25cf3e | 8 | #include <stdio.h> |
feb11 | 3:85c6ee25cf3e | 9 | #include <stdlib.h> |
feb11 | 0:7a1237bd2d13 | 10 | |
feb11 | 3:85c6ee25cf3e | 11 | #define F0(B,C,D) ((B & C) | ((~B) & D)) |
feb11 | 3:85c6ee25cf3e | 12 | #define F1(B,C,D) (B ^ C ^ D) |
feb11 | 3:85c6ee25cf3e | 13 | #define F2(B,C,D) ((B & C) | (B & D) | (C & D)) |
feb11 | 3:85c6ee25cf3e | 14 | #define ROTL(W,N) (((W) << N) | ((W) >> (32-N))) |
feb11 | 3:85c6ee25cf3e | 15 | |
feb11 | 3:85c6ee25cf3e | 16 | static const uint32_t K0 = 0x5A827999; |
feb11 | 3:85c6ee25cf3e | 17 | static const uint32_t K1 = 0x6ED9EBA1; |
feb11 | 3:85c6ee25cf3e | 18 | static const uint32_t K2 = 0x8F1BBCDC; |
feb11 | 3:85c6ee25cf3e | 19 | static const uint32_t K3 = 0xCA62C1D6; |
feb11 | 0:7a1237bd2d13 | 20 | |
feb11 | 0:7a1237bd2d13 | 21 | |
feb11 | 0:7a1237bd2d13 | 22 | static const uint32_t H0 = 0x67452301; |
feb11 | 0:7a1237bd2d13 | 23 | static const uint32_t H1 = 0xEFCDAB89; |
feb11 | 0:7a1237bd2d13 | 24 | static const uint32_t H2 = 0x98BADCFE; |
feb11 | 0:7a1237bd2d13 | 25 | static const uint32_t H3 = 0x10325476; |
feb11 | 0:7a1237bd2d13 | 26 | static const uint32_t H4 = 0xC3D2E1F0; |
feb11 | 3:85c6ee25cf3e | 27 | |
feb11 | 3:85c6ee25cf3e | 28 | static const uint32_t MASK = 0xF; |
feb11 | 3:85c6ee25cf3e | 29 | |
feb11 | 3:85c6ee25cf3e | 30 | #define W(s) ( w[s] = ROTL(w[((s) + 13) & MASK] ^ w[((s) + 8) & MASK] ^ w[((s) + 2) & MASK] ^ w[s],1)) |
feb11 | 0:7a1237bd2d13 | 31 | |
feb11 | 3:85c6ee25cf3e | 32 | #define R0(A,B,C,D,E,T) E += ROTL(A, 5) + F0(B, C, D) + w[T] + K0; \ |
feb11 | 3:85c6ee25cf3e | 33 | B = ROTL(B,30); |
feb11 | 3:85c6ee25cf3e | 34 | #define R1(A,B,C,D,E,T) E += ROTL(A, 5) + F0(B, C, D) + W(T & MASK) + K0; \ |
feb11 | 3:85c6ee25cf3e | 35 | B = ROTL(B,30); |
feb11 | 3:85c6ee25cf3e | 36 | #define R2(A,B,C,D,E,T) E += ROTL(A, 5) + F1(B, C, D) + W(T & MASK) + K1; \ |
feb11 | 3:85c6ee25cf3e | 37 | B = ROTL(B,30); |
feb11 | 3:85c6ee25cf3e | 38 | #define R3(A,B,C,D,E,T) E += ROTL(A, 5) + F2(B, C, D) + W(T & MASK) + K2; \ |
feb11 | 3:85c6ee25cf3e | 39 | B = ROTL(B,30); |
feb11 | 3:85c6ee25cf3e | 40 | #define R4(A,B,C,D,E,T) E += ROTL(A, 5) + F1(B, C, D) + W(T & MASK) + K3; \ |
feb11 | 3:85c6ee25cf3e | 41 | B = ROTL(B,30); |
feb11 | 0:7a1237bd2d13 | 42 | |
feb11 | 3:85c6ee25cf3e | 43 | |
feb11 | 0:7a1237bd2d13 | 44 | SHA1::SHA1(): |
feb11 | 0:7a1237bd2d13 | 45 | HashAlgorithm(), |
feb11 | 0:7a1237bd2d13 | 46 | h0(H0), |
feb11 | 0:7a1237bd2d13 | 47 | h1(H1), |
feb11 | 0:7a1237bd2d13 | 48 | h2(H2), |
feb11 | 0:7a1237bd2d13 | 49 | h3(H3), |
feb11 | 0:7a1237bd2d13 | 50 | h4(H4), |
feb11 | 0:7a1237bd2d13 | 51 | totalBufferLength(0), |
feb11 | 0:7a1237bd2d13 | 52 | buffer(), |
feb11 | 0:7a1237bd2d13 | 53 | bufferLength(0) |
feb11 | 0:7a1237bd2d13 | 54 | { |
feb11 | 0:7a1237bd2d13 | 55 | } |
feb11 | 0:7a1237bd2d13 | 56 | |
feb11 | 0:7a1237bd2d13 | 57 | uint8_t SHA1::outputSize() const |
feb11 | 0:7a1237bd2d13 | 58 | { |
feb11 | 0:7a1237bd2d13 | 59 | return 20; |
feb11 | 0:7a1237bd2d13 | 60 | } |
feb11 | 0:7a1237bd2d13 | 61 | |
feb11 | 0:7a1237bd2d13 | 62 | void SHA1::add(uint8_t *in, uint32_t length) |
feb11 | 0:7a1237bd2d13 | 63 | { |
feb11 | 0:7a1237bd2d13 | 64 | if(length < 64-bufferLength) |
feb11 | 0:7a1237bd2d13 | 65 | { |
feb11 | 0:7a1237bd2d13 | 66 | memcpy(&buffer[bufferLength], in, length); |
feb11 | 0:7a1237bd2d13 | 67 | bufferLength += length; |
feb11 | 0:7a1237bd2d13 | 68 | totalBufferLength += length; |
feb11 | 0:7a1237bd2d13 | 69 | return; |
feb11 | 0:7a1237bd2d13 | 70 | } |
feb11 | 0:7a1237bd2d13 | 71 | int offset = 64-bufferLength; |
feb11 | 0:7a1237bd2d13 | 72 | memcpy(&buffer[bufferLength], in, offset); |
feb11 | 0:7a1237bd2d13 | 73 | computeBlock(&h0,&h1,&h2,&h3,&h4, buffer); |
feb11 | 0:7a1237bd2d13 | 74 | while(length-offset > 64) |
feb11 | 0:7a1237bd2d13 | 75 | { |
feb11 | 0:7a1237bd2d13 | 76 | memcpy(buffer, &in[offset], 64); |
feb11 | 0:7a1237bd2d13 | 77 | computeBlock(&h0,&h1,&h2,&h3,&h4, buffer); |
feb11 | 0:7a1237bd2d13 | 78 | offset += 64; |
feb11 | 0:7a1237bd2d13 | 79 | } |
feb11 | 0:7a1237bd2d13 | 80 | if(offset > length) |
feb11 | 0:7a1237bd2d13 | 81 | offset -= 64; |
feb11 | 0:7a1237bd2d13 | 82 | bufferLength = length - offset; |
feb11 | 0:7a1237bd2d13 | 83 | memcpy(buffer, &in[offset], bufferLength); |
feb11 | 0:7a1237bd2d13 | 84 | totalBufferLength += length; |
feb11 | 0:7a1237bd2d13 | 85 | } |
feb11 | 0:7a1237bd2d13 | 86 | |
feb11 | 0:7a1237bd2d13 | 87 | void SHA1::computeDigest(uint8_t *digest) |
feb11 | 0:7a1237bd2d13 | 88 | { |
feb11 | 3:85c6ee25cf3e | 89 | uint32_t *digest2 = (uint32_t*)digest; |
feb11 | 0:7a1237bd2d13 | 90 | uint16_t padding; |
feb11 | 0:7a1237bd2d13 | 91 | if(totalBufferLength % 64 < 56) |
feb11 | 0:7a1237bd2d13 | 92 | padding = 56 - (totalBufferLength % 64); |
feb11 | 0:7a1237bd2d13 | 93 | else |
feb11 | 0:7a1237bd2d13 | 94 | padding = 56 + (64 - (totalBufferLength % 64)); |
feb11 | 3:85c6ee25cf3e | 95 | |
feb11 | 3:85c6ee25cf3e | 96 | buffer[bufferLength++] = 0x80; |
feb11 | 3:85c6ee25cf3e | 97 | padding--; |
feb11 | 3:85c6ee25cf3e | 98 | if(padding+bufferLength == 56) |
feb11 | 3:85c6ee25cf3e | 99 | memset(&buffer[bufferLength], 0, padding); |
feb11 | 3:85c6ee25cf3e | 100 | else |
feb11 | 3:85c6ee25cf3e | 101 | { |
feb11 | 3:85c6ee25cf3e | 102 | memset(&buffer[bufferLength], 0, 64-bufferLength); |
feb11 | 3:85c6ee25cf3e | 103 | computeBlock(&h0,&h1,&h2,&h3,&h4, buffer); |
feb11 | 3:85c6ee25cf3e | 104 | memset(buffer, 0, 48); |
feb11 | 3:85c6ee25cf3e | 105 | } |
feb11 | 3:85c6ee25cf3e | 106 | |
feb11 | 3:85c6ee25cf3e | 107 | uint64_t lengthBit = totalBufferLength << 3; |
feb11 | 0:7a1237bd2d13 | 108 | uint32_t lengthBitLow = lengthBit; |
feb11 | 0:7a1237bd2d13 | 109 | uint32_t lengthBitHigh = lengthBit >> 32; |
feb11 | 3:85c6ee25cf3e | 110 | lengthBitLow = __rev(lengthBitLow); |
feb11 | 3:85c6ee25cf3e | 111 | lengthBitHigh = __rev(lengthBitHigh); |
feb11 | 3:85c6ee25cf3e | 112 | memcpy(&buffer[56], &lengthBitHigh, 4); |
feb11 | 3:85c6ee25cf3e | 113 | memcpy(&buffer[60], &lengthBitLow, 4); |
feb11 | 3:85c6ee25cf3e | 114 | computeBlock(&h0,&h1,&h2,&h3,&h4, buffer); |
feb11 | 3:85c6ee25cf3e | 115 | |
feb11 | 3:85c6ee25cf3e | 116 | digest2[0] = __rev(h0); |
feb11 | 3:85c6ee25cf3e | 117 | digest2[1] = __rev(h1); |
feb11 | 3:85c6ee25cf3e | 118 | digest2[2] = __rev(h2); |
feb11 | 3:85c6ee25cf3e | 119 | digest2[3] = __rev(h3); |
feb11 | 3:85c6ee25cf3e | 120 | digest2[4] = __rev(h4); |
feb11 | 0:7a1237bd2d13 | 121 | |
feb11 | 0:7a1237bd2d13 | 122 | // reset state |
feb11 | 0:7a1237bd2d13 | 123 | h0 = H0; |
feb11 | 0:7a1237bd2d13 | 124 | h1 = H1; |
feb11 | 0:7a1237bd2d13 | 125 | h2 = H2; |
feb11 | 0:7a1237bd2d13 | 126 | h3 = H3; |
feb11 | 0:7a1237bd2d13 | 127 | h4 = H4; |
feb11 | 0:7a1237bd2d13 | 128 | totalBufferLength = 0; |
feb11 | 0:7a1237bd2d13 | 129 | bufferLength = 0; |
feb11 | 0:7a1237bd2d13 | 130 | } |
feb11 | 0:7a1237bd2d13 | 131 | |
feb11 | 0:7a1237bd2d13 | 132 | void SHA1::computeBlock(uint32_t *h02, uint32_t *h12, uint32_t *h22, uint32_t *h32, uint32_t *h42, uint8_t *buffer) |
feb11 | 0:7a1237bd2d13 | 133 | { |
feb11 | 3:85c6ee25cf3e | 134 | uint32_t *buffer2 = (uint32_t*)buffer; |
feb11 | 0:7a1237bd2d13 | 135 | uint32_t w[16]; |
feb11 | 3:85c6ee25cf3e | 136 | for(int t = 0; t < 16; ++t) |
feb11 | 3:85c6ee25cf3e | 137 | w[t] = __rev(buffer2[t]); |
feb11 | 0:7a1237bd2d13 | 138 | |
feb11 | 0:7a1237bd2d13 | 139 | uint32_t a = *h02, b = *h12, c = *h22, d = *h32, e = *h42; |
feb11 | 3:85c6ee25cf3e | 140 | |
feb11 | 3:85c6ee25cf3e | 141 | 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) |
feb11 | 3:85c6ee25cf3e | 142 | 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) |
feb11 | 3:85c6ee25cf3e | 143 | 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) |
feb11 | 3:85c6ee25cf3e | 144 | 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) |
feb11 | 3:85c6ee25cf3e | 145 | 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) |
feb11 | 3:85c6ee25cf3e | 146 | |
feb11 | 3:85c6ee25cf3e | 147 | |
feb11 | 3:85c6ee25cf3e | 148 | 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) |
feb11 | 3:85c6ee25cf3e | 149 | 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) |
feb11 | 3:85c6ee25cf3e | 150 | 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) |
feb11 | 3:85c6ee25cf3e | 151 | 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) |
feb11 | 3:85c6ee25cf3e | 152 | 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) |
feb11 | 3:85c6ee25cf3e | 153 | |
feb11 | 3:85c6ee25cf3e | 154 | 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) |
feb11 | 3:85c6ee25cf3e | 155 | 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) |
feb11 | 3:85c6ee25cf3e | 156 | 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) |
feb11 | 3:85c6ee25cf3e | 157 | 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) |
feb11 | 3:85c6ee25cf3e | 158 | 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) |
feb11 | 3:85c6ee25cf3e | 159 | |
feb11 | 3:85c6ee25cf3e | 160 | |
feb11 | 3:85c6ee25cf3e | 161 | 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) |
feb11 | 3:85c6ee25cf3e | 162 | 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) |
feb11 | 3:85c6ee25cf3e | 163 | 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) |
feb11 | 3:85c6ee25cf3e | 164 | 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) |
feb11 | 3:85c6ee25cf3e | 165 | 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) |
feb11 | 0:7a1237bd2d13 | 166 | |
feb11 | 0:7a1237bd2d13 | 167 | *h02 += a; |
feb11 | 0:7a1237bd2d13 | 168 | *h12 += b; |
feb11 | 0:7a1237bd2d13 | 169 | *h22 += c; |
feb11 | 0:7a1237bd2d13 | 170 | *h32 += d; |
feb11 | 0:7a1237bd2d13 | 171 | *h42 += e; |
feb11 | 0:7a1237bd2d13 | 172 | } |
feb11 | 0:7a1237bd2d13 | 173 | |
feb11 | 0:7a1237bd2d13 | 174 | |
feb11 | 0:7a1237bd2d13 | 175 | |
feb11 | 3:85c6ee25cf3e | 176 | /* method 1 */ |
feb11 | 0:7a1237bd2d13 | 177 | void SHA1::computeDigest(uint8_t *digest, uint8_t *in, uint32_t length) |
feb11 | 0:7a1237bd2d13 | 178 | { |
feb11 | 3:85c6ee25cf3e | 179 | uint64_t lengthBit = length << 3; |
feb11 | 3:85c6ee25cf3e | 180 | uint32_t padding; |
feb11 | 0:7a1237bd2d13 | 181 | if(length % 64 < 56) |
feb11 | 0:7a1237bd2d13 | 182 | padding = 56 - (length % 64); |
feb11 | 0:7a1237bd2d13 | 183 | else |
feb11 | 0:7a1237bd2d13 | 184 | padding = 56 + (64 - (length % 64)); |
feb11 | 1:14a7cea431aa | 185 | |
feb11 | 1:14a7cea431aa | 186 | uint32_t h0 = H0, h1 = H1, h2 = H2, h3 = H3, h4 = H4; |
feb11 | 3:85c6ee25cf3e | 187 | while(length >= 64) |
feb11 | 1:14a7cea431aa | 188 | { |
feb11 | 3:85c6ee25cf3e | 189 | computeBlock(&h0,&h1,&h2,&h3,&h4, in); |
feb11 | 3:85c6ee25cf3e | 190 | length -= 64; |
feb11 | 3:85c6ee25cf3e | 191 | in += 64; |
feb11 | 3:85c6ee25cf3e | 192 | } |
feb11 | 3:85c6ee25cf3e | 193 | |
feb11 | 3:85c6ee25cf3e | 194 | uint8_t buffer[64]; |
feb11 | 3:85c6ee25cf3e | 195 | memcpy(buffer, in, length); |
feb11 | 3:85c6ee25cf3e | 196 | buffer[length++] = 0x80; |
feb11 | 3:85c6ee25cf3e | 197 | padding--; |
feb11 | 3:85c6ee25cf3e | 198 | if(padding+length+8 == 64) |
feb11 | 3:85c6ee25cf3e | 199 | memset(&buffer[length], 0, padding); |
feb11 | 3:85c6ee25cf3e | 200 | else |
feb11 | 3:85c6ee25cf3e | 201 | { |
feb11 | 3:85c6ee25cf3e | 202 | memset(&buffer[length], 0, 64-length); |
feb11 | 3:85c6ee25cf3e | 203 | computeBlock(&h0,&h1,&h2,&h3,&h4, buffer); |
feb11 | 3:85c6ee25cf3e | 204 | memset(buffer, 0, length); |
feb11 | 1:14a7cea431aa | 205 | } |
feb11 | 1:14a7cea431aa | 206 | |
feb11 | 0:7a1237bd2d13 | 207 | uint32_t lengthBitLow = lengthBit; |
feb11 | 0:7a1237bd2d13 | 208 | uint32_t lengthBitHigh = lengthBit >> 32; |
feb11 | 2:473bac39ae7c | 209 | lengthBitLow = __rev(lengthBitLow); |
feb11 | 2:473bac39ae7c | 210 | lengthBitHigh = __rev(lengthBitHigh); |
feb11 | 2:473bac39ae7c | 211 | memcpy(&buffer[60], &lengthBitLow, 4); |
feb11 | 2:473bac39ae7c | 212 | memcpy(&buffer[56], &lengthBitHigh, 4); |
feb11 | 0:7a1237bd2d13 | 213 | |
feb11 | 1:14a7cea431aa | 214 | computeBlock(&h0,&h1,&h2,&h3,&h4, buffer); |
feb11 | 0:7a1237bd2d13 | 215 | |
feb11 | 2:473bac39ae7c | 216 | h0 = __rev(h0); |
feb11 | 2:473bac39ae7c | 217 | h1 = __rev(h1); |
feb11 | 2:473bac39ae7c | 218 | h2 = __rev(h2); |
feb11 | 2:473bac39ae7c | 219 | h3 = __rev(h3); |
feb11 | 2:473bac39ae7c | 220 | h4 = __rev(h4); |
feb11 | 2:473bac39ae7c | 221 | |
feb11 | 2:473bac39ae7c | 222 | memcpy(digest, &h0, 4); |
feb11 | 2:473bac39ae7c | 223 | memcpy(&digest[4], &h1, 4); |
feb11 | 2:473bac39ae7c | 224 | memcpy(&digest[8], &h2, 4); |
feb11 | 2:473bac39ae7c | 225 | memcpy(&digest[12], &h3, 4); |
feb11 | 2:473bac39ae7c | 226 | memcpy(&digest[16], &h4, 4); |
feb11 | 0:7a1237bd2d13 | 227 | } |
feb11 | 0:7a1237bd2d13 | 228 |