tradingview

Keccak

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ź”.