Hex.pm Documentation

Elixir NIF bindings for tholos-pq, a post-quantum cryptography library. This package provides secure cryptographic primitives resistant to quantum computing attacks using Rustler NIFs.

Features

  • Post-Quantum Security: Implements ML-KEM-1024 (CRYSTALS-Kyber), a NIST-standardized post-quantum algorithm
  • Multi-Recipient Encryption: Encrypt once for multiple recipients
  • Sender Authentication: Digital signatures using Dilithium-3
  • High Performance: Native Rust implementation via Rustler NIFs
  • Simple API: Easy-to-use Elixir functions
  • Type-Safe: Comprehensive typespecs and documentation

Installation

Add ex_tholos_pq to your list of dependencies in mix.exs:

def deps do
  [
    {:ex_tholos_pq, "~> 0.1.0"}
  ]
end

Requirements

  • Elixir 1.14 or later
  • Rust toolchain (for compilation)
  • Erlang/OTP 24 or later

Usage

Basic Multi-Recipient Encryption

# Generate recipient keypairs
{:ok, {kid_alice, pub_alice}} = ExTholosPq.gen_recipient_keypair("Alice")
{:ok, {kid_bob, pub_bob}} = ExTholosPq.gen_recipient_keypair("Bob")

# Generate sender keypair
{:ok, {sid, sender_pub}} = ExTholosPq.gen_sender_keypair("Sender1")

# Encrypt message for multiple recipients
message = "Hello, post-quantum world!"
{:ok, ciphertext} = ExTholosPq.encrypt(message, sid, [pub_alice, pub_bob])

# Each recipient can decrypt
{:ok, plaintext_alice} = ExTholosPq.decrypt(ciphertext, kid_alice, [sender_pub])
{:ok, plaintext_bob} = ExTholosPq.decrypt(ciphertext, kid_bob, [sender_pub])

# Verify decryption
^message = plaintext_alice
^message = plaintext_bob

Practical Example: Secure Communication

defmodule SecureChannel do
  @doc """
  Establish a secure channel with sender authentication.
  """
  def establish_channel do
    # Generate keys
    {:ok, {kid, recipient_pub}} = ExTholosPq.gen_recipient_keypair("Recipient1")
    {:ok, {sid, sender_pub}} = ExTholosPq.gen_sender_keypair("Sender1")
    
    # Encrypt message
    message = "Secure message with authentication"
    {:ok, ciphertext} = ExTholosPq.encrypt(message, sid, [recipient_pub])
    
    # Decrypt and verify sender
    {:ok, plaintext} = ExTholosPq.decrypt(ciphertext, kid, [sender_pub])
    
    {:ok, plaintext}
  end
end

API Reference

gen_recipient_keypair/1

Generates a new recipient keypair for post-quantum encryption.

Parameters:

  • kid - Key identifier string for the recipient

Returns:

  • {:ok, {kid, public_key}} on success where public_key is CBOR-encoded
  • {:error, reason} on failure

Note: The private key is stored internally in the NIF and referenced by the key identifier.

gen_sender_keypair/1

Generates a new sender keypair for signing encrypted messages.

Parameters:

  • sid - Sender identifier string

Returns:

  • {:ok, {sid, public_key}} on success where public_key is CBOR-encoded
  • {:error, reason} on failure

Note: The private key is stored internally in the NIF and referenced by the sender identifier.

encrypt/3

Encrypts a message for multiple recipients with sender authentication.

Parameters:

  • message - The message to encrypt (binary or string)
  • sender_id - The sender's identifier (from gen_sender_keypair/1)
  • recipient_pub_keys - List of recipient public keys (CBOR-encoded)

Returns:

  • {:ok, ciphertext} on success
  • {:error, reason} on failure

decrypt/3

Decrypts a message for a specific recipient.

Parameters:

  • ciphertext - The encrypted message
  • kid - The recipient's key identifier (must have been generated with gen_recipient_keypair/1)
  • allowed_sender_pub_keys - List of allowed sender public keys for verification (CBOR-encoded)

Returns:

  • {:ok, plaintext} on success
  • {:error, reason} on failure

Security Considerations

  • Key Storage: Secret keys should be stored securely and never transmitted
  • Quantum Resistance: ML-KEM provides security against both classical and quantum computer attacks
  • Shared Secrets: Use the shared secrets as keys for authenticated encryption schemes
  • Key Lifecycle: Generate new keypairs for each session when appropriate

Development

Building from Source

# Install dependencies
mix deps.get

# Compile (includes Rust NIF compilation)
mix compile

# Run tests
mix test

Running Tests

mix test

Documentation

Generate documentation locally:

mix docs

Performance

The library provides high-performance cryptographic operations through native Rust code:

  • Key generation: ~100k ops/sec
  • Encapsulation: ~80k ops/sec
  • Decapsulation: ~90k ops/sec

Benchmarks may vary based on hardware and system configuration.

About Post-Quantum Cryptography

Post-quantum cryptography (PQC) refers to cryptographic algorithms that are secure against attacks by both classical and quantum computers. As quantum computers become more powerful, traditional public-key cryptography schemes (like RSA and ECC) become vulnerable.

ML-KEM (Module-Lattice-Based Key Encapsulation Mechanism) is one of the NIST-standardized post-quantum algorithms designed to replace current key exchange mechanisms.

Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Acknowledgments

  • Built on tholos-pq
  • Uses Rustler for Elixir-Rust interoperability
  • Implements NIST-standardized ML-KEM algorithm