Skip to content
Learning Platform
Intermediate
20 minutes
Keccak SHA-3 Конструкция губки Ethereum

Prerequisites:

  • 03-hash-functions

Keccak и SHA-3

Зачем это нужно: ловушка для разработчиков Ethereum

Ethereum использует Keccak-256, а не SHA-3-256. Это одно и то же? Нет! Они дают разные хеши для одних и тех же данных. Если вы используете стандартную библиотеку SHA-3 для вычисления Ethereum-адреса, вы получите неверный результат.

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

Краткая история

  1. 2007-2012: NIST проводит конкурс на новый стандарт хеширования (SHA-3)
  2. 2012: Команда Guido Bertoni, Joan Daemen, Michael Peeters, Gilles Van Assche побеждает с алгоритмом Keccak
  3. 2014: Ethereum начинает разработку и выбирает Keccak как хеш-функцию
  4. 2015 (август): NIST публикует финальный стандарт SHA-3 (FIPS 202) — но с измененным padding по сравнению с оригинальным Keccak
  5. 2015 (июль): Ethereum запускается с оригинальным Keccak (до публикации SHA-3)

Результат: Ethereum навсегда “застрял” с оригинальным Keccak, а стандарт SHA-3 использует другой padding.

Конструкция губки (Sponge Construction)

В отличие от SHA-256, который использует конструкцию Merkle-Damgard, Keccak/SHA-3 основан на конструкции губки (sponge construction).

Конструкция губки (Sponge)
Состояние Keccak1600 бит = rate (r) + capacity (c). Для Keccak-256: r=1088, c=512. Для SHA-3-256: r=1088, c=512, но другой padding.
rate (r) = 1088 бит
capacity (c) = 512 бит
Фаза впитывания (Absorb)
Блок M1
XOR
r
c
f-перестановка (Keccak-f)
Блок M2
XOR
r
c
f-перестановка (Keccak-f)
... повторяется для каждого блока входных данных ...
Фаза выжимания (Squeeze)
r
c
Читаем r
Выход Z1
Для Keccak-256: нужно 256 бит, r=1088 бит -- хватает одного выжимания
Ключевое отличие от Merkle-DamgardВ конструкции губки capacity (c) никогда не XOR-ится с входом и не читается напрямую. Это обеспечивает безопасность: атакующий не имеет доступа к полному состоянию.

Как работает губка

Состояние — это массив из 1600 бит, разделенный на две части:

  • Rate (r) — открытая часть, через которую поступают данные и извлекается хеш
  • Capacity (c) — скрытая часть, обеспечивающая безопасность (не доступна напрямую)

Фаза впитывания (Absorb):

  1. Начинаем с нулевого состояния (1600 нулевых бит)
  2. XOR блок входных данных с rate-частью состояния
  3. Применяем перестановку Keccak-f (24 раунда)
  4. Повторяем для каждого блока данных

Фаза выжимания (Squeeze):

  1. Читаем rate-часть состояния как выходные данные
  2. Если нужно больше выходных бит — применяем перестановку и читаем снова
  3. Для Keccak-256: нужно 256 бит, rate = 1088 бит — хватает одного выжимания

Сравнение с SHA-256

Merkle-Damgard vs Конструкция губки
Merkle-Damgard (SHA-256)
IV (256 бит)
M1
Функция сжатия f
M2
Функция сжатия f
Хеш (256 бит)
Фиксированный размер состояния = размер выхода. Последовательная обработка блоков. Уязвима к length extension attack.
Конструкция губки (Keccak/SHA-3)
Нулевое состояние (1600 бит)
XOR rate
M1
Перестановка Keccak-f
XOR rate
M2
Перестановка Keccak-f
Squeeze
Хеш (256 бит из rate)
Большое внутреннее состояние (1600 бит) > размер выхода. Capacity защищает от length extension. Нет уязвимости к этой атаке.
Свойство
SHA-256
Keccak-256 / SHA-3
Конструкция
Merkle-Damgard
Губка (Sponge)
Внутреннее состояние
256 бит
1600 бит
Размер блока
512 бит
1088 бит (rate)
Раундов
64
24 перестановки
Length extension
Уязвима
Защищена
Bitcoin
SHA-256
--
Ethereum
--
Keccak-256

Преимущества конструкции губки

  1. Защита от length extension attack: В SHA-256 (Merkle-Damgard) злоумышленник может продолжить хеширование, не зная исходного сообщения. С конструкцией губки это невозможно, потому что capacity-часть скрыта.

  2. Гибкость выхода: Губка может производить выход произвольной длины (от 1 бита до бесконечности). SHA-256 всегда выдает ровно 256 бит.

  3. Большое внутреннее состояние: 1600 бит вместо 256 — больше “скрытой” информации.

Keccak-256 vs SHA-3-256: в чем разница?

Оба алгоритма используют одну и ту же перестановку Keccak-f[1600] с одинаковыми параметрами. Разница только в padding:

  • Keccak-256 (оригинальный): padding добавляет биты 10*1 (бит 1, нули, бит 1)
  • SHA-3-256 (NIST стандарт): padding добавляет 01 || 10*1 (дополнительные 2 бита domain separation)

NIST добавил domain separation для разделения SHA-3 и SHAKE (расширяемый вариант). Это минимальное изменение, но оно приводит к полностью различным хешам.

Доказательство кодом

import hashlib
from Crypto.Hash import keccak

message = b"hello"

# SHA-3-256 (стандарт NIST, FIPS 202)
sha3_hash = hashlib.sha3_256(message).hexdigest()

# Keccak-256 (Ethereum)
keccak_hash = keccak.new(data=message, digest_bits=256).hexdigest()

print(f"SHA-3-256:    {sha3_hash}")
print(f"Keccak-256:   {keccak_hash}")
print(f"Совпадают?    {sha3_hash == keccak_hash}")  # False!

Вывод:

SHA-3-256:    3338be694f50c5f338814986cdf0686453a888b84f424d792af4b9202398f392
Keccak-256:   1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8
Совпадают?    False

Критически важно: При работе с Ethereum всегда используйте Keccak-256, а НЕ SHA-3-256!

Почему Ethereum использует Keccak-256

В 2014 году, когда Виталик Бутерин и команда Ethereum проектировали протокол, Keccak уже выиграл конкурс NIST, но финальный стандарт SHA-3 еще не был опубликован. Ethereum принял оригинальный Keccak.

Когда NIST опубликовал SHA-3 с измененным padding в 2015 году, Ethereum уже был запущен. Менять хеш-функцию в работающем блокчейне невозможно — это сломало бы все адреса, транзакции и смарт-контракты.

Где Ethereum использует Keccak-256

ПрименениеКак используется
Адресаaddress = Keccak-256(public_key)[12:] — последние 20 байт
Storage slotsKeccak-256(key . slot) — позиция данных в хранилище
Идентификаторы функцийbytes4(Keccak-256("transfer(address,uint256)"))
Event topicsKeccak-256(event_signature)
Merkle Patricia TrieХеширование узлов дерева состояний

Состояние Keccak

Внутреннее состояние Keccak — это трехмерный массив бит размером 5 x 5 x 64 = 1600 бит.

Перестановка Keccak-f[1600] выполняет 24 раунда, каждый из которых состоит из 5 шагов:

ШагНазваниеОписание
1thetaXOR столбцов с соседями — обеспечивает диффузию
2rhoЦиклический сдвиг каждого слова на разное количество бит
3piПерестановка позиций слов в матрице 5x5
4chiНелинейная операция (единственная нелинейная!)
5iotaXOR с раундовой константой — нарушает симметрию

Все 5 шагов вместе обеспечивают полную диффузию и нелинейность за 24 раунда.

Алгоритмический уровень

Вычисление Ethereum-адреса из публичного ключа

from Crypto.Hash import keccak

# Публичный ключ (64 байта, без префикса 0x04)
public_key_hex = "a1b2c3d4..."  # 128 hex символов

# Keccak-256 от публичного ключа
public_key_bytes = bytes.fromhex(public_key_hex)
k = keccak.new(data=public_key_bytes, digest_bits=256)
hash_hex = k.hexdigest()

# Адрес = последние 20 байт (40 hex символов)
address = "0x" + hash_hex[-40:]
print(f"Ethereum address: {address}")

Идентификатор функции Solidity

from Crypto.Hash import keccak

# Сигнатура функции transfer(address,uint256)
signature = b"transfer(address,uint256)"
k = keccak.new(data=signature, digest_bits=256)

# Первые 4 байта хеша = selector
selector = k.hexdigest()[:8]
print(f"Function selector: 0x{selector}")  # 0xa9059cbb

Практика

Откройте notebook 03-hashing.ipynb (раздел “Часть 3: Keccak vs SHA-3”) и:

  1. Убедитесь, что Keccak-256 и SHA-3-256 дают разные результаты
  2. Вычислите Ethereum-адрес из публичного ключа
  3. Вычислите селектор функции для approve(address,uint256)
  4. Сравните скорость SHA-256, SHA-3-256 и Keccak-256

Итоги

  • Keccak/SHA-3 использует конструкцию губки вместо Merkle-Damgard
  • Внутреннее состояние — 1600 бит (rate + capacity)
  • Конструкция губки защищена от length extension attack
  • Keccak-256 и SHA-3-256 — это разные алгоритмы (разный padding)
  • Ethereum использует Keccak-256, а НЕ SHA-3-256
  • Разница возникла потому, что Ethereum принял Keccak до финализации SHA-3 стандарта NIST
  • При работе с Ethereum всегда используйте Crypto.Hash.keccak, а не hashlib.sha3_256

Check Your Understanding

Score: 0 of 0
Analytical
Question 1 of 3. Какая основная структурная разница между SHA-256 и Keccak (SHA-3)?

Finished the lesson?

Mark it as complete to track your progress