Oregami
Repositories/oxedyne/daimond

oxedyne/daimond/verify/README.md

10.1 KiB, 1 run

created by r2519314175:1003, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1# Verifying Daimond
2
3Daimond's privacy claim is meant to be **checked, not trusted**. The client is
4open source, it rebuilds byte-for-byte from that source, and every shipped build
5is sealed in a public, tamper-evident log. So you can confirm three things
6yourself, with no need to take anyone's word:
7
81. **The source is public** — read it.
92. **The running site is that source** — build it and compare the hashes.
103. **That build was really published** — check it is a sealed entry in the log.
11
12This directory is the machinery for (2) and (3).
13
14The **machine hand** — the program outside the page that runs commands on your
15computer — is published too, and is sealed by a weaker check that is set out in
16full under [The machine hand](#the-machine-hand). Read that section before
17building and installing it. Nothing on this page claims the hand's binary is
18reproducible, because it is not.
19
20## Check the running site (the honest way)
21
22```sh
23git clone https://github.com/oxedyne-com/daimond
24cd daimond
25rustup target add wasm32-unknown-unknown
26bash dev/build-wasm.sh # rebuilds the wasm from source
27node verify/check.mjs --url https://daimond.oxedyne.com
28```
29
30Use `dev/build-wasm.sh`, not `wasm-pack` directly. Rust bakes the path of every
31source file into the binary, so a plain build stamps your own home directory
32into the wasm and the hashes then cannot match anyone else's. The script maps
33those paths to fixed stand-ins first, which is what makes your rebuild and the
34published build comparable at all. It is a two-line script -- read it.
35
36Green means: every file the site served hashes to what the manifest says, the
37manifest's bundle hash is the hash of its own file list, and that bundle is a
38sealed entry in an unbroken chain in `verify/transparency.jsonl`. Red names
39exactly what differs. The verifier trusts nothing the server says beyond the
40bytes it serves — the authority is the source you cloned and the log in this
41repo.
42
43Being in the chain proves a bundle was published at some point, not that it is
44the one meant to be live now — so a server could serve an older, still-sealed,
45still-green build (a roll-back). By default that is reported as a warning; add
46`--latest` to fail unless the served build is the chain's tip, or `--expect
47<bundlehash>` to fail unless it is exactly the build you name.
48
49You can also check a local build directly (`node verify/check.mjs --dir www`),
50and there is an in-browser check at `/verify.html` on the running site — handy,
51but weaker, because a tampered server could tamper with that page too. Its one
52load-bearing check is against the public log on GitHub, an origin the site does
53not control.
54
55## How a build is fingerprinted
56
57- **File hash** — SHA-256 of the file's bytes.
58- **Manifest** (`www/manifest.json`) — a file hash for every served file of
59 Daimond's own code (JS, CSS, HTML, and the `pkg/` wasm), plus one **bundle
60 hash** over them all. `vendor/` (the third-party Typst tooling) is excluded:
61 it is not built from Daimond's source and carries its own integrity story.
62- **Transparency log** (`verify/transparency.jsonl`) — an append-only chain, one
63 entry per release, each `entry` hash covering the entry before it. Rewriting
64 any past release breaks every entry after it, and the file's git history is
65 public, so the history is tamper-evident.
66
67`verify/lib.mjs` is the single definition of this algorithm; the browser's
68`www/js/verify.js` recomputes the identical fingerprint with Web Crypto, and
69`verify/verify.test.mjs` asserts the two agree.
70
71## The machine hand
72
73Daimond can run a real command on your computer — `cargo test`, a build, a
74script. A web page cannot start a program, so that capability lives in a small
75separate program, the **hand**, which your browser starts on the extension's
76behalf and which runs each command inside a kernel fence. It is the most
77dangerous thing Daimond does, and until 2026-08-02 it was the one component that
78was not published, so it was also the only one you could not check. It is
79published now: `hand/` in this repository.
80
81Check your copy is the one that was sealed:
82
83```sh
84node verify/check.mjs --hand
85```
86
87**What that proves.** Every file under `hand/` hashes to what `verify/hand.json`
88records, and that seal is committed to this repository, so its history is public
89in the same way the transparency log's is. The seal also names the toolchain
90(`rust-toolchain.toml`) and the exact command that turns the source into the
91binary. Together: *the source you are about to build is the source the maintainer
92sealed for this release, and this is how it is built.*
93
94**What it does not prove, and will not.**
95
96- **Nothing about a binary.** No hand binary is published, signed or hashed. You
97 build your own from the source you just checked, with `cargo build --release
98 --manifest-path hand/Cargo.toml`. If somebody hands you a `daimond-hand`
99 binary, nothing here says anything whatever about it.
100- **Not reproducible.** A Rust release binary is not byte-identical across
101 toolchain versions, and this project has not demonstrated that it is identical
102 even within one. The wasm bundle's reproducibility was *measured* — two builds,
103 two directories, two cargo homes, compared — and until it has been measured for
104 the hand there is no such claim to make. Building the same source twice on the
105 same machine and getting the same bytes would prove nothing anyway: that is the
106 one arrangement guaranteed to agree with itself.
107- **`hand.json` is not chained.** The transparency log chains its entries, so a
108 rewritten past release breaks every entry after it. `hand.json` has no such
109 chain: it is one file per release, and what protects it is this repository's
110 public history and nothing more. That is weaker, and it is stated rather than
111 blurred by putting a hash into the chained log where a reader would assume the
112 chain covered it.
113- **Not a security review.** That the source is genuine says nothing about
114 whether the fence in it holds. The hand's own `README.md` sets out what it does
115 and does not guarantee; read it before installing.
116
117The release check (`dev/repro-check.sh`) also **builds** the published hand from
118a fresh clone. That is not a reproducibility check — it is the check that the
119published source compiles at all for somebody who is not the author, which is
120exactly what a `path` dependency into the author's home directory silently broke
121for the wasm between 2026-07-21 and 2026-07-27. The hand's `Cargo.toml` pins
122fe2o3 by git revision for the same reason, and `dev/publish.mjs` refuses to carve
123a revision that has not been pushed.
124
125## Sealing a build (maintainers, at deploy time)
126
127Run after building the wasm and before the files leave for the server:
128
129```sh
130node dev/publish.mjs # carve the public mirror, hand/ included
131bash dev/build-wasm.sh # in the PUBLIC tree — see below
132node dev/stamp-build.mjs # www/build.json — the staleness id + a note
133node verify/hand.mjs # seal the carved hand → verify/hand.json
134node dev/publish.mjs # carry hand.json across (one file)
135node verify/manifest.mjs # www/manifest.json + a transparency-log entry
136# commit verify/transparency.jsonl, verify/hand.json and www/manifest.json,
137# then deploy www/
138```
139
140The carve runs twice, and that is not a slip. `verify/hand.mjs` seals **the
141public tree's** hand, because that is the one a stranger builds — this tree's
142`hand/Cargo.toml` depends on fe2o3 by path, into a working copy that exists on no
143machine but the author's, and sealing it would seal a manifest nobody outside can
144build. So the seal has to come after a carve, and its output has to be carried
145across by another. `verify/hand.mjs` also regenerates the mirror's
146`hand/Cargo.lock` against the mirror's own git pin, which is why that lock is one
147of the files the mirror owns.
148
149**Seal the build a stranger can reproduce, which is the one built in the public
150tree.** Development builds fe2o3 as a path dependency out of a neighbouring
151working copy; the public tree pins it by git revision. The two are different
152builds of the same source and they do not agree hash for hash, so a bundle
153sealed from a development build is one that nobody outside can ever match. Build
154the wasm in the public tree, copy `www/pkg/` from there, and seal that.
155
156`manifest.json` is a pure function of the bundle (no timestamps), so an
157identical build seals identically; redeploying an unchanged bundle does not add
158a duplicate log entry. Commit the log — it is the public record the whole claim
159rests on.
160
161## What this does and does not prove
162
163It proves the bytes a site served are a published, unmodified Daimond release,
164and (because the build is reproducible) that those bytes are the public source.
165It does **not** vouch for a remote server's internals: web fetch, mail and
166metered-credit inference genuinely transit the gateway, which is a matter of
167published policy and audit, not of this cryptographic check. "With your own key,
168your chats and files never leave in the clear, and you can watch only ciphertext
169leave" is the client-side claim this makes checkable.
170
171## What reproducibility here does and does not cover
172
173Verified, by building the same source twice in two different directories with
174two different cargo homes and comparing: **the output does not depend on where
175it is built, or by whom.** That is the property the claim needs, and until
1762026-07-27 it did not hold -- absolute build paths went into the wasm, so the
177hashes only ever matched for someone rebuilding on the machine that sealed them.
178Anyone else who checked would have seen a mismatch and had no way to tell it
179from a tampered server.
180
181Not covered: **different toolchain versions.** Byte-identical output is
182established only within one rustc and wasm-pack version, so build with the ones
183`rust-toolchain.toml` and the `README` pin before concluding that a mismatch
184means anything. Making the build stable across toolchain versions is a further
185step, and is not claimed.
186
187Also not covered: **the machine hand.** Everything in this section is about the
188wasm bundle the browser runs. The hand is a native binary and none of it applies
189to one — see [The machine hand](#the-machine-hand) for what is claimed there
190instead, which is less.