react-native-aes-lite 1.0.1-0.rc → 1.0.1-1.rc
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AES.js +62 -56
- package/package.json +1 -1
package/dist/AES.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { randomBytes } from "./randomBytes";
|
|
3
3
|
|
|
4
4
|
/* ============================================================
|
|
5
|
-
UTF-8
|
|
5
|
+
UTF-8 Encode / Decode (Hermes-safe)
|
|
6
6
|
============================================================ */
|
|
7
7
|
function utf8Encode(str) {
|
|
8
8
|
const out = [];
|
|
@@ -25,9 +25,8 @@ function utf8Decode(bytes) {
|
|
|
25
25
|
let s = "";
|
|
26
26
|
for (let i = 0; i < bytes.length; ) {
|
|
27
27
|
const c = bytes[i++];
|
|
28
|
-
if (c < 0x80)
|
|
29
|
-
|
|
30
|
-
} else if (c < 0xe0) {
|
|
28
|
+
if (c < 0x80) s += String.fromCharCode(c);
|
|
29
|
+
else if (c < 0xe0) {
|
|
31
30
|
const c2 = bytes[i++];
|
|
32
31
|
s += String.fromCharCode(((c & 0x1f) << 6) | (c2 & 0x3f));
|
|
33
32
|
} else {
|
|
@@ -85,7 +84,7 @@ class AES {
|
|
|
85
84
|
}
|
|
86
85
|
|
|
87
86
|
/* ============================================================
|
|
88
|
-
UTILITY
|
|
87
|
+
UTILITY
|
|
89
88
|
============================================================= */
|
|
90
89
|
hexToBytes(h) {
|
|
91
90
|
return Uint8Array.from(h.match(/../g).map((x) => parseInt(x, 16)));
|
|
@@ -94,25 +93,40 @@ class AES {
|
|
|
94
93
|
return [...b].map((x) => x.toString(16).padStart(2, "0")).join("");
|
|
95
94
|
}
|
|
96
95
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
96
|
+
/* ============================================================
|
|
97
|
+
parseKey — supports ASCII + HEX
|
|
98
|
+
============================================================= */
|
|
99
|
+
parseKey(key) {
|
|
100
|
+
// HEX
|
|
101
|
+
if (/^[0-9a-fA-F]+$/.test(key)) {
|
|
102
|
+
if ([32, 48, 64].includes(key.length)) {
|
|
103
|
+
return key.match(/../g).map((b) => parseInt(b, 16));
|
|
104
|
+
}
|
|
105
|
+
throw new Error("Hex key must be 32, 48, or 64 chars");
|
|
106
|
+
}
|
|
103
107
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
108
|
+
// ASCII
|
|
109
|
+
if ([16, 24, 32].includes(key.length)) {
|
|
110
|
+
return key.split("").map((c) => c.charCodeAt(0));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
throw new Error("Key must be 32/48/64 hex OR 16/24/32 ASCII");
|
|
107
114
|
}
|
|
108
115
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
116
|
+
/* ============================================================
|
|
117
|
+
PKCS7
|
|
118
|
+
============================================================= */
|
|
119
|
+
pkcs7Pad(a) {
|
|
120
|
+
const pad = 16 - (a.length % 16);
|
|
121
|
+
return [...a, ...Array(pad).fill(pad)];
|
|
122
|
+
}
|
|
123
|
+
pkcs7Unpad(a) {
|
|
124
|
+
const pad = a[a.length - 1];
|
|
125
|
+
return a.slice(0, -pad);
|
|
112
126
|
}
|
|
113
127
|
|
|
114
128
|
/* ============================================================
|
|
115
|
-
|
|
129
|
+
KEY EXPANSION
|
|
116
130
|
============================================================= */
|
|
117
131
|
keyExpansion(key) {
|
|
118
132
|
const Nk = key.length / 4;
|
|
@@ -124,24 +138,24 @@ class AES {
|
|
|
124
138
|
}
|
|
125
139
|
|
|
126
140
|
for (let i = Nk; i < w.length; i++) {
|
|
127
|
-
let
|
|
141
|
+
let temp = [...w[i - 1]];
|
|
128
142
|
|
|
129
143
|
if (i % Nk === 0) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
144
|
+
temp.push(temp.shift());
|
|
145
|
+
temp = temp.map((x) => this.SBOX[x]);
|
|
146
|
+
temp[0] ^= this.RCON[i / Nk];
|
|
133
147
|
} else if (Nk > 6 && i % Nk === 4) {
|
|
134
|
-
|
|
148
|
+
temp = temp.map((x) => this.SBOX[x]);
|
|
135
149
|
}
|
|
136
150
|
|
|
137
|
-
w[i] = w[i - Nk].map((b, j) => b ^
|
|
151
|
+
w[i] = w[i - Nk].map((b, j) => b ^ temp[j]);
|
|
138
152
|
}
|
|
139
153
|
|
|
140
154
|
return { w, Nr };
|
|
141
155
|
}
|
|
142
156
|
|
|
143
157
|
/* ============================================================
|
|
144
|
-
|
|
158
|
+
ROUND FUNCTIONS
|
|
145
159
|
============================================================= */
|
|
146
160
|
subBytes(s) {
|
|
147
161
|
for (let r = 0; r < 4; r++)
|
|
@@ -186,15 +200,15 @@ class AES {
|
|
|
186
200
|
|
|
187
201
|
invMixColumns(s) {
|
|
188
202
|
const mul = (a, b) => {
|
|
189
|
-
let
|
|
203
|
+
let r = 0;
|
|
190
204
|
for (let i = 0; i < 8; i++) {
|
|
191
|
-
if (b & 1)
|
|
205
|
+
if (b & 1) r ^= a;
|
|
192
206
|
const hi = a & 0x80;
|
|
193
207
|
a = (a << 1) & 0xff;
|
|
194
208
|
if (hi) a ^= 0x1b;
|
|
195
209
|
b >>= 1;
|
|
196
210
|
}
|
|
197
|
-
return
|
|
211
|
+
return r;
|
|
198
212
|
};
|
|
199
213
|
|
|
200
214
|
for (let c = 0; c < 4; c++) {
|
|
@@ -219,7 +233,7 @@ class AES {
|
|
|
219
233
|
}
|
|
220
234
|
|
|
221
235
|
/* ============================================================
|
|
222
|
-
CIPHER
|
|
236
|
+
CIPHER
|
|
223
237
|
============================================================= */
|
|
224
238
|
cipher(input, w, Nr) {
|
|
225
239
|
let s = [[], [], [], []];
|
|
@@ -229,11 +243,11 @@ class AES {
|
|
|
229
243
|
|
|
230
244
|
s = this.addRoundKey(s, w, 0);
|
|
231
245
|
|
|
232
|
-
for (let
|
|
246
|
+
for (let r = 1; r < Nr; r++) {
|
|
233
247
|
s = this.subBytes(s);
|
|
234
248
|
s = this.shiftRows(s);
|
|
235
249
|
s = this.mixColumns(s);
|
|
236
|
-
s = this.addRoundKey(s, w,
|
|
250
|
+
s = this.addRoundKey(s, w, r);
|
|
237
251
|
}
|
|
238
252
|
|
|
239
253
|
s = this.subBytes(s);
|
|
@@ -241,28 +255,21 @@ class AES {
|
|
|
241
255
|
s = this.addRoundKey(s, w, Nr);
|
|
242
256
|
|
|
243
257
|
const out = new Array(16);
|
|
244
|
-
for (let i = 0; i < 16; i++)
|
|
245
|
-
|
|
246
|
-
}
|
|
247
|
-
return out;
|
|
258
|
+
for (let i = 0; i < 16; i++) out[i] = s[i % 4][(i / 4) | 0];
|
|
259
|
+
return Uint8Array.from(out);
|
|
248
260
|
}
|
|
249
261
|
|
|
250
|
-
/* ============================================================
|
|
251
|
-
INVERSE CIPHER (DECRYPT ONE BLOCK)
|
|
252
|
-
============================================================= */
|
|
253
262
|
invCipher(input, w, Nr) {
|
|
254
263
|
let s = [[], [], [], []];
|
|
255
264
|
|
|
256
|
-
for (let i = 0; i < 16; i++)
|
|
257
|
-
s[i % 4][(i / 4) | 0] = input[i];
|
|
258
|
-
}
|
|
265
|
+
for (let i = 0; i < 16; i++) s[i % 4][(i / 4) | 0] = input[i];
|
|
259
266
|
|
|
260
267
|
s = this.addRoundKey(s, w, Nr);
|
|
261
268
|
|
|
262
|
-
for (let
|
|
269
|
+
for (let r = Nr - 1; r >= 1; r--) {
|
|
263
270
|
s = this.invShiftRows(s);
|
|
264
271
|
s = this.invSubBytes(s);
|
|
265
|
-
s = this.addRoundKey(s, w,
|
|
272
|
+
s = this.addRoundKey(s, w, r);
|
|
266
273
|
s = this.invMixColumns(s);
|
|
267
274
|
}
|
|
268
275
|
|
|
@@ -271,10 +278,8 @@ class AES {
|
|
|
271
278
|
s = this.addRoundKey(s, w, 0);
|
|
272
279
|
|
|
273
280
|
const out = new Array(16);
|
|
274
|
-
for (let i = 0; i < 16; i++)
|
|
275
|
-
|
|
276
|
-
}
|
|
277
|
-
return out;
|
|
281
|
+
for (let i = 0; i < 16; i++) out[i] = s[i % 4][(i / 4) | 0];
|
|
282
|
+
return Uint8Array.from(out);
|
|
278
283
|
}
|
|
279
284
|
|
|
280
285
|
/* ============================================================
|
|
@@ -290,36 +295,37 @@ class AES {
|
|
|
290
295
|
const padded = this.pkcs7Pad(pt);
|
|
291
296
|
|
|
292
297
|
let out = [];
|
|
293
|
-
let prev = iv;
|
|
298
|
+
let prev = Uint8Array.from(iv);
|
|
294
299
|
|
|
295
300
|
for (let i = 0; i < padded.length; i += 16) {
|
|
296
301
|
const block = padded.slice(i, i + 16);
|
|
297
|
-
const
|
|
298
|
-
const enc = this.cipher(
|
|
302
|
+
const x = block.map((b, j) => b ^ prev[j]);
|
|
303
|
+
const enc = this.cipher(x, w, Nr);
|
|
299
304
|
out.push(...enc);
|
|
300
|
-
prev = enc;
|
|
305
|
+
prev = Uint8Array.from(enc);
|
|
301
306
|
}
|
|
302
307
|
|
|
303
|
-
return this.bytesToHex(iv) + ":" + this.bytesToHex(out);
|
|
308
|
+
return this.bytesToHex(iv) + ":" + this.bytesToHex(Uint8Array.from(out));
|
|
304
309
|
}
|
|
305
310
|
|
|
306
311
|
decrypt(input, keyHex) {
|
|
307
312
|
const [ivHex, dataHex] = input.split(":");
|
|
313
|
+
|
|
308
314
|
const key = this.parseKey(keyHex);
|
|
309
315
|
const { w, Nr } = this.keyExpansion(key);
|
|
310
316
|
|
|
311
|
-
const iv =
|
|
312
|
-
const data =
|
|
317
|
+
const iv = this.hexToBytes(ivHex);
|
|
318
|
+
const data = this.hexToBytes(dataHex);
|
|
313
319
|
|
|
314
320
|
let out = [];
|
|
315
|
-
let prev = iv;
|
|
321
|
+
let prev = Uint8Array.from(iv);
|
|
316
322
|
|
|
317
323
|
for (let i = 0; i < data.length; i += 16) {
|
|
318
324
|
const block = data.slice(i, i + 16);
|
|
319
325
|
const dec = this.invCipher(block, w, Nr);
|
|
320
326
|
const x = dec.map((b, j) => b ^ prev[j]);
|
|
321
327
|
out.push(...x);
|
|
322
|
-
prev = block;
|
|
328
|
+
prev = Uint8Array.from(block);
|
|
323
329
|
}
|
|
324
330
|
|
|
325
331
|
return this.decode(this.pkcs7Unpad(out));
|