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
