mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-07 08:56:17 +08:00
First SM9 release
SM9 digitial signature scheme is finished and tested.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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]));
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user