/* 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 <openssl/thread.h>

#include "internal.h"


/* This file implements the wNAF-based interleaving multi-exponentation method
 * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp>);
 * for multiplication with precomputation, we use wNAF splitting
 * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp>).
 * */

/* structure for precomputed multiples of the generator */
typedef struct ec_pre_comp_st {
  size_t blocksize;      /* block size for wNAF splitting */
  size_t numblocks; /* max. number of blocks for which we have precomputation */
  size_t w;         /* window size */
  EC_POINT **points; /* array with pre-calculated multiples of generator:
                      * 'num' pointers to EC_POINT objects followed by a NULL */
  size_t num; /* numblocks * 2^(w-1) */
  int references;
} EC_PRE_COMP;

static EC_PRE_COMP *ec_pre_comp_new(void) {
  EC_PRE_COMP *ret = NULL;

  ret = (EC_PRE_COMP *)OPENSSL_malloc(sizeof(EC_PRE_COMP));
  if (!ret) {
    OPENSSL_PUT_ERROR(EC, ec_pre_comp_new, ERR_R_MALLOC_FAILURE);
    return ret;
  }
  ret->blocksize = 8; /* default */
  ret->numblocks = 0;
  ret->w = 4; /* default */
  ret->points = NULL;
  ret->num = 0;
  ret->references = 1;
  return ret;
}

void *ec_pre_comp_dup(EC_PRE_COMP *pre_comp) {
  if (pre_comp == NULL) {
    return NULL;
  }

  CRYPTO_add(&pre_comp->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
  return pre_comp;
}

void ec_pre_comp_free(EC_PRE_COMP *pre_comp) {
  int i;

  if (!pre_comp) {
    return;
  }

  i = CRYPTO_add(&pre_comp->references, -1, CRYPTO_LOCK_EC_PRE_COMP);
  if (i > 0) {
    return;
  }

  if (pre_comp->points) {
    EC_POINT **p;

    for (p = pre_comp->points; *p != NULL; p++) {
      EC_POINT_free(*p);
    }
    OPENSSL_free(pre_comp->points);
  }
  OPENSSL_free(pre_comp);
}


/* Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'.
 * This is an array  r[]  of values that are either zero or odd with an
 * absolute value less than  2^w  satisfying
 *     scalar = \sum_j r[j]*2^j
 * where at most one of any  w+1  consecutive digits is non-zero
 * with the exception that the most significant digit may be only
 * w-1 zeros away from that next non-zero digit.
 */
static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) {
  int window_val;
  int ok = 0;
  signed char *r = NULL;
  int sign = 1;
  int bit, next_bit, mask;
  size_t len = 0, j;

  if (BN_is_zero(scalar)) {
    r = OPENSSL_malloc(1);
    if (!r) {
      OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_MALLOC_FAILURE);
      goto err;
    }
    r[0] = 0;
    *ret_len = 1;
    return r;
  }

  if (w <= 0 || w > 7) /* 'signed char' can represent integers with absolute
                          values less than 2^7 */
  {
    OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_INTERNAL_ERROR);
    goto err;
  }
  bit = 1 << w;        /* at most 128 */
  next_bit = bit << 1; /* at most 256 */
  mask = next_bit - 1; /* at most 255 */

  if (BN_is_negative(scalar)) {
    sign = -1;
  }

  if (scalar->d == NULL || scalar->top == 0) {
    OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_INTERNAL_ERROR);
    goto err;
  }

  len = BN_num_bits(scalar);
  r = OPENSSL_malloc(
      len +
      1); /* modified wNAF may be one digit longer than binary representation
           * (*ret_len will be set to the actual length, i.e. at most
           * BN_num_bits(scalar) + 1) */
  if (r == NULL) {
    OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_MALLOC_FAILURE);
    goto err;
  }
  window_val = scalar->d[0] & mask;
  j = 0;
  while ((window_val != 0) ||
         (j + w + 1 < len)) /* if j+w+1 >= len, window_val will not increase */
  {
    int digit = 0;

    /* 0 <= window_val <= 2^(w+1) */

    if (window_val & 1) {
      /* 0 < window_val < 2^(w+1) */

      if (window_val & bit) {
        digit = window_val - next_bit; /* -2^w < digit < 0 */

#if 1 /* modified wNAF */
        if (j + w + 1 >= len) {
          /* special case for generating modified wNAFs:
           * no new bits will be added into window_val,
           * so using a positive digit here will decrease
           * the total length of the representation */

          digit = window_val & (mask >> 1); /* 0 < digit < 2^w */
        }
#endif
      } else {
        digit = window_val; /* 0 < digit < 2^w */
      }

      if (digit <= -bit || digit >= bit || !(digit & 1)) {
        OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_INTERNAL_ERROR);
        goto err;
      }

      window_val -= digit;

      /* now window_val is 0 or 2^(w+1) in standard wNAF generation;
       * for modified window NAFs, it may also be 2^w
       */
      if (window_val != 0 && window_val != next_bit && window_val != bit) {
        OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_INTERNAL_ERROR);
        goto err;
      }
    }

    r[j++] = sign * digit;

    window_val >>= 1;
    window_val += bit * BN_is_bit_set(scalar, j + w);

    if (window_val > next_bit) {
      OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_INTERNAL_ERROR);
      goto err;
    }
  }

  if (j > len + 1) {
    OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_INTERNAL_ERROR);
    goto err;
  }
  len = j;
  ok = 1;

err:
  if (!ok) {
    OPENSSL_free(r);
    r = NULL;
  }
  if (ok) {
    *ret_len = len;
  }
  return r;
}


/* TODO: table should be optimised for the wNAF-based implementation,
 *       sometimes smaller windows will give better performance
 *       (thus the boundaries should be increased)
 */
#define EC_window_bits_for_scalar_size(b)                                      \
  ((size_t)((b) >= 2000 ? 6 : (b) >= 800 ? 5 : (b) >= 300                      \
                                                   ? 4                         \
                                                   : (b) >= 70 ? 3 : (b) >= 20 \
                                                                         ? 2   \
                                                                         : 1))

/* Compute
 *      \sum scalars[i]*points[i],
 * also including
 *      scalar*generator
 * in the addition if scalar != NULL
 */
int ec_wNAF_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;
  const EC_POINT *generator = NULL;
  EC_POINT *tmp = NULL;
  size_t totalnum;
  size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */
  size_t pre_points_per_block = 0;
  size_t i, j;
  int k;
  int r_is_inverted = 0;
  int r_is_at_infinity = 1;
  size_t *wsize = NULL;      /* individual window sizes */
  signed char **wNAF = NULL; /* individual wNAFs */
  size_t *wNAF_len = NULL;
  size_t max_len = 0;
  size_t num_val;
  EC_POINT **val = NULL; /* precomputation */
  EC_POINT **v;
  EC_POINT ***val_sub =
      NULL; /* pointers to sub-arrays of 'val' or 'pre_comp->points' */
  const EC_PRE_COMP *pre_comp = NULL;
  int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be treated like
                       * other scalars,
                       * i.e. precomputation is not available */
  int ret = 0;

  if (group->meth != r->meth) {
    OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, EC_R_INCOMPATIBLE_OBJECTS);
    return 0;
  }

  if ((scalar == NULL) && (num == 0)) {
    return EC_POINT_set_to_infinity(group, r);
  }

  for (i = 0; i < num; i++) {
    if (group->meth != points[i]->meth) {
      OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, EC_R_INCOMPATIBLE_OBJECTS);
      return 0;
    }
  }

  if (ctx == NULL) {
    ctx = new_ctx = BN_CTX_new();
    if (ctx == NULL) {
      goto err;
    }
  }

  if (scalar != NULL) {
    generator = EC_GROUP_get0_generator(group);
    if (generator == NULL) {
      OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, EC_R_UNDEFINED_GENERATOR);
      goto err;
    }

    /* look if we can use precomputed multiples of generator */

    pre_comp = group->pre_comp;

    if (pre_comp && pre_comp->numblocks &&
        (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) == 0)) {
      blocksize = pre_comp->blocksize;

      /* determine maximum number of blocks that wNAF splitting may yield
       * (NB: maximum wNAF length is bit length plus one) */
      numblocks = (BN_num_bits(scalar) / blocksize) + 1;

      /* we cannot use more blocks than we have precomputation for */
      if (numblocks > pre_comp->numblocks) {
        numblocks = pre_comp->numblocks;
      }

      pre_points_per_block = (size_t)1 << (pre_comp->w - 1);

      /* check that pre_comp looks sane */
      if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) {
        OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_INTERNAL_ERROR);
        goto err;
      }
    } else {
      /* can't use precomputation */
      pre_comp = NULL;
      numblocks = 1;
      num_scalar = 1; /* treat 'scalar' like 'num'-th element of 'scalars' */
    }
  }

  totalnum = num + numblocks;

  wsize = OPENSSL_malloc(totalnum * sizeof wsize[0]);
  wNAF_len = OPENSSL_malloc(totalnum * sizeof wNAF_len[0]);
  wNAF = OPENSSL_malloc((totalnum + 1) *
                        sizeof wNAF[0]); /* includes space for pivot */
  val_sub = OPENSSL_malloc(totalnum * sizeof val_sub[0]);

  /* Ensure wNAF is initialised in case we end up going to err. */
  if (wNAF) {
    wNAF[0] = NULL; /* preliminary pivot */
  }

  if (!wsize || !wNAF_len || !wNAF || !val_sub) {
    OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  /* num_val will be the total number of temporarily precomputed points */
  num_val = 0;

  for (i = 0; i < num + num_scalar; i++) {
    size_t bits;

    bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar);
    wsize[i] = EC_window_bits_for_scalar_size(bits);
    num_val += (size_t)1 << (wsize[i] - 1);
    wNAF[i + 1] = NULL; /* make sure we always have a pivot */
    wNAF[i] =
        compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], &wNAF_len[i]);
    if (wNAF[i] == NULL) {
      goto err;
    }
    if (wNAF_len[i] > max_len) {
      max_len = wNAF_len[i];
    }
  }

  if (numblocks) {
    /* we go here iff scalar != NULL */

    if (pre_comp == NULL) {
      if (num_scalar != 1) {
        OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_INTERNAL_ERROR);
        goto err;
      }
      /* we have already generated a wNAF for 'scalar' */
    } else {
      signed char *tmp_wNAF = NULL;
      size_t tmp_len = 0;

      if (num_scalar != 0) {
        OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_INTERNAL_ERROR);
        goto err;
      }

      /* use the window size for which we have precomputation */
      wsize[num] = pre_comp->w;
      tmp_wNAF = compute_wNAF(scalar, wsize[num], &tmp_len);
      if (!tmp_wNAF) {
        goto err;
      }

      if (tmp_len <= max_len) {
        /* One of the other wNAFs is at least as long
         * as the wNAF belonging to the generator,
         * so wNAF splitting will not buy us anything. */

        numblocks = 1; /* don't use wNAF splitting */
        totalnum = num + numblocks;
        wNAF[num] = tmp_wNAF;
        wNAF[num + 1] = NULL;
        wNAF_len[num] = tmp_len;
        /* pre_comp->points starts with the points that we need here: */
        val_sub[num] = pre_comp->points;
      } else {
        /* don't include tmp_wNAF directly into wNAF array
         * - use wNAF splitting and include the blocks */

        signed char *pp;
        EC_POINT **tmp_points;

        if (tmp_len < numblocks * blocksize) {
          /* possibly we can do with fewer blocks than estimated */
          numblocks = (tmp_len + blocksize - 1) / blocksize;
          if (numblocks > pre_comp->numblocks) {
            OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_INTERNAL_ERROR);
            goto err;
          }
          totalnum = num + numblocks;
        }

        /* split wNAF in 'numblocks' parts */
        pp = tmp_wNAF;
        tmp_points = pre_comp->points;

        for (i = num; i < totalnum; i++) {
          if (i < totalnum - 1) {
            wNAF_len[i] = blocksize;
            if (tmp_len < blocksize) {
              OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_INTERNAL_ERROR);
              goto err;
            }
            tmp_len -= blocksize;
          } else {
            /* last block gets whatever is left
             * (this could be more or less than 'blocksize'!) */
            wNAF_len[i] = tmp_len;
          }

          wNAF[i + 1] = NULL;
          wNAF[i] = OPENSSL_malloc(wNAF_len[i]);
          if (wNAF[i] == NULL) {
            OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_MALLOC_FAILURE);
            OPENSSL_free(tmp_wNAF);
            goto err;
          }
          memcpy(wNAF[i], pp, wNAF_len[i]);
          if (wNAF_len[i] > max_len) {
            max_len = wNAF_len[i];
          }

          if (*tmp_points == NULL) {
            OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_INTERNAL_ERROR);
            OPENSSL_free(tmp_wNAF);
            goto err;
          }
          val_sub[i] = tmp_points;
          tmp_points += pre_points_per_block;
          pp += blocksize;
        }
        OPENSSL_free(tmp_wNAF);
      }
    }
  }

  /* All points we precompute now go into a single array 'val'.
   * 'val_sub[i]' is a pointer to the subarray for the i-th point,
   * or to a subarray of 'pre_comp->points' if we already have precomputation.
   */
  val = OPENSSL_malloc((num_val + 1) * sizeof val[0]);
  if (val == NULL) {
    OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_MALLOC_FAILURE);
    goto err;
  }
  val[num_val] = NULL; /* pivot element */

  /* allocate points for precomputation */
  v = val;
  for (i = 0; i < num + num_scalar; i++) {
    val_sub[i] = v;
    for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++) {
      *v = EC_POINT_new(group);
      if (*v == NULL) {
        goto err;
      }
      v++;
    }
  }
  if (!(v == val + num_val)) {
    OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_INTERNAL_ERROR);
    goto err;
  }

  if (!(tmp = EC_POINT_new(group))) {
    goto err;
  }

  /* prepare precomputed values:
   *    val_sub[i][0] :=     points[i]
   *    val_sub[i][1] := 3 * points[i]
   *    val_sub[i][2] := 5 * points[i]
   *    ...
   */
  for (i = 0; i < num + num_scalar; i++) {
    if (i < num) {
      if (!EC_POINT_copy(val_sub[i][0], points[i])) {
        goto err;
      }
    } else if (!EC_POINT_copy(val_sub[i][0], generator)) {
      goto err;
    }

    if (wsize[i] > 1) {
      if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx)) {
        goto err;
      }
      for (j = 1; j < ((size_t)1 << (wsize[i] - 1)); j++) {
        if (!EC_POINT_add(group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx)) {
          goto err;
        }
      }
    }
  }

#if 1 /* optional; EC_window_bits_for_scalar_size assumes we do this step */
  if (!EC_POINTs_make_affine(group, num_val, val, ctx)) {
    goto err;
  }
#endif

  r_is_at_infinity = 1;

  for (k = max_len - 1; k >= 0; k--) {
    if (!r_is_at_infinity && !EC_POINT_dbl(group, r, r, ctx)) {
      goto err;
    }

    for (i = 0; i < totalnum; i++) {
      if (wNAF_len[i] > (size_t)k) {
        int digit = wNAF[i][k];
        int is_neg;

        if (digit) {
          is_neg = digit < 0;

          if (is_neg) {
            digit = -digit;
          }

          if (is_neg != r_is_inverted) {
            if (!r_is_at_infinity && !EC_POINT_invert(group, r, ctx)) {
              goto err;
            }
            r_is_inverted = !r_is_inverted;
          }

          /* digit > 0 */

          if (r_is_at_infinity) {
            if (!EC_POINT_copy(r, val_sub[i][digit >> 1])) {
              goto err;
            }
            r_is_at_infinity = 0;
          } else {
            if (!EC_POINT_add(group, r, r, val_sub[i][digit >> 1], ctx)) {
              goto err;
            }
          }
        }
      }
    }
  }

  if (r_is_at_infinity) {
    if (!EC_POINT_set_to_infinity(group, r)) {
      goto err;
    }
  } else if (r_is_inverted && !EC_POINT_invert(group, r, ctx)) {
    goto err;
  }

  ret = 1;

err:
  if (new_ctx != NULL) {
    BN_CTX_free(new_ctx);
  }
  if (tmp != NULL) {
    EC_POINT_free(tmp);
  }
  if (wsize != NULL) {
    OPENSSL_free(wsize);
  }
  if (wNAF_len != NULL) {
    OPENSSL_free(wNAF_len);
  }
  if (wNAF != NULL) {
    signed char **w;

    for (w = wNAF; *w != NULL; w++) {
      OPENSSL_free(*w);
    }

    OPENSSL_free(wNAF);
  }
  if (val != NULL) {
    for (v = val; *v != NULL; v++) {
      EC_POINT_clear_free(*v);
    }

    OPENSSL_free(val);
  }
  if (val_sub != NULL) {
    OPENSSL_free(val_sub);
  }
  return ret;
}


/* ec_wNAF_precompute_mult()
 * creates an EC_PRE_COMP object with preprecomputed multiples of the generator
 * for use with wNAF splitting as implemented in ec_wNAF_mul().
 *
 * 'pre_comp->points' is an array of multiples of the generator
 * of the following form:
 * points[0] =     generator;
 * points[1] = 3 * generator;
 * ...
 * points[2^(w-1)-1] =     (2^(w-1)-1) * generator;
 * points[2^(w-1)]   =     2^blocksize * generator;
 * points[2^(w-1)+1] = 3 * 2^blocksize * generator;
 * ...
 * points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) *  2^(blocksize*(numblocks-2)) *
 *generator
 * points[2^(w-1)*(numblocks-1)]   =              2^(blocksize*(numblocks-1)) *
 *generator
 * ...
 * points[2^(w-1)*numblocks-1]     = (2^(w-1)) *  2^(blocksize*(numblocks-1)) *
 *generator
 * points[2^(w-1)*numblocks]       = NULL
 */
int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) {
  const EC_POINT *generator;
  EC_POINT *tmp_point = NULL, *base = NULL, **var;
  BN_CTX *new_ctx = NULL;
  BIGNUM *order;
  size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num;
  EC_POINT **points = NULL;
  EC_PRE_COMP *pre_comp;
  int ret = 0;

  /* if there is an old EC_PRE_COMP object, throw it away */
  if (group->pre_comp) {
    ec_pre_comp_free(group->pre_comp);
    group->pre_comp = NULL;
  }

  generator = EC_GROUP_get0_generator(group);
  if (generator == NULL) {
    OPENSSL_PUT_ERROR(EC, ec_wNAF_precompute_mult, EC_R_UNDEFINED_GENERATOR);
    return 0;
  }

  pre_comp = ec_pre_comp_new();
  if (pre_comp == NULL) {
    return 0;
  }

  if (ctx == NULL) {
    ctx = new_ctx = BN_CTX_new();
    if (ctx == NULL) {
      goto err;
    }
  }

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

  if (!EC_GROUP_get_order(group, order, ctx)) {
    goto err;
  }
  if (BN_is_zero(order)) {
    OPENSSL_PUT_ERROR(EC, ec_wNAF_precompute_mult, EC_R_UNKNOWN_ORDER);
    goto err;
  }

  bits = BN_num_bits(order);
  /* The following parameters mean we precompute (approximately)
   * one point per bit.
   *
   * TBD: The combination  8, 4  is perfect for 160 bits; for other
   * bit lengths, other parameter combinations might provide better
   * efficiency.
   */
  blocksize = 8;
  w = 4;
  if (EC_window_bits_for_scalar_size(bits) > w) {
    /* let's not make the window too small ... */
    w = EC_window_bits_for_scalar_size(bits);
  }

  numblocks = (bits + blocksize - 1) /
              blocksize; /* max. number of blocks to use for wNAF splitting */

  pre_points_per_block = (size_t)1 << (w - 1);
  num = pre_points_per_block *
        numblocks; /* number of points to compute and store */

  points = OPENSSL_malloc(sizeof(EC_POINT *) * (num + 1));
  if (!points) {
    OPENSSL_PUT_ERROR(EC, ec_wNAF_precompute_mult, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  var = points;
  var[num] = NULL; /* pivot */
  for (i = 0; i < num; i++) {
    if ((var[i] = EC_POINT_new(group)) == NULL) {
      OPENSSL_PUT_ERROR(EC, ec_wNAF_precompute_mult, ERR_R_MALLOC_FAILURE);
      goto err;
    }
  }

  if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group))) {
    OPENSSL_PUT_ERROR(EC, ec_wNAF_precompute_mult, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  if (!EC_POINT_copy(base, generator)) {
    goto err;
  }

  /* do the precomputation */
  for (i = 0; i < numblocks; i++) {
    size_t j;

    if (!EC_POINT_dbl(group, tmp_point, base, ctx)) {
      goto err;
    }

    if (!EC_POINT_copy(*var++, base)) {
      goto err;
    }

    for (j = 1; j < pre_points_per_block; j++, var++) {
      /* calculate odd multiples of the current base point */
      if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx)) {
        goto err;
      }
    }

    if (i < numblocks - 1) {
      /* get the next base (multiply current one by 2^blocksize) */
      size_t k;

      if (blocksize <= 2) {
        OPENSSL_PUT_ERROR(EC, ec_wNAF_precompute_mult, ERR_R_INTERNAL_ERROR);
        goto err;
      }

      if (!EC_POINT_dbl(group, base, tmp_point, ctx)) {
        goto err;
      }
      for (k = 2; k < blocksize; k++) {
        if (!EC_POINT_dbl(group, base, base, ctx)) {
          goto err;
        }
      }
    }
  }

  if (!EC_POINTs_make_affine(group, num, points, ctx)) {
    goto err;
  }

  pre_comp->blocksize = blocksize;
  pre_comp->numblocks = numblocks;
  pre_comp->w = w;
  pre_comp->points = points;
  points = NULL;
  pre_comp->num = num;

  group->pre_comp = pre_comp;
  pre_comp = NULL;

  ret = 1;

err:
  if (ctx != NULL) {
    BN_CTX_end(ctx);
  }
  if (new_ctx != NULL) {
    BN_CTX_free(new_ctx);
  }
  if (pre_comp) {
    ec_pre_comp_free(pre_comp);
  }
  if (points) {
    EC_POINT **p;

    for (p = points; *p != NULL; p++) {
      EC_POINT_free(*p);
    }
    OPENSSL_free(points);
  }
  if (tmp_point) {
    EC_POINT_free(tmp_point);
  }
  if (base) {
    EC_POINT_free(base);
  }
  return ret;
}


int ec_wNAF_have_precompute_mult(const EC_GROUP *group) {
  return group->pre_comp != NULL;
}
