test/sm2_internal_test.c:292: error: BUFFER_OVERRUN_L3
  Offset added: [8, +oo] Size: [0, 536870848] by call to `EC_POINT_mul`.
Showing all 19 steps of the trace


test/sm2_internal_test.c:281:10: Call
279.       BIGNUM *s = NULL;
280.   
281.       if (!TEST_true(BN_hex2bn(&priv, privkey_hex)))
                ^
282.           goto done;
283.   

crypto/bn/bn_print.c:166:5: Assignment
  164.       j = i;                      /* least significant 'hex' */
  165.       m = 0;
  166.       h = 0;
             ^
  167.       while (j > 0) {
  168.           m = (BN_BYTES * 2 <= j) ? BN_BYTES * 2 : j;

crypto/bn/bn_print.c:184:5: Assignment
  182.           j -= BN_BYTES * 2;
  183.       }
  184.       ret->top = h;
             ^
  185.       bn_correct_top(ret);
  186.   

test/sm2_internal_test.c:292:17: Call
290.       pt = EC_POINT_new(group);
291.       if (!TEST_ptr(pt)
292.               || !TEST_true(EC_POINT_mul(group, pt, priv, NULL, NULL, NULL))
                       ^
293.               || !TEST_true(EC_KEY_set_public_key(key, pt)))
294.           goto done;

crypto/ec/ec_lib.c:929:1: Parameter `g_scalar->top`
  927.   }
  928.   
  929. > int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar,
  930.                    const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx)
  931.   {

crypto/ec/ec_lib.c:940:12: Call
  938.       scalars[0] = p_scalar;
  939.   
  940.       return EC_POINTs_mul(group, r, g_scalar,
                    ^
  941.                            (point != NULL
  942.                             && p_scalar != NULL), points, scalars, ctx);

crypto/ec/ec_lib.c:918:1: Parameter `scalar->top`
    916.    */
    917.   
    918. > int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
    919.                     size_t num, const EC_POINT *points[],
    920.                     const BIGNUM *scalars[], BN_CTX *ctx)

crypto/ec/ec_lib.c:924:16: Call
    922.       if (group->meth->mul == 0)
    923.           /* use default */
    924.           return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);
                          ^
    925.   
    926.       return group->meth->mul(group, r, scalar, num, points, scalars, ctx);

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

crypto/ec/ec_mult.c:406:20: Call
      404.                * constant time version.
      405.                */
      406.               return ec_mul_consttime(group, r, scalar, NULL, ctx);
                                ^
      407.           }
      408.           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:180:10: Call
        178.           goto err;
        179.   
        180.       if (!BN_copy(k, scalar))
                        ^
        181.           goto err;
        182.   

crypto/bn/bn_lib.c:280:1: <Offset trace>
278.   }
279.   
280. > BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
281.   {
282.       bn_check_top(b);

crypto/bn/bn_lib.c:280:1: Parameter `b->top`
          278.   }
          279.   
          280. > BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
          281.   {
          282.       bn_check_top(b);

crypto/bn/bn_lib.c:280:1: <Length trace>
278.   }
279.   
280. > BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
281.   {
282.       bn_check_top(b);

crypto/bn/bn_lib.c:280:1: Parameter `*a->d`
          278.   }
          279.   
          280. > BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
          281.   {
          282.       bn_check_top(b);

crypto/bn/bn_lib.c:286:9: Call
          284.       if (a == b)
          285.           return a;
          286.       if (bn_wexpand(a, b->top) == NULL)
                         ^
          287.           return NULL;
          288.   

crypto/bn/bn_lib.c:942:1: Parameter `*a->d`
            940.   }
            941.   
            942. > BIGNUM *bn_wexpand(BIGNUM *a, int words)
            943.   {
            944.       return (words <= a->dmax) ? a : bn_expand2(a, words);

crypto/bn/bn_lib.c:290:9: Array access: Offset added: [8, +oo] Size: [0, 536870848] by call to `EC_POINT_mul` 
          288.   
          289.       if (b->top > 0)
          290.           memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);
                         ^
          291.   
          292.       a->neg = b->neg;

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->neg = b->neg;
    a->top = b->top;
    a->flags |= b->flags & BN_FLG_FIXED_TOP;
    bn_check_top(a);
    return a;
}
['static int test_sm2_sign(const EC_GROUP *group,\n                         const char *userid,\n                         const char *privkey_hex,\n                         const char *message,\n                         const char *k_hex,\n                         const char *r_hex,\n                         const char *s_hex)\n{\n    const size_t msg_len = strlen(message);\n    int ok = 0;\n    BIGNUM *priv = NULL;\n    EC_POINT *pt = NULL;\n    EC_KEY *key = NULL;\n    ECDSA_SIG *sig = NULL;\n    const BIGNUM *sig_r = NULL;\n    const BIGNUM *sig_s = NULL;\n    BIGNUM *r = NULL;\n    BIGNUM *s = NULL;\n    if (!TEST_true(BN_hex2bn(&priv, privkey_hex)))\n        goto done;\n    key = EC_KEY_new();\n    if (!TEST_ptr(key)\n            || !TEST_true(EC_KEY_set_group(key, group))\n            || !TEST_true(EC_KEY_set_private_key(key, priv)))\n        goto done;\n    pt = EC_POINT_new(group);\n    if (!TEST_ptr(pt)\n            || !TEST_true(EC_POINT_mul(group, pt, priv, NULL, NULL, NULL))\n            || !TEST_true(EC_KEY_set_public_key(key, pt)))\n        goto done;\n    start_fake_rand(k_hex);\n    sig = sm2_do_sign(key, EVP_sm3(), userid, (const uint8_t *)message, msg_len);\n    if (!TEST_ptr(sig)\n            || !TEST_size_t_eq(fake_rand_bytes_offset, fake_rand_size)) {\n        restore_rand();\n        goto done;\n    }\n    restore_rand();\n    ECDSA_SIG_get0(sig, &sig_r, &sig_s);\n    if (!TEST_true(BN_hex2bn(&r, r_hex))\n            || !TEST_true(BN_hex2bn(&s, s_hex))\n            || !TEST_BN_eq(r, sig_r)\n            || !TEST_BN_eq(s, sig_s))\n        goto done;\n    ok = sm2_do_verify(key, EVP_sm3(), sig, userid, (const uint8_t *)message,\n                       msg_len);\n    TEST_true(ok);\n done:\n    ECDSA_SIG_free(sig);\n    EC_POINT_free(pt);\n    EC_KEY_free(key);\n    BN_free(priv);\n    BN_free(r);\n    BN_free(s);\n    return ok;\n}', "int BN_hex2bn(BIGNUM **bn, const char *a)\n{\n    BIGNUM *ret = NULL;\n    BN_ULONG l = 0;\n    int neg = 0, h, m, i, j, k, c;\n    int num;\n    if (a == NULL || *a == '\\0')\n        return 0;\n    if (*a == '-') {\n        neg = 1;\n        a++;\n    }\n    for (i = 0; i <= INT_MAX / 4 && ossl_isxdigit(a[i]); i++)\n        continue;\n    if (i == 0 || i > INT_MAX / 4)\n        goto err;\n    num = i + neg;\n    if (bn == NULL)\n        return num;\n    if (*bn == NULL) {\n        if ((ret = BN_new()) == NULL)\n            return 0;\n    } else {\n        ret = *bn;\n        BN_zero(ret);\n    }\n    if (bn_expand(ret, i * 4) == NULL)\n        goto err;\n    j = i;\n    m = 0;\n    h = 0;\n    while (j > 0) {\n        m = (BN_BYTES * 2 <= j) ? BN_BYTES * 2 : j;\n        l = 0;\n        for (;;) {\n            c = a[j - m];\n            k = OPENSSL_hexchar2int(c);\n            if (k < 0)\n                k = 0;\n            l = (l << 4) | k;\n            if (--m <= 0) {\n                ret->d[h++] = l;\n                break;\n            }\n        }\n        j -= BN_BYTES * 2;\n    }\n    ret->top = h;\n    bn_correct_top(ret);\n    *bn = ret;\n    bn_check_top(ret);\n    if (ret->top != 0)\n        ret->neg = neg;\n    return num;\n err:\n    if (*bn == NULL)\n        BN_free(ret);\n    return 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 (!ec_point_is_compat(r, group)) {\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    if (!BN_is_zero(group->order) && !BN_is_zero(group->cofactor)) {\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    }\n    for (i = 0; i < num; i++) {\n        if (!ec_point_is_compat(points[i], group)) {\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, cardinality_bits, group_top, kbit, pbit, Z_is_one;\n    EC_POINT *s = NULL;\n    BIGNUM *k = NULL;\n    BIGNUM *lambda = NULL;\n    BIGNUM *cardinality = NULL;\n    BN_CTX *new_ctx = NULL;\n    int ret = 0;\n    if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL)\n        return 0;\n    BN_CTX_start(ctx);\n    s = EC_POINT_new(group);\n    if (s == NULL)\n        goto err;\n    if (point == NULL) {\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    cardinality = BN_CTX_get(ctx);\n    lambda = BN_CTX_get(ctx);\n    k = BN_CTX_get(ctx);\n    if (k == NULL || !BN_mul(cardinality, group->order, group->cofactor, ctx))\n        goto err;\n    cardinality_bits = BN_num_bits(cardinality);\n    group_top = bn_get_top(cardinality);\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) > cardinality_bits) || (BN_is_negative(k))) {\n        if (!BN_nnmod(k, k, cardinality, ctx))\n            goto err;\n    }\n    if (!BN_add(lambda, k, cardinality))\n        goto err;\n    BN_set_flags(lambda, BN_FLG_CONSTTIME);\n    if (!BN_add(k, lambda, cardinality))\n        goto err;\n    kbit = BN_is_bit_set(lambda, cardinality_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_blind_coordinates(group, s, ctx))\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 = cardinality_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->neg = b->neg;\n    a->top = b->top;\n    a->flags |= b->flags & BN_FLG_FIXED_TOP;\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}']