Hoot uses NIP-59 gift wrapping to ensure complete privacy and metadata protection for all email messages. Each message is individually encrypted for every recipient, preventing relay operators and third parties from seeing who is communicating with whom.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/chakanysystems/hoot/llms.txt
Use this file to discover all available pages before exploring further.
NIP-59 gift wrapping overview
NIP-59 defines a three-layer encryption scheme that protects both message content and metadata:- Rumor: The actual mail event (kind 2024) containing the message content, subject, recipients, and threading information
- Seal: The rumor encrypted to the recipient using NIP-44 encryption and signed by the sender
- Gift wrap: The seal encrypted again and signed by a random ephemeral key to hide the sender’s identity from relays
- A gift wrap event (kind 1059) with a random public key as the author
- A
ptag indicating the intended recipient - A randomized timestamp
- Encrypted content that can only be decrypted by the recipient
NIP-59 provides stronger privacy guarantees than traditional NIP-04 encrypted DMs by hiding sender metadata and using modern encryption (NIP-44 instead of NIP-04).
Encryption flow
When a user sends an email message, Hoot creates individual encrypted events for each recipient. This process is handled by theMailMessage::to_events() method in src/mail_event.rs:24.
Creating the base mail event
First, Hoot constructs a kind 2024 event with all message metadata:Individual encryption per recipient
Hoot then creates a separate gift-wrapped event for each recipient:EventBuilder::gift_wrap() performs the three-layer encryption:
- Creates the rumor (unsigned kind 2024 event)
- Encrypts the rumor to the recipient and wraps it in a seal (kind 13)
- Encrypts the seal with a random ephemeral key and wraps it in a gift wrap (kind 1059)
Sending wrapped events
Each wrapped event is sent to all connected relays. Since each recipient gets a unique gift wrap with a different ephemeral key, relay operators cannot correlate events or determine that they came from the same sender.Decryption flow
When Hoot receives a gift-wrapped event from a relay, it performs the reverse process to extract and verify the message.Gift wrap subscription
Hoot subscribes to gift wraps addressed to any of its loaded accounts:p tag matching any of the user’s public keys.
Unwrapping process
When a gift wrap arrives, Hoot unwraps it using the recipient’s private key:Verification and storage
After unwrapping, Hoot performs security checks before storing the message:Event verification
All received events undergo cryptographic verification:- The event ID is correctly calculated from the event content
- The signature matches the claimed author’s public key
- The event hasn’t been tampered with during transmission
Security considerations
Metadata protection
Gift wrapping protects metadata in several ways:- Sender anonymity: The gift wrap is signed by a random ephemeral key, not the actual sender
- Timing obfuscation: Gift wrap timestamps are randomized (though Hoot currently uses the same timestamp for all recipients)
- Recipient privacy: Only the intended recipient can decrypt the seal to see the actual sender
Forward secrecy
While NIP-44 encryption is secure, it does not provide forward secrecy. If a recipient’s private key is compromised, all past messages encrypted to that key can be decrypted. Consider implementing key rotation for long-term security.Relay trust
Relays can:- See which public keys are receiving messages (from
ptags) - Correlate timing of events
- Perform traffic analysis
- Decrypt message contents
- Determine who sent a message
- Link gift wraps to the same sender
For maximum privacy, use Tor or a VPN when connecting to Nostr relays to prevent IP address correlation with public keys.