Use z256 and jacobian coordinates as inner presentation of SM2 point

This commit is contained in:
Zhi Guan
2024-04-18 21:27:00 +08:00
parent 549c68d2df
commit e9bbcf5490
18 changed files with 312 additions and 646 deletions

View File

@@ -17,63 +17,25 @@
#include <stdlib.h>
#include <gmssl/api.h>
#include <gmssl/sm3.h>
#include <gmssl/sm2_z256.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef uint8_t sm2_bn_t[32];
typedef struct {
uint8_t x[32];
uint8_t y[32];
} SM2_POINT;
#define sm2_point_init(P) memset((P),0,sizeof(SM2_POINT))
#define sm2_point_set_infinity(P) sm2_point_init(P)
int sm2_point_from_octets(SM2_POINT *P, const uint8_t *in, size_t inlen);
void sm2_point_to_compressed_octets(const SM2_POINT *P, uint8_t out[33]);
void sm2_point_to_uncompressed_octets(const SM2_POINT *P, uint8_t out[65]);
int sm2_point_from_x(SM2_POINT *P, const uint8_t x[32], int y);
int sm2_point_from_xy(SM2_POINT *P, const uint8_t x[32], const uint8_t y[32]);
int sm2_point_is_on_curve(const SM2_POINT *P);
int sm2_point_is_at_infinity(const SM2_POINT *P);
int sm2_point_add(SM2_POINT *R, const SM2_POINT *P, const SM2_POINT *Q);
int sm2_point_sub(SM2_POINT *R, const SM2_POINT *P, const SM2_POINT *Q);
int sm2_point_neg(SM2_POINT *R, const SM2_POINT *P);
int sm2_point_dbl(SM2_POINT *R, const SM2_POINT *P);
int sm2_point_mul(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P);
int sm2_point_mul_generator(SM2_POINT *R, const uint8_t k[32]);
int sm2_point_mul_sum(SM2_POINT *R, const uint8_t k[32], const SM2_POINT *P, const uint8_t s[32]); // R = k * P + s * G
/*
RFC 5480 Elliptic Curve Cryptography Subject Public Key Information
ECPoint ::= OCTET STRING
*/
#define SM2_POINT_MAX_SIZE (2 + 65)
int sm2_point_to_der(const SM2_POINT *P, uint8_t **out, size_t *outlen);
int sm2_point_from_der(SM2_POINT *P, const uint8_t **in, size_t *inlen);
int sm2_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_POINT *P);
int sm2_point_from_hash(SM2_POINT *R, const uint8_t *data, size_t datalen);
typedef struct {
SM2_POINT public_key;
uint8_t private_key[32];
SM2_Z256_POINT public_key;
sm2_z256_t private_key;
} SM2_KEY;
_gmssl_export int sm2_key_generate(SM2_KEY *key);
int sm2_key_set_private_key(SM2_KEY *key, const uint8_t private_key[32]); // key->public_key will be replaced
int sm2_key_set_public_key(SM2_KEY *key, const SM2_POINT *public_key); // key->private_key will be cleared // FIXME: support octets as input?
int sm2_key_set_private_key(SM2_KEY *key, const sm2_z256_t private_key);
int sm2_key_set_public_key(SM2_KEY *key, const SM2_Z256_POINT *public_key);
int sm2_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *key);
int sm2_public_key_equ(const SM2_KEY *sm2_key, const SM2_KEY *pub_key);
//int sm2_public_key_copy(SM2_KEY *sm2_key, const SM2_KEY *pub_key); // do we need this?
int sm2_public_key_digest(const SM2_KEY *key, uint8_t dgst[32]);
int sm2_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY *pub_key);
@@ -156,6 +118,12 @@ _gmssl_export int sm2_private_key_info_encrypt_to_pem(const SM2_KEY *key, const
_gmssl_export int sm2_private_key_info_decrypt_from_pem(SM2_KEY *key, const char *pass, FILE *fp);
typedef struct {
uint8_t r[32];
uint8_t s[32];
@@ -164,6 +132,10 @@ typedef struct {
int sm2_do_sign(const SM2_KEY *key, 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_fast_sign_compute_key(const SM2_KEY *key, sm2_z256_t fast_private);
int sm2_fast_sign_pre_compute(sm2_z256_t k, sm2_z256_t x1_modn);
int sm2_fast_sign(const sm2_z256_t fast_private, const sm2_z256_t k, const sm2_z256_t x1,
const uint8_t dgst[32], SM2_SIGNATURE *sig);
@@ -190,31 +162,25 @@ int sm2_sign_fixlen(const SM2_KEY *key, const uint8_t dgst[32], size_t siglen, u
#define SM2_MAX_ID_BITS 65535
#define SM2_MAX_ID_LENGTH (SM2_MAX_ID_BITS/8)
int sm2_compute_z(uint8_t z[32], const SM2_POINT *pub, const char *id, size_t idlen);
int sm2_compute_z(uint8_t z[32], const SM2_Z256_POINT *pub, const char *id, size_t idlen);
typedef struct {
uint64_t k[4];
uint64_t x1[4];
sm2_z256_t k;
sm2_z256_t x1; // x1 (mod n)
} SM2_SIGN_PRE_COMP;
#define SM2_SIGN_PRE_COMP_COUNT 32
typedef struct {
SM3_CTX sm3_ctx;
SM3_CTX saved_sm3_ctx;
SM2_KEY key;
// FIXME: change `key` to SM2_Z256_POINT and uint64_t[4], inner type, faster sign/verify
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];
sm2_z256_t fast_sign_private;
SM2_SIGN_PRE_COMP pre_comp[SM2_SIGN_PRE_COMP_COUNT];
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);
@@ -236,6 +202,11 @@ SM2Cipher ::= SEQUENCE {
#define SM2_MIN_PLAINTEXT_SIZE 1 // re-compute SM2_MIN_CIPHERTEXT_SIZE when modify
#define SM2_MAX_PLAINTEXT_SIZE 255 // re-compute SM2_MAX_CIPHERTEXT_SIZE when modify
typedef struct {
uint8_t x[32];
uint8_t y[32];
} SM2_POINT;
typedef struct {
SM2_POINT point;
uint8_t hash[32];
@@ -243,6 +214,7 @@ typedef struct {
uint8_t ciphertext[SM2_MAX_PLAINTEXT_SIZE];
} SM2_CIPHERTEXT;
int sm2_kdf(const uint8_t *in, size_t inlen, size_t outlen, uint8_t *out);
int sm2_do_encrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, SM2_CIPHERTEXT *out);
@@ -265,8 +237,8 @@ int sm2_do_encrypt_fixlen(const SM2_KEY *key, const uint8_t *in, size_t inlen, i
int sm2_encrypt_fixlen(const SM2_KEY *key, const uint8_t *in, size_t inlen, int point_size, uint8_t *out, size_t *outlen);
int sm2_do_ecdh(const SM2_KEY *key, const SM2_POINT *peer_public, SM2_POINT *out);
_gmssl_export int sm2_ecdh(const SM2_KEY *key, const uint8_t *peer_public, size_t peer_public_len, SM2_POINT *out);
int sm2_do_ecdh(const SM2_KEY *key, const SM2_Z256_POINT *peer_public, SM2_Z256_POINT *out);
_gmssl_export int sm2_ecdh(const SM2_KEY *key, const uint8_t *peer_public, size_t peer_public_len, uint8_t out[64]);
typedef struct {

View File

@@ -15,14 +15,19 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <gmssl/sm2.h>
#ifdef __cplusplus
extern "C" {
#endif
// z256 means compact presentation of uint256
typedef uint64_t sm2_z256_t[4];
void sm2_z256_set_one(sm2_z256_t r);
void sm2_z256_set_zero(sm2_z256_t r);
int sm2_z256_rand_range(uint64_t r[4], const uint64_t range[4]);
void sm2_z256_copy(uint64_t r[4], const uint64_t a[4]);
void sm2_z256_copy_conditional(uint64_t dst[4], const uint64_t src[4], uint64_t move);
@@ -38,7 +43,7 @@ void sm2_z256_mul(uint64_t r[8], const uint64_t a[4], const uint64_t b[4]);
int sm2_z256_get_booth(const uint64_t a[4], unsigned int window_size, int i);
void sm2_z256_from_hex(uint64_t r[4], const char *hex);
int sm2_z256_equ_hex(const uint64_t a[4], const char *hex);
int sm2_z256_print(FILE *fp, int ind, int fmt, const char *label, const uint64_t a[4]);
int sm2_z256_print(FILE *fp, int ind, int fmt, const char *label, const sm2_z256_t a);
void sm2_z256_modp_add(uint64_t r[4], const uint64_t a[4], const uint64_t b[4]);
void sm2_z256_modp_dbl(uint64_t r[4], const uint64_t a[4]);
@@ -79,7 +84,7 @@ typedef struct {
} SM2_Z256_POINT;
void sm2_z256_point_set_infinity(SM2_Z256_POINT *P);
void sm2_z256_point_from_bytes(SM2_Z256_POINT *P, const uint8_t in[64]); // 检查is_on_curve
int sm2_z256_point_from_bytes(SM2_Z256_POINT *P, const uint8_t in[64]);
void sm2_z256_point_to_bytes(const SM2_Z256_POINT *P, uint8_t out[64]);
int sm2_z256_point_is_at_infinity(const SM2_Z256_POINT *P);
@@ -131,12 +136,20 @@ int sm2_z256_point_from_x_bytes(SM2_Z256_POINT *P, const uint8_t x_bytes[32], in
int sm2_z256_point_from_hash(SM2_Z256_POINT *R, const uint8_t *data, size_t datalen, int y_is_odd);
int sm2_z256_point_from_octets(SM2_Z256_POINT *P, const uint8_t *in, size_t inlen);
int sm2_z256_point_to_uncompressed_octets(const SM2_Z256_POINT *P, uint8_t out[65]);
int sm2_z256_point_to_compressed_octets(const SM2_Z256_POINT *P, uint8_t out[33]);
int sm2_z256_point_from_octets(SM2_Z256_POINT *P, const uint8_t *in, size_t inlen);
/*
RFC 5480 Elliptic Curve Cryptography Subject Public Key Information
ECPoint ::= OCTET STRING
*/
#define SM2_POINT_MAX_SIZE (2 + 65)
int sm2_z256_point_to_der(const SM2_Z256_POINT *P, uint8_t **out, size_t *outlen);
int sm2_z256_point_from_der(SM2_Z256_POINT *P, const uint8_t **in, size_t *inlen);
int sm2_z256_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_Z256_POINT *P);
// 这些函数还是放到sm2_sign里面好了反正这个依赖关系是处理不了的
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
}

View File

@@ -502,13 +502,13 @@ int tls13_process_client_supported_versions(const uint8_t *ext_data, size_t ext_
int tls13_process_server_supported_versions(const uint8_t *ext_data, size_t ext_datalen);
int tls13_key_share_entry_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen);
int tls13_client_key_share_ext_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen);
int tls13_server_key_share_ext_to_bytes(const SM2_POINT *point, uint8_t **out, size_t *outlen);
int tls13_key_share_entry_to_bytes(const SM2_Z256_POINT *point, uint8_t **out, size_t *outlen);
int tls13_client_key_share_ext_to_bytes(const SM2_Z256_POINT *point, uint8_t **out, size_t *outlen);
int tls13_server_key_share_ext_to_bytes(const SM2_Z256_POINT *point, uint8_t **out, size_t *outlen);
int tls13_process_client_key_share(const uint8_t *ext_data, size_t ext_datalen,
const SM2_KEY *server_ecdhe_key, SM2_POINT *client_ecdhe_public,
const SM2_KEY *server_ecdhe_key, SM2_Z256_POINT *client_ecdhe_public,
uint8_t **out, size_t *outlen);
int tls13_process_server_key_share(const uint8_t *ext_data, size_t ext_datalen, SM2_POINT *point);
int tls13_process_server_key_share(const uint8_t *ext_data, size_t ext_datalen, SM2_Z256_POINT *point);
int tls13_certificate_authorities_ext_to_bytes(const uint8_t *ca_names, size_t ca_names_len,
@@ -533,14 +533,14 @@ int tls_server_key_exchange_print(FILE *fp, const uint8_t *ske, size_t skelen, i
#define TLS_MAX_SIGNATURE_SIZE SM2_MAX_SIGNATURE_SIZE
int tls_sign_server_ecdh_params(const SM2_KEY *server_sign_key,
const uint8_t client_random[32], const uint8_t server_random[32],
int curve, const SM2_POINT *point, uint8_t *sig, size_t *siglen);
int curve, const SM2_Z256_POINT *point, uint8_t *sig, size_t *siglen);
int tls_verify_server_ecdh_params(const SM2_KEY *server_sign_key,
const uint8_t client_random[32], const uint8_t server_random[32],
int curve, const SM2_POINT *point, const uint8_t *sig, size_t siglen);
int curve, const SM2_Z256_POINT *point, const uint8_t *sig, size_t siglen);
int tls_record_set_handshake_server_key_exchange_ecdhe(uint8_t *record, size_t *recordlen,
int curve, const SM2_POINT *point, const uint8_t *sig, size_t siglen);
int curve, const SM2_Z256_POINT *point, const uint8_t *sig, size_t siglen);
int tls_record_get_handshake_server_key_exchange_ecdhe(const uint8_t *record,
int *curve, SM2_POINT *point, const uint8_t **sig, size_t *siglen);
int *curve, SM2_Z256_POINT *point, const uint8_t **sig, size_t *siglen);
int tls_server_key_exchange_ecdhe_print(FILE *fp, const uint8_t *data, size_t datalen,
int format, int indent);
@@ -583,8 +583,8 @@ int tls_client_key_exchange_pke_print(FILE *fp, const uint8_t *cke, size_t ckele
int tls_client_key_exchange_print(FILE *fp, const uint8_t *cke, size_t ckelen, int format, int indent);
int tls_record_set_handshake_client_key_exchange_ecdhe(uint8_t *record, size_t *recordlen,
const SM2_POINT *point); // 这里不应该支持SM2_POINT类型
int tls_record_get_handshake_client_key_exchange_ecdhe(const uint8_t *record, SM2_POINT *point);
const SM2_Z256_POINT *point); // 这里不应该支持SM2_POINT类型
int tls_record_get_handshake_client_key_exchange_ecdhe(const uint8_t *record, SM2_Z256_POINT *point);
int tls_client_key_exchange_ecdhe_print(FILE *fp, const uint8_t *data, size_t datalen,
int format, int indent);