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

package org.bouncycastle.jcajce;

import java.security.Security;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.x9.ECNamedCurveTable;
import org.bouncycastle.asn1.sec.ECPrivateKey;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.crypto.util.PrivateKeyInfoFactory;
import org.bouncycastle.crypto.util.PrivateKeyFactory;
import org.bouncycastle.internal.asn1.iana.IANAObjectIdentifiers;
import java.io.IOException;
import org.bouncycastle.util.Exceptions;
import org.bouncycastle.jcajce.provider.asymmetric.compositesignatures.KeyFactorySpi;
import org.bouncycastle.jcajce.provider.asymmetric.compositesignatures.CompositeIndex;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.jcajce.interfaces.MLDSAPrivateKey;
import java.util.Collections;
import java.util.ArrayList;
import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import java.security.Provider;
import java.util.List;
import java.security.PrivateKey;

public class CompositePrivateKey implements PrivateKey
{
    private final List<PrivateKey> keys;
    private final List<Provider> providers;
    private AlgorithmIdentifier algorithmIdentifier;
    
    public static Builder builder(final ASN1ObjectIdentifier asn1ObjectIdentifier) {
        return new Builder(new AlgorithmIdentifier(asn1ObjectIdentifier));
    }
    
    public static Builder builder(final String s) {
        return builder(CompositeUtil.getOid(s));
    }
    
    public CompositePrivateKey(final PrivateKey... array) {
        this(MiscObjectIdentifiers.id_composite_key, array);
    }
    
    public CompositePrivateKey(final ASN1ObjectIdentifier asn1ObjectIdentifier, final PrivateKey... array) {
        this(new AlgorithmIdentifier(asn1ObjectIdentifier), array);
    }
    
    public CompositePrivateKey(final AlgorithmIdentifier algorithmIdentifier, final PrivateKey... array) {
        this.algorithmIdentifier = algorithmIdentifier;
        if (array == null || array.length == 0) {
            throw new IllegalArgumentException("at least one private key must be provided for the composite private key");
        }
        final ArrayList list = new ArrayList(array.length);
        for (int i = 0; i < array.length; ++i) {
            list.add(this.processKey(array[i]));
        }
        this.keys = (List<PrivateKey>)Collections.unmodifiableList((List<?>)list);
        this.providers = null;
    }
    
    private PrivateKey processKey(final PrivateKey privateKey) {
        if (privateKey instanceof MLDSAPrivateKey) {
            try {
                return ((MLDSAPrivateKey)privateKey).getPrivateKey(true);
            }
            catch (final Exception ex) {
                return privateKey;
            }
        }
        return privateKey;
    }
    
    private CompositePrivateKey(final AlgorithmIdentifier algorithmIdentifier, final PrivateKey[] array, final Provider[] array2) {
        this.algorithmIdentifier = algorithmIdentifier;
        if (array.length != 2) {
            throw new IllegalArgumentException("two keys required for composite private key");
        }
        final ArrayList list = new ArrayList(array.length);
        if (array2 == null) {
            for (int i = 0; i < array.length; ++i) {
                list.add(this.processKey(array[i]));
            }
            this.providers = null;
        }
        else {
            final ArrayList list2 = new ArrayList(array2.length);
            for (int j = 0; j < array.length; ++j) {
                list2.add(array2[j]);
                list.add(this.processKey(array[j]));
            }
            this.providers = (List<Provider>)Collections.unmodifiableList((List<?>)list2);
        }
        this.keys = (List<PrivateKey>)Collections.unmodifiableList((List<?>)list);
    }
    
    public CompositePrivateKey(final PrivateKeyInfo privateKeyInfo) {
        final ASN1ObjectIdentifier algorithm = privateKeyInfo.getPrivateKeyAlgorithm().getAlgorithm();
        CompositePrivateKey compositePrivateKey;
        try {
            if (!CompositeIndex.isAlgorithmSupported(algorithm)) {
                throw new IllegalStateException("Unable to create CompositePrivateKey from PrivateKeyInfo");
            }
            compositePrivateKey = (CompositePrivateKey)new KeyFactorySpi().generatePrivate(privateKeyInfo);
            if (compositePrivateKey == null) {
                throw new IllegalStateException("Unable to create CompositePrivateKey from PrivateKeyInfo");
            }
        }
        catch (final IOException ex) {
            throw Exceptions.illegalStateException(ex.getMessage(), ex);
        }
        this.keys = compositePrivateKey.getPrivateKeys();
        this.providers = null;
        this.algorithmIdentifier = compositePrivateKey.getAlgorithmIdentifier();
    }
    
    public List<PrivateKey> getPrivateKeys() {
        return this.keys;
    }
    
    public List<Provider> getProviders() {
        return this.providers;
    }
    
    @Override
    public String getAlgorithm() {
        return CompositeIndex.getAlgorithmName(this.algorithmIdentifier.getAlgorithm());
    }
    
    public AlgorithmIdentifier getAlgorithmIdentifier() {
        return this.algorithmIdentifier;
    }
    
    @Override
    public String getFormat() {
        return "PKCS#8";
    }
    
    @Override
    public byte[] getEncoded() {
        if (this.algorithmIdentifier.getAlgorithm().on(IANAObjectIdentifiers.id_alg)) {
            try {
                final byte[] seed = this.keys.get(0).getSeed();
                byte[] array = PrivateKeyInfoFactory.createPrivateKeyInfo(PrivateKeyFactory.createKey(this.keys.get(1).getEncoded())).getPrivateKey().getOctets();
                if (this.keys.get(1).getAlgorithm().contains("Ed")) {
                    array = ASN1OctetString.getInstance(array).getOctets();
                }
                else if (this.keys.get(1).getAlgorithm().contains("EC")) {
                    final ECPrivateKey instance = ECPrivateKey.getInstance(array);
                    array = new ECPrivateKey(ECNamedCurveTable.getByOID(ASN1ObjectIdentifier.getInstance(instance.getParametersObject())).getCurve().getFieldSize(), instance.getKey(), instance.getParametersObject()).getEncoded();
                }
                return new PrivateKeyInfo(this.algorithmIdentifier, Arrays.concatenate(seed, array)).getEncoded();
            }
            catch (final IOException ex) {
                throw new IllegalStateException("unable to encode composite public key: " + ex.getMessage());
            }
        }
        final ASN1EncodableVector asn1EncodableVector = new ASN1EncodableVector();
        if (this.algorithmIdentifier.getAlgorithm().equals(MiscObjectIdentifiers.id_composite_key)) {
            for (int i = 0; i < this.keys.size(); ++i) {
                asn1EncodableVector.add(PrivateKeyInfo.getInstance(this.keys.get(i).getEncoded()));
            }
            try {
                return new PrivateKeyInfo(this.algorithmIdentifier, new DERSequence(asn1EncodableVector)).getEncoded("DER");
            }
            catch (final IOException ex2) {
                throw new IllegalStateException("unable to encode composite private key: " + ex2.getMessage());
            }
        }
        byte[] concatenate = null;
        for (int j = 0; j < this.keys.size(); ++j) {
            concatenate = Arrays.concatenate(concatenate, PrivateKeyInfo.getInstance(this.keys.get(j).getEncoded()).getPrivateKey().getOctets());
        }
        try {
            return new PrivateKeyInfo(this.algorithmIdentifier, concatenate).getEncoded("DER");
        }
        catch (final IOException ex3) {
            throw new IllegalStateException("unable to encode composite private key: " + ex3.getMessage());
        }
    }
    
    @Override
    public int hashCode() {
        return this.keys.hashCode();
    }
    
    @Override
    public boolean equals(final Object o) {
        if (o == this) {
            return true;
        }
        if (o instanceof CompositePrivateKey) {
            boolean b = true;
            final CompositePrivateKey compositePrivateKey = (CompositePrivateKey)o;
            if (!compositePrivateKey.getAlgorithmIdentifier().equals(this.algorithmIdentifier) || !this.keys.equals(compositePrivateKey.keys)) {
                b = false;
            }
            return b;
        }
        return false;
    }
    
    public static class Builder
    {
        private final AlgorithmIdentifier algorithmIdentifier;
        private final PrivateKey[] keys;
        private final Provider[] providers;
        private int count;
        
        private Builder(final AlgorithmIdentifier algorithmIdentifier) {
            this.keys = new PrivateKey[2];
            this.providers = new Provider[2];
            this.count = 0;
            this.algorithmIdentifier = algorithmIdentifier;
        }
        
        public Builder addPrivateKey(final PrivateKey privateKey) {
            return this.addPrivateKey(privateKey, (Provider)null);
        }
        
        public Builder addPrivateKey(final PrivateKey privateKey, final String name) {
            return this.addPrivateKey(privateKey, Security.getProvider(name));
        }
        
        public Builder addPrivateKey(final PrivateKey privateKey, final Provider provider) {
            if (this.count == this.keys.length) {
                throw new IllegalStateException("only " + this.keys.length + " allowed in composite");
            }
            this.keys[this.count] = privateKey;
            this.providers[this.count++] = provider;
            return this;
        }
        
        public CompositePrivateKey build() {
            if (this.providers[0] == null && this.providers[1] == null) {
                return new CompositePrivateKey(this.algorithmIdentifier, this.keys, null, null);
            }
            return new CompositePrivateKey(this.algorithmIdentifier, this.keys, this.providers, null);
        }
    }
}
