paillier.com.unbound.common.crypto.Paillier Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of unbound-java-provider Show documentation
Show all versions of unbound-java-provider Show documentation
This is a collection of JAVA libraries that implement Unbound cryptographic classes for JAVA provider, PKCS11 wrapper, cryptoki, and advapi
package com.unbound.common.crypto;
import com.unbound.common.Convertable;
import com.unbound.common.Converter;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.Random;
public class Paillier implements Convertable
{
private BigInteger N, NN, p, q, pp, qq, dpp, dqq, qqInv, phiN, invPhiN;
public BigInteger getP() { return p; }
public BigInteger getQ() { return q; }
public BigInteger getPhiN() { return phiN; }
public BigInteger getNN() { return NN; }
public BigInteger getInvPhiN() { return invPhiN; }
public BigInteger getPP() { return pp; }
public BigInteger getQQ() { return qq; }
public static Paillier generate(int bits)
{
Random random = new SecureRandom();
BigInteger p = BigInteger.probablePrime(bits/2, random);
BigInteger q = BigInteger.probablePrime(bits/2, random);
BigInteger N = p.multiply(q);
return new Paillier(N, p, q);
}
private void init()
{
NN = N.multiply(N);
if (p==null) return;
phiN = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE)); //phi(N) = (p-1)(q-1)
invPhiN = phiN.modInverse(N);
pp = p.multiply(p);
qq = q.multiply(q);
qqInv = qq.modInverse(pp);
dpp = phiN.mod(pp.subtract(p));
dqq = phiN.mod(qq.subtract(q));
}
public Paillier(BigInteger N)
{
this.N = N;
init();
}
public BigInteger getPublic() {
return N;
}
private void init(BigInteger N, BigInteger p, BigInteger q)
{
this.N = N;
this.p = p;
this.q = q;
init();
}
public Paillier(BigInteger N, BigInteger p, BigInteger q)
{
this(N);
this.p = p;
this.q = q;
phiN = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE)); //phi(N) = (p-1)(q-1)
invPhiN = phiN.modInverse(N);
pp = p.multiply(p);
qq = q.multiply(q);
qqInv = qq.modInverse(pp);
dpp = phiN.mod(pp.subtract(p));
dqq = phiN.mod(qq.subtract(q));
}
public BigInteger encrypt(BigInteger x)
{
return encrypt(x, CryptoRandom.generateBigInteger(N));
}
public BigInteger encrypt(BigInteger x, BigInteger r)
{
return x.multiply(N).mod(NN).add(BigInteger.ONE).multiply(r.modPow(N, NN)).mod(NN);
}
public BigInteger decrypt(BigInteger x)
{
BigInteger c1 = crtModPow(x, NN, pp, qq, dpp, dqq, qqInv);
return c1.subtract(BigInteger.ONE).divide(N).multiply(invPhiN).mod(N);
}
private static BigInteger crtModPow(BigInteger x, BigInteger N, BigInteger p, BigInteger q, BigInteger dp, BigInteger dq, BigInteger qinv)
{
BigInteger m1 = x.modPow(dp, p);
BigInteger m2 = x.modPow(dq, q);
return m2.add(qinv.multiply(p.add(m1).subtract(m2)).mod(p).multiply(q));
}
@Override
public void convert(Converter converter)
{
int struct = converter.beginStructVersion0();
boolean hasPrivate = converter.convert(p!=null);
N = converter.convert(N);
if (hasPrivate)
{
p = converter.convert(p);
q = converter.convert(q);
}
converter.endStruct(struct);
if (!converter.isWrite())
{
if (!hasPrivate) p = q = null;
init();
}
}
}