How-to: using Bitcoin key pairs to for encrypted messaging

Ovadiah Myrgorod
3 min readJul 30, 2017

--

In my previous post, I have described an idea of building an anonymous messenger for Bitcoin users. Now it is a time to prove that it will work.

Let’s say, Alice wants to send Bob an encrypted text Greetings form Alice!. All she needs to know is Bob’s Bitcoin address and her own WIF (wallet import format) key. Bob will decrypt this text knowing Alice’s Bitcoin address and his own WIF key.

They will use ECDH algorithm to obtain a shared secret, which will be used for 256-bit symmetric AES encryption. Note that ECDH(public key A, private key B) = ECDH(public key B, private key A) = shared secret.

You may ask how Alice can get Bob’s public key knowing only his Bitcoin address? That’s very simple. If Bob has ever used his address for spending money, his public key is stored in the Blockchain, so it will be quite easy to retrieve it.

Algorithm

  1. Alice knows Bob’s Bitcoin address.
  2. Alice looks up Bob’s public key in the Blockchain.
  3. Alice generates a shared secret based on her private key and Bob’s public key using ECDH algorithm.
  4. Alice encrypts a message using 256-bit symmetric AES encryption with a shared secret.
  5. Alice sends an encrypted message to Bob. She also lets him know her Bitcoin address.
  6. Bob looks up Alice public key in the Blockchain.
  7. Bob generates a shared secret based on Alice’s public key and his own private key using ECDH algorithm.
  8. Bobs decrypts a message using 256-bit symmetric AES encryption with a shared secret.

A shared secret is always the same between two parties. Each party can compute it independently.

Proof

Let’s go through every step to prove that it will work.

In this example, Alice uses a compressed Bitcoin address (1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH), while Bob uses a regular one(1LagHJk2FyCV2VzrNHVqg3gYG4TSYwDV4m). For simplicity, these addresses were taken from the Bitcoin private key directory.

Encoding:

  1. Alice knows Bob’s address: 1LagHJk2FyCV2VzrNHVqg3gYG4TSYwDV4m.
  2. Alice looks up his address on Blockchain.info.
  3. Alice finds a spending transaction and retrieves Bob’s Public Key (130 characters, Hexadecimal): 04C6047F9441ED7D6D3045406E95C07CD85C778E4B8CEF3CA7ABAC09B95C709EE51AE168FEA63DC339A3C58419466CEAEEF7F632653266D0E1236431A950CFE52A.
  4. Since some transactions can contain multiple public keys, Alice verifies that she has found a correct public key by converting it into a Bitcoin address using this service. It should match Bob’s Bitcoin address.
  5. Alice knows her WIF key (compressed, Base58): KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn.
  6. Using this manual and Base58 decoder, Alice converts her WIF key into a private key (Hexademical): 0000000000000000000000000000000000000000000000000000000000000001.
  7. Using this Node.js script, which implements ECDH, Alice finds a shared secret (Hexademical):
    c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5.
  8. Using another Node.js script, Alice encrypts text Greetings form Alice! with 256-bit symmetric AES encryption and a shared secret. Encrypted text (hex) is: 89a7fa84bf762100ac09049bb7d1dc0d9b477f1632.
  9. Alice sends Bob an encrypted text as well as her Bitcoin address.

Decoding:

  1. Bob knows Alice’s Bitcoin Address: 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH.
  2. Bob looks up her address on Blockchain.info.
  3. Bob finds spending transaction and retrieves Alice’s Public Key (compressed, 66 characters, Hexadecimal): 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798.
  4. Bob verifies that he has found a correct public key by converting it into a Bitcoin address using this service. It should match Alice’s Bitcoin address.
  5. Bob knows his WIF key (Base58): 5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAvUcVfH.
  6. Using this manual and Base58 decoder, Bob converts his WIF key into a private key (Hexademical): 0000000000000000000000000000000000000000000000000000000000000002.
  7. Using this Node.js script, which implements ECDH, Bob finds a shared secret (Hexademical):
    c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5.
  8. Using another Node.js script, Bob decrypts hex string 89a7fa84bf762100ac09049bb7d1dc0d9b477f1632 with 256-bit symmetric AES encryption and a shared secret. Decrypted text is: Greetings form Alice!.

So it worked!

Consequences

Using this method we can do many fun things. E.g. we can create a server (or a distributed system), which will store all messages sent to all users. This makes possible for Alice to send a message to Bob, even before he started using a messenger. To get all messages, Bob does not ever need to sign in into a messenger. He can just run a simple REST request to get all of his data.

Another fun thing that could be made is communication between peers of different cryptocurrencies. For example, Ethereum is using the same secp256k1 ecliptic curve for generating keys as Bitcoin is, this means that we can still use ECDH for establishing a secure connection between Bitcoin and Ethereum users.

Support

Like an Idea? Make it happen: 135rcdVPUie3g1PXPazALpggZ6E72HVNj1!

--

--