Keccak (wymawiane „keczak”) to kryptograficzna funkcja skrótu – algorytm, który z dowolnych danych tworzy krótki ciąg znaków o stałej długości, nazywany hashem lub skrótem. Ten sam zestaw danych zawsze daje ten sam skrót, a najmniejsza zmiana danych daje skrót zupełnie inny.
Keccak jest znany z dwóch powodów. Po pierwsze, wygrał konkurs amerykańskiego instytutu NIST na nowy standard funkcji skrótu i stał się podstawą SHA-3. Po drugie, to na nim opiera się Ethereum – od adresów portfeli, przez smart kontrakty, po strukturę danych całego blockchaina.
Z tym drugim wiąże się ciekawostka, która do dziś wprowadza w błąd programistów: „SHA-3″ używane w Ethereum nie jest tym samym co oficjalny standard SHA-3.
Skąd się wziął
Keccak zaprojektowało czterech kryptografów: Guido Bertoni, Joan Daemen, Michaël Peeters i Gilles Van Assche. Joan Daemen był wcześniej współautorem algorytmu Rijndael, który w 2001 roku został przyjęty jako standard szyfrowania AES – ten sam, który dziś chroni ruch w internecie, bankowość i komunikatory.
W 2007 roku NIST ogłosił otwarty konkurs na nową funkcję skrótu. Powodem były ataki na starsze algorytmy, takie jak MD5 i SHA-1, które pokazywały, że rodzina funkcji opartych na podobnej konstrukcji może mieć wspólne słabości. SHA-2 nie został złamany, ale świat kryptografii chciał mieć zapasowy standard, zbudowany na zupełnie innej zasadzie.
Do konkursu zgłoszono kilkadziesiąt propozycji. Po kilku latach analiz, 2 października 2012 roku NIST ogłosił zwycięzcę: Keccak. W sierpniu 2015 roku opublikowano oficjalny standard SHA-3 (FIPS 202).
Jak działa: konstrukcja gąbki
Większość wcześniejszych funkcji skrótu, w tym MD5, SHA-1 i SHA-2, opierała się na konstrukcji Merkle’a–Damgårda: dane są przetwarzane blok po bloku, a każdy wynik pośredni trafia do kolejnego kroku.
Keccak działa inaczej. Wykorzystuje konstrukcję gąbki (sponge construction), która ma dwie fazy:
Wchłanianie (absorbing) – dane wejściowe są dzielone na kawałki i kolejno „wsiąkają” w wewnętrzny stan algorytmu, który po każdym kawałku jest dokładnie mieszany.
Wyciskanie (squeezing) – z wymieszanego stanu „wyciska się” wynik o potrzebnej długości.
Wewnętrzny stan Keccaka ma 1600 bitów i jest mieszany przez permutację powtarzaną w 24 rundach. Część stanu nigdy nie jest bezpośrednio ujawniana na zewnątrz – i to ona odpowiada za bezpieczeństwo.
Praktyczna zaleta gąbki: z jednej konstrukcji można uzyskać skrót dowolnej długości. Dlatego w ramach SHA-3 istnieją także funkcje SHAKE, które zwracają wynik o długości wybranej przez użytkownika.
Keccak-256 a SHA3-256 – różnica, która ma znaczenie
Tu zaczyna się część najważniejsza dla każdego, kto ma do czynienia z Ethereum.
W trakcie standaryzacji NIST wprowadził drobną zmianę w sposobie uzupełniania danych (tzw. padding) – dodał kilka bitów służących do rozróżniania wariantów funkcji. Sam rdzeń algorytmu pozostał bez zmian, ale wyniki są zupełnie inne.
Ethereum powstawało w latach 2014–2015, zanim ostateczny standard został opublikowany. Twórcy sieci użyli oryginalnego Keccaka w wersji z konkursu – i tak zostało.
Przykład. Skrót pustego ciągu znaków:
| Funkcja | Wynik |
|---|---|
| Keccak-256 (Ethereum) | c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 |
| SHA3-256 (standard NIST) | a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a |
Te same dane, ten sam rdzeń algorytmu, zupełnie inny wynik.
Żeby było trudniej: w języku Solidity funkcja przez pierwsze lata nazywała się sha3(), choć liczyła Keccak-256. Dopiero później zmieniono jej nazwę na keccak256(). W starszym kodzie, dokumentacji i poradnikach „SHA-3″ w kontekście Ethereum niemal zawsze oznacza Keccak-256.
Dla programisty to klasyczna pułapka: biblioteka kryptograficzna z funkcją sha3_256 zwróci wynik, który nie zgodzi się z niczym w Ethereum. Trzeba użyć funkcji wprost nazwanej Keccak-256.
Gdzie Keccak pracuje w Ethereum
Keccak-256 jest w Ethereum wszędzie. Kilka przykładów, z którymi styka się każdy użytkownik – nawet jeśli o tym nie wie:
Adresy portfeli. Adres Ethereum to ostatnie 20 bajtów skrótu Keccak-256 z klucza publicznego, zapisane jako 40 znaków szesnastkowych z prefiksem 0x. Za każdym razem, gdy kopiujesz swój adres z MetaMaska, patrzysz na fragment wyniku Keccaka.
Suma kontrolna adresu. Wielkość liter w adresie (np. 0xAbC… zamiast 0xabc…) nie jest przypadkowa. Standard EIP-55 wykorzystuje Keccak do ustalenia, które litery mają być wielkie. Dzięki temu portfel może wykryć literówkę w adresie, zanim wyślesz środki w próżnię.
Wywołania funkcji w smart kontraktach. Gdy portfel wysyła polecenie transfer(address,uint256) do kontraktu tokena, nie przesyła nazwy funkcji, tylko pierwsze 4 bajty jej skrótu Keccak-256 – w tym przypadku 0xa9059cbb. Ten identyfikator zobaczysz w polu danych niemal każdego przelewu tokenów ERC-20.
Zdarzenia (events). Logi zapisywane przez kontrakty, takie jak informacja o transferze tokena, są identyfikowane skrótem Keccak ich sygnatury.
Struktura danych blockchaina. Stan sieci, transakcje i potwierdzenia są przechowywane w drzewach, w których każdy węzeł jest identyfikowany skrótem Keccak.
Ten sam algorytm, choć w innej roli, wykorzystują też niektóre inne sieci i projekty zgodne z Ethereum.
Keccak a SHA-256 bitcoina
Bitcoin korzysta z SHA-256 z rodziny SHA-2 – do kopania, identyfikatorów transakcji i częściowo do adresów. Ethereum wybrało Keccak.
| SHA-256 (Bitcoin) | Keccak-256 (Ethereum) | |
|---|---|---|
| Rodzina | SHA-2 | SHA-3 (wersja przed standaryzacją) |
| Konstrukcja | Merkle–Damgård | gąbka |
| Autorzy | NSA, standard NIST z 2001 roku | Bertoni, Daemen, Peeters, Van Assche |
| Długość wyniku | 256 bitów | 256 bitów |
| Status bezpieczeństwa | niezłamany | niezłamany |
Oba algorytmy są dziś uznawane za bezpieczne. Wybór między nimi nie był kwestią tego, który jest „lepszy”, tylko projektowych decyzji twórców poszczególnych sieci.
Cztery mity
Mit 1: „Ethereum używa SHA-3.” Ethereum używa Keccak-256 w wersji sprzed standaryzacji. Oficjalny SHA3-256 daje inne wyniki dla tych samych danych.
Mit 2: „Keccak zastąpił SHA-2, bo SHA-2 został złamany.” SHA-2 nie został złamany. SHA-3 powstał jako zapasowy standard, zbudowany na innej zasadzie na wypadek przyszłych ataków.
Mit 3: „Z hasha da się odtworzyć dane.” Funkcja skrótu jest jednokierunkowa. Z adresu Ethereum nie da się wyliczyć klucza publicznego, a tym bardziej prywatnego.
Mit 4: „Wielkie i małe litery w adresie Ethereum nie mają znaczenia.” Dla sieci nie mają – adres działa tak samo. Ale dla portfela są sumą kontrolną, która pozwala wykryć błąd przy przepisywaniu.
Jak sam na to patrzę
Nie jestem kryptografem i nie muszę rozumieć każdej rundy permutacji, żeby bezpiecznie korzystać z Ethereum. Ale kilka rzeczy z tego hasła uważam za praktycznie ważne dla każdego, kto trzyma środki w portfelu.
Pierwsza: adres to skrót, a nie tajemnica. Adres portfela możesz podawać publicznie. Tajemnicą jest klucz prywatny i fraza odzyskiwania – i to ich trzeba chronić.
Druga: pole danych transakcji mówi, co naprawdę podpisujesz. Pierwsze cztery bajty to identyfikator funkcji. Jeśli portfel pokazuje 0x095ea7b3 zamiast 0xa9059cbb, to nie jest przelew, tylko approve – zgoda na to, żeby kontrakt mógł wydawać Twoje tokeny. Właśnie w ten sposób działa znaczna część oszustw z drenowaniem portfeli.
Trzecia: szczegóły techniczne mają znaczenie. Różnica między Keccak-256 a SHA3-256 to kilka bitów w paddingu – a wystarcza, żeby wszystko przestało się zgadzać. To dobra lekcja pokory wobec technologii, której się nie rozumie w pełni.
Co zapamiętać
Keccak to kryptograficzna funkcja skrótu oparta na konstrukcji gąbki, zwycięzca konkursu NIST na standard SHA-3 i podstawa kryptografii Ethereum.
Trzy rzeczy ponad resztą:
Keccak-256 w Ethereum to nie jest SHA3-256. NIST zmienił padding przy standaryzacji, więc wyniki są różne.
Adres Ethereum to ostatnie 20 bajtów skrótu Keccak-256 z klucza publicznego. Można go podawać publicznie – tajemnicą jest klucz prywatny.
Pierwsze 4 bajty danych transakcji to skrót nazwy funkcji. Warto wiedzieć, co podpisujesz, zanim klikniesz „potwierdź”.


