Modified Fibonacci Implementation Purpose

This question comes from a HackerRank problem called Fibonacci Modified. I think I have coded a valid solution, but would like feedback about my approach, implementation, and of course, any errors / edge cases that I may have missed.

Task



Implementation

public class FibonacciModifiedImpl implements FibonacciModified {

    @Override
    public BigInteger calculateNextTerm(final BigInteger currentTerm, final BigInteger lastTerm) {
        if (-1 == lastTerm.compareTo(BigInteger.ZERO) ) {
            throw new IllegalArgumentException("last term must be non-negative");
        }

        if (-1 == currentTerm.compareTo(lastTerm)) {
            throw new IllegalArgumentException("current term must be greater than or equal to last term");
        }

        final BigInteger squaredTerm = new BigDecimal(Math.pow(currentTerm.doubleValue(), 2)).toBigInteger();
        return squaredTerm.add(lastTerm);
    }

    @Override
    public BigInteger calculateNthTerm(final BigInteger firstTerm, final BigInteger secondTerm, final int n) {
        if (-1 == firstTerm.compareTo(BigInteger.ZERO) ) {
            throw new IllegalArgumentException("first term must be non-negative");
        }

        if (-1 == secondTerm.compareTo(firstTerm)) {
            throw new IllegalArgumentException("second term must be greater than or equal to last term");
        }

        if (n &lt; 1) {
            throw new IllegalArgumentException("number of terms must be greater than 0");
        }

        switch (n) {
            case 1: {
                return firstTerm;
            }

            case 2: {
                return secondTerm;
            }

            default: {
                int counter = 2;
                BigInteger currentTerm = secondTerm;
                BigInteger lastTerm = firstTerm;
                while (counter &lt; n) {
                    BigInteger nextTerm = calculateNextTerm(currentTerm, lastTerm);
                    lastTerm = currentTerm;
                    currentTerm = nextTerm;
                    counter++;
                }

                return currentTerm;
            }
        }
    }
}
Generally looks good. Except

    final BigInteger squaredTerm = new BigDecimal(Math.pow(currentTerm.doubleValue(), 2)).toBigInteger();


There is absolutely no reason to cast Math in. The computations are supposed to be exact, which Math is notoriously lacking. I recommend

    final BigInteger squaredTerm = currentTerm.multiply(currentTerm);