Nostr.NIP49 (Nostr Lib v0.2.1) (nip49)

View Source

NIP-49: Private Key Encryption

Encrypt and decrypt private keys using password-based encryption. Uses scrypt for key derivation and XChaCha20-Poly1305 for encryption.

Examples

# Encrypt a private key
{:ok, ncryptsec} = NIP49.encrypt(private_key_hex, "password", log_n: 16)

# Decrypt
{:ok, private_key_hex} = NIP49.decrypt(ncryptsec, "password")

Key Security

The key_security option indicates how securely the key has been handled:

  • :insecure (0x00) - key has been handled insecurely (stored/copied unencrypted)
  • :secure (0x01) - key has NOT been handled insecurely
  • :unknown (0x02) - client doesn't track this (default)

Log N Parameter

The log_n parameter controls scrypt memory/time cost:

  • 16: ~64 MiB, ~100ms
  • 18: ~256 MiB
  • 20: ~1 GiB, ~2s
  • 21: ~2 GiB
  • 22: ~4 GiB

See: https://github.com/nostr-protocol/nips/blob/master/49.md

Summary

Functions

Decrypt an ncryptsec-encoded private key.

Encrypt a private key with a password.

Normalize a password to NFKC unicode format.

Types

key_security()

@type key_security() :: :insecure | :secure | :unknown

Functions

decrypt(ncryptsec, password)

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

Decrypt an ncryptsec-encoded private key.

Arguments

  • ncryptsec - bech32-encoded encrypted key (starts with "ncryptsec1")
  • password - password string (will be NFKC-normalized)

Returns

  • {:ok, private_key_hex} - 64-character hex-encoded private key
  • {:error, reason} - on failure

encrypt(private_key_hex, password, opts \\ [])

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

Encrypt a private key with a password.

Arguments

  • private_key_hex - 64-character hex-encoded private key
  • password - password string (will be NFKC-normalized)
  • opts - options

Options

  • :log_n - scrypt cost parameter (default: 16, range: 16-22)
  • :key_security - :insecure | :secure | :unknown (default: :unknown)

Returns

  • {:ok, ncryptsec} - bech32-encoded encrypted key
  • {:error, reason} - on failure

normalize_password(password)

@spec normalize_password(String.t()) :: binary()

Normalize a password to NFKC unicode format.

This ensures passwords can be entered identically across different systems.