12

If I want to prove that I wrote a particular document before a certain point in time, it would be sufficient to generate the sha256 hash of the document and somehow arrange for that hash to appear in the blockchain.

Is there an easy way to do that simply by sending a transaction and leaving it to the miners to arrange for it to get into the blockchain for me?

One way that occurs to me is that I can treat the hash as a private key (bitaddress.org will tell me the address and private key that corresponds to any given input), and send a Bitcoin to the corresponding address. Then when I publish the document anyone can go through the same process and see the date of the transaction in the blockchain.

That seems a little convoluted. Is there a simpler way? Ideally free, not computationally intensive, and not requiring any special software to make the timestamp or to verify it.

1

5 Answers 5

7

You can encode any arbitrary data using the Bitcoin script's OP_PUSH and OP_DROP commands. For this, however, you would need some custom Bitcoin client, as the standard one does not allow you to send messages like this.

Alternatively, you could just use the hash as a part of the generation of a Bitcoin address and store it in the Block chain by destroying one satoshi on it.

There should be a topic covering encoding of any data into the Blockchain somewhere on this StackExchange, so you can also have a look at that.

1
  • 2
    Thanks. Now that bitaddress.org has added a 'brain wallet' tab, I think it's easiest just to paste the document hash (or even the whole document if it's short enough) into the brain wallet tab, and deposit a coin to the resulting address. Then if I need to prove that the document existed at that time I can point people at bitaddress.org to validate it. Jul 30, 2012 at 20:32
5

One way to insert an arbitrary SHA-256 hash into the blockchain is by using it to generate a Bitcon address, then sending a very small amount of Bitcoin to that address. The Bitcoin wiki does a good job of covering the actual process of generating an address from an ECDSA private key here and here.

If you'd prefer not to have to perform the computation manually, however, there's a useful command-line utility called bitcoin-tool. Suppose we want to generate a Bitcoin address from the SHA-256 hash of the string "test":

$ ./bitcoin-tool \
  --input-file <(echo -n "test" | openssl dgst -sha256 -binary) \
  --input-format raw \
  --input-type private-key \
  --network bitcoin \
  --output-type all \
  --public-key-compression uncompressed
address.hex:00b311d5766f9623408747554bcdec1d8dc05eeaf0
address.base58:13VhJywL2p5upGoXpU3RvECR7Heoq
address.base58check:1HKqKTMpBTZZ8H5zcqYEWYBaaWELrDEXeE
public-key-ripemd160.hex:b311d5766f9623408747554bcdec1d8dc05eeaf0
public-key-ripemd160.base58:3VhJywL2p5upGoXpU3RvECR7Heoq
public-key-ripemd160.base58check:HKqKTMpBTZZ8H5zcqYEWYBaaWELuen1WX
public-key-sha256.hex:c8d47a3b796bce36d80dd2e8622ce1bcc4eab1f4a78e8cd3e12b7db44d1c428a
public-key-sha256.base58:EWxTRzHpLN7GjXx6nwqDWJ6DSmrNTVYroZ2VdC7fg8Gq
public-key-sha256.base58check:2XSw67i599jF6FWxAApzSy2xBec9HrNCT7ZqWUo5dFhkqoDeQ3
public-key.hex:045f81956d5826bad7d30daed2b5c8c98e72046c1ec8323da336445476183fb7ca54ba511b8b782bc5085962412e8b9879496e3b60bebee7c36987d1d5848b9a50
public-key.base58:PPBn9d92VkgAZeSLkWyyRSzZusyAaR79PQEjVGX2UoXqHxmgEmr1BvJBYtXXux6TrytQ7FtYqAV2h7TxuMN1sxH5
public-key.base58check:3XTsV9raUUfajGdt6HibXREKMHXkZBQY6BLs9NSVGfE63GRFzKeBYQzCRVQzkkAQhnDkry1S6DdSXpmshbGuL73oiRr6Rs
private-key-wif.hex:809f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
private-key-wif.base58:fD8GVhUgAUmnrJPuyfqkUMDCk3RueN9bTskWv8nEsDWYF
private-key-wif.base58check:5K2YUVmWfxbmvsNxCsfvArXdGXm7d5DC9pn4yD75k2UaSYgkXTh
private-key.hex:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
private-key.base58:Bjj4AWTNrjQVHqgWbP2XaxXz4DYH1WZMyERHxsad7b2w
private-key.base58check:2DFtpKRbW2nfrzgAgE25onW3vwCQwM7S1iHk34LW9cwH1kzmHp

We would then proceed to send a small amount of Bitcoin to the address on the third line: 1HKqKTMpBTZZ8H5zcqYEWYBaaWELrDEXeE. Sure enough, this address has seen a lot of activity over the years. Unsurprisingly, it has a zero balance. If someone were to send coins to that address, we'd be able to spend them, since we have the private key.

Notice that, in the above example, we opted to output an uncompressed public key. We could have instead chosen to compress the public key, and the output would've been different:

$ ./bitcoin-tool \
  --input-file <(echo -n "test" | openssl dgst -sha256 -binary) \
  --input-format raw \
  --input-type private-key \
  --network bitcoin \
  --output-type all \
  --public-key-compression compressed
address.hex:005ec7f2d15a1f20eab67d60f09effca58b43eee9f
address.base58:12Kb2TaC79MfRSvRsaivP8eUWQYUW
address.base58check:19eA3hUfKRt7aZymavdQFXg5EZ6KCVKxr8
public-key-ripemd160.hex:5ec7f2d15a1f20eab67d60f09effca58b43eee9f
public-key-ripemd160.base58:2Kb2TaC79MfRSvRsaivP8eUWQYUW
public-key-ripemd160.base58check:9eA3hUfKRt7aZymavdQFXg5EZ6KD5ucx5
public-key-sha256.hex:2ad1722dab79ddc2bb3a7b7fe3b397176bda623ad9ad94ca52022aa44f5213c9
public-key-sha256.base58:3t9Mnijb12wM4TYXj4jgAAUyMgK6o9eUbqwWTruXPeRN
public-key-sha256.base58check:KrjTuGpsnRCbBDsP4UGYKa2SeFhDAfWLruDUeEQMtTPyTLqaV
public-key.hex:025f81956d5826bad7d30daed2b5c8c98e72046c1ec8323da336445476183fb7ca
public-key.base58:htT5U6vHyh8jy39y6AuJuRDH95z23Q1VgRpNmTBK2aPb
public-key.base58check:5cYvx6NBYNdcJUym9WydRRs6329UTzJgzKii8dESmw2ZXwAYnt
private-key-wif.hex:809f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a0801
private-key-wif.base58:3ueX5Pff9rqahNbn8q8SAsiCrpyiwMvLw7d153XLgCeDNtp
private-key-wif.base58check:L2ZovMyTxxQVJmMtfQemgVcB5YmiEDapDwsvX6RqvuWibgUNRiHz
private-key.hex:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
private-key.base58:Bjj4AWTNrjQVHqgWbP2XaxXz4DYH1WZMyERHxsad7b2w
private-key.base58check:2DFtpKRbW2nfrzgAgE25onW3vwCQwM7S1iHk34LW9cwH1kzmHp

Note that the resulting address is different: 19eA3hUfKRt7aZymavdQFXg5EZ6KCVKxr8. However, it's still an equally valid Bitcoin address, and it too has seen a bit of activity over the years, though not nearly as much as the address associated with the uncompressed key.

It's important to understand that, even though the public keys and addresses are different, the private keys are the same. Observe that the last three lines of each output are identical:

private-key.hex:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
private-key.base58:Bjj4AWTNrjQVHqgWbP2XaxXz4DYH1WZMyERHxsad7b2w
private-key.base58check:2DFtpKRbW2nfrzgAgE25onW3vwCQwM7S1iHk34LW9cwH1kzmHp

Nonetheless, you should be careful when converting raw private keys to addresses, since you can easily end up with different addresses.

So far, we've covered converting an arbitrary SHA-256 hash into a private key, but we can also convert one into a public key. This may be more suitable for public proofs. For example, if you publish a document, and you want others to be able to verify that it existed prior to a certain point in time, you can take the SHA-256 hash of that file, convert it into a public key, then send some small amount of Bitcoin to the associated address. There is, in fact, a real life example of this. Isis Agora Lovecruft, a core developer for the Tor Project, was being harassed by the FBI. She documented this in a post on her blog. In the post, she wrote:

In case the FBI is seeking data on Tor users or Tor bridges, and especially in case the subpoena turns out to be sealed or accompanied by an NSL: the original published contents of this post are archived as a PDF here, and the RIPE160(SHA256(PDF)) is equal to 5541405e08048658cf457b3c59bf42a51f84a1a3 and hence Bitcoin address 18mnc4BCud3vjAdLbCc3QhyrjN84VTT1iM, in order to prove in a cryptographically verifiable manner that I published before that point in time.

In this case, the SHA-256 hash of the PDF was converted to a uncompressed public key, which we can verify like so:

$ ./bitcoin-tool \
  --input-file <(curl https://fyb.patternsinthevoid.net/blog.patterns-in-the-void-2016-04-30.pdf | openssl dgst -sha256 -binary) \
  --input-format raw \
  --input-type public-key-sha \
  --network bitcoin \
  --output-type address \
  --output-format base58check \
  --public-key-compression uncompressed
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 4022k  100 4022k    0     0  1228k      0  0:00:03  0:00:03 --:--:-- 1229k
address.hex:005541405e08048658cf457b3c59bf42a51f84a1a3
address.base58:12Bta5yx2FwcU7yg2B6V3u9HFFWGS
address.base58check:18mnc4BCud3vjAdLbCc3QhyrjN84VTT1iM
public-key-ripemd160.hex:5541405e08048658cf457b3c59bf42a51f84a1a3
public-key-ripemd160.base58:2Bta5yx2FwcU7yg2B6V3u9HFFWGS
public-key-ripemd160.base58check:8mnc4BCud3vjAdLbCc3QhyrjN84WuGgTg
public-key-sha256.hex:0e4498fb5f299159452f97f9113edfb7dbb3973859f96c22c874dc7dafbdcb27
public-key-sha256.base58:xhNoGDN2QGu7J3bf8aYM8xrvuvJcuEBqQQGZwqsfraz
public-key-sha256.base58check:7HTSYwK5m87PyqNaAKz9H87PAzubhzP2ev9LoAxZcCvQjqcXA

Sure enough, public-key-ripemd160.hex:5541405e08048658cf457b3c59bf42a51f84a1a3 matches the posted value of RIPE160(SHA256(PDF)), and address.base58check:18mnc4BCud3vjAdLbCc3QhyrjN84VTT1iM matches the posted Bitcoin address. Finally, the deposit of 0.001 BTC to this address on 2016-05-01 proves that the address existed as of that date. Since generating a PDF after the fact (i.e., to match an existing Bitcoin address) would require, at the very least, a successful preimage attack against full round SHA-256, the conjunction of these facts prove beyond any reasonable (cryptographically-informed) doubt that the document in question existed at least as early as 2016-05-01.

2

While I understand the temptation to re-/abuse the blockchain for such things, why not use a service which is built on purpose for this? Have a look at guardtime.com, specifically http://www.guardtime.com/software/developer-tools/

0

Please check out this blockchain timestamping tool, it does exactly what you require for free (this blockchain has 0 fees for writing this data), and is technically better.

1
-1

There is no way to attach meta data to the block-chain without forming an alternate chain, which as ThePiachu pointed out requires a modified client. However, you could

  • Generate a wallet
  • Send 1 BTC to that wallet
  • Add both the public bitcoin wallet address and the block of your 1 BTC deposit
  • Use the private key of the Bitcoin wallet to sign the article contents

You can now prove to third parties you authored the document by sending 0.01 BTC to interested parties.

1
  • 2
    Completely misses the point.
    – Rotsor
    Aug 8, 2012 at 19:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.