waddling-errors-hash
WDP-compliant xxHash3 computation for diagnostic codes
A standalone hash utility crate implementing WDP (Waddling Diagnostic Protocol) Part 5 (Compact IDs) and Part 7 (Namespaces) specifications. Provides deterministic xxHash3-based hash generation for compact error code identifiers. Designed for compile-time hash embedding in procedural macros with zero runtime overhead.
WDP Conformance
This crate implements the Waddling Diagnostic Protocol (WDP) specifications:
- WDP Part 5: Compact IDs - Error code hash generation with xxHash3 and
"wdp-v1"seed - WDP Part 7: Namespaces - Namespace hash generation with xxHash3 and
"wdpns-v1"seed
Key WDP Requirements
Per WDP Part 5 §4.1:
Implementations MUST use xxHash3 (xxh3_64) as the hashing algorithm for Compact ID generation.
Per WDP Part 5 §4.3:
Alternative algorithms MUST NOT be used. This requirement ensures universal interoperability: identical error codes MUST produce identical Compact IDs across all WDP implementations.
Overview
This crate converts error codes like E.AUTH.TOKEN.001 into compact 5-character hashes using the WDP-standardized xxHash3 algorithm.
What It Does
use ;
// Hash an error code (WDP-compliant: case-insensitive, whitespace-trimmed)
let hash = compute_wdp_hash;
assert_eq!; // e.g., "V6a0B"
// These all produce the SAME hash (normalization per WDP Part 5 §3):
assert_eq!;
assert_eq!;
// Hash a namespace (WDP Part 7)
let ns_hash = compute_wdp_namespace_hash;
assert_eq!; // e.g., "05o5h"
// Combined identifier: namespace_hash-code_hash (WDP Part 7 §5)
let full_id = compute_wdp_full_id;
assert_eq!; // "05o5h-V6a0B"
Why Compact IDs?
- 📦 Compact logging:
[V6a0B]vs[E.AUTH.TOKEN.001](~70% size reduction) - 🌐 Network efficiency: IoT devices send 5 bytes instead of 20+ bytes
- 🔍 Quick lookups: Fast error correlation and catalog searches
- 🔒 Deterministic: Same input always produces same output
- 🌍 Cross-language: xxHash3 available in Python, JS, Go, Java, Rust, C, C++, etc.
- 📱 URL-safe: Base62 encoding (alphanumeric only, no special characters)
Algorithm: xxHash3 Only
This crate exclusively implements xxHash3 as mandated by WDP Part 5. xxHash3 was chosen for:
- ⚡ Speed: ~30 GB/s throughput
- 🎯 Optimized for small inputs: Perfect for 15-30 byte error codes
- 🌐 Universal availability: Supported in all major programming languages
- 📊 Excellent distribution: Minimal collision probability
- 🔒 Frozen specification: Stable since 2021, guaranteed cross-platform consistency
Specification References:
Note: This crate is NOT cryptographically secure. xxHash3 is designed for speed and distribution quality, not security. For security-sensitive applications, use cryptographic verification at a higher protocol layer (TLS, JWT, etc.) as recommended in WDP Part 5 §4.4.
Quick Start
Basic Usage (WDP-Compliant)
use compute_wdp_hash;
let hash = compute_wdp_hash;
println!; // e.g., "V6a0B"
// Properties:
assert_eq!;
assert!;
Algorithm: xxHash3 with "wdp-v1" seed + input normalization (uppercase, trim)
Without Normalization
use compute_hash;
// No normalization - input used as-is
let hash = compute_hash;
println!;
Algorithm: xxHash3 with "wdp-v1" seed (no normalization)
Custom Seed
use ;
// Use a custom seed for isolated hash space
let config = with_seed;
let hash = compute_hash_with_config;
Use case: Multi-tenant isolation (different seeds produce different hashes)
Use Cases
1. WDP-Conformant (Recommended)
use compute_wdp_hash;
// WDP-compliant: normalization + standard seed
let hash = compute_wdp_hash;
// Normalized: uppercase, trimmed (per WDP Part 5 §3)
assert_eq!;
Algorithm: xxHash3 with "wdp-v1" seed (0x000031762D706477)
Normalization: Trim + Uppercase
Use for: Interoperability with WDP ecosystem
2. General Purpose (Fast)
use compute_hash;
// Fast hashing without normalization
let hash = compute_hash;
Algorithm: xxHash3
Speed: ~30 GB/s
Use for: Projects not requiring WDP conformance
3. Multi-Tenant Isolation
use ;
// Each tenant gets unique hashes (prevents catalog sharing)
let tenant_a_config = with_seed;
let tenant_b_config = with_seed;
let hash_a = compute_hash_with_config;
let hash_b = compute_hash_with_config;
// Same error code, different hashes!
assert_ne!;
Use for: SaaS, multi-tenant systems where catalog isolation is needed
4. Namespace Hashing (WDP Part 7)
use ;
// Hash a namespace (library, service, or application name)
let ns_hash = compute_wdp_namespace_hash;
assert_eq!; // e.g., "05o5h"
// Combined identifier for global uniqueness
let full_id = compute_wdp_full_id;
assert_eq!; // e.g., "05o5h-V6a0B"
assert_eq!; // namespace_hash-code_hash format
Use for: Multi-library applications, microservices (WDP Part 7 §2)
Compile-Time Usage (Proc Macros)
The primary use case is compile-time hash generation in procedural macros:
// In waddling-errors-macros/src/diag.rs
use compute_hash;
// During macro expansion (compile time):
let full_code = "E.AUTH.TOKEN.001";
let hash = compute_hash;
// Generate constant in output code:
let hash_lit = new;
quote!
Result: Hash is computed once at compile time and embedded as a string constant in the binary. Zero runtime cost!
WDP Seed Constants
For WDP conformance, use these seed values:
| Purpose | Seed String | u64 Value (little-endian) | WDP Reference |
|---|---|---|---|
| Error code hashes | "wdp-v1" |
0x000031762D706477 |
Part 5 §4.5 |
| Namespace hashes | "wdpns-v1" |
0x31762D736E706477 |
Part 7 §4.2 |
Seed Conversion (WDP Part 5 §4.5.1):
- Take UTF-8 bytes of seed string (6 bytes for "wdp-v1")
- Zero-pad on the RIGHT to 8 bytes:
[0x77, 0x64, 0x70, 0x2D, 0x76, 0x31, 0x00, 0x00] - Interpret as little-endian u64:
0x000031762D706477
Cross-Language Examples
Rust:
use xxh3_64_with_seed;
const WDP_SEED: u64 = 0x000031762D706477;
let hash = xxh3_64_with_seed;
// Verification: compute from bytes
let seed_bytes: = ;
let seed = u64from_le_bytes;
assert_eq!;
Python:
= 0x000031762D706477 # 13891256219767
=
# Verification
= b + b # Zero-pad to 8 bytes
=
assert == 0x000031762D706477
TypeScript/JavaScript:
import { xxh3 } from 'xxhash-wasm';
const WDP_SEED = 0x000031762D706477n; // BigInt literal
const hash = xxh3.h64(inputBytes, WDP_SEED);
Go:
import "github.com/zeebo/xxh3"
const WDPSeedU64 uint64 = 0x000031762D706477
hash := xxh3.HashSeed(inputBytes, WDPSeedU64)
C/C++:
XXH64_hash_t hash = ;
Normalization (WDP Part 5 §3.3):
All languages MUST apply the same normalization for WDP compliance:
- Trim leading/trailing whitespace
- Convert to uppercase
- Encode as UTF-8 bytes
# Python normalization
return
# Usage
=
# Result: "E.AUTH.TOKEN.001"
Security Considerations
xxHash3 is NOT Cryptographically Secure
⚠️ NOT cryptographically secure
⚠️ Attackers can craft collisions if they control input
✅ Safe for error codes (you control the input, not attackers)
✅ Perfect for: Catalogs, logging, compression, lookups
WDP Part 5 §4.4 states:
Compact IDs are designed for IDENTIFICATION purposes, not AUTHENTICATION.
When xxHash3 is Appropriate
// This is SAFE because error codes are controlled by developers, not users
let hash = compute_hash; // xxHash3
Security Layering (WDP Part 5 §4.4)
For security requirements, use appropriate mechanisms at the correct architectural layer:
| Security Requirement | Recommended Solution | Layer |
|---|---|---|
| Transport security | HTTPS/TLS | Transport |
| Message integrity | JWT/JWS signing | Application |
| Catalog integrity | Ed25519 signature | Distribution |
| Authentication | OAuth/API keys | Application |
Example:
The Compact ID provides efficient identification while JWT provides message-level integrity.
Architecture
Why This Crate Exists
Procedural macros run in a separate compilation context and need a standalone hash implementation:
┌─────────────────────────────────┐
│ waddling-errors-macros │
│ (proc macro - compile time) │
│ │
│ Computes hash during macro │
│ expansion and embeds as const │
└────────────┬────────────────────┘
│
│ depends on
▼
┌─────────────────────────────────┐
│ waddling-errors-hash │◄─────────┐
│ (pure computation) │ │
│ │ │ depends on
│ • compute_hash() │ │ (optional)
│ • compute_wdp_hash() │ │
│ • compute_wdp_namespace_hash() │ │
│ • xxHash3 implementation │ │
└─────────────────────────────────┘ │
▲ │
│ depends on (optional) │
│ │
┌────────────┴────────────────────┐ │
│ waddling-errors │──────────┘
│ (runtime library) │
│ │
│ Can verify hashes at runtime │
│ (if hash feature enabled) │
└─────────────────────────────────┘
▲
│ user depends on
│
┌────────────┴────────────────────┐
│ User's Application │
│ │
│ Uses error codes with embedded │
│ hash constants (zero cost!) │
└─────────────────────────────────┘
Binary Size Impact
Compile-time (proc macro): xxHash3 implementation available, zero impact on user's binary
Runtime (optional): Only if user enables hash feature for verification
User's binary without hash feature:
├─ Hash constants: ~5 bytes per error code
└─ Hash algorithm code: 0 bytes (not included!)
User's binary WITH hash feature (runtime verification):
├─ Hash constants: ~5 bytes per error code
└─ xxHash3 implementation: ~10-15 KB
API Reference
WDP-Conformant Functions (Recommended)
/// Compute WDP-conformant hash (normalized: trim + uppercase)
/// Per WDP Part 5 §3
WDP Constants
/// WDP code hash seed: "wdp-v1" as little-endian u64
/// Per WDP Part 5 §4.5
pub const WDP_SEED: u64 = 0x000031762D706477;
/// WDP seed as string
pub const WDP_SEED_STR: &str = "wdp-v1";
/// WDP code seed for xxHash3
/// Per WDP Part 5 §4.5
pub const WDP_CODE_SEED: u64 = 0x000031762D706477;
/// WDP namespace seed: "wdpns-v1" as little-endian u64
/// Per WDP Part 7 §4.2
pub const WDP_NAMESPACE_SEED: u64 = 0x31762D736E706477;
Core Functions
/// Compute hash with default config (xxHash3 + "wdp-v1")
Configuration Types
/// Hash algorithm (currently only xxHash3 per WDP Part 5 §4.1)
/// Hash configuration
Utility Functions
/// Convert bytes to 5-character base62 string
Const (Compile-Time) Functions
/// Const version of compute_wdp_hash (for compile-time)
pub const pub const pub const pub const pub const
Configuration Loading
This crate also provides configuration loading utilities for WDP projects:
/// Load global hash configuration from Cargo.toml or environment
Features
[]
= ["std"]
= [] # Standard library support (enables config loading)
Note: xxHash3 implementation is always available. The std feature only affects configuration loading utilities.
no_std Support
Works in no_std environments with alloc:
[]
= { = "0.7", = false }
Core hashing functions work in no_std, but configuration loading requires std.
FAQ
Q: Why only xxHash3?
A: WDP Part 5 §4.3 mandates a single algorithm for universal interoperability. xxHash3 was chosen for speed, distribution quality, and cross-language availability.
Q: Can I use a different algorithm?
A: No, if you want WDP conformance. WDP-compliant implementations MUST use xxHash3 to ensure identical Compact IDs across all systems.
Q: Is xxHash3 secure enough?
A: xxHash3 is NOT cryptographically secure, but that's intentional. Compact IDs are for identification, not authentication. Use cryptographic verification at the protocol layer (TLS, JWT) as recommended in WDP Part 5 §4.4.
Q: Can I use custom seeds?
A: Yes, via compute_hash_with_config(). This is useful for multi-tenant isolation. However, custom seeds break WDP conformance—use only if you don't need catalog interoperability.
Q: Does this increase my binary size?
A: No! Hashes are computed at compile time. Only the 5-character string constants are in your binary (~5 bytes each).
Q: What if I need collision resistance beyond 916M?
A: Use full structured codes (E.AUTH.TOKEN.001) in scenarios where uniqueness is critical. Compact IDs are optimized for typical projects (<5,000 error codes).
Q: How do I verify cross-language compatibility?
A: Use the test vectors in WDP Part 5 §8. All implementations should produce identical hashes for the same inputs.
Contributing
Contributions welcome! Areas of interest:
- Performance optimizations
- Cross-language test vectors
- Documentation improvements
- Bug fixes
Note: Feature requests for alternative algorithms will be declined per WDP specification requirements.
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option.
See Also
- waddling-errors - Core error code library
- waddling-errors-macros - Procedural macros
- WDP Part 5: Compact IDs
- WDP Part 7: Namespaces
Built with 🦆 by the Waddling Errors team