void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)
{
    int i, j, max;
    const BN_ULONG *ap;
    BN_ULONG *rp;
    max = n * 2;
    ap = a;
    rp = r;
    rp[0] = rp[max - 1] = 0;
    rp++;
    j = n;
    if (--j > 0) {
        ap++;
        rp[j] = bn_mul_words(rp, ap, j, ap[-1]);
        rp += 2;
    }
    for (i = n - 2; i > 0; i--) {
        j--;
        ap++;
        rp[j] = bn_mul_add_words(rp, ap, j, ap[-1]);
        rp += 2;
    }
    bn_add_words(r, r, r, max);
    bn_sqr_words(tmp, a, n);
    bn_add_words(r, r, tmp, max);
}
['static int test_rsa_mp(void)\n{\n    int ret = 0;\n    RSA *key;\n    unsigned char ptext[256];\n    unsigned char ctext[256];\n    static unsigned char ptext_ex[] = "\\x54\\x85\\x9b\\x34\\x2c\\x49\\xea\\x2a";\n    int plen;\n    int clen = 0;\n    int num;\n    plen = sizeof(ptext_ex) - 1;\n    key = RSA_new();\n    if (!TEST_ptr(key))\n        goto err;\n    clen = key2048p3(key);\n    if (!TEST_int_eq(clen, 256))\n        goto err;\n    if (!TEST_true(RSA_check_key_ex(key, NULL)))\n        goto err;\n    num = RSA_public_encrypt(plen, ptext_ex, ctext, key,\n                             RSA_PKCS1_PADDING);\n    if (!TEST_int_eq(num, clen))\n        goto err;\n    num = RSA_private_decrypt(num, ctext, ptext, key, RSA_PKCS1_PADDING);\n    if (!TEST_mem_eq(ptext, num, ptext_ex, plen))\n        goto err;\n    ret = 1;\nerr:\n    RSA_free(key);\n    return ret;\n}', 'static int key2048p3(RSA *key)\n{\n    static const unsigned char n[] =\n        "\\x92\\x60\\xd0\\x75\\x0a\\xe1\\x17\\xee\\xe5\\x5c\\x3f\\x3d\\xea\\xba\\x74\\x91"\n        "\\x75\\x21\\xa2\\x62\\xee\\x76\\x00\\x7c\\xdf\\x8a\\x56\\x75\\x5a\\xd7\\x3a\\x15"\n        "\\x98\\xa1\\x40\\x84\\x10\\xa0\\x14\\x34\\xc3\\xf5\\xbc\\x54\\xa8\\x8b\\x57\\xfa"\n        "\\x19\\xfc\\x43\\x28\\xda\\xea\\x07\\x50\\xa4\\xc4\\x4e\\x88\\xcf\\xf3\\xb2\\x38"\n        "\\x26\\x21\\xb8\\x0f\\x67\\x04\\x64\\x43\\x3e\\x43\\x36\\xe6\\xd0\\x03\\xe8\\xcd"\n        "\\x65\\xbf\\xf2\\x11\\xda\\x14\\x4b\\x88\\x29\\x1c\\x22\\x59\\xa0\\x0a\\x72\\xb7"\n        "\\x11\\xc1\\x16\\xef\\x76\\x86\\xe8\\xfe\\xe3\\x4e\\x4d\\x93\\x3c\\x86\\x81\\x87"\n        "\\xbd\\xc2\\x6f\\x7b\\xe0\\x71\\x49\\x3c\\x86\\xf7\\xa5\\x94\\x1c\\x35\\x10\\x80"\n        "\\x6a\\xd6\\x7b\\x0f\\x94\\xd8\\x8f\\x5c\\xf5\\xc0\\x2a\\x09\\x28\\x21\\xd8\\x62"\n        "\\x6e\\x89\\x32\\xb6\\x5c\\x5b\\xd8\\xc9\\x20\\x49\\xc2\\x10\\x93\\x2b\\x7a\\xfa"\n        "\\x7a\\xc5\\x9c\\x0e\\x88\\x6a\\xe5\\xc1\\xed\\xb0\\x0d\\x8c\\xe2\\xc5\\x76\\x33"\n        "\\xdb\\x26\\xbd\\x66\\x39\\xbf\\xf7\\x3c\\xee\\x82\\xbe\\x92\\x75\\xc4\\x02\\xb4"\n        "\\xcf\\x2a\\x43\\x88\\xda\\x8c\\xf8\\xc6\\x4e\\xef\\xe1\\xc5\\xa0\\xf5\\xab\\x80"\n        "\\x57\\xc3\\x9f\\xa5\\xc0\\x58\\x9c\\x3e\\x25\\x3f\\x09\\x60\\x33\\x23\\x00\\xf9"\n        "\\x4b\\xea\\x44\\x87\\x7b\\x58\\x8e\\x1e\\xdb\\xde\\x97\\xcf\\x23\\x60\\x72\\x7a"\n        "\\x09\\xb7\\x75\\x26\\x2d\\x7e\\xe5\\x52\\xb3\\x31\\x9b\\x92\\x66\\xf0\\x5a\\x25";\n    static const unsigned char e[] = "\\x01\\x00\\x01";\n    static const unsigned char d[] =\n        "\\x6a\\x7d\\xf2\\xca\\x63\\xea\\xd4\\xdd\\xa1\\x91\\xd6\\x14\\xb6\\xb3\\x85\\xe0"\n        "\\xd9\\x05\\x6a\\x3d\\x6d\\x5c\\xfe\\x07\\xdb\\x1d\\xaa\\xbe\\xe0\\x22\\xdb\\x08"\n        "\\x21\\x2d\\x97\\x61\\x3d\\x33\\x28\\xe0\\x26\\x7c\\x9d\\xd2\\x3d\\x78\\x7a\\xbd"\n        "\\xe2\\xaf\\xcb\\x30\\x6a\\xeb\\x7d\\xfc\\xe6\\x92\\x46\\xcc\\x73\\xf5\\xc8\\x7f"\n        "\\xdf\\x06\\x03\\x01\\x79\\xa2\\x11\\x4b\\x76\\x7d\\xb1\\xf0\\x83\\xff\\x84\\x1c"\n        "\\x02\\x5d\\x7d\\xc0\\x0c\\xd8\\x24\\x35\\xb9\\xa9\\x0f\\x69\\x53\\x69\\xe9\\x4d"\n        "\\xf2\\x3d\\x2c\\xe4\\x58\\xbc\\x3b\\x32\\x83\\xad\\x8b\\xba\\x2b\\x8f\\xa1\\xba"\n        "\\x62\\xe2\\xdc\\xe9\\xac\\xcf\\xf3\\x79\\x9a\\xae\\x7c\\x84\\x00\\x16\\xf3\\xba"\n        "\\x8e\\x00\\x48\\xc0\\xb6\\xcc\\x43\\x39\\xaf\\x71\\x61\\x00\\x3a\\x5b\\xeb\\x86"\n        "\\x4a\\x01\\x64\\xb2\\xc1\\xc9\\x23\\x7b\\x64\\xbc\\x87\\x55\\x69\\x94\\x35\\x1b"\n        "\\x27\\x50\\x6c\\x33\\xd4\\xbc\\xdf\\xce\\x0f\\x9c\\x49\\x1a\\x7d\\x6b\\x06\\x28"\n        "\\xc7\\xc8\\x52\\xbe\\x4f\\x0a\\x9c\\x31\\x32\\xb2\\xed\\x3a\\x2c\\x88\\x81\\xe9"\n        "\\xaa\\xb0\\x7e\\x20\\xe1\\x7d\\xeb\\x07\\x46\\x91\\xbe\\x67\\x77\\x76\\xa7\\x8b"\n        "\\x5c\\x50\\x2e\\x05\\xd9\\xbd\\xde\\x72\\x12\\x6b\\x37\\x38\\x69\\x5e\\x2d\\xd1"\n        "\\xa0\\xa9\\x8a\\x14\\x24\\x7c\\x65\\xd8\\xa7\\xee\\x79\\x43\\x2a\\x09\\x2c\\xb0"\n        "\\x72\\x1a\\x12\\xdf\\x79\\x8e\\x44\\xf7\\xcf\\xce\\x0c\\x49\\x81\\x47\\xa9\\xb1";\n    static const unsigned char p[] =\n        "\\x06\\x77\\xcd\\xd5\\x46\\x9b\\xc1\\xd5\\x58\\x00\\x81\\xe2\\xf3\\x0a\\x36\\xb1"\n        "\\x6e\\x29\\x89\\xd5\\x2f\\x31\\x5f\\x92\\x22\\x3b\\x9b\\x75\\x30\\x82\\xfa\\xc5"\n        "\\xf5\\xde\\x8a\\x36\\xdb\\xc6\\xe5\\x8f\\xef\\x14\\x37\\xd6\\x00\\xf9\\xab\\x90"\n        "\\x9b\\x5d\\x57\\x4c\\xf5\\x1f\\x77\\xc4\\xbb\\x8b\\xdd\\x9b\\x67\\x11\\x45\\xb2"\n        "\\x64\\xe8\\xac\\xa8\\x03\\x0f\\x16\\x0d\\x5d\\x2d\\x53\\x07\\x23\\xfb\\x62\\x0d"\n        "\\xe6\\x16\\xd3\\x23\\xe8\\xb3";\n    static const unsigned char q[] =\n        "\\x06\\x66\\x9a\\x70\\x53\\xd6\\x72\\x74\\xfd\\xea\\x45\\xc3\\xc0\\x17\\xae\\xde"\n        "\\x79\\x17\\xae\\x79\\xde\\xfc\\x0e\\xf7\\xa4\\x3a\\x8c\\x43\\x8f\\xc7\\x8a\\xa2"\n        "\\x2c\\x51\\xc4\\xd0\\x72\\x89\\x73\\x5c\\x61\\xbe\\xfd\\x54\\x3f\\x92\\x65\\xde"\n        "\\x4d\\x65\\x71\\x70\\xf6\\xf2\\xe5\\x98\\xb9\\x0f\\xd1\\x0b\\xe6\\x95\\x09\\x4a"\n        "\\x7a\\xdf\\xf3\\x10\\x16\\xd0\\x60\\xfc\\xa5\\x10\\x34\\x97\\x37\\x6f\\x0a\\xd5"\n        "\\x5d\\x8f\\xd4\\xc3\\xa0\\x5b";\n    static const unsigned char dmp1[] =\n        "\\x05\\x7c\\x9e\\x1c\\xbd\\x90\\x25\\xe7\\x40\\x86\\xf5\\xa8\\x3b\\x7a\\x3f\\x99"\n        "\\x56\\x95\\x60\\x3a\\x7b\\x95\\x4b\\xb8\\xa0\\xd7\\xa5\\xf1\\xcc\\xdc\\x5f\\xb5"\n        "\\x8c\\xf4\\x62\\x95\\x54\\xed\\x2e\\x12\\x62\\xc2\\xe8\\xf6\\xde\\xce\\xed\\x8e"\n        "\\x77\\x6d\\xc0\\x40\\x25\\x74\\xb3\\x5a\\x2d\\xaa\\xe1\\xac\\x11\\xcb\\xe2\\x2f"\n        "\\x0a\\x51\\x23\\x1e\\x47\\xb2\\x05\\x88\\x02\\xb2\\x0f\\x4b\\xf0\\x67\\x30\\xf0"\n        "\\x0f\\x6e\\xef\\x5f\\xf7\\xe7";\n    static const unsigned char dmq1[] =\n        "\\x01\\xa5\\x6b\\xbc\\xcd\\xe3\\x0e\\x46\\xc6\\x72\\xf5\\x04\\x56\\x28\\x01\\x22"\n        "\\x58\\x74\\x5d\\xbc\\x1c\\x3c\\x29\\x41\\x49\\x6c\\x81\\x5c\\x72\\xe2\\xf7\\xe5"\n        "\\xa3\\x8e\\x58\\x16\\xe0\\x0e\\x37\\xac\\x1f\\xbb\\x75\\xfd\\xaf\\xe7\\xdf\\xe9"\n        "\\x1f\\x70\\xa2\\x8f\\x52\\x03\\xc0\\x46\\xd9\\xf9\\x96\\x63\\x00\\x27\\x7e\\x5f"\n        "\\x38\\x60\\xd6\\x6b\\x61\\xe2\\xaf\\xbe\\xea\\x58\\xd3\\x9d\\xbc\\x75\\x03\\x8d"\n        "\\x42\\x65\\xd6\\x6b\\x85\\x97";\n    static const unsigned char iqmp[] =\n        "\\x03\\xa1\\x8b\\x80\\xe4\\xd8\\x87\\x25\\x17\\x5d\\xcc\\x8d\\xa9\\x8a\\x22\\x2b"\n        "\\x6c\\x15\\x34\\x6f\\x80\\xcc\\x1c\\x44\\x04\\x68\\xbc\\x03\\xcd\\x95\\xbb\\x69"\n        "\\x37\\x61\\x48\\xb4\\x23\\x13\\x08\\x16\\x54\\x6a\\xa1\\x7c\\xf5\\xd4\\x3a\\xe1"\n        "\\x4f\\xa4\\x0c\\xf5\\xaf\\x80\\x85\\x27\\x06\\x0d\\x70\\xc0\\xc5\\x19\\x28\\xfe"\n        "\\xee\\x8e\\x86\\x21\\x98\\x8a\\x37\\xb7\\xe5\\x30\\x25\\x70\\x93\\x51\\x2d\\x49"\n        "\\x85\\x56\\xb3\\x0c\\x2b\\x96";\n    static const unsigned char ex_prime[] =\n        "\\x03\\x89\\x22\\xa0\\xb7\\x3a\\x91\\xcb\\x5e\\x0c\\xfd\\x73\\xde\\xa7\\x38\\xa9"\n        "\\x47\\x43\\xd6\\x02\\xbf\\x2a\\xb9\\x3c\\x48\\xf3\\x06\\xd6\\x58\\x35\\x50\\x56"\n        "\\x16\\x5c\\x34\\x9b\\x61\\x87\\xc8\\xaa\\x0a\\x5d\\x8a\\x0a\\xcd\\x9c\\x41\\xd9"\n        "\\x96\\x24\\xe0\\xa9\\x9b\\x26\\xb7\\xa8\\x08\\xc9\\xea\\xdc\\xa7\\x15\\xfb\\x62"\n        "\\xa0\\x2d\\x90\\xe6\\xa7\\x55\\x6e\\xc6\\x6c\\xff\\xd6\\x10\\x6d\\xfa\\x2e\\x04"\n        "\\x50\\xec\\x5c\\x66\\xe4\\x05";\n    static const unsigned char ex_exponent[] =\n        "\\x02\\x0a\\xcd\\xc3\\x82\\xd2\\x03\\xb0\\x31\\xac\\xd3\\x20\\x80\\x34\\x9a\\x57"\n        "\\xbc\\x60\\x04\\x57\\x25\\xd0\\x29\\x9a\\x16\\x90\\xb9\\x1c\\x49\\x6a\\xd1\\xf2"\n        "\\x47\\x8c\\x0e\\x9e\\xc9\\x20\\xc2\\xd8\\xe4\\x8f\\xce\\xd2\\x1a\\x9c\\xec\\xb4"\n        "\\x1f\\x33\\x41\\xc8\\xf5\\x62\\xd1\\xa5\\xef\\x1d\\xa1\\xd8\\xbd\\x71\\xc6\\xf7"\n        "\\xda\\x89\\x37\\x2e\\xe2\\xec\\x47\\xc5\\xb8\\xe3\\xb4\\xe3\\x5c\\x82\\xaa\\xdd"\n        "\\xb7\\x58\\x2e\\xaf\\x07\\x79";\n    static const unsigned char ex_coefficient[] =\n        "\\x00\\x9c\\x09\\x88\\x9b\\xc8\\x57\\x08\\x69\\x69\\xab\\x2d\\x9e\\x29\\x1c\\x3c"\n        "\\x6d\\x59\\x33\\x12\\x0d\\x2b\\x09\\x2e\\xaf\\x01\\x2c\\x27\\x01\\xfc\\xbd\\x26"\n        "\\x13\\xf9\\x2d\\x09\\x22\\x4e\\x49\\x11\\x03\\x82\\x88\\x87\\xf4\\x43\\x1d\\xac"\n        "\\xca\\xec\\x86\\xf7\\x23\\xf1\\x64\\xf3\\xf5\\x81\\xf0\\x37\\x36\\xcf\\x67\\xff"\n        "\\x1a\\xff\\x7a\\xc7\\xf9\\xf9\\x67\\x2d\\xa0\\x9d\\x61\\xf8\\xf6\\x47\\x5c\\x2f"\n        "\\xe7\\x66\\xe8\\x3c\\x3a\\xe8";\n    BIGNUM **pris = NULL, **exps = NULL, **coeffs = NULL;\n    int rv = 256;\n    if (!TEST_int_eq(RSA_set0_key(key,\n                                  BN_bin2bn(n, sizeof(n) - 1, NULL),\n                                  BN_bin2bn(e, sizeof(e) - 1, NULL),\n                                  BN_bin2bn(d, sizeof(d) - 1, NULL)), 1))\n        goto err;\n    if (!TEST_int_eq(RSA_set0_factors(key,\n                                      BN_bin2bn(p, sizeof(p) - 1, NULL),\n                                      BN_bin2bn(q, sizeof(q) - 1, NULL)), 1))\n        goto err;\n    if (!TEST_int_eq(RSA_set0_crt_params(key,\n                                         BN_bin2bn(dmp1, sizeof(dmp1) - 1, NULL),\n                                         BN_bin2bn(dmq1, sizeof(dmq1) - 1, NULL),\n                                         BN_bin2bn(iqmp, sizeof(iqmp) - 1,\n                                                   NULL)), 1))\n        return 0;\n    pris = OPENSSL_zalloc(sizeof(BIGNUM *));\n    exps = OPENSSL_zalloc(sizeof(BIGNUM *));\n    coeffs = OPENSSL_zalloc(sizeof(BIGNUM *));\n    if (!TEST_ptr(pris) || !TEST_ptr(exps) || !TEST_ptr(coeffs))\n        goto err;\n    pris[0] = BN_bin2bn(ex_prime, sizeof(ex_prime) - 1, NULL);\n    exps[0] = BN_bin2bn(ex_exponent, sizeof(ex_exponent) - 1, NULL);\n    coeffs[0] = BN_bin2bn(ex_coefficient, sizeof(ex_coefficient) - 1, NULL);\n    if (!TEST_ptr(pris[0]) || !TEST_ptr(exps[0]) || !TEST_ptr(coeffs[0]))\n        goto err;\n    if (!TEST_true(RSA_set0_multi_prime_params(key, pris, exps,\n                                               coeffs, NUM_EXTRA_PRIMES)))\n        goto err;\n ret:\n    OPENSSL_free(pris);\n    OPENSSL_free(exps);\n    OPENSSL_free(coeffs);\n    return rv;\n err:\n    if (pris != NULL)\n        BN_free(pris[0]);\n    if (exps != NULL)\n        BN_free(exps[0]);\n    if (coeffs != NULL)\n        BN_free(coeffs[0]);\n    rv = 0;\n    goto 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}', 'int RSA_check_key_ex(const RSA *key, BN_GENCB *cb)\n{\n    BIGNUM *i, *j, *k, *l, *m;\n    BN_CTX *ctx;\n    int ret = 1, ex_primes = 0, idx;\n    RSA_PRIME_INFO *pinfo;\n    if (key->p == NULL || key->q == NULL || key->n == NULL\n            || key->e == NULL || key->d == NULL) {\n        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_VALUE_MISSING);\n        return 0;\n    }\n    if (key->version == RSA_ASN1_VERSION_MULTI) {\n        ex_primes = sk_RSA_PRIME_INFO_num(key->prime_infos);\n        if (ex_primes <= 0\n                || (ex_primes + 2) > rsa_multip_cap(BN_num_bits(key->n))) {\n            RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_INVALID_MULTI_PRIME_KEY);\n            return 0;\n        }\n    }\n    i = BN_new();\n    j = BN_new();\n    k = BN_new();\n    l = BN_new();\n    m = BN_new();\n    ctx = BN_CTX_new();\n    if (i == NULL || j == NULL || k == NULL || l == NULL\n            || m == NULL || ctx == NULL) {\n        ret = -1;\n        RSAerr(RSA_F_RSA_CHECK_KEY_EX, ERR_R_MALLOC_FAILURE);\n        goto err;\n    }\n    if (BN_is_one(key->e)) {\n        ret = 0;\n        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_BAD_E_VALUE);\n    }\n    if (!BN_is_odd(key->e)) {\n        ret = 0;\n        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_BAD_E_VALUE);\n    }\n    if (BN_is_prime_ex(key->p, BN_prime_checks, NULL, cb) != 1) {\n        ret = 0;\n        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_P_NOT_PRIME);\n    }\n    if (BN_is_prime_ex(key->q, BN_prime_checks, NULL, cb) != 1) {\n        ret = 0;\n        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_Q_NOT_PRIME);\n    }\n    for (idx = 0; idx < ex_primes; idx++) {\n        pinfo = sk_RSA_PRIME_INFO_value(key->prime_infos, idx);\n        if (BN_is_prime_ex(pinfo->r, BN_prime_checks, NULL, cb) != 1) {\n            ret = 0;\n            RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_MP_R_NOT_PRIME);\n        }\n    }\n    if (!BN_mul(i, key->p, key->q, ctx)) {\n        ret = -1;\n        goto err;\n    }\n    for (idx = 0; idx < ex_primes; idx++) {\n        pinfo = sk_RSA_PRIME_INFO_value(key->prime_infos, idx);\n        if (!BN_mul(i, i, pinfo->r, ctx)) {\n            ret = -1;\n            goto err;\n        }\n    }\n    if (BN_cmp(i, key->n) != 0) {\n        ret = 0;\n        if (ex_primes)\n            RSAerr(RSA_F_RSA_CHECK_KEY_EX,\n                   RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES);\n        else\n            RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_N_DOES_NOT_EQUAL_P_Q);\n    }\n    if (!BN_sub(i, key->p, BN_value_one())) {\n        ret = -1;\n        goto err;\n    }\n    if (!BN_sub(j, key->q, BN_value_one())) {\n        ret = -1;\n        goto err;\n    }\n    if (!BN_mul(l, i, j, ctx)) {\n        ret = -1;\n        goto err;\n    }\n    if (!BN_gcd(m, i, j, ctx)) {\n        ret = -1;\n        goto err;\n    }\n    for (idx = 0; idx < ex_primes; idx++) {\n        pinfo = sk_RSA_PRIME_INFO_value(key->prime_infos, idx);\n        if (!BN_sub(k, pinfo->r, BN_value_one())) {\n            ret = -1;\n            goto err;\n        }\n        if (!BN_mul(l, l, k, ctx)) {\n            ret = -1;\n            goto err;\n        }\n        if (!BN_gcd(m, m, k, ctx)) {\n            ret = -1;\n            goto err;\n        }\n    }\n    if (!BN_div(k, NULL, l, m, ctx)) {\n        ret = -1;\n        goto err;\n    }\n    if (!BN_mod_mul(i, key->d, key->e, k, ctx)) {\n        ret = -1;\n        goto err;\n    }\n    if (!BN_is_one(i)) {\n        ret = 0;\n        RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_D_E_NOT_CONGRUENT_TO_1);\n    }\n    if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) {\n        if (!BN_sub(i, key->p, BN_value_one())) {\n            ret = -1;\n            goto err;\n        }\n        if (!BN_mod(j, key->d, i, ctx)) {\n            ret = -1;\n            goto err;\n        }\n        if (BN_cmp(j, key->dmp1) != 0) {\n            ret = 0;\n            RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_DMP1_NOT_CONGRUENT_TO_D);\n        }\n        if (!BN_sub(i, key->q, BN_value_one())) {\n            ret = -1;\n            goto err;\n        }\n        if (!BN_mod(j, key->d, i, ctx)) {\n            ret = -1;\n            goto err;\n        }\n        if (BN_cmp(j, key->dmq1) != 0) {\n            ret = 0;\n            RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_DMQ1_NOT_CONGRUENT_TO_D);\n        }\n        if (!BN_mod_inverse(i, key->q, key->p, ctx)) {\n            ret = -1;\n            goto err;\n        }\n        if (BN_cmp(i, key->iqmp) != 0) {\n            ret = 0;\n            RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_IQMP_NOT_INVERSE_OF_Q);\n        }\n    }\n    for (idx = 0; idx < ex_primes; idx++) {\n        pinfo = sk_RSA_PRIME_INFO_value(key->prime_infos, idx);\n        if (!BN_sub(i, pinfo->r, BN_value_one())) {\n            ret = -1;\n            goto err;\n        }\n        if (!BN_mod(j, key->d, i, ctx)) {\n            ret = -1;\n            goto err;\n        }\n        if (BN_cmp(j, pinfo->d) != 0) {\n            ret = 0;\n            RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D);\n        }\n        if (!BN_mod_inverse(i, pinfo->pp, pinfo->r, ctx)) {\n            ret = -1;\n            goto err;\n        }\n        if (BN_cmp(i, pinfo->t) != 0) {\n            ret = 0;\n            RSAerr(RSA_F_RSA_CHECK_KEY_EX, RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R);\n        }\n    }\n err:\n    BN_free(i);\n    BN_free(j);\n    BN_free(k);\n    BN_free(l);\n    BN_free(m);\n    BN_CTX_free(ctx);\n    return ret;\n}', 'int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m,\n               BN_CTX *ctx)\n{\n    BIGNUM *t;\n    int ret = 0;\n    bn_check_top(a);\n    bn_check_top(b);\n    bn_check_top(m);\n    BN_CTX_start(ctx);\n    if ((t = BN_CTX_get(ctx)) == NULL)\n        goto err;\n    if (a == b) {\n        if (!BN_sqr(t, a, ctx))\n            goto err;\n    } else {\n        if (!BN_mul(t, a, b, ctx))\n            goto err;\n    }\n    if (!BN_nnmod(r, t, m, ctx))\n        goto err;\n    bn_check_top(r);\n    ret = 1;\n err:\n    BN_CTX_end(ctx);\n    return ret;\n}', 'int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)\n{\n    int max, al;\n    int ret = 0;\n    BIGNUM *tmp, *rr;\n    bn_check_top(a);\n    al = a->top;\n    if (al <= 0) {\n        r->top = 0;\n        r->neg = 0;\n        return 1;\n    }\n    BN_CTX_start(ctx);\n    rr = (a != r) ? r : BN_CTX_get(ctx);\n    tmp = BN_CTX_get(ctx);\n    if (rr == NULL || tmp == NULL)\n        goto err;\n    max = 2 * al;\n    if (bn_wexpand(rr, max) == NULL)\n        goto err;\n    if (al == 4) {\n#ifndef BN_SQR_COMBA\n        BN_ULONG t[8];\n        bn_sqr_normal(rr->d, a->d, 4, t);\n#else\n        bn_sqr_comba4(rr->d, a->d);\n#endif\n    } else if (al == 8) {\n#ifndef BN_SQR_COMBA\n        BN_ULONG t[16];\n        bn_sqr_normal(rr->d, a->d, 8, t);\n#else\n        bn_sqr_comba8(rr->d, a->d);\n#endif\n    } else {\n#if defined(BN_RECURSION)\n        if (al < BN_SQR_RECURSIVE_SIZE_NORMAL) {\n            BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL * 2];\n            bn_sqr_normal(rr->d, a->d, al, t);\n        } else {\n            int j, k;\n            j = BN_num_bits_word((BN_ULONG)al);\n            j = 1 << (j - 1);\n            k = j + j;\n            if (al == j) {\n                if (bn_wexpand(tmp, k * 2) == NULL)\n                    goto err;\n                bn_sqr_recursive(rr->d, a->d, al, tmp->d);\n            } else {\n                if (bn_wexpand(tmp, max) == NULL)\n                    goto err;\n                bn_sqr_normal(rr->d, a->d, al, tmp->d);\n            }\n        }\n#else\n        if (bn_wexpand(tmp, max) == NULL)\n            goto err;\n        bn_sqr_normal(rr->d, a->d, al, tmp->d);\n#endif\n    }\n    rr->neg = 0;\n    if (a->d[al - 1] == (a->d[al - 1] & BN_MASK2l))\n        rr->top = max - 1;\n    else\n        rr->top = max;\n    if (r != rr && BN_copy(r, rr) == NULL)\n        goto err;\n    ret = 1;\n err:\n    bn_check_top(rr);\n    bn_check_top(tmp);\n    BN_CTX_end(ctx);\n    return ret;\n}', 'void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp)\n{\n    int i, j, max;\n    const BN_ULONG *ap;\n    BN_ULONG *rp;\n    max = n * 2;\n    ap = a;\n    rp = r;\n    rp[0] = rp[max - 1] = 0;\n    rp++;\n    j = n;\n    if (--j > 0) {\n        ap++;\n        rp[j] = bn_mul_words(rp, ap, j, ap[-1]);\n        rp += 2;\n    }\n    for (i = n - 2; i > 0; i--) {\n        j--;\n        ap++;\n        rp[j] = bn_mul_add_words(rp, ap, j, ap[-1]);\n        rp += 2;\n    }\n    bn_add_words(r, r, r, max);\n    bn_sqr_words(tmp, a, n);\n    bn_add_words(r, r, tmp, max);\n}']