Можно ли использовать функцию sizeof () в C ++ для предотвращения переполнения целых чисел? - PullRequest
0 голосов
/ 24 августа 2018

Я строю математические функции, которые планирую использовать для криптографии.

Ваш алгоритм бесполезен, если код уязвим для эксплуатации.Буферы довольно легко защитить от переполнения;а как насчет целых чисел?

Я не буду делиться своими функциями Galois, но вот одна из моих обычных функций сложения:

/**/
private:
    bool ERROR;
    signed int ret;

    void error(std::string msg){
            ERROR = true;
            std::cout<<"\n[-] "<<msg<<std::endl;
    }
/**/
public:
signed int add(signed int a, signed int b){
                if(sizeof(a) > sizeof(signed int) || sizeof(b) > sizeof(signed int) || sizeof(a+b) > sizeof(signed int)){
                        error("Integer overflow!");
                        ERROR = true;
                        ret = 0;
                        return ret;
                }else{
                        ERROR = false;
                        ret = a + b;
                        return ret;
                }
                error("context failure");
                ret = 0;
                ERROR = true;
                return ret;
        }

Достаточно ли условно, чтобы предотвратить злонамеренный ввод?Если нет, то как бы я мог исправить эту уязвимость?

Ответы [ 2 ]

0 голосов
/ 25 августа 2018

Итак, я нашел свой ответ.

Я решил использовать следующую логику if для предотвращения целочисленного переполнения:

if((a >= 2000000000 || a <= -2000000000) ||
  (b >= 2000000000 || b <= -2000000000) || 
  ((a+b) >= 2000000000 || (a+b) <= -2000000000)){

После выполнения некоторых тестов я смогубедитесь, что целое число возвращается в отрицательные числа.

Так как я работаю с конечными полями, я могу ожидать, что нормальный ввод из программы не достигнет 2 миллионов, а также обеспечит обработку переполнений.

Если за пределами границ, выход.

~ edit: исправлена ​​логическая ошибка

0 голосов
/ 24 августа 2018

Как и в другом ответе, нет, sizeof не защитит от того, что вы пытаетесь сделать. Он заботится о ширине байтов типов, а не о чем-либо еще.

Вы спрашиваете о переполнении целых чисел, но в вашем примере есть удвоения. Двойные числа с плавающей запятой, и AFAIK имеют четко определенную причину «переполнения». В случае значения, которое превышает максимальное значение, вы получите + INF, положительную бесконечность. Но вы потеряете много точности задолго до этого момента. Значения с плавающей точкой не будут меняться.

AFAIK, в соответствии с текущими соответствующими стандартами C / C ++, нет никакого способа портативно обнаружить "переполнение" беззнакового целого числа (которое хорошо определено), но gcc и clang имеют встроенные средства для его обнаружения. Вы можете попытаться предсказать переполнение без знака, но лучшие и наиболее переносимые методы по-прежнему горячо обсуждаются.

Переполнение со знаком целого числа - неопределенное поведение, означающее, что реализация может свободно делать все, что захочет, встречая его.

Если вы абсолютно не готовы развернуть собственную криптографию против лучших практик , вам следует внимательно изучить, что сделали другие реализации, и убедиться, что вы понимаете, почему.

Стоит также отметить, что с точки зрения безопасности переполнения целых чисел и чисел с плавающей точкой НЕ совпадают с переполнениями буфера.

...