椭圆曲线上的elgamal的Java实现

计算机密码学作业,计算过程过于麻烦且容易出错,写了个java程序,偷偷懒。

本程序实现了 求接收者的公钥,发送者对明文的加密。

目录

类Pkey.java   主要运行程序

类V.java   自己定义的矢量类,变量x,y表示矢量(x,y)

程序实现的难点在于求模

负数模整数

分数模整数


类Pkey.java   主要运行程序

import java.util.Scanner;
public class PKey {

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
//椭圆的相关信息的输入		
		//------------椭圆E(a,b);
		System.out.println("椭圆E(a,b):");
		String s = scanner.nextLine();
		String []ss = s.split(",");
		int a = Integer.parseInt(ss[0]);
		int b = Integer.parseInt(ss[1]);
		//------------阶n
		System.out.println("阶n:");
		int n = Integer.parseInt(scanner.nextLine());
		//----------生成元G(Gx,Gy)
		System.out.println("生成元G(Gx,Gy):");
		s = scanner.nextLine();
		ss = s.split(",");
		int Gx = Integer.parseInt(ss[0]);
		int Gy = Integer.parseInt(ss[1]);
		V G = new V(Gx,Gy);
		System.out.println("---------------------------------");
//接收者计算公钥
		//-------------输入私钥x
		System.out.println("私钥x: ");
		int x = Integer.parseInt(scanner.nextLine());
		
		
		//-------------计算公钥Pkey
		V Pkey = GeneratePkey(G, x, a , n);
		System.out.println("公钥Pkey = (" + Pkey.x + "," +Pkey.y + ")");
		System.out.println("---------------------------------");
//发送者给密文加密
		//-------------------随机输入的k
		System.out.println("随机输入k:");
		int k = Integer.parseInt(scanner.nextLine());
		//-------------------输入明文M(m1,m2)
		System.out.println("明文M(m1,m2):");
		s = scanner.nextLine();
		ss = s.split(",");
		int m1 = Integer.parseInt(ss[0]);
		int m2 = Integer.parseInt(ss[1]);
		V M = new V(m1,m2);
		//------------------计算出密文C(c1,c2);
		V[] C = GenerateC(Pkey,M,G,k,n,a);
		System.out.println("密文C(c1,c2) = {" + C[0] + " , " + C[1]+ "}" );
	}
	
	//计算出密文C  c1 = kG, c2 = M + k Pkey;
	private static V[] GenerateC(V pkey, V m, V g, int k, int n, int a) {
		V[] C =new V[2];
		//计算c1
		C[0] = GeneratePkey(g,k,a,n);  //因为c1 = kG 和 公钥Pkey = xG计算方法相同
		System.out.println("c1 = " + C[0] );
		System.out.println("---------------------------------");
		// 计算c2
		C[1] = Vadd(m,GeneratePkey(pkey,k,a,n),a,n);
		System.out.println("c2 = " + C[1] );
		System.out.println("---------------------------------");
		return C;
	}

	
	//计算出公钥   通过私钥x和生成元G   Pkey = xG
	private static V GeneratePkey(V G, int x,int a, int n) {
		V Pkey = new V(G.x,G.y);
		for(int i = 1; i < x; i++) {
			Pkey = Vadd(Pkey,G, a, n);
		}
		return Pkey;
	}
	
	
	//椭圆上矢量的加法
	private static V Vadd(V g1, V g2, int a, int n) {
		V ret = new V();
		int langda = 0;
		//求langda
		if(g1.x == g2.x && g1.y ==g2.y) {
			langda = mod(3 * g1.x * g1.x +a , 2 * g1.y,n);
		}else {
			langda = mod(g2.y - g1.y,g2.x - g1.x,n);
		}
		System.out.println("landa = " + langda);
		//求矢量加法之后的x和y坐标
		ret.x = ((langda * langda - g1.x - g2.x) % n + n)%n;
		ret.y = ((langda * (g1.x - ret.x) - g1.y) % n + n) %n;
		System.out.println(g1 + " + " + g2 + " = " + ret);
		return ret;
	}
	
	
	//分数模整数
	private static int mod(int i,int j, int n) {
		for(int k = 0; ; k++ ) {
			//由于负数mod整数结果为负数。于是将mod得的结果+n  mod n
			if(((k * j)%n + n)% n ==(i %n + n) %n)
				return k;
		}
	}

}

类V.java   自己定义的矢量类,变量x,y表示矢量(x,y)

public class V {
	
	int x;
	int y;
	public V() {
		super();
		
	}
	public V(int x, int y) {
		super();
		this.x = x;
		this.y = y;
	}
	@Override
//重写tostring是为了   让打印矢量时形式为(x,y)
	public String toString() {
		return "(" + x + "," + y + ")";
	}
	
	
}

程序实现的难点在于求模

在于实现负数模整数以及分数模整数

负数模整数

y = (x % n + n) % n;   //java程序中 -1 % 5 = -1; 为了让-1 % 5 = 4. 将结果 + n 再% n

            java程序中 -1 % 5 = -1; 为了让-1 % 5 = 4. 将结果 + n 再% n 

分数模整数

	//分数模整数
	private static int mod(int i,int j, int n) {
		for(int k = 0; ; k++ ) {
			//由于负数mod整数结果为负数。于是将mod得的结果+n  mod n
			if(((k * j)%n + n)% n ==(i %n + n) %n)
				return k;
		}
	}

         求分数模整数的结果, x =   a/b mod n,实则在求x,满足bx mod n= a mod n。本程序使用穷举求得分别是分数模整数的结果

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读