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 84 8C 00 00 B1 AF 9C 64
0010 | 14 00 00 00 F1 8E 7E BE B0 BB 83 C2 68 49 38 B7
0020 | 6A C4 92 3A A5 45 C8 F0
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 | 848C0000B1AF9C64 |
Message ID generated as specified here » |
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 | B0BB83C2684938B76AC4923AA545C8F0 |
Random number |
Received payload (excluding transport headers/trailers):
0000 | 00 00 00 00 00 00 00 00 01 9C 04 77 B1 AF 9C 64
0010 | 50 00 00 00 63 24 16 05 B0 BB 83 C2 68 49 38 B7
0020 | 6A C4 92 3A A5 45 C8 F0 59 2E 37 C5 BF 99 B8 DD
0030 | AE 33 E6 EE 39 4B 47 42 08 2E 07 1E 8F 6E F5 45
0040 | 63 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<long> = 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 | 019C0477B1AF9C64 |
Message ID generated as specified here » |
message_length | 16, 4 | 50000000 (80 in decimal) |
Message body length |
%(resPQ) | 20, 4 | 63241605 |
resPQ constructor number from TL schema |
nonce | 24, 16 | B0BB83C2684938B76AC4923AA545C8F0 |
Value generated by client in Step 1 |
server_nonce | 40, 16 | 592E37C5BF99B8DDAE33E6EE394B4742 |
Server-generated random number |
pq | 56, 12 | 082E071E8F6EF54563000000 TL byte deserialization => bigendian conversion to decimal => 3316653251972384099 |
Single-byte prefix denoting length, an 8-byte string, and three bytes of padding |
%(Vector long) | 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 = 3316653251972384099
Decompose into 2 prime cofactors: 3316653251972384099 = 1704206131 * 1946157329
p = 1704206131
q = 1946157329
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 2E 07 1E 8F 6E F5 45 63 00 00 00
0010 | 04 65 94 1F 33 00 00 00 04 74 00 01 11 00 00 00
0020 | B0 BB 83 C2 68 49 38 B7 6A C4 92 3A A5 45 C8 F0
0030 | 59 2E 37 C5 BF 99 B8 DD AE 33 E6 EE 39 4B 47 42
0040 | FA 05 D4 1E 4C C4 D7 94 58 F8 26 B2 33 4B 26 67
0050 | 5C C6 64 8E 23 E7 62 6B 75 A1 B9 09 98 1A C9 55
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 | 082E071E8F6EF54563000000 TL byte deserialization => bigendian conversion to decimal => 3316653251972384099 |
Single-byte prefix denoting length, 8-byte string, and three bytes of padding |
p | 16, 8 | 0465941F33000000 TL byte deserialization => bigendian conversion to decimal => 1704206131 |
First prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding |
q | 24, 8 | 0474000111000000 TL byte deserialization => bigendian conversion to decimal => 1946157329 |
Second prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding |
nonce | 32, 16 | B0BB83C2684938B76AC4923AA545C8F0 |
Value generated by client in Step 1 |
server_nonce | 48, 16 | 592E37C5BF99B8DDAE33E6EE394B4742 |
Value received from server in Step 2 |
new_nonce | 64, 32 | FA05D41E4CC4D79458F826B2334B2667 5CC6648E23E7626B75A1B909981AC955 |
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 = 955FF5A9082E071E8F6EF545630000000465941F330000000474000111000000B0BB83C2684938B76AC4923AA545C8F0592E37C5BF99B8DDAE33E6EE394B4742FA05D41E4CC4D79458F826B2334B26675CC6648E23E7626B75A1B909981AC95502000000
random_padding_bytes = 2F9E22AC78033569C4B3F7035D5FFAFC3EBF28ECD70A65926B2E64D9118B8AB14EB6A100AA469AACCB3B9961D5E588C19A4E0C17F8C5CEDC003442FD0AECC129BFD6EEA4AD293FF753A0B194AB005F24E74FA78A98E10EAA2F16AD98
And this is the output:
encrypted_data = DF92287F32BBAE22049A7DF88007F9FBE0103D8DF533E4ED59C0A25B6D99FA0A9F2C83A8E45C28B2C7AB6D541B38C6254FDE09B773B38ECDB94B660D71415CDFD4B8BAD8B91DC60B837BF4205A781AB77885D8E0EF71E329D4B9356302C4D2BE16E34A6A939559BE65EC2F0EFE2CD561E9B058A13B5C8EEEB6907DF897AA7E48BE7F7DE1D13058476C8EDF60A79330D0A9178E3FA064EF069063BC37AAA3CC1B5E0E347290E5C1197A10C01986035E20C0B106074C857906131ACE5F75900037E16F66FC0D0D62383412CE7D7A9DCC45AFC3025AD9976268664F4162581175139A2F0910C69CDFBE9DA93CAC8C3CA67A4278E2CD2A67EF9D9FF5D7F866E24596
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 74 07 01 00 B1 AF 9C 64
0010 | 40 01 00 00 BE E4 12 D7 B0 BB 83 C2 68 49 38 B7
0020 | 6A C4 92 3A A5 45 C8 F0 59 2E 37 C5 BF 99 B8 DD
0030 | AE 33 E6 EE 39 4B 47 42 04 65 94 1F 33 00 00 00
0040 | 04 74 00 01 11 00 00 00 85 FD 64 DE 85 1D 9D D0
0050 | FE 00 01 00 DF 92 28 7F 32 BB AE 22 04 9A 7D F8
0060 | 80 07 F9 FB E0 10 3D 8D F5 33 E4 ED 59 C0 A2 5B
0070 | 6D 99 FA 0A 9F 2C 83 A8 E4 5C 28 B2 C7 AB 6D 54
0080 | 1B 38 C6 25 4F DE 09 B7 73 B3 8E CD B9 4B 66 0D
0090 | 71 41 5C DF D4 B8 BA D8 B9 1D C6 0B 83 7B F4 20
00A0 | 5A 78 1A B7 78 85 D8 E0 EF 71 E3 29 D4 B9 35 63
00B0 | 02 C4 D2 BE 16 E3 4A 6A 93 95 59 BE 65 EC 2F 0E
00C0 | FE 2C D5 61 E9 B0 58 A1 3B 5C 8E EE B6 90 7D F8
00D0 | 97 AA 7E 48 BE 7F 7D E1 D1 30 58 47 6C 8E DF 60
00E0 | A7 93 30 D0 A9 17 8E 3F A0 64 EF 06 90 63 BC 37
00F0 | AA A3 CC 1B 5E 0E 34 72 90 E5 C1 19 7A 10 C0 19
0100 | 86 03 5E 20 C0 B1 06 07 4C 85 79 06 13 1A CE 5F
0110 | 75 90 00 37 E1 6F 66 FC 0D 0D 62 38 34 12 CE 7D
0120 | 7A 9D CC 45 AF C3 02 5A D9 97 62 68 66 4F 41 62
0130 | 58 11 75 13 9A 2F 09 10 C6 9C DF BE 9D A9 3C AC
0140 | 8C 3C A6 7A 42 78 E2 CD 2A 67 EF 9D 9F F5 D7 F8
0150 | 66 E2 45 96
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 | 74070100B1AF9C64 |
Message ID generated as specified here » |
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 | B0BB83C2684938B76AC4923AA545C8F0 |
Value generated by client in Step 1 |
server_nonce | 40, 16 | 592E37C5BF99B8DDAE33E6EE394B4742 |
Value received from server in Step 2 |
p | 56, 8 | 0465941F33000000 TL byte deserialization => bigendian conversion to decimal => 1704206131 |
First prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding |
q | 64, 8 | 0474000111000000 TL byte deserialization => bigendian conversion to decimal => 1946157329 |
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 | FE000100DF92287F32BBAE22049A7DF8 8007F9FBE0103D8DF533E4ED59C0A25B 6D99FA0A9F2C83A8E45C28B2C7AB6D54 1B38C6254FDE09B773B38ECDB94B660D 71415CDFD4B8BAD8B91DC60B837BF420 5A781AB77885D8E0EF71E329D4B93563 02C4D2BE16E34A6A939559BE65EC2F0E FE2CD561E9B058A13B5C8EEEB6907DF8 97AA7E48BE7F7DE1D13058476C8EDF60 A79330D0A9178E3FA064EF069063BC37 AAA3CC1B5E0E347290E5C1197A10C019 86035E20C0B106074C857906131ACE5F 75900037E16F66FC0D0D62383412CE7D 7A9DCC45AFC3025AD9976268664F4162 581175139A2F0910C69CDFBE9DA93CAC 8C3CA67A4278E2CD2A67EF9D9FF5D7F8 66E24596 |
Value generated above |
Received payload (excluding transport headers/trailers):
0000 | 00 00 00 00 00 00 00 00 01 30 87 1E B2 AF 9C 64
0010 | 78 02 00 00 5C 07 E8 D0 B0 BB 83 C2 68 49 38 B7
0020 | 6A C4 92 3A A5 45 C8 F0 59 2E 37 C5 BF 99 B8 DD
0030 | AE 33 E6 EE 39 4B 47 42 FE 50 02 00 07 3F F0 CE
0040 | BA 1A 9E F8 80 F8 85 E4 D0 E9 C1 EF 93 F6 1A 18
0050 | BD 1B B7 8D 7A 36 D3 BF 1B 76 6E 28 13 91 02 C4
0060 | 85 BA 0D 47 D3 83 C8 E6 03 9D BB D3 78 BA A6 4D
0070 | C0 67 F1 60 43 96 DA A0 4D 72 1E 11 0D 23 08 F4
0080 | 95 A5 34 DE 44 30 06 DE 91 76 B4 B8 D9 27 24 84
0090 | 02 E1 6D 69 FC 8F 73 48 54 BA FB F8 06 00 4E 43
00A0 | 26 9C A8 C8 72 91 D4 F8 F4 36 84 3A 0C B3 FD 63
00B0 | 1F E4 D7 F4 1E 8F AC 2E 34 EF 84 0B DA C0 33 14
00C0 | 24 8A 4A F6 91 AD AB 7A 0C 6B DC CA 3D 85 FD 49
00D0 | E4 9A E6 E5 18 AF 6D DA 95 CF 03 4F 90 EB 1B 42
00E0 | 50 CD F6 03 F5 81 21 BC 3C 48 89 E0 C6 73 0C 89
00F0 | 77 3A 8D 77 C9 FC 7A F3 05 C9 F9 3B D8 35 10 FB
0100 | F1 B9 8E D7 08 49 61 5A D2 C9 49 7F 9C 8A 94 4C
0110 | B1 D3 A5 1A D1 01 44 B7 77 7A 4A 5E D9 59 FF E0
0120 | 3B 87 3D 4C F0 10 B3 61 C6 2F 7B 42 3E EC 02 CA
0130 | CE 0D 28 0A 6E 34 1E A5 BD AE 28 EF BA 69 D0 50
0140 | 58 10 56 35 6B 7B 6F 66 D9 A9 51 44 16 57 88 42
0150 | 24 0B ED 86 33 38 1F 0C 4A B0 06 C5 4B 60 29 E5
0160 | 8E AF A3 6F 87 2E E7 C9 5B 5D F5 91 C7 C2 68 6A
0170 | 3E 61 48 9F FB 06 F9 10 AC 03 C5 F4 56 B9 A3 C3
0180 | 4A 5C CA CE 67 6E 87 5C F3 E7 67 91 C4 AD 88 C3
0190 | 1F 9D 6F 43 EF 4E 9E F4 8E 0D BC 30 1E F2 9D 2E
01A0 | B3 80 30 70 5E 1A 0F 25 F2 00 7D 54 12 96 66 38
01B0 | DC 51 14 37 1A 63 08 2C 81 46 2C 3B 70 0E A5 35
01C0 | 6E 28 92 3F 50 87 AF 05 1C FD 81 59 B6 4B 2A DC
01D0 | 80 4E 66 CB 70 F6 AD 25 17 21 C6 B8 CA 2F 21 68
01E0 | 73 14 32 C9 67 BC 8B AE AD 02 96 40 E8 0C 2D C2
01F0 | 7A E0 3C FC 5F C1 17 39 65 F9 CD F8 C2 93 1B 6E
0200 | C5 D4 63 51 D7 E7 9D 33 AF BE 6C 58 66 3F 3E AD
0210 | A5 B2 A4 9D F6 CD E1 C9 90 78 61 08 11 65 11 DD
0220 | 9F C6 73 E0 55 9D 84 A5 51 36 C0 01 83 0F E6 2C
0230 | 49 5C 90 39 8E 96 05 49 4E 24 10 7C 02 67 BD A1
0240 | 29 79 7B 7B 1A CF 86 1C 04 F0 7D 6B BA 8B 11 1F
0250 | 88 86 11 E5 63 1E FF 97 16 C4 06 A7 AE 8B E2 DD
0260 | E1 D8 73 FB 57 1C 82 08 8A BD 18 FE 05 1F 6E 4A
0270 | EE 9B 90 94 C6 3F AC 38 CA 68 B4 EA 46 F1 2C D7
0280 | 09 DF DA C9 44 ED 46 AF 79 2F DB A2
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 | 0130871EB2AF9C64 |
Message ID generated as specified here » |
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 | B0BB83C2684938B76AC4923AA545C8F0 |
Value generated by client in Step 1 |
server_nonce | 40, 16 | 592E37C5BF99B8DDAE33E6EE394B4742 |
Value received from server in Step 2 |
encrypted_answer | 56, 596 | FE500200073FF0CEBA1A9EF880F885E4 D0E9C1EF93F61A18BD1BB78D7A36D3BF 1B766E28139102C485BA0D47D383C8E6 039DBBD378BAA64DC067F1604396DAA0 4D721E110D2308F495A534DE443006DE 9176B4B8D927248402E16D69FC8F7348 54BAFBF806004E43269CA8C87291D4F8 F436843A0CB3FD631FE4D7F41E8FAC2E 34EF840BDAC03314248A4AF691ADAB7A 0C6BDCCA3D85FD49E49AE6E518AF6DDA 95CF034F90EB1B4250CDF603F58121BC 3C4889E0C6730C89773A8D77C9FC7AF3 05C9F93BD83510FBF1B98ED70849615A D2C9497F9C8A944CB1D3A51AD10144B7 777A4A5ED959FFE03B873D4CF010B361 C62F7B423EEC02CACE0D280A6E341EA5 BDAE28EFBA69D050581056356B7B6F66 D9A9514416578842240BED8633381F0C 4AB006C54B6029E58EAFA36F872EE7C9 5B5DF591C7C2686A3E61489FFB06F910 AC03C5F456B9A3C34A5CCACE676E875C F3E76791C4AD88C31F9D6F43EF4E9EF4 8E0DBC301EF29D2EB38030705E1A0F25 F2007D5412966638DC5114371A63082C 81462C3B700EA5356E28923F5087AF05 1CFD8159B64B2ADC804E66CB70F6AD25 1721C6B8CA2F2168731432C967BC8BAE AD029640E80C2DC27AE03CFC5FC11739 65F9CDF8C2931B6EC5D46351D7E79D33 AFBE6C58663F3EADA5B2A49DF6CDE1C9 90786108116511DD9FC673E0559D84A5 5136C001830FE62C495C90398E960549 4E24107C0267BDA129797B7B1ACF861C 04F07D6BBA8B111F888611E5631EFF97 16C406A7AE8BE2DDE1D873FB571C8208 8ABD18FE051F6E4AEE9B9094C63FAC38 CA68B4EA46F12CD709DFDAC944ED46AF 792FDBA2 |
See below |
Decrypt encrypted_answer
using the reverse of the process specified in step 6:
encrypted_answer = 073FF0CEBA1A9EF880F885E4D0E9C1EF93F61A18BD1BB78D7A36D3BF1B766E28139102C485BA0D47D383C8E6039DBBD378BAA64DC067F1604396DAA04D721E110D2308F495A534DE443006DE9176B4B8D927248402E16D69FC8F734854BAFBF806004E43269CA8C87291D4F8F436843A0CB3FD631FE4D7F41E8FAC2E34EF840BDAC03314248A4AF691ADAB7A0C6BDCCA3D85FD49E49AE6E518AF6DDA95CF034F90EB1B4250CDF603F58121BC3C4889E0C6730C89773A8D77C9FC7AF305C9F93BD83510FBF1B98ED70849615AD2C9497F9C8A944CB1D3A51AD10144B7777A4A5ED959FFE03B873D4CF010B361C62F7B423EEC02CACE0D280A6E341EA5BDAE28EFBA69D050581056356B7B6F66D9A9514416578842240BED8633381F0C4AB006C54B6029E58EAFA36F872EE7C95B5DF591C7C2686A3E61489FFB06F910AC03C5F456B9A3C34A5CCACE676E875CF3E76791C4AD88C31F9D6F43EF4E9EF48E0DBC301EF29D2EB38030705E1A0F25F2007D5412966638DC5114371A63082C81462C3B700EA5356E28923F5087AF051CFD8159B64B2ADC804E66CB70F6AD251721C6B8CA2F2168731432C967BC8BAEAD029640E80C2DC27AE03CFC5FC1173965F9CDF8C2931B6EC5D46351D7E79D33AFBE6C58663F3EADA5B2A49DF6CDE1C990786108116511DD9FC673E0559D84A55136C001830FE62C495C90398E9605494E24107C0267BDA129797B7B1ACF861C04F07D6BBA8B111F888611E5631EFF9716C406A7AE8BE2DDE1D873FB571C82088ABD18FE051F6E4AEE9B9094C63FAC38CA68B4EA46F12CD709DFDAC944ED46AF792FDBA2
tmp_aes_key = 3826079A7BBD2CC9B9AE0E9D1BEEDA1A663CE630DC446D259DE256A1C953E8FA
tmp_aes_iv = 7A6748BA29AAC95EF75BD4588351617832FD34568EF1C4018F04F871FA05D41E
Yielding:
answer_with_hash = 3C9D681E6DB06E8B9F3D3CA74BC92D7E67D227D0BA0D89B5B0BB83C2684938B76AC4923AA545C8F0592E37C5BF99B8DDAE33E6EE394B474203000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE0001002FDAB5904B04F687AFF2E819845CF3BE57A147004CFFEF1C5DEA2574EB87C7A1462EAF356CBAD7B11BC1AAF4C64924555834B4E0FECB94118F21958824D8E0EB78FD33BA711806508E1EFA3BDB4520DBD4459CA6BAD3A8CD59874AE8295DBD0B6EC31C2A381406FCFBCA4031EDB433CDCF43551BEDAC54CBF8209542C22BC0D564FC8585945869AF496994DEE5E9B1E59C96020713B4B3AE90ED7DC68FD1DB5B81C2411E7C0E70893BC1A5804563D424AE95A453419AFFEB3B8A8AF7C9995041DDBB3117F105397B250C2FF1F565926000CC06E175B9A7078ABFA6383D0771822291D83BC82DCD16E991B4ACF7F9C17814F6715D3517F4E66401863418F16AABB2AF9C641C1005E08D6EEDB1
answer = BA0D89B5B0BB83C2684938B76AC4923AA545C8F0592E37C5BF99B8DDAE33E6EE394B474203000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE0001002FDAB5904B04F687AFF2E819845CF3BE57A147004CFFEF1C5DEA2574EB87C7A1462EAF356CBAD7B11BC1AAF4C64924555834B4E0FECB94118F21958824D8E0EB78FD33BA711806508E1EFA3BDB4520DBD4459CA6BAD3A8CD59874AE8295DBD0B6EC31C2A381406FCFBCA4031EDB433CDCF43551BEDAC54CBF8209542C22BC0D564FC8585945869AF496994DEE5E9B1E59C96020713B4B3AE90ED7DC68FD1DB5B81C2411E7C0E70893BC1A5804563D424AE95A453419AFFEB3B8A8AF7C9995041DDBB3117F105397B250C2FF1F565926000CC06E175B9A7078ABFA6383D0771822291D83BC82DCD16E991B4ACF7F9C17814F6715D3517F4E66401863418F16AABB2AF9C641C1005E08D6EEDB1
Generated payload (excluding transport headers/trailers):
0000 | BA 0D 89 B5 B0 BB 83 C2 68 49 38 B7 6A C4 92 3A
0010 | A5 45 C8 F0 59 2E 37 C5 BF 99 B8 DD AE 33 E6 EE
0020 | 39 4B 47 42 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 | 2F DA B5 90 4B 04 F6 87 AF F2 E8 19 84 5C F3 BE
0140 | 57 A1 47 00 4C FF EF 1C 5D EA 25 74 EB 87 C7 A1
0150 | 46 2E AF 35 6C BA D7 B1 1B C1 AA F4 C6 49 24 55
0160 | 58 34 B4 E0 FE CB 94 11 8F 21 95 88 24 D8 E0 EB
0170 | 78 FD 33 BA 71 18 06 50 8E 1E FA 3B DB 45 20 DB
0180 | D4 45 9C A6 BA D3 A8 CD 59 87 4A E8 29 5D BD 0B
0190 | 6E C3 1C 2A 38 14 06 FC FB CA 40 31 ED B4 33 CD
01A0 | CF 43 55 1B ED AC 54 CB F8 20 95 42 C2 2B C0 D5
01B0 | 64 FC 85 85 94 58 69 AF 49 69 94 DE E5 E9 B1 E5
01C0 | 9C 96 02 07 13 B4 B3 AE 90 ED 7D C6 8F D1 DB 5B
01D0 | 81 C2 41 1E 7C 0E 70 89 3B C1 A5 80 45 63 D4 24
01E0 | AE 95 A4 53 41 9A FF EB 3B 8A 8A F7 C9 99 50 41
01F0 | DD BB 31 17 F1 05 39 7B 25 0C 2F F1 F5 65 92 60
0200 | 00 CC 06 E1 75 B9 A7 07 8A BF A6 38 3D 07 71 82
0210 | 22 91 D8 3B C8 2D CD 16 E9 91 B4 AC F7 F9 C1 78
0220 | 14 F6 71 5D 35 17 F4 E6 64 01 86 34 18 F1 6A AB
0230 | B2 AF 9C 64
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 | B0BB83C2684938B76AC4923AA545C8F0 |
Value generated by client in Step 1 |
server_nonce | 20, 16 | 592E37C5BF99B8DDAE33E6EE394B4742 |
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 | FE0001002FDAB5904B04F687AFF2E819 845CF3BE57A147004CFFEF1C5DEA2574 EB87C7A1462EAF356CBAD7B11BC1AAF4 C64924555834B4E0FECB94118F219588 24D8E0EB78FD33BA711806508E1EFA3B DB4520DBD4459CA6BAD3A8CD59874AE8 295DBD0B6EC31C2A381406FCFBCA4031 EDB433CDCF43551BEDAC54CBF8209542 C22BC0D564FC8585945869AF496994DE E5E9B1E59C96020713B4B3AE90ED7DC6 8FD1DB5B81C2411E7C0E70893BC1A580 4563D424AE95A453419AFFEB3B8A8AF7 C9995041DDBB3117F105397B250C2FF1 F565926000CC06E175B9A7078ABFA638 3D0771822291D83BC82DCD16E991B4AC F7F9C17814F6715D3517F4E664018634 18F16AAB |
g_a diffie-hellman parameter |
server_time | 560, 4 | B2AF9C64 (1687990194 in decimal) |
Server time |
First, generate a secure random 2048-bit number b:
b = 29F2FD3102D844146B82E7C115C554A80961BC260BCA739BB670787AF0A72A512BA2E47AD58D0C478415251E4D0F7A737C2BF06A364C6E995ED596C88F4685F412B60205ECB9FA3ECA18A5B7B2DBEF3F26614806067E2F5831BB9CFF38278A25BB79A8F081A9E72E92CF74DE524DFBC07B6F5F77DF5F1EFF385E0B943282DF43A220AF62387F662982CCEDB59302EAD733438089FE871856F3C6E9221198094EA76E20868AEC4A7D7C809223CB28627DF3A05961B5148BE043CC64ECA1BFCC427F476E8A6769CDD7F5B774311BC166DB8FEC80E7C2BB9DF3B391D5D441B6BB35F0828BB9A22C9151FC63F1F3C04517C127A0BB98A2850867D7074E8D0C2FC576
Then compute g_b = pow(g, b) mod dh_prime
g_b = 69A19DF1CA7E2F7EB2D1C4FB9BA2856EF2AA19510669FF991757F7A3A10AA176A81CBD993DC7BD794C4E169056601BABFFE5C1A8DC6BCB705BB24BDB5E17280D26DAF0A9A801558CB87A11E30D6E8DD29CC039D014EA819CD0F8148CBA1BDB21331FFCB6063ED8FB66A6E90A02A80B68CDE53CB45D1266E8C19617FDD5AFD824001FD16BF666A1946B54B45C751CDD535B3718C6BE7A2EBAD4B35F5CA61D128B5B10ED4223C08D7294FCE18C8D30B5CFC8D73A80469150F7180F5F76F4FEAA0156EFA7665BB37F87B5F9EEAA654550555C05F91342608BB76F1E394EA6C51CE64589540E8729F9F5AE1B33108E8D35233ABFEE824AA2B940C5F04335CA59E0C4
Generated payload (excluding transport headers/trailers):
0000 | 54 B6 43 66 B0 BB 83 C2 68 49 38 B7 6A C4 92 3A
0010 | A5 45 C8 F0 59 2E 37 C5 BF 99 B8 DD AE 33 E6 EE
0020 | 39 4B 47 42 00 00 00 00 00 00 00 00 FE 00 01 00
0030 | 69 A1 9D F1 CA 7E 2F 7E B2 D1 C4 FB 9B A2 85 6E
0040 | F2 AA 19 51 06 69 FF 99 17 57 F7 A3 A1 0A A1 76
0050 | A8 1C BD 99 3D C7 BD 79 4C 4E 16 90 56 60 1B AB
0060 | FF E5 C1 A8 DC 6B CB 70 5B B2 4B DB 5E 17 28 0D
0070 | 26 DA F0 A9 A8 01 55 8C B8 7A 11 E3 0D 6E 8D D2
0080 | 9C C0 39 D0 14 EA 81 9C D0 F8 14 8C BA 1B DB 21
0090 | 33 1F FC B6 06 3E D8 FB 66 A6 E9 0A 02 A8 0B 68
00A0 | CD E5 3C B4 5D 12 66 E8 C1 96 17 FD D5 AF D8 24
00B0 | 00 1F D1 6B F6 66 A1 94 6B 54 B4 5C 75 1C DD 53
00C0 | 5B 37 18 C6 BE 7A 2E BA D4 B3 5F 5C A6 1D 12 8B
00D0 | 5B 10 ED 42 23 C0 8D 72 94 FC E1 8C 8D 30 B5 CF
00E0 | C8 D7 3A 80 46 91 50 F7 18 0F 5F 76 F4 FE AA 01
00F0 | 56 EF A7 66 5B B3 7F 87 B5 F9 EE AA 65 45 50 55
0100 | 5C 05 F9 13 42 60 8B B7 6F 1E 39 4E A6 C5 1C E6
0110 | 45 89 54 0E 87 29 F9 F5 AE 1B 33 10 8E 8D 35 23
0120 | 3A BF EE 82 4A A2 B9 40 C5 F0 43 35 CA 59 E0 C4
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 | B0BB83C2684938B76AC4923AA545C8F0 |
Value generated by client in Step 1 |
server_nonce | 20, 16 | 592E37C5BF99B8DDAE33E6EE394B4742 |
Value received from server in Step 2 |
g_b | 36, 260 | FE00010069A19DF1CA7E2F7EB2D1C4FB 9BA2856EF2AA19510669FF991757F7A3 A10AA176A81CBD993DC7BD794C4E1690 56601BABFFE5C1A8DC6BCB705BB24BDB 5E17280D26DAF0A9A801558CB87A11E3 0D6E8DD29CC039D014EA819CD0F8148C BA1BDB21331FFCB6063ED8FB66A6E90A 02A80B68CDE53CB45D1266E8C19617FD D5AFD824001FD16BF666A1946B54B45C 751CDD535B3718C6BE7A2EBAD4B35F5C A61D128B5B10ED4223C08D7294FCE18C 8D30B5CFC8D73A80469150F7180F5F76 F4FEAA0156EFA7665BB37F87B5F9EEAA 654550555C05F91342608BB76F1E394E A6C51CE64589540E8729F9F5AE1B3310 8E8D35233ABFEE824AA2B940C5F04335 CA59E0C4 |
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 = 54B64366B0BB83C2684938B76AC4923AA545C8F0592E37C5BF99B8DDAE33E6EE394B47420000000000000000FE00010069A19DF1CA7E2F7EB2D1C4FB9BA2856EF2AA19510669FF991757F7A3A10AA176A81CBD993DC7BD794C4E169056601BABFFE5C1A8DC6BCB705BB24BDB5E17280D26DAF0A9A801558CB87A11E30D6E8DD29CC039D014EA819CD0F8148CBA1BDB21331FFCB6063ED8FB66A6E90A02A80B68CDE53CB45D1266E8C19617FDD5AFD824001FD16BF666A1946B54B45C751CDD535B3718C6BE7A2EBAD4B35F5CA61D128B5B10ED4223C08D7294FCE18C8D30B5CFC8D73A80469150F7180F5F76F4FEAA0156EFA7665BB37F87B5F9EEAA654550555C05F91342608BB76F1E394EA6C51CE64589540E8729F9F5AE1B33108E8D35233ABFEE824AA2B940C5F04335CA59E0C4
padding = 4670CB59FFB7033A86C62AA9
tmp_aes_key = 3826079A7BBD2CC9B9AE0E9D1BEEDA1A663CE630DC446D259DE256A1C953E8FA
tmp_aes_iv = 7A6748BA29AAC95EF75BD4588351617832FD34568EF1C4018F04F871FA05D41E
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 = B157BF3596956D48DF20A9E10AB507971128D20530E7E3B6087FB1BA74DBE774DE8C5A1AC9D01F70868ED3681FC694F30CE358FC74B854DB48143196F4555CB22721DB87E83D14286CBFB54F4C18F51C9EB719C5924B4E546D6B073C68BA93198FB7A91FB4538E88F6DA2DCCF3734F7EA0112595DEDD6E69C38A5F70E1507069C26E847FB39EEF4BE96863A898FB521117DA5289CAD8F26F3D912D3314A3D4E54D81202AB36ED3625704730BCB495D3464433CB2CC51D1A355AD788C04084CFF69AEAA9AC6282785192BE1C7C1E4AC14E91358056E1A4BC2B0D5E9840F19F70257AD7975DAC3338C5B393835296E51D4845C07962A58F88EE2E2E67C46B1F44CBCA4624D6BD8CC3BA6B59B635CAFF706893E6368404F0475975F652D4C7C69C4E8FA88A9023BB89895823132B3408C0326A4FE9EE68ADEBC56768F0329C9DB79108F080FCEE326135F10E4F89E4C9EF5
The length of the final string is 336 bytes.
Sent payload (excluding transport headers/trailers):
0000 | 00 00 00 00 00 00 00 00 BC D6 09 00 B2 AF 9C 64
0010 | 78 01 00 00 1F 5F 04 F5 B0 BB 83 C2 68 49 38 B7
0020 | 6A C4 92 3A A5 45 C8 F0 59 2E 37 C5 BF 99 B8 DD
0030 | AE 33 E6 EE 39 4B 47 42 FE 50 01 00 B1 57 BF 35
0040 | 96 95 6D 48 DF 20 A9 E1 0A B5 07 97 11 28 D2 05
0050 | 30 E7 E3 B6 08 7F B1 BA 74 DB E7 74 DE 8C 5A 1A
0060 | C9 D0 1F 70 86 8E D3 68 1F C6 94 F3 0C E3 58 FC
0070 | 74 B8 54 DB 48 14 31 96 F4 55 5C B2 27 21 DB 87
0080 | E8 3D 14 28 6C BF B5 4F 4C 18 F5 1C 9E B7 19 C5
0090 | 92 4B 4E 54 6D 6B 07 3C 68 BA 93 19 8F B7 A9 1F
00A0 | B4 53 8E 88 F6 DA 2D CC F3 73 4F 7E A0 11 25 95
00B0 | DE DD 6E 69 C3 8A 5F 70 E1 50 70 69 C2 6E 84 7F
00C0 | B3 9E EF 4B E9 68 63 A8 98 FB 52 11 17 DA 52 89
00D0 | CA D8 F2 6F 3D 91 2D 33 14 A3 D4 E5 4D 81 20 2A
00E0 | B3 6E D3 62 57 04 73 0B CB 49 5D 34 64 43 3C B2
00F0 | CC 51 D1 A3 55 AD 78 8C 04 08 4C FF 69 AE AA 9A
0100 | C6 28 27 85 19 2B E1 C7 C1 E4 AC 14 E9 13 58 05
0110 | 6E 1A 4B C2 B0 D5 E9 84 0F 19 F7 02 57 AD 79 75
0120 | DA C3 33 8C 5B 39 38 35 29 6E 51 D4 84 5C 07 96
0130 | 2A 58 F8 8E E2 E2 E6 7C 46 B1 F4 4C BC A4 62 4D
0140 | 6B D8 CC 3B A6 B5 9B 63 5C AF F7 06 89 3E 63 68
0150 | 40 4F 04 75 97 5F 65 2D 4C 7C 69 C4 E8 FA 88 A9
0160 | 02 3B B8 98 95 82 31 32 B3 40 8C 03 26 A4 FE 9E
0170 | E6 8A DE BC 56 76 8F 03 29 C9 DB 79 10 8F 08 0F
0180 | CE E3 26 13 5F 10 E4 F8 9E 4C 9E F5
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 | BCD60900B2AF9C64 |
Message ID generated as specified here » |
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 | B0BB83C2684938B76AC4923AA545C8F0 |
Value generated by client in Step 1 |
server_nonce | 40, 16 | 592E37C5BF99B8DDAE33E6EE394B4742 |
Value received from server in Step 2 |
encrypted_data | 56, 340 | FE500100B157BF3596956D48DF20A9E1 0AB507971128D20530E7E3B6087FB1BA 74DBE774DE8C5A1AC9D01F70868ED368 1FC694F30CE358FC74B854DB48143196 F4555CB22721DB87E83D14286CBFB54F 4C18F51C9EB719C5924B4E546D6B073C 68BA93198FB7A91FB4538E88F6DA2DCC F3734F7EA0112595DEDD6E69C38A5F70 E1507069C26E847FB39EEF4BE96863A8 98FB521117DA5289CAD8F26F3D912D33 14A3D4E54D81202AB36ED3625704730B CB495D3464433CB2CC51D1A355AD788C 04084CFF69AEAA9AC6282785192BE1C7 C1E4AC14E91358056E1A4BC2B0D5E984 0F19F70257AD7975DAC3338C5B393835 296E51D4845C07962A58F88EE2E2E67C 46B1F44CBCA4624D6BD8CC3BA6B59B63 5CAFF706893E6368404F0475975F652D 4C7C69C4E8FA88A9023BB89895823132 B3408C0326A4FE9EE68ADEBC56768F03 29C9DB79108F080FCEE326135F10E4F8 9E4C9EF5 |
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 = 4B2FB207D87D159C14CFBC094533E4305721FD3F8CF1F4C2E218481DAD5BDE4BD687064C86A2F9B15DDF2EB43F6558C7EF91B99FADF614711AEDC6BBAE02F10B97EC40B81837695E58F11F2FAC48E949AF2DBC35E3A8476FF2C8C1CA85835634BEA918657C9801AD8876E8319C02ADF9209EAF5A3D429560D98816943C3019971B67372E146106CD27FB110A589DA8890F43348AF77143AFFCB08BEBEF89BD14BBFECC6AFE2B028C4BEC26ADC3D6786DABFF738CDAEBFE2D15806977DB496736716CD0B64938F1AEC6911FB56B70CC86BFB458048E970CD28E2F3844B7082493C1D46C0EA0AA798068C4160DA2C2D7562A6160255C6A1D7C3C47B7B8DD1C6D55
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 60 9B 67 B2 AF 9C 64
0010 | 34 00 00 00 34 F7 CB 3B B0 BB 83 C2 68 49 38 B7
0020 | 6A C4 92 3A A5 45 C8 F0 59 2E 37 C5 BF 99 B8 DD
0030 | AE 33 E6 EE 39 4B 47 42 6A F1 5D D5 EA 4A 58 6A
0040 | 27 E0 A1 DC 7E 26 D2 C4
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 | 01609B67B2AF9C64 |
Message ID generated as specified here » |
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 | B0BB83C2684938B76AC4923AA545C8F0 |
Value generated by client in Step 1 |
server_nonce | 40, 16 | 592E37C5BF99B8DDAE33E6EE394B4742 |
Value received from server in Step 2 |
new_nonce_hash1 | 56, 16 | 6AF15DD5EA4A586A27E0A1DC7E26D2C4 |
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. |