一、ECC的简介
椭圆曲线算法可以看作是定义在特殊集合下数的运算,满足一定的规则。椭圆曲线在如下两个域中定义:Fp域和F2m域。
Fp域,素数域,p为素数;
F2m域:特征为2的有限域,称之为二元域或者二进制扩展域。该域中,元素的个数为2m个。
以下只介绍素数域。
一些术语说明:
1) 椭圆曲线的阶(order of a curve)
椭圆曲线所有点的个数,包含无穷远点;
2) 椭圆曲线上点的阶(order of a point)
P为椭圆曲线上的点,nP=无穷远点,n取最小整数,既是P的阶;
3)基点(base point)
椭圆曲线参数之一,用G表示,是椭圆曲线上都一个点;
4)余因子(cofactor)
椭圆曲线的余因子,用h表示,为椭圆曲线点的个数/基点的阶
5)椭圆曲线参数:
素数域:(p,a,b,G,n,h)
其中,p为素数,确定Fp,a和b确定椭圆曲线方程,G为基点,n为G的阶,h为余因子。
二、Openssl对ECC的实现
Openssl实现ECC算法包括三部分:ECC算法(crypto/ec)、椭圆曲线数字签名算法ECDSA(crypto/ecdsa)以及椭圆曲线密钥交换算法ECDH(crypto/ecdh)。
2.1 数据结构
我们首先来看一下密钥的数据结构(定义在crypto/ec/ec_lcl.h):
struct ec_key_st {
int version;//版本号
EC_GROUP *group;//密钥参数
EC_POINT *pub_key;//公钥
BIGNUM *priv_key;//大数私钥
//下面的是其他项
unsigned int enc_flag;
point_conversion_form_t conv_form;
int references;
int flags;
EC_EXTRA_DATA *method_data;
};
初次学习看到这个一头雾水,但没有关系我们一个个来分析,从源代码中找到源头。
首先让我们疑惑的应该是EC_GROUP结构体(crypto/ec/ec_lcl.h):
struct ec_group_st {
const EC_METHOD *meth; //方法(函数)
EC_POINT *generator; //基向量(基点)
BIGNUM order, cofactor; //基点的阶和余因子
int curve_name; //选择椭圆曲线的名字
BIGNUM a, b;//a和b确定椭圆曲线方程
//其他项此处省去
};
这里可以看到EC_GROUP结构体包含了一个椭圆曲线的基本参数,是不是感觉到豁然开朗,等等,EC_METHOD结构体又是什么?
别着急,我们再来找一下EC_METHOD在哪里定义。
EC_METHOD结构体定义如下(crypto/ec/ec_lcl.h)
struct ec_method_st {
int flags;
int field_type;
int (*group_init) (EC_GROUP *);
void (*group_finish) (EC_GROUP *);
void (*group_clear_finish) (EC_GROUP *);
int (*group_copy) (EC_GROUP *, const EC_GROUP *);
//其他函数声明此处省去
};
当打开源代码看到EC_METHOD的结