DECISION: signature scheme questions blocking 1.0 #82

Open
opened 2026-08-09 03:44:20 +02:00 by clawbot · 0 comments
Collaborator

Owner decisions required. Four signature questions from the README 1.0
roadmap, with empty answer slots. Like the format questions, these freeze at
1.0 — a signature scheme cannot be changed without breaking every already
signed manifest.


7. Does the outer SHA-256 cover compressed or uncompressed data? The
code currently hashes the compressed bytes, which is good — it lets a
verifier check integrity before spending resources decompressing, which
matters given the decompression bomb surface. But this is not documented
anywhere.

Recommendation: keep hashing compressed data, and document it
explicitly. This is not really a decision so much as an undocumented
invariant that needs writing down before someone "fixes" it.

8. Should signatureString() sign raw bytes instead of a hex string?
The canonical string is currently MAGIC-UUID-MULTIHASH with hex encoding.
Signing the raw sha256 bytes, or the compressed innerMessage directly,
removes a transformation layer.

Recommendation: this is the one I would change. Every encoding layer
between the data and the signature is a place where two implementations
can disagree — and there is a second implementation planned in JavaScript.
A canonical string with hex encoding and delimiters has more ways to be
subtly wrong (case, delimiter, field order) than signing raw bytes does.
If the string form is kept for human debuggability, the spec must nail
down hex case and delimiter exactly.

9. Support detached .mf.sig files? Embedded signatures are better for
single-file distribution. Detached files follow the familiar
SHASUMS/SHASUMS.asc pattern the README explicitly sets out to replace.

Recommendation: embedded only for 1.0. The README's stated goal is to
replace the detached-sidecar pattern; supporting both doubles the
verification surface and the test matrix to re-introduce the thing being
replaced. Detached support can be added post-1.0 additively if demand
appears.

10. GPG subprocess or pure-Go crypto? Shelling out to gpg is fragile:
it may not be installed, output is version-dependent, and it currently hangs
without a deadline (#62). Alternatives are github.com/ProtonMail/go-crypto
for pure-Go OpenPGP, or Ed25519/signify for something much simpler.

Recommendation: this is the highest-stakes question in the milestone and
deserves a real decision rather than a default. Shipping 1.0 with a hard
runtime dependency on an external gpg binary means the library does not
work in a FROM scratch container — which is what this repo's own
Dockerfile produces. Pure-Go OpenPGP keeps compatibility with existing PGP
keys and the ?key=FINGERPRINT URL idea in the README; Ed25519/signify is
dramatically simpler but abandons the PGP web of trust. I lean pure-Go
OpenPGP for compatibility, but if the web of trust is not actually valued
here, signify is a much smaller thing to own.


Definition of done

  • Each question answered inline in a comment here.
  • Question 10's answer becomes its own implementation issue if it is
    anything other than "keep the subprocess" — it is a large change.
  • The final scheme is fully documented in docs/FORMAT.md: what is signed,
    in what encoding, how a verifier reconstructs it, and how the public key
    is embedded and located. The current documentation is insufficient for
    anyone to write a second interoperable implementation, which is the
    project's stated goal.

Please answer and reassign to clawbot.

Owner decisions required. Four signature questions from the README 1.0 roadmap, with empty answer slots. Like the format questions, these freeze at 1.0 — a signature scheme cannot be changed without breaking every already signed manifest. --- **7. Does the outer SHA-256 cover compressed or uncompressed data?** The code currently hashes the compressed bytes, which is good — it lets a verifier check integrity before spending resources decompressing, which matters given the decompression bomb surface. But this is not documented anywhere. > _Recommendation:_ keep hashing compressed data, and document it > explicitly. This is not really a decision so much as an undocumented > invariant that needs writing down before someone "fixes" it. **8. Should `signatureString()` sign raw bytes instead of a hex string?** The canonical string is currently `MAGIC-UUID-MULTIHASH` with hex encoding. Signing the raw sha256 bytes, or the compressed `innerMessage` directly, removes a transformation layer. > _Recommendation:_ this is the one I would change. Every encoding layer > between the data and the signature is a place where two implementations > can disagree — and there is a second implementation planned in JavaScript. > A canonical string with hex encoding and delimiters has more ways to be > subtly wrong (case, delimiter, field order) than signing raw bytes does. > If the string form is kept for human debuggability, the spec must nail > down hex case and delimiter exactly. **9. Support detached `.mf.sig` files?** Embedded signatures are better for single-file distribution. Detached files follow the familiar `SHASUMS`/`SHASUMS.asc` pattern the README explicitly sets out to replace. > _Recommendation:_ embedded only for 1.0. The README's stated goal is to > replace the detached-sidecar pattern; supporting both doubles the > verification surface and the test matrix to re-introduce the thing being > replaced. Detached support can be added post-1.0 additively if demand > appears. **10. GPG subprocess or pure-Go crypto?** Shelling out to `gpg` is fragile: it may not be installed, output is version-dependent, and it currently hangs without a deadline (#62). Alternatives are `github.com/ProtonMail/go-crypto` for pure-Go OpenPGP, or Ed25519/signify for something much simpler. > _Recommendation:_ this is the highest-stakes question in the milestone and > deserves a real decision rather than a default. Shipping 1.0 with a hard > runtime dependency on an external `gpg` binary means the library does not > work in a `FROM scratch` container — which is what this repo's own > Dockerfile produces. Pure-Go OpenPGP keeps compatibility with existing PGP > keys and the `?key=FINGERPRINT` URL idea in the README; Ed25519/signify is > dramatically simpler but abandons the PGP web of trust. I lean pure-Go > OpenPGP for compatibility, but if the web of trust is not actually valued > here, signify is a much smaller thing to own. --- ## Definition of done - Each question answered inline in a comment here. - Question 10's answer becomes its own implementation issue if it is anything other than "keep the subprocess" — it is a large change. - The final scheme is fully documented in `docs/FORMAT.md`: what is signed, in what encoding, how a verifier reconstructs it, and how the public key is embedded and located. The current documentation is insufficient for anyone to write a second interoperable implementation, which is the project's stated goal. Please answer and reassign to `clawbot`.
clawbot added this to the 1.0.0 milestone 2026-08-09 03:44:20 +02:00
sneak was assigned by clawbot 2026-08-09 03:44:20 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/mfer#82