diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
 # CHANGELOG
 
+## 2.0.0
+### Changed
+* Change versioning to semver
+* Use `cryptonite` instead of deprecated `cryptohash` (broken backwards
+  compatibility)
+
 ## 1.0.0.1
 
 * Documentation typos fixed
diff --git a/one-time-password.cabal b/one-time-password.cabal
--- a/one-time-password.cabal
+++ b/one-time-password.cabal
@@ -1,8 +1,5 @@
 name:                one-time-password
--- PVP summary:      +-+------- breaking API changes
---                   | | +----- non-breaking API additions
---                   | | | +--- code changes with no API change
-version:             1.0.0.1
+version:             2.0.0
 synopsis:            HMAC-Based and Time-Based One-Time Passwords
 
 description: Implements HMAC-Based One-Time Password Algorithm as
@@ -11,7 +8,7 @@
 
 license:        MIT
 license-file:   LICENSE
-copyright:      (c) 2012 Artem Leshchev, 2015 Aleksey Uimanov
+copyright:      (c) 2012 Artem Leshchev, 2016 Aleksey Uimanov
 author:         Artem Leshchev, Aleksey Uimanov
 maintainer:     s9gf4ult@gmail.com <Aleksey Uimanov>
 homepage:       https://github.com/s9gf4ult/one-time-password
@@ -30,37 +27,30 @@
 library
   default-language:  Haskell2010
   hs-source-dirs:    src
-
   default-extensions: OverloadedStrings
-
+                    , ScopedTypeVariables
   exposed-modules:   Data.OTP
-
   build-depends:     base >= 3 && < 5
-                   , byteable
                    , bytestring
                    , cereal
-                   , cryptohash
+                   , cryptonite
+                   , memory
                    , time >= 1.1
-
   ghc-options: -Wall
 
 test-suite tests
   default-language: Haskell2010
   type:            exitcode-stdio-1.0
   hs-source-dirs:  test
-
+  ghc-options: -Wall
   default-extensions: ExistentialQuantification
                     , OverloadedStrings
                     , RankNTypes
-
   main-is:         Test.hs
-
   build-depends:   base >= 3 && < 5
                  , bytestring
-                 , cryptohash
+                 , cryptonite
                  , one-time-password
                  , tasty
                  , tasty-hunit
                  , time >= 1.1
-
-  ghc-options: -Wall
diff --git a/src/Data/OTP.hs b/src/Data/OTP.hs
--- a/src/Data/OTP.hs
+++ b/src/Data/OTP.hs
@@ -14,9 +14,9 @@
        ) where
 
 import Crypto.Hash
+import Crypto.MAC.HMAC
 import Data.Bits
-import Data.Byteable
-import Data.ByteString       (ByteString)
+import Data.ByteArray (unpack, ByteArrayAccess)
 import Data.Serialize.Get
 import Data.Serialize.Put
 import Data.Time
@@ -25,7 +25,7 @@
 
 import qualified Data.ByteString as BS
 
-{- | Compute HOTP using secret key and counter value.
+{- | Compute HMAC-Based One-Time Password using secret key and counter value.
 
 >>> hotp SHA1 "1234" 100 6
 317569
@@ -38,28 +38,28 @@
 
 -}
 
-hotp :: (HashAlgorithm a)
-     => a                       -- ^ Hashing algorithm from module "Crypto.Hash"
-     -> ByteString              -- ^ Shared secret
-     -> Word64                  -- ^ Counter value
-     -> Word                    -- ^ Number of digits in a password
-     -> Word32                  -- ^ HOTP
-hotp alg secr cnt len =
-    let h = trunc
-            $ toBytes
-            $ hmacAlg alg secr
-            $ runPut
-            $ putWord64be cnt
-    in h `mod` (10^len)
+hotp
+  :: forall a key
+   . (HashAlgorithm a, ByteArrayAccess key)
+  => a                       -- ^ Hashing algorithm from module "Crypto.Hash.IO"
+  -> key                     -- ^ Shared secret
+  -> Word64                  -- ^ Counter value
+  -> Word                    -- ^ Number of digits in a password
+  -> Word32                  -- ^ HOTP
+hotp _ key cnt digits =
+  let msg = runPut $ putWord64be cnt
+      h :: HMAC a
+      h = hmac key msg
+      w = trunc $ unpack h
+  in w `mod` (10 ^ digits)
   where
-    trunc :: ByteString -> Word32
+    trunc :: [Word8] -> Word32
     trunc b =
-        let offset = BS.last b .&. 15 -- take low 4 bits of last byte
-            rb = BS.take 4
-                 $ BS.drop (fromIntegral offset) b -- resulting 4 byte value
-        in case runGet getWord32be rb of
-            Left e -> error e
-            Right res -> res .&. (0x80000000 - 1) -- reset highest bit
+      let offset = last b .&. 15 -- take low 4 bits of last byte
+          rb = BS.pack $ take 4 $ drop (fromIntegral offset) b -- resulting 4 byte value
+      in case runGet getWord32be rb of
+      Left e    -> error e
+      Right res -> res .&. (0x80000000 - 1) -- reset highest bit
 
 {- | Check presented password against a valid range.
 
@@ -92,20 +92,21 @@
 
 -}
 
-hotpCheck :: (HashAlgorithm a)
-          => a                  -- ^ Hashing algorithm
-          -> ByteString         -- ^ Shared secret
-          -> (Word64, Word64)   -- ^ Valid counter range, before and after ideal
-          -> Word64             -- ^ Ideal (expected) counter value
-          -> Word               -- ^ Number of digits in a password
-          -> Word32             -- ^ Password entered by user
-          -> Bool               -- ^ True if password is valid
+hotpCheck
+  :: (HashAlgorithm a, ByteArrayAccess key)
+  => a                  -- ^ Hashing algorithm
+  -> key                -- ^ Shared secret
+  -> (Word64, Word64)   -- ^ Valid counter range, before and after ideal
+  -> Word64             -- ^ Ideal (expected) counter value
+  -> Word               -- ^ Number of digits in a password
+  -> Word32             -- ^ Password entered by user
+  -> Bool               -- ^ True if password is valid
 hotpCheck alg secr rng cnt len pass =
     let counters = counterRange rng cnt
         passwds = map (\c -> hotp alg secr c len) counters
     in any (pass ==) passwds
 
-{- | Compute a TOTP using secret key and time.
+{- | Compute a Time-Based One-Time Password using secret key and time.
 
 >>> totp SHA1 "1234" (read "2010-10-10 00:01:00 UTC") 30 6
 388892
@@ -121,13 +122,14 @@
 
 -}
 
-totp :: (HashAlgorithm a)
-     => a                       -- ^ Hash algorithm to use
-     -> ByteString              -- ^ Shared secret
-     -> UTCTime                 -- ^ Time of TOTP
-     -> Word64                  -- ^ Time period in seconds
-     -> Word                    -- ^ Number of digits in a password
-     -> Word32                  -- ^ TOTP
+totp
+  :: (HashAlgorithm a, ByteArrayAccess key)
+  => a         -- ^ Hash algorithm to use
+  -> key       -- ^ Shared secret
+  -> UTCTime   -- ^ Time of TOTP
+  -> Word64    -- ^ Time range in seconds
+  -> Word      -- ^ Number of digits in a password
+  -> Word32    -- ^ TOTP
 totp alg secr time period len =
     hotp alg secr (totpCounter time period) len
 
@@ -152,15 +154,16 @@
 True
 -}
 
-totpCheck :: (HashAlgorithm a)
-          => a                  -- ^ Hashing algorithm
-          -> ByteString         -- ^ Shared secret
-          -> (Word64, Word64)   -- ^ Valid counter range, before and after ideal
-          -> UTCTime            -- ^ Time of TOTP
-          -> Word64             -- ^ Period duration in seconds
-          -> Word               -- ^ Numer of digits in a password
-          -> Word32             -- ^ Password given by user
-          -> Bool               -- ^ True if password is valid
+totpCheck
+  :: (HashAlgorithm a, ByteArrayAccess key)
+  => a                  -- ^ Hashing algorithm
+  -> key                -- ^ Shared secret
+  -> (Word64, Word64)   -- ^ Valid counter range, before and after ideal
+  -> UTCTime            -- ^ Time of TOTP
+  -> Word64             -- ^ Time range in seconds
+  -> Word               -- ^ Numer of digits in a password
+  -> Word32             -- ^ Password given by user
+  -> Bool               -- ^ True if password is valid
 totpCheck alg secr rng time period len pass =
     let counters = totpCounterRange rng time period
         passwds = map (\c -> hotp alg secr c len) counters
@@ -181,9 +184,10 @@
 
 -}
 
-totpCounter :: UTCTime          -- ^ Time of totp
-            -> Word64           -- ^ Period duration in seconds
-            -> Word64           -- ^ Resulting counter
+totpCounter
+  :: UTCTime     -- ^ Time of totp
+  -> Word64      -- ^ Time range in seconds
+  -> Word64      -- ^ Resulting counter
 totpCounter time period =
     let timePOSIX = floor $ utcTimeToPOSIXSeconds time
     in timePOSIX `div` period
@@ -219,9 +223,10 @@
 RFC recommends avoiding excessively large values for counter ranges.
 -}
 
-counterRange :: (Word64, Word64) -- ^ Number of counters before and after ideal
-             -> Word64           -- ^ Ideal counter value
-             -> [Word64]
+counterRange
+  :: (Word64, Word64) -- ^ Number of counters before and after ideal
+  -> Word64           -- ^ Ideal counter value
+  -> [Word64]
 counterRange (tolow', tohigh') ideal =
     let tolow = min 500 tolow'
         tohigh = min 499 tohigh'
