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

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

import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.pqc.crypto.util.PrivateKeyInfoFactory;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.pqc.crypto.util.PrivateKeyFactory;
import org.bouncycastle.pqc.asn1.SPHINCS256KeyParams;
import java.io.IOException;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.pqc.crypto.sphincs.SPHINCSPrivateKeyParameters;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.pqc.jcajce.interfaces.SPHINCSKey;
import java.security.PrivateKey;

public class BCSphincs256PrivateKey implements PrivateKey, SPHINCSKey
{
    private static final long serialVersionUID = 1L;
    private transient ASN1ObjectIdentifier treeDigest;
    private transient SPHINCSPrivateKeyParameters params;
    private transient ASN1Set attributes;
    
    public BCSphincs256PrivateKey(final ASN1ObjectIdentifier treeDigest, final SPHINCSPrivateKeyParameters params) {
        this.treeDigest = treeDigest;
        this.params = params;
    }
    
    public BCSphincs256PrivateKey(final PrivateKeyInfo privateKeyInfo) throws IOException {
        this.init(privateKeyInfo);
    }
    
    private void init(final PrivateKeyInfo privateKeyInfo) throws IOException {
        this.attributes = privateKeyInfo.getAttributes();
        this.treeDigest = SPHINCS256KeyParams.getInstance(privateKeyInfo.getPrivateKeyAlgorithm().getParameters()).getTreeDigest().getAlgorithm();
        this.params = (SPHINCSPrivateKeyParameters)PrivateKeyFactory.createKey(privateKeyInfo);
    }
    
    @Override
    public boolean equals(final Object o) {
        if (o == this) {
            return true;
        }
        if (o instanceof BCSphincs256PrivateKey) {
            final BCSphincs256PrivateKey bcSphincs256PrivateKey = (BCSphincs256PrivateKey)o;
            return this.treeDigest.equals(bcSphincs256PrivateKey.treeDigest) && Arrays.areEqual(this.params.getKeyData(), bcSphincs256PrivateKey.params.getKeyData());
        }
        return false;
    }
    
    @Override
    public int hashCode() {
        return this.treeDigest.hashCode() + 37 * Arrays.hashCode(this.params.getKeyData());
    }
    
    @Override
    public final String getAlgorithm() {
        return "SPHINCS-256";
    }
    
    @Override
    public byte[] getEncoded() {
        try {
            PrivateKeyInfo privateKeyInfo;
            if (this.params.getTreeDigest() != null) {
                privateKeyInfo = PrivateKeyInfoFactory.createPrivateKeyInfo(this.params, this.attributes);
            }
            else {
                privateKeyInfo = new PrivateKeyInfo(new AlgorithmIdentifier(PQCObjectIdentifiers.sphincs256, new SPHINCS256KeyParams(new AlgorithmIdentifier(this.treeDigest))), new DEROctetString(this.params.getKeyData()), this.attributes);
            }
            return privateKeyInfo.getEncoded();
        }
        catch (final IOException ex) {
            return null;
        }
    }
    
    @Override
    public String getFormat() {
        return "PKCS#8";
    }
    
    ASN1ObjectIdentifier getTreeDigest() {
        return this.treeDigest;
    }
    
    @Override
    public byte[] getKeyData() {
        return this.params.getKeyData();
    }
    
    CipherParameters getKeyParams() {
        return this.params;
    }
    
    private void readObject(final ObjectInputStream objectInputStream) throws IOException, ClassNotFoundException {
        objectInputStream.defaultReadObject();
        this.init(PrivateKeyInfo.getInstance(objectInputStream.readObject()));
    }
    
    private void writeObject(final ObjectOutputStream objectOutputStream) throws IOException {
        objectOutputStream.defaultWriteObject();
        objectOutputStream.writeObject(this.getEncoded());
    }
}
