Skip to content

Advert isValid returns true for packets whose Ed25519 signature does not verify #14

Description

@khagele

Thanks for this library!

I noticed that the isValid field on a decoded Advert returns true even when the Ed25519 signature does not verify against the embedded public key. It looks like isValid currently reflects structural/parse validity rather than signature validity, which makes sense, I just wasn't sure whether signature verification was intended to be part of it.

Repro

Three real adverts seen on the Dutch mesh. Full packet hex (route type 2, payload type 4, decodes cleanly via the CLI):

# 95e3908d  genuine advert, signature VALID
1200CCCC2F1EFE5EE0D1A8FAD40DAC12E4E0F25A37D7B58B72D63A7B0A09BF6F6EF5D208426A46EECC75F4E8DDFE42BC617376559F8BF66B7C35165B2DB6DB4E65D4B3C1D4CD79337B4E29D11B490588CADDB537955F81CBC933D83E1C21558881FDF4F4200292109C19033C1C4D0055747265636874204765726272616E6479746F72656E

# e5bbd3c4  corrupted, signature INVALID, timestamp 1995
1200CCCC2F1EFE5EE0D1A8FAD40DAC12E4E0F25A37D7B58B72763A7B1A48EACBCEFFF2F3112F5F23904CCD84E5282192FC08A6CF090BE84F1C0DBC5BF03F484E1220CB1C702D1EC0A5E890DA14548C25DA4AC12E5559351CB7693F1D622BA72EED8975CC060E92109C19033C1C4D0055747265636874204765726272616E6479746F72656E

# 0b342b52  corrupted, signature INVALID, timestamp 1998
1200AE645D639540732658E71010D2858D997D25D263DEC7B34AE3A27D55188AFC8710EC6136A8E228D0AD921B06D74E8AD8B5C2E0784B3BEDD2924BFC258BED17D0389A851404822E81F0EB9FF0DE71BEEB1F1527F0583FC759036FC80D85B824FA8B4032059209841303EB4C49004E4C2D4252442052502061653634

Decoding all three returns isValid: true, but verifying the signature against the embedded key (layout from analyzeStructure: pubkey [0:32], timestamp [32:36], signature [36:100], appData [100:]; signed region = pubkey + timestamp + appData) gives:

Packet decoder isValid Ed25519 verify timestamp
95e3908d true VALID 1782712530 (2026)
e5bbd3c4 true INVALID 789705714 (1995)
0b342b52 true INVALID 912387088 (1998)

Minimal check (matches crypto.verify('ed25519', ...) in Node):

from nacl.signing import VerifyKey
b = bytes.fromhex(payload_raw)
pub, ts, sig, app = b[0:32], b[32:36], b[36:100], b[100:]
VerifyKey(pub).verify(pub + ts + app, sig)  # raises for e5bbd3c4 and 0b342b52

Suggestion

Either note in the README that advert isValid means "parsed successfully" rather than "signature verified," or add a separate signatureValid field that runs an Ed25519 verification of the signed region against the embedded key. The orlp WASM is already in place for key derivation, so the verify path should be straightforward.

Happy to open a PR if that'd help.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions