/*
 * 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.ov.mixing.commons.proofs.bg.multiexp.basic;

import static org.junit.Assert.assertEquals;

import java.io.IOException;
import java.math.BigInteger;

import org.junit.BeforeClass;
import org.junit.Test;

import com.scytl.cryptolib.mathematical.groups.impl.Exponent;
import com.scytl.cryptolib.mathematical.groups.impl.ZpSubgroup;
import com.scytl.ov.mixing.commons.proofs.bg.commitments.CommitmentParams;
import com.scytl.ov.mixing.commons.proofs.bg.commitments.PrivateCommitment;
import com.scytl.ov.mixing.commons.tools.ExponentTools;
import com.scytl.ov.mixing.commons.tools.GroupTools;
import com.scytl.ov.mixing.commons.tools.MultiExponentiation;
import com.scytl.ov.mixing.commons.tools.MultiExponentiationImpl;

public class InitialMessageHelperTest {

    private static final BigInteger _groupModulos = new BigInteger("23");

    private static final BigInteger _groupOrder = new BigInteger("11");

    private static int _m;

    private static int _n;

    private static ZpSubgroup _zp;

    @BeforeClass
    public static void setUp() throws IOException {

        _m = 8;

        _n = 32;

        _zp = GroupTools.createGroupWithRandomGenerator(_groupModulos, _groupOrder);
    }

    @Test
    public void calculate_private_commitments() {

        final int mByTwo = _m * 2;

        final Exponent[] b = new Exponent[mByTwo];
        for (int i = 0; i < mByTwo; i++) {
            b[i] = ExponentTools.getRandomExponent(_groupOrder);
        }

        final Exponent[] s = ExponentTools.getVectorRandomExponent(mByTwo, _groupOrder);

        final CommitmentParams commitmentParams = new CommitmentParams(_zp, _n);

        final MultiExponentiation limMultiExpo = MultiExponentiationImpl.getInstance();

        final PrivateCommitment[] privateCommitments = InitialMessageHelper.calculatePrivateCommitments(_m, b, s,
            commitmentParams, limMultiExpo);

        String errorMsg = "Generated private commitments dont have expected length";
        assertEquals(errorMsg, mByTwo, privateCommitments.length);
    }

    @Test
    public void calculate_exponents_array_S() {

        final int expectedLength = 2 * _m;

        final Exponent[] obtainedExponents = InitialMessageHelper.calculateExponentsArrayS(_m, _groupOrder);

        String errorMsg = "exponent array length does not match expected value";
        assertEquals(errorMsg, expectedLength, obtainedExponents.length);

        for (Exponent obtainedExponent : obtainedExponents) {
            errorMsg = "exponent order does not match expected order";
            assertEquals(errorMsg, obtainedExponent.getQ(), _groupOrder);
        }
    }

    @Test
    public void calculate_exponents_multiarray_B() {

        final int ciphertextsCount = 6;

        final Exponent[] result = InitialMessageHelper.calculateExponentsMultiarrayB(ciphertextsCount, _groupOrder);
        final int expectedFirstDimensionLength = 2 * ciphertextsCount;

        final int actualFirstDimensionLength = result.length;

        String errorMsg = "Array first dimension length was not the expected value";
        assertEquals(errorMsg, expectedFirstDimensionLength, actualFirstDimensionLength);

        for (Exponent aResult : result) {
            errorMsg = "exponent order does not match expected order";
            assertEquals(errorMsg, aResult.getQ(), _groupOrder);
        }
    }
}
