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