mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-06-19 19:33:38 +08:00
Remove SM2 extensions
This commit is contained in:
@@ -389,19 +389,6 @@ if (ENABLE_SM4_XTS)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
if (ENABLE_SM2_EXTS)
|
|
||||||
message(STATUS "ENABLE_SM4_AESNI_AVX")
|
|
||||||
list(APPEND src
|
|
||||||
src/sm2_key_share.c
|
|
||||||
src/sm2_recover.c
|
|
||||||
src/sm2_blind.c
|
|
||||||
src/sm2_ring.c
|
|
||||||
src/sm2_elgamal.c
|
|
||||||
src/sm2_commit.c)
|
|
||||||
list(APPEND tests sm2_key_share sm2_blind sm2_ring sm2_elgamal sm2_commit)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
if (ENABLE_SM9)
|
if (ENABLE_SM9)
|
||||||
message(STATUS "ENABLE_SM9 is ON")
|
message(STATUS "ENABLE_SM9 is ON")
|
||||||
add_definitions(-DENABLE_SM9)
|
add_definitions(-DENABLE_SM9)
|
||||||
@@ -777,7 +764,7 @@ endif()
|
|||||||
#
|
#
|
||||||
set(CPACK_PACKAGE_NAME "GmSSL")
|
set(CPACK_PACKAGE_NAME "GmSSL")
|
||||||
set(CPACK_PACKAGE_VENDOR "GmSSL develop team")
|
set(CPACK_PACKAGE_VENDOR "GmSSL develop team")
|
||||||
set(CPACK_PACKAGE_VERSION "3.2.0-dev.1043")
|
set(CPACK_PACKAGE_VERSION "3.2.0-dev.1044")
|
||||||
set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md)
|
set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md)
|
||||||
set(CPACK_NSIS_MODIFY_PATH ON)
|
set(CPACK_NSIS_MODIFY_PATH ON)
|
||||||
include(CPack)
|
include(CPack)
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ extern "C" {
|
|||||||
|
|
||||||
// Also update CPACK_PACKAGE_VERSION in CMakeLists.txt
|
// Also update CPACK_PACKAGE_VERSION in CMakeLists.txt
|
||||||
#define GMSSL_VERSION_NUM 30200
|
#define GMSSL_VERSION_NUM 30200
|
||||||
#define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1043"
|
#define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1044"
|
||||||
|
|
||||||
int gmssl_version_num(void);
|
int gmssl_version_num(void);
|
||||||
const char *gmssl_version_str(void);
|
const char *gmssl_version_str(void);
|
||||||
|
|||||||
230
src/aes_modes.c
230
src/aes_modes.c
@@ -8,7 +8,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -104,7 +103,7 @@ int aes_cbc_padding_decrypt(const AES_KEY *key, const uint8_t iv[16],
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ctr_incr(uint8_t a[16])
|
static void ctr128_incr(uint8_t a[16])
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 15; i >= 0; i--) {
|
for (i = 15; i >= 0; i--) {
|
||||||
@@ -122,13 +121,125 @@ void aes_ctr_encrypt(const AES_KEY *key, uint8_t ctr[16], const uint8_t *in, siz
|
|||||||
len = inlen < 16 ? inlen : 16;
|
len = inlen < 16 ? inlen : 16;
|
||||||
aes_encrypt(key, ctr, block);
|
aes_encrypt(key, ctr, block);
|
||||||
gmssl_memxor(out, in, block, len);
|
gmssl_memxor(out, in, block, len);
|
||||||
ctr_incr(ctr);
|
ctr128_incr(ctr);
|
||||||
in += len;
|
in += len;
|
||||||
out += len;
|
out += len;
|
||||||
inlen -= len;
|
inlen -= len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ctr32_incr(uint8_t a[16])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 15; i >= 12; i--) {
|
||||||
|
a[i]++;
|
||||||
|
if (a[i]) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void aes_ctr32_encrypt(const AES_KEY *key, uint8_t ctr[16], const uint8_t *in, size_t inlen, uint8_t *out)
|
||||||
|
{
|
||||||
|
uint8_t block[16];
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
while (inlen) {
|
||||||
|
len = inlen < 16 ? inlen : 16;
|
||||||
|
aes_encrypt(key, ctr, block);
|
||||||
|
gmssl_memxor(out, in, block, len);
|
||||||
|
ctr32_incr(ctr);
|
||||||
|
in += len;
|
||||||
|
out += len;
|
||||||
|
inlen -= len;
|
||||||
|
}
|
||||||
|
gmssl_secure_clear(block, sizeof(block));
|
||||||
|
}
|
||||||
|
|
||||||
|
int aes_gcm_encrypt(const AES_KEY *key, const uint8_t *iv, size_t ivlen,
|
||||||
|
const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen,
|
||||||
|
uint8_t *out, size_t taglen, uint8_t *tag)
|
||||||
|
{
|
||||||
|
const uint8_t *pin = in;
|
||||||
|
uint8_t *pout = out;
|
||||||
|
size_t left = inlen;
|
||||||
|
uint8_t H[16] = {0};
|
||||||
|
uint8_t Y[16];
|
||||||
|
uint8_t T[16];
|
||||||
|
|
||||||
|
if (taglen > AES_GCM_MAX_TAG_SIZE) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
aes_encrypt(key, H, H);
|
||||||
|
|
||||||
|
if (ivlen == 12) {
|
||||||
|
memcpy(Y, iv, 12);
|
||||||
|
Y[12] = Y[13] = Y[14] = 0;
|
||||||
|
Y[15] = 1;
|
||||||
|
} else {
|
||||||
|
ghash(H, NULL, 0, iv, ivlen, Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
aes_encrypt(key, Y, T);
|
||||||
|
|
||||||
|
ctr32_incr(Y);
|
||||||
|
aes_ctr32_encrypt(key, Y, in, inlen, out);
|
||||||
|
|
||||||
|
ghash(H, aad, aadlen, out, inlen, H);
|
||||||
|
gmssl_memxor(tag, T, H, taglen);
|
||||||
|
|
||||||
|
gmssl_secure_clear(H, sizeof(H));
|
||||||
|
gmssl_secure_clear(Y, sizeof(Y));
|
||||||
|
gmssl_secure_clear(T, sizeof(T));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int aes_gcm_decrypt(const AES_KEY *key, const uint8_t *iv, size_t ivlen,
|
||||||
|
const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen,
|
||||||
|
const uint8_t *tag, size_t taglen, uint8_t *out)
|
||||||
|
{
|
||||||
|
const uint8_t *pin = in;
|
||||||
|
uint8_t *pout = out;
|
||||||
|
size_t left = inlen;
|
||||||
|
uint8_t H[16] = {0};
|
||||||
|
uint8_t Y[16];
|
||||||
|
uint8_t T[16];
|
||||||
|
|
||||||
|
if (taglen > AES_GCM_MAX_TAG_SIZE) {
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
aes_encrypt(key, H, H);
|
||||||
|
|
||||||
|
if (ivlen == 12) {
|
||||||
|
memcpy(Y, iv, 12);
|
||||||
|
Y[12] = Y[13] = Y[14] = 0;
|
||||||
|
Y[15] = 1;
|
||||||
|
} else {
|
||||||
|
ghash(H, NULL, 0, iv, ivlen, Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
ghash(H, aad, aadlen, in, inlen, H);
|
||||||
|
aes_encrypt(key, Y, T);
|
||||||
|
gmssl_memxor(T, T, H, taglen);
|
||||||
|
if (gmssl_secure_memcmp(T, tag, taglen) != 0) {
|
||||||
|
gmssl_secure_clear(H, sizeof(H));
|
||||||
|
gmssl_secure_clear(Y, sizeof(Y));
|
||||||
|
gmssl_secure_clear(T, sizeof(T));
|
||||||
|
error_print();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctr32_incr(Y);
|
||||||
|
aes_ctr32_encrypt(key, Y, in, inlen, out);
|
||||||
|
|
||||||
|
gmssl_secure_clear(H, sizeof(H));
|
||||||
|
gmssl_secure_clear(Y, sizeof(Y));
|
||||||
|
gmssl_secure_clear(T, sizeof(T));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_AES_CCM
|
#ifdef ENABLE_AES_CCM
|
||||||
static void length_to_bytes(size_t len, size_t nbytes, uint8_t *out)
|
static void length_to_bytes(size_t len, size_t nbytes, uint8_t *out)
|
||||||
{
|
{
|
||||||
@@ -390,116 +501,3 @@ int aes_ccm_decrypt(const AES_KEY *key, const uint8_t *iv, size_t ivlen,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void ctr32_incr(uint8_t a[16])
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 15; i >= 12; i--) {
|
|
||||||
a[i]++;
|
|
||||||
if (a[i]) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void aes_ctr32_encrypt(const AES_KEY *key, uint8_t ctr[16], const uint8_t *in, size_t inlen, uint8_t *out)
|
|
||||||
{
|
|
||||||
uint8_t block[16];
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
while (inlen) {
|
|
||||||
len = inlen < 16 ? inlen : 16;
|
|
||||||
aes_encrypt(key, ctr, block);
|
|
||||||
gmssl_memxor(out, in, block, len);
|
|
||||||
ctr32_incr(ctr);
|
|
||||||
in += len;
|
|
||||||
out += len;
|
|
||||||
inlen -= len;
|
|
||||||
}
|
|
||||||
gmssl_secure_clear(block, sizeof(block));
|
|
||||||
}
|
|
||||||
|
|
||||||
int aes_gcm_encrypt(const AES_KEY *key, const uint8_t *iv, size_t ivlen,
|
|
||||||
const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen,
|
|
||||||
uint8_t *out, size_t taglen, uint8_t *tag)
|
|
||||||
{
|
|
||||||
const uint8_t *pin = in;
|
|
||||||
uint8_t *pout = out;
|
|
||||||
size_t left = inlen;
|
|
||||||
uint8_t H[16] = {0};
|
|
||||||
uint8_t Y[16];
|
|
||||||
uint8_t T[16];
|
|
||||||
|
|
||||||
if (taglen > AES_GCM_MAX_TAG_SIZE) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
aes_encrypt(key, H, H);
|
|
||||||
|
|
||||||
if (ivlen == 12) {
|
|
||||||
memcpy(Y, iv, 12);
|
|
||||||
Y[12] = Y[13] = Y[14] = 0;
|
|
||||||
Y[15] = 1;
|
|
||||||
} else {
|
|
||||||
ghash(H, NULL, 0, iv, ivlen, Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
aes_encrypt(key, Y, T);
|
|
||||||
|
|
||||||
ctr32_incr(Y);
|
|
||||||
aes_ctr32_encrypt(key, Y, in, inlen, out);
|
|
||||||
|
|
||||||
ghash(H, aad, aadlen, out, inlen, H);
|
|
||||||
gmssl_memxor(tag, T, H, taglen);
|
|
||||||
|
|
||||||
gmssl_secure_clear(H, sizeof(H));
|
|
||||||
gmssl_secure_clear(Y, sizeof(Y));
|
|
||||||
gmssl_secure_clear(T, sizeof(T));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int aes_gcm_decrypt(const AES_KEY *key, const uint8_t *iv, size_t ivlen,
|
|
||||||
const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen,
|
|
||||||
const uint8_t *tag, size_t taglen, uint8_t *out)
|
|
||||||
{
|
|
||||||
const uint8_t *pin = in;
|
|
||||||
uint8_t *pout = out;
|
|
||||||
size_t left = inlen;
|
|
||||||
uint8_t H[16] = {0};
|
|
||||||
uint8_t Y[16];
|
|
||||||
uint8_t T[16];
|
|
||||||
|
|
||||||
if (taglen > AES_GCM_MAX_TAG_SIZE) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
aes_encrypt(key, H, H);
|
|
||||||
|
|
||||||
if (ivlen == 12) {
|
|
||||||
memcpy(Y, iv, 12);
|
|
||||||
Y[12] = Y[13] = Y[14] = 0;
|
|
||||||
Y[15] = 1;
|
|
||||||
} else {
|
|
||||||
ghash(H, NULL, 0, iv, ivlen, Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
ghash(H, aad, aadlen, in, inlen, H);
|
|
||||||
aes_encrypt(key, Y, T);
|
|
||||||
gmssl_memxor(T, T, H, taglen);
|
|
||||||
if (gmssl_secure_memcmp(T, tag, taglen) != 0) {
|
|
||||||
gmssl_secure_clear(H, sizeof(H));
|
|
||||||
gmssl_secure_clear(Y, sizeof(Y));
|
|
||||||
gmssl_secure_clear(T, sizeof(T));
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctr32_incr(Y);
|
|
||||||
aes_ctr32_encrypt(key, Y, in, inlen, out);
|
|
||||||
|
|
||||||
gmssl_secure_clear(H, sizeof(H));
|
|
||||||
gmssl_secure_clear(Y, sizeof(Y));
|
|
||||||
gmssl_secure_clear(T, sizeof(T));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|||||||
174
src/sm2_blind.c
174
src/sm2_blind.c
@@ -1,174 +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 <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <gmssl/sm2.h>
|
|
||||||
#include <gmssl/mem.h>
|
|
||||||
#include <gmssl/asn1.h>
|
|
||||||
#include <gmssl/error.h>
|
|
||||||
#include <gmssl/sm2_blind.h>
|
|
||||||
|
|
||||||
|
|
||||||
extern SM2_BN SM2_N;
|
|
||||||
extern SM2_BN SM2_ONE;
|
|
||||||
|
|
||||||
int sm2_blind_sign_commit(SM2_Fn k, uint8_t *commit, size_t *commitlen)
|
|
||||||
{
|
|
||||||
SM2_POINT K;
|
|
||||||
uint8_t k_bytes[32];
|
|
||||||
|
|
||||||
sm2_fn_rand(k); // FIXME: check return
|
|
||||||
sm2_bn_to_bytes(k, k_bytes);
|
|
||||||
|
|
||||||
// commitment = k * G
|
|
||||||
sm2_point_mul_generator(&K, k_bytes);
|
|
||||||
sm2_point_to_compressed_octets(&K, commit);
|
|
||||||
*commitlen = 33;
|
|
||||||
gmssl_secure_clear(k_bytes, sizeof(k_bytes));
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_blind_sign_init(SM2_BLIND_SIGN_CTX *ctx, const SM2_KEY *public_key, const char *id, size_t idlen)
|
|
||||||
{
|
|
||||||
ctx->public_key = *public_key;
|
|
||||||
sm3_init(&ctx->sm3_ctx);
|
|
||||||
if (id) {
|
|
||||||
uint8_t z[SM3_DIGEST_SIZE];
|
|
||||||
if (idlen <= 0 || idlen > SM2_MAX_ID_LENGTH) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
sm2_compute_z(z, &public_key->public_key, id, idlen);
|
|
||||||
sm3_update(&ctx->sm3_ctx, z, sizeof(z));
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_blind_sign_update(SM2_BLIND_SIGN_CTX *ctx, const uint8_t *data, size_t datalen)
|
|
||||||
{
|
|
||||||
if (!ctx) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (data && datalen > 0) {
|
|
||||||
sm3_update(&ctx->sm3_ctx, data, datalen);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_blind_sign_finish(SM2_BLIND_SIGN_CTX *ctx,
|
|
||||||
const uint8_t *commit, size_t commitlen,
|
|
||||||
uint8_t blinded_sig_r[32])
|
|
||||||
{
|
|
||||||
int ret = -1;
|
|
||||||
SM2_Fn a;
|
|
||||||
SM2_Fn b;
|
|
||||||
SM2_POINT K;
|
|
||||||
SM2_Fn e;
|
|
||||||
SM2_Fn r;
|
|
||||||
uint8_t dgst[32];
|
|
||||||
|
|
||||||
sm3_finish(&ctx->sm3_ctx, dgst);
|
|
||||||
sm2_bn_from_bytes(e, dgst);
|
|
||||||
if (sm2_bn_cmp(e, SM2_N) >= 0) {
|
|
||||||
sm2_bn_sub(e, e, SM2_N);
|
|
||||||
}
|
|
||||||
|
|
||||||
//FIXME: return value of sm2_fn_rand()
|
|
||||||
sm2_fn_rand(a);
|
|
||||||
sm2_bn_to_bytes(a, ctx->blind_factor_a);
|
|
||||||
sm2_fn_rand(b);
|
|
||||||
sm2_bn_to_bytes(b, ctx->blind_factor_b);
|
|
||||||
|
|
||||||
if (sm2_point_from_octets(&K, commit, commitlen) != 1) {
|
|
||||||
error_print();
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
// K'(x1, y1) = a * K + b * G
|
|
||||||
if (sm2_point_mul_sum(&K, ctx->blind_factor_a, &K, ctx->blind_factor_b) != 1) {
|
|
||||||
error_print();
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
sm2_bn_from_bytes(r, K.x);
|
|
||||||
if (sm2_bn_cmp(r, SM2_N) >= 0) {
|
|
||||||
sm2_bn_sub(r, r, SM2_N);
|
|
||||||
}
|
|
||||||
|
|
||||||
// r = x1 + e (mod n)
|
|
||||||
sm2_fn_add(r, r, e);
|
|
||||||
sm2_bn_to_bytes(r, ctx->sig_r);
|
|
||||||
|
|
||||||
// r' = a^-1 * (r + b)
|
|
||||||
sm2_fn_add(r, r, b);
|
|
||||||
sm2_fn_inv(a, a);
|
|
||||||
sm2_fn_mul(r, r, a);
|
|
||||||
|
|
||||||
sm2_bn_to_bytes(r, blinded_sig_r);
|
|
||||||
ret = 1;
|
|
||||||
|
|
||||||
end:
|
|
||||||
gmssl_secure_clear(a, sizeof(a));
|
|
||||||
gmssl_secure_clear(b, sizeof(b));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_blind_sign(const SM2_KEY *key, const SM2_Fn k, const uint8_t blinded_r[32], uint8_t blinded_s[32])
|
|
||||||
{
|
|
||||||
SM2_Fn x;
|
|
||||||
SM2_Fn r;
|
|
||||||
SM2_Fn s;
|
|
||||||
|
|
||||||
sm2_bn_from_bytes(x, key->private_key);
|
|
||||||
sm2_bn_from_bytes(r, blinded_r);
|
|
||||||
|
|
||||||
// s = (1 + x)^-1 * (k - r * x) (mod n)
|
|
||||||
sm2_fn_mul(r, r, x);
|
|
||||||
sm2_fn_sub(s, k, r);
|
|
||||||
sm2_fn_add(x, x, SM2_ONE);
|
|
||||||
sm2_fn_inv(x, x);
|
|
||||||
sm2_fn_mul(s, s, x);
|
|
||||||
sm2_bn_to_bytes(s, blinded_s);
|
|
||||||
|
|
||||||
gmssl_secure_clear(x, sizeof(x));
|
|
||||||
gmssl_secure_clear(r, sizeof(r));
|
|
||||||
gmssl_secure_clear(s, sizeof(s));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_blind_sign_unblind(SM2_BLIND_SIGN_CTX *ctx, const uint8_t blinded_sig_s[32], uint8_t *sig, size_t *siglen)
|
|
||||||
{
|
|
||||||
SM2_Fn a;
|
|
||||||
SM2_Fn b;
|
|
||||||
SM2_Fn s;
|
|
||||||
SM2_SIGNATURE signature;
|
|
||||||
|
|
||||||
sm2_bn_from_bytes(a, ctx->blind_factor_a);
|
|
||||||
sm2_bn_from_bytes(b, ctx->blind_factor_b);
|
|
||||||
sm2_bn_from_bytes(s, blinded_sig_s);
|
|
||||||
|
|
||||||
// s = a * s' + b
|
|
||||||
sm2_fn_mul(s, s, a);
|
|
||||||
sm2_fn_add(s, s, b);
|
|
||||||
|
|
||||||
memcpy(signature.r, ctx->sig_r, 32);
|
|
||||||
sm2_bn_to_bytes(s, signature.s);
|
|
||||||
|
|
||||||
|
|
||||||
*siglen = 0;
|
|
||||||
sm2_signature_to_der(&signature, &sig, siglen);
|
|
||||||
|
|
||||||
gmssl_secure_clear(a, sizeof(a));
|
|
||||||
gmssl_secure_clear(b, sizeof(b));
|
|
||||||
gmssl_secure_clear(ctx, sizeof(*ctx));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
172
src/sm2_commit.c
172
src/sm2_commit.c
@@ -1,172 +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 <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <gmssl/sm2.h>
|
|
||||||
#include <gmssl/sm3.h>
|
|
||||||
#include <gmssl/mem.h>
|
|
||||||
#include <gmssl/asn1.h>
|
|
||||||
#include <gmssl/rand.h>
|
|
||||||
#include <gmssl/error.h>
|
|
||||||
#include <gmssl/sm2_commit.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define SM2_COMMIT_SEED "GmSSL SM2 Pederson Commitment Generator H"
|
|
||||||
|
|
||||||
|
|
||||||
// C = rG + xH
|
|
||||||
int sm2_commit_generate(const uint8_t x[32], uint8_t r[32], uint8_t commit[65], size_t *commitlen)
|
|
||||||
{
|
|
||||||
SM2_POINT H;
|
|
||||||
SM2_POINT C;
|
|
||||||
SM2_BN r_;
|
|
||||||
|
|
||||||
if (sm2_point_from_hash(&H, (uint8_t *)SM2_COMMIT_SEED, sizeof(SM2_COMMIT_SEED)-1) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
sm2_fn_rand(r_);
|
|
||||||
} while (sm2_bn_is_zero(r_));
|
|
||||||
|
|
||||||
sm2_bn_to_bytes(r_, r);
|
|
||||||
gmssl_secure_clear(r_, sizeof(r_));
|
|
||||||
|
|
||||||
// C = xH + rG
|
|
||||||
sm2_point_mul_sum(&C, x, &H, r);
|
|
||||||
|
|
||||||
sm2_point_to_compressed_octets(&C, commit);
|
|
||||||
*commitlen = 33;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_commit_open(const uint8_t x[32], const uint8_t r[32], const uint8_t *commit, size_t commitlen)
|
|
||||||
{
|
|
||||||
SM2_POINT H;
|
|
||||||
SM2_POINT C;
|
|
||||||
SM2_POINT C_;
|
|
||||||
|
|
||||||
if (sm2_point_from_octets(&C, commit, commitlen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sm2_point_from_hash(&H, (uint8_t *)SM2_COMMIT_SEED, sizeof(SM2_COMMIT_SEED)-1) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// C' = xH + rG
|
|
||||||
if (sm2_point_mul_sum(&C_, x, &H, r) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (memcmp(&C, &C_, sizeof(SM2_POINT)) != 0) {
|
|
||||||
error_print();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// C = r*G + x1*H1 + x2*H2 + ...
|
|
||||||
int sm2_commit_vector_generate(const sm2_bn_t *x, size_t count, uint8_t r[32], uint8_t commit[65], size_t *commitlen)
|
|
||||||
{
|
|
||||||
SM2_POINT H;
|
|
||||||
SM2_POINT C;
|
|
||||||
SM2_Fn r_;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (count < 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sm2_point_from_hash(&H, (uint8_t *)SM2_COMMIT_SEED, sizeof(SM2_COMMIT_SEED)-1) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
sm2_fn_rand(r_);
|
|
||||||
} while (sm2_bn_is_zero(r_));
|
|
||||||
|
|
||||||
sm2_bn_to_bytes(r_, r);
|
|
||||||
gmssl_secure_clear(r_, sizeof(r_));
|
|
||||||
|
|
||||||
if (sm2_point_mul_sum(&C, x[0], &H, r) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 1; i < count; i++) {
|
|
||||||
SM2_POINT xH;
|
|
||||||
|
|
||||||
if (sm2_point_from_hash(&H, (uint8_t *)&H, sizeof(H)) != 1
|
|
||||||
|| sm2_point_mul(&xH, x[i], &H) != 1
|
|
||||||
|| sm2_point_add(&C, &C, &xH) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sm2_point_to_compressed_octets(&C, commit);
|
|
||||||
*commitlen = 33;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_commit_vector_open(const sm2_bn_t *x, size_t count, const uint8_t r[32], const uint8_t *commit, size_t commitlen)
|
|
||||||
{
|
|
||||||
SM2_POINT H;
|
|
||||||
SM2_POINT C;
|
|
||||||
SM2_POINT C_;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (count < 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sm2_point_from_octets(&C, commit, commitlen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sm2_point_from_hash(&H, (uint8_t *)SM2_COMMIT_SEED, sizeof(SM2_COMMIT_SEED)-1) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sm2_point_mul_sum(&C_, x[0], &H, r) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 1; i< count; i++) {
|
|
||||||
SM2_POINT xH;
|
|
||||||
|
|
||||||
if (sm2_point_from_hash(&H, (uint8_t *)&H, sizeof(H)) != 1
|
|
||||||
|| sm2_point_mul(&xH, x[i], &H) != 1
|
|
||||||
|| sm2_point_add(&C_, &C_, &xH) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (memcmp(&C, &C_, sizeof(SM2_POINT)) != 0) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
@@ -1,412 +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 <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <gmssl/mem.h>
|
|
||||||
#include <gmssl/sm2_elgamal.h>
|
|
||||||
#include <gmssl/asn1.h>
|
|
||||||
#include <gmssl/error.h>
|
|
||||||
|
|
||||||
|
|
||||||
extern const SM2_JACOBIAN_POINT *SM2_G;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// generate baby-step table
|
|
||||||
int sm2_elgamal_decrypt_pre_compute(SM2_PRE_COMPUTE table[1<<16])
|
|
||||||
{
|
|
||||||
SM2_JACOBIAN_POINT P;
|
|
||||||
SM2_BN x;
|
|
||||||
uint32_t i, j;
|
|
||||||
|
|
||||||
memset(table, 0, sizeof(SM2_PRE_COMPUTE) * (1<<16));
|
|
||||||
|
|
||||||
sm2_jacobian_point_set_infinity(&P);
|
|
||||||
for (i = 0; i < (1<<16); i++) {
|
|
||||||
sm2_jacobian_point_add(&P, &P, SM2_G);
|
|
||||||
sm2_jacobian_point_get_xy(&P, x, NULL);
|
|
||||||
sm2_bn_to_bytes(x, table[i].x_coordinate);
|
|
||||||
|
|
||||||
j = ((uint16_t)table[i].x_coordinate[30] << 8) | table[i].x_coordinate[31];
|
|
||||||
assert(table[j].offset_count <= SM2_PRE_COMPUTE_MAX_OFFSETS);
|
|
||||||
|
|
||||||
table[j].offset[ table[j].offset_count ] = (uint16_t)i;
|
|
||||||
(table[j].offset_count)++;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sm2_pre_compute_get_offset(const SM2_PRE_COMPUTE table[1<<16], const uint8_t x[32], uint16_t *offset)
|
|
||||||
{
|
|
||||||
uint32_t i = ((uint16_t)x[30] << 8) | x[31];
|
|
||||||
uint16_t j;
|
|
||||||
uint8_t w;
|
|
||||||
|
|
||||||
for (w = 0; w < table[i].offset_count; w++) {
|
|
||||||
j = table[i].offset[w];
|
|
||||||
if (memcmp(x, table[j].x_coordinate, 32) == 0) {
|
|
||||||
*offset = j;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// run gaint-step
|
|
||||||
int sm2_elgamal_solve_ecdlp(const SM2_PRE_COMPUTE table[1<<16], const SM2_POINT *point, uint32_t *private)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
SM2_JACOBIAN_POINT P;
|
|
||||||
SM2_JACOBIAN_POINT Q;
|
|
||||||
SM2_BN k;
|
|
||||||
SM2_BN x;
|
|
||||||
uint8_t x_bytes[32];
|
|
||||||
uint8_t Q_bytes[64];
|
|
||||||
uint32_t i;
|
|
||||||
uint16_t j;
|
|
||||||
|
|
||||||
sm2_jacobian_point_from_bytes(&P, (uint8_t *)point);
|
|
||||||
|
|
||||||
// Q = -[2^16]G
|
|
||||||
sm2_bn_set_word(k, 65536);
|
|
||||||
sm2_jacobian_point_mul_generator(&Q, k);
|
|
||||||
sm2_jacobian_point_neg(&Q, &Q);
|
|
||||||
|
|
||||||
// Q to Affine
|
|
||||||
sm2_jacobian_point_to_bytes(&Q, Q_bytes);
|
|
||||||
sm2_jacobian_point_from_bytes(&Q, Q_bytes);
|
|
||||||
|
|
||||||
for (i = 0; i < (1<<16); i++) {
|
|
||||||
// P - i*(kG) == O ==> d = i*k
|
|
||||||
if (sm2_jacobian_point_is_at_infinity(&P)) {
|
|
||||||
*private = (i << 16);
|
|
||||||
ret = 1;
|
|
||||||
goto ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
sm2_jacobian_point_get_xy(&P, x, NULL);
|
|
||||||
sm2_bn_to_bytes(x, x_bytes);
|
|
||||||
if (sm2_pre_compute_get_offset(table, x_bytes, &j) == 1) {
|
|
||||||
// P - i*(kG) == j*G ==> d = j + i*k
|
|
||||||
*private = (i<<16) + j + 1; // table[0] is 1*G, so j + 1
|
|
||||||
ret = 1;
|
|
||||||
goto ok;
|
|
||||||
}
|
|
||||||
sm2_jacobian_point_add(&P, &P, &Q);
|
|
||||||
}
|
|
||||||
printf("gaint steps failed\n");
|
|
||||||
|
|
||||||
ok:
|
|
||||||
i = j = 0;
|
|
||||||
gmssl_secure_clear(x, sizeof(x));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_elgamal_do_encrypt(const SM2_KEY *pub_key, uint32_t in, SM2_ELGAMAL_CIPHERTEXT *out)
|
|
||||||
{
|
|
||||||
int ret = -1;
|
|
||||||
SM2_Fn k;
|
|
||||||
SM2_Fn m;
|
|
||||||
uint8_t k_bytes[32];
|
|
||||||
uint8_t m_bytes[32];
|
|
||||||
|
|
||||||
if (!pub_key || !out) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (sm2_fn_rand(k) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} while (sm2_bn_is_zero(k));
|
|
||||||
sm2_bn_to_bytes(k, k_bytes);
|
|
||||||
|
|
||||||
// C1 = k * G
|
|
||||||
if (sm2_point_mul_generator(&out->C1, k_bytes) != 1) {
|
|
||||||
error_print();
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
// C2 = k * P + m * G
|
|
||||||
sm2_bn_set_word(m, in);
|
|
||||||
sm2_bn_to_bytes(m, m_bytes);
|
|
||||||
if (sm2_point_mul_sum(&out->C2, k_bytes, &pub_key->public_key, m_bytes) != 1) {
|
|
||||||
error_print();
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
ret = 1;
|
|
||||||
|
|
||||||
end:
|
|
||||||
gmssl_secure_clear(k, sizeof(k));
|
|
||||||
gmssl_secure_clear(m, sizeof(m));
|
|
||||||
gmssl_secure_clear(k_bytes, sizeof(k_bytes));
|
|
||||||
gmssl_secure_clear(m_bytes, sizeof(m_bytes));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// M = m*G = -x*C1 + C2
|
|
||||||
int sm2_elgamal_do_decrypt(const SM2_KEY *key, const SM2_ELGAMAL_CIPHERTEXT *in, uint32_t *out)
|
|
||||||
{
|
|
||||||
static SM2_PRE_COMPUTE *table = NULL;
|
|
||||||
SM2_POINT M;
|
|
||||||
|
|
||||||
if (!key || !in || !out) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sm2_point_mul(&M, key->private_key, &in->C1);
|
|
||||||
sm2_point_sub(&M, &in->C2, &M);
|
|
||||||
|
|
||||||
if (!table) {
|
|
||||||
if (!(table = malloc(sizeof(SM2_PRE_COMPUTE) * (1<<16)))) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
sm2_elgamal_decrypt_pre_compute(table);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sm2_elgamal_solve_ecdlp(table, &M, out) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// (A1, A2) = (k1*G, m1*G + k1*P)
|
|
||||||
// (B1, B2) = (k2*G, m2*G + k2*P)
|
|
||||||
// (R1, R2) = (A1 + B1 + k*G, A2 + B2 + k*P)
|
|
||||||
int sm2_elgamal_ciphertext_add(SM2_ELGAMAL_CIPHERTEXT *r,
|
|
||||||
const SM2_ELGAMAL_CIPHERTEXT *a,
|
|
||||||
const SM2_ELGAMAL_CIPHERTEXT *b,
|
|
||||||
const SM2_KEY *pub_key)
|
|
||||||
{
|
|
||||||
SM2_Fn k;
|
|
||||||
uint8_t k_bytes[32];
|
|
||||||
SM2_POINT R;
|
|
||||||
|
|
||||||
if (!r || !a || !b || !pub_key) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (sm2_fn_rand(k) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} while (sm2_bn_is_zero(k));
|
|
||||||
sm2_bn_to_bytes(k, k_bytes);
|
|
||||||
|
|
||||||
// R1 = A1 + B1 + k*G
|
|
||||||
sm2_point_add(&r->C1, &a->C1, &b->C1);
|
|
||||||
sm2_point_mul_generator(&R, k_bytes);
|
|
||||||
sm2_point_add(&r->C1, &r->C1, &R);
|
|
||||||
|
|
||||||
// R2 = A2 + B2 + k*P
|
|
||||||
sm2_point_add(&r->C2, &a->C2, &b->C2);
|
|
||||||
sm2_point_mul(&R, k_bytes, &pub_key->public_key);
|
|
||||||
sm2_point_add(&r->C2, &r->C2, &R);
|
|
||||||
|
|
||||||
gmssl_secure_clear(k, sizeof(k));
|
|
||||||
gmssl_secure_clear(k_bytes, sizeof(k_bytes));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_elgamal_cipehrtext_sub(SM2_ELGAMAL_CIPHERTEXT *r,
|
|
||||||
const SM2_ELGAMAL_CIPHERTEXT *a, const SM2_ELGAMAL_CIPHERTEXT *b,
|
|
||||||
const SM2_KEY *pub_key)
|
|
||||||
{
|
|
||||||
SM2_Fn k;
|
|
||||||
uint8_t k_bytes[32];
|
|
||||||
SM2_POINT R;
|
|
||||||
|
|
||||||
if (!r || !a || !b || !pub_key) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (sm2_fn_rand(k) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} while (sm2_bn_is_zero(k));
|
|
||||||
sm2_bn_to_bytes(k, k_bytes);
|
|
||||||
|
|
||||||
// R1 = A1 - B1 + k*G
|
|
||||||
sm2_point_sub(&r->C1, &a->C1, &b->C1);
|
|
||||||
sm2_point_mul_generator(&R, k_bytes);
|
|
||||||
sm2_point_add(&r->C1, &a->C1, &R);
|
|
||||||
|
|
||||||
// R2 = A2 - B2 + k*P
|
|
||||||
sm2_point_sub(&r->C2, &a->C2, &b->C2);
|
|
||||||
sm2_point_mul(&R, k_bytes, &pub_key->public_key);
|
|
||||||
sm2_point_add(&r->C2, &r->C2, &R);
|
|
||||||
|
|
||||||
gmssl_secure_clear(k, sizeof(k));
|
|
||||||
gmssl_secure_clear(k_bytes, sizeof(k_bytes));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_elgamal_cipehrtext_neg(SM2_ELGAMAL_CIPHERTEXT *r,
|
|
||||||
const SM2_ELGAMAL_CIPHERTEXT *a, const SM2_KEY *pub_key)
|
|
||||||
{
|
|
||||||
SM2_Fn k;
|
|
||||||
uint8_t k_bytes[32];
|
|
||||||
SM2_POINT R;
|
|
||||||
|
|
||||||
if (!r || !a || !pub_key) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (sm2_fn_rand(k) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} while (sm2_bn_is_zero(k));
|
|
||||||
sm2_bn_to_bytes(k, k_bytes);
|
|
||||||
|
|
||||||
// R1 = -A1 + k*G = -r*G + k*G
|
|
||||||
sm2_point_mul_generator(&R, k_bytes);
|
|
||||||
sm2_point_sub(&r->C1, &R, &a->C1);
|
|
||||||
|
|
||||||
// R2 = -A2 + k*P = -m*G -r*P + k*P
|
|
||||||
sm2_point_mul(&R, k_bytes, &pub_key->public_key);
|
|
||||||
sm2_point_sub(&r->C2, &R, &a->C2);
|
|
||||||
|
|
||||||
gmssl_secure_clear(k, sizeof(k));
|
|
||||||
gmssl_secure_clear(k_bytes, sizeof(k_bytes));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// s * (C1, C2) := (s*C1 + r*G, s*C2 + r*P)
|
|
||||||
int sm2_elgamal_ciphertext_scalar_mul(SM2_ELGAMAL_CIPHERTEXT *R,
|
|
||||||
const uint8_t scalar[32], const SM2_ELGAMAL_CIPHERTEXT *A,
|
|
||||||
const SM2_KEY *pub_key)
|
|
||||||
{
|
|
||||||
SM2_Fn k;
|
|
||||||
uint8_t k_bytes[32];
|
|
||||||
SM2_POINT kP;
|
|
||||||
|
|
||||||
if (!R || !scalar || !A || !pub_key) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (sm2_fn_rand(k) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} while (sm2_bn_is_zero(k));
|
|
||||||
sm2_bn_to_bytes(k, k_bytes);
|
|
||||||
|
|
||||||
// R1 = s*C1 + k*G
|
|
||||||
sm2_point_mul_sum(&R->C1, scalar, &A->C1, k_bytes);
|
|
||||||
|
|
||||||
// R2 = s*C2 + r*P
|
|
||||||
sm2_point_mul(&kP, k_bytes, &pub_key->public_key);
|
|
||||||
sm2_point_mul(&R->C2, scalar, &A->C2);
|
|
||||||
sm2_point_add(&R->C2, &R->C2, &kP);
|
|
||||||
|
|
||||||
gmssl_secure_clear(k, sizeof(k));
|
|
||||||
gmssl_secure_clear(k_bytes, sizeof(k_bytes));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_elgamal_ciphertext_to_der(const SM2_ELGAMAL_CIPHERTEXT *c, uint8_t **out, size_t *outlen)
|
|
||||||
{
|
|
||||||
uint8_t c1[65];
|
|
||||||
uint8_t c2[65];
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
sm2_point_to_uncompressed_octets(&c->C1, c1);
|
|
||||||
sm2_point_to_uncompressed_octets(&c->C2, c2);
|
|
||||||
|
|
||||||
if (asn1_octet_string_to_der(c1, sizeof(c1), NULL, &len) != 1
|
|
||||||
|| asn1_octet_string_to_der(c2, sizeof(c2), NULL, &len) != 1
|
|
||||||
|| asn1_sequence_header_to_der(len, out, outlen) != 1
|
|
||||||
|| asn1_octet_string_to_der(c1, sizeof(c1), out, outlen) != 1
|
|
||||||
|| asn1_octet_string_to_der(c2, sizeof(c2), out, outlen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_elgamal_ciphertext_from_der(SM2_ELGAMAL_CIPHERTEXT *c, const uint8_t **in, size_t *inlen)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
const uint8_t *d;
|
|
||||||
size_t dlen;
|
|
||||||
const uint8_t *c1;
|
|
||||||
size_t c1len;
|
|
||||||
const uint8_t *c2;
|
|
||||||
size_t c2len;
|
|
||||||
|
|
||||||
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (asn1_octet_string_from_der(&c1, &c1len, &d, &dlen) != 1
|
|
||||||
|| asn1_octet_string_from_der(&c2, &c2len, &d, &dlen) != 1
|
|
||||||
|| asn1_length_is_zero(dlen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (sm2_point_from_octets(&c->C1, c1, c1len) != 1
|
|
||||||
|| sm2_point_from_octets(&c->C2, c2, c2len) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_elgamal_encrypt(const SM2_KEY *pub_key, uint32_t in, uint8_t *out, size_t *outlen)
|
|
||||||
{
|
|
||||||
SM2_ELGAMAL_CIPHERTEXT C;
|
|
||||||
|
|
||||||
if (sm2_elgamal_do_encrypt(pub_key, in, &C) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*outlen = 0;
|
|
||||||
if (sm2_elgamal_ciphertext_to_der(&C, &out, outlen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_elgamal_decrypt(SM2_KEY *key, const uint8_t *in, size_t inlen, uint32_t *out)
|
|
||||||
{
|
|
||||||
SM2_ELGAMAL_CIPHERTEXT C;
|
|
||||||
|
|
||||||
if (sm2_elgamal_ciphertext_from_der(&C, &in, &inlen) != 1
|
|
||||||
|| asn1_length_is_zero(inlen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (sm2_elgamal_do_decrypt(key, &C, out) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
@@ -1,215 +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 <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <gmssl/sm2_key_share.h>
|
|
||||||
#include <gmssl/mem.h>
|
|
||||||
#include <gmssl/error.h>
|
|
||||||
|
|
||||||
extern SM2_BN SM2_N;
|
|
||||||
|
|
||||||
int sm2_key_share_print(FILE *fp, int fmt, int ind, const char *label, const SM2_KEY_SHARE *share)
|
|
||||||
{
|
|
||||||
format_print(fp, fmt, ind, "%s\n", label);
|
|
||||||
ind += 4;
|
|
||||||
format_print(fp, fmt, ind, "%zu/%zu\n", share->index, share->total_cnt);
|
|
||||||
format_print(fp, fmt, ind, "key", &share->key);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// y = f(x)
|
|
||||||
static void eval_univariate_poly(SM2_Fn y, const SM2_Fn *coeffs, size_t coeffs_cnt, uint32_t x)
|
|
||||||
{
|
|
||||||
sm2_bn_set_zero(y);
|
|
||||||
while (coeffs_cnt--) {
|
|
||||||
sm2_fn_mul_word(y, y, x);
|
|
||||||
sm2_fn_add(y, y, coeffs[coeffs_cnt]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_key_split(const SM2_KEY *key, size_t recover_cnt, size_t total_cnt, SM2_KEY_SHARE *shares)
|
|
||||||
{
|
|
||||||
SM2_Fn coeffs[SM2_KEY_MAX_SHARES];
|
|
||||||
SM2_Fn y;
|
|
||||||
uint8_t y_bytes[32];
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (!key || !shares) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (!total_cnt || total_cnt > SM2_KEY_MAX_SHARES) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (!recover_cnt || recover_cnt > total_cnt) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
// try to access mem
|
|
||||||
memset(shares, 0, sizeof(SM2_KEY_SHARE) * total_cnt);
|
|
||||||
|
|
||||||
for (i = 1; i < recover_cnt; i++) {
|
|
||||||
if (sm2_fn_rand(coeffs[i]) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sm2_bn_from_bytes(coeffs[0], key->private_key);
|
|
||||||
|
|
||||||
for (i = 0; i < total_cnt; i++) {
|
|
||||||
uint32_t x = (uint32_t)(i + 1);
|
|
||||||
eval_univariate_poly(y, coeffs, recover_cnt, x);
|
|
||||||
sm2_bn_to_bytes(y, y_bytes);
|
|
||||||
sm2_key_set_private_key(&(shares[i].key), y_bytes);
|
|
||||||
shares[i].index = i;
|
|
||||||
shares[i].total_cnt = total_cnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
gmssl_secure_clear(coeffs, sizeof(coeffs));
|
|
||||||
gmssl_secure_clear(y, sizeof(y));
|
|
||||||
gmssl_secure_clear(y_bytes, sizeof(y_bytes));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_key_recover(SM2_KEY *key, const SM2_KEY_SHARE *shares, size_t shares_cnt)
|
|
||||||
{
|
|
||||||
SM2_Fn s;
|
|
||||||
uint8_t s_bytes[32];
|
|
||||||
int x_i;
|
|
||||||
SM2_Fn y_i;
|
|
||||||
size_t i, j, k, n;
|
|
||||||
|
|
||||||
if (!shares || !shares_cnt || !key) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
k = shares_cnt;
|
|
||||||
n = shares[0].total_cnt;
|
|
||||||
|
|
||||||
if (n > SM2_KEY_MAX_SHARES) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
for (i = 0; i < k; i++) {
|
|
||||||
if (shares[i].total_cnt != n
|
|
||||||
|| shares[i].index >= n) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sm2_bn_set_zero(s);
|
|
||||||
|
|
||||||
for (i = 0; i < k; i++) {
|
|
||||||
// delta_i
|
|
||||||
SM2_Fn d;
|
|
||||||
int num = 1;
|
|
||||||
int den = 1;
|
|
||||||
int sign = 1;
|
|
||||||
|
|
||||||
x_i = (int)(shares[i].index + 1);
|
|
||||||
|
|
||||||
for (j = 0; j < k; j++) {
|
|
||||||
if (i != j) {
|
|
||||||
int x_j = (int)(shares[j].index + 1);
|
|
||||||
num *= -x_j;
|
|
||||||
den *= x_i - x_j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (num < 0) {
|
|
||||||
num = -num;
|
|
||||||
sign = -sign;
|
|
||||||
}
|
|
||||||
if (den < 0) {
|
|
||||||
den = -den;
|
|
||||||
sign = -sign;
|
|
||||||
}
|
|
||||||
|
|
||||||
// delta_i = Fn( num / den )
|
|
||||||
sm2_bn_set_word(d, den);
|
|
||||||
sm2_fn_inv(d, d);
|
|
||||||
sm2_fn_mul_word(d, d, num);
|
|
||||||
if (sign < 0) {
|
|
||||||
sm2_fn_neg(d, d);
|
|
||||||
}
|
|
||||||
|
|
||||||
// s += delta_i * y_i
|
|
||||||
sm2_bn_from_bytes(y_i, shares[i].key.private_key);
|
|
||||||
if (sm2_bn_cmp(y_i, SM2_N) >= 0) {
|
|
||||||
gmssl_secure_clear(y_i, sizeof(y_i));
|
|
||||||
gmssl_secure_clear(s, sizeof(s));
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
sm2_fn_mul(y_i, y_i, d);
|
|
||||||
sm2_fn_add(s, s, y_i);
|
|
||||||
}
|
|
||||||
|
|
||||||
sm2_bn_to_bytes(s, s_bytes);
|
|
||||||
sm2_key_set_private_key(key, s_bytes);
|
|
||||||
|
|
||||||
gmssl_secure_clear(y_i, sizeof(y_i));
|
|
||||||
gmssl_secure_clear(s, sizeof(s));
|
|
||||||
gmssl_secure_clear(s_bytes, sizeof(s_bytes));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_key_share_encrypt_to_file(const SM2_KEY_SHARE *share, const char *pass, const char *path_prefix)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
char *path = NULL;
|
|
||||||
FILE *fp = NULL;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
if (!share || !pass || !path_prefix) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (!share->total_cnt || share->total_cnt > 12 || share->index >= share->total_cnt) {
|
|
||||||
sm2_key_share_print(stderr, 0, 0, "share", share);
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if ((len = snprintf(NULL, 0, "%s-%zu-of-%zu.pem", path_prefix, share->index + 1, share->total_cnt)) <= 0) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (!(path = malloc(len + 1))) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
snprintf(path, len+1, "%s-%zu-of-%zu.pem", path_prefix, share->index + 1, share->total_cnt);
|
|
||||||
|
|
||||||
|
|
||||||
if (!(fp = fopen(path, "wb"))) {
|
|
||||||
error_print();
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
if (sm2_private_key_info_encrypt_to_pem(&share->key, pass, fp) != 1) {
|
|
||||||
error_print();
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
ret = 1;
|
|
||||||
end:
|
|
||||||
if (path) free(path);
|
|
||||||
if (fp) fclose(fp);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_key_share_decrypt_from_file(SM2_KEY_SHARE *share, const char *pass, const char *file)
|
|
||||||
{
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
@@ -1,138 +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 <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <gmssl/sm2.h>
|
|
||||||
#include <gmssl/error.h>
|
|
||||||
|
|
||||||
|
|
||||||
extern SM2_BN SM2_P;
|
|
||||||
extern SM2_BN SM2_B;
|
|
||||||
extern SM2_BN SM2_N;
|
|
||||||
extern SM2_BN SM2_THREE;
|
|
||||||
|
|
||||||
// r = H(Z||M) + x1 (mod n)
|
|
||||||
// x1 = r - H(Z||M) (mod n) or (r - H(Z||M) (mod n)) + n
|
|
||||||
// y1 = sqrt(x1^3 + a*x1 + b)
|
|
||||||
// R = (x1, y1) or (x1, -y1)
|
|
||||||
// P = (r + s)^-1 * R - (r + s)^-1 * s * G
|
|
||||||
int sm2_signature_to_public_key_points(const SM2_SIGNATURE *sig, const uint8_t dgst[32],
|
|
||||||
SM2_POINT points[4], size_t *points_cnt)
|
|
||||||
{
|
|
||||||
SM2_BN SM2_P_SUB_N;
|
|
||||||
SM2_JACOBIAN_POINT P;
|
|
||||||
SM2_JACOBIAN_POINT R;
|
|
||||||
|
|
||||||
SM2_Fp r;
|
|
||||||
SM2_Fp s;
|
|
||||||
SM2_Fp e;
|
|
||||||
SM2_Fn u;
|
|
||||||
SM2_Fn v;
|
|
||||||
SM2_Fp x1;
|
|
||||||
SM2_Fp y1;
|
|
||||||
|
|
||||||
// FIXME: check r, s
|
|
||||||
sm2_bn_from_bytes(r, sig->r);
|
|
||||||
sm2_bn_from_bytes(s, sig->s);
|
|
||||||
|
|
||||||
// u = (r + s)^-1, v = -(r + s)^-1 * s
|
|
||||||
sm2_fn_add(u, r, s);
|
|
||||||
sm2_fn_inv(u, u);
|
|
||||||
sm2_fn_mul(v, u, s);
|
|
||||||
sm2_fn_neg(v, v);
|
|
||||||
|
|
||||||
// e = H(Z||M) (mod n)
|
|
||||||
sm2_bn_from_bytes(e, dgst);
|
|
||||||
if (sm2_bn_cmp(e, SM2_N) >= 0) {
|
|
||||||
sm2_bn_sub(e, e, SM2_N);
|
|
||||||
}
|
|
||||||
|
|
||||||
// x1 = r - e (mod n)
|
|
||||||
sm2_fn_sub(x1, r, e);
|
|
||||||
|
|
||||||
// y1 = sqrt(x1^3 + a*x + b) = sqrt((x1^2 + a)*x1 + b)
|
|
||||||
sm2_fp_sqr(y1, x1);
|
|
||||||
sm2_fp_sub(y1, y1, SM2_THREE);
|
|
||||||
sm2_fp_mul(y1, y1, x1);
|
|
||||||
sm2_fp_add(y1, y1, SM2_B);
|
|
||||||
|
|
||||||
if (sm2_fp_sqrt(y1, y1) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
sm2_jacobian_point_set_xy(&R, x1, y1);
|
|
||||||
|
|
||||||
// P = u * R + v * G
|
|
||||||
sm2_jacobian_point_mul_sum(&P, u, &R, v);
|
|
||||||
sm2_jacobian_point_to_bytes(&P, (uint8_t *)&points[0]);
|
|
||||||
|
|
||||||
// P' = u * (-R) + v * G
|
|
||||||
sm2_jacobian_point_neg(&R, &R);
|
|
||||||
sm2_jacobian_point_mul_sum(&P, u, &R, v);
|
|
||||||
sm2_jacobian_point_to_bytes(&P, (uint8_t *)&points[1]);
|
|
||||||
*points_cnt = 2;
|
|
||||||
|
|
||||||
// if x1 in [n, p-1], x1 (mod n) in [0, p-n-1]
|
|
||||||
// ==> if x1 (mod n) in [0, p-n-1], x1 == (x1 (mod n) + n) (mod p)
|
|
||||||
sm2_bn_sub(SM2_P_SUB_N, SM2_P, SM2_N);
|
|
||||||
|
|
||||||
if (sm2_bn_cmp(x1, SM2_P_SUB_N) < 0) {
|
|
||||||
|
|
||||||
// x1' = x1 (mod n) + n
|
|
||||||
sm2_bn_add(x1, x1, SM2_N);
|
|
||||||
|
|
||||||
// y1' = sqrt(x1'^3 + a*x' + b)
|
|
||||||
sm2_fp_sqr(y1, x1);
|
|
||||||
sm2_fp_sub(y1, y1, SM2_THREE);
|
|
||||||
sm2_fp_mul(y1, y1, x1);
|
|
||||||
sm2_fp_add(y1, y1, SM2_B);
|
|
||||||
if (sm2_fp_sqrt(y1, y1) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
sm2_jacobian_point_set_xy(&R, x1, y1);
|
|
||||||
|
|
||||||
// P = u * R + v * G
|
|
||||||
sm2_jacobian_point_mul_sum(&P, u, &R, v);
|
|
||||||
sm2_jacobian_point_to_bytes(&P, (uint8_t *)&points[2]);
|
|
||||||
// P' = u * (-R) + v * G
|
|
||||||
sm2_jacobian_point_neg(&R, &R);
|
|
||||||
sm2_jacobian_point_mul_sum(&P, u, &R, v);
|
|
||||||
sm2_jacobian_point_to_bytes(&P, (uint8_t *)&points[3]);
|
|
||||||
*points_cnt = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// verify the xR of R = s * G + (s + r) * P
|
|
||||||
// so (-r, -s) is also a valid SM2 signature
|
|
||||||
int sm2_signature_conjugate(const SM2_SIGNATURE *sig, SM2_SIGNATURE *new_sig)
|
|
||||||
{
|
|
||||||
SM2_Fn r;
|
|
||||||
SM2_Fn s;
|
|
||||||
|
|
||||||
// FIXME: check r,s
|
|
||||||
sm2_bn_from_bytes(r, sig->r);
|
|
||||||
sm2_bn_from_bytes(s, sig->s);
|
|
||||||
sm2_fn_neg(r, r);
|
|
||||||
sm2_fn_neg(s, s);
|
|
||||||
sm2_bn_to_bytes(r, new_sig->r);
|
|
||||||
sm2_bn_to_bytes(s, new_sig->s);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Add API to support sig,siglen
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
580
src/sm2_ring.c
580
src/sm2_ring.c
@@ -1,580 +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 <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <gmssl/sm2_ring.h>
|
|
||||||
#include <gmssl/asn1.h>
|
|
||||||
#include <gmssl/error.h>
|
|
||||||
|
|
||||||
|
|
||||||
extern SM2_BN SM2_N;
|
|
||||||
extern SM2_BN SM2_ONE;
|
|
||||||
|
|
||||||
|
|
||||||
static int compare_point(const void *P, const void *Q)
|
|
||||||
{
|
|
||||||
const uint8_t *p = (uint8_t *)P;
|
|
||||||
const uint8_t *q = (uint8_t *)Q;
|
|
||||||
int i, r;
|
|
||||||
for (i = 0; i < sizeof(SM2_POINT); i++) {
|
|
||||||
r = p[i] - q[i];
|
|
||||||
if (r) {
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sm2_ring_sort_public_keys(SM2_POINT *points, size_t points_cnt)
|
|
||||||
{
|
|
||||||
qsort(points, points_cnt, sizeof(SM2_POINT), compare_point);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_ring_signature_to_der(const sm2_bn_t r, const sm2_bn_t *s, size_t s_cnt, uint8_t **out, size_t *outlen)
|
|
||||||
{
|
|
||||||
size_t i, len = 0;
|
|
||||||
uint8_t *p = *out;
|
|
||||||
|
|
||||||
if (asn1_integer_to_der(r, 32, NULL, &len) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
for (i = 0; i < s_cnt; i++) {
|
|
||||||
if (asn1_integer_to_der(s[i], 32, NULL, &len) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (asn1_sequence_header_to_der(len, out, outlen) != 1
|
|
||||||
|| asn1_integer_to_der(r, 32, out, outlen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
for (i = 0; i < s_cnt; i++) {
|
|
||||||
if (asn1_integer_to_der(s[i], 32, out, outlen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: support when s_vec == NULL
|
|
||||||
int sm2_ring_signature_from_der(sm2_bn_t r0, sm2_bn_t *s_vec, size_t *s_cnt, const uint8_t **in, size_t *inlen)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
const uint8_t *d;
|
|
||||||
size_t dlen;
|
|
||||||
const uint8_t *p;
|
|
||||||
size_t len;
|
|
||||||
uint8_t *s = (uint8_t *)&s_vec[0];
|
|
||||||
|
|
||||||
if ((ret = asn1_sequence_from_der(&d, &dlen, in, inlen)) != 1) {
|
|
||||||
if (ret < 0) error_print();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if (asn1_integer_from_der(&p, &len, &d, &dlen) != 1
|
|
||||||
|| asn1_length_le(len, 32) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memset(r0, 0, 32);
|
|
||||||
memcpy(r0 + 32 - len, p, len);
|
|
||||||
|
|
||||||
*s_cnt = 0;
|
|
||||||
while (dlen) {
|
|
||||||
if (asn1_integer_from_der(&p, &len, &d, &dlen) != 1
|
|
||||||
|| asn1_length_le(len, 32) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memset(s, 0, 32 - len);
|
|
||||||
memcpy(s + 32 - len, p, len);
|
|
||||||
s += 32;
|
|
||||||
|
|
||||||
(*s_cnt)++;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_ring_do_sign(const SM2_KEY *sign_key,
|
|
||||||
const SM2_POINT *public_keys, size_t public_keys_cnt,
|
|
||||||
const uint8_t dgst[32], uint8_t r0[32], sm2_bn_t *s_vec)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
size_t sign_index = public_keys_cnt; // assign an invalid value
|
|
||||||
|
|
||||||
SM2_JACOBIAN_POINT R;
|
|
||||||
SM2_JACOBIAN_POINT P;
|
|
||||||
SM2_Fn e;
|
|
||||||
SM2_Fn k;
|
|
||||||
SM2_Fp x;
|
|
||||||
SM2_Fn r;
|
|
||||||
SM2_Fn s;
|
|
||||||
SM2_Fn t;
|
|
||||||
SM2_Fn d;
|
|
||||||
|
|
||||||
// e = H(M) (mod n)
|
|
||||||
sm2_bn_from_bytes(e, dgst);
|
|
||||||
if (sm2_bn_cmp(e, SM2_N) >= 0) {
|
|
||||||
sm2_bn_sub(e, e, SM2_N);
|
|
||||||
}
|
|
||||||
|
|
||||||
// find signer's index
|
|
||||||
for (i = 0; i < public_keys_cnt; i++) {
|
|
||||||
if (memcmp(&public_keys[i], &(sign_key->public_key), sizeof(SM2_POINT)) == 0) {
|
|
||||||
sign_index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sign_index >= public_keys_cnt) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// k[i] = rand(1, n-1), r[i], s[i] will be computed at the last step
|
|
||||||
sm2_fn_rand(k);
|
|
||||||
|
|
||||||
// R[i+1] = k[i] * G
|
|
||||||
sm2_jacobian_point_mul_generator(&R, k);
|
|
||||||
sm2_jacobian_point_get_xy(&R, x, NULL);
|
|
||||||
|
|
||||||
// i = i + 1 (mod N)
|
|
||||||
for (i = (i + 1) % public_keys_cnt; i != sign_index; i = (i + 1) % public_keys_cnt) {
|
|
||||||
|
|
||||||
// r[i] = x[i] + e (mod n)
|
|
||||||
sm2_fn_add(r, x, e);
|
|
||||||
|
|
||||||
// output r[0]
|
|
||||||
if (i == 0) {
|
|
||||||
sm2_bn_to_bytes(r, r0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// s[i] = rand(1, n-1)
|
|
||||||
sm2_fn_rand(s);
|
|
||||||
sm2_bn_to_bytes(s, s_vec[i]);
|
|
||||||
|
|
||||||
// R[i+1] = k[i] * G = (s[i] + r[i]) * P[i] + s[i] * G
|
|
||||||
sm2_fn_add(t, s, r);
|
|
||||||
sm2_jacobian_point_from_bytes(&P, (const uint8_t *)&public_keys[i]);
|
|
||||||
sm2_jacobian_point_mul_sum(&R, t, &P, s);
|
|
||||||
sm2_jacobian_point_get_xy(&R, x, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// r[i] = x[i] + e (mod n)
|
|
||||||
sm2_fn_add(r, x, e);
|
|
||||||
if (i == 0) {
|
|
||||||
sm2_bn_to_bytes(r, r0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// s[i] = (k[i] - r[i] * d)/(1 + d)
|
|
||||||
sm2_bn_from_bytes(d, sign_key->private_key);
|
|
||||||
sm2_fn_mul(r, r, d);
|
|
||||||
sm2_fn_sub(s, k, r);
|
|
||||||
sm2_fn_add(d, d, SM2_ONE);
|
|
||||||
sm2_fn_inv(d, d);
|
|
||||||
sm2_fn_mul(s, s, d);
|
|
||||||
sm2_bn_to_bytes(s, s_vec[i]);
|
|
||||||
|
|
||||||
// cleanup
|
|
||||||
memset(d, 0, sizeof(d));
|
|
||||||
memset(k, 0, sizeof(k));
|
|
||||||
memset(r, 0, sizeof(r));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_ring_do_verify(const SM2_POINT *public_keys, size_t public_keys_cnt,
|
|
||||||
const uint8_t dgst[32], const uint8_t r0[32], const sm2_bn_t *s_vec)
|
|
||||||
{
|
|
||||||
SM2_JACOBIAN_POINT P;
|
|
||||||
SM2_JACOBIAN_POINT R;
|
|
||||||
SM2_Fn r;
|
|
||||||
SM2_Fn r_;
|
|
||||||
SM2_Fn s;
|
|
||||||
SM2_Fn e;
|
|
||||||
SM2_Fn t;
|
|
||||||
SM2_Fn x;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
sm2_bn_from_bytes(e, dgst);
|
|
||||||
if (sm2_bn_cmp(e, SM2_N) >= 0) {
|
|
||||||
sm2_bn_sub(e, e, SM2_N);
|
|
||||||
}
|
|
||||||
|
|
||||||
sm2_bn_from_bytes(r, r0);
|
|
||||||
|
|
||||||
for (i = 0; i < public_keys_cnt; i++) {
|
|
||||||
sm2_bn_from_bytes(s, s_vec[i]);
|
|
||||||
|
|
||||||
// R(x, y) = k * G = s * G + (s + r) * P
|
|
||||||
sm2_fn_add(t, s, r);
|
|
||||||
sm2_jacobian_point_from_bytes(&P, (const uint8_t *)&public_keys[i]);
|
|
||||||
sm2_jacobian_point_mul_sum(&R, t, &P, s);
|
|
||||||
sm2_jacobian_point_get_xy(&R, x, NULL);
|
|
||||||
|
|
||||||
// r = e + x (mod n)
|
|
||||||
sm2_fn_add(r, x, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
sm2_bn_from_bytes(r_, r0);
|
|
||||||
if (sm2_bn_cmp(r_, r) != 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_ring_sign(const SM2_KEY *sign_key,
|
|
||||||
const SM2_POINT *public_keys, size_t public_keys_cnt,
|
|
||||||
const uint8_t dgst[32], uint8_t *sig, size_t *siglen)
|
|
||||||
{
|
|
||||||
sm2_bn_t r;
|
|
||||||
sm2_bn_t s[SM2_RING_SIGN_MAX_SIGNERS];
|
|
||||||
|
|
||||||
if (!public_keys_cnt || public_keys_cnt > sizeof(s)/sizeof(s[0])) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (sm2_ring_do_sign(sign_key, public_keys, public_keys_cnt, dgst, r, s) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*siglen = 0;
|
|
||||||
if (sm2_ring_signature_to_der(r, s, public_keys_cnt, &sig, siglen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_ring_verify(const SM2_POINT *public_keys, size_t public_keys_cnt,
|
|
||||||
const uint8_t dgst[32], const uint8_t *sig, size_t siglen)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
sm2_bn_t r;
|
|
||||||
sm2_bn_t s[SM2_RING_SIGN_MAX_SIGNERS];
|
|
||||||
size_t s_cnt;
|
|
||||||
|
|
||||||
if (!public_keys_cnt || public_keys_cnt > sizeof(s)/sizeof(s[0])) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (sm2_ring_signature_from_der(r, s, &s_cnt, &sig, &siglen) != 1
|
|
||||||
|| asn1_length_is_zero(siglen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (s_cnt != public_keys_cnt) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ret = sm2_ring_do_verify(public_keys, public_keys_cnt, dgst, r, s)) < 0) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_ring_sign_init(SM2_RING_SIGN_CTX *ctx, const SM2_KEY *sign_key, const char *id, size_t idlen)
|
|
||||||
{
|
|
||||||
sm3_init(&ctx->sm3_ctx);
|
|
||||||
ctx->sign_key = *sign_key;
|
|
||||||
ctx->public_keys[0] = sign_key->public_key;
|
|
||||||
ctx->public_keys_count = 1;
|
|
||||||
if (!(ctx->id = malloc(idlen + 1))) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memcpy(ctx->id, id, idlen);
|
|
||||||
ctx->id[idlen] = 0;
|
|
||||||
ctx->idlen = idlen;
|
|
||||||
ctx->state = 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_ring_sign_add_signer(SM2_RING_SIGN_CTX *ctx, const SM2_KEY *public_key)
|
|
||||||
{
|
|
||||||
if (ctx->state) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (ctx->public_keys_count >= SM2_RING_SIGN_MAX_SIGNERS) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
ctx->public_keys[ctx->public_keys_count++] = public_key->public_key;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_ring_sign_update(SM2_RING_SIGN_CTX *ctx, const uint8_t *data, size_t datalen)
|
|
||||||
{
|
|
||||||
if (!ctx->state) {
|
|
||||||
SM2_POINT point = ctx->public_keys[0];
|
|
||||||
uint8_t z[32];
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 1; i < ctx->public_keys_count; i++) {
|
|
||||||
sm2_point_add(&point, &point, &ctx->public_keys[i]);
|
|
||||||
}
|
|
||||||
sm2_compute_z(z, &point, ctx->id, ctx->idlen);
|
|
||||||
sm3_update(&ctx->sm3_ctx, z, sizeof(z));
|
|
||||||
ctx->state = 1;
|
|
||||||
}
|
|
||||||
if (data && datalen) {
|
|
||||||
sm3_update(&ctx->sm3_ctx, data, datalen);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_ring_sign_finish(SM2_RING_SIGN_CTX *ctx, uint8_t *sig, size_t *siglen)
|
|
||||||
{
|
|
||||||
uint8_t dgst[32];
|
|
||||||
|
|
||||||
sm3_finish(&ctx->sm3_ctx, dgst);
|
|
||||||
|
|
||||||
if (sm2_ring_sort_public_keys(ctx->public_keys, ctx->public_keys_count) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (sm2_ring_sign(&ctx->sign_key, ctx->public_keys, ctx->public_keys_count, dgst, sig, siglen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_ring_verify_init(SM2_RING_SIGN_CTX *ctx, const char *id, size_t idlen)
|
|
||||||
{
|
|
||||||
sm3_init(&ctx->sm3_ctx);
|
|
||||||
ctx->public_keys_count = 0;
|
|
||||||
if (!(ctx->id = malloc(idlen + 1))) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memcpy(ctx->id, id, idlen);
|
|
||||||
ctx->id[idlen] = 0;
|
|
||||||
ctx->idlen = idlen;
|
|
||||||
ctx->state = 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_ring_verify_add_signer(SM2_RING_SIGN_CTX *ctx, const SM2_KEY *public_key)
|
|
||||||
{
|
|
||||||
if (ctx->state) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (ctx->public_keys_count >= SM2_RING_SIGN_MAX_SIGNERS) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
ctx->public_keys[ctx->public_keys_count++] = public_key->public_key;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_ring_verify_update(SM2_RING_SIGN_CTX *ctx, const uint8_t *data, size_t datalen)
|
|
||||||
{
|
|
||||||
if (!ctx->state) {
|
|
||||||
SM2_POINT point = ctx->public_keys[0];
|
|
||||||
uint8_t z[32];
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 1; i < ctx->public_keys_count; i++) {
|
|
||||||
sm2_point_add(&point, &point, &ctx->public_keys[i]);
|
|
||||||
}
|
|
||||||
sm2_compute_z(z, &point, ctx->id, ctx->idlen);
|
|
||||||
sm3_update(&ctx->sm3_ctx, z, sizeof(z));
|
|
||||||
ctx->state = 1;
|
|
||||||
}
|
|
||||||
if (data && datalen) {
|
|
||||||
sm3_update(&ctx->sm3_ctx, data, datalen);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sm2_ring_verify_finish(SM2_RING_SIGN_CTX *ctx, uint8_t *sig, size_t siglen)
|
|
||||||
{
|
|
||||||
uint8_t dgst[32];
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
sm3_finish(&ctx->sm3_ctx, dgst);
|
|
||||||
|
|
||||||
if (sm2_ring_sort_public_keys(ctx->public_keys, ctx->public_keys_count) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if ((ret = sm2_ring_verify(ctx->public_keys, ctx->public_keys_count, dgst, sig, siglen)) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int test_sm2_ring_do_sign(void)
|
|
||||||
{
|
|
||||||
SM2_KEY sign_key;
|
|
||||||
SM2_POINT public_keys[5];
|
|
||||||
size_t public_keys_count = sizeof(public_keys)/sizeof(public_keys[0]);
|
|
||||||
size_t sign_index, i;
|
|
||||||
uint8_t dgst[32];
|
|
||||||
uint8_t r[32];
|
|
||||||
uint8_t s[sizeof(public_keys)/sizeof(public_keys[0])][32];
|
|
||||||
|
|
||||||
for (sign_index = 0; sign_index < 5; sign_index++) {
|
|
||||||
|
|
||||||
for (i = 0; i < public_keys_count; i++) {
|
|
||||||
SM2_KEY key;
|
|
||||||
sm2_key_generate(&key);
|
|
||||||
memcpy(&public_keys[i], &(key.public_key), sizeof(SM2_POINT));
|
|
||||||
|
|
||||||
if (i == sign_index) {
|
|
||||||
memcpy(&sign_key, &key, sizeof(SM2_KEY));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sm2_ring_do_sign(&sign_key, public_keys, public_keys_count, dgst, r, s) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (sm2_ring_do_verify(public_keys, public_keys_count, dgst, r, s) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s() ok\n", __FUNCTION__);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int test_sm2_ring_sign(void)
|
|
||||||
{
|
|
||||||
SM2_KEY sign_key;
|
|
||||||
SM2_POINT public_keys[5];
|
|
||||||
size_t public_keys_count = sizeof(public_keys)/sizeof(public_keys[0]);
|
|
||||||
size_t sign_index = 2, i;
|
|
||||||
uint8_t dgst[32];
|
|
||||||
uint8_t sig[9 + (2 + 33) * (1 + sizeof(public_keys)/sizeof(public_keys[0]))];
|
|
||||||
size_t siglen = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < public_keys_count; i++) {
|
|
||||||
SM2_KEY key;
|
|
||||||
sm2_key_generate(&key);
|
|
||||||
memcpy(&public_keys[i], &(key.public_key), sizeof(SM2_POINT));
|
|
||||||
|
|
||||||
if (i == sign_index) {
|
|
||||||
memcpy(&sign_key, &key, sizeof(SM2_KEY));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sm2_ring_sign(&sign_key, public_keys, public_keys_count, dgst, sig, &siglen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (sm2_ring_verify(public_keys, 5, dgst, sig, siglen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s() ok\n", __FUNCTION__);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int test_sm2_ring_sign_crosscheck(void)
|
|
||||||
{
|
|
||||||
SM2_KEY sign_key;
|
|
||||||
SM2_POINT public_key;
|
|
||||||
uint8_t dgst[32];
|
|
||||||
uint8_t sig[SM2_MAX_SIGNATURE_SIZE];
|
|
||||||
size_t siglen = 0;
|
|
||||||
|
|
||||||
sm2_key_generate(&sign_key);
|
|
||||||
public_key = sign_key.public_key;
|
|
||||||
|
|
||||||
if (sm2_ring_sign(&sign_key, &public_key, 1, dgst, sig, &siglen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (sm2_ring_verify(&public_key, 1, dgst, sig, siglen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s() ok\n", __FUNCTION__);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int test_sm2_ring_sign_update(void)
|
|
||||||
{
|
|
||||||
SM2_KEY keys[5];
|
|
||||||
SM2_RING_SIGN_CTX sign_ctx;
|
|
||||||
SM2_RING_SIGN_CTX verify_ctx;
|
|
||||||
size_t public_keys_count = sizeof(keys)/sizeof(keys[0]);
|
|
||||||
char *id = "Alice";
|
|
||||||
uint8_t msg[128] = {0};
|
|
||||||
uint8_t sig[9 + (2 + 33) * (1 + sizeof(keys)/sizeof(keys[0]))];
|
|
||||||
size_t siglen = 0;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < public_keys_count; i++) {
|
|
||||||
sm2_key_generate(&keys[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sm2_ring_sign_init(&sign_ctx, &keys[0], id, strlen(id)) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
for (i = 1; i < public_keys_count; i++) {
|
|
||||||
if (sm2_ring_sign_add_signer(&sign_ctx, &keys[i]) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sm2_ring_sign_update(&sign_ctx, msg, 32) != 1
|
|
||||||
|| sm2_ring_sign_update(&sign_ctx, msg + 32, 32) != 1
|
|
||||||
|| sm2_ring_sign_update(&sign_ctx, msg + 64, 64) != 1
|
|
||||||
|| sm2_ring_sign_finish(&sign_ctx, sig, &siglen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sm2_ring_verify_init(&verify_ctx, id, strlen(id)) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
for (i = 0; i < public_keys_count; i++) {
|
|
||||||
if (sm2_ring_verify_add_signer(&verify_ctx, &keys[i]) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sm2_ring_verify_update(&verify_ctx, msg, sizeof(msg)) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (sm2_ring_verify_finish(&verify_ctx, sig, siglen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s() ok\n", __FUNCTION__);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int test_sm2_ring()
|
|
||||||
{
|
|
||||||
if (test_sm2_ring_do_sign() != 1) { error_print(); return -1; }
|
|
||||||
if (test_sm2_ring_sign() != 1) { error_print(); return -1; }
|
|
||||||
if (test_sm2_ring_sign_crosscheck() != 1) { error_print(); return -1; }
|
|
||||||
if (test_sm2_ring_sign_update() != 1) { error_print(); return -1; }
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,100 +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 <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <gmssl/sm2.h>
|
|
||||||
#include <gmssl/sm2_blind.h>
|
|
||||||
#include <gmssl/error.h>
|
|
||||||
|
|
||||||
|
|
||||||
static int test_sm2_blind_sign(void)
|
|
||||||
{
|
|
||||||
int r = -1;
|
|
||||||
|
|
||||||
// signer
|
|
||||||
SM2_KEY key;
|
|
||||||
SM2_Fn k;
|
|
||||||
uint8_t commit[65];
|
|
||||||
size_t commitlen;
|
|
||||||
|
|
||||||
// caller
|
|
||||||
SM2_KEY public_key;
|
|
||||||
SM2_BLIND_SIGN_CTX sign_ctx;
|
|
||||||
uint8_t msg[128] = {0};
|
|
||||||
uint8_t blinded_sig_s[32];
|
|
||||||
uint8_t blinded_sig_r[32];
|
|
||||||
uint8_t sig[128];
|
|
||||||
size_t siglen;
|
|
||||||
|
|
||||||
// verifier
|
|
||||||
SM2_SIGN_CTX verify_ctx;
|
|
||||||
|
|
||||||
|
|
||||||
// signer
|
|
||||||
if (sm2_key_generate(&key) != 1
|
|
||||||
|| sm2_key_set_public_key(&public_key, &key.public_key) != 1) {
|
|
||||||
error_print();
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
if (sm2_blind_sign_commit(k, commit, &commitlen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
format_bytes(stderr, 0, 0, "signer: commitment", commit, commitlen);
|
|
||||||
|
|
||||||
// caller
|
|
||||||
if (sm2_blind_sign_init(&sign_ctx, &public_key,
|
|
||||||
SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1
|
|
||||||
|| sm2_blind_sign_update(&sign_ctx, msg, 32) != 1
|
|
||||||
|| sm2_blind_sign_update(&sign_ctx, msg + 32, 32) != 1
|
|
||||||
|| sm2_blind_sign_update(&sign_ctx, msg + 64, 64) != 1
|
|
||||||
|| sm2_blind_sign_finish(&sign_ctx, commit, commitlen, blinded_sig_r) != 1) {
|
|
||||||
error_print();
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
format_bytes(stderr, 0, 0, "caller: blinded_sig_r", blinded_sig_r, sizeof(blinded_sig_r));
|
|
||||||
|
|
||||||
// signer
|
|
||||||
if (sm2_blind_sign(&key, k, blinded_sig_r, blinded_sig_s) != 1) {
|
|
||||||
error_print();
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
format_bytes(stderr, 0, 0, "signer: blinded_sig_s", blinded_sig_s, sizeof(blinded_sig_s));
|
|
||||||
|
|
||||||
// caller
|
|
||||||
if (sm2_blind_sign_unblind(&sign_ctx, blinded_sig_s, sig, &siglen) != 1) {
|
|
||||||
error_print();
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
format_bytes(stderr, 0, 0, "caller: unblinded_sig", sig, siglen);
|
|
||||||
|
|
||||||
// verifier
|
|
||||||
if (sm2_verify_init(&verify_ctx, &public_key,
|
|
||||||
SM2_DEFAULT_ID, strlen(SM2_DEFAULT_ID)) != 1
|
|
||||||
|| sm2_verify_update(&verify_ctx, msg, sizeof(msg)) != 1
|
|
||||||
|| (r = sm2_verify_finish(&verify_ctx, sig, siglen)) < 0) {
|
|
||||||
error_print();
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
format_print(stderr, 0, 0, "verifier: %s\n", r == 1 ? "success" : "failure");
|
|
||||||
|
|
||||||
end:
|
|
||||||
gmssl_secure_clear(&key, sizeof(key));
|
|
||||||
gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx));
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
if (test_sm2_blind_sign() != 1) { error_print(); return -1; }
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,59 +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 <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <gmssl/sm2.h>
|
|
||||||
#include <gmssl/sm2_commit.h>
|
|
||||||
#include <gmssl/error.h>
|
|
||||||
|
|
||||||
|
|
||||||
static int test_sm2_commit(void)
|
|
||||||
{
|
|
||||||
uint8_t x[32];
|
|
||||||
uint8_t xvec[8][32];
|
|
||||||
uint8_t r[32];
|
|
||||||
uint8_t commit[65];
|
|
||||||
size_t commitlen;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
rand_bytes(x, sizeof(x));
|
|
||||||
format_bytes(stderr, 0, 0, "secret", x, sizeof(x));
|
|
||||||
|
|
||||||
sm2_commit_generate(x, r, commit, &commitlen);
|
|
||||||
format_bytes(stderr, 0, 0, "random", r, sizeof(r));
|
|
||||||
format_bytes(stderr, 0, 0, "commitment", commit, commitlen);
|
|
||||||
|
|
||||||
ret = sm2_commit_open(x, r, commit, commitlen);
|
|
||||||
printf("open commitment: %s\n", ret == 1 ? "success" : "failure");
|
|
||||||
|
|
||||||
|
|
||||||
sm2_commit_vector_generate(&x, 1, r, commit, &commitlen);
|
|
||||||
format_bytes(stderr, 0, 0, "random", r, sizeof(r));
|
|
||||||
format_bytes(stderr, 0, 0, "commitment", commit, commitlen);
|
|
||||||
|
|
||||||
ret = sm2_commit_vector_open(&x, 1, r, commit, commitlen);
|
|
||||||
printf("open commitment: %s\n", ret == 1 ? "success" : "failure");
|
|
||||||
|
|
||||||
|
|
||||||
rand_bytes(xvec[0], sizeof(xvec));
|
|
||||||
sm2_commit_vector_generate(xvec, 8, r, commit, &commitlen);
|
|
||||||
ret = sm2_commit_vector_open(xvec, 8, r, commit, commitlen);
|
|
||||||
printf("open commitment: %s\n", ret == 1 ? "success" : "failure");
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
if (test_sm2_commit() != 1) { error_print(); return -1; }
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,22 +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 <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <gmssl/sm2.h>
|
|
||||||
#include <gmssl/sm2_elgamal.h>
|
|
||||||
#include <gmssl/error.h>
|
|
||||||
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,96 +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 <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <gmssl/sm2.h>
|
|
||||||
#include <gmssl/sm2_key_share.h>
|
|
||||||
#include <gmssl/mem.h>
|
|
||||||
#include <gmssl/error.h>
|
|
||||||
|
|
||||||
|
|
||||||
static int test_sm2_key_share_args(size_t k, size_t n)
|
|
||||||
{
|
|
||||||
SM2_KEY key;
|
|
||||||
SM2_KEY key_;
|
|
||||||
SM2_KEY_SHARE shares[SM2_KEY_MAX_SHARES];
|
|
||||||
|
|
||||||
if (sm2_key_generate(&key) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (sm2_key_split(&key, k, n, shares) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// recover from 0 .. k
|
|
||||||
if (sm2_key_recover(&key_, shares, k) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (memcmp(&key_, &key, sizeof(SM2_KEY)) != 0) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// recover from n-k .. n
|
|
||||||
memset(&key_, 0, sizeof(key_));
|
|
||||||
if (sm2_key_recover(&key_, shares + n - k, k) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (memcmp(&key_, &key, sizeof(SM2_KEY)) != 0) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int test_sm2_key_share(void)
|
|
||||||
{
|
|
||||||
if (test_sm2_key_share_args(1, 1) != 1) { error_print(); return -1; }
|
|
||||||
if (test_sm2_key_share_args(1, 3) != 1) { error_print(); return -1; }
|
|
||||||
if (test_sm2_key_share_args(2, 3) != 1) { error_print(); return -1; }
|
|
||||||
if (test_sm2_key_share_args(3, 5) != 1) { error_print(); return -1; }
|
|
||||||
if (test_sm2_key_share_args(4, 5) != 1) { error_print(); return -1; }
|
|
||||||
if (test_sm2_key_share_args(5, 5) != 1) { error_print(); return -1; }
|
|
||||||
if (test_sm2_key_share_args(11, 12) != 1) { error_print(); return -1; }
|
|
||||||
if (test_sm2_key_share_args(12, 12) != 1) { error_print(); return -1; }
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int test_sm2_key_share_file(void)
|
|
||||||
{
|
|
||||||
SM2_KEY key;
|
|
||||||
SM2_KEY_SHARE shares[SM2_KEY_MAX_SHARES];
|
|
||||||
|
|
||||||
if (sm2_key_generate(&key) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (sm2_key_split(&key, 2, 3, shares) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (sm2_key_share_encrypt_to_file(&shares[0], "123456", "sm2key") != 1
|
|
||||||
|| sm2_key_share_encrypt_to_file(&shares[1], "123456", "sm2key") != 1
|
|
||||||
|| sm2_key_share_encrypt_to_file(&shares[2], "123456", "sm2key") != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,44 +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 <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <gmssl/sm2.h>
|
|
||||||
#include <gmssl/sm2_recover.h>
|
|
||||||
#include <gmssl/error.h>
|
|
||||||
|
|
||||||
|
|
||||||
static int test_sm2_signature_to_public_key_points(void)
|
|
||||||
{
|
|
||||||
SM2_KEY key;
|
|
||||||
uint8_t dgst[32] = {1,2,3,4};
|
|
||||||
SM2_SIGNATURE sig;
|
|
||||||
SM2_POINT points[4];
|
|
||||||
size_t points_cnt, i;
|
|
||||||
|
|
||||||
sm2_key_generate(&key);
|
|
||||||
sm2_do_sign(&key, dgst, &sig);
|
|
||||||
sm2_signature_to_public_key_points(&sig, dgst, points, &points_cnt);
|
|
||||||
|
|
||||||
for (i = 0; i < points_cnt; i++) {
|
|
||||||
int vr;
|
|
||||||
sm2_point_print(stderr, 0, 0, "point", &points[i]);
|
|
||||||
vr = sm2_do_verify((SM2_KEY *)&points[1], dgst, &sig);
|
|
||||||
printf("verify = %d\n", vr);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
if (test_sm2_signature_to_public_key_points() != 1) { error_print(); return -1; }
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,174 +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 <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <gmssl/sm2.h>
|
|
||||||
#include <gmssl/sm2_ring.h>
|
|
||||||
#include <gmssl/error.h>
|
|
||||||
|
|
||||||
|
|
||||||
static int test_sm2_ring_do_sign(void)
|
|
||||||
{
|
|
||||||
SM2_KEY sign_key;
|
|
||||||
SM2_POINT public_keys[5];
|
|
||||||
size_t public_keys_count = sizeof(public_keys)/sizeof(public_keys[0]);
|
|
||||||
size_t sign_index, i;
|
|
||||||
uint8_t dgst[32];
|
|
||||||
uint8_t r[32];
|
|
||||||
uint8_t s[sizeof(public_keys)/sizeof(public_keys[0])][32];
|
|
||||||
|
|
||||||
for (sign_index = 0; sign_index < 5; sign_index++) {
|
|
||||||
|
|
||||||
for (i = 0; i < public_keys_count; i++) {
|
|
||||||
SM2_KEY key;
|
|
||||||
sm2_key_generate(&key);
|
|
||||||
memcpy(&public_keys[i], &(key.public_key), sizeof(SM2_POINT));
|
|
||||||
|
|
||||||
if (i == sign_index) {
|
|
||||||
memcpy(&sign_key, &key, sizeof(SM2_KEY));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sm2_ring_do_sign(&sign_key, public_keys, public_keys_count, dgst, r, s) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (sm2_ring_do_verify(public_keys, public_keys_count, dgst, r, s) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s() ok\n", __FUNCTION__);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int test_sm2_ring_sign(void)
|
|
||||||
{
|
|
||||||
SM2_KEY sign_key;
|
|
||||||
SM2_POINT public_keys[5];
|
|
||||||
size_t public_keys_count = sizeof(public_keys)/sizeof(public_keys[0]);
|
|
||||||
size_t sign_index = 2, i;
|
|
||||||
uint8_t dgst[32];
|
|
||||||
uint8_t sig[9 + (2 + 33) * (1 + sizeof(public_keys)/sizeof(public_keys[0]))];
|
|
||||||
size_t siglen = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < public_keys_count; i++) {
|
|
||||||
SM2_KEY key;
|
|
||||||
sm2_key_generate(&key);
|
|
||||||
memcpy(&public_keys[i], &(key.public_key), sizeof(SM2_POINT));
|
|
||||||
|
|
||||||
if (i == sign_index) {
|
|
||||||
memcpy(&sign_key, &key, sizeof(SM2_KEY));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sm2_ring_sign(&sign_key, public_keys, public_keys_count, dgst, sig, &siglen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (sm2_ring_verify(public_keys, 5, dgst, sig, siglen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s() ok\n", __FUNCTION__);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int test_sm2_ring_sign_crosscheck(void)
|
|
||||||
{
|
|
||||||
SM2_KEY sign_key;
|
|
||||||
SM2_POINT public_key;
|
|
||||||
uint8_t dgst[32];
|
|
||||||
uint8_t sig[SM2_MAX_SIGNATURE_SIZE];
|
|
||||||
size_t siglen = 0;
|
|
||||||
|
|
||||||
sm2_key_generate(&sign_key);
|
|
||||||
public_key = sign_key.public_key;
|
|
||||||
|
|
||||||
if (sm2_ring_sign(&sign_key, &public_key, 1, dgst, sig, &siglen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (sm2_ring_verify(&public_key, 1, dgst, sig, siglen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s() ok\n", __FUNCTION__);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int test_sm2_ring_sign_update(void)
|
|
||||||
{
|
|
||||||
SM2_KEY keys[5];
|
|
||||||
SM2_RING_SIGN_CTX sign_ctx;
|
|
||||||
SM2_RING_SIGN_CTX verify_ctx;
|
|
||||||
size_t public_keys_count = sizeof(keys)/sizeof(keys[0]);
|
|
||||||
char *id = "Alice";
|
|
||||||
uint8_t msg[128] = {0};
|
|
||||||
uint8_t sig[9 + (2 + 33) * (1 + sizeof(keys)/sizeof(keys[0]))];
|
|
||||||
size_t siglen = 0;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = 0; i < public_keys_count; i++) {
|
|
||||||
sm2_key_generate(&keys[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sm2_ring_sign_init(&sign_ctx, &keys[0], id, strlen(id)) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
for (i = 1; i < public_keys_count; i++) {
|
|
||||||
if (sm2_ring_sign_add_signer(&sign_ctx, &keys[i]) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sm2_ring_sign_update(&sign_ctx, msg, 32) != 1
|
|
||||||
|| sm2_ring_sign_update(&sign_ctx, msg + 32, 32) != 1
|
|
||||||
|| sm2_ring_sign_update(&sign_ctx, msg + 64, 64) != 1
|
|
||||||
|| sm2_ring_sign_finish(&sign_ctx, sig, &siglen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sm2_ring_verify_init(&verify_ctx, id, strlen(id)) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
for (i = 0; i < public_keys_count; i++) {
|
|
||||||
if (sm2_ring_verify_add_signer(&verify_ctx, &keys[i]) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sm2_ring_verify_update(&verify_ctx, msg, sizeof(msg)) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (sm2_ring_verify_finish(&verify_ctx, sig, siglen) != 1) {
|
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s() ok\n", __FUNCTION__);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
if (test_sm2_ring_do_sign() != 1) { error_print(); return -1; }
|
|
||||||
if (test_sm2_ring_sign() != 1) { error_print(); return -1; }
|
|
||||||
if (test_sm2_ring_sign_crosscheck() != 1) { error_print(); return -1; }
|
|
||||||
if (test_sm2_ring_sign_update() != 1) { error_print(); return -1; }
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user