Skip to main content

🛡️ ThreatEngine

Crates.io Rust Edition Python Bindings License Author

ThreatEngine is a high-performance, 100% native Rust implementation of Meta (Facebook) ThreatExchange's PDQ (Photo/Image Hashing) and TMK (Temporal Match Kernel Video Hashing) perceptual similarity algorithms with Python bindings (PyO3).


✨ Features

  • 📷 PDQ (Photo Hashing): Generates 256-bit perceptual image signatures via 2D Discrete Cosine Transform (DCT) & Median Quantization.
  • 🎬 TMK (Video Hashing): Aggregates frame-level PDQF signatures across video timelines using Fourier/Cosine basis functions $\psi_m(t)$ into compact video signatures.
  • ⚡ Zero-Cost Performance: Native SIMD and bitwise Hamming distance calculations in Rust (10x-50x faster than pure Python loops).
  • 🛡️ Robustness: Highly resistant to resizing, compression, frame-rate changes, transcoding, and minor visual modifications.
  • 🐍 Python & Rust Ready: Use directly in Rust as a crate, in Python via import threatengine, or as a command-line binary.

🚀 Installation

Rust (Cargo Crate)

Add threatengine to your Cargo.toml:

[dependencies]
threatengine = "0.1.0"

Or run:

cargo add threatengine

Python Package (PyO3)

Install locally using maturin or pip:

pip install maturin
maturin develop --release

📖 Usage Examples

🦀 Rust Example

use threatengine::{generate_pdq_hash, pdq_similarity, hash_video_file};
use image::open;

fn main() {
    // 1. Image Hashing
    let img1 = open("photo1.jpg").unwrap();
    let img2 = open("photo2.jpg").unwrap();

    let (hash1, quality1) = generate_pdq_hash(&img1);
    let (hash2, quality2) = generate_pdq_hash(&img2);

    println!("Image 1 PDQ Hash: {} (Quality: {}/100)", hash1.to_hex(), quality1);
    println!("Image 2 PDQ Hash: {} (Quality: {}/100)", hash2.to_hex(), quality2);

    // Compute Hamming distance & match verdict (threshold <= 31)
    let (distance, similarity) = pdq_similarity(&hash1, &hash2);
    println!("Hamming Distance: {} bits", distance);
    println!("Similarity Score: {:.2}%", similarity * 100.0);
    println!("Verdict: {}", if hash1.is_match(&hash2, 31) { "MATCH" } else { "NO MATCH" });

    // 2. Video Hashing & Comparison
    let sig1 = hash_video_file("video1.mp4", 2.0).unwrap();
    let sig2 = hash_video_file("video2.mp4", 2.0).unwrap();

    let video_score = sig1.match_score(&sig2);
    println!("Video Similarity Score: {:.4}", video_score);
    println!("Verdict: {}", if sig1.is_match(&sig2, 0.75) { "MATCH" } else { "NO MATCH" });
}

🐍 Python Example

import threatengine

# 1. Image Hashing & Distance
hash1, quality1 = threatengine.pdq_hash_file("photo1.jpg")
hash2, quality2 = threatengine.pdq_hash_file("photo2.jpg")

distance, similarity = threatengine.pdq_similarity(hash1, hash2)
print(f"Hamming Distance: {distance} bits")
print(f"Similarity: {similarity * 100:.2f}%")
print(f"Is Match: {distance <= 31}")

# 2. Video Comparison
score = threatengine.tmk_compare_videos("video1.mp4", "video2.mp4", fps=2.0)
print(f"Video Match Score: {score:.4f}")
print(f"Is Match: {score >= 0.75}")

💻 Command-Line Interface (CLI)

# Generate image hash & quality rating
cargo run -- pdq-hash photo.jpg

# Compare two images
cargo run -- pdq-compare photo1.jpg photo2.jpg --threshold 31

# Compare two videos
cargo run -- tmk-compare video1.mp4 video2.mp4 --threshold 0.75

📊 Invariance & Robustness Matrix

Transformation Tested Scenario Match Score / Distance Match Verdict
Image Resizing 400x400 -> 120x120 10 bits (96.09% Sim) MATCH
Video FPS Downsample 30 FPS -> 5 FPS 0.9971 Cosine Score MATCH
Video Resolution 1080p -> 360p 0.8471 Cosine Score MATCH
HD Video Resolution 4K -> 720p HD 0.9166 Cosine Score MATCH
Standard Video 480p -> 360p 0.9861 Cosine Score MATCH

🤝 Contributing

Contributions, issues, and feature requests are welcome! Feel free to check the issues page.


👨‍💻 Author

Crafted with ❤️ by Shakib Ahmed (@expertskb)

📜 License

Distributed under the MIT License. See LICENSE for more details.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

threatengine-0.1.0.tar.gz (17.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

threatengine-0.1.0-cp38-abi3-manylinux_2_34_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.8+manylinux: glibc 2.34+ x86-64

File details

Details for the file threatengine-0.1.0.tar.gz.

File metadata

  • Download URL: threatengine-0.1.0.tar.gz
  • Upload date:
  • Size: 17.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for threatengine-0.1.0.tar.gz
Algorithm Hash digest
SHA256 668a0a36d88585e44537b0725851f43fef27272fc10d5513fdb83a0f076712ed
MD5 cd7e5b62bd2b466ba76e8f0550698328
BLAKE2b-256 8ec9d99f8306096c2a8794986f691c35cb86ea26210860975acfb4be857fab1d

See more details on using hashes here.

File details

Details for the file threatengine-0.1.0-cp38-abi3-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for threatengine-0.1.0-cp38-abi3-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 a29cdf359fbff636112fc74cc4c4e12db6fb6f25ac0fd54d4ea296e98d104c54
MD5 4f824eeaa73bde1fc6aa79acecc98f3a
BLAKE2b-256 0901de70cf4fec01bb1cfd5d4ab67847c67fc6a8e77dc9041dae845b213f04e9

See more details on using hashes here.

Release history Release notifications | RSS feed

0.3.0

2 files

0.2.0

1 file

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page