This library implements some hash and cryptographic algorithms.

Dependents:   mBuinoBlinky PB_Emma_Ethernet SLOTrashHTTP Garagem ... more

This library implements the following algorithms :

  • RC4
  • AES (AES-128, AES-192, AES-256)
  • DES
  • Triple DES (EDE)
  • MD2
  • MD4
  • MD5
  • SHA-1
  • SHA-2 (SHA-224, SHA-256, SHA-384, SHA-512)

The hash algorithms have been optimized for the mbed and you should get decent performance. However, I did not optimize the ciphers. Also, I did not test extensively these algorithms : it should work but you may find some bugs. Block ciphers support two modes : ECB and CBC.

Warning

If you are using SHA-384 or SHA-512, be aware that it produces large binary files and the compilation (using the online compiler) takes much longer to execute. It may happen that the compiler stops because it timed-out. In this case, just compile again and it should work.

Computing hash

You can compute the hash of some data in two different ways. The first one is the easiest, each hash algorithm has a static method that takes some data and compute the hash from it.

Computing hash using method 1

#include "Crypto.h"
#include "mbed.h"

static const char msg[] = "mbed is great !";

int main()
{
    uint8_t hash[16];
    MD2::computeHash(hash, (uint8_t*)msg, strlen(msg));
    printf("hash: ");
    for(int i = 0; i < 16; ++i)
        printf("%02x", hash[i]);
    printf("\n");
    
    return 0;
}

The second one is slightly slower (around 2-3% slower) but it allows you to compute the hash of some data in several steps (by calling update method). This is the method you should use if you need to compute the hash from a large source and you don't have enough memory to store it in a single buffer.

Computing hash using method 2

#include "Crypto.h"
#include "mbed.h"

static const char msg[] = "mbed is great !";

int main()
{
    uint8_t hash[16];
    MD2 h;
    h.update((uint8_t*)msg, strlen(msg));
    h.finalize(hash);
    printf("hash: ");
    for(int i = 0; i < 16; ++i)
        printf("%02x", hash[i]);
    printf("\n");
    
    return 0;
}

TODO

  • optimize ciphers
  • add doc
Committer:
feb11
Date:
Sun May 11 13:36:45 2014 +0000
Revision:
14:f04410cef037
Parent:
13:ac8e23b98dae
CBC mode completed

Who changed what in which revision?

UserRevisionLine numberNew contents of line
feb11 0:7a1237bd2d13 1 #include "SHA2_32.h"
feb11 0:7a1237bd2d13 2 #include <string.h>
feb11 10:bc9c23aa3870 3
feb11 0:7a1237bd2d13 4
feb11 4:0da19393bd57 5
feb11 4:0da19393bd57 6 static const uint8_t MASK = 0x0F;
feb11 13:ac8e23b98dae 7
feb11 4:0da19393bd57 8 #define W(t) (w[(t)] = SSIG1(w[((t)+14)&MASK]) + w[((t)+9)&MASK] + SSIG0(w[((t)+1)&MASK]) + w[t])
feb11 0:7a1237bd2d13 9
feb11 3:85c6ee25cf3e 10 #define ROTL(W,N) (((W) << (N)) | ((W) >> (32-(N))))
feb11 13:ac8e23b98dae 11 #define ROTR(W,N) (rotRWord(W,N))
feb11 3:85c6ee25cf3e 12 #define CH(X,Y,Z) (((X) & (Y)) ^ ((~(X)) & (Z)))
feb11 3:85c6ee25cf3e 13 #define MAJ(X,Y,Z) (((X) & (Y)) ^ ((X) & (Z)) ^ ((Y) & (Z)))
feb11 3:85c6ee25cf3e 14 #define BSIG0(X) (ROTR(X,2) ^ ROTR(X,13) ^ ROTR(X,22))
feb11 3:85c6ee25cf3e 15 #define BSIG1(X) (ROTR(X,6) ^ ROTR(X,11) ^ ROTR(X,25))
feb11 3:85c6ee25cf3e 16 #define SSIG0(X) (ROTR((X),7) ^ ROTR((X),18) ^ ((X) >> 3))
feb11 3:85c6ee25cf3e 17 #define SSIG1(X) (ROTR((X),17) ^ ROTR((X),19) ^ ((X) >> 10))
feb11 13:ac8e23b98dae 18 #define R(A,B,C,D,E,F,G,H,T,K) T1 = H + BSIG1(E) + CH(E,F,G) + K + (w[T] = revWord(buffer2[T])); \
feb11 4:0da19393bd57 19 T2 = BSIG0(A) + MAJ(A,B,C); \
feb11 4:0da19393bd57 20 D += T1; \
feb11 4:0da19393bd57 21 H = T1 + T2;
feb11 4:0da19393bd57 22 #define R2(A,B,C,D,E,F,G,H,T,K) T1 = H + BSIG1(E) + CH(E,F,G) + K + W(T&MASK); \
feb11 3:85c6ee25cf3e 23 T2 = BSIG0(A) + MAJ(A,B,C); \
feb11 3:85c6ee25cf3e 24 D += T1; \
feb11 3:85c6ee25cf3e 25 H = T1 + T2;
feb11 3:85c6ee25cf3e 26
feb11 0:7a1237bd2d13 27 static const uint32_t H[] =
feb11 0:7a1237bd2d13 28 {
feb11 0:7a1237bd2d13 29 // SHA-224
feb11 0:7a1237bd2d13 30 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
feb11 0:7a1237bd2d13 31 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4,
feb11 0:7a1237bd2d13 32
feb11 0:7a1237bd2d13 33 // SHA-256
feb11 0:7a1237bd2d13 34 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
feb11 0:7a1237bd2d13 35 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
feb11 0:7a1237bd2d13 36 };
feb11 0:7a1237bd2d13 37
feb11 13:ac8e23b98dae 38 static uint32_t revWord(const uint32_t w)
feb11 13:ac8e23b98dae 39 {
feb11 13:ac8e23b98dae 40 #ifdef __CC_ARM
feb11 13:ac8e23b98dae 41 return __rev(w);
feb11 13:ac8e23b98dae 42 #else
feb11 13:ac8e23b98dae 43 return (w >> 24)
feb11 13:ac8e23b98dae 44 | ((w & 0x00FF0000) >> 8)
feb11 13:ac8e23b98dae 45 | ((w & 0x0000FF00) << 8)
feb11 13:ac8e23b98dae 46 | ((w & 0x000000FF) << 24);
feb11 13:ac8e23b98dae 47 #endif
feb11 13:ac8e23b98dae 48 }
feb11 13:ac8e23b98dae 49
feb11 13:ac8e23b98dae 50 static uint32_t rotRWord(const uint32_t w, const uint32_t n)
feb11 13:ac8e23b98dae 51 {
feb11 13:ac8e23b98dae 52 #ifdef __CC_ARM
feb11 13:ac8e23b98dae 53 return __ror(w, n);
feb11 13:ac8e23b98dae 54 #else
feb11 13:ac8e23b98dae 55 return (w >> n) | (w << (32-n));
feb11 13:ac8e23b98dae 56 #endif
feb11 13:ac8e23b98dae 57 }
feb11 13:ac8e23b98dae 58
feb11 0:7a1237bd2d13 59 SHA2_32::SHA2_32(SHA_32_TYPE t):
feb11 0:7a1237bd2d13 60 type(t),
feb11 0:7a1237bd2d13 61 totalBufferLength(0),
feb11 0:7a1237bd2d13 62 bufferLength(0)
feb11 0:7a1237bd2d13 63 {
feb11 0:7a1237bd2d13 64 switch(type)
feb11 0:7a1237bd2d13 65 {
feb11 0:7a1237bd2d13 66 case SHA_224:
feb11 0:7a1237bd2d13 67 h0 = H[0];
feb11 0:7a1237bd2d13 68 h1 = H[1];
feb11 0:7a1237bd2d13 69 h2 = H[2];
feb11 0:7a1237bd2d13 70 h3 = H[3];
feb11 0:7a1237bd2d13 71 h4 = H[4];
feb11 0:7a1237bd2d13 72 h5 = H[5];
feb11 0:7a1237bd2d13 73 h6 = H[6];
feb11 0:7a1237bd2d13 74 h7 = H[7];
feb11 0:7a1237bd2d13 75 break;
feb11 0:7a1237bd2d13 76
feb11 0:7a1237bd2d13 77 case SHA_256:
feb11 0:7a1237bd2d13 78 h0 = H[8];
feb11 0:7a1237bd2d13 79 h1 = H[9];
feb11 0:7a1237bd2d13 80 h2 = H[10];
feb11 0:7a1237bd2d13 81 h3 = H[11];
feb11 0:7a1237bd2d13 82 h4 = H[12];
feb11 0:7a1237bd2d13 83 h5 = H[13];
feb11 0:7a1237bd2d13 84 h6 = H[14];
feb11 0:7a1237bd2d13 85 h7 = H[15];
feb11 0:7a1237bd2d13 86 break;
feb11 0:7a1237bd2d13 87 }
feb11 0:7a1237bd2d13 88 }
feb11 0:7a1237bd2d13 89
feb11 6:19aa835f2bbb 90 void SHA2_32::update(uint8_t *data, uint32_t length)
feb11 0:7a1237bd2d13 91 {
feb11 13:ac8e23b98dae 92 if((int)length < 64-bufferLength)
feb11 0:7a1237bd2d13 93 {
feb11 6:19aa835f2bbb 94 memcpy(&buffer[bufferLength], data, length);
feb11 0:7a1237bd2d13 95 bufferLength += length;
feb11 0:7a1237bd2d13 96 totalBufferLength += length;
feb11 0:7a1237bd2d13 97 return;
feb11 0:7a1237bd2d13 98 }
feb11 0:7a1237bd2d13 99 int offset = 64-bufferLength;
feb11 6:19aa835f2bbb 100 memcpy(&buffer[bufferLength], data, offset);
feb11 0:7a1237bd2d13 101 computeBlock(&h0,&h1,&h2,&h3,&h4,&h5,&h6,&h7,buffer);
feb11 0:7a1237bd2d13 102 while(length-offset > 64)
feb11 0:7a1237bd2d13 103 {
feb11 6:19aa835f2bbb 104 memcpy(buffer, &data[offset], 64);
feb11 0:7a1237bd2d13 105 computeBlock(&h0,&h1,&h2,&h3,&h4,&h5,&h6,&h7,buffer);
feb11 0:7a1237bd2d13 106 offset += 64;
feb11 0:7a1237bd2d13 107 }
feb11 13:ac8e23b98dae 108 if(offset > (int)length)
feb11 0:7a1237bd2d13 109 offset -= 64;
feb11 0:7a1237bd2d13 110 bufferLength = length - offset;
feb11 6:19aa835f2bbb 111 memcpy(buffer, &data[offset], bufferLength);
feb11 0:7a1237bd2d13 112 totalBufferLength += length;
feb11 0:7a1237bd2d13 113 }
feb11 0:7a1237bd2d13 114
feb11 6:19aa835f2bbb 115 void SHA2_32::finalize(uint8_t *hash)
feb11 0:7a1237bd2d13 116 {
feb11 6:19aa835f2bbb 117 uint32_t *hash2 = (uint32_t*)hash;
feb11 0:7a1237bd2d13 118 uint16_t padding;
feb11 0:7a1237bd2d13 119 if(totalBufferLength % 64 < 56)
feb11 0:7a1237bd2d13 120 padding = 56 - (totalBufferLength % 64);
feb11 0:7a1237bd2d13 121 else
feb11 0:7a1237bd2d13 122 padding = 56 + (64 - (totalBufferLength % 64));
feb11 3:85c6ee25cf3e 123
feb11 3:85c6ee25cf3e 124 buffer[bufferLength++] = 0x80;
feb11 3:85c6ee25cf3e 125 padding--;
feb11 3:85c6ee25cf3e 126 if(padding+bufferLength == 56)
feb11 3:85c6ee25cf3e 127 memset(&buffer[bufferLength], 0, padding);
feb11 3:85c6ee25cf3e 128 else
feb11 3:85c6ee25cf3e 129 {
feb11 3:85c6ee25cf3e 130 memset(&buffer[bufferLength], 0, 64-bufferLength);
feb11 3:85c6ee25cf3e 131 computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, buffer);
feb11 5:06cd9c8afa0b 132 memset(buffer, 0, 56);
feb11 3:85c6ee25cf3e 133 }
feb11 3:85c6ee25cf3e 134
feb11 3:85c6ee25cf3e 135 uint64_t lengthBit = totalBufferLength << 3;
feb11 0:7a1237bd2d13 136 uint32_t lengthBitLow = lengthBit;
feb11 0:7a1237bd2d13 137 uint32_t lengthBitHigh = lengthBit >> 32;
feb11 13:ac8e23b98dae 138 lengthBitLow = revWord(lengthBitLow);
feb11 13:ac8e23b98dae 139 lengthBitHigh = revWord(lengthBitHigh);
feb11 3:85c6ee25cf3e 140 memcpy(&buffer[60], &lengthBitLow, 4);
feb11 3:85c6ee25cf3e 141 memcpy(&buffer[56], &lengthBitHigh, 4);
feb11 3:85c6ee25cf3e 142 computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, buffer);
feb11 0:7a1237bd2d13 143
feb11 13:ac8e23b98dae 144 hash2[0] = revWord(h0);
feb11 13:ac8e23b98dae 145 hash2[1] = revWord(h1);
feb11 13:ac8e23b98dae 146 hash2[2] = revWord(h2);
feb11 13:ac8e23b98dae 147 hash2[3] = revWord(h3);
feb11 13:ac8e23b98dae 148 hash2[4] = revWord(h4);
feb11 13:ac8e23b98dae 149 hash2[5] = revWord(h5);
feb11 13:ac8e23b98dae 150 hash2[6] = revWord(h6);
feb11 6:19aa835f2bbb 151
feb11 3:85c6ee25cf3e 152
feb11 0:7a1237bd2d13 153 if(type == SHA_256)
feb11 13:ac8e23b98dae 154 hash2[7] = revWord(h7);
feb11 0:7a1237bd2d13 155
feb11 0:7a1237bd2d13 156 // reset state
feb11 0:7a1237bd2d13 157 switch(type)
feb11 0:7a1237bd2d13 158 {
feb11 0:7a1237bd2d13 159 case SHA_224:
feb11 0:7a1237bd2d13 160 h0 = H[0];
feb11 0:7a1237bd2d13 161 h1 = H[1];
feb11 0:7a1237bd2d13 162 h2 = H[2];
feb11 0:7a1237bd2d13 163 h3 = H[3];
feb11 0:7a1237bd2d13 164 h4 = H[4];
feb11 0:7a1237bd2d13 165 h5 = H[5];
feb11 0:7a1237bd2d13 166 h6 = H[6];
feb11 0:7a1237bd2d13 167 h7 = H[7];
feb11 0:7a1237bd2d13 168 break;
feb11 0:7a1237bd2d13 169
feb11 0:7a1237bd2d13 170 case SHA_256:
feb11 0:7a1237bd2d13 171 h0 = H[8];
feb11 0:7a1237bd2d13 172 h1 = H[9];
feb11 0:7a1237bd2d13 173 h2 = H[10];
feb11 0:7a1237bd2d13 174 h3 = H[11];
feb11 0:7a1237bd2d13 175 h4 = H[12];
feb11 0:7a1237bd2d13 176 h5 = H[13];
feb11 0:7a1237bd2d13 177 h6 = H[14];
feb11 0:7a1237bd2d13 178 h7 = H[15];
feb11 0:7a1237bd2d13 179 break;
feb11 0:7a1237bd2d13 180 }
feb11 0:7a1237bd2d13 181 totalBufferLength = 0;
feb11 0:7a1237bd2d13 182 bufferLength = 0;
feb11 0:7a1237bd2d13 183 }
feb11 0:7a1237bd2d13 184
feb11 6:19aa835f2bbb 185 void SHA2_32::computeHash(SHA_32_TYPE type, uint8_t *hash, uint8_t *data, uint32_t length)
feb11 6:19aa835f2bbb 186 {
feb11 6:19aa835f2bbb 187 uint32_t *hash2 = (uint32_t*)hash;
feb11 10:bc9c23aa3870 188
feb11 10:bc9c23aa3870 189 uint32_t h[8];
feb11 10:bc9c23aa3870 190 h[0] = H[type*8];
feb11 10:bc9c23aa3870 191 h[1] = H[type*8+1];
feb11 10:bc9c23aa3870 192 h[2] = H[type*8+2];
feb11 10:bc9c23aa3870 193 h[3] = H[type*8+3];
feb11 10:bc9c23aa3870 194 h[4] = H[type*8+4];
feb11 10:bc9c23aa3870 195 h[5] = H[type*8+5];
feb11 10:bc9c23aa3870 196 h[6] = H[type*8+6];
feb11 10:bc9c23aa3870 197 h[7] = H[type*8+7];
feb11 10:bc9c23aa3870 198
feb11 6:19aa835f2bbb 199 uint64_t lengthBit = length << 3;
feb11 10:bc9c23aa3870 200 uint32_t padding;
feb11 6:19aa835f2bbb 201 if(length % 64 < 56)
feb11 6:19aa835f2bbb 202 padding = 56 - (length % 64);
feb11 6:19aa835f2bbb 203 else
feb11 6:19aa835f2bbb 204 padding = 56 + (64 - (length % 64));
feb11 6:19aa835f2bbb 205
feb11 6:19aa835f2bbb 206 while(length >= 64)
feb11 6:19aa835f2bbb 207 {
feb11 10:bc9c23aa3870 208 computeBlock(h, &h[1], &h[2], &h[3], &h[4], &h[5], &h[6], &h[7], data);
feb11 6:19aa835f2bbb 209 length -= 64;
feb11 6:19aa835f2bbb 210 data += 64;
feb11 6:19aa835f2bbb 211 }
feb11 6:19aa835f2bbb 212 uint8_t buffer[64];
feb11 6:19aa835f2bbb 213 memcpy(buffer, data,length);
feb11 6:19aa835f2bbb 214 buffer[length++] = 0x80;
feb11 6:19aa835f2bbb 215 padding--;
feb11 6:19aa835f2bbb 216 if(padding+length == 56)
feb11 6:19aa835f2bbb 217 memset(&buffer[length], 0, padding);
feb11 6:19aa835f2bbb 218 else
feb11 6:19aa835f2bbb 219 {
feb11 6:19aa835f2bbb 220 memset(&buffer[length], 0, 64-length);
feb11 10:bc9c23aa3870 221 computeBlock(h, &h[1], &h[2], &h[3], &h[4], &h[5], &h[6], &h[7], buffer);
feb11 6:19aa835f2bbb 222 memset(buffer, 0, 56);
feb11 6:19aa835f2bbb 223 }
feb11 6:19aa835f2bbb 224
feb11 6:19aa835f2bbb 225 uint32_t lengthBitLow = lengthBit;
feb11 6:19aa835f2bbb 226 uint32_t lengthBitHigh = lengthBit >> 32;
feb11 13:ac8e23b98dae 227 lengthBitLow = revWord(lengthBitLow);
feb11 6:19aa835f2bbb 228 memcpy(&buffer[60], &lengthBitLow, 4);
feb11 13:ac8e23b98dae 229 lengthBitHigh = revWord(lengthBitHigh);
feb11 6:19aa835f2bbb 230 memcpy(&buffer[56], &lengthBitHigh, 4);
feb11 10:bc9c23aa3870 231 computeBlock(h, &h[1], &h[2], &h[3], &h[4], &h[5], &h[6], &h[7], buffer);
feb11 6:19aa835f2bbb 232
feb11 13:ac8e23b98dae 233 hash2[0] = revWord(h[0]);
feb11 13:ac8e23b98dae 234 hash2[1] = revWord(h[1]);
feb11 13:ac8e23b98dae 235 hash2[2] = revWord(h[2]);
feb11 13:ac8e23b98dae 236 hash2[3] = revWord(h[3]);
feb11 13:ac8e23b98dae 237 hash2[4] = revWord(h[4]);
feb11 13:ac8e23b98dae 238 hash2[5] = revWord(h[5]);
feb11 13:ac8e23b98dae 239 hash2[6] = revWord(h[6]);
feb11 6:19aa835f2bbb 240
feb11 6:19aa835f2bbb 241
feb11 6:19aa835f2bbb 242 if(type == SHA_256)
feb11 13:ac8e23b98dae 243 hash2[7] = revWord(h[7]);
feb11 6:19aa835f2bbb 244 }
feb11 6:19aa835f2bbb 245
feb11 13:ac8e23b98dae 246
feb11 13:ac8e23b98dae 247 #ifdef __CC_ARM
feb11 13:ac8e23b98dae 248 __forceinline
feb11 13:ac8e23b98dae 249 #endif
feb11 13:ac8e23b98dae 250 void SHA2_32::computeBlock(uint32_t *h02,
feb11 0:7a1237bd2d13 251 uint32_t *h12,
feb11 0:7a1237bd2d13 252 uint32_t *h22,
feb11 0:7a1237bd2d13 253 uint32_t *h32,
feb11 0:7a1237bd2d13 254 uint32_t *h42,
feb11 0:7a1237bd2d13 255 uint32_t *h52,
feb11 0:7a1237bd2d13 256 uint32_t *h62,
feb11 0:7a1237bd2d13 257 uint32_t *h72,
feb11 0:7a1237bd2d13 258 uint8_t *buffer)
feb11 0:7a1237bd2d13 259 {
feb11 4:0da19393bd57 260 uint32_t w[16];
feb11 3:85c6ee25cf3e 261 uint32_t *buffer2 = (uint32_t*)buffer;
feb11 3:85c6ee25cf3e 262 uint32_t a = *h02, b = *h12, c = *h22, d = *h32, e = *h42, f = *h52, g = *h62, h = *h72;
feb11 3:85c6ee25cf3e 263 uint32_t T1, T2;
feb11 4:0da19393bd57 264
feb11 4:0da19393bd57 265 R(a,b,c,d,e,f,g,h,0,0x428a2f98)
feb11 4:0da19393bd57 266 R(h,a,b,c,d,e,f,g,1,0x71374491)
feb11 4:0da19393bd57 267 R(g,h,a,b,c,d,e,f,2,0xb5c0fbcf)
feb11 4:0da19393bd57 268 R(f,g,h,a,b,c,d,e,3,0xe9b5dba5)
feb11 4:0da19393bd57 269 R(e,f,g,h,a,b,c,d,4,0x3956c25b)
feb11 4:0da19393bd57 270 R(d,e,f,g,h,a,b,c,5,0x59f111f1)
feb11 4:0da19393bd57 271 R(c,d,e,f,g,h,a,b,6,0x923f82a4)
feb11 4:0da19393bd57 272 R(b,c,d,e,f,g,h,a,7,0xab1c5ed5)
feb11 3:85c6ee25cf3e 273
feb11 4:0da19393bd57 274 R(a,b,c,d,e,f,g,h,8,0xd807aa98)
feb11 4:0da19393bd57 275 R(h,a,b,c,d,e,f,g,9,0x12835b01)
feb11 4:0da19393bd57 276 R(g,h,a,b,c,d,e,f,10,0x243185be)
feb11 4:0da19393bd57 277 R(f,g,h,a,b,c,d,e,11,0x550c7dc3)
feb11 4:0da19393bd57 278 R(e,f,g,h,a,b,c,d,12,0x72be5d74)
feb11 4:0da19393bd57 279 R(d,e,f,g,h,a,b,c,13,0x80deb1fe)
feb11 4:0da19393bd57 280 R(c,d,e,f,g,h,a,b,14,0x9bdc06a7)
feb11 4:0da19393bd57 281 R(b,c,d,e,f,g,h,a,15,0xc19bf174)
feb11 4:0da19393bd57 282
feb11 4:0da19393bd57 283 R2(a,b,c,d,e,f,g,h,16,0xe49b69c1)
feb11 4:0da19393bd57 284 R2(h,a,b,c,d,e,f,g,17,0xefbe4786)
feb11 4:0da19393bd57 285 R2(g,h,a,b,c,d,e,f,18,0x0fc19dc6)
feb11 4:0da19393bd57 286 R2(f,g,h,a,b,c,d,e,19,0x240ca1cc)
feb11 4:0da19393bd57 287 R2(e,f,g,h,a,b,c,d,20,0x2de92c6f)
feb11 4:0da19393bd57 288 R2(d,e,f,g,h,a,b,c,21,0x4a7484aa)
feb11 4:0da19393bd57 289 R2(c,d,e,f,g,h,a,b,22,0x5cb0a9dc)
feb11 4:0da19393bd57 290 R2(b,c,d,e,f,g,h,a,23,0x76f988da)
feb11 3:85c6ee25cf3e 291
feb11 4:0da19393bd57 292 R2(a,b,c,d,e,f,g,h,24,0x983e5152)
feb11 4:0da19393bd57 293 R2(h,a,b,c,d,e,f,g,25,0xa831c66d)
feb11 4:0da19393bd57 294 R2(g,h,a,b,c,d,e,f,26,0xb00327c8)
feb11 4:0da19393bd57 295 R2(f,g,h,a,b,c,d,e,27,0xbf597fc7)
feb11 4:0da19393bd57 296 R2(e,f,g,h,a,b,c,d,28,0xc6e00bf3)
feb11 4:0da19393bd57 297 R2(d,e,f,g,h,a,b,c,29,0xd5a79147)
feb11 4:0da19393bd57 298 R2(c,d,e,f,g,h,a,b,30,0x06ca6351)
feb11 4:0da19393bd57 299 R2(b,c,d,e,f,g,h,a,31,0x14292967)
feb11 4:0da19393bd57 300
feb11 4:0da19393bd57 301 R2(a,b,c,d,e,f,g,h,32,0x27b70a85)
feb11 4:0da19393bd57 302 R2(h,a,b,c,d,e,f,g,33,0x2e1b2138)
feb11 4:0da19393bd57 303 R2(g,h,a,b,c,d,e,f,34,0x4d2c6dfc)
feb11 4:0da19393bd57 304 R2(f,g,h,a,b,c,d,e,35,0x53380d13)
feb11 4:0da19393bd57 305 R2(e,f,g,h,a,b,c,d,36,0x650a7354)
feb11 4:0da19393bd57 306 R2(d,e,f,g,h,a,b,c,37,0x766a0abb)
feb11 4:0da19393bd57 307 R2(c,d,e,f,g,h,a,b,38,0x81c2c92e)
feb11 4:0da19393bd57 308 R2(b,c,d,e,f,g,h,a,39,0x92722c85)
feb11 3:85c6ee25cf3e 309
feb11 4:0da19393bd57 310 R2(a,b,c,d,e,f,g,h,40,0xa2bfe8a1)
feb11 4:0da19393bd57 311 R2(h,a,b,c,d,e,f,g,41,0xa81a664b)
feb11 4:0da19393bd57 312 R2(g,h,a,b,c,d,e,f,42,0xc24b8b70)
feb11 4:0da19393bd57 313 R2(f,g,h,a,b,c,d,e,43,0xc76c51a3)
feb11 4:0da19393bd57 314 R2(e,f,g,h,a,b,c,d,44,0xd192e819)
feb11 4:0da19393bd57 315 R2(d,e,f,g,h,a,b,c,45,0xd6990624)
feb11 4:0da19393bd57 316 R2(c,d,e,f,g,h,a,b,46,0xf40e3585)
feb11 4:0da19393bd57 317 R2(b,c,d,e,f,g,h,a,47,0x106aa070)
feb11 3:85c6ee25cf3e 318
feb11 4:0da19393bd57 319 R2(a,b,c,d,e,f,g,h,48,0x19a4c116)
feb11 4:0da19393bd57 320 R2(h,a,b,c,d,e,f,g,49,0x1e376c08)
feb11 4:0da19393bd57 321 R2(g,h,a,b,c,d,e,f,50,0x2748774c)
feb11 4:0da19393bd57 322 R2(f,g,h,a,b,c,d,e,51,0x34b0bcb5)
feb11 4:0da19393bd57 323 R2(e,f,g,h,a,b,c,d,52,0x391c0cb3)
feb11 4:0da19393bd57 324 R2(d,e,f,g,h,a,b,c,53,0x4ed8aa4a)
feb11 4:0da19393bd57 325 R2(c,d,e,f,g,h,a,b,54,0x5b9cca4f)
feb11 4:0da19393bd57 326 R2(b,c,d,e,f,g,h,a,55,0x682e6ff3)
feb11 4:0da19393bd57 327
feb11 4:0da19393bd57 328 R2(a,b,c,d,e,f,g,h,56,0x748f82ee)
feb11 4:0da19393bd57 329 R2(h,a,b,c,d,e,f,g,57,0x78a5636f)
feb11 4:0da19393bd57 330 R2(g,h,a,b,c,d,e,f,58,0x84c87814)
feb11 4:0da19393bd57 331 R2(f,g,h,a,b,c,d,e,59,0x8cc70208)
feb11 4:0da19393bd57 332 R2(e,f,g,h,a,b,c,d,60,0x90befffa)
feb11 4:0da19393bd57 333 R2(d,e,f,g,h,a,b,c,61,0xa4506ceb)
feb11 4:0da19393bd57 334 R2(c,d,e,f,g,h,a,b,62,0xbef9a3f7)
feb11 4:0da19393bd57 335 R2(b,c,d,e,f,g,h,a,63,0xc67178f2)
feb11 3:85c6ee25cf3e 336
feb11 0:7a1237bd2d13 337
feb11 0:7a1237bd2d13 338 *h02 += a;
feb11 0:7a1237bd2d13 339 *h12 += b;
feb11 0:7a1237bd2d13 340 *h22 += c;
feb11 0:7a1237bd2d13 341 *h32 += d;
feb11 0:7a1237bd2d13 342 *h42 += e;
feb11 0:7a1237bd2d13 343 *h52 += f;
feb11 0:7a1237bd2d13 344 *h62 += g;
feb11 0:7a1237bd2d13 345 *h72 += h;
feb11 0:7a1237bd2d13 346 }