Skip to main content

Privacy on Nostr

Nostr has been taking the Bitcoin world by storm over the past few months, and with it comes a chance to correct the mistakes of the current social media paradigm. While the actual use-cases for Nostr are practically limitless, the overwhelming majority of usage today has come in the form of a censorship-resistant and Lightning-centric social media platform built around user choice. Nostr takes a novel approach to its network design, and we want to be sure that Nostr users like yourself are well-equipped to use Nostr in a way that preserves your privacy and security from the start.

What is Nostr?

Nostr is a new protocol (think TCP/IP or HTTP, like what your browser uses) that focuses on the very simple goal of publishing and reading events in a distributed way. It does this by allowing anyone to run a client (how you read or write events) and/or a relay (how you share events with others). Each relay communicates only with users who choose to send or receive events using it and not with other relays, a significant departure from Bitcoin’s model – called a “gossip” model, where all servers share events with all other servers they know – and the approach taken by the Fediverse, where servers that can communicate and share events but do not have to.

This new protocol is extremely simple and diverse by design, allowing a plethora of apps and services to be built on top of it, but the most traction so far has come from its use as a social media platform. Nostr provides a strong base for a user-centric social media platform, as you, the user, have complete control over where your posts are shared (which relays), which users you see or don’t see in your feed (by following specific users or only reading from specific relays), and what client you choose to use to post or consume content.

When you post to Nostr, your client simply translates the content you write into a format called JSON, signs it with your private key to prove it’s from you and cannot be tampered with, and publishes it to relays you’ve selected. Everyone who follows you and connects with relays you publish to will see your content in their timeline exactly as intended. When you browse Nostr, you see only content from people you choose to follow, in chronological order, without advertisements or algorithmic wizardry causing issues. Simple. Clear. Social media as it should be.

If you want to learn more about Nostr, you can read some excellent resources below:

Nostr’s privacy tradeoffs

The proxied-relay approach that Nostr takes is excellent at decentralization and censorship-resistance, but one thing it doesn’t do well is protect a user’s privacy by default. Because you need to connect to many different relays to communicate with most people using Nostr today, you’ll be exposing your IP address (your unique identifier on the internet) to every relay you connect to, directly associating your IP address to your digital identity on Nostr. This could be used to connect your Nostr identity with other online activity, connect multiple Nostr identities you control together without your consent, and even give the relay operators a rough idea of where you live.

Another key issue with the approach taken by Nostr is that there is no central server used for hosting media like pictures and videos, so users have to upload media to a server of their choice to share it. As a result, your Nostr client will have to connect to any number of untrusted servers hosting media to properly show you pictures and videos in your feed. While this does remove trust in a centralized server, it also exposes you to tracking or malicious content from third parties that you may or may not want to connect to. Thankfully, most Nostr clients are starting to prevent loading of content from untrusted sources, but this still poses a broad risk to your privacy and security.

Lastly, there are two more minor privacy caveats with Nostr that are important to know, but don’t necessarily present a problem for the average user. The first is that direct messages in Nostr use public events where the message content is encrypted to the recipient’s private key, meaning that while all message content is private by design, the metadata about who you talk to, when, is completely public information. The second minor privacy issue in Nostr is that Zaps, a Lightning tip sent for a specific note on Nostr to show that you loved the post, are public by default and reveal the amount, timing, and any comment included to the entire Nostr network. While this is the default, clients like Damus and Amethyst are working on ways to allow you to send “private Zaps” which encrypt all information except time and amount to the recipient, hiding the sender and any comments from everyone else on Nostr.

Protecting your keys

One of the foundational ways to preserve your privacy involves making sure that no one else ever gets access to your private keys. In Nostr, in order to access your account, post notes, and respond to others, you have to be able to sign events on the Nostr network with the correlated private key for your account. That means that every Nostr app requires a way to sign using your private key, leading to less than ideal security with many of the current approaches. 

When approaching Nostr, you should aim to minimize how often you expose your private key to apps and restrict access as much as possible to your private key. In order to limit how often you expose your private key to apps, the best way on mobile is to choose a client, sign in with your private key, and stick with it if at all possible. Unfortunately, you’ll currently have to copy and paste (or manually type out) your private key (the key starting with ‘nsec’) to sign into mobile apps, but won’t need access to your private key on mobile after the initial sign-in.

When you’re using desktop apps, particularly web apps like iris.to or nostr.social, you can limit exposure of your private keys by using a browser extension to store your private key in an encrypted manner and authorize access to it. That way, you can paste your private key into a trusted extension once and use any web app you like after that without directly exposing your private key to each app. We recommend the most popular and trusted extensions below:

  • Nos2x (Chrome/Brave-only)
    • Nos2x is an extremely simple extension for key management without any bells or whistles
    • If you’re on Firefox, you can use this fork
  • Alby
    • The popular Alby extension added native Nostr key support, and pairs well with it’s Lightning functionality for Nostr Zaps
  • Flamingo (Chrome/Brave-only)
    • Flamingo is another simple Nostr extension with a beautiful UI
Logging into nostr.social with the Alby extension

While we’re working on some unique ways to leverage Passport for Nostr key management, the best way to store your private key for Nostr will be to treat it like a sensitive password and store it in an end-to-end encrypted password manager like Bitwarden. Bitwarden is an amazing tool for managing your online life through storing usernames, passwords, and email addresses for all of your accounts and auto-filling them via their browser extension, and Nostr private keys are a great fit. Bitwarden is free and open-source, and uses strong end-to-end encryption to ensure that even if Bitwarden was malicious they couldn’t view what sites you access or any of your login information. You can easily store your Nostr private key as an item in Bitwarden, allowing you to enter it as needed on desktop or mobile easily.

Protecting your IP address

The next key step to take is to prevent relays and media hosting servers from learning your true IP address, and the easiest way to do that is to use a trustworthy and dependable VPN provider. While a VPN provider isn’t a perfect solution to network privacy issues, it does allow you to shift the trust from your network provider (home ISP, mobile carrier, etc.) to a 3rd-party you trust more than them (and that don’t have your personal information or address). Once you’re using a VPN, you’re actively preventing the sites, apps, and tools you interact with online from learning your home IP address and connecting all of your activities back to you.

Our team is a big fan and many of us are users of two well-known VPN providers in the space which we’ve linked below for easy reference. Both IVPN and Mullvad accept Bitcoin (on-chain and Lightning) for subscriptions and require no information from you to create an account, not even an email address!

Using IVPN on desktop via their native app

Please note that we have no direct affiliation with either provider and don’t profit off of your use of either, we just love their approaches and use them ourselves.

Choosing the right relays

Nostr takes the idea of self-sovereignty and personal responsibility as a core ethos, as you are in complete control of your data and your usage of the protocol. As each Nostr relay you connect with gets information about your IP address (hopefully just a VPN address if you followed the above recommendation), when you’re using Nostr, when you publish events, and who you interact with. While much of this information is public – and has to be so for a useful social media platform – being able to selectively reveal this information is an important benefit of Nostr.

While relay selection is certainly a personal preference as it changes what notes you can view and who can see your notes, limiting it to the bare minimum provides better privacy and generally better performance in your Nostr clients at the same time. The use of paid relays can also be helpful, as they limit spam and access to your public data behind a paywall. The list of relays and their usefulness changes frequently at this early stage in the network’s development, but we’ll provide a few recommendations below that are widely recommended:

  • nostr.wine
    • Nostr.wine is a paid relay that has a stellar reputation and a unique additional service that paid users can leverage
    • Their filter/broadcast service allows you to publish events to the most popular relays through their relay
      • More on their filter/broadcast service here
  • nostr.mutinywallet.com
    • This relay is actually just a proxy that publishes events for you to all known relays using a tool called Blastr
    • This can be a great single write-only relay, ensuring your notes make it to pretty much the entire Nostrverse
    • Note that if you do use only this relay proxy to write to, you do open up censorship as they could choose not to relay your events for some reason! If that’s a concern for you, consider writing to multiple relays.
  • relay.nostr.band
    • This relay applies a trust-based spam filter to all events, providing a much better global feed than most and serves as a good read-only relay

Adding these relays to your client will vary depending on which client you choose, so please check out the documentation of your favorite client or check in the settings! You usually will have to add a ‘wss://’ before the relay address as well.

Getting started with Nostr

If you’ve read through this post and want to jump into using Nostr, we’ve learned a few things as team members have jumped onto the Nostr train. We’ll drop recommendations based on this below in a rapid-fire style, but feel free to reach out with questions and we’d be happy to help point you in the right direction!

Choosing a client

Choosing a client is ultimately down to personal preference and depends on what platform you use (Android, iOS, Windows, etc.), but some of our favorites are:

  • Amethyst (Android-only)
    • Vitor Pamplona, the lead dev, has done a fantastic job building out Amethyst and it feels like he releases a new major improvement every day. Amethyst is a fantastic client top-to-bottom, and is what both Seth For Privacy and Bitcoin QnA use on our team.
  • Damus (iOS-only)
    • Damus has become a huge part of Nostr adoption, driving new features and bringing a snazzy Nostr experience to the Apple crowd.
  • snort.social (web client)
    • snort.social is a great client for using on desktop or on mobile as a progressive web app, and is quickly improving and innovating as well.
  • Iris.to (web client)
    • Iris.to is another great web client and is quickly becoming the go-to for web.
Amethyst on Android’s UI as of v0.24.0

Verifying your Nostr account

Nostr takes a very different approach to Twitter, allowing all users to be “verified” through the use of DNS and a simple web server. While we definitely recommend pursuing the fully self-sovereign approach to verifying your account on Nostr and hosting it yourself, we recognize that not everyone can do that so we’ve included some trusted Nostr verification services as well below:

  • For more info on verification, you can read more here
  • NIP-05 Simple Guide (self-hosted)
    • This guide walks you through the process of setting up verification start to finish, and is recommended widely.
  • Easy-nip5 (self-hosted)
    • Our very own Seth For Privacy has created an easy-to-use way to do your own self-hosted verification using Docker, allowing you to quickly set up the full verification on a VPS with your own domain name
  • Bitcoiner.chat (trusted)
    • Bitcoin QnA has set up an easy to use tool to get a verified account using his domain, bitcoiner.chat, for free! This is an excellent solution for those of you who can’t self-host your own verification, and is provided by one of the most trustworthy people in the space, if we do say so ourselves.
  • Nostr Plebs! (trusted)
    • Nostr Plebs is one of the original NIP-05 verifiers, and is run by a fantastic Nostrich named Derek Ross.
A NIP-05 verified account, see the purple check-mark

Conclusion

We’re thrilled to watch the progress being made in a Bitcoin-centric social media platform that puts the user first, as it embodies so much of what Foundation is all about. We hope that this short guide helps you get started with Nostr in a way that allows you to preserve your privacy and security from the start, and we look forward to seeing you all over there.

If you’d like to follow us on Nostr you can find our official company account along with a few of our team members below!

  • Foundation
    • foundationdevices.com
    • npub1s0vtkgej33n7ec4d7ycxmwt78up8hpfa30d0yfksrshq7t82mchqynpq6j
  • Seth for Privacy
  • BitcoinQnA
  • nickmonad
    • nickmonad.blog
    • npub1tln5mjd8xjd7rqnfqp7cu77lwkvcd89kwllr7fu5a0vzru2xl6qssuq0v6
  • Jack Smith
    • npub1d8mwl982z209f3zf856t87z36gmavgctw59r30pxr880emxmjy6sq4qtwj

Making sense of stealth addresses

In our previous blog post we briefly touched on how important it is to protect the privacy of the recipient in a transaction. Today we’re going to take a closer look at a specific way to preserve privacy – “reusable payment codes”, otherwise known as “stealth addresses.” While the concept of the reusable payment code is not a new one – a form of them was officially proposed as a Bitcoin Improvement Proposal (“BIP”) in 2015 by Peter Todd – they’ve become a popular topic again after two recent proposals on new ways to implement them.

Today we’ll walk through why we need reusable payment codes, how the current approaches differ, and how you can start using them today.

Why do we need reusable payment codes?

If you’ve ever had to receive Bitcoin multiple times from the same person before, you’ll know that there is a seemingly simple choice to make – do you generate a new address for them each time (and communicate it somehow), or do you tell them to re-use the same address? If you choose to generate a new address each time, you have to actively communicate somehow, send them the address, and hope they copy and paste it correctly each time. If you instead choose for them to reuse a single address, you harm the privacy of both participants in order to simplify repeat payments.

For a real-world example, consider the case of wanting to accept donations as a political dissident. If you choose to post a single static Bitcoin address, you put every donor (and yourself) at risk of trivial surveillance in order to simplify the process for you and your donors. If you choose to generate a new address for each donor, you have to run extra infrastructure like BTCPay Server or SatSale, increasing the difficulty exponentially and requiring some technical know-how. We’ve even seen a recent example of this in donations raised by Russian opposition leader Alexey Navalny, easily visible to anyone with a blockchain explorer and actively surveilled by the Russian pro-Putin government.

The dilemma in both of these simple cases is exactly what reusable payment codes seek to solve, allowing you to provide a single static string of characters (a “code”) that can be reused as many times as necessary – even by multiple senders – without sacrificing privacy or requiring online communication with the recipient. To better understand how this type of tool presents a solution, we need to dig into each of the current proposals, including the only current live implementation of reusable payment codes, PayNyms (or BIP 47).

Where did the idea of reusable payment codes come from?

The original idea for reusable payment codes (originally called “stealth addresses”) is over a decade old at this point, originally being proposed in 2011 on the Bitcoin Talk forums and then unofficially given a BIP number (63) in 2015 after a proposal by Peter Todd in early 2014. This proposal never gained traction and was abandoned by the author when a change to Bitcoin’s OP_RETURN field broke his approach.

This original proposal shares many similarities to PayNyms, Silent Payments, and Private Payments, using a set of keys combined into one long payment code to allow senders to generate unique addresses for the recipient and leveraging the OP_RETURN. This approach is simple and relatively easy to implement, but relied on a large OP_RETURN field (something that was reduced shortly after it was proposed) and made every payment utilizing stealth addresses stand out on-chain. Even with its drawbacks, this was a major step forward and would form the foundation for future proposals.

Reusable payment codes become a reality

The next proposal to build on the work of Peter Todd was presented in BIP 47 and ultimately became what we know today as “PayNyms.” BIP 47 iterated on the stealth address proposal by utilizing a single notification transaction to signal to the recipient to watch for payments to a specific public key (and thus set of addresses) instead of including payment code signaling in every payment. While there are multiple versions of BIP 47, as the only one in use is version 1 we will focus on that in this post. For simplicity’s sake, for the rest of this post let’s have “Alice” represent the sender in a transaction, and “Bob” represent the recipient who is using a reusable payment code.

How it works

When Alice goes to send funds to Bob, her wallet uses the reusable payment code she got from Bob to generate a unique shared secret by combining (1) a private key from an output she owns, (2) the public key in Bob’s reusable payment code, and (3) a 64-byte blinding factor so that only Bob can interpret the shared secret. Alice’s wallet then converts this payment code to binary and inserts it into this notification transaction’s OP_RETURN field in order to let Bob know where to expect future payments from her. 

Both Alice and Bob have to be extremely careful not to link this notification transaction (or the inputs or outputs) with other transactions, as that could provide an on-chain link between their wallets and undo privacy gained from using BIP 47 reusable payment codes. Thankfully, current implementations in Samourai and Sparrow Wallet hide this “toxic” output associated with the notification transaction by default to protect both sender and recipient.

When Bob wants to check for received funds, he monitors his notification address, and when a transaction is received to it he (1) validates that it includes a BIP 47 payment code, (2) decrypts it with his private key, and then (3) stores the information on the set of addresses Alice can send to and watches them like any normal Bitcoin wallet. Even though this notification code is publicly visible on the blockchain, it is encrypted in such a way that only Bob can deduce the addresses it is used to generate, and thus all of Alice’s future payments are known only to Bob. Alice can now send as many payments as she would like to a unique address every time, and Bob can easily watch for new payments with both “light” wallets and “full” wallets.

A example BIP 47 notification transaction, note the OP_RETURN output

Advantages and trade-offs

BIP 47 holds the unique status of being the only form of reusable payment code to actually be implemented and widely used thanks to the efforts of the Samourai Wallet team, who have implemented BIP 47 as “PayNyms.” PayNyms are leveraged in Samourai Wallet, Sparrow Wallet, and Stack Wallet, allowing any user to easily share a reusable payment code or register their PayNym with Samourai Wallet’s servers to get a short version of their reusable payment code like “+shrillsurf491.” This short form of their reusable payment code can then be looked up by any PayNym user on Samourai’s servers and resolved to the full payment code, allowing them to then send payments in a privacy-preserving way.

While BIP 47 does have the major drawback of requiring a notification transaction for funds to be easily recovered, this is outweighed by the ability for light wallets to utilize reusable payment codes and the simplicity of implementation, making it very easy for wallet developers to add support for BIP 47 reusable payment codes to their wallets.

While BIP 47 does have the major drawback of requiring a notification transaction for funds to be easily recovered, this is outweighed by the ability for light wallets to utilize reusable payment codes and the simplicity of implementation, making it very easy for wallet developers to add support for BIP 47 reusable payment codes to their wallets. This has led to rapid growth and adoption of BIP 47 and PayNyms in a way that no other proposal has seen so far.

Doing away with the notification transaction via Silent Payments

Some Bitcoin developers consider the trade-offs inherent in BIP 47 too harmful, and have sought ways to implement reusable payment codes without needing an on-chain notification transaction, but no other proposals gained interest until 2022. However, in March of 2022 Ruben Somsen proposed “Silent Payments,” a new approach to reusable payment codes that removes the need for a notification transaction entirely by leveraging the outputs in a transaction to signal to the recipient when funds are intended for them. Silent Payments makes use of advances in Bitcoin scanning to remove the need for a notification transaction, thereby improving scaling and privacy associated with reusable payment codes (with a key trade-off we’ll address later).

How it works

When Alice goes to send funds to Bob, she takes three keys and creates a unique one-time address that only Bob controls the keys to. These three keys are the (1) public key of the output(s) Alice wants to send to Bob, (2) Bob’s public key in his reusable payment code, and (3) a shared secret (generated using the same cryptography as stealth addresses and BIP 47, “ECDH“) that only Alice and Bob know. These three keys combine into a unique one-time address that Bob can then validate and spend from, allowing Alice to generate practically infinite addresses without any communication with Bob. This payment appears exactly like any other payment using the same script type (i.e. Taproot), thereby preventing an outside observer from even knowing Silent Payments were used at all, much less link payments to a Silent Payment address together.

When Bob wants to check for received funds, he takes (1) the private key from his payment code and (2) the aggregated key across the inputs of every transaction on-chain and checks to see if the combination matches an output in a transaction. If it matches, that output is owned by his private key and he can spend it at will, and if it doesn’t match he simply ignores that transaction and continues scanning. This process of checking every input in transactions is relatively costly and requires a full node, but does preserve privacy and remove the need for problematic notification transactions entirely. 

An example testnet SIlent Payment transaction, note that it looks like any other standard Taproot transaction

Advantages and trade-offs

[This] brings us to the significant trade-off of Silent Payments: because this scanning is relatively costly and can only be performed with a full Bitcoin node, Silent Payments necessarily do not work on light wallets, limiting their usage in practice.

Because with Silent Payments Bob must scan all transactions on the blockchain from the point that he generated the payment code, it brings us to the significant tradeoff of Silent Payments: because this scanning is relatively costly and can only be performed with a full Bitcoin node, Silent Payments necessarily do not work on light wallets, limiting their usage in practice.

While Silent Payments present a unique and useful set of trade-offs in comparison to BIP 47, they have not yet been implemented in any wallet and thus cannot be used by the average person. Silent Payments are particularly useful when you only want to send a single payment or donation to a given reusable payment code, as they do not require a separate notification transaction and so are cheaper and more efficient than the alternatives available today. It will be interesting to see if Silent Payments catch on, but for now you can follow the conversation on the topic on Github for future developments.

BIP 47 with a twist: Private Payments

Last but not least, the newest kid on the block is BIP 351, or “Private Payments.” Private Payments strikes a middle ground in trade-offs between BIP 47 and Silent Payments, minimizing the potential impact and issues of a notification transaction (while still requiring one) and reducing the scanning requirements to only scanning OP_RETURNs (while still requiring a full node). Private Payments was proposed in July of 2022 by Alfred Hodler and Clark Moody, and is the latest approach to reusable payment codes.

How it works

When Alice goes to send funds to Bob, she takes (1) Bob’s public key encoded in his payment code and combines it with (2) a shared secret she generates to create a unique one-time address to use for a notification transaction. She then generates a unique notification code to include in the OP_RETURN of the notification transaction, creating a transaction that does not re-use a notification address (unlike BIP 47), but does stand out on-chain (unlike Silent Payments). Once she has sent this notification transaction, she can then generate a new, unique address for each subsequent payment to Bob without any links on-chain, and no direct link between any of her UTXOs and Bob’s notification address.

When Bob wants to check for received funds, he checks the OP_RETURN on every transaction since he generated his payment code for those with OP_RETURNs including a notification code that matches his private key. When he finds one that matches, he can then add all derived addresses to a watch list and monitor them for transactions just like a normal Bitcoin wallet. As this only requires checking the OP_RETURN field in each transaction instead of performing validation of every input and output, it’s necessarily much lighter on requirements than that of Silent Payments. While this still precludes the simple usage of light wallets (similar to Silent Payments), it would be easier to off-load the validation of OP_RETURNs to an external (trusted) service.

Advantages and trade-offs

As Private Payments requires both a notification transaction and a full node for proper scanning, it strikes something of a balance between the two other proposals without fully gaining the benefits of BIP 47’s notification transactions and the ability to use light wallets, or the scaling and privacy improvements from the omission of a notification transaction in Silent Payments. It could still pose an interesting approach for light wallets that are willing to trust an external OP_RETURN validation service, however, and gives us a great example of the continuing innovation and exploration around how we can best approach reusable payment codes.

Using reusable payment codes today

If you’ve read through this and are wondering how you can actually use this fascinating technology today, I’ve got great news for you – BIP 47, or PayNyms, are extremely easy to use today with both Samourai Wallet and Sparrow Wallet. Both have well-implemented native support for reusable payment codes, making it extremely easy to create one (all hot wallets have one by default) and to send to a reusable payment code. For the relevant documentation on using PayNyms in both wallets, you can jump in below:

If you’re not currently using one of these wallets, using reusable payment codes is unfortunately often not supported as it does require a bit of work for wallet developers to implement. There is, however, ongoing work by an independent developer to implement BIP 47 PayNyms in Blue Wallet, and we at Foundation are eager to implement PayNyms into Envoy in the future. Outside of using Samourai Wallet. Sparrow Wallet, or Stack Wallet, you can help along the growth of reusable payment codes by talking about the need on social media, following the relevant conversations and BIPs, and donating to developers and projects working on innovation and implementations along the way.

What We Protect

In Part 1 of our series on making every spend a CoinJoin, “Why We Mix”, we walked through the philosophical and practical first steps behind the fight for privacy in Bitcoin. In Part 2 we’re digging into what information we share when we make a standard Bitcoin transaction, and what we want to (and can!) choose to protect to gain financial privacy. 

Each transaction we send in Bitcoin contains information on all inputs used, all outputs sent, and the time when the transaction is published to the mempool and included in a block. This ultimately breaks down into 4 key pieces of information; the sender, the recipient, the amount sent, and the source node.

Why does Bitcoin reveal so much information in each transaction?

When you sit down and think about the amount of information contained in a Bitcoin transaction, you may begin to wonder why in the world all of this has to be shared with the world each time you send a Bitcoin transaction. One of the tradeoffs that comes with making Bitcoin a decentralized and distributed ledger is that each transaction must contain enough information for (1) miners and nodes to validate that transactions don’t double spend funds, (2) users to be able to find their own funds without hassle, and (3) for the supply of Bitcoin to be easily validated by network participants.

While novel approaches to leveraging more powerful (but more complex!) forms of cryptography to hide sender, recipient(s), and amounts have been developed and proposed over the years, none of these approaches existed in the early days of Bitcoin, and each comes with its own set of tradeoffs and risks. Instead of implementing protocol changes like ring signatures, confidential amounts, or stealth addresses at the base layer, the Bitcoin community and developers have opted to keep Bitcoin’s base layer transparent by design and rely on higher layers and application-level privacy tools to allow users to opt-in to better privacy in Bitcoin.

Because of this choice, the ability for each of us to gain privacy becomes a matter of personal responsibility and knowledge instead of a protocol-enforced default. For better or worse, we each get to choose our own preferences and path towards financial privacy when it comes to Bitcoin.

An example transaction

As we walk through these four key pieces of information about each Bitcoin transaction, having an example transaction to refer back to will be invaluable. This transaction has been chosen at random from the Bitcoin ledger, but illustrates quite a few key aspects of a lack of privacy being inherent in Bitcoin.

Transaction ID: 01b668043b819fd812dd861c2d28deba04136751af087386dc5b991beb73493a

What can we learn from a simple look into the transaction? Let’s break it down into key findings from using simple, widely available blockchain exploration tools like mempool.space and oxt.me:

  • The sender consolidated multiple outputs to make the transaction, revealing all the inputs as almost certainly belonging to them
  • Going back one hop with the largest input shows us that some of the funds were withdrawn from Bitstamp (but not all)
  • The sent amount is almost certainly 0.011 BTC, as it is sent to a different type of address (“P2SH”, or wrapped/nested SegWit)
    • We can also confirm this analysis due to the rounded payment amount (0.011 BTC) which almost never happens with fees or change outputs
  • The recipient is still using a legacy Bitcoin wallet and has not upgraded to use Segwit
  • The change amount is almost certainly 0.00004088 BTC, as it is sent to the same type of address as the inputs (“P2WPKH”, or Segwit Bech32)

We’ll look more at these findings in each section below.

Protecting the sender

When we look at the different pieces of information revealed in a Bitcoin transaction, the information on funds being spent (and thus on the sender themselves) rightfully deserves the most focus when approaching transactional privacy. When you view any basic Bitcoin transaction in an explorer, you quickly realize that you can learn an immense amount of information about the sender by simply following the inputs backwards.

How do we see this play out in our example transaction? Let’s take a closer look:

  • The sender consolidated multiple outputs to make the transaction, revealing all the inputs as almost certainly belonging to them
  • Going back one hop with the largest input shows us that some of the funds were withdrawn from Bitstamp (but not all), tying multiple addresses together with funds connected to the sender’s identity known by Bitstamp
Inputs to a previous transaction sent from Bitstamp wallets

This simple analysis is primarily possible because in Bitcoin, almost all transactions are performed by a single entity; and if a single entity is performing a transaction, then all inputs to that transaction are necessarily owned by them. This heuristic is called the “common-input-ownership heuristic” and is one of the foundational building blocks for the majority of chain surveillance in Bitcoin today. When those wishing to surveil Bitcoin’s usage can safely assume that all inputs in a transaction are owned by the sender, they can build detailed and nearly complete pictures of a user’s spending habits past, present, and future.

This heuristic is also the core of what CoinJoin-style transactions attempt to confuse and break by coordinating a single transaction between many different participants. If enough Bitcoin users started to make CoinJoin transactions regularly, we could even go so far as to break this heuristic and make it inaccurate for chain surveillance companies, severely limiting their visibility into our financial activity on Bitcoin.

While hiding the input addresses and amounts is strictly not possible in Bitcoin today, we do have a few options for obfuscating and confusing chain surveillance, making their lives as difficult as possible.

What can we do today?

While we’ll keep things short and sweet in this section, here are a few ways you can better protect your financial privacy when sending Bitcoin transactions:

  1. Always use a new receive address
    1. If your current Bitcoin wallet doesn’t do this automatically, it’s far past time to switch!
  2. Don’t consolidate funds in your wallet (a commonly recommended way to save on fees down the line) by sending all of your Bitcoin back to yourself in a single transaction
  3. Use as few inputs as possible (only one, if possible!) when sending a transaction
    1. Thankfully most good Bitcoin wallets will do this for you by default!
  4. Prefer using PayJoin when enabled by a merchant (anyone using BTCPay Server can easily enable this if they’re using a hot wallet!)
    1. Read our guide on doing just that when buying a Passport: Buying Passport Privately Using CoinJoin
  5. Use wallets like Samourai Wallet and Sparrow Wallet to CoinJoin your funds, ensuring that even when you spend funds the prior history of each input isn’t able to be traced
  6. Use wallets like Samourai Wallet and Sparrow Wallet which automatically create dummy CoinJoin transactions whenever possible to obscure the sender (often called a “STONEWALL” transaction)
  7. Use wallets like Samourai Wallet and Sparrow Wallet to create collaborative transactions that obfuscate the true sender and input (often called a “STONEWALLx2” transaction)

Protecting the amount sent

Protecting the sender is the core focus for many of the privacy tools built on Bitcoin, but protecting the amount sent in each transaction is also an important piece of a holistic approach to privacy on-chain. If we’re not careful about how amounts are handled, we can make it easier to undo our privacy and link transactions and addresses to each other. The most common ways to use amounts to reveal information in a transaction are to look for rounded payment amounts (i.e., 0.001 BTC exactly) or to look for exactly matching amounts (minus normal fees) going into and out of exchanges, instant exchangers, or decentralized exchanges.

How do we see this play out in our example transaction? Let’s take a closer look:

  • The sent amount is almost certainly 0.011 BTC, as it is sent to a different type of address (“P2SH”, or legacy SegWit)
    • We can also confirm this analysis due to the rounded payment amount (0.011 BTC) which almost never happens with fees or change outputs
  • The change amount is almost certainly 0.00004088 BTC, as it is sent to the same type of address as the inputs (“P2WPKH”, or Segwit Bech32)

Amount-based heuristics are a common tool used by chain surveillance companies to confirm other heuristics (like the “common-input-ownership heuristic” we’ve already discussed) or to make educated guesses in the absence of clearer signs on-chain. The ability to use amounts to tie transactions and inputs together is one of the main reasons that most of the most battle-tested CoinJoin protocols use common denominations for inputs (i.e., 0.05 BTC) instead of allowing arbitrary amounts. Using these common denominations prevents trivial linkage of inputs and outputs down the line.

What can we do today?

  1. Avoid using rounded amounts (i.e,. 0.01 BTC) when sending funds unless necessary
  2. Avoid using specific fee amounts (outside of 1sat/vbyte, of course) and allow your wallet to calculate fees appropriately
  3. Prefer using PayJoin when enabled by a merchant (anyone using BTCPay Server can easily enable this if they’re using a hot wallet!)
  4. Use wallets like Samourai Wallet and Sparrow Wallet and create a “STOWAWAY” transaction with other Samourai and Sparrow users to hide the amount being sent and true input

Protecting the recipient

Now that we’ve taken a look at protecting both the sender and amount in a transaction, how do we go about protecting the recipient’s privacy? Thankfully, many of the same principles apply here as well, especially avoiding address re-use. As every transaction in Bitcoin necessarily has a recipient with address and amount being visible on-chain, it can be quite difficult to actually preserve the privacy of the recipient, both from the sender and from outside observers.

How do we see this play out in our example transaction? Let’s take a closer look:

  • The sent amount is almost certainly 0.011 BTC, as it is sent to a different type of address (“P2SH”, or legacy SegWit)
    • We can also confirm this analysis due to the rounded payment amount (0.011 BTC) which almost never happens with fees or change outputs
  • The recipient is still using a legacy Bitcoin wallet and has not upgraded to use Segwit
  • The recipient sweeps this output along with many others in a later transaction, linking their other receive history together

Chain surveillance companies leverage many of the same techniques to identify recipients as they do with senders, including wallet fingerprinting by fees, script types, output consolidation, and address re-use. When these types of heuristics are used, it can lead to “wallet clustering”, where those performing surveillance can tie together transactions under a single entity, even if there is no direct identification attached. As always with privacy, it’s important to blend in with the crowd and avoid any mistakes that can make it easier to separate and cluster transactions under a single entity.

What can we do today?

  1. Avoid re-using addresses when receiving funds
  2. If you’re the sender and a recipient is re-using an address or has a static Bitcoin address posted for donations or payments, pressure them to either use a PayNym or a solution like SatSale or BTCPay Server to provide a new address with every payment
  3. Prefer using PayJoin when enabled by a merchant (anyone using BTCPay Server can enable this, if it’s not enabled ask your merchant to enable it!)
  4. Use wallets like Samourai Wallet and Sparrow Wallet to create collaborative transactions that obfuscate the true sender, receiver and input (often called a “STONEWALLx2” transaction)
  5. Use wallets like Samourai Wallet and Sparrow Wallet and create a “STOWAWAY” transaction with other Samourai and Sparrow users to hide the amount being sent and true received output
Graphic explaining a STOWAWAY transaction

Protecting the source node

Last but not least comes an aspect of Bitcoin privacy that is often forgotten – protecting the IP address of the Bitcoin node that broadcasts the transaction in question. While the IP address and information about the originating node isn’t stored on the blockchain directly, it can be relatively easily seen by anyone operating a few nodes on the network and desiring to gather that type of information.

Because Bitcoin Core uses a very simplistic transaction broadcast protocol, an adversary seeking to surveil the network can run many nodes in many different geographic locations to try and be at least one connection of most nodes in the network. Once they have these broadly distributed nodes (a “Sybil attack”, something that is very cheap and easy to do in a permissionless and decentralized network like Bitcoin), they can then watch for where in the network they see transactions first broadcast. If they notice that a transaction they’re interested in was first broadcast from one node and propagated from there, they can make a very well educated guess that it was the source node for the transaction.

While this doesn’t guarantee that their guess is correct, it does help them narrow down the potential source node of a transaction and more actively Sybil attack that specific node to look for further transactions of interest. This can be combined with on-chain heuristics to try and find the source node being used by a specific entity and gain vast insight into their spending habits, their geographic location, and even their home address (if they reveal their true IP address to the Bitcoin network).

It’s important to remember that a peer-to-peer network like that used in Bitcoin is designed to be censorship-resistant and permissionless, not private. This approach works extremely well at ensuring that in most censorship scenarios a transaction can still be broadcast to the whole network, but also ensures that a motivated adversary can quite easily follow the flow of transaction propagation and block propagation across the network.

If you’d like to learn more about the issues inherent in this approach, there is an excellent article on the topic titled “Bitcoin’s P2P Network” at nakamoto.com.

What can we do today?

  1. If you run your own Bitcoin node, set it to only use the Tor network for communication
    1. This option is controlled by `onlynet=onion` in the config file, read more on the topic here
  2. Broadcast transactions manually via the Tor Browser and a service like mempool.space
    1. Only do this over Tor, never via clearnet!
    2. The current Onion address of the mempool.space broadcast tool is here
  3. Run your own Samourai Wallet “Dojo” node stack, which is Tor-only by default

Conclusion

After reading this I hope you come away with the conclusion that while Bitcoin’s on-chain privacy is imperfect by default, there are solutions available to each of these problems today. It may seem daunting to have to consider each of these aspects of information when sending or receiving a Bitcoin transaction, but as the issues around privacy within Bitcoin are clarified and made known, the wallets and apps we use to interact with Bitcoin can grow to better handle all of these potential issues for a user automatically.

Over the long-term it’s extremely important that wallet developers and node developers work hard to build in sane and private defaults to their apps, as most users have neither the knowledge nor expertise to properly handle every core piece of Bitcoin privacy. The more we as developers can improve users’ privacy without them even thinking actively about it, the better off our users will be and the better off the Bitcoin network and ecosystem will be.

In part 3 of this series we’ll take a closer look at protecting the sender via CoinJoin, including a sneak peak at what we’re working on to help make Bitcoin privacy more approachable for every Bitcoin user.

Stay tuned, and thanks for diving into the deep end of Bitcoin privacy with us today!