#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;
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;
sm2_bn_from_bytes(r, sig->r);
sm2_bn_from_bytes(s, sig->s);
sm2_fn_add(u, r, s);
sm2_fn_inv(u, u);
sm2_fn_mul(v, u, s);
sm2_fn_neg(v, v);
sm2_bn_from_bytes(e, dgst);
if (sm2_bn_cmp(e, SM2_N) >= 0) {
sm2_bn_sub(e, e, SM2_N);
}
sm2_fn_sub(x1, r, e);
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);
sm2_jacobian_point_mul_sum(&P, u, &R, v);
sm2_jacobian_point_to_bytes(&P, (uint8_t *)&points[0]);
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;
sm2_bn_sub(SM2_P_SUB_N, SM2_P, SM2_N);
if (sm2_bn_cmp(x1, SM2_P_SUB_N) < 0) {
sm2_bn_add(x1, x1, SM2_N);
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);
sm2_jacobian_point_mul_sum(&P, u, &R, v);
sm2_jacobian_point_to_bytes(&P, (uint8_t *)&points[2]);
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;
}
int sm2_signature_conjugate(const SM2_SIGNATURE *sig, SM2_SIGNATURE *new_sig)
{
SM2_Fn r;
SM2_Fn 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;
}