Как получить биты шестнадцатеричной реализации AES

у меня есть sbox для реализации типа AES, например

int   box[4][4] = {{0xA,0x3,0xC,0xB},
            {0xE,0xF,0x2,0xE},
            {0x6,0x4,0x0,0xF},
            {0xC,0x4,0xF,0x3}};

я хочу получить первые 2 бита и последние 2 бита шестнадцатеричного числа, а затем заменить его позицией в sbox, например

  int x = 0xA //Because A has a binary representation from hex as 1010

тогда номер строки станет первыми 2 битами A "10", а номер столбца станет вторыми 2 битами A "10", поэтому int x перейдет в sbox и будет заменен на "0xF"

как я могу получить биты A и использовать их для поиска моего sbox?


person theForgottenCoder    schedule 08.03.2014    source источник
comment
Почему заменено на 0xF, если в этой позиции есть 0x0?   -  person Joachim Isaksson    schedule 08.03.2014
comment
o я начинаю с позиции 0, поэтому sbox имеет столбцы 0 1 2 3 и строки 0 1 2 3, но в любом случае 0x0 или 0xF знаете ли вы, как получить биты указанной позиции и получить доступ к sbox   -  person theForgottenCoder    schedule 08.03.2014
comment
Вы должны помнить, что шестнадцатеричный формат — это всего лишь презентационная функция. В любом случае, все это хранится в двоичном формате внутри компьютера. Кроме того, вам нужны (всего) четыре бита самого младшего полубайта, вы не можете забыть, что int обычно составляет 32 бита, что означает, что два старших бита означают что-то еще.   -  person Some programmer dude    schedule 08.03.2014
comment
также Иоахим Пилеборг да, мне трудно всегда помнить, что шестнадцатеричное число в c - это просто представление, и оно по-прежнему представлено как двоичное, также да, я знаю, что обычно 32 бита, это моя проблема, я просто хочу младшие 4 биты, и я хочу разделить их на 2 и использовать их для поиска моего sbox Спасибо за то, что мирились с моей неопытностью, любая помощь приветствуется!   -  person theForgottenCoder    schedule 08.03.2014
comment
Joachim Isaksson Работал блестяще, спасибо   -  person theForgottenCoder    schedule 08.03.2014


Ответы (1)


x = box[x & 3][(x >> 2) & 3]; будет работать, если вы сказали, что «номер строки станет первыми 2 битами», вы имели в виду два младших бита из четырех [т.е. два правых]; в противном случае (когда вы сказали «первые 2», вы имели в виду «левые 2»), x = box[(x >> 2) & 3][x & 3]; - это то, что вам нужно.

В целом, однако, ваш доступ к двумерному массиву медленнее, чем доступ к одномерному массиву, поэтому вместо этого я бы использовал одномерный массив и не изолировал две пары битов как отдельные индексы. Вместо этого используйте младшие 4 бита x в качестве одномерного индекса. Тогда не будет никакого дополнительного смещения и маскирования или умножения и добавления вычисления адреса смещения 2D.

Если "первые 2 бита" означают "самые правые 2 бита"...

int box[16] = {0xA,0xE,0x6,0xC, 0x3,0xF,0x4,0x4, 0xC,0x2,0x0,0xF, 0xB,0xE,0xF,0x3};

Если "первые 2 бита" означают "самые левые 2 бита"...

int box[16] = {0xA,0x3,0xC,0xB, 0xE,0xF,0x2,0xE, 0x6,0x4,0x0,0xF, 0xC,0x4,0xF,0x3};

Затем, чтобы использовать коробку...

x = box[x & 0xF];  // use the bottom 4 bits as single index

Надеюсь, это поможет :-)

person Amos    schedule 13.03.2014
comment
Просто дополнительное примечание... последняя строка кода, x = box[x & 0xF];, использует маску 0xF, которую достаточно легко понять, но вам все равно придется продумать эти необработанные шестнадцатеричные маски, чтобы определить, какие биты будут 1 или 0. Вы можете также генерирует эту маску во время компиляции (не влияет на скорость), например... #define MASK (~(~0 << 4) << 0). ~ 0 (инвертировать 0) - это все 1 с. ~0 ‹‹ 4 — это все единицы с 4 нулями справа. Инвертируйте, и вы получите все 0 с 4 единицами справа. Левый сдвиг 0 запускает нижний конец 4 1 с бита 0. Измените последний 0 на 12, и 4 1 начнутся с 12 бита. - person Amos; 13.03.2014