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

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

import org.bouncycastle.crypto.SecretWithEncapsulation;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.pqc.crypto.hqc.HQCKEMExtractor;
import javax.security.auth.DestroyFailedException;
import org.bouncycastle.jcajce.SecretKeyWithEncapsulation;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.pqc.crypto.hqc.HQCKEMGenerator;
import javax.crypto.SecretKey;
import java.security.InvalidAlgorithmParameterException;
import org.bouncycastle.pqc.jcajce.spec.HQCParameterSpec;
import java.security.spec.AlgorithmParameterSpec;
import org.bouncycastle.pqc.crypto.hqc.HQCParameters;
import org.bouncycastle.jcajce.spec.KEMExtractSpec;
import java.security.SecureRandom;
import org.bouncycastle.jcajce.spec.KEMGenerateSpec;
import javax.crypto.KeyGeneratorSpi;

public class HQCKeyGeneratorSpi extends KeyGeneratorSpi
{
    private KEMGenerateSpec genSpec;
    private SecureRandom random;
    private KEMExtractSpec extSpec;
    private HQCParameters hqcParameters;
    
    public HQCKeyGeneratorSpi() {
        this(null);
    }
    
    public HQCKeyGeneratorSpi(final HQCParameters hqcParameters) {
        this.hqcParameters = hqcParameters;
    }
    
    @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.hqcParameters != null) {
                final String name = HQCParameterSpec.fromName(this.hqcParameters.getName()).getName();
                if (!name.equals(this.genSpec.getPublicKey().getAlgorithm())) {
                    throw new InvalidAlgorithmParameterException("key generator locked to " + name);
                }
            }
        }
        else {
            if (!(algorithmParameterSpec instanceof KEMExtractSpec)) {
                throw new InvalidAlgorithmParameterException("unknown spec");
            }
            this.genSpec = null;
            this.extSpec = (KEMExtractSpec)algorithmParameterSpec;
            if (this.hqcParameters != null) {
                final String name2 = HQCParameterSpec.fromName(this.hqcParameters.getName()).getName();
                if (!name2.equals(this.extSpec.getPrivateKey().getAlgorithm())) {
                    throw new InvalidAlgorithmParameterException("key generator locked to " + name2);
                }
            }
        }
    }
    
    @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 HQCKEMGenerator(this.random).generateEncapsulated(((BCHQCPublicKey)this.genSpec.getPublicKey()).getKeyParams());
            final SecretKeyWithEncapsulation secretKeyWithEncapsulation = new SecretKeyWithEncapsulation(new SecretKeySpec(generateEncapsulated.getSecret(), this.genSpec.getKeyAlgorithmName()), generateEncapsulated.getEncapsulation());
            try {
                generateEncapsulated.destroy();
            }
            catch (final DestroyFailedException ex) {
                throw new IllegalStateException("key cleanup failed");
            }
            return secretKeyWithEncapsulation;
        }
        final HQCKEMExtractor hqckemExtractor = new HQCKEMExtractor(((BCHQCPrivateKey)this.extSpec.getPrivateKey()).getKeyParams());
        final byte[] encapsulation = this.extSpec.getEncapsulation();
        final byte[] secret = hqckemExtractor.extractSecret(encapsulation);
        final SecretKeyWithEncapsulation secretKeyWithEncapsulation2 = new SecretKeyWithEncapsulation(new SecretKeySpec(secret, this.extSpec.getKeyAlgorithmName()), encapsulation);
        Arrays.clear(secret);
        return secretKeyWithEncapsulation2;
    }
    
    public static class HQC128 extends HQCKeyGeneratorSpi
    {
        public HQC128() {
            super(HQCParameters.hqc128);
        }
    }
    
    public static class HQC192 extends HQCKeyGeneratorSpi
    {
        public HQC192() {
            super(HQCParameters.hqc192);
        }
    }
    
    public static class HQC256 extends HQCKeyGeneratorSpi
    {
        public HQC256() {
            super(HQCParameters.hqc256);
        }
    }
}
