ElGamal算法java实现

ElGamal算法,是一种较为常见的加密算法,它是基于1985年提出的公钥密码体制和椭圆曲线加密体系。既能用于数据加密也能用于数字签名,其安全性依赖于计算有限域上离散对数这一难题。在加密过程中,生成的密文长度是明文的两倍,且每次加密后都会在密文中生成一个随机数K,在密码中主要应用离散对数问题的几个性质:求解离散对数(可能)是困难的,而其逆运算指数运算可以应用平方-乘的方法有效地计算。

import java.math.BigInteger;
import java.util.Random;
 
public class EIG {
    public static void main(String[] args) {
 
    }
    /*
        y=α^x(mod p),1≤x≤p-1
        x=logαy,1≤y≤p-1
     */
    public BigInteger p, alpha, y;
    private BigInteger d;   //private key
 
    public EIG() {
        do {
            p = BigInteger.probablePrime(100, new Random());
        } while (p.subtract(BigInteger.ONE).divide(new BigInteger("2")).isProbablePrime(100));
        do {
            alpha = new BigInteger(100, new Random());
        } while (! isOrigin(alpha, p));
        do {
            d = new BigInteger(100, new Random());
        } while (d.compareTo(BigInteger.ONE) != 1 || d.compareTo(p.subtract(BigInteger.ONE)) != -1);
        y = alpha.modPow(d, p);
    }
 
    public EIG(BigInteger p, BigInteger alpha, BigInteger d) {
        this.p = p;
        this.alpha = alpha;
        this.d = d;
        y = alpha.modPow(d, p);
    }
 
    /**
     * 加密
     * @param M
     * @return
     */
    BigInteger[] encrypt(BigInteger M) {
        BigInteger[] C = new BigInteger[2];
        BigInteger k, U;
        do {
            do {
                k = new BigInteger(100, new Random());
            } while (k.compareTo(BigInteger.ONE) != 1 || k.compareTo(p.subtract(BigInteger.ONE)) != -1);
            U = y.modPow(k, p);
        } while (U.intValue() != 1);
        C[0] = alpha.modPow(k, p);
        C[1] = U.multiply(M).mod(p);
        return C;
    }
 
    /**
     * 加密
     * @param M
     * @param k
     * @return
     */
    BigInteger[] encrypt(BigInteger M, BigInteger k) {
        BigInteger[] C = new BigInteger[2];
        BigInteger U = y.modPow(k, p);
        C[0] = alpha.modPow(k, p);
        C[1] = U.multiply(M).mod(p);
        return C;
    }
 
    /**
     * 解密
     * @param C
     * @return
     */
    BigInteger decrypt(BigInteger[] C) {
        BigInteger V = C[0].modPow(d, p);
        BigInteger M = C[1].multiply(V.modPow(new BigInteger("-1"), p)).mod(p);
        return M;
    }
 
    /**
     * 判断a是否为模m的原根,其中m为素数
     * @param a
     * @param m
     * @return
     */
    static boolean isOrigin(BigInteger a, BigInteger m) {
        if (a.gcd(m).intValue() != 1) return false;
        BigInteger i = new BigInteger("2");
        while (i.compareTo(m.subtract(BigInteger.ONE)) == -1) {
            if (m.mod(i).intValue() == 0) {
                if (a.modPow(i, m).intValue() == 1)
                    return false;
                while (m.mod(i).intValue() == 0)
                    m = m.divide(i);
            }
            i = i.add(BigInteger.ONE);
        }
        return true;
    }
 
    public BigInteger getD() {
        return d;
    }
 
 
 
}
import java.math.BigInteger;
 
public class test {
    public static void main(String[] args) {
        //BigInteger p=BigInteger.valueOf(2579L);
        System.out.println("initial...");
        BigInteger p=new BigInteger("2579");
        BigInteger alpha=new BigInteger("2");
        BigInteger d=new BigInteger("765");//sk
        EIG elGamalDemo=new EIG(p,alpha,d);
 
        System.out.println("System Parameter...");
        System.out.println("p="+elGamalDemo.p);
        System.out.println("alpha="+elGamalDemo.alpha);
        System.out.println("d="+elGamalDemo.getD());
        System.out.println("y="+elGamalDemo.y);
 
        BigInteger M=new BigInteger("2023");
        BigInteger k=new BigInteger("853");
        System.out.println("M="+M);
 
        System.out.println("Encrypt...");
        BigInteger[] C=elGamalDemo.encrypt(M,k);
        System.out.print("After encryption : ");
        System.out.println(C[0]+" "+C[1]);
 
        BigInteger newM=elGamalDemo.decrypt(C);
        System.out.println("Decrypt...");
        System.out.print("After decryption : ");
        System.out.println(newM);
 
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超翔之逸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值