pepperflake 0.1.0

Fast, unforgeable, sortable 64-bit ID generation
Documentation
  • Coverage
  • 100%
    7 out of 7 items documented1 out of 7 items with examples
  • Size
  • Source code size: 29.16 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 1.29 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 55s Average build duration of successful builds.
  • all releases: 55s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • agilov/pepperflake
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • agilov

☥ pepperflake

Crates.io Docs.rs CI

Fast, unforgeable, roughly sortable 64-bit ID generation in Rust.

Standard Snowflake IDs are guessable, allowing attackers to scrape your data or forge IDs. UUIDs are unforgeable, but take up 128 bits and destroy database index locality.

pepperflake provides the best of both worlds: a 64-bit integer that sorts chronologically, but includes a peppered checksum that instantly rejects ~98.4% of forged or guessed IDs without a database lookup.

Performance

  • Generation: ~5–40 ns (depending on OS clock syscalls).
  • Validation: ~1 ns (nearly 1 billion validations/sec per core).
  • Memory: Zero allocations. Pure arithmetic.

Bit Layout

 63                    20 19           6 5           0
 |------- time (44b) ------|-- rand (14b) -|- check (6b) -|
  • 44 bits: Millisecond timestamp (valid for ~557 years).
  • 14 bits: Xorshift random tail (16,384 slots per ms tick).
  • 6 bits: Checksum seeded with a secret pepper.

Usage

Add pepperflake to your Cargo.toml:

[dependencies]
pepperflake = "0.1.0"

Basic generation and validation:

fn main() {
    // Generate a new 64-bit ID
    let id = pepperflake::generate();
    
    // Validate an incoming ID instantly
    if pepperflake::is_valid(id) {
        println!("Valid ID: {}", id);
    }
}

Securing the Checksum

At application startup, inject a secret pepper. Without this pepper, an attacker cannot generate a valid checksum, meaning you can drop bad traffic before it ever hits your database.

fn main() {
    // Set this once at startup using a securely generated random u64
    pepperflake::set_pepper(0x8F2A_9B3C_4D5E_6F70);
    
    let secure_id = pepperflake::generate();
}

Configuration

You can adjust the balance between throughput and security at runtime. Every bit moved from the checksum to the random tail doubles your throughput but halves your fake-ID rejection rate.


fn main() {
    // Move to 12 bits of randomness (4,096 IDs/ms) and 8 bits of checksum (99.6% rejection)
    pepperflake::configure(0x8F2A_9B3C_4D5E_6F70, 12, 8);
}