zoukankan      html  css  js  c++  java
  • sequence.c

    /*
     * sequence.c
     */
    #include <stdio.h>
    #include <memory.h>
    
    /*
     * SM3算法产生的哈希值大小(单位:字节)
     */
    #define SM3_HASH_SIZE 32 
    
    /*
     * SM3上下文
     */
    typedef struct SM3Context
    {
        unsigned int intermediateHash[SM3_HASH_SIZE / 4];
        unsigned char messageBlock[64];
    } SM3Context;
    
    /*
     * 判断运行环境是否为小端
     */
    static const int endianTest = 1;
    #define IsLittleEndian() (*(char *)&endianTest == 1)
    
    /*
     * 向左循环移位
     */
    #define LeftRotate(word, bits) ( (word) << (bits) | (word) >> (32 - (bits)) )
    
    /*
     * 反转四字节整型字节序
     */
    unsigned int *ReverseWord(unsigned int *word)
    {
        unsigned char *byte, temp;
    
        byte = (unsigned char *)word;
        temp = byte[0];
        byte[0] = byte[3];    
        byte[3] = temp;
    
        temp = byte[1];
        byte[1] = byte[2];
        byte[2] = temp;
        return word;
    }
    
    /*
     * T
     */
    unsigned int T(int i)
    {
        if (i >= 0 && i <= 15)
            return 0x79CC4519;
        else if (i >= 16 && i <= 63)
            return 0x7A879D8A;
        else
            return 0;
    }
    
    /*
     * FF
     */
    unsigned int FF(unsigned int X, unsigned int Y, unsigned int Z, int i)
    {
        if (i >= 0 && i <= 15)
            return X ^ Y ^ Z;
        else if (i >= 16 && i <= 63)
            return (X & Y) | (X & Z) | (Y & Z);
        else
            return 0;
    }
    
    /*
     * GG
     */
    unsigned int GG(unsigned int X, unsigned int Y, unsigned int Z, int i)
    {
        if (i >= 0 && i <= 15)
            return X ^ Y ^ Z;
        else if (i >= 16 && i <= 63)
            return (X & Y) | (~X & Z);
        else
            return 0;
    }
    
    /*
     * P0
     */
    unsigned int P0(unsigned int X)
    {
        return X ^ LeftRotate(X, 9) ^ LeftRotate(X, 17);
    }
    
    /*
     * P1
     */
    unsigned int P1(unsigned int X)
    {
        return X ^ LeftRotate(X, 15) ^ LeftRotate(X, 23);
    }
    
    /*
     * 初始化函数
     */
    void SM3Init(SM3Context *context)
    {
        context->intermediateHash[0] = 0x7380166F;
        context->intermediateHash[1] = 0x4914B2B9;
        context->intermediateHash[2] = 0x172442D7;
        context->intermediateHash[3] = 0xDA8A0600;
        context->intermediateHash[4] = 0xA96F30BC;
        context->intermediateHash[5] = 0x163138AA;
        context->intermediateHash[6] = 0xE38DEE4D;
        context->intermediateHash[7] = 0xB0FB0E4E;
    }
    
    /*
     * 处理消息块
     */
    void SM3ProcessMessageBlock(SM3Context *context)
    {
        int i;
        unsigned int W[68];
        unsigned int W_[64];
        unsigned int A, B, C, D, E, F, G, H, SS1, SS2, TT1, TT2;
    
        /* 消息扩展 */
        for (i = 0; i < 16; i++)
        {
            W[i] = *(unsigned int *)(context->messageBlock + i * 4);
            if (IsLittleEndian())
                ReverseWord(W + i);
            //printf("%d: %x
    ", i, W[i]);  
        }
        for (i = 16; i < 68; i++)
        {
            W[i] = P1(W[i - 16] ^ W[i - 9] ^ LeftRotate(W[i - 3], 15)) 
                    ^ LeftRotate(W[i - 13], 7) 
                    ^ W[i - 6];
            //printf("%d: %x
    ", i, W[i]);  
        }
        for (i = 0; i < 64; i++)
        {
            W_[i] = W[i] ^ W[i + 4];
            //printf("%d: %x
    ", i, W_[i]); 
        }
    
        /* 消息压缩 */
        A = context->intermediateHash[0];
        B = context->intermediateHash[1];
        C = context->intermediateHash[2];
        D = context->intermediateHash[3];
        E = context->intermediateHash[4];
        F = context->intermediateHash[5];
        G = context->intermediateHash[6];
        H = context->intermediateHash[7];
        for (i = 0; i < 64; i++)
        {
            SS1 = LeftRotate((LeftRotate(A, 12) + E + LeftRotate(T(i), i)), 7);
            SS2 = SS1 ^ LeftRotate(A, 12);
            TT1 = FF(A, B, C, i) + D + SS2 + W_[i];
            TT2 = GG(E, F, G, i) + H + SS1 + W[i];
            D = C;
            C = LeftRotate(B, 9);
            B = A;
            A = TT1;
            H = G;
            G = LeftRotate(F, 19);
            F = E;
            E = P0(TT2);
        }
        context->intermediateHash[0] ^= A;
        context->intermediateHash[1] ^= B;
        context->intermediateHash[2] ^= C;
        context->intermediateHash[3] ^= D;
        context->intermediateHash[4] ^= E;
        context->intermediateHash[5] ^= F;
        context->intermediateHash[6] ^= G;
        context->intermediateHash[7] ^= H;
    }
    
    /*
     * SM3算法主函数
     */
    unsigned char *SM3Calc(const unsigned char *message, 
            unsigned int messageLen, unsigned char digest[SM3_HASH_SIZE])
    {
        SM3Context context;
        unsigned int i, remainder, bitLen;
    
        SM3Init(&context);
    
        for (i = 0; i < messageLen / 64; i++)
        {
            memcpy(context.messageBlock, message + i * 64, 64);
            SM3ProcessMessageBlock(&context);
        }
    
        bitLen = messageLen * 8;
        if (IsLittleEndian())
            ReverseWord(&bitLen);
        remainder = messageLen % 64;
        memcpy(context.messageBlock, message + i * 64, remainder);
        context.messageBlock[remainder] = 0x80;
        if (remainder <= 55)
        {
            memset(context.messageBlock + remainder + 1, 0, 64 - remainder - 1 - 8 + 4);
            memcpy(context.messageBlock + 64 - 4, &bitLen, 4);  
            SM3ProcessMessageBlock(&context);
        }
        else
        {
            memset(context.messageBlock + remainder + 1, 0, 64 - remainder - 1);
            SM3ProcessMessageBlock(&context);
            memset(context.messageBlock, 0, 64 - 4);
            memcpy(context.messageBlock + 64 - 4, &bitLen, 4);  
            SM3ProcessMessageBlock(&context);
        }
    
        if (IsLittleEndian())
            for (i = 0; i < 8; i++)
                ReverseWord(context.intermediateHash + i);
        memcpy(digest, context.intermediateHash, SM3_HASH_SIZE);
    
        return digest;
    }
    
    /*
     * 计算SM3,并将结果以无符号整数形式返回
     */
    unsigned int SM3CalcAndReturnUInt(const unsigned char *message, unsigned int messageLen)
    {   
        int i;
        unsigned int s;
        unsigned char digest[SM3_HASH_SIZE];
        
        SM3Calc(message, messageLen, digest);
        for (i = 0, s = 0; i < SM3_HASH_SIZE; i += 4)
        {
            s += digest[i + 0] << 24 |
                 digest[i + 1] << 16 |
                 digest[i + 2] << 8  |
                 digest[i + 3] << 0;
        }
    
        return s;
    }
    
    int main(void)
    {
        printf("%x
    ", SM3CalcAndReturnUInt("x1x2x3x4x5x6", strlen("x1x2x3x4x5x6")));
        return 0;
    }
  • 相关阅读:
    [Luogu P3626] [APIO2009] 会议中心
    杭电 1869 六度分离 (求每两个节点间的距离)
    杭电 1874 畅通工程续 (求某节点到某节点的最短路径)
    最短路径模板
    杭电 2544 最短路径
    POJ 1287 Networking (最小生成树模板题)
    NYOJ 1875 畅通工程再续 (无节点间距离求最小生成树)
    POJ 2485 Highways (求最小生成树中最大的边)
    杭电 1233 还是畅通工程 (最小生成树)
    杭电 1863 畅通工程 (最小生成树)
  • 原文地址:https://www.cnblogs.com/liubaocheng999/p/4191113.html
Copyright © 2011-2022 走看看