com.akeyless.crypto.rsa.RsaMpcUtils Maven / Gradle / Ivy
package com.akeyless.crypto.rsa;
import com.akeyless.crypto.rsa.internal.JCAUtil;
import java.math.BigInteger;
import java.security.*;
import java.security.interfaces.RSAPrivateCrtKey;
import java.util.ArrayList;
import java.util.List;
public class RsaMpcUtils {
public static List splitPrivateKey(RSAPrivateCrtKey prvKey , int numOfFragments) {
return splitPrivateKey(prvKey, numOfFragments, null);
}
public static List splitPrivateKey(RSAPrivateCrtKey prvKey , int numOfFragments, SecureRandom random) {
if (random == null) {
random = JCAUtil.getSecureRandom();
}
ArrayList fragments = new ArrayList<>();
List primes = new ArrayList<>();
primes.add(prvKey.getPrimeP());
primes.add(prvKey.getPrimeQ());
BigInteger phi = calcPhi(primes);
BigInteger phiSubOne = phi.subtract(BigInteger.ONE);
BigInteger maxRand = phiSubOne.divide(BigInteger.valueOf(numOfFragments+1));
BigInteger sumRands = BigInteger.ZERO;
for(int i = 0; i < numOfFragments-1; i++) {
BigInteger r = nextRandomBigInteger(maxRand,random);
sumRands = sumRands.add(r);
fragments.add(new RsaMpcFragment(prvKey.getModulus(),r));
}
BigInteger lastFrgD = prvKey.getPrivateExponent().subtract(sumRands);
fragments.add(new RsaMpcFragment(prvKey.getModulus(),lastFrgD.mod(phi)));
return fragments;
}
static BigInteger combineFragmentsDecryptRes(List decryptResults, BigInteger n){
if(decryptResults == null || decryptResults.isEmpty()) {
return null;
}
BigInteger res = decryptResults.get(0);
for( int i = 1; i < decryptResults.size(); i++) {
res = res.multiply(decryptResults.get(i));
}
return res.mod(n);
}
static byte[] finalRsaResultToByteArray(BigInteger var0, int var1){
byte[] var2 = var0.toByteArray();
int var3 = var2.length;
if (var3 == var1) {
return var2;
} else {
byte[] var4;
if (var3 == var1 + 1 && var2[0] == 0) {
var4 = new byte[var1];
System.arraycopy(var2, 1, var4, 0, var1);
return var4;
} else {
assert var3 < var1;
var4 = new byte[var1];
System.arraycopy(var2, 0, var4, var1 - var3, var3);
return var4;
}
}
}
private static BigInteger calcPhi(List primes) {
BigInteger totient = BigInteger.ONE;
for(BigInteger p : primes) {
BigInteger pminus1 = p.subtract(BigInteger.ONE);
totient = totient.multiply(pminus1);
}
return totient;
}
private static BigInteger nextRandomBigInteger(BigInteger n, SecureRandom random) {
if (random == null) {
random = JCAUtil.getSecureRandom();
}
BigInteger result = new BigInteger(n.bitLength(), random);
while( result.compareTo(n) >= 0 ) {
result = new BigInteger(n.bitLength(), random);
}
return result;
}
}