test/ectest.c:1141: error: BUFFER_OVERRUN_L3
  Offset added: [8, +oo] Size: [0, 536870848] by call to `EC_GROUP_check`.
Showing all 24 steps of the trace


test/ectest.c:1136:10: Call
1134.       int nid = curves[n].nid;
1135.   
1136.       if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
                 ^
1137.           TEST_info("EC_GROUP_new_curve_name() failed with curve %s\n",
1138.                     OBJ_nid2sn(nid));

crypto/ec/ec_curve.c:3125:19: Call
  3123.       for (i = 0; i < curve_list_length; i++)
  3124.           if (curve_list[i].nid == nid) {
  3125.               ret = ec_group_new_from_data(curve_list[i]);
                            ^
  3126.               break;
  3127.           }

crypto/ec/ec_curve.c:3038:14: Call
    3036.       params += seed_len;         /* skip seed */
    3037.   
    3038.       if ((p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) == NULL
                         ^
    3039.           || (a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) == NULL
    3040.           || (b = BN_bin2bn(params + 2 * param_len, param_len, NULL)) == NULL) {

crypto/bn/bn_lib.c:369:1: Parameter `ret->top`
      367.   }
      368.   
      369. > BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
      370.   {
      371.       unsigned int i, m;

test/ectest.c:1141:10: Call
1139.           return 0;
1140.       }
1141.       if (!TEST_true(EC_GROUP_check(group, NULL))) {
                 ^
1142.           TEST_info("EC_GROUP_check() failed with curve %s\n", OBJ_nid2sn(nid));
1143.           EC_GROUP_free(group);

crypto/ec/ec_check.c:13:1: Parameter `group->order->top`
  11.   #include <openssl/err.h>
  12.   
  13. > int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
  14.   {
  15.       int ret = 0;

crypto/ec/ec_check.c:54:9: Call
  52.       if (order == NULL)
  53.           goto err;
  54.       if (BN_is_zero(order)) {
                ^
  55.           ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER);
  56.           goto err;

crypto/bn/bn_lib.c:827:1: Parameter `a->top`
    825.   }
    826.   
    827. > int BN_is_zero(const BIGNUM *a)
    828.   {
    829.       return a->top == 0;

crypto/ec/ec_check.c:59:10: Call
  57.       }
  58.   
  59.       if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx))
                 ^
  60.           goto err;
  61.       if (!EC_POINT_is_at_infinity(group, point)) {

crypto/ec/ec_lib.c:922:1: Parameter `g_scalar->top`
    920.   }
    921.   
    922. > int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
    923.                    const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
    924.   {

crypto/ec/ec_lib.c:933:12: Call
    931.       scalars[0] = p_scalar;
    932.   
    933.       return EC_POINTs_mul(group, r, g_scalar,
                      ^
    934.                            (point != NULL
    935.                             && p_scalar != NULL), points, scalars, ctx);

crypto/ec/ec_lib.c:911:1: Parameter `scalar->top`
      909.    */
      910.   
      911. > int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
      912.                     size_t num, const EC_POINT *points[],
      913.                     const BIGNUM *scalars[], BN_CTX *ctx)

crypto/ec/ec_lib.c:917:16: Call
      915.       if (group->meth->mul == 0)
      916.           /* use default */
      917.           return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
                            ^
      918.   
      919.       return group->meth->mul(group, r, scalar, num, points, scalars, ctx);

crypto/ec/ec_mult.c:346:1: Parameter `scalar->top`
        344.    * in the addition if scalar != NULL
        345.    */
        346. > int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
        347.                   size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
        348.                   BN_CTX *ctx)

crypto/ec/ec_mult.c:388:16: Call
        386.            * constant time version.
        387.            */
        388.           return ec_mul_consttime(group, r, scalar, NULL, ctx);
                              ^
        389.       }
        390.       if ((scalar == NULL) && (num == 1)) {

crypto/ec/ec_mult.c:131:1: Parameter `scalar->top`
          129.    * Returns 1 on success, 0 otherwise.
          130.    */
          131. > static int ec_mul_consttime(const EC_GROUP *group, EC_POINT *r,
          132.                               const BIGNUM *scalar, const EC_POINT *point,
          133.                               BN_CTX *ctx)

crypto/ec/ec_mult.c:183:10: Call
          181.           goto err;
          182.   
          183.       if (!BN_copy(k, scalar))
                          ^
          184.           goto err;
          185.   

crypto/bn/bn_lib.c:285:1: <Offset trace>
283.   }
284.   
285. > BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
286.   {
287.       bn_check_top(b);

crypto/bn/bn_lib.c:285:1: Parameter `b->top`
            283.   }
            284.   
            285. > BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
            286.   {
            287.       bn_check_top(b);

crypto/bn/bn_lib.c:285:1: <Length trace>
283.   }
284.   
285. > BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
286.   {
287.       bn_check_top(b);

crypto/bn/bn_lib.c:285:1: Parameter `*a->d`
            283.   }
            284.   
            285. > BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
            286.   {
            287.       bn_check_top(b);

crypto/bn/bn_lib.c:291:9: Call
            289.       if (a == b)
            290.           return a;
            291.       if (bn_wexpand(a, b->top) == NULL)
                           ^
            292.           return NULL;
            293.   

crypto/bn/bn_lib.c:923:1: Parameter `*a->d`
              921.   }
              922.   
              923. > BIGNUM *bn_wexpand(BIGNUM *a, int words)
              924.   {
              925.       return (words <= a->dmax) ? a : bn_expand2(a, words);

crypto/bn/bn_lib.c:295:9: Array access: Offset added: [8, +oo] Size: [0, 536870848] by call to `EC_GROUP_check` 
            293.   
            294.       if (b->top > 0)
            295.           memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);
                           ^
            296.   
            297.       a->top = b->top;

BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
{
    bn_check_top(b);
    if (a == b)
        return a;
    if (bn_wexpand(a, b->top) == NULL)
        return NULL;
    if (b->top > 0)
        memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);
    a->top = b->top;
    a->neg = b->neg;
    bn_check_top(a);
    return a;
}
['static int internal_curve_test(int n)\n{\n    EC_GROUP *group = NULL;\n    int nid = curves[n].nid;\n    if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {\n        TEST_info("EC_GROUP_new_curve_name() failed with curve %s\\n",\n                  OBJ_nid2sn(nid));\n        return 0;\n    }\n    if (!TEST_true(EC_GROUP_check(group, NULL))) {\n        TEST_info("EC_GROUP_check() failed with curve %s\\n", OBJ_nid2sn(nid));\n        EC_GROUP_free(group);\n        return 0;\n    }\n    EC_GROUP_free(group);\n    return 1;\n}', 'EC_GROUP *EC_GROUP_new_by_curve_name(int nid)\n{\n    size_t i;\n    EC_GROUP *ret = NULL;\n    if (nid <= 0)\n        return NULL;\n    for (i = 0; i < curve_list_length; i++)\n        if (curve_list[i].nid == nid) {\n            ret = ec_group_new_from_data(curve_list[i]);\n            break;\n        }\n    if (ret == NULL) {\n        ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP);\n        return NULL;\n    }\n    EC_GROUP_set_curve_name(ret, nid);\n    return ret;\n}', 'static EC_GROUP *ec_group_new_from_data(const ec_list_element curve)\n{\n    EC_GROUP *group = NULL;\n    EC_POINT *P = NULL;\n    BN_CTX *ctx = NULL;\n    BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order =\n        NULL;\n    int ok = 0;\n    int seed_len, param_len;\n    const EC_METHOD *meth;\n    const EC_CURVE_DATA *data;\n    const unsigned char *params;\n    if (curve.data == NULL)\n        return EC_GROUP_new(curve.meth != NULL ? curve.meth() : NULL);\n    if ((ctx = BN_CTX_new()) == NULL) {\n        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE);\n        goto err;\n    }\n    data = curve.data;\n    seed_len = data->seed_len;\n    param_len = data->param_len;\n    params = (const unsigned char *)(data + 1);\n    params += seed_len;\n    if ((p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) == NULL\n        || (a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) == NULL\n        || (b = BN_bin2bn(params + 2 * param_len, param_len, NULL)) == NULL) {\n        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);\n        goto err;\n    }\n    if (curve.meth != 0) {\n        meth = curve.meth();\n        if (((group = EC_GROUP_new(meth)) == NULL) ||\n            (!(group->meth->group_set_curve(group, p, a, b, ctx)))) {\n            ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);\n            goto err;\n        }\n    } else if (data->field_type == NID_X9_62_prime_field) {\n        if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {\n            ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);\n            goto err;\n        }\n    }\n#ifndef OPENSSL_NO_EC2M\n    else {\n        if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) {\n            ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);\n            goto err;\n        }\n    }\n#endif\n    if ((P = EC_POINT_new(group)) == NULL) {\n        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);\n        goto err;\n    }\n    if ((x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) == NULL\n        || (y = BN_bin2bn(params + 4 * param_len, param_len, NULL)) == NULL) {\n        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);\n        goto err;\n    }\n    if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {\n        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);\n        goto err;\n    }\n    if ((order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) == NULL\n        || !BN_set_word(x, (BN_ULONG)data->cofactor)) {\n        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB);\n        goto err;\n    }\n    if (!EC_GROUP_set_generator(group, P, order, x)) {\n        ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);\n        goto err;\n    }\n    if (seed_len) {\n        if (!EC_GROUP_set_seed(group, params - seed_len, seed_len)) {\n            ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB);\n            goto err;\n        }\n    }\n    ok = 1;\n err:\n    if (!ok) {\n        EC_GROUP_free(group);\n        group = NULL;\n    }\n    EC_POINT_free(P);\n    BN_CTX_free(ctx);\n    BN_free(p);\n    BN_free(a);\n    BN_free(b);\n    BN_free(order);\n    BN_free(x);\n    BN_free(y);\n    return group;\n}', 'BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)\n{\n    unsigned int i, m;\n    unsigned int n;\n    BN_ULONG l;\n    BIGNUM *bn = NULL;\n    if (ret == NULL)\n        ret = bn = BN_new();\n    if (ret == NULL)\n        return NULL;\n    bn_check_top(ret);\n    for ( ; len > 0 && *s == 0; s++, len--)\n        continue;\n    n = len;\n    if (n == 0) {\n        ret->top = 0;\n        return ret;\n    }\n    i = ((n - 1) / BN_BYTES) + 1;\n    m = ((n - 1) % (BN_BYTES));\n    if (bn_wexpand(ret, (int)i) == NULL) {\n        BN_free(bn);\n        return NULL;\n    }\n    ret->top = i;\n    ret->neg = 0;\n    l = 0;\n    while (n--) {\n        l = (l << 8L) | *(s++);\n        if (m-- == 0) {\n            ret->d[--i] = l;\n            l = 0;\n            m = BN_BYTES - 1;\n        }\n    }\n    bn_correct_top(ret);\n    return ret;\n}', 'int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)\n{\n    int ret = 0;\n    const BIGNUM *order;\n    BN_CTX *new_ctx = NULL;\n    EC_POINT *point = NULL;\n    if ((group->meth->flags & EC_FLAGS_CUSTOM_CURVE) != 0)\n        return 1;\n    if (ctx == NULL) {\n        ctx = new_ctx = BN_CTX_new();\n        if (ctx == NULL) {\n            ECerr(EC_F_EC_GROUP_CHECK, ERR_R_MALLOC_FAILURE);\n            goto err;\n        }\n    }\n    if (!EC_GROUP_check_discriminant(group, ctx)) {\n        ECerr(EC_F_EC_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO);\n        goto err;\n    }\n    if (group->generator == NULL) {\n        ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR);\n        goto err;\n    }\n    if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0) {\n        ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE);\n        goto err;\n    }\n    if ((point = EC_POINT_new(group)) == NULL)\n        goto err;\n    order = EC_GROUP_get0_order(group);\n    if (order == NULL)\n        goto err;\n    if (BN_is_zero(order)) {\n        ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER);\n        goto err;\n    }\n    if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx))\n        goto err;\n    if (!EC_POINT_is_at_infinity(group, point)) {\n        ECerr(EC_F_EC_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER);\n        goto err;\n    }\n    ret = 1;\n err:\n    BN_CTX_free(new_ctx);\n    EC_POINT_free(point);\n    return ret;\n}', 'int BN_is_zero(const BIGNUM *a)\n{\n    return a->top == 0;\n}', 'int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,\n                 const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)\n{\n    const EC_POINT *points[1];\n    const BIGNUM *scalars[1];\n    points[0] = point;\n    scalars[0] = p_scalar;\n    return EC_POINTs_mul(group, r, g_scalar,\n                         (point != NULL\n                          && p_scalar != NULL), points, scalars, ctx);\n}', 'int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,\n                  size_t num, const EC_POINT *points[],\n                  const BIGNUM *scalars[], BN_CTX *ctx)\n{\n    if (group->meth->mul == 0)\n        return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);\n    return group->meth->mul(group, r, scalar, num, points, scalars, ctx);\n}', 'int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,\n                size_t num, const EC_POINT *points[], const BIGNUM *scalars[],\n                BN_CTX *ctx)\n{\n    BN_CTX *new_ctx = NULL;\n    const EC_POINT *generator = NULL;\n    EC_POINT *tmp = NULL;\n    size_t totalnum;\n    size_t blocksize = 0, numblocks = 0;\n    size_t pre_points_per_block = 0;\n    size_t i, j;\n    int k;\n    int r_is_inverted = 0;\n    int r_is_at_infinity = 1;\n    size_t *wsize = NULL;\n    signed char **wNAF = NULL;\n    size_t *wNAF_len = NULL;\n    size_t max_len = 0;\n    size_t num_val;\n    EC_POINT **val = NULL;\n    EC_POINT **v;\n    EC_POINT ***val_sub = NULL;\n    const EC_PRE_COMP *pre_comp = NULL;\n    int num_scalar = 0;\n    int ret = 0;\n    if ((scalar != NULL) && (num == 0)) {\n        return ec_mul_consttime(group, r, scalar, NULL, ctx);\n    }\n    if ((scalar == NULL) && (num == 1)) {\n        return ec_mul_consttime(group, r, scalars[0], points[0], ctx);\n    }\n    if (group->meth != r->meth) {\n        ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);\n        return 0;\n    }\n    if ((scalar == NULL) && (num == 0)) {\n        return EC_POINT_set_to_infinity(group, r);\n    }\n    for (i = 0; i < num; i++) {\n        if (group->meth != points[i]->meth) {\n            ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS);\n            return 0;\n        }\n    }\n    if (ctx == NULL) {\n        ctx = new_ctx = BN_CTX_new();\n        if (ctx == NULL)\n            goto err;\n    }\n    if (scalar != NULL) {\n        generator = EC_GROUP_get0_generator(group);\n        if (generator == NULL) {\n            ECerr(EC_F_EC_WNAF_MUL, EC_R_UNDEFINED_GENERATOR);\n            goto err;\n        }\n        pre_comp = group->pre_comp.ec;\n        if (pre_comp && pre_comp->numblocks\n            && (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) ==\n                0)) {\n            blocksize = pre_comp->blocksize;\n            numblocks = (BN_num_bits(scalar) / blocksize) + 1;\n            if (numblocks > pre_comp->numblocks)\n                numblocks = pre_comp->numblocks;\n            pre_points_per_block = (size_t)1 << (pre_comp->w - 1);\n            if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) {\n                ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);\n                goto err;\n            }\n        } else {\n            pre_comp = NULL;\n            numblocks = 1;\n            num_scalar = 1;\n        }\n    }\n    totalnum = num + numblocks;\n    wsize = OPENSSL_malloc(totalnum * sizeof(wsize[0]));\n    wNAF_len = OPENSSL_malloc(totalnum * sizeof(wNAF_len[0]));\n    wNAF = OPENSSL_malloc((totalnum + 1) * sizeof(wNAF[0]));\n    val_sub = OPENSSL_malloc(totalnum * sizeof(val_sub[0]));\n    if (wNAF != NULL)\n        wNAF[0] = NULL;\n    if (wsize == NULL || wNAF_len == NULL || wNAF == NULL || val_sub == NULL) {\n        ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);\n        goto err;\n    }\n    num_val = 0;\n    for (i = 0; i < num + num_scalar; i++) {\n        size_t bits;\n        bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar);\n        wsize[i] = EC_window_bits_for_scalar_size(bits);\n        num_val += (size_t)1 << (wsize[i] - 1);\n        wNAF[i + 1] = NULL;\n        wNAF[i] =\n            bn_compute_wNAF((i < num ? scalars[i] : scalar), wsize[i],\n                            &wNAF_len[i]);\n        if (wNAF[i] == NULL)\n            goto err;\n        if (wNAF_len[i] > max_len)\n            max_len = wNAF_len[i];\n    }\n    if (numblocks) {\n        if (pre_comp == NULL) {\n            if (num_scalar != 1) {\n                ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);\n                goto err;\n            }\n        } else {\n            signed char *tmp_wNAF = NULL;\n            size_t tmp_len = 0;\n            if (num_scalar != 0) {\n                ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);\n                goto err;\n            }\n            wsize[num] = pre_comp->w;\n            tmp_wNAF = bn_compute_wNAF(scalar, wsize[num], &tmp_len);\n            if (!tmp_wNAF)\n                goto err;\n            if (tmp_len <= max_len) {\n                numblocks = 1;\n                totalnum = num + 1;\n                wNAF[num] = tmp_wNAF;\n                wNAF[num + 1] = NULL;\n                wNAF_len[num] = tmp_len;\n                val_sub[num] = pre_comp->points;\n            } else {\n                signed char *pp;\n                EC_POINT **tmp_points;\n                if (tmp_len < numblocks * blocksize) {\n                    numblocks = (tmp_len + blocksize - 1) / blocksize;\n                    if (numblocks > pre_comp->numblocks) {\n                        ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);\n                        OPENSSL_free(tmp_wNAF);\n                        goto err;\n                    }\n                    totalnum = num + numblocks;\n                }\n                pp = tmp_wNAF;\n                tmp_points = pre_comp->points;\n                for (i = num; i < totalnum; i++) {\n                    if (i < totalnum - 1) {\n                        wNAF_len[i] = blocksize;\n                        if (tmp_len < blocksize) {\n                            ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);\n                            OPENSSL_free(tmp_wNAF);\n                            goto err;\n                        }\n                        tmp_len -= blocksize;\n                    } else\n                        wNAF_len[i] = tmp_len;\n                    wNAF[i + 1] = NULL;\n                    wNAF[i] = OPENSSL_malloc(wNAF_len[i]);\n                    if (wNAF[i] == NULL) {\n                        ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);\n                        OPENSSL_free(tmp_wNAF);\n                        goto err;\n                    }\n                    memcpy(wNAF[i], pp, wNAF_len[i]);\n                    if (wNAF_len[i] > max_len)\n                        max_len = wNAF_len[i];\n                    if (*tmp_points == NULL) {\n                        ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);\n                        OPENSSL_free(tmp_wNAF);\n                        goto err;\n                    }\n                    val_sub[i] = tmp_points;\n                    tmp_points += pre_points_per_block;\n                    pp += blocksize;\n                }\n                OPENSSL_free(tmp_wNAF);\n            }\n        }\n    }\n    val = OPENSSL_malloc((num_val + 1) * sizeof(val[0]));\n    if (val == NULL) {\n        ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);\n        goto err;\n    }\n    val[num_val] = NULL;\n    v = val;\n    for (i = 0; i < num + num_scalar; i++) {\n        val_sub[i] = v;\n        for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++) {\n            *v = EC_POINT_new(group);\n            if (*v == NULL)\n                goto err;\n            v++;\n        }\n    }\n    if (!(v == val + num_val)) {\n        ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);\n        goto err;\n    }\n    if ((tmp = EC_POINT_new(group)) == NULL)\n        goto err;\n    for (i = 0; i < num + num_scalar; i++) {\n        if (i < num) {\n            if (!EC_POINT_copy(val_sub[i][0], points[i]))\n                goto err;\n        } else {\n            if (!EC_POINT_copy(val_sub[i][0], generator))\n                goto err;\n        }\n        if (wsize[i] > 1) {\n            if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx))\n                goto err;\n            for (j = 1; j < ((size_t)1 << (wsize[i] - 1)); j++) {\n                if (!EC_POINT_add\n                    (group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx))\n                    goto err;\n            }\n        }\n    }\n    if (!EC_POINTs_make_affine(group, num_val, val, ctx))\n        goto err;\n    r_is_at_infinity = 1;\n    for (k = max_len - 1; k >= 0; k--) {\n        if (!r_is_at_infinity) {\n            if (!EC_POINT_dbl(group, r, r, ctx))\n                goto err;\n        }\n        for (i = 0; i < totalnum; i++) {\n            if (wNAF_len[i] > (size_t)k) {\n                int digit = wNAF[i][k];\n                int is_neg;\n                if (digit) {\n                    is_neg = digit < 0;\n                    if (is_neg)\n                        digit = -digit;\n                    if (is_neg != r_is_inverted) {\n                        if (!r_is_at_infinity) {\n                            if (!EC_POINT_invert(group, r, ctx))\n                                goto err;\n                        }\n                        r_is_inverted = !r_is_inverted;\n                    }\n                    if (r_is_at_infinity) {\n                        if (!EC_POINT_copy(r, val_sub[i][digit >> 1]))\n                            goto err;\n                        r_is_at_infinity = 0;\n                    } else {\n                        if (!EC_POINT_add\n                            (group, r, r, val_sub[i][digit >> 1], ctx))\n                            goto err;\n                    }\n                }\n            }\n        }\n    }\n    if (r_is_at_infinity) {\n        if (!EC_POINT_set_to_infinity(group, r))\n            goto err;\n    } else {\n        if (r_is_inverted)\n            if (!EC_POINT_invert(group, r, ctx))\n                goto err;\n    }\n    ret = 1;\n err:\n    BN_CTX_free(new_ctx);\n    EC_POINT_free(tmp);\n    OPENSSL_free(wsize);\n    OPENSSL_free(wNAF_len);\n    if (wNAF != NULL) {\n        signed char **w;\n        for (w = wNAF; *w != NULL; w++)\n            OPENSSL_free(*w);\n        OPENSSL_free(wNAF);\n    }\n    if (val != NULL) {\n        for (v = val; *v != NULL; v++)\n            EC_POINT_clear_free(*v);\n        OPENSSL_free(val);\n    }\n    OPENSSL_free(val_sub);\n    return ret;\n}', 'static int ec_mul_consttime(const EC_GROUP *group, EC_POINT *r,\n                            const BIGNUM *scalar, const EC_POINT *point,\n                            BN_CTX *ctx)\n{\n    int i, order_bits, group_top, kbit, pbit, Z_is_one;\n    EC_POINT *s = NULL;\n    BIGNUM *k = NULL;\n    BIGNUM *lambda = NULL;\n    BN_CTX *new_ctx = NULL;\n    int ret = 0;\n    if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL)\n        goto err;\n    if ((group->order == NULL) || (group->field == NULL))\n        goto err;\n    order_bits = BN_num_bits(group->order);\n    s = EC_POINT_new(group);\n    if (s == NULL)\n        goto err;\n    if (point == NULL) {\n        if (group->generator == NULL)\n            goto err;\n        if (!EC_POINT_copy(s, group->generator))\n            goto err;\n    } else {\n        if (!EC_POINT_copy(s, point))\n            goto err;\n    }\n    EC_POINT_BN_set_flags(s, BN_FLG_CONSTTIME);\n    BN_CTX_start(ctx);\n    lambda = BN_CTX_get(ctx);\n    k = BN_CTX_get(ctx);\n    if (k == NULL)\n        goto err;\n    group_top = bn_get_top(group->order);\n    if ((bn_wexpand(k, group_top + 1) == NULL)\n        || (bn_wexpand(lambda, group_top + 1) == NULL))\n        goto err;\n    if (!BN_copy(k, scalar))\n        goto err;\n    BN_set_flags(k, BN_FLG_CONSTTIME);\n    if ((BN_num_bits(k) > order_bits) || (BN_is_negative(k))) {\n        if (!BN_nnmod(k, k, group->order, ctx))\n            goto err;\n    }\n    if (!BN_add(lambda, k, group->order))\n        goto err;\n    BN_set_flags(lambda, BN_FLG_CONSTTIME);\n    if (!BN_add(k, lambda, group->order))\n        goto err;\n    kbit = BN_is_bit_set(lambda, order_bits);\n    BN_consttime_swap(kbit, k, lambda, group_top + 1);\n    group_top = bn_get_top(group->field);\n    if ((bn_wexpand(s->X, group_top) == NULL)\n        || (bn_wexpand(s->Y, group_top) == NULL)\n        || (bn_wexpand(s->Z, group_top) == NULL)\n        || (bn_wexpand(r->X, group_top) == NULL)\n        || (bn_wexpand(r->Y, group_top) == NULL)\n        || (bn_wexpand(r->Z, group_top) == NULL))\n        goto err;\n    if (!EC_POINT_copy(r, s))\n        goto err;\n    EC_POINT_BN_set_flags(r, BN_FLG_CONSTTIME);\n    if (!EC_POINT_dbl(group, s, s, ctx))\n        goto err;\n    pbit = 0;\n#define EC_POINT_CSWAP(c, a, b, w, t) do {         \\\n        BN_consttime_swap(c, (a)->X, (b)->X, w);   \\\n        BN_consttime_swap(c, (a)->Y, (b)->Y, w);   \\\n        BN_consttime_swap(c, (a)->Z, (b)->Z, w);   \\\n        t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \\\n        (a)->Z_is_one ^= (t);                      \\\n        (b)->Z_is_one ^= (t);                      \\\n} while(0)\n    for (i = order_bits - 1; i >= 0; i--) {\n        kbit = BN_is_bit_set(k, i) ^ pbit;\n        EC_POINT_CSWAP(kbit, r, s, group_top, Z_is_one);\n        if (!EC_POINT_add(group, s, r, s, ctx))\n            goto err;\n        if (!EC_POINT_dbl(group, r, r, ctx))\n            goto err;\n        pbit ^= kbit;\n    }\n    EC_POINT_CSWAP(pbit, r, s, group_top, Z_is_one);\n#undef EC_POINT_CSWAP\n    ret = 1;\n err:\n    EC_POINT_free(s);\n    BN_CTX_end(ctx);\n    BN_CTX_free(new_ctx);\n    return ret;\n}', 'BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)\n{\n    bn_check_top(b);\n    if (a == b)\n        return a;\n    if (bn_wexpand(a, b->top) == NULL)\n        return NULL;\n    if (b->top > 0)\n        memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);\n    a->top = b->top;\n    a->neg = b->neg;\n    bn_check_top(a);\n    return a;\n}', 'BIGNUM *bn_wexpand(BIGNUM *a, int words)\n{\n    return (words <= a->dmax) ? a : bn_expand2(a, words);\n}']