If Name.getContentDigestValue() returns a content digest, then use Sha256 to digest the content and dump an error if not equal.
diff --git a/js/ndnProtocol.xpi b/js/ndnProtocol.xpi
index 834c170..ecf43f8 100644
--- a/js/ndnProtocol.xpi
+++ b/js/ndnProtocol.xpi
Binary files differ
diff --git a/js/ndnProtocol/components/ndnProtocolService.js b/js/ndnProtocol/components/ndnProtocolService.js
index f3a8909..290f91a 100644
--- a/js/ndnProtocol/components/ndnProtocolService.js
+++ b/js/ndnProtocol/components/ndnProtocolService.js
@@ -111,6 +111,7 @@
     

     this.firstReceivedSegmentNumber = null;

     this.firstReceivedContentObject = null;

+    this.contentSha256 = null;

 }

 

 ContentClosure.prototype.upcall = function(kind, upcallInfo) {

@@ -151,8 +152,7 @@
         var contentUriSpec;

         if (!this.uriEndsWithSegmentNumber && endsWithSegmentNumber(contentObject.name)) {

             var nameWithoutSegmentNumber = new Name

-                (contentObject.name.components.slice

-                 (0, contentObject.name.components.length - 1));

+                (contentObject.name.components.slice(0, contentObject.name.components.length - 1));

             contentUriSpec = "ndn:" + nameWithoutSegmentNumber.to_uri();

         }

         else

@@ -165,9 +165,15 @@
         var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);

         this.contentListener.onStart(contentTypeEtc.contentType, contentTypeEtc.contentCharset, 

             ioService.newURI(contentUriSpec, this.uriOriginCharset, null));

+            

+        if (contentObject.name.getContentDigestValue() != null)

+            // We need to compute the content digest.

+            this.contentSha256 = new Sha256();

     }

 

     this.contentListener.onReceivedContent(DataUtils.toString(contentObject.content));

+    if (this.contentSha256 != null)

+        this.contentSha256.update(contentObject.content);

     

     // Check for the special case if the saved content is for the next segment that we need.

     if (this.firstReceivedContentObject != null && 

@@ -179,6 +185,8 @@
         this.firstReceivedContentObject = null;

         

         this.contentListener.onReceivedContent(DataUtils.toString(contentObject.content));        

+        if (this.contentSha256 != null)

+            this.contentSha256.update(contentObject.content);

     }

 

     var finalSegmentNumber = null;

@@ -199,9 +207,17 @@
         components.push(nextSegmentNumber);

         this.ndn.expressInterest(new Name(components), this);

     }

-    else

+    else {

         // Finished.

-        this.contentListener.onStop(); 

+        this.contentListener.onStop();

+        if (this.contentSha256 != null) {

+            var nameContentDigest = contentObject.name.getContentDigestValue();

+            if (nameContentDigest != null &&

+                !DataUtils.arraysEqual(nameContentDigest, this.contentSha256.finalize()))

+                // TODO: How to show the user an error for invalid digest?

+                dump("Content does not match digest in name " + contentObject.name.to_uri());

+        }

+    }

         

     return Closure.RESULT_OK;

 };

@@ -278,4 +294,4 @@
         return "";

     else

         return "?" + terms.join('&');

-}
\ No newline at end of file
+}

diff --git a/js/ndnProtocol/modules/ndn-js-header.txt b/js/ndnProtocol/modules/ndn-js-header.txt
index c4703d4..acadf90 100644
--- a/js/ndnProtocol/modules/ndn-js-header.txt
+++ b/js/ndnProtocol/modules/ndn-js-header.txt
@@ -5,8 +5,8 @@
  * See COPYING for copyright and distribution information.
  */
 
-var EXPORTED_SYMBOLS = ["NDN", "Closure", "Name", "Interest", "ContentObject",
-      "DataUtils", "MimeTypes", "XpcomTransport"];
+var EXPORTED_SYMBOLS = ["Closure", "ContentObject", "DataUtils", "Interest", "MimeTypes", "NDN", 
+      "Name", "Sha256", "XpcomTransport"];
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/NetUtil.jsm");
diff --git a/js/ndnProtocol/modules/ndn-js.jsm b/js/ndnProtocol/modules/ndn-js.jsm
index 928467f..73ca64a 100644
--- a/js/ndnProtocol/modules/ndn-js.jsm
+++ b/js/ndnProtocol/modules/ndn-js.jsm
@@ -5,8 +5,8 @@
  * See COPYING for copyright and distribution information.
  */
 
-var EXPORTED_SYMBOLS = ["NDN", "Closure", "Name", "Interest", "ContentObject",
-      "DataUtils", "MimeTypes", "XpcomTransport"];
+var EXPORTED_SYMBOLS = ["Closure", "ContentObject", "DataUtils", "Interest", "MimeTypes", "NDN", 
+      "Name", "Sha256", "XpcomTransport"];
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/NetUtil.jsm");
@@ -96,7 +96,7 @@
  * This class represents the top-level object for communicating with an NDN host.
  */
 
-var LOG = 3;
+var LOG = 0;
 
 /**
  * settings is an associative array with the following defaults:
@@ -729,6 +729,32 @@
     return -1;
 }
 
+/*
+ * Find the last component in name that has a ContentDigest and return the digest value as Uint8Array, 
+ *   or null if not found.
+ * A ContentDigest component is Name.ContentDigestPrefix + 32 bytes + Name.ContentDigestSuffix.
+ */
+Name.prototype.getContentDigestValue = function() {
+    var digestComponentLength = Name.ContentDigestPrefix.length + 32 + Name.ContentDigestSuffix.length; 
+    for (var i = this.components.length - 1; i >= 0; --i) {
+        // Check for the correct length and equal ContentDigestPrefix and ContentDigestSuffix.
+        if (this.components[i].length == digestComponentLength &&
+            DataUtils.arraysEqual(this.components[i].subarray(0, Name.ContentDigestPrefix.length), 
+                                  Name.ContentDigestPrefix) &&
+            DataUtils.arraysEqual(this.components[i].subarray
+               (this.components[i].length - Name.ContentDigestSuffix.length, this.components[i].length),
+                                  Name.ContentDigestSuffix))
+           return this.components[i].subarray
+               (Name.ContentDigestPrefix.length, Name.ContentDigestPrefix.length + 32);
+    }
+    
+    return null;
+}
+
+// Meta GUID "%C1.M.G%C1" + ContentDigest with a 32 byte BLOB. 
+Name.ContentDigestPrefix = new Uint8Array([0xc1, 0x2e, 0x4d, 0x2e, 0x47, 0xc1, 0x01, 0xaa, 0x02, 0x85]);
+Name.ContentDigestSuffix = new Uint8Array([0x00]);
+
 /**
  * Return component as an escaped string according to "CCNx URI Scheme".
  * We can't use encodeURIComponent because that doesn't encode all the characters we want to.
@@ -961,26 +987,6 @@
 	this.digestAlgorithm = _digestAlgorithm//String _digestAlgorithm;
 };
 
-var generateSignature = function(contentName,content,signedinfo){
-	
-	var enc = new BinaryXMLEncoder();
-	contentName.to_ccnb(enc);
-	var hex1 = toHex(enc.getReducedOstream());
-
-	var enc = new BinaryXMLEncoder();
-	content.to_ccnb(enc);
-	var hex2 = toHex(enc.getReducedOstream());
-
-	var enc = new BinaryXMLEncoder();
-	signedinfo.to_ccnb(enc);
-	var hex3 = toHex(enc.getReducedOstream());
-
-	var hex = hex1+hex2+hex3;
-
-	//globalKeyManager.sig
-
-};
-
 Signature.prototype.from_ccnb =function( decoder) {
 		decoder.readStartElement(this.getElementLabel());
 		
@@ -5492,8 +5498,10 @@
 {

   //console.log('Raw string comming is '+input);

   var output = Array(input.length >> 2);

+  /* JavaScript automatically zeroizes a new array.

   for(var i = 0; i < output.length; i++)

     output[i] = 0;

+   */

   for(var i = 0; i < input.length * 8; i += 8)

     output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);

   return output;

@@ -5508,8 +5516,10 @@
 function byteArray2binb(input){

 	//console.log("Byte array coming is " + input);

 	var output = Array(input.length >> 2);

+      /* JavaScript automatically zeroizes a new array.

 	  for(var i = 0; i < output.length; i++)

 	    output[i] = 0;

+       */

 	  for(var i = 0; i < input.length * 8; i += 8)

 	    output[i>>5] |= (input[i / 8] & 0xFF) << (24 - i % 32);

 	  return output;

@@ -5562,15 +5572,25 @@
   var HASH = new Array(1779033703, -1150833019, 1013904242, -1521486534,

                        1359893119, -1694144372, 528734635, 1541459225);

   var W = new Array(64);

-  var a, b, c, d, e, f, g, h;

-  var i, j, T1, T2;

 

   /* append padding */

   m[l >> 5] |= 0x80 << (24 - l % 32);

   m[((l + 64 >> 9) << 4) + 15] = l;

+ 

+  for(var offset = 0; offset < m.length; offset += 16)

+    processBlock_sha256(m, offset, HASH, W);

 

-  for(i = 0; i < m.length; i += 16)

-  {

+  return HASH;

+}

+

+/*

+ * Process a block of 16 4-byte words in m starting at offset and update HASH.  

+ * offset must be a multiple of 16 and less than m.length.  W is a scratchpad Array(64).

+ */

+function processBlock_sha256(m, offset, HASH, W) {

+    var a, b, c, d, e, f, g, h;

+    var j, T1, T2;

+    

     a = HASH[0];

     b = HASH[1];

     c = HASH[2];

@@ -5582,7 +5602,7 @@
 

     for(j = 0; j < 64; j++)

     {

-      if (j < 16) W[j] = m[j + i];

+      if (j < 16) W[j] = m[j + offset];

       else W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]),

                                             sha256_Gamma0256(W[j - 15])), W[j - 16]);

 

@@ -5607,8 +5627,6 @@
     HASH[5] = safe_add(f, HASH[5]);

     HASH[6] = safe_add(g, HASH[6]);

     HASH[7] = safe_add(h, HASH[7]);

-  }

-  return HASH;

 }

 

 function safe_add (x, y)

@@ -5617,6 +5635,90 @@
   var msw = (x >> 16) + (y >> 16) + (lsw >> 16);

   return (msw << 16) | (lsw & 0xFFFF);

 }

+

+/*

+ * Create a Sha256, call update(data) multiple times, then call finalize().

+ */

+var Sha256 = function Sha256() {

+    this.W = new Array(64);

+    this.hash = new Array(1779033703, -1150833019, 1013904242, -1521486534,

+                          1359893119, -1694144372, 528734635, 1541459225);

+    this.nTotalBytes = 0;

+    this.buffer = new Uint8Array(16 * 4);

+    this.nBufferBytes = 0;

+}

+

+/*

+ * Update the hash with data, which is Uint8Array.

+ */

+Sha256.prototype.update = function(data) {

+    this.nTotalBytes += data.length;

+    

+    if (this.nBufferBytes > 0) {

+        // Fill up the buffer and process it first.

+        var bytesNeeded = this.buffer.length - this.nBufferBytes;

+        if (data.length < bytesNeeded) {

+            this.buffer.set(data, this.nBufferBytes);

+            this.nBufferBytes += data.length;

+            return;

+        }

+        else {

+            this.buffer.set(data.subarray(0, bytesNeeded), this.nBufferBytes);

+            processBlock_sha256(byteArray2binb(this.buffer), 0, this.hash, this.W);

+            this.nBufferBytes = 0;

+            // Consume the bytes from data.

+            data = data.subarray(bytesNeeded, data.length);

+            if (data.length == 0)

+                return;

+        }

+    }

+    

+    // 2^6 is 16 * 4.

+    var nBlocks = data.length >> 6;

+    if (nBlocks > 0) {

+        var nBytes = nBlocks * 16 * 4;

+        var m = byteArray2binb(data.subarray(0, nBytes));

+        for(var offset = 0; offset < m.length; offset += 16)

+            processBlock_sha256(m, offset, this.hash, this.W);

+

+        data = data.subarray(nBytes, data.length);

+    }

+    

+    if (data.length > 0) {

+        // Save the remainder in the buffer.

+        this.buffer.set(data);

+        this.nBufferBytes = data.length;

+    }

+}

+

+/*

+ * Finalize the hash and return the result as Uint8Array.

+ * Only call this once.  Return values on subsequent calls are undefined.

+ */

+Sha256.prototype.finalize = function() {

+    var m = byteArray2binb(this.buffer.subarray(0, this.nBufferBytes));

+    /* append padding */

+    var l = this.nBufferBytes * 8;

+    m[l >> 5] |= 0x80 << (24 - l % 32);

+    m[((l + 64 >> 9) << 4) + 15] = this.nTotalBytes * 8;

+

+    for(var offset = 0; offset < m.length; offset += 16)

+        processBlock_sha256(m, offset, this.hash, this.W);

+

+    return Sha256.binb2Uint8Array(this.hash);

+}

+

+/*

+ * Convert an array of big-endian words to Uint8Array.

+ */

+Sha256.binb2Uint8Array = function(input)

+{

+    var output = new Uint8Array(input.length * 4);

+    var iOutput = 0;

+    for (var i = 0; i < input.length * 32; i += 8)

+        output[iOutput++] = (input[i>>5] >>> (24 - i % 32)) & 0xFF;

+    return output;

+}

 /*

  * A JavaScript implementation of the Secure Hash Algorithm, SHA-512, as defined

  * in FIPS 180-2