test/ectest.c:1320: error: BUFFER_OVERRUN_L3
  Offset: [0, 3] Size: [0, +oo] by call to `EC_POINTs_mul`.
Showing all 8 steps of the trace


test/ectest.c:1320:14: Call
1318.           scalars[2] = z;         /* z = -(x+y) */
1319.   
1320.           if (!EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx))
                     ^
1321.               ABORT;
1322.           if (!EC_POINT_is_at_infinity(group, P))

crypto/ec/ec_lib.c:1010:1: Parameter `num`
  1008.    */
  1009.   
  1010. > int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
  1011.                     size_t num, const EC_POINT *points[],
  1012.                     const BIGNUM *scalars[], BN_CTX *ctx)

crypto/ec/ec_lib.c:1016:16: Call
  1014.       if (group->meth->mul == 0)
  1015.           /* use default */
  1016.           return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
                         ^
  1017.   
  1018.       return group->meth->mul(group, r, scalar, num, points, scalars, ctx);

crypto/ec/ec_mult.c:193:1: Parameter `num`
    191.    * in the addition if scalar != NULL
    192.    */
    193. > int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
    194.                   size_t num, const EC_POINT *points[], const BIGNUM *scalars[],
    195.                   BN_CTX *ctx)

crypto/ec/ec_mult.c:320:13: Call
    318.           wNAF[i + 1] = NULL;     /* make sure we always have a pivot */
    319.           wNAF[i] =
    320.               bn_compute_wNAF((i < num ? scalars[i] : scalar), wsize[i],
                       ^
    321.                               &wNAF_len[i]);
    322.           if (wNAF[i] == NULL)

crypto/bn/bn_intern.c:67:1: <Length trace>
65.    * w-1 zeros away from that next non-zero digit.
66.    */
67. > signed char *bn_compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
68.   {
69.       int window_val;

crypto/bn/bn_intern.c:67:1: Parameter `*ret_len`
      65.    * w-1 zeros away from that next non-zero digit.
      66.    */
      67. > signed char *bn_compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
      68.   {
      69.       int window_val;

crypto/bn/bn_intern.c:82:9: Array access: Offset: [0, 3] Size: [0, +oo] by call to `EC_POINTs_mul` 
      80.           }
      81.           r[0] = 0;
      82.           *ret_len = 1;
                    ^
      83.           return r;
      84.       }

signed char *bn_compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)
{
    int window_val;
    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 == NULL) {
            BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
            goto err;
        }
        r[0] = 0;
        *ret_len = 1;
        return r;
    }
    if (w <= 0 || w > 7) {
        BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
        goto err;
    }
    bit = 1 << w;
    next_bit = bit << 1;
    mask = next_bit - 1;
    if (BN_is_negative(scalar)) {
        sign = -1;
    }
    if (scalar->d == NULL || scalar->top == 0) {
        BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
        goto err;
    }
    len = BN_num_bits(scalar);
    r = OPENSSL_malloc(len + 1);
    if (r == NULL) {
        BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    window_val = scalar->d[0] & mask;
    j = 0;
    while ((window_val != 0) || (j + w + 1 < len)) {
        int digit = 0;
        if (window_val & 1) {
            if (window_val & bit) {
                digit = window_val - next_bit;
#if 1
                if (j + w + 1 >= len) {
                    digit = window_val & (mask >> 1);
                }
#endif
            } else {
                digit = window_val;
            }
            if (digit <= -bit || digit >= bit || !(digit & 1)) {
                BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
                goto err;
            }
            window_val -= digit;
            if (window_val != 0 && window_val != next_bit
                && window_val != bit) {
                BNerr(BN_F_BN_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) {
            BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
            goto err;
        }
    }
    if (j > len + 1) {
        BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);
        goto err;
    }
    *ret_len = j;
    return r;
 err:
    OPENSSL_free(r);
    return NULL;
}
['static void char2_field_tests(void)\n{\n    BN_CTX *ctx = NULL;\n    BIGNUM *p, *a, *b;\n    EC_GROUP *group;\n    EC_GROUP *C2_K163 = NULL, *C2_K233 = NULL, *C2_K283 = NULL, *C2_K409 =\n        NULL, *C2_K571 = NULL;\n    EC_GROUP *C2_B163 = NULL, *C2_B233 = NULL, *C2_B283 = NULL, *C2_B409 =\n        NULL, *C2_B571 = NULL;\n    EC_POINT *P, *Q, *R;\n    BIGNUM *x, *y, *z, *cof;\n    unsigned char buf[100];\n    size_t i, len;\n    int k;\n    ctx = BN_CTX_new();\n    if (!ctx)\n        ABORT;\n    p = BN_new();\n    a = BN_new();\n    b = BN_new();\n    if (!p || !a || !b)\n        ABORT;\n    if (!BN_hex2bn(&p, "13"))\n        ABORT;\n    if (!BN_hex2bn(&a, "3"))\n        ABORT;\n    if (!BN_hex2bn(&b, "1"))\n        ABORT;\n    group = EC_GROUP_new(EC_GF2m_simple_method());\n    if (!group)\n        ABORT;\n    if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx))\n        ABORT;\n    {\n        EC_GROUP *tmp;\n        tmp = EC_GROUP_new(EC_GROUP_method_of(group));\n        if (!tmp)\n            ABORT;\n        if (!EC_GROUP_copy(tmp, group))\n            ABORT;\n        EC_GROUP_free(group);\n        group = tmp;\n    }\n    if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx))\n        ABORT;\n    fprintf(stdout,\n            "Curve defined by Weierstrass equation\\n     y^2 + x*y = x^3 + a*x^2 + b  (mod 0x");\n    BN_print_fp(stdout, p);\n    fprintf(stdout, ")\\n     a = 0x");\n    BN_print_fp(stdout, a);\n    fprintf(stdout, "\\n     b = 0x");\n    BN_print_fp(stdout, b);\n    fprintf(stdout, "\\n(0x... means binary polynomial)\\n");\n    P = EC_POINT_new(group);\n    Q = EC_POINT_new(group);\n    R = EC_POINT_new(group);\n    if (!P || !Q || !R)\n        ABORT;\n    if (!EC_POINT_set_to_infinity(group, P))\n        ABORT;\n    if (!EC_POINT_is_at_infinity(group, P))\n        ABORT;\n    buf[0] = 0;\n    if (!EC_POINT_oct2point(group, Q, buf, 1, ctx))\n        ABORT;\n    if (!EC_POINT_add(group, P, P, Q, ctx))\n        ABORT;\n    if (!EC_POINT_is_at_infinity(group, P))\n        ABORT;\n    x = BN_new();\n    y = BN_new();\n    z = BN_new();\n    cof = BN_new();\n    if (!x || !y || !z || !cof)\n        ABORT;\n    if (!BN_hex2bn(&x, "6"))\n        ABORT;\n#  ifdef OPENSSL_EC_BIN_PT_COMP\n    if (!EC_POINT_set_compressed_coordinates_GF2m(group, Q, x, 1, ctx))\n        ABORT;\n#  else\n    if (!BN_hex2bn(&y, "8"))\n        ABORT;\n    if (!EC_POINT_set_affine_coordinates_GF2m(group, Q, x, y, ctx))\n        ABORT;\n#  endif\n    if (EC_POINT_is_on_curve(group, Q, ctx) <= 0) {\n#  ifdef OPENSSL_EC_BIN_PT_COMP\n        if (!EC_POINT_get_affine_coordinates_GF2m(group, Q, x, y, ctx))\n            ABORT;\n#  endif\n        fprintf(stderr, "Point is not on curve: x = 0x");\n        BN_print_fp(stderr, x);\n        fprintf(stderr, ", y = 0x");\n        BN_print_fp(stderr, y);\n        fprintf(stderr, "\\n");\n        ABORT;\n    }\n    fprintf(stdout, "A cyclic subgroup:\\n");\n    k = 100;\n    do {\n        if (k-- == 0)\n            ABORT;\n        if (EC_POINT_is_at_infinity(group, P))\n            fprintf(stdout, "     point at infinity\\n");\n        else {\n            if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx))\n                ABORT;\n            fprintf(stdout, "     x = 0x");\n            BN_print_fp(stdout, x);\n            fprintf(stdout, ", y = 0x");\n            BN_print_fp(stdout, y);\n            fprintf(stdout, "\\n");\n        }\n        if (!EC_POINT_copy(R, P))\n            ABORT;\n        if (!EC_POINT_add(group, P, P, Q, ctx))\n            ABORT;\n    }\n    while (!EC_POINT_is_at_infinity(group, P));\n    if (!EC_POINT_add(group, P, Q, R, ctx))\n        ABORT;\n    if (!EC_POINT_is_at_infinity(group, P))\n        ABORT;\n#  ifdef OPENSSL_EC_BIN_PT_COMP\n    len =\n        EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf,\n                           sizeof buf, ctx);\n    if (len == 0)\n        ABORT;\n    if (!EC_POINT_oct2point(group, P, buf, len, ctx))\n        ABORT;\n    if (0 != EC_POINT_cmp(group, P, Q, ctx))\n        ABORT;\n    fprintf(stdout, "Generator as octet string, compressed form:\\n     ");\n    for (i = 0; i < len; i++)\n        fprintf(stdout, "%02X", buf[i]);\n#  endif\n    len =\n        EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf,\n                           sizeof buf, ctx);\n    if (len == 0)\n        ABORT;\n    if (!EC_POINT_oct2point(group, P, buf, len, ctx))\n        ABORT;\n    if (0 != EC_POINT_cmp(group, P, Q, ctx))\n        ABORT;\n    fprintf(stdout, "\\nGenerator as octet string, uncompressed form:\\n     ");\n    for (i = 0; i < len; i++)\n        fprintf(stdout, "%02X", buf[i]);\n#  ifdef OPENSSL_EC_BIN_PT_COMP\n    len =\n        EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf,\n                           ctx);\n    if (len == 0)\n        ABORT;\n    if (!EC_POINT_oct2point(group, P, buf, len, ctx))\n        ABORT;\n    if (0 != EC_POINT_cmp(group, P, Q, ctx))\n        ABORT;\n    fprintf(stdout, "\\nGenerator as octet string, hybrid form:\\n     ");\n    for (i = 0; i < len; i++)\n        fprintf(stdout, "%02X", buf[i]);\n#  endif\n    fprintf(stdout, "\\n");\n    if (!EC_POINT_invert(group, P, ctx))\n        ABORT;\n    if (0 != EC_POINT_cmp(group, P, R, ctx))\n        ABORT;\n    CHAR2_CURVE_TEST\n        ("NIST curve K-163",\n         "0800000000000000000000000000000000000000C9",\n         "1",\n         "1",\n         "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8",\n         "0289070FB05D38FF58321F2E800536D538CCDAA3D9",\n         1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163, C2_K163);\n    CHAR2_CURVE_TEST\n        ("NIST curve B-163",\n         "0800000000000000000000000000000000000000C9",\n         "1",\n         "020A601907B8C953CA1481EB10512F78744A3205FD",\n         "03F0EBA16286A2D57EA0991168D4994637E8343E36",\n         "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1",\n         1, "040000000000000000000292FE77E70C12A4234C33", "2", 163, C2_B163);\n    CHAR2_CURVE_TEST\n        ("NIST curve K-233",\n         "020000000000000000000000000000000000000004000000000000000001",\n         "0",\n         "1",\n         "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126",\n         "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3",\n         0,\n         "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF",\n         "4", 233, C2_K233);\n    CHAR2_CURVE_TEST\n        ("NIST curve B-233",\n         "020000000000000000000000000000000000000004000000000000000001",\n         "000000000000000000000000000000000000000000000000000000000001",\n         "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD",\n         "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B",\n         "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052",\n         1,\n         "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7",\n         "2", 233, C2_B233);\n    CHAR2_CURVE_TEST\n        ("NIST curve K-283",\n         "0800000000000000000000000000000000000000000000000000000000000000000010A1",\n         "0",\n         "1",\n         "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836",\n         "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259",\n         0,\n         "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61",\n         "4", 283, C2_K283);\n    CHAR2_CURVE_TEST\n        ("NIST curve B-283",\n         "0800000000000000000000000000000000000000000000000000000000000000000010A1",\n         "000000000000000000000000000000000000000000000000000000000000000000000001",\n         "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5",\n         "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053",\n         "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4",\n         1,\n         "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307",\n         "2", 283, C2_B283);\n    CHAR2_CURVE_TEST\n        ("NIST curve K-409",\n         "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",\n         "0",\n         "1",\n         "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746",\n         "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B",\n         1,\n         "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF",\n         "4", 409, C2_K409);\n    CHAR2_CURVE_TEST\n        ("NIST curve B-409",\n         "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001",\n         "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",\n         "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F",\n         "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7",\n         "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706",\n         1,\n         "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173",\n         "2", 409, C2_B409);\n    CHAR2_CURVE_TEST\n        ("NIST curve K-571",\n         "80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",\n         "0",\n         "1",\n         "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972",\n         "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3",\n         0,\n         "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001",\n         "4", 571, C2_K571);\n    CHAR2_CURVE_TEST\n        ("NIST curve B-571",\n         "80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425",\n         "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",\n         "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A",\n         "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19",\n         "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B",\n         1,\n         "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47",\n         "2", 571, C2_B571);\n    if (!EC_POINT_copy(Q, P))\n        ABORT;\n    if (EC_POINT_is_at_infinity(group, Q))\n        ABORT;\n    if (!EC_POINT_dbl(group, P, P, ctx))\n        ABORT;\n    if (EC_POINT_is_on_curve(group, P, ctx) <= 0)\n        ABORT;\n    if (!EC_POINT_invert(group, Q, ctx))\n        ABORT;\n    if (!EC_POINT_add(group, R, P, Q, ctx))\n        ABORT;\n    if (!EC_POINT_add(group, R, R, Q, ctx))\n        ABORT;\n    if (!EC_POINT_is_at_infinity(group, R))\n        ABORT;\n    {\n        const EC_POINT *points[3];\n        const BIGNUM *scalars[3];\n        if (EC_POINT_is_at_infinity(group, Q))\n            ABORT;\n        points[0] = Q;\n        points[1] = Q;\n        points[2] = Q;\n        if (!BN_add(y, z, BN_value_one()))\n            ABORT;\n        if (BN_is_odd(y))\n            ABORT;\n        if (!BN_rshift1(y, y))\n            ABORT;\n        scalars[0] = y;\n        scalars[1] = y;\n        fprintf(stdout, "combined multiplication ...");\n        fflush(stdout);\n        if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))\n            ABORT;\n        if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))\n            ABORT;\n        if (0 != EC_POINT_cmp(group, P, R, ctx))\n            ABORT;\n        if (0 != EC_POINT_cmp(group, R, Q, ctx))\n            ABORT;\n        fprintf(stdout, ".");\n        fflush(stdout);\n        if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0))\n            ABORT;\n        if (!BN_add(z, z, y))\n            ABORT;\n        BN_set_negative(z, 1);\n        scalars[0] = y;\n        scalars[1] = z;\n        if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))\n            ABORT;\n        if (!EC_POINT_is_at_infinity(group, P))\n            ABORT;\n        fprintf(stdout, ".");\n        fflush(stdout);\n        if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0))\n            ABORT;\n        if (!BN_add(z, x, y))\n            ABORT;\n        BN_set_negative(z, 1);\n        scalars[0] = x;\n        scalars[1] = y;\n        scalars[2] = z;\n        if (!EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx))\n            ABORT;\n        if (!EC_POINT_is_at_infinity(group, P))\n            ABORT;\n        fprintf(stdout, " ok\\n\\n");\n    }\n    BN_CTX_free(ctx);\n    BN_free(p);\n    BN_free(a);\n    BN_free(b);\n    EC_GROUP_free(group);\n    EC_POINT_free(P);\n    EC_POINT_free(Q);\n    EC_POINT_free(R);\n    BN_free(x);\n    BN_free(y);\n    BN_free(z);\n    BN_free(cof);\n    EC_GROUP_free(C2_K163);\n    EC_GROUP_free(C2_B163);\n    EC_GROUP_free(C2_K233);\n    EC_GROUP_free(C2_B233);\n    EC_GROUP_free(C2_K283);\n    EC_GROUP_free(C2_B283);\n    EC_GROUP_free(C2_K409);\n    EC_GROUP_free(C2_B409);\n    EC_GROUP_free(C2_K571);\n    EC_GROUP_free(C2_B571);\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 (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 =\n            EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup,\n                                ec_pre_comp_free, ec_pre_comp_clear_free);\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                if (tmp_len > max_len)\n                    max_len = 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                        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                            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}', 'signed char *bn_compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len)\n{\n    int window_val;\n    signed char *r = NULL;\n    int sign = 1;\n    int bit, next_bit, mask;\n    size_t len = 0, j;\n    if (BN_is_zero(scalar)) {\n        r = OPENSSL_malloc(1);\n        if (r == NULL) {\n            BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);\n            goto err;\n        }\n        r[0] = 0;\n        *ret_len = 1;\n        return r;\n    }\n    if (w <= 0 || w > 7) {\n        BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);\n        goto err;\n    }\n    bit = 1 << w;\n    next_bit = bit << 1;\n    mask = next_bit - 1;\n    if (BN_is_negative(scalar)) {\n        sign = -1;\n    }\n    if (scalar->d == NULL || scalar->top == 0) {\n        BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);\n        goto err;\n    }\n    len = BN_num_bits(scalar);\n    r = OPENSSL_malloc(len + 1);\n    if (r == NULL) {\n        BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE);\n        goto err;\n    }\n    window_val = scalar->d[0] & mask;\n    j = 0;\n    while ((window_val != 0) || (j + w + 1 < len)) {\n        int digit = 0;\n        if (window_val & 1) {\n            if (window_val & bit) {\n                digit = window_val - next_bit;\n#if 1\n                if (j + w + 1 >= len) {\n                    digit = window_val & (mask >> 1);\n                }\n#endif\n            } else {\n                digit = window_val;\n            }\n            if (digit <= -bit || digit >= bit || !(digit & 1)) {\n                BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);\n                goto err;\n            }\n            window_val -= digit;\n            if (window_val != 0 && window_val != next_bit\n                && window_val != bit) {\n                BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);\n                goto err;\n            }\n        }\n        r[j++] = sign * digit;\n        window_val >>= 1;\n        window_val += bit * BN_is_bit_set(scalar, j + w);\n        if (window_val > next_bit) {\n            BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);\n            goto err;\n        }\n    }\n    if (j > len + 1) {\n        BNerr(BN_F_BN_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR);\n        goto err;\n    }\n    *ret_len = j;\n    return r;\n err:\n    OPENSSL_free(r);\n    return NULL;\n}']