package meerkat.crypto.secretsharing.feldman;

import meerkat.crypto.secretsharing.shamir.Polynomial;
import org.factcenter.qilin.primitives.Group;
import org.factcenter.qilin.primitives.concrete.Zpstar;
import org.junit.Before;
import org.junit.Test;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Random;

/**
 * Created by Tzlil on 1/29/2016.
 */
public class VerifiableSecretSharingTest {


    VerifiableSecretSharing[] verifiableSecretSharingArray;
    int tests = 1 << 10;
    Random random;

    @Before
    public void settings(){
        BigInteger p = BigInteger.valueOf(2903);
        BigInteger q = p.subtract(BigInteger.ONE).divide(BigInteger.valueOf(2));
        Zpstar zpstar = new Zpstar(p);
        random = new Random();
        BigInteger g;
        BigInteger ZERO = zpstar.zero();
        do{
            g = zpstar.sample(random);
        }while (!g.equals(ZERO) && !zpstar.multiply(g,q).equals(ZERO));// sample from QRZp*
        int t = 8;
        int n = 20;
        verifiableSecretSharingArray = new VerifiableSecretSharing[tests];
        for (int i = 0; i < verifiableSecretSharingArray.length; i++){
            verifiableSecretSharingArray[i] = new VerifiableSecretSharing(t,n
                    ,new BigInteger(q.bitLength(),random).mod(q),random,q,g,zpstar);
        }
    }

    public void oneTest(VerifiableSecretSharing<BigInteger> verifiableSecretSharing) throws Exception {
        int n = verifiableSecretSharing.getN();
        Group<BigInteger> zpstar = verifiableSecretSharing.getGroup();
        BigInteger g = verifiableSecretSharing.getGenerator();
        Polynomial.Point[] shares = new Polynomial.Point[n];
        ArrayList<BigInteger> commitments = verifiableSecretSharing.getCommitmentsArrayList();
        BigInteger[] verifications = new BigInteger[n];
        for (int i = 1 ; i <= shares.length; i ++){
            shares[i - 1] = verifiableSecretSharing.getShare(i);
            verifications[i - 1] = VerifiableSecretSharing.computeVerificationValue(i,commitments,zpstar);
        }
        BigInteger expected;
        for (int i = 0 ; i < shares.length ; i++){
            expected = zpstar.multiply(g,shares[i].y);
            assert (expected.equals(verifications[i]));
        }

    }

    @Test
    public void secretSharingTest() throws Exception {
        for (int i = 0 ; i < verifiableSecretSharingArray.length; i ++){
            oneTest(verifiableSecretSharingArray[i]);
        }
    }
}
