diff --git a/lib/Crypto/PublicKey/ElGamal.py b/lib/Crypto/PublicKey/ElGamal.py
index 793d970..109963d 100644
--- a/lib/Crypto/PublicKey/ElGamal.py
+++ b/lib/Crypto/PublicKey/ElGamal.py
@@ -77,7 +77,7 @@ def generate(bits, randfunc, progress_func=None):
     return obj
 
 def construct(tuple):
-    """construct(tuple:(long,long,long,long)|(long,long,long,long,long)))
+    """construct(tuple:(long,long,long)|(long,long,long,long)))
              : ElGamalobj
     Construct an ElGamal key from a 3- or 4-tuple of numbers.
     """
diff --git a/lib/Crypto/Util/number.py b/lib/Crypto/Util/number.py
index 7be595b..0ab710a 100644
--- a/lib/Crypto/Util/number.py
+++ b/lib/Crypto/Util/number.py
@@ -297,37 +297,32 @@ def getStrongPrime(N, e=0, false_positive_prob=1e-6, randfunc=None):
     # search for final prime number starting by Y0
     #    Y0 = X + (R - X mod p1p2)
     increment = p[0] * p[1]
-    X = X + (R - (X % increment))
-    while 1:
-        is_possible_prime = 1
+    for X in xrange(X + (R - (X % increment)), 1L << N, increment):
         # first check canidate against sieve_base
+        failed_sieve_test = 0
         for prime in sieve_base:
             if (X % prime) == 0:
-                is_possible_prime = 0
+                failed_sieve_test = 1
                 break
+        if failed_sieve_test:
+            continue
         # if e is given make sure that e and X-1 are coprime
         # this is not necessarily a strong prime criterion but usefull when
         # creating them for RSA where the p-1 and q-1 should be coprime to
         # the public exponent e
-        if e and is_possible_prime:
+        if e:
             if e & 1:
                 if GCD (e, X-1) != 1:
-                    is_possible_prime = 0
+                    continue
             else:
-                if GCD (e, (X-1)/2) != 1:
-                    is_possible_prime = 0
+                if GCD (e, (X-1)>>1) != 1:
+                    continue
         # do some Rabin-Miller-Tests
-        if is_possible_prime:
-            result = _rabinMillerTest (X, rabin_miller_rounds)
-            if result > 0:
-                break
-        X += increment
-		# abort when X has more bits than requested
-		# TODO: maybe we shouldn't abort but rather start over.
-        if X >= 1L << N:
-            raise RuntimeError ("Couln't find prime in field. "
-                                "Developer: Increase field_size")
-    return X
+        if _rabinMillerTest (X, rabin_miller_rounds) > 0:
+            return X
+    # TODO: maybe we shouldn't abort but rather start over.
+    raise RuntimeError ("Couln't find prime in field. "
+                        "Developer: Increase field_size")
 
 def isPrime(N, false_positive_prob=1e-6, randfunc=None):
     """isPrime(N:long, false_positive_prob:float, randfunc:callable):bool
diff --git a/lib/Crypto/__init__.py b/lib/Crypto/__init__.py
index d596e4f..4a1623a 100644
--- a/lib/Crypto/__init__.py
+++ b/lib/Crypto/__init__.py
@@ -42,5 +42,5 @@ __version__ = '2.3'     # See also below and setup.py
 __revision__ = "$Id$"
 
 # New software should look at this instead of at __version__ above.
-version_info = (2, 1, 0, 'final', 0)    # See also above and setup.py
+version_info = (2, 3, 0, 'final', 0)    # See also above and setup.py
 
diff --git a/src/_fastmath.c b/src/_fastmath.c
index 67c3cc5..2ac419e 100755
--- a/src/_fastmath.c
+++ b/src/_fastmath.c
@@ -873,7 +873,7 @@ getRNG (void)
 	if (!PyCallable_Check (new_func))
 	{
 		PyErr_SetString (PyExc_RuntimeError,
-						 "Cryptor.Random.new is not callable.");
+						 "Crypto.Random.new is not callable.");
 		return NULL;
 	}
 	rng = PyObject_CallObject (new_func, NULL);
@@ -1033,7 +1033,7 @@ sieve_field (char *field, unsigned long int field_size, mpz_t start)
 /* Tests if n is prime.
  * Returns 0 when n is definitly composite.
  * Returns 1 when n is probably prime.
- * every round reduces the chance of a false positive be at least 1/4.
+ * every round reduces the chance of a false positive by at least 1/4.
  *
  * If randfunc is omitted, then the python version Random.new().read is used.
  *
@@ -1108,8 +1108,7 @@ rabinMillerTest (mpz_t n, int rounds, PyObject *randfunc)
 		for (j = 0; j < b; ++j)
 		{
 			/* z = (z * z) % n */
-			mpz_mul (z, z, z);
-			mpz_mod (z, z, n);
+			mpz_powm_ui (z, z, 2, n);
 			if (mpz_cmp_ui (z, 1) == 0)
 			{
 				return_val = 0;
@@ -1161,7 +1160,7 @@ getStrongPrime (PyObject *self, PyObject *args, PyObject *kwargs)
 	mpf_t tmp_bound;
 	char *field;
 	double false_positive_prob;
-	int rabin_miller_rounds, is_possible_prime, error = 0;
+	int rabin_miller_rounds, failed_sieve_test, error = 0;
 	PyObject *prime, *randfunc=NULL;
 	static char *kwlist[] = {"N", "e", "false_positive_prob", "randfunc", NULL};
 	unsigned long int base_size = SIEVE_BASE_SIZE;
@@ -1284,27 +1283,29 @@ getStrongPrime (PyObject *self, PyObject *args, PyObject *kwargs)
 	mpz_mod (tmp[0], X, increment);  /* X mod (p1*p2) */
 	mpz_sub (tmp[1], R, tmp[0]);	 /* R - X mod (p1*p2) */
 	mpz_add (X, X, tmp[1]);			 /* X + (R - X mod (p1*p2)) */
-	while (1)
+	for (X; mpz_cmp (X, upper_bound) >= 0; mpz_add(X, X, increment))
 	{
-		is_possible_prime = 1;
+		failed_sieve_test = 1;
 		/* first check canidate against sieve_base */
 		for (j = 0; j < base_size; ++j)
 		{
 			if (mpz_divisible_ui_p (X, sieve_base[j]))
 			{
-				is_possible_prime = 0;
+				failed_sieve_test = 1;
 				break;
 			}
 		}
-		/* if e is given check for some more constrains */
-		if (e && is_possible_prime)
+		if (failed_sieve_test)
+			continue;
+		/* if e is given check for some more constraints */
+		if (e)
 		{
 			/* if e is odd make sure that e and X-1 are coprime */
 			if (e & 1)
 			{
 				mpz_sub_ui (tmp[0], X, 1);
 				if (mpz_gcd_ui (NULL, tmp[0], e) != 1)
-					is_possible_prime = 0;
+					continue;
 			}
 			/* if e is even make sure that e and (X-1)/2 are coprime. */
 			else
@@ -1312,39 +1313,25 @@ getStrongPrime (PyObject *self, PyObject *args, PyObject *kwargs)
 				mpz_sub_ui (tmp[0], X, 1);
 				mpz_divexact_ui (tmp[0], tmp[0], 2);
 				if (mpz_gcd_ui (NULL, tmp[0], e) != 1)
-					is_possible_prime = 0;
-			}
-		}
-		/* let gmp do some Rabin-Miller-Tests */
-		if (is_possible_prime)
-		{
-			Py_BLOCK_THREADS;
-			result = rabinMillerTest(X, rabin_miller_rounds, randfunc);
-			Py_UNBLOCK_THREADS;
-			if (result > 0)
-				break;
-			else if (result < 0)
-			{
-				error = 1;
-				goto cleanup;
+					continue;
 			}
 		}
-		mpz_add (X, X, increment);
-		/* abort when X is larger than upper_bound */
-		/* TODO: maybe we shouldn't abort but rather start over.
-		 *	   X probably was an unfortunate choice. */
-		if (mpz_cmp (X, upper_bound) >= 0)
-		{
-			error = 1;
-			Py_BLOCK_THREADS;
-			PyErr_SetString (PyExc_RuntimeError,
-							 "Couln't find prime in field. "
-							 "Developer: Increase field_size");
-			/* unblock threads because we acquire the GIL after cleanup */
-			Py_UNBLOCK_THREADS;
+		/* let us do some Rabin-Miller-Tests */
+		Py_BLOCK_THREADS;
+		result = rabinMillerTest(X, rabin_miller_rounds, randfunc);
+		Py_UNBLOCK_THREADS;
+		/* If successful jump to cleanup. Do *not* break from the for loop */
+		if (result > 0)
 			goto cleanup;
-		}
 	}
+	/* if the for loop terminates we didn't find a strong prime */
+	error = 1;
+	Py_BLOCK_THREADS;
+	PyErr_SetString (PyExc_RuntimeError,
+	                 "Couln't find prime in field. "
+	                 "Developer: Increase field_size");
+	/* unblock threads because we acquire the GIL after cleanup */
+	Py_UNBLOCK_THREADS;
 
 cleanup:
 	mpz_clear (range);