// 
// Decompiled by Procyon v0.6.0
// 

package org.bouncycastle.crypto.kems;

import org.bouncycastle.crypto.DerivationParameters;
import org.bouncycastle.crypto.params.KDFParameters;
import org.bouncycastle.util.BigIntegers;
import org.bouncycastle.crypto.CryptoServiceProperties;
import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.constraints.DefaultServiceProperties;
import org.bouncycastle.crypto.CryptoServicePurpose;
import org.bouncycastle.crypto.constraints.ConstraintUtils;
import org.bouncycastle.crypto.params.RSAKeyParameters;
import org.bouncycastle.crypto.SecretWithEncapsulation;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import java.security.SecureRandom;
import org.bouncycastle.crypto.DerivationFunction;
import java.math.BigInteger;
import org.bouncycastle.crypto.EncapsulatedSecretGenerator;

public class RSAKEMGenerator implements EncapsulatedSecretGenerator
{
    private static final BigInteger ZERO;
    private static final BigInteger ONE;
    private final int keyLen;
    private DerivationFunction kdf;
    private SecureRandom rnd;
    
    public RSAKEMGenerator(final int keyLen, final DerivationFunction kdf, final SecureRandom rnd) {
        this.keyLen = keyLen;
        this.kdf = kdf;
        this.rnd = rnd;
    }
    
    @Override
    public SecretWithEncapsulation generateEncapsulated(final AsymmetricKeyParameter asymmetricKeyParameter) {
        final RSAKeyParameters rsaKeyParameters = (RSAKeyParameters)asymmetricKeyParameter;
        if (rsaKeyParameters.isPrivate()) {
            throw new IllegalArgumentException("public key required for encryption");
        }
        CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties("RSAKem", ConstraintUtils.bitsOfSecurityFor(rsaKeyParameters.getModulus()), rsaKeyParameters, CryptoServicePurpose.ENCRYPTION));
        final BigInteger modulus = rsaKeyParameters.getModulus();
        final BigInteger exponent = rsaKeyParameters.getExponent();
        final BigInteger randomInRange = BigIntegers.createRandomInRange(RSAKEMGenerator.ZERO, modulus.subtract(RSAKEMGenerator.ONE), this.rnd);
        return new SecretWithEncapsulationImpl(generateKey(this.kdf, modulus, randomInRange, this.keyLen), BigIntegers.asUnsignedByteArray((modulus.bitLength() + 7) / 8, randomInRange.modPow(exponent, modulus)));
    }
    
    static byte[] generateKey(final DerivationFunction derivationFunction, final BigInteger bigInteger, final BigInteger bigInteger2, final int n) {
        derivationFunction.init(new KDFParameters(BigIntegers.asUnsignedByteArray((bigInteger.bitLength() + 7) / 8, bigInteger2), null));
        final byte[] array = new byte[n];
        derivationFunction.generateBytes(array, 0, array.length);
        return array;
    }
    
    static {
        ZERO = BigInteger.valueOf(0L);
        ONE = BigInteger.valueOf(1L);
    }
}
