diff --git a/Crypto/PubKey/DH.hs b/Crypto/PubKey/DH.hs
--- a/Crypto/PubKey/DH.hs
+++ b/Crypto/PubKey/DH.hs
@@ -18,7 +18,7 @@
     , getShared
     ) where
 
-import Crypto.Number.ModArithmetic (exponantiation)
+import Crypto.Number.ModArithmetic (expSafe)
 import Crypto.Number.Prime (generateSafePrime)
 import Crypto.Number.Generate (generateOfSize)
 import Crypto.Types.PubKey.DH
@@ -39,8 +39,8 @@
 -- | generate a public number that is for the other party benefits.
 -- this number is usually called Y in DH text.
 generatePublic :: Params -> PrivateNumber -> PublicNumber
-generatePublic (Params p g) (PrivateNumber x) = PublicNumber $ exponantiation g x p
+generatePublic (Params p g) (PrivateNumber x) = PublicNumber $ expSafe g x p
 
 -- | generate a shared key using our private number and the other party public number
 getShared :: Params -> PrivateNumber -> PublicNumber -> SharedKey
-getShared (Params p _) (PrivateNumber x) (PublicNumber y) = SharedKey $ exponantiation y x p
+getShared (Params p _) (PrivateNumber x) (PublicNumber y) = SharedKey $ expSafe y x p
diff --git a/Crypto/PubKey/DSA.hs b/Crypto/PubKey/DSA.hs
--- a/Crypto/PubKey/DSA.hs
+++ b/Crypto/PubKey/DSA.hs
@@ -22,7 +22,7 @@
 import Crypto.Random.API
 import Data.Maybe
 import Data.ByteString (ByteString)
-import Crypto.Number.ModArithmetic (exponantiation, inverse)
+import Crypto.Number.ModArithmetic (expFast, expSafe, inverse)
 import Crypto.Number.Serialize
 import Crypto.Number.Generate
 import Crypto.Types.PubKey.DSA
@@ -43,7 +43,7 @@
           -- compute r,s
           kInv      = fromJust $ inverse k q
           hm        = os2ip $ hash msg
-          r         = expmod g k p `mod` q
+          r         = expSafe g k p `mod` q
           s         = (kInv * (hm + x * r)) `mod` q
 
 -- | sign message using the private key.
@@ -68,7 +68,4 @@
           w       = fromJust $ inverse s q
           u1      = (hm*w) `mod` q
           u2      = (r*w) `mod` q
-          v       = ((expmod g u1 p) * (expmod y u2 p)) `mod` p `mod` q
-
-expmod :: Integer -> Integer -> Integer -> Integer
-expmod = exponantiation
+          v       = ((expFast g u1 p) * (expFast y u2 p)) `mod` p `mod` q
diff --git a/Crypto/PubKey/ElGamal.hs b/Crypto/PubKey/ElGamal.hs
--- a/Crypto/PubKey/ElGamal.hs
+++ b/Crypto/PubKey/ElGamal.hs
@@ -33,7 +33,7 @@
     ) where
 
 import Data.ByteString (ByteString)
-import Crypto.Number.ModArithmetic (exponantiation, inverse)
+import Crypto.Number.ModArithmetic (expSafe, expFast, inverse)
 import Crypto.Number.Generate (generateMax)
 import Crypto.Number.Serialize (os2ip)
 import Crypto.Number.Basic (gcde_binary)
@@ -66,14 +66,14 @@
 -- | generate a public number that is for the other party benefits.
 -- this number is usually called h=g^a
 generatePublic :: Params -> PrivateNumber -> PublicNumber
-generatePublic (Params p g) (PrivateNumber a) = PublicNumber $ exponantiation g a p
+generatePublic (Params p g) (PrivateNumber a) = PublicNumber $ expSafe g a p
 
 -- | encrypt with a specified ephemeral key
 -- do not reuse ephemeral key.
 encryptWith :: EphemeralKey -> Params -> PublicNumber -> Integer -> (Integer,Integer)
 encryptWith (EphemeralKey b) (Params p g) (PublicNumber h) m = (c1,c2)
-    where s  = exponantiation h b p
-          c1 = exponantiation g b p
+    where s  = expSafe h b p
+          c1 = expSafe g b p
           c2 = (s * m) `mod` p
 
 -- | encrypt a message using params and public keys
@@ -85,7 +85,7 @@
 -- | decrypt message
 decrypt :: Params -> PrivateNumber -> (Integer, Integer) -> Integer
 decrypt (Params p _) (PrivateNumber a) (c1,c2) = (c2 * sm1) `mod` p
-    where s   = exponantiation c1 a p
+    where s   = expSafe c1 a p
           sm1 = fromJust $ inverse s p -- always inversible in Zp
 
 -- | sign a message with an explicit k number
@@ -105,7 +105,7 @@
     | k >= p-1 || d > 1 = Nothing -- gcd(k,p-1) is not 1
     | s == 0            = Nothing
     | otherwise         = Just $ Signature (r,s)
-    where r          = exponantiation g k p
+    where r          = expSafe g k p
           h          = os2ip $ hashF msg
           s          = ((h - x*r) * kInv) `mod` (p-1)
           (kInv,_,d) = gcde_binary k (p-1)
@@ -140,5 +140,5 @@
     | or [r <= 0,r >= p,s <= 0,s >= (p-1)] = False
     | otherwise                            = lhs == rhs
     where h   = os2ip $ hashF msg
-          lhs = exponantiation g h p
-          rhs = (exponantiation y r p * exponantiation r s p) `mod` p
+          lhs = expFast g h p
+          rhs = (expFast y r p * expFast r s p) `mod` p
diff --git a/Crypto/PubKey/RSA/Prim.hs b/Crypto/PubKey/RSA/Prim.hs
--- a/Crypto/PubKey/RSA/Prim.hs
+++ b/Crypto/PubKey/RSA/Prim.hs
@@ -16,13 +16,13 @@
 import Data.ByteString (ByteString)
 import Crypto.PubKey.RSA.Types (Blinder(..))
 import Crypto.Types.PubKey.RSA
-import Crypto.Number.ModArithmetic (exponantiation)
+import Crypto.Number.ModArithmetic (expFast, expSafe)
 import Crypto.Number.Serialize (os2ip, i2ospOf_)
 
 {- dpSlow computes the decrypted message not using any precomputed cache value.
    only n and d need to valid. -}
 dpSlow :: PrivateKey -> ByteString -> ByteString
-dpSlow pk c = i2ospOf_ (private_size pk) $ expmod (os2ip c) (private_d pk) (private_n pk)
+dpSlow pk c = i2ospOf_ (private_size pk) $ expSafe (os2ip c) (private_d pk) (private_n pk)
 
 {- dpFast computes the decrypted message more efficiently if the
    precomputed private values are available. mod p and mod q are faster
@@ -31,17 +31,17 @@
 dpFast (Blinder r rm1) pk c =
     i2ospOf_ (private_size pk) (multiplication rm1 (m2 + h * (private_q pk)) (private_n pk))
     where
-        re  = expmod r (public_e $ private_pub pk) (private_n pk)
+        re  = expFast r (public_e $ private_pub pk) (private_n pk)
         iC  = multiplication re (os2ip c) (private_n pk)
-        m1  = expmod iC (private_dP pk) (private_p pk)
-        m2  = expmod iC (private_dQ pk) (private_q pk)
+        m1  = expSafe iC (private_dP pk) (private_p pk)
+        m2  = expSafe iC (private_dQ pk) (private_q pk)
         h   = ((private_qinv pk) * (m1 - m2)) `mod` (private_p pk)
 
 dpFastNoBlinder :: PrivateKey -> ByteString -> ByteString
 dpFastNoBlinder pk c = i2ospOf_ (private_size pk) (m2 + h * (private_q pk))
      where iC = os2ip c
-           m1 = expmod iC (private_dP pk) (private_p pk)
-           m2 = expmod iC (private_dQ pk) (private_q pk)
+           m1 = expSafe iC (private_dP pk) (private_p pk)
+           m2 = expSafe iC (private_dQ pk) (private_q pk)
            h  = ((private_qinv pk) * (m1 - m2)) `mod` (private_p pk)
 
 -- | Compute the RSA decrypt primitive.
@@ -54,10 +54,7 @@
 
 -- | Compute the RSA encrypt primitive
 ep :: PublicKey -> ByteString -> ByteString
-ep pk m = i2ospOf_ (public_size pk) $ expmod (os2ip m) (public_e pk) (public_n pk)
-
-expmod :: Integer -> Integer -> Integer -> Integer
-expmod = exponantiation
+ep pk m = i2ospOf_ (public_size pk) $ expFast (os2ip m) (public_e pk) (public_n pk)
 
 -- | multiply 2 integers in Zm only performing the modulo operation if necessary
 multiplication :: Integer -> Integer -> Integer -> Integer
diff --git a/Tests/T.hs b/Tests/T.hs
new file mode 100644
--- /dev/null
+++ b/Tests/T.hs
@@ -0,0 +1,44 @@
+{-# LANGUAGE BangPatterns #-}
+module Main where
+
+import PregenKeys
+import Control.Applicative
+import qualified Crypto.Hash.SHA1 as SHA1
+import qualified Crypto.PubKey.RSA as RSA
+import qualified Crypto.PubKey.RSA.OAEP as RSAOAEP
+import qualified Crypto.PubKey.RSA.PKCS15 as RSAPKCS15
+import qualified Data.ByteString as B
+
+import Crypto.Random
+
+priv = rsaPrivatekey
+pub  = rsaPublickey
+oaepParams = RSAOAEP.defaultOAEPParams SHA1.hash
+
+doEncrypt = False
+
+nbEncrypt = 944242
+nbDecrypt = 64325
+
+main = do
+    system <- cprgCreate <$> createEntropyPool :: IO SystemRNG
+    if doEncrypt
+        then do
+            putStrLn $ show $ justEncrypt system nbEncrypt B.empty
+        else do
+            let t = either (error . show) id $ fst $ RSAPKCS15.encrypt system pub msg
+    --let t = either (error . show) id $ RSAOAEP.encryptWithSeed (B.replicate 20 0) oaepParams pub msg
+ 
+            putStrLn $ show $ decryptEncrypt nbDecrypt (t, msg)
+  where msg = B.replicate 10 4
+        decryptEncrypt 0 (!bEnc, !b) = b
+        decryptEncrypt n (!bEnc, !b) =
+            let bDec = either (error . show) id $ RSAPKCS15.decrypt Nothing priv bEnc in
+            --let bDec = either (error . show) id $ RSAOAEP.decrypt Nothing oaepParams priv bEnc in
+            decryptEncrypt (n-1) (bEnc, bDec)
+
+        justEncrypt _ 0 (!bEnc) = bEnc
+        justEncrypt rng n (!bEnc) =
+            let bEnc2 = either (error . show) id $ fst $ RSAPKCS15.encrypt rng pub msg in
+            justEncrypt rng (n-1) bEnc2 
+            
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.1
+Version:             0.2.2
 Description:
     Public Key cryptography
     .
@@ -31,7 +31,7 @@
                    , crypto-random >= 0.0 && < 0.1
                    , crypto-pubkey-types >= 0.4 && < 0.5
                    , cryptohash >= 0.9.1
-                   , crypto-numbers >= 0.2
+                   , crypto-numbers >= 0.2.2
   Exposed-modules:   Crypto.PubKey.RSA
                      Crypto.PubKey.RSA.PKCS15
                      Crypto.PubKey.RSA.OAEP
