/* 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"
#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) */
  CRYPTO_refcount_t 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, 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_refcount_inc(&pre_comp->references);
  return pre_comp;
}

void ec_pre_comp_free(EC_PRE_COMP *pre_comp) {
  if (pre_comp == NULL ||
      !CRYPTO_refcount_dec_and_test_zero(&pre_comp->references)) {
    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, 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, 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, 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, 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, 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, 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, ERR_R_INTERNAL_ERROR);
      goto err;
    }
  }

  if (j > len + 1) {
    OPENSSL_PUT_ERROR(EC, 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_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_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_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, 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, 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, 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, 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, ERR_R_INTERNAL_ERROR);
            OPENSSL_free(tmp_wNAF);
            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, ERR_R_INTERNAL_ERROR);
              OPENSSL_free(tmp_wNAF);
              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, 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, 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, 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, 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:
  BN_CTX_free(new_ctx);
  EC_POINT_free(tmp);
  OPENSSL_free(wsize);
  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);
  }
  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 */
  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_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_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, 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, ERR_R_MALLOC_FAILURE);
      goto err;
    }
  }

  if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group))) {
    OPENSSL_PUT_ERROR(EC, 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, 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);
  }
  BN_CTX_free(new_ctx);
  ec_pre_comp_free(pre_comp);
  if (points) {
    EC_POINT **p;

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


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