22b23e8e by brandonocasey

only precompute tables once, rather than doing it every time

1 parent cf12b162
...@@ -50,6 +50,62 @@ const ntoh = function(word) { ...@@ -50,6 +50,62 @@ const ntoh = function(word) {
50 }; 50 };
51 51
52 /** 52 /**
53 * Expand the S-box tables.
54 *
55 * @private
56 */
57 const precompute = function() {
58 let _tables = [[[], [], [], [], []], [[], [], [], [], []]];
59 let encTable = _tables[0];
60 let decTable = _tables[1];
61 let sbox = encTable[4];
62 let sboxInv = decTable[4];
63 let i;
64 let x;
65 let xInv;
66 let d = [];
67 let th = [];
68 let x2;
69 let x4;
70 let x8;
71 let s;
72 let tEnc;
73 let tDec;
74
75 // Compute double and third tables
76 for (i = 0; i < 256; i++) {
77 th[(d[i] = i << 1 ^ (i >> 7) * 283) ^ i] = i;
78 }
79
80 for (x = xInv = 0; !sbox[x]; x ^= x2 || 1, xInv = th[xInv] || 1) {
81 // Compute sbox
82 s = xInv ^ xInv << 1 ^ xInv << 2 ^ xInv << 3 ^ xInv << 4;
83 s = s >> 8 ^ s & 255 ^ 99;
84 sbox[x] = s;
85 sboxInv[s] = x;
86
87 // Compute MixColumns
88 x8 = d[x4 = d[x2 = d[x]]];
89 tDec = x8 * 0x1010101 ^ x4 * 0x10001 ^ x2 * 0x101 ^ x * 0x1010100;
90 tEnc = d[s] * 0x101 ^ s * 0x1010100;
91
92 for (i = 0; i < 4; i++) {
93 encTable[i][x] = tEnc = tEnc << 24 ^ tEnc >>> 8;
94 decTable[i][s] = tDec = tDec << 24 ^ tDec >>> 8;
95 }
96 }
97
98 // Compactify. Considerable speedup on Firefox.
99 for (i = 0; i < 5; i++) {
100 encTable[i] = encTable[i].slice(0);
101 decTable[i] = decTable[i].slice(0);
102 }
103 return _tables;
104 }
105
106 let tables;
107
108 /**
53 * Schedule out an AES key for both encryption and decryption. This 109 * Schedule out an AES key for both encryption and decryption. This
54 * is a low-level class. Use a cipher mode to do bulk encryption. 110 * is a low-level class. Use a cipher mode to do bulk encryption.
55 * 111 *
...@@ -70,8 +126,10 @@ class AES { ...@@ -70,8 +126,10 @@ class AES {
70 * 126 *
71 * @private 127 * @private
72 */ 128 */
73 this._tables = [[[], [], [], [], []], [[], [], [], [], []]]; 129 if (!tables) {
74 this._precompute(); 130 tables = precompute();
131 }
132 this._tables = tables;
75 let i; 133 let i;
76 let j; 134 let j;
77 let tmp; 135 let tmp;
...@@ -199,57 +257,6 @@ class AES { ...@@ -199,57 +257,6 @@ class AES {
199 } 257 }
200 } 258 }
201 259
202 /**
203 * Expand the S-box tables.
204 *
205 * @private
206 */
207 _precompute() {
208 let encTable = this._tables[0];
209 let decTable = this._tables[1];
210 let sbox = encTable[4];
211 let sboxInv = decTable[4];
212 let i;
213 let x;
214 let xInv;
215 let d = [];
216 let th = [];
217 let x2;
218 let x4;
219 let x8;
220 let s;
221 let tEnc;
222 let tDec;
223
224 // Compute double and third tables
225 for (i = 0; i < 256; i++) {
226 th[(d[i] = i << 1 ^ (i >> 7) * 283) ^ i] = i;
227 }
228
229 for (x = xInv = 0; !sbox[x]; x ^= x2 || 1, xInv = th[xInv] || 1) {
230 // Compute sbox
231 s = xInv ^ xInv << 1 ^ xInv << 2 ^ xInv << 3 ^ xInv << 4;
232 s = s >> 8 ^ s & 255 ^ 99;
233 sbox[x] = s;
234 sboxInv[s] = x;
235
236 // Compute MixColumns
237 x8 = d[x4 = d[x2 = d[x]]];
238 tDec = x8 * 0x1010101 ^ x4 * 0x10001 ^ x2 * 0x101 ^ x * 0x1010100;
239 tEnc = d[s] * 0x101 ^ s * 0x1010100;
240
241 for (i = 0; i < 4; i++) {
242 encTable[i][x] = tEnc = tEnc << 24 ^ tEnc >>> 8;
243 decTable[i][s] = tDec = tDec << 24 ^ tDec >>> 8;
244 }
245 }
246
247 // Compactify. Considerable speedup on Firefox.
248 for (i = 0; i < 5; i++) {
249 encTable[i] = encTable[i].slice(0);
250 decTable[i] = decTable[i].slice(0);
251 }
252 }
253 } 260 }
254 261
255 /* eslint-disable max-len */ 262 /* eslint-disable max-len */
......