diff --git a/src/producer-db.cpp b/src/producer-db.cpp
new file mode 100644
index 0000000..c748953
--- /dev/null
+++ b/src/producer-db.cpp
@@ -0,0 +1,151 @@
+/* -*- 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 Prashanth Swaminathan <prashanthsw@gmail.com>
+ */
+
+#include "producer-db.hpp"
+
+#include <sqlite3.h>
+#include <boost/filesystem.hpp>
+#include <ndn-cxx/util/sqlite3-statement.hpp>
+#include <ndn-cxx/security/identity-certificate.hpp>
+
+namespace ndn {
+namespace gep {
+
+using util::Sqlite3Statement;
+using time::system_clock;
+
+static const std::string INITIALIZATION =
+  "CREATE TABLE IF NOT EXISTS                         \n"
+  "  contentkeys(                                     \n"
+  "    rowId            INTEGER PRIMARY KEY,          \n"
+  "    timeslot         INTEGER,                      \n"
+  "    key              BLOB NOT NULL                 \n"
+  "  );                                               \n"
+  "CREATE UNIQUE INDEX IF NOT EXISTS                  \n"
+  "   timeslotIndex ON contentkeys(timeslot);         \n";
+
+class ProducerDB::Impl
+{
+public:
+  Impl(const std::string& dbPath)
+  {
+    // open Database
+
+    int result = sqlite3_open_v2(dbPath.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("Producer DB cannot be opened/created: " + dbPath));
+
+    // enable foreign key
+    sqlite3_exec(m_database, "PRAGMA foreign_keys = ON", nullptr, nullptr, nullptr);
+
+    // 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("Producer DB cannot be initialized"));
+    }
+  }
+
+  ~Impl()
+  {
+    sqlite3_close(m_database);
+  }
+
+public:
+  sqlite3* m_database;
+};
+
+ProducerDB::ProducerDB(const std::string& dbPath)
+  : m_impl(new Impl(dbPath))
+{
+}
+
+ProducerDB::~ProducerDB() = default;
+
+static int32_t
+getFixedTimeslot(const system_clock::TimePoint& timeslot) {
+  return (time::toUnixTimestamp(timeslot)).count() / 3600000;
+}
+
+bool
+ProducerDB::hasContentKey(const system_clock::TimePoint& timeslot) const
+{
+  int32_t fixedTimeslot = getFixedTimeslot(timeslot);
+  Sqlite3Statement statement(m_impl->m_database,
+                             "SELECT key FROM contentkeys where timeslot=?");
+  statement.bind(1, fixedTimeslot);
+  return (statement.step() == SQLITE_ROW);
+}
+
+
+Buffer
+ProducerDB::getContentKey(const system_clock::TimePoint& timeslot) const
+{
+  int32_t fixedTimeslot = getFixedTimeslot(timeslot);
+  Sqlite3Statement statement(m_impl->m_database,
+                             "SELECT key FROM contentkeys where timeslot=?");
+  statement.bind(1, fixedTimeslot);
+
+  Buffer result;
+  if (statement.step() == SQLITE_ROW) {
+    result = Buffer(statement.getBlob(0), statement.getSize(0));
+  }
+  else {
+    BOOST_THROW_EXCEPTION(Error("Cannot get the key from database"));
+  }
+  return result;
+}
+
+void
+ProducerDB::addContentKey(const system_clock::TimePoint& timeslot, const Buffer& key)
+{
+  // BOOST_ASSERT(key.length() != 0);
+  int32_t fixedTimeslot = getFixedTimeslot(timeslot);
+  Sqlite3Statement statement(m_impl->m_database,
+                             "INSERT INTO contentkeys (timeslot, key)\
+                              values (?, ?)");
+  statement.bind(1, fixedTimeslot);
+  statement.bind(2, key.buf(), key.size(), SQLITE_TRANSIENT);
+  if (statement.step() != SQLITE_DONE)
+    BOOST_THROW_EXCEPTION(Error("Cannot add the key to database"));
+}
+
+void
+ProducerDB::deleteContentKey(const system_clock::TimePoint& timeslot)
+{
+  int32_t fixedTimeslot = getFixedTimeslot(timeslot);
+  Sqlite3Statement statement(m_impl->m_database,
+                             "DELETE FROM contentkeys WHERE timeslot=?");
+  statement.bind(1, fixedTimeslot);
+  statement.step();
+}
+
+} // namespace gep
+} // namespace ndn
diff --git a/src/producer-db.hpp b/src/producer-db.hpp
new file mode 100644
index 0000000..4a10d3f
--- /dev/null
+++ b/src/producer-db.hpp
@@ -0,0 +1,89 @@
+/* -*- 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 Prashanth Swaminathan <prashanthsw@gmail.com>
+ */
+
+#ifndef NDN_GEP_PRODUCER_DB_HPP
+#define NDN_GEP_PRODUCER_DB_HPP
+
+#include "common.hpp"
+
+namespace ndn {
+namespace gep {
+
+/**
+ * @brief ProducerDB is a class to manage the database of data producer.
+ * It contains one table that maps timeslots (to the nearest hour) to the
+ * content key created for that timeslot.
+ */
+class ProducerDB
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+public:
+  explicit
+  ProducerDB(const std::string& dbPath);
+
+  ~ProducerDB();
+
+public:
+  /**
+   * @brief Check if content key exists for the hour covering @p timeslot
+   */
+  bool
+  hasContentKey(const time::system_clock::TimePoint& timeslot) const;
+
+  /**
+   * @brief Get content key for the hour covering @p timeslot
+   * @throws Error if the key does not exist
+   */
+  Buffer
+  getContentKey(const time::system_clock::TimePoint& timeslot) const;
+
+  /**
+   * @brief Add @p key as the content key for the hour covering @p timeslot
+   * @throws Error if a key for the same hour already exists
+   */
+  void
+  addContentKey(const time::system_clock::TimePoint& timeslot, const Buffer& key);
+
+  /**
+   * @brief Delete content key for the hour covering @p timeslot
+   */
+  void
+  deleteContentKey(const time::system_clock::TimePoint& timeslot);
+
+private:
+  class Impl;
+  unique_ptr<Impl> m_impl;
+};
+
+} // namespace gep
+} // namespace ndn
+
+#endif // NDN_GEP_PRODUCER_DB_HPP
diff --git a/src/producer.cpp b/src/producer.cpp
new file mode 100644
index 0000000..f112fa6
--- /dev/null
+++ b/src/producer.cpp
@@ -0,0 +1,241 @@
+/* -*- 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 Prashanth Swaminathan <prashanthsw@gmail.com>
+ */
+
+#include "producer.hpp"
+#include "random-number-generator.hpp"
+#include "algo/encryptor.hpp"
+#include "algo/aes.hpp"
+
+namespace ndn {
+namespace gep {
+
+using time::system_clock;
+
+static const int startTs = -2;
+static const int endTs = -1;
+
+/**
+  @brief Method to round the provided @p timeslot to the nearest whole
+  hour, so that we can store content keys uniformly (by start of the hour).
+*/
+static const system_clock::TimePoint
+getRoundedTimeslot(const system_clock::TimePoint& timeslot) {
+  return time::fromUnixTimestamp(
+    (time::toUnixTimestamp(timeslot) / 3600000) * 3600000);
+}
+
+Producer::Producer(const Name& prefix, const Name& dataType,
+                   Face& face, const std::string& dbPath, uint8_t repeatAttempts)
+  : m_face(face),
+    m_db(dbPath),
+    m_maxRepeatAttempts(repeatAttempts)
+{
+  Name fixedPrefix = prefix;
+  Name fixedDataType = dataType;
+  KeyInfo keyInfo;
+  /**
+    Fill m_ekeyInfo vector with all permutations of dataType, including the 'E-KEY'
+    component of the name. This will be used in DataProducer::createContentKey to
+    send interests without reconstructing names every time.
+  */
+  fixedPrefix.append(NAME_COMPONENT_READ);
+  while (!fixedDataType.empty()) {
+    Name nodeName = fixedPrefix;
+    nodeName.append(fixedDataType);
+    nodeName.append(NAME_COMPONENT_E_KEY);
+
+    m_ekeyInfo[nodeName] = keyInfo;
+    fixedDataType = fixedDataType.getPrefix(-1);
+  }
+  fixedPrefix.append(dataType);
+  m_namespace = prefix;
+  m_namespace.append(NAME_COMPONENT_SAMPLE);
+  m_namespace.append(dataType);
+}
+
+Name
+Producer::createContentKey(const system_clock::TimePoint& timeslot,
+                           const ProducerEKeyCallback& callback)
+{
+  const system_clock::TimePoint hourSlot = getRoundedTimeslot(timeslot);
+
+  // Create content key name.
+  Name contentKeyName = m_namespace;
+  contentKeyName.append(NAME_COMPONENT_C_KEY);
+  contentKeyName.append(time::toIsoString(hourSlot));
+
+  Buffer contentKeyBits;
+  if (m_db.hasContentKey(timeslot)) {
+    contentKeyBits = m_db.getContentKey(timeslot);
+    return contentKeyName;
+  }
+
+  RandomNumberGenerator rng;
+  AesKeyParams aesParams(128);
+  contentKeyBits = algo::Aes::generateKey(rng, aesParams).getKeyBits();
+  m_db.addContentKey(timeslot, contentKeyBits);
+
+  uint64_t timeCount = toUnixTimestamp(timeslot).count();
+  m_keyRequests.insert({timeCount, KeyRequest(m_ekeyInfo.size())});
+  KeyRequest& keyRequest = m_keyRequests.at(timeCount);
+
+  Exclude timeRange;
+  timeRange.excludeAfter(name::Component(time::toIsoString(timeslot)));
+  // Send interests for all nodes in tree.
+  std::unordered_map<Name, KeyInfo>::iterator it;
+  for (it = m_ekeyInfo.begin(); it != m_ekeyInfo.end(); ++it) {
+    const KeyInfo& keyInfo = it->second;
+    keyRequest.repeatAttempts.insert({it->first, 0});
+    if (timeslot < keyInfo.beginTimeslot || timeslot >= keyInfo.endTimeslot) {
+      sendKeyInterest(it->first, timeslot, keyRequest, callback, timeRange);
+    }
+    else {
+      Name eKeyName(it->first);
+      eKeyName.append(time::toIsoString(keyInfo.beginTimeslot));
+      eKeyName.append(time::toIsoString(keyInfo.endTimeslot));
+      encryptContentKey(keyRequest, keyInfo.keyBits, eKeyName, timeslot, callback);
+    }
+  }
+
+  return contentKeyName;
+}
+
+void
+Producer::produce(Data& data, const system_clock::TimePoint& timeslot,
+                  const uint8_t* content, size_t contentLen)
+{
+  Buffer contentKey;
+
+  Name contentKeyName = createContentKey(timeslot, nullptr);
+  contentKey = m_db.getContentKey(timeslot);
+
+  Name dataName = m_namespace;
+  dataName.append(time::toIsoString(getRoundedTimeslot(timeslot)));
+
+  data.setName(dataName);
+  algo::EncryptParams params(tlv::AlgorithmAesCbc, 16);
+  algo::encryptData(data, content, contentLen, contentKeyName,
+                    contentKey.buf(), contentKey.size(), params);
+  m_keychain.sign(data);
+}
+
+void
+Producer::sendKeyInterest(const Name& name, const system_clock::TimePoint& timeslot,
+                          KeyRequest& keyRequest,
+                          const ProducerEKeyCallback& callback,
+                          const Exclude& timeRange)
+{
+  auto onkey = std::bind(&Producer::handleCoveringKey, this, _1, _2,
+                         std::cref(timeslot), std::ref(keyRequest), callback);
+  auto timeout = std::bind(&Producer::handleTimeout, this, _1,
+                           std::cref(timeslot), std::ref(keyRequest), callback);
+
+  Selectors selector;
+  selector.setExclude(timeRange);
+  selector.setChildSelector(1);
+
+  Interest keyInterest(name);
+  keyInterest.setSelectors(selector);
+
+  m_face.expressInterest(keyInterest, onkey, timeout);
+}
+
+void
+Producer::encryptContentKey(KeyRequest& keyRequest, const Buffer& encryptionKey,
+                            const Name& eKeyName,
+                            const system_clock::TimePoint& timeslot,
+                            const ProducerEKeyCallback& callback)
+{
+  Name keyName = m_namespace;
+  keyName.append(NAME_COMPONENT_C_KEY);
+  keyName.append(time::toIsoString(getRoundedTimeslot(timeslot)));
+
+  Buffer contentKey = m_db.getContentKey(timeslot);
+
+  Data cKeyData;
+  cKeyData.setName(keyName);
+  algo::EncryptParams params(tlv::AlgorithmRsaOaep);
+  algo::encryptData(cKeyData, contentKey.buf(), contentKey.size(), eKeyName,
+                    encryptionKey.buf(), encryptionKey.size(), params);
+  m_keychain.sign(cKeyData);
+  keyRequest.encryptedKeys.push_back(cKeyData);
+
+  keyRequest.interestCount--;
+  if (keyRequest.interestCount == 0 && callback) {
+    callback(keyRequest.encryptedKeys);
+    m_keyRequests.erase(toUnixTimestamp(timeslot).count());
+  }
+}
+
+void
+Producer::handleCoveringKey(const Interest& interest, Data& data,
+                            const system_clock::TimePoint& timeslot,
+                            KeyRequest& keyRequest,
+                            const ProducerEKeyCallback& callback)
+{
+  Name interestName = interest.getName();
+  Name keyName = data.getName();
+
+  system_clock::TimePoint begin = time::fromIsoString(keyName.get(startTs).toUri());
+  system_clock::TimePoint end = time::fromIsoString(keyName.get(endTs).toUri());
+
+  if (timeslot >= end) {
+    Exclude timeRange = interest.getSelectors().getExclude();
+    timeRange.excludeBefore(keyName.get(startTs));
+    keyRequest.repeatAttempts[interestName] = 0;
+    sendKeyInterest(interestName, timeslot, keyRequest, callback, timeRange);
+    return;
+  }
+
+  const Block keyBlock = data.getContent();
+  Buffer encryptionKey(keyBlock.value(), keyBlock.value_size());
+  m_ekeyInfo[interestName].beginTimeslot = begin;
+  m_ekeyInfo[interestName].endTimeslot = end;
+  m_ekeyInfo[interestName].keyBits = encryptionKey;
+
+  encryptContentKey(keyRequest, encryptionKey, keyName, timeslot, callback);
+}
+
+void
+Producer::handleTimeout(const Interest& interest,
+                        const system_clock::TimePoint& timeslot,
+                        KeyRequest& keyRequest,
+                        const ProducerEKeyCallback& callback)
+{
+  Name interestName = interest.getName();
+
+  if (keyRequest.repeatAttempts[interestName] < m_maxRepeatAttempts) {
+    keyRequest.repeatAttempts[interestName]++;
+    sendKeyInterest(interestName, timeslot, keyRequest, callback,
+                    interest.getSelectors().getExclude());
+  }
+  else {
+    keyRequest.interestCount--;
+  }
+
+  if (keyRequest.interestCount == 0 && callback) {
+    callback(keyRequest.encryptedKeys);
+    m_keyRequests.erase(toUnixTimestamp(timeslot).count());
+  }
+}
+
+} // namespace gep
+} // namespace ndn
\ No newline at end of file
diff --git a/src/producer.hpp b/src/producer.hpp
new file mode 100644
index 0000000..c3cd14e
--- /dev/null
+++ b/src/producer.hpp
@@ -0,0 +1,150 @@
+/* -*- 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 Prashanth Swaminathan <prashanthsw@gmail.com>
+ */
+
+#ifndef NDN_GEP_PRODUCER_HPP
+#define NDN_GEP_PRODUCER_HPP
+
+#include "producer-db.hpp"
+
+#include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/face.hpp>
+
+namespace ndn {
+namespace gep {
+
+// @brief Callback returns vector of Data contains content keys encrypted by E-KEYS
+typedef function<void(const std::vector<Data>&)> ProducerEKeyCallback;
+
+/**
+ * @brief Manage content key and data encryption
+ */
+class Producer
+{
+public:
+  struct KeyInfo {
+    time::system_clock::TimePoint beginTimeslot;
+    time::system_clock::TimePoint endTimeslot;
+    Buffer keyBits;
+  };
+
+  struct KeyRequest {
+    KeyRequest(size_t interests)
+    : interestCount(interests)
+    {}
+    size_t interestCount;
+    std::unordered_map<Name, size_t> repeatAttempts;
+    std::vector<Data> encryptedKeys;
+  };
+
+public:
+  /**
+   * @brief Construct a producer
+   *
+   * A producer can produce data with a naming convention:
+   *   /<@p prefix>/SAMPLES/<@p dataType>/[timestamp]
+   *
+   * The produced data packet is encrypted with a content key,
+   * which is stored in a database at @p dbPath.
+   *
+   * A producer also need to produce data containing content key
+   * encrypted with E-KEYs. A producer can retrieve E-KEYs through
+   * @p face, and will re-try for at most @p repeatAttemps times when
+   * E-KEY retrieval fails.
+   */
+  Producer(const Name& prefix, const Name& dataType,
+           Face& face, const std::string& dbPath, uint8_t repeatAttempts = 3);
+
+  /**
+   * @brief Create content key
+   *
+   * This method will first check if the content key exists. For existing
+   * content key, the method will return content key name directly.
+   * If the key does not exist, the method will create one and encrypt
+   * it using corresponding E-KEY. The encrypted content keys will be
+   * passed back through @p callback.
+   */
+  Name
+  createContentKey(const time::system_clock::TimePoint& timeslot,
+                   const ProducerEKeyCallback& callback);
+
+  /**
+   * @brief Produce an data packet encrypted using corresponding content key
+   *
+   * This method encrypts @p content with a content key covering
+   * @p timeslot, and set @p data with the encrypted content and
+   * appropriate data name.
+   */
+  void
+  produce(Data& data, const time::system_clock::TimePoint& timeslot,
+          const uint8_t* content, size_t contentLen);
+
+private:
+
+  /**
+   * @brief Sends interest through face with necessary callbacks
+   *        Uses @p exclude to limit interest if specified
+   */
+  void
+  sendKeyInterest(const Name& name, const time::system_clock::TimePoint& timeslot,
+                  KeyRequest& keyRequest, const ProducerEKeyCallback& callback,
+                  const Exclude& timeRange = Exclude());
+
+  /**
+   * @brief Updates state in @p keyRequest on timeout
+   */
+  void
+  handleTimeout(const Interest& interest,
+                const time::system_clock::TimePoint& timeslot,
+                KeyRequest& keyRequest, const ProducerEKeyCallback& callback);
+
+  /**
+   * @brief Checks that encryption key contained in @p data fits @p timeslot
+   *        Sends refined interest if required
+   */
+  void
+  handleCoveringKey(const Interest& interest, Data& data,
+                    const time::system_clock::TimePoint& timeslot,
+                    KeyRequest& keyRequest, const ProducerEKeyCallback& callback);
+
+  /**
+   * @brief Encrypts content key for @p timeslot with @p encryptionKey
+   *        Fires @p callback if no more interests to process
+   */
+  void
+  encryptContentKey(KeyRequest& keyRequest, const Buffer& encryptionKey,
+                    const Name& eKeyName,
+                    const time::system_clock::TimePoint& timeslot,
+                    const ProducerEKeyCallback& callback);
+
+private:
+  Face& m_face;
+  Name m_namespace;
+  KeyChain m_keychain;
+  std::unordered_map<Name, KeyInfo> m_ekeyInfo;
+  std::unordered_map<uint64_t, KeyRequest> m_keyRequests;
+  ProducerDB m_db;
+  uint8_t m_maxRepeatAttempts;
+};
+
+} // namespace gep
+} // namespace ndn
+
+#endif // NDN_GEP_PRODUCER_HPP
diff --git a/tests/unit-tests/producer-db.t.cpp b/tests/unit-tests/producer-db.t.cpp
new file mode 100644
index 0000000..bcf09e0
--- /dev/null
+++ b/tests/unit-tests/producer-db.t.cpp
@@ -0,0 +1,115 @@
+/* -*- 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 Prashanth Swaminathan <prashanthsw@gmail.com>
+ */
+
+#include "producer-db.hpp"
+#include "algo/aes.hpp"
+#include "boost-test.hpp"
+
+#include <boost/filesystem.hpp>
+
+namespace ndn {
+namespace gep {
+namespace tests {
+
+using time::system_clock;
+
+class ProducerDBFixture
+{
+public:
+  ProducerDBFixture()
+    : tmpPath(boost::filesystem::path(TMP_TESTS_PATH))
+  {
+    boost::filesystem::create_directories(tmpPath);
+  }
+
+  ~ProducerDBFixture()
+  {
+    boost::filesystem::remove_all(tmpPath);
+  }
+
+public:
+  boost::filesystem::path tmpPath;
+};
+
+BOOST_FIXTURE_TEST_SUITE(TestProducerDB, ProducerDBFixture)
+
+BOOST_AUTO_TEST_CASE(DatabaseFunctions)
+{
+  // construction
+  std::string dbDir = tmpPath.c_str();
+  dbDir += "/test.db";
+  ProducerDB db(dbDir);
+
+  // create member
+  RandomNumberGenerator rng;
+  AesKeyParams params(128);
+  Buffer keyBuf1 = algo::Aes::generateKey(rng, params).getKeyBits();
+  Buffer keyBuf2 = algo::Aes::generateKey(rng, params).getKeyBits();
+
+  system_clock::TimePoint point1(time::fromIsoString("20150101T100000"));
+  system_clock::TimePoint point2(time::fromIsoString("20150102T100000"));
+  system_clock::TimePoint point3(time::fromIsoString("20150103T100000"));
+  system_clock::TimePoint point4(time::fromIsoString("20150104T100000"));
+
+  // add keys into the database
+  BOOST_CHECK_NO_THROW(db.addContentKey(point1, keyBuf1));
+  BOOST_CHECK_NO_THROW(db.addContentKey(point2, keyBuf1));
+  BOOST_CHECK_NO_THROW(db.addContentKey(point3, keyBuf2));
+
+  // throw exception when adding a key to an existing timeslot
+  BOOST_CHECK_THROW(db.addContentKey(point1, keyBuf1), ProducerDB::Error);
+
+  // has function
+  BOOST_CHECK_EQUAL(db.hasContentKey(point1), true);
+  BOOST_CHECK_EQUAL(db.hasContentKey(point2), true);
+  BOOST_CHECK_EQUAL(db.hasContentKey(point3), true);
+  BOOST_CHECK_EQUAL(db.hasContentKey(point4), false);
+
+  // get content key
+  Buffer keyResult = db.getContentKey(point1);
+  BOOST_CHECK_EQUAL_COLLECTIONS(keyResult.begin(),
+                                keyResult.end(),
+                                keyBuf1.begin(),
+                                keyBuf1.end());
+
+  keyResult = db.getContentKey(point3);
+  BOOST_CHECK_EQUAL_COLLECTIONS(keyResult.begin(),
+                                keyResult.end(),
+                                keyBuf2.begin(),
+                                keyBuf2.end());
+
+  // throw exception when there is no such timeslot in database
+  BOOST_CHECK_THROW(db.getContentKey(point4), ProducerDB::Error);
+
+  // delete content key
+  BOOST_CHECK_EQUAL(db.hasContentKey(point1), true);
+  db.deleteContentKey(point1);
+  BOOST_CHECK_EQUAL(db.hasContentKey(point1), false);
+
+  // delete at a non-existing timeslot
+  BOOST_CHECK_NO_THROW(db.deleteContentKey(point4));
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace gep
+} // namespace ndn
diff --git a/tests/unit-tests/producer.t.cpp b/tests/unit-tests/producer.t.cpp
new file mode 100755
index 0000000..84ed8c3
--- /dev/null
+++ b/tests/unit-tests/producer.t.cpp
@@ -0,0 +1,400 @@
+/* -*- 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/>.
+ */
+
+#include "producer.hpp"
+#include "algo/encryptor.hpp"
+#include "algo/rsa.hpp"
+#include "algo/aes.hpp"
+#include "encrypted-content.hpp"
+#include "unit-test-time-fixture.hpp"
+#include "random-number-generator.hpp"
+
+#include <ndn-cxx/util/dummy-client-face.hpp>
+
+#include "boost-test.hpp"
+#include <boost/asio.hpp>
+#include <boost/filesystem.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
+};
+
+class ProducerFixture : public UnitTestTimeFixture
+{
+public:
+  ProducerFixture()
+    : 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)
+  {
+    boost::filesystem::create_directories(tmpPath);
+  }
+
+  ~ProducerFixture()
+  {
+    boost::filesystem::remove_all(tmpPath);
+  }
+
+  void
+  createEncryptionKey(Name eKeyName, const Name& timeMarker)
+  {
+    RandomNumberGenerator rng;
+    RsaKeyParams params;
+    eKeyName.append(timeMarker);
+
+    Buffer dKeyBuf = algo::Rsa::generateKey(rng, params).getKeyBits();
+    Buffer eKeyBuf = algo::Rsa::deriveEncryptKey(dKeyBuf).getKeyBits();
+    decryptionKeys[eKeyName] = dKeyBuf;
+
+    shared_ptr<Data> keyData = make_shared<Data>(eKeyName);
+    keyData->setContent(eKeyBuf.buf(), eKeyBuf.size());
+    keyChain.sign(*keyData);
+    encryptionKeys[eKeyName] = keyData;
+  }
+
+  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;
+
+  std::unordered_map<Name, Buffer> decryptionKeys;
+  std::unordered_map<Name, shared_ptr<Data>> encryptionKeys;
+};
+
+BOOST_FIXTURE_TEST_SUITE(TestProducer, ProducerFixture)
+
+BOOST_AUTO_TEST_CASE(ContentKeyRequest)
+{
+  std::string dbDir = tmpPath.c_str();
+  dbDir += "/test.db";
+
+  Name prefix("/prefix");
+  Name suffix("/a/b/c");
+  Name expectedInterest = prefix;
+  expectedInterest.append(NAME_COMPONENT_READ);
+  expectedInterest.append(suffix);
+  expectedInterest.append(NAME_COMPONENT_E_KEY);
+
+  Name cKeyName = prefix;
+  cKeyName.append(NAME_COMPONENT_SAMPLE);
+  cKeyName.append(suffix);
+  cKeyName.append(NAME_COMPONENT_C_KEY);
+
+  Name timeMarker("20150101T100000/20150101T120000");
+  time::system_clock::TimePoint testTime1 = time::fromIsoString("20150101T100001");
+  time::system_clock::TimePoint testTime2 = time::fromIsoString("20150101T110001");
+  name::Component testTimeRounded1("20150101T100000");
+  name::Component testTimeRounded2("20150101T110000");
+
+  // Create content keys required for this test case:
+  for (size_t i = 0; i < suffix.size(); i++) {
+    createEncryptionKey(expectedInterest, timeMarker);
+    expectedInterest = expectedInterest.getPrefix(-2).append(NAME_COMPONENT_E_KEY);
+  }
+
+  face2->setInterestFilter(prefix,
+         [&] (const InterestFilter&, const Interest& i) {
+            Name interestName = i.getName();
+            interestName.append(timeMarker);
+            BOOST_REQUIRE_EQUAL(encryptionKeys.find(interestName) !=
+                                encryptionKeys.end(), true);
+            face2->put(*(encryptionKeys[interestName]));
+            return;
+         },
+         RegisterPrefixSuccessCallback(),
+         [] (const Name&, const std::string& e) { });
+
+  do {
+    advanceClocks(time::milliseconds(10), 20);
+  } while (passPacket());
+
+  /*
+  Verify that content key is correctly encrypted for each domain, and the
+  produce method encrypts provided data with the same content key.
+  */
+  Producer producer(prefix, suffix, *face1, dbDir);
+  ProducerDB testDb(dbDir);
+  Buffer contentKey;
+
+  auto checkEncryptionKeys =
+          [&](const std::vector<Data>& result,
+              const time::system_clock::TimePoint& testTime,
+              const name::Component& roundedTime) {
+            BOOST_CHECK_EQUAL(testDb.hasContentKey(testTime), true);
+            contentKey = testDb.getContentKey(testTime);
+
+            algo::EncryptParams params(tlv::AlgorithmRsaOaep);
+            std::vector<Data>::const_iterator it;
+            for (it = result.begin(); it != result.end(); ++it) {
+              Name keyName = it->getName();
+              BOOST_CHECK_EQUAL(keyName.getSubName(0,6), cKeyName);
+              BOOST_CHECK_EQUAL(keyName.get(6), roundedTime);
+              BOOST_CHECK_EQUAL(keyName.get(7), NAME_COMPONENT_FOR);
+              BOOST_CHECK_EQUAL(decryptionKeys.find(keyName.getSubName(8)) !=
+                                decryptionKeys.end(), true);
+              Name testName = it->getName().getSubName(-8);
+              Buffer decryptionKey;
+
+              decryptionKey = decryptionKeys.at(keyName.getSubName(8));
+              BOOST_CHECK_EQUAL(decryptionKey.size() != 0, true);
+              Block encryptedKeyBlock = it->getContent();
+              encryptedKeyBlock.parse();
+
+              EncryptedContent content(*(encryptedKeyBlock.elements_begin()));
+              const Buffer& encryptedKey = content.getPayload();
+              Buffer retrievedKey = algo::Rsa::decrypt(decryptionKey.buf(),
+                                                       decryptionKey.size(),
+                                                       encryptedKey.buf(),
+                                                       encryptedKey.size(),
+                                                       params);
+
+              BOOST_CHECK_EQUAL_COLLECTIONS(contentKey.begin(),
+                                            contentKey.end(),
+                                            retrievedKey.begin(),
+                                            retrievedKey.end());
+            }
+            BOOST_CHECK_EQUAL(result.size(), 3);
+          };
+
+  // Initial test to confirm that keys are created for this timeslot
+  Name contentKeyName1 =
+      producer.createContentKey(testTime1,
+      std::bind(checkEncryptionKeys, _1, testTime1, testTimeRounded1));
+
+  do {
+    advanceClocks(time::milliseconds(10), 20);
+  } while (passPacket());
+
+  // Verify that we do not repeat the search for e-keys, don't advance clock
+  Name contentKeyName2 =
+      producer.createContentKey(testTime2,
+      std::bind(checkEncryptionKeys, _1, testTime2, testTimeRounded2));
+
+  // Confirm content key names are correct
+  BOOST_CHECK_EQUAL(contentKeyName1.getPrefix(-1), cKeyName);
+  BOOST_CHECK_EQUAL(contentKeyName1.get(6), testTimeRounded1);
+  BOOST_CHECK_EQUAL(contentKeyName2.getPrefix(-1), cKeyName);
+  BOOST_CHECK_EQUAL(contentKeyName2.get(6), testTimeRounded2);
+
+  // Confirm produce encrypts with correct key and has right name
+  Data testData;
+  producer.produce(testData, testTime2, DATA_CONTEN, sizeof(DATA_CONTEN));
+
+  Name producedName = testData.getName();
+  BOOST_CHECK_EQUAL(producedName.getSubName(0,5), cKeyName.getPrefix(-1));
+  BOOST_CHECK_EQUAL(producedName.get(5), testTimeRounded2);
+  BOOST_CHECK_EQUAL(producedName.get(6), NAME_COMPONENT_FOR);
+  BOOST_CHECK_EQUAL(producedName.getSubName(7,6), cKeyName);
+  BOOST_CHECK_EQUAL(producedName.get(13), testTimeRounded2);
+
+  Block dataBlock = testData.getContent();
+  dataBlock.parse();
+
+  EncryptedContent dataContent(*(dataBlock).elements_begin());
+  const Buffer& encData = dataContent.getPayload();
+  const Buffer& iv = dataContent.getInitialVector();
+
+  algo::EncryptParams params(tlv::AlgorithmAesCbc, 16);
+  params.setIV(iv.buf(), iv.size());
+  Buffer decryptTest = algo::Aes::decrypt(contentKey.buf(), contentKey.size(),
+                                          encData.buf(), encData.size(), params);
+  BOOST_CHECK_EQUAL_COLLECTIONS(decryptTest.begin(),
+                                decryptTest.end(),
+                                DATA_CONTEN,
+                                DATA_CONTEN + sizeof(DATA_CONTEN));
+}
+
+BOOST_AUTO_TEST_CASE(ContentKeySearch)
+{
+  std::string dbDir = tmpPath.c_str();
+  dbDir += "/test.db";
+
+  Name timeMarkerFirstHop("20150101T070000/20150101T080000");
+  Name timeMarkerSecondHop("20150101T080000/20150101T090000");
+  Name timeMarkerThirdHop("20150101T100000/20150101T110000");
+
+  Name prefix("/prefix");
+  Name suffix("/suffix");
+  Name expectedInterest = prefix;
+  expectedInterest.append(NAME_COMPONENT_READ);
+  expectedInterest.append(suffix);
+  expectedInterest.append(NAME_COMPONENT_E_KEY);
+
+  Name cKeyName = prefix;
+  cKeyName.append(NAME_COMPONENT_SAMPLE);
+  cKeyName.append(suffix);
+  cKeyName.append(NAME_COMPONENT_C_KEY);
+
+  time::system_clock::TimePoint testTime = time::fromIsoString("20150101T100001");
+
+  // Create content keys required for this test case:
+  createEncryptionKey(expectedInterest, timeMarkerFirstHop);
+  createEncryptionKey(expectedInterest, timeMarkerSecondHop);
+  createEncryptionKey(expectedInterest, timeMarkerThirdHop);
+
+  size_t requestCount = 0;
+  face2->setInterestFilter(prefix,
+         [&] (const InterestFilter&, const Interest& i) {
+            BOOST_REQUIRE_EQUAL(i.getName(), expectedInterest);
+            Name interestName = i.getName();
+            switch(requestCount) {
+              case 0:
+                interestName.append(timeMarkerFirstHop);
+                break;
+
+              case 1:
+                interestName.append(timeMarkerSecondHop);
+                break;
+
+              case 2:
+                interestName.append(timeMarkerThirdHop);
+                break;
+
+              default:
+                break;
+            }
+            face2->put(*(encryptionKeys[interestName]));
+            requestCount++;
+            return;
+         },
+         RegisterPrefixSuccessCallback(),
+         [] (const Name&, const std::string& e) { });
+
+  do {
+    advanceClocks(time::milliseconds(10), 20);
+  } while (passPacket());
+
+  /*
+  Verify that if a key is found, but not within the right timeslot, the search
+  is refined until a valid timeslot is found.
+  */
+  Producer producer(prefix, suffix, *face1, dbDir);
+  producer.createContentKey(testTime,
+          [&](const std::vector<Data>& result){
+            BOOST_CHECK_EQUAL(requestCount, 3);
+            BOOST_CHECK_EQUAL(result.size(), 1);
+
+            Data keyData = result[0];
+            Name keyName = keyData.getName();
+            BOOST_CHECK_EQUAL(keyName.getSubName(0,4), cKeyName);
+            BOOST_CHECK_EQUAL(keyName.get(4), timeMarkerThirdHop[0]);
+            BOOST_CHECK_EQUAL(keyName.get(5), NAME_COMPONENT_FOR);
+            BOOST_CHECK_EQUAL(keyName.getSubName(6),
+                              expectedInterest.append(timeMarkerThirdHop));
+          });
+  do {
+    advanceClocks(time::milliseconds(10), 20);
+  } while (passPacket());
+}
+
+BOOST_AUTO_TEST_CASE(ContentKeyTimeout)
+{
+  std::string dbDir = tmpPath.c_str();
+  dbDir += "/test.db";
+
+  Name prefix("/prefix");
+  Name suffix("/suffix");
+  Name expectedInterest = prefix;
+  expectedInterest.append(NAME_COMPONENT_READ);
+  expectedInterest.append(suffix);
+  expectedInterest.append(NAME_COMPONENT_E_KEY);
+
+  time::system_clock::TimePoint testTime = time::fromIsoString("20150101T100001");
+
+  size_t timeoutCount = 0;
+  face2->setInterestFilter(prefix,
+         [&] (const InterestFilter&, const Interest& i) {
+            BOOST_CHECK_EQUAL(i.getName(), expectedInterest);
+            timeoutCount++;
+            return;
+         },
+         RegisterPrefixSuccessCallback(),
+         [] (const Name&, const std::string& e) { });
+
+  do {
+    advanceClocks(time::milliseconds(10), 20);
+  } while (passPacket());
+
+  /*
+  Verify that if no response is received, the producer appropriately times out.
+  The result vector should not contain elements that have timed out.
+  */
+  Producer producer(prefix, suffix, *face1, dbDir);
+  producer.createContentKey(testTime,
+          [&](const std::vector<Data>& result){
+            BOOST_CHECK_EQUAL(timeoutCount, 4);
+            BOOST_CHECK_EQUAL(result.size(), 0);
+          });
+
+  do {
+    advanceClocks(time::milliseconds(10), 500);
+  } while (passPacket());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace gep
+} // namespace ndn
