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; or0x7f
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 send0xef
as 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 D4 72 06 00 50 3D C5 65
0010 | 14 00 00 00 F1 8E 7E BE 40 67 09 F6 12 FA DF BE
0020 | C3 F0 28 9D 0A A6 7E EF
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 | D4720600503DC565 |
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 | 406709F612FADFBEC3F0289D0AA67EEF |
Random number |
Received payload (excluding transport headers/trailers):
0000 | 00 00 00 00 00 00 00 00 01 D8 31 75 50 3D C5 65
0010 | A8 00 00 00 63 24 16 05 40 67 09 F6 12 FA DF BE
0020 | C3 F0 28 9D 0A A6 7E EF E1 1D BC 3B C9 7D 91 A2
0030 | 61 54 F9 32 AF 01 99 43 08 25 65 95 ED B7 76 67
0040 | 97 00 00 00 15 C4 B5 1C 03 00 00 00 A5 B7 F7 09
0050 | 35 5F C3 0B 21 6B E8 6C 02 2B B4 C3 85 FD 64 DE
0060 | 85 1D 9D D0
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 | 01D83175503DC565 |
Message ID generated as specified here » (unixtime() << 32) + (N*4) |
message_length | 16, 4 | A8000000 (168 in decimal) |
Message body length |
%(resPQ) | 20, 4 | 63241605 |
resPQ constructor number from TL schema |
nonce | 24, 16 | 406709F612FADFBEC3F0289D0AA67EEF |
Value generated by client in Step 1 |
server_nonce | 40, 16 | E11DBC3BC97D91A26154F932AF019943 |
Server-generated random number |
pq | 56, 12 | 08256595EDB7766797000000 TL byte deserialization => bigendian conversion to decimal => 2694724800268887959 |
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 | A5B7F709355FC30B |
64 lower-order bits of SHA1(server_public_key) |
server_public_key_fingerprints[1] | 84, 8 | 216BE86C022BB4C3 |
64 lower-order bits of SHA1(server_public_key) |
server_public_key_fingerprints[2] | 92, 8 | 85FD64DE851D9DD0 |
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
.
pq = 2694724800268887959
Decompose into 2 prime cofactors p < q
: 2694724800268887959 = 1513098571 * 1780931429
p = 1513098571
q = 1780931429
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 25 65 95 ED B7 76 67 97 00 00 00
0010 | 04 5A 30 0D 4B 00 00 00 04 6A 26 DB 65 00 00 00
0020 | 40 67 09 F6 12 FA DF BE C3 F0 28 9D 0A A6 7E EF
0030 | E1 1D BC 3B C9 7D 91 A2 61 54 F9 32 AF 01 99 43
0040 | A8 BB C8 49 51 2D AC 6C 67 B6 EF D9 15 7D 6C A7
0050 | 37 7A 17 76 30 7D 84 26 5C 6B E9 BD CF 80 2A C1
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 | 08256595EDB7766797000000 TL byte deserialization => bigendian conversion to decimal => 2694724800268887959 |
Single-byte prefix denoting length, 8-byte string, and three bytes of padding |
p | 16, 8 | 045A300D4B000000 TL byte deserialization => bigendian conversion to decimal => 1513098571 |
First prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding |
q | 24, 8 | 046A26DB65000000 TL byte deserialization => bigendian conversion to decimal => 1780931429 |
Second prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding |
nonce | 32, 16 | 406709F612FADFBEC3F0289D0AA67EEF |
Value generated by client in Step 1 |
server_nonce | 48, 16 | E11DBC3BC97D91A26154F932AF019943 |
Value received from server in Step 2 |
new_nonce | 64, 32 | A8BBC849512DAC6C67B6EFD9157D6CA7 377A1776307D84265C6BE9BDCF802AC1 |
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 = 955FF5A908256595EDB7766797000000045A300D4B000000046A26DB65000000406709F612FADFBEC3F0289D0AA67EEFE11DBC3BC97D91A26154F932AF019943A8BBC849512DAC6C67B6EFD9157D6CA7377A1776307D84265C6BE9BDCF802AC102000000
random_padding_bytes = D944BB8347C876177FE03C2562BF4E87258EF147A7815D8853AA4B1065A5A385D0DA7E0B6100FAF55728D04DFC84E7E0D20006E07E1CB036730F5B3209CF85B2365B39DE2CBC56F40B725AD347835E5D1973567ECE8A02CF343D54F7
And this is the output:
encrypted_data = B80632B3F0D1AB28EFAE2CF974C4A2D51A77FCB6DEFD415E1EC284CAB2B5F88D5C4C5B19AFF5E940CE14CCB6A7F340EC88DF7C1F091FB6F7323B047C02DC63212D0DEBE4B3B7A0310E26DB1289CBA24112DF37506C90DEAB797623E4AFF4643D2A921891346BC176C4E1CCE14F64FA59526DD021EFFA428E8F8ACEEB96DBD4729E99BBB26DDDC744D584B732415DFFE20418953F4EAFC81DADE5C6606A1E7FAA3EDB90F36ECF405422C97C360CC31A444B1EEB6C33D62C5802165C72BBC85D1ADBCCD17988DE7F43DA0F340502744B52B196A78EF1ED1372C6EA1232603FDB9C28F7F8783F29098FFD0FE9B066C460ECBA0A2962B82398C1B32D3DCB3BC3A59E
The length of the final string is 256 bytes.
encrypted_data
Sent payload (excluding transport headers/trailers):
0000 | 00 00 00 00 00 00 00 00 D8 72 06 00 50 3D C5 65
0010 | 40 01 00 00 BE E4 12 D7 40 67 09 F6 12 FA DF BE
0020 | C3 F0 28 9D 0A A6 7E EF E1 1D BC 3B C9 7D 91 A2
0030 | 61 54 F9 32 AF 01 99 43 04 5A 30 0D 4B 00 00 00
0040 | 04 6A 26 DB 65 00 00 00 85 FD 64 DE 85 1D 9D D0
0050 | FE 00 01 00 B8 06 32 B3 F0 D1 AB 28 EF AE 2C F9
0060 | 74 C4 A2 D5 1A 77 FC B6 DE FD 41 5E 1E C2 84 CA
0070 | B2 B5 F8 8D 5C 4C 5B 19 AF F5 E9 40 CE 14 CC B6
0080 | A7 F3 40 EC 88 DF 7C 1F 09 1F B6 F7 32 3B 04 7C
0090 | 02 DC 63 21 2D 0D EB E4 B3 B7 A0 31 0E 26 DB 12
00A0 | 89 CB A2 41 12 DF 37 50 6C 90 DE AB 79 76 23 E4
00B0 | AF F4 64 3D 2A 92 18 91 34 6B C1 76 C4 E1 CC E1
00C0 | 4F 64 FA 59 52 6D D0 21 EF FA 42 8E 8F 8A CE EB
00D0 | 96 DB D4 72 9E 99 BB B2 6D DD C7 44 D5 84 B7 32
00E0 | 41 5D FF E2 04 18 95 3F 4E AF C8 1D AD E5 C6 60
00F0 | 6A 1E 7F AA 3E DB 90 F3 6E CF 40 54 22 C9 7C 36
0100 | 0C C3 1A 44 4B 1E EB 6C 33 D6 2C 58 02 16 5C 72
0110 | BB C8 5D 1A DB CC D1 79 88 DE 7F 43 DA 0F 34 05
0120 | 02 74 4B 52 B1 96 A7 8E F1 ED 13 72 C6 EA 12 32
0130 | 60 3F DB 9C 28 F7 F8 78 3F 29 09 8F FD 0F E9 B0
0140 | 66 C4 60 EC BA 0A 29 62 B8 23 98 C1 B3 2D 3D CB
0150 | 3B C3 A5 9E
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 | D8720600503DC565 |
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 | 406709F612FADFBEC3F0289D0AA67EEF |
Value generated by client in Step 1 |
server_nonce | 40, 16 | E11DBC3BC97D91A26154F932AF019943 |
Value received from server in Step 2 |
p | 56, 8 | 045A300D4B000000 TL byte deserialization => bigendian conversion to decimal => 1513098571 |
First prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding |
q | 64, 8 | 046A26DB65000000 TL byte deserialization => bigendian conversion to decimal => 1780931429 |
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 | FE000100B80632B3F0D1AB28EFAE2CF9 74C4A2D51A77FCB6DEFD415E1EC284CA B2B5F88D5C4C5B19AFF5E940CE14CCB6 A7F340EC88DF7C1F091FB6F7323B047C 02DC63212D0DEBE4B3B7A0310E26DB12 89CBA24112DF37506C90DEAB797623E4 AFF4643D2A921891346BC176C4E1CCE1 4F64FA59526DD021EFFA428E8F8ACEEB 96DBD4729E99BBB26DDDC744D584B732 415DFFE20418953F4EAFC81DADE5C660 6A1E7FAA3EDB90F36ECF405422C97C36 0CC31A444B1EEB6C33D62C5802165C72 BBC85D1ADBCCD17988DE7F43DA0F3405 02744B52B196A78EF1ED1372C6EA1232 603FDB9C28F7F8783F29098FFD0FE9B0 66C460ECBA0A2962B82398C1B32D3DCB 3BC3A59E |
Value generated above |
Received payload (excluding transport headers/trailers):
0000 | 00 00 00 00 00 00 00 00 01 4C 6E 1E 51 3D C5 65
0010 | C4 02 00 00 5C 07 E8 D0 40 67 09 F6 12 FA DF BE
0020 | C3 F0 28 9D 0A A6 7E EF E1 1D BC 3B C9 7D 91 A2
0030 | 61 54 F9 32 AF 01 99 43 FE 50 02 00 6A D7 DD 5D
0040 | 8B 25 26 C7 61 AB E5 0E 93 C8 2A 6F 33 1B 1E AE
0050 | 0A D0 11 89 3D A9 76 E3 77 1D 4A A4 52 09 D2 34
0060 | FE A6 56 42 98 53 86 B8 17 BF 89 80 F5 17 F6 D3
0070 | 2D BE B4 7E 34 53 45 56 F9 50 DD F9 60 DB 72 1A
0080 | 48 48 02 31 61 91 61 11 26 82 C6 04 6D 56 29 C7
0090 | 1C D1 EC 80 61 DF CD D7 04 70 3E C7 A8 AE BD CB
00A0 | D1 59 57 9F C8 88 6D 9F A5 1E 00 9A F4 9B 5A B9
00B0 | 0C 76 28 EB 81 C9 78 8A 2E B6 AC 0E 75 7A 7D EB
00C0 | E3 D9 49 F8 0A 99 0B ED B4 D2 DB AE 43 F0 03 28
00D0 | B8 2F 4D 8F C8 3A 9B 9C FE EF 46 7E 15 93 BB 45
00E0 | 79 EE 32 41 2F 16 7A 78 0C FA 51 76 50 BD 0E B5
00F0 | 1C BF B5 0E 3A FE 97 88 39 46 61 31 FC D9 56 71
0100 | 1E 63 61 4F 00 6A 55 ED 35 ED 2B 1F 83 3C 29 F4
0110 | FD 7A 84 F0 C8 F1 C1 0D FC 1A 1A AF 9A 8A 57 10
0120 | 8D EC F2 06 E3 96 84 06 F0 FB 25 E9 22 DF 15 4F
0130 | 49 7B 51 52 7E 48 34 20 2F AB 47 7A 13 7D 0A 99
0140 | D1 C3 47 19 6F BA 10 69 9F 52 EA 56 F0 1E F9 38
0150 | 29 B3 10 A5 C9 7D B9 5F D5 7E 64 41 7E 52 6E B9
0160 | 20 D2 61 15 7C 6E 38 79 1B DD 53 89 EE B7 44 E0
0170 | 75 D9 52 DB 33 A8 15 12 07 D0 AB 3C 62 9E 30 A7
0180 | 23 A5 20 5F 8F A1 83 98 93 7E D2 71 4A 4E 76 A5
0190 | F4 51 25 08 A4 BE 1B 4D 6A E4 6F D1 56 C6 F0 63
01A0 | 47 AF 5E 07 CE 49 27 91 95 13 3B 07 CC E4 BC 67
01B0 | 75 D8 8F 36 11 18 0D 23 C4 C7 09 46 61 9A D7 59
01C0 | AB 9F 18 3A 38 5C CF 9B F1 93 15 FA DB E8 A4 FD
01D0 | C7 48 AF 52 DF 93 03 45 90 9C 87 0D E4 B4 89 01
01E0 | E9 F9 0E 56 D7 4C A5 34 D8 E1 FE 3A 35 A9 2A 18
01F0 | D6 76 95 8E B8 FC 3D 82 F9 CE E3 08 DF 2A 9E 4C
0200 | CD 23 FF 89 EA 25 5B 9E ED BC 33 78 14 88 79 66
0210 | 6F FC 2E 19 A4 31 CB B5 7A E1 A0 10 FF E5 CB 39
0220 | AB F1 31 AD D9 E9 0B F9 69 A1 12 C4 35 50 9B 78
0230 | 96 0E 0B 20 03 1C 82 21 90 84 15 61 E8 39 04 46
0240 | 22 76 60 BB AC CF 3D 53 57 4B FB A3 3B F4 76 E3
0250 | BD C9 EB 68 0A A2 A1 7F D6 75 6F 65 27 25 ED 03
0260 | 13 E5 EB 0F D6 A9 C8 C9 49 EE FB E8 09 A8 93 11
0270 | BF 20 F4 00 55 CA 25 FD 16 9D C1 3E E1 4B 31 50
0280 | 92 FD E4 18 46 38 D8 49 68 2F D8 62
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 | 014C6E1E513DC565 |
Message ID generated as specified here » (unixtime() << 32) + (N*4) |
message_length | 16, 4 | C4020000 (708 in decimal) |
Message body length |
%(server_DH_params_ok) | 20, 4 | 5c07e8d0 |
server_DH_params_ok constructor number from TL schema |
nonce | 24, 16 | 406709F612FADFBEC3F0289D0AA67EEF |
Value generated by client in Step 1 |
server_nonce | 40, 16 | E11DBC3BC97D91A26154F932AF019943 |
Value received from server in Step 2 |
encrypted_answer | 56, 596 | FE5002006AD7DD5D8B2526C761ABE50E 93C82A6F331B1EAE0AD011893DA976E3 771D4AA45209D234FEA65642985386B8 17BF8980F517F6D32DBEB47E34534556 F950DDF960DB721A4848023161916111 2682C6046D5629C71CD1EC8061DFCDD7 04703EC7A8AEBDCBD159579FC8886D9F A51E009AF49B5AB90C7628EB81C9788A 2EB6AC0E757A7DEBE3D949F80A990BED B4D2DBAE43F00328B82F4D8FC83A9B9C FEEF467E1593BB4579EE32412F167A78 0CFA517650BD0EB51CBFB50E3AFE9788 39466131FCD956711E63614F006A55ED 35ED2B1F833C29F4FD7A84F0C8F1C10D FC1A1AAF9A8A57108DECF206E3968406 F0FB25E922DF154F497B51527E483420 2FAB477A137D0A99D1C347196FBA1069 9F52EA56F01EF93829B310A5C97DB95F D57E64417E526EB920D261157C6E3879 1BDD5389EEB744E075D952DB33A81512 07D0AB3C629E30A723A5205F8FA18398 937ED2714A4E76A5F4512508A4BE1B4D 6AE46FD156C6F06347AF5E07CE492791 95133B07CCE4BC6775D88F3611180D23 C4C70946619AD759AB9F183A385CCF9B F19315FADBE8A4FDC748AF52DF930345 909C870DE4B48901E9F90E56D74CA534 D8E1FE3A35A92A18D676958EB8FC3D82 F9CEE308DF2A9E4CCD23FF89EA255B9E EDBC3378148879666FFC2E19A431CBB5 7AE1A010FFE5CB39ABF131ADD9E90BF9 69A112C435509B78960E0B20031C8221 90841561E8390446227660BBACCF3D53 574BFBA33BF476E3BDC9EB680AA2A17F D6756F652725ED0313E5EB0FD6A9C8C9 49EEFBE809A89311BF20F40055CA25FD 169DC13EE14B315092FDE4184638D849 682FD862 |
See below |
Decrypt encrypted_answer
using the reverse of the process specified in step 6:
encrypted_answer = 6AD7DD5D8B2526C761ABE50E93C82A6F331B1EAE0AD011893DA976E3771D4AA45209D234FEA65642985386B817BF8980F517F6D32DBEB47E34534556F950DDF960DB721A48480231619161112682C6046D5629C71CD1EC8061DFCDD704703EC7A8AEBDCBD159579FC8886D9FA51E009AF49B5AB90C7628EB81C9788A2EB6AC0E757A7DEBE3D949F80A990BEDB4D2DBAE43F00328B82F4D8FC83A9B9CFEEF467E1593BB4579EE32412F167A780CFA517650BD0EB51CBFB50E3AFE978839466131FCD956711E63614F006A55ED35ED2B1F833C29F4FD7A84F0C8F1C10DFC1A1AAF9A8A57108DECF206E3968406F0FB25E922DF154F497B51527E4834202FAB477A137D0A99D1C347196FBA10699F52EA56F01EF93829B310A5C97DB95FD57E64417E526EB920D261157C6E38791BDD5389EEB744E075D952DB33A8151207D0AB3C629E30A723A5205F8FA18398937ED2714A4E76A5F4512508A4BE1B4D6AE46FD156C6F06347AF5E07CE49279195133B07CCE4BC6775D88F3611180D23C4C70946619AD759AB9F183A385CCF9BF19315FADBE8A4FDC748AF52DF930345909C870DE4B48901E9F90E56D74CA534D8E1FE3A35A92A18D676958EB8FC3D82F9CEE308DF2A9E4CCD23FF89EA255B9EEDBC3378148879666FFC2E19A431CBB57AE1A010FFE5CB39ABF131ADD9E90BF969A112C435509B78960E0B20031C822190841561E8390446227660BBACCF3D53574BFBA33BF476E3BDC9EB680AA2A17FD6756F652725ED0313E5EB0FD6A9C8C949EEFBE809A89311BF20F40055CA25FD169DC13EE14B315092FDE4184638D849682FD862
tmp_aes_key = 5EA702F743E850F5546E857F08B7D5337BBAEDF9B61248751594851BE2E8C297
tmp_aes_iv = 1CEF8E372A63D97EBFA805C0DBB018BC7C1E0931693FBCB1A1AFC0C0A8BBC849
Yielding:
answer_with_hash = 60026275CC91DDEC5371C67B10331C4C1D362585BA0D89B5406709F612FADFBEC3F0289D0AA67EEFE11DBC3BC97D91A26154F932AF01994303000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE0001000A77200BDFF6E6C4C126A2C41DF310AB3A3BDBD698CD480749E1F3C64FB1CFC9DFC70AC6F1AA671019620A640055B2CF7D7D99CC86533645C0FA000954DE2987BAD68D7450CF134C9F0305F34C1BB285DA8233F65970A01C4BD3AFD5EA3CD5864B8F1DCB35D5E9737DF15063C54CF53048EF519A280498DDDAF23764F29FFB0C5813CAAD90C319BE8592B78C4BE815E65ADA7C62EA23754B5A2C5A86C4721872D0CC48E0F895C3EBE186E81E5F0E88A6B3F09101C409AF3410B64238FBF2A2095E3F3B7FFC7EB3A02A319B99A155647BC59958BCDFED8A1CC6EB7F13F8600E521D9D0247B0F639F2FA3B09F72987781F71C0E8AA950167DE5092380B4853E7F1513DC565C26F8049523E89D2
answer = BA0D89B5406709F612FADFBEC3F0289D0AA67EEFE11DBC3BC97D91A26154F932AF01994303000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE0001000A77200BDFF6E6C4C126A2C41DF310AB3A3BDBD698CD480749E1F3C64FB1CFC9DFC70AC6F1AA671019620A640055B2CF7D7D99CC86533645C0FA000954DE2987BAD68D7450CF134C9F0305F34C1BB285DA8233F65970A01C4BD3AFD5EA3CD5864B8F1DCB35D5E9737DF15063C54CF53048EF519A280498DDDAF23764F29FFB0C5813CAAD90C319BE8592B78C4BE815E65ADA7C62EA23754B5A2C5A86C4721872D0CC48E0F895C3EBE186E81E5F0E88A6B3F09101C409AF3410B64238FBF2A2095E3F3B7FFC7EB3A02A319B99A155647BC59958BCDFED8A1CC6EB7F13F8600E521D9D0247B0F639F2FA3B09F72987781F71C0E8AA950167DE5092380B4853E7F1513DC565C26F8049523E89D2
Generated payload (excluding transport headers/trailers):
0000 | BA 0D 89 B5 40 67 09 F6 12 FA DF BE C3 F0 28 9D
0010 | 0A A6 7E EF E1 1D BC 3B C9 7D 91 A2 61 54 F9 32
0020 | AF 01 99 43 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 | 0A 77 20 0B DF F6 E6 C4 C1 26 A2 C4 1D F3 10 AB
0140 | 3A 3B DB D6 98 CD 48 07 49 E1 F3 C6 4F B1 CF C9
0150 | DF C7 0A C6 F1 AA 67 10 19 62 0A 64 00 55 B2 CF
0160 | 7D 7D 99 CC 86 53 36 45 C0 FA 00 09 54 DE 29 87
0170 | BA D6 8D 74 50 CF 13 4C 9F 03 05 F3 4C 1B B2 85
0180 | DA 82 33 F6 59 70 A0 1C 4B D3 AF D5 EA 3C D5 86
0190 | 4B 8F 1D CB 35 D5 E9 73 7D F1 50 63 C5 4C F5 30
01A0 | 48 EF 51 9A 28 04 98 DD DA F2 37 64 F2 9F FB 0C
01B0 | 58 13 CA AD 90 C3 19 BE 85 92 B7 8C 4B E8 15 E6
01C0 | 5A DA 7C 62 EA 23 75 4B 5A 2C 5A 86 C4 72 18 72
01D0 | D0 CC 48 E0 F8 95 C3 EB E1 86 E8 1E 5F 0E 88 A6
01E0 | B3 F0 91 01 C4 09 AF 34 10 B6 42 38 FB F2 A2 09
01F0 | 5E 3F 3B 7F FC 7E B3 A0 2A 31 9B 99 A1 55 64 7B
0200 | C5 99 58 BC DF ED 8A 1C C6 EB 7F 13 F8 60 0E 52
0210 | 1D 9D 02 47 B0 F6 39 F2 FA 3B 09 F7 29 87 78 1F
0220 | 71 C0 E8 AA 95 01 67 DE 50 92 38 0B 48 53 E7 F1
0230 | 51 3D C5 65
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 | 406709F612FADFBEC3F0289D0AA67EEF |
Value generated by client in Step 1 |
server_nonce | 20, 16 | E11DBC3BC97D91A26154F932AF019943 |
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 | FE0001000A77200BDFF6E6C4C126A2C4 1DF310AB3A3BDBD698CD480749E1F3C6 4FB1CFC9DFC70AC6F1AA671019620A64 0055B2CF7D7D99CC86533645C0FA0009 54DE2987BAD68D7450CF134C9F0305F3 4C1BB285DA8233F65970A01C4BD3AFD5 EA3CD5864B8F1DCB35D5E9737DF15063 C54CF53048EF519A280498DDDAF23764 F29FFB0C5813CAAD90C319BE8592B78C 4BE815E65ADA7C62EA23754B5A2C5A86 C4721872D0CC48E0F895C3EBE186E81E 5F0E88A6B3F09101C409AF3410B64238 FBF2A2095E3F3B7FFC7EB3A02A319B99 A155647BC59958BCDFED8A1CC6EB7F13 F8600E521D9D0247B0F639F2FA3B09F7 2987781F71C0E8AA950167DE5092380B 4853E7F1 |
g_a diffie-hellman parameter |
server_time | 560, 4 | 513DC565 (1707425105 in decimal) |
Server time |
First, generate a secure random 2048-bit number b:
b = 1376A5A6BF7A9F874B47028F3D5CFF0689FD52F58949BB0EE9BACDBE81DD1CED07101844EB6F2AE19E61120B84799431F445785E33A18141399821479AE96786E0F4E9C5C6C9E46BF562C21C96B0F8F7438C8CABA3DFCB3DD3B886C2A37B95ED804315335C0DDFFEB3A278243D89F964278BC734D1087D6D4B554C1F78397A414F440E38BA9A4F1211B20AE835437762F81A45FDB035BB2220D939693084B39A3C7BE2481309AB9AE378EAB8BB3A15A69EBA80BEF683582E2218FA604E823EABD111553D31DBB46B9383A0D8EEF615FFF9CF266C970800AA28AC5E962D20351311A815FFA7562989CA6D6323BF2B5AF40EF3F45021B7445664852D07B80172CE
Then compute g_b = pow(g, b) mod dh_prime
g_b = A215D057BC6648453D68C2F418A38D9D4F4FA47E5D520AC7EBC2ADC3B00075090C10A1E9D96A5DDA127317F2DDC165C5F6C8C2854648C106D0D9DF684DAE70B0E6021658806245B494B762B1979E8BD597B5CC8E43A80F96CA47FB0765C98D40529F3D94C82113AE32C603AA24411EF8B330565A1D66EA6B89C9D4F8AFFEEA397C4B247564215D147B6AD0DF7F3FB4499E89E34304531D87448B91967B5BD53093F09386C0F78940C1DD6AA7C8667E15857453E6AAD275F94CD386468CF49108FB7C54282596A4D0314DCE9EFED4066A6E072471439AEAAA74157DB7DD53F01982982534DEE8740610BA433BF459B3DFE38674561F31991CE007BA112DDA6718
Generated payload (excluding transport headers/trailers):
0000 | 54 B6 43 66 40 67 09 F6 12 FA DF BE C3 F0 28 9D
0010 | 0A A6 7E EF E1 1D BC 3B C9 7D 91 A2 61 54 F9 32
0020 | AF 01 99 43 00 00 00 00 00 00 00 00 FE 00 01 00
0030 | A2 15 D0 57 BC 66 48 45 3D 68 C2 F4 18 A3 8D 9D
0040 | 4F 4F A4 7E 5D 52 0A C7 EB C2 AD C3 B0 00 75 09
0050 | 0C 10 A1 E9 D9 6A 5D DA 12 73 17 F2 DD C1 65 C5
0060 | F6 C8 C2 85 46 48 C1 06 D0 D9 DF 68 4D AE 70 B0
0070 | E6 02 16 58 80 62 45 B4 94 B7 62 B1 97 9E 8B D5
0080 | 97 B5 CC 8E 43 A8 0F 96 CA 47 FB 07 65 C9 8D 40
0090 | 52 9F 3D 94 C8 21 13 AE 32 C6 03 AA 24 41 1E F8
00A0 | B3 30 56 5A 1D 66 EA 6B 89 C9 D4 F8 AF FE EA 39
00B0 | 7C 4B 24 75 64 21 5D 14 7B 6A D0 DF 7F 3F B4 49
00C0 | 9E 89 E3 43 04 53 1D 87 44 8B 91 96 7B 5B D5 30
00D0 | 93 F0 93 86 C0 F7 89 40 C1 DD 6A A7 C8 66 7E 15
00E0 | 85 74 53 E6 AA D2 75 F9 4C D3 86 46 8C F4 91 08
00F0 | FB 7C 54 28 25 96 A4 D0 31 4D CE 9E FE D4 06 6A
0100 | 6E 07 24 71 43 9A EA AA 74 15 7D B7 DD 53 F0 19
0110 | 82 98 25 34 DE E8 74 06 10 BA 43 3B F4 59 B3 DF
0120 | E3 86 74 56 1F 31 99 1C E0 07 BA 11 2D DA 67 18
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 | 406709F612FADFBEC3F0289D0AA67EEF |
Value generated by client in Step 1 |
server_nonce | 20, 16 | E11DBC3BC97D91A26154F932AF019943 |
Value received from server in Step 2 |
g_b | 36, 260 | FE000100A215D057BC6648453D68C2F4 18A38D9D4F4FA47E5D520AC7EBC2ADC3 B00075090C10A1E9D96A5DDA127317F2 DDC165C5F6C8C2854648C106D0D9DF68 4DAE70B0E6021658806245B494B762B1 979E8BD597B5CC8E43A80F96CA47FB07 65C98D40529F3D94C82113AE32C603AA 24411EF8B330565A1D66EA6B89C9D4F8 AFFEEA397C4B247564215D147B6AD0DF 7F3FB4499E89E34304531D87448B9196 7B5BD53093F09386C0F78940C1DD6AA7 C8667E15857453E6AAD275F94CD38646 8CF49108FB7C54282596A4D0314DCE9E FED4066A6E072471439AEAAA74157DB7 DD53F01982982534DEE8740610BA433B F459B3DFE38674561F31991CE007BA11 2DDA6718 |
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 = 54B64366406709F612FADFBEC3F0289D0AA67EEFE11DBC3BC97D91A26154F932AF0199430000000000000000FE000100A215D057BC6648453D68C2F418A38D9D4F4FA47E5D520AC7EBC2ADC3B00075090C10A1E9D96A5DDA127317F2DDC165C5F6C8C2854648C106D0D9DF684DAE70B0E6021658806245B494B762B1979E8BD597B5CC8E43A80F96CA47FB0765C98D40529F3D94C82113AE32C603AA24411EF8B330565A1D66EA6B89C9D4F8AFFEEA397C4B247564215D147B6AD0DF7F3FB4499E89E34304531D87448B91967B5BD53093F09386C0F78940C1DD6AA7C8667E15857453E6AAD275F94CD386468CF49108FB7C54282596A4D0314DCE9EFED4066A6E072471439AEAAA74157DB7DD53F01982982534DEE8740610BA433BF459B3DFE38674561F31991CE007BA112DDA6718
padding = 74876952857BA6AAA495A20D
tmp_aes_key = 5EA702F743E850F5546E857F08B7D5337BBAEDF9B61248751594851BE2E8C297
tmp_aes_iv = 1CEF8E372A63D97EBFA805C0DBB018BC7C1E0931693FBCB1A1AFC0C0A8BBC849
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 = 14D185E575255986C29BE3A0437D525BA22430CBA0CD755225945AD3A1ACEFB536518514F5086892E6E3FA84D1CBB644BC8F7BEBCDE74E31BA8A073F47623EBB6E7D94B3A676A4C1AFD4689C52D05F73D21C33F64FE6AEABD04273D9117CD064E467E1F8E6C887BCAE4679E0399AD35DB1302A80629618F8C8485248D89A4E3568B464FF7B608CBE24B51EEB81B65D76224B62A1669EAA48A99C122E5E8A778E13DD441DC52175160088A498F186A2B99C736FE8C5C3E274D804C629564A0F15DDABC5B449356A7990900652A7432AFB1499C7CE09246F6B29006425DF2926465B04F17C0077B6A336A50E46B675AD5607F05818F84EADEC1F4847BF311027E742F8B1E183C01810C4CE964F2A0F36E257849C144C9B0B93B4A7A9E57391DB0CCB0D757A2B7A77257C8FF55553D66B6E1D45E9D8CA88E5A47B16322FF2ED5F5ABE099E7006B2D29C829D746B704130B1
The length of the final string is 336 bytes.
Sent payload (excluding transport headers/trailers):
0000 | 00 00 00 00 00 00 00 00 18 5C 07 00 51 3D C5 65
0010 | 78 01 00 00 1F 5F 04 F5 40 67 09 F6 12 FA DF BE
0020 | C3 F0 28 9D 0A A6 7E EF E1 1D BC 3B C9 7D 91 A2
0030 | 61 54 F9 32 AF 01 99 43 FE 50 01 00 14 D1 85 E5
0040 | 75 25 59 86 C2 9B E3 A0 43 7D 52 5B A2 24 30 CB
0050 | A0 CD 75 52 25 94 5A D3 A1 AC EF B5 36 51 85 14
0060 | F5 08 68 92 E6 E3 FA 84 D1 CB B6 44 BC 8F 7B EB
0070 | CD E7 4E 31 BA 8A 07 3F 47 62 3E BB 6E 7D 94 B3
0080 | A6 76 A4 C1 AF D4 68 9C 52 D0 5F 73 D2 1C 33 F6
0090 | 4F E6 AE AB D0 42 73 D9 11 7C D0 64 E4 67 E1 F8
00A0 | E6 C8 87 BC AE 46 79 E0 39 9A D3 5D B1 30 2A 80
00B0 | 62 96 18 F8 C8 48 52 48 D8 9A 4E 35 68 B4 64 FF
00C0 | 7B 60 8C BE 24 B5 1E EB 81 B6 5D 76 22 4B 62 A1
00D0 | 66 9E AA 48 A9 9C 12 2E 5E 8A 77 8E 13 DD 44 1D
00E0 | C5 21 75 16 00 88 A4 98 F1 86 A2 B9 9C 73 6F E8
00F0 | C5 C3 E2 74 D8 04 C6 29 56 4A 0F 15 DD AB C5 B4
0100 | 49 35 6A 79 90 90 06 52 A7 43 2A FB 14 99 C7 CE
0110 | 09 24 6F 6B 29 00 64 25 DF 29 26 46 5B 04 F1 7C
0120 | 00 77 B6 A3 36 A5 0E 46 B6 75 AD 56 07 F0 58 18
0130 | F8 4E AD EC 1F 48 47 BF 31 10 27 E7 42 F8 B1 E1
0140 | 83 C0 18 10 C4 CE 96 4F 2A 0F 36 E2 57 84 9C 14
0150 | 4C 9B 0B 93 B4 A7 A9 E5 73 91 DB 0C CB 0D 75 7A
0160 | 2B 7A 77 25 7C 8F F5 55 53 D6 6B 6E 1D 45 E9 D8
0170 | CA 88 E5 A4 7B 16 32 2F F2 ED 5F 5A BE 09 9E 70
0180 | 06 B2 D2 9C 82 9D 74 6B 70 41 30 B1
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 | 185C0700513DC565 |
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 | 406709F612FADFBEC3F0289D0AA67EEF |
Value generated by client in Step 1 |
server_nonce | 40, 16 | E11DBC3BC97D91A26154F932AF019943 |
Value received from server in Step 2 |
encrypted_data | 56, 340 | FE50010014D185E575255986C29BE3A0 437D525BA22430CBA0CD755225945AD3 A1ACEFB536518514F5086892E6E3FA84 D1CBB644BC8F7BEBCDE74E31BA8A073F 47623EBB6E7D94B3A676A4C1AFD4689C 52D05F73D21C33F64FE6AEABD04273D9 117CD064E467E1F8E6C887BCAE4679E0 399AD35DB1302A80629618F8C8485248 D89A4E3568B464FF7B608CBE24B51EEB 81B65D76224B62A1669EAA48A99C122E 5E8A778E13DD441DC52175160088A498 F186A2B99C736FE8C5C3E274D804C629 564A0F15DDABC5B449356A7990900652 A7432AFB1499C7CE09246F6B29006425 DF2926465B04F17C0077B6A336A50E46 B675AD5607F05818F84EADEC1F4847BF 311027E742F8B1E183C01810C4CE964F 2A0F36E257849C144C9B0B93B4A7A9E5 7391DB0CCB0D757A2B7A77257C8FF555 53D66B6E1D45E9D8CA88E5A47B16322F F2ED5F5ABE099E7006B2D29C829D746B 704130B1 |
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 = ACA2547BAA3B4B3E6AD9129ADEE796042FC4ACAAABA40DCE7A1196640595829E2BA85C5E68E5D2B7B713B28720CCD0E65DA3B80CD8A9282BDE895755B924F4CBBCED119DEE057D3066D7095C25771A53D9AD6EC3464EE0E7FE1A4D9851F17B6CC7D6E636E0BDEA7D66153CF37005835A528E65673C1F5ADAA27465964BA89AA6FD045108B25B1DC9AB2D979864858C9EACBFA4A399CDBF2154D2CC6743C5CAA40683343D80A36C7F1289DC5AC5EE585DEA1E1CD296444EA6CD8F6C3564B2D355B310A3C02608EEA5EC36D38E941BF811489AB7A24C069E44FF54714CB4A45EEE2F310FDDC0A1B08BD3DFF8801E27C8508EFD7AD51EF3C13EF1D9A02EE4601741
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 00 BE 91 51 3D C5 65
0010 | 74 00 00 00 34 F7 CB 3B 40 67 09 F6 12 FA DF BE
0020 | C3 F0 28 9D 0A A6 7E EF E1 1D BC 3B C9 7D 91 A2
0030 | 61 54 F9 32 AF 01 99 43 11 42 87 13 52 16 5E 59
0040 | E1 12 40 36 B4 8B 97 D3
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 | 0100BE91513DC565 |
Message ID generated as specified here » (unixtime() << 32) + (N*4) |
message_length | 16, 4 | 74000000 (116 in decimal) |
Message body length |
%(dh_gen_ok) | 20, 4 | 34f7cb3b |
dh_gen_ok constructor number from TL schema |
nonce | 24, 16 | 406709F612FADFBEC3F0289D0AA67EEF |
Value generated by client in Step 1 |
server_nonce | 40, 16 | E11DBC3BC97D91A26154F932AF019943 |
Value received from server in Step 2 |
new_nonce_hash1 | 56, 16 | 1142871352165E59E1124036B48B97D3 |
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. |