有限域F_p上的椭圆曲线E:y^2=x^3+ax+b(mod p)的Mordell-Weil群的计算
Posted 华仔Ivan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了有限域F_p上的椭圆曲线E:y^2=x^3+ax+b(mod p)的Mordell-Weil群的计算相关的知识,希望对你有一定的参考价值。
D:\\MathTool\\gaptool>ECGroup 2 1 13
y^2=x^3+2x+1(mod13)=>GAP[8,1]:
0->(0,0),ord=1=>0->(0,0),ord=1
1->(0,1),ord=8=>2->(0,12),ord=8
2->(0,12),ord=8=>1->(0,1),ord=8
3->(1,2),ord=4=>4->(1,11),ord=4
4->(1,11),ord=4=>3->(1,2),ord=4
5->(2,0),ord=2=>5->(2,0),ord=2
6->(8,3),ord=8=>7->(8,10),ord=8
7->(8,10),ord=8=>6->(8,3),ord=8
1 2 3 4 5 6 7 8
2 5 1 3 8 7 4 6
3 1 4 7 2 8 6 5
4 3 7 6 1 5 8 2
5 8 2 1 6 4 3 7
6 7 8 5 4 1 2 3
7 4 6 8 3 2 5 1
8 6 5 2 7 3 1 4
D:\\MathTool\\gaptool>ECGroup 4 20 29
y^2=x^3+4x+20(mod29)=>GAP[37,1]:
0->(0,0),ord=1=>0->(0,0),ord=1
1->(0,7),ord=37=>2->(0,22),ord=37
2->(0,22),ord=37=>1->(0,7),ord=37
3->(1,5),ord=37=>4->(1,24),ord=37
4->(1,24),ord=37=>3->(1,5),ord=37
5->(2,6),ord=37=>6->(2,23),ord=37
6->(2,23),ord=37=>5->(2,6),ord=37
7->(3,1),ord=37=>8->(3,28),ord=37
8->(3,28),ord=37=>7->(3,1),ord=37
9->(4,10),ord=37=>10->(4,19),ord=37
10->(4,19),ord=37=>9->(4,10),ord=37
11->(5,7),ord=37=>12->(5,22),ord=37
12->(5,22),ord=37=>11->(5,7),ord=37
13->(6,12),ord=37=>14->(6,17),ord=37
14->(6,17),ord=37=>13->(6,12),ord=37
15->(8,10),ord=37=>16->(8,19),ord=37
16->(8,19),ord=37=>15->(8,10),ord=37
17->(10,4),ord=37=>18->(10,25),ord=37
18->(10,25),ord=37=>17->(10,4),ord=37
19->(13,6),ord=37=>20->(13,23),ord=37
20->(13,23),ord=37=>19->(13,6),ord=37
21->(14,6),ord=37=>22->(14,23),ord=37
22->(14,23),ord=37=>21->(14,6),ord=37
23->(15,2),ord=37=>24->(15,27),ord=37
24->(15,27),ord=37=>23->(15,2),ord=37
25->(16,2),ord=37=>26->(16,27),ord=37
26->(16,27),ord=37=>25->(16,2),ord=37
27->(17,10),ord=37=>28->(17,19),ord=37
28->(17,19),ord=37=>27->(17,10),ord=37
29->(19,13),ord=37=>30->(19,16),ord=37
30->(19,16),ord=37=>29->(19,13),ord=37
31->(20,3),ord=37=>32->(20,26),ord=37
32->(20,26),ord=37=>31->(20,3),ord=37
33->(24,7),ord=37=>34->(24,22),ord=37
34->(24,22),ord=37=>33->(24,7),ord=37
35->(27,2),ord=37=>36->(27,27),ord=37
36->(27,27),ord=37=>35->(27,2),ord=37
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
2 14 1 9 37 32 11 5 29 6 12 35 10 18 3 17 27 21 15 19 28 30 34 36 31 16 33 8 20 24 23 26 7 13 22 4 25
3 1 15 36 8 10 33 28 4 13 7 11 34 2 19 26 16 14 20 29 18 35 31 30 37 32 17 21 9 22 25 6 27 23 12 24 5
4 9 36 11 1 37 6 3 12 5 32 26 8 29 24 23 34 20 30 22 19 17 21 33 14 31 13 15 35 27 18 25 10 28 16 7 2
5 37 8 1 10 7 36 13 2 33 4 9 27 25 28 35 22 31 21 18 23 20 16 15 32 12 30 34 14 19 26 11 24 17 29 3 6
6 32 10 37 7 4 1 33 25 36 2 14 24 26 13 20 19 16 34 23 17 21 22 8 12 29 15 27 31 28 35 9 3 30 18 5 11
7 11 33 6 36 1 5 24 32 3 37 25 15 12 27 18 21 35 17 16 22 23 20 13 9 14 28 30 26 34 29 2 8 19 31 10 4
8 5 28 3 13 33 24 34 1 27 36 4 17 37 21 12 35 25 18 14 31 29 26 19 6 11 22 23 2 20 32 7 30 16 9 15 10
9 29 4 12 2 25 32 1 35 37 26 16 5 20 36 34 13 19 24 30 15 27 28 7 18 23 10 3 22 33 21 31 6 8 17 11 14
10 6 13 5 33 36 3 27 37 24 1 2 30 32 34 29 20 26 23 31 16 18 35 28 11 9 19 17 25 21 12 4 15 22 14 8 7
11 12 7 32 4 2 37 36 26 1 25 31 3 35 33 21 28 22 27 17 30 34 19 10 29 18 8 24 16 13 20 14 5 15 23 6 9
12 35 11 26 9 14 25 4 16 2 31 23 1 22 7 28 8 30 33 27 24 13 15 6 20 21 5 36 17 10 19 18 37 3 34 32 29
13 10 34 8 27 24 15 17 5 30 3 1 22 6 23 9 29 32 31 25 26 14 12 21 7 4 20 16 37 18 11 36 19 35 2 28 33
14 18 2 29 25 26 12 37 20 32 35 22 6 21 1 27 33 28 3 15 8 24 13 4 23 17 7 5 19 36 34 16 11 10 30 9 31
15 3 19 24 28 13 27 21 36 34 33 7 23 1 20 32 26 2 29 9 14 12 25 22 5 6 16 18 4 35 37 10 17 31 11 30 8
16 17 26 23 35 20 18 12 34 29 21 28 9 27 32 3 1 33 6 10 7 5 36 25 30 15 2 11 13 37 24 19 14 4 8 31 22
17 27 16 34 22 19 21 35 13 20 28 8 29 33 26 1 2 7 32 6 11 37 4 31 24 3 14 12 10 25 36 15 18 9 5 23 30
18 21 14 20 31 16 35 25 19 26 22 30 32 28 2 33 7 8 1 3 5 36 10 9 34 27 11 37 15 4 13 17 12 6 24 29 23
19 15 20 30 21 34 17 18 24 23 27 33 31 3 29 6 32 1 9 4 2 11 37 35 8 10 26 14 36 12 5 13 16 25 7 22 28
20 19 29 22 18 23 16 14 30 31 17 27 25 15 9 10 6 3 4 36 1 7 5 12 28 13 32 2 24 11 8 34 26 37 33 35 21
21 28 18 19 23 17 22 31 15 16 30 24 26 8 14 7 11 5 2 1 37 4 6 29 13 33 12 25 3 9 10 27 35 32 36 20 34
22 30 35 17 20 21 23 29 27 18 34 13 14 24 12 5 37 36 11 7 4 6 1 26 15 8 25 9 33 32 3 28 31 2 10 16 19
23 34 31 21 16 22 20 26 28 35 19 15 12 13 25 36 4 10 37 5 6 1 7 14 27 24 9 32 8 2 33 30 29 11 3 18 17
24 36 30 33 15 8 13 19 7 28 10 6 21 4 22 25 31 9 35 12 29 26 14 17 1 37 23 20 11 16 2 5 34 18 32 27 3
25 31 37 14 32 12 9 6 18 11 29 20 7 23 5 30 24 34 8 28 13 15 27 1 16 22 36 10 21 3 17 35 4 33 19 2 26
26 16 32 31 12 29 14 11 23 9 18 21 4 17 6 15 3 27 10 13 33 8 24 37 22 19 1 7 34 5 30 20 2 36 28 25 35
27 33 17 13 30 15 28 22 10 19 8 5 20 7 16 2 14 11 26 32 12 25 9 23 36 1 18 35 6 31 4 3 21 29 37 34 24
28 8 21 15 34 27 30 23 3 17 24 36 16 5 18 11 12 37 14 2 25 9 32 20 10 7 35 31 1 29 6 33 22 26 4 19 13
29 20 9 35 14 31 26 2 22 25 16 17 37 19 4 13 10 15 36 24 3 33 8 11 21 34 6 1 30 7 28 23 32 5 27 12 18
30 24 22 27 19 28 34 20 33 21 13 10 18 36 35 37 25 4 12 11 9 32 2 16 3 5 31 29 7 26 1 8 23 14 6 17 15
31 23 25 18 26 35 29 32 21 12 20 19 11 34 37 24 36 13 5 8 10 3 33 2 17 30 4 6 28 1 27 22 9 7 15 14 16
32 26 6 25 11 9 2 7 31 4 14 18 36 16 10 19 15 17 13 34 27 28 30 5 35 20 3 33 23 8 22 29 1 24 21 37 12
33 7 27 10 24 3 8 30 6 15 5 37 19 11 17 14 18 12 16 26 35 31 29 34 4 2 21 22 32 23 9 1 28 20 25 13 36
34 13 23 28 17 30 19 16 8 22 15 3 35 10 31 4 9 6 25 37 32 2 11 18 33 36 29 26 5 14 7 24 20 12 1 21 27
35 22 12 16 29 18 31 9 17 14 23 34 2 30 11 8 5 24 7 33 36 10 3 32 19 28 37 4 27 6 15 21 25 1 13 26 20
36 4 24 7 3 5 10 15 11 8 6 32 28 9 30 31 23 29 22 35 20 16 18 27 2 25 34 19 12 17 14 37 13 21 26 33 1
37 25 5 2 6 11 4 10 14 7 9 29 33 31 8 22 30 23 28 21 34 19 17 3 26 35 24 13 18 15 16 12 36 27 20 1 32
#include"IGroup.h"
#include<functional>
#include<iostream>
#include<vector>
#include<cassert>
using namespace std;
/*
本程序计算有限域F_p上的椭圆曲线E:y^2=x^3+ax+b(mod p)的#E阶交换群结构。
椭圆曲线上有理点全体构成一个Abel群。也就是说群的元素现在不是数而是点。因此我们必须规定,两个点的和(我们用(+)表示)应该是哪一点?每个点的逆元素是什么?然后再验证它们是否满足Abel群的几条公理。
1.首先我们规定每一点P的反点~P。即如果P(x,y)是椭圆曲线上一点,则(x,-y)也是椭圆曲线上一点,我们称它为P(x,y)的反点,记作~P(x,-y)。
2.现在我们定义两点P_1(x_1,y_1)和P_2(x_2,y_2)的加法运算(+)。如果连接P_1与P_2的直线与椭圆曲线相交于一点P_3,则定义其和为P_3的反点:P_1(+)P_2=~P_3。
3.每一点的逆元素为其反点。
4.零元素为无穷原点。
已知有限域F_p上的椭圆曲线群E(F_p):(x,y)|y^2=x^3+ax+b,a,b∈F_p∪O,以及点P=(x,y)的阶为一个大素数,
那么给定整数a,计算点aP=(x_a,y_a)=Q很容易;给定点Q,计算整数x,使得xP=Q非常困难。
假定有椭圆曲线上的点P和B并且我们知道有某个整数k满足B=kP=P+P+…+P。找到这个k就被称为椭圆曲线上的离散对数问题。
数论和算术中常用的形式EC3:y^2=x^3+ax+b(mod p)
Mordell-Weil定理:椭圆曲线上有理点构成的群是有限生成的。
Siegel定理:椭圆曲线上的整点只有有限多个。
y^2=x^3+4x+20(mod29)=>GAP[37,1]:
y^2=x^3+1x+1(mod5)=>GAP[9,1]:
y^2=x^3+1x+1(mod7)=>GAP[5,1]:
y^2=x^3+1x+1(mod11)=>GAP[14,2]:
y^2=x^3+1x+1(mod13)=>GAP[18,2]:
y^2=x^3+1x+7(mod17)=>GAP[12,5]:
y^2=x^3+1x+11(mod17)=>GAP[20,2]:
y^2=x^3+2x+1(mod5)=>GAP[7,1]:
y^2=x^3+2x+1(mod7)=>GAP[5,1]:
y^2=x^3+2x+1(mod11)=>GAP[16,1]:
y^2=x^3+2x+1(mod13)=>GAP[8,1]:
y^2=x^3+2x+1(mod17)=>GAP[24,9]:
*/
// y^2=x^3+ax+b
typedef int(*pFuncInt2)(int x,int a,int b);
typedef pair<int,int> IntPoint;
IntPoint g_Zero=make_pair(0,0);// 无穷远点,与有限整点区分开来即可,加法群的单位元
//struct IntPoint
//
// int x;
// int y;
//;
struct EC3:public IGroup
public:
// 静态函数
static int Mod(int ret,unsigned int n);
static int minv(int a,int b,int c);
static int calk(int a,int p,int xp,int yp,int xq,int yq);
static IntPoint Add(int a,int p,const IntPoint &P,const IntPoint &Q);// R=P+Q
public:
// 实现抽象基类的方法
virtual void printSet();
virtual void printTable();
virtual int mul(int a,int b);
virtual int size();
virtual int inv(int a);
// 构造函数
EC3(int a,int b,int p);
// 析构函数
~EC3();
// 成员函数
// 成员变量
vector<IntPoint> m_Set;
function<int(int,int,int)> m_PolygonEC;
int m_a;
int m_b;
int m_p;
;
int EC3::Mod(int ret,unsigned int n)
assert(n>0);
if(ret<0)
int ret1=ret+(-ret+1)*n;
return ret1%n;
return ret%n;
int EC3::minv(int a,int b,int c)
int ret=1;
a=a%c;
while(b)
if(b&1)
ret=(ret*a)%c;
a=(a*a)%c;
b=b>>1;
return ret;
int EC3::calk(int a,int p,int xp,int yp,int xq,int yq)
if(xp==xq&&yp==yq)
return (((3*xp*xp+a)*minv(2*yp,p-2,p))%p+p)%p;
return (((yq-yp)*minv(xq-xp,p-2,p))%p+p)%p;
IntPoint EC3::Add(int a,int p,const IntPoint &P,const IntPoint &Q)
int x1=P.first;
int y1=P.second;
int x2=Q.first;
int y2=Q.second;
int t=calk(a,p,x1,y1,x2,y2);
int x3=((t*t-x1-x2)%p+p)%p;
int y3=((t*(x1-x3)-y1)%p+p)%p;
return make_pair(x3,y3);
EC3::EC3(int a,int b,int p):m_a(a),m_b(b),m_p(p)
m_PolygonEC=[=](int x,int a,int b)return x*x*x+a*x+b;;
m_Set.push_back(g_Zero);
for(int i=0;i<p;i++)
for(int j=0;j<p;j++)
if(Mod(m_PolygonEC(i,a,b),p)==Mod(j*j,p))
m_Set.push_back(make_pair(i,j));
void EC3::printSet()
int ID=IdGroup(this);
printf("y^2=x^3+%dx+%d(mod%d)=>GAP[%d,%d]:\\n",m_a,m_b,m_p,size(),ID);
function<int(int)> ord=[=](int a)vector<int> S1=Order(this,a);int o=S1.size();return o;;
for(int i=0;i<size();i++)
IntPoint I=m_Set[i];
int i1=inv(i);
IntPoint I1=m_Set[i1];
int o=ord(i);
int o1=ord(i1);
printf("%d->(%d,%d),ord=%d=>%d->(%d,%d),ord=%d\\n",i,I.first,I.second,o,i1,I1.first,I1.second,o1);
void EC3::printTable()
printGroup(this);
int EC3::mul(int a,int b)
if(a<0||b<0)
return -1;
if(a==0)
return b;
if(b==0)
return a;
if(m_Set[a].first==m_Set[b].first && m_Set[a].second+m_Set[b].second==m_p)
return 0;
if(a==b && m_Set[a].second==0)
return 0;
IntPoint R=Add(m_a,m_p,m_Set[a],m_Set[b]);
int ret=-1;
vector<IntPoint>::iterator p=std::find(m_Set.begin(),m_Set.end(),R);
if(p!=m_Set.end())
ret=p-m_Set.begin();
else
//cout<<"("<<R.first<<","<<R.second<<")";
return ret;
int EC3::size()
return m_Set.size();
int EC3::inv(int a)
vector<int> S1=Order(this,a);
int ord=S1.size();
return S1[ord-1];
void test()
// E:y^2=x^3+4x+20(mod29)
EC3 c37(4,20,29);
//cout<<"有限整点个数:"<<c37.size()-1<<endl;
//for(int i=1;i<c37.size();i++)
// cout<<"("<<c37.m_Set[i].first<<","<<c37.m_Set[i].second<<")";
// if(i<c37.size())
// cout<<",";
//
//cout<<endl;
c37.printSet();
//c37.printTable();
EC3 c9(1,1,5);
c9.printSet();
EC3 c5(1,1,7);
c5.printSet();
EC3 c14(1,1,11);
c14.printSet();
EC3 c18(1,1,13);
c18.printSet();
EC3 c18a(1,1,17);
c18a.printSet();
EC3 c2c2c3(1,7,17);
c2c2c3.printSet();
EC3 c20(1,11,17);
c20.printSet();
EC3 c7(2,1,5);
c7.printSet();
EC3 c5a(2,1,7);
c5a.printSet();
EC3 c16(2,1,11);
c16.printSet();
EC3 c8(2,1,13);
c8.printSet();
EC3 c2c12(2,1,17);
c2c12.printSet();
bool IsPrime(unsigned int N)
if(N==0||N==1)
return false;
int up=sqrt((float)N);
for(int i=2;i<=up;i++)
if(N%i==0)
return false;
return true;
int main(int argc, char* argv[])
#if 0
test();
system("pause");
return 0;
#endif
char sz[100]=0;
if(argc<4)
printf("Usage: ECGroup a b p\\n");
return 0;
int a=atoi(argv[1]);
int b=atoi(argv[2]);
int p=atoi(argv[3]);
if(a<1||b<1||!IsPrime(p))
return 0;
EC3 E(a,b,p);
E.printSet();
E.printTable();
return 0;
以上是关于有限域F_p上的椭圆曲线E:y^2=x^3+ax+b(mod p)的Mordell-Weil群的计算的主要内容,如果未能解决你的问题,请参考以下文章