diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2017-03-11  Vladimir Shabanov  <vshabanoff@gmail.com>
+
+	* HsOpenSSL.cabal (Version): Bump version to 0.11.4.2
+
+	* Ported BN to integer-gmp-1.0.x,
+	by SX91 (#17).
+
 2017-02-27  Vladimir Shabanov  <vshabanoff@gmail.com>
 
 	* HsOpenSSL.cabal (Version): Bump version to 0.11.4.1
diff --git a/HsOpenSSL.cabal b/HsOpenSSL.cabal
--- a/HsOpenSSL.cabal
+++ b/HsOpenSSL.cabal
@@ -12,7 +12,7 @@
     <http://hackage.haskell.org/package/tls>, which is a pure Haskell
     implementation of SSL.
     .
-Version:       0.11.4.1
+Version:       0.11.4.2
 License:       PublicDomain
 License-File:  COPYING
 Author:        Adam Langley, Mikhail Vorozhtsov, PHO, Taru Karttunen
@@ -68,15 +68,12 @@
         network    >= 2.1   && < 2.7,
         time       >= 1.5   && < 1.7
 
-    if flag(fast-bignum)
+    if flag(fast-bignum) && impl(ghc >= 7.10.1)
+        -- only new integer-gmp 1.0.0 is supported
+        -- and it only works in OpenSSL version < 1.1.0 where BIGNUM
+        -- wasn't opaque structure.
         CPP-Options: -DFAST_BIGNUM
-        if impl(ghc >= 6.11)
-            -- TODO: integer-gmp >= 1 is not supported yet.
-            -- https://github.com/phonohawk/HsOpenSSL/issues/36
-            Build-Depends: integer-gmp >= 0.2 && < 1
-            -- Doesn't work since GHC 7.10.1 (integer-gmp-1.0.0.0)
-        else
-            Build-Depends: ghc-prim, integer
+        Build-Depends: integer-gmp >= 1.0.0 && < 1.1.0
 
     if os(darwin) && flag(homebrew-openssl)
         Include-Dirs: /usr/local/opt/openssl/include
diff --git a/OpenSSL/BN.hsc b/OpenSSL/BN.hsc
--- a/OpenSSL/BN.hsc
+++ b/OpenSSL/BN.hsc
@@ -1,3 +1,10 @@
+#include "HsOpenSSL.h"
+
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && defined(FAST_BIGNUM))
+-- BIGNUM is opaque type in OpenSSL 1.1.x
+#undef FAST_BIGNUM
+#endif
+
 #if defined(FAST_BIGNUM)
 {-# LANGUAGE BangPatterns             #-}
 #endif
@@ -42,7 +49,7 @@
     , prandIntegerOneToNMinusOne
     )
     where
-#include "HsOpenSSL.h"
+
 import           Control.Exception hiding (try)
 import qualified Data.ByteString as BS
 import           Foreign.Marshal
@@ -54,14 +61,7 @@
 #if defined(FAST_BIGNUM)
 import           Foreign.C.Types
 import           GHC.Base
-#  if MIN_VERSION_integer_gmp(0,2,0)
 import           GHC.Integer.GMP.Internals
-#  else
-import           GHC.Num
-import           GHC.Prim
-import           GHC.Integer.Internals
-import           GHC.IOBase (IO(..))
-#  endif
 #else
 import           Control.Monad
 import           Foreign.C
@@ -167,7 +167,7 @@
             negative <- (#peek BIGNUM, neg) (unwrapBN bn) :: IO CInt
             if negative == 0
                then return $ S## i
-               else return $ 0 - (S## i)
+               else return $ S## (0## -## i)
     _ -> do
       let !(I## nlimbsi) = fromIntegral nlimbs
           !(I## limbsize) = (#size unsigned long)
@@ -177,8 +177,8 @@
       _ <- _copy_in ba limbs $ fromIntegral $ nlimbs * (#size unsigned long)
       negative <- (#peek BIGNUM, neg) (unwrapBN bn) :: IO CInt
       if negative == 0
-         then return $ J## nlimbsi ba
-         else return $ 0 - (J## nlimbsi ba)
+         then return $ Jp## (byteArrayToBigNat## ba nlimbsi)
+         else return $ Jn## (byteArrayToBigNat## ba nlimbsi)
 
 -- | This is a GHC specific, fast conversion between Integers and OpenSSL
 --   bignums. It returns a malloced BigNum.
@@ -212,9 +212,15 @@
   (#poke BIGNUM, neg) bnptr (if (I## v) < 0 then one else 0)
   return (wrapBN bnptr)
 
-integerToBN v@(J## nlimbs_ bytearray)
-  | v >= 0 = do
-      let nlimbs = (I## nlimbs_)
+integerToBN v =
+  case v of
+    Jp## bn -> convert 0 bn
+    Jn## bn -> convert 1 bn
+    S## _   -> undefined
+  where
+    convert :: CInt -> BigNat -> IO BigNum
+    convert negValue bn@(BN## bytearray) = do
+      let nlimbs = I## (sizeofBigNat## bn)
       bnptr <- mallocBytes (#size BIGNUM)
       limbs <- mallocBytes ((#size unsigned long) * nlimbs)
       (#poke BIGNUM, d) bnptr limbs
@@ -222,12 +228,8 @@
       _ <- _copy_out limbs bytearray (fromIntegral $ (#size unsigned long) * nlimbs)
       (#poke BIGNUM, top) bnptr ((fromIntegral nlimbs) :: CInt)
       (#poke BIGNUM, dmax) bnptr ((fromIntegral nlimbs) :: CInt)
-      (#poke BIGNUM, neg) bnptr (0 :: CInt)
+      (#poke BIGNUM, neg) bnptr negValue
       return (wrapBN bnptr)
-  | otherwise = do bnptr <- integerToBN (0-v)
-                   (#poke BIGNUM, neg) (unwrapBN bnptr) (1 :: CInt)
-                   return bnptr
-
 #endif
 
 -- TODO: we could make a function which doesn't even allocate BN data if we
