资源简介
在goldboar写的SM2签名及验签函数( http://download.csdn.net/detail/goldboar/3833072)的基础上,改写的一个纯粹用来做SM2签名验证的函数,编译时需要用到OpenSSL的头文件和库文件(libeay32.lib或libeay32.dll),与goldboar的程序区别如下:
1.仅用于做验签,不能签名;
2.验签使用外部传入的SM2公钥,SM2公钥以(x,y)坐标形式传入;
3.签名也是以(r,s)坐标形式传入;
4.增加了一些内存清理语句,内存泄漏有改善;
5.goldboar的程序中使用的ECC参数是示例参数,不是GM/T 0003.5-2012规范中定义的参数,这里的验签函数中采用的是规范中定义的参数。
6.将一些对椭圆曲线参数的验证操作放入 _DEBUG 宏限制的范围内。因为参数是规范推荐的,已经过验证,所以在程序中无需再验证。将这些验证语句放入 _DEBUG 宏限制的范围内以后,如果编译 release 版本时就不会包含这些验证语句,效率可以有一点提升。
代码片段和文件信息
// derived from goldboar‘s program: http://download.csdn.net/detail/goldboar/3833072
#include “sm2_custom.h“
#include
#include
#include
/*********************************************************/
int BNPrintf(BIGNUM* bn)
{
char *p=NULL;
p=BN_bn2hex(bn);
printf(“%s“p);
OPENSSL_free(p);
return 0;
}
/*********************************************************/
int sm2_do_verify(const unsigned char *dgst
int dgst_len
const ECDSA_SIG *sig
EC_KEY *eckey)
{
int ret=(-1) i;
BN_CTX *ctx;
BIGNUM *order *R *m *X *t;
EC_POINT *point=NULL;
const EC_GROUP *group=NULL;
const EC_POINT *pub_key=NULL;
/* check input values */
if ( (!eckey) || ( !(group = EC_KEY_get0_group(eckey)) ) ||
( !(pub_key = EC_KEY_get0_public_key(eckey)) ) || (!sig) )
return ret;
if ( !(ctx = BN_CTX_new()) )
return ret;
BN_CTX_start(ctx);
order = BN_CTX_get(ctx);
R = BN_CTX_get(ctx);
t = BN_CTX_get(ctx);
m = BN_CTX_get(ctx);
X = BN_CTX_get(ctx);
if ( (!order) || (!R) || (!t) || (!m) || (!X) )
goto clean_memory;
if ( !(EC_GROUP_get_order(group order ctx)) )
goto clean_memory;
if ( BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
(BN_ucmp(sig->r order) >= 0) || BN_is_zero(sig->s) ||
BN_is_negative(sig->s) || (BN_ucmp(sig->s order) >= 0) )
{
ret=0; /* signature is invalid */
goto clean_memory;
}
//t =(r+s) mod n
if ( !(BN_mod_add_quick(t sig->s sig->rorder)) )
goto clean_memory;
if ( BN_is_zero(t) )
{
ret=0; /* signature is invalid */
goto clean_memory;
}
#ifdef _DEBUG
printf(“\nsig->r = 0x“);
BNPrintf(sig->r);
printf(“\n“);
printf(“sig->s = 0x“);
BNPrintf(sig->s);
printf(“\n“);
printf(“\nt = 0x“);
BNPrintf(t);
printf(“\n“);
#endif
//point = s*G+t*PA
if ( !(point = EC_POINT_new(group)) )
goto clean_memory;
if ( !(EC_POINT_mul(group point sig->s pub_key t ctx)) )
goto clean_memory;
if ( EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field )
{
if ( !(EC_POINT_get_affine_coordinates_GFp(group point X NULL ctx)) )
goto clean_memory;
}
else /* NID_X9_62_characteristic_two_field */
{
if ( !(EC_POINT_get_affine_coordinates_GF2m(group point X NULL ctx)) )
goto clean_memory;
}
i = BN_num_bits(order);
#ifdef _DEBUG
printf(“EC order = %d bits\n“ i);
#endif
/* Need to truncate digest if it is too long: first truncate whole bytes. */
if ( (8 * dgst_len) > i )
dgst_len = (i + 7)/8;
if ( !(BN_bin2bn(dgst dgst_len m)) )
goto clean_memory;
/* If still too long truncate remaining bits with a shift */
if ( ((8 * dgst_len) > i) && (!(BN_rshift(m m 8 - (i & 0x7)))) )
goto clean_memory;
/* R = m + X mod order */
if ( !(BN_mod_add_quick(R m X order)) )
goto clean_memory;
#ifdef _DEBUG
printf(
属性 大小 日期 时间 名称
----------- --------- ---------- ----- ----
文件 8408 2014-07-15 14:21 sm2_custom.c
文件 2540 2014-07-15 11:30 sm2_custom.h
文件 3095 2014-07-15 14:18 test_main.c
相关资源
- 国密SM2算法C代码
- SM2/SM3算法C语言实现
- 国密算法--Openssl 实现国密算法加密和
- RSA数字签名系统c源码
- SM2_SM3_SM4_C语言实现+SM3_C++实现+国家密
- 基于Gmssl的SM2加解密算法Demo
- sm2加密,解密,签名,验签sm3哈希基
- SM2_SM3_SM4_C语言实现
- SM2SM3SM4国密算法C语言实现VS2008
- 国密算法 SM2_SM3_SM4 C语言实现
- Sm2_sm3_sm4_c语言实现.zip
- SM2SM3;SM4;国密算法的C语言实现.rar
- RSA数字签名程序(C++实现)
- RSA数字签名算法实现
- C++编写的 rsa数字签名 源代码
- 基于rsa数字签名c++实现
- VC6cryptoapi加密数字签名
- sm2 签名验证 公钥机密私钥解密的实现
评论
共有 条评论