Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Крипто, кастомная функция получения ключа
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Математика и Физика
denyslb
Требуется помощь тех, кто соображает в криптографии, т.к. мои познания в теме очень поверхностны.

Задача - сделать алгоритм формирования ключа из passphrase, чтобы он не перебирался слишком просто на ASIC/GPU/FPGA (как например PBKDF2).

Функция такова:
Есть фиксированный salt[X]
Есть password
первый оборот -
intermediate[0] = SHA512(salt+password)
intermediate[n] = SHA512(intermediate[0] + ... + intermediate[n-1]) (т.е. хешируем все бОльший и больший блок)
Т.е. упор на то, что в последующих оборотах используется материал всех предыдущих(чтобы не параллелили), и к концу обьем используемой памяти растет(чтобы не засунули в ASIC/FPGA с быстрой памятью перебирающий в несколько потоков)
Конечное вычисление = последний оборот.

Имеет ли право на жизнь такое?


kolobok0
Цитата(denyslb @ Nov 27 2017, 22:47) *
...Есть фиксированный salt[X]
Есть password
первый оборот -
intermediate[0] = SHA512(salt+password)
intermediate[n] = SHA512(intermediate[0] + ... + intermediate[n-1]) (т.е. хешируем все бОльший и больший блок)
...Имеет ли право на жизнь такое?


ОФФ/2:

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

out[0] = f1(password)
out[1] = f2(out[0])
out[2] = f2(out[1])
out[3] = f2(out[2])
out[n] = f2(out[n-1])

где
- f1 не обратимая функция (взятие хэша от пароля)
- f2 обратимая функция шифрования

собственно алгоритм вскрытия банален и виден не вооружённым взглядом.
смотрите - не сделайте похожий ляп biggrin.gif

с уважением
(круглый)
jojo
Первый проход
intermediate[0] = SHA512(salt+password)
intermediate[n] = SHA512(intermediate[n-1])
Второй проход

= SHA512(intermediate[SHA512(intermediate[0]&ff.ff])&ff.ff]) n раз

Примеры scrypt, cryptonight и, конечно, Ethereum.
myq
Выглядит, вроде, нормально. Тут каждая функция необратима. Только нет смысла усложнять. Просто SHA m раз. m равно общему числу хэширований в вашей схеме, примерно n*n / 2 (арифм. прогрессия).
denyslb
Цитата(jojo @ Dec 1 2017, 01:05) *
Первый проход
intermediate[0] = SHA512(salt+password)
intermediate[n] = SHA512(intermediate[n-1])
Второй проход

= SHA512(intermediate[SHA512(intermediate[0]&ff.ff])&ff.ff]) n раз

Примеры scrypt, cryptonight и, конечно, Ethereum.

В обоих случаях оптимизации, если мы делаем просто несколько оборотов (как в PBKDF2) мы используем лишь 64*2 байта памяти, чего я стараюсь намеренно избежать.
Чем больше памяти использует KDF - тем хуже для запихивания ее перебора в FPGA/GPU и распараллеливания.
jojo
Цитата(denyslb @ Dec 4 2017, 02:33) *
В обоих случаях оптимизации, если мы делаем просто несколько оборотов (как в PBKDF2) мы используем лишь 64*2 байта памяти, чего я стараюсь намеренно избежать.
Чем больше памяти использует KDF - тем хуже для запихивания ее перебора в FPGA/GPU и распараллеливания.


Я может скобки не так расставил. Что, и в этом случае тоже?
Идея в том, чтобы использовать часть текущего значения хэша для обращения к заранее вычисленному массиву.
На первом проходе массив заполняется хэшами последовательно.
intermediate[0] = SHA512(salt+password)
intermediate[n] = SHA512(intermediate[n-1])
На втором проходе младшие биты последнего хэша используются как адрес в ранее вычисленном массиве:
address0=intermediate[n]&ff.ff
hash0=SHA512(intermediate[address0])
address1=hash0&ff.ff
hash1=SHA512(intermediate[address1]) и т.д.

Примеры того, что вы хотите сделать, я привёл выше.
denyslb
Цитата(jojo @ Dec 4 2017, 14:38) *
Я может скобки не так расставил. Что, и в этом случае тоже?
Идея в том, чтобы использовать часть текущего значения хэша для обращения к заранее вычисленному массиву.
На первом проходе массив заполняется хэшами последовательно.
intermediate[0] = SHA512(salt+password)
intermediate[n] = SHA512(intermediate[n-1])
На втором проходе младшие биты последнего хэша используются как адрес в ранее вычисленном массиве:
address0=intermediate[n]&ff.ff
hash0=SHA512(intermediate[address0])
address1=hash0&ff.ff
hash1=SHA512(intermediate[address1]) и т.д.

Примеры того, что вы хотите сделать, я привёл выше.

Если как вы написали - intermediate массив заполнен (4 мбайта еще надо суметь заполнить хорошим хешем), то ваша функция скорее тогда дополнение к изначальной, в принципе неплохая идея.
Но я подумываю сделать немного по другому, особенность DDR памяти в том, что intermediate[n] вычитывается из памяти очень быстро и возможно кешируется, GDDR5X как раз читает куском в 64 байта, т.е. все равно считается достаточно быстро в GPU.
А вот если я сделаю составление аргумента для SHA512 скажем из 1 байта из каждого intermediate элемента...
Т.е. например
start = intermediate[n]&0xffff
i = 0..63 {
arg |= intermediate[(start+i)&0xffff][i] << i; (т.е. первый байт аргумента получаем, из первого 64 байт куска, первый байт в нем и т.д.)
}

и т.д. (возможно есть более аккуратный способ написать это)
И писать таким же образом, модифицируя исходный intermediate, по байту, это заодно вымоет все возможные кеши в типичных архитектурах.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.