C语言实现SHA1算法

1.头文件及循环左移.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SAL(x,n) (((x>>(32-n)))|(x<<n))

2.字符串扩充.

int sha1_pad_message(unsigned char *str, int len)
{
    unsigned long high, low;
    int u = len % 64;

    high = 0;
    low = len * 8;

    if(u < 56)
    {
        str[len++] = 0x80;
        u++;

        while(u < 56)
        {
            str[len++] = 0x00;
            u++;
        }
    }
    else if(u > 56)
    {
        str[len++] = 0x80;
        u++;

        while(u < 56+64)
        {
            str[len++] = 0x00;
            u++;
        }
    }

    str[len++] = high >> 24;
    str[len++] = high >> 16;
    str[len++] = high >> 8;
    str[len++] = high;
    str[len++] = low >> 24;
    str[len++] = low >> 16;
    str[len++] = low >> 8;
    str[len++] = low;

    return len;
}

3.字符串打印.

int print_str(unsigned char *str, int len)
{
    int i = 0;

    printf("str=[");

    for(i=0; i<len; i++)
    {
        printf("%02X", str[i]);
    }

    printf("], len=[%d]\n", len);

    return 0;
}

4.信息分组处理.

int sha1_str_group_xor(unsigned char *a, unsigned char *b, unsigned char *c, unsigned char *d, unsigned char *e, int len)
{
    int i = 0;

    for(i=0; i<len; i++)
    {
        e[i] = a[i] ^ b[i] ^ c[i] ^ d[i];
    }

    return 0;
}

int sha1_str_group_sal(unsigned char *a, int len)
{
    int x = 0;
    int y = 0;
    int i = 0;

    for(i=len-1; i>=0; i--)
    {
        //printf("a[%d]=%d\n", i, a[i]);
        x = a[i] >> 7;
        a[i] <<= 1;
        //printf("a[%d]=%d\n", i, a[i]);
        a[i] |= y;
        //printf("a[%d]=%d\n", i, a[i]);
        y = x;
    }

    a[len-1] |= y;

    return 0;
}

unsigned long sha1_str_to_long(unsigned char *a)
{
    unsigned long x = 0;
    unsigned char *b = (unsigned char *)&x;

    b[0] = a[3];
    b[1] = a[2];
    b[2] = a[1];
    b[3] = a[0];

    return x;
}

int sha1_long_to_str(unsigned long a, unsigned char *b)
{
    unsigned long x = a;
    unsigned char *d = (unsigned char *)&x;

    b[0] = d[3];
    b[1] = d[2];
    b[2] = d[1];
    b[3] = d[0];

    return 0;
}

int sha1_str_group(unsigned char *str, int len)
{
    unsigned char M[64];
    unsigned char W[80][4];
    int u = len / 64;
    int v = 64 / 16 * 80;
    int i = 0;
    int j = 0;

    for(i=u-1; i>=0; i--)
    {
        memset(M, 0x00, sizeof(M));

        memcpy(M, str+i*64, 64);
        memcpy(str+i*v, M, 64);

        for(j=0; j<16; j++)
        {
            memcpy(W[j], M+4*j, 4);
            printf("W[%02d], ", j);
            print_str(W[j], 4);
        }

        for(j=16; j<80; j++)
        {
            sha1_str_group_xor(W[j-3], W[j-8], W[j-14], W[j-16], W[j], 4);
            //printf("W[%02d], ", j);
            //print_str(W[j], 4);
            sha1_str_group_sal(W[j], 4);
            printf("W[%02d], ", j);
            print_str(W[j], 4);
            memcpy(str+i*v+4*j, W[j], 4);
            //printf("W[%02d], ", j);
            //print_str(W[j], 4);
        }
    }

    return  u * v;
}

5.计算信息摘要.

int sha1_str_summ(unsigned char *str, unsigned char *summ, int len)
{
    unsigned char W[80][4];
    unsigned char Q[20] = {0x67, 0x45, 0x23, 0x01, 0xEF, 0xCD, 0xAB, 0x89, 0x98, 0xBA, 0xDC, 0xFE, 0x10, 0x32, 0x54, 0x76, 0xC3, 0xD2, 0xE1, 0xF0};
    unsigned long K[4]={0x5A827999,0x6ED9EBA1,0x8F1BBCDC,0xCA62C1D6};
    unsigned long N[5]={0, 0, 0, 0, 0};
    unsigned long A = sha1_str_to_long(Q);
    unsigned long B = sha1_str_to_long(Q+4);
    unsigned long C = sha1_str_to_long(Q+8);
    unsigned long D = sha1_str_to_long(Q+12);
    unsigned long E = sha1_str_to_long(Q+16);
    unsigned long F = 0;
    unsigned long G = 0;
    unsigned long H = 0;

    int u = len / 320;
    int i = 0;
    int j = 0;
    int k = 0;

    N[0] += A;
    N[1] += B;
    N[2] += C;
    N[3] += D;
    N[4] += E;

    for(i=0; i<u; i++)
    {
        for(j=0; j<80; j++)
        {
            memcpy(W[j], str+i*320+j*4, 4);
        }

        A = N[0];
        B = N[1];
        C = N[2];
        D = N[3];
        E = N[4];

        for(k=0; k<20; k++)
        {
            printf("A=[%08x]\n", A);

            G = sha1_str_to_long(W[k]);

            printf("W[%d]=[%08x]\n", i, G);
            F = ((B & C) | (~B & D));
            H = SAL(A,5) + F + E + G + K[0];
            E = D;
            D = C;
            C = SAL(B,30);
            B = A;
            A = H;

            printf("A=[%08x]\n", A);
        }

        for(k=20; k<40; k++)
        {
            G = sha1_str_to_long(W[k]);
            F = (B ^ C ^ D);
            H = SAL(A,5)+ F + E + G + K[1];
            E = D;
            D = C;
            C = SAL(B,30);
            B = A;
            A = H;

            printf("A=[%08x]\n", A);
        }

        for(k=40; k<60; k++)
        {
            G = sha1_str_to_long(W[k]);
            F = ((B & C) | (B & D) | (C & D));
            H = SAL(A,5)+ F + E + G + K[2];
            E = D;
            D = C;
            C = SAL(B,30);
            B = A;
            A = H;

            printf("A=[%08x]\n", A);
        }

        for(k=60; k<80; k++)
        {
            G = sha1_str_to_long(W[k]);
            F = (B ^ C ^ D);
            H = SAL(A,5)+ F + E + G + K[3];
            E = D;
            D = C;
            C = SAL(B,30);
            B = A;
            A = H;

            printf("A=[%08x]\n", A);
        }

        N[0] += A;
        N[1] += B;
        N[2] += C;
        N[3] += D;
        N[4] += E;
    }

    sha1_long_to_str(N[0], Q);
    sha1_long_to_str(N[1], Q+4);
    sha1_long_to_str(N[2], Q+8);
    sha1_long_to_str(N[3], Q+12);
    sha1_long_to_str(N[4], Q+16);

    memcpy(summ, Q, 20);

    return 0;
}

6.主函数部分.

int main()
{
    unsigned char str[256/16*80] = {0};
    unsigned char str_sha1[20];
    int len = 6;

    str[0] = 'a';
    str[1] = 'b';
    str[2] = 'c';
    str[3] = 'd';
    str[4] = 'e';
    str[5] = 'f';

    print_str(str, len);

    len = sha1_pad_message(str, len);

    print_str(str, len);

    len = sha1_str_group(str, len);

    print_str(str, len);

    sha1_str_summ(str, str_sha1, len);

    print_str(str_sha1, 20);

    return 0;
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容