умножение поля Галуа для блока столбцов микса AES на языке c

Я работаю над программой шифрования AES, используя c, выполняя умножение поля Галуа в блоке столбцов микширования,

бывший. [https://crypto.stackexchange.com/questions/2402/how-to-solve-mixcolumns][1]

код

for galois field multiplication
    int galois_multiply( int a,int b){
        int flag,res;
        switch (a){
            case 1:
                return b;
                break;
            case 2: flag= b * 0x80;
                b= b << 1;      //left shift
                if (flag)
                    res= b ^ 0x1b;
                else
                    res= b ^0x00;
                printf("\nnumber  %d returned by galois_multiply function\n",res);
                return res;

            case 3: res= b ^ galois_multiply(2,b);
                printf("\nnumber  %d returned by galois_multiply function\n",res);
                return res;

            default:
                printf("Invalid number  %d passed to galois_multiply function\n",a);
                exit(EXIT_FAILURE);
        }
                         return 0;
    }

предположим для

  • d4×02 — это d4‹‹1, исключающее ИЛИ с 1b (поскольку установлен старший бит d4), правильный ответ — b3; тогда как с помощью этого кода я получаю 1b3
  • bf×03 — это bf‹‹1, исключающее ИЛИ с 1b (поскольку установлен старший бит bf) и bf (поскольку мы умножаем на 3), должно дать da; но с использованием кода результат 1da

даже несмотря на то, что вышеуказанная проблема решается путем маскирования старшего разряда, при использовании в столбце mixcolumn в следующем коде ответ кажется неверным, его общая матричная операция только там, где умножение заменено умножением Галуа, а сложение - операцией XOR.

void mixColumn(unsigned char **state){
    int mc[4][4]={{2,3,1,1},{1,2,3,1},{1,1,2,3},{3,1,1,2}};
    int res[4][4]={{0}};
    int i,j,k;

    for(i=0;i<4;i++){
            for(j=0;j<4;j++){
                    res[i][j]=0;
                    for(k=0;k<4;k++)
                        res[i][j]= res[i][j] ^ galois_multiply(mc[i][k],state[k][j]);
                    state[i][j]=res[i][j];
            }
    }

}

Можете ли вы найти какие-либо ошибки, которые могут вызывать ошибку ...


person Himanshu Sourav    schedule 26.04.2014    source источник
comment
Итак, похоже, вы должны маскировать старший бит.   -  person Oliver Charlesworth    schedule 26.04.2014
comment
любое предложение, как мне это сделать, я пробовал number & 0x100 , но это не помогло..   -  person Himanshu Sourav    schedule 26.04.2014
comment
Я бы начал с использования неподписанных типов. Подписанные целые могут делать ужасные вещи при смещении. Также b= b << 1; можно записать как b <<= 1;, а res= b ^0x00; AS `res = b;   -  person wildplasser    schedule 26.04.2014
comment
Ссылка, которую вы разместили, похоже, использует переменные размера short. Почему вы используете int?   -  person ryyker    schedule 26.04.2014
comment
Если вам легче думать в двоичном формате (как это часто бывает, если вы не тратите много времени на использование шестнадцатеричного кода), вы можете использовать двоичные литералы. stackoverflow.com/questions/2611764/   -  person Tyler    schedule 27.04.2014


Ответы (2)


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

flag= b * 0x80;

но то, что я должен был использовать, это

flag= b & 0x80;

мышление в biary заставило меня подумать, что это одни и те же операторы, но на уровне байтов история совсем другая, * будет умножать содержимое на 80h, тогда как & будет побитовое И (умножать) два операнда, что мне и нужно.

person Himanshu Sourav    schedule 27.04.2014

Для int
Если вы хотите очистить старший бит int x;, используйте x &=7fffffff; (удаляет только первый бит)
Для< /em> short int
Если вы хотите очистить старший бит short x;, используйте x &=7fff; (удаляет только первый бит)

если short x == 1001011111001010 и
short mask == 0111111111111111;, то
x &= mask; ==0001011111001010 (или 0x18ca)

Однако, если у вас есть: 0x1b3 (или 0x1da), но желательно 0xb3 (или 0xda), если появляется, вы хотите замаскировать первые два байта.

В таком случае установите маску на 0x00ff

Похоже, вы работаете в short int, измените свой код с int на short или (как комментирует @wildplasser) на unsigned short.

Приведенный вами пример кода содержит недостижимый код в нескольких местах и ​​не включает оператор возврата:

int galois_multiply( int a,int b){
    int flag,res;
    switch (a){
        case 1:
            return b;
            break;//unreachable code
        case 2: flag= b * 0x80;
            b= b << 1;      //left shift
            if (flag)
                res= b ^ 0x1b;
            else
                res= b ^0x00;
            printf("\nnumber  %d returned by galois_multiply function\n",res);
            return res;
            break;//unreachable code
        case 3: res= b ^ galois_multiply(2,b);
            printf("\nnumber  %d returned by galois_multiply function\n",res);
            return res;
            break;//unreachable code
        default:
            printf("Invalid number  %d passed to galois_multiply function\n",a);
            exit(EXIT_FAILURE);
    }
    //no return statement (prototype specifies one)
}

Оператор switch() не требует операторов break;, если ему предшествует какой-либо другой метод выхода, например return x;.

person ryyker    schedule 26.04.2014
comment
спасибо ryyker за ваши усилия и советы по основам.. любое предложение, как я могу замаскировать MSB, см. комментарии Оли... - person Himanshu Sourav; 26.04.2014
comment
Спасибо, ryyker, теперь он дает правильный ответ .. :) но когда я пытаюсь использовать его в методе mixcolumn, он, кажется, дает неверные значения - person Himanshu Sourav; 26.04.2014
comment
@Himu - я предлагаю опубликовать еще один конкретный вопрос по этой теме. также рассмотрите возможность использования предложений ЗДЕСЬ для лучшие ответы. - person ryyker; 26.04.2014