static int test_modexp_mont5()
{
    BIGNUM *a, *p, *m, *d, *e, *b, *n, *c;
    BN_MONT_CTX *mont;

    a = BN_new();
    p = BN_new();
    m = BN_new();
    d = BN_new();
    e = BN_new();
    b = BN_new();
    n = BN_new();
    c = BN_new();
    mont = BN_MONT_CTX_new();

    BN_bntest_rand(m, 1024, 0, 1); /* must be odd for montgomery */
    /* Zero exponent */
    BN_bntest_rand(a, 1024, 0, 0);
    BN_zero(p);
    if (!BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL))
        return 0;
    if (!BN_is_one(d)) {
        printf("Modular exponentiation test failed!\n");
        return 0;
    }

    /* Regression test for carry bug in mulx4x_mont */
    BN_hex2bn(&a,
        "7878787878787878787878787878787878787878787878787878787878787878"
        "7878787878787878787878787878787878787878787878787878787878787878"
        "7878787878787878787878787878787878787878787878787878787878787878"
        "7878787878787878787878787878787878787878787878787878787878787878");
    BN_hex2bn(&b,
        "095D72C08C097BA488C5E439C655A192EAFB6380073D8C2664668EDDB4060744"
        "E16E57FB4EDB9AE10A0CEFCDC28A894F689A128379DB279D48A2E20849D68593"
        "9B7803BCF46CEBF5C533FB0DD35B080593DE5472E3FE5DB951B8BFF9B4CB8F03"
        "9CC638A5EE8CDD703719F8000E6A9F63BEED5F2FCD52FF293EA05A251BB4AB81");
    BN_hex2bn(&n,
        "D78AF684E71DB0C39CFF4E64FB9DB567132CB9C50CC98009FEB820B26F2DED9B"
        "91B9B5E2B83AE0AE4EB4E0523CA726BFBE969B89FD754F674CE99118C3F2D1C5"
        "D81FDC7C54E02B60262B241D53C040E99E45826ECA37A804668E690E1AFC1CA4"
        "2C9A15D84D4954425F0B7642FC0BD9D7B24E2618D2DCC9B729D944BADACFDDAF");
    BN_MONT_CTX_set(mont, n, ctx);
    BN_mod_mul_montgomery(c, a, b, mont, ctx);
    BN_mod_mul_montgomery(d, b, a, mont, ctx);
    if (BN_cmp(c, d)) {
        fprintf(stderr, "Montgomery multiplication test failed:"
                        " a*b != b*a.\n");
        return 0;
    }

    /* Zero input */
    BN_bntest_rand(p, 1024, 0, 0);
    BN_zero(a);
    if (!BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL))
        return 0;
    if (!BN_is_zero(d)) {
        fprintf(stderr, "Modular exponentiation test failed!\n");
        return 0;
    }
    /*
     * Craft an input whose Montgomery representation is 1, i.e., shorter
     * than the modulus m, in order to test the const time precomputation
     * scattering/gathering.
     */
    BN_one(a);
    BN_MONT_CTX_set(mont, m, ctx);
    if (!BN_from_montgomery(e, a, mont, ctx))
        return 0;
    if (!BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL))
        return 0;
    if (!BN_mod_exp_simple(a, e, p, m, ctx))
        return 0;
    if (BN_cmp(a, d) != 0) {
        printf("Modular exponentiation test failed!\n");
        return 0;
    }
    /* Finally, some regular test vectors. */
    BN_bntest_rand(e, 1024, 0, 0);
    if (!BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL))
        return 0;
    if (!BN_mod_exp_simple(a, e, p, m, ctx))
        return 0;
    if (BN_cmp(a, d) != 0) {
        printf("Modular exponentiation test failed!\n");
        return 0;
    }
    BN_MONT_CTX_free(mont);
    BN_free(a);
    BN_free(p);
    BN_free(m);
    BN_free(d);
    BN_free(e);
    BN_free(b);
    BN_free(n);
    BN_free(c);
    return 1;
}