Рейтинг:4

Много близких столкновений, но нет полного столкновения

флаг in

Я прочитал этот вопрос: Крекинг $f(x) = Cx \oplus Dx$ Спрашивая о поиске коллизий в простом 64-битном хэше, я подумал, что попробую сам, просто для удовольствия. Я быстро написал код для поиска коллизий: https://gist.github.com/meirmaor/b0e59352eb73cacec47d0f95c25a25fc

И все же он находит много близких столкновений и не находит полных столкновений, это меня сбивает с толку.

Описание алгоритма: Я хотел решить эту проблему, используя 8 ГБ оперативной памяти, поэтому я выделяю два массива Int длины $2^{30}$ *(4 байта int) каждый. Я заполняю их, хэшируя значения Int, беру младшие 30 бит в качестве индекса в оба массива и сохраняю верхние 32 бита в первом массиве, а исходный int — во втором массиве.

я заполняю с помощью $2^{32}$ возможные значения Int (в виде массивов байтов) и получить, как и ожидалось, скорость заполнения 98%, варьируются близко к идеализированному $1-е^{-4}$ Я ожидал.

Это похоже на хеш-таблицу, но я не имею дело с коллизиями, просто сохраняю одно значение для каждого 30-битного хеш-ключа. По сути, это сопоставление усеченного 62-битного хэша с 32-битным источником.

Затем я пытаюсь хешировать более длинные значения с дополнительным префиксом Int и искать столкновения, снова используя младшие 30 бит в качестве индекса для массива, проверяя, совпадают ли верхние 32, и если они совпадают, мы обнаружили близкое столкновение. Однако при их проверке я не обнаружил полного столкновения, я нашел более 60 близких столкновений, проверил их отдельно, они действительно совпадают в 62 или 63 битах, но я ожидал, что 1/4 будет полным столкновением, я получил 0.

Я повторил тест дважды, сначала сравнив хэши из 4 байтов с хэшами из 8 байтов, начиная с байтов {маленькое число, 0,0,0}. Затем я попытался сравнить хэши одинаковой длины, предварительно заполнив хэши данных, начиная с последовательности байтов {1,0,0,0}, и снова сравнив с префиксом {2+,0,0,0}.

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

Пример найденного ближнего столкновения (у меня их много):

Массив (24, 0, 0, 0, 14, 103, 61, 80) против Массив (1, 0, 0, 0, -2, -81, 79, 79)

Meir Maor avatar
флаг in
Моей следующей попыткой будет двухпальцевый алгоритм памяти O(1), но я до сих пор не знаю, почему первая попытка не удалась.
Рейтинг:5
флаг ng

Позднее важное дополнение: теперь я понимаю, что код пытается найти коллизии для 64-битного $\имя_оператора{хэш}$ прием 64-битных сообщений. Если это $\имя_оператора{хэш}$ была биекцией, она не сталкивалась. Существует континуум между биекцией и случайной функцией, и нет гарантии, что $\имя_оператора{хэш}$ ведет себя в основном как позже. Наоборот, это внутренняя функция $f(x)=C\,x\oplus D\,x\bmod2^{64}$ не имеет правой диффузии. Это, $x\equiv x'\pmod{2^i}\предполагает f(x)\equiv f(x')\pmod{2^i}$, таким образом $f$ это плохая хеш-функция раунда. Это может объяснить, по крайней мере частично, трудности обнаружения коллизий методами, разработанными для случайных функций. В более позднем я предполагаю одно из:

  • место для сообщений $х$ является $b$-бит с $b$ значительно больше, чем (64-битный вывод)
  • мы пытаемся найти столкновения $х,х'$ такой, что $\operatorname{хэш}(p\mathbin\|x)=\operatorname{хэш}(p'\mathbin\|x')$ куда $р$ и $р'$ фиксированные различные префиксы, $х,х'$ находятся $b=64$-кусочек, $x\nex'$.

Я подозреваю, что еще одна важная проблема заключается в том, что в

Я заполняю (массивы) хешированием значений Int

это хэш постепенный Внутренние значения. Вполне возможно сделать такую ​​функцию, чтобы инкрементальные значения на большом интервале не сталкивались, и вполне возможно, что функция $\имя_оператора{хэш}$ поиск коллизий ведет себя так, поэтому любая попытка найти коллизии среди последовательных значений терпит неудачу.

В качестве примера функции без коллизий для ввода на небольшом интервале рассмотрим $H(x)=\left(263x+\left(\operatorname{MD5}(x)\bmod256\right)\right)\bmod2^{64}$. Он держит $H(x)-H(x')\equiv263(x-x')+(r-r')\pmod{2^{64}}$, с $r,r'\in[0,255]$ так как они получены как последний байт MD5; таким образом $\lvert r-r'\rvert<256$. Следовательно, если $x\nex'$, единственный способ получить $Н(х)=Н(х')$ в том, что $\lvert x-x'\rvert$ большой, по крайней мере $\lэтаж 2^{64}/263\rэтаж$, что не будет иметь место для последовательных $х$ в небольшом промежутке.

При попытке найти коллизии для такой недостаточно случайной хеш-функции $Ч$, простое решение состоит в том, чтобы найти коллизии для более случайной функции $x\mapstoH(G(x))$, построенный с помощью некоторой псевдослучайной вспомогательной биекции $G$, например $G(x)=G_2(G_1(G_0(x)))$ с $G_i(x)=k_i(x\oplus(x\gg\lceil b/3+1\rceil))\bmod2^b$ за $k_i$ случайный странный $b$-битовые константы [где $\гг$ правый сдвиг, и $b$ битовый размер $х$]. Однажды столкновение $х,х'$ находится с $ Н (G (х)) = Н (G (х')) $ но $x\nex'$, столкновение за $Ч$ является $G(х),G(х')$.


Одним из преимуществ поиска столкновений с помощью ро Полларда с выделенными точками (в отличие от метода в коде вопроса) является то, что его итеративный характер часто решает проблему недостаточно случайной функции, искомой для столкновений, без вспомогательного $G$; или относительно простой $G$ подойдет (здесь я думаю, что 1-битный поворот в обратной связи ро Полларда должен сделать, компенсируя отсутствие правильной диффузии). Кроме того, ро Полларда использует меньше памяти, поэтому работает для больших хэшей; а для быстрых хэш-функций это быстрее, потому что это удобно для кэширования.

kodlu avatar
флаг sa
красивый. есть ли глубокая алгебраическая причина в том, что ваш хэш, связанный с MD5, не допускает столкновений для последовательных целочисленных значений? кроме того, что 263 является относительно простым относительно соответствующего модуля? не может сказать с первого взгляда
Reppiz avatar
флаг gb
я лично не очень понял как, соответственно почему G фикс работает. Есть ли какое-либо дальнейшее (или более подробное) объяснение? Также подойдет ссылка на статью, блог, статью и т. д., в которой каким-то образом описывается этот метод.
fgrieu avatar
флаг ng
@Reppiz: теперь я пытаюсь объяснить это. По сути, если у нас есть проблема с $H$ из-за того, что она недостаточно случайна, мы делаем ее более случайной, вводя $G$.
fgrieu avatar
флаг ng
@Meir Maor: обязательно прочитайте новое вступление!
Meir Maor avatar
флаг in
Да, я беспокоился об этом, и это превращается в действительно отличный ответ. В моей попытке было несколько недостатков. Тем не менее мой успех в обнаружении близких столкновений с (несколько меньшей, но не намного меньшей) ожидаемой скоростью сбил меня с толку.
Рейтинг:2
флаг cn

Слишком неуважительно, чтобы комментировать...

Я ожидаю, что это проблема реализации - описание метода на высоком уровне кажется разумным. Может ли он найти коллизию, если вместо этого вы используете префиксы 0x01000099 и 0xDEADBD5C?

Спойлер: например 0x010000992287FF50 по сравнению с 0xDEADBD5C05F19159

Метод, используемый для обнаружения этой коллизии, по существу такой же, как тот, который вы описываете, за исключением того, что я также использовал это, если мы можем найти коллизию 56 старших байтов хэша (или, технически, хеш без конечного применение f), то тривиально расширить последовательность байтов на один байт каждую, чтобы получить полную (64-битную) коллизию.

fgrieu avatar
флаг ng
Это выглядит как законный ответ (а не комментарий) для меня, даже если он отвечает «почему не обнаружено столкновений» на «должно быть»; и у меня есть альтернативное объяснение.
Meir Maor avatar
флаг in
Сюжет утолщается, с этими префиксами мой код находит 65 близких столкновений и 64 из них становятся полными столкновениями. В идеальной функции я ожидал бы найти одно близкое столкновение в каждой паре префиксов (потому что я храню только 1/4 значений, хешированных в первом префиксе).
Maarten Bodewes avatar
флаг in
Что-то мод 127 или подобное?

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.