Update SM2

This commit is contained in:
Zhi Guan
2024-03-10 22:34:43 +08:00
parent cfdcd0c0e3
commit 33baa3df92
15 changed files with 2410 additions and 268 deletions

View File

@@ -16,88 +16,52 @@
#include <gmssl/sm2.h>
#include <gmssl/pkcs8.h>
// 由于当前Ciphertext中椭圆曲线点数据不正确因此无法通过测试
// 应该整理出不同编码长度的椭圆曲线点可以由x求出y
static int test_sm2_ciphertext(void)
{
struct {
char *label;
size_t ciphertext_size;
} tests[] = {
{ "null ciphertext", 0 },
{ "min ciphertext size", SM2_MIN_PLAINTEXT_SIZE },
{ "max ciphertext size", SM2_MAX_PLAINTEXT_SIZE },
};
SM2_CIPHERTEXT C;
SM2_KEY sm2_key;
uint8_t buf[1024];
uint8_t *p = buf;
const uint8_t *cp = buf;
size_t len = 0;
size_t i;
memset(&C, 0, sizeof(SM2_CIPHERTEXT));
rand_bytes(C.hash, 32);
rand_bytes(C.ciphertext, SM2_MAX_PLAINTEXT_SIZE);
cp = p = buf; len = 0;
if (sm2_ciphertext_to_der(&C, &p, &len) != 1) {
error_print();
return -1;
}
format_print(stderr, 0, 4, "SM2_NULL_CIPHERTEXT_SIZE: %zu\n", len);
format_bytes(stderr, 0, 4, "", buf, len);
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
uint8_t *p = buf;
const uint8_t *cp = buf;
size_t len = 0;
if (sm2_ciphertext_from_der(&C, &cp, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
if (sm2_key_generate(&sm2_key) != 1) {
error_print();
return -1;
}
C.point = sm2_key.public_key;
C.ciphertext_size = tests[i].ciphertext_size;
if (sm2_ciphertext_to_der(&C, &p, &len) != 1) {
error_print();
return -1;
}
// {0, 0, Hash, MinLen}
C.ciphertext_size = SM2_MIN_PLAINTEXT_SIZE;
cp = p = buf; len = 0;
if (sm2_ciphertext_to_der(&C, &p, &len) != 1) {
error_print();
return -1;
}
format_print(stderr, 0, 4, "SM2_MIN_PLAINTEXT_SIZE: %zu\n", SM2_MIN_PLAINTEXT_SIZE);
format_print(stderr, 0, 4, "SM2_MIN_CIPHERTEXT_SIZE: %zu\n", len);
format_bytes(stderr, 0, 4, "", buf, len);
if (len != SM2_MIN_CIPHERTEXT_SIZE) {
error_print();
return -1;
}
if (sm2_ciphertext_from_der(&C, &cp, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
printf("Plaintext size = %zu, SM2Ciphertext DER size %zu\n", tests[i].ciphertext_size, len);
// { 33, 33, Hash, NULL }
memset(&C, 0x80, sizeof(SM2_POINT));
cp = p = buf; len = 0;
if (sm2_ciphertext_to_der(&C, &p, &len) != 1) {
error_print();
return -1;
}
format_print(stderr, 0, 4, "ciphertext len: %zu\n", len);
format_bytes(stderr, 0, 4, "", buf, len);
if (sm2_ciphertext_from_der(&C, &cp, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
if (sm2_ciphertext_from_der(&C, &cp, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
// { 33, 33, Hash, MaxLen }
C.ciphertext_size = SM2_MAX_PLAINTEXT_SIZE;//SM2_MAX_PLAINTEXT_SIZE;
cp = p = buf; len = 0;
if (sm2_ciphertext_to_der(&C, &p, &len) != 1) {
error_print();
return -1;
}
format_print(stderr, 0, 4, "SM2_MAX_PLAINTEXT_SIZE: %zu\n", SM2_MAX_PLAINTEXT_SIZE);
format_print(stderr, 0, 4, "SM2_MAX_CIPHERTEXT_SIZE: %zu\n", len);
format_bytes(stderr, 0, 4, "", buf, len);
if (len != SM2_MAX_CIPHERTEXT_SIZE) {
error_print();
return -1;
}
if (sm2_ciphertext_from_der(&C, &cp, &len) != 1
|| asn1_length_is_zero(len) != 1) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
@@ -265,14 +229,6 @@ static int test_sm2_encrypt_fixlen(void)
}
// 应该生成不同情况下的密文!
static int test_sm2_encrypt(void)
{
SM2_KEY sm2_key;
@@ -327,7 +283,7 @@ static int test_sm2_encrypt(void)
int main(void)
{
//if (test_sm2_ciphertext() != 1) goto err; // 需要正确的Ciphertext数据
if (test_sm2_ciphertext() != 1) goto err;
if (test_sm2_do_encrypt() != 1) goto err;
if (test_sm2_do_encrypt_fixlen() != 1) goto err;
if (test_sm2_encrypt() != 1) goto err;

View File

@@ -109,6 +109,7 @@ static int test_sm2_do_sign(void)
#define sm2_u256_modn_add sm2_z256_modn_add
#define sm2_u256_modn_inv sm2_z256_modn_inv
static int test_sm2_do_sign_fast(void)
{
SM2_KEY sm2_key;
@@ -141,6 +142,45 @@ static int test_sm2_do_sign_fast(void)
return 1;
}
static int test_sm2_do_sign_pre_compute(void)
{
SM2_KEY sm2_key;
uint64_t d[4];
uint64_t k[4];
uint64_t x1[4];
uint8_t dgst[32];
SM2_SIGNATURE sig;
sm2_key_generate(&sm2_key);
const uint64_t *one = sm2_z256_one();
sm2_z256_from_bytes(d, sm2_key.private_key);
sm2_z256_modn_add(d, d, one);
sm2_z256_modn_inv(d, d);
if (sm2_do_sign_pre_compute(k, x1) != 1) {
error_print();
return -1;
}
rand_bytes(dgst, sizeof(dgst));
if (sm2_do_sign_fast_ex(d, k, x1, dgst, &sig) != 1) {
error_print();
return -1;
}
if (sm2_do_verify(&sm2_key, dgst, &sig) != 1) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_sm2_sign(void)
{
SM2_KEY sm2_key;
@@ -209,12 +249,95 @@ static int test_sm2_sign_ctx(void)
return 1;
}
static int test_sm2_sign_ctx_reset(void)
{
SM2_KEY sm2_key;
SM2_SIGN_CTX sign_ctx;
SM2_SIGN_CTX vrfy_ctx;
uint8_t msg[64];
uint8_t sig[SM2_MAX_SIGNATURE_SIZE];
size_t siglen;
if (sm2_key_generate(&sm2_key) != 1) {
error_print();
return -1;
}
// init sign_ctx and sign a message
rand_bytes(msg, sizeof(msg));
if (sm2_sign_init(&sign_ctx, &sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
error_print();
return -1;
}
if (sm2_sign_update(&sign_ctx, msg, sizeof(msg)) != 1) {
error_print();
return -1;
}
if (sm2_sign_finish(&sign_ctx, sig, &siglen) != 1) {
error_print();
return -1;
}
// reset sign_ctx and sign another message
rand_bytes(msg, sizeof(msg));
if (sm2_sign_ctx_reset(&sign_ctx) != 1) {
error_print();
return -1;
}
if (sm2_sign_update(&sign_ctx, msg, sizeof(msg)) != 1) {
error_print();
return -1;
}
if (sm2_sign_finish(&sign_ctx, sig, &siglen) != 1) {
error_print();
return -1;
}
// verify, check whether reset works
if (sm2_verify_init(&vrfy_ctx, &sm2_key, SM2_DEFAULT_ID, SM2_DEFAULT_ID_LENGTH) != 1) {
error_print();
return -1;
}
if (sm2_verify_update(&vrfy_ctx, msg, sizeof(msg)) != 1) {
error_print();
return -1;
}
if (sm2_verify_finish(&vrfy_ctx, sig, siglen) != 1) {
format_bytes(stderr, 0, 4, "signature", sig, siglen);
error_print();
return -1;
}
// reset ctx and verify again
if (sm2_sign_ctx_reset(&vrfy_ctx) != 1) {
error_print();
return -1;
}
if (sm2_verify_update(&vrfy_ctx, msg, sizeof(msg)) != 1) {
error_print();
return -1;
}
if (sm2_verify_finish(&vrfy_ctx, sig, siglen) != 1) {
format_bytes(stderr, 0, 4, "signature", sig, siglen);
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
int main(void)
{
if (test_sm2_do_sign_fast() != 1) goto err;
if (test_sm2_signature() != 1) goto err;
if (test_sm2_do_sign() != 1) goto err;
if (test_sm2_do_sign_pre_compute() != 1) goto err;
if (test_sm2_sign() != 1) goto err;
if (test_sm2_sign_ctx() != 1) goto err;
if (test_sm2_sign_ctx_reset() != 1) goto err;
printf("%s all tests passed\n", __FILE__);
return 0;
err:

View File

@@ -12,11 +12,20 @@
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <gmssl/sm2.h>
#include <gmssl/sm2_z256.h>
#include <gmssl/sm3.h>
#include <gmssl/sm3_digest.h>
#include <gmssl/hex.h>
#include <gmssl/rand.h>
#include <gmssl/error.h>
/*
TODO: 验证点加、倍点等计算是否支持无穷远点、共轭点等特殊形势
*/
enum {
OP_ADD,
OP_DBL,
@@ -28,6 +37,67 @@ enum {
OP_INV,
};
#define TEST_COUNT 10
static int test_sm2_z256_rshift(void)
{
uint64_t r[4];
uint64_t a[4];
uint64_t b[4];
unsigned int i;
sm2_z256_modn_rand(a);
sm2_z256_rshift(r, a, 0);
sm2_z256_copy(b, a);
if (sm2_z256_cmp(r, b) != 0) {
error_print();
return -1;
}
sm2_z256_rshift(r, a, 63);
for (i = 0; i < 63; i++) {
sm2_z256_rshift(a, a, 1);
}
if (sm2_z256_cmp(r, a) != 0) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_sm2_z256_modp_mont_sqrt(void)
{
uint64_t a[4];
uint64_t neg_a[4];
uint64_t mont_a[4];
uint64_t mont_sqr_a[4];
uint64_t mont_a_[4];
uint64_t a_[4];
int i;
for (i = 0; i < 6; i++) {
sm2_z256_modn_rand(a);
sm2_z256_modp_neg(neg_a, a);
sm2_z256_modp_to_mont(a, mont_a);
sm2_z256_modp_mont_sqr(mont_sqr_a, mont_a);
sm2_z256_modp_mont_sqrt(mont_a_, mont_sqr_a);
sm2_z256_modp_from_mont(a_, mont_a_);
// a_ = sqrt(a^2), a_ should be a or -a
if (sm2_z256_cmp(a_, a) != 0 && sm2_z256_cmp(a_, neg_a) != 0) {
error_print();
return -1;
}
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_sm2_z256_modp(void)
{
struct {
@@ -389,6 +459,95 @@ static int test_sm2_z256_point_get_xy(void)
return 1;
}
static int test_sm2_z256_point_from_x_bytes(void)
{
struct {
char *label;
char *xy;
int y_is_odd;
} tests[] = {
{
"G (y is even)",
"32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7"
"bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0",
0,
},
{
"2G (y is odd)",
"56cefd60d7c87c000d58ef57fa73ba4d9c0dfa08c08a7331495c2e1da3f2bd52"
"31b7e7e6cc8189f668535ce0f8eaf1bd6de84c182f6c8e716f780d3a970a23c3",
1,
},
};
SM2_Z256_POINT P;
uint8_t x_bytes[32];
size_t i, len;
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
hex_to_bytes(tests[i].xy, 64, x_bytes, &len);
sm2_z256_point_from_x_bytes(&P, x_bytes, tests[i].y_is_odd);
if (sm2_z256_point_equ_hex(&P, tests[i].xy) != 1) {
error_print();
return -1;
}
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_sm2_z256_point_add_conjugate(void)
{
char *hex_G =
"32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7"
"bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0";
char *hex_negG =
"32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7"
"43c8c95c0b098863a642311c9496deac2f56788239d5b8c0fd20cd1adec60f5f";
SM2_Z256_POINT R;
SM2_Z256_POINT P;
SM2_Z256_POINT Q;
sm2_z256_point_from_hex(&P, hex_G);
sm2_z256_point_from_hex(&Q, hex_negG);
sm2_z256_point_add(&R, &P, &Q);
// P + (-P) = (0:0:0)
if (!sm2_z256_is_zero(R.X)
|| !sm2_z256_is_zero(R.Y)
|| !sm2_z256_is_zero(R.Z)) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_sm2_z256_point_dbl_infinity(void)
{
SM2_Z256_POINT P_infinity;
SM2_Z256_POINT R;
sm2_z256_point_set_infinity(&P_infinity);
sm2_z256_point_dbl(&R, &P_infinity); // 显然这个计算就会出错了!
if (!sm2_z256_point_is_at_infinity(&R)) {
error_print(); // 这个会出错
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_sm2_z256_point_ops(void)
{
char *hex_G =
@@ -472,6 +631,8 @@ static int test_sm2_z256_point_ops(void)
return -1;
}
if (sm2_z256_point_equ_hex(&P, tests[i].R) != 1) {
fprintf(stderr, "%s\n", tests[i].label);
sm2_z256_point_print(stderr, 0, 4, "R", &P);
fprintf(stderr, " R: %s\n", tests[i].R);
@@ -479,8 +640,6 @@ static int test_sm2_z256_point_ops(void)
fprintf(stderr, " A: %s\n", tests[i].A);
fprintf(stderr, " B: %s\n", tests[i].B);
if (sm2_z256_point_equ_hex(&P, tests[i].R) != 1) {
error_print();
return -1;
}
@@ -614,14 +773,108 @@ static int test_sm2_z256_point_mul_generator(void)
return 1;
}
static int test_sm2_z256_point_equ(void)
{
struct {
char *label;
char *mont_X1;
char *mont_Y1;
char *mont_Z1;
char *mont_X2;
char *mont_Y2;
char *mont_Z2;
} tests[] = {
{
"Point at Infinity (1:1:0)",
"0000000100000000000000000000000000000000ffffffff0000000000000001", // mont(1)
"0000000100000000000000000000000000000000ffffffff0000000000000001", // mont(1)
"0000000000000000000000000000000000000000000000000000000000000000", // 0
"0000000100000000000000000000000000000000ffffffff0000000000000001", // mont(1)
"0000000100000000000000000000000000000000ffffffff0000000000000001", // mont(1)
"0000000000000000000000000000000000000000000000000000000000000000", // 0
},
{
"[2]2G == 2G + G + G",
"87b2ca9ded2487c6efdbc69303258763a0b5520fc63cf40154f6c059b945acf2",
"dc86353bc72db45ebb5b2d03cec4614b164688f19f12dd857fd007e181457b59",
"050653f8579d1d2d930d7346e31bad56b5a4654d6a9f2c5022434941744ced3a",
"e8457905838420a51366f7fe174ce34dc3579fefc188f0b5124e7537526ae99e",
"48c3374ab1d5fde0276bebb81b8ff0baa9805cc2d0f487e18d7b3a4352f4ae21",
"79f76fd57f22f1e282d64ff809a53f1f729f6b89c6f626b96725a9d05704e681",
}
};
SM2_Z256_POINT P;
SM2_Z256_POINT Q;
size_t i;
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
sm2_z256_from_hex(P.X, tests[i].mont_X1);
sm2_z256_from_hex(P.Y, tests[i].mont_Y1);
sm2_z256_from_hex(P.Z, tests[i].mont_Z1);
sm2_z256_from_hex(Q.X, tests[i].mont_X2);
sm2_z256_from_hex(Q.Y, tests[i].mont_Y2);
sm2_z256_from_hex(Q.Z, tests[i].mont_Z2);
if (sm2_z256_point_equ(&P, &Q) != 1) {
error_print();
return -1;
}
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_sm2_z256_point_from_hash(void)
{
SM2_Z256_POINT P;
uint8_t data[64];
size_t datalen = sizeof(data);
int y_is_odd = 1;
int y_is_even = 0;
size_t i;
for (i = 0; i < 5; i++) {
rand_bytes(data, datalen);
if (sm2_z256_point_from_hash(&P, data, datalen, y_is_odd) != 1) {
error_print();
return -1;
}
if (sm2_z256_point_from_hash(&P, data, datalen, y_is_even) != 1) {
error_print();
return -1;
}
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
int main(void)
{
if (test_sm2_z256_rshift() != 1) goto err;
if (test_sm2_z256_modp() != 1) goto err;
if (test_sm2_z256_modn() != 1) goto err;
if (test_sm2_z256_point_is_on_curve() != 1) goto err;
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;
if (test_sm2_z256_modp_mont_sqrt() != 1) goto err;
printf("%s all tests passed\n", __FILE__);
return 0;
err: