/* Originally written by Bodo Moeller for the OpenSSL project.
 * ====================================================================
 * Copyright (c) 1998-2005 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).
 *
 */
/* ====================================================================
 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
 *
 * Portions of the attached software ("Contribution") are developed by
 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
 *
 * The Contribution is licensed pursuant to the OpenSSL open source
 * license provided above.
 *
 * The elliptic curve binary polynomial software is originally written by
 * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
 * Laboratories. */

#include <openssl/ec.h>

#include <string.h>

#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/mem.h>

#include "internal.h"


/* Most method functions in this file are designed to work with non-trivial
 * representations of field elements if necessary (see ecp_mont.c): while
 * standard modular addition and subtraction are used, the field_mul and
 * field_sqr methods will be used for multiplication, and field_encode and
 * field_decode (if defined) will be used for converting between
 * representations.

 * Functions ec_GFp_simple_points_make_affine() and
 * ec_GFp_simple_point_get_affine_coordinates() specifically assume that if a
 * non-trivial representation is used, it is a Montgomery representation (i.e.
 * 'encoding' means multiplying by some factor R). */

int ec_GFp_simple_group_init(EC_GROUP *group) {
  BN_init(&group->field);
  BN_init(&group->a);
  BN_init(&group->b);
  BN_init(&group->one);
  group->a_is_minus3 = 0;
  return 1;
}

void ec_GFp_simple_group_finish(EC_GROUP *group) {
  BN_free(&group->field);
  BN_free(&group->a);
  BN_free(&group->b);
  BN_free(&group->one);
}

int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
  if (!BN_copy(&dest->field, &src->field) ||
      !BN_copy(&dest->a, &src->a) ||
      !BN_copy(&dest->b, &src->b) ||
      !BN_copy(&dest->one, &src->one)) {
    return 0;
  }

  dest->a_is_minus3 = src->a_is_minus3;
  return 1;
}

int ec_GFp_simple_group_set_curve(EC_GROUP *group, const BIGNUM *p,
                                  const BIGNUM *a, const BIGNUM *b,
                                  BN_CTX *ctx) {
  int ret = 0;
  BN_CTX *new_ctx = NULL;
  BIGNUM *tmp_a;

  /* p must be a prime > 3 */
  if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) {
    OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD);
    return 0;
  }

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

  BN_CTX_start(ctx);
  tmp_a = BN_CTX_get(ctx);
  if (tmp_a == NULL) {
    goto err;
  }

  /* group->field */
  if (!BN_copy(&group->field, p)) {
    goto err;
  }
  BN_set_negative(&group->field, 0);

  /* group->a */
  if (!BN_nnmod(tmp_a, a, p, ctx)) {
    goto err;
  }
  if (group->meth->field_encode) {
    if (!group->meth->field_encode(group, &group->a, tmp_a, ctx)) {
      goto err;
    }
  } else if (!BN_copy(&group->a, tmp_a)) {
    goto err;
  }

  /* group->b */
  if (!BN_nnmod(&group->b, b, p, ctx)) {
    goto err;
  }
  if (group->meth->field_encode &&
      !group->meth->field_encode(group, &group->b, &group->b, ctx)) {
    goto err;
  }

  /* group->a_is_minus3 */
  if (!BN_add_word(tmp_a, 3)) {
    goto err;
  }
  group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field));

  if (group->meth->field_encode != NULL) {
    if (!group->meth->field_encode(group, &group->one, BN_value_one(), ctx)) {
      goto err;
    }
  } else if (!BN_copy(&group->one, BN_value_one())) {
    goto err;
  }

  ret = 1;

err:
  BN_CTX_end(ctx);
  BN_CTX_free(new_ctx);
  return ret;
}

int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
                                  BIGNUM *b, BN_CTX *ctx) {
  int ret = 0;
  BN_CTX *new_ctx = NULL;

  if (p != NULL && !BN_copy(p, &group->field)) {
    return 0;
  }

  if (a != NULL || b != NULL) {
    if (group->meth->field_decode) {
      if (ctx == NULL) {
        ctx = new_ctx = BN_CTX_new();
        if (ctx == NULL) {
          return 0;
        }
      }
      if (a != NULL && !group->meth->field_decode(group, a, &group->a, ctx)) {
        goto err;
      }
      if (b != NULL && !group->meth->field_decode(group, b, &group->b, ctx)) {
        goto err;
      }
    } else {
      if (a != NULL && !BN_copy(a, &group->a)) {
        goto err;
      }
      if (b != NULL && !BN_copy(b, &group->b)) {
        goto err;
      }
    }
  }

  ret = 1;

err:
  BN_CTX_free(new_ctx);
  return ret;
}

unsigned ec_GFp_simple_group_get_degree(const EC_GROUP *group) {
  return BN_num_bits(&group->field);
}

int ec_GFp_simple_point_init(EC_POINT *point) {
  BN_init(&point->X);
  BN_init(&point->Y);
  BN_init(&point->Z);

  return 1;
}

void ec_GFp_simple_point_finish(EC_POINT *point) {
  BN_free(&point->X);
  BN_free(&point->Y);
  BN_free(&point->Z);
}

void ec_GFp_simple_point_clear_finish(EC_POINT *point) {
  BN_clear_free(&point->X);
  BN_clear_free(&point->Y);
  BN_clear_free(&point->Z);
}

int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src) {
  if (!BN_copy(&dest->X, &src->X) ||
      !BN_copy(&dest->Y, &src->Y) ||
      !BN_copy(&dest->Z, &src->Z)) {
    return 0;
  }

  return 1;
}

int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group,
                                        EC_POINT *point) {
  BN_zero(&point->Z);
  return 1;
}

static int set_Jprojective_coordinate_GFp(const EC_GROUP *group, BIGNUM *out,
                                          const BIGNUM *in, BN_CTX *ctx) {
  if (in == NULL) {
    return 1;
  }
  if (BN_is_negative(in) ||
      BN_cmp(in, &group->field) >= 0) {
    OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE);
    return 0;
  }
  if (group->meth->field_encode) {
    return group->meth->field_encode(group, out, in, ctx);
  }
  return BN_copy(out, in) != NULL;
}

int ec_GFp_simple_set_Jprojective_coordinates_GFp(
    const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, const BIGNUM *y,
    const BIGNUM *z, BN_CTX *ctx) {
  BN_CTX *new_ctx = NULL;
  int ret = 0;

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

  if (!set_Jprojective_coordinate_GFp(group, &point->X, x, ctx) ||
      !set_Jprojective_coordinate_GFp(group, &point->Y, y, ctx) ||
      !set_Jprojective_coordinate_GFp(group, &point->Z, z, ctx)) {
    goto err;
  }

  ret = 1;

err:
  BN_CTX_free(new_ctx);
  return ret;
}

int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
                                                  const EC_POINT *point,
                                                  BIGNUM *x, BIGNUM *y,
                                                  BIGNUM *z, BN_CTX *ctx) {
  BN_CTX *new_ctx = NULL;
  int ret = 0;

  if (group->meth->field_decode != 0) {
    if (ctx == NULL) {
      ctx = new_ctx = BN_CTX_new();
      if (ctx == NULL) {
        return 0;
      }
    }

    if (x != NULL && !group->meth->field_decode(group, x, &point->X, ctx)) {
      goto err;
    }
    if (y != NULL && !group->meth->field_decode(group, y, &point->Y, ctx)) {
      goto err;
    }
    if (z != NULL && !group->meth->field_decode(group, z, &point->Z, ctx)) {
      goto err;
    }
  } else {
    if (x != NULL && !BN_copy(x, &point->X)) {
      goto err;
    }
    if (y != NULL && !BN_copy(y, &point->Y)) {
      goto err;
    }
    if (z != NULL && !BN_copy(z, &point->Z)) {
      goto err;
    }
  }

  ret = 1;

err:
  BN_CTX_free(new_ctx);
  return ret;
}

int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group,
                                               EC_POINT *point, const BIGNUM *x,
                                               const BIGNUM *y, BN_CTX *ctx) {
  if (x == NULL || y == NULL) {
    /* unlike for projective coordinates, we do not tolerate this */
    OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
    return 0;
  }

  return ec_point_set_Jprojective_coordinates_GFp(group, point, x, y,
                                                  BN_value_one(), ctx);
}

int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group,
                                               const EC_POINT *point, BIGNUM *x,
                                               BIGNUM *y, BN_CTX *ctx) {
  BN_CTX *new_ctx = NULL;
  BIGNUM *Z, *Z_1, *Z_2, *Z_3;
  const BIGNUM *Z_;
  int ret = 0;

  if (EC_POINT_is_at_infinity(group, point)) {
    OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
    return 0;
  }

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

  BN_CTX_start(ctx);
  Z = BN_CTX_get(ctx);
  Z_1 = BN_CTX_get(ctx);
  Z_2 = BN_CTX_get(ctx);
  Z_3 = BN_CTX_get(ctx);
  if (Z == NULL || Z_1 == NULL || Z_2 == NULL || Z_3 == NULL) {
    goto err;
  }

  /* transform  (X, Y, Z)  into  (x, y) := (X/Z^2, Y/Z^3) */

  if (group->meth->field_decode) {
    if (!group->meth->field_decode(group, Z, &point->Z, ctx)) {
      goto err;
    }
    Z_ = Z;
  } else {
    Z_ = &point->Z;
  }

  if (BN_is_one(Z_)) {
    if (group->meth->field_decode) {
      if (x != NULL && !group->meth->field_decode(group, x, &point->X, ctx)) {
        goto err;
      }
      if (y != NULL && !group->meth->field_decode(group, y, &point->Y, ctx)) {
        goto err;
      }
    } else {
      if (x != NULL && !BN_copy(x, &point->X)) {
        goto err;
      }
      if (y != NULL && !BN_copy(y, &point->Y)) {
        goto err;
      }
    }
  } else {
    if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx)) {
      OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
      goto err;
    }

    if (group->meth->field_encode == 0) {
      /* field_sqr works on standard representation */
      if (!group->meth->field_sqr(group, Z_2, Z_1, ctx)) {
        goto err;
      }
    } else if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx)) {
      goto err;
    }

    /* in the Montgomery case, field_mul will cancel out Montgomery factor in
     * X: */
    if (x != NULL && !group->meth->field_mul(group, x, &point->X, Z_2, ctx)) {
      goto err;
    }

    if (y != NULL) {
      if (group->meth->field_encode == 0) {
        /* field_mul works on standard representation */
        if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) {
          goto err;
        }
      } else if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) {
        goto err;
      }

      /* in the Montgomery case, field_mul will cancel out Montgomery factor in
       * Y: */
      if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx)) {
        goto err;
      }
    }
  }

  ret = 1;

err:
  BN_CTX_end(ctx);
  BN_CTX_free(new_ctx);
  return ret;
}

int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
                      const EC_POINT *b, BN_CTX *ctx) {
  int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *,
                   BN_CTX *);
  int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
  const BIGNUM *p;
  BN_CTX *new_ctx = NULL;
  BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
  int ret = 0;

  if (a == b) {
    return EC_POINT_dbl(group, r, a, ctx);
  }
  if (EC_POINT_is_at_infinity(group, a)) {
    return EC_POINT_copy(r, b);
  }
  if (EC_POINT_is_at_infinity(group, b)) {
    return EC_POINT_copy(r, a);
  }

  field_mul = group->meth->field_mul;
  field_sqr = group->meth->field_sqr;
  p = &group->field;

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

  BN_CTX_start(ctx);
  n0 = BN_CTX_get(ctx);
  n1 = BN_CTX_get(ctx);
  n2 = BN_CTX_get(ctx);
  n3 = BN_CTX_get(ctx);
  n4 = BN_CTX_get(ctx);
  n5 = BN_CTX_get(ctx);
  n6 = BN_CTX_get(ctx);
  if (n6 == NULL) {
    goto end;
  }

  /* Note that in this function we must not read components of 'a' or 'b'
   * once we have written the corresponding components of 'r'.
   * ('r' might be one of 'a' or 'b'.)
   */

  /* n1, n2 */
  int b_Z_is_one = BN_cmp(&b->Z, &group->one) == 0;

  if (b_Z_is_one) {
    if (!BN_copy(n1, &a->X) || !BN_copy(n2, &a->Y)) {
      goto end;
    }
    /* n1 = X_a */
    /* n2 = Y_a */
  } else {
    if (!field_sqr(group, n0, &b->Z, ctx) ||
        !field_mul(group, n1, &a->X, n0, ctx)) {
      goto end;
    }
    /* n1 = X_a * Z_b^2 */

    if (!field_mul(group, n0, n0, &b->Z, ctx) ||
        !field_mul(group, n2, &a->Y, n0, ctx)) {
      goto end;
    }
    /* n2 = Y_a * Z_b^3 */
  }

  /* n3, n4 */
  int a_Z_is_one = BN_cmp(&a->Z, &group->one) == 0;
  if (a_Z_is_one) {
    if (!BN_copy(n3, &b->X) || !BN_copy(n4, &b->Y)) {
      goto end;
    }
    /* n3 = X_b */
    /* n4 = Y_b */
  } else {
    if (!field_sqr(group, n0, &a->Z, ctx) ||
        !field_mul(group, n3, &b->X, n0, ctx)) {
      goto end;
    }
    /* n3 = X_b * Z_a^2 */

    if (!field_mul(group, n0, n0, &a->Z, ctx) ||
        !field_mul(group, n4, &b->Y, n0, ctx)) {
      goto end;
    }
    /* n4 = Y_b * Z_a^3 */
  }

  /* n5, n6 */
  if (!BN_mod_sub_quick(n5, n1, n3, p) ||
      !BN_mod_sub_quick(n6, n2, n4, p)) {
    goto end;
  }
  /* n5 = n1 - n3 */
  /* n6 = n2 - n4 */

  if (BN_is_zero(n5)) {
    if (BN_is_zero(n6)) {
      /* a is the same point as b */
      BN_CTX_end(ctx);
      ret = EC_POINT_dbl(group, r, a, ctx);
      ctx = NULL;
      goto end;
    } else {
      /* a is the inverse of b */
      BN_zero(&r->Z);
      ret = 1;
      goto end;
    }
  }

  /* 'n7', 'n8' */
  if (!BN_mod_add_quick(n1, n1, n3, p) ||
      !BN_mod_add_quick(n2, n2, n4, p)) {
    goto end;
  }
  /* 'n7' = n1 + n3 */
  /* 'n8' = n2 + n4 */

  /* Z_r */
  if (a_Z_is_one && b_Z_is_one) {
    if (!BN_copy(&r->Z, n5)) {
      goto end;
    }
  } else {
    if (a_Z_is_one) {
      if (!BN_copy(n0, &b->Z)) {
        goto end;
      }
    } else if (b_Z_is_one) {
      if (!BN_copy(n0, &a->Z)) {
        goto end;
      }
    } else if (!field_mul(group, n0, &a->Z, &b->Z, ctx)) {
      goto end;
    }
    if (!field_mul(group, &r->Z, n0, n5, ctx)) {
      goto end;
    }
  }

  /* Z_r = Z_a * Z_b * n5 */

  /* X_r */
  if (!field_sqr(group, n0, n6, ctx) ||
      !field_sqr(group, n4, n5, ctx) ||
      !field_mul(group, n3, n1, n4, ctx) ||
      !BN_mod_sub_quick(&r->X, n0, n3, p)) {
    goto end;
  }
  /* X_r = n6^2 - n5^2 * 'n7' */

  /* 'n9' */
  if (!BN_mod_lshift1_quick(n0, &r->X, p) ||
      !BN_mod_sub_quick(n0, n3, n0, p)) {
    goto end;
  }
  /* n9 = n5^2 * 'n7' - 2 * X_r */

  /* Y_r */
  if (!field_mul(group, n0, n0, n6, ctx) ||
      !field_mul(group, n5, n4, n5, ctx)) {
    goto end; /* now n5 is n5^3 */
  }
  if (!field_mul(group, n1, n2, n5, ctx) ||
      !BN_mod_sub_quick(n0, n0, n1, p)) {
    goto end;
  }
  if (BN_is_odd(n0) && !BN_add(n0, n0, p)) {
    goto end;
  }
  /* now  0 <= n0 < 2*p,  and n0 is even */
  if (!BN_rshift1(&r->Y, n0)) {
    goto end;
  }
  /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */

  ret = 1;

end:
  if (ctx) {
    /* otherwise we already called BN_CTX_end */
    BN_CTX_end(ctx);
  }
  BN_CTX_free(new_ctx);
  return ret;
}

int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
                      BN_CTX *ctx) {
  int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *,
                   BN_CTX *);
  int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
  const BIGNUM *p;
  BN_CTX *new_ctx = NULL;
  BIGNUM *n0, *n1, *n2, *n3;
  int ret = 0;

  if (EC_POINT_is_at_infinity(group, a)) {
    BN_zero(&r->Z);
    return 1;
  }

  field_mul = group->meth->field_mul;
  field_sqr = group->meth->field_sqr;
  p = &group->field;

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

  BN_CTX_start(ctx);
  n0 = BN_CTX_get(ctx);
  n1 = BN_CTX_get(ctx);
  n2 = BN_CTX_get(ctx);
  n3 = BN_CTX_get(ctx);
  if (n3 == NULL) {
    goto err;
  }

  /* Note that in this function we must not read components of 'a'
   * once we have written the corresponding components of 'r'.
   * ('r' might the same as 'a'.)
   */

  /* n1 */
  if (BN_cmp(&a->Z, &group->one) == 0) {
    if (!field_sqr(group, n0, &a->X, ctx) ||
        !BN_mod_lshift1_quick(n1, n0, p) ||
        !BN_mod_add_quick(n0, n0, n1, p) ||
        !BN_mod_add_quick(n1, n0, &group->a, p)) {
      goto err;
    }
    /* n1 = 3 * X_a^2 + a_curve */
  } else if (group->a_is_minus3) {
    if (!field_sqr(group, n1, &a->Z, ctx) ||
        !BN_mod_add_quick(n0, &a->X, n1, p) ||
        !BN_mod_sub_quick(n2, &a->X, n1, p) ||
        !field_mul(group, n1, n0, n2, ctx) ||
        !BN_mod_lshift1_quick(n0, n1, p) ||
        !BN_mod_add_quick(n1, n0, n1, p)) {
      goto err;
    }
    /* n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2)
     *    = 3 * X_a^2 - 3 * Z_a^4 */
  } else {
    if (!field_sqr(group, n0, &a->X, ctx) ||
        !BN_mod_lshift1_quick(n1, n0, p) ||
        !BN_mod_add_quick(n0, n0, n1, p) ||
        !field_sqr(group, n1, &a->Z, ctx) ||
        !field_sqr(group, n1, n1, ctx) ||
        !field_mul(group, n1, n1, &group->a, ctx) ||
        !BN_mod_add_quick(n1, n1, n0, p)) {
      goto err;
    }
    /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */
  }

  /* Z_r */
  if (BN_cmp(&a->Z, &group->one) == 0) {
    if (!BN_copy(n0, &a->Y)) {
      goto err;
    }
  } else if (!field_mul(group, n0, &a->Y, &a->Z, ctx)) {
    goto err;
  }
  if (!BN_mod_lshift1_quick(&r->Z, n0, p)) {
    goto err;
  }
  /* Z_r = 2 * Y_a * Z_a */

  /* n2 */
  if (!field_sqr(group, n3, &a->Y, ctx) ||
      !field_mul(group, n2, &a->X, n3, ctx) ||
      !BN_mod_lshift_quick(n2, n2, 2, p)) {
    goto err;
  }
  /* n2 = 4 * X_a * Y_a^2 */

  /* X_r */
  if (!BN_mod_lshift1_quick(n0, n2, p) ||
      !field_sqr(group, &r->X, n1, ctx) ||
      !BN_mod_sub_quick(&r->X, &r->X, n0, p)) {
    goto err;
  }
  /* X_r = n1^2 - 2 * n2 */

  /* n3 */
  if (!field_sqr(group, n0, n3, ctx) ||
      !BN_mod_lshift_quick(n3, n0, 3, p)) {
    goto err;
  }
  /* n3 = 8 * Y_a^4 */

  /* Y_r */
  if (!BN_mod_sub_quick(n0, n2, &r->X, p) ||
      !field_mul(group, n0, n1, n0, ctx) ||
      !BN_mod_sub_quick(&r->Y, n0, n3, p)) {
    goto err;
  }
  /* Y_r = n1 * (n2 - X_r) - n3 */

  ret = 1;

err:
  BN_CTX_end(ctx);
  BN_CTX_free(new_ctx);
  return ret;
}

int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
  if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y)) {
    /* point is its own inverse */
    return 1;
  }

  return BN_usub(&point->Y, &group->field, &point->Y);
}

int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
  return BN_is_zero(&point->Z);
}

int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
                              BN_CTX *ctx) {
  int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *,
                   BN_CTX *);
  int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
  const BIGNUM *p;
  BN_CTX *new_ctx = NULL;
  BIGNUM *rh, *tmp, *Z4, *Z6;
  int ret = 0;

  if (EC_POINT_is_at_infinity(group, point)) {
    return 1;
  }

  field_mul = group->meth->field_mul;
  field_sqr = group->meth->field_sqr;
  p = &group->field;

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

  BN_CTX_start(ctx);
  rh = BN_CTX_get(ctx);
  tmp = BN_CTX_get(ctx);
  Z4 = BN_CTX_get(ctx);
  Z6 = BN_CTX_get(ctx);
  if (Z6 == NULL) {
    goto err;
  }

  /* We have a curve defined by a Weierstrass equation
   *      y^2 = x^3 + a*x + b.
   * The point to consider is given in Jacobian projective coordinates
   * where  (X, Y, Z)  represents  (x, y) = (X/Z^2, Y/Z^3).
   * Substituting this and multiplying by  Z^6  transforms the above equation
   * into
   *      Y^2 = X^3 + a*X*Z^4 + b*Z^6.
   * To test this, we add up the right-hand side in 'rh'.
   */

  /* rh := X^2 */
  if (!field_sqr(group, rh, &point->X, ctx)) {
    goto err;
  }

  if (BN_cmp(&point->Z, &group->one) != 0) {
    if (!field_sqr(group, tmp, &point->Z, ctx) ||
        !field_sqr(group, Z4, tmp, ctx) ||
        !field_mul(group, Z6, Z4, tmp, ctx)) {
      goto err;
    }

    /* rh := (rh + a*Z^4)*X */
    if (group->a_is_minus3) {
      if (!BN_mod_lshift1_quick(tmp, Z4, p) ||
          !BN_mod_add_quick(tmp, tmp, Z4, p) ||
          !BN_mod_sub_quick(rh, rh, tmp, p) ||
          !field_mul(group, rh, rh, &point->X, ctx)) {
        goto err;
      }
    } else {
      if (!field_mul(group, tmp, Z4, &group->a, ctx) ||
          !BN_mod_add_quick(rh, rh, tmp, p) ||
          !field_mul(group, rh, rh, &point->X, ctx)) {
        goto err;
      }
    }

    /* rh := rh + b*Z^6 */
    if (!field_mul(group, tmp, &group->b, Z6, ctx) ||
        !BN_mod_add_quick(rh, rh, tmp, p)) {
      goto err;
    }
  } else {
    /* rh := (rh + a)*X */
    if (!BN_mod_add_quick(rh, rh, &group->a, p) ||
        !field_mul(group, rh, rh, &point->X, ctx)) {
      goto err;
    }
    /* rh := rh + b */
    if (!BN_mod_add_quick(rh, rh, &group->b, p)) {
      goto err;
    }
  }

  /* 'lh' := Y^2 */
  if (!field_sqr(group, tmp, &point->Y, ctx)) {
    goto err;
  }

  ret = (0 == BN_ucmp(tmp, rh));

err:
  BN_CTX_end(ctx);
  BN_CTX_free(new_ctx);
  return ret;
}

int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
                      const EC_POINT *b, BN_CTX *ctx) {
  /* return values:
   *  -1   error
   *   0   equal (in affine coordinates)
   *   1   not equal
   */

  int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *,
                   BN_CTX *);
  int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
  BN_CTX *new_ctx = NULL;
  BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
  const BIGNUM *tmp1_, *tmp2_;
  int ret = -1;

  if (EC_POINT_is_at_infinity(group, a)) {
    return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
  }

  if (EC_POINT_is_at_infinity(group, b)) {
    return 1;
  }

  int a_Z_is_one = BN_cmp(&a->Z, &group->one) == 0;
  int b_Z_is_one = BN_cmp(&b->Z, &group->one) == 0;

  if (a_Z_is_one && b_Z_is_one) {
    return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
  }

  field_mul = group->meth->field_mul;
  field_sqr = group->meth->field_sqr;

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

  BN_CTX_start(ctx);
  tmp1 = BN_CTX_get(ctx);
  tmp2 = BN_CTX_get(ctx);
  Za23 = BN_CTX_get(ctx);
  Zb23 = BN_CTX_get(ctx);
  if (Zb23 == NULL) {
    goto end;
  }

  /* We have to decide whether
   *     (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3),
   * or equivalently, whether
   *     (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).
   */

  if (!b_Z_is_one) {
    if (!field_sqr(group, Zb23, &b->Z, ctx) ||
        !field_mul(group, tmp1, &a->X, Zb23, ctx)) {
      goto end;
    }
    tmp1_ = tmp1;
  } else {
    tmp1_ = &a->X;
  }
  if (!a_Z_is_one) {
    if (!field_sqr(group, Za23, &a->Z, ctx) ||
        !field_mul(group, tmp2, &b->X, Za23, ctx)) {
      goto end;
    }
    tmp2_ = tmp2;
  } else {
    tmp2_ = &b->X;
  }

  /* compare  X_a*Z_b^2  with  X_b*Z_a^2 */
  if (BN_cmp(tmp1_, tmp2_) != 0) {
    ret = 1; /* points differ */
    goto end;
  }


  if (!b_Z_is_one) {
    if (!field_mul(group, Zb23, Zb23, &b->Z, ctx) ||
        !field_mul(group, tmp1, &a->Y, Zb23, ctx)) {
      goto end;
    }
    /* tmp1_ = tmp1 */
  } else {
    tmp1_ = &a->Y;
  }
  if (!a_Z_is_one) {
    if (!field_mul(group, Za23, Za23, &a->Z, ctx) ||
        !field_mul(group, tmp2, &b->Y, Za23, ctx)) {
      goto end;
    }
    /* tmp2_ = tmp2 */
  } else {
    tmp2_ = &b->Y;
  }

  /* compare  Y_a*Z_b^3  with  Y_b*Z_a^3 */
  if (BN_cmp(tmp1_, tmp2_) != 0) {
    ret = 1; /* points differ */
    goto end;
  }

  /* points are equal */
  ret = 0;

end:
  BN_CTX_end(ctx);
  BN_CTX_free(new_ctx);
  return ret;
}

int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
                              BN_CTX *ctx) {
  BN_CTX *new_ctx = NULL;
  BIGNUM *x, *y;
  int ret = 0;

  if (BN_cmp(&point->Z, &group->one) == 0 ||
      EC_POINT_is_at_infinity(group, point)) {
    return 1;
  }

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

  BN_CTX_start(ctx);
  x = BN_CTX_get(ctx);
  y = BN_CTX_get(ctx);
  if (y == NULL) {
    goto err;
  }

  if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx) ||
      !EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) {
    goto err;
  }
  if (BN_cmp(&point->Z, &group->one) != 0) {
    OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
    goto err;
  }

  ret = 1;

err:
  BN_CTX_end(ctx);
  BN_CTX_free(new_ctx);
  return ret;
}

int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num,
                                     EC_POINT *points[], BN_CTX *ctx) {
  BN_CTX *new_ctx = NULL;
  BIGNUM *tmp, *tmp_Z;
  BIGNUM **prod_Z = NULL;
  size_t i;
  int ret = 0;

  if (num == 0) {
    return 1;
  }

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

  BN_CTX_start(ctx);
  tmp = BN_CTX_get(ctx);
  tmp_Z = BN_CTX_get(ctx);
  if (tmp == NULL || tmp_Z == NULL) {
    goto err;
  }

  prod_Z = OPENSSL_malloc(num * sizeof(prod_Z[0]));
  if (prod_Z == NULL) {
    goto err;
  }
  memset(prod_Z, 0, num * sizeof(prod_Z[0]));
  for (i = 0; i < num; i++) {
    prod_Z[i] = BN_new();
    if (prod_Z[i] == NULL) {
      goto err;
    }
  }

  /* Set each prod_Z[i] to the product of points[0]->Z .. points[i]->Z,
   * skipping any zero-valued inputs (pretend that they're 1). */

  if (!BN_is_zero(&points[0]->Z)) {
    if (!BN_copy(prod_Z[0], &points[0]->Z)) {
      goto err;
    }
  } else {
    if (BN_copy(prod_Z[0], &group->one) == NULL) {
      goto err;
    }
  }

  for (i = 1; i < num; i++) {
    if (!BN_is_zero(&points[i]->Z)) {
      if (!group->meth->field_mul(group, prod_Z[i], prod_Z[i - 1],
                                  &points[i]->Z, ctx)) {
        goto err;
      }
    } else {
      if (!BN_copy(prod_Z[i], prod_Z[i - 1])) {
        goto err;
      }
    }
  }

  /* Now use a single explicit inversion to replace every
   * non-zero points[i]->Z by its inverse. */

  if (!BN_mod_inverse(tmp, prod_Z[num - 1], &group->field, ctx)) {
    OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
    goto err;
  }

  if (group->meth->field_encode != NULL) {
    /* In the Montgomery case, we just turned R*H (representing H)
     * into 1/(R*H), but we need R*(1/H) (representing 1/H);
     * i.e. we need to multiply by the Montgomery factor twice. */
    if (!group->meth->field_encode(group, tmp, tmp, ctx) ||
        !group->meth->field_encode(group, tmp, tmp, ctx)) {
      goto err;
    }
  }

  for (i = num - 1; i > 0; --i) {
    /* Loop invariant: tmp is the product of the inverses of
     * points[0]->Z .. points[i]->Z (zero-valued inputs skipped). */
    if (BN_is_zero(&points[i]->Z)) {
      continue;
    }

    /* Set tmp_Z to the inverse of points[i]->Z (as product
     * of Z inverses 0 .. i, Z values 0 .. i - 1). */
    if (!group->meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx) ||
        /* Update tmp to satisfy the loop invariant for i - 1. */
        !group->meth->field_mul(group, tmp, tmp, &points[i]->Z, ctx) ||
        /* Replace points[i]->Z by its inverse. */
        !BN_copy(&points[i]->Z, tmp_Z)) {
      goto err;
    }
  }

  /* Replace points[0]->Z by its inverse. */
  if (!BN_is_zero(&points[0]->Z) && !BN_copy(&points[0]->Z, tmp)) {
    goto err;
  }

  /* Finally, fix up the X and Y coordinates for all points. */
  for (i = 0; i < num; i++) {
    EC_POINT *p = points[i];

    if (!BN_is_zero(&p->Z)) {
      /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1). */
      if (!group->meth->field_sqr(group, tmp, &p->Z, ctx) ||
          !group->meth->field_mul(group, &p->X, &p->X, tmp, ctx) ||
          !group->meth->field_mul(group, tmp, tmp, &p->Z, ctx) ||
          !group->meth->field_mul(group, &p->Y, &p->Y, tmp, ctx)) {
        goto err;
      }

      if (BN_copy(&p->Z, &group->one) == NULL) {
        goto err;
      }
    }
  }

  ret = 1;

err:
  BN_CTX_end(ctx);
  BN_CTX_free(new_ctx);
  if (prod_Z != NULL) {
    for (i = 0; i < num; i++) {
      if (prod_Z[i] == NULL) {
        break;
      }
      BN_clear_free(prod_Z[i]);
    }
    OPENSSL_free(prod_Z);
  }

  return ret;
}

int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
                            const BIGNUM *b, BN_CTX *ctx) {
  return BN_mod_mul(r, a, b, &group->field, ctx);
}

int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
                            BN_CTX *ctx) {
  return BN_mod_sqr(r, a, &group->field, ctx);
}
