實現橢圓曲線上離散對數問題的求解

密碼學實驗課的題目,分享一下自己的代碼,可能不夠完美,供參考~自己動手纔是王道哦!

一、實驗目的

  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;
}

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章