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

package org.bouncycastle.pqc.jcajce.provider.kyber;

import org.bouncycastle.crypto.SecretWithEncapsulation;
import org.bouncycastle.pqc.crypto.mlkem.MLKEMExtractor;
import javax.security.auth.DestroyFailedException;
import org.bouncycastle.jcajce.SecretKeyWithEncapsulation;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.pqc.crypto.mlkem.MLKEMGenerator;
import javax.crypto.SecretKey;
import java.security.InvalidAlgorithmParameterException;
import org.bouncycastle.util.Strings;
import java.security.spec.AlgorithmParameterSpec;
import org.bouncycastle.pqc.crypto.mlkem.MLKEMParameters;
import org.bouncycastle.jcajce.spec.KEMExtractSpec;
import java.security.SecureRandom;
import org.bouncycastle.jcajce.spec.KEMGenerateSpec;
import javax.crypto.KeyGeneratorSpi;

public class KyberKeyGeneratorSpi extends KeyGeneratorSpi
{
    private KEMGenerateSpec genSpec;
    private SecureRandom random;
    private KEMExtractSpec extSpec;
    private MLKEMParameters kyberParameters;
    
    public KyberKeyGeneratorSpi() {
        this(null);
    }
    
    protected KyberKeyGeneratorSpi(final MLKEMParameters kyberParameters) {
        this.kyberParameters = kyberParameters;
    }
    
    @Override
    protected void engineInit(final SecureRandom secureRandom) {
        throw new UnsupportedOperationException("Operation not supported");
    }
    
    @Override
    protected void engineInit(final AlgorithmParameterSpec algorithmParameterSpec, final SecureRandom random) throws InvalidAlgorithmParameterException {
        this.random = random;
        if (algorithmParameterSpec instanceof KEMGenerateSpec) {
            this.genSpec = (KEMGenerateSpec)algorithmParameterSpec;
            this.extSpec = null;
            if (this.kyberParameters != null) {
                final String upperCase = Strings.toUpperCase(this.kyberParameters.getName());
                if (!upperCase.equals(this.genSpec.getPublicKey().getAlgorithm())) {
                    throw new InvalidAlgorithmParameterException("key generator locked to " + upperCase);
                }
            }
        }
        else {
            if (!(algorithmParameterSpec instanceof KEMExtractSpec)) {
                throw new InvalidAlgorithmParameterException("unknown spec");
            }
            this.genSpec = null;
            this.extSpec = (KEMExtractSpec)algorithmParameterSpec;
            if (this.kyberParameters != null) {
                final String upperCase2 = Strings.toUpperCase(this.kyberParameters.getName());
                if (!upperCase2.equals(this.extSpec.getPrivateKey().getAlgorithm())) {
                    throw new InvalidAlgorithmParameterException("key generator locked to " + upperCase2);
                }
            }
        }
    }
    
    @Override
    protected void engineInit(final int n, final SecureRandom secureRandom) {
        throw new UnsupportedOperationException("Operation not supported");
    }
    
    @Override
    protected SecretKey engineGenerateKey() {
        if (this.genSpec != null) {
            final SecretWithEncapsulation generateEncapsulated = new MLKEMGenerator(this.random).generateEncapsulated(((BCKyberPublicKey)this.genSpec.getPublicKey()).getKeyParams());
            final byte[] secret = generateEncapsulated.getSecret();
            final byte[] copyOfRange = Arrays.copyOfRange(secret, 0, (this.genSpec.getKeySize() + 7) / 8);
            Arrays.clear(secret);
            final SecretKeyWithEncapsulation secretKeyWithEncapsulation = new SecretKeyWithEncapsulation(new SecretKeySpec(copyOfRange, this.genSpec.getKeyAlgorithmName()), generateEncapsulated.getEncapsulation());
            try {
                generateEncapsulated.destroy();
            }
            catch (final DestroyFailedException ex) {
                throw new IllegalStateException("key cleanup failed");
            }
            return secretKeyWithEncapsulation;
        }
        final MLKEMExtractor mlkemExtractor = new MLKEMExtractor(((BCKyberPrivateKey)this.extSpec.getPrivateKey()).getKeyParams());
        final byte[] encapsulation = this.extSpec.getEncapsulation();
        final byte[] secret2 = mlkemExtractor.extractSecret(encapsulation);
        final byte[] copyOfRange2 = Arrays.copyOfRange(secret2, 0, (this.extSpec.getKeySize() + 7) / 8);
        Arrays.clear(secret2);
        final SecretKeyWithEncapsulation secretKeyWithEncapsulation2 = new SecretKeyWithEncapsulation(new SecretKeySpec(copyOfRange2, this.extSpec.getKeyAlgorithmName()), encapsulation);
        Arrays.clear(copyOfRange2);
        return secretKeyWithEncapsulation2;
    }
    
    public static class Kyber1024 extends KyberKeyGeneratorSpi
    {
        public Kyber1024() {
            super(MLKEMParameters.ml_kem_1024);
        }
    }
    
    public static class Kyber512 extends KyberKeyGeneratorSpi
    {
        public Kyber512() {
            super(MLKEMParameters.ml_kem_512);
        }
    }
    
    public static class Kyber768 extends KyberKeyGeneratorSpi
    {
        public Kyber768() {
            super(MLKEMParameters.ml_kem_768);
        }
    }
}
