/* 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"


/* 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;
  }

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

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

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