package aalgTest;


import java.math.BigInteger;

import org.junit.Test;
import org.junit.Assert;

import aalg.algebra.Utils;
import aalg.crypto.CtrStreamCipher;

/**
 * Test that verifies expected properties of increment constant of CTR cipher mode.
 * @author Ing. Petr Ležák
 */
public class CtrIncrementTest {
	@Test
	public void testBitCount() {
		Assert.assertEquals(Long.SIZE / 2, Long.bitCount(CtrStreamCipher.INCREMENT_CONSTANT));
	}
	
	@Test
	public void testRotate() {
		for (int i = 1; i < Long.SIZE; i++)
			Assert.assertTrue(Long.rotateLeft(CtrStreamCipher.INCREMENT_CONSTANT, i) != CtrStreamCipher.INCREMENT_CONSTANT);
	}
	
	
	@Test
	public void testInvertibility() {
		for (int i = 1; i < 1024 / Utils.INT_BYTE_COUNT; i++) {
			final int[] increment = CtrStreamCipher.generateIncrement(i);
			Assert.assertEquals(i, increment.length);
			
			BigInteger incrementNumber = BigInteger.ZERO;
			
			for (int j = 0; j < i; j++) {
				incrementNumber = incrementNumber.add(BigInteger.valueOf(increment[j] & Utils.INT_MASK).shiftLeft(j * Integer.SIZE));
			}
			
			incrementNumber.modInverse(BigInteger.ONE.shiftLeft(i * Integer.SIZE));   // Throws exception when there is no inverse
		}
	}
}
