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

package org.bouncycastle.crypto.generators;

import org.bouncycastle.math.ec.FixedPointCombMultiplier;
import org.bouncycastle.math.ec.ECMultiplier;
import java.math.BigInteger;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.math.ec.WNafUtil;
import org.bouncycastle.util.BigIntegers;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
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.ECKeyGenerationParameters;
import org.bouncycastle.crypto.KeyGenerationParameters;
import java.security.SecureRandom;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.math.ec.ECConstants;
import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;

public class ECKeyPairGenerator implements AsymmetricCipherKeyPairGenerator, ECConstants
{
    private final String name;
    ECDomainParameters params;
    SecureRandom random;
    
    public ECKeyPairGenerator() {
        this("ECKeyGen");
    }
    
    protected ECKeyPairGenerator(final String name) {
        this.name = name;
    }
    
    @Override
    public void init(final KeyGenerationParameters keyGenerationParameters) {
        final ECKeyGenerationParameters ecKeyGenerationParameters = (ECKeyGenerationParameters)keyGenerationParameters;
        this.random = ecKeyGenerationParameters.getRandom();
        this.params = ecKeyGenerationParameters.getDomainParameters();
        CryptoServicesRegistrar.checkConstraints(new DefaultServiceProperties(this.name, ConstraintUtils.bitsOfSecurityFor(this.params.getCurve()), ecKeyGenerationParameters.getDomainParameters(), CryptoServicePurpose.KEYGEN));
    }
    
    @Override
    public AsymmetricCipherKeyPair generateKeyPair() {
        final BigInteger n = this.params.getN();
        final int bitLength = n.bitLength();
        final int n2 = bitLength >>> 2;
        BigInteger randomBigInteger;
        while (true) {
            randomBigInteger = BigIntegers.createRandomBigInteger(bitLength, this.random);
            if (this.isOutOfRangeD(randomBigInteger, n)) {
                continue;
            }
            if (WNafUtil.getNafWeight(randomBigInteger) < n2) {
                continue;
            }
            break;
        }
        return new AsymmetricCipherKeyPair(new ECPublicKeyParameters(this.createBasePointMultiplier().multiply(this.params.getG(), randomBigInteger), this.params), new ECPrivateKeyParameters(randomBigInteger, this.params));
    }
    
    protected boolean isOutOfRangeD(final BigInteger bigInteger, final BigInteger val) {
        return bigInteger.compareTo(ECKeyPairGenerator.ONE) < 0 || bigInteger.compareTo(val) >= 0;
    }
    
    protected ECMultiplier createBasePointMultiplier() {
        return new FixedPointCombMultiplier();
    }
}
