Skip to content

[2.8.0] XEdDSA packet signing UI #35

Description

@jamesarich

Implement the XEdDSA packet-signing UI for Standalone UI (MUI), per the cross-platform spec in meshtastic/design#113 — that issue is the source of truth, read it first.

Summary

Surface when a node and its broadcast packets are cryptographically signed and verified (XEdDSA over the node's identity key). This is read-only — the radio does all crypto and drops invalid/stripped signatures before the client sees them, so there is no error state to render. Clients only ever affirm the good state.

Two distinct marks, kept separate:

  • 🛡️ shield-with-check = authentic (a verified, signed broadcast) — the UI's nearest shield-with-check asset
  • 🔒 lock = private (a PKI-encrypted DM) — keep the existing lock, unchanged

Flags from the radio (read-only — no client-side crypto)

Field Meaning
MeshPacket.xeddsa_signed (22) this received packet's signature is verified — primary signal
NodeInfo.has_xeddsa_signed (14) this node signs its packets (≥1 verified)

Data.xeddsa_signature (10) is not needed for v1.

What to build

  • Messaging — broadcast bubbles: a green 🛡️ on xeddsa_signed bubbles; reveal "Signed · verified" on tap. Per-message. Never on DMs — firmware never sets the flag on DMs, so gating on the boolean alone is sufficient (it can't false-positive on a DM).
  • Node details — "Signed node": a green, prominent 🛡️ row driven by has_xeddsa_signed, in the existing security section, ordered most-trusted-first (manual-verified → signed → has-key → no-key). Label it as automatic trust (e.g. "Verified automatically"), distinct from user-asserted manual key verification. Phrase as observed ("signs its packets"), not "signing enabled".
  • Node list (rows): show the same 🛡️ in each node row's security cluster, beside the key/lock status icon — visible at a glance without opening details. Apply to all list densities (compact + full).
  • Message detail/info: affirmative plain-language state, e.g. "Signed & verified — verified with their key." Neutral (never accusatory) copy for unsigned.

v1 decisions (settled in #113)

  • Two affordances (shield + lock), not merged into one "security" concept.
  • Node: two distinct cells (manual key-verify + signature-verify), laid out per platform (Android pairs them in one row), not conflated.
  • Per-data-field signed badges → deferred. Unsigned → strictly silent. Compose-time "will be signed" hint → out. "Signed but unverifiable" state → dropped (use the verified bool only).

Don'ts

  • Don't reuse the lock icon for signing.
  • Don't use red / error styling anywhere — nothing here is an error.
  • Don't flag unsigned DMs / large / legacy traffic as insecure.

Reference

Android implementation: meshtastic/Meshtastic-Android#5976 (+ #5980 for making the shield green & prominent). Reference screenshots live in the parent spec.

Parent: meshtastic/design#113

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions