Skip to main content

PQC Dual USB Library

PyPI version Python 3.8+ License: MIT Security: Post-Quantum

A comprehensive Python library for post-quantum cryptographic dual USB backup operations with advanced hardware security features and side-channel attack countermeasures.

SECURITY NOTICE — v0.15.6: This release patches multiple vulnerabilities found during a full code audit. Users on v0.15.5 or earlier should upgrade immediately: pip install --upgrade pqcdualusb

Fixes: path traversal in validate_path(), weakened scrypt KDF (n=2**15), timing leak in constant-time comparison, OverflowError in side-channel dummy ops, error-message information disclosure, backup restore using wrong KDF parameters, and dead hybrid key domain separator.

NOTE: This is a library package designed to be imported into your applications. For full documentation, diagrams, and architecture details visit the GitHub Repository.


Overview

The PQC Dual USB Library provides a robust, enterprise-grade solution for securing data against threats from both classical and quantum computers. It offers a functional API for developers to integrate post-quantum cryptography (PQC) into applications requiring secure data storage, especially for scenarios involving redundant backups on physical devices like USB drives.

The library is designed with a "secure-by-default" philosophy, automatically handling complex security operations like side-channel attack mitigation, secure memory management, and hybrid cryptographic schemes.


️ Architecture Overview

┌─────────────────────────────────────────────────────────────┐
│                     YOUR APPLICATION                        │
└─────────────────────┬───────────────────────────────────────┘
                      │ Import & Use
                      ▼
┌─────────────────────────────────────────────────────────────┐
│                  pqcdualusb Library                         │
├─────────────────────────────────────────────────────────────┤
│  storage.py    │  High-level API (init, rotate, verify)    │
│  backup.py     │  Backup creation and restoration          │
│  crypto.py     │  Classical crypto (AES-256-GCM, Argon2id) │
│  pqc.py        │  Post-quantum crypto (Kyber, Dilithium)   │
│  device.py     │  USB device validation                    │
│  audit.py      │  Tamper-evident logging                   │
└─────────────────────────────────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────────────────┐
│              Physical Storage (USB Drives)                  │
│  ┌──────────────┐              ┌──────────────┐            │
│  │  PRIMARY USB │              │  BACKUP USB  │            │
│  │  • Token     │◄────────────►│  • Token     │            │
│  │  • State     │   Redundant  │  • State     │            │
│  │  • Backup    │              │  • Backup    │            │
│  └──────────────┘              └──────────────┘            │
└─────────────────────────────────────────────────────────────┘

Key Features

Post-Quantum Security

  • NIST-standardized algorithms: Kyber1024 (KEM) and Dilithium3 (signatures)
  • Hybrid encryption: Combines classical AES-256-GCM with post-quantum KEMs
  • Future-proof: Protection against both classical and quantum computer attacks

Dual USB Architecture

  • Split secret design: Data is secured across two physical USB devices
  • Redundant storage: Automatic synchronization between primary and backup drives
  • Atomic operations: Ensures data integrity even during power failures

️ Security Features

  • Secure memory: Automatic wiping of sensitive data from RAM
  • Side-channel resistance: Constant-time operations to prevent timing attacks
  • Strong KDF: Argon2id protects passphrases against brute-force attacks
  • Tamper-evident logging: Comprehensive audit trail of all security events

Developer-Friendly

  • Simple API: Clean, functional interface with minimal boilerplate
  • Type hints: Full type annotations for better IDE support
  • Comprehensive tests: Extensive test suite ensures reliability
  • Cross-platform: Works on Windows, Linux, and macOS

Installation

pip install pqcdualusb

Backend Dependencies

The library requires at least one PQC backend. Choose one:

Option 1: Python backend (Recommended for most users)

pip install pqcdualusb[pqc]

Option 2: High-performance Rust backend

For advanced users who need maximum performance. See the GitHub README for Rust setup instructions.


Quick Start Guide

This example demonstrates the end-to-end process of creating and managing a secure dual USB backup using the library's functions.

Basic Usage

from pathlib import Path
from pqcdualusb.storage import init_dual_usb, rotate_token, verify_dual_setup
from pqcdualusb.backup import restore_from_backup

# Define your USB drive paths
primary_usb = Path("/media/usb1")  # Adjust to your system
backup_usb = Path("/media/usb2")   # Adjust to your system

# Your secret data (e.g., encryption key, master password)
secret_data = b"my-super-secret-master-key"
passphrase = "a-very-strong-and-unique-passphrase"

# 1. Initialize the dual USB backup system
init_info = init_dual_usb(
    token=secret_data,
    primary_mount=primary_usb,
    backup_mount=backup_usb,
    passphrase=passphrase
)
print(f" Initialized: {init_info['primary']}, {init_info['backup']}")

# 2. Verify the backup integrity
is_valid = verify_dual_setup(
    primary_mount=primary_usb,
    backup_mount=backup_usb,
    passphrase=passphrase
)
print(f" Backup verified: {is_valid}")

# 3. Rotate the secret (e.g., periodic key rotation)
new_secret = b"my-new-rotated-master-key"
rotate_info = rotate_token(
    token=new_secret,
    primary_mount=primary_usb,
    backup_mount=backup_usb,
    passphrase=passphrase,
    prev_rotation=0  # Increment on each rotation
)
print(f" Token rotated to rotation #{rotate_info['rotation']}")

# 4. Restore from backup (disaster recovery)
restore_path = Path("/media/usb_restore")
restored_token, _ = restore_from_backup(
    backup_file=Path(rotate_info['backup']),
    restore_primary=restore_path,
    passphrase=passphrase
)
print(f" Restored to: {restored_token}")

Complete Example with Error Handling

import os
from pathlib import Path
import tempfile
import shutil

# Import the necessary functions from the library
from pqcdualusb.storage import init_dual_usb, rotate_token
from pqcdualusb.backup import restore_from_backup
from pqcdualusb.crypto import verify_backup
from pqcdualusb.exceptions import (
    PassphraseMismatchError,
    BackupVerificationError,
    DeviceNotFoundError
)

# --- Setup: Create temporary directories to simulate USB drives ---
# In a real application, these paths would point to your actual USB drives.
tmp_dir = Path(tempfile.mkdtemp(prefix="pqc_usb_demo_"))
primary_path = tmp_dir / "PRIMARY"
backup_path = tmp_dir / "BACKUP"
primary_path.mkdir()
backup_path.mkdir()

print(f" Simulating USB drives:\n   Primary: {primary_path}\n   Backup:  {backup_path}\n")

# --- Core Variables ---
passphrase = "a-very-strong-and-unique-passphrase"
initial_secret = os.urandom(64)  # 512-bit secret

try:
    # 1. Initialize the Dual USB Backup
    print("Step 1: Initializing the dual USB backup...")
    init_info = init_dual_usb(
        token=initial_secret,
        primary_mount=primary_path,
        backup_mount=backup_path,
        passphrase=passphrase
    )
    print(f" Initialization complete.")
    print(f"   Primary: {init_info['primary']}")
    print(f"   Backup:  {init_info['backup']}\n")

    # 2. Verify the Backup Integrity
    print("Step 2: Verifying the backup file...")
    is_valid = verify_backup(
        Path(init_info['backup_file']),
        passphrase,
        initial_secret
    )
    if is_valid:
        print(" Backup integrity verified successfully.\n")
    else:
        raise BackupVerificationError("Backup verification failed!")

    # 3. Rotate the Token with a New Secret
    print("Step 3: Rotating the token with a new secret...")
    new_secret = os.urandom(64)
    rotate_info = rotate_token(
        token=new_secret,
        primary_mount=primary_path,
        backup_mount=backup_path,
        passphrase=passphrase,
        prev_rotation=0
    )
    print(f" Token rotation complete.")
    print(f"   Rotation number: {rotate_info['rotation']}")
    print(f"   New backup: {rotate_info['backup']}\n")

    # 4. Restore from the Latest Backup
    print("Step 4: Restoring the secret from the latest backup...")
    restore_path = tmp_dir / "RESTORED"
    restore_path.mkdir()
    
    restored_token_path, _ = restore_from_backup(
        backup_file=Path(rotate_info['backup']),
        restore_primary=restore_path,
        passphrase=passphrase
    )
    
    # Verify that the restored data matches the new secret
    restored_data = restored_token_path.read_bytes()
    assert restored_data == new_secret, "Restored data doesn't match!"
    print(f" Restore successful!")
    print(f"   Restored to: {restored_token_path}")
    print(f"   Data verified: {len(restored_data)} bytes match.\n")

except PassphraseMismatchError:
    print(" Error: Incorrect passphrase provided.")
except BackupVerificationError as e:
    print(f" Error: Backup verification failed - {e}")
except DeviceNotFoundError as e:
    print(f" Error: USB device not found - {e}")
except Exception as e:
    print(f" Unexpected error: {e}")
finally:
    # --- Cleanup ---
    shutil.rmtree(tmp_dir)
    print(" Cleanup complete.")

Security Properties

Cryptographic Stack

Component Algorithm Purpose
Key Derivation Argon2id Protects passphrase from brute-force attacks
Symmetric Encryption AES-256-GCM Fast, authenticated encryption for data
Post-Quantum KEM Kyber1024 Quantum-resistant key encapsulation
Post-Quantum Signature Dilithium3 Quantum-resistant digital signatures
HMAC HMAC-SHA256 Additional integrity verification

Security Workflow

User Passphrase
      │
      ▼
┌─────────────┐
│  Argon2id   │  ← Memory-hard KDF
└──────┬──────┘
       │
       ▼
  Master Key (256-bit)
       │
       ├─────────────────────┐
       │                     │
       ▼                     ▼
┌──────────────┐      ┌──────────────┐
│ AES-256-GCM  │      │  Kyber1024   │
│  Classical   │      │ Post-Quantum │
└──────┬───────┘      └──────┬───────┘
       │                     │
       └──────────┬──────────┘
                  │
                  ▼
          Encrypted Secret
                  │
                  ▼
┌─────────────────────────────┐
│       Dilithium3            │
│   Digital Signature         │
└─────────────────────────────┘
                  │
                  ▼
        USB Storage (Dual)

API Reference

Core Functions

init_dual_usb(token, primary_mount, backup_mount, passphrase)

Initialize a new dual USB backup system.

Parameters:

  • token (bytes): The secret data to protect (32-128 bytes recommended)
  • primary_mount (Path): Path to the primary USB drive
  • backup_mount (Path): Path to the backup USB drive
  • passphrase (str): User passphrase for encryption

Returns: Dictionary with initialization information


rotate_token(token, primary_mount, backup_mount, passphrase, prev_rotation)

Rotate the secret with a new value.

Parameters:

  • token (bytes): The new secret data
  • primary_mount (Path): Path to the primary USB drive
  • backup_mount (Path): Path to the backup USB drive
  • passphrase (str): User passphrase (must match initialization)
  • prev_rotation (int): Previous rotation number

Returns: Dictionary with rotation information


verify_dual_setup(primary_mount, backup_mount, passphrase)

Verify the integrity of the dual USB setup.

Parameters:

  • primary_mount (Path): Path to the primary USB drive
  • backup_mount (Path): Path to the backup USB drive
  • passphrase (str): User passphrase

Returns: True if verification passes, False otherwise


restore_from_backup(backup_file, restore_primary, passphrase)

Restore data from a backup file.

Parameters:

  • backup_file (Path): Path to the backup file
  • restore_primary (Path): Path where to restore the primary token
  • passphrase (str): User passphrase

Returns: Tuple of (restored_token_path, state_data)


Use Cases

1. Cryptocurrency Wallet Protection

Securely store master private keys across two USB devices with quantum-resistant encryption.

2. Enterprise Key Management

Manage encryption keys for organizational data with audit logging and rotation capabilities.

3. Password Manager Master Key

Protect the master encryption key for password management systems with redundant backups.

4. Secure Document Storage

Encrypt and backup sensitive documents with post-quantum security guarantees.

5. Hardware Security Module (HSM) Backup

Create offline backups of HSM keys with tamper-evident logging.


Advanced Configuration

Custom Argon2id Parameters

from pqcdualusb.crypto import derive_key

# High-security settings (slower but more secure)
key = derive_key(
    passphrase="my-passphrase",
    salt=b"random-salt-32-bytes",
    time_cost=4,      # Default: 3
    memory_cost=65536 # Default: 65536 (64 MB)
)

Secure Memory Wiping

from pqcdualusb.crypto import secure_wipe

sensitive_data = bytearray(b"secret-data")
# Use the data...
secure_wipe(sensitive_data)  # Automatically wipes on deletion

Documentation

For comprehensive documentation including:

  • Architecture diagrams (interactive Mermaid diagrams on GitHub)
  • Detailed API reference
  • Security analysis
  • Contribution guidelines
  • Threat model

Visit the GitHub Repository.


Contributing

Contributions are welcome! Please see the CONTRIBUTING.md file for guidelines.


Security

For security vulnerabilities, please email Johnsonajibi@gmail.com instead of using the issue tracker.

See SECURITY.md for our security policy.


License

This project is licensed under the MIT License. See the LICENSE file for details.


Acknowledgments

  • NIST for standardizing post-quantum cryptography algorithms
  • Open Quantum Safe (OQS) project for the liboqs library
  • The cryptography community for ongoing research and development

Support

Metadata

Release files for pqcdualusb 0.15.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pqcdualusb 0.15.6
File Size Uploaded
pqcdualusb-0.15.6.tar.gz 69.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pqcdualusb 0.15.6
File Interpreter ABI Platform
pqcdualusb-0.15.6-py3-none-any.whl Python 3 none any Details

Total release size: 122.2 kB

Release files / pqcdualusb-0.15.6.tar.gz

Download URL pqcdualusb-0.15.6.tar.gz
Size 69.9 kB
Tags Source
SHA-256 checksum
How to use checksums
6e3ee61195f57d25723d7f0e5554f33f4cbbfdabb6655f4eff1d74ab29bdb694
BLAKE2b-256 checksum
How to use checksums
b4dcdf80e88cc3e826d6a7c60531cf1346b186322b873740bfb4125b58f5b5b4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.9

Release files / pqcdualusb-0.15.6-py3-none-any.whl

Download URL pqcdualusb-0.15.6-py3-none-any.whl
Size 52.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bcc6204abfd77251ea64a2d90caac8b2b83931027e7666ec7844dc2efa037c6c
BLAKE2b-256 checksum
How to use checksums
ee7bb11695094edcd0f41eb7744fb8fb830026387d153f458e42b1a04b83c7f3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.9

Release history Release notifications | RSS feed

This release

0.15.6 This release

2 release files

0.15.5

2 release files

0.15.4

2 release files

0.15.3

2 release files

0.15.2

2 release files

0.15.1

2 release files

0.15.0

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release 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