mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-06 16:36:16 +08:00
Add SM2 Z256 implementation
This commit is contained in:
@@ -313,9 +313,13 @@ if (ENABLE_SM4_XTS)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
option(ENABLE_SM2_Z256 "Enable SM2 z256 implementation" OFF)
|
||||
if (ENABLE_SM2_Z256)
|
||||
message(STATUS "ENABLE_SM2_Z256 is ON")
|
||||
add_definitions(-DENABLE_SM2_Z256)
|
||||
list(APPEND src src/sm2_z256.c src/sm2_z256_table.c)
|
||||
list(APPEND tests sm2_z256)
|
||||
endif()
|
||||
|
||||
|
||||
option(ENABLE_SM2_EXTS "Enable SM2 Extensions" OFF)
|
||||
|
||||
87
include/gmssl/sm2_z256.h
Normal file
87
include/gmssl/sm2_z256.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef GMSSL_SM2_Z256_H
|
||||
#define GMSSL_SM2_Z256_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
void sm2_z256_copy(uint64_t r[4], const uint64_t a[4]);
|
||||
void sm2_z256_copy_conditional(uint64_t dst[4], const uint64_t src[4], uint64_t move);
|
||||
void sm2_z256_from_bytes(uint64_t r[4], const uint8_t in[32]);
|
||||
void sm2_z256_to_bytes(const uint64_t a[4], uint8_t out[32]);
|
||||
int sm2_z256_cmp(const uint64_t a[4], const uint64_t b[4]);
|
||||
uint64_t sm2_z256_equ(const uint64_t a[4], const uint64_t b[4]);
|
||||
uint64_t sm2_z256_add(uint64_t r[4], const uint64_t a[4], const uint64_t b[4]);
|
||||
uint64_t sm2_z256_sub(uint64_t r[4], const uint64_t a[4], const uint64_t b[4]);
|
||||
void sm2_z256_mul(uint64_t r[8], const uint64_t a[4], const uint64_t b[4]);
|
||||
uint64_t sm2_z512_add(uint64_t r[8], const uint64_t a[8], const uint64_t b[8]);
|
||||
int sm2_z256_get_booth(const uint64_t a[4], unsigned int window_size, int i);
|
||||
void sm2_z256_from_hex(uint64_t r[4], const char *hex);
|
||||
int sm2_z256_print(FILE *fp, int ind, int fmt, const char *label, const uint64_t a[4]);
|
||||
int sm2_z512_print(FILE *fp, int ind, int fmt, const char *label, const uint64_t a[8]);
|
||||
|
||||
void sm2_z256_modp_add(uint64_t r[4], const uint64_t a[4], const uint64_t b[4]);
|
||||
void sm2_z256_modp_sub(uint64_t r[4], const uint64_t a[4], const uint64_t b[4]);
|
||||
void sm2_z256_modp_neg(uint64_t r[4], const uint64_t a[4]);
|
||||
void sm2_z256_modp_mul_by_2(uint64_t r[4], const uint64_t a[4]);
|
||||
void sm2_z256_modp_mul_by_3(uint64_t r[4], const uint64_t a[4]);
|
||||
void sm2_z256_modp_div_by_2(uint64_t r[4], const uint64_t a[4]);
|
||||
|
||||
void sm2_z256_to_mont(const uint64_t a[4], uint64_t r[4]);
|
||||
void sm2_z256_from_mont(uint64_t r[4], const uint64_t a[4]);
|
||||
void sm2_z256_mont_mul(uint64_t r[4], const uint64_t a[4], const uint64_t b[4]);
|
||||
void sm2_z256_mont_sqr(uint64_t r[4], const uint64_t a[4]);
|
||||
void sm2_z256_mont_inv(uint64_t r[4], const uint64_t a[4]);
|
||||
int sm2_z256_mont_print(FILE *fp, int ind, int fmt, const char *label, const uint64_t a[4]);
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint64_t X[4];
|
||||
uint64_t Y[4];
|
||||
uint64_t Z[4];
|
||||
} SM2_Z256_POINT;
|
||||
|
||||
void sm2_z256_point_to_bytes(const SM2_Z256_POINT *P, uint8_t out[64]);
|
||||
void sm2_z256_point_dbl(SM2_Z256_POINT *R, const SM2_Z256_POINT *A);
|
||||
void sm2_z256_point_add(SM2_Z256_POINT *r, const SM2_Z256_POINT *a, const SM2_Z256_POINT *b);
|
||||
void sm2_z256_point_neg(SM2_Z256_POINT *R, const SM2_Z256_POINT *P);
|
||||
void sm2_z256_point_sub(SM2_Z256_POINT *R, const SM2_Z256_POINT *A, const SM2_Z256_POINT *B);
|
||||
void sm2_z256_point_get_affine(const SM2_Z256_POINT *P, uint64_t x[4], uint64_t y[4]);
|
||||
int sm2_z256_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_Z256_POINT *P);
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint64_t x[4];
|
||||
uint64_t y[4];
|
||||
} SM2_Z256_POINT_AFFINE;
|
||||
|
||||
void sm2_z256_point_copy_affine(SM2_Z256_POINT *R, const SM2_Z256_POINT_AFFINE *P);
|
||||
void sm2_z256_point_add_affine(SM2_Z256_POINT *r, const SM2_Z256_POINT *a, const SM2_Z256_POINT_AFFINE *b);
|
||||
void sm2_z256_point_sub_affine(SM2_Z256_POINT *R, const SM2_Z256_POINT *A, const SM2_Z256_POINT_AFFINE *B);
|
||||
int sm2_z256_point_affine_print(FILE *fp, int fmt, int ind, const char *label, const SM2_Z256_POINT_AFFINE *P);
|
||||
|
||||
void sm2_z256_point_mul_generator(SM2_Z256_POINT *R, const uint64_t k[4]);
|
||||
void sm2_z256_point_mul(SM2_Z256_POINT *R, const SM2_Z256_POINT *P, const uint64_t k[4]);
|
||||
void sm2_z256_point_mul_sum(SM2_Z256_POINT *R, const uint64_t t[4], const SM2_Z256_POINT *P, const uint64_t s[4]);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
1004
src/sm2_z256.c
Normal file
1004
src/sm2_z256.c
Normal file
File diff suppressed because it is too large
Load Diff
4835
src/sm2_z256_table.c
Normal file
4835
src/sm2_z256_table.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
|
||||
* 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.
|
||||
@@ -12,462 +12,91 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <gmssl/hex.h>
|
||||
#include <gmssl/error.h>
|
||||
#include <gmssl/sm2_z256.h>
|
||||
#include <gmssl/hex.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
|
||||
static int sm2_z256_equ_hex(const uint64_t a[4], const char *hex)
|
||||
static int test_sm2_z256_point_mul_generator(void)
|
||||
{
|
||||
uint64_t b[4];
|
||||
sm2_z256_from_hex(b, hex);
|
||||
return (sm2_z256_cmp(a, b) == 0);
|
||||
}
|
||||
|
||||
|
||||
int sm2_z256_mont_equ_hex(const uint64_t a[4], const char *hex)
|
||||
{
|
||||
uint64_t a_[4];
|
||||
uint64_t b[4];
|
||||
|
||||
sm2_z256_from_mont(a_, a);
|
||||
sm2_z256_from_hex(b, hex);
|
||||
return (sm2_z256_cmp(a_, b) == 0);
|
||||
}
|
||||
|
||||
static int test_sm2_z256_add(void)
|
||||
{
|
||||
char *hex_x = "32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7";
|
||||
char *hex_y = "bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0";
|
||||
char *hex_add_x_y = "eefbe4cf140ff8b5b956d329d5a2eae8608c933cb89053217439786e54866567";
|
||||
char *hex_2y = "786e6d45e9ecef38b37b9dc6d6d242a7a1530ef98c548e8005be65ca4273e140";
|
||||
|
||||
uint64_t x[4];
|
||||
uint64_t y[4];
|
||||
uint64_t r[4];
|
||||
uint64_t c;
|
||||
|
||||
sm2_z256_from_hex(x, hex_x);
|
||||
sm2_z256_from_hex(y, hex_y);
|
||||
|
||||
c = sm2_z256_add(r, x, y);
|
||||
if (c != 0 || sm2_z256_equ_hex(r, hex_add_x_y) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
c = sm2_z256_add(r, y, y);
|
||||
if (c != 1 || sm2_z256_equ_hex(r, hex_2y) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm2_z256_sub(void)
|
||||
{
|
||||
char *hex_x = "32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7";
|
||||
char *hex_y = "bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0";
|
||||
char *hex_sub_x_y = "768d77892a23097d05db3562fed0a840bf3984432c3bc4a16e7b12a412128427";
|
||||
char *hex_sub_y_x = "89728876d5dcf682fa24ca9d012f57bf40c67bbcd3c43b5e9184ed5beded7bd9";
|
||||
uint64_t x[4];
|
||||
uint64_t y[4];
|
||||
uint64_t r[4];
|
||||
uint64_t c;
|
||||
|
||||
sm2_z256_from_hex(x, hex_x);
|
||||
sm2_z256_from_hex(y, hex_y);
|
||||
|
||||
c = sm2_z256_sub(r, x, y);
|
||||
if (c != 1 || sm2_z256_equ_hex(r, hex_sub_x_y) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
c = sm2_z256_sub(r, y, x);
|
||||
if (c != 0 || sm2_z256_equ_hex(r, hex_sub_y_x) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm2_z256_mul(void)
|
||||
{
|
||||
char *hex_x = "32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7";
|
||||
char *hex_y = "bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0";
|
||||
char *hex_mul_x_y =
|
||||
"255362ffa019467e48add0ebbe29d15e82fab48f15592867dbdab16dde8d0673"
|
||||
"dd4057dd755d04ff86dad43f0ecaf69ddccd043ba61f523ebe51b0ee64928c60";
|
||||
|
||||
uint64_t x[4];
|
||||
uint64_t y[4];
|
||||
uint64_t r[8];
|
||||
|
||||
sm2_z256_from_hex(x, hex_x);
|
||||
sm2_z256_from_hex(y, hex_y);
|
||||
|
||||
sm2_z256_mul(r, x, y);
|
||||
|
||||
if (sm2_z256_equ_hex(r + 4, hex_mul_x_y) != 1
|
||||
|| sm2_z256_equ_hex(r, hex_mul_x_y + 64) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm2_z256_cmp(void)
|
||||
{
|
||||
char *hex_x = "32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7";
|
||||
char *hex_y = "bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0";
|
||||
|
||||
uint64_t x[4];
|
||||
uint64_t y[4];
|
||||
|
||||
sm2_z256_from_hex(x, hex_x);
|
||||
sm2_z256_from_hex(y, hex_y);
|
||||
|
||||
if (sm2_z256_cmp(x, y) != -1
|
||||
|| sm2_z256_cmp(x, x) != 0
|
||||
|| sm2_z256_cmp(y, y) != 0
|
||||
|| sm2_z256_cmp(y, x) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm2_z256_modp_add(void)
|
||||
{
|
||||
char *hex_x = "32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7";
|
||||
char *hex_y = "bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0";
|
||||
char *hex_modp_add_x_y = "eefbe4cf140ff8b5b956d329d5a2eae8608c933cb89053217439786e54866567";
|
||||
char *hex_neg_x = "cd3b51d2e0e67ee6a066fbb995c6366b701cf43f0d99f41f8ea5ba76ccb38b38";
|
||||
char *hex_p_sub_1 = "fffffffeffffffffffffffffffffffffffffffff00000000fffffffffffffffe";
|
||||
char *hex_2 = "0000000000000000000000000000000000000000000000000000000000000002";
|
||||
char *hex_1 = "0000000000000000000000000000000000000000000000000000000000000001";
|
||||
char *hex_0 = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||
char *hex_modp_2y = "786e6d46e9ecef38b37b9dc6d6d242a7a1530efa8c548e7f05be65ca4273e141";
|
||||
|
||||
uint64_t x[4];
|
||||
uint64_t y[4];
|
||||
uint64_t r[4];
|
||||
|
||||
sm2_z256_from_hex(x, hex_x);
|
||||
sm2_z256_from_hex(y, hex_y);
|
||||
|
||||
// x + y < p
|
||||
sm2_z256_modp_add(r, x, y);
|
||||
if (sm2_z256_equ_hex(r, hex_modp_add_x_y) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// x + y > 2^256
|
||||
sm2_z256_modp_add(r, y, y);
|
||||
if (sm2_z256_equ_hex(r, hex_modp_2y) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// x + y = p
|
||||
sm2_z256_from_hex(r, hex_neg_x);
|
||||
sm2_z256_modp_add(r, r, x);
|
||||
if (sm2_z256_equ_hex(r, hex_0) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// p < x + y < 2^256
|
||||
sm2_z256_from_hex(x, hex_p_sub_1);
|
||||
sm2_z256_from_hex(y, hex_2);
|
||||
sm2_z256_modp_add(r, x, y);
|
||||
if (sm2_z256_equ_hex(r, hex_1) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm2_z256_modp_sub(void)
|
||||
{
|
||||
char *hex_x = "32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7";
|
||||
char *hex_y = "bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0";
|
||||
char *hex_modp_sub_x_y = "768d77882a23097d05db3562fed0a840bf3984422c3bc4a26e7b12a412128426";
|
||||
char *hex_modp_sub_y_x = "89728876d5dcf682fa24ca9d012f57bf40c67bbcd3c43b5e9184ed5beded7bd9";
|
||||
char *hex_0 = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||
|
||||
uint64_t x[4];
|
||||
uint64_t y[4];
|
||||
uint64_t r[4];
|
||||
|
||||
sm2_z256_from_hex(x, hex_x);
|
||||
sm2_z256_from_hex(y, hex_y);
|
||||
|
||||
sm2_z256_modp_sub(r, x, y);
|
||||
if (sm2_z256_equ_hex(r, hex_modp_sub_x_y) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
sm2_z256_modp_sub(r, y, x);
|
||||
if (sm2_z256_equ_hex(r, hex_modp_sub_y_x) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
sm2_z256_modp_sub(r, x, x);
|
||||
if (sm2_z256_equ_hex(r, hex_0) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm2_z256_modp_div_by_2(void)
|
||||
{
|
||||
char *hex_x = "32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7";
|
||||
char *hex_y = "bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0";
|
||||
char *hex_modp_x_div_2 = "996257158f8cc08cafcc8223351ce4ca47f185df793305f138ad22c499a63a63";
|
||||
char *hex_modp_y_div_2 = "5e1b9b517a7b3bce2cdee771b5b490a9e854c3be631523a0016f9972909cf850";
|
||||
|
||||
uint64_t x[4];
|
||||
uint64_t y[4];
|
||||
uint64_t r[4];
|
||||
|
||||
sm2_z256_from_hex(x, hex_x);
|
||||
sm2_z256_from_hex(y, hex_y);
|
||||
|
||||
sm2_z256_modp_div_by_2(r, x);
|
||||
if (sm2_z256_equ_hex(r, hex_modp_x_div_2) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
sm2_z256_modp_div_by_2(r, y);
|
||||
if (sm2_z256_equ_hex(r, hex_modp_y_div_2) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm2_z256_modp_mul(void)
|
||||
{
|
||||
char *hex_x = "32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7";
|
||||
char *hex_y = "bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0";
|
||||
char *hex_modp_mul_x_y = "edd7e745bdc4630ccfa1da1057033a525346dbf202f082f3c431349991ace76a";
|
||||
char *hex_0 = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||
|
||||
uint64_t x[4];
|
||||
uint64_t y[4];
|
||||
uint64_t r[4];
|
||||
|
||||
sm2_z256_from_hex(x, hex_x);
|
||||
sm2_z256_from_hex(y, hex_y);
|
||||
|
||||
sm2_z256_to_mont(x, x);
|
||||
sm2_z256_to_mont(y, y);
|
||||
sm2_z256_mont_mul(r, x, y);
|
||||
sm2_z256_from_mont(r, r);
|
||||
|
||||
if (sm2_z256_equ_hex(r, hex_modp_mul_x_y) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm2_z256_modp_inv(void)
|
||||
{
|
||||
char *hex_x = "32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7";
|
||||
char *hex_y = "bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0";
|
||||
char *hex_modp_inv_x = "053b878fb82e213c17e554b9a574b7bd31775222704b7fd9c7d6f8441026cd80";
|
||||
char *hex_modp_inv_y = "7adc850505c462b280f710414ab54e922551dbc97eefbc04e99cb743624c729f";
|
||||
char *hex_0 = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||
char *hex_1 = "0000000000000000000000000000000000000000000000000000000000000001";
|
||||
|
||||
uint64_t x[4];
|
||||
uint64_t y[4];
|
||||
uint64_t r[4];
|
||||
|
||||
sm2_z256_from_hex(x, hex_x);
|
||||
sm2_z256_from_hex(y, hex_y);
|
||||
|
||||
sm2_z256_to_mont(x, x);
|
||||
sm2_z256_mont_inv(r, x);
|
||||
sm2_z256_from_mont(r ,r);
|
||||
if (sm2_z256_equ_hex(r, hex_modp_inv_x) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
sm2_z256_to_mont(y, y);
|
||||
sm2_z256_mont_inv(r, y);
|
||||
sm2_z256_from_mont(r ,r);
|
||||
if (sm2_z256_equ_hex(r, hex_modp_inv_y) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const uint64_t SM2_Z256_MONT_X[4] = {
|
||||
0x61328990f418029e, 0x3e7981eddca6c050, 0xd6a1ed99ac24c3c3, 0x91167a5ee1c13b05,
|
||||
};
|
||||
|
||||
static const uint64_t SM2_Z256_MONT_Y[4] = {
|
||||
0xc1354e593c2d0ddd, 0xc1f5e5788d3295fa, 0x8d4cfb066e2a48f8, 0x63cd65d481d735bd,
|
||||
};
|
||||
|
||||
static int test_sm2_z256_point_get_affine(void)
|
||||
{
|
||||
const char *hex_x = "32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7";
|
||||
const char *hex_y = "bc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0";
|
||||
SM2_Z256_POINT P;
|
||||
uint64_t x[4];
|
||||
uint64_t y[4];
|
||||
|
||||
sm2_z256_copy(P.X, SM2_Z256_MONT_X);
|
||||
sm2_z256_copy(P.Y, SM2_Z256_MONT_Y);
|
||||
sm2_z256_copy(P.Z, SM2_Z256_MONT_ONE);
|
||||
|
||||
sm2_z256_point_get_affine(&P, x, y);
|
||||
|
||||
if (sm2_z256_equ_hex(x, hex_x) != 1 || sm2_z256_equ_hex(y, hex_y) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm2_z256_point_dbl(void)
|
||||
{
|
||||
char *hex_x_2G = "56cefd60d7c87c000d58ef57fa73ba4d9c0dfa08c08a7331495c2e1da3f2bd52";
|
||||
char *hex_y_2G = "31b7e7e6cc8189f668535ce0f8eaf1bd6de84c182f6c8e716f780d3a970a23c3";
|
||||
SM2_Z256_POINT P;
|
||||
uint64_t x[4];
|
||||
uint64_t y[4];
|
||||
|
||||
sm2_z256_copy(P.X, SM2_Z256_MONT_X);
|
||||
sm2_z256_copy(P.Y, SM2_Z256_MONT_Y);
|
||||
sm2_z256_copy(P.Z, SM2_Z256_MONT_ONE);
|
||||
|
||||
sm2_z256_point_dbl(&P, &P);
|
||||
sm2_z256_point_get_affine(&P, x, y);
|
||||
|
||||
if (sm2_z256_equ_hex(x, hex_x_2G) != 1 || sm2_z256_equ_hex(y, hex_y_2G) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
static int test_sm2_z256_point_add_affine(void)
|
||||
{
|
||||
char *hex_x_3G = "a97f7cd4b3c993b4be2daa8cdb41e24ca13f6bd945302244e26918f1d0509ebf";
|
||||
char *hex_y_3G = "530b5dd88c688ef5ccc5cec08a72150f7c400ee5cd045292aaacdd037458f6e6";
|
||||
SM2_Z256_POINT P;
|
||||
SM2_Z256_POINT Q;
|
||||
uint64_t x[4];
|
||||
uint64_t y[4];
|
||||
|
||||
sm2_z256_copy(P.X, SM2_Z256_MONT_X);
|
||||
sm2_z256_copy(P.Y, SM2_Z256_MONT_Y);
|
||||
sm2_z256_copy(P.Z, SM2_Z256_MONT_ONE);
|
||||
|
||||
sm2_z256_point_dbl(&Q, &P);
|
||||
sm2_z256_point_add_affine(&Q, &Q, (SM2_Z256_POINT_AFFINE *)&P);
|
||||
sm2_z256_point_get_affine(&Q, x, y);
|
||||
|
||||
if (sm2_z256_equ_hex(x, hex_x_3G) != 1 || sm2_z256_equ_hex(y, hex_y_3G) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm2_z256_point_add(void)
|
||||
{
|
||||
char *hex_x_5G = "c749061668652e26040e008fdd5eb77a344a417b7fce19dba575da57cc372a9e";
|
||||
char *hex_y_5G = "f2df5db2d144e9454504c622b51cf38f5006206eb579ff7da6976eff5fbe6480";
|
||||
SM2_Z256_POINT G;
|
||||
SM2_Z256_POINT P;
|
||||
SM2_Z256_POINT Q;
|
||||
SM2_Z256_POINT R;
|
||||
uint64_t x[4];
|
||||
uint64_t y[4];
|
||||
|
||||
sm2_z256_copy(G.X, SM2_Z256_MONT_X);
|
||||
sm2_z256_copy(G.Y, SM2_Z256_MONT_Y);
|
||||
sm2_z256_copy(G.Z, SM2_Z256_MONT_ONE);
|
||||
|
||||
// P = 2*G
|
||||
sm2_z256_point_dbl(&P, &G);
|
||||
|
||||
// Q = 3*G
|
||||
sm2_z256_point_add_affine(&Q, &P, (SM2_Z256_POINT_AFFINE *)&G);
|
||||
|
||||
// R = P + Q
|
||||
sm2_z256_point_add(&R, &P, &Q);
|
||||
|
||||
sm2_z256_point_get_affine(&R, x, y);
|
||||
|
||||
if (sm2_z256_equ_hex(x, hex_x_5G) != 1 || sm2_z256_equ_hex(y, hex_y_5G) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm2_z256_get_booth(void)
|
||||
{
|
||||
char *hex_a = "7a648a77d0cbe0b9ee841433be0c132aa98f6757da70a18c74999774fa587762";
|
||||
|
||||
// window_size = 7, len(booth) = (256 + 6)/7 = 7
|
||||
int booth_a[37] = {
|
||||
-30, -17, -30, -45, -48, -17, -26, -51, -11, 25, 6, 5, 39, -5, -42, 52,
|
||||
15, -45, 43, 25, -63, -62, -16, 26, 20, 8, 58, -49, 12, -4, 51, -24, -8,
|
||||
21, 18, -45, 8
|
||||
struct {
|
||||
char *k;
|
||||
char *kG;
|
||||
} tests[] = {
|
||||
// k = 0
|
||||
{"0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
"0000000000000000000000000000000000000000000000000000000000000000"},
|
||||
// k = 1
|
||||
{"0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7"
|
||||
"BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"},
|
||||
// k = 2
|
||||
{"0000000000000000000000000000000000000000000000000000000000000002",
|
||||
"56CEFD60D7C87C000D58EF57FA73BA4D9C0DFA08C08A7331495C2E1DA3F2BD52"
|
||||
"31B7E7E6CC8189F668535CE0F8EAF1BD6DE84C182F6C8E716F780D3A970A23C3"},
|
||||
// k = 3
|
||||
{"0000000000000000000000000000000000000000000000000000000000000003",
|
||||
"A97F7CD4B3C993B4BE2DAA8CDB41E24CA13F6BD945302244E26918F1D0509EBF"
|
||||
"530B5DD88C688EF5CCC5CEC08A72150F7C400EE5CD045292AAACDD037458F6E6"},
|
||||
// k = 4
|
||||
{"0000000000000000000000000000000000000000000000000000000000000004",
|
||||
"C239507105C683242A81052FF641ED69009A084AD5CC937DB21646CD34A0CED5"
|
||||
"B1BF7EC4080F3C8735F1294AC0DB19686BEE2E96AB8C71FB7A253666CB66E009"},
|
||||
// k = 5
|
||||
{"0000000000000000000000000000000000000000000000000000000000000005",
|
||||
"C749061668652E26040E008FDD5EB77A344A417B7FCE19DBA575DA57CC372A9E"
|
||||
"F2DF5DB2D144E9454504C622B51CF38F5006206EB579FF7DA6976EFF5FBE6480"},
|
||||
// k = 6
|
||||
{"0000000000000000000000000000000000000000000000000000000000000006",
|
||||
"0927AFB57D93483BBB17C93E71F22A3105FF8856A66016892C8B1A1A3C4B0D30"
|
||||
"150C6B1AB4D1FC7EAC1C0EF6EBF2664581ADF1F0855A064DD572103000088F63"},
|
||||
// k = 7
|
||||
{"0000000000000000000000000000000000000000000000000000000000000007",
|
||||
"DDF092555409C19DFDBE86A75C139906A80198337744EE78CD27E384D9FCAF15"
|
||||
"847D18FFB38E87065CD6B6E9C12D2922037937707D6A49A2223B949657E52BC1"},
|
||||
// k = G.x
|
||||
{"32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7",
|
||||
"782E1941B8A8C802543BC831E19F3548235C94A9C42AAD1EA8952CEAAECF12BA"
|
||||
"EEE0D9A6939E87F3B47A85863F873B324B9859136E2BF3235E17B3270164202D"},
|
||||
// k = G.y
|
||||
{"BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0",
|
||||
"1000165E3FFF85F1DFFFB3AA1DF9F5E62B9A86A9A2927B4FF1AC16D19FEFF330"
|
||||
"3116F22B65320DD3B7F73DCF4A4028063A9BE6EFBD1DB0915C72F1EE067C5ECF"},
|
||||
// k = n - 1 = -1
|
||||
{"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54122",
|
||||
"32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7"
|
||||
"43C8C95C0B098863A642311C9496DEAC2F56788239D5B8C0FD20CD1ADEC60F5F"},
|
||||
// k = n = 0
|
||||
{"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123",
|
||||
"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
"0000000000000000000000000000000000000000000000000000000000000000"},
|
||||
// k = n + 1 = 1
|
||||
{"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54124",
|
||||
"32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7"
|
||||
"BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"},
|
||||
// k = 2^256 - 1
|
||||
{"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
||||
"B3217D884BC175E6BA6B360EB0E6D4396EAEA725C3D66E87BFA5BEB6C0D3456B"
|
||||
"A5199445C54B56602AA60025E1907BFD26B30E867DB6C58A034263AE4A2E27C2"},
|
||||
};
|
||||
uint64_t a[4];
|
||||
int i = 0;
|
||||
|
||||
sm2_z256_from_hex(a, hex_a);
|
||||
uint64_t k[4];
|
||||
SM2_Z256_POINT P;
|
||||
uint8_t P_bytes[64];
|
||||
uint8_t kG_bytes[64];
|
||||
size_t i, len;
|
||||
|
||||
for (i = 0; i < 37; i++) {
|
||||
if (sm2_z256_get_booth(a, 7, i) != booth_a[i]) {
|
||||
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
|
||||
|
||||
sm2_z256_from_hex(k, tests[i].k);
|
||||
hex_to_bytes(tests[i].kG, strlen(tests[i].kG), kG_bytes, &len);
|
||||
|
||||
sm2_z256_point_mul_generator(&P, k);
|
||||
sm2_z256_point_to_bytes(&P, P_bytes);
|
||||
|
||||
if (memcmp(P_bytes, kG_bytes, 64) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
@@ -477,81 +106,68 @@ static int test_sm2_z256_get_booth(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm2_z256_point_mul_generator(void)
|
||||
{
|
||||
char *hex_b = "28e9fa9e9d9f5e344d5a9e4bcf6509a7f39789f515ab8f92ddbcbd414d940e93";
|
||||
char *hex_x = "528470bc74a6ebc663c06fc4cfa1b630d1e9d4a80c0a127b47f73c324c46c0ba";
|
||||
char *hex_y = "832cf9c5a15b997e60962b4cf6e2c9cee488faaec98d20599d323d4cabfc1bf4";
|
||||
|
||||
uint64_t b[4];
|
||||
SM2_Z256_POINT P;
|
||||
uint64_t x[4];
|
||||
uint64_t y[4];
|
||||
|
||||
sm2_z256_from_hex(b, hex_b);
|
||||
sm2_z256_point_mul_generator(&P, b);
|
||||
sm2_z256_point_get_affine(&P, x, y);
|
||||
|
||||
if (sm2_z256_equ_hex(x, hex_x) != 1 || sm2_z256_equ_hex(y, hex_y) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int test_sm2_z256_point_mul(void)
|
||||
{
|
||||
char *hex_b = "28e9fa9e9d9f5e344d5a9e4bcf6509a7f39789f515ab8f92ddbcbd414d940e93";
|
||||
char *hex_x = "528470bc74a6ebc663c06fc4cfa1b630d1e9d4a80c0a127b47f73c324c46c0ba";
|
||||
char *hex_y = "832cf9c5a15b997e60962b4cf6e2c9cee488faaec98d20599d323d4cabfc1bf4";
|
||||
|
||||
uint64_t b[4];
|
||||
SM2_Z256_POINT G;
|
||||
SM2_Z256_POINT P;
|
||||
uint64_t x[4];
|
||||
uint64_t y[4];
|
||||
|
||||
sm2_z256_from_hex(b, hex_b);
|
||||
|
||||
sm2_z256_copy(G.X, SM2_Z256_MONT_X);
|
||||
sm2_z256_copy(G.Y, SM2_Z256_MONT_Y);
|
||||
sm2_z256_copy(G.Z, SM2_Z256_MONT_ONE);
|
||||
|
||||
sm2_z256_point_mul(&P, &G, b);
|
||||
sm2_z256_point_get_affine(&P, x, y);
|
||||
|
||||
if (sm2_z256_equ_hex(x, hex_x) != 1 || sm2_z256_equ_hex(y, hex_y) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (test_sm2_z256_add() != 1) { error_print(); return -1; }
|
||||
if (test_sm2_z256_sub() != 1) { error_print(); return -1; }
|
||||
if (test_sm2_z256_mul() != 1) { error_print(); return -1; }
|
||||
if (test_sm2_z256_cmp() != 1) { error_print(); return -1; }
|
||||
if (test_sm2_z256_modp_add() != 1) { error_print(); return -1; }
|
||||
if (test_sm2_z256_modp_sub() != 1) { error_print(); return -1; }
|
||||
if (test_sm2_z256_modp_mul() != 1) { error_print(); return -1; }
|
||||
if (test_sm2_z256_modp_inv() != 1) { error_print(); return -1; }
|
||||
if (test_sm2_z256_modp_div_by_2() != 1) { error_print(); return -1; }
|
||||
if (test_sm2_z256_get_booth() != 1) { error_print(); return -1; }
|
||||
if (test_sm2_z256_point_get_affine() != 1) { error_print(); return -1; }
|
||||
if (test_sm2_z256_point_dbl() != 1) { error_print(); return -1; }
|
||||
if (test_sm2_z256_point_add_affine() != 1) { error_print(); return -1; }
|
||||
if (test_sm2_z256_point_add() != 1) { error_print(); return -1; }
|
||||
if (test_sm2_z256_point_mul_generator() != 1) { error_print(); return -1; }
|
||||
if (test_sm2_z256_point_mul() != 1) { error_print(); return -1; }
|
||||
/*
|
||||
SM2_POINT P;
|
||||
uint8_t k[32] = {0};
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
k[31] = i;
|
||||
|
||||
format_bytes(stderr, 0, 0, "k", k, 32);
|
||||
|
||||
sm2_point_mul_generator(&P, k);
|
||||
sm2_point_print(stdout, 0, 4, "kG", &P);
|
||||
}
|
||||
|
||||
size_t len;
|
||||
|
||||
char *xG = "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7";
|
||||
char *yG = "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0";
|
||||
|
||||
hex_to_bytes(xG, strlen(xG), k, &len);
|
||||
|
||||
sm2_point_mul_generator(&P, k);
|
||||
format_bytes(stderr, 0, 0, "k", k, 32);
|
||||
sm2_point_print(stdout, 0, 4, "kG", &P);
|
||||
|
||||
hex_to_bytes(yG, strlen(yG), k, &len);
|
||||
sm2_point_mul_generator(&P, k);
|
||||
format_bytes(stderr, 0, 0, "k", k, 32);
|
||||
sm2_point_print(stdout, 0, 4, "kG", &P);
|
||||
|
||||
char *n = "fffffffeffffffffffffffffffffffff7203df6b21c6052b53bbf40939d54123";
|
||||
char *n_minus_one = "fffffffeffffffffffffffffffffffff7203df6b21c6052b53bbf40939d54122";
|
||||
char *n_plus_one = "fffffffeffffffffffffffffffffffff7203df6b21c6052b53bbf40939d54124";
|
||||
char *max256 = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
|
||||
|
||||
hex_to_bytes(n_minus_one, strlen(n_minus_one), k, &len);
|
||||
sm2_point_mul_generator(&P, k);
|
||||
format_bytes(stderr, 0, 0, "n-1", k, 32);
|
||||
sm2_point_print(stdout, 0, 4, "kG", &P);
|
||||
|
||||
hex_to_bytes(n, strlen(n), k, &len);
|
||||
sm2_point_mul_generator(&P, k);
|
||||
format_bytes(stderr, 0, 0, "n", k, 32);
|
||||
sm2_point_print(stdout, 0, 4, "kG", &P);
|
||||
|
||||
hex_to_bytes(n_plus_one, strlen(n_plus_one), k, &len);
|
||||
sm2_point_mul_generator(&P, k);
|
||||
format_bytes(stderr, 0, 0, "n+1", k, 32);
|
||||
sm2_point_print(stdout, 0, 4, "kG", &P);
|
||||
|
||||
hex_to_bytes(max256, strlen(max256), k, &len);
|
||||
sm2_point_mul_generator(&P, k);
|
||||
format_bytes(stderr, 0, 0, "n+1", k, 32);
|
||||
sm2_point_print(stdout, 0, 4, "kG", &P);
|
||||
|
||||
*/
|
||||
if (test_sm2_z256_point_mul_generator() != 1) goto err;
|
||||
printf("%s all tests passed\n", __FILE__);
|
||||
return 0;
|
||||
err:
|
||||
error_print();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user