Update SM2

This commit is contained in:
Zhi Guan
2024-03-19 21:37:36 +08:00
parent 33baa3df92
commit 31440f9948
10 changed files with 483 additions and 2957 deletions

View File

@@ -18,8 +18,6 @@ set(src
src/sm3_hmac.c src/sm3_hmac.c
src/sm3_kdf.c src/sm3_kdf.c
src/sm3_digest.c src/sm3_digest.c
#src/sm2_alg.c
src/sm2_point.c
src/sm2_z256.c src/sm2_z256.c
src/sm2_z256_table.c src/sm2_z256_table.c
src/sm2_z256_key.c src/sm2_z256_key.c

View File

@@ -17,7 +17,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <gmssl/api.h> #include <gmssl/api.h>
#include <gmssl/sm3.h> #include <gmssl/sm3.h>
#include <gmssl/sm2_z256.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@@ -163,13 +162,9 @@ typedef struct {
} SM2_SIGNATURE; } SM2_SIGNATURE;
int sm2_do_sign(const SM2_KEY *key, const uint8_t dgst[32], SM2_SIGNATURE *sig); int sm2_do_sign(const SM2_KEY *key, const uint8_t dgst[32], SM2_SIGNATURE *sig);
int sm2_do_sign_fast(const uint64_t d[4], const uint8_t dgst[32], SM2_SIGNATURE *sig);
int sm2_do_verify(const SM2_KEY *key, const uint8_t dgst[32], const SM2_SIGNATURE *sig); int sm2_do_verify(const SM2_KEY *key, const uint8_t dgst[32], const SM2_SIGNATURE *sig);
int sm2_do_sign_pre_compute(uint64_t k[4], uint64_t x1[4]);
int sm2_do_sign_fast_ex(const uint64_t d[4], const uint64_t k[4], const uint64_t x1[4], const uint8_t dgst[32], SM2_SIGNATURE *sig);
int sm2_do_verify_fast(const SM2_Z256_POINT *P, const uint8_t dgst[32], const SM2_SIGNATURE *sig);
#define SM2_MIN_SIGNATURE_SIZE 8 #define SM2_MIN_SIGNATURE_SIZE 8
@@ -203,20 +198,23 @@ typedef struct {
uint64_t x1[4]; uint64_t x1[4];
} SM2_SIGN_PRE_COMP; } SM2_SIGN_PRE_COMP;
typedef struct { typedef struct {
SM3_CTX sm3_ctx; SM3_CTX sm3_ctx;
SM2_KEY key; SM2_KEY key;
// FIXME: change `key` to SM2_Z256_POINT and uint64_t[4], inner type, faster sign/verify // FIXME: change `key` to SM2_Z256_POINT and uint64_t[4], inner type, faster sign/verify
SM2_Z256_POINT public_key; // z256 only uint64_t public_key[3][8]; // enough to hold point in Jacobian format
uint64_t sign_key[8]; // u64[8] to support SM2_BN uint64_t sign_key[8]; // u64[8] to support SM2_BN
SM3_CTX inited_sm3_ctx; SM3_CTX inited_sm3_ctx;
SM2_SIGN_PRE_COMP pre_comp[32]; SM2_SIGN_PRE_COMP pre_comp[32];
unsigned int num_pre_comp; unsigned int num_pre_comp;
} SM2_SIGN_CTX; } SM2_SIGN_CTX;
_gmssl_export int sm2_sign_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen); _gmssl_export int sm2_sign_init(SM2_SIGN_CTX *ctx, const SM2_KEY *key, const char *id, size_t idlen);
_gmssl_export int sm2_sign_update(SM2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen); _gmssl_export int sm2_sign_update(SM2_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);
_gmssl_export int sm2_sign_finish(SM2_SIGN_CTX *ctx, uint8_t *sig, size_t *siglen); _gmssl_export int sm2_sign_finish(SM2_SIGN_CTX *ctx, uint8_t *sig, size_t *siglen);

View File

@@ -15,6 +15,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <gmssl/sm2.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@@ -134,6 +135,13 @@ int sm2_z256_point_from_hash(SM2_Z256_POINT *R, const uint8_t *data, size_t data
int sm2_z256_point_from_octets(SM2_Z256_POINT *P, const uint8_t *in, size_t inlen); int sm2_z256_point_from_octets(SM2_Z256_POINT *P, const uint8_t *in, size_t inlen);
// 这些函数的问题是依赖于sm2.h 这些接口的,最好是不要有这些依赖
// 这些接口和底层的SM2曲线实现是相关的
int sm2_do_sign_fast(const uint64_t d[4], const uint8_t dgst[32], SM2_SIGNATURE *sig);
int sm2_do_sign_pre_compute(uint64_t k[4], uint64_t x1[4]);
int sm2_do_sign_fast_ex(const uint64_t d[4], const uint64_t k[4], const uint64_t x1[4], const uint8_t dgst[32], SM2_SIGNATURE *sig);
int sm2_do_verify_fast(const SM2_Z256_POINT *P, const uint8_t dgst[32], const SM2_SIGNATURE *sig);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,691 +0,0 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#include <string.h>
#include <gmssl/sm2.h>
#include <gmssl/oid.h>
#include <gmssl/asn1.h>
#include <gmssl/pem.h>
#include <gmssl/sm4.h>
#include <gmssl/rand.h>
#include <gmssl/pbkdf2.h>
#include <gmssl/pkcs8.h>
#include <gmssl/error.h>
#include <gmssl/ec.h>
#include <gmssl/mem.h>
#include <gmssl/x509_alg.h>
extern const SM2_BN SM2_N;
int sm2_key_generate(SM2_KEY *key)
{
SM2_BN x;
SM2_BN y;
SM2_JACOBIAN_POINT _P, *P = &_P;
if (!key) {
error_print();
return -1;
}
memset(key, 0, sizeof(SM2_KEY));
do {
if (sm2_bn_rand_range(x, SM2_N) != 1) {
error_print();
return -1;
}
} while (sm2_bn_is_zero(x));
sm2_bn_to_bytes(x, key->private_key);
sm2_jacobian_point_mul_generator(P, x);
sm2_jacobian_point_get_xy(P, x, y);
sm2_bn_to_bytes(x, key->public_key.x);
sm2_bn_to_bytes(y, key->public_key.y);
return 1;
}
int sm2_key_set_private_key(SM2_KEY *key, const uint8_t private_key[32])
{
SM2_BN bn;
sm2_bn_from_bytes(bn, private_key);
if (sm2_bn_is_zero(bn)
|| sm2_bn_cmp(bn, SM2_N) >= 0) {
gmssl_secure_clear(bn, sizeof(bn));
error_print();
return -1;
}
memcpy(&key->private_key, private_key, 32);
if (sm2_point_mul_generator(&key->public_key, private_key) != 1) {
gmssl_secure_clear(bn, sizeof(bn));
gmssl_secure_clear(key, sizeof(SM2_KEY));
error_print();
return -1;
}
gmssl_secure_clear(bn, sizeof(bn));
return 1;
}
int sm2_key_set_public_key(SM2_KEY *key, const SM2_POINT *public_key)
{
if (!key || !public_key) {
error_print();
return -1;
}
if (sm2_point_is_on_curve(public_key) != 1) {
error_print();
return -1;
}
gmssl_secure_clear(key, sizeof(SM2_KEY));
key->public_key = *public_key;
return 1;
}
int sm2_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *key)
{
format_print(fp, fmt, ind, "%s\n", label);
ind += 4;
sm2_public_key_print(fp, fmt, ind, "publicKey", key);
format_bytes(fp, fmt, ind, "privateKey", key->private_key, 32);
return 1;
}
int sm2_public_key_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen)
{
uint8_t buf[65];
size_t len = 0;
if (!key) {
return 0;
}
sm2_point_to_uncompressed_octets(&key->public_key, buf);
if (asn1_bit_octets_to_der(buf, sizeof(buf), out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
int sm2_public_key_from_der(SM2_KEY *key, const uint8_t **in, size_t *inlen)
{
int ret;
const uint8_t *d;
size_t dlen;
SM2_POINT P;
if ((ret = asn1_bit_octets_from_der(&d, &dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (dlen != 65) {
error_print();
return -1;
}
if (sm2_point_from_octets(&P, d, dlen) != 1
|| sm2_key_set_public_key(key, &P) != 1) {
error_print();
return -1;
}
return 1;
}
int sm2_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *pub_key)
{
return sm2_point_print(fp, fmt, ind, label, &pub_key->public_key);
}
int sm2_public_key_algor_to_der(uint8_t **out, size_t *outlen)
{
if (x509_public_key_algor_to_der(OID_ec_public_key, OID_sm2, out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
int sm2_public_key_algor_from_der(const uint8_t **in, size_t *inlen)
{
int ret;
int oid;
int curve;
if ((ret = x509_public_key_algor_from_der(&oid, &curve, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (oid != OID_ec_public_key) {
error_print();
return -1;
}
if (curve != OID_sm2) {
error_print();
return -1;
}
return 1;
}
#define SM2_PRIVATE_KEY_DER_SIZE 121
int sm2_private_key_to_der(const SM2_KEY *key, uint8_t **out, size_t *outlen)
{
size_t len = 0;
uint8_t params[64];
uint8_t pubkey[128];
uint8_t *params_ptr = params;
uint8_t *pubkey_ptr = pubkey;
size_t params_len = 0;
size_t pubkey_len = 0;
if (!key) {
error_print();
return -1;
}
if (ec_named_curve_to_der(OID_sm2, &params_ptr, &params_len) != 1
|| sm2_public_key_to_der(key, &pubkey_ptr, &pubkey_len) != 1) {
error_print();
return -1;
}
if (asn1_int_to_der(EC_private_key_version, NULL, &len) != 1
|| asn1_octet_string_to_der(key->private_key, 32, NULL, &len) != 1
|| asn1_explicit_to_der(0, params, params_len, NULL, &len) != 1
|| asn1_explicit_to_der(1, pubkey, pubkey_len, NULL, &len) != 1
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|| asn1_int_to_der(EC_private_key_version, out, outlen) != 1
|| asn1_octet_string_to_der(key->private_key, 32, out, outlen) != 1
|| asn1_explicit_to_der(0, params, params_len, out, outlen) != 1
|| asn1_explicit_to_der(1, pubkey, pubkey_len, out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
int sm2_private_key_from_der(SM2_KEY *key, const uint8_t **in, size_t *inlen)
{
int ret;
const uint8_t *d;
size_t dlen;
int ver;
const uint8_t *prikey;
const uint8_t *params;
const uint8_t *pubkey;
size_t prikey_len, params_len, pubkey_len;
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (asn1_int_from_der(&ver, &d, &dlen) != 1
|| asn1_octet_string_from_der(&prikey, &prikey_len, &d, &dlen) != 1
|| asn1_explicit_from_der(0, &params, &params_len, &d, &dlen) != 1
|| asn1_explicit_from_der(1, &pubkey, &pubkey_len, &d, &dlen) != 1
|| asn1_check(ver == EC_private_key_version) != 1
|| asn1_length_is_zero(dlen) != 1) {
error_print();
return -1;
}
if (params) {
int curve;
if (ec_named_curve_from_der(&curve, &params, &params_len) != 1
|| asn1_check(curve == OID_sm2) != 1
|| asn1_length_is_zero(params_len) != 1) {
error_print();
return -1;
}
}
if (asn1_check(prikey_len == 32) != 1
|| sm2_key_set_private_key(key, prikey) != 1) {
error_print();
return -1;
}
// check if the public key is correct
if (pubkey) {
SM2_KEY tmp_key;
if (sm2_public_key_from_der(&tmp_key, &pubkey, &pubkey_len) != 1
|| asn1_length_is_zero(pubkey_len) != 1) {
error_print();
return -1;
}
if (sm2_public_key_equ(key, &tmp_key) != 1) {
error_print();
return -1;
}
}
return 1;
}
int sm2_private_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
{
return ec_private_key_print(fp, fmt, ind, label, d, dlen);
}
#define SM2_PRIVATE_KEY_INFO_DER_SIZE 150
int sm2_private_key_info_to_der(const SM2_KEY *sm2_key, uint8_t **out, size_t *outlen)
{
size_t len = 0;
uint8_t prikey[SM2_PRIVATE_KEY_DER_SIZE];
uint8_t *p = prikey;
size_t prikey_len = 0;
if (sm2_private_key_to_der(sm2_key, &p, &prikey_len) != 1) {
error_print();
return -1;
}
if (asn1_int_to_der(PKCS8_private_key_info_version, NULL, &len) != 1
|| sm2_public_key_algor_to_der(NULL, &len) != 1
|| asn1_octet_string_to_der(prikey, prikey_len, NULL, &len) != 1
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|| asn1_int_to_der(PKCS8_private_key_info_version, out, outlen) != 1
|| sm2_public_key_algor_to_der(out, outlen) != 1
|| asn1_octet_string_to_der(prikey, prikey_len, out, outlen) != 1) {
memset(prikey, 0, sizeof(prikey));
error_print();
return -1;
}
memset(prikey, 0, sizeof(prikey));
return 1;
}
int sm2_private_key_info_from_der(SM2_KEY *sm2_key, const uint8_t **attrs, size_t *attrslen,
const uint8_t **in, size_t *inlen)
{
int ret;
const uint8_t *d;
size_t dlen;
int version;
const uint8_t *prikey;
size_t prikey_len;
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (asn1_int_from_der(&version, &d, &dlen) != 1
|| sm2_public_key_algor_from_der(&d, &dlen) != 1
|| asn1_octet_string_from_der(&prikey, &prikey_len, &d, &dlen) != 1
|| asn1_implicit_set_from_der(0, attrs, attrslen, &d, &dlen) < 0
|| asn1_length_is_zero(dlen) != 1) {
error_print();
return -1;
}
if (asn1_check(version == PKCS8_private_key_info_version) != 1
|| sm2_private_key_from_der(sm2_key, &prikey, &prikey_len) != 1
|| asn1_length_is_zero(prikey_len) != 1) {
error_print();
return -1;
}
return 1;
}
int sm2_private_key_info_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen)
{
int ret;
const uint8_t *p;
size_t len;
int val;
const uint8_t *prikey;
size_t prikey_len;
format_print(fp, fmt, ind, "%s\n", label);
ind += 4;
if (asn1_int_from_der(&val, &d, &dlen) != 1) goto err;
format_print(fp, fmt, ind, "version: %d\n", val);
if (asn1_sequence_from_der(&p, &len, &d, &dlen) != 1) goto err;
x509_public_key_algor_print(fp, fmt, ind, "privateKeyAlgorithm", p, len);
if (asn1_octet_string_from_der(&p, &len, &d, &dlen) != 1) goto err;
if (asn1_sequence_from_der(&prikey, &prikey_len, &p, &len) != 1) goto err;
ec_private_key_print(fp, fmt, ind + 4, "privateKey", prikey, prikey_len);
if (asn1_length_is_zero(len) != 1) goto err;
if ((ret = asn1_implicit_set_from_der(0, &p, &len, &d, &dlen)) < 0) goto err;
else if (ret) format_bytes(fp, fmt, ind, "attributes", p, len);
if (asn1_length_is_zero(dlen) != 1) goto err;
return 1;
err:
error_print();
return -1;
}
#ifdef ENABLE_SM2_PRIVATE_KEY_EXPORT
int sm2_private_key_info_to_pem(const SM2_KEY *key, FILE *fp)
{
int ret = -1;
uint8_t buf[SM2_PRIVATE_KEY_INFO_DER_SIZE];
uint8_t *p = buf;
size_t len = 0;
if (!key || !fp) {
error_print();
return -1;
}
if (sm2_private_key_info_to_der(key, &p, &len) != 1) {
error_print();
goto end;
}
if (len != sizeof(buf)) {
error_print();
goto end;
}
if (pem_write(fp, "PRIVATE KEY", buf, len) != 1) {
error_print();
goto end;
}
ret = 1;
end:
gmssl_secure_clear(buf, sizeof(buf));
return ret;
}
int sm2_private_key_info_from_pem(SM2_KEY *sm2_key, FILE *fp)
{
uint8_t buf[512];
const uint8_t *cp = buf;
size_t len;
const uint8_t *attrs;
size_t attrs_len;
if (pem_read(fp, "PRIVATE KEY", buf, &len, sizeof(buf)) != 1
|| sm2_private_key_info_from_der(sm2_key, &attrs, &attrs_len, &cp, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
if (attrs_len) {
error_print();
}
return 1;
}
#endif
int sm2_public_key_info_to_der(const SM2_KEY *pub_key, uint8_t **out, size_t *outlen)
{
size_t len = 0;
if (sm2_public_key_algor_to_der(NULL, &len) != 1
|| sm2_public_key_to_der(pub_key, NULL, &len) != 1
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|| sm2_public_key_algor_to_der(out, outlen) != 1
|| sm2_public_key_to_der(pub_key, out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
int sm2_public_key_info_from_der(SM2_KEY *pub_key, const uint8_t **in, size_t *inlen)
{
int ret;
const uint8_t *d;
size_t dlen;
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (sm2_public_key_algor_from_der(&d, &dlen) != 1
|| sm2_public_key_from_der(pub_key, &d, &dlen) != 1
|| asn1_length_is_zero(dlen) != 1) {
error_print();
return -1;
}
return 1;
}
#ifdef ENABLE_SM2_PRIVATE_KEY_EXPORT
// FIXME: side-channel of Base64
int sm2_private_key_to_pem(const SM2_KEY *a, FILE *fp)
{
uint8_t buf[512];
uint8_t *p = buf;
size_t len = 0;
if (sm2_private_key_to_der(a, &p, &len) != 1) {
error_print();
return -1;
}
if (pem_write(fp, "EC PRIVATE KEY", buf, len) <= 0) {
error_print();
return -1;
}
return 1;
}
int sm2_private_key_from_pem(SM2_KEY *a, FILE *fp)
{
uint8_t buf[512];
const uint8_t *cp = buf;
size_t len;
if (pem_read(fp, "EC PRIVATE KEY", buf, &len, sizeof(buf)) != 1) {
error_print();
return -1;
}
if (sm2_private_key_from_der(a, &cp, &len) != 1
|| len > 0) {
error_print();
return -1;
}
return 1;
}
#endif
int sm2_public_key_info_to_pem(const SM2_KEY *a, FILE *fp)
{
uint8_t buf[512];
uint8_t *p = buf;
size_t len = 0;
if (sm2_public_key_info_to_der(a, &p, &len) != 1) {
error_print();
return -1;
}
if (pem_write(fp, "PUBLIC KEY", buf, len) <= 0) {
error_print();
return -1;
}
return 1;
}
int sm2_public_key_info_from_pem(SM2_KEY *a, FILE *fp)
{
uint8_t buf[512];
const uint8_t *cp = buf;
size_t len;
if (pem_read(fp, "PUBLIC KEY", buf, &len, sizeof(buf)) != 1) {
error_print();
return -1;
}
if (sm2_public_key_info_from_der(a, &cp, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
return 1;
}
int sm2_public_key_equ(const SM2_KEY *sm2_key, const SM2_KEY *pub_key)
{
if (memcmp(sm2_key, pub_key, sizeof(SM2_POINT)) == 0) {
return 1;
}
return 0;
}
int sm2_public_key_copy(SM2_KEY *sm2_key, const SM2_KEY *pub_key)
{
return sm2_key_set_public_key(sm2_key, &pub_key->public_key);
}
int sm2_public_key_digest(const SM2_KEY *sm2_key, uint8_t dgst[32])
{
uint8_t bits[65];
sm2_point_to_uncompressed_octets(&sm2_key->public_key, bits);
sm3_digest(bits, sizeof(bits), dgst);
return 1;
}
int sm2_private_key_info_encrypt_to_der(const SM2_KEY *sm2_key, const char *pass,
uint8_t **out, size_t *outlen)
{
int ret = -1;
uint8_t pkey_info[SM2_PRIVATE_KEY_INFO_DER_SIZE];
uint8_t *p = pkey_info;
size_t pkey_info_len = 0;
uint8_t salt[16];
int iter = 65536;
uint8_t iv[16];
uint8_t key[16];
SM4_KEY sm4_key;
uint8_t enced_pkey_info[sizeof(pkey_info) + 32];
size_t enced_pkey_info_len;
if (!sm2_key || !pass || !outlen) {
error_print();
return -1;
}
if (sm2_private_key_info_to_der(sm2_key, &p, &pkey_info_len) != 1
|| rand_bytes(salt, sizeof(salt)) != 1
|| rand_bytes(iv, sizeof(iv)) != 1
|| pbkdf2_genkey(DIGEST_sm3(), pass, strlen(pass),
salt, sizeof(salt), iter, sizeof(key), key) != 1) {
error_print();
goto end;
}
/*
if (pkey_info_len != sizeof(pkey_info)) {
error_print();
goto end;
}
*/
sm4_set_encrypt_key(&sm4_key, key);
if (sm4_cbc_padding_encrypt(
&sm4_key, iv, pkey_info, pkey_info_len,
enced_pkey_info, &enced_pkey_info_len) != 1
|| pkcs8_enced_private_key_info_to_der(
salt, sizeof(salt), iter, sizeof(key), OID_hmac_sm3,
OID_sm4_cbc, iv, sizeof(iv),
enced_pkey_info, enced_pkey_info_len, out, outlen) != 1) {
error_print();
goto end;
}
ret = 1;
end:
gmssl_secure_clear(pkey_info, sizeof(pkey_info));
gmssl_secure_clear(key, sizeof(key));
gmssl_secure_clear(&sm4_key, sizeof(sm4_key));
return ret;
}
int sm2_private_key_info_decrypt_from_der(SM2_KEY *sm2,
const uint8_t **attrs, size_t *attrs_len,
const char *pass, const uint8_t **in, size_t *inlen)
{
int ret = -1;
const uint8_t *salt;
size_t saltlen;
int iter;
int keylen;
int prf;
int cipher;
const uint8_t *iv;
size_t ivlen;
uint8_t key[16];
SM4_KEY sm4_key;
const uint8_t *enced_pkey_info;
size_t enced_pkey_info_len;
uint8_t pkey_info[256];
const uint8_t *cp = pkey_info;
size_t pkey_info_len;
if (!sm2 || !attrs || !attrs_len || !pass || !in || !(*in) || !inlen) {
error_print();
return -1;
}
if (pkcs8_enced_private_key_info_from_der(&salt, &saltlen, &iter, &keylen, &prf,
&cipher, &iv, &ivlen, &enced_pkey_info, &enced_pkey_info_len, in, inlen) != 1
|| asn1_check(keylen == -1 || keylen == 16) != 1
|| asn1_check(prf == - 1 || prf == OID_hmac_sm3) != 1
|| asn1_check(cipher == OID_sm4_cbc) != 1
|| asn1_check(ivlen == 16) != 1
|| asn1_length_le(enced_pkey_info_len, sizeof(pkey_info)) != 1) {
error_print();
return -1;
}
if (pbkdf2_genkey(DIGEST_sm3(), pass, strlen(pass), salt, saltlen, iter, sizeof(key), key) != 1) {
error_print();
goto end;
}
sm4_set_decrypt_key(&sm4_key, key);
if (sm4_cbc_padding_decrypt(&sm4_key, iv, enced_pkey_info, enced_pkey_info_len,
pkey_info, &pkey_info_len) != 1
|| sm2_private_key_info_from_der(sm2, attrs, attrs_len, &cp, &pkey_info_len) != 1
|| asn1_length_is_zero(pkey_info_len) != 1) {
error_print();
goto end;
}
ret = 1;
end:
gmssl_secure_clear(&sm4_key, sizeof(sm4_key));
gmssl_secure_clear(key, sizeof(key));
gmssl_secure_clear(pkey_info, sizeof(pkey_info));
return ret;
}
int sm2_private_key_info_encrypt_to_pem(const SM2_KEY *sm2_key, const char *pass, FILE *fp)
{
uint8_t buf[1024];
uint8_t *p = buf;
size_t len = 0;
if (!fp) {
error_print();
return -1;
}
if (sm2_private_key_info_encrypt_to_der(sm2_key, pass, &p, &len) != 1) {
error_print();
return -1;
}
if (pem_write(fp, "ENCRYPTED PRIVATE KEY", buf, len) != 1) {
error_print();
return -1;
}
return 1;
}
int sm2_private_key_info_decrypt_from_pem(SM2_KEY *key, const char *pass, FILE *fp)
{
uint8_t buf[512];
const uint8_t *cp = buf;
size_t len;
const uint8_t *attrs;
size_t attrs_len;
if (!key || !pass || !fp) {
error_print();
return -1;
}
if (pem_read(fp, "ENCRYPTED PRIVATE KEY", buf, &len, sizeof(buf)) != 1
|| sm2_private_key_info_decrypt_from_der(key, &attrs, &attrs_len, pass, &cp, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
return 1;
}

View File

@@ -1,282 +0,0 @@
/*
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <gmssl/sm2.h>
#include <gmssl/sm2_z256.h>
#include <gmssl/mem.h>
#include <gmssl/asn1.h>
#include <gmssl/rand.h>
#include <gmssl/error.h>
#include <gmssl/endian.h>
int sm2_point_is_on_curve(const SM2_POINT *P)
{
SM2_Z256_POINT T;
sm2_z256_point_from_bytes(&T, (const uint8_t *)P);
if (sm2_z256_point_is_on_curve(&T) == 1) {
return 1;
} else {
return 0;
}
}
int sm2_point_is_at_infinity(const SM2_POINT *P)
{
return mem_is_zero((uint8_t *)P, sizeof(SM2_POINT));
}
int sm2_point_from_x(SM2_POINT *P, const uint8_t x[32], int y_is_odd)
{
SM2_Z256_POINT T;
if (sm2_z256_point_from_x_bytes(&T, x, y_is_odd) != 1) {
error_print();
return -1;
}
sm2_z256_point_to_bytes(&T, (uint8_t *)P);
return 1;
}
int sm2_point_from_xy(SM2_POINT *P, const uint8_t x[32], const uint8_t y[32])
{
memcpy(P->x, x, 32);
memcpy(P->y, y, 32);
return sm2_point_is_on_curve(P);
}
int sm2_point_add(SM2_POINT *R, const SM2_POINT *P, const SM2_POINT *Q)
{
SM2_Z256_POINT P_;
SM2_Z256_POINT Q_;
sm2_z256_point_from_bytes(&P_, (uint8_t *)P);
sm2_z256_point_from_bytes(&Q_, (uint8_t *)Q);
sm2_z256_point_add(&P_, &P_, &Q_);
sm2_z256_point_to_bytes(&P_, (uint8_t *)R);
return 1;
}
int sm2_point_sub(SM2_POINT *R, const SM2_POINT *P, const SM2_POINT *Q)
{
SM2_Z256_POINT P_;
SM2_Z256_POINT Q_;
sm2_z256_point_from_bytes(&P_, (uint8_t *)P);
sm2_z256_point_from_bytes(&Q_, (uint8_t *)Q);
sm2_z256_point_sub(&P_, &P_, &Q_);
sm2_z256_point_to_bytes(&P_, (uint8_t *)R);
return 1;
}
int sm2_point_neg(SM2_POINT *R, const SM2_POINT *P)
{
SM2_Z256_POINT P_;
sm2_z256_point_from_bytes(&P_, (uint8_t *)P);
sm2_z256_point_neg(&P_, &P_);
sm2_z256_point_to_bytes(&P_, (uint8_t *)R);
return 1;
}
int sm2_point_dbl(SM2_POINT *R, const SM2_POINT *P)
{
SM2_Z256_POINT P_;
sm2_z256_point_from_bytes(&P_, (uint8_t *)P);
sm2_z256_point_dbl(&P_, &P_);
sm2_z256_point_to_bytes(&P_, (uint8_t *)R);
return 1;
}
int sm2_point_mul(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P)
{
uint64_t _k[4];
SM2_Z256_POINT _P;
sm2_z256_from_bytes(_k, k);
sm2_z256_point_from_bytes(&_P, (uint8_t *)P);
sm2_z256_point_mul(&_P, _k, &_P);
sm2_z256_point_to_bytes(&_P, (uint8_t *)R);
memset(_k, 0, sizeof(_k));
return 1;
}
int sm2_point_mul_generator(SM2_POINT *R, const uint8_t k[32])
{
uint64_t _k[4];
SM2_Z256_POINT _R;
sm2_z256_from_bytes(_k, k);
sm2_z256_point_mul_generator(&_R, _k);
sm2_z256_point_to_bytes(&_R, (uint8_t *)R);
memset(_k, 0, sizeof(_k));
return 1;
}
int sm2_point_mul_sum(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P, const uint8_t s[32])
{
uint64_t _k[4];
SM2_Z256_POINT _P;
uint64_t _s[4];
sm2_z256_from_bytes(_k, k);
sm2_z256_point_from_bytes(&_P, (uint8_t *)P);
sm2_z256_from_bytes(_s, s);
sm2_z256_point_mul_sum(&_P, _k, &_P, _s);
sm2_z256_point_to_bytes(&_P, (uint8_t *)R);
memset(_k, 0, sizeof(_k));
memset(_s, 0, sizeof(_s));
return 1;
}
int sm2_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_POINT *P)
{
format_print(fp, fmt, ind, "%s\n", label);
ind += 4;
format_bytes(fp, fmt, ind, "x", P->x, 32);
format_bytes(fp, fmt, ind, "y", P->y, 32);
return 1;
}
void sm2_point_to_compressed_octets(const SM2_POINT *P, uint8_t out[33])
{
*out++ = (P->y[31] & 0x01) ? 0x03 : 0x02;
memcpy(out, P->x, 32);
}
void sm2_point_to_uncompressed_octets(const SM2_POINT *P, uint8_t out[65])
{
*out++ = 0x04;
memcpy(out, P, 64);
}
int sm2_z256_point_from_octets(SM2_Z256_POINT *P, const uint8_t *in, size_t inlen)
{
switch (*in) {
case SM2_point_at_infinity:
if (inlen != 1) {
error_print();
return -1;
}
sm2_z256_point_set_infinity(P);
break;
case SM2_point_compressed_y_even:
if (inlen != 33) {
error_print();
return -1;
}
if (sm2_z256_point_from_x_bytes(P, in + 1, 0) != 1) {
error_print();
return -1;
}
break;
case SM2_point_compressed_y_odd:
if (inlen != 33) {
error_print();
return -1;
}
if (sm2_z256_point_from_x_bytes(P, in + 1, 1) != 1) {
error_print();
return -1;
}
break;
case SM2_point_uncompressed:
if (inlen != 65) {
error_print();
return -1;
}
sm2_z256_point_from_bytes(P, in + 1);
if (sm2_z256_point_is_on_curve(P) != 1) {
error_print();
return -1;
}
break;
default:
error_print();
return -1;
}
return 1;
}
int sm2_point_from_octets(SM2_POINT *P, const uint8_t *in, size_t inlen)
{
if ((*in == 0x02 || *in == 0x03) && inlen == 33) {
if (sm2_point_from_x(P, in + 1, *in) != 1) {
error_print();
return -1;
}
} else if (*in == 0x04 && inlen == 65) {
if (sm2_point_from_xy(P, in + 1, in + 33) != 1) {
error_print();
return -1;
}
} else {
error_print();
return -1;
}
return 1;
}
int sm2_point_to_der(const SM2_POINT *P, uint8_t **out, size_t *outlen)
{
uint8_t octets[65];
if (!P) {
return 0;
}
sm2_point_to_uncompressed_octets(P, octets);
if (asn1_octet_string_to_der(octets, sizeof(octets), out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
int sm2_point_from_der(SM2_POINT *P, const uint8_t **in, size_t *inlen)
{
int ret;
const uint8_t *d;
size_t dlen;
if ((ret = asn1_octet_string_from_der(&d, &dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (dlen != 65) {
error_print();
return -1;
}
if (sm2_point_from_octets(P, d, dlen) != 1) {
error_print();
return -1;
}
return 1;
}
int sm2_point_from_hash(SM2_POINT *R, const uint8_t *data, size_t datalen)
{
return 1;
}

View File

@@ -1,425 +0,0 @@
/*
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gmssl/mem.h>
#include <gmssl/sm2.h>
#include <gmssl/sm3.h>
#include <gmssl/asn1.h>
#include <gmssl/error.h>
#include <gmssl/endian.h>
int sm2_do_sign(const SM2_KEY *key, const uint8_t dgst[32], SM2_SIGNATURE *sig)
{
SM2_JACOBIAN_POINT _P, *P = &_P;
SM2_BN d;
SM2_BN d_inv;
SM2_BN e;
SM2_BN k;
SM2_BN x;
SM2_BN t;
SM2_BN r;
SM2_BN s;
const uint64_t *one = sm2_bn_one();
const uint64_t *order = sm2_bn_order();
//fprintf(stderr, "sm2_do_sign\n");
sm2_bn_from_bytes(d, key->private_key);
// compute (d + 1)^-1 (mod n)
sm2_fn_add(d_inv, d, one); //sm2_bn_print(stderr, 0, 4, "(1+d)", d_inv);
if (sm2_bn_is_zero(d_inv)) {
error_print();
return -1;
}
sm2_fn_inv(d_inv, d_inv); //sm2_bn_print(stderr, 0, 4, "(1+d)^-1", d_inv);
// e = H(M)
sm2_bn_from_bytes(e, dgst); //sm2_bn_print(stderr, 0, 4, "e", e);
retry:
// rand k in [1, n - 1]
do {
if (sm2_fn_rand(k) != 1) {
error_print();
return -1;
}
} while (sm2_bn_is_zero(k)); //sm2_bn_print(stderr, 0, 4, "k", k);
// (x, y) = kG
sm2_jacobian_point_mul_generator(P, k);
sm2_jacobian_point_get_xy(P, x, NULL);
//sm2_bn_print(stderr, 0, 4, "x", x);
// r = e + x (mod n)
if (sm2_bn_cmp(e, order) >= 0) {
sm2_bn_sub(e, e, order);
}
if (sm2_bn_cmp(x, order) >= 0) {
sm2_bn_sub(x, x, order);
}
sm2_fn_add(r, e, x); //sm2_bn_print(stderr, 0, 4, "r = e + x (mod n)", r);
// if r == 0 or r + k == n re-generate k
sm2_bn_add(t, r, k);
if (sm2_bn_is_zero(r) || sm2_bn_cmp(t, order) == 0) {
//sm2_bn_print(stderr, 0, 4, "r + k", t);
goto retry;
}
// s = ((1 + d)^-1 * (k - r * d)) mod n
sm2_fn_mul(t, r, d); //sm2_bn_print(stderr, 0, 4, "r*d", t);
sm2_fn_sub(k, k, t); //sm2_bn_print(stderr, 0, 4, "k-r*d", k);
sm2_fn_mul(s, d_inv, k); //sm2_bn_print(stderr, 0, 4, "s = ((1 + d)^-1 * (k - r * d)) mod n", s);
// check s != 0
if (sm2_bn_is_zero(s)) {
goto retry;
}
sm2_bn_to_bytes(r, sig->r); //sm2_bn_print_bn(stderr, 0, 4, "r", r);
sm2_bn_to_bytes(s, sig->s); //sm2_bn_print_bn(stderr, 0, 4, "s", s);
gmssl_secure_clear(d, sizeof(d));
gmssl_secure_clear(d_inv, sizeof(d_inv ));
gmssl_secure_clear(k, sizeof(k));
gmssl_secure_clear(t, sizeof(t));
return 1;
}
// (x1, y1) = k * G
// r = e + x1
// s = (k - r * d)/(1 + d) = (k +r - r * d - r)/(1 + d) = (k + r - r(1 +d))/(1 + d) = (k + r)/(1 + d) - r
// = -r + (k + r)*(1 + d)^-1
// = -r + (k + r) * d'
int sm2_do_sign_fast(const SM2_Fn d, const uint8_t dgst[32], SM2_SIGNATURE *sig)
{
SM2_JACOBIAN_POINT R;
SM2_BN e;
SM2_BN k;
SM2_BN x1;
SM2_BN r;
SM2_BN s;
const uint64_t *order = sm2_bn_order();
// e = H(M)
sm2_bn_from_bytes(e, dgst);
if (sm2_bn_cmp(e, order) >= 0) {
sm2_bn_sub(e, e, order);
}
// rand k in [1, n - 1]
do {
if (sm2_fn_rand(k) != 1) {
error_print();
return -1;
}
} while (sm2_bn_is_zero(k));
// (x1, y1) = kG
sm2_jacobian_point_mul_generator(&R, k);
sm2_jacobian_point_get_xy(&R, x1, NULL);
// r = e + x1 (mod n)
sm2_fn_add(r, e, x1);
// s = (k + r) * d' - r
sm2_bn_add(s, k, r);
sm2_fn_mul(s, s, d);
sm2_fn_sub(s, s, r);
sm2_bn_to_bytes(r, sig->r);
sm2_bn_to_bytes(s, sig->s);
return 1;
}
int sm2_do_verify(const SM2_KEY *key, const uint8_t dgst[32], const SM2_SIGNATURE *sig)
{
SM2_JACOBIAN_POINT _P, *P = &_P;
SM2_JACOBIAN_POINT _R, *R = &_R;
SM2_BN r;
SM2_BN s;
SM2_BN e;
SM2_BN x;
SM2_BN t;
const uint64_t *order = sm2_bn_order();
// parse public key
sm2_jacobian_point_from_bytes(P, (const uint8_t *)&key->public_key);
//sm2_jacobian_point_print(stderr, 0, 4, "P", P);
// parse signature values
sm2_bn_from_bytes(r, sig->r); //sm2_bn_print(stderr, 0, 4, "r", r);
sm2_bn_from_bytes(s, sig->s); //sm2_bn_print(stderr, 0, 4, "s", s);
// check r, s in [1, n-1]
if (sm2_bn_is_zero(r) == 1
|| sm2_bn_cmp(r, order) >= 0
|| sm2_bn_is_zero(s) == 1
|| sm2_bn_cmp(s, order) >= 0) {
error_print();
return -1;
}
// e = H(M)
sm2_bn_from_bytes(e, dgst); //sm2_bn_print(stderr, 0, 4, "e = H(M)", e);
// t = r + s (mod n), check t != 0
sm2_fn_add(t, r, s); //sm2_bn_print(stderr, 0, 4, "t = r + s (mod n)", t);
if (sm2_bn_is_zero(t)) {
error_print();
return -1;
}
// Q = s * G + t * P
sm2_jacobian_point_mul_sum(R, t, P, s);
sm2_jacobian_point_get_xy(R, x, NULL);
//sm2_bn_print(stderr, 0, 4, "x", x);
// r' = e + x (mod n)
if (sm2_bn_cmp(e, order) >= 0) {
sm2_bn_sub(e, e, order);
}
if (sm2_bn_cmp(x, order) >= 0) {
sm2_bn_sub(x, x, order);
}
sm2_fn_add(e, e, x); //sm2_bn_print(stderr, 0, 4, "e + x (mod n)", e);
// check if r == r'
if (sm2_bn_cmp(e, r) != 0) {
error_print();
return -1;
}
return 1;
}
static int all_zero(const uint8_t *buf, size_t len)
{
size_t i;
for (i = 0; i < len; i++) {
if (buf[i]) {
return 0;
}
}
return 1;
}
int sm2_do_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out)
{
SM2_BN k;
SM2_JACOBIAN_POINT _P, *P = &_P;
SM2_JACOBIAN_POINT _C1, *C1 = &_C1;
SM2_JACOBIAN_POINT _kP, *kP = &_kP;
uint8_t x2y2[64];
SM3_CTX sm3_ctx;
if (!(SM2_MIN_PLAINTEXT_SIZE <= inlen && inlen <= SM2_MAX_PLAINTEXT_SIZE)) {
error_print();
return -1;
}
sm2_jacobian_point_from_bytes(P, (uint8_t *)&key->public_key);
// S = h * P, check S != O
// for sm2 curve, h == 1 and S == P
// SM2_POINT can not present point at infinity, do do nothing here
retry:
// rand k in [1, n - 1]
do {
if (sm2_fn_rand(k) != 1) {
error_print();
return -1;
}
} while (sm2_bn_is_zero(k)); //sm2_bn_print(stderr, 0, 4, "k", k);
// output C1 = k * G = (x1, y1)
sm2_jacobian_point_mul_generator(C1, k);
sm2_jacobian_point_to_bytes(C1, (uint8_t *)&out->point);
// k * P = (x2, y2)
sm2_jacobian_point_mul(kP, k, P);
sm2_jacobian_point_to_bytes(kP, x2y2);
// t = KDF(x2 || y2, inlen)
sm2_kdf(x2y2, 64, inlen, out->ciphertext);
// if t is all zero, retry
if (all_zero(out->ciphertext, inlen)) {
goto retry;
}
// output C2 = M xor t
gmssl_memxor(out->ciphertext, out->ciphertext, in, inlen);
out->ciphertext_size = (uint32_t)inlen;
// output C3 = Hash(x2 || m || y2)
sm3_init(&sm3_ctx);
sm3_update(&sm3_ctx, x2y2, 32);
sm3_update(&sm3_ctx, in, inlen);
sm3_update(&sm3_ctx, x2y2 + 32, 32);
sm3_finish(&sm3_ctx, out->hash);
gmssl_secure_clear(k, sizeof(k));
gmssl_secure_clear(kP, sizeof(SM2_JACOBIAN_POINT));
gmssl_secure_clear(x2y2, sizeof(x2y2));
return 1;
}
int sm2_do_encrypt_fixlen(const SM2_KEY *key, const uint8_t *in, size_t inlen, int point_size, SM2_CIPHERTEXT *out)
{
unsigned int trys = 200;
SM2_BN k;
SM2_JACOBIAN_POINT _P, *P = &_P;
SM2_JACOBIAN_POINT _C1, *C1 = &_C1;
SM2_JACOBIAN_POINT _kP, *kP = &_kP;
uint8_t x2y2[64];
SM3_CTX sm3_ctx;
if (!(SM2_MIN_PLAINTEXT_SIZE <= inlen && inlen <= SM2_MAX_PLAINTEXT_SIZE)) {
error_print();
return -1;
}
switch (point_size) {
case SM2_ciphertext_compact_point_size:
case SM2_ciphertext_typical_point_size:
case SM2_ciphertext_max_point_size:
break;
default:
error_print();
return -1;
}
sm2_jacobian_point_from_bytes(P, (uint8_t *)&key->public_key);
// S = h * P, check S != O
// for sm2 curve, h == 1 and S == P
// SM2_POINT can not present point at infinity, do do nothing here
retry:
// rand k in [1, n - 1]
do {
if (sm2_fn_rand(k) != 1) {
error_print();
return -1;
}
} while (sm2_bn_is_zero(k)); //sm2_bn_print(stderr, 0, 4, "k", k);
// output C1 = k * G = (x1, y1)
sm2_jacobian_point_mul_generator(C1, k);
sm2_jacobian_point_to_bytes(C1, (uint8_t *)&out->point);
// check fixlen
if (trys) {
size_t len = 0;
asn1_integer_to_der(out->point.x, 32, NULL, &len);
asn1_integer_to_der(out->point.y, 32, NULL, &len);
if (len != point_size) {
trys--;
goto retry;
}
} else {
gmssl_secure_clear(k, sizeof(k));
error_print();
return -1;
}
// k * P = (x2, y2)
sm2_jacobian_point_mul(kP, k, P);
sm2_jacobian_point_to_bytes(kP, x2y2);
// t = KDF(x2 || y2, inlen)
sm2_kdf(x2y2, 64, inlen, out->ciphertext);
// if t is all zero, retry
if (all_zero(out->ciphertext, inlen)) {
goto retry;
}
// output C2 = M xor t
gmssl_memxor(out->ciphertext, out->ciphertext, in, inlen);
out->ciphertext_size = (uint32_t)inlen;
// output C3 = Hash(x2 || m || y2)
sm3_init(&sm3_ctx);
sm3_update(&sm3_ctx, x2y2, 32);
sm3_update(&sm3_ctx, in, inlen);
sm3_update(&sm3_ctx, x2y2 + 32, 32);
sm3_finish(&sm3_ctx, out->hash);
gmssl_secure_clear(k, sizeof(k));
gmssl_secure_clear(kP, sizeof(SM2_JACOBIAN_POINT));
gmssl_secure_clear(x2y2, sizeof(x2y2));
return 1;
}
int sm2_do_decrypt(const SM2_KEY *key, const SM2_CIPHERTEXT *in, uint8_t *out, size_t *outlen)
{
int ret = -1;
SM2_BN d;
SM2_JACOBIAN_POINT _C1, *C1 = &_C1;
uint8_t x2y2[64];
SM3_CTX sm3_ctx;
uint8_t hash[32];
// check C1 is on sm2 curve
sm2_jacobian_point_from_bytes(C1, (uint8_t *)&in->point);
if (!sm2_jacobian_point_is_on_curve(C1)) {
error_print();
return -1;
}
// check if S = h * C1 is point at infinity
// this will not happen, as SM2_POINT can not present point at infinity
// d * C1 = (x2, y2)
sm2_bn_from_bytes(d, key->private_key);
sm2_jacobian_point_mul(C1, d, C1);
// t = KDF(x2 || y2, klen) and check t is not all zeros
sm2_jacobian_point_to_bytes(C1, x2y2);
sm2_kdf(x2y2, 64, in->ciphertext_size, out);
if (all_zero(out, in->ciphertext_size)) {
error_print();
goto end;
}
// M = C2 xor t
gmssl_memxor(out, out, in->ciphertext, in->ciphertext_size);
*outlen = in->ciphertext_size;
// u = Hash(x2 || M || y2)
sm3_init(&sm3_ctx);
sm3_update(&sm3_ctx, x2y2, 32);
sm3_update(&sm3_ctx, out, in->ciphertext_size);
sm3_update(&sm3_ctx, x2y2 + 32, 32);
sm3_finish(&sm3_ctx, hash);
// check if u == C3
if (memcmp(in->hash, hash, sizeof(hash)) != 0) {
error_print();
goto end;
}
ret = 1;
end:
gmssl_secure_clear(d, sizeof(d));
gmssl_secure_clear(C1, sizeof(SM2_JACOBIAN_POINT));
gmssl_secure_clear(x2y2, sizeof(x2y2));
return ret;
}

View File

@@ -53,7 +53,7 @@
#include <gmssl/endian.h> #include <gmssl/endian.h>
#include <gmssl/sm2_z256.h> #include <gmssl/sm2_z256.h>
#include <gmssl/sm3.h> #include <gmssl/sm3.h>
#include <gmssl/asn1.h>
/* /*
SM2 parameters SM2 parameters
@@ -1054,6 +1054,7 @@ void sm2_z256_point_multi_dbl(SM2_Z256_POINT *R, const SM2_Z256_POINT *P, unsign
// A = Z1^2 // A = Z1^2
} }
#ifndef ENABLE_SM2_Z256_ARMV8
void sm2_z256_point_dbl(SM2_Z256_POINT *R, const SM2_Z256_POINT *A) void sm2_z256_point_dbl(SM2_Z256_POINT *R, const SM2_Z256_POINT *A)
{ {
const uint64_t *X1 = A->X; const uint64_t *X1 = A->X;
@@ -1069,58 +1070,75 @@ void sm2_z256_point_dbl(SM2_Z256_POINT *R, const SM2_Z256_POINT *A)
// S = 2*Y1 // S = 2*Y1
sm2_z256_modp_mul_by_2(S, Y1); sm2_z256_modp_mul_by_2(S, Y1);
sm2_z256_print(stderr, 0, 0, "1. S = 2*Y1", S);
// Zsqr = Z1^2 // Zsqr = Z1^2
sm2_z256_modp_mont_sqr(Zsqr, Z1); sm2_z256_modp_mont_sqr(Zsqr, Z1);
sm2_z256_print(stderr, 0, 0, "2. Zsqr = Z1^2", Zsqr);
// S = S^2 = 4*Y1^2 // S = S^2 = 4*Y1^2
sm2_z256_modp_mont_sqr(S, S); sm2_z256_modp_mont_sqr(S, S);
sm2_z256_print(stderr, 0, 0, "3. S = S^2 = 4*Y1^2", S);
// Z3 = Z1 * Y1 // Z3 = Z1 * Y1
sm2_z256_modp_mont_mul(Z3, Z1, Y1); sm2_z256_modp_mont_mul(Z3, Z1, Y1);
sm2_z256_print(stderr, 0, 0, "4. Z3 = Z1 * Y1", Z3);
// Z3 = 2 * Z3 = 2*Y1*Z1 // Z3 = 2 * Z3 = 2*Y1*Z1
sm2_z256_modp_mul_by_2(Z3, Z3); sm2_z256_modp_mul_by_2(Z3, Z3);
sm2_z256_print(stderr, 0, 0, "5. Z3 = 2 * Z3 = 2*Y1*Z1", Z3);
// M = X1 + Zsqr = X1 + Z1^2 // M = X1 + Zsqr = X1 + Z1^2
sm2_z256_modp_add(M, X1, Zsqr); sm2_z256_modp_add(M, X1, Zsqr);
sm2_z256_print(stderr, 0, 0, "6. M = X1 + Zsqr = X1 + Z1^2", M);
// Zsqr = X1 - Zsqr = X1 - Z1^2 // Zsqr = X1 - Zsqr = X1 - Z1^2
sm2_z256_modp_sub(Zsqr, X1, Zsqr); sm2_z256_modp_sub(Zsqr, X1, Zsqr);
sm2_z256_print(stderr, 0, 0, "7. Zsqr = X1 - Zsqr = X1 - Z1^2", Zsqr);
// Y3 = S^2 = 16 * Y1^4 // Y3 = S^2 = 16 * Y1^4
sm2_z256_modp_mont_sqr(Y3, S); sm2_z256_modp_mont_sqr(Y3, S);
sm2_z256_print(stderr, 0, 0, "8. Y3 = S^2 = 16 * Y1^4", Y3);
// Y3 = Y3/2 = 8 * Y1^4 // Y3 = Y3/2 = 8 * Y1^4
sm2_z256_modp_div_by_2(Y3, Y3); sm2_z256_modp_div_by_2(Y3, Y3);
sm2_z256_print(stderr, 0, 0, "9. Y3 = Y3/2 = 8 * Y1^4", Y3);
// M = M * Zsqr = (X1 + Z1^2)(X1 - Z1^2) // M = M * Zsqr = (X1 + Z1^2)(X1 - Z1^2)
sm2_z256_modp_mont_mul(M, M, Zsqr); sm2_z256_modp_mont_mul(M, M, Zsqr);
sm2_z256_print(stderr, 0, 0, "10. M = M * Zsqr = (X1 + Z1^2)(X1 - Z1^2)", M);
// M = 3*M = 3(X1 + Z1^2)(X1 - Z1^2) // M = 3*M = 3(X1 + Z1^2)(X1 - Z1^2)
sm2_z256_modp_mul_by_3(M, M); sm2_z256_modp_mul_by_3(M, M);
sm2_z256_print(stderr, 0, 0, "11. M = 3*M = 3(X1 + Z1^2)(X1 - Z1^2)", M);
// S = S * X1 = 4 * X1 * Y1^2 // S = S * X1 = 4 * X1 * Y1^2
sm2_z256_modp_mont_mul(S, S, X1); sm2_z256_modp_mont_mul(S, S, X1);
sm2_z256_print(stderr, 0, 0, "12. S = S * X1 = 4 * X1 * Y1^2", S);
// tmp0 = 2 * S = 8 * X1 * Y1^2 // tmp0 = 2 * S = 8 * X1 * Y1^2
sm2_z256_modp_mul_by_2(tmp0, S); sm2_z256_modp_mul_by_2(tmp0, S);
sm2_z256_print(stderr, 0, 0, "13. tmp0 = 2 * S = 8 * X1 * Y1^2", tmp0);
// X3 = M^2 = (3(X1 + Z1^2)(X1 - Z1^2))^2 // X3 = M^2 = (3(X1 + Z1^2)(X1 - Z1^2))^2
sm2_z256_modp_mont_sqr(X3, M); sm2_z256_modp_mont_sqr(X3, M);
sm2_z256_print(stderr, 0, 0, "14. X3 = M^2 = (3(X1 + Z1^2)(X1 - Z1^2))^2", X3);
// X3 = X3 - tmp0 = (3(X1 + Z1^2)(X1 - Z1^2))^2 - 8 * X1 * Y1^2 // X3 = X3 - tmp0 = (3(X1 + Z1^2)(X1 - Z1^2))^2 - 8 * X1 * Y1^2
sm2_z256_modp_sub(X3, X3, tmp0); sm2_z256_modp_sub(X3, X3, tmp0);
sm2_z256_print(stderr, 0, 0, "15. X3 = X3 - tmp0 = (3(X1 + Z1^2)(X1 - Z1^2))^2 - 8 * X1 * Y1^2", X3);
// S = S - X3 = 4 * X1 * Y1^2 - X3 // S = S - X3 = 4 * X1 * Y1^2 - X3
sm2_z256_modp_sub(S, S, X3); sm2_z256_modp_sub(S, S, X3);
sm2_z256_print(stderr, 0, 0, "16. S = S - X3 = 4 * X1 * Y1^2 - X3", S);
// S = S * M = 3(X1 + Z1^2)(X1 - Z1^2)(4 * X1 * Y1^2 - X3) // S = S * M = 3(X1 + Z1^2)(X1 - Z1^2)(4 * X1 * Y1^2 - X3)
sm2_z256_modp_mont_mul(S, S, M); sm2_z256_modp_mont_mul(S, S, M);
sm2_z256_print(stderr, 0, 0, "17. S = S * M", S);
// Y3 = S - Y3 = 3(X1 + Z1^2)(X1 - Z1^2)(4 * X1 * Y1^2 - X3) - 8 * Y1^4 // Y3 = S - Y3 = 3(X1 + Z1^2)(X1 - Z1^2)(4 * X1 * Y1^2 - X3) - 8 * Y1^4
sm2_z256_modp_sub(Y3, S, Y3); sm2_z256_modp_sub(Y3, S, Y3);
sm2_z256_print(stderr, 0, 0, "18. Y3", Y3);
} }
/* /*
@@ -1234,6 +1252,7 @@ void sm2_z256_point_add(SM2_Z256_POINT *r, const SM2_Z256_POINT *a, const SM2_Z2
memcpy(r->Y, res_y, sizeof(res_y)); memcpy(r->Y, res_y, sizeof(res_y));
memcpy(r->Z, res_z, sizeof(res_z)); memcpy(r->Z, res_z, sizeof(res_z));
} }
#endif
void sm2_z256_point_neg(SM2_Z256_POINT *R, const SM2_Z256_POINT *P) void sm2_z256_point_neg(SM2_Z256_POINT *R, const SM2_Z256_POINT *P)
{ {
@@ -1363,6 +1382,7 @@ void sm2_z256_point_copy_affine(SM2_Z256_POINT *R, const SM2_Z256_POINT_AFFINE *
// 这是一个比较容易并行的算法 // 这是一个比较容易并行的算法
// r, a, b 都转换为实际输入的值 // r, a, b 都转换为实际输入的值
#ifndef ENABLE_SM2_Z256_ARMV8
void sm2_z256_point_add_affine(SM2_Z256_POINT *r, const SM2_Z256_POINT *a, const SM2_Z256_POINT_AFFINE *b) void sm2_z256_point_add_affine(SM2_Z256_POINT *r, const SM2_Z256_POINT *a, const SM2_Z256_POINT_AFFINE *b)
{ {
uint64_t U2[4], S2[4]; uint64_t U2[4], S2[4];
@@ -1443,6 +1463,7 @@ void sm2_z256_point_add_affine(SM2_Z256_POINT *r, const SM2_Z256_POINT *a, const
memcpy(r->Y, res_y, sizeof(res_y)); memcpy(r->Y, res_y, sizeof(res_y));
memcpy(r->Z, res_z, sizeof(res_z)); memcpy(r->Z, res_z, sizeof(res_z));
} }
#endif
void sm2_z256_point_sub_affine(SM2_Z256_POINT *R, void sm2_z256_point_sub_affine(SM2_Z256_POINT *R,
const SM2_Z256_POINT *A, const SM2_Z256_POINT_AFFINE *B) const SM2_Z256_POINT *A, const SM2_Z256_POINT_AFFINE *B)
@@ -1701,3 +1722,283 @@ int sm2_z256_point_from_hash(SM2_Z256_POINT *R, const uint8_t *data, size_t data
return 1; return 1;
} }
int sm2_point_is_on_curve(const SM2_POINT *P)
{
SM2_Z256_POINT T;
sm2_z256_point_from_bytes(&T, (const uint8_t *)P);
if (sm2_z256_point_is_on_curve(&T) == 1) {
return 1;
} else {
return 0;
}
}
// 应该测试这个函数
int sm2_point_is_at_infinity(const SM2_POINT *P)
{
SM2_Z256_POINT T;
sm2_z256_point_from_bytes(&T, (const uint8_t *)P);
if (sm2_z256_point_is_at_infinity(&T)) {
return 1;
} else {
return 0;
}
}
int sm2_point_from_x(SM2_POINT *P, const uint8_t x[32], int y_is_odd)
{
SM2_Z256_POINT T;
if (sm2_z256_point_from_x_bytes(&T, x, y_is_odd) != 1) {
error_print();
return -1;
}
sm2_z256_point_to_bytes(&T, (uint8_t *)P);
return 1;
}
int sm2_point_from_xy(SM2_POINT *P, const uint8_t x[32], const uint8_t y[32])
{
memcpy(P->x, x, 32);
memcpy(P->y, y, 32);
return sm2_point_is_on_curve(P);
}
int sm2_point_add(SM2_POINT *R, const SM2_POINT *P, const SM2_POINT *Q)
{
SM2_Z256_POINT P_;
SM2_Z256_POINT Q_;
sm2_z256_point_from_bytes(&P_, (uint8_t *)P);
sm2_z256_point_from_bytes(&Q_, (uint8_t *)Q);
sm2_z256_point_add(&P_, &P_, &Q_);
sm2_z256_point_to_bytes(&P_, (uint8_t *)R);
return 1;
}
int sm2_point_sub(SM2_POINT *R, const SM2_POINT *P, const SM2_POINT *Q)
{
SM2_Z256_POINT P_;
SM2_Z256_POINT Q_;
sm2_z256_point_from_bytes(&P_, (uint8_t *)P);
sm2_z256_point_from_bytes(&Q_, (uint8_t *)Q);
sm2_z256_point_sub(&P_, &P_, &Q_);
sm2_z256_point_to_bytes(&P_, (uint8_t *)R);
return 1;
}
int sm2_point_neg(SM2_POINT *R, const SM2_POINT *P)
{
SM2_Z256_POINT P_;
sm2_z256_point_from_bytes(&P_, (uint8_t *)P);
sm2_z256_point_neg(&P_, &P_);
sm2_z256_point_to_bytes(&P_, (uint8_t *)R);
return 1;
}
int sm2_point_dbl(SM2_POINT *R, const SM2_POINT *P)
{
SM2_Z256_POINT P_;
sm2_z256_point_from_bytes(&P_, (uint8_t *)P);
sm2_z256_point_dbl(&P_, &P_);
sm2_z256_point_to_bytes(&P_, (uint8_t *)R);
return 1;
}
int sm2_point_mul(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P)
{
uint64_t _k[4];
SM2_Z256_POINT _P;
sm2_z256_from_bytes(_k, k);
sm2_z256_point_from_bytes(&_P, (uint8_t *)P);
sm2_z256_point_mul(&_P, _k, &_P);
sm2_z256_point_to_bytes(&_P, (uint8_t *)R);
memset(_k, 0, sizeof(_k));
return 1;
}
int sm2_point_mul_generator(SM2_POINT *R, const uint8_t k[32])
{
uint64_t _k[4];
SM2_Z256_POINT _R;
sm2_z256_from_bytes(_k, k);
sm2_z256_point_mul_generator(&_R, _k);
sm2_z256_point_to_bytes(&_R, (uint8_t *)R);
memset(_k, 0, sizeof(_k));
return 1;
}
int sm2_point_mul_sum(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P, const uint8_t s[32])
{
uint64_t _k[4];
SM2_Z256_POINT _P;
uint64_t _s[4];
sm2_z256_from_bytes(_k, k);
sm2_z256_point_from_bytes(&_P, (uint8_t *)P);
sm2_z256_from_bytes(_s, s);
sm2_z256_point_mul_sum(&_P, _k, &_P, _s);
sm2_z256_point_to_bytes(&_P, (uint8_t *)R);
memset(_k, 0, sizeof(_k));
memset(_s, 0, sizeof(_s));
return 1;
}
int sm2_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_POINT *P)
{
format_print(fp, fmt, ind, "%s\n", label);
ind += 4;
format_bytes(fp, fmt, ind, "x", P->x, 32);
format_bytes(fp, fmt, ind, "y", P->y, 32);
return 1;
}
void sm2_point_to_compressed_octets(const SM2_POINT *P, uint8_t out[33])
{
*out++ = (P->y[31] & 0x01) ? 0x03 : 0x02;
memcpy(out, P->x, 32);
}
void sm2_point_to_uncompressed_octets(const SM2_POINT *P, uint8_t out[65])
{
*out++ = 0x04;
memcpy(out, P, 64);
}
int sm2_z256_point_from_octets(SM2_Z256_POINT *P, const uint8_t *in, size_t inlen)
{
switch (*in) {
case SM2_point_at_infinity:
if (inlen != 1) {
error_print();
return -1;
}
sm2_z256_point_set_infinity(P);
break;
case SM2_point_compressed_y_even:
if (inlen != 33) {
error_print();
return -1;
}
if (sm2_z256_point_from_x_bytes(P, in + 1, 0) != 1) {
error_print();
return -1;
}
break;
case SM2_point_compressed_y_odd:
if (inlen != 33) {
error_print();
return -1;
}
if (sm2_z256_point_from_x_bytes(P, in + 1, 1) != 1) {
error_print();
return -1;
}
break;
case SM2_point_uncompressed:
if (inlen != 65) {
error_print();
return -1;
}
sm2_z256_point_from_bytes(P, in + 1);
if (sm2_z256_point_is_on_curve(P) != 1) {
error_print();
return -1;
}
break;
default:
error_print();
return -1;
}
return 1;
}
int sm2_point_from_octets(SM2_POINT *P, const uint8_t *in, size_t inlen)
{
if ((*in == 0x02 || *in == 0x03) && inlen == 33) {
if (sm2_point_from_x(P, in + 1, *in) != 1) {
error_print();
return -1;
}
} else if (*in == 0x04 && inlen == 65) {
if (sm2_point_from_xy(P, in + 1, in + 33) != 1) {
error_print();
return -1;
}
} else {
error_print();
return -1;
}
return 1;
}
int sm2_point_to_der(const SM2_POINT *P, uint8_t **out, size_t *outlen)
{
uint8_t octets[65];
if (!P) {
return 0;
}
sm2_point_to_uncompressed_octets(P, octets);
if (asn1_octet_string_to_der(octets, sizeof(octets), out, outlen) != 1) {
error_print();
return -1;
}
return 1;
}
int sm2_point_from_der(SM2_POINT *P, const uint8_t **in, size_t *inlen)
{
int ret;
const uint8_t *d;
size_t dlen;
if ((ret = asn1_octet_string_from_der(&d, &dlen, in, inlen)) != 1) {
if (ret < 0) error_print();
return ret;
}
if (dlen != 65) {
error_print();
return -1;
}
if (sm2_point_from_octets(P, d, dlen) != 1) {
error_print();
return -1;
}
return 1;
}
int sm2_point_from_hash(SM2_POINT *R, const uint8_t *data, size_t datalen)
{
return 1;
}

View File

@@ -20,64 +20,34 @@
#include <gmssl/endian.h> #include <gmssl/endian.h>
typedef SM2_Z256 SM2_U256;
#define sm2_u256_one() sm2_z256_one()
#define sm2_u256_order() sm2_z256_order()
#define sm2_u256_from_bytes(a,in) sm2_z256_from_bytes(a,in)
#define sm2_u256_to_bytes(a,out) sm2_z256_to_bytes(a,out)
#define sm2_u256_print(fp,fmt,ind,label,a) sm2_z256_print(fp,fmt,ind,label,a)
#define sm2_u256_is_zero(a) sm2_z256_is_zero(a)
#define sm2_u256_cmp(a,b) sm2_z256_cmp(a,b)
#define sm2_u256_add(r,a,b) sm2_z256_add(r,a,b)
#define sm2_u256_sub(r,a,b) sm2_z256_sub(r,a,b)
#define sm2_u256_modn_add(r,a,b) sm2_z256_modn_add(r,a,b)
#define sm2_u256_modn_sub(r,a,b) sm2_z256_modn_sub(r,a,b)
#define sm2_u256_modn_mul(r,a,b) sm2_z256_modn_mul(r,a,b)
#define sm2_u256_modn_inv(r,a) sm2_z256_modn_inv(r,a)
#define sm2_u256_modn_rand(r) sm2_z256_modn_rand(r)
typedef SM2_Z256_POINT SM2_U256_POINT;
#define sm2_u256_point_from_bytes(P,in) sm2_z256_point_from_bytes((P),(in))
#define sm2_u256_point_to_bytes(P,out) sm2_z256_point_to_bytes((P),(out))
#define sm2_u256_point_is_on_curve(P) sm2_z256_point_is_on_curve(P)
#define sm2_u256_point_mul_generator(R,k) sm2_z256_point_mul_generator((R),(k))
#define sm2_u256_point_mul(R,k,P) sm2_z256_point_mul((R),(k),(P))
#define sm2_u256_point_mul_sum(R,t,P,s) sm2_z256_point_mul_sum((R),(t),(P),(s))
#define sm2_u256_point_get_xy(P,x,y) sm2_z256_point_get_xy((P),(x),(y))
int sm2_do_sign(const SM2_KEY *key, const uint8_t dgst[32], SM2_SIGNATURE *sig) int sm2_do_sign(const SM2_KEY *key, const uint8_t dgst[32], SM2_SIGNATURE *sig)
{ {
SM2_U256_POINT _P, *P = &_P; SM2_Z256_POINT _P, *P = &_P;
SM2_U256 d; SM2_Z256 d;
SM2_U256 d_inv; SM2_Z256 d_inv;
SM2_U256 e; SM2_Z256 e;
SM2_U256 k; SM2_Z256 k;
SM2_U256 x; SM2_Z256 x;
SM2_U256 t; SM2_Z256 t;
SM2_U256 r; SM2_Z256 r;
SM2_U256 s; SM2_Z256 s;
const uint64_t *one = sm2_u256_one(); const uint64_t *one = sm2_z256_one();
const uint64_t *order = sm2_u256_order(); const uint64_t *order = sm2_z256_order();
sm2_u256_from_bytes(d, key->private_key); sm2_z256_from_bytes(d, key->private_key);
// compute (d + 1)^-1 (mod n) // compute (d + 1)^-1 (mod n)
sm2_u256_modn_add(d_inv, d, one); //sm2_bn_print(stderr, 0, 4, "(1+d)", d_inv); sm2_z256_modn_add(d_inv, d, one); //sm2_bn_print(stderr, 0, 4, "(1+d)", d_inv);
if (sm2_u256_is_zero(d_inv)) { if (sm2_z256_is_zero(d_inv)) {
error_print(); error_print();
return -1; return -1;
} }
sm2_u256_modn_inv(d_inv, d_inv); //sm2_bn_print(stderr, 0, 4, "(1+d)^-1", d_inv); sm2_z256_modn_inv(d_inv, d_inv); //sm2_bn_print(stderr, 0, 4, "(1+d)^-1", d_inv);
// e = H(M) // e = H(M)
sm2_u256_from_bytes(e, dgst); //sm2_bn_print(stderr, 0, 4, "e", e); sm2_z256_from_bytes(e, dgst); //sm2_bn_print(stderr, 0, 4, "e", e);
retry: retry:
@@ -86,15 +56,15 @@ retry:
// rand k in [1, n - 1] // rand k in [1, n - 1]
do { do {
if (sm2_u256_modn_rand(k) != 1) { if (sm2_z256_modn_rand(k) != 1) {
error_print(); error_print();
return -1; return -1;
} }
} while (sm2_u256_is_zero(k)); //sm2_bn_print(stderr, 0, 4, "k", k); } while (sm2_z256_is_zero(k)); //sm2_bn_print(stderr, 0, 4, "k", k);
// (x, y) = kG // (x, y) = kG
sm2_u256_point_mul_generator(P, k); sm2_z256_point_mul_generator(P, k);
sm2_u256_point_get_xy(P, x, NULL); sm2_z256_point_get_xy(P, x, NULL);
//sm2_bn_print(stderr, 0, 4, "x", x); //sm2_bn_print(stderr, 0, 4, "x", x);
@@ -104,33 +74,33 @@ retry:
// >>>>>>>>>>> END PRECOMP // >>>>>>>>>>> END PRECOMP
// r = e + x (mod n) // r = e + x (mod n)
if (sm2_u256_cmp(e, order) >= 0) { if (sm2_z256_cmp(e, order) >= 0) {
sm2_u256_sub(e, e, order); sm2_z256_sub(e, e, order);
} }
if (sm2_u256_cmp(x, order) >= 0) { if (sm2_z256_cmp(x, order) >= 0) {
sm2_u256_sub(x, x, order); sm2_z256_sub(x, x, order);
} }
sm2_u256_modn_add(r, e, x); //sm2_bn_print(stderr, 0, 4, "r = e + x (mod n)", r); sm2_z256_modn_add(r, e, x); //sm2_bn_print(stderr, 0, 4, "r = e + x (mod n)", r);
// if r == 0 or r + k == n re-generate k // if r == 0 or r + k == n re-generate k
sm2_u256_add(t, r, k); sm2_z256_add(t, r, k);
if (sm2_u256_is_zero(r) || sm2_u256_cmp(t, order) == 0) { if (sm2_z256_is_zero(r) || sm2_z256_cmp(t, order) == 0) {
//sm2_bn_print(stderr, 0, 4, "r + k", t); //sm2_bn_print(stderr, 0, 4, "r + k", t);
goto retry; goto retry;
} }
// s = ((1 + d)^-1 * (k - r * d)) mod n // s = ((1 + d)^-1 * (k - r * d)) mod n
sm2_u256_modn_mul(t, r, d); //sm2_bn_print(stderr, 0, 4, "r*d", t); sm2_z256_modn_mul(t, r, d); //sm2_bn_print(stderr, 0, 4, "r*d", t);
sm2_u256_modn_sub(k, k, t); //sm2_bn_print(stderr, 0, 4, "k-r*d", k); sm2_z256_modn_sub(k, k, t); //sm2_bn_print(stderr, 0, 4, "k-r*d", k);
sm2_u256_modn_mul(s, d_inv, k); //sm2_bn_print(stderr, 0, 4, "s = ((1 + d)^-1 * (k - r * d)) mod n", s); sm2_z256_modn_mul(s, d_inv, k); //sm2_bn_print(stderr, 0, 4, "s = ((1 + d)^-1 * (k - r * d)) mod n", s);
// check s != 0 // check s != 0
if (sm2_u256_is_zero(s)) { if (sm2_z256_is_zero(s)) {
goto retry; goto retry;
} }
sm2_u256_to_bytes(r, sig->r); //sm2_bn_print_bn(stderr, 0, 4, "r", r); sm2_z256_to_bytes(r, sig->r); //sm2_bn_print_bn(stderr, 0, 4, "r", r);
sm2_u256_to_bytes(s, sig->s); //sm2_bn_print_bn(stderr, 0, 4, "s", s); sm2_z256_to_bytes(s, sig->s); //sm2_bn_print_bn(stderr, 0, 4, "s", s);
gmssl_secure_clear(d, sizeof(d)); gmssl_secure_clear(d, sizeof(d));
gmssl_secure_clear(d_inv, sizeof(d_inv )); gmssl_secure_clear(d_inv, sizeof(d_inv ));
@@ -153,8 +123,8 @@ int sm2_do_sign_pre_compute(uint64_t k[4], uint64_t x1[4])
} while (sm2_z256_is_zero(k)); } while (sm2_z256_is_zero(k));
// (x1, y1) = kG // (x1, y1) = kG
sm2_u256_point_mul_generator(&P, k); // 这个函数要粗力度并行,这要怎么做? sm2_z256_point_mul_generator(&P, k); // 这个函数要粗力度并行,这要怎么做?
sm2_u256_point_get_xy(&P, x1, NULL); sm2_z256_point_get_xy(&P, x1, NULL);
return 1; return 1;
} }
@@ -183,8 +153,8 @@ int sm2_do_sign_fast_ex(const uint64_t d[4], const uint64_t k[4], const uint64_t
sm2_z256_modn_mul(s, s, d); sm2_z256_modn_mul(s, s, d);
sm2_z256_modn_sub(s, s, r); sm2_z256_modn_sub(s, s, r);
sm2_u256_to_bytes(r, sig->r); sm2_z256_to_bytes(r, sig->r);
sm2_u256_to_bytes(s, sig->s); sm2_z256_to_bytes(s, sig->s);
return 1; return 1;
} }
@@ -199,39 +169,39 @@ int sm2_do_sign_fast_ex(const uint64_t d[4], const uint64_t k[4], const uint64_t
// 这个函数是我们真正要调用的,甚至可以替代原来的函数 // 这个函数是我们真正要调用的,甚至可以替代原来的函数
int sm2_do_sign_fast(const uint64_t d[4], const uint8_t dgst[32], SM2_SIGNATURE *sig) int sm2_do_sign_fast(const uint64_t d[4], const uint8_t dgst[32], SM2_SIGNATURE *sig)
{ {
SM2_U256_POINT R; SM2_Z256_POINT R;
SM2_U256 e; SM2_Z256 e;
SM2_U256 k; SM2_Z256 k;
SM2_U256 x1; SM2_Z256 x1;
SM2_U256 r; SM2_Z256 r;
SM2_U256 s; SM2_Z256 s;
const uint64_t *order = sm2_u256_order(); const uint64_t *order = sm2_z256_order();
// e = H(M) // e = H(M)
sm2_u256_from_bytes(e, dgst); sm2_z256_from_bytes(e, dgst);
if (sm2_u256_cmp(e, order) >= 0) { if (sm2_z256_cmp(e, order) >= 0) {
sm2_u256_sub(e, e, order); sm2_z256_sub(e, e, order);
} }
/// <<<<<<<<<<< 这里的 (k, x1) 应该是从外部输入的!!,这样才是最快的。 /// <<<<<<<<<<< 这里的 (k, x1) 应该是从外部输入的!!,这样才是最快的。
// rand k in [1, n - 1] // rand k in [1, n - 1]
do { do {
if (sm2_u256_modn_rand(k) != 1) { if (sm2_z256_modn_rand(k) != 1) {
error_print(); error_print();
return -1; return -1;
} }
} while (sm2_u256_is_zero(k)); } while (sm2_z256_is_zero(k));
// (x1, y1) = kG // (x1, y1) = kG
sm2_u256_point_mul_generator(&R, k); // 这个函数要粗力度并行,这要怎么做? sm2_z256_point_mul_generator(&R, k); // 这个函数要粗力度并行,这要怎么做?
sm2_u256_point_get_xy(&R, x1, NULL); sm2_z256_point_get_xy(&R, x1, NULL);
/// >>>>>>>>>>>>>>>>>> /// >>>>>>>>>>>>>>>>>>
// r = e + x1 (mod n) // r = e + x1 (mod n)
sm2_u256_modn_add(r, e, x1); sm2_z256_modn_add(r, e, x1);
// 对于快速实现来说,只需要一次乘法 // 对于快速实现来说,只需要一次乘法
@@ -240,12 +210,12 @@ int sm2_do_sign_fast(const uint64_t d[4], const uint8_t dgst[32], SM2_SIGNATURE
// s = (k + r) * d' - r // s = (k + r) * d' - r
sm2_u256_modn_add(s, k, r); sm2_z256_modn_add(s, k, r);
sm2_u256_modn_mul(s, s, d); sm2_z256_modn_mul(s, s, d);
sm2_u256_modn_sub(s, s, r); sm2_z256_modn_sub(s, s, r);
sm2_u256_to_bytes(r, sig->r); sm2_z256_to_bytes(r, sig->r);
sm2_u256_to_bytes(s, sig->s); sm2_z256_to_bytes(s, sig->s);
return 1; return 1;
} }
@@ -253,62 +223,62 @@ int sm2_do_sign_fast(const uint64_t d[4], const uint8_t dgst[32], SM2_SIGNATURE
// 这里根本没有modn的乘法 // 这里根本没有modn的乘法
int sm2_do_verify_fast(const SM2_Z256_POINT *P, const uint8_t dgst[32], const SM2_SIGNATURE *sig) int sm2_do_verify_fast(const SM2_Z256_POINT *P, const uint8_t dgst[32], const SM2_SIGNATURE *sig)
{ {
SM2_U256_POINT R; SM2_Z256_POINT R;
SM2_U256 r; SM2_Z256 r;
SM2_U256 s; SM2_Z256 s;
SM2_U256 e; SM2_Z256 e;
SM2_U256 x; SM2_Z256 x;
SM2_U256 t; SM2_Z256 t;
const uint64_t *order = sm2_u256_order(); const uint64_t *order = sm2_z256_order();
sm2_u256_from_bytes(r, sig->r); sm2_z256_from_bytes(r, sig->r);
// check r in [1, n-1] // check r in [1, n-1]
if (sm2_u256_is_zero(r) == 1) { if (sm2_z256_is_zero(r) == 1) {
error_print(); error_print();
return -1; return -1;
} }
if (sm2_u256_cmp(r, order) >= 0) { if (sm2_z256_cmp(r, order) >= 0) {
error_print(); error_print();
return -1; return -1;
} }
sm2_u256_from_bytes(s, sig->s); sm2_z256_from_bytes(s, sig->s);
// check s in [1, n-1] // check s in [1, n-1]
if (sm2_u256_is_zero(s) == 1) { if (sm2_z256_is_zero(s) == 1) {
error_print(); error_print();
return -1; return -1;
} }
if (sm2_u256_cmp(s, order) >= 0) { if (sm2_z256_cmp(s, order) >= 0) {
error_print(); error_print();
return -1; return -1;
} }
// e = H(M) // e = H(M)
sm2_u256_from_bytes(e, dgst); sm2_z256_from_bytes(e, dgst);
// t = r + s (mod n), check t != 0 // t = r + s (mod n), check t != 0
sm2_u256_modn_add(t, r, s); sm2_z256_modn_add(t, r, s);
if (sm2_u256_is_zero(t)) { if (sm2_z256_is_zero(t)) {
error_print(); error_print();
return -1; return -1;
} }
// Q = s * G + t * P // Q = s * G + t * P
sm2_u256_point_mul_sum(&R, t, P, s); sm2_z256_point_mul_sum(&R, t, P, s);
sm2_u256_point_get_xy(&R, x, NULL); sm2_z256_point_get_xy(&R, x, NULL);
// r' = e + x (mod n) // r' = e + x (mod n)
if (sm2_u256_cmp(e, order) >= 0) { if (sm2_z256_cmp(e, order) >= 0) {
sm2_u256_sub(e, e, order); sm2_z256_sub(e, e, order);
} }
if (sm2_u256_cmp(x, order) >= 0) { if (sm2_z256_cmp(x, order) >= 0) {
sm2_u256_sub(x, x, order); sm2_z256_sub(x, x, order);
} }
sm2_u256_modn_add(e, e, x); sm2_z256_modn_add(e, e, x);
// check if r == r' // check if r == r'
if (sm2_u256_cmp(e, r) != 0) { if (sm2_z256_cmp(e, r) != 0) {
error_print(); error_print();
return -1; return -1;
} }
@@ -317,49 +287,49 @@ int sm2_do_verify_fast(const SM2_Z256_POINT *P, const uint8_t dgst[32], const SM
int sm2_do_verify(const SM2_KEY *key, const uint8_t dgst[32], const SM2_SIGNATURE *sig) int sm2_do_verify(const SM2_KEY *key, const uint8_t dgst[32], const SM2_SIGNATURE *sig)
{ {
SM2_U256_POINT _P, *P = &_P; SM2_Z256_POINT _P, *P = &_P;
SM2_U256_POINT _R, *R = &_R; SM2_Z256_POINT _R, *R = &_R;
SM2_U256 r; SM2_Z256 r;
SM2_U256 s; SM2_Z256 s;
SM2_U256 e; SM2_Z256 e;
SM2_U256 x; SM2_Z256 x;
SM2_U256 t; SM2_Z256 t;
const uint64_t *order = sm2_u256_order(); const uint64_t *order = sm2_z256_order();
sm2_u256_print(stderr, 0, 4, "n", order); sm2_z256_print(stderr, 0, 4, "n", order);
// parse public key // parse public key
sm2_u256_point_from_bytes(P, (const uint8_t *)&key->public_key); sm2_z256_point_from_bytes(P, (const uint8_t *)&key->public_key);
//sm2_u256_point_from_bytes(P, (const uint8_t *)&key->public_key); //sm2_z256_point_from_bytes(P, (const uint8_t *)&key->public_key);
//sm2_jacobian_point_print(stderr, 0, 4, "P", P); //sm2_jacobian_point_print(stderr, 0, 4, "P", P);
// parse signature values // parse signature values
sm2_u256_from_bytes(r, sig->r); sm2_u256_print(stderr, 0, 4, "r", r); sm2_z256_from_bytes(r, sig->r); sm2_z256_print(stderr, 0, 4, "r", r);
sm2_u256_from_bytes(s, sig->s); sm2_u256_print(stderr, 0, 4, "s", s); sm2_z256_from_bytes(s, sig->s); sm2_z256_print(stderr, 0, 4, "s", s);
// check r, s in [1, n-1] // check r, s in [1, n-1]
if (sm2_u256_is_zero(r) == 1) { if (sm2_z256_is_zero(r) == 1) {
error_print(); error_print();
return -1; return -1;
} }
if (sm2_u256_cmp(r, order) >= 0) { if (sm2_z256_cmp(r, order) >= 0) {
sm2_u256_print(stderr, 0, 4, "err: r", r); sm2_z256_print(stderr, 0, 4, "err: r", r);
sm2_u256_print(stderr, 0, 4, "err: order", order); sm2_z256_print(stderr, 0, 4, "err: order", order);
error_print(); error_print();
return -1; return -1;
} }
if (sm2_u256_is_zero(s) == 1) { if (sm2_z256_is_zero(s) == 1) {
error_print(); error_print();
return -1; return -1;
} }
if (sm2_u256_cmp(s, order) >= 0) { if (sm2_z256_cmp(s, order) >= 0) {
sm2_u256_print(stderr, 0, 4, "err: s", s); sm2_z256_print(stderr, 0, 4, "err: s", s);
sm2_u256_print(stderr, 0, 4, "err: order", order); sm2_z256_print(stderr, 0, 4, "err: order", order);
printf(">>>>>\n"); printf(">>>>>\n");
int r = sm2_u256_cmp(s, order); int r = sm2_z256_cmp(s, order);
fprintf(stderr, "cmp ret = %d\n", r); fprintf(stderr, "cmp ret = %d\n", r);
printf(">>>>>\n"); printf(">>>>>\n");
@@ -368,31 +338,31 @@ int sm2_do_verify(const SM2_KEY *key, const uint8_t dgst[32], const SM2_SIGNATUR
} }
// e = H(M) // e = H(M)
sm2_u256_from_bytes(e, dgst); //sm2_bn_print(stderr, 0, 4, "e = H(M)", e); sm2_z256_from_bytes(e, dgst); //sm2_bn_print(stderr, 0, 4, "e = H(M)", e);
// t = r + s (mod n), check t != 0 // t = r + s (mod n), check t != 0
sm2_u256_modn_add(t, r, s); //sm2_bn_print(stderr, 0, 4, "t = r + s (mod n)", t); sm2_z256_modn_add(t, r, s); //sm2_bn_print(stderr, 0, 4, "t = r + s (mod n)", t);
if (sm2_u256_is_zero(t)) { if (sm2_z256_is_zero(t)) {
error_print(); error_print();
return -1; return -1;
} }
// Q = s * G + t * P // Q = s * G + t * P
sm2_u256_point_mul_sum(R, t, P, s); sm2_z256_point_mul_sum(R, t, P, s);
sm2_u256_point_get_xy(R, x, NULL); sm2_z256_point_get_xy(R, x, NULL);
//sm2_bn_print(stderr, 0, 4, "x", x); //sm2_bn_print(stderr, 0, 4, "x", x);
// r' = e + x (mod n) // r' = e + x (mod n)
if (sm2_u256_cmp(e, order) >= 0) { if (sm2_z256_cmp(e, order) >= 0) {
sm2_u256_sub(e, e, order); sm2_z256_sub(e, e, order);
} }
if (sm2_u256_cmp(x, order) >= 0) { if (sm2_z256_cmp(x, order) >= 0) {
sm2_u256_sub(x, x, order); sm2_z256_sub(x, x, order);
} }
sm2_u256_modn_add(e, e, x); //sm2_bn_print(stderr, 0, 4, "e + x (mod n)", e); sm2_z256_modn_add(e, e, x); //sm2_bn_print(stderr, 0, 4, "e + x (mod n)", e);
// check if r == r' // check if r == r'
if (sm2_u256_cmp(e, r) != 0) { if (sm2_z256_cmp(e, r) != 0) {
error_print(); error_print();
return -1; return -1;
} }
@@ -433,10 +403,10 @@ int sm2_do_encrypt_pre_compute(uint64_t k[4], uint8_t C1[64])
// 其中k是要参与计算的但是 (x1, y1) 不参与计算,输出为 bytes 就可以了 // 其中k是要参与计算的但是 (x1, y1) 不参与计算,输出为 bytes 就可以了
int sm2_do_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out) int sm2_do_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out)
{ {
SM2_U256 k; SM2_Z256 k;
SM2_U256_POINT _P, *P = &_P; SM2_Z256_POINT _P, *P = &_P;
SM2_U256_POINT _C1, *C1 = &_C1; SM2_Z256_POINT _C1, *C1 = &_C1;
SM2_U256_POINT _kP, *kP = &_kP; SM2_Z256_POINT _kP, *kP = &_kP;
uint8_t x2y2[64]; uint8_t x2y2[64];
SM3_CTX sm3_ctx; SM3_CTX sm3_ctx;
@@ -445,7 +415,7 @@ int sm2_do_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, SM2_CIPH
return -1; return -1;
} }
sm2_u256_point_from_bytes(P, (uint8_t *)&key->public_key); sm2_z256_point_from_bytes(P, (uint8_t *)&key->public_key);
// S = h * P, check S != O // S = h * P, check S != O
// for sm2 curve, h == 1 and S == P // for sm2 curve, h == 1 and S == P
@@ -455,19 +425,19 @@ retry:
// rand k in [1, n - 1] // rand k in [1, n - 1]
// TODO: set rand_bytes output for testing // TODO: set rand_bytes output for testing
do { do {
if (sm2_u256_modn_rand(k) != 1) { if (sm2_z256_modn_rand(k) != 1) {
error_print(); error_print();
return -1; return -1;
} }
} while (sm2_u256_is_zero(k)); //sm2_bn_print(stderr, 0, 4, "k", k); } while (sm2_z256_is_zero(k)); //sm2_bn_print(stderr, 0, 4, "k", k);
// output C1 = k * G = (x1, y1) // output C1 = k * G = (x1, y1)
sm2_u256_point_mul_generator(C1, k); sm2_z256_point_mul_generator(C1, k);
sm2_u256_point_to_bytes(C1, (uint8_t *)&out->point); sm2_z256_point_to_bytes(C1, (uint8_t *)&out->point);
// k * P = (x2, y2) // k * P = (x2, y2)
sm2_u256_point_mul(kP, k, P); sm2_z256_point_mul(kP, k, P);
sm2_u256_point_to_bytes(kP, x2y2); sm2_z256_point_to_bytes(kP, x2y2);
// t = KDF(x2 || y2, inlen) // t = KDF(x2 || y2, inlen)
sm2_kdf(x2y2, 64, inlen, out->ciphertext); sm2_kdf(x2y2, 64, inlen, out->ciphertext);
@@ -489,7 +459,7 @@ retry:
sm3_finish(&sm3_ctx, out->hash); sm3_finish(&sm3_ctx, out->hash);
gmssl_secure_clear(k, sizeof(k)); gmssl_secure_clear(k, sizeof(k));
gmssl_secure_clear(kP, sizeof(SM2_U256_POINT)); gmssl_secure_clear(kP, sizeof(SM2_Z256_POINT));
gmssl_secure_clear(x2y2, sizeof(x2y2)); gmssl_secure_clear(x2y2, sizeof(x2y2));
return 1; return 1;
} }
@@ -497,10 +467,10 @@ retry:
int sm2_do_encrypt_fixlen(const SM2_KEY *key, const uint8_t *in, size_t inlen, int point_size, SM2_CIPHERTEXT *out) int sm2_do_encrypt_fixlen(const SM2_KEY *key, const uint8_t *in, size_t inlen, int point_size, SM2_CIPHERTEXT *out)
{ {
unsigned int trys = 200; unsigned int trys = 200;
SM2_U256 k; SM2_Z256 k;
SM2_U256_POINT _P, *P = &_P; SM2_Z256_POINT _P, *P = &_P;
SM2_U256_POINT _C1, *C1 = &_C1; SM2_Z256_POINT _C1, *C1 = &_C1;
SM2_U256_POINT _kP, *kP = &_kP; SM2_Z256_POINT _kP, *kP = &_kP;
uint8_t x2y2[64]; uint8_t x2y2[64];
SM3_CTX sm3_ctx; SM3_CTX sm3_ctx;
@@ -519,7 +489,7 @@ int sm2_do_encrypt_fixlen(const SM2_KEY *key, const uint8_t *in, size_t inlen, i
return -1; return -1;
} }
sm2_u256_point_from_bytes(P, (uint8_t *)&key->public_key); sm2_z256_point_from_bytes(P, (uint8_t *)&key->public_key);
// S = h * P, check S != O // S = h * P, check S != O
// for sm2 curve, h == 1 and S == P // for sm2 curve, h == 1 and S == P
@@ -528,15 +498,15 @@ int sm2_do_encrypt_fixlen(const SM2_KEY *key, const uint8_t *in, size_t inlen, i
retry: retry:
// rand k in [1, n - 1] // rand k in [1, n - 1]
do { do {
if (sm2_u256_modn_rand(k) != 1) { if (sm2_z256_modn_rand(k) != 1) {
error_print(); error_print();
return -1; return -1;
} }
} while (sm2_u256_is_zero(k)); //sm2_bn_print(stderr, 0, 4, "k", k); } while (sm2_z256_is_zero(k)); //sm2_bn_print(stderr, 0, 4, "k", k);
// output C1 = k * G = (x1, y1) // output C1 = k * G = (x1, y1)
sm2_u256_point_mul_generator(C1, k); sm2_z256_point_mul_generator(C1, k);
sm2_u256_point_to_bytes(C1, (uint8_t *)&out->point); sm2_z256_point_to_bytes(C1, (uint8_t *)&out->point);
// check fixlen // check fixlen
if (trys) { if (trys) {
@@ -554,8 +524,8 @@ retry:
} }
// k * P = (x2, y2) // k * P = (x2, y2)
sm2_u256_point_mul(kP, k, P); sm2_z256_point_mul(kP, k, P);
sm2_u256_point_to_bytes(kP, x2y2); sm2_z256_point_to_bytes(kP, x2y2);
// t = KDF(x2 || y2, inlen) // t = KDF(x2 || y2, inlen)
sm2_kdf(x2y2, 64, inlen, out->ciphertext); sm2_kdf(x2y2, 64, inlen, out->ciphertext);
@@ -577,7 +547,7 @@ retry:
sm3_finish(&sm3_ctx, out->hash); sm3_finish(&sm3_ctx, out->hash);
gmssl_secure_clear(k, sizeof(k)); gmssl_secure_clear(k, sizeof(k));
gmssl_secure_clear(kP, sizeof(SM2_U256_POINT)); gmssl_secure_clear(kP, sizeof(SM2_Z256_POINT));
gmssl_secure_clear(x2y2, sizeof(x2y2)); gmssl_secure_clear(x2y2, sizeof(x2y2));
return 1; return 1;
} }
@@ -585,15 +555,15 @@ retry:
int sm2_do_decrypt(const SM2_KEY *key, const SM2_CIPHERTEXT *in, uint8_t *out, size_t *outlen) int sm2_do_decrypt(const SM2_KEY *key, const SM2_CIPHERTEXT *in, uint8_t *out, size_t *outlen)
{ {
int ret = -1; int ret = -1;
SM2_U256 d; SM2_Z256 d;
SM2_U256_POINT _C1, *C1 = &_C1; SM2_Z256_POINT _C1, *C1 = &_C1;
uint8_t x2y2[64]; uint8_t x2y2[64];
SM3_CTX sm3_ctx; SM3_CTX sm3_ctx;
uint8_t hash[32]; uint8_t hash[32];
// check C1 is on sm2 curve // check C1 is on sm2 curve
sm2_u256_point_from_bytes(C1, (uint8_t *)&in->point); sm2_z256_point_from_bytes(C1, (uint8_t *)&in->point);
if (!sm2_u256_point_is_on_curve(C1)) { if (!sm2_z256_point_is_on_curve(C1)) {
error_print(); error_print();
return -1; return -1;
} }
@@ -602,11 +572,11 @@ int sm2_do_decrypt(const SM2_KEY *key, const SM2_CIPHERTEXT *in, uint8_t *out, s
// this will not happen, as SM2_POINT can not present point at infinity // this will not happen, as SM2_POINT can not present point at infinity
// d * C1 = (x2, y2) // d * C1 = (x2, y2)
sm2_u256_from_bytes(d, key->private_key); sm2_z256_from_bytes(d, key->private_key);
sm2_u256_point_mul(C1, d, C1); sm2_z256_point_mul(C1, d, C1);
// t = KDF(x2 || y2, klen) and check t is not all zeros // t = KDF(x2 || y2, klen) and check t is not all zeros
sm2_u256_point_to_bytes(C1, x2y2); sm2_z256_point_to_bytes(C1, x2y2);
sm2_kdf(x2y2, 64, in->ciphertext_size, out); sm2_kdf(x2y2, 64, in->ciphertext_size, out);
if (all_zero(out, in->ciphertext_size)) { if (all_zero(out, in->ciphertext_size)) {
error_print(); error_print();
@@ -633,7 +603,7 @@ int sm2_do_decrypt(const SM2_KEY *key, const SM2_CIPHERTEXT *in, uint8_t *out, s
end: end:
gmssl_secure_clear(d, sizeof(d)); gmssl_secure_clear(d, sizeof(d));
gmssl_secure_clear(C1, sizeof(SM2_U256_POINT)); gmssl_secure_clear(C1, sizeof(SM2_Z256_POINT));
gmssl_secure_clear(x2y2, sizeof(x2y2)); gmssl_secure_clear(x2y2, sizeof(x2y2));
return ret; return ret;
} }

View File

@@ -517,10 +517,22 @@ static int test_sm2_z256_point_add_conjugate(void)
sm2_z256_point_from_hex(&Q, hex_negG); sm2_z256_point_from_hex(&Q, hex_negG);
sm2_z256_point_add(&R, &P, &Q); sm2_z256_point_add(&R, &P, &Q);
// 汇编代码在实现点加的时候为什么会出现X, Y != 0的情况呢
sm2_z256_print(stderr, 0, 0, "R.X", R.X);
sm2_z256_print(stderr, 0, 0, "R.Y", R.Y);
sm2_z256_print(stderr, 0, 0, "R.Z", R.Z);
// P + (-P) = (0:0:0) // P + (-P) = (0:0:0)
/*
// 有可能在计算的时候,已经发现这是共轭点,那就不做进一步的计算了
if (!sm2_z256_is_zero(R.X) if (!sm2_z256_is_zero(R.X)
|| !sm2_z256_is_zero(R.Y) || !sm2_z256_is_zero(R.Y)) {
|| !sm2_z256_is_zero(R.Z)) { error_print();
return -1;
}
*/
if (!sm2_z256_is_zero(R.Z)) {
error_print(); error_print();
return -1; return -1;
} }
@@ -536,9 +548,10 @@ static int test_sm2_z256_point_dbl_infinity(void)
sm2_z256_point_set_infinity(&P_infinity); sm2_z256_point_set_infinity(&P_infinity);
sm2_z256_point_dbl(&R, &P_infinity); // 显然这个计算就会出错了! sm2_z256_point_dbl(&R, &P_infinity); // 显然这个计算就会出错了!
sm2_z256_print(stderr, 0, 0, "ret", R.X);
if (!sm2_z256_point_is_at_infinity(&R)) { if (!sm2_z256_point_is_at_infinity(&R)) {
error_print(); // 这个会出错 error_print();
return -1; return -1;
} }
@@ -616,6 +629,9 @@ static int test_sm2_z256_point_ops(void)
break; break;
case OP_DBL: case OP_DBL:
sm2_z256_point_dbl(&P, &A); sm2_z256_point_dbl(&P, &A);
sm2_z256_print(stderr, 0, 0, "X", P.X);
sm2_z256_print(stderr, 0, 0, "Y", P.Y);
sm2_z256_print(stderr, 0, 0, "Z", P.Z);
break; break;
case OP_SUB: case OP_SUB:
sm2_z256_point_sub(&P, &A, &B); sm2_z256_point_sub(&P, &A, &B);
@@ -860,6 +876,8 @@ static int test_sm2_z256_point_from_hash(void)
int main(void) int main(void)
{ {
if (test_sm2_z256_point_dbl_infinity() != 1) goto err;
if (test_sm2_z256_point_ops() != 1) goto err;
if (test_sm2_z256_rshift() != 1) goto err; if (test_sm2_z256_rshift() != 1) goto err;
if (test_sm2_z256_modp() != 1) goto err; if (test_sm2_z256_modp() != 1) goto err;
@@ -868,8 +886,6 @@ int main(void)
if (test_sm2_z256_point_equ() != 1) goto err; if (test_sm2_z256_point_equ() != 1) goto err;
if (test_sm2_z256_point_get_xy() != 1) goto err; if (test_sm2_z256_point_get_xy() != 1) goto err;
if (test_sm2_z256_point_add_conjugate() != 1) goto err; if (test_sm2_z256_point_add_conjugate() != 1) goto err;
if (test_sm2_z256_point_dbl_infinity() != 1) goto err;
if (test_sm2_z256_point_ops() != 1) goto err;
if (test_sm2_z256_point_mul_generator() != 1) goto err; if (test_sm2_z256_point_mul_generator() != 1) goto err;
if (test_sm2_z256_point_from_hash() != 1) goto err; if (test_sm2_z256_point_from_hash() != 1) goto err;
if (test_sm2_z256_point_from_x_bytes() != 1) goto err; if (test_sm2_z256_point_from_x_bytes() != 1) goto err;