This specification is for version 300 of the CashShuffle protocol.
- The server should support TLSv1.2 between the client and server.
- The server should only accept messages on the wire with the following structure:
- Magic prefix
0x42bcc32669467873. - 4-bytes specifying the length of the message in bytes in big endian order.
- The protobuf payload.
- Magic prefix
In order to avoid client identification and ensure compatibility:
- Transactions should use only ECDSA signing.
- Transactions should use
nLockTime = 0. - Transactions should use
nVersion = 1. - Each input should use
nSequence = 0xfffffffe.
- The client and server should communicate according to the protobuf specification for messages.
- The server should only receive messages of the
Packetstype.
Example payload content for client registering with the server:
Packets: [
Signed{
packet: Packet{
registration: Registration{
amount: bch_in_sats
version: latest_version
type: shuffle_type
}
}
}
]
Example payload serialized bytes:
Work in Progress
After the SSL connection is established, the client should send the server a message containing only the verification key of the player and the desired amount to shuffle in satoshis, the type of shuffle and the protocol version. This message should be unsigned.
Packets: [
Signed{
packet: Packet{
from_key: VerificationKey{
key: verification_key
}
registration: Registration{
amount: bch_in_sats
version: latest_version
type: shuffle_type
}
}
}
]
If all is well with the verification key, the server should send back an simple message with a session value and the player's number in the pool.
Packets: [
Signed{
packet: Packet{
session: some_UUID
number: number_in_pool
}
}
]
If something goes wrong with the handshake, the server should send a blame message and close the connection.
Packets: [
Signed{
packet: Packet{
message: Message{
blame: Blame{
reason: blame_reason_enum
}
}
}
}
]
The server forms pools of a fixed size N. Every player who successfully registers should be added to the current pool and receive a confirmation as above. As long as the pool is not yet full, the server should also broadcast a simple message with the new player's number to all players in the pool, including the new player.
Packets: [
Signed{
packet: Packet{
number: new_player_number_in_pool
}
}
]
After the pool reaches its limit (N), instead of the new player broadcast, the server should broadcast that the pool has entered Phase 1 (Announcement) to all pool participants.
Packets: [
Signed{
packet: Packet{
phase: ANNOUNCEMENT
number: pool_size_N
}
}
]
After the client is registered as a player (it has a session UUID and number in the pool)
it switches to game mode and can send/receive messages. There are two types of messages broadcast and
unicast. broadcast messages are for everyone in the pool and unicast messages are only from one player to another.
Every time the server accepts a message from the client it should check if it has:
- A valid session UUID.
- A valid verification key.
- A valid player number.
- A valid
from_keyfield. - A valid or null
to_keyfield whereto_keymust be in the same pool.
If the message has a null value for to_key field, it means that it should be broadcast to every pool member
If the message does not have a null value for to_key it should be unicast to the specified player.
In the blame phase, players can exclude unreliable players from the pool.
If server got N-1 messages from players to exclude a player with verification key accused_key then the player with this verification key should be excluded. The message should be in the following form:
packet {
packet {
session: "session"
from_key {
key: "from_key"
}
phase: BLAME
message {
blame {
reason: LIAR
accused {
key: "excluded_key"
}
}
}
}
}
Packets: [
Signed{
packet: Packet{
session: session_id
from_key: VerificationKey{
key: verification_key
}
phase: BLAME
message {
blame Blame{
reason: LIAR
accused VerificationKey{
key: accused_key
}
}
}
}
}
]
If one of the players closes their connection during a round of shuffling then the shuffle is terminated and a new shuffle should be initiated by reconnecting to the server.
If everything goes well, all the clients will disconnect when shuffling is complete.
-
CoinJoin: A method by which transactions for a Bitcoin-based blockchain can be built to better protect the privacy of the parties involved. CoinJoin builds a transaction so that it uses identical
inputamounts thus normalizing the uniquely identifiable characteristic whichprivacy attackersrely upon to track the owner's of a particularcoinover time. -
CoinShuffle: A privacy protocol for Bitcoin based blockchains that attempts to achieve the benefits of the
CoinJoinprotocol in a decentralized way that does not rely on a trusted middle man. -
CashShuffle: A companion to the
CoinShuffleprotocol. CashShuffle adds a low-trust infrastructure layer that allows for the discovery ofCashShuffleparticipants as well as facilitating anonymous communication between them as they execute theCashShuffleprotocol to create trustlessCoinJointransactions. -
Blame: This may describe either the
Phaseimmediately following a failedCashShuffleRoundor the specificProtocol Messagethat is sent by aPlayerto signal a failedRound. TheBlameProtocol Messagetakes a specific form. See theServer Messagedocs for more info. -
Client: Any device or application that connects to a
CashShuffleserver with the intention and capability of carrying out the steps in theCashShuffleprotocol. Clients manage most of the shuffling complexity thus minimizing the influence and involvement of theServer. -
Coin: Frequently used as shorthand for an
Outputin a Bitcoin transaction. -
Connection: The underlying network socket between
ClientandServerused to exchangeProtocol Messages. Note,Connectionshave a 1:1 relationship with aPlayer. -
Equivocation:
-
Packet: A specific data type used in the formation of a
Protocol Message. See the communication spec for syntax. -
Phase: Describes each of the stages within a
CashShuffleRound. For complete descriptions see the "flow specification" -
Player: The unique representation of a
Clientwithin aPool. AClientmay participate simultaneously in multiplePools. It may be helpful to think of aPlayeras being linked to its ephemeral keypair (Verification KeyandSigning Key) because all three die at the end of aRound, regardless of its outcome. -
Pool: A group of
Playerswithin theServerthat participate in aRound.Playersare grouped based on the value of theCointhey intend to shuffle and the type of shuffle they intend to perform. WhileClientsmay have multiplePlayersin differentPools, no client should be allowed in the samePoolinstance as it would reduce the effectiveness of theCashShuffleprotocol. -
Protocol Message: A standardized message sent by either the
Serveror aPlayerin a shuffleRoundcontaining data relevant to the state of a shuffleRound. Protocol messages must adhere to theProtobufcommuncation spec outlined in this document. -
Round: An abstraction describing the sequence of events that take place in a single attempt by a
PoolofPlayersto shuffle their coins in adherence to theCashShuffleprotocol. -
Server: An intentionally minimal server whose primary duties are to put
ClientsintoPoolsand act as a blind ( minimal logs ) and dumb ( minimal complexity ) relay ofProtocol Messageduring shuffles. -
Signing Key: The private key portion of the ephemeral keypair created to be used exclusively for signing and verifying protocol messages for a particular
CashShuffleRound. TheVerification Keyand its correspondingSigning Keyare both intended for one time use. -
Verification Key: The public key portion of the ephemeral keypair created to be used exclusively for signing and verifying protocol messages for a particular
CashShuffleRound. TheVerification Keyand its correspondingSigning Keyare both intended for one time use.