/*
 * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved.
 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <openssl/err.h>

#include "internal/bn_int.h"
#include "ec_lcl.h"

#ifndef OPENSSL_NO_EC2M

/*-
 * Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery projective
 * coordinates.
 * Uses algorithm Mdouble in appendix of
 *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over
 *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
 * modified to not require precomputation of c=b^{2^{m-1}}.
 */
static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z,
                        BN_CTX *ctx)
{
    BIGNUM *t1;
    int ret = 0;

    /* Since Mdouble is static we can guarantee that ctx != NULL. */
    BN_CTX_start(ctx);
    t1 = BN_CTX_get(ctx);
    if (t1 == NULL)
        goto err;

    if (!group->meth->field_sqr(group, x, x, ctx))
        goto err;
    if (!group->meth->field_sqr(group, t1, z, ctx))
        goto err;
    if (!group->meth->field_mul(group, z, x, t1, ctx))
        goto err;
    if (!group->meth->field_sqr(group, x, x, ctx))
        goto err;
    if (!group->meth->field_sqr(group, t1, t1, ctx))
        goto err;
    if (!group->meth->field_mul(group, t1, group->b, t1, ctx))
        goto err;
    if (!BN_GF2m_add(x, x, t1))
        goto err;

    ret = 1;

 err:
    BN_CTX_end(ctx);
    return ret;
}

/*-
 * Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery
 * projective coordinates.
 * Uses algorithm Madd in appendix of
 *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over
 *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
 */
static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1,
                     BIGNUM *z1, const BIGNUM *x2, const BIGNUM *z2,
                     BN_CTX *ctx)
{
    BIGNUM *t1, *t2;
    int ret = 0;

    /* Since Madd is static we can guarantee that ctx != NULL. */
    BN_CTX_start(ctx);
    t1 = BN_CTX_get(ctx);
    t2 = BN_CTX_get(ctx);
    if (t2 == NULL)
        goto err;

    if (!BN_copy(t1, x))
        goto err;
    if (!group->meth->field_mul(group, x1, x1, z2, ctx))
        goto err;
    if (!group->meth->field_mul(group, z1, z1, x2, ctx))
        goto err;
    if (!group->meth->field_mul(group, t2, x1, z1, ctx))
        goto err;
    if (!BN_GF2m_add(z1, z1, x1))
        goto err;
    if (!group->meth->field_sqr(group, z1, z1, ctx))
        goto err;
    if (!group->meth->field_mul(group, x1, z1, t1, ctx))
        goto err;
    if (!BN_GF2m_add(x1, x1, t2))
        goto err;

    ret = 1;

 err:
    BN_CTX_end(ctx);
    return ret;
}

/*-
 * Compute the x, y affine coordinates from the point (x1, z1) (x2, z2)
 * using Montgomery point multiplication algorithm Mxy() in appendix of
 *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over
 *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
 * Returns:
 *     0 on error
 *     1 if return value should be the point at infinity
 *     2 otherwise
 */
static int gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y,
                    BIGNUM *x1, BIGNUM *z1, BIGNUM *x2, BIGNUM *z2,
                    BN_CTX *ctx)
{
    BIGNUM *t3, *t4, *t5;
    int ret = 0;

    if (BN_is_zero(z1)) {
        BN_zero(x2);
        BN_zero(z2);
        return 1;
    }

    if (BN_is_zero(z2)) {
        if (!BN_copy(x2, x))
            return 0;
        if (!BN_GF2m_add(z2, x, y))
            return 0;
        return 2;
    }

    /* Since Mxy is static we can guarantee that ctx != NULL. */
    BN_CTX_start(ctx);
    t3 = BN_CTX_get(ctx);
    t4 = BN_CTX_get(ctx);
    t5 = BN_CTX_get(ctx);
    if (t5 == NULL)
        goto err;

    if (!BN_one(t5))
        goto err;

    if (!group->meth->field_mul(group, t3, z1, z2, ctx))
        goto err;

    if (!group->meth->field_mul(group, z1, z1, x, ctx))
        goto err;
    if (!BN_GF2m_add(z1, z1, x1))
        goto err;
    if (!group->meth->field_mul(group, z2, z2, x, ctx))
        goto err;
    if (!group->meth->field_mul(group, x1, z2, x1, ctx))
        goto err;
    if (!BN_GF2m_add(z2, z2, x2))
        goto err;

    if (!group->meth->field_mul(group, z2, z2, z1, ctx))
        goto err;
    if (!group->meth->field_sqr(group, t4, x, ctx))
        goto err;
    if (!BN_GF2m_add(t4, t4, y))
        goto err;
    if (!group->meth->field_mul(group, t4, t4, t3, ctx))
        goto err;
    if (!BN_GF2m_add(t4, t4, z2))
        goto err;

    if (!group->meth->field_mul(group, t3, t3, x, ctx))
        goto err;
    if (!group->meth->field_div(group, t3, t5, t3, ctx))
        goto err;
    if (!group->meth->field_mul(group, t4, t3, t4, ctx))
        goto err;
    if (!group->meth->field_mul(group, x2, x1, t3, ctx))
        goto err;
    if (!BN_GF2m_add(z2, x2, x))
        goto err;

    if (!group->meth->field_mul(group, z2, z2, t4, ctx))
        goto err;
    if (!BN_GF2m_add(z2, z2, y))
        goto err;

    ret = 2;

 err:
    BN_CTX_end(ctx);
    return ret;
}

/*-
 * Computes scalar*point and stores the result in r.
 * point can not equal r.
 * Uses a modified algorithm 2P of
 *     Lopez, J. and Dahab, R.  "Fast multiplication on elliptic curves over
 *     GF(2^m) without precomputation" (CHES '99, LNCS 1717).
 *
 * To protect against side-channel attack the function uses constant time swap,
 * avoiding conditional branches.
 */
static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group,
                                             EC_POINT *r,
                                             const BIGNUM *scalar,
                                             const EC_POINT *point,
                                             BN_CTX *ctx)
{
    BIGNUM *x1, *x2, *z1, *z2;
    int ret = 0, i, group_top;
    BN_ULONG mask, word;

    if (r == point) {
        ECerr(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, EC_R_INVALID_ARGUMENT);
        return 0;
    }

    /* if result should be point at infinity */
    if ((scalar == NULL) || BN_is_zero(scalar) || (point == NULL) ||
        EC_POINT_is_at_infinity(group, point)) {
        return EC_POINT_set_to_infinity(group, r);
    }

    /* only support affine coordinates */
    if (!point->Z_is_one)
        return 0;

    /*
     * Since point_multiply is static we can guarantee that ctx != NULL.
     */
    BN_CTX_start(ctx);
    x1 = BN_CTX_get(ctx);
    z1 = BN_CTX_get(ctx);
    if (z1 == NULL)
        goto err;

    x2 = r->X;
    z2 = r->Y;

    group_top = bn_get_top(group->field);
    if (bn_wexpand(x1, group_top) == NULL
        || bn_wexpand(z1, group_top) == NULL
        || bn_wexpand(x2, group_top) == NULL
        || bn_wexpand(z2, group_top) == NULL)
        goto err;

    if (!BN_GF2m_mod_arr(x1, point->X, group->poly))
        goto err;               /* x1 = x */
    if (!BN_one(z1))
        goto err;               /* z1 = 1 */
    if (!group->meth->field_sqr(group, z2, x1, ctx))
        goto err;               /* z2 = x1^2 = x^2 */
    if (!group->meth->field_sqr(group, x2, z2, ctx))
        goto err;
    if (!BN_GF2m_add(x2, x2, group->b))
        goto err;               /* x2 = x^4 + b */

    /* find top most bit and go one past it */
    i = bn_get_top(scalar) - 1;
    mask = BN_TBIT;
    word = bn_get_words(scalar)[i];
    while (!(word & mask))
        mask >>= 1;
    mask >>= 1;
    /* if top most bit was at word break, go to next word */
    if (!mask) {
        i--;
        mask = BN_TBIT;
    }

    for (; i >= 0; i--) {
        word = bn_get_words(scalar)[i];
        while (mask) {
            BN_consttime_swap(word & mask, x1, x2, group_top);
            BN_consttime_swap(word & mask, z1, z2, group_top);
            if (!gf2m_Madd(group, point->X, x2, z2, x1, z1, ctx))
                goto err;
            if (!gf2m_Mdouble(group, x1, z1, ctx))
                goto err;
            BN_consttime_swap(word & mask, x1, x2, group_top);
            BN_consttime_swap(word & mask, z1, z2, group_top);
            mask >>= 1;
        }
        mask = BN_TBIT;
    }

    /* convert out of "projective" coordinates */
    i = gf2m_Mxy(group, point->X, point->Y, x1, z1, x2, z2, ctx);
    if (i == 0)
        goto err;
    else if (i == 1) {
        if (!EC_POINT_set_to_infinity(group, r))
            goto err;
    } else {
        if (!BN_one(r->Z))
            goto err;
        r->Z_is_one = 1;
    }

    /* GF(2^m) field elements should always have BIGNUM::neg = 0 */
    BN_set_negative(r->X, 0);
    BN_set_negative(r->Y, 0);

    ret = 1;

 err:
    BN_CTX_end(ctx);
    return ret;
}

/*-
 * Computes the sum
 *     scalar*group->generator + scalars[0]*points[0] + ... + scalars[num-1]*points[num-1]
 * gracefully ignoring NULL scalar values.
 */
int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r,
                       const BIGNUM *scalar, size_t num,
                       const EC_POINT *points[], const BIGNUM *scalars[],
                       BN_CTX *ctx)
{
    BN_CTX *new_ctx = NULL;
    int ret = 0;
    size_t i;
    EC_POINT *p = NULL;
    EC_POINT *acc = NULL;

    if (ctx == NULL) {
        ctx = new_ctx = BN_CTX_new();
        if (ctx == NULL)
            return 0;
    }

    /*
     * This implementation is more efficient than the wNAF implementation for
     * 2 or fewer points.  Use the ec_wNAF_mul implementation for 3 or more
     * points, or if we can perform a fast multiplication based on
     * precomputation.
     */
    if ((scalar && (num > 1)) || (num > 2)
        || (num == 0 && EC_GROUP_have_precompute_mult(group))) {
        ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
        goto err;
    }

    if ((p = EC_POINT_new(group)) == NULL)
        goto err;
    if ((acc = EC_POINT_new(group)) == NULL)
        goto err;

    if (!EC_POINT_set_to_infinity(group, acc))
        goto err;

    if (scalar) {
        if (!ec_GF2m_montgomery_point_multiply
            (group, p, scalar, group->generator, ctx))
            goto err;
        if (BN_is_negative(scalar))
            if (!group->meth->invert(group, p, ctx))
                goto err;
        if (!group->meth->add(group, acc, acc, p, ctx))
            goto err;
    }

    for (i = 0; i < num; i++) {
        if (!ec_GF2m_montgomery_point_multiply
            (group, p, scalars[i], points[i], ctx))
            goto err;
        if (BN_is_negative(scalars[i]))
            if (!group->meth->invert(group, p, ctx))
                goto err;
        if (!group->meth->add(group, acc, acc, p, ctx))
            goto err;
    }

    if (!EC_POINT_copy(r, acc))
        goto err;

    ret = 1;

 err:
    EC_POINT_free(p);
    EC_POINT_free(acc);
    BN_CTX_free(new_ctx);
    return ret;
}

/*
 * Precomputation for point multiplication: fall back to wNAF methods because
 * ec_GF2m_simple_mul() uses ec_wNAF_mul() if appropriate
 */

int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
{
    return ec_wNAF_precompute_mult(group, ctx);
}

int ec_GF2m_have_precompute_mult(const EC_GROUP *group)
{
    return ec_wNAF_have_precompute_mult(group);
}

#endif
