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

package org.bouncycastle.crypto.engines;

import org.bouncycastle.util.BigIntegers;
import org.bouncycastle.crypto.CryptoServicesRegistrar;
import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.crypto.CipherParameters;
import java.security.SecureRandom;
import org.bouncycastle.crypto.params.RSAKeyParameters;
import java.math.BigInteger;
import org.bouncycastle.crypto.AsymmetricBlockCipher;

public class RSABlindedEngine implements AsymmetricBlockCipher
{
    private static final BigInteger ONE;
    private RSACoreEngine core;
    private RSAKeyParameters key;
    private SecureRandom random;
    
    public RSABlindedEngine() {
        this.core = new RSACoreEngine();
    }
    
    @Override
    public void init(final boolean b, CipherParameters parameters) {
        SecureRandom random = null;
        if (parameters instanceof ParametersWithRandom) {
            final ParametersWithRandom parametersWithRandom = (ParametersWithRandom)parameters;
            random = parametersWithRandom.getRandom();
            parameters = parametersWithRandom.getParameters();
        }
        this.core.init(b, parameters);
        this.key = (RSAKeyParameters)parameters;
        this.random = this.initSecureRandom(this.key instanceof RSAPrivateCrtKeyParameters, random);
    }
    
    @Override
    public int getInputBlockSize() {
        return this.core.getInputBlockSize();
    }
    
    @Override
    public int getOutputBlockSize() {
        return this.core.getOutputBlockSize();
    }
    
    @Override
    public byte[] processBlock(final byte[] array, final int n, final int n2) {
        if (this.key == null) {
            throw new IllegalStateException("RSA engine not initialised");
        }
        return this.core.convertOutput(this.processInput(this.core.convertInput(array, n, n2)));
    }
    
    protected SecureRandom initSecureRandom(final boolean b, final SecureRandom secureRandom) {
        return b ? CryptoServicesRegistrar.getSecureRandom(secureRandom) : null;
    }
    
    private BigInteger processInput(final BigInteger val) {
        if (this.key instanceof RSAPrivateCrtKeyParameters) {
            final RSAPrivateCrtKeyParameters rsaPrivateCrtKeyParameters = (RSAPrivateCrtKeyParameters)this.key;
            final BigInteger publicExponent = rsaPrivateCrtKeyParameters.getPublicExponent();
            if (publicExponent != null) {
                final BigInteger modulus = rsaPrivateCrtKeyParameters.getModulus();
                final BigInteger randomInRange = BigIntegers.createRandomInRange(RSABlindedEngine.ONE, modulus.subtract(RSABlindedEngine.ONE), this.random);
                return BigIntegers.modOddInverse(modulus, randomInRange).multiply(this.core.processBlock(randomInRange.modPow(publicExponent, modulus).multiply(val).mod(modulus))).mod(modulus);
            }
        }
        return this.core.processBlock(val);
    }
    
    static {
        ONE = BigInteger.valueOf(1L);
    }
}
