Zatem do rzeczy: czym jest "oznaczony skrót"? Jak zapewne niektórzy zauważyli, swego czasu opisałem szczegółowo na anglojęzycznych częściach, jak działają funkcje skrótu, rozłożone na czynniki pierwsze:
Dlaczego funkcje skrótu są bezpieczne?
Wzmocnione SHA-1 kontra osłabione SHA-256: Jak je testować?
Na podstawie tych dwóch tematów wyżej (a zwłaszcza tego pierwszego, gdzie pokazuję podział na wektor inicjalizacyjny, dane, oraz hash końcowy) można zademonstrować, czym tak naprawdę jest "oznaczony skrót". Wróćmy do obrazka, który pokazałem w tamtym temacie:
wiadomość: 80000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
skrót końcowy: da39a3ee 5e6b4b0d 3255bfef 95601890 afd80709
Następnie mamy wiadomość, w przypadku SHA-1 oraz SHA-256, składającą się z 512-bitowego zestawu, który jest odpowiednio rozszerzany. Obie wymienione funkcje skrótu implementują samą wiadomość identycznie, nawet sposób dokładania jedynki na końcu, zer w celu wyrównania danych, a także 64-bitowego rozmiaru całości w bitach, wygląda dokładnie tak samo. Różnice występują dopiero przy rozszerzaniu wiadomości na kolejne rundy.
Ostatecznie, uzyskujemy skrót końcowy, który przy tych samych danych wejściowych, będzie zawsze identyczny. Oznacza to tyle, że SHA-1 pustej wiadomości zawsze i wszędzie wynosi dokładnie "da39a3ee 5e6b4b0d 3255bfef 95601890 afd80709".
W przeciwieństwie do poprzedniego tematu, tutaj zakładamy, że mamy do czynienia z więcej niż jednym blokiem danych. Dlaczego? Otóż cała idea oznaczonego skrótu polega właśnie na tym, aby wykorzystać atak rozszerzający wiadomość i zamienić go w coś pożytecznego. Spróbujmy zatem wykonać właśnie ten atak na dwóch blokach i zobaczyć, co nam z tego wyjdzie. Zaatakujmy pusty blok w taki sposób, aby dołożyć kolejny pasujący blok, dokładając tylko tyle danych, ile musimy:
pierwsza wiadomość: 80000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
skrót pośredni: da39a3ee 5e6b4b0d 3255bfef 95601890 afd80709
druga wiadomość: 80000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000200
skrót końcowy: c80b973c 1157a7fe 4f4150ad 4c2a9324 94bf7bc7
I właśnie na tym polega ten słynny oznaczony skrót, używany w Taproocie. Zamiast używać typowego wektora inicjalizacyjnego, mamy do czynienia z jakimiś danymi początkowymi, które zmieniają nam wektor inicjalizacyjny i sprawiają, że startujemy od innej wartości niż zwykle.
Przejdźmy zatem do SHA-256 i zobaczmy, jak to wygląda w praktyce. Naszym źródłem będzie tutaj BIP-340:
wektor inicjalizacyjny: 6a09e667 bb67ae85 3c6ef372 a54ff53a
510e527f 9b05688c 1f83d9ab 5be0cd19
pierwsza wiadomość: 7bb52d7a 9fef5832 3eb1bf7a 407db382
d2f3f2d8 1bb1224f 49fe518f 6d48d37c
7bb52d7a 9fef5832 3eb1bf7a 407db382
d2f3f2d8 1bb1224f 49fe518f 6d48d37c
skrót pośredni: c216d352 f5818b7b 4beacd4a e0a26fe8
88080823 d2a59885 6661bcd5 4f1b3713
tagged_hash("BIP0340/aux")=07fab5f97e680abb8389d1fa164281e124439468f5bd699fcbd1ae86e6405d69
Planuję jeszcze odgrzebać stare tematy związane z Taprootem, bo z tego co pamiętam, tam mogły być też używane takie hashe, bodajże przy tworzeniu klucza publicznego, który może być wydany tylko przez pojedynczą sygnaturę Schnorra, bez żadnego TapScriptu. Poszukam i postaram się to uzupełnić, na razie kończę w tym miejscu.
Zachęcam do pytań, żeby wiedzieć, w jakim kierunku pisać i czy w ogóle chcecie tego więcej, czy też idę w zbyt ciężkostrawne technikalia i powinienem zacząć od przetłumaczenia swoich starszych wpisów o funkcjach skrótu, zanim dotknę oznaczonych skrótów i innych nowszych tematów.