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

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

import java.security.AlgorithmParameters;
import java.security.spec.AlgorithmParameterSpec;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1OctetString;
import java.math.BigInteger;
import org.bouncycastle.asn1.DEROctetString;
import java.security.SignatureException;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.jce.interfaces.ECKey;
import java.security.PrivateKey;
import java.security.InvalidKeyException;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.asn1.ua.DSTU4145Params;
import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
import org.bouncycastle.crypto.digests.GOST3411Digest;
import java.security.PublicKey;
import org.bouncycastle.crypto.signers.DSTU4145Signer;
import org.bouncycastle.crypto.DSAExt;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;

public class SignatureSpi extends java.security.SignatureSpi implements PKCSObjectIdentifiers, X509ObjectIdentifiers
{
    private Digest digest;
    private DSAExt signer;
    
    public SignatureSpi() {
        this.signer = new DSTU4145Signer();
    }
    
    @Override
    protected void engineInitVerify(final PublicKey publicKey) throws InvalidKeyException {
        AsymmetricKeyParameter asymmetricKeyParameter;
        if (publicKey instanceof BCDSTU4145PublicKey) {
            asymmetricKeyParameter = ((BCDSTU4145PublicKey)publicKey).engineGetKeyParameters();
            this.digest = new GOST3411Digest(this.expandSbox(((BCDSTU4145PublicKey)publicKey).getSbox()));
        }
        else {
            asymmetricKeyParameter = ECUtil.generatePublicKeyParameter(publicKey);
            this.digest = new GOST3411Digest(this.expandSbox(DSTU4145Params.getDefaultDKE()));
        }
        this.signer.init(false, asymmetricKeyParameter);
    }
    
    byte[] expandSbox(final byte[] array) {
        final byte[] array2 = new byte[128];
        for (int i = 0; i < array.length; ++i) {
            array2[i * 2] = (byte)(array[i] >> 4 & 0xF);
            array2[i * 2 + 1] = (byte)(array[i] & 0xF);
        }
        return array2;
    }
    
    @Override
    protected void engineInitSign(final PrivateKey privateKey) throws InvalidKeyException {
        CipherParameters cipherParameters = null;
        if (privateKey instanceof BCDSTU4145PrivateKey) {
            cipherParameters = ECUtil.generatePrivateKeyParameter(privateKey);
            this.digest = new GOST3411Digest(this.expandSbox(DSTU4145Params.getDefaultDKE()));
        }
        else if (privateKey instanceof ECKey) {
            cipherParameters = ECUtil.generatePrivateKeyParameter(privateKey);
            this.digest = new GOST3411Digest(this.expandSbox(DSTU4145Params.getDefaultDKE()));
        }
        if (this.appRandom != null) {
            this.signer.init(true, new ParametersWithRandom(cipherParameters, this.appRandom));
        }
        else {
            this.signer.init(true, cipherParameters);
        }
    }
    
    @Override
    protected void engineUpdate(final byte b) throws SignatureException {
        this.digest.update(b);
    }
    
    @Override
    protected void engineUpdate(final byte[] array, final int n, final int n2) throws SignatureException {
        this.digest.update(array, n, n2);
    }
    
    @Override
    protected byte[] engineSign() throws SignatureException {
        final byte[] array = new byte[this.digest.getDigestSize()];
        this.digest.doFinal(array, 0);
        try {
            final BigInteger[] generateSignature = this.signer.generateSignature(array);
            final byte[] byteArray = generateSignature[0].toByteArray();
            final byte[] byteArray2 = generateSignature[1].toByteArray();
            final byte[] array2 = new byte[(byteArray.length > byteArray2.length) ? (byteArray.length * 2) : (byteArray2.length * 2)];
            System.arraycopy(byteArray2, 0, array2, array2.length / 2 - byteArray2.length, byteArray2.length);
            System.arraycopy(byteArray, 0, array2, array2.length - byteArray.length, byteArray.length);
            return new DEROctetString(array2).getEncoded();
        }
        catch (final Exception ex) {
            throw new SignatureException(ex.toString());
        }
    }
    
    @Override
    protected boolean engineVerify(final byte[] array) throws SignatureException {
        final byte[] array2 = new byte[this.digest.getDigestSize()];
        this.digest.doFinal(array2, 0);
        BigInteger[] array3;
        try {
            final byte[] octets = ((ASN1OctetString)ASN1Primitive.fromByteArray(array)).getOctets();
            final byte[] magnitude = new byte[octets.length / 2];
            final byte[] magnitude2 = new byte[octets.length / 2];
            System.arraycopy(octets, 0, magnitude2, 0, octets.length / 2);
            System.arraycopy(octets, octets.length / 2, magnitude, 0, octets.length / 2);
            array3 = new BigInteger[] { new BigInteger(1, magnitude), new BigInteger(1, magnitude2) };
        }
        catch (final Exception ex) {
            throw new SignatureException("error decoding signature bytes.");
        }
        return this.signer.verifySignature(array2, array3[0], array3[1]);
    }
    
    @Override
    protected void engineSetParameter(final AlgorithmParameterSpec algorithmParameterSpec) {
        throw new UnsupportedOperationException("engineSetParameter unsupported");
    }
    
    @Override
    protected AlgorithmParameters engineGetParameters() {
        return null;
    }
    
    @Override
    @Deprecated
    protected void engineSetParameter(final String s, final Object o) {
        throw new UnsupportedOperationException("engineSetParameter unsupported");
    }
    
    @Override
    @Deprecated
    protected Object engineGetParameter(final String s) {
        throw new UnsupportedOperationException("engineSetParameter unsupported");
    }
}
