code: function (prf, iterationCount) {
  
          var xor = function (l, r) {
              var i;
              for (i = 0; i < l.length; i++) {
                  l[i] = l[i] ^ r[i];
              }
              return l;
          };
  
          var _F = function (password, salt, iterationCount, i) {
              var k;
              var Ti = new Uint8Array(new ArrayBuffer(prf.hmacLength()));
              var U = new Uint8Array(new ArrayBuffer(salt.length + 4));
              U.set(salt, 0);
              U.set(convertToUInt32(i), salt.length);
              for (k = 1; k <= iterationCount; k++) {
                  prf.setKey(password);
                  prf.update(U);
                  U = new Uint8Array(prf.finalize());
                  Ti = xor(Ti, U);
              }
              return Ti;
          };
  
          var derive = function (password, salt, len) {
              var i, l, tmpBuf;
              if (len > prf.hmacLength() * 0xFFFFFFFF) {
                  throw "Derived key length too long";
              }
              l = Math.ceil(len / prf.hmacLength());
              tmpBuf = new Uint8Array(new ArrayBuffer(len * prf.hmacLength()));
              for (i = 1; i <= l; i++) {
                  tmpBuf.set(_F(password, salt, iterationCount, i), prf.hmacLength() * (i - 1));
              }
              return tmpBuf.buffer.slice(0, len);
          };
  
          return {
              deriveKey: function (password, salt, len) {
                  return derive(convertToUint8Array(password), convertToUint8Array(salt), len);
              }
          };
      }
docs: /* PBKDF2 Implementation