package aalg.algebra;

import java.math.BigInteger;

/**
 * Transformation from rational to prime field.
 * @author Ing. Petr Ležák
 *
 */
public class RationalToPrimeFieldTransformation implements IFieldTransformation<RationalFieldElement, PrimeFieldElement> {

	private final PrimeField outputField;
	private final BigInteger prime;
	
	public RationalToPrimeFieldTransformation(final PrimeField field) {
		this.outputField = field;
		this.prime = field.getPrime();
	}

	/**
	 * Element in the form
	 *   numerator / denominator
	 * is transformed into
	 *   numerator * denominator^(-1) (mod p).
	 * TransformationException is thrown in case that denominator is not invertible.
	 */
	@Override
	public PrimeFieldElement transformElement(final RationalFieldElement element) throws TransformationException {
		try {
			final BigInteger numerator = element.getNumerator().mod(prime);
			final BigInteger denominator = element.getDenominator();
			final BigInteger invDenominator = denominator.modInverse(prime);
			final BigInteger result = numerator.multiply(invDenominator).mod(prime);
			
			return new PrimeFieldElement(result);
		}
		catch (ArithmeticException ex) {
			throw new TransformationException();
		}
	}

	@Override
	public IField<RationalFieldElement> getInputField() {
		return RationalField.INSTANCE;
	}

	@Override
	public IField<PrimeFieldElement> getOutputField() {
		return outputField;
	}

}
