A production-ready Python library for dynamic snapshot-based encryption using server-client architecture
Project description
teeth-gnashing
A production-ready Python library for dynamic snapshot-based encryption using server-client architecture.
Security Classification
Security Level: B2 - Suitable for Business Data Protection
The library has undergone extensive security testing with the following results:
Security Test Results (Latest)
-
Entropy Scores:
- Payload Entropy: 7.46/8.00 bits (93.25% of theoretical maximum)
- Hash Entropy: 4.88/5.00 bits (97.6% effectiveness)
- Salt Entropy: 4.88/5.00 bits (97.6% effectiveness)
-
Cryptographic Properties:
- Perfect Hash/Salt Uniqueness (1000/1000 samples)
- Block Correlation: 0.3333 (Ideal random: ~0.33)
- Salt Correlation: 0.3342 (Near-ideal distribution)
- Key Space Utilization: 128.00/128 possible values (100% efficiency)
Security Guarantees
- ✅ Forward Secrecy through dynamic key derivation
- ✅ Protection against replay attacks
- ✅ HMAC-verified snapshots
- ✅ Timing attack mitigation
- ✅ Multi-source entropy generation
- ✅ Secure key derivation with ChaCha20
Limitations
- ⚠️ Position correlation: 0.9844 (design tradeoff for invertibility)
- ⚠️ Requires time synchronization between client and server
- ⚠️ Not suitable for long-term storage of highly sensitive data
Features
- Dynamic snapshot-based encryption
- Secure handshake protocol
- Configurable server and client settings
- Support for both string and binary data encryption
- Thread-safe server implementation
- Async/await client API
- HMAC verification for snapshots
- Automatic session management
- Health check endpoint
- Rust FFI integration for high-performance cryptographic operations
- Automatic fallback to Python implementation when Rust library is unavailable
Rust FFI Integration
The library includes optional Rust FFI integration for high-performance cryptographic operations. The Rust library provides:
- Key Derivation: Blake2b-based key derivation with seed, tick, and salt
- Keystream Generation: ChaCha20 cipher for secure keystream generation
- XOR Encryption: Fast XOR-based encryption/decryption
- Fast Hashing: Blake2b hashing with configurable output length
Building the Rust Library
To enable Rust FFI support, build the crypto_core library:
cd crypto_core
cargo build --release
The compiled library will be available in crypto_core/target/release/:
- Windows:
crypto_core.dll - Linux:
libcrypto_core.so - macOS:
libcrypto_core.dylib
Automatic Fallback
The library automatically falls back to Python implementations if the Rust library is not available, ensuring compatibility across all environments.
Installation
From PyPI (Recommended)
pip install teeth-gnashing
From Source
- Clone the repository
git clone https://github.com/username/teeth-gnashing.git
cd teeth-gnashing
- Install dependencies:
pip install -r requirements.txt
Development Setup
For development work, install with dev dependencies:
pip install -e ".[dev]"
# Or install dev dependencies separately
pip install -r requirements.txt
pip install pytest pytest-asyncio pytest-cov black isort mypy pylint
# Run tests with coverage
pytest --cov=teeth_gnashing tests/
# Run specific test files
pytest tests/test_crypto_ffi.py -v # Test Rust FFI integration
pytest tests/test_client.py -v # Test client functionality
# Test files overview
# - tests/test_crypto_ffi.py: Tests for Rust FFI cryptographic operations (20+ test cases)
# - tests/test_client.py: Tests for client functionality including Rust integration (50+ test cases)
# - tests/test_integration.py: Integration tests for full encryption/decryption flow
# - tests/test_server.py: Tests for server functionality
# New test cases added for Rust FFI integration:
# - Key derivation tests (deterministic, different seeds/ticks/salts)
# - Keystream generation tests (deterministic, different keys)
# - XOR encryption/decryption tests (self-inverse property)
# - Fast hashing tests (deterministic, different inputs)
# - Full integration cycles (key derivation -> keystream -> encryption -> decryption)
# - Rust FFI usage in client methods
# - Fallback to Python when Rust unavailable
# - Coprime guarantee maintenance
# - Hash consistency tests
# - Full encryption roundtrip tests
# - Different seeds produce different keys
# - Different ticks produce different keys
# - Different salts produce different keys
# - Singleton pattern for CryptoFFI instance
# - Short key validation for keystream generation
# - Different keystreams produce different results
# - Different hash lengths (16, 32, 64 bytes)
# - Key derivation and keystream generation integration
# - Hash and encrypt integration
# - Full encryption cycle with FFI functions
# Run code quality checks
black .
isort .
pylint teeth_gnashing
mypy teeth_gnashing
Server Configuration
Create a server_config.json file (will be created automatically with defaults if not present):
{
"secret_key": "base64_encoded_secret_key",
"tick_interval": 1.0,
"host": "0.0.0.0",
"port": 8000,
"hash_size": 16
}
Client Configuration
Create a client_config.json file or pass configuration directly:
{
"server_url": "http://localhost:8000",
"secret_key": "base64_encoded_secret_key",
"max_drift": 60,
"handshake_points": 8,
"hash_size": 16
}
Usage
Quick Start (Out of the Box)
Get started with the encryption protocol in just a few steps:
1. Start the Server
In one terminal window, run:
python server.py
The server will automatically:
- Create
server_config.jsonwith default settings if it doesn't exist - Start listening on
http://0.0.0.0:8000 - Initialize the snapshot generation system
- Output the startup status
2. Use the Client
In another terminal or Python script:
import asyncio
from client import CryptoClient, CryptoConfig
async def main():
# Use default client configuration
config = CryptoConfig(
server_url="http://localhost:8000",
secret_key=b"super_secret_key_for_hmac",
array_size=256,
hash_size=32
)
async with CryptoClient(config) as client:
# Authenticate with the server
await client.authenticate()
print("✓ Authenticated successfully")
# Encrypt a message
message = "Hello, Secure World!"
encrypted = await client.encrypt_message(message.encode())
print(f"✓ Encrypted: {encrypted.hex()[:40]}...")
# Decrypt the message
decrypted = await client.decrypt_message(encrypted)
print(f"✓ Decrypted: {decrypted.decode()}")
asyncio.run(main())
3. Run the Crypto Analysis (Optional)
To analyze the security properties of the encryption:
python crypto_analysis.py
This will:
- Collect 1000 encryption samples
- Analyze entropy and patterns
- Perform differential analysis
- Display security metrics
Complete Example Script
Create example.py:
import asyncio
from client import CryptoClient, CryptoConfig
async def encrypt_data():
config = CryptoConfig(
server_url="http://localhost:8000",
secret_key=b"super_secret_key_for_hmac"
)
async with CryptoClient(config) as client:
await client.authenticate()
# Encrypt multiple messages
messages = [
b"Message 1: Confidential data",
b"Message 2: More secure information",
b"Message 3: Binary data test"
]
for msg in messages:
encrypted = await client.encrypt_message(msg)
decrypted = await client.decrypt_message(encrypted)
assert decrypted == msg
print(f"✓ {msg.decode()} -> Encrypted -> Decrypted successfully")
if __name__ == "__main__":
asyncio.run(encrypt_data())
Run it:
python example.py
Starting the Server
python server.py
The server will start on http://localhost:8000 by default.
Using the Client
Basic usage with context manager:
import asyncio
from client import CryptoClient, CryptoConfig
async def main():
# Configuration can be loaded from file
async with CryptoClient("client_config.json") as client:
await client.authenticate()
# Encrypt string data
encrypted = await client.encrypt_message("Your secret message")
decrypted = await client.decrypt_message(encrypted)
print(decrypted.decode('utf-8'))
# Encrypt binary data
binary_data = b"Your binary data"
encrypted = await client.encrypt_message(binary_data)
decrypted = await client.decrypt_message(encrypted)
if __name__ == "__main__":
asyncio.run(main())
Or with direct configuration:
config = CryptoConfig(
server_url="http://localhost:8000",
secret_key=b"your_secret_key", # Will be base64 encoded automatically
max_drift=60 # Maximum allowed time drift in seconds
)
async with CryptoClient(config) as client:
# Your encryption/decryption code here
pass
API Reference
Server Endpoints
-
POST /handshake- Initialize client authentication- Request body:
{"hash": "32_byte_hex_string"} - Response:
{"status": "ok"}or error
- Request body:
-
GET /snapshot- Get current server snapshot- Response:
{"tick": int, "seed": int, "timestamp": int, "signature": string}
- Response:
-
GET /health- Server health check- Response:
{"status": "healthy", "timestamp": int}
- Response:
Client API
CryptoConfig
Configuration dataclass with the following fields:
server_url: Server endpoint URLsecret_key: HMAC secret key (bytes or base64 string)max_drift: Maximum allowed time drift in secondshandshake_points: Number of points for handshake functionhash_size: Size of hash in bytes
CryptoClient
Main client class with the following methods:
async with CryptoClient(config) as client- Create and manage client instanceawait client.authenticate()- Perform server handshakeawait client.encrypt_message(data)- Encrypt string or bytesawait client.decrypt_message(encrypted)- Decrypt dataawait client.close()- Close client session
CryptoFFI
Rust FFI wrapper class for high-performance cryptographic operations:
get_crypto_ffi()- Get or create the global CryptoFFI instancederive_key(seed, tick, salt, output_len)- Derive a key using Blake2b hashgenerate_keystream(key, salt, output_len)- Generate a keystream using ChaCha20 cipherencrypt_xor(data, keystream)- Encrypt data using XOR with a keystreamfast_hash(data, output_len)- Fast hash using Blake2b
Example usage:
from teeth_gnashing.crypto_ffi import get_crypto_ffi
crypto_ffi = get_crypto_ffi()
# Derive a key
key = crypto_ffi.derive_key(seed=12345, tick=100, salt=b"salt", output_len=32)
# Generate keystream
keystream = crypto_ffi.generate_keystream(key, salt=b"salt", output_len=64)
# Encrypt data
encrypted = crypto_ffi.encrypt_xor(data=b"Hello", keystream=keystream)
# Fast hash
hash_result = crypto_ffi.fast_hash(data=b"data", output_len=32)
Error Handling
The library provides specific exceptions for different error cases:
try:
async with CryptoClient(config) as client:
await client.authenticate()
encrypted = await client.encrypt_message("data")
except AuthenticationError:
print("Authentication failed")
except SnapshotError:
print("Invalid or expired snapshot")
except CryptoError:
print("General encryption error")
Security Considerations
- The secret key should be kept secure and should be the same on both server and client
- The server uses CORS middleware with "*" origins for development - configure appropriately for production
- Time synchronization between server and client is important
- The encryption method uses modular multiplication - suitable for data protection but not for critical security applications
Security Best Practices
-
Key Management
- Rotate secret keys regularly (recommended: every 90 days)
- Use a secure key management system in production
- Minimum key length: 256 bits
-
Server Configuration
- Configure CORS appropriately for production
- Use HTTPS in production
- Set appropriate rate limits
- Monitor for unusual patterns
-
Client Usage
- Don't store encrypted data longer than necessary
- Implement proper error handling
- Monitor time drift between client and server
- Use separate keys for different data classifications
-
Network Security
- Use TLS 1.3 or higher
- Implement proper firewall rules
- Monitor for unusual traffic patterns
- Set up intrusion detection
Performance Characteristics
- Encryption Speed: ~50MB/s on modern hardware
- Memory Usage: ~2MB base + ~1MB per active client
- Network Usage: ~100 bytes overhead per message
- Latency: ~5ms typical round-trip time
Compliance
The library's security properties make it suitable for:
- ✅ GDPR compliance (with proper key management)
- ✅ HIPAA compliance (non-PHI data)
- ✅ SOC 2 Type II requirements
- ✅ ISO 27001 controls
Not suitable for:
- ❌ Military/classified data
- ❌ Long-term storage of PHI
- ❌ Financial transaction data
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
License
See LICENSE file in the repository.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file teeth_gnashing-1.1.0.tar.gz.
File metadata
- Download URL: teeth_gnashing-1.1.0.tar.gz
- Upload date:
- Size: 528.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e074fa86929fabbc4b279b86464ca0e5e5518faf69cab29349e2d3b3cbf5d926
|
|
| MD5 |
2852a4ca0c1ca273b97415608e79293a
|
|
| BLAKE2b-256 |
543dad3034108be63346d51366a731f0af4afe14b4ace0e23d8c028bf1690d48
|
File details
Details for the file teeth_gnashing-1.1.0-py3-none-any.whl.
File metadata
- Download URL: teeth_gnashing-1.1.0-py3-none-any.whl
- Upload date:
- Size: 511.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2f00054451786a0ed7132a667200559453761015e7fb3db8ae2d30029ad14f02
|
|
| MD5 |
57efe277570ad75dc2020c84f082a6a3
|
|
| BLAKE2b-256 |
e9105eb565321f94124aa0bce9b68376ae1efcf327a948d8d2e62e5003d2e43f
|