国密SM9算法C++实现之五:签名验签算法
SM9算法C++实现系列目录:
基于JPBC的SM9算法的java实现与测试
国密SM9算法C++实现之0:源码下载地址
国密SM9算法C++实现之一:算法简介
国密SM9算法C++实现之二:测试工具
国密SM9算法C++实现之三:椭圆曲线接口、参数初始化
国密SM9算法C++实现之四:基本功能函数与KGC接口的实现
国密SM9算法C++实现之五:签名验签算法
国密SM9算法C++实现之六:密钥封装解封算法
国密SM9算法C++实现之七:加密解密算法
国密SM9算法C++实现之八:密钥交换算法
国密SM9算法C++实现之九:算法功能与测试例子
国密SM9算法C++实现之五:签名验签算法
文章目录
- 国密SM9算法C++实现之五:签名验签算法
- @[toc]
- 签名算法流程
- 签名值
- Signature.h
- 签名算法实现
- 验签算法流程
- 验签算法实现
实现完KGC部分后,可以开始实现SM9算法部分。本篇描述签名验签算法的实现。
签名算法流程
SM9标准文档中描述的签名算法流程如下所示:
其流程图为:
根据算法描述,定义接口函数:
/** * 签名* * @param masterPublicKey 签名主公钥* @param prikey 用户签名私钥* @param data 待签数据* @return 签名值* @throw std::exception SM9_ERROR_NOT_INIT | SM9_ERROR_CALC_RATE*/static Signature sign(const string& masterPublicKey, const string& prikey, const string& data);
签名值
SM9签名结果包括h和S两个部分,对此,也简单将其封装为一个类。
Signature.h
#ifndef YY_SM9_SIGNATURE_INCLUDE_H__
#define YY_SM9_SIGNATURE_INCLUDE_H__#pragma once#include <string>using namespace std;/**
* 签名值.
* @author YaoYuan
*/
class Signature {
public:Signature() {}Signature(const string& h, const string& s) {mH = h;mS = s;}~Signature() {}public:string getH() const { return mH; }string getS() const { return mS; }private:string mH;string mS;
};#endif
签名算法实现
按照签名流程,实现签名算法:
Signature SM9::sign(const string& masterPublicKey, const string& prikey, const string& data)
{Signature signature;bool hasException = true;string h, s, sw;ecn2 Ppubs;epoint* dsa = NULL;epoint* S = NULL;ZZN12 g;ZZN12 w;big h2 = NULL;big r = NULL;big l = NULL;big tmp = NULL;big zero = NULL;#ifdef SELF_CHECKstring gHex, rHex, wHex, h2Hex;
#endifif( !mIsInit ) {mErrorNum = SM9_ERROR_NOT_INIT;throw exception(getErrorMsg().c_str());}Parameters::init_ecn2(Ppubs);Parameters::init_big(h2);Parameters::init_big(r);Parameters::init_big(l);Parameters::init_big(tmp);Parameters::init_big(zero);Parameters::init_epoint(dsa);Parameters::init_epoint(S);// Step1 : g = e(P1, Ppub-s)Parameters::cin_ecn2_byte128(Ppubs, masterPublicKey.c_str());if( !ZZN12::calcRatePairing(g, Ppubs, Parameters::param_P1, Parameters::param_t, Parameters::norm_X) ) {mErrorNum = SM9_ERROR_CALC_RATE;goto END;}#ifdef SELF_CHECKgHex = YY::YHex::bin2Hex(g.toByteArray());
#endifwhile( true ) {
#ifdef SELF_CHECKrHex = YY::YHex::hex2bin("033C8616B06704813203DFD00965022ED15975C662337AED648835DC4B1CBE");Parameters::cin_big(r, rHex.c_str(), rHex.length());
#else// Step2: generate rbigrand(Parameters::param_N, r);
#endif// Step3 : calculate w=g^rw = g.pow(r);sw = w.toByteArray();#ifdef SELF_CHECKwHex = YY::YHex::bin2Hex(sw);
#endif// Step4 : calculate h=H2(M||w,N)h = KGC::H2(data, sw);Parameters::cin_big(h2, h.c_str(), h.length());#ifdef SELF_CHECKh2Hex = YY::YHex::bin2Hex(h);
#endif// Step5 : l=(r-h)mod Nsubtract(r, h2, l);divide(l, Parameters::param_N, tmp);while( mr_compare(l, zero) < 0 )add(l, Parameters::param_N, l);if( mr_compare(l, zero) != 0 )break;}// Step6 : S=[l]dSA=(xS,yS)Parameters::cin_epoint(dsa, prikey.c_str());ecurve_mult(l, dsa, S);s = Parameters::cout_epoint(S);// Step7 : signature=(h,s)signature = Signature(h, s);hasException = false;END:Parameters::release_epoint(dsa);Parameters::release_epoint(S);Parameters::release_ecn2(Ppubs);Parameters::release_big(h2);Parameters::release_big(r);Parameters::release_big(l);Parameters::release_big(tmp);Parameters::release_big(zero);if( hasException ) {throw exception(getErrorMsg().c_str());}return signature;
}
验签算法流程
SM9标准文档中描述的验签算法流程如下所示:
其流程为:
根据算法描述,定义接口函数:
/*** 验签** @param masterPublicKey 签名主公钥* @param prikey 用户ID* @param signature 签名值* @param data 待签数据* @return true-验签成功;false-验签失败* @throw std::exception SM9_ERROR_NOT_INIT | SM9_ERROR_CALC_RATE | * SM9_ERROR_VERIFY_H_OUTRANGE | SM9_ERROR_VERIFY_S_NOT_ON_G1 | SM9_ERROR_VERIFY_H_VERIFY_FAILED*/static bool verify(const string& masterPublicKey, const string& id, const Signature& signature, const string& data);
接口中没有必要提供hid,对于验签算法来说,这是确定的。
验签算法实现
bool SM9::verify(const string& masterPublicKey, const string& id, const Signature& signature, const string& data)
{bool result = false;bool hasException = true;big NSub1 = NULL;big one = NULL;big h = NULL;epoint* S = NULL;ecn2 Ppubs;ecn2 P;ZZN12 g;ZZN12 t;ZZN12 u;ZZN12 w;big h1 = NULL;string sH1, sH2, sw, sH, sS;if( !mIsInit ) {mErrorNum = SM9_ERROR_NOT_INIT;throw exception(getErrorMsg().c_str());}sH = signature.getH();sS = signature.getS();#ifdef SELF_CHECKstring gHex, rHex, h1Hex, tHex, pHex, uHex, wHex;
#endifParameters::init_big(NSub1);Parameters::init_big(one);Parameters::init_big(h);Parameters::init_epoint(S);Parameters::init_ecn2(Ppubs);Parameters::init_ecn2(P);Parameters::init_big(h1);// Step1 : check if h in the range [1, N-1]decr(Parameters::param_N, 1, NSub1);convert(1, one);Parameters::cin_big(h, sH.c_str(), sH.length());if( (mr_compare(h, one) < 0) | (mr_compare(h, NSub1) > 0) ) {mErrorNum = SM9_ERROR_VERIFY_H_OUTRANGE;goto END;}// Step2 : check if S is on G1Parameters::cin_epoint(S, sS.c_str());if( !Parameters::isPointOnG1(S) ) {mErrorNum = SM9_ERROR_VERIFY_S_NOT_ON_G1;goto END;}// Step3 : g = e(P1, Ppub-s)Parameters::cin_ecn2_byte128(Ppubs, masterPublicKey.c_str());if( !ZZN12::calcRatePairing(g, Ppubs, Parameters::param_P1, Parameters::param_t, Parameters::norm_X) ) {mErrorNum = SM9_ERROR_CALC_RATE;goto END;}#ifdef SELF_CHECKgHex = YY::YHex::bin2Hex(g.toByteArray());
#endif// Step4 : calculate t=g^ht = g.pow(h);#ifdef SELF_CHECKtHex = YY::YHex::bin2Hex(t.toByteArray());
#endif// Step5 : calculate h1=H1(IDA||hid,N)sH1 = KGC::H1(id, HID_SIGN);Parameters::cin_big(h1, sH1.c_str(), sH1.length());#ifdef SELF_CHECKh1Hex = YY::YHex::bin2Hex(sH1);
#endif// Step6 : P=[h1]P2+Ppubsecn2_copy(&Parameters::param_P2, &P);ecn2_mul(h1, &P);ecn2_add(&Ppubs, &P);ecn2_norm(&P);#ifdef SELF_CHECKpHex = YY::YHex::bin2Hex(Parameters::cout_ecn2(P));
#endif// Step7 : u=e(S,P)if( !ZZN12::calcRatePairing(u, P, S, Parameters::param_t, Parameters::norm_X) ) {mErrorNum = SM9_ERROR_CALC_RATE;goto END;}#ifdef SELF_CHECKuHex = YY::YHex::bin2Hex(u.toByteArray());
#endif// Step8 : w=u*tw = u.mul(t);sw = w.toByteArray();#ifdef SELF_CHECKwHex = YY::YHex::bin2Hex(sw);
#endif// Step9 : h2=H2(M||w,N)sH2 = KGC::H2(data, sw);if( sH2.compare(sH) == 0 ) {result = true;} else {mErrorNum = SM9_ERROR_VERIFY_H_VERIFY_FAILED;}hasException = false;
END:Parameters::release_big(NSub1);Parameters::release_big(one);Parameters::release_big(h);Parameters::release_epoint(S);Parameters::release_ecn2(Ppubs);Parameters::release_ecn2(P);Parameters::release_big(h1);if( hasException ) {throw exception(getErrorMsg().c_str());}return result;
}
由于验签函数返回类型是bool,因此验签失败后,可以通过getErrorMsg获取错误信息。
国密SM9算法C++实现之五:签名验签算法相关推荐
- php pkcs7签名验签算法,OpenSSL 签名验签接口调用及测试
OpenSSL 签名验签接口调用及测试 概述 项目中我们经常会遇到开发签名.验签功能.签名.验签是可信赖网络的一个重要功能.因此,我记录了OpenSSL 签名验签接口调用及测试. 相关测试代码 bas ...
- C语言——基于OpenSSL 的RSA 签名验签算法
OpenSSL开源工程中,实现RSA签名方法有多种.该方法基于OpenSSL 3.0版本,调用OpenSSL EVP层的EVP_DigestSign*()与EVP_DigestVerify*()实现p ...
- gmssl国密sm2(生成密钥对-私钥签字-证书验签)
生成密钥对: #include <stdio.h> #include <string.h> #include <stdlib.h> #include "e ...
- 国密SM9算法C++实现之一:算法简介
SM9算法C++实现系列目录: 基于JPBC的SM9算法的java实现与测试 国密SM9算法C++实现之0:源码下载地址 国密SM9算法C++实现之一:算法简介 国密SM9算法C++实现之二:测试工具 ...
- 国密SM9算法C++实现之八:密钥交换算法
SM9算法C++实现系列目录: 基于JPBC的SM9算法的java实现与测试 国密SM9算法C++实现之0:源码下载地址 国密SM9算法C++实现之一:算法简介 国密SM9算法C++实现之二:测试工具 ...
- 国密SM9算法C++实现之七:加密解密算法
SM9算法C++实现系列目录: 基于JPBC的SM9算法的java实现与测试 国密SM9算法C++实现之0:源码下载地址 国密SM9算法C++实现之一:算法简介 国密SM9算法C++实现之二:测试工具 ...
- 国密SM9算法C++实现之九:算法功能与测试例子
SM9算法C++实现系列目录: 基于JPBC的SM9算法的java实现与测试 国密SM9算法C++实现之0:源码下载地址 国密SM9算法C++实现之一:算法简介 国密SM9算法C++实现之二:测试工具 ...
- 国密SM9算法C++实现之六:密钥封装解封算法
SM9算法C++实现系列目录: 基于JPBC的SM9算法的java实现与测试 国密SM9算法C++实现之0:源码下载地址 国密SM9算法C++实现之一:算法简介 国密SM9算法C++实现之二:测试工具 ...
- 国密SM9算法C++实现之三:椭圆曲线接口、参数初始化
SM9算法C++实现系列目录: 基于JPBC的SM9算法的java实现与测试 国密SM9算法C++实现之0:源码下载地址 国密SM9算法C++实现之一:算法简介 国密SM9算法C++实现之二:测试工具 ...
最新文章
- Nginx+Tomcat出现session丢失问题
- SAP APO 介绍
- 软件测试工作常用linux命令,软件测试工程师工作中常用的Linux命令
- oracle 修索引改空间_Oracle如何更改表空间的数据文件位置详解
- spring 动态代理_分析动态代理给 Spring 事务埋下的坑
- PaddlePaddle中数据的基本操作
- 让我们了解下什么是智能客服(问答)
- 谈谈主策划需要的能力
- Unity粒子系统——简易特效制作(一)
- 计数器代码php,php的计数器程序_php
- G480改装固态硬盘、光驱变机械硬盘以及装系统(下)
- 特征选择:python lime
- AtCoder Beginner Contest 164 E Two Currencies Bellman-Ford优化思想+01背包+动归dp状态转移
- 计算机模拟电子云密度,小知识:分子动力学基本原理及应用
- RTC实时时钟(学习笔记)
- 全球人造丝卫生棉条行业调研及趋势分析报告
- [转载]删除微软拼音输入法
- Hidden Message
- wps word文档生成目录的时候显示断裂会生成大纲怎么办_自从学会了Word自动排版,我的秀发浓密多了...
- 获取沪深300成分股单日收盘价