Skip to content

Commit 418762a

Browse files
authored
Merge branch 'main' into JobDeclarator
2 parents 688a5b2 + ad5d444 commit 418762a

4 files changed

+67
-28
lines changed

03-Protocol-Overview.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ The message framing is outlined below:
103103
| msg_length | U24 | Length of the protocol message, not including this header |
104104
| payload | BYTES | Message-specific payload of length msg_length. If the MSB in extension_type (the channel_msg bit) is set the first four bytes are defined as a U32 "channel_id", though this definition is repeated in the message definitions below and these 4 bytes are included in msg_length. |
105105

106+
106107
## 3.3 Reconnecting Downstream Nodes
107108

108109
An upstream stratum node may occasionally request reconnection of its downstream peers to a different host (e.g. due to maintenance reasons, etc.).
@@ -162,7 +163,7 @@ Clients that are not configured to provide telemetry data to the upstream node S
162163
However, they MUST always set vendor to a string describing the manufacturer/developer and firmware version and SHOULD always set `hardware_version` to a string describing, at least, the particular hardware/software package in use.
163164

164165
| Field Name | Data Type | Description |
165-
| ------------------ | --------- | --------------------------------------------------------------------------------------------------------------------------- |
166+
|--------------------|-----------|-----------------------------------------------------------------------------------------------------------------------------|
166167
| protocol | U8 | 0 = Mining Protocol <br>1 = Job Negotiaion <br>2 = Template Distribution Protocol <br> 3 = Job Distribution Protocol |
167168
| min_version | U16 | The minimum protocol version the client supports (currently must be 3) |
168169
| max_version | U16 | The maximum protocol version the client supports (currently must be 3) |
@@ -182,7 +183,7 @@ Response to `SetupConnection` message if the server accepts the connection.
182183
The client is required to verify the set of feature flags that the server supports and act accordingly.
183184

184185
| Field Name | Data Type | Description |
185-
| ------------ | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
186+
|--------------|-----------|---------------------------------------------------------------------------------------------------------------------------------------------------------|
186187
| used_version | U16 | Selected version proposed by the connecting node that the upstream node supports. This version will be used on the connection for the rest of its life. |
187188
| flags | U32 | Flags indicating optional protocol features the server supports. Each protocol from protocol field has its own values/flags. |
188189

04-Protocol-Security.md

+60-22
Original file line numberDiff line numberDiff line change
@@ -331,29 +331,67 @@ If the server provides a non-empty `CIPHER_CHOICE`:
331331
2. New keys `key_new` are derived from the original CipherState keys `key_orig` by taking the first 32 bytes from `ENCRYPT(key_orig, maxnonce, zero_len, zeros)` using the negotiated cipher function where `maxnonce` is 2<sup>64</sup> - 1, `zerolen` is a zero-length byte sequence, and `zeros` is a sequence of 32 bytes filled with zeros. (see `Rekey(k)` function<sup>[8](#reference-8)</sup>)
332332
3. New CipherState objects are reinitialized: `InitializeKey(key_new)`.
333333

334-
### 4.5.6 Transport message encryption and format
335-
336-
After handshake process is finished, both initiator and responder have CipherState objects for encryption and decryption and after initiator validated server's identity, any subsequent traffic is encrypted and decrypted with `EncryptWithAd()` and `DecryptWithAd()` methods of the respectrive CipherState objects with zero-length associated data.
337-
338-
Ciphertext is sent in `NOISE_FRAME` over the wire.
339-
340-
##### NOISE_FRAME
341-
| Field Name | Data Type | Description |
342-
| ---------- | --------- | ----------- |
343-
| ciphertext | B0_64K | AEAD ciphertext including 16 bytes MAC |
344-
345-
Message length: `<Plaintext length> + 18 bytes = <Plaintext length> + <MAC length> + <Type length prefix>`
346-
347-
Maximum message length = 65537 bytes
348-
Maximum ciphertext length = 65535 bytes
349-
Maximum plaintext length 65519 bytes
334+
## 4.6 Encrypted stratum message framing
335+
336+
After handshake process is finished, both initiator and responder have CipherState objects for encryption and decryption and after initiator validated server's identity, any subsequent traffic is encrypted and decrypted with `EncryptWithAd()` and `DecryptWithAd()` methods of the respective CipherState objects with zero-length associated data.
337+
338+
Maximum transport message length (ciphertext) is for noise protocol message 65535 bytes.
339+
340+
Since Stratum Message Frame consists of
341+
- fixed length message header: 6 bytes
342+
- variable length serialized stratum message
343+
344+
Stratum Message header and stratum message payload are processed separately.
345+
346+
#### Encrypting stratum message
347+
1. serialize stratum message into a plaintext binary string (payload)
348+
2. prepare frame header for the stratum message with `message_length` being length of payload ciphertext*
349+
3. Encrypt and concatenate serialized header and payload:
350+
4. `EncryptWithAd([], header)` - 22 bytes
351+
5. `EncryptWithAd([], payload)` - variable length encrypted message
352+
4. concatenate resulting header and payload ciphertext
353+
354+
*converting plaintext length to ciphertext length:
355+
```c
356+
#define MAX_CT_LEN 65535
357+
#define MAC_LEN 16
358+
#define MAX_PT_LEN (MAX_CT_LEN - MAC_LEN)
359+
360+
uint pt_len_to_ct_len(uint pt_len) {
361+
uint remainder;
362+
remainder = pt_len % MAX_PT_LEN;
363+
if (remainder > 0) {
364+
remainder += MAC_LEN;
365+
}
366+
return pt_len / MAX_PT_LEN * MAX_CT_LEN + remainder;
367+
}
368+
```
350369
351-
Note that in regard to Stratum V2 message, `NOISE_FRAME` doesn't necessarily need to contain to exactly one encrypted Stratum message. Ciphertext payload may contain multiple subsequent messages or even only partial message. Examples:
370+
#### Decrypting stratum message
371+
1. read exactly 22 bytes and decrypt into stratum frame or fail
372+
2. read `frame.message_length` number of bytes and decrypt into plaintext payload or fail
373+
3. deserialize plaintext payload into stratum message given by `frame.extension_type` and `frame.message_type` or fail
352374
353-
- `OpenStandardMiningChannelSuccess` followed immediately with `NewMiningJob`
354-
- Arbitrary message containing `B0_16M` type, since the noise ciphertext can be at most `2**16 - 1 == 65535` bytes long
375+
#### Encrypted stratum message frame layout
376+
```
377+
+--------------------------------------------------+-------------------------------------------------------------------+
378+
| Extended noise header | Encrypted stratum-message payload |
379+
+--------------------------------------------------+-------------------+-------------------+---------------------------+
380+
| Header AEAD ciphertext | Noise block 1 | Noise block 2 | Last Noise block |
381+
| 22 Bytes | 65535 Bytes | 65535 Bytes | 17 - 65535 Bytes |
382+
+----------------------------------------+---------+-----------+-------+-----------+-------+---------------+-----------+
383+
| Encrypted Stratum message Header | MAC | ct_pld_1 | MAC_1 | ct_pld_2 | MAC_2 | ct_pld_rest | MAC_rest |
384+
| 6 Bytes | 16 B | 65519 B | 16 B | 65519 B | 16 B | 1 - 65519 B | 16 Bytes |
385+
+================+==========+============+=========+===========+=======+===========+=======+===============+===========+
386+
| extension_type | msg_type | pld_length | <padd | pt_pld_1 | <padd | pt_pld_2 | <padd | pt_pld_rest | <padding> |
387+
| U16 | U8 | U24 | ing> | 65519 B | ing> | 65519 B | ing> | 1 - 65519 B | |
388+
+----------------+----------+------------+---------+-------------------------------------------------------------------+
389+
390+
Serialized stratum-v2 body (payload) is split into 65519-byte chunks and encrypted to form 65535-bytes AEAD ciphertexts,
391+
where `ct_pld_N` is the N-th ciphertext block of payload and `pt_pld_N` is the N-th plaintext block of payload.
392+
```
355393
356-
## 4.6 URL Scheme and Pool Authority Key
394+
## 4.7 URL Scheme and Pool Authority Key
357395
358396
Downstream nodes that want to use the above outlined security scheme need to have configured the **Pool Authority Public Key** of the pool that they intend to connect to. It is provided by the target pool and communicated to its users via a trusted channel.
359397
At least, it can be published on the pool's public website.
@@ -374,7 +412,7 @@ stratum2+tcp://thepool.com/9bXiEd8boQVhq7WddEcERUL5tyyJVFYdU8th3HfbNXK3Yw6GRXh
374412

375413
```
376414
377-
### 4.6.1 Test vector:
415+
### 4.7.1 Test vector:
378416
379417
```
380418

@@ -383,7 +421,7 @@ prefixed_base58check = "9bXiEd8boQVhq7WddEcERUL5tyyJVFYdU8th3HfbNXK3Yw6GRXh"
383421

384422
```
385423
386-
## 4.7 References
424+
## 4.8 References
387425
388426
1. <a id="reference-1"> https://web.cs.ucdavis.edu/~rogaway/papers/ad.pdf</a>
389427
2. <a id="reference-2"> https://www.secg.org/sec2-v2.pdf</a>

07-Template-Distribution-Protocol.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Thus, this message is used to indicate that some additional space in the block/c
1717

1818
The Job Declarator MUST discover the maximum serialized size of the additional outputs which will be added by the pool(s) it intends to use this work.
1919
It then MUST communicate the maximum such size to the Template Provider via this message.
20-
The Template Provider MUST NOT provide `NewWork` messages which would represent consensus-invalid blocks once this additional size — along with a maximally-sized (100 byte) coinbase field — is added.
20+
The Template Provider MUST NOT provide `NewMiningJob` messages which would represent consensus-invalid blocks once this additional size — along with a maximally-sized (100 byte) coinbase field — is added.
2121
Further, the Template Provider MUST consider the maximum additional bytes required in the output count variable-length integer in the coinbase transaction when complying with the size limits.
2222

2323
| Field Name | Data Type | Description |
@@ -45,7 +45,7 @@ The primary template-providing function. Note that the `coinbase_tx_outputs` byt
4545
## 7.3 `SetNewPrevHash` (Server -> Client)
4646

4747
Upon successful validation of a new best block, the server MUST immediately provide a `SetNewPrevHash` message.
48-
If a `NewWork` message has previously been sent with an empty `min_ntime`, which is valid work based on the `prev_hash` contained in this message, the `template_id` field SHOULD be set to the `job_id` present in that `NewTemplate` message indicating the client MUST begin mining on that template as soon as possible.
48+
If a `NewMiningJob` message has previously been sent with an empty `min_ntime`, which is valid work based on the `prev_hash` contained in this message, the `template_id` field SHOULD be set to the `job_id` present in that `NewTemplate` message indicating the client MUST begin mining on that template as soon as possible.
4949

5050
TODO: Define how many previous works the client has to track (2? 3?), and require that the server reference one of those in `SetNewPrevHash`.
5151

@@ -105,7 +105,7 @@ Upon finding a coinbase transaction/nonce pair which double-SHA256 hashes at or
105105
| Field Name | Data Type | Description |
106106
| ---------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
107107
| template_id | U64 | The template_id field as it appeared in NewTemplate |
108-
| version | U32 | The version field in the block header. Bits not defined by BIP320 as additional nonce MUST be the same as they appear in the NewWork message, other bits may be set to any value. |
108+
| version | U32 | The version field in the block header. Bits not defined by BIP320 as additional nonce MUST be the same as they appear in the NewMiningJob message, other bits may be set to any value. |
109109
| header_timestamp | U32 | The nTime field in the block header. This MUST be greater than or equal to the header_timestamp field in the latest SetNewPrevHash message and lower than or equal to that value plus the number of seconds since the receipt of that message. |
110110
| header_nonce | U32 | The nonce field in the header |
111-
| coinbase_tx | B0_64K | The full serialized coinbase transaction, meeting all the requirements of the NewWork message, above |
111+
| coinbase_tx | B0_64K | The full serialized coinbase transaction, meeting all the requirements of the NewMiningJob message, above |
Loading

0 commit comments

Comments
 (0)