├── README.md ├── cryptojs.js ├── lib ├── AES.js ├── BlockModes.js ├── Crypto.js ├── CryptoMath.js ├── DES.js ├── HMAC.js ├── MARC4.js ├── MD5.js ├── PBKDF2.js ├── PBKDF2Async.js ├── Rabbit.js ├── SHA1.js └── SHA256.js ├── package.json └── test ├── PBKDF2-test.js └── test.coffee /README.md: -------------------------------------------------------------------------------- 1 | cryptojs 2 | -------- 3 | 4 | * with little modification, converted from googlecode project [crypto-js](http://code.google.com/p/crypto-js/), and keep the source code structure of the origin project on googlecode 5 | * source code worked in both browser engines and node scripts. see also: [https://github.com/gwjjeff/crypto-js-npm-conv](https://github.com/gwjjeff/crypto-js-npm-conv) 6 | * inspiration comes from [ezcrypto](https://github.com/ElmerZhang/ezcrypto), but my tests cannot pass with his version ( ECB/pkcs7 mode ), so I made it myself 7 | 8 | ### install 9 | 10 | ``` 11 | npm install cryptojs 12 | ``` 13 | 14 | ### usage (example with [coffee-script](http://coffeescript.org/)) 15 | 16 | ```coffee 17 | Crypto = (require 'cryptojs').Crypto 18 | key = '12345678' 19 | us = 'Hello, 世界!' 20 | 21 | mode = new Crypto.mode.ECB Crypto.pad.pkcs7 22 | 23 | ub = Crypto.charenc.UTF8.stringToBytes us 24 | eb = Crypto.DES.encrypt ub, key, {asBytes: true, mode: mode} 25 | ehs= Crypto.util.bytesToHex eb 26 | 27 | eb2= Crypto.util.hexToBytes ehs 28 | ub2= Crypto.DES.decrypt eb2, key, {asBytes: true, mode: mode} 29 | us2= Crypto.charenc.UTF8.bytesToString ub2 30 | # should be same as the var 'us' 31 | console .log us2 32 | ``` 33 | -------------------------------------------------------------------------------- /cryptojs.js: -------------------------------------------------------------------------------- 1 | var Crypto = exports.Crypto = require('./lib/Crypto').Crypto; 2 | 3 | [ 'CryptoMath' 4 | , 'BlockModes' 5 | , 'DES' 6 | , 'AES' 7 | , 'HMAC' 8 | , 'MARC4' 9 | , 'MD5' 10 | , 'PBKDF2' 11 | , 'PBKDF2Async' 12 | , 'Rabbit' 13 | , 'SHA1' 14 | , 'SHA256' 15 | ].forEach( function (path) { 16 | require('./lib/' + path); 17 | }); 18 | -------------------------------------------------------------------------------- /lib/AES.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | 3 | var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto; 4 | 5 | // Shortcuts 6 | var util = C.util, 7 | charenc = C.charenc, 8 | UTF8 = charenc.UTF8; 9 | 10 | // Precomputed SBOX 11 | var SBOX = [ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 12 | 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 13 | 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 14 | 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 15 | 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 16 | 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 17 | 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 18 | 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 19 | 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 20 | 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 21 | 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 22 | 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 23 | 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 24 | 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 25 | 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 26 | 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 27 | 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 28 | 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 29 | 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 30 | 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 31 | 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 32 | 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 33 | 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 34 | 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 35 | 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 36 | 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 37 | 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 38 | 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 39 | 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 40 | 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 41 | 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 42 | 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 ]; 43 | 44 | // Compute inverse SBOX lookup table 45 | for (var INVSBOX = [], i = 0; i < 256; i++) INVSBOX[SBOX[i]] = i; 46 | 47 | // Compute mulitplication in GF(2^8) lookup tables 48 | var MULT2 = [], 49 | MULT3 = [], 50 | MULT9 = [], 51 | MULTB = [], 52 | MULTD = [], 53 | MULTE = []; 54 | 55 | function xtime(a, b) { 56 | for (var result = 0, i = 0; i < 8; i++) { 57 | if (b & 1) result ^= a; 58 | var hiBitSet = a & 0x80; 59 | a = (a << 1) & 0xFF; 60 | if (hiBitSet) a ^= 0x1b; 61 | b >>>= 1; 62 | } 63 | return result; 64 | } 65 | 66 | for (var i = 0; i < 256; i++) { 67 | MULT2[i] = xtime(i,2); 68 | MULT3[i] = xtime(i,3); 69 | MULT9[i] = xtime(i,9); 70 | MULTB[i] = xtime(i,0xB); 71 | MULTD[i] = xtime(i,0xD); 72 | MULTE[i] = xtime(i,0xE); 73 | } 74 | 75 | // Precomputed RCon lookup 76 | var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36]; 77 | 78 | // Inner state 79 | var state = [[], [], [], []], 80 | keylength, 81 | nrounds, 82 | keyschedule; 83 | 84 | var AES = C.AES = { 85 | 86 | /** 87 | * Public API 88 | */ 89 | 90 | encrypt: function (message, password, options) { 91 | 92 | options = options || {}; 93 | 94 | // Determine mode 95 | var mode = options.mode || new C.mode.OFB; 96 | 97 | // Allow mode to override options 98 | if (mode.fixOptions) mode.fixOptions(options); 99 | 100 | var 101 | 102 | // Convert to bytes if message is a string 103 | m = ( 104 | message.constructor == String ? 105 | UTF8.stringToBytes(message) : 106 | message 107 | ), 108 | 109 | // Generate random IV 110 | iv = options.iv || util.randomBytes(AES._blocksize * 4), 111 | 112 | // Generate key 113 | k = ( 114 | password.constructor == String ? 115 | // Derive key from passphrase 116 | C.PBKDF2(password, iv, 32, { asBytes: true }) : 117 | // else, assume byte array representing cryptographic key 118 | password 119 | ); 120 | 121 | // Encrypt 122 | AES._init(k); 123 | mode.encrypt(AES, m, iv); 124 | 125 | // Return ciphertext 126 | m = options.iv ? m : iv.concat(m); 127 | return (options && options.asBytes) ? m : util.bytesToBase64(m); 128 | 129 | }, 130 | 131 | decrypt: function (ciphertext, password, options) { 132 | 133 | options = options || {}; 134 | 135 | // Determine mode 136 | var mode = options.mode || new C.mode.OFB; 137 | 138 | // Allow mode to override options 139 | if (mode.fixOptions) mode.fixOptions(options); 140 | 141 | var 142 | 143 | // Convert to bytes if ciphertext is a string 144 | c = ( 145 | ciphertext.constructor == String ? 146 | util.base64ToBytes(ciphertext): 147 | ciphertext 148 | ), 149 | 150 | // Separate IV and message 151 | iv = options.iv || c.splice(0, AES._blocksize * 4), 152 | 153 | // Generate key 154 | k = ( 155 | password.constructor == String ? 156 | // Derive key from passphrase 157 | C.PBKDF2(password, iv, 32, { asBytes: true }) : 158 | // else, assume byte array representing cryptographic key 159 | password 160 | ); 161 | 162 | // Decrypt 163 | AES._init(k); 164 | mode.decrypt(AES, c, iv); 165 | 166 | // Return plaintext 167 | return (options && options.asBytes) ? c : UTF8.bytesToString(c); 168 | 169 | }, 170 | 171 | 172 | /** 173 | * Package private methods and properties 174 | */ 175 | 176 | _blocksize: 4, 177 | 178 | _encryptblock: function (m, offset) { 179 | 180 | // Set input 181 | for (var row = 0; row < AES._blocksize; row++) { 182 | for (var col = 0; col < 4; col++) 183 | state[row][col] = m[offset + col * 4 + row]; 184 | } 185 | 186 | // Add round key 187 | for (var row = 0; row < 4; row++) { 188 | for (var col = 0; col < 4; col++) 189 | state[row][col] ^= keyschedule[col][row]; 190 | } 191 | 192 | for (var round = 1; round < nrounds; round++) { 193 | 194 | // Sub bytes 195 | for (var row = 0; row < 4; row++) { 196 | for (var col = 0; col < 4; col++) 197 | state[row][col] = SBOX[state[row][col]]; 198 | } 199 | 200 | // Shift rows 201 | state[1].push(state[1].shift()); 202 | state[2].push(state[2].shift()); 203 | state[2].push(state[2].shift()); 204 | state[3].unshift(state[3].pop()); 205 | 206 | // Mix columns 207 | for (var col = 0; col < 4; col++) { 208 | 209 | var s0 = state[0][col], 210 | s1 = state[1][col], 211 | s2 = state[2][col], 212 | s3 = state[3][col]; 213 | 214 | state[0][col] = MULT2[s0] ^ MULT3[s1] ^ s2 ^ s3; 215 | state[1][col] = s0 ^ MULT2[s1] ^ MULT3[s2] ^ s3; 216 | state[2][col] = s0 ^ s1 ^ MULT2[s2] ^ MULT3[s3]; 217 | state[3][col] = MULT3[s0] ^ s1 ^ s2 ^ MULT2[s3]; 218 | 219 | } 220 | 221 | // Add round key 222 | for (var row = 0; row < 4; row++) { 223 | for (var col = 0; col < 4; col++) 224 | state[row][col] ^= keyschedule[round * 4 + col][row]; 225 | } 226 | 227 | } 228 | 229 | // Sub bytes 230 | for (var row = 0; row < 4; row++) { 231 | for (var col = 0; col < 4; col++) 232 | state[row][col] = SBOX[state[row][col]]; 233 | } 234 | 235 | // Shift rows 236 | state[1].push(state[1].shift()); 237 | state[2].push(state[2].shift()); 238 | state[2].push(state[2].shift()); 239 | state[3].unshift(state[3].pop()); 240 | 241 | // Add round key 242 | for (var row = 0; row < 4; row++) { 243 | for (var col = 0; col < 4; col++) 244 | state[row][col] ^= keyschedule[nrounds * 4 + col][row]; 245 | } 246 | 247 | // Set output 248 | for (var row = 0; row < AES._blocksize; row++) { 249 | for (var col = 0; col < 4; col++) 250 | m[offset + col * 4 + row] = state[row][col]; 251 | } 252 | 253 | }, 254 | 255 | _decryptblock: function (c, offset) { 256 | 257 | // Set input 258 | for (var row = 0; row < AES._blocksize; row++) { 259 | for (var col = 0; col < 4; col++) 260 | state[row][col] = c[offset + col * 4 + row]; 261 | } 262 | 263 | // Add round key 264 | for (var row = 0; row < 4; row++) { 265 | for (var col = 0; col < 4; col++) 266 | state[row][col] ^= keyschedule[nrounds * 4 + col][row]; 267 | } 268 | 269 | for (var round = 1; round < nrounds; round++) { 270 | 271 | // Inv shift rows 272 | state[1].unshift(state[1].pop()); 273 | state[2].push(state[2].shift()); 274 | state[2].push(state[2].shift()); 275 | state[3].push(state[3].shift()); 276 | 277 | // Inv sub bytes 278 | for (var row = 0; row < 4; row++) { 279 | for (var col = 0; col < 4; col++) 280 | state[row][col] = INVSBOX[state[row][col]]; 281 | } 282 | 283 | // Add round key 284 | for (var row = 0; row < 4; row++) { 285 | for (var col = 0; col < 4; col++) 286 | state[row][col] ^= keyschedule[(nrounds - round) * 4 + col][row]; 287 | } 288 | 289 | // Inv mix columns 290 | for (var col = 0; col < 4; col++) { 291 | 292 | var s0 = state[0][col], 293 | s1 = state[1][col], 294 | s2 = state[2][col], 295 | s3 = state[3][col]; 296 | 297 | state[0][col] = MULTE[s0] ^ MULTB[s1] ^ MULTD[s2] ^ MULT9[s3]; 298 | state[1][col] = MULT9[s0] ^ MULTE[s1] ^ MULTB[s2] ^ MULTD[s3]; 299 | state[2][col] = MULTD[s0] ^ MULT9[s1] ^ MULTE[s2] ^ MULTB[s3]; 300 | state[3][col] = MULTB[s0] ^ MULTD[s1] ^ MULT9[s2] ^ MULTE[s3]; 301 | 302 | } 303 | 304 | } 305 | 306 | // Inv shift rows 307 | state[1].unshift(state[1].pop()); 308 | state[2].push(state[2].shift()); 309 | state[2].push(state[2].shift()); 310 | state[3].push(state[3].shift()); 311 | 312 | // Inv sub bytes 313 | for (var row = 0; row < 4; row++) { 314 | for (var col = 0; col < 4; col++) 315 | state[row][col] = INVSBOX[state[row][col]]; 316 | } 317 | 318 | // Add round key 319 | for (var row = 0; row < 4; row++) { 320 | for (var col = 0; col < 4; col++) 321 | state[row][col] ^= keyschedule[col][row]; 322 | } 323 | 324 | // Set output 325 | for (var row = 0; row < AES._blocksize; row++) { 326 | for (var col = 0; col < 4; col++) 327 | c[offset + col * 4 + row] = state[row][col]; 328 | } 329 | 330 | }, 331 | 332 | 333 | /** 334 | * Private methods 335 | */ 336 | 337 | _init: function (k) { 338 | keylength = k.length / 4; 339 | nrounds = keylength + 6; 340 | AES._keyexpansion(k); 341 | }, 342 | 343 | // Generate a key schedule 344 | _keyexpansion: function (k) { 345 | 346 | keyschedule = []; 347 | 348 | for (var row = 0; row < keylength; row++) { 349 | keyschedule[row] = [ 350 | k[row * 4], 351 | k[row * 4 + 1], 352 | k[row * 4 + 2], 353 | k[row * 4 + 3] 354 | ]; 355 | } 356 | 357 | for (var row = keylength; row < AES._blocksize * (nrounds + 1); row++) { 358 | 359 | var temp = [ 360 | keyschedule[row - 1][0], 361 | keyschedule[row - 1][1], 362 | keyschedule[row - 1][2], 363 | keyschedule[row - 1][3] 364 | ]; 365 | 366 | if (row % keylength == 0) { 367 | 368 | // Rot word 369 | temp.push(temp.shift()); 370 | 371 | // Sub word 372 | temp[0] = SBOX[temp[0]]; 373 | temp[1] = SBOX[temp[1]]; 374 | temp[2] = SBOX[temp[2]]; 375 | temp[3] = SBOX[temp[3]]; 376 | 377 | temp[0] ^= RCON[row / keylength]; 378 | 379 | } else if (keylength > 6 && row % keylength == 4) { 380 | 381 | // Sub word 382 | temp[0] = SBOX[temp[0]]; 383 | temp[1] = SBOX[temp[1]]; 384 | temp[2] = SBOX[temp[2]]; 385 | temp[3] = SBOX[temp[3]]; 386 | 387 | } 388 | 389 | keyschedule[row] = [ 390 | keyschedule[row - keylength][0] ^ temp[0], 391 | keyschedule[row - keylength][1] ^ temp[1], 392 | keyschedule[row - keylength][2] ^ temp[2], 393 | keyschedule[row - keylength][3] ^ temp[3] 394 | ]; 395 | 396 | } 397 | 398 | } 399 | 400 | }; 401 | 402 | })(); 403 | -------------------------------------------------------------------------------- /lib/BlockModes.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Crypto-JS contribution from Simon Greatrix 3 | */ 4 | 5 | (function(){ 6 | 7 | var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto; 8 | 9 | // Create pad namespace 10 | var C_pad = C.pad = {}; 11 | 12 | // Calculate the number of padding bytes required. 13 | function _requiredPadding(cipher, message) { 14 | var blockSizeInBytes = cipher._blocksize * 4; 15 | var reqd = blockSizeInBytes - message.length % blockSizeInBytes; 16 | return reqd; 17 | }; 18 | 19 | // Remove padding when the final byte gives the number of padding bytes. 20 | var _unpadLength = function (message) { 21 | var pad = message.pop(); 22 | for (var i = 1; i < pad; i++) { 23 | message.pop(); 24 | } 25 | }; 26 | 27 | // No-operation padding, used for stream ciphers 28 | C_pad.NoPadding = { 29 | pad : function (cipher,message) {}, 30 | unpad : function (message) {} 31 | }; 32 | 33 | // Zero Padding. 34 | // 35 | // If the message is not an exact number of blocks, the final block is 36 | // completed with 0x00 bytes. There is no unpadding. 37 | C_pad.ZeroPadding = { 38 | pad : function (cipher, message) { 39 | var blockSizeInBytes = cipher._blocksize * 4; 40 | var reqd = message.length % blockSizeInBytes; 41 | if( reqd!=0 ) { 42 | for(reqd = blockSizeInBytes - reqd; reqd>0; reqd--) { 43 | message.push(0x00); 44 | } 45 | } 46 | }, 47 | 48 | unpad : function (message) {} 49 | }; 50 | 51 | // ISO/IEC 7816-4 padding. 52 | // 53 | // Pads the plain text with an 0x80 byte followed by as many 0x00 54 | // bytes are required to complete the block. 55 | C_pad.iso7816 = { 56 | pad : function (cipher, message) { 57 | var reqd = _requiredPadding(cipher, message); 58 | message.push(0x80); 59 | for (; reqd > 1; reqd--) { 60 | message.push(0x00); 61 | } 62 | }, 63 | 64 | unpad : function (message) { 65 | while (message.pop() != 0x80) {} 66 | } 67 | }; 68 | 69 | // ANSI X.923 padding 70 | // 71 | // The final block is padded with zeros except for the last byte of the 72 | // last block which contains the number of padding bytes. 73 | C_pad.ansix923 = { 74 | pad : function (cipher, message) { 75 | var reqd = _requiredPadding(cipher, message); 76 | for (var i = 1; i < reqd; i++) { 77 | message.push(0x00); 78 | } 79 | message.push(reqd); 80 | }, 81 | 82 | unpad : _unpadLength 83 | }; 84 | 85 | // ISO 10126 86 | // 87 | // The final block is padded with random bytes except for the last 88 | // byte of the last block which contains the number of padding bytes. 89 | C_pad.iso10126 = { 90 | pad : function (cipher, message) { 91 | var reqd = _requiredPadding(cipher, message); 92 | for (var i = 1; i < reqd; i++) { 93 | message.push(Math.floor(Math.random() * 256)); 94 | } 95 | message.push(reqd); 96 | }, 97 | 98 | unpad : _unpadLength 99 | }; 100 | 101 | // PKCS7 padding 102 | // 103 | // PKCS7 is described in RFC 5652. Padding is in whole bytes. The 104 | // value of each added byte is the number of bytes that are added, 105 | // i.e. N bytes, each of value N are added. 106 | C_pad.pkcs7 = { 107 | pad : function (cipher, message) { 108 | var reqd = _requiredPadding(cipher, message); 109 | for (var i = 0; i < reqd; i++) { 110 | message.push(reqd); 111 | } 112 | }, 113 | 114 | unpad : _unpadLength 115 | }; 116 | 117 | // Create mode namespace 118 | var C_mode = C.mode = {}; 119 | 120 | /** 121 | * Mode base "class". 122 | */ 123 | var Mode = C_mode.Mode = function (padding) { 124 | if (padding) { 125 | this._padding = padding; 126 | } 127 | }; 128 | 129 | Mode.prototype = { 130 | encrypt: function (cipher, m, iv) { 131 | this._padding.pad(cipher, m); 132 | this._doEncrypt(cipher, m, iv); 133 | }, 134 | 135 | decrypt: function (cipher, m, iv) { 136 | this._doDecrypt(cipher, m, iv); 137 | this._padding.unpad(m); 138 | }, 139 | 140 | // Default padding 141 | _padding: C_pad.iso7816 142 | }; 143 | 144 | 145 | /** 146 | * Electronic Code Book mode. 147 | * 148 | * ECB applies the cipher directly against each block of the input. 149 | * 150 | * ECB does not require an initialization vector. 151 | */ 152 | var ECB = C_mode.ECB = function () { 153 | // Call parent constructor 154 | Mode.apply(this, arguments); 155 | }; 156 | 157 | // Inherit from Mode 158 | var ECB_prototype = ECB.prototype = new Mode; 159 | 160 | // Concrete steps for Mode template 161 | ECB_prototype._doEncrypt = function (cipher, m, iv) { 162 | var blockSizeInBytes = cipher._blocksize * 4; 163 | // Encrypt each block 164 | for (var offset = 0; offset < m.length; offset += blockSizeInBytes) { 165 | cipher._encryptblock(m, offset); 166 | } 167 | }; 168 | ECB_prototype._doDecrypt = function (cipher, c, iv) { 169 | var blockSizeInBytes = cipher._blocksize * 4; 170 | // Decrypt each block 171 | for (var offset = 0; offset < c.length; offset += blockSizeInBytes) { 172 | cipher._decryptblock(c, offset); 173 | } 174 | }; 175 | 176 | // ECB never uses an IV 177 | ECB_prototype.fixOptions = function (options) { 178 | options.iv = []; 179 | }; 180 | 181 | 182 | /** 183 | * Cipher block chaining 184 | * 185 | * The first block is XORed with the IV. Subsequent blocks are XOR with the 186 | * previous cipher output. 187 | */ 188 | var CBC = C_mode.CBC = function () { 189 | // Call parent constructor 190 | Mode.apply(this, arguments); 191 | }; 192 | 193 | // Inherit from Mode 194 | var CBC_prototype = CBC.prototype = new Mode; 195 | 196 | // Concrete steps for Mode template 197 | CBC_prototype._doEncrypt = function (cipher, m, iv) { 198 | var blockSizeInBytes = cipher._blocksize * 4; 199 | 200 | // Encrypt each block 201 | for (var offset = 0; offset < m.length; offset += blockSizeInBytes) { 202 | if (offset == 0) { 203 | // XOR first block using IV 204 | for (var i = 0; i < blockSizeInBytes; i++) 205 | m[i] ^= iv[i]; 206 | } else { 207 | // XOR this block using previous crypted block 208 | for (var i = 0; i < blockSizeInBytes; i++) 209 | m[offset + i] ^= m[offset + i - blockSizeInBytes]; 210 | } 211 | // Encrypt block 212 | cipher._encryptblock(m, offset); 213 | } 214 | }; 215 | CBC_prototype._doDecrypt = function (cipher, c, iv) { 216 | var blockSizeInBytes = cipher._blocksize * 4; 217 | 218 | // At the start, the previously crypted block is the IV 219 | var prevCryptedBlock = iv; 220 | 221 | // Decrypt each block 222 | for (var offset = 0; offset < c.length; offset += blockSizeInBytes) { 223 | // Save this crypted block 224 | var thisCryptedBlock = c.slice(offset, offset + blockSizeInBytes); 225 | // Decrypt block 226 | cipher._decryptblock(c, offset); 227 | // XOR decrypted block using previous crypted block 228 | for (var i = 0; i < blockSizeInBytes; i++) { 229 | c[offset + i] ^= prevCryptedBlock[i]; 230 | } 231 | prevCryptedBlock = thisCryptedBlock; 232 | } 233 | }; 234 | 235 | 236 | /** 237 | * Cipher feed back 238 | * 239 | * The cipher output is XORed with the plain text to produce the cipher output, 240 | * which is then fed back into the cipher to produce a bit pattern to XOR the 241 | * next block with. 242 | * 243 | * This is a stream cipher mode and does not require padding. 244 | */ 245 | var CFB = C_mode.CFB = function () { 246 | // Call parent constructor 247 | Mode.apply(this, arguments); 248 | }; 249 | 250 | // Inherit from Mode 251 | var CFB_prototype = CFB.prototype = new Mode; 252 | 253 | // Override padding 254 | CFB_prototype._padding = C_pad.NoPadding; 255 | 256 | // Concrete steps for Mode template 257 | CFB_prototype._doEncrypt = function (cipher, m, iv) { 258 | var blockSizeInBytes = cipher._blocksize * 4, 259 | keystream = iv.slice(0); 260 | 261 | // Encrypt each byte 262 | for (var i = 0; i < m.length; i++) { 263 | 264 | var j = i % blockSizeInBytes; 265 | if (j == 0) cipher._encryptblock(keystream, 0); 266 | 267 | m[i] ^= keystream[j]; 268 | keystream[j] = m[i]; 269 | } 270 | }; 271 | CFB_prototype._doDecrypt = function (cipher, c, iv) { 272 | var blockSizeInBytes = cipher._blocksize * 4, 273 | keystream = iv.slice(0); 274 | 275 | // Encrypt each byte 276 | for (var i = 0; i < c.length; i++) { 277 | 278 | var j = i % blockSizeInBytes; 279 | if (j == 0) cipher._encryptblock(keystream, 0); 280 | 281 | var b = c[i]; 282 | c[i] ^= keystream[j]; 283 | keystream[j] = b; 284 | } 285 | }; 286 | 287 | 288 | /** 289 | * Output feed back 290 | * 291 | * The cipher repeatedly encrypts its own output. The output is XORed with the 292 | * plain text to produce the cipher text. 293 | * 294 | * This is a stream cipher mode and does not require padding. 295 | */ 296 | var OFB = C_mode.OFB = function () { 297 | // Call parent constructor 298 | Mode.apply(this, arguments); 299 | }; 300 | 301 | // Inherit from Mode 302 | var OFB_prototype = OFB.prototype = new Mode; 303 | 304 | // Override padding 305 | OFB_prototype._padding = C_pad.NoPadding; 306 | 307 | // Concrete steps for Mode template 308 | OFB_prototype._doEncrypt = function (cipher, m, iv) { 309 | 310 | var blockSizeInBytes = cipher._blocksize * 4, 311 | keystream = iv.slice(0); 312 | 313 | // Encrypt each byte 314 | for (var i = 0; i < m.length; i++) { 315 | 316 | // Generate keystream 317 | if (i % blockSizeInBytes == 0) 318 | cipher._encryptblock(keystream, 0); 319 | 320 | // Encrypt byte 321 | m[i] ^= keystream[i % blockSizeInBytes]; 322 | 323 | } 324 | }; 325 | OFB_prototype._doDecrypt = OFB_prototype._doEncrypt; 326 | 327 | /** 328 | * Counter 329 | * @author Gergely Risko 330 | * 331 | * After every block the last 4 bytes of the IV is increased by one 332 | * with carry and that IV is used for the next block. 333 | * 334 | * This is a stream cipher mode and does not require padding. 335 | */ 336 | var CTR = C_mode.CTR = function () { 337 | // Call parent constructor 338 | Mode.apply(this, arguments); 339 | }; 340 | 341 | // Inherit from Mode 342 | var CTR_prototype = CTR.prototype = new Mode; 343 | 344 | // Override padding 345 | CTR_prototype._padding = C_pad.NoPadding; 346 | 347 | CTR_prototype._doEncrypt = function (cipher, m, iv) { 348 | var blockSizeInBytes = cipher._blocksize * 4; 349 | var counter = iv.slice(0); 350 | 351 | for (var i = 0; i < m.length;) { 352 | // do not lose iv 353 | var keystream = counter.slice(0); 354 | 355 | // Generate keystream for next block 356 | cipher._encryptblock(keystream, 0); 357 | 358 | // XOR keystream with block 359 | for (var j = 0; i < m.length && j < blockSizeInBytes; j++, i++) { 360 | m[i] ^= keystream[j]; 361 | } 362 | 363 | // Increase counter 364 | if(++(counter[blockSizeInBytes-1]) == 256) { 365 | counter[blockSizeInBytes-1] = 0; 366 | if(++(counter[blockSizeInBytes-2]) == 256) { 367 | counter[blockSizeInBytes-2] = 0; 368 | if(++(counter[blockSizeInBytes-3]) == 256) { 369 | counter[blockSizeInBytes-3] = 0; 370 | ++(counter[blockSizeInBytes-4]); 371 | } 372 | } 373 | } 374 | } 375 | }; 376 | CTR_prototype._doDecrypt = CTR_prototype._doEncrypt; 377 | 378 | })(); 379 | -------------------------------------------------------------------------------- /lib/Crypto.js: -------------------------------------------------------------------------------- 1 | if (typeof Crypto == "undefined" || ! Crypto.util) 2 | { 3 | (function(){ 4 | 5 | var base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 6 | 7 | // Global Crypto object 8 | // with browser window or with node module 9 | var Crypto = (typeof window === 'undefined') ? exports.Crypto = {} : window.Crypto = {}; 10 | 11 | // Crypto utilities 12 | var util = Crypto.util = { 13 | 14 | // Bit-wise rotate left 15 | rotl: function (n, b) { 16 | return (n << b) | (n >>> (32 - b)); 17 | }, 18 | 19 | // Bit-wise rotate right 20 | rotr: function (n, b) { 21 | return (n << (32 - b)) | (n >>> b); 22 | }, 23 | 24 | // Swap big-endian to little-endian and vice versa 25 | endian: function (n) { 26 | 27 | // If number given, swap endian 28 | if (n.constructor == Number) { 29 | return util.rotl(n, 8) & 0x00FF00FF | 30 | util.rotl(n, 24) & 0xFF00FF00; 31 | } 32 | 33 | // Else, assume array and swap all items 34 | for (var i = 0; i < n.length; i++) 35 | n[i] = util.endian(n[i]); 36 | return n; 37 | 38 | }, 39 | 40 | // Generate an array of any length of random bytes 41 | randomBytes: function (n) { 42 | for (var bytes = []; n > 0; n--) 43 | bytes.push(Math.floor(Math.random() * 256)); 44 | return bytes; 45 | }, 46 | 47 | // Convert a byte array to big-endian 32-bit words 48 | bytesToWords: function (bytes) { 49 | for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8) 50 | words[b >>> 5] |= (bytes[i] & 0xFF) << (24 - b % 32); 51 | return words; 52 | }, 53 | 54 | // Convert big-endian 32-bit words to a byte array 55 | wordsToBytes: function (words) { 56 | for (var bytes = [], b = 0; b < words.length * 32; b += 8) 57 | bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF); 58 | return bytes; 59 | }, 60 | 61 | // Convert a byte array to a hex string 62 | bytesToHex: function (bytes) { 63 | for (var hex = [], i = 0; i < bytes.length; i++) { 64 | hex.push((bytes[i] >>> 4).toString(16)); 65 | hex.push((bytes[i] & 0xF).toString(16)); 66 | } 67 | return hex.join(""); 68 | }, 69 | 70 | // Convert a hex string to a byte array 71 | hexToBytes: function (hex) { 72 | for (var bytes = [], c = 0; c < hex.length; c += 2) 73 | bytes.push(parseInt(hex.substr(c, 2), 16)); 74 | return bytes; 75 | }, 76 | 77 | // Convert a byte array to a base-64 string 78 | bytesToBase64: function (bytes) { 79 | 80 | // Use browser-native function if it exists 81 | if (typeof btoa == "function") return btoa(Binary.bytesToString(bytes)); 82 | 83 | for(var base64 = [], i = 0; i < bytes.length; i += 3) { 84 | var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]; 85 | for (var j = 0; j < 4; j++) { 86 | if (i * 8 + j * 6 <= bytes.length * 8) 87 | base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F)); 88 | else base64.push("="); 89 | } 90 | } 91 | 92 | return base64.join(""); 93 | 94 | }, 95 | 96 | // Convert a base-64 string to a byte array 97 | base64ToBytes: function (base64) { 98 | 99 | // Use browser-native function if it exists 100 | if (typeof atob == "function") return Binary.stringToBytes(atob(base64)); 101 | 102 | // Remove non-base-64 characters 103 | base64 = base64.replace(/[^A-Z0-9+\/]/ig, ""); 104 | 105 | for (var bytes = [], i = 0, imod4 = 0; i < base64.length; imod4 = ++i % 4) { 106 | if (imod4 == 0) continue; 107 | bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2)) | 108 | (base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2))); 109 | } 110 | 111 | return bytes; 112 | 113 | } 114 | 115 | }; 116 | 117 | // Crypto character encodings 118 | var charenc = Crypto.charenc = {}; 119 | 120 | // UTF-8 encoding 121 | var UTF8 = charenc.UTF8 = { 122 | 123 | // Convert a string to a byte array 124 | stringToBytes: function (str) { 125 | return Binary.stringToBytes(unescape(encodeURIComponent(str))); 126 | }, 127 | 128 | // Convert a byte array to a string 129 | bytesToString: function (bytes) { 130 | return decodeURIComponent(escape(Binary.bytesToString(bytes))); 131 | } 132 | 133 | }; 134 | 135 | // Binary encoding 136 | var Binary = charenc.Binary = { 137 | 138 | // Convert a string to a byte array 139 | stringToBytes: function (str) { 140 | for (var bytes = [], i = 0; i < str.length; i++) 141 | bytes.push(str.charCodeAt(i) & 0xFF); 142 | return bytes; 143 | }, 144 | 145 | // Convert a byte array to a string 146 | bytesToString: function (bytes) { 147 | for (var str = [], i = 0; i < bytes.length; i++) 148 | str.push(String.fromCharCode(bytes[i])); 149 | return str.join(""); 150 | } 151 | 152 | }; 153 | 154 | })(); 155 | } 156 | -------------------------------------------------------------------------------- /lib/CryptoMath.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | 3 | var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto; 4 | 5 | // Shortcut 6 | var util = C.util; 7 | 8 | // Convert n to unsigned 32-bit integer 9 | util.u32 = function (n) { 10 | return n >>> 0; 11 | }; 12 | 13 | // Unsigned 32-bit addition 14 | util.add = function () { 15 | var result = this.u32(arguments[0]); 16 | for (var i = 1; i < arguments.length; i++) 17 | result = this.u32(result + this.u32(arguments[i])); 18 | return result; 19 | }; 20 | 21 | // Unsigned 32-bit multiplication 22 | util.mult = function (m, n) { 23 | return this.add((n & 0xFFFF0000) * m, 24 | (n & 0x0000FFFF) * m); 25 | }; 26 | 27 | // Unsigned 32-bit greater than (>) comparison 28 | util.gt = function (m, n) { 29 | return this.u32(m) > this.u32(n); 30 | }; 31 | 32 | // Unsigned 32-bit less than (<) comparison 33 | util.lt = function (m, n) { 34 | return this.u32(m) < this.u32(n); 35 | }; 36 | 37 | })(); 38 | -------------------------------------------------------------------------------- /lib/DES.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition of Data Encryption Standard (DES) taken from: 3 | * http://www.itl.nist.gov/fipspubs/fip46-2.htm 4 | */ 5 | 6 | (function() { 7 | 8 | var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto; 9 | 10 | // Shortcuts 11 | var util = C.util, charenc = C.charenc, UTF8 = charenc.UTF8; 12 | 13 | /*************************************************************************** 14 | * 15 | * DES Key Schedule. 16 | * 17 | * The Key consists of 16 sub-keys of 48 bits each. As each sub-key is 18 | * applied to an expanded 32-bit value where each 4 bits of input is 19 | * expanded into 6 bits of output the sub-key can be broken down into 8 20 | * 32-bit values which allows the key to be used without expansion. 21 | * 22 | * To create the 16 sub-keys, 56 bits are selected from the input 64 bit key 23 | * according to PC1. Each sub-key is generated by left rotating the 24 | * bits a different amount and then selecting 48 bits according to PC2. 25 | * 26 | **************************************************************************/ 27 | 28 | var KeySchedule; 29 | 30 | /** 31 | * Representation of a DES key schedule. 32 | * 33 | * @param {Array 34 | * of 8 bytes} key The cipher key 35 | * 36 | * @constructor 37 | */ 38 | KeySchedule = function(key) { 39 | /** 40 | * The schedule of 16 keys 41 | */ 42 | this.keys = new Array(16); 43 | this._initialiseKeys(key); 44 | }; 45 | 46 | /** 47 | * Permuted Choice 1 (PC1) byte offsets into the key. Each of the 56 entries 48 | * selects one bit of DES's 56 bit key. 49 | *
50 | * 51 | *
52 | * The PC1 is defined as: 53 | * 54 | * 57, 49, 41, 33, 25, 17, 9, 55 | * 1, 58, 50, 42, 34, 26, 18, 56 | * 10, 2, 59, 51, 43, 35, 27, 57 | * 19, 11, 3, 60, 52, 44, 36, 58 | * 63, 55, 47, 39, 31, 23, 15, 59 | * 7, 62, 54, 46, 38, 30, 22, 60 | * 14, 6, 61, 53, 45, 37, 29, 61 | * 21, 13, 5, 28, 20, 12, 4 62 | *63 | * 64 | * We represent this as an offset into an 8-byte array and a bit mask upon 65 | * that byte. For example 57=(7*8)+1 so is the first (MSB) of the 7th byte. 66 | * 67 | * @constant 68 | */ 69 | KeySchedule.PC1_offsets = [ 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 70 | 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 71 | 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 3, 2, 1, 0 ]; 72 | 73 | /** 74 | * Permuted Choice 1 (PC1) bit masks. Each of the 56 entries selects one bit 75 | * of DES's 56 bit key. 76 | * 77 | * @constant 78 | */ 79 | KeySchedule.PC1_masks = [ 128, 128, 128, 128, 128, 128, 128, 128, 64, 64, 80 | 64, 64, 64, 64, 64, 64, 32, 32, 32, 32, 32, 32, 32, 32, 16, 16, 16, 81 | 16, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 82 | 8, 8, 8, 16, 16, 16, 16 ]; 83 | 84 | /** 85 | * Permuted Choice 2 (PC2) selects the active 48 bits from the 56 bits of 86 | * the key. 87 | *
88 | * 89 | *
90 | * The PC2 is defined as: 91 | * 92 | * 14, 17, 11, 24, 1, 5, 93 | * 3, 28, 15, 6, 21, 10, 94 | * 23, 19, 12, 4, 26, 8, 95 | * 16, 7, 27, 20, 13, 2, 96 | * 41, 52, 31, 37, 47, 55, 97 | * 30, 40, 51, 45, 33, 48, 98 | * 44, 49, 39, 56, 34, 53, 99 | * 46, 42, 50, 36, 29, 32 100 | *101 | * 102 | * We invert the choice to specify what each bit adds to each 6-bit value of 103 | * the key. For example, bit 1 is the 5th bit selected so this add 2 to the 104 | * first 6-bit value. 105 | * 106 | * @constant 107 | */ 108 | KeySchedule.PC2_offsets1 = [ 0, 3, 1, 2, 0, 1, 3, 2, 0, 1, 0, 2, 3, 0, 1, 109 | 3, 0, 0, 2, 3, 1, 0, 2, 0, 0, 2, 3, 1 ]; 110 | 111 | /** 112 | * PC2 offsets for 2nd block. 113 | * 114 | * @constant 115 | */ 116 | KeySchedule.PC2_offsets2 = [ 7, 5, 4, 7, 5, 6, 0, 7, 4, 0, 6, 5, 4, 7, 0, 117 | 6, 5, 7, 4, 5, 6, 7, 5, 4, 6, 0, 4, 6 ]; 118 | 119 | /** 120 | * Permuted Choice 2 (PC2) masks for 1st block. 121 | * 122 | * @constant 123 | */ 124 | KeySchedule.PC2_masks1 = [ 2, 1, 32, 4, 1, 4, 16, 1, 0, 1, 8, 8, 2, 32, 8, 125 | 32, 16, 0, 16, 4, 2, 0, 32, 4, 0, 2, 8, 16 ]; 126 | 127 | /** 128 | * PC2 masks for 2nd block. 129 | * 130 | * @constant 131 | */ 132 | KeySchedule.PC2_masks2 = [ 2, 32, 8, 1, 2, 2, 0, 4, 4, 0, 8, 16, 32, 16, 0, 133 | 32, 4, 32, 2, 1, 16, 8, 8, 16, 1, 0, 1, 4 ]; 134 | 135 | /** 136 | * Cumulative key shifts. 137 | * 138 | * @constant 139 | */ 140 | KeySchedule.keyShifts = [ 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 141 | 25, 27, 28 ]; 142 | 143 | KeySchedule.prototype._initialiseKeys = function(key) { 144 | var i; 145 | 146 | // extract 56 key bits in order determined by PC1 147 | var bits = new Array(56); 148 | for (i = 0; i < 56; i++) { 149 | bits[i] = (key[KeySchedule.PC1_offsets[i]] & KeySchedule.PC1_masks[i]) != 0; 150 | } 151 | 152 | // split 56 bits into two 28-bit chunks 153 | var bits1 = bits.slice(0, 28); 154 | var bits2 = bits.slice(28, 56); 155 | 156 | // duplicate each half to allow for easy bit shifts 157 | bits1 = bits1.concat(bits1); 158 | bits2 = bits2.concat(bits2); 159 | 160 | // assemble the 16 keys 161 | for (i = 0; i < 16; i++) { 162 | var k = [ 0, 0, 0, 0, 0, 0, 0, 0 ]; 163 | 164 | // select the bits of the key according to PC2 165 | var s = KeySchedule.keyShifts[i]; 166 | for ( var j = 0; j < 28; j++) { 167 | if (bits1[j + s]) { 168 | k[KeySchedule.PC2_offsets1[j]] += KeySchedule.PC2_masks1[j]; 169 | } 170 | if (bits2[j + s]) { 171 | k[KeySchedule.PC2_offsets2[j]] += KeySchedule.PC2_masks2[j]; 172 | } 173 | } 174 | 175 | // Scale each of the 8 blocks to a 32-bit mask. 176 | k[0] = ((k[0] & 0x1f) << 27) + ((k[0] & 0x20) >> 5); 177 | for ( var j = 1; j <= 6; j++) { 178 | k[j] = k[j] << (27 - 4 * j); 179 | } 180 | k[7] = ((k[7] & 0x3e) >> 1) + ((k[7] & 0x1) << 31); 181 | this.keys[i] = k; 182 | } 183 | }; 184 | 185 | /** 186 | * Retrieve the key for a specified round 187 | * 188 | * @param i 189 | * the round 190 | * @returns the key 191 | */ 192 | KeySchedule.prototype.getKey = function(i) { 193 | return this.keys[i]; 194 | }; 195 | 196 | /*************************************************************************** 197 | * 198 | * DES Engine State 199 | * 200 | **************************************************************************/ 201 | 202 | var State; 203 | 204 | /** 205 | * The algorithm's state. DES operates on two sets of 32-bits, with each 206 | * block of 32-bits treated as a single number. 207 | * 208 | * @class 209 | */ 210 | State = function() { 211 | /** The LHS of the Feistel scheme */ 212 | this.lhs = 0; 213 | /** The RHS of the Feistel scheme */ 214 | this.rhs = 0; 215 | }; 216 | 217 | /** 218 | * The masks that select the SBOX input. Each SBOX accepts 6 bits from the 219 | * input. 220 | * 221 | * @constant 222 | */ 223 | State.SBOX_MASK = [ 0xf8000001, 0x1f800000, 0x01f80000, 0x001f8000, 224 | 0x0001f800, 0x00001f80, 0x000001f8, 0x8000001f ]; 225 | 226 | /** 227 | * The SBOXes. The 8 SBOXes each map 6 bit masked bit of the input to 4 bits 228 | * of output. These SBOXes include the post SBOX permutation and benefit 229 | * from JavaScript's sparse arrays to make specifying the input match 230 | * simple. 231 | * 232 | * @constant 233 | */ 234 | State.SBOX = new Array(8); 235 | 236 | var SBOX = State.SBOX; 237 | 238 | SBOX[0] = new Array(); 239 | SBOX[0][0] = 0x808200; // 0 (0, 0) = 14 240 | SBOX[0][268435456] = 0x8000; // 10000000 (0, 1) = 4 241 | SBOX[0][536870912] = 0x808002; // 20000000 (0, 2) = 13 242 | SBOX[0][805306368] = 0x2; // 30000000 (0, 3) = 1 243 | SBOX[0][1073741824] = 0x200; // 40000000 (0, 4) = 2 244 | SBOX[0][1342177280] = 0x808202; // 50000000 (0, 5) = 15 245 | SBOX[0][1610612736] = 0x800202; // 60000000 (0, 6) = 11 246 | SBOX[0][1879048192] = 0x800000; // 70000000 (0, 7) = 8 247 | SBOX[0][-2147483648] = 0x202; // 80000000 (0, 8) = 3 248 | SBOX[0][-1879048192] = 0x800200; // 90000000 (0, 9) = 10 249 | SBOX[0][-1610612736] = 0x8200; // a0000000 (0, 10) = 6 250 | SBOX[0][-1342177280] = 0x808000; // b0000000 (0, 11) = 12 251 | SBOX[0][-1073741824] = 0x8002; // c0000000 (0, 12) = 5 252 | SBOX[0][-805306368] = 0x800002; // d0000000 (0, 13) = 9 253 | SBOX[0][-536870912] = 0x0; // e0000000 (0, 14) = 0 254 | SBOX[0][-268435456] = 0x8202; // f0000000 (0, 15) = 7 255 | SBOX[0][134217728] = 0x0; // 8000000 (1, 0) = 0 256 | SBOX[0][402653184] = 0x808202; // 18000000 (1, 1) = 15 257 | SBOX[0][671088640] = 0x8202; // 28000000 (1, 2) = 7 258 | SBOX[0][939524096] = 0x8000; // 38000000 (1, 3) = 4 259 | SBOX[0][1207959552] = 0x808200; // 48000000 (1, 4) = 14 260 | SBOX[0][1476395008] = 0x200; // 58000000 (1, 5) = 2 261 | SBOX[0][1744830464] = 0x808002; // 68000000 (1, 6) = 13 262 | SBOX[0][2013265920] = 0x2; // 78000000 (1, 7) = 1 263 | SBOX[0][-2013265920] = 0x800200; // 88000000 (1, 8) = 10 264 | SBOX[0][-1744830464] = 0x8200; // 98000000 (1, 9) = 6 265 | SBOX[0][-1476395008] = 0x808000; // a8000000 (1, 10) = 12 266 | SBOX[0][-1207959552] = 0x800202; // b8000000 (1, 11) = 11 267 | SBOX[0][-939524096] = 0x800002; // c8000000 (1, 12) = 9 268 | SBOX[0][-671088640] = 0x8002; // d8000000 (1, 13) = 5 269 | SBOX[0][-402653184] = 0x202; // e8000000 (1, 14) = 3 270 | SBOX[0][-134217728] = 0x800000; // f8000000 (1, 15) = 8 271 | SBOX[0][1] = 0x8000; // 1 (2, 0) = 4 272 | SBOX[0][268435457] = 0x2; // 10000001 (2, 1) = 1 273 | SBOX[0][536870913] = 0x808200; // 20000001 (2, 2) = 14 274 | SBOX[0][805306369] = 0x800000; // 30000001 (2, 3) = 8 275 | SBOX[0][1073741825] = 0x808002; // 40000001 (2, 4) = 13 276 | SBOX[0][1342177281] = 0x8200; // 50000001 (2, 5) = 6 277 | SBOX[0][1610612737] = 0x200; // 60000001 (2, 6) = 2 278 | SBOX[0][1879048193] = 0x800202; // 70000001 (2, 7) = 11 279 | SBOX[0][-2147483647] = 0x808202; // 80000001 (2, 8) = 15 280 | SBOX[0][-1879048191] = 0x808000; // 90000001 (2, 9) = 12 281 | SBOX[0][-1610612735] = 0x800002; // a0000001 (2, 10) = 9 282 | SBOX[0][-1342177279] = 0x8202; // b0000001 (2, 11) = 7 283 | SBOX[0][-1073741823] = 0x202; // c0000001 (2, 12) = 3 284 | SBOX[0][-805306367] = 0x800200; // d0000001 (2, 13) = 10 285 | SBOX[0][-536870911] = 0x8002; // e0000001 (2, 14) = 5 286 | SBOX[0][-268435455] = 0x0; // f0000001 (2, 15) = 0 287 | SBOX[0][134217729] = 0x808202; // 8000001 (3, 0) = 15 288 | SBOX[0][402653185] = 0x808000; // 18000001 (3, 1) = 12 289 | SBOX[0][671088641] = 0x800000; // 28000001 (3, 2) = 8 290 | SBOX[0][939524097] = 0x200; // 38000001 (3, 3) = 2 291 | SBOX[0][1207959553] = 0x8000; // 48000001 (3, 4) = 4 292 | SBOX[0][1476395009] = 0x800002; // 58000001 (3, 5) = 9 293 | SBOX[0][1744830465] = 0x2; // 68000001 (3, 6) = 1 294 | SBOX[0][2013265921] = 0x8202; // 78000001 (3, 7) = 7 295 | SBOX[0][-2013265919] = 0x8002; // 88000001 (3, 8) = 5 296 | SBOX[0][-1744830463] = 0x800202; // 98000001 (3, 9) = 11 297 | SBOX[0][-1476395007] = 0x202; // a8000001 (3, 10) = 3 298 | SBOX[0][-1207959551] = 0x808200; // b8000001 (3, 11) = 14 299 | SBOX[0][-939524095] = 0x800200; // c8000001 (3, 12) = 10 300 | SBOX[0][-671088639] = 0x0; // d8000001 (3, 13) = 0 301 | SBOX[0][-402653183] = 0x8200; // e8000001 (3, 14) = 6 302 | SBOX[0][-134217727] = 0x808002; // f8000001 (3, 15) = 13 303 | 304 | SBOX[1] = new Array(); 305 | SBOX[1][0] = 0x40084010; // 0 (0, 0) = 15 306 | SBOX[1][16777216] = 0x4000; // 1000000 (0, 1) = 1 307 | SBOX[1][33554432] = 0x80000; // 2000000 (0, 2) = 8 308 | SBOX[1][50331648] = 0x40080010; // 3000000 (0, 3) = 14 309 | SBOX[1][67108864] = 0x40000010; // 4000000 (0, 4) = 6 310 | SBOX[1][83886080] = 0x40084000; // 5000000 (0, 5) = 11 311 | SBOX[1][100663296] = 0x40004000; // 6000000 (0, 6) = 3 312 | SBOX[1][117440512] = 0x10; // 7000000 (0, 7) = 4 313 | SBOX[1][134217728] = 0x84000; // 8000000 (0, 8) = 9 314 | SBOX[1][150994944] = 0x40004010; // 9000000 (0, 9) = 7 315 | SBOX[1][167772160] = 0x40000000; // a000000 (0, 10) = 2 316 | SBOX[1][184549376] = 0x84010; // b000000 (0, 11) = 13 317 | SBOX[1][201326592] = 0x80010; // c000000 (0, 12) = 12 318 | SBOX[1][218103808] = 0x0; // d000000 (0, 13) = 0 319 | SBOX[1][234881024] = 0x4010; // e000000 (0, 14) = 5 320 | SBOX[1][251658240] = 0x40080000; // f000000 (0, 15) = 10 321 | SBOX[1][8388608] = 0x40004000; // 800000 (1, 0) = 3 322 | SBOX[1][25165824] = 0x84010; // 1800000 (1, 1) = 13 323 | SBOX[1][41943040] = 0x10; // 2800000 (1, 2) = 4 324 | SBOX[1][58720256] = 0x40004010; // 3800000 (1, 3) = 7 325 | SBOX[1][75497472] = 0x40084010; // 4800000 (1, 4) = 15 326 | SBOX[1][92274688] = 0x40000000; // 5800000 (1, 5) = 2 327 | SBOX[1][109051904] = 0x80000; // 6800000 (1, 6) = 8 328 | SBOX[1][125829120] = 0x40080010; // 7800000 (1, 7) = 14 329 | SBOX[1][142606336] = 0x80010; // 8800000 (1, 8) = 12 330 | SBOX[1][159383552] = 0x0; // 9800000 (1, 9) = 0 331 | SBOX[1][176160768] = 0x4000; // a800000 (1, 10) = 1 332 | SBOX[1][192937984] = 0x40080000; // b800000 (1, 11) = 10 333 | SBOX[1][209715200] = 0x40000010; // c800000 (1, 12) = 6 334 | SBOX[1][226492416] = 0x84000; // d800000 (1, 13) = 9 335 | SBOX[1][243269632] = 0x40084000; // e800000 (1, 14) = 11 336 | SBOX[1][260046848] = 0x4010; // f800000 (1, 15) = 5 337 | SBOX[1][268435456] = 0x0; // 10000000 (2, 0) = 0 338 | SBOX[1][285212672] = 0x40080010; // 11000000 (2, 1) = 14 339 | SBOX[1][301989888] = 0x40004010; // 12000000 (2, 2) = 7 340 | SBOX[1][318767104] = 0x40084000; // 13000000 (2, 3) = 11 341 | SBOX[1][335544320] = 0x40080000; // 14000000 (2, 4) = 10 342 | SBOX[1][352321536] = 0x10; // 15000000 (2, 5) = 4 343 | SBOX[1][369098752] = 0x84010; // 16000000 (2, 6) = 13 344 | SBOX[1][385875968] = 0x4000; // 17000000 (2, 7) = 1 345 | SBOX[1][402653184] = 0x4010; // 18000000 (2, 8) = 5 346 | SBOX[1][419430400] = 0x80000; // 19000000 (2, 9) = 8 347 | SBOX[1][436207616] = 0x80010; // 1a000000 (2, 10) = 12 348 | SBOX[1][452984832] = 0x40000010; // 1b000000 (2, 11) = 6 349 | SBOX[1][469762048] = 0x84000; // 1c000000 (2, 12) = 9 350 | SBOX[1][486539264] = 0x40004000; // 1d000000 (2, 13) = 3 351 | SBOX[1][503316480] = 0x40000000; // 1e000000 (2, 14) = 2 352 | SBOX[1][520093696] = 0x40084010; // 1f000000 (2, 15) = 15 353 | SBOX[1][276824064] = 0x84010; // 10800000 (3, 0) = 13 354 | SBOX[1][293601280] = 0x80000; // 11800000 (3, 1) = 8 355 | SBOX[1][310378496] = 0x40080000; // 12800000 (3, 2) = 10 356 | SBOX[1][327155712] = 0x4000; // 13800000 (3, 3) = 1 357 | SBOX[1][343932928] = 0x40004000; // 14800000 (3, 4) = 3 358 | SBOX[1][360710144] = 0x40084010; // 15800000 (3, 5) = 15 359 | SBOX[1][377487360] = 0x10; // 16800000 (3, 6) = 4 360 | SBOX[1][394264576] = 0x40000000; // 17800000 (3, 7) = 2 361 | SBOX[1][411041792] = 0x40084000; // 18800000 (3, 8) = 11 362 | SBOX[1][427819008] = 0x40000010; // 19800000 (3, 9) = 6 363 | SBOX[1][444596224] = 0x40004010; // 1a800000 (3, 10) = 7 364 | SBOX[1][461373440] = 0x80010; // 1b800000 (3, 11) = 12 365 | SBOX[1][478150656] = 0x0; // 1c800000 (3, 12) = 0 366 | SBOX[1][494927872] = 0x4010; // 1d800000 (3, 13) = 5 367 | SBOX[1][511705088] = 0x40080010; // 1e800000 (3, 14) = 14 368 | SBOX[1][528482304] = 0x84000; // 1f800000 (3, 15) = 9 369 | 370 | SBOX[2] = new Array(); 371 | SBOX[2][0] = 0x104; // 0 (0, 0) = 10 372 | SBOX[2][1048576] = 0x0; // 100000 (0, 1) = 0 373 | SBOX[2][2097152] = 0x4000100; // 200000 (0, 2) = 9 374 | SBOX[2][3145728] = 0x10104; // 300000 (0, 3) = 14 375 | SBOX[2][4194304] = 0x10004; // 400000 (0, 4) = 6 376 | SBOX[2][5242880] = 0x4000004; // 500000 (0, 5) = 3 377 | SBOX[2][6291456] = 0x4010104; // 600000 (0, 6) = 15 378 | SBOX[2][7340032] = 0x4010000; // 700000 (0, 7) = 5 379 | SBOX[2][8388608] = 0x4000000; // 800000 (0, 8) = 1 380 | SBOX[2][9437184] = 0x4010100; // 900000 (0, 9) = 13 381 | SBOX[2][10485760] = 0x10100; // a00000 (0, 10) = 12 382 | SBOX[2][11534336] = 0x4010004; // b00000 (0, 11) = 7 383 | SBOX[2][12582912] = 0x4000104; // c00000 (0, 12) = 11 384 | SBOX[2][13631488] = 0x10000; // d00000 (0, 13) = 4 385 | SBOX[2][14680064] = 0x4; // e00000 (0, 14) = 2 386 | SBOX[2][15728640] = 0x100; // f00000 (0, 15) = 8 387 | SBOX[2][524288] = 0x4010100; // 80000 (1, 0) = 13 388 | SBOX[2][1572864] = 0x4010004; // 180000 (1, 1) = 7 389 | SBOX[2][2621440] = 0x0; // 280000 (1, 2) = 0 390 | SBOX[2][3670016] = 0x4000100; // 380000 (1, 3) = 9 391 | SBOX[2][4718592] = 0x4000004; // 480000 (1, 4) = 3 392 | SBOX[2][5767168] = 0x10000; // 580000 (1, 5) = 4 393 | SBOX[2][6815744] = 0x10004; // 680000 (1, 6) = 6 394 | SBOX[2][7864320] = 0x104; // 780000 (1, 7) = 10 395 | SBOX[2][8912896] = 0x4; // 880000 (1, 8) = 2 396 | SBOX[2][9961472] = 0x100; // 980000 (1, 9) = 8 397 | SBOX[2][11010048] = 0x4010000; // a80000 (1, 10) = 5 398 | SBOX[2][12058624] = 0x10104; // b80000 (1, 11) = 14 399 | SBOX[2][13107200] = 0x10100; // c80000 (1, 12) = 12 400 | SBOX[2][14155776] = 0x4000104; // d80000 (1, 13) = 11 401 | SBOX[2][15204352] = 0x4010104; // e80000 (1, 14) = 15 402 | SBOX[2][16252928] = 0x4000000; // f80000 (1, 15) = 1 403 | SBOX[2][16777216] = 0x4010100; // 1000000 (2, 0) = 13 404 | SBOX[2][17825792] = 0x10004; // 1100000 (2, 1) = 6 405 | SBOX[2][18874368] = 0x10000; // 1200000 (2, 2) = 4 406 | SBOX[2][19922944] = 0x4000100; // 1300000 (2, 3) = 9 407 | SBOX[2][20971520] = 0x100; // 1400000 (2, 4) = 8 408 | SBOX[2][22020096] = 0x4010104; // 1500000 (2, 5) = 15 409 | SBOX[2][23068672] = 0x4000004; // 1600000 (2, 6) = 3 410 | SBOX[2][24117248] = 0x0; // 1700000 (2, 7) = 0 411 | SBOX[2][25165824] = 0x4000104; // 1800000 (2, 8) = 11 412 | SBOX[2][26214400] = 0x4000000; // 1900000 (2, 9) = 1 413 | SBOX[2][27262976] = 0x4; // 1a00000 (2, 10) = 2 414 | SBOX[2][28311552] = 0x10100; // 1b00000 (2, 11) = 12 415 | SBOX[2][29360128] = 0x4010000; // 1c00000 (2, 12) = 5 416 | SBOX[2][30408704] = 0x104; // 1d00000 (2, 13) = 10 417 | SBOX[2][31457280] = 0x10104; // 1e00000 (2, 14) = 14 418 | SBOX[2][32505856] = 0x4010004; // 1f00000 (2, 15) = 7 419 | SBOX[2][17301504] = 0x4000000; // 1080000 (3, 0) = 1 420 | SBOX[2][18350080] = 0x104; // 1180000 (3, 1) = 10 421 | SBOX[2][19398656] = 0x4010100; // 1280000 (3, 2) = 13 422 | SBOX[2][20447232] = 0x0; // 1380000 (3, 3) = 0 423 | SBOX[2][21495808] = 0x10004; // 1480000 (3, 4) = 6 424 | SBOX[2][22544384] = 0x4000100; // 1580000 (3, 5) = 9 425 | SBOX[2][23592960] = 0x100; // 1680000 (3, 6) = 8 426 | SBOX[2][24641536] = 0x4010004; // 1780000 (3, 7) = 7 427 | SBOX[2][25690112] = 0x10000; // 1880000 (3, 8) = 4 428 | SBOX[2][26738688] = 0x4010104; // 1980000 (3, 9) = 15 429 | SBOX[2][27787264] = 0x10104; // 1a80000 (3, 10) = 14 430 | SBOX[2][28835840] = 0x4000004; // 1b80000 (3, 11) = 3 431 | SBOX[2][29884416] = 0x4000104; // 1c80000 (3, 12) = 11 432 | SBOX[2][30932992] = 0x4010000; // 1d80000 (3, 13) = 5 433 | SBOX[2][31981568] = 0x4; // 1e80000 (3, 14) = 2 434 | SBOX[2][33030144] = 0x10100; // 1f80000 (3, 15) = 12 435 | 436 | SBOX[3] = new Array(); 437 | SBOX[3][0] = 0x80401000; // 0 (0, 0) = 7 438 | SBOX[3][65536] = 0x80001040; // 10000 (0, 1) = 13 439 | SBOX[3][131072] = 0x401040; // 20000 (0, 2) = 14 440 | SBOX[3][196608] = 0x80400000; // 30000 (0, 3) = 3 441 | SBOX[3][262144] = 0x0; // 40000 (0, 4) = 0 442 | SBOX[3][327680] = 0x401000; // 50000 (0, 5) = 6 443 | SBOX[3][393216] = 0x80000040; // 60000 (0, 6) = 9 444 | SBOX[3][458752] = 0x400040; // 70000 (0, 7) = 10 445 | SBOX[3][524288] = 0x80000000; // 80000 (0, 8) = 1 446 | SBOX[3][589824] = 0x400000; // 90000 (0, 9) = 2 447 | SBOX[3][655360] = 0x40; // a0000 (0, 10) = 8 448 | SBOX[3][720896] = 0x80001000; // b0000 (0, 11) = 5 449 | SBOX[3][786432] = 0x80400040; // c0000 (0, 12) = 11 450 | SBOX[3][851968] = 0x1040; // d0000 (0, 13) = 12 451 | SBOX[3][917504] = 0x1000; // e0000 (0, 14) = 4 452 | SBOX[3][983040] = 0x80401040; // f0000 (0, 15) = 15 453 | SBOX[3][32768] = 0x80001040; // 8000 (1, 0) = 13 454 | SBOX[3][98304] = 0x40; // 18000 (1, 1) = 8 455 | SBOX[3][163840] = 0x80400040; // 28000 (1, 2) = 11 456 | SBOX[3][229376] = 0x80001000; // 38000 (1, 3) = 5 457 | SBOX[3][294912] = 0x401000; // 48000 (1, 4) = 6 458 | SBOX[3][360448] = 0x80401040; // 58000 (1, 5) = 15 459 | SBOX[3][425984] = 0x0; // 68000 (1, 6) = 0 460 | SBOX[3][491520] = 0x80400000; // 78000 (1, 7) = 3 461 | SBOX[3][557056] = 0x1000; // 88000 (1, 8) = 4 462 | SBOX[3][622592] = 0x80401000; // 98000 (1, 9) = 7 463 | SBOX[3][688128] = 0x400000; // a8000 (1, 10) = 2 464 | SBOX[3][753664] = 0x1040; // b8000 (1, 11) = 12 465 | SBOX[3][819200] = 0x80000000; // c8000 (1, 12) = 1 466 | SBOX[3][884736] = 0x400040; // d8000 (1, 13) = 10 467 | SBOX[3][950272] = 0x401040; // e8000 (1, 14) = 14 468 | SBOX[3][1015808] = 0x80000040; // f8000 (1, 15) = 9 469 | SBOX[3][1048576] = 0x400040; // 100000 (2, 0) = 10 470 | SBOX[3][1114112] = 0x401000; // 110000 (2, 1) = 6 471 | SBOX[3][1179648] = 0x80000040; // 120000 (2, 2) = 9 472 | SBOX[3][1245184] = 0x0; // 130000 (2, 3) = 0 473 | SBOX[3][1310720] = 0x1040; // 140000 (2, 4) = 12 474 | SBOX[3][1376256] = 0x80400040; // 150000 (2, 5) = 11 475 | SBOX[3][1441792] = 0x80401000; // 160000 (2, 6) = 7 476 | SBOX[3][1507328] = 0x80001040; // 170000 (2, 7) = 13 477 | SBOX[3][1572864] = 0x80401040; // 180000 (2, 8) = 15 478 | SBOX[3][1638400] = 0x80000000; // 190000 (2, 9) = 1 479 | SBOX[3][1703936] = 0x80400000; // 1a0000 (2, 10) = 3 480 | SBOX[3][1769472] = 0x401040; // 1b0000 (2, 11) = 14 481 | SBOX[3][1835008] = 0x80001000; // 1c0000 (2, 12) = 5 482 | SBOX[3][1900544] = 0x400000; // 1d0000 (2, 13) = 2 483 | SBOX[3][1966080] = 0x40; // 1e0000 (2, 14) = 8 484 | SBOX[3][2031616] = 0x1000; // 1f0000 (2, 15) = 4 485 | SBOX[3][1081344] = 0x80400000; // 108000 (3, 0) = 3 486 | SBOX[3][1146880] = 0x80401040; // 118000 (3, 1) = 15 487 | SBOX[3][1212416] = 0x0; // 128000 (3, 2) = 0 488 | SBOX[3][1277952] = 0x401000; // 138000 (3, 3) = 6 489 | SBOX[3][1343488] = 0x400040; // 148000 (3, 4) = 10 490 | SBOX[3][1409024] = 0x80000000; // 158000 (3, 5) = 1 491 | SBOX[3][1474560] = 0x80001040; // 168000 (3, 6) = 13 492 | SBOX[3][1540096] = 0x40; // 178000 (3, 7) = 8 493 | SBOX[3][1605632] = 0x80000040; // 188000 (3, 8) = 9 494 | SBOX[3][1671168] = 0x1000; // 198000 (3, 9) = 4 495 | SBOX[3][1736704] = 0x80001000; // 1a8000 (3, 10) = 5 496 | SBOX[3][1802240] = 0x80400040; // 1b8000 (3, 11) = 11 497 | SBOX[3][1867776] = 0x1040; // 1c8000 (3, 12) = 12 498 | SBOX[3][1933312] = 0x80401000; // 1d8000 (3, 13) = 7 499 | SBOX[3][1998848] = 0x400000; // 1e8000 (3, 14) = 2 500 | SBOX[3][2064384] = 0x401040; // 1f8000 (3, 15) = 14 501 | 502 | SBOX[4] = new Array(); 503 | SBOX[4][0] = 0x80; // 0 (0, 0) = 2 504 | SBOX[4][4096] = 0x1040000; // 1000 (0, 1) = 12 505 | SBOX[4][8192] = 0x40000; // 2000 (0, 2) = 4 506 | SBOX[4][12288] = 0x20000000; // 3000 (0, 3) = 1 507 | SBOX[4][16384] = 0x20040080; // 4000 (0, 4) = 7 508 | SBOX[4][20480] = 0x1000080; // 5000 (0, 5) = 10 509 | SBOX[4][24576] = 0x21000080; // 6000 (0, 6) = 11 510 | SBOX[4][28672] = 0x40080; // 7000 (0, 7) = 6 511 | SBOX[4][32768] = 0x1000000; // 8000 (0, 8) = 8 512 | SBOX[4][36864] = 0x20040000; // 9000 (0, 9) = 5 513 | SBOX[4][40960] = 0x20000080; // a000 (0, 10) = 3 514 | SBOX[4][45056] = 0x21040080; // b000 (0, 11) = 15 515 | SBOX[4][49152] = 0x21040000; // c000 (0, 12) = 13 516 | SBOX[4][53248] = 0x0; // d000 (0, 13) = 0 517 | SBOX[4][57344] = 0x1040080; // e000 (0, 14) = 14 518 | SBOX[4][61440] = 0x21000000; // f000 (0, 15) = 9 519 | SBOX[4][2048] = 0x1040080; // 800 (1, 0) = 14 520 | SBOX[4][6144] = 0x21000080; // 1800 (1, 1) = 11 521 | SBOX[4][10240] = 0x80; // 2800 (1, 2) = 2 522 | SBOX[4][14336] = 0x1040000; // 3800 (1, 3) = 12 523 | SBOX[4][18432] = 0x40000; // 4800 (1, 4) = 4 524 | SBOX[4][22528] = 0x20040080; // 5800 (1, 5) = 7 525 | SBOX[4][26624] = 0x21040000; // 6800 (1, 6) = 13 526 | SBOX[4][30720] = 0x20000000; // 7800 (1, 7) = 1 527 | SBOX[4][34816] = 0x20040000; // 8800 (1, 8) = 5 528 | SBOX[4][38912] = 0x0; // 9800 (1, 9) = 0 529 | SBOX[4][43008] = 0x21040080; // a800 (1, 10) = 15 530 | SBOX[4][47104] = 0x1000080; // b800 (1, 11) = 10 531 | SBOX[4][51200] = 0x20000080; // c800 (1, 12) = 3 532 | SBOX[4][55296] = 0x21000000; // d800 (1, 13) = 9 533 | SBOX[4][59392] = 0x1000000; // e800 (1, 14) = 8 534 | SBOX[4][63488] = 0x40080; // f800 (1, 15) = 6 535 | SBOX[4][65536] = 0x40000; // 10000 (2, 0) = 4 536 | SBOX[4][69632] = 0x80; // 11000 (2, 1) = 2 537 | SBOX[4][73728] = 0x20000000; // 12000 (2, 2) = 1 538 | SBOX[4][77824] = 0x21000080; // 13000 (2, 3) = 11 539 | SBOX[4][81920] = 0x1000080; // 14000 (2, 4) = 10 540 | SBOX[4][86016] = 0x21040000; // 15000 (2, 5) = 13 541 | SBOX[4][90112] = 0x20040080; // 16000 (2, 6) = 7 542 | SBOX[4][94208] = 0x1000000; // 17000 (2, 7) = 8 543 | SBOX[4][98304] = 0x21040080; // 18000 (2, 8) = 15 544 | SBOX[4][102400] = 0x21000000; // 19000 (2, 9) = 9 545 | SBOX[4][106496] = 0x1040000; // 1a000 (2, 10) = 12 546 | SBOX[4][110592] = 0x20040000; // 1b000 (2, 11) = 5 547 | SBOX[4][114688] = 0x40080; // 1c000 (2, 12) = 6 548 | SBOX[4][118784] = 0x20000080; // 1d000 (2, 13) = 3 549 | SBOX[4][122880] = 0x0; // 1e000 (2, 14) = 0 550 | SBOX[4][126976] = 0x1040080; // 1f000 (2, 15) = 14 551 | SBOX[4][67584] = 0x21000080; // 10800 (3, 0) = 11 552 | SBOX[4][71680] = 0x1000000; // 11800 (3, 1) = 8 553 | SBOX[4][75776] = 0x1040000; // 12800 (3, 2) = 12 554 | SBOX[4][79872] = 0x20040080; // 13800 (3, 3) = 7 555 | SBOX[4][83968] = 0x20000000; // 14800 (3, 4) = 1 556 | SBOX[4][88064] = 0x1040080; // 15800 (3, 5) = 14 557 | SBOX[4][92160] = 0x80; // 16800 (3, 6) = 2 558 | SBOX[4][96256] = 0x21040000; // 17800 (3, 7) = 13 559 | SBOX[4][100352] = 0x40080; // 18800 (3, 8) = 6 560 | SBOX[4][104448] = 0x21040080; // 19800 (3, 9) = 15 561 | SBOX[4][108544] = 0x0; // 1a800 (3, 10) = 0 562 | SBOX[4][112640] = 0x21000000; // 1b800 (3, 11) = 9 563 | SBOX[4][116736] = 0x1000080; // 1c800 (3, 12) = 10 564 | SBOX[4][120832] = 0x40000; // 1d800 (3, 13) = 4 565 | SBOX[4][124928] = 0x20040000; // 1e800 (3, 14) = 5 566 | SBOX[4][129024] = 0x20000080; // 1f800 (3, 15) = 3 567 | 568 | SBOX[5] = new Array(); 569 | SBOX[5][0] = 0x10000008; // 0 (0, 0) = 12 570 | SBOX[5][256] = 0x2000; // 100 (0, 1) = 1 571 | SBOX[5][512] = 0x10200000; // 200 (0, 2) = 10 572 | SBOX[5][768] = 0x10202008; // 300 (0, 3) = 15 573 | SBOX[5][1024] = 0x10002000; // 400 (0, 4) = 9 574 | SBOX[5][1280] = 0x200000; // 500 (0, 5) = 2 575 | SBOX[5][1536] = 0x200008; // 600 (0, 6) = 6 576 | SBOX[5][1792] = 0x10000000; // 700 (0, 7) = 8 577 | SBOX[5][2048] = 0x0; // 800 (0, 8) = 0 578 | SBOX[5][2304] = 0x10002008; // 900 (0, 9) = 13 579 | SBOX[5][2560] = 0x202000; // a00 (0, 10) = 3 580 | SBOX[5][2816] = 0x8; // b00 (0, 11) = 4 581 | SBOX[5][3072] = 0x10200008; // c00 (0, 12) = 14 582 | SBOX[5][3328] = 0x202008; // d00 (0, 13) = 7 583 | SBOX[5][3584] = 0x2008; // e00 (0, 14) = 5 584 | SBOX[5][3840] = 0x10202000; // f00 (0, 15) = 11 585 | SBOX[5][128] = 0x10200000; // 80 (1, 0) = 10 586 | SBOX[5][384] = 0x10202008; // 180 (1, 1) = 15 587 | SBOX[5][640] = 0x8; // 280 (1, 2) = 4 588 | SBOX[5][896] = 0x200000; // 380 (1, 3) = 2 589 | SBOX[5][1152] = 0x202008; // 480 (1, 4) = 7 590 | SBOX[5][1408] = 0x10000008; // 580 (1, 5) = 12 591 | SBOX[5][1664] = 0x10002000; // 680 (1, 6) = 9 592 | SBOX[5][1920] = 0x2008; // 780 (1, 7) = 5 593 | SBOX[5][2176] = 0x200008; // 880 (1, 8) = 6 594 | SBOX[5][2432] = 0x2000; // 980 (1, 9) = 1 595 | SBOX[5][2688] = 0x10002008; // a80 (1, 10) = 13 596 | SBOX[5][2944] = 0x10200008; // b80 (1, 11) = 14 597 | SBOX[5][3200] = 0x0; // c80 (1, 12) = 0 598 | SBOX[5][3456] = 0x10202000; // d80 (1, 13) = 11 599 | SBOX[5][3712] = 0x202000; // e80 (1, 14) = 3 600 | SBOX[5][3968] = 0x10000000; // f80 (1, 15) = 8 601 | SBOX[5][4096] = 0x10002000; // 1000 (2, 0) = 9 602 | SBOX[5][4352] = 0x10200008; // 1100 (2, 1) = 14 603 | SBOX[5][4608] = 0x10202008; // 1200 (2, 2) = 15 604 | SBOX[5][4864] = 0x2008; // 1300 (2, 3) = 5 605 | SBOX[5][5120] = 0x200000; // 1400 (2, 4) = 2 606 | SBOX[5][5376] = 0x10000000; // 1500 (2, 5) = 8 607 | SBOX[5][5632] = 0x10000008; // 1600 (2, 6) = 12 608 | SBOX[5][5888] = 0x202000; // 1700 (2, 7) = 3 609 | SBOX[5][6144] = 0x202008; // 1800 (2, 8) = 7 610 | SBOX[5][6400] = 0x0; // 1900 (2, 9) = 0 611 | SBOX[5][6656] = 0x8; // 1a00 (2, 10) = 4 612 | SBOX[5][6912] = 0x10200000; // 1b00 (2, 11) = 10 613 | SBOX[5][7168] = 0x2000; // 1c00 (2, 12) = 1 614 | SBOX[5][7424] = 0x10002008; // 1d00 (2, 13) = 13 615 | SBOX[5][7680] = 0x10202000; // 1e00 (2, 14) = 11 616 | SBOX[5][7936] = 0x200008; // 1f00 (2, 15) = 6 617 | SBOX[5][4224] = 0x8; // 1080 (3, 0) = 4 618 | SBOX[5][4480] = 0x202000; // 1180 (3, 1) = 3 619 | SBOX[5][4736] = 0x200000; // 1280 (3, 2) = 2 620 | SBOX[5][4992] = 0x10000008; // 1380 (3, 3) = 12 621 | SBOX[5][5248] = 0x10002000; // 1480 (3, 4) = 9 622 | SBOX[5][5504] = 0x2008; // 1580 (3, 5) = 5 623 | SBOX[5][5760] = 0x10202008; // 1680 (3, 6) = 15 624 | SBOX[5][6016] = 0x10200000; // 1780 (3, 7) = 10 625 | SBOX[5][6272] = 0x10202000; // 1880 (3, 8) = 11 626 | SBOX[5][6528] = 0x10200008; // 1980 (3, 9) = 14 627 | SBOX[5][6784] = 0x2000; // 1a80 (3, 10) = 1 628 | SBOX[5][7040] = 0x202008; // 1b80 (3, 11) = 7 629 | SBOX[5][7296] = 0x200008; // 1c80 (3, 12) = 6 630 | SBOX[5][7552] = 0x0; // 1d80 (3, 13) = 0 631 | SBOX[5][7808] = 0x10000000; // 1e80 (3, 14) = 8 632 | SBOX[5][8064] = 0x10002008; // 1f80 (3, 15) = 13 633 | 634 | SBOX[6] = new Array(); 635 | SBOX[6][0] = 0x100000; // 0 (0, 0) = 4 636 | SBOX[6][16] = 0x2000401; // 10 (0, 1) = 11 637 | SBOX[6][32] = 0x400; // 20 (0, 2) = 2 638 | SBOX[6][48] = 0x100401; // 30 (0, 3) = 14 639 | SBOX[6][64] = 0x2100401; // 40 (0, 4) = 15 640 | SBOX[6][80] = 0x0; // 50 (0, 5) = 0 641 | SBOX[6][96] = 0x1; // 60 (0, 6) = 8 642 | SBOX[6][112] = 0x2100001; // 70 (0, 7) = 13 643 | SBOX[6][128] = 0x2000400; // 80 (0, 8) = 3 644 | SBOX[6][144] = 0x100001; // 90 (0, 9) = 12 645 | SBOX[6][160] = 0x2000001; // a0 (0, 10) = 9 646 | SBOX[6][176] = 0x2100400; // b0 (0, 11) = 7 647 | SBOX[6][192] = 0x2100000; // c0 (0, 12) = 5 648 | SBOX[6][208] = 0x401; // d0 (0, 13) = 10 649 | SBOX[6][224] = 0x100400; // e0 (0, 14) = 6 650 | SBOX[6][240] = 0x2000000; // f0 (0, 15) = 1 651 | SBOX[6][8] = 0x2100001; // 8 (1, 0) = 13 652 | SBOX[6][24] = 0x0; // 18 (1, 1) = 0 653 | SBOX[6][40] = 0x2000401; // 28 (1, 2) = 11 654 | SBOX[6][56] = 0x2100400; // 38 (1, 3) = 7 655 | SBOX[6][72] = 0x100000; // 48 (1, 4) = 4 656 | SBOX[6][88] = 0x2000001; // 58 (1, 5) = 9 657 | SBOX[6][104] = 0x2000000; // 68 (1, 6) = 1 658 | SBOX[6][120] = 0x401; // 78 (1, 7) = 10 659 | SBOX[6][136] = 0x100401; // 88 (1, 8) = 14 660 | SBOX[6][152] = 0x2000400; // 98 (1, 9) = 3 661 | SBOX[6][168] = 0x2100000; // a8 (1, 10) = 5 662 | SBOX[6][184] = 0x100001; // b8 (1, 11) = 12 663 | SBOX[6][200] = 0x400; // c8 (1, 12) = 2 664 | SBOX[6][216] = 0x2100401; // d8 (1, 13) = 15 665 | SBOX[6][232] = 0x1; // e8 (1, 14) = 8 666 | SBOX[6][248] = 0x100400; // f8 (1, 15) = 6 667 | SBOX[6][256] = 0x2000000; // 100 (2, 0) = 1 668 | SBOX[6][272] = 0x100000; // 110 (2, 1) = 4 669 | SBOX[6][288] = 0x2000401; // 120 (2, 2) = 11 670 | SBOX[6][304] = 0x2100001; // 130 (2, 3) = 13 671 | SBOX[6][320] = 0x100001; // 140 (2, 4) = 12 672 | SBOX[6][336] = 0x2000400; // 150 (2, 5) = 3 673 | SBOX[6][352] = 0x2100400; // 160 (2, 6) = 7 674 | SBOX[6][368] = 0x100401; // 170 (2, 7) = 14 675 | SBOX[6][384] = 0x401; // 180 (2, 8) = 10 676 | SBOX[6][400] = 0x2100401; // 190 (2, 9) = 15 677 | SBOX[6][416] = 0x100400; // 1a0 (2, 10) = 6 678 | SBOX[6][432] = 0x1; // 1b0 (2, 11) = 8 679 | SBOX[6][448] = 0x0; // 1c0 (2, 12) = 0 680 | SBOX[6][464] = 0x2100000; // 1d0 (2, 13) = 5 681 | SBOX[6][480] = 0x2000001; // 1e0 (2, 14) = 9 682 | SBOX[6][496] = 0x400; // 1f0 (2, 15) = 2 683 | SBOX[6][264] = 0x100400; // 108 (3, 0) = 6 684 | SBOX[6][280] = 0x2000401; // 118 (3, 1) = 11 685 | SBOX[6][296] = 0x2100001; // 128 (3, 2) = 13 686 | SBOX[6][312] = 0x1; // 138 (3, 3) = 8 687 | SBOX[6][328] = 0x2000000; // 148 (3, 4) = 1 688 | SBOX[6][344] = 0x100000; // 158 (3, 5) = 4 689 | SBOX[6][360] = 0x401; // 168 (3, 6) = 10 690 | SBOX[6][376] = 0x2100400; // 178 (3, 7) = 7 691 | SBOX[6][392] = 0x2000001; // 188 (3, 8) = 9 692 | SBOX[6][408] = 0x2100000; // 198 (3, 9) = 5 693 | SBOX[6][424] = 0x0; // 1a8 (3, 10) = 0 694 | SBOX[6][440] = 0x2100401; // 1b8 (3, 11) = 15 695 | SBOX[6][456] = 0x100401; // 1c8 (3, 12) = 14 696 | SBOX[6][472] = 0x400; // 1d8 (3, 13) = 2 697 | SBOX[6][488] = 0x2000400; // 1e8 (3, 14) = 3 698 | SBOX[6][504] = 0x100001; // 1f8 (3, 15) = 12 699 | 700 | SBOX[7] = new Array(); 701 | SBOX[7][0] = 0x8000820; // 0 (0, 0) = 13 702 | SBOX[7][1] = 0x20000; // 1 (0, 1) = 2 703 | SBOX[7][2] = 0x8000000; // 2 (0, 2) = 8 704 | SBOX[7][3] = 0x20; // 3 (0, 3) = 4 705 | SBOX[7][4] = 0x20020; // 4 (0, 4) = 6 706 | SBOX[7][5] = 0x8020820; // 5 (0, 5) = 15 707 | SBOX[7][6] = 0x8020800; // 6 (0, 6) = 11 708 | SBOX[7][7] = 0x800; // 7 (0, 7) = 1 709 | SBOX[7][8] = 0x8020000; // 8 (0, 8) = 10 710 | SBOX[7][9] = 0x8000800; // 9 (0, 9) = 9 711 | SBOX[7][10] = 0x20800; // a (0, 10) = 3 712 | SBOX[7][11] = 0x8020020; // b (0, 11) = 14 713 | SBOX[7][12] = 0x820; // c (0, 12) = 5 714 | SBOX[7][13] = 0x0; // d (0, 13) = 0 715 | SBOX[7][14] = 0x8000020; // e (0, 14) = 12 716 | SBOX[7][15] = 0x20820; // f (0, 15) = 7 717 | SBOX[7][-2147483648] = 0x800; // 80000000 (1, 0) = 1 718 | SBOX[7][-2147483647] = 0x8020820; // 80000001 (1, 1) = 15 719 | SBOX[7][-2147483646] = 0x8000820; // 80000002 (1, 2) = 13 720 | SBOX[7][-2147483645] = 0x8000000; // 80000003 (1, 3) = 8 721 | SBOX[7][-2147483644] = 0x8020000; // 80000004 (1, 4) = 10 722 | SBOX[7][-2147483643] = 0x20800; // 80000005 (1, 5) = 3 723 | SBOX[7][-2147483642] = 0x20820; // 80000006 (1, 6) = 7 724 | SBOX[7][-2147483641] = 0x20; // 80000007 (1, 7) = 4 725 | SBOX[7][-2147483640] = 0x8000020; // 80000008 (1, 8) = 12 726 | SBOX[7][-2147483639] = 0x820; // 80000009 (1, 9) = 5 727 | SBOX[7][-2147483638] = 0x20020; // 8000000a (1, 10) = 6 728 | SBOX[7][-2147483637] = 0x8020800; // 8000000b (1, 11) = 11 729 | SBOX[7][-2147483636] = 0x0; // 8000000c (1, 12) = 0 730 | SBOX[7][-2147483635] = 0x8020020; // 8000000d (1, 13) = 14 731 | SBOX[7][-2147483634] = 0x8000800; // 8000000e (1, 14) = 9 732 | SBOX[7][-2147483633] = 0x20000; // 8000000f (1, 15) = 2 733 | SBOX[7][16] = 0x20820; // 10 (2, 0) = 7 734 | SBOX[7][17] = 0x8020800; // 11 (2, 1) = 11 735 | SBOX[7][18] = 0x20; // 12 (2, 2) = 4 736 | SBOX[7][19] = 0x800; // 13 (2, 3) = 1 737 | SBOX[7][20] = 0x8000800; // 14 (2, 4) = 9 738 | SBOX[7][21] = 0x8000020; // 15 (2, 5) = 12 739 | SBOX[7][22] = 0x8020020; // 16 (2, 6) = 14 740 | SBOX[7][23] = 0x20000; // 17 (2, 7) = 2 741 | SBOX[7][24] = 0x0; // 18 (2, 8) = 0 742 | SBOX[7][25] = 0x20020; // 19 (2, 9) = 6 743 | SBOX[7][26] = 0x8020000; // 1a (2, 10) = 10 744 | SBOX[7][27] = 0x8000820; // 1b (2, 11) = 13 745 | SBOX[7][28] = 0x8020820; // 1c (2, 12) = 15 746 | SBOX[7][29] = 0x20800; // 1d (2, 13) = 3 747 | SBOX[7][30] = 0x820; // 1e (2, 14) = 5 748 | SBOX[7][31] = 0x8000000; // 1f (2, 15) = 8 749 | SBOX[7][-2147483632] = 0x20000; // 80000010 (3, 0) = 2 750 | SBOX[7][-2147483631] = 0x800; // 80000011 (3, 1) = 1 751 | SBOX[7][-2147483630] = 0x8020020; // 80000012 (3, 2) = 14 752 | SBOX[7][-2147483629] = 0x20820; // 80000013 (3, 3) = 7 753 | SBOX[7][-2147483628] = 0x20; // 80000014 (3, 4) = 4 754 | SBOX[7][-2147483627] = 0x8020000; // 80000015 (3, 5) = 10 755 | SBOX[7][-2147483626] = 0x8000000; // 80000016 (3, 6) = 8 756 | SBOX[7][-2147483625] = 0x8000820; // 80000017 (3, 7) = 13 757 | SBOX[7][-2147483624] = 0x8020820; // 80000018 (3, 8) = 15 758 | SBOX[7][-2147483623] = 0x8000020; // 80000019 (3, 9) = 12 759 | SBOX[7][-2147483622] = 0x8000800; // 8000001a (3, 10) = 9 760 | SBOX[7][-2147483621] = 0x0; // 8000001b (3, 11) = 0 761 | SBOX[7][-2147483620] = 0x20800; // 8000001c (3, 12) = 3 762 | SBOX[7][-2147483619] = 0x820; // 8000001d (3, 13) = 5 763 | SBOX[7][-2147483618] = 0x20020; // 8000001e (3, 14) = 6 764 | SBOX[7][-2147483617] = 0x8020800; // 8000001f (3, 15) = 11 765 | 766 | State.prototype._exchangeLR = function(v, m) { 767 | var t = ((this.lhs >> v) ^ this.rhs) & m; 768 | this.rhs ^= t; 769 | this.lhs ^= (t << v); 770 | }; 771 | 772 | State.prototype._exchangeRL = function(v, m) { 773 | var t = ((this.rhs >> v) ^ this.lhs) & m; 774 | this.lhs ^= t; 775 | this.rhs ^= (t << v); 776 | }; 777 | 778 | /** 779 | * Perform the initial permutation of the input to create the starting state 780 | * of the algorithm. The initial permutation maps each consecutive bit of 781 | * the input into a different byte of the state. 782 | * 783 | *
784 | * The initial permutation is defined to be: 785 | * 786 | * 58 50 42 34 26 18 10 2 787 | * 60 52 44 36 28 20 12 4 788 | * 62 54 46 38 30 22 14 6 789 | * 64 56 48 40 32 24 16 8 790 | * 57 49 41 33 25 17 9 1 791 | * 59 51 43 35 27 19 11 3 792 | * 61 53 45 37 29 21 13 5 793 | * 63 55 47 39 31 23 15 7 794 | *795 | * 796 | * 797 | * @param message 798 | * The message as an array of unsigned bytes. 799 | * @param offset 800 | * The offset into the message that the current 64-bit block 801 | * begins. 802 | * @returns the initial engine state 803 | */ 804 | State.prototype.initialPerm = function(message, offset) { 805 | var input = message.slice(offset, offset + 8); 806 | 807 | this.lhs = (input[0] << 24) + (input[1] << 16) + (input[2] << 8) 808 | + input[3]; 809 | this.rhs = (input[4] << 24) + (input[5] << 16) + (input[6] << 8) 810 | + input[7]; 811 | 812 | this._exchangeLR(4, 0x0f0f0f0f); 813 | this._exchangeLR(16, 0x0000ffff); 814 | this._exchangeRL(2, 0x33333333); 815 | this._exchangeRL(8, 0x00ff00ff); 816 | this._exchangeLR(1, 0x55555555); 817 | }; 818 | 819 | /** 820 | * Perform one round of the DES algorithm using the given key. A round is 821 | * defined as: 822 | * 823 | *
824 | * L&rsquo = R 825 | * R&rsquo = L ˆ f(R, k) 826 | *827 | * 828 | * where f consists of expanding, XORing with the key and contracting back 829 | * with the SBOXes. 830 | * 831 | * Note that the final round is defined slightly differently as: 832 | * 833 | *
834 | * L&rsquo = L ˆ f(R, k) 835 | * R&rsquo = R 836 | *837 | * 838 | * Therefore in the final round this function produces LHS and RHS the wrong 839 | * way around. 840 | * 841 | * @param k 842 | * the key 843 | */ 844 | State.prototype.round = function(k) { 845 | var r = this.rhs, l = this.lhs; 846 | var f = 0; 847 | for ( var i = 0; i < 8; i++) { 848 | var v = (r ^ k[i]) & State.SBOX_MASK[i]; 849 | f += State.SBOX[i][v]; 850 | } 851 | 852 | this.lhs = r; 853 | this.rhs = l ^ f; 854 | }; 855 | 856 | /** 857 | * Apply the inverse of the initial permutation. 858 | * 859 | *
860 | * The inverse is defined to be: 861 | * 862 | * 40 8 48 16 56 24 64 32 863 | * 39 7 47 15 55 23 63 31 864 | * 38 6 46 14 54 22 62 30 865 | * 37 5 45 13 53 21 61 29 866 | * 36 4 44 12 52 20 60 28 867 | * 35 3 43 11 51 19 59 27 868 | * 34 2 42 10 50 18 58 26 869 | * 33 1 41 9 49 17 57 25 870 | *871 | * 872 | * @param cipherText 873 | * @param offset 874 | */ 875 | State.prototype.finalPerm = function(cipherText, offset) { 876 | var t = this.lhs; 877 | this.lhs = this.rhs; 878 | this.rhs = t; 879 | 880 | this._exchangeLR(1, 0x55555555); 881 | this._exchangeRL(8, 0x00ff00ff); 882 | this._exchangeRL(2, 0x33333333); 883 | this._exchangeLR(16, 0x0000ffff); 884 | this._exchangeLR(4, 0x0f0f0f0f); 885 | 886 | cipherText[offset] = (this.lhs >> 24) & 0xff; 887 | cipherText[offset + 1] = (this.lhs >> 16) & 0xff; 888 | cipherText[offset + 2] = (this.lhs >> 8) & 0xff; 889 | cipherText[offset + 3] = (this.lhs) & 0xff; 890 | cipherText[offset + 4] = (this.rhs >> 24) & 0xff; 891 | cipherText[offset + 5] = (this.rhs >> 16) & 0xff; 892 | cipherText[offset + 6] = (this.rhs >> 8) & 0xff; 893 | cipherText[offset + 7] = (this.rhs) & 0xff; 894 | }; 895 | 896 | /** 897 | * DES cipher 898 | */ 899 | var DES = C.DES = { 900 | _blocksize : 2, 901 | 902 | _keyschedule : null, 903 | 904 | _state : new State(), 905 | 906 | _init : function(k) { 907 | this._keyschedule = new KeySchedule(k); 908 | }, 909 | 910 | encrypt : function(message, password, options) { 911 | 912 | options = options || {}; 913 | 914 | // Determine mode 915 | var mode = options.mode || new C.mode.OFB; 916 | 917 | // Allow mode to override options 918 | if (mode.fixOptions) 919 | mode.fixOptions(options); 920 | 921 | var 922 | // Convert to bytes if message is a string 923 | m = (message.constructor == String ? UTF8.stringToBytes(message) 924 | : message), 925 | 926 | // Generate random IV 927 | iv = options.iv || util.randomBytes(8), 928 | 929 | // Generate key 930 | k = (password.constructor == String ? 931 | // Derive key from passphrase 932 | C.PBKDF2(password, iv, 8, { 933 | asBytes : true 934 | }) : 935 | // else, assume byte array representing cryptographic key 936 | password); 937 | 938 | // Create key schedule 939 | this._keyschedule = new KeySchedule(k); 940 | 941 | // Encrypt 942 | mode.encrypt(DES, m, iv); 943 | 944 | // Return ciphertext 945 | m = options.iv ? m : iv.concat(m); 946 | return (options && options.asBytes) ? m : util.bytesToBase64(m); 947 | }, 948 | 949 | _encryptblock : function(message, offset) { 950 | this._state.initialPerm(message, offset); 951 | for ( var i = 0; i <= 15; i++) { 952 | this._state.round(this._keyschedule.getKey(i)); 953 | } 954 | this._state.finalPerm(message, offset); 955 | }, 956 | 957 | decrypt : function(ciphertext, password, options) { 958 | options = options || {}; 959 | 960 | // Determine mode 961 | var mode = options.mode || new C.mode.OFB; 962 | 963 | // Allow mode to override options 964 | if (mode.fixOptions) 965 | mode.fixOptions(options); 966 | 967 | var 968 | 969 | // Convert to bytes if ciphertext is a string 970 | c = (ciphertext.constructor == String ? util 971 | .base64ToBytes(ciphertext) : ciphertext), 972 | 973 | // Separate IV and message 974 | iv = options.iv || c.splice(0, 8), 975 | 976 | // Generate key 977 | k = (password.constructor == String ? 978 | // Derive key from passphrase 979 | C.PBKDF2(password, iv, 32, { 980 | asBytes : true 981 | }) : 982 | // else, assume byte array representing cryptographic key 983 | password); 984 | 985 | // Create key schedule 986 | this._keyschedule = new KeySchedule(k); 987 | 988 | mode.decrypt(DES, c, iv); 989 | 990 | // Return plaintext 991 | return (options && options.asBytes) ? c : UTF8.bytesToString(c); 992 | }, 993 | 994 | _decryptblock : function(message, offset) { 995 | this._state.initialPerm(message, offset); 996 | for ( var i = 15; i >= 0; i--) { 997 | this._state.round(this._keyschedule.getKey(i)); 998 | } 999 | this._state.finalPerm(message, offset); 1000 | } 1001 | 1002 | }; 1003 | })(); 1004 | -------------------------------------------------------------------------------- /lib/HMAC.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | 3 | var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto; 4 | 5 | // Shortcuts 6 | var util = C.util, 7 | charenc = C.charenc, 8 | UTF8 = charenc.UTF8, 9 | Binary = charenc.Binary; 10 | 11 | C.HMAC = function (hasher, message, key, options) { 12 | 13 | // Convert to byte arrays 14 | if (message.constructor == String) message = UTF8.stringToBytes(message); 15 | if (key.constructor == String) key = UTF8.stringToBytes(key); 16 | /* else, assume byte arrays already */ 17 | 18 | // Allow arbitrary length keys 19 | if (key.length > hasher._blocksize * 4) 20 | key = hasher(key, { asBytes: true }); 21 | 22 | // XOR keys with pad constants 23 | var okey = key.slice(0), 24 | ikey = key.slice(0); 25 | for (var i = 0; i < hasher._blocksize * 4; i++) { 26 | okey[i] ^= 0x5C; 27 | ikey[i] ^= 0x36; 28 | } 29 | 30 | var hmacbytes = hasher(okey.concat(hasher(ikey.concat(message), { asBytes: true })), { asBytes: true }); 31 | 32 | return options && options.asBytes ? hmacbytes : 33 | options && options.asString ? Binary.bytesToString(hmacbytes) : 34 | util.bytesToHex(hmacbytes); 35 | 36 | }; 37 | 38 | })(); 39 | -------------------------------------------------------------------------------- /lib/MARC4.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | 3 | var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto; 4 | 5 | // Shortcuts 6 | var util = C.util, 7 | charenc = C.charenc, 8 | UTF8 = charenc.UTF8, 9 | Binary = charenc.Binary; 10 | 11 | var MARC4 = C.MARC4 = { 12 | 13 | /** 14 | * Public API 15 | */ 16 | 17 | encrypt: function (message, password) { 18 | 19 | var 20 | 21 | // Convert to bytes 22 | m = UTF8.stringToBytes(message), 23 | 24 | // Generate random IV 25 | iv = util.randomBytes(16), 26 | 27 | // Generate key 28 | k = password.constructor == String ? 29 | // Derive key from passphrase 30 | C.PBKDF2(password, iv, 32, { asBytes: true }) : 31 | // else, assume byte array representing cryptographic key 32 | password; 33 | 34 | // Encrypt 35 | MARC4._marc4(m, k, 1536); 36 | 37 | // Return ciphertext 38 | return util.bytesToBase64(iv.concat(m)); 39 | 40 | }, 41 | 42 | decrypt: function (ciphertext, password) { 43 | 44 | var 45 | 46 | // Convert to bytes 47 | c = util.base64ToBytes(ciphertext), 48 | 49 | // Separate IV and message 50 | iv = c.splice(0, 16), 51 | 52 | // Generate key 53 | k = password.constructor == String ? 54 | // Derive key from passphrase 55 | C.PBKDF2(password, iv, 32, { asBytes: true }) : 56 | // else, assume byte array representing cryptographic key 57 | password; 58 | 59 | // Decrypt 60 | MARC4._marc4(c, k, 1536); 61 | 62 | // Return plaintext 63 | return UTF8.bytesToString(c); 64 | 65 | }, 66 | 67 | 68 | /** 69 | * Internal methods 70 | */ 71 | 72 | // The core 73 | _marc4: function (m, k, drop) { 74 | 75 | // State variables 76 | var i, j, s, temp; 77 | 78 | // Key setup 79 | for (i = 0, s = []; i < 256; i++) s[i] = i; 80 | for (i = 0, j = 0; i < 256; i++) { 81 | 82 | j = (j + s[i] + k[i % k.length]) % 256; 83 | 84 | // Swap 85 | temp = s[i]; 86 | s[i] = s[j]; 87 | s[j] = temp; 88 | 89 | } 90 | 91 | // Clear counters 92 | i = j = 0; 93 | 94 | // Encryption 95 | for (var k = -drop; k < m.length; k++) { 96 | 97 | i = (i + 1) % 256; 98 | j = (j + s[i]) % 256; 99 | 100 | // Swap 101 | temp = s[i]; 102 | s[i] = s[j]; 103 | s[j] = temp; 104 | 105 | // Stop here if we're still dropping keystream 106 | if (k < 0) continue; 107 | 108 | // Encrypt 109 | m[k] ^= s[(s[i] + s[j]) % 256]; 110 | 111 | } 112 | 113 | } 114 | 115 | }; 116 | 117 | })(); 118 | -------------------------------------------------------------------------------- /lib/MD5.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | 3 | var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto; 4 | 5 | // Shortcuts 6 | var util = C.util, 7 | charenc = C.charenc, 8 | UTF8 = charenc.UTF8, 9 | Binary = charenc.Binary; 10 | 11 | // Public API 12 | var MD5 = C.MD5 = function (message, options) { 13 | var digestbytes = util.wordsToBytes(MD5._md5(message)); 14 | return options && options.asBytes ? digestbytes : 15 | options && options.asString ? Binary.bytesToString(digestbytes) : 16 | util.bytesToHex(digestbytes); 17 | }; 18 | 19 | // The core 20 | MD5._md5 = function (message) { 21 | 22 | // Convert to byte array 23 | if (message.constructor == String) message = UTF8.stringToBytes(message); 24 | /* else, assume byte array already */ 25 | 26 | var m = util.bytesToWords(message), 27 | l = message.length * 8, 28 | a = 1732584193, 29 | b = -271733879, 30 | c = -1732584194, 31 | d = 271733878; 32 | 33 | // Swap endian 34 | for (var i = 0; i < m.length; i++) { 35 | m[i] = ((m[i] << 8) | (m[i] >>> 24)) & 0x00FF00FF | 36 | ((m[i] << 24) | (m[i] >>> 8)) & 0xFF00FF00; 37 | } 38 | 39 | // Padding 40 | m[l >>> 5] |= 0x80 << (l % 32); 41 | m[(((l + 64) >>> 9) << 4) + 14] = l; 42 | 43 | // Method shortcuts 44 | var FF = MD5._ff, 45 | GG = MD5._gg, 46 | HH = MD5._hh, 47 | II = MD5._ii; 48 | 49 | for (var i = 0; i < m.length; i += 16) { 50 | 51 | var aa = a, 52 | bb = b, 53 | cc = c, 54 | dd = d; 55 | 56 | a = FF(a, b, c, d, m[i+ 0], 7, -680876936); 57 | d = FF(d, a, b, c, m[i+ 1], 12, -389564586); 58 | c = FF(c, d, a, b, m[i+ 2], 17, 606105819); 59 | b = FF(b, c, d, a, m[i+ 3], 22, -1044525330); 60 | a = FF(a, b, c, d, m[i+ 4], 7, -176418897); 61 | d = FF(d, a, b, c, m[i+ 5], 12, 1200080426); 62 | c = FF(c, d, a, b, m[i+ 6], 17, -1473231341); 63 | b = FF(b, c, d, a, m[i+ 7], 22, -45705983); 64 | a = FF(a, b, c, d, m[i+ 8], 7, 1770035416); 65 | d = FF(d, a, b, c, m[i+ 9], 12, -1958414417); 66 | c = FF(c, d, a, b, m[i+10], 17, -42063); 67 | b = FF(b, c, d, a, m[i+11], 22, -1990404162); 68 | a = FF(a, b, c, d, m[i+12], 7, 1804603682); 69 | d = FF(d, a, b, c, m[i+13], 12, -40341101); 70 | c = FF(c, d, a, b, m[i+14], 17, -1502002290); 71 | b = FF(b, c, d, a, m[i+15], 22, 1236535329); 72 | 73 | a = GG(a, b, c, d, m[i+ 1], 5, -165796510); 74 | d = GG(d, a, b, c, m[i+ 6], 9, -1069501632); 75 | c = GG(c, d, a, b, m[i+11], 14, 643717713); 76 | b = GG(b, c, d, a, m[i+ 0], 20, -373897302); 77 | a = GG(a, b, c, d, m[i+ 5], 5, -701558691); 78 | d = GG(d, a, b, c, m[i+10], 9, 38016083); 79 | c = GG(c, d, a, b, m[i+15], 14, -660478335); 80 | b = GG(b, c, d, a, m[i+ 4], 20, -405537848); 81 | a = GG(a, b, c, d, m[i+ 9], 5, 568446438); 82 | d = GG(d, a, b, c, m[i+14], 9, -1019803690); 83 | c = GG(c, d, a, b, m[i+ 3], 14, -187363961); 84 | b = GG(b, c, d, a, m[i+ 8], 20, 1163531501); 85 | a = GG(a, b, c, d, m[i+13], 5, -1444681467); 86 | d = GG(d, a, b, c, m[i+ 2], 9, -51403784); 87 | c = GG(c, d, a, b, m[i+ 7], 14, 1735328473); 88 | b = GG(b, c, d, a, m[i+12], 20, -1926607734); 89 | 90 | a = HH(a, b, c, d, m[i+ 5], 4, -378558); 91 | d = HH(d, a, b, c, m[i+ 8], 11, -2022574463); 92 | c = HH(c, d, a, b, m[i+11], 16, 1839030562); 93 | b = HH(b, c, d, a, m[i+14], 23, -35309556); 94 | a = HH(a, b, c, d, m[i+ 1], 4, -1530992060); 95 | d = HH(d, a, b, c, m[i+ 4], 11, 1272893353); 96 | c = HH(c, d, a, b, m[i+ 7], 16, -155497632); 97 | b = HH(b, c, d, a, m[i+10], 23, -1094730640); 98 | a = HH(a, b, c, d, m[i+13], 4, 681279174); 99 | d = HH(d, a, b, c, m[i+ 0], 11, -358537222); 100 | c = HH(c, d, a, b, m[i+ 3], 16, -722521979); 101 | b = HH(b, c, d, a, m[i+ 6], 23, 76029189); 102 | a = HH(a, b, c, d, m[i+ 9], 4, -640364487); 103 | d = HH(d, a, b, c, m[i+12], 11, -421815835); 104 | c = HH(c, d, a, b, m[i+15], 16, 530742520); 105 | b = HH(b, c, d, a, m[i+ 2], 23, -995338651); 106 | 107 | a = II(a, b, c, d, m[i+ 0], 6, -198630844); 108 | d = II(d, a, b, c, m[i+ 7], 10, 1126891415); 109 | c = II(c, d, a, b, m[i+14], 15, -1416354905); 110 | b = II(b, c, d, a, m[i+ 5], 21, -57434055); 111 | a = II(a, b, c, d, m[i+12], 6, 1700485571); 112 | d = II(d, a, b, c, m[i+ 3], 10, -1894986606); 113 | c = II(c, d, a, b, m[i+10], 15, -1051523); 114 | b = II(b, c, d, a, m[i+ 1], 21, -2054922799); 115 | a = II(a, b, c, d, m[i+ 8], 6, 1873313359); 116 | d = II(d, a, b, c, m[i+15], 10, -30611744); 117 | c = II(c, d, a, b, m[i+ 6], 15, -1560198380); 118 | b = II(b, c, d, a, m[i+13], 21, 1309151649); 119 | a = II(a, b, c, d, m[i+ 4], 6, -145523070); 120 | d = II(d, a, b, c, m[i+11], 10, -1120210379); 121 | c = II(c, d, a, b, m[i+ 2], 15, 718787259); 122 | b = II(b, c, d, a, m[i+ 9], 21, -343485551); 123 | 124 | a = (a + aa) >>> 0; 125 | b = (b + bb) >>> 0; 126 | c = (c + cc) >>> 0; 127 | d = (d + dd) >>> 0; 128 | 129 | } 130 | 131 | return util.endian([a, b, c, d]); 132 | 133 | }; 134 | 135 | // Auxiliary functions 136 | MD5._ff = function (a, b, c, d, x, s, t) { 137 | var n = a + (b & c | ~b & d) + (x >>> 0) + t; 138 | return ((n << s) | (n >>> (32 - s))) + b; 139 | }; 140 | MD5._gg = function (a, b, c, d, x, s, t) { 141 | var n = a + (b & d | c & ~d) + (x >>> 0) + t; 142 | return ((n << s) | (n >>> (32 - s))) + b; 143 | }; 144 | MD5._hh = function (a, b, c, d, x, s, t) { 145 | var n = a + (b ^ c ^ d) + (x >>> 0) + t; 146 | return ((n << s) | (n >>> (32 - s))) + b; 147 | }; 148 | MD5._ii = function (a, b, c, d, x, s, t) { 149 | var n = a + (c ^ (b | ~d)) + (x >>> 0) + t; 150 | return ((n << s) | (n >>> (32 - s))) + b; 151 | }; 152 | 153 | // Package private blocksize 154 | MD5._blocksize = 16; 155 | 156 | MD5._digestsize = 16; 157 | 158 | })(); 159 | -------------------------------------------------------------------------------- /lib/PBKDF2.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | 3 | var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto; 4 | 5 | // Shortcuts 6 | var util = C.util, 7 | charenc = C.charenc, 8 | UTF8 = charenc.UTF8, 9 | Binary = charenc.Binary; 10 | 11 | C.PBKDF2 = function (password, salt, keylen, options) { 12 | 13 | // Convert to byte arrays 14 | if (password.constructor == String) password = UTF8.stringToBytes(password); 15 | if (salt.constructor == String) salt = UTF8.stringToBytes(salt); 16 | /* else, assume byte arrays already */ 17 | 18 | // Defaults 19 | var hasher = options && options.hasher || C.SHA1, 20 | iterations = options && options.iterations || 1; 21 | 22 | // Pseudo-random function 23 | function PRF(password, salt) { 24 | return C.HMAC(hasher, salt, password, { asBytes: true }); 25 | } 26 | 27 | // Generate key 28 | var derivedKeyBytes = [], 29 | blockindex = 1; 30 | while (derivedKeyBytes.length < keylen) { 31 | var block = PRF(password, salt.concat(util.wordsToBytes([blockindex]))); 32 | for (var u = block, i = 1; i < iterations; i++) { 33 | u = PRF(password, u); 34 | for (var j = 0; j < block.length; j++) block[j] ^= u[j]; 35 | } 36 | derivedKeyBytes = derivedKeyBytes.concat(block); 37 | blockindex++; 38 | } 39 | 40 | // Truncate excess bytes 41 | derivedKeyBytes.length = keylen; 42 | 43 | return options && options.asBytes ? derivedKeyBytes : 44 | options && options.asString ? Binary.bytesToString(derivedKeyBytes) : 45 | util.bytesToHex(derivedKeyBytes); 46 | 47 | }; 48 | 49 | })(); 50 | -------------------------------------------------------------------------------- /lib/PBKDF2Async.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | 3 | var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto; 4 | 5 | // Shortcuts 6 | var util = C.util, 7 | charenc = C.charenc, 8 | UTF8 = charenc.UTF8, 9 | Binary = charenc.Binary; 10 | 11 | if (!C.nextTick) { 12 | // node.js has setTime out but prefer process.nextTick 13 | if (typeof process != 'undefined' && typeof process.nextTick !== 'undefined') { 14 | C.nextTick = process.nextTick; 15 | } else if (typeof setTimeout !== 'undefined') { 16 | C.nextTick = function (callback) { 17 | setTimeout(callback, 0); 18 | }; 19 | } 20 | } 21 | 22 | C.PBKDF2Async = function (password, salt, keylen, callback, options) { 23 | 24 | // Convert to byte arrays 25 | if (password.constructor == String) password = UTF8.stringToBytes(password); 26 | if (salt.constructor == String) salt = UTF8.stringToBytes(salt); 27 | /* else, assume byte arrays already */ 28 | 29 | // Defaults 30 | var hasher = options && options.hasher || C.SHA1, 31 | iterations = options && options.iterations || 1; 32 | 33 | // Progress callback option 34 | var progressChangeHandler = options && options.onProgressChange; 35 | var totalIterations = Math.ceil(keylen / hasher._digestsize) * iterations; 36 | function fireProgressChange(currentIteration) { 37 | if (progressChangeHandler) { 38 | var iterationsSoFar = derivedKeyBytes.length / hasher._digestsize * iterations + currentIteration; 39 | setTimeout(function () { 40 | progressChangeHandler(Math.round(iterationsSoFar / totalIterations * 100)); 41 | }, 0); 42 | } 43 | } 44 | 45 | // Pseudo-random function 46 | function PRF(password, salt) { 47 | return C.HMAC(hasher, salt, password, { asBytes: true }); 48 | } 49 | 50 | var nextTick = C.nextTick; 51 | 52 | // Generate key 53 | var derivedKeyBytes = [], 54 | blockindex = 1; 55 | 56 | var outer, inner; 57 | nextTick(outer = function () { 58 | if (derivedKeyBytes.length < keylen) { 59 | var block = PRF(password, salt.concat(util.wordsToBytes([blockindex]))); 60 | fireProgressChange(1); 61 | 62 | var u = block, i = 1; 63 | nextTick(inner = function () { 64 | if (i < iterations) { 65 | u = PRF(password, u); 66 | for (var j = 0; j < block.length; j++) block[j] ^= u[j]; 67 | i++; 68 | fireProgressChange(i); 69 | 70 | nextTick(inner); 71 | } else { 72 | derivedKeyBytes = derivedKeyBytes.concat(block); 73 | blockindex++; 74 | nextTick(outer); 75 | } 76 | }); 77 | } else { 78 | // Truncate excess bytes 79 | derivedKeyBytes.length = keylen; 80 | callback( 81 | options && options.asBytes ? derivedKeyBytes : 82 | options && options.asString ? Binary.bytesToString(derivedKeyBytes) : 83 | util.bytesToHex(derivedKeyBytes)); 84 | } 85 | }); 86 | }; 87 | 88 | })(); 89 | -------------------------------------------------------------------------------- /lib/Rabbit.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | 3 | var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto; 4 | 5 | // Shortcuts 6 | var util = C.util, 7 | charenc = C.charenc, 8 | UTF8 = charenc.UTF8, 9 | Binary = charenc.Binary; 10 | 11 | // Inner state 12 | var x = [], 13 | c = [], 14 | b; 15 | 16 | var Rabbit = C.Rabbit = { 17 | 18 | /** 19 | * Public API 20 | */ 21 | 22 | encrypt: function (message, password) { 23 | 24 | var 25 | 26 | // Convert to bytes 27 | m = UTF8.stringToBytes(message), 28 | 29 | // Generate random IV 30 | iv = util.randomBytes(8), 31 | 32 | // Generate key 33 | k = password.constructor == String ? 34 | // Derive key from passphrase 35 | C.PBKDF2(password, iv, 32, { asBytes: true }) : 36 | // else, assume byte array representing cryptographic key 37 | password; 38 | 39 | // Encrypt 40 | Rabbit._rabbit(m, k, util.bytesToWords(iv)); 41 | 42 | // Return ciphertext 43 | return util.bytesToBase64(iv.concat(m)); 44 | 45 | }, 46 | 47 | decrypt: function (ciphertext, password) { 48 | 49 | var 50 | 51 | // Convert to bytes 52 | c = util.base64ToBytes(ciphertext), 53 | 54 | // Separate IV and message 55 | iv = c.splice(0, 8), 56 | 57 | // Generate key 58 | k = password.constructor == String ? 59 | // Derive key from passphrase 60 | C.PBKDF2(password, iv, 32, { asBytes: true }) : 61 | // else, assume byte array representing cryptographic key 62 | password; 63 | 64 | // Decrypt 65 | Rabbit._rabbit(c, k, util.bytesToWords(iv)); 66 | 67 | // Return plaintext 68 | return UTF8.bytesToString(c); 69 | 70 | }, 71 | 72 | 73 | /** 74 | * Internal methods 75 | */ 76 | 77 | // Encryption/decryption scheme 78 | _rabbit: function (m, k, iv) { 79 | 80 | Rabbit._keysetup(k); 81 | if (iv) Rabbit._ivsetup(iv); 82 | 83 | for (var s = [], i = 0; i < m.length; i++) { 84 | 85 | if (i % 16 == 0) { 86 | 87 | // Iterate the system 88 | Rabbit._nextstate(); 89 | 90 | // Generate 16 bytes of pseudo-random data 91 | s[0] = x[0] ^ (x[5] >>> 16) ^ (x[3] << 16); 92 | s[1] = x[2] ^ (x[7] >>> 16) ^ (x[5] << 16); 93 | s[2] = x[4] ^ (x[1] >>> 16) ^ (x[7] << 16); 94 | s[3] = x[6] ^ (x[3] >>> 16) ^ (x[1] << 16); 95 | 96 | // Swap endian 97 | for (var j = 0; j < 4; j++) { 98 | s[j] = ((s[j] << 8) | (s[j] >>> 24)) & 0x00FF00FF | 99 | ((s[j] << 24) | (s[j] >>> 8)) & 0xFF00FF00; 100 | } 101 | 102 | // Convert words to bytes 103 | for (var b = 120; b >= 0; b -= 8) 104 | s[b / 8] = (s[b >>> 5] >>> (24 - b % 32)) & 0xFF; 105 | 106 | } 107 | 108 | m[i] ^= s[i % 16]; 109 | 110 | } 111 | 112 | }, 113 | 114 | // Key setup scheme 115 | _keysetup: function (k) { 116 | 117 | // Generate initial state values 118 | x[0] = k[0]; 119 | x[2] = k[1]; 120 | x[4] = k[2]; 121 | x[6] = k[3]; 122 | x[1] = (k[3] << 16) | (k[2] >>> 16); 123 | x[3] = (k[0] << 16) | (k[3] >>> 16); 124 | x[5] = (k[1] << 16) | (k[0] >>> 16); 125 | x[7] = (k[2] << 16) | (k[1] >>> 16); 126 | 127 | // Generate initial counter values 128 | c[0] = util.rotl(k[2], 16); 129 | c[2] = util.rotl(k[3], 16); 130 | c[4] = util.rotl(k[0], 16); 131 | c[6] = util.rotl(k[1], 16); 132 | c[1] = (k[0] & 0xFFFF0000) | (k[1] & 0xFFFF); 133 | c[3] = (k[1] & 0xFFFF0000) | (k[2] & 0xFFFF); 134 | c[5] = (k[2] & 0xFFFF0000) | (k[3] & 0xFFFF); 135 | c[7] = (k[3] & 0xFFFF0000) | (k[0] & 0xFFFF); 136 | 137 | // Clear carry bit 138 | b = 0; 139 | 140 | // Iterate the system four times 141 | for (var i = 0; i < 4; i++) Rabbit._nextstate(); 142 | 143 | // Modify the counters 144 | for (var i = 0; i < 8; i++) c[i] ^= x[(i + 4) & 7]; 145 | 146 | }, 147 | 148 | // IV setup scheme 149 | _ivsetup: function (iv) { 150 | 151 | // Generate four subvectors 152 | var i0 = util.endian(iv[0]), 153 | i2 = util.endian(iv[1]), 154 | i1 = (i0 >>> 16) | (i2 & 0xFFFF0000), 155 | i3 = (i2 << 16) | (i0 & 0x0000FFFF); 156 | 157 | // Modify counter values 158 | c[0] ^= i0; 159 | c[1] ^= i1; 160 | c[2] ^= i2; 161 | c[3] ^= i3; 162 | c[4] ^= i0; 163 | c[5] ^= i1; 164 | c[6] ^= i2; 165 | c[7] ^= i3; 166 | 167 | // Iterate the system four times 168 | for (var i = 0; i < 4; i++) Rabbit._nextstate(); 169 | 170 | }, 171 | 172 | // Next-state function 173 | _nextstate: function () { 174 | 175 | // Save old counter values 176 | for (var c_old = [], i = 0; i < 8; i++) c_old[i] = c[i]; 177 | 178 | // Calculate new counter values 179 | c[0] = (c[0] + 0x4D34D34D + b) >>> 0; 180 | c[1] = (c[1] + 0xD34D34D3 + ((c[0] >>> 0) < (c_old[0] >>> 0) ? 1 : 0)) >>> 0; 181 | c[2] = (c[2] + 0x34D34D34 + ((c[1] >>> 0) < (c_old[1] >>> 0) ? 1 : 0)) >>> 0; 182 | c[3] = (c[3] + 0x4D34D34D + ((c[2] >>> 0) < (c_old[2] >>> 0) ? 1 : 0)) >>> 0; 183 | c[4] = (c[4] + 0xD34D34D3 + ((c[3] >>> 0) < (c_old[3] >>> 0) ? 1 : 0)) >>> 0; 184 | c[5] = (c[5] + 0x34D34D34 + ((c[4] >>> 0) < (c_old[4] >>> 0) ? 1 : 0)) >>> 0; 185 | c[6] = (c[6] + 0x4D34D34D + ((c[5] >>> 0) < (c_old[5] >>> 0) ? 1 : 0)) >>> 0; 186 | c[7] = (c[7] + 0xD34D34D3 + ((c[6] >>> 0) < (c_old[6] >>> 0) ? 1 : 0)) >>> 0; 187 | b = (c[7] >>> 0) < (c_old[7] >>> 0) ? 1 : 0; 188 | 189 | // Calculate the g-values 190 | for (var g = [], i = 0; i < 8; i++) { 191 | 192 | var gx = (x[i] + c[i]) >>> 0; 193 | 194 | // Construct high and low argument for squaring 195 | var ga = gx & 0xFFFF, 196 | gb = gx >>> 16; 197 | 198 | // Calculate high and low result of squaring 199 | var gh = ((((ga * ga) >>> 17) + ga * gb) >>> 15) + gb * gb, 200 | gl = (((gx & 0xFFFF0000) * gx) >>> 0) + (((gx & 0x0000FFFF) * gx) >>> 0) >>> 0; 201 | 202 | // High XOR low 203 | g[i] = gh ^ gl; 204 | 205 | } 206 | 207 | // Calculate new state values 208 | x[0] = g[0] + ((g[7] << 16) | (g[7] >>> 16)) + ((g[6] << 16) | (g[6] >>> 16)); 209 | x[1] = g[1] + ((g[0] << 8) | (g[0] >>> 24)) + g[7]; 210 | x[2] = g[2] + ((g[1] << 16) | (g[1] >>> 16)) + ((g[0] << 16) | (g[0] >>> 16)); 211 | x[3] = g[3] + ((g[2] << 8) | (g[2] >>> 24)) + g[1]; 212 | x[4] = g[4] + ((g[3] << 16) | (g[3] >>> 16)) + ((g[2] << 16) | (g[2] >>> 16)); 213 | x[5] = g[5] + ((g[4] << 8) | (g[4] >>> 24)) + g[3]; 214 | x[6] = g[6] + ((g[5] << 16) | (g[5] >>> 16)) + ((g[4] << 16) | (g[4] >>> 16)); 215 | x[7] = g[7] + ((g[6] << 8) | (g[6] >>> 24)) + g[5]; 216 | 217 | } 218 | 219 | }; 220 | 221 | })(); 222 | -------------------------------------------------------------------------------- /lib/SHA1.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | 3 | var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto; 4 | 5 | // Shortcuts 6 | var util = C.util, 7 | charenc = C.charenc, 8 | UTF8 = charenc.UTF8, 9 | Binary = charenc.Binary; 10 | 11 | // Public API 12 | var SHA1 = C.SHA1 = function (message, options) { 13 | var digestbytes = util.wordsToBytes(SHA1._sha1(message)); 14 | return options && options.asBytes ? digestbytes : 15 | options && options.asString ? Binary.bytesToString(digestbytes) : 16 | util.bytesToHex(digestbytes); 17 | }; 18 | 19 | // The core 20 | SHA1._sha1 = function (message) { 21 | 22 | // Convert to byte array 23 | if (message.constructor == String) message = UTF8.stringToBytes(message); 24 | /* else, assume byte array already */ 25 | 26 | var m = util.bytesToWords(message), 27 | l = message.length * 8, 28 | w = [], 29 | H0 = 1732584193, 30 | H1 = -271733879, 31 | H2 = -1732584194, 32 | H3 = 271733878, 33 | H4 = -1009589776; 34 | 35 | // Padding 36 | m[l >> 5] |= 0x80 << (24 - l % 32); 37 | m[((l + 64 >>> 9) << 4) + 15] = l; 38 | 39 | for (var i = 0; i < m.length; i += 16) { 40 | 41 | var a = H0, 42 | b = H1, 43 | c = H2, 44 | d = H3, 45 | e = H4; 46 | 47 | for (var j = 0; j < 80; j++) { 48 | 49 | if (j < 16) w[j] = m[i + j]; 50 | else { 51 | var n = w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16]; 52 | w[j] = (n << 1) | (n >>> 31); 53 | } 54 | 55 | var t = ((H0 << 5) | (H0 >>> 27)) + H4 + (w[j] >>> 0) + ( 56 | j < 20 ? (H1 & H2 | ~H1 & H3) + 1518500249 : 57 | j < 40 ? (H1 ^ H2 ^ H3) + 1859775393 : 58 | j < 60 ? (H1 & H2 | H1 & H3 | H2 & H3) - 1894007588 : 59 | (H1 ^ H2 ^ H3) - 899497514); 60 | 61 | H4 = H3; 62 | H3 = H2; 63 | H2 = (H1 << 30) | (H1 >>> 2); 64 | H1 = H0; 65 | H0 = t; 66 | 67 | } 68 | 69 | H0 += a; 70 | H1 += b; 71 | H2 += c; 72 | H3 += d; 73 | H4 += e; 74 | 75 | } 76 | 77 | return [H0, H1, H2, H3, H4]; 78 | 79 | }; 80 | 81 | // Package private blocksize 82 | SHA1._blocksize = 16; 83 | 84 | SHA1._digestsize = 20; 85 | 86 | })(); 87 | -------------------------------------------------------------------------------- /lib/SHA256.js: -------------------------------------------------------------------------------- 1 | (function(){ 2 | 3 | var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto; 4 | 5 | // Shortcuts 6 | var util = C.util, 7 | charenc = C.charenc, 8 | UTF8 = charenc.UTF8, 9 | Binary = charenc.Binary; 10 | 11 | // Constants 12 | var K = [ 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 13 | 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 14 | 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 15 | 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 16 | 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, 17 | 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 18 | 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 19 | 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, 20 | 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 21 | 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 22 | 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 23 | 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 24 | 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 25 | 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, 26 | 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 27 | 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 ]; 28 | 29 | // Public API 30 | var SHA256 = C.SHA256 = function (message, options) { 31 | var digestbytes = util.wordsToBytes(SHA256._sha256(message)); 32 | return options && options.asBytes ? digestbytes : 33 | options && options.asString ? Binary.bytesToString(digestbytes) : 34 | util.bytesToHex(digestbytes); 35 | }; 36 | 37 | // The core 38 | SHA256._sha256 = function (message) { 39 | 40 | // Convert to byte array 41 | if (message.constructor == String) message = UTF8.stringToBytes(message); 42 | /* else, assume byte array already */ 43 | 44 | var m = util.bytesToWords(message), 45 | l = message.length * 8, 46 | H = [ 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 47 | 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 ], 48 | w = [], 49 | a, b, c, d, e, f, g, h, i, j, 50 | t1, t2; 51 | 52 | // Padding 53 | m[l >> 5] |= 0x80 << (24 - l % 32); 54 | m[((l + 64 >> 9) << 4) + 15] = l; 55 | 56 | for (var i = 0; i < m.length; i += 16) { 57 | 58 | a = H[0]; 59 | b = H[1]; 60 | c = H[2]; 61 | d = H[3]; 62 | e = H[4]; 63 | f = H[5]; 64 | g = H[6]; 65 | h = H[7]; 66 | 67 | for (var j = 0; j < 64; j++) { 68 | 69 | if (j < 16) w[j] = m[j + i]; 70 | else { 71 | 72 | var gamma0x = w[j - 15], 73 | gamma1x = w[j - 2], 74 | gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^ 75 | ((gamma0x << 14) | (gamma0x >>> 18)) ^ 76 | (gamma0x >>> 3), 77 | gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^ 78 | ((gamma1x << 13) | (gamma1x >>> 19)) ^ 79 | (gamma1x >>> 10); 80 | 81 | w[j] = gamma0 + (w[j - 7] >>> 0) + 82 | gamma1 + (w[j - 16] >>> 0); 83 | 84 | } 85 | 86 | var ch = e & f ^ ~e & g, 87 | maj = a & b ^ a & c ^ b & c, 88 | sigma0 = ((a << 30) | (a >>> 2)) ^ 89 | ((a << 19) | (a >>> 13)) ^ 90 | ((a << 10) | (a >>> 22)), 91 | sigma1 = ((e << 26) | (e >>> 6)) ^ 92 | ((e << 21) | (e >>> 11)) ^ 93 | ((e << 7) | (e >>> 25)); 94 | 95 | 96 | t1 = (h >>> 0) + sigma1 + ch + (K[j]) + (w[j] >>> 0); 97 | t2 = sigma0 + maj; 98 | 99 | h = g; 100 | g = f; 101 | f = e; 102 | e = (d + t1) >>> 0; 103 | d = c; 104 | c = b; 105 | b = a; 106 | a = (t1 + t2) >>> 0; 107 | 108 | } 109 | 110 | H[0] += a; 111 | H[1] += b; 112 | H[2] += c; 113 | H[3] += d; 114 | H[4] += e; 115 | H[5] += f; 116 | H[6] += g; 117 | H[7] += h; 118 | 119 | } 120 | 121 | return H; 122 | 123 | }; 124 | 125 | // Package private blocksize 126 | SHA256._blocksize = 16; 127 | 128 | SHA256._digestsize = 32; 129 | 130 | })(); 131 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Jeff Guo