CCCPaste

91d9ff8141832

sjcl.mode.ccm = {
    name: "ccm",
    encrypt: function(a, b, c, d, e) {
        var f, g = b.slice(0), h = sjcl.bitArray, l = h.bitLength(c) / 8, k = h.bitLength(g) / 8;
        e = e || 64;
        d = d || [];
        7 > l && q(new sjcl.exception.invalid("ccm: iv must be at least 7 bytes"));
        for (f = 2; 4 > f && k >>> 8 * f; f++)
            ;
        f < 15 - l && (f = 15 - l);
        c = h.clamp(c, 8 * (15 - f));
        b = sjcl.mode.ccm.K(a, b, c, d, e, f);
        g = sjcl.mode.ccm.n(a, g, c, b, e, f);
        return h.concat(g.data, g.tag)
    },
    decrypt: function(a, b, c, d, e) {
        e = e || 64;
        d = d || [];
        var f = sjcl.bitArray
          , g = f.bitLength(c) / 8
          , h = f.bitLength(b)
          , l = f.clamp(b, h - e)
          , k = f.bitSlice(b, h - e)
          , h = (h - e) / 8;
        7 > g && q(new sjcl.exception.invalid("ccm: iv must be at least 7 bytes"));
        for (b = 2; 4 > b && h >>> 8 * b; b++)
            ;
        b < 15 - g && (b = 15 - g);
        c = f.clamp(c, 8 * (15 - b));
        l = sjcl.mode.ccm.n(a, l, c, k, e, b);
        a = sjcl.mode.ccm.K(a, l.data, c, d, e, b);
        f.equal(l.tag, a) || q(new sjcl.exception.corrupt("ccm: tag doesn't match"));
        return l.data
    },
    K: function(a, b, c, d, e, f) {
        var g = []
          , h = sjcl.bitArray
          , l = h.k;
        e /= 8;
        (e % 2 || 4 > e || 16 < e) && q(new sjcl.exception.invalid("ccm: invalid tag length"));
        (0xffffffff < d.length || 0xffffffff < b.length) && q(new sjcl.exception.bug("ccm: can't deal with 4GiB or more data"));
        f = [h.partial(8, (d.length ? 64 : 0) | e - 2 << 2 | f - 1)];
        f = h.concat(f, c);
        f[3] |= h.bitLength(b) / 8;
        f = a.encrypt(f);
        if (d.length) {
            c = h.bitLength(d) / 8;
            65279 >= c ? g = [h.partial(16, c)] : 0xffffffff >= c && (g = h.concat([h.partial(16, 65534)], [c]));
            g = h.concat(g, d);
            for (d = 0; d < g.length; d += 4)
                f = a.encrypt(l(f, g.slice(d, d + 4).concat([0, 0, 0])))
        }
        for (d = 0; d < b.length; d += 4)
            f = a.encrypt(l(f, b.slice(d, d + 4).concat([0, 0, 0])));
        return h.clamp(f, 8 * e)
    },
    n: function(a, b, c, d, e, f) {
        var g, h = sjcl.bitArray;
        g = h.k;
        var l = b.length
          , k = h.bitLength(b);
        c = h.concat([h.partial(8, f - 1)], c).concat([0, 0, 0]).slice(0, 4);
        d = h.bitSlice(g(d, a.encrypt(c)), 0, e);
        if (!l)
            return {
                tag: d,
                data: []
            };
        for (g = 0; g < l; g += 4)
            c[3]++,
            e = a.encrypt(c),
            b[g] ^= e[0],
            b[g + 1] ^= e[1],
            b[g + 2] ^= e[2],
            b[g + 3] ^= e[3];
        return {
            tag: d,
            data: h.clamp(b, k)
        }
    }
};