You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
proof(SafeCSRF): annotate 6 bodyless decls as OWED (Refs standards#158) (#53)
## Summary
Annotates the 6 bodyless declarations in
`src/Proven/SafeCSRF/Proofs.idr`
as **OWED-with-justification**, per the convention set 2026-05-20 by
sibling PRs #37 (SafeAPIKey), #38 (SafeCORS), #39 (SafeCSV), #40
(SafeSemVer), #41 (SafeHtml), and the SafeChecksum/SafeArgs in-repo
reference files. Refs hyperpolymath/standards#158.
## Form (matches the convention)
- Triple-pipe `||| OWED:` doc-block stating **claim + Idris2 0.8.0
blocker + concrete discharge path** for each declaration
- Leading `0 ` (erased-multiplicity, runtime-stripped)
- `public export` visibility upgraded from `export` to match the
SafeChecksum/SafeCSV reference dominant form
- Original type signature unchanged otherwise
- **No** `postulate` keyword, **no** `believe_me`, **no** `idris_crash`
## Decls + claims + reasons
1. **`constantTimeEqRefl`** — `constantTimeEqual s s = True`
Blocker: `String.unpack` FFI opacity + missing `prim__eq_Char x x =
True`
reflective lemma + `andTrueNeutral` not exposed as Refl identity in
Idris2 0.8.0 stdlib. Same family as SafeChecksum Luhn/ISBN + gossamer
`stringNotEqCommut` class-J axiom.
Discharge: `Data.String` reflective tactic + `Data.Bool`
`andTrueNeutral` + `prim__eq_Char` reflective lemma; alternatively
refactor `constantTimeEqual` to `Vect n Char`.
2. **`constantTimeEqSym`** — `constantTimeEqual a b = constantTimeEqual
b a`
Blocker: `prim__eq_Char` commutativity not exposed as Refl-reducible —
symmetric to `Boj.SafetyLemmas.charEqSym` class-J axiom already shipped
in boj-server; upstream `/=` length guard also FFI-opaque.
Discharge: `Data.Char` reflective `eqCharSym` lemma.
3. **`differentLengthUnequal`** — `Not (length a = length b) ->
constantTimeEqual a b = False`
Blocker: Bool-Prop reflection gap — hypothesis is propositional
`Not (length a = length b)` over `String.length`, but the comparison
branches on Boolean `(length as /= length bs)` over `List Char` (after
`unpack`). Same family as `SafeArgs.boolParsingComplete`.
Discharge: `Data.String` `lengthUnpackEq` + `Data.Nat` `decEqToNeq` Bool
reflection, or refactor to `LengthEq`-tagged input.
4. **`tokenValidatesSelf`** — `validateToken tok (tokenString tok) =
True`
Blocker: same as `constantTimeEqRefl` (chain `constantTimeEqRefl →
tokenValidatesSelf`).
Discharge: one-line `constantTimeEqRefl (tokenString tok)` once parent
discharges.
5. **`identicalDoubleSubmitValid`** —
`validateDoubleSubmit (MkDoubleSubmit val val) = True`
Blocker: same `constantTimeEqRefl` chain.
Discharge: one-line `constantTimeEqRefl val` once parent discharges.
6. **`fullValidationRequiresToken`** —
`validateToken tok submitted = False ->
fullValidation tok submitted origins origin = False`
Blocker: `validateToken`'s definitional opacity through the
`tokenString` record-field accessor. The sibling `wrongSessionFails`
(already proved by `rewrite prf in Refl` in this file) closes the
symmetric pattern only because its hypothesis is stated directly over
`constantTimeEqual`; here `prf` is wrapped through `validateToken` and
the wrapper does not reduce.
Discharge: refactor `validateToken` to take `String` directly (skipping
the `CSRFToken`-record indirection), at which point
`rewrite prf in Refl` closes it — cf. `wrongSessionFails`.
## Scope
- Touches only `src/Proven/SafeCSRF/Proofs.idr`
- The two `Refl`-discharged proofs (`mkTokenRejectsEmpty`,
`hexTokenEmpty`) and the one `rewrite`-discharged proof
(`wrongSessionFails`) are untouched
- No bindings, no FFI, no source `.idr` outside `Proofs.idr`
## Why draft
Mirrors the sibling-PR cadence: draft → CI gate → human review +
non-`--admin` merge. Local `idris2 --build proven.ipkg` is not green on
my machine because the installed `base` package has no compatible TTC
binaries (`Found version 0.8.0 of package base installed with no
compatible binaries for the current Idris2 compiler`) — same toolchain
state as on the sibling SafeCSV/SafeSemVer/SafeHtml PRs. CI is the
oracle.
Refs hyperpolymath/standards#158
0 commit comments