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

package org.bouncycastle.jcajce.provider.asymmetric.mldsa;

import org.bouncycastle.jcajce.util.SpecUtil;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import org.bouncycastle.pqc.crypto.mldsa.MLDSAPrivateKeyParameters;
import org.bouncycastle.pqc.crypto.mldsa.MLDSAPublicKeyParameters;
import java.security.KeyPair;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import org.bouncycastle.jcajce.util.BCJcaJceHelper;
import java.security.spec.AlgorithmParameterSpec;
import org.bouncycastle.crypto.KeyGenerationParameters;
import org.bouncycastle.util.Strings;
import org.bouncycastle.jcajce.spec.MLDSAParameterSpec;
import org.bouncycastle.crypto.CryptoServicesRegistrar;
import java.security.SecureRandom;
import org.bouncycastle.pqc.crypto.mldsa.MLDSAKeyPairGenerator;
import org.bouncycastle.pqc.crypto.mldsa.MLDSAKeyGenerationParameters;
import org.bouncycastle.pqc.crypto.mldsa.MLDSAParameters;
import java.security.KeyPairGenerator;

public class MLDSAKeyPairGeneratorSpi extends KeyPairGenerator
{
    private final MLDSAParameters mldsaParameters;
    MLDSAKeyGenerationParameters param;
    MLDSAKeyPairGenerator engine;
    SecureRandom random;
    boolean initialised;
    
    public MLDSAKeyPairGeneratorSpi(final String algorithm) {
        super(algorithm);
        this.engine = new MLDSAKeyPairGenerator();
        this.random = CryptoServicesRegistrar.getSecureRandom();
        this.initialised = false;
        this.mldsaParameters = null;
    }
    
    protected MLDSAKeyPairGeneratorSpi(final MLDSAParameterSpec mldsaParameterSpec) {
        super(Strings.toUpperCase(mldsaParameterSpec.getName()));
        this.engine = new MLDSAKeyPairGenerator();
        this.random = CryptoServicesRegistrar.getSecureRandom();
        this.initialised = false;
        this.mldsaParameters = Utils.getParameters(mldsaParameterSpec.getName());
        if (this.param == null) {
            this.param = new MLDSAKeyGenerationParameters(this.random, this.mldsaParameters);
        }
        this.engine.init(this.param);
        this.initialised = true;
    }
    
    @Override
    public void initialize(final int n, final SecureRandom secureRandom) {
        throw new IllegalArgumentException("use AlgorithmParameterSpec");
    }
    
    @Override
    public void initialize(final AlgorithmParameterSpec algorithmParameterSpec) throws InvalidAlgorithmParameterException {
        try {
            this.initialize(algorithmParameterSpec, new BCJcaJceHelper().createSecureRandom("DEFAULT"));
        }
        catch (final NoSuchAlgorithmException ex) {
            throw new IllegalStateException("unable to find DEFAULT DRBG");
        }
    }
    
    @Override
    public void initialize(final AlgorithmParameterSpec obj, final SecureRandom secureRandom) throws InvalidAlgorithmParameterException {
        final String nameFromParams = getNameFromParams(obj);
        if (nameFromParams == null) {
            throw new InvalidAlgorithmParameterException("invalid ParameterSpec: " + obj);
        }
        final MLDSAParameters parameters = Utils.getParameters(nameFromParams);
        if (parameters == null) {
            throw new InvalidAlgorithmParameterException("unknown parameter set name: " + nameFromParams);
        }
        this.param = new MLDSAKeyGenerationParameters(secureRandom, parameters);
        if (this.mldsaParameters != null && !parameters.getName().equals(this.mldsaParameters.getName())) {
            throw new InvalidAlgorithmParameterException("key pair generator locked to " + MLDSAParameterSpec.fromName(this.mldsaParameters.getName()).getName());
        }
        this.engine.init(this.param);
        this.initialised = true;
    }
    
    @Override
    public KeyPair generateKeyPair() {
        if (!this.initialised) {
            if (this.getAlgorithm().startsWith("HASH")) {
                this.param = new MLDSAKeyGenerationParameters(this.random, MLDSAParameters.ml_dsa_87_with_sha512);
            }
            else {
                this.param = new MLDSAKeyGenerationParameters(this.random, MLDSAParameters.ml_dsa_87);
            }
            this.engine.init(this.param);
            this.initialised = true;
        }
        final AsymmetricCipherKeyPair generateKeyPair = this.engine.generateKeyPair();
        return new KeyPair(new BCMLDSAPublicKey((MLDSAPublicKeyParameters)generateKeyPair.getPublic()), new BCMLDSAPrivateKey((MLDSAPrivateKeyParameters)generateKeyPair.getPrivate()));
    }
    
    private static String getNameFromParams(final AlgorithmParameterSpec algorithmParameterSpec) {
        if (algorithmParameterSpec instanceof MLDSAParameterSpec) {
            return ((MLDSAParameterSpec)algorithmParameterSpec).getName();
        }
        return Strings.toUpperCase(SpecUtil.getNameFrom(algorithmParameterSpec));
    }
    
    public static class Hash extends MLDSAKeyPairGeneratorSpi
    {
        public Hash() throws NoSuchAlgorithmException {
            super("HASH-ML-DSA");
        }
    }
    
    public static class MLDSA44 extends MLDSAKeyPairGeneratorSpi
    {
        public MLDSA44() throws NoSuchAlgorithmException {
            super(MLDSAParameterSpec.ml_dsa_44);
        }
    }
    
    public static class MLDSA44withSHA512 extends MLDSAKeyPairGeneratorSpi
    {
        public MLDSA44withSHA512() throws NoSuchAlgorithmException {
            super(MLDSAParameterSpec.ml_dsa_44_with_sha512);
        }
    }
    
    public static class MLDSA65 extends MLDSAKeyPairGeneratorSpi
    {
        public MLDSA65() throws NoSuchAlgorithmException {
            super(MLDSAParameterSpec.ml_dsa_65);
        }
    }
    
    public static class MLDSA65withSHA512 extends MLDSAKeyPairGeneratorSpi
    {
        public MLDSA65withSHA512() throws NoSuchAlgorithmException {
            super(MLDSAParameterSpec.ml_dsa_65_with_sha512);
        }
    }
    
    public static class MLDSA87 extends MLDSAKeyPairGeneratorSpi
    {
        public MLDSA87() throws NoSuchAlgorithmException {
            super(MLDSAParameterSpec.ml_dsa_87);
        }
    }
    
    public static class MLDSA87withSHA512 extends MLDSAKeyPairGeneratorSpi
    {
        public MLDSA87withSHA512() throws NoSuchAlgorithmException {
            super(MLDSAParameterSpec.ml_dsa_87_with_sha512);
        }
    }
    
    public static class Pure extends MLDSAKeyPairGeneratorSpi
    {
        public Pure() throws NoSuchAlgorithmException {
            super("ML-DSA");
        }
    }
}
