diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
 # Changelog for [`clash-prelude` package](http://hackage.haskell.org/package/clash-prelude)
 
+## 0.10.2 *October 21st 2015*
+* New features
+  * `ExtendingNum`, `BitPack`, and `Resize` instance for `Index`
+  * Add `bv2i`: convert `BitVector n` to `Index (2^n)`
+  * Export type-level operations from [ghc-typelits-extra](http://hackage.haskell.org/package/ghc-typelits-extra)
+
 ## 0.10.1 *October 16th 2015*
 * New features:
   * The `f` in `dfold p f`, now has an `SNat l` instead of a `Proxy l` as its first argument.
diff --git a/clash-prelude.cabal b/clash-prelude.cabal
--- a/clash-prelude.cabal
+++ b/clash-prelude.cabal
@@ -1,5 +1,5 @@
 Name:                 clash-prelude
-Version:              0.10.1
+Version:              0.10.2
 Synopsis:             CAES Language for Synchronous Hardware - Prelude library
 Description:
   CλaSH (pronounced ‘clash’) is a functional hardware description language that
@@ -155,6 +155,7 @@
                       data-default              >= 0.5.3,
                       integer-gmp               >= 0.5.1.0,
                       ghc-prim                  >= 0.3.1.0,
+                      ghc-typelits-extra        >= 0.1,
                       ghc-typelits-natnormalise >= 0.3,
                       lens                      >= 4.9,
                       QuickCheck                >= 2.7 && <2.9,
diff --git a/src/CLaSH/Prelude.hs b/src/CLaSH/Prelude.hs
--- a/src/CLaSH/Prelude.hs
+++ b/src/CLaSH/Prelude.hs
@@ -92,6 +92,7 @@
   , module CLaSH.Annotations.TopEntity
     -- ** Type-level natural numbers
   , module GHC.TypeLits
+  , module GHC.TypeLits.Extra
   , module CLaSH.Promoted.Nat
   , module CLaSH.Promoted.Nat.Literals
   , module CLaSH.Promoted.Nat.TH
@@ -121,6 +122,7 @@
 import Data.Bits
 import Data.Default
 import GHC.TypeLits
+import GHC.TypeLits.Extra
 import Language.Haskell.TH.Syntax  (Lift(..))
 #if __GLASGOW_HASKELL__ < 711
 import Language.Haskell.TH.Lift    (deriveLift)
diff --git a/src/CLaSH/Prelude/Safe.hs b/src/CLaSH/Prelude/Safe.hs
--- a/src/CLaSH/Prelude/Safe.hs
+++ b/src/CLaSH/Prelude/Safe.hs
@@ -79,6 +79,7 @@
   , module CLaSH.Annotations.TopEntity
     -- ** Type-level natural numbers
   , module GHC.TypeLits
+  , module GHC.TypeLits.Extra
   , module CLaSH.Promoted.Nat
   , module CLaSH.Promoted.Nat.Literals
   , module CLaSH.Promoted.Nat.TH
@@ -101,6 +102,7 @@
 import Control.Applicative
 import Data.Bits
 import GHC.TypeLits
+import GHC.TypeLits.Extra
 import Prelude                     hiding ((++), (!!), concat, drop, foldl,
                                            foldl1, foldr, foldr1, head, init,
                                            iterate, last, length, map, repeat,
diff --git a/src/CLaSH/Sized/Index.hs b/src/CLaSH/Sized/Index.hs
--- a/src/CLaSH/Sized/Index.hs
+++ b/src/CLaSH/Sized/Index.hs
@@ -1,11 +1,45 @@
+{-# LANGUAGE DataKinds        #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE MagicHash        #-}
+{-# LANGUAGE TypeOperators    #-}
+
 {-# LANGUAGE Trustworthy #-}
+
+{-# OPTIONS_GHC -fplugin GHC.TypeLits.Extra.Solver #-}
+{-# OPTIONS_GHC -fno-warn-unused-imports #-}
+{-# OPTIONS_HADDOCK show-extensions #-}
+
 {-|
 Copyright  :  (C) 2013-2015, University of Twente
 License    :  BSD2 (see the file LICENSE)
 Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>
 -}
 module CLaSH.Sized.Index
-  (Index)
+  (Index, bv2i)
 where
 
+import GHC.TypeLits               (KnownNat, type (^))
+import GHC.TypeLits.Extra         (CLog) -- documentation only
+
+import CLaSH.Sized.BitVector      (BitVector)
 import CLaSH.Sized.Internal.Index
+
+-- | An alternative implementation of 'CLaSH.Class.BitPack.unpack' for the
+-- 'Index' data type; for when you know the size of the 'BitVector' and want
+-- to determine the size of the 'Index'.
+--
+-- That is, the type of 'CLaSH.Class.BitPack.unpack' is:
+--
+-- @
+-- __unpack__ :: 'BitVector' ('CLog' 2 n) -> 'Index' n
+-- @
+--
+-- And is useful when you know the size of the 'Index', and want to get a value
+-- from a 'BitVector' that is large enough (@CLog 2 n@) enough to hold an
+-- 'Index'. Note that 'CLaSH.Class.BitPack.unpack' can fail at /run-time/ when
+-- the value inside the 'BitVector' is higher than 'n-1'.
+--
+-- 'bv2i' on the other hand will /never/ fail at run-time, because the
+-- 'BitVector' argument determines the size.
+bv2i :: KnownNat (2^n) => BitVector n -> Index (2^n)
+bv2i = unpack#
diff --git a/src/CLaSH/Sized/Internal/Index.hs b/src/CLaSH/Sized/Internal/Index.hs
--- a/src/CLaSH/Sized/Internal/Index.hs
+++ b/src/CLaSH/Sized/Internal/Index.hs
@@ -1,8 +1,11 @@
 {-# LANGUAGE DataKinds             #-}
 {-# LANGUAGE KindSignatures        #-}
 {-# LANGUAGE MagicHash             #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE TemplateHaskell       #-}
+{-# LANGUAGE TypeFamilies          #-}
 {-# LANGUAGE TypeOperators         #-}
+{-# LANGUAGE UndecidableInstances  #-}
 
 {-# LANGUAGE Unsafe #-}
 
@@ -17,6 +20,9 @@
   ( -- * Datatypes
     Index (..)
     -- * Type classes
+    -- ** BitConvert
+  , pack#
+  , unpack#
     -- ** Eq
   , eq#
   , neq#
@@ -37,21 +43,34 @@
   , (-#)
   , (*#)
   , fromInteger#
+    -- ** ExtendingNum
+  , plus#
+  , minus#
+  , times#
     -- ** Integral
   , quot#
   , rem#
   , toInteger#
+    -- ** Resize
+  , resize#
   )
 where
 
 import Data.Default               (Default (..))
 import Language.Haskell.TH        (TypeQ, appT, conT, litT, numTyLit, sigE)
 import Language.Haskell.TH.Syntax (Lift(..))
-import GHC.TypeLits               (KnownNat, Nat, natVal)
+import GHC.TypeLits               (KnownNat, Nat, type (+), type (-), type (*),
+                                   natVal)
+import GHC.TypeLits.Extra         (CLog)
 import Test.QuickCheck.Arbitrary  (Arbitrary (..), CoArbitrary (..),
                                    arbitrarySizedBoundedIntegral,
                                    coarbitraryIntegral, shrinkIntegral)
 
+import CLaSH.Class.BitPack            (BitPack (..))
+import CLaSH.Class.Num                (ExtendingNum (..))
+import CLaSH.Class.Resize             (Resize (..))
+import CLaSH.Sized.Internal.BitVector (BitVector (..))
+
 -- | Arbitrary-bounded unsigned integer represented by @ceil(log_2(n))@ bits.
 --
 -- Given an upper bound @n@, an 'Index' @n@ number has a range of: [0 .. @n@-1]
@@ -63,18 +82,31 @@
 -- >>> 1 + 2 :: Index 8
 -- 3
 -- >>> 2 + 6 :: Index 8
--- *** Exception: 8 is out of bounds: [0..7]
+-- *** Exception: CLaSH.Sized.Index: result 8 is out of bounds: [0..7]
 -- >>> 1 - 3 :: Index 8
--- *** Exception: -2 is out of bounds: [0..7]
+-- *** Exception: CLaSH.Sized.Index: result -2 is out of bounds: [0..7]
 -- >>> 2 * 3 :: Index 8
 -- 6
 -- >>> 2 * 4 :: Index 8
--- *** Exception: 8 is out of bounds: [0..7]
+-- *** Exception: CLaSH.Sized.Index: result 8 is out of bounds: [0..7]
 newtype Index (n :: Nat) =
     -- | The constructor, 'I', and the field, 'unsafeToInteger', are not
     -- synthesisable.
     I { unsafeToInteger :: Integer }
 
+instance KnownNat n => BitPack (Index n) where
+  type BitSize (Index n) = CLog 2 n
+  pack   = pack#
+  unpack = unpack#
+
+{-# NOINLINE pack# #-}
+pack# :: Index n -> BitVector (CLog 2 n)
+pack# (I i) = BV i
+
+{-# NOINLINE unpack# #-}
+unpack# :: KnownNat n => BitVector (CLog 2 n) -> Index n
+unpack# (BV i) = fromInteger_INLINE i
+
 instance Eq (Index n) where
   (==) = eq#
   (/=) = neq#
@@ -163,10 +195,34 @@
 fromInteger_INLINE i =
   let bound = natVal res
       i'    = i `mod` bound
-      err   = error (show i ++ " is out of bounds: [0.." ++ show (bound - 1) ++ "]")
+      err   = error ("CLaSH.Sized.Index: result " ++ show i ++
+                     " is out of bounds: [0.." ++ show (bound - 1) ++ "]")
       res   = if i' /= i then err else I i
   in  res
 
+instance ExtendingNum (Index m) (Index n) where
+  type AResult (Index m) (Index n) = Index (m + n - 1)
+  plus  = plus#
+  minus = minus#
+  type MResult (Index m) (Index n) = Index (((m - 1) * (n - 1)) + 1)
+  times = times#
+
+plus#, minus# :: Index m -> Index n -> Index (m + n - 1)
+{-# NOINLINE plus# #-}
+plus# (I a) (I b) = I (a + b)
+
+{-# NOINLINE minus# #-}
+minus# (I a) (I b) =
+  let z   = a - b
+      err = error ("CLaSH.Sized.Index.minus: result " ++ show z ++
+                   " is smaller than 0")
+      res = if z < 0 then err else I z
+  in  res
+
+{-# NOINLINE times# #-}
+times# :: Index m -> Index n -> Index (((m - 1) * (n - 1)) + 1)
+times# (I a) (I b) = I (a * b)
+
 instance KnownNat n => Real (Index n) where
   toRational = toRational . toInteger#
 
@@ -188,6 +244,16 @@
 {-# NOINLINE toInteger# #-}
 toInteger# :: Index n -> Integer
 toInteger# (I n) = n
+
+instance Resize Index where
+  resize     = resize#
+  zeroExtend = resize#
+  signExtend = resize#
+  truncateB  = resize#
+
+resize# :: KnownNat m => Index n -> Index m
+resize# (I i) = fromInteger_INLINE i
+{-# NOINLINE resize# #-}
 
 instance KnownNat n => Lift (Index n) where
   lift u@(I i) = sigE [| fromInteger# i |] (decIndex (natVal u))
diff --git a/src/CLaSH/Sized/Vector.hs b/src/CLaSH/Sized/Vector.hs
--- a/src/CLaSH/Sized/Vector.hs
+++ b/src/CLaSH/Sized/Vector.hs
@@ -567,7 +567,7 @@
 -- >>> :t imap (+) (2 :> 2 :> 2 :> 2 :> Nil)
 -- imap (+) (2 :> 2 :> 2 :> 2 :> Nil) :: Vec 4 (Index 4)
 -- >>> imap (+) (2 :> 2 :> 2 :> 2 :> Nil)
--- <2,3,*** Exception: 4 is out of bounds: [0..3]
+-- <2,3,*** Exception: CLaSH.Sized.Index: result 4 is out of bounds: [0..3]
 -- >>> imap (\i a -> fromIntegral i + a) (2 :> 2 :> 2 :> 2 :> Nil) :: Vec 4 (Unsigned 8)
 -- <2,3,4,5>
 --
@@ -585,7 +585,7 @@
 -- | Zip two vectors with a functions that also takes the elements' indices.
 --
 -- >>> izipWith (\i a b -> i + a + b) (2 :> 2 :> Nil)  (3 :> 3:> Nil)
--- <*** Exception: 3 is out of bounds: [0..1]
+-- <*** Exception: CLaSH.Sized.Index: result 3 is out of bounds: [0..1]
 -- >>> izipWith (\i a b -> fromIntegral i + a + b) (2 :> 2 :> Nil) (3 :> 3 :> Nil) :: Vec 2 (Unsigned 8)
 -- <5,6>
 --
