Можно ли построить хорошую хеш-функцию, взяв за основу CRC32C?

Учитывая, что SSE 4.2 (части Intel Core i7 и i5) включает инструкцию CRC32, кажется разумным исследовать, можно ли создать более быструю хеш-функцию общего назначения. Согласно это только 16 бит CRC32 распределяются равномерно. Итак, какое еще преобразование можно применить, чтобы преодолеть это?

Обновить Как насчет этого? Для хеш-значения подходят только 16 бит. Отлично. Если ваша таблица 65535 или меньше, тогда отлично. Если нет, запустите значение CRC с помощью инструкции Nehalem POPCNT (подсчет населения), чтобы получить количество установленных битов. Затем используйте это как индекс в массиве таблиц. Это работает, если ваша таблица находится к югу от 1 мм записей. Я готов поспорить, что это дешевле / быстрее, чем самые эффективные хеш-функции. Теперь, когда GCC 4.5 имеет встроенный CRC32, его должно быть легко протестировать ... если бы только у меня было достаточно свободного времени, чтобы поработать над этим.

Дэйвид


person DavidD    schedule 22.04.2010    source источник


Ответы (5)


Повторно посещено, август 2014 г.
По запросу Арно Буше в недавнем комментарии и с учетом других ответов и комментариев я подтверждаю, что исходный ответ необходимо изменить или для наименее квалифицированных. Я оставил оригинал как есть, в конце, для справки.

Во-первых, и, возможно, наиболее важно, честный ответ на вопрос зависит от предполагаемого использования хэш-кода: что означает «хорошая» [хеш-функция ...]? Где / как будет использоваться хеш? (например, для хеширования относительно короткого входного ключа? Для целей индексирования / поиска, для создания дайджестов сообщений или для других целей? Какова длина самого желаемого хеш-кода, все 32 бита [CRC32 или его производных], и т. бит, меньше ... и т. д.?
Вопросы OP требуют "более быстрой универсальной хэш-функции, поэтому фокус находится на СКОРОСТИ (что-то менее интенсивное для ЦП и / или что-то, что может использовать параллельную обработку различного характера). Здесь мы можем отметить, что время вычисления самого хэш-кода часто является лишь частью проблемы при применении хеш-кода ( например, если размер хэш-кода или его внутренние характеристики приводят к множеству коллизий, требующих дополнительных циклов для обработки) .Также требование «общего назначения» оставляет много вопросов относительно возможных применений.

Имея это в виду, короткий и лучший ответ, возможно, таков:

Да, аппаратные реализации CRC32C на новых процессорах Intel можно использовать для создания более быстрых хэш-кодов; Однако имейте в виду, что в зависимости от конкретной реализации хэша и его применения общие результаты могут быть неоптимальными из-за частоты конфликтов или необходимости использования более длинных кодов. Кроме того, безусловно, следует тщательно проверять криптографическое использование хэша, потому что сам алгоритм CRC32 очень слаб в этом отношении.

В исходном ответе цитировалась статья Брета Малви об оценке хеш-функций, и, как указано в ответе Mdlg, выводы этой статьи ошибочны в отношении CRC32, поскольку реализация CRC32, на которой он был основан, была ошибочной / ошибочный. Несмотря на эту серьезную ошибку в отношении CRC32, статья предоставляет полезные рекомендации относительно свойств хэш-алгоритмов в целом. URL-адрес этой статьи больше не существует; Я нашел его на archive.today, но не знаю, есть ли он у автора другое место, а также обновил ли он его.

В других ответах здесь упоминается CityHash 1.0 как пример хеш-библиотеки, использующей CRC32C. По-видимому, это используется в контексте некоторых более длинных (более 32 бит) хэш-кодов, но не для самой функции CityHash32 (). Кроме того, использование CRC32 функциями City Hash относительно невелико по сравнению со всеми операциями сдвига, перетасовки и другими операциями, которые выполняются для создания хэш-кода. (Это не критика CityHash, для которой у меня нет практического опыта. Я пойду на шаг, из беглого обзора исходного кода, который функции CityHash производят хорошо, например, все распределенные коды, но не значительно быстрее чем различные другие хэш-функции.)

Наконец, вы также можете найти представление об этой проблеме в почти повторяющемся вопросе на ТАК.


Исходный ответ и редактирование (апрель 2010 г.)

Априори, это звучит как плохая идея!.

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

[BRB: Я ищу в Интернете ссылки на этот счет ...]

Первое обращение Google [ключевые слова = распределение CRC32], похоже, подтверждает это:
Оценка CRC32 для хеш-таблиц

Изменить: указанная выше страница и даже полная статья предоставляет хорошую основу для поиска в хэш-функциях.
Прочитав [быстро] эту статью, мы подтвердили общее заявление о том, что в целом CRC32 не следует использовать в качестве хеш, однако, в зависимости от конкретной цели хеширования, может быть возможно использовать, по крайней мере частично, CRC32 в качестве хэш-кода.

Например, младшие (или более высокие, в зависимости от реализации) 16 бит кода CRC32 имеют относительно равномерное распределение и, при условии, что никто не заботится о криптографических свойствах хэш-кода (например, тот факт, что аналогичные ключи создавать очень похожие коды), можно создать хэш-код, который использует, скажем, конкатенацию младших [или более высоких] 16 бит для двух кодов CRC32, созданных с помощью двух половин (или любого другого деления) исходного ключа.
Потребуется запустить тесты, чтобы увидеть, будет ли эффективность встроенной инструкции CRC32 по сравнению с альтернативными хэш-функциями такой, что накладные расходы на двойной вызов инструкции и объединение кода вместе и т. д. не будут приводят к более медленной работе.

person mjv    schedule 22.04.2010
comment
MJV, спасибо за ваши усилия по предоставлению того, что Минитмены могли бы назвать ... более глубоким пониманием того, что уже понято. Приношу свои извинения апостериори за то, что я не был более явным. - person DavidD; 23.04.2010
comment
CRC разработан именно для целей хеширования с минимальной вероятностью конфликтов. Это нормально для хеширования общего назначения (не связанного с безопасностью). - person srking; 10.06.2012
comment
@rsking. Не совсем. Минимизация количества возможных коллизий - это второстепенная цель при разработке CRC; основная цель - максимизировать эффективность обнаружения ошибок в контексте конкретного ожидаемого распределения ключей При чисто случайных ключах эти две цели полностью совместимы, однако CRC обычно выбираются с конкретным каналом в разум, как с точки зрения его типичного содержания, так и с точки зрения наиболее распространенных шаблонов ошибок. Это, в частности, имело место в случае CRC32, и в статье К. Брайера и Дж. Хаммонда 1975 года об этом конкретно упоминается. Более того ... - person mjv; 12.06.2012
comment
... тот факт, что CRC32 распределяется неравномерно, может быть подтвержден различными эмпирическими тестами, такими как тот, который упоминается в ответе. Такое плохое [общее] распределение не является недостатком дизайна, а скорее является подтверждением того, что основное внимание уделялось ограничению коллизий [локально] для сообщений одинаковой длины, отправленных в тот же шумный канал, а не для произвольных сообщений, отправленных на случайный шум. Следовательно, CRC не обязательно хорошо подходит для использования в качестве хэша общего назначения. - person mjv; 12.06.2012
comment
-1 В цитируемой статье, используемой в качестве справочной, используется неправильная реализация crc32 - см. Ответ Mdlg ниже. Так что эта статья не является хорошим основанием для поиска хеш-функций. Я бы хотел, чтобы этот ответ был обновлен. Судя по моему собственному эксперименту, crc32 - очень хороший кандидат на хеш-функцию. - person Arnaud Bouchez; 25.08.2014
comment
@ArnaudBouchez, спасибо, что подтолкнули меня к улучшению ответа. Кстати, я чувствовал себя обязанным внести это длинное редактирование, и может показаться, что я не хочу признавать, что был неправ. Я действительно хочу, чтобы мой первоначальный ответ был полностью неверным (чтобы вики можно было исправить, просто удалив его или добавив несколько слов вверху, указывающих, почему это неверно, и где лучше ответить быть найденным, а не в этом долгом обсуждении.) - person mjv; 26.08.2014
comment
@mjv Спасибо за обновление! Сейчас мы говорим. ;) AFAIK, OP явно запросил хэш-функцию для использования в хеш-таблицах (прочтите Обновление): так что вы можете сделать свой ответ короче - нет необходимости обсуждать другие варианты использования, например дайджест сообщения. 32 бита точности достаточно для хеш-таблицы (если в вашей хеш-таблице не будет 2 ^ 32 слотов, то есть с использованием 32 ГБ ОЗУ в x64 - что маловероятно). Итак, в этом контексте crc32c звучит как победитель как универсальная хеш-функция. Вот что говорится в вашем ответе! Здорово! :) - person Arnaud Bouchez; 26.08.2014
comment
Ссылка на archive.today тоже не работает, копия статьи есть по адресу archive.org - person maxbublis; 21.02.2016

В статье, упомянутой в других ответах, делаются неверные выводы на основе ошибочного кода crc32. Алгоритм ранжирования Google еще не ранжирует на основе научной точности.

В отличие от упомянутой статьи «Оценка CRC32 для хеш-таблиц», выводы <сильные > CRC32 и CRC32C допустимы для использования хеш-таблицы. В авторском примере кода есть ошибка при генерации таблицы crc32. Исправление таблицы crc32 дает удовлетворительные результаты с использованием той же методологии. Кроме того, скорость инструкции CRC32 делает ее лучшим выбором во многих контекстах. Код, использующий инструкцию CRC32, на пике в 16 раз быстрее, чем оптимальная программная реализация. (Обратите внимание, что CRC32 не совсем то же самое, что CRC32C, который реализует инструкция Intel.)

CRC32 явно не подходит для использования в криптовалюте. (32 бита - это шутка с грубой силой).

person Mdlg    schedule 15.06.2010
comment
+1 Стоит отметить, что в цитируемой статье ошибочно реализован crc32! На практике, работая с текстом UTF-8, мы обнаружили, что crc32 - лучший компромисс с точки зрения скорости и коллизии (лучше, например, чем Kernighan & Ritchie, BobJenkins, FNV1a). А в последних процессорах SSE4.2 есть жестко запрограммированная программа crc32c, которая превосходит все остальные с точки зрения производительности. См. blog.synopse.info/post/2014/05/25/ и delphitools.info/2014/08/25/string-hashing-shootout/ - person Arnaud Bouchez; 25.08.2014
comment
не для криптографии: ее можно не только легко взломать, но и решить аналитически. - person Jasen; 04.05.2021

Да. CityHash 1.0.1 включает несколько новых "хороших хэш-функций". "которые используют инструкции CRC32.

person user730496    schedule 29.04.2011

Пока вы не ищете крипто-хеш, это может сработать.

person Joshua    schedule 22.04.2010

Для криптографических целей CRC32 - плохой фонд, потому что он линейен (в векторном пространстве GF (2) ^ 32) и его трудно исправить. Он может работать в не криптографических целях.

Однако в последних ядрах Intel есть Инструкции AES-NI, которые в основном выполняют 1/10 часть блочного шифрования AES за два такта. Они доступны на самых последних процессорах i5 и i7 (подробности см. На странице Википедии) . Это похоже на хорошее начало для создания криптографической хеш-функции (и хеш-функция, которая хороша для криптографии, будет полезна и для чего-нибудь еще).

Действительно, по крайней мере, один из раундов SHA-3 " 2 "кандидата (хеш-функция ECHO) построена на элементах AES. так что коды операций AES-NI обеспечивают очень существенный прирост производительности. (К сожалению, в отсутствие инструкции AES-NI производительность ECHO несколько отстой.)

person Thomas Pornin    schedule 23.04.2010