diff --git a/src/signature-info.cpp b/src/signature-info.cpp
new file mode 100644
index 0000000..1b8203d
--- /dev/null
+++ b/src/signature-info.cpp
@@ -0,0 +1,186 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library 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 Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "signature-info.hpp"
+
+namespace ndn {
+
+SignatureInfo::SignatureInfo()
+  : m_type(-1)
+  , m_hasKeyLocator(false)
+{
+}
+
+SignatureInfo::SignatureInfo(Tlv::SignatureTypeValue type)
+  : m_type(type)
+  , m_hasKeyLocator(false)
+{
+}
+
+SignatureInfo::SignatureInfo(Tlv::SignatureTypeValue type, const KeyLocator& keyLocator)
+  : m_type(type)
+  , m_hasKeyLocator(true)
+  , m_keyLocator(keyLocator)
+{
+}
+
+SignatureInfo::SignatureInfo(const Block& block)
+{
+  wireDecode(block);
+}
+
+void
+SignatureInfo::setSignatureType(Tlv::SignatureTypeValue type)
+{
+  m_wire.reset();
+  m_type = type;
+}
+
+void
+SignatureInfo::setKeyLocator(const KeyLocator& keyLocator)
+{
+  m_wire.reset();
+  m_keyLocator = keyLocator;
+  m_hasKeyLocator = true;
+}
+
+const KeyLocator&
+SignatureInfo::getKeyLocator() const
+{
+  if (m_hasKeyLocator)
+    return m_keyLocator;
+  else
+    throw Error("KeyLocator does not exist");
+}
+
+void
+SignatureInfo::appendTypeSpecificTlv(const Block& block)
+{
+  m_otherTlvs.push_back(block);
+}
+
+
+const Block&
+SignatureInfo::getTypeSpecificTlv(uint32_t type) const
+{
+  for (std::list<Block>::const_iterator i = m_otherTlvs.begin();
+       i != m_otherTlvs.end(); i++) {
+    if (i->type() == type)
+      return *i;
+  }
+
+  throw Error("(SignatureInfo::getTypeSpecificTlv) Requested a non-existed type [" +
+              boost::lexical_cast<std::string>(type) + "] from SignatureInfo");
+}
+
+template<bool T>
+size_t
+SignatureInfo::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t totalLength = 0;
+
+  for (std::list<Block>::const_reverse_iterator i = m_otherTlvs.rbegin();
+       i != m_otherTlvs.rend(); i++) {
+    totalLength += block.appendBlock(*i);
+  }
+
+  if (m_hasKeyLocator)
+    totalLength += m_keyLocator.wireEncode(block);
+
+  totalLength += prependNonNegativeIntegerBlock(block, Tlv::SignatureType, m_type);
+
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(Tlv::SignatureInfo);
+  return totalLength;
+}
+
+template size_t
+SignatureInfo::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+SignatureInfo::wireEncode<false>(EncodingImpl<false>& block) const;
+
+
+const Block&
+SignatureInfo::wireEncode() const
+{
+  if (m_wire.hasWire())
+    return m_wire;
+
+  EncodingEstimator estimator;
+  size_t estimatedSize = wireEncode(estimator);
+
+  EncodingBuffer buffer(estimatedSize, 0);
+  wireEncode(buffer);
+
+  m_wire = buffer.block();
+  return m_wire;
+}
+
+void
+SignatureInfo::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw Error("The supplied block does not contain wire format");
+  }
+
+  m_hasKeyLocator = false;
+
+  m_wire = wire;
+  m_wire.parse();
+
+  if (m_wire.type() != Tlv::SignatureInfo)
+    throw Tlv::Error("Unexpected TLV type when decoding Name");
+
+  Block::element_const_iterator it = m_wire.elements_begin();
+
+  // the first block must be SignatureType
+  if (it != m_wire.elements_end() && it->type() == Tlv::SignatureType) {
+    m_type = readNonNegativeInteger(*it);
+    it++;
+  }
+  else
+    throw Error("SignatureInfo does not have sub-TLV or the first sub-TLV is not SignatureType");
+
+  // the second block could be KeyLocator
+  if (it != m_wire.elements_end() && it->type() == Tlv::KeyLocator) {
+    m_keyLocator.wireDecode(*it);
+    m_hasKeyLocator = true;
+    it++;
+  }
+
+  // Decode the rest of type-specific TLVs, if any
+  while (it != m_wire.elements_end()) {
+    appendTypeSpecificTlv(*it);
+    it++;
+  }
+}
+
+bool
+SignatureInfo::operator==(const SignatureInfo& rhs) const
+{
+  return (m_type == rhs.m_type &&
+          m_hasKeyLocator == rhs.m_hasKeyLocator &&
+          m_keyLocator == rhs.m_keyLocator &&
+          m_otherTlvs == rhs.m_otherTlvs);
+}
+
+} // namespace ndn
