OpenSSL - EC
ec.h
:唯一需要包含的头文件ec_lcl.h
:结构体定义,EC_METHOD
,EC_GROUP
,EC_POINT
ec_lib.c
:函数实现,包含 - 群的内存控制、群的读写、点的内存控制、点的读写、点加、倍点、多倍点、点的逆ec_mult.c
:
G
F
(
p
)
GF(p)
G F ( p ) 上椭圆曲线的点乘ec2_mult.c
:
G
F
(
2
m
)
GF(2^m)
G F ( 2 m ) 上椭圆曲线的点乘ecp_smpl.c
:平凡的算法ecp_mont.c
:蒙特马利算法ecp_nist.c
:NIST素数域上的算法
示例
#include <openssl/ec.h>
#include <chrono>
#include <iostream>
using namespace std;
#pragma comment(lib,"libssl.lib")
#pragma comment(lib,"libcrypto.lib")
// 计时器
typedef std::chrono::high_resolution_clock clock_type;//标准时钟:steady_clock。高分辨率时钟:high_resolution_clock
extern std::chrono::time_point<clock_type> TM_start{}, TM_end{};
#define Clock() clock_type::now()
#define Time(t_start,t_end) std::chrono::duration<double, ratio<1, 1>>(t_end - t_start).count() //时间差,类型 double, s
#define Timer(code) TM_start = Clock(); code; TM_end = Clock(); std::cout << Time(TM_start,TM_end) << " s\n"; //对code部分计时
// 循环测试
#define Loop(loop, code) Timer(for(long long i=0;i<loop;i++) {code;})
// 换行
#define pn puts("")
//Sm2指定的参数,y2 = x3 + ax + b
#define _p "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF"
#define _a "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC"
#define _b "28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93"
#define _n "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123"
#define _Gx "32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7"
#define _Gy "BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"
void print_BN(BIGNUM* n)
{
char *s = BN_bn2hex(n);
printf("%s", s);
}
void print_ECP(EC_GROUP *group, EC_POINT* p, BN_CTX *ctx)
{
printf("struct EC_POINT\n");
BIGNUM *x = BN_new(), *y = BN_new();
//s = 04 || x || y
/*char* s = EC_POINT_point2hex(group, p, POINT_CONVERSION_UNCOMPRESSED, ctx);
printf("\tPoint = %s\n", s);*/
EC_POINT_get_affine_coordinates_GFp(group, p, x, y, ctx);
char *s1 = BN_bn2hex(x);
char *s2 = BN_bn2hex(y);
printf("\tx = %s\n", s1);
printf("\ty = %s\n", s2);
BN_free(x);
BN_free(y);
}
int main()
{
//上下文
BN_CTX *ctx = BN_CTX_new();
//大数
BIGNUM *p = BN_new(), *a = BN_new(), *b = BN_new(),
*n = BN_new(), *Gx = BN_new(), *Gy = BN_new(), *h = BN_new();
BN_hex2bn(&p, _p);
BN_hex2bn(&a, _a);
BN_hex2bn(&b, _b);
BN_hex2bn(&n, _n);
BN_hex2bn(&Gx, _Gx);
BN_hex2bn(&Gy, _Gy);
BN_set_word(h, 1);
printf("Gx = "); print_BN(Gx); pn;
printf("Gy = "); print_BN(Gy); pn;
//群
EC_GROUP *group = EC_GROUP_new(EC_GFp_mont_method());
//设置曲线
cout << "set curve: " << EC_GROUP_set_curve_GFp(group, p, a, b, ctx); pn;
//基点G
EC_POINT * G = EC_POINT_new(group);
cout << "set point: " << EC_POINT_set_affine_coordinates_GFp(group, G, Gx, Gy, ctx); pn;
cout << "G = "; print_ECP(group, G, ctx);
//设置基点
cout << "set generator: " << EC_GROUP_set_generator(group, G, n, h); pn;
//随机数
BIGNUM *rand = BN_new();
do {
BN_rand_range(rand, n);
} while (BN_is_zero(rand));
//随机点
EC_POINT * P = EC_POINT_new(group);
EC_POINT_mul(group, P, rand, NULL, NULL, ctx);
cout << "P = "; print_ECP(group, P, ctx);
//验证点是否在椭圆曲线上
cout << "tag = " << EC_POINT_is_on_curve(group, P, ctx) << endl;
int loop = 1000;
//点加
EC_POINT_add(group, P, P, G, ctx);
printf("%d - Add: ", loop); Loop(loop, EC_POINT_add(group, P, P, G, ctx));
//倍点
EC_POINT_dbl(group, P, P, ctx);
printf("%d - Double: ", loop); Loop(loop, EC_POINT_dbl(group, P, P, ctx));
//多倍点
EC_POINT_mul(group, P, NULL, G, rand, ctx);
printf("%d - Multiply: ", loop); Loop(loop, EC_POINT_mul(group, P, NULL, G, rand, ctx));
return 0;
}
结果
Gx = 32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7
Gy = BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0
set curve: 1
set point: 1
G = struct EC_POINT
x = 32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7
y = BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0
set generator: 1
P = struct EC_POINT
x = ED780F3E8EE01B898B6F85D7BAB9DC5AE72DF4A452334E8F09453CC6D71F0A3A
y = 9303A5EE46679F5C304858A55F62B3154FED634EFBEDBEF242F0C0E214C8F226
tag = 1
1000 - Add: 0.0035358 s
1000 - Double: 0.0033611 s
1000 - Multiply: 1.34196 s