promocrypt-core
Core Rust library for cryptographically secure promotional code generation and validation.
Overview
promocrypt-core is a high-performance library for generating and validating promotional codes with enterprise-grade security. It uses HMAC-SHA256 for code generation and Damm algorithm for check digit validation, ensuring 100% detection of single-character errors and transpositions.
Key Highlights
- Cryptographically Secure: HMAC-SHA256 based generation
- Two-Key Encryption: Separate keys for read (machineID) and write (secret) access
- Machine Binding:
.binfiles can be bound to specific machines - Damm Check Digit: 100% detection of single errors and transpositions
- Index-Based Check Position: Hide check digit location for added security
- Storage Encryption: Encrypt codes before database storage
- FFI Ready: C-compatible interface for PHP, Python, and other languages
Features
| Feature | Description |
|---|---|
| Code Generation | HMAC-SHA256 based, deterministic |
| Code Validation | Damm check digit with detailed error reporting |
| Batch Operations | Generate/validate thousands of codes efficiently |
| Prefix/Suffix | Optional formatting for branded codes |
| Separators | Configurable separator positions (e.g., XXXX-XXXX-XX) |
| Check Position | Index-based placement (-1=end, 0=start, N=position) |
| Storage Encryption | AES-256-SIV for database storage |
| Two-Key Encryption | MachineID (read) + Secret (write) |
| Machine Binding | Bind .bin files to specific machines |
| Counter Modes | File-based, in-bin, or manual |
| Secret Rotation | Change password without invalidating codes |
| History Tracking | Track rotations, masterings, config changes |
| Generation Log | Record all code generation operations |
| Statistics | Capacity, utilization, generation counts |
| FFI/C API | Use from PHP, Python, Go, etc. |
Installation
From Source
As Cargo Dependency
[]
= "1.0"
Pre-built Binaries
Download from GitHub Releases:
libpromocrypt-linux-x86_64.so- Linux x86_64libpromocrypt-macos-aarch64.dylib- macOS Apple Siliconpromocrypt.h- C header file
Quick Start
Create and Use a .bin File
use ;
// Create a new .bin file
let mut config = create_config;
config.counter_mode = InBin;
let mut bin = create?;
// Generate codes
let codes = bin.generate_batch?;
println!;
// Validate codes
for code in &codes
Read-Only Access (Validation Only)
use BinFile;
// Open with machine ID (read-only)
let bin = open_readonly?;
// Validate user input
let result = bin.validate;
if result.is_valid else
API Reference
BinFile Methods
Creation and Opening
// Create new .bin file (requires secret)
create // Open read-only with machine ID
open_readonly // Open with full access using secret
open_with_secret
Validation (Both Access Levels)
// Validate with detailed result
bin.validate // Quick boolean check
bin.is_valid // Batch validation
bin.validate_batch
Generation (Requires Secret)
// Generate single code
bin.generate // Generate batch
bin.generate_batch // Generate at specific counter (manual mode)
bin.generate_at // Generate batch at specific counter
bin.generate_batch_at
Storage Encryption (Requires Secret)
// Encrypt code for database storage
bin.encrypt_code // Decrypt code from storage
bin.decrypt_code // Batch operations
bin.encrypt_codes .decrypt_codes // Enable/disable storage encryption
bin.set_storage_encryption .is_storage_encryption_enabled
Counter Management
// Get current counter
bin.get_counter // Set counter (requires secret)
bin.set_counter // Reserve counter range atomically
bin.reserve_counter_range
Configuration Updates (Requires Secret)
// Update format options
bin.set_format // Update check position
bin.set_check_position // Rotate secret password
bin.rotate_secret
Machine Management (Requires Secret)
// Create copy bound to another machine
bin.master_for_machine // Export unbound copy
bin.export_unbound
History and Statistics
// Get history
bin.get_history .export_history // JSON
bin.clear_history // Get generation log
bin.get_generation_log
bin.export_generation_log // JSON
bin.clear_generation_log // Get statistics
bin.get_stats .total_codes_generated
Check Position (Index-Based)
The check digit can be placed at any position for added security:
use CheckPosition;
// End (default) - index 9 for 10-char code
let pos = End; // XXXXXXXXX[C]
// Start - index 0
let pos = Start; // [C]XXXXXXXXX
// Custom index
let pos = Index; // XXXX[C]XXXXX
let pos = Index; // XXXXXXX[C]XX
Code Format
use CodeFormat;
// Create format with prefix and suffix
let format = new
.with_prefix
.with_suffix;
// Result: PROMO-A3KF7NP2XM-2024
// Add separators
let format = new
.with_separator;
// Result: A3KF-7NP2-XM
// Combined
let format = new
.with_prefix
.with_suffix
.with_separator;
// Result: SALEA3KF-7NP2XM24
Counter Modes
use CounterMode;
// File-based counter (default)
File
// In-bin counter (stored in .bin file)
InBin
// Manual counter (caller provides values)
Manual
// External counter (for database-managed counters)
External
Binary File Format
The .bin file contains encrypted configuration and keys:
Offset Size Field
------ ---- -----
0 8 Magic: "PROMOCRY"
8 1 Version: 0x02
9 1 Flags
10 4 Header CRC32
14 16 Salt
30 48 MachineEncryptedKey
78 48 SecretEncryptedKey
126 4 EncryptedDataLength
130 N EncryptedData (JSON)
130+N 16 AuthTag
146+N 4 MutableLength
150+N M MutableSection (counter)
150+N+M 16 MutableAuthTag
Security
Two-Key Encryption System
data_key (random 32 bytes)
│
┌────────────┴────────────┐
│ │
▼ ▼
AES-GCM(machineID) AES-GCM(secret)
│ │
▼ ▼
machine_encrypted_key secret_encrypted_key
(READ-ONLY access) (FULL access)
- MachineID: Hardware-derived key for validation only
- Secret: User password for generation and configuration
Machine ID Components
- MAC addresses (all interfaces, sorted)
- CPU ID (if available)
- Root disk serial (if available)
Final ID: SHA256(components + "promocrypt-machine-id-v1")
Cryptographic Algorithms
| Component | Algorithm |
|---|---|
| Code Generation | HMAC-SHA256 |
| Key Derivation | Argon2id (m=64MB, t=3, p=1) |
| Encryption | AES-256-GCM |
| Storage Encryption | AES-256-SIV (deterministic) |
FFI/C API
Basic Usage (C)
int
PHP Usage
Python Usage
=
# Define types
=
=
=
=
=
=
=
# Use the library
=
=
=
=
Building from Source
Prerequisites
- Rust 1.85.0 or later
- Cargo
Build Commands
# Debug build
# Release build
# Build with FFI support
# Build shared library
Output Files
target/release/
├── libpromocrypt_core.so # Linux shared library
├── libpromocrypt_core.dylib # macOS shared library
├── libpromocrypt_core.a # Static library
└── libpromocrypt_core.rlib # Rust library
Running Tests
# Run all tests
# Run with all features
# Run specific test file
# Run with verbose output
# Run benchmarks
Examples
Full Workflow Example
use ;
Storage Encryption Example
use ;
Secret Rotation Example
use BinFile;
Performance
| Operation | Target | Notes |
|---|---|---|
validate() |
< 10us | Hot path optimization |
generate() |
< 100us | Including counter update |
generate_batch(1000) |
< 50ms | |
generate_batch(100000) |
< 5s | |
open_readonly() |
< 50ms | Includes Argon2 |
open_with_secret() |
< 100ms | Includes Argon2 |
License
MIT License - see LICENSE file for details.
Contributing
Contributions are welcome! Please read our contributing guidelines and submit pull requests to the main branch.
Related Projects
- promocrypt-cli - Command-line interface
- php-promocrypt - PHP bindings
- pg_promocrypt - PostgreSQL extension