mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-08-07 12:33:39 +08:00
Update SM9
to be continue ...
This commit is contained in:
@@ -76,6 +76,16 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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 {
|
struct SM9PublicParameters_st {
|
||||||
ASN1_OBJECT *curve;
|
ASN1_OBJECT *curve;
|
||||||
BIGNUM *p;
|
BIGNUM *p;
|
||||||
|
|||||||
@@ -55,14 +55,29 @@
|
|||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
|
|
||||||
|
|
||||||
#include "bn_lcl.h"
|
#include "../bn/bn_lcl.h"
|
||||||
#include "internal/cryptlib.h"
|
#include "internal/cryptlib.h"
|
||||||
|
|
||||||
|
|
||||||
#define BN_SM9_BN256_TOP (256+BN_BITS2-1)/BN_BITS2
|
#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_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] = {
|
static const BN_ULONG _sm9bn256v1_x2[][BN_SM9_BN256_TOP] = {
|
||||||
{0xF9B7213BAF82D65BULL, 0xEE265948D19C17ABULL,
|
{0xF9B7213BAF82D65BULL, 0xEE265948D19C17ABULL,
|
||||||
0xD2AAB97FD34EC120ULL, 0x3722755292130B08ULL},
|
0xD2AAB97FD34EC120ULL, 0x3722755292130B08ULL},
|
||||||
@@ -77,11 +92,25 @@ static const BN_ULONG _sm9bn256v1_y2[][BN_SM9_BN256_TOP] = {
|
|||||||
0x66BA0D262CBEE6EDULL, 0x17509B092E845C12ULL}
|
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,
|
0x400000000215D93EULL, 0x02ULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
#elif BN_BITS2 == 32
|
#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] = {
|
static const BN_ULONG _sm9bn256v1_x2[][BN_SM9_BN256_TOP] = {
|
||||||
{0xAF82D65B, 0xF9B7213B, 0xD19C17AB, 0xEE265948,
|
{0xAF82D65B, 0xF9B7213B, 0xD19C17AB, 0xEE265948,
|
||||||
0xD34EC120, 0xD2AAB97F, 0x92130B08, 0x37227552},
|
0xD34EC120, 0xD2AAB97F, 0x92130B08, 0x37227552},
|
||||||
@@ -96,14 +125,46 @@ static const BN_ULONG _sm9bn256v1_y2[][BN_SM9_BN256_TOP] = {
|
|||||||
0x2CBEE6ED, 0x66BA0D26, 0x2E845C12, 0x17509B09}
|
0x2CBEE6ED, 0x66BA0D26, 0x2E845C12, 0x17509B09}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const BN_ULONG _sm9bn256v1_trace[BN_SM9_TRACE_TOP] = {
|
static const BN_ULONG _sm9bn256v1_final_expo[BN_SM9_FINAL_EXPO_TOP] = {
|
||||||
0x0215D93E, 0x40000000, 0x02,
|
0, 0, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
# error "unsupported BN_BITS2"
|
# error "unsupported BN_BITS2"
|
||||||
#endif
|
#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 = {
|
static const BIGNUM _bignum_sm9bn256v1_x20 = {
|
||||||
(BN_ULONG *)_sm9bn256v1_x2[0],
|
(BN_ULONG *)_sm9bn256v1_x2[0],
|
||||||
BN_SM9_BN256_TOP,
|
BN_SM9_BN256_TOP,
|
||||||
@@ -136,22 +197,42 @@ static const BIGNUM _bignum_sm9bn256v1_y21 = {
|
|||||||
BN_FLG_STATIC_DATA
|
BN_FLG_STATIC_DATA
|
||||||
};
|
};
|
||||||
|
|
||||||
static const BIGNUM _bignum_sm9bn256v1_trace = {
|
const BIGNUM *SM9_get0_generator2_x0(void)
|
||||||
(BN_ULONG *)_sm9bn256v1_trace, // IS THIS CORRECT??
|
{
|
||||||
BN_SM9_TRACE_TOP,
|
return &_bignum_sm9bn256v1_x20;
|
||||||
BN_SM9_TRACE_TOP,
|
}
|
||||||
0,
|
|
||||||
BN_FLG_STATIC_DATA
|
|
||||||
};
|
|
||||||
|
|
||||||
// we should not put it here
|
const BIGNUM *SM9_get0_generator2_x1(void)
|
||||||
const point_t _sm9bn256v1_g2 = {
|
{
|
||||||
{&_bignum_sm9bn256v1_x20, &_bignum_sm9bn256v1_x21},
|
return &_bignum_sm9bn256v1_x21;
|
||||||
{&_bignum_sm9bn256v1_y20, &_bignum_sm9bn256v1_y21},
|
}
|
||||||
{&_bignum_one, &_bignum_zero}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -53,6 +53,7 @@
|
|||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#include <openssl/ec.h>
|
#include <openssl/ec.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
|
#include "sm9_lcl.h"
|
||||||
|
|
||||||
typedef BIGNUM *fp2_t[2];
|
typedef BIGNUM *fp2_t[2];
|
||||||
typedef fp2_t fp4_t[2];
|
typedef fp2_t fp4_t[2];
|
||||||
@@ -97,13 +98,13 @@ static void fp2_clear_cleanup(fp2_t a)
|
|||||||
a[1] = NULL;
|
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])
|
return BN_is_zero(a[0])
|
||||||
&& BN_is_zero(a[1]);
|
&& 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])
|
return BN_is_one(a[0])
|
||||||
&& BN_is_zero(a[1]);
|
&& 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)
|
static int fp2_set_bn(fp2_t r, const BIGNUM *a)
|
||||||
{
|
{
|
||||||
BN_zero(r[1]);
|
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)
|
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]);
|
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)
|
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)
|
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);
|
&& 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)
|
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)
|
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]);
|
&& 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)
|
static int fp2_mul(fp2_t r, const fp2_t a, const fp2_t b, const BIGNUM *p, BN_CTX *ctx)
|
||||||
{
|
{
|
||||||
BIGNUM *t = NULL;
|
BIGNUM *t = NULL;
|
||||||
if (!(t = BN_CTX_get(ctx))
|
if (!(t = BN_CTX_get(ctx))
|
||||||
/* r0 = a0 * b0 - 2 * a1 * b1 */
|
/* r0 = a0 * b0 - 2 * a1 * b1 */
|
||||||
|| !BN_mod_mul(r[0], a[0], b[0], p, ctx)
|
|| !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_add(t, t, t, p, ctx)
|
||||||
|| !BN_mod_sub(r[0], r[0], 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;
|
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;
|
BIGNUM *t = NULL;
|
||||||
if (!(t = BN_CTX_get(ctx))
|
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 {
|
} else {
|
||||||
|
BIGNUM *k = NULL;
|
||||||
|
BIGNUM *t = NULL;
|
||||||
if (!(k = BN_CTX_get(ctx))
|
if (!(k = BN_CTX_get(ctx))
|
||||||
|| !(t = 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;
|
int r;
|
||||||
r = fp2_init(a[0], ctx);
|
r = fp2_init(a[0], ctx);
|
||||||
r &&= fp2_init(a[1], ctx);
|
r &= fp2_init(a[1], ctx);
|
||||||
if (!r) {
|
if (!r) {
|
||||||
fp2_cleanup(a[0]);
|
fp2_cleanup(a[0]);
|
||||||
fp2_cleanup(a[1]);
|
fp2_cleanup(a[1]);
|
||||||
}
|
}
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fp4_cleanup(fp4_t a)
|
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)
|
static int fp4_set_one(fp4_t r)
|
||||||
{
|
{
|
||||||
fp2_set_zero(r[1]);
|
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)
|
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])
|
return fp2_equ(a[0], b[0])
|
||||||
&& fp2_equ(a[1], b[1]);
|
&& 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)
|
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);
|
&& 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)
|
return fp2_neg(r[0], a[0], p)
|
||||||
&&fp2_neg(r[1], a[1], p, ctx);
|
&&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)
|
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;
|
fp2_t t;
|
||||||
if (!fp2_init(t, ctx)
|
if (!fp2_init(t, ctx)
|
||||||
/* r[0] = 2 * (a[0] * a[1]) */
|
/* r[0] = 2 * (a[0] * a[1]) */
|
||||||
|| !fp2_mul_u(t0, a[0], a[1], p, ctx)
|
|| !fp2_mul_u(t, a[0], a[1], p, ctx)
|
||||||
|| !fp2_dbl(r[0], t0, p, ctx)
|
|| !fp2_dbl(r[0], t, p, ctx)
|
||||||
|
|
||||||
/* r[1] = a[0]^2 + a[1]^2 * u */
|
/* r[1] = a[0]^2 + a[1]^2 * u */
|
||||||
|| !fp2_sqr(r[1], a[0], p, ctx)
|
|| !fp2_sqr(r[1], a[0], p, ctx)
|
||||||
|| !fp2_sqr_u(t, a[1], p, ctx)
|
|| !fp2_sqr_u(t, a[1], p, ctx)
|
||||||
|| !fp2_add(r[1], r[1], t, p, ctx)) {
|
|| !fp2_add(r[1], r[1], t, p, ctx)) {
|
||||||
fp_cleanup(t);
|
fp2_cleanup(t);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
fp_cleanup(t);
|
fp2_cleanup(t);
|
||||||
return 1;
|
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) */
|
/* r[0] = -(a[0] * k) */
|
||||||
|| !fp2_mul(r[0], a[0], k, p, ctx)
|
|| !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 */
|
/* r[1] = a[1] * k */
|
||||||
|| !fp2_mul(r[1], a[1], k, p, ctx)) {
|
|| !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;
|
int r;
|
||||||
r = fp4_init(a[0], ctx);
|
r = fp4_init(a[0], ctx);
|
||||||
r &&= fp4_init(a[1], ctx);
|
r &= fp4_init(a[1], ctx);
|
||||||
r &&= fp4_init(a[2], ctx);
|
r &= fp4_init(a[2], ctx);
|
||||||
if (!r) {
|
if (!r) {
|
||||||
fp4_cleanup(a[0]);
|
fp4_cleanup(a[0]);
|
||||||
fp4_cleanup(a[1]);
|
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)
|
static int fp12_is_zero(const fp12_t a)
|
||||||
{
|
{
|
||||||
return fp12_is_zero(a[0])
|
return fp4_is_zero(a[0])
|
||||||
&& fp12_is_zero(a[1])
|
&& fp4_is_zero(a[1])
|
||||||
&& fp12_is_zero(a[2]);
|
&& fp4_is_zero(a[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fp12_is_one(const fp12_t a)
|
static int fp12_is_one(const fp12_t a)
|
||||||
{
|
{
|
||||||
return fp12_is_one(a[0])
|
return fp4_is_one(a[0])
|
||||||
&& fp12_is_zero(a[1])
|
&& fp4_is_zero(a[1])
|
||||||
&& fp12_is_zero(a[2]);
|
&& fp4_is_zero(a[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fp12_set_zero(fp12_t r)
|
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);
|
&& 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)
|
return fp4_neg(r[0], a[0], p)
|
||||||
&& fp4_neg(r[1], a[1], p, ctx)
|
&& fp4_neg(r[1], a[1], p)
|
||||||
&& fp4_neg(r[2], a[2], p, ctx);
|
&& 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)
|
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))
|
if (!(fp4_init(t, ctx))
|
||||||
/* r0 = a0^2 + 2*a1*a2*v */
|
/* r0 = a0^2 + 2*a1*a2*v */
|
||||||
|| !fp4_sqr(r[0], a[0], p, ctx)
|
|| !fp4_sqr(r[0], a[0], p, ctx)
|
||||||
|| ! fp4_mul_v(t, a[1], a[2], p, ctx)
|
|| !fp4_mul_v(t, a[1], a[2], p, ctx)
|
||||||
|| ! fp4_dbl(t, t, p, ctx)
|
|| !fp4_dbl(t, t, p, ctx)
|
||||||
|| ! fp4_add(r[0], t, p, ctx)
|
|| !fp4_add(r[0], r[0], t, p, ctx)
|
||||||
|
|
||||||
/* r1 = 2*a0*a1 + a^2 * v */
|
/* r1 = 2*a0*a1 + a^2 * v */
|
||||||
|| ! fp4_mul(r[1], a[0], a[1], p, ctx)
|
|| !fp4_mul(r[1], a[0], a[1], p, ctx)
|
||||||
|| ! fp4_dbl(r[1], r[1], p, ctx)
|
|| !fp4_dbl(r[1], r[1], p, ctx)
|
||||||
|| ! fp4_sqr_v(t, a[2], p, ctx)
|
|| !fp4_sqr_v(t, a[2], p, ctx)
|
||||||
|| ! fp4_add(r[1], r[1], t, p, ctx)
|
|| !fp4_add(r[1], r[1], t, p, ctx)
|
||||||
|
|
||||||
/* r2 = 2*a0*a2 + a1^2*/
|
/* r2 = 2*a0*a2 + a1^2*/
|
||||||
|| ! fp4_mul(r[2], a[0], a[2], p, ctx)
|
|| !fp4_mul(r[2], a[0], a[2], p, ctx)
|
||||||
|| ! fp4_dbl(r[2], r[2], p, ctx)
|
|| !fp4_dbl(r[2], r[2], p, ctx)
|
||||||
|| ! fp4_sqr(t, a[1], p, ctx)
|
|| !fp4_sqr(t, a[1], p, ctx)
|
||||||
|| ! fp4_add(r[2], t, p, ctx)) {
|
|| !fp4_add(r[2], r[2], t, p, ctx)) {
|
||||||
|
|
||||||
fp4_cleanup(t);
|
fp4_cleanup(t);
|
||||||
return 0;
|
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])) {
|
if (fp4_is_zero(a[2])) {
|
||||||
fp4_t k;
|
fp4_t k;
|
||||||
|
fp4_t t;
|
||||||
|
if (!fp4_init(t, ctx)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (!(fp4_init(k, ctx))
|
if (!(fp4_init(k, ctx))
|
||||||
/* k = (a0^3 + a1^3 * v)^-1 */
|
/* k = (a0^3 + a1^3 * v)^-1 */
|
||||||
|| !fp4_sqr(k, a[0], p, ctx)
|
|| !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) */
|
/* r1 = -(a0 * a1 * k) */
|
||||||
|| !fp4_mul(r[0], a[0], a[1], p, ctx)
|
|| !fp4_mul(r[0], a[0], a[1], p, ctx)
|
||||||
|| !fp4_mul(r[0], r[0], k, 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 */
|
/* r2 = a1^2 * k */
|
||||||
|| !fp4_sqr(r[2], a[1], p, ctx)
|
|| !fp4_sqr(r[2], a[1], p, ctx)
|
||||||
|| !fp4_mul(r[2], r[2], k, p, ctx)) {
|
|| !fp4_mul(r[2], r[2], k, p, ctx)) {
|
||||||
|
|
||||||
fp4_cleanup(k);
|
fp4_cleanup(k);
|
||||||
|
fp4_cleanup(t);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
fp4_cleanup(k);
|
fp4_cleanup(k);
|
||||||
|
fp4_cleanup(t);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
} else {
|
} 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(t2, ctx))
|
||||||
|| !(fp4_init(t3, ctx))
|
|| !(fp4_init(t3, ctx))
|
||||||
|
|
||||||
|
// CHECK THIS!!!!!
|
||||||
|
|
||||||
/* t0 = a1^2 - a0 * a1 */
|
/* t0 = a1^2 - a0 * a1 */
|
||||||
|| !fp4_sqr(t0, a[1], p, ctx)
|
|| !fp4_sqr(t0, a[1], p, ctx)
|
||||||
|| !fp4_mul(t1, a[0], a[2], 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 */
|
/* t3 = a2 * (t1^2 - t0 * t2)^-1 */
|
||||||
|| !fp4_sqr(t1, t1, p, ctx)
|
|| !fp4_sqr(t1, t1, p, ctx)
|
||||||
|| !fp4_mul(t4, t0, t2, p, ctx)
|
|| !fp4_mul(r[0], t0, t2, p, ctx)
|
||||||
|| !fp4_sub(t1, t1, t5, p, ctx)
|
|| !fp4_sub(t1, t1, r[0], p, ctx)
|
||||||
|| !fp4_mul(t3, a[2], t3, p, ctx)
|
|| !fp4_mul(t3, a[2], t3, p, ctx)
|
||||||
|| !fp4_inv(t3, 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;
|
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)
|
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)) {
|
if (BN_is_zero(k)) {
|
||||||
return fp12_set_one(r);
|
return fp12_set_one(r);
|
||||||
@@ -894,9 +929,9 @@ static int point_init(point_t P, BN_CTX *ctx)
|
|||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
r = fp2_init(P.X, ctx);
|
r = fp2_init(P.X, ctx);
|
||||||
r &&= fp2_init(P.Y, ctx);
|
r &= fp2_init(P.Y, ctx);
|
||||||
r &&= fp2_init(P.Z, ctx);
|
r &= fp2_init(P.Z, ctx);
|
||||||
r &&= fp2_set_one(P.Y, ctx);
|
r &= fp2_set_one(P.Y);
|
||||||
if (!r) {
|
if (!r) {
|
||||||
fp2_cleanup(P.X);
|
fp2_cleanup(P.X);
|
||||||
fp2_cleanup(P.Y);
|
fp2_cleanup(P.Y);
|
||||||
@@ -915,6 +950,13 @@ static void point_cleanup(point_t P)
|
|||||||
fp2_cleanup(P.Z);
|
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)
|
static int point_set_infinity(point_t P)
|
||||||
{
|
{
|
||||||
fp2_set_zero(P.X);
|
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);
|
&& 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;
|
int r;
|
||||||
fp2_t x, y, t;
|
fp2_t x, y, t;
|
||||||
|
|
||||||
r = fp2_init(x, ctx);
|
r = fp2_init(x, ctx);
|
||||||
r &&= fp2_init(y, ctx);
|
r &= fp2_init(y, ctx);
|
||||||
r &&= fp2_init(t, ctx);
|
r &= fp2_init(t, ctx);
|
||||||
if (!r) {
|
if (!r) {
|
||||||
goto end;
|
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_sqr(t, x, p, ctx)
|
||||||
|| !fp2_mul(x, x, t, p, ctx)
|
|| !fp2_mul(x, x, t, p, ctx)
|
||||||
|| !fp2_add_word(x, x, 5, p, ctx)
|
|| !fp2_add_word(x, x, 5, p, ctx)
|
||||||
@@ -965,33 +1029,18 @@ end:
|
|||||||
return r;
|
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)
|
static int point_dbl(point_t R, const point_t P, const BIGNUM *p, BN_CTX *ctx)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
fp2_t x3, y3, x1, y1, lambda, t;
|
fp2_t x3, y3, x1, y1, lambda, t;
|
||||||
|
|
||||||
r = 1;
|
r = 1;
|
||||||
r &&= fp2_init(x1, ctx);
|
r &= fp2_init(x1, ctx);
|
||||||
r &&= fp2_init(y1, ctx);
|
r &= fp2_init(y1, ctx);
|
||||||
r &&= fp2_init(x3, ctx);
|
r &= fp2_init(x3, ctx);
|
||||||
r &&= fp2_init(y3, ctx);
|
r &= fp2_init(y3, ctx);
|
||||||
r &&= fp2_init(t0, ctx);
|
r &= fp2_init(lambda, ctx);
|
||||||
r &&= fp2_init(t1, ctx);
|
r &= fp2_init(t, ctx);
|
||||||
r &&= fp2_init(lambda, ctx);
|
|
||||||
if (!r) {
|
if (!r) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -1027,7 +1076,7 @@ end:
|
|||||||
fp2_cleanup(x1);
|
fp2_cleanup(x1);
|
||||||
fp2_cleanup(y1);
|
fp2_cleanup(y1);
|
||||||
fp2_cleanup(x3);
|
fp2_cleanup(x3);
|
||||||
fp2_clenaup(y3);
|
fp2_cleanup(y3);
|
||||||
fp2_cleanup(lambda);
|
fp2_cleanup(lambda);
|
||||||
fp2_cleanup(t);
|
fp2_cleanup(t);
|
||||||
return r;
|
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 x3;
|
||||||
fp2_t y3;
|
fp2_t y3;
|
||||||
fp2_t lambda;
|
fp2_t lambda;
|
||||||
fp2_t t0;
|
fp2_t t;
|
||||||
fp2_t t1;
|
|
||||||
|
|
||||||
if (point_is_at_infinity(P)) {
|
if (point_is_at_infinity(P)) {
|
||||||
return point_copy(R, Q);
|
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 = 1;
|
||||||
r &&= fp2_init(x1, ctx);
|
r &= fp2_init(x1, ctx);
|
||||||
r &&= fp2_init(y1, ctx);
|
r &= fp2_init(y1, ctx);
|
||||||
r &&= fp2_init(x2, ctx);
|
r &= fp2_init(x2, ctx);
|
||||||
r &&= fp2_init(y2, ctx);
|
r &= fp2_init(y2, ctx);
|
||||||
r &&= fp2_init(x3, ctx);
|
r &= fp2_init(x3, ctx);
|
||||||
r &&= fp2_init(y3, ctx);
|
r &= fp2_init(y3, ctx);
|
||||||
r &&= fp2_init(lambda, ctx);
|
r &= fp2_init(lambda, ctx);
|
||||||
r &&= fp2_init(t, ctx);
|
r &= fp2_init(t, ctx);
|
||||||
if (!r) {
|
if (!r) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -1116,10 +1164,10 @@ end:
|
|||||||
return r;
|
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)
|
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);
|
&& 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;
|
point_t T;
|
||||||
if (!point_init(T, ctx)
|
if (!point_init(T, ctx)
|
||||||
|| !point_neg(T, Q)
|
|| !point_neg(T, Q, p)
|
||||||
|| !point_add(R, P, T, p, ctx)) {
|
|| !point_add(R, P, T, p, ctx)) {
|
||||||
point_cleanup(T);
|
point_cleanup(T);
|
||||||
return 0;
|
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;
|
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)
|
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)) {
|
if (BN_is_zero(k)) {
|
||||||
return point_set_infinity(R);
|
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;
|
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,
|
static int eval_tangent(fp12_t r, const fp12_t xP, const fp12_t yP,
|
||||||
const BIGNUM *xQ, const BIGNUM *yQ,
|
const BIGNUM *xQ, const BIGNUM *yQ,
|
||||||
const BIGNUM *p, BN_CTX *ctx)
|
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;
|
fp12_t x, y, lambda, t;
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
ret &&= fp12_init(x, ctx);
|
ret &= fp12_init(x, ctx);
|
||||||
ret &&= fp12_init(y, ctx);
|
ret &= fp12_init(y, ctx);
|
||||||
ret &&= fp12_init(lambda, ctx);
|
ret &= fp12_init(lambda, ctx);
|
||||||
ret &&= fp12_init(t, ctx);
|
ret &= fp12_init(t, ctx);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
goto end;
|
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)) {
|
|| !fp12_add(r, r, yP, p, ctx)) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
ret = 1
|
ret = 1;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
fp12_cleanup(x);
|
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;
|
fp12_t x, y, lambda, t;
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
ret &&= fp12_init(x, ctx);
|
ret &= fp12_init(x, ctx);
|
||||||
ret &&= fp12_init(y, ctx);
|
ret &= fp12_init(y, ctx);
|
||||||
ret &&= fp12_init(lambda, ctx);
|
ret &= fp12_init(lambda, ctx);
|
||||||
ret &&= fp12_init(t, ctx);
|
ret &= fp12_init(t, ctx);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -1246,53 +1306,101 @@ end:
|
|||||||
return ret;
|
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;
|
int r;
|
||||||
fp12_t t0, t1;
|
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);
|
r = 0;
|
||||||
fp2_conjugate(y);
|
if (!point_get_affine_coordinates(P, xP, yP)
|
||||||
fp12_set_fp(t0, x);
|
|| !fp12_set_fp2(x, xP)
|
||||||
fp12_set_fp(t1, y);
|
|| !fp12_set_fp2(y, yP)
|
||||||
fp12_mul(xR, t0, w2p);
|
|
||||||
fp12_mul(yR, t1, w3p);
|
/* 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;
|
return point_get_ext_affine_coordinates(P, x, y, p, ctx)
|
||||||
fp12_t t0, t1;
|
&& fp12_pow(x, x, p, p, ctx)
|
||||||
|
&& fp12_pow(y, y, p, p, ctx);
|
||||||
|
|
||||||
point_get_affine_coordinates(x, y, R);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
return point_frob(P, x, y, p, ctx)
|
||||||
for (i = 0; i < sizeof(ebits); i++) {
|
&& fp12_pow(x, x, p, p, ctx)
|
||||||
fp12_sqr_to(r);
|
&& fp12_pow(y, y, p, p, ctx);
|
||||||
if (ebits[i]) {
|
}
|
||||||
fp12_mul_to(r, a);
|
|
||||||
|
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;
|
int i;
|
||||||
|
point_t T;
|
||||||
fp12_t f, g;
|
fp12_t f, g;
|
||||||
|
|
||||||
|
point_init(T, ctx);
|
||||||
|
|
||||||
point_copy(T, Q);
|
point_copy(T, Q);
|
||||||
fp12_set_one(f);
|
fp12_set_one(f);
|
||||||
|
|
||||||
for (i = 0; i < sizeof(abits); i++) {
|
|
||||||
|
for (i = n - 2; i >= 0; i++) {
|
||||||
eval(g, T, T, xP, yP);
|
eval(g, T, T, xP, yP);
|
||||||
fp12_sqr_to(f);
|
fp12_sqr_to(f);
|
||||||
fp12_mul_to(f, g);
|
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);
|
//point_add_to(T, Q2);
|
||||||
|
|
||||||
final_expo(r, f);
|
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()
|
int test()
|
||||||
{
|
{
|
||||||
char *x_P2_1_str = "85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141";
|
/* P2 generator of the twist curve */
|
||||||
char *x_P2_0_str = "3722755292130B08D2AAB97FD34EC120EE265948D19C17ABF9B7213BAF82D65B";
|
char *x_P2_str[] = {
|
||||||
char *y_P2_1_str = "17509B092E845C1266BA0D262CBEE6ED0736A96FA347C8BD856DC76B84EBEB96";
|
"85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141",
|
||||||
char *y_P2_0_str = "A7CF28D519BE3DA65F3170153D278FF247EFBA98A71A08116215BBA5C999A7C7";
|
"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)
|
/* Ppubs = ks * P2 */
|
||||||
|| !BN_hex2bn(&x_P2_0, x_P2_0_str)
|
char *x_Ppubs_str[] = {
|
||||||
|| !BN_hex2bn(&y1, y_P2_1_str)
|
"9F64080B3084F733E48AFF4B41B565011CE0711C5E392CFB0AB1B6791B94C408",
|
||||||
|| !BN_hex2bn(&y0, y_P2_0_str)
|
"29DBA116152D1F786CE843ED24A3B573414D2177386A92DD8F14D65696EA5E32"};
|
||||||
|| !BN_hex2bn(ks, ks_str)) {
|
char *y_Ppubs_str[] = {
|
||||||
|
"69850938ABEA0112B57329F447E3A0CBAD3E2FDB1A77F335E89E1408D0EF1C25",
|
||||||
}
|
"41E00A53DDA532DA1A7CE027B7A46F741006E85F5CDFF0730E75C05FB4E3216D"};
|
||||||
|
|
||||||
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";
|
|
||||||
|
|
||||||
|
/* g = e(P1, Ppubs) */
|
||||||
char *g_str[] = {
|
char *g_str[] = {
|
||||||
"4E378FB5561CD0668F906B731AC58FEE25738EDF09CADC7A29C0ABC0177AEA6D",
|
"4E378FB5561CD0668F906B731AC58FEE25738EDF09CADC7A29C0ABC0177AEA6D",
|
||||||
"28B3404A61908F5D6198815C99AF1990C8AF38655930058C28C21BB539CE0000",
|
"28B3404A61908F5D6198815C99AF1990C8AF38655930058C28C21BB539CE0000",
|
||||||
@@ -1370,7 +1466,9 @@ int test()
|
|||||||
"84B87422330D7936EABA1109FA5A7A7181EE16F2438B0AEB2F38FD5F7554E57A",
|
"84B87422330D7936EABA1109FA5A7A7181EE16F2438B0AEB2F38FD5F7554E57A",
|
||||||
"AAB9F06A4EEBA4323A7833DB202E4E35639D93FA3305AF73F0F071D7D284FCFB"};
|
"AAB9F06A4EEBA4323A7833DB202E4E35639D93FA3305AF73F0F071D7D284FCFB"};
|
||||||
|
|
||||||
char *r_str = "033C8616B06704813203DFD00965022ED15975C662337AED648835DC4B1CBE";
|
/* r = rand(1, n-1) */
|
||||||
|
char *r_str =
|
||||||
|
"033C8616B06704813203DFD00965022ED15975C662337AED648835DC4B1CBE";
|
||||||
|
|
||||||
char *w_str[] = {
|
char *w_str[] = {
|
||||||
"81377B8FDBC2839B4FA2D0E0F8AA6853BBBE9E9C4099608F8612C6078ACD7563",
|
"81377B8FDBC2839B4FA2D0E0F8AA6853BBBE9E9C4099608F8612C6078ACD7563",
|
||||||
@@ -1386,31 +1484,36 @@ int test()
|
|||||||
"6A814AAF475F128AEF43A128E37F80154AE6CB92CAD7D1501BAE30F750B3A9BD",
|
"6A814AAF475F128AEF43A128E37F80154AE6CB92CAD7D1501BAE30F750B3A9BD",
|
||||||
"1F96B08E97997363911314705BFB9A9DBB97F75553EC90FBB2DDAE53C8F68E42"};
|
"1F96B08E97997363911314705BFB9A9DBB97F75553EC90FBB2DDAE53C8F68E42"};
|
||||||
|
|
||||||
EC_POINT *P1 = NULL;
|
|
||||||
|
|
||||||
const EC_GROUP *group;
|
const EC_GROUP *group;
|
||||||
const EC_POINT *P1;
|
const EC_POINT *P1;
|
||||||
|
const BIGNUM *n;
|
||||||
group = EC_GROUP_new_by_curve_name(NID_sm9bn256v1);
|
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);
|
ERR_print_errors_fp(stderr);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
fp2_set(x_P2, x0, x1);
|
EC_POINT_mul(group, Q, n, NULL, NULL, ctx)
|
||||||
fp2_set(y_P2, y0, y1);
|
if (!POINT_is_at_infinity(Q)) {
|
||||||
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);
|
|
||||||
|
|
||||||
|
point_mul_generator(Ppubs, ks, P2, p, ctx);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user