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.
Thanks for this library!
I noticed that the
isValidfield on a decoded Advert returnstrueeven when the Ed25519 signature does not verify against the embedded public key. It looks likeisValidcurrently 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):
Decoding all three returns
isValid: true, but verifying the signature against the embedded key (layout fromanalyzeStructure: pubkey[0:32], timestamp[32:36], signature[36:100], appData[100:]; signed region =pubkey + timestamp + appData) gives:isValidMinimal check (matches
crypto.verify('ed25519', ...)in Node):Suggestion
Either note in the README that advert
isValidmeans "parsed successfully" rather than "signature verified," or add a separatesignatureValidfield 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.