密码学实验课的题目,分享一下自己的代码,可能不够完美,供参考~自己动手才是王道哦!
一、实验目的
- 掌握椭圆曲线上的加法定律;
- 熟练求解椭圆曲线上的离散对数问题。
二、实验原理
(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;
}