Koch Laboratory

Time as evidence, a third look: cosigners with their own clocks and the limits of the “2 of 3” rule

Continues and corrects the entry of 2026-10-01. Since 6 October the state of the log has been confirmed by two cosigners that check the chain, the tree and the time of entries themselves, and since 19 October the verification page and the PHP library compute the “2 of 3” rule on their own. The limit is stated plainly: the operator holds two of the three keys, so the rule protects against a break-in and against misconfiguration. Also: a stamping lock when the clock error is unknown, two negative results and a proof of minimum elapsed time in its measurement phase.

Koch Laboratory - time as evidence, a third look: cosigners with their own clocks and the limits of the “2 of 3” rule

The entry of 2026-10-01 (“Time as evidence, revisited”) closed direction 1 with an open question: whether the state of the log should be signed by independent parties, so that the operator’s key alone - compromised or misconfigured - is not enough to present a convincing alternative history. Five days later two cosigners were running. This entry describes what they check and where the limits of the “2 of 3” rule lie, how the service stopped stamping when the error of its clock is unknown, what has since turned out to be a mistake, and which statements of the entry of 2026-10-01 are now outdated. The full description of the design and the procedure that a court expert carries out alone are given in the technical report of 9 October 2026 (doi.org/10.5281/zenodo.23265547).

What is research here and what is not. Witness signatures over the state of the log are a mature transparency-log pattern; authenticated time synchronisation (NTS, RFC 8915), the rule of suspending time stamps after a loss of synchronisation and the proof of sequential work from direction 4 are not ours either. The research content is in the limits - what exactly a cosigner’s signature attests, how much protection the “2 of 3” rule gives when the operator holds two of the three keys, and what of this a person checking a stamp sees - and in what failed. The evidentiary claim remains unchanged: a stamp shows that a file with a given fingerprint already existed at the moment of the stamp - not that it did not exist earlier, nor who its author is.

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 from tests are marked as such.

1. Direction 1 - cosigners that check the time of entries, not only the consistency of the log

Problem. After the key incident (entry of 2026-10-01, direction 1), trust moved from the signature to the copies and the anchors. The copies, however, are passive - they store but check nothing before accepting - and up to about a day passes between a stamp and the nearest anchor in Bitcoin. In that window the time of an entry was solely the operator’s word: nobody but the operator was observing the log on an ongoing basis. State of the art (published). Witnesses that cosign the tree state in transparency logs (the C2SP specifications tlog-cosignature and tlog-witness, the Go module checksum database, Sigstore) and collective witness signatures (CoSi; Syta et al., IEEE S&P 2016). Threshold analysis for witnesses (N. Möller, Sigsum project, 2023): a k-of-n rule protects against divergent versions of the history with f dishonest signers only if 2k > n + f. In this pattern a witness attests above all the consistency of successive tree states and the moment at which it saw them; it usually does not check the time recorded in individual entries. Criterion (falsifiable). (1) A cosigner signs only what it has checked itself: the hash chain, the global tree recomputed from scratch, and the time of each new entry against its own clock - with a tolerance of ±30 s, and no entry may be older than the cosigner’s previous observation; (2) the service’s server cannot itself produce a cosigner’s signature or slip it anything to sign; (3) a verifying program shows a stamp as confirmed only when it has itself checked at least two of the three signatures. The criterion is refuted by a cosigner’s signature over a state the cosigner did not check, a signed entry dated back beyond the tolerance, or a confirmation shown without two checked signatures. Method. Since 6 October 2026 two cosigner programs have been running on separate machines and accounts: one in AWS (a Lambda function in Frankfurt, the key in an AWS KMS hardware module), run by the Sigelith operator, the other at Konveria - an independent company in Kraków with no personal or capital ties to the operator, which also publishes the Sigelith Android apps. Every minute each cosigner fetches the public log itself, checks the chain and the time of new entries, recomputes the RFC 9162 tree and signs what it saw (sigelith-cosign-v1: tree size and root, last entry, its own time and the time of its previous observation). A cosigner takes no input of any kind from outside. The server holds no cosigner keys - it stores and serves their signatures, and records a signature that does not match its own tree as not matching. Any anomaly - a broken chain, time going backwards, a backdated entry or one dated in the future - stops the cosigner until a manual decision by its operator; a cosigner never signs “anyway”, and the latest signature of each cosigner is public, so an interruption is visible. A stamp counts as confirmed when any two of the three signatures support it: that of the log key (the receipt) and those of the two cosigners. The cosigner program is public, with a reproducible build, a protocol description, a test vector and tests of these stops (github.com/DeiFlagellum/sigelith-cosigner, Apache-2.0). Since 19 October the verification page (/proof/) and the PHP library for plugins compute the “2 of 3” rule themselves: the receipt, the RFC 9162 path to a signed root and the cosigners’ signatures, with keys built into the code; the page shows “N of 3 signatures verified in this browser” solely from its own computations, and a mismatching signature always in red. Since 26 October Sigelith Backup writes the cosigners’ signatures to an archive disc and checks them offline; its verifier is a port of the page’s module and uses the same test vectors. Result. Confirmed within the criterion. On 6 October at 20:13 UTC entry no. 300 had three of three signatures, each checked separately; on 19 October the page in the browser and the PHP library showed three of three on the live API (tests on shared vectors: 14 cases in JavaScript, 1724 checks in PHP 7.4 and 8.3). The time window of an entry shrank from about a day (anchors) to about a minute (the cosigners’ observations) - e.g. entry no. 320, recorded at 18:48:03.213 UTC, was seen by the AWS cosigner between 18:47:05 and 18:48:05 and by the Konveria cosigner between 18:47:31 and 18:48:31. Boundary conditions: (a) two of the three signing systems are run by the operator - the log key and the AWS cosigner; the service’s server has no access to the AWS account, but the operator, as its owner, does. For a 2-of-3 setup, the condition 2k > n + f gives f = 0: the rule tolerates no colluding signer, and the operator satisfies it on its own. “2 of 3” therefore protects against a break-in into one system and against a configuration error like the one in September; independent of the operator are the Konveria cosigner, Bitcoin, the bank and the archives; (b) that Konveria is independent and that the key cannot be copied out of AWS KMS are statements that cannot be checked cryptographically; (c) a cosigner’s window comes from its own clock - it is as good as that clock and is not an independent source of time; (d) the /proof/ page computes in the browser, but its code is delivered by the operator’s server - the procedure in the report remains the independent check, and the desktop client, which checks proofs without the server, does not yet check the cosigners’ signatures; (e) entries made before 6 October have no cosigner window; (f) a cosigner stops after every anomaly, and so far we have not measured the cosigners’ availability. Next step. Measuring the cosigners’ availability from their public signatures; checking the cosigners’ signatures in the desktop client. It remains open whether and when further independent cosigners will join: the same condition implies (our own calculation) that an operator with two keys stops satisfying the rule on its own when there are at least three independent cosigners and the threshold is 4 of 5. Status: implemented since 6 October 2026; “2 of 3” checking in the browser and in PHP since 19 October, in Sigelith Backup since 26 October; boundaries (a)-(f) apply.

2. Direction 2 - the service stops stamping when it does not know the error of its clock

Problem. The recorded time of an entry is a reading of the server clock. The entry of 2026-10-01 pointed out, by way of correction, that the offset measurement used until then had been a single unauthenticated SNTP query to a single server - a health signal, not evidence. Nor, until 6 October, did anything halt stamping when the clock deviated: an entry with a wrong time would at most have been detected by the anchors, to within hours. State of the art (published). Authenticated time synchronisation with NTS (RFC 8915); the ETSI EN 319 421 standard provides for suspending the issuance of time stamps after synchronisation with UTC is lost (Sigelith is not subject to this standard and does not claim conformity with it); RFC 3161 - the time of a time stamp is worth as much as the authority’s clock. Criterion (falsifiable). A new entry and a new checkpoint are created only when the last successful clock measurement is at most 15 minutes old and the offset does not exceed 0.25 s; otherwise the service refuses (code 503, clock_untrusted) and records nothing. A single entry recorded outside these conditions refutes it. Method. Since 6 October 2026 the service itself measures the offset of its clock every 5 minutes, over NTS, against the PTB servers (Physikalisch-Technische Bundesanstalt, Germany’s national metrology institute), and when both are unreachable - against Netnod. Every attempt is recorded; the latest measurement is public (/api/health/, the /evidence/ page), and the PDF certificate of an entry gives the last measurement before the entry (“Server clock”). The lock does not change entries recorded earlier. Result. Implemented; spot measurements: on 6 October an offset below 0.1 ms with a delay of 9 ms, on 9 October 0.2 ms. Boundary conditions: (a) the measurement is the operator’s statement about its own measurement, not a confirmation by PTB - PTB itself cautions that NTS gives no legally binding information about time; (b) the history of measurements is not public, and that the lock works is the operator’s word - there is no public indicator of its state; (c) an attacker on the path can shift the measurement by at most half the round-trip time, in practice by milliseconds; (d) independently of this measurement, the time of an entry is checked by the cosigners (direction 1, with a tolerance of ±30 s) and by the anchors. Next step. Establish whether and how to publish the history of measurements and the state of the lock so that they can be checked without asking the operator. Status: implemented since 6 October 2026.

3. Direction 3 - negative results and fixes since 1 October

(a) The access log made it possible to link a stamp to a network and a browser. The time of an entry is public to the microsecond, and the web server’s access log recorded the time of the request, the /24 network and the User-Agent header; the application server additionally recorded the full request URLs together with the fingerprints. After the fact, a stamp could therefore be matched to the network and browser of the person who made it. Negative result: the absence of an account and an e-mail address was not enough to keep a stamp from being linked to someone. Fix of 9 October 2026: an access log without IP address, port or request headers (only the domain of the referring page remains), an application server without an access log, a filter that cuts every 64-character fingerprint out of messages, rate-limit counters in process memory only; checked after deployment. Boundary condition: the operator, who controls the server, can change these settings at any time - anyone who needs anonymity towards the operator as well should stamp via Tor (connections via Tor do not end up in any access log). (b) The PHP library mistook a refusal for a stamp. The PHP library for plugins did not check the HTTP status code: responses 400, 429 and 503 gave a result that looked like a successful stamp. The error mattered all the more because since 6 October the service deliberately answers with code 503 when it does not trust its clock (direction 2). Found in an internal review on 6 October, fixed on 19 October: every 4xx and 5xx response is reported as an error carrying the HTTP code. This is the same class of error as in the review of the desktop client (entry of 2026-10-01, direction 5) - showing as done something that was not done. (c) Sentences stronger than the system - corrected after the external review of 7 October. The external reviewer reproduced the cryptographic core from the public specification alone and at the same time pointed out sentences that promised more than the system provides. Corrected the same day: (1) “Verifiable without trusting anyone - including us” was replaced by “Verifiable without taking our word for it”: the verifier in the browser comes from our server, and an independent check is made with the open-source Sigelith Desktop program or with the procedure for court experts; (2) anyone can check Bitcoin and the archives without us, but we provide the confirmation of the transfer carrying the root on request, and the bank confirms it at the request of a court; (3) GitHub is no longer on the list of “parties we do not control” - the releases are in our account; (4) where Konveria is mentioned, it was added that it is an independent company with no personal or capital ties to the operator; (5) the specification says explicitly that the recording of an entry can be delayed only towards a later time, never towards an earlier one, and that the server holds no cosigner keys. Status: fixes implemented.

4. Direction 4 - Hourglass: a proof of minimum elapsed time (in progress)

Problem. The anchors give an upper bound on time, and the Bitcoin block named in a checkpoint a lower one. Nothing, however, proves how much time passed between two events in the log, independently of clocks - neither ours nor the cosigners’. State of the art (published). Proofs of sequential work (B. Cohen, K. Pietrzak, Simple Proofs of Sequential Work, EUROCRYPT 2018). Verifiable delay functions (VDFs) cannot be built from hash functions alone in the random oracle model; the price of a construction based solely on hashes is that verification guarantees only that a part of the work was done. Criterion (falsifiable). Between two events at least the time implied by the number of steps performed has passed - under the explicit assumption k that nobody computes this work more than k times faster than the measured prover. Hardware that computes faster than the assumed k refutes it. Method. Since 19 October 2026 the service’s server has been computing Sigelith Hourglass - a Cohen-Pietrzak proof of sequential work on SHA-256, in segments, on a single processor core. The seed of each segment absorbs a fresh Bitcoin block and the latest Sigelith checkpoint, and each segment links to the root of the previous one; the segment’s record is stamped in the log and confirmed by the cosigners. We implement the Cohen-Pietrzak construction faithfully; what is new is the system and the measurements. The specification, the reference implementation and the code are public (github.com/DeiFlagellum/sigelith-hourglass, Apache-2.0). Result. None yet - phase 0 is a 30-day measurement on the production server (genesis stamped as entry no. 453, ending on 18 November 2026). Until it ends, k = 20 is an assumption, and nothing from phase 0 goes onto certificates. Boundary conditions stated in advance: (a) lower bounds only, and modest ones - with k = 20 a week of segments would prove about 6 hours; (b) Hourglass is computed by a single operator - the clock can be stopped; forging it silently is ruled out only by publicly available segments, because then anyone would see two different roots of one segment; (c) the segment files are not published yet, so today a third party can check only that the fingerprints of the segment records were recorded in the log, not the proof of work itself. Next step. After 18 November: analysis of the measurement, a public note, the parameters and the genesis of version 1 - in a separate entry. Status: in progress (phase 0).

Status of the steps announced on 1 October

Corrections to the entry of 2026-10-01

The entry of 2026-10-01 stays unchanged. Below are its statements that are outdated or were not accurate.

Direction 1, “Next step”: signatures of independent witnesses as an open question. Outdated since 6 October 2026 (direction 1 of this entry).

Direction 1, boundary conditions: “a rotation today requires changing the key list in three places”. Outdated: the public keys are now also built into the module of the /proof/ page, the PHP library and Sigelith Backup, so a rotation requires changes in more places and new releases.

Direction 2, Method and “Status of the direction”: GitHub among the copies held by third parties. Inaccurate: the releases on GitHub are immutable, but they sit in the operator’s account, and the whole repository can be deleted. GitHub keeps a copy outside our infrastructure, not outside our control.

Direction 2, boundary condition (c): “there are no cosigning witnesses”. Outdated since 6 October 2026.

Direction 2, boundary condition (f): the browser pages take the log part from the server’s response. Outdated for the /proof/ page: since 19 October it computes the receipt, the path to the signed root and the cosigners’ signatures itself.

Direction 3, Method: “the service also measures its own offset against an external server every five minutes and publishes the result”. Inaccurate since 6 October: the published result is now the last authenticated measurement against PTB, which blocks new entries (direction 2 of this entry); the history of measurements is not public.

“Status of the direction”: “Next steps: a standalone verification script for third parties and the decisions from direction 4”. The script was replaced by the procedure for court experts (see “Status of the steps”); the decisions from direction 4 remain open. Time capsules and the proof-of-delivery protocol are still waiting for a separate entry.

Status of the direction. Since 6 October the state of the log has been confirmed by two cosigners with their own clocks, and since 19 October the verification page and the PHP library compute the “2 of 3” rule themselves. The service stops stamping when it does not know the error of its clock. Next steps: measuring the cosigners’ availability, checking their signatures in the desktop client, the results of Hourglass phase 0 (after 18 November 2026) and a decision on publishing the history of clock measurements.

Proof of time

This text was hashed and stamped on publication. Verifying it takes both files: the stamp proves that one exact byte string existed at that moment, and only the source below is that byte string. Any later edit changes the hash and breaks the match — which is the point.

· @390.24 · 2026-W46

SHA-256 of the stamped text: 98f9b984c9299515d216ba8ace32d5d2460e38f30d498c60672fef9a51070fa4

Verify with: ots verify <proof> --file <source>