/*
 * Copyright (c) 2018, 2019, 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * 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.
 */

package sun.security.ec;

import java.io.IOException;
import java.math.BigInteger;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.NamedParameterSpec;
import java.util.Collections;
import java.util.Map;
import java.util.HashMap;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;

import sun.security.util.ObjectIdentifier;
import sun.security.x509.AlgorithmId;

public class XECParameters {

    // Naming/identification parameters
    private final ObjectIdentifier oid;
    private final String name;

    // Curve/field parameters
    private final int bits;
    private final BigInteger p;
    private final int logCofactor;
    private final int a24;
    private final byte basePoint;

    /**
     *
     * Construct an object holding the supplied parameters. No parameters are
     * checked, so this method always succeeds. This method supports
     * Montgomery curves of the form y^2 = x^3 + ax^2 + x.
     *
     * @param bits The number of relevant bits in a public/private key.
     * @param p The prime that defines the finite field.
     * @param a24 The value of (a - 2) / 4, where a is the second-degree curve
     *            coefficient.
     * @param basePoint The point that generates the desired group
     * @param logCofactor The base-2 logarithm of the cofactor of the curve
     * @param oid
     * @param name
     */
    public XECParameters(int bits, BigInteger p, int a24,
                         byte basePoint, int logCofactor,
                         ObjectIdentifier oid, String name) {

        this.bits = bits;
        this.logCofactor = logCofactor;
        this.p = p;
        this.a24 = a24;
        this.basePoint = basePoint;
        this.oid = oid;
        this.name = name;

    }

    public int getBits() {
        return bits;
    }
    public int getBytes() {
        return (bits + 7) / 8;
    }
    public int getLogCofactor() {
        return logCofactor;
    }
    public BigInteger getP() {
        return p;
    }
    public int getA24() {
        return a24;
    }
    public byte getBasePoint() {
        return basePoint;
    }
    public ObjectIdentifier getOid() {
        return oid;
    }
    public String getName() {
        return name;
    }

    private static final Map<Integer, XECParameters> SIZE_MAP;
    private static final Map<ObjectIdentifier, XECParameters> OID_MAP;
    private static final Map<String, XECParameters> NAME_MAP;

    static {
        final BigInteger TWO = BigInteger.valueOf(2);

        Map<Integer, XECParameters> bySize = new HashMap<>();
        Map<ObjectIdentifier, XECParameters> byOid = new HashMap<>();
        Map<String, XECParameters> byName = new HashMap<>();

        // set up X25519
        try {
            BigInteger p = TWO.pow(255).subtract(BigInteger.valueOf(19));
            addParameters(255, p, 121665, (byte) 0x09, 3,
                new int[]{1, 3, 101, 110}, NamedParameterSpec.X25519.getName(),
                bySize, byOid, byName);

        } catch (IOException ex) {
            // Unable to set X25519 parameters---it will be disabled
        }

        // set up X448
        try {
            BigInteger p = TWO.pow(448).subtract(TWO.pow(224))
                .subtract(BigInteger.ONE);
            addParameters(448, p, 39081, (byte) 0x05, 2,
                new int[]{1, 3, 101, 111}, NamedParameterSpec.X448.getName(),
                bySize, byOid, byName);

        } catch (IOException ex) {
            // Unable to set X448 parameters---it will be disabled
        }

        SIZE_MAP = Collections.unmodifiableMap(bySize);
        OID_MAP = Collections.unmodifiableMap(byOid);
        NAME_MAP = Collections.unmodifiableMap(byName);
    }

    private static void addParameters(int bits, BigInteger p, int a24,
        byte basePoint, int logCofactor, int[] oidBytes, String name,
        Map<Integer, XECParameters> bySize,
        Map<ObjectIdentifier, XECParameters> byOid,
        Map<String, XECParameters> byName) throws IOException {

        ObjectIdentifier oid = new ObjectIdentifier(oidBytes);
        XECParameters params =
            new XECParameters(bits, p, a24, basePoint, logCofactor, oid, name);
        bySize.put(bits, params);
        byOid.put(oid, params);
        byName.put(name.toLowerCase(), params);
    }

    public static Optional<XECParameters> getByOid(ObjectIdentifier id) {
        return Optional.ofNullable(OID_MAP.get(id));
    }
    public static Optional<XECParameters> getBySize(int size) {
        return Optional.ofNullable(SIZE_MAP.get(size));
    }
    public static Optional<XECParameters> getByName(String name) {
        return Optional.ofNullable(NAME_MAP.get(name.toLowerCase()));
    }

    boolean oidEquals(XECParameters other) {
        return oid.equals(other.getOid());
    }

    // Utility method that is used by the methods below to handle exception
    // suppliers
    private static
    <A, B> Supplier<B> apply(final Function<A, B> func, final A a) {
        return new Supplier<B>() {
            @Override
            public B get() {
                return func.apply(a);
            }
        };
    }

    /**
     * Get parameters by key size, or throw an exception if no parameters are
     * defined for the specified key size. This method is used in several
     * contexts that should throw different exceptions when the parameters
     * are not found. The first argument is a function that produces the
     * desired exception.
     *
     * @param exception a function that produces an exception from a string
     * @param size the desired key size
     * @param <T> the type of exception that is thrown
     * @return the parameters for the specified key size
     * @throws T when suitable parameters do not exist
     */
    public static
    <T extends Throwable>
    XECParameters getBySize(Function<String, T> exception,
                            int size) throws T {

        Optional<XECParameters> xecParams = getBySize(size);
        return xecParams.orElseThrow(
            apply(exception, "Unsupported size: " + size));
    }

    /**
     * Get parameters by algorithm ID, or throw an exception if no
     * parameters are defined for the specified ID. This method is used in
     * several contexts that should throw different exceptions when the
     * parameters are not found. The first argument is a function that produces
     * the desired exception.
     *
     * @param exception a function that produces an exception from a string
     * @param algId the algorithm ID
     * @param <T> the type of exception that is thrown
     * @return the parameters for the specified algorithm ID
     * @throws T when suitable parameters do not exist
     */
    public static
    <T extends Throwable>
    XECParameters get(Function<String, T> exception,
                      AlgorithmId algId) throws T {

        Optional<XECParameters> xecParams = getByOid(algId.getOID());
        return xecParams.orElseThrow(
            apply(exception, "Unsupported OID: " + algId.getOID()));
    }

    /**
     * Get parameters by algorithm parameter spec, or throw an exception if no
     * parameters are defined for the spec. This method is used in
     * several contexts that should throw different exceptions when the
     * parameters are not found. The first argument is a function that produces
     * the desired exception.
     *
     * @param exception a function that produces an exception from a string
     * @param params the algorithm parameters spec
     * @param <T> the type of exception that is thrown
     * @return the parameters for the spec
     * @throws T when suitable parameters do not exist
     */
    public static
    <T extends Throwable>
    XECParameters get(Function<String, T> exception,
                      AlgorithmParameterSpec params) throws T {

        if (params instanceof NamedParameterSpec) {
            NamedParameterSpec namedParams = (NamedParameterSpec) params;
            Optional<XECParameters> xecParams =
                getByName(namedParams.getName());
            return xecParams.orElseThrow(
                apply(exception, "Unsupported name: " + namedParams.getName()));
        } else {
            throw exception.apply("Only NamedParameterSpec is supported.");
        }
    }
}

