diff --git a/include/gmssl/sm2.h b/include/gmssl/sm2.h index 11a161e3..c819454c 100644 --- a/include/gmssl/sm2.h +++ b/include/gmssl/sm2.h @@ -67,6 +67,7 @@ int sm2_bn_from_hex(SM2_BN r, const char hex[64]); int sm2_bn_from_asn1_integer(SM2_BN r, const uint8_t *d, size_t dlen); int sm2_bn_equ_hex(const SM2_BN a, const char *hex); int sm2_bn_print(FILE *fp, int fmt, int ind, const char *label, const SM2_BN a); +int sm2_bn_rshift(SM2_BN ret, const SM2_BN a, unsigned int nbits); void sm2_bn_to_bytes(const SM2_BN a, uint8_t out[32]); void sm2_bn_from_bytes(SM2_BN r, const uint8_t in[32]); @@ -99,6 +100,8 @@ void sm2_fp_sqr(SM2_Fp r, const SM2_Fp a); void sm2_fp_inv(SM2_Fp r, const SM2_Fp a); void sm2_fp_rand(SM2_Fp r); // 外部提供随机性,如果满足条件就输出,如果不满足条件就哈希一下再输出 +int sm2_fp_sqrt(SM2_Fp r, const SM2_Fp a); + #define sm2_fp_init(r) sm2_bn_init(r) #define sm2_fp_set_zero(r) sm2_bn_set_zero(r) #define sm2_fp_set_one(r) sm2_bn_set_one(r) @@ -300,12 +303,16 @@ typedef struct { int sm2_do_sign_ex(const SM2_KEY *key, int flags, const uint8_t dgst[32], SM2_SIGNATURE *sig); int sm2_do_sign(const SM2_KEY *key, const uint8_t dgst[32], SM2_SIGNATURE *sig); +int sm2_do_sign_fast(const SM2_Fn d, 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); #define SM2_MIN_SIGNATURE_SIZE 8 #define SM2_MAX_SIGNATURE_SIZE 72 int sm2_signature_to_der(const SM2_SIGNATURE *sig, uint8_t **out, size_t *outlen); int sm2_signature_from_der(SM2_SIGNATURE *sig, const uint8_t **in, size_t *inlen); +int sm2_signature_to_public_key_points(const SM2_SIGNATURE *sig, const uint8_t dgst[32], + SM2_POINT points[4], size_t *points_cnt); + int sm2_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen); int sm2_sign_ex(const SM2_KEY *key, int flags, const uint8_t dgst[32], uint8_t *sig, size_t *siglen); int sm2_sign(const SM2_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen); diff --git a/src/sm2_alg.c b/src/sm2_alg.c index 8042aaf1..ef3e369b 100644 --- a/src/sm2_alg.c +++ b/src/sm2_alg.c @@ -268,6 +268,28 @@ void sm2_bn_set_word(SM2_BN r, uint32_t a) } } +int sm2_bn_rshift(SM2_BN ret, const SM2_BN a, unsigned int nbits) +{ + SM2_BN r; + int i; + + if (nbits > 31) { + error_print(); + return -1; + } + if (nbits == 0) { + sm2_bn_copy(ret, a); + } + + for (i = 0; i < 7; i++) { + r[i] = a[i] >> nbits; + r[i] |= (a[i+1] << (32 - nbits)) & 0xffffffff; + } + r[i] = a[i] >> nbits; + sm2_bn_copy(ret, r); + return 1; +} + void sm2_bn_add(SM2_BN r, const SM2_BN a, const SM2_BN b) { int i; @@ -504,6 +526,27 @@ void sm2_fp_inv(SM2_Fp r, const SM2_Fp a) sm2_bn_clean(a5); } +int sm2_fp_sqrt(SM2_Fp r, const SM2_Fp a) +{ + SM2_BN u; + SM2_BN y; // temp result, prevent call sm2_fp_sqrt(a, a) + + // r = a^((p - 1)/4) when p = 3 (mod 4) + sm2_bn_add(u, SM2_P, SM2_ONE); + sm2_bn_rshift(u, u, 2); + sm2_fp_exp(y, a, u); + + // check r^2 == a + sm2_fp_sqr(u, y); + if (sm2_bn_cmp(u, a) != 0) { + error_print(); + return -1; + } + + sm2_bn_copy(r, y); + return 1; +} + void sm2_fn_add(SM2_Fn r, const SM2_Fn a, const SM2_Fn b) { sm2_bn_add(r, a, b); diff --git a/src/sm2_pederson.c b/src/sm2_commit.c similarity index 100% rename from src/sm2_pederson.c rename to src/sm2_commit.c diff --git a/src/sm2_lib.c b/src/sm2_lib.c index ea9d54d3..a1bb2512 100644 --- a/src/sm2_lib.c +++ b/src/sm2_lib.c @@ -706,3 +706,47 @@ int sm2_ecdh(const SM2_KEY *key, const SM2_POINT *peer_public, SM2_POINT *out) } 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; + + // e = H(M) + sm2_bn_from_bytes(e, dgst); + if (sm2_bn_cmp(e, SM2_N) >= 0) { + sm2_bn_sub(e, e, SM2_N); + } + + // rand k in [1, n - 1] + do { + sm2_fn_rand(k); + } 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; +} + diff --git a/src/sm2_recover.c b/src/sm2_recover.c index 3a1ea278..bac370a4 100644 --- a/src/sm2_recover.c +++ b/src/sm2_recover.c @@ -13,67 +13,8 @@ #include #include #include -#include "sm2_recover.h" -static int sm2_bn_rshift(SM2_BN ret, const SM2_BN a, unsigned int nbits) -{ - SM2_BN r; - int i; - assert(nbits < 32); - for (i = 0; i < 7; i++) { - r[i] = a[i] >> nbits; - r[i] |= (a[i+1] << (32 - nbits)) & 0xffffffff; - } - r[i] = a[i] >> nbits; - sm2_bn_copy(ret, r); - return 1; -} - -static int test_sm2_bn_rshift(void) -{ - SM2_BN a; - int i; - - sm2_bn_from_hex(a, "ad23f3bff55b45c7192e25efcefa5fcecab1f072cd04a88e6cf64bfd3f531966"); - sm2_bn_print(stderr, 0, 0, "a", a); - - for (i = 0; i < 64; i++) { - sm2_bn_rshift(a, a, 31); - sm2_bn_print(stderr, 0, 0, "a", a); - } - - return 0; -} - -static int sm2_fp_sqrt(SM2_Fp r, const SM2_Fp a) -{ - SM2_BN u; - SM2_BN y; // temp result, prevent call sm2_fp_sqrt(a, a) - - // r = a^((p - 1)/4) when p = 3 (mod 4) - sm2_bn_add(u, SM2_P, SM2_ONE); - sm2_bn_rshift(u, u, 2); - sm2_fp_exp(y, a, u); - - // check r^2 == a - sm2_fp_sqr(u, y); - if (sm2_bn_cmp(u, a) != 0) { - error_print(); - return -1; - } - - sm2_bn_copy(r, y); - return 1; -} - -static int test_sm2_fp_sqrt(void) -{ - // a = 0x998eb0e4b8399fb359268966270049a6a4a317f9417c572c910d80c09969dc3 - // a^2 = 0x1b20ef7d2082f66c7561cdd4cdb0a8d58fa753e3e0d2e0560c80c849568f3fdb - return 1; -} - // 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) @@ -188,13 +129,3 @@ static int test_sm2_signature_to_public_key_points(void) return 1; } -#if 0 -int main(void) -{ - //test_sm2_bn_rshift(); - //test_sm2_fp_sqrt(); - - test_sm2_signature_to_public_key_points(); - return 0; -} -#endif diff --git a/src/sm2_ringsig.c b/src/sm2_ring.c similarity index 100% rename from src/sm2_ringsig.c rename to src/sm2_ring.c diff --git a/src/sm2_sign_fast.c b/src/sm2_sign_fast.c deleted file mode 100644 index 0b807d31..00000000 --- a/src/sm2_sign_fast.c +++ /dev/null @@ -1,61 +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 -#include -#include -#include -#include -#include -#include - - -// (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; - - // e = H(M) - sm2_bn_from_bytes(e, dgst); - if (sm2_bn_cmp(e, SM2_N) >= 0) { - sm2_bn_sub(e, e, SM2_N); - } - - // rand k in [1, n - 1] - do { - sm2_fn_rand(k); - } 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; -} -