/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (C) 2013 Regents of the University of California.
 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
 * See COPYING for copyright and distribution information.
 */

#include <iostream>
#include <time.h>
#include <sys/time.h>
#include <sstream>
#include <stdexcept>
#include <ndn-cpp/data.hpp>
#include <ndn-cpp/sha256-with-rsa-signature.hpp>
#include <ndn-cpp/key-locator.hpp>
#include <ndn-cpp/security/key-chain.hpp>
#include <ndn-cpp/security/identity/memory-identity-storage.hpp>
#include <ndn-cpp/security/identity/memory-private-key-storage.hpp>
#include <ndn-cpp/security/policy/self-verify-policy-manager.hpp>
// Hack: Hook directly into non-API functions.
#include "../src/c/encoding/binary-xml-decoder.h"
#include "../src/c/data.h"
#include "../src/c/encoding/binary-xml-data.h"
#include "../src/c/util/crypto.h"

using namespace std;
using namespace ndn;

static double
getNowSeconds()
{
  struct timeval t;
  gettimeofday(&t, 0);
  return t.tv_sec + t.tv_usec / 1000000.0;
}

static bool
verifyRsaSignature
  (uint8_t* signedPortion, size_t signedPortionLength, uint8_t* signatureBits, size_t signatureBitsLength, 
   uint8_t* publicKeyDer, size_t publicKeyDerLength)
{
  // Set signedPortionDigest to the digest of the signed portion of the wire encoding.
  uint8_t signedPortionDigest[SHA256_DIGEST_LENGTH];
  ndn_digestSha256(signedPortion, signedPortionLength, signedPortionDigest);
  
  // Verify the signedPortionDigest.
  // Use a temporary pointer since d2i updates it.
  const uint8_t *derPointer = publicKeyDer;
  RSA *rsaPublicKey = d2i_RSA_PUBKEY(NULL, &derPointer, publicKeyDerLength);
  if (!rsaPublicKey) {
    // Don't expect this to happen.
    cout << "Error decoding public key in d2i_RSAPublicKey" << endl;
    return 0;
  }
  int success = RSA_verify
    (NID_sha256, signedPortionDigest, sizeof(signedPortionDigest), signatureBits, signatureBitsLength, rsaPublicKey);
  // Free the public key before checking for success.
  RSA_free(rsaPublicKey);
  
  // RSA_verify returns 1 for a valid signature.
  return (success == 1);
}

static uint8_t DEFAULT_PUBLIC_KEY_DER[] = {
0x30, 0x81, 0x9F, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81,
0x8D, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xE1, 0x7D, 0x30, 0xA7, 0xD8, 0x28, 0xAB, 0x1B, 0x84, 0x0B, 0x17,
0x54, 0x2D, 0xCA, 0xF6, 0x20, 0x7A, 0xFD, 0x22, 0x1E, 0x08, 0x6B, 0x2A, 0x60, 0xD1, 0x6C, 0xB7, 0xF5, 0x44, 0x48, 0xBA,
0x9F, 0x3F, 0x08, 0xBC, 0xD0, 0x99, 0xDB, 0x21, 0xDD, 0x16, 0x2A, 0x77, 0x9E, 0x61, 0xAA, 0x89, 0xEE, 0xE5, 0x54, 0xD3,
0xA4, 0x7D, 0xE2, 0x30, 0xBC, 0x7A, 0xC5, 0x90, 0xD5, 0x24, 0x06, 0x7C, 0x38, 0x98, 0xBB, 0xA6, 0xF5, 0xDC, 0x43, 0x60,
0xB8, 0x45, 0xED, 0xA4, 0x8C, 0xBD, 0x9C, 0xF1, 0x26, 0xA7, 0x23, 0x44, 0x5F, 0x0E, 0x19, 0x52, 0xD7, 0x32, 0x5A, 0x75,
0xFA, 0xF5, 0x56, 0x14, 0x4F, 0x9A, 0x98, 0xAF, 0x71, 0x86, 0xB0, 0x27, 0x86, 0x85, 0xB8, 0xE2, 0xC0, 0x8B, 0xEA, 0x87,
0x17, 0x1B, 0x4D, 0xEE, 0x58, 0x5C, 0x18, 0x28, 0x29, 0x5B, 0x53, 0x95, 0xEB, 0x4A, 0x17, 0x77, 0x9F, 0x02, 0x03, 0x01,
0x00, 0x01  
};

static uint8_t DEFAULT_PRIVATE_KEY_DER[] = {
0x30, 0x82, 0x02, 0x5d, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xe1, 0x7d, 0x30, 0xa7, 0xd8, 0x28, 0xab, 0x1b, 0x84,
0x0b, 0x17, 0x54, 0x2d, 0xca, 0xf6, 0x20, 0x7a, 0xfd, 0x22, 0x1e, 0x08, 0x6b, 0x2a, 0x60, 0xd1, 0x6c, 0xb7, 0xf5, 0x44,
0x48, 0xba, 0x9f, 0x3f, 0x08, 0xbc, 0xd0, 0x99, 0xdb, 0x21, 0xdd, 0x16, 0x2a, 0x77, 0x9e, 0x61, 0xaa, 0x89, 0xee, 0xe5,
0x54, 0xd3, 0xa4, 0x7d, 0xe2, 0x30, 0xbc, 0x7a, 0xc5, 0x90, 0xd5, 0x24, 0x06, 0x7c, 0x38, 0x98, 0xbb, 0xa6, 0xf5, 0xdc,
0x43, 0x60, 0xb8, 0x45, 0xed, 0xa4, 0x8c, 0xbd, 0x9c, 0xf1, 0x26, 0xa7, 0x23, 0x44, 0x5f, 0x0e, 0x19, 0x52, 0xd7, 0x32,
0x5a, 0x75, 0xfa, 0xf5, 0x56, 0x14, 0x4f, 0x9a, 0x98, 0xaf, 0x71, 0x86, 0xb0, 0x27, 0x86, 0x85, 0xb8, 0xe2, 0xc0, 0x8b,
0xea, 0x87, 0x17, 0x1b, 0x4d, 0xee, 0x58, 0x5c, 0x18, 0x28, 0x29, 0x5b, 0x53, 0x95, 0xeb, 0x4a, 0x17, 0x77, 0x9f, 0x02,
0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x80, 0x1a, 0x4b, 0xfa, 0x4f, 0xa8, 0xc2, 0xdd, 0x69, 0xa1, 0x15, 0x96, 0x0b, 0xe8,
0x27, 0x42, 0x5a, 0xf9, 0x5c, 0xea, 0x0c, 0xac, 0x98, 0xaa, 0xe1, 0x8d, 0xaa, 0xeb, 0x2d, 0x3c, 0x60, 0x6a, 0xfb, 0x45,
0x63, 0xa4, 0x79, 0x83, 0x67, 0xed, 0xe4, 0x15, 0xc0, 0xb0, 0x20, 0x95, 0x6d, 0x49, 0x16, 0xc6, 0x42, 0x05, 0x48, 0xaa,
0xb1, 0xa5, 0x53, 0x65, 0xd2, 0x02, 0x99, 0x08, 0xd1, 0x84, 0xcc, 0xf0, 0xcd, 0xea, 0x61, 0xc9, 0x39, 0x02, 0x3f, 0x87,
0x4a, 0xe5, 0xc4, 0xd2, 0x07, 0x02, 0xe1, 0x9f, 0xa0, 0x06, 0xc2, 0xcc, 0x02, 0xe7, 0xaa, 0x6c, 0x99, 0x8a, 0xf8, 0x49,
0x00, 0xf1, 0xa2, 0x8c, 0x0c, 0x8a, 0xb9, 0x4f, 0x6d, 0x73, 0x3b, 0x2c, 0xb7, 0x9f, 0x8a, 0xa6, 0x7f, 0x9b, 0x9f, 0xb7,
0xa1, 0xcc, 0x74, 0x2e, 0x8f, 0xb8, 0xb0, 0x26, 0x89, 0xd2, 0xe5, 0x66, 0xe8, 0x8e, 0xa1, 0x02, 0x41, 0x00, 0xfc, 0xe7,
0x52, 0xbc, 0x4e, 0x95, 0xb6, 0x1a, 0xb4, 0x62, 0xcc, 0xd8, 0x06, 0xe1, 0xdc, 0x7a, 0xa2, 0xb6, 0x71, 0x01, 0xaa, 0x27,
0xfc, 0x99, 0xe5, 0xf2, 0x54, 0xbb, 0xb2, 0x85, 0xe1, 0x96, 0x54, 0x2d, 0xcb, 0xba, 0x86, 0xfa, 0x80, 0xdf, 0xcf, 0x39,
0xe6, 0x74, 0xcb, 0x22, 0xce, 0x70, 0xaa, 0x10, 0x00, 0x73, 0x1d, 0x45, 0x0a, 0x39, 0x51, 0x84, 0xf5, 0x15, 0x8f, 0x37,
0x76, 0x91, 0x02, 0x41, 0x00, 0xe4, 0x3f, 0xf0, 0xf4, 0xde, 0x79, 0x77, 0x48, 0x9b, 0x9c, 0x28, 0x45, 0x26, 0x57, 0x3c,
0x71, 0x40, 0x28, 0x6a, 0xa1, 0xfe, 0xc3, 0xe5, 0x37, 0xa1, 0x03, 0xf6, 0x2d, 0xbe, 0x80, 0x64, 0x72, 0x69, 0x2e, 0x9b,
0x4d, 0xe3, 0x2e, 0x1b, 0xfe, 0xe7, 0xf9, 0x77, 0x8c, 0x18, 0x53, 0x9f, 0xe2, 0xfe, 0x00, 0xbb, 0x49, 0x20, 0x47, 0xdf,
0x01, 0x61, 0x87, 0xd6, 0xe3, 0x44, 0xb5, 0x03, 0x2f, 0x02, 0x40, 0x54, 0xec, 0x7c, 0xbc, 0xdd, 0x0a, 0xaa, 0xde, 0xe6,
0xc9, 0xf2, 0x8d, 0x6c, 0x2a, 0x35, 0xf6, 0x3c, 0x63, 0x55, 0x29, 0x40, 0xf1, 0x32, 0x82, 0x9f, 0x53, 0xb3, 0x9e, 0x5f,
0xc1, 0x53, 0x52, 0x3e, 0xac, 0x2e, 0x28, 0x51, 0xa1, 0x16, 0xdb, 0x90, 0xe3, 0x99, 0x7e, 0x88, 0xa4, 0x04, 0x7c, 0x92,
0xae, 0xd2, 0xe7, 0xd4, 0xe1, 0x55, 0x20, 0x90, 0x3e, 0x3c, 0x6a, 0x63, 0xf0, 0x34, 0xf1, 0x02, 0x41, 0x00, 0x84, 0x5a,
0x17, 0x6c, 0xc6, 0x3c, 0x84, 0xd0, 0x93, 0x7a, 0xff, 0x56, 0xe9, 0x9e, 0x98, 0x2b, 0xcb, 0x5a, 0x24, 0x4a, 0xff, 0x21,
0xb4, 0x9e, 0x87, 0x3d, 0x76, 0xd8, 0x9b, 0xa8, 0x73, 0x96, 0x6c, 0x2b, 0x5c, 0x5e, 0xd3, 0xa6, 0xff, 0x10, 0xd6, 0x8e,
0xaf, 0xa5, 0x8a, 0xcd, 0xa2, 0xde, 0xcb, 0x0e, 0xbd, 0x8a, 0xef, 0xae, 0xfd, 0x3f, 0x1d, 0xc0, 0xd8, 0xf8, 0x3b, 0xf5,
0x02, 0x7d, 0x02, 0x41, 0x00, 0x8b, 0x26, 0xd3, 0x2c, 0x7d, 0x28, 0x38, 0x92, 0xf1, 0xbf, 0x15, 0x16, 0x39, 0x50, 0xc8,
0x6d, 0x32, 0xec, 0x28, 0xf2, 0x8b, 0xd8, 0x70, 0xc5, 0xed, 0xe1, 0x7b, 0xff, 0x2d, 0x66, 0x8c, 0x86, 0x77, 0x43, 0xeb,
0xb6, 0xf6, 0x50, 0x66, 0xb0, 0x40, 0x24, 0x6a, 0xaf, 0x98, 0x21, 0x45, 0x30, 0x01, 0x59, 0xd0, 0xc3, 0xfc, 0x7b, 0xae,
0x30, 0x18, 0xeb, 0x90, 0xfb, 0x17, 0xd3, 0xce, 0xb5
};

/**
 * Loop to encode a data packet nIterations times using C++.
 * @param nIterations The number of iterations.
 * @param useComplex If true, use a large name, large content and all fields.  If false, use a small name, small content
 * and only required fields.
 * @param useCrypto If true, sign the data packet.  If false, use a blank signature.
 * @param encoding Set this to the wire encoding.
 * @return The number of seconds for all iterations.
 */
static double
benchmarkEncodeDataSecondsCpp(int nIterations, bool useComplex, bool useCrypto, Blob& encoding)
{
  Name name;
  Blob content;
  if (useComplex) {
    // Use a large name and content.
    name = Name("/ndn/ucla.edu/apps/lwndn-test/numbers.txt/%FD%05%05%E8%0C%CE%1D/%00"); 
    
    ostringstream contentStream;
    int count = 1;
    contentStream << (count++);
    while (contentStream.str().length() < 1170)
      contentStream << " " << (count++);
    content = Blob((uint8_t*)contentStream.str().c_str(), contentStream.str().length());
  }
  else {
    // Use a small name and content.
    name = Name("/test");
    content = Blob((uint8_t*)"abc", 3);
  }
  Blob finalBlockId((uint8_t*)"\x00", 1);
  
  // Initialize the KeyChain storage in case useCrypto is true.
  ptr_lib::shared_ptr<MemoryIdentityStorage> identityStorage(new MemoryIdentityStorage());
  ptr_lib::shared_ptr<MemoryPrivateKeyStorage> privateKeyStorage(new MemoryPrivateKeyStorage());
  KeyChain keyChain
    (ptr_lib::make_shared<IdentityManager>(identityStorage, privateKeyStorage), 
     ptr_lib::make_shared<SelfVerifyPolicyManager>(identityStorage.get()));
  Name keyName("/testname/DSK-123");
  Name certificateName = keyName.getSubName(0, keyName.size() - 1).append("KEY").append
    (keyName.get(keyName.size() - 1)).append("ID-CERT").append("0");
  privateKeyStorage->setKeyPairForKeyName
    (keyName, DEFAULT_PUBLIC_KEY_DER, sizeof(DEFAULT_PUBLIC_KEY_DER), DEFAULT_PRIVATE_KEY_DER, sizeof(DEFAULT_PRIVATE_KEY_DER));
  
  // Set up publisherPublicKeyDigest and signatureBits in case useCrypto is false.
  uint8_t publisherPublicKeyDigestArray[32];
  memset(publisherPublicKeyDigestArray, 0, sizeof(publisherPublicKeyDigestArray));
  Blob publisherPublicKeyDigest(publisherPublicKeyDigestArray, sizeof(publisherPublicKeyDigestArray));
  uint8_t signatureBitsArray[128];
  memset(signatureBitsArray, 0, sizeof(signatureBitsArray));
  Blob signatureBits(signatureBitsArray, sizeof(signatureBitsArray));

  double start = getNowSeconds();
  for (int i = 0; i < nIterations; ++i) {
    Data data(name);
    data.setContent(content);
    if (useComplex) {
      data.getMetaInfo().setTimestampMilliseconds(1.3e+12);
      data.getMetaInfo().setFreshnessSeconds(1000);
      data.getMetaInfo().setFinalBlockID(finalBlockId);
    }

    if (useCrypto)
      // This sets the signature fields.
      keyChain.sign(data, certificateName);
    else {
      // Imitate IdentityManager::signByCertificate to set up the signature fields, but don't sign.
      KeyLocator keyLocator;    
      keyLocator.setType(ndn_KeyLocatorType_KEYNAME);
      keyLocator.setKeyName(certificateName);
      keyLocator.setKeyNameType((ndn_KeyNameType)-1);
      Sha256WithRsaSignature* sha256Signature = (Sha256WithRsaSignature*)data.getSignature();
      sha256Signature->setKeyLocator(keyLocator);
      sha256Signature->getPublisherPublicKeyDigest().setPublisherPublicKeyDigest(publisherPublicKeyDigest);
      sha256Signature->setSignature(signatureBits);
    }

    encoding = data.wireEncode();
  }
  double finish = getNowSeconds();
    
  return finish - start;
}

static void 
onVerified(const ptr_lib::shared_ptr<Data>& data)
{
  // Do nothing since we expect it to verify.
}

static void 
onVerifyFailed(const ptr_lib::shared_ptr<Data>& data)
{
  cout << "Signature verification: FAILED" << endl;
}

/**
 * Loop to decode a data packet nIterations times using C++.
 * @param nIterations The number of iterations.
 * @param useCrypto If true, verify the signature.  If false, don't verify.
 * @param encoding The wire encoding to decode.
 * @return The number of seconds for all iterations.
 */
static double 
benchmarkDecodeDataSecondsCpp(int nIterations, bool useCrypto, const Blob& encoding)
{
  // Initialize the KeyChain storage in case useCrypto is true.
  ptr_lib::shared_ptr<MemoryIdentityStorage> identityStorage(new MemoryIdentityStorage());
  ptr_lib::shared_ptr<MemoryPrivateKeyStorage> privateKeyStorage(new MemoryPrivateKeyStorage());
  KeyChain keyChain
    (ptr_lib::make_shared<IdentityManager>(identityStorage, privateKeyStorage), 
     ptr_lib::make_shared<SelfVerifyPolicyManager>(identityStorage.get()));
  Name keyName("/testname/DSK-123");
  identityStorage->addKey(keyName, KEY_TYPE_RSA, Blob(DEFAULT_PUBLIC_KEY_DER, sizeof(DEFAULT_PUBLIC_KEY_DER)));

  size_t nameSize = 0;
  double start = getNowSeconds();
  for (int i = 0; i < nIterations; ++i) {
    ptr_lib::shared_ptr<Data> data(new Data());
    data->wireDecode(*encoding);
    
    if (useCrypto)
      keyChain.verifyData(data, onVerified, onVerifyFailed);
  }
  double finish = getNowSeconds();
 
  return finish - start;
}

/**
 * Loop to encode a data packet nIterations times using C.
 * @param nIterations The number of iterations.
 * @param useComplex If true, use a large name, large content and all fields.  If false, use a small name, small content
 * and only required fields.
 * @param useCrypto If true, sign the data packet.  If false, use a blank signature.
 * @param encoding Output buffer for the wire encoding.
 * @param maxEncodingLength The size of the encoding buffer.
 * @param encodingLength Return the number of output bytes in encoding.
 * @return The number of seconds for all iterations.
 */
static double 
benchmarkEncodeDataSecondsC
  (int nIterations, bool useComplex, bool useCrypto, uint8_t* encoding, size_t maxEncodingLength, size_t *encodingLength)
{
  struct ndn_Blob finalBlockId;
  ndn_Blob_initialize(&finalBlockId, (uint8_t*)"\x00", 1);

  struct ndn_NameComponent nameComponents[20];
  struct ndn_Name name;
  ndn_Name_initialize(&name, nameComponents, sizeof(nameComponents) / sizeof(nameComponents[0]));
  Blob contentBlob;
  struct ndn_Blob content;
  if (useComplex) {
    // Use a large name and content.
    ndn_Name_appendString(&name, (char*)"ndn");
    ndn_Name_appendString(&name, (char*)"ucla.edu");
    ndn_Name_appendString(&name, (char*)"apps");
    ndn_Name_appendString(&name, (char*)"lwndn-test");
    ndn_Name_appendString(&name, (char*)"numbers.txt");
    ndn_Name_appendString(&name, (char*)"\xFD\x05\x05\xE8\x0C\xCE\x1D");
    ndn_Name_appendBlob(&name, &finalBlockId);
    
    ostringstream contentStream;
    int count = 1;
    contentStream << (count++);
    while (contentStream.str().length() < 1170)
      contentStream << " " << (count++);
    contentBlob = Blob((uint8_t*)contentStream.str().c_str(), contentStream.str().length());
  }
  else {
    // Use a small name and content.
    ndn_Name_appendString(&name, (char*)"test");
    contentBlob = Blob((uint8_t*)"abc", 3);
  }
  ndn_Blob_initialize(&content, (uint8_t*)contentBlob.buf(), contentBlob.size());
  
  struct ndn_NameComponent certificateNameComponents[20];
  struct ndn_Name certificateName;
  ndn_Name_initialize(&certificateName, certificateNameComponents, sizeof(certificateNameComponents) / sizeof(certificateNameComponents[0]));
  ndn_Name_appendString(&certificateName, (char*)"testname");
  ndn_Name_appendString(&certificateName, (char*)"KEY");
  ndn_Name_appendString(&certificateName, (char*)"DSK-123");
  ndn_Name_appendString(&certificateName, (char*)"ID-CERT");
  ndn_Name_appendString(&certificateName, (char*)"0");
  
  // Set up publisherPublicKeyDigest and signatureBits in case useCrypto is false.
  uint8_t* publicKeyDer = DEFAULT_PUBLIC_KEY_DER;
  size_t publicKeyDerLength = sizeof(DEFAULT_PUBLIC_KEY_DER);
  uint8_t publisherPublicKeyDigestArray[SHA256_DIGEST_LENGTH];
  ndn_digestSha256(publicKeyDer, publicKeyDerLength, publisherPublicKeyDigestArray);
  struct ndn_Blob publisherPublicKeyDigest;
  ndn_Blob_initialize(&publisherPublicKeyDigest, publisherPublicKeyDigestArray, sizeof(publisherPublicKeyDigestArray));
  uint8_t signatureBitsArray[128];
  memset(signatureBitsArray, 0, sizeof(signatureBitsArray));
  
  // Set up the private key now in case useCrypto is true.
  // Use a temporary pointer since d2i updates it.
  const uint8_t *privateKeyDerPointer = DEFAULT_PRIVATE_KEY_DER;
  RSA *privateKey = d2i_RSAPrivateKey(NULL, &privateKeyDerPointer, sizeof(DEFAULT_PRIVATE_KEY_DER));
  if (!privateKey) {
    // Don't expect this to happen.
    cout << "Error decoding private key DER" << endl;
    return 0;
  }
  
  double start = getNowSeconds();
  for (int i = 0; i < nIterations; ++i) {
    struct ndn_Data data;
    ndn_Data_initialize(&data, name.components, name.maxComponents, certificateName.components, certificateName.maxComponents);
    
    data.name = name;
    data.content = content;
    if (useComplex) {
      data.metaInfo.timestampMilliseconds = 1.3e+12;
      data.metaInfo.freshnessSeconds = 1000;
      ndn_NameComponent_initialize(&data.metaInfo.finalBlockID, finalBlockId.value, finalBlockId.length);
    }

    struct ndn_DynamicUInt8Array output;
    struct ndn_BinaryXmlEncoder encoder;
    size_t signedPortionBeginOffset, signedPortionEndOffset;
    ndn_Error error;

    data.signature.keyLocator.type = ndn_KeyLocatorType_KEYNAME;
    data.signature.keyLocator.keyName = certificateName;
    data.signature.keyLocator.keyNameType = (ndn_KeyNameType)-1;
    data.signature.publisherPublicKeyDigest.publisherPublicKeyDigest = publisherPublicKeyDigest;
    if (useCrypto) {
      // Encode once to get the signed portion.
      ndn_DynamicUInt8Array_initialize(&output, encoding, maxEncodingLength, 0);
      ndn_BinaryXmlEncoder_initialize(&encoder, &output);    
      if ((error = ndn_encodeBinaryXmlData(&data, &signedPortionBeginOffset, &signedPortionEndOffset, &encoder))) {
        cout << "Error in ndn_encodeBinaryXmlData: " << ndn_getErrorString(error) << endl;
        return 0;
      }
      
      // Imitate MemoryPrivateKeyStorage::sign.
      uint8_t digest[SHA256_DIGEST_LENGTH];
      ndn_digestSha256(encoding + signedPortionBeginOffset, signedPortionEndOffset - signedPortionBeginOffset, digest);
      unsigned int signatureBitsLength;
      if (!RSA_sign(NID_sha256, digest, sizeof(digest), signatureBitsArray, &signatureBitsLength, privateKey)) {
        // Don't expect this to happen.
        cout << "Error in RSA_sign" << endl;
        return 0;
      }    
      
      ndn_Blob_initialize(&data.signature.signature, signatureBitsArray, signatureBitsLength);
    }
    else
      // Set up the signature, but don't sign.
      ndn_Blob_initialize(&data.signature.signature, signatureBitsArray, sizeof(signatureBitsArray));

    // Assume the encoding buffer is big enough so we don't need to dynamically reallocate.
    ndn_DynamicUInt8Array_initialize(&output, encoding, maxEncodingLength, 0);
    ndn_BinaryXmlEncoder_initialize(&encoder, &output);    
    if ((error = ndn_encodeBinaryXmlData(&data, &signedPortionBeginOffset, &signedPortionEndOffset, &encoder))) {
      cout << "Error in ndn_encodeBinaryXmlData: " << ndn_getErrorString(error) << endl;
      return 0;
    }    
    *encodingLength = encoder.offset;
  }
  double finish = getNowSeconds();
  
  if (privateKey)
    RSA_free(privateKey);
  
  return finish - start;
}

/**
 * Loop to decode a data packet nIterations times using C.
 * @param nIterations The number of iterations.
 * @param useCrypto If true, verify the signature.  If false, don't verify.
 * @param encoding The buffer with wire encoding to decode.
 * @param encodingLength The number of bytes in the encoding.
 * @return The number of seconds for all iterations.
 */
static double 
benchmarkDecodeDataSecondsC(int nIterations, bool useCrypto, uint8_t* encoding, size_t encodingLength)
{
  double start = getNowSeconds();
  for (int i = 0; i < nIterations; ++i) {
    struct ndn_NameComponent nameComponents[100];
    struct ndn_NameComponent keyNameComponents[100];
    struct ndn_Data data;
    ndn_Data_initialize
      (&data, nameComponents, sizeof(nameComponents) / sizeof(nameComponents[0]), 
       keyNameComponents, sizeof(keyNameComponents) / sizeof(keyNameComponents[0]));

    ndn_BinaryXmlDecoder decoder;
    ndn_BinaryXmlDecoder_initialize(&decoder, encoding, encodingLength);  
    size_t signedPortionBeginOffset, signedPortionEndOffset;
    ndn_Error error;
    if ((error = ndn_decodeBinaryXmlData(&data, &signedPortionBeginOffset, &signedPortionEndOffset, &decoder))) {
      cout << "Error in ndn_decodeBinaryXmlData: " << ndn_getErrorString(error) << endl;
      return 0;
    }
    
    if (useCrypto) {
      if (!verifyRsaSignature
          (encoding + signedPortionBeginOffset, signedPortionEndOffset - signedPortionBeginOffset,
           data.signature.signature.value, data.signature.signature.length,
           DEFAULT_PUBLIC_KEY_DER, sizeof(DEFAULT_PUBLIC_KEY_DER)))
        cout << "Signature verification: FAILED" << endl;
    }
  }
  double finish = getNowSeconds();
 
  return finish - start;
}

/**
 * Call benchmarkEncodeDataSecondsCpp and benchmarkDecodeDataSecondsCpp with appropriate nInterations.  Print the 
 * results to cout.
 * @param useComplex See benchmarkEncodeDataSecondsCpp.
 * @param useCrypto See benchmarkEncodeDataSecondsCpp and benchmarkDecodeDataSecondsCpp.
 */
static void
benchmarkEncodeDecodeDataCpp(bool useComplex, bool useCrypto)
{
  Blob encoding;
  {
    int nIterations = useCrypto ? 20000 : 2000000;
    double duration = benchmarkEncodeDataSecondsCpp(nIterations, useComplex, useCrypto, encoding);
    cout << "Encode " << (useComplex ? "complex" : "simple ") << " data C++: Crypto? " << (useCrypto ? "yes" : "no ") 
         << ", Duration sec, Hz: " << duration << ", " << (nIterations / duration) << endl;  
  }
  {
    int nIterations = useCrypto ? 100000 : 2000000;
    double duration = benchmarkDecodeDataSecondsCpp(nIterations, useCrypto, encoding);
    cout << "Decode " << (useComplex ? "complex" : "simple ") << " data C++: Crypto? " << (useCrypto ? "yes" : "no ") 
         << ", Duration sec, Hz: " << duration << ", " << (nIterations / duration) << endl;  
  }
}

/**
 * Call benchmarkEncodeDataSecondsC and benchmarkDecodeDataSecondsC with appropriate nInterations.  Print the 
 * results to cout.
 * @param useComplex See benchmarkEncodeDataSecondsC.
 * @param useCrypto See benchmarkEncodeDataSecondsC and benchmarkDecodeDataSecondsC.
 */
static void
benchmarkEncodeDecodeDataC(bool useComplex, bool useCrypto)
{
  uint8_t encoding[1500];
  size_t encodingLength;
  {
    int nIterations = useCrypto ? 20000 : 10000000;
    double duration = benchmarkEncodeDataSecondsC(nIterations, useComplex, useCrypto, encoding, sizeof(encoding), &encodingLength);
    cout << "Encode " << (useComplex ? "complex" : "simple ") << " data C:   Crypto? " << (useCrypto ? "yes" : "no ") 
         << ", Duration sec, Hz: " << duration << ", " << (nIterations / duration) << endl;  
  }
  {
    int nIterations = useCrypto ? 150000 : 15000000;
    double duration = benchmarkDecodeDataSecondsC(nIterations, useCrypto, encoding, encodingLength);
    cout << "Decode " << (useComplex ? "complex" : "simple ") << " data C:   Crypto? " << (useCrypto ? "yes" : "no ") 
         << ", Duration sec, Hz: " << duration << ", " << (nIterations / duration) << endl;  
  }
}

int 
main(int argc, char** argv)
{
  try {
    benchmarkEncodeDecodeDataCpp(false, false);
    benchmarkEncodeDecodeDataCpp(true, false);
    benchmarkEncodeDecodeDataCpp(false, true);
    benchmarkEncodeDecodeDataCpp(true, true);
    
    benchmarkEncodeDecodeDataC(false, false);
    benchmarkEncodeDecodeDataC(true, false);
    benchmarkEncodeDecodeDataC(false, true);
    benchmarkEncodeDecodeDataC(true, true);
  } catch (std::exception& e) {
    cout << "exception: " << e.what() << endl;
  }
  return 0;
}
