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

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

import java.security.AlgorithmParameters;
import java.security.InvalidParameterException;
import org.bouncycastle.crypto.CryptoException;
import java.security.SignatureException;
import org.bouncycastle.crypto.signers.Ed25519Signer;
import org.bouncycastle.crypto.signers.Ed448Signer;
import org.bouncycastle.crypto.params.Ed448PrivateKeyParameters;
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
import java.security.PrivateKey;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.CipherParameters;
import java.security.InvalidKeyException;
import org.bouncycastle.crypto.params.Ed448PublicKeyParameters;
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
import java.security.PublicKey;
import org.bouncycastle.crypto.Signer;

public class SignatureSpi extends java.security.SignatureSpi
{
    private static final byte[] EMPTY_CONTEXT;
    private final String algorithm;
    private Signer signer;
    
    SignatureSpi(final String algorithm) {
        this.algorithm = algorithm;
    }
    
    @Override
    protected void engineInitVerify(final PublicKey publicKey) throws InvalidKeyException {
        final AsymmetricKeyParameter lwEdDSAKeyPublic = getLwEdDSAKeyPublic(publicKey);
        if (lwEdDSAKeyPublic instanceof Ed25519PublicKeyParameters) {
            this.signer = this.getSigner("Ed25519");
        }
        else {
            if (!(lwEdDSAKeyPublic instanceof Ed448PublicKeyParameters)) {
                throw new InvalidKeyException("unsupported public key type");
            }
            this.signer = this.getSigner("Ed448");
        }
        this.signer.init(false, lwEdDSAKeyPublic);
    }
    
    @Override
    protected void engineInitSign(final PrivateKey privateKey) throws InvalidKeyException {
        final AsymmetricKeyParameter lwEdDSAKeyPrivate = getLwEdDSAKeyPrivate(privateKey);
        if (lwEdDSAKeyPrivate instanceof Ed25519PrivateKeyParameters) {
            this.signer = this.getSigner("Ed25519");
        }
        else {
            if (!(lwEdDSAKeyPrivate instanceof Ed448PrivateKeyParameters)) {
                throw new InvalidKeyException("unsupported private key type");
            }
            this.signer = this.getSigner("Ed448");
        }
        this.signer.init(true, lwEdDSAKeyPrivate);
    }
    
    private static AsymmetricKeyParameter getLwEdDSAKeyPrivate(final PrivateKey privateKey) throws InvalidKeyException {
        return EdECUtil.generatePrivateKeyParameter(privateKey);
    }
    
    private static AsymmetricKeyParameter getLwEdDSAKeyPublic(final PublicKey publicKey) throws InvalidKeyException {
        return EdECUtil.generatePublicKeyParameter(publicKey);
    }
    
    private Signer getSigner(final String s) throws InvalidKeyException {
        if (this.algorithm != null && !s.equals(this.algorithm)) {
            throw new InvalidKeyException("inappropriate key for " + this.algorithm);
        }
        if (s.equals("Ed448")) {
            return new Ed448Signer(SignatureSpi.EMPTY_CONTEXT);
        }
        return new Ed25519Signer();
    }
    
    @Override
    protected void engineUpdate(final byte b) throws SignatureException {
        this.signer.update(b);
    }
    
    @Override
    protected void engineUpdate(final byte[] array, final int n, final int n2) throws SignatureException {
        this.signer.update(array, n, n2);
    }
    
    @Override
    protected byte[] engineSign() throws SignatureException {
        try {
            return this.signer.generateSignature();
        }
        catch (final CryptoException ex) {
            throw new SignatureException(ex.getMessage());
        }
    }
    
    @Override
    protected boolean engineVerify(final byte[] array) throws SignatureException {
        return this.signer.verifySignature(array);
    }
    
    @Override
    protected void engineSetParameter(final String s, final Object o) throws InvalidParameterException {
        throw new UnsupportedOperationException("engineSetParameter unsupported");
    }
    
    @Override
    protected Object engineGetParameter(final String s) throws InvalidParameterException {
        throw new UnsupportedOperationException("engineGetParameter unsupported");
    }
    
    @Override
    protected AlgorithmParameters engineGetParameters() {
        return null;
    }
    
    static {
        EMPTY_CONTEXT = new byte[0];
    }
    
    public static final class Ed25519 extends SignatureSpi
    {
        public Ed25519() {
            super("Ed25519");
        }
    }
    
    public static final class Ed448 extends SignatureSpi
    {
        public Ed448() {
            super("Ed448");
        }
    }
    
    public static final class EdDSA extends SignatureSpi
    {
        public EdDSA() {
            super(null);
        }
    }
}
