diff --git a/.gitignore b/.gitignore
index e43b0f9..ba0e039 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,6 @@
 .DS_Store
+.waf*
+.lock*
+tools/yui*.jar
+tools/compiler*.jar
+build
diff --git a/BUILD b/BUILD
deleted file mode 100644
index 45de260..0000000
--- a/BUILD
+++ /dev/null
@@ -1,22 +0,0 @@
-NDN.JS: A javascript client library for Named Data Networking
-
-BASIC LIBRARY: NO BUILD REQUIRED. 
-The basic NDN.JS library does not need to be "built".  For the library, you can manually
-include the necessary scripts in a web page or include Helper.js to have it load all of
-the scripts.
-
-BUILD A COMBINED, COMPRESSED LIBRARY. 
-A more efficient way to include the library is to used the combined, compressed library
-ndn-js.js that can be made using the js/tools/build/make-js.sh script.  See the README in
-that directly.  While we try to keep a built version in that directory for convenience, it
-may fall out of sync with the library, so we recommend building it using the script if
-possible.
-
-WEBSOCKETS PROXY. 
-If you wish to run your own WebSockets proxy instead of using the NDN testbed, you must
-build and install Node.js (often on the machine also running the ccnd you wish to proxy
-for, but that doesn't have to be the case).  See wsproxy/README.md
-
-THE FIREFOX ADD-ON.
-If the compressed library js/tools/build/ndn-js.js is out of date, first build it (see above).
-Go to js/ndnProtocol and run make-ndnProtocol.sh which makes js/ndnProtocol.xpi .
diff --git a/README.install b/README.install
new file mode 100644
index 0000000..da4ab4c
--- /dev/null
+++ b/README.install
@@ -0,0 +1,42 @@
+NDN.JS: A javascript client library for Named Data Networking
+-------------------------------------------------------------
+
+BASIC LIBRARY: NO BUILD REQUIRED
+================================
+The basic NDN.JS library does not need to be "built".  For the library, you can manually
+include the necessary scripts in a web page or include Helper.js to have it load all of
+the scripts.
+
+BUILD A COMBINED, COMPRESSED LIBRARY 
+====================================
+
+A more efficient way to include the library is to used the combined, compressed library
+ndn-js.js that can be made using the js/tools/build/make-js.sh script.  See the README in
+that directly.  While we try to keep a built version in that directory for convenience, it
+may fall out of sync with the library, so we recommend building it using the script if
+possible.
+
+To create a combined and optionally compressed version of NDN.JS scripts:
+
+    ./waf configure --no-ws --prefix=<PREFIX_TO_INSTALL_JS> --compiler
+    ./waf install
+
+These commands will create a combined version, combined version compressed using  Google's
+Closure Compiler, and install it into <PREFIX_TO_INSTALL_JS> folder.
+
+The compressed version is what we recommend including in applications.
+
+
+WEBSOCKETS PROXY
+================
+
+If you wish to run your own WebSockets proxy instead of using the NDN testbed, you must
+build and install Node.js (often on the machine also running the ccnd you wish to proxy
+for, but that doesn't have to be the case).  See wsproxy/README.md
+
+THE FIREFOX ADD-ON
+==================
+
+If the compressed library js/tools/build/ndn-js.js is out of date, first build it (see above).
+Go to js/ndnProtocol and run make-ndnProtocol.sh which makes js/ndnProtocol.xpi.
+
diff --git a/README b/README.md
similarity index 100%
rename from README
rename to README.md
diff --git a/js/securityLib/LICENSE.txt b/contrib/securityLib/LICENSE.txt
similarity index 100%
rename from js/securityLib/LICENSE.txt
rename to contrib/securityLib/LICENSE.txt
diff --git a/js/securityLib/THIRDPARTY_LICENSE.txt b/contrib/securityLib/THIRDPARTY_LICENSE.txt
similarity index 100%
rename from js/securityLib/THIRDPARTY_LICENSE.txt
rename to contrib/securityLib/THIRDPARTY_LICENSE.txt
diff --git a/js/securityLib/asn1hex-1.1.js b/contrib/securityLib/asn1hex-1.1.js
similarity index 99%
rename from js/securityLib/asn1hex-1.1.js
rename to contrib/securityLib/asn1hex-1.1.js
index 3205442..da3b4b7 100644
--- a/js/securityLib/asn1hex-1.1.js
+++ b/contrib/securityLib/asn1hex-1.1.js
@@ -1,279 +1,279 @@
-/*! asn1hex-1.1.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
- */
-//
-// asn1hex.js - Hexadecimal represented ASN.1 string library
-//
-// version: 1.1 (09-May-2012)
-//
-// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
-//
-// This software is licensed under the terms of the MIT License.
-// http://kjur.github.com/jsrsasign/license/
-//
-// The above copyright and license notice shall be 
-// included in all copies or substantial portions of the Software.
-//
-// Depends on:
-//
-
-// MEMO:
-//   f('3082025b02...', 2) ... 82025b ... 3bytes
-//   f('020100', 2) ... 01 ... 1byte
-//   f('0203001...', 2) ... 03 ... 1byte
-//   f('02818003...', 2) ... 8180 ... 2bytes
-//   f('3080....0000', 2) ... 80 ... -1
-//
-//   Requirements:
-//   - ASN.1 type octet length MUST be 1. 
-//     (i.e. ASN.1 primitives like SET, SEQUENCE, INTEGER, OCTETSTRING ...)
-//   - 
-/**
- * get byte length for ASN.1 L(length) bytes
- * @name getByteLengthOfL_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} pos string index
- * @return byte length for ASN.1 L(length) bytes
- */
-function _asnhex_getByteLengthOfL_AtObj(s, pos) {
-  if (s.substring(pos + 2, pos + 3) != '8') return 1;
-  var i = parseInt(s.substring(pos + 3, pos + 4));
-  if (i == 0) return -1; 		// length octet '80' indefinite length
-  if (0 < i && i < 10) return i + 1;	// including '8?' octet;
-  return -2;				// malformed format
-}
-
-
-/**
- * get hexadecimal string for ASN.1 L(length) bytes
- * @name getHexOfL_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} pos string index
- * @return {String} hexadecimal string for ASN.1 L(length) bytes
- */
-function _asnhex_getHexOfL_AtObj(s, pos) {
-  var len = _asnhex_getByteLengthOfL_AtObj(s, pos);
-  if (len < 1) return '';
-  return s.substring(pos + 2, pos + 2 + len * 2);
-}
-
-//
-//   getting ASN.1 length value at the position 'idx' of
-//   hexa decimal string 's'.
-//
-//   f('3082025b02...', 0) ... 82025b ... ???
-//   f('020100', 0) ... 01 ... 1
-//   f('0203001...', 0) ... 03 ... 3
-//   f('02818003...', 0) ... 8180 ... 128
-/**
- * get integer value of ASN.1 length for ASN.1 data
- * @name getIntOfL_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} pos string index
- * @return ASN.1 L(length) integer value
- */
-function _asnhex_getIntOfL_AtObj(s, pos) {
-  var hLength = _asnhex_getHexOfL_AtObj(s, pos);
-  if (hLength == '') return -1;
-  var bi;
-  if (parseInt(hLength.substring(0, 1)) < 8) {
-     bi = parseBigInt(hLength, 16);
-  } else {
-     bi = parseBigInt(hLength.substring(2), 16);
-  }
-  return bi.intValue();
-}
-
-/**
- * get ASN.1 value starting string position for ASN.1 object refered by index 'idx'.
- * @name getStartPosOfV_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} pos string index
- */
-function _asnhex_getStartPosOfV_AtObj(s, pos) {
-  var l_len = _asnhex_getByteLengthOfL_AtObj(s, pos);
-  if (l_len < 0) return l_len;
-  return pos + (l_len + 1) * 2;
-}
-
-/**
- * get hexadecimal string of ASN.1 V(value)
- * @name getHexOfV_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} pos string index
- * @return {String} hexadecimal string of ASN.1 value.
- */
-function _asnhex_getHexOfV_AtObj(s, pos) {
-  var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos);
-  var len = _asnhex_getIntOfL_AtObj(s, pos);
-  return s.substring(pos1, pos1 + len * 2);
-}
-
-/**
- * get hexadecimal string of ASN.1 TLV at
- * @name getHexOfTLV_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} pos string index
- * @return {String} hexadecimal string of ASN.1 TLV.
- * @since 1.1
- */
-function _asnhex_getHexOfTLV_AtObj(s, pos) {
-  var hT = s.substr(pos, 2);
-  var hL = _asnhex_getHexOfL_AtObj(s, pos);
-  var hV = _asnhex_getHexOfV_AtObj(s, pos);
-  return hT + hL + hV;
-}
-
-/**
- * get next sibling starting index for ASN.1 object string
- * @name getPosOfNextSibling_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} pos string index
- * @return next sibling starting index for ASN.1 object string
- */
-function _asnhex_getPosOfNextSibling_AtObj(s, pos) {
-  var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos);
-  var len = _asnhex_getIntOfL_AtObj(s, pos);
-  return pos1 + len * 2;
-}
-
-/**
- * get array of indexes of child ASN.1 objects
- * @name getPosArrayOfChildren_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} start string index of ASN.1 object
- * @return {Array of Number} array of indexes for childen of ASN.1 objects
- */
-function _asnhex_getPosArrayOfChildren_AtObj(h, pos) {
-  var a = new Array();
-  var p0 = _asnhex_getStartPosOfV_AtObj(h, pos);
-  a.push(p0);
-
-  var len = _asnhex_getIntOfL_AtObj(h, pos);
-  var p = p0;
-  var k = 0;
-  while (1) {
-    var pNext = _asnhex_getPosOfNextSibling_AtObj(h, p);
-    if (pNext == null || (pNext - p0  >= (len * 2))) break;
-    if (k >= 200) break;
-
-    a.push(pNext);
-    p = pNext;
-
-    k++;
-  }
-
-  return a;
-}
-
-/**
- * get string index of nth child object of ASN.1 object refered by h, idx
- * @name getNthChildIndex_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} h hexadecimal string of ASN.1 DER encoded data
- * @param {Number} idx start string index of ASN.1 object
- * @param {Number} nth for child
- * @return {Number} string index of nth child.
- * @since 1.1
- */
-function _asnhex_getNthChildIndex_AtObj(h, idx, nth) {
-  var a = _asnhex_getPosArrayOfChildren_AtObj(h, idx);
-  return a[nth];
-}
-
-// ========== decendant methods ==============================
-
-/**
- * get string index of nth child object of ASN.1 object refered by h, idx
- * @name getDecendantIndexByNthList
- * @memberOf ASN1HEX
- * @function
- * @param {String} h hexadecimal string of ASN.1 DER encoded data
- * @param {Number} currentIndex start string index of ASN.1 object
- * @param {Array of Number} nthList array list of nth
- * @return {Number} string index refered by nthList
- * @since 1.1
- */
-function _asnhex_getDecendantIndexByNthList(h, currentIndex, nthList) {
-  if (nthList.length == 0) {
-    return currentIndex;
-  }
-  var firstNth = nthList.shift();
-  var a = _asnhex_getPosArrayOfChildren_AtObj(h, currentIndex);
-  return _asnhex_getDecendantIndexByNthList(h, a[firstNth], nthList);
-}
-
-/**
- * get hexadecimal string of ASN.1 TLV refered by current index and nth index list.
- * @name getDecendantHexTLVByNthList
- * @memberOf ASN1HEX
- * @function
- * @param {String} h hexadecimal string of ASN.1 DER encoded data
- * @param {Number} currentIndex start string index of ASN.1 object
- * @param {Array of Number} nthList array list of nth
- * @return {Number} hexadecimal string of ASN.1 TLV refered by nthList
- * @since 1.1
- */
-function _asnhex_getDecendantHexTLVByNthList(h, currentIndex, nthList) {
-  var idx = _asnhex_getDecendantIndexByNthList(h, currentIndex, nthList);
-  return _asnhex_getHexOfTLV_AtObj(h, idx);
-}
-
-/**
- * get hexadecimal string of ASN.1 V refered by current index and nth index list.
- * @name getDecendantHexVByNthList
- * @memberOf ASN1HEX
- * @function
- * @param {String} h hexadecimal string of ASN.1 DER encoded data
- * @param {Number} currentIndex start string index of ASN.1 object
- * @param {Array of Number} nthList array list of nth
- * @return {Number} hexadecimal string of ASN.1 V refered by nthList
- * @since 1.1
- */
-function _asnhex_getDecendantHexVByNthList(h, currentIndex, nthList) {
-  var idx = _asnhex_getDecendantIndexByNthList(h, currentIndex, nthList);
-  return _asnhex_getHexOfV_AtObj(h, idx);
-}
-
-// ========== class definition ==============================
-
-/**
- * ASN.1 DER encoded hexadecimal string utility class
- * @class ASN.1 DER encoded hexadecimal string utility class
- * @author Kenji Urushima
- * @version 1.1 (09 May 2012)
- * @see <a href="http://kjur.github.com/jsrsasigns/">'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/</a>
- * @since 1.1
- */
-function ASN1HEX() {
-  return ASN1HEX;
-}
-
-ASN1HEX.getByteLengthOfL_AtObj = _asnhex_getByteLengthOfL_AtObj;
-ASN1HEX.getHexOfL_AtObj = _asnhex_getHexOfL_AtObj;
-ASN1HEX.getIntOfL_AtObj = _asnhex_getIntOfL_AtObj;
-ASN1HEX.getStartPosOfV_AtObj = _asnhex_getStartPosOfV_AtObj;
-ASN1HEX.getHexOfV_AtObj = _asnhex_getHexOfV_AtObj;
-ASN1HEX.getHexOfTLV_AtObj = _asnhex_getHexOfTLV_AtObj;
-ASN1HEX.getPosOfNextSibling_AtObj = _asnhex_getPosOfNextSibling_AtObj;
-ASN1HEX.getPosArrayOfChildren_AtObj = _asnhex_getPosArrayOfChildren_AtObj;
-ASN1HEX.getNthChildIndex_AtObj = _asnhex_getNthChildIndex_AtObj;
-ASN1HEX.getDecendantIndexByNthList = _asnhex_getDecendantIndexByNthList;
-ASN1HEX.getDecendantHexVByNthList = _asnhex_getDecendantHexVByNthList;
-ASN1HEX.getDecendantHexTLVByNthList = _asnhex_getDecendantHexTLVByNthList;
+/*! asn1hex-1.1.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
+ */
+//
+// asn1hex.js - Hexadecimal represented ASN.1 string library
+//
+// version: 1.1 (09-May-2012)
+//
+// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
+//
+// This software is licensed under the terms of the MIT License.
+// http://kjur.github.com/jsrsasign/license/
+//
+// The above copyright and license notice shall be 
+// included in all copies or substantial portions of the Software.
+//
+// Depends on:
+//
+
+// MEMO:
+//   f('3082025b02...', 2) ... 82025b ... 3bytes
+//   f('020100', 2) ... 01 ... 1byte
+//   f('0203001...', 2) ... 03 ... 1byte
+//   f('02818003...', 2) ... 8180 ... 2bytes
+//   f('3080....0000', 2) ... 80 ... -1
+//
+//   Requirements:
+//   - ASN.1 type octet length MUST be 1. 
+//     (i.e. ASN.1 primitives like SET, SEQUENCE, INTEGER, OCTETSTRING ...)
+//   - 
+/**
+ * get byte length for ASN.1 L(length) bytes
+ * @name getByteLengthOfL_AtObj
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} s hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} pos string index
+ * @return byte length for ASN.1 L(length) bytes
+ */
+function _asnhex_getByteLengthOfL_AtObj(s, pos) {
+  if (s.substring(pos + 2, pos + 3) != '8') return 1;
+  var i = parseInt(s.substring(pos + 3, pos + 4));
+  if (i == 0) return -1; 		// length octet '80' indefinite length
+  if (0 < i && i < 10) return i + 1;	// including '8?' octet;
+  return -2;				// malformed format
+}
+
+
+/**
+ * get hexadecimal string for ASN.1 L(length) bytes
+ * @name getHexOfL_AtObj
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} s hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} pos string index
+ * @return {String} hexadecimal string for ASN.1 L(length) bytes
+ */
+function _asnhex_getHexOfL_AtObj(s, pos) {
+  var len = _asnhex_getByteLengthOfL_AtObj(s, pos);
+  if (len < 1) return '';
+  return s.substring(pos + 2, pos + 2 + len * 2);
+}
+
+//
+//   getting ASN.1 length value at the position 'idx' of
+//   hexa decimal string 's'.
+//
+//   f('3082025b02...', 0) ... 82025b ... ???
+//   f('020100', 0) ... 01 ... 1
+//   f('0203001...', 0) ... 03 ... 3
+//   f('02818003...', 0) ... 8180 ... 128
+/**
+ * get integer value of ASN.1 length for ASN.1 data
+ * @name getIntOfL_AtObj
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} s hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} pos string index
+ * @return ASN.1 L(length) integer value
+ */
+function _asnhex_getIntOfL_AtObj(s, pos) {
+  var hLength = _asnhex_getHexOfL_AtObj(s, pos);
+  if (hLength == '') return -1;
+  var bi;
+  if (parseInt(hLength.substring(0, 1)) < 8) {
+     bi = parseBigInt(hLength, 16);
+  } else {
+     bi = parseBigInt(hLength.substring(2), 16);
+  }
+  return bi.intValue();
+}
+
+/**
+ * get ASN.1 value starting string position for ASN.1 object refered by index 'idx'.
+ * @name getStartPosOfV_AtObj
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} s hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} pos string index
+ */
+function _asnhex_getStartPosOfV_AtObj(s, pos) {
+  var l_len = _asnhex_getByteLengthOfL_AtObj(s, pos);
+  if (l_len < 0) return l_len;
+  return pos + (l_len + 1) * 2;
+}
+
+/**
+ * get hexadecimal string of ASN.1 V(value)
+ * @name getHexOfV_AtObj
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} s hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} pos string index
+ * @return {String} hexadecimal string of ASN.1 value.
+ */
+function _asnhex_getHexOfV_AtObj(s, pos) {
+  var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos);
+  var len = _asnhex_getIntOfL_AtObj(s, pos);
+  return s.substring(pos1, pos1 + len * 2);
+}
+
+/**
+ * get hexadecimal string of ASN.1 TLV at
+ * @name getHexOfTLV_AtObj
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} s hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} pos string index
+ * @return {String} hexadecimal string of ASN.1 TLV.
+ * @since 1.1
+ */
+function _asnhex_getHexOfTLV_AtObj(s, pos) {
+  var hT = s.substr(pos, 2);
+  var hL = _asnhex_getHexOfL_AtObj(s, pos);
+  var hV = _asnhex_getHexOfV_AtObj(s, pos);
+  return hT + hL + hV;
+}
+
+/**
+ * get next sibling starting index for ASN.1 object string
+ * @name getPosOfNextSibling_AtObj
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} s hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} pos string index
+ * @return next sibling starting index for ASN.1 object string
+ */
+function _asnhex_getPosOfNextSibling_AtObj(s, pos) {
+  var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos);
+  var len = _asnhex_getIntOfL_AtObj(s, pos);
+  return pos1 + len * 2;
+}
+
+/**
+ * get array of indexes of child ASN.1 objects
+ * @name getPosArrayOfChildren_AtObj
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} s hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} start string index of ASN.1 object
+ * @return {Array of Number} array of indexes for childen of ASN.1 objects
+ */
+function _asnhex_getPosArrayOfChildren_AtObj(h, pos) {
+  var a = new Array();
+  var p0 = _asnhex_getStartPosOfV_AtObj(h, pos);
+  a.push(p0);
+
+  var len = _asnhex_getIntOfL_AtObj(h, pos);
+  var p = p0;
+  var k = 0;
+  while (1) {
+    var pNext = _asnhex_getPosOfNextSibling_AtObj(h, p);
+    if (pNext == null || (pNext - p0  >= (len * 2))) break;
+    if (k >= 200) break;
+
+    a.push(pNext);
+    p = pNext;
+
+    k++;
+  }
+
+  return a;
+}
+
+/**
+ * get string index of nth child object of ASN.1 object refered by h, idx
+ * @name getNthChildIndex_AtObj
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} h hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} idx start string index of ASN.1 object
+ * @param {Number} nth for child
+ * @return {Number} string index of nth child.
+ * @since 1.1
+ */
+function _asnhex_getNthChildIndex_AtObj(h, idx, nth) {
+  var a = _asnhex_getPosArrayOfChildren_AtObj(h, idx);
+  return a[nth];
+}
+
+// ========== decendant methods ==============================
+
+/**
+ * get string index of nth child object of ASN.1 object refered by h, idx
+ * @name getDecendantIndexByNthList
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} h hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} currentIndex start string index of ASN.1 object
+ * @param {Array of Number} nthList array list of nth
+ * @return {Number} string index refered by nthList
+ * @since 1.1
+ */
+function _asnhex_getDecendantIndexByNthList(h, currentIndex, nthList) {
+  if (nthList.length == 0) {
+    return currentIndex;
+  }
+  var firstNth = nthList.shift();
+  var a = _asnhex_getPosArrayOfChildren_AtObj(h, currentIndex);
+  return _asnhex_getDecendantIndexByNthList(h, a[firstNth], nthList);
+}
+
+/**
+ * get hexadecimal string of ASN.1 TLV refered by current index and nth index list.
+ * @name getDecendantHexTLVByNthList
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} h hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} currentIndex start string index of ASN.1 object
+ * @param {Array of Number} nthList array list of nth
+ * @return {Number} hexadecimal string of ASN.1 TLV refered by nthList
+ * @since 1.1
+ */
+function _asnhex_getDecendantHexTLVByNthList(h, currentIndex, nthList) {
+  var idx = _asnhex_getDecendantIndexByNthList(h, currentIndex, nthList);
+  return _asnhex_getHexOfTLV_AtObj(h, idx);
+}
+
+/**
+ * get hexadecimal string of ASN.1 V refered by current index and nth index list.
+ * @name getDecendantHexVByNthList
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} h hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} currentIndex start string index of ASN.1 object
+ * @param {Array of Number} nthList array list of nth
+ * @return {Number} hexadecimal string of ASN.1 V refered by nthList
+ * @since 1.1
+ */
+function _asnhex_getDecendantHexVByNthList(h, currentIndex, nthList) {
+  var idx = _asnhex_getDecendantIndexByNthList(h, currentIndex, nthList);
+  return _asnhex_getHexOfV_AtObj(h, idx);
+}
+
+// ========== class definition ==============================
+
+/**
+ * ASN.1 DER encoded hexadecimal string utility class
+ * @class ASN.1 DER encoded hexadecimal string utility class
+ * @author Kenji Urushima
+ * @version 1.1 (09 May 2012)
+ * @see <a href="http://kjur.github.com/jsrsasigns/">'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/</a>
+ * @since 1.1
+ */
+function ASN1HEX() {
+  return ASN1HEX;
+}
+
+ASN1HEX.getByteLengthOfL_AtObj = _asnhex_getByteLengthOfL_AtObj;
+ASN1HEX.getHexOfL_AtObj = _asnhex_getHexOfL_AtObj;
+ASN1HEX.getIntOfL_AtObj = _asnhex_getIntOfL_AtObj;
+ASN1HEX.getStartPosOfV_AtObj = _asnhex_getStartPosOfV_AtObj;
+ASN1HEX.getHexOfV_AtObj = _asnhex_getHexOfV_AtObj;
+ASN1HEX.getHexOfTLV_AtObj = _asnhex_getHexOfTLV_AtObj;
+ASN1HEX.getPosOfNextSibling_AtObj = _asnhex_getPosOfNextSibling_AtObj;
+ASN1HEX.getPosArrayOfChildren_AtObj = _asnhex_getPosArrayOfChildren_AtObj;
+ASN1HEX.getNthChildIndex_AtObj = _asnhex_getNthChildIndex_AtObj;
+ASN1HEX.getDecendantIndexByNthList = _asnhex_getDecendantIndexByNthList;
+ASN1HEX.getDecendantHexVByNthList = _asnhex_getDecendantHexVByNthList;
+ASN1HEX.getDecendantHexTLVByNthList = _asnhex_getDecendantHexTLVByNthList;
diff --git a/js/securityLib/asn1hex-1.1.min.js b/contrib/securityLib/asn1hex-1.1.min.js
similarity index 100%
rename from js/securityLib/asn1hex-1.1.min.js
rename to contrib/securityLib/asn1hex-1.1.min.js
diff --git a/js/securityLib/base64.js b/contrib/securityLib/base64.js
similarity index 99%
rename from js/securityLib/base64.js
rename to contrib/securityLib/base64.js
index cc582e2..5f7f29d 100644
--- a/js/securityLib/base64.js
+++ b/contrib/securityLib/base64.js
@@ -1,71 +1,71 @@
-var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-var b64pad="=";
-
-function hex2b64(h) {
-  var i;
-  var c;
-  var ret = "";
-  for(i = 0; i+3 <= h.length; i+=3) {
-    c = parseInt(h.substring(i,i+3),16);
-    ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);
-  }
-  if(i+1 == h.length) {
-    c = parseInt(h.substring(i,i+1),16);
-    ret += b64map.charAt(c << 2);
-  }
-  else if(i+2 == h.length) {
-    c = parseInt(h.substring(i,i+2),16);
-    ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);
-  }
-  while((ret.length & 3) > 0) ret += b64pad;
-  return ret;
-}
-
-// convert a base64 string to hex
-function b64tohex(s) {
-  var ret = ""
-  var i;
-  var k = 0; // b64 state, 0-3
-  var slop;
-  for(i = 0; i < s.length; ++i) {
-    if(s.charAt(i) == b64pad) break;
-    var v = b64map.indexOf(s.charAt(i));
-    if(v < 0) continue;
-    if(k == 0) {
-      ret += int2char(v >> 2);
-      slop = v & 3;
-      k = 1;
-    }
-    else if(k == 1) {
-      ret += int2char((slop << 2) | (v >> 4));
-      slop = v & 0xf;
-      k = 2;
-    }
-    else if(k == 2) {
-      ret += int2char(slop);
-      ret += int2char(v >> 2);
-      slop = v & 3;
-      k = 3;
-    }
-    else {
-      ret += int2char((slop << 2) | (v >> 4));
-      ret += int2char(v & 0xf);
-      k = 0;
-    }
-  }
-  if(k == 1)
-    ret += int2char(slop << 2);
-  return ret;
-}
-
-// convert a base64 string to a byte/number array
-function b64toBA(s) {
-  //piggyback on b64tohex for now, optimize later
-  var h = b64tohex(s);
-  var i;
-  var a = new Array();
-  for(i = 0; 2*i < h.length; ++i) {
-    a[i] = parseInt(h.substring(2*i,2*i+2),16);
-  }
-  return a;
-}
+var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+var b64pad="=";
+
+function hex2b64(h) {
+  var i;
+  var c;
+  var ret = "";
+  for(i = 0; i+3 <= h.length; i+=3) {
+    c = parseInt(h.substring(i,i+3),16);
+    ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);
+  }
+  if(i+1 == h.length) {
+    c = parseInt(h.substring(i,i+1),16);
+    ret += b64map.charAt(c << 2);
+  }
+  else if(i+2 == h.length) {
+    c = parseInt(h.substring(i,i+2),16);
+    ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);
+  }
+  while((ret.length & 3) > 0) ret += b64pad;
+  return ret;
+}
+
+// convert a base64 string to hex
+function b64tohex(s) {
+  var ret = ""
+  var i;
+  var k = 0; // b64 state, 0-3
+  var slop;
+  for(i = 0; i < s.length; ++i) {
+    if(s.charAt(i) == b64pad) break;
+    var v = b64map.indexOf(s.charAt(i));
+    if(v < 0) continue;
+    if(k == 0) {
+      ret += int2char(v >> 2);
+      slop = v & 3;
+      k = 1;
+    }
+    else if(k == 1) {
+      ret += int2char((slop << 2) | (v >> 4));
+      slop = v & 0xf;
+      k = 2;
+    }
+    else if(k == 2) {
+      ret += int2char(slop);
+      ret += int2char(v >> 2);
+      slop = v & 3;
+      k = 3;
+    }
+    else {
+      ret += int2char((slop << 2) | (v >> 4));
+      ret += int2char(v & 0xf);
+      k = 0;
+    }
+  }
+  if(k == 1)
+    ret += int2char(slop << 2);
+  return ret;
+}
+
+// convert a base64 string to a byte/number array
+function b64toBA(s) {
+  //piggyback on b64tohex for now, optimize later
+  var h = b64tohex(s);
+  var i;
+  var a = new Array();
+  for(i = 0; 2*i < h.length; ++i) {
+    a[i] = parseInt(h.substring(2*i,2*i+2),16);
+  }
+  return a;
+}
diff --git a/js/securityLib/jsbn.js b/contrib/securityLib/jsbn.js
similarity index 99%
rename from js/securityLib/jsbn.js
rename to contrib/securityLib/jsbn.js
index a153e40..928cc4f 100644
--- a/js/securityLib/jsbn.js
+++ b/contrib/securityLib/jsbn.js
@@ -1,559 +1,559 @@
-// Copyright (c) 2005  Tom Wu
-// All Rights Reserved.
-// See "LICENSE" for details.
-
-// Basic JavaScript BN library - subset useful for RSA encryption.
-
-// Bits per digit
-var dbits;
-
-// JavaScript engine analysis
-var canary = 0xdeadbeefcafe;
-var j_lm = ((canary&0xffffff)==0xefcafe);
-
-// (public) Constructor
-function BigInteger(a,b,c) {
-  if(a != null)
-    if("number" == typeof a) this.fromNumber(a,b,c);
-    else if(b == null && "string" != typeof a) this.fromString(a,256);
-    else this.fromString(a,b);
-}
-
-// return new, unset BigInteger
-function nbi() { return new BigInteger(null); }
-
-// am: Compute w_j += (x*this_i), propagate carries,
-// c is initial carry, returns final carry.
-// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
-// We need to select the fastest one that works in this environment.
-
-// am1: use a single mult and divide to get the high bits,
-// max digit bits should be 26 because
-// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
-function am1(i,x,w,j,c,n) {
-  while(--n >= 0) {
-    var v = x*this[i++]+w[j]+c;
-    c = Math.floor(v/0x4000000);
-    w[j++] = v&0x3ffffff;
-  }
-  return c;
-}
-// am2 avoids a big mult-and-extract completely.
-// Max digit bits should be <= 30 because we do bitwise ops
-// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
-function am2(i,x,w,j,c,n) {
-  var xl = x&0x7fff, xh = x>>15;
-  while(--n >= 0) {
-    var l = this[i]&0x7fff;
-    var h = this[i++]>>15;
-    var m = xh*l+h*xl;
-    l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff);
-    c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);
-    w[j++] = l&0x3fffffff;
-  }
-  return c;
-}
-// Alternately, set max digit bits to 28 since some
-// browsers slow down when dealing with 32-bit numbers.
-function am3(i,x,w,j,c,n) {
-  var xl = x&0x3fff, xh = x>>14;
-  while(--n >= 0) {
-    var l = this[i]&0x3fff;
-    var h = this[i++]>>14;
-    var m = xh*l+h*xl;
-    l = xl*l+((m&0x3fff)<<14)+w[j]+c;
-    c = (l>>28)+(m>>14)+xh*h;
-    w[j++] = l&0xfffffff;
-  }
-  return c;
-}
-if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
-  BigInteger.prototype.am = am2;
-  dbits = 30;
-}
-else if(j_lm && (navigator.appName != "Netscape")) {
-  BigInteger.prototype.am = am1;
-  dbits = 26;
-}
-else { // Mozilla/Netscape seems to prefer am3
-  BigInteger.prototype.am = am3;
-  dbits = 28;
-}
-
-BigInteger.prototype.DB = dbits;
-BigInteger.prototype.DM = ((1<<dbits)-1);
-BigInteger.prototype.DV = (1<<dbits);
-
-var BI_FP = 52;
-BigInteger.prototype.FV = Math.pow(2,BI_FP);
-BigInteger.prototype.F1 = BI_FP-dbits;
-BigInteger.prototype.F2 = 2*dbits-BI_FP;
-
-// Digit conversions
-var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
-var BI_RC = new Array();
-var rr,vv;
-rr = "0".charCodeAt(0);
-for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
-rr = "a".charCodeAt(0);
-for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
-rr = "A".charCodeAt(0);
-for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
-
-function int2char(n) { return BI_RM.charAt(n); }
-function intAt(s,i) {
-  var c = BI_RC[s.charCodeAt(i)];
-  return (c==null)?-1:c;
-}
-
-// (protected) copy this to r
-function bnpCopyTo(r) {
-  for(var i = this.t-1; i >= 0; --i) r[i] = this[i];
-  r.t = this.t;
-  r.s = this.s;
-}
-
-// (protected) set from integer value x, -DV <= x < DV
-function bnpFromInt(x) {
-  this.t = 1;
-  this.s = (x<0)?-1:0;
-  if(x > 0) this[0] = x;
-  else if(x < -1) this[0] = x+DV;
-  else this.t = 0;
-}
-
-// return bigint initialized to value
-function nbv(i) { var r = nbi(); r.fromInt(i); return r; }
-
-// (protected) set from string and radix
-function bnpFromString(s,b) {
-  var k;
-  if(b == 16) k = 4;
-  else if(b == 8) k = 3;
-  else if(b == 256) k = 8; // byte array
-  else if(b == 2) k = 1;
-  else if(b == 32) k = 5;
-  else if(b == 4) k = 2;
-  else { this.fromRadix(s,b); return; }
-  this.t = 0;
-  this.s = 0;
-  var i = s.length, mi = false, sh = 0;
-  while(--i >= 0) {
-    var x = (k==8)?s[i]&0xff:intAt(s,i);
-    if(x < 0) {
-      if(s.charAt(i) == "-") mi = true;
-      continue;
-    }
-    mi = false;
-    if(sh == 0)
-      this[this.t++] = x;
-    else if(sh+k > this.DB) {
-      this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh;
-      this[this.t++] = (x>>(this.DB-sh));
-    }
-    else
-      this[this.t-1] |= x<<sh;
-    sh += k;
-    if(sh >= this.DB) sh -= this.DB;
-  }
-  if(k == 8 && (s[0]&0x80) != 0) {
-    this.s = -1;
-    if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh;
-  }
-  this.clamp();
-  if(mi) BigInteger.ZERO.subTo(this,this);
-}
-
-// (protected) clamp off excess high words
-function bnpClamp() {
-  var c = this.s&this.DM;
-  while(this.t > 0 && this[this.t-1] == c) --this.t;
-}
-
-// (public) return string representation in given radix
-function bnToString(b) {
-  if(this.s < 0) return "-"+this.negate().toString(b);
-  var k;
-  if(b == 16) k = 4;
-  else if(b == 8) k = 3;
-  else if(b == 2) k = 1;
-  else if(b == 32) k = 5;
-  else if(b == 4) k = 2;
-  else return this.toRadix(b);
-  var km = (1<<k)-1, d, m = false, r = "", i = this.t;
-  var p = this.DB-(i*this.DB)%k;
-  if(i-- > 0) {
-    if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); }
-    while(i >= 0) {
-      if(p < k) {
-        d = (this[i]&((1<<p)-1))<<(k-p);
-        d |= this[--i]>>(p+=this.DB-k);
-      }
-      else {
-        d = (this[i]>>(p-=k))&km;
-        if(p <= 0) { p += this.DB; --i; }
-      }
-      if(d > 0) m = true;
-      if(m) r += int2char(d);
-    }
-  }
-  return m?r:"0";
-}
-
-// (public) -this
-function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }
-
-// (public) |this|
-function bnAbs() { return (this.s<0)?this.negate():this; }
-
-// (public) return + if this > a, - if this < a, 0 if equal
-function bnCompareTo(a) {
-  var r = this.s-a.s;
-  if(r != 0) return r;
-  var i = this.t;
-  r = i-a.t;
-  if(r != 0) return r;
-  while(--i >= 0) if((r=this[i]-a[i]) != 0) return r;
-  return 0;
-}
-
-// returns bit length of the integer x
-function nbits(x) {
-  var r = 1, t;
-  if((t=x>>>16) != 0) { x = t; r += 16; }
-  if((t=x>>8) != 0) { x = t; r += 8; }
-  if((t=x>>4) != 0) { x = t; r += 4; }
-  if((t=x>>2) != 0) { x = t; r += 2; }
-  if((t=x>>1) != 0) { x = t; r += 1; }
-  return r;
-}
-
-// (public) return the number of bits in "this"
-function bnBitLength() {
-  if(this.t <= 0) return 0;
-  return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));
-}
-
-// (protected) r = this << n*DB
-function bnpDLShiftTo(n,r) {
-  var i;
-  for(i = this.t-1; i >= 0; --i) r[i+n] = this[i];
-  for(i = n-1; i >= 0; --i) r[i] = 0;
-  r.t = this.t+n;
-  r.s = this.s;
-}
-
-// (protected) r = this >> n*DB
-function bnpDRShiftTo(n,r) {
-  for(var i = n; i < this.t; ++i) r[i-n] = this[i];
-  r.t = Math.max(this.t-n,0);
-  r.s = this.s;
-}
-
-// (protected) r = this << n
-function bnpLShiftTo(n,r) {
-  var bs = n%this.DB;
-  var cbs = this.DB-bs;
-  var bm = (1<<cbs)-1;
-  var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i;
-  for(i = this.t-1; i >= 0; --i) {
-    r[i+ds+1] = (this[i]>>cbs)|c;
-    c = (this[i]&bm)<<bs;
-  }
-  for(i = ds-1; i >= 0; --i) r[i] = 0;
-  r[ds] = c;
-  r.t = this.t+ds+1;
-  r.s = this.s;
-  r.clamp();
-}
-
-// (protected) r = this >> n
-function bnpRShiftTo(n,r) {
-  r.s = this.s;
-  var ds = Math.floor(n/this.DB);
-  if(ds >= this.t) { r.t = 0; return; }
-  var bs = n%this.DB;
-  var cbs = this.DB-bs;
-  var bm = (1<<bs)-1;
-  r[0] = this[ds]>>bs;
-  for(var i = ds+1; i < this.t; ++i) {
-    r[i-ds-1] |= (this[i]&bm)<<cbs;
-    r[i-ds] = this[i]>>bs;
-  }
-  if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs;
-  r.t = this.t-ds;
-  r.clamp();
-}
-
-// (protected) r = this - a
-function bnpSubTo(a,r) {
-  var i = 0, c = 0, m = Math.min(a.t,this.t);
-  while(i < m) {
-    c += this[i]-a[i];
-    r[i++] = c&this.DM;
-    c >>= this.DB;
-  }
-  if(a.t < this.t) {
-    c -= a.s;
-    while(i < this.t) {
-      c += this[i];
-      r[i++] = c&this.DM;
-      c >>= this.DB;
-    }
-    c += this.s;
-  }
-  else {
-    c += this.s;
-    while(i < a.t) {
-      c -= a[i];
-      r[i++] = c&this.DM;
-      c >>= this.DB;
-    }
-    c -= a.s;
-  }
-  r.s = (c<0)?-1:0;
-  if(c < -1) r[i++] = this.DV+c;
-  else if(c > 0) r[i++] = c;
-  r.t = i;
-  r.clamp();
-}
-
-// (protected) r = this * a, r != this,a (HAC 14.12)
-// "this" should be the larger one if appropriate.
-function bnpMultiplyTo(a,r) {
-  var x = this.abs(), y = a.abs();
-  var i = x.t;
-  r.t = i+y.t;
-  while(--i >= 0) r[i] = 0;
-  for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t);
-  r.s = 0;
-  r.clamp();
-  if(this.s != a.s) BigInteger.ZERO.subTo(r,r);
-}
-
-// (protected) r = this^2, r != this (HAC 14.16)
-function bnpSquareTo(r) {
-  var x = this.abs();
-  var i = r.t = 2*x.t;
-  while(--i >= 0) r[i] = 0;
-  for(i = 0; i < x.t-1; ++i) {
-    var c = x.am(i,x[i],r,2*i,0,1);
-    if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) {
-      r[i+x.t] -= x.DV;
-      r[i+x.t+1] = 1;
-    }
-  }
-  if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1);
-  r.s = 0;
-  r.clamp();
-}
-
-// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
-// r != q, this != m.  q or r may be null.
-function bnpDivRemTo(m,q,r) {
-  var pm = m.abs();
-  if(pm.t <= 0) return;
-  var pt = this.abs();
-  if(pt.t < pm.t) {
-    if(q != null) q.fromInt(0);
-    if(r != null) this.copyTo(r);
-    return;
-  }
-  if(r == null) r = nbi();
-  var y = nbi(), ts = this.s, ms = m.s;
-  var nsh = this.DB-nbits(pm[pm.t-1]);	// normalize modulus
-  if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); }
-  else { pm.copyTo(y); pt.copyTo(r); }
-  var ys = y.t;
-  var y0 = y[ys-1];
-  if(y0 == 0) return;
-  var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0);
-  var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2;
-  var i = r.t, j = i-ys, t = (q==null)?nbi():q;
-  y.dlShiftTo(j,t);
-  if(r.compareTo(t) >= 0) {
-    r[r.t++] = 1;
-    r.subTo(t,r);
-  }
-  BigInteger.ONE.dlShiftTo(ys,t);
-  t.subTo(y,y);	// "negative" y so we can replace sub with am later
-  while(y.t < ys) y[y.t++] = 0;
-  while(--j >= 0) {
-    // Estimate quotient digit
-    var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);
-    if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) {	// Try it out
-      y.dlShiftTo(j,t);
-      r.subTo(t,r);
-      while(r[i] < --qd) r.subTo(t,r);
-    }
-  }
-  if(q != null) {
-    r.drShiftTo(ys,q);
-    if(ts != ms) BigInteger.ZERO.subTo(q,q);
-  }
-  r.t = ys;
-  r.clamp();
-  if(nsh > 0) r.rShiftTo(nsh,r);	// Denormalize remainder
-  if(ts < 0) BigInteger.ZERO.subTo(r,r);
-}
-
-// (public) this mod a
-function bnMod(a) {
-  var r = nbi();
-  this.abs().divRemTo(a,null,r);
-  if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r);
-  return r;
-}
-
-// Modular reduction using "classic" algorithm
-function Classic(m) { this.m = m; }
-function cConvert(x) {
-  if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
-  else return x;
-}
-function cRevert(x) { return x; }
-function cReduce(x) { x.divRemTo(this.m,null,x); }
-function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
-function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
-
-Classic.prototype.convert = cConvert;
-Classic.prototype.revert = cRevert;
-Classic.prototype.reduce = cReduce;
-Classic.prototype.mulTo = cMulTo;
-Classic.prototype.sqrTo = cSqrTo;
-
-// (protected) return "-1/this % 2^DB"; useful for Mont. reduction
-// justification:
-//         xy == 1 (mod m)
-//         xy =  1+km
-//   xy(2-xy) = (1+km)(1-km)
-// x[y(2-xy)] = 1-k^2m^2
-// x[y(2-xy)] == 1 (mod m^2)
-// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
-// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
-// JS multiply "overflows" differently from C/C++, so care is needed here.
-function bnpInvDigit() {
-  if(this.t < 1) return 0;
-  var x = this[0];
-  if((x&1) == 0) return 0;
-  var y = x&3;		// y == 1/x mod 2^2
-  y = (y*(2-(x&0xf)*y))&0xf;	// y == 1/x mod 2^4
-  y = (y*(2-(x&0xff)*y))&0xff;	// y == 1/x mod 2^8
-  y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff;	// y == 1/x mod 2^16
-  // last step - calculate inverse mod DV directly;
-  // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
-  y = (y*(2-x*y%this.DV))%this.DV;		// y == 1/x mod 2^dbits
-  // we really want the negative inverse, and -DV < y < DV
-  return (y>0)?this.DV-y:-y;
-}
-
-// Montgomery reduction
-function Montgomery(m) {
-  this.m = m;
-  this.mp = m.invDigit();
-  this.mpl = this.mp&0x7fff;
-  this.mph = this.mp>>15;
-  this.um = (1<<(m.DB-15))-1;
-  this.mt2 = 2*m.t;
-}
-
-// xR mod m
-function montConvert(x) {
-  var r = nbi();
-  x.abs().dlShiftTo(this.m.t,r);
-  r.divRemTo(this.m,null,r);
-  if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r);
-  return r;
-}
-
-// x/R mod m
-function montRevert(x) {
-  var r = nbi();
-  x.copyTo(r);
-  this.reduce(r);
-  return r;
-}
-
-// x = x/R mod m (HAC 14.32)
-function montReduce(x) {
-  while(x.t <= this.mt2)	// pad x so am has enough room later
-    x[x.t++] = 0;
-  for(var i = 0; i < this.m.t; ++i) {
-    // faster way of calculating u0 = x[i]*mp mod DV
-    var j = x[i]&0x7fff;
-    var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM;
-    // use am to combine the multiply-shift-add into one call
-    j = i+this.m.t;
-    x[j] += this.m.am(0,u0,x,i,0,this.m.t);
-    // propagate carry
-    while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }
-  }
-  x.clamp();
-  x.drShiftTo(this.m.t,x);
-  if(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
-}
-
-// r = "x^2/R mod m"; x != r
-function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
-
-// r = "xy/R mod m"; x,y != r
-function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
-
-Montgomery.prototype.convert = montConvert;
-Montgomery.prototype.revert = montRevert;
-Montgomery.prototype.reduce = montReduce;
-Montgomery.prototype.mulTo = montMulTo;
-Montgomery.prototype.sqrTo = montSqrTo;
-
-// (protected) true iff this is even
-function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; }
-
-// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
-function bnpExp(e,z) {
-  if(e > 0xffffffff || e < 1) return BigInteger.ONE;
-  var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1;
-  g.copyTo(r);
-  while(--i >= 0) {
-    z.sqrTo(r,r2);
-    if((e&(1<<i)) > 0) z.mulTo(r2,g,r);
-    else { var t = r; r = r2; r2 = t; }
-  }
-  return z.revert(r);
-}
-
-// (public) this^e % m, 0 <= e < 2^32
-function bnModPowInt(e,m) {
-  var z;
-  if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
-  return this.exp(e,z);
-}
-
-// protected
-BigInteger.prototype.copyTo = bnpCopyTo;
-BigInteger.prototype.fromInt = bnpFromInt;
-BigInteger.prototype.fromString = bnpFromString;
-BigInteger.prototype.clamp = bnpClamp;
-BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
-BigInteger.prototype.drShiftTo = bnpDRShiftTo;
-BigInteger.prototype.lShiftTo = bnpLShiftTo;
-BigInteger.prototype.rShiftTo = bnpRShiftTo;
-BigInteger.prototype.subTo = bnpSubTo;
-BigInteger.prototype.multiplyTo = bnpMultiplyTo;
-BigInteger.prototype.squareTo = bnpSquareTo;
-BigInteger.prototype.divRemTo = bnpDivRemTo;
-BigInteger.prototype.invDigit = bnpInvDigit;
-BigInteger.prototype.isEven = bnpIsEven;
-BigInteger.prototype.exp = bnpExp;
-
-// public
-BigInteger.prototype.toString = bnToString;
-BigInteger.prototype.negate = bnNegate;
-BigInteger.prototype.abs = bnAbs;
-BigInteger.prototype.compareTo = bnCompareTo;
-BigInteger.prototype.bitLength = bnBitLength;
-BigInteger.prototype.mod = bnMod;
-BigInteger.prototype.modPowInt = bnModPowInt;
-
-// "constants"
-BigInteger.ZERO = nbv(0);
-BigInteger.ONE = nbv(1);
+// Copyright (c) 2005  Tom Wu
+// All Rights Reserved.
+// See "LICENSE" for details.
+
+// Basic JavaScript BN library - subset useful for RSA encryption.
+
+// Bits per digit
+var dbits;
+
+// JavaScript engine analysis
+var canary = 0xdeadbeefcafe;
+var j_lm = ((canary&0xffffff)==0xefcafe);
+
+// (public) Constructor
+function BigInteger(a,b,c) {
+  if(a != null)
+    if("number" == typeof a) this.fromNumber(a,b,c);
+    else if(b == null && "string" != typeof a) this.fromString(a,256);
+    else this.fromString(a,b);
+}
+
+// return new, unset BigInteger
+function nbi() { return new BigInteger(null); }
+
+// am: Compute w_j += (x*this_i), propagate carries,
+// c is initial carry, returns final carry.
+// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
+// We need to select the fastest one that works in this environment.
+
+// am1: use a single mult and divide to get the high bits,
+// max digit bits should be 26 because
+// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
+function am1(i,x,w,j,c,n) {
+  while(--n >= 0) {
+    var v = x*this[i++]+w[j]+c;
+    c = Math.floor(v/0x4000000);
+    w[j++] = v&0x3ffffff;
+  }
+  return c;
+}
+// am2 avoids a big mult-and-extract completely.
+// Max digit bits should be <= 30 because we do bitwise ops
+// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
+function am2(i,x,w,j,c,n) {
+  var xl = x&0x7fff, xh = x>>15;
+  while(--n >= 0) {
+    var l = this[i]&0x7fff;
+    var h = this[i++]>>15;
+    var m = xh*l+h*xl;
+    l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff);
+    c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);
+    w[j++] = l&0x3fffffff;
+  }
+  return c;
+}
+// Alternately, set max digit bits to 28 since some
+// browsers slow down when dealing with 32-bit numbers.
+function am3(i,x,w,j,c,n) {
+  var xl = x&0x3fff, xh = x>>14;
+  while(--n >= 0) {
+    var l = this[i]&0x3fff;
+    var h = this[i++]>>14;
+    var m = xh*l+h*xl;
+    l = xl*l+((m&0x3fff)<<14)+w[j]+c;
+    c = (l>>28)+(m>>14)+xh*h;
+    w[j++] = l&0xfffffff;
+  }
+  return c;
+}
+if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
+  BigInteger.prototype.am = am2;
+  dbits = 30;
+}
+else if(j_lm && (navigator.appName != "Netscape")) {
+  BigInteger.prototype.am = am1;
+  dbits = 26;
+}
+else { // Mozilla/Netscape seems to prefer am3
+  BigInteger.prototype.am = am3;
+  dbits = 28;
+}
+
+BigInteger.prototype.DB = dbits;
+BigInteger.prototype.DM = ((1<<dbits)-1);
+BigInteger.prototype.DV = (1<<dbits);
+
+var BI_FP = 52;
+BigInteger.prototype.FV = Math.pow(2,BI_FP);
+BigInteger.prototype.F1 = BI_FP-dbits;
+BigInteger.prototype.F2 = 2*dbits-BI_FP;
+
+// Digit conversions
+var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
+var BI_RC = new Array();
+var rr,vv;
+rr = "0".charCodeAt(0);
+for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
+rr = "a".charCodeAt(0);
+for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
+rr = "A".charCodeAt(0);
+for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
+
+function int2char(n) { return BI_RM.charAt(n); }
+function intAt(s,i) {
+  var c = BI_RC[s.charCodeAt(i)];
+  return (c==null)?-1:c;
+}
+
+// (protected) copy this to r
+function bnpCopyTo(r) {
+  for(var i = this.t-1; i >= 0; --i) r[i] = this[i];
+  r.t = this.t;
+  r.s = this.s;
+}
+
+// (protected) set from integer value x, -DV <= x < DV
+function bnpFromInt(x) {
+  this.t = 1;
+  this.s = (x<0)?-1:0;
+  if(x > 0) this[0] = x;
+  else if(x < -1) this[0] = x+DV;
+  else this.t = 0;
+}
+
+// return bigint initialized to value
+function nbv(i) { var r = nbi(); r.fromInt(i); return r; }
+
+// (protected) set from string and radix
+function bnpFromString(s,b) {
+  var k;
+  if(b == 16) k = 4;
+  else if(b == 8) k = 3;
+  else if(b == 256) k = 8; // byte array
+  else if(b == 2) k = 1;
+  else if(b == 32) k = 5;
+  else if(b == 4) k = 2;
+  else { this.fromRadix(s,b); return; }
+  this.t = 0;
+  this.s = 0;
+  var i = s.length, mi = false, sh = 0;
+  while(--i >= 0) {
+    var x = (k==8)?s[i]&0xff:intAt(s,i);
+    if(x < 0) {
+      if(s.charAt(i) == "-") mi = true;
+      continue;
+    }
+    mi = false;
+    if(sh == 0)
+      this[this.t++] = x;
+    else if(sh+k > this.DB) {
+      this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh;
+      this[this.t++] = (x>>(this.DB-sh));
+    }
+    else
+      this[this.t-1] |= x<<sh;
+    sh += k;
+    if(sh >= this.DB) sh -= this.DB;
+  }
+  if(k == 8 && (s[0]&0x80) != 0) {
+    this.s = -1;
+    if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh;
+  }
+  this.clamp();
+  if(mi) BigInteger.ZERO.subTo(this,this);
+}
+
+// (protected) clamp off excess high words
+function bnpClamp() {
+  var c = this.s&this.DM;
+  while(this.t > 0 && this[this.t-1] == c) --this.t;
+}
+
+// (public) return string representation in given radix
+function bnToString(b) {
+  if(this.s < 0) return "-"+this.negate().toString(b);
+  var k;
+  if(b == 16) k = 4;
+  else if(b == 8) k = 3;
+  else if(b == 2) k = 1;
+  else if(b == 32) k = 5;
+  else if(b == 4) k = 2;
+  else return this.toRadix(b);
+  var km = (1<<k)-1, d, m = false, r = "", i = this.t;
+  var p = this.DB-(i*this.DB)%k;
+  if(i-- > 0) {
+    if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); }
+    while(i >= 0) {
+      if(p < k) {
+        d = (this[i]&((1<<p)-1))<<(k-p);
+        d |= this[--i]>>(p+=this.DB-k);
+      }
+      else {
+        d = (this[i]>>(p-=k))&km;
+        if(p <= 0) { p += this.DB; --i; }
+      }
+      if(d > 0) m = true;
+      if(m) r += int2char(d);
+    }
+  }
+  return m?r:"0";
+}
+
+// (public) -this
+function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }
+
+// (public) |this|
+function bnAbs() { return (this.s<0)?this.negate():this; }
+
+// (public) return + if this > a, - if this < a, 0 if equal
+function bnCompareTo(a) {
+  var r = this.s-a.s;
+  if(r != 0) return r;
+  var i = this.t;
+  r = i-a.t;
+  if(r != 0) return r;
+  while(--i >= 0) if((r=this[i]-a[i]) != 0) return r;
+  return 0;
+}
+
+// returns bit length of the integer x
+function nbits(x) {
+  var r = 1, t;
+  if((t=x>>>16) != 0) { x = t; r += 16; }
+  if((t=x>>8) != 0) { x = t; r += 8; }
+  if((t=x>>4) != 0) { x = t; r += 4; }
+  if((t=x>>2) != 0) { x = t; r += 2; }
+  if((t=x>>1) != 0) { x = t; r += 1; }
+  return r;
+}
+
+// (public) return the number of bits in "this"
+function bnBitLength() {
+  if(this.t <= 0) return 0;
+  return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));
+}
+
+// (protected) r = this << n*DB
+function bnpDLShiftTo(n,r) {
+  var i;
+  for(i = this.t-1; i >= 0; --i) r[i+n] = this[i];
+  for(i = n-1; i >= 0; --i) r[i] = 0;
+  r.t = this.t+n;
+  r.s = this.s;
+}
+
+// (protected) r = this >> n*DB
+function bnpDRShiftTo(n,r) {
+  for(var i = n; i < this.t; ++i) r[i-n] = this[i];
+  r.t = Math.max(this.t-n,0);
+  r.s = this.s;
+}
+
+// (protected) r = this << n
+function bnpLShiftTo(n,r) {
+  var bs = n%this.DB;
+  var cbs = this.DB-bs;
+  var bm = (1<<cbs)-1;
+  var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i;
+  for(i = this.t-1; i >= 0; --i) {
+    r[i+ds+1] = (this[i]>>cbs)|c;
+    c = (this[i]&bm)<<bs;
+  }
+  for(i = ds-1; i >= 0; --i) r[i] = 0;
+  r[ds] = c;
+  r.t = this.t+ds+1;
+  r.s = this.s;
+  r.clamp();
+}
+
+// (protected) r = this >> n
+function bnpRShiftTo(n,r) {
+  r.s = this.s;
+  var ds = Math.floor(n/this.DB);
+  if(ds >= this.t) { r.t = 0; return; }
+  var bs = n%this.DB;
+  var cbs = this.DB-bs;
+  var bm = (1<<bs)-1;
+  r[0] = this[ds]>>bs;
+  for(var i = ds+1; i < this.t; ++i) {
+    r[i-ds-1] |= (this[i]&bm)<<cbs;
+    r[i-ds] = this[i]>>bs;
+  }
+  if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs;
+  r.t = this.t-ds;
+  r.clamp();
+}
+
+// (protected) r = this - a
+function bnpSubTo(a,r) {
+  var i = 0, c = 0, m = Math.min(a.t,this.t);
+  while(i < m) {
+    c += this[i]-a[i];
+    r[i++] = c&this.DM;
+    c >>= this.DB;
+  }
+  if(a.t < this.t) {
+    c -= a.s;
+    while(i < this.t) {
+      c += this[i];
+      r[i++] = c&this.DM;
+      c >>= this.DB;
+    }
+    c += this.s;
+  }
+  else {
+    c += this.s;
+    while(i < a.t) {
+      c -= a[i];
+      r[i++] = c&this.DM;
+      c >>= this.DB;
+    }
+    c -= a.s;
+  }
+  r.s = (c<0)?-1:0;
+  if(c < -1) r[i++] = this.DV+c;
+  else if(c > 0) r[i++] = c;
+  r.t = i;
+  r.clamp();
+}
+
+// (protected) r = this * a, r != this,a (HAC 14.12)
+// "this" should be the larger one if appropriate.
+function bnpMultiplyTo(a,r) {
+  var x = this.abs(), y = a.abs();
+  var i = x.t;
+  r.t = i+y.t;
+  while(--i >= 0) r[i] = 0;
+  for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t);
+  r.s = 0;
+  r.clamp();
+  if(this.s != a.s) BigInteger.ZERO.subTo(r,r);
+}
+
+// (protected) r = this^2, r != this (HAC 14.16)
+function bnpSquareTo(r) {
+  var x = this.abs();
+  var i = r.t = 2*x.t;
+  while(--i >= 0) r[i] = 0;
+  for(i = 0; i < x.t-1; ++i) {
+    var c = x.am(i,x[i],r,2*i,0,1);
+    if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) {
+      r[i+x.t] -= x.DV;
+      r[i+x.t+1] = 1;
+    }
+  }
+  if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1);
+  r.s = 0;
+  r.clamp();
+}
+
+// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
+// r != q, this != m.  q or r may be null.
+function bnpDivRemTo(m,q,r) {
+  var pm = m.abs();
+  if(pm.t <= 0) return;
+  var pt = this.abs();
+  if(pt.t < pm.t) {
+    if(q != null) q.fromInt(0);
+    if(r != null) this.copyTo(r);
+    return;
+  }
+  if(r == null) r = nbi();
+  var y = nbi(), ts = this.s, ms = m.s;
+  var nsh = this.DB-nbits(pm[pm.t-1]);	// normalize modulus
+  if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); }
+  else { pm.copyTo(y); pt.copyTo(r); }
+  var ys = y.t;
+  var y0 = y[ys-1];
+  if(y0 == 0) return;
+  var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0);
+  var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2;
+  var i = r.t, j = i-ys, t = (q==null)?nbi():q;
+  y.dlShiftTo(j,t);
+  if(r.compareTo(t) >= 0) {
+    r[r.t++] = 1;
+    r.subTo(t,r);
+  }
+  BigInteger.ONE.dlShiftTo(ys,t);
+  t.subTo(y,y);	// "negative" y so we can replace sub with am later
+  while(y.t < ys) y[y.t++] = 0;
+  while(--j >= 0) {
+    // Estimate quotient digit
+    var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);
+    if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) {	// Try it out
+      y.dlShiftTo(j,t);
+      r.subTo(t,r);
+      while(r[i] < --qd) r.subTo(t,r);
+    }
+  }
+  if(q != null) {
+    r.drShiftTo(ys,q);
+    if(ts != ms) BigInteger.ZERO.subTo(q,q);
+  }
+  r.t = ys;
+  r.clamp();
+  if(nsh > 0) r.rShiftTo(nsh,r);	// Denormalize remainder
+  if(ts < 0) BigInteger.ZERO.subTo(r,r);
+}
+
+// (public) this mod a
+function bnMod(a) {
+  var r = nbi();
+  this.abs().divRemTo(a,null,r);
+  if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r);
+  return r;
+}
+
+// Modular reduction using "classic" algorithm
+function Classic(m) { this.m = m; }
+function cConvert(x) {
+  if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
+  else return x;
+}
+function cRevert(x) { return x; }
+function cReduce(x) { x.divRemTo(this.m,null,x); }
+function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
+function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
+
+Classic.prototype.convert = cConvert;
+Classic.prototype.revert = cRevert;
+Classic.prototype.reduce = cReduce;
+Classic.prototype.mulTo = cMulTo;
+Classic.prototype.sqrTo = cSqrTo;
+
+// (protected) return "-1/this % 2^DB"; useful for Mont. reduction
+// justification:
+//         xy == 1 (mod m)
+//         xy =  1+km
+//   xy(2-xy) = (1+km)(1-km)
+// x[y(2-xy)] = 1-k^2m^2
+// x[y(2-xy)] == 1 (mod m^2)
+// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
+// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
+// JS multiply "overflows" differently from C/C++, so care is needed here.
+function bnpInvDigit() {
+  if(this.t < 1) return 0;
+  var x = this[0];
+  if((x&1) == 0) return 0;
+  var y = x&3;		// y == 1/x mod 2^2
+  y = (y*(2-(x&0xf)*y))&0xf;	// y == 1/x mod 2^4
+  y = (y*(2-(x&0xff)*y))&0xff;	// y == 1/x mod 2^8
+  y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff;	// y == 1/x mod 2^16
+  // last step - calculate inverse mod DV directly;
+  // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
+  y = (y*(2-x*y%this.DV))%this.DV;		// y == 1/x mod 2^dbits
+  // we really want the negative inverse, and -DV < y < DV
+  return (y>0)?this.DV-y:-y;
+}
+
+// Montgomery reduction
+function Montgomery(m) {
+  this.m = m;
+  this.mp = m.invDigit();
+  this.mpl = this.mp&0x7fff;
+  this.mph = this.mp>>15;
+  this.um = (1<<(m.DB-15))-1;
+  this.mt2 = 2*m.t;
+}
+
+// xR mod m
+function montConvert(x) {
+  var r = nbi();
+  x.abs().dlShiftTo(this.m.t,r);
+  r.divRemTo(this.m,null,r);
+  if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r);
+  return r;
+}
+
+// x/R mod m
+function montRevert(x) {
+  var r = nbi();
+  x.copyTo(r);
+  this.reduce(r);
+  return r;
+}
+
+// x = x/R mod m (HAC 14.32)
+function montReduce(x) {
+  while(x.t <= this.mt2)	// pad x so am has enough room later
+    x[x.t++] = 0;
+  for(var i = 0; i < this.m.t; ++i) {
+    // faster way of calculating u0 = x[i]*mp mod DV
+    var j = x[i]&0x7fff;
+    var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM;
+    // use am to combine the multiply-shift-add into one call
+    j = i+this.m.t;
+    x[j] += this.m.am(0,u0,x,i,0,this.m.t);
+    // propagate carry
+    while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }
+  }
+  x.clamp();
+  x.drShiftTo(this.m.t,x);
+  if(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
+}
+
+// r = "x^2/R mod m"; x != r
+function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
+
+// r = "xy/R mod m"; x,y != r
+function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
+
+Montgomery.prototype.convert = montConvert;
+Montgomery.prototype.revert = montRevert;
+Montgomery.prototype.reduce = montReduce;
+Montgomery.prototype.mulTo = montMulTo;
+Montgomery.prototype.sqrTo = montSqrTo;
+
+// (protected) true iff this is even
+function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; }
+
+// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
+function bnpExp(e,z) {
+  if(e > 0xffffffff || e < 1) return BigInteger.ONE;
+  var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1;
+  g.copyTo(r);
+  while(--i >= 0) {
+    z.sqrTo(r,r2);
+    if((e&(1<<i)) > 0) z.mulTo(r2,g,r);
+    else { var t = r; r = r2; r2 = t; }
+  }
+  return z.revert(r);
+}
+
+// (public) this^e % m, 0 <= e < 2^32
+function bnModPowInt(e,m) {
+  var z;
+  if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
+  return this.exp(e,z);
+}
+
+// protected
+BigInteger.prototype.copyTo = bnpCopyTo;
+BigInteger.prototype.fromInt = bnpFromInt;
+BigInteger.prototype.fromString = bnpFromString;
+BigInteger.prototype.clamp = bnpClamp;
+BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
+BigInteger.prototype.drShiftTo = bnpDRShiftTo;
+BigInteger.prototype.lShiftTo = bnpLShiftTo;
+BigInteger.prototype.rShiftTo = bnpRShiftTo;
+BigInteger.prototype.subTo = bnpSubTo;
+BigInteger.prototype.multiplyTo = bnpMultiplyTo;
+BigInteger.prototype.squareTo = bnpSquareTo;
+BigInteger.prototype.divRemTo = bnpDivRemTo;
+BigInteger.prototype.invDigit = bnpInvDigit;
+BigInteger.prototype.isEven = bnpIsEven;
+BigInteger.prototype.exp = bnpExp;
+
+// public
+BigInteger.prototype.toString = bnToString;
+BigInteger.prototype.negate = bnNegate;
+BigInteger.prototype.abs = bnAbs;
+BigInteger.prototype.compareTo = bnCompareTo;
+BigInteger.prototype.bitLength = bnBitLength;
+BigInteger.prototype.mod = bnMod;
+BigInteger.prototype.modPowInt = bnModPowInt;
+
+// "constants"
+BigInteger.ZERO = nbv(0);
+BigInteger.ONE = nbv(1);
diff --git a/js/securityLib/jsbn2.js b/contrib/securityLib/jsbn2.js
similarity index 99%
rename from js/securityLib/jsbn2.js
rename to contrib/securityLib/jsbn2.js
index 65063fb..e53e00b 100644
--- a/js/securityLib/jsbn2.js
+++ b/contrib/securityLib/jsbn2.js
@@ -1,648 +1,648 @@
-// Copyright (c) 2005-2009  Tom Wu
-// All Rights Reserved.
-// See "LICENSE" for details.
-
-// Extended JavaScript BN functions, required for RSA private ops.
-
-// Version 1.1: new BigInteger("0", 10) returns "proper" zero
-
-// (public)
-function bnClone() { var r = nbi(); this.copyTo(r); return r; }
-
-// (public) return value as integer
-function bnIntValue() {
-  if(this.s < 0) {
-    if(this.t == 1) return this[0]-this.DV;
-    else if(this.t == 0) return -1;
-  }
-  else if(this.t == 1) return this[0];
-  else if(this.t == 0) return 0;
-  // assumes 16 < DB < 32
-  return ((this[1]&((1<<(32-this.DB))-1))<<this.DB)|this[0];
-}
-
-// (public) return value as byte
-function bnByteValue() { return (this.t==0)?this.s:(this[0]<<24)>>24; }
-
-// (public) return value as short (assumes DB>=16)
-function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; }
-
-// (protected) return x s.t. r^x < DV
-function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); }
-
-// (public) 0 if this == 0, 1 if this > 0
-function bnSigNum() {
-  if(this.s < 0) return -1;
-  else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0;
-  else return 1;
-}
-
-// (protected) convert to radix string
-function bnpToRadix(b) {
-  if(b == null) b = 10;
-  if(this.signum() == 0 || b < 2 || b > 36) return "0";
-  var cs = this.chunkSize(b);
-  var a = Math.pow(b,cs);
-  var d = nbv(a), y = nbi(), z = nbi(), r = "";
-  this.divRemTo(d,y,z);
-  while(y.signum() > 0) {
-    r = (a+z.intValue()).toString(b).substr(1) + r;
-    y.divRemTo(d,y,z);
-  }
-  return z.intValue().toString(b) + r;
-}
-
-// (protected) convert from radix string
-function bnpFromRadix(s,b) {
-  this.fromInt(0);
-  if(b == null) b = 10;
-  var cs = this.chunkSize(b);
-  var d = Math.pow(b,cs), mi = false, j = 0, w = 0;
-  for(var i = 0; i < s.length; ++i) {
-    var x = intAt(s,i);
-    if(x < 0) {
-      if(s.charAt(i) == "-" && this.signum() == 0) mi = true;
-      continue;
-    }
-    w = b*w+x;
-    if(++j >= cs) {
-      this.dMultiply(d);
-      this.dAddOffset(w,0);
-      j = 0;
-      w = 0;
-    }
-  }
-  if(j > 0) {
-    this.dMultiply(Math.pow(b,j));
-    this.dAddOffset(w,0);
-  }
-  if(mi) BigInteger.ZERO.subTo(this,this);
-}
-
-// (protected) alternate constructor
-function bnpFromNumber(a,b,c) {
-  if("number" == typeof b) {
-    // new BigInteger(int,int,RNG)
-    if(a < 2) this.fromInt(1);
-    else {
-      this.fromNumber(a,c);
-      if(!this.testBit(a-1))	// force MSB set
-        this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this);
-      if(this.isEven()) this.dAddOffset(1,0); // force odd
-      while(!this.isProbablePrime(b)) {
-        this.dAddOffset(2,0);
-        if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this);
-      }
-    }
-  }
-  else {
-    // new BigInteger(int,RNG)
-    var x = new Array(), t = a&7;
-    x.length = (a>>3)+1;
-    b.nextBytes(x);
-    if(t > 0) x[0] &= ((1<<t)-1); else x[0] = 0;
-    this.fromString(x,256);
-  }
-}
-
-// (public) convert to bigendian byte array
-function bnToByteArray() {
-  var i = this.t, r = new Array();
-  r[0] = this.s;
-  var p = this.DB-(i*this.DB)%8, d, k = 0;
-  if(i-- > 0) {
-    if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p)
-      r[k++] = d|(this.s<<(this.DB-p));
-    while(i >= 0) {
-      if(p < 8) {
-        d = (this[i]&((1<<p)-1))<<(8-p);
-        d |= this[--i]>>(p+=this.DB-8);
-      }
-      else {
-        d = (this[i]>>(p-=8))&0xff;
-        if(p <= 0) { p += this.DB; --i; }
-      }
-      if((d&0x80) != 0) d |= -256;
-      if(k == 0 && (this.s&0x80) != (d&0x80)) ++k;
-      if(k > 0 || d != this.s) r[k++] = d;
-    }
-  }
-  return r;
-}
-
-function bnEquals(a) { return(this.compareTo(a)==0); }
-function bnMin(a) { return(this.compareTo(a)<0)?this:a; }
-function bnMax(a) { return(this.compareTo(a)>0)?this:a; }
-
-// (protected) r = this op a (bitwise)
-function bnpBitwiseTo(a,op,r) {
-  var i, f, m = Math.min(a.t,this.t);
-  for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]);
-  if(a.t < this.t) {
-    f = a.s&this.DM;
-    for(i = m; i < this.t; ++i) r[i] = op(this[i],f);
-    r.t = this.t;
-  }
-  else {
-    f = this.s&this.DM;
-    for(i = m; i < a.t; ++i) r[i] = op(f,a[i]);
-    r.t = a.t;
-  }
-  r.s = op(this.s,a.s);
-  r.clamp();
-}
-
-// (public) this & a
-function op_and(x,y) { return x&y; }
-function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; }
-
-// (public) this | a
-function op_or(x,y) { return x|y; }
-function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; }
-
-// (public) this ^ a
-function op_xor(x,y) { return x^y; }
-function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; }
-
-// (public) this & ~a
-function op_andnot(x,y) { return x&~y; }
-function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; }
-
-// (public) ~this
-function bnNot() {
-  var r = nbi();
-  for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i];
-  r.t = this.t;
-  r.s = ~this.s;
-  return r;
-}
-
-// (public) this << n
-function bnShiftLeft(n) {
-  var r = nbi();
-  if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r);
-  return r;
-}
-
-// (public) this >> n
-function bnShiftRight(n) {
-  var r = nbi();
-  if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r);
-  return r;
-}
-
-// return index of lowest 1-bit in x, x < 2^31
-function lbit(x) {
-  if(x == 0) return -1;
-  var r = 0;
-  if((x&0xffff) == 0) { x >>= 16; r += 16; }
-  if((x&0xff) == 0) { x >>= 8; r += 8; }
-  if((x&0xf) == 0) { x >>= 4; r += 4; }
-  if((x&3) == 0) { x >>= 2; r += 2; }
-  if((x&1) == 0) ++r;
-  return r;
-}
-
-// (public) returns index of lowest 1-bit (or -1 if none)
-function bnGetLowestSetBit() {
-  for(var i = 0; i < this.t; ++i)
-    if(this[i] != 0) return i*this.DB+lbit(this[i]);
-  if(this.s < 0) return this.t*this.DB;
-  return -1;
-}
-
-// return number of 1 bits in x
-function cbit(x) {
-  var r = 0;
-  while(x != 0) { x &= x-1; ++r; }
-  return r;
-}
-
-// (public) return number of set bits
-function bnBitCount() {
-  var r = 0, x = this.s&this.DM;
-  for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x);
-  return r;
-}
-
-// (public) true iff nth bit is set
-function bnTestBit(n) {
-  var j = Math.floor(n/this.DB);
-  if(j >= this.t) return(this.s!=0);
-  return((this[j]&(1<<(n%this.DB)))!=0);
-}
-
-// (protected) this op (1<<n)
-function bnpChangeBit(n,op) {
-  var r = BigInteger.ONE.shiftLeft(n);
-  this.bitwiseTo(r,op,r);
-  return r;
-}
-
-// (public) this | (1<<n)
-function bnSetBit(n) { return this.changeBit(n,op_or); }
-
-// (public) this & ~(1<<n)
-function bnClearBit(n) { return this.changeBit(n,op_andnot); }
-
-// (public) this ^ (1<<n)
-function bnFlipBit(n) { return this.changeBit(n,op_xor); }
-
-// (protected) r = this + a
-function bnpAddTo(a,r) {
-  var i = 0, c = 0, m = Math.min(a.t,this.t);
-  while(i < m) {
-    c += this[i]+a[i];
-    r[i++] = c&this.DM;
-    c >>= this.DB;
-  }
-  if(a.t < this.t) {
-    c += a.s;
-    while(i < this.t) {
-      c += this[i];
-      r[i++] = c&this.DM;
-      c >>= this.DB;
-    }
-    c += this.s;
-  }
-  else {
-    c += this.s;
-    while(i < a.t) {
-      c += a[i];
-      r[i++] = c&this.DM;
-      c >>= this.DB;
-    }
-    c += a.s;
-  }
-  r.s = (c<0)?-1:0;
-  if(c > 0) r[i++] = c;
-  else if(c < -1) r[i++] = this.DV+c;
-  r.t = i;
-  r.clamp();
-}
-
-// (public) this + a
-function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; }
-
-// (public) this - a
-function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; }
-
-// (public) this * a
-function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; }
-
-// (public) this / a
-function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; }
-
-// (public) this % a
-function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; }
-
-// (public) [this/a,this%a]
-function bnDivideAndRemainder(a) {
-  var q = nbi(), r = nbi();
-  this.divRemTo(a,q,r);
-  return new Array(q,r);
-}
-
-// (protected) this *= n, this >= 0, 1 < n < DV
-function bnpDMultiply(n) {
-  this[this.t] = this.am(0,n-1,this,0,0,this.t);
-  ++this.t;
-  this.clamp();
-}
-
-// (protected) this += n << w words, this >= 0
-function bnpDAddOffset(n,w) {
-  if(n == 0) return;
-  while(this.t <= w) this[this.t++] = 0;
-  this[w] += n;
-  while(this[w] >= this.DV) {
-    this[w] -= this.DV;
-    if(++w >= this.t) this[this.t++] = 0;
-    ++this[w];
-  }
-}
-
-// A "null" reducer
-function NullExp() {}
-function nNop(x) { return x; }
-function nMulTo(x,y,r) { x.multiplyTo(y,r); }
-function nSqrTo(x,r) { x.squareTo(r); }
-
-NullExp.prototype.convert = nNop;
-NullExp.prototype.revert = nNop;
-NullExp.prototype.mulTo = nMulTo;
-NullExp.prototype.sqrTo = nSqrTo;
-
-// (public) this^e
-function bnPow(e) { return this.exp(e,new NullExp()); }
-
-// (protected) r = lower n words of "this * a", a.t <= n
-// "this" should be the larger one if appropriate.
-function bnpMultiplyLowerTo(a,n,r) {
-  var i = Math.min(this.t+a.t,n);
-  r.s = 0; // assumes a,this >= 0
-  r.t = i;
-  while(i > 0) r[--i] = 0;
-  var j;
-  for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t);
-  for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i);
-  r.clamp();
-}
-
-// (protected) r = "this * a" without lower n words, n > 0
-// "this" should be the larger one if appropriate.
-function bnpMultiplyUpperTo(a,n,r) {
-  --n;
-  var i = r.t = this.t+a.t-n;
-  r.s = 0; // assumes a,this >= 0
-  while(--i >= 0) r[i] = 0;
-  for(i = Math.max(n-this.t,0); i < a.t; ++i)
-    r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n);
-  r.clamp();
-  r.drShiftTo(1,r);
-}
-
-// Barrett modular reduction
-function Barrett(m) {
-  // setup Barrett
-  this.r2 = nbi();
-  this.q3 = nbi();
-  BigInteger.ONE.dlShiftTo(2*m.t,this.r2);
-  this.mu = this.r2.divide(m);
-  this.m = m;
-}
-
-function barrettConvert(x) {
-  if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m);
-  else if(x.compareTo(this.m) < 0) return x;
-  else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; }
-}
-
-function barrettRevert(x) { return x; }
-
-// x = x mod m (HAC 14.42)
-function barrettReduce(x) {
-  x.drShiftTo(this.m.t-1,this.r2);
-  if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); }
-  this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);
-  this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);
-  while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1);
-  x.subTo(this.r2,x);
-  while(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
-}
-
-// r = x^2 mod m; x != r
-function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
-
-// r = x*y mod m; x,y != r
-function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
-
-Barrett.prototype.convert = barrettConvert;
-Barrett.prototype.revert = barrettRevert;
-Barrett.prototype.reduce = barrettReduce;
-Barrett.prototype.mulTo = barrettMulTo;
-Barrett.prototype.sqrTo = barrettSqrTo;
-
-// (public) this^e % m (HAC 14.85)
-function bnModPow(e,m) {
-  var i = e.bitLength(), k, r = nbv(1), z;
-  if(i <= 0) return r;
-  else if(i < 18) k = 1;
-  else if(i < 48) k = 3;
-  else if(i < 144) k = 4;
-  else if(i < 768) k = 5;
-  else k = 6;
-  if(i < 8)
-    z = new Classic(m);
-  else if(m.isEven())
-    z = new Barrett(m);
-  else
-    z = new Montgomery(m);
-
-  // precomputation
-  var g = new Array(), n = 3, k1 = k-1, km = (1<<k)-1;
-  g[1] = z.convert(this);
-  if(k > 1) {
-    var g2 = nbi();
-    z.sqrTo(g[1],g2);
-    while(n <= km) {
-      g[n] = nbi();
-      z.mulTo(g2,g[n-2],g[n]);
-      n += 2;
-    }
-  }
-
-  var j = e.t-1, w, is1 = true, r2 = nbi(), t;
-  i = nbits(e[j])-1;
-  while(j >= 0) {
-    if(i >= k1) w = (e[j]>>(i-k1))&km;
-    else {
-      w = (e[j]&((1<<(i+1))-1))<<(k1-i);
-      if(j > 0) w |= e[j-1]>>(this.DB+i-k1);
-    }
-
-    n = k;
-    while((w&1) == 0) { w >>= 1; --n; }
-    if((i -= n) < 0) { i += this.DB; --j; }
-    if(is1) {	// ret == 1, don't bother squaring or multiplying it
-      g[w].copyTo(r);
-      is1 = false;
-    }
-    else {
-      while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; }
-      if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; }
-      z.mulTo(r2,g[w],r);
-    }
-
-    while(j >= 0 && (e[j]&(1<<i)) == 0) {
-      z.sqrTo(r,r2); t = r; r = r2; r2 = t;
-      if(--i < 0) { i = this.DB-1; --j; }
-    }
-  }
-  return z.revert(r);
-}
-
-// (public) gcd(this,a) (HAC 14.54)
-function bnGCD(a) {
-  var x = (this.s<0)?this.negate():this.clone();
-  var y = (a.s<0)?a.negate():a.clone();
-  if(x.compareTo(y) < 0) { var t = x; x = y; y = t; }
-  var i = x.getLowestSetBit(), g = y.getLowestSetBit();
-  if(g < 0) return x;
-  if(i < g) g = i;
-  if(g > 0) {
-    x.rShiftTo(g,x);
-    y.rShiftTo(g,y);
-  }
-  while(x.signum() > 0) {
-    if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x);
-    if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y);
-    if(x.compareTo(y) >= 0) {
-      x.subTo(y,x);
-      x.rShiftTo(1,x);
-    }
-    else {
-      y.subTo(x,y);
-      y.rShiftTo(1,y);
-    }
-  }
-  if(g > 0) y.lShiftTo(g,y);
-  return y;
-}
-
-// (protected) this % n, n < 2^26
-function bnpModInt(n) {
-  if(n <= 0) return 0;
-  var d = this.DV%n, r = (this.s<0)?n-1:0;
-  if(this.t > 0)
-    if(d == 0) r = this[0]%n;
-    else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n;
-  return r;
-}
-
-// (public) 1/this % m (HAC 14.61)
-function bnModInverse(m) {
-  var ac = m.isEven();
-  if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO;
-  var u = m.clone(), v = this.clone();
-  var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1);
-  while(u.signum() != 0) {
-    while(u.isEven()) {
-      u.rShiftTo(1,u);
-      if(ac) {
-        if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); }
-        a.rShiftTo(1,a);
-      }
-      else if(!b.isEven()) b.subTo(m,b);
-      b.rShiftTo(1,b);
-    }
-    while(v.isEven()) {
-      v.rShiftTo(1,v);
-      if(ac) {
-        if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); }
-        c.rShiftTo(1,c);
-      }
-      else if(!d.isEven()) d.subTo(m,d);
-      d.rShiftTo(1,d);
-    }
-    if(u.compareTo(v) >= 0) {
-      u.subTo(v,u);
-      if(ac) a.subTo(c,a);
-      b.subTo(d,b);
-    }
-    else {
-      v.subTo(u,v);
-      if(ac) c.subTo(a,c);
-      d.subTo(b,d);
-    }
-  }
-  if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;
-  if(d.compareTo(m) >= 0) return d.subtract(m);
-  if(d.signum() < 0) d.addTo(m,d); else return d;
-  if(d.signum() < 0) return d.add(m); else return d;
-}
-
-var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509];
-var lplim = (1<<26)/lowprimes[lowprimes.length-1];
-
-// (public) test primality with certainty >= 1-.5^t
-function bnIsProbablePrime(t) {
-  var i, x = this.abs();
-  if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) {
-    for(i = 0; i < lowprimes.length; ++i)
-      if(x[0] == lowprimes[i]) return true;
-    return false;
-  }
-  if(x.isEven()) return false;
-  i = 1;
-  while(i < lowprimes.length) {
-    var m = lowprimes[i], j = i+1;
-    while(j < lowprimes.length && m < lplim) m *= lowprimes[j++];
-    m = x.modInt(m);
-    while(i < j) if(m%lowprimes[i++] == 0) return false;
-  }
-  return x.millerRabin(t);
-}
-
-// (protected) true if probably prime (HAC 4.24, Miller-Rabin)
-function bnpMillerRabin(t) {
-  var n1 = this.subtract(BigInteger.ONE);
-  var k = n1.getLowestSetBit();
-  if(k <= 0) return false;
-  var r = n1.shiftRight(k);
-  t = (t+1)>>1;
-  if(t > lowprimes.length) t = lowprimes.length;
-  var a = nbi();
-  for(var i = 0; i < t; ++i) {
-    a.fromInt(lowprimes[i]);
-    var y = a.modPow(r,this);
-    if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
-      var j = 1;
-      while(j++ < k && y.compareTo(n1) != 0) {
-        y = y.modPowInt(2,this);
-        if(y.compareTo(BigInteger.ONE) == 0) return false;
-      }
-      if(y.compareTo(n1) != 0) return false;
-    }
-  }
-  return true;
-}
-
-// protected
-BigInteger.prototype.chunkSize = bnpChunkSize;
-BigInteger.prototype.toRadix = bnpToRadix;
-BigInteger.prototype.fromRadix = bnpFromRadix;
-BigInteger.prototype.fromNumber = bnpFromNumber;
-BigInteger.prototype.bitwiseTo = bnpBitwiseTo;
-BigInteger.prototype.changeBit = bnpChangeBit;
-BigInteger.prototype.addTo = bnpAddTo;
-BigInteger.prototype.dMultiply = bnpDMultiply;
-BigInteger.prototype.dAddOffset = bnpDAddOffset;
-BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;
-BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;
-BigInteger.prototype.modInt = bnpModInt;
-BigInteger.prototype.millerRabin = bnpMillerRabin;
-
-// public
-BigInteger.prototype.clone = bnClone;
-BigInteger.prototype.intValue = bnIntValue;
-BigInteger.prototype.byteValue = bnByteValue;
-BigInteger.prototype.shortValue = bnShortValue;
-BigInteger.prototype.signum = bnSigNum;
-BigInteger.prototype.toByteArray = bnToByteArray;
-BigInteger.prototype.equals = bnEquals;
-BigInteger.prototype.min = bnMin;
-BigInteger.prototype.max = bnMax;
-BigInteger.prototype.and = bnAnd;
-BigInteger.prototype.or = bnOr;
-BigInteger.prototype.xor = bnXor;
-BigInteger.prototype.andNot = bnAndNot;
-BigInteger.prototype.not = bnNot;
-BigInteger.prototype.shiftLeft = bnShiftLeft;
-BigInteger.prototype.shiftRight = bnShiftRight;
-BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;
-BigInteger.prototype.bitCount = bnBitCount;
-BigInteger.prototype.testBit = bnTestBit;
-BigInteger.prototype.setBit = bnSetBit;
-BigInteger.prototype.clearBit = bnClearBit;
-BigInteger.prototype.flipBit = bnFlipBit;
-BigInteger.prototype.add = bnAdd;
-BigInteger.prototype.subtract = bnSubtract;
-BigInteger.prototype.multiply = bnMultiply;
-BigInteger.prototype.divide = bnDivide;
-BigInteger.prototype.remainder = bnRemainder;
-BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;
-BigInteger.prototype.modPow = bnModPow;
-BigInteger.prototype.modInverse = bnModInverse;
-BigInteger.prototype.pow = bnPow;
-BigInteger.prototype.gcd = bnGCD;
-BigInteger.prototype.isProbablePrime = bnIsProbablePrime;
-
-// BigInteger interfaces not implemented in jsbn:
-
-// BigInteger(int signum, byte[] magnitude)
-// double doubleValue()
-// float floatValue()
-// int hashCode()
-// long longValue()
-// static BigInteger valueOf(long val)
+// Copyright (c) 2005-2009  Tom Wu
+// All Rights Reserved.
+// See "LICENSE" for details.
+
+// Extended JavaScript BN functions, required for RSA private ops.
+
+// Version 1.1: new BigInteger("0", 10) returns "proper" zero
+
+// (public)
+function bnClone() { var r = nbi(); this.copyTo(r); return r; }
+
+// (public) return value as integer
+function bnIntValue() {
+  if(this.s < 0) {
+    if(this.t == 1) return this[0]-this.DV;
+    else if(this.t == 0) return -1;
+  }
+  else if(this.t == 1) return this[0];
+  else if(this.t == 0) return 0;
+  // assumes 16 < DB < 32
+  return ((this[1]&((1<<(32-this.DB))-1))<<this.DB)|this[0];
+}
+
+// (public) return value as byte
+function bnByteValue() { return (this.t==0)?this.s:(this[0]<<24)>>24; }
+
+// (public) return value as short (assumes DB>=16)
+function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; }
+
+// (protected) return x s.t. r^x < DV
+function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); }
+
+// (public) 0 if this == 0, 1 if this > 0
+function bnSigNum() {
+  if(this.s < 0) return -1;
+  else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0;
+  else return 1;
+}
+
+// (protected) convert to radix string
+function bnpToRadix(b) {
+  if(b == null) b = 10;
+  if(this.signum() == 0 || b < 2 || b > 36) return "0";
+  var cs = this.chunkSize(b);
+  var a = Math.pow(b,cs);
+  var d = nbv(a), y = nbi(), z = nbi(), r = "";
+  this.divRemTo(d,y,z);
+  while(y.signum() > 0) {
+    r = (a+z.intValue()).toString(b).substr(1) + r;
+    y.divRemTo(d,y,z);
+  }
+  return z.intValue().toString(b) + r;
+}
+
+// (protected) convert from radix string
+function bnpFromRadix(s,b) {
+  this.fromInt(0);
+  if(b == null) b = 10;
+  var cs = this.chunkSize(b);
+  var d = Math.pow(b,cs), mi = false, j = 0, w = 0;
+  for(var i = 0; i < s.length; ++i) {
+    var x = intAt(s,i);
+    if(x < 0) {
+      if(s.charAt(i) == "-" && this.signum() == 0) mi = true;
+      continue;
+    }
+    w = b*w+x;
+    if(++j >= cs) {
+      this.dMultiply(d);
+      this.dAddOffset(w,0);
+      j = 0;
+      w = 0;
+    }
+  }
+  if(j > 0) {
+    this.dMultiply(Math.pow(b,j));
+    this.dAddOffset(w,0);
+  }
+  if(mi) BigInteger.ZERO.subTo(this,this);
+}
+
+// (protected) alternate constructor
+function bnpFromNumber(a,b,c) {
+  if("number" == typeof b) {
+    // new BigInteger(int,int,RNG)
+    if(a < 2) this.fromInt(1);
+    else {
+      this.fromNumber(a,c);
+      if(!this.testBit(a-1))	// force MSB set
+        this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this);
+      if(this.isEven()) this.dAddOffset(1,0); // force odd
+      while(!this.isProbablePrime(b)) {
+        this.dAddOffset(2,0);
+        if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this);
+      }
+    }
+  }
+  else {
+    // new BigInteger(int,RNG)
+    var x = new Array(), t = a&7;
+    x.length = (a>>3)+1;
+    b.nextBytes(x);
+    if(t > 0) x[0] &= ((1<<t)-1); else x[0] = 0;
+    this.fromString(x,256);
+  }
+}
+
+// (public) convert to bigendian byte array
+function bnToByteArray() {
+  var i = this.t, r = new Array();
+  r[0] = this.s;
+  var p = this.DB-(i*this.DB)%8, d, k = 0;
+  if(i-- > 0) {
+    if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p)
+      r[k++] = d|(this.s<<(this.DB-p));
+    while(i >= 0) {
+      if(p < 8) {
+        d = (this[i]&((1<<p)-1))<<(8-p);
+        d |= this[--i]>>(p+=this.DB-8);
+      }
+      else {
+        d = (this[i]>>(p-=8))&0xff;
+        if(p <= 0) { p += this.DB; --i; }
+      }
+      if((d&0x80) != 0) d |= -256;
+      if(k == 0 && (this.s&0x80) != (d&0x80)) ++k;
+      if(k > 0 || d != this.s) r[k++] = d;
+    }
+  }
+  return r;
+}
+
+function bnEquals(a) { return(this.compareTo(a)==0); }
+function bnMin(a) { return(this.compareTo(a)<0)?this:a; }
+function bnMax(a) { return(this.compareTo(a)>0)?this:a; }
+
+// (protected) r = this op a (bitwise)
+function bnpBitwiseTo(a,op,r) {
+  var i, f, m = Math.min(a.t,this.t);
+  for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]);
+  if(a.t < this.t) {
+    f = a.s&this.DM;
+    for(i = m; i < this.t; ++i) r[i] = op(this[i],f);
+    r.t = this.t;
+  }
+  else {
+    f = this.s&this.DM;
+    for(i = m; i < a.t; ++i) r[i] = op(f,a[i]);
+    r.t = a.t;
+  }
+  r.s = op(this.s,a.s);
+  r.clamp();
+}
+
+// (public) this & a
+function op_and(x,y) { return x&y; }
+function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; }
+
+// (public) this | a
+function op_or(x,y) { return x|y; }
+function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; }
+
+// (public) this ^ a
+function op_xor(x,y) { return x^y; }
+function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; }
+
+// (public) this & ~a
+function op_andnot(x,y) { return x&~y; }
+function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; }
+
+// (public) ~this
+function bnNot() {
+  var r = nbi();
+  for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i];
+  r.t = this.t;
+  r.s = ~this.s;
+  return r;
+}
+
+// (public) this << n
+function bnShiftLeft(n) {
+  var r = nbi();
+  if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r);
+  return r;
+}
+
+// (public) this >> n
+function bnShiftRight(n) {
+  var r = nbi();
+  if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r);
+  return r;
+}
+
+// return index of lowest 1-bit in x, x < 2^31
+function lbit(x) {
+  if(x == 0) return -1;
+  var r = 0;
+  if((x&0xffff) == 0) { x >>= 16; r += 16; }
+  if((x&0xff) == 0) { x >>= 8; r += 8; }
+  if((x&0xf) == 0) { x >>= 4; r += 4; }
+  if((x&3) == 0) { x >>= 2; r += 2; }
+  if((x&1) == 0) ++r;
+  return r;
+}
+
+// (public) returns index of lowest 1-bit (or -1 if none)
+function bnGetLowestSetBit() {
+  for(var i = 0; i < this.t; ++i)
+    if(this[i] != 0) return i*this.DB+lbit(this[i]);
+  if(this.s < 0) return this.t*this.DB;
+  return -1;
+}
+
+// return number of 1 bits in x
+function cbit(x) {
+  var r = 0;
+  while(x != 0) { x &= x-1; ++r; }
+  return r;
+}
+
+// (public) return number of set bits
+function bnBitCount() {
+  var r = 0, x = this.s&this.DM;
+  for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x);
+  return r;
+}
+
+// (public) true iff nth bit is set
+function bnTestBit(n) {
+  var j = Math.floor(n/this.DB);
+  if(j >= this.t) return(this.s!=0);
+  return((this[j]&(1<<(n%this.DB)))!=0);
+}
+
+// (protected) this op (1<<n)
+function bnpChangeBit(n,op) {
+  var r = BigInteger.ONE.shiftLeft(n);
+  this.bitwiseTo(r,op,r);
+  return r;
+}
+
+// (public) this | (1<<n)
+function bnSetBit(n) { return this.changeBit(n,op_or); }
+
+// (public) this & ~(1<<n)
+function bnClearBit(n) { return this.changeBit(n,op_andnot); }
+
+// (public) this ^ (1<<n)
+function bnFlipBit(n) { return this.changeBit(n,op_xor); }
+
+// (protected) r = this + a
+function bnpAddTo(a,r) {
+  var i = 0, c = 0, m = Math.min(a.t,this.t);
+  while(i < m) {
+    c += this[i]+a[i];
+    r[i++] = c&this.DM;
+    c >>= this.DB;
+  }
+  if(a.t < this.t) {
+    c += a.s;
+    while(i < this.t) {
+      c += this[i];
+      r[i++] = c&this.DM;
+      c >>= this.DB;
+    }
+    c += this.s;
+  }
+  else {
+    c += this.s;
+    while(i < a.t) {
+      c += a[i];
+      r[i++] = c&this.DM;
+      c >>= this.DB;
+    }
+    c += a.s;
+  }
+  r.s = (c<0)?-1:0;
+  if(c > 0) r[i++] = c;
+  else if(c < -1) r[i++] = this.DV+c;
+  r.t = i;
+  r.clamp();
+}
+
+// (public) this + a
+function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; }
+
+// (public) this - a
+function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; }
+
+// (public) this * a
+function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; }
+
+// (public) this / a
+function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; }
+
+// (public) this % a
+function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; }
+
+// (public) [this/a,this%a]
+function bnDivideAndRemainder(a) {
+  var q = nbi(), r = nbi();
+  this.divRemTo(a,q,r);
+  return new Array(q,r);
+}
+
+// (protected) this *= n, this >= 0, 1 < n < DV
+function bnpDMultiply(n) {
+  this[this.t] = this.am(0,n-1,this,0,0,this.t);
+  ++this.t;
+  this.clamp();
+}
+
+// (protected) this += n << w words, this >= 0
+function bnpDAddOffset(n,w) {
+  if(n == 0) return;
+  while(this.t <= w) this[this.t++] = 0;
+  this[w] += n;
+  while(this[w] >= this.DV) {
+    this[w] -= this.DV;
+    if(++w >= this.t) this[this.t++] = 0;
+    ++this[w];
+  }
+}
+
+// A "null" reducer
+function NullExp() {}
+function nNop(x) { return x; }
+function nMulTo(x,y,r) { x.multiplyTo(y,r); }
+function nSqrTo(x,r) { x.squareTo(r); }
+
+NullExp.prototype.convert = nNop;
+NullExp.prototype.revert = nNop;
+NullExp.prototype.mulTo = nMulTo;
+NullExp.prototype.sqrTo = nSqrTo;
+
+// (public) this^e
+function bnPow(e) { return this.exp(e,new NullExp()); }
+
+// (protected) r = lower n words of "this * a", a.t <= n
+// "this" should be the larger one if appropriate.
+function bnpMultiplyLowerTo(a,n,r) {
+  var i = Math.min(this.t+a.t,n);
+  r.s = 0; // assumes a,this >= 0
+  r.t = i;
+  while(i > 0) r[--i] = 0;
+  var j;
+  for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t);
+  for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i);
+  r.clamp();
+}
+
+// (protected) r = "this * a" without lower n words, n > 0
+// "this" should be the larger one if appropriate.
+function bnpMultiplyUpperTo(a,n,r) {
+  --n;
+  var i = r.t = this.t+a.t-n;
+  r.s = 0; // assumes a,this >= 0
+  while(--i >= 0) r[i] = 0;
+  for(i = Math.max(n-this.t,0); i < a.t; ++i)
+    r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n);
+  r.clamp();
+  r.drShiftTo(1,r);
+}
+
+// Barrett modular reduction
+function Barrett(m) {
+  // setup Barrett
+  this.r2 = nbi();
+  this.q3 = nbi();
+  BigInteger.ONE.dlShiftTo(2*m.t,this.r2);
+  this.mu = this.r2.divide(m);
+  this.m = m;
+}
+
+function barrettConvert(x) {
+  if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m);
+  else if(x.compareTo(this.m) < 0) return x;
+  else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; }
+}
+
+function barrettRevert(x) { return x; }
+
+// x = x mod m (HAC 14.42)
+function barrettReduce(x) {
+  x.drShiftTo(this.m.t-1,this.r2);
+  if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); }
+  this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);
+  this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);
+  while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1);
+  x.subTo(this.r2,x);
+  while(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
+}
+
+// r = x^2 mod m; x != r
+function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
+
+// r = x*y mod m; x,y != r
+function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
+
+Barrett.prototype.convert = barrettConvert;
+Barrett.prototype.revert = barrettRevert;
+Barrett.prototype.reduce = barrettReduce;
+Barrett.prototype.mulTo = barrettMulTo;
+Barrett.prototype.sqrTo = barrettSqrTo;
+
+// (public) this^e % m (HAC 14.85)
+function bnModPow(e,m) {
+  var i = e.bitLength(), k, r = nbv(1), z;
+  if(i <= 0) return r;
+  else if(i < 18) k = 1;
+  else if(i < 48) k = 3;
+  else if(i < 144) k = 4;
+  else if(i < 768) k = 5;
+  else k = 6;
+  if(i < 8)
+    z = new Classic(m);
+  else if(m.isEven())
+    z = new Barrett(m);
+  else
+    z = new Montgomery(m);
+
+  // precomputation
+  var g = new Array(), n = 3, k1 = k-1, km = (1<<k)-1;
+  g[1] = z.convert(this);
+  if(k > 1) {
+    var g2 = nbi();
+    z.sqrTo(g[1],g2);
+    while(n <= km) {
+      g[n] = nbi();
+      z.mulTo(g2,g[n-2],g[n]);
+      n += 2;
+    }
+  }
+
+  var j = e.t-1, w, is1 = true, r2 = nbi(), t;
+  i = nbits(e[j])-1;
+  while(j >= 0) {
+    if(i >= k1) w = (e[j]>>(i-k1))&km;
+    else {
+      w = (e[j]&((1<<(i+1))-1))<<(k1-i);
+      if(j > 0) w |= e[j-1]>>(this.DB+i-k1);
+    }
+
+    n = k;
+    while((w&1) == 0) { w >>= 1; --n; }
+    if((i -= n) < 0) { i += this.DB; --j; }
+    if(is1) {	// ret == 1, don't bother squaring or multiplying it
+      g[w].copyTo(r);
+      is1 = false;
+    }
+    else {
+      while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; }
+      if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; }
+      z.mulTo(r2,g[w],r);
+    }
+
+    while(j >= 0 && (e[j]&(1<<i)) == 0) {
+      z.sqrTo(r,r2); t = r; r = r2; r2 = t;
+      if(--i < 0) { i = this.DB-1; --j; }
+    }
+  }
+  return z.revert(r);
+}
+
+// (public) gcd(this,a) (HAC 14.54)
+function bnGCD(a) {
+  var x = (this.s<0)?this.negate():this.clone();
+  var y = (a.s<0)?a.negate():a.clone();
+  if(x.compareTo(y) < 0) { var t = x; x = y; y = t; }
+  var i = x.getLowestSetBit(), g = y.getLowestSetBit();
+  if(g < 0) return x;
+  if(i < g) g = i;
+  if(g > 0) {
+    x.rShiftTo(g,x);
+    y.rShiftTo(g,y);
+  }
+  while(x.signum() > 0) {
+    if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x);
+    if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y);
+    if(x.compareTo(y) >= 0) {
+      x.subTo(y,x);
+      x.rShiftTo(1,x);
+    }
+    else {
+      y.subTo(x,y);
+      y.rShiftTo(1,y);
+    }
+  }
+  if(g > 0) y.lShiftTo(g,y);
+  return y;
+}
+
+// (protected) this % n, n < 2^26
+function bnpModInt(n) {
+  if(n <= 0) return 0;
+  var d = this.DV%n, r = (this.s<0)?n-1:0;
+  if(this.t > 0)
+    if(d == 0) r = this[0]%n;
+    else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n;
+  return r;
+}
+
+// (public) 1/this % m (HAC 14.61)
+function bnModInverse(m) {
+  var ac = m.isEven();
+  if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO;
+  var u = m.clone(), v = this.clone();
+  var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1);
+  while(u.signum() != 0) {
+    while(u.isEven()) {
+      u.rShiftTo(1,u);
+      if(ac) {
+        if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); }
+        a.rShiftTo(1,a);
+      }
+      else if(!b.isEven()) b.subTo(m,b);
+      b.rShiftTo(1,b);
+    }
+    while(v.isEven()) {
+      v.rShiftTo(1,v);
+      if(ac) {
+        if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); }
+        c.rShiftTo(1,c);
+      }
+      else if(!d.isEven()) d.subTo(m,d);
+      d.rShiftTo(1,d);
+    }
+    if(u.compareTo(v) >= 0) {
+      u.subTo(v,u);
+      if(ac) a.subTo(c,a);
+      b.subTo(d,b);
+    }
+    else {
+      v.subTo(u,v);
+      if(ac) c.subTo(a,c);
+      d.subTo(b,d);
+    }
+  }
+  if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;
+  if(d.compareTo(m) >= 0) return d.subtract(m);
+  if(d.signum() < 0) d.addTo(m,d); else return d;
+  if(d.signum() < 0) return d.add(m); else return d;
+}
+
+var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509];
+var lplim = (1<<26)/lowprimes[lowprimes.length-1];
+
+// (public) test primality with certainty >= 1-.5^t
+function bnIsProbablePrime(t) {
+  var i, x = this.abs();
+  if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) {
+    for(i = 0; i < lowprimes.length; ++i)
+      if(x[0] == lowprimes[i]) return true;
+    return false;
+  }
+  if(x.isEven()) return false;
+  i = 1;
+  while(i < lowprimes.length) {
+    var m = lowprimes[i], j = i+1;
+    while(j < lowprimes.length && m < lplim) m *= lowprimes[j++];
+    m = x.modInt(m);
+    while(i < j) if(m%lowprimes[i++] == 0) return false;
+  }
+  return x.millerRabin(t);
+}
+
+// (protected) true if probably prime (HAC 4.24, Miller-Rabin)
+function bnpMillerRabin(t) {
+  var n1 = this.subtract(BigInteger.ONE);
+  var k = n1.getLowestSetBit();
+  if(k <= 0) return false;
+  var r = n1.shiftRight(k);
+  t = (t+1)>>1;
+  if(t > lowprimes.length) t = lowprimes.length;
+  var a = nbi();
+  for(var i = 0; i < t; ++i) {
+    a.fromInt(lowprimes[i]);
+    var y = a.modPow(r,this);
+    if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
+      var j = 1;
+      while(j++ < k && y.compareTo(n1) != 0) {
+        y = y.modPowInt(2,this);
+        if(y.compareTo(BigInteger.ONE) == 0) return false;
+      }
+      if(y.compareTo(n1) != 0) return false;
+    }
+  }
+  return true;
+}
+
+// protected
+BigInteger.prototype.chunkSize = bnpChunkSize;
+BigInteger.prototype.toRadix = bnpToRadix;
+BigInteger.prototype.fromRadix = bnpFromRadix;
+BigInteger.prototype.fromNumber = bnpFromNumber;
+BigInteger.prototype.bitwiseTo = bnpBitwiseTo;
+BigInteger.prototype.changeBit = bnpChangeBit;
+BigInteger.prototype.addTo = bnpAddTo;
+BigInteger.prototype.dMultiply = bnpDMultiply;
+BigInteger.prototype.dAddOffset = bnpDAddOffset;
+BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;
+BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;
+BigInteger.prototype.modInt = bnpModInt;
+BigInteger.prototype.millerRabin = bnpMillerRabin;
+
+// public
+BigInteger.prototype.clone = bnClone;
+BigInteger.prototype.intValue = bnIntValue;
+BigInteger.prototype.byteValue = bnByteValue;
+BigInteger.prototype.shortValue = bnShortValue;
+BigInteger.prototype.signum = bnSigNum;
+BigInteger.prototype.toByteArray = bnToByteArray;
+BigInteger.prototype.equals = bnEquals;
+BigInteger.prototype.min = bnMin;
+BigInteger.prototype.max = bnMax;
+BigInteger.prototype.and = bnAnd;
+BigInteger.prototype.or = bnOr;
+BigInteger.prototype.xor = bnXor;
+BigInteger.prototype.andNot = bnAndNot;
+BigInteger.prototype.not = bnNot;
+BigInteger.prototype.shiftLeft = bnShiftLeft;
+BigInteger.prototype.shiftRight = bnShiftRight;
+BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;
+BigInteger.prototype.bitCount = bnBitCount;
+BigInteger.prototype.testBit = bnTestBit;
+BigInteger.prototype.setBit = bnSetBit;
+BigInteger.prototype.clearBit = bnClearBit;
+BigInteger.prototype.flipBit = bnFlipBit;
+BigInteger.prototype.add = bnAdd;
+BigInteger.prototype.subtract = bnSubtract;
+BigInteger.prototype.multiply = bnMultiply;
+BigInteger.prototype.divide = bnDivide;
+BigInteger.prototype.remainder = bnRemainder;
+BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;
+BigInteger.prototype.modPow = bnModPow;
+BigInteger.prototype.modInverse = bnModInverse;
+BigInteger.prototype.pow = bnPow;
+BigInteger.prototype.gcd = bnGCD;
+BigInteger.prototype.isProbablePrime = bnIsProbablePrime;
+
+// BigInteger interfaces not implemented in jsbn:
+
+// BigInteger(int signum, byte[] magnitude)
+// double doubleValue()
+// float floatValue()
+// int hashCode()
+// long longValue()
+// static BigInteger valueOf(long val)
diff --git a/js/securityLib/md5.js b/contrib/securityLib/md5.js
similarity index 99%
rename from js/securityLib/md5.js
rename to contrib/securityLib/md5.js
index 8773a96..24d190e 100644
--- a/js/securityLib/md5.js
+++ b/contrib/securityLib/md5.js
@@ -1,379 +1,379 @@
-/*
- * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
- * Digest Algorithm, as defined in RFC 1321.
- * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for more info.
- */
-
-/*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
-var hexcase = 0;   /* hex output format. 0 - lowercase; 1 - uppercase        */
-var b64pad  = "";  /* base-64 pad character. "=" for strict RFC compliance   */
-
-/*
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
-function hex_md5(s)    { return rstr2hex(rstr_md5(str2rstr_utf8(s))); }
-function b64_md5(s)    { return rstr2b64(rstr_md5(str2rstr_utf8(s))); }
-function any_md5(s, e) { return rstr2any(rstr_md5(str2rstr_utf8(s)), e); }
-function hex_hmac_md5(k, d)
-  { return rstr2hex(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function b64_hmac_md5(k, d)
-  { return rstr2b64(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function any_hmac_md5(k, d, e)
-  { return rstr2any(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
-
-/*
- * Perform a simple self-test to see if the VM is working
- */
-function md5_vm_test()
-{
-  return hex_md5("abc").toLowerCase() == "900150983cd24fb0d6963f7d28e17f72";
-}
-
-/*
- * Calculate the MD5 of a raw string
- */
-function rstr_md5(s)
-{
-  return binl2rstr(binl_md5(rstr2binl(s), s.length * 8));
-}
-
-/*
- * Calculate the HMAC-MD5, of a key and some data (raw strings)
- */
-function rstr_hmac_md5(key, data)
-{
-  var bkey = rstr2binl(key);
-  if(bkey.length > 16) bkey = binl_md5(bkey, key.length * 8);
-
-  var ipad = Array(16), opad = Array(16);
-  for(var i = 0; i < 16; i++)
-  {
-    ipad[i] = bkey[i] ^ 0x36363636;
-    opad[i] = bkey[i] ^ 0x5C5C5C5C;
-  }
-
-  var hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
-  return binl2rstr(binl_md5(opad.concat(hash), 512 + 128));
-}
-
-/*
- * Convert a raw string to a hex string
- */
-function rstr2hex(input)
-{
-  try { hexcase } catch(e) { hexcase=0; }
-  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
-  var output = "";
-  var x;
-  for(var i = 0; i < input.length; i++)
-  {
-    x = input.charCodeAt(i);
-    output += hex_tab.charAt((x >>> 4) & 0x0F)
-           +  hex_tab.charAt( x        & 0x0F);
-  }
-  return output;
-}
-
-/*
- * Convert a raw string to a base-64 string
- */
-function rstr2b64(input)
-{
-  try { b64pad } catch(e) { b64pad=''; }
-  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-  var output = "";
-  var len = input.length;
-  for(var i = 0; i < len; i += 3)
-  {
-    var triplet = (input.charCodeAt(i) << 16)
-                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
-                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
-    for(var j = 0; j < 4; j++)
-    {
-      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
-      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
-    }
-  }
-  return output;
-}
-
-/*
- * Convert a raw string to an arbitrary string encoding
- */
-function rstr2any(input, encoding)
-{
-  var divisor = encoding.length;
-  var i, j, q, x, quotient;
-
-  /* Convert to an array of 16-bit big-endian values, forming the dividend */
-  var dividend = Array(Math.ceil(input.length / 2));
-  for(i = 0; i < dividend.length; i++)
-  {
-    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
-  }
-
-  /*
-   * Repeatedly perform a long division. The binary array forms the dividend,
-   * the length of the encoding is the divisor. Once computed, the quotient
-   * forms the dividend for the next step. All remainders are stored for later
-   * use.
-   */
-  var full_length = Math.ceil(input.length * 8 /
-                                    (Math.log(encoding.length) / Math.log(2)));
-  var remainders = Array(full_length);
-  for(j = 0; j < full_length; j++)
-  {
-    quotient = Array();
-    x = 0;
-    for(i = 0; i < dividend.length; i++)
-    {
-      x = (x << 16) + dividend[i];
-      q = Math.floor(x / divisor);
-      x -= q * divisor;
-      if(quotient.length > 0 || q > 0)
-        quotient[quotient.length] = q;
-    }
-    remainders[j] = x;
-    dividend = quotient;
-  }
-
-  /* Convert the remainders to the output string */
-  var output = "";
-  for(i = remainders.length - 1; i >= 0; i--)
-    output += encoding.charAt(remainders[i]);
-
-  return output;
-}
-
-/*
- * Encode a string as utf-8.
- * For efficiency, this assumes the input is valid utf-16.
- */
-function str2rstr_utf8(input)
-{
-  var output = "";
-  var i = -1;
-  var x, y;
-
-  while(++i < input.length)
-  {
-    /* Decode utf-16 surrogate pairs */
-    x = input.charCodeAt(i);
-    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
-    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
-    {
-      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
-      i++;
-    }
-
-    /* Encode output as utf-8 */
-    if(x <= 0x7F)
-      output += String.fromCharCode(x);
-    else if(x <= 0x7FF)
-      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
-                                    0x80 | ( x         & 0x3F));
-    else if(x <= 0xFFFF)
-      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
-                                    0x80 | ((x >>> 6 ) & 0x3F),
-                                    0x80 | ( x         & 0x3F));
-    else if(x <= 0x1FFFFF)
-      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
-                                    0x80 | ((x >>> 12) & 0x3F),
-                                    0x80 | ((x >>> 6 ) & 0x3F),
-                                    0x80 | ( x         & 0x3F));
-  }
-  return output;
-}
-
-/*
- * Encode a string as utf-16
- */
-function str2rstr_utf16le(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length; i++)
-    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
-                                  (input.charCodeAt(i) >>> 8) & 0xFF);
-  return output;
-}
-
-function str2rstr_utf16be(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length; i++)
-    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
-                                   input.charCodeAt(i)        & 0xFF);
-  return output;
-}
-
-/*
- * Convert a raw string to an array of little-endian words
- * Characters >255 have their high-byte silently ignored.
- */
-function rstr2binl(input)
-{
-  var output = Array(input.length >> 2);
-  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) << (i%32);
-  return output;
-}
-
-/*
- * Convert an array of little-endian words to a string
- */
-function binl2rstr(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length * 32; i += 8)
-    output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF);
-  return output;
-}
-
-/*
- * Calculate the MD5 of an array of little-endian words, and a bit length.
- */
-function binl_md5(x, len)
-{
-  /* append padding */
-  x[len >> 5] |= 0x80 << ((len) % 32);
-  x[(((len + 64) >>> 9) << 4) + 14] = len;
-
-  var a =  1732584193;
-  var b = -271733879;
-  var c = -1732584194;
-  var d =  271733878;
-
-  for(var i = 0; i < x.length; i += 16)
-  {
-    var olda = a;
-    var oldb = b;
-    var oldc = c;
-    var oldd = d;
-
-    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
-    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
-    c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
-    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
-    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
-    d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
-    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
-    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
-    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
-    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
-    c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
-    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
-    a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
-    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
-    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
-    b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);
-
-    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
-    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
-    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
-    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
-    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
-    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
-    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
-    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
-    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
-    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
-    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
-    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
-    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
-    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
-    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
-    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
-
-    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
-    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
-    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
-    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
-    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
-    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
-    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
-    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
-    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
-    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
-    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
-    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
-    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
-    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
-    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
-    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
-
-    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
-    d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
-    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
-    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
-    a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
-    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
-    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
-    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
-    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
-    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
-    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
-    b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
-    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
-    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
-    c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
-    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
-
-    a = safe_add(a, olda);
-    b = safe_add(b, oldb);
-    c = safe_add(c, oldc);
-    d = safe_add(d, oldd);
-  }
-  return Array(a, b, c, d);
-}
-
-/*
- * These functions implement the four basic operations the algorithm uses.
- */
-function md5_cmn(q, a, b, x, s, t)
-{
-  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
-}
-function md5_ff(a, b, c, d, x, s, t)
-{
-  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
-}
-function md5_gg(a, b, c, d, x, s, t)
-{
-  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
-}
-function md5_hh(a, b, c, d, x, s, t)
-{
-  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
-}
-function md5_ii(a, b, c, d, x, s, t)
-{
-  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
-}
-
-/*
- * Add integers, wrapping at 2^32. This uses 16-bit operations internally
- * to work around bugs in some JS interpreters.
- */
-function safe_add(x, y)
-{
-  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
-  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
-  return (msw << 16) | (lsw & 0xFFFF);
-}
-
-/*
- * Bitwise rotate a 32-bit number to the left.
- */
-function bit_rol(num, cnt)
-{
-  return (num << cnt) | (num >>> (32 - cnt));
-}
+/*
+ * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
+ * Digest Algorithm, as defined in RFC 1321.
+ * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ * Distributed under the BSD License
+ * See http://pajhome.org.uk/crypt/md5 for more info.
+ */
+
+/*
+ * Configurable variables. You may need to tweak these to be compatible with
+ * the server-side, but the defaults work in most cases.
+ */
+var hexcase = 0;   /* hex output format. 0 - lowercase; 1 - uppercase        */
+var b64pad  = "";  /* base-64 pad character. "=" for strict RFC compliance   */
+
+/*
+ * These are the functions you'll usually want to call
+ * They take string arguments and return either hex or base-64 encoded strings
+ */
+function hex_md5(s)    { return rstr2hex(rstr_md5(str2rstr_utf8(s))); }
+function b64_md5(s)    { return rstr2b64(rstr_md5(str2rstr_utf8(s))); }
+function any_md5(s, e) { return rstr2any(rstr_md5(str2rstr_utf8(s)), e); }
+function hex_hmac_md5(k, d)
+  { return rstr2hex(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); }
+function b64_hmac_md5(k, d)
+  { return rstr2b64(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d))); }
+function any_hmac_md5(k, d, e)
+  { return rstr2any(rstr_hmac_md5(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
+
+/*
+ * Perform a simple self-test to see if the VM is working
+ */
+function md5_vm_test()
+{
+  return hex_md5("abc").toLowerCase() == "900150983cd24fb0d6963f7d28e17f72";
+}
+
+/*
+ * Calculate the MD5 of a raw string
+ */
+function rstr_md5(s)
+{
+  return binl2rstr(binl_md5(rstr2binl(s), s.length * 8));
+}
+
+/*
+ * Calculate the HMAC-MD5, of a key and some data (raw strings)
+ */
+function rstr_hmac_md5(key, data)
+{
+  var bkey = rstr2binl(key);
+  if(bkey.length > 16) bkey = binl_md5(bkey, key.length * 8);
+
+  var ipad = Array(16), opad = Array(16);
+  for(var i = 0; i < 16; i++)
+  {
+    ipad[i] = bkey[i] ^ 0x36363636;
+    opad[i] = bkey[i] ^ 0x5C5C5C5C;
+  }
+
+  var hash = binl_md5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
+  return binl2rstr(binl_md5(opad.concat(hash), 512 + 128));
+}
+
+/*
+ * Convert a raw string to a hex string
+ */
+function rstr2hex(input)
+{
+  try { hexcase } catch(e) { hexcase=0; }
+  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+  var output = "";
+  var x;
+  for(var i = 0; i < input.length; i++)
+  {
+    x = input.charCodeAt(i);
+    output += hex_tab.charAt((x >>> 4) & 0x0F)
+           +  hex_tab.charAt( x        & 0x0F);
+  }
+  return output;
+}
+
+/*
+ * Convert a raw string to a base-64 string
+ */
+function rstr2b64(input)
+{
+  try { b64pad } catch(e) { b64pad=''; }
+  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+  var output = "";
+  var len = input.length;
+  for(var i = 0; i < len; i += 3)
+  {
+    var triplet = (input.charCodeAt(i) << 16)
+                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
+                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
+    for(var j = 0; j < 4; j++)
+    {
+      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
+      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
+    }
+  }
+  return output;
+}
+
+/*
+ * Convert a raw string to an arbitrary string encoding
+ */
+function rstr2any(input, encoding)
+{
+  var divisor = encoding.length;
+  var i, j, q, x, quotient;
+
+  /* Convert to an array of 16-bit big-endian values, forming the dividend */
+  var dividend = Array(Math.ceil(input.length / 2));
+  for(i = 0; i < dividend.length; i++)
+  {
+    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
+  }
+
+  /*
+   * Repeatedly perform a long division. The binary array forms the dividend,
+   * the length of the encoding is the divisor. Once computed, the quotient
+   * forms the dividend for the next step. All remainders are stored for later
+   * use.
+   */
+  var full_length = Math.ceil(input.length * 8 /
+                                    (Math.log(encoding.length) / Math.log(2)));
+  var remainders = Array(full_length);
+  for(j = 0; j < full_length; j++)
+  {
+    quotient = Array();
+    x = 0;
+    for(i = 0; i < dividend.length; i++)
+    {
+      x = (x << 16) + dividend[i];
+      q = Math.floor(x / divisor);
+      x -= q * divisor;
+      if(quotient.length > 0 || q > 0)
+        quotient[quotient.length] = q;
+    }
+    remainders[j] = x;
+    dividend = quotient;
+  }
+
+  /* Convert the remainders to the output string */
+  var output = "";
+  for(i = remainders.length - 1; i >= 0; i--)
+    output += encoding.charAt(remainders[i]);
+
+  return output;
+}
+
+/*
+ * Encode a string as utf-8.
+ * For efficiency, this assumes the input is valid utf-16.
+ */
+function str2rstr_utf8(input)
+{
+  var output = "";
+  var i = -1;
+  var x, y;
+
+  while(++i < input.length)
+  {
+    /* Decode utf-16 surrogate pairs */
+    x = input.charCodeAt(i);
+    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
+    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
+    {
+      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
+      i++;
+    }
+
+    /* Encode output as utf-8 */
+    if(x <= 0x7F)
+      output += String.fromCharCode(x);
+    else if(x <= 0x7FF)
+      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
+                                    0x80 | ( x         & 0x3F));
+    else if(x <= 0xFFFF)
+      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
+                                    0x80 | ((x >>> 6 ) & 0x3F),
+                                    0x80 | ( x         & 0x3F));
+    else if(x <= 0x1FFFFF)
+      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
+                                    0x80 | ((x >>> 12) & 0x3F),
+                                    0x80 | ((x >>> 6 ) & 0x3F),
+                                    0x80 | ( x         & 0x3F));
+  }
+  return output;
+}
+
+/*
+ * Encode a string as utf-16
+ */
+function str2rstr_utf16le(input)
+{
+  var output = "";
+  for(var i = 0; i < input.length; i++)
+    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
+                                  (input.charCodeAt(i) >>> 8) & 0xFF);
+  return output;
+}
+
+function str2rstr_utf16be(input)
+{
+  var output = "";
+  for(var i = 0; i < input.length; i++)
+    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
+                                   input.charCodeAt(i)        & 0xFF);
+  return output;
+}
+
+/*
+ * Convert a raw string to an array of little-endian words
+ * Characters >255 have their high-byte silently ignored.
+ */
+function rstr2binl(input)
+{
+  var output = Array(input.length >> 2);
+  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) << (i%32);
+  return output;
+}
+
+/*
+ * Convert an array of little-endian words to a string
+ */
+function binl2rstr(input)
+{
+  var output = "";
+  for(var i = 0; i < input.length * 32; i += 8)
+    output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF);
+  return output;
+}
+
+/*
+ * Calculate the MD5 of an array of little-endian words, and a bit length.
+ */
+function binl_md5(x, len)
+{
+  /* append padding */
+  x[len >> 5] |= 0x80 << ((len) % 32);
+  x[(((len + 64) >>> 9) << 4) + 14] = len;
+
+  var a =  1732584193;
+  var b = -271733879;
+  var c = -1732584194;
+  var d =  271733878;
+
+  for(var i = 0; i < x.length; i += 16)
+  {
+    var olda = a;
+    var oldb = b;
+    var oldc = c;
+    var oldd = d;
+
+    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
+    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
+    c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
+    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
+    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
+    d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
+    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
+    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
+    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
+    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
+    c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
+    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
+    a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
+    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
+    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
+    b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);
+
+    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
+    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
+    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
+    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
+    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
+    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
+    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
+    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
+    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
+    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
+    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
+    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
+    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
+    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
+    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
+    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
+
+    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
+    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
+    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
+    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
+    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
+    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
+    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
+    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
+    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
+    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
+    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
+    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
+    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
+    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
+    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
+    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
+
+    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
+    d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
+    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
+    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
+    a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
+    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
+    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
+    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
+    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
+    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
+    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
+    b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
+    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
+    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
+    c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
+    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
+
+    a = safe_add(a, olda);
+    b = safe_add(b, oldb);
+    c = safe_add(c, oldc);
+    d = safe_add(d, oldd);
+  }
+  return Array(a, b, c, d);
+}
+
+/*
+ * These functions implement the four basic operations the algorithm uses.
+ */
+function md5_cmn(q, a, b, x, s, t)
+{
+  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
+}
+function md5_ff(a, b, c, d, x, s, t)
+{
+  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
+}
+function md5_gg(a, b, c, d, x, s, t)
+{
+  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
+}
+function md5_hh(a, b, c, d, x, s, t)
+{
+  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
+}
+function md5_ii(a, b, c, d, x, s, t)
+{
+  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
+}
+
+/*
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
+ * to work around bugs in some JS interpreters.
+ */
+function safe_add(x, y)
+{
+  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+  return (msw << 16) | (lsw & 0xFFFF);
+}
+
+/*
+ * Bitwise rotate a 32-bit number to the left.
+ */
+function bit_rol(num, cnt)
+{
+  return (num << cnt) | (num >>> (32 - cnt));
+}
diff --git a/js/securityLib/ripemd160.js b/contrib/securityLib/ripemd160.js
similarity index 99%
rename from js/securityLib/ripemd160.js
rename to contrib/securityLib/ripemd160.js
index 6e12a88..7f60532 100644
--- a/js/securityLib/ripemd160.js
+++ b/contrib/securityLib/ripemd160.js
@@ -1,359 +1,359 @@
-/*
- * A JavaScript implementation of the RIPEMD-160 Algorithm
- * Version 2.2 Copyright Jeremy Lin, Paul Johnston 2000 - 2009.
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for details.
- * Also http://www.ocf.berkeley.edu/~jjlin/jsotp/
- */
-
-/*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
-var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
-var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
-
-/*
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
-function hex_rmd160(s)    { return rstr2hex(rstr_rmd160(str2rstr_utf8(s))); }
-function b64_rmd160(s)    { return rstr2b64(rstr_rmd160(str2rstr_utf8(s))); }
-function any_rmd160(s, e) { return rstr2any(rstr_rmd160(str2rstr_utf8(s)), e); }
-function hex_hmac_rmd160(k, d)
-  { return rstr2hex(rstr_hmac_rmd160(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function b64_hmac_rmd160(k, d)
-  { return rstr2b64(rstr_hmac_rmd160(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function any_hmac_rmd160(k, d, e)
-  { return rstr2any(rstr_hmac_rmd160(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
-
-/*
- * Perform a simple self-test to see if the VM is working
- */
-function rmd160_vm_test()
-{
-  return hex_rmd160("abc").toLowerCase() == "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc";
-}
-
-/*
- * Calculate the rmd160 of a raw string
- */
-function rstr_rmd160(s)
-{
-  return binl2rstr(binl_rmd160(rstr2binl(s), s.length * 8));
-}
-
-/*
- * Calculate the HMAC-rmd160 of a key and some data (raw strings)
- */
-function rstr_hmac_rmd160(key, data)
-{
-  var bkey = rstr2binl(key);
-  if(bkey.length > 16) bkey = binl_rmd160(bkey, key.length * 8);
-
-  var ipad = Array(16), opad = Array(16);
-  for(var i = 0; i < 16; i++)
-  {
-    ipad[i] = bkey[i] ^ 0x36363636;
-    opad[i] = bkey[i] ^ 0x5C5C5C5C;
-  }
-
-  var hash = binl_rmd160(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
-  return binl2rstr(binl_rmd160(opad.concat(hash), 512 + 160));
-}
-
-/*
- * Convert a raw string to a hex string
- */
-function rstr2hex(input)
-{
-  try { hexcase } catch(e) { hexcase=0; }
-  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
-  var output = "";
-  var x;
-  for(var i = 0; i < input.length; i++)
-  {
-    x = input.charCodeAt(i);
-    output += hex_tab.charAt((x >>> 4) & 0x0F)
-           +  hex_tab.charAt( x        & 0x0F);
-  }
-  return output;
-}
-
-/*
- * Convert a raw string to a base-64 string
- */
-function rstr2b64(input)
-{
-  try { b64pad } catch(e) { b64pad=''; }
-  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-  var output = "";
-  var len = input.length;
-  for(var i = 0; i < len; i += 3)
-  {
-    var triplet = (input.charCodeAt(i) << 16)
-                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
-                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
-    for(var j = 0; j < 4; j++)
-    {
-      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
-      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
-    }
-  }
-  return output;
-}
-
-/*
- * Convert a raw string to an arbitrary string encoding
- */
-function rstr2any(input, encoding)
-{
-  var divisor = encoding.length;
-  var remainders = Array();
-  var i, q, x, quotient;
-
-  /* Convert to an array of 16-bit big-endian values, forming the dividend */
-  var dividend = Array(Math.ceil(input.length / 2));
-  for(i = 0; i < dividend.length; i++)
-  {
-    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
-  }
-
-  /*
-   * Repeatedly perform a long division. The binary array forms the dividend,
-   * the length of the encoding is the divisor. Once computed, the quotient
-   * forms the dividend for the next step. We stop when the dividend is zero.
-   * All remainders are stored for later use.
-   */
-  while(dividend.length > 0)
-  {
-    quotient = Array();
-    x = 0;
-    for(i = 0; i < dividend.length; i++)
-    {
-      x = (x << 16) + dividend[i];
-      q = Math.floor(x / divisor);
-      x -= q * divisor;
-      if(quotient.length > 0 || q > 0)
-        quotient[quotient.length] = q;
-    }
-    remainders[remainders.length] = x;
-    dividend = quotient;
-  }
-
-  /* Convert the remainders to the output string */
-  var output = "";
-  for(i = remainders.length - 1; i >= 0; i--)
-    output += encoding.charAt(remainders[i]);
-
-  /* Append leading zero equivalents */
-  var full_length = Math.ceil(input.length * 8 /
-                                    (Math.log(encoding.length) / Math.log(2)))
-  for(i = output.length; i < full_length; i++)
-    output = encoding[0] + output;
-
-  return output;
-}
-
-/*
- * Encode a string as utf-8.
- * For efficiency, this assumes the input is valid utf-16.
- */
-function str2rstr_utf8(input)
-{
-  var output = "";
-  var i = -1;
-  var x, y;
-
-  while(++i < input.length)
-  {
-    /* Decode utf-16 surrogate pairs */
-    x = input.charCodeAt(i);
-    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
-    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
-    {
-      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
-      i++;
-    }
-
-    /* Encode output as utf-8 */
-    if(x <= 0x7F)
-      output += String.fromCharCode(x);
-    else if(x <= 0x7FF)
-      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
-                                    0x80 | ( x         & 0x3F));
-    else if(x <= 0xFFFF)
-      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
-                                    0x80 | ((x >>> 6 ) & 0x3F),
-                                    0x80 | ( x         & 0x3F));
-    else if(x <= 0x1FFFFF)
-      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
-                                    0x80 | ((x >>> 12) & 0x3F),
-                                    0x80 | ((x >>> 6 ) & 0x3F),
-                                    0x80 | ( x         & 0x3F));
-  }
-  return output;
-}
-
-/*
- * Encode a string as utf-16
- */
-function str2rstr_utf16le(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length; i++)
-    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
-                                  (input.charCodeAt(i) >>> 8) & 0xFF);
-  return output;
-}
-
-function str2rstr_utf16be(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length; i++)
-    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
-                                   input.charCodeAt(i)        & 0xFF);
-  return output;
-}
-
-/*
- * Convert a raw string to an array of little-endian words
- * Characters >255 have their high-byte silently ignored.
- */
-function rstr2binl(input)
-{
-  var output = Array(input.length >> 2);
-  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) << (i%32);
-  return output;
-}
-
-/*
- * Convert an array of little-endian words to a string
- */
-function binl2rstr(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length * 32; i += 8)
-    output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF);
-  return output;
-}
-
-/*
- * Calculate the RIPE-MD160 of an array of little-endian words, and a bit length.
- */
-function binl_rmd160(x, len)
-{
-  /* append padding */
-  x[len >> 5] |= 0x80 << (len % 32);
-  x[(((len + 64) >>> 9) << 4) + 14] = len;
-
-  var h0 = 0x67452301;
-  var h1 = 0xefcdab89;
-  var h2 = 0x98badcfe;
-  var h3 = 0x10325476;
-  var h4 = 0xc3d2e1f0;
-
-  for (var i = 0; i < x.length; i += 16) {
-    var T;
-    var A1 = h0, B1 = h1, C1 = h2, D1 = h3, E1 = h4;
-    var A2 = h0, B2 = h1, C2 = h2, D2 = h3, E2 = h4;
-    for (var j = 0; j <= 79; ++j) {
-      T = safe_add(A1, rmd160_f(j, B1, C1, D1));
-      T = safe_add(T, x[i + rmd160_r1[j]]);
-      T = safe_add(T, rmd160_K1(j));
-      T = safe_add(bit_rol(T, rmd160_s1[j]), E1);
-      A1 = E1; E1 = D1; D1 = bit_rol(C1, 10); C1 = B1; B1 = T;
-      T = safe_add(A2, rmd160_f(79-j, B2, C2, D2));
-      T = safe_add(T, x[i + rmd160_r2[j]]);
-      T = safe_add(T, rmd160_K2(j));
-      T = safe_add(bit_rol(T, rmd160_s2[j]), E2);
-      A2 = E2; E2 = D2; D2 = bit_rol(C2, 10); C2 = B2; B2 = T;
-    }
-    T = safe_add(h1, safe_add(C1, D2));
-    h1 = safe_add(h2, safe_add(D1, E2));
-    h2 = safe_add(h3, safe_add(E1, A2));
-    h3 = safe_add(h4, safe_add(A1, B2));
-    h4 = safe_add(h0, safe_add(B1, C2));
-    h0 = T;
-  }
-  return [h0, h1, h2, h3, h4];
-}
-
-function rmd160_f(j, x, y, z)
-{
-  return ( 0 <= j && j <= 15) ? (x ^ y ^ z) :
-         (16 <= j && j <= 31) ? (x & y) | (~x & z) :
-         (32 <= j && j <= 47) ? (x | ~y) ^ z :
-         (48 <= j && j <= 63) ? (x & z) | (y & ~z) :
-         (64 <= j && j <= 79) ? x ^ (y | ~z) :
-         "rmd160_f: j out of range";
-}
-function rmd160_K1(j)
-{
-  return ( 0 <= j && j <= 15) ? 0x00000000 :
-         (16 <= j && j <= 31) ? 0x5a827999 :
-         (32 <= j && j <= 47) ? 0x6ed9eba1 :
-         (48 <= j && j <= 63) ? 0x8f1bbcdc :
-         (64 <= j && j <= 79) ? 0xa953fd4e :
-         "rmd160_K1: j out of range";
-}
-function rmd160_K2(j)
-{
-  return ( 0 <= j && j <= 15) ? 0x50a28be6 :
-         (16 <= j && j <= 31) ? 0x5c4dd124 :
-         (32 <= j && j <= 47) ? 0x6d703ef3 :
-         (48 <= j && j <= 63) ? 0x7a6d76e9 :
-         (64 <= j && j <= 79) ? 0x00000000 :
-         "rmd160_K2: j out of range";
-}
-var rmd160_r1 = [
-   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
-   7,  4, 13,  1, 10,  6, 15,  3, 12,  0,  9,  5,  2, 14, 11,  8,
-   3, 10, 14,  4,  9, 15,  8,  1,  2,  7,  0,  6, 13, 11,  5, 12,
-   1,  9, 11, 10,  0,  8, 12,  4, 13,  3,  7, 15, 14,  5,  6,  2,
-   4,  0,  5,  9,  7, 12,  2, 10, 14,  1,  3,  8, 11,  6, 15, 13
-];
-var rmd160_r2 = [
-   5, 14,  7,  0,  9,  2, 11,  4, 13,  6, 15,  8,  1, 10,  3, 12,
-   6, 11,  3,  7,  0, 13,  5, 10, 14, 15,  8, 12,  4,  9,  1,  2,
-  15,  5,  1,  3,  7, 14,  6,  9, 11,  8, 12,  2, 10,  0,  4, 13,
-   8,  6,  4,  1,  3, 11, 15,  0,  5, 12,  2, 13,  9,  7, 10, 14,
-  12, 15, 10,  4,  1,  5,  8,  7,  6,  2, 13, 14,  0,  3,  9, 11
-];
-var rmd160_s1 = [
-  11, 14, 15, 12,  5,  8,  7,  9, 11, 13, 14, 15,  6,  7,  9,  8,
-   7,  6,  8, 13, 11,  9,  7, 15,  7, 12, 15,  9, 11,  7, 13, 12,
-  11, 13,  6,  7, 14,  9, 13, 15, 14,  8, 13,  6,  5, 12,  7,  5,
-  11, 12, 14, 15, 14, 15,  9,  8,  9, 14,  5,  6,  8,  6,  5, 12,
-   9, 15,  5, 11,  6,  8, 13, 12,  5, 12, 13, 14, 11,  8,  5,  6
-];
-var rmd160_s2 = [
-   8,  9,  9, 11, 13, 15, 15,  5,  7,  7,  8, 11, 14, 14, 12,  6,
-   9, 13, 15,  7, 12,  8,  9, 11,  7,  7, 12,  7,  6, 15, 13, 11,
-   9,  7, 15, 11,  8,  6,  6, 14, 12, 13,  5, 14, 13, 13,  7,  5,
-  15,  5,  8, 11, 14, 14,  6, 14,  6,  9, 12,  9, 12,  5, 15,  8,
-   8,  5, 12,  9, 12,  5, 14,  6,  8, 13,  6,  5, 15, 13, 11, 11
-];
-
-/*
- * Add integers, wrapping at 2^32. This uses 16-bit operations internally
- * to work around bugs in some JS interpreters.
- */
-function safe_add(x, y)
-{
-  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
-  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
-  return (msw << 16) | (lsw & 0xFFFF);
-}
-
-/*
- * Bitwise rotate a 32-bit number to the left.
- */
-function bit_rol(num, cnt)
-{
-  return (num << cnt) | (num >>> (32 - cnt));
-}
+/*
+ * A JavaScript implementation of the RIPEMD-160 Algorithm
+ * Version 2.2 Copyright Jeremy Lin, Paul Johnston 2000 - 2009.
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ * Distributed under the BSD License
+ * See http://pajhome.org.uk/crypt/md5 for details.
+ * Also http://www.ocf.berkeley.edu/~jjlin/jsotp/
+ */
+
+/*
+ * Configurable variables. You may need to tweak these to be compatible with
+ * the server-side, but the defaults work in most cases.
+ */
+var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
+var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
+
+/*
+ * These are the functions you'll usually want to call
+ * They take string arguments and return either hex or base-64 encoded strings
+ */
+function hex_rmd160(s)    { return rstr2hex(rstr_rmd160(str2rstr_utf8(s))); }
+function b64_rmd160(s)    { return rstr2b64(rstr_rmd160(str2rstr_utf8(s))); }
+function any_rmd160(s, e) { return rstr2any(rstr_rmd160(str2rstr_utf8(s)), e); }
+function hex_hmac_rmd160(k, d)
+  { return rstr2hex(rstr_hmac_rmd160(str2rstr_utf8(k), str2rstr_utf8(d))); }
+function b64_hmac_rmd160(k, d)
+  { return rstr2b64(rstr_hmac_rmd160(str2rstr_utf8(k), str2rstr_utf8(d))); }
+function any_hmac_rmd160(k, d, e)
+  { return rstr2any(rstr_hmac_rmd160(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
+
+/*
+ * Perform a simple self-test to see if the VM is working
+ */
+function rmd160_vm_test()
+{
+  return hex_rmd160("abc").toLowerCase() == "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc";
+}
+
+/*
+ * Calculate the rmd160 of a raw string
+ */
+function rstr_rmd160(s)
+{
+  return binl2rstr(binl_rmd160(rstr2binl(s), s.length * 8));
+}
+
+/*
+ * Calculate the HMAC-rmd160 of a key and some data (raw strings)
+ */
+function rstr_hmac_rmd160(key, data)
+{
+  var bkey = rstr2binl(key);
+  if(bkey.length > 16) bkey = binl_rmd160(bkey, key.length * 8);
+
+  var ipad = Array(16), opad = Array(16);
+  for(var i = 0; i < 16; i++)
+  {
+    ipad[i] = bkey[i] ^ 0x36363636;
+    opad[i] = bkey[i] ^ 0x5C5C5C5C;
+  }
+
+  var hash = binl_rmd160(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
+  return binl2rstr(binl_rmd160(opad.concat(hash), 512 + 160));
+}
+
+/*
+ * Convert a raw string to a hex string
+ */
+function rstr2hex(input)
+{
+  try { hexcase } catch(e) { hexcase=0; }
+  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+  var output = "";
+  var x;
+  for(var i = 0; i < input.length; i++)
+  {
+    x = input.charCodeAt(i);
+    output += hex_tab.charAt((x >>> 4) & 0x0F)
+           +  hex_tab.charAt( x        & 0x0F);
+  }
+  return output;
+}
+
+/*
+ * Convert a raw string to a base-64 string
+ */
+function rstr2b64(input)
+{
+  try { b64pad } catch(e) { b64pad=''; }
+  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+  var output = "";
+  var len = input.length;
+  for(var i = 0; i < len; i += 3)
+  {
+    var triplet = (input.charCodeAt(i) << 16)
+                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
+                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
+    for(var j = 0; j < 4; j++)
+    {
+      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
+      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
+    }
+  }
+  return output;
+}
+
+/*
+ * Convert a raw string to an arbitrary string encoding
+ */
+function rstr2any(input, encoding)
+{
+  var divisor = encoding.length;
+  var remainders = Array();
+  var i, q, x, quotient;
+
+  /* Convert to an array of 16-bit big-endian values, forming the dividend */
+  var dividend = Array(Math.ceil(input.length / 2));
+  for(i = 0; i < dividend.length; i++)
+  {
+    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
+  }
+
+  /*
+   * Repeatedly perform a long division. The binary array forms the dividend,
+   * the length of the encoding is the divisor. Once computed, the quotient
+   * forms the dividend for the next step. We stop when the dividend is zero.
+   * All remainders are stored for later use.
+   */
+  while(dividend.length > 0)
+  {
+    quotient = Array();
+    x = 0;
+    for(i = 0; i < dividend.length; i++)
+    {
+      x = (x << 16) + dividend[i];
+      q = Math.floor(x / divisor);
+      x -= q * divisor;
+      if(quotient.length > 0 || q > 0)
+        quotient[quotient.length] = q;
+    }
+    remainders[remainders.length] = x;
+    dividend = quotient;
+  }
+
+  /* Convert the remainders to the output string */
+  var output = "";
+  for(i = remainders.length - 1; i >= 0; i--)
+    output += encoding.charAt(remainders[i]);
+
+  /* Append leading zero equivalents */
+  var full_length = Math.ceil(input.length * 8 /
+                                    (Math.log(encoding.length) / Math.log(2)))
+  for(i = output.length; i < full_length; i++)
+    output = encoding[0] + output;
+
+  return output;
+}
+
+/*
+ * Encode a string as utf-8.
+ * For efficiency, this assumes the input is valid utf-16.
+ */
+function str2rstr_utf8(input)
+{
+  var output = "";
+  var i = -1;
+  var x, y;
+
+  while(++i < input.length)
+  {
+    /* Decode utf-16 surrogate pairs */
+    x = input.charCodeAt(i);
+    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
+    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
+    {
+      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
+      i++;
+    }
+
+    /* Encode output as utf-8 */
+    if(x <= 0x7F)
+      output += String.fromCharCode(x);
+    else if(x <= 0x7FF)
+      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
+                                    0x80 | ( x         & 0x3F));
+    else if(x <= 0xFFFF)
+      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
+                                    0x80 | ((x >>> 6 ) & 0x3F),
+                                    0x80 | ( x         & 0x3F));
+    else if(x <= 0x1FFFFF)
+      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
+                                    0x80 | ((x >>> 12) & 0x3F),
+                                    0x80 | ((x >>> 6 ) & 0x3F),
+                                    0x80 | ( x         & 0x3F));
+  }
+  return output;
+}
+
+/*
+ * Encode a string as utf-16
+ */
+function str2rstr_utf16le(input)
+{
+  var output = "";
+  for(var i = 0; i < input.length; i++)
+    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
+                                  (input.charCodeAt(i) >>> 8) & 0xFF);
+  return output;
+}
+
+function str2rstr_utf16be(input)
+{
+  var output = "";
+  for(var i = 0; i < input.length; i++)
+    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
+                                   input.charCodeAt(i)        & 0xFF);
+  return output;
+}
+
+/*
+ * Convert a raw string to an array of little-endian words
+ * Characters >255 have their high-byte silently ignored.
+ */
+function rstr2binl(input)
+{
+  var output = Array(input.length >> 2);
+  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) << (i%32);
+  return output;
+}
+
+/*
+ * Convert an array of little-endian words to a string
+ */
+function binl2rstr(input)
+{
+  var output = "";
+  for(var i = 0; i < input.length * 32; i += 8)
+    output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF);
+  return output;
+}
+
+/*
+ * Calculate the RIPE-MD160 of an array of little-endian words, and a bit length.
+ */
+function binl_rmd160(x, len)
+{
+  /* append padding */
+  x[len >> 5] |= 0x80 << (len % 32);
+  x[(((len + 64) >>> 9) << 4) + 14] = len;
+
+  var h0 = 0x67452301;
+  var h1 = 0xefcdab89;
+  var h2 = 0x98badcfe;
+  var h3 = 0x10325476;
+  var h4 = 0xc3d2e1f0;
+
+  for (var i = 0; i < x.length; i += 16) {
+    var T;
+    var A1 = h0, B1 = h1, C1 = h2, D1 = h3, E1 = h4;
+    var A2 = h0, B2 = h1, C2 = h2, D2 = h3, E2 = h4;
+    for (var j = 0; j <= 79; ++j) {
+      T = safe_add(A1, rmd160_f(j, B1, C1, D1));
+      T = safe_add(T, x[i + rmd160_r1[j]]);
+      T = safe_add(T, rmd160_K1(j));
+      T = safe_add(bit_rol(T, rmd160_s1[j]), E1);
+      A1 = E1; E1 = D1; D1 = bit_rol(C1, 10); C1 = B1; B1 = T;
+      T = safe_add(A2, rmd160_f(79-j, B2, C2, D2));
+      T = safe_add(T, x[i + rmd160_r2[j]]);
+      T = safe_add(T, rmd160_K2(j));
+      T = safe_add(bit_rol(T, rmd160_s2[j]), E2);
+      A2 = E2; E2 = D2; D2 = bit_rol(C2, 10); C2 = B2; B2 = T;
+    }
+    T = safe_add(h1, safe_add(C1, D2));
+    h1 = safe_add(h2, safe_add(D1, E2));
+    h2 = safe_add(h3, safe_add(E1, A2));
+    h3 = safe_add(h4, safe_add(A1, B2));
+    h4 = safe_add(h0, safe_add(B1, C2));
+    h0 = T;
+  }
+  return [h0, h1, h2, h3, h4];
+}
+
+function rmd160_f(j, x, y, z)
+{
+  return ( 0 <= j && j <= 15) ? (x ^ y ^ z) :
+         (16 <= j && j <= 31) ? (x & y) | (~x & z) :
+         (32 <= j && j <= 47) ? (x | ~y) ^ z :
+         (48 <= j && j <= 63) ? (x & z) | (y & ~z) :
+         (64 <= j && j <= 79) ? x ^ (y | ~z) :
+         "rmd160_f: j out of range";
+}
+function rmd160_K1(j)
+{
+  return ( 0 <= j && j <= 15) ? 0x00000000 :
+         (16 <= j && j <= 31) ? 0x5a827999 :
+         (32 <= j && j <= 47) ? 0x6ed9eba1 :
+         (48 <= j && j <= 63) ? 0x8f1bbcdc :
+         (64 <= j && j <= 79) ? 0xa953fd4e :
+         "rmd160_K1: j out of range";
+}
+function rmd160_K2(j)
+{
+  return ( 0 <= j && j <= 15) ? 0x50a28be6 :
+         (16 <= j && j <= 31) ? 0x5c4dd124 :
+         (32 <= j && j <= 47) ? 0x6d703ef3 :
+         (48 <= j && j <= 63) ? 0x7a6d76e9 :
+         (64 <= j && j <= 79) ? 0x00000000 :
+         "rmd160_K2: j out of range";
+}
+var rmd160_r1 = [
+   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+   7,  4, 13,  1, 10,  6, 15,  3, 12,  0,  9,  5,  2, 14, 11,  8,
+   3, 10, 14,  4,  9, 15,  8,  1,  2,  7,  0,  6, 13, 11,  5, 12,
+   1,  9, 11, 10,  0,  8, 12,  4, 13,  3,  7, 15, 14,  5,  6,  2,
+   4,  0,  5,  9,  7, 12,  2, 10, 14,  1,  3,  8, 11,  6, 15, 13
+];
+var rmd160_r2 = [
+   5, 14,  7,  0,  9,  2, 11,  4, 13,  6, 15,  8,  1, 10,  3, 12,
+   6, 11,  3,  7,  0, 13,  5, 10, 14, 15,  8, 12,  4,  9,  1,  2,
+  15,  5,  1,  3,  7, 14,  6,  9, 11,  8, 12,  2, 10,  0,  4, 13,
+   8,  6,  4,  1,  3, 11, 15,  0,  5, 12,  2, 13,  9,  7, 10, 14,
+  12, 15, 10,  4,  1,  5,  8,  7,  6,  2, 13, 14,  0,  3,  9, 11
+];
+var rmd160_s1 = [
+  11, 14, 15, 12,  5,  8,  7,  9, 11, 13, 14, 15,  6,  7,  9,  8,
+   7,  6,  8, 13, 11,  9,  7, 15,  7, 12, 15,  9, 11,  7, 13, 12,
+  11, 13,  6,  7, 14,  9, 13, 15, 14,  8, 13,  6,  5, 12,  7,  5,
+  11, 12, 14, 15, 14, 15,  9,  8,  9, 14,  5,  6,  8,  6,  5, 12,
+   9, 15,  5, 11,  6,  8, 13, 12,  5, 12, 13, 14, 11,  8,  5,  6
+];
+var rmd160_s2 = [
+   8,  9,  9, 11, 13, 15, 15,  5,  7,  7,  8, 11, 14, 14, 12,  6,
+   9, 13, 15,  7, 12,  8,  9, 11,  7,  7, 12,  7,  6, 15, 13, 11,
+   9,  7, 15, 11,  8,  6,  6, 14, 12, 13,  5, 14, 13, 13,  7,  5,
+  15,  5,  8, 11, 14, 14,  6, 14,  6,  9, 12,  9, 12,  5, 15,  8,
+   8,  5, 12,  9, 12,  5, 14,  6,  8, 13,  6,  5, 15, 13, 11, 11
+];
+
+/*
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
+ * to work around bugs in some JS interpreters.
+ */
+function safe_add(x, y)
+{
+  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+  return (msw << 16) | (lsw & 0xFFFF);
+}
+
+/*
+ * Bitwise rotate a 32-bit number to the left.
+ */
+function bit_rol(num, cnt)
+{
+  return (num << cnt) | (num >>> (32 - cnt));
+}
diff --git a/js/securityLib/rsa.js b/contrib/securityLib/rsa.js
similarity index 99%
rename from js/securityLib/rsa.js
rename to contrib/securityLib/rsa.js
index 11efe45..bc5601a 100644
--- a/js/securityLib/rsa.js
+++ b/contrib/securityLib/rsa.js
@@ -1,130 +1,130 @@
-// Depends on jsbn.js and rng.js
-
-// Version 1.1: support utf-8 encoding in pkcs1pad2
-
-// convert a (hex) string to a bignum object
-function parseBigInt(str,r) {
-  return new BigInteger(str,r);
-}
-
-function linebrk(s,n) {
-  var ret = "";
-  var i = 0;
-  while(i + n < s.length) {
-    ret += s.substring(i,i+n) + "\n";
-    i += n;
-  }
-  return ret + s.substring(i,s.length);
-}
-
-function byte2Hex(b) {
-  if(b < 0x10)
-    return "0" + b.toString(16);
-  else
-    return b.toString(16);
-}
-
-/**
- * PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
- * @param s: the string to encode
- * @param n: the size in byte
- */ 
-function pkcs1pad2(s,n) {
-  if(n < s.length + 11) { // TODO: fix for utf-8
-    alert("Message too long for RSA");
-    return null;
-  }
-  var ba = new Array();
-  var i = s.length - 1;
-  while(i >= 0 && n > 0) {
-    var c = s.charCodeAt(i--);
-    if(c < 128) { // encode using utf-8
-      ba[--n] = c;
-    }
-    else if((c > 127) && (c < 2048)) {
-      ba[--n] = (c & 63) | 128;
-      ba[--n] = (c >> 6) | 192;
-    }
-    else {
-      ba[--n] = (c & 63) | 128;
-      ba[--n] = ((c >> 6) & 63) | 128;
-      ba[--n] = (c >> 12) | 224;
-    }
-  }
-  ba[--n] = 0;
-  var rng = new SecureRandom();
-  var x = new Array();
-  while(n > 2) { // random non-zero pad
-    x[0] = 0;
-    while(x[0] == 0) rng.nextBytes(x);
-    ba[--n] = x[0];
-  }
-  ba[--n] = 2;
-  ba[--n] = 0;
-  return new BigInteger(ba);
-}
-
-/** 
- * "empty" RSA key constructor
- * @returns {RSAKey}
- */
-function RSAKey() {
-  this.n = null;
-  this.e = 0;
-  this.d = null;
-  this.p = null;
-  this.q = null;
-  this.dmp1 = null;
-  this.dmq1 = null;
-  this.coeff = null;
-}
-
-/** 
- * Set the public key fields N and e from hex strings
- * @param N
- * @param E
- * @returns {RSASetPublic}
- */
-function RSASetPublic(N,E) {
-  if(N != null && E != null && N.length > 0 && E.length > 0) {
-    this.n = parseBigInt(N,16);
-    this.e = parseInt(E,16);
-  }
-  else
-    alert("Invalid RSA public key");
-}
-
-/** 
- * Perform raw public operation on "x": return x^e (mod n)
- * @param x
- * @returns x^e (mod n)
- */
-function RSADoPublic(x) {
-  return x.modPowInt(this.e, this.n);
-}
-
-/**
- * Return the PKCS#1 RSA encryption of "text" as an even-length hex string
- */ 
-function RSAEncrypt(text) {
-  var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3);
-  if(m == null) return null;
-  var c = this.doPublic(m);
-  if(c == null) return null;
-  var h = c.toString(16);
-  if((h.length & 1) == 0) return h; else return "0" + h;
-}
-
-// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string
-//function RSAEncryptB64(text) {
-//  var h = this.encrypt(text);
-//  if(h) return hex2b64(h); else return null;
-//}
-
-// protected
-RSAKey.prototype.doPublic = RSADoPublic;
-
-// public
-RSAKey.prototype.setPublic = RSASetPublic;
-RSAKey.prototype.encrypt = RSAEncrypt;
-//RSAKey.prototype.encrypt_b64 = RSAEncryptB64;
+// Depends on jsbn.js and rng.js
+
+// Version 1.1: support utf-8 encoding in pkcs1pad2
+
+// convert a (hex) string to a bignum object
+function parseBigInt(str,r) {
+  return new BigInteger(str,r);
+}
+
+function linebrk(s,n) {
+  var ret = "";
+  var i = 0;
+  while(i + n < s.length) {
+    ret += s.substring(i,i+n) + "\n";
+    i += n;
+  }
+  return ret + s.substring(i,s.length);
+}
+
+function byte2Hex(b) {
+  if(b < 0x10)
+    return "0" + b.toString(16);
+  else
+    return b.toString(16);
+}
+
+/**
+ * PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
+ * @param s: the string to encode
+ * @param n: the size in byte
+ */ 
+function pkcs1pad2(s,n) {
+  if(n < s.length + 11) { // TODO: fix for utf-8
+    alert("Message too long for RSA");
+    return null;
+  }
+  var ba = new Array();
+  var i = s.length - 1;
+  while(i >= 0 && n > 0) {
+    var c = s.charCodeAt(i--);
+    if(c < 128) { // encode using utf-8
+      ba[--n] = c;
+    }
+    else if((c > 127) && (c < 2048)) {
+      ba[--n] = (c & 63) | 128;
+      ba[--n] = (c >> 6) | 192;
+    }
+    else {
+      ba[--n] = (c & 63) | 128;
+      ba[--n] = ((c >> 6) & 63) | 128;
+      ba[--n] = (c >> 12) | 224;
+    }
+  }
+  ba[--n] = 0;
+  var rng = new SecureRandom();
+  var x = new Array();
+  while(n > 2) { // random non-zero pad
+    x[0] = 0;
+    while(x[0] == 0) rng.nextBytes(x);
+    ba[--n] = x[0];
+  }
+  ba[--n] = 2;
+  ba[--n] = 0;
+  return new BigInteger(ba);
+}
+
+/** 
+ * "empty" RSA key constructor
+ * @returns {RSAKey}
+ */
+function RSAKey() {
+  this.n = null;
+  this.e = 0;
+  this.d = null;
+  this.p = null;
+  this.q = null;
+  this.dmp1 = null;
+  this.dmq1 = null;
+  this.coeff = null;
+}
+
+/** 
+ * Set the public key fields N and e from hex strings
+ * @param N
+ * @param E
+ * @returns {RSASetPublic}
+ */
+function RSASetPublic(N,E) {
+  if(N != null && E != null && N.length > 0 && E.length > 0) {
+    this.n = parseBigInt(N,16);
+    this.e = parseInt(E,16);
+  }
+  else
+    alert("Invalid RSA public key");
+}
+
+/** 
+ * Perform raw public operation on "x": return x^e (mod n)
+ * @param x
+ * @returns x^e (mod n)
+ */
+function RSADoPublic(x) {
+  return x.modPowInt(this.e, this.n);
+}
+
+/**
+ * Return the PKCS#1 RSA encryption of "text" as an even-length hex string
+ */ 
+function RSAEncrypt(text) {
+  var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3);
+  if(m == null) return null;
+  var c = this.doPublic(m);
+  if(c == null) return null;
+  var h = c.toString(16);
+  if((h.length & 1) == 0) return h; else return "0" + h;
+}
+
+// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string
+//function RSAEncryptB64(text) {
+//  var h = this.encrypt(text);
+//  if(h) return hex2b64(h); else return null;
+//}
+
+// protected
+RSAKey.prototype.doPublic = RSADoPublic;
+
+// public
+RSAKey.prototype.setPublic = RSASetPublic;
+RSAKey.prototype.encrypt = RSAEncrypt;
+//RSAKey.prototype.encrypt_b64 = RSAEncryptB64;
diff --git a/js/securityLib/rsa2.js b/contrib/securityLib/rsa2.js
similarity index 99%
rename from js/securityLib/rsa2.js
rename to contrib/securityLib/rsa2.js
index d75814e..a474053 100644
--- a/js/securityLib/rsa2.js
+++ b/contrib/securityLib/rsa2.js
@@ -1,141 +1,141 @@
-// Depends on rsa.js and jsbn2.js
-
-// Version 1.1: support utf-8 decoding in pkcs1unpad2
-
-// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext
-function pkcs1unpad2(d,n) {
-  var b = d.toByteArray();
-  var i = 0;
-  while(i < b.length && b[i] == 0) ++i;
-  if(b.length-i != n-1 || b[i] != 2)
-    return null;
-  ++i;
-  while(b[i] != 0)
-    if(++i >= b.length) return null;
-  var ret = "";
-  while(++i < b.length) {
-    var c = b[i] & 255;
-    if(c < 128) { // utf-8 decode
-      ret += String.fromCharCode(c);
-    }
-    else if((c > 191) && (c < 224)) {
-      ret += String.fromCharCode(((c & 31) << 6) | (b[i+1] & 63));
-      ++i;
-    }
-    else {
-      ret += String.fromCharCode(((c & 15) << 12) | ((b[i+1] & 63) << 6) | (b[i+2] & 63));
-      i += 2;
-    }
-  }
-  return ret;
-}
-
-// Set the private key fields N, e, and d from hex strings
-function RSASetPrivate(N,E,D) {
-  if(N != null && E != null && N.length > 0 && E.length > 0) {
-    this.n = parseBigInt(N,16);
-    this.e = parseInt(E,16);
-    this.d = parseBigInt(D,16);
-  }
-  else
-    alert("Invalid RSA private key");
-}
-
-// Set the private key fields N, e, d and CRT params from hex strings
-function RSASetPrivateEx(N,E,D,P,Q,DP,DQ,C) {
-  if(N != null && E != null && N.length > 0 && E.length > 0) {
-    this.n = parseBigInt(N,16);
-    this.e = parseInt(E,16);
-    this.d = parseBigInt(D,16);
-    this.p = parseBigInt(P,16);
-    this.q = parseBigInt(Q,16);
-    this.dmp1 = parseBigInt(DP,16);
-    this.dmq1 = parseBigInt(DQ,16);
-    this.coeff = parseBigInt(C,16);
-  }
-  else
-    alert("Invalid RSA private key");
-}
-
-/**
- * Generate a new random private key B bits long, using public expt E
- */
-function RSAGenerate(B,E) {
-  var rng = new SecureRandom();
-  var qs = B>>1;
-  this.e = parseInt(E,16);
-  var ee = new BigInteger(E,16);
-  for(;;) {
-    for(;;) {
-      this.p = new BigInteger(B-qs,1,rng);
-      if(this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) break;
-    }
-    for(;;) {
-      this.q = new BigInteger(qs,1,rng);
-      if(this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) break;
-    }
-    if(this.p.compareTo(this.q) <= 0) {
-      var t = this.p;
-      this.p = this.q;
-      this.q = t;
-    }
-    var p1 = this.p.subtract(BigInteger.ONE);	// p1 = p - 1
-    var q1 = this.q.subtract(BigInteger.ONE);	// q1 = q - 1
-    var phi = p1.multiply(q1);
-    if(phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
-      this.n = this.p.multiply(this.q);	// this.n = p * q
-      this.d = ee.modInverse(phi);	// this.d = 
-      this.dmp1 = this.d.mod(p1);	// this.dmp1 = d mod (p - 1)
-      this.dmq1 = this.d.mod(q1);	// this.dmq1 = d mod (q - 1)
-      this.coeff = this.q.modInverse(this.p);	// this.coeff = (q ^ -1) mod p
-      break;
-    }
-  }
-}
-
-/**
- * Perform raw private operation on "x": return x^d (mod n)
- * @return x^d (mod n)
- */ 
-function RSADoPrivate(x) {
-  if(this.p == null || this.q == null)
-    return x.modPow(this.d, this.n);
-
-  // TODO: re-calculate any missing CRT params
-  var xp = x.mod(this.p).modPow(this.dmp1, this.p); // xp=cp?
-  var xq = x.mod(this.q).modPow(this.dmq1, this.q); // xq=cq?
-
-  while(xp.compareTo(xq) < 0)
-    xp = xp.add(this.p);
-  // NOTE:
-  // xp.subtract(xq) => cp -cq
-  // xp.subtract(xq).multiply(this.coeff).mod(this.p) => (cp - cq) * u mod p = h
-  // xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq) => cq + (h * q) = M
-  return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq);
-}
-
-// Return the PKCS#1 RSA decryption of "ctext".
-// "ctext" is an even-length hex string and the output is a plain string.
-function RSADecrypt(ctext) {
-  var c = parseBigInt(ctext, 16);
-  var m = this.doPrivate(c);
-  if(m == null) return null;
-  return pkcs1unpad2(m, (this.n.bitLength()+7)>>3);
-}
-
-// Return the PKCS#1 RSA decryption of "ctext".
-// "ctext" is a Base64-encoded string and the output is a plain string.
-//function RSAB64Decrypt(ctext) {
-//  var h = b64tohex(ctext);
-//  if(h) return this.decrypt(h); else return null;
-//}
-
-// protected
-RSAKey.prototype.doPrivate = RSADoPrivate;
-
-// public
-RSAKey.prototype.setPrivate = RSASetPrivate;
-RSAKey.prototype.setPrivateEx = RSASetPrivateEx;
-RSAKey.prototype.generate = RSAGenerate;
-RSAKey.prototype.decrypt = RSADecrypt;
-//RSAKey.prototype.b64_decrypt = RSAB64Decrypt;
+// Depends on rsa.js and jsbn2.js
+
+// Version 1.1: support utf-8 decoding in pkcs1unpad2
+
+// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext
+function pkcs1unpad2(d,n) {
+  var b = d.toByteArray();
+  var i = 0;
+  while(i < b.length && b[i] == 0) ++i;
+  if(b.length-i != n-1 || b[i] != 2)
+    return null;
+  ++i;
+  while(b[i] != 0)
+    if(++i >= b.length) return null;
+  var ret = "";
+  while(++i < b.length) {
+    var c = b[i] & 255;
+    if(c < 128) { // utf-8 decode
+      ret += String.fromCharCode(c);
+    }
+    else if((c > 191) && (c < 224)) {
+      ret += String.fromCharCode(((c & 31) << 6) | (b[i+1] & 63));
+      ++i;
+    }
+    else {
+      ret += String.fromCharCode(((c & 15) << 12) | ((b[i+1] & 63) << 6) | (b[i+2] & 63));
+      i += 2;
+    }
+  }
+  return ret;
+}
+
+// Set the private key fields N, e, and d from hex strings
+function RSASetPrivate(N,E,D) {
+  if(N != null && E != null && N.length > 0 && E.length > 0) {
+    this.n = parseBigInt(N,16);
+    this.e = parseInt(E,16);
+    this.d = parseBigInt(D,16);
+  }
+  else
+    alert("Invalid RSA private key");
+}
+
+// Set the private key fields N, e, d and CRT params from hex strings
+function RSASetPrivateEx(N,E,D,P,Q,DP,DQ,C) {
+  if(N != null && E != null && N.length > 0 && E.length > 0) {
+    this.n = parseBigInt(N,16);
+    this.e = parseInt(E,16);
+    this.d = parseBigInt(D,16);
+    this.p = parseBigInt(P,16);
+    this.q = parseBigInt(Q,16);
+    this.dmp1 = parseBigInt(DP,16);
+    this.dmq1 = parseBigInt(DQ,16);
+    this.coeff = parseBigInt(C,16);
+  }
+  else
+    alert("Invalid RSA private key");
+}
+
+/**
+ * Generate a new random private key B bits long, using public expt E
+ */
+function RSAGenerate(B,E) {
+  var rng = new SecureRandom();
+  var qs = B>>1;
+  this.e = parseInt(E,16);
+  var ee = new BigInteger(E,16);
+  for(;;) {
+    for(;;) {
+      this.p = new BigInteger(B-qs,1,rng);
+      if(this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) break;
+    }
+    for(;;) {
+      this.q = new BigInteger(qs,1,rng);
+      if(this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) break;
+    }
+    if(this.p.compareTo(this.q) <= 0) {
+      var t = this.p;
+      this.p = this.q;
+      this.q = t;
+    }
+    var p1 = this.p.subtract(BigInteger.ONE);	// p1 = p - 1
+    var q1 = this.q.subtract(BigInteger.ONE);	// q1 = q - 1
+    var phi = p1.multiply(q1);
+    if(phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
+      this.n = this.p.multiply(this.q);	// this.n = p * q
+      this.d = ee.modInverse(phi);	// this.d = 
+      this.dmp1 = this.d.mod(p1);	// this.dmp1 = d mod (p - 1)
+      this.dmq1 = this.d.mod(q1);	// this.dmq1 = d mod (q - 1)
+      this.coeff = this.q.modInverse(this.p);	// this.coeff = (q ^ -1) mod p
+      break;
+    }
+  }
+}
+
+/**
+ * Perform raw private operation on "x": return x^d (mod n)
+ * @return x^d (mod n)
+ */ 
+function RSADoPrivate(x) {
+  if(this.p == null || this.q == null)
+    return x.modPow(this.d, this.n);
+
+  // TODO: re-calculate any missing CRT params
+  var xp = x.mod(this.p).modPow(this.dmp1, this.p); // xp=cp?
+  var xq = x.mod(this.q).modPow(this.dmq1, this.q); // xq=cq?
+
+  while(xp.compareTo(xq) < 0)
+    xp = xp.add(this.p);
+  // NOTE:
+  // xp.subtract(xq) => cp -cq
+  // xp.subtract(xq).multiply(this.coeff).mod(this.p) => (cp - cq) * u mod p = h
+  // xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq) => cq + (h * q) = M
+  return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq);
+}
+
+// Return the PKCS#1 RSA decryption of "ctext".
+// "ctext" is an even-length hex string and the output is a plain string.
+function RSADecrypt(ctext) {
+  var c = parseBigInt(ctext, 16);
+  var m = this.doPrivate(c);
+  if(m == null) return null;
+  return pkcs1unpad2(m, (this.n.bitLength()+7)>>3);
+}
+
+// Return the PKCS#1 RSA decryption of "ctext".
+// "ctext" is a Base64-encoded string and the output is a plain string.
+//function RSAB64Decrypt(ctext) {
+//  var h = b64tohex(ctext);
+//  if(h) return this.decrypt(h); else return null;
+//}
+
+// protected
+RSAKey.prototype.doPrivate = RSADoPrivate;
+
+// public
+RSAKey.prototype.setPrivate = RSASetPrivate;
+RSAKey.prototype.setPrivateEx = RSASetPrivateEx;
+RSAKey.prototype.generate = RSAGenerate;
+RSAKey.prototype.decrypt = RSADecrypt;
+//RSAKey.prototype.b64_decrypt = RSAB64Decrypt;
diff --git a/js/securityLib/rsapem-1.1.js b/contrib/securityLib/rsapem-1.1.js
similarity index 99%
rename from js/securityLib/rsapem-1.1.js
rename to contrib/securityLib/rsapem-1.1.js
index 87b8cb4..7a8f762 100644
--- a/js/securityLib/rsapem-1.1.js
+++ b/contrib/securityLib/rsapem-1.1.js
@@ -1,81 +1,81 @@
-/*! rsapem-1.1.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
- */
-//
-// rsa-pem.js - adding function for reading/writing PKCS#1 PEM private key
-//              to RSAKey class.
-//
-// version: 1.1 (2012-May-10)
-//
-// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
-//
-// This software is licensed under the terms of the MIT License.
-// http://kjur.github.com/jsrsasign/license/
-//
-// The above copyright and license notice shall be 
-// included in all copies or substantial portions of the Software.
-// 
-//
-// Depends on:
-//
-//
-//
-// _RSApem_pemToBase64(sPEM)
-//
-//   removing PEM header, PEM footer and space characters including
-//   new lines from PEM formatted RSA private key string.
-//
-
-function _rsapem_pemToBase64(sPEMPrivateKey) {
-  var s = sPEMPrivateKey;
-  s = s.replace("-----BEGIN RSA PRIVATE KEY-----", "");
-  s = s.replace("-----END RSA PRIVATE KEY-----", "");
-  s = s.replace(/[ \n]+/g, "");
-  return s;
-}
-
-function _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey) {
-  var a = new Array();
-  var v1 = ASN1HEX.getStartPosOfV_AtObj(hPrivateKey, 0);
-  var n1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, v1);
-  var e1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, n1);
-  var d1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, e1);
-  var p1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, d1);
-  var q1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, p1);
-  var dp1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, q1);
-  var dq1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, dp1);
-  var co1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, dq1);
-  a.push(v1, n1, e1, d1, p1, q1, dp1, dq1, co1);
-  return a;
-}
-
-function _rsapem_getHexValueArrayOfChildrenFromHex(hPrivateKey) {
-  var posArray = _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey);
-  var v =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[0]);
-  var n =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[1]);
-  var e =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[2]);
-  var d =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[3]);
-  var p =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[4]);
-  var q =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[5]);
-  var dp = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[6]);
-  var dq = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[7]);
-  var co = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[8]);
-  var a = new Array();
-  a.push(v, n, e, d, p, q, dp, dq, co);
-  return a;
-}
-
-/**
- * read PKCS#1 private key from a string
- * @name readPrivateKeyFromPEMString
- * @memberOf RSAKey#
- * @function
- * @param {String} keyPEM string of PKCS#1 private key.
- */
-function _rsapem_readPrivateKeyFromPEMString(keyPEM) {
-  var keyB64 = _rsapem_pemToBase64(keyPEM);
-  var keyHex = b64tohex(keyB64) // depends base64.js
-  var a = _rsapem_getHexValueArrayOfChildrenFromHex(keyHex);
-  this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]);
-}
-
-RSAKey.prototype.readPrivateKeyFromPEMString = _rsapem_readPrivateKeyFromPEMString;
+/*! rsapem-1.1.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
+ */
+//
+// rsa-pem.js - adding function for reading/writing PKCS#1 PEM private key
+//              to RSAKey class.
+//
+// version: 1.1 (2012-May-10)
+//
+// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
+//
+// This software is licensed under the terms of the MIT License.
+// http://kjur.github.com/jsrsasign/license/
+//
+// The above copyright and license notice shall be 
+// included in all copies or substantial portions of the Software.
+// 
+//
+// Depends on:
+//
+//
+//
+// _RSApem_pemToBase64(sPEM)
+//
+//   removing PEM header, PEM footer and space characters including
+//   new lines from PEM formatted RSA private key string.
+//
+
+function _rsapem_pemToBase64(sPEMPrivateKey) {
+  var s = sPEMPrivateKey;
+  s = s.replace("-----BEGIN RSA PRIVATE KEY-----", "");
+  s = s.replace("-----END RSA PRIVATE KEY-----", "");
+  s = s.replace(/[ \n]+/g, "");
+  return s;
+}
+
+function _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey) {
+  var a = new Array();
+  var v1 = ASN1HEX.getStartPosOfV_AtObj(hPrivateKey, 0);
+  var n1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, v1);
+  var e1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, n1);
+  var d1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, e1);
+  var p1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, d1);
+  var q1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, p1);
+  var dp1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, q1);
+  var dq1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, dp1);
+  var co1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, dq1);
+  a.push(v1, n1, e1, d1, p1, q1, dp1, dq1, co1);
+  return a;
+}
+
+function _rsapem_getHexValueArrayOfChildrenFromHex(hPrivateKey) {
+  var posArray = _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey);
+  var v =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[0]);
+  var n =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[1]);
+  var e =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[2]);
+  var d =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[3]);
+  var p =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[4]);
+  var q =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[5]);
+  var dp = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[6]);
+  var dq = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[7]);
+  var co = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[8]);
+  var a = new Array();
+  a.push(v, n, e, d, p, q, dp, dq, co);
+  return a;
+}
+
+/**
+ * read PKCS#1 private key from a string
+ * @name readPrivateKeyFromPEMString
+ * @memberOf RSAKey#
+ * @function
+ * @param {String} keyPEM string of PKCS#1 private key.
+ */
+function _rsapem_readPrivateKeyFromPEMString(keyPEM) {
+  var keyB64 = _rsapem_pemToBase64(keyPEM);
+  var keyHex = b64tohex(keyB64) // depends base64.js
+  var a = _rsapem_getHexValueArrayOfChildrenFromHex(keyHex);
+  this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]);
+}
+
+RSAKey.prototype.readPrivateKeyFromPEMString = _rsapem_readPrivateKeyFromPEMString;
diff --git a/js/securityLib/rsapem-1.1.min.js b/contrib/securityLib/rsapem-1.1.min.js
similarity index 100%
rename from js/securityLib/rsapem-1.1.min.js
rename to contrib/securityLib/rsapem-1.1.min.js
diff --git a/js/securityLib/rsasign-1.2.js b/contrib/securityLib/rsasign-1.2.js
similarity index 99%
rename from js/securityLib/rsasign-1.2.js
rename to contrib/securityLib/rsasign-1.2.js
index 0da2827..906c901 100644
--- a/js/securityLib/rsasign-1.2.js
+++ b/contrib/securityLib/rsasign-1.2.js
@@ -1,374 +1,374 @@
-/*! rsasign-1.2.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
- */
-//
-// rsa-sign.js - adding signing functions to RSAKey class.
-//
-//
-// version: 1.2.1 (08 May 2012)
-//
-// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
-//
-// This software is licensed under the terms of the MIT License.
-// http://kjur.github.com/jsrsasign/license/
-//
-// The above copyright and license notice shall be 
-// included in all copies or substantial portions of the Software.
-
-//
-// Depends on:
-//   function sha1.hex(s) of sha1.js
-//   jsbn.js
-//   jsbn2.js
-//   rsa.js
-//   rsa2.js
-//
-
-// keysize / pmstrlen
-//  512 /  128
-// 1024 /  256
-// 2048 /  512
-// 4096 / 1024
-
-/**
- * @property {Dictionary} _RSASIGN_DIHEAD
- * @description Array of head part of hexadecimal DigestInfo value for hash algorithms.
- * You can add any DigestInfo hash algorith for signing.
- * See PKCS#1 v2.1 spec (p38).
- */
-var _RSASIGN_DIHEAD = [];
-_RSASIGN_DIHEAD['sha1'] =      "3021300906052b0e03021a05000414";
-_RSASIGN_DIHEAD['sha256'] =    "3031300d060960864801650304020105000420";
-_RSASIGN_DIHEAD['sha384'] =    "3041300d060960864801650304020205000430";
-_RSASIGN_DIHEAD['sha512'] =    "3051300d060960864801650304020305000440";
-_RSASIGN_DIHEAD['md2'] =       "3020300c06082a864886f70d020205000410";
-_RSASIGN_DIHEAD['md5'] =       "3020300c06082a864886f70d020505000410";
-_RSASIGN_DIHEAD['ripemd160'] = "3021300906052b2403020105000414";
-
-/**
- * @property {Dictionary} _RSASIGN_HASHHEXFUNC
- * @description Array of functions which calculate hash and returns it as hexadecimal.
- * You can add any hash algorithm implementations.
- */
-var _RSASIGN_HASHHEXFUNC = [];
-_RSASIGN_HASHHEXFUNC['sha1'] =      function(s){return hex_sha1(s);};  // http://pajhome.org.uk/crypt/md5/md5.html
-_RSASIGN_HASHHEXFUNC['sha256'] =    function(s){return hex_sha256(s);} // http://pajhome.org.uk/crypt/md5/md5.html
-_RSASIGN_HASHHEXFUNC['sha512'] =    function(s){return hex_sha512(s);} // http://pajhome.org.uk/crypt/md5/md5.html
-_RSASIGN_HASHHEXFUNC['md5'] =       function(s){return hex_md5(s);};   // http://pajhome.org.uk/crypt/md5/md5.html
-_RSASIGN_HASHHEXFUNC['ripemd160'] = function(s){return hex_rmd160(s);};   // http://pajhome.org.uk/crypt/md5/md5.html
-
-//@author axelcdv
-var _RSASIGN_HASHBYTEFUNC = [];
-_RSASIGN_HASHBYTEFUNC['sha256'] = 	function(byteArray){return hex_sha256_from_bytes(byteArray);};
-
-//_RSASIGN_HASHHEXFUNC['sha1'] =   function(s){return sha1.hex(s);}   // http://user1.matsumoto.ne.jp/~goma/js/hash.html
-//_RSASIGN_HASHHEXFUNC['sha256'] = function(s){return sha256.hex;}    // http://user1.matsumoto.ne.jp/~goma/js/hash.html
-
-var _RE_HEXDECONLY = new RegExp("");
-_RE_HEXDECONLY.compile("[^0-9a-f]", "gi");
-
-// ========================================================================
-// Signature Generation
-// ========================================================================
-
-function _rsasign_getHexPaddedDigestInfoForString(s, keySize, hashAlg) {
-  var pmStrLen = keySize / 4;
-  var hashFunc = _RSASIGN_HASHHEXFUNC[hashAlg];
-  var sHashHex = hashFunc(s);
-
-  var sHead = "0001";
-  var sTail = "00" + _RSASIGN_DIHEAD[hashAlg] + sHashHex;
-  var sMid = "";
-  var fLen = pmStrLen - sHead.length - sTail.length;
-  for (var i = 0; i < fLen; i += 2) {
-    sMid += "ff";
-  }
-  sPaddedMessageHex = sHead + sMid + sTail;
-  return sPaddedMessageHex;
-}
-
-
-//@author: Meki Cheraoui
-function _rsasign_getHexPaddedDigestInfoForStringHEX(s, keySize, hashAlg) {
-  var pmStrLen = keySize / 4;
-  var hashFunc = _RSASIGN_HASHHEXFUNC[hashAlg];
-  var sHashHex = hashFunc(s);
-
-  var sHead = "0001";
-  var sTail = "00" + _RSASIGN_DIHEAD[hashAlg] + sHashHex;
-  var sMid = "";
-  var fLen = pmStrLen - sHead.length - sTail.length;
-  for (var i = 0; i < fLen; i += 2) {
-    sMid += "ff";
-  }
-  sPaddedMessageHex = sHead + sMid + sTail;
-  return sPaddedMessageHex;
-}
-
-/**
- * Apply padding, then computes the hash of the given byte array, according to the key size and with the hash algorithm
- * @param byteArray (byte[])
- * @param keySize (int)
- * @param hashAlg the hash algorithm to apply (string)
- * @return the hash of byteArray
- */
-function _rsasign_getHexPaddedDigestInfoForByteArray(byteArray, keySize, hashAlg){
-	var pmStrLen = keySize / 4;
-	var hashFunc = _RSASIGN_HASHBYTEFUNC[hashAlg];
-	var sHashHex = hashFunc(byteArray); //returns hex hash
-	
-	var sHead = "0001";
-	  var sTail = "00" + _RSASIGN_DIHEAD[hashAlg] + sHashHex;
-	  var sMid = "";
-	  var fLen = pmStrLen - sHead.length - sTail.length;
-	  for (var i = 0; i < fLen; i += 2) {
-	    sMid += "ff";
-	  }
-	  sPaddedMessageHex = sHead + sMid + sTail;
-	  return sPaddedMessageHex;
-}
-
-function _zeroPaddingOfSignature(hex, bitLength) {
-  var s = "";
-  var nZero = bitLength / 4 - hex.length;
-  for (var i = 0; i < nZero; i++) {
-    s = s + "0";
-  }
-  return s + hex;
-}
-
-/**
- * sign for a message string with RSA private key.<br/>
- * @name signString
- * @memberOf RSAKey#
- * @function
- * @param {String} s message string to be signed.
- * @param {String} hashAlg hash algorithm name for signing.<br/>
- * @return returns hexadecimal string of signature value.
- */
-function _rsasign_signString(s, hashAlg) {
-  //alert("this.n.bitLength() = " + this.n.bitLength());
-  var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), hashAlg);
-  var biPaddedMessage = parseBigInt(hPM, 16);
-  var biSign = this.doPrivate(biPaddedMessage);
-  var hexSign = biSign.toString(16);
-  return _zeroPaddingOfSignature(hexSign, this.n.bitLength());
-}
-
-//@author: ucla-cs
-function _rsasign_signStringHEX(s, hashAlg) {
-  //alert("this.n.bitLength() = " + this.n.bitLength());
-  var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), hashAlg);
-  var biPaddedMessage = parseBigInt(hPM, 16);
-  var biSign = this.doPrivate(biPaddedMessage);
-  var hexSign = biSign.toString(16);
-  return _zeroPaddingOfSignature(hexSign, this.n.bitLength());
-}
-
-
-/**
- * Sign a message byteArray with an RSA private key
- * @name signByteArray
- * @memberOf RSAKey#
- * @function
- * @param {byte[]} byteArray
- * @param {Sring} hashAlg the hash algorithm to apply
- * @param {RSAKey} rsa key to sign with: hack because the context is lost here
- * @return hexadecimal string of signature value
- */
-function _rsasign_signByteArray(byteArray, hashAlg, rsaKey) {
-	var hPM = _rsasign_getHexPaddedDigestInfoForByteArray(byteArray, rsaKey.n.bitLength(), hashAlg); ///hack because the context is lost here
-	var biPaddedMessage = parseBigInt(hPM, 16);
-	var biSign = rsaKey.doPrivate(biPaddedMessage); //hack because the context is lost here
-	var hexSign = biSign.toString(16);
-	return _zeroPaddingOfSignature(hexSign, rsaKey.n.bitLength()); //hack because the context is lost here
-}
-
-/**
- * Sign a byte array with the Sha-256 algorithm
- * @param {byte[]} byteArray
- * @return hexadecimal string of signature value
- */
-function _rsasign_signByteArrayWithSHA256(byteArray){
-	return _rsasign_signByteArray(byteArray, 'sha256', this); //Hack because the context is lost in the next function
-}
-
-
-function _rsasign_signStringWithSHA1(s) {
-  return _rsasign_signString(s, 'sha1');
-}
-
-function _rsasign_signStringWithSHA256(s) {
-  return _rsasign_signString(s, 'sha256');
-}
-
-// ========================================================================
-// Signature Verification
-// ========================================================================
-
-function _rsasign_getDecryptSignatureBI(biSig, hN, hE) {
-  var rsa = new RSAKey();
-  rsa.setPublic(hN, hE);
-  var biDecryptedSig = rsa.doPublic(biSig);
-  return biDecryptedSig;
-}
-
-function _rsasign_getHexDigestInfoFromSig(biSig, hN, hE) {
-  var biDecryptedSig = _rsasign_getDecryptSignatureBI(biSig, hN, hE);
-  var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
-  return hDigestInfo;
-}
-
-function _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo) {
-  for (var algName in _RSASIGN_DIHEAD) {
-    var head = _RSASIGN_DIHEAD[algName];
-    var len = head.length;
-    if (hDigestInfo.substring(0, len) == head) {
-      var a = [algName, hDigestInfo.substring(len)];
-      return a;
-    }
-  }
-  return [];
-}
-
-function _rsasign_verifySignatureWithArgs(sMsg, biSig, hN, hE) {
-  var hDigestInfo = _rsasign_getHexDigestInfoFromSig(biSig, hN, hE);
-  var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);
-  if (digestInfoAry.length == 0) return false;
-  var algName = digestInfoAry[0];
-  var diHashValue = digestInfoAry[1];
-  var ff = _RSASIGN_HASHHEXFUNC[algName];
-  var msgHashValue = ff(sMsg);
-  return (diHashValue == msgHashValue);
-}
-
-function _rsasign_verifyHexSignatureForMessage(hSig, sMsg) {
-  var biSig = parseBigInt(hSig, 16);
-  var result = _rsasign_verifySignatureWithArgs(sMsg, biSig,
-						this.n.toString(16),
-						this.e.toString(16));
-  return result;
-}
-
-/**
- * verifies a sigature for a message string with RSA public key.<br/>
- * @name verifyString
- * @memberOf RSAKey#
- * @function
- * @param {String} sMsg message string to be verified.
- * @param {String} hSig hexadecimal string of siganture.<br/>
- *                 non-hexadecimal charactors including new lines will be ignored.
- * @return returns 1 if valid, otherwise 0
- */
-function _rsasign_verifyString(sMsg, hSig) {
-  hSig = hSig.replace(_RE_HEXDECONLY, '');
-  
-  if(LOG>3)console.log('n is '+this.n);
-  if(LOG>3)console.log('e is '+this.e);
-  
-  if (hSig.length != this.n.bitLength() / 4) return 0;
-  hSig = hSig.replace(/[ \n]+/g, "");
-  var biSig = parseBigInt(hSig, 16);
-  var biDecryptedSig = this.doPublic(biSig);
-  var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
-  var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);
-  
-  if (digestInfoAry.length == 0) return false;
-  var algName = digestInfoAry[0];
-  var diHashValue = digestInfoAry[1];
-  var ff = _RSASIGN_HASHHEXFUNC[algName];
-  var msgHashValue = ff(sMsg);
-  return (diHashValue == msgHashValue);
-}
-
-/**
- * verifies a sigature for a message byte array with RSA public key.<br/>
- * @name verifyByteArray
- * @memberOf RSAKey#
- * @function
- * @param {byte[]} byteArray message byte array to be verified.
- * @param {String} hSig hexadecimal string of signature.<br/>
- *                 non-hexadecimal charactors including new lines will be ignored.
- * @return returns 1 if valid, otherwise 0 
- */
-function _rsasign_verifyByteArray(byteArray, witness, hSig) {
-	hSig = hSig.replace(_RE_HEXDECONLY, '');
-	  
-	  if(LOG>3)console.log('n is '+this.n);
-	  if(LOG>3)console.log('e is '+this.e);
-	  
-	  if (hSig.length != this.n.bitLength() / 4) return 0;
-	  hSig = hSig.replace(/[ \n]+/g, "");
-	  var biSig = parseBigInt(hSig, 16);
-	  var biDecryptedSig = this.doPublic(biSig);
-	  var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
-	  var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);
-	  
-	  if (digestInfoAry.length == 0) return false;
-	  var algName = digestInfoAry[0];
-	  var diHashValue = digestInfoAry[1];
-	  var msgHashValue = null;
-	  
-	  if (witness == null) {
-	  	var ff = _RSASIGN_HASHBYTEFUNC[algName];
-	  	msgHashValue = ff(byteArray);
-	  } else {
-	  	// Compute merkle hash
-		  var h = hex_sha256_from_bytes(byteArray);
-		  var index = witness.path.index;
-		  for (var i = witness.path.digestList.length - 1; i >= 0; i--) {
-		  	var str = "";
-		  	if (index % 2 == 0) {
-		  		str = h + witness.path.digestList[i];
-		  	} else {
-		  		str = witness.path.digestList[i] + h;
-		  	}
-		  	h = hex_sha256_from_bytes(DataUtils.toNumbers(str));
-		  	index = Math.floor(index / 2);
-		  }
-		  msgHashValue = hex_sha256_from_bytes(DataUtils.toNumbers(h));
-	  }
-	  //console.log(diHashValue);
-	  //console.log(msgHashValue);
-	  return (diHashValue == msgHashValue);
-}
-
-
-RSAKey.prototype.signString = _rsasign_signString;
-
-RSAKey.prototype.signByteArray = _rsasign_signByteArray; //@author axelcdv
-RSAKey.prototype.signByteArrayWithSHA256 = _rsasign_signByteArrayWithSHA256; //@author axelcdv
-
-RSAKey.prototype.signStringWithSHA1 = _rsasign_signStringWithSHA1;
-RSAKey.prototype.signStringWithSHA256 = _rsasign_signStringWithSHA256;
-RSAKey.prototype.sign = _rsasign_signString;
-RSAKey.prototype.signWithSHA1 = _rsasign_signStringWithSHA1;
-RSAKey.prototype.signWithSHA256 = _rsasign_signStringWithSHA256;
-
-
-/*RSAKey.prototype.signStringHEX = _rsasign_signStringHEX;
-RSAKey.prototype.signStringWithSHA1HEX = _rsasign_signStringWithSHA1HEX;
-RSAKey.prototype.signStringWithSHA256HEX = _rsasign_signStringWithSHA256HEX;
-RSAKey.prototype.signHEX = _rsasign_signStringHEX;
-RSAKey.prototype.signWithSHA1HEX = _rsasign_signStringWithSHA1HEX;
-RSAKey.prototype.signWithSHA256HEX = _rsasign_signStringWithSHA256HEX;
-*/
-
-RSAKey.prototype.verifyByteArray = _rsasign_verifyByteArray;
-RSAKey.prototype.verifyString = _rsasign_verifyString;
-RSAKey.prototype.verifyHexSignatureForMessage = _rsasign_verifyHexSignatureForMessage;
-RSAKey.prototype.verify = _rsasign_verifyString;
-RSAKey.prototype.verifyHexSignatureForByteArrayMessage = _rsasign_verifyHexSignatureForMessage;
-
-/*
-RSAKey.prototype.verifyStringHEX = _rsasign_verifyStringHEX;
-RSAKey.prototype.verifyHexSignatureForMessageHEX = _rsasign_verifyHexSignatureForMessageHEX;
-RSAKey.prototype.verifyHEX = _rsasign_verifyStringHEX;
-RSAKey.prototype.verifyHexSignatureForByteArrayMessageHEX = _rsasign_verifyHexSignatureForMessageHEX;
-*/
-	
-	
-/**
- * @name RSAKey
- * @class
- * @description Tom Wu's RSA Key class and extension
- */
+/*! rsasign-1.2.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
+ */
+//
+// rsa-sign.js - adding signing functions to RSAKey class.
+//
+//
+// version: 1.2.1 (08 May 2012)
+//
+// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
+//
+// This software is licensed under the terms of the MIT License.
+// http://kjur.github.com/jsrsasign/license/
+//
+// The above copyright and license notice shall be 
+// included in all copies or substantial portions of the Software.
+
+//
+// Depends on:
+//   function sha1.hex(s) of sha1.js
+//   jsbn.js
+//   jsbn2.js
+//   rsa.js
+//   rsa2.js
+//
+
+// keysize / pmstrlen
+//  512 /  128
+// 1024 /  256
+// 2048 /  512
+// 4096 / 1024
+
+/**
+ * @property {Dictionary} _RSASIGN_DIHEAD
+ * @description Array of head part of hexadecimal DigestInfo value for hash algorithms.
+ * You can add any DigestInfo hash algorith for signing.
+ * See PKCS#1 v2.1 spec (p38).
+ */
+var _RSASIGN_DIHEAD = [];
+_RSASIGN_DIHEAD['sha1'] =      "3021300906052b0e03021a05000414";
+_RSASIGN_DIHEAD['sha256'] =    "3031300d060960864801650304020105000420";
+_RSASIGN_DIHEAD['sha384'] =    "3041300d060960864801650304020205000430";
+_RSASIGN_DIHEAD['sha512'] =    "3051300d060960864801650304020305000440";
+_RSASIGN_DIHEAD['md2'] =       "3020300c06082a864886f70d020205000410";
+_RSASIGN_DIHEAD['md5'] =       "3020300c06082a864886f70d020505000410";
+_RSASIGN_DIHEAD['ripemd160'] = "3021300906052b2403020105000414";
+
+/**
+ * @property {Dictionary} _RSASIGN_HASHHEXFUNC
+ * @description Array of functions which calculate hash and returns it as hexadecimal.
+ * You can add any hash algorithm implementations.
+ */
+var _RSASIGN_HASHHEXFUNC = [];
+_RSASIGN_HASHHEXFUNC['sha1'] =      function(s){return hex_sha1(s);};  // http://pajhome.org.uk/crypt/md5/md5.html
+_RSASIGN_HASHHEXFUNC['sha256'] =    function(s){return hex_sha256(s);} // http://pajhome.org.uk/crypt/md5/md5.html
+_RSASIGN_HASHHEXFUNC['sha512'] =    function(s){return hex_sha512(s);} // http://pajhome.org.uk/crypt/md5/md5.html
+_RSASIGN_HASHHEXFUNC['md5'] =       function(s){return hex_md5(s);};   // http://pajhome.org.uk/crypt/md5/md5.html
+_RSASIGN_HASHHEXFUNC['ripemd160'] = function(s){return hex_rmd160(s);};   // http://pajhome.org.uk/crypt/md5/md5.html
+
+//@author axelcdv
+var _RSASIGN_HASHBYTEFUNC = [];
+_RSASIGN_HASHBYTEFUNC['sha256'] = 	function(byteArray){return hex_sha256_from_bytes(byteArray);};
+
+//_RSASIGN_HASHHEXFUNC['sha1'] =   function(s){return sha1.hex(s);}   // http://user1.matsumoto.ne.jp/~goma/js/hash.html
+//_RSASIGN_HASHHEXFUNC['sha256'] = function(s){return sha256.hex;}    // http://user1.matsumoto.ne.jp/~goma/js/hash.html
+
+var _RE_HEXDECONLY = new RegExp("");
+_RE_HEXDECONLY.compile("[^0-9a-f]", "gi");
+
+// ========================================================================
+// Signature Generation
+// ========================================================================
+
+function _rsasign_getHexPaddedDigestInfoForString(s, keySize, hashAlg) {
+  var pmStrLen = keySize / 4;
+  var hashFunc = _RSASIGN_HASHHEXFUNC[hashAlg];
+  var sHashHex = hashFunc(s);
+
+  var sHead = "0001";
+  var sTail = "00" + _RSASIGN_DIHEAD[hashAlg] + sHashHex;
+  var sMid = "";
+  var fLen = pmStrLen - sHead.length - sTail.length;
+  for (var i = 0; i < fLen; i += 2) {
+    sMid += "ff";
+  }
+  sPaddedMessageHex = sHead + sMid + sTail;
+  return sPaddedMessageHex;
+}
+
+
+//@author: Meki Cheraoui
+function _rsasign_getHexPaddedDigestInfoForStringHEX(s, keySize, hashAlg) {
+  var pmStrLen = keySize / 4;
+  var hashFunc = _RSASIGN_HASHHEXFUNC[hashAlg];
+  var sHashHex = hashFunc(s);
+
+  var sHead = "0001";
+  var sTail = "00" + _RSASIGN_DIHEAD[hashAlg] + sHashHex;
+  var sMid = "";
+  var fLen = pmStrLen - sHead.length - sTail.length;
+  for (var i = 0; i < fLen; i += 2) {
+    sMid += "ff";
+  }
+  sPaddedMessageHex = sHead + sMid + sTail;
+  return sPaddedMessageHex;
+}
+
+/**
+ * Apply padding, then computes the hash of the given byte array, according to the key size and with the hash algorithm
+ * @param byteArray (byte[])
+ * @param keySize (int)
+ * @param hashAlg the hash algorithm to apply (string)
+ * @return the hash of byteArray
+ */
+function _rsasign_getHexPaddedDigestInfoForByteArray(byteArray, keySize, hashAlg){
+	var pmStrLen = keySize / 4;
+	var hashFunc = _RSASIGN_HASHBYTEFUNC[hashAlg];
+	var sHashHex = hashFunc(byteArray); //returns hex hash
+	
+	var sHead = "0001";
+	  var sTail = "00" + _RSASIGN_DIHEAD[hashAlg] + sHashHex;
+	  var sMid = "";
+	  var fLen = pmStrLen - sHead.length - sTail.length;
+	  for (var i = 0; i < fLen; i += 2) {
+	    sMid += "ff";
+	  }
+	  sPaddedMessageHex = sHead + sMid + sTail;
+	  return sPaddedMessageHex;
+}
+
+function _zeroPaddingOfSignature(hex, bitLength) {
+  var s = "";
+  var nZero = bitLength / 4 - hex.length;
+  for (var i = 0; i < nZero; i++) {
+    s = s + "0";
+  }
+  return s + hex;
+}
+
+/**
+ * sign for a message string with RSA private key.<br/>
+ * @name signString
+ * @memberOf RSAKey#
+ * @function
+ * @param {String} s message string to be signed.
+ * @param {String} hashAlg hash algorithm name for signing.<br/>
+ * @return returns hexadecimal string of signature value.
+ */
+function _rsasign_signString(s, hashAlg) {
+  //alert("this.n.bitLength() = " + this.n.bitLength());
+  var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), hashAlg);
+  var biPaddedMessage = parseBigInt(hPM, 16);
+  var biSign = this.doPrivate(biPaddedMessage);
+  var hexSign = biSign.toString(16);
+  return _zeroPaddingOfSignature(hexSign, this.n.bitLength());
+}
+
+//@author: ucla-cs
+function _rsasign_signStringHEX(s, hashAlg) {
+  //alert("this.n.bitLength() = " + this.n.bitLength());
+  var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), hashAlg);
+  var biPaddedMessage = parseBigInt(hPM, 16);
+  var biSign = this.doPrivate(biPaddedMessage);
+  var hexSign = biSign.toString(16);
+  return _zeroPaddingOfSignature(hexSign, this.n.bitLength());
+}
+
+
+/**
+ * Sign a message byteArray with an RSA private key
+ * @name signByteArray
+ * @memberOf RSAKey#
+ * @function
+ * @param {byte[]} byteArray
+ * @param {Sring} hashAlg the hash algorithm to apply
+ * @param {RSAKey} rsa key to sign with: hack because the context is lost here
+ * @return hexadecimal string of signature value
+ */
+function _rsasign_signByteArray(byteArray, hashAlg, rsaKey) {
+	var hPM = _rsasign_getHexPaddedDigestInfoForByteArray(byteArray, rsaKey.n.bitLength(), hashAlg); ///hack because the context is lost here
+	var biPaddedMessage = parseBigInt(hPM, 16);
+	var biSign = rsaKey.doPrivate(biPaddedMessage); //hack because the context is lost here
+	var hexSign = biSign.toString(16);
+	return _zeroPaddingOfSignature(hexSign, rsaKey.n.bitLength()); //hack because the context is lost here
+}
+
+/**
+ * Sign a byte array with the Sha-256 algorithm
+ * @param {byte[]} byteArray
+ * @return hexadecimal string of signature value
+ */
+function _rsasign_signByteArrayWithSHA256(byteArray){
+	return _rsasign_signByteArray(byteArray, 'sha256', this); //Hack because the context is lost in the next function
+}
+
+
+function _rsasign_signStringWithSHA1(s) {
+  return _rsasign_signString(s, 'sha1');
+}
+
+function _rsasign_signStringWithSHA256(s) {
+  return _rsasign_signString(s, 'sha256');
+}
+
+// ========================================================================
+// Signature Verification
+// ========================================================================
+
+function _rsasign_getDecryptSignatureBI(biSig, hN, hE) {
+  var rsa = new RSAKey();
+  rsa.setPublic(hN, hE);
+  var biDecryptedSig = rsa.doPublic(biSig);
+  return biDecryptedSig;
+}
+
+function _rsasign_getHexDigestInfoFromSig(biSig, hN, hE) {
+  var biDecryptedSig = _rsasign_getDecryptSignatureBI(biSig, hN, hE);
+  var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
+  return hDigestInfo;
+}
+
+function _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo) {
+  for (var algName in _RSASIGN_DIHEAD) {
+    var head = _RSASIGN_DIHEAD[algName];
+    var len = head.length;
+    if (hDigestInfo.substring(0, len) == head) {
+      var a = [algName, hDigestInfo.substring(len)];
+      return a;
+    }
+  }
+  return [];
+}
+
+function _rsasign_verifySignatureWithArgs(sMsg, biSig, hN, hE) {
+  var hDigestInfo = _rsasign_getHexDigestInfoFromSig(biSig, hN, hE);
+  var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);
+  if (digestInfoAry.length == 0) return false;
+  var algName = digestInfoAry[0];
+  var diHashValue = digestInfoAry[1];
+  var ff = _RSASIGN_HASHHEXFUNC[algName];
+  var msgHashValue = ff(sMsg);
+  return (diHashValue == msgHashValue);
+}
+
+function _rsasign_verifyHexSignatureForMessage(hSig, sMsg) {
+  var biSig = parseBigInt(hSig, 16);
+  var result = _rsasign_verifySignatureWithArgs(sMsg, biSig,
+						this.n.toString(16),
+						this.e.toString(16));
+  return result;
+}
+
+/**
+ * verifies a sigature for a message string with RSA public key.<br/>
+ * @name verifyString
+ * @memberOf RSAKey#
+ * @function
+ * @param {String} sMsg message string to be verified.
+ * @param {String} hSig hexadecimal string of siganture.<br/>
+ *                 non-hexadecimal charactors including new lines will be ignored.
+ * @return returns 1 if valid, otherwise 0
+ */
+function _rsasign_verifyString(sMsg, hSig) {
+  hSig = hSig.replace(_RE_HEXDECONLY, '');
+  
+  if(LOG>3)console.log('n is '+this.n);
+  if(LOG>3)console.log('e is '+this.e);
+  
+  if (hSig.length != this.n.bitLength() / 4) return 0;
+  hSig = hSig.replace(/[ \n]+/g, "");
+  var biSig = parseBigInt(hSig, 16);
+  var biDecryptedSig = this.doPublic(biSig);
+  var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
+  var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);
+  
+  if (digestInfoAry.length == 0) return false;
+  var algName = digestInfoAry[0];
+  var diHashValue = digestInfoAry[1];
+  var ff = _RSASIGN_HASHHEXFUNC[algName];
+  var msgHashValue = ff(sMsg);
+  return (diHashValue == msgHashValue);
+}
+
+/**
+ * verifies a sigature for a message byte array with RSA public key.<br/>
+ * @name verifyByteArray
+ * @memberOf RSAKey#
+ * @function
+ * @param {byte[]} byteArray message byte array to be verified.
+ * @param {String} hSig hexadecimal string of signature.<br/>
+ *                 non-hexadecimal charactors including new lines will be ignored.
+ * @return returns 1 if valid, otherwise 0 
+ */
+function _rsasign_verifyByteArray(byteArray, witness, hSig) {
+	hSig = hSig.replace(_RE_HEXDECONLY, '');
+	  
+	  if(LOG>3)console.log('n is '+this.n);
+	  if(LOG>3)console.log('e is '+this.e);
+	  
+	  if (hSig.length != this.n.bitLength() / 4) return 0;
+	  hSig = hSig.replace(/[ \n]+/g, "");
+	  var biSig = parseBigInt(hSig, 16);
+	  var biDecryptedSig = this.doPublic(biSig);
+	  var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
+	  var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);
+	  
+	  if (digestInfoAry.length == 0) return false;
+	  var algName = digestInfoAry[0];
+	  var diHashValue = digestInfoAry[1];
+	  var msgHashValue = null;
+	  
+	  if (witness == null) {
+	  	var ff = _RSASIGN_HASHBYTEFUNC[algName];
+	  	msgHashValue = ff(byteArray);
+	  } else {
+	  	// Compute merkle hash
+		  var h = hex_sha256_from_bytes(byteArray);
+		  var index = witness.path.index;
+		  for (var i = witness.path.digestList.length - 1; i >= 0; i--) {
+		  	var str = "";
+		  	if (index % 2 == 0) {
+		  		str = h + witness.path.digestList[i];
+		  	} else {
+		  		str = witness.path.digestList[i] + h;
+		  	}
+		  	h = hex_sha256_from_bytes(DataUtils.toNumbers(str));
+		  	index = Math.floor(index / 2);
+		  }
+		  msgHashValue = hex_sha256_from_bytes(DataUtils.toNumbers(h));
+	  }
+	  //console.log(diHashValue);
+	  //console.log(msgHashValue);
+	  return (diHashValue == msgHashValue);
+}
+
+
+RSAKey.prototype.signString = _rsasign_signString;
+
+RSAKey.prototype.signByteArray = _rsasign_signByteArray; //@author axelcdv
+RSAKey.prototype.signByteArrayWithSHA256 = _rsasign_signByteArrayWithSHA256; //@author axelcdv
+
+RSAKey.prototype.signStringWithSHA1 = _rsasign_signStringWithSHA1;
+RSAKey.prototype.signStringWithSHA256 = _rsasign_signStringWithSHA256;
+RSAKey.prototype.sign = _rsasign_signString;
+RSAKey.prototype.signWithSHA1 = _rsasign_signStringWithSHA1;
+RSAKey.prototype.signWithSHA256 = _rsasign_signStringWithSHA256;
+
+
+/*RSAKey.prototype.signStringHEX = _rsasign_signStringHEX;
+RSAKey.prototype.signStringWithSHA1HEX = _rsasign_signStringWithSHA1HEX;
+RSAKey.prototype.signStringWithSHA256HEX = _rsasign_signStringWithSHA256HEX;
+RSAKey.prototype.signHEX = _rsasign_signStringHEX;
+RSAKey.prototype.signWithSHA1HEX = _rsasign_signStringWithSHA1HEX;
+RSAKey.prototype.signWithSHA256HEX = _rsasign_signStringWithSHA256HEX;
+*/
+
+RSAKey.prototype.verifyByteArray = _rsasign_verifyByteArray;
+RSAKey.prototype.verifyString = _rsasign_verifyString;
+RSAKey.prototype.verifyHexSignatureForMessage = _rsasign_verifyHexSignatureForMessage;
+RSAKey.prototype.verify = _rsasign_verifyString;
+RSAKey.prototype.verifyHexSignatureForByteArrayMessage = _rsasign_verifyHexSignatureForMessage;
+
+/*
+RSAKey.prototype.verifyStringHEX = _rsasign_verifyStringHEX;
+RSAKey.prototype.verifyHexSignatureForMessageHEX = _rsasign_verifyHexSignatureForMessageHEX;
+RSAKey.prototype.verifyHEX = _rsasign_verifyStringHEX;
+RSAKey.prototype.verifyHexSignatureForByteArrayMessageHEX = _rsasign_verifyHexSignatureForMessageHEX;
+*/
+	
+	
+/**
+ * @name RSAKey
+ * @class
+ * @description Tom Wu's RSA Key class and extension
+ */
diff --git a/js/securityLib/rsasign-1.2.min.js b/contrib/securityLib/rsasign-1.2.min.js
similarity index 100%
rename from js/securityLib/rsasign-1.2.min.js
rename to contrib/securityLib/rsasign-1.2.min.js
diff --git a/js/securityLib/sha1.js b/contrib/securityLib/sha1.js
similarity index 99%
rename from js/securityLib/sha1.js
rename to contrib/securityLib/sha1.js
index 0e5b5b7..697bce7 100644
--- a/js/securityLib/sha1.js
+++ b/contrib/securityLib/sha1.js
@@ -1,330 +1,330 @@
-/*
- * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
- * in FIPS 180-1
- * Version 2.2 Copyright Paul Johnston 2000 - 2009.
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for details.
- */
-
-/*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
-var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
-var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
-
-/**
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
-function hex_sha1(s)    { return rstr2hex(rstr_sha1(str2rstr_utf8(s))); }
-function b64_sha1(s)    { return rstr2b64(rstr_sha1(str2rstr_utf8(s))); }
-function any_sha1(s, e) { return rstr2any(rstr_sha1(str2rstr_utf8(s)), e); }
-function hex_hmac_sha1(k, d)
-  { return rstr2hex(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function b64_hmac_sha1(k, d)
-  { return rstr2b64(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function any_hmac_sha1(k, d, e)
-  { return rstr2any(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
-
-/**
- * Perform a simple self-test to see if the VM is working
- */
-function sha1_vm_test()
-{
-  return hex_sha1("abc").toLowerCase() == "a9993e364706816aba3e25717850c26c9cd0d89d";
-}
-
-/**
- * Calculate the SHA1 of a raw string
- */
-function rstr_sha1(s)
-{
-  return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8));
-}
-
-/**
- * Calculate the HMAC-SHA1 of a key and some data (raw strings)
- */
-function rstr_hmac_sha1(key, data)
-{
-  var bkey = rstr2binb(key);
-  if(bkey.length > 16) bkey = binb_sha1(bkey, key.length * 8);
-
-  var ipad = Array(16), opad = Array(16);
-  for(var i = 0; i < 16; i++)
-  {
-    ipad[i] = bkey[i] ^ 0x36363636;
-    opad[i] = bkey[i] ^ 0x5C5C5C5C;
-  }
-
-  var hash = binb_sha1(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
-  return binb2rstr(binb_sha1(opad.concat(hash), 512 + 160));
-}
-
-/**
- * Convert a raw string to a hex string
- */
-function rstr2hex(input)
-{
-  try { hexcase } catch(e) { hexcase=0; }
-  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
-  var output = "";
-  var x;
-  for(var i = 0; i < input.length; i++)
-  {
-    x = input.charCodeAt(i);
-    output += hex_tab.charAt((x >>> 4) & 0x0F)
-           +  hex_tab.charAt( x        & 0x0F);
-  }
-  return output;
-}
-
-/**
- * Convert a raw string to a base-64 string
- */
-function rstr2b64(input)
-{
-  try { b64pad } catch(e) { b64pad=''; }
-  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-  var output = "";
-  var len = input.length;
-  for(var i = 0; i < len; i += 3)
-  {
-    var triplet = (input.charCodeAt(i) << 16)
-                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
-                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
-    for(var j = 0; j < 4; j++)
-    {
-      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
-      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
-    }
-  }
-  return output;
-}
-
-/**
- * Convert a raw string to an arbitrary string encoding
- */
-function rstr2any(input, encoding)
-{
-  var divisor = encoding.length;
-  var remainders = Array();
-  var i, q, x, quotient;
-
-  /* Convert to an array of 16-bit big-endian values, forming the dividend */
-  var dividend = Array(Math.ceil(input.length / 2));
-  for(i = 0; i < dividend.length; i++)
-  {
-    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
-  }
-
-  /*
-   * Repeatedly perform a long division. The binary array forms the dividend,
-   * the length of the encoding is the divisor. Once computed, the quotient
-   * forms the dividend for the next step. We stop when the dividend is zero.
-   * All remainders are stored for later use.
-   */
-  while(dividend.length > 0)
-  {
-    quotient = Array();
-    x = 0;
-    for(i = 0; i < dividend.length; i++)
-    {
-      x = (x << 16) + dividend[i];
-      q = Math.floor(x / divisor);
-      x -= q * divisor;
-      if(quotient.length > 0 || q > 0)
-        quotient[quotient.length] = q;
-    }
-    remainders[remainders.length] = x;
-    dividend = quotient;
-  }
-
-  /* Convert the remainders to the output string */
-  var output = "";
-  for(i = remainders.length - 1; i >= 0; i--)
-    output += encoding.charAt(remainders[i]);
-
-  /* Append leading zero equivalents */
-  var full_length = Math.ceil(input.length * 8 /
-                                    (Math.log(encoding.length) / Math.log(2)));
-  for(i = output.length; i < full_length; i++)
-    output = encoding[0] + output;
-
-  return output;
-}
-
-/**
- * Encode a string as utf-8.
- * For efficiency, this assumes the input is valid utf-16.
- */
-function str2rstr_utf8(input)
-{
-  var output = "";
-  var i = -1;
-  var x, y;
-
-  while(++i < input.length)
-  {
-    /* Decode utf-16 surrogate pairs */
-    x = input.charCodeAt(i);
-    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
-    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
-    {
-      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
-      i++;
-    }
-
-    /* Encode output as utf-8 */
-    if(x <= 0x7F)
-      output += String.fromCharCode(x);
-    else if(x <= 0x7FF)
-      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
-                                    0x80 | ( x         & 0x3F));
-    else if(x <= 0xFFFF)
-      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
-                                    0x80 | ((x >>> 6 ) & 0x3F),
-                                    0x80 | ( x         & 0x3F));
-    else if(x <= 0x1FFFFF)
-      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
-                                    0x80 | ((x >>> 12) & 0x3F),
-                                    0x80 | ((x >>> 6 ) & 0x3F),
-                                    0x80 | ( x         & 0x3F));
-  }
-  return output;
-}
-
-/**
- * Encode a string as utf-16
- */
-function str2rstr_utf16le(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length; i++)
-    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
-                                  (input.charCodeAt(i) >>> 8) & 0xFF);
-  return output;
-}
-
-function str2rstr_utf16be(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length; i++)
-    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
-                                   input.charCodeAt(i)        & 0xFF);
-  return output;
-}
-
-/**
- * Convert a raw string to an array of big-endian words
- * Characters >255 have their high-byte silently ignored.
- */
-function rstr2binb(input)
-{
-  var output = Array(input.length >> 2);
-  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;
-}
-
-/**
- * Convert an array of big-endian words to a string
- */
-function binb2rstr(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length * 32; i += 8)
-    output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
-  return output;
-}
-
-/**
- * Calculate the SHA-1 of an array of big-endian words, and a bit length
- */
-function binb_sha1(x, len)
-{
-  /* append padding */
-  x[len >> 5] |= 0x80 << (24 - len % 32);
-  x[((len + 64 >> 9) << 4) + 15] = len;
-
-  var w = Array(80);
-  var a =  1732584193;
-  var b = -271733879;
-  var c = -1732584194;
-  var d =  271733878;
-  var e = -1009589776;
-
-  for(var i = 0; i < x.length; i += 16)
-  {
-    var olda = a;
-    var oldb = b;
-    var oldc = c;
-    var oldd = d;
-    var olde = e;
-
-    for(var j = 0; j < 80; j++)
-    {
-      if(j < 16) w[j] = x[i + j];
-      else w[j] = bit_rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
-      var t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
-                       safe_add(safe_add(e, w[j]), sha1_kt(j)));
-      e = d;
-      d = c;
-      c = bit_rol(b, 30);
-      b = a;
-      a = t;
-    }
-
-    a = safe_add(a, olda);
-    b = safe_add(b, oldb);
-    c = safe_add(c, oldc);
-    d = safe_add(d, oldd);
-    e = safe_add(e, olde);
-  }
-  return Array(a, b, c, d, e);
-
-}
-
-/**
- * Perform the appropriate triplet combination function for the current
- * iteration
- */
-function sha1_ft(t, b, c, d)
-{
-  if(t < 20) return (b & c) | ((~b) & d);
-  if(t < 40) return b ^ c ^ d;
-  if(t < 60) return (b & c) | (b & d) | (c & d);
-  return b ^ c ^ d;
-}
-
-/**
- * Determine the appropriate additive constant for the current iteration
- */
-function sha1_kt(t)
-{
-  return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
-         (t < 60) ? -1894007588 : -899497514;
-}
-
-/**
- * Add integers, wrapping at 2^32. This uses 16-bit operations internally
- * to work around bugs in some JS interpreters.
- */
-function safe_add(x, y)
-{
-  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
-  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
-  return (msw << 16) | (lsw & 0xFFFF);
-}
-
-/**
- * Bitwise rotate a 32-bit number to the left.
- */
-function bit_rol(num, cnt)
-{
-  return (num << cnt) | (num >>> (32 - cnt));
-}
+/*
+ * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
+ * in FIPS 180-1
+ * Version 2.2 Copyright Paul Johnston 2000 - 2009.
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ * Distributed under the BSD License
+ * See http://pajhome.org.uk/crypt/md5 for details.
+ */
+
+/*
+ * Configurable variables. You may need to tweak these to be compatible with
+ * the server-side, but the defaults work in most cases.
+ */
+var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
+var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
+
+/**
+ * These are the functions you'll usually want to call
+ * They take string arguments and return either hex or base-64 encoded strings
+ */
+function hex_sha1(s)    { return rstr2hex(rstr_sha1(str2rstr_utf8(s))); }
+function b64_sha1(s)    { return rstr2b64(rstr_sha1(str2rstr_utf8(s))); }
+function any_sha1(s, e) { return rstr2any(rstr_sha1(str2rstr_utf8(s)), e); }
+function hex_hmac_sha1(k, d)
+  { return rstr2hex(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
+function b64_hmac_sha1(k, d)
+  { return rstr2b64(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
+function any_hmac_sha1(k, d, e)
+  { return rstr2any(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
+
+/**
+ * Perform a simple self-test to see if the VM is working
+ */
+function sha1_vm_test()
+{
+  return hex_sha1("abc").toLowerCase() == "a9993e364706816aba3e25717850c26c9cd0d89d";
+}
+
+/**
+ * Calculate the SHA1 of a raw string
+ */
+function rstr_sha1(s)
+{
+  return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8));
+}
+
+/**
+ * Calculate the HMAC-SHA1 of a key and some data (raw strings)
+ */
+function rstr_hmac_sha1(key, data)
+{
+  var bkey = rstr2binb(key);
+  if(bkey.length > 16) bkey = binb_sha1(bkey, key.length * 8);
+
+  var ipad = Array(16), opad = Array(16);
+  for(var i = 0; i < 16; i++)
+  {
+    ipad[i] = bkey[i] ^ 0x36363636;
+    opad[i] = bkey[i] ^ 0x5C5C5C5C;
+  }
+
+  var hash = binb_sha1(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
+  return binb2rstr(binb_sha1(opad.concat(hash), 512 + 160));
+}
+
+/**
+ * Convert a raw string to a hex string
+ */
+function rstr2hex(input)
+{
+  try { hexcase } catch(e) { hexcase=0; }
+  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+  var output = "";
+  var x;
+  for(var i = 0; i < input.length; i++)
+  {
+    x = input.charCodeAt(i);
+    output += hex_tab.charAt((x >>> 4) & 0x0F)
+           +  hex_tab.charAt( x        & 0x0F);
+  }
+  return output;
+}
+
+/**
+ * Convert a raw string to a base-64 string
+ */
+function rstr2b64(input)
+{
+  try { b64pad } catch(e) { b64pad=''; }
+  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+  var output = "";
+  var len = input.length;
+  for(var i = 0; i < len; i += 3)
+  {
+    var triplet = (input.charCodeAt(i) << 16)
+                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
+                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
+    for(var j = 0; j < 4; j++)
+    {
+      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
+      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
+    }
+  }
+  return output;
+}
+
+/**
+ * Convert a raw string to an arbitrary string encoding
+ */
+function rstr2any(input, encoding)
+{
+  var divisor = encoding.length;
+  var remainders = Array();
+  var i, q, x, quotient;
+
+  /* Convert to an array of 16-bit big-endian values, forming the dividend */
+  var dividend = Array(Math.ceil(input.length / 2));
+  for(i = 0; i < dividend.length; i++)
+  {
+    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
+  }
+
+  /*
+   * Repeatedly perform a long division. The binary array forms the dividend,
+   * the length of the encoding is the divisor. Once computed, the quotient
+   * forms the dividend for the next step. We stop when the dividend is zero.
+   * All remainders are stored for later use.
+   */
+  while(dividend.length > 0)
+  {
+    quotient = Array();
+    x = 0;
+    for(i = 0; i < dividend.length; i++)
+    {
+      x = (x << 16) + dividend[i];
+      q = Math.floor(x / divisor);
+      x -= q * divisor;
+      if(quotient.length > 0 || q > 0)
+        quotient[quotient.length] = q;
+    }
+    remainders[remainders.length] = x;
+    dividend = quotient;
+  }
+
+  /* Convert the remainders to the output string */
+  var output = "";
+  for(i = remainders.length - 1; i >= 0; i--)
+    output += encoding.charAt(remainders[i]);
+
+  /* Append leading zero equivalents */
+  var full_length = Math.ceil(input.length * 8 /
+                                    (Math.log(encoding.length) / Math.log(2)));
+  for(i = output.length; i < full_length; i++)
+    output = encoding[0] + output;
+
+  return output;
+}
+
+/**
+ * Encode a string as utf-8.
+ * For efficiency, this assumes the input is valid utf-16.
+ */
+function str2rstr_utf8(input)
+{
+  var output = "";
+  var i = -1;
+  var x, y;
+
+  while(++i < input.length)
+  {
+    /* Decode utf-16 surrogate pairs */
+    x = input.charCodeAt(i);
+    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
+    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
+    {
+      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
+      i++;
+    }
+
+    /* Encode output as utf-8 */
+    if(x <= 0x7F)
+      output += String.fromCharCode(x);
+    else if(x <= 0x7FF)
+      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
+                                    0x80 | ( x         & 0x3F));
+    else if(x <= 0xFFFF)
+      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
+                                    0x80 | ((x >>> 6 ) & 0x3F),
+                                    0x80 | ( x         & 0x3F));
+    else if(x <= 0x1FFFFF)
+      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
+                                    0x80 | ((x >>> 12) & 0x3F),
+                                    0x80 | ((x >>> 6 ) & 0x3F),
+                                    0x80 | ( x         & 0x3F));
+  }
+  return output;
+}
+
+/**
+ * Encode a string as utf-16
+ */
+function str2rstr_utf16le(input)
+{
+  var output = "";
+  for(var i = 0; i < input.length; i++)
+    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
+                                  (input.charCodeAt(i) >>> 8) & 0xFF);
+  return output;
+}
+
+function str2rstr_utf16be(input)
+{
+  var output = "";
+  for(var i = 0; i < input.length; i++)
+    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
+                                   input.charCodeAt(i)        & 0xFF);
+  return output;
+}
+
+/**
+ * Convert a raw string to an array of big-endian words
+ * Characters >255 have their high-byte silently ignored.
+ */
+function rstr2binb(input)
+{
+  var output = Array(input.length >> 2);
+  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;
+}
+
+/**
+ * Convert an array of big-endian words to a string
+ */
+function binb2rstr(input)
+{
+  var output = "";
+  for(var i = 0; i < input.length * 32; i += 8)
+    output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
+  return output;
+}
+
+/**
+ * Calculate the SHA-1 of an array of big-endian words, and a bit length
+ */
+function binb_sha1(x, len)
+{
+  /* append padding */
+  x[len >> 5] |= 0x80 << (24 - len % 32);
+  x[((len + 64 >> 9) << 4) + 15] = len;
+
+  var w = Array(80);
+  var a =  1732584193;
+  var b = -271733879;
+  var c = -1732584194;
+  var d =  271733878;
+  var e = -1009589776;
+
+  for(var i = 0; i < x.length; i += 16)
+  {
+    var olda = a;
+    var oldb = b;
+    var oldc = c;
+    var oldd = d;
+    var olde = e;
+
+    for(var j = 0; j < 80; j++)
+    {
+      if(j < 16) w[j] = x[i + j];
+      else w[j] = bit_rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
+      var t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
+                       safe_add(safe_add(e, w[j]), sha1_kt(j)));
+      e = d;
+      d = c;
+      c = bit_rol(b, 30);
+      b = a;
+      a = t;
+    }
+
+    a = safe_add(a, olda);
+    b = safe_add(b, oldb);
+    c = safe_add(c, oldc);
+    d = safe_add(d, oldd);
+    e = safe_add(e, olde);
+  }
+  return Array(a, b, c, d, e);
+
+}
+
+/**
+ * Perform the appropriate triplet combination function for the current
+ * iteration
+ */
+function sha1_ft(t, b, c, d)
+{
+  if(t < 20) return (b & c) | ((~b) & d);
+  if(t < 40) return b ^ c ^ d;
+  if(t < 60) return (b & c) | (b & d) | (c & d);
+  return b ^ c ^ d;
+}
+
+/**
+ * Determine the appropriate additive constant for the current iteration
+ */
+function sha1_kt(t)
+{
+  return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
+         (t < 60) ? -1894007588 : -899497514;
+}
+
+/**
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
+ * to work around bugs in some JS interpreters.
+ */
+function safe_add(x, y)
+{
+  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+  return (msw << 16) | (lsw & 0xFFFF);
+}
+
+/**
+ * Bitwise rotate a 32-bit number to the left.
+ */
+function bit_rol(num, cnt)
+{
+  return (num << cnt) | (num >>> (32 - cnt));
+}
diff --git a/js/securityLib/sha256.js b/contrib/securityLib/sha256.js
similarity index 99%
rename from js/securityLib/sha256.js
rename to contrib/securityLib/sha256.js
index 214ee4d..51016cf 100644
--- a/js/securityLib/sha256.js
+++ b/contrib/securityLib/sha256.js
@@ -1,475 +1,475 @@
-/*
- * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
- * in FIPS 180-2
- * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009.
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for details.
- * Also http://anmar.eu.org/projects/jssha2/
- */
-
-/*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
-var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
-var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
-
-/*
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
-
-//@author axelcdv
-/**
- * Computes the Sha-256 hash of the given byte array
- * @param {byte[]} 
- * @return the hex string corresponding to the Sha-256 hash of the byte array
- */
-function hex_sha256_from_bytes(byteArray){
-	return rstr2hex(binb2rstr(binb_sha256( byteArray2binb(byteArray), byteArray.length * 8)));
-}
-
-function hex_sha256(s)    { return rstr2hex(rstr_sha256(str2rstr_utf8(s))); }
-function b64_sha256(s)    { return rstr2b64(rstr_sha256(str2rstr_utf8(s))); }
-function any_sha256(s, e) { return rstr2any(rstr_sha256(str2rstr_utf8(s)), e); }
-function hex_hmac_sha256(k, d)
-  { return rstr2hex(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function b64_hmac_sha256(k, d)
-  { return rstr2b64(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function any_hmac_sha256(k, d, e)
-  { return rstr2any(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
-
-	
-/*
-	function hex_sha256(s)    { return rstr2hex(rstr_sha256(s)); }
-function b64_sha256(s)    { return rstr2b64(rstr_sha256(s)); }
-function any_sha256(s, e) { return rstr2any(rstr_sha256(s), e); }
-function hex_hmac_sha256(k, d)
-  { return rstr2hex(rstr_hmac_sha256(str2rstr_utf8(k), d)); }
-function b64_hmac_sha256(k, d)
-  { return rstr2b64(rstr_hmac_sha256(str2rstr_utf8(k), d)); }
-function any_hmac_sha256(k, d, e)
-  { return rstr2any(rstr_hmac_sha256(str2rstr_utf8(k), d), e); }
-*/
-	
-/*
- * Perform a simple self-test to see if the VM is working
- */
-function sha256_vm_test()
-{
-  return hex_sha256("abc").toLowerCase() ==
-            "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad";
-}
-
-/**
- * Calculate the sha256 of a raw string
- * @param s: the raw string
- */
-function rstr_sha256(s)
-{
-  return binb2rstr(binb_sha256(rstr2binb(s), s.length * 8));
-}
-
-/**
- * Calculate the HMAC-sha256 of a key and some data (raw strings)
- */
-function rstr_hmac_sha256(key, data)
-{
-  var bkey = rstr2binb(key);
-  if(bkey.length > 16) bkey = binb_sha256(bkey, key.length * 8);
-
-  var ipad = Array(16), opad = Array(16);
-  for(var i = 0; i < 16; i++)
-  {
-    ipad[i] = bkey[i] ^ 0x36363636;
-    opad[i] = bkey[i] ^ 0x5C5C5C5C;
-  }
-
-  var hash = binb_sha256(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
-  return binb2rstr(binb_sha256(opad.concat(hash), 512 + 256));
-}
-
-/**
- * Convert a raw string to a hex string
- */
-function rstr2hex(input)
-{
-  try { hexcase } catch(e) { hexcase=0; }
-  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
-  var output = "";
-  var x;
-  for(var i = 0; i < input.length; i++)
-  {
-    x = input.charCodeAt(i);
-    output += hex_tab.charAt((x >>> 4) & 0x0F)
-           +  hex_tab.charAt( x        & 0x0F);
-  }
-  return output;
-}
-
-/*
- * Convert a raw string to a base-64 string
- */
-function rstr2b64(input)
-{
-  try { b64pad } catch(e) { b64pad=''; }
-  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-  var output = "";
-  var len = input.length;
-  for(var i = 0; i < len; i += 3)
-  {
-    var triplet = (input.charCodeAt(i) << 16)
-                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
-                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
-    for(var j = 0; j < 4; j++)
-    {
-      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
-      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
-    }
-  }
-  return output;
-}
-
-/*
- * Convert a raw string to an arbitrary string encoding
- */
-function rstr2any(input, encoding)
-{
-  var divisor = encoding.length;
-  var remainders = Array();
-  var i, q, x, quotient;
-
-  /* Convert to an array of 16-bit big-endian values, forming the dividend */
-  var dividend = Array(Math.ceil(input.length / 2));
-  for(i = 0; i < dividend.length; i++)
-  {
-    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
-  }
-
-  /*
-   * Repeatedly perform a long division. The binary array forms the dividend,
-   * the length of the encoding is the divisor. Once computed, the quotient
-   * forms the dividend for the next step. We stop when the dividend is zero.
-   * All remainders are stored for later use.
-   */
-  while(dividend.length > 0)
-  {
-    quotient = Array();
-    x = 0;
-    for(i = 0; i < dividend.length; i++)
-    {
-      x = (x << 16) + dividend[i];
-      q = Math.floor(x / divisor);
-      x -= q * divisor;
-      if(quotient.length > 0 || q > 0)
-        quotient[quotient.length] = q;
-    }
-    remainders[remainders.length] = x;
-    dividend = quotient;
-  }
-
-  /* Convert the remainders to the output string */
-  var output = "";
-  for(i = remainders.length - 1; i >= 0; i--)
-    output += encoding.charAt(remainders[i]);
-
-  /* Append leading zero equivalents */
-  var full_length = Math.ceil(input.length * 8 /
-                                    (Math.log(encoding.length) / Math.log(2)))
-  for(i = output.length; i < full_length; i++)
-    output = encoding[0] + output;
-
-  return output;
-}
-
-/*
- * Encode a string as utf-8.
- * For efficiency, this assumes the input is valid utf-16.
- */
-function str2rstr_utf8(input)
-{
-  var output = "";
-  var i = -1;
-  var x, y;
-
-  while(++i < input.length)
-  {
-    /* Decode utf-16 surrogate pairs */
-    x = input.charCodeAt(i);
-    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
-    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
-    {
-      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
-      i++;
-    }
-
-    /* Encode output as utf-8 */
-    if(x <= 0x7F)
-      output += String.fromCharCode(x);
-    else if(x <= 0x7FF)
-      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
-                                    0x80 | ( x         & 0x3F));
-    else if(x <= 0xFFFF)
-      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
-                                    0x80 | ((x >>> 6 ) & 0x3F),
-                                    0x80 | ( x         & 0x3F));
-    else if(x <= 0x1FFFFF)
-      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
-                                    0x80 | ((x >>> 12) & 0x3F),
-                                    0x80 | ((x >>> 6 ) & 0x3F),
-                                    0x80 | ( x         & 0x3F));
-  }
-  return output;
-}
-
-/*
- * Encode a string as utf-16
- */
-function str2rstr_utf16le(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length; i++)
-    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
-                                  (input.charCodeAt(i) >>> 8) & 0xFF);
-  return output;
-}
-
-function str2rstr_utf16be(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length; i++)
-    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
-                                   input.charCodeAt(i)        & 0xFF);
-  return output;
-}
-
-/**
- * Convert a raw string to an array of big-endian words
- * Characters >255 have their high-byte silently ignored.
- */
-function rstr2binb(input)
-{
-  //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;
-}
-
-/**
- * @author axelcdv
- * Convert a byte array to an array of big-endian words
- * @param {byte[]} input
- * @return the array of big-endian words
- */
-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;
-}
-
-/*
- * Convert an array of big-endian words to a string
- */
-function binb2rstr(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length * 32; i += 8)
-    output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
-  return output;
-}
-
-/*
- * Main sha256 function, with its support functions
- */
-function sha256_S (X, n) {return ( X >>> n ) | (X << (32 - n));}
-function sha256_R (X, n) {return ( X >>> n );}
-function sha256_Ch(x, y, z) {return ((x & y) ^ ((~x) & z));}
-function sha256_Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));}
-function sha256_Sigma0256(x) {return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));}
-function sha256_Sigma1256(x) {return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));}
-function sha256_Gamma0256(x) {return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));}
-function sha256_Gamma1256(x) {return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));}
-function sha256_Sigma0512(x) {return (sha256_S(x, 28) ^ sha256_S(x, 34) ^ sha256_S(x, 39));}
-function sha256_Sigma1512(x) {return (sha256_S(x, 14) ^ sha256_S(x, 18) ^ sha256_S(x, 41));}
-function sha256_Gamma0512(x) {return (sha256_S(x, 1)  ^ sha256_S(x, 8) ^ sha256_R(x, 7));}
-function sha256_Gamma1512(x) {return (sha256_S(x, 19) ^ sha256_S(x, 61) ^ sha256_R(x, 6));}
-
-var sha256_K = new Array
-(
-  1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993,
-  -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987,
-  1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522,
-  264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986,
-  -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585,
-  113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291,
-  1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885,
-  -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344,
-  430227734, 506948616, 659060556, 883997877, 958139571, 1322822218,
-  1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872,
-  -1866530822, -1538233109, -1090935817, -965641998
-);
-
-function binb_sha256(m, l)
-{
-  var HASH = new Array(1779033703, -1150833019, 1013904242, -1521486534,
-                       1359893119, -1694144372, 528734635, 1541459225);
-  var W = new Array(64);
-
-  /* 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);
-
-  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];
-    d = HASH[3];
-    e = HASH[4];
-    f = HASH[5];
-    g = HASH[6];
-    h = HASH[7];
-
-    for(j = 0; j < 64; j++)
-    {
-      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]);
-
-      T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)),
-                                                          sha256_K[j]), W[j]);
-      T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c));
-      h = g;
-      g = f;
-      f = e;
-      e = safe_add(d, T1);
-      d = c;
-      c = b;
-      b = a;
-      a = safe_add(T1, T2);
-    }
-
-    HASH[0] = safe_add(a, HASH[0]);
-    HASH[1] = safe_add(b, HASH[1]);
-    HASH[2] = safe_add(c, HASH[2]);
-    HASH[3] = safe_add(d, HASH[3]);
-    HASH[4] = safe_add(e, HASH[4]);
-    HASH[5] = safe_add(f, HASH[5]);
-    HASH[6] = safe_add(g, HASH[6]);
-    HASH[7] = safe_add(h, HASH[7]);
-}
-
-function safe_add (x, y)
-{
-  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
-  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-256, as defined
+ * in FIPS 180-2
+ * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009.
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ * Distributed under the BSD License
+ * See http://pajhome.org.uk/crypt/md5 for details.
+ * Also http://anmar.eu.org/projects/jssha2/
+ */
+
+/*
+ * Configurable variables. You may need to tweak these to be compatible with
+ * the server-side, but the defaults work in most cases.
+ */
+var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
+var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
+
+/*
+ * These are the functions you'll usually want to call
+ * They take string arguments and return either hex or base-64 encoded strings
+ */
+
+//@author axelcdv
+/**
+ * Computes the Sha-256 hash of the given byte array
+ * @param {byte[]} 
+ * @return the hex string corresponding to the Sha-256 hash of the byte array
+ */
+function hex_sha256_from_bytes(byteArray){
+	return rstr2hex(binb2rstr(binb_sha256( byteArray2binb(byteArray), byteArray.length * 8)));
+}
+
+function hex_sha256(s)    { return rstr2hex(rstr_sha256(str2rstr_utf8(s))); }
+function b64_sha256(s)    { return rstr2b64(rstr_sha256(str2rstr_utf8(s))); }
+function any_sha256(s, e) { return rstr2any(rstr_sha256(str2rstr_utf8(s)), e); }
+function hex_hmac_sha256(k, d)
+  { return rstr2hex(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d))); }
+function b64_hmac_sha256(k, d)
+  { return rstr2b64(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d))); }
+function any_hmac_sha256(k, d, e)
+  { return rstr2any(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
+
+	
+/*
+	function hex_sha256(s)    { return rstr2hex(rstr_sha256(s)); }
+function b64_sha256(s)    { return rstr2b64(rstr_sha256(s)); }
+function any_sha256(s, e) { return rstr2any(rstr_sha256(s), e); }
+function hex_hmac_sha256(k, d)
+  { return rstr2hex(rstr_hmac_sha256(str2rstr_utf8(k), d)); }
+function b64_hmac_sha256(k, d)
+  { return rstr2b64(rstr_hmac_sha256(str2rstr_utf8(k), d)); }
+function any_hmac_sha256(k, d, e)
+  { return rstr2any(rstr_hmac_sha256(str2rstr_utf8(k), d), e); }
+*/
+	
+/*
+ * Perform a simple self-test to see if the VM is working
+ */
+function sha256_vm_test()
+{
+  return hex_sha256("abc").toLowerCase() ==
+            "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad";
+}
+
+/**
+ * Calculate the sha256 of a raw string
+ * @param s: the raw string
+ */
+function rstr_sha256(s)
+{
+  return binb2rstr(binb_sha256(rstr2binb(s), s.length * 8));
+}
+
+/**
+ * Calculate the HMAC-sha256 of a key and some data (raw strings)
+ */
+function rstr_hmac_sha256(key, data)
+{
+  var bkey = rstr2binb(key);
+  if(bkey.length > 16) bkey = binb_sha256(bkey, key.length * 8);
+
+  var ipad = Array(16), opad = Array(16);
+  for(var i = 0; i < 16; i++)
+  {
+    ipad[i] = bkey[i] ^ 0x36363636;
+    opad[i] = bkey[i] ^ 0x5C5C5C5C;
+  }
+
+  var hash = binb_sha256(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
+  return binb2rstr(binb_sha256(opad.concat(hash), 512 + 256));
+}
+
+/**
+ * Convert a raw string to a hex string
+ */
+function rstr2hex(input)
+{
+  try { hexcase } catch(e) { hexcase=0; }
+  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+  var output = "";
+  var x;
+  for(var i = 0; i < input.length; i++)
+  {
+    x = input.charCodeAt(i);
+    output += hex_tab.charAt((x >>> 4) & 0x0F)
+           +  hex_tab.charAt( x        & 0x0F);
+  }
+  return output;
+}
+
+/*
+ * Convert a raw string to a base-64 string
+ */
+function rstr2b64(input)
+{
+  try { b64pad } catch(e) { b64pad=''; }
+  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+  var output = "";
+  var len = input.length;
+  for(var i = 0; i < len; i += 3)
+  {
+    var triplet = (input.charCodeAt(i) << 16)
+                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
+                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
+    for(var j = 0; j < 4; j++)
+    {
+      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
+      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
+    }
+  }
+  return output;
+}
+
+/*
+ * Convert a raw string to an arbitrary string encoding
+ */
+function rstr2any(input, encoding)
+{
+  var divisor = encoding.length;
+  var remainders = Array();
+  var i, q, x, quotient;
+
+  /* Convert to an array of 16-bit big-endian values, forming the dividend */
+  var dividend = Array(Math.ceil(input.length / 2));
+  for(i = 0; i < dividend.length; i++)
+  {
+    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
+  }
+
+  /*
+   * Repeatedly perform a long division. The binary array forms the dividend,
+   * the length of the encoding is the divisor. Once computed, the quotient
+   * forms the dividend for the next step. We stop when the dividend is zero.
+   * All remainders are stored for later use.
+   */
+  while(dividend.length > 0)
+  {
+    quotient = Array();
+    x = 0;
+    for(i = 0; i < dividend.length; i++)
+    {
+      x = (x << 16) + dividend[i];
+      q = Math.floor(x / divisor);
+      x -= q * divisor;
+      if(quotient.length > 0 || q > 0)
+        quotient[quotient.length] = q;
+    }
+    remainders[remainders.length] = x;
+    dividend = quotient;
+  }
+
+  /* Convert the remainders to the output string */
+  var output = "";
+  for(i = remainders.length - 1; i >= 0; i--)
+    output += encoding.charAt(remainders[i]);
+
+  /* Append leading zero equivalents */
+  var full_length = Math.ceil(input.length * 8 /
+                                    (Math.log(encoding.length) / Math.log(2)))
+  for(i = output.length; i < full_length; i++)
+    output = encoding[0] + output;
+
+  return output;
+}
+
+/*
+ * Encode a string as utf-8.
+ * For efficiency, this assumes the input is valid utf-16.
+ */
+function str2rstr_utf8(input)
+{
+  var output = "";
+  var i = -1;
+  var x, y;
+
+  while(++i < input.length)
+  {
+    /* Decode utf-16 surrogate pairs */
+    x = input.charCodeAt(i);
+    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
+    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
+    {
+      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
+      i++;
+    }
+
+    /* Encode output as utf-8 */
+    if(x <= 0x7F)
+      output += String.fromCharCode(x);
+    else if(x <= 0x7FF)
+      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
+                                    0x80 | ( x         & 0x3F));
+    else if(x <= 0xFFFF)
+      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
+                                    0x80 | ((x >>> 6 ) & 0x3F),
+                                    0x80 | ( x         & 0x3F));
+    else if(x <= 0x1FFFFF)
+      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
+                                    0x80 | ((x >>> 12) & 0x3F),
+                                    0x80 | ((x >>> 6 ) & 0x3F),
+                                    0x80 | ( x         & 0x3F));
+  }
+  return output;
+}
+
+/*
+ * Encode a string as utf-16
+ */
+function str2rstr_utf16le(input)
+{
+  var output = "";
+  for(var i = 0; i < input.length; i++)
+    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
+                                  (input.charCodeAt(i) >>> 8) & 0xFF);
+  return output;
+}
+
+function str2rstr_utf16be(input)
+{
+  var output = "";
+  for(var i = 0; i < input.length; i++)
+    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
+                                   input.charCodeAt(i)        & 0xFF);
+  return output;
+}
+
+/**
+ * Convert a raw string to an array of big-endian words
+ * Characters >255 have their high-byte silently ignored.
+ */
+function rstr2binb(input)
+{
+  //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;
+}
+
+/**
+ * @author axelcdv
+ * Convert a byte array to an array of big-endian words
+ * @param {byte[]} input
+ * @return the array of big-endian words
+ */
+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;
+}
+
+/*
+ * Convert an array of big-endian words to a string
+ */
+function binb2rstr(input)
+{
+  var output = "";
+  for(var i = 0; i < input.length * 32; i += 8)
+    output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
+  return output;
+}
+
+/*
+ * Main sha256 function, with its support functions
+ */
+function sha256_S (X, n) {return ( X >>> n ) | (X << (32 - n));}
+function sha256_R (X, n) {return ( X >>> n );}
+function sha256_Ch(x, y, z) {return ((x & y) ^ ((~x) & z));}
+function sha256_Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));}
+function sha256_Sigma0256(x) {return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));}
+function sha256_Sigma1256(x) {return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));}
+function sha256_Gamma0256(x) {return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));}
+function sha256_Gamma1256(x) {return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));}
+function sha256_Sigma0512(x) {return (sha256_S(x, 28) ^ sha256_S(x, 34) ^ sha256_S(x, 39));}
+function sha256_Sigma1512(x) {return (sha256_S(x, 14) ^ sha256_S(x, 18) ^ sha256_S(x, 41));}
+function sha256_Gamma0512(x) {return (sha256_S(x, 1)  ^ sha256_S(x, 8) ^ sha256_R(x, 7));}
+function sha256_Gamma1512(x) {return (sha256_S(x, 19) ^ sha256_S(x, 61) ^ sha256_R(x, 6));}
+
+var sha256_K = new Array
+(
+  1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993,
+  -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987,
+  1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522,
+  264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986,
+  -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585,
+  113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291,
+  1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885,
+  -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344,
+  430227734, 506948616, 659060556, 883997877, 958139571, 1322822218,
+  1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872,
+  -1866530822, -1538233109, -1090935817, -965641998
+);
+
+function binb_sha256(m, l)
+{
+  var HASH = new Array(1779033703, -1150833019, 1013904242, -1521486534,
+                       1359893119, -1694144372, 528734635, 1541459225);
+  var W = new Array(64);
+
+  /* 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);
+
+  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];
+    d = HASH[3];
+    e = HASH[4];
+    f = HASH[5];
+    g = HASH[6];
+    h = HASH[7];
+
+    for(j = 0; j < 64; j++)
+    {
+      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]);
+
+      T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)),
+                                                          sha256_K[j]), W[j]);
+      T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c));
+      h = g;
+      g = f;
+      f = e;
+      e = safe_add(d, T1);
+      d = c;
+      c = b;
+      b = a;
+      a = safe_add(T1, T2);
+    }
+
+    HASH[0] = safe_add(a, HASH[0]);
+    HASH[1] = safe_add(b, HASH[1]);
+    HASH[2] = safe_add(c, HASH[2]);
+    HASH[3] = safe_add(d, HASH[3]);
+    HASH[4] = safe_add(e, HASH[4]);
+    HASH[5] = safe_add(f, HASH[5]);
+    HASH[6] = safe_add(g, HASH[6]);
+    HASH[7] = safe_add(h, HASH[7]);
+}
+
+function safe_add (x, y)
+{
+  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+  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;
+}
diff --git a/js/securityLib/sha512.js b/contrib/securityLib/sha512.js
similarity index 99%
rename from js/securityLib/sha512.js
rename to contrib/securityLib/sha512.js
index 8d33c04..9fefd17 100644
--- a/js/securityLib/sha512.js
+++ b/contrib/securityLib/sha512.js
@@ -1,496 +1,496 @@
-/*
- * A JavaScript implementation of the Secure Hash Algorithm, SHA-512, as defined
- * in FIPS 180-2
- * Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009.
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for details.
- */
-
-/*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
-var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
-var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
-
-/*
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
-function hex_sha512(s)    { return rstr2hex(rstr_sha512(str2rstr_utf8(s))); }
-function b64_sha512(s)    { return rstr2b64(rstr_sha512(str2rstr_utf8(s))); }
-function any_sha512(s, e) { return rstr2any(rstr_sha512(str2rstr_utf8(s)), e);}
-function hex_hmac_sha512(k, d)
-  { return rstr2hex(rstr_hmac_sha512(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function b64_hmac_sha512(k, d)
-  { return rstr2b64(rstr_hmac_sha512(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function any_hmac_sha512(k, d, e)
-  { return rstr2any(rstr_hmac_sha512(str2rstr_utf8(k), str2rstr_utf8(d)), e);}
-
-/*
- * Perform a simple self-test to see if the VM is working
- */
-function sha512_vm_test()
-{
-  return hex_sha512("abc").toLowerCase() ==
-    "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" +
-    "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
-}
-
-/*
- * Calculate the SHA-512 of a raw string
- */
-function rstr_sha512(s)
-{
-  return binb2rstr(binb_sha512(rstr2binb(s), s.length * 8));
-}
-
-/*
- * Calculate the HMAC-SHA-512 of a key and some data (raw strings)
- */
-function rstr_hmac_sha512(key, data)
-{
-  var bkey = rstr2binb(key);
-  if(bkey.length > 32) bkey = binb_sha512(bkey, key.length * 8);
-
-  var ipad = Array(32), opad = Array(32);
-  for(var i = 0; i < 32; i++)
-  {
-    ipad[i] = bkey[i] ^ 0x36363636;
-    opad[i] = bkey[i] ^ 0x5C5C5C5C;
-  }
-
-  var hash = binb_sha512(ipad.concat(rstr2binb(data)), 1024 + data.length * 8);
-  return binb2rstr(binb_sha512(opad.concat(hash), 1024 + 512));
-}
-
-/*
- * Convert a raw string to a hex string
- */
-function rstr2hex(input)
-{
-  try { hexcase } catch(e) { hexcase=0; }
-  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
-  var output = "";
-  var x;
-  for(var i = 0; i < input.length; i++)
-  {
-    x = input.charCodeAt(i);
-    output += hex_tab.charAt((x >>> 4) & 0x0F)
-           +  hex_tab.charAt( x        & 0x0F);
-  }
-  return output;
-}
-
-/*
- * Convert a raw string to a base-64 string
- */
-function rstr2b64(input)
-{
-  try { b64pad } catch(e) { b64pad=''; }
-  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-  var output = "";
-  var len = input.length;
-  for(var i = 0; i < len; i += 3)
-  {
-    var triplet = (input.charCodeAt(i) << 16)
-                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
-                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
-    for(var j = 0; j < 4; j++)
-    {
-      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
-      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
-    }
-  }
-  return output;
-}
-
-/*
- * Convert a raw string to an arbitrary string encoding
- */
-function rstr2any(input, encoding)
-{
-  var divisor = encoding.length;
-  var i, j, q, x, quotient;
-
-  /* Convert to an array of 16-bit big-endian values, forming the dividend */
-  var dividend = Array(Math.ceil(input.length / 2));
-  for(i = 0; i < dividend.length; i++)
-  {
-    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
-  }
-
-  /*
-   * Repeatedly perform a long division. The binary array forms the dividend,
-   * the length of the encoding is the divisor. Once computed, the quotient
-   * forms the dividend for the next step. All remainders are stored for later
-   * use.
-   */
-  var full_length = Math.ceil(input.length * 8 /
-                                    (Math.log(encoding.length) / Math.log(2)));
-  var remainders = Array(full_length);
-  for(j = 0; j < full_length; j++)
-  {
-    quotient = Array();
-    x = 0;
-    for(i = 0; i < dividend.length; i++)
-    {
-      x = (x << 16) + dividend[i];
-      q = Math.floor(x / divisor);
-      x -= q * divisor;
-      if(quotient.length > 0 || q > 0)
-        quotient[quotient.length] = q;
-    }
-    remainders[j] = x;
-    dividend = quotient;
-  }
-
-  /* Convert the remainders to the output string */
-  var output = "";
-  for(i = remainders.length - 1; i >= 0; i--)
-    output += encoding.charAt(remainders[i]);
-
-  return output;
-}
-
-/*
- * Encode a string as utf-8.
- * For efficiency, this assumes the input is valid utf-16.
- */
-function str2rstr_utf8(input)
-{
-  var output = "";
-  var i = -1;
-  var x, y;
-
-  while(++i < input.length)
-  {
-    /* Decode utf-16 surrogate pairs */
-    x = input.charCodeAt(i);
-    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
-    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
-    {
-      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
-      i++;
-    }
-
-    /* Encode output as utf-8 */
-    if(x <= 0x7F)
-      output += String.fromCharCode(x);
-    else if(x <= 0x7FF)
-      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
-                                    0x80 | ( x         & 0x3F));
-    else if(x <= 0xFFFF)
-      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
-                                    0x80 | ((x >>> 6 ) & 0x3F),
-                                    0x80 | ( x         & 0x3F));
-    else if(x <= 0x1FFFFF)
-      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
-                                    0x80 | ((x >>> 12) & 0x3F),
-                                    0x80 | ((x >>> 6 ) & 0x3F),
-                                    0x80 | ( x         & 0x3F));
-  }
-  return output;
-}
-
-/*
- * Encode a string as utf-16
- */
-function str2rstr_utf16le(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length; i++)
-    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
-                                  (input.charCodeAt(i) >>> 8) & 0xFF);
-  return output;
-}
-
-function str2rstr_utf16be(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length; i++)
-    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
-                                   input.charCodeAt(i)        & 0xFF);
-  return output;
-}
-
-/*
- * Convert a raw string to an array of big-endian words
- * Characters >255 have their high-byte silently ignored.
- */
-function rstr2binb(input)
-{
-  var output = Array(input.length >> 2);
-  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;
-}
-
-/*
- * Convert an array of big-endian words to a string
- */
-function binb2rstr(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length * 32; i += 8)
-    output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
-  return output;
-}
-
-/*
- * Calculate the SHA-512 of an array of big-endian dwords, and a bit length
- */
-var sha512_k;
-function binb_sha512(x, len)
-{
-  if(sha512_k == undefined)
-  {
-    //SHA512 constants
-    sha512_k = new Array(
-new int64(0x428a2f98, -685199838), new int64(0x71374491, 0x23ef65cd),
-new int64(-1245643825, -330482897), new int64(-373957723, -2121671748),
-new int64(0x3956c25b, -213338824), new int64(0x59f111f1, -1241133031),
-new int64(-1841331548, -1357295717), new int64(-1424204075, -630357736),
-new int64(-670586216, -1560083902), new int64(0x12835b01, 0x45706fbe),
-new int64(0x243185be, 0x4ee4b28c), new int64(0x550c7dc3, -704662302),
-new int64(0x72be5d74, -226784913), new int64(-2132889090, 0x3b1696b1),
-new int64(-1680079193, 0x25c71235), new int64(-1046744716, -815192428),
-new int64(-459576895, -1628353838), new int64(-272742522, 0x384f25e3),
-new int64(0xfc19dc6, -1953704523), new int64(0x240ca1cc, 0x77ac9c65),
-new int64(0x2de92c6f, 0x592b0275), new int64(0x4a7484aa, 0x6ea6e483),
-new int64(0x5cb0a9dc, -1119749164), new int64(0x76f988da, -2096016459),
-new int64(-1740746414, -295247957), new int64(-1473132947, 0x2db43210),
-new int64(-1341970488, -1728372417), new int64(-1084653625, -1091629340),
-new int64(-958395405, 0x3da88fc2), new int64(-710438585, -1828018395),
-new int64(0x6ca6351, -536640913), new int64(0x14292967, 0xa0e6e70),
-new int64(0x27b70a85, 0x46d22ffc), new int64(0x2e1b2138, 0x5c26c926),
-new int64(0x4d2c6dfc, 0x5ac42aed), new int64(0x53380d13, -1651133473),
-new int64(0x650a7354, -1951439906), new int64(0x766a0abb, 0x3c77b2a8),
-new int64(-2117940946, 0x47edaee6), new int64(-1838011259, 0x1482353b),
-new int64(-1564481375, 0x4cf10364), new int64(-1474664885, -1136513023),
-new int64(-1035236496, -789014639), new int64(-949202525, 0x654be30),
-new int64(-778901479, -688958952), new int64(-694614492, 0x5565a910),
-new int64(-200395387, 0x5771202a), new int64(0x106aa070, 0x32bbd1b8),
-new int64(0x19a4c116, -1194143544), new int64(0x1e376c08, 0x5141ab53),
-new int64(0x2748774c, -544281703), new int64(0x34b0bcb5, -509917016),
-new int64(0x391c0cb3, -976659869), new int64(0x4ed8aa4a, -482243893),
-new int64(0x5b9cca4f, 0x7763e373), new int64(0x682e6ff3, -692930397),
-new int64(0x748f82ee, 0x5defb2fc), new int64(0x78a5636f, 0x43172f60),
-new int64(-2067236844, -1578062990), new int64(-1933114872, 0x1a6439ec),
-new int64(-1866530822, 0x23631e28), new int64(-1538233109, -561857047),
-new int64(-1090935817, -1295615723), new int64(-965641998, -479046869),
-new int64(-903397682, -366583396), new int64(-779700025, 0x21c0c207),
-new int64(-354779690, -840897762), new int64(-176337025, -294727304),
-new int64(0x6f067aa, 0x72176fba), new int64(0xa637dc5, -1563912026),
-new int64(0x113f9804, -1090974290), new int64(0x1b710b35, 0x131c471b),
-new int64(0x28db77f5, 0x23047d84), new int64(0x32caab7b, 0x40c72493),
-new int64(0x3c9ebe0a, 0x15c9bebc), new int64(0x431d67c4, -1676669620),
-new int64(0x4cc5d4be, -885112138), new int64(0x597f299c, -60457430),
-new int64(0x5fcb6fab, 0x3ad6faec), new int64(0x6c44198c, 0x4a475817));
-  }
-
-  //Initial hash values
-  var H = new Array(
-new int64(0x6a09e667, -205731576),
-new int64(-1150833019, -2067093701),
-new int64(0x3c6ef372, -23791573),
-new int64(-1521486534, 0x5f1d36f1),
-new int64(0x510e527f, -1377402159),
-new int64(-1694144372, 0x2b3e6c1f),
-new int64(0x1f83d9ab, -79577749),
-new int64(0x5be0cd19, 0x137e2179));
-
-  var T1 = new int64(0, 0),
-    T2 = new int64(0, 0),
-    a = new int64(0,0),
-    b = new int64(0,0),
-    c = new int64(0,0),
-    d = new int64(0,0),
-    e = new int64(0,0),
-    f = new int64(0,0),
-    g = new int64(0,0),
-    h = new int64(0,0),
-    //Temporary variables not specified by the document
-    s0 = new int64(0, 0),
-    s1 = new int64(0, 0),
-    Ch = new int64(0, 0),
-    Maj = new int64(0, 0),
-    r1 = new int64(0, 0),
-    r2 = new int64(0, 0),
-    r3 = new int64(0, 0);
-  var j, i;
-  var W = new Array(80);
-  for(i=0; i<80; i++)
-    W[i] = new int64(0, 0);
-
-  // append padding to the source string. The format is described in the FIPS.
-  x[len >> 5] |= 0x80 << (24 - (len & 0x1f));
-  x[((len + 128 >> 10)<< 5) + 31] = len;
-
-  for(i = 0; i<x.length; i+=32) //32 dwords is the block size
-  {
-    int64copy(a, H[0]);
-    int64copy(b, H[1]);
-    int64copy(c, H[2]);
-    int64copy(d, H[3]);
-    int64copy(e, H[4]);
-    int64copy(f, H[5]);
-    int64copy(g, H[6]);
-    int64copy(h, H[7]);
-
-    for(j=0; j<16; j++)
-    {
-        W[j].h = x[i + 2*j];
-        W[j].l = x[i + 2*j + 1];
-    }
-
-    for(j=16; j<80; j++)
-    {
-      //sigma1
-      int64rrot(r1, W[j-2], 19);
-      int64revrrot(r2, W[j-2], 29);
-      int64shr(r3, W[j-2], 6);
-      s1.l = r1.l ^ r2.l ^ r3.l;
-      s1.h = r1.h ^ r2.h ^ r3.h;
-      //sigma0
-      int64rrot(r1, W[j-15], 1);
-      int64rrot(r2, W[j-15], 8);
-      int64shr(r3, W[j-15], 7);
-      s0.l = r1.l ^ r2.l ^ r3.l;
-      s0.h = r1.h ^ r2.h ^ r3.h;
-
-      int64add4(W[j], s1, W[j-7], s0, W[j-16]);
-    }
-
-    for(j = 0; j < 80; j++)
-    {
-      //Ch
-      Ch.l = (e.l & f.l) ^ (~e.l & g.l);
-      Ch.h = (e.h & f.h) ^ (~e.h & g.h);
-
-      //Sigma1
-      int64rrot(r1, e, 14);
-      int64rrot(r2, e, 18);
-      int64revrrot(r3, e, 9);
-      s1.l = r1.l ^ r2.l ^ r3.l;
-      s1.h = r1.h ^ r2.h ^ r3.h;
-
-      //Sigma0
-      int64rrot(r1, a, 28);
-      int64revrrot(r2, a, 2);
-      int64revrrot(r3, a, 7);
-      s0.l = r1.l ^ r2.l ^ r3.l;
-      s0.h = r1.h ^ r2.h ^ r3.h;
-
-      //Maj
-      Maj.l = (a.l & b.l) ^ (a.l & c.l) ^ (b.l & c.l);
-      Maj.h = (a.h & b.h) ^ (a.h & c.h) ^ (b.h & c.h);
-
-      int64add5(T1, h, s1, Ch, sha512_k[j], W[j]);
-      int64add(T2, s0, Maj);
-
-      int64copy(h, g);
-      int64copy(g, f);
-      int64copy(f, e);
-      int64add(e, d, T1);
-      int64copy(d, c);
-      int64copy(c, b);
-      int64copy(b, a);
-      int64add(a, T1, T2);
-    }
-    int64add(H[0], H[0], a);
-    int64add(H[1], H[1], b);
-    int64add(H[2], H[2], c);
-    int64add(H[3], H[3], d);
-    int64add(H[4], H[4], e);
-    int64add(H[5], H[5], f);
-    int64add(H[6], H[6], g);
-    int64add(H[7], H[7], h);
-  }
-
-  //represent the hash as an array of 32-bit dwords
-  var hash = new Array(16);
-  for(i=0; i<8; i++)
-  {
-    hash[2*i] = H[i].h;
-    hash[2*i + 1] = H[i].l;
-  }
-  return hash;
-}
-
-//A constructor for 64-bit numbers
-function int64(h, l)
-{
-  this.h = h;
-  this.l = l;
-  //this.toString = int64toString;
-}
-
-//Copies src into dst, assuming both are 64-bit numbers
-function int64copy(dst, src)
-{
-  dst.h = src.h;
-  dst.l = src.l;
-}
-
-//Right-rotates a 64-bit number by shift
-//Won't handle cases of shift>=32
-//The function revrrot() is for that
-function int64rrot(dst, x, shift)
-{
-    dst.l = (x.l >>> shift) | (x.h << (32-shift));
-    dst.h = (x.h >>> shift) | (x.l << (32-shift));
-}
-
-//Reverses the dwords of the source and then rotates right by shift.
-//This is equivalent to rotation by 32+shift
-function int64revrrot(dst, x, shift)
-{
-    dst.l = (x.h >>> shift) | (x.l << (32-shift));
-    dst.h = (x.l >>> shift) | (x.h << (32-shift));
-}
-
-//Bitwise-shifts right a 64-bit number by shift
-//Won't handle shift>=32, but it's never needed in SHA512
-function int64shr(dst, x, shift)
-{
-    dst.l = (x.l >>> shift) | (x.h << (32-shift));
-    dst.h = (x.h >>> shift);
-}
-
-//Adds two 64-bit numbers
-//Like the original implementation, does not rely on 32-bit operations
-function int64add(dst, x, y)
-{
-   var w0 = (x.l & 0xffff) + (y.l & 0xffff);
-   var w1 = (x.l >>> 16) + (y.l >>> 16) + (w0 >>> 16);
-   var w2 = (x.h & 0xffff) + (y.h & 0xffff) + (w1 >>> 16);
-   var w3 = (x.h >>> 16) + (y.h >>> 16) + (w2 >>> 16);
-   dst.l = (w0 & 0xffff) | (w1 << 16);
-   dst.h = (w2 & 0xffff) | (w3 << 16);
-}
-
-//Same, except with 4 addends. Works faster than adding them one by one.
-function int64add4(dst, a, b, c, d)
-{
-   var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff);
-   var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (w0 >>> 16);
-   var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (w1 >>> 16);
-   var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (w2 >>> 16);
-   dst.l = (w0 & 0xffff) | (w1 << 16);
-   dst.h = (w2 & 0xffff) | (w3 << 16);
-}
-
-//Same, except with 5 addends
-function int64add5(dst, a, b, c, d, e)
-{
-   var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff) + (e.l & 0xffff);
-   var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (e.l >>> 16) + (w0 >>> 16);
-   var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (e.h & 0xffff) + (w1 >>> 16);
-   var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (e.h >>> 16) + (w2 >>> 16);
-   dst.l = (w0 & 0xffff) | (w1 << 16);
-   dst.h = (w2 & 0xffff) | (w3 << 16);
-}
+/*
+ * A JavaScript implementation of the Secure Hash Algorithm, SHA-512, as defined
+ * in FIPS 180-2
+ * Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009.
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ * Distributed under the BSD License
+ * See http://pajhome.org.uk/crypt/md5 for details.
+ */
+
+/*
+ * Configurable variables. You may need to tweak these to be compatible with
+ * the server-side, but the defaults work in most cases.
+ */
+var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
+var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
+
+/*
+ * These are the functions you'll usually want to call
+ * They take string arguments and return either hex or base-64 encoded strings
+ */
+function hex_sha512(s)    { return rstr2hex(rstr_sha512(str2rstr_utf8(s))); }
+function b64_sha512(s)    { return rstr2b64(rstr_sha512(str2rstr_utf8(s))); }
+function any_sha512(s, e) { return rstr2any(rstr_sha512(str2rstr_utf8(s)), e);}
+function hex_hmac_sha512(k, d)
+  { return rstr2hex(rstr_hmac_sha512(str2rstr_utf8(k), str2rstr_utf8(d))); }
+function b64_hmac_sha512(k, d)
+  { return rstr2b64(rstr_hmac_sha512(str2rstr_utf8(k), str2rstr_utf8(d))); }
+function any_hmac_sha512(k, d, e)
+  { return rstr2any(rstr_hmac_sha512(str2rstr_utf8(k), str2rstr_utf8(d)), e);}
+
+/*
+ * Perform a simple self-test to see if the VM is working
+ */
+function sha512_vm_test()
+{
+  return hex_sha512("abc").toLowerCase() ==
+    "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" +
+    "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
+}
+
+/*
+ * Calculate the SHA-512 of a raw string
+ */
+function rstr_sha512(s)
+{
+  return binb2rstr(binb_sha512(rstr2binb(s), s.length * 8));
+}
+
+/*
+ * Calculate the HMAC-SHA-512 of a key and some data (raw strings)
+ */
+function rstr_hmac_sha512(key, data)
+{
+  var bkey = rstr2binb(key);
+  if(bkey.length > 32) bkey = binb_sha512(bkey, key.length * 8);
+
+  var ipad = Array(32), opad = Array(32);
+  for(var i = 0; i < 32; i++)
+  {
+    ipad[i] = bkey[i] ^ 0x36363636;
+    opad[i] = bkey[i] ^ 0x5C5C5C5C;
+  }
+
+  var hash = binb_sha512(ipad.concat(rstr2binb(data)), 1024 + data.length * 8);
+  return binb2rstr(binb_sha512(opad.concat(hash), 1024 + 512));
+}
+
+/*
+ * Convert a raw string to a hex string
+ */
+function rstr2hex(input)
+{
+  try { hexcase } catch(e) { hexcase=0; }
+  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+  var output = "";
+  var x;
+  for(var i = 0; i < input.length; i++)
+  {
+    x = input.charCodeAt(i);
+    output += hex_tab.charAt((x >>> 4) & 0x0F)
+           +  hex_tab.charAt( x        & 0x0F);
+  }
+  return output;
+}
+
+/*
+ * Convert a raw string to a base-64 string
+ */
+function rstr2b64(input)
+{
+  try { b64pad } catch(e) { b64pad=''; }
+  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+  var output = "";
+  var len = input.length;
+  for(var i = 0; i < len; i += 3)
+  {
+    var triplet = (input.charCodeAt(i) << 16)
+                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
+                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
+    for(var j = 0; j < 4; j++)
+    {
+      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
+      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
+    }
+  }
+  return output;
+}
+
+/*
+ * Convert a raw string to an arbitrary string encoding
+ */
+function rstr2any(input, encoding)
+{
+  var divisor = encoding.length;
+  var i, j, q, x, quotient;
+
+  /* Convert to an array of 16-bit big-endian values, forming the dividend */
+  var dividend = Array(Math.ceil(input.length / 2));
+  for(i = 0; i < dividend.length; i++)
+  {
+    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
+  }
+
+  /*
+   * Repeatedly perform a long division. The binary array forms the dividend,
+   * the length of the encoding is the divisor. Once computed, the quotient
+   * forms the dividend for the next step. All remainders are stored for later
+   * use.
+   */
+  var full_length = Math.ceil(input.length * 8 /
+                                    (Math.log(encoding.length) / Math.log(2)));
+  var remainders = Array(full_length);
+  for(j = 0; j < full_length; j++)
+  {
+    quotient = Array();
+    x = 0;
+    for(i = 0; i < dividend.length; i++)
+    {
+      x = (x << 16) + dividend[i];
+      q = Math.floor(x / divisor);
+      x -= q * divisor;
+      if(quotient.length > 0 || q > 0)
+        quotient[quotient.length] = q;
+    }
+    remainders[j] = x;
+    dividend = quotient;
+  }
+
+  /* Convert the remainders to the output string */
+  var output = "";
+  for(i = remainders.length - 1; i >= 0; i--)
+    output += encoding.charAt(remainders[i]);
+
+  return output;
+}
+
+/*
+ * Encode a string as utf-8.
+ * For efficiency, this assumes the input is valid utf-16.
+ */
+function str2rstr_utf8(input)
+{
+  var output = "";
+  var i = -1;
+  var x, y;
+
+  while(++i < input.length)
+  {
+    /* Decode utf-16 surrogate pairs */
+    x = input.charCodeAt(i);
+    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
+    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
+    {
+      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
+      i++;
+    }
+
+    /* Encode output as utf-8 */
+    if(x <= 0x7F)
+      output += String.fromCharCode(x);
+    else if(x <= 0x7FF)
+      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
+                                    0x80 | ( x         & 0x3F));
+    else if(x <= 0xFFFF)
+      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
+                                    0x80 | ((x >>> 6 ) & 0x3F),
+                                    0x80 | ( x         & 0x3F));
+    else if(x <= 0x1FFFFF)
+      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
+                                    0x80 | ((x >>> 12) & 0x3F),
+                                    0x80 | ((x >>> 6 ) & 0x3F),
+                                    0x80 | ( x         & 0x3F));
+  }
+  return output;
+}
+
+/*
+ * Encode a string as utf-16
+ */
+function str2rstr_utf16le(input)
+{
+  var output = "";
+  for(var i = 0; i < input.length; i++)
+    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
+                                  (input.charCodeAt(i) >>> 8) & 0xFF);
+  return output;
+}
+
+function str2rstr_utf16be(input)
+{
+  var output = "";
+  for(var i = 0; i < input.length; i++)
+    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
+                                   input.charCodeAt(i)        & 0xFF);
+  return output;
+}
+
+/*
+ * Convert a raw string to an array of big-endian words
+ * Characters >255 have their high-byte silently ignored.
+ */
+function rstr2binb(input)
+{
+  var output = Array(input.length >> 2);
+  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;
+}
+
+/*
+ * Convert an array of big-endian words to a string
+ */
+function binb2rstr(input)
+{
+  var output = "";
+  for(var i = 0; i < input.length * 32; i += 8)
+    output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
+  return output;
+}
+
+/*
+ * Calculate the SHA-512 of an array of big-endian dwords, and a bit length
+ */
+var sha512_k;
+function binb_sha512(x, len)
+{
+  if(sha512_k == undefined)
+  {
+    //SHA512 constants
+    sha512_k = new Array(
+new int64(0x428a2f98, -685199838), new int64(0x71374491, 0x23ef65cd),
+new int64(-1245643825, -330482897), new int64(-373957723, -2121671748),
+new int64(0x3956c25b, -213338824), new int64(0x59f111f1, -1241133031),
+new int64(-1841331548, -1357295717), new int64(-1424204075, -630357736),
+new int64(-670586216, -1560083902), new int64(0x12835b01, 0x45706fbe),
+new int64(0x243185be, 0x4ee4b28c), new int64(0x550c7dc3, -704662302),
+new int64(0x72be5d74, -226784913), new int64(-2132889090, 0x3b1696b1),
+new int64(-1680079193, 0x25c71235), new int64(-1046744716, -815192428),
+new int64(-459576895, -1628353838), new int64(-272742522, 0x384f25e3),
+new int64(0xfc19dc6, -1953704523), new int64(0x240ca1cc, 0x77ac9c65),
+new int64(0x2de92c6f, 0x592b0275), new int64(0x4a7484aa, 0x6ea6e483),
+new int64(0x5cb0a9dc, -1119749164), new int64(0x76f988da, -2096016459),
+new int64(-1740746414, -295247957), new int64(-1473132947, 0x2db43210),
+new int64(-1341970488, -1728372417), new int64(-1084653625, -1091629340),
+new int64(-958395405, 0x3da88fc2), new int64(-710438585, -1828018395),
+new int64(0x6ca6351, -536640913), new int64(0x14292967, 0xa0e6e70),
+new int64(0x27b70a85, 0x46d22ffc), new int64(0x2e1b2138, 0x5c26c926),
+new int64(0x4d2c6dfc, 0x5ac42aed), new int64(0x53380d13, -1651133473),
+new int64(0x650a7354, -1951439906), new int64(0x766a0abb, 0x3c77b2a8),
+new int64(-2117940946, 0x47edaee6), new int64(-1838011259, 0x1482353b),
+new int64(-1564481375, 0x4cf10364), new int64(-1474664885, -1136513023),
+new int64(-1035236496, -789014639), new int64(-949202525, 0x654be30),
+new int64(-778901479, -688958952), new int64(-694614492, 0x5565a910),
+new int64(-200395387, 0x5771202a), new int64(0x106aa070, 0x32bbd1b8),
+new int64(0x19a4c116, -1194143544), new int64(0x1e376c08, 0x5141ab53),
+new int64(0x2748774c, -544281703), new int64(0x34b0bcb5, -509917016),
+new int64(0x391c0cb3, -976659869), new int64(0x4ed8aa4a, -482243893),
+new int64(0x5b9cca4f, 0x7763e373), new int64(0x682e6ff3, -692930397),
+new int64(0x748f82ee, 0x5defb2fc), new int64(0x78a5636f, 0x43172f60),
+new int64(-2067236844, -1578062990), new int64(-1933114872, 0x1a6439ec),
+new int64(-1866530822, 0x23631e28), new int64(-1538233109, -561857047),
+new int64(-1090935817, -1295615723), new int64(-965641998, -479046869),
+new int64(-903397682, -366583396), new int64(-779700025, 0x21c0c207),
+new int64(-354779690, -840897762), new int64(-176337025, -294727304),
+new int64(0x6f067aa, 0x72176fba), new int64(0xa637dc5, -1563912026),
+new int64(0x113f9804, -1090974290), new int64(0x1b710b35, 0x131c471b),
+new int64(0x28db77f5, 0x23047d84), new int64(0x32caab7b, 0x40c72493),
+new int64(0x3c9ebe0a, 0x15c9bebc), new int64(0x431d67c4, -1676669620),
+new int64(0x4cc5d4be, -885112138), new int64(0x597f299c, -60457430),
+new int64(0x5fcb6fab, 0x3ad6faec), new int64(0x6c44198c, 0x4a475817));
+  }
+
+  //Initial hash values
+  var H = new Array(
+new int64(0x6a09e667, -205731576),
+new int64(-1150833019, -2067093701),
+new int64(0x3c6ef372, -23791573),
+new int64(-1521486534, 0x5f1d36f1),
+new int64(0x510e527f, -1377402159),
+new int64(-1694144372, 0x2b3e6c1f),
+new int64(0x1f83d9ab, -79577749),
+new int64(0x5be0cd19, 0x137e2179));
+
+  var T1 = new int64(0, 0),
+    T2 = new int64(0, 0),
+    a = new int64(0,0),
+    b = new int64(0,0),
+    c = new int64(0,0),
+    d = new int64(0,0),
+    e = new int64(0,0),
+    f = new int64(0,0),
+    g = new int64(0,0),
+    h = new int64(0,0),
+    //Temporary variables not specified by the document
+    s0 = new int64(0, 0),
+    s1 = new int64(0, 0),
+    Ch = new int64(0, 0),
+    Maj = new int64(0, 0),
+    r1 = new int64(0, 0),
+    r2 = new int64(0, 0),
+    r3 = new int64(0, 0);
+  var j, i;
+  var W = new Array(80);
+  for(i=0; i<80; i++)
+    W[i] = new int64(0, 0);
+
+  // append padding to the source string. The format is described in the FIPS.
+  x[len >> 5] |= 0x80 << (24 - (len & 0x1f));
+  x[((len + 128 >> 10)<< 5) + 31] = len;
+
+  for(i = 0; i<x.length; i+=32) //32 dwords is the block size
+  {
+    int64copy(a, H[0]);
+    int64copy(b, H[1]);
+    int64copy(c, H[2]);
+    int64copy(d, H[3]);
+    int64copy(e, H[4]);
+    int64copy(f, H[5]);
+    int64copy(g, H[6]);
+    int64copy(h, H[7]);
+
+    for(j=0; j<16; j++)
+    {
+        W[j].h = x[i + 2*j];
+        W[j].l = x[i + 2*j + 1];
+    }
+
+    for(j=16; j<80; j++)
+    {
+      //sigma1
+      int64rrot(r1, W[j-2], 19);
+      int64revrrot(r2, W[j-2], 29);
+      int64shr(r3, W[j-2], 6);
+      s1.l = r1.l ^ r2.l ^ r3.l;
+      s1.h = r1.h ^ r2.h ^ r3.h;
+      //sigma0
+      int64rrot(r1, W[j-15], 1);
+      int64rrot(r2, W[j-15], 8);
+      int64shr(r3, W[j-15], 7);
+      s0.l = r1.l ^ r2.l ^ r3.l;
+      s0.h = r1.h ^ r2.h ^ r3.h;
+
+      int64add4(W[j], s1, W[j-7], s0, W[j-16]);
+    }
+
+    for(j = 0; j < 80; j++)
+    {
+      //Ch
+      Ch.l = (e.l & f.l) ^ (~e.l & g.l);
+      Ch.h = (e.h & f.h) ^ (~e.h & g.h);
+
+      //Sigma1
+      int64rrot(r1, e, 14);
+      int64rrot(r2, e, 18);
+      int64revrrot(r3, e, 9);
+      s1.l = r1.l ^ r2.l ^ r3.l;
+      s1.h = r1.h ^ r2.h ^ r3.h;
+
+      //Sigma0
+      int64rrot(r1, a, 28);
+      int64revrrot(r2, a, 2);
+      int64revrrot(r3, a, 7);
+      s0.l = r1.l ^ r2.l ^ r3.l;
+      s0.h = r1.h ^ r2.h ^ r3.h;
+
+      //Maj
+      Maj.l = (a.l & b.l) ^ (a.l & c.l) ^ (b.l & c.l);
+      Maj.h = (a.h & b.h) ^ (a.h & c.h) ^ (b.h & c.h);
+
+      int64add5(T1, h, s1, Ch, sha512_k[j], W[j]);
+      int64add(T2, s0, Maj);
+
+      int64copy(h, g);
+      int64copy(g, f);
+      int64copy(f, e);
+      int64add(e, d, T1);
+      int64copy(d, c);
+      int64copy(c, b);
+      int64copy(b, a);
+      int64add(a, T1, T2);
+    }
+    int64add(H[0], H[0], a);
+    int64add(H[1], H[1], b);
+    int64add(H[2], H[2], c);
+    int64add(H[3], H[3], d);
+    int64add(H[4], H[4], e);
+    int64add(H[5], H[5], f);
+    int64add(H[6], H[6], g);
+    int64add(H[7], H[7], h);
+  }
+
+  //represent the hash as an array of 32-bit dwords
+  var hash = new Array(16);
+  for(i=0; i<8; i++)
+  {
+    hash[2*i] = H[i].h;
+    hash[2*i + 1] = H[i].l;
+  }
+  return hash;
+}
+
+//A constructor for 64-bit numbers
+function int64(h, l)
+{
+  this.h = h;
+  this.l = l;
+  //this.toString = int64toString;
+}
+
+//Copies src into dst, assuming both are 64-bit numbers
+function int64copy(dst, src)
+{
+  dst.h = src.h;
+  dst.l = src.l;
+}
+
+//Right-rotates a 64-bit number by shift
+//Won't handle cases of shift>=32
+//The function revrrot() is for that
+function int64rrot(dst, x, shift)
+{
+    dst.l = (x.l >>> shift) | (x.h << (32-shift));
+    dst.h = (x.h >>> shift) | (x.l << (32-shift));
+}
+
+//Reverses the dwords of the source and then rotates right by shift.
+//This is equivalent to rotation by 32+shift
+function int64revrrot(dst, x, shift)
+{
+    dst.l = (x.h >>> shift) | (x.l << (32-shift));
+    dst.h = (x.l >>> shift) | (x.h << (32-shift));
+}
+
+//Bitwise-shifts right a 64-bit number by shift
+//Won't handle shift>=32, but it's never needed in SHA512
+function int64shr(dst, x, shift)
+{
+    dst.l = (x.l >>> shift) | (x.h << (32-shift));
+    dst.h = (x.h >>> shift);
+}
+
+//Adds two 64-bit numbers
+//Like the original implementation, does not rely on 32-bit operations
+function int64add(dst, x, y)
+{
+   var w0 = (x.l & 0xffff) + (y.l & 0xffff);
+   var w1 = (x.l >>> 16) + (y.l >>> 16) + (w0 >>> 16);
+   var w2 = (x.h & 0xffff) + (y.h & 0xffff) + (w1 >>> 16);
+   var w3 = (x.h >>> 16) + (y.h >>> 16) + (w2 >>> 16);
+   dst.l = (w0 & 0xffff) | (w1 << 16);
+   dst.h = (w2 & 0xffff) | (w3 << 16);
+}
+
+//Same, except with 4 addends. Works faster than adding them one by one.
+function int64add4(dst, a, b, c, d)
+{
+   var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff);
+   var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (w0 >>> 16);
+   var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (w1 >>> 16);
+   var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (w2 >>> 16);
+   dst.l = (w0 & 0xffff) | (w1 << 16);
+   dst.h = (w2 & 0xffff) | (w3 << 16);
+}
+
+//Same, except with 5 addends
+function int64add5(dst, a, b, c, d, e)
+{
+   var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff) + (e.l & 0xffff);
+   var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (e.l >>> 16) + (w0 >>> 16);
+   var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (e.h & 0xffff) + (w1 >>> 16);
+   var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (e.h >>> 16) + (w2 >>> 16);
+   dst.l = (w0 & 0xffff) | (w1 << 16);
+   dst.h = (w2 & 0xffff) | (w3 << 16);
+}
diff --git a/js/securityLib/x509-1.1.js b/contrib/securityLib/x509-1.1.js
similarity index 99%
rename from js/securityLib/x509-1.1.js
rename to contrib/securityLib/x509-1.1.js
index e6b9c27..262e5d2 100644
--- a/js/securityLib/x509-1.1.js
+++ b/contrib/securityLib/x509-1.1.js
@@ -1,294 +1,294 @@
-/*! x509-1.1.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
- */
-// 
-// x509.js - X509 class to read subject public key from certificate.
-//
-// version: 1.1 (10-May-2012)
-//
-// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
-//
-// This software is licensed under the terms of the MIT License.
-// http://kjur.github.com/jsrsasign/license
-//
-// The above copyright and license notice shall be 
-// included in all copies or substantial portions of the Software.
-// 
-
-// Depends:
-//   base64.js
-//   rsa.js
-//   asn1hex.js
-
-function _x509_pemToBase64(sCertPEM) {
-  var s = sCertPEM;
-  s = s.replace("-----BEGIN CERTIFICATE-----", "");
-  s = s.replace("-----END CERTIFICATE-----", "");
-  s = s.replace(/[ \n]+/g, "");
-  return s;
-}
-
-function _x509_pemToHex(sCertPEM) {
-  var b64Cert = _x509_pemToBase64(sCertPEM);
-  var hCert = b64tohex(b64Cert);
-  return hCert;
-}
-
-function _x509_getHexTbsCertificateFromCert(hCert) {
-  var pTbsCert = ASN1HEX.getStartPosOfV_AtObj(hCert, 0);
-  return pTbsCert;
-}
-
-// NOTE: privateKeyUsagePeriod field of X509v2 not supported.
-// NOTE: v1 and v3 supported
-function _x509_getSubjectPublicKeyInfoPosFromCertHex(hCert) {
-  var pTbsCert = ASN1HEX.getStartPosOfV_AtObj(hCert, 0);
-  var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, pTbsCert); 
-  if (a.length < 1) return -1;
-  if (hCert.substring(a[0], a[0] + 10) == "a003020102") { // v3
-    if (a.length < 6) return -1;
-    return a[6];
-  } else {
-    if (a.length < 5) return -1;
-    return a[5];
-  }
-}
-
-// NOTE: Without BITSTRING encapsulation.
-// If pInfo is supplied, it is the position in hCert of the SubjectPublicKeyInfo.
-function _x509_getSubjectPublicKeyPosFromCertHex(hCert, pInfo) {
-  if (pInfo == null)
-      pInfo = _x509_getSubjectPublicKeyInfoPosFromCertHex(hCert);
-  if (pInfo == -1) return -1;    
-  var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, pInfo); 
-  
-  if (a.length != 2) return -1;
-  var pBitString = a[1];
-  if (hCert.substring(pBitString, pBitString + 2) != '03') return -1;
-  var pBitStringV = ASN1HEX.getStartPosOfV_AtObj(hCert, pBitString);
-
-  if (hCert.substring(pBitStringV, pBitStringV + 2) != '00') return -1;
-  return pBitStringV + 2;
-}
-
-// If p is supplied, it is the public key position in hCert.
-function _x509_getPublicKeyHexArrayFromCertHex(hCert, p) {
-  if (p == null)
-      p = _x509_getSubjectPublicKeyPosFromCertHex(hCert);
-  var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, p); 
-  //var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, a[3]); 
-  if(LOG>4){
-	  console.log('a is now');
-	  console.log(a);
-  }
-  
-  //if (a.length != 2) return [];
-  if (a.length < 2) return [];
-
-  var hN = ASN1HEX.getHexOfV_AtObj(hCert, a[0]);
-  var hE = ASN1HEX.getHexOfV_AtObj(hCert, a[1]);
-  if (hN != null && hE != null) {
-    return [hN, hE];
-  } else {
-    return [];
-  }
-}
-
-function _x509_getPublicKeyHexArrayFromCertPEM(sCertPEM) {
-  var hCert = _x509_pemToHex(sCertPEM);
-  var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
-  return a;
-}
-
-// ===== get basic fields from hex =====================================
-/**
- * get hexadecimal string of serialNumber field of certificate.<br/>
- * @name getSerialNumberHex
- * @memberOf X509#
- * @function
- */
-function _x509_getSerialNumberHex() {
-  return ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 1]);
-}
-
-/**
- * get hexadecimal string of issuer field of certificate.<br/>
- * @name getIssuerHex
- * @memberOf X509#
- * @function
- */
-function _x509_getIssuerHex() {
-  return ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3]);
-}
-
-/**
- * get string of issuer field of certificate.<br/>
- * @name getIssuerString
- * @memberOf X509#
- * @function
- */
-function _x509_getIssuerString() {
-  return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3]));
-}
-
-/**
- * get hexadecimal string of subject field of certificate.<br/>
- * @name getSubjectHex
- * @memberOf X509#
- * @function
- */
-function _x509_getSubjectHex() {
-  return ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5]);
-}
-
-/**
- * get string of subject field of certificate.<br/>
- * @name getSubjectString
- * @memberOf X509#
- * @function
- */
-function _x509_getSubjectString() {
-  return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5]));
-}
-
-/**
- * get notBefore field string of certificate.<br/>
- * @name getNotBefore
- * @memberOf X509#
- * @function
- */
-function _x509_getNotBefore() {
-  var s = ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 4, 0]);
-  s = s.replace(/(..)/g, "%$1");
-  s = decodeURIComponent(s);
-  return s;
-}
-
-/**
- * get notAfter field string of certificate.<br/>
- * @name getNotAfter
- * @memberOf X509#
- * @function
- */
-function _x509_getNotAfter() {
-  var s = ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 4, 1]);
-  s = s.replace(/(..)/g, "%$1");
-  s = decodeURIComponent(s);
-  return s;
-}
-
-// ===== read certificate =====================================
-
-_x509_DN_ATTRHEX = {
-    "0603550406": "C",
-    "060355040a": "O",
-    "060355040b": "OU",
-    "0603550403": "CN",
-    "0603550405": "SN",
-    "0603550408": "ST",
-    "0603550407": "L" };
-
-function _x509_hex2dn(hDN) {
-  var s = "";
-  var a = ASN1HEX.getPosArrayOfChildren_AtObj(hDN, 0);
-  for (var i = 0; i < a.length; i++) {
-    var hRDN = ASN1HEX.getHexOfTLV_AtObj(hDN, a[i]);
-    s = s + "/" + _x509_hex2rdn(hRDN);
-  }
-  return s;
-}
-
-function _x509_hex2rdn(hRDN) {
-    var hType = ASN1HEX.getDecendantHexTLVByNthList(hRDN, 0, [0, 0]);
-    var hValue = ASN1HEX.getDecendantHexVByNthList(hRDN, 0, [0, 1]);
-    var type = "";
-    try { type = _x509_DN_ATTRHEX[hType]; } catch (ex) { type = hType; }
-    hValue = hValue.replace(/(..)/g, "%$1");
-    var value = decodeURIComponent(hValue);
-    return type + "=" + value;
-}
-
-// ===== read certificate =====================================
-
-
-/**
- * read PEM formatted X.509 certificate from string.<br/>
- * @name readCertPEM
- * @memberOf X509#
- * @function
- * @param {String} sCertPEM string for PEM formatted X.509 certificate
- */
-function _x509_readCertPEM(sCertPEM) {
-  var hCert = _x509_pemToHex(sCertPEM);
-  var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
-  if(LOG>4){
-	  console.log('HEX VALUE IS ' + hCert);
-	  console.log('type of a' + typeof a);
-	  console.log('a VALUE IS ');
-	  console.log(a);
-	  console.log('a[0] VALUE IS ' + a[0]);
-	  console.log('a[1] VALUE IS ' + a[1]);
-  }
-  var rsa = new RSAKey();
-  rsa.setPublic(a[0], a[1]);
-  this.subjectPublicKeyRSA = rsa;
-  this.subjectPublicKeyRSA_hN = a[0];
-  this.subjectPublicKeyRSA_hE = a[1];
-  this.hex = hCert;
-}
-
-/**
- * read hex formatted X.509 certificate from string.
- * @name readCertHex
- * @memberOf X509#
- * @function
- * @param {String} hCert string for hex formatted X.509 certificate
- */
-function _x509_readCertHex(hCert) {
-  hCert = hCert.toLowerCase();
-  var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
-  var rsa = new RSAKey();
-  rsa.setPublic(a[0], a[1]);
-  this.subjectPublicKeyRSA = rsa;
-  this.subjectPublicKeyRSA_hN = a[0];
-  this.subjectPublicKeyRSA_hE = a[1];
-  this.hex = hCert;
-}
-
-function _x509_readCertPEMWithoutRSAInit(sCertPEM) {
-  var hCert = _x509_pemToHex(sCertPEM);
-  var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
-  this.subjectPublicKeyRSA.setPublic(a[0], a[1]);
-  this.subjectPublicKeyRSA_hN = a[0];
-  this.subjectPublicKeyRSA_hE = a[1];
-  this.hex = hCert;
-}
-
-/**
- * X.509 certificate class.<br/>
- * @class X.509 certificate class
- * @property {RSAKey} subjectPublicKeyRSA Tom Wu's RSAKey object
- * @property {String} subjectPublicKeyRSA_hN hexadecimal string for modulus of RSA public key
- * @property {String} subjectPublicKeyRSA_hE hexadecimal string for public exponent of RSA public key
- * @property {String} hex hexacedimal string for X.509 certificate.
- * @author Kenji Urushima
- * @version 1.0.1 (08 May 2012)
- * @see <a href="http://kjur.github.com/jsrsasigns/">'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/</a>
- */
-function X509() {
-  this.subjectPublicKeyRSA = null;
-  this.subjectPublicKeyRSA_hN = null;
-  this.subjectPublicKeyRSA_hE = null;
-  this.hex = null;
-}
-
-X509.prototype.readCertPEM = _x509_readCertPEM;
-X509.prototype.readCertHex = _x509_readCertHex;
-X509.prototype.readCertPEMWithoutRSAInit = _x509_readCertPEMWithoutRSAInit;
-X509.prototype.getSerialNumberHex = _x509_getSerialNumberHex;
-X509.prototype.getIssuerHex = _x509_getIssuerHex;
-X509.prototype.getSubjectHex = _x509_getSubjectHex;
-X509.prototype.getIssuerString = _x509_getIssuerString;
-X509.prototype.getSubjectString = _x509_getSubjectString;
-X509.prototype.getNotBefore = _x509_getNotBefore;
-X509.prototype.getNotAfter = _x509_getNotAfter;
-
+/*! x509-1.1.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
+ */
+// 
+// x509.js - X509 class to read subject public key from certificate.
+//
+// version: 1.1 (10-May-2012)
+//
+// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
+//
+// This software is licensed under the terms of the MIT License.
+// http://kjur.github.com/jsrsasign/license
+//
+// The above copyright and license notice shall be 
+// included in all copies or substantial portions of the Software.
+// 
+
+// Depends:
+//   base64.js
+//   rsa.js
+//   asn1hex.js
+
+function _x509_pemToBase64(sCertPEM) {
+  var s = sCertPEM;
+  s = s.replace("-----BEGIN CERTIFICATE-----", "");
+  s = s.replace("-----END CERTIFICATE-----", "");
+  s = s.replace(/[ \n]+/g, "");
+  return s;
+}
+
+function _x509_pemToHex(sCertPEM) {
+  var b64Cert = _x509_pemToBase64(sCertPEM);
+  var hCert = b64tohex(b64Cert);
+  return hCert;
+}
+
+function _x509_getHexTbsCertificateFromCert(hCert) {
+  var pTbsCert = ASN1HEX.getStartPosOfV_AtObj(hCert, 0);
+  return pTbsCert;
+}
+
+// NOTE: privateKeyUsagePeriod field of X509v2 not supported.
+// NOTE: v1 and v3 supported
+function _x509_getSubjectPublicKeyInfoPosFromCertHex(hCert) {
+  var pTbsCert = ASN1HEX.getStartPosOfV_AtObj(hCert, 0);
+  var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, pTbsCert); 
+  if (a.length < 1) return -1;
+  if (hCert.substring(a[0], a[0] + 10) == "a003020102") { // v3
+    if (a.length < 6) return -1;
+    return a[6];
+  } else {
+    if (a.length < 5) return -1;
+    return a[5];
+  }
+}
+
+// NOTE: Without BITSTRING encapsulation.
+// If pInfo is supplied, it is the position in hCert of the SubjectPublicKeyInfo.
+function _x509_getSubjectPublicKeyPosFromCertHex(hCert, pInfo) {
+  if (pInfo == null)
+      pInfo = _x509_getSubjectPublicKeyInfoPosFromCertHex(hCert);
+  if (pInfo == -1) return -1;    
+  var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, pInfo); 
+  
+  if (a.length != 2) return -1;
+  var pBitString = a[1];
+  if (hCert.substring(pBitString, pBitString + 2) != '03') return -1;
+  var pBitStringV = ASN1HEX.getStartPosOfV_AtObj(hCert, pBitString);
+
+  if (hCert.substring(pBitStringV, pBitStringV + 2) != '00') return -1;
+  return pBitStringV + 2;
+}
+
+// If p is supplied, it is the public key position in hCert.
+function _x509_getPublicKeyHexArrayFromCertHex(hCert, p) {
+  if (p == null)
+      p = _x509_getSubjectPublicKeyPosFromCertHex(hCert);
+  var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, p); 
+  //var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, a[3]); 
+  if(LOG>4){
+	  console.log('a is now');
+	  console.log(a);
+  }
+  
+  //if (a.length != 2) return [];
+  if (a.length < 2) return [];
+
+  var hN = ASN1HEX.getHexOfV_AtObj(hCert, a[0]);
+  var hE = ASN1HEX.getHexOfV_AtObj(hCert, a[1]);
+  if (hN != null && hE != null) {
+    return [hN, hE];
+  } else {
+    return [];
+  }
+}
+
+function _x509_getPublicKeyHexArrayFromCertPEM(sCertPEM) {
+  var hCert = _x509_pemToHex(sCertPEM);
+  var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
+  return a;
+}
+
+// ===== get basic fields from hex =====================================
+/**
+ * get hexadecimal string of serialNumber field of certificate.<br/>
+ * @name getSerialNumberHex
+ * @memberOf X509#
+ * @function
+ */
+function _x509_getSerialNumberHex() {
+  return ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 1]);
+}
+
+/**
+ * get hexadecimal string of issuer field of certificate.<br/>
+ * @name getIssuerHex
+ * @memberOf X509#
+ * @function
+ */
+function _x509_getIssuerHex() {
+  return ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3]);
+}
+
+/**
+ * get string of issuer field of certificate.<br/>
+ * @name getIssuerString
+ * @memberOf X509#
+ * @function
+ */
+function _x509_getIssuerString() {
+  return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3]));
+}
+
+/**
+ * get hexadecimal string of subject field of certificate.<br/>
+ * @name getSubjectHex
+ * @memberOf X509#
+ * @function
+ */
+function _x509_getSubjectHex() {
+  return ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5]);
+}
+
+/**
+ * get string of subject field of certificate.<br/>
+ * @name getSubjectString
+ * @memberOf X509#
+ * @function
+ */
+function _x509_getSubjectString() {
+  return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5]));
+}
+
+/**
+ * get notBefore field string of certificate.<br/>
+ * @name getNotBefore
+ * @memberOf X509#
+ * @function
+ */
+function _x509_getNotBefore() {
+  var s = ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 4, 0]);
+  s = s.replace(/(..)/g, "%$1");
+  s = decodeURIComponent(s);
+  return s;
+}
+
+/**
+ * get notAfter field string of certificate.<br/>
+ * @name getNotAfter
+ * @memberOf X509#
+ * @function
+ */
+function _x509_getNotAfter() {
+  var s = ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 4, 1]);
+  s = s.replace(/(..)/g, "%$1");
+  s = decodeURIComponent(s);
+  return s;
+}
+
+// ===== read certificate =====================================
+
+_x509_DN_ATTRHEX = {
+    "0603550406": "C",
+    "060355040a": "O",
+    "060355040b": "OU",
+    "0603550403": "CN",
+    "0603550405": "SN",
+    "0603550408": "ST",
+    "0603550407": "L" };
+
+function _x509_hex2dn(hDN) {
+  var s = "";
+  var a = ASN1HEX.getPosArrayOfChildren_AtObj(hDN, 0);
+  for (var i = 0; i < a.length; i++) {
+    var hRDN = ASN1HEX.getHexOfTLV_AtObj(hDN, a[i]);
+    s = s + "/" + _x509_hex2rdn(hRDN);
+  }
+  return s;
+}
+
+function _x509_hex2rdn(hRDN) {
+    var hType = ASN1HEX.getDecendantHexTLVByNthList(hRDN, 0, [0, 0]);
+    var hValue = ASN1HEX.getDecendantHexVByNthList(hRDN, 0, [0, 1]);
+    var type = "";
+    try { type = _x509_DN_ATTRHEX[hType]; } catch (ex) { type = hType; }
+    hValue = hValue.replace(/(..)/g, "%$1");
+    var value = decodeURIComponent(hValue);
+    return type + "=" + value;
+}
+
+// ===== read certificate =====================================
+
+
+/**
+ * read PEM formatted X.509 certificate from string.<br/>
+ * @name readCertPEM
+ * @memberOf X509#
+ * @function
+ * @param {String} sCertPEM string for PEM formatted X.509 certificate
+ */
+function _x509_readCertPEM(sCertPEM) {
+  var hCert = _x509_pemToHex(sCertPEM);
+  var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
+  if(LOG>4){
+	  console.log('HEX VALUE IS ' + hCert);
+	  console.log('type of a' + typeof a);
+	  console.log('a VALUE IS ');
+	  console.log(a);
+	  console.log('a[0] VALUE IS ' + a[0]);
+	  console.log('a[1] VALUE IS ' + a[1]);
+  }
+  var rsa = new RSAKey();
+  rsa.setPublic(a[0], a[1]);
+  this.subjectPublicKeyRSA = rsa;
+  this.subjectPublicKeyRSA_hN = a[0];
+  this.subjectPublicKeyRSA_hE = a[1];
+  this.hex = hCert;
+}
+
+/**
+ * read hex formatted X.509 certificate from string.
+ * @name readCertHex
+ * @memberOf X509#
+ * @function
+ * @param {String} hCert string for hex formatted X.509 certificate
+ */
+function _x509_readCertHex(hCert) {
+  hCert = hCert.toLowerCase();
+  var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
+  var rsa = new RSAKey();
+  rsa.setPublic(a[0], a[1]);
+  this.subjectPublicKeyRSA = rsa;
+  this.subjectPublicKeyRSA_hN = a[0];
+  this.subjectPublicKeyRSA_hE = a[1];
+  this.hex = hCert;
+}
+
+function _x509_readCertPEMWithoutRSAInit(sCertPEM) {
+  var hCert = _x509_pemToHex(sCertPEM);
+  var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
+  this.subjectPublicKeyRSA.setPublic(a[0], a[1]);
+  this.subjectPublicKeyRSA_hN = a[0];
+  this.subjectPublicKeyRSA_hE = a[1];
+  this.hex = hCert;
+}
+
+/**
+ * X.509 certificate class.<br/>
+ * @class X.509 certificate class
+ * @property {RSAKey} subjectPublicKeyRSA Tom Wu's RSAKey object
+ * @property {String} subjectPublicKeyRSA_hN hexadecimal string for modulus of RSA public key
+ * @property {String} subjectPublicKeyRSA_hE hexadecimal string for public exponent of RSA public key
+ * @property {String} hex hexacedimal string for X.509 certificate.
+ * @author Kenji Urushima
+ * @version 1.0.1 (08 May 2012)
+ * @see <a href="http://kjur.github.com/jsrsasigns/">'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/</a>
+ */
+function X509() {
+  this.subjectPublicKeyRSA = null;
+  this.subjectPublicKeyRSA_hN = null;
+  this.subjectPublicKeyRSA_hE = null;
+  this.hex = null;
+}
+
+X509.prototype.readCertPEM = _x509_readCertPEM;
+X509.prototype.readCertHex = _x509_readCertHex;
+X509.prototype.readCertPEMWithoutRSAInit = _x509_readCertPEMWithoutRSAInit;
+X509.prototype.getSerialNumberHex = _x509_getSerialNumberHex;
+X509.prototype.getIssuerHex = _x509_getIssuerHex;
+X509.prototype.getSubjectHex = _x509_getSubjectHex;
+X509.prototype.getIssuerString = _x509_getIssuerString;
+X509.prototype.getSubjectString = _x509_getSubjectString;
+X509.prototype.getNotBefore = _x509_getNotBefore;
+X509.prototype.getNotAfter = _x509_getNotAfter;
+
diff --git a/js/securityLib/x509-1.1.min.js b/contrib/securityLib/x509-1.1.min.js
similarity index 100%
rename from js/securityLib/x509-1.1.min.js
rename to contrib/securityLib/x509-1.1.min.js
diff --git a/js/examples/ndnping/ndn-ping.html b/examples/ndnping/ndn-ping.html
similarity index 100%
rename from js/examples/ndnping/ndn-ping.html
rename to examples/ndnping/ndn-ping.html
diff --git a/js/examples/ndnping/ndn-ping.js b/examples/ndnping/ndn-ping.js
similarity index 100%
rename from js/examples/ndnping/ndn-ping.js
rename to examples/ndnping/ndn-ping.js
diff --git a/js/NDN.js b/js/NDN.js
index 8f09811..d5a4a0e 100644
--- a/js/NDN.js
+++ b/js/NDN.js
@@ -393,7 +393,7 @@
 										
 			if (this.verify == false) {
 				// Pass content up without verifying the signature
-				currentClosure.upcall(Closure.UPCALL_CONTENT_UNVERIFIED, new UpcallInfo(this, null, 0, co));
+				currentClosure.upcall(Closure.UPCALL_CONTENT_UNVERIFIED, new UpcallInfo(this, pitEntry.interest, 0, co));
 				return;
 			}
 				
@@ -457,9 +457,9 @@
 						var rsakey = decodeSubjectPublicKeyInfo(co.content);
 						var verified = rsakey.verifyByteArray(co.rawSignatureData, wit, sigHex);
 						var flag = (verified == true) ? Closure.UPCALL_CONTENT : Closure.UPCALL_CONTENT_BAD;
-									
-						currentClosure.upcall(flag, new UpcallInfo(this, null, 0, co));
-									
+
+						currentClosure.upcall(flag, new UpcallInfo(this, pitEntry.interest, 0, co));
+
 						// SWT: We don't need to store key here since the same key will be
 						//      stored again in the closure.
 						//var keyEntry = new KeyStoreEntry(keylocator.keyName, rsakey, new Date().getTime());
@@ -474,9 +474,9 @@
 							var rsakey = keyEntry.rsaKey;
 							var verified = rsakey.verifyByteArray(co.rawSignatureData, wit, sigHex);
 							var flag = (verified == true) ? Closure.UPCALL_CONTENT : Closure.UPCALL_CONTENT_BAD;
-										
+
 							// Raise callback
-							currentClosure.upcall(flag, new UpcallInfo(this, null, 0, co));
+							currentClosure.upcall(flag, new UpcallInfo(this, pitEntry.interest, 0, co));
 						} else {
 							// Not found, fetch now
 							if (LOG > 3) console.log("Fetch key according to keylocator");
@@ -492,8 +492,8 @@
 							
 					var flag = (verified == true) ? Closure.UPCALL_CONTENT : Closure.UPCALL_CONTENT_BAD;
 					// Raise callback
-					currentClosure.upcall(Closure.UPCALL_CONTENT, new UpcallInfo(this, null, 0, co));
-								
+					currentClosure.upcall(Closure.UPCALL_CONTENT, new UpcallInfo(this, pitEntry.interest, 0, co));
+
 					// Since KeyLocator does not contain key name for this key,
 					// we have no way to store it as a key entry in KeyStore.
 				} else {
diff --git a/js/Name.js b/js/Name.js
index 833f383..c4bb39f 100644
--- a/js/Name.js
+++ b/js/Name.js
@@ -159,6 +159,39 @@
 	return this;
 };
 
+/**
+ * @brief Add component that represents a segment number
+ *
+ * @param number Segment number (integer is expected)
+ *
+ * This component has a special format handling:
+ * - if number is zero, then %00 is added
+ * - if number is between 1 and 255, %00%01 .. %00%FF is added
+ * - ...
+ */
+Name.prototype.addSegment = function(number) {
+    // step 1: figure out how many bytes will be needed
+    var bytes = 1; // at least 1 byte
+    var test_number = number;
+    while (test_number > 0) {
+        bytes ++;
+        test_number >>= 8;
+    }
+
+    var result = new Uint8Array (bytes);
+    var index = 0;
+    result[index] = 0;
+    index ++;
+    while (number > 0) {
+        result[index] = number & 0xFF;
+        number >>= 8;
+        index ++;
+    }
+
+    this.components.push(result);
+    return this;
+}
+
 // Return the escaped name string according to "CCNx URI Scheme".
 Name.prototype.to_uri = function() {	
     if (this.components.length == 0)
@@ -199,6 +232,14 @@
     return new Name(this.components.slice(0, nComponents));
 }
 
+/**
+ * @brief Get prefix of the name, containing less minusComponents right components
+ * @param minusComponents number of components to cut from the back
+ */
+Name.prototype.cut = function (minusComponents) {
+    return new Name(this.components.slice(0, this.components.length-1));
+}
+
 /*
  * Return a new ArrayBuffer of the component at i.
  */
diff --git a/js/tools/build/.gitignore b/js/tools/build/.gitignore
deleted file mode 100644
index 6faf4d3..0000000
--- a/js/tools/build/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-ndn-js-uncomp.js
-ndn-js.js
diff --git a/js/tools/build/README b/js/tools/build/README
deleted file mode 100644
index 22163be..0000000
--- a/js/tools/build/README
+++ /dev/null
@@ -1,8 +0,0 @@
-
-The script make-js.sh combines all of the NDN.JS scripts into a file called
-ndn-js-uncomp.js that can be more easily included in a webpage.  It them runs Google's
-Closure Compiler to create a compressed version, ndn-js.js.   This is what we recommend
-including in applications.
-
-
-
diff --git a/js/tools/build/compiler/COPYING b/js/tools/build/compiler/COPYING
deleted file mode 100644
index d645695..0000000
--- a/js/tools/build/compiler/COPYING
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/js/tools/build/compiler/README b/js/tools/build/compiler/README
deleted file mode 100644
index 270cfc2..0000000
--- a/js/tools/build/compiler/README
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright 2009 The Closure Compiler Authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//
-// Contents
-//
-
-The Closure Compiler performs checking, instrumentation, and
-optimizations on JavaScript code. The purpose of this README is to
-explain how to build and run the Closure Compiler.
-
-The Closure Compiler requires Java 6 or higher.
-http://www.java.com/
-
-
-//
-// Building The Closure Compiler
-//
-
-There are three ways to get a Closure Compiler executable.
-
-1) Use one we built for you.
-
-Pre-built Closure binaries can be found at
-http://code.google.com/p/closure-compiler/downloads/list
-
-
-2) Check out the source and build it with Apache Ant.
-
-First, check out the full source tree of the Closure Compiler. There
-are instructions on how to do this at the project site.
-http://code.google.com/p/closure-compiler/source/checkout
-
-Apache Ant is a cross-platform build tool.
-http://ant.apache.org/
-
-At the root of the source tree, there is an Ant file named
-build.xml. To use it, navigate to the same directory and type the
-command
-
-ant jar
-
-This will produce a jar file called "build/compiler.jar".
-
-
-3) Check out the source and build it with Eclipse.
-
-Eclipse is a cross-platform IDE.
-http://www.eclipse.org/
-
-Under Eclipse's File menu, click "New > Project ..." and create a
-"Java Project."  You will see an options screen. Give the project a
-name, select "Create project from existing source," and choose the
-root of the checked-out source tree as the existing directory. Verify
-that you are using JRE version 6 or higher.
-
-Eclipse can use the build.xml file to discover rules. When you
-navigate to the build.xml file, you will see all the build rules in
-the "Outline" pane. Run the "jar" rule to build the compiler in
-build/compiler.jar.
-
-
-//
-// Running The Closure Compiler
-//
-
-Once you have the jar binary, running the Closure Compiler is straightforward.
-
-On the command line, type
-
-java -jar compiler.jar
-
-This starts the compiler in interactive mode. Type
-
-var x = 17 + 25;
-
-then hit "Enter", then hit "Ctrl-Z" (on Windows) or "Ctrl-D" (on Mac or Linux)
-and "Enter" again. The Compiler will respond:
-
-var x=42;
-
-The Closure Compiler has many options for reading input from a file,
-writing output to a file, checking your code, and running
-optimizations. To learn more, type
-
-java -jar compiler.jar --help
-
-You can read more detailed documentation about the many flags at
-http://code.google.com/closure/compiler/docs/gettingstarted_app.html
-
-
-//
-// Compiling Multiple Scripts
-//
-
-If you have multiple scripts, you should compile them all together with
-one compile command.
-
-java -jar compiler.jar --js=in1.js --js=in2.js ... --js_output_file=out.js
-
-The Closure Compiler will concatenate the files in the order they're
-passed at the command line.
-
-If you need to compile many, many scripts together, you may start to
-run into problems with managing dependencies between scripts. You
-should check out the Closure Library. It contains functions for
-enforcing dependencies between scripts, and a tool called calcdeps.py
-that knows how to give scripts to the Closure Compiler in the right
-order.
-
-http://code.google.com/p/closure-library/
-
-//
-// Licensing
-//
-
-Unless otherwise stated, all source files are licensed under
-the Apache License, Version 2.0.
-
-
------
-Code under:
-src/com/google/javascript/rhino
-test/com/google/javascript/rhino
-
-URL: http://www.mozilla.org/rhino
-Version:  1.5R3, with heavy modifications
-License:  Netscape Public License and MPL / GPL dual license
-
-Description: A partial copy of Mozilla Rhino. Mozilla Rhino is an
-implementation of JavaScript for the JVM.  The JavaScript parser and
-the parse tree data structures were extracted and modified
-significantly for use by Google's JavaScript compiler.
-
-Local Modifications: The packages have been renamespaced. All code not
-relevant to parsing has been removed. A JsDoc parser and static typing
-system have been added.
-
-
------
-Code in:
-lib/rhino
-
-Rhino
-URL: http://www.mozilla.org/rhino
-Version:  Trunk
-License:  Netscape Public License and MPL / GPL dual license
-
-Description: Mozilla Rhino is an implementation of JavaScript for the JVM.
-
-Local Modifications: Minor changes to parsing JSDoc that usually get pushed
-up-stream to Rhino trunk.
-
-
------
-Code in:
-lib/args4j.jar
-
-Args4j
-URL: https://args4j.dev.java.net/
-Version: 2.0.16
-License: MIT
-
-Description:
-args4j is a small Java class library that makes it easy to parse command line
-options/arguments in your CUI application.
-
-Local Modifications: None.
-
-
------
-Code in:
-lib/guava.jar
-
-Guava Libraries
-URL: http://code.google.com/p/guava-libraries/
-Version:  13.0.1
-License: Apache License 2.0
-
-Description: Google's core Java libraries.
-
-Local Modifications: None.
-
-
------
-Code in:
-lib/jsr305.jar
-
-Annotations for software defect detection
-URL: http://code.google.com/p/jsr-305/
-Version: svn revision 47
-License: BSD License
-
-Description: Annotations for software defect detection.
-
-Local Modifications: None.
-
-
------
-Code in:
-lib/jarjar.jar
-
-Jar Jar Links
-URL: http://jarjar.googlecode.com/
-Version: 1.1
-License: Apache License 2.0
-
-Description:
-A utility for repackaging Java libraries.
-
-Local Modifications: None.
-
-
-----
-Code in:
-lib/junit.jar
-
-JUnit
-URL:  http://sourceforge.net/projects/junit/
-Version:  4.10
-License:  Common Public License 1.0
-
-Description: A framework for writing and running automated tests in Java.
-
-Local Modifications: None.
-
-
----
-Code in:
-lib/protobuf-java.jar
-
-Protocol Buffers
-URL: http://code.google.com/p/protobuf/
-Version: 2.4.1
-License: New BSD License
-
-Description: Supporting libraries for protocol buffers,
-an encoding of structured data.
-
-Local Modifications: None
-
-
----
-Code in:
-lib/ant.jar
-lib/ant-launcher.jar
-
-URL: http://ant.apache.org/bindownload.cgi
-Version: 1.8.1
-License: Apache License 2.0
-Description:
-  Ant is a Java based build tool. In theory it is kind of like "make"
-  without make's wrinkles and with the full portability of pure java code.
-
-Local Modifications: None
-
-
----
-Code in:
-lib/json.jar
-URL: http://json.org/java/index.html
-Version: JSON version 20090211
-License: MIT license
-Description:
-JSON is a set of java files for use in transmitting data in JSON format.
-
-Local Modifications: None
-
----
-Code in:
-tools/maven-ant-tasks-2.1.3.jar
-URL: http://maven.apache.org
-Version 2.1.3
-License: Apache License 2.0
-Description:
-  Maven Ant tasks are used to manage dependencies and to install/deploy to
-  maven repositories.
-
-Local Modifications: None
diff --git a/js/tools/build/compiler/compiler.jar b/js/tools/build/compiler/compiler.jar
deleted file mode 100644
index e23352f..0000000
--- a/js/tools/build/compiler/compiler.jar
+++ /dev/null
Binary files differ
diff --git a/js/tools/build/make-js.sh b/js/tools/build/make-js.sh
deleted file mode 100755
index a592700..0000000
--- a/js/tools/build/make-js.sh
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/bin/sh
-
-rm ndn-js-uncomp.js
-
-cat ../../Closure.js \
-  ../../WebSocketTransport.js \
-  ../../util/CCNProtocolDTags.js \
-  ../../util/CCNTime.js \
-  ../../util/ExponentialReExpressClosure.js \
-  ../../Name.js \
-  ../../ContentObject.js \
-  ../../encoding/DateFormat.js \
-  ../../Interest.js \
-  ../../Key.js \
-  ../../PublisherID.js \
-  ../../PublisherPublicKeyDigest.js \
-  ../../FaceInstance.js \
-  ../../ForwardingEntry.js \
-  ../../encoding/DynamicUint8Array.js \
-  ../../encoding/BinaryXMLEncoder.js \
-  ../../encoding/BinaryXMLDecoder.js \
-  ../../encoding/BinaryXMLStructureDecoder.js \
-  ../../encoding/DataUtils.js \
-  ../../encoding/EncodingUtils.js \
-  ../../security/KeyManager.js \
-  ../../security/Witness.js \
-  ../../securityLib/sha256.js \
-  ../../securityLib/base64.js \
-  ../../securityLib/rsa.js \
-  ../../securityLib/rsa2.js \
-  ../../securityLib/rsapem-1.1.js \
-  ../../securityLib/rsasign-1.2.js \
-  ../../securityLib/asn1hex-1.1.js \
-  ../../securityLib/x509-1.1.js \
-  ../../securityLib/jsbn.js \
-  ../../securityLib/jsbn2.js \
-  ../../NDN.js \
-  > ndn-js-uncomp.js
-
-java -jar compiler/compiler.jar --js ndn-js-uncomp.js --js_output_file ndn-js.js
diff --git a/js/tools/build/ndn-js-uncomp.js b/js/tools/build/ndn-js-uncomp.js
deleted file mode 100644
index 51a90d8..0000000
--- a/js/tools/build/ndn-js-uncomp.js
+++ /dev/null
@@ -1,8164 +0,0 @@
-/**
- * @author: Jeff Thompson
- * See COPYING for copyright and distribution information.
- * Provide the callback closure for the async communication methods in the NDN class.
- * This is a port of Closure.py from PyCCN, written by: 
- * Derek Kulinski <takeda@takeda.tk>
- * Jeff Burke <jburke@ucla.edu>
- */
-
-/*
- * Create a subclass of Closure and pass an object to async calls.
- */
-var Closure = function Closure() {
-	// I don't think storing NDN's closure is needed
-	// and it creates a reference loop, as of now both
-	// of those variables are never set -- Derek
-	//
-	// Use instance variables to return data to callback
-	this.ndn_data = null;  // this holds the ndn_closure
-    this.ndn_data_dirty = false;
-    
-};
-
-// Upcall result
-Closure.RESULT_ERR               = -1; // upcall detected an error
-Closure.RESULT_OK                =  0; // normal upcall return
-Closure.RESULT_REEXPRESS         =  1; // reexpress the same interest again
-Closure.RESULT_INTEREST_CONSUMED =  2; // upcall claims to consume interest
-Closure.RESULT_VERIFY            =  3; // force an unverified result to be verified
-Closure.RESULT_FETCHKEY          =  4; // get the key in the key locator and re-call the interest
-                                       //   with the key available in the local storage
-
-// Upcall kind
-Closure.UPCALL_FINAL              = 0; // handler is about to be deregistered
-Closure.UPCALL_INTEREST           = 1; // incoming interest
-Closure.UPCALL_CONSUMED_INTEREST  = 2; // incoming interest, someone has answered
-Closure.UPCALL_CONTENT            = 3; // incoming verified content
-Closure.UPCALL_INTEREST_TIMED_OUT = 4; // interest timed out
-Closure.UPCALL_CONTENT_UNVERIFIED = 5; // content that has not been verified
-Closure.UPCALL_CONTENT_BAD        = 6; // verification failed
-
-/*
- * Override this in your subclass.
- * If you're getting strange errors in upcall()
- * check your code whether you're returning a value.
- */
-Closure.prototype.upcall = function(kind, upcallInfo) {
-	//dump('upcall ' + this + " " + kind + " " + upcallInfo + "\n");
-	return Closure.RESULT_OK;
-};
-
-var UpcallInfo = function UpcallInfo(ndn, interest, matchedComps, contentObject) {
-	this.ndn = ndn;  // NDN object (not used)
-	this.interest = interest;  // Interest object
-	this.matchedComps = matchedComps;  // int
-	this.contentObject = contentObject;  // Content object
-};
-
-UpcallInfo.prototype.toString = function() {
-	var ret = "ndn = " + this.ndn;
-	ret += "\nInterest = " + this.interest;
-	ret += "\nmatchedComps = " + this.matchedComps;
-	ret += "\nContentObject: " + this.contentObject;
-	return ret;
-}
-/** 
- * @author: Wentao Shang
- * See COPYING for copyright and distribution information.
- */
-
-var WebSocketTransport = function WebSocketTransport() {    
-    if (!WebSocket)
-        throw new Error("WebSocket support is not available on this platform.");
-    
-	this.ws = null;
-    this.connectedHost = null; // Read by NDN.
-    this.connectedPort = null; // Read by NDN.
-    this.elementReader = null;
-    this.defaultGetHostAndPort = NDN.makeShuffledGetHostAndPort
-        (["A.ws.ndn.ucla.edu", "B.ws.ndn.ucla.edu", "C.ws.ndn.ucla.edu", "D.ws.ndn.ucla.edu", 
-          "E.ws.ndn.ucla.edu"],
-         9696);
-};
-
-/*
- * Connect to the host and port in ndn.  This replaces a previous connection and sets connectedHost
- *   and connectedPort.  Once connected, call onopenCallback().
- * Listen on the port to read an entire binary XML encoded element and call
- *    ndn.onReceivedElement(element).
- */
-WebSocketTransport.prototype.connect = function(ndn, onopenCallback) {
-	if (this.ws != null)
-		delete this.ws;
-	
-	this.ws = new WebSocket('ws://' + ndn.host + ':' + ndn.port);
-	if (LOG > 0) console.log('ws connection created.');
-    this.connectedHost = ndn.host;
-    this.connectedPort = ndn.port;
-	
-	this.ws.binaryType = "arraybuffer";
-	
-    this.elementReader = new BinaryXmlElementReader(ndn);
-	var self = this;
-	this.ws.onmessage = function(ev) {
-		var result = ev.data;
-		//console.log('RecvHandle called.');
-			
-		if(result == null || result == undefined || result == "" ) {
-			console.log('INVALID ANSWER');
-		} else if (result instanceof ArrayBuffer) {
-	        var bytearray = new Uint8Array(result);
-	        
-			if (LOG>3) console.log('BINARY RESPONSE IS ' + DataUtils.toHex(bytearray));
-			
-			try {
-                // Find the end of the binary XML element and call ndn.onReceivedElement.
-                self.elementReader.onReceivedData(bytearray);
-			} catch (ex) {
-				console.log("NDN.ws.onmessage exception: " + ex);
-				return;
-			}
-		}
-	}
-	
-	this.ws.onopen = function(ev) {
-		if (LOG > 3) console.log(ev);
-		if (LOG > 3) console.log('ws.onopen: WebSocket connection opened.');
-		if (LOG > 3) console.log('ws.onopen: ReadyState: ' + this.readyState);
-        // NDN.registerPrefix will fetch the ccndid when needed.
-        
-        onopenCallback();
-	}
-	
-	this.ws.onerror = function(ev) {
-		console.log('ws.onerror: ReadyState: ' + this.readyState);
-		console.log(ev);
-		console.log('ws.onerror: WebSocket error: ' + ev.data);
-	}
-	
-	this.ws.onclose = function(ev) {
-		console.log('ws.onclose: WebSocket connection closed.');
-		self.ws = null;
-		
-		// Close NDN when WebSocket is closed
-		ndn.readyStatus = NDN.CLOSED;
-		ndn.onclose();
-		//console.log("NDN.onclose event fired.");
-	}
-};
-
-/*
- * Send the Uint8Array data.
- */
-WebSocketTransport.prototype.send = function(data) {
-	if (this.ws != null) {
-        // If we directly use data.buffer to feed ws.send(), 
-        // WebSocket may end up sending a packet with 10000 bytes of data.
-        // That is, WebSocket will flush the entire buffer
-        // regardless of the offset of the Uint8Array. So we have to create
-        // a new Uint8Array buffer with just the right size and copy the 
-        // content from binaryInterest to the new buffer.
-        //    ---Wentao
-        var bytearray = new Uint8Array(data.length);
-        bytearray.set(data);
-        this.ws.send(bytearray.buffer);
-		if (LOG > 3) console.log('ws.send() returned.');
-	}
-	else
-		console.log('WebSocket connection is not established.');
-}
-/**
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- * This class contains all CCNx tags
- */
-
-
-var CCNProtocolDTags = {
-
-	/**
-	 * Note if you add one of these, add it to the reverse string map as well.
-	 * Emphasize getting the work done at compile time over trying to make something
-	 * flexible and developer error-proof.
-	 */
-
-	 Any : 13,
-	 Name : 14,
-	 Component : 15,
-	 Certificate : 16,
-	 Collection : 17,
-	 CompleteName : 18,
-	 Content : 19,
-	 SignedInfo : 20,
-	 ContentDigest : 21,
-	 ContentHash : 22,
-	 Count : 24,
-	 Header : 25,
-	 Interest : 26,	/* 20090915 */
-	 Key : 27,
-	 KeyLocator : 28,
-	 KeyName : 29,
-	 Length : 30,
-	 Link : 31,
-	 LinkAuthenticator : 32,
-	 NameComponentCount : 33,	/* DeprecatedInInterest */
-	 RootDigest : 36,
-	 Signature : 37,
-	 Start : 38,
-	 Timestamp : 39,
-	 Type : 40,
-	 Nonce : 41,
-	 Scope : 42,
-	 Exclude : 43,
-	 Bloom : 44,
-	 BloomSeed : 45,
-	 AnswerOriginKind : 47,
-	 InterestLifetime : 48,
-	 Witness : 53,
-	 SignatureBits : 54,
-	 DigestAlgorithm : 55,
-	 BlockSize : 56,
-	 FreshnessSeconds : 58,
-	 FinalBlockID : 59,
-	 PublisherPublicKeyDigest : 60,
-	 PublisherCertificateDigest : 61,
-	 PublisherIssuerKeyDigest : 62,
-	 PublisherIssuerCertificateDigest : 63,
-	 ContentObject : 64,	/* 20090915 */
-	 WrappedKey : 65,
-	 WrappingKeyIdentifier : 66,
-	 WrapAlgorithm : 67,
-	 KeyAlgorithm : 68,
-	 Label : 69,
-	 EncryptedKey : 70,
-	 EncryptedNonceKey : 71,
-	 WrappingKeyName : 72,
-	 Action : 73,
-	 FaceID : 74,
-	 IPProto : 75,
-	 Host : 76,
-	 Port : 77,
-	 MulticastInterface : 78,
-	 ForwardingFlags : 79,
-	 FaceInstance : 80,
-	 ForwardingEntry : 81,
-	 MulticastTTL : 82,
-	 MinSuffixComponents : 83,
-	 MaxSuffixComponents : 84,
-	 ChildSelector : 85,
-	 RepositoryInfo : 86,
-	 Version : 87,
-	 RepositoryVersion : 88,
-	 GlobalPrefix : 89,
-	 LocalName : 90,
-	 Policy : 91,
-	 Namespace : 92,
-	 GlobalPrefixName : 93,
-	 PolicyVersion : 94,
-	 KeyValueSet : 95,
-	 KeyValuePair : 96,
-	 IntegerValue : 97,
-	 DecimalValue : 98,
-	 StringValue : 99,
-	 BinaryValue : 100,
-	 NameValue : 101,
-	 Entry : 102,
-	 ACL : 103,
-	 ParameterizedName : 104,
-	 Prefix : 105,
-	 Suffix : 106,
-	 Root : 107,
-	 ProfileName : 108,
-	 Parameters : 109,
-	 InfoString : 110,
-	// 111 unallocated
-	 StatusResponse : 112,
-	 StatusCode : 113,
-	 StatusText : 114,
-
-	// Sync protocol
-	 SyncNode : 115,
-	 SyncNodeKind : 116,
-	 SyncNodeElement : 117,
-	 SyncVersion : 118,
-	 SyncNodeElements : 119,
-	 SyncContentHash : 120,
-	 SyncLeafCount : 121,
-	 SyncTreeDepth : 122,
-	 SyncByteCount : 123,
-	 ConfigSlice : 124,
-	 ConfigSliceList : 125,
-	 ConfigSliceOp : 126,
-
-	// Remember to keep in sync with schema/tagnames.csvsdict
-	 CCNProtocolDataUnit : 17702112,
-	 CCNPROTOCOL_DATA_UNIT : "CCNProtocolDataUnit"
-};
-
-var CCNProtocolDTagsStrings = [
-	null, null, null, null, null, null, null, null, null, null, null,
-	null, null,
-	"Any", "Name", "Component", "Certificate", "Collection", "CompleteName",
-	"Content", "SignedInfo", "ContentDigest", "ContentHash", null, "Count", "Header",
-	"Interest", "Key", "KeyLocator", "KeyName", "Length", "Link", "LinkAuthenticator",
-	"NameComponentCount", null, null, "RootDigest", "Signature", "Start", "Timestamp", "Type",
-	"Nonce", "Scope", "Exclude", "Bloom", "BloomSeed", null, "AnswerOriginKind",
-	"InterestLifetime", null, null, null, null, "Witness", "SignatureBits", "DigestAlgorithm", "BlockSize",
-	null, "FreshnessSeconds", "FinalBlockID", "PublisherPublicKeyDigest", "PublisherCertificateDigest",
-	"PublisherIssuerKeyDigest", "PublisherIssuerCertificateDigest", "ContentObject",
-	"WrappedKey", "WrappingKeyIdentifier", "WrapAlgorithm", "KeyAlgorithm", "Label",
-	"EncryptedKey", "EncryptedNonceKey", "WrappingKeyName", "Action", "FaceID", "IPProto",
-	"Host", "Port", "MulticastInterface", "ForwardingFlags", "FaceInstance",
-	"ForwardingEntry", "MulticastTTL", "MinSuffixComponents", "MaxSuffixComponents", "ChildSelector",
-	"RepositoryInfo", "Version", "RepositoryVersion", "GlobalPrefix", "LocalName",
-	"Policy", "Namespace", "GlobalPrefixName", "PolicyVersion", "KeyValueSet", "KeyValuePair",
-	"IntegerValue", "DecimalValue", "StringValue", "BinaryValue", "NameValue", "Entry",
-	"ACL", "ParameterizedName", "Prefix", "Suffix", "Root", "ProfileName", "Parameters",
-	"InfoString", null,
-    "StatusResponse", "StatusCode", "StatusText", "SyncNode", "SyncNodeKind", "SyncNodeElement",
-    "SyncVersion", "SyncNodeElements", "SyncContentHash", "SyncLeafCount", "SyncTreeDepth", "SyncByteCount",
-    "ConfigSlice", "ConfigSliceList", "ConfigSliceOp" ];
-
-
-//TESTING
-//console.log(exports.CCNProtocolDTagsStrings[17]);
-
-/**
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- * This class represents CCNTime Objects
- */
-
-var CCNTime = function CCNTime(
-                               
-		input) {
-
-
-
-
-	this.NANOS_MAX = 999877929;
-	
-	/*if(typeof input =='object'){
-		this.longDate = DataUtils.byteArrayToUnsignedLong(input);
-		this.binaryDate = input;
-	}*/
-	if(typeof input =='number'){
-		this.msec = input;
-		//this.binaryDate = DataUtils.unsignedLongToByteArray(input);
-
-	}
-	else{
-		if(LOG>1) console.log('UNRECOGNIZED TYPE FOR TIME');
-	}
-};
-
-
-CCNTime.prototype.getJavascriptDate = function(){
-	var d = new Date();
-	d.setTime( this.msec );
-	return d
-};
-
-	/**
-	 * Create a CCNTime
-	 * @param timestamp source timestamp to initialize from, some precision will be lost
-	 */
-
-
-	/**
-	 * Create a CCNTime from its binary encoding
-	 * @param binaryTime12 the binary representation of a CCNTime
-	 */
-/*CCNTime.prototype.setDateBinary = function(
-	//byte [] 
-		binaryTime12) {
-
-
-	if ((null == binaryTime12) || (binaryTime12.length == 0)) {
-		throw new IllegalArgumentException("Invalid binary time!");
-	}
-	
-
-	value = 0;
-	for(i = 0; i < binaryTime12.length; i++) {
-		value = value << 8;
-		b = (binaryTime12[i]) & 0xFF;
-		value |= b;
-	}
-
-	//this.date = new Date(value);
-
-};
-
-//byte[]
-CCNTime.prototype.toBinaryTime = function() {
-
-	return this.msec; //unsignedLongToByteArray(this.date.getTime());
-
-}*/
-/*
-unsignedLongToByteArray= function( value) {
-	if( 0 == value )
-		return [0];
-
-	if( 0 <= value && value <= 0x00FF ) {
-		//byte [] 
-		bb = new Array[1];
-		bb[0] = (value & 0x00FF);
-		return bb;
-	}
-
-	
-	//byte [] 
-	out = null;
-	//int
-	offset = -1;
-	for(var i = 7; i >=0; --i) {
-		//byte
-		b = ((value >> (i * 8)) & 0xFF);
-		if( out == null && b != 0 ) {
-			out = new Array(i+1);//byte[i+1];
-			offset = i;
-		}
-		if( out != null )
-			out[ offset - i ] = b;
-	}
-	return out;
-}*/
-	
-/**
- * @author: Jeff Thompson
- * See COPYING for copyright and distribution information.
- * This is the closure class for use in expressInterest to re express with exponential falloff.
- */
-
-/*
- * Create a new ExponentialReExpressClosure where upcall responds to UPCALL_INTEREST_TIMED_OUT
- *   by expressing the interest again with double the interestLifetime. If the interesLifetime goes
- *   over maxInterestLifetime, then call callerClosure.upcall with UPCALL_INTEREST_TIMED_OUT.
- * When upcall is not UPCALL_INTEREST_TIMED_OUT, just call callerClosure.upcall.
- * 
- * settings is an associative array with the following defaults:
- * {
- *   maxInterestLifetime: 16000 // milliseconds
- * }
- */
-var ExponentialReExpressClosure = function ExponentialReExpressClosure
-        (callerClosure, settings) {
-    // Inherit from Closure.
-    Closure.call(this);
-    
-    this.callerClosure = callerClosure;
-    settings = (settings || {});
-	this.maxInterestLifetime = (settings.maxInterestLifetime || 16000);
-};
-
-ExponentialReExpressClosure.prototype.upcall = function(kind, upcallInfo) {
-    try {
-        if (kind == Closure.UPCALL_INTEREST_TIMED_OUT) {
-            var interestLifetime = upcallInfo.interest.interestLifetime;
-            if (interestLifetime == null)
-                return this.callerClosure.upcall(Closure.UPCALL_INTEREST_TIMED_OUT, upcallInfo);
-            
-            var nextInterestLifetime = interestLifetime * 2;
-            if (nextInterestLifetime > this.maxInterestLifetime)
-                return this.callerClosure.upcall(Closure.UPCALL_INTEREST_TIMED_OUT, upcallInfo);
-            
-            var nextInterest = upcallInfo.interest.clone();
-            nextInterest.interestLifetime = nextInterestLifetime;
-            upcallInfo.ndn.expressInterest(nextInterest.name, this, nextInterest);
-            return Closure.RESULT_OK;
-        }  
-        else
-            return this.callerClosure.upcall(kind, upcallInfo);
-    } catch (ex) {
-        console.log("ExponentialReExpressClosure.upcall exception: " + ex);
-        return Closure.RESULT_ERR;
-    }
-};
-/**
- * @author: Meki Cheraoui, Jeff Thompson
- * See COPYING for copyright and distribution information.
- * This class represents a Name as an array of components where each is a byte array.
- */
- 
-/*
- * Create a new Name from _components.
- * If _components is a string, parse it as a URI.
- * If _components is a Name, add a deep copy of its components.
- * Otherwise it is an array of components where each is a string, byte array, ArrayBuffer, Uint8Array
- *   or Name. 
- * Convert and store as an array of Uint8Array.
- * If a component is a string, encode as utf8.
- */
-var Name = function Name(_components){
-	if( typeof _components == 'string') {		
-		if(LOG>3)console.log('Content Name String '+_components);
-		this.components = Name.createNameArray(_components);
-	}
-	else if(typeof _components === 'object'){		
-		this.components = [];
-        if (_components instanceof Name)
-            this.add(_components);
-        else {
-            for (var i = 0; i < _components.length; ++i)
-                this.add(_components[i]);
-        }
-	}
-	else if(_components==null)
-		this.components =[];
-	else
-		if(LOG>1)console.log("NO CONTENT NAME GIVEN");
-};
-
-Name.prototype.getName = function() {
-    return this.to_uri();
-};
-
-/* Parse name as a URI and return an array of Uint8Array components.
- *
- */
-Name.createNameArray = function(name) {
-    name = name.trim();
-    if (name.length <= 0)
-        return [];
-
-    var iColon = name.indexOf(':');
-    if (iColon >= 0) {
-        // Make sure the colon came before a '/'.
-        var iFirstSlash = name.indexOf('/');
-        if (iFirstSlash < 0 || iColon < iFirstSlash)
-            // Omit the leading protocol such as ndn:
-            name = name.substr(iColon + 1, name.length - iColon - 1).trim();
-    }
-    
-  	if (name[0] == '/') {
-        if (name.length >= 2 && name[1] == '/') {
-            // Strip the authority following "//".
-            var iAfterAuthority = name.indexOf('/', 2);
-            if (iAfterAuthority < 0)
-                // Unusual case: there was only an authority.
-                return [];
-            else
-                name = name.substr(iAfterAuthority + 1, name.length - iAfterAuthority - 1).trim();
-        }
-        else
-            name = name.substr(1, name.length - 1).trim();
-    }
-
-	var array = name.split('/');
-    
-    // Unescape the components.
-    for (var i = 0; i < array.length; ++i) {
-        var component = Name.fromEscapedString(array[i]);
-        
-        if (component == null) {
-            // Ignore the illegal componenent.  This also gets rid of a trailing '/'.
-            array.splice(i, 1);
-            --i;  
-            continue;
-        }
-        else
-            array[i] = component;
-    }
-
-	return array;
-}
-
-
-Name.prototype.from_ccnb = function(/*XMLDecoder*/ decoder)  {
-		decoder.readStartElement(this.getElementLabel());
-
-		
-		this.components = new Array(); //new ArrayList<byte []>();
-
-		while (decoder.peekStartElement(CCNProtocolDTags.Component)) {
-			this.add(decoder.readBinaryElement(CCNProtocolDTags.Component));
-		}
-		
-		decoder.readEndElement();
-};
-
-Name.prototype.to_ccnb = function(/*XMLEncoder*/ encoder)  {
-		
-		if( this.components ==null ) 
-			throw new Error("CANNOT ENCODE EMPTY CONTENT NAME");
-
-		encoder.writeStartElement(this.getElementLabel());
-		var count = this.components.length;
-		for (var i=0; i < count; i++) {
-			encoder.writeElement(CCNProtocolDTags.Component, this.components[i]);
-		}
-		encoder.writeEndElement();
-};
-
-Name.prototype.getElementLabel = function(){
-	return CCNProtocolDTags.Name;
-};
-
-/*
- * component is a string, byte array, ArrayBuffer, Uint8Array or Name.
- * Convert to Uint8Array and add to this Name.
- * If a component is a string, encode as utf8.
- * Return this Name object to allow chaining calls to add.
- */
-Name.prototype.add = function(component){
-    var result;
-    if(typeof component == 'string')
-        result = DataUtils.stringToUtf8Array(component);
-	else if(typeof component == 'object' && component instanceof Uint8Array)
-        result = new Uint8Array(component);
-	else if(typeof component == 'object' && component instanceof ArrayBuffer) {
-        // Make a copy.  Don't use ArrayBuffer.slice since it isn't always supported.
-        result = new Uint8Array(new ArrayBuffer(component.byteLength));
-        result.set(new Uint8Array(component));
-    }
-    else if (typeof component == 'object' && component instanceof Name) {
-        var components;
-        if (component == this)
-            // special case, when we need to create a copy
-            components = this.components.slice(0, this.components.length);
-        else
-            components = component.components;
-        
-        for (var i = 0; i < components.length; ++i)
-            this.components.push(new Uint8Array(components[i]));
-        return this;
-    }
-	else if(typeof component == 'object')
-        // Assume component is a byte array.  We can't check instanceof Array because
-        //   this doesn't work in JavaScript if the array comes from a different module.
-        result = new Uint8Array(component);
-	else 
-		throw new Error("Cannot add Name element at index " + this.components.length + 
-            ": Invalid type");
-    
-    this.components.push(result);
-	return this;
-};
-
-// Return the escaped name string according to "CCNx URI Scheme".
-Name.prototype.to_uri = function() {	
-    if (this.components.length == 0)
-        return "/";
-    
-	var result = "";
-	
-	for(var i = 0; i < this.components.length; ++i)
-		result += "/"+ Name.toEscapedString(this.components[i]);
-	
-	return result;	
-};
-
-/**
-* @brief Add component that represents a segment number
-*
-* @param number Segment number (integer is expected)
-*
-* This component has a special format handling:
-* - if number is zero, then %00 is added
-* - if number is between 1 and 255, %00%01 .. %00%FF is added
-* - ...
-*/
-Name.prototype.addSegment = function(number) {
-    var segmentNumberBigEndian = DataUtils.nonNegativeIntToBigEndian(number);
-    // Put a 0 byte in front.
-    var segmentNumberComponent = new Uint8Array(segmentNumberBigEndian.length + 1);
-    segmentNumberComponent.set(segmentNumberBigEndian, 1);
-
-    this.components.push(segmentNumberComponent);
-    return this;
-};
-
-/*
- * Return a new Name with the first nComponents components of this Name.
- */
-Name.prototype.getPrefix = function(nComponents) {
-    return new Name(this.components.slice(0, nComponents));
-}
-
-/*
- * Return a new ArrayBuffer of the component at i.
- */
-Name.prototype.getComponent = function(i) {
-    var result = new ArrayBuffer(this.components[i].length);
-    new Uint8Array(result).set(this.components[i]);
-    return result;
-}
-
-/*
- * The "file name" in a name is the last component that isn't blank and doesn't start with one of the
- *   special marker octets (for version, etc.).  Return the index in this.components of
- *   the file name, or -1 if not found.
- */
-Name.prototype.indexOfFileName = function() {
-    for (var i = this.components.length - 1; i >= 0; --i) {
-        var component = this.components[i];
-        if (component.length <= 0)
-            continue;
-        
-        if (component[0] == 0 || component[0] == 0xC0 || component[0] == 0xC1 || 
-            (component[0] >= 0xF5 && component[0] <= 0xFF))
-            continue;
-        
-        return i;
-    }
-    
-    return -1;
-}
-
-/*
- * Return true if this Name has the same components as name.
- */
-Name.prototype.equalsName = function(name) {
-    if (this.components.length != name.components.length)
-        return false;
-    
-    // Start from the last component because they are more likely to differ.
-    for (var i = this.components.length - 1; i >= 0; --i) {
-        if (!DataUtils.arraysEqual(this.components[i], name.components[i]))
-            return false;
-    }
-    
-    return true;
-}
-
-/*
- * Find the last component in name that has a ContentDigest and return the digest value as Uint8Array, 
- *   or null if not found.  See Name.getComponentContentDigestValue.
- */
-Name.prototype.getContentDigestValue = function() {
-    for (var i = this.components.length - 1; i >= 0; --i) {
-        var digestValue = Name.getComponentContentDigestValue(this.components[i]);
-        if (digestValue != null)
-           return digestValue;
-    }
-    
-    return null;
-}
-
-/*
- * If component is a ContentDigest, return the digest value as a Uint8Array subarray (don't modify!).
- * If not a ContentDigest, return null.
- * A ContentDigest component is Name.ContentDigestPrefix + 32 bytes + Name.ContentDigestSuffix.
- */
-Name.getComponentContentDigestValue = function(component) {
-    var digestComponentLength = Name.ContentDigestPrefix.length + 32 + Name.ContentDigestSuffix.length; 
-    // Check for the correct length and equal ContentDigestPrefix and ContentDigestSuffix.
-    if (component.length == digestComponentLength &&
-        DataUtils.arraysEqual(component.subarray(0, Name.ContentDigestPrefix.length), 
-                              Name.ContentDigestPrefix) &&
-        DataUtils.arraysEqual(component.subarray
-           (component.length - Name.ContentDigestSuffix.length, component.length),
-                              Name.ContentDigestSuffix))
-       return component.subarray(Name.ContentDigestPrefix.length, Name.ContentDigestPrefix.length + 32);
-   else
-       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.
- */
-Name.toEscapedString = function(component) {
-    var result = "";
-    var gotNonDot = false;
-    for (var i = 0; i < component.length; ++i) {
-        if (component[i] != 0x2e) {
-            gotNonDot = true;
-            break;
-        }
-    }
-    if (!gotNonDot) {
-        // Special case for component of zero or more periods.  Add 3 periods.
-        result = "...";
-        for (var i = 0; i < component.length; ++i)
-            result += ".";
-    }
-    else {
-        for (var i = 0; i < component.length; ++i) {
-            var value = component[i];
-            // Check for 0-9, A-Z, a-z, (+), (-), (.), (_)
-            if (value >= 0x30 && value <= 0x39 || value >= 0x41 && value <= 0x5a ||
-                value >= 0x61 && value <= 0x7a || value == 0x2b || value == 0x2d || 
-                value == 0x2e || value == 0x5f)
-                result += String.fromCharCode(value);
-            else
-                result += "%" + (value < 16 ? "0" : "") + value.toString(16).toUpperCase();
-        }
-    }
-    return result;
-};
-
-/*
- * Return component as a Uint8Array by decoding the escapedString according to "CCNx URI Scheme".
- * If escapedString is "", "." or ".." then return null, which means to skip the component in the name.
- */
-Name.fromEscapedString = function(escapedString) {
-    var component = unescape(escapedString.trim());
-        
-    if (component.match(/[^.]/) == null) {
-        // Special case for component of only periods.  
-        if (component.length <= 2)
-            // Zero, one or two periods is illegal.  Ignore this componenent to be
-            //   consistent with the C implementation.
-            return null;
-        else
-            // Remove 3 periods.
-            return DataUtils.toNumbersFromString(component.substr(3, component.length - 3));
-    }
-    else
-        return DataUtils.toNumbersFromString(component);
-}
-
-Name.prototype.match = function(/*Name*/ name) {
-	var i_name = this.components;
-	var o_name = name.components;
-
-	// The intrest name is longer than the name we are checking it against.
-	if (i_name.length > o_name.length)
-            return false;
-
-	// Check if at least one of given components doesn't match.
-    for (var i = 0; i < i_name.length; ++i) {
-        if (!DataUtils.arraysEqual(i_name[i], o_name[i]))
-            return false;
-    }
-
-	return true;
-};
-/**
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- * This class represents ContentObject Objects
- */
-var ContentObject = function ContentObject(_name,_signedInfo,_content,_signature){
-	
-	
-	if (typeof _name == 'string') {
-		this.name = new Name(_name);
-	}
-	else{
-		//TODO Check the class of _name
-		this.name = _name;
-	}
-	this.signedInfo = _signedInfo;
-	
-	if (typeof _content == 'string') {
-		this.content = DataUtils.toNumbersFromString(_content);
-	} else {
-		this.content = _content;
-	}
-	
-	this.signature = _signature;
-
-	
-	this.startSIG = null;
-	this.endSIG = null;
-	
-	//this.startSignedInfo = null;
-	this.endContent = null;
-	
-	this.rawSignatureData = null;
-};
-
-ContentObject.prototype.sign = function(){
-
-	var n1 = this.encodeObject(this.name);
-	var n2 = this.encodeObject(this.signedInfo);
-	var n3 = this.encodeContent();
-	/*console.log('sign: ');
-	console.log(n1);
-	console.log(n2);
-	console.log(n3);*/
-	
-	//var n = n1.concat(n2,n3);
-	var tempBuf = new ArrayBuffer(n1.length + n2.length + n3.length);
-	var n = new Uint8Array(tempBuf);
-	//console.log(n);
-	n.set(n1, 0);
-	//console.log(n);
-	n.set(n2, n1.length);
-	//console.log(n);
-	n.set(n3, n1.length + n2.length);
-	//console.log(n);
-	
-	if(LOG>4)console.log('Signature Data is (binary) '+n);
-	
-	if(LOG>4)console.log('Signature Data is (RawString)');
-	
-	if(LOG>4)console.log( DataUtils.toString(n) );
-	
-	//var sig = DataUtils.toString(n);
-
-	
-	var rsa = new RSAKey();
-			
-	rsa.readPrivateKeyFromPEMString(globalKeyManager.privateKey);
-	
-	//var hSig = rsa.signString(sig, "sha256");
-
-	var hSig = rsa.signByteArrayWithSHA256(n);
-
-	
-	if(LOG>4)console.log('SIGNATURE SAVED IS');
-	
-	if(LOG>4)console.log(hSig);
-	
-	if(LOG>4)console.log(  DataUtils.toNumbers(hSig.trim()));
-
-	this.signature.signature = DataUtils.toNumbers(hSig.trim());
-	
-
-};
-
-ContentObject.prototype.encodeObject = function encodeObject(obj){
-	var enc = new BinaryXMLEncoder();
- 
-	obj.to_ccnb(enc);
-	
-	var num = enc.getReducedOstream();
-
-	return num;
-
-	
-};
-
-ContentObject.prototype.encodeContent = function encodeContent(obj){
-	var enc = new BinaryXMLEncoder();
-	 
-	enc.writeElement(CCNProtocolDTags.Content, this.content);
-
-	var num = enc.getReducedOstream();
-
-	return num;
-
-	
-};
-
-ContentObject.prototype.saveRawData = function(bytes){
-	
-	var sigBits = bytes.subarray(this.startSIG, this.endSIG);
-
-	this.rawSignatureData = sigBits;
-};
-
-ContentObject.prototype.from_ccnb = function(/*XMLDecoder*/ decoder) {
-
-	// TODO VALIDATE THAT ALL FIELDS EXCEPT SIGNATURE ARE PRESENT
-
-		decoder.readStartElement(this.getElementLabel());
-
-
-		if( decoder.peekStartElement(CCNProtocolDTags.Signature) ){
-			this.signature = new Signature();
-			this.signature.from_ccnb(decoder);
-		}
-		
-		//this.endSIG = decoder.offset;
-
-		this.startSIG = decoder.offset;
-
-		this.name = new Name();
-		this.name.from_ccnb(decoder);
-		
-		//this.startSignedInfo = decoder.offset;
-	
-		
-		if( decoder.peekStartElement(CCNProtocolDTags.SignedInfo) ){
-			this.signedInfo = new SignedInfo();
-			this.signedInfo.from_ccnb(decoder);
-		}
-
-        this.content = decoder.readBinaryElement(CCNProtocolDTags.Content, null, true);
-		
-		this.endSIG = decoder.offset;
-		
-		decoder.readEndElement();
-		
-		this.saveRawData(decoder.istream);
-};
-
-ContentObject.prototype.to_ccnb = function(/*XMLEncoder*/ encoder)  {
-
-	//TODO verify name, SignedInfo and Signature is present
-
-
-	encoder.writeStartElement(this.getElementLabel());
-
-	
-
-
-	if(null!=this.signature) this.signature.to_ccnb(encoder);
-	
-	
-	this.startSIG = encoder.offset;
-	
-
-	if(null!=this.name) this.name.to_ccnb(encoder);
-	
-	//this.endSIG = encoder.offset;
-	//this.startSignedInfo = encoder.offset;
-	
-	
-	if(null!=this.signedInfo) this.signedInfo.to_ccnb(encoder);
-
-	encoder.writeElement(CCNProtocolDTags.Content, this.content);
-
-	
-	this.endSIG = encoder.offset;
-	
-	//this.endContent = encoder.offset;
-	
-
-	encoder.writeEndElement();
-	
-	this.saveRawData(encoder.ostream);
-	
-};
-
-ContentObject.prototype.getElementLabel= function(){return CCNProtocolDTags.ContentObject;};
-
-/**
- * Signature
- */
-var Signature = function Signature(_witness,_signature,_digestAlgorithm) {
-	
-    this.Witness = _witness;//byte [] _witness;
-	this.signature = _signature;//byte [] _signature;
-	this.digestAlgorithm = _digestAlgorithm//String _digestAlgorithm;
-};
-
-Signature.prototype.from_ccnb =function( decoder) {
-		decoder.readStartElement(this.getElementLabel());
-		
-		if(LOG>4)console.log('STARTED DECODING SIGNATURE');
-		
-		if (decoder.peekStartElement(CCNProtocolDTags.DigestAlgorithm)) {
-			if(LOG>4)console.log('DIGIEST ALGORITHM FOUND');
-			this.digestAlgorithm = decoder.readUTF8Element(CCNProtocolDTags.DigestAlgorithm); 
-		}
-		if (decoder.peekStartElement(CCNProtocolDTags.Witness)) {
-			if(LOG>4)console.log('WITNESS FOUND');
-			this.Witness = decoder.readBinaryElement(CCNProtocolDTags.Witness); 
-		}
-		
-		//FORCE TO READ A SIGNATURE
-
-			if(LOG>4)console.log('SIGNATURE FOUND');
-			this.signature = decoder.readBinaryElement(CCNProtocolDTags.SignatureBits);
-
-		decoder.readEndElement();
-	
-};
-
-
-Signature.prototype.to_ccnb= function( encoder){
-    	
-	if (!this.validate()) {
-		throw new Error("Cannot encode: field values missing.");
-	}
-	
-	encoder.writeStartElement(this.getElementLabel());
-	
-	if ((null != this.digestAlgorithm) && (!this.digestAlgorithm.equals(CCNDigestHelper.DEFAULT_DIGEST_ALGORITHM))) {
-		encoder.writeElement(CCNProtocolDTags.DigestAlgorithm, OIDLookup.getDigestOID(this.DigestAlgorithm));
-	}
-	
-	if (null != this.Witness) {
-		// needs to handle null witness
-		encoder.writeElement(CCNProtocolDTags.Witness, this.Witness);
-	}
-
-	encoder.writeElement(CCNProtocolDTags.SignatureBits, this.signature);
-
-	encoder.writeEndElement();   		
-};
-
-Signature.prototype.getElementLabel = function() { return CCNProtocolDTags.Signature; };
-
-
-Signature.prototype.validate = function() {
-		return null != this.signature;
-};
-
-
-/**
- * SignedInfo
- */
-var ContentType = {DATA:0, ENCR:1, GONE:2, KEY:3, LINK:4, NACK:5};
-var ContentTypeValue = {0:0x0C04C0, 1:0x10D091,2:0x18E344,3:0x28463F,4:0x2C834A,5:0x34008A};
-var ContentTypeValueReverse = {0x0C04C0:0, 0x10D091:1,0x18E344:2,0x28463F:3,0x2C834A:4,0x34008A:5};
-
-var SignedInfo = function SignedInfo(_publisher,_timestamp,_type,_locator,_freshnessSeconds,_finalBlockID){
-
-	//TODO, Check types
-
-    this.publisher = _publisher; //publisherPublicKeyDigest
-    this.timestamp=_timestamp; // CCN Time
-    this.type=_type; // ContentType
-    this.locator =_locator;//KeyLocator
-    this.freshnessSeconds =_freshnessSeconds; // Integer
-    this.finalBlockID=_finalBlockID; //byte array
-    
-    // SWT: merge setFields() method into constructor
-    this.setFields();
-
-};
-
-SignedInfo.prototype.setFields = function(){
-	//BASE64 -> RAW STRING
-	
-	//this.locator = new KeyLocator(  DataUtils.toNumbersFromString(stringCertificate)  ,KeyLocatorType.CERTIFICATE );
-	
-	var publicKeyHex = globalKeyManager.publicKey;
-
-	if(LOG>4)console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
-	if(LOG>4)console.log(publicKeyHex);
-	
-	var publicKeyBytes = DataUtils.toNumbers(globalKeyManager.publicKey) ; 
-
-	
-
-	//var stringCertificate = DataUtils.base64toString(globalKeyManager.certificate);
-	
-	//if(LOG>3)console.log('string Certificate is '+stringCertificate);
-
-	//HEX -> BYTE ARRAY
-	//var publisherkey = DataUtils.toNumbers(hex_sha256(stringCertificate));
-	
-	//if(LOG>3)console.log('publisher key is ');
-	//if(LOG>3)console.log(publisherkey);
-	
-	var publisherKeyDigest = hex_sha256_from_bytes(publicKeyBytes);
-
-	this.publisher = new PublisherPublicKeyDigest(  DataUtils.toNumbers(  publisherKeyDigest )  );
-	
-	//this.publisher = new PublisherPublicKeyDigest(publisherkey);
-
-	var d = new Date();
-	
-	var time = d.getTime();
-	
-
-    this.timestamp = new CCNTime( time );
-    
-    if(LOG>4)console.log('TIME msec is');
-
-    if(LOG>4)console.log(this.timestamp.msec);
-
-    //DATA
-	this.type = 0;//0x0C04C0;//ContentTypeValue[ContentType.DATA];
-	
-	//if(LOG>4)console.log('toNumbersFromString(stringCertificate) '+DataUtils.toNumbersFromString(stringCertificate));
-	
-	if(LOG>4)console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
-	if(LOG>4)console.log(publicKeyBytes);
-
-	this.locator = new KeyLocator(  publicKeyBytes  ,KeyLocatorType.KEY );
-
-	//this.locator = new KeyLocator(  DataUtils.toNumbersFromString(stringCertificate)  ,KeyLocatorType.CERTIFICATE );
-
-};
-
-SignedInfo.prototype.from_ccnb = function( decoder){
-
-		decoder.readStartElement( this.getElementLabel() );
-		
-		if (decoder.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)) {
-			if(LOG>4)console.log('DECODING PUBLISHER KEY');
-			this.publisher = new PublisherPublicKeyDigest();
-			this.publisher.from_ccnb(decoder);
-		}
-
-		if (decoder.peekStartElement(CCNProtocolDTags.Timestamp)) {
-			if(LOG>4)console.log('DECODING TIMESTAMP');
-			this.timestamp = decoder.readDateTime(CCNProtocolDTags.Timestamp);
-		}
-
-		if (decoder.peekStartElement(CCNProtocolDTags.Type)) {
-			var binType = decoder.readBinaryElement(CCNProtocolDTags.Type);//byte [] 
-		
-			
-			//TODO Implement type of Key Reading
-			
-			if(LOG>4)console.log('Binary Type of of Signed Info is '+binType);
-
-			this.type = binType;
-			
-			
-			//TODO Implement type of Key Reading
-			
-			
-			if (null == this.type) {
-				throw new Error("Cannot parse signedInfo type: bytes.");
-			}
-			
-		} else {
-			this.type = ContentType.DATA; // default
-		}
-		
-		if (decoder.peekStartElement(CCNProtocolDTags.FreshnessSeconds)) {
-			this.freshnessSeconds = decoder.readIntegerElement(CCNProtocolDTags.FreshnessSeconds);
-			if(LOG>4)console.log('FRESHNESS IN SECONDS IS '+ this.freshnessSeconds);
-		}
-		
-		if (decoder.peekStartElement(CCNProtocolDTags.FinalBlockID)) {
-			if(LOG>4)console.log('DECODING FINAL BLOCKID');
-			this.finalBlockID = decoder.readBinaryElement(CCNProtocolDTags.FinalBlockID);
-		}
-		
-		if (decoder.peekStartElement(CCNProtocolDTags.KeyLocator)) {
-			if(LOG>4)console.log('DECODING KEY LOCATOR');
-			this.locator = new KeyLocator();
-			this.locator.from_ccnb(decoder);
-		}
-				
-		decoder.readEndElement();
-};
-
-SignedInfo.prototype.to_ccnb = function( encoder)  {
-		if (!this.validate()) {
-			throw new Error("Cannot encode : field values missing.");
-		}
-		encoder.writeStartElement(this.getElementLabel());
-		
-		if (null!=this.publisher) {
-			if(LOG>3) console.log('ENCODING PUBLISHER KEY' + this.publisher.publisherPublicKeyDigest);
-
-			this.publisher.to_ccnb(encoder);
-		}
-
-		if (null!=this.timestamp) {
-			encoder.writeDateTime(CCNProtocolDTags.Timestamp, this.timestamp );
-		}
-		
-		if (null!=this.type && this.type !=0) {
-			
-			encoder.writeElement(CCNProtocolDTags.type, this.type);
-		}
-		
-		if (null!=this.freshnessSeconds) {
-			encoder.writeElement(CCNProtocolDTags.FreshnessSeconds, this.freshnessSeconds);
-		}
-
-		if (null!=this.finalBlockID) {
-			encoder.writeElement(CCNProtocolDTags.FinalBlockID, this.finalBlockID);
-		}
-
-		if (null!=this.locator) {
-			this.locator.to_ccnb(encoder);
-		}
-
-		encoder.writeEndElement();   		
-};
-	
-SignedInfo.prototype.valueToType = function(){
-	//for (Entry<byte [], ContentType> entry : ContentValueTypes.entrySet()) {
-		//if (Arrays.equals(value, entry.getKey()))
-			//return entry.getValue();
-		//}
-	return null;
-	
-};
-
-SignedInfo.prototype.getElementLabel = function() { 
-	return CCNProtocolDTags.SignedInfo;
-};
-
-SignedInfo.prototype.validate = function() {
-		// We don't do partial matches any more, even though encoder/decoder
-		// is still pretty generous.
-		if (null ==this.publisher || null==this.timestamp ||null== this.locator)
-			return false;
-		return true;
-};
-/*
- * Date Format 1.2.3
- * (c) 2007-2009 Steven Levithan <stevenlevithan.com>
- * MIT license
- *
- * Includes enhancements by Scott Trenda <scott.trenda.net>
- * and Kris Kowal <cixar.com/~kris.kowal/>
- *
- * Accepts a date, a mask, or a date and a mask.
- * Returns a formatted version of the given date.
- * The date defaults to the current date/time.
- * The mask defaults to dateFormat.masks.default.
- */
-
-var DateFormat = function () {
-	var	token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
-		timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
-		timezoneClip = /[^-+\dA-Z]/g,
-		pad = function (val, len) {
-			val = String(val);
-			len = len || 2;
-			while (val.length < len) val = "0" + val;
-			return val;
-		};
-
-	// Regexes and supporting functions are cached through closure
-	return function (date, mask, utc) {
-		var dF = dateFormat;
-
-		// You can't provide utc if you skip other args (use the "UTC:" mask prefix)
-		if (arguments.length == 1 && Object.prototype.toString.call(date) == "[object String]" && !/\d/.test(date)) {
-			mask = date;
-			date = undefined;
-		}
-
-		// Passing date through Date applies Date.parse, if necessary
-		date = date ? new Date(date) : new Date;
-		if (isNaN(date)) throw SyntaxError("invalid date");
-
-		mask = String(dF.masks[mask] || mask || dF.masks["default"]);
-
-		// Allow setting the utc argument via the mask
-		if (mask.slice(0, 4) == "UTC:") {
-			mask = mask.slice(4);
-			utc = true;
-		}
-
-		var	_ = utc ? "getUTC" : "get",
-			d = date[_ + "Date"](),
-			D = date[_ + "Day"](),
-			m = date[_ + "Month"](),
-			y = date[_ + "FullYear"](),
-			H = date[_ + "Hours"](),
-			M = date[_ + "Minutes"](),
-			s = date[_ + "Seconds"](),
-			L = date[_ + "Milliseconds"](),
-			o = utc ? 0 : date.getTimezoneOffset(),
-			flags = {
-				d:    d,
-				dd:   pad(d),
-				ddd:  dF.i18n.dayNames[D],
-				dddd: dF.i18n.dayNames[D + 7],
-				m:    m + 1,
-				mm:   pad(m + 1),
-				mmm:  dF.i18n.monthNames[m],
-				mmmm: dF.i18n.monthNames[m + 12],
-				yy:   String(y).slice(2),
-				yyyy: y,
-				h:    H % 12 || 12,
-				hh:   pad(H % 12 || 12),
-				H:    H,
-				HH:   pad(H),
-				M:    M,
-				MM:   pad(M),
-				s:    s,
-				ss:   pad(s),
-				l:    pad(L, 3),
-				L:    pad(L > 99 ? Math.round(L / 10) : L),
-				t:    H < 12 ? "a"  : "p",
-				tt:   H < 12 ? "am" : "pm",
-				T:    H < 12 ? "A"  : "P",
-				TT:   H < 12 ? "AM" : "PM",
-				Z:    utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
-				o:    (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
-				S:    ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
-			};
-
-		return mask.replace(token, function ($0) {
-			return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
-		});
-	};
-}();
-
-// Some common format strings
-DateFormat.masks = {
-	"default":      "ddd mmm dd yyyy HH:MM:ss",
-	shortDate:      "m/d/yy",
-	mediumDate:     "mmm d, yyyy",
-	longDate:       "mmmm d, yyyy",
-	fullDate:       "dddd, mmmm d, yyyy",
-	shortTime:      "h:MM TT",
-	mediumTime:     "h:MM:ss TT",
-	longTime:       "h:MM:ss TT Z",
-	isoDate:        "yyyy-mm-dd",
-	isoTime:        "HH:MM:ss",
-	isoDateTime:    "yyyy-mm-dd'T'HH:MM:ss",
-	isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
-};
-
-// Internationalization strings
-DateFormat.i18n = {
-	dayNames: [
-		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
-		"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
-	],
-	monthNames: [
-		"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
-		"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
-	]
-};
-
-// For convenience...
-Date.prototype.format = function (mask, utc) {
-	return dateFormat(this, mask, utc);
-};
-/**
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- * This class represents Interest Objects
- */
-
-// _interestLifetime is in milliseconds.
-var Interest = function Interest
-   (_name, _faceInstance, _minSuffixComponents, _maxSuffixComponents, _publisherPublicKeyDigest, _exclude, 
-    _childSelector, _answerOriginKind, _scope, _interestLifetime, _nonce) {
-		
-	this.name = _name;
-	this.faceInstance = _faceInstance;
-	this.maxSuffixComponents = _maxSuffixComponents;
-	this.minSuffixComponents = _minSuffixComponents;
-	
-	this.publisherPublicKeyDigest = _publisherPublicKeyDigest;
-	this.exclude = _exclude;
-	this.childSelector = _childSelector;
-	this.answerOriginKind = _answerOriginKind;
-	this.scope = _scope;
-	this.interestLifetime = _interestLifetime;  // milli seconds
-	this.nonce = _nonce;	
-};
-
-Interest.RECURSIVE_POSTFIX = "*";
-
-Interest.CHILD_SELECTOR_LEFT = 0;
-Interest.CHILD_SELECTOR_RIGHT = 1;
-Interest.ANSWER_CONTENT_STORE = 1;
-Interest.ANSWER_GENERATED = 2;
-Interest.ANSWER_STALE = 4;		// Stale answer OK
-Interest.MARK_STALE = 16;		// Must have scope 0.  Michael calls this a "hack"
-
-Interest.DEFAULT_ANSWER_ORIGIN_KIND = Interest.ANSWER_CONTENT_STORE | Interest.ANSWER_GENERATED;
-
-
-Interest.prototype.from_ccnb = function(/*XMLDecoder*/ decoder) {
-
-		decoder.readStartElement(CCNProtocolDTags.Interest);
-
-		this.name = new Name();
-		this.name.from_ccnb(decoder);
-
-		if (decoder.peekStartElement(CCNProtocolDTags.MinSuffixComponents))
-			this.minSuffixComponents = decoder.readIntegerElement(CCNProtocolDTags.MinSuffixComponents);
-
-		if (decoder.peekStartElement(CCNProtocolDTags.MaxSuffixComponents)) 
-			this.maxSuffixComponents = decoder.readIntegerElement(CCNProtocolDTags.MaxSuffixComponents);
-			
-		if (decoder.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)) {
-			this.publisherPublicKeyDigest = new PublisherPublicKeyDigest();
-			this.publisherPublicKeyDigest.from_ccnb(decoder);
-		}
-
-		if (decoder.peekStartElement(CCNProtocolDTags.Exclude)) {
-			this.exclude = new Exclude();
-			this.exclude.from_ccnb(decoder);
-		}
-		
-		if (decoder.peekStartElement(CCNProtocolDTags.ChildSelector))
-			this.childSelector = decoder.readIntegerElement(CCNProtocolDTags.ChildSelector);
-		
-		if (decoder.peekStartElement(CCNProtocolDTags.AnswerOriginKind))
-			this.answerOriginKind = decoder.readIntegerElement(CCNProtocolDTags.AnswerOriginKind);
-		
-		if (decoder.peekStartElement(CCNProtocolDTags.Scope))
-			this.scope = decoder.readIntegerElement(CCNProtocolDTags.Scope);
-
-		if (decoder.peekStartElement(CCNProtocolDTags.InterestLifetime))
-			this.interestLifetime = 1000.0 * DataUtils.bigEndianToUnsignedInt
-                (decoder.readBinaryElement(CCNProtocolDTags.InterestLifetime)) / 4096;
-		
-		if (decoder.peekStartElement(CCNProtocolDTags.Nonce))
-			this.nonce = decoder.readBinaryElement(CCNProtocolDTags.Nonce);
-		
-		decoder.readEndElement();
-};
-
-Interest.prototype.to_ccnb = function(/*XMLEncoder*/ encoder){
-		//Could check if name is present
-		
-		encoder.writeStartElement(CCNProtocolDTags.Interest);
-		
-		this.name.to_ccnb(encoder);
-	
-		if (null != this.minSuffixComponents) 
-			encoder.writeElement(CCNProtocolDTags.MinSuffixComponents, this.minSuffixComponents);	
-
-		if (null != this.maxSuffixComponents) 
-			encoder.writeElement(CCNProtocolDTags.MaxSuffixComponents, this.maxSuffixComponents);
-
-		if (null != this.publisherPublicKeyDigest)
-			this.publisherPublicKeyDigest.to_ccnb(encoder);
-		
-		if (null != this.exclude)
-			this.exclude.to_ccnb(encoder);
-		
-		if (null != this.childSelector) 
-			encoder.writeElement(CCNProtocolDTags.ChildSelector, this.childSelector);
-
-		if (this.DEFAULT_ANSWER_ORIGIN_KIND != this.answerOriginKind && this.answerOriginKind!=null) 
-			encoder.writeElement(CCNProtocolDTags.AnswerOriginKind, this.answerOriginKind);
-		
-		if (null != this.scope) 
-			encoder.writeElement(CCNProtocolDTags.Scope, this.scope);
-		
-		if (null != this.interestLifetime) 
-			encoder.writeElement(CCNProtocolDTags.InterestLifetime, 
-                DataUtils.nonNegativeIntToBigEndian((this.interestLifetime / 1000.0) * 4096));
-		
-		if (null != this.nonce)
-			encoder.writeElement(CCNProtocolDTags.Nonce, this.nonce);
-		
-		encoder.writeEndElement();
-
-};
-
-/*
- * Return true if this.name.match(name) and the name conforms to the interest selectors.
- */
-Interest.prototype.matches_name = function(/*Name*/ name) {
-    if (!this.name.match(name))
-        return false;
-    
-    if (this.minSuffixComponents != null &&
-        // Add 1 for the implicit digest.
-        !(name.components.length + 1 - this.name.components.length >= this.minSuffixComponents))
-        return false;
-    if (this.maxSuffixComponents != null &&
-        // Add 1 for the implicit digest.
-        !(name.components.length + 1 - this.name.components.length <= this.maxSuffixComponents))
-        return false;
-    if (this.exclude != null && name.components.length > this.name.components.length &&
-        this.exclude.matches(name.components[this.name.components.length]))
-        return false;
-    
-    return true;
-};
-
-/*
- * Return a new Interest with the same fields as this Interest.  
- * Note: This does NOT make a deep clone of the name, exclue or other objects.
- */
-Interest.prototype.clone = function() {
-    return new Interest
-       (this.name, this.faceInstance, this.minSuffixComponents, this.maxSuffixComponents, 
-        this.publisherPublicKeyDigest, this.exclude, this.childSelector, this.answerOriginKind, 
-        this.scope, this.interestLifetime, this.nonce);
-};
-
-/*
- * Handle the interest Exclude element.
- * _values is an array where each element is either Uint8Array component or Exclude.ANY.
- */
-var Exclude = function Exclude(_values) { 
-	this.values = (_values || []);
-}
-
-Exclude.ANY = "*";
-
-Exclude.prototype.from_ccnb = function(/*XMLDecoder*/ decoder) {
-	decoder.readStartElement(CCNProtocolDTags.Exclude);
-
-	while (true) {
-        if (decoder.peekStartElement(CCNProtocolDTags.Component))
-            this.values.push(decoder.readBinaryElement(CCNProtocolDTags.Component));
-        else if (decoder.peekStartElement(CCNProtocolDTags.Any)) {
-            decoder.readStartElement(CCNProtocolDTags.Any);
-            decoder.readEndElement();
-            this.values.push(Exclude.ANY);
-        }
-        else if (decoder.peekStartElement(CCNProtocolDTags.Bloom)) {
-            // Skip the Bloom and treat it as Any.
-            decoder.readBinaryElement(CCNProtocolDTags.Bloom);
-            this.values.push(Exclude.ANY);
-        }
-        else
-            break;
-	}
-    
-    decoder.readEndElement();
-};
-
-Exclude.prototype.to_ccnb = function(/*XMLEncoder*/ encoder)  {
-	if (this.values == null || this.values.length == 0)
-		return;
-
-	encoder.writeStartElement(CCNProtocolDTags.Exclude);
-    
-    // TODO: Do we want to order the components (except for ANY)?
-    for (var i = 0; i < this.values.length; ++i) {
-        if (this.values[i] == Exclude.ANY) {
-            encoder.writeStartElement(CCNProtocolDTags.Any);
-            encoder.writeEndElement();
-        }
-        else
-            encoder.writeElement(CCNProtocolDTags.Component, this.values[i]);
-    }
-
-	encoder.writeEndElement();
-};
-
-/*
- * Return a string with elements separated by "," and Exclude.ANY shown as "*". 
- */
-Exclude.prototype.to_uri = function() {
-	if (this.values == null || this.values.length == 0)
-		return "";
-
-    var result = "";
-    for (var i = 0; i < this.values.length; ++i) {
-        if (i > 0)
-            result += ",";
-        
-        if (this.values[i] == Exclude.ANY)
-            result += "*";
-        else
-            result += Name.toEscapedString(this.values[i]);
-    }
-    return result;
-};
-
-/*
- * Return true if the component matches any of the exclude criteria.
- */
-Exclude.prototype.matches = function(/*Uint8Array*/ component) {
-    for (var i = 0; i < this.values.length; ++i) {
-        if (this.values[i] == Exclude.ANY) {
-            var lowerBound = null;
-            if (i > 0)
-                lowerBound = this.values[i - 1];
-            
-            // Find the upper bound, possibly skipping over multiple ANY in a row.
-            var iUpperBound;
-            var upperBound = null;
-            for (iUpperBound = i + 1; iUpperBound < this.values.length; ++iUpperBound) {
-                if (this.values[iUpperBound] != Exclude.ANY) {
-                    upperBound = this.values[iUpperBound];
-                    break;
-                }
-            }
-            
-            // If lowerBound != null, we already checked component equals lowerBound on the last pass.
-            // If upperBound != null, we will check component equals upperBound on the next pass.
-            if (upperBound != null) {
-                if (lowerBound != null) {
-                    if (Exclude.compareComponents(component, lowerBound) > 0 &&
-                        Exclude.compareComponents(component, upperBound) < 0)
-                        return true;
-                }
-                else {
-                    if (Exclude.compareComponents(component, upperBound) < 0)
-                        return true;
-                }
-                
-                // Make i equal iUpperBound on the next pass.
-                i = iUpperBound - 1;
-            }
-            else {
-                if (lowerBound != null) {
-                    if (Exclude.compareComponents(component, lowerBound) > 0)
-                        return true;
-                }
-                else
-                    // this.values has only ANY.
-                    return true;
-            }
-        }
-        else {
-            if (DataUtils.arraysEqual(component, this.values[i]))
-                return true;
-        }
-    }
-    
-    return false;
-};
-
-/*
- * Return -1 if component1 is less than component2, 1 if greater or 0 if equal.
- * A component is less if it is shorter, otherwise if equal length do a byte comparison.
- */
-Exclude.compareComponents = function(/*Uint8Array*/ component1, /*Uint8Array*/ component2) {
-    if (component1.length < component2.length)
-        return -1;
-    if (component1.length > component2.length)
-        return 1;
-    
-    for (var i = 0; i < component1.length; ++i) {
-        if (component1[i] < component2[i])
-            return -1;
-        if (component1[i] > component2[i])
-            return 1;
-    }
-
-    return 0;
-};
-/**
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- * This class represents Key Objects
- */
-
-var Key = function Key(){
-    /* TODO: Port from PyCCN:
-	generateRSA()
-	privateToDER()
-	publicToDER()
-	privateToPEM()
-	publicToPEM()
-	fromDER()
-	fromPEM()
-     */
-}
-
-/**
- * KeyLocator
- */
-var KeyLocatorType = {
-	KEY:1,
-	CERTIFICATE:2,
-	KEYNAME:3
-};
-
-var KeyLocator = function KeyLocator(_input,_type){ 
-
-    this.type = _type;
-    
-    if (_type == KeyLocatorType.KEYNAME){
-    	if (LOG>3) console.log('KeyLocator: SET KEYNAME');
-    	this.keyName = _input;
-    }
-    else if (_type == KeyLocatorType.KEY){
-    	if (LOG>3) console.log('KeyLocator: SET KEY');
-    	this.publicKey = _input;
-    }
-    else if (_type == KeyLocatorType.CERTIFICATE){
-    	if (LOG>3) console.log('KeyLocator: SET CERTIFICATE');
-    	this.certificate = _input;
-    }
-
-};
-
-KeyLocator.prototype.from_ccnb = function(decoder) {
-
-	decoder.readStartElement(this.getElementLabel());
-
-	if (decoder.peekStartElement(CCNProtocolDTags.Key)) {
-		try {
-			var encodedKey = decoder.readBinaryElement(CCNProtocolDTags.Key);
-			// This is a DER-encoded SubjectPublicKeyInfo.
-			
-			//TODO FIX THIS, This should create a Key Object instead of keeping bytes
-
-			this.publicKey =   encodedKey;//CryptoUtil.getPublicKey(encodedKey);
-			this.type = KeyLocatorType.KEY;
-			
-
-			if(LOG>4) console.log('PUBLIC KEY FOUND: '+ this.publicKey);
-			//this.publicKey = encodedKey;
-			
-			
-		} catch (e) {
-			throw new Error("Cannot parse key: ", e);
-		} 
-
-		if (null == this.publicKey) {
-			throw new Error("Cannot parse key: ");
-		}
-
-	} else if ( decoder.peekStartElement(CCNProtocolDTags.Certificate)) {
-		try {
-			var encodedCert = decoder.readBinaryElement(CCNProtocolDTags.Certificate);
-			
-			/*
-			 * Certificates not yet working
-			 */
-			
-			//CertificateFactory factory = CertificateFactory.getInstance("X.509");
-			//this.certificate = (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(encodedCert));
-			
-
-			this.certificate = encodedCert;
-			this.type = KeyLocatorType.CERTIFICATE;
-
-			if(LOG>4) console.log('CERTIFICATE FOUND: '+ this.certificate);
-			
-		} catch ( e) {
-			throw new Error("Cannot decode certificate: " +  e);
-		}
-		if (null == this.certificate) {
-			throw new Error("Cannot parse certificate! ");
-		}
-	} else  {
-		this.type = KeyLocatorType.KEYNAME;
-		
-		this.keyName = new KeyName();
-		this.keyName.from_ccnb(decoder);
-	}
-	decoder.readEndElement();
-};
-	
-
-KeyLocator.prototype.to_ccnb = function( encoder) {
-	
-	if(LOG>4) console.log('type is is ' + this.type);
-	//TODO Check if Name is missing
-	if (!this.validate()) {
-		throw new ContentEncodingException("Cannot encode " + this.getClass().getName() + ": field values missing.");
-	}
-
-	
-	//TODO FIX THIS TOO
-	encoder.writeStartElement(this.getElementLabel());
-	
-	if (this.type == KeyLocatorType.KEY) {
-		if(LOG>5)console.log('About to encode a public key' +this.publicKey);
-		encoder.writeElement(CCNProtocolDTags.Key, this.publicKey);
-		
-	} else if (this.type == KeyLocatorType.CERTIFICATE) {
-		
-		try {
-			encoder.writeElement(CCNProtocolDTags.Certificate, this.certificate);
-		} catch ( e) {
-			throw new Error("CertificateEncodingException attempting to write key locator: " + e);
-		}
-		
-	} else if (this.type == KeyLocatorType.KEYNAME) {
-		
-		this.keyName.to_ccnb(encoder);
-	}
-	encoder.writeEndElement();
-	
-};
-
-KeyLocator.prototype.getElementLabel = function() {
-	return CCNProtocolDTags.KeyLocator; 
-};
-
-KeyLocator.prototype.validate = function() {
-	return (  (null != this.keyName) || (null != this.publicKey) || (null != this.certificate)   );
-};
-
-/**
- * KeyName is only used by KeyLocator.
- */
-var KeyName = function KeyName() {
-	this.contentName = this.contentName;  //contentName
-	this.publisherID = this.publisherID;  //publisherID
-
-};
-
-KeyName.prototype.from_ccnb=function( decoder){
-	
-
-	decoder.readStartElement(this.getElementLabel());
-
-	this.contentName = new Name();
-	this.contentName.from_ccnb(decoder);
-	
-	if(LOG>4) console.log('KEY NAME FOUND: ');
-	
-	if ( PublisherID.peek(decoder) ) {
-		this.publisherID = new PublisherID();
-		this.publisherID.from_ccnb(decoder);
-	}
-	
-	decoder.readEndElement();
-};
-
-KeyName.prototype.to_ccnb = function( encoder) {
-	if (!this.validate()) {
-		throw new Error("Cannot encode : field values missing.");
-	}
-	
-	encoder.writeStartElement(this.getElementLabel());
-	
-	this.contentName.to_ccnb(encoder);
-	if (null != this.publisherID)
-		this.publisherID.to_ccnb(encoder);
-
-	encoder.writeEndElement();   		
-};
-	
-KeyName.prototype.getElementLabel = function() { return CCNProtocolDTags.KeyName; };
-
-KeyName.prototype.validate = function() {
-		// DKS -- do we do recursive validation?
-		// null signedInfo ok
-		return (null != this.contentName);
-};
-
-/**
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- * This class represents Publisher and PublisherType Objects
- */
-
-
-var PublisherType = function PublisherType(_tag){
-    	this.KEY =(CCNProtocolDTags.PublisherPublicKeyDigest);
-    	this.CERTIFICATE= (CCNProtocolDTags.PublisherCertificateDigest);
-    	this.ISSUER_KEY=	(CCNProtocolDTags.PublisherIssuerKeyDigest);
-    	this.ISSUER_CERTIFICATE	=(CCNProtocolDTags.PublisherIssuerCertificateDigest);
-
-    	this.Tag = _tag;
-}; 
-
-var isTypeTagVal = function(tagVal) {
-		if ((tagVal == CCNProtocolDTags.PublisherPublicKeyDigest) ||
-			(tagVal == CCNProtocolDTags.PublisherCertificateDigest) ||
-			(tagVal == CCNProtocolDTags.PublisherIssuerKeyDigest) ||
-			(tagVal == CCNProtocolDTags.PublisherIssuerCertificateDigest)) {
-			return true;
-		}
-		return false;
-};
-
-
-
-
-var PublisherID = function PublisherID() {
-
-	this.PUBLISHER_ID_DIGEST_ALGORITHM = "SHA-256";
-	this.PUBLISHER_ID_LEN = 256/8;
-    
-	//TODO, implement publisherID creation and key creation
-
-    //TODO implement generatePublicKeyDigest
-    this.publisherID =null;//= generatePublicKeyDigest(key);//ByteArray
-    
-    //TODO implement generate key
-    //CryptoUtil.generateKeyID(PUBLISHER_ID_DIGEST_ALGORITHM, key);
-    this.publisherType = null;//isIssuer ? PublisherType.ISSUER_KEY : PublisherType.KEY;//publisher Type
-    
-};
-
-
-PublisherID.prototype.from_ccnb = function(decoder) {
-		
-		// We have a choice here of one of 4 binary element types.
-		var nextTag = decoder.peekStartElementAsLong();
-		
-		if (null == nextTag) {
-			throw new Error("Cannot parse publisher ID.");
-		} 
-		
-		this.publisherType = new PublisherType(nextTag); 
-		
-		if (!isTypeTagVal(nextTag)) {
-			throw new Error("Invalid publisher ID, got unexpected type: " + nextTag);
-		}
-		this.publisherID = decoder.readBinaryElement(nextTag);
-		if (null == this.publisherID) {
-			throw new ContentDecodingException(new Error("Cannot parse publisher ID of type : " + nextTag + "."));
-		}
-};
-
-PublisherID.prototype.to_ccnb = function(encoder) {
-	if (!this.validate()) {
-		throw new Error("Cannot encode " + this.getClass().getName() + ": field values missing.");
-	}
-
-	encoder.writeElement(this.getElementLabel(), this.publisherID);
-};
-	
-PublisherID.peek = function(/* XMLDecoder */ decoder) {
-
-		//Long
-		var nextTag = decoder.peekStartElementAsLong();
-		
-		if (null == nextTag) {
-			// on end element
-			return false;
-		}
-		return (isTypeTagVal(nextTag));
-	};
-
-PublisherID.prototype.getElementLabel = function() { 
-	return this.publisherType.Tag;
-};
-
-PublisherID.prototype.validate = function(){
-	return ((null != id() && (null != type())));
-};
-
-
-
-/**
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- * This class represents PublisherPublicKeyDigest Objects
- */
-var PublisherPublicKeyDigest = function PublisherPublicKeyDigest(_pkd){ 
-	
- 	 //this.PUBLISHER_ID_LEN = 256/8;
-	 this.PUBLISHER_ID_LEN = 512/8;
- 	 
-
-	 this.publisherPublicKeyDigest = _pkd;
- 	 //if( typeof _pkd == "object") this.publisherPublicKeyDigest = _pkd; // Byte Array
- 	 //else if( typeof _pkd == "PublicKey") ;//TODO...
-    
-};
-
-PublisherPublicKeyDigest.prototype.from_ccnb = function( decoder) {		
-
-		this.publisherPublicKeyDigest = decoder.readBinaryElement(this.getElementLabel());
-		
-		if(LOG>4)console.log('Publisher public key digest is ' + this.publisherPublicKeyDigest);
-
-		if (null == this.publisherPublicKeyDigest) {
-			throw new Error("Cannot parse publisher key digest.");
-		}
-		
-		//TODO check if the length of the PublisherPublicKeyDigest is correct ( Security reason)
-
-		if (this.publisherPublicKeyDigest.length != this.PUBLISHER_ID_LEN) {
-			if (LOG > 0)
-                console.log('LENGTH OF PUBLISHER ID IS WRONG! Expected ' + this.PUBLISHER_ID_LEN + ", got " + this.publisherPublicKeyDigest.length);
-			
-			//this.publisherPublicKeyDigest = new PublisherPublicKeyDigest(this.PublisherPublicKeyDigest).PublisherKeyDigest;		
-		}
-	};
-
-PublisherPublicKeyDigest.prototype.to_ccnb= function( encoder) {
-		//TODO Check that the ByteArray for the key is present
-		if (!this.validate()) {
-			throw new Error("Cannot encode : field values missing.");
-		}
-		if(LOG>3) console.log('PUBLISHER KEY DIGEST IS'+this.publisherPublicKeyDigest);
-		encoder.writeElement(this.getElementLabel(), this.publisherPublicKeyDigest);
-};
-	
-PublisherPublicKeyDigest.prototype.getElementLabel = function() { return CCNProtocolDTags.PublisherPublicKeyDigest; };
-
-PublisherPublicKeyDigest.prototype.validate =function() {
-		return (null != this.publisherPublicKeyDigest);
-};
-/**
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- * This class represents Face Instances
- */
-
-var NetworkProtocol = { TCP:6, UDP:17};
-
-var FaceInstance  = function FaceInstance(
-	    _action,
-		_publisherPublicKeyDigest,
-		_faceID,
-		_ipProto,
-		_host,
-		_port,
-		_multicastInterface,
-		_multicastTTL,
-		_freshnessSeconds){
-	
-
-	this.action = _action;
-	this.publisherPublicKeyDigest = _publisherPublicKeyDigest;
-	this.faceID = _faceID;
-	this.ipProto = _ipProto;
-	this.host = _host;
-	this.Port = _port;
-	this.multicastInterface =_multicastInterface;
-	this.multicastTTL =_multicastTTL;
-	this.freshnessSeconds = _freshnessSeconds;
-	
-	//action           ::= ("newface" | "destroyface" | "queryface")
-	//publisherPublicKeyDigest ::= SHA-256 digest
-	//faceID           ::= nonNegativeInteger
-	//ipProto          ::= nonNegativeInteger [IANA protocol number, 6=TCP, 17=UDP]
-	//Host             ::= textual representation of numeric IPv4 or IPv6 address
-	//Port             ::= nonNegativeInteger [1..65535]
-	//MulticastInterface ::= textual representation of numeric IPv4 or IPv6 address
-	//MulticastTTL     ::= nonNegativeInteger [1..255]
-	//freshnessSeconds ::= nonNegativeInteger
-
-};
-
-/**
- * Used by NetworkObject to decode the object from a network stream.
- */
-FaceInstance.prototype.from_ccnb = function(//XMLDecoder 
-	decoder) {
-
-	decoder.readStartElement(this.getElementLabel());
-	
-	if (decoder.peekStartElement(CCNProtocolDTags.Action)) {
-		
-		this.action = decoder.readUTF8Element(CCNProtocolDTags.Action);
-		
-	}
-	if (decoder.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)) {
-		
-		this.publisherPublicKeyDigest = new PublisherPublicKeyDigest();
-		this.publisherPublicKeyDigest.from_ccnb(decoder);
-		
-	}
-	if (decoder.peekStartElement(CCNProtocolDTags.FaceID)) {
-		
-		this.faceID = decoder.readIntegerElement(CCNProtocolDTags.FaceID);
-		
-	}
-	if (decoder.peekStartElement(CCNProtocolDTags.IPProto)) {
-		
-		//int
-		var pI = decoder.readIntegerElement(CCNProtocolDTags.IPProto);
-		
-		this.ipProto = null;
-		
-		if (NetworkProtocol.TCP == pI) {
-			
-			this.ipProto = NetworkProtocol.TCP;
-			
-		} else if (NetworkProtocol.UDP == pI) {
-			
-			this.ipProto = NetworkProtocol.UDP;
-			
-		} else {
-			
-			throw new Error("FaceInstance.decoder.  Invalid " + 
-					CCNProtocolDTags.tagToString(CCNProtocolDTags.IPProto) + " field: " + pI);
-			
-		}
-	}
-	
-	if (decoder.peekStartElement(CCNProtocolDTags.Host)) {
-		
-		this.host = decoder.readUTF8Element(CCNProtocolDTags.Host);
-		
-	}
-	
-	if (decoder.peekStartElement(CCNProtocolDTags.Port)) {
-		this.Port = decoder.readIntegerElement(CCNProtocolDTags.Port); 
-	}
-	
-	if (decoder.peekStartElement(CCNProtocolDTags.MulticastInterface)) {
-		this.multicastInterface = decoder.readUTF8Element(CCNProtocolDTags.MulticastInterface); 
-	}
-	
-	if (decoder.peekStartElement(CCNProtocolDTags.MulticastTTL)) {
-		this.multicastTTL = decoder.readIntegerElement(CCNProtocolDTags.MulticastTTL); 
-	}
-	
-	if (decoder.peekStartElement(CCNProtocolDTags.FreshnessSeconds)) {
-		this.freshnessSeconds = decoder.readIntegerElement(CCNProtocolDTags.FreshnessSeconds); 
-	}
-	decoder.readEndElement();
-}
-
-/**
- * Used by NetworkObject to encode the object to a network stream.
- */
-FaceInstance.prototype.to_ccnb = function(//XMLEncoder
-	encoder){
-
-	//if (!this.validate()) {
-		//throw new Error("Cannot encode : field values missing.");
-		//throw new Error("")
-	//}
-	encoder.writeStartElement(this.getElementLabel());
-	
-	if (null != this.action && this.action.length != 0)
-		encoder.writeElement(CCNProtocolDTags.Action, this.action);	
-	
-	if (null != this.publisherPublicKeyDigest) {
-		this.publisherPublicKeyDigest.to_ccnb(encoder);
-	}
-	if (null != this.faceID) {
-		encoder.writeElement(CCNProtocolDTags.FaceID, this.faceID);
-	}
-	if (null != this.ipProto) {
-		//encoder.writeElement(CCNProtocolDTags.IPProto, this.IpProto.value());
-		encoder.writeElement(CCNProtocolDTags.IPProto, this.ipProto);
-	}
-	if (null != this.host && this.host.length != 0) {
-		encoder.writeElement(CCNProtocolDTags.Host, this.host);	
-	}
-	if (null != this.Port) {
-		encoder.writeElement(CCNProtocolDTags.Port, this.Port);
-	}
-	if (null != this.multicastInterface && this.multicastInterface.length != 0) {
-		encoder.writeElement(CCNProtocolDTags.MulticastInterface, this.multicastInterface);
-	}
-	if (null !=  this.multicastTTL) {
-		encoder.writeElement(CCNProtocolDTags.MulticastTTL, this.multicastTTL);
-	}
-	if (null != this.freshnessSeconds) {
-		encoder.writeElement(CCNProtocolDTags.FreshnessSeconds, this.freshnessSeconds);
-	}
-	encoder.writeEndElement();   			
-}
-
-
-FaceInstance.prototype.getElementLabel= function(){return CCNProtocolDTags.FaceInstance;};
-
-/**
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- * This class represents Forwarding Entries
- */
-
-var ForwardingEntry = function ForwardingEntry(
-                                               //ActionType 
-		_action, 
-		//Name 
-		_prefixName, 
-		//PublisherPublicKeyDigest
-		_ccndId, 
-		//Integer 
-		_faceID, 
-		//Integer 
-		_flags, 
-		//Integer 
-		_lifetime){
-		
-		
-	
-		//String
-	this.action = _action;
-		//Name\
-	this.prefixName = _prefixName;
-		//PublisherPublicKeyDigest 
-	this.ccndID = _ccndId;
-		//Integer		
-	this.faceID = _faceID;
-		//Integer		
-	this.flags = _flags;
-		//Integer 		
-	this.lifetime = _lifetime;  // in seconds
-
-};
-
-ForwardingEntry.prototype.from_ccnb =function(
-	//XMLDecoder 
-	decoder) 
-	//throws ContentDecodingException
-	{
-			decoder.readStartElement(this.getElementLabel());
-			if (decoder.peekStartElement(CCNProtocolDTags.Action)) {
-				this.action = decoder.readUTF8Element(CCNProtocolDTags.Action); 
-			}
-			if (decoder.peekStartElement(CCNProtocolDTags.Name)) {
-				this.prefixName = new Name();
-				this.prefixName.from_ccnb(decoder) ;
-			}
-			if (decoder.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)) {
-				this.CcndId = new PublisherPublicKeyDigest();
-				this.CcndId.from_ccnb(decoder);
-			}
-			if (decoder.peekStartElement(CCNProtocolDTags.FaceID)) {
-				this.faceID = decoder.readIntegerElement(CCNProtocolDTags.FaceID); 
-			}
-			if (decoder.peekStartElement(CCNProtocolDTags.ForwardingFlags)) {
-				this.flags = decoder.readIntegerElement(CCNProtocolDTags.ForwardingFlags); 
-			}
-			if (decoder.peekStartElement(CCNProtocolDTags.FreshnessSeconds)) {
-				this.lifetime = decoder.readIntegerElement(CCNProtocolDTags.FreshnessSeconds); 
-			}
-			decoder.readEndElement();
-		};
-
-		/**
-		 * Used by NetworkObject to encode the object to a network stream.
-		 */
-ForwardingEntry.prototype.to_ccnb =function(
-	//XMLEncoder 
-encoder) 
-{
-
-
-			//if (!validate()) {
-				//throw new ContentEncodingException("Cannot encode " + this.getClass().getName() + ": field values missing.");
-			//}
-			encoder.writeStartElement(this.getElementLabel());
-			if (null != this.action && this.action.length != 0)
-				encoder.writeElement(CCNProtocolDTags.Action, this.action);	
-			if (null != this.prefixName) {
-				this.prefixName.to_ccnb(encoder);
-			}
-			if (null != this.CcndId) {
-				this.CcndId.to_ccnb(encoder);
-			}
-			if (null != this.faceID) {
-				encoder.writeElement(CCNProtocolDTags.FaceID, this.faceID);
-			}
-			if (null != this.flags) {
-				encoder.writeElement(CCNProtocolDTags.ForwardingFlags, this.flags);
-			}
-			if (null != this.lifetime) {
-				encoder.writeElement(CCNProtocolDTags.FreshnessSeconds, this.lifetime);
-			}
-			encoder.writeEndElement();   			
-		};
-
-ForwardingEntry.prototype.getElementLabel = function() { return CCNProtocolDTags.ForwardingEntry; }
-/**
- * @author: Jeff Thompson
- * See COPYING for copyright and distribution information.
- * Encapsulate an Uint8Array and support dynamic reallocation.
- */
-
-/*
- * Create a DynamicUint8Array where this.array is a Uint8Array of size length.
- * If length is not supplied, use a default initial length.
- * The methods will update this.length.
- * To access the array, use this.array or call subarray.
- */
-var DynamicUint8Array = function DynamicUint8Array(length) {
-	if (!length)
-        length = 16;
-    
-    this.array = new Uint8Array(length);
-    this.length = length;
-};
-
-/*
- * Ensure that this.array has the length, reallocate and copy if necessary.
- * Update this.length which may be greater than length.
- */
-DynamicUint8Array.prototype.ensureLength = function(length) {
-    if (this.array.length >= length)
-        return;
-    
-    // See if double is enough.
-    var newLength = this.array.length * 2;
-    if (length > newLength)
-        // The needed length is much greater, so use it.
-        newLength = length;
-    
-    var newArray = new Uint8Array(newLength);
-    newArray.set(this.array);
-    this.array = newArray;
-    this.length = newLength;
-};
-
-/*
- * Call this.array.set(value, offset), reallocating if necessary. 
- */
-DynamicUint8Array.prototype.set = function(value, offset) {
-    this.ensureLength(value.length + offset);
-    this.array.set(value, offset);
-};
-
-/*
- * Return this.array.subarray(begin, end);
- */
-DynamicUint8Array.prototype.subarray = function(begin, end) {
-    return this.array.subarray(begin, end);
-}
-/**
- * This class is used to encode ccnb binary elements (blob, type/value pairs).
- * 
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- */
-
-var XML_EXT = 0x00; 
-	
-var XML_TAG = 0x01; 
-	
-var XML_DTAG = 0x02; 
-	
-var XML_ATTR = 0x03; 
- 
-var XML_DATTR = 0x04; 
-	
-var XML_BLOB = 0x05; 
-	
-var XML_UDATA = 0x06; 
-	
-var XML_CLOSE = 0x0;
-
-var XML_SUBTYPE_PROCESSING_INSTRUCTIONS = 16; 
-
-
-var XML_TT_BITS = 3;
-var XML_TT_MASK = ((1 << XML_TT_BITS) - 1);
-var XML_TT_VAL_BITS = XML_TT_BITS + 1;
-var XML_TT_VAL_MASK = ((1 << (XML_TT_VAL_BITS)) - 1);
-var XML_REG_VAL_BITS = 7;
-var XML_REG_VAL_MASK = ((1 << XML_REG_VAL_BITS) - 1);
-var XML_TT_NO_MORE = (1 << XML_REG_VAL_BITS); // 0x80
-var BYTE_MASK = 0xFF;
-var LONG_BYTES = 8;
-var LONG_BITS = 64;
-	
-var bits_11 = 0x0000007FF;
-var bits_18 = 0x00003FFFF;
-var bits_32 = 0x0FFFFFFFF;
-
-
-var BinaryXMLEncoder = function BinaryXMLEncoder(){
-	this.ostream = new DynamicUint8Array(100);
-	this.offset =0;
-	this.CODEC_NAME = "Binary";
-};
-
-/*
- * Encode utf8Content as utf8.
- */
-BinaryXMLEncoder.prototype.writeUString = function(/*String*/ utf8Content) {
-	this.encodeUString(utf8Content, XML_UDATA);
-};
-
-
-BinaryXMLEncoder.prototype.writeBlob = function(
-		/*Uint8Array*/ binaryContent
-		) {
-	
-	if(LOG >3) console.log(binaryContent);
-	
-	this.encodeBlob(binaryContent, binaryContent.length);
-};
-
-
-BinaryXMLEncoder.prototype.writeStartElement = function(
-	/*String*/ tag, 
-	/*TreeMap<String,String>*/ attributes
-	) {
-
-	/*Long*/ var dictionaryVal = tag; //stringToTag(tag);
-	
-	if (null == dictionaryVal) {
-		this.encodeUString(tag, XML_TAG);
-	} else {
-		this.encodeTypeAndVal(XML_DTAG, dictionaryVal);
-	}
-	
-	if (null != attributes) {
-		this.writeAttributes(attributes); 
-	}
-};
-
-
-BinaryXMLEncoder.prototype.writeEndElement = function() {
-    this.ostream.ensureLength(this.offset + 1);
-	this.ostream.array[this.offset] = XML_CLOSE;
-	this.offset += 1;
-}
-
-
-BinaryXMLEncoder.prototype.writeAttributes = function(/*TreeMap<String,String>*/ attributes) {
-	if (null == attributes) {
-		return;
-	}
-
-	// the keySet of a TreeMap is sorted.
-
-	for(var i=0; i<attributes.length;i++){
-		var strAttr = attributes[i].k;
-		var strValue = attributes[i].v;
-
-		var dictionaryAttr = stringToTag(strAttr);
-		if (null == dictionaryAttr) {
-			// not in dictionary, encode as attr
-			// compressed format wants length of tag represented as length-1
-			// to save that extra bit, as tag cannot be 0 length.
-			// encodeUString knows to do that.
-			this.encodeUString(strAttr, XML_ATTR);
-		} else {
-			this.encodeTypeAndVal(XML_DATTR, dictionaryAttr);
-		}
-		// Write value
-		this.encodeUString(strValue);
-		
-	}
-}
-
-
-//returns a string
-stringToTag = function(/*long*/ tagVal) {
-	if ((tagVal >= 0) && (tagVal < CCNProtocolDTagsStrings.length)) {
-		return CCNProtocolDTagsStrings[tagVal];
-	} else if (tagVal == CCNProtocolDTags.CCNProtocolDataUnit) {
-		return CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT;
-	}
-	return null;
-};
-
-//returns a Long
-tagToString =  function(/*String*/ tagName) {
-	// the slow way, but right now we don't care.... want a static lookup for the forward direction
-	for (var i=0; i < CCNProtocolDTagsStrings.length; ++i) {
-		if ((null != CCNProtocolDTagsStrings[i]) && (CCNProtocolDTagsStrings[i] == tagName)) {
-			return i;
-		}
-	}
-	if (CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT == tagName) {
-		return CCNProtocolDTags.CCNProtocolDataUnit;
-	}
-	return null;
-};
-
-/*
- * If Content is a string, then encode as utf8 and write UDATA.
- */
-BinaryXMLEncoder.prototype.writeElement = function(
-		//long 
-		tag, 
-		//byte[] 
-		Content,
-		//TreeMap<String, String> 
-		attributes
-		) {
-	this.writeStartElement(tag, attributes);
-	// Will omit if 0-length
-	
-	if(typeof Content === 'number') {
-		if(LOG>4) console.log('GOING TO WRITE THE NUMBER .charCodeAt(0) ' + Content.toString().charCodeAt(0) );
-		if(LOG>4) console.log('GOING TO WRITE THE NUMBER ' + Content.toString() );
-		if(LOG>4) console.log('type of number is ' + typeof Content.toString() );
-		
-		this.writeUString(Content.toString());
-		//whatever
-	}
-	else if(typeof Content === 'string'){
-		if(LOG>4) console.log('GOING TO WRITE THE STRING  ' + Content );
-		if(LOG>4) console.log('type of STRING is ' + typeof Content );
-		
-		this.writeUString(Content);
-	}
-	else{
-		if(LOG>4) console.log('GOING TO WRITE A BLOB  ' + Content );
-
-		this.writeBlob(Content);
-	}
-	
-	this.writeEndElement();
-}
-
-
-
-var TypeAndVal = function TypeAndVal(_type,_val) {
-	this.type = _type;
-	this.val = _val;
-	
-};
-
-
-BinaryXMLEncoder.prototype.encodeTypeAndVal = function(
-		//int
-		type, 
-		//long 
-		val
-		) {
-	
-	if(LOG>4) console.log('Encoding type '+ type+ ' and value '+ val);
-	
-	if(LOG>4) console.log('OFFSET IS ' + this.offset);
-	
-	if ((type > XML_UDATA) || (type < 0) || (val < 0)) {
-		throw new Error("Tag and value must be positive, and tag valid.");
-	}
-	
-	// Encode backwards. Calculate how many bytes we need:
-	var numEncodingBytes = this.numEncodingBytes(val);
-	this.ostream.ensureLength(this.offset + numEncodingBytes);
-
-	// Bottom 4 bits of val go in last byte with tag.
-	this.ostream.array[this.offset + numEncodingBytes - 1] = 
-		//(byte)
-			(BYTE_MASK &
-					(((XML_TT_MASK & type) | 
-					 ((XML_TT_VAL_MASK & val) << XML_TT_BITS))) |
-					 XML_TT_NO_MORE); // set top bit for last byte
-	val = val >>> XML_TT_VAL_BITS;
-	
-	// Rest of val goes into preceding bytes, 7 bits per byte, top bit
-	// is "more" flag.
-	var i = this.offset + numEncodingBytes - 2;
-	while ((0 != val) && (i >= this.offset)) {
-		this.ostream.array[i] = //(byte)
-				(BYTE_MASK & (val & XML_REG_VAL_MASK)); // leave top bit unset
-		val = val >>> XML_REG_VAL_BITS;
-		--i;
-	}
-	if (val != 0) {
-		throw new Error( "This should not happen: miscalculated encoding");
-		//Log.warning(Log.FAC_ENCODING, "This should not happen: miscalculated encoding length, have " + val + " left.");
-	}
-	this.offset+= numEncodingBytes;
-	
-	return numEncodingBytes;
-};
-
-/*
- * Encode ustring as utf8.
- */
-BinaryXMLEncoder.prototype.encodeUString = function(
-		//String 
-		ustring, 
-		//byte 
-		type) {
-	
-	if (null == ustring)
-		return;
-	if (type == XML_TAG || type == XML_ATTR && ustring.length == 0)
-		return;
-	
-	if(LOG>3) console.log("The string to write is ");
-	if(LOG>3) console.log(ustring);
-
-	var strBytes = DataUtils.stringToUtf8Array(ustring);
-	
-	this.encodeTypeAndVal(type, 
-						(((type == XML_TAG) || (type == XML_ATTR)) ?
-								(strBytes.length-1) :
-								strBytes.length));
-	
-	if(LOG>3) console.log("THE string to write is ");
-	
-	if(LOG>3) console.log(strBytes);
-	
-	this.writeString(strBytes);
-	this.offset+= strBytes.length;
-};
-
-
-
-BinaryXMLEncoder.prototype.encodeBlob = function(
-		//Uint8Array 
-		blob, 
-		//int 
-		length) {
-
-
-	if (null == blob)
-		return;
-	
-	if(LOG>4) console.log('LENGTH OF XML_BLOB IS '+length);
-	
-	/*blobCopy = new Array(blob.Length);
-	
-	for (i = 0; i < blob.length; i++) //in InStr.ToCharArray())
-	{
-		blobCopy[i] = blob[i];
-	}*/
-
-	this.encodeTypeAndVal(XML_BLOB, length);
-
-	this.writeBlobArray(blob);
-	this.offset += length;
-};
-
-var ENCODING_LIMIT_1_BYTE = ((1 << (XML_TT_VAL_BITS)) - 1);
-var ENCODING_LIMIT_2_BYTES = ((1 << (XML_TT_VAL_BITS + XML_REG_VAL_BITS)) - 1);
-var ENCODING_LIMIT_3_BYTES = ((1 << (XML_TT_VAL_BITS + 2 * XML_REG_VAL_BITS)) - 1);
-
-BinaryXMLEncoder.prototype.numEncodingBytes = function(
-		//long
-		x) {
-	if (x <= ENCODING_LIMIT_1_BYTE) return (1);
-	if (x <= ENCODING_LIMIT_2_BYTES) return (2);
-	if (x <= ENCODING_LIMIT_3_BYTES) return (3);
-	
-	var numbytes = 1;
-	
-	// Last byte gives you XML_TT_VAL_BITS
-	// Remainder each give you XML_REG_VAL_BITS
-	x = x >>> XML_TT_VAL_BITS;
-	while (x != 0) {
-        numbytes++;
-		x = x >>> XML_REG_VAL_BITS;
-	}
-	return (numbytes);
-};
-
-BinaryXMLEncoder.prototype.writeDateTime = function(
-		//String 
-		tag, 
-		//CCNTime 
-		dateTime) {
-	
-	if(LOG>4)console.log('ENCODING DATE with LONG VALUE');
-	if(LOG>4)console.log(dateTime.msec);
-	
-	//var binarydate = DataUtils.unsignedLongToByteArray( Math.round((dateTime.msec/1000) * 4096)  );
-	
-
-	//parse to hex
-	var binarydate =  Math.round((dateTime.msec/1000) * 4096).toString(16)  ;
-
-	//HACK
-	var binarydate =  DataUtils.toNumbers( '0'.concat(binarydate,'0')) ;
-
-	
-	if(LOG>4)console.log('ENCODING DATE with BINARY VALUE');
-	if(LOG>4)console.log(binarydate);
-	if(LOG>4)console.log('ENCODING DATE with BINARY VALUE(HEX)');
-	if(LOG>4)console.log(DataUtils.toHex(binarydate));
-	
-	this.writeElement(tag, binarydate);
-};
-
-// This does not update this.offset.
-BinaryXMLEncoder.prototype.writeString = function(input) {
-	
-    if(typeof input === 'string'){
-		//console.log('went here');
-    	if(LOG>4) console.log('GOING TO WRITE A STRING');
-    	if(LOG>4) console.log(input);
-        
-        this.ostream.ensureLength(this.offset + input.length);
-		for (var i = 0; i < input.length; i++) {
-			if(LOG>4) console.log('input.charCodeAt(i)=' + input.charCodeAt(i));
-		    this.ostream.array[this.offset + i] = (input.charCodeAt(i));
-		}
-	}
-    else{
-		if(LOG>4) console.log('GOING TO WRITE A STRING IN BINARY FORM');
-		if(LOG>4) console.log(input);
-		
-		this.writeBlobArray(input);
-    }
-    /*
-	else if(typeof input === 'object'){
-		
-	}	
-	*/
-};
-
-
-BinaryXMLEncoder.prototype.writeBlobArray = function(
-		//Uint8Array 
-		blob) {
-	
-	if(LOG>4) console.log('GOING TO WRITE A BLOB');
-    
-	this.ostream.set(blob, this.offset);
-};
-
-
-BinaryXMLEncoder.prototype.getReducedOstream = function() {
-	return this.ostream.subarray(0, this.offset);
-};
-
-/**
- * This class is used to decode ccnb binary elements (blob, type/value pairs).
- * 
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- */
-
-var XML_EXT = 0x00; 
-	
-var XML_TAG = 0x01; 
-	
-var XML_DTAG = 0x02; 
-	
-var XML_ATTR = 0x03; 
- 
-var XML_DATTR = 0x04; 
-	
-var XML_BLOB = 0x05; 
-	
-var XML_UDATA = 0x06; 
-	
-var XML_CLOSE = 0x0;
-
-var XML_SUBTYPE_PROCESSING_INSTRUCTIONS = 16; 
-	
-
-var XML_TT_BITS = 3;
-var XML_TT_MASK = ((1 << XML_TT_BITS) - 1);
-var XML_TT_VAL_BITS = XML_TT_BITS + 1;
-var XML_TT_VAL_MASK = ((1 << (XML_TT_VAL_BITS)) - 1);
-var XML_REG_VAL_BITS = 7;
-var XML_REG_VAL_MASK = ((1 << XML_REG_VAL_BITS) - 1);
-var XML_TT_NO_MORE = (1 << XML_REG_VAL_BITS); // 0x80
-var BYTE_MASK = 0xFF;
-var LONG_BYTES = 8;
-var LONG_BITS = 64;
-	
-var bits_11 = 0x0000007FF;
-var bits_18 = 0x00003FFFF;
-var bits_32 = 0x0FFFFFFFF;
-
-
-
-//returns a string
-tagToString = function(/*long*/ tagVal) {
-	if ((tagVal >= 0) && (tagVal < CCNProtocolDTagsStrings.length)) {
-		return CCNProtocolDTagsStrings[tagVal];
-	} else if (tagVal == CCNProtocolDTags.CCNProtocolDataUnit) {
-		return CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT;
-	}
-	return null;
-};
-
-//returns a Long
-stringToTag =  function(/*String*/ tagName) {
-	// the slow way, but right now we don't care.... want a static lookup for the forward direction
-	for (var i=0; i < CCNProtocolDTagsStrings.length; ++i) {
-		if ((null != CCNProtocolDTagsStrings[i]) && (CCNProtocolDTagsStrings[i] == tagName)) {
-			return i;
-		}
-	}
-	if (CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT == tagName) {
-		return CCNProtocolDTags.CCNProtocolDataUnit;
-	}
-	return null;
-};
-
-//console.log(stringToTag(64));
-var BinaryXMLDecoder = function BinaryXMLDecoder(istream){
-	var MARK_LEN=512;
-	var DEBUG_MAX_LEN =  32768;
-	
-	this.istream = istream;
-	this.offset = 0;
-};
-
-BinaryXMLDecoder.prototype.initializeDecoding = function() {
-		//if (!this.istream.markSupported()) {
-			//throw new IllegalArgumentException(this.getClass().getName() + ": input stream must support marking!");
-		//}
-}
-
-BinaryXMLDecoder.prototype.readStartDocument = function(){
-		// Currently no start document in binary encoding.
-	}
-
-BinaryXMLDecoder.prototype.readEndDocument = function() {
-		// Currently no end document in binary encoding.
-	};
-
-BinaryXMLDecoder.prototype.readStartElement = function(
-		//String 
-		startTag,
-		//TreeMap<String, String> 
-		attributes) {
-	
-		
-		//NOT SURE
-		//if(typeof startTag == 'number')
-			//startTag = tagToString(startTag);
-		
-			//TypeAndVal 
-			var tv = this.decodeTypeAndVal();
-			
-			if (null == tv) {
-				throw new ContentDecodingException(new Error("Expected start element: " + startTag + " got something not a tag."));
-			}
-			
-			//String 
-			var decodedTag = null;
-			//console.log(tv);
-			//console.log(typeof tv);
-			
-			//console.log(XML_TAG);
-			if (tv.type() == XML_TAG) {
-				//console.log('got here');
-				//Log.info(Log.FAC_ENCODING, "Unexpected: got tag in readStartElement; looking for tag " + startTag + " got length: " + (int)tv.val()+1);
-				// Tag value represents length-1 as tags can never be empty.
-				var valval ;
-				if(typeof tv.val() == 'string'){
-					valval = (parseInt(tv.val())) + 1;
-				}
-				else
-					valval = (tv.val())+ 1;
-				
-				//console.log('valval is ' +valval);
-				
-				decodedTag = this.decodeUString(valval);
-				
-			} else if (tv.type() == XML_DTAG) {
-				//console.log('gothere');
-				//console.log(tv.val());
-				//decodedTag = tagToString(tv.val());
-				//console.log()
-				decodedTag = tv.val();
-			}
-			
-			//console.log(decodedTag);
-			//console.log('startTag is '+startTag);
-			
-			
-			if ((null ==  decodedTag) || decodedTag != startTag ) {
-				console.log('expecting '+ startTag + ' but got '+ decodedTag);
-				throw new ContentDecodingException(new Error("Expected start element: " + startTag + " got: " + decodedTag + "(" + tv.val() + ")"));
-			}
-			
-			// DKS: does not read attributes out of stream if caller doesn't
-			// ask for them. Should possibly peek and skip over them regardless.
-			// TODO: fix this
-			if (null != attributes) {
-				readAttributes(attributes); 
-			}
-	}
-	
-
-BinaryXMLDecoder.prototype.readAttributes = function(
-	// array of [attributeName, attributeValue] 
-	attributes) {
-	
-	if (null == attributes) {
-		return;
-	}
-
-	try {
-		// Now need to get attributes.
-		//TypeAndVal 
-		var nextTV = this.peekTypeAndVal();
-
-		while ((null != nextTV) && ((XML_ATTR == nextTV.type()) ||
-				(XML_DATTR == nextTV.type()))) {
-
-			// Decode this attribute. First, really read the type and value.
-			//this.TypeAndVal 
-			var thisTV = this.decodeTypeAndVal();
-
-			//String 
-			var attributeName = null;
-			if (XML_ATTR == thisTV.type()) {
-				// Tag value represents length-1 as attribute names cannot be empty.
-				var valval ;
-				if(typeof thisTV.val() == 'string'){
-					valval = (parseInt(thisTV.val())) + 1;
-				}
-				else
-					valval = (thisTV.val())+ 1;
-				
-				attributeName = this.decodeUString(valval);
-
-			} else if (XML_DATTR == thisTV.type()) {
-				// DKS TODO are attributes same or different dictionary?
-				attributeName = tagToString(thisTV.val());
-				if (null == attributeName) {
-					throw new ContentDecodingException(new Error("Unknown DATTR value" + thisTV.val()));
-				}
-			}
-			// Attribute values are always UDATA
-			//String
-			var attributeValue = this.decodeUString();
-
-			//
-			attributes.push([attributeName, attributeValue]);
-
-			nextTV = this.peekTypeAndVal();
-		}
-	} catch ( e) {
-		throw new ContentDecodingException(new Error("readStartElement", e));
-	}
-};
-
-//returns a string
-BinaryXMLDecoder.prototype.peekStartElementAsString = function() {
-	//this.istream.mark(MARK_LEN);
-
-	//String 
-	var decodedTag = null;
-	var previousOffset = this.offset;
-	try {
-		// Have to distinguish genuine errors from wrong tags. Could either use
-		// a special exception subtype, or redo the work here.
-		//this.TypeAndVal 
-		var tv = this.decodeTypeAndVal();
-
-		if (null != tv) {
-
-			if (tv.type() == XML_TAG) {
-				/*if (tv.val()+1 > DEBUG_MAX_LEN) {
-					throw new ContentDecodingException(new Error("Decoding error: length " + tv.val()+1 + " longer than expected maximum length!")(;
-				}*/
-
-				// Tag value represents length-1 as tags can never be empty.
-				var valval ;
-				if(typeof tv.val() == 'string'){
-					valval = (parseInt(tv.val())) + 1;
-				}
-				else
-					valval = (tv.val())+ 1;
-				
-				decodedTag = this.decodeUString(valval);
-				
-				//Log.info(Log.FAC_ENCODING, "Unexpected: got text tag in peekStartElement; length: " + valval + " decoded tag = " + decodedTag);
-
-			} else if (tv.type() == XML_DTAG) {
-				decodedTag = tagToString(tv.val());					
-			}
-
-		} // else, not a type and val, probably an end element. rewind and return false.
-
-	} catch ( e) {
-
-	} finally {
-		try {
-			this.offset = previousOffset;
-		} catch ( e) {
-			Log.logStackTrace(Log.FAC_ENCODING, Level.WARNING, e);
-			throw new ContentDecodingException(new Error("Cannot reset stream! " + e.getMessage(), e));
-		}
-	}
-	return decodedTag;
-};
-
-BinaryXMLDecoder.prototype.peekStartElement = function(
-		//String 
-		startTag) {
-	//String 
-	if(typeof startTag == 'string'){
-		var decodedTag = this.peekStartElementAsString();
-		
-		if ((null !=  decodedTag) && decodedTag == startTag) {
-			return true;
-		}
-		return false;
-	}
-	else if(typeof startTag == 'number'){
-		var decodedTag = this.peekStartElementAsLong();
-		if ((null !=  decodedTag) && decodedTag == startTag) {
-			return true;
-		}
-		return false;
-	}
-	else{
-		throw new ContentDecodingException(new Error("SHOULD BE STRING OR NUMBER"));
-	}
-}
-//returns Long
-BinaryXMLDecoder.prototype.peekStartElementAsLong = function() {
-		//this.istream.mark(MARK_LEN);
-
-		//Long
-		var decodedTag = null;
-		
-		var previousOffset = this.offset;
-		
-		try {
-			// Have to distinguish genuine errors from wrong tags. Could either use
-			// a special exception subtype, or redo the work here.
-			//this.TypeAndVal
-			var tv = this.decodeTypeAndVal();
-
-			if (null != tv) {
-
-				if (tv.type() == XML_TAG) {
-					if (tv.val()+1 > DEBUG_MAX_LEN) {
-						throw new ContentDecodingException(new Error("Decoding error: length " + tv.val()+1 + " longer than expected maximum length!"));
-					}
-
-					var valval ;
-					if(typeof tv.val() == 'string'){
-						valval = (parseInt(tv.val())) + 1;
-					}
-					else
-						valval = (tv.val())+ 1;
-					
-					// Tag value represents length-1 as tags can never be empty.
-					//String 
-					var strTag = this.decodeUString(valval);
-					
-					decodedTag = stringToTag(strTag);
-					
-					//Log.info(Log.FAC_ENCODING, "Unexpected: got text tag in peekStartElement; length: " + valval + " decoded tag = " + decodedTag);
-					
-				} else if (tv.type() == XML_DTAG) {
-					decodedTag = tv.val();					
-				}
-
-			} // else, not a type and val, probably an end element. rewind and return false.
-
-		} catch ( e) {
-			
-		} finally {
-			try {
-				//this.istream.reset();
-				this.offset = previousOffset;
-			} catch ( e) {
-				Log.logStackTrace(Log.FAC_ENCODING, Level.WARNING, e);
-				throw new Error("Cannot reset stream! " + e.getMessage(), e);
-			}
-		}
-		return decodedTag;
-	};
-
-
-// Returns a Uint8Array.
-BinaryXMLDecoder.prototype.readBinaryElement = function(
-		//long 
-		startTag,
-		//TreeMap<String, String> 
-		attributes,
-		//boolean
-		allowNull){
-	this.readStartElement(startTag, attributes);
-	return this.readBlob(allowNull);	
-};
-	
-	
-BinaryXMLDecoder.prototype.readEndElement = function(){
-			if(LOG>4)console.log('this.offset is '+this.offset);
-			
-			var next = this.istream[this.offset]; 
-			
-			this.offset++;
-			//read();
-			
-			if(LOG>4)console.log('XML_CLOSE IS '+XML_CLOSE);
-			if(LOG>4)console.log('next is '+next);
-			
-			if (next != XML_CLOSE) {
-				console.log("Expected end element, got: " + next);
-				throw new ContentDecodingException(new Error("Expected end element, got: " + next));
-			}
-	};
-
-
-//String	
-BinaryXMLDecoder.prototype.readUString = function(){
-			//String 
-			var ustring = this.decodeUString();	
-			this.readEndElement();
-			return ustring;
-
-	};
-	
-
-/*
- * Read a blob as well as the end element. Returns a Uint8Array (or null for missing blob).
- * If the blob is missing and allowNull is false (default), throw an exception.  Otherwise,
- *   just read the end element and return null.
- */
-BinaryXMLDecoder.prototype.readBlob = function(allowNull) {
-    if (this.istream[this.offset] == XML_CLOSE && allowNull) {
-        this.readEndElement();
-        return null;
-    }
-    
-	var blob = this.decodeBlob();	
-	this.readEndElement();
-	return blob;
-};
-
-
-//CCNTime
-BinaryXMLDecoder.prototype.readDateTime = function(
-	//long 
-	startTag)  {
-	//byte [] 
-	
-	var byteTimestamp = this.readBinaryElement(startTag);
-
-	//var lontimestamp = DataUtils.byteArrayToUnsignedLong(byteTimestamp);
-
-	byteTimestamp = DataUtils.toHex(byteTimestamp);
-	
-	
-	byteTimestamp = parseInt(byteTimestamp, 16);
-
-	var lontimestamp = (byteTimestamp/ 4096) * 1000;
-
-	//if(lontimestamp<0) lontimestamp =  - lontimestamp;
-
-	if(LOG>4) console.log('DECODED DATE WITH VALUE');
-	if(LOG>4) console.log(lontimestamp);
-	
-
-	//CCNTime 
-	var timestamp = new CCNTime(lontimestamp);
-	//timestamp.setDateBinary(byteTimestamp);
-	
-	if (null == timestamp) {
-		throw new ContentDecodingException(new Error("Cannot parse timestamp: " + DataUtils.printHexBytes(byteTimestamp)));
-	}		
-	return timestamp;
-};
-
-BinaryXMLDecoder.prototype.decodeTypeAndVal = function() {
-	
-	/*int*/var type = -1;
-	/*long*/var val = 0;
-	/*boolean*/var more = true;
-
-	do {
-		
-		var next = this.istream[this.offset ];
-		
-		
-		if (next < 0) {
-			return null; 
-		}
-
-		if ((0 == next) && (0 == val)) {
-			return null;
-		}
-		
-		more = (0 == (next & XML_TT_NO_MORE));
-		
-		if  (more) {
-			val = val << XML_REG_VAL_BITS;
-			val |= (next & XML_REG_VAL_MASK);
-		} else {
-
-			type = next & XML_TT_MASK;
-			val = val << XML_TT_VAL_BITS;
-			val |= ((next >>> XML_TT_BITS) & XML_TT_VAL_MASK);
-		}
-		
-		this.offset++;
-		
-	} while (more);
-	
-	if(LOG>4)console.log('TYPE is '+ type + ' VAL is '+ val);
-
-	return new TypeAndVal(type, val);
-};
-
-//TypeAndVal
-BinaryXMLDecoder.prototype.peekTypeAndVal = function() {
-	//TypeAndVal 
-	var tv = null;
-	var previousOffset = this.offset;
-	
-	try {
-		tv = this.decodeTypeAndVal();
-	} finally {
-		this.offset = previousOffset;
-	}
-	
-	return tv;
-};
-
-//Uint8Array
-BinaryXMLDecoder.prototype.decodeBlob = function(
-		//int 
-		blobLength) {
-	
-	if(null == blobLength){
-		//TypeAndVal
-		var tv = this.decodeTypeAndVal();
-
-		var valval ;
-		
-		if(typeof tv.val() == 'string'){
-			valval = (parseInt(tv.val()));
-		}
-		else
-			valval = (tv.val());
-		
-		//console.log('valval here is ' + valval);
-		return  this.decodeBlob(valval);
-	}
-	
-	//
-	//Uint8Array
-	var bytes = this.istream.subarray(this.offset, this.offset+ blobLength);
-	this.offset += blobLength;
-	
-	return bytes;
-};
-
-//String
-BinaryXMLDecoder.prototype.decodeUString = function(
-		//int 
-		byteLength) {
-	if(null == byteLength ){
-		var tempStreamPosition = this.offset;
-			
-		//TypeAndVal 
-		var tv = this.decodeTypeAndVal();
-		
-		if(LOG>4)console.log('TV is '+tv);
-		if(LOG>4)console.log(tv);
-		
-		if(LOG>4)console.log('Type of TV is '+typeof tv);
-	
-		if ((null == tv) || (XML_UDATA != tv.type())) { // if we just have closers left, will get back null
-			//if (Log.isLoggable(Log.FAC_ENCODING, Level.FINEST))
-				//Log.finest(Log.FAC_ENCODING, "Expected UDATA, got " + ((null == tv) ? " not a tag " : tv.type()) + ", assuming elided 0-length blob.");
-			
-			this.offset = tempStreamPosition;
-			
-			return "";
-		}
-			
-		return this.decodeUString(tv.val());
-	}
-	else{
-		//uint8array 
-		var stringBytes = this.decodeBlob(byteLength);
-		
-		//return DataUtils.getUTF8StringFromBytes(stringBytes);
-		return  DataUtils.toString(stringBytes);
-		
-	}
-};
-
-//OBject containg a pair of type and value
-var TypeAndVal = function TypeAndVal(_type,_val) {
-	this.t = _type;
-	this.v = _val;
-};
-
-TypeAndVal.prototype.type = function(){
-	return this.t;
-};
-
-TypeAndVal.prototype.val = function(){
-	return this.v;
-};
-
-
-
-
-BinaryXMLDecoder.prototype.readIntegerElement =function(
-	//String 
-	startTag) {
-
-	//String 
-	if(LOG>4) console.log('READING INTEGER '+ startTag);
-	if(LOG>4) console.log('TYPE OF '+ typeof startTag);
-	
-	var strVal = this.readUTF8Element(startTag);
-	
-	return parseInt(strVal);
-};
-
-
-BinaryXMLDecoder.prototype.readUTF8Element =function(
-			//String 
-			startTag,
-			//TreeMap<String, String> 
-			attributes) {
-			//throws Error where name == "ContentDecodingException" 
-
-		this.readStartElement(startTag, attributes); // can't use getElementText, can't get attributes
-		//String 
-		var strElementText = this.readUString();
-		return strElementText;
-};
-
-
-/* 
- * Set the offset into the input, used for the next read.
- */
-BinaryXMLDecoder.prototype.seek = function(
-        //int
-        offset) {
-    this.offset = offset;
-}
-
-/*
- * Call with: throw new ContentDecodingException(new Error("message")).
- */
-function ContentDecodingException(error) {
-    this.message = error.message;
-    // Copy lineNumber, etc. from where new Error was called.
-    for (var prop in error)
-        this[prop] = error[prop];
-}
-ContentDecodingException.prototype = new Error();
-ContentDecodingException.prototype.name = "ContentDecodingException";
-
-/**
- * This class uses BinaryXMLDecoder to follow the structure of a ccnb binary element to 
- * determine its end.
- * 
- * @author: Jeff Thompson
- * See COPYING for copyright and distribution information.
- */
-
-var BinaryXMLStructureDecoder = function BinaryXMLDecoder() {
-    this.gotElementEnd = false;
-	this.offset = 0;
-    this.level = 0;
-    this.state = BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE;
-    this.headerLength = 0;
-    this.useHeaderBuffer = false;
-    this.headerBuffer = new DynamicUint8Array(5);
-    this.nBytesToRead = 0;
-};
-
-BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE = 0;
-BinaryXMLStructureDecoder.READ_BYTES = 1;
-
-/*
- * Continue scanning input starting from this.offset.  If found the end of the element
- *   which started at offset 0 then return true, else false.
- * If this returns false, you should read more into input and call again.
- * You have to pass in input each time because the array could be reallocated.
- * This throws an exception for badly formed ccnb.
- */
-BinaryXMLStructureDecoder.prototype.findElementEnd = function(
-    // Uint8Array
-    input)
-{
-    if (this.gotElementEnd)
-        // Someone is calling when we already got the end.
-        return true;
-    
-    var decoder = new BinaryXMLDecoder(input);
-    
-    while (true) {
-        if (this.offset >= input.length)
-            // All the cases assume we have some input.
-            return false;
-        
-        switch (this.state) {
-            case BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE:               
-                // First check for XML_CLOSE.
-                if (this.headerLength == 0 && input[this.offset] == XML_CLOSE) {
-                    ++this.offset;
-                    // Close the level.
-                    --this.level;
-                    if (this.level == 0)
-                        // Finished.
-                        return true;
-                    if (this.level < 0)
-                        throw new Error("BinaryXMLStructureDecoder: Unexepected close tag at offset " +
-                            (this.offset - 1));
-                    
-                    // Get ready for the next header.
-                    this.startHeader();
-                    break;
-                }
-                
-                var startingHeaderLength = this.headerLength;
-                while (true) {
-                    if (this.offset >= input.length) {
-                        // We can't get all of the header bytes from this input. Save in headerBuffer.
-                        this.useHeaderBuffer = true;
-                        var nNewBytes = this.headerLength - startingHeaderLength;
-                        this.headerBuffer.set
-                            (input.subarray(this.offset - nNewBytes, nNewBytes), startingHeaderLength);
-                        
-                        return false;
-                    }
-                    var headerByte = input[this.offset++];
-                    ++this.headerLength;
-                    if (headerByte & XML_TT_NO_MORE)
-                        // Break and read the header.
-                        break;
-                }
-                
-                var typeAndVal;
-                if (this.useHeaderBuffer) {
-                    // Copy the remaining bytes into headerBuffer.
-                    nNewBytes = this.headerLength - startingHeaderLength;
-                    this.headerBuffer.set
-                        (input.subarray(this.offset - nNewBytes, nNewBytes), startingHeaderLength);
-
-                    typeAndVal = new BinaryXMLDecoder(this.headerBuffer.array).decodeTypeAndVal();
-                }
-                else {
-                    // We didn't have to use the headerBuffer.
-                    decoder.seek(this.offset - this.headerLength);
-                    typeAndVal = decoder.decodeTypeAndVal();
-                }
-                
-                if (typeAndVal == null)
-                    throw new Error("BinaryXMLStructureDecoder: Can't read header starting at offset " +
-                        (this.offset - this.headerLength));
-                
-                // Set the next state based on the type.
-                var type = typeAndVal.t;
-                if (type == XML_DATTR)
-                    // We already consumed the item. READ_HEADER_OR_CLOSE again.
-                    // ccnb has rules about what must follow an attribute, but we are just scanning.
-                    this.startHeader();
-                else if (type == XML_DTAG || type == XML_EXT) {
-                    // Start a new level and READ_HEADER_OR_CLOSE again.
-                    ++this.level;
-                    this.startHeader();
-                }
-                else if (type == XML_TAG || type == XML_ATTR) {
-                    if (type == XML_TAG)
-                        // Start a new level and read the tag.
-                        ++this.level;
-                    // Minimum tag or attribute length is 1.
-                    this.nBytesToRead = typeAndVal.v + 1;
-                    this.state = BinaryXMLStructureDecoder.READ_BYTES;
-                    // ccnb has rules about what must follow an attribute, but we are just scanning.
-                }
-                else if (type == XML_BLOB || type == XML_UDATA) {
-                    this.nBytesToRead = typeAndVal.v;
-                    this.state = BinaryXMLStructureDecoder.READ_BYTES;
-                }
-                else
-                    throw new Error("BinaryXMLStructureDecoder: Unrecognized header type " + type);
-                break;
-            
-            case BinaryXMLStructureDecoder.READ_BYTES:
-                var nRemainingBytes = input.length - this.offset;
-                if (nRemainingBytes < this.nBytesToRead) {
-                    // Need more.
-                    this.offset += nRemainingBytes;
-                    this.nBytesToRead -= nRemainingBytes;
-                    return false;
-                }
-                // Got the bytes.  Read a new header or close.
-                this.offset += this.nBytesToRead;
-                this.startHeader();
-                break;
-            
-            default:
-                // We don't expect this to happen.
-                throw new Error("BinaryXMLStructureDecoder: Unrecognized state " + this.state);
-        }
-    }
-};
-
-/*
- * Set the state to READ_HEADER_OR_CLOSE and set up to start reading the header
- */
-BinaryXMLStructureDecoder.prototype.startHeader = function() {
-    this.headerLength = 0;
-    this.useHeaderBuffer = false;
-    this.state = BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE;    
-}
-
-/*
- *  Set the offset into the input, used for the next read.
- */
-BinaryXMLStructureDecoder.prototype.seek = function(
-        //int
-        offset) {
-    this.offset = offset;
-}
-/**
- * This class contains utilities to help parse the data
- * author: Meki Cheraoui, Jeff Thompson
- * See COPYING for copyright and distribution information.
- */
- 
-var DataUtils = function DataUtils(){
-	
-	
-};
-
-
-/*
- * NOTE THIS IS CURRENTLY NOT BEHING USED
- * 
- */
-
-DataUtils.keyStr = "ABCDEFGHIJKLMNOP" +
-               "QRSTUVWXYZabcdef" +
-               "ghijklmnopqrstuv" +
-               "wxyz0123456789+/" +
-               "=";
-
-               
-/**
- * Raw String to Base 64
- */
-DataUtils.stringtoBase64=function stringtoBase64(input) {
-     input = escape(input);
-     var output = "";
-     var chr1, chr2, chr3 = "";
-     var enc1, enc2, enc3, enc4 = "";
-     var i = 0;
-
-     do {
-        chr1 = input.charCodeAt(i++);
-        chr2 = input.charCodeAt(i++);
-        chr3 = input.charCodeAt(i++);
-
-        enc1 = chr1 >> 2;
-        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
-        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
-        enc4 = chr3 & 63;
-
-        if (isNaN(chr2)) {
-           enc3 = enc4 = 64;
-        } else if (isNaN(chr3)) {
-           enc4 = 64;
-        }
-
-        output = output +
-           DataUtils.keyStr.charAt(enc1) +
-           DataUtils.keyStr.charAt(enc2) +
-           DataUtils.keyStr.charAt(enc3) +
-           DataUtils.keyStr.charAt(enc4);
-        chr1 = chr2 = chr3 = "";
-        enc1 = enc2 = enc3 = enc4 = "";
-     } while (i < input.length);
-
-     return output;
-  }
-
-/**
- * Base 64 to Raw String 
- */
-DataUtils.base64toString = function base64toString(input) {
-     var output = "";
-     var chr1, chr2, chr3 = "";
-     var enc1, enc2, enc3, enc4 = "";
-     var i = 0;
-
-     // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
-     var base64test = /[^A-Za-z0-9\+\/\=]/g;
-     /* Test for invalid characters. */
-     if (base64test.exec(input)) {
-        alert("There were invalid base64 characters in the input text.\n" +
-              "Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" +
-              "Expect errors in decoding.");
-     }
-     
-     input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
-
-     do {
-        enc1 = DataUtils.keyStr.indexOf(input.charAt(i++));
-        enc2 = DataUtils.keyStr.indexOf(input.charAt(i++));
-        enc3 = DataUtils.keyStr.indexOf(input.charAt(i++));
-        enc4 = DataUtils.keyStr.indexOf(input.charAt(i++));
-
-        chr1 = (enc1 << 2) | (enc2 >> 4);
-        chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
-        chr3 = ((enc3 & 3) << 6) | enc4;
-
-        output = output + String.fromCharCode(chr1);
-
-        if (enc3 != 64) {
-           output = output + String.fromCharCode(chr2);
-        }
-        if (enc4 != 64) {
-           output = output + String.fromCharCode(chr3);
-        }
-
-        chr1 = chr2 = chr3 = "";
-        enc1 = enc2 = enc3 = enc4 = "";
-
-     } while (i < input.length);
-
-     return unescape(output);
-  };
-
-//byte [] 
-
-/**
- * NOT WORKING!!!!!
- * 
- * Unsiged Long Number to Byte Array
- */
-	
- /*
-DataUtils.unsignedLongToByteArray= function( value) {
-	
-	if(LOG>4)console.log('INPUT IS '+value);
-	
-	if( 0 == value )
-		return [0];
-
-	if( 0 <= value && value <= 0x00FF ) {
-		//byte [] 
-		var bb = new Array(1);
-		bb[0] = (value & 0x00FF);
-		return bb;
-	}
-
-	if(LOG>4) console.log('type of value is '+typeof value);
-	if(LOG>4) console.log('value is '+value);
-	//byte [] 
-	var out = null;
-	//int
-	var offset = -1;
-	for(var i = 7; i >=0; --i) {
-		//byte
-		console.log(i);
-		console.log('value is '+value);
-		console.log('(value >> (i * 8)) '+ (value >> (i * 8))  );
-		console.log(' ((value >> (i * 8)) & 0xFF) '+ ((value >> (i * 8)) & 0xFF)  );
-
-		var b = ((value >> (i * 8)) & 0xFF)  ;
-		
-		if(LOG>4) console.log('b is '+b);
-		
-		if( out == null && b != 0 ) {
-			//out = new byte[i+1];
-			out = new Array(i+1);
-			offset = i;
-		}
-		
-		if( out != null )
-			out[ offset - i ] = b;
-	}
-	if(LOG>4)console.log('OUTPUT IS ');
-	if(LOG>4)console.log(out);
-	return out;
-}
-*/
-	
-/**
- * NOT WORKING!!!!!
- * 
- * Unsiged Long Number to Byte Array
- *//*
-DataUtils.byteArrayToUnsignedLong = function(//final byte [] 
-	src) {
-		if(LOG>4) console.log('INPUT IS ');
-		if(LOG>4) console.log(src);
-		
-		var value = 0;
-		for(var i = 0; i < src.length; i++) {
-			value = value << 8;
-			// Java will assume the byte is signed, so extend it and trim it.
-			
-			
-			var b = ((src[i]) & 0xFF );
-			value |= b;
-		}
-		
-		if(LOG>4) console.log('OUTPUT IS ');
-		
-		if(LOG>4) console.log(value);
-
-		return value;
-	}*/
-
-
-/**
- * Hex String to Byte Array
- */
-	//THIS IS NOT WORKING
-/*
-DataUtils.HexStringtoByteArray = function(str) {
-    var byteArray = [];
-    for (var i = 0; i < str.length; i++)
-        if (str.charCodeAt(i) <= 0x7F)
-            byteArray.push(str.charCodeAt(i));
-        else {
-            var h = encodeURIComponent(str.charAt(i)).substr(1).split('%');
-            for (var j = 0; j < h.length; j++)
-                byteArray.push(parseInt(h[j], 16));
-        }
-    return byteArray;
-};
-*/
-
-/**
- * Uint8Array to Hex String
- */
-//http://ejohn.org/blog/numbers-hex-and-colors/
-DataUtils.toHex = function(args){
-	if (LOG>4) console.log('ABOUT TO CONVERT '+ args);
-	//console.log(args);
-  	var ret = "";
-  	for ( var i = 0; i < args.length; i++ )
-    	ret += (args[i] < 16 ? "0" : "") + args[i].toString(16);
-  	if (LOG>4) console.log('Converted to: ' + ret);
-  	return ret; //.toUpperCase();
-}
-
-/**
- * Raw string to hex string.
- */
-DataUtils.stringToHex = function(args){
-	var ret = "";
-	for (var i = 0; i < args.length; ++i) {
-		var value = args.charCodeAt(i);
-		ret += (value < 16 ? "0" : "") + value.toString(16);
-	}
-	return ret;
-}
-
-/**
- * Uint8Array to raw string.
- */
-DataUtils.toString = function(args){
-  //console.log(arguments);
-  var ret = "";
-  for ( var i = 0; i < args.length; i++ )
-    ret += String.fromCharCode(args[i]);
-  return ret;
-}
-
-/**
- * Hex String to Uint8Array.
- */
-DataUtils.toNumbers = function(str) {
-	if (typeof str == 'string') {
-		var ret = new Uint8Array(Math.floor(str.length / 2));
-        var i = 0;
-		str.replace(/(..)/g, function(str) {
-		    ret[i++] = parseInt(str, 16);
-		});
-		return ret;
-    }
-}
-
-/**
- * Hex String to raw string.
- */
-DataUtils.hexToRawString = function(str) {
-    if(typeof str =='string') {
-		var ret = "";
-		str.replace(/(..)/g, function(s) {
-			ret += String.fromCharCode(parseInt(s, 16));
-		});
-		return ret;
-    }
-}
-
-/**
- * Raw String to Uint8Array.
- */
-DataUtils.toNumbersFromString = function(str) {
-	var bytes = new Uint8Array(str.length);
-	for(var i=0;i<str.length;i++)
-		bytes[i] = str.charCodeAt(i);
-	return bytes;
-}
-
-/*
- * Encode str as utf8 and return as Uint8Array.
- * TODO: Use TextEncoder when available.
- */
-DataUtils.stringToUtf8Array = function(str) {
-    return DataUtils.toNumbersFromString(str2rstr_utf8(str));
-}
-
-/*
- * arrays is an array of Uint8Array. Return a new Uint8Array which is the concatenation of all.
- */
-DataUtils.concatArrays = function(arrays) {
-    var totalLength = 0;
-	for (var i = 0; i < arrays.length; ++i)
-        totalLength += arrays[i].length;
-    
-    var result = new Uint8Array(totalLength);
-    var offset = 0;
-	for (var i = 0; i < arrays.length; ++i) {
-        result.set(arrays[i], offset);
-        offset += arrays[i].length;
-    }
-    return result;
-    
-}
- 
-// TODO: Take Uint8Array and use TextDecoder when available.
-DataUtils.decodeUtf8 = function (utftext) {
-		var string = "";
-		var i = 0;
-		var c = 0;
-        var c1 = 0;
-        var c2 = 0;
- 
-		while ( i < utftext.length ) {
- 
-			c = utftext.charCodeAt(i);
- 
-			if (c < 128) {
-				string += String.fromCharCode(c);
-				i++;
-			}
-			else if((c > 191) && (c < 224)) {
-				c2 = utftext.charCodeAt(i+1);
-				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
-				i += 2;
-			}
-			else {
-				c2 = utftext.charCodeAt(i+1);
-				var c3 = utftext.charCodeAt(i+2);
-				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
-				i += 3;
-			}
- 
-		}
- 
-		return string;
-	};
-
-//NOT WORKING
-/*
-DataUtils.getUTF8StringFromBytes = function(bytes) {
-	
-	bytes = toString(bytes);
-
-    var ix = 0;
- 
-    if( bytes.slice(0,3) == "\xEF\xBB\xBF") {
-        ix = 3;
-    }
- 
-    var string = "";
-    for( ; ix < bytes.length; ix++ ) {
-        var byte1 = bytes[ix].charCodeAt(0);
-        if( byte1 < 0x80 ) {
-            string += String.fromCharCode(byte1);
-        } else if( byte1 >= 0xC2 && byte1 < 0xE0 ) {
-            var byte2 = bytes[++ix].charCodeAt(0);
-            string += String.fromCharCode(((byte1&0x1F)<<6) + (byte2&0x3F));
-        } else if( byte1 >= 0xE0 && byte1 < 0xF0 ) {
-            var byte2 = bytes[++ix].charCodeAt(0);
-            var byte3 = bytes[++ix].charCodeAt(0);
-            string += String.fromCharCode(((byte1&0xFF)<<12) + ((byte2&0x3F)<<6) + (byte3&0x3F));
-        } else if( byte1 >= 0xF0 && byte1 < 0xF5) {
-            var byte2 = bytes[++ix].charCodeAt(0);
-            var byte3 = bytes[++ix].charCodeAt(0);
-            var byte4 = bytes[++ix].charCodeAt(0);
-            var codepoint = ((byte1&0x07)<<18) + ((byte2&0x3F)<<12)+ ((byte3&0x3F)<<6) + (byte4&0x3F);
-            codepoint -= 0x10000;
-            string += String.fromCharCode(
-                (codepoint>>10) + 0xD800,
-                (codepoint&0x3FF) + 0xDC00
-            );
-        }
-    }
- 
-    return string;
-}*/
-
-/**
- * Return true if a1 and a2 are the same length with equal elements.
- */
-DataUtils.arraysEqual = function(a1, a2){
-    if (a1.length != a2.length)
-        return false;
-    
-    for (var i = 0; i < a1.length; ++i) {
-        if (a1[i] != a2[i])
-            return false;
-    }
-
-    return true;
-};
-
-/*
- * Convert the big endian Uint8Array to an unsigned int.
- * Don't check for overflow.
- */
-DataUtils.bigEndianToUnsignedInt = function(bytes) {
-    var result = 0;
-    for (var i = 0; i < bytes.length; ++i) {
-        result <<= 8;
-        result += bytes[i];
-    }
-    return result;
-};
-
-/*
- * Convert the int value to a new big endian Uint8Array and return.
- * If value is 0 or negative, return Uint8Array(0). 
- */
-DataUtils.nonNegativeIntToBigEndian = function(value) {
-    value = Math.round(value);
-    if (value <= 0)
-        return new Uint8Array(0);
-    
-    // Assume value is not over 64 bits.
-    var size = 8;
-    var result = new Uint8Array(size);
-    var i = 0;
-    while (value != 0) {
-        ++i;
-        result[size - i] = value & 0xff;
-        value >>= 8;
-    }
-    return result.subarray(size - i, size);
-};
-
-/*
- * Modify array to randomly shuffle the elements.
- */
-DataUtils.shuffle = function(array) {
-    for (var i = array.length - 1; i >= 1; --i) {
-        // j is from 0 to i.
-        var j = Math.floor(Math.random() * (i + 1));
-        var temp = array[i];
-        array[i] = array[j];
-        array[j] = temp;
-    }
-}
-/**
- * This file contains utilities to help encode and decode NDN objects.
- * author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- */
-
-function encodeToHexInterest(interest){
-    return DataUtils.toHex(encodeToBinaryInterest(interest));
-}
-
-
-function encodeToBinaryInterest(interest) {
-	var enc = new BinaryXMLEncoder();
-	interest.to_ccnb(enc);
-	
-	return enc.getReducedOstream();
-}
-
-
-function encodeToHexContentObject(co){
-    return DataUtils.toHex(encodeToBinaryContentObject(co));
-}
-
-function encodeToBinaryContentObject(co){
-	var enc = new BinaryXMLEncoder();
-	co.to_ccnb(enc);
-
-	return enc.getReducedOstream();
-}
-
-function encodeForwardingEntry(co){
-	var enc = new BinaryXMLEncoder();
- 
-	co.to_ccnb(enc);
-	
-	var bytes = enc.getReducedOstream();
-
-	return bytes;
-
-	
-}
-
-
-
-function decodeHexFaceInstance(result){
-	
-	var numbers = DataUtils.toNumbers(result);
-			
-	
-	var decoder = new BinaryXMLDecoder(numbers);
-	
-	if(LOG>3)console.log('DECODING HEX FACE INSTANCE  \n'+numbers);
-
-	var faceInstance = new FaceInstance();
-
-	faceInstance.from_ccnb(decoder);
-
-	return faceInstance;
-	
-}
-
-
-
-function decodeHexInterest(result){
-	var numbers = DataUtils.toNumbers(result);	
-	
-	var decoder = new BinaryXMLDecoder(numbers);
-	
-	if(LOG>3)console.log('DECODING HEX INTERST  \n'+numbers);
-
-	var interest = new Interest();
-
-	interest.from_ccnb(decoder);
-
-	return interest;
-	
-}
-
-
-
-function decodeHexContentObject(result){
-	var numbers = DataUtils.toNumbers(result);
-	
-	var decoder = new BinaryXMLDecoder(numbers);
-	
-	if(LOG>3)console.log('DECODED HEX CONTENT OBJECT \n'+numbers);
-	
-	var co = new ContentObject();
-
-	co.from_ccnb(decoder);
-
-	return co;
-	
-}
-
-
-
-function decodeHexForwardingEntry(result){
-	var numbers = DataUtils.toNumbers(result);
-
-	var decoder = new BinaryXMLDecoder(numbers);
-	
-	if(LOG>3)console.log('DECODED HEX FORWARDING ENTRY \n'+numbers);
-	
-	var forwardingEntry = new ForwardingEntry();
-
-	forwardingEntry.from_ccnb(decoder);
-
-	return forwardingEntry;
-	
-}
-
-/*
- * Decode the Uint8Array which holds SubjectPublicKeyInfo and return an RSAKey.
- */
-function decodeSubjectPublicKeyInfo(array) {
-    var hex = DataUtils.toHex(array).toLowerCase();
-    var a = _x509_getPublicKeyHexArrayFromCertHex(hex, _x509_getSubjectPublicKeyPosFromCertHex(hex, 0));
-    var rsaKey = new RSAKey();
-    rsaKey.setPublic(a[0], a[1]);
-    return rsaKey;
-}
-
-/* Return a user friendly HTML string with the contents of co.
-   This also outputs to console.log.
- */
-function contentObjectToHtml(/* ContentObject */ co) {
-    var output ="";
-			
-    if(co==-1)
-	output+= "NO CONTENT FOUND"
-    else if (co==-2)
-	output+= "CONTENT NAME IS EMPTY"
-    else{
-	if(co.name!=null && co.name.components!=null){
-	    output+= "NAME: " + co.name.to_uri();
-        
-	    output+= "<br />";
-	    output+= "<br />";
-	}
-	
-	if(co.content !=null){
-	    output += "CONTENT(ASCII): "+ DataUtils.toString(co.content);
-	    
-	    output+= "<br />";
-	    output+= "<br />";
-	}
-	if(co.content !=null){
-	    output += "CONTENT(hex): "+ DataUtils.toHex(co.content);
-	    
-	    output+= "<br />";
-	    output+= "<br />";
-	}
-	if(co.signature !=null && co.signature.signature!=null){
-	    output += "SIGNATURE(hex): "+ DataUtils.toHex(co.signature.signature);
-	    
-	    output+= "<br />";
-	    output+= "<br />";
-	}
-	if(co.signedInfo !=null && co.signedInfo.publisher!=null && co.signedInfo.publisher.publisherPublicKeyDigest!=null){
-	    output += "Publisher Public Key Digest(hex): "+ DataUtils.toHex(co.signedInfo.publisher.publisherPublicKeyDigest);
-	    
-	    output+= "<br />";
-	    output+= "<br />";
-	}
-	if(co.signedInfo !=null && co.signedInfo.timestamp!=null){
-	    var d = new Date();
-	    d.setTime( co.signedInfo.timestamp.msec );
-	    
-	    var bytes = [217, 185, 12, 225, 217, 185, 12, 225];
-	    
-	    output += "TimeStamp: "+d;
-	    output+= "<br />";
-	    output += "TimeStamp(number): "+ co.signedInfo.timestamp.msec;
-	    
-	    output+= "<br />";
-	}
-	if(co.signedInfo !=null && co.signedInfo.finalBlockID!=null){
-	    output += "FinalBlockID: "+ DataUtils.toHex(co.signedInfo.finalBlockID);
-	    output+= "<br />";
-	}
-	if(co.signedInfo!=null && co.signedInfo.locator!=null && co.signedInfo.locator.certificate!=null){
-	    var certificateHex = DataUtils.toHex(co.signedInfo.locator.certificate).toLowerCase();
-	    var signature = DataUtils.toHex(co.signature.signature).toLowerCase();
-	    var input = DataUtils.toString(co.rawSignatureData);
-	    
-	    output += "Hex Certificate: "+ certificateHex ;
-	    
-	    output+= "<br />";
-	    output+= "<br />";
-	    
-	    var x509 = new X509();
-	    x509.readCertHex(certificateHex);
-	    output += "Public key (hex) modulus: " + x509.subjectPublicKeyRSA.n.toString(16) + "<br/>";
-	    output += "exponent: " + x509.subjectPublicKeyRSA.e.toString(16) + "<br/>";
-	    output += "<br/>";
-	    
-	    var result = x509.subjectPublicKeyRSA.verifyByteArray(co.rawSignatureData, null, signature);
-	    if(LOG>2) console.log('result is '+result);
-	    
-	    var n = x509.subjectPublicKeyRSA.n;
-	    var e =  x509.subjectPublicKeyRSA.e;
-	    
-	    if(LOG>2) console.log('PUBLIC KEY n after is ');
-	    if(LOG>2) console.log(n);
-
-	    if(LOG>2) console.log('EXPONENT e after is ');
-	    if(LOG>2) console.log(e);
-	    
-	    if(result)
-            output += 'SIGNATURE VALID';
-	    else
-            output += 'SIGNATURE INVALID';
-	    
-	    //output += "VALID: "+ toHex(co.signedInfo.locator.publicKey);
-	    
-	    output+= "<br />";
-	    output+= "<br />";
-	    
-	    //if(LOG>4) console.log('str'[1]);
-	}
-	if(co.signedInfo!=null && co.signedInfo.locator!=null && co.signedInfo.locator.publicKey!=null){
-	    var publickeyHex = DataUtils.toHex(co.signedInfo.locator.publicKey).toLowerCase();
-	    var publickeyString = DataUtils.toString(co.signedInfo.locator.publicKey);
-	    var signature = DataUtils.toHex(co.signature.signature).toLowerCase();
-	    var input = DataUtils.toString(co.rawSignatureData);
-	    
-	    var wit = null;
-	    var witHex = "";
-		if (co.signature.Witness != null) {
-			wit = new Witness();
-			wit.decode(co.signature.Witness);
-			witHex = DataUtils.toHex(co.signature.Witness);
-		}
-	    
-	    output += "Public key: " + publickeyHex;
-	    
-	    output+= "<br />";
-	    output+= "<br />";
-	    
-	    if(LOG>2) console.log(" ContentName + SignedInfo + Content = "+input);
-	    if(LOG>2) console.log(" PublicKeyHex = "+publickeyHex );
-	    if(LOG>2) console.log(" PublicKeyString = "+publickeyString );
-	    
-	    if(LOG>2) console.log(" Signature "+signature );
-	    if(LOG>2) console.log(" Witness "+witHex );
-	    
-	    if(LOG>2) console.log(" Signature NOW IS" );
-	    
-	    if(LOG>2) console.log(co.signature.signature);
-	   
-	    var rsakey = decodeSubjectPublicKeyInfo(co.signedInfo.locator.publicKey);
-
-	    output += "Public key (hex) modulus: " + rsakey.n.toString(16) + "<br/>";
-	    output += "exponent: " + rsakey.e.toString(16) + "<br/>";
-	    output += "<br/>";
-	   	    
-	    var result = rsakey.verifyByteArray(co.rawSignatureData, wit, signature);
-	    // var result = rsakey.verifyString(input, signature);
-	    
-	    if(LOG>2) console.log('PUBLIC KEY n after is ');
-	    if(LOG>2) console.log(rsakey.n);
-
-	    if(LOG>2) console.log('EXPONENT e after is ');
-	    if(LOG>2) console.log(rsakey.e);
-	    
-	    if(result)
-			output += 'SIGNATURE VALID';
-	    else
-			output += 'SIGNATURE INVALID';
-	    
-	    //output += "VALID: "+ toHex(co.signedInfo.locator.publicKey);
-	    
-	    output+= "<br />";
-	    output+= "<br />";
-	    
-	    //if(LOG>4) console.log('str'[1]);
-	}
-    }
-
-    return output;
-}
-
-
-/**
- * @author: Meki Cheraoui
- * See COPYING for copyright and distribution information.
- */
-
-var KeyManager = function KeyManager(){
-
-	
-//Certificate
-
-this.certificate = 'MIIBmzCCAQQCCQC32FyQa61S7jANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd'+
-
-'heGVsY2R2MB4XDTEyMDQyODIzNDQzN1oXDTEyMDUyODIzNDQzN1owEjEQMA4GA1'+
-
-'UEAxMHYXhlbGNkdjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4X0wp9goq'+
-
-'xuECxdULcr2IHr9Ih4Iaypg0Wy39URIup8/CLzQmdsh3RYqd55hqonu5VTTpH3i'+
-
-'MLx6xZDVJAZ8OJi7pvXcQ2C4Re2kjL2c8SanI0RfDhlS1zJadfr1VhRPmpivcYa'+
-
-'wJ4aFuOLAi+qHFxtN7lhcGCgpW1OV60oXd58CAwEAATANBgkqhkiG9w0BAQUFAA'+
-
-'OBgQDLOrA1fXzSrpftUB5Ro6DigX1Bjkf7F5Bkd69hSVp+jYeJFBBlsILQAfSxU'+
-
-'ZPQtD+2Yc3iCmSYNyxqu9PcufDRJlnvB7PG29+L3y9lR37tetzUV9eTscJ7rdp8'+
-
-'Wt6AzpW32IJ/54yKNfP7S6ZIoIG+LP6EIxq6s8K1MXRt8uBJKw==';
-
-
-//this.publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDhfTCn2CirG4QLF1QtyvYgev0iHghrKmDRbLf1REi6nz8IvNCZ2yHdFip3nmGqie7lVNOkfeIwvHrFkNUkBnw4mLum9dxDYLhF7aSMvZzxJqcjRF8OGVLXMlp1+vVWFE+amK9xhrAnhoW44sCL6ocXG03uWFwYKClbU5XrShd3nwIDAQAB';
-this.publicKey ='30819F300D06092A864886F70D010101050003818D0030818902818100E17D30A7D828AB1B840B17542DCAF6207AFD221E086B2A60D16CB7F54448BA9F3F08BCD099DB21DD162A779E61AA89EEE554D3A47DE230BC7AC590D524067C3898BBA6F5DC4360B845EDA48CBD9CF126A723445F0E1952D7325A75FAF556144F9A98AF7186B0278685B8E2C08BEA87171B4DEE585C1828295B5395EB4A17779F0203010001';
-//Private Key
-
-this.privateKey ='MIICXQIBAAKBgQDhfTCn2CirG4QLF1QtyvYgev0iHghrKmDRbLf1REi6nz8IvNCZ2yHdFip3nmGqie7lVNOkfeIwvHrFkNUkBnw4mLum9dxDYLhF7aSMvZzxJqcjRF8OGVLXMlp1+vVWFE+amK9xhrAnhoW44sCL6ocXG03uWFwYKClbU5XrShd3nwIDAQABAoGAGkv6T6jC3WmhFZYL6CdCWvlc6gysmKrhjarrLTxgavtFY6R5g2ft5BXAsCCVbUkWxkIFSKqxpVNl0gKZCNGEzPDN6mHJOQI/h0rlxNIHAuGfoAbCzALnqmyZivhJAPGijAyKuU9tczsst5+Kpn+bn7ehzHQuj7iwJonS5WbojqECQQD851K8TpW2GrRizNgG4dx6orZxAaon/Jnl8lS7soXhllQty7qG+oDfzznmdMsiznCqEABzHUUKOVGE9RWPN3aRAkEA5D/w9N55d0ibnChFJlc8cUAoaqH+w+U3oQP2Lb6AZHJpLptN4y4b/uf5d4wYU5/i/gC7SSBH3wFhh9bjRLUDLwJAVOx8vN0Kqt7myfKNbCo19jxjVSlA8TKCn1Oznl/BU1I+rC4oUaEW25DjmX6IpAR8kq7S59ThVSCQPjxqY/A08QJBAIRaF2zGPITQk3r/VumemCvLWiRK/yG0noc9dtibqHOWbCtcXtOm/xDWjq+lis2i3ssOvYrvrv0/HcDY+Dv1An0CQQCLJtMsfSg4kvG/FRY5UMhtMuwo8ovYcMXt4Xv/LWaMhndD67b2UGawQCRqr5ghRTABWdDD/HuuMBjrkPsX0861';
-
-
-/*
-	this.certificate = 
-			'MIIBvTCCASYCCQD55fNzc0WF7TANBgkqhkiG9w0BAQUFADAjMQswCQYDVQQGEwJK'+
-			'UDEUMBIGA1UEChMLMDAtVEVTVC1SU0EwHhcNMTAwNTI4MDIwODUxWhcNMjAwNTI1'+
-			'MDIwODUxWjAjMQswCQYDVQQGEwJKUDEUMBIGA1UEChMLMDAtVEVTVC1SU0EwgZ8w'+
-			'DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANGEYXtfgDRlWUSDn3haY4NVVQiKI9Cz'+
-			'Thoua9+DxJuiseyzmBBe7Roh1RPqdvmtOHmEPbJ+kXZYhbozzPRbFGHCJyBfCLzQ'+
-			'fVos9/qUQ88u83b0SFA2MGmQWQAlRtLy66EkR4rDRwTj2DzR4EEXgEKpIvo8VBs/'+
-			'3+sHLF3ESgAhAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAEZ6mXFFq3AzfaqWHmCy1'+
-			'ARjlauYAa8ZmUFnLm0emg9dkVBJ63aEqARhtok6bDQDzSJxiLpCEF6G4b/Nv/M/M'+
-			'LyhP+OoOTmETMegAVQMq71choVJyOFE5BtQa6M/lCHEOya5QUfoRF2HF9EjRF44K'+
-			'3OK+u3ivTSj3zwjtpudY5Xo=';
-	
-	this.privateKey =
-			'MIICWwIBAAKBgQDRhGF7X4A0ZVlEg594WmODVVUIiiPQs04aLmvfg8SborHss5gQ'+
-			'Xu0aIdUT6nb5rTh5hD2yfpF2WIW6M8z0WxRhwicgXwi80H1aLPf6lEPPLvN29EhQ'+
-			'NjBpkFkAJUbS8uuhJEeKw0cE49g80eBBF4BCqSL6PFQbP9/rByxdxEoAIQIDAQAB'+
-			'AoGAA9/q3Zk6ib2GFRpKDLO/O2KMnAfR+b4XJ6zMGeoZ7Lbpi3MW0Nawk9ckVaX0'+
-			'ZVGqxbSIX5Cvp/yjHHpww+QbUFrw/gCjLiiYjM9E8C3uAF5AKJ0r4GBPl4u8K4bp'+
-			'bXeSxSB60/wPQFiQAJVcA5xhZVzqNuF3EjuKdHsw+dk+dPECQQDubX/lVGFgD/xY'+
-			'uchz56Yc7VHX+58BUkNSewSzwJRbcueqknXRWwj97SXqpnYfKqZq78dnEF10SWsr'+
-			'/NMKi+7XAkEA4PVqDv/OZAbWr4syXZNv/Mpl4r5suzYMMUD9U8B2JIRnrhmGZPzL'+
-			'x23N9J4hEJ+Xh8tSKVc80jOkrvGlSv+BxwJAaTOtjA3YTV+gU7Hdza53sCnSw/8F'+
-			'YLrgc6NOJtYhX9xqdevbyn1lkU0zPr8mPYg/F84m6MXixm2iuSz8HZoyzwJARi2p'+
-			'aYZ5/5B2lwroqnKdZBJMGKFpUDn7Mb5hiSgocxnvMkv6NjT66Xsi3iYakJII9q8C'+
-			'Ma1qZvT/cigmdbAh7wJAQNXyoizuGEltiSaBXx4H29EdXNYWDJ9SS5f070BRbAIl'+
-			'dqRh3rcNvpY6BKJqFapda1DjdcncZECMizT/GMrc1w==';
-			
-			*/
-};
-
-
-KeyManager.prototype.verify = function verify(message,signature){
-	
-	var input = message;
-
-	var  _PEM_X509CERT_STRING_ = this.certificate;
-	
-	var x509 = new X509();
-	
-	x509.readCertPEM(_PEM_X509CERT_STRING_);
-	
-	var result = x509.subjectPublicKeyRSA.verifyString(input, signature);
-	
-	return result;
-};
-
-KeyManager.prototype.sign= function sign(message){
-	
-	var input = message;
-		
-	var  _PEM_PRIVATE_KEY_STRING_ = this.privateKey;
-	
-	var rsa = new RSAKey();
-	
-	rsa.readPrivateKeyFromPEMString(_PEM_PRIVATE_KEY_STRING_);
-	
-	var hSig = rsa.signString(input, "sha256");
-	
-	return hSig;
-
-};
-
-
-
-var globalKeyManager = new KeyManager();
-//var KeyPair = { "public" : "PUBLIC KEY" , "private" : "PRIVATE KEY" };
-
-
-/** 
- * @author: Wentao Shang
- * See COPYING for copyright and distribution information.
- */
-
-var MerklePath = function MerkelPath() {
-	this.index = null;  // int
-	this.digestList = [];  // array of hex string
-};
-
-var Witness = function Witness() {
-	this.oid = null;  // string
-	this.path = new MerklePath();  // MerklePath
-};
-
-function parseOID(bytes, start, end) {
-    var s, n = 0, bits = 0;
-    for (var i = start; i < end; ++i) {
-        var v = bytes[i];
-        n = (n << 7) | (v & 0x7F);
-        bits += 7;
-        if (!(v & 0x80)) { // finished
-            if (s == undefined)
-                s = parseInt(n / 40) + "." + (n % 40);
-            else
-                s += "." + ((bits >= 31) ? "bigint" : n);
-            n = bits = 0;
-        }
-        s += String.fromCharCode();
-    }
-    return s;
-}
-
-function parseInteger(bytes, start, end) {
-    var n = 0;
-    for (var i = start; i < end; ++i)
-        n = (n << 8) | bytes[i];
-    return n;
-}
-
-Witness.prototype.decode = function(/* Uint8Array */ witness) {
-	/* The asn1.js decoder has some bug and 
-	 * cannot decode certain kind of witness.
-	 * So we use an alternative (and dirty) hack
-	 * to read witness from byte streams
-	 *      ------Wentao
-	 */
-	/*
-	var wit = DataUtils.toHex(witness).toLowerCase();
-	try {
-		var der = Hex.decode(wit);
-		var asn1 = ASN1.decode(der);
-	}
-	catch (e) {
-		console.log(e);
-		console.log(wit);
-	}
-	//console.log(asn1.toPrettyString());
-	
-	this.oid = asn1.sub[0].sub[0].content();  // OID
-	//console.log(this.oid);
-	this.path.index = asn1.sub[1].sub[0].sub[0].content();  // index
-	//console.log(this.path.index);
-	for (i = 0; i < asn1.sub[1].sub[0].sub[1].sub.length; i++) {
-		pos = asn1.sub[1].sub[0].sub[1].sub[i].stream.pos;
-		str = wit.substring(2 * pos + 4, 2 * pos + 68);
-		this.path.digestList.push(str);  // digest hex string
-		//console.log(str);
-	}
-	*/
-	
-	// FIXME: Need to be fixed to support arbitrary ASN1 encoding,
-	// But do we really nned that????  -------Wentao
-	
-	// The structure of Witness is fixed as follows:
-	// SEQUENCE  (2 elem)
-	//   SEQUENCE  (1 elem)
-	//     OBJECT IDENTIFIER  1.2.840.113550.11.1.2.2
-	//   OCTET STRING  (1 elem)
-	//     SEQUENCE  (2 elem)
-	//       INTEGER  index
-	//       SEQUENCE  (n elem)
-	//         OCTET STRING(32 byte) 345FB4B5E9A1D2FF450ECA87EB87601683027A1A...
-	//         OCTET STRING(32 byte) DBCEE5B7A6C2B851B029324197DDBD9A655723DC...
-	//         OCTET STRING(32 byte) 4C79B2D256E4CD657A27F01DCB51AC3C56A24E71...
-	//         OCTET STRING(32 byte) 7F7FB169604A87EAC94378F0BDB4FC5D5899AB88...
-	//         ......
-	// Hence we can follow this structure to extract witness fields at fixed level
-	// Tag numbers for ASN1:
-	//    SEQUENCE            0x10
-	//    OCT STRING          0x04
-	//    INTEGER             0x02
-	//    OBJECT IDENTIFIER   0x06
-	var i = 0;
-	var step = 0;  // count of sequence tag
-	while (i < witness.length) {
-		var len = 0;
-		
-		if (witness[i] == 0x30) {
-			// Sequence (constructed)
-			// There is no primitive sequence in Witness
-			if ((witness[i + 1] & 0x80) != 0) {
-				len = witness[i+1] & 0x7F;
-			}
-			step++;
-		} else if (witness[i] == 0x06) {
-			// Decode OID
-			len = witness[i+1];  // XXX: OID will not be longer than 127 bytes
-			this.oid = parseOID(witness, i + 2, i + 2 + len);
-			//console.log(this.oid);
-		} else if (witness[i] == 0x02) {
-			// Decode node index
-			len = witness[i+1];  // XXX: index will not be longer than 127 bytes
-			this.path.index = parseInteger(witness, i + 2, i + 2 + len);
-			//console.log(this.path.index);
-		} else if (witness[i] == 0x04) {
-			if ((witness[i + 1] & 0x80) != 0) {
-				len = witness[i+1] & 0x7F;
-			}
-			if (step == 4) {
-				// Start to decode digest hex string
-				len = witness[i+1];  // XXX: digest hex should always be 32 bytes
-				var str = DataUtils.toHex(witness.subarray(i + 2, i + 2 + len));
-				this.path.digestList.push(str);  // digest hex string
-				//console.log(str);
-			}
-		}
-		i = i + 2 + len;
-	}
-};
-/*
- * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
- * in FIPS 180-2
- * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009.
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for details.
- * Also http://anmar.eu.org/projects/jssha2/
- */
-
-/*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
-var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
-var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
-
-/*
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
-
-//@author axelcdv
-/**
- * Computes the Sha-256 hash of the given byte array
- * @param {byte[]} 
- * @return the hex string corresponding to the Sha-256 hash of the byte array
- */
-function hex_sha256_from_bytes(byteArray){
-	return rstr2hex(binb2rstr(binb_sha256( byteArray2binb(byteArray), byteArray.length * 8)));
-}
-
-function hex_sha256(s)    { return rstr2hex(rstr_sha256(str2rstr_utf8(s))); }
-function b64_sha256(s)    { return rstr2b64(rstr_sha256(str2rstr_utf8(s))); }
-function any_sha256(s, e) { return rstr2any(rstr_sha256(str2rstr_utf8(s)), e); }
-function hex_hmac_sha256(k, d)
-  { return rstr2hex(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function b64_hmac_sha256(k, d)
-  { return rstr2b64(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function any_hmac_sha256(k, d, e)
-  { return rstr2any(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
-
-	
-/*
-	function hex_sha256(s)    { return rstr2hex(rstr_sha256(s)); }
-function b64_sha256(s)    { return rstr2b64(rstr_sha256(s)); }
-function any_sha256(s, e) { return rstr2any(rstr_sha256(s), e); }
-function hex_hmac_sha256(k, d)
-  { return rstr2hex(rstr_hmac_sha256(str2rstr_utf8(k), d)); }
-function b64_hmac_sha256(k, d)
-  { return rstr2b64(rstr_hmac_sha256(str2rstr_utf8(k), d)); }
-function any_hmac_sha256(k, d, e)
-  { return rstr2any(rstr_hmac_sha256(str2rstr_utf8(k), d), e); }
-*/
-	
-/*
- * Perform a simple self-test to see if the VM is working
- */
-function sha256_vm_test()
-{
-  return hex_sha256("abc").toLowerCase() ==
-            "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad";
-}
-
-/**
- * Calculate the sha256 of a raw string
- * @param s: the raw string
- */
-function rstr_sha256(s)
-{
-  return binb2rstr(binb_sha256(rstr2binb(s), s.length * 8));
-}
-
-/**
- * Calculate the HMAC-sha256 of a key and some data (raw strings)
- */
-function rstr_hmac_sha256(key, data)
-{
-  var bkey = rstr2binb(key);
-  if(bkey.length > 16) bkey = binb_sha256(bkey, key.length * 8);
-
-  var ipad = Array(16), opad = Array(16);
-  for(var i = 0; i < 16; i++)
-  {
-    ipad[i] = bkey[i] ^ 0x36363636;
-    opad[i] = bkey[i] ^ 0x5C5C5C5C;
-  }
-
-  var hash = binb_sha256(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
-  return binb2rstr(binb_sha256(opad.concat(hash), 512 + 256));
-}
-
-/**
- * Convert a raw string to a hex string
- */
-function rstr2hex(input)
-{
-  try { hexcase } catch(e) { hexcase=0; }
-  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
-  var output = "";
-  var x;
-  for(var i = 0; i < input.length; i++)
-  {
-    x = input.charCodeAt(i);
-    output += hex_tab.charAt((x >>> 4) & 0x0F)
-           +  hex_tab.charAt( x        & 0x0F);
-  }
-  return output;
-}
-
-/*
- * Convert a raw string to a base-64 string
- */
-function rstr2b64(input)
-{
-  try { b64pad } catch(e) { b64pad=''; }
-  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-  var output = "";
-  var len = input.length;
-  for(var i = 0; i < len; i += 3)
-  {
-    var triplet = (input.charCodeAt(i) << 16)
-                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
-                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
-    for(var j = 0; j < 4; j++)
-    {
-      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
-      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
-    }
-  }
-  return output;
-}
-
-/*
- * Convert a raw string to an arbitrary string encoding
- */
-function rstr2any(input, encoding)
-{
-  var divisor = encoding.length;
-  var remainders = Array();
-  var i, q, x, quotient;
-
-  /* Convert to an array of 16-bit big-endian values, forming the dividend */
-  var dividend = Array(Math.ceil(input.length / 2));
-  for(i = 0; i < dividend.length; i++)
-  {
-    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
-  }
-
-  /*
-   * Repeatedly perform a long division. The binary array forms the dividend,
-   * the length of the encoding is the divisor. Once computed, the quotient
-   * forms the dividend for the next step. We stop when the dividend is zero.
-   * All remainders are stored for later use.
-   */
-  while(dividend.length > 0)
-  {
-    quotient = Array();
-    x = 0;
-    for(i = 0; i < dividend.length; i++)
-    {
-      x = (x << 16) + dividend[i];
-      q = Math.floor(x / divisor);
-      x -= q * divisor;
-      if(quotient.length > 0 || q > 0)
-        quotient[quotient.length] = q;
-    }
-    remainders[remainders.length] = x;
-    dividend = quotient;
-  }
-
-  /* Convert the remainders to the output string */
-  var output = "";
-  for(i = remainders.length - 1; i >= 0; i--)
-    output += encoding.charAt(remainders[i]);
-
-  /* Append leading zero equivalents */
-  var full_length = Math.ceil(input.length * 8 /
-                                    (Math.log(encoding.length) / Math.log(2)))
-  for(i = output.length; i < full_length; i++)
-    output = encoding[0] + output;
-
-  return output;
-}
-
-/*
- * Encode a string as utf-8.
- * For efficiency, this assumes the input is valid utf-16.
- */
-function str2rstr_utf8(input)
-{
-  var output = "";
-  var i = -1;
-  var x, y;
-
-  while(++i < input.length)
-  {
-    /* Decode utf-16 surrogate pairs */
-    x = input.charCodeAt(i);
-    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
-    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
-    {
-      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
-      i++;
-    }
-
-    /* Encode output as utf-8 */
-    if(x <= 0x7F)
-      output += String.fromCharCode(x);
-    else if(x <= 0x7FF)
-      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
-                                    0x80 | ( x         & 0x3F));
-    else if(x <= 0xFFFF)
-      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
-                                    0x80 | ((x >>> 6 ) & 0x3F),
-                                    0x80 | ( x         & 0x3F));
-    else if(x <= 0x1FFFFF)
-      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
-                                    0x80 | ((x >>> 12) & 0x3F),
-                                    0x80 | ((x >>> 6 ) & 0x3F),
-                                    0x80 | ( x         & 0x3F));
-  }
-  return output;
-}
-
-/*
- * Encode a string as utf-16
- */
-function str2rstr_utf16le(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length; i++)
-    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
-                                  (input.charCodeAt(i) >>> 8) & 0xFF);
-  return output;
-}
-
-function str2rstr_utf16be(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length; i++)
-    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
-                                   input.charCodeAt(i)        & 0xFF);
-  return output;
-}
-
-/**
- * Convert a raw string to an array of big-endian words
- * Characters >255 have their high-byte silently ignored.
- */
-function rstr2binb(input)
-{
-  //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;
-}
-
-/**
- * @author axelcdv
- * Convert a byte array to an array of big-endian words
- * @param {byte[]} input
- * @return the array of big-endian words
- */
-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;
-}
-
-/*
- * Convert an array of big-endian words to a string
- */
-function binb2rstr(input)
-{
-  var output = "";
-  for(var i = 0; i < input.length * 32; i += 8)
-    output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
-  return output;
-}
-
-/*
- * Main sha256 function, with its support functions
- */
-function sha256_S (X, n) {return ( X >>> n ) | (X << (32 - n));}
-function sha256_R (X, n) {return ( X >>> n );}
-function sha256_Ch(x, y, z) {return ((x & y) ^ ((~x) & z));}
-function sha256_Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));}
-function sha256_Sigma0256(x) {return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));}
-function sha256_Sigma1256(x) {return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));}
-function sha256_Gamma0256(x) {return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));}
-function sha256_Gamma1256(x) {return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));}
-function sha256_Sigma0512(x) {return (sha256_S(x, 28) ^ sha256_S(x, 34) ^ sha256_S(x, 39));}
-function sha256_Sigma1512(x) {return (sha256_S(x, 14) ^ sha256_S(x, 18) ^ sha256_S(x, 41));}
-function sha256_Gamma0512(x) {return (sha256_S(x, 1)  ^ sha256_S(x, 8) ^ sha256_R(x, 7));}
-function sha256_Gamma1512(x) {return (sha256_S(x, 19) ^ sha256_S(x, 61) ^ sha256_R(x, 6));}
-
-var sha256_K = new Array
-(
-  1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993,
-  -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987,
-  1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522,
-  264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986,
-  -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585,
-  113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291,
-  1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885,
-  -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344,
-  430227734, 506948616, 659060556, 883997877, 958139571, 1322822218,
-  1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872,
-  -1866530822, -1538233109, -1090935817, -965641998
-);
-
-function binb_sha256(m, l)
-{
-  var HASH = new Array(1779033703, -1150833019, 1013904242, -1521486534,
-                       1359893119, -1694144372, 528734635, 1541459225);
-  var W = new Array(64);
-
-  /* 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);
-
-  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];
-    d = HASH[3];
-    e = HASH[4];
-    f = HASH[5];
-    g = HASH[6];
-    h = HASH[7];
-
-    for(j = 0; j < 64; j++)
-    {
-      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]);
-
-      T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)),
-                                                          sha256_K[j]), W[j]);
-      T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c));
-      h = g;
-      g = f;
-      f = e;
-      e = safe_add(d, T1);
-      d = c;
-      c = b;
-      b = a;
-      a = safe_add(T1, T2);
-    }
-
-    HASH[0] = safe_add(a, HASH[0]);
-    HASH[1] = safe_add(b, HASH[1]);
-    HASH[2] = safe_add(c, HASH[2]);
-    HASH[3] = safe_add(d, HASH[3]);
-    HASH[4] = safe_add(e, HASH[4]);
-    HASH[5] = safe_add(f, HASH[5]);
-    HASH[6] = safe_add(g, HASH[6]);
-    HASH[7] = safe_add(h, HASH[7]);
-}
-
-function safe_add (x, y)
-{
-  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
-  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;
-}
-var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-var b64pad="=";
-
-function hex2b64(h) {
-  var i;
-  var c;
-  var ret = "";
-  for(i = 0; i+3 <= h.length; i+=3) {
-    c = parseInt(h.substring(i,i+3),16);
-    ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);
-  }
-  if(i+1 == h.length) {
-    c = parseInt(h.substring(i,i+1),16);
-    ret += b64map.charAt(c << 2);
-  }
-  else if(i+2 == h.length) {
-    c = parseInt(h.substring(i,i+2),16);
-    ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);
-  }
-  while((ret.length & 3) > 0) ret += b64pad;
-  return ret;
-}
-
-// convert a base64 string to hex
-function b64tohex(s) {
-  var ret = ""
-  var i;
-  var k = 0; // b64 state, 0-3
-  var slop;
-  for(i = 0; i < s.length; ++i) {
-    if(s.charAt(i) == b64pad) break;
-    var v = b64map.indexOf(s.charAt(i));
-    if(v < 0) continue;
-    if(k == 0) {
-      ret += int2char(v >> 2);
-      slop = v & 3;
-      k = 1;
-    }
-    else if(k == 1) {
-      ret += int2char((slop << 2) | (v >> 4));
-      slop = v & 0xf;
-      k = 2;
-    }
-    else if(k == 2) {
-      ret += int2char(slop);
-      ret += int2char(v >> 2);
-      slop = v & 3;
-      k = 3;
-    }
-    else {
-      ret += int2char((slop << 2) | (v >> 4));
-      ret += int2char(v & 0xf);
-      k = 0;
-    }
-  }
-  if(k == 1)
-    ret += int2char(slop << 2);
-  return ret;
-}
-
-// convert a base64 string to a byte/number array
-function b64toBA(s) {
-  //piggyback on b64tohex for now, optimize later
-  var h = b64tohex(s);
-  var i;
-  var a = new Array();
-  for(i = 0; 2*i < h.length; ++i) {
-    a[i] = parseInt(h.substring(2*i,2*i+2),16);
-  }
-  return a;
-}
-// Depends on jsbn.js and rng.js
-
-// Version 1.1: support utf-8 encoding in pkcs1pad2
-
-// convert a (hex) string to a bignum object
-function parseBigInt(str,r) {
-  return new BigInteger(str,r);
-}
-
-function linebrk(s,n) {
-  var ret = "";
-  var i = 0;
-  while(i + n < s.length) {
-    ret += s.substring(i,i+n) + "\n";
-    i += n;
-  }
-  return ret + s.substring(i,s.length);
-}
-
-function byte2Hex(b) {
-  if(b < 0x10)
-    return "0" + b.toString(16);
-  else
-    return b.toString(16);
-}
-
-/**
- * PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
- * @param s: the string to encode
- * @param n: the size in byte
- */ 
-function pkcs1pad2(s,n) {
-  if(n < s.length + 11) { // TODO: fix for utf-8
-    alert("Message too long for RSA");
-    return null;
-  }
-  var ba = new Array();
-  var i = s.length - 1;
-  while(i >= 0 && n > 0) {
-    var c = s.charCodeAt(i--);
-    if(c < 128) { // encode using utf-8
-      ba[--n] = c;
-    }
-    else if((c > 127) && (c < 2048)) {
-      ba[--n] = (c & 63) | 128;
-      ba[--n] = (c >> 6) | 192;
-    }
-    else {
-      ba[--n] = (c & 63) | 128;
-      ba[--n] = ((c >> 6) & 63) | 128;
-      ba[--n] = (c >> 12) | 224;
-    }
-  }
-  ba[--n] = 0;
-  var rng = new SecureRandom();
-  var x = new Array();
-  while(n > 2) { // random non-zero pad
-    x[0] = 0;
-    while(x[0] == 0) rng.nextBytes(x);
-    ba[--n] = x[0];
-  }
-  ba[--n] = 2;
-  ba[--n] = 0;
-  return new BigInteger(ba);
-}
-
-/** 
- * "empty" RSA key constructor
- * @returns {RSAKey}
- */
-function RSAKey() {
-  this.n = null;
-  this.e = 0;
-  this.d = null;
-  this.p = null;
-  this.q = null;
-  this.dmp1 = null;
-  this.dmq1 = null;
-  this.coeff = null;
-}
-
-/** 
- * Set the public key fields N and e from hex strings
- * @param N
- * @param E
- * @returns {RSASetPublic}
- */
-function RSASetPublic(N,E) {
-  if(N != null && E != null && N.length > 0 && E.length > 0) {
-    this.n = parseBigInt(N,16);
-    this.e = parseInt(E,16);
-  }
-  else
-    alert("Invalid RSA public key");
-}
-
-/** 
- * Perform raw public operation on "x": return x^e (mod n)
- * @param x
- * @returns x^e (mod n)
- */
-function RSADoPublic(x) {
-  return x.modPowInt(this.e, this.n);
-}
-
-/**
- * Return the PKCS#1 RSA encryption of "text" as an even-length hex string
- */ 
-function RSAEncrypt(text) {
-  var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3);
-  if(m == null) return null;
-  var c = this.doPublic(m);
-  if(c == null) return null;
-  var h = c.toString(16);
-  if((h.length & 1) == 0) return h; else return "0" + h;
-}
-
-// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string
-//function RSAEncryptB64(text) {
-//  var h = this.encrypt(text);
-//  if(h) return hex2b64(h); else return null;
-//}
-
-// protected
-RSAKey.prototype.doPublic = RSADoPublic;
-
-// public
-RSAKey.prototype.setPublic = RSASetPublic;
-RSAKey.prototype.encrypt = RSAEncrypt;
-//RSAKey.prototype.encrypt_b64 = RSAEncryptB64;
-// Depends on rsa.js and jsbn2.js
-
-// Version 1.1: support utf-8 decoding in pkcs1unpad2
-
-// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext
-function pkcs1unpad2(d,n) {
-  var b = d.toByteArray();
-  var i = 0;
-  while(i < b.length && b[i] == 0) ++i;
-  if(b.length-i != n-1 || b[i] != 2)
-    return null;
-  ++i;
-  while(b[i] != 0)
-    if(++i >= b.length) return null;
-  var ret = "";
-  while(++i < b.length) {
-    var c = b[i] & 255;
-    if(c < 128) { // utf-8 decode
-      ret += String.fromCharCode(c);
-    }
-    else if((c > 191) && (c < 224)) {
-      ret += String.fromCharCode(((c & 31) << 6) | (b[i+1] & 63));
-      ++i;
-    }
-    else {
-      ret += String.fromCharCode(((c & 15) << 12) | ((b[i+1] & 63) << 6) | (b[i+2] & 63));
-      i += 2;
-    }
-  }
-  return ret;
-}
-
-// Set the private key fields N, e, and d from hex strings
-function RSASetPrivate(N,E,D) {
-  if(N != null && E != null && N.length > 0 && E.length > 0) {
-    this.n = parseBigInt(N,16);
-    this.e = parseInt(E,16);
-    this.d = parseBigInt(D,16);
-  }
-  else
-    alert("Invalid RSA private key");
-}
-
-// Set the private key fields N, e, d and CRT params from hex strings
-function RSASetPrivateEx(N,E,D,P,Q,DP,DQ,C) {
-  if(N != null && E != null && N.length > 0 && E.length > 0) {
-    this.n = parseBigInt(N,16);
-    this.e = parseInt(E,16);
-    this.d = parseBigInt(D,16);
-    this.p = parseBigInt(P,16);
-    this.q = parseBigInt(Q,16);
-    this.dmp1 = parseBigInt(DP,16);
-    this.dmq1 = parseBigInt(DQ,16);
-    this.coeff = parseBigInt(C,16);
-  }
-  else
-    alert("Invalid RSA private key");
-}
-
-/**
- * Generate a new random private key B bits long, using public expt E
- */
-function RSAGenerate(B,E) {
-  var rng = new SecureRandom();
-  var qs = B>>1;
-  this.e = parseInt(E,16);
-  var ee = new BigInteger(E,16);
-  for(;;) {
-    for(;;) {
-      this.p = new BigInteger(B-qs,1,rng);
-      if(this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) break;
-    }
-    for(;;) {
-      this.q = new BigInteger(qs,1,rng);
-      if(this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) break;
-    }
-    if(this.p.compareTo(this.q) <= 0) {
-      var t = this.p;
-      this.p = this.q;
-      this.q = t;
-    }
-    var p1 = this.p.subtract(BigInteger.ONE);	// p1 = p - 1
-    var q1 = this.q.subtract(BigInteger.ONE);	// q1 = q - 1
-    var phi = p1.multiply(q1);
-    if(phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
-      this.n = this.p.multiply(this.q);	// this.n = p * q
-      this.d = ee.modInverse(phi);	// this.d = 
-      this.dmp1 = this.d.mod(p1);	// this.dmp1 = d mod (p - 1)
-      this.dmq1 = this.d.mod(q1);	// this.dmq1 = d mod (q - 1)
-      this.coeff = this.q.modInverse(this.p);	// this.coeff = (q ^ -1) mod p
-      break;
-    }
-  }
-}
-
-/**
- * Perform raw private operation on "x": return x^d (mod n)
- * @return x^d (mod n)
- */ 
-function RSADoPrivate(x) {
-  if(this.p == null || this.q == null)
-    return x.modPow(this.d, this.n);
-
-  // TODO: re-calculate any missing CRT params
-  var xp = x.mod(this.p).modPow(this.dmp1, this.p); // xp=cp?
-  var xq = x.mod(this.q).modPow(this.dmq1, this.q); // xq=cq?
-
-  while(xp.compareTo(xq) < 0)
-    xp = xp.add(this.p);
-  // NOTE:
-  // xp.subtract(xq) => cp -cq
-  // xp.subtract(xq).multiply(this.coeff).mod(this.p) => (cp - cq) * u mod p = h
-  // xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq) => cq + (h * q) = M
-  return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq);
-}
-
-// Return the PKCS#1 RSA decryption of "ctext".
-// "ctext" is an even-length hex string and the output is a plain string.
-function RSADecrypt(ctext) {
-  var c = parseBigInt(ctext, 16);
-  var m = this.doPrivate(c);
-  if(m == null) return null;
-  return pkcs1unpad2(m, (this.n.bitLength()+7)>>3);
-}
-
-// Return the PKCS#1 RSA decryption of "ctext".
-// "ctext" is a Base64-encoded string and the output is a plain string.
-//function RSAB64Decrypt(ctext) {
-//  var h = b64tohex(ctext);
-//  if(h) return this.decrypt(h); else return null;
-//}
-
-// protected
-RSAKey.prototype.doPrivate = RSADoPrivate;
-
-// public
-RSAKey.prototype.setPrivate = RSASetPrivate;
-RSAKey.prototype.setPrivateEx = RSASetPrivateEx;
-RSAKey.prototype.generate = RSAGenerate;
-RSAKey.prototype.decrypt = RSADecrypt;
-//RSAKey.prototype.b64_decrypt = RSAB64Decrypt;
-/*! rsapem-1.1.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
- */
-//
-// rsa-pem.js - adding function for reading/writing PKCS#1 PEM private key
-//              to RSAKey class.
-//
-// version: 1.1 (2012-May-10)
-//
-// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
-//
-// This software is licensed under the terms of the MIT License.
-// http://kjur.github.com/jsrsasign/license/
-//
-// The above copyright and license notice shall be 
-// included in all copies or substantial portions of the Software.
-// 
-//
-// Depends on:
-//
-//
-//
-// _RSApem_pemToBase64(sPEM)
-//
-//   removing PEM header, PEM footer and space characters including
-//   new lines from PEM formatted RSA private key string.
-//
-
-function _rsapem_pemToBase64(sPEMPrivateKey) {
-  var s = sPEMPrivateKey;
-  s = s.replace("-----BEGIN RSA PRIVATE KEY-----", "");
-  s = s.replace("-----END RSA PRIVATE KEY-----", "");
-  s = s.replace(/[ \n]+/g, "");
-  return s;
-}
-
-function _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey) {
-  var a = new Array();
-  var v1 = ASN1HEX.getStartPosOfV_AtObj(hPrivateKey, 0);
-  var n1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, v1);
-  var e1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, n1);
-  var d1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, e1);
-  var p1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, d1);
-  var q1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, p1);
-  var dp1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, q1);
-  var dq1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, dp1);
-  var co1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, dq1);
-  a.push(v1, n1, e1, d1, p1, q1, dp1, dq1, co1);
-  return a;
-}
-
-function _rsapem_getHexValueArrayOfChildrenFromHex(hPrivateKey) {
-  var posArray = _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey);
-  var v =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[0]);
-  var n =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[1]);
-  var e =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[2]);
-  var d =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[3]);
-  var p =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[4]);
-  var q =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[5]);
-  var dp = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[6]);
-  var dq = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[7]);
-  var co = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[8]);
-  var a = new Array();
-  a.push(v, n, e, d, p, q, dp, dq, co);
-  return a;
-}
-
-/**
- * read PKCS#1 private key from a string
- * @name readPrivateKeyFromPEMString
- * @memberOf RSAKey#
- * @function
- * @param {String} keyPEM string of PKCS#1 private key.
- */
-function _rsapem_readPrivateKeyFromPEMString(keyPEM) {
-  var keyB64 = _rsapem_pemToBase64(keyPEM);
-  var keyHex = b64tohex(keyB64) // depends base64.js
-  var a = _rsapem_getHexValueArrayOfChildrenFromHex(keyHex);
-  this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]);
-}
-
-RSAKey.prototype.readPrivateKeyFromPEMString = _rsapem_readPrivateKeyFromPEMString;
-/*! rsasign-1.2.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
- */
-//
-// rsa-sign.js - adding signing functions to RSAKey class.
-//
-//
-// version: 1.2.1 (08 May 2012)
-//
-// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
-//
-// This software is licensed under the terms of the MIT License.
-// http://kjur.github.com/jsrsasign/license/
-//
-// The above copyright and license notice shall be 
-// included in all copies or substantial portions of the Software.
-
-//
-// Depends on:
-//   function sha1.hex(s) of sha1.js
-//   jsbn.js
-//   jsbn2.js
-//   rsa.js
-//   rsa2.js
-//
-
-// keysize / pmstrlen
-//  512 /  128
-// 1024 /  256
-// 2048 /  512
-// 4096 / 1024
-
-/**
- * @property {Dictionary} _RSASIGN_DIHEAD
- * @description Array of head part of hexadecimal DigestInfo value for hash algorithms.
- * You can add any DigestInfo hash algorith for signing.
- * See PKCS#1 v2.1 spec (p38).
- */
-var _RSASIGN_DIHEAD = [];
-_RSASIGN_DIHEAD['sha1'] =      "3021300906052b0e03021a05000414";
-_RSASIGN_DIHEAD['sha256'] =    "3031300d060960864801650304020105000420";
-_RSASIGN_DIHEAD['sha384'] =    "3041300d060960864801650304020205000430";
-_RSASIGN_DIHEAD['sha512'] =    "3051300d060960864801650304020305000440";
-_RSASIGN_DIHEAD['md2'] =       "3020300c06082a864886f70d020205000410";
-_RSASIGN_DIHEAD['md5'] =       "3020300c06082a864886f70d020505000410";
-_RSASIGN_DIHEAD['ripemd160'] = "3021300906052b2403020105000414";
-
-/**
- * @property {Dictionary} _RSASIGN_HASHHEXFUNC
- * @description Array of functions which calculate hash and returns it as hexadecimal.
- * You can add any hash algorithm implementations.
- */
-var _RSASIGN_HASHHEXFUNC = [];
-_RSASIGN_HASHHEXFUNC['sha1'] =      function(s){return hex_sha1(s);};  // http://pajhome.org.uk/crypt/md5/md5.html
-_RSASIGN_HASHHEXFUNC['sha256'] =    function(s){return hex_sha256(s);} // http://pajhome.org.uk/crypt/md5/md5.html
-_RSASIGN_HASHHEXFUNC['sha512'] =    function(s){return hex_sha512(s);} // http://pajhome.org.uk/crypt/md5/md5.html
-_RSASIGN_HASHHEXFUNC['md5'] =       function(s){return hex_md5(s);};   // http://pajhome.org.uk/crypt/md5/md5.html
-_RSASIGN_HASHHEXFUNC['ripemd160'] = function(s){return hex_rmd160(s);};   // http://pajhome.org.uk/crypt/md5/md5.html
-
-//@author axelcdv
-var _RSASIGN_HASHBYTEFUNC = [];
-_RSASIGN_HASHBYTEFUNC['sha256'] = 	function(byteArray){return hex_sha256_from_bytes(byteArray);};
-
-//_RSASIGN_HASHHEXFUNC['sha1'] =   function(s){return sha1.hex(s);}   // http://user1.matsumoto.ne.jp/~goma/js/hash.html
-//_RSASIGN_HASHHEXFUNC['sha256'] = function(s){return sha256.hex;}    // http://user1.matsumoto.ne.jp/~goma/js/hash.html
-
-var _RE_HEXDECONLY = new RegExp("");
-_RE_HEXDECONLY.compile("[^0-9a-f]", "gi");
-
-// ========================================================================
-// Signature Generation
-// ========================================================================
-
-function _rsasign_getHexPaddedDigestInfoForString(s, keySize, hashAlg) {
-  var pmStrLen = keySize / 4;
-  var hashFunc = _RSASIGN_HASHHEXFUNC[hashAlg];
-  var sHashHex = hashFunc(s);
-
-  var sHead = "0001";
-  var sTail = "00" + _RSASIGN_DIHEAD[hashAlg] + sHashHex;
-  var sMid = "";
-  var fLen = pmStrLen - sHead.length - sTail.length;
-  for (var i = 0; i < fLen; i += 2) {
-    sMid += "ff";
-  }
-  sPaddedMessageHex = sHead + sMid + sTail;
-  return sPaddedMessageHex;
-}
-
-
-//@author: Meki Cheraoui
-function _rsasign_getHexPaddedDigestInfoForStringHEX(s, keySize, hashAlg) {
-  var pmStrLen = keySize / 4;
-  var hashFunc = _RSASIGN_HASHHEXFUNC[hashAlg];
-  var sHashHex = hashFunc(s);
-
-  var sHead = "0001";
-  var sTail = "00" + _RSASIGN_DIHEAD[hashAlg] + sHashHex;
-  var sMid = "";
-  var fLen = pmStrLen - sHead.length - sTail.length;
-  for (var i = 0; i < fLen; i += 2) {
-    sMid += "ff";
-  }
-  sPaddedMessageHex = sHead + sMid + sTail;
-  return sPaddedMessageHex;
-}
-
-/**
- * Apply padding, then computes the hash of the given byte array, according to the key size and with the hash algorithm
- * @param byteArray (byte[])
- * @param keySize (int)
- * @param hashAlg the hash algorithm to apply (string)
- * @return the hash of byteArray
- */
-function _rsasign_getHexPaddedDigestInfoForByteArray(byteArray, keySize, hashAlg){
-	var pmStrLen = keySize / 4;
-	var hashFunc = _RSASIGN_HASHBYTEFUNC[hashAlg];
-	var sHashHex = hashFunc(byteArray); //returns hex hash
-	
-	var sHead = "0001";
-	  var sTail = "00" + _RSASIGN_DIHEAD[hashAlg] + sHashHex;
-	  var sMid = "";
-	  var fLen = pmStrLen - sHead.length - sTail.length;
-	  for (var i = 0; i < fLen; i += 2) {
-	    sMid += "ff";
-	  }
-	  sPaddedMessageHex = sHead + sMid + sTail;
-	  return sPaddedMessageHex;
-}
-
-function _zeroPaddingOfSignature(hex, bitLength) {
-  var s = "";
-  var nZero = bitLength / 4 - hex.length;
-  for (var i = 0; i < nZero; i++) {
-    s = s + "0";
-  }
-  return s + hex;
-}
-
-/**
- * sign for a message string with RSA private key.<br/>
- * @name signString
- * @memberOf RSAKey#
- * @function
- * @param {String} s message string to be signed.
- * @param {String} hashAlg hash algorithm name for signing.<br/>
- * @return returns hexadecimal string of signature value.
- */
-function _rsasign_signString(s, hashAlg) {
-  //alert("this.n.bitLength() = " + this.n.bitLength());
-  var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), hashAlg);
-  var biPaddedMessage = parseBigInt(hPM, 16);
-  var biSign = this.doPrivate(biPaddedMessage);
-  var hexSign = biSign.toString(16);
-  return _zeroPaddingOfSignature(hexSign, this.n.bitLength());
-}
-
-//@author: ucla-cs
-function _rsasign_signStringHEX(s, hashAlg) {
-  //alert("this.n.bitLength() = " + this.n.bitLength());
-  var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), hashAlg);
-  var biPaddedMessage = parseBigInt(hPM, 16);
-  var biSign = this.doPrivate(biPaddedMessage);
-  var hexSign = biSign.toString(16);
-  return _zeroPaddingOfSignature(hexSign, this.n.bitLength());
-}
-
-
-/**
- * Sign a message byteArray with an RSA private key
- * @name signByteArray
- * @memberOf RSAKey#
- * @function
- * @param {byte[]} byteArray
- * @param {Sring} hashAlg the hash algorithm to apply
- * @param {RSAKey} rsa key to sign with: hack because the context is lost here
- * @return hexadecimal string of signature value
- */
-function _rsasign_signByteArray(byteArray, hashAlg, rsaKey) {
-	var hPM = _rsasign_getHexPaddedDigestInfoForByteArray(byteArray, rsaKey.n.bitLength(), hashAlg); ///hack because the context is lost here
-	var biPaddedMessage = parseBigInt(hPM, 16);
-	var biSign = rsaKey.doPrivate(biPaddedMessage); //hack because the context is lost here
-	var hexSign = biSign.toString(16);
-	return _zeroPaddingOfSignature(hexSign, rsaKey.n.bitLength()); //hack because the context is lost here
-}
-
-/**
- * Sign a byte array with the Sha-256 algorithm
- * @param {byte[]} byteArray
- * @return hexadecimal string of signature value
- */
-function _rsasign_signByteArrayWithSHA256(byteArray){
-	return _rsasign_signByteArray(byteArray, 'sha256', this); //Hack because the context is lost in the next function
-}
-
-
-function _rsasign_signStringWithSHA1(s) {
-  return _rsasign_signString(s, 'sha1');
-}
-
-function _rsasign_signStringWithSHA256(s) {
-  return _rsasign_signString(s, 'sha256');
-}
-
-// ========================================================================
-// Signature Verification
-// ========================================================================
-
-function _rsasign_getDecryptSignatureBI(biSig, hN, hE) {
-  var rsa = new RSAKey();
-  rsa.setPublic(hN, hE);
-  var biDecryptedSig = rsa.doPublic(biSig);
-  return biDecryptedSig;
-}
-
-function _rsasign_getHexDigestInfoFromSig(biSig, hN, hE) {
-  var biDecryptedSig = _rsasign_getDecryptSignatureBI(biSig, hN, hE);
-  var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
-  return hDigestInfo;
-}
-
-function _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo) {
-  for (var algName in _RSASIGN_DIHEAD) {
-    var head = _RSASIGN_DIHEAD[algName];
-    var len = head.length;
-    if (hDigestInfo.substring(0, len) == head) {
-      var a = [algName, hDigestInfo.substring(len)];
-      return a;
-    }
-  }
-  return [];
-}
-
-function _rsasign_verifySignatureWithArgs(sMsg, biSig, hN, hE) {
-  var hDigestInfo = _rsasign_getHexDigestInfoFromSig(biSig, hN, hE);
-  var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);
-  if (digestInfoAry.length == 0) return false;
-  var algName = digestInfoAry[0];
-  var diHashValue = digestInfoAry[1];
-  var ff = _RSASIGN_HASHHEXFUNC[algName];
-  var msgHashValue = ff(sMsg);
-  return (diHashValue == msgHashValue);
-}
-
-function _rsasign_verifyHexSignatureForMessage(hSig, sMsg) {
-  var biSig = parseBigInt(hSig, 16);
-  var result = _rsasign_verifySignatureWithArgs(sMsg, biSig,
-						this.n.toString(16),
-						this.e.toString(16));
-  return result;
-}
-
-/**
- * verifies a sigature for a message string with RSA public key.<br/>
- * @name verifyString
- * @memberOf RSAKey#
- * @function
- * @param {String} sMsg message string to be verified.
- * @param {String} hSig hexadecimal string of siganture.<br/>
- *                 non-hexadecimal charactors including new lines will be ignored.
- * @return returns 1 if valid, otherwise 0
- */
-function _rsasign_verifyString(sMsg, hSig) {
-  hSig = hSig.replace(_RE_HEXDECONLY, '');
-  
-  if(LOG>3)console.log('n is '+this.n);
-  if(LOG>3)console.log('e is '+this.e);
-  
-  if (hSig.length != this.n.bitLength() / 4) return 0;
-  hSig = hSig.replace(/[ \n]+/g, "");
-  var biSig = parseBigInt(hSig, 16);
-  var biDecryptedSig = this.doPublic(biSig);
-  var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
-  var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);
-  
-  if (digestInfoAry.length == 0) return false;
-  var algName = digestInfoAry[0];
-  var diHashValue = digestInfoAry[1];
-  var ff = _RSASIGN_HASHHEXFUNC[algName];
-  var msgHashValue = ff(sMsg);
-  return (diHashValue == msgHashValue);
-}
-
-/**
- * verifies a sigature for a message byte array with RSA public key.<br/>
- * @name verifyByteArray
- * @memberOf RSAKey#
- * @function
- * @param {byte[]} byteArray message byte array to be verified.
- * @param {String} hSig hexadecimal string of signature.<br/>
- *                 non-hexadecimal charactors including new lines will be ignored.
- * @return returns 1 if valid, otherwise 0 
- */
-function _rsasign_verifyByteArray(byteArray, witness, hSig) {
-	hSig = hSig.replace(_RE_HEXDECONLY, '');
-	  
-	  if(LOG>3)console.log('n is '+this.n);
-	  if(LOG>3)console.log('e is '+this.e);
-	  
-	  if (hSig.length != this.n.bitLength() / 4) return 0;
-	  hSig = hSig.replace(/[ \n]+/g, "");
-	  var biSig = parseBigInt(hSig, 16);
-	  var biDecryptedSig = this.doPublic(biSig);
-	  var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
-	  var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);
-	  
-	  if (digestInfoAry.length == 0) return false;
-	  var algName = digestInfoAry[0];
-	  var diHashValue = digestInfoAry[1];
-	  var msgHashValue = null;
-	  
-	  if (witness == null) {
-	  	var ff = _RSASIGN_HASHBYTEFUNC[algName];
-	  	msgHashValue = ff(byteArray);
-	  } else {
-	  	// Compute merkle hash
-		  var h = hex_sha256_from_bytes(byteArray);
-		  var index = witness.path.index;
-		  for (var i = witness.path.digestList.length - 1; i >= 0; i--) {
-		  	var str = "";
-		  	if (index % 2 == 0) {
-		  		str = h + witness.path.digestList[i];
-		  	} else {
-		  		str = witness.path.digestList[i] + h;
-		  	}
-		  	h = hex_sha256_from_bytes(DataUtils.toNumbers(str));
-		  	index = Math.floor(index / 2);
-		  }
-		  msgHashValue = hex_sha256_from_bytes(DataUtils.toNumbers(h));
-	  }
-	  //console.log(diHashValue);
-	  //console.log(msgHashValue);
-	  return (diHashValue == msgHashValue);
-}
-
-
-RSAKey.prototype.signString = _rsasign_signString;
-
-RSAKey.prototype.signByteArray = _rsasign_signByteArray; //@author axelcdv
-RSAKey.prototype.signByteArrayWithSHA256 = _rsasign_signByteArrayWithSHA256; //@author axelcdv
-
-RSAKey.prototype.signStringWithSHA1 = _rsasign_signStringWithSHA1;
-RSAKey.prototype.signStringWithSHA256 = _rsasign_signStringWithSHA256;
-RSAKey.prototype.sign = _rsasign_signString;
-RSAKey.prototype.signWithSHA1 = _rsasign_signStringWithSHA1;
-RSAKey.prototype.signWithSHA256 = _rsasign_signStringWithSHA256;
-
-
-/*RSAKey.prototype.signStringHEX = _rsasign_signStringHEX;
-RSAKey.prototype.signStringWithSHA1HEX = _rsasign_signStringWithSHA1HEX;
-RSAKey.prototype.signStringWithSHA256HEX = _rsasign_signStringWithSHA256HEX;
-RSAKey.prototype.signHEX = _rsasign_signStringHEX;
-RSAKey.prototype.signWithSHA1HEX = _rsasign_signStringWithSHA1HEX;
-RSAKey.prototype.signWithSHA256HEX = _rsasign_signStringWithSHA256HEX;
-*/
-
-RSAKey.prototype.verifyByteArray = _rsasign_verifyByteArray;
-RSAKey.prototype.verifyString = _rsasign_verifyString;
-RSAKey.prototype.verifyHexSignatureForMessage = _rsasign_verifyHexSignatureForMessage;
-RSAKey.prototype.verify = _rsasign_verifyString;
-RSAKey.prototype.verifyHexSignatureForByteArrayMessage = _rsasign_verifyHexSignatureForMessage;
-
-/*
-RSAKey.prototype.verifyStringHEX = _rsasign_verifyStringHEX;
-RSAKey.prototype.verifyHexSignatureForMessageHEX = _rsasign_verifyHexSignatureForMessageHEX;
-RSAKey.prototype.verifyHEX = _rsasign_verifyStringHEX;
-RSAKey.prototype.verifyHexSignatureForByteArrayMessageHEX = _rsasign_verifyHexSignatureForMessageHEX;
-*/
-	
-	
-/**
- * @name RSAKey
- * @class
- * @description Tom Wu's RSA Key class and extension
- */
-/*! asn1hex-1.1.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
- */
-//
-// asn1hex.js - Hexadecimal represented ASN.1 string library
-//
-// version: 1.1 (09-May-2012)
-//
-// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
-//
-// This software is licensed under the terms of the MIT License.
-// http://kjur.github.com/jsrsasign/license/
-//
-// The above copyright and license notice shall be 
-// included in all copies or substantial portions of the Software.
-//
-// Depends on:
-//
-
-// MEMO:
-//   f('3082025b02...', 2) ... 82025b ... 3bytes
-//   f('020100', 2) ... 01 ... 1byte
-//   f('0203001...', 2) ... 03 ... 1byte
-//   f('02818003...', 2) ... 8180 ... 2bytes
-//   f('3080....0000', 2) ... 80 ... -1
-//
-//   Requirements:
-//   - ASN.1 type octet length MUST be 1. 
-//     (i.e. ASN.1 primitives like SET, SEQUENCE, INTEGER, OCTETSTRING ...)
-//   - 
-/**
- * get byte length for ASN.1 L(length) bytes
- * @name getByteLengthOfL_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} pos string index
- * @return byte length for ASN.1 L(length) bytes
- */
-function _asnhex_getByteLengthOfL_AtObj(s, pos) {
-  if (s.substring(pos + 2, pos + 3) != '8') return 1;
-  var i = parseInt(s.substring(pos + 3, pos + 4));
-  if (i == 0) return -1; 		// length octet '80' indefinite length
-  if (0 < i && i < 10) return i + 1;	// including '8?' octet;
-  return -2;				// malformed format
-}
-
-
-/**
- * get hexadecimal string for ASN.1 L(length) bytes
- * @name getHexOfL_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} pos string index
- * @return {String} hexadecimal string for ASN.1 L(length) bytes
- */
-function _asnhex_getHexOfL_AtObj(s, pos) {
-  var len = _asnhex_getByteLengthOfL_AtObj(s, pos);
-  if (len < 1) return '';
-  return s.substring(pos + 2, pos + 2 + len * 2);
-}
-
-//
-//   getting ASN.1 length value at the position 'idx' of
-//   hexa decimal string 's'.
-//
-//   f('3082025b02...', 0) ... 82025b ... ???
-//   f('020100', 0) ... 01 ... 1
-//   f('0203001...', 0) ... 03 ... 3
-//   f('02818003...', 0) ... 8180 ... 128
-/**
- * get integer value of ASN.1 length for ASN.1 data
- * @name getIntOfL_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} pos string index
- * @return ASN.1 L(length) integer value
- */
-function _asnhex_getIntOfL_AtObj(s, pos) {
-  var hLength = _asnhex_getHexOfL_AtObj(s, pos);
-  if (hLength == '') return -1;
-  var bi;
-  if (parseInt(hLength.substring(0, 1)) < 8) {
-     bi = parseBigInt(hLength, 16);
-  } else {
-     bi = parseBigInt(hLength.substring(2), 16);
-  }
-  return bi.intValue();
-}
-
-/**
- * get ASN.1 value starting string position for ASN.1 object refered by index 'idx'.
- * @name getStartPosOfV_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} pos string index
- */
-function _asnhex_getStartPosOfV_AtObj(s, pos) {
-  var l_len = _asnhex_getByteLengthOfL_AtObj(s, pos);
-  if (l_len < 0) return l_len;
-  return pos + (l_len + 1) * 2;
-}
-
-/**
- * get hexadecimal string of ASN.1 V(value)
- * @name getHexOfV_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} pos string index
- * @return {String} hexadecimal string of ASN.1 value.
- */
-function _asnhex_getHexOfV_AtObj(s, pos) {
-  var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos);
-  var len = _asnhex_getIntOfL_AtObj(s, pos);
-  return s.substring(pos1, pos1 + len * 2);
-}
-
-/**
- * get hexadecimal string of ASN.1 TLV at
- * @name getHexOfTLV_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} pos string index
- * @return {String} hexadecimal string of ASN.1 TLV.
- * @since 1.1
- */
-function _asnhex_getHexOfTLV_AtObj(s, pos) {
-  var hT = s.substr(pos, 2);
-  var hL = _asnhex_getHexOfL_AtObj(s, pos);
-  var hV = _asnhex_getHexOfV_AtObj(s, pos);
-  return hT + hL + hV;
-}
-
-/**
- * get next sibling starting index for ASN.1 object string
- * @name getPosOfNextSibling_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} pos string index
- * @return next sibling starting index for ASN.1 object string
- */
-function _asnhex_getPosOfNextSibling_AtObj(s, pos) {
-  var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos);
-  var len = _asnhex_getIntOfL_AtObj(s, pos);
-  return pos1 + len * 2;
-}
-
-/**
- * get array of indexes of child ASN.1 objects
- * @name getPosArrayOfChildren_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} s hexadecimal string of ASN.1 DER encoded data
- * @param {Number} start string index of ASN.1 object
- * @return {Array of Number} array of indexes for childen of ASN.1 objects
- */
-function _asnhex_getPosArrayOfChildren_AtObj(h, pos) {
-  var a = new Array();
-  var p0 = _asnhex_getStartPosOfV_AtObj(h, pos);
-  a.push(p0);
-
-  var len = _asnhex_getIntOfL_AtObj(h, pos);
-  var p = p0;
-  var k = 0;
-  while (1) {
-    var pNext = _asnhex_getPosOfNextSibling_AtObj(h, p);
-    if (pNext == null || (pNext - p0  >= (len * 2))) break;
-    if (k >= 200) break;
-
-    a.push(pNext);
-    p = pNext;
-
-    k++;
-  }
-
-  return a;
-}
-
-/**
- * get string index of nth child object of ASN.1 object refered by h, idx
- * @name getNthChildIndex_AtObj
- * @memberOf ASN1HEX
- * @function
- * @param {String} h hexadecimal string of ASN.1 DER encoded data
- * @param {Number} idx start string index of ASN.1 object
- * @param {Number} nth for child
- * @return {Number} string index of nth child.
- * @since 1.1
- */
-function _asnhex_getNthChildIndex_AtObj(h, idx, nth) {
-  var a = _asnhex_getPosArrayOfChildren_AtObj(h, idx);
-  return a[nth];
-}
-
-// ========== decendant methods ==============================
-
-/**
- * get string index of nth child object of ASN.1 object refered by h, idx
- * @name getDecendantIndexByNthList
- * @memberOf ASN1HEX
- * @function
- * @param {String} h hexadecimal string of ASN.1 DER encoded data
- * @param {Number} currentIndex start string index of ASN.1 object
- * @param {Array of Number} nthList array list of nth
- * @return {Number} string index refered by nthList
- * @since 1.1
- */
-function _asnhex_getDecendantIndexByNthList(h, currentIndex, nthList) {
-  if (nthList.length == 0) {
-    return currentIndex;
-  }
-  var firstNth = nthList.shift();
-  var a = _asnhex_getPosArrayOfChildren_AtObj(h, currentIndex);
-  return _asnhex_getDecendantIndexByNthList(h, a[firstNth], nthList);
-}
-
-/**
- * get hexadecimal string of ASN.1 TLV refered by current index and nth index list.
- * @name getDecendantHexTLVByNthList
- * @memberOf ASN1HEX
- * @function
- * @param {String} h hexadecimal string of ASN.1 DER encoded data
- * @param {Number} currentIndex start string index of ASN.1 object
- * @param {Array of Number} nthList array list of nth
- * @return {Number} hexadecimal string of ASN.1 TLV refered by nthList
- * @since 1.1
- */
-function _asnhex_getDecendantHexTLVByNthList(h, currentIndex, nthList) {
-  var idx = _asnhex_getDecendantIndexByNthList(h, currentIndex, nthList);
-  return _asnhex_getHexOfTLV_AtObj(h, idx);
-}
-
-/**
- * get hexadecimal string of ASN.1 V refered by current index and nth index list.
- * @name getDecendantHexVByNthList
- * @memberOf ASN1HEX
- * @function
- * @param {String} h hexadecimal string of ASN.1 DER encoded data
- * @param {Number} currentIndex start string index of ASN.1 object
- * @param {Array of Number} nthList array list of nth
- * @return {Number} hexadecimal string of ASN.1 V refered by nthList
- * @since 1.1
- */
-function _asnhex_getDecendantHexVByNthList(h, currentIndex, nthList) {
-  var idx = _asnhex_getDecendantIndexByNthList(h, currentIndex, nthList);
-  return _asnhex_getHexOfV_AtObj(h, idx);
-}
-
-// ========== class definition ==============================
-
-/**
- * ASN.1 DER encoded hexadecimal string utility class
- * @class ASN.1 DER encoded hexadecimal string utility class
- * @author Kenji Urushima
- * @version 1.1 (09 May 2012)
- * @see <a href="http://kjur.github.com/jsrsasigns/">'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/</a>
- * @since 1.1
- */
-function ASN1HEX() {
-  return ASN1HEX;
-}
-
-ASN1HEX.getByteLengthOfL_AtObj = _asnhex_getByteLengthOfL_AtObj;
-ASN1HEX.getHexOfL_AtObj = _asnhex_getHexOfL_AtObj;
-ASN1HEX.getIntOfL_AtObj = _asnhex_getIntOfL_AtObj;
-ASN1HEX.getStartPosOfV_AtObj = _asnhex_getStartPosOfV_AtObj;
-ASN1HEX.getHexOfV_AtObj = _asnhex_getHexOfV_AtObj;
-ASN1HEX.getHexOfTLV_AtObj = _asnhex_getHexOfTLV_AtObj;
-ASN1HEX.getPosOfNextSibling_AtObj = _asnhex_getPosOfNextSibling_AtObj;
-ASN1HEX.getPosArrayOfChildren_AtObj = _asnhex_getPosArrayOfChildren_AtObj;
-ASN1HEX.getNthChildIndex_AtObj = _asnhex_getNthChildIndex_AtObj;
-ASN1HEX.getDecendantIndexByNthList = _asnhex_getDecendantIndexByNthList;
-ASN1HEX.getDecendantHexVByNthList = _asnhex_getDecendantHexVByNthList;
-ASN1HEX.getDecendantHexTLVByNthList = _asnhex_getDecendantHexTLVByNthList;
-/*! x509-1.1.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
- */
-// 
-// x509.js - X509 class to read subject public key from certificate.
-//
-// version: 1.1 (10-May-2012)
-//
-// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
-//
-// This software is licensed under the terms of the MIT License.
-// http://kjur.github.com/jsrsasign/license
-//
-// The above copyright and license notice shall be 
-// included in all copies or substantial portions of the Software.
-// 
-
-// Depends:
-//   base64.js
-//   rsa.js
-//   asn1hex.js
-
-function _x509_pemToBase64(sCertPEM) {
-  var s = sCertPEM;
-  s = s.replace("-----BEGIN CERTIFICATE-----", "");
-  s = s.replace("-----END CERTIFICATE-----", "");
-  s = s.replace(/[ \n]+/g, "");
-  return s;
-}
-
-function _x509_pemToHex(sCertPEM) {
-  var b64Cert = _x509_pemToBase64(sCertPEM);
-  var hCert = b64tohex(b64Cert);
-  return hCert;
-}
-
-function _x509_getHexTbsCertificateFromCert(hCert) {
-  var pTbsCert = ASN1HEX.getStartPosOfV_AtObj(hCert, 0);
-  return pTbsCert;
-}
-
-// NOTE: privateKeyUsagePeriod field of X509v2 not supported.
-// NOTE: v1 and v3 supported
-function _x509_getSubjectPublicKeyInfoPosFromCertHex(hCert) {
-  var pTbsCert = ASN1HEX.getStartPosOfV_AtObj(hCert, 0);
-  var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, pTbsCert); 
-  if (a.length < 1) return -1;
-  if (hCert.substring(a[0], a[0] + 10) == "a003020102") { // v3
-    if (a.length < 6) return -1;
-    return a[6];
-  } else {
-    if (a.length < 5) return -1;
-    return a[5];
-  }
-}
-
-// NOTE: Without BITSTRING encapsulation.
-// If pInfo is supplied, it is the position in hCert of the SubjectPublicKeyInfo.
-function _x509_getSubjectPublicKeyPosFromCertHex(hCert, pInfo) {
-  if (pInfo == null)
-      pInfo = _x509_getSubjectPublicKeyInfoPosFromCertHex(hCert);
-  if (pInfo == -1) return -1;    
-  var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, pInfo); 
-  
-  if (a.length != 2) return -1;
-  var pBitString = a[1];
-  if (hCert.substring(pBitString, pBitString + 2) != '03') return -1;
-  var pBitStringV = ASN1HEX.getStartPosOfV_AtObj(hCert, pBitString);
-
-  if (hCert.substring(pBitStringV, pBitStringV + 2) != '00') return -1;
-  return pBitStringV + 2;
-}
-
-// If p is supplied, it is the public key position in hCert.
-function _x509_getPublicKeyHexArrayFromCertHex(hCert, p) {
-  if (p == null)
-      p = _x509_getSubjectPublicKeyPosFromCertHex(hCert);
-  var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, p); 
-  //var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, a[3]); 
-  if(LOG>4){
-	  console.log('a is now');
-	  console.log(a);
-  }
-  
-  //if (a.length != 2) return [];
-  if (a.length < 2) return [];
-
-  var hN = ASN1HEX.getHexOfV_AtObj(hCert, a[0]);
-  var hE = ASN1HEX.getHexOfV_AtObj(hCert, a[1]);
-  if (hN != null && hE != null) {
-    return [hN, hE];
-  } else {
-    return [];
-  }
-}
-
-function _x509_getPublicKeyHexArrayFromCertPEM(sCertPEM) {
-  var hCert = _x509_pemToHex(sCertPEM);
-  var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
-  return a;
-}
-
-// ===== get basic fields from hex =====================================
-/**
- * get hexadecimal string of serialNumber field of certificate.<br/>
- * @name getSerialNumberHex
- * @memberOf X509#
- * @function
- */
-function _x509_getSerialNumberHex() {
-  return ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 1]);
-}
-
-/**
- * get hexadecimal string of issuer field of certificate.<br/>
- * @name getIssuerHex
- * @memberOf X509#
- * @function
- */
-function _x509_getIssuerHex() {
-  return ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3]);
-}
-
-/**
- * get string of issuer field of certificate.<br/>
- * @name getIssuerString
- * @memberOf X509#
- * @function
- */
-function _x509_getIssuerString() {
-  return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3]));
-}
-
-/**
- * get hexadecimal string of subject field of certificate.<br/>
- * @name getSubjectHex
- * @memberOf X509#
- * @function
- */
-function _x509_getSubjectHex() {
-  return ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5]);
-}
-
-/**
- * get string of subject field of certificate.<br/>
- * @name getSubjectString
- * @memberOf X509#
- * @function
- */
-function _x509_getSubjectString() {
-  return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5]));
-}
-
-/**
- * get notBefore field string of certificate.<br/>
- * @name getNotBefore
- * @memberOf X509#
- * @function
- */
-function _x509_getNotBefore() {
-  var s = ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 4, 0]);
-  s = s.replace(/(..)/g, "%$1");
-  s = decodeURIComponent(s);
-  return s;
-}
-
-/**
- * get notAfter field string of certificate.<br/>
- * @name getNotAfter
- * @memberOf X509#
- * @function
- */
-function _x509_getNotAfter() {
-  var s = ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 4, 1]);
-  s = s.replace(/(..)/g, "%$1");
-  s = decodeURIComponent(s);
-  return s;
-}
-
-// ===== read certificate =====================================
-
-_x509_DN_ATTRHEX = {
-    "0603550406": "C",
-    "060355040a": "O",
-    "060355040b": "OU",
-    "0603550403": "CN",
-    "0603550405": "SN",
-    "0603550408": "ST",
-    "0603550407": "L" };
-
-function _x509_hex2dn(hDN) {
-  var s = "";
-  var a = ASN1HEX.getPosArrayOfChildren_AtObj(hDN, 0);
-  for (var i = 0; i < a.length; i++) {
-    var hRDN = ASN1HEX.getHexOfTLV_AtObj(hDN, a[i]);
-    s = s + "/" + _x509_hex2rdn(hRDN);
-  }
-  return s;
-}
-
-function _x509_hex2rdn(hRDN) {
-    var hType = ASN1HEX.getDecendantHexTLVByNthList(hRDN, 0, [0, 0]);
-    var hValue = ASN1HEX.getDecendantHexVByNthList(hRDN, 0, [0, 1]);
-    var type = "";
-    try { type = _x509_DN_ATTRHEX[hType]; } catch (ex) { type = hType; }
-    hValue = hValue.replace(/(..)/g, "%$1");
-    var value = decodeURIComponent(hValue);
-    return type + "=" + value;
-}
-
-// ===== read certificate =====================================
-
-
-/**
- * read PEM formatted X.509 certificate from string.<br/>
- * @name readCertPEM
- * @memberOf X509#
- * @function
- * @param {String} sCertPEM string for PEM formatted X.509 certificate
- */
-function _x509_readCertPEM(sCertPEM) {
-  var hCert = _x509_pemToHex(sCertPEM);
-  var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
-  if(LOG>4){
-	  console.log('HEX VALUE IS ' + hCert);
-	  console.log('type of a' + typeof a);
-	  console.log('a VALUE IS ');
-	  console.log(a);
-	  console.log('a[0] VALUE IS ' + a[0]);
-	  console.log('a[1] VALUE IS ' + a[1]);
-  }
-  var rsa = new RSAKey();
-  rsa.setPublic(a[0], a[1]);
-  this.subjectPublicKeyRSA = rsa;
-  this.subjectPublicKeyRSA_hN = a[0];
-  this.subjectPublicKeyRSA_hE = a[1];
-  this.hex = hCert;
-}
-
-/**
- * read hex formatted X.509 certificate from string.
- * @name readCertHex
- * @memberOf X509#
- * @function
- * @param {String} hCert string for hex formatted X.509 certificate
- */
-function _x509_readCertHex(hCert) {
-  hCert = hCert.toLowerCase();
-  var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
-  var rsa = new RSAKey();
-  rsa.setPublic(a[0], a[1]);
-  this.subjectPublicKeyRSA = rsa;
-  this.subjectPublicKeyRSA_hN = a[0];
-  this.subjectPublicKeyRSA_hE = a[1];
-  this.hex = hCert;
-}
-
-function _x509_readCertPEMWithoutRSAInit(sCertPEM) {
-  var hCert = _x509_pemToHex(sCertPEM);
-  var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
-  this.subjectPublicKeyRSA.setPublic(a[0], a[1]);
-  this.subjectPublicKeyRSA_hN = a[0];
-  this.subjectPublicKeyRSA_hE = a[1];
-  this.hex = hCert;
-}
-
-/**
- * X.509 certificate class.<br/>
- * @class X.509 certificate class
- * @property {RSAKey} subjectPublicKeyRSA Tom Wu's RSAKey object
- * @property {String} subjectPublicKeyRSA_hN hexadecimal string for modulus of RSA public key
- * @property {String} subjectPublicKeyRSA_hE hexadecimal string for public exponent of RSA public key
- * @property {String} hex hexacedimal string for X.509 certificate.
- * @author Kenji Urushima
- * @version 1.0.1 (08 May 2012)
- * @see <a href="http://kjur.github.com/jsrsasigns/">'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/</a>
- */
-function X509() {
-  this.subjectPublicKeyRSA = null;
-  this.subjectPublicKeyRSA_hN = null;
-  this.subjectPublicKeyRSA_hE = null;
-  this.hex = null;
-}
-
-X509.prototype.readCertPEM = _x509_readCertPEM;
-X509.prototype.readCertHex = _x509_readCertHex;
-X509.prototype.readCertPEMWithoutRSAInit = _x509_readCertPEMWithoutRSAInit;
-X509.prototype.getSerialNumberHex = _x509_getSerialNumberHex;
-X509.prototype.getIssuerHex = _x509_getIssuerHex;
-X509.prototype.getSubjectHex = _x509_getSubjectHex;
-X509.prototype.getIssuerString = _x509_getIssuerString;
-X509.prototype.getSubjectString = _x509_getSubjectString;
-X509.prototype.getNotBefore = _x509_getNotBefore;
-X509.prototype.getNotAfter = _x509_getNotAfter;
-
-// Copyright (c) 2005  Tom Wu
-// All Rights Reserved.
-// See "LICENSE" for details.
-
-// Basic JavaScript BN library - subset useful for RSA encryption.
-
-// Bits per digit
-var dbits;
-
-// JavaScript engine analysis
-var canary = 0xdeadbeefcafe;
-var j_lm = ((canary&0xffffff)==0xefcafe);
-
-// (public) Constructor
-function BigInteger(a,b,c) {
-  if(a != null)
-    if("number" == typeof a) this.fromNumber(a,b,c);
-    else if(b == null && "string" != typeof a) this.fromString(a,256);
-    else this.fromString(a,b);
-}
-
-// return new, unset BigInteger
-function nbi() { return new BigInteger(null); }
-
-// am: Compute w_j += (x*this_i), propagate carries,
-// c is initial carry, returns final carry.
-// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
-// We need to select the fastest one that works in this environment.
-
-// am1: use a single mult and divide to get the high bits,
-// max digit bits should be 26 because
-// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
-function am1(i,x,w,j,c,n) {
-  while(--n >= 0) {
-    var v = x*this[i++]+w[j]+c;
-    c = Math.floor(v/0x4000000);
-    w[j++] = v&0x3ffffff;
-  }
-  return c;
-}
-// am2 avoids a big mult-and-extract completely.
-// Max digit bits should be <= 30 because we do bitwise ops
-// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
-function am2(i,x,w,j,c,n) {
-  var xl = x&0x7fff, xh = x>>15;
-  while(--n >= 0) {
-    var l = this[i]&0x7fff;
-    var h = this[i++]>>15;
-    var m = xh*l+h*xl;
-    l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff);
-    c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);
-    w[j++] = l&0x3fffffff;
-  }
-  return c;
-}
-// Alternately, set max digit bits to 28 since some
-// browsers slow down when dealing with 32-bit numbers.
-function am3(i,x,w,j,c,n) {
-  var xl = x&0x3fff, xh = x>>14;
-  while(--n >= 0) {
-    var l = this[i]&0x3fff;
-    var h = this[i++]>>14;
-    var m = xh*l+h*xl;
-    l = xl*l+((m&0x3fff)<<14)+w[j]+c;
-    c = (l>>28)+(m>>14)+xh*h;
-    w[j++] = l&0xfffffff;
-  }
-  return c;
-}
-if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
-  BigInteger.prototype.am = am2;
-  dbits = 30;
-}
-else if(j_lm && (navigator.appName != "Netscape")) {
-  BigInteger.prototype.am = am1;
-  dbits = 26;
-}
-else { // Mozilla/Netscape seems to prefer am3
-  BigInteger.prototype.am = am3;
-  dbits = 28;
-}
-
-BigInteger.prototype.DB = dbits;
-BigInteger.prototype.DM = ((1<<dbits)-1);
-BigInteger.prototype.DV = (1<<dbits);
-
-var BI_FP = 52;
-BigInteger.prototype.FV = Math.pow(2,BI_FP);
-BigInteger.prototype.F1 = BI_FP-dbits;
-BigInteger.prototype.F2 = 2*dbits-BI_FP;
-
-// Digit conversions
-var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
-var BI_RC = new Array();
-var rr,vv;
-rr = "0".charCodeAt(0);
-for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
-rr = "a".charCodeAt(0);
-for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
-rr = "A".charCodeAt(0);
-for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
-
-function int2char(n) { return BI_RM.charAt(n); }
-function intAt(s,i) {
-  var c = BI_RC[s.charCodeAt(i)];
-  return (c==null)?-1:c;
-}
-
-// (protected) copy this to r
-function bnpCopyTo(r) {
-  for(var i = this.t-1; i >= 0; --i) r[i] = this[i];
-  r.t = this.t;
-  r.s = this.s;
-}
-
-// (protected) set from integer value x, -DV <= x < DV
-function bnpFromInt(x) {
-  this.t = 1;
-  this.s = (x<0)?-1:0;
-  if(x > 0) this[0] = x;
-  else if(x < -1) this[0] = x+DV;
-  else this.t = 0;
-}
-
-// return bigint initialized to value
-function nbv(i) { var r = nbi(); r.fromInt(i); return r; }
-
-// (protected) set from string and radix
-function bnpFromString(s,b) {
-  var k;
-  if(b == 16) k = 4;
-  else if(b == 8) k = 3;
-  else if(b == 256) k = 8; // byte array
-  else if(b == 2) k = 1;
-  else if(b == 32) k = 5;
-  else if(b == 4) k = 2;
-  else { this.fromRadix(s,b); return; }
-  this.t = 0;
-  this.s = 0;
-  var i = s.length, mi = false, sh = 0;
-  while(--i >= 0) {
-    var x = (k==8)?s[i]&0xff:intAt(s,i);
-    if(x < 0) {
-      if(s.charAt(i) == "-") mi = true;
-      continue;
-    }
-    mi = false;
-    if(sh == 0)
-      this[this.t++] = x;
-    else if(sh+k > this.DB) {
-      this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh;
-      this[this.t++] = (x>>(this.DB-sh));
-    }
-    else
-      this[this.t-1] |= x<<sh;
-    sh += k;
-    if(sh >= this.DB) sh -= this.DB;
-  }
-  if(k == 8 && (s[0]&0x80) != 0) {
-    this.s = -1;
-    if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh;
-  }
-  this.clamp();
-  if(mi) BigInteger.ZERO.subTo(this,this);
-}
-
-// (protected) clamp off excess high words
-function bnpClamp() {
-  var c = this.s&this.DM;
-  while(this.t > 0 && this[this.t-1] == c) --this.t;
-}
-
-// (public) return string representation in given radix
-function bnToString(b) {
-  if(this.s < 0) return "-"+this.negate().toString(b);
-  var k;
-  if(b == 16) k = 4;
-  else if(b == 8) k = 3;
-  else if(b == 2) k = 1;
-  else if(b == 32) k = 5;
-  else if(b == 4) k = 2;
-  else return this.toRadix(b);
-  var km = (1<<k)-1, d, m = false, r = "", i = this.t;
-  var p = this.DB-(i*this.DB)%k;
-  if(i-- > 0) {
-    if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); }
-    while(i >= 0) {
-      if(p < k) {
-        d = (this[i]&((1<<p)-1))<<(k-p);
-        d |= this[--i]>>(p+=this.DB-k);
-      }
-      else {
-        d = (this[i]>>(p-=k))&km;
-        if(p <= 0) { p += this.DB; --i; }
-      }
-      if(d > 0) m = true;
-      if(m) r += int2char(d);
-    }
-  }
-  return m?r:"0";
-}
-
-// (public) -this
-function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }
-
-// (public) |this|
-function bnAbs() { return (this.s<0)?this.negate():this; }
-
-// (public) return + if this > a, - if this < a, 0 if equal
-function bnCompareTo(a) {
-  var r = this.s-a.s;
-  if(r != 0) return r;
-  var i = this.t;
-  r = i-a.t;
-  if(r != 0) return r;
-  while(--i >= 0) if((r=this[i]-a[i]) != 0) return r;
-  return 0;
-}
-
-// returns bit length of the integer x
-function nbits(x) {
-  var r = 1, t;
-  if((t=x>>>16) != 0) { x = t; r += 16; }
-  if((t=x>>8) != 0) { x = t; r += 8; }
-  if((t=x>>4) != 0) { x = t; r += 4; }
-  if((t=x>>2) != 0) { x = t; r += 2; }
-  if((t=x>>1) != 0) { x = t; r += 1; }
-  return r;
-}
-
-// (public) return the number of bits in "this"
-function bnBitLength() {
-  if(this.t <= 0) return 0;
-  return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));
-}
-
-// (protected) r = this << n*DB
-function bnpDLShiftTo(n,r) {
-  var i;
-  for(i = this.t-1; i >= 0; --i) r[i+n] = this[i];
-  for(i = n-1; i >= 0; --i) r[i] = 0;
-  r.t = this.t+n;
-  r.s = this.s;
-}
-
-// (protected) r = this >> n*DB
-function bnpDRShiftTo(n,r) {
-  for(var i = n; i < this.t; ++i) r[i-n] = this[i];
-  r.t = Math.max(this.t-n,0);
-  r.s = this.s;
-}
-
-// (protected) r = this << n
-function bnpLShiftTo(n,r) {
-  var bs = n%this.DB;
-  var cbs = this.DB-bs;
-  var bm = (1<<cbs)-1;
-  var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i;
-  for(i = this.t-1; i >= 0; --i) {
-    r[i+ds+1] = (this[i]>>cbs)|c;
-    c = (this[i]&bm)<<bs;
-  }
-  for(i = ds-1; i >= 0; --i) r[i] = 0;
-  r[ds] = c;
-  r.t = this.t+ds+1;
-  r.s = this.s;
-  r.clamp();
-}
-
-// (protected) r = this >> n
-function bnpRShiftTo(n,r) {
-  r.s = this.s;
-  var ds = Math.floor(n/this.DB);
-  if(ds >= this.t) { r.t = 0; return; }
-  var bs = n%this.DB;
-  var cbs = this.DB-bs;
-  var bm = (1<<bs)-1;
-  r[0] = this[ds]>>bs;
-  for(var i = ds+1; i < this.t; ++i) {
-    r[i-ds-1] |= (this[i]&bm)<<cbs;
-    r[i-ds] = this[i]>>bs;
-  }
-  if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs;
-  r.t = this.t-ds;
-  r.clamp();
-}
-
-// (protected) r = this - a
-function bnpSubTo(a,r) {
-  var i = 0, c = 0, m = Math.min(a.t,this.t);
-  while(i < m) {
-    c += this[i]-a[i];
-    r[i++] = c&this.DM;
-    c >>= this.DB;
-  }
-  if(a.t < this.t) {
-    c -= a.s;
-    while(i < this.t) {
-      c += this[i];
-      r[i++] = c&this.DM;
-      c >>= this.DB;
-    }
-    c += this.s;
-  }
-  else {
-    c += this.s;
-    while(i < a.t) {
-      c -= a[i];
-      r[i++] = c&this.DM;
-      c >>= this.DB;
-    }
-    c -= a.s;
-  }
-  r.s = (c<0)?-1:0;
-  if(c < -1) r[i++] = this.DV+c;
-  else if(c > 0) r[i++] = c;
-  r.t = i;
-  r.clamp();
-}
-
-// (protected) r = this * a, r != this,a (HAC 14.12)
-// "this" should be the larger one if appropriate.
-function bnpMultiplyTo(a,r) {
-  var x = this.abs(), y = a.abs();
-  var i = x.t;
-  r.t = i+y.t;
-  while(--i >= 0) r[i] = 0;
-  for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t);
-  r.s = 0;
-  r.clamp();
-  if(this.s != a.s) BigInteger.ZERO.subTo(r,r);
-}
-
-// (protected) r = this^2, r != this (HAC 14.16)
-function bnpSquareTo(r) {
-  var x = this.abs();
-  var i = r.t = 2*x.t;
-  while(--i >= 0) r[i] = 0;
-  for(i = 0; i < x.t-1; ++i) {
-    var c = x.am(i,x[i],r,2*i,0,1);
-    if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) {
-      r[i+x.t] -= x.DV;
-      r[i+x.t+1] = 1;
-    }
-  }
-  if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1);
-  r.s = 0;
-  r.clamp();
-}
-
-// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
-// r != q, this != m.  q or r may be null.
-function bnpDivRemTo(m,q,r) {
-  var pm = m.abs();
-  if(pm.t <= 0) return;
-  var pt = this.abs();
-  if(pt.t < pm.t) {
-    if(q != null) q.fromInt(0);
-    if(r != null) this.copyTo(r);
-    return;
-  }
-  if(r == null) r = nbi();
-  var y = nbi(), ts = this.s, ms = m.s;
-  var nsh = this.DB-nbits(pm[pm.t-1]);	// normalize modulus
-  if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); }
-  else { pm.copyTo(y); pt.copyTo(r); }
-  var ys = y.t;
-  var y0 = y[ys-1];
-  if(y0 == 0) return;
-  var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0);
-  var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2;
-  var i = r.t, j = i-ys, t = (q==null)?nbi():q;
-  y.dlShiftTo(j,t);
-  if(r.compareTo(t) >= 0) {
-    r[r.t++] = 1;
-    r.subTo(t,r);
-  }
-  BigInteger.ONE.dlShiftTo(ys,t);
-  t.subTo(y,y);	// "negative" y so we can replace sub with am later
-  while(y.t < ys) y[y.t++] = 0;
-  while(--j >= 0) {
-    // Estimate quotient digit
-    var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);
-    if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) {	// Try it out
-      y.dlShiftTo(j,t);
-      r.subTo(t,r);
-      while(r[i] < --qd) r.subTo(t,r);
-    }
-  }
-  if(q != null) {
-    r.drShiftTo(ys,q);
-    if(ts != ms) BigInteger.ZERO.subTo(q,q);
-  }
-  r.t = ys;
-  r.clamp();
-  if(nsh > 0) r.rShiftTo(nsh,r);	// Denormalize remainder
-  if(ts < 0) BigInteger.ZERO.subTo(r,r);
-}
-
-// (public) this mod a
-function bnMod(a) {
-  var r = nbi();
-  this.abs().divRemTo(a,null,r);
-  if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r);
-  return r;
-}
-
-// Modular reduction using "classic" algorithm
-function Classic(m) { this.m = m; }
-function cConvert(x) {
-  if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
-  else return x;
-}
-function cRevert(x) { return x; }
-function cReduce(x) { x.divRemTo(this.m,null,x); }
-function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
-function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
-
-Classic.prototype.convert = cConvert;
-Classic.prototype.revert = cRevert;
-Classic.prototype.reduce = cReduce;
-Classic.prototype.mulTo = cMulTo;
-Classic.prototype.sqrTo = cSqrTo;
-
-// (protected) return "-1/this % 2^DB"; useful for Mont. reduction
-// justification:
-//         xy == 1 (mod m)
-//         xy =  1+km
-//   xy(2-xy) = (1+km)(1-km)
-// x[y(2-xy)] = 1-k^2m^2
-// x[y(2-xy)] == 1 (mod m^2)
-// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
-// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
-// JS multiply "overflows" differently from C/C++, so care is needed here.
-function bnpInvDigit() {
-  if(this.t < 1) return 0;
-  var x = this[0];
-  if((x&1) == 0) return 0;
-  var y = x&3;		// y == 1/x mod 2^2
-  y = (y*(2-(x&0xf)*y))&0xf;	// y == 1/x mod 2^4
-  y = (y*(2-(x&0xff)*y))&0xff;	// y == 1/x mod 2^8
-  y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff;	// y == 1/x mod 2^16
-  // last step - calculate inverse mod DV directly;
-  // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
-  y = (y*(2-x*y%this.DV))%this.DV;		// y == 1/x mod 2^dbits
-  // we really want the negative inverse, and -DV < y < DV
-  return (y>0)?this.DV-y:-y;
-}
-
-// Montgomery reduction
-function Montgomery(m) {
-  this.m = m;
-  this.mp = m.invDigit();
-  this.mpl = this.mp&0x7fff;
-  this.mph = this.mp>>15;
-  this.um = (1<<(m.DB-15))-1;
-  this.mt2 = 2*m.t;
-}
-
-// xR mod m
-function montConvert(x) {
-  var r = nbi();
-  x.abs().dlShiftTo(this.m.t,r);
-  r.divRemTo(this.m,null,r);
-  if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r);
-  return r;
-}
-
-// x/R mod m
-function montRevert(x) {
-  var r = nbi();
-  x.copyTo(r);
-  this.reduce(r);
-  return r;
-}
-
-// x = x/R mod m (HAC 14.32)
-function montReduce(x) {
-  while(x.t <= this.mt2)	// pad x so am has enough room later
-    x[x.t++] = 0;
-  for(var i = 0; i < this.m.t; ++i) {
-    // faster way of calculating u0 = x[i]*mp mod DV
-    var j = x[i]&0x7fff;
-    var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM;
-    // use am to combine the multiply-shift-add into one call
-    j = i+this.m.t;
-    x[j] += this.m.am(0,u0,x,i,0,this.m.t);
-    // propagate carry
-    while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }
-  }
-  x.clamp();
-  x.drShiftTo(this.m.t,x);
-  if(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
-}
-
-// r = "x^2/R mod m"; x != r
-function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
-
-// r = "xy/R mod m"; x,y != r
-function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
-
-Montgomery.prototype.convert = montConvert;
-Montgomery.prototype.revert = montRevert;
-Montgomery.prototype.reduce = montReduce;
-Montgomery.prototype.mulTo = montMulTo;
-Montgomery.prototype.sqrTo = montSqrTo;
-
-// (protected) true iff this is even
-function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; }
-
-// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
-function bnpExp(e,z) {
-  if(e > 0xffffffff || e < 1) return BigInteger.ONE;
-  var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1;
-  g.copyTo(r);
-  while(--i >= 0) {
-    z.sqrTo(r,r2);
-    if((e&(1<<i)) > 0) z.mulTo(r2,g,r);
-    else { var t = r; r = r2; r2 = t; }
-  }
-  return z.revert(r);
-}
-
-// (public) this^e % m, 0 <= e < 2^32
-function bnModPowInt(e,m) {
-  var z;
-  if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
-  return this.exp(e,z);
-}
-
-// protected
-BigInteger.prototype.copyTo = bnpCopyTo;
-BigInteger.prototype.fromInt = bnpFromInt;
-BigInteger.prototype.fromString = bnpFromString;
-BigInteger.prototype.clamp = bnpClamp;
-BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
-BigInteger.prototype.drShiftTo = bnpDRShiftTo;
-BigInteger.prototype.lShiftTo = bnpLShiftTo;
-BigInteger.prototype.rShiftTo = bnpRShiftTo;
-BigInteger.prototype.subTo = bnpSubTo;
-BigInteger.prototype.multiplyTo = bnpMultiplyTo;
-BigInteger.prototype.squareTo = bnpSquareTo;
-BigInteger.prototype.divRemTo = bnpDivRemTo;
-BigInteger.prototype.invDigit = bnpInvDigit;
-BigInteger.prototype.isEven = bnpIsEven;
-BigInteger.prototype.exp = bnpExp;
-
-// public
-BigInteger.prototype.toString = bnToString;
-BigInteger.prototype.negate = bnNegate;
-BigInteger.prototype.abs = bnAbs;
-BigInteger.prototype.compareTo = bnCompareTo;
-BigInteger.prototype.bitLength = bnBitLength;
-BigInteger.prototype.mod = bnMod;
-BigInteger.prototype.modPowInt = bnModPowInt;
-
-// "constants"
-BigInteger.ZERO = nbv(0);
-BigInteger.ONE = nbv(1);
-// Copyright (c) 2005-2009  Tom Wu
-// All Rights Reserved.
-// See "LICENSE" for details.
-
-// Extended JavaScript BN functions, required for RSA private ops.
-
-// Version 1.1: new BigInteger("0", 10) returns "proper" zero
-
-// (public)
-function bnClone() { var r = nbi(); this.copyTo(r); return r; }
-
-// (public) return value as integer
-function bnIntValue() {
-  if(this.s < 0) {
-    if(this.t == 1) return this[0]-this.DV;
-    else if(this.t == 0) return -1;
-  }
-  else if(this.t == 1) return this[0];
-  else if(this.t == 0) return 0;
-  // assumes 16 < DB < 32
-  return ((this[1]&((1<<(32-this.DB))-1))<<this.DB)|this[0];
-}
-
-// (public) return value as byte
-function bnByteValue() { return (this.t==0)?this.s:(this[0]<<24)>>24; }
-
-// (public) return value as short (assumes DB>=16)
-function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; }
-
-// (protected) return x s.t. r^x < DV
-function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); }
-
-// (public) 0 if this == 0, 1 if this > 0
-function bnSigNum() {
-  if(this.s < 0) return -1;
-  else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0;
-  else return 1;
-}
-
-// (protected) convert to radix string
-function bnpToRadix(b) {
-  if(b == null) b = 10;
-  if(this.signum() == 0 || b < 2 || b > 36) return "0";
-  var cs = this.chunkSize(b);
-  var a = Math.pow(b,cs);
-  var d = nbv(a), y = nbi(), z = nbi(), r = "";
-  this.divRemTo(d,y,z);
-  while(y.signum() > 0) {
-    r = (a+z.intValue()).toString(b).substr(1) + r;
-    y.divRemTo(d,y,z);
-  }
-  return z.intValue().toString(b) + r;
-}
-
-// (protected) convert from radix string
-function bnpFromRadix(s,b) {
-  this.fromInt(0);
-  if(b == null) b = 10;
-  var cs = this.chunkSize(b);
-  var d = Math.pow(b,cs), mi = false, j = 0, w = 0;
-  for(var i = 0; i < s.length; ++i) {
-    var x = intAt(s,i);
-    if(x < 0) {
-      if(s.charAt(i) == "-" && this.signum() == 0) mi = true;
-      continue;
-    }
-    w = b*w+x;
-    if(++j >= cs) {
-      this.dMultiply(d);
-      this.dAddOffset(w,0);
-      j = 0;
-      w = 0;
-    }
-  }
-  if(j > 0) {
-    this.dMultiply(Math.pow(b,j));
-    this.dAddOffset(w,0);
-  }
-  if(mi) BigInteger.ZERO.subTo(this,this);
-}
-
-// (protected) alternate constructor
-function bnpFromNumber(a,b,c) {
-  if("number" == typeof b) {
-    // new BigInteger(int,int,RNG)
-    if(a < 2) this.fromInt(1);
-    else {
-      this.fromNumber(a,c);
-      if(!this.testBit(a-1))	// force MSB set
-        this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this);
-      if(this.isEven()) this.dAddOffset(1,0); // force odd
-      while(!this.isProbablePrime(b)) {
-        this.dAddOffset(2,0);
-        if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this);
-      }
-    }
-  }
-  else {
-    // new BigInteger(int,RNG)
-    var x = new Array(), t = a&7;
-    x.length = (a>>3)+1;
-    b.nextBytes(x);
-    if(t > 0) x[0] &= ((1<<t)-1); else x[0] = 0;
-    this.fromString(x,256);
-  }
-}
-
-// (public) convert to bigendian byte array
-function bnToByteArray() {
-  var i = this.t, r = new Array();
-  r[0] = this.s;
-  var p = this.DB-(i*this.DB)%8, d, k = 0;
-  if(i-- > 0) {
-    if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p)
-      r[k++] = d|(this.s<<(this.DB-p));
-    while(i >= 0) {
-      if(p < 8) {
-        d = (this[i]&((1<<p)-1))<<(8-p);
-        d |= this[--i]>>(p+=this.DB-8);
-      }
-      else {
-        d = (this[i]>>(p-=8))&0xff;
-        if(p <= 0) { p += this.DB; --i; }
-      }
-      if((d&0x80) != 0) d |= -256;
-      if(k == 0 && (this.s&0x80) != (d&0x80)) ++k;
-      if(k > 0 || d != this.s) r[k++] = d;
-    }
-  }
-  return r;
-}
-
-function bnEquals(a) { return(this.compareTo(a)==0); }
-function bnMin(a) { return(this.compareTo(a)<0)?this:a; }
-function bnMax(a) { return(this.compareTo(a)>0)?this:a; }
-
-// (protected) r = this op a (bitwise)
-function bnpBitwiseTo(a,op,r) {
-  var i, f, m = Math.min(a.t,this.t);
-  for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]);
-  if(a.t < this.t) {
-    f = a.s&this.DM;
-    for(i = m; i < this.t; ++i) r[i] = op(this[i],f);
-    r.t = this.t;
-  }
-  else {
-    f = this.s&this.DM;
-    for(i = m; i < a.t; ++i) r[i] = op(f,a[i]);
-    r.t = a.t;
-  }
-  r.s = op(this.s,a.s);
-  r.clamp();
-}
-
-// (public) this & a
-function op_and(x,y) { return x&y; }
-function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; }
-
-// (public) this | a
-function op_or(x,y) { return x|y; }
-function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; }
-
-// (public) this ^ a
-function op_xor(x,y) { return x^y; }
-function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; }
-
-// (public) this & ~a
-function op_andnot(x,y) { return x&~y; }
-function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; }
-
-// (public) ~this
-function bnNot() {
-  var r = nbi();
-  for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i];
-  r.t = this.t;
-  r.s = ~this.s;
-  return r;
-}
-
-// (public) this << n
-function bnShiftLeft(n) {
-  var r = nbi();
-  if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r);
-  return r;
-}
-
-// (public) this >> n
-function bnShiftRight(n) {
-  var r = nbi();
-  if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r);
-  return r;
-}
-
-// return index of lowest 1-bit in x, x < 2^31
-function lbit(x) {
-  if(x == 0) return -1;
-  var r = 0;
-  if((x&0xffff) == 0) { x >>= 16; r += 16; }
-  if((x&0xff) == 0) { x >>= 8; r += 8; }
-  if((x&0xf) == 0) { x >>= 4; r += 4; }
-  if((x&3) == 0) { x >>= 2; r += 2; }
-  if((x&1) == 0) ++r;
-  return r;
-}
-
-// (public) returns index of lowest 1-bit (or -1 if none)
-function bnGetLowestSetBit() {
-  for(var i = 0; i < this.t; ++i)
-    if(this[i] != 0) return i*this.DB+lbit(this[i]);
-  if(this.s < 0) return this.t*this.DB;
-  return -1;
-}
-
-// return number of 1 bits in x
-function cbit(x) {
-  var r = 0;
-  while(x != 0) { x &= x-1; ++r; }
-  return r;
-}
-
-// (public) return number of set bits
-function bnBitCount() {
-  var r = 0, x = this.s&this.DM;
-  for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x);
-  return r;
-}
-
-// (public) true iff nth bit is set
-function bnTestBit(n) {
-  var j = Math.floor(n/this.DB);
-  if(j >= this.t) return(this.s!=0);
-  return((this[j]&(1<<(n%this.DB)))!=0);
-}
-
-// (protected) this op (1<<n)
-function bnpChangeBit(n,op) {
-  var r = BigInteger.ONE.shiftLeft(n);
-  this.bitwiseTo(r,op,r);
-  return r;
-}
-
-// (public) this | (1<<n)
-function bnSetBit(n) { return this.changeBit(n,op_or); }
-
-// (public) this & ~(1<<n)
-function bnClearBit(n) { return this.changeBit(n,op_andnot); }
-
-// (public) this ^ (1<<n)
-function bnFlipBit(n) { return this.changeBit(n,op_xor); }
-
-// (protected) r = this + a
-function bnpAddTo(a,r) {
-  var i = 0, c = 0, m = Math.min(a.t,this.t);
-  while(i < m) {
-    c += this[i]+a[i];
-    r[i++] = c&this.DM;
-    c >>= this.DB;
-  }
-  if(a.t < this.t) {
-    c += a.s;
-    while(i < this.t) {
-      c += this[i];
-      r[i++] = c&this.DM;
-      c >>= this.DB;
-    }
-    c += this.s;
-  }
-  else {
-    c += this.s;
-    while(i < a.t) {
-      c += a[i];
-      r[i++] = c&this.DM;
-      c >>= this.DB;
-    }
-    c += a.s;
-  }
-  r.s = (c<0)?-1:0;
-  if(c > 0) r[i++] = c;
-  else if(c < -1) r[i++] = this.DV+c;
-  r.t = i;
-  r.clamp();
-}
-
-// (public) this + a
-function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; }
-
-// (public) this - a
-function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; }
-
-// (public) this * a
-function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; }
-
-// (public) this / a
-function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; }
-
-// (public) this % a
-function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; }
-
-// (public) [this/a,this%a]
-function bnDivideAndRemainder(a) {
-  var q = nbi(), r = nbi();
-  this.divRemTo(a,q,r);
-  return new Array(q,r);
-}
-
-// (protected) this *= n, this >= 0, 1 < n < DV
-function bnpDMultiply(n) {
-  this[this.t] = this.am(0,n-1,this,0,0,this.t);
-  ++this.t;
-  this.clamp();
-}
-
-// (protected) this += n << w words, this >= 0
-function bnpDAddOffset(n,w) {
-  if(n == 0) return;
-  while(this.t <= w) this[this.t++] = 0;
-  this[w] += n;
-  while(this[w] >= this.DV) {
-    this[w] -= this.DV;
-    if(++w >= this.t) this[this.t++] = 0;
-    ++this[w];
-  }
-}
-
-// A "null" reducer
-function NullExp() {}
-function nNop(x) { return x; }
-function nMulTo(x,y,r) { x.multiplyTo(y,r); }
-function nSqrTo(x,r) { x.squareTo(r); }
-
-NullExp.prototype.convert = nNop;
-NullExp.prototype.revert = nNop;
-NullExp.prototype.mulTo = nMulTo;
-NullExp.prototype.sqrTo = nSqrTo;
-
-// (public) this^e
-function bnPow(e) { return this.exp(e,new NullExp()); }
-
-// (protected) r = lower n words of "this * a", a.t <= n
-// "this" should be the larger one if appropriate.
-function bnpMultiplyLowerTo(a,n,r) {
-  var i = Math.min(this.t+a.t,n);
-  r.s = 0; // assumes a,this >= 0
-  r.t = i;
-  while(i > 0) r[--i] = 0;
-  var j;
-  for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t);
-  for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i);
-  r.clamp();
-}
-
-// (protected) r = "this * a" without lower n words, n > 0
-// "this" should be the larger one if appropriate.
-function bnpMultiplyUpperTo(a,n,r) {
-  --n;
-  var i = r.t = this.t+a.t-n;
-  r.s = 0; // assumes a,this >= 0
-  while(--i >= 0) r[i] = 0;
-  for(i = Math.max(n-this.t,0); i < a.t; ++i)
-    r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n);
-  r.clamp();
-  r.drShiftTo(1,r);
-}
-
-// Barrett modular reduction
-function Barrett(m) {
-  // setup Barrett
-  this.r2 = nbi();
-  this.q3 = nbi();
-  BigInteger.ONE.dlShiftTo(2*m.t,this.r2);
-  this.mu = this.r2.divide(m);
-  this.m = m;
-}
-
-function barrettConvert(x) {
-  if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m);
-  else if(x.compareTo(this.m) < 0) return x;
-  else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; }
-}
-
-function barrettRevert(x) { return x; }
-
-// x = x mod m (HAC 14.42)
-function barrettReduce(x) {
-  x.drShiftTo(this.m.t-1,this.r2);
-  if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); }
-  this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);
-  this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);
-  while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1);
-  x.subTo(this.r2,x);
-  while(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
-}
-
-// r = x^2 mod m; x != r
-function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
-
-// r = x*y mod m; x,y != r
-function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
-
-Barrett.prototype.convert = barrettConvert;
-Barrett.prototype.revert = barrettRevert;
-Barrett.prototype.reduce = barrettReduce;
-Barrett.prototype.mulTo = barrettMulTo;
-Barrett.prototype.sqrTo = barrettSqrTo;
-
-// (public) this^e % m (HAC 14.85)
-function bnModPow(e,m) {
-  var i = e.bitLength(), k, r = nbv(1), z;
-  if(i <= 0) return r;
-  else if(i < 18) k = 1;
-  else if(i < 48) k = 3;
-  else if(i < 144) k = 4;
-  else if(i < 768) k = 5;
-  else k = 6;
-  if(i < 8)
-    z = new Classic(m);
-  else if(m.isEven())
-    z = new Barrett(m);
-  else
-    z = new Montgomery(m);
-
-  // precomputation
-  var g = new Array(), n = 3, k1 = k-1, km = (1<<k)-1;
-  g[1] = z.convert(this);
-  if(k > 1) {
-    var g2 = nbi();
-    z.sqrTo(g[1],g2);
-    while(n <= km) {
-      g[n] = nbi();
-      z.mulTo(g2,g[n-2],g[n]);
-      n += 2;
-    }
-  }
-
-  var j = e.t-1, w, is1 = true, r2 = nbi(), t;
-  i = nbits(e[j])-1;
-  while(j >= 0) {
-    if(i >= k1) w = (e[j]>>(i-k1))&km;
-    else {
-      w = (e[j]&((1<<(i+1))-1))<<(k1-i);
-      if(j > 0) w |= e[j-1]>>(this.DB+i-k1);
-    }
-
-    n = k;
-    while((w&1) == 0) { w >>= 1; --n; }
-    if((i -= n) < 0) { i += this.DB; --j; }
-    if(is1) {	// ret == 1, don't bother squaring or multiplying it
-      g[w].copyTo(r);
-      is1 = false;
-    }
-    else {
-      while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; }
-      if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; }
-      z.mulTo(r2,g[w],r);
-    }
-
-    while(j >= 0 && (e[j]&(1<<i)) == 0) {
-      z.sqrTo(r,r2); t = r; r = r2; r2 = t;
-      if(--i < 0) { i = this.DB-1; --j; }
-    }
-  }
-  return z.revert(r);
-}
-
-// (public) gcd(this,a) (HAC 14.54)
-function bnGCD(a) {
-  var x = (this.s<0)?this.negate():this.clone();
-  var y = (a.s<0)?a.negate():a.clone();
-  if(x.compareTo(y) < 0) { var t = x; x = y; y = t; }
-  var i = x.getLowestSetBit(), g = y.getLowestSetBit();
-  if(g < 0) return x;
-  if(i < g) g = i;
-  if(g > 0) {
-    x.rShiftTo(g,x);
-    y.rShiftTo(g,y);
-  }
-  while(x.signum() > 0) {
-    if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x);
-    if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y);
-    if(x.compareTo(y) >= 0) {
-      x.subTo(y,x);
-      x.rShiftTo(1,x);
-    }
-    else {
-      y.subTo(x,y);
-      y.rShiftTo(1,y);
-    }
-  }
-  if(g > 0) y.lShiftTo(g,y);
-  return y;
-}
-
-// (protected) this % n, n < 2^26
-function bnpModInt(n) {
-  if(n <= 0) return 0;
-  var d = this.DV%n, r = (this.s<0)?n-1:0;
-  if(this.t > 0)
-    if(d == 0) r = this[0]%n;
-    else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n;
-  return r;
-}
-
-// (public) 1/this % m (HAC 14.61)
-function bnModInverse(m) {
-  var ac = m.isEven();
-  if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO;
-  var u = m.clone(), v = this.clone();
-  var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1);
-  while(u.signum() != 0) {
-    while(u.isEven()) {
-      u.rShiftTo(1,u);
-      if(ac) {
-        if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); }
-        a.rShiftTo(1,a);
-      }
-      else if(!b.isEven()) b.subTo(m,b);
-      b.rShiftTo(1,b);
-    }
-    while(v.isEven()) {
-      v.rShiftTo(1,v);
-      if(ac) {
-        if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); }
-        c.rShiftTo(1,c);
-      }
-      else if(!d.isEven()) d.subTo(m,d);
-      d.rShiftTo(1,d);
-    }
-    if(u.compareTo(v) >= 0) {
-      u.subTo(v,u);
-      if(ac) a.subTo(c,a);
-      b.subTo(d,b);
-    }
-    else {
-      v.subTo(u,v);
-      if(ac) c.subTo(a,c);
-      d.subTo(b,d);
-    }
-  }
-  if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;
-  if(d.compareTo(m) >= 0) return d.subtract(m);
-  if(d.signum() < 0) d.addTo(m,d); else return d;
-  if(d.signum() < 0) return d.add(m); else return d;
-}
-
-var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509];
-var lplim = (1<<26)/lowprimes[lowprimes.length-1];
-
-// (public) test primality with certainty >= 1-.5^t
-function bnIsProbablePrime(t) {
-  var i, x = this.abs();
-  if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) {
-    for(i = 0; i < lowprimes.length; ++i)
-      if(x[0] == lowprimes[i]) return true;
-    return false;
-  }
-  if(x.isEven()) return false;
-  i = 1;
-  while(i < lowprimes.length) {
-    var m = lowprimes[i], j = i+1;
-    while(j < lowprimes.length && m < lplim) m *= lowprimes[j++];
-    m = x.modInt(m);
-    while(i < j) if(m%lowprimes[i++] == 0) return false;
-  }
-  return x.millerRabin(t);
-}
-
-// (protected) true if probably prime (HAC 4.24, Miller-Rabin)
-function bnpMillerRabin(t) {
-  var n1 = this.subtract(BigInteger.ONE);
-  var k = n1.getLowestSetBit();
-  if(k <= 0) return false;
-  var r = n1.shiftRight(k);
-  t = (t+1)>>1;
-  if(t > lowprimes.length) t = lowprimes.length;
-  var a = nbi();
-  for(var i = 0; i < t; ++i) {
-    a.fromInt(lowprimes[i]);
-    var y = a.modPow(r,this);
-    if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
-      var j = 1;
-      while(j++ < k && y.compareTo(n1) != 0) {
-        y = y.modPowInt(2,this);
-        if(y.compareTo(BigInteger.ONE) == 0) return false;
-      }
-      if(y.compareTo(n1) != 0) return false;
-    }
-  }
-  return true;
-}
-
-// protected
-BigInteger.prototype.chunkSize = bnpChunkSize;
-BigInteger.prototype.toRadix = bnpToRadix;
-BigInteger.prototype.fromRadix = bnpFromRadix;
-BigInteger.prototype.fromNumber = bnpFromNumber;
-BigInteger.prototype.bitwiseTo = bnpBitwiseTo;
-BigInteger.prototype.changeBit = bnpChangeBit;
-BigInteger.prototype.addTo = bnpAddTo;
-BigInteger.prototype.dMultiply = bnpDMultiply;
-BigInteger.prototype.dAddOffset = bnpDAddOffset;
-BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;
-BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;
-BigInteger.prototype.modInt = bnpModInt;
-BigInteger.prototype.millerRabin = bnpMillerRabin;
-
-// public
-BigInteger.prototype.clone = bnClone;
-BigInteger.prototype.intValue = bnIntValue;
-BigInteger.prototype.byteValue = bnByteValue;
-BigInteger.prototype.shortValue = bnShortValue;
-BigInteger.prototype.signum = bnSigNum;
-BigInteger.prototype.toByteArray = bnToByteArray;
-BigInteger.prototype.equals = bnEquals;
-BigInteger.prototype.min = bnMin;
-BigInteger.prototype.max = bnMax;
-BigInteger.prototype.and = bnAnd;
-BigInteger.prototype.or = bnOr;
-BigInteger.prototype.xor = bnXor;
-BigInteger.prototype.andNot = bnAndNot;
-BigInteger.prototype.not = bnNot;
-BigInteger.prototype.shiftLeft = bnShiftLeft;
-BigInteger.prototype.shiftRight = bnShiftRight;
-BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;
-BigInteger.prototype.bitCount = bnBitCount;
-BigInteger.prototype.testBit = bnTestBit;
-BigInteger.prototype.setBit = bnSetBit;
-BigInteger.prototype.clearBit = bnClearBit;
-BigInteger.prototype.flipBit = bnFlipBit;
-BigInteger.prototype.add = bnAdd;
-BigInteger.prototype.subtract = bnSubtract;
-BigInteger.prototype.multiply = bnMultiply;
-BigInteger.prototype.divide = bnDivide;
-BigInteger.prototype.remainder = bnRemainder;
-BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;
-BigInteger.prototype.modPow = bnModPow;
-BigInteger.prototype.modInverse = bnModInverse;
-BigInteger.prototype.pow = bnPow;
-BigInteger.prototype.gcd = bnGCD;
-BigInteger.prototype.isProbablePrime = bnIsProbablePrime;
-
-// BigInteger interfaces not implemented in jsbn:
-
-// BigInteger(int signum, byte[] magnitude)
-// double doubleValue()
-// float floatValue()
-// int hashCode()
-// long longValue()
-// static BigInteger valueOf(long val)
-/**
- * @author: Meki Cherkaoui, Jeff Thompson, Wentao Shang
- * See COPYING for copyright and distribution information.
- * This class represents the top-level object for communicating with an NDN host.
- */
-
-var LOG = 0;
-
-/**
- * settings is an associative array with the following defaults:
- * {
- *   getTransport: function() { return new WebSocketTransport(); },
- *   getHostAndPort: transport.defaultGetHostAndPort,
- *   host: null, // If null, use getHostAndPort when connecting.
- *   port: 9696,
- *   onopen: function() { if (LOG > 3) console.log("NDN connection established."); },
- *   onclose: function() { if (LOG > 3) console.log("NDN connection closed."); },
- *   verify: true // If false, don't verify and call upcall with Closure.UPCALL_CONTENT_UNVERIFIED.
- * }
- * 
- * getHostAndPort is a function, on each call it returns a new { host: host, port: port } or
- *   null if there are no more hosts.
- *   
- * This throws an exception if NDN.supported is false.
- */
-var NDN = function NDN(settings) {
-    if (!NDN.supported)
-        throw new Error("The necessary JavaScript support is not available on this platform.");
-    
-    settings = (settings || {});
-    var getTransport = (settings.getTransport || function() { return new WebSocketTransport(); });
-    this.transport = getTransport();
-    this.getHostAndPort = (settings.getHostAndPort || this.transport.defaultGetHostAndPort);
-	this.host = (settings.host !== undefined ? settings.host : null);
-	this.port = (settings.port || 9696);
-    this.readyStatus = NDN.UNOPEN;
-    this.verify = (settings.verify !== undefined ? settings.verify : true);
-    // Event handler
-    this.onopen = (settings.onopen || function() { if (LOG > 3) console.log("NDN connection established."); });
-    this.onclose = (settings.onclose || function() { if (LOG > 3) console.log("NDN connection closed."); });
-	this.ccndid = null;
-};
-
-NDN.UNOPEN = 0;  // created but not opened yet
-NDN.OPENED = 1;  // connection to ccnd opened
-NDN.CLOSED = 2;  // connection to ccnd closed
-
-/*
- * Return true if necessary JavaScript support is available, else log an error and return false.
- */
-NDN.getSupported = function() {
-    try {
-        var dummy = new Uint8Array(1).subarray(0, 1);
-    } catch (ex) {
-        console.log("NDN not available: Uint8Array not supported. " + ex);
-        return false;
-    }
-    
-    return true;
-};
-
-NDN.supported = NDN.getSupported();
-
-NDN.ccndIdFetcher = new Name('/%C1.M.S.localhost/%C1.M.SRV/ccnd/KEY');
-
-NDN.prototype.createRoute = function(host, port) {
-	this.host=host;
-	this.port=port;
-};
-
-
-NDN.KeyStore = new Array();
-
-var KeyStoreEntry = function KeyStoreEntry(name, rsa, time) {
-	this.keyName = name;  // KeyName
-	this.rsaKey = rsa;    // RSA key
-	this.timeStamp = time;  // Time Stamp
-};
-
-NDN.addKeyEntry = function(/* KeyStoreEntry */ keyEntry) {
-	var result = NDN.getKeyByName(keyEntry.keyName);
-	if (result == null) 
-		NDN.KeyStore.push(keyEntry);
-	else
-		result = keyEntry;
-};
-
-NDN.getKeyByName = function(/* KeyName */ name) {
-	var result = null;
-	
-	for (var i = 0; i < NDN.KeyStore.length; i++) {
-		if (NDN.KeyStore[i].keyName.contentName.match(name.contentName)) {
-            if (result == null || 
-                NDN.KeyStore[i].keyName.contentName.components.length > result.keyName.contentName.components.length)
-                result = NDN.KeyStore[i];
-        }
-	}
-    
-	return result;
-};
-
-// For fetching data
-NDN.PITTable = new Array();
-
-var PITEntry = function PITEntry(interest, closure) {
-	this.interest = interest;  // Interest
-	this.closure = closure;    // Closure
-	this.timerID = -1;  // Timer ID
-};
-
-/*
- * Return the entry from NDN.PITTable where the name conforms to the interest selectors, and
- * the interest name is the longest that matches name.
- */
-NDN.getEntryForExpressedInterest = function(/*Name*/ name) {
-    var result = null;
-    
-	for (var i = 0; i < NDN.PITTable.length; i++) {
-		if (NDN.PITTable[i].interest.matches_name(name)) {
-            if (result == null || 
-                NDN.PITTable[i].interest.name.components.length > result.interest.name.components.length)
-                result = NDN.PITTable[i];
-        }
-	}
-    
-	return result;
-};
-
-// For publishing data
-NDN.CSTable = new Array();
-
-var CSEntry = function CSEntry(name, closure) {
-	this.name = name;        // String
-	this.closure = closure;  // Closure
-};
-
-function getEntryForRegisteredPrefix(name) {
-	for (var i = 0; i < NDN.CSTable.length; i++) {
-		if (NDN.CSTable[i].name.match(name) != null)
-			return NDN.CSTable[i];
-	}
-	return null;
-}
-
-/*
- * Return a function that selects a host at random from hostList and returns { host: host, port: port }.
- * If no more hosts remain, return null.
- */
-NDN.makeShuffledGetHostAndPort = function(hostList, port) {
-    // Make a copy.
-    hostList = hostList.slice(0, hostList.length);
-    DataUtils.shuffle(hostList);
-
-    return function() {
-        if (hostList.length == 0)
-            return null;
-        
-        return { host: hostList.splice(0, 1)[0], port: port };
-    };
-};
-
-/** Encode name as an Interest. If template is not null, use its attributes.
- *  Send the interest to host:port, read the entire response and call
- *  closure.upcall(Closure.UPCALL_CONTENT (or Closure.UPCALL_CONTENT_UNVERIFIED),
- *                 new UpcallInfo(this, interest, 0, contentObject)).                 
- */
-NDN.prototype.expressInterest = function(
-        // Name
-        name,
-        // Closure
-        closure,
-        // Interest
-        template) {
-	var interest = new Interest(name);
-    if (template != null) {
-		interest.minSuffixComponents = template.minSuffixComponents;
-		interest.maxSuffixComponents = template.maxSuffixComponents;
-		interest.publisherPublicKeyDigest = template.publisherPublicKeyDigest;
-		interest.exclude = template.exclude;
-		interest.childSelector = template.childSelector;
-		interest.answerOriginKind = template.answerOriginKind;
-		interest.scope = template.scope;
-		interest.interestLifetime = template.interestLifetime;
-    }
-    else
-        interest.interestLifetime = 4000;   // default interest timeout value in milliseconds.
-
-	if (this.host == null || this.port == null) {
-        if (this.getHostAndPort == null)
-            console.log('ERROR: host OR port NOT SET');
-        else {
-            var thisNDN = this;
-            this.connectAndExecute
-                (function() { thisNDN.reconnectAndExpressInterest(interest, closure); });
-        }
-    }
-    else
-        this.reconnectAndExpressInterest(interest, closure);
-};
-
-/*
- * If the host and port are different than the ones in this.transport, then call
- *   this.transport.connect to change the connection (or connect for the first time).
- * Then call expressInterestHelper.
- */
-NDN.prototype.reconnectAndExpressInterest = function(interest, closure) {
-    if (this.transport.connectedHost != this.host || this.transport.connectedPort != this.port) {
-        var thisNDN = this;
-        this.transport.connect(thisNDN, function() { thisNDN.expressInterestHelper(interest, closure); });
-    }
-    else
-        this.expressInterestHelper(interest, closure);
-};
-
-/*
- * Do the work of reconnectAndExpressInterest once we know we are connected.  Set the PITTable and call
- *   this.transport.send to send the interest.
- */
-NDN.prototype.expressInterestHelper = function(interest, closure) {
-    var binaryInterest = encodeToBinaryInterest(interest);
-    var thisNDN = this;    
-	//TODO: check local content store first
-	if (closure != null) {
-		var pitEntry = new PITEntry(interest, closure);
-        // TODO: This needs to be a single thread-safe transaction on a global object.
-		NDN.PITTable.push(pitEntry);
-		closure.pitEntry = pitEntry;
-
-        // Set interest timer.
-        var timeoutMilliseconds = (interest.interestLifetime || 4000);
-        var timeoutCallback = function() {
-			if (LOG > 1) console.log("Interest time out: " + interest.name.to_uri());
-				
-			// Remove PIT entry from NDN.PITTable, even if we add it again later to re-express
-            //   the interest because we don't want to match it in the mean time.
-            // TODO: Make this a thread-safe operation on the global PITTable.
-			var index = NDN.PITTable.indexOf(pitEntry);
-			if (index >= 0) 
-	            NDN.PITTable.splice(index, 1);
-				
-			// Raise closure callback
-			if (closure.upcall(Closure.UPCALL_INTEREST_TIMED_OUT, 
-                  new UpcallInfo(thisNDN, interest, 0, null)) == Closure.RESULT_REEXPRESS) {
-			    if (LOG > 1) console.log("Re-express interest: " + interest.name.to_uri());
-                pitEntry.timerID = setTimeout(timeoutCallback, timeoutMilliseconds);
-                NDN.PITTable.push(pitEntry);
-                thisNDN.transport.send(binaryInterest);
-            }
-		};
-		pitEntry.timerID = setTimeout(timeoutCallback, timeoutMilliseconds);
-	}
-
-	this.transport.send(binaryInterest);
-};
-
-NDN.prototype.registerPrefix = function(name, closure, flag) {
-    var thisNDN = this;
-    var onConnected = function() {
-    	if (thisNDN.ccndid == null) {
-            // Fetch ccndid first, then register.
-            var interest = new Interest(NDN.ccndIdFetcher);
-    		interest.interestLifetime = 4000; // milliseconds
-            if (LOG>3) console.log('Expressing interest for ccndid from ccnd.');
-            thisNDN.reconnectAndExpressInterest
-               (interest, new NDN.FetchCcndidClosure(thisNDN, name, closure, flag));
-        }
-        else	
-            thisNDN.registerPrefixHelper(name, closure, flag);
-    };
-
-	if (this.host == null || this.port == null) {
-        if (this.getHostAndPort == null)
-            console.log('ERROR: host OR port NOT SET');
-        else
-            this.connectAndExecute(onConnected);
-    }
-    else
-        onConnected();
-};
-
-/*
- * This is a closure to receive the ContentObject for NDN.ccndIdFetcher and call
- *   registerPrefixHelper(name, callerClosure, flag).
- */
-NDN.FetchCcndidClosure = function FetchCcndidClosure(ndn, name, callerClosure, flag) {
-    // Inherit from Closure.
-    Closure.call(this);
-    
-    this.ndn = ndn;
-    this.name = name;
-    this.callerClosure = callerClosure;
-    this.flag = flag;
-};
-
-NDN.FetchCcndidClosure.prototype.upcall = function(kind, upcallInfo) {
-    if (kind == Closure.UPCALL_INTEREST_TIMED_OUT) {
-        console.log("Timeout while requesting the ccndid.  Cannot registerPrefix for " +
-            this.name.to_uri() + " .");
-        return Closure.RESULT_OK;
-    }
-    if (!(kind == Closure.UPCALL_CONTENT ||
-          kind == Closure.UPCALL_CONTENT_UNVERIFIED))
-        // The upcall is not for us.
-        return Closure.RESULT_ERR;
-       
-    var co = upcallInfo.contentObject;
-    if (!co.signedInfo || !co.signedInfo.publisher 
-		|| !co.signedInfo.publisher.publisherPublicKeyDigest)
-        console.log
-          ("ContentObject doesn't have a publisherPublicKeyDigest. Cannot set ccndid and registerPrefix for "
-           + this.name.to_uri() + " .");
-    else {
-		if (LOG>3) console.log('Got ccndid from ccnd.');
-		this.ndn.ccndid = co.signedInfo.publisher.publisherPublicKeyDigest;
-		if (LOG>3) console.log(this.ndn.ccndid);
-        
-        this.ndn.registerPrefixHelper(this.name, this.callerClosure, this.flag);
-	}
-    
-    return Closure.RESULT_OK;
-};
-
-/*
- * Do the work of registerPrefix once we know we are connected with a ccndid.
- */
-NDN.prototype.registerPrefixHelper = function(name, closure, flag) {
-	var fe = new ForwardingEntry('selfreg', name, null, null, 3, 2147483647);
-	var bytes = encodeForwardingEntry(fe);
-		
-	var si = new SignedInfo();
-	si.setFields();
-		
-	var co = new ContentObject(new Name(), si, bytes, new Signature()); 
-	co.sign();
-	var coBinary = encodeToBinaryContentObject(co);
-		
-	//var nodename = unescape('%00%88%E2%F4%9C%91%16%16%D6%21%8E%A0c%95%A5%A6r%11%E0%A0%82%89%A6%A9%85%AB%D6%E2%065%DB%AF');
-	var nodename = this.ccndid;
-	var interestName = new Name(['ccnx', nodename, 'selfreg', coBinary]);
-
-	var interest = new Interest(interestName);
-	interest.scope = 1;
-	if (LOG > 3) console.log('Send Interest registration packet.');
-    	
-    var csEntry = new CSEntry(name.getName(), closure);
-	NDN.CSTable.push(csEntry);
-    
-    this.transport.send(encodeToBinaryInterest(interest));
-};
-
-/*
- * This is called when an entire binary XML element is received, such as a ContentObject or Interest.
- * Look up in the PITTable and call the closure callback.
- */
-NDN.prototype.onReceivedElement = function(element) {
-    if (LOG>3) console.log('Complete element received. Length ' + element.length + '. Start decoding.');
-	var decoder = new BinaryXMLDecoder(element);
-	// Dispatch according to packet type
-	if (decoder.peekStartElement(CCNProtocolDTags.Interest)) {  // Interest packet
-		if (LOG > 3) console.log('Interest packet received.');
-				
-		var interest = new Interest();
-		interest.from_ccnb(decoder);
-		if (LOG > 3) console.log(interest);
-		var nameStr = escape(interest.name.getName());
-		if (LOG > 3) console.log(nameStr);
-				
-		var entry = getEntryForRegisteredPrefix(nameStr);
-		if (entry != null) {
-			//console.log(entry);
-			var info = new UpcallInfo(this, interest, 0, null);
-			var ret = entry.closure.upcall(Closure.UPCALL_INTEREST, info);
-			if (ret == Closure.RESULT_INTEREST_CONSUMED && info.contentObject != null) 
-				this.transport.send(encodeToBinaryContentObject(info.contentObject));
-		}				
-	} else if (decoder.peekStartElement(CCNProtocolDTags.ContentObject)) {  // Content packet
-		if (LOG > 3) console.log('ContentObject packet received.');
-				
-		var co = new ContentObject();
-		co.from_ccnb(decoder);
-				
-		var pitEntry = NDN.getEntryForExpressedInterest(co.name);
-		if (pitEntry != null) {
-			// Cancel interest timer
-			clearTimeout(pitEntry.timerID);
-            
-			// Remove PIT entry from NDN.PITTable
-			var index = NDN.PITTable.indexOf(pitEntry);
-			if (index >= 0)
-				NDN.PITTable.splice(index, 1);
-						
-			var currentClosure = pitEntry.closure;
-										
-			if (this.verify == false) {
-				// Pass content up without verifying the signature
-				currentClosure.upcall(Closure.UPCALL_CONTENT_UNVERIFIED, new UpcallInfo(this, null, 0, co));
-				return;
-			}
-				
-			// Key verification
-						
-			// Recursive key fetching & verification closure
-			var KeyFetchClosure = function KeyFetchClosure(content, closure, key, sig, wit) {
-				this.contentObject = content;  // unverified content object
-				this.closure = closure;  // closure corresponding to the contentObject
-				this.keyName = key;  // name of current key to be fetched
-				this.sigHex = sig;  // hex signature string to be verified
-				this.witness = wit;
-						
-				Closure.call(this);
-			};
-						
-            var thisNDN = this;
-			KeyFetchClosure.prototype.upcall = function(kind, upcallInfo) {
-				if (kind == Closure.UPCALL_INTEREST_TIMED_OUT) {
-					console.log("In KeyFetchClosure.upcall: interest time out.");
-					console.log(this.keyName.contentName.getName());
-				} else if (kind == Closure.UPCALL_CONTENT) {
-					//console.log("In KeyFetchClosure.upcall: signature verification passed");
-								
-					var rsakey = decodeSubjectPublicKeyInfo(upcallInfo.contentObject.content);
-					var verified = rsakey.verifyByteArray(this.contentObject.rawSignatureData, this.witness, this.sigHex);
-								
-					var flag = (verified == true) ? Closure.UPCALL_CONTENT : Closure.UPCALL_CONTENT_BAD;
-					//console.log("raise encapsulated closure");
-					this.closure.upcall(flag, new UpcallInfo(thisNDN, null, 0, this.contentObject));
-								
-					// Store key in cache
-					var keyEntry = new KeyStoreEntry(keylocator.keyName, rsakey, new Date().getTime());
-					NDN.addKeyEntry(keyEntry);
-					//console.log(NDN.KeyStore);
-				} else if (kind == Closure.UPCALL_CONTENT_BAD) {
-					console.log("In KeyFetchClosure.upcall: signature verification failed");
-				}
-			};
-						
-			if (co.signedInfo && co.signedInfo.locator && co.signature) {
-				if (LOG > 3) console.log("Key verification...");
-				var sigHex = DataUtils.toHex(co.signature.signature).toLowerCase();
-							
-				var wit = null;
-				if (co.signature.Witness != null) {
-					wit = new Witness();
-					wit.decode(co.signature.Witness);
-				}
-							
-				var keylocator = co.signedInfo.locator;
-				if (keylocator.type == KeyLocatorType.KEYNAME) {
-					if (LOG > 3) console.log("KeyLocator contains KEYNAME");
-					//var keyname = keylocator.keyName.contentName.getName();
-					//console.log(nameStr);
-					//console.log(keyname);
-								
-					if (keylocator.keyName.contentName.match(co.name)) {
-						if (LOG > 3) console.log("Content is key itself");
-									
-						var rsakey = decodeSubjectPublicKeyInfo(co.content);
-						var verified = rsakey.verifyByteArray(co.rawSignatureData, wit, sigHex);
-						var flag = (verified == true) ? Closure.UPCALL_CONTENT : Closure.UPCALL_CONTENT_BAD;
-									
-						currentClosure.upcall(flag, new UpcallInfo(this, null, 0, co));
-									
-						// SWT: We don't need to store key here since the same key will be
-						//      stored again in the closure.
-						//var keyEntry = new KeyStoreEntry(keylocator.keyName, rsakey, new Date().getTime());
-						//NDN.addKeyEntry(keyEntry);
-						//console.log(NDN.KeyStore);
-					} else {
-						// Check local key store
-						var keyEntry = NDN.getKeyByName(keylocator.keyName);
-						if (keyEntry) {
-							// Key found, verify now
-							if (LOG > 3) console.log("Local key cache hit");
-							var rsakey = keyEntry.rsaKey;
-							var verified = rsakey.verifyByteArray(co.rawSignatureData, wit, sigHex);
-							var flag = (verified == true) ? Closure.UPCALL_CONTENT : Closure.UPCALL_CONTENT_BAD;
-										
-							// Raise callback
-							currentClosure.upcall(flag, new UpcallInfo(this, null, 0, co));
-						} else {
-							// Not found, fetch now
-							if (LOG > 3) console.log("Fetch key according to keylocator");
-							var nextClosure = new KeyFetchClosure(co, currentClosure, keylocator.keyName, sigHex, wit);
-							this.expressInterest(keylocator.keyName.contentName.getPrefix(4), nextClosure);
-						}
-					}
-				} else if (keylocator.type == KeyLocatorType.KEY) {
-					if (LOG > 3) console.log("Keylocator contains KEY");
-								
-					var rsakey = decodeSubjectPublicKeyInfo(co.signedInfo.locator.publicKey);
-					var verified = rsakey.verifyByteArray(co.rawSignatureData, wit, sigHex);
-							
-					var flag = (verified == true) ? Closure.UPCALL_CONTENT : Closure.UPCALL_CONTENT_BAD;
-					// Raise callback
-					currentClosure.upcall(Closure.UPCALL_CONTENT, new UpcallInfo(this, null, 0, co));
-								
-					// Since KeyLocator does not contain key name for this key,
-					// we have no way to store it as a key entry in KeyStore.
-				} else {
-					var cert = keylocator.certificate;
-					console.log("KeyLocator contains CERT");
-					console.log(cert);
-								
-					// TODO: verify certificate
-				}
-			}
-		}
-	} else
-		console.log('Incoming packet is not Interest or ContentObject. Discard now.');
-};
-
-/*
- * Assume this.getHostAndPort is not null.  This is called when this.host is null or its host
- *   is not alive.  Get a host and port, connect, then execute onConnected().
- */
-NDN.prototype.connectAndExecute = function(onConnected) {
-    var hostAndPort = this.getHostAndPort();
-    if (hostAndPort == null) {
-        console.log('ERROR: No more hosts from getHostAndPort');
-        this.host = null;
-        return;
-    }
-
-    if (hostAndPort.host == this.host && hostAndPort.port == this.port) {
-        console.log('ERROR: The host returned by getHostAndPort is not alive: ' + 
-                this.host + ":" + this.port);
-        return;
-    }
-        
-    this.host = hostAndPort.host;
-    this.port = hostAndPort.port;   
-    if (LOG>0) console.log("connectAndExecute: trying host from getHostAndPort: " + this.host);
-    
-    // Fetch any content.
-    var interest = new Interest(new Name("/"));
-	interest.interestLifetime = 4000; // milliseconds    
-
-    var thisNDN = this;
-	var timerID = setTimeout(function() {
-        if (LOG>0) console.log("connectAndExecute: timeout waiting for host " + thisNDN.host);
-        // Try again.
-        thisNDN.connectAndExecute(onConnected);
-	}, 3000);
-  
-    this.reconnectAndExpressInterest
-        (interest, new NDN.ConnectClosure(this, onConnected, timerID));
-};
-
-NDN.ConnectClosure = function ConnectClosure(ndn, onConnected, timerID) {
-    // Inherit from Closure.
-    Closure.call(this);
-    
-    this.ndn = ndn;
-    this.onConnected = onConnected;
-    this.timerID = timerID;
-};
-
-NDN.ConnectClosure.prototype.upcall = function(kind, upcallInfo) {
-    if (!(kind == Closure.UPCALL_CONTENT ||
-          kind == Closure.UPCALL_CONTENT_UNVERIFIED))
-        // The upcall is not for us.
-        return Closure.RESULT_ERR;
-        
-    // The host is alive, so cancel the timeout and continue with onConnected().
-    clearTimeout(this.timerID);
-
-    // Call NDN.onopen after success
-	this.ndn.readyStatus = NDN.OPENED;
-	this.ndn.onopen();
-
-    if (LOG>0) console.log("connectAndExecute: connected to host " + this.ndn.host);
-    this.onConnected();
-
-    return Closure.RESULT_OK;
-};
-
-/*
- * A BinaryXmlElementReader lets you call onReceivedData multiple times which uses a
- *   BinaryXMLStructureDecoder to detect the end of a binary XML element and calls
- *   elementListener.onReceivedElement(element) with the element. 
- * This handles the case where a single call to onReceivedData may contain multiple elements.
- */
-var BinaryXmlElementReader = function BinaryXmlElementReader(elementListener) {
-    this.elementListener = elementListener;
-	this.dataParts = [];
-    this.structureDecoder = new BinaryXMLStructureDecoder();
-};
-
-BinaryXmlElementReader.prototype.onReceivedData = function(/* Uint8Array */ rawData) {
-    // Process multiple objects in the data.
-    while(true) {
-        // Scan the input to check if a whole ccnb object has been read.
-        this.structureDecoder.seek(0);
-        if (this.structureDecoder.findElementEnd(rawData)) {
-            // Got the remainder of an object.  Report to the caller.
-            this.dataParts.push(rawData.subarray(0, this.structureDecoder.offset));
-            var element = DataUtils.concatArrays(this.dataParts);
-            this.dataParts = [];
-            try {
-                this.elementListener.onReceivedElement(element);
-            } catch (ex) {
-                console.log("BinaryXmlElementReader: ignoring exception from onReceivedElement: " + ex);
-            }
-        
-            // Need to read a new object.
-            rawData = rawData.subarray(this.structureDecoder.offset, rawData.length);
-            this.structureDecoder = new BinaryXMLStructureDecoder();
-            if (rawData.length == 0)
-                // No more data in the packet.
-                return;
-            
-            // else loop back to decode.
-        }
-        else {
-            // Save for a later call to concatArrays so that we only copy data once.
-            this.dataParts.push(rawData);
-			if (LOG>3) console.log('Incomplete packet received. Length ' + rawData.length + '. Wait for more input.');
-            return;
-        }
-    }    
-}
\ No newline at end of file
diff --git a/js/tools/build/ndn-js.js b/js/tools/build/ndn-js.js
deleted file mode 100644
index e5cba68..0000000
--- a/js/tools/build/ndn-js.js
+++ /dev/null
@@ -1,283 +0,0 @@
-var Closure=function(){this.ndn_data=null;this.ndn_data_dirty=!1};Closure.RESULT_ERR=-1;Closure.RESULT_OK=0;Closure.RESULT_REEXPRESS=1;Closure.RESULT_INTEREST_CONSUMED=2;Closure.RESULT_VERIFY=3;Closure.RESULT_FETCHKEY=4;Closure.UPCALL_FINAL=0;Closure.UPCALL_INTEREST=1;Closure.UPCALL_CONSUMED_INTEREST=2;Closure.UPCALL_CONTENT=3;Closure.UPCALL_INTEREST_TIMED_OUT=4;Closure.UPCALL_CONTENT_UNVERIFIED=5;Closure.UPCALL_CONTENT_BAD=6;Closure.prototype.upcall=function(){return Closure.RESULT_OK};
-var UpcallInfo=function(a,b,c,d){this.ndn=a;this.interest=b;this.matchedComps=c;this.contentObject=d};UpcallInfo.prototype.toString=function(){var a="ndn = "+this.ndn,a=a+("\nInterest = "+this.interest),a=a+("\nmatchedComps = "+this.matchedComps);return a+="\nContentObject: "+this.contentObject};
-var WebSocketTransport=function(){if(!WebSocket)throw Error("WebSocket support is not available on this platform.");this.elementReader=this.connectedPort=this.connectedHost=this.ws=null;this.defaultGetHostAndPort=NDN.makeShuffledGetHostAndPort(["A.ws.ndn.ucla.edu","B.ws.ndn.ucla.edu","C.ws.ndn.ucla.edu","D.ws.ndn.ucla.edu","E.ws.ndn.ucla.edu"],9696)};
-WebSocketTransport.prototype.connect=function(a,b){null!=this.ws&&delete this.ws;this.ws=new WebSocket("ws://"+a.host+":"+a.port);0<LOG&&console.log("ws connection created.");this.connectedHost=a.host;this.connectedPort=a.port;this.ws.binaryType="arraybuffer";this.elementReader=new BinaryXmlElementReader(a);var c=this;this.ws.onmessage=function(a){a=a.data;if(null==a||void 0==a||""==a)console.log("INVALID ANSWER");else if(a instanceof ArrayBuffer){a=new Uint8Array(a);3<LOG&&console.log("BINARY RESPONSE IS "+
-DataUtils.toHex(a));try{c.elementReader.onReceivedData(a)}catch(b){console.log("NDN.ws.onmessage exception: "+b)}}};this.ws.onopen=function(a){3<LOG&&console.log(a);3<LOG&&console.log("ws.onopen: WebSocket connection opened.");3<LOG&&console.log("ws.onopen: ReadyState: "+this.readyState);b()};this.ws.onerror=function(a){console.log("ws.onerror: ReadyState: "+this.readyState);console.log(a);console.log("ws.onerror: WebSocket error: "+a.data)};this.ws.onclose=function(){console.log("ws.onclose: WebSocket connection closed.");
-c.ws=null;a.readyStatus=NDN.CLOSED;a.onclose()}};WebSocketTransport.prototype.send=function(a){if(null!=this.ws){var b=new Uint8Array(a.length);b.set(a);this.ws.send(b.buffer);3<LOG&&console.log("ws.send() returned.")}else console.log("WebSocket connection is not established.")};
-var CCNProtocolDTags={Any:13,Name:14,Component:15,Certificate:16,Collection:17,CompleteName:18,Content:19,SignedInfo:20,ContentDigest:21,ContentHash:22,Count:24,Header:25,Interest:26,Key:27,KeyLocator:28,KeyName:29,Length:30,Link:31,LinkAuthenticator:32,NameComponentCount:33,RootDigest:36,Signature:37,Start:38,Timestamp:39,Type:40,Nonce:41,Scope:42,Exclude:43,Bloom:44,BloomSeed:45,AnswerOriginKind:47,InterestLifetime:48,Witness:53,SignatureBits:54,DigestAlgorithm:55,BlockSize:56,FreshnessSeconds:58,
-FinalBlockID:59,PublisherPublicKeyDigest:60,PublisherCertificateDigest:61,PublisherIssuerKeyDigest:62,PublisherIssuerCertificateDigest:63,ContentObject:64,WrappedKey:65,WrappingKeyIdentifier:66,WrapAlgorithm:67,KeyAlgorithm:68,Label:69,EncryptedKey:70,EncryptedNonceKey:71,WrappingKeyName:72,Action:73,FaceID:74,IPProto:75,Host:76,Port:77,MulticastInterface:78,ForwardingFlags:79,FaceInstance:80,ForwardingEntry:81,MulticastTTL:82,MinSuffixComponents:83,MaxSuffixComponents:84,ChildSelector:85,RepositoryInfo:86,
-Version:87,RepositoryVersion:88,GlobalPrefix:89,LocalName:90,Policy:91,Namespace:92,GlobalPrefixName:93,PolicyVersion:94,KeyValueSet:95,KeyValuePair:96,IntegerValue:97,DecimalValue:98,StringValue:99,BinaryValue:100,NameValue:101,Entry:102,ACL:103,ParameterizedName:104,Prefix:105,Suffix:106,Root:107,ProfileName:108,Parameters:109,InfoString:110,StatusResponse:112,StatusCode:113,StatusText:114,SyncNode:115,SyncNodeKind:116,SyncNodeElement:117,SyncVersion:118,SyncNodeElements:119,SyncContentHash:120,
-SyncLeafCount:121,SyncTreeDepth:122,SyncByteCount:123,ConfigSlice:124,ConfigSliceList:125,ConfigSliceOp:126,CCNProtocolDataUnit:17702112,CCNPROTOCOL_DATA_UNIT:"CCNProtocolDataUnit"},CCNProtocolDTagsStrings=[null,null,null,null,null,null,null,null,null,null,null,null,null,"Any","Name","Component","Certificate","Collection","CompleteName","Content","SignedInfo","ContentDigest","ContentHash",null,"Count","Header","Interest","Key","KeyLocator","KeyName","Length","Link","LinkAuthenticator","NameComponentCount",
-null,null,"RootDigest","Signature","Start","Timestamp","Type","Nonce","Scope","Exclude","Bloom","BloomSeed",null,"AnswerOriginKind","InterestLifetime",null,null,null,null,"Witness","SignatureBits","DigestAlgorithm","BlockSize",null,"FreshnessSeconds","FinalBlockID","PublisherPublicKeyDigest","PublisherCertificateDigest","PublisherIssuerKeyDigest","PublisherIssuerCertificateDigest","ContentObject","WrappedKey","WrappingKeyIdentifier","WrapAlgorithm","KeyAlgorithm","Label","EncryptedKey","EncryptedNonceKey",
-"WrappingKeyName","Action","FaceID","IPProto","Host","Port","MulticastInterface","ForwardingFlags","FaceInstance","ForwardingEntry","MulticastTTL","MinSuffixComponents","MaxSuffixComponents","ChildSelector","RepositoryInfo","Version","RepositoryVersion","GlobalPrefix","LocalName","Policy","Namespace","GlobalPrefixName","PolicyVersion","KeyValueSet","KeyValuePair","IntegerValue","DecimalValue","StringValue","BinaryValue","NameValue","Entry","ACL","ParameterizedName","Prefix","Suffix","Root","ProfileName",
-"Parameters","InfoString",null,"StatusResponse","StatusCode","StatusText","SyncNode","SyncNodeKind","SyncNodeElement","SyncVersion","SyncNodeElements","SyncContentHash","SyncLeafCount","SyncTreeDepth","SyncByteCount","ConfigSlice","ConfigSliceList","ConfigSliceOp"],CCNTime=function(a){this.NANOS_MAX=999877929;"number"==typeof a?this.msec=a:1<LOG&&console.log("UNRECOGNIZED TYPE FOR TIME")};CCNTime.prototype.getJavascriptDate=function(){var a=new Date;a.setTime(this.msec);return a};
-var ExponentialReExpressClosure=function(a,b){Closure.call(this);this.callerClosure=a;b=b||{};this.maxInterestLifetime=b.maxInterestLifetime||16E3};
-ExponentialReExpressClosure.prototype.upcall=function(a,b){try{if(a==Closure.UPCALL_INTEREST_TIMED_OUT){var c=b.interest.interestLifetime;if(null==c)return this.callerClosure.upcall(Closure.UPCALL_INTEREST_TIMED_OUT,b);c*=2;if(c>this.maxInterestLifetime)return this.callerClosure.upcall(Closure.UPCALL_INTEREST_TIMED_OUT,b);var d=b.interest.clone();d.interestLifetime=c;b.ndn.expressInterest(d.name,this,d);return Closure.RESULT_OK}return this.callerClosure.upcall(a,b)}catch(e){return console.log("ExponentialReExpressClosure.upcall exception: "+
-e),Closure.RESULT_ERR}};var Name=function Name(b){if("string"==typeof b)3<LOG&&console.log("Content Name String "+b),this.components=Name.createNameArray(b);else if("object"===typeof b)if(this.components=[],b instanceof Name)this.add(b);else for(var c=0;c<b.length;++c)this.add(b[c]);else null==b?this.components=[]:1<LOG&&console.log("NO CONTENT NAME GIVEN")};Name.prototype.getName=function(){return this.to_uri()};
-Name.createNameArray=function(a){a=a.trim();if(0>=a.length)return[];var b=a.indexOf(":");if(0<=b){var c=a.indexOf("/");if(0>c||b<c)a=a.substr(b+1,a.length-b-1).trim()}if("/"==a[0])if(2<=a.length&&"/"==a[1]){b=a.indexOf("/",2);if(0>b)return[];a=a.substr(b+1,a.length-b-1).trim()}else a=a.substr(1,a.length-1).trim();a=a.split("/");for(b=0;b<a.length;++b)c=Name.fromEscapedString(a[b]),null==c?(a.splice(b,1),--b):a[b]=c;return a};
-Name.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());for(this.components=[];a.peekStartElement(CCNProtocolDTags.Component);)this.add(a.readBinaryElement(CCNProtocolDTags.Component));a.readEndElement()};Name.prototype.to_ccnb=function(a){if(null==this.components)throw Error("CANNOT ENCODE EMPTY CONTENT NAME");a.writeStartElement(this.getElementLabel());for(var b=this.components.length,c=0;c<b;c++)a.writeElement(CCNProtocolDTags.Component,this.components[c]);a.writeEndElement()};
-Name.prototype.getElementLabel=function(){return CCNProtocolDTags.Name};
-Name.prototype.add=function(a){var b;if("string"==typeof a)b=DataUtils.stringToUtf8Array(a);else if("object"==typeof a&&a instanceof Uint8Array)b=new Uint8Array(a);else if("object"==typeof a&&a instanceof ArrayBuffer)b=new Uint8Array(new ArrayBuffer(a.byteLength)),b.set(new Uint8Array(a));else{if("object"==typeof a&&a instanceof Name){a=a==this?this.components.slice(0,this.components.length):a.components;for(b=0;b<a.length;++b)this.components.push(new Uint8Array(a[b]));return this}if("object"==typeof a)b=
-new Uint8Array(a);else throw Error("Cannot add Name element at index "+this.components.length+": Invalid type");}this.components.push(b);return this};Name.prototype.to_uri=function(){if(0==this.components.length)return"/";for(var a="",b=0;b<this.components.length;++b)a+="/"+Name.toEscapedString(this.components[b]);return a};Name.prototype.addSegment=function(a){var a=DataUtils.nonNegativeIntToBigEndian(a),b=new Uint8Array(a.length+1);b.set(a,1);this.components.push(b);return this};
-Name.prototype.getPrefix=function(a){return new Name(this.components.slice(0,a))};Name.prototype.getComponent=function(a){var b=new ArrayBuffer(this.components[a].length);(new Uint8Array(b)).set(this.components[a]);return b};Name.prototype.indexOfFileName=function(){for(var a=this.components.length-1;0<=a;--a){var b=this.components[a];if(!(0>=b.length)&&!(0==b[0]||192==b[0]||193==b[0]||245<=b[0]&&255>=b[0]))return a}return-1};
-Name.prototype.equalsName=function(a){if(this.components.length!=a.components.length)return!1;for(var b=this.components.length-1;0<=b;--b)if(!DataUtils.arraysEqual(this.components[b],a.components[b]))return!1;return!0};Name.prototype.getContentDigestValue=function(){for(var a=this.components.length-1;0<=a;--a){var b=Name.getComponentContentDigestValue(this.components[a]);if(null!=b)return b}return null};
-Name.getComponentContentDigestValue=function(a){return a.length==Name.ContentDigestPrefix.length+32+Name.ContentDigestSuffix.length&&DataUtils.arraysEqual(a.subarray(0,Name.ContentDigestPrefix.length),Name.ContentDigestPrefix)&&DataUtils.arraysEqual(a.subarray(a.length-Name.ContentDigestSuffix.length,a.length),Name.ContentDigestSuffix)?a.subarray(Name.ContentDigestPrefix.length,Name.ContentDigestPrefix.length+32):null};Name.ContentDigestPrefix=new Uint8Array([193,46,77,46,71,193,1,170,2,133]);
-Name.ContentDigestSuffix=new Uint8Array([0]);Name.toEscapedString=function(a){for(var b="",c=!1,d=0;d<a.length;++d)if(46!=a[d]){c=!0;break}if(c)for(d=0;d<a.length;++d)c=a[d],b=48<=c&&57>=c||65<=c&&90>=c||97<=c&&122>=c||43==c||45==c||46==c||95==c?b+String.fromCharCode(c):b+("%"+(16>c?"0":"")+c.toString(16).toUpperCase());else{b="...";for(d=0;d<a.length;++d)b+="."}return b};
-Name.fromEscapedString=function(a){a=unescape(a.trim());return null==a.match(/[^.]/)?2>=a.length?null:DataUtils.toNumbersFromString(a.substr(3,a.length-3)):DataUtils.toNumbersFromString(a)};Name.prototype.match=function(a){var b=this.components,a=a.components;if(b.length>a.length)return!1;for(var c=0;c<b.length;++c)if(!DataUtils.arraysEqual(b[c],a[c]))return!1;return!0};
-var ContentObject=function(a,b,c,d){this.name="string"==typeof a?new Name(a):a;this.signedInfo=b;this.content="string"==typeof c?DataUtils.toNumbersFromString(c):c;this.signature=d;this.rawSignatureData=this.endContent=this.endSIG=this.startSIG=null};
-ContentObject.prototype.sign=function(){var a=this.encodeObject(this.name),b=this.encodeObject(this.signedInfo),c=this.encodeContent(),d=new ArrayBuffer(a.length+b.length+c.length),d=new Uint8Array(d);d.set(a,0);d.set(b,a.length);d.set(c,a.length+b.length);4<LOG&&console.log("Signature Data is (binary) "+d);4<LOG&&console.log("Signature Data is (RawString)");4<LOG&&console.log(DataUtils.toString(d));a=new RSAKey;a.readPrivateKeyFromPEMString(globalKeyManager.privateKey);a=a.signByteArrayWithSHA256(d);
-4<LOG&&console.log("SIGNATURE SAVED IS");4<LOG&&console.log(a);4<LOG&&console.log(DataUtils.toNumbers(a.trim()));this.signature.signature=DataUtils.toNumbers(a.trim())};ContentObject.prototype.encodeObject=function(a){var b=new BinaryXMLEncoder;a.to_ccnb(b);return b.getReducedOstream()};ContentObject.prototype.encodeContent=function(){var a=new BinaryXMLEncoder;a.writeElement(CCNProtocolDTags.Content,this.content);return a.getReducedOstream()};
-ContentObject.prototype.saveRawData=function(a){this.rawSignatureData=a.subarray(this.startSIG,this.endSIG)};
-ContentObject.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());a.peekStartElement(CCNProtocolDTags.Signature)&&(this.signature=new Signature,this.signature.from_ccnb(a));this.startSIG=a.offset;this.name=new Name;this.name.from_ccnb(a);a.peekStartElement(CCNProtocolDTags.SignedInfo)&&(this.signedInfo=new SignedInfo,this.signedInfo.from_ccnb(a));this.content=a.readBinaryElement(CCNProtocolDTags.Content,null,!0);this.endSIG=a.offset;a.readEndElement();this.saveRawData(a.istream)};
-ContentObject.prototype.to_ccnb=function(a){a.writeStartElement(this.getElementLabel());null!=this.signature&&this.signature.to_ccnb(a);this.startSIG=a.offset;null!=this.name&&this.name.to_ccnb(a);null!=this.signedInfo&&this.signedInfo.to_ccnb(a);a.writeElement(CCNProtocolDTags.Content,this.content);this.endSIG=a.offset;a.writeEndElement();this.saveRawData(a.ostream)};ContentObject.prototype.getElementLabel=function(){return CCNProtocolDTags.ContentObject};
-var Signature=function(a,b,c){this.Witness=a;this.signature=b;this.digestAlgorithm=c};
-Signature.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());4<LOG&&console.log("STARTED DECODING SIGNATURE");a.peekStartElement(CCNProtocolDTags.DigestAlgorithm)&&(4<LOG&&console.log("DIGIEST ALGORITHM FOUND"),this.digestAlgorithm=a.readUTF8Element(CCNProtocolDTags.DigestAlgorithm));a.peekStartElement(CCNProtocolDTags.Witness)&&(4<LOG&&console.log("WITNESS FOUND"),this.Witness=a.readBinaryElement(CCNProtocolDTags.Witness));4<LOG&&console.log("SIGNATURE FOUND");this.signature=
-a.readBinaryElement(CCNProtocolDTags.SignatureBits);a.readEndElement()};
-Signature.prototype.to_ccnb=function(a){if(!this.validate())throw Error("Cannot encode: field values missing.");a.writeStartElement(this.getElementLabel());null!=this.digestAlgorithm&&!this.digestAlgorithm.equals(CCNDigestHelper.DEFAULT_DIGEST_ALGORITHM)&&a.writeElement(CCNProtocolDTags.DigestAlgorithm,OIDLookup.getDigestOID(this.DigestAlgorithm));null!=this.Witness&&a.writeElement(CCNProtocolDTags.Witness,this.Witness);a.writeElement(CCNProtocolDTags.SignatureBits,this.signature);a.writeEndElement()};
-Signature.prototype.getElementLabel=function(){return CCNProtocolDTags.Signature};Signature.prototype.validate=function(){return null!=this.signature};
-var ContentType={DATA:0,ENCR:1,GONE:2,KEY:3,LINK:4,NACK:5},ContentTypeValue={"0":787648,1:1101969,2:1631044,3:2639423,4:2917194,5:3408010},ContentTypeValueReverse={787648:0,1101969:1,1631044:2,2639423:3,2917194:4,3408010:5},SignedInfo=function(a,b,c,d,e,f){this.publisher=a;this.timestamp=b;this.type=c;this.locator=d;this.freshnessSeconds=e;this.finalBlockID=f;this.setFields()};
-SignedInfo.prototype.setFields=function(){var a=globalKeyManager.publicKey;4<LOG&&console.log("PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ");4<LOG&&console.log(a);var a=DataUtils.toNumbers(globalKeyManager.publicKey),b=hex_sha256_from_bytes(a);this.publisher=new PublisherPublicKeyDigest(DataUtils.toNumbers(b));b=(new Date).getTime();this.timestamp=new CCNTime(b);4<LOG&&console.log("TIME msec is");4<LOG&&console.log(this.timestamp.msec);this.type=0;4<LOG&&console.log("PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ");
-4<LOG&&console.log(a);this.locator=new KeyLocator(a,KeyLocatorType.KEY)};
-SignedInfo.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());a.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)&&(4<LOG&&console.log("DECODING PUBLISHER KEY"),this.publisher=new PublisherPublicKeyDigest,this.publisher.from_ccnb(a));a.peekStartElement(CCNProtocolDTags.Timestamp)&&(4<LOG&&console.log("DECODING TIMESTAMP"),this.timestamp=a.readDateTime(CCNProtocolDTags.Timestamp));if(a.peekStartElement(CCNProtocolDTags.Type)){var b=a.readBinaryElement(CCNProtocolDTags.Type);
-4<LOG&&console.log("Binary Type of of Signed Info is "+b);this.type=b;if(null==this.type)throw Error("Cannot parse signedInfo type: bytes.");}else this.type=ContentType.DATA;a.peekStartElement(CCNProtocolDTags.FreshnessSeconds)&&(this.freshnessSeconds=a.readIntegerElement(CCNProtocolDTags.FreshnessSeconds),4<LOG&&console.log("FRESHNESS IN SECONDS IS "+this.freshnessSeconds));a.peekStartElement(CCNProtocolDTags.FinalBlockID)&&(4<LOG&&console.log("DECODING FINAL BLOCKID"),this.finalBlockID=a.readBinaryElement(CCNProtocolDTags.FinalBlockID));
-a.peekStartElement(CCNProtocolDTags.KeyLocator)&&(4<LOG&&console.log("DECODING KEY LOCATOR"),this.locator=new KeyLocator,this.locator.from_ccnb(a));a.readEndElement()};
-SignedInfo.prototype.to_ccnb=function(a){if(!this.validate())throw Error("Cannot encode : field values missing.");a.writeStartElement(this.getElementLabel());null!=this.publisher&&(3<LOG&&console.log("ENCODING PUBLISHER KEY"+this.publisher.publisherPublicKeyDigest),this.publisher.to_ccnb(a));null!=this.timestamp&&a.writeDateTime(CCNProtocolDTags.Timestamp,this.timestamp);null!=this.type&&0!=this.type&&a.writeElement(CCNProtocolDTags.type,this.type);null!=this.freshnessSeconds&&a.writeElement(CCNProtocolDTags.FreshnessSeconds,
-this.freshnessSeconds);null!=this.finalBlockID&&a.writeElement(CCNProtocolDTags.FinalBlockID,this.finalBlockID);null!=this.locator&&this.locator.to_ccnb(a);a.writeEndElement()};SignedInfo.prototype.valueToType=function(){return null};SignedInfo.prototype.getElementLabel=function(){return CCNProtocolDTags.SignedInfo};SignedInfo.prototype.validate=function(){return null==this.publisher||null==this.timestamp||null==this.locator?!1:!0};
-var DateFormat=function(){var a=/d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,b=/\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,c=/[^-+\dA-Z]/g,d=function(a,b){a=String(a);for(b=b||2;a.length<b;)a="0"+a;return a};return function(e,f,g){var h=dateFormat;1==arguments.length&&("[object String]"==Object.prototype.toString.call(e)&&!/\d/.test(e))&&(f=e,e=void 0);e=e?new Date(e):new Date;if(isNaN(e))throw SyntaxError("invalid date");
-f=String(h.masks[f]||f||h.masks["default"]);"UTC:"==f.slice(0,4)&&(f=f.slice(4),g=!0);var i=g?"getUTC":"get",k=e[i+"Date"](),m=e[i+"Day"](),l=e[i+"Month"](),n=e[i+"FullYear"](),j=e[i+"Hours"](),p=e[i+"Minutes"](),r=e[i+"Seconds"](),i=e[i+"Milliseconds"](),q=g?0:e.getTimezoneOffset(),s={d:k,dd:d(k),ddd:h.i18n.dayNames[m],dddd:h.i18n.dayNames[m+7],m:l+1,mm:d(l+1),mmm:h.i18n.monthNames[l],mmmm:h.i18n.monthNames[l+12],yy:String(n).slice(2),yyyy:n,h:j%12||12,hh:d(j%12||12),H:j,HH:d(j),M:p,MM:d(p),s:r,
-ss:d(r),l:d(i,3),L:d(99<i?Math.round(i/10):i),t:12>j?"a":"p",tt:12>j?"am":"pm",T:12>j?"A":"P",TT:12>j?"AM":"PM",Z:g?"UTC":(String(e).match(b)||[""]).pop().replace(c,""),o:(0<q?"-":"+")+d(100*Math.floor(Math.abs(q)/60)+Math.abs(q)%60,4),S:["th","st","nd","rd"][3<k%10?0:(10!=k%100-k%10)*k%10]};return f.replace(a,function(a){return a in s?s[a]:a.slice(1,a.length-1)})}}();
-DateFormat.masks={"default":"ddd mmm dd yyyy HH:MM:ss",shortDate:"m/d/yy",mediumDate:"mmm d, yyyy",longDate:"mmmm d, yyyy",fullDate:"dddd, mmmm d, yyyy",shortTime:"h:MM TT",mediumTime:"h:MM:ss TT",longTime:"h:MM:ss TT Z",isoDate:"yyyy-mm-dd",isoTime:"HH:MM:ss",isoDateTime:"yyyy-mm-dd'T'HH:MM:ss",isoUtcDateTime:"UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"};DateFormat.i18n={dayNames:"Sun Mon Tue Wed Thu Fri Sat Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),monthNames:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec January February March April May June July August September October November December".split(" ")};
-Date.prototype.format=function(a,b){return dateFormat(this,a,b)};var Interest=function(a,b,c,d,e,f,g,h,i,k,m){this.name=a;this.faceInstance=b;this.maxSuffixComponents=d;this.minSuffixComponents=c;this.publisherPublicKeyDigest=e;this.exclude=f;this.childSelector=g;this.answerOriginKind=h;this.scope=i;this.interestLifetime=k;this.nonce=m};Interest.RECURSIVE_POSTFIX="*";Interest.CHILD_SELECTOR_LEFT=0;Interest.CHILD_SELECTOR_RIGHT=1;Interest.ANSWER_CONTENT_STORE=1;Interest.ANSWER_GENERATED=2;
-Interest.ANSWER_STALE=4;Interest.MARK_STALE=16;Interest.DEFAULT_ANSWER_ORIGIN_KIND=Interest.ANSWER_CONTENT_STORE|Interest.ANSWER_GENERATED;
-Interest.prototype.from_ccnb=function(a){a.readStartElement(CCNProtocolDTags.Interest);this.name=new Name;this.name.from_ccnb(a);a.peekStartElement(CCNProtocolDTags.MinSuffixComponents)&&(this.minSuffixComponents=a.readIntegerElement(CCNProtocolDTags.MinSuffixComponents));a.peekStartElement(CCNProtocolDTags.MaxSuffixComponents)&&(this.maxSuffixComponents=a.readIntegerElement(CCNProtocolDTags.MaxSuffixComponents));a.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)&&(this.publisherPublicKeyDigest=
-new PublisherPublicKeyDigest,this.publisherPublicKeyDigest.from_ccnb(a));a.peekStartElement(CCNProtocolDTags.Exclude)&&(this.exclude=new Exclude,this.exclude.from_ccnb(a));a.peekStartElement(CCNProtocolDTags.ChildSelector)&&(this.childSelector=a.readIntegerElement(CCNProtocolDTags.ChildSelector));a.peekStartElement(CCNProtocolDTags.AnswerOriginKind)&&(this.answerOriginKind=a.readIntegerElement(CCNProtocolDTags.AnswerOriginKind));a.peekStartElement(CCNProtocolDTags.Scope)&&(this.scope=a.readIntegerElement(CCNProtocolDTags.Scope));
-a.peekStartElement(CCNProtocolDTags.InterestLifetime)&&(this.interestLifetime=1E3*DataUtils.bigEndianToUnsignedInt(a.readBinaryElement(CCNProtocolDTags.InterestLifetime))/4096);a.peekStartElement(CCNProtocolDTags.Nonce)&&(this.nonce=a.readBinaryElement(CCNProtocolDTags.Nonce));a.readEndElement()};
-Interest.prototype.to_ccnb=function(a){a.writeStartElement(CCNProtocolDTags.Interest);this.name.to_ccnb(a);null!=this.minSuffixComponents&&a.writeElement(CCNProtocolDTags.MinSuffixComponents,this.minSuffixComponents);null!=this.maxSuffixComponents&&a.writeElement(CCNProtocolDTags.MaxSuffixComponents,this.maxSuffixComponents);null!=this.publisherPublicKeyDigest&&this.publisherPublicKeyDigest.to_ccnb(a);null!=this.exclude&&this.exclude.to_ccnb(a);null!=this.childSelector&&a.writeElement(CCNProtocolDTags.ChildSelector,
-this.childSelector);this.DEFAULT_ANSWER_ORIGIN_KIND!=this.answerOriginKind&&null!=this.answerOriginKind&&a.writeElement(CCNProtocolDTags.AnswerOriginKind,this.answerOriginKind);null!=this.scope&&a.writeElement(CCNProtocolDTags.Scope,this.scope);null!=this.interestLifetime&&a.writeElement(CCNProtocolDTags.InterestLifetime,DataUtils.nonNegativeIntToBigEndian(4096*(this.interestLifetime/1E3)));null!=this.nonce&&a.writeElement(CCNProtocolDTags.Nonce,this.nonce);a.writeEndElement()};
-Interest.prototype.matches_name=function(a){return!this.name.match(a)||null!=this.minSuffixComponents&&!(a.components.length+1-this.name.components.length>=this.minSuffixComponents)||null!=this.maxSuffixComponents&&!(a.components.length+1-this.name.components.length<=this.maxSuffixComponents)||null!=this.exclude&&a.components.length>this.name.components.length&&this.exclude.matches(a.components[this.name.components.length])?!1:!0};
-Interest.prototype.clone=function(){return new Interest(this.name,this.faceInstance,this.minSuffixComponents,this.maxSuffixComponents,this.publisherPublicKeyDigest,this.exclude,this.childSelector,this.answerOriginKind,this.scope,this.interestLifetime,this.nonce)};var Exclude=function(a){this.values=a||[]};Exclude.ANY="*";
-Exclude.prototype.from_ccnb=function(a){for(a.readStartElement(CCNProtocolDTags.Exclude);;)if(a.peekStartElement(CCNProtocolDTags.Component))this.values.push(a.readBinaryElement(CCNProtocolDTags.Component));else if(a.peekStartElement(CCNProtocolDTags.Any))a.readStartElement(CCNProtocolDTags.Any),a.readEndElement(),this.values.push(Exclude.ANY);else if(a.peekStartElement(CCNProtocolDTags.Bloom))a.readBinaryElement(CCNProtocolDTags.Bloom),this.values.push(Exclude.ANY);else break;a.readEndElement()};
-Exclude.prototype.to_ccnb=function(a){if(!(null==this.values||0==this.values.length)){a.writeStartElement(CCNProtocolDTags.Exclude);for(var b=0;b<this.values.length;++b)this.values[b]==Exclude.ANY?(a.writeStartElement(CCNProtocolDTags.Any),a.writeEndElement()):a.writeElement(CCNProtocolDTags.Component,this.values[b]);a.writeEndElement()}};
-Exclude.prototype.to_uri=function(){if(null==this.values||0==this.values.length)return"";for(var a="",b=0;b<this.values.length;++b)0<b&&(a+=","),a=this.values[b]==Exclude.ANY?a+"*":a+Name.toEscapedString(this.values[b]);return a};
-Exclude.prototype.matches=function(a){for(var b=0;b<this.values.length;++b)if(this.values[b]==Exclude.ANY){var c=null;0<b&&(c=this.values[b-1]);var d,e=null;for(d=b+1;d<this.values.length;++d)if(this.values[d]!=Exclude.ANY){e=this.values[d];break}if(null!=e){if(null!=c){if(0<Exclude.compareComponents(a,c)&&0>Exclude.compareComponents(a,e))return!0}else if(0>Exclude.compareComponents(a,e))return!0;b=d-1}else if(null!=c){if(0<Exclude.compareComponents(a,c))return!0}else return!0}else if(DataUtils.arraysEqual(a,
-this.values[b]))return!0;return!1};Exclude.compareComponents=function(a,b){if(a.length<b.length)return-1;if(a.length>b.length)return 1;for(var c=0;c<a.length;++c){if(a[c]<b[c])return-1;if(a[c]>b[c])return 1}return 0};
-var Key=function(){},KeyLocatorType={KEY:1,CERTIFICATE:2,KEYNAME:3},KeyLocator=function(a,b){this.type=b;b==KeyLocatorType.KEYNAME?(3<LOG&&console.log("KeyLocator: SET KEYNAME"),this.keyName=a):b==KeyLocatorType.KEY?(3<LOG&&console.log("KeyLocator: SET KEY"),this.publicKey=a):b==KeyLocatorType.CERTIFICATE&&(3<LOG&&console.log("KeyLocator: SET CERTIFICATE"),this.certificate=a)};
-KeyLocator.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());if(a.peekStartElement(CCNProtocolDTags.Key)){try{this.publicKey=a.readBinaryElement(CCNProtocolDTags.Key),this.type=KeyLocatorType.KEY,4<LOG&&console.log("PUBLIC KEY FOUND: "+this.publicKey)}catch(b){throw Error("Cannot parse key: ",b);}if(null==this.publicKey)throw Error("Cannot parse key: ");}else if(a.peekStartElement(CCNProtocolDTags.Certificate)){try{this.certificate=a.readBinaryElement(CCNProtocolDTags.Certificate),
-this.type=KeyLocatorType.CERTIFICATE,4<LOG&&console.log("CERTIFICATE FOUND: "+this.certificate)}catch(c){throw Error("Cannot decode certificate: "+c);}if(null==this.certificate)throw Error("Cannot parse certificate! ");}else this.type=KeyLocatorType.KEYNAME,this.keyName=new KeyName,this.keyName.from_ccnb(a);a.readEndElement()};
-KeyLocator.prototype.to_ccnb=function(a){4<LOG&&console.log("type is is "+this.type);if(!this.validate())throw new ContentEncodingException("Cannot encode "+this.getClass().getName()+": field values missing.");a.writeStartElement(this.getElementLabel());if(this.type==KeyLocatorType.KEY)5<LOG&&console.log("About to encode a public key"+this.publicKey),a.writeElement(CCNProtocolDTags.Key,this.publicKey);else if(this.type==KeyLocatorType.CERTIFICATE)try{a.writeElement(CCNProtocolDTags.Certificate,this.certificate)}catch(b){throw Error("CertificateEncodingException attempting to write key locator: "+
-b);}else this.type==KeyLocatorType.KEYNAME&&this.keyName.to_ccnb(a);a.writeEndElement()};KeyLocator.prototype.getElementLabel=function(){return CCNProtocolDTags.KeyLocator};KeyLocator.prototype.validate=function(){return null!=this.keyName||null!=this.publicKey||null!=this.certificate};var KeyName=function(){this.contentName=this.contentName;this.publisherID=this.publisherID};
-KeyName.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());this.contentName=new Name;this.contentName.from_ccnb(a);4<LOG&&console.log("KEY NAME FOUND: ");PublisherID.peek(a)&&(this.publisherID=new PublisherID,this.publisherID.from_ccnb(a));a.readEndElement()};
-KeyName.prototype.to_ccnb=function(a){if(!this.validate())throw Error("Cannot encode : field values missing.");a.writeStartElement(this.getElementLabel());this.contentName.to_ccnb(a);null!=this.publisherID&&this.publisherID.to_ccnb(a);a.writeEndElement()};KeyName.prototype.getElementLabel=function(){return CCNProtocolDTags.KeyName};KeyName.prototype.validate=function(){return null!=this.contentName};
-var PublisherType=function(a){this.KEY=CCNProtocolDTags.PublisherPublicKeyDigest;this.CERTIFICATE=CCNProtocolDTags.PublisherCertificateDigest;this.ISSUER_KEY=CCNProtocolDTags.PublisherIssuerKeyDigest;this.ISSUER_CERTIFICATE=CCNProtocolDTags.PublisherIssuerCertificateDigest;this.Tag=a},isTypeTagVal=function(a){return a==CCNProtocolDTags.PublisherPublicKeyDigest||a==CCNProtocolDTags.PublisherCertificateDigest||a==CCNProtocolDTags.PublisherIssuerKeyDigest||a==CCNProtocolDTags.PublisherIssuerCertificateDigest?
-!0:!1},PublisherID=function(){this.PUBLISHER_ID_DIGEST_ALGORITHM="SHA-256";this.PUBLISHER_ID_LEN=32;this.publisherType=this.publisherID=null};
-PublisherID.prototype.from_ccnb=function(a){var b=a.peekStartElementAsLong();if(null==b)throw Error("Cannot parse publisher ID.");this.publisherType=new PublisherType(b);if(!isTypeTagVal(b))throw Error("Invalid publisher ID, got unexpected type: "+b);this.publisherID=a.readBinaryElement(b);if(null==this.publisherID)throw new ContentDecodingException(Error("Cannot parse publisher ID of type : "+b+"."));};
-PublisherID.prototype.to_ccnb=function(a){if(!this.validate())throw Error("Cannot encode "+this.getClass().getName()+": field values missing.");a.writeElement(this.getElementLabel(),this.publisherID)};PublisherID.peek=function(a){a=a.peekStartElementAsLong();return null==a?!1:isTypeTagVal(a)};PublisherID.prototype.getElementLabel=function(){return this.publisherType.Tag};PublisherID.prototype.validate=function(){return null!=id()&&null!=type()};
-var PublisherPublicKeyDigest=function(a){this.PUBLISHER_ID_LEN=64;this.publisherPublicKeyDigest=a};
-PublisherPublicKeyDigest.prototype.from_ccnb=function(a){this.publisherPublicKeyDigest=a.readBinaryElement(this.getElementLabel());4<LOG&&console.log("Publisher public key digest is "+this.publisherPublicKeyDigest);if(null==this.publisherPublicKeyDigest)throw Error("Cannot parse publisher key digest.");this.publisherPublicKeyDigest.length!=this.PUBLISHER_ID_LEN&&0<LOG&&console.log("LENGTH OF PUBLISHER ID IS WRONG! Expected "+this.PUBLISHER_ID_LEN+", got "+this.publisherPublicKeyDigest.length)};
-PublisherPublicKeyDigest.prototype.to_ccnb=function(a){if(!this.validate())throw Error("Cannot encode : field values missing.");3<LOG&&console.log("PUBLISHER KEY DIGEST IS"+this.publisherPublicKeyDigest);a.writeElement(this.getElementLabel(),this.publisherPublicKeyDigest)};PublisherPublicKeyDigest.prototype.getElementLabel=function(){return CCNProtocolDTags.PublisherPublicKeyDigest};PublisherPublicKeyDigest.prototype.validate=function(){return null!=this.publisherPublicKeyDigest};
-var NetworkProtocol={TCP:6,UDP:17},FaceInstance=function(a,b,c,d,e,f,g,h,i){this.action=a;this.publisherPublicKeyDigest=b;this.faceID=c;this.ipProto=d;this.host=e;this.Port=f;this.multicastInterface=g;this.multicastTTL=h;this.freshnessSeconds=i};
-FaceInstance.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());a.peekStartElement(CCNProtocolDTags.Action)&&(this.action=a.readUTF8Element(CCNProtocolDTags.Action));a.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)&&(this.publisherPublicKeyDigest=new PublisherPublicKeyDigest,this.publisherPublicKeyDigest.from_ccnb(a));a.peekStartElement(CCNProtocolDTags.FaceID)&&(this.faceID=a.readIntegerElement(CCNProtocolDTags.FaceID));if(a.peekStartElement(CCNProtocolDTags.IPProto)){var b=
-a.readIntegerElement(CCNProtocolDTags.IPProto);this.ipProto=null;if(NetworkProtocol.TCP==b)this.ipProto=NetworkProtocol.TCP;else if(NetworkProtocol.UDP==b)this.ipProto=NetworkProtocol.UDP;else throw Error("FaceInstance.decoder.  Invalid "+CCNProtocolDTags.tagToString(CCNProtocolDTags.IPProto)+" field: "+b);}a.peekStartElement(CCNProtocolDTags.Host)&&(this.host=a.readUTF8Element(CCNProtocolDTags.Host));a.peekStartElement(CCNProtocolDTags.Port)&&(this.Port=a.readIntegerElement(CCNProtocolDTags.Port));
-a.peekStartElement(CCNProtocolDTags.MulticastInterface)&&(this.multicastInterface=a.readUTF8Element(CCNProtocolDTags.MulticastInterface));a.peekStartElement(CCNProtocolDTags.MulticastTTL)&&(this.multicastTTL=a.readIntegerElement(CCNProtocolDTags.MulticastTTL));a.peekStartElement(CCNProtocolDTags.FreshnessSeconds)&&(this.freshnessSeconds=a.readIntegerElement(CCNProtocolDTags.FreshnessSeconds));a.readEndElement()};
-FaceInstance.prototype.to_ccnb=function(a){a.writeStartElement(this.getElementLabel());null!=this.action&&0!=this.action.length&&a.writeElement(CCNProtocolDTags.Action,this.action);null!=this.publisherPublicKeyDigest&&this.publisherPublicKeyDigest.to_ccnb(a);null!=this.faceID&&a.writeElement(CCNProtocolDTags.FaceID,this.faceID);null!=this.ipProto&&a.writeElement(CCNProtocolDTags.IPProto,this.ipProto);null!=this.host&&0!=this.host.length&&a.writeElement(CCNProtocolDTags.Host,this.host);null!=this.Port&&
-a.writeElement(CCNProtocolDTags.Port,this.Port);null!=this.multicastInterface&&0!=this.multicastInterface.length&&a.writeElement(CCNProtocolDTags.MulticastInterface,this.multicastInterface);null!=this.multicastTTL&&a.writeElement(CCNProtocolDTags.MulticastTTL,this.multicastTTL);null!=this.freshnessSeconds&&a.writeElement(CCNProtocolDTags.FreshnessSeconds,this.freshnessSeconds);a.writeEndElement()};FaceInstance.prototype.getElementLabel=function(){return CCNProtocolDTags.FaceInstance};
-var ForwardingEntry=function(a,b,c,d,e,f){this.action=a;this.prefixName=b;this.ccndID=c;this.faceID=d;this.flags=e;this.lifetime=f};
-ForwardingEntry.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());a.peekStartElement(CCNProtocolDTags.Action)&&(this.action=a.readUTF8Element(CCNProtocolDTags.Action));a.peekStartElement(CCNProtocolDTags.Name)&&(this.prefixName=new Name,this.prefixName.from_ccnb(a));a.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)&&(this.CcndId=new PublisherPublicKeyDigest,this.CcndId.from_ccnb(a));a.peekStartElement(CCNProtocolDTags.FaceID)&&(this.faceID=a.readIntegerElement(CCNProtocolDTags.FaceID));
-a.peekStartElement(CCNProtocolDTags.ForwardingFlags)&&(this.flags=a.readIntegerElement(CCNProtocolDTags.ForwardingFlags));a.peekStartElement(CCNProtocolDTags.FreshnessSeconds)&&(this.lifetime=a.readIntegerElement(CCNProtocolDTags.FreshnessSeconds));a.readEndElement()};
-ForwardingEntry.prototype.to_ccnb=function(a){a.writeStartElement(this.getElementLabel());null!=this.action&&0!=this.action.length&&a.writeElement(CCNProtocolDTags.Action,this.action);null!=this.prefixName&&this.prefixName.to_ccnb(a);null!=this.CcndId&&this.CcndId.to_ccnb(a);null!=this.faceID&&a.writeElement(CCNProtocolDTags.FaceID,this.faceID);null!=this.flags&&a.writeElement(CCNProtocolDTags.ForwardingFlags,this.flags);null!=this.lifetime&&a.writeElement(CCNProtocolDTags.FreshnessSeconds,this.lifetime);
-a.writeEndElement()};ForwardingEntry.prototype.getElementLabel=function(){return CCNProtocolDTags.ForwardingEntry};var DynamicUint8Array=function(a){a||(a=16);this.array=new Uint8Array(a);this.length=a};DynamicUint8Array.prototype.ensureLength=function(a){if(!(this.array.length>=a)){var b=2*this.array.length;a>b&&(b=a);a=new Uint8Array(b);a.set(this.array);this.array=a;this.length=b}};DynamicUint8Array.prototype.set=function(a,b){this.ensureLength(a.length+b);this.array.set(a,b)};
-DynamicUint8Array.prototype.subarray=function(a,b){return this.array.subarray(a,b)};
-var XML_EXT=0,XML_TAG=1,XML_DTAG=2,XML_ATTR=3,XML_DATTR=4,XML_BLOB=5,XML_UDATA=6,XML_CLOSE=0,XML_SUBTYPE_PROCESSING_INSTRUCTIONS=16,XML_TT_BITS=3,XML_TT_MASK=(1<<XML_TT_BITS)-1,XML_TT_VAL_BITS=XML_TT_BITS+1,XML_TT_VAL_MASK=(1<<XML_TT_VAL_BITS)-1,XML_REG_VAL_BITS=7,XML_REG_VAL_MASK=(1<<XML_REG_VAL_BITS)-1,XML_TT_NO_MORE=1<<XML_REG_VAL_BITS,BYTE_MASK=255,LONG_BYTES=8,LONG_BITS=64,bits_11=2047,bits_18=262143,bits_32=4294967295,BinaryXMLEncoder=function(){this.ostream=new DynamicUint8Array(100);this.offset=
-0;this.CODEC_NAME="Binary"};BinaryXMLEncoder.prototype.writeUString=function(a){this.encodeUString(a,XML_UDATA)};BinaryXMLEncoder.prototype.writeBlob=function(a){3<LOG&&console.log(a);this.encodeBlob(a,a.length)};BinaryXMLEncoder.prototype.writeStartElement=function(a,b){null==a?this.encodeUString(a,XML_TAG):this.encodeTypeAndVal(XML_DTAG,a);null!=b&&this.writeAttributes(b)};
-BinaryXMLEncoder.prototype.writeEndElement=function(){this.ostream.ensureLength(this.offset+1);this.ostream.array[this.offset]=XML_CLOSE;this.offset+=1};BinaryXMLEncoder.prototype.writeAttributes=function(a){if(null!=a)for(var b=0;b<a.length;b++){var c=a[b].k,d=a[b].v,e=stringToTag(c);null==e?this.encodeUString(c,XML_ATTR):this.encodeTypeAndVal(XML_DATTR,e);this.encodeUString(d)}};
-stringToTag=function(a){return 0<=a&&a<CCNProtocolDTagsStrings.length?CCNProtocolDTagsStrings[a]:a==CCNProtocolDTags.CCNProtocolDataUnit?CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT:null};tagToString=function(a){for(var b=0;b<CCNProtocolDTagsStrings.length;++b)if(null!=CCNProtocolDTagsStrings[b]&&CCNProtocolDTagsStrings[b]==a)return b;return CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT==a?CCNProtocolDTags.CCNProtocolDataUnit:null};
-BinaryXMLEncoder.prototype.writeElement=function(a,b,c){this.writeStartElement(a,c);"number"===typeof b?(4<LOG&&console.log("GOING TO WRITE THE NUMBER .charCodeAt(0) "+b.toString().charCodeAt(0)),4<LOG&&console.log("GOING TO WRITE THE NUMBER "+b.toString()),4<LOG&&console.log("type of number is "+typeof b.toString()),this.writeUString(b.toString())):"string"===typeof b?(4<LOG&&console.log("GOING TO WRITE THE STRING  "+b),4<LOG&&console.log("type of STRING is "+typeof b),this.writeUString(b)):(4<LOG&&
-console.log("GOING TO WRITE A BLOB  "+b),this.writeBlob(b));this.writeEndElement()};var TypeAndVal=function(a,b){this.type=a;this.val=b};
-BinaryXMLEncoder.prototype.encodeTypeAndVal=function(a,b){4<LOG&&console.log("Encoding type "+a+" and value "+b);4<LOG&&console.log("OFFSET IS "+this.offset);if(a>XML_UDATA||0>a||0>b)throw Error("Tag and value must be positive, and tag valid.");var c=this.numEncodingBytes(b);this.ostream.ensureLength(this.offset+c);this.ostream.array[this.offset+c-1]=BYTE_MASK&(XML_TT_MASK&a|(XML_TT_VAL_MASK&b)<<XML_TT_BITS)|XML_TT_NO_MORE;for(var b=b>>>XML_TT_VAL_BITS,d=this.offset+c-2;0!=b&&d>=this.offset;)this.ostream.array[d]=
-BYTE_MASK&b&XML_REG_VAL_MASK,b>>>=XML_REG_VAL_BITS,--d;if(0!=b)throw Error("This should not happen: miscalculated encoding");this.offset+=c;return c};
-BinaryXMLEncoder.prototype.encodeUString=function(a,b){if(null!=a&&!(b==XML_TAG||b==XML_ATTR&&0==a.length)){3<LOG&&console.log("The string to write is ");3<LOG&&console.log(a);var c=DataUtils.stringToUtf8Array(a);this.encodeTypeAndVal(b,b==XML_TAG||b==XML_ATTR?c.length-1:c.length);3<LOG&&console.log("THE string to write is ");3<LOG&&console.log(c);this.writeString(c);this.offset+=c.length}};
-BinaryXMLEncoder.prototype.encodeBlob=function(a,b){null!=a&&(4<LOG&&console.log("LENGTH OF XML_BLOB IS "+b),this.encodeTypeAndVal(XML_BLOB,b),this.writeBlobArray(a),this.offset+=b)};var ENCODING_LIMIT_1_BYTE=(1<<XML_TT_VAL_BITS)-1,ENCODING_LIMIT_2_BYTES=(1<<XML_TT_VAL_BITS+XML_REG_VAL_BITS)-1,ENCODING_LIMIT_3_BYTES=(1<<XML_TT_VAL_BITS+2*XML_REG_VAL_BITS)-1;
-BinaryXMLEncoder.prototype.numEncodingBytes=function(a){if(a<=ENCODING_LIMIT_1_BYTE)return 1;if(a<=ENCODING_LIMIT_2_BYTES)return 2;if(a<=ENCODING_LIMIT_3_BYTES)return 3;for(var b=1,a=a>>>XML_TT_VAL_BITS;0!=a;)b++,a>>>=XML_REG_VAL_BITS;return b};
-BinaryXMLEncoder.prototype.writeDateTime=function(a,b){4<LOG&&console.log("ENCODING DATE with LONG VALUE");4<LOG&&console.log(b.msec);var c=Math.round(4096*(b.msec/1E3)).toString(16),c=DataUtils.toNumbers("0".concat(c,"0"));4<LOG&&console.log("ENCODING DATE with BINARY VALUE");4<LOG&&console.log(c);4<LOG&&console.log("ENCODING DATE with BINARY VALUE(HEX)");4<LOG&&console.log(DataUtils.toHex(c));this.writeElement(a,c)};
-BinaryXMLEncoder.prototype.writeString=function(a){if("string"===typeof a){4<LOG&&console.log("GOING TO WRITE A STRING");4<LOG&&console.log(a);this.ostream.ensureLength(this.offset+a.length);for(var b=0;b<a.length;b++)4<LOG&&console.log("input.charCodeAt(i)="+a.charCodeAt(b)),this.ostream.array[this.offset+b]=a.charCodeAt(b)}else 4<LOG&&console.log("GOING TO WRITE A STRING IN BINARY FORM"),4<LOG&&console.log(a),this.writeBlobArray(a)};
-BinaryXMLEncoder.prototype.writeBlobArray=function(a){4<LOG&&console.log("GOING TO WRITE A BLOB");this.ostream.set(a,this.offset)};BinaryXMLEncoder.prototype.getReducedOstream=function(){return this.ostream.subarray(0,this.offset)};XML_EXT=0;XML_TAG=1;XML_DTAG=2;XML_ATTR=3;XML_DATTR=4;XML_BLOB=5;XML_UDATA=6;XML_CLOSE=0;XML_SUBTYPE_PROCESSING_INSTRUCTIONS=16;XML_TT_BITS=3;XML_TT_MASK=(1<<XML_TT_BITS)-1;XML_TT_VAL_BITS=XML_TT_BITS+1;XML_TT_VAL_MASK=(1<<XML_TT_VAL_BITS)-1;XML_REG_VAL_BITS=7;
-XML_REG_VAL_MASK=(1<<XML_REG_VAL_BITS)-1;XML_TT_NO_MORE=1<<XML_REG_VAL_BITS;BYTE_MASK=255;LONG_BYTES=8;LONG_BITS=64;bits_11=2047;bits_18=262143;bits_32=4294967295;tagToString=function(a){return 0<=a&&a<CCNProtocolDTagsStrings.length?CCNProtocolDTagsStrings[a]:a==CCNProtocolDTags.CCNProtocolDataUnit?CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT:null};
-stringToTag=function(a){for(var b=0;b<CCNProtocolDTagsStrings.length;++b)if(null!=CCNProtocolDTagsStrings[b]&&CCNProtocolDTagsStrings[b]==a)return b;return CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT==a?CCNProtocolDTags.CCNProtocolDataUnit:null};var BinaryXMLDecoder=function(a){this.istream=a;this.offset=0};BinaryXMLDecoder.prototype.initializeDecoding=function(){};BinaryXMLDecoder.prototype.readStartDocument=function(){};BinaryXMLDecoder.prototype.readEndDocument=function(){};
-BinaryXMLDecoder.prototype.readStartElement=function(a,b){var c=this.decodeTypeAndVal();if(null==c)throw new ContentDecodingException(Error("Expected start element: "+a+" got something not a tag."));var d=null;c.type()==XML_TAG?(d="string"==typeof c.val()?parseInt(c.val())+1:c.val()+1,d=this.decodeUString(d)):c.type()==XML_DTAG&&(d=c.val());if(null==d||d!=a)throw console.log("expecting "+a+" but got "+d),new ContentDecodingException(Error("Expected start element: "+a+" got: "+d+"("+c.val()+")"));
-null!=b&&readAttributes(b)};
-BinaryXMLDecoder.prototype.readAttributes=function(a){if(null!=a)try{for(var b=this.peekTypeAndVal();null!=b&&(XML_ATTR==b.type()||XML_DATTR==b.type());){var c=this.decodeTypeAndVal(),d=null;if(XML_ATTR==c.type()){var e;e="string"==typeof c.val()?parseInt(c.val())+1:c.val()+1;d=this.decodeUString(e)}else if(XML_DATTR==c.type()&&(d=tagToString(c.val()),null==d))throw new ContentDecodingException(Error("Unknown DATTR value"+c.val()));var f=this.decodeUString();a.push([d,f]);b=this.peekTypeAndVal()}}catch(g){throw new ContentDecodingException(Error("readStartElement",
-g));}};BinaryXMLDecoder.prototype.peekStartElementAsString=function(){var a=null,b=this.offset;try{var c=this.decodeTypeAndVal();if(null!=c)if(c.type()==XML_TAG){var d;d="string"==typeof c.val()?parseInt(c.val())+1:c.val()+1;a=this.decodeUString(d)}else c.type()==XML_DTAG&&(a=tagToString(c.val()))}catch(e){}finally{try{this.offset=b}catch(f){throw Log.logStackTrace(Log.FAC_ENCODING,Level.WARNING,f),new ContentDecodingException(Error("Cannot reset stream! "+f.getMessage(),f));}}return a};
-BinaryXMLDecoder.prototype.peekStartElement=function(a){if("string"==typeof a){var b=this.peekStartElementAsString();return null!=b&&b==a?!0:!1}if("number"==typeof a)return b=this.peekStartElementAsLong(),null!=b&&b==a?!0:!1;throw new ContentDecodingException(Error("SHOULD BE STRING OR NUMBER"));};
-BinaryXMLDecoder.prototype.peekStartElementAsLong=function(){var a=null,b=this.offset;try{var c=this.decodeTypeAndVal();if(null!=c)if(c.type()==XML_TAG){if(c.val()+1>DEBUG_MAX_LEN)throw new ContentDecodingException(Error("Decoding error: length "+c.val()+1+" longer than expected maximum length!"));var d;d="string"==typeof c.val()?parseInt(c.val())+1:c.val()+1;var e=this.decodeUString(d),a=stringToTag(e)}else c.type()==XML_DTAG&&(a=c.val())}catch(f){}finally{try{this.offset=b}catch(g){throw Log.logStackTrace(Log.FAC_ENCODING,
-Level.WARNING,g),Error("Cannot reset stream! "+g.getMessage(),g);}}return a};BinaryXMLDecoder.prototype.readBinaryElement=function(a,b,c){this.readStartElement(a,b);return this.readBlob(c)};
-BinaryXMLDecoder.prototype.readEndElement=function(){4<LOG&&console.log("this.offset is "+this.offset);var a=this.istream[this.offset];this.offset++;4<LOG&&console.log("XML_CLOSE IS "+XML_CLOSE);4<LOG&&console.log("next is "+a);if(a!=XML_CLOSE)throw console.log("Expected end element, got: "+a),new ContentDecodingException(Error("Expected end element, got: "+a));};BinaryXMLDecoder.prototype.readUString=function(){var a=this.decodeUString();this.readEndElement();return a};
-BinaryXMLDecoder.prototype.readBlob=function(a){if(this.istream[this.offset]==XML_CLOSE&&a)return this.readEndElement(),null;a=this.decodeBlob();this.readEndElement();return a};
-BinaryXMLDecoder.prototype.readDateTime=function(a){var a=this.readBinaryElement(a),a=DataUtils.toHex(a),a=parseInt(a,16),b=1E3*(a/4096);4<LOG&&console.log("DECODED DATE WITH VALUE");4<LOG&&console.log(b);b=new CCNTime(b);if(null==b)throw new ContentDecodingException(Error("Cannot parse timestamp: "+DataUtils.printHexBytes(a)));return b};
-BinaryXMLDecoder.prototype.decodeTypeAndVal=function(){var a=-1,b=0,c=!0;do{var d=this.istream[this.offset];if(0>d||0==d&&0==b)return null;(c=0==(d&XML_TT_NO_MORE))?(b<<=XML_REG_VAL_BITS,b|=d&XML_REG_VAL_MASK):(a=d&XML_TT_MASK,b<<=XML_TT_VAL_BITS,b|=d>>>XML_TT_BITS&XML_TT_VAL_MASK);this.offset++}while(c);4<LOG&&console.log("TYPE is "+a+" VAL is "+b);return new TypeAndVal(a,b)};
-BinaryXMLDecoder.prototype.peekTypeAndVal=function(){var a=null,b=this.offset;try{a=this.decodeTypeAndVal()}finally{this.offset=b}return a};BinaryXMLDecoder.prototype.decodeBlob=function(a){if(null==a)return a=this.decodeTypeAndVal(),a="string"==typeof a.val()?parseInt(a.val()):a.val(),this.decodeBlob(a);var b=this.istream.subarray(this.offset,this.offset+a);this.offset+=a;return b};
-BinaryXMLDecoder.prototype.decodeUString=function(a){if(null==a){var a=this.offset,b=this.decodeTypeAndVal();4<LOG&&console.log("TV is "+b);4<LOG&&console.log(b);4<LOG&&console.log("Type of TV is "+typeof b);return null==b||XML_UDATA!=b.type()?(this.offset=a,""):this.decodeUString(b.val())}a=this.decodeBlob(a);return DataUtils.toString(a)};TypeAndVal=function(a,b){this.t=a;this.v=b};TypeAndVal.prototype.type=function(){return this.t};TypeAndVal.prototype.val=function(){return this.v};
-BinaryXMLDecoder.prototype.readIntegerElement=function(a){4<LOG&&console.log("READING INTEGER "+a);4<LOG&&console.log("TYPE OF "+typeof a);a=this.readUTF8Element(a);return parseInt(a)};BinaryXMLDecoder.prototype.readUTF8Element=function(a,b){this.readStartElement(a,b);return this.readUString()};BinaryXMLDecoder.prototype.seek=function(a){this.offset=a};function ContentDecodingException(a){this.message=a.message;for(var b in a)this[b]=a[b]}ContentDecodingException.prototype=Error();
-ContentDecodingException.prototype.name="ContentDecodingException";var BinaryXMLStructureDecoder=function(){this.gotElementEnd=!1;this.level=this.offset=0;this.state=BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE;this.headerLength=0;this.useHeaderBuffer=!1;this.headerBuffer=new DynamicUint8Array(5);this.nBytesToRead=0};BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE=0;BinaryXMLStructureDecoder.READ_BYTES=1;
-BinaryXMLStructureDecoder.prototype.findElementEnd=function(a){if(this.gotElementEnd)return!0;for(var b=new BinaryXMLDecoder(a);;){if(this.offset>=a.length)return!1;switch(this.state){case BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE:if(0==this.headerLength&&a[this.offset]==XML_CLOSE){++this.offset;--this.level;if(0==this.level)return!0;if(0>this.level)throw Error("BinaryXMLStructureDecoder: Unexepected close tag at offset "+(this.offset-1));this.startHeader();break}for(var c=this.headerLength;;){if(this.offset>=
-a.length){this.useHeaderBuffer=!0;var d=this.headerLength-c;this.headerBuffer.set(a.subarray(this.offset-d,d),c);return!1}d=a[this.offset++];++this.headerLength;if(d&XML_TT_NO_MORE)break}this.useHeaderBuffer?(d=this.headerLength-c,this.headerBuffer.set(a.subarray(this.offset-d,d),c),c=(new BinaryXMLDecoder(this.headerBuffer.array)).decodeTypeAndVal()):(b.seek(this.offset-this.headerLength),c=b.decodeTypeAndVal());if(null==c)throw Error("BinaryXMLStructureDecoder: Can't read header starting at offset "+
-(this.offset-this.headerLength));d=c.t;if(d==XML_DATTR)this.startHeader();else if(d==XML_DTAG||d==XML_EXT)++this.level,this.startHeader();else if(d==XML_TAG||d==XML_ATTR)d==XML_TAG&&++this.level,this.nBytesToRead=c.v+1,this.state=BinaryXMLStructureDecoder.READ_BYTES;else if(d==XML_BLOB||d==XML_UDATA)this.nBytesToRead=c.v,this.state=BinaryXMLStructureDecoder.READ_BYTES;else throw Error("BinaryXMLStructureDecoder: Unrecognized header type "+d);break;case BinaryXMLStructureDecoder.READ_BYTES:c=a.length-
-this.offset;if(c<this.nBytesToRead)return this.offset+=c,this.nBytesToRead-=c,!1;this.offset+=this.nBytesToRead;this.startHeader();break;default:throw Error("BinaryXMLStructureDecoder: Unrecognized state "+this.state);}}};BinaryXMLStructureDecoder.prototype.startHeader=function(){this.headerLength=0;this.useHeaderBuffer=!1;this.state=BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE};BinaryXMLStructureDecoder.prototype.seek=function(a){this.offset=a};var DataUtils=function(){};DataUtils.keyStr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
-DataUtils.stringtoBase64=function(a){var a=escape(a),b="",c,d,e="",f,g,h="",i=0;do c=a.charCodeAt(i++),d=a.charCodeAt(i++),e=a.charCodeAt(i++),f=c>>2,c=(c&3)<<4|d>>4,g=(d&15)<<2|e>>6,h=e&63,isNaN(d)?g=h=64:isNaN(e)&&(h=64),b=b+DataUtils.keyStr.charAt(f)+DataUtils.keyStr.charAt(c)+DataUtils.keyStr.charAt(g)+DataUtils.keyStr.charAt(h);while(i<a.length);return b};
-DataUtils.base64toString=function(a){var b="",c,d,e="",f,g="",h=0;/[^A-Za-z0-9\+\/\=]/g.exec(a)&&alert("There were invalid base64 characters in the input text.\nValid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\nExpect errors in decoding.");a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");do c=DataUtils.keyStr.indexOf(a.charAt(h++)),d=DataUtils.keyStr.indexOf(a.charAt(h++)),f=DataUtils.keyStr.indexOf(a.charAt(h++)),g=DataUtils.keyStr.indexOf(a.charAt(h++)),c=c<<2|d>>4,d=(d&15)<<4|f>>2,e=(f&3)<<6|g,
-b+=String.fromCharCode(c),64!=f&&(b+=String.fromCharCode(d)),64!=g&&(b+=String.fromCharCode(e));while(h<a.length);return unescape(b)};DataUtils.toHex=function(a){4<LOG&&console.log("ABOUT TO CONVERT "+a);for(var b="",c=0;c<a.length;c++)b+=(16>a[c]?"0":"")+a[c].toString(16);4<LOG&&console.log("Converted to: "+b);return b};DataUtils.stringToHex=function(a){for(var b="",c=0;c<a.length;++c)var d=a.charCodeAt(c),b=b+((16>d?"0":"")+d.toString(16));return b};
-DataUtils.toString=function(a){for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(a[c]);return b};DataUtils.toNumbers=function(a){if("string"==typeof a){var b=new Uint8Array(Math.floor(a.length/2)),c=0;a.replace(/(..)/g,function(a){b[c++]=parseInt(a,16)});return b}};DataUtils.hexToRawString=function(a){if("string"==typeof a){var b="";a.replace(/(..)/g,function(a){b+=String.fromCharCode(parseInt(a,16))});return b}};
-DataUtils.toNumbersFromString=function(a){for(var b=new Uint8Array(a.length),c=0;c<a.length;c++)b[c]=a.charCodeAt(c);return b};DataUtils.stringToUtf8Array=function(a){return DataUtils.toNumbersFromString(str2rstr_utf8(a))};DataUtils.concatArrays=function(a){for(var b=0,c=0;c<a.length;++c)b+=a[c].length;for(var b=new Uint8Array(b),d=0,c=0;c<a.length;++c)b.set(a[c],d),d+=a[c].length;return b};
-DataUtils.decodeUtf8=function(a){for(var b="",c=0,d=0,e=0;c<a.length;)if(d=a.charCodeAt(c),128>d)b+=String.fromCharCode(d),c++;else if(191<d&&224>d)e=a.charCodeAt(c+1),b+=String.fromCharCode((d&31)<<6|e&63),c+=2;else var e=a.charCodeAt(c+1),f=a.charCodeAt(c+2),b=b+String.fromCharCode((d&15)<<12|(e&63)<<6|f&63),c=c+3;return b};DataUtils.arraysEqual=function(a,b){if(a.length!=b.length)return!1;for(var c=0;c<a.length;++c)if(a[c]!=b[c])return!1;return!0};
-DataUtils.bigEndianToUnsignedInt=function(a){for(var b=0,c=0;c<a.length;++c)b<<=8,b+=a[c];return b};DataUtils.nonNegativeIntToBigEndian=function(a){a=Math.round(a);if(0>=a)return new Uint8Array(0);for(var b=new Uint8Array(8),c=0;0!=a;)++c,b[8-c]=a&255,a>>=8;return b.subarray(8-c,8)};DataUtils.shuffle=function(a){for(var b=a.length-1;1<=b;--b){var c=Math.floor(Math.random()*(b+1)),d=a[b];a[b]=a[c];a[c]=d}};function encodeToHexInterest(a){return DataUtils.toHex(encodeToBinaryInterest(a))}
-function encodeToBinaryInterest(a){var b=new BinaryXMLEncoder;a.to_ccnb(b);return b.getReducedOstream()}function encodeToHexContentObject(a){return DataUtils.toHex(encodeToBinaryContentObject(a))}function encodeToBinaryContentObject(a){var b=new BinaryXMLEncoder;a.to_ccnb(b);return b.getReducedOstream()}function encodeForwardingEntry(a){var b=new BinaryXMLEncoder;a.to_ccnb(b);return b.getReducedOstream()}
-function decodeHexFaceInstance(a){var b=DataUtils.toNumbers(a),a=new BinaryXMLDecoder(b);3<LOG&&console.log("DECODING HEX FACE INSTANCE  \n"+b);b=new FaceInstance;b.from_ccnb(a);return b}function decodeHexInterest(a){var b=DataUtils.toNumbers(a),a=new BinaryXMLDecoder(b);3<LOG&&console.log("DECODING HEX INTERST  \n"+b);b=new Interest;b.from_ccnb(a);return b}
-function decodeHexContentObject(a){var b=DataUtils.toNumbers(a),a=new BinaryXMLDecoder(b);3<LOG&&console.log("DECODED HEX CONTENT OBJECT \n"+b);b=new ContentObject;b.from_ccnb(a);return b}function decodeHexForwardingEntry(a){var b=DataUtils.toNumbers(a),a=new BinaryXMLDecoder(b);3<LOG&&console.log("DECODED HEX FORWARDING ENTRY \n"+b);b=new ForwardingEntry;b.from_ccnb(a);return b}
-function decodeSubjectPublicKeyInfo(a){var a=DataUtils.toHex(a).toLowerCase(),a=_x509_getPublicKeyHexArrayFromCertHex(a,_x509_getSubjectPublicKeyPosFromCertHex(a,0)),b=new RSAKey;b.setPublic(a[0],a[1]);return b}
-function contentObjectToHtml(a){var b="";if(-1==a)b+="NO CONTENT FOUND";else if(-2==a)b+="CONTENT NAME IS EMPTY";else{null!=a.name&&null!=a.name.components&&(b+="NAME: "+a.name.to_uri(),b+="<br /><br />");null!=a.content&&(b+="CONTENT(ASCII): "+DataUtils.toString(a.content),b+="<br />",b+="<br />");null!=a.content&&(b+="CONTENT(hex): "+DataUtils.toHex(a.content),b+="<br />",b+="<br />");null!=a.signature&&null!=a.signature.signature&&(b+="SIGNATURE(hex): "+DataUtils.toHex(a.signature.signature),b+=
-"<br />",b+="<br />");null!=a.signedInfo&&(null!=a.signedInfo.publisher&&null!=a.signedInfo.publisher.publisherPublicKeyDigest)&&(b+="Publisher Public Key Digest(hex): "+DataUtils.toHex(a.signedInfo.publisher.publisherPublicKeyDigest),b+="<br />",b+="<br />");if(null!=a.signedInfo&&null!=a.signedInfo.timestamp){var c=new Date;c.setTime(a.signedInfo.timestamp.msec);b+="TimeStamp: "+c;b+="<br />";b+="TimeStamp(number): "+a.signedInfo.timestamp.msec;b+="<br />"}null!=a.signedInfo&&null!=a.signedInfo.finalBlockID&&
-(b+="FinalBlockID: "+DataUtils.toHex(a.signedInfo.finalBlockID),b+="<br />");if(null!=a.signedInfo&&null!=a.signedInfo.locator&&null!=a.signedInfo.locator.certificate){var d=DataUtils.toHex(a.signedInfo.locator.certificate).toLowerCase(),c=DataUtils.toHex(a.signature.signature).toLowerCase(),e=DataUtils.toString(a.rawSignatureData),b=b+("Hex Certificate: "+d),b=b+"<br />",b=b+"<br />",e=new X509;e.readCertHex(d);b+="Public key (hex) modulus: "+e.subjectPublicKeyRSA.n.toString(16)+"<br/>";b+="exponent: "+
-e.subjectPublicKeyRSA.e.toString(16)+"<br/>";b+="<br/>";c=e.subjectPublicKeyRSA.verifyByteArray(a.rawSignatureData,null,c);2<LOG&&console.log("result is "+c);d=e.subjectPublicKeyRSA.n;e=e.subjectPublicKeyRSA.e;2<LOG&&console.log("PUBLIC KEY n after is ");2<LOG&&console.log(d);2<LOG&&console.log("EXPONENT e after is ");2<LOG&&console.log(e);b=c?b+"SIGNATURE VALID":b+"SIGNATURE INVALID";b+="<br />";b+="<br />"}if(null!=a.signedInfo&&null!=a.signedInfo.locator&&null!=a.signedInfo.locator.publicKey){var f=
-DataUtils.toHex(a.signedInfo.locator.publicKey).toLowerCase(),g=DataUtils.toString(a.signedInfo.locator.publicKey),c=DataUtils.toHex(a.signature.signature).toLowerCase(),e=DataUtils.toString(a.rawSignatureData),d=null,h="";null!=a.signature.Witness&&(d=new Witness,d.decode(a.signature.Witness),h=DataUtils.toHex(a.signature.Witness));b+="Public key: "+f;b+="<br />";b+="<br />";2<LOG&&console.log(" ContentName + SignedInfo + Content = "+e);2<LOG&&console.log(" PublicKeyHex = "+f);2<LOG&&console.log(" PublicKeyString = "+
-g);2<LOG&&console.log(" Signature "+c);2<LOG&&console.log(" Witness "+h);2<LOG&&console.log(" Signature NOW IS");2<LOG&&console.log(a.signature.signature);e=decodeSubjectPublicKeyInfo(a.signedInfo.locator.publicKey);b+="Public key (hex) modulus: "+e.n.toString(16)+"<br/>";b+="exponent: "+e.e.toString(16)+"<br/>";b+="<br/>";c=e.verifyByteArray(a.rawSignatureData,d,c);2<LOG&&console.log("PUBLIC KEY n after is ");2<LOG&&console.log(e.n);2<LOG&&console.log("EXPONENT e after is ");2<LOG&&console.log(e.e);
-b=c?b+"SIGNATURE VALID":b+"SIGNATURE INVALID";b+="<br />";b+="<br />"}}return b}
-var KeyManager=function(){this.certificate="MIIBmzCCAQQCCQC32FyQa61S7jANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwdheGVsY2R2MB4XDTEyMDQyODIzNDQzN1oXDTEyMDUyODIzNDQzN1owEjEQMA4GA1UEAxMHYXhlbGNkdjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4X0wp9goqxuECxdULcr2IHr9Ih4Iaypg0Wy39URIup8/CLzQmdsh3RYqd55hqonu5VTTpH3iMLx6xZDVJAZ8OJi7pvXcQ2C4Re2kjL2c8SanI0RfDhlS1zJadfr1VhRPmpivcYawJ4aFuOLAi+qHFxtN7lhcGCgpW1OV60oXd58CAwEAATANBgkqhkiG9w0BAQUFAAOBgQDLOrA1fXzSrpftUB5Ro6DigX1Bjkf7F5Bkd69hSVp+jYeJFBBlsILQAfSxUZPQtD+2Yc3iCmSYNyxqu9PcufDRJlnvB7PG29+L3y9lR37tetzUV9eTscJ7rdp8Wt6AzpW32IJ/54yKNfP7S6ZIoIG+LP6EIxq6s8K1MXRt8uBJKw==";this.publicKey=
-"30819F300D06092A864886F70D010101050003818D0030818902818100E17D30A7D828AB1B840B17542DCAF6207AFD221E086B2A60D16CB7F54448BA9F3F08BCD099DB21DD162A779E61AA89EEE554D3A47DE230BC7AC590D524067C3898BBA6F5DC4360B845EDA48CBD9CF126A723445F0E1952D7325A75FAF556144F9A98AF7186B0278685B8E2C08BEA87171B4DEE585C1828295B5395EB4A17779F0203010001";this.privateKey="MIICXQIBAAKBgQDhfTCn2CirG4QLF1QtyvYgev0iHghrKmDRbLf1REi6nz8IvNCZ2yHdFip3nmGqie7lVNOkfeIwvHrFkNUkBnw4mLum9dxDYLhF7aSMvZzxJqcjRF8OGVLXMlp1+vVWFE+amK9xhrAnhoW44sCL6ocXG03uWFwYKClbU5XrShd3nwIDAQABAoGAGkv6T6jC3WmhFZYL6CdCWvlc6gysmKrhjarrLTxgavtFY6R5g2ft5BXAsCCVbUkWxkIFSKqxpVNl0gKZCNGEzPDN6mHJOQI/h0rlxNIHAuGfoAbCzALnqmyZivhJAPGijAyKuU9tczsst5+Kpn+bn7ehzHQuj7iwJonS5WbojqECQQD851K8TpW2GrRizNgG4dx6orZxAaon/Jnl8lS7soXhllQty7qG+oDfzznmdMsiznCqEABzHUUKOVGE9RWPN3aRAkEA5D/w9N55d0ibnChFJlc8cUAoaqH+w+U3oQP2Lb6AZHJpLptN4y4b/uf5d4wYU5/i/gC7SSBH3wFhh9bjRLUDLwJAVOx8vN0Kqt7myfKNbCo19jxjVSlA8TKCn1Oznl/BU1I+rC4oUaEW25DjmX6IpAR8kq7S59ThVSCQPjxqY/A08QJBAIRaF2zGPITQk3r/VumemCvLWiRK/yG0noc9dtibqHOWbCtcXtOm/xDWjq+lis2i3ssOvYrvrv0/HcDY+Dv1An0CQQCLJtMsfSg4kvG/FRY5UMhtMuwo8ovYcMXt4Xv/LWaMhndD67b2UGawQCRqr5ghRTABWdDD/HuuMBjrkPsX0861"};
-KeyManager.prototype.verify=function(a,b){var c=this.certificate,d=new X509;d.readCertPEM(c);return d.subjectPublicKeyRSA.verifyString(a,b)};KeyManager.prototype.sign=function(a){var b=this.privateKey,c=new RSAKey;c.readPrivateKeyFromPEMString(b);return c.signString(a,"sha256")};var globalKeyManager=new KeyManager,MerklePath=function(){this.index=null;this.digestList=[]},Witness=function(){this.oid=null;this.path=new MerklePath};
-function parseOID(a,b,c){for(var d,e=0,f=0;b<c;++b){var g=a[b],e=e<<7|g&127,f=f+7;g&128||(d=void 0==d?parseInt(e/40)+"."+e%40:d+("."+(31<=f?"bigint":e)),e=f=0);d+=String.fromCharCode()}return d}function parseInteger(a,b,c){for(var d=0;b<c;++b)d=d<<8|a[b];return d}
-Witness.prototype.decode=function(a){for(var b=0,c=0;b<a.length;){var d=0;if(48==a[b])0!=(a[b+1]&128)&&(d=a[b+1]&127),c++;else if(6==a[b])d=a[b+1],this.oid=parseOID(a,b+2,b+2+d);else if(2==a[b])d=a[b+1],this.path.index=parseInteger(a,b+2,b+2+d);else if(4==a[b]&&(0!=(a[b+1]&128)&&(d=a[b+1]&127),4==c)){var d=a[b+1],e=DataUtils.toHex(a.subarray(b+2,b+2+d));this.path.digestList.push(e)}b=b+2+d}};var hexcase=0,b64pad="";
-function hex_sha256_from_bytes(a){return rstr2hex(binb2rstr(binb_sha256(byteArray2binb(a),8*a.length)))}function hex_sha256(a){return rstr2hex(rstr_sha256(str2rstr_utf8(a)))}function b64_sha256(a){return rstr2b64(rstr_sha256(str2rstr_utf8(a)))}function any_sha256(a,b){return rstr2any(rstr_sha256(str2rstr_utf8(a)),b)}function hex_hmac_sha256(a,b){return rstr2hex(rstr_hmac_sha256(str2rstr_utf8(a),str2rstr_utf8(b)))}
-function b64_hmac_sha256(a,b){return rstr2b64(rstr_hmac_sha256(str2rstr_utf8(a),str2rstr_utf8(b)))}function any_hmac_sha256(a,b,c){return rstr2any(rstr_hmac_sha256(str2rstr_utf8(a),str2rstr_utf8(b)),c)}function sha256_vm_test(){return"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"==hex_sha256("abc").toLowerCase()}function rstr_sha256(a){return binb2rstr(binb_sha256(rstr2binb(a),8*a.length))}
-function rstr_hmac_sha256(a,b){var c=rstr2binb(a);16<c.length&&(c=binb_sha256(c,8*a.length));for(var d=Array(16),e=Array(16),f=0;16>f;f++)d[f]=c[f]^909522486,e[f]=c[f]^1549556828;c=binb_sha256(d.concat(rstr2binb(b)),512+8*b.length);return binb2rstr(binb_sha256(e.concat(c),768))}function rstr2hex(a){try{hexcase}catch(b){hexcase=0}for(var c=hexcase?"0123456789ABCDEF":"0123456789abcdef",d="",e,f=0;f<a.length;f++)e=a.charCodeAt(f),d+=c.charAt(e>>>4&15)+c.charAt(e&15);return d}
-function rstr2b64(a){try{b64pad}catch(b){b64pad=""}for(var c="",d=a.length,e=0;e<d;e+=3)for(var f=a.charCodeAt(e)<<16|(e+1<d?a.charCodeAt(e+1)<<8:0)|(e+2<d?a.charCodeAt(e+2):0),g=0;4>g;g++)c=8*e+6*g>8*a.length?c+b64pad:c+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(f>>>6*(3-g)&63);return c}
-function rstr2any(a,b){var c=b.length,d=[],e,f,g,h,i=Array(Math.ceil(a.length/2));for(e=0;e<i.length;e++)i[e]=a.charCodeAt(2*e)<<8|a.charCodeAt(2*e+1);for(;0<i.length;){h=[];for(e=g=0;e<i.length;e++)if(g=(g<<16)+i[e],f=Math.floor(g/c),g-=f*c,0<h.length||0<f)h[h.length]=f;d[d.length]=g;i=h}c="";for(e=d.length-1;0<=e;e--)c+=b.charAt(d[e]);d=Math.ceil(8*a.length/(Math.log(b.length)/Math.log(2)));for(e=c.length;e<d;e++)c=b[0]+c;return c}
-function str2rstr_utf8(a){for(var b="",c=-1,d,e;++c<a.length;)d=a.charCodeAt(c),e=c+1<a.length?a.charCodeAt(c+1):0,55296<=d&&(56319>=d&&56320<=e&&57343>=e)&&(d=65536+((d&1023)<<10)+(e&1023),c++),127>=d?b+=String.fromCharCode(d):2047>=d?b+=String.fromCharCode(192|d>>>6&31,128|d&63):65535>=d?b+=String.fromCharCode(224|d>>>12&15,128|d>>>6&63,128|d&63):2097151>=d&&(b+=String.fromCharCode(240|d>>>18&7,128|d>>>12&63,128|d>>>6&63,128|d&63));return b}
-function str2rstr_utf16le(a){for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(a.charCodeAt(c)&255,a.charCodeAt(c)>>>8&255);return b}function str2rstr_utf16be(a){for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(a.charCodeAt(c)>>>8&255,a.charCodeAt(c)&255);return b}function rstr2binb(a){for(var b=Array(a.length>>2),c=0;c<8*a.length;c+=8)b[c>>5]|=(a.charCodeAt(c/8)&255)<<24-c%32;return b}
-function byteArray2binb(a){for(var b=Array(a.length>>2),c=0;c<8*a.length;c+=8)b[c>>5]|=(a[c/8]&255)<<24-c%32;return b}function binb2rstr(a){for(var b="",c=0;c<32*a.length;c+=8)b+=String.fromCharCode(a[c>>5]>>>24-c%32&255);return b}function sha256_S(a,b){return a>>>b|a<<32-b}function sha256_R(a,b){return a>>>b}function sha256_Ch(a,b,c){return a&b^~a&c}function sha256_Maj(a,b,c){return a&b^a&c^b&c}function sha256_Sigma0256(a){return sha256_S(a,2)^sha256_S(a,13)^sha256_S(a,22)}
-function sha256_Sigma1256(a){return sha256_S(a,6)^sha256_S(a,11)^sha256_S(a,25)}function sha256_Gamma0256(a){return sha256_S(a,7)^sha256_S(a,18)^sha256_R(a,3)}function sha256_Gamma1256(a){return sha256_S(a,17)^sha256_S(a,19)^sha256_R(a,10)}function sha256_Sigma0512(a){return sha256_S(a,28)^sha256_S(a,34)^sha256_S(a,39)}function sha256_Sigma1512(a){return sha256_S(a,14)^sha256_S(a,18)^sha256_S(a,41)}function sha256_Gamma0512(a){return sha256_S(a,1)^sha256_S(a,8)^sha256_R(a,7)}
-function sha256_Gamma1512(a){return sha256_S(a,19)^sha256_S(a,61)^sha256_R(a,6)}
-var sha256_K=[1116352408,1899447441,-1245643825,-373957723,961987163,1508970993,-1841331548,-1424204075,-670586216,310598401,607225278,1426881987,1925078388,-2132889090,-1680079193,-1046744716,-459576895,-272742522,264347078,604807628,770255983,1249150122,1555081692,1996064986,-1740746414,-1473132947,-1341970488,-1084653625,-958395405,-710438585,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,-2117940946,-1838011259,-1564481375,-1474664885,-1035236496,-949202525,
--778901479,-694614492,-200395387,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,-2067236844,-1933114872,-1866530822,-1538233109,-1090935817,-965641998];function binb_sha256(a,b){var c=[1779033703,-1150833019,1013904242,-1521486534,1359893119,-1694144372,528734635,1541459225],d=Array(64);a[b>>5]|=128<<24-b%32;a[(b+64>>9<<4)+15]=b;for(var e=0;e<a.length;e+=16)processBlock_sha256(a,e,c,d);return c}
-function processBlock_sha256(a,b,c,d){var e,f,g,h,i,k,m,l,n,j,p;e=c[0];f=c[1];g=c[2];h=c[3];i=c[4];k=c[5];m=c[6];l=c[7];for(n=0;64>n;n++)d[n]=16>n?a[n+b]:safe_add(safe_add(safe_add(sha256_Gamma1256(d[n-2]),d[n-7]),sha256_Gamma0256(d[n-15])),d[n-16]),j=safe_add(safe_add(safe_add(safe_add(l,sha256_Sigma1256(i)),sha256_Ch(i,k,m)),sha256_K[n]),d[n]),p=safe_add(sha256_Sigma0256(e),sha256_Maj(e,f,g)),l=m,m=k,k=i,i=safe_add(h,j),h=g,g=f,f=e,e=safe_add(j,p);c[0]=safe_add(e,c[0]);c[1]=safe_add(f,c[1]);c[2]=
-safe_add(g,c[2]);c[3]=safe_add(h,c[3]);c[4]=safe_add(i,c[4]);c[5]=safe_add(k,c[5]);c[6]=safe_add(m,c[6]);c[7]=safe_add(l,c[7])}function safe_add(a,b){var c=(a&65535)+(b&65535);return(a>>16)+(b>>16)+(c>>16)<<16|c&65535}var Sha256=function(){this.W=Array(64);this.hash=[1779033703,-1150833019,1013904242,-1521486534,1359893119,-1694144372,528734635,1541459225];this.nTotalBytes=0;this.buffer=new Uint8Array(64);this.nBufferBytes=0};
-Sha256.prototype.update=function(a){this.nTotalBytes+=a.length;if(0<this.nBufferBytes){var b=this.buffer.length-this.nBufferBytes;if(a.length<b){this.buffer.set(a,this.nBufferBytes);this.nBufferBytes+=a.length;return}this.buffer.set(a.subarray(0,b),this.nBufferBytes);processBlock_sha256(byteArray2binb(this.buffer),0,this.hash,this.W);this.nBufferBytes=0;a=a.subarray(b,a.length);if(0==a.length)return}b=a.length>>6;if(0<b){for(var b=64*b,c=byteArray2binb(a.subarray(0,b)),d=0;d<c.length;d+=16)processBlock_sha256(c,
-d,this.hash,this.W);a=a.subarray(b,a.length)}0<a.length&&(this.buffer.set(a),this.nBufferBytes=a.length)};Sha256.prototype.finalize=function(){var a=byteArray2binb(this.buffer.subarray(0,this.nBufferBytes)),b=8*this.nBufferBytes;a[b>>5]|=128<<24-b%32;a[(b+64>>9<<4)+15]=8*this.nTotalBytes;for(b=0;b<a.length;b+=16)processBlock_sha256(a,b,this.hash,this.W);return Sha256.binb2Uint8Array(this.hash)};
-Sha256.binb2Uint8Array=function(a){for(var b=new Uint8Array(4*a.length),c=0,d=0;d<32*a.length;d+=8)b[c++]=a[d>>5]>>>24-d%32&255;return b};var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",b64pad="=";
-function hex2b64(a){var b,c,d="";for(b=0;b+3<=a.length;b+=3)c=parseInt(a.substring(b,b+3),16),d+=b64map.charAt(c>>6)+b64map.charAt(c&63);b+1==a.length?(c=parseInt(a.substring(b,b+1),16),d+=b64map.charAt(c<<2)):b+2==a.length&&(c=parseInt(a.substring(b,b+2),16),d+=b64map.charAt(c>>2)+b64map.charAt((c&3)<<4));for(;0<(d.length&3);)d+=b64pad;return d}
-function b64tohex(a){var b="",c,d=0,e;for(c=0;c<a.length&&a.charAt(c)!=b64pad;++c){var f=b64map.indexOf(a.charAt(c));0>f||(0==d?(b+=int2char(f>>2),e=f&3,d=1):1==d?(b+=int2char(e<<2|f>>4),e=f&15,d=2):2==d?(b+=int2char(e),b+=int2char(f>>2),e=f&3,d=3):(b+=int2char(e<<2|f>>4),b+=int2char(f&15),d=0))}1==d&&(b+=int2char(e<<2));return b}function b64toBA(a){var a=b64tohex(a),b,c=[];for(b=0;2*b<a.length;++b)c[b]=parseInt(a.substring(2*b,2*b+2),16);return c}
-function parseBigInt(a,b){return new BigInteger(a,b)}function linebrk(a,b){for(var c="",d=0;d+b<a.length;)c+=a.substring(d,d+b)+"\n",d+=b;return c+a.substring(d,a.length)}function byte2Hex(a){return 16>a?"0"+a.toString(16):a.toString(16)}
-function pkcs1pad2(a,b){if(b<a.length+11)return alert("Message too long for RSA"),null;for(var c=[],d=a.length-1;0<=d&&0<b;){var e=a.charCodeAt(d--);128>e?c[--b]=e:127<e&&2048>e?(c[--b]=e&63|128,c[--b]=e>>6|192):(c[--b]=e&63|128,c[--b]=e>>6&63|128,c[--b]=e>>12|224)}c[--b]=0;d=new SecureRandom;for(e=[];2<b;){for(e[0]=0;0==e[0];)d.nextBytes(e);c[--b]=e[0]}c[--b]=2;c[--b]=0;return new BigInteger(c)}function RSAKey(){this.n=null;this.e=0;this.coeff=this.dmq1=this.dmp1=this.q=this.p=this.d=null}
-function RSASetPublic(a,b){null!=a&&null!=b&&0<a.length&&0<b.length?(this.n=parseBigInt(a,16),this.e=parseInt(b,16)):alert("Invalid RSA public key")}function RSADoPublic(a){return a.modPowInt(this.e,this.n)}function RSAEncrypt(a){a=pkcs1pad2(a,this.n.bitLength()+7>>3);if(null==a)return null;a=this.doPublic(a);if(null==a)return null;a=a.toString(16);return 0==(a.length&1)?a:"0"+a}RSAKey.prototype.doPublic=RSADoPublic;RSAKey.prototype.setPublic=RSASetPublic;RSAKey.prototype.encrypt=RSAEncrypt;
-function pkcs1unpad2(a,b){for(var c=a.toByteArray(),d=0;d<c.length&&0==c[d];)++d;if(c.length-d!=b-1||2!=c[d])return null;for(++d;0!=c[d];)if(++d>=c.length)return null;for(var e="";++d<c.length;){var f=c[d]&255;128>f?e+=String.fromCharCode(f):191<f&&224>f?(e+=String.fromCharCode((f&31)<<6|c[d+1]&63),++d):(e+=String.fromCharCode((f&15)<<12|(c[d+1]&63)<<6|c[d+2]&63),d+=2)}return e}
-function RSASetPrivate(a,b,c){null!=a&&null!=b&&0<a.length&&0<b.length?(this.n=parseBigInt(a,16),this.e=parseInt(b,16),this.d=parseBigInt(c,16)):alert("Invalid RSA private key")}
-function RSASetPrivateEx(a,b,c,d,e,f,g,h){null!=a&&null!=b&&0<a.length&&0<b.length?(this.n=parseBigInt(a,16),this.e=parseInt(b,16),this.d=parseBigInt(c,16),this.p=parseBigInt(d,16),this.q=parseBigInt(e,16),this.dmp1=parseBigInt(f,16),this.dmq1=parseBigInt(g,16),this.coeff=parseBigInt(h,16)):alert("Invalid RSA private key")}
-function RSAGenerate(a,b){var c=new SecureRandom,d=a>>1;this.e=parseInt(b,16);for(var e=new BigInteger(b,16);;){for(;!(this.p=new BigInteger(a-d,1,c),0==this.p.subtract(BigInteger.ONE).gcd(e).compareTo(BigInteger.ONE)&&this.p.isProbablePrime(10)););for(;!(this.q=new BigInteger(d,1,c),0==this.q.subtract(BigInteger.ONE).gcd(e).compareTo(BigInteger.ONE)&&this.q.isProbablePrime(10)););if(0>=this.p.compareTo(this.q)){var f=this.p;this.p=this.q;this.q=f}var f=this.p.subtract(BigInteger.ONE),g=this.q.subtract(BigInteger.ONE),
-h=f.multiply(g);if(0==h.gcd(e).compareTo(BigInteger.ONE)){this.n=this.p.multiply(this.q);this.d=e.modInverse(h);this.dmp1=this.d.mod(f);this.dmq1=this.d.mod(g);this.coeff=this.q.modInverse(this.p);break}}}function RSADoPrivate(a){if(null==this.p||null==this.q)return a.modPow(this.d,this.n);for(var b=a.mod(this.p).modPow(this.dmp1,this.p),a=a.mod(this.q).modPow(this.dmq1,this.q);0>b.compareTo(a);)b=b.add(this.p);return b.subtract(a).multiply(this.coeff).mod(this.p).multiply(this.q).add(a)}
-function RSADecrypt(a){a=parseBigInt(a,16);a=this.doPrivate(a);return null==a?null:pkcs1unpad2(a,this.n.bitLength()+7>>3)}RSAKey.prototype.doPrivate=RSADoPrivate;RSAKey.prototype.setPrivate=RSASetPrivate;RSAKey.prototype.setPrivateEx=RSASetPrivateEx;RSAKey.prototype.generate=RSAGenerate;RSAKey.prototype.decrypt=RSADecrypt;function _rsapem_pemToBase64(a){a=a.replace("-----BEGIN RSA PRIVATE KEY-----","");a=a.replace("-----END RSA PRIVATE KEY-----","");return a=a.replace(/[ \n]+/g,"")}
-function _rsapem_getPosArrayOfChildrenFromHex(a){var b=[],c=ASN1HEX.getStartPosOfV_AtObj(a,0),d=ASN1HEX.getPosOfNextSibling_AtObj(a,c),e=ASN1HEX.getPosOfNextSibling_AtObj(a,d),f=ASN1HEX.getPosOfNextSibling_AtObj(a,e),g=ASN1HEX.getPosOfNextSibling_AtObj(a,f),h=ASN1HEX.getPosOfNextSibling_AtObj(a,g),i=ASN1HEX.getPosOfNextSibling_AtObj(a,h),k=ASN1HEX.getPosOfNextSibling_AtObj(a,i),a=ASN1HEX.getPosOfNextSibling_AtObj(a,k);b.push(c,d,e,f,g,h,i,k,a);return b}
-function _rsapem_getHexValueArrayOfChildrenFromHex(a){var b=_rsapem_getPosArrayOfChildrenFromHex(a),c=ASN1HEX.getHexOfV_AtObj(a,b[0]),d=ASN1HEX.getHexOfV_AtObj(a,b[1]),e=ASN1HEX.getHexOfV_AtObj(a,b[2]),f=ASN1HEX.getHexOfV_AtObj(a,b[3]),g=ASN1HEX.getHexOfV_AtObj(a,b[4]),h=ASN1HEX.getHexOfV_AtObj(a,b[5]),i=ASN1HEX.getHexOfV_AtObj(a,b[6]),k=ASN1HEX.getHexOfV_AtObj(a,b[7]),a=ASN1HEX.getHexOfV_AtObj(a,b[8]),b=[];b.push(c,d,e,f,g,h,i,k,a);return b}
-function _rsapem_readPrivateKeyFromPEMString(a){a=_rsapem_pemToBase64(a);a=b64tohex(a);a=_rsapem_getHexValueArrayOfChildrenFromHex(a);this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8])}RSAKey.prototype.readPrivateKeyFromPEMString=_rsapem_readPrivateKeyFromPEMString;var _RSASIGN_DIHEAD=[];_RSASIGN_DIHEAD.sha1="3021300906052b0e03021a05000414";_RSASIGN_DIHEAD.sha256="3031300d060960864801650304020105000420";_RSASIGN_DIHEAD.sha384="3041300d060960864801650304020205000430";
-_RSASIGN_DIHEAD.sha512="3051300d060960864801650304020305000440";_RSASIGN_DIHEAD.md2="3020300c06082a864886f70d020205000410";_RSASIGN_DIHEAD.md5="3020300c06082a864886f70d020505000410";_RSASIGN_DIHEAD.ripemd160="3021300906052b2403020105000414";var _RSASIGN_HASHHEXFUNC=[];_RSASIGN_HASHHEXFUNC.sha1=function(a){return hex_sha1(a)};_RSASIGN_HASHHEXFUNC.sha256=function(a){return hex_sha256(a)};_RSASIGN_HASHHEXFUNC.sha512=function(a){return hex_sha512(a)};_RSASIGN_HASHHEXFUNC.md5=function(a){return hex_md5(a)};
-_RSASIGN_HASHHEXFUNC.ripemd160=function(a){return hex_rmd160(a)};var _RSASIGN_HASHBYTEFUNC=[];_RSASIGN_HASHBYTEFUNC.sha256=function(a){return hex_sha256_from_bytes(a)};var _RE_HEXDECONLY=RegExp("");_RE_HEXDECONLY.compile("[^0-9a-f]","gi");function _rsasign_getHexPaddedDigestInfoForString(a,b,c){for(var b=b/4,a=(0,_RSASIGN_HASHHEXFUNC[c])(a),c="00"+_RSASIGN_DIHEAD[c]+a,a="",b=b-4-c.length,d=0;d<b;d+=2)a+="ff";return sPaddedMessageHex="0001"+a+c}
-function _rsasign_getHexPaddedDigestInfoForStringHEX(a,b,c){for(var b=b/4,a=(0,_RSASIGN_HASHHEXFUNC[c])(a),c="00"+_RSASIGN_DIHEAD[c]+a,a="",b=b-4-c.length,d=0;d<b;d+=2)a+="ff";return sPaddedMessageHex="0001"+a+c}function _rsasign_getHexPaddedDigestInfoForByteArray(a,b,c){for(var b=b/4,a=(0,_RSASIGN_HASHBYTEFUNC[c])(a),c="00"+_RSASIGN_DIHEAD[c]+a,a="",b=b-4-c.length,d=0;d<b;d+=2)a+="ff";return sPaddedMessageHex="0001"+a+c}
-function _zeroPaddingOfSignature(a,b){for(var c="",d=b/4-a.length,e=0;e<d;e++)c+="0";return c+a}function _rsasign_signString(a,b){var c=_rsasign_getHexPaddedDigestInfoForString(a,this.n.bitLength(),b),c=parseBigInt(c,16),c=this.doPrivate(c).toString(16);return _zeroPaddingOfSignature(c,this.n.bitLength())}
-function _rsasign_signStringHEX(a,b){var c=_rsasign_getHexPaddedDigestInfoForString(a,this.n.bitLength(),b),c=parseBigInt(c,16),c=this.doPrivate(c).toString(16);return _zeroPaddingOfSignature(c,this.n.bitLength())}function _rsasign_signByteArray(a,b,c){a=_rsasign_getHexPaddedDigestInfoForByteArray(a,c.n.bitLength(),b);a=parseBigInt(a,16);a=c.doPrivate(a).toString(16);return _zeroPaddingOfSignature(a,c.n.bitLength())}
-function _rsasign_signByteArrayWithSHA256(a){return _rsasign_signByteArray(a,"sha256",this)}function _rsasign_signStringWithSHA1(a){return _rsasign_signString(a,"sha1")}function _rsasign_signStringWithSHA256(a){return _rsasign_signString(a,"sha256")}function _rsasign_getDecryptSignatureBI(a,b,c){var d=new RSAKey;d.setPublic(b,c);return d.doPublic(a)}function _rsasign_getHexDigestInfoFromSig(a,b,c){return _rsasign_getDecryptSignatureBI(a,b,c).toString(16).replace(/^1f+00/,"")}
-function _rsasign_getAlgNameAndHashFromHexDisgestInfo(a){for(var b in _RSASIGN_DIHEAD){var c=_RSASIGN_DIHEAD[b],d=c.length;if(a.substring(0,d)==c)return[b,a.substring(d)]}return[]}function _rsasign_verifySignatureWithArgs(a,b,c,d){b=_rsasign_getHexDigestInfoFromSig(b,c,d);c=_rsasign_getAlgNameAndHashFromHexDisgestInfo(b);if(0==c.length)return!1;b=c[1];a=(0,_RSASIGN_HASHHEXFUNC[c[0]])(a);return b==a}
-function _rsasign_verifyHexSignatureForMessage(a,b){var c=parseBigInt(a,16);return _rsasign_verifySignatureWithArgs(b,c,this.n.toString(16),this.e.toString(16))}
-function _rsasign_verifyString(a,b){b=b.replace(_RE_HEXDECONLY,"");3<LOG&&console.log("n is "+this.n);3<LOG&&console.log("e is "+this.e);if(b.length!=this.n.bitLength()/4)return 0;var b=b.replace(/[ \n]+/g,""),c=parseBigInt(b,16),c=this.doPublic(c).toString(16).replace(/^1f+00/,""),d=_rsasign_getAlgNameAndHashFromHexDisgestInfo(c);if(0==d.length)return!1;c=d[1];d=(0,_RSASIGN_HASHHEXFUNC[d[0]])(a);return c==d}
-function _rsasign_verifyByteArray(a,b,c){c=c.replace(_RE_HEXDECONLY,"");3<LOG&&console.log("n is "+this.n);3<LOG&&console.log("e is "+this.e);if(c.length!=this.n.bitLength()/4)return 0;c=c.replace(/[ \n]+/g,"");c=parseBigInt(c,16);c=this.doPublic(c).toString(16).replace(/^1f+00/,"");c=_rsasign_getAlgNameAndHashFromHexDisgestInfo(c);if(0==c.length)return!1;var d=c[0],c=c[1],e=null;if(null==b)e=(0,_RSASIGN_HASHBYTEFUNC[d])(a);else{a=hex_sha256_from_bytes(a);d=b.path.index;for(e=b.path.digestList.length-
-1;0<=e;e--)var f="",f=0==d%2?a+b.path.digestList[e]:b.path.digestList[e]+a,a=hex_sha256_from_bytes(DataUtils.toNumbers(f)),d=Math.floor(d/2);e=hex_sha256_from_bytes(DataUtils.toNumbers(a))}return c==e}RSAKey.prototype.signString=_rsasign_signString;RSAKey.prototype.signByteArray=_rsasign_signByteArray;RSAKey.prototype.signByteArrayWithSHA256=_rsasign_signByteArrayWithSHA256;RSAKey.prototype.signStringWithSHA1=_rsasign_signStringWithSHA1;RSAKey.prototype.signStringWithSHA256=_rsasign_signStringWithSHA256;
-RSAKey.prototype.sign=_rsasign_signString;RSAKey.prototype.signWithSHA1=_rsasign_signStringWithSHA1;RSAKey.prototype.signWithSHA256=_rsasign_signStringWithSHA256;RSAKey.prototype.verifyByteArray=_rsasign_verifyByteArray;RSAKey.prototype.verifyString=_rsasign_verifyString;RSAKey.prototype.verifyHexSignatureForMessage=_rsasign_verifyHexSignatureForMessage;RSAKey.prototype.verify=_rsasign_verifyString;RSAKey.prototype.verifyHexSignatureForByteArrayMessage=_rsasign_verifyHexSignatureForMessage;
-function _asnhex_getByteLengthOfL_AtObj(a,b){if("8"!=a.substring(b+2,b+3))return 1;var c=parseInt(a.substring(b+3,b+4));return 0==c?-1:0<c&&10>c?c+1:-2}function _asnhex_getHexOfL_AtObj(a,b){var c=_asnhex_getByteLengthOfL_AtObj(a,b);return 1>c?"":a.substring(b+2,b+2+2*c)}function _asnhex_getIntOfL_AtObj(a,b){var c=_asnhex_getHexOfL_AtObj(a,b);return""==c?-1:(8>parseInt(c.substring(0,1))?parseBigInt(c,16):parseBigInt(c.substring(2),16)).intValue()}
-function _asnhex_getStartPosOfV_AtObj(a,b){var c=_asnhex_getByteLengthOfL_AtObj(a,b);return 0>c?c:b+2*(c+1)}function _asnhex_getHexOfV_AtObj(a,b){var c=_asnhex_getStartPosOfV_AtObj(a,b),d=_asnhex_getIntOfL_AtObj(a,b);return a.substring(c,c+2*d)}function _asnhex_getHexOfTLV_AtObj(a,b){var c=a.substr(b,2),d=_asnhex_getHexOfL_AtObj(a,b),e=_asnhex_getHexOfV_AtObj(a,b);return c+d+e}
-function _asnhex_getPosOfNextSibling_AtObj(a,b){var c=_asnhex_getStartPosOfV_AtObj(a,b),d=_asnhex_getIntOfL_AtObj(a,b);return c+2*d}function _asnhex_getPosArrayOfChildren_AtObj(a,b){var c=[],d=_asnhex_getStartPosOfV_AtObj(a,b);c.push(d);for(var e=_asnhex_getIntOfL_AtObj(a,b),f=d,g=0;;){f=_asnhex_getPosOfNextSibling_AtObj(a,f);if(null==f||f-d>=2*e)break;if(200<=g)break;c.push(f);g++}return c}function _asnhex_getNthChildIndex_AtObj(a,b,c){return _asnhex_getPosArrayOfChildren_AtObj(a,b)[c]}
-function _asnhex_getDecendantIndexByNthList(a,b,c){if(0==c.length)return b;var d=c.shift(),b=_asnhex_getPosArrayOfChildren_AtObj(a,b);return _asnhex_getDecendantIndexByNthList(a,b[d],c)}function _asnhex_getDecendantHexTLVByNthList(a,b,c){b=_asnhex_getDecendantIndexByNthList(a,b,c);return _asnhex_getHexOfTLV_AtObj(a,b)}function _asnhex_getDecendantHexVByNthList(a,b,c){b=_asnhex_getDecendantIndexByNthList(a,b,c);return _asnhex_getHexOfV_AtObj(a,b)}function ASN1HEX(){return ASN1HEX}
-ASN1HEX.getByteLengthOfL_AtObj=_asnhex_getByteLengthOfL_AtObj;ASN1HEX.getHexOfL_AtObj=_asnhex_getHexOfL_AtObj;ASN1HEX.getIntOfL_AtObj=_asnhex_getIntOfL_AtObj;ASN1HEX.getStartPosOfV_AtObj=_asnhex_getStartPosOfV_AtObj;ASN1HEX.getHexOfV_AtObj=_asnhex_getHexOfV_AtObj;ASN1HEX.getHexOfTLV_AtObj=_asnhex_getHexOfTLV_AtObj;ASN1HEX.getPosOfNextSibling_AtObj=_asnhex_getPosOfNextSibling_AtObj;ASN1HEX.getPosArrayOfChildren_AtObj=_asnhex_getPosArrayOfChildren_AtObj;ASN1HEX.getNthChildIndex_AtObj=_asnhex_getNthChildIndex_AtObj;
-ASN1HEX.getDecendantIndexByNthList=_asnhex_getDecendantIndexByNthList;ASN1HEX.getDecendantHexVByNthList=_asnhex_getDecendantHexVByNthList;ASN1HEX.getDecendantHexTLVByNthList=_asnhex_getDecendantHexTLVByNthList;function _x509_pemToBase64(a){a=a.replace("-----BEGIN CERTIFICATE-----","");a=a.replace("-----END CERTIFICATE-----","");return a=a.replace(/[ \n]+/g,"")}function _x509_pemToHex(a){a=_x509_pemToBase64(a);return b64tohex(a)}
-function _x509_getHexTbsCertificateFromCert(a){return ASN1HEX.getStartPosOfV_AtObj(a,0)}function _x509_getSubjectPublicKeyInfoPosFromCertHex(a){var b=ASN1HEX.getStartPosOfV_AtObj(a,0),b=ASN1HEX.getPosArrayOfChildren_AtObj(a,b);return 1>b.length?-1:"a003020102"==a.substring(b[0],b[0]+10)?6>b.length?-1:b[6]:5>b.length?-1:b[5]}
-function _x509_getSubjectPublicKeyPosFromCertHex(a,b){null==b&&(b=_x509_getSubjectPublicKeyInfoPosFromCertHex(a));if(-1==b)return-1;var c=ASN1HEX.getPosArrayOfChildren_AtObj(a,b);if(2!=c.length)return-1;c=c[1];if("03"!=a.substring(c,c+2))return-1;c=ASN1HEX.getStartPosOfV_AtObj(a,c);return"00"!=a.substring(c,c+2)?-1:c+2}
-function _x509_getPublicKeyHexArrayFromCertHex(a,b){null==b&&(b=_x509_getSubjectPublicKeyPosFromCertHex(a));var c=ASN1HEX.getPosArrayOfChildren_AtObj(a,b);4<LOG&&(console.log("a is now"),console.log(c));if(2>c.length)return[];var d=ASN1HEX.getHexOfV_AtObj(a,c[0]),c=ASN1HEX.getHexOfV_AtObj(a,c[1]);return null!=d&&null!=c?[d,c]:[]}function _x509_getPublicKeyHexArrayFromCertPEM(a){a=_x509_pemToHex(a);return _x509_getPublicKeyHexArrayFromCertHex(a)}
-function _x509_getSerialNumberHex(){return ASN1HEX.getDecendantHexVByNthList(this.hex,0,[0,1])}function _x509_getIssuerHex(){return ASN1HEX.getDecendantHexTLVByNthList(this.hex,0,[0,3])}function _x509_getIssuerString(){return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex,0,[0,3]))}function _x509_getSubjectHex(){return ASN1HEX.getDecendantHexTLVByNthList(this.hex,0,[0,5])}function _x509_getSubjectString(){return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex,0,[0,5]))}
-function _x509_getNotBefore(){var a=ASN1HEX.getDecendantHexVByNthList(this.hex,0,[0,4,0]),a=a.replace(/(..)/g,"%$1");return a=decodeURIComponent(a)}function _x509_getNotAfter(){var a=ASN1HEX.getDecendantHexVByNthList(this.hex,0,[0,4,1]),a=a.replace(/(..)/g,"%$1");return a=decodeURIComponent(a)}_x509_DN_ATTRHEX={"0603550406":"C","060355040a":"O","060355040b":"OU","0603550403":"CN","0603550405":"SN","0603550408":"ST","0603550407":"L"};
-function _x509_hex2dn(a){for(var b="",c=ASN1HEX.getPosArrayOfChildren_AtObj(a,0),d=0;d<c.length;d++)var e=ASN1HEX.getHexOfTLV_AtObj(a,c[d]),b=b+"/"+_x509_hex2rdn(e);return b}function _x509_hex2rdn(a){var b=ASN1HEX.getDecendantHexTLVByNthList(a,0,[0,0]),c=ASN1HEX.getDecendantHexVByNthList(a,0,[0,1]),a="";try{a=_x509_DN_ATTRHEX[b]}catch(d){a=b}c=c.replace(/(..)/g,"%$1");b=decodeURIComponent(c);return a+"="+b}
-function _x509_readCertPEM(a){var a=_x509_pemToHex(a),b=_x509_getPublicKeyHexArrayFromCertHex(a);4<LOG&&(console.log("HEX VALUE IS "+a),console.log("type of a"+typeof b),console.log("a VALUE IS "),console.log(b),console.log("a[0] VALUE IS "+b[0]),console.log("a[1] VALUE IS "+b[1]));var c=new RSAKey;c.setPublic(b[0],b[1]);this.subjectPublicKeyRSA=c;this.subjectPublicKeyRSA_hN=b[0];this.subjectPublicKeyRSA_hE=b[1];this.hex=a}
-function _x509_readCertHex(a){var a=a.toLowerCase(),b=_x509_getPublicKeyHexArrayFromCertHex(a),c=new RSAKey;c.setPublic(b[0],b[1]);this.subjectPublicKeyRSA=c;this.subjectPublicKeyRSA_hN=b[0];this.subjectPublicKeyRSA_hE=b[1];this.hex=a}function _x509_readCertPEMWithoutRSAInit(a){var a=_x509_pemToHex(a),b=_x509_getPublicKeyHexArrayFromCertHex(a);this.subjectPublicKeyRSA.setPublic(b[0],b[1]);this.subjectPublicKeyRSA_hN=b[0];this.subjectPublicKeyRSA_hE=b[1];this.hex=a}
-function X509(){this.hex=this.subjectPublicKeyRSA_hE=this.subjectPublicKeyRSA_hN=this.subjectPublicKeyRSA=null}X509.prototype.readCertPEM=_x509_readCertPEM;X509.prototype.readCertHex=_x509_readCertHex;X509.prototype.readCertPEMWithoutRSAInit=_x509_readCertPEMWithoutRSAInit;X509.prototype.getSerialNumberHex=_x509_getSerialNumberHex;X509.prototype.getIssuerHex=_x509_getIssuerHex;X509.prototype.getSubjectHex=_x509_getSubjectHex;X509.prototype.getIssuerString=_x509_getIssuerString;
-X509.prototype.getSubjectString=_x509_getSubjectString;X509.prototype.getNotBefore=_x509_getNotBefore;X509.prototype.getNotAfter=_x509_getNotAfter;var dbits,canary=0xdeadbeefcafe,j_lm=15715070==(canary&16777215);function BigInteger(a,b,c){null!=a&&("number"==typeof a?this.fromNumber(a,b,c):null==b&&"string"!=typeof a?this.fromString(a,256):this.fromString(a,b))}function nbi(){return new BigInteger(null)}
-function am1(a,b,c,d,e,f){for(;0<=--f;){var g=b*this[a++]+c[d]+e,e=Math.floor(g/67108864);c[d++]=g&67108863}return e}function am2(a,b,c,d,e,f){for(var g=b&32767,b=b>>15;0<=--f;){var h=this[a]&32767,i=this[a++]>>15,k=b*h+i*g,h=g*h+((k&32767)<<15)+c[d]+(e&1073741823),e=(h>>>30)+(k>>>15)+b*i+(e>>>30);c[d++]=h&1073741823}return e}
-function am3(a,b,c,d,e,f){for(var g=b&16383,b=b>>14;0<=--f;){var h=this[a]&16383,i=this[a++]>>14,k=b*h+i*g,h=g*h+((k&16383)<<14)+c[d]+e,e=(h>>28)+(k>>14)+b*i;c[d++]=h&268435455}return e}j_lm&&"Microsoft Internet Explorer"==navigator.appName?(BigInteger.prototype.am=am2,dbits=30):j_lm&&"Netscape"!=navigator.appName?(BigInteger.prototype.am=am1,dbits=26):(BigInteger.prototype.am=am3,dbits=28);BigInteger.prototype.DB=dbits;BigInteger.prototype.DM=(1<<dbits)-1;BigInteger.prototype.DV=1<<dbits;
-var BI_FP=52;BigInteger.prototype.FV=Math.pow(2,BI_FP);BigInteger.prototype.F1=BI_FP-dbits;BigInteger.prototype.F2=2*dbits-BI_FP;var BI_RM="0123456789abcdefghijklmnopqrstuvwxyz",BI_RC=[],rr,vv;rr=48;for(vv=0;9>=vv;++vv)BI_RC[rr++]=vv;rr=97;for(vv=10;36>vv;++vv)BI_RC[rr++]=vv;rr=65;for(vv=10;36>vv;++vv)BI_RC[rr++]=vv;function int2char(a){return BI_RM.charAt(a)}function intAt(a,b){var c=BI_RC[a.charCodeAt(b)];return null==c?-1:c}
-function bnpCopyTo(a){for(var b=this.t-1;0<=b;--b)a[b]=this[b];a.t=this.t;a.s=this.s}function bnpFromInt(a){this.t=1;this.s=0>a?-1:0;0<a?this[0]=a:-1>a?this[0]=a+DV:this.t=0}function nbv(a){var b=nbi();b.fromInt(a);return b}
-function bnpFromString(a,b){var c;if(16==b)c=4;else if(8==b)c=3;else if(256==b)c=8;else if(2==b)c=1;else if(32==b)c=5;else if(4==b)c=2;else{this.fromRadix(a,b);return}this.s=this.t=0;for(var d=a.length,e=!1,f=0;0<=--d;){var g=8==c?a[d]&255:intAt(a,d);0>g?"-"==a.charAt(d)&&(e=!0):(e=!1,0==f?this[this.t++]=g:f+c>this.DB?(this[this.t-1]|=(g&(1<<this.DB-f)-1)<<f,this[this.t++]=g>>this.DB-f):this[this.t-1]|=g<<f,f+=c,f>=this.DB&&(f-=this.DB))}8==c&&0!=(a[0]&128)&&(this.s=-1,0<f&&(this[this.t-1]|=(1<<this.DB-
-f)-1<<f));this.clamp();e&&BigInteger.ZERO.subTo(this,this)}function bnpClamp(){for(var a=this.s&this.DM;0<this.t&&this[this.t-1]==a;)--this.t}
-function bnToString(a){if(0>this.s)return"-"+this.negate().toString(a);if(16==a)a=4;else if(8==a)a=3;else if(2==a)a=1;else if(32==a)a=5;else if(4==a)a=2;else return this.toRadix(a);var b=(1<<a)-1,c,d=!1,e="",f=this.t,g=this.DB-f*this.DB%a;if(0<f--){if(g<this.DB&&0<(c=this[f]>>g))d=!0,e=int2char(c);for(;0<=f;)g<a?(c=(this[f]&(1<<g)-1)<<a-g,c|=this[--f]>>(g+=this.DB-a)):(c=this[f]>>(g-=a)&b,0>=g&&(g+=this.DB,--f)),0<c&&(d=!0),d&&(e+=int2char(c))}return d?e:"0"}
-function bnNegate(){var a=nbi();BigInteger.ZERO.subTo(this,a);return a}function bnAbs(){return 0>this.s?this.negate():this}function bnCompareTo(a){var b=this.s-a.s;if(0!=b)return b;var c=this.t,b=c-a.t;if(0!=b)return b;for(;0<=--c;)if(0!=(b=this[c]-a[c]))return b;return 0}function nbits(a){var b=1,c;if(0!=(c=a>>>16))a=c,b+=16;if(0!=(c=a>>8))a=c,b+=8;if(0!=(c=a>>4))a=c,b+=4;if(0!=(c=a>>2))a=c,b+=2;0!=a>>1&&(b+=1);return b}
-function bnBitLength(){return 0>=this.t?0:this.DB*(this.t-1)+nbits(this[this.t-1]^this.s&this.DM)}function bnpDLShiftTo(a,b){var c;for(c=this.t-1;0<=c;--c)b[c+a]=this[c];for(c=a-1;0<=c;--c)b[c]=0;b.t=this.t+a;b.s=this.s}function bnpDRShiftTo(a,b){for(var c=a;c<this.t;++c)b[c-a]=this[c];b.t=Math.max(this.t-a,0);b.s=this.s}
-function bnpLShiftTo(a,b){var c=a%this.DB,d=this.DB-c,e=(1<<d)-1,f=Math.floor(a/this.DB),g=this.s<<c&this.DM,h;for(h=this.t-1;0<=h;--h)b[h+f+1]=this[h]>>d|g,g=(this[h]&e)<<c;for(h=f-1;0<=h;--h)b[h]=0;b[f]=g;b.t=this.t+f+1;b.s=this.s;b.clamp()}
-function bnpRShiftTo(a,b){b.s=this.s;var c=Math.floor(a/this.DB);if(c>=this.t)b.t=0;else{var d=a%this.DB,e=this.DB-d,f=(1<<d)-1;b[0]=this[c]>>d;for(var g=c+1;g<this.t;++g)b[g-c-1]|=(this[g]&f)<<e,b[g-c]=this[g]>>d;0<d&&(b[this.t-c-1]|=(this.s&f)<<e);b.t=this.t-c;b.clamp()}}
-function bnpSubTo(a,b){for(var c=0,d=0,e=Math.min(a.t,this.t);c<e;)d+=this[c]-a[c],b[c++]=d&this.DM,d>>=this.DB;if(a.t<this.t){for(d-=a.s;c<this.t;)d+=this[c],b[c++]=d&this.DM,d>>=this.DB;d+=this.s}else{for(d+=this.s;c<a.t;)d-=a[c],b[c++]=d&this.DM,d>>=this.DB;d-=a.s}b.s=0>d?-1:0;-1>d?b[c++]=this.DV+d:0<d&&(b[c++]=d);b.t=c;b.clamp()}
-function bnpMultiplyTo(a,b){var c=this.abs(),d=a.abs(),e=c.t;for(b.t=e+d.t;0<=--e;)b[e]=0;for(e=0;e<d.t;++e)b[e+c.t]=c.am(0,d[e],b,e,0,c.t);b.s=0;b.clamp();this.s!=a.s&&BigInteger.ZERO.subTo(b,b)}function bnpSquareTo(a){for(var b=this.abs(),c=a.t=2*b.t;0<=--c;)a[c]=0;for(c=0;c<b.t-1;++c){var d=b.am(c,b[c],a,2*c,0,1);if((a[c+b.t]+=b.am(c+1,2*b[c],a,2*c+1,d,b.t-c-1))>=b.DV)a[c+b.t]-=b.DV,a[c+b.t+1]=1}0<a.t&&(a[a.t-1]+=b.am(c,b[c],a,2*c,0,1));a.s=0;a.clamp()}
-function bnpDivRemTo(a,b,c){var d=a.abs();if(!(0>=d.t)){var e=this.abs();if(e.t<d.t)null!=b&&b.fromInt(0),null!=c&&this.copyTo(c);else{null==c&&(c=nbi());var f=nbi(),g=this.s,a=a.s,h=this.DB-nbits(d[d.t-1]);0<h?(d.lShiftTo(h,f),e.lShiftTo(h,c)):(d.copyTo(f),e.copyTo(c));d=f.t;e=f[d-1];if(0!=e){var i=e*(1<<this.F1)+(1<d?f[d-2]>>this.F2:0),k=this.FV/i,i=(1<<this.F1)/i,m=1<<this.F2,l=c.t,n=l-d,j=null==b?nbi():b;f.dlShiftTo(n,j);0<=c.compareTo(j)&&(c[c.t++]=1,c.subTo(j,c));BigInteger.ONE.dlShiftTo(d,
-j);for(j.subTo(f,f);f.t<d;)f[f.t++]=0;for(;0<=--n;){var p=c[--l]==e?this.DM:Math.floor(c[l]*k+(c[l-1]+m)*i);if((c[l]+=f.am(0,p,c,n,0,d))<p){f.dlShiftTo(n,j);for(c.subTo(j,c);c[l]<--p;)c.subTo(j,c)}}null!=b&&(c.drShiftTo(d,b),g!=a&&BigInteger.ZERO.subTo(b,b));c.t=d;c.clamp();0<h&&c.rShiftTo(h,c);0>g&&BigInteger.ZERO.subTo(c,c)}}}}function bnMod(a){var b=nbi();this.abs().divRemTo(a,null,b);0>this.s&&0<b.compareTo(BigInteger.ZERO)&&a.subTo(b,b);return b}function Classic(a){this.m=a}
-function cConvert(a){return 0>a.s||0<=a.compareTo(this.m)?a.mod(this.m):a}function cRevert(a){return a}function cReduce(a){a.divRemTo(this.m,null,a)}function cMulTo(a,b,c){a.multiplyTo(b,c);this.reduce(c)}function cSqrTo(a,b){a.squareTo(b);this.reduce(b)}Classic.prototype.convert=cConvert;Classic.prototype.revert=cRevert;Classic.prototype.reduce=cReduce;Classic.prototype.mulTo=cMulTo;Classic.prototype.sqrTo=cSqrTo;
-function bnpInvDigit(){if(1>this.t)return 0;var a=this[0];if(0==(a&1))return 0;var b=a&3,b=b*(2-(a&15)*b)&15,b=b*(2-(a&255)*b)&255,b=b*(2-((a&65535)*b&65535))&65535,b=b*(2-a*b%this.DV)%this.DV;return 0<b?this.DV-b:-b}function Montgomery(a){this.m=a;this.mp=a.invDigit();this.mpl=this.mp&32767;this.mph=this.mp>>15;this.um=(1<<a.DB-15)-1;this.mt2=2*a.t}
-function montConvert(a){var b=nbi();a.abs().dlShiftTo(this.m.t,b);b.divRemTo(this.m,null,b);0>a.s&&0<b.compareTo(BigInteger.ZERO)&&this.m.subTo(b,b);return b}function montRevert(a){var b=nbi();a.copyTo(b);this.reduce(b);return b}
-function montReduce(a){for(;a.t<=this.mt2;)a[a.t++]=0;for(var b=0;b<this.m.t;++b){var c=a[b]&32767,d=c*this.mpl+((c*this.mph+(a[b]>>15)*this.mpl&this.um)<<15)&a.DM,c=b+this.m.t;for(a[c]+=this.m.am(0,d,a,b,0,this.m.t);a[c]>=a.DV;)a[c]-=a.DV,a[++c]++}a.clamp();a.drShiftTo(this.m.t,a);0<=a.compareTo(this.m)&&a.subTo(this.m,a)}function montSqrTo(a,b){a.squareTo(b);this.reduce(b)}function montMulTo(a,b,c){a.multiplyTo(b,c);this.reduce(c)}Montgomery.prototype.convert=montConvert;
-Montgomery.prototype.revert=montRevert;Montgomery.prototype.reduce=montReduce;Montgomery.prototype.mulTo=montMulTo;Montgomery.prototype.sqrTo=montSqrTo;function bnpIsEven(){return 0==(0<this.t?this[0]&1:this.s)}function bnpExp(a,b){if(4294967295<a||1>a)return BigInteger.ONE;var c=nbi(),d=nbi(),e=b.convert(this),f=nbits(a)-1;for(e.copyTo(c);0<=--f;)if(b.sqrTo(c,d),0<(a&1<<f))b.mulTo(d,e,c);else var g=c,c=d,d=g;return b.revert(c)}
-function bnModPowInt(a,b){var c;c=256>a||b.isEven()?new Classic(b):new Montgomery(b);return this.exp(a,c)}BigInteger.prototype.copyTo=bnpCopyTo;BigInteger.prototype.fromInt=bnpFromInt;BigInteger.prototype.fromString=bnpFromString;BigInteger.prototype.clamp=bnpClamp;BigInteger.prototype.dlShiftTo=bnpDLShiftTo;BigInteger.prototype.drShiftTo=bnpDRShiftTo;BigInteger.prototype.lShiftTo=bnpLShiftTo;BigInteger.prototype.rShiftTo=bnpRShiftTo;BigInteger.prototype.subTo=bnpSubTo;
-BigInteger.prototype.multiplyTo=bnpMultiplyTo;BigInteger.prototype.squareTo=bnpSquareTo;BigInteger.prototype.divRemTo=bnpDivRemTo;BigInteger.prototype.invDigit=bnpInvDigit;BigInteger.prototype.isEven=bnpIsEven;BigInteger.prototype.exp=bnpExp;BigInteger.prototype.toString=bnToString;BigInteger.prototype.negate=bnNegate;BigInteger.prototype.abs=bnAbs;BigInteger.prototype.compareTo=bnCompareTo;BigInteger.prototype.bitLength=bnBitLength;BigInteger.prototype.mod=bnMod;BigInteger.prototype.modPowInt=bnModPowInt;
-BigInteger.ZERO=nbv(0);BigInteger.ONE=nbv(1);function bnClone(){var a=nbi();this.copyTo(a);return a}function bnIntValue(){if(0>this.s){if(1==this.t)return this[0]-this.DV;if(0==this.t)return-1}else{if(1==this.t)return this[0];if(0==this.t)return 0}return(this[1]&(1<<32-this.DB)-1)<<this.DB|this[0]}function bnByteValue(){return 0==this.t?this.s:this[0]<<24>>24}function bnShortValue(){return 0==this.t?this.s:this[0]<<16>>16}function bnpChunkSize(a){return Math.floor(Math.LN2*this.DB/Math.log(a))}
-function bnSigNum(){return 0>this.s?-1:0>=this.t||1==this.t&&0>=this[0]?0:1}function bnpToRadix(a){null==a&&(a=10);if(0==this.signum()||2>a||36<a)return"0";var b=this.chunkSize(a),b=Math.pow(a,b),c=nbv(b),d=nbi(),e=nbi(),f="";for(this.divRemTo(c,d,e);0<d.signum();)f=(b+e.intValue()).toString(a).substr(1)+f,d.divRemTo(c,d,e);return e.intValue().toString(a)+f}
-function bnpFromRadix(a,b){this.fromInt(0);null==b&&(b=10);for(var c=this.chunkSize(b),d=Math.pow(b,c),e=!1,f=0,g=0,h=0;h<a.length;++h){var i=intAt(a,h);0>i?"-"==a.charAt(h)&&0==this.signum()&&(e=!0):(g=b*g+i,++f>=c&&(this.dMultiply(d),this.dAddOffset(g,0),g=f=0))}0<f&&(this.dMultiply(Math.pow(b,f)),this.dAddOffset(g,0));e&&BigInteger.ZERO.subTo(this,this)}
-function bnpFromNumber(a,b,c){if("number"==typeof b)if(2>a)this.fromInt(1);else{this.fromNumber(a,c);this.testBit(a-1)||this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this);for(this.isEven()&&this.dAddOffset(1,0);!this.isProbablePrime(b);)this.dAddOffset(2,0),this.bitLength()>a&&this.subTo(BigInteger.ONE.shiftLeft(a-1),this)}else{var c=[],d=a&7;c.length=(a>>3)+1;b.nextBytes(c);c[0]=0<d?c[0]&(1<<d)-1:0;this.fromString(c,256)}}
-function bnToByteArray(){var a=this.t,b=[];b[0]=this.s;var c=this.DB-a*this.DB%8,d,e=0;if(0<a--){if(c<this.DB&&(d=this[a]>>c)!=(this.s&this.DM)>>c)b[e++]=d|this.s<<this.DB-c;for(;0<=a;)if(8>c?(d=(this[a]&(1<<c)-1)<<8-c,d|=this[--a]>>(c+=this.DB-8)):(d=this[a]>>(c-=8)&255,0>=c&&(c+=this.DB,--a)),0!=(d&128)&&(d|=-256),0==e&&(this.s&128)!=(d&128)&&++e,0<e||d!=this.s)b[e++]=d}return b}function bnEquals(a){return 0==this.compareTo(a)}function bnMin(a){return 0>this.compareTo(a)?this:a}
-function bnMax(a){return 0<this.compareTo(a)?this:a}function bnpBitwiseTo(a,b,c){var d,e,f=Math.min(a.t,this.t);for(d=0;d<f;++d)c[d]=b(this[d],a[d]);if(a.t<this.t){e=a.s&this.DM;for(d=f;d<this.t;++d)c[d]=b(this[d],e);c.t=this.t}else{e=this.s&this.DM;for(d=f;d<a.t;++d)c[d]=b(e,a[d]);c.t=a.t}c.s=b(this.s,a.s);c.clamp()}function op_and(a,b){return a&b}function bnAnd(a){var b=nbi();this.bitwiseTo(a,op_and,b);return b}function op_or(a,b){return a|b}
-function bnOr(a){var b=nbi();this.bitwiseTo(a,op_or,b);return b}function op_xor(a,b){return a^b}function bnXor(a){var b=nbi();this.bitwiseTo(a,op_xor,b);return b}function op_andnot(a,b){return a&~b}function bnAndNot(a){var b=nbi();this.bitwiseTo(a,op_andnot,b);return b}function bnNot(){for(var a=nbi(),b=0;b<this.t;++b)a[b]=this.DM&~this[b];a.t=this.t;a.s=~this.s;return a}function bnShiftLeft(a){var b=nbi();0>a?this.rShiftTo(-a,b):this.lShiftTo(a,b);return b}
-function bnShiftRight(a){var b=nbi();0>a?this.lShiftTo(-a,b):this.rShiftTo(a,b);return b}function lbit(a){if(0==a)return-1;var b=0;0==(a&65535)&&(a>>=16,b+=16);0==(a&255)&&(a>>=8,b+=8);0==(a&15)&&(a>>=4,b+=4);0==(a&3)&&(a>>=2,b+=2);0==(a&1)&&++b;return b}function bnGetLowestSetBit(){for(var a=0;a<this.t;++a)if(0!=this[a])return a*this.DB+lbit(this[a]);return 0>this.s?this.t*this.DB:-1}function cbit(a){for(var b=0;0!=a;)a&=a-1,++b;return b}
-function bnBitCount(){for(var a=0,b=this.s&this.DM,c=0;c<this.t;++c)a+=cbit(this[c]^b);return a}function bnTestBit(a){var b=Math.floor(a/this.DB);return b>=this.t?0!=this.s:0!=(this[b]&1<<a%this.DB)}function bnpChangeBit(a,b){var c=BigInteger.ONE.shiftLeft(a);this.bitwiseTo(c,b,c);return c}function bnSetBit(a){return this.changeBit(a,op_or)}function bnClearBit(a){return this.changeBit(a,op_andnot)}function bnFlipBit(a){return this.changeBit(a,op_xor)}
-function bnpAddTo(a,b){for(var c=0,d=0,e=Math.min(a.t,this.t);c<e;)d+=this[c]+a[c],b[c++]=d&this.DM,d>>=this.DB;if(a.t<this.t){for(d+=a.s;c<this.t;)d+=this[c],b[c++]=d&this.DM,d>>=this.DB;d+=this.s}else{for(d+=this.s;c<a.t;)d+=a[c],b[c++]=d&this.DM,d>>=this.DB;d+=a.s}b.s=0>d?-1:0;0<d?b[c++]=d:-1>d&&(b[c++]=this.DV+d);b.t=c;b.clamp()}function bnAdd(a){var b=nbi();this.addTo(a,b);return b}function bnSubtract(a){var b=nbi();this.subTo(a,b);return b}
-function bnMultiply(a){var b=nbi();this.multiplyTo(a,b);return b}function bnDivide(a){var b=nbi();this.divRemTo(a,b,null);return b}function bnRemainder(a){var b=nbi();this.divRemTo(a,null,b);return b}function bnDivideAndRemainder(a){var b=nbi(),c=nbi();this.divRemTo(a,b,c);return[b,c]}function bnpDMultiply(a){this[this.t]=this.am(0,a-1,this,0,0,this.t);++this.t;this.clamp()}
-function bnpDAddOffset(a,b){if(0!=a){for(;this.t<=b;)this[this.t++]=0;for(this[b]+=a;this[b]>=this.DV;)this[b]-=this.DV,++b>=this.t&&(this[this.t++]=0),++this[b]}}function NullExp(){}function nNop(a){return a}function nMulTo(a,b,c){a.multiplyTo(b,c)}function nSqrTo(a,b){a.squareTo(b)}NullExp.prototype.convert=nNop;NullExp.prototype.revert=nNop;NullExp.prototype.mulTo=nMulTo;NullExp.prototype.sqrTo=nSqrTo;function bnPow(a){return this.exp(a,new NullExp)}
-function bnpMultiplyLowerTo(a,b,c){var d=Math.min(this.t+a.t,b);c.s=0;for(c.t=d;0<d;)c[--d]=0;var e;for(e=c.t-this.t;d<e;++d)c[d+this.t]=this.am(0,a[d],c,d,0,this.t);for(e=Math.min(a.t,b);d<e;++d)this.am(0,a[d],c,d,0,b-d);c.clamp()}function bnpMultiplyUpperTo(a,b,c){--b;var d=c.t=this.t+a.t-b;for(c.s=0;0<=--d;)c[d]=0;for(d=Math.max(b-this.t,0);d<a.t;++d)c[this.t+d-b]=this.am(b-d,a[d],c,0,0,this.t+d-b);c.clamp();c.drShiftTo(1,c)}
-function Barrett(a){this.r2=nbi();this.q3=nbi();BigInteger.ONE.dlShiftTo(2*a.t,this.r2);this.mu=this.r2.divide(a);this.m=a}function barrettConvert(a){if(0>a.s||a.t>2*this.m.t)return a.mod(this.m);if(0>a.compareTo(this.m))return a;var b=nbi();a.copyTo(b);this.reduce(b);return b}function barrettRevert(a){return a}
-function barrettReduce(a){a.drShiftTo(this.m.t-1,this.r2);a.t>this.m.t+1&&(a.t=this.m.t+1,a.clamp());this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);for(this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);0>a.compareTo(this.r2);)a.dAddOffset(1,this.m.t+1);for(a.subTo(this.r2,a);0<=a.compareTo(this.m);)a.subTo(this.m,a)}function barrettSqrTo(a,b){a.squareTo(b);this.reduce(b)}function barrettMulTo(a,b,c){a.multiplyTo(b,c);this.reduce(c)}Barrett.prototype.convert=barrettConvert;
-Barrett.prototype.revert=barrettRevert;Barrett.prototype.reduce=barrettReduce;Barrett.prototype.mulTo=barrettMulTo;Barrett.prototype.sqrTo=barrettSqrTo;
-function bnModPow(a,b){var c=a.bitLength(),d,e=nbv(1),f;if(0>=c)return e;d=18>c?1:48>c?3:144>c?4:768>c?5:6;f=8>c?new Classic(b):b.isEven()?new Barrett(b):new Montgomery(b);var g=[],h=3,i=d-1,k=(1<<d)-1;g[1]=f.convert(this);if(1<d){c=nbi();for(f.sqrTo(g[1],c);h<=k;)g[h]=nbi(),f.mulTo(c,g[h-2],g[h]),h+=2}for(var m=a.t-1,l,n=!0,j=nbi(),c=nbits(a[m])-1;0<=m;){c>=i?l=a[m]>>c-i&k:(l=(a[m]&(1<<c+1)-1)<<i-c,0<m&&(l|=a[m-1]>>this.DB+c-i));for(h=d;0==(l&1);)l>>=1,--h;if(0>(c-=h))c+=this.DB,--m;if(n)g[l].copyTo(e),
-n=!1;else{for(;1<h;)f.sqrTo(e,j),f.sqrTo(j,e),h-=2;0<h?f.sqrTo(e,j):(h=e,e=j,j=h);f.mulTo(j,g[l],e)}for(;0<=m&&0==(a[m]&1<<c);)f.sqrTo(e,j),h=e,e=j,j=h,0>--c&&(c=this.DB-1,--m)}return f.revert(e)}
-function bnGCD(a){var b=0>this.s?this.negate():this.clone(),a=0>a.s?a.negate():a.clone();if(0>b.compareTo(a))var c=b,b=a,a=c;var c=b.getLowestSetBit(),d=a.getLowestSetBit();if(0>d)return b;c<d&&(d=c);0<d&&(b.rShiftTo(d,b),a.rShiftTo(d,a));for(;0<b.signum();)0<(c=b.getLowestSetBit())&&b.rShiftTo(c,b),0<(c=a.getLowestSetBit())&&a.rShiftTo(c,a),0<=b.compareTo(a)?(b.subTo(a,b),b.rShiftTo(1,b)):(a.subTo(b,a),a.rShiftTo(1,a));0<d&&a.lShiftTo(d,a);return a}
-function bnpModInt(a){if(0>=a)return 0;var b=this.DV%a,c=0>this.s?a-1:0;if(0<this.t)if(0==b)c=this[0]%a;else for(var d=this.t-1;0<=d;--d)c=(b*c+this[d])%a;return c}
-function bnModInverse(a){var b=a.isEven();if(this.isEven()&&b||0==a.signum())return BigInteger.ZERO;for(var c=a.clone(),d=this.clone(),e=nbv(1),f=nbv(0),g=nbv(0),h=nbv(1);0!=c.signum();){for(;c.isEven();){c.rShiftTo(1,c);if(b){if(!e.isEven()||!f.isEven())e.addTo(this,e),f.subTo(a,f);e.rShiftTo(1,e)}else f.isEven()||f.subTo(a,f);f.rShiftTo(1,f)}for(;d.isEven();){d.rShiftTo(1,d);if(b){if(!g.isEven()||!h.isEven())g.addTo(this,g),h.subTo(a,h);g.rShiftTo(1,g)}else h.isEven()||h.subTo(a,h);h.rShiftTo(1,
-h)}0<=c.compareTo(d)?(c.subTo(d,c),b&&e.subTo(g,e),f.subTo(h,f)):(d.subTo(c,d),b&&g.subTo(e,g),h.subTo(f,h))}if(0!=d.compareTo(BigInteger.ONE))return BigInteger.ZERO;if(0<=h.compareTo(a))return h.subtract(a);if(0>h.signum())h.addTo(a,h);else return h;return 0>h.signum()?h.add(a):h}
-var lowprimes=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509],lplim=67108864/lowprimes[lowprimes.length-1];
-function bnIsProbablePrime(a){var b,c=this.abs();if(1==c.t&&c[0]<=lowprimes[lowprimes.length-1]){for(b=0;b<lowprimes.length;++b)if(c[0]==lowprimes[b])return!0;return!1}if(c.isEven())return!1;for(b=1;b<lowprimes.length;){for(var d=lowprimes[b],e=b+1;e<lowprimes.length&&d<lplim;)d*=lowprimes[e++];for(d=c.modInt(d);b<e;)if(0==d%lowprimes[b++])return!1}return c.millerRabin(a)}
-function bnpMillerRabin(a){var b=this.subtract(BigInteger.ONE),c=b.getLowestSetBit();if(0>=c)return!1;var d=b.shiftRight(c),a=a+1>>1;a>lowprimes.length&&(a=lowprimes.length);for(var e=nbi(),f=0;f<a;++f){e.fromInt(lowprimes[f]);var g=e.modPow(d,this);if(0!=g.compareTo(BigInteger.ONE)&&0!=g.compareTo(b)){for(var h=1;h++<c&&0!=g.compareTo(b);)if(g=g.modPowInt(2,this),0==g.compareTo(BigInteger.ONE))return!1;if(0!=g.compareTo(b))return!1}}return!0}BigInteger.prototype.chunkSize=bnpChunkSize;
-BigInteger.prototype.toRadix=bnpToRadix;BigInteger.prototype.fromRadix=bnpFromRadix;BigInteger.prototype.fromNumber=bnpFromNumber;BigInteger.prototype.bitwiseTo=bnpBitwiseTo;BigInteger.prototype.changeBit=bnpChangeBit;BigInteger.prototype.addTo=bnpAddTo;BigInteger.prototype.dMultiply=bnpDMultiply;BigInteger.prototype.dAddOffset=bnpDAddOffset;BigInteger.prototype.multiplyLowerTo=bnpMultiplyLowerTo;BigInteger.prototype.multiplyUpperTo=bnpMultiplyUpperTo;BigInteger.prototype.modInt=bnpModInt;
-BigInteger.prototype.millerRabin=bnpMillerRabin;BigInteger.prototype.clone=bnClone;BigInteger.prototype.intValue=bnIntValue;BigInteger.prototype.byteValue=bnByteValue;BigInteger.prototype.shortValue=bnShortValue;BigInteger.prototype.signum=bnSigNum;BigInteger.prototype.toByteArray=bnToByteArray;BigInteger.prototype.equals=bnEquals;BigInteger.prototype.min=bnMin;BigInteger.prototype.max=bnMax;BigInteger.prototype.and=bnAnd;BigInteger.prototype.or=bnOr;BigInteger.prototype.xor=bnXor;
-BigInteger.prototype.andNot=bnAndNot;BigInteger.prototype.not=bnNot;BigInteger.prototype.shiftLeft=bnShiftLeft;BigInteger.prototype.shiftRight=bnShiftRight;BigInteger.prototype.getLowestSetBit=bnGetLowestSetBit;BigInteger.prototype.bitCount=bnBitCount;BigInteger.prototype.testBit=bnTestBit;BigInteger.prototype.setBit=bnSetBit;BigInteger.prototype.clearBit=bnClearBit;BigInteger.prototype.flipBit=bnFlipBit;BigInteger.prototype.add=bnAdd;BigInteger.prototype.subtract=bnSubtract;
-BigInteger.prototype.multiply=bnMultiply;BigInteger.prototype.divide=bnDivide;BigInteger.prototype.remainder=bnRemainder;BigInteger.prototype.divideAndRemainder=bnDivideAndRemainder;BigInteger.prototype.modPow=bnModPow;BigInteger.prototype.modInverse=bnModInverse;BigInteger.prototype.pow=bnPow;BigInteger.prototype.gcd=bnGCD;BigInteger.prototype.isProbablePrime=bnIsProbablePrime;
-var LOG=0,NDN=function NDN(b){if(!NDN.supported)throw Error("The necessary JavaScript support is not available on this platform.");b=b||{};this.transport=(b.getTransport||function(){return new WebSocketTransport})();this.getHostAndPort=b.getHostAndPort||this.transport.defaultGetHostAndPort;this.host=void 0!==b.host?b.host:null;this.port=b.port||9696;this.readyStatus=NDN.UNOPEN;this.verify=void 0!==b.verify?b.verify:!0;this.onopen=b.onopen||function(){3<LOG&&console.log("NDN connection established.")};
-this.onclose=b.onclose||function(){3<LOG&&console.log("NDN connection closed.")};this.ccndid=null};NDN.UNOPEN=0;NDN.OPENED=1;NDN.CLOSED=2;NDN.getSupported=function(){try{(new Uint8Array(1)).subarray(0,1)}catch(a){return console.log("NDN not available: Uint8Array not supported. "+a),!1}return!0};NDN.supported=NDN.getSupported();NDN.ccndIdFetcher=new Name("/%C1.M.S.localhost/%C1.M.SRV/ccnd/KEY");NDN.prototype.createRoute=function(a,b){this.host=a;this.port=b};NDN.KeyStore=[];
-var KeyStoreEntry=function(a,b,c){this.keyName=a;this.rsaKey=b;this.timeStamp=c};NDN.addKeyEntry=function(a){null==NDN.getKeyByName(a.keyName)&&NDN.KeyStore.push(a)};NDN.getKeyByName=function(a){for(var b=null,c=0;c<NDN.KeyStore.length;c++)if(NDN.KeyStore[c].keyName.contentName.match(a.contentName)&&(null==b||NDN.KeyStore[c].keyName.contentName.components.length>b.keyName.contentName.components.length))b=NDN.KeyStore[c];return b};NDN.PITTable=[];
-var PITEntry=function(a,b){this.interest=a;this.closure=b;this.timerID=-1};NDN.getEntryForExpressedInterest=function(a){for(var b=null,c=0;c<NDN.PITTable.length;c++)if(NDN.PITTable[c].interest.matches_name(a)&&(null==b||NDN.PITTable[c].interest.name.components.length>b.interest.name.components.length))b=NDN.PITTable[c];return b};NDN.CSTable=[];var CSEntry=function(a,b){this.name=a;this.closure=b};
-function getEntryForRegisteredPrefix(a){for(var b=0;b<NDN.CSTable.length;b++)if(null!=NDN.CSTable[b].name.match(a))return NDN.CSTable[b];return null}NDN.makeShuffledGetHostAndPort=function(a,b){a=a.slice(0,a.length);DataUtils.shuffle(a);return function(){return 0==a.length?null:{host:a.splice(0,1)[0],port:b}}};
-NDN.prototype.expressInterest=function(a,b,c){var d=new Interest(a);null!=c?(d.minSuffixComponents=c.minSuffixComponents,d.maxSuffixComponents=c.maxSuffixComponents,d.publisherPublicKeyDigest=c.publisherPublicKeyDigest,d.exclude=c.exclude,d.childSelector=c.childSelector,d.answerOriginKind=c.answerOriginKind,d.scope=c.scope,d.interestLifetime=c.interestLifetime):d.interestLifetime=4E3;if(null==this.host||null==this.port)if(null==this.getHostAndPort)console.log("ERROR: host OR port NOT SET");else{var e=
-this;this.connectAndExecute(function(){e.reconnectAndExpressInterest(d,b)})}else this.reconnectAndExpressInterest(d,b)};NDN.prototype.reconnectAndExpressInterest=function(a,b){if(this.transport.connectedHost!=this.host||this.transport.connectedPort!=this.port){var c=this;this.transport.connect(c,function(){c.expressInterestHelper(a,b)})}else this.expressInterestHelper(a,b)};
-NDN.prototype.expressInterestHelper=function(a,b){var c=encodeToBinaryInterest(a),d=this;if(null!=b){var e=new PITEntry(a,b);NDN.PITTable.push(e);b.pitEntry=e;var f=a.interestLifetime||4E3,g=function(){1<LOG&&console.log("Interest time out: "+a.name.to_uri());var h=NDN.PITTable.indexOf(e);0<=h&&NDN.PITTable.splice(h,1);b.upcall(Closure.UPCALL_INTEREST_TIMED_OUT,new UpcallInfo(d,a,0,null))==Closure.RESULT_REEXPRESS&&(1<LOG&&console.log("Re-express interest: "+a.name.to_uri()),e.timerID=setTimeout(g,
-f),NDN.PITTable.push(e),d.transport.send(c))};e.timerID=setTimeout(g,f)}this.transport.send(c)};
-NDN.prototype.registerPrefix=function(a,b,c){var d=this,e=function(){if(null==d.ccndid){var e=new Interest(NDN.ccndIdFetcher);e.interestLifetime=4E3;3<LOG&&console.log("Expressing interest for ccndid from ccnd.");d.reconnectAndExpressInterest(e,new NDN.FetchCcndidClosure(d,a,b,c))}else d.registerPrefixHelper(a,b,c)};null==this.host||null==this.port?null==this.getHostAndPort?console.log("ERROR: host OR port NOT SET"):this.connectAndExecute(e):e()};
-NDN.FetchCcndidClosure=function(a,b,c,d){Closure.call(this);this.ndn=a;this.name=b;this.callerClosure=c;this.flag=d};
-NDN.FetchCcndidClosure.prototype.upcall=function(a,b){if(a==Closure.UPCALL_INTEREST_TIMED_OUT)return console.log("Timeout while requesting the ccndid.  Cannot registerPrefix for "+this.name.to_uri()+" ."),Closure.RESULT_OK;if(!(a==Closure.UPCALL_CONTENT||a==Closure.UPCALL_CONTENT_UNVERIFIED))return Closure.RESULT_ERR;var c=b.contentObject;!c.signedInfo||!c.signedInfo.publisher||!c.signedInfo.publisher.publisherPublicKeyDigest?console.log("ContentObject doesn't have a publisherPublicKeyDigest. Cannot set ccndid and registerPrefix for "+
-this.name.to_uri()+" ."):(3<LOG&&console.log("Got ccndid from ccnd."),this.ndn.ccndid=c.signedInfo.publisher.publisherPublicKeyDigest,3<LOG&&console.log(this.ndn.ccndid),this.ndn.registerPrefixHelper(this.name,this.callerClosure,this.flag));return Closure.RESULT_OK};
-NDN.prototype.registerPrefixHelper=function(a,b){var c=new ForwardingEntry("selfreg",a,null,null,3,2147483647),c=encodeForwardingEntry(c),d=new SignedInfo;d.setFields();c=new ContentObject(new Name,d,c,new Signature);c.sign();c=encodeToBinaryContentObject(c);c=new Name(["ccnx",this.ccndid,"selfreg",c]);c=new Interest(c);c.scope=1;3<LOG&&console.log("Send Interest registration packet.");d=new CSEntry(a.getName(),b);NDN.CSTable.push(d);this.transport.send(encodeToBinaryInterest(c))};
-NDN.prototype.onReceivedElement=function(a){3<LOG&&console.log("Complete element received. Length "+a.length+". Start decoding.");var b=new BinaryXMLDecoder(a);if(b.peekStartElement(CCNProtocolDTags.Interest))3<LOG&&console.log("Interest packet received."),a=new Interest,a.from_ccnb(b),3<LOG&&console.log(a),b=escape(a.name.getName()),3<LOG&&console.log(b),b=getEntryForRegisteredPrefix(b),null!=b&&(a=new UpcallInfo(this,a,0,null),b.closure.upcall(Closure.UPCALL_INTEREST,a)==Closure.RESULT_INTEREST_CONSUMED&&
-null!=a.contentObject&&this.transport.send(encodeToBinaryContentObject(a.contentObject)));else if(b.peekStartElement(CCNProtocolDTags.ContentObject)){if(3<LOG&&console.log("ContentObject packet received."),a=new ContentObject,a.from_ccnb(b),b=NDN.getEntryForExpressedInterest(a.name),null!=b){clearTimeout(b.timerID);var c=NDN.PITTable.indexOf(b);0<=c&&NDN.PITTable.splice(c,1);b=b.closure;if(!1==this.verify)b.upcall(Closure.UPCALL_CONTENT_UNVERIFIED,new UpcallInfo(this,null,0,a));else{var d=function(a,
-b,c,d,e){this.contentObject=a;this.closure=b;this.keyName=c;this.sigHex=d;this.witness=e;Closure.call(this)},e=this;d.prototype.upcall=function(a,b){if(a==Closure.UPCALL_INTEREST_TIMED_OUT)console.log("In KeyFetchClosure.upcall: interest time out."),console.log(this.keyName.contentName.getName());else if(a==Closure.UPCALL_CONTENT){var c=decodeSubjectPublicKeyInfo(b.contentObject.content),d=!0==c.verifyByteArray(this.contentObject.rawSignatureData,this.witness,this.sigHex)?Closure.UPCALL_CONTENT:Closure.UPCALL_CONTENT_BAD;
-this.closure.upcall(d,new UpcallInfo(e,null,0,this.contentObject));c=new KeyStoreEntry(g.keyName,c,(new Date).getTime());NDN.addKeyEntry(c)}else a==Closure.UPCALL_CONTENT_BAD&&console.log("In KeyFetchClosure.upcall: signature verification failed")};if(a.signedInfo&&a.signedInfo.locator&&a.signature){3<LOG&&console.log("Key verification...");var c=DataUtils.toHex(a.signature.signature).toLowerCase(),f=null;null!=a.signature.Witness&&(f=new Witness,f.decode(a.signature.Witness));var g=a.signedInfo.locator;
-if(g.type==KeyLocatorType.KEYNAME)if(3<LOG&&console.log("KeyLocator contains KEYNAME"),g.keyName.contentName.match(a.name))3<LOG&&console.log("Content is key itself"),d=decodeSubjectPublicKeyInfo(a.content),c=d.verifyByteArray(a.rawSignatureData,f,c),c=!0==c?Closure.UPCALL_CONTENT:Closure.UPCALL_CONTENT_BAD,b.upcall(c,new UpcallInfo(this,null,0,a));else{var h=NDN.getKeyByName(g.keyName);h?(3<LOG&&console.log("Local key cache hit"),d=h.rsaKey,c=d.verifyByteArray(a.rawSignatureData,f,c),c=!0==c?Closure.UPCALL_CONTENT:
-Closure.UPCALL_CONTENT_BAD,b.upcall(c,new UpcallInfo(this,null,0,a))):(3<LOG&&console.log("Fetch key according to keylocator"),a=new d(a,b,g.keyName,c,f),this.expressInterest(g.keyName.contentName.getPrefix(4),a))}else g.type==KeyLocatorType.KEY?(3<LOG&&console.log("Keylocator contains KEY"),d=decodeSubjectPublicKeyInfo(a.signedInfo.locator.publicKey),c=d.verifyByteArray(a.rawSignatureData,f,c),c=!0==c?Closure.UPCALL_CONTENT:Closure.UPCALL_CONTENT_BAD,b.upcall(Closure.UPCALL_CONTENT,new UpcallInfo(this,
-null,0,a))):(a=g.certificate,console.log("KeyLocator contains CERT"),console.log(a))}}}}else console.log("Incoming packet is not Interest or ContentObject. Discard now.")};
-NDN.prototype.connectAndExecute=function(a){var b=this.getHostAndPort();if(null==b)console.log("ERROR: No more hosts from getHostAndPort"),this.host=null;else if(b.host==this.host&&b.port==this.port)console.log("ERROR: The host returned by getHostAndPort is not alive: "+this.host+":"+this.port);else{this.host=b.host;this.port=b.port;0<LOG&&console.log("connectAndExecute: trying host from getHostAndPort: "+this.host);b=new Interest(new Name("/"));b.interestLifetime=4E3;var c=this,d=setTimeout(function(){0<
-LOG&&console.log("connectAndExecute: timeout waiting for host "+c.host);c.connectAndExecute(a)},3E3);this.reconnectAndExpressInterest(b,new NDN.ConnectClosure(this,a,d))}};NDN.ConnectClosure=function(a,b,c){Closure.call(this);this.ndn=a;this.onConnected=b;this.timerID=c};
-NDN.ConnectClosure.prototype.upcall=function(a){if(!(a==Closure.UPCALL_CONTENT||a==Closure.UPCALL_CONTENT_UNVERIFIED))return Closure.RESULT_ERR;clearTimeout(this.timerID);this.ndn.readyStatus=NDN.OPENED;this.ndn.onopen();0<LOG&&console.log("connectAndExecute: connected to host "+this.ndn.host);this.onConnected();return Closure.RESULT_OK};var BinaryXmlElementReader=function(a){this.elementListener=a;this.dataParts=[];this.structureDecoder=new BinaryXMLStructureDecoder};
-BinaryXmlElementReader.prototype.onReceivedData=function(a){for(;;)if(this.structureDecoder.seek(0),this.structureDecoder.findElementEnd(a)){this.dataParts.push(a.subarray(0,this.structureDecoder.offset));var b=DataUtils.concatArrays(this.dataParts);this.dataParts=[];try{this.elementListener.onReceivedElement(b)}catch(c){console.log("BinaryXmlElementReader: ignoring exception from onReceivedElement: "+c)}a=a.subarray(this.structureDecoder.offset,a.length);this.structureDecoder=new BinaryXMLStructureDecoder;
-if(0==a.length)break}else{this.dataParts.push(a);3<LOG&&console.log("Incomplete packet received. Length "+a.length+". Wait for more input.");break}};
diff --git a/js/ndnProtocol/chrome.manifest b/ndnProtocol/chrome.manifest
similarity index 100%
rename from js/ndnProtocol/chrome.manifest
rename to ndnProtocol/chrome.manifest
diff --git a/js/ndnProtocol/components/ndnProtocolService.js b/ndnProtocol/components/ndnProtocolService.js
similarity index 100%
rename from js/ndnProtocol/components/ndnProtocolService.js
rename to ndnProtocol/components/ndnProtocolService.js
diff --git a/js/ndnProtocol/content/ndnToolbar.js b/ndnProtocol/content/ndnToolbar.js
similarity index 100%
rename from js/ndnProtocol/content/ndnToolbar.js
rename to ndnProtocol/content/ndnToolbar.js
diff --git a/js/ndnProtocol/content/toolbar.xul b/ndnProtocol/content/toolbar.xul
similarity index 100%
rename from js/ndnProtocol/content/toolbar.xul
rename to ndnProtocol/content/toolbar.xul
diff --git a/js/ndnProtocol/install.rdf b/ndnProtocol/install.rdf
similarity index 100%
rename from js/ndnProtocol/install.rdf
rename to ndnProtocol/install.rdf
diff --git a/js/ndnProtocol/make-ndnProtocol.sh b/ndnProtocol/make-ndnProtocol.sh
similarity index 100%
rename from js/ndnProtocol/make-ndnProtocol.sh
rename to ndnProtocol/make-ndnProtocol.sh
diff --git a/js/ndnProtocol/modules/ContentChannel.jsm b/ndnProtocol/modules/ContentChannel.jsm
similarity index 100%
rename from js/ndnProtocol/modules/ContentChannel.jsm
rename to ndnProtocol/modules/ContentChannel.jsm
diff --git a/js/ndnProtocol/modules/NdnProtocolInfo.jsm b/ndnProtocol/modules/NdnProtocolInfo.jsm
similarity index 100%
rename from js/ndnProtocol/modules/NdnProtocolInfo.jsm
rename to ndnProtocol/modules/NdnProtocolInfo.jsm
diff --git a/js/ndnProtocol/modules/make-ndn-js.jsm.sh b/ndnProtocol/modules/make-ndn-js.jsm.sh
similarity index 100%
rename from js/ndnProtocol/modules/make-ndn-js.jsm.sh
rename to ndnProtocol/modules/make-ndn-js.jsm.sh
diff --git a/js/ndnProtocol/modules/ndn-js-header.txt b/ndnProtocol/modules/ndn-js-header.txt
similarity index 100%
rename from js/ndnProtocol/modules/ndn-js-header.txt
rename to ndnProtocol/modules/ndn-js-header.txt
diff --git a/js/ndnProtocol/modules/ndn-js.jsm b/ndnProtocol/modules/ndn-js.jsm
similarity index 100%
rename from js/ndnProtocol/modules/ndn-js.jsm
rename to ndnProtocol/modules/ndn-js.jsm
diff --git a/js/testing/test-PIT-matching.html b/tests/test-PIT-matching.html
similarity index 100%
rename from js/testing/test-PIT-matching.html
rename to tests/test-PIT-matching.html
diff --git a/js/testing/test-decode-FaceInstance.html b/tests/test-decode-FaceInstance.html
similarity index 100%
rename from js/testing/test-decode-FaceInstance.html
rename to tests/test-decode-FaceInstance.html
diff --git a/js/testing/test-decode-Interest+Forwarding+Entry.html b/tests/test-decode-Interest+Forwarding+Entry.html
similarity index 100%
rename from js/testing/test-decode-Interest+Forwarding+Entry.html
rename to tests/test-decode-Interest+Forwarding+Entry.html
diff --git a/js/testing/test-encode-decode-ContentObject.html b/tests/test-encode-decode-ContentObject.html
similarity index 100%
rename from js/testing/test-encode-decode-ContentObject.html
rename to tests/test-encode-decode-ContentObject.html
diff --git a/js/testing/test-encode-decode-Interest.html b/tests/test-encode-decode-Interest.html
similarity index 100%
rename from js/testing/test-encode-decode-Interest.html
rename to tests/test-encode-decode-Interest.html
diff --git a/js/testing/test-get-async.html b/tests/test-get-async.html
similarity index 100%
rename from js/testing/test-get-async.html
rename to tests/test-get-async.html
diff --git a/js/testing/test-image-parsing.html b/tests/test-image-parsing.html
similarity index 100%
rename from js/testing/test-image-parsing.html
rename to tests/test-image-parsing.html
diff --git a/js/testing/test-interest-matches-name.html b/tests/test-interest-matches-name.html
similarity index 100%
rename from js/testing/test-interest-matches-name.html
rename to tests/test-interest-matches-name.html
diff --git a/js/testing/test-name.html b/tests/test-name.html
similarity index 100%
rename from js/testing/test-name.html
rename to tests/test-name.html
diff --git a/js/testing/test-path.html b/tests/test-path.html
similarity index 100%
rename from js/testing/test-path.html
rename to tests/test-path.html
diff --git a/js/testing/test-publish-async.html b/tests/test-publish-async.html
similarity index 100%
rename from js/testing/test-publish-async.html
rename to tests/test-publish-async.html
diff --git a/js/testing/test-sha256.html b/tests/test-sha256.html
similarity index 100%
rename from js/testing/test-sha256.html
rename to tests/test-sha256.html
diff --git a/js/testing/test-signature-binary.html b/tests/test-signature-binary.html
similarity index 100%
rename from js/testing/test-signature-binary.html
rename to tests/test-signature-binary.html
diff --git a/js/testing/test-signature-string.html b/tests/test-signature-string.html
similarity index 100%
rename from js/testing/test-signature-string.html
rename to tests/test-signature-string.html
diff --git a/js/testing/test-throughput-http.html b/tests/test-throughput-http.html
similarity index 100%
rename from js/testing/test-throughput-http.html
rename to tests/test-throughput-http.html
diff --git a/js/testing/test-throughput-ws-pipeline.html b/tests/test-throughput-ws-pipeline.html
similarity index 100%
rename from js/testing/test-throughput-ws-pipeline.html
rename to tests/test-throughput-ws-pipeline.html
diff --git a/js/testing/test-throughput-ws.html b/tests/test-throughput-ws.html
similarity index 100%
rename from js/testing/test-throughput-ws.html
rename to tests/test-throughput-ws.html
diff --git a/js/testing/test-websocket.html b/tests/test-websocket.html
similarity index 100%
rename from js/testing/test-websocket.html
rename to tests/test-websocket.html
diff --git a/js/ndnProtocol.xpi b/tools/ndnProtocol.xpi
similarity index 100%
rename from js/ndnProtocol.xpi
rename to tools/ndnProtocol.xpi
Binary files differ
diff --git a/js/tools/ndnpublish/make-node-ndn-js.js.sh b/tools/ndnpublish/make-node-ndn-js.js.sh
similarity index 100%
rename from js/tools/ndnpublish/make-node-ndn-js.js.sh
rename to tools/ndnpublish/make-node-ndn-js.js.sh
diff --git a/js/tools/ndnpublish/node-ndn-js-footer.txt b/tools/ndnpublish/node-ndn-js-footer.txt
similarity index 100%
rename from js/tools/ndnpublish/node-ndn-js-footer.txt
rename to tools/ndnpublish/node-ndn-js-footer.txt
diff --git a/js/tools/ndnpublish/node-ndn-js-header.txt b/tools/ndnpublish/node-ndn-js-header.txt
similarity index 100%
rename from js/tools/ndnpublish/node-ndn-js-header.txt
rename to tools/ndnpublish/node-ndn-js-header.txt
diff --git a/js/tools/ndnpublish/node-ndn-js.js b/tools/ndnpublish/node-ndn-js.js
similarity index 100%
rename from js/tools/ndnpublish/node-ndn-js.js
rename to tools/ndnpublish/node-ndn-js.js
diff --git a/waf b/waf
new file mode 100755
index 0000000..7ff229c
--- /dev/null
+++ b/waf
Binary files differ
diff --git a/wscript b/wscript
new file mode 100644
index 0000000..70e00a2
--- /dev/null
+++ b/wscript
@@ -0,0 +1,189 @@
+# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+VERSION='0.1'
+APPNAME='ndnjs'
+
+YUICOMPRESSOR_URL="http://github.com/downloads/yui/yuicompressor/"
+YUICOMPRESSOR_NAME="yuicompressor-2.4.7"
+
+CLOSURE_COMPILER="http://closure-compiler.googlecode.com/files/compiler-20121212.zip"
+
+from waflib import Task, TaskGen, Utils, Logs
+import urllib, subprocess, os, shutil
+
+def options (opt):
+    js = opt.add_option_group ("ndn.js compilation options")
+
+    js.add_option('--no-js',action='store_false',default=True,dest='js',
+                  help='''Disable ndn.js compilation and installation''')
+    js.add_option('--js-dir',action='store',dest='jsdir',
+                  help='''Directory where .js files will be installed (Default: ${PREFIX}/share/ndn-js)''')
+    js.add_option('--yui',action='store_true',default=False,dest='yui',
+                  help='''Download and use yuicompressor-2.4.7 (http://yui.github.com/yuicompressor/)''')
+    js.add_option('--compiler',action='store_true',default=False,dest='compiler',
+                  help='''Download and use closure-compiler-r2388 (https://code.google.com/p/closure-compiler/)''')
+
+    ws = opt.add_option_group ("ws-proxy options")
+    ws.add_option ('--no-ws',action='store_false',default=True,dest='ws',
+                   help='''Disable ws-proxy installation''')
+
+def configure (conf):
+    if conf.options.js:
+        conf.env.JS = 1
+        if not conf.env.JSDIR:
+            if conf.options.jsdir or Utils.is_win32:
+                conf.env.JSDIR=os.path.abspath (os.path.expanduser (conf.options.jsdir))
+            else:
+                conf.env.JSDIR=Utils.subst_vars ('${PREFIX}/bin',conf.env)
+
+        if conf.options.yui:
+            conf.start_msg ("Checking for yuicompressor")
+            if os.path.exists('tools/yuicompressor.jar'):
+                conf.end_msg('tools/yuicompressor.jar')
+                conf.env.HAVE_YUI = 1
+            else:
+                conf.end_msg('not found','YELLOW')
+                url="%s%s.zip" % (YUICOMPRESSOR_URL, YUICOMPRESSOR_NAME)
+                Logs.info ("Downloading yuicompressor from %s..." % url)
+                urllib.urlretrieve (url, "build/yuicompressor.zip")
+
+                filename='%s/build/%s.jar' % (YUICOMPRESSOR_NAME,YUICOMPRESSOR_NAME)
+                subprocess.check_call (['unzip', '-qq', '-o', '-j', 'build/yuicompressor.zip',
+                                        filename, '-d', 'tools/'])
+                os.rename ("tools/%s.jar" % YUICOMPRESSOR_NAME, "tools/yuicompressor.jar")
+                conf.env.HAVE_YUI = 1
+
+        if conf.options.compiler:
+            conf.start_msg ("Checking for closure-compiler")
+            if os.path.exists('tools/compiler.jar'):
+                conf.end_msg('tools/compiler.jar')
+                conf.env.HAVE_COMPILER = 1
+            else:
+                conf.end_msg('not found','YELLOW')
+                Logs.info ("Downloading closure-compiler from %s..." % CLOSURE_COMPILER)
+                urllib.urlretrieve (CLOSURE_COMPILER, "build/closure-compiler.zip")
+
+                subprocess.check_call (['unzip', '-qq', '-o', '-j', 'build/closure-compiler.zip', 'compiler.jar', '-d', 'tools/'])
+                conf.env.HAVE_COMPILER = 1
+
+    if conf.options.ws:
+        conf.env.WS = 1
+
+def build (bld):
+    if bld.env['JS']:
+        securityLib = ["contrib/securityLib/sha256.js",
+                       "contrib/securityLib/base64.js",
+                       "contrib/securityLib/rsa.js",
+                       "contrib/securityLib/rsa2.js",
+                       "contrib/securityLib/rsapem-1.1.js",
+                       "contrib/securityLib/rsasign-1.2.js",
+                       "contrib/securityLib/asn1hex-1.1.js",
+                       "contrib/securityLib/x509-1.1.js",
+                       "contrib/securityLib/jsbn.js",
+                       "contrib/securityLib/jsbn2.js"]
+
+        ndnjs = ["js/Closure.js",
+                 "js/WebSocketTransport.js",
+                 "js/util/CCNProtocolDTags.js",
+                 "js/util/CCNTime.js",
+                 "js/util/ExponentialReExpressClosure.js",
+                 "js/Name.js",
+                 "js/ContentObject.js",
+                 "js/encoding/DateFormat.js",
+                 "js/Interest.js",
+                 "js/Key.js",
+                 "js/PublisherID.js",
+                 "js/PublisherPublicKeyDigest.js",
+                 "js/FaceInstance.js",
+                 "js/ForwardingEntry.js",
+                 "js/encoding/DynamicUint8Array.js",
+                 "js/encoding/BinaryXMLEncoder.js",
+                 "js/encoding/BinaryXMLDecoder.js",
+                 "js/encoding/BinaryXMLStructureDecoder.js",
+                 "js/encoding/DataUtils.js",
+                 "js/encoding/EncodingUtils.js",
+                 "js/security/KeyManager.js",
+                 "js/security/Witness.js"] + securityLib + ["js/NDN.js"]
+
+        ndnjs = bld (features="combine",
+                     target="ndn-js",
+                     source=ndnjs,
+                     install_path="${JSDIR}")
+
+        if bld.env['HAVE_YUI']:
+            ndnjs.yui = True
+
+        if bld.env['HAVE_COMPILER']:
+            ndnjs.compiler = True
+
+    if bld.env['WS']:
+        bld.install_as ('${BINDIR}/ccnx-wsproxy-tcp.js', 'wsproxy/wsproxy-tcp.js', chmod=Utils.O755)
+        bld.install_as ('${BINDIR}/ccnx-wsproxy-udp.js', 'wsproxy/wsproxy-udp.js', chmod=Utils.O755)
+
+@TaskGen.extension('.js')
+def js_hook(self, node):
+    node.sig=Utils.h_file (node.abspath())
+
+@TaskGen.feature('combine')
+@TaskGen.after_method('process_source')
+def apply_combine(self):
+    out = "%s.js" % self.target
+    tasks = []
+    task = self.create_task ('combine', self.source)
+    task.set_outputs (task.generator.path.find_or_declare (out))
+    tasks.append (task)
+
+    if getattr(self, 'yui', False):
+        out_yui = "%s.min.yui.js" % self.target
+        yui = self.create_task ('yuicompressor')
+        yui.combine = task
+        yui.set_outputs (yui.generator.path.find_or_declare (out_yui))
+        tasks.append (yui)
+
+    if getattr(self, 'compiler', False):
+        out_min = "%s.min.js" % self.target
+        compiler = self.create_task ('closure_compiler')
+        compiler.combine = task
+        compiler.set_outputs (compiler.generator.path.find_or_declare (out_min))
+        tasks.append (compiler)
+
+    try:
+        for task in tasks:
+            self.bld.install_files (self.install_path, task.outputs[:], env=self.env)
+    except:
+        pass
+
+class combine (Task.Task):
+    def run(self):
+        outFile = self.outputs[0]
+        self.outputs[0].write ("", "w") # make file empty
+        for inFile in self.inputs:
+            self.outputs[0].write (inFile.read (), 'a')
+
+class yuicompressor (Task.Task):
+    after="combine"
+    color='PINK'
+    def __str__(self):
+        src_str=self.combine.outputs[0].nice_path()
+        tgt_str=self.outputs[0].nice_path()
+        return'%s: %s -> %s\n'%(self.__class__.__name__.replace('_task',''),src_str,tgt_str)
+
+    def run(self):
+        return self.exec_command(['java',
+                                  '-jar', '../tools/yuicompressor.jar',
+                                  '-o', self.outputs[0].abspath(),
+                                  self.combine.outputs[0].abspath()])
+
+class closure_compiler (Task.Task):
+    after="combine"
+    color='PINK'
+    def __str__(self):
+        src_str=self.combine.outputs[0].nice_path()
+        tgt_str=self.outputs[0].nice_path()
+        return'%s: %s -> %s\n'%(self.__class__.__name__.replace('_task',''),src_str,tgt_str)
+
+    def run(self):
+        return self.exec_command(['java',
+                                  '-jar', '../tools/compiler.jar',
+                                  '--js', self.combine.outputs[0].abspath(),
+                                  '--js_output_file', self.outputs[0].abspath()])
diff --git a/wsproxy/wsproxy-tcp.js b/wsproxy/wsproxy-tcp.js
old mode 100644
new mode 100755
index fe4f816..0e700c6
--- a/wsproxy/wsproxy-tcp.js
+++ b/wsproxy/wsproxy-tcp.js
@@ -1,3 +1,5 @@
+#!/usr/bin/env node
+
 /* 
  * @author: Wentao Shang
  * See COPYING for copyright and distribution information.
diff --git a/wsproxy/wsproxy-udp.js b/wsproxy/wsproxy-udp.js
old mode 100644
new mode 100755
index b81e2bd..db63b82
--- a/wsproxy/wsproxy-udp.js
+++ b/wsproxy/wsproxy-udp.js
@@ -1,3 +1,5 @@
+#!/usr/bin/env node
+
 /* 
  * @author: Wentao Shang
  * See COPYING for copyright and distribution information.
