Protocol Description
This protocol is python implemetation of protocol described in this paper and inspired by this java implementation.
This protocol implemented as a state machine which start from configarable initial state and can evaluate its state to successfull final state or unsuccesfull final state. This machine have 1 input and 2 outputs. Machine input and output messages from another state machines implementing the same protocol and also a log outputs.
Every protocol implenetation is called player.
Player initial state configured by the next patameters and objects:
-
coin
is an object which is reliable for communitcation with bitcoin network -
crytpo
is an object which is reliable for making ecnryption and decryption of messages -
messages
is an object which is reliable for handling the messages between players -
inchan
is an input channel for incoming messages from other players -
outchan
is an output channel for outcomming messages to other players -
logchan
is an logging channel for logging the evoluation of players state -
session
is unique identificator of shuffling round for player -
phase
is a phase of protocol round -
amount
of bitcoins for shuffling -
fee
for bitcoin transaction -
sk
is a player signing key object for signing the messages and transaction -
players
is an dictionary (associative array, kv-storage) where keys correspond to the number of player in the pool and value correspond to players verification key -
addr_new
is a players outcome address for the joint transaction -
change
is players change address for the joint transaction
The protocol not specified the full interface of the object used in the implementation but it expect the used objects to have some methods and properties. Description of such properties described below.
Succesfull final state represent the properly made multiple inputs and outputs transaction for bitcoin network. Unsuccessfull final state represent the fail during the making of multiple input transaction.
Coin object should be able to make the following:
-
coin.address(public_key)
- this method should get an wallet address from players public key -
coin.sufficient_funds(address, amount)
- this method should check for sufficient amount of funds in output with selected address -
coin.make_unsigned_transaction(amount, fee, inputs, outputs, changes)
- this method should prepare the unsigned transaction with selected amount and fee for the inputs, outputs and change outputs for players. inputs, and changes is expected to be dictionary with players verification keys as a keys and addresses as a values. Outputs in supposed to be vector or set. -
get_transaction_signature(transaction, secret_key, verification_key)
- this method should return signature for transaction. Signature should be made with specified secret_key corresponding to specified verification key. -
add_transaction_signatures(transaction, signatures)
- add the signatures to coinjoined transaction. Signatures is expected to be dictionary with inputs public keys as a key and signature as a value. -
verify_tx_signature(signature, transaction, verification_key)
- this method verifies the correspondence of transaction signature to public key. -
broadcast_transaction(transaction)
- broadcast raw transaction to blockchain network. -
verify_signature(signature, message, verification_key)
- this method verifies the signature of message to verification key. It is used for verifing the sender of messages from players from pool.
Crtypto object should be able to make the following:
-
crypto.generate_the_key_pair()
- this method should generate the Ecnryption\Decryption key pair -
crytpo.export_private_key()
- this method should get the private (Decryption) key from the generated key pair -
crytpo.export_public_key()
- this method should get the public (Encryption) key from the generated key pair -
crypto.encrypt(message , pubkey)
- this method should encrypt the message with public key (pubkey
) -
crypto.decrypt(message)
- this method should decrypt message from ciphertext. It raise an exception if decryption is failed -
restore_from_privkey(secret_string)
- this method restore the encryption/decryption keypair from private key expressed in a hex form. -
hash(text)
- computes the hash of the text. In this realizationsha224
choosen as hashing function.
Messages object should have the following fields:
-
messages.packets
- represent the object of sequence of packets in the message -
messages.phases
- represent the aliases for the phases of the protocol
Messages object should have the following methods:
messages.blame_reason(name) - returns the number of blame reason by its name
-
messages.make_greeting(verification_key, amount)
- this method makes a greeting message for entering the pool with verification_key -
messages.blame_the_liar(accused)
- this method forms the message to blame the liar accused by a player -
messages.blame_insufficient_funds(accused)
- this method forms the message to blame the players insufficient funds accused by a player -
messages.blame_equivocation_failure(accused, invalid_packets=None)
- this method forms the message to blame the player who send invalid hash. Invalid packets consist the packets with bad hash -
messages.blame_missing_output(accused)
- this method forms the message to blame accused by the player whose message do not have the players output -
messages.blame_shuffle_failure(accused, hash_value)
- this method forms the message to blame the player with bad hash value -
messages.blame_shuffle_and_equivocation_failure(accused, encryption_key, decryption_key, invalid_packets)
- this methods form the blame message accused by the the player with invalid encryption decryption key. Invalid packet used to prove it. -
messages.blame_invalid_signature(accused)
- this method forms the blame message accused by the player with invalid signature -
messages.blame_wrong_transaction_signature(accused)
- this method forms the blame message accused by the player with wrong transaction signature. -
messages.get_new_addresses()
- get new addresses from the packets -
messages.get_hashes()
- get hashes from packets -
messages.add_signature(signature)
- add new packet with signature -
messages.encryption_keys_count()
- counts the number of encryption keys -
messages.get_signature()
- gets the signature from the last packet -
messages.get_blame_reason()
- gets the blame reason from the last packet -
messages.get_accused_key()
- get the key of player accused for blame from the last packet -
messages.get_invalid_packets()
- get the invalid packets value from the last packet -
messages.get_public_key()
- get the public key from the last packet -
messages.get_decryption_key()
- gets the decryption key from the last packet -
messages.get_signatures_and_packets()
- gets signatures and packets -
messages.get_players()
- gets players from the packet -
messages.get_blame()
- gets blames from the packet -
messages.get_strs()
- gets strs values from the packets -
messages.add_encryption_key(ek, change)
- add a packet which is contain encryption key (ek) and a change address. -
messages.add_str(string)
- add a packet which contain the string -
messages.add_hash(hash_value)
- add a packet with hash_value. -
messages.clear_packets()
- clear the all packets in the message -
messages.shuffle_packets()
- shuffle the packets in the message -
messages.get_session()
- get the session value from the last packet -
messages.get_number()
- get the number value from the last packet -
messages.get_hash()
- get the hash value from the last packet -
messages.get_address()
- get the address value from the last packet -
messages.get_phase()
- get the phase value from the last packet -
messages.get_from_key()
- get the from_key value from the last packet -
messages.get_to_key()
- get the to_key value from the last packet -
messages.get_encryption_key()
- get the encryption key from the last packet -
messages.form_all_packets(sk, session, number, vk_from, vk_to, phase)
- form all packets for the send.sk
is a singing key object.session
is a session value,number
is a number value,vk_from
is a sender verification key,vk_to
is a receiver verifivation key. Ifvk_to
is set toNone
than message broadcasted for all players in the pool.phase
is a phase of the protocol
Messages are prepared for sending with serialization:
messages.packets.SerializeToString()
Messages parsed from string with deserialization:
messages.packets.ParseFromString(string)
This simpliest way for making this object is to use google.protobuf specification. Some methods for Messages object are taken directly from it.
Inchan object should be able to receive the messages with method:
incah.recv()
Outchan object should be able to send the messages with method
outchan.send()
Inchan object should not block Outchan object and vice versa
Logchan object should send data to log with logchan.send()
method.
Sign key object should be able to sign the message with method:
sk.sign(message)
and verify the message with its signature
sk.verify_messafe(signature, message)
Succesfull final state represent the properly made multiple inputs and outputs transaction for bitcoin network. Unsuccessfull final state represent the fail during the making of multiple input transaction.
Protocol implemented as a class. Make the object with constructor
protocol = Round(coin, crypto, messages, inchan, outchan, logchan , session , phase, amount, fee, sk, players, addr_new, change)
And start the protocol evoluation with method
protocol.protocol_definition()