Started formatting the Protocol Specification:

in index.rst README.md is splitted in two parts - References now in the
bottom of the page; protocol.rst is the separate file, referenced on top.

Closes: #1033
This commit is contained in:
Dmitri Bogomolov 2021-01-31 20:42:34 +02:00
parent fcfc539d7e
commit c71a6e5843
Signed by untrusted user: g1itch
GPG Key ID: 720A756F18DEED13
2 changed files with 227 additions and 0 deletions

View File

@ -1,4 +1,8 @@
.. mdinclude:: ../README.md
:end-line: 20
:doc:`protocol`
Documentation
-------------
@ -21,3 +25,6 @@ Indices and tables
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
.. mdinclude:: ../README.md
:start-line: 21

220
docs/protocol.rst Normal file
View File

@ -0,0 +1,220 @@
Protocol specification
======================
.. toctree::
:maxdepth: 2
Common standards
----------------
Hashes
^^^^^^
Most of the time `SHA-512 <http://en.wikipedia.org/wiki/SHA-2>`_ hashes are
used, however `RIPEMD-160 <http://en.wikipedia.org/wiki/RIPEMD>`_ 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":
.. highlight:: nasm
::
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. (This is different from Bitcoin).
.. list-table:: Message structure
:header-rows: 1
:widths: auto
* - Field Size
- Description
- Data type
- Comments
* - 4
- magic
- uint32_t
- Magic value indicating message origin network, and used to seek to next
message when stream state is unknown
* - 12
- command
- char[12]
- ASCII string identifying the packet content, NULL padded (non-NULL
padding results in packet rejected)
* - 4
- length
- uint32_t
- Length of payload in number of bytes. Because of other restrictions,
there is no reason why this length would ever be larger than 1600003
bytes. Some clients include a sanity-check to avoid processing messages
which are larger than this.
* - 4
- checksum
- uint32_t
- First 4 bytes of sha512(payload)
* - ?
- message_payload
- uchar[]
- The actual data, a message or an object_. Not to be confused with
objectPayload.
Known magic values:
+-------------+-------------------+
| Magic value | Sent over wire as |
+=============+===================+
| 0xE9BEB4D9 | E9 BE B4 D9 |
+-------------+-------------------+
.. _varint:
Variable length integer
^^^^^^^^^^^^^^^^^^^^^^^
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.
+---------------+----------------+------------------------------------------+
| Value | Storage length | Format |
+===============+================+==========================================+
| < 0xfd | 1 | uint8_t |
+---------------+----------------+------------------------------------------+
| <= 0xffff | 3 | 0xfd followed by the integer as uint16_t |
+---------------+----------------+------------------------------------------+
| <= 0xffffffff | 5 | 0xfe followed by the integer as uint32_t |
+---------------+----------------+------------------------------------------+
| - | 9 | 0xff followed by the integer as uint64_t |
+---------------+----------------+------------------------------------------+
Variable length string
^^^^^^^^^^^^^^^^^^^^^^
Variable length string can be stored using a variable length integer followed by
the string itself.
+------------+-------------+------------+----------------------------------+
| Field Size | Description | Data type | Comments |
+============+=============+============+==================================+
| 1+ | length | |var_int| | Length of the string |
+------------+-------------+------------+----------------------------------+
| ? | string | char[] | The string itself (can be empty) |
+------------+-------------+------------+----------------------------------+
Variable length list of integers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
n integers can be stored using n+1 :ref:`variable length integers <varint>`
where the first var_int equals n.
+------------+-------------+-----------+----------------------------+
| Field Size | Description | Data type | Comments |
+============+=============+===========+============================+
| 1+ | count | |var_int| | Number of var_ints below |
+------------+-------------+-----------+----------------------------+
| 1+ | | var_int | The first value stored |
+------------+-------------+-----------+----------------------------+
| 1+ | | var_int | The second value stored... |
+------------+-------------+-----------+----------------------------+
| 1+ | | var_int | etc... |
+------------+-------------+-----------+----------------------------+
.. |var_int| replace:: :ref:`var_int <varint>`
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.
.. list-table::
:header-rows: 1
:widths: auto
* - Field Size
- Description
- Data type
- Comments
* - 8
- time
- uint64
- the Time.
* - 4
- stream
- uint32
- Stream number for this node
* - 8
- services
- uint64_t
- same service(s) listed in version
* - 16
- IPv6/4
- char[16]
- IPv6 address. IPv4 addresses are written into the message as a 16 byte
`IPv4-mapped IPv6 address <http://en.wikipedia.org/wiki/IPv6#IPv4-mapped_IPv6_addresses>`_
(12 bytes 00 00 00 00 00 00 00 00 00 00 FF FF, followed by the 4 bytes of
the IPv4 address).
* - 2
- port
- uint16_t
- port number
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 later 32 bytes are ignored.
Inventory vectors consist of the following data format:
+------------+-------------+-----------+--------------------+
| Field Size | Description | Data type | Comments |
+============+=============+===========+====================+
| 32 | hash | char[32] | Hash of the object |
+------------+-------------+-----------+--------------------+
Encrypted payload
^^^^^^^^^^^^^^^^^
Bitmessage uses `ECIES <https://en.wikipedia.org/wiki/Integrated_Encryption_Scheme>`_ to encrypt its messages. For more information see Encryption
+------------+-------------+-----------+--------------------------------------------+
| Field Size | Description | Data type | Comments |
+============+=============+===========+============================================+
| 16 | IV | uchar[] | Initialization Vector used for AES-256-CBC |
+------------+-------------+-----------+--------------------------------------------+
| 2 | Curve type | uint16_t | Elliptic Curve type 0x02CA (714) |
+------------+-------------+-----------+--------------------------------------------+
| 2 | X length | uint16_t | Length of X component of public key R |
+------------+-------------+-----------+--------------------------------------------+
| X length | X | uchar[] | X component of public key R |
+------------+-------------+-----------+--------------------------------------------+
| 2 | Y length | uint16_t | Length of Y component of public key R |
+------------+-------------+-----------+--------------------------------------------+
| Y length | Y | uchar[] | Y component of public key R |
+------------+-------------+-----------+--------------------------------------------+
| ? | encrypted | uchar[] | Cipher text |
+------------+-------------+-----------+--------------------------------------------+
| 32 | MAC | uchar[] | HMACSHA256 Message Authentication Code |
+------------+-------------+-----------+--------------------------------------------+