- 实验目的
熟悉EIGamal加解密算法的构造和运行过程,加深离散对数问题的理解。
二、 实验原理
读取消息M
使用serializeMsg函数转化消息M
serializeMsg函数的运行结果是将明文每个数字加上256后拼接在一起
素数p和随机数g,x为随机选择数
y使用公式y=g ^ x mod p来计算
k为随机大整数,使用getPrime函数生成
a为密文二元组的c1,使用公式y=g ^ k mod p来计算
b为密文二元组的c1,使用公式b=mb * y ^ k mod p来计算,其中mb为扩充明文m使用BigInteger类封装后的大整数
现在已经得到了密文二元组(a,b)
md为扩充明文,使用公式b * ( a ^ x ) ^ ( - 1 ) mod p来计算
使用deSerializeMsg函数将扩充明文md转化为原来明文ms
四 、代码实现
package ea;
import java.math.BigInteger;
import java.lang.Math;
import java.util.Random;
import java.io.*;
public class ElGamal {
public static BigInteger getPrime(int bitLenth) {
BigInteger p = BigInteger.probablePrime(bitLenth, new Random());
while(!p.isProbablePrime(6)) {
p.nextProbablePrime();
}
return p;
}
public static BigInteger encrypt (BigInteger m, BigInteger y, BigInteger k, BigInteger p) {
BigInteger b = null;
b = m.multiply(y.modPow(k,p)).mod(p);
return b;
}
public static BigInteger decrypt (BigInteger b, BigInteger a, BigInteger x, BigInteger p) {
BigInteger m = b.multiply(a.modPow(x.negate(),p)).mod(p);
return m;
}
public static String serializeMsg (String str) {
byte[] b = null;
StringBuffer sb = new StringBuffer();
b = str.getBytes();
for(byte bb : b){
sb.append(((int)bb + 256));
}
return sb.toString();
}
public static String deSerializeMsg (String num) {
String str = null;
byte [] b = new byte[num.length()];
for (int i = 0, j = 0; i <= num.length() - 3; i+=3,j++) {
b[j] = (byte)(Integer.parseInt(num.substring(i,i+3)) - 256);
}
str = new String(b);
return str;
}
public static void main (String [] args) {
BigInteger p = null;
BigInteger g = null;
BigInteger x = null;
BigInteger y = null;
String m0 = "";
System.out.println("请输入消息M:");
InputStream clav= System.in;
BufferedReader rd = new BufferedReader(new InputStreamReader(clav));
try {m0 = rd.readLine();}
catch(IOException e) {System.out.println(e.getMessage());}
String m = ElGamal.serializeMsg(m0);
System.out.println("m = " + m);
int len = m.length() * 8;
p = ElGamal.getPrime(len);
System.out.println("p = "+p.toString());
g = new BigInteger(len,new Random());
System.out.println("g = "+g.toString());
x = new BigInteger(len,new Random());
System.out.println("x = "+x.toString());
y = g.modPow(x,p);
System.out.println("y = "+y.toString());
BigInteger k = ElGamal.getPrime(len+1);
System.out.println("k = "+k.toString());
BigInteger a = g.modPow(k,p);
System.out.println("a = "+a.toString());
BigInteger mb = new BigInteger(m);
System.out.println("mb = "+mb.toString());
BigInteger b = ElGamal.encrypt(mb,y,k,p);
System.out.println("b = "+b.toString());
BigInteger md = ElGamal.decrypt(b,a,x,p);
System.out.println("md = "+md.toString());
String ms = ElGamal.deSerializeMsg(md.toString());
System.out.println("ms = " + ms);
}
结果:



