# Auth key generation example



 

In the examples below, the [transport](/mtproto.md#transport) headers are omitted:

> For example, for the [abridged version of the transport »](/mtproto/mtproto-transports.md#abridged), the client sends `0xef` as the first byte (**important:** only prior to the very first data packet), then the packet length is encoded with a single byte (`0x01-0x7e` = data length divided by 4; or `0x7f` followed by 3 bytes (little endian) divided by 4) followed by the data itself. In this case, server responses have the same structure (although the server does not send `0xef`as the first byte). Detailed documentation on creating authorization keys is available [here »](/mtproto/auth_key.md).

#### DH exchange initiation

##### 1) Client sends query to server

<!-- start req_pq_multi -->

Sent payload (excluding transport headers/trailers):

```
0000 | 00 00 00 00 00 00 00 00 78 F4 04 00 61 70 46 6A
0010 | 14 00 00 00 F1 8E 7E BE 51 A1 14 3F C7 A3 66 6B
0020 | E4 BE 54 D6 89 0A 02 DC
```

Payload (de)serialization:

```
req_pq_multi#00000000 nonce:int128 = ResPQ;
```

| Parameter | Offset, Length in bytes | Value | Description |
| --- | --- | --- | --- |
| auth\_key\_id | 0, 8 | `0000000000000000` | 0 since the message is in plain text |
| message\_id | 8, 8 | `78F404006170466A` | Message ID generated as specified [here &raquo;](/mtproto/description.md#message-identifier-msg-id) (unixtime() << 32) + (N*4) |
| message\_length | 16, 4 | `14000000` (20 in decimal) | Message body length |
| %(req\_pq\_multi) | 20, 4 | `f18e7ebe` | *req_pq_multi* constructor number from TL schema |
| nonce | 24, 16 | `51A1143FC7A3666BE4BE54D6890A02DC` | Random number |

<!-- end req_pq_multi -->

##### 2) Server sends response of the form

<!-- start resPQ -->

Received payload (excluding transport headers/trailers):

```
0000 | 00 00 00 00 00 00 00 00 01 F4 CC C2 61 70 46 6A
0010 | 50 00 00 00 63 24 16 05 51 A1 14 3F C7 A3 66 6B
0020 | E4 BE 54 D6 89 0A 02 DC 63 24 8F 67 48 21 4E AB
0030 | 8A 2F 4C C8 76 E1 19 74 08 2E 9C DB 98 C8 0C DA
0040 | 4B 00 00 00 15 C4 B5 1C 03 00 00 00 85 FD 64 DE
0050 | 85 1D 9D D0 A5 B7 F7 09 35 5F C3 0B 21 6B E8 6C
0060 | 02 2B B4 C3
```

Payload (de)serialization:

```
resPQ#00000000 nonce:int128 server_nonce:int128 pq:string server_public_key_fingerprints:Vector<strlong> = ResPQ;
```

| Parameter | Offset, Length in bytes | Value | Description |
| --- | --- | --- | --- |
| auth\_key\_id | 0, 8 | `0000000000000000` | 0 since the message is in plain text |
| message\_id | 8, 8 | `01F4CCC26170466A` | Message ID generated as specified [here &raquo;](/mtproto/description.md#message-identifier-msg-id) (unixtime() << 32) + (N*4) |
| message\_length | 16, 4 | `50000000` (80 in decimal) | Message body length |
| %(resPQ) | 20, 4 | `63241605` | *resPQ* constructor number from TL schema |
| nonce | 24, 16 | `51A1143FC7A3666BE4BE54D6890A02DC` | Value generated by client in Step 1 |
| server\_nonce | 40, 16 | `63248F6748214EAB8A2F4CC876E11974` | Server-generated random number |
| pq | 56, 12 | `082E9CDB98C80CDA4B000000`\
TL byte deserialization \
=> bigendian conversion to decimal\
=> 3358800871349344843 | Single-byte prefix denoting length, an 8-byte string, and three bytes of padding |
| %(Vector strlong) | 68, 4 | `15c4b51c` | *Vector t* constructor number from TL schema |
| count | 72, 4 | `03000000` | Number of elements in server_public_key_fingerprints |
| server\_public\_key\_fingerprints[0] | 76, 8 | `85FD64DE851D9DD0` | 64 lower-order bits of `SHA1(server_public_key)` |
| server\_public\_key\_fingerprints[1] | 84, 8 | `A5B7F709355FC30B` | 64 lower-order bits of `SHA1(server_public_key)` |
| server\_public\_key\_fingerprints[2] | 92, 8 | `216BE86C022BB4C3` | 64 lower-order bits of `SHA1(server_public_key)` |

<!-- end resPQ -->

In our case, the client only has the following public keys, with the following fingerprints:

<!-- start fingerprints -->

* `85FD64DE851D9DD0`

Let's choose the only matching key, the one with fingerprint equal to `85FD64DE851D9DD0`.

<!-- end fingerprints -->

#### Proof of work

##### 3) Client decomposes pq into prime factors such that p &lt; q.

<!-- start pq -->

```
pq = 3358800871349344843
```
Decompose into 2 prime cofactors `p < q`: `3358800871349344843 = 1786331737 * 1880278339`
```
p = 1786331737
q = 1880278339
```

<!-- end pq -->

#### Presenting proof of work; Server authentication

##### 4) `encrypted_data` payload generation

First of all, generate an `encrypted_data` payload as follows:

<!-- start p_q_inner_data_dc -->

Generated payload (excluding transport headers/trailers):

```
0000 | 95 5F F5 A9 08 2E 9C DB 98 C8 0C DA 4B 00 00 00
0010 | 04 6A 79 42 59 00 00 00 04 70 12 C5 43 00 00 00
0020 | 51 A1 14 3F C7 A3 66 6B E4 BE 54 D6 89 0A 02 DC
0030 | 63 24 8F 67 48 21 4E AB 8A 2F 4C C8 76 E1 19 74
0040 | BF 8C B5 BD 9C 5B 4F E7 CF 24 D6 4D 28 1F 89 31
0050 | 15 76 D5 3C 0D A6 5A 83 26 7E 57 31 54 14 C9 A6
0060 | 02 00 00 00
```

Payload (de)serialization:

```
p_q_inner_data_dc#00000000 pq:string p:string q:string nonce:int128 server_nonce:int128 new_nonce:int256 dc:int = P_Q_inner_data;
```

| Parameter | Offset, Length in bytes | Value | Description |
| --- | --- | --- | --- |
| %(p\_q\_inner\_data\_dc) | 0, 4 | `955ff5a9` | *p_q_inner_data_dc* constructor number from TL schema |
| pq | 4, 12 | `082E9CDB98C80CDA4B000000`\
TL byte deserialization \
=> bigendian conversion to decimal\
=> 3358800871349344843 | Single-byte prefix denoting length, 8-byte string, and three bytes of padding |
| p | 16, 8 | `046A794259000000`\
TL byte deserialization \
=> bigendian conversion to decimal\
=> 1786331737 | First prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding |
| q | 24, 8 | `047012C543000000`\
TL byte deserialization \
=> bigendian conversion to decimal\
=> 1880278339 | Second prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding |
| nonce | 32, 16 | `51A1143FC7A3666BE4BE54D6890A02DC` | Value generated by client in Step 1 |
| server\_nonce | 48, 16 | `63248F6748214EAB8A2F4CC876E11974` | Value received from server in Step 2 |
| new\_nonce | 64, 32 | `BF8CB5BD9C5B4FE7CF24D64D281F8931` `1576D53C0DA65A83267E57315414C9A6` | Client-generated random number |
| dc | 96, 4 | `02000000` (2 in decimal) | DC ID: `10000` (decimal) has to be added to the DC ID to connect to the test servers; it has to be made negative if the DC we're connecting to is a media (not CDN) DC. |

<!-- end p_q_inner_data_dc -->

The serialization of *P\_Q\_inner\_data* produces **data**, which is used to generate **encrypted\_data** as specified in [step 4.1](/mtproto/auth_key.md).  
These are the inputs to the algorithm specified in [step 4.1](/mtproto/auth_key.md):

<!-- start p_q_inner_data_input -->

```
data = 955FF5A9082E9CDB98C80CDA4B000000046A794259000000047012C54300000051A1143FC7A3666BE4BE54D6890A02DC63248F6748214EAB8A2F4CC876E11974BF8CB5BD9C5B4FE7CF24D64D281F89311576D53C0DA65A83267E57315414C9A602000000
random_padding_bytes = CAA2EE40A79783204C32BE8CB0EB37F550E2B037C8D587641F0AA0CC5A00ED9A482D035C8535ECC4E1D7FD961765525AD4E09497F9152C013CC14E9D50357A280F33E60E86AEF0B92775947BDF76D95966CCD0FF47E06FA6F2C8ACDF
```

<!-- end p_q_inner_data_input -->

And this is the output:

<!-- start p_q_inner_data_output -->

```
encrypted_data = 07FB235B4C7728558405705E3F18B09E5E2434977C42112E50DDE7C339D5893F966E40D8C951E37D9E32538189A83D59E005502B7CC125FBCD346EE75E33D0A26EDFFF456914245AC707B427E1DA7C7EAADBE1DD868B81B675D516E8DD20193FD51CACDE5A2281DCC57A724C77872511F7D156AAA032C7E731F971F3F4C9BE9233A3A1EE782C3311B0D380C0639386B57366AB38CA232B08805095D182C1382F1E0274D3EAE59F08AB7C8F50BB9CE75AB7A2B727A052F720B115BE65F455128B02BF182D243255894E1D376C4B287D45218012FBA1B9CD7619B1CF827FEAB4E00EB9722A126CC022A1DDCC094F3B7F258FDEE75FA21C8DA61F4136C23BADDB0C
```

<!-- end p_q_inner_data_output -->

The length of the final string is 256 bytes.

##### 5) Send req\_DH\_params query with generated `encrypted_data`

<!-- start req_DH_params -->

Sent payload (excluding transport headers/trailers):

```
0000 | 00 00 00 00 00 00 00 00 F4 DD 0B 00 61 70 46 6A
0010 | 40 01 00 00 BE E4 12 D7 51 A1 14 3F C7 A3 66 6B
0020 | E4 BE 54 D6 89 0A 02 DC 63 24 8F 67 48 21 4E AB
0030 | 8A 2F 4C C8 76 E1 19 74 04 6A 79 42 59 00 00 00
0040 | 04 70 12 C5 43 00 00 00 85 FD 64 DE 85 1D 9D D0
0050 | FE 00 01 00 07 FB 23 5B 4C 77 28 55 84 05 70 5E
0060 | 3F 18 B0 9E 5E 24 34 97 7C 42 11 2E 50 DD E7 C3
0070 | 39 D5 89 3F 96 6E 40 D8 C9 51 E3 7D 9E 32 53 81
0080 | 89 A8 3D 59 E0 05 50 2B 7C C1 25 FB CD 34 6E E7
0090 | 5E 33 D0 A2 6E DF FF 45 69 14 24 5A C7 07 B4 27
00A0 | E1 DA 7C 7E AA DB E1 DD 86 8B 81 B6 75 D5 16 E8
00B0 | DD 20 19 3F D5 1C AC DE 5A 22 81 DC C5 7A 72 4C
00C0 | 77 87 25 11 F7 D1 56 AA A0 32 C7 E7 31 F9 71 F3
00D0 | F4 C9 BE 92 33 A3 A1 EE 78 2C 33 11 B0 D3 80 C0
00E0 | 63 93 86 B5 73 66 AB 38 CA 23 2B 08 80 50 95 D1
00F0 | 82 C1 38 2F 1E 02 74 D3 EA E5 9F 08 AB 7C 8F 50
0100 | BB 9C E7 5A B7 A2 B7 27 A0 52 F7 20 B1 15 BE 65
0110 | F4 55 12 8B 02 BF 18 2D 24 32 55 89 4E 1D 37 6C
0120 | 4B 28 7D 45 21 80 12 FB A1 B9 CD 76 19 B1 CF 82
0130 | 7F EA B4 E0 0E B9 72 2A 12 6C C0 22 A1 DD CC 09
0140 | 4F 3B 7F 25 8F DE E7 5F A2 1C 8D A6 1F 41 36 C2
0150 | 3B AD DB 0C
```

Payload (de)serialization:

```
req_DH_params#00000000 nonce:int128 server_nonce:int128 p:string q:string public_key_fingerprint:long encrypted_data:string = Server_DH_Params;
```

| Parameter | Offset, Length in bytes | Value | Description |
| --- | --- | --- | --- |
| auth\_key\_id | 0, 8 | `0000000000000000` | 0 since the message is in plain text |
| message\_id | 8, 8 | `F4DD0B006170466A` | Message ID generated as specified [here &raquo;](/mtproto/description.md#message-identifier-msg-id) (unixtime() << 32) + (N*4) |
| message\_length | 16, 4 | `40010000` (320 in decimal) | Message body length |
| %(req\_DH\_params) | 20, 4 | `bee412d7` | *req_DH_params* constructor number from TL schema |
| nonce | 24, 16 | `51A1143FC7A3666BE4BE54D6890A02DC` | Value generated by client in Step 1 |
| server\_nonce | 40, 16 | `63248F6748214EAB8A2F4CC876E11974` | Value received from server in Step 2 |
| p | 56, 8 | `046A794259000000`\
TL byte deserialization \
=> bigendian conversion to decimal\
=> 1786331737 | First prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding |
| q | 64, 8 | `047012C543000000`\
TL byte deserialization \
=> bigendian conversion to decimal\
=> 1880278339 | Second prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding |
| public\_key\_fingerprint | 72, 8 | `85FD64DE851D9DD0` | `fingerprint` of public key used |
| encrypted\_data | 80, 260 | `FE00010007FB235B4C7728558405705E` `3F18B09E5E2434977C42112E50DDE7C3` `39D5893F966E40D8C951E37D9E325381` `89A83D59E005502B7CC125FBCD346EE7` `5E33D0A26EDFFF456914245AC707B427` `E1DA7C7EAADBE1DD868B81B675D516E8` `DD20193FD51CACDE5A2281DCC57A724C` `77872511F7D156AAA032C7E731F971F3` `F4C9BE9233A3A1EE782C3311B0D380C0` `639386B57366AB38CA232B08805095D1` `82C1382F1E0274D3EAE59F08AB7C8F50` `BB9CE75AB7A2B727A052F720B115BE65` `F455128B02BF182D243255894E1D376C` `4B287D45218012FBA1B9CD7619B1CF82` `7FEAB4E00EB9722A126CC022A1DDCC09` `4F3B7F258FDEE75FA21C8DA61F4136C2`\
 `3BADDB0C` | Value generated above |

<!-- end req_DH_params -->

##### 6) Server responds with:

<!-- start server_DH_params_ok -->

Received payload (excluding transport headers/trailers):

```
0000 | 00 00 00 00 00 00 00 00 01 C8 63 F4 61 70 46 6A
0010 | 78 02 00 00 5C 07 E8 D0 51 A1 14 3F C7 A3 66 6B
0020 | E4 BE 54 D6 89 0A 02 DC 63 24 8F 67 48 21 4E AB
0030 | 8A 2F 4C C8 76 E1 19 74 FE 50 02 00 C3 34 D3 13
0040 | 06 41 74 F4 43 CE 90 E1 3C 83 5F AE A6 AE 96 77
0050 | 08 9A 07 81 CC 8C 17 AD C8 FF 5B 50 72 93 4C 1D
0060 | FB 1F 2B 92 22 19 7D E8 06 18 6E 66 12 E0 CF A2
0070 | 59 38 09 B4 B9 1B 49 F0 06 FF BB D9 EA AA DE 1E
0080 | ED CA 04 6F 50 0A 77 BB 53 8E 3C 2F 02 A4 A6 81
0090 | 4D F0 BC 77 99 3E 49 3B 7F 2C 98 34 4F 67 44 55
00A0 | A9 0A 54 10 70 74 0F 4B 81 1F FF 4B 80 B1 61 73
00B0 | 7E 0E 86 7F F2 0D 03 BE 6B 52 BA 66 F7 31 9D 03
00C0 | B6 21 73 2E 1C 88 02 02 EA F6 1D F3 1D E8 31 E7
00D0 | AC 97 B0 FF DB FF FF A7 01 9D 39 95 53 F3 7B 64
00E0 | 59 13 23 84 43 F4 C5 60 A5 9A 5B A6 AA 6B FA EB
00F0 | 15 9F D2 29 1F CD A4 9A 23 E8 00 91 96 B8 06 2D
0100 | D4 24 F4 5D 3B 43 53 8C 68 B2 C0 70 A8 45 C2 60
0110 | 05 2D D3 C2 66 65 9F A6 C0 C6 A8 FF 36 FB FF 8D
0120 | AB 36 E0 6B EB 5E 18 AF E3 80 27 FD A4 5E 65 88
0130 | 4A 50 34 02 84 0E 21 C1 86 91 01 F4 C6 13 E9 ED
0140 | A6 1C 2E B0 AA 98 70 46 F8 06 9C 2C 00 2E E4 8A
0150 | 95 84 4D D6 2E 0E 4B 61 22 57 39 1B 01 4D 3B 04
0160 | 3D 7C 19 3F 93 63 52 F9 D7 99 CC 40 17 CA 54 48
0170 | 96 BB 09 B3 B5 B8 B7 0C 2C 5E 48 29 5A 82 CF 13
0180 | BC F5 FB 0B A5 29 91 EC 5C 25 18 8A B7 83 CB CE
0190 | D3 57 3B AB B2 55 E8 27 41 EA F4 94 16 09 AE FF
01A0 | 96 0A 4F 2B 41 F9 2E 78 59 51 41 EB C7 36 77 E0
01B0 | 91 04 B8 69 0D 3E 3C 30 FC A7 8B B0 F9 7B 43 36
01C0 | E9 25 BC B0 C8 5A 80 54 58 EE 7B 8D AD 75 99 38
01D0 | 8C 33 83 94 FB 31 7C 0C 6B D5 EC 2C D5 64 17 7E
01E0 | C0 59 E9 70 5E FA F2 04 8E D0 B0 14 EA 89 C6 0E
01F0 | E4 8C C5 47 FE 51 CE 4D 0F 13 DE A2 AB EA 9F 24
0200 | 25 B3 FA 29 87 D9 60 ED EF 61 9B 67 92 1B 2E 92
0210 | 21 9C 81 F7 09 C2 92 44 14 93 22 57 D5 F3 EE B1
0220 | 2D 0A AF 2B 29 51 19 88 DA CC 96 67 92 D7 E2 6F
0230 | 04 EF 5F 78 CC 18 F8 A9 C6 20 66 8F D7 6A 66 8A
0240 | C6 E6 D4 34 74 BF B5 CF C9 27 C1 5B 5D 1F D5 31
0250 | F5 0B 7E DF FC D5 0F 6F 04 A0 88 45 66 CC 85 8D
0260 | 05 A2 B8 46 D6 9A 87 99 D3 60 22 11 2A CC CA 56
0270 | 7D 6B 5E FE 79 9A C9 3D E4 39 A7 D1 6C E6 1C 16
0280 | B0 2F 89 AD 9A CB D0 45 11 1B C5 F1
```

Payload (de)serialization:

```
server_DH_params_ok#00000000 nonce:int128 server_nonce:int128 encrypted_answer:string = Server_DH_Params;
```

| Parameter | Offset, Length in bytes | Value | Description |
| --- | --- | --- | --- |
| auth\_key\_id | 0, 8 | `0000000000000000` | 0 since the message is in plain text |
| message\_id | 8, 8 | `01C863F46170466A` | Message ID generated as specified [here &raquo;](/mtproto/description.md#message-identifier-msg-id) (unixtime() << 32) + (N*4) |
| message\_length | 16, 4 | `78020000` (632 in decimal) | Message body length |
| %(server\_DH\_params\_ok) | 20, 4 | `5c07e8d0` | *server_DH_params_ok* constructor number from TL schema |
| nonce | 24, 16 | `51A1143FC7A3666BE4BE54D6890A02DC` | Value generated by client in Step 1 |
| server\_nonce | 40, 16 | `63248F6748214EAB8A2F4CC876E11974` | Value received from server in Step 2 |
| encrypted\_answer | 56, 596 | `FE500200C334D313064174F443CE90E1` `3C835FAEA6AE9677089A0781CC8C17AD` `C8FF5B5072934C1DFB1F2B9222197DE8` `06186E6612E0CFA2593809B4B91B49F0` `06FFBBD9EAAADE1EEDCA046F500A77BB` `538E3C2F02A4A6814DF0BC77993E493B` `7F2C98344F674455A90A541070740F4B` `811FFF4B80B161737E0E867FF20D03BE` `6B52BA66F7319D03B621732E1C880202` `EAF61DF31DE831E7AC97B0FFDBFFFFA7` `019D399553F37B645913238443F4C560` `A59A5BA6AA6BFAEB159FD2291FCDA49A` `23E8009196B8062DD424F45D3B43538C` `68B2C070A845C260052DD3C266659FA6` `C0C6A8FF36FBFF8DAB36E06BEB5E18AF` `E38027FDA45E65884A503402840E21C1` `869101F4C613E9EDA61C2EB0AA987046` `F8069C2C002EE48A95844DD62E0E4B61` `2257391B014D3B043D7C193F936352F9` `D799CC4017CA544896BB09B3B5B8B70C` `2C5E48295A82CF13BCF5FB0BA52991EC` `5C25188AB783CBCED3573BABB255E827` `41EAF4941609AEFF960A4F2B41F92E78` `595141EBC73677E09104B8690D3E3C30` `FCA78BB0F97B4336E925BCB0C85A8054` `58EE7B8DAD7599388C338394FB317C0C` `6BD5EC2CD564177EC059E9705EFAF204` `8ED0B014EA89C60EE48CC547FE51CE4D` `0F13DEA2ABEA9F2425B3FA2987D960ED` `EF619B67921B2E92219C81F709C29244` `14932257D5F3EEB12D0AAF2B29511988` `DACC966792D7E26F04EF5F78CC18F8A9` `C620668FD76A668AC6E6D43474BFB5CF` `C927C15B5D1FD531F50B7EDFFCD50F6F` `04A0884566CC858D05A2B846D69A8799` `D36022112ACCCA567D6B5EFE799AC93D` `E439A7D16CE61C16B02F89AD9ACBD045`\
 `111BC5F1` | See below |

<!-- end server_DH_params_ok -->

Decrypt `encrypted_answer` using the reverse of the process specified in [step 6](/mtproto/auth_key.md#6-server-responds-with):

<!-- start server_DH_inner_data_input -->

```
encrypted_answer = C334D313064174F443CE90E13C835FAEA6AE9677089A0781CC8C17ADC8FF5B5072934C1DFB1F2B9222197DE806186E6612E0CFA2593809B4B91B49F006FFBBD9EAAADE1EEDCA046F500A77BB538E3C2F02A4A6814DF0BC77993E493B7F2C98344F674455A90A541070740F4B811FFF4B80B161737E0E867FF20D03BE6B52BA66F7319D03B621732E1C880202EAF61DF31DE831E7AC97B0FFDBFFFFA7019D399553F37B645913238443F4C560A59A5BA6AA6BFAEB159FD2291FCDA49A23E8009196B8062DD424F45D3B43538C68B2C070A845C260052DD3C266659FA6C0C6A8FF36FBFF8DAB36E06BEB5E18AFE38027FDA45E65884A503402840E21C1869101F4C613E9EDA61C2EB0AA987046F8069C2C002EE48A95844DD62E0E4B612257391B014D3B043D7C193F936352F9D799CC4017CA544896BB09B3B5B8B70C2C5E48295A82CF13BCF5FB0BA52991EC5C25188AB783CBCED3573BABB255E82741EAF4941609AEFF960A4F2B41F92E78595141EBC73677E09104B8690D3E3C30FCA78BB0F97B4336E925BCB0C85A805458EE7B8DAD7599388C338394FB317C0C6BD5EC2CD564177EC059E9705EFAF2048ED0B014EA89C60EE48CC547FE51CE4D0F13DEA2ABEA9F2425B3FA2987D960EDEF619B67921B2E92219C81F709C2924414932257D5F3EEB12D0AAF2B29511988DACC966792D7E26F04EF5F78CC18F8A9C620668FD76A668AC6E6D43474BFB5CFC927C15B5D1FD531F50B7EDFFCD50F6F04A0884566CC858D05A2B846D69A8799D36022112ACCCA567D6B5EFE799AC93DE439A7D16CE61C16B02F89AD9ACBD045111BC5F1
tmp_aes_key = 16F548177058E8D39C41CBAD4D419446BEB12EB9B8F5AD28EA824B8015F17D81
tmp_aes_iv = C4D14166C1378E35C698460047DBB6075441BE9984611C28837357EBBF8CB5BD
```

<!-- end server_DH_inner_data_input -->

Yielding:

<!-- start server_DH_inner_data_output -->

```
answer_with_hash = 8BB20017894315B136AE5F4BAAD0F0BA20334342BA0D89B551A1143FC7A3666BE4BE54D6890A02DC63248F6748214EAB8A2F4CC876E1197403000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE0001008539DB1E497692EE8BD112463F5F26699039792151BE8B575AA56D8914EDBAA242C2A8096FFAB06211B36291FC4994CB0FDFD37389DF8886F2C6B634C0D01B1C8EBD3E9BE1F49B4A8BD33C3952EF1CEC5E9425CD9C2136CA482A521F9ACC86BEA7D8E224F3D6D78A7F734961EED863EA52EC399C58AE94B733E4CB0AFC728926FB2F457D4AB89576D8067489E323DF8702DEC6EFA2EAF1D85548748D2DFA62925920563076F143D8AE852BCAE61553371BEDA580FEBD952AC7C7C1AFBB3F15934CE815716C6C362F9382BE91DC6F964E97C1A308D63FC1E4DFB2B8395A3E7B9A996C2DD3086488EB281301BEEC1ECEDD00296D76AC7EF7B786EA82F0FA7896DB6170466AA674223E982CE5E5
answer = BA0D89B551A1143FC7A3666BE4BE54D6890A02DC63248F6748214EAB8A2F4CC876E1197403000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE0001008539DB1E497692EE8BD112463F5F26699039792151BE8B575AA56D8914EDBAA242C2A8096FFAB06211B36291FC4994CB0FDFD37389DF8886F2C6B634C0D01B1C8EBD3E9BE1F49B4A8BD33C3952EF1CEC5E9425CD9C2136CA482A521F9ACC86BEA7D8E224F3D6D78A7F734961EED863EA52EC399C58AE94B733E4CB0AFC728926FB2F457D4AB89576D8067489E323DF8702DEC6EFA2EAF1D85548748D2DFA62925920563076F143D8AE852BCAE61553371BEDA580FEBD952AC7C7C1AFBB3F15934CE815716C6C362F9382BE91DC6F964E97C1A308D63FC1E4DFB2B8395A3E7B9A996C2DD3086488EB281301BEEC1ECEDD00296D76AC7EF7B786EA82F0FA7896DB6170466AA674223E982CE5E5
```

<!-- end server_DH_inner_data_output -->

<!-- start server_DH_inner_data -->

Generated payload (excluding transport headers/trailers):

```
0000 | BA 0D 89 B5 51 A1 14 3F C7 A3 66 6B E4 BE 54 D6
0010 | 89 0A 02 DC 63 24 8F 67 48 21 4E AB 8A 2F 4C C8
0020 | 76 E1 19 74 03 00 00 00 FE 00 01 00 C7 1C AE B9
0030 | C6 B1 C9 04 8E 6C 52 2F 70 F1 3F 73 98 0D 40 23
0040 | 8E 3E 21 C1 49 34 D0 37 56 3D 93 0F 48 19 8A 0A
0050 | A7 C1 40 58 22 94 93 D2 25 30 F4 DB FA 33 6F 6E
0060 | 0A C9 25 13 95 43 AE D4 4C CE 7C 37 20 FD 51 F6
0070 | 94 58 70 5A C6 8C D4 FE 6B 6B 13 AB DC 97 46 51
0080 | 29 69 32 84 54 F1 8F AF 8C 59 5F 64 24 77 FE 96
0090 | BB 2A 94 1D 5B CD 1D 4A C8 CC 49 88 07 08 FA 9B
00A0 | 37 8E 3C 4F 3A 90 60 BE E6 7C F9 A4 A4 A6 95 81
00B0 | 10 51 90 7E 16 27 53 B5 6B 0F 6B 41 0D BA 74 D8
00C0 | A8 4B 2A 14 B3 14 4E 0E F1 28 47 54 FD 17 ED 95
00D0 | 0D 59 65 B4 B9 DD 46 58 2D B1 17 8D 16 9C 6B C4
00E0 | 65 B0 D6 FF 9C A3 92 8F EF 5B 9A E4 E4 18 FC 15
00F0 | E8 3E BE A0 F8 7F A9 FF 5E ED 70 05 0D ED 28 49
0100 | F4 7B F9 59 D9 56 85 0C E9 29 85 1F 0D 81 15 F6
0110 | 35 B1 05 EE 2E 4E 15 D0 4B 24 54 BF 6F 4F AD F0
0120 | 34 B1 04 03 11 9C D8 E3 B9 2F CC 5B FE 00 01 00
0130 | 85 39 DB 1E 49 76 92 EE 8B D1 12 46 3F 5F 26 69
0140 | 90 39 79 21 51 BE 8B 57 5A A5 6D 89 14 ED BA A2
0150 | 42 C2 A8 09 6F FA B0 62 11 B3 62 91 FC 49 94 CB
0160 | 0F DF D3 73 89 DF 88 86 F2 C6 B6 34 C0 D0 1B 1C
0170 | 8E BD 3E 9B E1 F4 9B 4A 8B D3 3C 39 52 EF 1C EC
0180 | 5E 94 25 CD 9C 21 36 CA 48 2A 52 1F 9A CC 86 BE
0190 | A7 D8 E2 24 F3 D6 D7 8A 7F 73 49 61 EE D8 63 EA
01A0 | 52 EC 39 9C 58 AE 94 B7 33 E4 CB 0A FC 72 89 26
01B0 | FB 2F 45 7D 4A B8 95 76 D8 06 74 89 E3 23 DF 87
01C0 | 02 DE C6 EF A2 EA F1 D8 55 48 74 8D 2D FA 62 92
01D0 | 59 20 56 30 76 F1 43 D8 AE 85 2B CA E6 15 53 37
01E0 | 1B ED A5 80 FE BD 95 2A C7 C7 C1 AF BB 3F 15 93
01F0 | 4C E8 15 71 6C 6C 36 2F 93 82 BE 91 DC 6F 96 4E
0200 | 97 C1 A3 08 D6 3F C1 E4 DF B2 B8 39 5A 3E 7B 9A
0210 | 99 6C 2D D3 08 64 88 EB 28 13 01 BE EC 1E CE DD
0220 | 00 29 6D 76 AC 7E F7 B7 86 EA 82 F0 FA 78 96 DB
0230 | 61 70 46 6A
```

Payload (de)serialization:

```
server_DH_inner_data#00000000 nonce:int128 server_nonce:int128 g:int dh_prime:string g_a:string server_time:int = Server_DH_inner_data;
```

| Parameter | Offset, Length in bytes | Value | Description |
| --- | --- | --- | --- |
| %(server\_DH\_inner\_data) | 0, 4 | `ba0d89b5` | *server_DH_inner_data* constructor number from TL schema |
| nonce | 4, 16 | `51A1143FC7A3666BE4BE54D6890A02DC` | Value generated by client in Step 1 |
| server\_nonce | 20, 16 | `63248F6748214EAB8A2F4CC876E11974` | Value received from server in Step 2 |
| g | 36, 4 | `03000000` (3 in decimal) | Value received from server in Step 2 |
| dh\_prime | 40, 260 | `FE000100C71CAEB9C6B1C9048E6C522F` `70F13F73980D40238E3E21C14934D037` `563D930F48198A0AA7C14058229493D2` `2530F4DBFA336F6E0AC925139543AED4` `4CCE7C3720FD51F69458705AC68CD4FE` `6B6B13ABDC9746512969328454F18FAF` `8C595F642477FE96BB2A941D5BCD1D4A` `C8CC49880708FA9B378E3C4F3A9060BE` `E67CF9A4A4A695811051907E162753B5` `6B0F6B410DBA74D8A84B2A14B3144E0E` `F1284754FD17ED950D5965B4B9DD4658` `2DB1178D169C6BC465B0D6FF9CA3928F` `EF5B9AE4E418FC15E83EBEA0F87FA9FF` `5EED70050DED2849F47BF959D956850C` `E929851F0D8115F635B105EE2E4E15D0` `4B2454BF6F4FADF034B10403119CD8E3`\
 `B92FCC5B` | 2048-bit prime, in big-endian byte order, to be checked as specified in the auth key docs |
| g\_a | 300, 260 | `FE0001008539DB1E497692EE8BD11246` `3F5F26699039792151BE8B575AA56D89` `14EDBAA242C2A8096FFAB06211B36291` `FC4994CB0FDFD37389DF8886F2C6B634` `C0D01B1C8EBD3E9BE1F49B4A8BD33C39` `52EF1CEC5E9425CD9C2136CA482A521F` `9ACC86BEA7D8E224F3D6D78A7F734961` `EED863EA52EC399C58AE94B733E4CB0A` `FC728926FB2F457D4AB89576D8067489` `E323DF8702DEC6EFA2EAF1D85548748D` `2DFA62925920563076F143D8AE852BCA` `E61553371BEDA580FEBD952AC7C7C1AF` `BB3F15934CE815716C6C362F9382BE91` `DC6F964E97C1A308D63FC1E4DFB2B839` `5A3E7B9A996C2DD3086488EB281301BE` `EC1ECEDD00296D76AC7EF7B786EA82F0`\
 `FA7896DB` | `g_a` diffie-hellman parameter |
| server\_time | 560, 4 | `6170466A` (1783001185 in decimal) | Server time |

<!-- end server_DH_inner_data -->

##### 7) Client computes random 2048-bit number *b* (using a sufficient amount of entropy) and sends the server a message

First, generate a secure random 2048-bit number b:

<!-- start b -->

```
b = 96E8D3D298D05AA574B92495F566D0C71C2CA5E1A1FCB18CEFF2408CC57F9E5D5EBD18F3DAFB5FA3DA41F6A73ADB14CF36642882D403A39FD640B9A3B4DEAD433DB0FFA55262EBC89A44324E6F3BEDEA1EB9CA19E465E1135B73497B8567ED842DFCC8F02EB2A8E4C8F923826CDF98D717FBF6F6D55313779163D40E3B18289A7BBCD9CC2B2280B888DCC36117E342D352BE67944CC9C723D928339877E7CB47917A582AB8DAB59A9BFFBEC88A21ECCAF93BAEF9AFB4EE3FB69FFF55A1D7EFAE03328C585E39750506D7C795E5737AFC3FF6CA79C7C205269A8BCB3F03D74DF36CE727E8E3D52663F208AE31B786EC852F1BA4C36EFEE2F8528AD1945E2C7ECF
```

<!-- end b -->

Then compute `g_b = pow(g, b) mod dh_prime`

<!-- start g_b -->

```
g_b = 2EE7B6CC1343B2D39A1AAB034551C9912E5DEE8047C6C62FFBD42B5E1894CFCB79EFEF794135A9FAA3F32C88D5D6D19F75289A5362984AC02A53A4E49E78C07E78C35FF505BC707F7F64E9AAA4BFBD0DBB11E3CACE330048C629DB154463731A2833E11130328EDE8C1230B246D1D999A0336CAC5B32BE5780253DE10BAA6513A5A079F2B9D6A59DB7799E97915F556C89407617BE822C7F65532C8E37792442EDD83793940F5606BC1994B4964ED3458C9AD513977F217699D32368315C7BB07D99C9EE77DE069E62E4A4DFDB16F4F911AA1AEF7373A2F49185501BE684A777772BFC4BD99E38FA51014A3E059543BDCF213977FE913E8A3D881C2EB5523B04
```

<!-- end g_b -->

###### 7.1) generation of encrypted\_data

<!-- start client_DH_inner_data -->

Generated payload (excluding transport headers/trailers):

```
0000 | 54 B6 43 66 51 A1 14 3F C7 A3 66 6B E4 BE 54 D6
0010 | 89 0A 02 DC 63 24 8F 67 48 21 4E AB 8A 2F 4C C8
0020 | 76 E1 19 74 00 00 00 00 00 00 00 00 FE 00 01 00
0030 | 2E E7 B6 CC 13 43 B2 D3 9A 1A AB 03 45 51 C9 91
0040 | 2E 5D EE 80 47 C6 C6 2F FB D4 2B 5E 18 94 CF CB
0050 | 79 EF EF 79 41 35 A9 FA A3 F3 2C 88 D5 D6 D1 9F
0060 | 75 28 9A 53 62 98 4A C0 2A 53 A4 E4 9E 78 C0 7E
0070 | 78 C3 5F F5 05 BC 70 7F 7F 64 E9 AA A4 BF BD 0D
0080 | BB 11 E3 CA CE 33 00 48 C6 29 DB 15 44 63 73 1A
0090 | 28 33 E1 11 30 32 8E DE 8C 12 30 B2 46 D1 D9 99
00A0 | A0 33 6C AC 5B 32 BE 57 80 25 3D E1 0B AA 65 13
00B0 | A5 A0 79 F2 B9 D6 A5 9D B7 79 9E 97 91 5F 55 6C
00C0 | 89 40 76 17 BE 82 2C 7F 65 53 2C 8E 37 79 24 42
00D0 | ED D8 37 93 94 0F 56 06 BC 19 94 B4 96 4E D3 45
00E0 | 8C 9A D5 13 97 7F 21 76 99 D3 23 68 31 5C 7B B0
00F0 | 7D 99 C9 EE 77 DE 06 9E 62 E4 A4 DF DB 16 F4 F9
0100 | 11 AA 1A EF 73 73 A2 F4 91 85 50 1B E6 84 A7 77
0110 | 77 2B FC 4B D9 9E 38 FA 51 01 4A 3E 05 95 43 BD
0120 | CF 21 39 77 FE 91 3E 8A 3D 88 1C 2E B5 52 3B 04
```

Payload (de)serialization:

```
client_DH_inner_data#00000000 nonce:int128 server_nonce:int128 retry_id:long g_b:string = Client_DH_Inner_Data;
```

| Parameter | Offset, Length in bytes | Value | Description |
| --- | --- | --- | --- |
| %(client\_DH\_inner\_data) | 0, 4 | `54b64366` | *client_DH_inner_data* constructor number from TL schema |
| nonce | 4, 16 | `51A1143FC7A3666BE4BE54D6890A02DC` | Value generated by client in Step 1 |
| server\_nonce | 20, 16 | `63248F6748214EAB8A2F4CC876E11974` | Value received from server in Step 2 |
| g\_b | 36, 260 | `FE0001002EE7B6CC1343B2D39A1AAB03` `4551C9912E5DEE8047C6C62FFBD42B5E` `1894CFCB79EFEF794135A9FAA3F32C88` `D5D6D19F75289A5362984AC02A53A4E4` `9E78C07E78C35FF505BC707F7F64E9AA` `A4BFBD0DBB11E3CACE330048C629DB15` `4463731A2833E11130328EDE8C1230B2` `46D1D999A0336CAC5B32BE5780253DE1` `0BAA6513A5A079F2B9D6A59DB7799E97` `915F556C89407617BE822C7F65532C8E` `37792442EDD83793940F5606BC1994B4` `964ED3458C9AD513977F217699D32368` `315C7BB07D99C9EE77DE069E62E4A4DF` `DB16F4F911AA1AEF7373A2F49185501B` `E684A777772BFC4BD99E38FA51014A3E` `059543BDCF213977FE913E8A3D881C2E`\
 `B5523B04` | Single-byte prefix denoting length, a 256-byte (2048-bit) string, and zero bytes of padding |
| retry\_id | 296, 8 | `0000000000000000` | Equal to zero at the time of the first attempt; otherwise, it is equal to `auth_key_aux_hash` from the previous failed attempt (see Item 7). |

<!-- end client_DH_inner_data -->

The serialization of *Client\_DH\_Inner\_Data* produces a string **data**. This is used to generate **encrypted\_data** as specified in [step 6](#7-client-computes-random-2048-bit-number-b-using-a-sufficient-amount-of-entropy-and-sends-the-server-a-message), using the following inputs:

<!-- start client_DH_inner_data_input -->

```
data = 54B6436651A1143FC7A3666BE4BE54D6890A02DC63248F6748214EAB8A2F4CC876E119740000000000000000FE0001002EE7B6CC1343B2D39A1AAB034551C9912E5DEE8047C6C62FFBD42B5E1894CFCB79EFEF794135A9FAA3F32C88D5D6D19F75289A5362984AC02A53A4E49E78C07E78C35FF505BC707F7F64E9AAA4BFBD0DBB11E3CACE330048C629DB154463731A2833E11130328EDE8C1230B246D1D999A0336CAC5B32BE5780253DE10BAA6513A5A079F2B9D6A59DB7799E97915F556C89407617BE822C7F65532C8E37792442EDD83793940F5606BC1994B4964ED3458C9AD513977F217699D32368315C7BB07D99C9EE77DE069E62E4A4DFDB16F4F911AA1AEF7373A2F49185501BE684A777772BFC4BD99E38FA51014A3E059543BDCF213977FE913E8A3D881C2EB5523B04
padding = A813B31F76CD0D537283454A
tmp_aes_key = 16F548177058E8D39C41CBAD4D419446BEB12EB9B8F5AD28EA824B8015F17D81
tmp_aes_iv = C4D14166C1378E35C698460047DBB6075441BE9984611C28837357EBBF8CB5BD
```

<!-- end client_DH_inner_data_input -->

Process:

```
data_with_hash := SHA1(data) + data + padding (0-15 random bytes such that total length is divisible by 16)
encrypted_data := AES256_ige_encrypt (data_with_hash, tmp_aes_key, tmp_aes_iv);
```

Output:

<!-- start client_DH_inner_data_output -->

```
encrypted_data = 136CA7E1F58C243372404792D3519F815AA6EC5E0324B2B11D89197CE5FFCDC2E53C5444A399E9C2111C143D1DFDA34932FC5F290EF51E28BE6AD31F68FB6CE9A8273EAD64262D78A5E132E5789E2620CD9C6E4C0A259E8B154FB07BA4725E9F883D2FA8EC59CAA7F683586CC35C3231B2023675C2759CB4194F6BBBC46EA47827CF2B07242357B6FC300EF086AF41D98E06C4DE2FCC41CD9216AF01D30A0DBA421D928D1D7386ECA1D18CA6772466169173425C272A22D78D9E55BEA4DB25EB9BD32D31115563AE2BFCD0374CEAEF3E42661F9059228BFCA3DF79F2E77C4AA5CBCF03963783CE0D6257399F7A4DD644BF1E57F19A9DF46172ECED9610C4F6A5A57FA4D08173732B1BA95B992B8B633A474A9D8FD18BDC673077178C5C20506FD226399C1F87D022C5C395428D92B8E4E39218EA68D3D6E010BBFFE839F8D124C5C458BCDF8FE5F25190F97C0C46C206
```

<!-- end client_DH_inner_data_output -->

The length of the final string is 336 bytes.

###### 7.2) set\_client\_DH\_params query

<!-- start set_client_DH_params -->

Sent payload (excluding transport headers/trailers):

```
0000 | 00 00 00 00 00 00 00 00 E0 73 0E 00 61 70 46 6A
0010 | 78 01 00 00 1F 5F 04 F5 51 A1 14 3F C7 A3 66 6B
0020 | E4 BE 54 D6 89 0A 02 DC 63 24 8F 67 48 21 4E AB
0030 | 8A 2F 4C C8 76 E1 19 74 FE 50 01 00 13 6C A7 E1
0040 | F5 8C 24 33 72 40 47 92 D3 51 9F 81 5A A6 EC 5E
0050 | 03 24 B2 B1 1D 89 19 7C E5 FF CD C2 E5 3C 54 44
0060 | A3 99 E9 C2 11 1C 14 3D 1D FD A3 49 32 FC 5F 29
0070 | 0E F5 1E 28 BE 6A D3 1F 68 FB 6C E9 A8 27 3E AD
0080 | 64 26 2D 78 A5 E1 32 E5 78 9E 26 20 CD 9C 6E 4C
0090 | 0A 25 9E 8B 15 4F B0 7B A4 72 5E 9F 88 3D 2F A8
00A0 | EC 59 CA A7 F6 83 58 6C C3 5C 32 31 B2 02 36 75
00B0 | C2 75 9C B4 19 4F 6B BB C4 6E A4 78 27 CF 2B 07
00C0 | 24 23 57 B6 FC 30 0E F0 86 AF 41 D9 8E 06 C4 DE
00D0 | 2F CC 41 CD 92 16 AF 01 D3 0A 0D BA 42 1D 92 8D
00E0 | 1D 73 86 EC A1 D1 8C A6 77 24 66 16 91 73 42 5C
00F0 | 27 2A 22 D7 8D 9E 55 BE A4 DB 25 EB 9B D3 2D 31
0100 | 11 55 63 AE 2B FC D0 37 4C EA EF 3E 42 66 1F 90
0110 | 59 22 8B FC A3 DF 79 F2 E7 7C 4A A5 CB CF 03 96
0120 | 37 83 CE 0D 62 57 39 9F 7A 4D D6 44 BF 1E 57 F1
0130 | 9A 9D F4 61 72 EC ED 96 10 C4 F6 A5 A5 7F A4 D0
0140 | 81 73 73 2B 1B A9 5B 99 2B 8B 63 3A 47 4A 9D 8F
0150 | D1 8B DC 67 30 77 17 8C 5C 20 50 6F D2 26 39 9C
0160 | 1F 87 D0 22 C5 C3 95 42 8D 92 B8 E4 E3 92 18 EA
0170 | 68 D3 D6 E0 10 BB FF E8 39 F8 D1 24 C5 C4 58 BC
0180 | DF 8F E5 F2 51 90 F9 7C 0C 46 C2 06
```

Payload (de)serialization:

```
set_client_DH_params#00000000 nonce:int128 server_nonce:int128 encrypted_data:string = Set_client_DH_params_answer;
```

| Parameter | Offset, Length in bytes | Value | Description |
| --- | --- | --- | --- |
| auth\_key\_id | 0, 8 | `0000000000000000` | 0 since the message is in plain text |
| message\_id | 8, 8 | `E0730E006170466A` | Message ID generated as specified [here &raquo;](/mtproto/description.md#message-identifier-msg-id) (unixtime() << 32) + (N*4) |
| message\_length | 16, 4 | `78010000` (376 in decimal) | Message body length |
| %(set\_client\_DH\_params) | 20, 4 | `1f5f04f5` | *set_client_DH_params* constructor number from TL schema |
| nonce | 24, 16 | `51A1143FC7A3666BE4BE54D6890A02DC` | Value generated by client in Step 1 |
| server\_nonce | 40, 16 | `63248F6748214EAB8A2F4CC876E11974` | Value received from server in Step 2 |
| encrypted\_data | 56, 340 | `FE500100136CA7E1F58C243372404792` `D3519F815AA6EC5E0324B2B11D89197C` `E5FFCDC2E53C5444A399E9C2111C143D` `1DFDA34932FC5F290EF51E28BE6AD31F` `68FB6CE9A8273EAD64262D78A5E132E5` `789E2620CD9C6E4C0A259E8B154FB07B` `A4725E9F883D2FA8EC59CAA7F683586C` `C35C3231B2023675C2759CB4194F6BBB` `C46EA47827CF2B07242357B6FC300EF0` `86AF41D98E06C4DE2FCC41CD9216AF01` `D30A0DBA421D928D1D7386ECA1D18CA6` `772466169173425C272A22D78D9E55BE` `A4DB25EB9BD32D31115563AE2BFCD037` `4CEAEF3E42661F9059228BFCA3DF79F2` `E77C4AA5CBCF03963783CE0D6257399F` `7A4DD644BF1E57F19A9DF46172ECED96` `10C4F6A5A57FA4D08173732B1BA95B99` `2B8B633A474A9D8FD18BDC673077178C` `5C20506FD226399C1F87D022C5C39542` `8D92B8E4E39218EA68D3D6E010BBFFE8` `39F8D124C5C458BCDF8FE5F25190F97C`\
 `0C46C206` | Encrypted client_DH_inner_data generated previously, serialized as a TL byte string |

<!-- end set_client_DH_params -->

##### 8) Auth key generation

The client computes the auth\_key using formula `g_a^b mod dh_prime`:

<!-- start auth_key -->

```
auth_key = 8E1081A1B5CA1B399A9A9D7E08BB9A9182AB634F8C03F2A49F944E2F944A9C71EDBA61A32A70D3DADEB33752AE515B16B2D8E75039C40EBE18136775C3727372A8DF486606D671FD63842DF0A44ACC31E68B7B1EC6A731A1DC5C748F0CB46AC00FDE363F0520B51D9B59EAE519EA511A8E8591FC7010DF0B07CDBAB04013DD85172CB54555DC5C982EA0A5DCF4411E798D338B823161FD8C93100B7A426186B4C16F9113521081C8D2075872F4A0CF238034843DC01F2C26828721A2E2FFD93A9B0142B8DF6355C43D9AEF5B448F1CC0D84E0E72A7FF494D4CC3B1650050DDEC5DC321ADA68E420F45098280CEAB58A1CBFAA60FFF3218E56B4741143AC5A6F0
```

<!-- end auth_key -->

##### 9) Final server reply

The server verifies and confirms that auth\_key\_hash is unique: since it's unique, it replies with the following:

<!-- start dh_gen_ok -->

Received payload (excluding transport headers/trailers):

```
0000 | 00 00 00 00 00 00 00 00 01 A4 4A EF 62 70 46 6A
0010 | 34 00 00 00 34 F7 CB 3B 51 A1 14 3F C7 A3 66 6B
0020 | E4 BE 54 D6 89 0A 02 DC 63 24 8F 67 48 21 4E AB
0030 | 8A 2F 4C C8 76 E1 19 74 AA 40 4B 58 DF 40 4D 8F
0040 | 36 37 72 B1 4C E5 A5 6F
```

Payload (de)serialization:

```
dh_gen_ok#00000004 nonce:int128 server_nonce:int128 new_nonce_hash1:int128 = Set_client_DH_params_answer;
```

| Parameter | Offset, Length in bytes | Value | Description |
| --- | --- | --- | --- |
| auth\_key\_id | 0, 8 | `0000000000000000` | 0 since the message is in plain text |
| message\_id | 8, 8 | `01A44AEF6270466A` | Message ID generated as specified [here &raquo;](/mtproto/description.md#message-identifier-msg-id) (unixtime() << 32) + (N*4) |
| message\_length | 16, 4 | `34000000` (52 in decimal) | Message body length |
| %(dh\_gen\_ok) | 20, 4 | `34f7cb3b` | *dh_gen_ok* constructor number from TL schema |
| nonce | 24, 16 | `51A1143FC7A3666BE4BE54D6890A02DC` | Value generated by client in Step 1 |
| server\_nonce | 40, 16 | `63248F6748214EAB8A2F4CC876E11974` | Value received from server in Step 2 |
| new\_nonce\_hash1 | 56, 16 | `AA404B58DF404D8F363772B14CE5A56F` | The 128 lower-order bits of SHA1 of the byte string derived from the `new_nonce` string by adding a single byte with the value of 1, 2, or 3, and followed by another 8 bytes with `auth_key_aux_hash`. Different values are required to prevent an intruder from changing server response dh_gen_ok into dh_gen_retry. |

<!-- end dh_gen_ok -->

