Bitmessage Protocol Version 3

Hashes
Most of the time SHA-512 hashes are used, however RIPEMD-160 is also used when creating an address.

A double-round of SHA-512 is used for the Proof Of Work. Example of double-SHA-512 encoding of string "hello":

hello 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043(first round of sha-512) 0592a10584ffabf96539f3d780d776828c67da1ab5b169e9e8aed838aaecc9ed36d49ff1423c55f019e050c66c6324f53588be88894fef4dcffdb74b98e2b200(second round of sha-512)

For Bitmessage addresses (RIPEMD-160) this would give:

hello 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043(first round is sha-512) 79a324faeebcbf9849f310545ed531556882487e (with ripemd-160)

Common structures
All integers are encoded in big endian

Message structure
Known magic values:

Variable length integer
An integer can be encoded depending on the represented value to save space. Variable length integers always precede an array/vector of a type of data that may vary in length. Varints MUST use the minimum possible number of bytes to encode a value. For example; the value 6 can be encoded with one byte therefore a varint that uses three bytes to encode the value 6 is malformed and the decoding task must be aborted.

Variable length string
A variable length string can be stored using a variable length integer to encode the length followed by the string itself.

Variable length list of integers
n integers can be stored using n+1 variable length integers where the first var_int equals n.

Network address
When a network address is needed somewhere, this structure is used. Network addresses are not prefixed with a timestamp or stream in the version message.

Inventory Vectors
Inventory vectors are used for notifying other nodes about objects they have or data which is being requested. Two rounds of SHA-512 are used, resulting in a 64 byte hash. Only the first 32 bytes are used; the remaining 32 bytes are ignored.

Inventory vectors consist of the following data format:

Envelope
Bitmessage uses ECIES to encrypt its messages. For more information see Encryption

Tagged Envelope
A tagged envelope is identical to an plain envelope but prepended with a tag. Tagged envelopes are only used by v4 pubkeys and v5 broadcasts.

Message Encodings
Further values for the message encodings can be decided upon by the community. Any MIME or MIME-like encoding format, should they be used, should make use of Bitmessage's 8-bit bytes.

Node services
The following services are currently assigned:

Message types
Undefined messages received on the wire must be ignored.

error
error is used to convey the reason for a following disconnection.

The only error PyBitmessage sends is a FATAL error when it receives a version message where the timestamp is out by more than hour from its own

version
When a node creates an outgoing connection, it will immediately advertise its version. The remote node will respond with its version. No further communication is possible until both peers have exchanged their version. A PyBitmessage server responds with verack then version. A bmd server responds with version then verack

A "verack" packet shall be sent if the version packet was accepted. Once you have sent and received a verack messages with the remote node, send an addr message advertising up to 1,000 peers of which you are aware, and one or more inv messages advertising all of the valid objects of which you are aware.

verack
This message is sent in reply to version and has no payload. The TCP timeout starts out at 20 seconds; after verack messages are exchanged, the timeout is raised to 10 minutes.

If both sides announce that they support SSL, they MUST perform a SSL handshake immediately after they both send and receive verack. During this SSL handshake, the TCP client acts as a SSL client, and the TCP server acts as a SSL server. PyBitmessage v0.5.4 or later requires the AECDH-AES256-SHA cipher using the secp256k1 curve over TLSv1.

addr
Provide information on known nodes of the network. Only nodes that have been known to be on the network in the last 3 hours should be advertised. This command is regularly abused and any entries should not be relied upon as being nodes

inv
Allows a node to advertise its knowledge of one or more objects.

getdata
getdata is used in response to an inv message to retrieve the content of a specific object after filtering known elements.

Current usage reveals getdata to only ever contain 1 entry

ping
ping is used to check whether a peer is still responsive and has no payload. A ping should be sent if a peer has not sent anything for more than 5 minutes. A peer receiving a ping may either close the connection or keep it open. To keep a connection open a peer should respond with either a pong (if it has nothing to send) or any contextually valid message. If a peer is silent for a full 10 minutes the connection should be closed.

pong
pong may be sent in response to a ping. pong may also be sent pre-emptively when a node recognises it hasn't sent anything to a peer for up to 5 minutes and wishes to keep the connection open. pong has no payload.

object
An object is a message which is shared throughout a stream. It is the only message which propagates; all others are only between two nodes. Objects have a type, like 'msg', or 'broadcast'. To be a valid object, the Proof Of Work must be done. The maximum allowable length of an object (not to be confused with the objectPayload) is 218 bytes (256 KiB).

Object types
Here are the payloads for various object types.

getpubkey
When a node has the hash of a public key (from an address) but not the public key itself, it must send out a request for the public key.

v2 pubkey
This is the first 3 fields of an identity (behavior bitfield, public signing key, and public encryption key). The proof of work difficulty fields (nonce_trials_per_byte and extra_bytes) are omitted, inferring the network default values. For clarity This is still in use and supported by PyBitmessage but new v2 addresses are not generated by PyBitmessage.

v3 pubkey
This is the full identity structure protected by a signature

v4 pubkey
This is basically an encrypted v3 pubkey except the version is is 4.

When version 4 pubkeys are created, most of the data in the pubkey is encrypted. This is done in such a way that only someone who has the Bitmessage address which corresponds to a pubkey can decrypt and use that pubkey. This prevents people from gathering pubkeys sent around the network and using the data from them to create messages to be used in spam or in flooding attacks.

In order to encrypt the pubkey data, a double SHA-512 hash is calculated from the address version number, stream number, and ripe hash of the Bitmessage address that the pubkey corresponds to. The first 32 bytes of this hash are used to create a public and private key pair with which to encrypt and decrypt the pubkey data, using the same algorithm as message encryption (see Encryption). The remaining 32 bytes of this hash are added to the unencrypted part of the pubkey and used as a tag, as above. This allows nodes to determine which pubkey to decrypt when they wish to send a message.

In PyBitmessage, the double hash of the address data is calculated using the python code below:

doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(encodeVarint(addressVersionNumber) + encodeVarint(streamNumber) + hash).digest).digest

msg
Used for person-to-person messages.

msg ack
A special form of msg used as an acknowledgement receipt. The objectType and version fields in the object header are set exactly the same as for a v1 msg

broadcast
Users who are subscribed to the sending address will see the message appear in their inbox.

Pubkey objects and v5 broadcast objects are encrypted the same way: The data encoded in the sender's Bitmessage address is hashed twice. The first 32 bytes of the resulting hash constitutes the "private" encryption key and the last 32 bytes constitute a tag so that anyone listening can easily decide if this particular message is interesting. The sender calculates the public key from the private key and then encrypts the object with this public key. Thus anyone who knows the Bitmessage address of the sender of a broadcast or pubkey object can decrypt it.

Having a broadcast version of 5 indicates that a tag is used which, in turn, is used when the sender's address version is >=4.

Decrypted broadcast
A decrypted broadcast is nearly identical to a decrypted msg. The decrypted broadcast does not have destination ripe field nor an acknowlegement field.