corrade-nucleus-nucleons – Rev 20

Subversion Repositories:
Rev:
(function(){

var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;

// Shortcuts
var util = C.util,
    charenc = C.charenc,
    UTF8 = charenc.UTF8,
    Binary = charenc.Binary;

// Inner state
var x = [],
    c = [],
    b;

var Rabbit = C.Rabbit = {

        /**
         * Public API
         */

        encrypt: function (message, password) {

                var

                    // Convert to bytes
                    m = UTF8.stringToBytes(message),

                    // Generate random IV
                    iv = util.randomBytes(8),

                    // Generate key
                    k = password.constructor == String ?
                        // Derive key from passphrase
                        C.PBKDF2(password, iv, 32, { asBytes: true }) :
                        // else, assume byte array representing cryptographic key
                        password;

                // Encrypt
                Rabbit._rabbit(m, k, util.bytesToWords(iv));

                // Return ciphertext
                return util.bytesToBase64(iv.concat(m));

        },

        decrypt: function (ciphertext, password) {

                var

                    // Convert to bytes
                    c = util.base64ToBytes(ciphertext),

                    // Separate IV and message
                    iv = c.splice(0, 8),

                    // Generate key
                    k = password.constructor == String ?
                        // Derive key from passphrase
                        C.PBKDF2(password, iv, 32, { asBytes: true }) :
                        // else, assume byte array representing cryptographic key
                        password;

                // Decrypt
                Rabbit._rabbit(c, k, util.bytesToWords(iv));

                // Return plaintext
                return UTF8.bytesToString(c);

        },


        /**
         * Internal methods
         */

        // Encryption/decryption scheme
        _rabbit: function (m, k, iv) {

                Rabbit._keysetup(k);
                if (iv) Rabbit._ivsetup(iv);

                for (var s = [], i = 0; i < m.length; i++) {

                        if (i % 16 == 0) {

                                // Iterate the system
                                Rabbit._nextstate();

                                // Generate 16 bytes of pseudo-random data
                                s[0] = x[0] ^ (x[5] >>> 16) ^ (x[3] << 16);
                                s[1] = x[2] ^ (x[7] >>> 16) ^ (x[5] << 16);
                                s[2] = x[4] ^ (x[1] >>> 16) ^ (x[7] << 16);
                                s[3] = x[6] ^ (x[3] >>> 16) ^ (x[1] << 16);

                                // Swap endian
                                for (var j = 0; j < 4; j++) {
                                        s[j] = ((s[j] <<  8) | (s[j] >>> 24)) & 0x00FF00FF |
                                               ((s[j] << 24) | (s[j] >>>  8)) & 0xFF00FF00;
                                }

                                // Convert words to bytes
                                for (var b = 120; b >= 0; b -= 8)
                                        s[b / 8] = (s[b >>> 5] >>> (24 - b % 32)) & 0xFF;

                        }

                        m[i] ^= s[i % 16];

                }

        },

        // Key setup scheme
        _keysetup: function (k) {

                // Generate initial state values
                x[0] = k[0];
                x[2] = k[1];
                x[4] = k[2];
                x[6] = k[3];
                x[1] = (k[3] << 16) | (k[2] >>> 16);
                x[3] = (k[0] << 16) | (k[3] >>> 16);
                x[5] = (k[1] << 16) | (k[0] >>> 16);
                x[7] = (k[2] << 16) | (k[1] >>> 16);

                // Generate initial counter values
                c[0] = util.rotl(k[2], 16);
                c[2] = util.rotl(k[3], 16);
                c[4] = util.rotl(k[0], 16);
                c[6] = util.rotl(k[1], 16);
                c[1] = (k[0] & 0xFFFF0000) | (k[1] & 0xFFFF);
                c[3] = (k[1] & 0xFFFF0000) | (k[2] & 0xFFFF);
                c[5] = (k[2] & 0xFFFF0000) | (k[3] & 0xFFFF);
                c[7] = (k[3] & 0xFFFF0000) | (k[0] & 0xFFFF);

                // Clear carry bit
                b = 0;

                // Iterate the system four times
                for (var i = 0; i < 4; i++) Rabbit._nextstate();

                // Modify the counters
                for (var i = 0; i < 8; i++) c[i] ^= x[(i + 4) & 7];

        },

        // IV setup scheme
        _ivsetup: function (iv) {

                // Generate four subvectors
                var i0 = util.endian(iv[0]),
                    i2 = util.endian(iv[1]),
                    i1 = (i0 >>> 16) | (i2 & 0xFFFF0000),
                    i3 = (i2 <<  16) | (i0 & 0x0000FFFF);

                // Modify counter values
                c[0] ^= i0;
                c[1] ^= i1;
                c[2] ^= i2;
                c[3] ^= i3;
                c[4] ^= i0;
                c[5] ^= i1;
                c[6] ^= i2;
                c[7] ^= i3;

                // Iterate the system four times
                for (var i = 0; i < 4; i++) Rabbit._nextstate();

        },

        // Next-state function
        _nextstate: function () {

                // Save old counter values
                for (var c_old = [], i = 0; i < 8; i++) c_old[i] = c[i];

                // Calculate new counter values
                c[0] = (c[0] + 0x4D34D34D + b) >>> 0;
                c[1] = (c[1] + 0xD34D34D3 + ((c[0] >>> 0) < (c_old[0] >>> 0) ? 1 : 0)) >>> 0;
                c[2] = (c[2] + 0x34D34D34 + ((c[1] >>> 0) < (c_old[1] >>> 0) ? 1 : 0)) >>> 0;
                c[3] = (c[3] + 0x4D34D34D + ((c[2] >>> 0) < (c_old[2] >>> 0) ? 1 : 0)) >>> 0;
                c[4] = (c[4] + 0xD34D34D3 + ((c[3] >>> 0) < (c_old[3] >>> 0) ? 1 : 0)) >>> 0;
                c[5] = (c[5] + 0x34D34D34 + ((c[4] >>> 0) < (c_old[4] >>> 0) ? 1 : 0)) >>> 0;
                c[6] = (c[6] + 0x4D34D34D + ((c[5] >>> 0) < (c_old[5] >>> 0) ? 1 : 0)) >>> 0;
                c[7] = (c[7] + 0xD34D34D3 + ((c[6] >>> 0) < (c_old[6] >>> 0) ? 1 : 0)) >>> 0;
                b = (c[7] >>> 0) < (c_old[7] >>> 0) ? 1 : 0;

                // Calculate the g-values
                for (var g = [], i = 0; i < 8; i++) {

                        var gx = (x[i] + c[i]) >>> 0;

                        // Construct high and low argument for squaring
                        var ga = gx & 0xFFFF,
                            gb = gx >>> 16;

                        // Calculate high and low result of squaring
                        var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb,
                            gl = (((gx & 0xFFFF0000) * gx) >>> 0) + (((gx & 0x0000FFFF) * gx) >>> 0) >>> 0;

                        // High XOR low
                        g[i] = gh ^ gl;

                }

                // Calculate new state values
                x[0] = g[0] + ((g[7] << 16) | (g[7] >>> 16)) + ((g[6] << 16) | (g[6] >>> 16));
                x[1] = g[1] + ((g[0] <<  8) | (g[0] >>> 24)) + g[7];
                x[2] = g[2] + ((g[1] << 16) | (g[1] >>> 16)) + ((g[0] << 16) | (g[0] >>> 16));
                x[3] = g[3] + ((g[2] <<  8) | (g[2] >>> 24)) + g[1];
                x[4] = g[4] + ((g[3] << 16) | (g[3] >>> 16)) + ((g[2] << 16) | (g[2] >>> 16));
                x[5] = g[5] + ((g[4] <<  8) | (g[4] >>> 24)) + g[3];
                x[6] = g[6] + ((g[5] << 16) | (g[5] >>> 16)) + ((g[4] << 16) | (g[4] >>> 16));
                x[7] = g[7] + ((g[6] <<  8) | (g[6] >>> 24)) + g[5];

        }

};

})();

Generated by GNU Enscript 1.6.5.90.