package meerkat.crypto.secretsharing.shamir.PolynomialTests;

import meerkat.crypto.secretsharing.shamir.Polynomial;
import meerkat.crypto.utils.Arithmetic;
import meerkat.crypto.utils.concrete.Fp;
import meerkat.crypto.utils.GenerateRandomPolynomial;
import meerkat.crypto.utils.GenerateRandomPrime;
import org.junit.Before;
import org.junit.Test;

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

/**
 * Created by Tzlil on 1/27/2016.
 */
public class InterpolationTest {
    Polynomial[] polynomials;
    int tests = 1 << 10;
    int maxDegree = 15;
    int bits = 128;
    Random random;
    Polynomial.Point[][] pointsArrays;
    Arithmetic<BigInteger> arithmetic;
    BigInteger p = GenerateRandomPrime.SafePrime100Bits;

    @Before
    public void settings(){
        random = new Random();
        polynomials = new Polynomial[tests];
        pointsArrays = new Polynomial.Point[tests][];
        arithmetic = new Fp(p);
        for (int i = 0; i < polynomials.length; i++){
            polynomials[i] = GenerateRandomPolynomial.generateRandomPolynomial(random.nextInt(maxDegree),bits,random,p);
            pointsArrays[i] = randomPoints(polynomials[i]);
        }
    }

    public Polynomial.Point[] randomPoints(Polynomial polynomial){
        Polynomial.Point[] points = new Polynomial.Point[polynomial.getDegree() + 1];
        BigInteger x;
        Set<BigInteger> set = new HashSet();
        for (int i = 0; i < points.length; i++){
            x = new BigInteger(bits,random).mod(p);
            if(set.contains(x)){
                i--;
                continue;
            }
            set.add(x);
            points[i] = new Polynomial.Point(x,polynomial);
        }
        return points;
    }

    public void oneTest(Polynomial p, Polynomial.Point[] points) throws Exception {
        Polynomial interpolation = Polynomial.interpolation(points,arithmetic);
        assert (p.compareTo(interpolation) == 0);
    }

    @Test
    public void interpolationTest() throws Exception {
        for (int i = 0; i < polynomials.length; i ++){
            oneTest(polynomials[i],pointsArrays[i]);
        }
    }
}
