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

package org.bouncycastle.pqc.crypto.mldsa;

import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.CryptoException;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.crypto.params.ParametersWithContext;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.digests.SHAKEDigest;
import java.security.SecureRandom;
import org.bouncycastle.crypto.Signer;

public class MLDSASigner implements Signer
{
    private static final byte[] EMPTY_CONTEXT;
    private MLDSAPublicKeyParameters pubKey;
    private MLDSAPrivateKeyParameters privKey;
    private SecureRandom random;
    private MLDSAEngine engine;
    private SHAKEDigest msgDigest;
    
    @Override
    public void init(final boolean b, CipherParameters parameters) {
        byte[] array = MLDSASigner.EMPTY_CONTEXT;
        if (parameters instanceof ParametersWithContext) {
            final ParametersWithContext parametersWithContext = (ParametersWithContext)parameters;
            array = parametersWithContext.getContext();
            parameters = parametersWithContext.getParameters();
            if (array.length > 255) {
                throw new IllegalArgumentException("context too long");
            }
        }
        MLDSAParameters mldsaParameters;
        if (b) {
            this.pubKey = null;
            if (parameters instanceof ParametersWithRandom) {
                final ParametersWithRandom parametersWithRandom = (ParametersWithRandom)parameters;
                this.privKey = (MLDSAPrivateKeyParameters)parametersWithRandom.getParameters();
                this.random = parametersWithRandom.getRandom();
            }
            else {
                this.privKey = (MLDSAPrivateKeyParameters)parameters;
                this.random = null;
            }
            mldsaParameters = this.privKey.getParameters();
            (this.engine = mldsaParameters.getEngine(this.random)).initSign(this.privKey.tr, false, array);
        }
        else {
            this.pubKey = (MLDSAPublicKeyParameters)parameters;
            this.privKey = null;
            this.random = null;
            mldsaParameters = this.pubKey.getParameters();
            (this.engine = mldsaParameters.getEngine(null)).initVerify(this.pubKey.rho, this.pubKey.t1, false, array);
        }
        if (mldsaParameters.isPreHash()) {
            throw new IllegalArgumentException("\"pure\" ml-dsa must use non pre-hash parameters");
        }
        this.reset();
    }
    
    @Override
    public void update(final byte b) {
        this.msgDigest.update(b);
    }
    
    @Override
    public void update(final byte[] array, final int n, final int n2) {
        this.msgDigest.update(array, n, n2);
    }
    
    public byte[] generateMu() throws CryptoException, DataLengthException {
        final byte[] generateMu = this.engine.generateMu(this.msgDigest);
        this.reset();
        return generateMu;
    }
    
    public byte[] generateMuSignature(final byte[] array) throws CryptoException, DataLengthException {
        if (array.length != 64) {
            throw new DataLengthException("mu value must be 64 bytes");
        }
        final byte[] bytes = new byte[32];
        if (this.random != null) {
            this.random.nextBytes(bytes);
        }
        this.msgDigest.reset();
        final byte[] generateSignature = this.engine.generateSignature(array, this.msgDigest, this.privKey.rho, this.privKey.k, this.privKey.t0, this.privKey.s1, this.privKey.s2, bytes);
        this.reset();
        return generateSignature;
    }
    
    @Override
    public byte[] generateSignature() throws CryptoException, DataLengthException {
        final byte[] bytes = new byte[32];
        if (this.random != null) {
            this.random.nextBytes(bytes);
        }
        final byte[] generateSignature = this.engine.generateSignature(this.engine.generateMu(this.msgDigest), this.msgDigest, this.privKey.rho, this.privKey.k, this.privKey.t0, this.privKey.s1, this.privKey.s2, bytes);
        this.reset();
        return generateSignature;
    }
    
    public boolean verifyMu(final byte[] array) {
        if (array.length != 64) {
            throw new DataLengthException("mu value must be 64 bytes");
        }
        final boolean verifyInternalMu = this.engine.verifyInternalMu(array);
        this.reset();
        return verifyInternalMu;
    }
    
    @Override
    public boolean verifySignature(final byte[] array) {
        final boolean verifyInternal = this.engine.verifyInternal(array, array.length, this.msgDigest, this.pubKey.rho, this.pubKey.t1);
        this.reset();
        return verifyInternal;
    }
    
    public boolean verifyMuSignature(final byte[] array, final byte[] array2) {
        if (array.length != 64) {
            throw new DataLengthException("mu value must be 64 bytes");
        }
        this.msgDigest.reset();
        final boolean verifyInternalMuSignature = this.engine.verifyInternalMuSignature(array, array2, array2.length, this.msgDigest, this.pubKey.rho, this.pubKey.t1);
        this.reset();
        return verifyInternalMuSignature;
    }
    
    @Override
    public void reset() {
        this.msgDigest = this.engine.getShake256Digest();
    }
    
    protected byte[] internalGenerateSignature(final byte[] array, final byte[] array2) {
        final MLDSAEngine engine = this.privKey.getParameters().getEngine(this.random);
        engine.initSign(this.privKey.tr, false, null);
        return engine.signInternal(array, array.length, this.privKey.rho, this.privKey.k, this.privKey.t0, this.privKey.s1, this.privKey.s2, array2);
    }
    
    protected boolean internalVerifySignature(final byte[] array, final byte[] array2) {
        final MLDSAEngine engine = this.pubKey.getParameters().getEngine(this.random);
        engine.initVerify(this.pubKey.rho, this.pubKey.t1, false, null);
        final SHAKEDigest shake256Digest = engine.getShake256Digest();
        shake256Digest.update(array, 0, array.length);
        return engine.verifyInternal(array2, array2.length, shake256Digest, this.pubKey.rho, this.pubKey.t1);
    }
    
    static {
        EMPTY_CONTEXT = new byte[0];
    }
}
