diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2017, Gregor Kleen
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Gregor Kleen nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/changes.md b/changes.md
new file mode 100644
--- /dev/null
+++ b/changes.md
@@ -0,0 +1,3 @@
+# 0.0.0
+
+First published version
diff --git a/cryptoids-class.cabal b/cryptoids-class.cabal
new file mode 100644
--- /dev/null
+++ b/cryptoids-class.cabal
@@ -0,0 +1,33 @@
+name: cryptoids-class
+version: 0.0.0
+cabal-version: >=1.10
+build-type: Simple
+license: BSD3
+license-file: LICENSE
+maintainer: Gregor Kleen <aethoago@141.li>
+synopsis: Typeclass-based interface to cryptoids
+category: Web
+author: Gregor Kleen <aethoago@141.li>
+extra-source-files:
+    changes.md
+
+source-repository head
+    type: git
+    location: https://git.rheperire.org/cryptoids/cryptoids-class
+
+library
+    exposed-modules:
+        Data.CryptoID.Class
+        Data.CryptoID.Class.ImplicitNamespace
+    build-depends:
+        base >=4.10.1.0 && <4.11,
+        cryptoids-types >=0.0.0 && <0.1,
+        exceptions >=0.8.3 && <0.9
+    default-language: Haskell2010
+    default-extensions: DataKinds KindSignatures MultiParamTypeClasses
+                        TypeFamilies FlexibleContexts ConstraintKinds PatternSynonyms
+    hs-source-dirs: src
+    other-modules:
+        Paths_cryptoids_class
+    ghc-options: -Wall -fno-warn-name-shadowing
+
diff --git a/src/Data/CryptoID/Class.hs b/src/Data/CryptoID/Class.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/CryptoID/Class.hs
@@ -0,0 +1,35 @@
+{-|
+Description: Typeclass based interface to 'cryptoids'
+License: BSD3
+
+Polymorphic functions to perform cryptographic operations on 'CryptoID's in a monadic context
+-}
+module Data.CryptoID.Class
+  ( MonadCrypto(..)
+  , HasCryptoID(..)
+  ) where
+
+import Data.CryptoID (CryptoID)
+
+import GHC.TypeLits (Symbol)
+
+import Control.Monad.Catch (MonadThrow)
+
+-- | Class of monads granting reader access to a key and allowing for failure during cryptographic operations
+--
+-- This formulation is weaker than @MonadReader key@ (from mtl) in that it does not require @local@.
+class MonadThrow m => MonadCrypto (m :: * -> *) where
+  type MonadCryptoKey m :: *
+  cryptoIDKey :: (MonadCryptoKey m -> m a) -> m a
+
+-- | Multiparameter typeclass of @(namespace, ciphertext, plaintext, monad)@ tuples which allow for cryptographic operations on 'CryptoID's with appropriate @namespace@, @plaintext@, and @ciphertext@, utilising the state of @monad@
+--
+-- Instances of this typeclass are usually universally quantified over (at least) @namespace@, and @m@
+class MonadCrypto m => HasCryptoID (namespace :: Symbol) (ciphertext :: *) (plaintext :: *) (m :: * -> *) where
+  encrypt :: plaintext -> m (CryptoID namespace ciphertext)
+  -- ^ Encrypt a @plaintext@ in a fashion dependent on the @namespace@ and desired @ciphertext@-type retrieving the key from and throwing errors into @m@
+    
+  decrypt :: CryptoID namespace ciphertext -> m plaintext
+  -- ^ Encrypt a @ciphertext@ in a fashion dependent on the @namespace@ and desired @plaintext@-type retrieving the key from and throwing errors into @m@
+
+
diff --git a/src/Data/CryptoID/Class/ImplicitNamespace.hs b/src/Data/CryptoID/Class/ImplicitNamespace.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/CryptoID/Class/ImplicitNamespace.hs
@@ -0,0 +1,39 @@
+{-|
+Description: 'cryptoids' with implied namespaces
+License: BSD3
+
+When unambiguous it can be convenient to automatically infer the namespace based on the plaintext type.
+
+Consider using newtype wrappers in order to do so.
+-}
+module Data.CryptoID.Class.ImplicitNamespace
+  ( E.MonadCrypto(..)
+  , CryptoIDNamespace
+  , HasCryptoID
+  , CryptoID, pattern E.CryptoID, E.ciphertext
+  , encrypt, decrypt
+  ) where
+
+import qualified Data.CryptoID.Class as E
+import qualified Data.CryptoID as E
+
+import GHC.TypeLits (Symbol)
+  
+
+-- | Type family of @namespace@s associated to certain @plaintext@-types (parameterized over @ciphertext@ for completeness)
+type family CryptoIDNamespace (ciphertext :: *) (plaintext :: *) :: Symbol
+
+-- | 'E.HasCryptoID' reformulated to utilize 'CryptoIDNamespace'
+type HasCryptoID ciphertext plaintext = E.HasCryptoID (CryptoIDNamespace ciphertext plaintext) ciphertext plaintext
+
+-- | 'E.CryptoID' reformulated to utilize 'CryptoIDNamespace'
+type CryptoID ciphertext plaintext = E.CryptoID (CryptoIDNamespace ciphertext plaintext) ciphertext
+
+
+encrypt :: HasCryptoID ciphertext plaintext m => plaintext -> m (CryptoID ciphertext plaintext)
+-- ^ Specialised version of 'encrypt' for when @(plaintext, ciphertext)@ uniquely determines the namespace
+encrypt = E.encrypt
+
+decrypt :: HasCryptoID ciphertext plaintext m => CryptoID ciphertext plaintext -> m plaintext
+-- ^ Specialised version of 'decrypt' for when @(plaintext, ciphertext)@ uniquely determines the namespace
+decrypt = E.decrypt
