/* 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 <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 {
  const EC_GROUP *group; /* parent EC_GROUP object */
  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(const EC_GROUP *group) {
  EC_PRE_COMP *ret = NULL;

  if (!group)
    return 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->group = group;
  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]);

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

  wNAF[0] = NULL; /* preliminary pivot */

  /* 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;
        totalnum = num + 1; /* don't use wNAF splitting */
        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) {
      if (!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) {
              if (!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)
      if (!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;
  }

  if ((pre_comp = ec_pre_comp_new(group)) == 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->group = group;
  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;
}
