# Koch Laboratory — Czas jako dowód, raz jeszcze: incydent z kluczem i log, który można skontrolować z zewnątrz (Sigelith) · Forschungsportfolio / Portfolio badawcze / Research Portfolio

> **Zasada publikacji.** Formaty, klucze publiczne wraz z historią, odrzucone korzenie i cały log są jawne — dowód, którego nie da się sprawdzić bez pytania operatora, nie jest dowodem. Wstrzymane pozostają wyłącznie klucze prywatne i szczegóły operacyjne infrastruktury.
> **Zasada uczciwości.** Ten wpis kontynuuje i koryguje wpis z 2026-08-20, który pozostaje niezmieniony. Większość opisanych tu elementów to integracja opublikowanych standardów; treścią badawczą są granice i to, co zawiodło — łącznie z incydentem, który osłabił część wcześniejszych twierdzeń.

---
---

# 🇵🇱 WERSJA POLSKA

## 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](https://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/](https://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](https://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](https://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](https://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.

---
---

# 🇩🇪 DEUTSCHE FASSUNG

## Koch Laboratory — Zeit als Beweis, neu betrachtet: ein Schlüsselvorfall und ein Log, das sich von außen prüfen lässt

Der Eintrag vom 2026-08-20 („Zeit als vereinbarte Einheit und als Beweis") beschrieb einen Zeitdienst, dessen Angabe für jemanden tragen soll, der weder uns noch unserem Server traut. Sechs Wochen später steht fest, dass eine seiner Aussagen schwächer war, als sie aussah: Mehr als drei Monate lang war derselbe Signaturschlüssel auf zwei Maschinen konfiguriert. Dieser Eintrag beschreibt, was daraus folgte, was als Antwort gebaut wurde und welche Aussagen des vorigen Eintrags einer Korrektur bedürfen. Der vorige Eintrag bleibt unverändert; die Korrekturen stehen hier, mit Datum.

**Name.** Seit dem 27. September 2026 heißt die gesamte Beweisinfrastruktur — Log, Checkpoints, PDF-Nachweise und Prüf-API — Sigelith und ist unter sigelith.org erreichbar. Seiten unter beattime.live leiten (301) auf dieselbe Adresse unter sigelith.org weiter; die API, die Beweisdateien und alles, was ein Programm liest, antworten unter beiden Adressen ohne Weiterleitung. Die Formatkennungen innerhalb der signierten Bytes bleiben unverändert (`beattime-proof-v1`, `beattime-entry-v1`, `beattime-checkpoint-v1`) — eine Umbenennung in signierten Daten würde jeden bereits ausgestellten Beweis ungültig machen. Der Name BeatTime bezeichnet heute nur noch die beiden Android-Apps: die Uhr und das Zifferblatt für die Smartwatch. Die Uhr bleibt eine Uhr der Internet Time — der Tag in 1000 Teile geteilt, in UTC verankert —, und eine Angabe schreibt man als @beat, etwa @523.

**Was hier Forschung ist und was nicht.** Die meisten beschriebenen Elemente sind Integration veröffentlichter Standards: Merkle-Bäume mit Inklusions- und Konsistenzbeweisen (RFC 9162), kanonisches JSON (RFC 8785), Ed25519-Signaturen (RFC 8032), OpenTimestamps, authentifizierte Zeitsynchronisation mit NTS (RFC 8915). Keiner dieser Mechanismen stammt von uns. Forschungsgegenstand sind die Grenzen — was genau eine Signatur abdeckt, was ein Anker bezeugt, was eine Kopie nicht bezeugt — und das, was versagt hat.

**Methodik.** Wie im übrigen Labor: Problem → Stand der Technik → falsifizierbares Kriterium → Methode → Ergebnis (bestätigt, widerlegt oder teilweise, mit Randbedingungen) → nächster Schritt. Ein negatives Ergebnis ist ein Ergebnis. Zahlen zum Log stammen aus dessen öffentlichen Daten und sind ohne Rückfrage bei uns nachprüfbar; Zahlen aus Tests sind als solche gekennzeichnet.

### 1. Richtung 1 — negatives Ergebnis: Eine gültige Signatur zeigte nicht, wem eine Wurzel gehört
**Problem.** Der Eintrag vom 2026-08-20 behandelte die Ed25519-Signatur über der wöchentlichen Merkle-Wurzel als Bestätigung, dass die Wurzel von uns stammt. Vom 15. Juni bis zum 21. September 2026 war derselbe private Schlüssel jedoch auf zwei Maschinen konfiguriert: im Produktivdienst und auf einem Entwicklungsspiegel. Der Spiegel führt dieselben periodischen Aufgaben aus; er schloss daher eigene Wochen ab, signierte deren Wurzeln mit dem gemeinsamen Schlüssel und verankerte sie über OpenTimestamps in Bitcoin. So entstanden zwei solche Wurzeln, für die Wochen 2026-W25 und 2026-W30. Aufgedeckt wurde der Fehler durch eine eigene Sicherheitsüberprüfung im September 2026.
**Stand der Technik (veröffentlicht).** Bei Zeitstempeln nach RFC 3161 und ETSI EN 319 421 wird die Kompromittierung des Schlüssels einer Zeitstempeleinheit durch Widerruf und Benachrichtigung behandelt — das Vertrauen bleibt beim Anbieter. In Certificate Transparency (RFC 6962, RFC 9162) verliert ein Log, das zwei unvereinbare Zustände signiert, das Vertrauen insgesamt. Beide Antworten setzen voraus, dass die Signatur den Aussteller ausweist.
**Kriterium (falsifizierbar).** Hypothese des Eintrags vom 2026-08-20: Eine gültige Signatur mit unserem Schlüssel weist eine Wurzel als unsere aus. Widerlegt wird sie durch eine einzige gültig signierte Wurzel, die nicht unsere ist. Ersatzkriterium: Die maßgebliche Wurzel muss sich ohne Vertrauen in die Signatur bestimmen lassen, aus Daten, die außerhalb unserer Infrastruktur liegen.
**Methode.** Schlüsselrotation am 21. September 2026 und Neusignierung jeder veröffentlichten Wurzel mit dem neuen Schlüssel — die Wurzeln ändern sich nicht, und ihr Bestehen zu einem Zeitpunkt bezeugen Bitcoin und die Bank; die Neusignierung verschiebt also nichts in der Zeit. Den zurückgezogenen Schlüssel lehnt bereits der Signaturcode ab; jede Maschine pinnt den öffentlichen Schlüssel, mit dem sie signieren darf, sodass eine falsch konfigurierte Maschine ohne Signatur endet statt mit einer fremden; der Spiegel verankert nichts mehr. Die Schlüsselhistorie ist öffentlich, und nichts wird aus ihr entfernt. Die erste öffentliche Notiz sprach nur von einer Rotation „nach einer Sicherheitsüberprüfung"; einige Tage später veröffentlichten wir die vollständige Darstellung mit der Liste der verworfenen Wurzeln ([sigelith.org/spec/#incident-2026-09](https://sigelith.org/spec/#incident-2026-09)), denn eine verworfene Wurzel, die wir nicht selbst benennen, wirkt glaubwürdig auf jeden, dem man sie mit gültiger Signatur vorlegt. Die Seite nennt drei Prüfungen, die ohne Vertrauen in uns durchführbar sind — darunter die für W25 entscheidende: Die Wurzel dieser Woche wurde auf dem Spiegel am Montag derselben Woche eingefroren, und eine Wochenwurzel kann vor dem Ende ihrer Woche nicht endgültig sein.
**Ergebnis.** Hypothese widerlegt: Zwei gültig signierte Wurzeln (2026-W25, 2026-W30) sind nicht unsere; wir veröffentlichen sie selbst, namentlich, als verworfen. Kein Hash im Log hat sich geändert, kein Stempel ging verloren oder wurde rückdatiert — geschwächt ist die Aussage, die allein auf der Signatur beruht. Ersatzkriterium erfüllt: Maßgeblich ist für jede Woche die Wurzel, die sich aus den veröffentlichten Einträgen dieser Woche nachrechnen lässt (Kopien bei Dritten, Richtung 2), und für Wochen mit Bankanker zusätzlich die Wurzel im Verwendungszweck `MROOT` der Überweisung. Keine der beiden verworfenen Wurzeln besteht diese Prüfung. **Das Vertrauen hat sich von der Signatur auf Kopien in fremder Hand und auf die Anker verlagert:** Die Signatur ist heute einer der Zeugen, nicht die Identität des Logs. Randbedingungen: Ein OpenTimestamps-Anker bezeugt die Zeit, nicht die Urheberschaft — der Spiegel nutzte dieselben öffentlichen Kalender wie der Produktivdienst; eine Rotation verlangt heute die Änderung der Schlüsselliste an drei Stellen (Dienst, Desktop-Client, öffentliches Log-Repository) und eine neue Client-Version, und ein Client ohne diese Änderung zeigt jeden neuen Beweis als mit fremdem Schlüssel signiert an.
**Nächster Schritt.** Ein einziger Schlüssel signiert heute Wochenwurzeln, Checkpoints und Stempelquittungen. Offene Frage: Sollten Checkpoints Signaturen unabhängiger Zeugen tragen, wie bei einem Teil der Transparenz-Logs, damit der Schlüssel des Betreibers allein — kompromittiert oder falsch konfiguriert — nicht genügt, um eine überzeugende alternative Geschichte vorzulegen?
**Status:** negatives Ergebnis (Hypothese widerlegt); Korrektur umgesetzt und öffentlich beschrieben.

### 2. Richtung 2 — ein Log, das sich von außen prüfen lässt
**Problem.** Bis zum 25. September 2026 konnte jeder *seinen* Eintrag prüfen — den Inklusionspfad zur Wochenwurzel —, aber niemand konnte *uns* prüfen: das ganze Log herunterladen, von Grund auf nachrechnen und zeigen, dass nichts herausgeschnitten oder umgeschrieben wurde. Nach Richtung 1 ist das keine kosmetische Lücke: Wenn die Signatur nicht genügt, braucht es etwas, das andere aufbewahren.
**Stand der Technik (veröffentlicht).** Certificate Transparency (RFC 6962, RFC 9162): ein Merkle-Baum über das ganze Log, Inklusions- und Konsistenzbeweise, signierte Baumzustände; nach diesem Muster gebaute Transparenz-Logs (u. a. die Prüfsummendatenbank der Go-Module, Sigstore Rekor) sowie Zeugen, die Checkpoints gegenzeichnen. Das Muster ist ausgereift; wir bauen kein neues.
**Kriterium (falsifizierbar).** Eine Person ohne Zugang zu unserer Infrastruktur lädt das ganze Log herunter, rechnet die Hash-Kette und jede Wurzel nach, prüft, dass jeder spätere Checkpoint den früheren erweitert (Konsistenzbeweis nach RFC 9162), und vergleicht die Checkpoints mit Kopien, die andere aufbewahren. Widerlegt wird das Kriterium durch jede Änderung der veröffentlichten Geschichte — ein entfernter, umgeschriebener oder umgestellter Eintrag, zwei verschiedene Checkpoints mit derselben Nummer —, die dieses Verfahren nicht erkennt.
**Methode.** Ein globaler Baum über alle Einträge seit dem ersten, in der Form des Merkle Tree Hash aus RFC 9162. Das Blatt bindet Nummer, Hash und Zeit des Eintrags (`beattime-entry-v1|Nummer|Hash|Zeit`), sodass ein einziger Pfad belegt: „Dieser Hash war Eintrag Nr. N zum Zeitpunkt T" — und nicht nur: „Dieser Hash steht irgendwo im Baum". Wochenbäume, ihre Signaturen und die Verwendungszwecke der Überweisungen bleiben unverändert; der globale Baum ergänzt sie, er ersetzt sie nicht. Ein Checkpoint ist ein signierter Baumzustand in kanonischem JSON: täglich und unmittelbar nach Wochenabschluss ausgestellt, über den Hash der vorigen Checkpoint-Datei verkettet, mit einem benannten Bitcoin-Block (Tiefe 3; zwei unabhängige Block-Explorer müssen übereinstimmen) und selbst über OpenTimestamps in Bitcoin verankert. Checkpoint Nr. 1 (25. September) umfasst das ganze Log seit dem ersten Eintrag — 171 Einträge. Das ganze Log lässt sich herunterladen (Eintragsseiten und wöchentliche Exportdateien), Konsistenzbeweise zwischen Checkpoints sind öffentlich abrufbar ([sigelith.org/checkpoints/](https://sigelith.org/checkpoints/)). Kopien bei Dritten entstehen automatisch: OpenTimestamps/Bitcoin — jeder Checkpoint, täglich; Verwendungszweck `MROOT` einer Banküberweisung — jede Wochenwurzel, wöchentlich; GitHub (unveränderliche Releases, [github.com/DeiFlagellum/sigelith-log](https://github.com/DeiFlagellum/sigelith-log)) und Internet Archive — wöchentlich; Zenodo — vierteljährlich, ein vollständiger Schnappschuss unter CC0. Seit dem 28. September trägt jede Antwort auf eine Stempelung eine signierte Quittung (Nummer, Hash, Zeit, Kettenglied): Ein Log, dem ein solcher Eintrag später fehlt, wird durch die eigene Signatur überführt — dieselbe Rolle spielen SCTs in Certificate Transparency. Der Desktop-Client (heute Sigelith Desktop, vor Version 3.0 BeatStamp) prüft seit Version 2.2 im Hintergrund jeden Checkpoint — Dateibytes, Signatur, Kette, Konsistenz —, vergleicht ihn Byte für Byte mit den Kopien bei GitHub, Internet Archive und Zenodo und prüft den Block bei einem unabhängigen Explorer; einen Checkpoint mit bekannter Nummer und anderem Inhalt bewahrt er als Beweismaterial auf. Im Standardmodus hält er eine Kopie des ganzen Logs und berechnet die Pfade selbst; der Server erfährt höchstens, nach welcher Woche gefragt wurde.
**Ergebnis.** Im Rahmen des Kriteriums bestätigt. Inklusions- und Konsistenzbeweise wurden vor der Inbetriebnahme für jede Baumgröße von 1 bis 64 erschöpfend geprüft (Test): 2080 von 2080 echten Beweisen jeder Art angenommen, 8190 von 8190 Fälschungen verworfen (u. a. falscher Pfad, falscher Index, umgeschriebener Eintrag in der Geschichte); die Erzeugung folgt der rekursiven Definition, die Prüfung dem iterativen Algorithmus — beide Formen aus RFC 9162 müssen dasselbe ergeben. Eine zweite Implementierung, allein aus dem Text der Spezifikation geschrieben und bewusst ohne Import von Produktivcode, reproduzierte den Produktivdienst beim ersten Lauf am 25. September: 171 Einträge, 13 wöchentliche Exportdateien, globale Wurzel und Wochenwurzeln übereinstimmend, Wochenwurzeln gleich den Verwendungszwecken `MROOT`. Zum Zeitpunkt des Schreibens wurde dies mit einer weiteren, separat geschriebenen Implementierung wiederholt: Die Wurzeln bei 171 und 211 Einträgen entsprechen den Wurzeln der Checkpoints Nr. 1 und Nr. 8, der Konsistenzbeweis zwischen ihnen ist gültig, ebenso die Signatur von Checkpoint Nr. 1. Randbedingungen: (a) Ein erschöpfender Test an kleinen Bäumen spricht für die Korrektheit der Implementierung, beweist sie aber nicht; (b) die zweite Implementierung ist im Code unabhängig, nicht in der Person — sie stammt vom selben Autor; ein Audit durch Dritte gab es bisher nicht; (c) die Kopien bei GitHub, Internet Archive und Zenodo sind passiv — sie bewahren auf, prüfen aber vor der Annahme nichts; geprüft wird von Clients und von jedem, der sie herunterlädt, und gegenzeichnende Zeugen gibt es nicht; (d) die Geschichte vor dem 25. September wird als Ganzes erst durch Checkpoint Nr. 1 festgehalten, davor nur durch die wöchentlichen Anker; (e) der Servercode ist nicht öffentlich und muss es nicht sein, weil die Prüfung ihn nicht nutzt: Die Formate beschreiben die Spezifikation und das öffentliche Log-Repository; (f) lokal prüft der Desktop-Client; Browserseiten und die Android-App berechnen den Hash einer Datei lokal, übernehmen den Log-Teil aber aus der Serverantwort und verweisen auf die unabhängigen Kopien zum eigenen Vergleich.
**Nächster Schritt.** Ein eigenständiges Prüfskript für Dritte, das den Checkpoint aus einer unabhängigen Kopie bezieht und nicht von uns — der einzige noch offene Punkt des Plans dieser Richtung.
**Status:** umgesetzt seit dem 25. September 2026 (erstes Wochen-Release: 2026-W39, erste Quartalsversion: 2026-Q3).

### 3. Richtung 3 — ein Zeitintervall für jeden Eintrag aus externen Ankern statt aus unserer Uhr
**Problem.** Die Zeit eines Eintrags ist die Angabe unserer Serveruhr. Der Eintrag vom 2026-08-20 stützte sich auf die Wochengranularität („nicht später als") und auf die Veröffentlichung des eigenen Uhrenfehlers, doch beides bleibt unser Wort. Der schwerste Vorwurf gegen jeden Zeitstempeldienst lautet: Der Betreiber hat einen Eintrag auf Wunsch rückdatiert. Die Antwort darauf darf nicht von der Uhr des Betreibers abhängen.
**Stand der Technik (veröffentlicht).** RFC 3161: Die Zeit stammt von der Uhr der Stelle und ist so viel wert wie das Vertrauen in sie; verkettete Zeitstempel (Haber und Stornetta, 1991) — Reihenfolge ohne Vertrauen, aber ohne absolute Zeit; OpenTimestamps — eine Obergrenze („existierte nicht später als") aus Bitcoin; Roughtime — authentifizierte Grobzeit mit Beweis für Fehlverhalten des Servers; NTS (RFC 8915) — authentifizierte Uhrensynchronisation. Die Untergrenze liefert eine bekannte Technik: Ein Wert, der vor einem bestimmten Zeitpunkt nicht bekannt sein konnte — hier der Hash eines Bitcoin-Blocks —, belegt, dass alles, was ihn enthält, später entstanden ist.
**Kriterium (falsifizierbar).** Für jeden Eintrag lassen sich beide Grenzen ohne unsere Uhr ableiten, aus Daten außerhalb unserer Infrastruktur, und die erfasste Zeit des Eintrags liegt dazwischen. Widerlegt wird das Kriterium durch einen einzigen Eintrag, dessen erfasste Zeit außerhalb seines eigenen Intervalls liegt.
**Methode.** Jeder Eintrag hat drei Zeiten. *Erfasst* — die Serveruhr, auf die Mikrosekunde; das ist unser einziges Wort. *Nicht früher als* — der Bitcoin-Block, der im letzten vor dem Eintrag ausgestellten Checkpoint genannt ist: Der Eintrag liegt außerhalb des Baums dieses Checkpoints, wurde also später angefügt, und der Checkpoint konnte nicht vor dem Schürfen seines Blocks entstehen. *Nicht später als* — der früheste Anker, der den Eintrag abdeckt: die OpenTimestamps-Attestierung des ersten Checkpoints, der ihn enthält, die Attestierung der Wochenwurzel oder die Buchung der Überweisung mit dieser Wurzel. API und PDF-Nachweis nennen alle drei, zusammen mit dem Pfad des Eintrags zum ersten Checkpoint, der ihn enthält — der Nachweis und ein Checkpoint aus einer unabhängigen Kopie genügen zur Prüfung ohne uns. Unabhängig davon folgt die Uhr des Hosts heute vier Zeitservern dreier unabhängiger Betreiber, authentifiziert über NTS; eine Quelle, die von den übrigen abweicht, wird überstimmt. Der Dienst misst außerdem alle fünf Minuten seinen Offset gegenüber einem externen Server und veröffentlicht das Ergebnis — das Intervall aus den Ankern braucht diese Messung jedoch nicht.
**Ergebnis.** Bestätigt für Einträge seit dem ersten Checkpoint (25. September 2026); teilweise für das Log als Ganzes. Eine Prüfung zum Zeitpunkt des Schreibens umfasste alle 41 Einträge seit diesem Zeitpunkt: Die erfasste Zeit liegt in jedem Fall im Intervall; 40 Einträge haben beide Grenzen (der neueste wartet auf den Anker des nächsten Checkpoints); die Intervallbreite reicht von etwa 14 bis 25,5 Stunden, der Median liegt bei etwa 25. Beispiel: Eintrag Nr. 191 (Bekanntgabe des Namens Sigelith), erfasst am 27. September um 17:17:27 UTC — nicht früher als 26. September, 23:43 UTC (Block 968756), nicht später als 28. September, 00:35 UTC (Block 968908). Randbedingungen: (a) Blockzeiten stammen aus den Block-Headern, die der Miner mit einer Genauigkeit von etwa zwei Stunden setzt — die Grenzen sind auf Stunden genau, nicht auf Sekunden; (b) das Intervall betrifft den Zeitpunkt der Erfassung im Log, nicht die Entstehung des Dokuments; (c) die 171 Einträge vor dem ersten Checkpoint haben nur eine Obergrenze, und eine Untergrenze lässt sich nicht nachträglich hinzufügen; (d) die Bankbuchung trägt ein Datum ohne Uhrzeit; (e) die Untergrenze beruht auf der unveränderlichen Reihenfolge des Logs, und diese prüfen die Konsistenzbeweise gegen Kopien bei anderen (Richtung 2).
**Nächster Schritt.** Der Bankanker ist heute öffentlich als Verwendungszweck `MROOT` und als Referenznummer sichtbar; eine eigenständige Prüfung verlangt einen Kontoauszug oder eine Bestätigung der Bank. Die Spezifikation lässt die Veröffentlichung geschwärzter Auszüge zu, bisher wurde keiner veröffentlicht. Nächster Schritt: klären, ob ein solcher Auszug einem Dritten etwas gibt, was die Referenznummer allein nicht gibt.
**Status:** umgesetzt; volles Intervall für Einträge seit dem 25. September 2026, für frühere nur die Obergrenze.

### 4. Richtung 4 — eine Datensicherung, die ihren eigenen Nachweis mitführt
**Problem.** Ein Sicherungsprogramm vergleicht Dateien mit seinem eigenen Inhaltsverzeichnis, das neben ihnen liegt. Wer Dateien austauscht — Ransomware, ein Einbruch, ein alternder Datenträger, jemand mit Zugriff auf das Laufwerk —, kann auch das Verzeichnis austauschen, und die Prüfung fällt dann positiv aus. Zudem verlangt der Nachweis, dass eine bestimmte Datei in der Sicherung eines bestimmten Tages enthalten war, meist die Offenlegung der ganzen Sicherung oder zumindest ihres Verzeichnisses.
**Stand der Technik (veröffentlicht).** restic (`check --read-data`) und Borg (`check --verify-data`) prüfen die Daten gegen den authentifizierten Index des Repositorys — der Schutz beruht auf einem Schlüssel, den der Nutzer verwahrt; unveränderliche Datenträger und Speicher (WORM, Object Lock) schützen vor Änderungen, liefern Dritten aber für sich keinen Nachweis; gesalzene Hashes zur selektiven Offenlegung (u. a. SD-JWT); Domänentrennung von Blättern und Knoten nach RFC 6962.
**Kriterium (falsifizierbar).** (1) Ein Eintrag im öffentlichen Log je Sicherungsversion, ohne Dateinamen und deren Hashes; (2) für jede einzelne Datei ein Nachweis, der keine anderen Dateien der Version offenlegt; (3) eine Prüfung, die den Austausch einer Datei auch dann erkennt, wenn das Verzeichnis neben den Dateien ausgetauscht wurde. Widerlegt wird das Kriterium durch einen Austausch, den die Prüfung bei unverändertem Log-Eintrag nicht erkennt.
**Methode.** Sigelith Backup — ein Programm für versionierte, optional verschlüsselte Sicherungen auf ein externes Laufwerk, mit öffentlichem Code ([github.com/DeiFlagellum/sigelith-backup](https://github.com/DeiFlagellum/sigelith-backup)) — versieht jede Version mit einer Erklärung: dem Hash des Versionsverzeichnisses (Pfad, Größe und SHA-256 jeder Datei) und der Wurzel eines Merkle-Baums über den Dateien der Version. Ein Blatt ist der SHA-256 über Domänenbyte, Salz, Datei-Hash, Größe und Pfad-Hash; das Salz ist ein HMAC-SHA256 aus einem zufälligen Startwert der Version und dem Pfad. In das Log gelangt nur der Hash der Erklärung — ein Eintrag je Version. Der Nachweis einer einzelnen Datei (`sigelith-file-proof-v1`) besteht aus dem Pfad im Baum, der Erklärung und dem eingebetteten Nachweis des Log-Eintrags; den Dateipfad kann er offenlegen oder nicht. Die Prüfung kontrolliert die Erklärung ohne Netz (Pfad im Wochenbaum und Signatur mit einem im Programm hinterlegten, nicht vom Server gelieferten Schlüssel) und liest dann jede Datei vom Datenträger — nach Entschlüsselung mit Prüfung des GCM-Authentifizierungs-Tags und nach dem Zusammensetzen der Fragmente — und vergleicht sie mit dem Hash aus der Erklärung. Maßstab ist der Eintrag im öffentlichen Log, nicht das Verzeichnis neben den Dateien. „Letzte unberührte" ist die neueste Version, die zu ihrem Eintrag passt — aus ihr sollte man nach einem Angriff wiederherstellen. Die laufende Sicherung ergänzt Änderungen in der heutigen Version; eine Version, die bereits ihre Erklärung erhalten hat, wird nie ergänzt, und bei eingeschalteter Stempelung schließt die erste Ergänzung eines neuen Tages die gestrige Version ab und stempelt sie erst dann.
**Ergebnis.** Im Rahmen des Kriteriums bestätigt (Tests): Der Austausch einer Datei wird auch nach Zerstörung oder „Korrektur" des Inhaltsverzeichnisses erkannt; ein geändertes Verzeichnis, das von der Erklärung erfasst ist, ergibt kein falsches „unberührt"; in einer verschlüsselten Sicherung wird ein einzelnes geändertes Bit des Chiffrats erkannt; der Pfad zur Wurzel wurde für Bäume mit 1 bis 1000 Blättern geprüft; der Dateinachweis legt weder andere Dateien noch den Startwert offen. Dasselbe Nachweisformat prüfen drei Implementierungen an einem gemeinsamen Testvektor: das Programm selbst, der Desktop-Client und die Prüfseite im Browser. Randbedingungen, ausdrücklich: (a) Die Prüfung bindet die Dateien an *irgendeinen* Eintrag im öffentlichen Log, belegt aber nicht, dass es der erste Eintrag für diese Version ist — stempeln kann jeder, also kann, wer Schreibzugriff auf den Datenträger hat, eine Version neu aufbauen und mit einem neuen Eintrag versehen; verraten würde ihn das spätere Datum des Eintrags — das Programm zeigt es in seiner Zeitstempel-Ansicht an, die Prüfung vergleicht es heute aber nicht mit dem Datum der Version; (b) fehlendes Netz ist kein Sicherungsfehler — der Eintrag wird mit der nächsten Sicherung gesendet, sodass auch ein redlicher Eintrag später als das Versionsdatum liegen kann, was die Unterscheidung aus (a) schwächt; (c) bei eingeschalteter Stempelung liegen auf einem verschlüsselten Datenträger das Versionsverzeichnis (Pfade, Größen und SHA-256 des Klartexts jeder Datei) und die Erklärung unverschlüsselt neben den verschlüsselten Dateien — die Pfade sind ohnehin als Dateinamen sichtbar, die Klartext-Hashes erlauben aber jedem, der den Datenträger hat, zu prüfen, ob eine ihm bekannte Datei in der Sicherung liegt; (d) der Dateinachweis bezeugt, dass eine Datei mit genau diesen Bytes Teil einer zu einem bestimmten Zeitpunkt gestempelten Version war — nicht, wann die Datei entstand oder wer sie verfasst hat; (e) die laufende Sicherung hat einen Nachweis mit Tagesgenauigkeit: Änderungen des laufenden Tages haben keinen Eintrag, bis die Version dieses Tages abgeschlossen ist.
**Nächster Schritt.** Zwei offene Entscheidungen: ob die Prüfung das Datum des Eintrags selbst mit dem Datum der Version vergleichen soll — und wie sich eine verspätete Stempelung von einer neu aufgebauten Version unterscheiden lässt —, und ob das Versionsverzeichnis einer verschlüsselten Sicherung verschlüsselt werden soll: Der Preis ist die Prüfung der Erklärung ohne Passwort, der Gewinn ein Datenträger, der keine Klartext-Hashes preisgibt.
**Status:** umgesetzt (Sigelith Backup 3.0, öffentlicher Code); die Grenzen (a)–(e) gelten.

### 5. Richtung 5 — Durchsicht des Clients: was er als geprüft anzeigte und was er nicht prüfte
**Problem.** Ein Prüfprogramm, das als geprüft anzeigt, was es nicht geprüft hat, ist schlechter als keines: Es verwandelt die Behauptung des Ausstellers in ein grünes Häkchen beim Empfänger. Der Desktop-Client ist der Ort, an dem Beweise ohne Rückfrage beim Server geprüft werden — also der erste, der daraufhin durchgesehen werden musste.
**Stand der Technik (veröffentlicht).** Eine bekannte Fehlerklasse: Die Oberfläche schreibt die Gültigkeit einer Signatur Daten zu, die die Signatur nicht abdeckt — beschrieben u. a. für E-Mail-Clients mit OpenPGP und S/MIME („Johnny, you are fired!", USENIX Security 2019) und für PDF-Signaturen; das Pinnen eines einzigen Schlüssels ohne Historie — derselbe Ausfallmechanismus, wegen dessen die Browser HTTP Public Key Pinning (RFC 7469) zurückgezogen haben.
**Kriterium (falsifizierbar).** Jeder als geprüft angezeigte Wert ist durch eine Kontrolle gedeckt, die der Client tatsächlich ausgeführt hat; jeder andere ist als Angabe gekennzeichnet. Widerlegt wird das Kriterium durch einen einzigen als geprüft angezeigten Wert ohne diese Deckung.
**Methode.** Durchsicht des Client-Codes gegen die Formatspezifikation — was genau jede Signatur und jeder Pfad abdeckt — und Tests mit Manipulationsfällen.
**Ergebnis.** Kriterium widerlegt für die Versionen vor 2.1. Gefundene Fehlerklassen, alle in Version 2.1 (September 2026) behoben: (1) Der Client hatte einen einzigen Schlüssel fest hinterlegt — den zurückgezogenen; nach der Rotation hätte er jeden aktuellen Beweis als mit fremdem Schlüssel signiert verworfen und zugleich die Wurzeln des Spiegels angenommen; heute ergibt sich das Vertrauen aus einer eingebauten Schlüsselhistorie mit Daten, und eine Signatur mit einem zurückgezogenen Schlüssel ergibt höchstens die Stufe „registriert" mit der Bitte um Aktualisierung; (2) eine Beweisdatei mit verschobenem Datum wurde als „offline verifiziert" angenommen — die Signatur deckt Woche und Wurzel ab, das Blatt des Wochenbaums nur den Hash, die genaue Zeit in der Datei war also eine unsignierte Angabe; heute muss sie in der signierten Woche liegen, und strukturell schließt die Lücke das Blatt des globalen Baums, das die Zeit bindet (Richtung 2); (3) der PDF-Bericht nannte einen verworfenen Beweis bestätigt; (4) Bankanker wurden gezählt, ohne zu prüfen, ob sie dieselbe Wurzel tragen; (5) einige Felder aus der Serverantwort gelangten ohne Maskierung von Sonderzeichen in Beschriftungen der Oberfläche. Randbedingungen: Die Durchsicht war intern, kein externes Audit; sie betrifft den Desktop-Client ([github.com/DeiFlagellum/sigelith-desktop](https://github.com/DeiFlagellum/sigelith-desktop)) — den einzigen, der den Log-Teil lokal prüft.
**Nächster Schritt.** Die Manipulationsfälle aus dieser Durchsicht in die gemeinsamen Testvektoren aufnehmen, damit jedes Prüfprogramm — im Sicherungsprogramm, im Desktop-Client und im Browser — am selben Satz geprüft wird.
**Status:** Korrekturen umgesetzt; interne Durchsicht.

### Korrekturen zum Eintrag vom 2026-08-20
Der Eintrag vom 2026-08-20 bleibt unverändert. Im Folgenden seine Aussagen, die veraltet sind oder nicht genau waren.

**Der Stempel des Eintrags selbst.** Der Eintrag vom 2026-08-20 wurde am 20. August 2026 um 14:52 UTC gestempelt, in der Woche 2026-W34 — im Zeitraum des Vorfalls aus Richtung 1. Die Wurzel dieser Woche hatte ursprünglich der zurückgezogene Schlüssel signiert; heute trägt sie eine Signatur des neuen Schlüssels. Das Datum des Eintrags beruht nicht auf jener Signatur, sondern auf den Ankern: der Buchung der Überweisung mit der Wurzel der Woche W34 (25. August) und der Bitcoin-Attestierung dieser Wurzel über OpenTimestamps (26. August); auch Checkpoint Nr. 1 umfasst ihn. Eine Untergrenze aus Ankern gibt es nicht — der Eintrag ist älter als der erste Checkpoint. Die neben jenem Eintrag veröffentlichte Stempeldatei hält den Stand zum Zeitpunkt der Stempelung fest (Woche offen, vorläufige Wurzel); die endgültige Wurzel, den Pfad zu ihr und die Anker liefert das Log, etwa die Exportdatei der Woche 2026-W34 in der Quartalskopie bei Zenodo.

**„Die Anwendungsschichten (Android, Wear, Erweiterung, SDK) befinden sich im Aufbau".** Veraltet: Die Android-App und das Zifferblatt für die Smartwatch, der Desktop-Client, die Browsererweiterung und die SDK-Pakete sind veröffentlicht.

**Richtung 2: „eine periodische Aufgabe misst die Abweichung der Hostuhr gegenüber NTP".** Ungenau. Die Messung ist eine einzelne, nicht authentifizierte SNTP-Abfrage an einen einzigen externen Server; das Ergebnis ist die Differenz zu diesem Server, kein Fehler gegenüber UTC, und bleibt unsere Angabe — ein Zustandssignal des Dienstes, kein Beweis. Die Hostuhr folgt heute vier über NTS authentifizierten Servern, und der Zeitbeweis stützt sich nicht auf unsere Uhr (Richtung 3).

**Richtung 3: die Ed25519-Signatur als Teil des Ergebnisses „bestätigt".** Für den Zeitraum vom 15. Juni bis zum 21. September 2026 ungenau: Derselbe private Schlüssel lag auf dem Entwicklungsspiegel, eine gültige Signatur wies eine Wurzel also nicht als unsere aus (Richtung 1). Zudem war das Log Eintrag für Eintrag prüfbar, nicht aber als Ganzes — diese Lücke schließt Richtung 2.

**Richtung 4: „mindestens zwei unabhängige Ankerkanäle … jeder für sich prüfbar" — bestätigt.** Präzisierungsbedürftig. (a) Ein Anker bezeugt die Zeit, nicht die Urheberschaft: Der Entwicklungsspiegel verankerte seine Wurzeln über dieselben öffentlichen OpenTimestamps-Kalender. (b) Der Bankkanal ist in der Erfassung von uns unabhängig, doch ein Dritter sieht öffentlich nur den Verwendungszweck `MROOT` und die Referenznummer; eine eigenständige Prüfung verlangt einen Kontoauszug oder eine Bestätigung der Bank. (c) Für die Wochen 2026-W32, W33 und W34 kam die Bitcoin-Attestierung der Wurzeln erst am 26. August — 16,5, 9,5 und 2,5 Tage nach Wochenabschluss; die Obergrenze für diese Wochen bestimmt die Bankbuchung, am Tag des Abschlusses oder einen Tag danach. Der zweite Kanal erwies sich als nicht überflüssig. (d) Der manuelle Schritt des Bankkanals versagte einmal: Für 2026-W30 wurde ein zweiter Datensatz derselben Referenz mit einem Wert erfasst, der nicht die Wochenwurzel ist. Der Datensatz bleibt sichtbar und ist als nicht übereinstimmend gekennzeichnet; das Formular trägt die Wurzel heute selbst ein und prüft ihre Übereinstimmung mit der Woche.

**Richtung 6: Ko-Stempel-Protokoll v2.** Eine Replay-Lücke: Die Startsignatur der ersten Seite war nicht an eine einzelne Sitzung gebunden, sodass die öffentlichen Daten einer abgeschlossenen Sitzung genügten, um in ihrem Namen eine neue zu eröffnen; das Log konnte dann einen Ko-Stempel enthalten, den der Inhaber dieses Schlüssels nie ausgeführt hat. Seit dem 21. September wird ein Salz aus einer abgeschlossenen Sitzung abgelehnt.

**„Nächster Forschungsschritt: … (C2PA)".** Nicht aufgenommen; die Arbeit an C2PA hat nicht begonnen. Umgesetzt wurde ein anderer Schritt: ein Log, das sich von außen prüfen lässt (Richtung 2).

**Status der Richtung.** Die Beweisinfrastruktur läuft unter dem Namen Sigelith. Der Schlüsselvorfall hat die Annahme widerlegt, dass die Signatur unsere Wurzeln ausweist; das Vertrauen stützt sich heute auf ein Log, das jeder herunterladen und nachrechnen kann, auf Kopien bei GitHub, Internet Archive und Zenodo sowie auf Anker in Bitcoin und bei einer Bank. Jeder Eintrag seit dem 25. September 2026 hat ein von unserer Uhr unabhängiges Zeitintervall; Sicherungen führen ihren eigenen Nachweis mit offen benannten Grenzen; der Desktop-Client zeigt als geprüft nur, was er geprüft hat. Nächste Schritte: ein eigenständiges Prüfskript für Dritte und die Entscheidungen aus Richtung 4. Zeitkapseln — bis zu einem gewählten Zeitpunkt verschlossene Umschläge — und das Protokoll für Zustellnachweise werden in einem eigenen Eintrag beschrieben.

---
---

# 🇬🇧 ENGLISH VERSION

## Koch Laboratory — time as evidence, revisited: a key incident and a log that can be audited from outside

The entry of 2026-08-20 ("Time as an agreed unit and as evidence") described a time service whose statement is meant to hold for someone who trusts neither us nor our server. Six weeks later it is clear that one of its claims was weaker than it looked: for more than three months the same signing key was configured on two machines. This entry describes what followed from that, what was built in response, and which statements of the previous entry need correcting. The previous entry stays unchanged; the corrections are here, with a date.

**Name.** Since 27 September 2026 the whole proof infrastructure — the log, the checkpoints, the PDF proof documents and the verification API — is called Sigelith and runs at sigelith.org. Pages at beattime.live redirect (301) to the same address at sigelith.org; the API, the proof files and everything a program reads answer at both addresses without a redirect. The format identifiers inside signed bytes stay unchanged (`beattime-proof-v1`, `beattime-entry-v1`, `beattime-checkpoint-v1`) — renaming them inside signed data would invalidate every proof already issued. The name BeatTime now refers only to the two Android apps: the clock and the watch face. The clock remains an Internet Time clock — the day divided into 1000 parts, anchored in UTC — and a moment is written as @beat, for example @523.

**What is research here and what is not.** Most of what is described is integration of published standards: Merkle trees with inclusion and consistency proofs (RFC 9162), canonical JSON (RFC 8785), Ed25519 signatures (RFC 8032), OpenTimestamps, authenticated time synchronisation with NTS (RFC 8915). None of these mechanisms is ours. The research content is in the boundaries — what exactly a signature covers, what an anchor attests, what a copy does not attest — and in what failed.

**Method.** As in the rest of the laboratory: problem → state of the art → falsifiable criterion → method → result (confirmed, refuted or partial, with boundary conditions) → next step. A negative result is a result. Figures about the log come from its public data and anyone can check them without asking us; figures from tests are marked as such.

### 1. Direction 1 — a negative result: a valid signature did not show whose root it was
**Problem.** The entry of 2026-08-20 treated the Ed25519 signature over the weekly Merkle root as confirmation that the root came from us. From 15 June to 21 September 2026, however, the same private key was configured on two machines: the production service and a development mirror. The mirror runs the same scheduled jobs, so it closed weeks of its own, signed their roots with the shared key and anchored them in Bitcoin through OpenTimestamps. Two such roots came into being, for weeks 2026-W25 and 2026-W30. The error was found by our own security review in September 2026.
**State of the art (published).** In time-stamping under RFC 3161 and ETSI EN 319 421, compromise of a time-stamping unit's key is handled by revocation and notification — trust stays with the provider. In Certificate Transparency (RFC 6962, RFC 9162), a log that signs two inconsistent states loses trust as a whole. Both answers assume that the signature identifies the issuer.
**Criterion (falsifiable).** The hypothesis of the entry of 2026-08-20: a valid signature with our key identifies a root as ours. A single validly signed root that is not ours refutes it. Replacement criterion: the authoritative root must be determinable without trusting the signature, from data held outside our infrastructure.
**Method.** Key rotation on 21 September 2026 and re-signing of every published root with the new key — the roots do not change, and their existence in time is attested by Bitcoin and the bank, so re-signing moves nothing in time. The retired key is refused by the signing code itself; each machine pins the public key it is allowed to sign with, so a misconfigured machine ends up with no signature rather than a foreign one; the mirror no longer anchors anything. The key history is public and nothing is ever removed from it. The first public note said only that the key had been rotated "after a security review"; a few days later we published the full account with the list of rejected roots ([sigelith.org/spec/#incident-2026-09](https://sigelith.org/spec/#incident-2026-09)), because a rejected root that we do not name ourselves looks credible to anyone who is shown it with a valid signature. The page gives three checks that can be run without trusting us — including the decisive one for W25: the mirror's root for that week was frozen on the Monday of the same week, and a weekly root cannot be final before its week has ended.
**Result.** Hypothesis refuted: two validly signed roots (2026-W25, 2026-W30) are not ours; we publish them ourselves, by name, as rejected. No hash in the log changed, no stamp was lost or backdated — what was weakened is the claim resting on the signature alone. Replacement criterion met: the authoritative root of each week is the one recomputed from that week's published entries (copies held by third parties, direction 2), and for weeks with a bank anchor also the one written in the `MROOT` reference line of the transfer. Neither rejected root passes this test. **Trust has moved from the signature to copies held by others and to the anchors:** the signature is now one witness among several, not the identity of the log. Boundary conditions: an OpenTimestamps anchor attests time, not authorship — the mirror used the same public calendars as production; a rotation today requires changing the key list in three places (the service, the desktop client, the public log repository) and a new client release, and a client without that change shows every new proof as signed by a foreign key.
**Next step.** One key currently signs weekly roots, checkpoints and stamp receipts. Open question: should checkpoints carry signatures of independent witnesses, as some transparency logs do, so that the operator's key alone — compromised or misconfigured — is not enough to present a convincing alternative history?
**Status:** negative result (hypothesis refuted); correction implemented and described publicly.

### 2. Direction 2 — a log that can be audited from outside
**Problem.** Until 25 September 2026 anyone could check *their own* entry — the inclusion path to the weekly root — but nobody could audit *us*: download the whole log, recompute it from scratch and show that nothing had been cut out or rewritten. After direction 1 this is not a cosmetic gap: if the signature is not enough, something held by others is needed.
**State of the art (published).** Certificate Transparency (RFC 6962, RFC 9162): a Merkle tree over the whole log, inclusion and consistency proofs, signed tree states; transparency logs built on that pattern (among them the Go module checksum database and Sigstore Rekor), and witnesses that cosign checkpoints. The pattern is mature; we are not building a new one.
**Criterion (falsifiable).** A person with no access to our infrastructure downloads the whole log, recomputes the hash chain and every root, checks that each later checkpoint extends the earlier one (an RFC 9162 consistency proof), and compares the checkpoints with copies held by others. The criterion is refuted by any change to the published history — an entry removed, rewritten or reordered, two different checkpoints with the same number — that this procedure does not detect.
**Method.** One global tree over all entries since the first, in the shape of the RFC 9162 Merkle Tree Hash. A leaf binds the number, hash and time of an entry (`beattime-entry-v1|number|hash|time`), so a single path proves "this hash was entry no. N at moment T", not merely "this hash is somewhere in the tree". The weekly trees, their signatures and the transfer reference lines stay unchanged; the global tree complements them, it does not replace them. A checkpoint is a signed tree state in canonical JSON: issued daily and right after each week closes, chained to the hash of the previous checkpoint file, naming a Bitcoin block (depth 3; two independent block explorers must agree) and itself anchored in Bitcoin through OpenTimestamps. Checkpoint no. 1 (25 September) covers the whole log since the first entry — 171 entries. The whole log can be downloaded (entry pages and weekly dumps), and consistency proofs between checkpoints are publicly available ([sigelith.org/checkpoints/](https://sigelith.org/checkpoints/)). Copies held by third parties are made automatically: OpenTimestamps/Bitcoin — every checkpoint, daily; the `MROOT` reference line of a bank transfer — every weekly root, weekly; GitHub (immutable releases, [github.com/DeiFlagellum/sigelith-log](https://github.com/DeiFlagellum/sigelith-log)) and the Internet Archive — weekly; Zenodo — quarterly, a complete snapshot under CC0. Since 28 September every response to a stamp request carries a signed receipt (number, hash, time, chain link): a log that later lacks such an entry is convicted by its own signature — the role an SCT plays in Certificate Transparency. Since version 2.2 the desktop client (now Sigelith Desktop, called BeatStamp before version 3.0) checks every checkpoint in the background — file bytes, signature, chain, consistency — compares it byte for byte with the copies at GitHub, the Internet Archive and Zenodo, and checks the block with an independent explorer; a checkpoint with a known number and different content is kept as evidence. In its default mode it keeps a copy of the whole log and computes paths itself; the server learns at most which week was asked about.
**Result.** Confirmed within the criterion. Inclusion and consistency proofs were checked exhaustively before going live for every tree size from 1 to 64 (test): 2080 of 2080 genuine proofs of each kind accepted, 8190 of 8190 forgeries rejected (among them a wrong path, a wrong index, a rewritten entry in history); generation follows the recursive definition, verification the iterative algorithm — both forms in RFC 9162 must agree. A second implementation, written from the text of the specification alone and deliberately without importing any production code, reproduced production on its first run on 25 September: 171 entries, 13 weekly dumps, global root and weekly roots matching, weekly roots equal to the `MROOT` reference lines. At the time of writing this was repeated with a further, separately written implementation: the roots at 171 and 211 entries equal the roots of checkpoints no. 1 and no. 8, the consistency proof between them is valid, and so is the signature of checkpoint no. 1. Boundary conditions: (a) an exhaustive test on small trees is an argument for a correct implementation, not a proof; (b) the second implementation is independent in code, not in person — it was written by the same author; there has been no third-party audit so far; (c) the copies at GitHub, the Internet Archive and Zenodo are passive — they store but check nothing before accepting; checking is done by clients and by anyone who downloads them, and there are no cosigning witnesses; (d) the history before 25 September is pinned as a whole only by checkpoint no. 1, before that only by the weekly anchors; (e) the server code is not public and does not need to be, because verification does not use it: the formats are described in the specification and in the public log repository; (f) local verification is done by the desktop client; the browser pages and the Android app compute a file's hash locally but take the log part from the server's response and point to the independent copies for comparison.
**Next step.** A standalone verification script for third parties that takes the checkpoint from an independent copy rather than from us — the only item of this direction's plan not yet done.
**Status:** implemented since 25 September 2026 (first weekly release: 2026-W39; first quarterly version: 2026-Q3).

### 3. Direction 3 — a time bracket for every entry from external anchors instead of our clock
**Problem.** The time of an entry is a reading of our server's clock. The entry of 2026-08-20 relied on weekly granularity ("no later than") and on publishing the clock's own error, but both remain our word. The most serious accusation against any time-stamping service is that the operator backdated an entry at someone's request. The answer to it must not depend on the operator's clock.
**State of the art (published).** RFC 3161: the time comes from the authority's clock and is worth as much as trust in the authority; linked time-stamping (Haber and Stornetta, 1991) — order without trust, but no absolute time; OpenTimestamps — an upper bound ("existed no later than") from Bitcoin; Roughtime — authenticated rough time with proof of server misbehaviour; NTS (RFC 8915) — authenticated clock synchronisation. The lower bound comes from a known technique: a value that could not have been known before a given moment — here the hash of a Bitcoin block — proves that whatever contains it was created later.
**Criterion (falsifiable).** For every entry both bounds can be derived without our clock, from data held outside our infrastructure, and the recorded time of the entry lies between them. A single entry whose recorded time lies outside its own bracket refutes the criterion.
**Method.** Every entry has three times. *Recorded* — the server clock, to the microsecond; this is our only word. *Not earlier than* — the Bitcoin block named in the last checkpoint issued before the entry: the entry lies outside that checkpoint's tree, so it was appended later, and the checkpoint could not have been created before its block was mined. *Not later than* — the earliest anchor that covers the entry: the OpenTimestamps attestation of the first checkpoint containing it, the attestation of the weekly root, or the booking of the transfer carrying that root. The API and the PDF proof document give all three, together with the entry's path to the first checkpoint containing it — the document plus a checkpoint taken from an independent copy suffice to check without us. Independently of this, the host clock now follows four time servers of three independent operators, authenticated with NTS; a source that disagrees with the others is outvoted. The service also measures its own offset against an external server every five minutes and publishes the result — but the bracket from the anchors does not need that measurement.
**Result.** Confirmed for entries since the first checkpoint (25 September 2026); partial for the log as a whole. A check at the time of writing covered all 41 entries made since then: in every case the recorded time lies within the bracket; 40 entries have both bounds (the newest is waiting for the anchor of the next checkpoint); bracket widths range from about 14 to 25.5 hours, median about 25. Example: entry no. 191 (the announcement of the name Sigelith), recorded on 27 September at 17:17:27 UTC — not earlier than 26 September, 23:43 UTC (block 968756), not later than 28 September, 00:35 UTC (block 968908). Boundary conditions: (a) block times come from block headers, which miners set to within about two hours — the bounds are accurate to hours, not seconds; (b) the bracket concerns the moment of recording in the log, not the creation of the document; (c) the 171 entries made before the first checkpoint have only an upper bound, and a lower bound cannot be added retroactively; (d) a bank booking carries a date without a time of day; (e) the lower bound rests on the log's order being immutable, which the consistency proofs against copies held by others check (direction 2).
**Next step.** The bank anchor is publicly visible today as the `MROOT` reference line and a reference number; checking it independently requires a statement or a confirmation from the bank. The specification allows for publishing redacted statements; none has been published so far. Next step: establish whether such a statement gives a third party anything the reference number alone does not.
**Status:** implemented; full bracket for entries since 25 September 2026, upper bound only for earlier ones.

### 4. Direction 4 — a backup that carries its own evidence
**Problem.** A backup program compares files with its own table of contents, which lies next to them. Whoever replaces the files — ransomware, an intrusion, a failing drive, someone with access to the disk — can replace the table of contents as well, and the check then passes. Moreover, showing that a particular file was in a given day's backup usually requires disclosing the whole backup, or at least its file list.
**State of the art (published).** restic (`check --read-data`) and Borg (`check --verify-data`) check data against the repository's authenticated index — the protection rests on a key the user keeps; immutable media and storage (WORM, object lock) protect against change but by themselves give no evidence to a third party; salted hashes for selective disclosure (e.g. SD-JWT); domain separation of leaves and nodes as in RFC 6962.
**Criterion (falsifiable).** (1) One entry in the public log per backup version, with no file names and no file hashes; (2) for any single file, a proof that discloses no other file of the version; (3) an audit that detects a replaced file even when the table of contents next to the files has been replaced too. The criterion is refuted by a replacement that the audit does not detect while the log entry is intact.
**Method.** Sigelith Backup — a program for versioned, optionally encrypted backups to an external drive, with public code ([github.com/DeiFlagellum/sigelith-backup](https://github.com/DeiFlagellum/sigelith-backup)) — gives every version a statement: the hash of the version's file list (path, size and SHA-256 of every file) and the root of a Merkle tree over the version's files. A leaf is the SHA-256 of a domain byte, a salt, the file hash, the size and the hash of the path; the salt is an HMAC-SHA256 of a random per-version seed and the path. Only the hash of the statement goes to the log — one entry per version. The proof for a single file (`sigelith-file-proof-v1`) consists of the path in the tree, the statement and the embedded proof of the log entry; it may or may not disclose the file's path. The audit checks the statement offline (the path in the weekly tree and the signature, using a key built into the program rather than one supplied by the server), then reads every file back from the drive — after decryption with a check of the GCM authentication tag and after reassembling chunks — and compares it with the hash covered by the statement. The reference is the entry in the public log, not the file list lying next to the files. "Last untouched" is the newest version that matches its entry — the one to restore from after an attack. The live backup tops up today's version with changes; a version that has already been given its statement is never topped up, and with stamping switched on the first top-up of a new day closes yesterday's version and only then stamps it.
**Result.** Confirmed within the criterion (tests): a replaced file is detected even after the table of contents was destroyed or "corrected"; a modified file list covered by the statement yields no false "untouched"; in an encrypted backup a single changed bit of ciphertext is detected; the path to the root was checked for trees of 1 to 1000 leaves; a file proof discloses neither other files nor the seed. The same file-proof format is checked by three implementations on a shared test vector: the program itself, the desktop client and the verification page in the browser. Boundary conditions, stated plainly: (a) the audit binds the files to *some* entry in the public log, but does not prove that it is the first entry for this version — anyone can stamp, so whoever has write access to the drive can rebuild a version and give it a new entry; the later date of that entry would give it away, and the program shows that date in its timestamp view, but the audit does not yet compare it with the version's date; (b) a missing network connection is not a backup error — the entry is sent with the next backup, so an honest entry may also be later than the version's date, which weakens the distinction in (a); (c) with stamping switched on, an encrypted drive holds the version's file list (paths, sizes and SHA-256 of every file's plaintext) and the statement unencrypted, next to the encrypted files — paths are visible anyway as file names, but the plaintext hashes let anyone holding the drive test whether a file they know is in the backup; (d) a file proof attests that a file with exactly these bytes was part of a version stamped at a given moment — not when the file was created or who wrote it; (e) the live backup has evidence to the day: the current day's changes have no entry until that day's version is closed.
**Next step.** Two open decisions: whether the audit should itself compare the entry's date with the version's date — and how to tell late stamping from a rebuilt version — and whether the file list of an encrypted backup should be encrypted: the cost is checking the statement without the passphrase, the gain a drive that does not reveal plaintext hashes.
**Status:** implemented (Sigelith Backup 3.0, public code); boundaries (a)–(e) apply.

### 5. Direction 5 — a client review: what it showed as verified and what it did not check
**Problem.** A verifier that shows as verified something it did not check is worse than no verifier: it turns the issuer's claim into a green tick at the recipient's end. The desktop client is where proofs are checked without asking the server — so it was the first that had to be reviewed from this angle.
**State of the art (published).** A known class of errors: the interface attributes a signature's validity to data the signature does not cover — described, among others, for e-mail clients with OpenPGP and S/MIME ("Johnny, you are fired!", USENIX Security 2019) and for PDF signatures; pinning a single key without history — the same failure mechanism that led browsers to drop HTTP Public Key Pinning (RFC 7469).
**Criterion (falsifiable).** Every value shown as verified is covered by a check the client actually performed; every other value is marked as a declaration. A single value shown as verified without such cover refutes it.
**Method.** A review of the client code against the format specification — what exactly each signature and each path covers — and tests with manipulation cases.
**Result.** Criterion refuted for the versions before 2.1. The classes of error found, all fixed in version 2.1 (September 2026): (1) the client had a single key hard-coded — the retired one; after the rotation it would have rejected every current proof as signed by a foreign key while accepting the mirror's roots; trust now comes from a built-in key history with dates, and a signature by a retired key yields at most the level "registered", with a prompt to refresh; (2) a proof file with a shifted date was accepted as "verified offline" — the signature covers the week and the root, the leaf of the weekly tree only the hash, so the exact time in the file was an unsigned declaration; it must now lie within the signed week, and structurally the gap is closed by the leaf of the global tree, which binds the time (direction 2); (3) the PDF report called a rejected proof confirmed; (4) bank anchors were counted without checking that they carry the same root; (5) some fields from the server response reached interface labels without escaping of special characters. Boundary conditions: the review was internal, not an external audit; it covers the desktop client ([github.com/DeiFlagellum/sigelith-desktop](https://github.com/DeiFlagellum/sigelith-desktop)) — the only one that verifies the log part locally.
**Next step.** Add the manipulation cases from this review to the shared test vectors, so that every verifier — in the backup program, in the desktop client and in the browser — is tested against the same set.
**Status:** fixes implemented; internal review.

### Corrections to the entry of 2026-08-20
The entry of 2026-08-20 stays unchanged. Below are its statements that are outdated or were not accurate.

**The stamp of that entry itself.** The entry of 2026-08-20 was stamped on 20 August 2026 at 14:52 UTC, in week 2026-W34 — within the period of the incident in direction 1. The root of that week was originally signed with the retired key; it is now re-signed with the new one. The date of the entry does not rest on that signature but on the anchors: the booking of the transfer carrying the W34 root (25 August) and the Bitcoin attestation of that root through OpenTimestamps (26 August); checkpoint no. 1 also covers it. There is no lower bound from anchors — the entry is older than the first checkpoint. The stamp file published next to that entry records the state at the moment of stamping (week open, provisional root); the final root, the path to it and the anchors come from the log, for example from the dump of week 2026-W34 in the quarterly copy at Zenodo.

**"The application layers (Android, wear, extension, SDK) are under construction".** Outdated: the Android app and the watch face, the desktop client, the browser extension and the SDK packages are published.

**Direction 2: "a periodic task measures the host clock's drift against NTP".** Imprecise. The measurement is a single unauthenticated SNTP query to a single external server; the result is the difference from that server, not an error against UTC, and it remains our statement — a health signal of the service, not evidence. The host clock now follows four servers authenticated with NTS, and the proof of time does not rest on our clock (direction 3).

**Direction 3: the Ed25519 signature as part of the result "confirmed".** Inaccurate for the period from 15 June to 21 September 2026: the same private key was on the development mirror, so a valid signature did not identify a root as ours (direction 1). Moreover, the log could be checked entry by entry but not as a whole — direction 2 closes that gap.

**Direction 4: "at least two independent anchoring channels … each verifiable on its own" — confirmed.** Needs qualifying. (a) An anchor attests time, not authorship: the development mirror anchored its roots through the same public OpenTimestamps calendars. (b) The banking channel is independent of us in the recording, but a third party publicly sees only the `MROOT` reference line and the reference number; checking it independently requires a statement or a confirmation from the bank. (c) For weeks 2026-W32, W33 and W34 the Bitcoin attestation of the roots arrived only on 26 August — 16.5, 9.5 and 2.5 days after the week closed; for those weeks the upper bound is set by the bank booking, on the day of closing or one day later. The second channel turned out not to be redundant. (d) The manual step of the banking channel failed once: for 2026-W30 a second record of the same reference was entered with a value that is not the week's root. The record stays visible, marked as not matching; the form now fills in the root itself and checks it against the week.

**Direction 6: co-stamping protocol v2.** A replay gap: the first party's start signature was not bound to a single session, so the public data of a completed session sufficed to open a new one in that party's name; the log could then contain a co-stamp that the holder of that key never performed. Since 21 September a salt from a completed session is refused.

**"Next research step: … (C2PA)".** Not taken; work on C2PA has not started. A different step was taken: a log that can be audited from outside (direction 2).

**Status of the direction.** The proof infrastructure runs under the name Sigelith. The key incident refuted the assumption that the signature identifies our roots; trust now rests on a log anyone can download and recompute, on copies held by GitHub, the Internet Archive and Zenodo, and on anchors in Bitcoin and at a bank. Every entry since 25 September 2026 has a time bracket independent of our clock; backups carry their own evidence with openly stated boundaries; the desktop client shows as verified only what it has verified. Next steps: a standalone verification script for third parties and the decisions from direction 4. Time capsules — envelopes closed until a chosen moment in the future — and the proof-of-delivery protocol will be described in a separate entry.
