From 361e6c260523a70073b7f31a1fa1f50edbdb00fc Mon Sep 17 00:00:00 2001 From: Dmitri Bogomolov <4glitch@gmail.com> Date: Fri, 5 Mar 2021 00:09:17 +0200 Subject: [PATCH] Finish pubkey object type --- docs/protocol.rst | 155 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 151 insertions(+), 4 deletions(-) diff --git a/docs/protocol.rst b/docs/protocol.rst index 3208adfe..967ab363 100644 --- a/docs/protocol.rst +++ b/docs/protocol.rst @@ -541,13 +541,160 @@ A version 2 pubkey. This is still in use and supported by current clients but * - 64 - public signing key - uchar[] - - The ECC public key used for signing (uncompressed format; normally - prepended with \x04 ) + - The ECC public key used for signing (uncompressed format; + normally prepended with \x04 ) * - 64 - public encryption key - uchar[] - - The ECC public key used for encryption (uncompressed format; normally - prepended with \x04 ) + - The ECC public key used for encryption (uncompressed format; + normally prepended with \x04 ) + +.. list-table:: A version 3 pubkey + :header-rows: 1 + :widths: auto + + * - Field Size + - Description + - Data type + - Comments + * - 4 + - behavior bitfield + - uint32_t + - A bitfield of optional behaviors and features that can be expected from + the node receiving the message. + * - 64 + - public signing key + - uchar[] + - The ECC public key used for signing (uncompressed format; + normally prepended with \x04 ) + * - 64 + - public encryption key + - uchar[] + - The ECC public key used for encryption (uncompressed format; + normally prepended with \x04 ) + * - 1+ + - nonce_trials_per_byte + - var_int + - Used to calculate the difficulty target of messages accepted by this + node. The higher this value, the more difficult the Proof of Work must + be before this individual will accept the message. This number is the + average number of nonce trials a node will have to perform to meet the + Proof of Work requirement. 1000 is the network minimum so any lower + values will be automatically raised to 1000. + * - 1+ + - extra_bytes + - var_int + - Used to calculate the difficulty target of messages accepted by this + node. The higher this value, the more difficult the Proof of Work must + be before this individual will accept the message. This number is added + to the data length to make sending small messages more difficult. + 1000 is the network minimum so any lower values will be automatically + raised to 1000. + * - 1+ + - sig_length + - var_int + - Length of the signature + * - sig_length + - signature + - uchar[] + - The ECDSA signature which, as of protocol v3, covers the object + header starting with the time, appended with the data described in this + table down to the extra_bytes. + +.. list-table:: A version 4 pubkey + :header-rows: 1 + :widths: auto + + * - Field Size + - Description + - Data type + - Comments + * - 32 + - tag + - uchar[] + - The tag, made up of bytes 32-64 of the double hash of the address data + (see example python code below) + * - ? + - encrypted + - uchar[] + - Encrypted pubkey data. + +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 :doc:`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: + +.. code-block:: python + + doubleHashOfAddressData = hashlib.sha512(hashlib.sha512( + encodeVarint(addressVersionNumber) + encodeVarint(streamNumber) + hash + ).digest()).digest() + + +.. list-table:: Encrypted data in version 4 pubkeys: + :header-rows: 1 + :widths: auto + + * - Field Size + - Description + - Data type + - Comments + * - 4 + - behavior bitfield + - uint32_t + - A bitfield of optional behaviors and features that can be expected from + the node receiving the message. + * - 64 + - public signing key + - uchar[] + - The ECC public key used for signing (uncompressed format; + normally prepended with \x04 ) + * - 64 + - public encryption key + - uchar[] + - The ECC public key used for encryption (uncompressed format; + normally prepended with \x04 ) + * - 1+ + - nonce_trials_per_byte + - var_int + - Used to calculate the difficulty target of messages accepted by this + node. The higher this value, the more difficult the Proof of Work must + be before this individual will accept the message. This number is the + average number of nonce trials a node will have to perform to meet the + Proof of Work requirement. 1000 is the network minimum so any lower + values will be automatically raised to 1000. + * - 1+ + - extra_bytes + - var_int + - Used to calculate the difficulty target of messages accepted by this + node. The higher this value, the more difficult the Proof of Work must + be before this individual will accept the message. This number is added + to the data length to make sending small messages more difficult. + 1000 is the network minimum so any lower values will be automatically + raised to 1000. + * - 1+ + - sig_length + - var_int + - Length of the signature + * - sig_length + - signature + - uchar[] + - The ECDSA signature which covers everything from the object header + starting with the time, then appended with the decrypted data down to + the extra_bytes. This was changed in protocol v3. msg ^^^