only run precompute for tables once, slice copy after that
Showing
1 changed file
with
72 additions
and
55 deletions
... | @@ -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 | ... | ... |
-
Please register or sign in to post a comment