2021SC@SDUSC
20 椭圆曲线
20.1 ECC介绍
椭圆曲线算法可以看作是定义在特殊集合下数的运算,满足一定的规则。
椭圆曲线在如 下两个域中定义:Fp 域和 F2m 域。
Fp 域,素数域,p 为素数;
F2m 域:特征为 2 的有限域,称之为二元域或者二进制扩展域。该域中,元素的个数为 2m 个。
椭圆曲线标准文档如下:
- X9.62
Public Key Cryptography For The Financial Services Industry: The Elliptic Curve
Digital Signature Algorithm (ECDSA); - SEC1
SEC 1:Elliptic Curve Cryptography; - SEC2
SEC 2: Recommended Elliptic Curve Domain Parameters; - NIST
(U.S.) National Institute of Standards and Technology,美国国家标准。
这些标准一般都描述了 Fp 域和 F2m 域、椭圆曲线参数、数据转换、密钥生成以及
推荐了多种椭圆曲线。
一些术语说明:
-
椭圆曲线的阶(order of a curve)
椭圆曲线所有点的个数,包括无穷远点; -
椭圆曲线上点的阶(order of a point)
P 为椭圆曲线上的点,nP=无穷远点,n 取最小整数,既是 P 的阶; -
基点(base point)
椭圆曲线参数之一,用 G 表示,是椭圆曲线上都一个点; -
余因子(cofactor)
椭圆曲线的余因子,用 h 表示,为椭圆曲线点的个数/基点的阶 -
椭圆曲线参数:
素数域:
(p,a,b,G,n,h)
其中,p 为素数,确定 Fp,a 和 b 确定椭圆曲线方程,G 为基点,
n 为 G 的阶, h 为余因子。
二进制扩展域:
(m,f(x),a,b,G,n,h)
其中,m 确定 F2m,f(x)为不可约多项式,a 和 b 用于确定椭圆曲线方程,G 为基点,
n 为 G 的阶, h 为余因子。 -
椭圆曲线公钥和私钥
椭圆曲线的私钥是一个随机整数,小于 n;
椭圆曲线的公钥是椭圆曲线上的一个点: Q = 私钥 * G。
20.2 openssl的ECC实现
Openssl实现了ECC算法。
ECC算法系列包括三部分:
1. ECC算法 (crypto/ec)、
2. 椭圆曲线数字签名算法 ECDSA (crypto/ecdsa)
3. 圆曲线密钥交换算法 ECDH (crypto/dh)
研究椭圆曲线需要注意的有:
-
密钥数据结构
主要是 公钥 和 私钥 数据结构。椭圆曲线密钥数据结构如下,定义在/crypto/ec/ec_lcl.h:272 中,对用户是透明的。
struct ec_key_st {
int version;
EC_GROUP *group;
EC_POINT *pub_key;
BIGNUM *priv_key;
/* 其他项 */
}
EC_POINT据结构如下,定义在/crypto/ec/ec_lcl.h: 287 中,
struct ec_point_st {
const EC_METHOD *meth;
/* NID for the curve if known */
int curve_name;
/*
* All members except 'meth' are handled by the method functions, even if
* they appear generic
*/
BIGNUM *X;
BIGNUM *Y;
BIGNUM *Z; /* Jacobian projective coordinates: * (X, Y,
* Z) represents (X/Z^2, Y/Z^3) if Z != 0 */
int Z_is_one; /* enable optimized point arithmetics for
* special case */
};
include/openssl/ec.h:46
typedef struct ec_point_st EC_POINT;
- 密钥生成
对照公钥和私钥的表示方法,非对称算法不同有各自的密钥生成过程。
椭圆曲线的密钥生成实现在crytpo/ec/ec_key.c中。
Openssl中,椭圆曲线密钥生成时,首先用户需要选取一种椭圆曲线
(openssl的crypto/ec_curve.c中内置实现了67种,调用EC_get_builtin_curves获取该列表),
然后根据选择的椭圆曲线计算密钥生成参数group,最后根据密钥参数group来生公私钥。
3)签名值数据结构
非对称算法不同,签名的结果表示也不一样。
与DSA签名值一样,ECDSA的签名结果表示为两项。
ECDSA的签名结果数据结构定义在crypto/ecdsa/ecdsa.h中,如下:
typedef struct ECDSA_SIG_st {
BIGNUM *r;
BIGNUM *s;
} ECDSA_SIG;
- 签名与验签
对照签名结果,研究其是如何生成的。
crypto/ecdsa/ ecs_sign.c实现了签名算法,crypto/ecdsa/ ecs_vrf.c实现了验签。
5)密钥交换
研究其密钥交换是如何进行的;crypto/ecdh/ech_ossl.c实现了密钥交换算法。
20.3 主要函数
20.3.1 参数设置
1.
int EC_POINT_set_affine_coordinates_GF2m(
const EC_GROUP *group,
EC_POINT *point,
const BIGNUM *x,
const BIGNUM *y,
BN_CTX *ctx )
说明: 设置二进制域椭圆曲线上点 point 的几何坐标;
2.
int EC_POINT_set_affine_coordinates_GFp(
const EC_GROUP *group,
EC_POINT *point,
const BIGNUM *x,
const BIGNUM *y,
BN_CTX *ctx )
说明: 设置素数域椭圆曲线上点 point 的几何坐标;
int EC_POINT_set_affine_coordinates(const EC_GROUP *group, EC_POINT *p,
const BIGNUM *x, const BIGNUM *y,
BN_CTX *ctx);
说明:设置素数域椭圆曲线上点point的几何坐标;
The functions EC_POINT_set_affine_coordinates_GFp() and EC_POINT_set_affine_coordinates_GF2m()
are synonyms for EC_POINT_set_affine_coordinates().
They are defined for backwards compatibility only and should not be used.
3.
int EC_POINT_set_compressed_coordinates_GF2m(
const EC_GROUP *group,
EC_POINT *point,
const BIGNUM *x,
int y_bit,
BN_CTX *ctx )
说明: 二进制域椭圆曲线,给定压缩坐标x和y_bit参数,设置point的几何坐标;
用于将 Octet-String转化为椭圆曲线上的点;
4.
int EC_POINT_set_compressed_coordinates_GFp(
const EC_GROUP *group,
EC_POINT *point,
const BIGNUM *x,
int y_bit,
BN_CTX *ctx)
说明: 素数域椭圆曲线,给定压缩坐标x和y_bit参数,设置point的几何坐标;
用于将 Octet-String转化为椭圆曲线上的点;
5.
int EC_POINT_set_Jprojective_coordinates_GFp(
const EC_GROUP *group,
EC_POINT *point,
const BIGNUM *x,
const BIGNUM *y,
const BIGNUM *z,
BN_CTX *ctx )
说明: 素数域椭圆曲线group,设置点point的投影坐标系坐标x、y和z;
6
int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point)
说明:将点 point 设为无穷远点
7
int EC_GROUP_set_curve_GF2m(
EC_GROUP *group,
const BIGNUM *p,
const BIGNUM *a,
const BIGNUM *b,
BN_CTX *ctx )
说明: 设置二进制域椭圆曲线参数;
8
int EC_GROUP_set_curve_GFp( EC_GROUP *group,
const BIGNUM *p,
const BIGNUM *a,
const BIGNUM *b,
BN_CTX *ctx )
说明: 设置素数域椭圆曲线参数;
9
int EC_GROUP_set_generator( EC_GROUP *group,
const EC_POINT *generator,
const BIGNUM *order,
const BIGNUM *cofactor)
说明: 设置椭圆曲线的基G; generator、order和cofactor为输入参数;
10
size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len)
说明: 设置椭圆曲线随机数,用于生成a和b;
11
EC_GROUP *EC_GROUP_new_curve_GF2m( const BIGNUM *p,
const BIGNUM *a,
const BIGNUM *b,
BN_CTX *ctx)
说明: 生成二进制域上的椭圆曲线,输入参数为p,a和b;
12
EC_GROUP *EC_GROUP_new_curve_GFp( const BIGNUM *p,
const BIGNUM *a,