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 <openssl/bn_hash.h>
#include "sm9_lcl.h" #include "sm9_lcl.h"
#if 0
int SM9_hash1(const EVP_MD *md, BIGNUM **r, int SM9_hash1(const EVP_MD *md, BIGNUM **r,
const char *id, size_t idlen, const char *id, size_t idlen,
unsigned char hid, unsigned char hid,
@@ -77,6 +77,59 @@ int SM9_hash1(const EVP_MD *md, BIGNUM **r,
OPENSSL_free(buf); OPENSSL_free(buf);
return 1; 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, SM9PrivateKey *SM9_extract_private_key(SM9MasterSecret *msk,
const char *id, size_t idlen) 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); SM9err(SM9_F_SM9_EXTRACT_PRIVATE_KEY, ERR_R_SM9_LIB);
goto end; goto end;
} }
if (!BN_mod_add(t, t, msk->masterSecret, n, ctx)) { if (!BN_mod_add(t, t, msk->masterSecret, n, ctx)) {
SM9err(SM9_F_SM9_EXTRACT_PRIVATE_KEY, ERR_R_BN_LIB); SM9err(SM9_F_SM9_EXTRACT_PRIVATE_KEY, ERR_R_BN_LIB);
goto end; 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_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_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_to_bin(const fp12_t a, unsigned char to[384]);
int fp12_print(const fp12_t a);
void fp12_cleanup(fp12_t a); void fp12_cleanup(fp12_t a);
int point_init(point_t *P, BN_CTX *ctx); int point_init(point_t *P, BN_CTX *ctx);
int point_copy(point_t *R, const point_t *P); 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_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_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); 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]) static int fp2_to_bin(const fp2_t a, unsigned char to[64])
{ {
memset(to, 0, 64); memset(to, 0, 64);
BN_bn2bin(a[0], to + 32 - BN_num_bytes(a[0])); BN_bn2bin(a[1], to + 32 - BN_num_bytes(a[1]));
BN_bn2bin(a[1], to + 64 - BN_num_bytes(a[1])); BN_bn2bin(a[0], to + 64 - BN_num_bytes(a[0]));
return 1; return 1;
} }
static int fp2_from_bin(fp2_t a, const unsigned char from[64]) static int fp2_from_bin(fp2_t a, const unsigned char from[64])
{ {
return BN_bin2bn(from, 32, a[0]) return BN_bin2bn(from, 32, a[1])
&& BN_bin2bn(from + 32, 32, a[1]); && BN_bin2bn(from + 32, 32, a[0]);
} }
static int fp2_test(const BIGNUM *p, BN_CTX *ctx) 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]); 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[0]);
fp4_print(a[1]); fp4_print(a[1]);
@@ -1734,7 +1734,7 @@ void point_cleanup(point_t *P)
fp2_cleanup(P->Z); 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(" X1: %s\n", BN_bn2hex((P->X)[1]));
printf(" X0: %s\n", BN_bn2hex((P->X)[0])); 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) */ /* generate master secret k = rand(1, n - 1) */
do { do {
if (!BN_rand_range(msk->masterSecret, n)) { 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)); } 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) 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)) { if (!EVP_DigestInit_ex(ctx, md, eng)) {
SM9err(SM9_F_SM9_SIGNINIT, ERR_R_EVP_LIB); SM9err(SM9_F_SM9_SIGNINIT, ERR_R_EVP_LIB);
return 0; return 0;
} }
if (!EVP_DigestUpdate(ctx, &prefix, 1)) { if (!EVP_DigestUpdate(ctx, prefix, sizeof(prefix))) {
SM9err(SM9_F_SM9_SIGNINIT, ERR_R_EVP_LIB); SM9err(SM9_F_SM9_SIGNINIT, ERR_R_EVP_LIB);
return 0; return 0;
} }
@@ -85,10 +85,10 @@ SM9Signature *SM9_SignFinal(EVP_MD_CTX *ctx1, SM9PrivateKey *sk)
const BIGNUM *n = SM9_get0_order(); const BIGNUM *n = SM9_get0_order();
int point_form = POINT_CONVERSION_COMPRESSED; int point_form = POINT_CONVERSION_COMPRESSED;
/* buf for w and prefix zeros of ct1/2 */ /* buf for w and prefix zeros of ct1/2 */
unsigned char buf[387] = {0}; unsigned char buf[384] = {0};
unsigned int len; unsigned int len;
const unsigned char ct1 = 0x01; const unsigned char ct1[4] = {0x00, 0x00, 0x00, 0x01};
const unsigned char ct2 = 0x02; const unsigned char ct2[4] = {0x00, 0x00, 0x00, 0x02};
EVP_MD_CTX *ctx2 = NULL; EVP_MD_CTX *ctx2 = NULL;
EC_GROUP *group = NULL; EC_GROUP *group = NULL;
EC_POINT *S = 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)) if (!EVP_DigestUpdate(ctx1, buf, sizeof(buf))
|| !EVP_MD_CTX_copy(ctx2, ctx1) || !EVP_MD_CTX_copy(ctx2, ctx1)
/* Ha1 = Hv(0x02||M||w||0x00000001) */ /* Ha1 = Hv(0x02||M||w||0x00000001) */
|| !EVP_DigestUpdate(ctx1, &ct1, 1) || !EVP_DigestUpdate(ctx1, ct1, sizeof(ct1))
|| !EVP_DigestFinal_ex(ctx1, buf, &len)
/* Ha2 = Hv(0x02||M||w||0x00000002) */ /* 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)) { || !EVP_DigestFinal_ex(ctx2, buf + len, &len)) {
SM9err(SM9_F_SM9_SIGNFINAL, SM9_R_DIGEST_FAILURE); SM9err(SM9_F_SM9_SIGNFINAL, SM9_R_DIGEST_FAILURE);
goto end; goto end;
@@ -159,8 +159,8 @@ SM9Signature *SM9_SignFinal(EVP_MD_CTX *ctx1, SM9PrivateKey *sk)
/* h = (Ha mod (n - 1)) + 1 */ /* h = (Ha mod (n - 1)) + 1 */
|| !BN_mod(sig->h, sig->h, SM9_get0_order_minus_one(), bn_ctx) || !BN_mod(sig->h, sig->h, SM9_get0_order_minus_one(), bn_ctx)
|| !BN_add_word(sig->h, 1) || !BN_add_word(sig->h, 1)
/* l = r - h */ /* l = r - h (mod n) */
|| !BN_mod_sub(r, r, sig->h, p, bn_ctx)) { || !BN_mod_sub(r, r, sig->h, n, bn_ctx)) {
SM9err(SM9_F_SM9_SIGNFINAL, ERR_R_BN_LIB); SM9err(SM9_F_SM9_SIGNFINAL, ERR_R_BN_LIB);
goto end; goto end;
} }
@@ -197,13 +197,13 @@ end:
int SM9_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *md, ENGINE *eng) 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)) { if (!EVP_DigestInit_ex(ctx, md, eng)) {
SM9err(SM9_F_SM9_VERIFYINIT, ERR_R_EVP_LIB); SM9err(SM9_F_SM9_VERIFYINIT, ERR_R_EVP_LIB);
return 0; return 0;
} }
if (!EVP_DigestUpdate(ctx, &prefix, 1)) { if (!EVP_DigestUpdate(ctx, prefix, sizeof(prefix))) {
SM9err(SM9_F_SM9_VERIFYINIT, ERR_R_EVP_LIB); SM9err(SM9_F_SM9_VERIFYINIT, ERR_R_EVP_LIB);
return 0; 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 *p = SM9_get0_prime();
const BIGNUM *n = SM9_get0_order(); const BIGNUM *n = SM9_get0_order();
const EVP_MD *md; const EVP_MD *md;
unsigned char buf[387] = {0}; unsigned char buf[384] = {0};
unsigned int len; unsigned int len;
const unsigned char ct1 = 0x01; const unsigned char ct1[4] = {0x00, 0x00, 0x00, 0x01};
const unsigned char ct2 = 0x02; const unsigned char ct2[4] = {0x00, 0x00, 0x00, 0x02};
EVP_MD_CTX *ctx2 = NULL; EVP_MD_CTX *ctx2 = NULL;
EC_GROUP *group = NULL; EC_GROUP *group = NULL;
EC_POINT *S = 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)) if (!EVP_DigestUpdate(ctx1, buf, sizeof(buf))
|| !EVP_MD_CTX_copy(ctx2, ctx1) || !EVP_MD_CTX_copy(ctx2, ctx1)
/* Ha1 = Hv(0x02||M||w||0x00000001) */ /* Ha1 = Hv(0x02||M||w||0x00000001) */
|| !EVP_DigestUpdate(ctx1, &ct1, 1) || !EVP_DigestUpdate(ctx1, ct1, sizeof(ct1))
/* Ha2 = Hv(0x02||M||w||0x00000002) */ /* 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(ctx1, buf, &len)
|| !EVP_DigestFinal_ex(ctx2, buf + len, &len)) { || !EVP_DigestFinal_ex(ctx2, buf + len, &len)) {
SM9err(SM9_F_SM9_VERIFYFINAL, SM9_R_DIGEST_FAILURE); 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 = 0;
} }
ret = 1; ret = 1;
end: end:
@@ -426,6 +427,10 @@ int SM9_verify(int type, /* NID_[sm3 | sha256] */
goto end; 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) if (!SM9_VerifyInit(ctx, md, NULL)
|| !SM9_VerifyUpdate(ctx, data, datalen) || !SM9_VerifyUpdate(ctx, data, datalen)
|| (ret = SM9_VerifyFinal(ctx, sm9sig, pk)) < 0) { || (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); ERR_print_errors_fp(stderr);
goto end; 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); ERR_print_errors_fp(stderr);
goto end; 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); ERR_print_errors_fp(stderr);
goto end; goto end;
} }
printf("sm9test_sign() success\n");
ret = 1; ret = 1;
end: end:
SM9PublicParameters_free(mpk); SM9PublicParameters_free(mpk);
@@ -143,10 +144,10 @@ int main(int argc, char **argv)
char *id = "guanzhi1980@gmail.com"; char *id = "guanzhi1980@gmail.com";
unsigned char in[] = "message to be signed or encrypted"; 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++; err++;
} }
if (!sm9test_enc(id, in, sizeof(in))) { if (!sm9test_enc(id, in, sizeof(in)-1)) {
err++; err++;
} }