# Waxseal records in evidence

What a tender record establishes, how anyone can check it, and — at length — what it does
not prove. Version 0.2, September 2026. Draft for comment.

Written for counsel, procurement officers and auditors. The authors are not lawyers and
this is not legal advice; corrections are more useful than agreement.

## Summary

Waxseal runs sealed-bid tenders and auctions on the Midnight network. Each tender is a
smart contract. Bids never appear on the ledger: each bidder publishes a *commitment* (a
32-byte hash of the bid and a random value) and a zero-knowledge proof that the hidden bid
is valid. The winner is later proven from the commitments, not announced by anyone.

A tender record lets any party, without an account and without Waxseal's cooperation,
establish five things:

1. the rules and the published description were fixed before bidding, and nobody could
   change them afterwards;
2. each sealed bid was recorded before the deadline, and none was changed afterwards;
3. the published result follows from the sealed bids and the rules;
4. deposits were locked and released as the rules say;
5. a bidder can later prove to a person of their choosing exactly what they bid.

Each point is separately checkable. Losing bids are never disclosed by the system.

## 1. What a record establishes

### 1.1 The rules were fixed, and could not change

At creation the contract stores the public parameters (valid bid range, deadline, deposit,
whether the lowest or highest bid wins, clock or committee settings) and the SHA-256 hash of
the tender's description and document list. Anyone holding the description can hash it and
compare; a single changed character gives a different hash.

What the contract *can do* is determined by its circuits. On Midnight, a contract accepts a
transaction only with a zero-knowledge proof that verifies against the contract's stored
verifier keys. Waxseal publishes the fingerprint of every verifier key of every release
(`packages/contracts/releases.json`); a verifier compares the keys stored on chain with that
list.

Midnight contracts can carry a *maintenance authority* able to replace their verifier keys.
Tenders created by Waxseal software from 25 September 2026 renounce it immediately after
creation: the authority is replaced by one with no keys, which the ledger will never allow
to sign anything. The renunciation is itself a transaction on the record. Test tenders
created earlier were renounced on 25 September 2026, and their records show when. The
verifier reports any tender that is still changeable, and whether a change ever happened.

### 1.2 Each bid was sealed before the deadline, and not changed

A bid is recorded as `commitment = SHA-256(tag ‖ bid ‖ salt ‖ bidder id)` (specified byte
for byte in `docs/COMMITMENT_FORMAT.md`). The contract accepts at most one commitment per
bidder id and refuses commitments once the deadline has passed by its own clock. Each
commitment appears in a specific transaction in a specific block, with the block's time.

Producing a different bid that matches an existing commitment requires finding a SHA-256
collision, which is not considered feasible. So the commitment fixes the bid at the time
of the block, without disclosing it. Shortly after each transaction the tender's state,
including every commitment, is also time-stamped by public time-stamping authorities
(section 5), so the time does not rest on the network's clocks alone.

### 1.3 The result follows from the bids and the rules

*Clock mode.* After the deadline a public price moves one step per round. A bidder can
claim only in the first round whose price reaches their sealed bid, proving this in zero
knowledge against their own commitment; the first valid claim settles the tender at that
round's price. The record shows the round, the time of the claim, and that the winner holds
one of the commitments. The published price is the clock price, within one step of the
winning bid.

*Committee mode.* A named committee can decrypt the bids (each is encrypted to the
committee's key, with a proof that the ciphertext holds the same values as the
commitment). The committee then submits one proof that consumes every commitment on the
ledger in order and shows that the named winner's bid is the best. It cannot leave a bid
out or substitute one.

In both modes losing bids stay sealed on the ledger.

### 1.4 Deposits followed the rules

Where a deposit is required, each bid locks a shielded deposit in the contract. Losers
recover theirs; the winner's becomes a performance bond; the organiser can collect only what
the rules allow. The record shows each lock, refund and collection, and the verifier checks
that they add up.

### 1.5 A bidder can prove what they bid

The bidder's device holds the bid and the random value. The bidder can give a *receipt*
(tender, bidder id, commitment, block — no bid) to anyone, and, if they choose, an *opening*
(the same plus the bid and random value) to a specific person, who recomputes the
commitment and compares. Only the bidder can create an opening. Waxseal cannot, because it
never holds the values.

## 2. How a record is checked

Everything below uses public data and open procedures. No account is needed, and nothing
depends on Waxseal continuing to exist.

- **Public ledger.** The contract's state and full history are read from any Midnight
  indexer; Midnight runs a public one per network. The verifier believes the indexer it
  reads; for a dispute, read from your own node and indexer, or compare two.
- **The verifier** (`/verify` on the website, and `packages/sdk/scripts/verify-tender.ts`)
  reads the history straight from the indexer and checks: the verifier keys against the
  published releases; that the maintenance authority is renounced; that the keys never
  changed; that no commitment was replaced; that every commitment precedes the deadline;
  that the count is consistent; that the result follows the rules; that deposits add up;
  and, if given the description, that it matches the hash. It produces a report with a
  SHA-256 digest; two parties running it against the same block get the same findings.
- **Independent time stamps.** The verifier also checks every RFC 3161 time stamp supplied
  with the tender: the authority's signature, its certificate chain to a pinned root, and
  that the time-stamped statement is exactly the chain's state after the stated transaction.
  It then reports, for each sealed bid, the earliest independent time that covers it. Each
  time stamp can also be checked with OpenSSL alone.
- **Independent recomputation.** `conformance/waxseal_verify.py` is a second implementation
  of the commitment format using only the Python standard library, written from the
  specification. It recomputes commitments from an opening and hashes of descriptions. The
  compiled contracts, the TypeScript SDK and the Python program are checked against the same
  published test vectors (`conformance/vectors.json`); a deliberately wrong implementation
  is included to show that the vectors catch errors.

A useful practice for a dispute: record the report digest and the block height it was
produced at, and keep the tender description file and any documents whose hashes it lists.

## 3. What a record does not prove

Stated at length, because a record that is trusted for more than it shows is worse than no
record.

- **Who a bidder is.** A bidder id is a per-tender pseudonym derived from a secret on the
  bidder's device. The record does not name anyone. Linking a bidder id to a person or
  company needs the bidder's cooperation (an opening from their device) or the organiser's
  own off-chain procedure.
- **That a bidder can deliver.** The record concerns prices, timing and the rules. It says
  nothing about capacity, quality, eligibility beyond an optional allow list, or conflicts
  of interest.
- **That the clock found the best bid in every case.** The clock result is within one price
  step of the best committed bid only if the best bidder claims in their round. A better
  bidder who stays silent loses their deposit, which makes silence costly; with no deposit
  there is no such incentive, and the result is only as good as the bidders' conduct. The
  verifier reports the deposit setting.
- **That a committee kept bids confidential.** In committee mode the committee can read
  every bid as it arrives and could leak it before the deadline. It cannot change the result
  or omit a bid. Splitting the committee key between several members reduces the risk of a
  single insider; the key is reassembled on one machine to decrypt.
- **An exact time.** Block times are set by the network's block producers. They order events
  and are close to real time, but a Midnight block time is not a qualified electronic
  timestamp in the sense of EU law. The independent time stamps of section 5 come from
  public, non-qualified authorities: they show that a state existed *no later than* the time
  signed, typically within a minute or so of the transaction, not the exact moment it
  happened. A bid sealed in the last minute before the deadline may therefore carry an
  independent time just after it; its block time and the contract's own deadline check
  remain the evidence for that bid.
- **That the description is true.** The hash proves the description was not edited after
  creation; it does not prove its content accurate. Documents are referenced by their hash;
  the parties must keep the files themselves.
- **Unlinkability of every transaction.** Deposits are shielded, but a party who already
  knows a bidder's shielded address can test the refund transaction against it and confirm
  that the bidder took part (not what they bid); and fees on Midnight are paid from a
  resource tied to the payer's registered NIGHT, whose linkability is an open question.
  Both are stated in `docs/THREAT_MODEL.md`, invariant I4.
- **Audited software.** As of this version the contracts have been reviewed by their authors
  but not by an independent auditor, and run on a test network only. Deployment to the
  production network is locked in the software until an audit is complete.
- **That a tender satisfies procurement law.** Whether a smart-contract procedure is an
  acceptable procurement procedure depends on the jurisdiction and the kind of buyer. Public
  procurement is generally bound to prescribed systems; Waxseal is intended for private-sector
  procurement and auctions until a legal partner has reviewed a public-sector use.

## 4. Authentication: orientation by jurisdiction

Pointers only, to be confirmed by counsel in the jurisdiction concerned.

- **European Union.** Under the eIDAS Regulation (EU) No 910/2014, an electronic time stamp
  may not be denied legal effect solely because it is electronic (Art. 41(1)); the
  presumption of accuracy of date and time attaches only to *qualified* time stamps
  (Art. 41(2)). The 2024 amendment (Regulation (EU) 2024/1183) adds electronic ledgers as a
  trust service with presumptions for *qualified* ledgers. Midnight is not a qualified trust
  service, so a Waxseal record is ordinary electronic evidence, assessed on its merits.
- **Italy.** Art. 8-ter of Decree-Law 135/2018 (converted by Law 12/2019) gives the storage of
  an electronic document on a distributed ledger the effect of an electronic time stamp under
  eIDAS Art. 41, subject to technical standards issued by AgID.
- **United States.** Authentication may rely on evidence describing a process or system that
  produces an accurate result (Fed. R. Evid. 901(b)(9)), or on a certification by a qualified
  person for records generated by an electronic process and for data identified by a process
  of digital identification such as hash values (Fed. R. Evid. 902(13) and (14)). Vermont
  provides specifically for blockchain records (12 V.S.A. § 1913).
- **China.** Since 2018 the Supreme People's Court's provisions on internet courts allow
  electronic data fixed by blockchain, trusted time stamps or hash verification to be
  confirmed where its authenticity can be shown (Art. 11).
- **Vietnam.** The Law on Electronic Transactions 2023 (No. 20/2023/QH15) recognises data
  messages as evidence, weighed on the reliability of how they were created, stored and kept
  intact. Public procurement is governed by the Law on Bidding 2023 (No. 22/2023/QH15) and
  conducted on the national e-procurement system; Waxseal is not a substitute for it.

## 5. Independent time stamps

A record carries more than one anchor. Besides the ledger, each tender's public state is
time-stamped under RFC 3161, the Internet standard for trusted time stamps, by two
independent public authorities: DigiCert and Sectigo. They are free services, and each time
stamp is a small signed file.

- **What is stamped.** A statement of the tender's state after a transaction: the contract,
  the network, the block and its hash, the transaction, the deadline, the phase, every sealed
  commitment and any result (format in `docs/COMMITMENT_FORMAT.md`, section 8). Only its
  SHA-256 digest is sent to the authority. Statements contain public ledger data only.
- **What it proves.** That this state, and that block, existed no later than the signed
  time. Because anyone can rebuild the statement from the chain, the time stamp ties the
  ledger's history to a clock outside the network. A later claim that the history was
  different would contradict a signed statement from a third party.
- **Who requests them.** The Waxseal service requests them shortly after each transaction
  and publishes them with the tender. It cannot forge or backdate one; it could only fail to
  request one, and anyone can request their own for any tender with
  `packages/sdk/scripts/anchor-tender.ts`, with no account.
- **How to check one.** In the browser on the verification page, with the repository's
  verifier, with the Python program (`anchor`), or with OpenSSL alone:
  `openssl ts -verify -data statement.json -in response.tsr -CAfile tsa-roots.pem`.
- **Legal weight.** In the EU these are *electronic* time stamps: they may not be denied
  legal effect solely for being electronic (eIDAS Art. 41(1)), but they do not carry the
  presumption of accurate time that only *qualified* time stamps do (Art. 41(2)). Where that
  presumption matters, the same statements can be stamped by a qualified trust service
  provider as well; that is a paid service and has not been set up.
- **Limits.** The Waxseal verifier checks certificate validity at the signed time but not
  revocation; OpenSSL can be asked to (`-crl_check` with the authority's CRL). Both
  authorities state their accuracy as unspecified in the tokens.

## 6. Reproducing a verification

```
# from a checkout of the repository
cd packages/sdk
npx tsx scripts/verify-tender.ts <tender address> --network preprod --api https://waxseal.xyz/api --json report.json

# recompute a commitment from an opening a bidder gave you, with no dependencies
python3 conformance/waxseal_verify.py opening --file waxseal-opening.json

# check the independent implementation against the published vectors
python3 conformance/waxseal_verify.py selftest

# time-stamp a tender yourself, then check those time stamps along with the chain
cd packages/sdk
npx tsx scripts/anchor-tender.ts <tender address> --network preprod --out anchors
npx tsx scripts/verify-tender.ts <tender address> --network preprod --anchors anchors

# check one time stamp without any Waxseal code
openssl ts -verify -data statement.json -in response.tsr -CAfile tsa-roots.pem
python3 conformance/waxseal_verify.py anchor --statement statement.json --tsr response.tsr
```

The specification, vectors, Python program and release list are also served at
`https://waxseal.xyz/conformance`.
