Skip to content

Harden protocol identity, signatures, peer auth, and snapshots - #6

Merged
the-code-learner merged 88 commits into
mainfrom
chatgpt/protocol-hardening
Aug 18, 2026
Merged

Harden protocol identity, signatures, peer auth, and snapshots#6
the-code-learner merged 88 commits into
mainfrom
chatgpt/protocol-hardening

Conversation

@the-code-learner

@the-code-learner the-code-learner commented Aug 18, 2026

Copy link
Copy Markdown
Owner

Scope

Implements the protocol hardening approved in issues #2, #3, #4, and #5 on top of the foundation hardening PR.

This is intentionally a clean protocol break. There is no active Zephyr devnet or deployed chain state that requires compatibility with the pre-hardening message formats.

#2 — chain identity and signing domains

  • add explicit configurable ZEPHYR_CHAIN_ID with local-development default zephyr-devnet-1
  • require chain ID on security-critical received messages; verifiers do not infer a missing network ID
  • add versioned domains for transactions, blocks, proposals, votes, transport identities, request proofs, state commitments, and snapshots
  • bind transactions/consensus/transport proofs to their chain and signing domain
  • expose chain ID through node status and make the browser wallet read the connected node chain before signing
  • reject cross-chain transaction and consensus replay
  • persist chain ID in state.json, initialize it on first store creation, reject a reused data directory under a different chain, and reject persisted blocks whose chain does not match the configured store

#3 — canonical P-256 and deterministic transaction identity

  • emit canonical low-S P-256 signatures from Go validator/node signers and the browser wallet
  • reject high-S signatures during verification
  • redefine transaction ID over canonical chain/domain/transaction/public-key identity rather than signature bytes
  • add malleability tests proving equivalent ECDSA representations cannot create different transaction IDs

#4 — replay-safe request-bound peer authentication

  • keep status identity as discovery/admission evidence only
  • sign every internal peer request over chain ID, method, canonical path/query, body SHA-256, node ID, validator address, nonce, and timestamp
  • verify the proof before internal operations and restore request bodies after hashing
  • persist a bounded owner-only replay database so used nonces remain rejected across restart
  • require signed proofs for all /v1/internal/* endpoints even through the embedded handler
  • apply the same 1 MiB body ceiling while hashing embedded/internal peer requests, preventing the auth verifier from bypassing the process-facing request limit
  • add adversarial tests for exact replay, cross-path reuse, malformed proof, unbound validator policy, restart replay, and oversized internal bodies

#5 — committed state roots and quorum snapshot recovery

  • add chain ID and deterministic stateRoot to blocks and include both in the block hash
  • define a versioned chain-bound state commitment over committed accounts, active validator snapshot, and sorted applied-funding request IDs
  • preserve faucet/funding idempotency across recovery by committing and restoring AppliedFundingIDs; tampering those IDs invalidates the snapshot commitment
  • deterministically execute proposal transactions locally and reject a proposal before voting when its state root differs from local execution
  • validate block chain continuity, chain-bound transactions, transaction IDs, validator arithmetic, funding-idempotency metadata, and latest state commitment before snapshot consideration
  • sign snapshot proofs over chain, height, block hash, state commitment, and validator-set version
  • use the locally trusted validator set as the recovery trust anchor and require distinct matching proofs reaching the normal 2/3+ voting-power quorum
  • disable unsigned/single-peer snapshot replacement paths
  • sanitize volatile remote state during recovery rather than importing mempool, pending rounds/votes/proposals, or remote diagnostics
  • add tests proving 60% alone cannot restore, 100% matching proofs can, tampered account/funding state invalidates the snapshot, and a recovered funding request ID cannot be replayed

Additional hardening

  • make internal request authentication consistent across direct/internal HTTP handler use
  • keep consensus round timers local while preserving signed protocol metadata
  • update docs/protocol-security.md as the normative security model for the clean-break protocol, including persisted chain identity and funding-id commitment semantics

Verification

Permanent CI run #140 passes on final head 893d11c5df8a44450a4a9c56cb812dd643439619:

  • changed-file gofmt check
  • go vet ./...
  • go test ./...
  • npm ci
  • npm audit --audit-level=high
  • wallet TypeScript/Vite build

A separate post-audit verifier also passed the full Go vet/test suite before the final cleanup commit. Temporary integration workflows, scripts, triggers, and diagnostics used during development were removed from the final diff. The PR remains stacked on chatgpt/hardening-foundation; neither this PR nor the foundation PR is merged into main automatically.

the-code-learner and others added 30 commits August 18, 2026 15:48
the-code-learner and others added 27 commits August 18, 2026 16:48
@the-code-learner
the-code-learner changed the base branch from chatgpt/hardening-foundation to main August 18, 2026 15:23
@the-code-learner
the-code-learner marked this pull request as ready for review August 18, 2026 15:24
@the-code-learner
the-code-learner merged commit 899a27d into main Aug 18, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant