如何用分布式Pollard-Rho法对椭圆曲线离散对数问题(ECDLP)进行攻击(上)

 上个学期,竞赛因为种种原因没有继续进行而搁浅。这里仅仅分享一下临时成果。
 椭圆曲线离散对数问题赛题介绍如下
在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述
 任何一个熟悉密码学的人基本上都会了解椭圆曲线离散对数问题。它比较普通素数域离散对数问题更具有难解性。因此相当多的公钥密码体制都构建在这个问题的基础上,如EC-Elgamal系统,以及数字签名、密钥交换协议等。再次不多介绍。

 接下来给出上述数据文档的内容

		椭圆曲线参数形式为
		E/F_p: y^2=x^3+ax+b,n:=#E(F_p ),P∈E(F_p),r:=order(P),R∈<P>.
		求解k,1≤k≤r,s.t.R=[k]P.

第一类曲线参数:
(1)  p:= 211108170305887; a:=0;b:=7;n:=p;r:=p;
P:=( 47815642535808, 116240163507508);
R:=( 77983503452527, 143728424564583);

(2) p:= 13835058061724614657; a:=0;b:=20;n:=p;r:=p;
P:=( 616859655854051956, 12065166484289278801);
R:=( 5170466145333976578, 7139090565738339416);

(3) p:=906694364778591846139117; a:=0; b:=2;n:=p;r:=p;
P:=(475325122433864976165476 ,666857317692667708141096 );
R:=(519814743429987512024682, 392414632044199857512746);

(4) p:= 59421121885714719481295537269; a:=0;b:=10;n:=p;r:=p;
P:=(17547290159953212409742744311, 23276625757393135830641872446);
R:=(22782721588122522786532109807, 29566916200346945584248955766);

(5) p:=3894222643901127098494944603540019; a:=0; b:=2;n:=p;r:=p;
P:=(3474281736844926688615305014567004, 3343311742974261537268420184037101);
R:=(46006664812763786791056435590121, 1631023347800240287678172773820495);

(6) p:= 255211775190703851000955237173238443091; 
a:=0;b:=32;n:=p;r:=p;
P:=(82054120567654459070422632716611948091,
208358019881453692582450632924824868211);
R:=(54625405255845450735684923869953661538,
82751760415032967427013207973543496169);

(7) p:=16725558898897967356385545845388318567564081; 
a:=0; b:=39;n:=p;r:=p;
P:=(15866255640827385375149316462253403735143979, 13637900016555731147592334085022810288787804);
R:=(1641844846280313158776293444944029290477363, 1916339757694211104728115095781816602417918);

(8) p:= 1096126227998177188652856107362412783873814431647; 
a:=0;b:=5;n:=p;r:=p;
P:= (83173790821618364013911485269418053634749973470, 331912486564013055335956381322549180967694844964);
R:=(163008382252281273947629676562612579052560281605, 50645003441262331054159546612247657430098333396);

第二类曲线参数:
(9) p:= 140737488356467; a:=1;b:=0;
n:= 140737488356468; r:= 35184372089117;
P:=( 59477512413747, 79851403980273);
R:=( 125962305399026, 124644987166940);

(10) p:= 9223372036854782251; a:=1;b:=0;
n:= 9223372036854782252; r:= 2305843009213695563;
P:=(8930887567779448763 , 890632237231967440);
R:=( 4707122633993752935 , 3224323188778636920);

(11) p:=604462909807314587364667;a:=1;b:=0;
n:=604462909807314587364668; r:=151115727451828646841167;
P:=(587411173575122535454189, 184243119926212298785598);
R:=(539012794797204313781763, 513627008874848913042314);

(12) p:= 39614081257132168796771986051; a:=1;b:=0;
n:= 39614081257132168796771986052;
r:= 9903520314283042199192996513;
P:=( 17135037968192446511660916347 , 15756828316532436197954290560);
R:=( 14307140364976860571933505517 , 31289859728052046761658770776);

(13) p:=2596148429267413814265248164627363;a:=1;b:=0;
n:=2596148429267413814265248164627364;
r:=649037107316853453566312041156841;
P:=(622497953272208887929891881018762, 578415484635633376407094129167605);
R:=(1641315995010304174750922058961802, 498062680065145119027669812682594);

(14) p:= 170141183460469231731687303715884123283; a:=1;b:=0;
n:= 170141183460469231731687303715884123284;
r:= 42535295865117307932921825928971030821;
P:=(67561795560749592594257348250381095281 ,132967032564783335773794402620839168397);
R:=( 81767392472072972289932811718039895097 , 74483734086357842747707740743879456218);

(15) p:=11150372599265311570767859136324180753031283;a:=1;b:=0;
n:=11150372599265311570767859136324180753031284;
r:=2787593149816327892691964784081045188257821;
P:=(10280081406291279076050813261615407334758360, 10524832460733629896529554181939223304289725);
R:=(1653939556554266819965991031125172966638801, 8370614898071115688249737076845551200138218);

(16) p:= 730750818665451459101842416358141509827966272147; a:=1;b:=0;
n:= 730750818665451459101842416358141509827966272148;
r:= 182687704666362864775460604089535377456991568037;
P:=(221903508784709687556506235376523499020990986034 , 287854209568598432667871196372312232614552000893);
R:=( 219270464789952726868617287704232288912801490505, 578348937880270477205296252062048509994911317888);

第三类曲线参数:
(17) p:= 140737488355333; a:=-3;b:=234;
n:= 140737484527007;r:=n;
P:= (118344265104828, 25754556069705);
R:=( 8594518695631, 14966619423525);

(18) p:= 9223372036854775837; a:=-3;b:=37;
n:= 9223372038068412403;r:=n;
P:=(7220661838117791356 ,6477969291505257777);
R:=( 7819726923954549567 ,6266868167000835108);

(19) p:=604462909807314587353111;a:=-3;b:=95;
n:= 604462909807750541909849;r:=n;
P:=(428432040100075198254744, 95025782588400118295756);
R:=(472138605558837378507194, 138148835226095728614736);

(20) p:= 39614081257132168796771975177; a:=-3;b:=562;
n:= 39614081257132147751873462213;r:=n;
P:=(39220344157117715096559716859 , 3087260393566610895498596606);
R:=( 13160703755766149325136222951 , 6533567029273948676370251736);

(21) p:= 2596148429267413814265248164610099; a:=-3;b:=171;
n:= 2596148429267413788194246433592681;r:=n;
P:=(177627746966506201527866528484813 , 1735330667419561032038559795836927);
R:=( 1575178132453901115471501570466697, 538238983595050290992251454098891);

(22) p:= 170141183460469231731687303715884105757; a:=-3;b:=33;
n:= 170141183460469231728561996679834270597; r:=n;
P:=( 96152442714630401692673834213524521597 , 58626340067602219522071225434282008266);
R:=( 47795192678737921133501161460114957836 , 166078919686417913546029950371468891352);

 在比赛文件刚刚出来时,我便开始着手尝试,作为一名ICPC选手,首先会想到接触过的大步小步(BSGS)法,这个可谓是解决离散对数问题的经典算法。对于三个文件的首个数据都在C++的long long范围之内,因此用大步小步法是可以尝试的。


注:以下关于椭圆曲线的运算,我会用乘法代表普遍而言的加法,幂次代表普遍而言的数乘,目的在于和“群”的定义更为符合


 BSGS法的内容很简单,要求解 P x = R ,   x ∈ ( 0 , n ) P^x=R,\ x \in(0,n) Px=R, x(0,n),我们可以设定一个数m,将 n n n均分成 ⌈ n m ⌉ \lceil\frac{n}{m}\rceil mn份,先求出 P 1 , P 2 … P m P^{1},P^{2}…P^{m} P1,P2Pm,将这m个值,储存于一个映射表(map)中,键为点,值为幂次,接着我们开始不断求出 Q = R ∗ P − ⌈ n m ⌉ , R ∗ P − ⌈ n m ⌉ ∗ 2 … Q=R*P^{-\lceil\frac{n}{m}\rceil},R*P^{-\lceil\frac{n}{m}\rceil*2}… Q=RPmn,RPmn2每一次尝试将点Q在映射表中查找,倘若查找到,那么有 R ∗ P − ⌈ n m ⌉ ∗ i = P j R*P^{-{\lceil\frac{n}{m}\rceil}*i}=P^{j} RPmni=Pj,于是有 R = P ⌈ n m ⌉ ∗ i + j R=P^{ {\lceil\frac{n}{m}\rceil}*i+j} R=Pmni+j,也就是得到解。
 BSGS法的本质是分块,或者比起单纯的暴力枚举,是在用空间换时间,理想状态下,空间复杂度和时间复杂度均可以做到 O ( s q r t ( n ) ) O(sqrt(n)) O(sqrt(n))级别(这里忽略映射表的修改与查找所需的复杂度)。但是注意到一般的存储设备是无法做到储存如此量级的数据的,因此真正实现BSGS法不现实,我们只可能把m设置的远小于 s q r t ( n ) sqrt(n) sqrt(n)用少量空间来换取时间,而这对于n很大的情况,效率依旧是难以被我们所接受的。
 这里给出我的第一份代码,可以解出每一组的首个数据。

//第一个版本,采用分块+map的方式,作为尝试性求解
#include<cstdio>
#include<algorithm>
#include<map>
#define mo 211108170305887LL //模数
#define a 0LL
#define b 7LL
#define x first
#define y second
using namespace std;
using LL=long long;
using Point=pair<LL,LL>; //定义ECC上的点

Point P={
   
   47815642535808LL, 116240163507508LL};
Point R={
   
   77983503452527LL, 143728424564583LL};
Point inv;
LL ans,block,sz;
map<Point,LL> M;

LL mul(LL p,LL q) //icpc 常用的快速乘模技巧
{
   
   
	p=(p%mo+mo)%mo,q=(q%mo+mo)%mo;
	return ((p*q-(LL)((long double)p/mo*q+1e-6)*mo)%mo+mo)%mo;
}

LL quick_power(LL p, LL q)  //快速幂
{
   
   
	LL res=1LL,base=p;
	while(q)
	{
   
   
		if(q&1LL)
			res=mul(res,base);
		base=mul(base,base);
		q>>=1;
	}
	return res;
}

Point Point_square(Point Q)  //点的平方
{
   
   
	Point P;
	LL tmp=mul((3LL*mul(Q.x,Q.x)%mo+a)%mo,quick_power(2LL*Q.y%mo,mo-2LL));
	P.x=(mul(tmp,tmp)-2LL*Q.x%mo+mo)%mo;
	P.y=(mul(tmp,(Q.x-P.x+mo)%mo)-Q.y+mo)%mo;
	return P;
}

Point Point_mul(Point P, Point Q)  //点的乘积
{
   
   
	if(P==Q)
		return Point_square(P);
	Point res;
	LL tmp=mul((Q.y-P.y+mo)%mo,quick_power((Q.x-P.x+mo)%mo,mo-2LL));
	res.x=(mul(tmp,tmp)-Q.x+mo-P.x+mo)%mo;
	res.y=(mul(tmp,(P.x-res.x+mo)%mo)-P.y+mo)%mo;
	return res;
}

Point Point_quick_power(Point p, LL q)  //点的快速幂
{
   
   
	Point res=p,base=p;
	--q;
	while(q)
	{
   
   
		if(q&1LL)
			res=Point_mul(res,base);
		base=Point_mul(base,base);
		q>>=1LL;
	}
	return res;
}

int main()
{
   
   
	Point PP=P,QQ=R;
	block=LL(sqrtl(mo))*10LL;  //定义分块个数,乘以10是一个内存限制的体现
	sz=(mo-1)/block+1;  //求出块的大小
	inv=Point_quick_power(P,sz);  //P^-sz
	inv.y=mo-inv.y;
	for(int i=1;i<=sz;i++)
	{
   
   
		M[PP]=i;
		PP=Point_mul(PP,P);
	}
	printf("%d",M.size());
	for(int i=0;i<=block;i++)
	{
   
   
		
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值