精华内容
下载资源
问答
  • 向GCC学习C语言_国密SM3散列算法消息扩展函数实现相关
    2021-05-24 03:30:17

    依据国密SM3散列算法的标准文档,很容易写出其消息扩展函数的C语言实现:

    #include

    void expand_data(uint32_t W[68], uint32_t data[16])

    {

    uint32_tj, P1, X;

    for(j = 0; j < 16; j++) W[j] = data[j];

    for(j = 16; j < 68; j++) {

    X = W[j-16] ^ W[j-9] ^ ((W[j-3]<<15) | (W[j-3]>>17));

    P1 = X ^ ((X<<15)|(X>>17)) ^((X<<23)|(X>>9));

    W[j] = ((W[j-13]<<7)|(W[j-13]>>25)) ^ W[j-6] ^ P1;

    }

    }

    然而经过GCC编译成汇编语言之后,更接近下面的C语言实现

    #include

    void expand_data(uint32_t W[68], uint32_t data[16])

    {

    uint32_tj, X;

    for(j = 0; j < 16; j++) W[j] = data[j];

    for(j = 0; j < 52; j++) {

    X = W[j] ^ W[j+7] ^ ((W[j+13]<<15) | (W[j+13]>>17));

    W[j+16] = ((W[j+3]<<7)|(W[j+3]>>25)) ^ W[j+10] ^ X ^ ((X<<15)|(X>>17)) ^((X<<23)|(X>>9));

    }

    }

    上述两份C语言代码编译之后得到的汇编代码是完全相同的:

    .file"expand_data.c"

    .text

    .p2align 4,,15

    .globl expand_data

    .typeexpand_data, @function

    expand_data:

    .LFB0:

    .cfi_startproc

    xorl%eax, %eax#j = 0

    .p2align 4,,10

    .p2align 3

    .L2:

    movl(%rsi,%rax), %edx#edx = data[j]

    movl%edx, (%rdi,%rax)#W[j] = edx

    addq$4, %rax#j++

    cmpq$64, %rax#(j == 16)

    jne.L2#if (!=) goto .L2

    xorl%edx, %edx#j = 0

    .p2align 4,,10

    .p2align 3

    .L3:

    movl28(%rdi,%rdx), %ecx#ecx = W[j+7]

    movl52(%rdi,%rdx), %eax#eax = W[j+13]

    xorl(%rdi,%rdx), %ecx#ecx ^ W[j+0]

    rorl$17, %eax#eax = W[j+13]>>>17

    xorl%eax, %ecx#ecx ^ W[j+13]>>>17

    movl12(%rdi,%rdx), %eax#eax = W[j+3]

    movl%ecx, %esi#esi = X

    rorl$17, %esi#esi = X>>>17

    rorl$25, %eax#eax = W[j+3]>>>25

    xorl40(%rdi,%rdx), %eax#eax ^ W[j+10]

    xorl%ecx, %eax#eax ^ X

    rorl$9, %ecx#ecx = X>>>9

    xorl%esi, %eax#eax ^ X>>>17

    xorl%ecx, %eax#eax ^ X>>>9

    movl%eax, 64(%rdi,%rdx)#W[j+16] = eax

    addq$4, %rdx#j++

    cmpq$208, %rdx#(j == 52)

    jne.L3#if (!=) goto .L3

    rep; ret

    .cfi_endproc

    .LFE0:

    .sizeexpand_data, .-expand_data

    .ident"GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-23)"

    .section.note.GNU-stack,"",@progbits

    阅读GCC产生的汇编代码可知:

    1、((x >> 15) | (x << 17))这种会自动变成xor指令,无须使用宏夹杂内联汇编代码污染C语言代码的可读性;

    2、GCC会根据需要将临时变量进行寄存器优化,为了可读性多用几个临时变量没啥坏处;

    3、GCC似乎不喜欢减法,所以在C语言程序编写时,循环变量也好,数组下标也好,尽量使用加法而不是减法;

    更多相关内容
  • SM3算法 C语言 (从OpenSSL库中分离算法:六) OpenSSL简介: OpenSSL 是用于传输层安全性 (TLS) 和安全套接字层 (SSL) 协议的一个强大、商业级和功能齐全的工具包,它也是一个通用的密码学库。包含有RSA、SM4、DES、...

    SM3算法 C语言 (从OpenSSL库中分离算法:六)

    OpenSSL简介:

    OpenSSL 是用于传输层安全性 (TLS) 和安全套接字层 (SSL) 协议的一个强大、商业级和功能齐全的工具包,它也是一个通用的密码学库。包含有RSA、SM4、DES、AES等诸多加密算法。

    OpenSSL GitHub地址如下:

    GitHub - openssl/openssl: TLS/SSL and crypto library

    在日常的开发工作中,有时只想用OpenSSL库中的一种算法,此时调用整个OpenSSL库,往往是没必要的;再或者在嵌入式平台使用某一算法,那我们只移植这个算法,没有必要移植整个OpenSSL库。

    SM3简介

    SM3是我国采用的一种密码散列函数标准,由国家密码管理局于2010年12月17日发布。相关标准为“GM/T 0004-2012 《SM3密码杂凑算法》”。它可以将任意长度的消息压缩成固定长度的摘要,主要用于数字签名和数据完整性保护等

    在商用密码体系中,SM3主要用于数字签名及验证、消息认证码生成及验证、随机数生成等,其算法公开。据国家密码管理局表示,其安全性及效率与SHA-256相当。

    移植过程

    一、下载代码

    从OpenSSL的Github仓库下载代码,可以下载master分支,也可以下载最新的release版本。将下载的文件解压,得到代码。

    重点关注红框目录:

    • crypto目录内是各种加密算法
    • include目录内是各加密算法对外接口的头文件

    在这里插入图片描述

    二、准备环境

    新建Visual Studio C++ 控制台项目"sm3test",编译选项是:x86\Debug

    在这里插入图片描述
    在这里插入图片描述

    三、准备文件

    1. 复制OpenSSL源码中:/crypto/sm3文件夹到VS工程代码目录下
    2. 复制OpenSSL源码中:/include/internal/sm3.h文件到VS工程代码目录中sm3文件夹内
    3. 复制OpenSSL源码中:/include/crypto/md32_common.h文件到VS工程代码目录中sm3文件夹内
    4. 复制完成后,VS工程代码目录sm3文件夹内文件如下:

    在这里插入图片描述
    删除目录内的如下本项目中无用文件:

    • build.info
    • legacy_sm3.c

    四、修改代码

    修改调用文件

    在VS工程中含有main函数的主文件:sm3test.cpp中,增加包含sm3.h头文件

    #include "sm3/sm3.h"
    

    在main函数中添加如下代码

    SM3_CTX SMC;
        ossl_sm3_init(&SMC);
    
        const unsigned char Data[1024] = "Hello World";
        unsigned char md[SM3_DIGEST_LENGTH] = { 0 };
    
        ossl_sm3_update(&SMC, Data, strlen((const char *) Data));
        ossl_sm3_final(md, &SMC);
    
        for (int i = 0; i < SM3_DIGEST_LENGTH; i++) {
            printf("%02x-", *(md + i));
        }
    

    修改后的sm3test.cpp代码如下:

    #include <iostream>
    #include "sm3/sm3.h"
    int main()
    {
        SM3_CTX SMC;
        ossl_sm3_init(&SMC);
    
        const unsigned char Data[1024] = "Hello World";
        unsigned char md[SM3_DIGEST_LENGTH] = { 0 };
    
        ossl_sm3_update(&SMC, Data, strlen((const char *) Data));
        ossl_sm3_final(md, &SMC);
    
        for (int i = 0; i < SM3_DIGEST_LENGTH; i++) {
            printf("%02x-", *(md + i));
        }
    }
    

    修改sm3.h

    删除条件编译 OPENSSL_SM3_H

    删除头文件# include <openssl/opensslconf.h>

    删除条件编译 OPENSSL_NO_SM3

    添加C++调用时的宏

    修改或删除后的文件如下:

    # pragma once
    #  ifdef  __cplusplus
    extern "C" {
    #  endif
    
    # define SM3_DIGEST_LENGTH 32
    # define SM3_WORD unsigned int
    
    # define SM3_CBLOCK      64
    # define SM3_LBLOCK      (SM3_CBLOCK/4)
    
    typedef struct SM3state_st {
    	SM3_WORD A, B, C, D, E, F, G, H;
    	SM3_WORD Nl, Nh;
    	SM3_WORD data[SM3_LBLOCK];
    	unsigned int num;
    } SM3_CTX;
    
    int ossl_sm3_init(SM3_CTX* c);
    int ossl_sm3_update(SM3_CTX* c, const void* data, size_t len);
    int ossl_sm3_final(unsigned char* md, SM3_CTX* c);
    
    #  ifdef  __cplusplus
    }
    #  endif
    

    修改sm3_local.h

    修改头文件# include "internal/sm3.h"改为#include "sm3.h"

    修改头文件# include "crypto/md32_common.h"改为#include "md32_common.h"

    修改或删除后的文件如下:

    
    #include <string.h>
    #include "sm3.h"
    
    #define DATA_ORDER_IS_BIG_ENDIAN
    
    #define HASH_LONG               SM3_WORD
    #define HASH_CTX                SM3_CTX
    #define HASH_CBLOCK             SM3_CBLOCK
    #define HASH_UPDATE             ossl_sm3_update
    #define HASH_TRANSFORM          ossl_sm3_transform
    #define HASH_FINAL              ossl_sm3_final
    #define HASH_MAKE_STRING(c, s)              \
          do {                                  \
            unsigned long ll;                   \
            ll=(c)->A; (void)HOST_l2c(ll, (s)); \
            ll=(c)->B; (void)HOST_l2c(ll, (s)); \
            ll=(c)->C; (void)HOST_l2c(ll, (s)); \
            ll=(c)->D; (void)HOST_l2c(ll, (s)); \
            ll=(c)->E; (void)HOST_l2c(ll, (s)); \
            ll=(c)->F; (void)HOST_l2c(ll, (s)); \
            ll=(c)->G; (void)HOST_l2c(ll, (s)); \
            ll=(c)->H; (void)HOST_l2c(ll, (s)); \
          } while (0)
    #define HASH_BLOCK_DATA_ORDER   ossl_sm3_block_data_order
    
    void ossl_sm3_block_data_order(SM3_CTX *c, const void *p, size_t num);
    void ossl_sm3_transform(SM3_CTX *c, const unsigned char *data);
    
    #include "md32_common.h"
    
    #define P0(X) (X ^ ROTATE(X, 9) ^ ROTATE(X, 17))
    #define P1(X) (X ^ ROTATE(X, 15) ^ ROTATE(X, 23))
    
    #define FF0(X,Y,Z) (X ^ Y ^ Z)
    #define GG0(X,Y,Z) (X ^ Y ^ Z)
    
    #define FF1(X,Y,Z) ((X & Y) | ((X | Y) & Z))
    #define GG1(X,Y,Z) ((Z ^ (X & (Y ^ Z))))
    
    #define EXPAND(W0,W7,W13,W3,W10) \
       (P1(W0 ^ W7 ^ ROTATE(W13, 15)) ^ ROTATE(W3, 7) ^ W10)
    
    #define RND(A, B, C, D, E, F, G, H, TJ, Wi, Wj, FF, GG)           \
         do {                                                         \
           const SM3_WORD A12 = ROTATE(A, 12);                        \
           const SM3_WORD A12_SM = A12 + E + TJ;                      \
           const SM3_WORD SS1 = ROTATE(A12_SM, 7);                    \
           const SM3_WORD TT1 = FF(A, B, C) + D + (SS1 ^ A12) + (Wj); \
           const SM3_WORD TT2 = GG(E, F, G) + H + SS1 + Wi;           \
           B = ROTATE(B, 9);                                          \
           D = TT1;                                                   \
           F = ROTATE(F, 19);                                         \
           H = P0(TT2);                                               \
         } while(0)
    
    #define R1(A,B,C,D,E,F,G,H,TJ,Wi,Wj) \
       RND(A,B,C,D,E,F,G,H,TJ,Wi,Wj,FF0,GG0)
    
    #define R2(A,B,C,D,E,F,G,H,TJ,Wi,Wj) \
       RND(A,B,C,D,E,F,G,H,TJ,Wi,Wj,FF1,GG1)
    
    #define SM3_A 0x7380166fUL
    #define SM3_B 0x4914b2b9UL
    #define SM3_C 0x172442d7UL
    #define SM3_D 0xda8a0600UL
    #define SM3_E 0xa96f30bcUL
    #define SM3_F 0x163138aaUL
    #define SM3_G 0xe38dee4dUL
    #define SM3_H 0xb0fb0e4eUL
    
    

    修改sm3.c

    删除头文件#include <openssl/e_os2.h>

    修改或删除后的文件如下:

    #include "sm3_local.h"
    
    int ossl_sm3_init(SM3_CTX *c)
    {
        memset(c, 0, sizeof(*c));
        c->A = SM3_A;
        c->B = SM3_B;
        c->C = SM3_C;
        c->D = SM3_D;
        c->E = SM3_E;
        c->F = SM3_F;
        c->G = SM3_G;
        c->H = SM3_H;
        return 1;
    }
    
    void ossl_sm3_block_data_order(SM3_CTX *ctx, const void *p, size_t num)
    {
        const unsigned char *data = p;
        register unsigned MD32_REG_T A, B, C, D, E, F, G, H;
    
        unsigned MD32_REG_T W00, W01, W02, W03, W04, W05, W06, W07,
            W08, W09, W10, W11, W12, W13, W14, W15;
    
        for (; num--;) {
    
            A = ctx->A;
            B = ctx->B;
            C = ctx->C;
            D = ctx->D;
            E = ctx->E;
            F = ctx->F;
            G = ctx->G;
            H = ctx->H;
    
            /*
            * We have to load all message bytes immediately since SM3 reads
            * them slightly out of order.
            */
            (void)HOST_c2l(data, W00);
            (void)HOST_c2l(data, W01);
            (void)HOST_c2l(data, W02);
            (void)HOST_c2l(data, W03);
            (void)HOST_c2l(data, W04);
            (void)HOST_c2l(data, W05);
            (void)HOST_c2l(data, W06);
            (void)HOST_c2l(data, W07);
            (void)HOST_c2l(data, W08);
            (void)HOST_c2l(data, W09);
            (void)HOST_c2l(data, W10);
            (void)HOST_c2l(data, W11);
            (void)HOST_c2l(data, W12);
            (void)HOST_c2l(data, W13);
            (void)HOST_c2l(data, W14);
            (void)HOST_c2l(data, W15);
    
            R1(A, B, C, D, E, F, G, H, 0x79CC4519, W00, W00 ^ W04);
            W00 = EXPAND(W00, W07, W13, W03, W10);
            R1(D, A, B, C, H, E, F, G, 0xF3988A32, W01, W01 ^ W05);
            W01 = EXPAND(W01, W08, W14, W04, W11);
            R1(C, D, A, B, G, H, E, F, 0xE7311465, W02, W02 ^ W06);
            W02 = EXPAND(W02, W09, W15, W05, W12);
            R1(B, C, D, A, F, G, H, E, 0xCE6228CB, W03, W03 ^ W07);
            W03 = EXPAND(W03, W10, W00, W06, W13);
            R1(A, B, C, D, E, F, G, H, 0x9CC45197, W04, W04 ^ W08);
            W04 = EXPAND(W04, W11, W01, W07, W14);
            R1(D, A, B, C, H, E, F, G, 0x3988A32F, W05, W05 ^ W09);
            W05 = EXPAND(W05, W12, W02, W08, W15);
            R1(C, D, A, B, G, H, E, F, 0x7311465E, W06, W06 ^ W10);
            W06 = EXPAND(W06, W13, W03, W09, W00);
            R1(B, C, D, A, F, G, H, E, 0xE6228CBC, W07, W07 ^ W11);
            W07 = EXPAND(W07, W14, W04, W10, W01);
            R1(A, B, C, D, E, F, G, H, 0xCC451979, W08, W08 ^ W12);
            W08 = EXPAND(W08, W15, W05, W11, W02);
            R1(D, A, B, C, H, E, F, G, 0x988A32F3, W09, W09 ^ W13);
            W09 = EXPAND(W09, W00, W06, W12, W03);
            R1(C, D, A, B, G, H, E, F, 0x311465E7, W10, W10 ^ W14);
            W10 = EXPAND(W10, W01, W07, W13, W04);
            R1(B, C, D, A, F, G, H, E, 0x6228CBCE, W11, W11 ^ W15);
            W11 = EXPAND(W11, W02, W08, W14, W05);
            R1(A, B, C, D, E, F, G, H, 0xC451979C, W12, W12 ^ W00);
            W12 = EXPAND(W12, W03, W09, W15, W06);
            R1(D, A, B, C, H, E, F, G, 0x88A32F39, W13, W13 ^ W01);
            W13 = EXPAND(W13, W04, W10, W00, W07);
            R1(C, D, A, B, G, H, E, F, 0x11465E73, W14, W14 ^ W02);
            W14 = EXPAND(W14, W05, W11, W01, W08);
            R1(B, C, D, A, F, G, H, E, 0x228CBCE6, W15, W15 ^ W03);
            W15 = EXPAND(W15, W06, W12, W02, W09);
            R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W00, W00 ^ W04);
            W00 = EXPAND(W00, W07, W13, W03, W10);
            R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W01, W01 ^ W05);
            W01 = EXPAND(W01, W08, W14, W04, W11);
            R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W02, W02 ^ W06);
            W02 = EXPAND(W02, W09, W15, W05, W12);
            R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W03, W03 ^ W07);
            W03 = EXPAND(W03, W10, W00, W06, W13);
            R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W04, W04 ^ W08);
            W04 = EXPAND(W04, W11, W01, W07, W14);
            R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W05, W05 ^ W09);
            W05 = EXPAND(W05, W12, W02, W08, W15);
            R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W06, W06 ^ W10);
            W06 = EXPAND(W06, W13, W03, W09, W00);
            R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W07, W07 ^ W11);
            W07 = EXPAND(W07, W14, W04, W10, W01);
            R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W08, W08 ^ W12);
            W08 = EXPAND(W08, W15, W05, W11, W02);
            R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W09, W09 ^ W13);
            W09 = EXPAND(W09, W00, W06, W12, W03);
            R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W10, W10 ^ W14);
            W10 = EXPAND(W10, W01, W07, W13, W04);
            R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W11, W11 ^ W15);
            W11 = EXPAND(W11, W02, W08, W14, W05);
            R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W12, W12 ^ W00);
            W12 = EXPAND(W12, W03, W09, W15, W06);
            R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W13, W13 ^ W01);
            W13 = EXPAND(W13, W04, W10, W00, W07);
            R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W14, W14 ^ W02);
            W14 = EXPAND(W14, W05, W11, W01, W08);
            R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W15, W15 ^ W03);
            W15 = EXPAND(W15, W06, W12, W02, W09);
            R2(A, B, C, D, E, F, G, H, 0x7A879D8A, W00, W00 ^ W04);
            W00 = EXPAND(W00, W07, W13, W03, W10);
            R2(D, A, B, C, H, E, F, G, 0xF50F3B14, W01, W01 ^ W05);
            W01 = EXPAND(W01, W08, W14, W04, W11);
            R2(C, D, A, B, G, H, E, F, 0xEA1E7629, W02, W02 ^ W06);
            W02 = EXPAND(W02, W09, W15, W05, W12);
            R2(B, C, D, A, F, G, H, E, 0xD43CEC53, W03, W03 ^ W07);
            W03 = EXPAND(W03, W10, W00, W06, W13);
            R2(A, B, C, D, E, F, G, H, 0xA879D8A7, W04, W04 ^ W08);
            W04 = EXPAND(W04, W11, W01, W07, W14);
            R2(D, A, B, C, H, E, F, G, 0x50F3B14F, W05, W05 ^ W09);
            W05 = EXPAND(W05, W12, W02, W08, W15);
            R2(C, D, A, B, G, H, E, F, 0xA1E7629E, W06, W06 ^ W10);
            W06 = EXPAND(W06, W13, W03, W09, W00);
            R2(B, C, D, A, F, G, H, E, 0x43CEC53D, W07, W07 ^ W11);
            W07 = EXPAND(W07, W14, W04, W10, W01);
            R2(A, B, C, D, E, F, G, H, 0x879D8A7A, W08, W08 ^ W12);
            W08 = EXPAND(W08, W15, W05, W11, W02);
            R2(D, A, B, C, H, E, F, G, 0x0F3B14F5, W09, W09 ^ W13);
            W09 = EXPAND(W09, W00, W06, W12, W03);
            R2(C, D, A, B, G, H, E, F, 0x1E7629EA, W10, W10 ^ W14);
            W10 = EXPAND(W10, W01, W07, W13, W04);
            R2(B, C, D, A, F, G, H, E, 0x3CEC53D4, W11, W11 ^ W15);
            W11 = EXPAND(W11, W02, W08, W14, W05);
            R2(A, B, C, D, E, F, G, H, 0x79D8A7A8, W12, W12 ^ W00);
            W12 = EXPAND(W12, W03, W09, W15, W06);
            R2(D, A, B, C, H, E, F, G, 0xF3B14F50, W13, W13 ^ W01);
            W13 = EXPAND(W13, W04, W10, W00, W07);
            R2(C, D, A, B, G, H, E, F, 0xE7629EA1, W14, W14 ^ W02);
            W14 = EXPAND(W14, W05, W11, W01, W08);
            R2(B, C, D, A, F, G, H, E, 0xCEC53D43, W15, W15 ^ W03);
            W15 = EXPAND(W15, W06, W12, W02, W09);
            R2(A, B, C, D, E, F, G, H, 0x9D8A7A87, W00, W00 ^ W04);
            W00 = EXPAND(W00, W07, W13, W03, W10);
            R2(D, A, B, C, H, E, F, G, 0x3B14F50F, W01, W01 ^ W05);
            W01 = EXPAND(W01, W08, W14, W04, W11);
            R2(C, D, A, B, G, H, E, F, 0x7629EA1E, W02, W02 ^ W06);
            W02 = EXPAND(W02, W09, W15, W05, W12);
            R2(B, C, D, A, F, G, H, E, 0xEC53D43C, W03, W03 ^ W07);
            W03 = EXPAND(W03, W10, W00, W06, W13);
            R2(A, B, C, D, E, F, G, H, 0xD8A7A879, W04, W04 ^ W08);
            R2(D, A, B, C, H, E, F, G, 0xB14F50F3, W05, W05 ^ W09);
            R2(C, D, A, B, G, H, E, F, 0x629EA1E7, W06, W06 ^ W10);
            R2(B, C, D, A, F, G, H, E, 0xC53D43CE, W07, W07 ^ W11);
            R2(A, B, C, D, E, F, G, H, 0x8A7A879D, W08, W08 ^ W12);
            R2(D, A, B, C, H, E, F, G, 0x14F50F3B, W09, W09 ^ W13);
            R2(C, D, A, B, G, H, E, F, 0x29EA1E76, W10, W10 ^ W14);
            R2(B, C, D, A, F, G, H, E, 0x53D43CEC, W11, W11 ^ W15);
            R2(A, B, C, D, E, F, G, H, 0xA7A879D8, W12, W12 ^ W00);
            R2(D, A, B, C, H, E, F, G, 0x4F50F3B1, W13, W13 ^ W01);
            R2(C, D, A, B, G, H, E, F, 0x9EA1E762, W14, W14 ^ W02);
            R2(B, C, D, A, F, G, H, E, 0x3D43CEC5, W15, W15 ^ W03);
    
            ctx->A ^= A;
            ctx->B ^= B;
            ctx->C ^= C;
            ctx->D ^= D;
            ctx->E ^= E;
            ctx->F ^= F;
            ctx->G ^= G;
            ctx->H ^= H;
        }
    }
    

    修改md32_common.h

    删除头文件# include <openssl/crypto.h>

    删除代码中全部的OPENSSL_cleanse();

    *解释:经查阅openssl代码中的OPENSSL_cleanse函数声明,此函数作用等同与标准C中的memset(p,0,size)功能,是将参数一内存清0,本文件中调用该函数的地方,其参数1均为栈空间,函数结束后将自动回收,因此没必要手动清0,因此该函数可以不调用,若不放心,可以用memset函数替代。

    修改或删除后的文件如下:

    #if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
    # error "DATA_ORDER must be defined!"
    #endif
    
    #ifndef HASH_CBLOCK
    # error "HASH_CBLOCK must be defined!"
    #endif
    #ifndef HASH_LONG
    # error "HASH_LONG must be defined!"
    #endif
    #ifndef HASH_CTX
    # error "HASH_CTX must be defined!"
    #endif
    
    #ifndef HASH_UPDATE
    # error "HASH_UPDATE must be defined!"
    #endif
    #ifndef HASH_TRANSFORM
    # error "HASH_TRANSFORM must be defined!"
    #endif
    #ifndef HASH_FINAL
    # error "HASH_FINAL must be defined!"
    #endif
    
    #ifndef HASH_BLOCK_DATA_ORDER
    # error "HASH_BLOCK_DATA_ORDER must be defined!"
    #endif
    
    #define ROTATE(a,n)     (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
    
    #if defined(DATA_ORDER_IS_BIG_ENDIAN)
    
    # define HOST_c2l(c,l)  (l =(((unsigned long)(*((c)++)))<<24),          \
                             l|=(((unsigned long)(*((c)++)))<<16),          \
                             l|=(((unsigned long)(*((c)++)))<< 8),          \
                             l|=(((unsigned long)(*((c)++)))    )           )
    # define HOST_l2c(l,c)  (*((c)++)=(unsigned char)(((l)>>24)&0xff),      \
                             *((c)++)=(unsigned char)(((l)>>16)&0xff),      \
                             *((c)++)=(unsigned char)(((l)>> 8)&0xff),      \
                             *((c)++)=(unsigned char)(((l)    )&0xff),      \
                             l)
    
    #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
    
    # define HOST_c2l(c,l)  (l =(((unsigned long)(*((c)++)))    ),          \
                             l|=(((unsigned long)(*((c)++)))<< 8),          \
                             l|=(((unsigned long)(*((c)++)))<<16),          \
                             l|=(((unsigned long)(*((c)++)))<<24)           )
    # define HOST_l2c(l,c)  (*((c)++)=(unsigned char)(((l)    )&0xff),      \
                             *((c)++)=(unsigned char)(((l)>> 8)&0xff),      \
                             *((c)++)=(unsigned char)(((l)>>16)&0xff),      \
                             *((c)++)=(unsigned char)(((l)>>24)&0xff),      \
                             l)
    
    #endif
    
    /*
     * Time for some action :-)
     */
    
    int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len)
    {
        const unsigned char *data = data_;
        unsigned char *p;
        HASH_LONG l;
        size_t n;
    
        if (len == 0)
            return 1;
    
        l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL;
        if (l < c->Nl)              /* overflow */
            c->Nh++;
        c->Nh += (HASH_LONG) (len >> 29); /* might cause compiler warning on
                                           * 16-bit */
        c->Nl = l;
    
        n = c->num;
        if (n != 0) {
            p = (unsigned char *)c->data;
    
            if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) {
                memcpy(p + n, data, HASH_CBLOCK - n);
                HASH_BLOCK_DATA_ORDER(c, p, 1);
                n = HASH_CBLOCK - n;
                data += n;
                len -= n;
                c->num = 0;
                /*
                 * We use memset rather than OPENSSL_cleanse() here deliberately.
                 * Using OPENSSL_cleanse() here could be a performance issue. It
                 * will get properly cleansed on finalisation so this isn't a
                 * security problem.
                 */
                memset(p, 0, HASH_CBLOCK); /* keep it zeroed */
            } else {
                memcpy(p + n, data, len);
                c->num += (unsigned int)len;
                return 1;
            }
        }
    
        n = len / HASH_CBLOCK;
        if (n > 0) {
            HASH_BLOCK_DATA_ORDER(c, data, n);
            n *= HASH_CBLOCK;
            data += n;
            len -= n;
        }
    
        if (len != 0) {
            p = (unsigned char *)c->data;
            c->num = (unsigned int)len;
            memcpy(p, data, len);
        }
        return 1;
    }
    
    void HASH_TRANSFORM(HASH_CTX *c, const unsigned char *data)
    {
        HASH_BLOCK_DATA_ORDER(c, data, 1);
    }
    
    int HASH_FINAL(unsigned char *md, HASH_CTX *c)
    {
        unsigned char *p = (unsigned char *)c->data;
        size_t n = c->num;
    
        p[n] = 0x80;                /* there is always room for one */
        n++;
    
        if (n > (HASH_CBLOCK - 8)) {
            memset(p + n, 0, HASH_CBLOCK - n);
            n = 0;
            HASH_BLOCK_DATA_ORDER(c, p, 1);
        }
        memset(p + n, 0, HASH_CBLOCK - 8 - n);
    
        p += HASH_CBLOCK - 8;
    #if   defined(DATA_ORDER_IS_BIG_ENDIAN)
        (void)HOST_l2c(c->Nh, p);
        (void)HOST_l2c(c->Nl, p);
    #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
        (void)HOST_l2c(c->Nl, p);
        (void)HOST_l2c(c->Nh, p);
    #endif
        p -= HASH_CBLOCK;
        HASH_BLOCK_DATA_ORDER(c, p, 1);
        c->num = 0;
    
    #ifndef HASH_MAKE_STRING
    # error "HASH_MAKE_STRING must be defined!"
    #else
        HASH_MAKE_STRING(c, md);
    #endif
    
        return 1;
    }
    
    #ifndef MD32_REG_T
    # if defined(__alpha) || defined(__sparcv9) || defined(__mips)
    #  define MD32_REG_T long
    /*
     * This comment was originally written for MD5, which is why it
     * discusses A-D. But it basically applies to all 32-bit digests,
     * which is why it was moved to common header file.
     *
     * In case you wonder why A-D are declared as long and not
     * as MD5_LONG. Doing so results in slight performance
     * boost on LP64 architectures. The catch is we don't
     * really care if 32 MSBs of a 64-bit register get polluted
     * with eventual overflows as we *save* only 32 LSBs in
     * *either* case. Now declaring 'em long excuses the compiler
     * from keeping 32 MSBs zeroed resulting in 13% performance
     * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
     * Well, to be honest it should say that this *prevents*
     * performance degradation.
     */
    # else
    /*
     * Above is not absolute and there are LP64 compilers that
     * generate better code if MD32_REG_T is defined int. The above
     * pre-processor condition reflects the circumstances under which
     * the conclusion was made and is subject to further extension.
     */
    #  define MD32_REG_T int
    # endif
    #endif
    
    

    五、编译运行

    将sm3.h,sm3.c,sm3_local.h,md32_common.h文件,配置添加到VS工程中。

    编译运行,输出sm3结果如下:

    77-01-58-16-14-3e-e6-27-f4-fa-41-0b-6d-ad-2b-db-9f-cb-df-1e-06-1a-45-2a-68-6b-87-11-a4-84-c5-d7
    

    上述算法,适用于计算字符串、缓冲区的SM3值。至于小文件、大文件的SM3如何计算,可以参考本人的另外两篇关于MD5的博客,与SM3非常相似。

    小文件MD5计算

    大文件MD5计算

    欢迎大家关注、留言讨论、可分享源码

    展开全文
  • SM2/SM3算法C语言实现

    2018-06-06 20:07:24
    1、完整的SM2/SM3算法C语言实现,可用于扫码POS安全认证; 2、SM2加密/解密、SM2签名/验签 3、内含测试程序,在Linux环境下进入目录后make即可编译,已经在ubuntu16.04环境下编译测试OK; 4、已经在银行卡检测中心...
  • SM3算法C语言源码

    2017-01-09 11:52:55
    国家密码管理局的SM3算法标准的C语言源码,此代码的计算结果经过国家密码管理局商用密码检测中心的测试,代码简洁,易用性强。
  • SM3算法及HMAC<SM3>算法C语言实现。内附详细测试例程。 SM3测试数据取自 GMT 0004-2012 HMAC测试数据来自Crypto++ 源文件列表: test.cpp sm3.cpp sm3.h 包含测试工程: VC++6.0, VC++2008, VC++2013, CentOS7-x64+...
  • SM3算法C语言实现

    热门讨论 2011-11-03 15:43:54
    按国密标准开发的C语言版(VC6)的SM3算法源代码 参考xyssl源码库实现 计算结果与标准测试数据完全相同 附带有SM3-HMAC算法
  • SM3密码算法c语言实现

    2019-03-17 14:27:30
    本文件内含sm3国家密码算法设计总则,对sm3进行C语言实现,在Windows环境下可编程实现,包括源代码,内容详细,简单易懂。
  • SM3密码杂凑算法C语言实现

    千次阅读 2018-11-27 15:00:14
    SM3密码杂凑算法C语言实现 信息安全综合实验的一个作业,要求使用miracl库。但实际上,sm3的绝大部分操作都是在32位的字上的,没有任何必要使用这个库,并且由于它对很多操作都不支持,实际上是加大了編程的难度。就...

    SM3密码杂凑算法C语言实现

    信息安全综合实验的一个作业,要求使用miracl库。但实际上,sm3的绝大部分操作都是在32位的字上的,没有任何必要使用这个库,并且由于它对很多操作都不支持,实际上是加大了編程的难度。就当是练手了- -

    #include<stdio.h>
    #include"miracl.h"
    #include<string.h>
    #define AND 0
    #define OR 3
    #define XOR 2
    #define PLUS 1
    #define MAXN 100
    
    int fill(big m, int l)
    //消息填充
    {
    	//填充1到末尾
    	sftbit(m, 1, m);
            add(m, mirvar(1), m);
    	//填充k个0
    	int k = ((447-l)%512+512)%512;
    	sftbit(m, k, m);
    	//填充64位比特串
    	sftbit(m, 64 ,m);
    	add(m, mirvar(l), m);
    	return (l+k+65)/512;
    }
    
    void leftshift(big a, int len, big ans)
    //32位的a 循环左移len位
    {
    	len %= 32;
    	big x = mirvar(0);
    	big b = mirvar(0);
    	expb2(32-len, x);
    	copy(a, ans);
    	divide(ans, x, b);
    	sftbit(ans, len, ans);
    	add(ans, b, ans);
    }
    
    void inverse(big x, big ans)
    //对32位的x进行取反位操作
    {
    	char xb[4];
    	big_to_bytes(4, x, xb, TRUE);
    	for (int i=0;i<4;i++)
    		xb[i] = ~xb[i];
    	bytes_to_big(4, xb, ans);
    }
    
    void operation(big a, big b, int op, big ans)
    //对32位的a和b进行操作
    {
    	if (op == PLUS)
    	{
    		big x = mirvar(0);expb2(32, x);
    		add(a, b, ans);
    		divide(ans, x, x);
    		return;
    	}
    	char ab[4], bb[4];
            big_to_bytes(4, a, ab, TRUE);
            big_to_bytes(4, b, bb, TRUE);
    	switch(op){
    		case XOR:for (int i=0;i<4;i++) ab[i] = ab[i] ^ bb[i];break;
    		case AND:for (int i=0;i<4;i++) ab[i] = ab[i] & bb[i];break;
    		case OR:for (int i=0;i<4;i++) ab[i] = ab[i] | bb[i];break;
    	}
            bytes_to_big(4, ab, ans);
    }
    
    void P(int k, big x, big ans)
    /*置换函数
    P0(X) = X xor (X <<< 9) xor (X<<<17)
    P1(X) = X xor (X <<< 15) xor (X<<<23)*/
    {
    	big a = mirvar(0);
    	big b = mirvar(0);
    	copy(x, a);
    	copy(x, b);
    	if (k == 1)
    	{
    		leftshift(a, 15, a);
    		leftshift(b, 23, b);
    	}
    	else{
    		leftshift(a, 9, a);
    		leftshift(b, 17, b);
    	}
    	operation(x, a, XOR, ans);
    	operation(ans, b, XOR, ans);
    }
    
    void T(int j, big x)
    {
    	if (0<=j && j<=15)
    		cinstr(x, "79cc4519");
    	else if (16<=j && j<=63)
    		cinstr(x, "7a879d8a");
    }
    
    void expand(big B, big W[], big Wap[])
    //填充
    {
    	big t[2];
    	t[0] = mirvar(0);copy(B, t[0]);
    	t[1] = mirvar(0);
    	big x = mirvar(0);expb2(32, x);
    	int l = 0;
    
    	for (int i=15;i>=0;i--)
    	{
    		divide(t[l], x, t[1-l]);
    		W[i] = mirvar(0);
    		copy(t[l],W[i]);
    		l=1-l;
    	}
    	//Wj = P1(W[j−16] xor W[j−9] xor (W[j−3]<<<15)) xor (W[j−13]<<<7) xor W[j−6]
    	for (int i=16;i<=67;i++)
    	{
    		W[i] = mirvar(0);
    		operation(W[i-16],W[i-9], XOR, W[i]);
    		big t = mirvar(0);
    		leftshift(W[i-3], 15, t);
    		operation(W[i], t, XOR, W[i]);
    		P(1, W[i], W[i]);
    		leftshift(W[i-13], 7, t);
    		operation(W[i], t, XOR, W[i]);
    		operation(W[i], W[i-6], XOR, W[i]);
    	}
    	for (int i=0;i<=63;i++)
    	{
    		Wap[i] = mirvar(0);
    		operation(W[i], W[i+4], XOR, Wap[i]);
    	}
    }
    
    void FF(int j, big X, big Y, big Z, big ans)
    {
    	if (0<=j && j<=15)
    	{
    		operation(X, Y, XOR, ans);
    		operation(ans, Z, XOR, ans);
    	}
    	else if (16<=j && j<=63)
    	{
    		//(X and Y ) or (X and Z) or (Y and Z )
    		big t = mirvar(0);
    		operation(X, Y, AND, ans);
    		operation(X, Z, AND, t);
    		operation(ans, t, OR, ans);
    		operation(Y, Z, AND, t);
    		operation(ans, t, OR, ans);
    	}
    }
    
    void GG(int j, big X, big Y, big Z, big ans)
    {
    	if (0<=j && j<=15)
            {
                    operation(X, Y, XOR, ans);
                    operation(ans, Z, XOR, ans);
            }
            else if (16<=j && j<=63)
            {
    		//(X and Y) or (not X and Z)
                    big t = mirvar(0);
                    operation(X, Y, AND, ans);
    		inverse(X, t);
    		operation(t, Z, AND, t);
    		operation(ans, t, OR, ans);
            }
    }
    
    void print(big V[])
    {
    	char s[10];
    	for (int i=0;i<8;i++)
    	{
    		cotstr(V[i], s);
    		for(int j=0;j<8-strlen(s);j++) 
    			putchar('0');
    		printf("%s", s);
    		if (i==7) putchar('\n');
    		else putchar(' ');
    	}
    }
    
    void compress(big W[], big Wap[], big V[])
    //压缩
    {
    	big SS1,SS2,TT1,TT2,t;
    	SS1 = mirvar(0);SS2 = mirvar(0);
    	TT1 = mirvar(0);TT2 = mirvar(0);
    	t = mirvar(0);
    	big A,B,C,D,E,F,G,H;
    	A = mirvar(0);copy(V[0], A);B = mirvar(0);copy(V[1], B);
    	C = mirvar(0);copy(V[2], C);D = mirvar(0);copy(V[3], D);
    	E = mirvar(0);copy(V[4], E);F = mirvar(0);copy(V[5], F);
            G = mirvar(0);copy(V[6], G);H = mirvar(0);copy(V[7], H);
    
    	for (int i=0;i<=63;i++)
    	{
    		//SS1 = ((A<<<12) + E + (Tj<<<j))<<<7
    		leftshift(A, 12, SS1);
    		operation(SS1, E, PLUS, SS1);
    		T(i, t);
    		leftshift(t, i, t);
    		operation(SS1, t, PLUS, SS1);
    		leftshift(SS1, 7, SS1);	
    		//SS2 = SS1 xor (A<<<12)
    		leftshift(A, 12, SS2);
    		operation(SS1, SS2, XOR, SS2);
    		//TT1 = FFj(A,B,C) + D + SS2 +Wj′
    		FF(i, A, B, C, TT1);
    		operation(TT1, D, PLUS, TT1);
    		operation(TT1, SS2, PLUS, TT1);
    		operation(TT1, Wap[i], PLUS, TT1);
    		//TT2 = GGj(E, F, G) + H + SS1 +Wj
    		GG(i, E, F, G, TT2);
    		operation(TT2, H, PLUS, TT2);
    		operation(TT2, SS1, PLUS, TT2);
    		operation(TT2, W[i], PLUS, TT2);
    		//D=C; C=B<<<9; B=A; A=TT1; H=G; G=F<<<19; F=E; E=P0(TT2)
    		copy(C,D);
    		leftshift(B, 9, C);
    		copy(A, B);
    		copy(TT1, A);
    		copy(G, H);
    		leftshift(F, 19, G);
    		copy(E, F);
    		P(0, TT2, E);
    		//printf("%2d: ", i);
    		//print(A,B,C,D,E,F,G,H);
    	}
    	//V[i+1] = ABCDEFGH xor V[i]
    	operation(A, V[0], XOR, V[0]);operation(B, V[1], XOR, V[1]);
    	operation(C, V[2], XOR, V[2]);operation(D, V[3], XOR, V[3]);
    	operation(E, V[4], XOR, V[4]);operation(F, V[5], XOR, V[5]);
            operation(G, V[6], XOR, V[6]);operation(H, V[7], XOR, V[7]);
    }
    
    void iteration(big m, int n, big V[])
    //迭代
    {
    	big Bi[10], t[2], W[68], Wap[64];
            t[0] = mirvar(0);copy(m, t[0]);
    	t[1] = mirvar(0);
            int l = 0;
    	big x = mirvar(0);expb2(512, x);
    
            for (int i=n-1;i>=0;i--)
            {
                    divide(t[l], x, t[1-l]);
                    Bi[i] = mirvar(0);
                    copy(t[l],Bi[i]);
                    l=1-l;
            }
    	
    	for (int i=0;i<n;i++)
    	{
    		expand(Bi[i], W, Wap);
    		compress(W, Wap, V);	
    	}
    }
    
    int main()
    {
    	//读入
    	miracl *mip = mirsys(512*MAXN, 10);
          	mip->IOBASE = 16;	
    	char s[64*MAXN];
    	scanf("%s", s);
    	int l = strlen(s);
    	big m = mirvar(0);
    	for (int i=0;i<l;i++)
    	{
    		sftbit(m, 8, m);
    		add(m, mirvar(s[i]), m);
    	}
    	//填充
    	l *= 8;
    	int n = fill(m,l);
    	//迭代压缩
    	big V[8];
    	for (int i=0;i<8;i++)
    		V[i] = mirvar(0);
    	cinstr(V[0], "7380166f"); cinstr(V[1], "4914b2b9"); cinstr(V[2], "172442d7");
    	cinstr(V[3], "da8a0600"); cinstr(V[4], "a96f30bc"); cinstr(V[5], "163138aa");
    	cinstr(V[6], "e38dee4d"); cinstr(V[7], "b0fb0e4e");
    	iteration(m, n, V);
    	
    	print(V);
    	return 0;
    }
    
    
    

    程序运行结果
    结果与sm3文档给出的一致。

    展开全文
  • SM2SM3SM4国密算法C语言实现VS2015 还包含以下文本档可以学习 SM2椭圆曲线公钥密码算法 SM2椭圆曲线公钥密码算法推荐曲线参数 SM3密码杂凑算法 SM4分组密码算法
  • 基于Miracl大数运算库实现SM2算法,包含加密和签名算法,纯C语言实现,包含Miracl库手册。提供了Linux平台下的Makefile文件,可直接运行。Windows平台需要重新建立项目工程。
  • SM3国密加密算法(C语言)

    千次阅读 2021-01-23 20:37:01
    SM3算法是公开的。实现原理如下图所示: C代码展示: 完整代码见github:https://github.com/CMwshuai/Algorithm.git 1、初始值IV static const unsigned int IV[8] = { 0x7380166F, 0x4914B2B9, 0x...

    SM3是国产哈希算法,在商用密码体系中,主要用于数字签名及验证、消息认证码生成及验证、随机数生成等。对于用户需要加密的数据在加密后会生成一个固定长度(32字节)的哈希值。SM3算法是公开的。实现原理如下图所示:

    C代码展示:

    完整代码见github:https://github.com/CMwshuai/Algorithm.git

    1、初始值IV

    static const unsigned int IV[8] =
    {
    	0x7380166F,	0x4914B2B9,
    	0x172442D7,	0xDA8A0600,
    	0xA96F30BC,	0x163138AA,
    	0xE38DEE4D,	0xB0FB0E4E,
    };
    

    2、常量初始化T

    static void _init_T()
    {
    	int i = 0;
    	for (; i < 16; i++)
    		T[i] = 0x79CC4519;
    	for (; i < 64; i++)
    		T[i] = 0x7A879D8A;
    }
    

    3、 布尔函数_FF,_GG

    static unsigned int _FF(
                const unsigned int X,
                const unsigned int Y,
                const unsigned int Z,
                const unsigned int j)
    {
    	if (0 <= j && j < 16)
    		return (X ^ Y ^ Z);
    	else if (16 <= j && j < 64)
    		return ((X & Y) | (X & Z) | (Y & Z));
    
    	return 0;
    }
    
    static unsigned int _GG(
            const unsigned int X, 
            const unsigned int Y, 
            const unsigned int Z, 
            const unsigned int j)
    {
    	if (0 <= j && j < 16)
    		return (X ^ Y ^ Z);
    	else if (16 <= j && j < 64)
    		return ((X & Y) | ((~X) & Z));
    
    	return 0;
    }
    

    4、置换函数_P0,_P1

    static unsigned int _P0(const unsigned int X)
    {
    	return (X ^ (_rotate_left_move(X, 9)) ^ (_rotate_left_move(X, 17)));
    }
    
    static unsigned int _P1(const unsigned int X)
    {
    	return (X ^ (_rotate_left_move(X, 15)) ^ (_rotate_left_move(X, 23)));
    }
    

     5、消息填充

    unsigned int nGroupNum = (nSrcLen + 1 + 8 + 64) / 64;
    unsigned char *ucpMsgBuf = (unsigned char*)malloc(nGroupNum * 64);
    memset(ucpMsgBuf, 0, nGroupNum * 64);
    memcpy(ucpMsgBuf, ucpSrcData, nSrcLen);
    ucpMsgBuf[nSrcLen] = 0x80;
    
    int i = 0;
    for (i = 0; i < 8; i++)
    {
    	ucpMsgBuf[nGroupNum * 64 - i - 1] = ((unsigned long long)(nSrcLen * 8) >> (i * 8)) & 0xFF;
    }

     6、迭代压缩

    static unsigned int _CF(unsigned char* ucpSrcMsg, unsigned int nHash[8])
    {
    	unsigned int W68[68] = { 0 };
    	unsigned int W64[64] = { 0 };
    
    	//message extension
    	int j = 0;
    	for (j = 0; j < 16; j++)
    	{
    		W68[j] = ((unsigned int)ucpSrcMsg[j * 4 + 0] << 24) & 0xFF000000
    			| ((unsigned int)ucpSrcMsg[j * 4 + 1] << 16) & 0x00FF0000
    			| ((unsigned int)ucpSrcMsg[j * 4 + 2] << 8) & 0x0000FF00
    			| ((unsigned int)ucpSrcMsg[j * 4 + 3] << 0) & 0x000000FF;
    	}
    
    	for (j = 16; j < 68; j++)
    	{
    		W68[j] = _P1(W68[j - 16] ^ W68[j - 9] ^ (_rotate_left_move(W68[j - 3], 15))) ^ (_rotate_left_move(W68[j - 13], 7)) ^ W68[j - 6];
    	}
    
    	for (j = 0; j < 64; j++)
    	{
    		W64[j] = W68[j] ^ W68[j + 4];
    	}
    	
    	//iterative process
    	unsigned int A_G[8] = { 0 };
    	for (j = 0; j < 8; j++)
    	{
    		A_G[j] = nHash[j];
    	}
    
    	//tempporary variable
    	unsigned int SS1 = 0, SS2 = 0, TT1 = 0, TT2 = 0;
    
    	for (j = 0; j < 64; j++)
    	{
    		SS1 = _rotate_left_move((_rotate_left_move(A_G[A], 12) + A_G[E] + _rotate_left_move(T[j], j % 32)), 7);
    		SS2 = SS1 ^ (_rotate_left_move(A_G[A], 12));
    		TT1 = _FF(A_G[A], A_G[B], A_G[C], j) + A_G[D] + SS2 + W64[j];
    		TT2 = _GG(A_G[E], A_G[F], A_G[G], j) + A_G[H] + SS1 + W68[j];
    		A_G[D] = A_G[C];
    		A_G[C] = _rotate_left_move(A_G[B], 9);
    		A_G[B] = A_G[A];
    		A_G[A] = TT1;
    		A_G[H] = A_G[G];
    		A_G[G] = _rotate_left_move(A_G[F], 19);
    		A_G[F] = A_G[E];
    		A_G[E] = _P0(TT2);
    	}
    
    	for (j = 0; j < 8; j++)
    	{
    		nHash[j] = A_G[j] ^ nHash[j];
    	}
    
    	return 0;
    }
    

     

    展开全文
  • SM3密码算法C语言实现

    2017-10-10 15:21:59
    亲测好用,做了一定的封装。里面还包含一些spec。我也是从网上下载的根据自己的需求改了一下。
  • 按照国密文档通过C语言实现SM2密码算法加密/解密、签名/验签,SM3密码杂凑算法SM4分组密码算法ECB、CBC模式加密/解密。 经过国密标准中数据验证无误。若有问题请及时反馈,期待和大家进行交流学习。 附带国密规范...
  • SM4国密加密算法C语言实现 包括 Spec,C代码,测试用例和分组密码有五种工作体制:1.电码本模式(Electronic Codebook Book (ECB));2.密码分组链接模式(Cipher Block Chaining (CBC));3.计算器模式(Counter ...
  • C语言实现国密SM4对称加解密算法。编译环境:VS2010。请参考我的博客https://blog.csdn.net/u013073067/article/details/86578753 分析代码
  • SM3算法的编程实现

    千次阅读 2021-06-19 21:04:51
    SM3算法的编程实现SM3算法的编程实现【实验目的】【实验环境】【实验预备知识点】【实验步骤】【实验思考题】 SM3算法的编程实现 【实验目的】 1、理解Hash函数的计算原理和特点; 2、理解SM3算法原理; 3、了解SM3...
  • 国密SM2密码算法C语言实现

    千次阅读 2021-05-24 07:48:26
    SM2椭圆曲线密码算法是国家密码管理局批准的...本文介绍了SM2椭圆曲线公钥密码算法和加密解密算法中一部分过程的C语言实现。【关键词】 椭圆曲线 SM2 密码算法 公钥 加密解密Implementation of Public Key Cryptogr...
  • SM3杂凑算法是我国自主设计的密码杂凑算法 SM3是中华人民共和国政府采用的一种密码散列函数标准,由国家密码管理局于2010年12月17日发布。相关标准为“GM/T 0004-2012 《SM3密码杂凑算法》”。 在商用密码体系中...
  • 一、SM3算法介绍 杂凑值算法也可称为摘要算法或者哈希算法。通过对数据资料的填充、分组、扩展压缩等方式计算成特定长度的数值,来作为数据指纹或者数据特征使用。常见的MD5算法长度为128bit(16字节),SHA1算法...
  • C语言实现SM3

    千次阅读 2020-05-28 22:58:27
    C语言实现SM3,源码已上传至github
  • 当前位置:我的异常网» C++»求 国密sm2 算法 第四部分 公钥加密算法 c语言实现求 国密sm2 算法 第四部分 公钥加密算法 c语言实现代码,该怎么解决www.myexceptions.net网友分享于:2014-07-26浏览:0次求 国密sm2 ...
  • 国密算法SM2算法 C语言源码 签名验签 加解密, 密钥交换
  • 按照国密文档通过C语言实现SM2密码算法加密/解密、签名/验签,SM3密码杂凑算法SM4分组密码算法ECB、CBC模式加密/解密。 经过详尽的测试目前未发现问题,并附有国密标准中数据检测结果。若有问题请及时反馈,期待和...
  • SM4算法 C语言 (从OpenSSL库中分离算法:七) OpenSSL简介: OpenSSL 是用于传输层安全性 (TLS) 和安全套接字层 (SSL) 协议的一个强大、商业级和功能齐全的工具包,它也是一个通用的密码学库。包含有RSA、SM4、DES、...
  • sm3算法

    千次阅读 2017-09-30 09:59:44
    sm3算法c语言实现 /*    2017.9.24 am 10:00 -11:50  2017.9.24 pm 14:00-17:00 19:00-23:00  2017.9.25 pm 14:00-17:30 */ #include #include #include unsigned int w0[70],w1[70];//用于压缩...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,967
精华内容 786
关键字:

sm3算法c语言