code: function (Constructor) {
          var update = function (input) {
              var len = input.length;
              var offset = 0;
              while (len > 0) {
                  var copyLen = this.blockLen - this.inLen;
                  if (copyLen > len) {
                      copyLen = len;
                  }
                  var tmpInput = input.subarray(offset, offset + copyLen);
                  this.inbuf.set(tmpInput, this.inLen);
                  offset += copyLen;
                  len -= copyLen;
                  this.inLen += copyLen;
                  if (this.inLen === this.blockLen) {
  		    //var t0 = performance.now();
                      this.processBlock(this.inbuf);
  		    //var t1 = performance.now();
  		    //console.log(t1 - t0);
                      this.inLen = 0;
                  }
              }
          };
  
          var finalize = function () {
              var padding = this.doPadding();
              this.update(padding);
              var result = this.getDigest();
              this.reset();
              return result;
          };
  
          var engine = (function () {
              if (!Constructor) {
                  throw "Unsupported algorithm: " + Constructor.toString();
              }
              Constructor.prototype.update = update;
              Constructor.prototype.finalize = finalize;
              var engine = new Constructor();
              engine.inbuf = new Uint8Array(new ArrayBuffer(engine.blockLen));
              engine.reset();
              return engine;
          }());
  
          return {
              update: function (input) {
                  engine.update(convertToUint8Array(input));
              },
  
              finalize: function () {
                  return engine.finalize();
              },
  
              digest: function (input) {
                  engine.update(convertToUint8Array(input));
                  return engine.finalize();
              },
  
              reset: function () {
                  engine.reset();
              },
  
              digestLength: function () {
                  return engine.digestLen;
              }
          };
      }
docs: /* Digest implementation