diff --git a/src/consumer-db.cpp b/src/consumer-db.cpp
new file mode 100644
index 0000000..6baa696
--- /dev/null
+++ b/src/consumer-db.cpp
@@ -0,0 +1,130 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  Regents of the University of California
+ *
+ * This file is part of ndn-group-encrypt (Group-based Encryption Protocol for NDN).
+ * See AUTHORS.md for complete list of ndn-group-encrypt authors and contributors.
+ *
+ * ndn-group-encrypt is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-group-encrypt is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-group-encrypt, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author Zhiyi Zhang <dreamerbarrychang@gmail.com>
+ */
+
+#include "consumer-db.hpp"
+
+#include <sqlite3.h>
+#include <boost/filesystem.hpp>
+#include <ndn-cxx/util/sqlite3-statement.hpp>
+
+namespace ndn {
+namespace gep {
+
+using util::Sqlite3Statement;
+
+static const std::string INITIALIZATION =
+  "CREATE TABLE IF NOT EXISTS                         \n"
+  "  decryptionkeys(                                  \n"
+  "    key_id              INTEGER PRIMARY KEY,       \n"
+  "    key_name            BLOB NOT NULL,             \n"
+  "    key_buf             BLOB NOT NULL              \n"
+  "  );                                               \n"
+  "CREATE UNIQUE INDEX IF NOT EXISTS                  \n"
+  "   KeyNameIndex ON decryptionkeys(key_name);       \n"
+  "CREATE TABLE IF NOT EXISTS                         \n"
+  "  consumer(                                        \n"
+  "    prefix              BLOB PRIMARY KEY           \n"
+  "  );                                               \n";
+
+class ConsumerDB::Impl
+{
+public:
+  Impl(const std::string& dbDir)
+  {
+    // open Database
+
+    int result = sqlite3_open_v2(dbDir.c_str(), &m_database,
+                                 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
+#ifdef NDN_CXX_DISABLE_SQLITE3_FS_LOCKING
+                                 "unix-dotfile"
+#else
+                                 nullptr
+#endif
+                                 );
+
+    if (result != SQLITE_OK)
+      BOOST_THROW_EXCEPTION(Error("GroupManager DB cannot be opened/created: " + dbDir));
+
+    // initialize database specific tables
+    char* errorMessage = nullptr;
+    result = sqlite3_exec(m_database, INITIALIZATION.c_str(), nullptr, nullptr, &errorMessage);
+    if (result != SQLITE_OK && errorMessage != nullptr) {
+      sqlite3_free(errorMessage);
+      BOOST_THROW_EXCEPTION(Error("GroupManager DB cannot be initialized"));
+    }
+  }
+
+  ~Impl()
+  {
+    sqlite3_close(m_database);
+  }
+
+public:
+  sqlite3* m_database;
+};
+
+
+ConsumerDB::ConsumerDB(const std::string& dbDir)
+  : m_impl(new Impl(dbDir))
+{
+}
+
+ConsumerDB::~ConsumerDB() = default;
+
+const Buffer
+ConsumerDB::getKey(const Name& keyName) const
+{
+  Sqlite3Statement statement(m_impl->m_database,
+                             "SELECT key_buf FROM decryptionkeys\
+                              WHERE key_name=?");
+  statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
+
+  Buffer result;
+  if (statement.step() == SQLITE_ROW) {
+    result = Buffer(statement.getBlob(0), statement.getSize(0));
+  }
+  return result;
+}
+
+void
+ConsumerDB::addKey(const Name& keyName, const Buffer& keyBuf)
+{
+  Sqlite3Statement statement(m_impl->m_database,
+                             "INSERT INTO decryptionkeys(key_name, key_buf)\
+                              values (?, ?)");
+  statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
+  statement.bind(2, keyBuf.buf(), keyBuf.size(), SQLITE_TRANSIENT);
+
+  if (statement.step() != SQLITE_DONE)
+    BOOST_THROW_EXCEPTION(Error("Cannot add the key to database"));
+}
+
+void
+ConsumerDB::deleteKey(const Name& keyName)
+{
+  Sqlite3Statement statement(m_impl->m_database,
+                             "DELETE FROM decryptionkeys WHERE key_name=?");
+  statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
+  statement.step();
+}
+
+} // namespace gep
+} // namespace ndn
diff --git a/src/consumer-db.hpp b/src/consumer-db.hpp
new file mode 100644
index 0000000..4b1f971
--- /dev/null
+++ b/src/consumer-db.hpp
@@ -0,0 +1,83 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  Regents of the University of California
+ *
+ * This file is part of ndn-group-encrypt (Group-based Encryption Protocol for NDN).
+ * See AUTHORS.md for complete list of ndn-group-encrypt authors and contributors.
+ *
+ * ndn-group-encrypt is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-group-encrypt is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-group-encrypt, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author Zhiyi Zhang <dreamerbarrychang@gmail.com>
+ */
+
+#ifndef NDN_GEP_CONSUMER_DB_HPP
+#define NDN_GEP_CONSUMER_DB_HPP
+
+#include "common.hpp"
+
+namespace ndn {
+namespace gep {
+
+/**
+ * @brief ConsumerDB is a class to manage decryption keys for consumer.
+ */
+class ConsumerDB
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+public:
+  explicit
+  ConsumerDB(const std::string& dbDir);
+
+  ~ConsumerDB();
+
+public:
+  /**
+   * @brief Get the key with @p keyName from database.
+   *
+   * @return Empty buffer when there is no key with @p keyName in database
+   */
+  const Buffer
+  getKey(const Name& keyName) const;
+
+  /**
+   * @brief Add the key with @p keyName and @p keyBuf to database.
+   *
+   * @throw Error when a key with the same name already exists in database.
+   */
+  void
+  addKey(const Name& keyName, const Buffer& keyBuf);
+
+  /**
+   * @brief Remove the key with @p keyName from the database.
+   */
+  void
+  deleteKey(const Name& keyName);
+
+private:
+  class Impl;
+  unique_ptr<Impl> m_impl;
+};
+
+} // namespace gep
+} // namespace ndn
+
+#endif // NDN_GEP_CONSUMER_DB_HPP
diff --git a/src/consumer.cpp b/src/consumer.cpp
new file mode 100644
index 0000000..f515652
--- /dev/null
+++ b/src/consumer.cpp
@@ -0,0 +1,284 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  Regents of the University of California
+ *
+ * This file is part of ndn-group-encrypt (Group-based Encryption Protocol for NDN).
+ * See AUTHORS.md for complete list of ndn-group-encrypt authors and contributors.
+ *
+ * ndn-group-encrypt is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-group-encrypt is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-group-encrypt, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author Zhiyi Zhang <dreamerbarrychang@gmail.com>
+ * @author Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#include "consumer.hpp"
+#include "encrypted-content.hpp"
+
+namespace ndn {
+namespace gep {
+
+// public
+Consumer::Consumer(Face& face, const Name& groupName, const Name& consumerName, const std::string& dbDir)
+  : m_db(dbDir)
+  , m_validator(new ValidatorNull)
+  , m_face(face)
+  , m_groupName(groupName)
+  , m_consumerName(consumerName)
+{
+}
+
+void
+Consumer::setGroup(const Name& groupName)
+{
+  m_groupName = groupName;
+}
+
+void
+Consumer::addDecryptionKey(const Name& keyName, const Buffer& keyBuf)
+{
+  BOOST_ASSERT(m_consumerName.isPrefixOf(keyName));
+
+  m_db.addKey(keyName, keyBuf);
+}
+
+void
+Consumer::consume(const Name& contentName,
+                  const ConsumptionCallBack& consumptionCallBack,
+                  const ErrorCallBack& errorCallBack)
+{
+  shared_ptr<Interest> interest = make_shared<Interest>(contentName);
+
+  // prepare callback functions
+  auto onData = [=] (const Interest& contentInterest, const Data& contentData) {
+    if (!contentInterest.matchesData(contentData))
+      return;
+
+    this->m_validator->validate(contentData,
+      [=] (const shared_ptr<const Data>& validData) {
+        // decrypt content
+        decryptContent(*validData,
+                       [=] (const Buffer& plainText) {consumptionCallBack(contentData, plainText);},
+                       errorCallBack);
+      },
+      [=] (const shared_ptr<const Data>& d, const std::string& e) {
+        errorCallBack(ErrorCode::Validation, e);
+      });
+  };
+
+  auto onTimeout = [=] (const Interest& contentInterest) {
+    // we should re-try at least once.
+    this->m_face.expressInterest(*interest, onData,
+      [=] (const Interest& contentInterest) {
+        errorCallBack(ErrorCode::Timeout, interest->getName().toUri());
+      });
+  };
+
+  // express Interest packet
+  m_face.expressInterest(*interest, onData, onTimeout);
+}
+
+// private
+
+void
+Consumer::decrypt(const Block& encryptedBlock,
+                  const Buffer& keyBits,
+                  const PlainTextCallBack& plainTextCallBack,
+                  const ErrorCallBack& errorCallBack)
+{
+  EncryptedContent encryptedContent(encryptedBlock);
+  const Buffer& payload = encryptedContent.getPayload();
+
+  switch (encryptedContent.getAlgorithmType()) {
+    case tlv::AlgorithmAesCbc: {
+      // prepare parameter
+      algo::EncryptParams decryptParams(tlv::AlgorithmAesCbc);
+      decryptParams.setIV(encryptedContent.getInitialVector().buf(),
+                          encryptedContent.getInitialVector().size());
+
+      // decrypt content
+      Buffer content = algo::Aes::decrypt(keyBits.buf(), keyBits.size(),
+                                          payload.buf(), payload.size(),
+                                          decryptParams);
+      plainTextCallBack(content);
+      break;
+    }
+    case tlv::AlgorithmRsaOaep: {
+      // prepare parameter
+      algo::EncryptParams decryptParams(tlv::AlgorithmRsaOaep);
+
+      // decrypt content
+      Buffer content = algo::Rsa::decrypt(keyBits.buf(), keyBits.size(),
+                                          payload.buf(), payload.size(),
+                                          decryptParams);
+      plainTextCallBack(content);
+      break;
+    }
+    default: {
+      errorCallBack(ErrorCode::UnsupportedEncryptionScheme,
+                    std::to_string(encryptedContent.getAlgorithmType()));
+    }
+  }
+}
+
+void
+Consumer::decryptContent(const Data& data,
+                         const PlainTextCallBack& plainTextCallBack,
+                         const ErrorCallBack& errorCallBack)
+{
+  // get encrypted content
+  Block encryptedContent = data.getContent().blockFromValue();
+  Name cKeyName = EncryptedContent(encryptedContent).getKeyLocator().getName();
+
+  // check if content key already in store
+  auto it = m_cKeyMap.find(cKeyName);
+
+  if (it != m_cKeyMap.end()) { // decrypt content directly
+    decrypt(encryptedContent, it->second, plainTextCallBack, errorCallBack);
+  }
+  else {
+    // retrieve the C-Key Data from network
+    Name interestName = cKeyName;
+    interestName.append(NAME_COMPONENT_FOR).append(m_groupName);
+    shared_ptr<Interest> interest = make_shared<Interest>(interestName);
+
+    // prepare callback functions
+    auto onData = [=] (const Interest& cKeyInterest, const Data& cKeyData) {
+      if (!cKeyInterest.matchesData(cKeyData))
+        return;
+
+      this->m_validator->validate(cKeyData,
+        [=] (const shared_ptr<const Data>& validCKeyData) {
+          decryptCKey(*validCKeyData,
+                      [=] (const Buffer& cKeyBits) {
+                        decrypt(encryptedContent, cKeyBits, plainTextCallBack, errorCallBack);
+                        this->m_cKeyMap.insert(std::make_pair(cKeyName, cKeyBits));
+                      },
+                      errorCallBack);},
+        [=] (const shared_ptr<const Data>& d, const std::string& e) {
+          errorCallBack(ErrorCode::Validation, e);
+        });
+    };
+
+    auto onTimeout = [=] (const Interest& cKeyInterest) {
+      // we should re-try at least once.
+      this->m_face.expressInterest(*interest, onData,
+        [=] (const Interest& contentInterest) {
+          errorCallBack(ErrorCode::Timeout, interest->getName().toUri());
+        });
+    };
+
+    // express Interest packet
+    m_face.expressInterest(*interest, onData, onTimeout);
+  }
+}
+
+void
+Consumer::decryptCKey(const Data& cKeyData,
+                      const PlainTextCallBack& plainTextCallBack,
+                      const ErrorCallBack& errorCallBack)
+{
+  // get encrypted content
+  Block cKeyContent = cKeyData.getContent().blockFromValue();
+  Name eKeyName = EncryptedContent(cKeyContent).getKeyLocator().getName();
+  Name dKeyName = eKeyName.getPrefix(-3);
+  dKeyName.append(NAME_COMPONENT_D_KEY).append(eKeyName.getSubName(-2));
+
+  // check if decryption key already in store
+  auto it = m_dKeyMap.find(dKeyName);
+
+  if (it != m_dKeyMap.end()) { // decrypt C-Key directly
+    decrypt(cKeyContent, it->second, plainTextCallBack, errorCallBack);
+  }
+  else {
+    // get the D-Key Data
+    Name interestName = dKeyName;
+    interestName.append(NAME_COMPONENT_FOR).append(m_consumerName);
+    shared_ptr<Interest> interest = make_shared<Interest>(dKeyName);
+
+    // prepare callback functions
+    auto onData = [=] (const Interest& dKeyInterest, const Data& dKeyData) {
+      if (!dKeyInterest.matchesData(dKeyData))
+        return;
+
+      this->m_validator->validate(dKeyData,
+        [=] (const shared_ptr<const Data>& validDKeyData) {
+          decryptDKey(*validDKeyData,
+                      [=] (const Buffer& dKeyBits) {
+                        decrypt(cKeyContent, dKeyBits, plainTextCallBack, errorCallBack);
+                        this->m_dKeyMap.insert(std::make_pair(dKeyName, dKeyBits));
+                      },
+                      errorCallBack);},
+        [=] (const shared_ptr<const Data>& d, const std::string& e) {
+          errorCallBack(ErrorCode::Validation, e);
+        });
+    };
+
+    auto onTimeout = [=] (const Interest& dKeyInterest) {
+      // we should re-try at least once.
+      this->m_face.expressInterest(*interest, onData,
+        [=] (const Interest& contentInterest) {
+          errorCallBack(ErrorCode::Timeout, interest->getName().toUri());
+        });
+    };
+
+    // express Interest packet
+    m_face.expressInterest(*interest, onData, onTimeout);
+  }
+}
+
+void
+Consumer::decryptDKey(const Data& dKeyData,
+                      const PlainTextCallBack& plainTextCallBack,
+                      const ErrorCallBack& errorCallBack)
+{
+  // get encrypted content
+  Block dataContent = dKeyData.getContent();
+  dataContent.parse();
+
+  if (dataContent.elements_size() != 2)
+    errorCallBack(ErrorCode::InvalidEncryptedFormat,
+                  "Data packet does not satisfy D-KEY packet format");
+
+  // process nonce;
+  auto it = dataContent.elements_begin();
+  Block encryptedNonceBlock = *it;
+  EncryptedContent encryptedNonce(encryptedNonceBlock);
+  Name consumerKeyName = encryptedNonce.getKeyLocator().getName();
+
+  // get consumer decryption key
+  Buffer consumerKeyBuf = getDecryptionKey(consumerKeyName);
+  if (consumerKeyBuf.empty()) {
+    errorCallBack(ErrorCode::NoDecryptKey,
+                  "No desired consumer decryption key in database");
+    return;
+  }
+
+  // process d-key
+  it++;
+  Block encryptedPayloadBlock = *it;
+
+  // decrypt d-key
+  decrypt(encryptedNonceBlock, consumerKeyBuf,
+          [&] (const Buffer& nonceKeyBits) {
+            decrypt(encryptedPayloadBlock, nonceKeyBits, plainTextCallBack, errorCallBack);
+          },
+          errorCallBack);
+}
+
+const Buffer
+Consumer::getDecryptionKey(const Name& decryptionKeyName)
+{
+  return m_db.getKey(decryptionKeyName);
+}
+
+} // namespace gep
+} // namespace ndn
diff --git a/src/consumer.hpp b/src/consumer.hpp
new file mode 100644
index 0000000..5da849b
--- /dev/null
+++ b/src/consumer.hpp
@@ -0,0 +1,147 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  Regents of the University of California
+ *
+ * This file is part of ndn-group-encrypt (Group-based Encryption Protocol for NDN).
+ * See AUTHORS.md for complete list of ndn-group-encrypt authors and contributors.
+ *
+ * ndn-group-encrypt is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-group-encrypt is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-group-encrypt, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author Zhiyi Zhang <dreamerbarrychang@gmail.com>
+ * @author Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef NDN_GEP_CONSUMER_HPP
+#define NDN_GEP_CONSUMER_HPP
+
+#include "algo/rsa.hpp"
+#include "algo/aes.hpp"
+#include "consumer-db.hpp"
+#include "error-code.hpp"
+
+#include <ndn-cxx/security/validator-null.hpp>
+#include <ndn-cxx/face.hpp>
+
+namespace ndn {
+namespace gep {
+
+typedef function<void (const Data&, const Buffer&)> ConsumptionCallBack;
+
+/**
+ * @brief Consumer in group-based encryption protocol
+ */
+class Consumer
+{
+private:
+  typedef function<void (const Buffer&)> PlainTextCallBack;
+
+public:
+  /**
+   * @brief Create a consumer instance
+   *
+   * @param face The face used for key fetching
+   * @param groupName The reading group name that the consumer belongs to
+   * @param consumerName The identity of the consumer
+   * @param dbDir The path to database storing decryption key
+   */
+  Consumer(Face& face, const Name& groupName, const Name& consumerName, const std::string& dbDir);
+
+  /**
+   * @brief Send out the Interest packet to fetch content packet with @p dataName.
+   *
+   * @param consumptionCallBack The callback when requested data is decrypted
+   * @param errorCallBack The callback when error happens in consumption
+   */
+  void
+  consume(const Name& dataName,
+          const ConsumptionCallBack& consumptionCallBack,
+          const ErrorCallBack& errorCallBack);
+
+  /**
+   * @brief Set the group name to @p groupName.
+   */
+  void
+  setGroup(const Name& groupName);
+
+  /**
+   * @brief Add new decryption key with @p keyName and @p keyBuf.
+   */
+  void
+  addDecryptionKey(const Name& keyName, const Buffer& keyBuf);
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+
+  /**
+   * @brief Decrypt @p encryptedBlock using @p keyBits
+   *
+   * Invoke @p plainTextCallBack when block is decrypted, otherwise @p errorCallBack.
+   */
+  void
+  decrypt(const Block& encryptedBlock,
+          const Buffer& keyBits,
+          const PlainTextCallBack& plainTextCallBack,
+          const ErrorCallBack& errorCallBack);
+
+  /**
+   * @brief Decrypt @p data.
+   *
+   * Invoke @p plainTextCallBack when block is decrypted, otherwise @p errorCallBack.
+   */
+  void
+  decryptContent(const Data& data,
+                 const PlainTextCallBack& plainTextCallBack,
+                 const ErrorCallBack& errorCallBack);
+
+  /**
+   * @brief Decrypt @p cKeyData.
+   *
+   * Invoke @p plainTextCallBack when block is decrypted, otherwise @p errorCallBack.
+   */
+  void
+  decryptCKey(const Data& cKeyData,
+              const PlainTextCallBack& plainTextCallBack,
+              const ErrorCallBack& errorCallBack);
+
+  /**
+   * @brief Decrypt @p dKeyData.
+   *
+   * Invoke @p plainTextCallBack when block is decrypted, otherwise @p errorCallBack.
+   */
+  void
+  decryptDKey(const Data& dKeyData,
+              const PlainTextCallBack& plainTextCallBack,
+              const ErrorCallBack& errorCallBack);
+
+
+  /**
+   * @brief Get the buffer of decryption key with @p decryptionKeyName from database.
+   *
+   * @return Null buffer when there is no decryption key with @p decryptionKeyName.
+   */
+  const Buffer
+  getDecryptionKey(const Name& decryptionKeyName);
+
+private:
+  ConsumerDB m_db;
+  unique_ptr<Validator> m_validator;
+  Face& m_face;
+  Name m_groupName;
+  Name m_consumerName;
+
+  std::map<Name, Buffer> m_cKeyMap;
+  std::map<Name, Buffer> m_dKeyMap;
+};
+
+} // namespace gep
+} // namespace ndn
+
+#endif // NDN_GEP_CONSUMER_HPP
diff --git a/src/error-code.hpp b/src/error-code.hpp
new file mode 100644
index 0000000..3e5d2a6
--- /dev/null
+++ b/src/error-code.hpp
@@ -0,0 +1,43 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  Regents of the University of California
+ *
+ * This file is part of ndn-group-encrypt (Group-based Encryption Protocol for NDN).
+ * See AUTHORS.md for complete list of ndn-group-encrypt authors and contributors.
+ *
+ * ndn-group-encrypt is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-group-encrypt is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-group-encrypt, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#ifndef NDN_GEP_ERROR_CODE_HPP
+#define NDN_GEP_ERROR_CODE_HPP
+
+#include "common.hpp"
+
+namespace ndn {
+namespace gep {
+
+enum class ErrorCode {
+  Timeout = 1,
+  Validation = 2,
+  UnsupportedEncryptionScheme = 32,
+  InvalidEncryptedFormat = 33,
+  NoDecryptKey = 34
+};
+
+typedef function<void (const ErrorCode&, const std::string&)> ErrorCallBack;
+
+} // namespace gep
+} // namespace ndn
+
+#endif // NDN_GEP_ERROR_CODE_HPP
diff --git a/tests/unit-tests/consumer-db.t.cpp b/tests/unit-tests/consumer-db.t.cpp
new file mode 100644
index 0000000..bad6213
--- /dev/null
+++ b/tests/unit-tests/consumer-db.t.cpp
@@ -0,0 +1,131 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  Regents of the University of California
+ *
+ * This file is part of ndn-group-encrypt (Group-based Encryption Protocol for NDN).
+ * See AUTHORS.md for complete list of ndn-group-encrypt authors and contributors.
+ *
+ * ndn-group-encrypt is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-group-encrypt is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-group-encrypt, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author Zhiyi Zhang <dreamerbarrychang@gmail.com>
+ */
+
+#include "consumer-db.hpp"
+#include "algo/rsa.hpp"
+#include "algo/aes.hpp"
+#include "boost-test.hpp"
+
+#include <boost/filesystem.hpp>
+
+namespace ndn {
+namespace gep {
+namespace tests {
+
+class ConsumerDBFixture
+{
+public:
+  ConsumerDBFixture()
+    : tmpPath(boost::filesystem::path(TMP_TESTS_PATH))
+  {
+    boost::filesystem::create_directories(tmpPath);
+  }
+
+  ~ConsumerDBFixture()
+  {
+    boost::filesystem::remove_all(tmpPath);
+  }
+
+  void
+  generateRsaKey(Buffer& encryptionKeyBuf, Buffer& decryptionKeyBuf)
+  {
+    RandomNumberGenerator rng;
+    RsaKeyParams params;
+    DecryptKey<algo::Rsa> dKey = algo::Rsa::generateKey(rng, params);
+    decryptionKeyBuf = dKey.getKeyBits();
+    EncryptKey<algo::Rsa> eKey = algo::Rsa::deriveEncryptKey(decryptionKeyBuf);
+    encryptionKeyBuf = eKey.getKeyBits();
+  }
+
+  void
+  generateAesKey(Buffer& encryptionKeyBuf, Buffer& decryptionKeyBuf)
+  {
+    RandomNumberGenerator rng;
+    AesKeyParams params;
+    DecryptKey<algo::Aes> memberDecryptKey = algo::Aes::generateKey(rng, params);
+    decryptionKeyBuf = memberDecryptKey.getKeyBits();
+    EncryptKey<algo::Aes> memberEncryptKey = algo::Aes::deriveEncryptKey(decryptionKeyBuf);
+    encryptionKeyBuf = memberEncryptKey.getKeyBits();
+  }
+
+public:
+  boost::filesystem::path tmpPath;
+};
+
+BOOST_FIXTURE_TEST_SUITE(TestConsumerDB, ConsumerDBFixture)
+
+BOOST_AUTO_TEST_CASE(OperateAesDecryptionKey)
+{
+  // construction
+  std::string dbDir = tmpPath.c_str();
+  dbDir += "/test.db";
+  ConsumerDB db(dbDir);
+
+  // generate key buffer
+  Buffer eKeyBuf;
+  Buffer dKeyBuf;
+  generateAesKey(eKeyBuf, dKeyBuf);
+
+  Name keyName("/alice/health/samples/activity/steps/C-KEY/20150928080000/20150928090000!");
+  keyName.append("FOR/alice/health/read/activity!");
+  db.addKey(keyName, dKeyBuf);
+  Buffer resultBuf = db.getKey(keyName);
+
+  BOOST_CHECK_EQUAL_COLLECTIONS(dKeyBuf.begin(), dKeyBuf.end(),
+                                resultBuf.begin(), resultBuf.end());
+
+  db.deleteKey(keyName);
+  resultBuf = db.getKey(keyName);
+
+  BOOST_CHECK_EQUAL(resultBuf.size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(OperateRsaDecryptionKey)
+{
+  // construction
+  std::string dbDir = tmpPath.c_str();
+  dbDir += "/test.db";
+  ConsumerDB db(dbDir);
+
+  // generate key buffer
+  Buffer eKeyBuf;
+  Buffer dKeyBuf;
+  generateRsaKey(eKeyBuf, dKeyBuf);
+
+  Name keyName("/alice/health/samples/activity/steps/D-KEY/20150928080000/20150928090000!");
+  keyName.append("FOR/test/member/KEY/123!");
+  db.addKey(keyName, dKeyBuf);
+  Buffer resultBuf = db.getKey(keyName);
+
+  BOOST_CHECK_EQUAL_COLLECTIONS(dKeyBuf.begin(), dKeyBuf.end(),
+                                resultBuf.begin(), resultBuf.end());
+
+  db.deleteKey(keyName);
+  resultBuf = db.getKey(keyName);
+
+  BOOST_CHECK_EQUAL(resultBuf.size(), 0);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace gep
+} // namespace ndn
diff --git a/tests/unit-tests/consumer.t.cpp b/tests/unit-tests/consumer.t.cpp
new file mode 100644
index 0000000..4db7e5f
--- /dev/null
+++ b/tests/unit-tests/consumer.t.cpp
@@ -0,0 +1,297 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  Regents of the University of California
+ *
+ * This file is part of ndn-group-encrypt (Group-based Encryption Protocol for NDN).
+ * See AUTHORS.md for complete list of ndn-group-encrypt authors and contributors.
+ *
+ * ndn-group-encrypt is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-group-encrypt is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-group-encrypt, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author Zhiyi Zhang <dreamerbarrychang@gmail.com>
+ * @author Yingdi Yu <yingdi@cs.ucla.edu>
+ */
+
+#include "consumer.hpp"
+#include "boost-test.hpp"
+#include "algo/encryptor.hpp"
+#include "unit-test-time-fixture.hpp"
+
+#include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/util/dummy-client-face.hpp>
+#include <ndn-cxx/util/time-unit-test-clock.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/asio.hpp>
+
+namespace ndn {
+namespace gep {
+namespace tests {
+
+static const uint8_t DATA_CONTEN[] = {
+  0xcb, 0xe5, 0x6a, 0x80, 0x41, 0x24, 0x58, 0x23,
+  0x84, 0x14, 0x15, 0x61, 0x80, 0xb9, 0x5e, 0xbd,
+  0xce, 0x32, 0xb4, 0xbe, 0xbc, 0x91, 0x31, 0xd6,
+  0x19, 0x00, 0x80, 0x8b, 0xfa, 0x00, 0x05, 0x9c
+};
+
+static const uint8_t AES_KEY[] = {
+  0xdd, 0x60, 0x77, 0xec, 0xa9, 0x6b, 0x23, 0x1b,
+  0x40, 0x6b, 0x5a, 0xf8, 0x7d, 0x3d, 0x55, 0x32
+};
+
+static const uint8_t IV[] = {
+  0x73, 0x6f, 0x6d, 0x65, 0x72, 0x61, 0x6e, 0x64,
+  0x6f, 0x6d, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72
+};
+
+class ConsumerFixture : public UnitTestTimeFixture
+{
+public:
+  ConsumerFixture()
+    : tmpPath(boost::filesystem::path(TMP_TESTS_PATH))
+    , face1(util::makeDummyClientFace(io, {true, true}))
+    , face2(util::makeDummyClientFace(io, {true, true}))
+    , readInterestOffset1(0)
+    , readDataOffset1(0)
+    , readInterestOffset2(0)
+    , readDataOffset2(0)
+    , groupName("/Prefix/READ")
+    , contentName("/Prefix/SAMPLE/Content")
+    , cKeyName("/Prefix/SAMPLE/Content/C-KEY/1")
+    , eKeyName("/Prefix/READ/E-KEY/1/2")
+    , dKeyName("/Prefix/READ/D-KEY/1/2")
+    , uKeyName("/U/Key")
+    , uName("/U")
+  {
+    boost::filesystem::create_directories(tmpPath);
+
+    // generate e/d key
+    RandomNumberGenerator rng;
+    RsaKeyParams params;
+    fixtureDKeyBuf = algo::Rsa::generateKey(rng, params).getKeyBits();
+    fixtureEKeyBuf = algo::Rsa::deriveEncryptKey(fixtureDKeyBuf).getKeyBits();
+
+    // generate user key
+    fixtureUDKeyBuf = algo::Rsa::generateKey(rng, params).getKeyBits();
+    fixtureUEKeyBuf = algo::Rsa::deriveEncryptKey(fixtureUDKeyBuf).getKeyBits();
+
+    // load C-KEY
+    fixtureCKeyBuf = Buffer(AES_KEY, sizeof(AES_KEY));
+  }
+
+  ~ConsumerFixture()
+  {
+    boost::filesystem::remove_all(tmpPath);
+  }
+
+  shared_ptr<Data>
+  createEncryptedContent()
+  {
+    shared_ptr<Data> contentData = make_shared<Data>(contentName);
+    algo::EncryptParams eparams(tlv::AlgorithmAesCbc);
+    eparams.setIV(IV, sizeof(IV));
+    algo::encryptData(*contentData, DATA_CONTEN, sizeof(DATA_CONTEN), cKeyName,
+                      fixtureCKeyBuf.buf(), fixtureCKeyBuf.size(), eparams);
+    keyChain.sign(*contentData);
+    return contentData;
+  }
+
+  shared_ptr<Data>
+  createEncryptedCKey()
+  {
+    shared_ptr<Data> cKeyData = make_shared<Data>(cKeyName);
+    algo::EncryptParams eparams(tlv::AlgorithmRsaOaep);
+    algo::encryptData(*cKeyData, fixtureCKeyBuf.buf(), fixtureCKeyBuf.size(), dKeyName,
+                      fixtureEKeyBuf.buf(), fixtureEKeyBuf.size(), eparams);
+    keyChain.sign(*cKeyData);
+    return cKeyData;
+  }
+
+  shared_ptr<Data>
+  createEncryptedDKey()
+  {
+    shared_ptr<Data> dKeyData = make_shared<Data>(dKeyName);
+    algo::EncryptParams eparams(tlv::AlgorithmRsaOaep);
+    algo::encryptData(*dKeyData, fixtureDKeyBuf.buf(), fixtureDKeyBuf.size(), uKeyName,
+                      fixtureUEKeyBuf.buf(), fixtureUEKeyBuf.size(), eparams);
+    keyChain.sign(*dKeyData);
+    return dKeyData;
+  }
+
+  bool
+  passPacket()
+  {
+    bool hasPassed = false;
+
+    checkFace(face1->sentInterests, readInterestOffset1, *face2, hasPassed);
+    checkFace(face1->sentDatas, readDataOffset1, *face2, hasPassed);
+    checkFace(face2->sentInterests, readInterestOffset2, *face1, hasPassed);
+    checkFace(face2->sentDatas, readDataOffset2, *face1, hasPassed);
+
+    return hasPassed;
+  }
+
+  template<typename Packet>
+  void
+  checkFace(std::vector<Packet>& receivedPackets,
+            size_t& readPacketOffset,
+            util::DummyClientFace& receiver,
+            bool& hasPassed)
+  {
+    while (receivedPackets.size() > readPacketOffset) {
+      receiver.receive(receivedPackets[readPacketOffset]);
+      readPacketOffset++;
+      hasPassed = true;
+    }
+  }
+
+public:
+  boost::filesystem::path tmpPath;
+
+  shared_ptr<util::DummyClientFace> face1;
+  shared_ptr<util::DummyClientFace> face2;
+
+  size_t readInterestOffset1;
+  size_t readDataOffset1;
+  size_t readInterestOffset2;
+  size_t readDataOffset2;
+
+  KeyChain keyChain;
+
+  Buffer fixtureCKeyBuf;
+  Buffer fixtureEKeyBuf;
+  Buffer fixtureDKeyBuf;
+  Buffer fixtureUEKeyBuf;
+  Buffer fixtureUDKeyBuf;
+
+  Name groupName;
+  Name contentName;
+  Name cKeyName;
+  Name eKeyName;
+  Name dKeyName;
+  Name uKeyName;
+  Name uName;
+};
+
+BOOST_FIXTURE_TEST_SUITE(TestConsumer, ConsumerFixture)
+
+BOOST_AUTO_TEST_CASE(DecryptContent)
+{
+  std::string dbDir = tmpPath.c_str();
+  dbDir += "/test.db";
+
+  // generate AES key pairs
+  Buffer aesKeyBuf = Buffer(AES_KEY, sizeof(AES_KEY));
+
+  // generate C-KEY packet
+  auto cKeyData = createEncryptedCKey();
+  // generate Content packet
+  auto contentData = createEncryptedContent();
+
+  // create consumer
+  Consumer consumer(*face1, Name("/Group"), Name("/U"), dbDir);
+
+  // decrypt
+  consumer.decrypt(cKeyData->getContent().blockFromValue(),
+                   fixtureDKeyBuf,
+                   [=](const Buffer& result){
+                     BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(),
+                                                   aesKeyBuf.begin(),
+                                                   aesKeyBuf.end());
+                   },
+                   [=](const ErrorCode&, const std::string&){
+                     BOOST_CHECK(false);
+                   });
+
+  // decrypt
+  consumer.decrypt(contentData->getContent().blockFromValue(),
+                   fixtureCKeyBuf,
+                   [=](const Buffer& result){
+                     BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(),
+                                                   DATA_CONTEN,
+                                                   DATA_CONTEN + sizeof(DATA_CONTEN));
+                   },
+                   [=](const ErrorCode&, const std::string&){
+                     BOOST_CHECK(false);
+                   });
+}
+
+BOOST_AUTO_TEST_CASE(Consume)
+{
+  auto contentData = createEncryptedContent();
+  auto cKeyData = createEncryptedCKey();
+  auto dKeyData = createEncryptedDKey();
+
+  int contentCount = 0;
+  int cKeyCount = 0;
+  int dKeyCount = 0;
+
+  Name prefix("/Prefix");
+  // prepare face1
+  face1->setInterestFilter(prefix,
+                           [&] (const InterestFilter&, const Interest& i) {
+                             if (i.matchesData(*contentData)) {
+                               contentCount = 1;
+                               face1->put(*contentData);
+                               return;
+                             }
+                             if (i.matchesData(*cKeyData)) {
+                               cKeyCount = 1;
+                               face1->put(*cKeyData);
+                               return;
+                             }
+                             if (i.matchesData(*dKeyData)) {
+                               dKeyCount = 1;
+                               face1->put(*dKeyData);
+                               return;
+                             }
+                             return;
+                           },
+                           RegisterPrefixSuccessCallback(),
+                           [] (const Name&, const std::string& e) { });
+
+  do {
+    advanceClocks(time::milliseconds(10), 20);
+  } while (passPacket());
+
+  // create consumer
+  std::string dbDir = tmpPath.c_str();
+  dbDir += "/test.db";
+  Consumer consumer(*face2, groupName, uName, dbDir);
+  consumer.addDecryptionKey(uKeyName, fixtureUDKeyBuf);
+
+  int finalCount = 0;
+  consumer.consume(contentName,
+                   [&](const Data& data, const Buffer& result){
+                     finalCount = 1;
+                     BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(),
+                                                   DATA_CONTEN,
+                                                   DATA_CONTEN + sizeof(DATA_CONTEN));
+                   },
+                   [&](const ErrorCode& code, const std::string& str){
+                     BOOST_CHECK(false);
+                   });
+
+  do {
+    advanceClocks(time::milliseconds(10), 20);
+  } while (passPacket());
+
+  BOOST_CHECK_EQUAL(contentCount, 1);
+  BOOST_CHECK_EQUAL(cKeyCount, 1);
+  BOOST_CHECK_EQUAL(dKeyCount, 1);
+  BOOST_CHECK_EQUAL(finalCount, 1);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace test
+} // namespace gep
+} // namespace ndn
diff --git a/tests/unit-tests/unit-test-time-fixture.hpp b/tests/unit-tests/unit-test-time-fixture.hpp
new file mode 100644
index 0000000..62db2d7
--- /dev/null
+++ b/tests/unit-tests/unit-test-time-fixture.hpp
@@ -0,0 +1,70 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  Regents of the University of California
+ *
+ * This file is part of ndn-group-encrypt (Group-based Encryption Protocol for NDN).
+ * See AUTHORS.md for complete list of ndn-group-encrypt authors and contributors.
+ *
+ * ndn-group-encrypt is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-group-encrypt is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * ndn-group-encrypt, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#ifndef NDN_GEP_TESTS_UNIT_TESTS_UNIT_TEST_TIME_FIXTURE_HPP
+#define NDN_GEP_TESTS_UNIT_TESTS_UNIT_TEST_TIME_FIXTURE_HPP
+
+#include <ndn-cxx/util/time-unit-test-clock.hpp>
+#include <boost/asio.hpp>
+
+namespace ndn {
+namespace gep {
+namespace tests {
+
+class UnitTestTimeFixture
+{
+public:
+  UnitTestTimeFixture()
+    : steadyClock(make_shared<time::UnitTestSteadyClock>())
+    , systemClock(make_shared<time::UnitTestSystemClock>())
+  {
+    time::setCustomClocks(steadyClock, systemClock);
+  }
+
+  ~UnitTestTimeFixture()
+  {
+    time::setCustomClocks(nullptr, nullptr);
+  }
+
+  void
+  advanceClocks(const time::nanoseconds& tick, size_t nTicks = 1)
+  {
+    for (size_t i = 0; i < nTicks; ++i) {
+      steadyClock->advance(tick);
+      systemClock->advance(tick);
+
+      if (io.stopped())
+        io.reset();
+      io.poll();
+    }
+  }
+
+public:
+  shared_ptr<time::UnitTestSteadyClock> steadyClock;
+  shared_ptr<time::UnitTestSystemClock> systemClock;
+  boost::asio::io_service io;
+};
+
+} // namespace tests
+} // namespace gep
+} // namespace ndn
+
+#endif // NDN_GEP_TESTS_UNIT_TESTS_UNIT_TEST_TIME_FIXTURE_HPP
