diff --git a/CMakeLists.txt b/CMakeLists.txt index bbc2f0e9..3858832d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/include/gmssl/sm2.h b/include/gmssl/sm2.h index b5c28f8c..a0abcd82 100644 --- a/include/gmssl/sm2.h +++ b/include/gmssl/sm2.h @@ -17,7 +17,6 @@ #include #include #include -#include #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); diff --git a/include/gmssl/sm2_z256.h b/include/gmssl/sm2_z256.h index b0191d4b..8f743477 100644 --- a/include/gmssl/sm2_z256.h +++ b/include/gmssl/sm2_z256.h @@ -15,6 +15,7 @@ #include #include #include +#include #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 diff --git a/src/sm2_alg.c b/src/sm2_alg.c deleted file mode 100644 index 59d4fd9a..00000000 --- a/src/sm2_alg.c +++ /dev/null @@ -1,1367 +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 -#include -#include -#include -#include -#include -#include -#include -#include - - -const SM2_BN SM2_P = { - 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, - 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe, -}; - -const SM2_BN SM2_B = { - 0x4d940e93, 0xddbcbd41, 0x15ab8f92, 0xf39789f5, - 0xcf6509a7, 0x4d5a9e4b, 0x9d9f5e34, 0x28e9fa9e, -}; - -const SM2_JACOBIAN_POINT _SM2_G = { - { - 0x334c74c7, 0x715a4589, 0xf2660be1, 0x8fe30bbf, - 0x6a39c994, 0x5f990446, 0x1f198119, 0x32c4ae2c, - }, - { - 0x2139f0a0, 0x02df32e5, 0xc62a4740, 0xd0a9877c, - 0x6b692153, 0x59bdcee3, 0xf4f6779c, 0xbc3736a2, - }, - { - 1, 0, 0, 0, 0, 0, 0, 0, - }, -}; -const SM2_JACOBIAN_POINT *SM2_G = &_SM2_G; - -const SM2_BN SM2_N = { - 0x39d54123, 0x53bbf409, 0x21c6052b, 0x7203df6b, - 0xffffffff, 0xffffffff, 0xffffffff, 0xfffffffe, -}; - -// u = (p - 1)/4, u + 1 = (p + 1)/4 -const SM2_BN SM2_U_PLUS_ONE = { - 0x00000000, 0x40000000, 0xc0000000, 0xffffffff, - 0xffffffff, 0xffffffff, 0xbfffffff, 0x3fffffff, -}; - -const SM2_BN SM2_ONE = {1,0,0,0,0,0,0,0}; -const SM2_BN SM2_TWO = {2,0,0,0,0,0,0,0}; -const SM2_BN SM2_THREE = {3,0,0,0,0,0,0,0}; - - -int sm2_bn_check(const SM2_BN a) -{ - int err = 0; - int i; - for (i = 0; i < 8; i++) { - if (a[i] > 0xffffffff) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - err++; - } - } - if (err) - return -1; - else return 1; -} - -int sm2_bn_is_zero(const SM2_BN a) -{ - int i; - for (i = 0; i < 8; i++) { - if (a[i] != 0) - return 0; - } - return 1; -} - -int sm2_bn_is_one(const SM2_BN a) -{ - int i; - if (a[0] != 1) - return 0; - for (i = 1; i < 8; i++) { - if (a[i] != 0) - return 0; - } - return 1; -} - -void sm2_bn_to_bytes(const SM2_BN a, uint8_t out[32]) -{ - int i; - uint8_t *p = out; - - /* - fprintf(stderr, "sm2_bn_to_bytes:\n"); - for (i = 0; i < 8; i++) { - fprintf(stderr, "%016lx ", a[i]); - } - fprintf(stderr, "\n"); - */ - - for (i = 7; i >= 0; i--) { - uint32_t ai = (uint32_t)a[i]; - PUTU32(out, ai); - out += sizeof(uint32_t); - } - - /* - for (i = 0; i < 32; i++) { - fprintf(stderr, "%02X ", p[i]); - } - */ - -} - -void sm2_bn_from_bytes(SM2_BN r, const uint8_t in[32]) -{ - int i; - for (i = 7; i >= 0; i--) { - r[i] = GETU32(in); - in += sizeof(uint32_t); - } -} - -static int hexchar2int(char c) -{ - if ('0' <= c && c <= '9') return c - '0'; - else if ('a' <= c && c <= 'f') return c - 'a' + 10; - else if ('A' <= c && c <= 'F') return c - 'A' + 10; - else return -1; -} - -static int hex2bin(const char *in, size_t inlen, uint8_t *out) -{ - int c; - if (inlen % 2) - return -1; - - while (inlen) { - if ((c = hexchar2int(*in++)) < 0) - return -1; - *out = (uint8_t)c << 4; - if ((c = hexchar2int(*in++)) < 0) - return -1; - *out |= (uint8_t)c; - inlen -= 2; - out++; - } - return 1; -} - -void sm2_bn_to_hex(const SM2_BN a, char hex[64]) -{ - int i; - for (i = 7; i >= 0; i--) { - int len; - len = sprintf(hex, "%08x", (uint32_t)a[i]); - assert(len == 8); - hex += 8; - } -} - -int sm2_bn_from_hex(SM2_BN r, const char hex[64]) -{ - uint8_t buf[32]; - if (hex2bin(hex, 64, buf) < 0) - return -1; - sm2_bn_from_bytes(r, buf); - return 1; -} - -int sm2_bn_from_asn1_integer(SM2_BN r, const uint8_t *d, size_t dlen) -{ - uint8_t buf[32] = {0}; - if (!d || dlen == 0) { - error_print(); - return -1; - } - if (dlen > sizeof(buf)) { - error_print(); - return -1; - } - memcpy(buf + sizeof(buf) - dlen, d, dlen); - sm2_bn_from_bytes(r, buf); - return 1; -} - -int sm2_bn_print(FILE *fp, int fmt, int ind, const char *label, const SM2_BN a) -{ - int ret = 0, i; - format_print(fp, fmt, ind, "%s: ", label); - - for (i = 7; i >= 0; i--) { - if (a[i] >= ((uint64_t)1 << 32)) { - printf("bn_print check failed\n"); - } - ret += fprintf(fp, "%08x", (uint32_t)a[i]); - } - ret += fprintf(fp, "\n"); - return ret; -} - -void sm2_bn_to_bits(const SM2_BN a, char bits[256]) -{ - int i, j; - uint64_t w; - for (i = 7; i >= 0; i--) { - w = a[i]; - for (j = 0; j < 32; j++) { - *bits++ = (w & 0x80000000) ? '1' : '0'; - w <<= 1; - } - } -} - -int sm2_bn_cmp(const SM2_BN a, const SM2_BN b) -{ - int i; - for (i = 7; i >= 0; i--) { - if (a[i] > b[i]) - return 1; - if (a[i] < b[i]) - return -1; - } - return 0; -} - -int sm2_bn_equ_hex(const SM2_BN a, const char *hex) -{ - char buf[65] = {0}; - char *p = buf; - int i; - - for (i = 7; i >= 0; i--) { - sprintf(p, "%08x", (uint32_t)a[i]); - p += 8; - } - return (strcmp(buf, hex) == 0); -} - -int sm2_bn_is_odd(const SM2_BN a) -{ - return a[0] & 0x01; -} - -void sm2_bn_set_word(SM2_BN r, uint32_t a) -{ - int i; - r[0] = a; - for (i = 1; i < 8; i++) { - r[i] = 0; - } -} - -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; - r[0] = a[0] + b[0]; - - for (i = 1; i < 8; i++) { - r[i] = a[i] + b[i] + (r[i-1] >> 32); - } - for (i = 0; i < 7; i++) { - r[i] &= 0xffffffff; - } -} - -void sm2_bn_sub(SM2_BN ret, const SM2_BN a, const SM2_BN b) -{ - int i; - SM2_BN r; - r[0] = ((uint64_t)1 << 32) + a[0] - b[0]; - for (i = 1; i < 7; i++) { - r[i] = 0xffffffff + a[i] - b[i] + (r[i - 1] >> 32); - r[i - 1] &= 0xffffffff; - } - r[i] = a[i] - b[i] + (r[i - 1] >> 32) - 1; - r[i - 1] &= 0xffffffff; - sm2_bn_copy(ret, r); -} - -int sm2_bn_rand_range(SM2_BN r, const SM2_BN range) -{ - uint8_t buf[32]; - do { - if (rand_bytes(buf, sizeof(buf)) != 1) { - error_print(); - return -1; - } - sm2_bn_from_bytes(r, buf); - } while (sm2_bn_cmp(r, range) >= 0); - return 1; -} - -int sm2_fp_rand(SM2_Fp r) -{ - if (sm2_bn_rand_range(r, SM2_P) != 1) { - error_print(); - return -1; - } - return 1; -} - -void sm2_fp_add(SM2_Fp r, const SM2_Fp a, const SM2_Fp b) -{ - sm2_bn_add(r, a, b); - if (sm2_bn_cmp(r, SM2_P) >= 0) { - sm2_bn_sub(r, r, SM2_P); - } -} - -void sm2_fp_sub(SM2_Fp r, const SM2_Fp a, const SM2_Fp b) -{ - if (sm2_bn_cmp(a, b) >= 0) { - sm2_bn_sub(r, a, b); - } else { - SM2_BN t; - sm2_bn_sub(t, SM2_P, b); - sm2_bn_add(r, t, a); - } -} - -void sm2_fp_dbl(SM2_Fp r, const SM2_Fp a) -{ - sm2_fp_add(r, a, a); -} - -void sm2_fp_tri(SM2_Fp r, const SM2_Fp a) -{ - SM2_BN t; - sm2_fp_dbl(t, a); - sm2_fp_add(r, t, a); -} - -void sm2_fp_div2(SM2_Fp r, const SM2_Fp a) -{ - int i; - sm2_bn_copy(r, a); - if (r[0] & 0x01) { - sm2_bn_add(r, r, SM2_P); - } - for (i = 0; i < 7; i++) { - r[i] = (r[i] >> 1) | ((r[i + 1] & 0x01) << 31); - } - r[i] >>= 1; -} - -void sm2_fp_neg(SM2_Fp r, const SM2_Fp a) -{ - if (sm2_bn_is_zero(a)) { - sm2_bn_copy(r, a); - } else { - sm2_bn_sub(r, SM2_P, a); - } -} - -void sm2_fp_mul(SM2_Fp r, const SM2_Fp a, const SM2_Fp b) -{ - int i, j; - uint64_t s[16] = {0}; - SM2_BN d = {0}; - uint64_t u; - - // s = a * b - for (i = 0; i < 8; i++) { - u = 0; - for (j = 0; j < 8; j++) { - u = s[i + j] + a[i] * b[j] + u; - s[i + j] = u & 0xffffffff; - u >>= 32; - } - s[i + 8] = u; - } - - r[0] = s[0] + s[ 8] + s[ 9] + s[10] + s[11] + s[12] + ((s[13] + s[14] + s[15]) << 1); - r[1] = s[1] + s[ 9] + s[10] + s[11] + s[12] + s[13] + ((s[14] + s[15]) << 1); - r[2] = s[2]; - r[3] = s[3] + s[ 8] + s[11] + s[12] + s[14] + s[15] + (s[13] << 1); - r[4] = s[4] + s[ 9] + s[12] + s[13] + s[15] + (s[14] << 1); - r[5] = s[5] + s[10] + s[13] + s[14] + (s[15] << 1); - r[6] = s[6] + s[11] + s[14] + s[15]; - r[7] = s[7] + s[ 8] + s[ 9] + s[10] + s[11] + s[15] + ((s[12] + s[13] + s[14] + s[15]) << 1); - - for (i = 1; i < 8; i++) { - r[i] += r[i - 1] >> 32; - r[i - 1] &= 0xffffffff; - } - - d[2] = s[8] + s[9] + s[13] + s[14]; - d[3] = d[2] >> 32; - d[2] &= 0xffffffff; - sm2_bn_sub(r, r, d); - - // max times ? - while (sm2_bn_cmp(r, SM2_P) >= 0) { - sm2_bn_sub(r, r, SM2_P); - } -} - -void sm2_fp_sqr(SM2_Fp r, const SM2_Fp a) -{ - sm2_fp_mul(r, a, a); -} - -void sm2_fp_exp(SM2_Fp r, const SM2_Fp a, const SM2_Fp e) -{ - SM2_BN t; - uint32_t w; - int i, j; - - sm2_bn_set_one(t); - for (i = 7; i >= 0; i--) { - w = (uint32_t)e[i]; - for (j = 0; j < 32; j++) { - sm2_fp_sqr(t, t); - if (w & 0x80000000) - sm2_fp_mul(t, t, a); - w <<= 1; - } - } - - sm2_bn_copy(r, t); -} - -void sm2_fp_inv(SM2_Fp r, const SM2_Fp a) -{ - SM2_BN a1; - SM2_BN a2; - SM2_BN a3; - SM2_BN a4; - SM2_BN a5; - int i; - - sm2_fp_sqr(a1, a); - sm2_fp_mul(a2, a1, a); - sm2_fp_sqr(a3, a2); - sm2_fp_sqr(a3, a3); - sm2_fp_mul(a3, a3, a2); - sm2_fp_sqr(a4, a3); - sm2_fp_sqr(a4, a4); - sm2_fp_sqr(a4, a4); - sm2_fp_sqr(a4, a4); - sm2_fp_mul(a4, a4, a3); - sm2_fp_sqr(a5, a4); - for (i = 1; i < 8; i++) - sm2_fp_sqr(a5, a5); - sm2_fp_mul(a5, a5, a4); - for (i = 0; i < 8; i++) - sm2_fp_sqr(a5, a5); - sm2_fp_mul(a5, a5, a4); - for (i = 0; i < 4; i++) - sm2_fp_sqr(a5, a5); - sm2_fp_mul(a5, a5, a3); - sm2_fp_sqr(a5, a5); - sm2_fp_sqr(a5, a5); - sm2_fp_mul(a5, a5, a2); - sm2_fp_sqr(a5, a5); - sm2_fp_mul(a5, a5, a); - sm2_fp_sqr(a4, a5); - sm2_fp_mul(a3, a4, a1); - sm2_fp_sqr(a5, a4); - for (i = 1; i< 31; i++) - sm2_fp_sqr(a5, a5); - sm2_fp_mul(a4, a5, a4); - sm2_fp_sqr(a4, a4); - sm2_fp_mul(a4, a4, a); - sm2_fp_mul(a3, a4, a2); - for (i = 0; i < 33; i++) - sm2_fp_sqr(a5, a5); - sm2_fp_mul(a2, a5, a3); - sm2_fp_mul(a3, a2, a3); - for (i = 0; i < 32; i++) - sm2_fp_sqr(a5, a5); - sm2_fp_mul(a2, a5, a3); - sm2_fp_mul(a3, a2, a3); - sm2_fp_mul(a4, a2, a4); - for (i = 0; i < 32; i++) - sm2_fp_sqr(a5, a5); - sm2_fp_mul(a2, a5, a3); - sm2_fp_mul(a3, a2, a3); - sm2_fp_mul(a4, a2, a4); - for (i = 0; i < 32; i++) - sm2_fp_sqr(a5, a5); - sm2_fp_mul(a2, a5, a3); - sm2_fp_mul(a3, a2, a3); - sm2_fp_mul(a4, a2, a4); - for (i = 0; i < 32; i++) - sm2_fp_sqr(a5, a5); - sm2_fp_mul(a2, a5, a3); - sm2_fp_mul(a3, a2, a3); - sm2_fp_mul(a4, a2, a4); - for (i = 0; i < 32; i++) - sm2_fp_sqr(a5, a5); - sm2_fp_mul(r, a4, a5); - - sm2_bn_clean(a1); - sm2_bn_clean(a2); - sm2_bn_clean(a3); - sm2_bn_clean(a4); - 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) - - printf("sm2_fp_sqrt\n"); - sm2_bn_print(stderr, 0, 4, "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_bn_print(stderr, 0, 4, "u", u); - - sm2_fp_exp(y, a, u); - sm2_bn_print(stderr, 0, 4, "y", y); - - // 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); - if (sm2_bn_cmp(r, SM2_N) >= 0) { - sm2_bn_sub(r, r, SM2_N); - } -} - -void sm2_fn_sub(SM2_Fn r, const SM2_Fn a, const SM2_Fn b) -{ - if (sm2_bn_cmp(a, b) >= 0) { - sm2_bn_sub(r, a, b); - } else { - SM2_BN t; - sm2_bn_add(t, a, SM2_N); - sm2_bn_sub(r, t, b); - } -} - -void sm2_fn_neg(SM2_Fn r, const SM2_Fn a) -{ - if (sm2_bn_is_zero(a)) { - sm2_bn_copy(r, a); - } else { - sm2_bn_sub(r, SM2_N, a); - } -} - -/* bn288 only used in barrett reduction */ -static int sm2_bn288_cmp(const uint64_t a[9], const uint64_t b[9]) -{ - int i; - for (i = 8; i >= 0; i--) { - if (a[i] > b[i]) - return 1; - if (a[i] < b[i]) - return -1; - } - return 0; -} - -static void sm2_bn288_add(uint64_t r[9], const uint64_t a[9], const uint64_t b[9]) -{ - int i; - r[0] = a[0] + b[0]; - for (i = 1; i < 9; i++) { - r[i] = a[i] + b[i] + (r[i-1] >> 32); - } - for (i = 0; i < 8; i++) { - r[i] &= 0xffffffff; - } -} - -static void sm2_bn288_sub(uint64_t ret[9], const uint64_t a[9], const uint64_t b[9]) -{ - int i; - uint64_t r[9]; - - r[0] = ((uint64_t)1 << 32) + a[0] - b[0]; - for (i = 1; i < 8; i++) { - r[i] = 0xffffffff + a[i] - b[i] + (r[i - 1] >> 32); - r[i - 1] &= 0xffffffff; - } - r[i] = a[i] - b[i] + (r[i - 1] >> 32) - 1; - r[i - 1] &= 0xffffffff; - - for (i = 0; i < 9; i++) { - ret[i] = r[i]; - } -} - -void sm2_fn_mul(SM2_BN ret, const SM2_BN a, const SM2_BN b) -{ - SM2_BN r; - static const uint64_t mu[9] = { - 0xf15149a0, 0x12ac6361, 0xfa323c01, 0x8dfc2096, 1, 1, 1, 1, 1, - }; - - uint64_t s[18]; - uint64_t zh[9]; - uint64_t zl[9]; - uint64_t q[9]; - uint64_t w; - int i, j; - - /* z = a * b */ - for (i = 0; i < 8; i++) { - s[i] = 0; - } - for (i = 0; i < 8; i++) { - w = 0; - for (j = 0; j < 8; j++) { - w += s[i + j] + a[i] * b[j]; - s[i + j] = w & 0xffffffff; - w >>= 32; - } - s[i + 8] = w; - } - - /* zl = z mod (2^32)^9 = z[0..8] - * zh = z // (2^32)^7 = z[7..15] */ - for (i = 0; i < 9; i++) { - zl[i] = s[i]; - zh[i] = s[7 + i]; - } - //printf("zl = "); for (i = 8; i >= 0; i--) printf("%08x", (uint32_t)zl[i]); printf("\n"); - //printf("zh = "); for (i = 8; i >= 0; i--) printf("%08x", (uint32_t)zh[i]); printf("\n"); - - /* q = zh * mu // (2^32)^9 */ - for (i = 0; i < 9; i++) { - s[i] = 0; - } - for (i = 0; i < 9; i++) { - w = 0; - for (j = 0; j < 9; j++) { - w += s[i + j] + zh[i] * mu[j]; - s[i + j] = w & 0xffffffff; - w >>= 32; - } - s[i + 9] = w; - } - for (i = 0; i < 8; i++) { - q[i] = s[9 + i]; - } - //printf("q = "); for (i = 7; i >= 0; i--) printf("%08x", (uint32_t)q[i]); printf("\n"); - - /* q = q * n mod (2^32)^9 */ - for (i = 0; i < 17; i++) { - s[i] = 0; - } - for (i = 0; i < 8; i++) { - w = 0; - for (j = 0; j < 8; j++) { - w += s[i + j] + q[i] * SM2_N[j]; - s[i + j] = w & 0xffffffff; - w >>= 32; - } - s[i + 8] = w; - } - for (i = 0; i < 9; i++) { - q[i] = s[i]; - } - //printf("qn = "); for (i = 8; i >= 0; i--) printf("%08x ", (uint32_t)q[i]); printf("\n"); - - /* r = zl - q (mod (2^32)^9) */ - - if (sm2_bn288_cmp(zl, q)) { - sm2_bn288_sub(zl, zl, q); - } else { - uint64_t c[9] = {0,0,0,0,0,0,0,0,0x100000000}; - sm2_bn288_sub(q, c, q); - sm2_bn288_add(zl, q, zl); - } - //printf("zl = "); for (i = 8; i >= 0; i--) printf("%08x ", (uint32_t)zl[i]); printf("\n"); - for (i = 0; i < 8; i++) { - r[i] = zl[i]; - } - r[7] += zl[8] << 32; - - /* while r >= p do: r = r - n */ - while (sm2_bn_cmp(r, SM2_N) >= 0) { - sm2_bn_sub(r, r, SM2_N); - //printf("r-n = "); for (i = 7; i >= 0; i--) printf("%16llx ", r[i]); printf("\n"); - } - sm2_bn_copy(ret, r); -} - -void sm2_fn_mul_word(SM2_Fn r, const SM2_Fn a, uint32_t b) -{ - SM2_Fn t; - sm2_bn_set_word(t, b); - sm2_fn_mul(r, a, t); -} - -void sm2_fn_sqr(SM2_BN r, const SM2_BN a) -{ - sm2_fn_mul(r, a, a); -} - -void sm2_fn_exp(SM2_BN r, const SM2_BN a, const SM2_BN e) -{ - SM2_BN t; - uint32_t w; - int i, j; - - sm2_bn_set_one(t); - for (i = 7; i >= 0; i--) { - w = (uint32_t)e[i]; - for (j = 0; j < 32; j++) { - sm2_fn_sqr(t, t); - if (w & 0x80000000) { - sm2_fn_mul(t, t, a); - } - w <<= 1; - } - } - sm2_bn_copy(r, t); -} - -void sm2_fn_inv(SM2_BN r, const SM2_BN a) -{ - SM2_BN e; - sm2_bn_sub(e, SM2_N, SM2_TWO); - sm2_fn_exp(r, a, e); -} - -int sm2_fn_rand(SM2_BN r) -{ - if (sm2_bn_rand_range(r, SM2_N) != 1) { - error_print(); - return -1; - } - return 1; -} - -void sm2_jacobian_point_init(SM2_JACOBIAN_POINT *R) -{ - memset(R, 0, sizeof(SM2_JACOBIAN_POINT)); - R->X[0] = 1; - R->Y[0] = 1; -} - -int sm2_jacobian_point_is_at_infinity(const SM2_JACOBIAN_POINT *P) -{ - return sm2_bn_is_zero(P->Z); -} - -void sm2_jacobian_point_set_xy(SM2_JACOBIAN_POINT *R, const SM2_BN x, const SM2_BN y) -{ - sm2_bn_copy(R->X, x); - sm2_bn_copy(R->Y, y); - sm2_bn_set_one(R->Z); -} - -void sm2_jacobian_point_get_xy(const SM2_JACOBIAN_POINT *P, SM2_BN x, SM2_BN y) -{ - if (sm2_bn_is_one(P->Z)) { - sm2_bn_copy(x, P->X); - if (y) { - sm2_bn_copy(y, P->Y); - } - } else { - SM2_BN z_inv; - sm2_fp_inv(z_inv, P->Z); - if (y) { - sm2_fp_mul(y, P->Y, z_inv); - } - sm2_fp_sqr(z_inv, z_inv); - sm2_fp_mul(x, P->X, z_inv); - if (y) { - sm2_fp_mul(y, y, z_inv); - } - } -} - -int sm2_jacobian_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_JACOBIAN_POINT *P) -{ - int len = 0; - SM2_BN x; - SM2_BN y; - - format_print(fp, fmt, ind, "%s\n", label); - ind += 4; - - sm2_jacobian_point_get_xy(P, x, y); - - sm2_bn_print(fp, fmt, ind, "x", x); - sm2_bn_print(fp, fmt, ind, "y", y); - - return 1; -} - -int sm2_jacobian_point_is_on_curve(const SM2_JACOBIAN_POINT *P) -{ - SM2_BN t0; - SM2_BN t1; - SM2_BN t2; - - if (sm2_bn_is_one(P->Z)) { - sm2_fp_sqr(t0, P->Y); - sm2_fp_add(t0, t0, P->X); - sm2_fp_add(t0, t0, P->X); - sm2_fp_add(t0, t0, P->X); - sm2_fp_sqr(t1, P->X); - sm2_fp_mul(t1, t1, P->X); - sm2_fp_add(t1, t1, SM2_B); - } else { - sm2_fp_sqr(t0, P->Y); - sm2_fp_sqr(t1, P->Z); - sm2_fp_sqr(t2, t1); - sm2_fp_mul(t1, t1, t2); - sm2_fp_mul(t1, t1, SM2_B); - sm2_fp_mul(t2, t2, P->X); - sm2_fp_add(t0, t0, t2); - sm2_fp_add(t0, t0, t2); - sm2_fp_add(t0, t0, t2); - sm2_fp_sqr(t2, P->X); - sm2_fp_mul(t2, t2, P->X); - sm2_fp_add(t1, t1, t2); - } - - if (sm2_bn_cmp(t0, t1) != 0) { - error_print(); - return -1; - } - return 1; -} - -void sm2_jacobian_point_neg(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P) -{ - sm2_bn_copy(R->X, P->X); - sm2_fp_neg(R->Y, P->Y); - sm2_bn_copy(R->Z, P->Z); -} - -void sm2_jacobian_point_dbl(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P) -{ - const uint64_t *X1 = P->X; - const uint64_t *Y1 = P->Y; - const uint64_t *Z1 = P->Z; - SM2_BN T1; - SM2_BN T2; - SM2_BN T3; - SM2_BN X3; - SM2_BN Y3; - SM2_BN Z3; - //printf("X1 = "); print_bn(X1); - //printf("Y1 = "); print_bn(Y1); - //printf("Z1 = "); print_bn(Z1); - - if (sm2_jacobian_point_is_at_infinity(P)) { - sm2_jacobian_point_copy(R, P); - return; - } - - sm2_fp_sqr(T1, Z1); //printf("T1 = Z1^2 = "); print_bn(T1); - sm2_fp_sub(T2, X1, T1); //printf("T2 = X1 - T1 = "); print_bn(T2); - sm2_fp_add(T1, X1, T1); //printf("T1 = X1 + T1 = "); print_bn(T1); - sm2_fp_mul(T2, T2, T1); //printf("T2 = T2 * T1 = "); print_bn(T2); - sm2_fp_tri(T2, T2); //printf("T2 = 3 * T2 = "); print_bn(T2); - sm2_fp_dbl(Y3, Y1); //printf("Y3 = 2 * Y1 = "); print_bn(Y3); - sm2_fp_mul(Z3, Y3, Z1); //printf("Z3 = Y3 * Z1 = "); print_bn(Z3); - sm2_fp_sqr(Y3, Y3); //printf("Y3 = Y3^2 = "); print_bn(Y3); - sm2_fp_mul(T3, Y3, X1); //printf("T3 = Y3 * X1 = "); print_bn(T3); - sm2_fp_sqr(Y3, Y3); //printf("Y3 = Y3^2 = "); print_bn(Y3); - sm2_fp_div2(Y3, Y3); //printf("Y3 = Y3/2 = "); print_bn(Y3); - sm2_fp_sqr(X3, T2); //printf("X3 = T2^2 = "); print_bn(X3); - sm2_fp_dbl(T1, T3); //printf("T1 = 2 * T1 = "); print_bn(T1); - sm2_fp_sub(X3, X3, T1); //printf("X3 = X3 - T1 = "); print_bn(X3); - sm2_fp_sub(T1, T3, X3); //printf("T1 = T3 - X3 = "); print_bn(T1); - sm2_fp_mul(T1, T1, T2); //printf("T1 = T1 * T2 = "); print_bn(T1); - sm2_fp_sub(Y3, T1, Y3); //printf("Y3 = T1 - Y3 = "); print_bn(Y3); - - sm2_bn_copy(R->X, X3); - sm2_bn_copy(R->Y, Y3); - sm2_bn_copy(R->Z, Z3); - - //printf("X3 = "); print_bn(R->X); - //printf("Y3 = "); print_bn(R->Y); - //printf("Z3 = "); print_bn(R->Z); - -} - -void sm2_jacobian_point_add(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P, const SM2_JACOBIAN_POINT *Q) -{ - const uint64_t *X1 = P->X; - const uint64_t *Y1 = P->Y; - const uint64_t *Z1 = P->Z; - const uint64_t *x2 = Q->X; - const uint64_t *y2 = Q->Y; - SM2_BN T1; - SM2_BN T2; - SM2_BN T3; - SM2_BN T4; - SM2_BN X3; - SM2_BN Y3; - SM2_BN Z3; - - if (sm2_jacobian_point_is_at_infinity(Q)) { - sm2_jacobian_point_copy(R, P); - return; - } - - if (sm2_jacobian_point_is_at_infinity(P)) { - sm2_jacobian_point_copy(R, Q); - return; - } - - assert(sm2_bn_is_one(Q->Z)); - - sm2_fp_sqr(T1, Z1); - sm2_fp_mul(T2, T1, Z1); - sm2_fp_mul(T1, T1, x2); - sm2_fp_mul(T2, T2, y2); - sm2_fp_sub(T1, T1, X1); - sm2_fp_sub(T2, T2, Y1); - if (sm2_bn_is_zero(T1)) { - if (sm2_bn_is_zero(T2)) { - SM2_JACOBIAN_POINT _Q, *Q = &_Q; - sm2_jacobian_point_set_xy(Q, x2, y2); - - sm2_jacobian_point_dbl(R, Q); - return; - } else { - sm2_jacobian_point_set_infinity(R); - return; - } - } - sm2_fp_mul(Z3, Z1, T1); - sm2_fp_sqr(T3, T1); - sm2_fp_mul(T4, T3, T1); - sm2_fp_mul(T3, T3, X1); - sm2_fp_dbl(T1, T3); - sm2_fp_sqr(X3, T2); - sm2_fp_sub(X3, X3, T1); - sm2_fp_sub(X3, X3, T4); - sm2_fp_sub(T3, T3, X3); - sm2_fp_mul(T3, T3, T2); - sm2_fp_mul(T4, T4, Y1); - sm2_fp_sub(Y3, T3, T4); - - sm2_bn_copy(R->X, X3); - sm2_bn_copy(R->Y, Y3); - sm2_bn_copy(R->Z, Z3); -} - -void sm2_jacobian_point_sub(SM2_JACOBIAN_POINT *R, const SM2_JACOBIAN_POINT *P, const SM2_JACOBIAN_POINT *Q) -{ - SM2_JACOBIAN_POINT _T, *T = &_T; - sm2_jacobian_point_neg(T, Q); - sm2_jacobian_point_add(R, P, T); -} - -void sm2_jacobian_point_mul(SM2_JACOBIAN_POINT *R, const SM2_BN k, const SM2_JACOBIAN_POINT *P) -{ - char bits[257] = {0}; - SM2_JACOBIAN_POINT _Q, *Q = &_Q; - SM2_JACOBIAN_POINT _T, *T = &_T; - int i; - - // FIXME: point_add need affine, so we can not use point_add - if (!sm2_bn_is_one(P->Z)) { - SM2_BN x; - SM2_BN y; - sm2_jacobian_point_get_xy(P, x, y); - sm2_jacobian_point_set_xy(T, x, y); - P = T; - } - - sm2_jacobian_point_set_infinity(Q); - sm2_bn_to_bits(k, bits); - for (i = 0; i < 256; i++) { - sm2_jacobian_point_dbl(Q, Q); - if (bits[i] == '1') { - sm2_jacobian_point_add(Q, Q, P); - } - } - sm2_jacobian_point_copy(R, Q); -} - -void sm2_jacobian_point_to_bytes(const SM2_JACOBIAN_POINT *P, uint8_t out[64]) -{ - SM2_BN x; - SM2_BN y; - sm2_jacobian_point_get_xy(P, x, y); - sm2_bn_to_bytes(x, out); - sm2_bn_to_bytes(y, out + 32); -} - -void sm2_jacobian_point_from_bytes(SM2_JACOBIAN_POINT *P, const uint8_t in[64]) -{ - sm2_bn_from_bytes(P->X, in); - sm2_bn_from_bytes(P->Y, in + 32); - sm2_bn_set_word(P->Z, 1); - /* should we check if sm2_jacobian_point_is_on_curve */ -} - -void sm2_jacobian_point_mul_generator(SM2_JACOBIAN_POINT *R, const SM2_BN k) -{ - sm2_jacobian_point_mul(R, k, SM2_G); -} - -/* R = t * P + s * G */ -void sm2_jacobian_point_mul_sum(SM2_JACOBIAN_POINT *R, const SM2_BN t, const SM2_JACOBIAN_POINT *P, const SM2_BN s) -{ - SM2_JACOBIAN_POINT _sG, *sG = &_sG; - SM2_BN x; - SM2_BN y; - - /* T = s * G */ - sm2_jacobian_point_mul_generator(sG, s); - - // R = t * P - sm2_jacobian_point_mul(R, t, P); - sm2_jacobian_point_get_xy(R, x, y); - sm2_jacobian_point_set_xy(R, x, y); - - // R = R + T - sm2_jacobian_point_add(R, sG, R); -} - -void sm2_jacobian_point_from_hex(SM2_JACOBIAN_POINT *P, const char hex[64 * 2]) -{ - sm2_bn_from_hex(P->X, hex); - sm2_bn_from_hex(P->Y, hex + 64); - sm2_bn_set_one(P->Z); -} - -int sm2_jacobian_point_equ_hex(const SM2_JACOBIAN_POINT *P, const char hex[128]) -{ - SM2_BN x; - SM2_BN y; - SM2_JACOBIAN_POINT _T, *T = &_T; - - sm2_jacobian_point_get_xy(P, x, y); - sm2_jacobian_point_from_hex(T, hex); - - return (sm2_bn_cmp(x, T->X) == 0) && (sm2_bn_cmp(y, T->Y) == 0); -} - -int sm2_point_is_on_curve(const SM2_POINT *P) -{ - SM2_JACOBIAN_POINT T; - sm2_jacobian_point_from_bytes(&T, (const uint8_t *)P); - return sm2_jacobian_point_is_on_curve(&T); -} - -int sm2_point_is_at_infinity(const SM2_POINT *P) -{ - return mem_is_zero((uint8_t *)P, sizeof(SM2_POINT)); -} - -// 这个函数和 sm2_z256_point_from_x_bytes 不一样 -int sm2_point_from_x(SM2_POINT *P, const uint8_t x[32], int y) -{ - SM2_BN _x, _y, _g, _z; - sm2_bn_from_bytes(_x, x); - - // g = x^3 - 3x + b = (x^2 - 3)*x + b - sm2_fp_sqr(_g, _x); - sm2_fp_sub(_g, _g, SM2_THREE); - sm2_fp_mul(_g, _g, _x); - sm2_fp_add(_g, _g, SM2_B); - - // y = g^(u + 1) mod p, u = (p - 3)/4 - sm2_fp_exp(_y, _g, SM2_U_PLUS_ONE); - - // z = y^2 mod p - sm2_fp_sqr(_z, _y); - if (sm2_bn_cmp(_z, _g)) { - error_print(); - return -1; - } - - if ((y == 0x02 && sm2_bn_is_odd(_y)) || ((y == 0x03) && !sm2_bn_is_odd(_y))) { - sm2_fp_neg(_y, _y); - } - - sm2_bn_to_bytes(_x, P->x); - sm2_bn_to_bytes(_y, P->y); - - sm2_bn_clean(_x); - sm2_bn_clean(_y); - sm2_bn_clean(_g); - sm2_bn_clean(_z); - - if (sm2_point_is_on_curve(P) != 1) { - error_print(); - return -1; - } - 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_JACOBIAN_POINT P_; - SM2_JACOBIAN_POINT Q_; - - sm2_jacobian_point_from_bytes(&P_, (uint8_t *)P); - sm2_jacobian_point_from_bytes(&Q_, (uint8_t *)Q); - sm2_jacobian_point_add(&P_, &P_, &Q_); - sm2_jacobian_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_JACOBIAN_POINT P_; - SM2_JACOBIAN_POINT Q_; - - sm2_jacobian_point_from_bytes(&P_, (uint8_t *)P); - sm2_jacobian_point_from_bytes(&Q_, (uint8_t *)Q); - sm2_jacobian_point_sub(&P_, &P_, &Q_); - sm2_jacobian_point_to_bytes(&P_, (uint8_t *)R); - - return 1; -} - -int sm2_point_neg(SM2_POINT *R, const SM2_POINT *P) -{ - SM2_JACOBIAN_POINT P_; - - sm2_jacobian_point_from_bytes(&P_, (uint8_t *)P); - sm2_jacobian_point_neg(&P_, &P_); - sm2_jacobian_point_to_bytes(&P_, (uint8_t *)R); - - return 1; -} - -int sm2_point_dbl(SM2_POINT *R, const SM2_POINT *P) -{ - SM2_JACOBIAN_POINT P_; - - sm2_jacobian_point_from_bytes(&P_, (uint8_t *)P); - sm2_jacobian_point_dbl(&P_, &P_); - sm2_jacobian_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) -{ - SM2_BN _k; - SM2_JACOBIAN_POINT _P; - - sm2_bn_from_bytes(_k, k); - sm2_jacobian_point_from_bytes(&_P, (uint8_t *)P); - sm2_jacobian_point_mul(&_P, _k, &_P); - sm2_jacobian_point_to_bytes(&_P, (uint8_t *)R); - - sm2_bn_clean(_k); - return 1; -} - -int sm2_point_mul_generator(SM2_POINT *R, const uint8_t k[32]) -{ - SM2_BN _k; - SM2_JACOBIAN_POINT _R; - - sm2_bn_from_bytes(_k, k); - sm2_jacobian_point_mul_generator(&_R, _k); - sm2_jacobian_point_to_bytes(&_R, (uint8_t *)R); - - sm2_bn_clean(_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]) -{ - SM2_BN _k; - SM2_JACOBIAN_POINT _P; - SM2_BN _s; - - sm2_bn_from_bytes(_k, k); - sm2_jacobian_point_from_bytes(&_P, (uint8_t *)P); - sm2_bn_from_bytes(_s, s); - sm2_jacobian_point_mul_sum(&_P, _k, &_P, _s); - sm2_jacobian_point_to_bytes(&_P, (uint8_t *)R); - - sm2_bn_clean(_k); - sm2_bn_clean(_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_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) -{ - SM2_BN u; - SM2_Fp x; - SM2_Fp y; - SM2_Fp s; - SM2_Fp s_; - uint8_t dgst[32]; - - // u = (p + 1)/4 - sm2_bn_add(u, SM2_P, SM2_ONE); - sm2_bn_rshift(u, u, 2); - - // How many times? - do { - sm3_digest(data, datalen, dgst); - - sm2_bn_from_bytes(x, dgst); - if (sm2_bn_cmp(x, SM2_P) >= 0) { - sm2_bn_sub(x, x, SM2_P); - } - - // s = y^2 = x^3 + a*x + b - sm2_fp_sqr(s, x); - sm2_fp_sub(s, s, SM2_THREE); - sm2_fp_mul(s, s, x); - sm2_fp_add(s, s, SM2_B); - - // y = s^((p+1)/4) = (sqrt(s) (mod p)) - sm2_fp_exp(y, s, u); - sm2_fp_sqr(s_, y); - - data = dgst; - datalen = sizeof(dgst); - - } while (sm2_bn_cmp(s, s_) != 0); - - sm2_bn_to_bytes(x, R->x); - sm2_bn_to_bytes(y, R->y); - return 1; -} - -const uint64_t *sm2_bn_prime(void) { - return &SM2_P[0]; -} - -const uint64_t *sm2_bn_order(void) { - return &SM2_N[0]; -} - -const uint64_t *sm2_bn_one(void) { - return &SM2_ONE[0]; -} - - - diff --git a/src/sm2_key.c b/src/sm2_key.c deleted file mode 100644 index 574d4a8c..00000000 --- a/src/sm2_key.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -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; -} diff --git a/src/sm2_point.c b/src/sm2_point.c deleted file mode 100644 index 0e517915..00000000 --- a/src/sm2_point.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -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; -} - diff --git a/src/sm2_sign.c b/src/sm2_sign.c deleted file mode 100644 index ddf4993d..00000000 --- a/src/sm2_sign.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#include -#include - - -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; -} diff --git a/src/sm2_z256.c b/src/sm2_z256.c index bf47a96f..a25f3040 100644 --- a/src/sm2_z256.c +++ b/src/sm2_z256.c @@ -53,7 +53,7 @@ #include #include #include - +#include /* 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; +} + + + diff --git a/src/sm2_z256_sign.c b/src/sm2_z256_sign.c index d413c236..973d97d6 100644 --- a/src/sm2_z256_sign.c +++ b/src/sm2_z256_sign.c @@ -20,64 +20,34 @@ #include -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; } diff --git a/tests/sm2_z256test.c b/tests/sm2_z256test.c index e29cb68f..194c41eb 100644 --- a/tests/sm2_z256test.c +++ b/tests/sm2_z256test.c @@ -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;