reverse_resonance_id

Crates.ioreverse_resonance_id
lib.rsreverse_resonance_id
version0.1.0
created_at2025-10-08 01:28:18.166551+00
updated_at2025-10-08 01:28:18.166551+00
descriptionSelf-checking symmetric tokens based on reversing squared user identifiers.
homepagehttps://github.com/andysay1/rrid
repositoryhttps://github.com/andysay1/rrid
max_upload_size
id1873160
size1,258,343
(andysay1)

documentation

README

Baseline token example

reverse_resonance_id

Self-checking symmetric tokens based on reversing and pairing it with fast integrity tags. The crate ships a zero-allocation core API, an optional CLI, and Criterion benches so you can validate throughput before rollout.

Highlights

  • Three schemes: baseline (CRC32 + Blake2s), HMAC (Blake2s) and salt+iter (slow hash w/ configurable work factor).
  • Safe, pure-Rust implementation (Rust 1.70+ MSRV) with no unsafe.
  • Strong test coverage including property and tamper tests, plus a 100k-token smoke test (opt-in).
  • Optional features for CLI (cli), salted hashing (salt-iter), HMAC (hmac), serde integration, and in-memory key zeroisation (zeroize).

Installation

[dependencies]
reverse_resonance_id = { version = "0.1.0", features = ["hmac", "salt-iter"] }

Feature flags:

Feature Default Purpose
baseline Core CRC32 + Blake2s flow.
hmac Enables HMAC-Blake2s generation/verification.
salt-iter Enables salt+iter flow with secure randomness.
cli Builds the rrid binary (cargo install --features cli).
serde Derives serde::Serialize/Deserialize for structs that need it (used by CLI).
zeroize Zeroizes stored secrets (Scheme enum, HMAC helper) when dropped.

Quick Start (Rust)

use reverse_resonance_id::{make_token_baseline, validate_token_baseline};
#[cfg(feature = "hmac")]
use reverse_resonance_id::{make_token_hmac, validate_token_hmac};
#[cfg(feature = "salt-iter")]
use reverse_resonance_id::{make_token_salt_iter, validate_token_salt_iter};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Baseline: CRC32 + truncated Blake2s (8 hex chars)
    let baseline = make_token_baseline(33)?;
    assert!(validate_token_baseline(baseline.as_str()));

    // HMAC (Blake2s) with 64-bit tag (16 hex chars)
    #[cfg(feature = "hmac")]
    {
        let key = hex::decode("00112233445566778899aabbccddeeff")?;
        let hmac = make_token_hmac(33, &key, 16)?;
        assert!(validate_token_hmac(hmac.as_str(), &key, 16));
    }

    // Salted iterative hash (default salt=4 bytes, iters=2048)
    #[cfg(feature = "salt-iter")]
    {
        let slow = make_token_salt_iter(33, 4, 2_048)?;
        assert!(validate_token_salt_iter(slow.as_str()));
    }

    Ok(())
}

Scheme formats:

Scheme Format
Baseline <n2>-<rev>-<crc32hex8>-<blake2s8hex>
HMAC <n2>-<rev>-<hmac_blake2s_hex>
Salt+Iter <n2>-<rev>-<salt_hex>-<iters>-<tag8hex>

Where n2 = n * n as decimal string, rev is that string reversed, and the payload hashed is "{n2}|{rev}".

CLI

Enable the cli feature to build the rrid binary:

cargo install --path . --features cli

Generate

$ rrid make --scheme baseline 33
{"token":"1089-9801-f7961616-283a12c9","scheme":"baseline","gen_time_ms":0.088709}

$ rrid make --scheme hmac --key 00112233445566778899aabbccddeeff --tag-len 16 33
{"token":"1089-9801-6d779ec117c17c71","scheme":"hmac","gen_time_ms":0.10254100000000001}

$ rrid make --scheme salt-iter --salt-len 4 --iters 2048 33
{"token":"1089-9801-b453dac8-2048-8cebd230","scheme":"salt-iter","gen_time_ms":12.504375}

Verify

$ rrid verify --scheme baseline 1089-9801-f7961616-283a12c9
{"token":"1089-9801-f7961616-283a12c9","scheme":"baseline","gen_time_ms":0.088917}

The command exits with code 0 when validation succeeds and 1 otherwise. JSON always contains token, scheme, and the measured runtime in milliseconds.

Errors

Token generation returns Result<Token, RRIDError>. Validation helpers return bool (false on any error). RRIDError variants cover invalid user IDs, format/parse problems, reversed-string mismatches, tag mismatches, and cryptographic errors. Convert or display them directly for logging/auditing.

Security Notes

  • Baseline: Fast and deterministic, but only a 32-bit CRC + 32-bit Blake2s tag. Best for human-readable, low-risk use-cases.
  • HMAC: Requires a server-side secret. Default tag length is 16 hex chars (64 bits). Increase tag_len for harder brute force. Enable the zeroize feature to erase in-memory keys on drop.
  • Salt+Iter: Keyless, time-hardening defence against brute force. Defaults to 2048 iterations; adjust upward for higher security (but note the slower throughput and DoS trade-offs).
  • All hex digests are lowercase. Always compare using the provided helpers to avoid subtle mistakes.
  • For long-term, high-assurance deployments, consider layering stronger authentication (e.g., Ed25519 signatures) on top—this crate documents the core rev(n²) idea.

Benchmarks

Measured with cargo bench on Rust 1.88.0 (release build) on the developer machine. Throughput counts complete generate+validate pairs.

Scheme Workload Throughput
Baseline 100k tokens / batch ~595k tokens/sec
HMAC (tag 16) 50k tokens / batch ~506k tokens/sec
Salt+Iter (512 iters) 5k tokens / batch ~7.9k tokens/sec
Salt+Iter (1024 iters) 5k tokens / batch ~3.9k tokens/sec
Salt+Iter (2048 iters) 5k tokens / batch ~2.0k tokens/sec
Salt+Iter (4096 iters) 5k tokens / batch ~0.93k tokens/sec

Use the benches to evaluate your own hardware (cargo bench). Plots are stored under target/criterion/.

Testing & QA

cargo fmt
cargo clippy --all-targets --all-features
cargo test
cargo bench             # runs Criterion suites
cargo test -- --ignored # runs the 100k-token smoke test

The test suite includes:

  • Round-trip, tamper, and uniqueness checks for every scheme.
  • Property tests with Proptest.
  • Deterministic RNG tests for salt generation.
  • A long-running #[ignore] bulk test covering 100k tokens and salt iter smoke coverage.

Actix Web Integration Snippet

use actix_web::{dev::Payload, error::ErrorUnauthorized, FromRequest, HttpRequest};
use futures_util::future::{ready, Ready};
use reverse_resonance_id::validate_token_hmac;

pub struct RridToken(String);

impl FromRequest for RridToken {
    type Error = actix_web::Error;
    type Future = Ready<Result<Self, Self::Error>>;

    fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
        const KEY: &[u8] = b"0123456789abcdef0123456789abcdef";
        let header = req
            .headers()
            .get("x-rrid-token")
            .and_then(|v| v.to_str().ok());

        match header {
            Some(token) if validate_token_hmac(token, KEY, 16) => {
                ready(Ok(RridToken(token.to_owned())))
            }
            _ => ready(Err(ErrorUnauthorized("invalid rrid token"))),
        }
    }
}

License

Dual-licensed under MIT or Apache-2.0. See LICENSE-MIT and LICENSE-APACHE for details.

Commit count: 0

cargo fmt