MetamorphicCrypto (metamorphic_crypto v0.1.0)

Copy Markdown View Source

Zero-knowledge end-to-end encryption for Elixir.

MetamorphicCrypto provides NaCl-compatible cryptographic primitives powered by Rust NIFs with precompiled binaries — no Rust toolchain required.

Quick Start

# Generate keys
key = MetamorphicCrypto.generate_key()
{public_key, private_key} = MetamorphicCrypto.generate_keypair()

# Symmetric encryption (XSalsa20-Poly1305)
{:ok, ciphertext} = MetamorphicCrypto.encrypt("hello", key)
{:ok, "hello"} = MetamorphicCrypto.decrypt(ciphertext, key)

# Public-key encryption (X25519 sealed box)
{:ok, sealed} = MetamorphicCrypto.seal("secret", public_key)
{:ok, "secret"} = MetamorphicCrypto.unseal(sealed, public_key, private_key)

Modules

For full control, use the specialized modules directly:

Wire Format

All functions accept and return base64-encoded strings. Ciphertext produced by this library is byte-compatible with libsodium/NaCl and the metamorphic-crypto WASM module used in browser clients.

Summary

Functions

Decrypt a ciphertext back to a UTF-8 string.

Encrypt a UTF-8 string with a symmetric key.

Generate a random 32-byte symmetric key (base64-encoded).

Generate an X25519 keypair.

Encrypt a UTF-8 string to a recipient's public key (anonymous sealed box).

Decrypt a sealed box using the recipient's keypair.

Functions

decrypt(ciphertext, key)

@spec decrypt(ciphertext :: String.t(), key :: String.t()) ::
  {:ok, String.t()} | {:error, String.t()}

Decrypt a ciphertext back to a UTF-8 string.

Example

{:ok, "hello, world!"} = MetamorphicCrypto.decrypt(ciphertext, key)

encrypt(plaintext, key)

@spec encrypt(plaintext :: String.t(), key :: String.t()) ::
  {:ok, String.t()} | {:error, String.t()}

Encrypt a UTF-8 string with a symmetric key.

Uses XSalsa20-Poly1305 (NaCl secretbox). Returns base64-encoded ciphertext.

Example

key = MetamorphicCrypto.generate_key()
{:ok, ciphertext} = MetamorphicCrypto.encrypt("hello, world!", key)

generate_key()

@spec generate_key() :: String.t()

Generate a random 32-byte symmetric key (base64-encoded).

Example

key = MetamorphicCrypto.generate_key()

generate_keypair()

@spec generate_keypair() :: {String.t(), String.t()}

Generate an X25519 keypair.

Returns {public_key, private_key} as base64-encoded strings.

Example

{public_key, private_key} = MetamorphicCrypto.generate_keypair()

seal(plaintext, public_key)

@spec seal(plaintext :: String.t(), public_key :: String.t()) ::
  {:ok, String.t()} | {:error, String.t()}

Encrypt a UTF-8 string to a recipient's public key (anonymous sealed box).

The sender remains anonymous — only the recipient can decrypt.

Example

{public_key, _private_key} = MetamorphicCrypto.generate_keypair()
{:ok, sealed} = MetamorphicCrypto.seal("secret message", public_key)

unseal(ciphertext, public_key, private_key)

@spec unseal(
  ciphertext :: String.t(),
  public_key :: String.t(),
  private_key :: String.t()
) ::
  {:ok, String.t()} | {:error, String.t()}

Decrypt a sealed box using the recipient's keypair.

Example

{public_key, private_key} = MetamorphicCrypto.generate_keypair()
{:ok, sealed} = MetamorphicCrypto.seal("secret", public_key)
{:ok, "secret"} = MetamorphicCrypto.unseal(sealed, public_key, private_key)