int test_mont(BIO *bp, BN_CTX *ctx)
{
    BIGNUM *a, *b, *c, *d, *A, *B;
    BIGNUM *n;
    int i;
    BN_MONT_CTX *mont;
    a = BN_new();
    b = BN_new();
    c = BN_new();
    d = BN_new();
    A = BN_new();
    B = BN_new();
    n = BN_new();
    mont = BN_MONT_CTX_new();
    if (mont == NULL)
        return 0;
    BN_zero(n);
    if (BN_MONT_CTX_set(mont, n, ctx)) {
        fprintf(stderr, "BN_MONT_CTX_set succeeded for zero modulus!\n");
        return 0;
    }
    BN_set_word(n, 16);
    if (BN_MONT_CTX_set(mont, n, ctx)) {
        fprintf(stderr, "BN_MONT_CTX_set succeeded for even modulus!\n");
        return 0;
    }
    BN_bntest_rand(a, 100, 0, 0);
    BN_bntest_rand(b, 100, 0, 0);
    for (i = 0; i < num2; i++) {
        int bits = (200 * (i + 1)) / num2;
        if (bits == 0)
            continue;
        BN_bntest_rand(n, bits, 0, 1);
        BN_MONT_CTX_set(mont, n, ctx);
        BN_nnmod(a, a, n, ctx);
        BN_nnmod(b, b, n, ctx);
        BN_to_montgomery(A, a, mont, ctx);
        BN_to_montgomery(B, b, mont, ctx);
        BN_mod_mul_montgomery(c, A, B, mont, ctx);
        BN_from_montgomery(A, c, mont, ctx);
        if (bp != NULL) {
            if (!results) {
                BN_print(bp, a);
                BIO_puts(bp, " * ");
                BN_print(bp, b);
                BIO_puts(bp, " % ");
                BN_print(bp, &mont->N);
                BIO_puts(bp, " - ");
            }
            BN_print(bp, A);
            BIO_puts(bp, "\n");
        }
        BN_mod_mul(d, a, b, n, ctx);
        BN_sub(d, d, A);
        if (!BN_is_zero(d)) {
            fprintf(stderr, "Montgomery multiplication test failed!\n");
            return 0;
        }
    }
    BN_MONT_CTX_free(mont);
    BN_free(a);
    BN_free(b);
    BN_free(c);
    BN_free(d);
    BN_free(A);
    BN_free(B);
    BN_free(n);
    return (1);
}
['int test_mont(BIO *bp, BN_CTX *ctx)\n{\n    BIGNUM *a, *b, *c, *d, *A, *B;\n    BIGNUM *n;\n    int i;\n    BN_MONT_CTX *mont;\n    a = BN_new();\n    b = BN_new();\n    c = BN_new();\n    d = BN_new();\n    A = BN_new();\n    B = BN_new();\n    n = BN_new();\n    mont = BN_MONT_CTX_new();\n    if (mont == NULL)\n        return 0;\n    BN_zero(n);\n    if (BN_MONT_CTX_set(mont, n, ctx)) {\n        fprintf(stderr, "BN_MONT_CTX_set succeeded for zero modulus!\\n");\n        return 0;\n    }\n    BN_set_word(n, 16);\n    if (BN_MONT_CTX_set(mont, n, ctx)) {\n        fprintf(stderr, "BN_MONT_CTX_set succeeded for even modulus!\\n");\n        return 0;\n    }\n    BN_bntest_rand(a, 100, 0, 0);\n    BN_bntest_rand(b, 100, 0, 0);\n    for (i = 0; i < num2; i++) {\n        int bits = (200 * (i + 1)) / num2;\n        if (bits == 0)\n            continue;\n        BN_bntest_rand(n, bits, 0, 1);\n        BN_MONT_CTX_set(mont, n, ctx);\n        BN_nnmod(a, a, n, ctx);\n        BN_nnmod(b, b, n, ctx);\n        BN_to_montgomery(A, a, mont, ctx);\n        BN_to_montgomery(B, b, mont, ctx);\n        BN_mod_mul_montgomery(c, A, B, mont, ctx);\n        BN_from_montgomery(A, c, mont, ctx);\n        if (bp != NULL) {\n            if (!results) {\n                BN_print(bp, a);\n                BIO_puts(bp, " * ");\n                BN_print(bp, b);\n                BIO_puts(bp, " % ");\n                BN_print(bp, &mont->N);\n                BIO_puts(bp, " - ");\n            }\n            BN_print(bp, A);\n            BIO_puts(bp, "\\n");\n        }\n        BN_mod_mul(d, a, b, n, ctx);\n        BN_sub(d, d, A);\n        if (!BN_is_zero(d)) {\n            fprintf(stderr, "Montgomery multiplication test failed!\\n");\n            return 0;\n        }\n    }\n    BN_MONT_CTX_free(mont);\n    BN_free(a);\n    BN_free(b);\n    BN_free(c);\n    BN_free(d);\n    BN_free(A);\n    BN_free(B);\n    BN_free(n);\n    return (1);\n}', 'BIGNUM *BN_new(void)\n{\n    BIGNUM *ret;\n    if ((ret = OPENSSL_zalloc(sizeof(*ret))) == NULL) {\n        BNerr(BN_F_BN_NEW, ERR_R_MALLOC_FAILURE);\n        return (NULL);\n    }\n    ret->flags = BN_FLG_MALLOCED;\n    bn_check_top(ret);\n    return (ret);\n}', 'void *CRYPTO_zalloc(size_t num, const char *file, int line)\n{\n    void *ret = CRYPTO_malloc(num, file, line);\n    if (ret != NULL)\n        memset(ret, 0, num);\n    return ret;\n}', 'void *CRYPTO_malloc(size_t num, const char *file, int line)\n{\n    void *ret = NULL;\n    if (num <= 0)\n        return NULL;\n    allow_customize = 0;\n#ifndef OPENSSL_NO_CRYPTO_MDEBUG\n    if (call_malloc_debug) {\n        CRYPTO_mem_debug_malloc(NULL, num, 0, file, line);\n        ret = malloc(num);\n        CRYPTO_mem_debug_malloc(ret, num, 1, file, line);\n    } else {\n        ret = malloc(num);\n    }\n#else\n    (void)file;\n    (void)line;\n    ret = malloc(num);\n#endif\n#ifndef OPENSSL_CPUID_OBJ\n    if (ret && (num > 2048)) {\n        extern unsigned char cleanse_ctr;\n        ((unsigned char *)ret)[0] = cleanse_ctr;\n    }\n#endif\n    return ret;\n}', 'BN_MONT_CTX *BN_MONT_CTX_new(void)\n{\n    BN_MONT_CTX *ret;\n    if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL)\n        return (NULL);\n    BN_MONT_CTX_init(ret);\n    ret->flags = BN_FLG_MALLOCED;\n    return (ret);\n}', 'void BN_MONT_CTX_init(BN_MONT_CTX *ctx)\n{\n    ctx->ri = 0;\n    bn_init(&(ctx->RR));\n    bn_init(&(ctx->N));\n    bn_init(&(ctx->Ni));\n    ctx->n0[0] = ctx->n0[1] = 0;\n    ctx->flags = 0;\n}', 'int BN_set_word(BIGNUM *a, BN_ULONG w)\n{\n    bn_check_top(a);\n    if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL)\n        return (0);\n    a->neg = 0;\n    a->d[0] = w;\n    a->top = (w ? 1 : 0);\n    bn_check_top(a);\n    return (1);\n}']