ExTholosPq (ExTholosPq v0.2.0)

Copy Markdown View Source

Elixir NIF bindings for tholos-pq, a post-quantum multi-recipient encryption library.

This module provides access to post-quantum secure cryptographic primitives through Native Implemented Functions (NIFs) written in Rust using the tholos-pq library.

Algorithm Suite

  • Key Encapsulation: ML-KEM-1024 (Kyber-1024) for per-recipient key wrapping
  • Symmetric Encryption: XChaCha20-Poly1305 for payload encryption
  • Digital Signatures: Dilithium-3 for sender authentication
  • Wire Format: Canonical CBOR with versioning

Installation

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

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

Usage

The library provides functions for multi-recipient encryption with sender authentication.

Example

# Recipient keypairs: `{:ok, {kid, public_key}}`
{:ok, {alice_kid, pub_a}} = ExTholosPq.gen_recipient_keypair("Alice")
{:ok, {bob_kid, pub_b}} = ExTholosPq.gen_recipient_keypair("Bob")

# Sender: `{:ok, {sender_id, sender_public}}`
{:ok, {sender_id, sender_pub}} = ExTholosPq.gen_sender_keypair("Sender1")

message = "Hello, post-quantum world!"
{:ok, ciphertext} = ExTholosPq.encrypt(message, sender_id, [pub_a, pub_b])

# Decrypt with recipient `kid` and allowed sender public keys
{:ok, plaintext_a} = ExTholosPq.decrypt(ciphertext, alice_kid, [sender_pub])
{:ok, plaintext_b} = ExTholosPq.decrypt(ciphertext, bob_kid, [sender_pub])

Summary

Functions

Decrypts a message for a specific recipient.

Encrypts a message for multiple recipients with sender authentication.

Generates a new recipient keypair for post-quantum encryption.

Generates a new sender keypair for signing encrypted messages.

Functions

decrypt(ciphertext, kid, allowed_sender_pub_keys)

@spec decrypt(binary(), String.t(), [binary()]) ::
  {:ok, binary()} | {:error, String.t()}

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

Examples

iex> {:ok, {kid, pub}} = ExTholosPq.gen_recipient_keypair("Alice")
iex> {:ok, {sid, sender_pub}} = ExTholosPq.gen_sender_keypair("Sender")
iex> {:ok, ct} = ExTholosPq.encrypt("secret", sid, [pub])
iex> {:ok, plain} = ExTholosPq.decrypt(ct, kid, [sender_pub])
iex> plain == "secret"
true

encrypt(message, sender_id, recipient_pub_keys)

@spec encrypt(binary(), String.t(), [binary()]) ::
  {:ok, binary()} | {:error, String.t()}

Encrypts a message for multiple recipients with sender authentication.

This function encrypts a message that can be decrypted by any of the specified recipients. The sender's signature ensures authenticity.

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

Examples

iex> {:ok, {_kid, pub_a}} = ExTholosPq.gen_recipient_keypair("Alice")
iex> {:ok, {sid, _pub}} = ExTholosPq.gen_sender_keypair("Sender")
iex> {:ok, ct} = ExTholosPq.encrypt("secret", sid, [pub_a])
iex> is_binary(ct)
true

gen_recipient_keypair(kid)

@spec gen_recipient_keypair(String.t()) ::
  {:ok, {String.t(), binary()}} | {:error, String.t()}

Generates a new recipient keypair for post-quantum encryption.

The keypair is stored internally in the NIF and referenced by the key identifier.

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

Examples

iex> {:ok, {kid, pub_key}} = ExTholosPq.gen_recipient_keypair("recipient1")
iex> is_binary(kid) and is_binary(pub_key)
true

gen_sender_keypair(sid)

@spec gen_sender_keypair(String.t()) ::
  {:ok, {String.t(), binary()}} | {:error, String.t()}

Generates a new sender keypair for signing encrypted messages.

The keypair is stored internally in the NIF and referenced by the sender identifier.

Parameters

  • sid - Sender identifier string

Returns

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

Examples

iex> {:ok, {sid, pub_key}} = ExTholosPq.gen_sender_keypair("sender1")
iex> is_binary(sid) and is_binary(pub_key)
true