//+++++++++++++++++++++++++++++++++++++++++++++++++
//| Copyright @ HZFLK
//| Author : Xiedongfu
//| Email : xiedongfu@hzflk->com
//+++++++++++++++++++++++++++++++++++++++++++++++++
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include "init.h"
#include "curvepoint_fp.h"
#include "twistpoint_fp2.h"
#include "points.h"
#include "fp12e.h"
#include "randompoints.h"
#include "ate_optate.h"
#include "fp6.h"
#include "print_hex.h"
#include "sm9hv.h"
#include "sm9.h"
#include "curve.h"
//+-----------------------------------------------
//| General function
//+-----------------------------------------------
int cycflag = 1;
int BelongG1(unsigned char *ucX, unsigned char *ucY)
{
mpz_t x3, y2;
int chkflag = 0x3;
mpz_init(x3);
mpz_init(y2);
mpz_import(x3, 32, 1, 1, 0, 0, ucX);
mpz_import(y2, 32, 1, 1, 0, 0, ucY);
mpz_powm_ui(x3, x3, 3, sm9_p);
mpz_powm_ui(y2, y2, 2, sm9_p);
mpz_add_ui(x3, x3, 5);
if(mpz_cmp(y2, x3)){
chkflag = -1; //check,y^2 = x^3 + 5
}
else{
chkflag = 0;
}
mpz_clear(x3);
mpz_clear(y2);
return chkflag;
}
//+-----------------------------------------------
//| sm9-1 : parameter
//| init_sm9: initialling system parameters
//| clear_sm9: free ram by initialling SM9SIGN
//+-----------------------------------------------
void init_sm9(void)
{
init_globals();//initialling pairing parameters
}
void clear_sm9(void)
{
clear_globals();//initialling pairing parameters
}
//+-----------------------------------------------
//| sm9-2 : dsa
//| hk_sm9sign: generater host key (public and private)
//| uk_sm9sign: generater user key (public and private)
//| sign_sm9sign: sign function
//| chk_sm9sign: check function
//+-----------------------------------------------
void hk_sm9sign(SignHKey_st HKey)
{
mpz_t ks;
twistpoint_fp2_t pubs;
size_t len;
mpz_init(ks);
get_random_r(ks);
#ifdef TEST_SM9 //set ks & pubs, used in test
mpz_init_set_str(ks, KS_SIGN, 10);
#endif
twistpoint_fp2_mul(pubs, twist_gen, ks);
mpz_export(HKey->ucPvaKey, &len, 1, 1, 0, 0, ks);
memmove(&HKey->ucPvaKey[32-len], &HKey->ucPvaKey[0], len);
memset(&HKey->ucPvaKey[0], 0, 32-len);
twistpoint_fp2_makeaffine(pubs);
fpe_to_bytearray(HKey->ucPubKeyXa, pubs->m_x->m_a);
fpe_to_bytearray(HKey->ucPubKeyXb, pubs->m_x->m_b);
fpe_to_bytearray(HKey->ucPubKeyYa, pubs->m_y->m_a);
fpe_to_bytearray(HKey->ucPubKeyYb, pubs->m_y->m_b);
#ifdef TEST_SM9
printf("\n ks =");
mpz_out_str(stdout, 16, ks);
printf("\n ksu=");
int i;
for(i=0; i<32; i++)
{
printf("%02X", HKey->ucPvaKey[i]);
}
printf("\n pubs_xa1=");
fpe_print_hex(pubs->m_x->m_a);
printf("\n pubs_xa2=");
for(i=0; i<32; i++)
{
printf("%02X", HKey->ucPubKeyXa[i]);
}
printf("\n");
#endif
mpz_clear(ks);
}
//+-----------------------------------------------------
//|uk_sm9sign: sm9-2,p5-6
//+----------------------------------------------------------------------------------------
int uk_sm9sign(SignUKey_st UKey, SignHKey_st HKey)
{
mpz_t mHout;
mpz_t ks;
curvepoint_fp_t CurPvaKey;
int ret = 0;
unsigned char *ucIdAHid;
ucIdAHid = (unsigned char *) malloc((UKey->ulIdLen + 1) * sizeof(unsigned char));
memcpy(ucIdAHid, UKey->ucId, UKey->ulIdLen);
ucIdAHid[UKey->ulIdLen] = UKey->ucHid;
mpz_init(mHout);
mpz_init(ks);
mpz_import(ks, 32, 1, 1, 0, 0, HKey->ucPvaKey);
sm9h(mHout, ucIdAHid, UKey->ulIdLen+1, sm_n, 0x01);
mpz_add(mHout, mHout, ks);
mpz_mod(mHout, mHout, sm_n);
if(!mpz_cmp_ui(mHout, 0)){
ret = -1;
goto UK_RET;
}
mpz_invert(mHout, mHout, sm_n);
mpz_mul(mHout, mHout, ks);
mpz_mod(mHout, mHout, sm_n);
curvepoint_fp_mul(CurPvaKey, curve_gen, mHout);
curvepoint_fp_makeaffine(CurPvaKey);
fpe_to_bytearray(UKey->ucPvaKeyX, CurPvaKey->m_x);
fpe_to_bytearray(UKey->ucPvaKeyY, CurPvaKey->m_y);
ret = 0;
#ifdef TEST_SM9
printf("\n ukx1=");
fpe_print_hex(CurPvaKey->m_x);
printf("\n ukx2=");
int i;
for(i=0; i<32; i++)
{
printf("%02X", UKey->ucPvaKeyX[i]);
}
printf("\n");
printf("\n uky1=");
fpe_print_hex(CurPvaKey->m_y);
printf("\n uky2=");
for(i=0; i<32; i++)
{
printf("%02X", UKey->ucPvaKeyY[i]);
}
printf("\n");
#endif
UK_RET:
mpz_clear(mHout);
mpz_clear(ks);
free(ucIdAHid);
return ret;
}
//+----------------------------------------------------------------------------------------
//|sign_sm9sign: sm9-2,p5-6
//+----------------------------------------------------------------------------------------
void sign_sm9sign(SignInf_st Inf, SignUKey_st UKey, SignHKey_st HKey)
{
twistpoint_fp2_t PubsSm9;
//set pubs
twistpoint_fp2_set_bytearray(PubsSm9, HKey->ucPubKeyXa, HKey->ucPubKeyXb, HKey->ucPubKeyYa, HKey->ucPubKeyYb);
fp12e_t Gpubs;
mpz_t Rrnd;
mpz_t mHout;
mpz_t mL;
fp12e_t Wgpr;
unsigned char ucWgprInchar[384];
unsigned char *ucMw;
optate(Gpubs, PubsSm9, curve_gen);
ucMw = (unsigned char *) malloc((Inf->ulMsgLen + 384) * sizeof(unsigned char));
mpz_init(Rrnd);
mpz_init(mHout);
mpz_init(mL);
do{
get_random_r(Rrnd);
#ifdef TEST_SM9 //test data, r
mpz_init_set_str(Rrnd, SM9_R, 16);
#endif
fp12e_pow(Wgpr, Gpubs, Rrnd);
fp12e_to_bytearray(ucWgprInchar, Wgpr);
memcpy(ucMw, Inf->ucMsg, Inf->ulMsgLen);
memcpy(&ucMw[Inf->ulMsgLen], ucWgprInchar, 384);
sm9h(mHout, ucMw, Inf->ulMsgLen+384, sm_n, 0x02);
mpz_sub(mL, Rrnd, mHout);
mpz_mod(mL, mL, sm_n);
}while(!mpz_cmp_ui(mL,0));
curvepoint_fp_t dsa;
curvepoint_fp_t sign;
size_t len;
curvepoint_fp_set_bytearray(dsa, UKey->ucPvaKeyX, UKey->ucPvaKeyY);
curvepoint_fp_mul(sign, dsa, mL);
curvepoint_fp_makeaffine(sign);
mpz_export(Inf->ucHash, &len, 1, 1, 0, 0, mHout); //export hash
memmove(&Inf->ucHash[32-len], &Inf->ucHash[0], len);
memset(&Inf->ucHash[0], 0, 32-len);
fpe_to_bytearray(Inf->ucSignX, sign->m_x); //export sign
fpe_to_bytearray(Inf->ucSignY, sign->m_y);
#ifdef TEST_SM9
printf("\n curve_gen_x=\n");
fpe_print_hex(curve_gen->m_x);
printf("\n curve_gen_y=\n");
fpe_print_hex(curve_gen->m_y);
printf("\n pubs_xa=\n");
fp2e_print_hex(PubsSm9->m_x);
printf("\n pubs_xb=\n");
fp2e_print_hex(PubsSm9->m_y);
printf("\n g=e(pubs, p1)=\n");
fp12e_print_hex(Gpubs);
printf("\n w=g^r=\n");
fp12e_print_hex(Wgpr);
printf("\n mw=\n");
int i = 0, j=0;
for(i=0;i<(Inf->ulMsgLen+384);i++)
{
printf("%02X", ucMw[i]);
j++;
if(j==40){
j=0;
printf("\n");
}
}
printf("\n hash=\n");
mpz_out_str(stdout, 16, mHout);
printf("\n");
printf("\n signx=\n");
fpe_print_hex(sign->m_x);
printf("\n signy=\n");
fpe_print_hex(sign->m_y);
printf("\n ucSignX=\n");
for(i=0; i<32; i++)
{
printf("%02X", Inf->ucSignX[i]);
}
printf("\n");
#endif
free(ucMw);
mpz_clear(Rrnd);
mpz_clear(mHout);
mpz_clear(mL);
}
//+----------------------------------------------------------------------------------------
//|chk_sm9sign:sm9-2,p6-7
//|return 0 : hash is right
//|return -1 : condition is not fullfish
//|return 1 : hash is error
//+----------------------------------------------------------------------------------------
int chk_sm9sign(SignInf_st Inf, SignUKey_st UKey, SignHKey_st HKey)
{
mpz_t mHash;
curvepoint_fp_t crSign;
in