In the examples below, the transport headers are omitted:
For example, for the abridged version of the transport », the client sends
0xefas 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; or0x7ffollowed 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 send0xefas the first byte). Detailed documentation on creating authorization keys is available here ».
Sent payload (excluding transport headers/trailers):
0000 | 00 00 00 00 00 00 00 00 90 1E 05 00 76 BB 12 6A
0010 | 14 00 00 00 F1 8E 7E BE B2 7A 68 0E 9C 46 69 59
0020 | 8A A9 0C 13 80 4D 1A 2B
Payload (de)serialization:
req_pq_multi#be7e8ef1 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 | 901E050076BB126A |
Message ID generated as specified here » (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 | B27A680E9C4669598AA90C13804D1A2B |
Random number |
Received payload (excluding transport headers/trailers):
0000 | 00 00 00 00 00 00 00 00 01 8C D0 BE 76 BB 12 6A
0010 | 50 00 00 00 63 24 16 05 B2 7A 68 0E 9C 46 69 59
0020 | 8A A9 0C 13 80 4D 1A 2B 25 83 74 61 16 A6 6C 44
0030 | FD 1B CA A1 14 33 3E 7A 08 1B 69 C8 1F BC E9 18
0040 | 55 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#05162463 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 | 018CD0BE76BB126A |
Message ID generated as specified here » (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 | B27A680E9C4669598AA90C13804D1A2B |
Value generated by client in Step 1 |
| server_nonce | 40, 16 | 2583746116A66C44FD1BCAA114333E7A |
Server-generated random number |
| pq | 56, 12 | 081B69C81FBCE91855000000TL byte deserialization => bigendian conversion to decimal => 1975329950217607253 |
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) |
In our case, the client only has the following public keys, with the following fingerprints:
85FD64DE851D9DD0Let's choose the only matching key, the one with fingerprint equal to 85FD64DE851D9DD0.
pq = 1975329950217607253
Decompose into 2 prime cofactors p < q: 1975329950217607253 = 1207167769 * 1636334237
p = 1207167769
q = 1636334237
encrypted_data payload generationFirst of all, generate an encrypted_data payload as follows:
Generated payload (excluding transport headers/trailers):
0000 | 95 5F F5 A9 08 1B 69 C8 1F BC E9 18 55 00 00 00
0010 | 04 47 F3 EB 19 00 00 00 04 61 88 7A 9D 00 00 00
0020 | B2 7A 68 0E 9C 46 69 59 8A A9 0C 13 80 4D 1A 2B
0030 | 25 83 74 61 16 A6 6C 44 FD 1B CA A1 14 33 3E 7A
0040 | 1D 44 72 DD C6 4E 52 BD E1 D2 D9 C0 B8 56 0E 05
0050 | 9B FE 8C 6F C2 57 AE 1B 7E 4C 34 05 20 45 B7 4E
0060 | 02 00 00 00
Payload (de)serialization:
p_q_inner_data_dc#a9f55f95 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 | 081B69C81FBCE91855000000TL byte deserialization => bigendian conversion to decimal => 1975329950217607253 |
Single-byte prefix denoting length, 8-byte string, and three bytes of padding |
| p | 16, 8 | 0447F3EB19000000TL byte deserialization => bigendian conversion to decimal => 1207167769 |
First prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding |
| q | 24, 8 | 0461887A9D000000TL byte deserialization => bigendian conversion to decimal => 1636334237 |
Second prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding |
| nonce | 32, 16 | B27A680E9C4669598AA90C13804D1A2B |
Value generated by client in Step 1 |
| server_nonce | 48, 16 | 2583746116A66C44FD1BCAA114333E7A |
Value received from server in Step 2 |
| new_nonce | 64, 32 | 1D4472DDC64E52BDE1D2D9C0B8560E05 9BFE8C6FC257AE1B7E4C34052045B74E |
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. |
The serialization of P_Q_inner_data produces data, which is used to generate encrypted_data as specified in step 4.1.
These are the inputs to the algorithm specified in step 4.1:
data = 955FF5A9081B69C81FBCE918550000000447F3EB190000000461887A9D000000B27A680E9C4669598AA90C13804D1A2B2583746116A66C44FD1BCAA114333E7A1D4472DDC64E52BDE1D2D9C0B8560E059BFE8C6FC257AE1B7E4C34052045B74E02000000
random_padding_bytes = 37598C31E90E986D66A00592396BB63A21F8A16681059CBEAB03E63CCB9F14D00B4DA8D5B5AC6857FF802FD7E9F6EB6B8E342EE4DCB005DB4C3249B2F0ED1F882996FED6CDDCF376F677F3961C48F40BCF1AEEAA23AB0DDB727DDA6F
And this is the output:
encrypted_data = 26D11DA5744725B1649F640AB6ECDC9CB02835AFEA501C878AA85258E666BE21A570B31632E93C82A4256396F4641A43A3315D35C2ACA2841BAF53C0AD9D2D98D89ABF3DEC26142175551F78330F3055B707ECFDDD42A3FC89CDC5C03F22C8F58FEBE4D3BFEE0F33F63CFB0F6E714199A06AB14179D89EE81B047F664D063E60C9CF9C84E5684BD649A5C76BBDBCE9AA8C7F51D3DD86B6E7DD10B05EDC5AC27C479401A261B256822901394A3D75D75EE99C89047241CFD9AC4AEC2362169E28367B5EC09C7B951D42D3DE42C554240C40CA5DCFC5CC819737F877C81ECED67D0053E52B1E3F6C715705BAD1DE6A50AC61DC5355817BB7882C016327F1F38656
The length of the final string is 256 bytes.
encrypted_dataSent payload (excluding transport headers/trailers):
0000 | 00 00 00 00 00 00 00 00 A0 61 0D 00 76 BB 12 6A
0010 | 40 01 00 00 BE E4 12 D7 B2 7A 68 0E 9C 46 69 59
0020 | 8A A9 0C 13 80 4D 1A 2B 25 83 74 61 16 A6 6C 44
0030 | FD 1B CA A1 14 33 3E 7A 04 47 F3 EB 19 00 00 00
0040 | 04 61 88 7A 9D 00 00 00 85 FD 64 DE 85 1D 9D D0
0050 | FE 00 01 00 26 D1 1D A5 74 47 25 B1 64 9F 64 0A
0060 | B6 EC DC 9C B0 28 35 AF EA 50 1C 87 8A A8 52 58
0070 | E6 66 BE 21 A5 70 B3 16 32 E9 3C 82 A4 25 63 96
0080 | F4 64 1A 43 A3 31 5D 35 C2 AC A2 84 1B AF 53 C0
0090 | AD 9D 2D 98 D8 9A BF 3D EC 26 14 21 75 55 1F 78
00A0 | 33 0F 30 55 B7 07 EC FD DD 42 A3 FC 89 CD C5 C0
00B0 | 3F 22 C8 F5 8F EB E4 D3 BF EE 0F 33 F6 3C FB 0F
00C0 | 6E 71 41 99 A0 6A B1 41 79 D8 9E E8 1B 04 7F 66
00D0 | 4D 06 3E 60 C9 CF 9C 84 E5 68 4B D6 49 A5 C7 6B
00E0 | BD BC E9 AA 8C 7F 51 D3 DD 86 B6 E7 DD 10 B0 5E
00F0 | DC 5A C2 7C 47 94 01 A2 61 B2 56 82 29 01 39 4A
0100 | 3D 75 D7 5E E9 9C 89 04 72 41 CF D9 AC 4A EC 23
0110 | 62 16 9E 28 36 7B 5E C0 9C 7B 95 1D 42 D3 DE 42
0120 | C5 54 24 0C 40 CA 5D CF C5 CC 81 97 37 F8 77 C8
0130 | 1E CE D6 7D 00 53 E5 2B 1E 3F 6C 71 57 05 BA D1
0140 | DE 6A 50 AC 61 DC 53 55 81 7B B7 88 2C 01 63 27
0150 | F1 F3 86 56
Payload (de)serialization:
req_DH_params#d712e4be 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 | A0610D0076BB126A |
Message ID generated as specified here » (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 | B27A680E9C4669598AA90C13804D1A2B |
Value generated by client in Step 1 |
| server_nonce | 40, 16 | 2583746116A66C44FD1BCAA114333E7A |
Value received from server in Step 2 |
| p | 56, 8 | 0447F3EB19000000TL byte deserialization => bigendian conversion to decimal => 1207167769 |
First prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding |
| q | 64, 8 | 0461887A9D000000TL byte deserialization => bigendian conversion to decimal => 1636334237 |
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 | FE00010026D11DA5744725B1649F640A B6ECDC9CB02835AFEA501C878AA85258 E666BE21A570B31632E93C82A4256396 F4641A43A3315D35C2ACA2841BAF53C0 AD9D2D98D89ABF3DEC26142175551F78 330F3055B707ECFDDD42A3FC89CDC5C0 3F22C8F58FEBE4D3BFEE0F33F63CFB0F 6E714199A06AB14179D89EE81B047F66 4D063E60C9CF9C84E5684BD649A5C76B BDBCE9AA8C7F51D3DD86B6E7DD10B05E DC5AC27C479401A261B256822901394A 3D75D75EE99C89047241CFD9AC4AEC23 62169E28367B5EC09C7B951D42D3DE42 C554240C40CA5DCFC5CC819737F877C8 1ECED67D0053E52B1E3F6C715705BAD1 DE6A50AC61DC5355817BB7882C016327F1F38656 |
Value generated above |
Received payload (excluding transport headers/trailers):
0000 | 00 00 00 00 00 00 00 00 01 8C 5E 04 77 BB 12 6A
0010 | 78 02 00 00 5C 07 E8 D0 B2 7A 68 0E 9C 46 69 59
0020 | 8A A9 0C 13 80 4D 1A 2B 25 83 74 61 16 A6 6C 44
0030 | FD 1B CA A1 14 33 3E 7A FE 50 02 00 76 C9 8C E7
0040 | 9E 69 C7 29 41 93 A8 87 A4 B1 7D 35 71 74 5C FA
0050 | 3C 96 59 A2 94 C7 E4 42 D2 CC 35 6B 00 D5 54 B3
0060 | 7B 48 C6 23 5A 3C E4 09 AA 35 EE 64 6C 8D A2 9C
0070 | E2 DB 8B 91 4A D8 C5 8F E9 FF C6 23 3C 25 39 23
0080 | 79 98 97 B4 DB AF 36 43 39 72 1B E9 86 21 FD 74
0090 | 20 5D 59 07 99 3F FE 2B 8F C7 DF FF F4 96 DF 55
00A0 | 9E AE 3F 38 21 4A F1 83 99 D4 BA 55 7A 58 67 67
00B0 | AE A3 99 A3 2C 5D 54 0F 00 01 C3 66 5C BE 70 11
00C0 | D6 48 56 3A 9C FA 8C 94 DE 13 F9 D4 B2 95 1F 4E
00D0 | 6D 29 BE 87 AF 88 46 8F 9C 9F 48 01 91 B1 0A 0F
00E0 | 7E 03 10 1E 6F 1F 57 9C E2 3D 1D E2 EF 15 5F DB
00F0 | 71 C8 EF 00 FA 09 6B 66 94 20 50 AC E9 58 7F 22
0100 | EF 47 5D 83 9F 0A 43 5A CE C1 E5 6E 12 63 B0 60
0110 | F2 E0 85 4C E3 D7 8F 46 DC 6B 11 B5 04 E2 22 EF
0120 | BC 55 C8 64 5D B7 90 1B E3 91 63 9D 4A D7 D3 D5
0130 | 01 C3 F4 8C 5A C3 A5 F5 B6 31 F3 9E CD B7 AB 50
0140 | 2C FD 0F E2 28 29 97 CF FE 3F 5D 31 AE E4 62 B2
0150 | 49 F4 29 18 C1 82 F9 D1 AE 6A 26 4B 6A 8F F9 A1
0160 | 46 39 E0 65 04 25 AE FF 8A 62 91 B9 4E D4 15 30
0170 | 3D 89 70 EC A5 CC FD 91 00 B0 E9 E8 98 3F A6 3A
0180 | 56 1B 61 1C A3 7E E3 25 05 97 E6 47 1C 63 36 E3
0190 | 28 87 FC F5 AA 63 14 18 5F E8 D3 DA 7E EF 2C 01
01A0 | C9 1E E3 51 28 BC 3D 70 D2 94 F8 C4 B5 B7 34 18
01B0 | B7 3B A1 9C AE 4A 8A 44 49 2C 41 BC A0 6A 13 D4
01C0 | 3E A4 94 B0 8F 35 AE FF 24 4F 89 3D 91 68 E5 8D
01D0 | CA 00 4D 53 D3 41 5A 8B 31 01 93 7B 32 11 FC FF
01E0 | 3A 38 73 19 0F 8B 7C 04 1B CD 36 85 CD E9 DA F2
01F0 | 2F 29 31 33 DF A5 7E D4 9C AD FC 7C CA 94 CB 06
0200 | 91 1D BA E5 B6 A1 1E C9 6D 08 B9 C3 88 41 F3 63
0210 | C1 87 D1 A6 3E EA 58 8B 72 B4 BE 35 B3 9C 7F BE
0220 | C5 1B F3 1D 49 01 36 C9 FF D3 FA D4 D5 5D 14 46
0230 | F5 49 77 8D F6 4F 2E 72 A6 86 F6 D6 28 36 67 BB
0240 | 87 55 AA E4 D7 E0 3B B6 2B C3 2C 4B 39 28 CC 9A
0250 | E4 3B 45 10 65 AE 1F BB 67 85 F5 EE DC D1 1E 88
0260 | ED 8B 9A 9D CE 6C E2 11 AF EC BA 61 51 DC EE D8
0270 | CB BC 17 B2 48 B9 51 BD 68 08 9F 1C 0A C4 2E CC
0280 | 12 B0 1A AD 06 79 08 34 E6 60 AC 94
Payload (de)serialization:
server_DH_params_ok#d0e8075c 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 | 018C5E0477BB126A |
Message ID generated as specified here » (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 | B27A680E9C4669598AA90C13804D1A2B |
Value generated by client in Step 1 |
| server_nonce | 40, 16 | 2583746116A66C44FD1BCAA114333E7A |
Value received from server in Step 2 |
| encrypted_answer | 56, 596 | FE50020076C98CE79E69C7294193A887 A4B17D3571745CFA3C9659A294C7E442 D2CC356B00D554B37B48C6235A3CE409 AA35EE646C8DA29CE2DB8B914AD8C58F E9FFC6233C253923799897B4DBAF3643 39721BE98621FD74205D5907993FFE2B 8FC7DFFFF496DF559EAE3F38214AF183 99D4BA557A586767AEA399A32C5D540F 0001C3665CBE7011D648563A9CFA8C94 DE13F9D4B2951F4E6D29BE87AF88468F 9C9F480191B10A0F7E03101E6F1F579C E23D1DE2EF155FDB71C8EF00FA096B66 942050ACE9587F22EF475D839F0A435A CEC1E56E1263B060F2E0854CE3D78F46 DC6B11B504E222EFBC55C8645DB7901B E391639D4AD7D3D501C3F48C5AC3A5F5 B631F39ECDB7AB502CFD0FE2282997CF FE3F5D31AEE462B249F42918C182F9D1 AE6A264B6A8FF9A14639E0650425AEFF 8A6291B94ED415303D8970ECA5CCFD91 00B0E9E8983FA63A561B611CA37EE325 0597E6471C6336E32887FCF5AA631418 5FE8D3DA7EEF2C01C91EE35128BC3D70 D294F8C4B5B73418B73BA19CAE4A8A44 492C41BCA06A13D43EA494B08F35AEFF 244F893D9168E58DCA004D53D3415A8B 3101937B3211FCFF3A3873190F8B7C04 1BCD3685CDE9DAF22F293133DFA57ED4 9CADFC7CCA94CB06911DBAE5B6A11EC9 6D08B9C38841F363C187D1A63EEA588B 72B4BE35B39C7FBEC51BF31D490136C9 FFD3FAD4D55D1446F549778DF64F2E72 A686F6D6283667BB8755AAE4D7E03BB6 2BC32C4B3928CC9AE43B451065AE1FBB 6785F5EEDCD11E88ED8B9A9DCE6CE211 AFECBA6151DCEED8CBBC17B248B951BD 68089F1C0AC42ECC12B01AAD06790834E660AC94 |
See below |
Decrypt encrypted_answer using the reverse of the process specified in step 6:
encrypted_answer = 76C98CE79E69C7294193A887A4B17D3571745CFA3C9659A294C7E442D2CC356B00D554B37B48C6235A3CE409AA35EE646C8DA29CE2DB8B914AD8C58FE9FFC6233C253923799897B4DBAF364339721BE98621FD74205D5907993FFE2B8FC7DFFFF496DF559EAE3F38214AF18399D4BA557A586767AEA399A32C5D540F0001C3665CBE7011D648563A9CFA8C94DE13F9D4B2951F4E6D29BE87AF88468F9C9F480191B10A0F7E03101E6F1F579CE23D1DE2EF155FDB71C8EF00FA096B66942050ACE9587F22EF475D839F0A435ACEC1E56E1263B060F2E0854CE3D78F46DC6B11B504E222EFBC55C8645DB7901BE391639D4AD7D3D501C3F48C5AC3A5F5B631F39ECDB7AB502CFD0FE2282997CFFE3F5D31AEE462B249F42918C182F9D1AE6A264B6A8FF9A14639E0650425AEFF8A6291B94ED415303D8970ECA5CCFD9100B0E9E8983FA63A561B611CA37EE3250597E6471C6336E32887FCF5AA6314185FE8D3DA7EEF2C01C91EE35128BC3D70D294F8C4B5B73418B73BA19CAE4A8A44492C41BCA06A13D43EA494B08F35AEFF244F893D9168E58DCA004D53D3415A8B3101937B3211FCFF3A3873190F8B7C041BCD3685CDE9DAF22F293133DFA57ED49CADFC7CCA94CB06911DBAE5B6A11EC96D08B9C38841F363C187D1A63EEA588B72B4BE35B39C7FBEC51BF31D490136C9FFD3FAD4D55D1446F549778DF64F2E72A686F6D6283667BB8755AAE4D7E03BB62BC32C4B3928CC9AE43B451065AE1FBB6785F5EEDCD11E88ED8B9A9DCE6CE211AFECBA6151DCEED8CBBC17B248B951BD68089F1C0AC42ECC12B01AAD06790834E660AC94
tmp_aes_key = 54FF4494FB599566F7EC23B78B671FB3B8FE354BBE4A52F5F3DE16198F3E5195
tmp_aes_iv = 3197693B4CF8623471F4636EC49307A49EDD3A2C6D721031139259831D4472DD
Yielding:
answer_with_hash = BC3C985B0D743F327150F61BA0CE88677737A967BA0D89B5B27A680E9C4669598AA90C13804D1A2B2583746116A66C44FD1BCAA114333E7A03000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE0001001A096793C2FBA85829051C2D02AC349C6D1BA758D61155C3A4E334F1C2209CDB226CF08026911F1E43CA92A5201ABB5011AE43616760D68E1399AC89BC16FA39C0E0A155E9A0AAAB2C3A7CAB30B5805466A18CD7F06C1D040ECFBA8FAEDF46BB847C7EAD771F4945F0FF9F8A0E23485F1B23C19B6F6A17769F538A7CF40ADECE03365979429EE067210F6B6563A33F2C50EA3E7FE83E2F7FC09671BCB1210A5175E442745DA652A00B728BC58532E3B246DE96EBDFD74CC240CBA15132D8E9518688072E5193BEFB3C136A087175853F84A6465EBE335794ABEC87A58CCC7CCAFE331FBFFAB0C3CB936576713B4ACF6F90D38EE2DF360505276148DFA020375677BB126AA4105CA221D719A7
answer = BA0D89B5B27A680E9C4669598AA90C13804D1A2B2583746116A66C44FD1BCAA114333E7A03000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE0001001A096793C2FBA85829051C2D02AC349C6D1BA758D61155C3A4E334F1C2209CDB226CF08026911F1E43CA92A5201ABB5011AE43616760D68E1399AC89BC16FA39C0E0A155E9A0AAAB2C3A7CAB30B5805466A18CD7F06C1D040ECFBA8FAEDF46BB847C7EAD771F4945F0FF9F8A0E23485F1B23C19B6F6A17769F538A7CF40ADECE03365979429EE067210F6B6563A33F2C50EA3E7FE83E2F7FC09671BCB1210A5175E442745DA652A00B728BC58532E3B246DE96EBDFD74CC240CBA15132D8E9518688072E5193BEFB3C136A087175853F84A6465EBE335794ABEC87A58CCC7CCAFE331FBFFAB0C3CB936576713B4ACF6F90D38EE2DF360505276148DFA020375677BB126AA4105CA221D719A7
Generated payload (excluding transport headers/trailers):
0000 | BA 0D 89 B5 B2 7A 68 0E 9C 46 69 59 8A A9 0C 13
0010 | 80 4D 1A 2B 25 83 74 61 16 A6 6C 44 FD 1B CA A1
0020 | 14 33 3E 7A 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 | 1A 09 67 93 C2 FB A8 58 29 05 1C 2D 02 AC 34 9C
0140 | 6D 1B A7 58 D6 11 55 C3 A4 E3 34 F1 C2 20 9C DB
0150 | 22 6C F0 80 26 91 1F 1E 43 CA 92 A5 20 1A BB 50
0160 | 11 AE 43 61 67 60 D6 8E 13 99 AC 89 BC 16 FA 39
0170 | C0 E0 A1 55 E9 A0 AA AB 2C 3A 7C AB 30 B5 80 54
0180 | 66 A1 8C D7 F0 6C 1D 04 0E CF BA 8F AE DF 46 BB
0190 | 84 7C 7E AD 77 1F 49 45 F0 FF 9F 8A 0E 23 48 5F
01A0 | 1B 23 C1 9B 6F 6A 17 76 9F 53 8A 7C F4 0A DE CE
01B0 | 03 36 59 79 42 9E E0 67 21 0F 6B 65 63 A3 3F 2C
01C0 | 50 EA 3E 7F E8 3E 2F 7F C0 96 71 BC B1 21 0A 51
01D0 | 75 E4 42 74 5D A6 52 A0 0B 72 8B C5 85 32 E3 B2
01E0 | 46 DE 96 EB DF D7 4C C2 40 CB A1 51 32 D8 E9 51
01F0 | 86 88 07 2E 51 93 BE FB 3C 13 6A 08 71 75 85 3F
0200 | 84 A6 46 5E BE 33 57 94 AB EC 87 A5 8C CC 7C CA
0210 | FE 33 1F BF FA B0 C3 CB 93 65 76 71 3B 4A CF 6F
0220 | 90 D3 8E E2 DF 36 05 05 27 61 48 DF A0 20 37 56
0230 | 77 BB 12 6A
Payload (de)serialization:
server_DH_inner_data#b5890dba 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 | B27A680E9C4669598AA90C13804D1A2B |
Value generated by client in Step 1 |
| server_nonce | 20, 16 | 2583746116A66C44FD1BCAA114333E7A |
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 4B2454BF6F4FADF034B10403119CD8E3B92FCC5B |
2048-bit prime, in big-endian byte order, to be checked as specified in the auth key docs |
| g_a | 300, 260 | FE0001001A096793C2FBA85829051C2D 02AC349C6D1BA758D61155C3A4E334F1 C2209CDB226CF08026911F1E43CA92A5 201ABB5011AE43616760D68E1399AC89 BC16FA39C0E0A155E9A0AAAB2C3A7CAB 30B5805466A18CD7F06C1D040ECFBA8F AEDF46BB847C7EAD771F4945F0FF9F8A 0E23485F1B23C19B6F6A17769F538A7C F40ADECE03365979429EE067210F6B65 63A33F2C50EA3E7FE83E2F7FC09671BC B1210A5175E442745DA652A00B728BC5 8532E3B246DE96EBDFD74CC240CBA151 32D8E9518688072E5193BEFB3C136A08 7175853F84A6465EBE335794ABEC87A5 8CCC7CCAFE331FBFFAB0C3CB93657671 3B4ACF6F90D38EE2DF360505276148DFA0203756 |
g_a diffie-hellman parameter |
| server_time | 560, 4 | 77BB126A (1779612535 in decimal) |
Server time |
First, generate a secure random 2048-bit number b:
b = 21497783ED68554141E9F6DF5EA8E837C215639C0A0575B9FBC89F8AFD0BC208107A009795CFF13F2351703FBE06E06048B737983CE529ACBE03B7E3B55FC1EB4B23244B6DA32A1FCA845D81C42019FFF73D0D8831FE86DB0B903B1B9CB11CA8DFA64F3E2E33D95B0EB10E18C6E312EF563D5925822B0420915C3630B08C00199DCFD9273079E98F1C065CC78806F0252F416A56C3F415CD389B73278E880B7A3C4B6A5E9EE7DB59E9302AC6379A994BA82DDE97D5746FF40223E945B0089BD94B53713D80D9E072C6C24924AA9221FA43FBC1EEE0363A72A0227420E8AAC740DE11763A6E11EF77344AD3A15513F25FD04CAF4D8B2D36D9EDC14E246B7C23D3
Then compute g_b = pow(g, b) mod dh_prime
g_b = 249A734E5E77C066859805DF4808C472F8F383EA4624C11481537C3230A91C6FF7BB7CB48B70B6F875B6326CA7BB38380B95CD80A7D7657F39C66FFB030C87ECDD61B5833DE8BFB143C1FE94BE30A21B5132486DACB5EB6FE7E1B76499C8888F2D7E7CD5948ADF6F9FFF21E949525262C3BEBD00BD3317FB1175E638E88B7ED404D3BA56F8FA68612310E328EDC732B090B66E90785594E3017564602BA13257CB88451076AEB8603CB4866C968C7AE918F39D1E4F1D5AF0DBF7B9A45F40391E162EFD1E88F70CAFD7495D4BFA46227467A4EB0E805085EE7C1D517691D0D5F4501FF4E79C0CF0CFEE3C7BB278A2B24067CBD735D7077F195FEE42BE7C2C274C
Generated payload (excluding transport headers/trailers):
0000 | 54 B6 43 66 B2 7A 68 0E 9C 46 69 59 8A A9 0C 13
0010 | 80 4D 1A 2B 25 83 74 61 16 A6 6C 44 FD 1B CA A1
0020 | 14 33 3E 7A 00 00 00 00 00 00 00 00 FE 00 01 00
0030 | 24 9A 73 4E 5E 77 C0 66 85 98 05 DF 48 08 C4 72
0040 | F8 F3 83 EA 46 24 C1 14 81 53 7C 32 30 A9 1C 6F
0050 | F7 BB 7C B4 8B 70 B6 F8 75 B6 32 6C A7 BB 38 38
0060 | 0B 95 CD 80 A7 D7 65 7F 39 C6 6F FB 03 0C 87 EC
0070 | DD 61 B5 83 3D E8 BF B1 43 C1 FE 94 BE 30 A2 1B
0080 | 51 32 48 6D AC B5 EB 6F E7 E1 B7 64 99 C8 88 8F
0090 | 2D 7E 7C D5 94 8A DF 6F 9F FF 21 E9 49 52 52 62
00A0 | C3 BE BD 00 BD 33 17 FB 11 75 E6 38 E8 8B 7E D4
00B0 | 04 D3 BA 56 F8 FA 68 61 23 10 E3 28 ED C7 32 B0
00C0 | 90 B6 6E 90 78 55 94 E3 01 75 64 60 2B A1 32 57
00D0 | CB 88 45 10 76 AE B8 60 3C B4 86 6C 96 8C 7A E9
00E0 | 18 F3 9D 1E 4F 1D 5A F0 DB F7 B9 A4 5F 40 39 1E
00F0 | 16 2E FD 1E 88 F7 0C AF D7 49 5D 4B FA 46 22 74
0100 | 67 A4 EB 0E 80 50 85 EE 7C 1D 51 76 91 D0 D5 F4
0110 | 50 1F F4 E7 9C 0C F0 CF EE 3C 7B B2 78 A2 B2 40
0120 | 67 CB D7 35 D7 07 7F 19 5F EE 42 BE 7C 2C 27 4C
Payload (de)serialization:
client_DH_inner_data#6643b654 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 | B27A680E9C4669598AA90C13804D1A2B |
Value generated by client in Step 1 |
| server_nonce | 20, 16 | 2583746116A66C44FD1BCAA114333E7A |
Value received from server in Step 2 |
| g_b | 36, 260 | FE000100249A734E5E77C066859805DF 4808C472F8F383EA4624C11481537C32 30A91C6FF7BB7CB48B70B6F875B6326C A7BB38380B95CD80A7D7657F39C66FFB 030C87ECDD61B5833DE8BFB143C1FE94 BE30A21B5132486DACB5EB6FE7E1B764 99C8888F2D7E7CD5948ADF6F9FFF21E9 49525262C3BEBD00BD3317FB1175E638 E88B7ED404D3BA56F8FA68612310E328 EDC732B090B66E90785594E301756460 2BA13257CB88451076AEB8603CB4866C 968C7AE918F39D1E4F1D5AF0DBF7B9A4 5F40391E162EFD1E88F70CAFD7495D4B FA46227467A4EB0E805085EE7C1D5176 91D0D5F4501FF4E79C0CF0CFEE3C7BB2 78A2B24067CBD735D7077F195FEE42BE7C2C274C |
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). |
The serialization of Client_DH_Inner_Data produces a string data. This is used to generate encrypted_data as specified in step 6, using the following inputs:
data = 54B64366B27A680E9C4669598AA90C13804D1A2B2583746116A66C44FD1BCAA114333E7A0000000000000000FE000100249A734E5E77C066859805DF4808C472F8F383EA4624C11481537C3230A91C6FF7BB7CB48B70B6F875B6326CA7BB38380B95CD80A7D7657F39C66FFB030C87ECDD61B5833DE8BFB143C1FE94BE30A21B5132486DACB5EB6FE7E1B76499C8888F2D7E7CD5948ADF6F9FFF21E949525262C3BEBD00BD3317FB1175E638E88B7ED404D3BA56F8FA68612310E328EDC732B090B66E90785594E3017564602BA13257CB88451076AEB8603CB4866C968C7AE918F39D1E4F1D5AF0DBF7B9A45F40391E162EFD1E88F70CAFD7495D4BFA46227467A4EB0E805085EE7C1D517691D0D5F4501FF4E79C0CF0CFEE3C7BB278A2B24067CBD735D7077F195FEE42BE7C2C274C
padding = 6C4272DF4F39CCC81E43D5E4
tmp_aes_key = 54FF4494FB599566F7EC23B78B671FB3B8FE354BBE4A52F5F3DE16198F3E5195
tmp_aes_iv = 3197693B4CF8623471F4636EC49307A49EDD3A2C6D721031139259831D4472DD
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:
encrypted_data = 4B7E5D426D47AB78BCEDC3455B87BF50C81283066B6046E111443B46E3D6A4D7A2D0A48EB4C2E2F2EABDC93E492AB1930944F325D4C14A95EEC0F0442FD865F1C101A01CE86FF2C099628D18D37A12CDD57E806FF2EE170A02CF139DCCC572BA3AA6CD5600376669C98B915B813FE3B1D45DB3ACFEF7DFF36CBE41124CFF3326C6E951D454F1D089B4972B780FBED1E1FA7BC95AF7DB1F2EC25C35CAA7910ACA2C25594B3EEAA7F60064DF771275CFD493737F78A2659A41EA058AE8401F5D13FD2491C9E8333494CA77A53F9579E5A44EC51E196B495F895F4E93CA7BD5801DA79694513DC7E20B07D5DF682DF45740F76A1F5E7676643AB03FADC4487793FCC0B784C6E28ABFE3A06626884D0A40C19274A3912005F34408FBD1A13AAA1B7BB97197955FF5C0B490AA8A08C1C5616E624D6EE7BAE07261645E918A6A112827C9879DC093AC7FBC139AE741C7F1180E
The length of the final string is 336 bytes.
Sent payload (excluding transport headers/trailers):
0000 | 00 00 00 00 00 00 00 00 4C 2B 00 00 77 BB 12 6A
0010 | 78 01 00 00 1F 5F 04 F5 B2 7A 68 0E 9C 46 69 59
0020 | 8A A9 0C 13 80 4D 1A 2B 25 83 74 61 16 A6 6C 44
0030 | FD 1B CA A1 14 33 3E 7A FE 50 01 00 4B 7E 5D 42
0040 | 6D 47 AB 78 BC ED C3 45 5B 87 BF 50 C8 12 83 06
0050 | 6B 60 46 E1 11 44 3B 46 E3 D6 A4 D7 A2 D0 A4 8E
0060 | B4 C2 E2 F2 EA BD C9 3E 49 2A B1 93 09 44 F3 25
0070 | D4 C1 4A 95 EE C0 F0 44 2F D8 65 F1 C1 01 A0 1C
0080 | E8 6F F2 C0 99 62 8D 18 D3 7A 12 CD D5 7E 80 6F
0090 | F2 EE 17 0A 02 CF 13 9D CC C5 72 BA 3A A6 CD 56
00A0 | 00 37 66 69 C9 8B 91 5B 81 3F E3 B1 D4 5D B3 AC
00B0 | FE F7 DF F3 6C BE 41 12 4C FF 33 26 C6 E9 51 D4
00C0 | 54 F1 D0 89 B4 97 2B 78 0F BE D1 E1 FA 7B C9 5A
00D0 | F7 DB 1F 2E C2 5C 35 CA A7 91 0A CA 2C 25 59 4B
00E0 | 3E EA A7 F6 00 64 DF 77 12 75 CF D4 93 73 7F 78
00F0 | A2 65 9A 41 EA 05 8A E8 40 1F 5D 13 FD 24 91 C9
0100 | E8 33 34 94 CA 77 A5 3F 95 79 E5 A4 4E C5 1E 19
0110 | 6B 49 5F 89 5F 4E 93 CA 7B D5 80 1D A7 96 94 51
0120 | 3D C7 E2 0B 07 D5 DF 68 2D F4 57 40 F7 6A 1F 5E
0130 | 76 76 64 3A B0 3F AD C4 48 77 93 FC C0 B7 84 C6
0140 | E2 8A BF E3 A0 66 26 88 4D 0A 40 C1 92 74 A3 91
0150 | 20 05 F3 44 08 FB D1 A1 3A AA 1B 7B B9 71 97 95
0160 | 5F F5 C0 B4 90 AA 8A 08 C1 C5 61 6E 62 4D 6E E7
0170 | BA E0 72 61 64 5E 91 8A 6A 11 28 27 C9 87 9D C0
0180 | 93 AC 7F BC 13 9A E7 41 C7 F1 18 0E
Payload (de)serialization:
set_client_DH_params#f5045f1f 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 | 4C2B000077BB126A |
Message ID generated as specified here » (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 | B27A680E9C4669598AA90C13804D1A2B |
Value generated by client in Step 1 |
| server_nonce | 40, 16 | 2583746116A66C44FD1BCAA114333E7A |
Value received from server in Step 2 |
| encrypted_data | 56, 340 | FE5001004B7E5D426D47AB78BCEDC345 5B87BF50C81283066B6046E111443B46 E3D6A4D7A2D0A48EB4C2E2F2EABDC93E 492AB1930944F325D4C14A95EEC0F044 2FD865F1C101A01CE86FF2C099628D18 D37A12CDD57E806FF2EE170A02CF139D CCC572BA3AA6CD5600376669C98B915B 813FE3B1D45DB3ACFEF7DFF36CBE4112 4CFF3326C6E951D454F1D089B4972B78 0FBED1E1FA7BC95AF7DB1F2EC25C35CA A7910ACA2C25594B3EEAA7F60064DF77 1275CFD493737F78A2659A41EA058AE8 401F5D13FD2491C9E8333494CA77A53F 9579E5A44EC51E196B495F895F4E93CA 7BD5801DA79694513DC7E20B07D5DF68 2DF45740F76A1F5E7676643AB03FADC4 487793FCC0B784C6E28ABFE3A0662688 4D0A40C19274A3912005F34408FBD1A1 3AAA1B7BB97197955FF5C0B490AA8A08 C1C5616E624D6EE7BAE07261645E918A 6A112827C9879DC093AC7FBC139AE741C7F1180E |
Encrypted client_DH_inner_data generated previously, serialized as a TL byte string |
The client computes the auth_key using formula g_a^b mod dh_prime:
auth_key = 67AF5C88EC31572E95A648C21DCA1782816550ACFFE774D8D11CC5F30E16A5C6C240B3C57CBC059B3AA8C18073D78D4FC72318C1A6EEDBF34558E95AC31D85C25290AF43AA43CA6739B32C839B0C69FE14B06E80DE0ECAEF4AF3192E874BDDAB62C1AE19A71DBF5F610C62AFEF23AF88157047C352E662023AB95AC3F0047B3B67B1B1300095EBAC02D179A16B98F8D45571BD4C70FB2E91615E9385111463F3975D85C5DBC890C3D191C77969BAC3876FB7918592AF55483128BA1163458F3EE3B77D8BA1300704791818A26B39EA8A87F49510E3BF8B010F336B004B427B1F14C3CB6678C34F0DCEC707033D0896F329B785DFCD49852E1E1C47F01B72D096
The server verifies and confirms that auth_key_hash is unique: since it's unique, it replies with the following:
Received payload (excluding transport headers/trailers):
0000 | 00 00 00 00 00 00 00 00 01 88 B2 12 78 BB 12 6A
0010 | 34 00 00 00 34 F7 CB 3B B2 7A 68 0E 9C 46 69 59
0020 | 8A A9 0C 13 80 4D 1A 2B 25 83 74 61 16 A6 6C 44
0030 | FD 1B CA A1 14 33 3E 7A CC 75 64 DD 1E 84 0C C4
0040 | 5F 92 5B 0E 8B 12 05 2C
Payload (de)serialization:
dh_gen_ok#3bcbf734 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 | 0188B21278BB126A |
Message ID generated as specified here » (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 | B27A680E9C4669598AA90C13804D1A2B |
Value generated by client in Step 1 |
| server_nonce | 40, 16 | 2583746116A66C44FD1BCAA114333E7A |
Value received from server in Step 2 |
| new_nonce_hash1 | 56, 16 | CC7564DD1E840CC45F925B0E8B12052C |
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. |