docs: function(prf, plaintext, iv, adata, tlen, L) {
      // compute B[0]
      var mac, tmp, i, macData = [], w=sjcl.bitArray, xor = w._xor4;
  
      tlen /= 8;
  
      // check tag length and message length
      if (tlen % 2 || tlen < 4 || tlen > 16) {
        throw new sjcl.exception.invalid("ccm: invalid tag length");
      }
  
      if (adata.length > 0xFFFFFFFF || plaintext.length > 0xFFFFFFFF) {
        // I don't want to deal with extracting high words from doubles.
        throw new sjcl.exception.bug("ccm: can't deal with 4GiB or more data");
      }
  
      // mac the flags
      mac = [w.partial(8, (adata.length ? 1<<6 : 0) | (tlen-2) << 2 | L-1)];
  
      // mac the iv and length
      mac = w.concat(mac, iv);
      mac[3] |= w.bitLength(plaintext)/8;
      mac = prf.encrypt(mac);
  
  
      if (adata.length) {
        // mac the associated data.  start with its length...
        tmp = w.bitLength(adata)/8;
        if (tmp <= 0xFEFF) {
          macData = [w.partial(16, tmp)];
        } else if (tmp <= 0xFFFFFFFF) {
          macData = w.concat([w.partial(16,0xFFFE)], [tmp]);
        } // else ...
  
        // mac the data itself
        macData = w.concat(macData, adata);
        for (i=0; i<macData.length; i += 4) {
          mac = prf.encrypt(xor(mac, macData.slice(i,i+4).concat([0,0,0])));
        }
      }
  
      // mac the plaintext
      for (i=0; i<plaintext.length; i+=4) {
        mac = prf.encrypt(xor(mac, plaintext.slice(i,i+4).concat([0,0,0])));
      }
  
      return w.clamp(mac, tlen * 8);
    }