diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f24964e..b6939b28 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -177,6 +177,19 @@ if (ENABLE_SM4_AESNI_AVX) endif() +option(ENABLE_SM2_EXTS "Enable SM2 Extensions" OFF) +if (ENABLE_SM2_EXTS) + list(APPEND src + src/sm2_key_share.c + src/sm2_recover.c + src/sm2_blind.c + src/sm2_ring.c + src/sm2_elgamal.c + src/sm2_commit.c) + list(APPEND tests sm2_key_share sm2_blind sm2_ring sm2_elgamal sm2_commit) +endif() + + option(ENABLE_BROKEN_CRYPTO "Enable broken crypto algorithms" OFF) if (ENABLE_BROKEN_CRYPTO) list(APPEND src src/des.c src/sha1.c src/md5.c src/rc4.c) diff --git a/include/gmssl/sm2.h b/include/gmssl/sm2.h index 0c36303a..a4f63abc 100644 --- a/include/gmssl/sm2.h +++ b/include/gmssl/sm2.h @@ -279,19 +279,6 @@ int sm2_private_key_info_decrypt_from_der(SM2_KEY *key, const uint8_t **attrs, s int sm2_private_key_info_encrypt_to_pem(const SM2_KEY *key, const char *pass, FILE *fp); int sm2_private_key_info_decrypt_from_pem(SM2_KEY *key, const char *pass, FILE *fp); -// SM2 Key Shamir Secret Sharing -typedef struct { - SM2_KEY key; - size_t index; - size_t total_cnt; -} SM2_KEY_SHARE; - -int sm2_key_split(const SM2_KEY *key, size_t recover_cnt, size_t total_cnt, SM2_KEY_SHARE *shares); -int sm2_key_recover(SM2_KEY *key, const SM2_KEY_SHARE *shares, size_t shares_cnt); -int sm2_key_share_encrypt_to_file(const SM2_KEY_SHARE *share, const char *pass, const char *path_prefix); -int sm2_key_share_decrypt_from_file(SM2_KEY_SHARE *share, const char *pass, const char *file); -int sm2_key_share_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY_SHARE *share); - typedef struct { uint8_t r[32]; @@ -372,47 +359,8 @@ int sm2_decrypt(const SM2_KEY *key, const uint8_t *in, size_t inlen, uint8_t *ou int sm2_ecdh(const SM2_KEY *key, const SM2_POINT *peer_public, SM2_POINT *out); -int sm2_signature_to_public_key_points(const SM2_SIGNATURE *sig, const uint8_t dgst[32], - SM2_POINT points[4], size_t *points_cnt); - - -// SM2 Ring Signature - typedef uint8_t sm2_bn_t[32]; -int sm2_ring_do_sign(const SM2_KEY *sign_key, const SM2_POINT *public_keys, size_t public_keys_cnt, - const uint8_t dgst[32], uint8_t r[32], sm2_bn_t *s); -int sm2_ring_do_verify(const SM2_POINT *public_keys, size_t public_keys_cnt, - const uint8_t dgst[32], const uint8_t r[32], const sm2_bn_t *s); -int sm2_ring_signature_to_der(const sm2_bn_t r, const sm2_bn_t *s, size_t s_cnt, uint8_t **out, size_t *outlen); -int sm2_ring_signature_from_der(sm2_bn_t r, sm2_bn_t *s, size_t *s_cnt, const uint8_t **in, size_t *inlen); -int sm2_ring_sign(const SM2_KEY *sign_key, const SM2_POINT *public_keys, size_t public_keys_cnt, - const uint8_t dgst[32], uint8_t *sig, size_t *siglen); -int sm2_ring_verify(const SM2_POINT *public_keys, size_t public_keys_cnt, - const uint8_t dgst[32], const uint8_t *sig, size_t siglen); - - -#define SM2_RING_SIGN_MAX_SIGNERS 32 -typedef struct { - int state; - SM3_CTX sm3_ctx; - SM2_KEY sign_key; - SM2_POINT public_keys[SM2_RING_SIGN_MAX_SIGNERS]; - size_t public_keys_count; - char *id; - size_t idlen; -} SM2_RING_SIGN_CTX; - -int sm2_ring_sign_init(SM2_RING_SIGN_CTX *ctx, const SM2_KEY *sign_key, const char *id, size_t idlen); -int sm2_ring_sign_add_signer(SM2_RING_SIGN_CTX *ctx, const SM2_KEY *public_key); -int sm2_ring_sign_update(SM2_RING_SIGN_CTX *ctx, const uint8_t *data, size_t datalen); -int sm2_ring_sign_finish(SM2_RING_SIGN_CTX *ctx, uint8_t *sig, size_t *siglen); -int sm2_ring_verify_init(SM2_RING_SIGN_CTX *ctx, const char *id, size_t idlen); -int sm2_ring_verify_add_signer(SM2_RING_SIGN_CTX *ctx, const SM2_KEY *public_key); -int sm2_ring_verify_update(SM2_RING_SIGN_CTX *ctx, const uint8_t *data, size_t datalen); -int sm2_ring_verify_finish(SM2_RING_SIGN_CTX *ctx, uint8_t *sig, size_t siglen); - - #ifdef __cplusplus } diff --git a/include/gmssl/sm2_commit.h b/include/gmssl/sm2_commit.h index a60625c3..6df89583 100644 --- a/include/gmssl/sm2_commit.h +++ b/include/gmssl/sm2_commit.h @@ -28,12 +28,10 @@ extern "C" { #endif -typedef uint8_t sm2_bn_t[32]; - -int sm2_commit_generate(const uint8_t x[32], uint8_t r[32], uint8_t commit[65], size_t *commitlen) -int sm2_commit_open(const uint8_t x[32], const uint8_t r[32], const uint8_t *commit, size_t commitlen) -int sm2_commit_vector_generate(const sm2_bn_t *x, size_t count, uint8_t r[32], uint8_t commit[65], size_t *commitlen) -int sm2_commit_vector_open(const sm2_bn_t *x, size_t count, const uint8_t r[32], const uint8_t *commit, size_t commitlen) +int sm2_commit_generate(const uint8_t x[32], uint8_t r[32], uint8_t commit[65], size_t *commitlen); +int sm2_commit_open(const uint8_t x[32], const uint8_t r[32], const uint8_t *commit, size_t commitlen); +int sm2_commit_vector_generate(const sm2_bn_t *x, size_t count, uint8_t r[32], uint8_t commit[65], size_t *commitlen); +int sm2_commit_vector_open(const sm2_bn_t *x, size_t count, const uint8_t r[32], const uint8_t *commit, size_t commitlen); #ifdef __cplusplus diff --git a/include/gmssl/sm2_elgamal.h b/include/gmssl/sm2_elgamal.h index 892eaceb..e9ee7a9a 100644 --- a/include/gmssl/sm2_elgamal.h +++ b/include/gmssl/sm2_elgamal.h @@ -21,23 +21,45 @@ extern "C" { #endif -typedef uint32_t sm2_elgamal_plaintext_t; +#define SM2_PRE_COMPUTE_MAX_OFFSETS 6 + +typedef struct { + uint16_t offset[SM2_PRE_COMPUTE_MAX_OFFSETS]; + uint8_t offset_count; + uint8_t x_coordinate[32]; +} SM2_PRE_COMPUTE; + +int sm2_elgamal_decrypt_pre_compute(SM2_PRE_COMPUTE table[1<<16]); +int sm2_elgamal_solve_ecdlp(const SM2_PRE_COMPUTE table[1<<16], const SM2_POINT *point, uint32_t *private); + typedef struct { SM2_POINT C1; SM2_POINT C2; } SM2_ELGAMAL_CIPHERTEXT; +int sm2_elgamal_do_encrypt(const SM2_KEY *pub_key, uint32_t in, SM2_ELGAMAL_CIPHERTEXT *out); +int sm2_elgamal_do_decrypt(const SM2_KEY *key, const SM2_ELGAMAL_CIPHERTEXT *in, uint32_t *out); + +int sm2_elgamal_ciphertext_add(SM2_ELGAMAL_CIPHERTEXT *r, + const SM2_ELGAMAL_CIPHERTEXT *a, + const SM2_ELGAMAL_CIPHERTEXT *b, + const SM2_KEY *pub_key); +int sm2_elgamal_cipehrtext_sub(SM2_ELGAMAL_CIPHERTEXT *r, + const SM2_ELGAMAL_CIPHERTEXT *a, const SM2_ELGAMAL_CIPHERTEXT *b, + const SM2_KEY *pub_key); +int sm2_elgamal_cipehrtext_neg(SM2_ELGAMAL_CIPHERTEXT *r, + const SM2_ELGAMAL_CIPHERTEXT *a, const SM2_KEY *pub_key); +int sm2_elgamal_ciphertext_scalar_mul(SM2_ELGAMAL_CIPHERTEXT *R, + const uint8_t scalar[32], const SM2_ELGAMAL_CIPHERTEXT *A, + const SM2_KEY *pub_key); -int sm2_elgamal_encrypt(const SM2_KEY *pub_key, sm2_elgamal_plaintext_t in, SM2_ELGAMAL_CIPHERTEXT *out); -int sm2_elgamal_decrypt(const SM2_KEY *key, const SM2_ELGAMAL_CIPHERTEXT *in, sm2_elgamal_plaintext_t *out); -int sm2_elgamal_ciphertext_add(SM2_ELGAMAL_CIPHERTEXT *r, const SM2_ELGAMAL_CIPHERTEXT *a, const SM2_ELGAMAL_CIPHERTEXT *b, const SM2_KEY *pub_key); -int sm2_elgamal_cipehrtext_sub(SM2_ELGAMAL_CIPHERTEXT *r, const SM2_ELGAMAL_CIPHERTEXT *a, const SM2_ELGAMAL_CIPHERTEXT *b, const SM2_KEY *pub_key); -int sm2_elgamal_cipehrtext_neg(SM2_ELGAMAL_CIPHERTEXT *r, const SM2_ELGAMAL_CIPHERTEXT *a, const SM2_KEY *pub_key); -int sm2_elgamal_ciphertext_scalar_mul(SM2_ELGAMAL_CIPHERTEXT *r, uint32_t scalar, const SM2_ELGAMAL_CIPHERTEXT *a, const SM2_KEY *pub_key); int sm2_elgamal_ciphertext_to_der(const SM2_ELGAMAL_CIPHERTEXT *c, uint8_t **out, size_t *outlen); int sm2_elgamal_ciphertext_from_der(SM2_ELGAMAL_CIPHERTEXT *c, const uint8_t **in, size_t *inlen); +int sm2_elgamal_encrypt(const SM2_KEY *pub_key, uint32_t in, uint8_t *out, size_t *outlen); +int sm2_elgamal_decrypt(SM2_KEY *key, const uint8_t *in, size_t inlen, uint32_t *out); + #ifdef __cplusplus } diff --git a/include/gmssl/sm2_key_share.h b/include/gmssl/sm2_key_share.h new file mode 100644 index 00000000..7288d324 --- /dev/null +++ b/include/gmssl/sm2_key_share.h @@ -0,0 +1,45 @@ +/* + * 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 + */ + +// SM2 Key Shamir Secret Sharing + + +#ifndef GMSSL_SM2_KEY_SHARE_H +#define GMSSL_SM2_KEY_SHARE_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +#define SM2_KEY_MAX_SHARES 12 // 12! = 479001600 < 2^31 = 2147483648 + + +typedef struct { + SM2_KEY key; + size_t index; + size_t total_cnt; +} SM2_KEY_SHARE; + +int sm2_key_split(const SM2_KEY *key, size_t recover_cnt, size_t total_cnt, SM2_KEY_SHARE *shares); +int sm2_key_recover(SM2_KEY *key, const SM2_KEY_SHARE *shares, size_t shares_cnt); +int sm2_key_share_encrypt_to_file(const SM2_KEY_SHARE *share, const char *pass, const char *path_prefix); +int sm2_key_share_decrypt_from_file(SM2_KEY_SHARE *share, const char *pass, const char *file); +int sm2_key_share_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY_SHARE *share); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/sm2_recover.h b/include/gmssl/sm2_recover.h new file mode 100644 index 00000000..b89807cd --- /dev/null +++ b/include/gmssl/sm2_recover.h @@ -0,0 +1,31 @@ +/* + * 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 + */ + + + +#ifndef GMSSL_SM2_RECOVER_H +#define GMSSL_SM2_RECOVER_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int sm2_signature_to_public_key_points(const SM2_SIGNATURE *sig, const uint8_t dgst[32], + SM2_POINT points[4], size_t *points_cnt); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/gmssl/sm2_ring.h b/include/gmssl/sm2_ring.h new file mode 100644 index 00000000..6ce4e49c --- /dev/null +++ b/include/gmssl/sm2_ring.h @@ -0,0 +1,63 @@ +/* + * 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 + */ + + + +#ifndef GMSSL_SM2_RING_H +#define GMSSL_SM2_RING_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef uint8_t sm2_bn_t[32]; + +int sm2_ring_do_sign(const SM2_KEY *sign_key, const SM2_POINT *public_keys, size_t public_keys_cnt, + const uint8_t dgst[32], uint8_t r[32], sm2_bn_t *s); +int sm2_ring_do_verify(const SM2_POINT *public_keys, size_t public_keys_cnt, + const uint8_t dgst[32], const uint8_t r[32], const sm2_bn_t *s); +int sm2_ring_signature_to_der(const sm2_bn_t r, const sm2_bn_t *s, size_t s_cnt, uint8_t **out, size_t *outlen); +int sm2_ring_signature_from_der(sm2_bn_t r, sm2_bn_t *s, size_t *s_cnt, const uint8_t **in, size_t *inlen); +int sm2_ring_sign(const SM2_KEY *sign_key, const SM2_POINT *public_keys, size_t public_keys_cnt, + const uint8_t dgst[32], uint8_t *sig, size_t *siglen); +int sm2_ring_verify(const SM2_POINT *public_keys, size_t public_keys_cnt, + const uint8_t dgst[32], const uint8_t *sig, size_t siglen); + + +#define SM2_RING_SIGN_MAX_SIGNERS 32 +typedef struct { + int state; + SM3_CTX sm3_ctx; + SM2_KEY sign_key; + SM2_POINT public_keys[SM2_RING_SIGN_MAX_SIGNERS]; + size_t public_keys_count; + char *id; + size_t idlen; +} SM2_RING_SIGN_CTX; + +int sm2_ring_sign_init(SM2_RING_SIGN_CTX *ctx, const SM2_KEY *sign_key, const char *id, size_t idlen); +int sm2_ring_sign_add_signer(SM2_RING_SIGN_CTX *ctx, const SM2_KEY *public_key); +int sm2_ring_sign_update(SM2_RING_SIGN_CTX *ctx, const uint8_t *data, size_t datalen); +int sm2_ring_sign_finish(SM2_RING_SIGN_CTX *ctx, uint8_t *sig, size_t *siglen); +int sm2_ring_verify_init(SM2_RING_SIGN_CTX *ctx, const char *id, size_t idlen); +int sm2_ring_verify_add_signer(SM2_RING_SIGN_CTX *ctx, const SM2_KEY *public_key); +int sm2_ring_verify_update(SM2_RING_SIGN_CTX *ctx, const uint8_t *data, size_t datalen); +int sm2_ring_verify_finish(SM2_RING_SIGN_CTX *ctx, uint8_t *sig, size_t siglen); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/sm2_blind.c b/src/sm2_blind.c index 7e5880a2..02ea7aa7 100644 --- a/src/sm2_blind.c +++ b/src/sm2_blind.c @@ -18,6 +18,9 @@ #include +extern SM2_BN SM2_N; +extern SM2_BN SM2_ONE; + int sm2_blind_sign_commit(SM2_Fn k, uint8_t *commit, size_t *commitlen) { SM2_POINT K; @@ -169,80 +172,3 @@ int sm2_blind_sign_unblind(SM2_BLIND_SIGN_CTX *ctx, const uint8_t blinded_sig_s[ gmssl_secure_clear(ctx, sizeof(*ctx)); return 1; } - -int test_sm2_blind_sign(void) -{ - int r = -1; - - // signer - SM2_KEY key; - SM2_Fn k; - uint8_t commit[65]; - size_t commitlen; - - // caller - SM2_KEY public_key; - SM2_BLIND_SIGN_CTX sign_ctx; - uint8_t msg[128] = {0}; - uint8_t blinded_sig_s[32]; - uint8_t blinded_sig_r[32]; - uint8_t sig[128]; - size_t siglen; - - // verifier - SM2_SIGN_CTX verify_ctx; - - - // signer - if (sm2_key_generate(&key) != 1 - || sm2_key_set_public_key(&public_key, &key.public_key) != 1) { - error_print(); - goto end; - } - if (sm2_blind_sign_commit(k, commit, &commitlen) != 1) { - error_print(); - return -1; - } - format_bytes(stderr, 0, 0, "signer: commitment", commit, commitlen); - - // caller - if (sm2_blind_sign_init(&sign_ctx, &public_key, - SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1 - || sm2_blind_sign_update(&sign_ctx, msg, 32) != 1 - || sm2_blind_sign_update(&sign_ctx, msg + 32, 32) != 1 - || sm2_blind_sign_update(&sign_ctx, msg + 64, 64) != 1 - || sm2_blind_sign_finish(&sign_ctx, commit, commitlen, blinded_sig_r) != 1) { - error_print(); - goto end; - } - format_bytes(stderr, 0, 0, "caller: blinded_sig_r", blinded_sig_r, sizeof(blinded_sig_r)); - - // signer - if (sm2_blind_sign(&key, k, blinded_sig_r, blinded_sig_s) != 1) { - error_print(); - goto end; - } - format_bytes(stderr, 0, 0, "signer: blinded_sig_s", blinded_sig_s, sizeof(blinded_sig_s)); - - // caller - if (sm2_blind_sign_unblind(&sign_ctx, blinded_sig_s, sig, &siglen) != 1) { - error_print(); - goto end; - } - format_bytes(stderr, 0, 0, "caller: unblinded_sig", sig, siglen); - - // verifier - if (sm2_verify_init(&verify_ctx, &public_key, - SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1 - || sm2_verify_update(&verify_ctx, msg, sizeof(msg)) != 1 - || (r = sm2_verify_finish(&verify_ctx, sig, siglen)) < 0) { - error_print(); - goto end; - } - format_print(stderr, 0, 0, "verifier: %s\n", r == 1 ? "success" : "failure"); - -end: - gmssl_secure_clear(&key, sizeof(key)); - gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx)); - return r; -} diff --git a/src/sm2_commit.c b/src/sm2_commit.c index d3a6c0de..8bd14706 100644 --- a/src/sm2_commit.c +++ b/src/sm2_commit.c @@ -168,43 +168,5 @@ int sm2_commit_vector_open(const sm2_bn_t *x, size_t count, const uint8_t r[32], error_print(); return -1; } - return 1; -} - -int test_sm2_commit(void) -{ - uint8_t x[32]; - uint8_t xvec[8][32]; - uint8_t r[32]; - uint8_t commit[65]; - size_t commitlen; - int ret; - - rand_bytes(x, sizeof(x)); - format_bytes(stderr, 0, 0, "secret", x, sizeof(x)); - - sm2_commit_generate(x, r, commit, &commitlen); - format_bytes(stderr, 0, 0, "random", r, sizeof(r)); - format_bytes(stderr, 0, 0, "commitment", commit, commitlen); - - ret = sm2_commit_open(x, r, commit, commitlen); - printf("open commitment: %s\n", ret == 1 ? "success" : "failure"); - - - sm2_commit_vector_generate(&x, 1, r, commit, &commitlen); - format_bytes(stderr, 0, 0, "random", r, sizeof(r)); - format_bytes(stderr, 0, 0, "commitment", commit, commitlen); - - ret = sm2_commit_vector_open(&x, 1, r, commit, commitlen); - printf("open commitment: %s\n", ret == 1 ? "success" : "failure"); - - - rand_bytes(xvec[0], sizeof(xvec)); - sm2_commit_vector_generate(xvec, 8, r, commit, &commitlen); - ret = sm2_commit_vector_open(xvec, 8, r, commit, commitlen); - printf("open commitment: %s\n", ret == 1 ? "success" : "failure"); - - - return 1; } diff --git a/src/sm2_elgamal.c b/src/sm2_elgamal.c index a553f751..afbd21d7 100644 --- a/src/sm2_elgamal.c +++ b/src/sm2_elgamal.c @@ -14,18 +14,14 @@ #include #include #include -#include +#include #include #include -#define SM2_PRE_COMPUTE_MAX_OFFSETS 6 +extern const SM2_JACOBIAN_POINT *SM2_G; + -typedef struct { - uint16_t offset[SM2_PRE_COMPUTE_MAX_OFFSETS]; - uint8_t offset_count; - uint8_t x_coordinate[32]; -} SM2_PRE_COMPUTE; // generate baby-step table int sm2_elgamal_decrypt_pre_compute(SM2_PRE_COMPUTE table[1<<16]) @@ -117,11 +113,6 @@ ok: return ret; } -typedef struct { - SM2_POINT C1; - SM2_POINT C2; -} SM2_ELGAMAL_CIPHERTEXT; - int sm2_elgamal_do_encrypt(const SM2_KEY *pub_key, uint32_t in, SM2_ELGAMAL_CIPHERTEXT *out) { int ret = -1; @@ -419,14 +410,3 @@ int sm2_elgamal_decrypt(SM2_KEY *key, const uint8_t *in, size_t inlen, uint32_t } return 1; } - -int test_sm2_elgamal_do_encrypt(void) -{ - return -1; -} - -int test_sm2_elgamal_encrypt(void) -{ - return -1; -} - diff --git a/src/sm2_key_share.c b/src/sm2_key_share.c index ba55b507..0c8abfde 100644 --- a/src/sm2_key_share.c +++ b/src/sm2_key_share.c @@ -11,10 +11,11 @@ #include #include #include -#include +#include #include #include +extern SM2_BN SM2_N; int sm2_key_share_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY_SHARE *share) { @@ -36,8 +37,6 @@ static void eval_univariate_poly(SM2_Fn y, const SM2_Fn *coeffs, size_t coeffs_c } } -#define SM2_KEY_MAX_SHARES 12 // 12! = 479001600 < 2^31 = 2147483648 - int sm2_key_split(const SM2_KEY *key, size_t recover_cnt, size_t total_cnt, SM2_KEY_SHARE *shares) { SM2_Fn coeffs[SM2_KEY_MAX_SHARES]; @@ -214,77 +213,3 @@ int sm2_key_share_decrypt_from_file(SM2_KEY_SHARE *share, const char *pass, cons error_print(); return -1; } - -int test_sm2_key_share_args(size_t k, size_t n) -{ - SM2_KEY key; - SM2_KEY key_; - SM2_KEY_SHARE shares[SM2_KEY_MAX_SHARES]; - - if (sm2_key_generate(&key) != 1) { - error_print(); - return -1; - } - if (sm2_key_split(&key, k, n, shares) != 1) { - error_print(); - return -1; - } - - // recover from 0 .. k - if (sm2_key_recover(&key_, shares, k) != 1) { - error_print(); - return -1; - } - if (memcmp(&key_, &key, sizeof(SM2_KEY)) != 0) { - error_print(); - return -1; - } - - // recover from n-k .. n - memset(&key_, 0, sizeof(key_)); - if (sm2_key_recover(&key_, shares + n - k, k) != 1) { - error_print(); - return -1; - } - if (memcmp(&key_, &key, sizeof(SM2_KEY)) != 0) { - error_print(); - return -1; - } - return 1; -} - -int test_sm2_key_share(void) -{ - if (test_sm2_key_share_args(1, 1) != 1) { error_print(); return -1; } - if (test_sm2_key_share_args(1, 3) != 1) { error_print(); return -1; } - if (test_sm2_key_share_args(2, 3) != 1) { error_print(); return -1; } - if (test_sm2_key_share_args(3, 5) != 1) { error_print(); return -1; } - if (test_sm2_key_share_args(4, 5) != 1) { error_print(); return -1; } - if (test_sm2_key_share_args(5, 5) != 1) { error_print(); return -1; } - if (test_sm2_key_share_args(11, 12) != 1) { error_print(); return -1; } - if (test_sm2_key_share_args(12, 12) != 1) { error_print(); return -1; } - return 1; -} - -int test_sm2_key_share_file(void) -{ - SM2_KEY key; - SM2_KEY_SHARE shares[SM2_KEY_MAX_SHARES]; - - if (sm2_key_generate(&key) != 1) { - error_print(); - return -1; - } - if (sm2_key_split(&key, 2, 3, shares) != 1) { - error_print(); - return -1; - } - if (sm2_key_share_encrypt_to_file(&shares[0], "123456", "sm2key") != 1 - || sm2_key_share_encrypt_to_file(&shares[1], "123456", "sm2key") != 1 - || sm2_key_share_encrypt_to_file(&shares[2], "123456", "sm2key") != 1) { - error_print(); - return -1; - } - return 1; -} - diff --git a/src/sm2_recover.c b/src/sm2_recover.c index bac370a4..386dcfc3 100644 --- a/src/sm2_recover.c +++ b/src/sm2_recover.c @@ -15,6 +15,11 @@ #include +extern SM2_BN SM2_P; +extern SM2_BN SM2_B; +extern SM2_BN SM2_N; +extern SM2_BN SM2_THREE; + // r = H(Z||M) + x1 (mod n) // x1 = r - H(Z||M) (mod n) or (r - H(Z||M) (mod n)) + n // y1 = sqrt(x1^3 + a*x1 + b) @@ -107,25 +112,3 @@ int sm2_signature_to_public_key_points(const SM2_SIGNATURE *sig, const uint8_t d return 1; } - -static int test_sm2_signature_to_public_key_points(void) -{ - SM2_KEY key; - uint8_t dgst[32] = {1,2,3,4}; - SM2_SIGNATURE sig; - SM2_POINT points[4]; - size_t points_cnt, i; - - sm2_key_generate(&key); - sm2_do_sign(&key, dgst, &sig); - sm2_signature_to_public_key_points(&sig, dgst, points, &points_cnt); - - for (i = 0; i < points_cnt; i++) { - int vr; - sm2_point_print(stderr, 0, 0, "point", &points[i]); - vr = sm2_do_verify((SM2_KEY *)&points[1], dgst, &sig); - printf("verify = %d\n", vr); - } - return 1; -} - diff --git a/src/sm2_ring.c b/src/sm2_ring.c index 693980d7..a0adeafb 100644 --- a/src/sm2_ring.c +++ b/src/sm2_ring.c @@ -11,11 +11,15 @@ #include #include #include -#include +#include #include #include +extern SM2_BN SM2_N; +extern SM2_BN SM2_ONE; + + static int compare_point(const void *P, const void *Q) { const uint8_t *p = (uint8_t *)P; diff --git a/tests/sm2_blindtest.c b/tests/sm2_blindtest.c new file mode 100644 index 00000000..7fdce984 --- /dev/null +++ b/tests/sm2_blindtest.c @@ -0,0 +1,100 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + + +static int test_sm2_blind_sign(void) +{ + int r = -1; + + // signer + SM2_KEY key; + SM2_Fn k; + uint8_t commit[65]; + size_t commitlen; + + // caller + SM2_KEY public_key; + SM2_BLIND_SIGN_CTX sign_ctx; + uint8_t msg[128] = {0}; + uint8_t blinded_sig_s[32]; + uint8_t blinded_sig_r[32]; + uint8_t sig[128]; + size_t siglen; + + // verifier + SM2_SIGN_CTX verify_ctx; + + + // signer + if (sm2_key_generate(&key) != 1 + || sm2_key_set_public_key(&public_key, &key.public_key) != 1) { + error_print(); + goto end; + } + if (sm2_blind_sign_commit(k, commit, &commitlen) != 1) { + error_print(); + return -1; + } + format_bytes(stderr, 0, 0, "signer: commitment", commit, commitlen); + + // caller + if (sm2_blind_sign_init(&sign_ctx, &public_key, + SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1 + || sm2_blind_sign_update(&sign_ctx, msg, 32) != 1 + || sm2_blind_sign_update(&sign_ctx, msg + 32, 32) != 1 + || sm2_blind_sign_update(&sign_ctx, msg + 64, 64) != 1 + || sm2_blind_sign_finish(&sign_ctx, commit, commitlen, blinded_sig_r) != 1) { + error_print(); + goto end; + } + format_bytes(stderr, 0, 0, "caller: blinded_sig_r", blinded_sig_r, sizeof(blinded_sig_r)); + + // signer + if (sm2_blind_sign(&key, k, blinded_sig_r, blinded_sig_s) != 1) { + error_print(); + goto end; + } + format_bytes(stderr, 0, 0, "signer: blinded_sig_s", blinded_sig_s, sizeof(blinded_sig_s)); + + // caller + if (sm2_blind_sign_unblind(&sign_ctx, blinded_sig_s, sig, &siglen) != 1) { + error_print(); + goto end; + } + format_bytes(stderr, 0, 0, "caller: unblinded_sig", sig, siglen); + + // verifier + if (sm2_verify_init(&verify_ctx, &public_key, + SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1 + || sm2_verify_update(&verify_ctx, msg, sizeof(msg)) != 1 + || (r = sm2_verify_finish(&verify_ctx, sig, siglen)) < 0) { + error_print(); + goto end; + } + format_print(stderr, 0, 0, "verifier: %s\n", r == 1 ? "success" : "failure"); + +end: + gmssl_secure_clear(&key, sizeof(key)); + gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx)); + return r; +} + +int main(void) +{ + if (test_sm2_blind_sign() != 1) { error_print(); return -1; } + return 0; +} diff --git a/tests/sm2_committest.c b/tests/sm2_committest.c new file mode 100644 index 00000000..80d474ec --- /dev/null +++ b/tests/sm2_committest.c @@ -0,0 +1,59 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + + +static int test_sm2_commit(void) +{ + uint8_t x[32]; + uint8_t xvec[8][32]; + uint8_t r[32]; + uint8_t commit[65]; + size_t commitlen; + int ret; + + rand_bytes(x, sizeof(x)); + format_bytes(stderr, 0, 0, "secret", x, sizeof(x)); + + sm2_commit_generate(x, r, commit, &commitlen); + format_bytes(stderr, 0, 0, "random", r, sizeof(r)); + format_bytes(stderr, 0, 0, "commitment", commit, commitlen); + + ret = sm2_commit_open(x, r, commit, commitlen); + printf("open commitment: %s\n", ret == 1 ? "success" : "failure"); + + + sm2_commit_vector_generate(&x, 1, r, commit, &commitlen); + format_bytes(stderr, 0, 0, "random", r, sizeof(r)); + format_bytes(stderr, 0, 0, "commitment", commit, commitlen); + + ret = sm2_commit_vector_open(&x, 1, r, commit, commitlen); + printf("open commitment: %s\n", ret == 1 ? "success" : "failure"); + + + rand_bytes(xvec[0], sizeof(xvec)); + sm2_commit_vector_generate(xvec, 8, r, commit, &commitlen); + ret = sm2_commit_vector_open(xvec, 8, r, commit, commitlen); + printf("open commitment: %s\n", ret == 1 ? "success" : "failure"); + + return 1; +} + +int main(void) +{ + if (test_sm2_commit() != 1) { error_print(); return -1; } + return 0; +} diff --git a/tests/sm2_elgamaltest.c b/tests/sm2_elgamaltest.c new file mode 100644 index 00000000..57cd7b8c --- /dev/null +++ b/tests/sm2_elgamaltest.c @@ -0,0 +1,22 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + + +int main(void) +{ + return 0; +} diff --git a/tests/sm2_key_sharetest.c b/tests/sm2_key_sharetest.c new file mode 100644 index 00000000..ac969fd3 --- /dev/null +++ b/tests/sm2_key_sharetest.c @@ -0,0 +1,96 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include + + +static int test_sm2_key_share_args(size_t k, size_t n) +{ + SM2_KEY key; + SM2_KEY key_; + SM2_KEY_SHARE shares[SM2_KEY_MAX_SHARES]; + + if (sm2_key_generate(&key) != 1) { + error_print(); + return -1; + } + if (sm2_key_split(&key, k, n, shares) != 1) { + error_print(); + return -1; + } + + // recover from 0 .. k + if (sm2_key_recover(&key_, shares, k) != 1) { + error_print(); + return -1; + } + if (memcmp(&key_, &key, sizeof(SM2_KEY)) != 0) { + error_print(); + return -1; + } + + // recover from n-k .. n + memset(&key_, 0, sizeof(key_)); + if (sm2_key_recover(&key_, shares + n - k, k) != 1) { + error_print(); + return -1; + } + if (memcmp(&key_, &key, sizeof(SM2_KEY)) != 0) { + error_print(); + return -1; + } + return 1; +} + +static int test_sm2_key_share(void) +{ + if (test_sm2_key_share_args(1, 1) != 1) { error_print(); return -1; } + if (test_sm2_key_share_args(1, 3) != 1) { error_print(); return -1; } + if (test_sm2_key_share_args(2, 3) != 1) { error_print(); return -1; } + if (test_sm2_key_share_args(3, 5) != 1) { error_print(); return -1; } + if (test_sm2_key_share_args(4, 5) != 1) { error_print(); return -1; } + if (test_sm2_key_share_args(5, 5) != 1) { error_print(); return -1; } + if (test_sm2_key_share_args(11, 12) != 1) { error_print(); return -1; } + if (test_sm2_key_share_args(12, 12) != 1) { error_print(); return -1; } + return 1; +} + +static int test_sm2_key_share_file(void) +{ + SM2_KEY key; + SM2_KEY_SHARE shares[SM2_KEY_MAX_SHARES]; + + if (sm2_key_generate(&key) != 1) { + error_print(); + return -1; + } + if (sm2_key_split(&key, 2, 3, shares) != 1) { + error_print(); + return -1; + } + if (sm2_key_share_encrypt_to_file(&shares[0], "123456", "sm2key") != 1 + || sm2_key_share_encrypt_to_file(&shares[1], "123456", "sm2key") != 1 + || sm2_key_share_encrypt_to_file(&shares[2], "123456", "sm2key") != 1) { + error_print(); + return -1; + } + return 1; +} + +int main(void) +{ + return 0; +} diff --git a/tests/sm2_recovertest.c b/tests/sm2_recovertest.c new file mode 100644 index 00000000..66fe82e6 --- /dev/null +++ b/tests/sm2_recovertest.c @@ -0,0 +1,44 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + + +static int test_sm2_signature_to_public_key_points(void) +{ + SM2_KEY key; + uint8_t dgst[32] = {1,2,3,4}; + SM2_SIGNATURE sig; + SM2_POINT points[4]; + size_t points_cnt, i; + + sm2_key_generate(&key); + sm2_do_sign(&key, dgst, &sig); + sm2_signature_to_public_key_points(&sig, dgst, points, &points_cnt); + + for (i = 0; i < points_cnt; i++) { + int vr; + sm2_point_print(stderr, 0, 0, "point", &points[i]); + vr = sm2_do_verify((SM2_KEY *)&points[1], dgst, &sig); + printf("verify = %d\n", vr); + } + return 1; +} + +int main(void) +{ + if (test_sm2_signature_to_public_key_points() != 1) { error_print(); return -1; } + return 0; +} diff --git a/tests/sm2_ringtest.c b/tests/sm2_ringtest.c new file mode 100644 index 00000000..5a1776c5 --- /dev/null +++ b/tests/sm2_ringtest.c @@ -0,0 +1,174 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + + +static int test_sm2_ring_do_sign(void) +{ + SM2_KEY sign_key; + SM2_POINT public_keys[5]; + size_t public_keys_count = sizeof(public_keys)/sizeof(public_keys[0]); + size_t sign_index, i; + uint8_t dgst[32]; + uint8_t r[32]; + uint8_t s[sizeof(public_keys)/sizeof(public_keys[0])][32]; + + for (sign_index = 0; sign_index < 5; sign_index++) { + + for (i = 0; i < public_keys_count; i++) { + SM2_KEY key; + sm2_key_generate(&key); + memcpy(&public_keys[i], &(key.public_key), sizeof(SM2_POINT)); + + if (i == sign_index) { + memcpy(&sign_key, &key, sizeof(SM2_KEY)); + } + } + if (sm2_ring_do_sign(&sign_key, public_keys, public_keys_count, dgst, r, s) != 1) { + error_print(); + return -1; + } + if (sm2_ring_do_verify(public_keys, public_keys_count, dgst, r, s) != 1) { + error_print(); + return -1; + } + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm2_ring_sign(void) +{ + SM2_KEY sign_key; + SM2_POINT public_keys[5]; + size_t public_keys_count = sizeof(public_keys)/sizeof(public_keys[0]); + size_t sign_index = 2, i; + uint8_t dgst[32]; + uint8_t sig[9 + (2 + 33) * (1 + sizeof(public_keys)/sizeof(public_keys[0]))]; + size_t siglen = 0; + + for (i = 0; i < public_keys_count; i++) { + SM2_KEY key; + sm2_key_generate(&key); + memcpy(&public_keys[i], &(key.public_key), sizeof(SM2_POINT)); + + if (i == sign_index) { + memcpy(&sign_key, &key, sizeof(SM2_KEY)); + } + } + if (sm2_ring_sign(&sign_key, public_keys, public_keys_count, dgst, sig, &siglen) != 1) { + error_print(); + return -1; + } + if (sm2_ring_verify(public_keys, 5, dgst, sig, siglen) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm2_ring_sign_crosscheck(void) +{ + SM2_KEY sign_key; + SM2_POINT public_key; + uint8_t dgst[32]; + uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; + size_t siglen = 0; + + sm2_key_generate(&sign_key); + public_key = sign_key.public_key; + + if (sm2_ring_sign(&sign_key, &public_key, 1, dgst, sig, &siglen) != 1) { + error_print(); + return -1; + } + if (sm2_ring_verify(&public_key, 1, dgst, sig, siglen) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm2_ring_sign_update(void) +{ + SM2_KEY keys[5]; + SM2_RING_SIGN_CTX sign_ctx; + SM2_RING_SIGN_CTX verify_ctx; + size_t public_keys_count = sizeof(keys)/sizeof(keys[0]); + char *id = "Alice"; + uint8_t msg[128] = {0}; + uint8_t sig[9 + (2 + 33) * (1 + sizeof(keys)/sizeof(keys[0]))]; + size_t siglen = 0; + size_t i; + + for (i = 0; i < public_keys_count; i++) { + sm2_key_generate(&keys[i]); + } + + if (sm2_ring_sign_init(&sign_ctx, &keys[0], id, strlen(id)) != 1) { + error_print(); + return -1; + } + for (i = 1; i < public_keys_count; i++) { + if (sm2_ring_sign_add_signer(&sign_ctx, &keys[i]) != 1) { + error_print(); + return -1; + } + } + if (sm2_ring_sign_update(&sign_ctx, msg, 32) != 1 + || sm2_ring_sign_update(&sign_ctx, msg + 32, 32) != 1 + || sm2_ring_sign_update(&sign_ctx, msg + 64, 64) != 1 + || sm2_ring_sign_finish(&sign_ctx, sig, &siglen) != 1) { + error_print(); + return -1; + } + + if (sm2_ring_verify_init(&verify_ctx, id, strlen(id)) != 1) { + error_print(); + return -1; + } + for (i = 0; i < public_keys_count; i++) { + if (sm2_ring_verify_add_signer(&verify_ctx, &keys[i]) != 1) { + error_print(); + return -1; + } + } + if (sm2_ring_verify_update(&verify_ctx, msg, sizeof(msg)) != 1) { + error_print(); + return -1; + } + if (sm2_ring_verify_finish(&verify_ctx, sig, siglen) != 1) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int main(void) +{ + if (test_sm2_ring_do_sign() != 1) { error_print(); return -1; } + if (test_sm2_ring_sign() != 1) { error_print(); return -1; } + if (test_sm2_ring_sign_crosscheck() != 1) { error_print(); return -1; } + if (test_sm2_ring_sign_update() != 1) { error_print(); return -1; } + return 0; +}