static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
{
    BN_ULONG *A, *a = NULL;
    const BN_ULONG *B;
    int i;
    bn_check_top(b);
    if (words > (INT_MAX / (4 * BN_BITS2))) {
        BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_BIGNUM_TOO_LONG);
        return NULL;
    }
    if (BN_get_flags(b, BN_FLG_STATIC_DATA)) {
        BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
        return (NULL);
    }
    if (BN_get_flags(b,BN_FLG_SECURE))
        a = A = OPENSSL_secure_zalloc(words * sizeof(*a));
    else
        a = A = OPENSSL_zalloc(words * sizeof(*a));
    if (A == NULL) {
        BNerr(BN_F_BN_EXPAND_INTERNAL, ERR_R_MALLOC_FAILURE);
        return (NULL);
    }
#if 1
    B = b->d;
    if (B != NULL) {
        for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) {
            BN_ULONG a0, a1, a2, a3;
            a0 = B[0];
            a1 = B[1];
            a2 = B[2];
            a3 = B[3];
            A[0] = a0;
            A[1] = a1;
            A[2] = a2;
            A[3] = a3;
        }
        switch (b->top & 3) {
        case 3:
            A[2] = B[2];
        case 2:
            A[1] = B[1];
        case 1:
            A[0] = B[0];
        case 0:
            ;
        }
    }
#else
    memset(A, 0, sizeof(*A) * words);
    memcpy(A, b->d, sizeof(b->d[0]) * b->top);
#endif
    return (a);
}
['int test_builtin(BIO *out)\n{\n    EC_builtin_curve *curves = NULL;\n    size_t crv_len = 0, n = 0;\n    EC_KEY *eckey = NULL, *wrong_eckey = NULL;\n    EC_GROUP *group;\n    ECDSA_SIG *ecdsa_sig = NULL, *modified_sig = NULL;\n    unsigned char digest[20], wrong_digest[20];\n    unsigned char *signature = NULL;\n    const unsigned char *sig_ptr;\n    unsigned char *sig_ptr2;\n    unsigned char *raw_buf = NULL;\n    const BIGNUM *sig_r, *sig_s;\n    BIGNUM *modified_r = NULL, *modified_s = NULL;\n    BIGNUM *unmodified_r = NULL, *unmodified_s = NULL;\n    unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len;\n    int nid, ret = 0;\n    if (RAND_bytes(digest, 20) <= 0 || RAND_bytes(wrong_digest, 20) <= 0) {\n        BIO_printf(out, "ERROR: unable to get random data\\n");\n        goto builtin_err;\n    }\n    BIO_printf(out, "\\ntesting ECDSA_sign() and ECDSA_verify() "\n               "with some internal curves:\\n");\n    crv_len = EC_get_builtin_curves(NULL, 0);\n    curves = OPENSSL_malloc(sizeof(*curves) * crv_len);\n    if (curves == NULL) {\n        BIO_printf(out, "malloc error\\n");\n        goto builtin_err;\n    }\n    if (!EC_get_builtin_curves(curves, crv_len)) {\n        BIO_printf(out, "unable to get internal curves\\n");\n        goto builtin_err;\n    }\n    for (n = 0; n < crv_len; n++) {\n        unsigned char dirt, offset;\n        nid = curves[n].nid;\n        if (nid == NID_ipsec4 || nid == NID_X25519)\n            continue;\n        if ((eckey = EC_KEY_new()) == NULL)\n            goto builtin_err;\n        group = EC_GROUP_new_by_curve_name(nid);\n        if (group == NULL)\n            goto builtin_err;\n        if (EC_KEY_set_group(eckey, group) == 0)\n            goto builtin_err;\n        EC_GROUP_free(group);\n        degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey));\n        if (degree < 160) {\n            EC_KEY_free(eckey);\n            eckey = NULL;\n            continue;\n        }\n        BIO_printf(out, "%s: ", OBJ_nid2sn(nid));\n        if (!EC_KEY_generate_key(eckey)) {\n            BIO_printf(out, " failed\\n");\n            goto builtin_err;\n        }\n        if ((wrong_eckey = EC_KEY_new()) == NULL)\n            goto builtin_err;\n        group = EC_GROUP_new_by_curve_name(nid);\n        if (group == NULL)\n            goto builtin_err;\n        if (EC_KEY_set_group(wrong_eckey, group) == 0)\n            goto builtin_err;\n        EC_GROUP_free(group);\n        if (!EC_KEY_generate_key(wrong_eckey)) {\n            BIO_printf(out, " failed\\n");\n            goto builtin_err;\n        }\n        BIO_printf(out, ".");\n        (void)BIO_flush(out);\n        if (!EC_KEY_check_key(eckey)) {\n            BIO_printf(out, " failed\\n");\n            goto builtin_err;\n        }\n        BIO_printf(out, ".");\n        (void)BIO_flush(out);\n        sig_len = ECDSA_size(eckey);\n        if ((signature = OPENSSL_malloc(sig_len)) == NULL)\n            goto builtin_err;\n        if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey)) {\n            BIO_printf(out, " failed\\n");\n            goto builtin_err;\n        }\n        BIO_printf(out, ".");\n        (void)BIO_flush(out);\n        if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) {\n            BIO_printf(out, " failed\\n");\n            goto builtin_err;\n        }\n        BIO_printf(out, ".");\n        (void)BIO_flush(out);\n        if (ECDSA_verify(0, digest, 20, signature, sig_len, wrong_eckey) == 1) {\n            BIO_printf(out, " failed\\n");\n            goto builtin_err;\n        }\n        BIO_printf(out, ".");\n        (void)BIO_flush(out);\n        if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len, eckey) == 1) {\n            BIO_printf(out, " failed\\n");\n            goto builtin_err;\n        }\n        BIO_printf(out, ".");\n        (void)BIO_flush(out);\n        if (ECDSA_verify(0, digest, 20, signature, sig_len - 1, eckey) == 1) {\n            BIO_printf(out, " failed\\n");\n            goto builtin_err;\n        }\n        BIO_printf(out, ".");\n        (void)BIO_flush(out);\n        sig_ptr = signature;\n        if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)) == NULL) {\n            BIO_printf(out, " failed\\n");\n            goto builtin_err;\n        }\n        ECDSA_SIG_get0(ecdsa_sig, &sig_r, &sig_s);\n        r_len = BN_num_bytes(sig_r);\n        s_len = BN_num_bytes(sig_s);\n        bn_len = (degree + 7) / 8;\n        if ((r_len > bn_len) || (s_len > bn_len)) {\n            BIO_printf(out, " failed\\n");\n            goto builtin_err;\n        }\n        buf_len = 2 * bn_len;\n        if ((raw_buf = OPENSSL_zalloc(buf_len)) == NULL)\n            goto builtin_err;\n        BN_bn2bin(sig_r, raw_buf + bn_len - r_len);\n        BN_bn2bin(sig_s, raw_buf + buf_len - s_len);\n        offset = raw_buf[10] % buf_len;\n        dirt = raw_buf[11] ? raw_buf[11] : 1;\n        raw_buf[offset] ^= dirt;\n        modified_sig = ECDSA_SIG_new();\n        if (modified_sig == NULL)\n            goto builtin_err;\n        if (((modified_r = BN_bin2bn(raw_buf, bn_len, NULL)) == NULL)\n            || ((modified_s = BN_bin2bn(raw_buf + bn_len, bn_len, NULL)) == NULL)\n            || !ECDSA_SIG_set0(modified_sig, modified_r, modified_s)) {\n            BN_free(modified_r);\n            BN_free(modified_s);\n            goto builtin_err;\n        }\n        sig_ptr2 = signature;\n        sig_len = i2d_ECDSA_SIG(modified_sig, &sig_ptr2);\n        if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1) {\n            BIO_printf(out, " failed\\n");\n            goto builtin_err;\n        }\n        raw_buf[offset] ^= dirt;\n        if (((unmodified_r = BN_bin2bn(raw_buf, bn_len, NULL)) == NULL)\n            || ((unmodified_s = BN_bin2bn(raw_buf + bn_len, bn_len, NULL)) == NULL)\n            || !ECDSA_SIG_set0(modified_sig, unmodified_r, unmodified_s)) {\n            BN_free(unmodified_r);\n            BN_free(unmodified_s);\n            goto builtin_err;\n        }\n        sig_ptr2 = signature;\n        sig_len = i2d_ECDSA_SIG(modified_sig, &sig_ptr2);\n        if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) {\n            BIO_printf(out, " failed\\n");\n            goto builtin_err;\n        }\n        BIO_printf(out, ".");\n        (void)BIO_flush(out);\n        BIO_printf(out, " ok\\n");\n        ERR_clear_error();\n        OPENSSL_free(signature);\n        signature = NULL;\n        EC_KEY_free(eckey);\n        eckey = NULL;\n        EC_KEY_free(wrong_eckey);\n        wrong_eckey = NULL;\n        ECDSA_SIG_free(ecdsa_sig);\n        ecdsa_sig = NULL;\n        ECDSA_SIG_free(modified_sig);\n        modified_sig = NULL;\n        OPENSSL_free(raw_buf);\n        raw_buf = NULL;\n    }\n    ret = 1;\n builtin_err:\n    EC_KEY_free(eckey);\n    EC_KEY_free(wrong_eckey);\n    ECDSA_SIG_free(ecdsa_sig);\n    ECDSA_SIG_free(modified_sig);\n    OPENSSL_free(signature);\n    OPENSSL_free(raw_buf);\n    OPENSSL_free(curves);\n    return ret;\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}', 'BIGNUM *bn_wexpand(BIGNUM *a, int words)\n{\n    return (words <= a->dmax) ? a : bn_expand2(a, words);\n}', 'BIGNUM *bn_expand2(BIGNUM *b, int words)\n{\n    bn_check_top(b);\n    if (words > b->dmax) {\n        BN_ULONG *a = bn_expand_internal(b, words);\n        if (!a)\n            return NULL;\n        if (b->d) {\n            OPENSSL_cleanse(b->d, b->dmax * sizeof(b->d[0]));\n            bn_free_d(b);\n        }\n        b->d = a;\n        b->dmax = words;\n    }\n    bn_check_top(b);\n    return b;\n}', 'static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)\n{\n    BN_ULONG *A, *a = NULL;\n    const BN_ULONG *B;\n    int i;\n    bn_check_top(b);\n    if (words > (INT_MAX / (4 * BN_BITS2))) {\n        BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_BIGNUM_TOO_LONG);\n        return NULL;\n    }\n    if (BN_get_flags(b, BN_FLG_STATIC_DATA)) {\n        BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);\n        return (NULL);\n    }\n    if (BN_get_flags(b,BN_FLG_SECURE))\n        a = A = OPENSSL_secure_zalloc(words * sizeof(*a));\n    else\n        a = A = OPENSSL_zalloc(words * sizeof(*a));\n    if (A == NULL) {\n        BNerr(BN_F_BN_EXPAND_INTERNAL, ERR_R_MALLOC_FAILURE);\n        return (NULL);\n    }\n#if 1\n    B = b->d;\n    if (B != NULL) {\n        for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) {\n            BN_ULONG a0, a1, a2, a3;\n            a0 = B[0];\n            a1 = B[1];\n            a2 = B[2];\n            a3 = B[3];\n            A[0] = a0;\n            A[1] = a1;\n            A[2] = a2;\n            A[3] = a3;\n        }\n        switch (b->top & 3) {\n        case 3:\n            A[2] = B[2];\n        case 2:\n            A[1] = B[1];\n        case 1:\n            A[0] = B[0];\n        case 0:\n            ;\n        }\n    }\n#else\n    memset(A, 0, sizeof(*A) * words);\n    memcpy(A, b->d, sizeof(b->d[0]) * b->top);\n#endif\n    return (a);\n}']