public function randomPrime($min = false, $max = false, $timeout = false)
    {
        if ($min === false) {
            $min = new BigInteger(0);
        }
        if ($max === false) {
            $max = new BigInteger(0x7FFFFFFF);
        }
        $compare = $max->compare($min);
        if (! $compare) {
            return $min->isPrime() ? $min : false;
        } elseif ($compare < 0) {
            // if $min is bigger then $max, swap $min and $max
            $temp = $max;
            $max = $min;
            $min = $temp;
        }
        static $one, $two;
        if (! isset($one)) {
            $one = new BigInteger(1);
            $two = new BigInteger(2);
        }
        $start = time();
        $x = $this->random($min, $max);
        // gmp_nextprime() requires PHP 5 >= 5.2.0 per <http://php.net/gmp-nextprime>.
        if (MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_GMP && function_exists('gmp_nextprime')) {
            $p = new BigInteger();
            $p->value = gmp_nextprime($x->value);
            if ($p->compare($max) <= 0) {
                return $p;
            }
            if (! $min->equals($x)) {
                $x = $x->subtract($one);
            }
            return $x->randomPrime($min, $x);
        }
        if ($x->equals($two)) {
            return $x;
        }
        $x->protectedMakeOdd();
        if ($x->compare($max) > 0) {
            // if $x > $max then $max is even and if $min == $max
            // then no prime number exists between the specified range
            if ($min->equals($max)) {
                return false;
            }
            $x = $min->copy();
            $x->protectedMakeOdd();
        }
        $initial_x = $x->copy();
        while (true) {
            if ($timeout !== false && time() - $start > $timeout) {
                return false;
            }
            if ($x->isPrime()) {
                return $x;
            }
            $x = $x->add($two);
            if ($x->compare($max) > 0) {
                $x = $min->copy();
                if ($x->equals($two)) {
                    return $x;
                }
                $x->protectedMakeOdd();
            }
            if ($x->equals($initial_x)) {
                return false;
            }
        }
    }