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

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

import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
import org.bouncycastle.crypto.params.Ed448PublicKeyParameters;
import org.bouncycastle.util.Arrays;
import java.security.PrivateKey;
import org.bouncycastle.jcajce.interfaces.EdDSAPublicKey;
import org.bouncycastle.crypto.util.PrivateKeyInfoFactory;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.util.Properties;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers;
import org.bouncycastle.asn1.ASN1OctetString;
import java.io.IOException;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
import org.bouncycastle.crypto.params.Ed448PrivateKeyParameters;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.jcajce.interfaces.BCKey;
import org.bouncycastle.jcajce.interfaces.EdDSAPrivateKey;

public class BCEdDSAPrivateKey implements EdDSAPrivateKey, BCKey
{
    static final long serialVersionUID = 1L;
    transient AsymmetricKeyParameter eddsaPrivateKey;
    transient AsymmetricKeyParameter eddsaPublicKey;
    transient int hashCode;
    private final boolean hasPublicKey;
    private final byte[] attributes;
    
    BCEdDSAPrivateKey(final AsymmetricKeyParameter eddsaPrivateKey) {
        this.hasPublicKey = true;
        this.attributes = null;
        this.eddsaPrivateKey = eddsaPrivateKey;
        if (this.eddsaPrivateKey instanceof Ed448PrivateKeyParameters) {
            this.eddsaPublicKey = ((Ed448PrivateKeyParameters)this.eddsaPrivateKey).generatePublicKey();
        }
        else {
            this.eddsaPublicKey = ((Ed25519PrivateKeyParameters)this.eddsaPrivateKey).generatePublicKey();
        }
        this.hashCode = this.calculateHashCode();
    }
    
    BCEdDSAPrivateKey(final PrivateKeyInfo privateKeyInfo) throws IOException {
        this.hasPublicKey = privateKeyInfo.hasPublicKey();
        this.attributes = (byte[])((privateKeyInfo.getAttributes() != null) ? privateKeyInfo.getAttributes().getEncoded() : null);
        this.populateFromPrivateKeyInfo(privateKeyInfo);
    }
    
    private void populateFromPrivateKeyInfo(final PrivateKeyInfo privateKeyInfo) throws IOException {
        final byte[] octets = ASN1OctetString.getInstance(privateKeyInfo.parsePrivateKey()).getOctets();
        if (EdECObjectIdentifiers.id_Ed448.equals(privateKeyInfo.getPrivateKeyAlgorithm().getAlgorithm())) {
            this.eddsaPrivateKey = new Ed448PrivateKeyParameters(octets);
            this.eddsaPublicKey = ((Ed448PrivateKeyParameters)this.eddsaPrivateKey).generatePublicKey();
        }
        else {
            this.eddsaPrivateKey = new Ed25519PrivateKeyParameters(octets);
            this.eddsaPublicKey = ((Ed25519PrivateKeyParameters)this.eddsaPrivateKey).generatePublicKey();
        }
        this.hashCode = this.calculateHashCode();
    }
    
    @Override
    public String getAlgorithm() {
        if (Properties.isOverrideSet("org.bouncycastle.emulate.oracle")) {
            return "EdDSA";
        }
        return (this.eddsaPrivateKey instanceof Ed448PrivateKeyParameters) ? "Ed448" : "Ed25519";
    }
    
    @Override
    public String getFormat() {
        return "PKCS#8";
    }
    
    @Override
    public byte[] getEncoded() {
        try {
            final PrivateKeyInfo privateKeyInfo = this.getPrivateKeyInfo();
            if (privateKeyInfo == null) {
                return null;
            }
            return privateKeyInfo.getEncoded();
        }
        catch (final IOException ex) {
            return null;
        }
    }
    
    private PrivateKeyInfo getPrivateKeyInfo() {
        try {
            final ASN1Set instance = ASN1Set.getInstance(this.attributes);
            final PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.createPrivateKeyInfo(this.eddsaPrivateKey, instance);
            if (this.hasPublicKey && !Properties.isOverrideSet("org.bouncycastle.pkcs8.v1_info_only")) {
                return privateKeyInfo;
            }
            return new PrivateKeyInfo(privateKeyInfo.getPrivateKeyAlgorithm(), privateKeyInfo.parsePrivateKey(), instance);
        }
        catch (final IOException ex) {
            return null;
        }
    }
    
    @Override
    public EdDSAPublicKey getPublicKey() {
        return new BCEdDSAPublicKey(this.eddsaPublicKey);
    }
    
    AsymmetricKeyParameter engineGetKeyParameters() {
        return this.eddsaPrivateKey;
    }
    
    @Override
    public String toString() {
        return Utils.keyToString("Private Key", this.getAlgorithm(), this.eddsaPublicKey);
    }
    
    @Override
    public boolean equals(final Object o) {
        if (o == this) {
            return true;
        }
        if (!(o instanceof PrivateKey)) {
            return false;
        }
        final PrivateKey privateKey = (PrivateKey)o;
        final PrivateKeyInfo privateKeyInfo = this.getPrivateKeyInfo();
        final PrivateKeyInfo privateKeyInfo2 = (privateKey instanceof BCEdDSAPrivateKey) ? ((BCEdDSAPrivateKey)privateKey).getPrivateKeyInfo() : PrivateKeyInfo.getInstance(privateKey.getEncoded());
        if (privateKeyInfo == null || privateKeyInfo2 == null) {
            return false;
        }
        try {
            return Arrays.constantTimeAreEqual(privateKeyInfo.getPrivateKeyAlgorithm().getEncoded(), privateKeyInfo2.getPrivateKeyAlgorithm().getEncoded()) & Arrays.constantTimeAreEqual(privateKeyInfo.getPrivateKey().getEncoded(), privateKeyInfo2.getPrivateKey().getEncoded());
        }
        catch (final IOException ex) {
            return false;
        }
    }
    
    @Override
    public int hashCode() {
        return this.hashCode;
    }
    
    private int calculateHashCode() {
        byte[] array;
        if (this.eddsaPublicKey instanceof Ed448PublicKeyParameters) {
            array = ((Ed448PublicKeyParameters)this.eddsaPublicKey).getEncoded();
        }
        else {
            array = ((Ed25519PublicKeyParameters)this.eddsaPublicKey).getEncoded();
        }
        return 31 * this.getAlgorithm().hashCode() + Arrays.hashCode(array);
    }
    
    private void readObject(final ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException {
        objectInputStream.defaultReadObject();
        this.populateFromPrivateKeyInfo(PrivateKeyInfo.getInstance(objectInputStream.readObject()));
    }
    
    private void writeObject(final ObjectOutputStream objectOutputStream) throws IOException {
        objectOutputStream.defaultWriteObject();
        objectOutputStream.writeObject(this.getEncoded());
    }
}
