椭圆曲线上两种基本的运算:点集运算、P+Q详解

椭圆曲线简介

RSA密码体制在我们现在还是非常常用的,但是当今,计算机运算速度之快给该加密方式带来了一定的威胁,为了保证安全性,它的密钥长度需要一再地增大,使其运算负担也随之增大。相比下,椭圆密码体制ECC(elliptic curve cryptography)可以用短得多的密钥获得同样的安全性,因而具有广泛的前景,如果没记错的话,区块链技术就有用到椭圆曲线密码体制,感兴趣的小伙伴可以了解了解。

在密码中,比较普遍的是采用有限域的椭圆曲线,有限域的椭圆曲线指的是曲线方程y2+axy+by=x3+cx2+dx+e(一般形式)中,所有系数都是某一有限域GF(p)中的元素(其中p为一个大素数)。(GF(p)是定义在整数集合{0, 1, 2, …, p-1}上的域,GF(p)上的加法和乘法分别是模加法和模乘法)。其中最常用的曲线方程是y2≡x3+ax+b(mod p)(其中a,b属于GF(p),4a3+27b2≠0)。

基本运算一:求椭圆曲线上的点集

查阅了很多网上的资料,椭圆曲线上的点集计算大多数的人都是通过代码或者伪代码(大多都是用暴力穷举)来表示给我们看。但是对于需要考试,用笔计算的我来说可能不太适用,所以在此,想和大家分享下动笔计算的方法。

步骤

以我们假定的椭圆曲线为例,即:椭圆曲线方程为:y2≡x3+x+1,p=23。所以满足a,b属于GF(p),4a3+27b2≠0。下面就开始计算点集E23(1,1),我们可以进行计算第一象限的点集,即{(x, y)|0<=x<p, 0<=y<p, x, y均为整数}:
1.对于每一x计算x3+ax+b(mod p),记录其值,假定为x’。
2. 对于每一个y计算y2(mod p),记录其值,假定为y’。
3. 如果x’==y’,就记录(x, y)这一点就是椭圆曲线点集中的一点。
4. 在这个例子中,x可以有23种可能,y也可能有23种可能,所以我们要计算232个点。
5. 最终满足条件的点所构成的集合就是该曲线方程的点集。
我们可以从步骤种看出我们所需要计算量之大,因此用程序跑,可能会省时省力。

基本运算二:P+Q

在这个计算中,P点和Q点的相加不是我们初高中所列的式子(x1+x2, y1+y2)这么简单,椭圆密码体制下的P+Q有其一套运算。

步骤

假定P点为(x1, y1),Q点为(x2, y2),P+Q为(x3, y3),因此P+Q由以下规则确定:

  1. x3≡𝜆2-x1-x2(mod p)
  2. y3≡𝜆(x1-x3)-y1(mod p)
  3. 𝜆有两种情况:(1)P=Q,(2)P≠Q
  4. P=Q情况下:𝜆=(3x12+a)/(2*y1)
  5. P≠Q的情况下:𝜆=(y2-y1)/(x2-x1)

由此我们便将P+Q计算出来了。相信大家在学习过程也碰到了2P,3P,…,NP的计算,这个不是单纯的2*P这么简单,而是要进行如P+Q的运算,如2P=P+P等等。

到此我们就把在椭圆曲线上比较基本的运算介绍完了,如有不合理的地方,希望大家能批评指正,另外希望能帮助到有需要的小伙伴们。

  • 13
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要求解椭圆曲线上的点集,首先需要定义椭圆曲线的参数,包括有限域Fp上的参数p、a、b和椭圆曲线上的基点G的坐标(x,y)。然后采用椭圆曲线上的加法运算,循环计算椭圆曲线上所有可能的点,直到出现无穷远点为止。 以下是一个简单的C++程序,可以实现求解椭圆曲线上的点集: ``` #include <iostream> #include <gmpxx.h> //需要引入gmp库 using namespace std; const mpz_class p("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"); //有限域Fp上的参数p const mpz_class a("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2C"); //椭圆曲线参数a const mpz_class b("0x0000000000000000000000000000000000000000000000000000000000000003"); //椭圆曲线参数b const mpz_class x("0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"); //基点G的x坐标 const mpz_class y("0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5"); //基点G的y坐标 mpz_class mod_inverse(mpz_class a, mpz_class n) //求逆元函数 { mpz_class x, y, gcd; mpz_gcdext(gcd.get_mpz_t(), x.get_mpz_t(), y.get_mpz_t(), a.get_mpz_t(), n.get_mpz_t()); //使用gmp库中的扩展欧几里得算法求逆元 if (gcd != 1) return 0; else return (x % n + n) % n; } class Point //定义椭圆曲线上的点类 { public: mpz_class x, y; Point() {} Point(mpz_class _x, mpz_class _y) { x = _x; y = _y; } }; Point operator +(Point p1, Point p2) //椭圆曲线上的加法运算 { Point p; mpz_class lambda; if (p1.x == p2.x && p1.y == p2.y) //点p1与点p2相等,即点p1为自己的相反点 { mpz_class inv = mod_inverse(2 * p1.y, p); //求逆元 if (inv == 0) return Point(0, 0); //不存在逆元 lambda = (3 * p1.x * p1.x + a) * inv; //计算斜率 } else //点p1与点p2不相等 { mpz_class inv = mod_inverse(p2.x - p1.x, p); //求逆元 if (inv == 0) return Point(0, 0); //不存在逆元 lambda = (p2.y - p1.y) * inv; //计算斜率 } p.x = (lambda * lambda - p1.x - p2.x) % p; //计算新点的x坐标 p.y = (lambda * (p1.x - p.x) - p1.y) % p; //计算新点的y坐标 return p; } int main() { Point G(x, y), P = G; //定义基点G和当前点P cout << "椭圆曲线上的点为:" << endl; cout << "(" << G.x << ", " << G.y << ")" << endl; //输出基点G for (int i = 1; i < 16; i++) //循环计算椭圆曲线上的点 { P = P + G; //点加运算 cout << "(" << P.x << ", " << P.y << ")" << endl; //输出当前点P } return 0; } ``` 该程序中,使用了gmp库中的mpz_class类,可以处理任意大小的整数。定义了椭圆曲线上的点类Point,以及椭圆曲线上的加法运算,使用循环计算椭圆曲线上的所有点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值