Koch Laboratory

Czas jako dowód, raz jeszcze: incydent z kluczem i log, który można skontrolować z zewnątrz

Kontynuuje i koryguje wpis z 20 sierpnia 2026, już pod nazwą Sigelith. Klucz podpisujący współdzielony z lustrem deweloperskim obalił założenie, że ważny podpis wskazuje nasze korzenie; zaufanie przeszło na log, który każdy może pobrać i przeliczyć (RFC 9162), oraz na kopie i kotwice w cudzych rękach. Do tego przedziały czasu dla każdego wpisu z Bitcoina i banku zamiast z naszego zegara, kopie zapasowe niosące własny dowód i przegląd tego, co klient pokazywał jako sprawdzone — z granicami każdego z tych elementów.

Koch Laboratory — czas jako dowód, raz jeszcze: incydent z kluczem i log, który można skontrolować z zewnątrz

Wpis z 2026-08-20 („Czas jako uzgodniona jednostka i jako dowód”) opisywał usługę czasu, której wskazanie ma się bronić przed kimś, kto nie ufa ani nam, ani naszemu serwerowi. Sześć tygodni później wiadomo, że jedno z jego twierdzeń było słabsze, niż wyglądało: przez ponad trzy miesiące ten sam klucz podpisujący był skonfigurowany na dwóch maszynach. Ten wpis opisuje, co z tego wynikło, co zbudowano w odpowiedzi i które stwierdzenia poprzedniego wpisu wymagają korekty. Poprzedni wpis pozostaje niezmieniony; korekty są tutaj, z datą.

Nazwa. Od 27 września 2026 cała infrastruktura dowodowa — log, checkpointy, dokumenty PDF z dowodem i API weryfikacji — nazywa się Sigelith i działa pod adresem sigelith.org. Strony pod beattime.live przekierowują (301) pod ten sam adres w sigelith.org; API, pliki dowodów i wszystko, co czyta program, odpowiada pod oboma adresami bez przekierowania. Identyfikatory formatów wewnątrz podpisanych bajtów pozostają bez zmian (beattime-proof-v1, beattime-entry-v1, beattime-checkpoint-v1) — zmiana nazwy w podpisanych danych unieważniłaby każdy wydany dowód. Nazwa BeatTime oznacza dziś wyłącznie dwie aplikacje na Androida: zegar i tarczę zegarka. Zegar pozostaje zegarem Internet Time — doba podzielona na 1000 części, kotwica w UTC — a wskazanie zapisuje się jako @beat, np. @523.

Co tu jest badaniem, a co nie. Większość opisanych elementów to integracja opublikowanych standardów: drzewa Merkle z dowodami inkluzji i spójności (RFC 9162), kanoniczny JSON (RFC 8785), podpisy Ed25519 (RFC 8032), OpenTimestamps, uwierzytelniona synchronizacja czasu NTS (RFC 8915). Żaden z tych mechanizmów nie jest nasz. Treścią badawczą są granice — co dokładnie obejmuje podpis, co poświadcza kotwica, czego nie poświadcza kopia — oraz to, co zawiodło.

Metodyka. Jak w reszcie laboratorium: problem → stan techniki → falsyfikowalne kryterium → metoda → wynik (potwierdzony, obalony albo częściowy, z warunkami brzegowymi) → następny krok. Wynik negatywny jest wynikiem. Liczby dotyczące logu pochodzą z jego publicznych danych i każdy może je sprawdzić bez pytania nas; liczby z testów są oznaczone jako takie.

1. Kierunek 1 — wynik negatywny: ważny podpis nie wskazywał, czyj jest korzeń

Problem. Wpis z 2026-08-20 traktował podpis Ed25519 nad tygodniowym korzeniem Merkle jako potwierdzenie, że korzeń pochodzi od nas. Od 15 czerwca do 21 września 2026 ten sam klucz prywatny był jednak skonfigurowany na dwóch maszynach: w usłudze produkcyjnej i na lustrze deweloperskim. Lustro wykonuje te same zadania cykliczne, więc zamknęło własne tygodnie, podpisało ich korzenie wspólnym kluczem i zakotwiczyło je w Bitcoinie przez OpenTimestamps. Powstały dwa takie korzenie, dla tygodni 2026-W25 i 2026-W30. Błąd ujawnił własny przegląd bezpieczeństwa we wrześniu 2026. Stan techniki (publikowany). W znakowaniu czasem według RFC 3161 i ETSI EN 319 421 kompromitację klucza jednostki znakującej obsługuje się unieważnieniem i powiadomieniem — zaufanie pozostaje przy dostawcy. W Certificate Transparency (RFC 6962, RFC 9162) log, który podpisze dwa niezgodne stany, traci zaufanie w całości. Obie odpowiedzi zakładają, że podpis identyfikuje wystawcę. Kryterium (falsyfikowalne). Hipoteza wpisu z 2026-08-20: ważny podpis naszym kluczem identyfikuje korzeń jako nasz. Obala ją jeden korzeń z ważnym podpisem, który nie jest naszym korzeniem. Kryterium zastępcze: korzeń autorytatywny musi dać się ustalić bez zaufania do podpisu, z danych przechowywanych poza naszą infrastrukturą. Metoda. Rotacja klucza 21 września 2026 i ponowne podpisanie każdego opublikowanego korzenia nowym kluczem — korzenie się nie zmieniają, a ich istnienie w czasie poświadczają Bitcoin i bank, więc ponowny podpis niczego nie przesuwa w czasie. Sam kod podpisujący odrzuca wycofany klucz; każda maszyna przypina klucz publiczny, którym wolno jej podpisywać, więc źle skonfigurowana maszyna kończy bez podpisu, a nie z obcym; lustro niczego już nie kotwiczy. Historia kluczy jest publiczna i nic się z niej nie usuwa. Pierwsza publiczna notka mówiła tylko o rotacji „po przeglądzie bezpieczeństwa”; kilka dni później opublikowaliśmy pełny opis z listą odrzuconych korzeni (sigelith.org/spec/#incident-2026-09), bo odrzucony korzeń, którego sami nie nazwiemy, wygląda wiarygodnie dla każdego, komu ktoś pokaże go z ważnym podpisem. Strona podaje trzy sprawdzenia wykonalne bez zaufania do nas — w tym rozstrzygające dla W25: korzeń tego tygodnia na lustrze zamrożono w poniedziałek tego samego tygodnia, a korzeń tygodniowy nie może być końcowy przed końcem swojego tygodnia. Wynik. Hipoteza obalona: dwa korzenie z ważnym podpisem (2026-W25, 2026-W30) nie są naszymi korzeniami; publikujemy je sami, z nazwy, jako odrzucone. Żaden skrót w logu się nie zmienił, żaden stempel nie zginął ani nie został przedatowany — osłabło twierdzenie oparte na samym podpisie. Kryterium zastępcze spełnione: korzeń autorytatywny każdego tygodnia to ten, który odtwarza się z opublikowanych wpisów tego tygodnia (kopie u stron trzecich, kierunek 2), a dla tygodni z kotwicą bankową — także ten zapisany w tytule przelewu MROOT. Żaden z dwóch odrzuconych korzeni tego testu nie przechodzi. Zaufanie przesunęło się z podpisu na kopie przechowywane przez innych i na kotwice: podpis jest dziś jednym ze świadków, a nie tożsamością logu. Warunki brzegowe: kotwica OpenTimestamps poświadcza czas, nie autorstwo — lustro korzystało z tych samych publicznych kalendarzy co produkcja; rotacja wymaga dziś zmiany listy kluczy w trzech miejscach (usługa, klient desktopowy, publiczne repozytorium logu) i nowego wydania klienta, a klient bez tej zmiany pokaże każdy nowy dowód jako podpisany obcym kluczem. Następny krok. Jeden klucz podpisuje dziś korzenie tygodni, checkpointy i pokwitowania stempli. Otwarte pytanie: czy checkpointy powinny nieść podpisy niezależnych świadków, jak w części logów przejrzystości, tak aby sam klucz operatora — skompromitowany albo źle skonfigurowany — nie wystarczał do przedstawienia przekonującej alternatywnej historii. Status: wynik negatywny (hipoteza obalona); korekta wdrożona i opisana publicznie.

2. Kierunek 2 — log, który można skontrolować z zewnątrz

Problem. Do 25 września 2026 każdy mógł sprawdzić swój wpis — ścieżkę inkluzji do korzenia tygodnia — ale nikt nie mógł skontrolować nas: pobrać całego logu, przeliczyć go od zera i wykazać, że nic nie zostało wycięte ani przepisane. Po kierunku 1 nie jest to brak kosmetyczny: skoro podpis nie wystarcza, potrzebne jest coś, co przechowują inni. Stan techniki (publikowany). Certificate Transparency (RFC 6962, RFC 9162): drzewo Merkle nad całym logiem, dowody inkluzji i spójności, podpisane stany drzewa; logi przejrzystości zbudowane według tego wzorca (m.in. baza sum kontrolnych modułów Go, Sigstore Rekor) oraz świadkowie, którzy kontrasygnują checkpointy. Wzorzec jest dojrzały; nie budujemy nowego. Kryterium (falsyfikowalne). Osoba bez dostępu do naszej infrastruktury pobiera cały log, przelicza łańcuch skrótów i każdy korzeń, sprawdza, że każdy późniejszy checkpoint rozszerza wcześniejszy (dowód spójności z RFC 9162), i porównuje checkpointy z kopiami przechowywanymi przez innych. Kryterium obala każda zmiana opublikowanej historii — wpis usunięty, przepisany albo przestawiony, dwa różne checkpointy o tym samym numerze — której ta procedura nie wykrywa. Metoda. Jedno globalne drzewo nad wszystkimi wpisami od pierwszego, w kształcie Merkle Tree Hash z RFC 9162. Liść wiąże numer, skrót i czas wpisu (beattime-entry-v1|numer|skrót|czas), więc jedna ścieżka dowodzi „ten skrót był wpisem nr N z chwilą T”, a nie tylko „ten skrót jest gdzieś w drzewie”. Drzewa tygodniowe, ich podpisy i tytuły przelewów zostają bez zmian — drzewo globalne je uzupełnia, nie zastępuje. Checkpoint to podpisany stan drzewa w kanonicznym JSON: wystawiany codziennie i zaraz po zamknięciu tygodnia, spięty skrótem pliku poprzedniego checkpointu, z nazwanym blokiem Bitcoina (głębokość 3; dwa niezależne eksploratory bloków muszą się zgadzać) i sam kotwiczony w Bitcoinie przez OpenTimestamps. Checkpoint nr 1 (25 września) obejmuje cały log od pierwszego wpisu — 171 wpisów. Cały log można pobrać (strony wpisów i tygodniowe zrzuty), a dowody spójności między checkpointami są dostępne publicznie (sigelith.org/checkpoints/). Kopie u stron trzecich powstają automatycznie: OpenTimestamps/Bitcoin — każdy checkpoint, codziennie; tytuł przelewu bankowego MROOT — każdy korzeń tygodnia, co tydzień; GitHub (niezmienne wydania, github.com/DeiFlagellum/sigelith-log) i Internet Archive — co tydzień; Zenodo — co kwartał, pełna migawka na licencji CC0. Od 28 września każda odpowiedź na stemplowanie niesie podpisane pokwitowanie (numer, skrót, czas, ogniwo łańcucha): log, któremu później zabraknie takiego wpisu, zostaje przyłapany własnym podpisem — tę rolę pełni SCT w Certificate Transparency. Klient desktopowy (dziś Sigelith Desktop, przed wersją 3.0 — BeatStamp) od wersji 2.2 sprawdza w tle każdy checkpoint — bajty pliku, podpis, łańcuch, spójność — porównuje go bajt w bajt z kopiami w GitHubie, Internet Archive i Zenodo, a blok sprawdza u niezależnego eksploratora; checkpoint o znanym numerze i innej treści zachowuje jako materiał dowodowy. W trybie domyślnym trzyma kopię całego logu i liczy ścieżki sam, a serwer dowiaduje się najwyżej, o który tydzień pytano. Wynik. Potwierdzony w zakresie kryterium. Dowody inkluzji i spójności sprawdzono przed włączeniem wyczerpująco dla każdego rozmiaru drzewa od 1 do 64 (test): przyjętych 2080 z 2080 prawdziwych dowodów każdego rodzaju, odrzuconych 8190 z 8190 podróbek (m.in. zła ścieżka, zły indeks, przepisany wpis w historii); dowody powstają według definicji rekurencyjnej, a sprawdza je algorytm iteracyjny — obie postaci z RFC 9162 muszą dać to samo. Druga implementacja, napisana wyłącznie z tekstu specyfikacji, celowo bez importu kodu produkcyjnego, odtworzyła produkcję przy pierwszym uruchomieniu 25 września: 171 wpisów, 13 tygodniowych zrzutów, korzeń globalny i korzenie tygodni zgodne, korzenie tygodni równe tytułom przelewów MROOT. W chwili pisania powtórzono to kolejną, osobno napisaną implementacją: korzenie przy 171 i 211 wpisach są równe korzeniom checkpointów nr 1 i nr 8, dowód spójności między nimi jest poprawny, podpis checkpointu nr 1 — także. Warunki brzegowe: (a) test wyczerpujący na małych drzewach jest argumentem za poprawnością implementacji, nie dowodem; (b) druga implementacja jest niezależna w kodzie, nie w osobie — napisał ją ten sam autor; audytu przez stronę trzecią dotąd nie było; (c) kopie w GitHubie, Internet Archive i Zenodo są bierne — przechowują, ale niczego nie sprawdzają przed przyjęciem; sprawdzają klienci i każdy, kto je pobierze, a świadków kontrasygnujących nie ma; (d) historię sprzed 25 września przypina w całości dopiero checkpoint nr 1, wcześniej — wyłącznie tygodniowe kotwice; (e) kod serwera nie jest publiczny i nie musi być, bo weryfikacja z niego nie korzysta: formaty opisują specyfikacja i publiczne repozytorium logu; (f) lokalnie weryfikuje klient desktopowy; strony w przeglądarce i aplikacja na Androida liczą skrót pliku lokalnie, ale część dotyczącą logu biorą z odpowiedzi serwera i wskazują kopie niezależne do samodzielnego porównania. Następny krok. Samodzielny skrypt weryfikacyjny dla osób trzecich, który bierze checkpoint z kopii niezależnej, a nie od nas — jedyny niewykonany punkt planu tego kierunku. Status: wdrożone od 25 września 2026 (pierwsze wydanie tygodniowe: 2026-W39, pierwsza wersja kwartalna: 2026-Q3).

3. Kierunek 3 — przedział czasu dla każdego wpisu z kotwic zewnętrznych zamiast z naszego zegara

Problem. Czas wpisu to wskazanie zegara naszego serwera. Wpis z 2026-08-20 bronił się tygodniową granulacją („nie później niż”) i publikacją własnego błędu zegara, ale oba elementy pozostają naszym słowem. Najpoważniejszy zarzut wobec każdej usługi znakowania czasem brzmi: operator wydatował wpis wstecz na czyjąś prośbę. Odpowiedź na ten zarzut nie może zależeć od zegara operatora. Stan techniki (publikowany). RFC 3161: czas pochodzi z zegara urzędu i jest wart tyle, ile zaufanie do urzędu; łańcuchowe znakowanie czasem (Haber i Stornetta, 1991) — kolejność bez zaufania, ale bez czasu bezwzględnego; OpenTimestamps — górna granica („istniało nie później niż”) z Bitcoina; Roughtime — uwierzytelniony czas zgrubny z dowodem niewłaściwego zachowania serwera; NTS (RFC 8915) — uwierzytelniona synchronizacja zegara. Dolną granicę daje znana technika: wartość, której nie dało się znać przed daną chwilą — tu skrót bloku Bitcoina — dowodzi, że to, co ją zawiera, powstało później. Kryterium (falsyfikowalne). Dla każdego wpisu obie granice dają się wyprowadzić bez naszego zegara, z danych przechowywanych poza naszą infrastrukturą, a zapisany czas wpisu leży między nimi. Kryterium obala jeden wpis, którego zapisany czas leży poza jego własnym przedziałem. Metoda. Każdy wpis ma trzy czasy. Zapisany — zegar serwera, do mikrosekundy; to jedyne nasze słowo. Nie wcześniej niż — blok Bitcoina nazwany w ostatnim checkpoincie wystawionym przed wpisem: wpis leży poza drzewem tego checkpointu, więc dopisano go później, a checkpoint nie mógł powstać przed wydobyciem swojego bloku. Nie później niż — najwcześniejsza kotwica obejmująca wpis: atestacja OpenTimestamps pierwszego checkpointu, który go zawiera, atestacja korzenia tygodnia albo księgowanie przelewu z tym korzeniem. API i dokument PDF z dowodem podają wszystkie trzy wraz ze ścieżką wpisu do pierwszego checkpointu, który go zawiera — dokument i checkpoint wzięty z kopii niezależnej wystarczają do sprawdzenia bez nas. Niezależnie od tego zegar hosta podąża dziś za czterema serwerami czasu trzech niezależnych operatorów, uwierzytelnianymi przez NTS; źródło, które odbiega od pozostałych, zostaje przegłosowane. Usługa co pięć minut mierzy też swój offset względem zewnętrznego serwera i publikuje wynik — przedział z kotwic tego pomiaru jednak nie potrzebuje. Wynik. Potwierdzony dla wpisów od pierwszego checkpointu (25 września 2026); częściowy dla logu jako całości. Sprawdzenie w chwili pisania objęło wszystkie 41 wpisów od tamtej chwili: zapisany czas w każdym przypadku leży w przedziale; 40 wpisów ma obie granice (najnowszy czeka na kotwicę następnego checkpointu); szerokość przedziału od około 14 do 25,5 godziny, mediana około 25. Przykład: wpis nr 191 (ogłoszenie nazwy Sigelith), zapisany 27 września o 17:17:27 UTC — nie wcześniej niż 26 września, 23:43 UTC (blok 968756), nie później niż 28 września, 00:35 UTC (blok 968908). Warunki brzegowe: (a) czasy bloków pochodzą z nagłówków, które górnik ustawia z dokładnością do około dwóch godzin — granice są dokładne co do godzin, nie sekund; (b) przedział dotyczy chwili zapisu w logu, nie powstania dokumentu; (c) 171 wpisów sprzed pierwszego checkpointu ma wyłącznie górną granicę, a dolnej nie da się dodać wstecz; (d) księgowanie bankowe niesie datę bez godziny; (e) dolna granica stoi na nienaruszalnej kolejności logu, a tę sprawdzają dowody spójności względem kopii u innych (kierunek 2). Następny krok. Kotwicę bankową widać dziś publicznie jako tytuł MROOT i numer referencji; samodzielne sprawdzenie wymaga wyciągu albo potwierdzenia banku. Specyfikacja dopuszcza publikację wyciągów z ukrytymi danymi, a dotąd żadnego nie opublikowano. Następny krok: ustalić, czy taki wyciąg daje osobie trzeciej coś, czego nie daje sam numer referencji. Status: wdrożone; pełny przedział dla wpisów od 25 września 2026, dla wcześniejszych wyłącznie górna granica.

4. Kierunek 4 — kopia zapasowa, która niesie własny dowód

Problem. Program kopii zapasowych porównuje pliki z własnym spisem treści, który leży obok nich. Kto podmienia pliki — ransomware, włamanie, psujący się nośnik, ktoś z dostępem do dysku — może podmienić i spis, a wtedy weryfikacja wypada pomyślnie. Do tego wykazanie, że konkretny plik był w kopii z danego dnia, wymaga zwykle ujawnienia całej kopii albo przynajmniej jej spisu. Stan techniki (publikowany). restic (check --read-data) i Borg (check --verify-data) sprawdzają dane względem uwierzytelnionego indeksu repozytorium — ochrona opiera się na kluczu, który przechowuje użytkownik; nośniki i magazyny niezmienne (WORM, blokada obiektów) chronią przed zmianą, ale same nie dają dowodu osobie trzeciej; solone skróty do selektywnego ujawniania (m.in. SD-JWT); separacja domen liści i węzłów z RFC 6962. Kryterium (falsyfikowalne). (1) Jeden wpis w publicznym logu na jedną wersję kopii, bez nazw plików i ich skrótów; (2) dla dowolnego pojedynczego pliku dowód, który nie ujawnia innych plików wersji; (3) audyt wykrywa podmianę pliku także wtedy, gdy podmieniono spis treści obok plików. Kryterium obala podmiana, której audyt nie wykrywa przy nienaruszonym wpisie w logu. Metoda. Sigelith Backup — program do wersjonowanych, opcjonalnie szyfrowanych kopii na dysk zewnętrzny, z publicznym kodem (github.com/DeiFlagellum/sigelith-backup) — opatruje każdą wersję oświadczeniem: skrótem spisu wersji (ścieżka, rozmiar i SHA-256 każdego pliku) i korzeniem drzewa Merkle nad plikami wersji. Liść to SHA-256 z bajtu domeny, soli, skrótu pliku, rozmiaru i skrótu ścieżki; sól to HMAC-SHA256 z losowego ziarna wersji i ścieżki. Do logu trafia wyłącznie skrót oświadczenia — jeden wpis na wersję. Dowód pojedynczego pliku (sigelith-file-proof-v1) to ścieżka w drzewie, oświadczenie i osadzony dowód wpisu w logu; ścieżkę pliku można w nim ujawnić albo nie. Audyt sprawdza oświadczenie bez sieci (ścieżka w drzewie tygodnia i podpis kluczem wpisanym w program, a nie podanym przez serwer), a potem czyta z nośnika każdy plik — po odszyfrowaniu z kontrolą znacznika uwierzytelniającego GCM i po złożeniu fragmentów — i porównuje go ze skrótem objętym oświadczeniem. Wzorcem jest wpis w publicznym logu, nie spis leżący obok plików. „Ostatnia nietknięta” to najnowsza wersja zgodna ze swoim wpisem — z niej warto przywracać po ataku. Kopia „na bieżąco” dogrywa zmiany do dzisiejszej wersji; wersji, która ma już swoje oświadczenie, nie uzupełnia się nigdy, a przy włączonym stemplowaniu pierwsza dogrywka nowego dnia zamyka wczorajszą wersję i dopiero wtedy ją stempluje. Wynik. Potwierdzony w zakresie kryterium (testy): podmiana pliku wykryta także po zniszczeniu albo „poprawieniu” spisu treści; zmieniony spis objęty oświadczeniem nie daje fałszywego „nietknięta”; w kopii zaszyfrowanej wykryty jeden zmieniony bit szyfrogramu; ścieżka do korzenia sprawdzona dla drzew od 1 do 1000 liści; dowód pliku nie ujawnia innych plików ani ziarna. Ten sam format dowodu pliku sprawdzają trzy implementacje na wspólnym wektorze testowym: sam program, klient desktopowy i strona weryfikacji w przeglądarce. Warunki brzegowe, podane wprost: (a) audyt wiąże pliki z jakimś wpisem w publicznym logu, ale nie dowodzi, że to pierwszy wpis dla tej wersji — stemplować może każdy, więc kto ma prawo zapisu na nośniku, może przebudować wersję i opatrzyć ją nowym wpisem; zdradziłaby go późniejsza data wpisu, którą program pokazuje w oknie znaczników czasu, ale której audyt dziś nie porównuje z datą wersji; (b) brak sieci nie jest błędem kopii — wpis wysyła się przy następnej kopii, więc i uczciwy wpis bywa późniejszy niż data wersji, co osłabia rozróżnienie z punktu (a); (c) przy włączonym stemplowaniu na zaszyfrowanym nośniku spis wersji (ścieżki, rozmiary i SHA-256 treści jawnej każdego pliku) oraz oświadczenie leżą obok zaszyfrowanych plików w postaci jawnej — ścieżki i tak widać jako nazwy plików, ale skróty treści jawnej pozwalają każdemu, kto ma nośnik, sprawdzić, czy znany mu plik jest w kopii; (d) dowód pliku poświadcza, że plik o tych bajtach był w wersji ostemplowanej w danej chwili — nie to, kiedy plik powstał ani kto jest jego autorem; (e) kopia „na bieżąco” ma dowód z dokładnością do doby: zmiany bieżącego dnia nie mają wpisu, dopóki wersja tego dnia nie zostanie zamknięta. Następny krok. Dwa otwarte rozstrzygnięcia: czy audyt ma sam porównywać datę wpisu z datą wersji — i jak odróżnić opóźnione stemplowanie od przebudowanej wersji — oraz czy spis wersji kopii zaszyfrowanej ma być szyfrowany: kosztem jest sprawdzanie oświadczenia bez hasła, zyskiem nośnik, który nie ujawnia skrótów treści jawnej. Status: wdrożone (Sigelith Backup 3.0, kod publiczny); granice (a)–(e) obowiązują.

5. Kierunek 5 — przegląd klienta: co pokazywał jako sprawdzone, a czego nie sprawdzał

Problem. Weryfikator, który pokazuje jako sprawdzone coś, czego nie sprawdził, jest gorszy niż brak weryfikatora: zamienia twierdzenie wystawcy w zielony znaczek u odbiorcy. Klient desktopowy jest miejscem, w którym dowody sprawdza się bez pytania serwera — więc pierwszym, które trzeba było przejrzeć pod tym kątem. Stan techniki (publikowany). Znana klasa błędów: interfejs przypisuje ważność podpisu danym, których podpis nie obejmuje — opisana m.in. dla klientów poczty z OpenPGP i S/MIME („Johnny, you are fired!”, USENIX Security 2019) oraz dla podpisów w PDF; przypięcie jednego klucza bez historii — ten sam mechanizm awarii, przez który przeglądarki wycofały HTTP Public Key Pinning (RFC 7469). Kryterium (falsyfikowalne). Każda wartość pokazana jako sprawdzona jest objęta kontrolą, którą klient faktycznie wykonał; każda inna jest oznaczona jako deklaracja. Obala je jedna wartość pokazana jako sprawdzona bez takiego pokrycia. Metoda. Przegląd kodu klienta względem specyfikacji formatów — co dokładnie obejmuje każdy podpis i każda ścieżka — oraz testy przypadków manipulacji. Wynik. Kryterium obalone dla wersji sprzed 2.1. Znalezione klasy błędów, wszystkie poprawione w wersji 2.1 (wrzesień 2026): (1) klient miał wpisany na sztywno jeden klucz — ten wycofany; po rotacji odrzucałby każdy aktualny dowód jako podpisany obcym kluczem, a zarazem przyjmował korzenie z lustra; dziś zaufanie wynika z wbudowanej historii kluczy z datami, a podpis kluczem wycofanym daje najwyżej poziom „zarejestrowany” z prośbą o odświeżenie; (2) plik dowodu z przesuniętą datą był przyjmowany jako „zweryfikowany offline” — podpis obejmuje tydzień i korzeń, liść drzewa tygodniowego sam skrót, więc dokładny czas w pliku był niepodpisaną deklaracją; dziś musi leżeć w podpisanym tygodniu, a strukturalnie lukę zamyka liść drzewa globalnego, który wiąże czas (kierunek 2); (3) raport PDF dla odrzuconego dowodu nazywał go potwierdzonym; (4) kotwice bankowe liczyły się bez sprawdzenia, że niosą ten sam korzeń; (5) kilka pól z odpowiedzi serwera trafiało do etykiet interfejsu bez escapowania znaków specjalnych. Warunki brzegowe: przegląd był wewnętrzny, nie był to zewnętrzny audyt; dotyczy klienta desktopowego (github.com/DeiFlagellum/sigelith-desktop) — jedynego, który część dotyczącą logu weryfikuje lokalnie. Następny krok. Dopisać przypadki manipulacji z tego przeglądu do wspólnych wektorów testowych, tak aby każdy weryfikator — w programie kopii, w kliencie desktopowym i w przeglądarce — był sprawdzany na tym samym zestawie. Status: poprawki wdrożone; przegląd wewnętrzny.

Korekty wpisu z 2026-08-20

Wpis z 2026-08-20 pozostaje niezmieniony. Poniżej jego stwierdzenia, które są nieaktualne albo nie były dokładne.

Stempel samego wpisu. Wpis z 2026-08-20 ostemplowano 20 sierpnia 2026 o 14:52 UTC, w tygodniu 2026-W34 — w okresie incydentu z kierunku 1. Korzeń tego tygodnia podpisał pierwotnie wycofany klucz; dziś jest ponownie podpisany nowym kluczem. Data wpisu nie stoi na tamtym podpisie, tylko na kotwicach: księgowaniu przelewu z korzeniem tygodnia W34 (25 sierpnia) i atestacji Bitcoin tego korzenia przez OpenTimestamps (26 sierpnia); obejmuje go też checkpoint nr 1. Dolnej granicy z kotwic brak — wpis jest starszy niż pierwszy checkpoint. Plik stempla opublikowany obok tamtego wpisu zapisuje stan z chwili stemplowania (tydzień otwarty, korzeń tymczasowy); korzeń końcowy, ścieżkę do niego i kotwice daje log, np. zrzut tygodnia 2026-W34 w kwartalnej kopii w Zenodo.

„Warstwy aplikacyjne (Android, wear, rozszerzenie, SDK) są w budowie”. Nieaktualne: aplikacja na Androida i tarcza zegarka, klient desktopowy, rozszerzenie przeglądarki i paczki SDK są opublikowane.

Kierunek 2: „zadanie okresowe mierzy odchyłkę zegara hosta względem NTP”. Nieprecyzyjne. Pomiar to jedno nieuwierzytelnione zapytanie SNTP do jednego zewnętrznego serwera; wynik jest różnicą względem tego serwera, nie błędem względem UTC, i pozostaje naszym oświadczeniem — sygnałem stanu usługi, nie dowodem. Zegar hosta podąża dziś za czterema serwerami uwierzytelnianymi przez NTS, a dowód czasu nie opiera się na naszym zegarze (kierunek 3).

Kierunek 3: podpis Ed25519 jako część wyniku „potwierdzony”. Dla okresu od 15 czerwca do 21 września 2026 niedokładne: ten sam klucz prywatny był na lustrze deweloperskim, więc ważny podpis nie identyfikował korzenia jako naszego (kierunek 1). Ponadto log był sprawdzalny wpis po wpisie, ale nie jako całość — tę lukę zamyka kierunek 2.

Kierunek 4: „co najmniej dwa niezależne kanały kotwiczenia … każdy weryfikowalny osobno” — potwierdzony. Wymaga uściśleń. (a) Kotwica poświadcza czas, nie autorstwo: lustro deweloperskie zakotwiczyło swoje korzenie przez te same publiczne kalendarze OpenTimestamps. (b) Kanał bankowy jest niezależny od nas w zapisie, ale osoba trzecia widzi publicznie tylko tytuł MROOT i numer referencji; samodzielne sprawdzenie wymaga wyciągu albo potwierdzenia banku. (c) Dla tygodni 2026-W32, W33 i W34 atestacja Bitcoin korzeni przyszła dopiero 26 sierpnia — 16,5, 9,5 i 2,5 doby po zamknięciu tygodnia; górną granicę dla tych tygodni wyznacza księgowanie bankowe, w dniu zamknięcia albo dzień później. Drugi kanał nie okazał się nadmiarowy. (d) Ręczny krok kanału bankowego zawiódł raz: dla 2026-W30 zapisano drugi rekord tej samej referencji z wartością, która nie jest korzeniem tygodnia. Rekord pozostaje widoczny i oznaczony jako niezgodny; formularz wpisuje dziś korzeń sam i sprawdza jego zgodność z tygodniem.

Kierunek 6: protokół współstemplowania v2. Luka typu replay: podpis startowy pierwszej strony nie był związany z jedną sesją, więc publiczne dane zakończonej sesji wystarczały do otwarcia nowej w jej imieniu; log mógł wtedy zawierać współstempel, którego właściciel tego klucza nie wykonał. Od 21 września sól z zakończonej sesji jest odrzucana.

„Najbliższy krok badawczy: … (C2PA)”. Nie został podjęty; prace nad C2PA nie ruszyły. Wykonany został inny krok: log, który można skontrolować z zewnątrz (kierunek 2).

Status kierunku. Infrastruktura dowodowa działa pod nazwą Sigelith. Incydent z kluczem obalił założenie, że podpis identyfikuje nasze korzenie; zaufanie opiera się dziś na logu, który każdy może pobrać i przeliczyć, na kopiach przechowywanych przez GitHub, Internet Archive i Zenodo oraz na kotwicach w Bitcoinie i w banku. Każdy wpis od 25 września 2026 ma przedział czasu niezależny od naszego zegara; kopie zapasowe niosą własny dowód z jawnie podanymi granicami; klient desktopowy pokazuje jako sprawdzone tylko to, co sprawdził. Najbliższe kroki: samodzielny skrypt weryfikacyjny dla osób trzecich i rozstrzygnięcia z kierunku 4. Kapsuły czasowe — koperty zamknięte do wybranej chwili w przyszłości — i protokół dowodu doręczenia będą opisane w osobnym wpisie.


Dowód czasu

Ten tekst został zahaszowany i ostemplowany przy publikacji. Do sprawdzenia potrzebne są oba pliki: stempel dowodzi, że w tamtej chwili istniał dokładnie jeden ciąg bajtów, a tym ciągiem jest wyłącznie źródło poniżej. Każda późniejsza zmiana przesuwa skrót i zrywa zgodność — i o to właśnie chodzi.

· @529.58 · 2026-W40

SHA-256 ostemplowanego tekstu: 90ee5eb66f12eaaa998a1eca1e9f5688ce04a7e322e5398c397ca7ac4882adc2

Sprawdzenie: ots verify <dowód> --file <źródło>