Path: blob/trunk/third_party/closure/goog/crypt/aes.js
2868 views
// Copyright 2012 The Closure Library Authors. All Rights Reserved.1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS-IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314/**15* @fileoverview Implementation of AES in JavaScript.16* @see http://en.wikipedia.org/wiki/Advanced_Encryption_Standard17*18* @author [email protected] (Nathan Naze) - port to Closure19*/2021goog.provide('goog.crypt.Aes');2223goog.require('goog.asserts');24goog.require('goog.crypt.BlockCipher');25262728/**29* Implementation of AES in JavaScript.30* See http://en.wikipedia.org/wiki/Advanced_Encryption_Standard31*32* WARNING: This is ECB mode only. If you are encrypting something33* longer than 16 bytes, or encrypting more than one value with the same key34* (so basically, always) you need to use this with a block cipher mode of35* operation. See goog.crypt.Cbc.36*37* See http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation for more38* information.39*40* @constructor41* @implements {goog.crypt.BlockCipher}42* @param {!Array<number>} key The key as an array of integers in {0, 255}.43* The key must have lengths of 16, 24, or 32 integers for 128-,44* 192-, or 256-bit encryption, respectively.45* @final46* @struct47*/48goog.crypt.Aes = function(key) {49goog.crypt.Aes.assertKeyArray_(key);5051/**52* The AES key.53* @type {!Array<number>}54* @private55*/56this.key_ = key;5758/**59* Key length, in words.60* @type {number}61* @private62*/63this.keyLengthInWords_ = this.key_.length / 4;6465/**66* Number of rounds. Based on key length per AES spec.67* @type {number}68* @private69*/70this.numberOfRounds_ = this.keyLengthInWords_ + 6;7172/**73* 4x4 byte array containing the current state.74* @type {!Array<!Array<number>>}75* @private76*/77this.state_ = [[], [], [], []];7879/**80* Scratch temporary array for calculation.81* @type {!Array<!Array<number>>}82* @private83*/84this.temp_ = [[], [], [], []];8586/**87* The key schedule.88* @type {!Array<!Array<number>>}89* @private90*/91this.keySchedule_;9293this.keyExpansion_();94};959697/**98* Block size, in bytes. Fixed at 16 per AES spec.99* @override100* @type {number}101* @const102* @public103*/104goog.crypt.Aes.prototype.BLOCK_SIZE = 16;105106/**107* Number of words in a block.108* @type {number}109* @const110* @private111*/112goog.crypt.Aes.BLOCK_SIZE_IN_WORDS_ = goog.crypt.Aes.prototype.BLOCK_SIZE / 4;113114115/**116* @define {boolean} Whether to call test method stubs. This can be enabled117* for unit testing.118*/119goog.define('goog.crypt.Aes.ENABLE_TEST_MODE', false);120121122/**123* @override124*/125goog.crypt.Aes.prototype.encrypt = function(input) {126127if (goog.crypt.Aes.ENABLE_TEST_MODE) {128this.testKeySchedule_(0, this.keySchedule_, 0);129}130131this.copyInput_(input);132this.addRoundKey_(0);133134for (var round = 1; round < this.numberOfRounds_; ++round) {135if (goog.crypt.Aes.ENABLE_TEST_MODE) {136this.testKeySchedule_(round, this.keySchedule_, round);137this.testStartRound_(round, this.state_);138}139140this.subBytes_(goog.crypt.Aes.SBOX_);141if (goog.crypt.Aes.ENABLE_TEST_MODE) {142this.testAfterSubBytes_(round, this.state_);143}144145this.shiftRows_();146if (goog.crypt.Aes.ENABLE_TEST_MODE) {147this.testAfterShiftRows_(round, this.state_);148}149150this.mixColumns_();151if (goog.crypt.Aes.ENABLE_TEST_MODE) {152this.testAfterMixColumns_(round, this.state_);153}154155this.addRoundKey_(round);156}157158this.subBytes_(goog.crypt.Aes.SBOX_);159if (goog.crypt.Aes.ENABLE_TEST_MODE) {160this.testAfterSubBytes_(round, this.state_);161}162163this.shiftRows_();164if (goog.crypt.Aes.ENABLE_TEST_MODE) {165this.testAfterShiftRows_(round, this.state_);166}167168this.addRoundKey_(this.numberOfRounds_);169170return this.generateOutput_();171};172173174/**175* @override176*/177goog.crypt.Aes.prototype.decrypt = function(input) {178179if (goog.crypt.Aes.ENABLE_TEST_MODE) {180this.testKeySchedule_(0, this.keySchedule_, this.numberOfRounds_);181}182183this.copyInput_(input);184this.addRoundKey_(this.numberOfRounds_);185186for (var round = 1; round < this.numberOfRounds_; ++round) {187if (goog.crypt.Aes.ENABLE_TEST_MODE) {188this.testKeySchedule_(189round, this.keySchedule_, this.numberOfRounds_ - round);190this.testStartRound_(round, this.state_);191}192193this.invShiftRows_();194if (goog.crypt.Aes.ENABLE_TEST_MODE) {195this.testAfterShiftRows_(round, this.state_);196}197198this.subBytes_(goog.crypt.Aes.INV_SBOX_);199if (goog.crypt.Aes.ENABLE_TEST_MODE) {200this.testAfterSubBytes_(round, this.state_);201}202203this.addRoundKey_(this.numberOfRounds_ - round);204if (goog.crypt.Aes.ENABLE_TEST_MODE) {205this.testAfterAddRoundKey_(round, this.state_);206}207208this.invMixColumns_();209}210211this.invShiftRows_();212if (goog.crypt.Aes.ENABLE_TEST_MODE) {213this.testAfterShiftRows_(round, this.state_);214}215216this.subBytes_(goog.crypt.Aes.INV_SBOX_);217if (goog.crypt.Aes.ENABLE_TEST_MODE) {218this.testAfterSubBytes_(this.numberOfRounds_, this.state_);219}220221if (goog.crypt.Aes.ENABLE_TEST_MODE) {222this.testKeySchedule_(this.numberOfRounds_, this.keySchedule_, 0);223}224225this.addRoundKey_(0);226227return this.generateOutput_();228};229230231/**232* Asserts that the key's array of integers is in the correct format.233* @param {!Array<number>} arr AES key as array of integers.234* @private235*/236goog.crypt.Aes.assertKeyArray_ = function(arr) {237if (goog.asserts.ENABLE_ASSERTS) {238goog.asserts.assert(239arr.length == 16 || arr.length == 24 || arr.length == 32,240'Key must have length 16, 24, or 32.');241for (var i = 0; i < arr.length; i++) {242goog.asserts.assertNumber(arr[i]);243goog.asserts.assert(arr[i] >= 0 && arr[i] <= 255);244}245}246};247248249/**250* Tests can populate this with a callback, and that callback will get called251* at the start of each round *in both functions encrypt() and decrypt()*.252* @param {number} roundNum Round number.253* @param {!Array<Array<number>>} Current state.254* @private255*/256goog.crypt.Aes.prototype.testStartRound_ = goog.nullFunction;257258259/**260* Tests can populate this with a callback, and that callback will get called261* each round right after the SubBytes step gets executed *in both functions262* encrypt() and decrypt()*.263* @param {number} roundNum Round number.264* @param {!Array<Array<number>>} Current state.265* @private266*/267goog.crypt.Aes.prototype.testAfterSubBytes_ = goog.nullFunction;268269270/**271* Tests can populate this with a callback, and that callback will get called272* each round right after the ShiftRows step gets executed *in both functions273* encrypt() and decrypt()*.274* @param {number} roundNum Round number.275* @param {!Array<Array<number>>} Current state.276* @private277*/278goog.crypt.Aes.prototype.testAfterShiftRows_ = goog.nullFunction;279280281/**282* Tests can populate this with a callback, and that callback will get called283* each round right after the MixColumns step gets executed *but only in the284* decrypt() function*.285* @param {number} roundNum Round number.286* @param {!Array<Array<number>>} Current state.287* @private288*/289goog.crypt.Aes.prototype.testAfterMixColumns_ = goog.nullFunction;290291292/**293* Tests can populate this with a callback, and that callback will get called294* each round right after the AddRoundKey step gets executed encrypt().295* @param {number} roundNum Round number.296* @param {!Array<Array<number>>} Current state.297* @private298*/299goog.crypt.Aes.prototype.testAfterAddRoundKey_ = goog.nullFunction;300301302/**303* Tests can populate this with a callback, and that callback will get called304* before each round on the round key. *Gets called in both the encrypt() and305* decrypt() functions.*306* @param {number} roundNum Round number.307* @param {Array<!Array<number>>} Computed key schedule.308* @param {number} index The index into the key schedule to test. This is not309* necessarily roundNum because the key schedule is used in reverse310* in the case of decryption.311* @private312*/313goog.crypt.Aes.prototype.testKeySchedule_ = goog.nullFunction;314315316/**317* Helper to copy input into the AES state matrix.318* @param {!Array<number>|!Uint8Array} input Byte array to copy into the state319* matrix.320* @private321*/322goog.crypt.Aes.prototype.copyInput_ = function(input) {323var v, p;324325goog.asserts.assert(326input.length == this.BLOCK_SIZE, 'Expecting input of block size.');327328for (var r = 0; r < goog.crypt.Aes.BLOCK_SIZE_IN_WORDS_; r++) {329for (var c = 0; c < 4; c++) {330p = c * 4 + r;331v = input[p];332333goog.asserts.assert(334v <= 255 && v >= 0,335'Invalid input. Value %s at position %s is not a byte.', v, p);336337this.state_[r][c] = v;338}339}340};341342343/**344* Helper to copy the state matrix into an output array.345* @return {!Array<number>} Output byte array.346* @private347*/348goog.crypt.Aes.prototype.generateOutput_ = function() {349var output = [];350for (var r = 0; r < goog.crypt.Aes.BLOCK_SIZE_IN_WORDS_; r++) {351for (var c = 0; c < 4; c++) {352output[c * 4 + r] = this.state_[r][c];353}354}355return output;356};357358359/**360* AES's AddRoundKey procedure. Add the current round key to the state.361* @param {number} round The current round.362* @private363*/364goog.crypt.Aes.prototype.addRoundKey_ = function(round) {365for (var r = 0; r < 4; r++) {366for (var c = 0; c < 4; c++) {367this.state_[r][c] ^= this.keySchedule_[round * 4 + c][r];368}369}370};371372373/**374* AES's SubBytes procedure. Substitute bytes from the precomputed SBox lookup375* into the state.376* @param {!Array<number>} box The SBox or invSBox.377* @private378*/379goog.crypt.Aes.prototype.subBytes_ = function(box) {380for (var r = 0; r < 4; r++) {381for (var c = 0; c < 4; c++) {382this.state_[r][c] = box[this.state_[r][c]];383}384}385};386387388/**389* AES's ShiftRows procedure. Shift the values in each row to the right. Each390* row is shifted one more slot than the one above it.391* @private392*/393goog.crypt.Aes.prototype.shiftRows_ = function() {394for (var r = 1; r < 4; r++) {395for (var c = 0; c < 4; c++) {396this.temp_[r][c] = this.state_[r][c];397}398}399400for (var r = 1; r < 4; r++) {401for (var c = 0; c < 4; c++) {402this.state_[r][c] =403this.temp_[r][(c + r) % goog.crypt.Aes.BLOCK_SIZE_IN_WORDS_];404}405}406};407408409/**410* AES's InvShiftRows procedure. Shift the values in each row to the right.411* @private412*/413goog.crypt.Aes.prototype.invShiftRows_ = function() {414for (var r = 1; r < 4; r++) {415for (var c = 0; c < 4; c++) {416this.temp_[r][(c + r) % goog.crypt.Aes.BLOCK_SIZE_IN_WORDS_] =417this.state_[r][c];418}419}420421for (var r = 1; r < 4; r++) {422for (var c = 0; c < 4; c++) {423this.state_[r][c] = this.temp_[r][c];424}425}426};427428429/**430* AES's MixColumns procedure. Mix the columns of the state using magic.431* @private432*/433goog.crypt.Aes.prototype.mixColumns_ = function() {434var s = this.state_;435var t = this.temp_[0];436437for (var c = 0; c < 4; c++) {438t[0] = s[0][c];439t[1] = s[1][c];440t[2] = s[2][c];441t[3] = s[3][c];442443s[0][c] =444(goog.crypt.Aes.MULT_2_[t[0]] ^ goog.crypt.Aes.MULT_3_[t[1]] ^ t[2] ^445t[3]);446s[1][c] =447(t[0] ^ goog.crypt.Aes.MULT_2_[t[1]] ^ goog.crypt.Aes.MULT_3_[t[2]] ^448t[3]);449s[2][c] =450(t[0] ^ t[1] ^ goog.crypt.Aes.MULT_2_[t[2]] ^451goog.crypt.Aes.MULT_3_[t[3]]);452s[3][c] =453(goog.crypt.Aes.MULT_3_[t[0]] ^ t[1] ^ t[2] ^454goog.crypt.Aes.MULT_2_[t[3]]);455}456};457458459/**460* AES's InvMixColumns procedure.461* @private462*/463goog.crypt.Aes.prototype.invMixColumns_ = function() {464var s = this.state_;465var t = this.temp_[0];466467for (var c = 0; c < 4; c++) {468t[0] = s[0][c];469t[1] = s[1][c];470t[2] = s[2][c];471t[3] = s[3][c];472473s[0][c] =474(goog.crypt.Aes.MULT_E_[t[0]] ^ goog.crypt.Aes.MULT_B_[t[1]] ^475goog.crypt.Aes.MULT_D_[t[2]] ^ goog.crypt.Aes.MULT_9_[t[3]]);476477s[1][c] =478(goog.crypt.Aes.MULT_9_[t[0]] ^ goog.crypt.Aes.MULT_E_[t[1]] ^479goog.crypt.Aes.MULT_B_[t[2]] ^ goog.crypt.Aes.MULT_D_[t[3]]);480481s[2][c] =482(goog.crypt.Aes.MULT_D_[t[0]] ^ goog.crypt.Aes.MULT_9_[t[1]] ^483goog.crypt.Aes.MULT_E_[t[2]] ^ goog.crypt.Aes.MULT_B_[t[3]]);484485s[3][c] =486(goog.crypt.Aes.MULT_B_[t[0]] ^ goog.crypt.Aes.MULT_D_[t[1]] ^487goog.crypt.Aes.MULT_9_[t[2]] ^ goog.crypt.Aes.MULT_E_[t[3]]);488}489};490491492/**493* AES's KeyExpansion procedure. Create the key schedule from the initial key.494* @private495*/496goog.crypt.Aes.prototype.keyExpansion_ = function() {497this.keySchedule_ = new Array(498goog.crypt.Aes.BLOCK_SIZE_IN_WORDS_ * (this.numberOfRounds_ + 1));499500for (var rowNum = 0; rowNum < this.keyLengthInWords_; rowNum++) {501this.keySchedule_[rowNum] = [502this.key_[4 * rowNum], this.key_[4 * rowNum + 1],503this.key_[4 * rowNum + 2], this.key_[4 * rowNum + 3]504];505}506507var temp = new Array(4);508509for (var rowNum = this.keyLengthInWords_; rowNum <510(goog.crypt.Aes.BLOCK_SIZE_IN_WORDS_ * (this.numberOfRounds_ + 1));511rowNum++) {512temp[0] = this.keySchedule_[rowNum - 1][0];513temp[1] = this.keySchedule_[rowNum - 1][1];514temp[2] = this.keySchedule_[rowNum - 1][2];515temp[3] = this.keySchedule_[rowNum - 1][3];516517if (rowNum % this.keyLengthInWords_ == 0) {518this.rotWord_(temp);519this.subWord_(temp);520521temp[0] ^= goog.crypt.Aes.RCON_[rowNum / this.keyLengthInWords_][0];522temp[1] ^= goog.crypt.Aes.RCON_[rowNum / this.keyLengthInWords_][1];523temp[2] ^= goog.crypt.Aes.RCON_[rowNum / this.keyLengthInWords_][2];524temp[3] ^= goog.crypt.Aes.RCON_[rowNum / this.keyLengthInWords_][3];525} else if (526this.keyLengthInWords_ > 6 && rowNum % this.keyLengthInWords_ == 4) {527this.subWord_(temp);528}529530this.keySchedule_[rowNum] = new Array(4);531this.keySchedule_[rowNum][0] =532this.keySchedule_[rowNum - this.keyLengthInWords_][0] ^ temp[0];533this.keySchedule_[rowNum][1] =534this.keySchedule_[rowNum - this.keyLengthInWords_][1] ^ temp[1];535this.keySchedule_[rowNum][2] =536this.keySchedule_[rowNum - this.keyLengthInWords_][2] ^ temp[2];537this.keySchedule_[rowNum][3] =538this.keySchedule_[rowNum - this.keyLengthInWords_][3] ^ temp[3];539}540};541542543/**544* AES's SubWord procedure.545* @param {!Array<number>} w Bytes to find the SBox substitution for.546* @return {!Array<number>} The substituted bytes.547* @private548*/549goog.crypt.Aes.prototype.subWord_ = function(w) {550w[0] = goog.crypt.Aes.SBOX_[w[0]];551w[1] = goog.crypt.Aes.SBOX_[w[1]];552w[2] = goog.crypt.Aes.SBOX_[w[2]];553w[3] = goog.crypt.Aes.SBOX_[w[3]];554555return w;556};557558559/**560* AES's RotWord procedure.561* @param {!Array<number>} w Array of bytes to rotate.562* @return {!Array<number>} The rotated bytes.563* @private564*/565goog.crypt.Aes.prototype.rotWord_ = function(w) {566var temp = w[0];567568w[0] = w[1];569w[1] = w[2];570w[2] = w[3];571w[3] = temp;572573return w;574};575576// clang-format off577/**578* Precomputed SBox lookup.579* @type {!Array<number>}580* @private581*/582goog.crypt.Aes.SBOX_ = [5830x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe,5840xd7, 0xab, 0x76,5855860xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c,5870xa4, 0x72, 0xc0,5885890xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71,5900xd8, 0x31, 0x15,5915920x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb,5930x27, 0xb2, 0x75,5945950x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29,5960xe3, 0x2f, 0x84,5975980x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a,5990x4c, 0x58, 0xcf,6006010xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50,6020x3c, 0x9f, 0xa8,6036040x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10,6050xff, 0xf3, 0xd2,6066070xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64,6080x5d, 0x19, 0x73,6096100x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde,6110x5e, 0x0b, 0xdb,6126130xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91,6140x95, 0xe4, 0x79,6156160xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65,6170x7a, 0xae, 0x08,6186190xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b,6200xbd, 0x8b, 0x8a,6216220x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86,6230xc1, 0x1d, 0x9e,6246250xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce,6260x55, 0x28, 0xdf,6276280x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0,6290x54, 0xbb, 0x16630];631632633/**634* Precomputed InvSBox lookup.635* @type {!Array<number>}636* @private637*/638goog.crypt.Aes.INV_SBOX_ = [6390x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81,6400xf3, 0xd7, 0xfb,6416420x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4,6430xde, 0xe9, 0xcb,6446450x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42,6460xfa, 0xc3, 0x4e,6476480x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d,6490x8b, 0xd1, 0x25,6506510x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d,6520x65, 0xb6, 0x92,6536540x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7,6550x8d, 0x9d, 0x84,6566570x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8,6580xb3, 0x45, 0x06,6596600xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01,6610x13, 0x8a, 0x6b,6626630x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0,6640xb4, 0xe6, 0x73,6656660x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c,6670x75, 0xdf, 0x6e,6686690x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa,6700x18, 0xbe, 0x1b,6716720xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78,6730xcd, 0x5a, 0xf4,6746750x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27,6760x80, 0xec, 0x5f,6776780x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93,6790xc9, 0x9c, 0xef,6806810xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83,6820x53, 0x99, 0x61,6836840x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55,6850x21, 0x0c, 0x7d686];687688689/**690* Precomputed RCon lookup.691* @type {!Array<!Array<number>>}692* @private693*/694goog.crypt.Aes.RCON_ = [695[0x00, 0x00, 0x00, 0x00],696[0x01, 0x00, 0x00, 0x00],697[0x02, 0x00, 0x00, 0x00],698[0x04, 0x00, 0x00, 0x00],699[0x08, 0x00, 0x00, 0x00],700[0x10, 0x00, 0x00, 0x00],701[0x20, 0x00, 0x00, 0x00],702[0x40, 0x00, 0x00, 0x00],703[0x80, 0x00, 0x00, 0x00],704[0x1b, 0x00, 0x00, 0x00],705[0x36, 0x00, 0x00, 0x00]706];707708709/**710* Precomputed lookup of multiplication by 2 in GF(2^8)711* @type {!Array<number>}712* @private713*/714goog.crypt.Aes.MULT_2_ = [7150x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x14, 0x16,7160x18, 0x1A, 0x1C, 0x1E,7177180x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, 0x2E, 0x30, 0x32, 0x34, 0x36,7190x38, 0x3A, 0x3C, 0x3E,7207210x40, 0x42, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56,7220x58, 0x5A, 0x5C, 0x5E,7237240x60, 0x62, 0x64, 0x66, 0x68, 0x6A, 0x6C, 0x6E, 0x70, 0x72, 0x74, 0x76,7250x78, 0x7A, 0x7C, 0x7E,7267270x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8C, 0x8E, 0x90, 0x92, 0x94, 0x96,7280x98, 0x9A, 0x9C, 0x9E,7297300xA0, 0xA2, 0xA4, 0xA6, 0xA8, 0xAA, 0xAC, 0xAE, 0xB0, 0xB2, 0xB4, 0xB6,7310xB8, 0xBA, 0xBC, 0xBE,7327330xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE, 0xD0, 0xD2, 0xD4, 0xD6,7340xD8, 0xDA, 0xDC, 0xDE,7357360xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE, 0xF0, 0xF2, 0xF4, 0xF6,7370xF8, 0xFA, 0xFC, 0xFE,7387390x1B, 0x19, 0x1F, 0x1D, 0x13, 0x11, 0x17, 0x15, 0x0B, 0x09, 0x0F, 0x0D,7400x03, 0x01, 0x07, 0x05,7417420x3B, 0x39, 0x3F, 0x3D, 0x33, 0x31, 0x37, 0x35, 0x2B, 0x29, 0x2F, 0x2D,7430x23, 0x21, 0x27, 0x25,7447450x5B, 0x59, 0x5F, 0x5D, 0x53, 0x51, 0x57, 0x55, 0x4B, 0x49, 0x4F, 0x4D,7460x43, 0x41, 0x47, 0x45,7477480x7B, 0x79, 0x7F, 0x7D, 0x73, 0x71, 0x77, 0x75, 0x6B, 0x69, 0x6F, 0x6D,7490x63, 0x61, 0x67, 0x65,7507510x9B, 0x99, 0x9F, 0x9D, 0x93, 0x91, 0x97, 0x95, 0x8B, 0x89, 0x8F, 0x8D,7520x83, 0x81, 0x87, 0x85,7537540xBB, 0xB9, 0xBF, 0xBD, 0xB3, 0xB1, 0xB7, 0xB5, 0xAB, 0xA9, 0xAF, 0xAD,7550xA3, 0xA1, 0xA7, 0xA5,7567570xDB, 0xD9, 0xDF, 0xDD, 0xD3, 0xD1, 0xD7, 0xD5, 0xCB, 0xC9, 0xCF, 0xCD,7580xC3, 0xC1, 0xC7, 0xC5,7597600xFB, 0xF9, 0xFF, 0xFD, 0xF3, 0xF1, 0xF7, 0xF5, 0xEB, 0xE9, 0xEF, 0xED,7610xE3, 0xE1, 0xE7, 0xE5762];763764765/**766* Precomputed lookup of multiplication by 3 in GF(2^8)767* @type {!Array<number>}768* @private769*/770goog.crypt.Aes.MULT_3_ = [7710x00, 0x03, 0x06, 0x05, 0x0C, 0x0F, 0x0A, 0x09, 0x18, 0x1B, 0x1E, 0x1D,7720x14, 0x17, 0x12, 0x11,7737740x30, 0x33, 0x36, 0x35, 0x3C, 0x3F, 0x3A, 0x39, 0x28, 0x2B, 0x2E, 0x2D,7750x24, 0x27, 0x22, 0x21,7767770x60, 0x63, 0x66, 0x65, 0x6C, 0x6F, 0x6A, 0x69, 0x78, 0x7B, 0x7E, 0x7D,7780x74, 0x77, 0x72, 0x71,7797800x50, 0x53, 0x56, 0x55, 0x5C, 0x5F, 0x5A, 0x59, 0x48, 0x4B, 0x4E, 0x4D,7810x44, 0x47, 0x42, 0x41,7827830xC0, 0xC3, 0xC6, 0xC5, 0xCC, 0xCF, 0xCA, 0xC9, 0xD8, 0xDB, 0xDE, 0xDD,7840xD4, 0xD7, 0xD2, 0xD1,7857860xF0, 0xF3, 0xF6, 0xF5, 0xFC, 0xFF, 0xFA, 0xF9, 0xE8, 0xEB, 0xEE, 0xED,7870xE4, 0xE7, 0xE2, 0xE1,7887890xA0, 0xA3, 0xA6, 0xA5, 0xAC, 0xAF, 0xAA, 0xA9, 0xB8, 0xBB, 0xBE, 0xBD,7900xB4, 0xB7, 0xB2, 0xB1,7917920x90, 0x93, 0x96, 0x95, 0x9C, 0x9F, 0x9A, 0x99, 0x88, 0x8B, 0x8E, 0x8D,7930x84, 0x87, 0x82, 0x81,7947950x9B, 0x98, 0x9D, 0x9E, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86,7960x8F, 0x8C, 0x89, 0x8A,7977980xAB, 0xA8, 0xAD, 0xAE, 0xA7, 0xA4, 0xA1, 0xA2, 0xB3, 0xB0, 0xB5, 0xB6,7990xBF, 0xBC, 0xB9, 0xBA,8008010xFB, 0xF8, 0xFD, 0xFE, 0xF7, 0xF4, 0xF1, 0xF2, 0xE3, 0xE0, 0xE5, 0xE6,8020xEF, 0xEC, 0xE9, 0xEA,8038040xCB, 0xC8, 0xCD, 0xCE, 0xC7, 0xC4, 0xC1, 0xC2, 0xD3, 0xD0, 0xD5, 0xD6,8050xDF, 0xDC, 0xD9, 0xDA,8068070x5B, 0x58, 0x5D, 0x5E, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46,8080x4F, 0x4C, 0x49, 0x4A,8098100x6B, 0x68, 0x6D, 0x6E, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76,8110x7F, 0x7C, 0x79, 0x7A,8128130x3B, 0x38, 0x3D, 0x3E, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26,8140x2F, 0x2C, 0x29, 0x2A,8158160x0B, 0x08, 0x0D, 0x0E, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16,8170x1F, 0x1C, 0x19, 0x1A818];819820821/**822* Precomputed lookup of multiplication by 9 in GF(2^8)823* @type {!Array<number>}824* @private825*/826goog.crypt.Aes.MULT_9_ = [8270x00, 0x09, 0x12, 0x1B, 0x24, 0x2D, 0x36, 0x3F, 0x48, 0x41, 0x5A, 0x53,8280x6C, 0x65, 0x7E, 0x77,8298300x90, 0x99, 0x82, 0x8B, 0xB4, 0xBD, 0xA6, 0xAF, 0xD8, 0xD1, 0xCA, 0xC3,8310xFC, 0xF5, 0xEE, 0xE7,8328330x3B, 0x32, 0x29, 0x20, 0x1F, 0x16, 0x0D, 0x04, 0x73, 0x7A, 0x61, 0x68,8340x57, 0x5E, 0x45, 0x4C,8358360xAB, 0xA2, 0xB9, 0xB0, 0x8F, 0x86, 0x9D, 0x94, 0xE3, 0xEA, 0xF1, 0xF8,8370xC7, 0xCE, 0xD5, 0xDC,8388390x76, 0x7F, 0x64, 0x6D, 0x52, 0x5B, 0x40, 0x49, 0x3E, 0x37, 0x2C, 0x25,8400x1A, 0x13, 0x08, 0x01,8418420xE6, 0xEF, 0xF4, 0xFD, 0xC2, 0xCB, 0xD0, 0xD9, 0xAE, 0xA7, 0xBC, 0xB5,8430x8A, 0x83, 0x98, 0x91,8448450x4D, 0x44, 0x5F, 0x56, 0x69, 0x60, 0x7B, 0x72, 0x05, 0x0C, 0x17, 0x1E,8460x21, 0x28, 0x33, 0x3A,8478480xDD, 0xD4, 0xCF, 0xC6, 0xF9, 0xF0, 0xEB, 0xE2, 0x95, 0x9C, 0x87, 0x8E,8490xB1, 0xB8, 0xA3, 0xAA,8508510xEC, 0xE5, 0xFE, 0xF7, 0xC8, 0xC1, 0xDA, 0xD3, 0xA4, 0xAD, 0xB6, 0xBF,8520x80, 0x89, 0x92, 0x9B,8538540x7C, 0x75, 0x6E, 0x67, 0x58, 0x51, 0x4A, 0x43, 0x34, 0x3D, 0x26, 0x2F,8550x10, 0x19, 0x02, 0x0B,8568570xD7, 0xDE, 0xC5, 0xCC, 0xF3, 0xFA, 0xE1, 0xE8, 0x9F, 0x96, 0x8D, 0x84,8580xBB, 0xB2, 0xA9, 0xA0,8598600x47, 0x4E, 0x55, 0x5C, 0x63, 0x6A, 0x71, 0x78, 0x0F, 0x06, 0x1D, 0x14,8610x2B, 0x22, 0x39, 0x30,8628630x9A, 0x93, 0x88, 0x81, 0xBE, 0xB7, 0xAC, 0xA5, 0xD2, 0xDB, 0xC0, 0xC9,8640xF6, 0xFF, 0xE4, 0xED,8658660x0A, 0x03, 0x18, 0x11, 0x2E, 0x27, 0x3C, 0x35, 0x42, 0x4B, 0x50, 0x59,8670x66, 0x6F, 0x74, 0x7D,8688690xA1, 0xA8, 0xB3, 0xBA, 0x85, 0x8C, 0x97, 0x9E, 0xE9, 0xE0, 0xFB, 0xF2,8700xCD, 0xC4, 0xDF, 0xD6,8718720x31, 0x38, 0x23, 0x2A, 0x15, 0x1C, 0x07, 0x0E, 0x79, 0x70, 0x6B, 0x62,8730x5D, 0x54, 0x4F, 0x46874];875876877/**878* Precomputed lookup of multiplication by 11 in GF(2^8)879* @type {!Array<number>}880* @private881*/882goog.crypt.Aes.MULT_B_ = [8830x00, 0x0B, 0x16, 0x1D, 0x2C, 0x27, 0x3A, 0x31, 0x58, 0x53, 0x4E, 0x45,8840x74, 0x7F, 0x62, 0x69,8858860xB0, 0xBB, 0xA6, 0xAD, 0x9C, 0x97, 0x8A, 0x81, 0xE8, 0xE3, 0xFE, 0xF5,8870xC4, 0xCF, 0xD2, 0xD9,8888890x7B, 0x70, 0x6D, 0x66, 0x57, 0x5C, 0x41, 0x4A, 0x23, 0x28, 0x35, 0x3E,8900x0F, 0x04, 0x19, 0x12,8918920xCB, 0xC0, 0xDD, 0xD6, 0xE7, 0xEC, 0xF1, 0xFA, 0x93, 0x98, 0x85, 0x8E,8930xBF, 0xB4, 0xA9, 0xA2,8948950xF6, 0xFD, 0xE0, 0xEB, 0xDA, 0xD1, 0xCC, 0xC7, 0xAE, 0xA5, 0xB8, 0xB3,8960x82, 0x89, 0x94, 0x9F,8978980x46, 0x4D, 0x50, 0x5B, 0x6A, 0x61, 0x7C, 0x77, 0x1E, 0x15, 0x08, 0x03,8990x32, 0x39, 0x24, 0x2F,9009010x8D, 0x86, 0x9B, 0x90, 0xA1, 0xAA, 0xB7, 0xBC, 0xD5, 0xDE, 0xC3, 0xC8,9020xF9, 0xF2, 0xEF, 0xE4,9039040x3D, 0x36, 0x2B, 0x20, 0x11, 0x1A, 0x07, 0x0C, 0x65, 0x6E, 0x73, 0x78,9050x49, 0x42, 0x5F, 0x54,9069070xF7, 0xFC, 0xE1, 0xEA, 0xDB, 0xD0, 0xCD, 0xC6, 0xAF, 0xA4, 0xB9, 0xB2,9080x83, 0x88, 0x95, 0x9E,9099100x47, 0x4C, 0x51, 0x5A, 0x6B, 0x60, 0x7D, 0x76, 0x1F, 0x14, 0x09, 0x02,9110x33, 0x38, 0x25, 0x2E,9129130x8C, 0x87, 0x9A, 0x91, 0xA0, 0xAB, 0xB6, 0xBD, 0xD4, 0xDF, 0xC2, 0xC9,9140xF8, 0xF3, 0xEE, 0xE5,9159160x3C, 0x37, 0x2A, 0x21, 0x10, 0x1B, 0x06, 0x0D, 0x64, 0x6F, 0x72, 0x79,9170x48, 0x43, 0x5E, 0x55,9189190x01, 0x0A, 0x17, 0x1C, 0x2D, 0x26, 0x3B, 0x30, 0x59, 0x52, 0x4F, 0x44,9200x75, 0x7E, 0x63, 0x68,9219220xB1, 0xBA, 0xA7, 0xAC, 0x9D, 0x96, 0x8B, 0x80, 0xE9, 0xE2, 0xFF, 0xF4,9230xC5, 0xCE, 0xD3, 0xD8,9249250x7A, 0x71, 0x6C, 0x67, 0x56, 0x5D, 0x40, 0x4B, 0x22, 0x29, 0x34, 0x3F,9260x0E, 0x05, 0x18, 0x13,9279280xCA, 0xC1, 0xDC, 0xD7, 0xE6, 0xED, 0xF0, 0xFB, 0x92, 0x99, 0x84, 0x8F,9290xBE, 0xB5, 0xA8, 0xA3930];931932933/**934* Precomputed lookup of multiplication by 13 in GF(2^8)935* @type {!Array<number>}936* @private937*/938goog.crypt.Aes.MULT_D_ = [9390x00, 0x0D, 0x1A, 0x17, 0x34, 0x39, 0x2E, 0x23, 0x68, 0x65, 0x72, 0x7F,9400x5C, 0x51, 0x46, 0x4B,9419420xD0, 0xDD, 0xCA, 0xC7, 0xE4, 0xE9, 0xFE, 0xF3, 0xB8, 0xB5, 0xA2, 0xAF,9430x8C, 0x81, 0x96, 0x9B,9449450xBB, 0xB6, 0xA1, 0xAC, 0x8F, 0x82, 0x95, 0x98, 0xD3, 0xDE, 0xC9, 0xC4,9460xE7, 0xEA, 0xFD, 0xF0,9479480x6B, 0x66, 0x71, 0x7C, 0x5F, 0x52, 0x45, 0x48, 0x03, 0x0E, 0x19, 0x14,9490x37, 0x3A, 0x2D, 0x20,9509510x6D, 0x60, 0x77, 0x7A, 0x59, 0x54, 0x43, 0x4E, 0x05, 0x08, 0x1F, 0x12,9520x31, 0x3C, 0x2B, 0x26,9539540xBD, 0xB0, 0xA7, 0xAA, 0x89, 0x84, 0x93, 0x9E, 0xD5, 0xD8, 0xCF, 0xC2,9550xE1, 0xEC, 0xFB, 0xF6,9569570xD6, 0xDB, 0xCC, 0xC1, 0xE2, 0xEF, 0xF8, 0xF5, 0xBE, 0xB3, 0xA4, 0xA9,9580x8A, 0x87, 0x90, 0x9D,9599600x06, 0x0B, 0x1C, 0x11, 0x32, 0x3F, 0x28, 0x25, 0x6E, 0x63, 0x74, 0x79,9610x5A, 0x57, 0x40, 0x4D,9629630xDA, 0xD7, 0xC0, 0xCD, 0xEE, 0xE3, 0xF4, 0xF9, 0xB2, 0xBF, 0xA8, 0xA5,9640x86, 0x8B, 0x9C, 0x91,9659660x0A, 0x07, 0x10, 0x1D, 0x3E, 0x33, 0x24, 0x29, 0x62, 0x6F, 0x78, 0x75,9670x56, 0x5B, 0x4C, 0x41,9689690x61, 0x6C, 0x7B, 0x76, 0x55, 0x58, 0x4F, 0x42, 0x09, 0x04, 0x13, 0x1E,9700x3D, 0x30, 0x27, 0x2A,9719720xB1, 0xBC, 0xAB, 0xA6, 0x85, 0x88, 0x9F, 0x92, 0xD9, 0xD4, 0xC3, 0xCE,9730xED, 0xE0, 0xF7, 0xFA,9749750xB7, 0xBA, 0xAD, 0xA0, 0x83, 0x8E, 0x99, 0x94, 0xDF, 0xD2, 0xC5, 0xC8,9760xEB, 0xE6, 0xF1, 0xFC,9779780x67, 0x6A, 0x7D, 0x70, 0x53, 0x5E, 0x49, 0x44, 0x0F, 0x02, 0x15, 0x18,9790x3B, 0x36, 0x21, 0x2C,9809810x0C, 0x01, 0x16, 0x1B, 0x38, 0x35, 0x22, 0x2F, 0x64, 0x69, 0x7E, 0x73,9820x50, 0x5D, 0x4A, 0x47,9839840xDC, 0xD1, 0xC6, 0xCB, 0xE8, 0xE5, 0xF2, 0xFF, 0xB4, 0xB9, 0xAE, 0xA3,9850x80, 0x8D, 0x9A, 0x97986];987988989/**990* Precomputed lookup of multiplication by 14 in GF(2^8)991* @type {!Array<number>}992* @private993*/994goog.crypt.Aes.MULT_E_ = [9950x00, 0x0E, 0x1C, 0x12, 0x38, 0x36, 0x24, 0x2A, 0x70, 0x7E, 0x6C, 0x62,9960x48, 0x46, 0x54, 0x5A,9979980xE0, 0xEE, 0xFC, 0xF2, 0xD8, 0xD6, 0xC4, 0xCA, 0x90, 0x9E, 0x8C, 0x82,9990xA8, 0xA6, 0xB4, 0xBA,100010010xDB, 0xD5, 0xC7, 0xC9, 0xE3, 0xED, 0xFF, 0xF1, 0xAB, 0xA5, 0xB7, 0xB9,10020x93, 0x9D, 0x8F, 0x81,100310040x3B, 0x35, 0x27, 0x29, 0x03, 0x0D, 0x1F, 0x11, 0x4B, 0x45, 0x57, 0x59,10050x73, 0x7D, 0x6F, 0x61,100610070xAD, 0xA3, 0xB1, 0xBF, 0x95, 0x9B, 0x89, 0x87, 0xDD, 0xD3, 0xC1, 0xCF,10080xE5, 0xEB, 0xF9, 0xF7,100910100x4D, 0x43, 0x51, 0x5F, 0x75, 0x7B, 0x69, 0x67, 0x3D, 0x33, 0x21, 0x2F,10110x05, 0x0B, 0x19, 0x17,101210130x76, 0x78, 0x6A, 0x64, 0x4E, 0x40, 0x52, 0x5C, 0x06, 0x08, 0x1A, 0x14,10140x3E, 0x30, 0x22, 0x2C,101510160x96, 0x98, 0x8A, 0x84, 0xAE, 0xA0, 0xB2, 0xBC, 0xE6, 0xE8, 0xFA, 0xF4,10170xDE, 0xD0, 0xC2, 0xCC,101810190x41, 0x4F, 0x5D, 0x53, 0x79, 0x77, 0x65, 0x6B, 0x31, 0x3F, 0x2D, 0x23,10200x09, 0x07, 0x15, 0x1B,102110220xA1, 0xAF, 0xBD, 0xB3, 0x99, 0x97, 0x85, 0x8B, 0xD1, 0xDF, 0xCD, 0xC3,10230xE9, 0xE7, 0xF5, 0xFB,102410250x9A, 0x94, 0x86, 0x88, 0xA2, 0xAC, 0xBE, 0xB0, 0xEA, 0xE4, 0xF6, 0xF8,10260xD2, 0xDC, 0xCE, 0xC0,102710280x7A, 0x74, 0x66, 0x68, 0x42, 0x4C, 0x5E, 0x50, 0x0A, 0x04, 0x16, 0x18,10290x32, 0x3C, 0x2E, 0x20,103010310xEC, 0xE2, 0xF0, 0xFE, 0xD4, 0xDA, 0xC8, 0xC6, 0x9C, 0x92, 0x80, 0x8E,10320xA4, 0xAA, 0xB8, 0xB6,103310340x0C, 0x02, 0x10, 0x1E, 0x34, 0x3A, 0x28, 0x26, 0x7C, 0x72, 0x60, 0x6E,10350x44, 0x4A, 0x58, 0x56,103610370x37, 0x39, 0x2B, 0x25, 0x0F, 0x01, 0x13, 0x1D, 0x47, 0x49, 0x5B, 0x55,10380x7F, 0x71, 0x63, 0x6D,103910400xD7, 0xD9, 0xCB, 0xC5, 0xEF, 0xE1, 0xF3, 0xFD, 0xA7, 0xA9, 0xBB, 0xB5,10410x9F, 0x91, 0x83, 0x8D1042];1043// clang-format on104410451046