mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-07 00:46:17 +08:00
Merge branch 'guanzhi:master' into master
This commit is contained in:
@@ -18,8 +18,6 @@ set(src
|
||||
src/sm3_hmac.c
|
||||
src/sm3_kdf.c
|
||||
src/sm3_digest.c
|
||||
#src/sm2_alg.c
|
||||
src/sm2_point.c
|
||||
src/sm2_z256.c
|
||||
src/sm2_z256_table.c
|
||||
src/sm2_z256_key.c
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/api.h>
|
||||
#include <gmssl/sm3.h>
|
||||
#include <gmssl/sm2_z256.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -163,13 +162,9 @@ typedef struct {
|
||||
} SM2_SIGNATURE;
|
||||
|
||||
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_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
|
||||
@@ -203,20 +198,23 @@ typedef struct {
|
||||
uint64_t x1[4];
|
||||
} SM2_SIGN_PRE_COMP;
|
||||
|
||||
|
||||
typedef struct {
|
||||
SM3_CTX sm3_ctx;
|
||||
SM2_KEY key;
|
||||
// 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
|
||||
SM3_CTX inited_sm3_ctx;
|
||||
|
||||
SM2_SIGN_PRE_COMP pre_comp[32];
|
||||
unsigned int num_pre_comp;
|
||||
|
||||
} 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_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);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/sm2.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
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);
|
||||
|
||||
// 这些函数的问题是依赖于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
|
||||
}
|
||||
#endif
|
||||
|
||||
1367
src/sm2_alg.c
1367
src/sm2_alg.c
File diff suppressed because it is too large
Load Diff
691
src/sm2_key.c
691
src/sm2_key.c
@@ -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, ¶ms_ptr, ¶ms_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, ¶ms, ¶ms_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, ¶ms, ¶ms_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;
|
||||
}
|
||||
282
src/sm2_point.c
282
src/sm2_point.c
@@ -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;
|
||||
}
|
||||
|
||||
425
src/sm2_sign.c
425
src/sm2_sign.c
@@ -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;
|
||||
}
|
||||
305
src/sm2_z256.c
305
src/sm2_z256.c
@@ -53,7 +53,7 @@
|
||||
#include <gmssl/endian.h>
|
||||
#include <gmssl/sm2_z256.h>
|
||||
#include <gmssl/sm3.h>
|
||||
|
||||
#include <gmssl/asn1.h>
|
||||
|
||||
/*
|
||||
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
|
||||
}
|
||||
|
||||
#ifndef ENABLE_SM2_Z256_ARMV8
|
||||
void sm2_z256_point_dbl(SM2_Z256_POINT *R, const SM2_Z256_POINT *A)
|
||||
{
|
||||
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
|
||||
sm2_z256_modp_mul_by_2(S, Y1);
|
||||
|
||||
sm2_z256_print(stderr, 0, 0, "1. S = 2*Y1", S);
|
||||
|
||||
// Zsqr = Z1^2
|
||||
sm2_z256_modp_mont_sqr(Zsqr, Z1);
|
||||
sm2_z256_print(stderr, 0, 0, "2. Zsqr = Z1^2", Zsqr);
|
||||
|
||||
// S = S^2 = 4*Y1^2
|
||||
sm2_z256_modp_mont_sqr(S, S);
|
||||
sm2_z256_print(stderr, 0, 0, "3. S = S^2 = 4*Y1^2", S);
|
||||
|
||||
// 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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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)
|
||||
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)
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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)
|
||||
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
|
||||
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->Z, res_z, sizeof(res_z));
|
||||
}
|
||||
#endif
|
||||
|
||||
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 都转换为实际输入的值
|
||||
#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)
|
||||
{
|
||||
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->Z, res_z, sizeof(res_z));
|
||||
}
|
||||
#endif
|
||||
|
||||
void sm2_z256_point_sub_affine(SM2_Z256_POINT *R,
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -20,64 +20,34 @@
|
||||
#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)
|
||||
{
|
||||
SM2_U256_POINT _P, *P = &_P;
|
||||
SM2_U256 d;
|
||||
SM2_U256 d_inv;
|
||||
SM2_U256 e;
|
||||
SM2_U256 k;
|
||||
SM2_U256 x;
|
||||
SM2_U256 t;
|
||||
SM2_U256 r;
|
||||
SM2_U256 s;
|
||||
SM2_Z256_POINT _P, *P = &_P;
|
||||
SM2_Z256 d;
|
||||
SM2_Z256 d_inv;
|
||||
SM2_Z256 e;
|
||||
SM2_Z256 k;
|
||||
SM2_Z256 x;
|
||||
SM2_Z256 t;
|
||||
SM2_Z256 r;
|
||||
SM2_Z256 s;
|
||||
|
||||
const uint64_t *one = sm2_u256_one();
|
||||
const uint64_t *order = sm2_u256_order();
|
||||
const uint64_t *one = sm2_z256_one();
|
||||
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)
|
||||
sm2_u256_modn_add(d_inv, d, one); //sm2_bn_print(stderr, 0, 4, "(1+d)", d_inv);
|
||||
if (sm2_u256_is_zero(d_inv)) {
|
||||
sm2_z256_modn_add(d_inv, d, one); //sm2_bn_print(stderr, 0, 4, "(1+d)", d_inv);
|
||||
if (sm2_z256_is_zero(d_inv)) {
|
||||
error_print();
|
||||
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)
|
||||
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:
|
||||
|
||||
@@ -86,15 +56,15 @@ retry:
|
||||
|
||||
// rand k in [1, n - 1]
|
||||
do {
|
||||
if (sm2_u256_modn_rand(k) != 1) {
|
||||
if (sm2_z256_modn_rand(k) != 1) {
|
||||
error_print();
|
||||
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
|
||||
sm2_u256_point_mul_generator(P, k);
|
||||
sm2_u256_point_get_xy(P, x, NULL);
|
||||
sm2_z256_point_mul_generator(P, k);
|
||||
sm2_z256_point_get_xy(P, x, NULL);
|
||||
//sm2_bn_print(stderr, 0, 4, "x", x);
|
||||
|
||||
|
||||
@@ -104,33 +74,33 @@ retry:
|
||||
// >>>>>>>>>>> END PRECOMP
|
||||
|
||||
// r = e + x (mod n)
|
||||
if (sm2_u256_cmp(e, order) >= 0) {
|
||||
sm2_u256_sub(e, e, order);
|
||||
if (sm2_z256_cmp(e, order) >= 0) {
|
||||
sm2_z256_sub(e, e, order);
|
||||
}
|
||||
if (sm2_u256_cmp(x, order) >= 0) {
|
||||
sm2_u256_sub(x, x, order);
|
||||
if (sm2_z256_cmp(x, order) >= 0) {
|
||||
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
|
||||
sm2_u256_add(t, r, k);
|
||||
if (sm2_u256_is_zero(r) || sm2_u256_cmp(t, order) == 0) {
|
||||
sm2_z256_add(t, r, k);
|
||||
if (sm2_z256_is_zero(r) || sm2_z256_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_u256_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_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(t, r, d); //sm2_bn_print(stderr, 0, 4, "r*d", t);
|
||||
sm2_z256_modn_sub(k, k, t); //sm2_bn_print(stderr, 0, 4, "k-r*d", k);
|
||||
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
|
||||
if (sm2_u256_is_zero(s)) {
|
||||
if (sm2_z256_is_zero(s)) {
|
||||
goto retry;
|
||||
}
|
||||
|
||||
sm2_u256_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(r, sig->r); //sm2_bn_print_bn(stderr, 0, 4, "r", r);
|
||||
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_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));
|
||||
|
||||
// (x1, y1) = kG
|
||||
sm2_u256_point_mul_generator(&P, k); // 这个函数要粗力度并行,这要怎么做?
|
||||
sm2_u256_point_get_xy(&P, x1, NULL);
|
||||
sm2_z256_point_mul_generator(&P, k); // 这个函数要粗力度并行,这要怎么做?
|
||||
sm2_z256_point_get_xy(&P, x1, NULL);
|
||||
|
||||
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_sub(s, s, r);
|
||||
|
||||
sm2_u256_to_bytes(r, sig->r);
|
||||
sm2_u256_to_bytes(s, sig->s);
|
||||
sm2_z256_to_bytes(r, sig->r);
|
||||
sm2_z256_to_bytes(s, sig->s);
|
||||
|
||||
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)
|
||||
{
|
||||
SM2_U256_POINT R;
|
||||
SM2_U256 e;
|
||||
SM2_U256 k;
|
||||
SM2_U256 x1;
|
||||
SM2_U256 r;
|
||||
SM2_U256 s;
|
||||
SM2_Z256_POINT R;
|
||||
SM2_Z256 e;
|
||||
SM2_Z256 k;
|
||||
SM2_Z256 x1;
|
||||
SM2_Z256 r;
|
||||
SM2_Z256 s;
|
||||
|
||||
const uint64_t *order = sm2_u256_order();
|
||||
const uint64_t *order = sm2_z256_order();
|
||||
|
||||
// e = H(M)
|
||||
sm2_u256_from_bytes(e, dgst);
|
||||
if (sm2_u256_cmp(e, order) >= 0) {
|
||||
sm2_u256_sub(e, e, order);
|
||||
sm2_z256_from_bytes(e, dgst);
|
||||
if (sm2_z256_cmp(e, order) >= 0) {
|
||||
sm2_z256_sub(e, e, order);
|
||||
}
|
||||
|
||||
/// <<<<<<<<<<< 这里的 (k, x1) 应该是从外部输入的!!,这样才是最快的。
|
||||
|
||||
// rand k in [1, n - 1]
|
||||
do {
|
||||
if (sm2_u256_modn_rand(k) != 1) {
|
||||
if (sm2_z256_modn_rand(k) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
} while (sm2_u256_is_zero(k));
|
||||
} while (sm2_z256_is_zero(k));
|
||||
|
||||
// (x1, y1) = kG
|
||||
sm2_u256_point_mul_generator(&R, k); // 这个函数要粗力度并行,这要怎么做?
|
||||
sm2_u256_point_get_xy(&R, x1, NULL);
|
||||
sm2_z256_point_mul_generator(&R, k); // 这个函数要粗力度并行,这要怎么做?
|
||||
sm2_z256_point_get_xy(&R, x1, NULL);
|
||||
|
||||
/// >>>>>>>>>>>>>>>>>>
|
||||
|
||||
// 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
|
||||
sm2_u256_modn_add(s, k, r);
|
||||
sm2_u256_modn_mul(s, s, d);
|
||||
sm2_u256_modn_sub(s, s, r);
|
||||
sm2_z256_modn_add(s, k, r);
|
||||
sm2_z256_modn_mul(s, s, d);
|
||||
sm2_z256_modn_sub(s, s, r);
|
||||
|
||||
sm2_u256_to_bytes(r, sig->r);
|
||||
sm2_u256_to_bytes(s, sig->s);
|
||||
sm2_z256_to_bytes(r, sig->r);
|
||||
sm2_z256_to_bytes(s, sig->s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -253,62 +223,62 @@ int sm2_do_sign_fast(const uint64_t d[4], const uint8_t dgst[32], SM2_SIGNATURE
|
||||
// 这里根本没有modn的乘法
|
||||
int sm2_do_verify_fast(const SM2_Z256_POINT *P, const uint8_t dgst[32], const SM2_SIGNATURE *sig)
|
||||
{
|
||||
SM2_U256_POINT R;
|
||||
SM2_U256 r;
|
||||
SM2_U256 s;
|
||||
SM2_U256 e;
|
||||
SM2_U256 x;
|
||||
SM2_U256 t;
|
||||
SM2_Z256_POINT R;
|
||||
SM2_Z256 r;
|
||||
SM2_Z256 s;
|
||||
SM2_Z256 e;
|
||||
SM2_Z256 x;
|
||||
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]
|
||||
if (sm2_u256_is_zero(r) == 1) {
|
||||
if (sm2_z256_is_zero(r) == 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (sm2_u256_cmp(r, order) >= 0) {
|
||||
if (sm2_z256_cmp(r, order) >= 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
sm2_u256_from_bytes(s, sig->s);
|
||||
sm2_z256_from_bytes(s, sig->s);
|
||||
// check s in [1, n-1]
|
||||
if (sm2_u256_is_zero(s) == 1) {
|
||||
if (sm2_z256_is_zero(s) == 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (sm2_u256_cmp(s, order) >= 0) {
|
||||
if (sm2_z256_cmp(s, order) >= 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// e = H(M)
|
||||
sm2_u256_from_bytes(e, dgst);
|
||||
sm2_z256_from_bytes(e, dgst);
|
||||
|
||||
// t = r + s (mod n), check t != 0
|
||||
sm2_u256_modn_add(t, r, s);
|
||||
if (sm2_u256_is_zero(t)) {
|
||||
sm2_z256_modn_add(t, r, s);
|
||||
if (sm2_z256_is_zero(t)) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Q = s * G + t * P
|
||||
sm2_u256_point_mul_sum(&R, t, P, s);
|
||||
sm2_u256_point_get_xy(&R, x, NULL);
|
||||
sm2_z256_point_mul_sum(&R, t, P, s);
|
||||
sm2_z256_point_get_xy(&R, x, NULL);
|
||||
|
||||
// r' = e + x (mod n)
|
||||
if (sm2_u256_cmp(e, order) >= 0) {
|
||||
sm2_u256_sub(e, e, order);
|
||||
if (sm2_z256_cmp(e, order) >= 0) {
|
||||
sm2_z256_sub(e, e, order);
|
||||
}
|
||||
if (sm2_u256_cmp(x, order) >= 0) {
|
||||
sm2_u256_sub(x, x, order);
|
||||
if (sm2_z256_cmp(x, order) >= 0) {
|
||||
sm2_z256_sub(x, x, order);
|
||||
}
|
||||
sm2_u256_modn_add(e, e, x);
|
||||
sm2_z256_modn_add(e, e, x);
|
||||
|
||||
// check if r == r'
|
||||
if (sm2_u256_cmp(e, r) != 0) {
|
||||
if (sm2_z256_cmp(e, r) != 0) {
|
||||
error_print();
|
||||
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)
|
||||
{
|
||||
SM2_U256_POINT _P, *P = &_P;
|
||||
SM2_U256_POINT _R, *R = &_R;
|
||||
SM2_U256 r;
|
||||
SM2_U256 s;
|
||||
SM2_U256 e;
|
||||
SM2_U256 x;
|
||||
SM2_U256 t;
|
||||
SM2_Z256_POINT _P, *P = &_P;
|
||||
SM2_Z256_POINT _R, *R = &_R;
|
||||
SM2_Z256 r;
|
||||
SM2_Z256 s;
|
||||
SM2_Z256 e;
|
||||
SM2_Z256 x;
|
||||
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
|
||||
sm2_u256_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_z256_point_from_bytes(P, (const uint8_t *)&key->public_key);
|
||||
//sm2_jacobian_point_print(stderr, 0, 4, "P", P);
|
||||
|
||||
// parse signature values
|
||||
sm2_u256_from_bytes(r, sig->r); sm2_u256_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(r, sig->r); sm2_z256_print(stderr, 0, 4, "r", r);
|
||||
sm2_z256_from_bytes(s, sig->s); sm2_z256_print(stderr, 0, 4, "s", s);
|
||||
|
||||
// check r, s in [1, n-1]
|
||||
if (sm2_u256_is_zero(r) == 1) {
|
||||
if (sm2_z256_is_zero(r) == 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (sm2_u256_cmp(r, order) >= 0) {
|
||||
sm2_u256_print(stderr, 0, 4, "err: r", r);
|
||||
sm2_u256_print(stderr, 0, 4, "err: order", order);
|
||||
if (sm2_z256_cmp(r, order) >= 0) {
|
||||
sm2_z256_print(stderr, 0, 4, "err: r", r);
|
||||
sm2_z256_print(stderr, 0, 4, "err: order", order);
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (sm2_u256_is_zero(s) == 1) {
|
||||
if (sm2_z256_is_zero(s) == 1) {
|
||||
error_print();
|
||||
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_u256_print(stderr, 0, 4, "err: order", order);
|
||||
sm2_z256_print(stderr, 0, 4, "err: s", s);
|
||||
sm2_z256_print(stderr, 0, 4, "err: order", order);
|
||||
|
||||
printf(">>>>>\n");
|
||||
int r = sm2_u256_cmp(s, order);
|
||||
int r = sm2_z256_cmp(s, order);
|
||||
fprintf(stderr, "cmp ret = %d\n", r);
|
||||
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)
|
||||
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
|
||||
sm2_u256_modn_add(t, r, s); //sm2_bn_print(stderr, 0, 4, "t = r + s (mod n)", t);
|
||||
if (sm2_u256_is_zero(t)) {
|
||||
sm2_z256_modn_add(t, r, s); //sm2_bn_print(stderr, 0, 4, "t = r + s (mod n)", t);
|
||||
if (sm2_z256_is_zero(t)) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Q = s * G + t * P
|
||||
sm2_u256_point_mul_sum(R, t, P, s);
|
||||
sm2_u256_point_get_xy(R, x, NULL);
|
||||
sm2_z256_point_mul_sum(R, t, P, s);
|
||||
sm2_z256_point_get_xy(R, x, NULL);
|
||||
//sm2_bn_print(stderr, 0, 4, "x", x);
|
||||
|
||||
// r' = e + x (mod n)
|
||||
if (sm2_u256_cmp(e, order) >= 0) {
|
||||
sm2_u256_sub(e, e, order);
|
||||
if (sm2_z256_cmp(e, order) >= 0) {
|
||||
sm2_z256_sub(e, e, order);
|
||||
}
|
||||
if (sm2_u256_cmp(x, order) >= 0) {
|
||||
sm2_u256_sub(x, x, order);
|
||||
if (sm2_z256_cmp(x, order) >= 0) {
|
||||
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'
|
||||
if (sm2_u256_cmp(e, r) != 0) {
|
||||
if (sm2_z256_cmp(e, r) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -433,10 +403,10 @@ int sm2_do_encrypt_pre_compute(uint64_t k[4], uint8_t C1[64])
|
||||
// 其中k是要参与计算的,但是 (x1, y1) 不参与计算,输出为 bytes 就可以了
|
||||
int sm2_do_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out)
|
||||
{
|
||||
SM2_U256 k;
|
||||
SM2_U256_POINT _P, *P = &_P;
|
||||
SM2_U256_POINT _C1, *C1 = &_C1;
|
||||
SM2_U256_POINT _kP, *kP = &_kP;
|
||||
SM2_Z256 k;
|
||||
SM2_Z256_POINT _P, *P = &_P;
|
||||
SM2_Z256_POINT _C1, *C1 = &_C1;
|
||||
SM2_Z256_POINT _kP, *kP = &_kP;
|
||||
uint8_t x2y2[64];
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
// for sm2 curve, h == 1 and S == P
|
||||
@@ -455,19 +425,19 @@ retry:
|
||||
// rand k in [1, n - 1]
|
||||
// TODO: set rand_bytes output for testing
|
||||
do {
|
||||
if (sm2_u256_modn_rand(k) != 1) {
|
||||
if (sm2_z256_modn_rand(k) != 1) {
|
||||
error_print();
|
||||
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)
|
||||
sm2_u256_point_mul_generator(C1, k);
|
||||
sm2_u256_point_to_bytes(C1, (uint8_t *)&out->point);
|
||||
sm2_z256_point_mul_generator(C1, k);
|
||||
sm2_z256_point_to_bytes(C1, (uint8_t *)&out->point);
|
||||
|
||||
// k * P = (x2, y2)
|
||||
sm2_u256_point_mul(kP, k, P);
|
||||
sm2_u256_point_to_bytes(kP, x2y2);
|
||||
sm2_z256_point_mul(kP, k, P);
|
||||
sm2_z256_point_to_bytes(kP, x2y2);
|
||||
|
||||
// t = KDF(x2 || y2, inlen)
|
||||
sm2_kdf(x2y2, 64, inlen, out->ciphertext);
|
||||
@@ -489,7 +459,7 @@ retry:
|
||||
sm3_finish(&sm3_ctx, out->hash);
|
||||
|
||||
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));
|
||||
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)
|
||||
{
|
||||
unsigned int trys = 200;
|
||||
SM2_U256 k;
|
||||
SM2_U256_POINT _P, *P = &_P;
|
||||
SM2_U256_POINT _C1, *C1 = &_C1;
|
||||
SM2_U256_POINT _kP, *kP = &_kP;
|
||||
SM2_Z256 k;
|
||||
SM2_Z256_POINT _P, *P = &_P;
|
||||
SM2_Z256_POINT _C1, *C1 = &_C1;
|
||||
SM2_Z256_POINT _kP, *kP = &_kP;
|
||||
uint8_t x2y2[64];
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
// 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:
|
||||
// rand k in [1, n - 1]
|
||||
do {
|
||||
if (sm2_u256_modn_rand(k) != 1) {
|
||||
if (sm2_z256_modn_rand(k) != 1) {
|
||||
error_print();
|
||||
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)
|
||||
sm2_u256_point_mul_generator(C1, k);
|
||||
sm2_u256_point_to_bytes(C1, (uint8_t *)&out->point);
|
||||
sm2_z256_point_mul_generator(C1, k);
|
||||
sm2_z256_point_to_bytes(C1, (uint8_t *)&out->point);
|
||||
|
||||
// check fixlen
|
||||
if (trys) {
|
||||
@@ -554,8 +524,8 @@ retry:
|
||||
}
|
||||
|
||||
// k * P = (x2, y2)
|
||||
sm2_u256_point_mul(kP, k, P);
|
||||
sm2_u256_point_to_bytes(kP, x2y2);
|
||||
sm2_z256_point_mul(kP, k, P);
|
||||
sm2_z256_point_to_bytes(kP, x2y2);
|
||||
|
||||
// t = KDF(x2 || y2, inlen)
|
||||
sm2_kdf(x2y2, 64, inlen, out->ciphertext);
|
||||
@@ -577,7 +547,7 @@ retry:
|
||||
sm3_finish(&sm3_ctx, out->hash);
|
||||
|
||||
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));
|
||||
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 ret = -1;
|
||||
SM2_U256 d;
|
||||
SM2_U256_POINT _C1, *C1 = &_C1;
|
||||
SM2_Z256 d;
|
||||
SM2_Z256_POINT _C1, *C1 = &_C1;
|
||||
uint8_t x2y2[64];
|
||||
SM3_CTX sm3_ctx;
|
||||
uint8_t hash[32];
|
||||
|
||||
// check C1 is on sm2 curve
|
||||
sm2_u256_point_from_bytes(C1, (uint8_t *)&in->point);
|
||||
if (!sm2_u256_point_is_on_curve(C1)) {
|
||||
sm2_z256_point_from_bytes(C1, (uint8_t *)&in->point);
|
||||
if (!sm2_z256_point_is_on_curve(C1)) {
|
||||
error_print();
|
||||
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
|
||||
|
||||
// d * C1 = (x2, y2)
|
||||
sm2_u256_from_bytes(d, key->private_key);
|
||||
sm2_u256_point_mul(C1, d, C1);
|
||||
sm2_z256_from_bytes(d, key->private_key);
|
||||
sm2_z256_point_mul(C1, d, C1);
|
||||
|
||||
// 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);
|
||||
if (all_zero(out, in->ciphertext_size)) {
|
||||
error_print();
|
||||
@@ -633,7 +603,7 @@ int sm2_do_decrypt(const SM2_KEY *key, const SM2_CIPHERTEXT *in, uint8_t *out, s
|
||||
|
||||
end:
|
||||
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));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -517,10 +517,22 @@ static int test_sm2_z256_point_add_conjugate(void)
|
||||
sm2_z256_point_from_hex(&Q, hex_negG);
|
||||
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)
|
||||
/*
|
||||
// 有可能在计算的时候,已经发现这是共轭点,那就不做进一步的计算了
|
||||
if (!sm2_z256_is_zero(R.X)
|
||||
|| !sm2_z256_is_zero(R.Y)
|
||||
|| !sm2_z256_is_zero(R.Z)) {
|
||||
|| !sm2_z256_is_zero(R.Y)) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
|
||||
if (!sm2_z256_is_zero(R.Z)) {
|
||||
error_print();
|
||||
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_dbl(&R, &P_infinity); // 显然这个计算就会出错了!
|
||||
sm2_z256_print(stderr, 0, 0, "ret", R.X);
|
||||
|
||||
if (!sm2_z256_point_is_at_infinity(&R)) {
|
||||
error_print(); // 这个会出错
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -616,6 +629,9 @@ static int test_sm2_z256_point_ops(void)
|
||||
break;
|
||||
case OP_DBL:
|
||||
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;
|
||||
case OP_SUB:
|
||||
sm2_z256_point_sub(&P, &A, &B);
|
||||
@@ -860,6 +876,8 @@ static int test_sm2_z256_point_from_hash(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_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_get_xy() != 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_from_hash() != 1) goto err;
|
||||
if (test_sm2_z256_point_from_x_bytes() != 1) goto err;
|
||||
|
||||
Reference in New Issue
Block a user