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
