信息摘要算法——SHA-1(OpenSSL源码注释)
我是小绿,研究了一下OpenSSL中SHA-1算法的实现流程。
我并没有去深究加密细节(如,某个哈希常量为什么是这个数字、为什么要在这里左移多少多少位),因为完全没有必要,发明者发明它享受荣誉,使用者使用它享受便捷。我是使用者,就是这样。
SHA/MD5加密流程:
01. 分块
02. 补位
03. 补长度
04. 加密
05. 输出
主逻辑函数:
1 unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md) 2 { 3 SHA_CTX c; 4 static unsigned char m[SHA_DIGEST_LENGTH]; 5 6 if (md == NULL) 7 md = m; 8 if (!SHA1_Init(&c)) 9 return NULL; 10 SHA1_Update(&c, d, n); 11 SHA1_Final(md, &c); 12 bzero(&c, sizeof(c)); 13 return md; 14 }
SHA1.h:
1 #include2 #include 3 4 #define SHA_LBLOCK 16 5 #define SHA_CBLOCK (SHA_LBLOCK*4) 6 #define SHA_LAST_BLOCK (SHA_CBLOCK-8) 7 #define SHA_DIGEST_LENGTH 20 8 9 typedef struct SHAstate_st { 10 unsigned int h0, h1, h2, h3, h4; // 保存哈希初始值、最终加密后的散列值 11 unsigned int Nl, Nh; // 记录输入字符串的长度,字符串长度的单位是位。Nl-保存低32位;Nh-保存高32位。如,长度是5字节(40位),Nh保存0,Nl保存40 12 unsigned int data[SHA_LBLOCK]; // 缓冲区,用于保存:原始报文+补位的数据+补长度的数据 13 unsigned int num; // 记录缓冲区已经使用了多少位 14 } SHA_CTX; 15 16 int SHA1_Init(SHA_CTX *c); 17 int SHA1_Update(SHA_CTX *c, const void *data, size_t len); 18 int SHA1_Final(unsigned char *md, SHA_CTX *c); 19 unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md); 20 static void sha1_block_data_order(SHA_CTX *c, const void *p, size_t num);
SHA1.c
1 #include "sha1.h" 2 3 #define X(i) XX##i 4 5 /* 哈希初值 */ 6 #define INIT_DATA_h0 0x67452301UL 7 #define INIT_DATA_h1 0xefcdab89UL 8 #define INIT_DATA_h2 0x98badcfeUL 9 #define INIT_DATA_h3 0x10325476UL 10 #define INIT_DATA_h4 0xc3d2e1f0UL 11 12 /* 哈希常量(与哈希函数对应) */ 13 #define K_00_19 0x5a827999UL // 使用轮次:00~19 14 #define K_20_39 0x6ed9eba1UL // 使用轮次:20~39 15 #define K_40_59 0x8f1bbcdcUL // 使用轮次:40~59 16 #define K_60_79 0xca62c1d6UL // 使用轮次:60~79 17 18 /* 哈希函数(与哈希常量对应) */ 19 #define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) // 使用轮次:00~19 20 #define F_20_39(b,c,d) ((b) ^ (c) ^ (d)) // 使用轮次:20~39 21 #define F_40_59(b,c,d) (((b) & (c)) | (((b)|(c)) & (d))) // 使用轮次:40~59 22 #define F_60_79(b,c,d) F_20_39(b,c,d) // 使用轮次:60~79 23 24 /* 将a循环左移n位,相当于汇编指令中的rol */ 25 #define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) 26 27 /* 28 * SHA1官方文档: 29 * W(t) = S^1(W(t-3) XOR W(t-8) XOR W(t-14) XOR W(t-16)). 30 */ 31 #define Xupdate(a,ix,ia,ib,ic,id) ( (a)=(ia^ib^ic^id), \ 32 ix=(a)=ROTATE((a),1) \ 33 ) 34 35 /* 在轮次00~15时加密 */ 36 /* 37 * SHA1官方文档: 38 * TEMP = S^5(A) + f(B,C,D) + E + W(t) + K(t); 39 * E = D; D = C; C = S^30(B); B = A; A = TEMP; 40 */ 41 // i :轮次 42 // f :TEMP 43 // K_00_19 :0x5a827999 44 // ROTATE((a),5) :将a循环左移5次 45 // F_00_19((b),(c),(d)) :((c ^ d) & b) ^ d 46 // ROTATE((b),30) :将b循环左移30次 47 #define BODY_00_15(i,a,b,c,d,e,f,xi) \ 48 (f)=xi+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \ 49 (b)=ROTATE((b),30); 50 51 /* 在轮次16~19时加密 */ 52 /* 53 * SHA1官方文档: 54 * TEMP = S^5(A) + f(B,C,D) + E + W(t) + K(t); 55 * E = D; D = C; C = S^30(B); B = A; A = TEMP; 56 * W(t) = S^1(W(t-3) XOR W(t-8) XOR W(t-14) XOR W(t-16)). 57 */ 58 // i :轮次 59 // K_00_19 :0x5a827999 60 // ROTATE((a),5) :将a循环左移5次 61 // F_00_19((b),(c),(d)) :((c ^ d) & b) ^ d 62 // ROTATE((b),30) :将b循环左移30次 63 #define BODY_16_19(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \ 64 Xupdate(f,xi,xa,xb,xc,xd); \ 65 (f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \ 66 (b)=ROTATE((b),30); 67 68 /* 在轮次20~31时加密 */ 69 /* 70 * SHA1官方文档: 71 * TEMP = S^5(A) + f(B,C,D) + E + W(t) + K(t); 72 * E = D; D = C; C = S^30(B); B = A; A = TEMP; 73 * W(t) = S^1(W(t-3) XOR W(t-8) XOR W(t-14) XOR W(t-16)). 74 */ 75 // i :轮次 76 // K_20_39 :0x6ed9eba1 77 // ROTATE((a),5) :将a循环左移5次 78 // F_20_39((b),(c),(d)) :b ^ c ^ d 79 // ROTATE((b),30) :将b循环左移30次 80 #define BODY_20_31(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \ 81 Xupdate(f,xi,xa,xb,xc,xd); \ 82 (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \ 83 (b)=ROTATE((b),30); 84 85 /* 在轮次32~39时加密 */ 86 /* 87 * SHA1官方文档: 88 * TEMP = S^5(A) + f(B,C,D) + E + W(t) + K(t); 89 * E = D; D = C; C = S^30(B); B = A; A = TEMP; 90 * W(t) = S^1(W(t-3) XOR W(t-8) XOR W(t-14) XOR W(t-16)). 91 */ 92 // i :轮次 93 // K_20_39 :0x6ed9eba1 94 // ROTATE((a),5) :将a循环左移5次 95 // F_20_39((b),(c),(d)) :b ^ c ^ d 96 // ROTATE((b),30) :将b循环左移30次 97 #define BODY_32_39(i,a,b,c,d,e,f,xa,xb,xc,xd) \ 98 Xupdate(f,xa,xa,xb,xc,xd); \ 99 (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \ 100 (b)=ROTATE((b),30); 101 102 /* 在轮次40~59时加密 */ 103 /* 104 * SHA1官方文档: 105 * TEMP = S^5(A) + f(B,C,D) + E + W(t) + K(t); 106 * E = D; D = C; C = S^30(B); B = A; A = TEMP; 107 * W(t) = S^1(W(t-3) XOR W(t-8) XOR W(t-14) XOR W(t-16)). 108 */ 109 // i :轮次 110 // K_40_59 :0x8f1bbcdc 111 // ROTATE((a),5) :将a循环左移5次 112 // F_40_59((b),(c),(d)) :(b & c) | ((b | c) & (d)) 113 // ROTATE((b),30) :将b循环左移30次 114 #define BODY_40_59(i,a,b,c,d,e,f,xa,xb,xc,xd) \ 115 Xupdate(f,xa,xa,xb,xc,xd); \ 116 (f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \ 117 (b)=ROTATE((b),30); 118 119 /* 在轮次60~79时加密 */ 120 /* 121 * SHA1官方文档: 122 * TEMP = S^5(A) + f(B,C,D) + E + W(t) + K(t); 123 * E = D; D = C; C = S^30(B); B = A; A = TEMP; 124 * W(t) = S^1(W(t-3) XOR W(t-8) XOR W(t-14) XOR W(t-16)). 125 */ 126 // i :轮次 127 // K_60_79 :0xca62c1d6 128 // ROTATE((a),5) :将a循环左移5次 129 // F_60_79((b),(c),(d)) :b ^ c ^ d 130 // ROTATE((b),30) :将b循环左移30次 131 #define BODY_60_79(i,a,b,c,d,e,f,xa,xb,xc,xd) \ 132 Xupdate(f,xa,xa,xb,xc,xd); \ 133 (f)=xa+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \ 134 (b)=ROTATE((b),30); 135 136 /* 32位赋值(将某地址上的值赋给某个变量,赋值完后地址相对于原先+4) */ 137 // c-地址 138 // l-变量 139 #define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ 140 l|=(((unsigned long)(*((c)++)))<<16), \ 141 l|=(((unsigned long)(*((c)++)))<< 8), \ 142 l|=(((unsigned long)(*((c)++))) ) ) 143 144 /* 32位赋值(将指定的值赋给某地址上,赋值完后地址相对于原先+4) */ 145 // c-地址 146 // l-变量/立即数 147 #define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ 148 *((c)++)=(unsigned char)(((l)>>16)&0xff), \ 149 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ 150 *((c)++)=(unsigned char)(((l) )&0xff), \ 151 l) 152 153 /* 生成20字节的散列值 */ 154 #define HASH_MAKE_STRING(c,s) do { \ 155 unsigned long ll; \ 156 ll=(c)->h0; (void)HOST_l2c(ll,(s)); \ 157 ll=(c)->h1; (void)HOST_l2c(ll,(s)); \ 158 ll=(c)->h2; (void)HOST_l2c(ll,(s)); \ 159 ll=(c)->h3; (void)HOST_l2c(ll,(s)); \ 160 ll=(c)->h4; (void)HOST_l2c(ll,(s)); \ 161 } while (0) 162 163 void bzero(void *ptr, size_t len) 164 { 165 memset(ptr, 0, len); 166 } 167 168 169 unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md) 170 { 171 SHA_CTX c; 172 static unsigned char m[SHA_DIGEST_LENGTH]; 173 174 if (md == NULL) 175 md = m; 176 if (!SHA1_Init(&c)) 177 return NULL; 178 SHA1_Update(&c, d, n); 179 SHA1_Final(md, &c); 180 bzero(&c, sizeof(c)); 181 return md; 182 } 183 184 int SHA1_Init(SHA_CTX *c) 185 { 186 memset(c, 0, sizeof(*c)); 187 c->h0 = INIT_DATA_h0; 188 c->h1 = INIT_DATA_h1; 189 c->h2 = INIT_DATA_h2; 190 c->h3 = INIT_DATA_h3; 191 c->h4 = INIT_DATA_h4; 192 return 1; 193 } 194 195 int SHA1_Update(SHA_CTX *c, const void *data_, size_t len) 196 { 197 const unsigned char *input = (const unsigned char *)data_; 198 unsigned char *p; 199 unsigned int l; 200 size_t n; 201 202 if (len == 0) 203 return 1; 204 205 // len << 3:传入加密报文的长度,原先单位是字节,左移3位相当于乘以8转换为位数 206 // c->Nl:保存输入报文长度的低32位,报文长度的单位是位 207 l = (c->Nl + (((unsigned int)len) << 3)) & 0xffffffffUL; 208 209 /* 若发生溢出 */ 210 if (l < c->Nl) 211 c->Nh++; 212 213 /* 更新输入报文长度的高32位 */ 214 c->Nh += (unsigned int)(len >> 29); 215 216 /* 更新输入报文长度的低32位 */ 217 c->Nl = l; 218 219 /*------------------------------------------------------------------*/ 220 // 当调用SHA1()时该区域不会被执行,只有手动多次调用SHA1_Update()时才会用到 221 // OpenSSL源码中多次调用SHA1_Update()是在crypto\md5\md5_sha1.c 222 n = c->num; 223 if (n != 0) { 224 p = (unsigned char *)c->data; 225 226 if (len >= SHA_CBLOCK || len + n >= SHA_CBLOCK) { 227 memcpy(p + n, input, SHA_CBLOCK - n); 228 sha1_block_data_order(c, p, 1); 229 n = SHA_CBLOCK - n; 230 input += n; 231 len -= n; 232 c->num = 0; 233 memset(p, 0, SHA_CBLOCK); 234 } 235 else { 236 memcpy(p + n, input, len); 237 c->num += (unsigned int)len; 238 return 1; 239 } 240 } 241 /*------------------------------------------------------------------*/ 242 243 /* 若需要分组,就先加密n*512位 */ 244 // n = len / 64,即n是输入报文的长度以64字节为单位分割的分组个数 245 n = len / SHA_CBLOCK; 246 if (n > 0) { 247 sha1_block_data_order(c, input, n); 248 n *= SHA_CBLOCK; 249 input += n; 250 len -= n; 251 } 252 253 /* 若不是报文长度不是64的整数倍,就拷贝(剩余)报文 */ 254 if (len != 0) { 255 p = (unsigned char *)c->data; 256 c->num = (unsigned int)len; 257 memcpy(p, input, len); 258 } 259 return 1; 260 } 261 262 int SHA1_Final(unsigned char *md, SHA_CTX *c) 263 { 264 unsigned char *p = (unsigned char *)c->data; 265 size_t n = c->num; // n-需要补位的位置 266 267 /* 补位1000 0000 */ 268 p[n] = 0x80; 269 n++; 270 271 /* 若n超出了56(即448位),就先加密512位 */ 272 if (n > (SHA_CBLOCK - 8)) { 273 memset(p + n, 0, SHA_CBLOCK - n); 274 n = 0; 275 sha1_block_data_order(c, p, 1); 276 } 277 /* 补位0000 0000 .... .... */ 278 memset(p + n, 0, SHA_CBLOCK - 8 - n); 279 280 /* 补长度 */ 281 p += SHA_CBLOCK - 8; 282 (void)HOST_l2c(c->Nh, p); 283 (void)HOST_l2c(c->Nl, p); 284 285 /* 加密 */ 286 p -= SHA_CBLOCK; 287 sha1_block_data_order(c, p, 1); 288 289 /* 清理 */ 290 c->num = 0; 291 bzero(p, SHA_CBLOCK); 292 293 /* 生成20字节的散列值 */ 294 HASH_MAKE_STRING(c, md); 295 296 return 1; 297 } 298 299 static void sha1_block_data_order(SHA_CTX *c, const void *p, size_t num) 300 { 301 const unsigned char *data = (const unsigned char *)p; 302 register unsigned int A, B, C, D, E, T, l; 303 unsigned int XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, 304 XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15; 305 306 /* 307 * SHA1官方文档: 308 * The words of the first 5-word buffer are labeled A,B,C,D,E. 309 * The words of the second 5-word buffer are labeled H0, H1, H2, H3, H4. 310 * Let A = H0, B = H1, C = H2, D = H3, E = H4. 311 */ 312 A = c->h0; 313 B = c->h1; 314 C = c->h2; 315 D = c->h3; 316 E = c->h4; 317 318 for (;;) { 319 const union { 320 long one; 321 char little; 322 } is_endian = { 323 1 324 }; 325 326 327 /* 328 * SHA1官方文档: 329 * The words of the 80-word sequence are labeled W(0), W(1),..., W(79). 330 * Divide M(i) into 16 words W(0), W(1), ... , W(15), where W(0) is the left-most word. 331 * For t = 0 to 79 do: 332 TEMP = S^5(A) + f(B,C,D) + E + W(t) + K(t); 333 E = D; D = C; C = S^30(B); B = A; A = TEMP; 334 */ 335 // M(i):待加密数据的缓冲区 336 337 // is_endian.little:若为1,表明是运行此程序的CPU是小端序 338 // (size_t)p % 4:判断地址是不是4的整数倍 339 if (!is_endian.little && sizeof(unsigned int) == 4 && ((size_t)p % 4) == 0) { 340 const unsigned int *W = (const unsigned int *)data; 341 342 X(0) = W[0]; 343 X(1) = W[1]; 344 BODY_00_15(0, A, B, C, D, E, T, X(0)); 345 X(2) = W[2]; 346 BODY_00_15(1, T, A, B, C, D, E, X(1)); 347 X(3) = W[3]; 348 BODY_00_15(2, E, T, A, B, C, D, X(2)); 349 X(4) = W[4]; 350 BODY_00_15(3, D, E, T, A, B, C, X(3)); 351 X(5) = W[5]; 352 BODY_00_15(4, C, D, E, T, A, B, X(4)); 353 X(6) = W[6]; 354 BODY_00_15(5, B, C, D, E, T, A, X(5)); 355 X(7) = W[7]; 356 BODY_00_15(6, A, B, C, D, E, T, X(6)); 357 X(8) = W[8]; 358 BODY_00_15(7, T, A, B, C, D, E, X(7)); 359 X(9) = W[9]; 360 BODY_00_15(8, E, T, A, B, C, D, X(8)); 361 X(10) = W[10]; 362 BODY_00_15(9, D, E, T, A, B, C, X(9)); 363 X(11) = W[11]; 364 BODY_00_15(10, C, D, E, T, A, B, X(10)); 365 X(12) = W[12]; 366 BODY_00_15(11, B, C, D, E, T, A, X(11)); 367 X(13) = W[13]; 368 BODY_00_15(12, A, B, C, D, E, T, X(12)); 369 X(14) = W[14]; 370 BODY_00_15(13, T, A, B, C, D, E, X(13)); 371 X(15) = W[15]; 372 BODY_00_15(14, E, T, A, B, C, D, X(14)); 373 BODY_00_15(15, D, E, T, A, B, C, X(15)); 374 375 data += SHA_CBLOCK; 376 } 377 else { 378 (void)HOST_c2l(data, l); 379 X(0) = l; 380 (void)HOST_c2l(data, l); 381 X(1) = l; 382 BODY_00_15(0, A, B, C, D, E, T, X(0)); 383 (void)HOST_c2l(data, l); 384 X(2) = l; 385 // 对于上一组来说ABCDET循环右移一位成TABCDE 386 // 即SHA1官方文档上的:E = D; D = C; C = S^30(B); B = A; A = TEMP; 387 // 往后类似 388 BODY_00_15(1, T, A, B, C, D, E, X(1)); 389 (void)HOST_c2l(data, l); 390 X(3) = l; 391 BODY_00_15(2, E, T, A, B, C, D, X(2)); 392 (void)HOST_c2l(data, l); 393 X(4) = l; 394 BODY_00_15(3, D, E, T, A, B, C, X(3)); 395 (void)HOST_c2l(data, l); 396 X(5) = l; 397 BODY_00_15(4, C, D, E, T, A, B, X(4)); 398 (void)HOST_c2l(data, l); 399 X(6) = l; 400 BODY_00_15(5, B, C, D, E, T, A, X(5)); 401 (void)HOST_c2l(data, l); 402 X(7) = l; 403 BODY_00_15(6, A, B, C, D, E, T, X(6)); 404 (void)HOST_c2l(data, l); 405 X(8) = l; 406 BODY_00_15(7, T, A, B, C, D, E, X(7)); 407 (void)HOST_c2l(data, l); 408 X(9) = l; 409 BODY_00_15(8, E, T, A, B, C, D, X(8)); 410 (void)HOST_c2l(data, l); 411 X(10) = l; 412 BODY_00_15(9, D, E, T, A, B, C, X(9)); 413 (void)HOST_c2l(data, l); 414 X(11) = l; 415 BODY_00_15(10, C, D, E, T, A, B, X(10)); 416 (void)HOST_c2l(data, l); 417 X(12) = l; 418 BODY_00_15(11, B, C, D, E, T, A, X(11)); 419 (void)HOST_c2l(data, l); 420 X(13) = l; 421 BODY_00_15(12, A, B, C, D, E, T, X(12)); 422 (void)HOST_c2l(data, l); 423 X(14) = l; 424 BODY_00_15(13, T, A, B, C, D, E, X(13)); 425 (void)HOST_c2l(data, l); 426 X(15) = l; 427 BODY_00_15(14, E, T, A, B, C, D, X(14)); 428 BODY_00_15(15, D, E, T, A, B, C, X(15)); 429 } 430 431 /* 432 * SHA1官方文档: 433 * For t = 16 to 79 let: 434 W(t) = S^1(W(t-3) XOR W(t-8) XOR W(t-14) XOR W(t-16)). 435 TEMP = S^5(A) + f(B,C,D) + E + W(t) + K(t); 436 E = D; D = C; C = S^30(B); B = A; A = TEMP; 437 */ 438 BODY_16_19(16, C, D, E, T, A, B, X(0), X(0), X(2), X(8), X(13)); 439 BODY_16_19(17, B, C, D, E, T, A, X(1), X(1), X(3), X(9), X(14)); 440 BODY_16_19(18, A, B, C, D, E, T, X(2), X(2), X(4), X(10), X(15)); 441 BODY_16_19(19, T, A, B, C, D, E, X(3), X(3), X(5), X(11), X(0)); 442 443 BODY_20_31(20, E, T, A, B, C, D, X(4), X(4), X(6), X(12), X(1)); 444 BODY_20_31(21, D, E, T, A, B, C, X(5), X(5), X(7), X(13), X(2)); 445 BODY_20_31(22, C, D, E, T, A, B, X(6), X(6), X(8), X(14), X(3)); 446 BODY_20_31(23, B, C, D, E, T, A, X(7), X(7), X(9), X(15), X(4)); 447 BODY_20_31(24, A, B, C, D, E, T, X(8), X(8), X(10), X(0), X(5)); 448 BODY_20_31(25, T, A, B, C, D, E, X(9), X(9), X(11), X(1), X(6)); 449 BODY_20_31(26, E, T, A, B, C, D, X(10), X(10), X(12), X(2), X(7)); 450 BODY_20_31(27, D, E, T, A, B, C, X(11), X(11), X(13), X(3), X(8)); 451 BODY_20_31(28, C, D, E, T, A, B, X(12), X(12), X(14), X(4), X(9)); 452 BODY_20_31(29, B, C, D, E, T, A, X(13), X(13), X(15), X(5), X(10)); 453 BODY_20_31(30, A, B, C, D, E, T, X(14), X(14), X(0), X(6), X(11)); 454 BODY_20_31(31, T, A, B, C, D, E, X(15), X(15), X(1), X(7), X(12)); 455 456 BODY_32_39(32, E, T, A, B, C, D, X(0), X(2), X(8), X(13)); 457 BODY_32_39(33, D, E, T, A, B, C, X(1), X(3), X(9), X(14)); 458 BODY_32_39(34, C, D, E, T, A, B, X(2), X(4), X(10), X(15)); 459 BODY_32_39(35, B, C, D, E, T, A, X(3), X(5), X(11), X(0)); 460 BODY_32_39(36, A, B, C, D, E, T, X(4), X(6), X(12), X(1)); 461 BODY_32_39(37, T, A, B, C, D, E, X(5), X(7), X(13), X(2)); 462 BODY_32_39(38, E, T, A, B, C, D, X(6), X(8), X(14), X(3)); 463 BODY_32_39(39, D, E, T, A, B, C, X(7), X(9), X(15), X(4)); 464 465 BODY_40_59(40, C, D, E, T, A, B, X(8), X(10), X(0), X(5)); 466 BODY_40_59(41, B, C, D, E, T, A, X(9), X(11), X(1), X(6)); 467 BODY_40_59(42, A, B, C, D, E, T, X(10), X(12), X(2), X(7)); 468 BODY_40_59(43, T, A, B, C, D, E, X(11), X(13), X(3), X(8)); 469 BODY_40_59(44, E, T, A, B, C, D, X(12), X(14), X(4), X(9)); 470 BODY_40_59(45, D, E, T, A, B, C, X(13), X(15), X(5), X(10)); 471 BODY_40_59(46, C, D, E, T, A, B, X(14), X(0), X(6), X(11)); 472 BODY_40_59(47, B, C, D, E, T, A, X(15), X(1), X(7), X(12)); 473 BODY_40_59(48, A, B, C, D, E, T, X(0), X(2), X(8), X(13)); 474 BODY_40_59(49, T, A, B, C, D, E, X(1), X(3), X(9), X(14)); 475 BODY_40_59(50, E, T, A, B, C, D, X(2), X(4), X(10), X(15)); 476 BODY_40_59(51, D, E, T, A, B, C, X(3), X(5), X(11), X(0)); 477 BODY_40_59(52, C, D, E, T, A, B, X(4), X(6), X(12), X(1)); 478 BODY_40_59(53, B, C, D, E, T, A, X(5), X(7), X(13), X(2)); 479 BODY_40_59(54, A, B, C, D, E, T, X(6), X(8), X(14), X(3)); 480 BODY_40_59(55, T, A, B, C, D, E, X(7), X(9), X(15), X(4)); 481 BODY_40_59(56, E, T, A, B, C, D, X(8), X(10), X(0), X(5)); 482 BODY_40_59(57, D, E, T, A, B, C, X(9), X(11), X(1), X(6)); 483 BODY_40_59(58, C, D, E, T, A, B, X(10), X(12), X(2), X(7)); 484 BODY_40_59(59, B, C, D, E, T, A, X(11), X(13), X(3), X(8)); 485 486 BODY_60_79(60, A, B, C, D, E, T, X(12), X(14), X(4), X(9)); 487 BODY_60_79(61, T, A, B, C, D, E, X(13), X(15), X(5), X(10)); 488 BODY_60_79(62, E, T, A, B, C, D, X(14), X(0), X(6), X(11)); 489 BODY_60_79(63, D, E, T, A, B, C, X(15), X(1), X(7), X(12)); 490 BODY_60_79(64, C, D, E, T, A, B, X(0), X(2), X(8), X(13)); 491 BODY_60_79(65, B, C, D, E, T, A, X(1), X(3), X(9), X(14)); 492 BODY_60_79(66, A, B, C, D, E, T, X(2), X(4), X(10), X(15)); 493 BODY_60_79(67, T, A, B, C, D, E, X(3), X(5), X(11), X(0)); 494 BODY_60_79(68, E, T, A, B, C, D, X(4), X(6), X(12), X(1)); 495 BODY_60_79(69, D, E, T, A, B, C, X(5), X(7), X(13), X(2)); 496 BODY_60_79(70, C, D, E, T, A, B, X(6), X(8), X(14), X(3)); 497 BODY_60_79(71, B, C, D, E, T, A, X(7), X(9), X(15), X(4)); 498 BODY_60_79(72, A, B, C, D, E, T, X(8), X(10), X(0), X(5)); 499 BODY_60_79(73, T, A, B, C, D, E, X(9), X(11), X(1), X(6)); 500 BODY_60_79(74, E, T, A, B, C, D, X(10), X(12), X(2), X(7)); 501 BODY_60_79(75, D, E, T, A, B, C, X(11), X(13), X(3), X(8)); 502 BODY_60_79(76, C, D, E, T, A, B, X(12), X(14), X(4), X(9)); 503 BODY_60_79(77, B, C, D, E, T, A, X(13), X(15), X(5), X(10)); 504 BODY_60_79(78, A, B, C, D, E, T, X(14), X(0), X(6), X(11)); 505 BODY_60_79(79, T, A, B, C, D, E, X(15), X(1), X(7), X(12)); 506 507 /* 508 * SHA1官方文档: 509 * Let H0 = H0 + A, H1 = H1 + B, H2 = H2 + C, H3 = H3 + D, H4 = H4 + E. 510 */ 511 c->h0 = (c->h0 + E) & 0xffffffffL; 512 c->h1 = (c->h1 + T) & 0xffffffffL; 513 c->h2 = (c->h2 + A) & 0xffffffffL; 514 c->h3 = (c->h3 + B) & 0xffffffffL; 515 c->h4 = (c->h4 + C) & 0xffffffffL; 516 517 if (--num == 0) 518 break; 519 520 /* 521 * SHA1官方文档: 522 * Let A = H0, B = H1, C = H2, D = H3, E = H4. 523 */ 524 A = c->h0; 525 B = c->h1; 526 C = c->h2; 527 D = c->h3; 528 E = c->h4; 529 530 } 531 }
main.c:
1 #include "sha1.h" 2 3 int main() 4 { 5 // be98dd7e9d71f94f83ef721326da671a38fb66a2 6 unsigned char strBuf[] = "Hello Sha1"; 7 int nSize = strlen((char*)strBuf); 8 unsigned char strOut[1024]; 9 SHA1(strBuf, nSize, strOut); 10 11 for (int i = 0; i < 20; i++) 12 { 13 printf("%x", strOut[i]); 14 } 15 puts(""); 16 17 getchar(); 18 return 0; 19 }