I could not find published numbers for what post-quantum signature verification costs on small targets, so I measured it. Four crates, LMS/HSS verification plus measurement harnesses.
Three Rust-specific things came out of it.
First one. sha2 0.10 SHA-256 compiles to 3808 bytes on Cortex-M4F. sha2 0.11 compiles to 8776. Same algorithm, same target, same flags. Both versions end up linked in my workspace because different dependencies require different ones.
This means comparing whole verifier binaries mostly compares hash crates, not signature schemes. Ed25519 binary is around 64% unrolled SHA-512. So now every scheme is subtracted from baseline built with same hash it uses.
Second one. Adding second call site to small helper made LLVM stop inlining it at opt-level = "z". Reasonable decision. But forcing #\[inline(always)\] saves 408 bytes on Cortex-M0+ and costs 48 bytes on M4F and RISC-V. Different direction on different targets, so I keep the attribute because 16 KB boot ROM cares and 64 KB one does not.
Third one. Static stack analysis from -Z emit-stack-sizes plus call graph from disassembly does not give upper bound. On one binary 55 call sites cannot be resolved: indirect calls, tail calls compiled as branches, linker thunks. Every missing edge only makes answer smaller. Tool said 720 bytes, hardware said 1152.
Crates are no_std and allocation-free. Hash is behind trait, so software sha2 and ESP32 SHA peripheral both work. That trait design changed twice, and [DECISIONS.md](http://DECISIONS.md) has why.
Not audited. lms-verify passes RFC 8554 Appendix F vectors, which is not same thing.
https://github.com/mnaza/pqc-embedded