MD5和SHA1算法C++实现及运行时间分析

来源:互联网 发布:不用网络和流量的游戏 编辑:程序博客网 时间:2024/05/17 20:33

1.MD5代码实现

HMAC.H即MD5头文件。

#ifndef HMAC_H#define HMAC_H//POINTER defines a generic pointer type typedef unsigned char *POINTER;//UINT2 defines a two byte word typedef unsigned short int UINT2;//UINT4 defines a four byte word typedef unsigned long int UINT4;typedef struct {UINT4 state[4];             //state (ABCD)UINT4 count[2];//number of bits, modulo 2^64 (lsb first)unsigned char buffer[64];   //input buffer } MD5_CTX;#define S11 7#define S12 12#define S13 17#define S14 22#define S21 5#define S22 9#define S23 14#define S24 20#define S31 4#define S32 11#define S33 16#define S34 23#define S41 6#define S42 10#define S43 15#define S44 21static unsigned char PADDING[64] = {  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};//F, G, H and I are basic MD5 functions.#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))#define H(x, y, z) ((x) ^ (y) ^ (z))#define I(x, y, z) ((y) ^ ((x) | (~z)))//ROTATE_LEFT rotates x left n bits.#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))////FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.//Rotation is separate from addition to prevent recomputation.//#define FF(a, b, c, d, x, s, ac) { \ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \  }#define GG(a, b, c, d, x, s, ac) { \ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \  }#define HH(a, b, c, d, x, s, ac) { \ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \  }#define II(a, b, c, d, x, s, ac) { \ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \  }extern voidMD5Init(MD5_CTX *);extern voidMD5Update(MD5_CTX *, unsigned char *, unsigned int);extern voidMD5Final(unsigned char [16], MD5_CTX *);extern voidhmac_md5( unsigned char*  text, int             text_len,   unsigned char*  key,        int             key_len,    unsigned char*  digest      );#endif


HMAC.CPP,即MD5源码

#include "HMAC.H"#include <string.h>/*Following work is derived from "derived from the RSA DataSecurity, Inc. MD5 Message-Digest Algorithm"*/staticvoidMD5Transform(UINT4 [4], unsigned char [64]);staticvoidEncode(unsigned char *, UINT4 *, unsigned int);staticvoidDecode(UINT4 *, unsigned char *, unsigned int);staticvoidMD5_memcpy (POINTER, POINTER, unsigned int);staticvoidMD5_memset (POINTER, int, unsigned int);/*MD5 initialization. Begins an MD5 operation, writing a new context.*/voidMD5Init(MD5_CTX *context){context->count[0] = context->count[1] = 0;////Load magic initialization constants.//context->state[0] = 0x67452301;context->state[1] = 0xefcdab89;context->state[2] = 0x98badcfe;context->state[3] = 0x10325476;}/* MD5 block update operation. Continues an MD5 message-digestoperation, processing another message block, and updating thecontext.*/void MD5Update(   MD5_CTX*context,//context    unsigned char*input,     //input block   unsigned intinputLen//length of input block   ){unsigned int i, index, partLen;////Compute number of bytes mod 64//index = (unsigned int)((context->count[0] >> 3) & 0x3F);////Update number of bits//if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3)){context->count[1]++;}context->count[1] += ((UINT4)inputLen >> 29);partLen = 64 - index;////Transform as many times as possible.//if (inputLen >= partLen) {MD5_memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen);MD5Transform (context->state, context->buffer);for (i = partLen; i + 63 < inputLen; i += 64){MD5Transform (context->state, &input[i]);}index = 0;}else{i = 0;}////Buffer remaining input //MD5_memcpy((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i);}/* MD5 finalization. Ends an MD5 message-digest operation, writing thethe message digest and zeroizing the context.*/void MD5Final (unsigned chardigest[16],//message digestMD5_CTX*context//context){unsigned charbits[8];unsigned intindex, padLen;////Save number of bits//Encode (bits, context->count, 8);////Pad out to 56 mod 64.//index = (unsigned int)((context->count[0] >> 3) & 0x3f);padLen = (index < 56) ? (56 - index) : (120 - index);  MD5Update (context, PADDING, padLen);////Append length (before padding) //MD5Update (context, bits, 8);////Store state in digest//Encode (digest, context->state, 16);////Zeroize sensitive information.//MD5_memset ((POINTER)context, 0, sizeof (*context));}/* MD5 basic transformation. Transforms state based on block.*/static void MD5Transform( UINT4 state[4], unsigned char block[64] ){UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];Decode (x, block, 64);// Round 1FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 *//* Round 2 */GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 *//* Round 3 */HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 *//* Round 4 */II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */state[0] += a;state[1] += b;state[2] += c;state[3] += d;// Zeroize sensitive information.MD5_memset ((POINTER)x, 0, sizeof (x));}/* Encodes input (UINT4) into output (unsigned char). Assumes len isa multiple of 4.*/staticvoidEncode(unsigned char *output,UINT4 *input,unsigned int len){unsigned int i, j;for (i = 0, j = 0; j < len; i++, j += 4) {output[j]= (unsigned char)(input[i] & 0xff);output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);}}/* Decodes input (unsigned char) into output (UINT4). Assumes len isa multiple of 4.*/static void Decode (UINT4 *output,unsigned char *input,unsigned int len){unsigned int i, j;for (i = 0, j = 0; j < len; i++, j += 4){output[i] = ((UINT4)input[j])| (((UINT4)input[j+1]) << 8) |(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);}}static void MD5_memcpy (POINTER output,POINTER input,unsigned int len){unsigned int i;for (i = 0; i < len; i++){output[i] = input[i];}}static void MD5_memset (POINTER output,int value,unsigned int len){unsigned int i;for (i = 0; i < len; i++){((char *)output)[i] = (char)value;}}/* Digests a string and prints the result.*/static void MDString (char *string){MD5_CTX context;unsigned char digest[16];unsigned int len = strlen (string);MD5Init (&context);MD5Update (&context, (unsigned char*)string, len);MD5Final (digest, &context);}/*Function: hmac_md5*/voidhmac_md5( unsigned char*  text,// pointer to data stream int             text_len,  // length of data stream unsigned char*  key,       // pointer to authentication key int             key_len,   // length of authentication key unsigned char*  digest     // caller digest to be filled in ){MD5_CTX context;unsigned char k_ipad[65];    // inner padding - key XORd with ipad                                       unsigned char k_opad[65];    // outer padding - key XORd with opadunsigned char tk[16];        int i;    //    //if key is longer than 64 bytes reset it to key=MD5(key)    //    if (key_len > 64) {MD5_CTX      tctx;MD5Init(&tctx);MD5Update(&tctx, key, key_len);MD5Final(tk, &tctx);key = tk;key_len = 16;}/*the HMAC_MD5 transform looks like: MD5(K XOR opad, MD5(K XOR ipad, text)) where K is an n byte key ipad is the byte 0x36 repeated 64 timesopad is the byte 0x5c repeated 64 times     and text is the data being protected */     ////start out by storing key in pads//for(i=0;i<65;i++){k_ipad[i]=k_opad[i]=0;}for(i=0;i<key_len;i++){k_ipad[i]=k_opad[i]=key[i];}////XOR key with ipad and opad values//    for (i=0; i<64; i++) {k_ipad[i] ^= 0x36;k_opad[i] ^= 0x5c;}////perform inner MD5//MD5Init(&context);MD5Update(&context, k_ipad, 64); MD5Update(&context, text, text_len); MD5Final(digest, &context);               ////perform outer MD5//MD5Init(&context);  MD5Update(&context, k_opad, 64);MD5Update(&context, digest, 16);    MD5Final(digest, &context);}

2. SHA1算法代码

sha1.h

#ifndef _IPSEC_SHA1_H_#define _IPSEC_SHA1_H_typedef unsigned long__u32;typedef unsigned char__u8;typedef struct{__u32 state[5];__u32 count[2];__u8  buffer[64];} SHA1_CTX;#if defined(rol)#undef rol#endif#define SHA1HANDSOFF#define __LITTLE_ENDIAN #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))/* blk0() and blk() perform the initial expand. *//* I got the idea of expanding during the round function from SSLeay */#ifdef __LITTLE_ENDIAN#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \    |(rol(block->l[i],8)&0x00FF00FF))#else#define blk0(i) block->l[i]#endif#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \    ^block->l[(i+2)&15]^block->l[i&15],1))/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);/* Hash a single 512-bit block. This is the core of the algorithm. */void SHA1Transform(__u32 state[5], __u8 buffer[64]);void SHA1Init(SHA1_CTX *context);void SHA1Update(SHA1_CTX *context, unsigned char *data, __u32 len);void SHA1Final(unsigned char digest[20], SHA1_CTX *context);//void hmac_sha1(unsigned char *to_mac,unsigned int to_mac_length, unsigned char *key,unsigned int key_length, unsigned char *out_mac); /* Function to compute the digest */void hmac_sha1(unsigned char* d, /* data */intld, //data lenunsigned char* k, /* secret key */intlk, //key lenunsigned char* out /* output buffer, at least "t" bytes */);#endif /* _IPSEC_SHA1_H_ */
sha1.cpp

#include "sha1.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <memory.h>#ifndef SHA_DIGESTSIZE#define SHA_DIGESTSIZE 20#endif#ifndef SHA_BLOCKSIZE#define SHA_BLOCKSIZE 64#endif/* Hash a single 512-bit block. This is the core of the algorithm. */void SHA1Transform(__u32 state[5], __u8 buffer[64]){__u32 a, b, c, d, e;typedef union {    unsigned char c[64];    __u32 l[16];} CHAR64LONG16;CHAR64LONG16* block;#ifdef SHA1HANDSOFFstatic unsigned char workspace[64];    block = (CHAR64LONG16*)workspace;//    NdisMoveMemory(block, buffer, 64);    memcpy(block, buffer, 64);#else    block = (CHAR64LONG16*)buffer;#endif    /* Copy context->state[] to working vars */    a = state[0];    b = state[1];    c = state[2];    d = state[3];    e = state[4];    /* 4 rounds of 20 operations each. Loop unrolled. */    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);    /* Add the working vars back into context.state[] */    state[0] += a;    state[1] += b;    state[2] += c;    state[3] += d;    state[4] += e;    /* Wipe variables */    a = b = c = d = e = 0;}/* SHA1Init - Initialize new context */void SHA1Init(SHA1_CTX* context){    /* SHA1 initialization constants */    context->state[0] = 0x67452301;    context->state[1] = 0xEFCDAB89;    context->state[2] = 0x98BADCFE;    context->state[3] = 0x10325476;    context->state[4] = 0xC3D2E1F0;    context->count[0] = context->count[1] = 0;}/* Run your data through this. */void SHA1Update(SHA1_CTX* context, unsigned char* data, __u32 len){__u32 i, j;    j = context->count[0];    if ((context->count[0] += len << 3) < j)context->count[1]++;    context->count[1] += (len>>29);    j = (j >> 3) & 63;    if ((j + len) > 63) {//        NdisMoveMemory(&context->buffer[j], data, (i = 64-j));        memcpy(&context->buffer[j], data, (i = 64-j));        SHA1Transform(context->state, context->buffer);        for ( ; i + 63 < len; i += 64) {            SHA1Transform(context->state, &data[i]);        }        j = 0;    }    else i = 0;//    NdisMoveMemory(&context->buffer[j], &data[i], len - i);    memcpy(&context->buffer[j], &data[i], len - i);}/* Add padding and return the message digest. */void SHA1Final(unsigned char digest[20], SHA1_CTX* context){__u32 i, j;unsigned char finalcount[8];    for (i = 0; i < 8; i++) {        finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]         >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */    }    SHA1Update(context, (unsigned char *)"\200", 1);    while ((context->count[0] & 504) != 448) {        SHA1Update(context, (unsigned char *)"\0", 1);    }    SHA1Update(context, finalcount, 8);  /* Should cause a SHA1Transform() */    for (i = 0; i < 20; i++) {        digest[i] = (unsigned char)         ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);    }    /* Wipe variables */    i = j = 0;//    NdisZeroMemory(context->buffer, 64);//    NdisZeroMemory(context->state, 20);//    NdisZeroMemory(context->count, 8);//    NdisZeroMemory(&finalcount, 8);    memset(context->buffer, 0x00, 64);    memset(context->state, 0x00, 20);    memset(context->count, 0x00, 8);    memset(&finalcount, 0x00, 8);    #ifdef SHA1HANDSOFF  /* make SHA1Transform overwrite its own static vars */    SHA1Transform(context->state, context->buffer);#endif}/* Function to print the digest */void pr_sha(FILE* fp, unsigned char* s, int t){    int i ;for(i=0;i<t;i++)printf("%02x",s[i]);printf("\n");/*fprintf(fp, "0x") ;for (i = 0 ; i < t ; i++){fprintf(fp, "%02x", s[i]) ;printf("\n");}fprintf(fp, "0") ;*/}void truncate(char* d1, /* data to be truncated */char* d2, /* truncated data */int len /* length in bytes to keep */){int i ;for (i = 0 ; i < len ; i++) d2[i] = d1[i];}/* Function to compute the digest *//* Function to compute the digest */void hmac_sha1(unsigned char* d, /* data */intld, //data lenunsigned char* k, /* secret key */intlk, //key lenunsigned char* out /* output buffer, at least "t" bytes */){int t=SHA_DIGESTSIZE;SHA1_CTX ictx, octx ;char isha[SHA_DIGESTSIZE], osha[SHA_DIGESTSIZE] ;unsigned char key[SHA_DIGESTSIZE] ;char buf[SHA_BLOCKSIZE] ;int i ;if (lk > SHA_BLOCKSIZE) {SHA1_CTX tctx ;SHA1Init(&tctx) ;SHA1Update(&tctx, k, lk) ;SHA1Final(key, &tctx) ;k = key ;lk = SHA_DIGESTSIZE ;}/**** Inner Digest ****/SHA1Init(&ictx) ;/* Pad the key for inner digest */for (i = 0 ; i < lk ; ++i) buf[i] = k[i] ^ 0x36 ;for (i = lk ; i < SHA_BLOCKSIZE ; ++i) buf[i] = 0x36 ;SHA1Update(&ictx, (unsigned char*)buf, SHA_BLOCKSIZE) ;SHA1Update(&ictx, d, ld) ;SHA1Final((unsigned char*)isha, &ictx) ;/**** Outter Digest ****/SHA1Init(&octx) ;/* Pad the key for outter digest */for (i = 0 ; i < lk ; ++i) buf[i] = k[i] ^ 0x5C ;for (i = lk ; i < SHA_BLOCKSIZE ; ++i) buf[i] = 0x5C ;SHA1Update(&octx, (unsigned char*)buf, SHA_BLOCKSIZE) ;SHA1Update(&octx, (unsigned char*)isha, SHA_DIGESTSIZE) ;SHA1Final((unsigned char*)out, &octx) ;/* truncate and print the results */t = t > SHA_DIGESTSIZE ? SHA_DIGESTSIZE : t ;//truncate(osha, (char*)out, t) ;//pr_sha(stdout, out, t) ;}

3.测试代码及时间分析

#include "stdio.h" #include "stdlib.h"#include "time.h"#include "sha1.h"#include "HMAC.H"#include "string.h"/* Function to print the digest */void pr_hex(FILE* fp, unsigned char* s, int t){    int i ;for(i=0;i<t;i++)fprintf(fp, "%02x",s[i]);fprintf(fp,"\n");}int main( ) { clock_t start, finish; double Total_time; unsigned char key[20] = "gfedcba987654321";//16bytesunsigned char data[20] = "123456789abcdefg";//16bytesunsigned char digest[20];FILE* time_file;if ((time_file = fopen("time.txt","w")) == NULL){printf("open time.txt fail\n");}int data_len, key_len;fprintf(time_file, "MD5:\n");for (data_len = 4; data_len <= 16; data_len += 4){for (key_len = 4; key_len <= 16; key_len += 4){/* 测量一个事件持续的时间*/ fprintf(time_file, "Time to loop 1000 times is(data_len=%2d, key_len=%2d): ",data_len, key_len); start = clock(); for (int j = 0; j < 1000; j++){hmac_md5(data,data_len,key,key_len,digest);}finish = clock(); Total_time = (double)(finish-start) / CLOCKS_PER_SEC; fprintf(time_file, "%f seconds\n", Total_time); pr_hex(time_file, digest, 16);}}fprintf(time_file, "\n\n\n\nSHA1:\n");for (data_len = 4; data_len <= 16; data_len += 4){for (key_len = 4; key_len <= 16; key_len += 4){/* 测量一个事件持续的时间*/ fprintf(time_file, "Time to loop 1000 times is(data_len=%2d, key_len=%2d): ",data_len, key_len); start = clock(); for (int j = 0; j < 1000; j++){hmac_sha1(data,data_len,key,key_len,digest);}finish = clock(); Total_time = (double)(finish-start) / CLOCKS_PER_SEC; fprintf(time_file, "%f seconds\n", Total_time); pr_hex(time_file, digest, 20);}}pr_hex(time_file, digest, 20);    return 0;}



0 0