github.com/jincm/wesharechain@v0.0.0-20210122032815-1537409ce26a/app/lib/crypto1/aes/aes.js (about)

     1  /*!
     2   * Crypto-JS v1.1.0
     3   * http://code.google.com/p/crypto-js/
     4   * Copyright (c) 2009, Jeff Mott. All rights reserved.
     5   * http://code.google.com/p/crypto-js/wiki/License
     6   */
     7  (function(){
     8  
     9  // Shortcut
    10  var util = Crypto.util;
    11  
    12  // Precomputed SBOX
    13  var SBOX = [ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
    14               0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
    15               0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
    16               0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
    17               0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
    18               0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
    19               0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
    20               0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
    21               0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
    22               0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
    23               0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
    24               0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
    25               0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
    26               0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
    27               0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
    28               0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
    29               0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
    30               0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
    31               0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
    32               0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
    33               0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
    34               0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
    35               0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
    36               0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
    37               0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
    38               0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
    39               0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
    40               0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
    41               0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
    42               0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
    43               0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
    44               0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 ];
    45  
    46  // Compute inverse SBOX lookup table
    47  for (var INVSBOX = [], i = 0; i < 256; i++) INVSBOX[SBOX[i]] = i;
    48  
    49  // Compute mulitplication in GF(2^8) lookup tables
    50  var MULT2 = [],
    51      MULT3 = [],
    52      MULT9 = [],
    53      MULTB = [],
    54      MULTD = [],
    55      MULTE = [];
    56  
    57  function xtime(a, b) {
    58  	for (var result = 0, i = 0; i < 8; i++) {
    59  		if (b & 1) result ^= a;
    60  		var hiBitSet = a & 0x80;
    61  		a = (a << 1) & 0xFF;
    62  		if (hiBitSet) a ^= 0x1b;
    63  		b >>>= 1;
    64  	}
    65  	return result;
    66  }
    67  
    68  for (var i = 0; i < 256; i++) {
    69  	MULT2[i] = xtime(i,2);
    70  	MULT3[i] = xtime(i,3);
    71  	MULT9[i] = xtime(i,9);
    72  	MULTB[i] = xtime(i,0xB);
    73  	MULTD[i] = xtime(i,0xD);
    74  	MULTE[i] = xtime(i,0xE);
    75  }
    76  
    77  // Precomputed RCon lookup
    78  var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
    79  
    80  // Inner state
    81  var state = [[], [], [], []],
    82      keylength,
    83      nrounds,
    84      keyschedule;
    85  
    86  var AES = Crypto.AES = {
    87  
    88  	/**
    89  	 * Public API
    90  	 */
    91  
    92  	encrypt: function (message, password, mode) {
    93  
    94  		var
    95  
    96  		    // Convert to bytes
    97  		    m = util.stringToBytes(message),
    98  
    99  		    // Generate random IV
   100  		    iv = util.randomBytes(AES._blocksize * 4),
   101  
   102  		    // Generate key
   103  		    k = Crypto.PBKDF2(password, util.bytesToString(iv), 32, { asBytes: true });
   104  
   105  		// Determine mode
   106  		mode = mode || Crypto.mode.OFB;
   107  
   108  		// Encrypt
   109  		AES._init(k);
   110  		mode.encrypt(AES, m, iv);
   111  
   112  		// Return ciphertext
   113  		return util.bytesToBase64(iv.concat(m));
   114  
   115  	},
   116  
   117  	decrypt: function (ciphertext, password, mode) {
   118  
   119  		var
   120  
   121  		    // Convert to bytes
   122  		    c = util.base64ToBytes(ciphertext),
   123  
   124  		    // Separate IV and message
   125  		    iv = c.splice(0, AES._blocksize * 4),
   126  
   127  		    // Generate key
   128  		    k = Crypto.PBKDF2(password, util.bytesToString(iv), 32, { asBytes: true });
   129  
   130  		// Determine mode
   131  		mode = mode || Crypto.mode.OFB;
   132  
   133  		// Decrypt
   134  		AES._init(k);
   135  		mode.decrypt(AES, c, iv);
   136  
   137  		// Return plaintext
   138  		return util.bytesToString(c);
   139  
   140  	},
   141  
   142  
   143  	/**
   144  	 * Package private methods and properties
   145  	 */
   146  
   147  	_blocksize: 4,
   148  
   149  	_encryptblock: function (m, offset) {
   150  
   151  		// Set input
   152  		for (var row = 0; row < AES._blocksize; row++) {
   153  			for (var col = 0; col < 4; col++)
   154  				state[row][col] = m[offset + col * 4 + row];
   155  		}
   156  
   157  		// Add round key
   158  		for (var row = 0; row < 4; row++) {
   159  			for (var col = 0; col < 4; col++)
   160  				state[row][col] ^= keyschedule[col][row];
   161  		}
   162  
   163  		for (var round = 1; round < nrounds; round++) {
   164  
   165  			// Sub bytes
   166  			for (var row = 0; row < 4; row++) {
   167  				for (var col = 0; col < 4; col++)
   168  					state[row][col] = SBOX[state[row][col]];
   169  			}
   170  
   171  			// Shift rows
   172  			state[1].push(state[1].shift());
   173  			state[2].push(state[2].shift());
   174  			state[2].push(state[2].shift());
   175  			state[3].unshift(state[3].pop());
   176  
   177  			// Mix columns
   178  			for (var col = 0; col < 4; col++) {
   179  
   180  				var s0 = state[0][col],
   181  				    s1 = state[1][col],
   182  				    s2 = state[2][col],
   183  				    s3 = state[3][col];
   184  
   185  				state[0][col] = MULT2[s0] ^ MULT3[s1] ^ s2 ^ s3;
   186  				state[1][col] = s0 ^ MULT2[s1] ^ MULT3[s2] ^ s3;
   187  				state[2][col] = s0 ^ s1 ^ MULT2[s2] ^ MULT3[s3];
   188  				state[3][col] = MULT3[s0] ^ s1 ^ s2 ^ MULT2[s3];
   189  
   190  			}
   191  
   192  			// Add round key
   193  			for (var row = 0; row < 4; row++) {
   194  				for (var col = 0; col < 4; col++)
   195  					state[row][col] ^= keyschedule[round * 4 + col][row];
   196  			}
   197  
   198  		}
   199  
   200  		// Sub bytes
   201  		for (var row = 0; row < 4; row++) {
   202  			for (var col = 0; col < 4; col++)
   203  				state[row][col] = SBOX[state[row][col]];
   204  		}
   205  
   206  		// Shift rows
   207  		state[1].push(state[1].shift());
   208  		state[2].push(state[2].shift());
   209  		state[2].push(state[2].shift());
   210  		state[3].unshift(state[3].pop());
   211  
   212  		// Add round key
   213  		for (var row = 0; row < 4; row++) {
   214  			for (var col = 0; col < 4; col++)
   215  				state[row][col] ^= keyschedule[nrounds * 4 + col][row];
   216  		}
   217  
   218  		// Set output
   219  		for (var row = 0; row < AES._blocksize; row++) {
   220  			for (var col = 0; col < 4; col++)
   221  				m[offset + col * 4 + row] = state[row][col];
   222  		}
   223  
   224  	},
   225  
   226  	_decryptblock: function (c, offset) {
   227  
   228  		// Set input
   229  		for (var row = 0; row < AES._blocksize; row++) {
   230  			for (var col = 0; col < 4; col++)
   231  				state[row][col] = c[offset + col * 4 + row];
   232  		}
   233  
   234  		// Add round key
   235  		for (var row = 0; row < 4; row++) {
   236  			for (var col = 0; col < 4; col++)
   237  				state[row][col] ^= keyschedule[nrounds * 4 + col][row];
   238  		}
   239  
   240  		for (var round = 1; round < nrounds; round++) {
   241  
   242  			// Inv shift rows
   243  			state[1].unshift(state[1].pop());
   244  			state[2].push(state[2].shift());
   245  			state[2].push(state[2].shift());
   246  			state[3].push(state[3].shift());
   247  
   248  			// Inv sub bytes
   249  			for (var row = 0; row < 4; row++) {
   250  				for (var col = 0; col < 4; col++)
   251  					state[row][col] = INVSBOX[state[row][col]];
   252  			}
   253  
   254  			// Add round key
   255  			for (var row = 0; row < 4; row++) {
   256  				for (var col = 0; col < 4; col++)
   257  					state[row][col] ^= keyschedule[(nrounds - round) * 4 + col][row];
   258  			}
   259  
   260  			// Inv mix columns
   261  			for (var col = 0; col < 4; col++) {
   262  
   263  				var s0 = state[0][col],
   264  				    s1 = state[1][col],
   265  				    s2 = state[2][col],
   266  				    s3 = state[3][col];
   267  
   268  				state[0][col] = MULTE[s0] ^ MULTB[s1] ^ MULTD[s2] ^ MULT9[s3];
   269  				state[1][col] = MULT9[s0] ^ MULTE[s1] ^ MULTB[s2] ^ MULTD[s3];
   270  				state[2][col] = MULTD[s0] ^ MULT9[s1] ^ MULTE[s2] ^ MULTB[s3];
   271  				state[3][col] = MULTB[s0] ^ MULTD[s1] ^ MULT9[s2] ^ MULTE[s3];
   272  
   273  			}
   274  
   275  		}
   276  
   277  		// Inv shift rows
   278  		state[1].unshift(state[1].pop());
   279  		state[2].push(state[2].shift());
   280  		state[2].push(state[2].shift());
   281  		state[3].push(state[3].shift());
   282  
   283  		// Inv sub bytes
   284  		for (var row = 0; row < 4; row++) {
   285  			for (var col = 0; col < 4; col++)
   286  				state[row][col] = INVSBOX[state[row][col]];
   287  		}
   288  
   289  		// Add round key
   290  		for (var row = 0; row < 4; row++) {
   291  			for (var col = 0; col < 4; col++)
   292  				state[row][col] ^= keyschedule[col][row];
   293  		}
   294  
   295  		// Set output
   296  		for (var row = 0; row < AES._blocksize; row++) {
   297  			for (var col = 0; col < 4; col++)
   298  				c[offset + col * 4 + row] = state[row][col];
   299  		}
   300  
   301  	},
   302  
   303  
   304  	/**
   305  	 * Private methods
   306  	 */
   307  
   308  	_init: function (k) {
   309  		keylength = k.length / 4;
   310  		nrounds = keylength + 6;
   311  		AES._keyexpansion(k);
   312  	},
   313  
   314  	// Generate a key schedule
   315  	_keyexpansion: function (k) {
   316  
   317  		keyschedule = [];
   318  
   319  		for (var row = 0; row < keylength; row++) {
   320  			keyschedule[row] = [
   321  				k[row * 4],
   322  				k[row * 4 + 1],
   323  				k[row * 4 + 2],
   324  				k[row * 4 + 3]
   325  			];
   326  		}
   327  
   328  		for (var row = keylength; row < AES._blocksize * (nrounds + 1); row++) {
   329  
   330  			var temp = [
   331  				keyschedule[row - 1][0],
   332  				keyschedule[row - 1][1],
   333  				keyschedule[row - 1][2],
   334  				keyschedule[row - 1][3]
   335  			];
   336  
   337  			if (row % keylength == 0) {
   338  
   339  				// Rot word
   340  				temp.push(temp.shift());
   341  
   342  				// Sub word
   343  				temp[0] = SBOX[temp[0]];
   344  				temp[1] = SBOX[temp[1]];
   345  				temp[2] = SBOX[temp[2]];
   346  				temp[3] = SBOX[temp[3]];
   347  
   348  				temp[0] ^= RCON[row / keylength];
   349  
   350  			} else if (keylength > 6 && row % keylength == 4) {
   351  
   352  				// Sub word
   353  				temp[0] = SBOX[temp[0]];
   354  				temp[1] = SBOX[temp[1]];
   355  				temp[2] = SBOX[temp[2]];
   356  				temp[3] = SBOX[temp[3]];
   357  
   358  			}
   359  
   360  			keyschedule[row] = [
   361  				keyschedule[row - keylength][0] ^ temp[0],
   362  				keyschedule[row - keylength][1] ^ temp[1],
   363  				keyschedule[row - keylength][2] ^ temp[2],
   364  				keyschedule[row - keylength][3] ^ temp[3]
   365  			];
   366  
   367  		}
   368  
   369  	}
   370  
   371  };
   372  
   373  })();