herolib-crypt 0.3.5

Simple and secure asymmetric cryptography: signing and encryption using Ed25519
Documentation

Herolib Crypt

Simple and secure cryptography library for Rust.

Features

  • Asymmetric Cryptography

    • Ed25519 digital signatures (signing/verification)
    • X25519 ECDH encryption (encrypt/decrypt)
    • Dual keypair architecture (separate keys for signing and encryption)
  • Symmetric Cryptography

    • XChaCha20-Poly1305 authenticated encryption
    • Argon2id password-based key derivation
    • Secure key handling with automatic memory zeroization

Quick Start

Asymmetric: Generate a Keypair

use herolib_crypt::generate_keypair;

let keypair = generate_keypair()?;

// For signing (Ed25519)
println!("Signing Private: {}", keypair.private_key_hex);
println!("Signing Public:  {}", keypair.public_key_hex);

// For encryption (X25519)
println!("Encryption Private: {}", keypair.encryption_private_key_hex);
println!("Encryption Public:  {}", keypair.encryption_public_key_hex);

Asymmetric: Sign and Verify Messages

use herolib_crypt::{generate_keypair, sign_message, verify_signature};

// Generate keypair
let keypair = generate_keypair()?;

// Sign a message (uses Ed25519 signing key)
let message = "Hello, world!";
let signature = sign_message(message, &keypair.private_key_hex)?;

// Verify the signature (uses Ed25519 public key)
let is_valid = verify_signature(message, &signature, &keypair.public_key_hex)?;
assert!(is_valid);

Asymmetric: Encrypt and Decrypt Messages

use herolib_crypt::{generate_keypair, encrypt_message, decrypt_message};

// Alice and Bob generate their keypairs
let alice = generate_keypair()?;
let bob = generate_keypair()?;

// Alice encrypts a message for Bob (uses Bob's X25519 encryption public key)
let message = "Secret message";
let encrypted = encrypt_message(message, &bob.encryption_public_key_hex)?;

// Bob decrypts with his X25519 encryption private key
let decrypted = decrypt_message(&encrypted, &bob.encryption_private_key_hex)?;
assert_eq!(decrypted, message);

Symmetric: Password-Based Encryption (Recommended)

use herolib_crypt::symmetric::{encrypt_with_password, decrypt_with_password};

// Encrypt with just a password - salt is handled automatically!
let encrypted = encrypt_with_password(b"secret data", "my-password")?;

// Decrypt with the same password
let decrypted = decrypt_with_password(&encrypted, "my-password")?;
assert_eq!(decrypted, b"secret data");

Symmetric: String Encryption

use herolib_crypt::symmetric::{encrypt_string, decrypt_string};

// Encrypt string to base64
let encrypted = encrypt_string("Hello, World!", "my-password")?;

// Decrypt back to string
let decrypted = decrypt_string(&encrypted, "my-password")?;
assert_eq!(decrypted, "Hello, World!");

Symmetric: Advanced - Random Key

use herolib_crypt::symmetric::{EncryptionKey, Cipher};

// Generate a random key (for programmatic key management)
let key = EncryptionKey::generate();
let cipher = Cipher::new(key);

// Encrypt and decrypt
let encrypted = cipher.encrypt(b"secret data")?;
let decrypted = cipher.decrypt(&encrypted)?;

API Reference

Asymmetric Key Generation

  • generate_keypair() -> CryptoResult<KeyPair> - Generate a new dual keypair (Ed25519 + X25519)
  • public_key_from_private(private_key_hex) -> CryptoResult<String> - Derive Ed25519 public key
  • encryption_public_key_from_private(encryption_private_key_hex) -> CryptoResult<String> - Derive X25519 public key

Asymmetric Signing (Ed25519)

  • sign_message(message, private_key_hex) -> CryptoResult<String> - Sign a message
  • verify_signature(message, signature_hex, public_key_hex) -> CryptoResult<bool> - Verify a signature

Asymmetric Encryption (X25519 + ChaCha20-Poly1305)

  • encrypt_message(message, recipient_encryption_public_key_hex) -> CryptoResult<String> - Encrypt for a recipient
  • decrypt_message(encrypted_hex, encryption_private_key_hex) -> CryptoResult<String> - Decrypt a message

Symmetric Encryption (Simple API)

  • encrypt_with_password(data, password) -> SymmetricResult<Vec<u8>> - Encrypt with password
  • decrypt_with_password(encrypted, password) -> SymmetricResult<Vec<u8>> - Decrypt with password
  • encrypt_string(text, password) -> SymmetricResult<String> - Encrypt string to base64
  • decrypt_string(encrypted_base64, password) -> SymmetricResult<String> - Decrypt base64 to string

Symmetric Encryption (Advanced API)

  • EncryptionKey::generate() -> EncryptionKey - Generate a random 256-bit key
  • Cipher::new(key) -> Cipher - Create a cipher
  • Cipher::encrypt(plaintext) -> SymmetricResult<Vec<u8>> - Encrypt data
  • Cipher::decrypt(ciphertext) -> SymmetricResult<Vec<u8>> - Decrypt data

Key Formats

All keys are represented as hex strings:

Key Type Size (bytes) Hex Length
Ed25519 Private Key 32 64 chars
Ed25519 Public Key 32 64 chars
X25519 Private Key 32 64 chars
X25519 Public Key 32 64 chars
Ed25519 Signature 64 128 chars

Security Properties

Signing (Ed25519)

  • Deterministic: Same message + key = same signature
  • Unforgeable: Cannot create valid signature without the private key
  • Verifiable: Anyone with public key can verify authenticity

Encryption (X25519 + ChaCha20-Poly1305)

  • Confidential: Only recipient's private key can decrypt
  • Authenticated: Tampering is detected (AEAD)
  • Forward Secure: Each message uses ephemeral keys

Symmetric (XChaCha20-Poly1305)

  • Authenticated: Tampering detection via Poly1305 MAC
  • Large Nonce: 192-bit nonces prevent collisions
  • Memory Safe: Keys are automatically zeroized on drop

Dependencies

  • ed25519-dalek - Ed25519 signatures
  • curve25519-dalek - X25519 key exchange
  • chacha20poly1305 - AEAD encryption
  • sha3 - Key derivation (KDF)
  • argon2 - Password-based key derivation
  • zeroize - Secure memory handling

Testing

Run all tests:

cargo test -p herolib-crypt

Or use the helper script:

./run.sh

Building

./build.sh

Specifications

See the detailed specifications:

License

Apache-2.0