First SM9 release

SM9 digitial signature scheme is finished and tested.
This commit is contained in:
Zhi Guan
2018-09-29 11:54:00 +08:00
parent b54a3d35e6
commit 93064bf826
6 changed files with 93 additions and 30 deletions

View File

@@ -54,7 +54,7 @@
#include <openssl/bn_hash.h>
#include "sm9_lcl.h"
#if 0
int SM9_hash1(const EVP_MD *md, BIGNUM **r,
const char *id, size_t idlen,
unsigned char hid,
@@ -77,6 +77,59 @@ int SM9_hash1(const EVP_MD *md, BIGNUM **r,
OPENSSL_free(buf);
return 1;
}
#endif
int SM9_hash1(const EVP_MD *md, BIGNUM **r, const char *id, size_t idlen,
unsigned char hid, const BIGNUM *n, BN_CTX *ctx)
{
int ret = 0;
BIGNUM *h = NULL;
BN_CTX *bn_ctx = NULL;
EVP_MD_CTX *ctx1 = NULL;
EVP_MD_CTX *ctx2 = NULL;
unsigned char prefix[1] = {0x01};
unsigned char ct1[4] = {0x00, 0x00, 0x00, 0x01};
unsigned char ct2[4] = {0x00, 0x00, 0x00, 0x02};
unsigned char buf[128];
unsigned int len;
if (!(ctx1 = EVP_MD_CTX_new())
|| !(ctx2 = EVP_MD_CTX_new())
|| !(bn_ctx = BN_CTX_new())
|| !(h = BN_new())) {
goto end;
}
if (!EVP_DigestInit_ex(ctx1, md, NULL)
|| !EVP_DigestUpdate(ctx1, prefix, sizeof(prefix))
|| !EVP_DigestUpdate(ctx1, id, idlen)
|| !EVP_DigestUpdate(ctx1, &hid, 1)
|| !EVP_MD_CTX_copy(ctx2, ctx1)
|| !EVP_DigestUpdate(ctx1, ct1, sizeof(ct1))
|| !EVP_DigestUpdate(ctx2, ct2, sizeof(ct2))
|| !EVP_DigestFinal_ex(ctx1, buf, &len)
|| !EVP_DigestFinal_ex(ctx2, buf + len, &len)) {
goto end;
}
if (!BN_bin2bn(buf, 40, h)
|| !BN_mod(h, h, SM9_get0_order_minus_one(), bn_ctx)
|| !BN_add_word(h, 1)) {
goto end;
}
*r = h;
h = NULL;
ret = 1;
end:
BN_free(h);
BN_CTX_free(bn_ctx);
EVP_MD_CTX_free(ctx1);
EVP_MD_CTX_free(ctx2);
return ret;
}
SM9PrivateKey *SM9_extract_private_key(SM9MasterSecret *msk,
const char *id, size_t idlen)
@@ -155,6 +208,7 @@ SM9PrivateKey *SM9_extract_private_key(SM9MasterSecret *msk,
SM9err(SM9_F_SM9_EXTRACT_PRIVATE_KEY, ERR_R_SM9_LIB);
goto end;
}
if (!BN_mod_add(t, t, msk->masterSecret, n, ctx)) {
SM9err(SM9_F_SM9_EXTRACT_PRIVATE_KEY, ERR_R_BN_LIB);
goto end;

View File

@@ -154,10 +154,12 @@ int fp12_init(fp12_t a, BN_CTX *ctx);
int fp12_mul(fp12_t r, const fp12_t a, const fp12_t b, const BIGNUM *p, BN_CTX *ctx);
int fp12_pow(fp12_t r, const fp12_t a, const BIGNUM *k, const BIGNUM *p, BN_CTX *ctx);
int fp12_to_bin(const fp12_t a, unsigned char to[384]);
int fp12_print(const fp12_t a);
void fp12_cleanup(fp12_t a);
int point_init(point_t *P, BN_CTX *ctx);
int point_copy(point_t *R, const point_t *P);
void point_print(const point_t *P);
int point_equ(const point_t *P, const point_t *Q);
int point_is_on_curve(point_t *P, const BIGNUM *p, BN_CTX *ctx);
int point_to_octets(const point_t *P, unsigned char to[129], BN_CTX *ctx);

View File

@@ -414,15 +414,15 @@ static int fp2_div(fp2_t r, const fp2_t a, const fp2_t b, const BIGNUM *p, BN_CT
static int fp2_to_bin(const fp2_t a, unsigned char to[64])
{
memset(to, 0, 64);
BN_bn2bin(a[0], to + 32 - BN_num_bytes(a[0]));
BN_bn2bin(a[1], to + 64 - BN_num_bytes(a[1]));
BN_bn2bin(a[1], to + 32 - BN_num_bytes(a[1]));
BN_bn2bin(a[0], to + 64 - BN_num_bytes(a[0]));
return 1;
}
static int fp2_from_bin(fp2_t a, const unsigned char from[64])
{
return BN_bin2bn(from, 32, a[0])
&& BN_bin2bn(from + 32, 32, a[1]);
return BN_bin2bn(from, 32, a[1])
&& BN_bin2bn(from + 32, 32, a[0]);
}
static int fp2_test(const BIGNUM *p, BN_CTX *ctx)
@@ -1007,7 +1007,7 @@ static void fp12_clear_cleanup(fp12_t a)
fp4_clear_cleanup(a[2]);
}
static int fp12_print(const fp12_t a)
int fp12_print(const fp12_t a)
{
fp4_print(a[0]);
fp4_print(a[1]);
@@ -1734,7 +1734,7 @@ void point_cleanup(point_t *P)
fp2_cleanup(P->Z);
}
static void point_print(const point_t *P)
void point_print(const point_t *P)
{
printf(" X1: %s\n", BN_bn2hex((P->X)[1]));
printf(" X0: %s\n", BN_bn2hex((P->X)[0]));

View File

@@ -118,7 +118,8 @@ SM9MasterSecret *SM9_generate_master_secret(int pairing, int scheme, int hash1)
/* generate master secret k = rand(1, n - 1) */
do {
if (!BN_rand_range(msk->masterSecret, n)) {
return 0;
SM9err(SM9_F_SM9_GENERATE_MASTER_SECRET, ERR_R_BN_LIB);
goto end;
}
} while (BN_is_zero(msk->masterSecret));

View File

@@ -63,13 +63,13 @@ int SM9_signature_size(SM9PublicParameters *mpk)
int SM9_SignInit(EVP_MD_CTX *ctx, const EVP_MD *md, ENGINE *eng)
{
unsigned char prefix = 0x02;
unsigned char prefix[1] = {0x02};
if (!EVP_DigestInit_ex(ctx, md, eng)) {
SM9err(SM9_F_SM9_SIGNINIT, ERR_R_EVP_LIB);
return 0;
}
if (!EVP_DigestUpdate(ctx, &prefix, 1)) {
if (!EVP_DigestUpdate(ctx, prefix, sizeof(prefix))) {
SM9err(SM9_F_SM9_SIGNINIT, ERR_R_EVP_LIB);
return 0;
}
@@ -85,10 +85,10 @@ SM9Signature *SM9_SignFinal(EVP_MD_CTX *ctx1, SM9PrivateKey *sk)
const BIGNUM *n = SM9_get0_order();
int point_form = POINT_CONVERSION_COMPRESSED;
/* buf for w and prefix zeros of ct1/2 */
unsigned char buf[387] = {0};
unsigned char buf[384] = {0};
unsigned int len;
const unsigned char ct1 = 0x01;
const unsigned char ct2 = 0x02;
const unsigned char ct1[4] = {0x00, 0x00, 0x00, 0x01};
const unsigned char ct2[4] = {0x00, 0x00, 0x00, 0x02};
EVP_MD_CTX *ctx2 = NULL;
EC_GROUP *group = NULL;
EC_POINT *S = NULL;
@@ -145,10 +145,10 @@ SM9Signature *SM9_SignFinal(EVP_MD_CTX *ctx1, SM9PrivateKey *sk)
if (!EVP_DigestUpdate(ctx1, buf, sizeof(buf))
|| !EVP_MD_CTX_copy(ctx2, ctx1)
/* Ha1 = Hv(0x02||M||w||0x00000001) */
|| !EVP_DigestUpdate(ctx1, &ct1, 1)
|| !EVP_DigestFinal_ex(ctx1, buf, &len)
|| !EVP_DigestUpdate(ctx1, ct1, sizeof(ct1))
/* Ha2 = Hv(0x02||M||w||0x00000002) */
|| !EVP_DigestUpdate(ctx2, &ct2, 1)
|| !EVP_DigestUpdate(ctx2, ct2, sizeof(ct2))
|| !EVP_DigestFinal_ex(ctx1, buf, &len)
|| !EVP_DigestFinal_ex(ctx2, buf + len, &len)) {
SM9err(SM9_F_SM9_SIGNFINAL, SM9_R_DIGEST_FAILURE);
goto end;
@@ -159,8 +159,8 @@ SM9Signature *SM9_SignFinal(EVP_MD_CTX *ctx1, SM9PrivateKey *sk)
/* h = (Ha mod (n - 1)) + 1 */
|| !BN_mod(sig->h, sig->h, SM9_get0_order_minus_one(), bn_ctx)
|| !BN_add_word(sig->h, 1)
/* l = r - h */
|| !BN_mod_sub(r, r, sig->h, p, bn_ctx)) {
/* l = r - h (mod n) */
|| !BN_mod_sub(r, r, sig->h, n, bn_ctx)) {
SM9err(SM9_F_SM9_SIGNFINAL, ERR_R_BN_LIB);
goto end;
}
@@ -197,13 +197,13 @@ end:
int SM9_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *md, ENGINE *eng)
{
unsigned char prefix = 0x02;
unsigned char prefix[1] = {0x02};
if (!EVP_DigestInit_ex(ctx, md, eng)) {
SM9err(SM9_F_SM9_VERIFYINIT, ERR_R_EVP_LIB);
return 0;
}
if (!EVP_DigestUpdate(ctx, &prefix, 1)) {
if (!EVP_DigestUpdate(ctx, prefix, sizeof(prefix))) {
SM9err(SM9_F_SM9_VERIFYINIT, ERR_R_EVP_LIB);
return 0;
}
@@ -228,10 +228,10 @@ int SM9_VerifyFinal(EVP_MD_CTX *ctx1, const SM9Signature *sig, SM9PublicKey *pk)
const BIGNUM *p = SM9_get0_prime();
const BIGNUM *n = SM9_get0_order();
const EVP_MD *md;
unsigned char buf[387] = {0};
unsigned char buf[384] = {0};
unsigned int len;
const unsigned char ct1 = 0x01;
const unsigned char ct2 = 0x02;
const unsigned char ct1[4] = {0x00, 0x00, 0x00, 0x01};
const unsigned char ct2[4] = {0x00, 0x00, 0x00, 0x02};
EVP_MD_CTX *ctx2 = NULL;
EC_GROUP *group = NULL;
EC_POINT *S = NULL;
@@ -314,9 +314,9 @@ int SM9_VerifyFinal(EVP_MD_CTX *ctx1, const SM9Signature *sig, SM9PublicKey *pk)
if (!EVP_DigestUpdate(ctx1, buf, sizeof(buf))
|| !EVP_MD_CTX_copy(ctx2, ctx1)
/* Ha1 = Hv(0x02||M||w||0x00000001) */
|| !EVP_DigestUpdate(ctx1, &ct1, 1)
|| !EVP_DigestUpdate(ctx1, ct1, sizeof(ct1))
/* Ha2 = Hv(0x02||M||w||0x00000002) */
|| !EVP_DigestUpdate(ctx2, &ct2, 1)
|| !EVP_DigestUpdate(ctx2, ct2, sizeof(ct2))
|| !EVP_DigestFinal_ex(ctx1, buf, &len)
|| !EVP_DigestFinal_ex(ctx2, buf + len, &len)) {
SM9err(SM9_F_SM9_VERIFYFINAL, SM9_R_DIGEST_FAILURE);
@@ -337,6 +337,7 @@ int SM9_VerifyFinal(EVP_MD_CTX *ctx1, const SM9Signature *sig, SM9PublicKey *pk)
ret = 0;
}
ret = 1;
end:
@@ -426,6 +427,10 @@ int SM9_verify(int type, /* NID_[sm3 | sha256] */
goto end;
}
if (!(ctx = EVP_MD_CTX_new())) {
SM9err(SM9_F_SM9_VERIFY, ERR_R_MALLOC_FAILURE);
goto end;
}
if (!SM9_VerifyInit(ctx, md, NULL)
|| !SM9_VerifyUpdate(ctx, data, datalen)
|| (ret = SM9_VerifyFinal(ctx, sm9sig, pk)) < 0) {

View File

@@ -80,15 +80,16 @@ static int sm9test_sign(const char *id, const unsigned char *msg, size_t msglen)
ERR_print_errors_fp(stderr);
goto end;
}
if (!SM9_sign(NID_sm3, msg, sizeof(msg), sig, &siglen, sk)) {
if (!SM9_sign(NID_sm3, msg, msglen, sig, &siglen, sk)) {
ERR_print_errors_fp(stderr);
goto end;
}
if (1 != SM9_verify(NID_sm3, msg, sizeof(msg), sig, siglen, mpk, id, strlen(id))) {
if (1 != SM9_verify(NID_sm3, msg, msglen, sig, siglen, mpk, id, strlen(id))) {
ERR_print_errors_fp(stderr);
goto end;
}
printf("sm9test_sign() success\n");
ret = 1;
end:
SM9PublicParameters_free(mpk);
@@ -143,10 +144,10 @@ int main(int argc, char **argv)
char *id = "guanzhi1980@gmail.com";
unsigned char in[] = "message to be signed or encrypted";
if (!sm9test_sign(id, in, sizeof(in))) {
if (!sm9test_sign(id, in, sizeof(in)-1)) {
err++;
}
if (!sm9test_enc(id, in, sizeof(in))) {
if (!sm9test_enc(id, in, sizeof(in)-1)) {
err++;
}