int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng)
{
    int ret = FP_YES;

    if (a == NULL || result == NULL || rng == NULL)
        return FP_VAL;

    if (fp_isone(a)) {
        *result = FP_NO;
        return FP_OKAY;
    }

    if (ret == FP_YES) {
        fp_digit d;
        int r;

        /* check against primes table */
        for (r = 0; r < FP_PRIME_SIZE; r++) {
            if (fp_cmp_d(a, primes[r]) == FP_EQ) {
                *result = FP_YES;
                return FP_OKAY;
            }
        }

        /* do trial division */
        for (r = 0; r < FP_PRIME_SIZE; r++) {
            if (fp_mod_d(a, primes[r], &d) == MP_OKAY) {
                if (d == 0) {
                    *result = FP_NO;
                    return FP_OKAY;
                }
            }
            else
                return FP_VAL;
        }
    }

#ifndef WC_NO_RNG
    /* now do a miller rabin with up to t random numbers, this should
     * give a (1/4)^t chance of a false prime. */
    if (ret == FP_YES) {
    #ifndef WOLFSSL_SMALL_STACK
        fp_int b[1], c[1], n1[1], y[1], r[1];
        byte   base[FP_MAX_PRIME_SIZE];
    #else
        fp_int *b, *c, *n1, *y, *r;
        byte*  base;
    #endif
        word32 baseSz;
        int    err;

        baseSz = fp_count_bits(a);
        /* The base size is the number of bits / 8. One is added if the number
         * of bits isn't an even 8. */
        baseSz = (baseSz / 8) + ((baseSz % 8) ? 1 : 0);

    #ifndef WOLFSSL_SMALL_STACK
        if (baseSz > sizeof(base))
            return FP_MEM;
    #else
        base = (byte*)XMALLOC(baseSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        if (base == NULL)
            return FP_MEM;

        b = (fp_int*)XMALLOC(sizeof(fp_int) * 5, NULL, DYNAMIC_TYPE_BIGINT);
        if (b == NULL) {
            return FP_MEM;
        }
        c = &b[1]; n1 = &b[2]; y= &b[3]; r = &b[4];
    #endif

        fp_init(b);
        fp_init(c);
        fp_init(n1);
        fp_init(y);
        fp_init(r);

        err = fp_sub_d(a, 2, c);
        if (err != FP_OKAY) {
        #ifdef WOLFSSL_SMALL_STACK
           XFREE(b, NULL, DYNAMIC_TYPE_BIGINT);
           XFREE(base, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        #endif
           return err;
        }
        while (t > 0) {
            if ((err = wc_RNG_GenerateBlock(rng, base, baseSz)) != 0) {
            #ifdef WOLFSSL_SMALL_STACK
               XFREE(b, NULL, DYNAMIC_TYPE_BIGINT);
               XFREE(base, NULL, DYNAMIC_TYPE_TMP_BUFFER);
            #endif
               return err;
            }

            fp_read_unsigned_bin(b, base, baseSz);
            if (fp_cmp_d(b, 2) != FP_GT || fp_cmp(b, c) != FP_LT) {
                continue;
            }

            fp_prime_miller_rabin_ex(a, b, &ret, n1, y, r);
            if (ret == FP_NO)
                break;
            fp_zero(b);
            t--;
        }

        fp_clear(n1);
        fp_clear(y);
        fp_clear(r);
        fp_clear(b);
        fp_clear(c);
     #ifdef WOLFSSL_SMALL_STACK
        XFREE(b, NULL, DYNAMIC_TYPE_BIGINT);
        XFREE(base, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     #endif
    }
#else
    (void)t;
#endif /* !WC_NO_RNG */

    *result = ret;
    return FP_OKAY;
}
int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng)
{
    int ret = FP_YES;

    if (a == NULL || result == NULL || rng == NULL)
        return FP_VAL;

    if (fp_isone(a)) {
        *result = FP_NO;
        return FP_OKAY;
    }

    if (ret == FP_YES) {
        fp_digit d;
        int r;

         
        for (r = 0; r < FP_PRIME_SIZE; r++) {
            if (fp_cmp_d(a, primes[r]) == FP_EQ) {
                *result = FP_YES;
                return FP_OKAY;
            }
        }

         
        for (r = 0; r < FP_PRIME_SIZE; r++) {
            if (fp_mod_d(a, primes[r], &d) == MP_OKAY) {
                if (d == 0) {
                    *result = FP_NO;
                    return FP_OKAY;
                }
            }
            else
                return FP_VAL;
        }
    }

#ifndef WC_NO_RNG
     
    if (ret == FP_YES) {
    #ifndef WOLFSSL_SMALL_STACK
        fp_int b[1], c[1], n1[1], y[1], r[1];
        byte   base[FP_MAX_PRIME_SIZE];
    #else
        fp_int *b, *c, *n1, *y, *r;
        byte*  base;
    #endif
        word32 baseSz;
        int    err;

        baseSz = fp_count_bits(a);
         
        baseSz = (baseSz / 8) + ((baseSz % 8) ? 1 : 0);

    #ifndef WOLFSSL_SMALL_STACK
        if (baseSz > sizeof(base))
            return FP_MEM;
    #else
        base = (byte*)XMALLOC(baseSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        if (base == NULL)
            return FP_MEM;

        b = (fp_int*)XMALLOC(sizeof(fp_int) * 5, NULL, DYNAMIC_TYPE_BIGINT);
        if (b == NULL) {
            return FP_MEM;
        }
        c = &b[1]; n1 = &b[2]; y= &b[3]; r = &b[4];
    #endif

        fp_init(b);
        fp_init(c);
        fp_init(n1);
        fp_init(y);
        fp_init(r);

        err = fp_sub_d(a, 2, c);
        if (err != FP_OKAY) {
        #ifdef WOLFSSL_SMALL_STACK
           XFREE(b, NULL, DYNAMIC_TYPE_BIGINT);
           XFREE(base, NULL, DYNAMIC_TYPE_TMP_BUFFER);
        #endif
           return err;
        }
        while (t > 0) {
            if ((err = wc_RNG_GenerateBlock(rng, base, baseSz)) != 0) {
            #ifdef WOLFSSL_SMALL_STACK
               XFREE(b, NULL, DYNAMIC_TYPE_BIGINT);
               XFREE(base, NULL, DYNAMIC_TYPE_TMP_BUFFER);
            #endif
               return err;
            }

            fp_read_unsigned_bin(b, base, baseSz);
            if (fp_cmp_d(b, 2) != FP_GT || fp_cmp(b, c) != FP_LT) {
                continue;
            }

            fp_prime_miller_rabin_ex(a, b, &ret, n1, y, r);
            if (ret == FP_NO)
                break;
            fp_zero(b);
            t--;
        }

        fp_clear(n1);
        fp_clear(y);
        fp_clear(r);
        fp_clear(b);
        fp_clear(c);
     #ifdef WOLFSSL_SMALL_STACK
        XFREE(b, NULL, DYNAMIC_TYPE_BIGINT);
        XFREE(base, NULL, DYNAMIC_TYPE_TMP_BUFFER);
     #endif
    }
#else
    (void)t;
#endif  

    *result = ret;
    return FP_OKAY;
}