diff --git a/tools/pib/encoding/default-param.cpp b/tools/pib/encoding/default-param.cpp
new file mode 100644
index 0000000..015bf19
--- /dev/null
+++ b/tools/pib/encoding/default-param.cpp
@@ -0,0 +1,168 @@
+/* -*- 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 "default-param.hpp"
+#include <ndn-cxx/encoding/block-helpers.hpp>
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+namespace pib {
+
+static_assert(std::is_base_of<tlv::Error, DefaultParam::Error>::value,
+              "DefaultParam::Error must inherit from tlv::Error");
+
+const std::string DefaultParam::VERB("default");
+
+DefaultParam::DefaultParam()
+  : m_targetType(TYPE_DEFAULT)
+  , m_originType(TYPE_DEFAULT)
+{
+}
+
+DefaultParam::DefaultParam(const pib::Type targetType,
+                           const pib::Type originType,
+                           const Name& originName)
+  : m_targetType(targetType)
+  , m_originType(originType)
+  , m_originName(originName)
+{
+}
+
+DefaultParam::DefaultParam(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+const Name&
+DefaultParam::getOriginName() const
+{
+  if (m_originType == TYPE_ID || m_originType == TYPE_KEY || m_originType == TYPE_CERT)
+    return m_originName;
+  else
+    throw Error("DefaultParam::getOriginName: origin name does not exist");
+}
+
+template<bool T>
+size_t
+DefaultParam::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t totalLength = 0;
+
+  switch (m_originType) {
+  case TYPE_ID:
+  case TYPE_KEY:
+  case TYPE_CERT:
+    {
+      totalLength += m_originName.wireEncode(block);
+      break;
+    }
+  case TYPE_USER:
+    break;
+  default:
+    throw Error("DefaultParam::wireEncode: unsupported PibType: " +
+                boost::lexical_cast<std::string>(m_originType));
+  }
+
+  totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::Type, m_originType);
+  totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::Type, m_targetType);
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::pib::DefaultParam);
+
+  return totalLength;
+}
+
+template size_t
+DefaultParam::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+DefaultParam::wireEncode<false>(EncodingImpl<false>& block) const;
+
+const Block&
+DefaultParam::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
+DefaultParam::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw Error("The supplied block does not contain wire format");
+  }
+
+  m_wire = wire;
+  m_wire.parse();
+
+  if (m_wire.type() != tlv::pib::DefaultParam)
+    throw Error("Unexpected TLV type when decoding DefaultParam");
+
+  Block::element_const_iterator it = m_wire.elements_begin();
+
+  // the first block must be PibType
+  if (it != m_wire.elements_end() && it->type() == tlv::pib::Type) {
+    m_targetType = static_cast<pib::Type>(readNonNegativeInteger(*it));
+    it++;
+  }
+  else
+    throw Error("DefaultParam requires the first sub-TLV to be PibType");
+
+  // the second block must be PibType
+  if (it != m_wire.elements_end() && it->type() == tlv::pib::Type) {
+    m_originType = static_cast<pib::Type>(readNonNegativeInteger(*it));
+    it++;
+  }
+  else
+    throw Error("DefaultParam requires the second sub-TLV to be PibType");
+
+  switch (m_originType) {
+  case TYPE_ID:
+  case TYPE_KEY:
+  case TYPE_CERT:
+    {
+      if (it != m_wire.elements_end()) {
+        // the third block, if exists, must be Name
+        m_originName.wireDecode(*it);
+        return;
+      }
+      else {
+        throw Error("DefaultParam requires the third sub-TLV to be Name");
+      }
+    }
+  case TYPE_USER:
+    return;
+  default:
+    throw Error("DefaultParam::wireDecode: unsupported PibType: " +
+                boost::lexical_cast<std::string>(m_originType));
+  }
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/encoding/default-param.hpp b/tools/pib/encoding/default-param.hpp
new file mode 100644
index 0000000..1906954
--- /dev/null
+++ b/tools/pib/encoding/default-param.hpp
@@ -0,0 +1,128 @@
+/* -*- 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.
+ */
+
+
+#ifndef NDN_PIB_DEFAULT_PARAM_HPP
+#define NDN_PIB_DEFAULT_PARAM_HPP
+
+#include "pib-common.hpp"
+#include <ndn-cxx/name.hpp>
+
+namespace ndn {
+namespace pib {
+
+/**
+ * @brief DefaultParam is the abstraction of PIB Default parameter.
+ *
+ *  PibDefaultParam := PIB-DEFAULT-PARAM-TYPE TLV-LENGTH
+ *                     PibType    // target type
+ *                     PibType    // origin type
+ *                     Name?      // origin name
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Default-Parameters
+ */
+
+class DefaultParam : noncopyable
+{
+public:
+  class Error : public tlv::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : tlv::Error(what)
+    {
+    }
+  };
+
+  DefaultParam();
+
+  DefaultParam(const pib::Type targetType,
+               const pib::Type originType,
+               const Name& originName = Name());
+
+  explicit
+  DefaultParam(const Block& wire);
+
+  tlv::pib::ParamType
+  getParamType() const
+  {
+    return tlv::pib::DefaultParam;
+  }
+
+  pib::Type
+  getTargetType() const
+  {
+    return m_targetType;
+  }
+
+  pib::Type
+  getOriginType() const
+  {
+    return m_originType;
+  }
+
+  /**
+   * @brief Get target name
+   *
+   * @throws Error if origin name does not exist
+   */
+  const Name&
+  getOriginName() const;
+
+  /// @brief Encode to a wire format or estimate wire format
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  /**
+   * @brief Encode to a wire format
+   *
+   * @throws Error if encoding fails
+   */
+  const Block&
+  wireEncode() const;
+
+  /**
+   * @brief Decode GetParam from a wire encoded block
+   *
+   * @throws Error if decoding fails
+   */
+  void
+  wireDecode(const Block& wire);
+
+public:
+  static const std::string VERB;
+
+private:
+  pib::Type m_targetType;
+  pib::Type m_originType;
+  Name m_originName;
+
+  mutable Block m_wire;
+};
+
+} // namespace pib
+} // namespace ndn
+
+
+
+#endif // NDN_PIB_DEFAULT_PARAM_HPP
diff --git a/tools/pib/encoding/delete-param.cpp b/tools/pib/encoding/delete-param.cpp
new file mode 100644
index 0000000..41c8f6a
--- /dev/null
+++ b/tools/pib/encoding/delete-param.cpp
@@ -0,0 +1,129 @@
+/* -*- 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 "delete-param.hpp"
+#include <ndn-cxx/encoding/block-helpers.hpp>
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+namespace pib {
+
+static_assert(std::is_base_of<tlv::Error, DeleteParam::Error>::value,
+              "DeleteParam::Error must inherit from tlv::Error");
+
+const std::string DeleteParam::VERB("delete");
+
+DeleteParam::DeleteParam()
+  : m_targetType(TYPE_DEFAULT)
+{
+}
+
+DeleteParam::DeleteParam(const Name& name, pib::Type type)
+  : m_targetType(type)
+  , m_targetName(name)
+{
+}
+
+DeleteParam::DeleteParam(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+template<bool T>
+size_t
+DeleteParam::wireEncode(EncodingImpl<T>& block) const
+{
+  if (m_targetType != TYPE_ID &&
+      m_targetType != TYPE_KEY &&
+      m_targetType != TYPE_CERT &&
+      m_targetType != TYPE_USER)
+    throw Error("DeleteParam::wireEncode: Wrong Type value: " +
+                boost::lexical_cast<std::string>(m_targetType));
+
+  size_t totalLength = 0;
+
+  totalLength += m_targetName.wireEncode(block);
+  totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::Type, m_targetType);
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::pib::DeleteParam);
+
+  return totalLength;
+}
+
+template size_t
+DeleteParam::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+DeleteParam::wireEncode<false>(EncodingImpl<false>& block) const;
+
+const Block&
+DeleteParam::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
+DeleteParam::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw Error("The supplied block does not contain wire format");
+  }
+
+  m_wire = wire;
+  m_wire.parse();
+
+  if (m_wire.type() != tlv::pib::DeleteParam)
+    throw Error("Unexpected TLV type when decoding DeleteParam");
+
+  Block::element_const_iterator it = m_wire.elements_begin();
+
+  // the first block must be Type
+  if (it != m_wire.elements_end() && it->type() == tlv::pib::Type) {
+    m_targetType = static_cast<pib::Type>(readNonNegativeInteger(*it));
+    it++;
+  }
+  else
+    throw Error("DeleteParam requires the first sub-TLV to be Type");
+
+  // the second block must be Name
+  if (it != m_wire.elements_end() && it->type() == tlv::Name) {
+    m_targetName.wireDecode(*it);
+    it++;
+  }
+  else
+    throw Error("DeleteParam requires the second sub-TLV to be Name");
+
+  if (it != m_wire.elements_end())
+    throw Error("DeleteParam must not contain more than two sub-TLVs");
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/encoding/delete-param.hpp b/tools/pib/encoding/delete-param.hpp
new file mode 100644
index 0000000..14d8392
--- /dev/null
+++ b/tools/pib/encoding/delete-param.hpp
@@ -0,0 +1,114 @@
+/* -*- 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.
+ */
+
+#ifndef NDN_PIB_DELETE_PARAM_HPP
+#define NDN_PIB_DELETE_PARAM_HPP
+
+#include "pib-common.hpp"
+#include <ndn-cxx/name.hpp>
+
+namespace ndn {
+namespace pib {
+
+/**
+ * @brief DeleteParam is the abstraction of PIB Delete parameter.
+ *
+ * PibDeleteParam := PIB-DELETE-PARAM-TYPE TLV-LENGTH
+ *                   PibType
+ *                   Name
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Delete-Parameters
+ */
+
+class DeleteParam : noncopyable
+{
+public:
+  class Error : public tlv::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : tlv::Error(what)
+    {
+    }
+  };
+
+  DeleteParam();
+
+  explicit
+  DeleteParam(const Name& name, const pib::Type type = TYPE_ID);
+
+  explicit
+  DeleteParam(const Block& wire);
+
+  tlv::pib::ParamType
+  getParamType() const
+  {
+    return tlv::pib::DeleteParam;
+  }
+
+  pib::Type
+  getTargetType() const
+  {
+    return m_targetType;
+  }
+
+  const Name&
+  getTargetName() const
+  {
+    return m_targetName;
+  }
+
+  /// @brief Encode to a wire format or estimate wire format
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  /**
+   * @brief Encode to a wire format
+   *
+   * @throws Error if encoding fails
+   */
+  const Block&
+  wireEncode() const;
+
+  /**
+   * @brief Decode GetParam from a wire encoded block
+   *
+   * @throws Error if decoding fails
+   */
+  void
+  wireDecode(const Block& wire);
+
+public:
+  static const std::string VERB;
+
+private:
+  pib::Type m_targetType;
+  Name m_targetName;
+
+  mutable Block m_wire;
+};
+
+} // namespace pib
+} // namespace ndn
+
+#endif // NDN_PIB_DELETE_PARAM_HPP
diff --git a/tools/pib/encoding/get-param.cpp b/tools/pib/encoding/get-param.cpp
new file mode 100644
index 0000000..ea076f9
--- /dev/null
+++ b/tools/pib/encoding/get-param.cpp
@@ -0,0 +1,156 @@
+/* -*- 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 "get-param.hpp"
+#include <boost/lexical_cast.hpp>
+#include <ndn-cxx/encoding/block-helpers.hpp>
+
+namespace ndn {
+namespace pib {
+
+static_assert(std::is_base_of<tlv::Error, GetParam::Error>::value,
+              "GetParam::Error must inherit from tlv::Error");
+
+const std::string GetParam::VERB("get");
+
+GetParam::GetParam()
+  : m_targetType(TYPE_USER)
+{
+}
+
+GetParam::GetParam(const pib::Type targetType, const Name& targetName)
+  : m_targetType(targetType)
+  , m_targetName(targetName)
+{
+}
+
+GetParam::GetParam(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+const Name&
+GetParam::getTargetName() const
+{
+  if (m_targetType == TYPE_ID || m_targetType == TYPE_KEY || m_targetType == TYPE_CERT)
+    return m_targetName;
+  else
+    throw Error("GetParam::getTargetName: target name does not exist");
+}
+
+template<bool T>
+size_t
+GetParam::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t totalLength = 0;
+
+  switch (m_targetType) {
+  case TYPE_ID:
+  case TYPE_KEY:
+  case TYPE_CERT:
+    {
+      totalLength += m_targetName.wireEncode(block);
+      break;
+    }
+  case TYPE_USER:
+    break;
+  default:
+    throw Error("GetParam::wireEncode: unsupported PibType: " +
+                boost::lexical_cast<std::string>(m_targetType));
+  }
+
+  // Encode Type
+  totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::Type, m_targetType);
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::pib::GetParam);
+
+  return totalLength;
+}
+
+template size_t
+GetParam::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+GetParam::wireEncode<false>(EncodingImpl<false>& block) const;
+
+const Block&
+GetParam::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
+GetParam::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw Error("The supplied block does not contain wire format");
+  }
+
+  m_wire = wire;
+  m_wire.parse();
+
+  if (m_wire.type() != tlv::pib::GetParam)
+    throw Error("Unexpected TLV type when decoding GetParam");
+
+  Block::element_const_iterator it = m_wire.elements_begin();
+
+  // the first block must be Type
+  if (it != m_wire.elements_end() && it->type() == tlv::pib::Type) {
+    m_targetType = static_cast<pib::Type>(readNonNegativeInteger(*it));
+    it++;
+  }
+  else
+    throw Error("GetParam requires the first sub-TLV to be PibType");
+
+  switch (m_targetType) {
+  case TYPE_ID:
+  case TYPE_KEY:
+  case TYPE_CERT:
+    {
+      if (it != m_wire.elements_end()) {
+        // the second block, if exists, must be Name
+        m_targetName.wireDecode(*it);
+        return;
+      }
+      else {
+        throw Error("GetParam requires the second sub-TLV to be Name");
+      }
+    }
+  case TYPE_USER:
+    return;
+  default:
+    throw Error("GetParam::wireDecode: unsupported PibType: " +
+                boost::lexical_cast<std::string>(m_targetType));
+  }
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/encoding/get-param.hpp b/tools/pib/encoding/get-param.hpp
new file mode 100644
index 0000000..39a6c0e
--- /dev/null
+++ b/tools/pib/encoding/get-param.hpp
@@ -0,0 +1,115 @@
+/* -*- 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.
+ */
+
+#ifndef NDN_PIB_GET_PARAM_HPP
+#define NDN_PIB_GET_PARAM_HPP
+
+#include "pib-common.hpp"
+#include <ndn-cxx/name.hpp>
+
+namespace ndn {
+namespace pib {
+
+/**
+ * @brief GetParam is the abstraction of PIB Get parameter.
+ *
+ * PibGetParam := PIB-GET-PARAM-TYPE TLV-LENGTH
+ *                PibType
+ *                Name?
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Get-Parameters
+ */
+
+class GetParam : noncopyable
+{
+public:
+  class Error : public tlv::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : tlv::Error(what)
+    {
+    }
+  };
+
+  GetParam();
+
+  GetParam(const pib::Type targetType, const Name& targetName);
+
+  explicit
+  GetParam(const Block& wire);
+
+  tlv::pib::ParamType
+  getParamType() const
+  {
+    return tlv::pib::GetParam;
+  }
+
+  pib::Type
+  getTargetType() const
+  {
+    return m_targetType;
+  }
+
+  /**
+   * @brief Get target name
+   *
+   * @throws Error if target name does not exist
+   */
+  const Name&
+  getTargetName() const;
+
+  /// @brief Encode to a wire format or estimate wire format
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  /**
+   * @brief Encode to a wire format
+   *
+   * @throws Error if encoding fails
+   */
+  const Block&
+  wireEncode() const;
+
+  /**
+   * @brief Decode GetParam from a wire encoded block
+   *
+   * @throws Error if decoding fails
+   */
+  void
+  wireDecode(const Block& wire);
+
+public:
+  static const std::string VERB;
+
+private:
+  pib::Type m_targetType;
+  Name m_targetName;
+
+  mutable Block m_wire;
+};
+
+} // namespace pib
+} // namespace ndn
+
+#endif // NDN_PIB_GET_PARAM_HPP
diff --git a/tools/pib/encoding/list-param.cpp b/tools/pib/encoding/list-param.cpp
new file mode 100644
index 0000000..cb604e6
--- /dev/null
+++ b/tools/pib/encoding/list-param.cpp
@@ -0,0 +1,155 @@
+/* -*- 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 "list-param.hpp"
+#include <ndn-cxx/encoding/block-helpers.hpp>
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+namespace pib {
+
+static_assert(std::is_base_of<tlv::Error, ListParam::Error>::value,
+              "ListParam::Error must inherit from tlv::Error");
+
+const std::string ListParam::VERB("list");
+
+ListParam::ListParam()
+  : m_originType(TYPE_USER)
+{
+}
+
+ListParam::ListParam(const pib::Type originType, const Name& originName)
+  : m_originType(originType)
+  , m_originName(originName)
+{
+}
+
+ListParam::ListParam(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+const Name&
+ListParam::getOriginName() const
+{
+  if (m_originType == TYPE_ID || m_originType == TYPE_KEY || m_originType == TYPE_CERT)
+    return m_originName;
+  else
+    throw Error("ListParam::getOriginName: origin name does not exist");
+}
+
+template<bool T>
+size_t
+ListParam::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t totalLength = 0;
+
+  switch (m_originType) {
+  case TYPE_ID:
+  case TYPE_KEY:
+  case TYPE_CERT:
+    {
+      totalLength += m_originName.wireEncode(block);
+      break;
+    }
+  case TYPE_USER:
+    break;
+  default:
+    throw Error("ListParam::wireEncode: unsupported PibType: " +
+                boost::lexical_cast<std::string>(m_originType));
+  }
+
+  totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::Type, m_originType);
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::pib::ListParam);
+
+  return totalLength;
+}
+
+template size_t
+ListParam::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+ListParam::wireEncode<false>(EncodingImpl<false>& block) const;
+
+const Block&
+ListParam::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
+ListParam::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw Error("The supplied block does not contain wire format");
+  }
+
+  m_wire = wire;
+  m_wire.parse();
+
+  if (m_wire.type() != tlv::pib::ListParam)
+    throw Error("Unexpected TLV type when decoding ListParam");
+
+  Block::element_const_iterator it = m_wire.elements_begin();
+
+  // the first block must be PibType
+  if (it != m_wire.elements_end() && it->type() == tlv::pib::Type) {
+    m_originType = static_cast<pib::Type>(readNonNegativeInteger(*it));
+    it++;
+  }
+  else
+    throw Error("ListParam requires the first sub-TLV to be PibType");
+
+  switch (m_originType) {
+  case TYPE_ID:
+  case TYPE_KEY:
+  case TYPE_CERT:
+    {
+      if (it != m_wire.elements_end()) {
+        // the second block, if exists, must be Name
+        m_originName.wireDecode(*it);
+        return;
+      }
+      else {
+        throw Error("ListParam requires the second sub-TLV to be Name");
+      }
+    }
+  case TYPE_USER:
+    return;
+  default:
+    throw Error("ListParam::wireDecode: unsupported PibType: " +
+                boost::lexical_cast<std::string>(m_originType));
+  }
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/encoding/list-param.hpp b/tools/pib/encoding/list-param.hpp
new file mode 100644
index 0000000..f94732e
--- /dev/null
+++ b/tools/pib/encoding/list-param.hpp
@@ -0,0 +1,118 @@
+/* -*- 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.
+ */
+
+
+#ifndef NDN_PIB_LIST_PARAM_HPP
+#define NDN_PIB_LIST_PARAM_HPP
+
+#include "pib-common.hpp"
+#include <ndn-cxx/name.hpp>
+
+namespace ndn {
+namespace pib {
+
+/**
+ * @brief ListParam is the abstraction of PIB List parameter.
+ *
+ *  PibListParam := PIB-LIST-PARAM-TYPE TLV-LENGTH
+ *                  PibType    // origin type
+ *                  Name?      // origin name
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#List-Parameters
+ */
+
+class ListParam : noncopyable
+{
+public:
+  class Error : public tlv::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : tlv::Error(what)
+    {
+    }
+  };
+
+  ListParam();
+
+  ListParam(const pib::Type originType, const Name& originName);
+
+  explicit
+  ListParam(const Block& wire);
+
+  tlv::pib::ParamType
+  getParamType() const
+  {
+    return tlv::pib::ListParam;
+  }
+
+  pib::Type
+  getOriginType() const
+  {
+    return m_originType;
+  }
+
+  /**
+   * @brief Get target name
+   *
+   * @throws Error if origin name does not exist
+   */
+  const Name&
+  getOriginName() const;
+
+  /// @brief Encode to a wire format or estimate wire format
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  /**
+   * @brief Encode to a wire format
+   *
+   * @throws Error if encoding fails
+   */
+  const Block&
+  wireEncode() const;
+
+  /**
+   * @brief Decode GetParam from a wire encoded block
+   *
+   * @throws Error if decoding fails
+   */
+  void
+  wireDecode(const Block& wire);
+
+public:
+  static const std::string VERB;
+
+private:
+  pib::Type m_originType;
+  Name m_originName;
+
+  mutable Block m_wire;
+};
+
+} // namespace pib
+} // namespace ndn
+
+
+
+#endif // NDN_PIB_LIST_PARAM_HPP
diff --git a/tools/pib/encoding/pib-common.hpp b/tools/pib/encoding/pib-common.hpp
new file mode 100644
index 0000000..74c5daf
--- /dev/null
+++ b/tools/pib/encoding/pib-common.hpp
@@ -0,0 +1,128 @@
+/* -*- 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.
+ */
+
+#ifndef NDN_PIB_PIB_COMMON_HPP
+#define NDN_PIB_PIB_COMMON_HPP
+
+namespace ndn {
+namespace pib {
+
+/// @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base
+
+enum {
+  OFFSET_USER              = 2,
+  OFFSET_VERB              = 3,
+  OFFSET_PARAM             = 4,
+  OFFSET_TIMESTAMP         = 5,
+  OFFSET_NONCE             = 6,
+  OFFSET_SIG_INFO          = 7,
+  OFFSET_SIG_VALUE         = 8,
+
+  MIN_PIB_INTEREST_SIZE    = 5,
+  SIGNED_PIB_INTEREST_SIZE = 9
+};
+
+enum Type {
+  TYPE_USER    = 0,
+  TYPE_ID      = 1,
+  TYPE_KEY     = 2,
+  TYPE_CERT    = 3,
+  TYPE_DEFAULT = 255
+};
+
+enum DefaultOpt {
+  DEFAULT_OPT_NO   = 0,
+  DEFAULT_OPT_KEY  = 1, // 0x01
+  DEFAULT_OPT_ID   = 3, // 0x03
+  DEFAULT_OPT_USER = 7 // 0x07
+};
+
+enum DefaultOptMask {
+  DEFAULT_OPT_KEY_MASK  = 0x1,
+  DEFAULT_OPT_ID_MASK   = 0x2,
+  DEFAULT_OPT_USER_MASK = 0x4
+};
+
+enum ErrCode {
+  ERR_SUCCESS = 0,
+
+  // Invalid query
+  ERR_INCOMPLETE_COMMAND = 1,
+  ERR_WRONG_VERB         = 2,
+  ERR_WRONG_PARAM        = 3,
+  ERR_WRONG_SIGNER       = 4,
+  ERR_INTERNAL_ERROR     = 5,
+
+  // Non existing entity
+  ERR_NON_EXISTING_USER = 128,
+  ERR_NON_EXISTING_ID   = 129,
+  ERR_NON_EXISTING_KEY  = 130,
+  ERR_NON_EXISTING_CERT = 131,
+
+  // No default setting
+  ERR_NO_DEFAULT_ID     = 256,
+  ERR_NO_DEFAULT_KEY    = 257,
+  ERR_NO_DEFAULT_CERT   = 258,
+
+  // Delete default setting
+  ERR_DELETE_DEFAULT_SETTING = 384
+};
+
+} // namespace pib
+
+
+namespace tlv {
+namespace pib {
+
+enum ParamType {
+  GetParam          = 128, // 0x80
+  DefaultParam      = 129, // 0x81
+  ListParam         = 130, // 0x82
+  UpdateParam       = 131, // 0x83
+  DeleteParam       = 132  // 0x84
+};
+
+enum EntityType {
+  User              = 144, // 0x90
+  Identity          = 145, // 0x91
+  PublicKey         = 146, // 0x92
+  Certificate       = 147  // 0x93
+};
+
+// Other
+enum {
+  Bytes             = 148, // 0x94
+  DefaultOpt        = 149, // 0x95
+  NameList          = 150, // 0x96
+  Type              = 151, // 0x97
+  Error             = 152, // 0x98
+  TpmLocator        = 153, // 0x99
+
+  // ErrorCode
+  ErrorCode         = 252  // 0xfc
+};
+
+} // namespace pib
+} // namespace tlv
+} // namespace ndn
+
+
+#endif // NDN_PIB_PIB_COMMON_HPP
diff --git a/tools/pib/encoding/pib-encoding.cpp b/tools/pib/encoding/pib-encoding.cpp
new file mode 100644
index 0000000..e7c5ca4
--- /dev/null
+++ b/tools/pib/encoding/pib-encoding.cpp
@@ -0,0 +1,525 @@
+/* -*- 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 "pib-encoding.hpp"
+#include <ndn-cxx/encoding/block-helpers.hpp>
+#include <ndn-cxx/encoding/encoding-buffer.hpp>
+#include <vector>
+#include <string>
+
+namespace ndn {
+namespace pib {
+
+using std::vector;
+using std::string;
+
+PibIdentity::PibIdentity()
+{
+}
+
+PibIdentity::PibIdentity(const Name& identity)
+  : m_identity(identity)
+{
+}
+
+PibIdentity::PibIdentity(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+template<bool T>
+size_t
+PibIdentity::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t totalLength = m_identity.wireEncode(block);
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::pib::Identity);
+
+  return totalLength;
+}
+
+template size_t
+PibIdentity::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+PibIdentity::wireEncode<false>(EncodingImpl<false>& block) const;
+
+const Block&
+PibIdentity::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
+PibIdentity::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw tlv::Error("The supplied block does not contain wire format");
+  }
+
+  if (wire.type() != tlv::pib::Identity)
+    throw tlv::Error("Unexpected TLV type when decoding PibIdentity");
+
+  m_wire = wire;
+  m_identity.wireDecode(m_wire.blockFromValue());
+}
+
+
+
+PibPublicKey::PibPublicKey()
+  : m_isValueSet(false)
+{
+}
+
+PibPublicKey::PibPublicKey(const Name& keyName, const PublicKey& key)
+  : m_isValueSet(true)
+  , m_keyName(keyName)
+  , m_key(key)
+{
+}
+
+PibPublicKey::PibPublicKey(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+const Name&
+PibPublicKey::getKeyName() const
+{
+  if (m_isValueSet)
+    return m_keyName;
+  else
+    throw tlv::Error("PibPublicKey::getKeyName: keyName is not set");
+}
+
+const PublicKey&
+PibPublicKey::getPublicKey() const
+{
+  if (m_isValueSet)
+    return m_key;
+  else
+    throw tlv::Error("PibPublicKey::getPublicKey: key is not set");
+}
+
+template<bool T>
+size_t
+PibPublicKey::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t totalLength = prependByteArrayBlock(block, tlv::pib::Bytes,
+                                             m_key.get().buf(), m_key.get().size());
+  totalLength += m_keyName.wireEncode(block);
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::pib::PublicKey);
+
+  return totalLength;
+}
+
+template size_t
+PibPublicKey::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+PibPublicKey::wireEncode<false>(EncodingImpl<false>& block) const;
+
+const Block&
+PibPublicKey::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
+PibPublicKey::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw tlv::Error("The supplied block does not contain wire format");
+  }
+
+  if (wire.type() != tlv::pib::PublicKey)
+    throw tlv::Error("Unexpected TLV type when decoding PibPublicKey");
+
+  m_wire = wire;
+  m_wire.parse();
+
+  Block::element_const_iterator it = m_wire.elements_begin();
+  if (it != m_wire.elements_end() && it->type() == tlv::Name) {
+    m_keyName.wireDecode(*it);
+    it++;
+  }
+  else
+    throw tlv::Error("PibPublicKey requires the first sub-TLV to be Name");
+
+  if (it != m_wire.elements_end() && it->type() == tlv::pib::Bytes) {
+    m_key = PublicKey(it->value(), it->value_size());
+    it++;
+  }
+  else
+    throw tlv::Error("PibPublicKey requires the second sub-TLV to be Bytes");
+
+  m_isValueSet = true;
+  if (it != m_wire.elements_end())
+    throw tlv::Error("PibPublicKey must contain only two sub-TLVs");
+}
+
+
+PibCertificate::PibCertificate()
+  : m_isValueSet(false)
+{
+}
+
+PibCertificate::PibCertificate(const IdentityCertificate& certificate)
+  : m_isValueSet(true)
+  , m_certificate(certificate)
+{
+}
+
+PibCertificate::PibCertificate(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+const IdentityCertificate&
+PibCertificate::getCertificate() const
+{
+  if (m_isValueSet)
+    return m_certificate;
+  else
+    throw tlv::Error("PibCertificate::getCertificate: certificate is not set");
+}
+
+template<bool T>
+size_t
+PibCertificate::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t totalLength = prependBlock(block, m_certificate.wireEncode());
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::pib::Certificate);
+
+  return totalLength;
+}
+
+template size_t
+PibCertificate::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+PibCertificate::wireEncode<false>(EncodingImpl<false>& block) const;
+
+const Block&
+PibCertificate::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
+PibCertificate::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw tlv::Error("The supplied block does not contain wire format");
+  }
+
+  if (wire.type() != tlv::pib::Certificate)
+    throw tlv::Error("Unexpected TLV type when decoding PibCertificate");
+
+  m_wire = wire;
+  m_certificate.wireDecode(m_wire.blockFromValue());
+
+  m_isValueSet = true;
+}
+
+
+PibNameList::PibNameList()
+{
+}
+
+PibNameList::PibNameList(const std::vector<Name>& names)
+  : m_names(names)
+{
+}
+
+PibNameList::PibNameList(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+template<bool T>
+size_t
+PibNameList::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t totalLength = 0;
+
+  for (vector<Name>::const_reverse_iterator it = m_names.rbegin();
+       it != m_names.rend(); it++) {
+    totalLength += it->wireEncode(block);
+  }
+
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::pib::NameList);
+  return totalLength;
+}
+
+template size_t
+PibNameList::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+PibNameList::wireEncode<false>(EncodingImpl<false>& block) const;
+
+
+const Block&
+PibNameList::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
+PibNameList::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw tlv::Error("The supplied block does not contain wire format");
+  }
+
+  if (wire.type() != tlv::pib::NameList)
+    throw tlv::Error("Unexpected TLV type when decoding PibNameList");
+
+  m_wire = wire;
+  m_wire.parse();
+  for (Block::element_const_iterator it = m_wire.elements_begin();
+       it != m_wire.elements_end(); it++) {
+    if (it->type() == tlv::Name) {
+      Name name;
+      name.wireDecode(*it);
+      m_names.push_back(name);
+    }
+  }
+}
+
+PibError::PibError()
+  : m_errCode(ERR_SUCCESS)
+{
+}
+
+PibError::PibError(const pib::ErrCode errCode, const std::string& msg)
+  : m_errCode(errCode)
+  , m_msg(msg)
+{
+}
+
+PibError::PibError(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+template<bool T>
+size_t
+PibError::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t totalLength = 0;
+  totalLength += prependByteArrayBlock(block, tlv::pib::Bytes,
+                                       reinterpret_cast<const uint8_t*>(m_msg.c_str()),
+                                       m_msg.size());
+  totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::ErrorCode, m_errCode);
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::pib::Error);
+  return totalLength;
+}
+
+template size_t
+PibError::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+PibError::wireEncode<false>(EncodingImpl<false>& block) const;
+
+
+const Block&
+PibError::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
+PibError::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw tlv::Error("The supplied block does not contain wire format");
+  }
+
+  if (wire.type() != tlv::pib::Error)
+    throw tlv::Error("Unexpected TLV type when decoding Error");
+
+  m_wire = wire;
+  m_wire.parse();
+  Block::element_const_iterator it = m_wire.elements_begin();
+
+  if (it != m_wire.elements_end() && it->type() == tlv::pib::ErrorCode) {
+    m_errCode = static_cast<pib::ErrCode>(readNonNegativeInteger(*it));
+    it++;
+  }
+  else
+    throw tlv::Error("PibError requires the first sub-TLV to be ErrorCode");
+
+  if (it != m_wire.elements_end() && it->type() == tlv::pib::Bytes) {
+    m_msg = string(reinterpret_cast<const char*>(it->value()), it->value_size());
+    it++;
+  }
+  else
+    throw tlv::Error("PibError requires the second sub-TLV to be Bytes");
+}
+
+PibUser::PibUser()
+{
+}
+
+PibUser::PibUser(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+void
+PibUser::setMgmtCert(const IdentityCertificate& mgmtCert)
+{
+  m_wire.reset();
+  m_mgmtCert = mgmtCert;
+}
+
+void
+PibUser::setTpmLocator(const std::string& tpmLocator)
+{
+  m_wire.reset();
+  m_tpmLocator = tpmLocator;
+}
+
+template<bool T>
+size_t
+PibUser::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t totalLength = 0;
+
+  if (!m_tpmLocator.empty())
+    totalLength = prependByteArrayBlock(block, tlv::pib::TpmLocator,
+                                        reinterpret_cast<const uint8_t*>(m_tpmLocator.c_str()),
+                                        m_tpmLocator.size());
+
+  totalLength += prependBlock(block, m_mgmtCert.wireEncode());
+
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::pib::User);
+
+  return totalLength;
+}
+
+template size_t
+PibUser::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+PibUser::wireEncode<false>(EncodingImpl<false>& block) const;
+
+
+const Block&
+PibUser::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
+PibUser::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw tlv::Error("The supplied block does not contain wire format");
+  }
+
+  if (wire.type() != tlv::pib::User)
+    throw tlv::Error("Unexpected TLV type when decoding Content");
+
+  m_wire = wire;
+  m_wire.parse();
+
+  Block::element_const_iterator it = m_wire.elements_begin();
+  if (it != m_wire.elements_end() && it->type() == tlv::Data) {
+    m_mgmtCert.wireDecode(*it);
+    it++;
+  }
+  else
+    throw tlv::Error("PibError requires the first sub-TLV to be Data");
+
+  if (it != m_wire.elements_end() && it->type() == tlv::pib::TpmLocator) {
+    m_tpmLocator = string(reinterpret_cast<const char*>(it->value()), it->value_size());
+  }
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/encoding/pib-encoding.hpp b/tools/pib/encoding/pib-encoding.hpp
new file mode 100644
index 0000000..9ebb4c4
--- /dev/null
+++ b/tools/pib/encoding/pib-encoding.hpp
@@ -0,0 +1,316 @@
+/* -*- 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.
+ */
+
+#ifndef NDN_PIB_PIB_ENCODING_HPP
+#define NDN_PIB_PIB_ENCODING_HPP
+
+#include "pib-common.hpp"
+#include <ndn-cxx/security/identity-certificate.hpp>
+
+namespace ndn {
+namespace pib {
+
+/**
+ * @brief Abstraction of pib::Identity TLV.
+ *
+ * This class is copyable since it is used by a variety of pib parameters
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Query-Responses
+ */
+class PibIdentity
+{
+public:
+  PibIdentity();
+
+  explicit
+  PibIdentity(const Name& identity);
+
+  explicit
+  PibIdentity(const Block& wire);
+
+  const Name&
+  getIdentity() const
+  {
+    return m_identity;
+  }
+
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  const Block&
+  wireEncode() const;
+
+  /**
+   * @brief Decode PibIdentity from a wire encoded block
+   *
+   * @throws tlv::Error if decoding fails
+   */
+  void
+  wireDecode(const Block& wire);
+
+private:
+  Name m_identity;
+
+  mutable Block m_wire;
+};
+
+/**
+ * @brief Abstraction of pib::PublicKey TLV.
+ *
+ * This class is copyable since it is used by a variety of pib parameters
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Query-Responses
+ */
+class PibPublicKey
+{
+public:
+  PibPublicKey();
+
+  PibPublicKey(const Name& keyName, const PublicKey& key);
+
+  explicit
+  PibPublicKey(const Block& wire);
+
+  const Name&
+  getKeyName() const;
+
+  const PublicKey&
+  getPublicKey() const;
+
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  const Block&
+  wireEncode() const;
+
+  /**
+   * @brief Decode PibPublicKey from a wire encoded block
+   *
+   * @throws tlv::Error if decoding fails
+   */
+  void
+  wireDecode(const Block& wire);
+
+private:
+  bool m_isValueSet;
+  Name m_keyName;
+  PublicKey m_key;
+
+  mutable Block m_wire;
+};
+
+/**
+ * @brief Abstraction of pib::Certificate TLV.
+ *
+ * This class is copyable since it is used by a variety of pib parameters
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Query-Responses
+ */
+class PibCertificate
+{
+public:
+  PibCertificate();
+
+  explicit
+  PibCertificate(const IdentityCertificate& certificate);
+
+  explicit
+  PibCertificate(const Block& wire);
+
+  const IdentityCertificate&
+  getCertificate() const;
+
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  const Block&
+  wireEncode() const;
+
+  /**
+   * @brief Decode PibCertificate from a wire encoded block
+   *
+   * @throws tlv::Error if decoding fails
+   */
+  void
+  wireDecode(const Block& wire);
+
+private:
+  bool m_isValueSet;
+  IdentityCertificate m_certificate;
+
+  mutable Block m_wire;
+};
+
+/**
+ * @brief Abstraction of pib::NameList TLV.
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#List-Parameters
+ */
+class PibNameList : noncopyable
+{
+public:
+  PibNameList();
+
+  explicit
+  PibNameList(const std::vector<Name>& names);
+
+  explicit
+  PibNameList(const Block& wire);
+
+  const std::vector<Name>&
+  getNameList() const
+  {
+    return m_names;
+  }
+
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  const Block&
+  wireEncode() const;
+
+  /**
+   * @brief Decode PibCertificate from a wire encoded block
+   *
+   * @throws tlv::Error if decoding fails
+   */
+  void
+  wireDecode(const Block& wire);
+
+private:
+  std::vector<Name> m_names;
+
+  mutable Block m_wire;
+};
+
+/**
+ * @brief Abstraction of pib::Error TLV.
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Query-Responses
+ */
+class PibError : noncopyable
+{
+public:
+  PibError();
+
+  explicit
+  PibError(const pib::ErrCode errCode, const std::string& msg = "");
+
+  explicit
+  PibError(const Block& wire);
+
+  pib::ErrCode
+  getErrorCode() const
+  {
+    return m_errCode;
+  }
+
+  const std::string&
+  getErrorMsg() const
+  {
+    return m_msg;
+  }
+
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  const Block&
+  wireEncode() const;
+
+  /**
+   * @brief Decode PibCertificate from a wire encoded block
+   *
+   * @throws tlv::Error if decoding fails
+   */
+  void
+  wireDecode(const Block& wire);
+
+private:
+  pib::ErrCode m_errCode;
+  std::string m_msg;
+
+  mutable Block m_wire;
+};
+
+/**
+ * @brief Abstraction of pib::User TLV.
+ *
+ * This class is copyable since it is used by a variety of pib parameters
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Query-Responses
+ */
+class PibUser
+{
+public:
+  PibUser();
+
+  explicit
+  PibUser(const Block& wire);
+
+  void
+  setMgmtCert(const IdentityCertificate& mgmtCert);
+
+  const IdentityCertificate&
+  getMgmtCert() const
+  {
+    return m_mgmtCert;
+  }
+
+  void
+  setTpmLocator(const std::string& tpmLocator);
+
+  const std::string&
+  getTpmLocator() const
+  {
+    return m_tpmLocator;
+  }
+
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  const Block&
+  wireEncode() const;
+
+  /**
+   * @brief Decode PibCertificate from a wire encoded block
+   *
+   * @throws tlv::Error if decoding fails
+   */
+  void
+  wireDecode(const Block& wire);
+
+private:
+  IdentityCertificate m_mgmtCert;
+  std::string m_tpmLocator;
+
+  mutable Block m_wire;
+};
+
+} // namespace pib
+} // namespace ndn
+
+#endif // NDN_PIB_PIB_ENCODING_HPP
diff --git a/tools/pib/encoding/update-param.cpp b/tools/pib/encoding/update-param.cpp
new file mode 100644
index 0000000..71a6602
--- /dev/null
+++ b/tools/pib/encoding/update-param.cpp
@@ -0,0 +1,235 @@
+/* -*- 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 "update-param.hpp"
+#include <ndn-cxx/encoding/block-helpers.hpp>
+#include <boost/lexical_cast.hpp>
+
+namespace ndn {
+namespace pib {
+
+static_assert(std::is_base_of<tlv::Error, UpdateParam::Error>::value,
+              "UpdateParam::Error must inherit from tlv::Error");
+
+const std::string UpdateParam::VERB("update");
+
+UpdateParam::UpdateParam()
+  : m_defaultOpt(DEFAULT_OPT_NO)
+{
+}
+
+UpdateParam::UpdateParam(const PibUser& user)
+  : m_entityType(tlv::pib::User)
+  , m_user(user)
+  , m_defaultOpt(DEFAULT_OPT_NO)
+{
+}
+
+UpdateParam::UpdateParam(const Name& identity, DefaultOpt defaultOpt)
+  : m_entityType(tlv::pib::Identity)
+  , m_identity(identity)
+  , m_defaultOpt(defaultOpt)
+{
+}
+
+UpdateParam::UpdateParam(const Name& keyName, const PublicKey& key, DefaultOpt defaultOpt)
+  : m_entityType(tlv::pib::PublicKey)
+  , m_key(keyName, key)
+  , m_defaultOpt(defaultOpt)
+{
+}
+
+UpdateParam::UpdateParam(const IdentityCertificate& certificate, DefaultOpt defaultOpt)
+  : m_entityType(tlv::pib::Certificate)
+  , m_certificate(certificate)
+  , m_defaultOpt(defaultOpt)
+{
+}
+
+UpdateParam::UpdateParam(const Block& wire)
+{
+  wireDecode(wire);
+}
+
+const PibUser&
+UpdateParam::getUser() const
+{
+  if (m_entityType == tlv::pib::User)
+      return m_user;
+  else
+    throw Error("UpdateParam::getUser: entityType must be User");
+}
+
+const PibIdentity&
+UpdateParam::getIdentity() const
+{
+  if (m_entityType == tlv::pib::Identity)
+    return m_identity;
+  else
+    throw Error("UpdateParam::getIdentity: entityType must be Identity");
+}
+
+const PibPublicKey&
+UpdateParam::getPublicKey() const
+{
+  if (m_entityType == tlv::pib::PublicKey)
+    return m_key;
+  else
+    throw Error("UpdateParam::getPublicKey: entityType must be PublicKey");
+}
+
+const PibCertificate&
+UpdateParam::getCertificate() const
+{
+  if (m_entityType == tlv::pib::Certificate)
+    return m_certificate;
+  else
+    throw Error("UpdateParam::getCertificate: entityType must be Certificate");
+}
+
+template<bool T>
+size_t
+UpdateParam::wireEncode(EncodingImpl<T>& block) const
+{
+  size_t totalLength = 0;
+
+  totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::DefaultOpt, m_defaultOpt);
+
+  // Encode Entity
+  switch (m_entityType) {
+  case tlv::pib::Identity:
+    {
+      totalLength += m_identity.wireEncode(block);
+      break;
+    }
+  case tlv::pib::PublicKey:
+    {
+      totalLength += m_key.wireEncode(block);
+      break;
+    }
+  case tlv::pib::Certificate:
+    {
+      totalLength += m_certificate.wireEncode(block);
+      break;
+    }
+  case tlv::pib::User:
+    {
+      totalLength += m_user.wireEncode(block);
+      break;
+    }
+  default:
+    throw Error("UpdateParam::wireEncode: unsupported entity type: " +
+                boost::lexical_cast<std::string>(m_entityType));
+  }
+
+  totalLength += block.prependVarNumber(totalLength);
+  totalLength += block.prependVarNumber(tlv::pib::UpdateParam);
+
+  return totalLength;
+}
+
+template size_t
+UpdateParam::wireEncode<true>(EncodingImpl<true>& block) const;
+
+template size_t
+UpdateParam::wireEncode<false>(EncodingImpl<false>& block) const;
+
+const Block&
+UpdateParam::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
+UpdateParam::wireDecode(const Block& wire)
+{
+  if (!wire.hasWire()) {
+    throw Error("The supplied block does not contain wire format");
+  }
+
+  m_wire = wire;
+  m_wire.parse();
+
+  if (m_wire.type() != tlv::pib::UpdateParam)
+    throw Error("Unexpected TLV type when decoding UpdateParam");
+
+  Block::element_const_iterator it = m_wire.elements_begin();
+
+  // the first block must be Entity
+  if (it != m_wire.elements_end()) {
+    switch (it->type()) {
+    case tlv::pib::Identity:
+      {
+        m_entityType = tlv::pib::Identity;
+        m_identity.wireDecode(*it);
+        break;
+      }
+    case tlv::pib::PublicKey:
+      {
+        m_entityType = tlv::pib::PublicKey;
+        m_key.wireDecode(*it);
+        break;
+      }
+    case tlv::pib::Certificate:
+      {
+        m_entityType = tlv::pib::Certificate;
+        m_certificate.wireDecode(*it);
+        break;
+      }
+    case tlv::pib::User:
+      {
+        m_entityType = tlv::pib::User;
+        m_user.wireDecode(*it);
+        break;
+      }
+    default:
+      throw Error("The first sub-TLV of UpdateParam is not an entity type");
+    }
+
+    it++;
+  }
+  else
+    throw Error("UpdateParam requires the first sub-TLV to be an entity type");
+
+  // the second block must be DefaultOpt
+  if (it != m_wire.elements_end() && it->type() == tlv::pib::DefaultOpt) {
+    m_defaultOpt = static_cast<pib::DefaultOpt>(readNonNegativeInteger(*it));
+    it++;
+  }
+  else
+    throw Error("UpdateParam requires the second sub-TLV to be DefaultOpt");
+
+  if (it != m_wire.elements_end())
+    throw Error("UpdateParam must not contain more than two sub-TLVs");
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/encoding/update-param.hpp b/tools/pib/encoding/update-param.hpp
new file mode 100644
index 0000000..6a6e5ba
--- /dev/null
+++ b/tools/pib/encoding/update-param.hpp
@@ -0,0 +1,136 @@
+/* -*- 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.
+ */
+
+#ifndef NDN_PIB_UPDATE_PARAM_HPP
+#define NDN_PIB_UPDATE_PARAM_HPP
+
+#include "pib-common.hpp"
+#include "pib-encoding.hpp"
+#include <ndn-cxx/name.hpp>
+#include <ndn-cxx/security/identity-certificate.hpp>
+
+namespace ndn {
+namespace pib {
+
+/**
+ * @brief UpdateParam is the abstraction of PIB Update parameter.
+ *
+ * PibUpdateParam := PIB-UPDATE-PARAM-TYPE TLV-LENGTH
+ *                   (PibIdentity | PibPublicKey | PibCertificate)
+ *                   PibDefaultOpt
+ *
+ * @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Update-Parameters
+ */
+
+class UpdateParam : noncopyable
+{
+public:
+  class Error : public tlv::Error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : tlv::Error(what)
+    {
+    }
+  };
+
+  UpdateParam();
+
+  explicit
+  UpdateParam(const PibUser& user);
+
+  explicit
+  UpdateParam(const Name& identity, DefaultOpt defaultOpt = DEFAULT_OPT_NO);
+
+  UpdateParam(const Name& keyName, const PublicKey& key, DefaultOpt defaultOpt = DEFAULT_OPT_NO);
+
+  explicit
+  UpdateParam(const IdentityCertificate& certificate, DefaultOpt defaultOpt = DEFAULT_OPT_NO);
+
+  explicit
+  UpdateParam(const Block& wire);
+
+  tlv::pib::ParamType
+  getParamType() const
+  {
+    return tlv::pib::UpdateParam;
+  }
+
+  tlv::pib::EntityType
+  getEntityType() const
+  {
+    return m_entityType;
+  }
+
+  const PibUser&
+  getUser() const;
+
+  const PibIdentity&
+  getIdentity() const;
+
+  const PibPublicKey&
+  getPublicKey() const;
+
+  const PibCertificate&
+  getCertificate() const;
+
+  pib::DefaultOpt
+  getDefaultOpt() const
+  {
+    return m_defaultOpt;
+  }
+
+  /// @brief Encode to a wire format or estimate wire format
+  template<bool T>
+  size_t
+  wireEncode(EncodingImpl<T>& block) const;
+
+  /// @brief Encode to a wire format
+  const Block&
+  wireEncode() const;
+
+  /**
+   * @brief Decode GetParam from a wire encoded block
+   *
+   * @throws Error if decoding fails
+   */
+  void
+  wireDecode(const Block& wire);
+
+public:
+  static const std::string VERB;
+
+private:
+  tlv::pib::EntityType m_entityType;
+  PibUser m_user;
+  PibIdentity m_identity;
+  PibPublicKey m_key;
+  PibCertificate m_certificate;
+  pib::DefaultOpt m_defaultOpt;
+
+  mutable Block m_wire;
+};
+
+} // namespace pib
+} // namespace ndn
+
+#endif // NDN_PIB_UPDATE_PARAM_HPP
