Widestrip
@Widestrip
кодер-самоучка

В чем причина ошибки в функции keyExpansion реализации AES Java?

Перевел с Python на Java работающий алгоритм шифрования AES.
При запуске получаем ошибку Out of Bounds в функции расширения ключа.

Текст функции:

public static ArrayList<ArrayList<Integer>> keyExpansion(String key) {
	ArrayList<Integer> keySymbols = new ArrayList<>();
	for (Character c : key.toCharArray())
		keySymbols.add((int) c);
	if (keySymbols.size() < 4 * nk)
		for (int i = 0; i < 4 * nk - keySymbols.size(); i++)
			keySymbols.add(0x01);
	ArrayList<ArrayList<Integer>> keySchedule = new ArrayList<>();
	for (int r = 0; r < 4; r++) {
		keySchedule.add(new ArrayList<>());
		for (int c = 0; c < nk; c++)
			keySchedule.get(r).add(keySymbols.get(r + 4 * c));
	}
	for (int col = nk; col < nb * (nr + 1); col++)
		if (col % nk == 0) {
			ArrayList<Integer> tmp = new ArrayList<>();
			for (int row = 1; row < 4; row++)
				tmp.add(keySchedule.get(row).get(col - 1));
			tmp.add(keySchedule.get(0).get(col - 1));
			for (int j = 0; j < tmp.size(); j++) {
				int sBoxR = tmp.get(j) / 0x10;
				int sBoxC = tmp.get(j) % 0x10;
				int sBoxElem = sBox[16 * sBoxR + sBoxC];
				tmp.set(j, sBoxElem);
			}
			for (int row = 0; row < 4; row++) {
				int s = keySchedule.get(row).get(col - 4) ^ tmp.get(row) ^ rCon[row][col / nk - 1];
				keySchedule.get(row).add(s);
			}
		} else {
			for (int row = 0; row < 4; row++) {
				int s = keySchedule.get(row).get(col - 4) ^ keySchedule.get(row).get(col - 1);
				keySchedule.get(row).add(s);
			}
		}
	return keySchedule;
}


Ошибка вылезает в строке:
keySchedule.get(r).add(keySymbols.get(r + 4 * c));

Значения nk, nb и nr (4, 4, 10) - заданы заранее глобальными переменными.
Массивы sBox и rCon - тоже.
Длина ключа не превышает 4 * nk = 16.

В чем может быть проблема?
В Питоне данный код работает как надо.
  • Вопрос задан
  • 53 просмотра
Решения вопроса 1
Widestrip
@Widestrip Автор вопроса
кодер-самоучка
Ответ от @Dmitry Roo

В цикле
for (int i = 0; i < 4 * nk - keySymbols.size(); i++)

верхнюю границу выносим наружу, так как она пересчитывается при каждом шаге цикла
if (keySymbols.size() < 4 * nk) {
	var toAdd = 4 * nk - keySymbols.size();
	for (int i = 0; i < toAdd; i++) {
		keySymbols.add(0x01);
	}
}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
xez
@xez Куратор тега Java
TL Junior Roo
Очевидно, потому, что "r + 4 * c" больше длины keySymbols
При r = 0, значения будут 0, 4, 8, 12 и т.д...
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы