diff --git a/crypto/sm9/sm9_lcl.h b/crypto/sm9/sm9_lcl.h index 403cba01..38c5e02b 100644 --- a/crypto/sm9/sm9_lcl.h +++ b/crypto/sm9/sm9_lcl.h @@ -76,6 +76,16 @@ extern "C" { #endif + +const BIGNUM *SM9_get0_prime(void); +const BIGNUM *SM9_get0_order(void); +const BIGNUM *SM9_get0_trace(void); +const BIGNUM *SM9_get0_generator2_x0(void); +const BIGNUM *SM9_get0_generator2_x1(void); +const BIGNUM *SM9_get0_generator2_y0(void); +const BIGNUM *SM9_get0_generator2_y1(void); + + struct SM9PublicParameters_st { ASN1_OBJECT *curve; BIGNUM *p; diff --git a/crypto/sm9/sm9_params.c b/crypto/sm9/sm9_params.c index 6047a3a8..5bc161b5 100644 --- a/crypto/sm9/sm9_params.c +++ b/crypto/sm9/sm9_params.c @@ -55,14 +55,29 @@ #include -#include "bn_lcl.h" +#include "../bn/bn_lcl.h" #include "internal/cryptlib.h" #define BN_SM9_BN256_TOP (256+BN_BITS2-1)/BN_BITS2 #define BN_SM9_TRACE_TOP (66+BN_BITS2-1)/BN_BITS2 +#define BN_SM9_FINAL_EXPO_TOP (66+BN_BITS2-1)/BN_BITS2 + +#if BN_BITS2 == 64 +static const BN_ULONG _sm9bn256v1_prime[BN_SM9_BN256_TOP] = { + 0xE56F9B27E351457DULL, 0x21F2934B1A7AEEDBULL, + 0xD603AB4FF58EC745ULL, 0xB640000002A3A6F1ULL, +}; + +static const BN_ULONG _sm9bn256v1_order[BN_SM9_BN256_TOP] = { + 0xE56EE19CD69ECF25ULL, 0x49F2934B18EA8BEEULL, + 0xD603AB4FF58EC744ULL, 0xB640000002A3A6F1ULL, +}; + +static const BN_ULONG _sm9bn256v1_trace[BN_SM9_TRACE_TOP] = { + 0x400000000215D93EULL, 0x02ULL, +}; -#if BN_BITS == 64 static const BN_ULONG _sm9bn256v1_x2[][BN_SM9_BN256_TOP] = { {0xF9B7213BAF82D65BULL, 0xEE265948D19C17ABULL, 0xD2AAB97FD34EC120ULL, 0x3722755292130B08ULL}, @@ -77,11 +92,25 @@ static const BN_ULONG _sm9bn256v1_y2[][BN_SM9_BN256_TOP] = { 0x66BA0D262CBEE6EDULL, 0x17509B092E845C12ULL} }; -static const BN_ULONG _sm9bn256v1_trace[BN_SM9_TRACE_TOP] = { +static const BN_ULONG _sm9bn256v1_final_expo[BN_SM9_FINAL_EXPO_TOP] = { 0x400000000215D93EULL, 0x02ULL, }; #elif BN_BITS2 == 32 +static const BN_ULONG _sm9bn256v1_prime[BN_SM9_BN256_TOP] = { + 0xE351457D, 0xE56F9B27, 0x1A7AEEDB, 0x21F2934B, + 0xF58EC745, 0xD603AB4F, 0x02A3A6F1, 0xB6400000, +}; + +static const BN_ULONG _sm9bn256v1_order[BN_SM9_BN256_TOP] = { + 0xD69ECF25, 0xE56EE19C, 0x18EA8BEE, 0x49F2934B, + 0xF58EC744, 0xD603AB4F, 0x02A3A6F1, 0xB6400000, +}; + +static const BN_ULONG _sm9bn256v1_trace[BN_SM9_TRACE_TOP] = { + 0x0215D93E, 0x40000000, 0x02, +}; + static const BN_ULONG _sm9bn256v1_x2[][BN_SM9_BN256_TOP] = { {0xAF82D65B, 0xF9B7213B, 0xD19C17AB, 0xEE265948, 0xD34EC120, 0xD2AAB97F, 0x92130B08, 0x37227552}, @@ -96,14 +125,46 @@ static const BN_ULONG _sm9bn256v1_y2[][BN_SM9_BN256_TOP] = { 0x2CBEE6ED, 0x66BA0D26, 0x2E845C12, 0x17509B09} }; -static const BN_ULONG _sm9bn256v1_trace[BN_SM9_TRACE_TOP] = { - 0x0215D93E, 0x40000000, 0x02, +static const BN_ULONG _sm9bn256v1_final_expo[BN_SM9_FINAL_EXPO_TOP] = { + 0, 0, 0 }; #else # error "unsupported BN_BITS2" #endif +static const BIGNUM _bignum_sm9bn256v1_prime = { + (BN_ULONG *)_sm9bn256v1_prime, + BN_SM9_BN256_TOP, + BN_SM9_BN256_TOP, + 0, + BN_FLG_STATIC_DATA +}; + +static const BIGNUM _bignum_sm9bn256v1_order = { + (BN_ULONG *)_sm9bn256v1_order, + BN_SM9_BN256_TOP, + BN_SM9_BN256_TOP, + 0, + BN_FLG_STATIC_DATA +}; + +static const BIGNUM _bignum_sm9bn256v1_trace = { + (BN_ULONG *)_sm9bn256v1_trace, + BN_SM9_TRACE_TOP, + BN_SM9_TRACE_TOP, + 0, + BN_FLG_STATIC_DATA +}; + +static const BIGNUM _bignum_sm9bn256v1_final_expo = { + (BN_ULONG *)_sm9bn256v1_final_expo, + BN_SM9_FINAL_EXPO_TOP, + BN_SM9_FINAL_EXPO_TOP, + 0, + BN_FLG_STATIC_DATA +}; + static const BIGNUM _bignum_sm9bn256v1_x20 = { (BN_ULONG *)_sm9bn256v1_x2[0], BN_SM9_BN256_TOP, @@ -136,22 +197,42 @@ static const BIGNUM _bignum_sm9bn256v1_y21 = { BN_FLG_STATIC_DATA }; -static const BIGNUM _bignum_sm9bn256v1_trace = { - (BN_ULONG *)_sm9bn256v1_trace, // IS THIS CORRECT?? - BN_SM9_TRACE_TOP, - BN_SM9_TRACE_TOP, - 0, - BN_FLG_STATIC_DATA -}; +const BIGNUM *SM9_get0_generator2_x0(void) +{ + return &_bignum_sm9bn256v1_x20; +} -// we should not put it here -const point_t _sm9bn256v1_g2 = { - {&_bignum_sm9bn256v1_x20, &_bignum_sm9bn256v1_x21}, - {&_bignum_sm9bn256v1_y20, &_bignum_sm9bn256v1_y21}, - {&_bignum_one, &_bignum_zero} -}; +const BIGNUM *SM9_get0_generator2_x1(void) +{ + return &_bignum_sm9bn256v1_x21; +} +const BIGNUM *SM9_get0_generator2_y0(void) +{ + return &_bignum_sm9bn256v1_y20; +} +const BIGNUM *SM9_get0_generator2_y1(void) +{ + return &_bignum_sm9bn256v1_y21; +} +const BIGNUM *SM9_get0_prime(void) +{ + return &_bignum_sm9bn256v1_prime; +} +const BIGNUM *SM9_get0_order(void) +{ + return &_bignum_sm9bn256v1_order; +} +const BIGNUM *SM9_get0_trace(void) +{ + return &_bignum_sm9bn256v1_trace; +} + +const BIGNUM *SM9_get0_final_exponent(void) +{ + return &_bignum_sm9bn256v1_final_expo; +} diff --git a/crypto/sm9/sm9_rate.c b/crypto/sm9/sm9_rate.c index 7ca68c8d..cf30c62e 100644 --- a/crypto/sm9/sm9_rate.c +++ b/crypto/sm9/sm9_rate.c @@ -53,6 +53,7 @@ #include #include #include +#include "sm9_lcl.h" typedef BIGNUM *fp2_t[2]; typedef fp2_t fp4_t[2]; @@ -97,13 +98,13 @@ static void fp2_clear_cleanup(fp2_t a) a[1] = NULL; } -static int fp2_is_zero(fp2_t a) +static int fp2_is_zero(const fp2_t a) { return BN_is_zero(a[0]) && BN_is_zero(a[1]); } -static int fp2_is_one(fp2_t a) +static int fp2_is_one(const fp2_t a) { return BN_is_one(a[0]) && BN_is_zero(a[1]); @@ -142,7 +143,7 @@ static int fp2_set_u(fp2_t r) static int fp2_set_bn(fp2_t r, const BIGNUM *a) { BN_zero(r[1]); - return BN_copy(r[0], a); + return BN_copy(r[0], a) != NULL; } static int fp2_set_word(fp2_t r, unsigned long a) @@ -156,6 +157,20 @@ static int fp2_equ(const fp2_t a, const fp2_t b) return !BN_cmp(a[0], b[0]) && !BN_cmp(a[1], b[1]); } +static int fp2_add_word(fp2_t r, const fp2_t a, unsigned long b, const BIGNUM *p, BN_CTX *ctx) +{ + BIGNUM *w = NULL; + if (!(w = BN_CTX_get(ctx)) + || !BN_set_word(w, b) + || !BN_mod_add(r[0], a[0], w, p, ctx) + || !BN_copy(r[1], a[1])) { + BN_free(w); + return 0; + } + BN_free(w); + return 1; +} + static int fp2_add(fp2_t r, const fp2_t a, const fp2_t b, const BIGNUM *p, BN_CTX *ctx) { return BN_mod_add(r[0], a[0], b[0], p, ctx) @@ -168,6 +183,14 @@ static int fp2_dbl(fp2_t r, const fp2_t a, const BIGNUM *p, BN_CTX *ctx) && BN_mod_add(r[1], a[1], a[1], p, ctx); } +static int fp2_tri(fp2_t r, const fp2_t a, const BIGNUM *p, BN_CTX *ctx) +{ + return BN_mod_add(r[0], a[0], a[0], p, ctx) + && BN_mod_add(r[0], r[0], a[0], p, ctx) + && BN_mod_add(r[1], a[1], a[1], p, ctx) + && BN_mod_add(r[1], r[1], a[1], p, ctx); +} + static int fp2_sub(fp2_t r, const fp2_t a, const fp2_t b, const BIGNUM *p, BN_CTX *ctx) { return BN_mod_sub(r[0], a[0], b[0], p, ctx) @@ -180,19 +203,13 @@ static int fp2_neg(fp2_t r, const fp2_t a, const BIGNUM *p) && BN_sub(r[1], p, a[1]); } -static void fp2_conjugate(fp2_t r, const fp2_t a, const BIGNUM *p) -{ - return fp2_copy(r[0], a[0]) - && fp2_neg(r[1], a[1], p); -} - static int fp2_mul(fp2_t r, const fp2_t a, const fp2_t b, const BIGNUM *p, BN_CTX *ctx) { BIGNUM *t = NULL; if (!(t = BN_CTX_get(ctx)) /* r0 = a0 * b0 - 2 * a1 * b1 */ || !BN_mod_mul(r[0], a[0], b[0], p, ctx) - || !BN_mod_sqr(t, a[1], b[1], p, ctx) + || !BN_mod_mul(t, a[1], b[1], p, ctx) || !BN_mod_add(t, t, t, p, ctx) || !BN_mod_sub(r[0], r[0], t, p, ctx) @@ -207,7 +224,7 @@ static int fp2_mul(fp2_t r, const fp2_t a, const fp2_t b, const BIGNUM *p, BN_CT return 1; } -static int fp2_mul_u(fp2_t r, fp2_t a, fp2_t b, const BIGNUM *p, BN_CTX *ctx) +static int fp2_mul_u(fp2_t r, const fp2_t a, const fp2_t b, const BIGNUM *p, BN_CTX *ctx) { BIGNUM *t = NULL; if (!(t = BN_CTX_get(ctx)) @@ -293,6 +310,8 @@ static int fp2_inv(fp2_t r, const fp2_t a, const BIGNUM *p, BN_CTX *ctx) } } else { + BIGNUM *k = NULL; + BIGNUM *t = NULL; if (!(k = BN_CTX_get(ctx)) || !(t = BN_CTX_get(ctx)) @@ -328,11 +347,12 @@ static int fp4_init(fp4_t a, BN_CTX *ctx) { int r; r = fp2_init(a[0], ctx); - r &&= fp2_init(a[1], ctx); + r &= fp2_init(a[1], ctx); if (!r) { fp2_cleanup(a[0]); fp2_cleanup(a[1]); } + return r; } static void fp4_cleanup(fp4_t a) @@ -368,7 +388,7 @@ static void fp4_set_zero(fp4_t r) static int fp4_set_one(fp4_t r) { fp2_set_zero(r[1]); - return fd2_set_one(r[0]); + return fp2_set_one(r[0]); } static int fp4_set_bn(fp4_t r, const BIGNUM *a) @@ -417,6 +437,7 @@ static int fp4_equ(const fp4_t a, const fp4_t b) { return fp2_equ(a[0], b[0]) && fp2_equ(a[1], b[1]); +} static int fp4_add(fp4_t r, const fp4_t a, const fp4_t b, const BIGNUM *p, BN_CTX *ctx) { @@ -436,10 +457,10 @@ static int fp4_sub(fp4_t r, const fp4_t a, const fp4_t b, const BIGNUM *p, BN_CT && fp2_sub(r[1], a[1], b[1], p, ctx); } -static int fp4_neg(fp4_t r, const fp4_t a, const BIGNUM *p, BN_CTX *ctx) +static int fp4_neg(fp4_t r, const fp4_t a, const BIGNUM *p) { - return fp2_neg(r[0], a[0], p, ctx) - &&fp2_neg(r[1], a[1], p, ctx); + return fp2_neg(r[0], a[0], p) + &&fp2_neg(r[1], a[1], p); } static int fp4_mul(fp4_t r, const fp4_t a, const fp4_t b, const BIGNUM *p, BN_CTX *ctx) @@ -505,17 +526,17 @@ static int fp4_sqr_v(fp4_t r, const fp4_t a, const BIGNUM *p, BN_CTX *ctx) fp2_t t; if (!fp2_init(t, ctx) /* r[0] = 2 * (a[0] * a[1]) */ - || !fp2_mul_u(t0, a[0], a[1], p, ctx) - || !fp2_dbl(r[0], t0, p, ctx) + || !fp2_mul_u(t, a[0], a[1], p, ctx) + || !fp2_dbl(r[0], t, p, ctx) /* r[1] = a[0]^2 + a[1]^2 * u */ || !fp2_sqr(r[1], a[0], p, ctx) || !fp2_sqr_u(t, a[1], p, ctx) || !fp2_add(r[1], r[1], t, p, ctx)) { - fp_cleanup(t); + fp2_cleanup(t); return 0; } - fp_cleanup(t); + fp2_cleanup(t); return 1; } @@ -531,7 +552,7 @@ static int fp4_inv(fp4_t r, const fp4_t a, const BIGNUM *p, BN_CTX *ctx) /* r[0] = -(a[0] * k) */ || !fp2_mul(r[0], a[0], k, p, ctx) - || !fp2_neg(r[0], r[0], p, ctx) + || !fp2_neg(r[0], r[0], p) /* r[1] = a[1] * k */ || !fp2_mul(r[1], a[1], k, p, ctx)) { @@ -546,8 +567,8 @@ static int fp12_init(fp12_t a, BN_CTX *ctx) { int r; r = fp4_init(a[0], ctx); - r &&= fp4_init(a[1], ctx); - r &&= fp4_init(a[2], ctx); + r &= fp4_init(a[1], ctx); + r &= fp4_init(a[2], ctx); if (!r) { fp4_cleanup(a[0]); fp4_cleanup(a[1]); @@ -572,16 +593,16 @@ static void fp12_clear_cleanup(fp12_t a) static int fp12_is_zero(const fp12_t a) { - return fp12_is_zero(a[0]) - && fp12_is_zero(a[1]) - && fp12_is_zero(a[2]); + return fp4_is_zero(a[0]) + && fp4_is_zero(a[1]) + && fp4_is_zero(a[2]); } static int fp12_is_one(const fp12_t a) { - return fp12_is_one(a[0]) - && fp12_is_zero(a[1]) - && fp12_is_zero(a[2]); + return fp4_is_one(a[0]) + && fp4_is_zero(a[1]) + && fp4_is_zero(a[2]); } static void fp12_set_zero(fp12_t r) @@ -703,11 +724,11 @@ static int fp12_sub(fp12_t r, const fp12_t a, const fp12_t b, const BIGNUM *p, B && fp4_sub(r[2], a[2], b[2], p, ctx); } -static int fp12_neg(fp12_t r, const fp12_t a, const BIGNUM *p, BN_CTX *ctx) +static int fp12_neg(fp12_t r, const fp12_t a, const BIGNUM *p) { - return fp4_neg(r[0], a[0], p, ctx) - && fp4_neg(r[1], a[1], p, ctx) - && fp4_neg(r[2], a[2], p, ctx); + return fp4_neg(r[0], a[0], p) + && fp4_neg(r[1], a[1], p) + && fp4_neg(r[2], a[2], p); } static int fp12_mul(fp12_t r, const fp12_t a, const fp12_t b, const BIGNUM *p, BN_CTX *ctx) @@ -748,21 +769,21 @@ static int fp12_sqr(fp12_t r, const fp12_t a, const BIGNUM *p, BN_CTX *ctx) if (!(fp4_init(t, ctx)) /* r0 = a0^2 + 2*a1*a2*v */ || !fp4_sqr(r[0], a[0], p, ctx) - || ! fp4_mul_v(t, a[1], a[2], p, ctx) - || ! fp4_dbl(t, t, p, ctx) - || ! fp4_add(r[0], t, p, ctx) + || !fp4_mul_v(t, a[1], a[2], p, ctx) + || !fp4_dbl(t, t, p, ctx) + || !fp4_add(r[0], r[0], t, p, ctx) /* r1 = 2*a0*a1 + a^2 * v */ - || ! fp4_mul(r[1], a[0], a[1], p, ctx) - || ! fp4_dbl(r[1], r[1], p, ctx) - || ! fp4_sqr_v(t, a[2], p, ctx) - || ! fp4_add(r[1], r[1], t, p, ctx) + || !fp4_mul(r[1], a[0], a[1], p, ctx) + || !fp4_dbl(r[1], r[1], p, ctx) + || !fp4_sqr_v(t, a[2], p, ctx) + || !fp4_add(r[1], r[1], t, p, ctx) /* r2 = 2*a0*a2 + a1^2*/ - || ! fp4_mul(r[2], a[0], a[2], p, ctx) - || ! fp4_dbl(r[2], r[2], p, ctx) - || ! fp4_sqr(t, a[1], p, ctx) - || ! fp4_add(r[2], t, p, ctx)) { + || !fp4_mul(r[2], a[0], a[2], p, ctx) + || !fp4_dbl(r[2], r[2], p, ctx) + || !fp4_sqr(t, a[1], p, ctx) + || !fp4_add(r[2], r[2], t, p, ctx)) { fp4_cleanup(t); return 0; @@ -775,6 +796,10 @@ static int fp12_inv(fp12_t r, const fp12_t a, const BIGNUM *p, BN_CTX *ctx) { if (fp4_is_zero(a[2])) { fp4_t k; + fp4_t t; + if (!fp4_init(t, ctx)) { + return 0; + } if (!(fp4_init(k, ctx)) /* k = (a0^3 + a1^3 * v)^-1 */ || !fp4_sqr(k, a[0], p, ctx) @@ -791,16 +816,18 @@ static int fp12_inv(fp12_t r, const fp12_t a, const BIGNUM *p, BN_CTX *ctx) /* r1 = -(a0 * a1 * k) */ || !fp4_mul(r[0], a[0], a[1], p, ctx) || !fp4_mul(r[0], r[0], k, p, ctx) - || fp4_neg(r[0], r[0], p, ctx) + || fp4_neg(r[0], r[0], p) /* r2 = a1^2 * k */ || !fp4_sqr(r[2], a[1], p, ctx) || !fp4_mul(r[2], r[2], k, p, ctx)) { fp4_cleanup(k); + fp4_cleanup(t); return 0; } fp4_cleanup(k); + fp4_cleanup(t); return 1; } else { @@ -812,6 +839,8 @@ static int fp12_inv(fp12_t r, const fp12_t a, const BIGNUM *p, BN_CTX *ctx) || !(fp4_init(t2, ctx)) || !(fp4_init(t3, ctx)) + // CHECK THIS!!!!! + /* t0 = a1^2 - a0 * a1 */ || !fp4_sqr(t0, a[1], p, ctx) || !fp4_mul(t1, a[0], a[2], p, ctx) @@ -829,8 +858,8 @@ static int fp12_inv(fp12_t r, const fp12_t a, const BIGNUM *p, BN_CTX *ctx) /* t3 = a2 * (t1^2 - t0 * t2)^-1 */ || !fp4_sqr(t1, t1, p, ctx) - || !fp4_mul(t4, t0, t2, p, ctx) - || !fp4_sub(t1, t1, t5, p, ctx) + || !fp4_mul(r[0], t0, t2, p, ctx) + || !fp4_sub(t1, t1, r[0], p, ctx) || !fp4_mul(t3, a[2], t3, p, ctx) || !fp4_inv(t3, t3, p, ctx) @@ -861,9 +890,15 @@ static int fp12_inv(fp12_t r, const fp12_t a, const BIGNUM *p, BN_CTX *ctx) return 1; } +static int fp12_div(fp12_t r, const fp12_t a, const fp12_t b, const BIGNUM *p, BN_CTX *ctx) +{ + return fp12_inv(r, b, p, ctx) + && fp12_mul(r, a, r, p, ctx); +} + static int fp12_pow(fp12_t r, const fp12_t a, const BIGNUM *k, const BIGNUM *p, BN_CTX *ctx) { - int n; + int n, i; if (BN_is_zero(k)) { return fp12_set_one(r); @@ -894,9 +929,9 @@ static int point_init(point_t P, BN_CTX *ctx) { int r; r = fp2_init(P.X, ctx); - r &&= fp2_init(P.Y, ctx); - r &&= fp2_init(P.Z, ctx); - r &&= fp2_set_one(P.Y, ctx); + r &= fp2_init(P.Y, ctx); + r &= fp2_init(P.Z, ctx); + r &= fp2_set_one(P.Y); if (!r) { fp2_cleanup(P.X); fp2_cleanup(P.Y); @@ -915,6 +950,13 @@ static void point_cleanup(point_t P) fp2_cleanup(P.Z); } +static int point_copy(point_t R, const point_t P) +{ + return fp2_copy(R.X, P.X) + && fp2_copy(R.Y, P.Y) + && fp2_copy(R.Z, P.Z); +} + static int point_set_infinity(point_t P) { fp2_set_zero(P.X); @@ -936,19 +978,41 @@ static int point_equ(const point_t P, const point_t Q) && fp2_equ(P.Z, Q.Z); } -static int point_is_on_curve(point_t P, BN_CTX *ctx) +static int point_set_affine_coordinates(point_t P, const fp2_t x, const fp2_t y) +{ + return fp2_copy(P.X, x) + && fp2_copy(P.Y, y) + && fp2_set_one(P.Z); +} + +static int point_set_affine_coordinates_bignums(point_t P, + const BIGNUM *x0, const BIGNUM *x1, const BIGNUM *y0, const BIGNUM *y1) +{ + return fp2_set(P.X, x0, x1) + && fp2_set(P.Y, y0, y1) + && fp2_set_one(P.Z); +} + +static int point_get_affine_coordinates(const point_t P, fp2_t x, fp2_t y) +{ + return fp2_copy(x, P.X) + && fp2_copy(y, P.Y) + && fp2_is_one(P.Z); +} + +static int point_is_on_curve(point_t P, const BIGNUM *p, BN_CTX *ctx) { int r; fp2_t x, y, t; r = fp2_init(x, ctx); - r &&= fp2_init(y, ctx); - r &&= fp2_init(t, ctx); + r &= fp2_init(y, ctx); + r &= fp2_init(t, ctx); if (!r) { goto end; } - if (!point_get_affine_coordinates(P, x, y, p, ctx) + if (!point_get_affine_coordinates(P, x, y) || !fp2_sqr(t, x, p, ctx) || !fp2_mul(x, x, t, p, ctx) || !fp2_add_word(x, x, 5, p, ctx) @@ -965,33 +1029,18 @@ end: return r; } -static int point_set_affine_coordinates(point_t P, const fp2_t x, const fp2_t y) -{ - return fp2_copy(P.X, x) - && fp2_copy(P.Y, y) - && fp2_set_one(P.Z); -} - -static int point_get_affine_coordinates(const point_t P, fp2_t x, fp2_t y) -{ - return fp2_copy(x, P.X) - && fp2_copy(y, P.y) - && fp2_is_one(P.Z); -} - static int point_dbl(point_t R, const point_t P, const BIGNUM *p, BN_CTX *ctx) { int r; fp2_t x3, y3, x1, y1, lambda, t; r = 1; - r &&= fp2_init(x1, ctx); - r &&= fp2_init(y1, ctx); - r &&= fp2_init(x3, ctx); - r &&= fp2_init(y3, ctx); - r &&= fp2_init(t0, ctx); - r &&= fp2_init(t1, ctx); - r &&= fp2_init(lambda, ctx); + r &= fp2_init(x1, ctx); + r &= fp2_init(y1, ctx); + r &= fp2_init(x3, ctx); + r &= fp2_init(y3, ctx); + r &= fp2_init(lambda, ctx); + r &= fp2_init(t, ctx); if (!r) { goto end; } @@ -1027,7 +1076,7 @@ end: fp2_cleanup(x1); fp2_cleanup(y1); fp2_cleanup(x3); - fp2_clenaup(y3); + fp2_cleanup(y3); fp2_cleanup(lambda); fp2_cleanup(t); return r; @@ -1043,8 +1092,7 @@ static int point_add(point_t R, const point_t P, const point_t Q, const BIGNUM * fp2_t x3; fp2_t y3; fp2_t lambda; - fp2_t t0; - fp2_t t1; + fp2_t t; if (point_is_at_infinity(P)) { return point_copy(R, Q); @@ -1060,14 +1108,14 @@ static int point_add(point_t R, const point_t P, const point_t Q, const BIGNUM * } r = 1; - r &&= fp2_init(x1, ctx); - r &&= fp2_init(y1, ctx); - r &&= fp2_init(x2, ctx); - r &&= fp2_init(y2, ctx); - r &&= fp2_init(x3, ctx); - r &&= fp2_init(y3, ctx); - r &&= fp2_init(lambda, ctx); - r &&= fp2_init(t, ctx); + r &= fp2_init(x1, ctx); + r &= fp2_init(y1, ctx); + r &= fp2_init(x2, ctx); + r &= fp2_init(y2, ctx); + r &= fp2_init(x3, ctx); + r &= fp2_init(y3, ctx); + r &= fp2_init(lambda, ctx); + r &= fp2_init(t, ctx); if (!r) { goto end; } @@ -1116,10 +1164,10 @@ end: return r; } -static int point_neg(point_t R, const point_t P) +static int point_neg(point_t R, const point_t P, const BIGNUM *p) { return fp2_copy(R.X, P.X) - && fp2_neg(R.y, P.y) + && fp2_neg(R.Y, P.Y, p) && fp2_copy(R.Z, P.Z); } @@ -1127,7 +1175,7 @@ static int point_sub(point_t R, const point_t P, const point_t Q, const BIGNUM * { point_t T; if (!point_init(T, ctx) - || !point_neg(T, Q) + || !point_neg(T, Q, p) || !point_add(R, P, T, p, ctx)) { point_cleanup(T); return 0; @@ -1136,12 +1184,10 @@ static int point_sub(point_t R, const point_t P, const point_t Q, const BIGNUM * return 1; } -static void point_mul_generator(point_t R, const BIGNUM *k, const BIGNUM *p, BN_CTX *ctx) -{ -} - static int point_mul(point_t R, const BIGNUM *k, const point_t P, const BIGNUM *p, BN_CTX *ctx) { + int i, n; + if (BN_is_zero(k)) { return point_set_infinity(R); } @@ -1164,6 +1210,20 @@ static int point_mul(point_t R, const BIGNUM *k, const point_t P, const BIGNUM * return 1; } +static int point_mul_generator(point_t R, const BIGNUM *k, const BIGNUM *p, BN_CTX *ctx) +{ + point_t G; + + point_init(G, ctx); + point_set_affine_coordinates_bignums(G, + SM9_get0_generator2_x0, + SM9_get0_generator2_x1, + SM9_get0_generator2_y0, + SM9_get0_generator2_y1); + + return point_mul(R, k, G, p, ctx); +} + static int eval_tangent(fp12_t r, const fp12_t xP, const fp12_t yP, const BIGNUM *xQ, const BIGNUM *yQ, const BIGNUM *p, BN_CTX *ctx) @@ -1172,10 +1232,10 @@ static int eval_tangent(fp12_t r, const fp12_t xP, const fp12_t yP, fp12_t x, y, lambda, t; ret = 1; - ret &&= fp12_init(x, ctx); - ret &&= fp12_init(y, ctx); - ret &&= fp12_init(lambda, ctx); - ret &&= fp12_init(t, ctx); + ret &= fp12_init(x, ctx); + ret &= fp12_init(y, ctx); + ret &= fp12_init(lambda, ctx); + ret &= fp12_init(t, ctx); if (!ret) { goto end; } @@ -1195,7 +1255,7 @@ static int eval_tangent(fp12_t r, const fp12_t xP, const fp12_t yP, || !fp12_add(r, r, yP, p, ctx)) { goto end; } - ret = 1 + ret = 1; end: fp12_cleanup(x); @@ -1214,10 +1274,10 @@ static int eval_line(fp12_t r, const fp12_t xT, const fp12_t yT, fp12_t x, y, lambda, t; ret = 1; - ret &&= fp12_init(x, ctx); - ret &&= fp12_init(y, ctx); - ret &&= fp12_init(lambda, ctx); - ret &&= fp12_init(t, ctx); + ret &= fp12_init(x, ctx); + ret &= fp12_init(y, ctx); + ret &= fp12_init(lambda, ctx); + ret &= fp12_init(t, ctx); if (!ret) { goto end; } @@ -1246,53 +1306,101 @@ end: return ret; } -static void frob(fp12_t xR, fp12_t yR, const point_t P, const BIGNUM *p, BN_CTX *ctx) +static int point_get_ext_affine_coordinates(const point_t *P, fp12_t x, fp12_t y, const BIGNUM *p, BN_CTX *ctx) { - fp2_t x, y; - fp12_t t0, t1; + int r; + fp2_t xP; + fp2_t yP; + fp12_t wem2; + fp12_t wem3; - point_get_affine_coordinates(x, y, R); + r = 1; + r &= fp2_init(xP, ctx); + r &= fp2_init(yP, ctx); + r &= fp12_init(wem2, ctx); + r &= fp12_init(wem2, ctx); + if (!r) { + goto end; + } - fp2_conjugate(x); - fp2_conjugate(y); - fp12_set_fp(t0, x); - fp12_set_fp(t1, y); - fp12_mul(xR, t0, w2p); - fp12_mul(yR, t1, w3p); + r = 0; + if (!point_get_affine_coordinates(P, xP, yP) + || !fp12_set_fp2(x, xP) + || !fp12_set_fp2(y, yP) + + /* x = x * w^-2 */ + || !fp12_set_w2(wem2) + || !fp12_inv(wem2, wem2, p, ctx) + || !fp12_mul(x, x, wem2, p, ctx) + + /* y = y * w^-3 */ + || !fp12_set_v(wem3) + || !fp12_inv(wem3, wem3, p, ctx) + || !fp12_mul(y, y, wem3, p, ctx)) { + goto end; + } + r = 1; + +end: + fp2_cleanup(xP); + fp2_cleanup(yP); + fp12_cleanup(wem2); + fp12_cleanup(wem3); + return r; } -static void frob_twice(fp12_t xR, fp12_t yR, const point_t P, const BIGNUM *p, BN_CTX *ctx) +static int point_frob(const point_t P, fp12_t x, fp12_t y, const BIGNUM *p, BN_CTX *ctx) { - fp2_t x, y; - fp12_t t0, t1; - - - point_get_affine_coordinates(x, y, R); - - + return point_get_ext_affine_coordinates(P, x, y, p, ctx) + && fp12_pow(x, x, p, p, ctx) + && fp12_pow(y, y, p, p, ctx); } -static void final_expo(fp12_t r, const fp12_t a, const BIGNUM *p, BN_CTX *ctx) +static int point_frob_twice(const point_t P, fp12_t x, fp12_t y, const BIGNUM *p, BN_CTX *ctx) { - fp12_copy(r, a); - for (i = 0; i < sizeof(ebits); i++) { - fp12_sqr_to(r); - if (ebits[i]) { - fp12_mul_to(r, a); + return point_frob(P, x, y, p, ctx) + && fp12_pow(x, x, p, p, ctx) + && fp12_pow(y, y, p, p, ctx); +} + +static int final_expo(fp12_t r, const fp12_t a, const BIGNUM *k, const BIGNUM *p, BN_CTX *ctx) +{ + int i, n; + + if (!fp12_copy(r, a)) { + return 0; + } + + n = BN_num_bits(k); + for (i = n - 2; i >= 0; i--) { + if (!fp12_sqr(r, r, p, ctx)) { + return 0; + } + + if (BN_is_bit_set(k, i)) { + if (!fp12_mul(r, r, a, p, ctx)) { + return 0; + } } } + + return 1; } -static void rate(fp12_t r, const point_t Q, const fp_t xP, const fp_t yP) +static int rate(fp12_t r, const point_t Q, const BIGNUM *xP, const BIGNUM *yP, + const BIGNUM *p, BN_CTX *ctx) { int i; - + point_t T; fp12_t f, g; + point_init(T, ctx); + point_copy(T, Q); fp12_set_one(f); - for (i = 0; i < sizeof(abits); i++) { + + for (i = n - 2; i >= 0; i++) { eval(g, T, T, xP, yP); fp12_sqr_to(f); fp12_mul_to(f, g); @@ -1318,44 +1426,32 @@ static void rate(fp12_t r, const point_t Q, const fp_t xP, const fp_t yP) //point_add_to(T, Q2); final_expo(r, f); + return 0; } -/* - * the following API should be exported: - * 1. mul generator P2/or G2, over E'(F_p^2), - * 2. e(P, G1) where G1 is a fixed generator over E(Fp) - * 3. fp12_pow(), g^k, where g in Fp12, k is in Fp - * 4. k * G2 same as 1 - * - * - */ - int test() { - char *x_P2_1_str = "85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141"; - char *x_P2_0_str = "3722755292130B08D2AAB97FD34EC120EE265948D19C17ABF9B7213BAF82D65B"; - char *y_P2_1_str = "17509B092E845C1266BA0D262CBEE6ED0736A96FA347C8BD856DC76B84EBEB96"; - char *y_P2_0_str = "A7CF28D519BE3DA65F3170153D278FF247EFBA98A71A08116215BBA5C999A7C7"; + /* P2 generator of the twist curve */ + char *x_P2_str[] = { + "85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141", + "3722755292130B08D2AAB97FD34EC120EE265948D19C17ABF9B7213BAF82D65B"}; + char *y_P2_str[] = { + "17509B092E845C1266BA0D262CBEE6ED0736A96FA347C8BD856DC76B84EBEB96", + "A7CF28D519BE3DA65F3170153D278FF247EFBA98A71A08116215BBA5C999A7C7"}; + /* ks signing master secret */ + char *ks_str = + "0130E78459D78545CB54C587E02CF480CE0B66340F319F348A1D5B1F2DC5F4"; - if (!BN_hex2bn(&x_P2_1, x_P2_1_str) - || !BN_hex2bn(&x_P2_0, x_P2_0_str) - || !BN_hex2bn(&y1, y_P2_1_str) - || !BN_hex2bn(&y0, y_P2_0_str) - || !BN_hex2bn(ks, ks_str)) { - - } - - if (!fp2_set(x_P2, x0, x1) - || !fp2_set(y_P2, y0, y1)) { - } - - char *ks_str = "0130E78459D78545CB54C587E02CF480CE0B66340F319F348A1D5B1F2DC5F4"; - char *x_Ppubs_1_str = "9F64080B3084F733E48AFF4B41B565011CE0711C5E392CFB0AB1B6791B94C408"; - char *x_Ppubs_0_str = "29DBA116152D1F786CE843ED24A3B573414D2177386A92DD8F14D65696EA5E32"; - char *y_Ppubs_1_str = "69850938ABEA0112B57329F447E3A0CBAD3E2FDB1A77F335E89E1408D0EF1C25"; - char *y_Ppubs_0_str = "41E00A53DDA532DA1A7CE027B7A46F741006E85F5CDFF0730E75C05FB4E3216D"; + /* Ppubs = ks * P2 */ + char *x_Ppubs_str[] = { + "9F64080B3084F733E48AFF4B41B565011CE0711C5E392CFB0AB1B6791B94C408", + "29DBA116152D1F786CE843ED24A3B573414D2177386A92DD8F14D65696EA5E32"}; + char *y_Ppubs_str[] = { + "69850938ABEA0112B57329F447E3A0CBAD3E2FDB1A77F335E89E1408D0EF1C25", + "41E00A53DDA532DA1A7CE027B7A46F741006E85F5CDFF0730E75C05FB4E3216D"}; + /* g = e(P1, Ppubs) */ char *g_str[] = { "4E378FB5561CD0668F906B731AC58FEE25738EDF09CADC7A29C0ABC0177AEA6D", "28B3404A61908F5D6198815C99AF1990C8AF38655930058C28C21BB539CE0000", @@ -1370,7 +1466,9 @@ int test() "84B87422330D7936EABA1109FA5A7A7181EE16F2438B0AEB2F38FD5F7554E57A", "AAB9F06A4EEBA4323A7833DB202E4E35639D93FA3305AF73F0F071D7D284FCFB"}; - char *r_str = "033C8616B06704813203DFD00965022ED15975C662337AED648835DC4B1CBE"; + /* r = rand(1, n-1) */ + char *r_str = + "033C8616B06704813203DFD00965022ED15975C662337AED648835DC4B1CBE"; char *w_str[] = { "81377B8FDBC2839B4FA2D0E0F8AA6853BBBE9E9C4099608F8612C6078ACD7563", @@ -1386,31 +1484,36 @@ int test() "6A814AAF475F128AEF43A128E37F80154AE6CB92CAD7D1501BAE30F750B3A9BD", "1F96B08E97997363911314705BFB9A9DBB97F75553EC90FBB2DDAE53C8F68E42"}; - EC_POINT *P1 = NULL; - const EC_GROUP *group; const EC_POINT *P1; - - group = EC_GROUP_new_by_curve_name(NID_sm9bn256v1); + const BIGNUM *n; + BIGNUM *p = NULL; + BIGNUM *a = NULL; + BIGNUM *b = NULL; - EC_GROUP_get_order(); + BIGNUM *ks = NULL; + point_t P2; + point_t Ppubs; - P1 = EC_GROUP_get0_generator(G1); - if (!EC_POINT_set_affine_coordinates_GFp(group, P1, xP1, yP1, bn_ctx)) { + p = BN_new(); + a = BN_new(); + b = BN_new(); + + /* check curve is correct */ + if (!(group = EC_GROUP_new_by_curve_name(NID_sm9bn256v1)) + || !EC_GROUP_get_curve_GFp(group, p, a, b, ctx) + || !(P1 = EC_GROUP_get0_generator(group)) + || !(n = EC_GROUP_get0_order(group)) + || !POINT_is_on_curve(group, P1, ctx)) { ERR_print_errors_fp(stderr); goto end; } - fp2_set(x_P2, x0, x1); - fp2_set(y_P2, y0, y1); - point_set_affine_coordinates(P2, x_P2, y_P2); - - point_mul(R, k, P2); - point_is_at_infinity(R); - - point_mul(Ppubs, ks, P2); - - sm9_rate(g, Ppubs, P1); + EC_POINT_mul(group, Q, n, NULL, NULL, ctx) + if (!POINT_is_at_infinity(Q)) { + } + point_mul_generator(Ppubs, ks, P2, p, ctx); + return 0; }