diff --git a/core/sub-tree-binary.cpp b/core/sub-tree-binary.cpp
new file mode 100644
index 0000000..be9c2d3
--- /dev/null
+++ b/core/sub-tree-binary.cpp
@@ -0,0 +1,471 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California
+ *
+ * This file is part of NSL (NDN Signature Logger).
+ * See AUTHORS.md for complete list of NSL authors and contributors.
+ *
+ * NSL 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.
+ *
+ * NSL 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
+ * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of nsl authors and contributors.
+ */
+
+#include "sub-tree-binary.hpp"
+
+#include <ndn-cxx/util/digest.hpp>
+#include <ndn-cxx/util/crypto.hpp>
+#include <ndn-cxx/security/digest-sha256.hpp>
+
+namespace nsl {
+
+const time::milliseconds SubTreeBinary::INCOMPLETE_FRESHNESS_PERIOD(60000);
+const std::string SubTreeBinary::COMPONENT_COMPLETE("complete");
+const ssize_t SubTreeBinary::OFFSET_ROOTHASH = -1;
+const ssize_t SubTreeBinary::OFFSET_COMPLETE = -2;
+const ssize_t SubTreeBinary::OFFSET_SEQNO = -3;
+const ssize_t SubTreeBinary::OFFSET_LEVEL = -4;
+const size_t SubTreeBinary::N_LOGGER_SUFFIX = 4;
+const size_t SubTreeBinary::SUB_TREE_DEPTH = 6;
+
+
+SubTreeBinary::SubTreeBinary(const Name& loggerName,
+                             const CompleteCallback& completeCallback,
+                             const RootUpdateCallback& rootUpdateCallback)
+  : m_loggerName(loggerName)
+  , m_completeCallback(completeCallback)
+  , m_rootUpdateCallback(rootUpdateCallback)
+{
+}
+
+SubTreeBinary::SubTreeBinary(const Name& loggerName,
+                             const Node::Index& peakIndex,
+                             const CompleteCallback& completeCallback,
+                             const RootUpdateCallback& rootUpdateCallback)
+  : m_loggerName(loggerName)
+  , m_completeCallback(completeCallback)
+  , m_rootUpdateCallback(rootUpdateCallback)
+{
+  initialize(peakIndex);
+}
+
+const NonNegativeInteger&
+SubTreeBinary::getNextLeafSeqNo() const
+{
+  if (m_actualRoot != nullptr)
+    return m_actualRoot->getLeafSeqNo();
+
+  return m_peakIndex.seqNo;
+}
+
+ndn::ConstBufferPtr
+SubTreeBinary::getRootHash() const
+{
+  if (m_actualRoot != nullptr)
+    return m_actualRoot->getHash();
+
+  return nullptr;
+}
+
+ConstNodePtr
+SubTreeBinary::getNode(const Node::Index& index) const
+{
+  auto it = m_nodes.find(index);
+  if (it != m_nodes.end()) {
+    return it->second;
+  }
+
+  return nullptr;
+}
+
+bool
+SubTreeBinary::addLeaf(NodePtr leaf)
+{
+  // sanity check: must be a valid leaf
+  if (leaf->getIndex().level != m_leafLevel ||
+      leaf->getIndex().seqNo < m_minSeqNo ||
+      leaf->getIndex().seqNo >= m_maxSeqNo)
+    return false;
+
+  // sanity check: must be the expected next leaf
+  if (leaf->getIndex().seqNo != m_pendingLeafSeqNo ||
+      !m_isPendingLeafEmpty)
+    return false;
+
+  // add the leaf
+  m_nodes[leaf->getIndex()] = leaf;
+
+  // update actual root (guarantee we will have a root)
+  updateActualRoot(leaf);
+
+  // update nodes and their hashes
+  updateParentNode(leaf);
+
+  if (leaf->isFull()) {
+    m_pendingLeafSeqNo = leaf->getIndex().seqNo + leaf->getIndex().range;
+    m_isPendingLeafEmpty = true;
+  }
+  else {
+    m_isPendingLeafEmpty = false;
+  }
+
+  return true;
+}
+
+bool
+SubTreeBinary::updateLeaf(const NonNegativeInteger& nextSeqNo, ndn::ConstBufferPtr hash)
+{
+  // std::cerr << "NextSeqNo: " << nextSeqNo << std::endl;
+  // std::cerr << "minSeqNo: " << m_minSeqNo << std::endl;
+  // std::cerr << "maxSeqNo: " << m_maxSeqNo << std::endl;
+
+  // sanity check
+  if (nextSeqNo < m_minSeqNo || nextSeqNo > m_maxSeqNo)
+    return false;
+
+  // std::cerr << "2" << std::endl;
+  // determine leaf index
+  NonNegativeInteger leafSeqNo = ((nextSeqNo - 1) >> m_leafLevel) << m_leafLevel;
+  if (m_pendingLeafSeqNo != leafSeqNo)
+    return false;
+
+  Node::Index index(leafSeqNo, m_leafLevel);
+  auto leaf = m_nodes[index];
+
+  if (leaf == nullptr) {
+    leaf = make_shared<Node>(leafSeqNo, m_leafLevel, nextSeqNo, hash);
+    m_nodes[index] = leaf;
+    updateActualRoot(leaf);
+  }
+  else {
+    leaf->setLeafSeqNo(nextSeqNo);
+    leaf->setHash(hash);
+  }
+
+  if (nextSeqNo == leafSeqNo + (1 << m_leafLevel)) {
+    m_pendingLeafSeqNo = nextSeqNo;
+    m_isPendingLeafEmpty = true;
+  }
+
+  updateParentNode(leaf);
+
+  return true;
+}
+
+bool
+SubTreeBinary::isFull() const
+{
+  if (m_actualRoot != nullptr &&
+      m_actualRoot->getIndex() == m_peakIndex &&
+      m_actualRoot->isFull())
+    return true;
+
+  return false;
+}
+
+shared_ptr<Data>
+SubTreeBinary::encode() const
+{
+  if (m_actualRoot == nullptr) {
+    auto emptyData = make_shared<Data>();
+    // Name
+    Name emptyName = m_loggerName;
+    emptyName.appendNumber(m_peakIndex.level)
+      .appendNumber(m_peakIndex.seqNo)
+      .appendNumber(m_peakIndex.seqNo)
+      .append(Node::getEmptyHash()->buf(), Node::getEmptyHash()->size());
+    emptyData->setName(emptyName);
+
+    // MetaInfo
+    emptyData->setFreshnessPeriod(time::milliseconds(0));
+
+    // Signature
+    ndn::DigestSha256 sig;
+    emptyData->setSignature(sig);
+
+    Block sigValue(tlv::SignatureValue,
+                   ndn::crypto::sha256(emptyData->wireEncode().value(),
+                                       emptyData->wireEncode().value_size() -
+                                       emptyData->getSignature().getValue().size()));
+    emptyData->setSignatureValue(sigValue);
+
+    emptyData->wireEncode();
+
+    return emptyData;
+  }
+
+  // Name
+  Name dataName = m_loggerName;
+  dataName.appendNumber(m_actualRoot->getIndex().level)
+    .appendNumber(m_actualRoot->getIndex().seqNo);
+  if (isFull())
+    dataName.append(COMPONENT_COMPLETE.c_str());
+  else
+    dataName.appendNumber(m_actualRoot->getLeafSeqNo());
+  dataName.append(m_actualRoot->getHash()->buf(), m_actualRoot->getHash()->size());
+
+  auto data = make_shared<Data>(dataName);
+
+  // MetaInfo
+  if (!isFull())
+    data->setFreshnessPeriod(INCOMPLETE_FRESHNESS_PERIOD);
+
+  // Content
+  auto buffer = make_shared<ndn::Buffer>();
+  NonNegativeInteger range = 1 << m_leafLevel;
+  for (NonNegativeInteger i = m_minSeqNo; i < m_maxSeqNo; i += range) {
+    auto it = m_nodes.find(Node::Index(i, m_leafLevel));
+    if (it == m_nodes.end())
+      break;
+
+    auto leaf = it->second;
+    if (leaf == nullptr)
+      break;
+    BOOST_ASSERT(leaf->getHash() != nullptr);
+    BOOST_ASSERT(leaf->getHash()->size() == 32);
+    buffer->insert(buffer->end(), leaf->getHash()->begin(), leaf->getHash()->end());
+  }
+  data->setContent(buffer->buf(), buffer->size());
+
+  // Signature
+  ndn::DigestSha256 sig;
+  data->setSignature(sig);
+
+  Block sigValue(tlv::SignatureValue,
+                 ndn::crypto::sha256(data->wireEncode().value(),
+                                     data->wireEncode().value_size() -
+                                     data->getSignature().getValue().size()));
+  data->setSignatureValue(sigValue);
+
+  data->wireEncode();
+  return data;
+}
+
+void
+SubTreeBinary::decode(const Data& data)
+{
+  bool isComplete = false;
+  NonNegativeInteger nextSeqNo;
+  ndn::ConstBufferPtr rootHash;
+  NonNegativeInteger seqNo;
+  size_t level;
+
+  const Name& dataName = data.getName();
+
+  if (!m_loggerName.isPrefixOf(dataName))
+    throw Error("decode: logger name does not match");
+
+  if (m_loggerName.size() + N_LOGGER_SUFFIX != dataName.size())
+    throw Error("decode: data name does not follow the naming convention");
+
+  try {
+    if (dataName.get(OFFSET_COMPLETE).toUri() == COMPONENT_COMPLETE)
+      isComplete = true;
+    else
+      nextSeqNo = dataName.get(OFFSET_COMPLETE).toNumber();
+
+    rootHash = make_shared<ndn::Buffer>(dataName.get(OFFSET_ROOTHASH).value(),
+                                        dataName.get(OFFSET_ROOTHASH).value_size());
+
+    seqNo = dataName.get(OFFSET_SEQNO).toNumber();
+    level = dataName.get(OFFSET_LEVEL).toNumber();
+  }
+  catch (tlv::Error&) {
+    throw Error("decode: logger name encoding error");
+  }
+
+  if (seqNo == 0) {
+    size_t peakLevel = 0;
+    if (level % (SUB_TREE_DEPTH - 1) != 0)
+      peakLevel = ((level + SUB_TREE_DEPTH - 1) / (SUB_TREE_DEPTH - 1)) * (SUB_TREE_DEPTH - 1);
+    else
+      peakLevel = level;
+
+    if (nextSeqNo == 1 << peakLevel)
+      peakLevel = peakLevel + SUB_TREE_DEPTH - 1;
+
+    initialize(Node::Index(seqNo, peakLevel));
+  }
+  else
+    initialize(Node::Index(seqNo, level));
+
+  if (isComplete)
+    nextSeqNo = seqNo + (1 << level);
+  else if (nextSeqNo == seqNo) // empty tree
+    return;
+
+  if (rootHash->size() != 32)
+    throw Error("decode: wrong root hash size");
+
+  if (nextSeqNo <= seqNo || nextSeqNo > seqNo + (1 << level))
+    throw Error("decode: wrong current leaf SeqNo");
+
+  int nLeaves = (nextSeqNo - seqNo - 1) / (1 << m_leafLevel) + 1;
+
+  // std::cerr << data.getName() << std::endl;
+  // std::cerr << nextSeqNo << std::endl;
+  // std::cerr << nLeaves * 32 << std::endl;
+  // std::cerr << data.getContent().value_size() << std::endl;
+
+  if (nLeaves * 32 != data.getContent().value_size())
+    throw Error("decode: inconsistent content");
+
+  const uint8_t* offset = data.getContent().value();
+  NonNegativeInteger seqNoInterval = 1 << m_leafLevel;
+  int i = 0;
+  for (; i < nLeaves - 1; i++) {
+    auto node = make_shared<Node>(seqNo + (i * seqNoInterval),
+                                  m_peakIndex.level + 1 - SUB_TREE_DEPTH,
+                                  seqNo + (i * seqNoInterval) + seqNoInterval,
+                                  make_shared<ndn::Buffer>(offset + (i * 32), 32));
+    addLeaf(node);
+  }
+
+  auto node = make_shared<Node>(seqNo + (i * seqNoInterval),
+                                m_peakIndex.level + 1 - SUB_TREE_DEPTH,
+                                nextSeqNo,
+                                make_shared<ndn::Buffer>(offset + (i * 32), 32));
+  addLeaf(node);
+
+  if (*rootHash != *getRoot()->getHash())
+    throw Error("decode: Inconsistent hash");
+}
+
+Node::Index
+SubTreeBinary::toSubTreePeakIndex(const Node::Index& index, bool notRoot)
+{
+  size_t peakLevel =
+    ((index.level + SUB_TREE_DEPTH - 1) / (SUB_TREE_DEPTH - 1)) * (SUB_TREE_DEPTH - 1);
+
+  size_t leafLevel = peakLevel + 1 - SUB_TREE_DEPTH;
+
+  if (index.level % (SUB_TREE_DEPTH - 1) == 0 && index.level > 0 && !notRoot) {
+    peakLevel -= (SUB_TREE_DEPTH - 1);
+    leafLevel -= (SUB_TREE_DEPTH - 1);
+  }
+
+  NonNegativeInteger peakSeqNo = (index.seqNo >> peakLevel) << peakLevel;
+
+  return Node::Index(peakSeqNo, peakLevel);
+}
+
+void
+SubTreeBinary::initialize(const Node::Index& peakIndex)
+{
+  m_peakIndex = peakIndex;
+
+  if (peakIndex.level + 1 < SUB_TREE_DEPTH ||
+      peakIndex.level % (SUB_TREE_DEPTH - 1) != 0)
+    throw Error("SubTreeBinary: peak level does not match the depth");
+
+  m_leafLevel = peakIndex.level + 1 - SUB_TREE_DEPTH;
+
+  m_minSeqNo = peakIndex.seqNo;
+  m_maxSeqNo = peakIndex.seqNo + peakIndex.range;
+
+  m_pendingLeafSeqNo = m_minSeqNo;
+  m_isPendingLeafEmpty = true;
+}
+
+
+
+void
+SubTreeBinary::updateActualRoot(NodePtr node)
+{
+  if (m_actualRoot == nullptr) {
+    // if actual root is not set yet
+    if (node->getIndex().seqNo == 0) { // root sub-tree
+      m_actualRoot = node;
+      m_rootUpdateCallback(node->getIndex(), node->getLeafSeqNo(), node->getHash());
+      return;
+    }
+    else {
+      m_actualRoot = make_shared<Node>(m_peakIndex.seqNo, m_peakIndex.level);
+      m_nodes[m_actualRoot->getIndex()] = m_actualRoot;
+      return;
+    }
+  }
+
+  if (m_actualRoot->getIndex() == m_peakIndex)
+    return;
+
+  if ((node->getIndex().seqNo >> m_actualRoot->getIndex().level) != 0) {
+    // a new actual root at a higher is needed
+    m_actualRoot = make_shared<Node>(m_minSeqNo, m_actualRoot->getIndex().level + 1);
+    m_nodes[m_actualRoot->getIndex()] = m_actualRoot;
+    return;
+  }
+}
+
+void
+SubTreeBinary::updateParentNode(NodePtr node)
+{
+  if (node->getIndex() == m_actualRoot->getIndex()) { // root does not have a parent
+    return;
+  }
+
+  size_t parentLevel = node->getIndex().level + 1;
+  NodePtr parentNode;
+
+  if ((node->getIndex().seqNo >> node->getIndex().level) % 2 == 0) { // left child
+    // parent may not exist
+    Node::Index parentIndex(node->getIndex().seqNo, parentLevel);
+    parentNode = m_nodes[parentIndex];
+
+    ndn::util::Sha256 sha256;
+    sha256 << parentIndex.level << parentIndex.seqNo;
+    sha256.update(node->getHash()->buf(), node->getHash()->size());
+    sha256.update(Node::getEmptyHash()->buf(), Node::getEmptyHash()->size());
+
+    if (parentNode == nullptr) {
+      parentNode = make_shared<Node>(node->getIndex().seqNo,
+                                     parentLevel,
+                                     node->getLeafSeqNo(),
+                                     sha256.computeDigest());
+    }
+    else {
+      parentNode->setHash(sha256.computeDigest());
+      parentNode->setLeafSeqNo(node->getLeafSeqNo());
+    }
+
+    m_nodes[parentNode->getIndex()] = parentNode;
+  }
+  else { // right child
+    // parent must exist
+    NonNegativeInteger parentSeqNo = node->getIndex().seqNo - node->getIndex().range;
+
+    Node::Index parentIndex(parentSeqNo, parentLevel);
+    Node::Index siblingIndex(parentSeqNo, parentLevel - 1);
+
+    parentNode = m_nodes[parentIndex];
+    auto siblingNode = m_nodes[siblingIndex];
+
+    ndn::util::Sha256 sha256;
+    sha256 << parentNode->getIndex().level << parentNode->getIndex().seqNo;
+    sha256.update(siblingNode->getHash()->buf(), siblingNode->getHash()->size());
+    sha256.update(node->getHash()->buf(), node->getHash()->size());
+
+    parentNode->setHash(sha256.computeDigest());
+    parentNode->setLeafSeqNo(node->getLeafSeqNo());
+  }
+
+  if (parentNode->getIndex() == m_actualRoot->getIndex()) { // reach root
+    m_rootUpdateCallback(parentNode->getIndex(),
+                         parentNode->getLeafSeqNo(),
+                         parentNode->getHash());
+    if (parentNode->getIndex() == m_peakIndex && parentNode->isFull())
+      m_completeCallback(parentNode->getIndex());
+  }
+  else
+    updateParentNode(parentNode);
+}
+
+} // namespace nsl
