实现椭圆曲线上离散对数问题的求解

密码学实验课的题目,分享一下自己的代码,可能不够完美,供参考~自己动手才是王道哦!

一、实验目的

  1. 掌握椭圆曲线上的加法定律;
  2. 熟练求解椭圆曲线上的离散对数问题。

二、实验原理

(1)有限域GF§上的椭圆曲线:对于固定的a和b,满足形如方程
y2≡x3+ax+b(mod p) ( a,b,x,yGF§且4a3+27b2(mod p)≠0).
(2)椭圆曲线Ep(a,b)上的加法定义如下:
设P, Q, REp(a,b),则
①P+O=O+P=P;
②若P=(x,y),那么(x, y)+(x, -y)=O,即(x, -y)是P的加法逆元,记为-P;
③P+Q=Q+P;
④(P+Q)+R=P+(Q+R);
⑤设P=(x1,y1),Q=(x2,y2),P≠-Q,则P+Q=(x3,y3)由以下确定:
x3≡λ2-x1-x2(mod p)
y3≡λ(x1-x3)-y1(mod p)
其中。
(3)椭圆曲线上的离散对数问题(ECDLP):
用E(GF§)表示定义在有限域GF§上椭圆曲线E的有理子群,设任意两点P,QE (GF§)。求使kP=Q成立的k值问题就是E上的椭圆曲线离散对数问题。

三、实验要求

编程求解椭圆曲线上的离散对数问题,主要包括椭圆曲线上的加法函数,乘法逆元的求解,以及验证点是否在椭圆曲线上等。

四、实验内容

GF(29)上曲线E:y2=x3+4x+20 (mod p);E上两点P=(13,23),Q=(3,28)。编程求解k使满足kP=Q。

五、 源代码

// 密码学08.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
using  namespace std;
int qx ;
int qy ;

class Point{
public:
	Point(int a, int b):px(a),py(b){}
	int getx(){ return px; }
	int gety(){ return py; }
	Point add(Point p2);
private:
	int px, py;
};

int x, y, q;
int func(int a, int  b){
	if (b == 0){
		x = 1; y = 0; q = a;
	}
	else{
		func(b, a%b);
		double t = x;
		x = y; y = t - a / b*y;
	}
	return y;//y是 b mod a的逆元 不保证y在一定范围内
}
Point Point:: add(Point p2){
	int x1 = px;
	int y1 = py;
	int x2 = p2.getx();
	int y2 = p2.gety();
	int r = 0;
	int x3 = x1, y3 = y1;
		if (x1 == x2&&y1 == y2){
			int ni = func(29, 2 * y1);
			while (ni<0){
				ni += 29;
			}
			r = ((3 * x1*x1 + 4)*ni)%29;
		}
		else{
			int x21 = x2 - x1;
			while (x21 < 0){ x21 = x21 + 29; }
			int ni = func(29, x21);
			while (ni<0){
				ni += 29;
			}
			r = ((y2 - y1)*ni)%29;
		}
    x3 = (r*r - x1 - x2);
	while (x3 < 0 || x3 >= 29){
		if (x3 < 0){ x3 = x3 + 29; }
		else{ x3 = x3 - 29; }
	}
    y3 = (r*(x1 - x3) - y1);
	while (y3< 0 || y3 >= 29){
		if (y3 < 0){y3 = y3 + 29; }
		else{ y3= y3 - 29; }
	}
	return Point(x3, y3);

}
int qiuk(){
	Point p(13, 23);
	Point pp = p;
	for (int i = 0;; i++){
		if (pp.getx() == 3 && pp.gety() == 28){
			return (i + 1);
		}
		pp = pp.add(p);
	}
}
int _tmain(int argc, _TCHAR* argv[])
{
	cout << "曲线E:y2=x3+4x+20 (mod 29)" << endl;
	cout << "点P=(13,23),Q=(3,28)" << endl;
	cout << "满足kP=Q的k是:" << endl;
	cout <<qiuk()<<endl;
	return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42189863/article/details/86490100
今日推荐