Nostr.NIP44 (Nostr Lib v0.2.0) (crypto) (nip44)

View Source

NIP-44 Versioned Encrypted Payloads

Implements version 2 encryption: secp256k1 ECDH, HKDF, ChaCha20, HMAC-SHA256

Defined in NIP 44 https://github.com/nostr-protocol/nips/blob/master/44.md

Summary

Functions

Decrypts a payload using a pre-computed conversation key.

Decrypts a payload using the recipient's secret key.

Encrypts plaintext using a pre-computed conversation key.

Encrypts plaintext for a recipient using their public key.

Encrypts plaintext using a conversation key and specific nonce.

Computes the conversation key between two parties.

Derives message-specific keys from conversation key and nonce.

Functions

decrypt(payload, conversation_key)

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

Decrypts a payload using a pre-computed conversation key.

Parameters

  • payload: Base64-encoded encrypted payload
  • conversation_key: 32-byte conversation key (raw bytes)

Returns

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

decrypt(payload, seckey, pubkey)

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

Decrypts a payload using the recipient's secret key.

Parameters

  • payload: Base64-encoded encrypted payload
  • seckey: Recipient's secret key (hex-encoded)
  • pubkey: Sender's public key (hex-encoded, x-only)

Returns

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

encrypt(plaintext, conversation_key)

@spec encrypt(String.t(), binary()) :: binary()

Encrypts plaintext using a pre-computed conversation key.

Parameters

  • plaintext: The message to encrypt (1-65535 bytes)
  • conversation_key: 32-byte conversation key (raw bytes)

Returns

Base64-encoded encrypted payload

encrypt(plaintext, seckey, pubkey)

@spec encrypt(String.t(), binary(), binary()) :: binary()

Encrypts plaintext for a recipient using their public key.

Parameters

  • plaintext: The message to encrypt (1-65535 bytes)
  • seckey: Sender's secret key (hex-encoded)
  • pubkey: Recipient's public key (hex-encoded, x-only)

Returns

Base64-encoded encrypted payload

encrypt_with_nonce(plaintext, conversation_key, nonce)

@spec encrypt_with_nonce(String.t(), binary(), binary()) :: binary()

Encrypts plaintext using a conversation key and specific nonce.

This function is primarily for testing with deterministic nonces. In production, use encrypt/2 or encrypt/3 which generate random nonces.

Parameters

  • plaintext: The message to encrypt (1-65535 bytes)
  • conversation_key: 32-byte conversation key (raw bytes)
  • nonce: 32-byte nonce (raw bytes)

Returns

Base64-encoded encrypted payload

get_conversation_key(seckey, pubkey)

@spec get_conversation_key(binary(), binary()) :: binary()

Computes the conversation key between two parties.

The conversation key is symmetric: get_conversation_key(a, B) == get_conversation_key(b, A)

Parameters

  • seckey: Secret key (hex-encoded)
  • pubkey: Public key (hex-encoded, x-only)

Returns

32-byte conversation key (raw bytes)

get_message_keys(conversation_key, nonce)

@spec get_message_keys(binary(), binary()) :: {binary(), binary(), binary()}

Derives message-specific keys from conversation key and nonce.

Parameters

  • conversation_key: 32-byte conversation key (raw bytes)
  • nonce: 32-byte nonce (raw bytes)

Returns

Tuple of {chacha_key, chacha_nonce, hmac_key}