您可以使用OpenSSL的
EC_GROUP_check()
函数来确保它是一个有效的组。在下面的程序中,我做了两件事:
- 使用提供的参数生成EC_GROUP,并检查其是否有效
- 使用生成的EC_group生成EC_KEY,并检查它是否有效
请注意,您要检查的是EC组是否可以用于生成有效的EC密钥,而不是EC曲线。
请阅读注释以获取详细信息 :)
#include <openssl/ec.h>
#include <stdio.h>
int main(){
BN_CTX *ctx = NULL;
BIGNUM *p, *a, *b, *x, *y, *order;
EC_GROUP *group;
EC_POINT *G;
int ok = 1;
ctx = BN_CTX_new();
p = BN_new();
a = BN_new();
b = BN_new();
x = BN_new();
y = BN_new();
order = BN_new();
group = EC_GROUP_new(EC_GFp_mont_method());
BN_dec2bn(&p, "10997031918897188677");
BN_dec2bn(&a, "3628449283386729367");
BN_dec2bn(&b, "4889270915382004880");
EC_GROUP_set_curve_GFp(group, p, a, b, ctx);
G = EC_POINT_new(group);
BN_dec2bn(&x, "3124469192170877657");
BN_dec2bn(&y, "4370601445727723733");
BN_dec2bn(&order, "10997031916045924769");
EC_POINT_set_affine_coordinates_GFp(group,G,x,y,ctx);
EC_GROUP_set_generator(group,G,order,BN_value_one());
if(!EC_GROUP_check(group,ctx)) {
fprintf(stdout, "EC_GROUP_check() failed\n");
ok = 0;
}
if (ok) {
fprintf(stdout, "It is a valid EC group\n");
}
if (ok) {
BIGNUM *private_key, *pub_x, *pub_y;
EC_POINT *public_key;
EC_KEY *eckey;
pub_x = BN_new(); pub_y = BN_new();
eckey = EC_KEY_new();
EC_KEY_set_group(eckey,group);
EC_KEY_generate_key(eckey);
if (!EC_KEY_check_key(eckey)) {
fprintf(stdout, "EC_KEY_check_key() failed\n");
ok = 0;
}
if (ok) {
fprintf(stdout, "It is a valid EC key, where\n");
private_key = EC_KEY_get0_private_key(eckey);
fprintf(stdout, "\tprivate key = %s",BN_bn2dec(private_key));
public_key = EC_KEY_get0_public_key(eckey);
EC_POINT_get_affine_coordinates_GFp(group,public_key,pub_x,pub_y,ctx);
fprintf(stdout, "\n\tpublic key = ( %s , %s )\n",
BN_bn2dec(pub_x),BN_bn2dec(pub_y));
}
BN_free(pub_x); BN_free(pub_y);
EC_KEY_free(eckey);
}
if (ctx)
BN_CTX_free(ctx);
BN_free(p); BN_free(a); BN_free(b);
EC_GROUP_free(group);
EC_POINT_free(G);
BN_free(x); BN_free(y); BN_free(order);
return 0;
}
使用以下命令进行编译和运行:
$ gcc 22270485.c -lcrypto -o 22270485
$ ./22270485
stdout 应该打印。
It is a valid EC group
It is a valid EC key, where
private key = 1524190197747279622
public key = ( 3228020167903858345 , 9344375093791763077 )
私钥/公钥对每次都会发生变化,因为
EC_KEY_generate_key(eckey)
会随机选择私钥并计算出相应的公钥。
d
是一个大数;公钥P
是一个EC点。假设生成器为G
,G=(x,y)
,那么P=d*G
,其中P=(pub_x,pub_y)
。你希望公钥是什么样子的?ECC算法(如ECDSA)中的公钥实际上是曲线上的EC点,是EC群的一个元素。你也可以打印出该点的压缩坐标,它看起来像一个大数,但它仍然是一个点 ;) - Chiara Hsieh