密碼學實驗課的題目,分享一下自己的代碼,可能不夠完美,供參考~自己動手纔是王道哦!
一、實驗目的
- 掌握橢圓曲線上的加法定律;
- 熟練求解橢圓曲線上的離散對數問題。
二、實驗原理
(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;
}