/* crypto/ec/ec2_mult.c */
/* ====================================================================
 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
 *
 * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
 * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
 * to the OpenSSL project.
 *
 * The ECC Code is licensed pursuant to the OpenSSL open source
 * license provided below.
 *
 * The software is originally written by Sheueling Chang Shantz and
 * Douglas Stebila of Sun Microsystems Laboratories.
 *
 */
/* ====================================================================
 * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
 *
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 *    endorse or promote products derived from this software without
 *    prior written permission. For written permission, please contact
 *    openssl-core@openssl.org.
 *
 * 5. Products derived from this software may not be called "OpenSSL"
 *    nor may "OpenSSL" appear in their names without prior written
 *    permission of the OpenSSL Project.
 *
 * 6. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by the OpenSSL Project
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
 *
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 * ====================================================================
 *
 * This product includes cryptographic software written by Eric Young
 * (eay@cryptsoft.com).  This product includes software written by Tim
 * Hudson (tjh@cryptsoft.com).
 *
 */

#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;
    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;

    bn_wexpand(x1, bn_get_top(group->field));
    bn_wexpand(z1, bn_get_top(group->field));
    bn_wexpand(x2, bn_get_top(group->field));
    bn_wexpand(z2, bn_get_top(group->field));

    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, bn_get_top(group->field));
            BN_consttime_swap(word & mask, z1, z2, bn_get_top(group->field));
            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, bn_get_top(group->field));
            BN_consttime_swap(word & mask, z1, z2, bn_get_top(group->field));
            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
