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

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

import org.bouncycastle.crypto.DataLengthException;
import java.io.ByteArrayOutputStream;
import java.security.NoSuchAlgorithmException;
import org.bouncycastle.crypto.CipherParameters;
import java.security.SignatureException;
import org.bouncycastle.jcajce.interfaces.MLDSAPublicKey;
import java.io.IOException;
import org.bouncycastle.jcajce.MLDSAProxyPrivateKey;
import java.security.SecureRandom;
import java.security.PrivateKey;
import java.security.InvalidKeyException;
import org.bouncycastle.pqc.crypto.mldsa.MLDSAPublicKeyParameters;
import org.bouncycastle.pqc.crypto.util.PublicKeyFactory;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import java.security.PublicKey;
import org.bouncycastle.jcajce.spec.MLDSAParameterSpec;
import org.bouncycastle.pqc.crypto.mldsa.MLDSAParameters;
import org.bouncycastle.pqc.crypto.mldsa.MLDSASigner;
import org.bouncycastle.jcajce.provider.asymmetric.util.BaseDeterministicOrRandomSignature;

public class SignatureSpi extends BaseDeterministicOrRandomSignature
{
    protected MLDSASigner signer;
    protected MLDSAParameters parameters;
    
    protected SignatureSpi(final MLDSASigner signer) {
        super("MLDSA");
        this.signer = signer;
        this.parameters = null;
    }
    
    protected SignatureSpi(final MLDSASigner signer, final MLDSAParameters parameters) {
        super(MLDSAParameterSpec.fromName(parameters.getName()).getName());
        this.signer = signer;
        this.parameters = parameters;
    }
    
    @Override
    protected void verifyInit(PublicKey publicKey) throws InvalidKeyException {
        if (publicKey instanceof BCMLDSAPublicKey) {
            this.keyParams = ((BCMLDSAPublicKey)publicKey).getKeyParams();
        }
        else {
            try {
                this.keyParams = PublicKeyFactory.createKey(SubjectPublicKeyInfo.getInstance(publicKey.getEncoded()));
                publicKey = new BCMLDSAPublicKey((MLDSAPublicKeyParameters)this.keyParams);
            }
            catch (final Exception ex) {
                throw new InvalidKeyException("unknown public key passed to ML-DSA");
            }
        }
        if (this.parameters != null) {
            final String name = MLDSAParameterSpec.fromName(this.parameters.getName()).getName();
            if (!name.equals(publicKey.getAlgorithm())) {
                throw new InvalidKeyException("signature configured for " + name);
            }
        }
    }
    
    @Override
    protected void signInit(final PrivateKey privateKey, final SecureRandom appRandom) throws InvalidKeyException {
        this.appRandom = appRandom;
        if (privateKey instanceof BCMLDSAPrivateKey) {
            final BCMLDSAPrivateKey bcmldsaPrivateKey = (BCMLDSAPrivateKey)privateKey;
            this.keyParams = bcmldsaPrivateKey.getKeyParams();
            if (this.parameters != null) {
                final String name = MLDSAParameterSpec.fromName(this.parameters.getName()).getName();
                if (!name.equals(bcmldsaPrivateKey.getAlgorithm())) {
                    throw new InvalidKeyException("signature configured for " + name);
                }
            }
        }
        else {
            if (!(privateKey instanceof MLDSAProxyPrivateKey) || !(this instanceof MLDSACalcMu)) {
                throw new InvalidKeyException("unknown private key passed to ML-DSA");
            }
            final MLDSAPublicKey publicKey = ((MLDSAProxyPrivateKey)privateKey).getPublicKey();
            try {
                this.keyParams = PublicKeyFactory.createKey(publicKey.getEncoded());
            }
            catch (final IOException ex) {
                throw new InvalidKeyException(ex.getMessage());
            }
            if (this.parameters != null) {
                final String name2 = MLDSAParameterSpec.fromName(this.parameters.getName()).getName();
                if (!name2.equals(publicKey.getAlgorithm())) {
                    throw new InvalidKeyException("signature configured for " + name2);
                }
            }
        }
    }
    
    @Override
    protected void updateEngine(final byte b) throws SignatureException {
        this.signer.update(b);
    }
    
    @Override
    protected void updateEngine(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 Exception ex) {
            throw new SignatureException(ex.toString());
        }
    }
    
    @Override
    protected boolean engineVerify(final byte[] array) throws SignatureException {
        return this.signer.verifySignature(array);
    }
    
    @Override
    protected void reInitialize(final boolean b, final CipherParameters cipherParameters) {
        this.signer.init(b, cipherParameters);
    }
    
    public static class MLDSA extends SignatureSpi
    {
        public MLDSA() {
            super(new MLDSASigner());
        }
    }
    
    public static class MLDSA44 extends SignatureSpi
    {
        public MLDSA44() {
            super(new MLDSASigner(), MLDSAParameters.ml_dsa_44);
        }
    }
    
    public static class MLDSA65 extends SignatureSpi
    {
        public MLDSA65() {
            super(new MLDSASigner(), MLDSAParameters.ml_dsa_65);
        }
    }
    
    public static class MLDSA87 extends SignatureSpi
    {
        public MLDSA87() throws NoSuchAlgorithmException {
            super(new MLDSASigner(), MLDSAParameters.ml_dsa_87);
        }
    }
    
    public static class MLDSACalcMu extends SignatureSpi
    {
        public MLDSACalcMu() {
            super(new MLDSASigner());
        }
        
        @Override
        protected byte[] engineSign() throws SignatureException {
            try {
                return this.signer.generateMu();
            }
            catch (final Exception ex) {
                throw new SignatureException(ex.toString());
            }
        }
        
        @Override
        protected boolean engineVerify(final byte[] array) throws SignatureException {
            return this.signer.verifyMu(array);
        }
    }
    
    public static class MLDSAExtMu extends SignatureSpi
    {
        private ByteArrayOutputStream bOut;
        
        public MLDSAExtMu() {
            super(new MLDSASigner());
            this.bOut = new ByteArrayOutputStream(64);
        }
        
        @Override
        protected void updateEngine(final byte b) throws SignatureException {
            this.bOut.write(b);
        }
        
        @Override
        protected void updateEngine(final byte[] b, final int off, final int len) throws SignatureException {
            this.bOut.write(b, off, len);
        }
        
        @Override
        protected byte[] engineSign() throws SignatureException {
            try {
                final byte[] byteArray = this.bOut.toByteArray();
                this.bOut.reset();
                return this.signer.generateMuSignature(byteArray);
            }
            catch (final DataLengthException ex) {
                throw new SignatureException(ex.getMessage());
            }
            catch (final Exception ex2) {
                throw new SignatureException(ex2.toString());
            }
        }
        
        @Override
        protected boolean engineVerify(final byte[] array) throws SignatureException {
            final byte[] byteArray = this.bOut.toByteArray();
            this.bOut.reset();
            try {
                return this.signer.verifyMuSignature(byteArray, array);
            }
            catch (final DataLengthException ex) {
                throw new SignatureException(ex.getMessage());
            }
        }
    }
}
