• 大小: 5KB
    文件类型: .zip
    金币: 1
    下载: 0 次
    发布日期: 2021-06-11
  • 语言: C/C++
  • 标签: SM2  数字签名  

资源简介

在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

评论

共有 条评论