package profiling.Convert;

import com.google.protobuf.InvalidProtocolBufferException;
import meerkat.crypto.concrete.ECElGamalEncryption;
import meerkat.crypto.concrete.Util;
import meerkat.mixer.Utils;
import meerkat.protobuf.ConcreteCrypto;
import meerkat.protobuf.Voting;
import org.spongycastle.math.ec.ECPoint;
import org.factcenter.qilin.primitives.concrete.ECElGamal;
import org.factcenter.qilin.primitives.concrete.ECGroup;

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

/**
 * Created by Tzlil on 1/25/2016.
 */
public class ByteString2ECPoint {
    Random rand;
    ECElGamal.SK key;
    ECGroup group;
    ECElGamalEncryption enc;
    ConcreteCrypto.ElGamalPublicKey serializedPk;
    int tests;
    ConcreteCrypto.ElGamalCiphertext[] encryptedMessage;

    public void setup() throws Exception {
        rand = new Random();
        group = new ECGroup("secp256k1");
        BigInteger sk = ECElGamal.generateSecretKey(group, rand);
        key = new ECElGamal.SK(group, sk);
        serializedPk = Util.encodePK(group, key);
        enc = new ECElGamalEncryption();
        enc.init(serializedPk);
        tests = 1024 * 19;
        encryptedMessage = new ConcreteCrypto.ElGamalCiphertext[tests];

        Voting.PlaintextBallot msg;

        for (int i = 0; i < tests; i ++){
            msg = Utils.genRandomBallot(2,3,16);

            encryptedMessage[i] = ECElGamalEncryption.RerandomizableEncryptedMessage2ElGamalCiphertext
                    (enc.encrypt(msg, enc.generateRandomness(rand)));
        }
    }
    private ECPoint convert2ECPoint(ConcreteCrypto.GroupElement bs){
        return enc.decodeElement(bs);
    }

    public void ByteString2ECPointProfiling() throws InvalidProtocolBufferException {

        System.out.println("ByteString2ECPointProfiling");
        System.out.println("#"+ tests + " tests");
        System.out.println("start tests operations");
        long startTime = System.currentTimeMillis();

        for (int i = 0; i < tests; i ++){
            convert2ECPoint(encryptedMessage[i].getC1());
            convert2ECPoint(encryptedMessage[i].getC2());
        }

        long finishTime = System.currentTimeMillis();
        System.out.println("    that took: "+(finishTime-startTime)+ " ms");
        System.out.println("    avg of "+((double)(finishTime-startTime))/ (2 * tests) + " ms");
    }
}
