Auth key generation example

In the examples below, the transport headers are omitted:

For example, for the abridged version of the transport », 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 0xefas the first byte).

Detailed documentation on creating authorization keys is available here ».

DH exchange initiation

1) Client sends query to server

Sent payload (excluding transport headers/trailers):

0000 | 00 00 00 00 00 00 00 00 1C 4C 0B 00 6E 6B 9C 68
0010 | 14 00 00 00 F1 8E 7E BE 2C 77 8C E5 A8 6C 26 E5
0020 | 9A 2F 7A A9 50 2E CF E8

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 1C4C0B006E6B9C68 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 2C778CE5A86C26E59A2F7AA9502ECFE8 Random number
2) Server sends response of the form

Received payload (excluding transport headers/trailers):

0000 | 00 00 00 00 00 00 00 00 01 18 F9 A7 6E 6B 9C 68
0010 | 50 00 00 00 63 24 16 05 2C 77 8C E5 A8 6C 26 E5
0020 | 9A 2F 7A A9 50 2E CF E8 EE 59 A6 10 44 FB 02 B6
0030 | CB D9 B9 12 4D 4C 30 24 08 1F 15 75 FC 6F E4 AB
0040 | 97 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 0118F9A76E6B9C68 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 2C778CE5A86C26E59A2F7AA9502ECFE8 Value generated by client in Step 1
server_nonce 40, 16 EE59A61044FB02B6CBD9B9124D4C3024 Server-generated random number
pq 56, 12 081F1575FC6FE4AB97000000
TL byte deserialization
=> bigendian conversion to decimal
=> 2239826116756155287
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:

  • 85FD64DE851D9DD0

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

Proof of work

3) Client decomposes pq into prime factors such that p < q.
pq = 2239826116756155287

Decompose into 2 prime cofactors p < q: 2239826116756155287 = 1475695031 * 1517810977

p = 1475695031
q = 1517810977

Presenting proof of work; Server authentication

4) encrypted_data payload generation

First of all, generate an encrypted_data payload as follows:

Generated payload (excluding transport headers/trailers):

0000 | 95 5F F5 A9 08 1F 15 75 FC 6F E4 AB 97 00 00 00
0010 | 04 57 F5 51 B7 00 00 00 04 5A 77 F5 21 00 00 00
0020 | 2C 77 8C E5 A8 6C 26 E5 9A 2F 7A A9 50 2E CF E8
0030 | EE 59 A6 10 44 FB 02 B6 CB D9 B9 12 4D 4C 30 24
0040 | B5 31 A0 8D DC E8 C1 6C 86 05 E4 D3 BE A2 1E CA
0050 | 00 FD EF AA B4 6D 3D 55 74 B0 E4 AA 02 AF A2 72
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 081F1575FC6FE4AB97000000
TL byte deserialization
=> bigendian conversion to decimal
=> 2239826116756155287
Single-byte prefix denoting length, 8-byte string, and three bytes of padding
p 16, 8 0457F551B7000000
TL byte deserialization
=> bigendian conversion to decimal
=> 1475695031
First prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding
q 24, 8 045A77F521000000
TL byte deserialization
=> bigendian conversion to decimal
=> 1517810977
Second prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding
nonce 32, 16 2C778CE5A86C26E59A2F7AA9502ECFE8 Value generated by client in Step 1
server_nonce 48, 16 EE59A61044FB02B6CBD9B9124D4C3024 Value received from server in Step 2
new_nonce 64, 32 B531A08DDCE8C16C8605E4D3BEA21ECA 00FDEFAAB46D3D5574B0E4AA02AFA272 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 = 955FF5A9081F1575FC6FE4AB970000000457F551B7000000045A77F5210000002C778CE5A86C26E59A2F7AA9502ECFE8EE59A61044FB02B6CBD9B9124D4C3024B531A08DDCE8C16C8605E4D3BEA21ECA00FDEFAAB46D3D5574B0E4AA02AFA27202000000
random_padding_bytes = 7FC20CFEAFC42FEFBE9A828D90208C73B5E9C75DB2FC9D56E852825A6B56900F855E5061300E841201FC51BDAEE642F846EA6E895391AC1C34910B929DE070311D06369D022BBDD68D8BE60DDFF92E7F2773DA8A6824C849EA69E010

And this is the output:

encrypted_data = A4A30CFDEFE5E40AC528D4FF51FAEBF82C1B01F400D2F085193B4D8727AB8EAD6E3878E06BEF89254A89C3E690673282EB11EC8747083E2694FA249AA8C1467779AF7EB8824925309E1246668F3D85F70A5355BDDABC5FD601B9C745E1E789C6AA92B0049139E2AE75D266B501EDA2D267BE604C26F9836A56B1E5F78D8C3B04A2CC4C1918AD07DCA5B8152D1D8AF7459E78B27A51810D388EE2E67A16C2C0526A0B0A1F5E34246876CE9246753A75F90D8D17E081B7059A7FA92AB2D5FA82A4C202C30BC2FE4F34D1D32CF2FA5794C39926EE9DC1E91EB06854E7D8B77ACA85188868F079E32A9221AA397DE933AB0116D753C86AAE079DFEF613C431CEAB2F

The length of the final string is 256 bytes.

5) Send req_DH_params query with generated encrypted_data

Sent payload (excluding transport headers/trailers):

0000 | 00 00 00 00 00 00 00 00 20 4C 0B 00 6E 6B 9C 68
0010 | 40 01 00 00 BE E4 12 D7 2C 77 8C E5 A8 6C 26 E5
0020 | 9A 2F 7A A9 50 2E CF E8 EE 59 A6 10 44 FB 02 B6
0030 | CB D9 B9 12 4D 4C 30 24 04 57 F5 51 B7 00 00 00
0040 | 04 5A 77 F5 21 00 00 00 85 FD 64 DE 85 1D 9D D0
0050 | FE 00 01 00 A4 A3 0C FD EF E5 E4 0A C5 28 D4 FF
0060 | 51 FA EB F8 2C 1B 01 F4 00 D2 F0 85 19 3B 4D 87
0070 | 27 AB 8E AD 6E 38 78 E0 6B EF 89 25 4A 89 C3 E6
0080 | 90 67 32 82 EB 11 EC 87 47 08 3E 26 94 FA 24 9A
0090 | A8 C1 46 77 79 AF 7E B8 82 49 25 30 9E 12 46 66
00A0 | 8F 3D 85 F7 0A 53 55 BD DA BC 5F D6 01 B9 C7 45
00B0 | E1 E7 89 C6 AA 92 B0 04 91 39 E2 AE 75 D2 66 B5
00C0 | 01 ED A2 D2 67 BE 60 4C 26 F9 83 6A 56 B1 E5 F7
00D0 | 8D 8C 3B 04 A2 CC 4C 19 18 AD 07 DC A5 B8 15 2D
00E0 | 1D 8A F7 45 9E 78 B2 7A 51 81 0D 38 8E E2 E6 7A
00F0 | 16 C2 C0 52 6A 0B 0A 1F 5E 34 24 68 76 CE 92 46
0100 | 75 3A 75 F9 0D 8D 17 E0 81 B7 05 9A 7F A9 2A B2
0110 | D5 FA 82 A4 C2 02 C3 0B C2 FE 4F 34 D1 D3 2C F2
0120 | FA 57 94 C3 99 26 EE 9D C1 E9 1E B0 68 54 E7 D8
0130 | B7 7A CA 85 18 88 68 F0 79 E3 2A 92 21 AA 39 7D
0140 | E9 33 AB 01 16 D7 53 C8 6A AE 07 9D FE F6 13 C4
0150 | 31 CE AB 2F

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 204C0B006E6B9C68 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 2C778CE5A86C26E59A2F7AA9502ECFE8 Value generated by client in Step 1
server_nonce 40, 16 EE59A61044FB02B6CBD9B9124D4C3024 Value received from server in Step 2
p 56, 8 0457F551B7000000
TL byte deserialization
=> bigendian conversion to decimal
=> 1475695031
First prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding
q 64, 8 045A77F521000000
TL byte deserialization
=> bigendian conversion to decimal
=> 1517810977
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 FE000100A4A30CFDEFE5E40AC528D4FF 51FAEBF82C1B01F400D2F085193B4D87 27AB8EAD6E3878E06BEF89254A89C3E6 90673282EB11EC8747083E2694FA249A A8C1467779AF7EB8824925309E124666 8F3D85F70A5355BDDABC5FD601B9C745 E1E789C6AA92B0049139E2AE75D266B5 01EDA2D267BE604C26F9836A56B1E5F7 8D8C3B04A2CC4C1918AD07DCA5B8152D 1D8AF7459E78B27A51810D388EE2E67A 16C2C0526A0B0A1F5E34246876CE9246 753A75F90D8D17E081B7059A7FA92AB2 D5FA82A4C202C30BC2FE4F34D1D32CF2 FA5794C39926EE9DC1E91EB06854E7D8 B77ACA85188868F079E32A9221AA397D E933AB0116D753C86AAE079DFEF613C4
31CEAB2F
Value generated above
6) Server responds with:

Received payload (excluding transport headers/trailers):

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

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 011412CA6E6B9C68 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 2C778CE5A86C26E59A2F7AA9502ECFE8 Value generated by client in Step 1
server_nonce 40, 16 EE59A61044FB02B6CBD9B9124D4C3024 Value received from server in Step 2
encrypted_answer 56, 596 FE500200D0423D98F3E1A7A39254489D 81DD397E832E09F4F57870F6303A8E61 C67AF9D5465779B8EE55E2C80F3598F1 06FCAF1FF0D5C7FF727C86D2C5DE8731 2D9CD73E39E242CE7D4002C4B8205B7F C8D471D9970D23502E570F46FE0C3A77 D098CDFFCD2DE985B203C12F869353FB 0A3FC14C777377915C6753E0A8C223CD 6E9A25421FBCB92D8CD2E593BDD5ABEC 241E020F117264B2EC0BD034652FE087 AD127D8AFFFEE2602F211EAFD75D50DF 82A72BFDA105812A3D132B598FED6EC6 3C5029049F91521FC8E294FE41FC2756 AA0206A9A6C36AD70480A3799208E635 908B786A338429D452A99E8D7DEC3ADA 047264A28879A7465F3181C8D38BBD48 AFB44F873ADD5A3D12AF8AC1159EB873 6CED5470A0163123C1210D7A4BDEB714 1DDC4C7717F0400EBCBA304B0B37F085 B55FD8A51B57563215859A1733B74516 CDF82EB545CC8EEEA23C24B692F10051 134B769291EA264934AC6EE88A4AE420 2533BE0261708A27B8EFC051AC96FDF5 162577BFAC3F5A8A878EBD6AD4F71FBD 7218590E95D77CE96D45753B72C310C8 18310D91117994F3F8803BD12B0C04A1 CF17CC1E8FA770D9E5D674FE5AA826E7 8E0AD44D04CFAB59831EF15EDD296367 C3AE09C5D6F23CBDF9DF98AA36B459C4 F6CA50EA42C1634DEA104FF0D4DD0356 5768A7D294ECBF25487C379E47027CC6 B170059F9924A74EEDA3DC93C3C01B84 5FA9F87FD8952FDD5D7E2FAB5D91BD6C AA430A3CA5755723D31C4CBCF2394EA6 C7D4F1B1F1045747AABD902287D3E13A 38AEC93E7ED289AC844C27C485FAD839 05AA83E3458334C6840C94E57C686F3B
2B080744
See below

Decrypt encrypted_answer using the reverse of the process specified in step 6:

encrypted_answer = D0423D98F3E1A7A39254489D81DD397E832E09F4F57870F6303A8E61C67AF9D5465779B8EE55E2C80F3598F106FCAF1FF0D5C7FF727C86D2C5DE87312D9CD73E39E242CE7D4002C4B8205B7FC8D471D9970D23502E570F46FE0C3A77D098CDFFCD2DE985B203C12F869353FB0A3FC14C777377915C6753E0A8C223CD6E9A25421FBCB92D8CD2E593BDD5ABEC241E020F117264B2EC0BD034652FE087AD127D8AFFFEE2602F211EAFD75D50DF82A72BFDA105812A3D132B598FED6EC63C5029049F91521FC8E294FE41FC2756AA0206A9A6C36AD70480A3799208E635908B786A338429D452A99E8D7DEC3ADA047264A28879A7465F3181C8D38BBD48AFB44F873ADD5A3D12AF8AC1159EB8736CED5470A0163123C1210D7A4BDEB7141DDC4C7717F0400EBCBA304B0B37F085B55FD8A51B57563215859A1733B74516CDF82EB545CC8EEEA23C24B692F10051134B769291EA264934AC6EE88A4AE4202533BE0261708A27B8EFC051AC96FDF5162577BFAC3F5A8A878EBD6AD4F71FBD7218590E95D77CE96D45753B72C310C818310D91117994F3F8803BD12B0C04A1CF17CC1E8FA770D9E5D674FE5AA826E78E0AD44D04CFAB59831EF15EDD296367C3AE09C5D6F23CBDF9DF98AA36B459C4F6CA50EA42C1634DEA104FF0D4DD03565768A7D294ECBF25487C379E47027CC6B170059F9924A74EEDA3DC93C3C01B845FA9F87FD8952FDD5D7E2FAB5D91BD6CAA430A3CA5755723D31C4CBCF2394EA6C7D4F1B1F1045747AABD902287D3E13A38AEC93E7ED289AC844C27C485FAD83905AA83E3458334C6840C94E57C686F3B2B080744
tmp_aes_key = DDBF239F7830AA4F3F114D03F51064C3BA57F670F3D1AE3AD3EE3BF7FC5DD6F0
tmp_aes_iv = 94227170B201320D851385CA9EAAA0488BFD8AC8992638835C3A9C85B531A08D

Yielding:

answer_with_hash = E49D78DA78A8BF2F2750C248C779DD059BB3EAA7BA0D89B52C778CE5A86C26E59A2F7AA9502ECFE8EE59A61044FB02B6CBD9B9124D4C302403000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE0001004A601FFE50301E8BF2ED9FF527EBB586291B898D62F934EDB069F443386DCABACEB38717FD42229D61C8A7F474EAA1F4A92B3CE8852DF79B64FDA1E0F392496E71F6964B48F95FE7FC9E0B565C9A8624E89FC0BF86C3B11231C0D8CEACA260AF988C03A36847EEFB75F47DEB1DA734555FDD6034E120248433EE14B308B7FC1ADC923C412FD993FC23B44ED45F1566CCE25A23C40F2CDA4A6BE86F563A5BFDC3378CFB6DFF32C978DF6EAC9832596F77AC668029AC19F11D877D959B69494DB93B578B9DF86A26EC53CB09D4FA4406261C4B62B8387AD0F160D13D19DBFB9D4ECC87F23AB07C00279CA9841E9B8C3DB7ABB06AA3C0823024223D690979576CD46E6B9C685DF8C39907CDE61D
answer = BA0D89B52C778CE5A86C26E59A2F7AA9502ECFE8EE59A61044FB02B6CBD9B9124D4C302403000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE0001004A601FFE50301E8BF2ED9FF527EBB586291B898D62F934EDB069F443386DCABACEB38717FD42229D61C8A7F474EAA1F4A92B3CE8852DF79B64FDA1E0F392496E71F6964B48F95FE7FC9E0B565C9A8624E89FC0BF86C3B11231C0D8CEACA260AF988C03A36847EEFB75F47DEB1DA734555FDD6034E120248433EE14B308B7FC1ADC923C412FD993FC23B44ED45F1566CCE25A23C40F2CDA4A6BE86F563A5BFDC3378CFB6DFF32C978DF6EAC9832596F77AC668029AC19F11D877D959B69494DB93B578B9DF86A26EC53CB09D4FA4406261C4B62B8387AD0F160D13D19DBFB9D4ECC87F23AB07C00279CA9841E9B8C3DB7ABB06AA3C0823024223D690979576CD46E6B9C685DF8C39907CDE61D

Generated payload (excluding transport headers/trailers):

0000 | BA 0D 89 B5 2C 77 8C E5 A8 6C 26 E5 9A 2F 7A A9
0010 | 50 2E CF E8 EE 59 A6 10 44 FB 02 B6 CB D9 B9 12
0020 | 4D 4C 30 24 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 | 4A 60 1F FE 50 30 1E 8B F2 ED 9F F5 27 EB B5 86
0140 | 29 1B 89 8D 62 F9 34 ED B0 69 F4 43 38 6D CA BA
0150 | CE B3 87 17 FD 42 22 9D 61 C8 A7 F4 74 EA A1 F4
0160 | A9 2B 3C E8 85 2D F7 9B 64 FD A1 E0 F3 92 49 6E
0170 | 71 F6 96 4B 48 F9 5F E7 FC 9E 0B 56 5C 9A 86 24
0180 | E8 9F C0 BF 86 C3 B1 12 31 C0 D8 CE AC A2 60 AF
0190 | 98 8C 03 A3 68 47 EE FB 75 F4 7D EB 1D A7 34 55
01A0 | 5F DD 60 34 E1 20 24 84 33 EE 14 B3 08 B7 FC 1A
01B0 | DC 92 3C 41 2F D9 93 FC 23 B4 4E D4 5F 15 66 CC
01C0 | E2 5A 23 C4 0F 2C DA 4A 6B E8 6F 56 3A 5B FD C3
01D0 | 37 8C FB 6D FF 32 C9 78 DF 6E AC 98 32 59 6F 77
01E0 | AC 66 80 29 AC 19 F1 1D 87 7D 95 9B 69 49 4D B9
01F0 | 3B 57 8B 9D F8 6A 26 EC 53 CB 09 D4 FA 44 06 26
0200 | 1C 4B 62 B8 38 7A D0 F1 60 D1 3D 19 DB FB 9D 4E
0210 | CC 87 F2 3A B0 7C 00 27 9C A9 84 1E 9B 8C 3D B7
0220 | AB B0 6A A3 C0 82 30 24 22 3D 69 09 79 57 6C D4
0230 | 6E 6B 9C 68

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 2C778CE5A86C26E59A2F7AA9502ECFE8 Value generated by client in Step 1
server_nonce 20, 16 EE59A61044FB02B6CBD9B9124D4C3024 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 FE0001004A601FFE50301E8BF2ED9FF5 27EBB586291B898D62F934EDB069F443 386DCABACEB38717FD42229D61C8A7F4 74EAA1F4A92B3CE8852DF79B64FDA1E0 F392496E71F6964B48F95FE7FC9E0B56 5C9A8624E89FC0BF86C3B11231C0D8CE ACA260AF988C03A36847EEFB75F47DEB 1DA734555FDD6034E120248433EE14B3 08B7FC1ADC923C412FD993FC23B44ED4 5F1566CCE25A23C40F2CDA4A6BE86F56 3A5BFDC3378CFB6DFF32C978DF6EAC98 32596F77AC668029AC19F11D877D959B 69494DB93B578B9DF86A26EC53CB09D4 FA4406261C4B62B8387AD0F160D13D19 DBFB9D4ECC87F23AB07C00279CA9841E 9B8C3DB7ABB06AA3C0823024223D6909
79576CD4
g_a diffie-hellman parameter
server_time 560, 4 6E6B9C68 (1755081582 in decimal) Server time
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:

b = E0B9603B22B1CC571E54194B5F27EF918560DF5E2F346E88FF4CA25265B1DC4BB9DDC985DB5CF6AC2B8697333C4E467B4DA2F5FC6DAFDF5368CFD6F908696ACB2F6D05315CB4784B2E51BF3BA2C9F006C2627C64C542150396F17F71D887A62903863715D1EA1C93FC1D7A274995D187250D022BEE42FB82395BD91DA212E9624BB6962D5B731C8C7255E1722E8F26B30FE2ADA5CB0A9980B9BC22D049EC31955AB4C4563ADBED6F2636C34870AB21FD35875F46031DE06A7B8378D35EAB7500BB649B44E0B1E46E98E6FC2991B9366AA264DC47A91EA8598BC3E77A21507A9613E929E46856CF1EA502895E413214D86F9111D39AD3913B61CD7E7FDEEE8234

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

g_b = 57500CDF13B22D653288118232DA6A1D8A05F1904FF6EF99E8DE8F2F9EA343C0026E09C6E296741AE849053AE135F4A3831CC5BEBEE2DF52A95405B50F203641AC1C90411079DA49674EE7FDCF62EAE61C4A181AC13AEDCEFCD809D78F5259FA8D5F3FC9A0B9AABD8535A033E251B006DF5EE41C9E6EC5B88776133E559FB4CA574533BFA648E5E58D3307723A03DCFC50A1386AF114465A16C46458D25FEEEDFE6DCEA0258E328AA6422AD7C042FCA15220158403AAD09E4A8A9A26B47308F706989B2DCE04704DC194A39347F426F14A11907DAA71FE372626BAD252D520CBF304A2593AB871590435E47808F45289FA1785E0A6735256D1454DA2DB828ED2
7.1) generation of encrypted_data

Generated payload (excluding transport headers/trailers):

0000 | 54 B6 43 66 2C 77 8C E5 A8 6C 26 E5 9A 2F 7A A9
0010 | 50 2E CF E8 EE 59 A6 10 44 FB 02 B6 CB D9 B9 12
0020 | 4D 4C 30 24 00 00 00 00 00 00 00 00 FE 00 01 00
0030 | 57 50 0C DF 13 B2 2D 65 32 88 11 82 32 DA 6A 1D
0040 | 8A 05 F1 90 4F F6 EF 99 E8 DE 8F 2F 9E A3 43 C0
0050 | 02 6E 09 C6 E2 96 74 1A E8 49 05 3A E1 35 F4 A3
0060 | 83 1C C5 BE BE E2 DF 52 A9 54 05 B5 0F 20 36 41
0070 | AC 1C 90 41 10 79 DA 49 67 4E E7 FD CF 62 EA E6
0080 | 1C 4A 18 1A C1 3A ED CE FC D8 09 D7 8F 52 59 FA
0090 | 8D 5F 3F C9 A0 B9 AA BD 85 35 A0 33 E2 51 B0 06
00A0 | DF 5E E4 1C 9E 6E C5 B8 87 76 13 3E 55 9F B4 CA
00B0 | 57 45 33 BF A6 48 E5 E5 8D 33 07 72 3A 03 DC FC
00C0 | 50 A1 38 6A F1 14 46 5A 16 C4 64 58 D2 5F EE ED
00D0 | FE 6D CE A0 25 8E 32 8A A6 42 2A D7 C0 42 FC A1
00E0 | 52 20 15 84 03 AA D0 9E 4A 8A 9A 26 B4 73 08 F7
00F0 | 06 98 9B 2D CE 04 70 4D C1 94 A3 93 47 F4 26 F1
0100 | 4A 11 90 7D AA 71 FE 37 26 26 BA D2 52 D5 20 CB
0110 | F3 04 A2 59 3A B8 71 59 04 35 E4 78 08 F4 52 89
0120 | FA 17 85 E0 A6 73 52 56 D1 45 4D A2 DB 82 8E D2

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 2C778CE5A86C26E59A2F7AA9502ECFE8 Value generated by client in Step 1
server_nonce 20, 16 EE59A61044FB02B6CBD9B9124D4C3024 Value received from server in Step 2
g_b 36, 260 FE00010057500CDF13B22D6532881182 32DA6A1D8A05F1904FF6EF99E8DE8F2F 9EA343C0026E09C6E296741AE849053A E135F4A3831CC5BEBEE2DF52A95405B5 0F203641AC1C90411079DA49674EE7FD CF62EAE61C4A181AC13AEDCEFCD809D7 8F5259FA8D5F3FC9A0B9AABD8535A033 E251B006DF5EE41C9E6EC5B88776133E 559FB4CA574533BFA648E5E58D330772 3A03DCFC50A1386AF114465A16C46458 D25FEEEDFE6DCEA0258E328AA6422AD7 C042FCA15220158403AAD09E4A8A9A26 B47308F706989B2DCE04704DC194A393 47F426F14A11907DAA71FE372626BAD2 52D520CBF304A2593AB871590435E478 08F45289FA1785E0A6735256D1454DA2
DB828ED2
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 = 54B643662C778CE5A86C26E59A2F7AA9502ECFE8EE59A61044FB02B6CBD9B9124D4C30240000000000000000FE00010057500CDF13B22D653288118232DA6A1D8A05F1904FF6EF99E8DE8F2F9EA343C0026E09C6E296741AE849053AE135F4A3831CC5BEBEE2DF52A95405B50F203641AC1C90411079DA49674EE7FDCF62EAE61C4A181AC13AEDCEFCD809D78F5259FA8D5F3FC9A0B9AABD8535A033E251B006DF5EE41C9E6EC5B88776133E559FB4CA574533BFA648E5E58D3307723A03DCFC50A1386AF114465A16C46458D25FEEEDFE6DCEA0258E328AA6422AD7C042FCA15220158403AAD09E4A8A9A26B47308F706989B2DCE04704DC194A39347F426F14A11907DAA71FE372626BAD252D520CBF304A2593AB871590435E47808F45289FA1785E0A6735256D1454DA2DB828ED2
padding = 96D442C6E08D528C4F0A5BAB
tmp_aes_key = DDBF239F7830AA4F3F114D03F51064C3BA57F670F3D1AE3AD3EE3BF7FC5DD6F0
tmp_aes_iv = 94227170B201320D851385CA9EAAA0488BFD8AC8992638835C3A9C85B531A08D

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 = CE28E5995D618A4FA41DC58DF7A8AE988222E6ACBE0752766BA5A6FD2404751BD4D63FE732CBE7C06CB11439338AC85558415BA932C047FADCD547012DCB27AD4D84CAC106AF896C3A0D9BE5F0F6F836358B9902970548B0CA82D224E8B3BAD6724367B647491AEB8821D04690286D5419DF9127E68EA685908B6B86144F46FD0455FFD35660EF19EE8CEFAB7B09D4D0C5CDEBC4E5EB42F6940A82B2D1EEE337A16ED6C50990722F51B220C16F9FCD2249505A4A9FDC65F97A66B2DBEABDBD706CC8FDAEA9ECB4C7679CA8ABE0069716CA647E587049D63CFFD577F2D43AC71684497064AB02698F554DEFC87437CB4F02D2CF9A0F5E2B5EC3BA745AE26422650464262E7D1AF6E4801C00DBDBFB7A24D81DC6F56E98877EE4194F7157C8967373F60562F1D6A30F4D0F3B7E8760E299B23F8BDA6F0C2FAF17EA746F307559F36F3627AFD2EC5C7D868605772FFD22D2

The length of the final string is 336 bytes.

7.2) set_client_DH_params query

Sent payload (excluding transport headers/trailers):

0000 | 00 00 00 00 00 00 00 00 24 4C 0B 00 6E 6B 9C 68
0010 | 78 01 00 00 1F 5F 04 F5 2C 77 8C E5 A8 6C 26 E5
0020 | 9A 2F 7A A9 50 2E CF E8 EE 59 A6 10 44 FB 02 B6
0030 | CB D9 B9 12 4D 4C 30 24 FE 50 01 00 CE 28 E5 99
0040 | 5D 61 8A 4F A4 1D C5 8D F7 A8 AE 98 82 22 E6 AC
0050 | BE 07 52 76 6B A5 A6 FD 24 04 75 1B D4 D6 3F E7
0060 | 32 CB E7 C0 6C B1 14 39 33 8A C8 55 58 41 5B A9
0070 | 32 C0 47 FA DC D5 47 01 2D CB 27 AD 4D 84 CA C1
0080 | 06 AF 89 6C 3A 0D 9B E5 F0 F6 F8 36 35 8B 99 02
0090 | 97 05 48 B0 CA 82 D2 24 E8 B3 BA D6 72 43 67 B6
00A0 | 47 49 1A EB 88 21 D0 46 90 28 6D 54 19 DF 91 27
00B0 | E6 8E A6 85 90 8B 6B 86 14 4F 46 FD 04 55 FF D3
00C0 | 56 60 EF 19 EE 8C EF AB 7B 09 D4 D0 C5 CD EB C4
00D0 | E5 EB 42 F6 94 0A 82 B2 D1 EE E3 37 A1 6E D6 C5
00E0 | 09 90 72 2F 51 B2 20 C1 6F 9F CD 22 49 50 5A 4A
00F0 | 9F DC 65 F9 7A 66 B2 DB EA BD BD 70 6C C8 FD AE
0100 | A9 EC B4 C7 67 9C A8 AB E0 06 97 16 CA 64 7E 58
0110 | 70 49 D6 3C FF D5 77 F2 D4 3A C7 16 84 49 70 64
0120 | AB 02 69 8F 55 4D EF C8 74 37 CB 4F 02 D2 CF 9A
0130 | 0F 5E 2B 5E C3 BA 74 5A E2 64 22 65 04 64 26 2E
0140 | 7D 1A F6 E4 80 1C 00 DB DB FB 7A 24 D8 1D C6 F5
0150 | 6E 98 87 7E E4 19 4F 71 57 C8 96 73 73 F6 05 62
0160 | F1 D6 A3 0F 4D 0F 3B 7E 87 60 E2 99 B2 3F 8B DA
0170 | 6F 0C 2F AF 17 EA 74 6F 30 75 59 F3 6F 36 27 AF
0180 | D2 EC 5C 7D 86 86 05 77 2F FD 22 D2

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 244C0B006E6B9C68 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 2C778CE5A86C26E59A2F7AA9502ECFE8 Value generated by client in Step 1
server_nonce 40, 16 EE59A61044FB02B6CBD9B9124D4C3024 Value received from server in Step 2
encrypted_data 56, 340 FE500100CE28E5995D618A4FA41DC58D F7A8AE988222E6ACBE0752766BA5A6FD 2404751BD4D63FE732CBE7C06CB11439 338AC85558415BA932C047FADCD54701 2DCB27AD4D84CAC106AF896C3A0D9BE5 F0F6F836358B9902970548B0CA82D224 E8B3BAD6724367B647491AEB8821D046 90286D5419DF9127E68EA685908B6B86 144F46FD0455FFD35660EF19EE8CEFAB 7B09D4D0C5CDEBC4E5EB42F6940A82B2 D1EEE337A16ED6C50990722F51B220C1 6F9FCD2249505A4A9FDC65F97A66B2DB EABDBD706CC8FDAEA9ECB4C7679CA8AB E0069716CA647E587049D63CFFD577F2 D43AC71684497064AB02698F554DEFC8 7437CB4F02D2CF9A0F5E2B5EC3BA745A E26422650464262E7D1AF6E4801C00DB DBFB7A24D81DC6F56E98877EE4194F71 57C8967373F60562F1D6A30F4D0F3B7E 8760E299B23F8BDA6F0C2FAF17EA746F 307559F36F3627AFD2EC5C7D86860577
2FFD22D2
Encrypted client_DH_inner_data generated previously, serialized as a TL byte string
8) Auth key generation

The client computes the auth_key using formula g_a^b mod dh_prime:

auth_key = 8624E3894D4602118F4C5B85EDDDCED2A8C460BFD88EF001E987FDD137BB42331FF703E240D9425798EB5925B9F5C199635ED9D5534F26D695D5183B6355FFC58C72E61DD2A1F545FED494AE89060E89CEDFDDCF59CC36D672529038D7F67B01156A4883983F1C856F665007B063A16116C0457122361A4C15A3ABA2EB79A5B21DD5C996CFB873CA65A3FEAA7E81EE2F47E96AEF167AE8FBD1CB7BD44607B90AEA4C3D9F532E71C14B538167B15FD8578F3AA9CC61416DF220B32BC33AA3AF5B7A4F42A7ACF470713C23523DDCE2DDDBF282AB69AC38DAF4133D0CF8705259946EC33AE5F1316A970484891231675BFF4F2CC17DE945BB90E1AFAFFA1FBBD994
9) Final server reply

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 0C 54 35 71 6B 9C 68
0010 | 34 00 00 00 34 F7 CB 3B 2C 77 8C E5 A8 6C 26 E5
0020 | 9A 2F 7A A9 50 2E CF E8 EE 59 A6 10 44 FB 02 B6
0030 | CB D9 B9 12 4D 4C 30 24 9F 9C F4 DE 76 C5 E5 D4
0040 | F2 F5 B0 3B 95 B9 2C A2

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 010C5435716B9C68 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 2C778CE5A86C26E59A2F7AA9502ECFE8 Value generated by client in Step 1
server_nonce 40, 16 EE59A61044FB02B6CBD9B9124D4C3024 Value received from server in Step 2
new_nonce_hash1 56, 16 9F9CF4DE76C5E5D4F2F5B03B95B92CA2 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.