e3c93f60 by David LaPalomento

Merge pull request #543 from BrandonOCasey/precompute-optimization

only run precompute for tables once, slice copy after that
2 parents 18ec2e0b 4db01738
...@@ -38,6 +38,62 @@ ...@@ -38,6 +38,62 @@
38 */ 38 */
39 39
40 /** 40 /**
41 * Expand the S-box tables.
42 *
43 * @private
44 */
45 const precompute = function() {
46 let tables = [[[], [], [], [], []], [[], [], [], [], []]];
47 let encTable = tables[0];
48 let decTable = tables[1];
49 let sbox = encTable[4];
50 let sboxInv = decTable[4];
51 let i;
52 let x;
53 let xInv;
54 let d = [];
55 let th = [];
56 let x2;
57 let x4;
58 let x8;
59 let s;
60 let tEnc;
61 let tDec;
62
63 // Compute double and third tables
64 for (i = 0; i < 256; i++) {
65 th[(d[i] = i << 1 ^ (i >> 7) * 283) ^ i] = i;
66 }
67
68 for (x = xInv = 0; !sbox[x]; x ^= x2 || 1, xInv = th[xInv] || 1) {
69 // Compute sbox
70 s = xInv ^ xInv << 1 ^ xInv << 2 ^ xInv << 3 ^ xInv << 4;
71 s = s >> 8 ^ s & 255 ^ 99;
72 sbox[x] = s;
73 sboxInv[s] = x;
74
75 // Compute MixColumns
76 x8 = d[x4 = d[x2 = d[x]]];
77 tDec = x8 * 0x1010101 ^ x4 * 0x10001 ^ x2 * 0x101 ^ x * 0x1010100;
78 tEnc = d[s] * 0x101 ^ s * 0x1010100;
79
80 for (i = 0; i < 4; i++) {
81 encTable[i][x] = tEnc = tEnc << 24 ^ tEnc >>> 8;
82 decTable[i][s] = tDec = tDec << 24 ^ tDec >>> 8;
83 }
84 }
85
86 // Compactify. Considerable speedup on Firefox.
87 for (i = 0; i < 5; i++) {
88 encTable[i] = encTable[i].slice(0);
89 decTable[i] = decTable[i].slice(0);
90 }
91 return tables;
92 }
93
94
95 let aesTables = null;
96 /**
41 * Schedule out an AES key for both encryption and decryption. This 97 * Schedule out an AES key for both encryption and decryption. This
42 * is a low-level class. Use a cipher mode to do bulk encryption. 98 * is a low-level class. Use a cipher mode to do bulk encryption.
43 * 99 *
...@@ -58,7 +114,22 @@ export default class AES { ...@@ -58,7 +114,22 @@ export default class AES {
58 * 114 *
59 * @private 115 * @private
60 */ 116 */
61 this._tables = this._precompute(); 117 // if we have yet to precompute the S-box tables
118 // do so now
119 if(!aesTables) {
120 aesTables = precompute();
121 }
122 // then make a copy of that object for use
123 this._tables = [[aesTables[0][0].slice(),
124 aesTables[0][1].slice(),
125 aesTables[0][2].slice(),
126 aesTables[0][3].slice(),
127 aesTables[0][4].slice()],
128 [aesTables[1][0].slice(),
129 aesTables[1][1].slice(),
130 aesTables[1][2].slice(),
131 aesTables[1][3].slice(),
132 aesTables[1][4].slice()]];
62 let i; 133 let i;
63 let j; 134 let j;
64 let tmp; 135 let tmp;
...@@ -113,60 +184,6 @@ export default class AES { ...@@ -113,60 +184,6 @@ export default class AES {
113 } 184 }
114 185
115 /** 186 /**
116 * Expand the S-box tables.
117 *
118 * @private
119 */
120 _precompute() {
121 let tables = [[[], [], [], [], []], [[], [], [], [], []]];
122 let encTable = tables[0];
123 let decTable = tables[1];
124 let sbox = encTable[4];
125 let sboxInv = decTable[4];
126 let i;
127 let x;
128 let xInv;
129 let d = [];
130 let th = [];
131 let x2;
132 let x4;
133 let x8;
134 let s;
135 let tEnc;
136 let tDec;
137
138 // Compute double and third tables
139 for (i = 0; i < 256; i++) {
140 th[(d[i] = i << 1 ^ (i >> 7) * 283) ^ i] = i;
141 }
142
143 for (x = xInv = 0; !sbox[x]; x ^= x2 || 1, xInv = th[xInv] || 1) {
144 // Compute sbox
145 s = xInv ^ xInv << 1 ^ xInv << 2 ^ xInv << 3 ^ xInv << 4;
146 s = s >> 8 ^ s & 255 ^ 99;
147 sbox[x] = s;
148 sboxInv[s] = x;
149
150 // Compute MixColumns
151 x8 = d[x4 = d[x2 = d[x]]];
152 tDec = x8 * 0x1010101 ^ x4 * 0x10001 ^ x2 * 0x101 ^ x * 0x1010100;
153 tEnc = d[s] * 0x101 ^ s * 0x1010100;
154
155 for (i = 0; i < 4; i++) {
156 encTable[i][x] = tEnc = tEnc << 24 ^ tEnc >>> 8;
157 decTable[i][s] = tDec = tDec << 24 ^ tDec >>> 8;
158 }
159 }
160
161 // Compactify. Considerable speedup on Firefox.
162 for (i = 0; i < 5; i++) {
163 encTable[i] = encTable[i].slice(0);
164 decTable[i] = decTable[i].slice(0);
165 }
166 return tables;
167 }
168
169 /**
170 * Decrypt 16 bytes, specified as four 32-bit words. 187 * Decrypt 16 bytes, specified as four 32-bit words.
171 * @param encrypted0 {number} the first word to decrypt 188 * @param encrypted0 {number} the first word to decrypt
172 * @param encrypted1 {number} the second word to decrypt 189 * @param encrypted1 {number} the second word to decrypt
......