Crunch: Embedding Validation Directly into Message Protocols for Safer Systems
Share this article
In the world of distributed systems and embedded devices, message protocols like protobuf and MAVLink have long been staples for serializing data. Yet, a persistent flaw undermines their reliability: validation is often an afterthought, decoupled from message definitions. This gap can lead to vulnerabilities where invalid data slips through, causing system failures or security breaches. Enter Crunch, a new open-source protocol that embeds validation directly into its DNA, making it impossible to overlook semantic correctness while offering unprecedented flexibility in serialization.
The Validation Gap in Existing Protocols
Most message frameworks treat validation as a secondary concern. For instance, protobuf relies on extensions like protovalidate for semantic checks, which introduces runtime parsing of Google CEL and heavy dependencies—making it unsuitable for embedded systems without dynamic memory allocation. Alternatives like nanopb or MAVLink offer partial solutions but lack built-in semantic validation or protocol flexibility. Crunch's creator highlights this shortfall:
"Validation—both of individual fields and of whole messages—is completely decoupled from the message definitions. This is a fundamental gap in what makes a message valid."
A comparison underscores Crunch's advantages:
| Framework | Static Memory Allocation | Built-In Integrity | Flexible Serialization | Semantic Validation |
|---|---|---|---|---|
| Crunch | ✔ | ✔ | ✔ | ✔ |
| Protobuf | ✘ | ✘ | ✘ | With protovalidate |
| MAVLink | ✔ | ✔ | ✘ | ✘ |
| FlatBuffers | ✔ | ✘ | ✘ | ✘ |
Crunch flips the script by making validation opt-out rather than opt-in. Every field definition includes validity criteria, such as range checks or required flags, enforced at compile time where possible. This ensures messages are inherently correct, reducing runtime errors.
Core Design Principles
Crunch is built on three pillars:
1. Validation First: Fields specify validators (e.g., validators::positive for integers) during definition. Messages include cross-field validators as constexpr functions.
2. Zero Dynamic Allocation: Ideal for embedded systems, it avoids heap usage entirely.
3. Swappable Serialization: Developers choose between protocols—e.g., a size-optimized Tag-Length-Value (TLV) format or a speed-optimized static layout—without altering message definitions.
Here’s a sample message definition in C++:
#include <crunch>
struct BarMessage {
using Crunch::types;
using Crunch::validators;
types::VInt8<0, validators::positive> barint;
types::VArray<1, 3, VInt8<validators::positive>> bararray;
};
struct FooMessage {
types::VInt32<0, validators::positive> field1;
types::VMsg<2, BarMessage, validators::required> field3;
static constexpr auto validate(const FooMessage& m) -> std::expected<void, ValidationError> {
if (m.field1.get() > m.field3.get().barint.get()) return {};
return std::unexpected({"field1 must be > barint"});
}
};
Key features include:
- Field Types: Supports integers, floats, strings, enums, arrays, maps, and nested messages, all with compile-time sizing.
- Accessors: Values are set via methods like set() or add(), which trigger immediate validation. Access assumes prior validation.
- Integrity Checks: Built-in CRC16 or custom algorithms ensure data integrity during serialization.
Development Roadmap and Implications
Crunch's rollout is methodical:
1. Basic Functionality: Implement core C++ APIs (Serialize, Deserialize, Validate) with one serialization protocol and embedded device testing.
2. Robust Infrastructure: Add fuzz testing, CI metrics, and cross-platform validation.
3. Language Interoperability: Generate bindings for C and Rust, leveraging C++26 reflection for future expansions.
4. Domain-Specific Language (DSL): Potentially abstract definitions into a .crunch format once the C++ API stabilizes.
For developers in aerospace, IoT, or automotive sectors, Crunch offers a compelling alternative where safety and performance are non-negotiable. Unlike one-size-fits-all solutions, it sacrifices broad compatibility for deep reliability in critical systems. As the project evolves, it could reshape how validation is handled in low-level communications, turning a persistent weakness into a foundational strength.
Source: Volatile Int