Hi all,
I've written this python library that encrypts messages for a particular Bitcoin public key from a particular public key. The message content is provably from the sender's Bitcoin address. It is also hidden as ciphertext en route. Only the recipient Bitcoin address can decrypt the contents.
Here's how it works.
a secret shared key between sender and receiver is created in the following way:
- the sender scrapes the Blockchain (or some other source) for the recipient's public key. Any transaction signed with pay_to_pubkey hash reveals the address's public key. I wrote a small utility that scrapes this key, if available from transaction scripts, using the Blockchain.info API (although any other source would suffice).
- Using the recipient's public key, the sender multiplies that point on the elliptic curve by his private key (ie the integer it represents). A new point is created.
- The new created point's coordinates map to a 32 byte string that is the shared secret key.
- Meanwhile the sender broadcasts his public key as part of the encrypted message. The recipient uses his private key to mulitply by the public point of the sender. He should arrive at the same point calculated by the sender. This maps again to the shared secret key.
Then I use AES-CBC to symmetrically encrypt the message contents using the shared secret key.
Finally, a timestamp is included in the encrypted message. Received messages are only valid within X seconds of their creation by the sender. This is a simple method to limit reply attacks to a brief window.
This was my first foray into crypto, so I'd appreciate feedback and corrections. Don't use this library as a finished product, as it has not been reviewed. There could well be glaring errors I've missed. I'm not a professional cryptographer so... take it with a grain of salt.