docs: function(prf, ciphertext, iv, adata, tlen) {
      tlen = tlen || 64;
      adata = adata || [];
      var L,
          w=sjcl.bitArray,
          ivl = w.bitLength(iv) / 8,
          ol = w.bitLength(ciphertext),
          out = w.clamp(ciphertext, ol - tlen),
          tag = w.bitSlice(ciphertext, ol - tlen), tag2;
  
  
      ol = (ol - tlen) / 8;
  
      if (ivl < 7) {
        throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");
      }
  
      // compute the length of the length
      for (L=2; L<4 && ol >>> 8*L; L++) {}
      if (L < 15 - ivl) { L = 15-ivl; }
      iv = w.clamp(iv,8*(15-L));
  
      // decrypt
      out = sjcl.mode.ccm._ctrMode(prf, out, iv, tag, tlen, L);
  
      // check the tag
      tag2 = sjcl.mode.ccm._computeTag(prf, out.data, iv, adata, tlen, L);
      if (!w.equal(out.tag, tag2)) {
        throw new sjcl.exception.corrupt("ccm: tag doesn't match");
      }
  
      return out.data;
    }