// 
// 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.X25519PublicKeyParameters;
import org.bouncycastle.crypto.params.X448PublicKeyParameters;
import org.bouncycastle.util.Arrays;
import java.security.PrivateKey;
import org.bouncycastle.jcajce.interfaces.XDHPublicKey;
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.X25519PrivateKeyParameters;
import org.bouncycastle.crypto.params.X448PrivateKeyParameters;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.jcajce.interfaces.XDHPrivateKey;

public class BCXDHPrivateKey implements XDHPrivateKey
{
    static final long serialVersionUID = 1L;
    transient AsymmetricKeyParameter xdhPrivateKey;
    transient AsymmetricKeyParameter xdhPublicKey;
    transient int hashCode;
    private final boolean hasPublicKey;
    private final byte[] attributes;
    
    BCXDHPrivateKey(final AsymmetricKeyParameter xdhPrivateKey) {
        this.hasPublicKey = true;
        this.attributes = null;
        this.xdhPrivateKey = xdhPrivateKey;
        if (this.xdhPrivateKey instanceof X448PrivateKeyParameters) {
            this.xdhPublicKey = ((X448PrivateKeyParameters)this.xdhPrivateKey).generatePublicKey();
        }
        else {
            this.xdhPublicKey = ((X25519PrivateKeyParameters)this.xdhPrivateKey).generatePublicKey();
        }
        this.hashCode = this.calculateHashCode();
    }
    
    BCXDHPrivateKey(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 int privateKeyLength = privateKeyInfo.getPrivateKeyLength();
        byte[] array;
        if (privateKeyLength == 32 || privateKeyLength == 56) {
            array = privateKeyInfo.getPrivateKey().getOctets();
        }
        else {
            array = ASN1OctetString.getInstance(privateKeyInfo.parsePrivateKey()).getOctets();
        }
        if (EdECObjectIdentifiers.id_X448.equals(privateKeyInfo.getPrivateKeyAlgorithm().getAlgorithm())) {
            this.xdhPrivateKey = new X448PrivateKeyParameters(array);
            this.xdhPublicKey = ((X448PrivateKeyParameters)this.xdhPrivateKey).generatePublicKey();
        }
        else {
            this.xdhPrivateKey = new X25519PrivateKeyParameters(array);
            this.xdhPublicKey = ((X25519PrivateKeyParameters)this.xdhPrivateKey).generatePublicKey();
        }
        this.hashCode = this.calculateHashCode();
    }
    
    @Override
    public String getAlgorithm() {
        if (Properties.isOverrideSet("org.bouncycastle.emulate.oracle")) {
            return "XDH";
        }
        return (this.xdhPrivateKey instanceof X448PrivateKeyParameters) ? "X448" : "X25519";
    }
    
    @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.xdhPrivateKey, 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 XDHPublicKey getPublicKey() {
        return new BCXDHPublicKey(this.xdhPublicKey);
    }
    
    AsymmetricKeyParameter engineGetKeyParameters() {
        return this.xdhPrivateKey;
    }
    
    @Override
    public String toString() {
        return Utils.keyToString("Private Key", this.getAlgorithm(), this.xdhPublicKey);
    }
    
    @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 BCXDHPrivateKey) ? ((BCXDHPrivateKey)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.xdhPublicKey instanceof X448PublicKeyParameters) {
            array = ((X448PublicKeyParameters)this.xdhPublicKey).getEncoded();
        }
        else {
            array = ((X25519PublicKeyParameters)this.xdhPublicKey).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());
    }
}
