国密SM2/SM3算法在单片机平台上的实现(C语言)

最新发现资源文件中sm2.c 654行(KDF函数中)的i++需要删除,现在CSDN付费资源不能修改,请下载的同学自行删除这行,十分抱歉!
     在网上搜过关于SM2/SM3的资源,很少有在单片机上实现的代码。主要是因为大数运算基本都用 Miracl/Openssl库,移植到嵌入式平台上很麻烦。所以索性自己动手写了一下Fp域(质数域)下的SM2算法实现(动态申请内存)。包括SM2算法三步曲——数字签名,秘钥交换和公钥加密,以及SM3哈希杂凑算法的实现。由于SM3算法比较简单,所以本文主要介绍SM2算法。本文所有代码参考国家密码管理局官方文档https://sca.gov.cn/sca/xwdt/2010-12/17/1002386/files/b791a9f908bb4803875ab6aeeb7b4e03.pdf 完整代码点这里。有任何问题可以私信联系。

1. 国密SM2介绍

     SM2是国家密码管理局于2010年12月17日发布的椭圆曲线公钥密码算法。SM2算法和RSA算法都是公钥密码算法,SM2算法是一种更先进安全的算法,在我们国家商用密码体系中被用来替换RSA算法。SM2是ECC(Elliptic Curve Cryptosystem)算法的一种,基于椭圆曲线离散对数问题,计算复杂度是指数级,求解难度较大,同等安全程度要求下,椭圆曲线密码较其他公钥秒速昂发所需密钥长度小很多。
     随着密码技术和计算机技术的发展,目前常用的1024位RSA算法面临严重的安全威胁,我们国家密码管理部门经过研究,决定采用SM2椭圆曲线算法替换RSA算法。

2. SM2数字签名算法

     数字签名算法由一个签名者对数据产生数字签名,并由一个验证者验证签名的可靠性。每个签名者有一个公钥和一个私钥,其中私钥用于产生签名,验证者用签名者的公钥验证签名。在签名的生成过程之前,要用密码杂凑函数对 M ‾ \overline{M} M (包含Z A _A A和待签消息M)进行压缩;在验证过程之前,要用密码杂凑函数对 M ‾ \overline{M} M’(包含Z A _A A和验证消息M′)进行压缩。

2.1 数字签名生成算法流程: 在这里插入图片描述

在这里插入图片描述

1.	SM2Signature* SM2Sign(char* message, int messageSizeInBit, char* IDA, uint16_t ENTLAInBit, EccPoint* G, EccPoint* pubKey, uint64_t* privKey)  
2.	{  
3.	    //ZA = SM3(ENT LA ∥ IDA ∥ a ∥ b ∥ xG ∥ yG ∥ xA ∥ yA)。  
4.	    uint8_t* Z = malloc(2 + ENTLAInBit / 8 + 32 + 32 + 32 + 32 + 32 + 32), * ZA = malloc(32);  
5.	    uint256_t tmpN = { 0 };  
6.	    SM2Signature* result = malloc(sizeof(SM2Signature));  
7.	  
8.	    for (int i = 0; i < 4; i++)  
9.	    {  
10.	        tmpN[i] = ellipticCurve_n[3 - i];  
11.		}
12.	    Z[0] = ENTLAInBit >> 8;  
13.	    Z[1] = ENTLAInBit & 0xff;  
14.	    memcpy(Z + 2, IDA, ENTLAInBit / 8);  
15.	    Uint256ToString(ZA, Ec->a);  
16.	    memcpy(Z + 2 + ENTLAInBit / 8, ZA, 32);  
17.	    Uint256ToString(ZA, Ec->b);  
18.	    memcpy(Z + 2 + ENTLAInBit / 8 + 32, ZA, 32);  
19.	    Uint256ToString(ZA, G->x);  
20.	    memcpy(Z + 2 + ENTLAInBit / 8 + 32 * 2, ZA, 32);  
21.	    Uint256ToString(ZA, G->y);  
22.	    memcpy(Z + 2 + ENTLAInBit / 8 + 32 * 3, ZA, 32);  
23.	    Uint256ToString(ZA, pubKey->x);  
24.	    memcpy(Z + 2 + ENTLAInBit / 8 + 32 * 4, ZA, 32);  
25.	    Uint256ToString(ZA, pubKey->y);  
26.	    memcpy(Z + 2 + ENTLAInBit / 8 + 32 * 5, ZA, 32);  
27.	    SM3(Z, 2 + ENTLAInBit / 8 + 32 + 32 + 32 + 32 + 32 + 32, ZA);//ZA = SM3(ENT LA ∥ IDA ∥ a ∥ b ∥ xG ∥ yG ∥ xA ∥ yA)。  
28.	    free(Z);  
29.	  
30.	    uint8_t* M_ = malloc(messageSizeInBit / 8 + 32), * e = malloc(32);  
31.	    memcpy(M_, ZA, 32);  
32.	    memcpy(M_ + 32, message, messageSizeInBit / 8);  
33.	    SM3(M_, messageSizeInBit / 8 + 32, e);  //e = H256(M_):  
34.	    free(M_);  
35.	  
36.	    uint8_t* x1 = malloc(32), * y1 = malloc(32), * r = malloc(32), * s = malloc(32);  
37.	    uint256_t randomK = { 0 }, tmpE = { 0 }, tmpX = { 0 }, tmpR = { 0 }, num1 = { 1 };  
38.	    EccPoint* point1 = malloc(sizeof(EccPoint));  
39.	    GetRandomNumber(randomK, tmpN);  
40.	#ifdef DEBUG_MODE  
41.	    for (int i = 0; i < 4; i++)  //测试时随机数先固定  
42.	    {  
43.	        randomK[i] = exRandomK[3 - i];  
44.	    }  
45.	#endif  
46.	  
47.	    CurvePointMul(point1, G, randomK);  
48.	    Uint256ToString(x1, point1->x);  
49.	    Uint256ToString(y1, point1->y);  
50.	    free(point1);  
51.	    StringToUint256(tmpE, e);  
52.	    StringToUint256(tmpX, x1);  
53.	    vli_modAdd(tmpR, tmpE, tmpX, tmpN);  
54.	    Uint256ToString(r, tmpR);   //r=(e+x1) modn  
55.	  
56.	    vli_modAdd(tmpE, num1, privKey, tmpN);  
57.	    vli_modInv(tmpX, tmpE, tmpN);   //(1+dA)^-1  
58.	    vli_modMult(tmpE, tmpR, privKey, tmpN);  
59.	    vli_modSub(tmpE, randomK, tmpE, tmpN);  
60.	    vli_modMult(tmpX, tmpX, tmpE, tmpN);  
61.	    Uint256ToString(s, tmpX);   //s = ((1+dA)^-1 * (k - r*dA))modn  
62.	    memcpy(result->r, r, 32);  
63.	    memcpy(result->s, s, 32);  
64.	    free(ZA);  
65.	    free(e);  
66.	    free(x1);  
67.	    free(y1);  
68.	    free(r);  
69.	    free(s);  
70.	  
71.	    return result;  
72.	}  

2.2 数字签名的验证算法及流程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注:如果Z A _A A不是用户A所对应的杂凑值,验证自然通不过。

1.	BOOL SM2SignatureVerify(char* message, int messageSizeInBit, SM2Signature* sign, char* IDA, uint16_t ENTLAInBit, EccPoint* G, EccPoint* pubKey)  
2.	{  
3.	    uint256_t tmp = { 0 }, tmpN = { 0 }, num1 = { 1 };  
4.	  
5.	    for (int i = 0; i < 4; i++)  
6.	    {  
7.	        tmpN[i] = ellipticCurve_n[3 - i];  
8.	    }  
9.	    vli_modSub(tmpN, tmpN, num1, Ec->p); //因为n是大质数必定为奇数,所以这里可以直接n[0] = n[0] - 1,不必像我这样写  
10.	    StringToUint256(tmp, sign->r);  
11.	    if (IsZeroUint256(tmp) || vli_cmp(tmp, tmpN) >= 0)   //make sure r∈[1,n-1]  
12.	    {  
13.	        return FALSE;  
14.	    }  
15.	    StringToUint256(tmp, sign->s);  
16.	    if (IsZeroUint256(tmp) || vli_cmp(tmp, tmpN) >= 0)   //make sure s∈[1,n-1]  
17.	    {  
18.	        return FALSE;  
19.	    }  
20.	    vli_modAdd(tmpN, tmpN, num1, Ec->p);  
21.	  
22.	    //ZA = SM3(ENT LA ∥ IDA ∥ a ∥ b ∥ xG ∥ yG ∥ xA ∥ yA)。  
23.	    uint8_t* Z = malloc(2 + ENTLAInBit / 8 + 32 + 32 + 32 + 32 + 32 + 32), * ZA = malloc(32);  
24.	  
25.	    Z[0] = ENTLAInBit >> 8;  
26.	    Z[1] = ENTLAInBit & 0xff;  
27.	    memcpy(Z + 2, IDA, ENTLAInBit / 8);  
28.	    Uint256ToString(ZA, Ec->a);  
29.	    memcpy(Z + 2 + ENTLAInBit / 8, ZA, 32);  
30.	    Uint256ToString(ZA, Ec->b);  
31.	    memcpy(Z + 2 + ENTLAInBit / 8 + 32, ZA, 32);  
32.	    Uint256ToString(ZA, G->x);  
33.	    memcpy(Z + 2 + ENTLAInBit / 8 + 32 * 2, ZA, 32);  
34.	    Uint256ToString(ZA, G->y);  
35.	    memcpy(Z + 2 + ENTLAInBit / 8 + 32 * 3, ZA, 32);  
36.	    Uint256ToString(ZA, pubKey->x);  
37.	    memcpy(Z + 2 + ENTLAInBit / 8 + 32 * 4, ZA, 32);  
38.	    Uint256ToString(ZA, pubKey->y);  
39.	    memcpy(Z + 2 + ENTLAInBit / 8 + 32 * 5, ZA, 32);  
40.	    SM3(Z, 2 + ENTLAInBit / 8 + 32 + 32 + 32 + 32 + 32 + 32, ZA);//ZA = SM3(ENT LA ∥ IDA ∥ a ∥ b ∥ xG ∥ yG ∥ xA ∥ yA)。  
41.	    free(Z);  
42.	  
43.	    uint8_t* M_ = malloc(messageSizeInBit / 8 + 32), * e = malloc(32);  
44.	    memcpy(M_, ZA, 32);  
45.	    memcpy(M_ + 32, message, messageSizeInBit / 8);  
46.	    SM3(M_, messageSizeInBit / 8 + 32, e);  //e=H256(M_):  
47.	    free(M_);  
48.	  
49.	    uint256_t tmpR = { 0 }, tmpS = { 0 }, tmpT = { 0 };  
50.	  
51.	    StringToUint256(tmpR, sign->r);  
52.	    StringToUint256(tmpS, sign->s);  
53.	    vli_modAdd(tmpT, tmpR, tmpS, tmpN); //t = (r' + s')modn  
54.	  
55.	    EccPoint* point0 = malloc(sizeof(EccPoint)), * point00 = malloc(sizeof(EccPoint)),  
56.	        * point1 = malloc(sizeof(EccPoint));  
57.	  
58.	    CurvePointMul(point0, G, tmpS); //point0 = s' * G  
59.	    CurvePointMul(point00, pubKey, tmpT);   //point00 = t * PA  
60.	    CurvePointAdd(point1, point0, point00); //point1 = s'*G+t*PA  
61.	    free(point0);  
62.	    free(point00);  
63.	  
64.	    uint8_t* r = malloc(32);  
65.	    StringToUint256(tmpT, e);   //只是把e存在tmpT里  
66.	    vli_modAdd(tmpR, tmpT, point1->x, tmpN);  
67.	    Uint256ToString(r, tmpR);  
68.	    free(ZA);  
69.	    free(e);  
70.	    free(point1);  
71.	  
72.	    for (int i = 0; i < 32; i++)  
73.	    {  
74.	        if (r[i] != sign->r[i])  
75.	        {  
76.	            free(r);  
77.	            return FALSE;  
78.	        }  
79.	    }  
80.	    free(r);  
81.	    return TRUE;  
82.	} 

3. 秘钥交换协议

     密钥交换协议是两个用户A和B通过交互的信息传递,用各自的私钥和对方的公钥来商定一个只有他们知道的秘密密钥。这个共享的秘密密钥通常用在某个对称密码算法中。该密钥交换协议能够用于密钥管理和协商。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注:如果Z A _A A、Z B _B B不是用户A和B所对应的杂凑值,则自然不能达成一致的共享秘密值。

1.	BOOL KeyExchangeCheck = TRUE;//可选项,是否要验证S2 == SA以及S1 == SB  
2.	BOOL SM2KeyExchange(char* IDA, uint32_t ENTLAInBit, char* IDB, uint32_t ENTLBInBit, EccPoint* G, int klenInBit)  
3.	{  
4.	    EccPoint* RA = malloc(sizeof(EccPoint)), * V = malloc(sizeof(EccPoint)),  
5.	        * U = malloc(sizeof(EccPoint)),  
6.	        * pubKeyA = malloc(sizeof(EccPoint)), * pubKeyB = malloc(sizeof(EccPoint)),  
7.	        * RB = malloc(sizeof(EccPoint));  
8.	    uint256_t tB = { 0 }, privKeyA = { 0 }, privKeyB = { 0 };  
9.	    uint8_t* tmp = malloc(2 + ENTLAInBit / 8 + 32 * 6), * tmp1 = malloc(32);//用来算ZA ZB  
10.	  
11.	    GenerateKeys(privKeyA, pubKeyA, G);  
12.	    GenerateKeys(privKeyB, pubKeyB, G);  
13.	    if (!(IsValidPoint(pubKeyA, Ec) && IsValidPoint(pubKeyB, Ec)))  
14.	    {  
15.	        return FALSE;  
16.	    }  
17.	  
18.	#ifdef DEBUG_MODE  
19.	    for (int i = 0; i < 4; i++)  //测试固定随机数  
20.	    {  
21.	        privKeyA[i] = exPrivateKey_A[3 - i];  
22.	        privKeyB[i] = exPrivateKey_B[3 - i];  
23.	        pubKeyA->x[i] = exPublicKey_Ax[3 - i];  
24.	        pubKeyA->y[i] = exPublicKey_Ay[3 - i];  
25.	        pubKeyB->x[i] = exPublicKey_Bx[3 - i];  
26.	        pubKeyB->y[i] = exPublicKey_By[3 - i];  
27.	    }  
28.	#endif  
29.	    //双方的原始数据  
30.	    KeyExchangeAOriginalInfoDef infoA =  
31.	    { {0},{0},privKeyA[0],privKeyA[1],privKeyA[2],privKeyA[3],pubKeyA,pubKeyB,0,1,{0},G };  
32.	    KeyExchangeBOriginalInfoDef infoB =  
33.	    { {0},{0},privKeyB[0],privKeyB[1],privKeyB[2],privKeyB[3],pubKeyA,pubKeyB,0,1,{0},G };  
34.	  
35.	    for (int i = 0; i < 4; i++)  
36.	    {  
37.	        infoA.n[i] = ellipticCurve_n[3 - i];  
38.	        infoB.n[i] = ellipticCurve_n[3 - i];  
39.	    }  
40.	    infoA.w = (int)(GetMSB(infoA.n) / 2 + 1) - 1;   //w = [log2(n)/2] - 1   +1是向上取整,大质数取对数必带小数点  
41.	    infoB.w = infoA.w;  
42.	  
43.	    tmp[0] = ENTLAInBit >> 8;  
44.	    tmp[1] = ENTLAInBit & 0xff;  
45.	    memcpy(tmp + 2, IDA, ENTLAInBit / 8);  
46.	    Uint256ToString(tmp1, Ec->a);  
47.	    memcpy(tmp + 2 + ENTLAInBit / 8, tmp1, 32);  
48.	    Uint256ToString(tmp1, Ec->b);  
49.	    memcpy(tmp + 2 + ENTLAInBit / 8 + 32, tmp1, 32);  
50.	    Uint256ToString(tmp1, G->x);  
51.	    memcpy(tmp + 2 + ENTLAInBit / 8 + 32 * 2, tmp1, 32);  
52.	    Uint256ToString(tmp1, G->y);  
53.	    memcpy(tmp + 2 + ENTLAInBit / 8 + 32 * 3, tmp1, 32);  
54.	    Uint256ToString(tmp1, pubKeyA->x);  
55.	    memcpy(tmp + 2 + ENTLAInBit / 8 + 32 * 4, tmp1, 32);  
56.	    Uint256ToString(tmp1, pubKeyA->y);  
57.	    memcpy(tmp + 2 + ENTLAInBit / 8 + 32 * 5, tmp1, 32);  
58.	    SM3(tmp, 2 + ENTLAInBit / 8 + 32 * 6, infoA.ZA);  
59.	    memcpy(infoB.ZA, infoA.ZA, 32);  
60.	  
61.	    tmp[0] = ENTLBInBit >> 8;  
62.	    tmp[1] = ENTLBInBit & 0xff;  
63.	    memcpy(tmp + 2, IDB, ENTLBInBit / 8);  
64.	    Uint256ToString(tmp1, Ec->a);  
65.	    memcpy(tmp + 2 + ENTLBInBit / 8, tmp1, 32);  
66.	    Uint256ToString(tmp1, Ec->b);  
67.	    memcpy(tmp + 2 + ENTLBInBit / 8 + 32, tmp1, 32);  
68.	    Uint256ToString(tmp1, G->x);  
69.	    memcpy(tmp + 2 + ENTLBInBit / 8 + 32 * 2, tmp1, 32);  
70.	    Uint256ToString(tmp1, G->y);  
71.	    memcpy(tmp + 2 + ENTLBInBit / 8 + 32 * 3, tmp1, 32);  
72.	    Uint256ToString(tmp1, pubKeyB->x);  
73.	    memcpy(tmp + 2 + ENTLBInBit / 8 + 32 * 4, tmp1, 32);  
74.	    Uint256ToString(tmp1, pubKeyB->y);  
75.	    memcpy(tmp + 2 + ENTLBInBit / 8 + 32 * 5, tmp1, 32);  
76.	    SM3(tmp, 2 + ENTLBInBit / 8 + 32 * 6, infoB.ZB);  
77.	    memcpy(infoA.ZB, infoB.ZB, 32);  
78.	    free(tmp);  
79.	    free(tmp1);  
80.	  
81.	    uint256_t rA = { 0 };  
82.	    SM2KeyExchange_AStep1To3(RA, rA, infoA);    //A step1~3,generate RA  
83.	  
84.	    SM2KeyExchange_BStep1To4(tB, RB, infoB);    //B step1~4  
85.	    if (!IsValidPoint(RA, Ec))  //B 判断RA是否满足曲线方程  
86.	    {  
87.	        return FALSE;  
88.	    }  
89.	    SM2KeyExchange_BStep5To6(V, tB, RA, infoB); //B step5~6  
90.	    if (IsZeroPoint(V)) //B 判断V是否为(0,0)  
91.	    {  
92.	        return FALSE;  
93.	    }  
94.	  
95.	    uint8_t* SB = malloc(32), * KB = malloc(klenInBit / 8);  
96.	    SM2KeyExchange_BStep7To9(KB, SB, *V, klenInBit, *RA, *RB, infoB);   //B step7~9  
97.	  
98.	    uint256_t tA = { 0 };  
99.	    SM2KeyExchange_AStep4To5(tA, RA, rA, infoA);    //A step4~5  
100.	  
101.	    if (IsZeroPoint(RB))    //A 判断RB是否为(0,0)  
102.	    {  
103.	        return FALSE;  
104.	    }  
105.	  
106.	    SM2KeyExchange_AStep6To7(U, tA, RB, infoA); //A step6~7  
107.	    if (IsZeroPoint(U)) //A 判断U是否为(0,0)  
108.	    {  
109.	        return FALSE;  
110.	    }  
111.	    uint8_t* S1 = malloc(32), * KA = malloc(klenInBit / 8);  
112.	    SM2KeyExchange_AStep8To9(KA, S1, *U, klenInBit, *RA, *RB, infoA);   //A step8~9  
113.	  
114.	    if (KeyExchangeCheck)  
115.	    {  
116.	        for (int i = 0; i < 32; i++)//A 判断S1是否==SB  
117.	        {  
118.	            if (S1[i] != SB[i])  
119.	            {  
120.	                return FALSE;  
121.	            }  
122.	        }  
123.	    }  
124.	  
125.	    uint8_t* SA = malloc(32);  
126.	    SM2KeyExchange_AStep10(SA, *U, *RA, *RB, infoA);    //A step10  
127.	  
128.	    uint8_t* S2 = malloc(32);  
129.	    SM2KeyExchange_BStep10(S2, *V, *RA, *RB, infoB);    //B step10  
130.	  
131.	    if (KeyExchangeCheck)  
132.	    {  
133.	        for (int i = 0; i < 32; i++)//B 判断S2是否==SA  
134.	        {  
135.	            if (S2[i] != SA[i])  
136.	            {  
137.	                return FALSE;  
138.	            }  
139.	        }  
140.	    }  
141.	    free(RA);  
142.	    free(V);  
143.	    free(U);  
144.	    free(pubKeyA);  
145.	    free(pubKeyB);  
146.	    free(RB);  
147.	    free(SB);  
148.	    free(KB);  
149.	    free(S1);  
150.	    free(KA);  
151.	    free(SA);  
152.	    free(S2);  
153.	  
154.	    return TRUE;  
155.	}  

4. 公钥加密算法

     公钥加密算法规定发送者用接收者的公钥将消息加密成密文,接收者用自已的私钥对收到的密文进行解密还原成原始消息。

4.1 加密算法

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

1.	uint8_t* SM2Encrypt(char* messagePlain, int messageSizeInBit, EccPoint* pubKey)  
2.	{  
3.	    uint256_t randomK = { 0 };  
4.	    EccPoint* pointC1 = malloc(sizeof(EccPoint)), * kPb = malloc(sizeof(EccPoint));  
5.	    uint8_t* t = malloc(messageSizeInBit / 8), * x2 = malloc(64), * y2 = malloc(32),//t = KDF()  
6.	        * C1 = malloc(65), * x1 = malloc(32), * y1 = malloc(32),  
7.	        * C2 = malloc(messageSizeInBit / 8), * C3 = malloc(64 + messageSizeInBit / 8),  
8.	        * C = malloc(65 + messageSizeInBit / 8 + 32);  
9.	    GetRandomNumber(randomK, Ec->p);  
10.	#ifdef DEBUG_MODE  
11.	    for (int i = 0; i < 4; i++)  //测试时随机数先固定  
12.	    {  
13.	        randomK[i] = exRandomK[3 - i];  
14.	    }  
15.	#endif  
16.	    CalculateC1(pointC1, randomK, G);  
17.	    Uint256ToString(x1, pointC1->x);  
18.	    Uint256ToString(y1, pointC1->y);  
19.	    C1[0] = 0x04;  
20.	    memcpy(C1 + 1, x1, 32);  
21.	    memcpy(C1 + 33, y1, 32);//C1 = 04||x1||y1  
22.	  
23.	    CalculateKPb(kPb, randomK, pubKey);  
24.	    Uint256ToString(x2, kPb->x);  
25.	    Uint256ToString(y2, kPb->y);  
26.	  
27.	    memcpy(C3, x2, 32);  
28.	    memcpy(C3 + 32, messagePlain, messageSizeInBit / 8);  
29.	    memcpy(C3 + 32 + messageSizeInBit / 8, y2, 32);  
30.	  
31.	    memcpy(x2 + 32, y2, 32);//x2 = x2 || y2  
32.	    KDF(t, x2, 64 * 8, messageSizeInBit);   //t = KDF()  
33.	    CalculateC2(C2, messagePlain, t, messageSizeInBit / 8); //C2 = M^t  
34.	    SM3((uint8_t*)C3, 64 + messageSizeInBit / 8, (uint8_t*)C3); //C3 = SM3(x2||M||y2)  
35.	  
36.	    memcpy(C, C1, 65);  
37.	    memcpy(C + 65, C2, messageSizeInBit / 8);  
38.	    memcpy(C + 65 + messageSizeInBit / 8, C3, 32);  //C = C1 || C2 || C3  
39.	    free(pointC1);  
40.	    free(kPb);  
41.	    free(t);  
42.	    free(x2);  
43.	    free(y2);  
44.	    free(C1);  
45.	    free(x1);  
46.	    free(y1);  
47.	    free(C2);  
48.	    free(C3);  
49.	  
50.	    return C;  
51.	}  

4.2 解密算法

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

1.	uint8_t* SM2Decrypt(char* C, int lenInByte, uint64_t* privKey)  
2.	{  
3.	    EccPoint* pointC1 = malloc(sizeof(EccPoint)), * point2 = malloc(sizeof(EccPoint));  
4.	    int lenOfMsg = lenInByte - 65 - 32;  
5.	    uint8_t* C2 = malloc(lenOfMsg + 1), * msg = malloc(lenOfMsg + 1),  
6.	        * x1 = malloc(32), * y1 = malloc(32),  
7.	        * x2 = malloc(64), * y2 = malloc(32), * t = malloc(lenOfMsg);  
8.	  
9.	    msg[lenInByte - 65 - 32] = '\0';  
10.	    memcpy(C2, C + 65, lenInByte - 65 - 32);//密文msg  
11.	    memcpy(x1, C + 1, 32);  
12.	    memcpy(y1, C + 1 + 32, 32);  
13.	    StringToUint256(pointC1->x, x1);  
14.	    StringToUint256(pointC1->y, y1);  
15.	    CurvePointMul(point2, pointC1, privKey);  
16.	    Uint256ToString(x2, point2->x);  
17.	    Uint256ToString(y2, point2->y);  
18.	    memcpy(x2 + 32, y2, 32);    //x2 = x2 || y2  
19.	    KDF(t, x2, 64 * 8, (lenInByte - 65 - 32) * 8);//t = KDF(x2||y2,klenInBit)  
20.	    CalculateMessage(msg, C2, t, lenOfMsg); //M' = C2 ^ t  
21.	    free(pointC1);  
22.	    free(point2);  
23.	    free(C2);  
24.	    free(x1);  
25.	    free(y1);  
26.	    free(x2);  
27.	    free(y2);  
28.	    free(t);  
29.	  
30.	    return msg;  
31.	}  

评论 33
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

emXiaoMing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值