/*
 * 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.cryptolib.primitives.ffc;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.math.BigInteger;

import org.junit.Before;
import org.junit.Test;

import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.ffc.cryptoapi.FFCPrimes;

/**
 * Tests of {@link FFCPrimesFactoryImpl}
 */
public class FFCPrimesFactoryImplTest {
    private FFCPrimesFactoryImpl factory;

    @Before
    public void setUp() {
        SmallPrimesProvider provider =
            SmallPrimesProviderImpl.getInstance();
        FFCPrimeFactory primeFactory = new FFCPrimeFactoryImpl(provider);
        factory = new FFCPrimesFactoryImpl(primeFactory);
    }

    @Test
    public void testNewFFCPrimes1024x160()
            throws GeneralCryptoLibException {
        testNewFFCPrimes(1024, 160);
    }

    @Test
    public void testNewFFCPrimes2048x224()
            throws GeneralCryptoLibException {
        testNewFFCPrimes(2048, 224);
    }

    @Test
    public void testNewFFCPrimes2048x256()
            throws GeneralCryptoLibException {
        testNewFFCPrimes(2048, 256);
    }

    @Test
    public void testNewFFCPrimes3072x256()
            throws GeneralCryptoLibException {
        testNewFFCPrimes(3072, 256);
    }

    private void testNewFFCPrimes(int l, int n)
            throws GeneralCryptoLibException {
        PseudoRandom random = FakePseudoRandom.newInstance(n);
        FFCPrimes primes = factory.newFFCPrimes(l, n, random);
        assertTrue(primes.p().value().isProbablePrime(80));
        assertEquals(l, primes.p().value().bitLength());
        assertTrue(primes.p().genCounter() > 0);
        assertTrue(primes.q().value().isProbablePrime(80));
        assertEquals(n, primes.q().value().bitLength());
        assertTrue(primes.q().genCounter() > 0);
        assertEquals(random.seed(), primes.p().seed());
        assertEquals(BigInteger.ZERO, primes.p().value()
            .subtract(BigInteger.ONE).mod(primes.q().value()));
    }
}
