package meerkat.mixer;

/**
 * Created by Tzlil on 12/30/2015.
 */

import com.google.protobuf.InvalidProtocolBufferException;
import meerkat.mixer.proofs.concrete.Mix2nizk;
import meerkat.protobuf.Crypto;
import meerkat.protobuf.Voting;
import org.junit.Before;
import org.junit.Test;

import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class MixingTest extends ECParamTestBase {
    Random random,randomMixer,randomProver;
    Mix2nizk mix2nizk;
    MixGenerator mixer;
    private int n;


    @Before
    public void setup() throws InvalidKeySpecException {
        // initialization
        random = new Random(1);
        randomMixer = new Random(2);
        randomProver = new Random(3);
        mix2nizk = new Mix2nizk(randomProver, enc);
        mixer = new MixGenerator(mix2nizk, enc);

        // generate n
        int logN = 5; //  + random.nextInt(8)
        n = 1 << logN;
    }

    public List<Crypto.RerandomizableEncryptedMessage> generateMixerInput(int n){
        List<Crypto.RerandomizableEncryptedMessage> result = new ArrayList<Crypto.RerandomizableEncryptedMessage>();
        Voting.PlaintextBallot msg;
        for (int i = 0; i < n ; i++){
            msg = Utils.genRandomBallot(2,3,16);
            result.add(enc.encrypt(msg, enc.generateRandomness(random)));
        }
        return result;
    }

    @Test
    public void mixingTest() throws InvalidProtocolBufferException {
        System.out.println("n is : " + n);
        System.out.println("  generating input");
        List<Crypto.RerandomizableEncryptedMessage> mixerInput = generateMixerInput(n);
        System.out.println("  start network");
        long startTime = System.currentTimeMillis();

        MixerOutput mixerOutput = mixer.mix(mixerInput,randomMixer);

        long finishTime = System.currentTimeMillis();
        System.out.println("    that took: "+(finishTime-startTime)+ " ms");

        System.out.println("start verification");
        startTime = System.currentTimeMillis();

        assert (MixVerifier.verifyTable(mix2nizk, mixerOutput, true));

        finishTime = System.currentTimeMillis();
        System.out.println("    that took: "+(finishTime-startTime)+ " ms");
    }
}
