diff --git a/Crypto/PubKey/DSA.hs b/Crypto/PubKey/DSA.hs
--- a/Crypto/PubKey/DSA.hs
+++ b/Crypto/PubKey/DSA.hs
@@ -5,6 +5,7 @@
 -- Stability   : experimental
 -- Portability : Good
 --
+-- An implementation of the Digital Signature Algorithm (DSA)
 
 module Crypto.PubKey.DSA
     ( Params(..)
diff --git a/Crypto/PubKey/RSA.hs b/Crypto/PubKey/RSA.hs
--- a/Crypto/PubKey/RSA.hs
+++ b/Crypto/PubKey/RSA.hs
@@ -18,41 +18,60 @@
 
 import Crypto.Random.API
 import Crypto.Types.PubKey.RSA
-import Crypto.Number.ModArithmetic (inverseCoprimes)
+import Crypto.Number.ModArithmetic (inverse, inverseCoprimes)
 import Crypto.Number.Generate (generateMax)
 import Crypto.Number.Prime (generatePrime)
 import Crypto.PubKey.RSA.Types
 
--- | generate a public key and private key with p and q.
+-- | Generate a key pair given p and q.
 --
--- p and q need to be distinct primes numbers.
+-- p and q need to be distinct prime numbers.
 --
--- e need to be coprime to phi=(p-1)*(q-1). a small hamming weight results in better performance.
--- 0x10001 is a popular choice. 3 is popular as well, but proven to not be as secure for some cases.
-generateWith :: (Integer, Integer) -> Int -> Integer -> (PublicKey, PrivateKey)
-generateWith (p,q) size e = (pub,priv)
-    where n   = p*q
-          phi = (p-1)*(q-1)
-          d   = inverseCoprimes e phi -- e and phi need to be coprime
-          pub = PublicKey { public_size = size
-                          , public_n    = n
-                          , public_e    = e
-                          }
-          priv = PrivateKey { private_pub  = pub
+-- e need to be coprime to phi=(p-1)*(q-1). If that's not the
+-- case, the function will not return a key pair.
+-- A small hamming weight results in better performance.
+--
+-- * e=0x10001 is a popular choice
+--
+-- * e=3 is popular as well, but proven to not be as secure for some cases.
+--
+generateWith :: (Integer, Integer) -- ^ chosen distinct primes p and q
+             -> Int                -- ^ size in bytes
+             -> Integer            -- ^ RSA public exponant 'e'
+             -> Maybe (PublicKey, PrivateKey)
+generateWith (p,q) size e =
+    case inverse e phi of
+        Nothing -> Nothing
+        Just d  -> Just (pub,priv d)
+  where n   = p*q
+        phi = (p-1)*(q-1)
+        -- q and p should be *distinct* *prime* numbers, hence always coprime
+        qinv = inverseCoprimes q p
+        pub = PublicKey { public_size = size
+                        , public_n    = n
+                        , public_e    = e
+                        }
+        priv d = PrivateKey { private_pub  = pub
                             , private_d    = d
                             , private_p    = p
                             , private_q    = q
                             , private_dP   = d `mod` (p-1)
                             , private_dQ   = d `mod` (q-1)
-                            , private_qinv = inverseCoprimes q p -- q and p are coprime
+                            , private_qinv = qinv
                             }
 
 -- | generate a pair of (private, public) key of size in bytes.
-generate :: CPRG g => g -> Int -> Integer -> ((PublicKey, PrivateKey), g)
-generate rng size e = do
-    let (pq, rng') = generatePQ rng
-     in (generateWith pq size e, rng')
-    where
+generate :: CPRG g
+         => g       -- ^ CPRG
+         -> Int     -- ^ size in bytes
+         -> Integer -- ^ RSA public exponant 'e'
+         -> ((PublicKey, PrivateKey), g)
+generate rng size e = loop rng
+  where loop g = -- loop until we find a valid key pair given e
+            let (pq, g') = generatePQ g
+             in case generateWith pq size e of
+                    Nothing -> loop g'
+                    Just pp -> (pp, g')
         generatePQ g =
             let (p, g')  = generatePrime g (8 * (size `div` 2))
                 (q, g'') = generateQ p g'
@@ -67,8 +86,7 @@
 -- public key value N.
 generateBlinder :: CPRG g
                 => g       -- ^ CPRG to use.
-                -> Integer -- ^ RSA public N parameters.
+                -> Integer -- ^ RSA public N parameter.
                 -> (Blinder, g)
-generateBlinder rng n =
-    let (r, rng') = generateMax rng n
-     in (Blinder r (inverseCoprimes r n), rng')
+generateBlinder rng n = (Blinder r (inverseCoprimes r n), rng')
+  where (r, rng') = generateMax rng n
diff --git a/crypto-pubkey.cabal b/crypto-pubkey.cabal
--- a/crypto-pubkey.cabal
+++ b/crypto-pubkey.cabal
@@ -1,5 +1,5 @@
 Name:                crypto-pubkey
-Version:             0.2.0
+Version:             0.2.1
 Description:
     Public Key cryptography
     .
