Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: wolciph on August 26, 2011, 04:25:45 PM



Title: Proof of authenticity (POA) using the bitcoin blockchain
Post by: wolciph on August 26, 2011, 04:25:45 PM
The purpose of the following method and script is to permit one to provide a proof of the authenticity of a document, that is prove that a document is the original version, that it has not been altered since it's first publication.
This can have several uses, such as proving authorship, or preventing an adversary from spreading disinformation or confusion about for instance the date and location of an event (e.g. if "Anonymous" wishes to coordinate a DDOS attack). Another example which triggered my interest in this is that of Breivik's manifesto of which some decided to spread altered versions in order to make the original message difficult to find and spread. (note: I do not support Breivik; I am merely providing a method that can help all people, regardless of their intention. In the end, this method benefits the Truth.)

The idea is to insert a hash of a document in a block before publishing said document. Then, as the blockchain grows, it becomes increasingly difficult to modify this block and the hash it contains, thus providing a cryptographic proof that this exact document existed at a certain point in time.
So, in order to be able to prove a document of mine is authentic I would first have to publish it's hash in the blockchain and then wait a sufficient amount of time for two things:
 - that the blockchain has grown sufficiently that modifying the block of my hash has become infeasible;
 - and more importantly, that enough time had elapsed that there would be no doubt in the eyes of my public that the document was not publicly available at the time I inserted the hash.
 Thus, depending on the situation, waiting weeks or months after insertion of the hash may be necessary before publishing.

Technically, there are several ways of inserting a hash in the blockchain.
One would be to send transactions of amounts which, once concatenated, would form the hash. This method is somewhat impractical.
Another is to generate a "false" bitcoin address formed from the hash and to send a small amount of bitcoins to it (e.g. one satoshi). This is the method implemented in my script.
Yet another would be to instead generate the bitcoin private key from the hash, by using it as seed for the pseudo-random number generator for instance, and later disclosing this private key to enable verification.



Title: Re: Proof of authenticity (POA) using the bitcoin blockchain
Post by: wolciph on August 26, 2011, 04:26:56 PM
I can already hear the screams of "Satoshi intended the bitcoin blockchain for bitcoin transfer only" and the like but once again I am merely providing a tool which you may or may not use at your own discretion. There is also no blockchain more secure than that of bitcoin and I am afraid that a blockchain specifically for the purpose of POA may never catch on and never be secure enough against powerful adverseries. Anyhow, I do not see this method being used on a daily basis by many so it would not pose much risk of overloading the network, especially given the need for transaction fees.


Bellow, is a bash script which enables creation and verification of a bitcoin POA.
It requires the original bitcoin client running as a daemon for creation of a POA and Gavin Andresen's dbdump.py (https://github.com/gavinandresen/bitcointools/tree/45f5c0030ac9a121fff504b0ffd27efc27423bde) for verification.

Code:
#!/bin/bash
#bitpoa: Bitcoin blockchain based proof of authenticity
#Author: Wolciph
#Public domain, use at your own risk
set -e

#config:
interactive=1
hashAlgo=sha256
amount=0.00000001
fee=0.0001
keyType=pk
infoFile='info.poa'

bitcoind=~/bitcoind
bitcoinDir=~/.bitcoin/
dbdump=~/bitcointools/dbdump.py

cd "$(dirname "$0")"
. addrgen.so.bash
#. bitpoa.conf
cd - >/dev/null

_tries=5
get_transaction_block() #(txid)
{
#workaround to access block of transaction:
local c=$($bitcoind getblockcount)
local b=$($bitcoind gettransaction $1 |
grep -m1 '"confirmations" :' |
sed -r 's/^.*"confirmations" : ([0-9]*).*$/\1/g';
[[ ${PIPESTATUS[@]} = '0 0 0' ]])
local c2=$($bitcoind getblockcount)
if (( $c2 == $c )); then echo $((c - b + 1))
elif (( _tries > 0 )); then ((_tries--)); get_transaction_block
else
echo "Cannot get stable blockcount. Wait until your blockchain is up\
to date and try again." >&2
return 2
fi
}
get_field() #(field)
{
grep -m1 "^$1:" | sed -r "s/^$1:(.*)$/\1/g"
[[ ${PIPESTATUS[@]} = '0 0' ]]
}

check_pipes() { [[ "${PIPESTATUS[@]}" =~ ^0(\ 0)*$ ]]; }

help="bitpoa Bitcoin blockchain proof of authenticity tool:
Examples:
  These tasks require the bitcoin server to be active:
    Creation: $0 -cf document.txt -i info.poa -a sha256 -A 0.00000001
    Finding the block: $0 -b -i info.poa
  This task requires the bitcoin server to be stopped:
    Verifying: $0 -vf document.txt -i info.poa
Commands:
-c, --create : create and send _amount_ coins to a new address
-b, --find-block : find the block in which the new transaction is to
complete the info file
-v, --verify : verify a POA
-f, --file= : file from which to create a hash
-i, --info-file= : info file to read or write info for checking the POA
-h, --hash : do not hash the file (to use if it already is a hash)
-a, --algo= : the hashing algorithm; uses openssl
-y, --assume-yes : do not prompt before critical operations, non-interactive
-s, --secret-key : use hash in the private key (NOT IMPLEMENTED)
-A, --amount= : amount of bitcoins to send (WILL BE LOST FOREVER!!!)
-F, --fee= : transaction fee
"
#------------------

OPTS=$(getopt -o cvbf:i:ha:yA:F: \
--long create,verify,find-block,file:,info-file:,hash,algo:,assume-yes,help,amount,fee\
-n "$0" -- "$@")
if [ $? != 0 ]; then echo "Terminating. Use --help for help." >&2; exit 1; fi
eval set -- "$OPTS"
while true; do
case "$1" in
-c|--create) action=create; shift;;
-v|--verify) action=verify; shift;;
-b|--find-block) action=findBlock; shift;;
-f|--file) file="$2"; shift 2;;
-i|--info-file) infoFile="$2"; shift 2;;
-h|--hash) hash=1;; #the file cointains the hash
-a|--algo) hashAlgo="$2"; shift 2;; #first round (followed by ripemd160)
-y|--assume-yes) interactive=0; shift;;
-s|--secret-key) keyType=sk; shift;;
-A|--amount) amount=$2; shift 2;;
-F|--fee) txfee=$2; shift 2;;
--help) printf "%s" "$help" >&2; exit 0;;
--) shift; break;;
*) echo "Invalid argument: $1. Use --help for help." >&2; exit 1;;
esac
done
[ -n "$1" ] && { echo "Unknown extra argument: $1" >&2; exit 1; }
[ -z "$action" ] && { echo 'No action specified (-c|-v|-b)' >&2; exit 1; }

if [[ $action = findBlock ]]; then
txid="$(get_field txid < $infoFile)"
block=$(get_transaction_block $txid)
printf "%s\n" "block:$block" >> $infoFile
exit 0
fi

if [[ "$hash" = '1' ]]; then
hash=$(cat "$file")
else
hash=$(cat "$file" | openssl dgst -$hashAlgo -hex; [[ ${PIPESTATUS[@]} = '0 0' ]];) ||
{ echo "Error while hashing using $hashAlgo. Exiting." >&2; exit 1; }
fi

if [[ $keyType = pk ]]; then
h=$(xxd -p -r <<< "$hash" | openssl dgst -rmd160)
address=$(hash160ToAddress $h)
else
exit 1
#use hash as seed for prng?
fi

if [[ $action = 'create' ]]; then
printf "%s\n%s\n%s\n" "file:$file" "algo:$hashAlgo" "address:$address" > $infoFile
cmd="$bitcoind -paytxfee=$txfee sendtoaddress $address $amount"
if [[ $interactive = '1' ]]; then
echo "Warning: $amount bitcoins will be lost forever." >&2
printf '%s\n%s\n%s\n' "The following command is about to be sent to the bitcoin daemon:"\
"$cmd" "Make sure it is running. Proceed? (y/n)" >&2
read r
[[ "$r" =~ ^y(es?)?$ ]] || exit 0
fi
echo -n 'txid:' >> $infoFile
eval $cmd >> $infoFile
if [[ $interactive = '1' ]]; then
printf "%s%s\n" 'You must now wait for the transaction to be '\
"integrated into a new block before launching $0 -b [...]" >&2
fi
elif [[ $action = 'verify' ]]; then
address2="$(get_field address < $infoFile)"
if [[ "$address2" != "$address" ]]; then
printf "%s\n" "FAILURE: The address is incorrect (should be $address)!" >&2
exit 5
fi
block=$(get_field block < $infoFile)
blockInfo="$($dbdump --block=$block)"
if ! (grep -m1 "pubkey: $address" <<< "$blockInfo"); then
echo "FAILURE: The address is correct but does not appear in the given block!" >&2
exit 6
fi
echo "The address is correct and was published in the blockchain at around:"
grep -m1 '^Time: ' <<< "$blockInfo" | sed -r 's/Time: (.*) Nonce:.*$/\1/'
fi


Usage examples:
Code:
  These tasks require the bitcoin server to be active:
    Creation: ./bitpoa.bash -cf document.txt -i info.poa -a sha256 -A 0.00000001
    Finding the block: ./bitpoa.bash -b -i info.poa
      (for creation, a second step must be taken to find the block of the transaction in order to speed up verification)
  This task requires the bitcoin server to be stopped:
    Verifying: ./bitpoa.bash -vf document.txt -i info.poa


Title: Re: Proof of authenticity (POA) using the bitcoin blockchain
Post by: wolciph on August 26, 2011, 04:30:37 PM
I would like to thank Grondilu for his bash library (I guess we could call it that) for generating bitcoin addresses.

Here is a bitpoa info file for the script, that I just made for testing purposes:
Code:
file:bitpoa.bash
algo:sha256
address:1Dga4BiLThvbFeA7b2sxzQx2G85uCk67kr
txid:9209f8bfaa967cf2530a6a708ac12b370615ca4e4d5242e8bc28261f12522bce
block:142683
You can check it with
Code:
bitpoa -v -f bitpoa.bash -i bitpoa.bash.poa
where bitpoa.bash.poa is this info file. But it may not work if you copy/paste due to tabbing (yes, I know: tabs are evil) and newlines. However, it should work with the file provided in the archive below.
(blockexplorer link: http://blockexplorer.com/address/1Dga4BiLThvbFeA7b2sxzQx2G85uCk67kr)

Megaupload link to an archive containing the script, grondilu's script and Gavin Andresen's tools: http://www.megaupload.com/?d=BR470E20
(sha256sum: 76ee03f4dc494af8fe16d0340679803eeb745394dbb97d1e1e96c8ebe3d5db2a  bitpoa.tar.gz)

Sorry for multiple posts but I'm having problems sending it all in one chunk.


Title: Re: Proof of authenticity (POA) using the bitcoin blockchain
Post by: theymos on August 27, 2011, 04:21:44 AM
There's a very easy way to do this without any program:

First, SHA-1 the data you want to timestamp (or RIPEMD-160, or SHA-256 and truncate to 160 bits). Then use this to turn it into an address:

http://blockexplorer.com/q/hashtoaddress/putHashHere

Then, send any amount of BTC to the returned address. (If you modify Bitcoin, it's actually possible to create a transaction that sends 0 BTC to an address, which would also work. Then you don't have to destroy BTC.)

Finally, you can see the timestamp here:

http://blockexplorer.com/q/addressfirstseen/timestampAddress


Title: Re: Proof of authenticity (POA) using the bitcoin blockchain
Post by: ArtForz on August 27, 2011, 05:23:30 AM
nice hack, but innovative?
https://bitcointalk.org/index.php?topic=24605.0


Title: Re: Proof of authenticity (POA) using the bitcoin blockchain
Post by: wolciph on August 27, 2011, 05:02:21 PM
I did do a quick search before posting but didn't find anything.
Well, anyhow, my implementation still has the advantage of being automated and not relying on trust in blockexplorer I guess.


Title: Re: Proof of authenticity (POA) using the bitcoin blockchain
Post by: Sukrim on August 27, 2011, 06:06:27 PM
You can do this on your own offline as well.


Title: Re: Proof of authenticity (POA) using the bitcoin blockchain
Post by: Frozenlock on September 11, 2011, 05:57:32 PM
Just so you know, I used this in a real life situation.

I just moved in a new apartment. The previous occupant obviously left a window opened and it rained inside. Now part of the floor is ugly.

http://img8.imageshack.us/img8/8408/dsc01021mf.jpg

I told the owner about it, but I still want to keep a proof that I didn't do it. (What if he dies? Did he wrote somewhere the floor is in this state?)

Instead of "hoping" nothing bad happens, I took some pictures, zipped them, got the SHA-1 and sent 0.01 BTC to the equivalent address.

Here is the official time-stamp that will protect my ass if I ever need to: http://blockexplorer.com/q/addressfirstseen/1Lx3wYgWJJ6Rxj3EyXf8riMFd9SCZNVFzD


Title: Re: Proof of authenticity (POA) using the bitcoin blockchain
Post by: ElectricMucus on September 11, 2011, 06:05:07 PM
A more automated way to accomplish this would be nice.
Lets do this :)


Title: Re: Proof of authenticity (POA) using the bitcoin blockchain
Post by: molecular on March 31, 2012, 09:04:07 PM
A more automated way to accomplish this would be nice.
Lets do this :)

the service could safe-keep the data itself, too (just in case the customer misplaces it) and help with providing expert witnesses for use in court.


Title: Re: Proof of authenticity (POA) using the bitcoin blockchain
Post by: bitcool on March 31, 2012, 09:27:18 PM
Just so you know, I used this in a real life situation.

I just moved in a new apartment. The previous occupant obviously left a window opened and it rained inside. Now part of the floor is ugly.

http://img8.imageshack.us/img8/8408/dsc01021mf.jpg

I told the owner about it, but I still want to keep a proof that I didn't do it. (What if he dies? Did he wrote somewhere the floor is in this state?)

Instead of "hoping" nothing bad happens, I took some pictures, zipped them, got the SHA-1 and sent 0.01 BTC to the equivalent address.

Here is the official time-stamp that will protect my ass if I ever need to: http://blockexplorer.com/q/addressfirstseen/1Lx3wYgWJJ6Rxj3EyXf8riMFd9SCZNVFzD

That 0.01 BTC was sent to hyperspace and even Satoshi can't get it back, correct?

Smart but a more sustainable approach will be better.


Edit: Sorry, didn't scroll up far enough to see theymos's comment.


Title: Re: Proof of authenticity (POA) using the bitcoin blockchain
Post by: mila on March 31, 2012, 09:36:26 PM
(If you modify Bitcoin, it's actually possible to create a transaction that sends 0 BTC to an address, which would also work. Then you don't have to destroy BTC.)

I thought it was legal to send 0.00 btc as long as I pay the .0005 fee

I like the approach of commit coin. they do not destroy the bitcoins at all, in fact the message is computed from the send to and send from transactions. but could be pruned from blockchain eventually. (unless a satoshi is left in the account, but that could be spend by the attacker and empty address pruned anyway)
maybe burning bitcoin is the cost of this