diff --git a/js/tools/build/ndn-js-uncomp.js b/js/tools/build/ndn-js-uncomp.js
index a8762c7..bc92e99 100644
--- a/js/tools/build/ndn-js-uncomp.js
+++ b/js/tools/build/ndn-js-uncomp.js
@@ -346,7 +346,7 @@
 		if (LOG > 3) console.log('ws.onopen: ReadyState: ' + this.readyState);
 
 		// Fetch ccndid now
-		var interest = new Interest(new Name(NDN.ccndIdFetcher));
+		var interest = new Interest(NDN.ccndIdFetcher);
 		interest.interestLifetime = 4000; // milliseconds
 		var subarray = encodeToBinaryInterest(interest);
 		
@@ -4488,559 +4488,6 @@
 }
 
 
-// ASN.1 JavaScript decoder
-// Copyright (c) 2008-2009 Lapo Luchini <lapo@lapo.it>
-
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-function Stream(enc, pos) {
-    if (enc instanceof Stream) {
-        this.enc = enc.enc;
-        this.pos = enc.pos;
-    } else {
-        this.enc = enc;
-        this.pos = pos;
-    }
-}
-Stream.prototype.get = function(pos) {
-    if (pos == undefined)
-        pos = this.pos++;
-    if (pos >= this.enc.length)
-        throw 'Requesting byte offset ' + pos + ' on a stream of length ' + this.enc.length;
-    return this.enc[pos];
-}
-Stream.prototype.hexDigits = "0123456789ABCDEF";
-Stream.prototype.hexByte = function(b) {
-    return this.hexDigits.charAt((b >> 4) & 0xF) + this.hexDigits.charAt(b & 0xF);
-}
-Stream.prototype.hexDump = function(start, end) {
-    var s = "";
-    for (var i = start; i < end; ++i) {
-        s += this.hexByte(this.get(i));
-        switch (i & 0xF) {
-        case 0x7: s += "  "; break;
-        case 0xF: s += "\n"; break;
-        default:  s += " ";
-        }
-    }
-    return s;
-}
-Stream.prototype.parseStringISO = function(start, end) {
-    var s = "";
-    for (var i = start; i < end; ++i)
-        s += String.fromCharCode(this.get(i));
-    return s;
-}
-Stream.prototype.parseStringUTF = function(start, end) {
-    var s = "", c = 0;
-    for (var i = start; i < end; ) {
-        var c = this.get(i++);
-        if (c < 128)
-            s += String.fromCharCode(c);
-        else if ((c > 191) && (c < 224))
-            s += String.fromCharCode(((c & 0x1F) << 6) | (this.get(i++) & 0x3F));
-        else
-            s += String.fromCharCode(((c & 0x0F) << 12) | ((this.get(i++) & 0x3F) << 6) | (this.get(i++) & 0x3F));
-        //TODO: this doesn't check properly 'end', some char could begin before and end after
-    }
-    return s;
-}
-Stream.prototype.reTime = /^((?:1[89]|2\d)?\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/;
-Stream.prototype.parseTime = function(start, end) {
-    var s = this.parseStringISO(start, end);
-    var m = this.reTime.exec(s);
-    if (!m)
-        return "Unrecognized time: " + s;
-    s = m[1] + "-" + m[2] + "-" + m[3] + " " + m[4];
-    if (m[5]) {
-        s += ":" + m[5];
-        if (m[6]) {
-            s += ":" + m[6];
-            if (m[7])
-                s += "." + m[7];
-        }
-    }
-    if (m[8]) {
-        s += " UTC";
-        if (m[8] != 'Z') {
-            s += m[8];
-            if (m[9])
-                s += ":" + m[9];
-        }
-    }
-    return s;
-}
-Stream.prototype.parseInteger = function(start, end) {
-    //TODO support negative numbers
-    var len = end - start;
-    if (len > 4) {
-        len <<= 3;
-        var s = this.get(start);
-        if (s == 0)
-            len -= 8;
-        else
-            while (s < 128) {
-                s <<= 1;
-                --len;
-            }
-        return "(" + len + " bit)";
-    }
-    var n = 0;
-    for (var i = start; i < end; ++i)
-        n = (n << 8) | this.get(i);
-    return n;
-}
-Stream.prototype.parseBitString = function(start, end) {
-    var unusedBit = this.get(start);
-    var lenBit = ((end - start - 1) << 3) - unusedBit;
-    var s  = "(" + lenBit + " bit)";
-    if (lenBit <= 20) {
-        var skip = unusedBit;
-        s += " ";
-        for (var i = end - 1; i > start; --i) {
-            var b = this.get(i);
-            for (var j = skip; j < 8; ++j)
-                s += (b >> j) & 1 ? "1" : "0";
-            skip = 0;
-        }
-    }
-    return s;
-}
-Stream.prototype.parseOctetString = function(start, end) {
-    var len = end - start;
-    var s = "(" + len + " byte) ";
-    if (len > 20)
-        end = start + 20;
-    for (var i = start; i < end; ++i)
-        s += this.hexByte(this.get(i));
-    if (len > 20)
-        s += String.fromCharCode(8230); // ellipsis
-    return s;
-}
-Stream.prototype.parseOID = function(start, end) {
-    var s, n = 0, bits = 0;
-    for (var i = start; i < end; ++i) {
-        var v = this.get(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 ASN1(stream, header, length, tag, sub) {
-    this.stream = stream;
-    this.header = header;
-    this.length = length;
-    this.tag = tag;
-    this.sub = sub;
-}
-ASN1.prototype.typeName = function() {
-    if (this.tag == undefined)
-        return "unknown";
-    var tagClass = this.tag >> 6;
-    var tagConstructed = (this.tag >> 5) & 1;
-    var tagNumber = this.tag & 0x1F;
-    switch (tagClass) {
-    case 0: // universal
-        switch (tagNumber) {
-        case 0x00: return "EOC";
-        case 0x01: return "BOOLEAN";
-        case 0x02: return "INTEGER";
-        case 0x03: return "BIT_STRING";
-        case 0x04: return "OCTET_STRING";
-        case 0x05: return "NULL";
-        case 0x06: return "OBJECT_IDENTIFIER";
-        case 0x07: return "ObjectDescriptor";
-        case 0x08: return "EXTERNAL";
-        case 0x09: return "REAL";
-        case 0x0A: return "ENUMERATED";
-        case 0x0B: return "EMBEDDED_PDV";
-        case 0x0C: return "UTF8String";
-        case 0x10: return "SEQUENCE";
-        case 0x11: return "SET";
-        case 0x12: return "NumericString";
-        case 0x13: return "PrintableString"; // ASCII subset
-        case 0x14: return "TeletexString"; // aka T61String
-        case 0x15: return "VideotexString";
-        case 0x16: return "IA5String"; // ASCII
-        case 0x17: return "UTCTime";
-        case 0x18: return "GeneralizedTime";
-        case 0x19: return "GraphicString";
-        case 0x1A: return "VisibleString"; // ASCII subset
-        case 0x1B: return "GeneralString";
-        case 0x1C: return "UniversalString";
-        case 0x1E: return "BMPString";
-        default: return "Universal_" + tagNumber.toString(16);
-        }
-    case 1: return "Application_" + tagNumber.toString(16);
-    case 2: return "[" + tagNumber + "]"; // Context
-    case 3: return "Private_" + tagNumber.toString(16);
-    }
-}
-ASN1.prototype.content = function() {
-    if (this.tag == undefined)
-        return null;
-    var tagClass = this.tag >> 6;
-    if (tagClass != 0) // universal
-        return (this.sub == null) ? null : "(" + this.sub.length + ")";
-    var tagNumber = this.tag & 0x1F;
-    var content = this.posContent();
-    var len = Math.abs(this.length);
-    switch (tagNumber) {
-    case 0x01: // BOOLEAN
-        return (this.stream.get(content) == 0) ? "false" : "true";
-    case 0x02: // INTEGER
-        return this.stream.parseInteger(content, content + len);
-    case 0x03: // BIT_STRING
-        return this.sub ? "(" + this.sub.length + " elem)" :
-            this.stream.parseBitString(content, content + len)
-    case 0x04: // OCTET_STRING
-        return this.sub ? "(" + this.sub.length + " elem)" :
-            this.stream.parseOctetString(content, content + len)
-    //case 0x05: // NULL
-    case 0x06: // OBJECT_IDENTIFIER
-        return this.stream.parseOID(content, content + len);
-    //case 0x07: // ObjectDescriptor
-    //case 0x08: // EXTERNAL
-    //case 0x09: // REAL
-    //case 0x0A: // ENUMERATED
-    //case 0x0B: // EMBEDDED_PDV
-    case 0x10: // SEQUENCE
-    case 0x11: // SET
-        return "(" + this.sub.length + " elem)";
-    case 0x0C: // UTF8String
-        return this.stream.parseStringUTF(content, content + len);
-    case 0x12: // NumericString
-    case 0x13: // PrintableString
-    case 0x14: // TeletexString
-    case 0x15: // VideotexString
-    case 0x16: // IA5String
-    //case 0x19: // GraphicString
-    case 0x1A: // VisibleString
-    //case 0x1B: // GeneralString
-    //case 0x1C: // UniversalString
-    //case 0x1E: // BMPString
-        return this.stream.parseStringISO(content, content + len);
-    case 0x17: // UTCTime
-    case 0x18: // GeneralizedTime
-        return this.stream.parseTime(content, content + len);
-    }
-    return null;
-}
-ASN1.prototype.toString = function() {
-    return this.typeName() + "@" + this.stream.pos + "[header:" + this.header + ",length:" + this.length + ",sub:" + ((this.sub == null) ? 'null' : this.sub.length) + "]";
-}
-ASN1.prototype.print = function(indent) {
-    if (indent == undefined) indent = '';
-    document.writeln(indent + this);
-    if (this.sub != null) {
-        indent += '  ';
-        for (var i = 0, max = this.sub.length; i < max; ++i)
-            this.sub[i].print(indent);
-    }
-}
-ASN1.prototype.toPrettyString = function(indent) {
-    if (indent == undefined) indent = '';
-    var s = indent + this.typeName() + " @" + this.stream.pos;
-    if (this.length >= 0)
-        s += "+";
-    s += this.length;
-    if (this.tag & 0x20)
-        s += " (constructed)";
-    else if (((this.tag == 0x03) || (this.tag == 0x04)) && (this.sub != null))
-        s += " (encapsulates)";
-    s += "\n";
-    if (this.sub != null) {
-        indent += '  ';
-        for (var i = 0, max = this.sub.length; i < max; ++i)
-            s += this.sub[i].toPrettyString(indent);
-    }
-    return s;
-}
-ASN1.prototype.toDOM = function() {
-    var node = document.createElement("div");
-    node.className = "node";
-    node.asn1 = this;
-    var head = document.createElement("div");
-    head.className = "head";
-    var s = this.typeName().replace(/_/g, " ");
-    head.innerHTML = s;
-    var content = this.content();
-    if (content != null) {
-        content = String(content).replace(/</g, "&lt;");
-        var preview = document.createElement("span");
-        preview.className = "preview";
-        preview.innerHTML = content;
-        head.appendChild(preview);
-    }
-    node.appendChild(head);
-    this.node = node;
-    this.head = head;
-    var value = document.createElement("div");
-    value.className = "value";
-    s = "Offset: " + this.stream.pos + "<br/>";
-    s += "Length: " + this.header + "+";
-    if (this.length >= 0)
-        s += this.length;
-    else
-        s += (-this.length) + " (undefined)";
-    if (this.tag & 0x20)
-        s += "<br/>(constructed)";
-    else if (((this.tag == 0x03) || (this.tag == 0x04)) && (this.sub != null))
-        s += "<br/>(encapsulates)";
-    //TODO if (this.tag == 0x03) s += "Unused bits: "
-    if (content != null) {
-        s += "<br/>Value:<br/><b>" + content + "</b>";
-        if ((typeof(oids) == 'object') && (this.tag == 0x06)) {
-            var oid = oids[content];
-            if (oid) {
-                if (oid.d) s += "<br/>" + oid.d;
-                if (oid.c) s += "<br/>" + oid.c;
-                if (oid.w) s += "<br/>(warning!)";
-            }
-        }
-    }
-    value.innerHTML = s;
-    node.appendChild(value);
-    var sub = document.createElement("div");
-    sub.className = "sub";
-    if (this.sub != null) {
-        for (var i = 0, max = this.sub.length; i < max; ++i)
-            sub.appendChild(this.sub[i].toDOM());
-    }
-    node.appendChild(sub);
-    head.switchNode = node;
-    head.onclick = function() {
-        var node = this.switchNode;
-        node.className = (node.className == "node collapsed") ? "node" : "node collapsed";
-    };
-    return node;
-}
-ASN1.prototype.posStart = function() {
-    return this.stream.pos;
-}
-ASN1.prototype.posContent = function() {
-    return this.stream.pos + this.header;
-}
-ASN1.prototype.posEnd = function() {
-    return this.stream.pos + this.header + Math.abs(this.length);
-}
-ASN1.prototype.fakeHover = function(current) {
-    this.node.className += " hover";
-    if (current)
-        this.head.className += " hover";
-}
-ASN1.prototype.fakeOut = function(current) {
-    var re = / ?hover/;
-    this.node.className = this.node.className.replace(re, "");
-    if (current)
-        this.head.className = this.head.className.replace(re, "");
-}
-ASN1.prototype.toHexDOM_sub = function(node, className, stream, start, end) {
-    if (start >= end)
-        return;
-    var sub = document.createElement("span");
-    sub.className = className;
-    sub.appendChild(document.createTextNode(
-        stream.hexDump(start, end)));
-    node.appendChild(sub);
-}
-ASN1.prototype.toHexDOM = function(root) {
-    var node = document.createElement("span");
-    node.className = 'hex';
-    if (root == undefined) root = node;
-    this.head.hexNode = node;
-    this.head.onmouseover = function() { this.hexNode.className = "hexCurrent"; }
-    this.head.onmouseout  = function() { this.hexNode.className = "hex"; }
-    node.asn1 = this;
-    node.onmouseover = function() {
-        var current = !root.selected;
-        if (current) {
-            root.selected = this.asn1;
-            this.className = "hexCurrent";
-        }
-        this.asn1.fakeHover(current);
-    }
-    node.onmouseout  = function() {
-        var current = (root.selected == this.asn1);
-        this.asn1.fakeOut(current);
-        if (current) {
-            root.selected = null;
-            this.className = "hex";
-        }
-    }
-    this.toHexDOM_sub(node, "tag", this.stream, this.posStart(), this.posStart() + 1);
-    this.toHexDOM_sub(node, (this.length >= 0) ? "dlen" : "ulen", this.stream, this.posStart() + 1, this.posContent());
-    if (this.sub == null)
-        node.appendChild(document.createTextNode(
-            this.stream.hexDump(this.posContent(), this.posEnd())));
-    else if (this.sub.length > 0) {
-        var first = this.sub[0];
-        var last = this.sub[this.sub.length - 1];
-        this.toHexDOM_sub(node, "intro", this.stream, this.posContent(), first.posStart());
-        for (var i = 0, max = this.sub.length; i < max; ++i)
-            node.appendChild(this.sub[i].toHexDOM(root));
-        this.toHexDOM_sub(node, "outro", this.stream, last.posEnd(), this.posEnd());
-    }
-    return node;
-}
-ASN1.decodeLength = function(stream) {
-    var buf = stream.get();
-    var len = buf & 0x7F;
-    if (len == buf)
-        return len;
-    if (len > 3)
-        throw "Length over 24 bits not supported at position " + (stream.pos - 1);
-    if (len == 0)
-        return -1; // undefined
-    buf = 0;
-    for (var i = 0; i < len; ++i)
-        buf = (buf << 8) | stream.get();
-    return buf;
-}
-ASN1.hasContent = function(tag, len, stream) {
-    if (tag & 0x20) // constructed
-        return true;
-    if ((tag < 0x03) || (tag > 0x04))
-        return false;
-    var p = new Stream(stream);
-    if (tag == 0x03) p.get(); // BitString unused bits, must be in [0, 7]
-    var subTag = p.get();
-    if ((subTag >> 6) & 0x01) // not (universal or context)
-        return false;
-    try {
-        var subLength = ASN1.decodeLength(p);
-        return ((p.pos - stream.pos) + subLength == len);
-    } catch (exception) {
-        return false;
-    }
-}
-ASN1.decode = function(stream) {
-    if (!(stream instanceof Stream))
-        stream = new Stream(stream, 0);
-    var streamStart = new Stream(stream);
-    var tag = stream.get();
-    var len = ASN1.decodeLength(stream);
-    var header = stream.pos - streamStart.pos;
-    var sub = null;
-    if (ASN1.hasContent(tag, len, stream)) {
-        // it has content, so we decode it
-        var start = stream.pos;
-        if (tag == 0x03) stream.get(); // skip BitString unused bits, must be in [0, 7]
-        sub = [];
-        if (len >= 0) {
-            // definite length
-            var end = start + len;
-            while (stream.pos < end)
-                sub[sub.length] = ASN1.decode(stream);
-            if (stream.pos != end)
-                throw "Content size is not correct for container starting at offset " + start;
-        } else {
-            // undefined length
-            try {
-                for (;;) {
-                    var s = ASN1.decode(stream);
-                    if (s.tag == 0)
-                        break;
-                    sub[sub.length] = s;
-                }
-                len = start - stream.pos;
-            } catch (e) {
-                throw "Exception while decoding undefined length content: " + e;
-            }
-        }
-    } else
-        stream.pos += len; // skip content
-    return new ASN1(streamStart, header, len, tag, sub);
-}
-/*
-ASN1.test = function() {
-    var test = [
-        { value: [0x27],                   expected: 0x27     },
-        { value: [0x81, 0xC9],             expected: 0xC9     },
-        { value: [0x83, 0xFE, 0xDC, 0xBA], expected: 0xFEDCBA },
-    ];
-    for (var i = 0, max = test.length; i < max; ++i) {
-        var pos = 0;
-        var stream = new Stream(test[i].value, 0);
-        var res = ASN1.decodeLength(stream);
-        if (res != test[i].expected)
-            document.write("In test[" + i + "] expected " + test[i].expected + " got " + res + "\n");
-    }
-}*/
-// Hex JavaScript decoder
-// Copyright (c) 2008 Lapo Luchini <lapo@lapo.it>
-
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-Hex = {};
-
-Hex.decode = function(a) {
-    if (Hex.decoder == undefined) {
-        var hex = "0123456789ABCDEF";
-        var allow = " \f\n\r\t\u00A0\u2028\u2029";
-        var dec = [];
-        for (var i = 0; i < 16; ++i)
-            dec[hex.charAt(i)] = i;
-        hex = hex.toLowerCase();
-        for (var i = 10; i < 16; ++i)
-            dec[hex.charAt(i)] = i;
-        for (var i = 0; i < allow.length; ++i)
-            dec[allow.charAt(i)] = -1;
-        Hex.decoder = dec;
-    }
-    var out = [];
-    var bits = 0, char_count = 0;
-    for (var i = 0; i < a.length; ++i) {
-        var c = a.charAt(i);
-        if (c == '=')
-            break;
-        c = Hex.decoder[c];
-        if (c == -1)
-            continue;
-        if (c == undefined)
-            throw 'Illegal character at offset ' + i;
-        bits |= c;
-        if (++char_count >= 2) {
-            out[out.length] = bits;
-            bits = 0;
-            char_count = 0;
-        } else {
-            bits <<= 4;
-        }
-    }
-    if (char_count)
-        throw "Hex encoding incomplete: 4 bits missing";
-    return out;
-}
 /**
  * @author: Meki Cheraoui
  * See COPYING for copyright and distribution information.
@@ -5161,18 +4608,120 @@
 	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();
-	var der = Hex.decode(wit);
-	var asn1 = ASN1.decode(der);
+	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;
+			} else {
+				len = witness[i+1];
+			}
+			if (step == 4) {
+				// Start to decode digest hex string
+				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;
 	}
 };
 /*
