Koch Laboratory

Czas jako dowód, po raz trzeci: strażnicy z własnym zegarem i granice reguły „2 z 3”

Kontynuuje i koryguje wpis z 2026-10-01. Od 6 października stan dziennika potwierdzają dwaj strażnicy, którzy sami sprawdzają łańcuch, drzewo i czas wpisów, a od 19 października strona weryfikacji i biblioteka PHP same liczą regułę „2 z 3”. Granica jest podana wprost: dwa z trzech kluczy ma operator, więc reguła chroni przed włamaniem i błędem konfiguracji. Do tego blokada stempli przy nieznanym błędzie zegara, dwa wyniki negatywne i dowód minimalnego upływu czasu w fazie pomiarów.

Koch Laboratory - czas jako dowód, po raz trzeci: strażnicy z własnym zegarem i granice reguły „2 z 3”

Wpis z 2026-10-01 („Czas jako dowód, raz jeszcze”) zamykał kierunek 1 otwartym pytaniem: czy stan dziennika powinny podpisywać niezależne strony, tak aby sam klucz operatora - skompromitowany albo źle skonfigurowany - nie wystarczał do przedstawienia przekonującej alternatywnej historii. Pięć dni później działali dwaj strażnicy. Ten wpis opisuje, co sprawdzają i gdzie leżą granice reguły „2 z 3”, jak usługa przestała stemplować przy nieznanym błędzie zegara, co od tamtej pory okazało się błędem i które stwierdzenia wpisu z 2026-10-01 są już nieaktualne. Pełny opis budowy i procedurę, którą biegły przeprowadza sam, zawiera raport techniczny z 9 października 2026 (doi.org/10.5281/zenodo.23265547).

Co tu jest badaniem, a co nie. Podpisy świadków nad stanem dziennika to dojrzały wzorzec logów przejrzystości; uwierzytelniona synchronizacja czasu (NTS, RFC 8915), zasada wstrzymania znaczników po utracie synchronizacji i dowód pracy sekwencyjnej z kierunku 4 też nie są nasze. Treścią badawczą są granice - co dokładnie poświadcza podpis strażnika, ile ochrony daje reguła „2 z 3”, gdy dwa z trzech kluczy ma operator, i co z tego widzi osoba sprawdzająca stempel - oraz to, co zawiodło. Teza dowodowa pozostaje bez zmian: stempel wykazuje, że plik o danym odcisku istniał już w chwili stempla - nie to, że wcześniej nie istniał, ani kto jest jego autorem.

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 z testów są oznaczone jako takie.

1. Kierunek 1 - strażnicy, którzy sprawdzają czas wpisów, a nie tylko spójność dziennika

Problem. Po incydencie z kluczem (wpis z 2026-10-01, kierunek 1) zaufanie przeszło z podpisu na kopie i kotwice. Kopie są jednak bierne - przechowują, ale niczego nie sprawdzają przed przyjęciem - a między stemplem a najbliższą kotwicą w Bitcoinie mija do około doby. W tym oknie czas wpisu był wyłącznie słowem operatora: nikt poza nim nie obserwował dziennika na bieżąco. Stan techniki (publikowany). Świadkowie kontrasygnujący stan drzewa w logach przejrzystości (specyfikacje C2SP tlog-cosignature i tlog-witness, baza sum kontrolnych modułów Go, Sigstore) i kolektywne podpisy świadków (CoSi; Syta i in., IEEE S&P 2016). Analiza progów dla świadków (N. Möller, projekt Sigsum, 2023): reguła k z n chroni przed rozbieżnymi wersjami historii przy f nieuczciwych podpisujących tylko wtedy, gdy 2k > n + f. Świadek w tym wzorcu poświadcza przede wszystkim spójność kolejnych stanów drzewa i chwilę, w której je zobaczył; czasu zapisanego w poszczególnych wpisach zwykle nie sprawdza. Kryterium (falsyfikowalne). (1) Strażnik podpisuje tylko to, co sam sprawdził: łańcuch skrótów, drzewo globalne przeliczone od zera i czas każdego nowego wpisu względem własnego zegara - z tolerancją ±30 s, przy czym wpis nie może być starszy niż poprzednia obserwacja strażnika; (2) serwer usługi nie może sam wytworzyć podpisu strażnika ani podsunąć mu niczego do podpisania; (3) program sprawdzający pokazuje stempel jako potwierdzony tylko wtedy, gdy sam sprawdził co najmniej dwa z trzech podpisów. Kryterium obala podpis strażnika nad stanem, którego strażnik nie sprawdził, podpisany wpis z czasem wstecznym ponad tolerancję albo potwierdzenie pokazane bez dwóch sprawdzonych podpisów. Metoda. Od 6 października 2026 dwa programy-strażnicy działają na osobnych maszynach i kontach: jeden w AWS (funkcja Lambda we Frankfurcie, klucz w module sprzętowym AWS KMS), prowadzony przez operatora Sigelith, drugi u Konverii - niezależnej firmy z Krakowa, bez powiązań osobowych i kapitałowych z operatorem, która publikuje też aplikacje Sigelith na Androida. Co minutę każdy strażnik sam pobiera publiczny dziennik, sprawdza łańcuch i czas nowych wpisów, przelicza drzewo RFC 9162 i podpisuje to, co zobaczył (sigelith-cosign-v1: rozmiar i korzeń drzewa, ostatni wpis, własny czas i czas poprzedniej obserwacji). Strażnik nie ma żadnego wejścia z zewnątrz. Serwer nie ma kluczy strażników - przechowuje i udostępnia ich podpisy, a podpis niezgodny z własnym drzewem zapisuje jako niezgodny. Każda nieprawidłowość - przerwany łańcuch, czas cofający się, wpis datowany wstecz albo z przyszłości - zatrzymuje strażnika do ręcznej decyzji jego operatora; strażnik nigdy nie podpisuje „mimo wszystko”, a ostatni podpis każdego strażnika jest publiczny, więc przerwę widać. Stempel uznaje się za potwierdzony, gdy popierają go dowolne dwa z trzech podpisów: klucza dziennika (kwit) i dwóch strażników. Program strażnika jest publiczny, z powtarzalną kompilacją, opisem protokołu, wektorem testowym i testami tych zatrzymań (github.com/DeiFlagellum/sigelith-cosigner, Apache-2.0). Od 19 października strona weryfikacji (/proof/) i biblioteka PHP dla wtyczek same liczą regułę „2 z 3”: kwit, ścieżkę RFC 9162 do podpisanego korzenia i podpisy strażników, kluczami wpisanymi w kod; strona pokazuje „N z 3 podpisów sprawdzonych w tej przeglądarce” wyłącznie z własnych obliczeń, a niezgodny podpis zawsze na czerwono. Od 26 października Sigelith Backup zapisuje podpisy strażników na płycie archiwalnej i sprawdza je bez sieci; jego weryfikator jest przeniesieniem modułu strony i używa tych samych wektorów testowych. Wynik. Potwierdzony w zakresie kryterium. 6 października o 20:13 UTC wpis nr 300 miał trzy z trzech podpisów, każdy sprawdzony osobno; 19 października strona w przeglądarce oraz biblioteka PHP na żywym API pokazały trzy z trzech (testy na wspólnych wektorach: 14 przypadków w JavaScripcie, 1724 sprawdzenia w PHP 7.4 i 8.3). Okno czasu wpisu skurczyło się z około doby (kotwice) do około minuty (obserwacje strażników) - np. wpis nr 320, zapisany o 18:48:03,213 UTC, strażnik w AWS zobaczył między 18:47:05 a 18:48:05, a strażnik Konverii między 18:47:31 a 18:48:31. Warunki brzegowe: (a) dwa z trzech podpisujących systemów prowadzi operator - klucz dziennika i strażnika w AWS; serwer usługi nie ma dostępu do konta AWS, ale operator jako jego właściciel - tak. Z warunku 2k > n + f dla układu 2 z 3 wynika f = 0: reguła nie toleruje żadnego zmawiającego się podpisującego, a operator sam ją spełnia. „2 z 3” chroni więc przed włamaniem do jednego systemu i przed błędem konfiguracji takim jak wrześniowy; wobec operatora niezależni są strażnik Konverii, Bitcoin, bank i archiwa; (b) niezależność Konverii i to, że klucza z AWS KMS nie da się skopiować, są oświadczeniami, których nie da się sprawdzić kryptograficznie; (c) okno strażnika pochodzi z jego własnego zegara - jest tak dobre jak ten zegar i nie jest niezależnym źródłem czasu; (d) strona /proof/ liczy w przeglądarce, ale jej kod dostarcza serwer operatora - niezależnym sprawdzeniem pozostaje procedura z raportu, a klient desktopowy, który sprawdza dowody bez serwera, podpisów strażników jeszcze nie sprawdza; (e) wpisy sprzed 6 października nie mają okna strażników; (f) strażnik zatrzymuje się po każdej nieprawidłowości, a dostępności strażników dotąd nie mierzyliśmy. Następny krok. Zmierzyć dostępność strażników z ich publicznych podpisów; sprawdzanie podpisów strażników w kliencie desktopowym. Otwarte pozostaje, czy i kiedy dołączą kolejni niezależni strażnicy: z tego samego warunku wynika (obliczenie własne), że operator z dwoma kluczami przestaje sam spełniać regułę, gdy niezależnych strażników jest co najmniej trzech, a próg wynosi 4 z 5. Status: wdrożone od 6 października 2026; sprawdzanie „2 z 3” w przeglądarce i w PHP od 19 października, w Sigelith Backup od 26 października; granice (a)-(f) obowiązują.

2. Kierunek 2 - usługa przestaje stemplować, gdy nie zna błędu swojego zegara

Problem. Zapisany czas wpisu to wskazanie zegara serwera. Wpis z 2026-10-01 prostował, że dotychczasowy pomiar odchyłki był jednym nieuwierzytelnionym zapytaniem SNTP do jednego serwera - sygnałem stanu, nie dowodem. Do 6 października nic też nie wstrzymywało stemplowania, gdy zegar odbiegał: wpis z błędnym czasem wykryłyby najwyżej kotwice, z dokładnością do godzin. Stan techniki (publikowany). Uwierzytelniona synchronizacja czasu NTS (RFC 8915); norma ETSI EN 319 421 przewiduje wstrzymanie wydawania znaczników czasu po utracie synchronizacji z UTC (Sigelith tej normie nie podlega i nie deklaruje z nią zgodności); RFC 3161 - czas znacznika jest wart tyle, ile zegar urzędu. Kryterium (falsyfikowalne). Nowy wpis i nowy checkpoint powstają wyłącznie wtedy, gdy ostatni udany pomiar zegara ma najwyżej 15 minut, a odchyłka nie przekracza 0,25 s; w przeciwnym razie usługa odmawia (kod 503, clock_untrusted) i nie zapisuje niczego. Obala je jeden wpis zapisany poza tymi warunkami. Metoda. Od 6 października 2026 usługa co 5 minut sama mierzy odchyłkę swojego zegara przez NTS względem serwerów PTB (Physikalisch-Technische Bundesanstalt, niemiecki krajowy instytut metrologii), a gdy oba są nieosiągalne - względem Netnodu. Każda próba jest zapisywana; ostatni pomiar jest publiczny (/api/health/, strona /evidence/), a certyfikat PDF wpisu podaje ostatni pomiar sprzed wpisu („Server clock”). Wpisów zapisanych wcześniej blokada nie zmienia. Wynik. Wdrożone; pomiary punktowe: 6 października odchyłka poniżej 0,1 ms przy opóźnieniu 9 ms, 9 października 0,2 ms. Warunki brzegowe: (a) pomiar jest oświadczeniem operatora o jego własnym pomiarze, nie potwierdzeniem PTB - sama PTB zastrzega, że NTS nie daje prawnie wiążącej informacji o czasie; (b) historia pomiarów nie jest publiczna, a to, że blokada działa, jest słowem operatora - nie ma publicznego wskaźnika jej stanu; (c) atakujący na łączu może przesunąć pomiar najwyżej o połowę czasu przejścia w obie strony, w praktyce o milisekundy; (d) niezależnie od tego pomiaru czas wpisu sprawdzają strażnicy (kierunek 1, z tolerancją ±30 s) i kotwice. Następny krok. Ustalić, czy i jak publikować historię pomiarów i stan blokady, tak by dało się je sprawdzić bez pytania operatora. Status: wdrożone od 6 października 2026.

3. Kierunek 3 - wyniki negatywne i poprawki od 1 października

(a) Dziennik dostępu pozwalał powiązać stempel z siecią i przeglądarką. Czas wpisu jest publiczny z dokładnością do mikrosekundy, a dziennik dostępu serwera WWW zapisywał czas zapytania, sieć /24 i nagłówek User-Agent; serwer aplikacji zapisywał do tego pełne adresy zapytań razem z odciskami. Po czasie dało się więc dopasować stempel do sieci i przeglądarki osoby, która go wykonała. Wynik negatywny: brak konta i adresu e-mail nie wystarczał, żeby stempla nie dało się z kimś powiązać. Poprawka z 9 października 2026: dziennik dostępu bez adresu IP, portu i nagłówków zapytania (ze strony odsyłającej zostaje tylko domena), serwer aplikacji bez dziennika dostępu, filtr wycinający z komunikatów każdy 64-znakowy odcisk, liczniki limitów zapytań wyłącznie w pamięci procesu; po wdrożeniu sprawdzone. Warunek brzegowy: operator, który kontroluje serwer, może te ustawienia w każdej chwili zmienić - kto potrzebuje anonimowości także wobec niego, powinien stemplować przez Tor (połączenia przez Tor nie trafiają do żadnego dziennika dostępu). (b) Biblioteka PHP brała odmowę za stempel. Biblioteka PHP dla wtyczek nie sprawdzała kodu odpowiedzi HTTP: odpowiedzi 400, 429 i 503 dawały wynik wyglądający na udany stempel. Błąd ważył tym więcej, że od 6 października usługa celowo odpowiada kodem 503, gdy nie ufa swojemu zegarowi (kierunek 2). Znaleziony w przeglądzie wewnętrznym 6 października, poprawiony 19 października: każda odpowiedź 4xx i 5xx jest zgłaszana jako błąd z kodem HTTP. To ta sama klasa błędu co w przeglądzie klienta desktopowego (wpis z 2026-10-01, kierunek 5) - pokazanie jako wykonanego czegoś, czego nie wykonano. (c) Zdania mocniejsze niż system - poprawione po recenzji zewnętrznej z 7 października. Recenzent zewnętrzny odtworzył rdzeń kryptograficzny z samej publicznej specyfikacji, a zarazem wskazał zdania, które obiecywały więcej, niż system zapewnia. Poprawione tego samego dnia: (1) zamiast „sprawdzisz, nie ufając nikomu - także nam” strona mówi „sprawdzisz, nie wierząc nam na słowo”: weryfikator w przeglądarce pochodzi z naszego serwera, a niezależnie sprawdza się programem Sigelith Desktop o otwartym kodzie albo procedurą dla biegłego; (2) Bitcoin i archiwa każdy sprawdzi bez nas, ale potwierdzenie przelewu z korzeniem wydajemy na prośbę, a bank potwierdza je na wniosek sądu; (3) GitHub zniknął z listy „stron, których nie kontrolujemy” - wydania leżą na naszym koncie; (4) przy Konverii dopisano, że to niezależna firma bez powiązań osobowych i kapitałowych z operatorem; (5) specyfikacja mówi wprost, że zapis wpisu może się opóźnić tylko w stronę późniejszą, nigdy wcześniejszą, i że serwer nie ma kluczy strażników. Status: poprawki wdrożone.

4. Kierunek 4 - Klepsydra: dowód minimalnego upływu czasu (w toku)

Problem. Kotwice dają górną granicę czasu, a blok Bitcoina nazwany w checkpoincie - dolną. Nic nie dowodzi natomiast, ile czasu upłynęło między dwoma zdarzeniami w dzienniku, niezależnie od zegarów - ani naszego, ani strażników. Stan techniki (publikowany). Dowody pracy sekwencyjnej (B. Cohen, K. Pietrzak, Simple Proofs of Sequential Work, EUROCRYPT 2018). Funkcje opóźniające z weryfikacją (VDF) nie istnieją z samych funkcji skrótu w modelu wyroczni losowej; ceną konstrukcji opartej wyłącznie na skrótach jest to, że sprawdzenie gwarantuje wykonanie tylko części pracy. Kryterium (falsyfikowalne). Między dwoma zdarzeniami upłynął co najmniej czas wynikający z liczby wykonanych kroków - przy jawnym założeniu k, że nikt nie liczy tej pracy więcej niż k razy szybciej niż zmierzony prover. Obala je sprzęt liczący szybciej niż założone k. Metoda. Od 19 października 2026 serwer usługi liczy Klepsydrę (Sigelith Hourglass) - dowód pracy sekwencyjnej Cohena i Pietrzaka na SHA-256, w odcinkach, na jednym rdzeniu procesora. Ziarno każdego odcinka wchłania świeży blok Bitcoina i ostatni checkpoint Sigelith, a odcinek łączy się z korzeniem poprzedniego; rekord odcinka jest stemplowany w dzienniku i potwierdzany przez strażników. Konstrukcję Cohena i Pietrzaka implementujemy wiernie; nowe są system i pomiary. Specyfikacja, implementacja referencyjna i kod są publiczne (github.com/DeiFlagellum/sigelith-hourglass, Apache-2.0). Wynik. Jeszcze brak - faza 0 to 30-dniowy pomiar na serwerze produkcyjnym (genesis ostemplowany jako wpis nr 453, koniec 18 listopada 2026). Do jego końca k = 20 jest założeniem, a nic z fazy 0 nie trafia na certyfikaty. Warunki brzegowe podane z góry: (a) wyłącznie dolne granice, i to skromne - przy k = 20 tydzień odcinków dowodziłby około 6 godzin; (b) Klepsydrę liczy jeden operator - zegar można zatrzymać; podrobienie go po cichu wykluczają dopiero publicznie dostępne odcinki, bo wtedy dwa różne korzenie jednego odcinka zobaczy każdy; (c) pliki odcinków nie są jeszcze publikowane, więc dziś osoba trzecia sprawdzi tylko, że w dzienniku zapisano odciski rekordów odcinków, a nie sam dowód pracy. Następny krok. Po 18 listopada: analiza pomiaru, publiczna notatka, parametry i genesis wersji 1 - w osobnym wpisie. Status: w toku (faza 0).

Stan kroków zapowiedzianych 1 października

Korekty wpisu z 2026-10-01

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

Kierunek 1, „Następny krok”: podpisy niezależnych świadków jako otwarte pytanie. Nieaktualne od 6 października 2026 (kierunek 1 tego wpisu).

Kierunek 1, warunki brzegowe: „rotacja wymaga dziś zmiany listy kluczy w trzech miejscach”. Nieaktualne: klucze publiczne są dziś wpisane także w moduł strony /proof/, w bibliotekę PHP i w Sigelith Backup, więc rotacja wymaga zmian w większej liczbie miejsc i nowych wydań.

Kierunek 2, Metoda i „Status kierunku”: GitHub wśród kopii u stron trzecich. Niedokładne: wydania w GitHubie są niezmienne, ale leżą na koncie operatora, a całe repozytorium można usunąć. GitHub przechowuje kopię poza naszą infrastrukturą, nie poza naszą kontrolą.

Kierunek 2, warunek brzegowy (c): „świadków kontrasygnujących nie ma”. Nieaktualne od 6 października 2026.

Kierunek 2, warunek brzegowy (f): strony w przeglądarce biorą część dotyczącą logu z odpowiedzi serwera. Nieaktualne dla strony /proof/: od 19 października sama liczy kwit, ścieżkę do podpisanego korzenia i podpisy strażników.

Kierunek 3, Metoda: „usługa co pięć minut mierzy też swój offset względem zewnętrznego serwera i publikuje wynik”. Niedokładne od 6 października: publikowany wynik to dziś ostatni uwierzytelniony pomiar względem PTB, który blokuje nowe wpisy (kierunek 2 tego wpisu); historia pomiarów nie jest publiczna.

„Status kierunku”: „Najbliższe kroki: samodzielny skrypt weryfikacyjny dla osób trzecich i rozstrzygnięcia z kierunku 4”. Skrypt zastąpiła procedura dla biegłego (patrz „Stan kroków”); rozstrzygnięcia z kierunku 4 pozostają otwarte. Kapsuły czasowe i protokół dowodu doręczenia nadal czekają na osobny wpis.

Status kierunku. Stan dziennika potwierdzają od 6 października dwaj strażnicy z własnymi zegarami, a od 19 października strona weryfikacji i biblioteka PHP liczą regułę „2 z 3” same. Usługa przestaje stemplować, gdy nie zna błędu swojego zegara. Najbliższe kroki: pomiar dostępności strażników, sprawdzanie ich podpisów w kliencie desktopowym, wyniki fazy 0 Klepsydry (po 18 listopada 2026) i decyzja o publikacji historii pomiarów zegara.


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.

· @390.24 · 2026-W46

SHA-256 ostemplowanego tekstu: 98f9b984c9299515d216ba8ace32d5d2460e38f30d498c60672fef9a51070fa4

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