/*
 * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * @test id=IntegerPolynomial25519
 * @bug 8181594 8208648
 * @summary Test proper operation of integer field arithmetic
 * @modules java.base/sun.security.util java.base/sun.security.util.math java.base/sun.security.util.math.intpoly
 * @build BigIntegerModuloP
 * @run main TestIntegerModuloP sun.security.util.math.intpoly.IntegerPolynomial25519 32 0
 */

 /*
 * @test id=IntegerPolynomial448
 * @modules java.base/sun.security.util java.base/sun.security.util.math java.base/sun.security.util.math.intpoly
 * @build BigIntegerModuloP
 * @run main TestIntegerModuloP sun.security.util.math.intpoly.IntegerPolynomial448 56 1
 */

 /*
 * @test id=IntegerPolynomial1305
 * @modules java.base/sun.security.util java.base/sun.security.util.math java.base/sun.security.util.math.intpoly
 * @build BigIntegerModuloP
 * @run main TestIntegerModuloP sun.security.util.math.intpoly.IntegerPolynomial1305 16 2
 */

 /*
 * @test id=IntegerPolynomialP256
 * @modules java.base/sun.security.util java.base/sun.security.util.math java.base/sun.security.util.math.intpoly
 * @build BigIntegerModuloP
 * @run main TestIntegerModuloP sun.security.util.math.intpoly.IntegerPolynomialP256 32 5
 */

 /*
 * @test id=IntegerPolynomialP384
 * @modules java.base/sun.security.util java.base/sun.security.util.math java.base/sun.security.util.math.intpoly
 * @build BigIntegerModuloP
 * @run main TestIntegerModuloP sun.security.util.math.intpoly.IntegerPolynomialP384 48 6
 */

 /*
 * @test id=IntegerPolynomialP521
 * @modules java.base/sun.security.util java.base/sun.security.util.math java.base/sun.security.util.math.intpoly
 * @build BigIntegerModuloP
 * @run main TestIntegerModuloP sun.security.util.math.intpoly.IntegerPolynomialP521 66 7
 */

 /*
 * @test id=P256OrderField
 * @modules java.base/sun.security.util java.base/sun.security.util.math java.base/sun.security.util.math.intpoly
 * @build BigIntegerModuloP
 * @run main TestIntegerModuloP sun.security.util.math.intpoly.P256OrderField 32 8
 */

 /*
 * @test id=P384OrderField
 * @modules java.base/sun.security.util java.base/sun.security.util.math java.base/sun.security.util.math.intpoly
 * @build BigIntegerModuloP
 * @run main TestIntegerModuloP sun.security.util.math.intpoly.P384OrderField 48 9
 */

 /*
 * @test id=P521OrderField
 * @modules java.base/sun.security.util java.base/sun.security.util.math java.base/sun.security.util.math.intpoly
 * @build BigIntegerModuloP
 * @run main TestIntegerModuloP sun.security.util.math.intpoly.P521OrderField 66 10
 */

 /*
 * @test id=Curve25519OrderField
 * @modules java.base/sun.security.util java.base/sun.security.util.math java.base/sun.security.util.math.intpoly
 * @build BigIntegerModuloP
 * @run main TestIntegerModuloP sun.security.util.math.intpoly.Curve25519OrderField 32 11
 */

 /*
 * @test id=Curve448OrderField
 * @modules java.base/sun.security.util java.base/sun.security.util.math java.base/sun.security.util.math.intpoly
 * @build BigIntegerModuloP
 * @run main TestIntegerModuloP sun.security.util.math.intpoly.Curve448OrderField 56 12
 */

import sun.security.util.math.*;
import sun.security.util.math.intpoly.*;
import java.util.function.*;

import java.util.*;
import java.math.*;
import java.nio.*;

public class TestIntegerModuloP {

    static BigInteger TWO = BigInteger.valueOf(2);

    // The test has a list of functions, and it selects randomly from that list

    // The function types
    interface ElemFunction extends BiFunction
        <MutableIntegerModuloP, IntegerModuloP, IntegerModuloP> { }
    interface ElemArrayFunction extends BiFunction
        <MutableIntegerModuloP, IntegerModuloP, byte[]> { }
    interface TriConsumer <T, U, V> {
        void accept(T t, U u, V v);
    }
    interface ElemSetFunction extends TriConsumer
        <MutableIntegerModuloP, IntegerModuloP, byte[]> { }

    // The lists of functions. Multiple lists are needed because the test
    // respects the limitations of the arithmetic implementations.
    static final List<ElemFunction> ADD_FUNCTIONS = new ArrayList<>();
    static final List<ElemFunction> MULT_FUNCTIONS = new ArrayList<>();
    static final List<ElemArrayFunction> ARRAY_FUNCTIONS = new ArrayList<>();
    static final List<ElemSetFunction> SET_FUNCTIONS = new ArrayList<>();

    static void setUpFunctions(IntegerFieldModuloP field, int length) {

        ADD_FUNCTIONS.clear();
        MULT_FUNCTIONS.clear();
        SET_FUNCTIONS.clear();
        ARRAY_FUNCTIONS.clear();

        byte highByte = (byte)
            (field.getSize().bitLength() > length * 8 ? 1 : 0);

        // add functions are (im)mutable add/subtract
        ADD_FUNCTIONS.add(IntegerModuloP::add);
        ADD_FUNCTIONS.add(IntegerModuloP::subtract);
        ADD_FUNCTIONS.add(MutableIntegerModuloP::setSum);
        ADD_FUNCTIONS.add(MutableIntegerModuloP::setDifference);
        // also include functions that return the first/second argument
        ADD_FUNCTIONS.add((a, b) -> a);
        ADD_FUNCTIONS.add((a, b) -> b);

        // mult functions are (im)mutable multiply and square
        MULT_FUNCTIONS.add(IntegerModuloP::multiply);
        MULT_FUNCTIONS.add((a, b) -> a.square());
        MULT_FUNCTIONS.add((a, b) -> b.square());
        MULT_FUNCTIONS.add(MutableIntegerModuloP::setProduct);
        MULT_FUNCTIONS.add((a, b) -> a.setSquare());
        // also test multiplication by a small value
        MULT_FUNCTIONS.add((a, b) -> a.setProduct(b.getField().getSmallValue(
            b.asBigInteger().mod(BigInteger.valueOf(262144)).intValue())));

        // set functions are setValue with various argument types
        SET_FUNCTIONS.add((a, b, c) -> a.setValue(b));
        SET_FUNCTIONS.add((a, b, c) ->
            a.setValue(c, 0, c.length, (byte) 0));
        SET_FUNCTIONS.add((a, b, c) ->
            a.setValue(c, 0, c.length / 2, (byte) 0));
        SET_FUNCTIONS.add((a, b, c) ->
            a.setValue(ByteBuffer.wrap(c, 0, c.length / 2).order(ByteOrder.LITTLE_ENDIAN),
            c.length / 2, highByte));

        // array functions return the (possibly modified) value as byte array
        ARRAY_FUNCTIONS.add((a, b ) -> a.asByteArray(length));
        ARRAY_FUNCTIONS.add((a, b) -> a.addModPowerTwo(b, length));
    }

    public static void main(String[] args) {

        String className = args[0];
        final int length = Integer.parseInt(args[1]);
        int seed = Integer.parseInt(args[2]);

        try {
            Class<?> clazz = Class.forName(className);
            IntegerFieldModuloP field = (IntegerFieldModuloP)
                    clazz.getDeclaredField("ONE").get(null);

            setUpFunctions(field, length);

            runFieldTest(field, length, seed);
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
        System.out.println("All tests passed");
    }

    static void assertEqual(IntegerModuloP e1, IntegerModuloP e2) {

        if (!e1.asBigInteger().equals(e2.asBigInteger())) {
            throw new RuntimeException("values not equal: "
                + e1.asBigInteger() + " != " + e2.asBigInteger());
        }
    }

    // A class that holds pairs of actual/expected values, and allows
    // computation on these pairs.
    static class TestPair<T extends IntegerModuloP> {
        private final T test;
        private final T baseline;

        public TestPair(T test, T baseline) {
            this.test = test;
            this.baseline = baseline;
        }

        public T getTest() {
            return test;
        }
        public T getBaseline() {
            return baseline;
        }

        private void assertEqual() {
            TestIntegerModuloP.assertEqual(test, baseline);
        }

        public TestPair<MutableIntegerModuloP> mutable() {
            return new TestPair<>(test.mutable(), baseline.mutable());
        }

        public
        <R extends IntegerModuloP, X extends IntegerModuloP>
        TestPair<X> apply(BiFunction<T, R, X> func, TestPair<R> right) {
            X testResult = func.apply(test, right.test);
            X baselineResult = func.apply(baseline, right.baseline);
            return new TestPair(testResult, baselineResult);
        }

        public
        <U extends IntegerModuloP, V>
        void apply(TriConsumer<T, U, V> func, TestPair<U> right, V argV) {
            func.accept(test, right.test, argV);
            func.accept(baseline, right.baseline, argV);
        }

        public
        <R extends IntegerModuloP>
        void applyAndCheckArray(BiFunction<T, R, byte[]> func,
                                TestPair<R> right) {
            byte[] testResult = func.apply(test, right.test);
            byte[] baselineResult = func.apply(baseline, right.baseline);
            if (!Arrays.equals(testResult, baselineResult)) {
                throw new RuntimeException("Array values do not match: "
                    + HexFormat.of().withUpperCase().formatHex(testResult) + " != "
                    + HexFormat.of().withUpperCase().formatHex(baselineResult));
            }
        }

    }

    static TestPair<IntegerModuloP>
    applyAndCheck(ElemFunction func, TestPair<MutableIntegerModuloP> left,
                  TestPair<IntegerModuloP> right) {

        TestPair<IntegerModuloP> result = left.apply(func, right);
        result.assertEqual();
        left.assertEqual();
        right.assertEqual();

        return result;
    }

    static void
    setAndCheck(ElemSetFunction func, TestPair<MutableIntegerModuloP> left,
                TestPair<IntegerModuloP> right, byte[] argV) {

        left.apply(func, right, argV);
        left.assertEqual();
        right.assertEqual();
    }

    static TestPair<MutableIntegerModuloP>
    applyAndCheckMutable(ElemFunction func,
                         TestPair<MutableIntegerModuloP> left,
                         TestPair<IntegerModuloP> right) {

        TestPair<IntegerModuloP> result = applyAndCheck(func, left, right);

        TestPair<MutableIntegerModuloP> mutableResult = result.mutable();
        mutableResult.assertEqual();
        result.assertEqual();
        left.assertEqual();
        right.assertEqual();

        return mutableResult;
    }

    static void
    cswapAndCheck(int swap, TestPair<MutableIntegerModuloP> left,
                  TestPair<MutableIntegerModuloP> right) {

        left.getTest().conditionalSwapWith(right.getTest(), swap);
        left.getBaseline().conditionalSwapWith(right.getBaseline(), swap);

        left.assertEqual();
        right.assertEqual();

    }

    // Request arithmetic that should overflow, and ensure that overflow is
    // detected.
    static void runOverflowTest(TestPair<IntegerModuloP> elem) {

        TestPair<MutableIntegerModuloP> mutableElem = elem.mutable();

        try {
            for (int i = 0; i < 1000; i++) {
                applyAndCheck(MutableIntegerModuloP::setSum, mutableElem, elem);
            }
            applyAndCheck(MutableIntegerModuloP::setProduct, mutableElem, elem);
        } catch (ArithmeticException ex) {
            // this is expected
        }

        mutableElem = elem.mutable();
        try {
            for (int i = 0; i < 1000; i++) {
                elem = applyAndCheck(IntegerModuloP::add,
                    mutableElem, elem);
            }
            applyAndCheck(IntegerModuloP::multiply, mutableElem, elem);
        } catch (ArithmeticException ex) {
            // this is expected
        }
    }

    // Run a large number of random operations and ensure that
    // results are correct
    static void runOperationsTest(Random random, int length,
                                  TestPair<IntegerModuloP> elem,
                                  TestPair<IntegerModuloP> right) {

        TestPair<MutableIntegerModuloP> left = elem.mutable();

        for (int i = 0; i < 10000; i++) {

            ElemFunction addFunc1 =
                ADD_FUNCTIONS.get(random.nextInt(ADD_FUNCTIONS.size()));
            TestPair<MutableIntegerModuloP> result1 =
                applyAndCheckMutable(addFunc1, left, right);

            // left could have been modified, so turn it back into a summand
            applyAndCheckMutable((a, b) -> a.setSquare(), left, right);

            ElemFunction addFunc2 =
                ADD_FUNCTIONS.get(random.nextInt(ADD_FUNCTIONS.size()));
            TestPair<IntegerModuloP> result2 =
                applyAndCheck(addFunc2, left, right);

            if (elem.test.getField() instanceof IntegerPolynomial) {
                IntegerPolynomial field =
                    (IntegerPolynomial) elem.test.getField();
                int numAdds = 10;   // check for addition overflow
                for (int j = 1; j < numAdds; j++) {
                    ElemFunction addFunc3 = ADD_FUNCTIONS.
                        get(random.nextInt(ADD_FUNCTIONS.size()));
                    result2 = applyAndCheck(addFunc3, left, right);
                }
            }

            ElemFunction multFunc2 =
                MULT_FUNCTIONS.get(random.nextInt(MULT_FUNCTIONS.size()));
            TestPair<MutableIntegerModuloP> multResult =
                applyAndCheckMutable(multFunc2, result1, result2);

            int swap = random.nextInt(2);
            cswapAndCheck(swap, left, multResult);

            ElemSetFunction setFunc =
                SET_FUNCTIONS.get(random.nextInt(SET_FUNCTIONS.size()));
            byte[] valueArr = new byte[2 * length];
            random.nextBytes(valueArr);
            setAndCheck(setFunc, result1, result2, valueArr);

            // left could have been modified, so to turn it back into a summand
            applyAndCheckMutable((a, b) -> a.setSquare(), left, right);

            ElemArrayFunction arrayFunc =
                ARRAY_FUNCTIONS.get(random.nextInt(ARRAY_FUNCTIONS.size()));
            left.applyAndCheckArray(arrayFunc, right);
        }
    }

    // Run all the tests for a given field
    static void runFieldTest(IntegerFieldModuloP testField,
                             int length, int seed) {
        System.out.println("Testing: " + testField.getClass().getSimpleName());

        Random random = new Random(seed);

        IntegerFieldModuloP baselineField =
            new BigIntegerModuloP(testField.getSize());

        int numBits = testField.getSize().bitLength();
        BigInteger r =
            new BigInteger(numBits, random).mod(testField.getSize());
        TestPair<IntegerModuloP> rand =
            new TestPair(testField.getElement(r), baselineField.getElement(r));

        runOverflowTest(rand);

        // check combinations of operations for different kinds of elements
        List<TestPair<IntegerModuloP>> testElements = new ArrayList<>();
        testElements.add(rand);
        testElements.add(new TestPair(testField.get0(), baselineField.get0()));
        testElements.add(new TestPair(testField.get1(), baselineField.get1()));
        byte[] testArr = {121, 37, -100, -5, 76, 33};
        testElements.add(new TestPair(testField.getElement(testArr),
            baselineField.getElement(testArr)));

        testArr = new byte[length];
        random.nextBytes(testArr);
        testElements.add(new TestPair(testField.getElement(testArr),
            baselineField.getElement(testArr)));

        random.nextBytes(testArr);
        byte highByte = (byte) (numBits > length * 8 ? 1 : 0);
        testElements.add(
            new TestPair(
                testField.getElement(testArr, 0, testArr.length, highByte),
                baselineField.getElement(testArr, 0, testArr.length, highByte)
            )
        );

        for (int i = 0; i < testElements.size(); i++) {
            for (int j = 0; j < testElements.size(); j++) {
                runOperationsTest(random, length, testElements.get(i),
                    testElements.get(j));
            }
        }
    }
}

