/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
package com.scytl.products.ov.mixnet.proofs.bg.product;

import java.math.BigInteger;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.scytl.cryptolib.mathematical.groups.impl.Exponent;
import com.scytl.products.ov.mixnet.commons.beans.proofs.ProductProofMessage;
import com.scytl.products.ov.mixnet.commons.proofs.bg.commitments.CommitmentParams;
import com.scytl.products.ov.mixnet.commons.proofs.bg.commitments.PublicCommitment;
import com.scytl.products.ov.mixnet.commons.tools.GroupTools;
import com.scytl.products.ov.mixnet.commons.tools.MultiExponentiation;
import com.scytl.products.ov.mixnet.proofs.bg.hadamard.HadamardProductProofVerifier;
import com.scytl.products.ov.mixnet.proofs.bg.singlevalprod.SingleValueProductProofVerifier;

/**
 *
 */
public class ProductProofVerifier {

    private static final Logger LOG = LoggerFactory.getLogger("std");

    private final CommitmentParams pars;

    private final PublicCommitment[] cA;

    private final int n;

    private final int m;

    private final Exponent b;

    private final BigInteger groupOrder;

    private final MultiExponentiation multiExponentiation;

    public ProductProofVerifier(final int n, final int m, final CommitmentParams pars, final PublicCommitment[] cA,
            final Exponent b, final BigInteger groupOrder, final MultiExponentiation multiExponentiation) {
        this.n = n;
        this.m = m;
        this.pars = pars;
        this.cA = cA;
        this.b = b;
        this.groupOrder = groupOrder;

        this.multiExponentiation = multiExponentiation;
    }

    public boolean verify(final ProductProofMessage ans) {

        boolean correct = true;

        if (!GroupTools.isGroupElement(ans.getCommitmentPublicB().getElement())) {
            correct = false;
            LOG.error("ERROR(Product Argument): cd is not a group element");
        }

        // next parts can run in parallel
        final HadamardProductProofVerifier verifHA = new HadamardProductProofVerifier(n, m, pars, cA,
            ans.getCommitmentPublicB(), groupOrder, multiExponentiation);
        final boolean answer1 = verifHA.verify(ans.getIniHPA(), ans.getAnsHPA());

        final SingleValueProductProofVerifier verifSVA = new SingleValueProductProofVerifier(n, pars,
            ans.getCommitmentPublicB(), b, groupOrder, multiExponentiation);
        final boolean answer2 = verifSVA.verify(ans.getIniSVA(), ans.getAnsSVA());

        return answer1 && answer2 && correct;
    }

}
