test: add MLS and MeshEnvelope size measurement tests

- measure_mls_wire_sizes: KeyPackage, Welcome, Commit, AppMessage sizes
- measure_mls_wire_sizes_hybrid: same with post-quantum mode
- measure_mesh_envelope_overhead: MeshEnvelope overhead for various payloads

These tests print actual byte sizes to inform constrained link
feasibility planning (LoRa SF12, MLS-Lite design).
This commit is contained in:
2026-03-30 23:45:07 +02:00
parent db49d83fda
commit 3f81837112
2 changed files with 151 additions and 0 deletions

View File

@@ -375,4 +375,63 @@ mod tests {
let result = MeshEnvelope::from_wire(&garbage);
assert!(result.is_err(), "garbage input must return Err, not panic");
}
/// Measure MeshEnvelope overhead for various payload sizes.
/// This informs constrained link feasibility planning.
#[test]
fn measure_mesh_envelope_overhead() {
let id = test_identity();
let recipient = [0xAAu8; 32];
println!("=== MeshEnvelope Wire Overhead (CBOR) ===");
// Empty payload
let env_empty = MeshEnvelope::new(&id, &recipient, vec![], 3600, 5);
let wire_empty = env_empty.to_wire();
println!("Payload 0B: wire {} bytes (overhead: {} bytes)", wire_empty.len(), wire_empty.len());
let base_overhead = wire_empty.len();
// 1-byte payload
let env_1 = MeshEnvelope::new(&id, &recipient, vec![0x42], 3600, 5);
let wire_1 = env_1.to_wire();
println!("Payload 1B: wire {} bytes (overhead: {} bytes)", wire_1.len(), wire_1.len() - 1);
// 10-byte payload ("hello mesh")
let env_10 = MeshEnvelope::new(&id, &recipient, b"hello mesh".to_vec(), 3600, 5);
let wire_10 = env_10.to_wire();
println!("Payload 10B: wire {} bytes (overhead: {} bytes)", wire_10.len(), wire_10.len() - 10);
// 50-byte payload
let env_50 = MeshEnvelope::new(&id, &recipient, vec![0x42; 50], 3600, 5);
let wire_50 = env_50.to_wire();
println!("Payload 50B: wire {} bytes (overhead: {} bytes)", wire_50.len(), wire_50.len() - 50);
// 100-byte payload (typical short message)
let env_100 = MeshEnvelope::new(&id, &recipient, vec![0x42; 100], 3600, 5);
let wire_100 = env_100.to_wire();
println!("Payload 100B: wire {} bytes (overhead: {} bytes)", wire_100.len(), wire_100.len() - 100);
// Broadcast (empty recipient) - saves 32 bytes
let env_bc = MeshEnvelope::new(&id, &[], b"broadcast".to_vec(), 3600, 5);
let wire_bc = env_bc.to_wire();
println!("Broadcast 9B: wire {} bytes (no recipient)", wire_bc.len());
println!("\n=== LoRa Feasibility (SF12/BW125, MTU=51 bytes) ===");
println!("Empty envelope: {} fragments", (wire_empty.len() + 50) / 51);
println!("10B payload: {} fragments", (wire_10.len() + 50) / 51);
println!("100B payload: {} fragments", (wire_100.len() + 50) / 51);
// Baseline overhead is fixed fields:
// - id: 32 bytes
// - sender_key: 32 bytes
// - recipient_key: 32 bytes (or 0 for broadcast)
// - signature: 64 bytes
// - ttl_secs: 4 bytes
// - hop_count: 1 byte
// - max_hops: 1 byte
// - timestamp: 8 bytes
// Total fixed: ~174 bytes raw, CBOR adds ~5-10% overhead
assert!(base_overhead < 200, "Base overhead should be under 200 bytes");
assert!(base_overhead > 150, "Base overhead should be over 150 bytes (sanity check)");
}
}