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"}
]
endUsage
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
Decrypts a message for a specific recipient.
Parameters
ciphertext- The encrypted messagekid- The recipient's key identifier (must have been generated withgen_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
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 (fromgen_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
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
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