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 54 BC 00 00 FF 9A 9E 64
0010 | 14 00 00 00 F1 8E 7E BE DA 60 3B 0B 6C 74 D6 0E
0020 | C9 4A 04 D8 3A F2 02 7D
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 | 54BC0000FF9A9E64 |
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 | DA603B0B6C74D60EC94A04D83AF2027D |
Random number |
Received payload (excluding transport headers/trailers):
0000 | 00 00 00 00 00 00 00 00 01 64 63 C2 FF 9A 9E 64
0010 | 50 00 00 00 63 24 16 05 DA 60 3B 0B 6C 74 D6 0E
0020 | C9 4A 04 D8 3A F2 02 7D 8C 0C 71 9D 73 8B 75 78
0030 | 66 BA 31 F7 EF 43 97 39 08 1D 03 06 D7 8C 29 2A
0040 | 69 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 | 016463C2FF9A9E64 |
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 | DA603B0B6C74D60EC94A04D83AF2027D |
Value generated by client in Step 1 |
server_nonce | 40, 16 | 8C0C719D738B757866BA31F7EF439739 |
Server-generated random number |
pq | 56, 12 | 081D0306D78C292A69000000 TL byte deserialization => bigendian conversion to decimal => 2090522174869285481 |
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 = 2090522174869285481
Decompose into 2 prime cofactors p < q
: 2090522174869285481 = 1112973847 * 1878321023
p = 1112973847
q = 1878321023
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 1D 03 06 D7 8C 29 2A 69 00 00 00
0010 | 04 42 56 A2 17 00 00 00 04 6F F4 E7 7F 00 00 00
0020 | DA 60 3B 0B 6C 74 D6 0E C9 4A 04 D8 3A F2 02 7D
0030 | 8C 0C 71 9D 73 8B 75 78 66 BA 31 F7 EF 43 97 39
0040 | 0E 63 58 A8 84 41 7C 48 A8 81 CD B2 44 E1 CE 7D
0050 | 3F F7 C4 E4 4E 38 10 39 EF DC E2 57 66 F4 8C E4
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 | 081D0306D78C292A69000000 TL byte deserialization => bigendian conversion to decimal => 2090522174869285481 |
Single-byte prefix denoting length, 8-byte string, and three bytes of padding |
p | 16, 8 | 044256A217000000 TL byte deserialization => bigendian conversion to decimal => 1112973847 |
First prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding |
q | 24, 8 | 046FF4E77F000000 TL byte deserialization => bigendian conversion to decimal => 1878321023 |
Second prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding |
nonce | 32, 16 | DA603B0B6C74D60EC94A04D83AF2027D |
Value generated by client in Step 1 |
server_nonce | 48, 16 | 8C0C719D738B757866BA31F7EF439739 |
Value received from server in Step 2 |
new_nonce | 64, 32 | 0E6358A884417C48A881CDB244E1CE7D 3FF7C4E44E381039EFDCE25766F48CE4 |
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 = 955FF5A9081D0306D78C292A69000000044256A217000000046FF4E77F000000DA603B0B6C74D60EC94A04D83AF2027D8C0C719D738B757866BA31F7EF4397390E6358A884417C48A881CDB244E1CE7D3FF7C4E44E381039EFDCE25766F48CE402000000
random_padding_bytes = 6A5F16CE16C2F010CF1F5B1305F4340A22E68A8BC48EC863A7F3FB907CBA6FFDE7C240684F1767F3ABECA72A65B6B737894D25CF280679407F569BD4F5A52BCEB645852B499E9A467DFFD015FC2AA75DE1AB51568B018CEE65999DD3
And this is the output:
encrypted_data = 978CD0DA71C89E58D5DD3A369FD23C91CDF29AE8DEF7D7FADC5303F2D7D0BF676E6408C20F9888167525245E891B2884D4894406FD34D0A3739BB89D8BEFC5982F4CE7D899CAD65156931C8048627A86C3549183D914CFFBCB3B39E2B719B1F243CEFBFEEB8E5EBCD0C343772500D27BA8CEB80A46FA4EEBD88435FDF979DF40938AC43C6947D55F7C3130122D5D90BAA23C03CDBD5EEDDF9D1F0D46054856E3A3F4A86E9BE4FF61E80FA5606A9A0D1F797DE334D6DE845B71C48544A5AC2ECEFC92F0194789C66085F6DBC1D81E6674A8CDAC6D1911BAEAE1279133C162A4091E04B85732AEBEC304C17DCD5A8637413EC2CAE8B00A06A2121179D4DBAACBB7
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 9C A0 09 00 FF 9A 9E 64
0010 | 40 01 00 00 BE E4 12 D7 DA 60 3B 0B 6C 74 D6 0E
0020 | C9 4A 04 D8 3A F2 02 7D 8C 0C 71 9D 73 8B 75 78
0030 | 66 BA 31 F7 EF 43 97 39 04 42 56 A2 17 00 00 00
0040 | 04 6F F4 E7 7F 00 00 00 85 FD 64 DE 85 1D 9D D0
0050 | FE 00 01 00 97 8C D0 DA 71 C8 9E 58 D5 DD 3A 36
0060 | 9F D2 3C 91 CD F2 9A E8 DE F7 D7 FA DC 53 03 F2
0070 | D7 D0 BF 67 6E 64 08 C2 0F 98 88 16 75 25 24 5E
0080 | 89 1B 28 84 D4 89 44 06 FD 34 D0 A3 73 9B B8 9D
0090 | 8B EF C5 98 2F 4C E7 D8 99 CA D6 51 56 93 1C 80
00A0 | 48 62 7A 86 C3 54 91 83 D9 14 CF FB CB 3B 39 E2
00B0 | B7 19 B1 F2 43 CE FB FE EB 8E 5E BC D0 C3 43 77
00C0 | 25 00 D2 7B A8 CE B8 0A 46 FA 4E EB D8 84 35 FD
00D0 | F9 79 DF 40 93 8A C4 3C 69 47 D5 5F 7C 31 30 12
00E0 | 2D 5D 90 BA A2 3C 03 CD BD 5E ED DF 9D 1F 0D 46
00F0 | 05 48 56 E3 A3 F4 A8 6E 9B E4 FF 61 E8 0F A5 60
0100 | 6A 9A 0D 1F 79 7D E3 34 D6 DE 84 5B 71 C4 85 44
0110 | A5 AC 2E CE FC 92 F0 19 47 89 C6 60 85 F6 DB C1
0120 | D8 1E 66 74 A8 CD AC 6D 19 11 BA EA E1 27 91 33
0130 | C1 62 A4 09 1E 04 B8 57 32 AE BE C3 04 C1 7D CD
0140 | 5A 86 37 41 3E C2 CA E8 B0 0A 06 A2 12 11 79 D4
0150 | DB AA CB B7
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 | 9CA00900FF9A9E64 |
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 | DA603B0B6C74D60EC94A04D83AF2027D |
Value generated by client in Step 1 |
server_nonce | 40, 16 | 8C0C719D738B757866BA31F7EF439739 |
Value received from server in Step 2 |
p | 56, 8 | 044256A217000000 TL byte deserialization => bigendian conversion to decimal => 1112973847 |
First prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding |
q | 64, 8 | 046FF4E77F000000 TL byte deserialization => bigendian conversion to decimal => 1878321023 |
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 | FE000100978CD0DA71C89E58D5DD3A36 9FD23C91CDF29AE8DEF7D7FADC5303F2 D7D0BF676E6408C20F9888167525245E 891B2884D4894406FD34D0A3739BB89D 8BEFC5982F4CE7D899CAD65156931C80 48627A86C3549183D914CFFBCB3B39E2 B719B1F243CEFBFEEB8E5EBCD0C34377 2500D27BA8CEB80A46FA4EEBD88435FD F979DF40938AC43C6947D55F7C313012 2D5D90BAA23C03CDBD5EEDDF9D1F0D46 054856E3A3F4A86E9BE4FF61E80FA560 6A9A0D1F797DE334D6DE845B71C48544 A5AC2ECEFC92F0194789C66085F6DBC1 D81E6674A8CDAC6D1911BAEAE1279133 C162A4091E04B85732AEBEC304C17DCD 5A8637413EC2CAE8B00A06A2121179D4 DBAACBB7 |
Value generated above |
Received payload (excluding transport headers/trailers):
0000 | 00 00 00 00 00 00 00 00 01 98 C2 50 00 9B 9E 64
0010 | 78 02 00 00 5C 07 E8 D0 DA 60 3B 0B 6C 74 D6 0E
0020 | C9 4A 04 D8 3A F2 02 7D 8C 0C 71 9D 73 8B 75 78
0030 | 66 BA 31 F7 EF 43 97 39 FE 50 02 00 A0 35 2C C0
0040 | 87 EA 1E 38 08 20 F7 C9 46 61 88 32 08 B6 F3 9D
0050 | 47 BA DA 5D C7 2B 94 D7 22 F6 F7 C4 19 4B D2 56
0060 | B0 75 4F BD 65 E2 C2 CA 64 28 AB 69 7A 3C D2 25
0070 | 5C 3C 28 96 7A 0B 83 3C 1B 51 C9 D5 73 F2 DE BC
0080 | B9 AE 8E BF 03 F6 C8 63 55 7D 44 02 7F 39 60 8B
0090 | 2C A0 2F C9 8F EF CD 0C 1F 31 54 95 E7 EC C8 B1
00A0 | 7A 33 47 D6 6C FD E0 35 3D E7 EB 42 1F E0 63 B0
00B0 | C2 E4 85 DC 3E F6 EB 7B AE 57 4B 21 DD DB F7 D2
00C0 | 73 BF D0 8B 0A 17 CF B9 34 0D D2 C9 C4 B6 FF F2
00D0 | 4E 02 DE 47 32 22 D0 86 9E D1 A2 2E C6 59 3F 3A
00E0 | 6E B6 55 07 2A CA B4 54 DC 17 33 A8 BA 64 A2 FA
00F0 | FC B9 67 9D 8F 1A 43 20 4C BB F3 59 60 5A FB A7
0100 | 7F 4F 4B 89 86 D8 A8 4B 35 76 83 38 09 78 BB 66
0110 | F7 15 8C 5A 89 ED 75 B1 07 99 8E 89 51 6D D9 33
0120 | DE DE 35 D2 FA 4F 53 DF 49 29 54 1B 45 26 FB 13
0130 | 49 38 1F 96 A8 57 EE FB 9D F2 65 84 FF 51 6F D0
0140 | 6B 23 67 96 0A 4E 38 6D 7D FA 06 7E 60 30 41 DB
0150 | 1A BD 27 48 28 BD 3D 5F B7 43 6D B2 B1 C2 5D 81
0160 | 05 F2 10 8A 48 AE 0B F4 19 65 24 E6 83 EC 10 CC
0170 | 3A B8 CD 58 35 8C 02 AC 41 D9 26 FF 1E CD 4A 5F
0180 | 19 36 98 6B C9 73 21 BD 4C 88 ED 7B 5F 09 4B 1E
0190 | 70 B7 2B 5E FC 1D 86 E9 82 43 05 19 52 35 F0 E0
01A0 | 66 F2 DF A0 BB D2 48 8C C8 8B B5 7A C7 89 59 59
01B0 | CB 1A FE BF B0 36 FB 92 00 E8 44 D2 60 31 A1 4A
01C0 | BB F5 18 B0 89 3A FA 4C 29 D7 B0 6C 69 0D 5A 7F
01D0 | D3 16 CC 92 08 17 D4 5E 7E FE BF EB B5 89 BA 99
01E0 | F4 10 40 93 29 6E 99 99 B0 9E A6 6A 72 67 9A DD
01F0 | BA CE C3 63 D1 50 E1 6D FB 8D 51 C4 6E 19 50 5D
0200 | C1 53 97 32 DD D3 CF F3 51 BD CE B2 8A D3 79 3C
0210 | 0D A3 08 D1 2A 31 3B D7 D2 66 BB BA 88 76 5E 20
0220 | F3 39 22 08 58 43 97 68 07 2F 26 C4 AB EC CE 48
0230 | A5 F8 99 C5 26 E5 26 6F 7A 4A 4E F2 F3 B0 8B 5F
0240 | 53 AB 6B 45 90 F9 E0 DF 8B 44 10 05 C8 0C E4 72
0250 | E2 68 31 F8 64 E0 A9 CE 06 C9 DF FE C4 E6 01 3A
0260 | 26 B8 23 A8 3B A4 64 3D 5F DD B6 DE EA F7 5D A3
0270 | 0C 87 AB FE 29 F4 71 DD 82 7B 39 9C 6E C5 9D 98
0280 | CE EE 1F D4 30 19 63 95 88 5F DB F9
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 | 0198C250009B9E64 |
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 | DA603B0B6C74D60EC94A04D83AF2027D |
Value generated by client in Step 1 |
server_nonce | 40, 16 | 8C0C719D738B757866BA31F7EF439739 |
Value received from server in Step 2 |
encrypted_answer | 56, 596 | FE500200A0352CC087EA1E380820F7C9 4661883208B6F39D47BADA5DC72B94D7 22F6F7C4194BD256B0754FBD65E2C2CA 6428AB697A3CD2255C3C28967A0B833C 1B51C9D573F2DEBCB9AE8EBF03F6C863 557D44027F39608B2CA02FC98FEFCD0C 1F315495E7ECC8B17A3347D66CFDE035 3DE7EB421FE063B0C2E485DC3EF6EB7B AE574B21DDDBF7D273BFD08B0A17CFB9 340DD2C9C4B6FFF24E02DE473222D086 9ED1A22EC6593F3A6EB655072ACAB454 DC1733A8BA64A2FAFCB9679D8F1A4320 4CBBF359605AFBA77F4F4B8986D8A84B 357683380978BB66F7158C5A89ED75B1 07998E89516DD933DEDE35D2FA4F53DF 4929541B4526FB1349381F96A857EEFB 9DF26584FF516FD06B2367960A4E386D 7DFA067E603041DB1ABD274828BD3D5F B7436DB2B1C25D8105F2108A48AE0BF4 196524E683EC10CC3AB8CD58358C02AC 41D926FF1ECD4A5F1936986BC97321BD 4C88ED7B5F094B1E70B72B5EFC1D86E9 824305195235F0E066F2DFA0BBD2488C C88BB57AC7895959CB1AFEBFB036FB92 00E844D26031A14ABBF518B0893AFA4C 29D7B06C690D5A7FD316CC920817D45E 7EFEBFEBB589BA99F4104093296E9999 B09EA66A72679ADDBACEC363D150E16D FB8D51C46E19505DC1539732DDD3CFF3 51BDCEB28AD3793C0DA308D12A313BD7 D266BBBA88765E20F339220858439768 072F26C4ABECCE48A5F899C526E5266F 7A4A4EF2F3B08B5F53AB6B4590F9E0DF 8B441005C80CE472E26831F864E0A9CE 06C9DFFEC4E6013A26B823A83BA4643D 5FDDB6DEEAF75DA30C87ABFE29F471DD 827B399C6EC59D98CEEE1FD430196395 885FDBF9 |
See below |
Decrypt encrypted_answer
using the reverse of the process specified in step 6:
encrypted_answer = A0352CC087EA1E380820F7C94661883208B6F39D47BADA5DC72B94D722F6F7C4194BD256B0754FBD65E2C2CA6428AB697A3CD2255C3C28967A0B833C1B51C9D573F2DEBCB9AE8EBF03F6C863557D44027F39608B2CA02FC98FEFCD0C1F315495E7ECC8B17A3347D66CFDE0353DE7EB421FE063B0C2E485DC3EF6EB7BAE574B21DDDBF7D273BFD08B0A17CFB9340DD2C9C4B6FFF24E02DE473222D0869ED1A22EC6593F3A6EB655072ACAB454DC1733A8BA64A2FAFCB9679D8F1A43204CBBF359605AFBA77F4F4B8986D8A84B357683380978BB66F7158C5A89ED75B107998E89516DD933DEDE35D2FA4F53DF4929541B4526FB1349381F96A857EEFB9DF26584FF516FD06B2367960A4E386D7DFA067E603041DB1ABD274828BD3D5FB7436DB2B1C25D8105F2108A48AE0BF4196524E683EC10CC3AB8CD58358C02AC41D926FF1ECD4A5F1936986BC97321BD4C88ED7B5F094B1E70B72B5EFC1D86E9824305195235F0E066F2DFA0BBD2488CC88BB57AC7895959CB1AFEBFB036FB9200E844D26031A14ABBF518B0893AFA4C29D7B06C690D5A7FD316CC920817D45E7EFEBFEBB589BA99F4104093296E9999B09EA66A72679ADDBACEC363D150E16DFB8D51C46E19505DC1539732DDD3CFF351BDCEB28AD3793C0DA308D12A313BD7D266BBBA88765E20F339220858439768072F26C4ABECCE48A5F899C526E5266F7A4A4EF2F3B08B5F53AB6B4590F9E0DF8B441005C80CE472E26831F864E0A9CE06C9DFFEC4E6013A26B823A83BA4643D5FDDB6DEEAF75DA30C87ABFE29F471DD827B399C6EC59D98CEEE1FD430196395885FDBF9
tmp_aes_key = FD36AB8054D1E2F02F5205DC00729025F859AB708409CE4F32E82FDA951B0D7A
tmp_aes_iv = 049A211296D24BE36D7FFA1E3C30904487A544973922E4930CD594630E6358A8
Yielding:
answer_with_hash = 46A914334DFF3DF06D9A1E5330BF60A105E40B07BA0D89B5DA603B0B6C74D60EC94A04D83AF2027D8C0C719D738B757866BA31F7EF43973903000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE00010035D6639175B1FF6E0AC40189370B3067AF8D52CEA7087E49E01707B5E6112CB33327267BD526CDCD1E971B0488E8C93510E86049B25F640170B02BDE609E83050E5FAB0654C03837E7832018152B11928E0F2E4C3327DBE2717E123CC5994EA0A6034CED7EAD34D99CA90D8940B2065897EBF617B9B1662E682053CDC75A31FD6D7B27B1B8FE868C8139752A4848A5493DFC71477009E0653D185051A7D6F6C3A59C2A89EC8B9BCDD87CB849893D709261D690E3843565DEB19B76B21FB8A0A28DE3BEA19869F1D73346909D17666F94778077C599761176248536A8BB944F4F73C366BF70A04D13326D227999E146C830A473FC9B1F3525263FE30B7D82C2B7009B9E644AD2ABF1F215707B
answer = BA0D89B5DA603B0B6C74D60EC94A04D83AF2027D8C0C719D738B757866BA31F7EF43973903000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE00010035D6639175B1FF6E0AC40189370B3067AF8D52CEA7087E49E01707B5E6112CB33327267BD526CDCD1E971B0488E8C93510E86049B25F640170B02BDE609E83050E5FAB0654C03837E7832018152B11928E0F2E4C3327DBE2717E123CC5994EA0A6034CED7EAD34D99CA90D8940B2065897EBF617B9B1662E682053CDC75A31FD6D7B27B1B8FE868C8139752A4848A5493DFC71477009E0653D185051A7D6F6C3A59C2A89EC8B9BCDD87CB849893D709261D690E3843565DEB19B76B21FB8A0A28DE3BEA19869F1D73346909D17666F94778077C599761176248536A8BB944F4F73C366BF70A04D13326D227999E146C830A473FC9B1F3525263FE30B7D82C2B7009B9E644AD2ABF1F215707B
Generated payload (excluding transport headers/trailers):
0000 | BA 0D 89 B5 DA 60 3B 0B 6C 74 D6 0E C9 4A 04 D8
0010 | 3A F2 02 7D 8C 0C 71 9D 73 8B 75 78 66 BA 31 F7
0020 | EF 43 97 39 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 | 35 D6 63 91 75 B1 FF 6E 0A C4 01 89 37 0B 30 67
0140 | AF 8D 52 CE A7 08 7E 49 E0 17 07 B5 E6 11 2C B3
0150 | 33 27 26 7B D5 26 CD CD 1E 97 1B 04 88 E8 C9 35
0160 | 10 E8 60 49 B2 5F 64 01 70 B0 2B DE 60 9E 83 05
0170 | 0E 5F AB 06 54 C0 38 37 E7 83 20 18 15 2B 11 92
0180 | 8E 0F 2E 4C 33 27 DB E2 71 7E 12 3C C5 99 4E A0
0190 | A6 03 4C ED 7E AD 34 D9 9C A9 0D 89 40 B2 06 58
01A0 | 97 EB F6 17 B9 B1 66 2E 68 20 53 CD C7 5A 31 FD
01B0 | 6D 7B 27 B1 B8 FE 86 8C 81 39 75 2A 48 48 A5 49
01C0 | 3D FC 71 47 70 09 E0 65 3D 18 50 51 A7 D6 F6 C3
01D0 | A5 9C 2A 89 EC 8B 9B CD D8 7C B8 49 89 3D 70 92
01E0 | 61 D6 90 E3 84 35 65 DE B1 9B 76 B2 1F B8 A0 A2
01F0 | 8D E3 BE A1 98 69 F1 D7 33 46 90 9D 17 66 6F 94
0200 | 77 80 77 C5 99 76 11 76 24 85 36 A8 BB 94 4F 4F
0210 | 73 C3 66 BF 70 A0 4D 13 32 6D 22 79 99 E1 46 C8
0220 | 30 A4 73 FC 9B 1F 35 25 26 3F E3 0B 7D 82 C2 B7
0230 | 00 9B 9E 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 | DA603B0B6C74D60EC94A04D83AF2027D |
Value generated by client in Step 1 |
server_nonce | 20, 16 | 8C0C719D738B757866BA31F7EF439739 |
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 | FE00010035D6639175B1FF6E0AC40189 370B3067AF8D52CEA7087E49E01707B5 E6112CB33327267BD526CDCD1E971B04 88E8C93510E86049B25F640170B02BDE 609E83050E5FAB0654C03837E7832018 152B11928E0F2E4C3327DBE2717E123C C5994EA0A6034CED7EAD34D99CA90D89 40B2065897EBF617B9B1662E682053CD C75A31FD6D7B27B1B8FE868C8139752A 4848A5493DFC71477009E0653D185051 A7D6F6C3A59C2A89EC8B9BCDD87CB849 893D709261D690E3843565DEB19B76B2 1FB8A0A28DE3BEA19869F1D73346909D 17666F94778077C599761176248536A8 BB944F4F73C366BF70A04D13326D2279 99E146C830A473FC9B1F3525263FE30B 7D82C2B7 |
g_a diffie-hellman parameter |
server_time | 560, 4 | 009B9E64 (1688115968 in decimal) |
Server time |
First, generate a secure random 2048-bit number b:
b = F7C5CD46D4A88DED59C1B412D39FEC78BD86A6DC2BF2C5C5D8AF305204158F14B3244D42FFCF2363DC0D25DC6C48A16A3A0E63813D9E87442CA3C2CF84DF848C540531FCDBAD8290A6B25E021EB9AAEEB702F6FB31DC39C48EF615BB0CBBEDE1958D8BF5DCC205CBED3A9DFCD597115163A131DFD4939E68EB2C6F097A5632A3773D5201783A3B6CDE805794F5CBEEFD9FCB8DEAEAD1C5BCADD6366C8A907FABE99A026E59E8521085CE6130123E80B72DFD5EF3D2C0BC880F52DEEF7404638D8053D464036BF7057A77BE75EDA78D3C82221BB131FE6ECB8C43F77DF1D04935F978BA40F3F59385D6D6C2E7782BFFB040AB60F28459EB68A42A904B55E8088C
Then compute g_b = pow(g, b) mod dh_prime
g_b = 2545CE89DAD14BDF0F1E2E34F366124474E221B5C2019CF5240612B81798311E9ED33201DE78EA34B59DC0151E4CF820DEEC3850E1B08114B7599A1C99F28A85234ABCF8DC8BE8AB0CD1019EC56AB7BB2E05F07B7656338BE254ABB2F45AD42A86848E602B04A6B9CC9262780D4F87505A8B17191F53E72BDB00AB290B76810EB15C873183D72EC3D2CB411C3F4BDC7944E1CABF5571B152F7FC3CA1DA470977329DC49854BA62A85AE7645FECBD8183B5A4AAD06DFC56D4BA6106F81A45BEF32A9E4F56A213FB2A027B3ACDFDDDE6A6D57E68352C82F7C0D2108FC010725929CB7C88EE737F7B498D86134C7C7F2626F0357067A07813C0D3F2C86876CC1FF1
Generated payload (excluding transport headers/trailers):
0000 | 54 B6 43 66 DA 60 3B 0B 6C 74 D6 0E C9 4A 04 D8
0010 | 3A F2 02 7D 8C 0C 71 9D 73 8B 75 78 66 BA 31 F7
0020 | EF 43 97 39 00 00 00 00 00 00 00 00 FE 00 01 00
0030 | 25 45 CE 89 DA D1 4B DF 0F 1E 2E 34 F3 66 12 44
0040 | 74 E2 21 B5 C2 01 9C F5 24 06 12 B8 17 98 31 1E
0050 | 9E D3 32 01 DE 78 EA 34 B5 9D C0 15 1E 4C F8 20
0060 | DE EC 38 50 E1 B0 81 14 B7 59 9A 1C 99 F2 8A 85
0070 | 23 4A BC F8 DC 8B E8 AB 0C D1 01 9E C5 6A B7 BB
0080 | 2E 05 F0 7B 76 56 33 8B E2 54 AB B2 F4 5A D4 2A
0090 | 86 84 8E 60 2B 04 A6 B9 CC 92 62 78 0D 4F 87 50
00A0 | 5A 8B 17 19 1F 53 E7 2B DB 00 AB 29 0B 76 81 0E
00B0 | B1 5C 87 31 83 D7 2E C3 D2 CB 41 1C 3F 4B DC 79
00C0 | 44 E1 CA BF 55 71 B1 52 F7 FC 3C A1 DA 47 09 77
00D0 | 32 9D C4 98 54 BA 62 A8 5A E7 64 5F EC BD 81 83
00E0 | B5 A4 AA D0 6D FC 56 D4 BA 61 06 F8 1A 45 BE F3
00F0 | 2A 9E 4F 56 A2 13 FB 2A 02 7B 3A CD FD DD E6 A6
0100 | D5 7E 68 35 2C 82 F7 C0 D2 10 8F C0 10 72 59 29
0110 | CB 7C 88 EE 73 7F 7B 49 8D 86 13 4C 7C 7F 26 26
0120 | F0 35 70 67 A0 78 13 C0 D3 F2 C8 68 76 CC 1F F1
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 | DA603B0B6C74D60EC94A04D83AF2027D |
Value generated by client in Step 1 |
server_nonce | 20, 16 | 8C0C719D738B757866BA31F7EF439739 |
Value received from server in Step 2 |
g_b | 36, 260 | FE0001002545CE89DAD14BDF0F1E2E34 F366124474E221B5C2019CF5240612B8 1798311E9ED33201DE78EA34B59DC015 1E4CF820DEEC3850E1B08114B7599A1C 99F28A85234ABCF8DC8BE8AB0CD1019E C56AB7BB2E05F07B7656338BE254ABB2 F45AD42A86848E602B04A6B9CC926278 0D4F87505A8B17191F53E72BDB00AB29 0B76810EB15C873183D72EC3D2CB411C 3F4BDC7944E1CABF5571B152F7FC3CA1 DA470977329DC49854BA62A85AE7645F ECBD8183B5A4AAD06DFC56D4BA6106F8 1A45BEF32A9E4F56A213FB2A027B3ACD FDDDE6A6D57E68352C82F7C0D2108FC0 10725929CB7C88EE737F7B498D86134C 7C7F2626F0357067A07813C0D3F2C868 76CC1FF1 |
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 = 54B64366DA603B0B6C74D60EC94A04D83AF2027D8C0C719D738B757866BA31F7EF4397390000000000000000FE0001002545CE89DAD14BDF0F1E2E34F366124474E221B5C2019CF5240612B81798311E9ED33201DE78EA34B59DC0151E4CF820DEEC3850E1B08114B7599A1C99F28A85234ABCF8DC8BE8AB0CD1019EC56AB7BB2E05F07B7656338BE254ABB2F45AD42A86848E602B04A6B9CC9262780D4F87505A8B17191F53E72BDB00AB290B76810EB15C873183D72EC3D2CB411C3F4BDC7944E1CABF5571B152F7FC3CA1DA470977329DC49854BA62A85AE7645FECBD8183B5A4AAD06DFC56D4BA6106F81A45BEF32A9E4F56A213FB2A027B3ACDFDDDE6A6D57E68352C82F7C0D2108FC010725929CB7C88EE737F7B498D86134C7C7F2626F0357067A07813C0D3F2C86876CC1FF1
padding = BD8A6AC82FFB68885A48E0ED
tmp_aes_key = FD36AB8054D1E2F02F5205DC00729025F859AB708409CE4F32E82FDA951B0D7A
tmp_aes_iv = 049A211296D24BE36D7FFA1E3C30904487A544973922E4930CD594630E6358A8
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 = E3B5716AC2E86342AD2E8C7B75FD17C713CE5C8559659F8301258D63D9101D1DB99EA9C1909315495C8776FD7885CA40AB860F38C8BD946F90CCEC63F3ED2A5A8F06F4E45BFDD0CC4A626AF74C299623B64E8E384BB7A66C36483EA667CE513FB5C2B9C7C635206E824F6BFC45A259CE0692745EBF3FDE3DEE350903FC0E2FF821DAECDF333B23F77866A444E2AC3B1BC8CC2EA38D4C2C3FF375FF70CFAF76E35BE863D54969CF4A887C8D6223874017B4B509CF3DE096E288512FBEF295D4DE4CC3CA6EAEA779B07100D8CC9E2EF7A6B40575CCC5EC93E32E7F8E4FD7332737F3B179573B4BEC13ABD868CC06A725ECFFC29494FE6AFFD3CEF2DE94681D4A3F19DDE0CF9BB0F13974443EA04D6CE173E0655BAFC847B5D55393BE982E00903B557B61FB38F15A88CADA345BC8B7820BB1C051C0A8B13AE70A5479E87D6BCA8A7AA73C306AF0FACD6760C566014DE790
The length of the final string is 336 bytes.
Sent payload (excluding transport headers/trailers):
0000 | 00 00 00 00 00 00 00 00 E8 30 0F 00 00 9B 9E 64
0010 | 78 01 00 00 1F 5F 04 F5 DA 60 3B 0B 6C 74 D6 0E
0020 | C9 4A 04 D8 3A F2 02 7D 8C 0C 71 9D 73 8B 75 78
0030 | 66 BA 31 F7 EF 43 97 39 FE 50 01 00 E3 B5 71 6A
0040 | C2 E8 63 42 AD 2E 8C 7B 75 FD 17 C7 13 CE 5C 85
0050 | 59 65 9F 83 01 25 8D 63 D9 10 1D 1D B9 9E A9 C1
0060 | 90 93 15 49 5C 87 76 FD 78 85 CA 40 AB 86 0F 38
0070 | C8 BD 94 6F 90 CC EC 63 F3 ED 2A 5A 8F 06 F4 E4
0080 | 5B FD D0 CC 4A 62 6A F7 4C 29 96 23 B6 4E 8E 38
0090 | 4B B7 A6 6C 36 48 3E A6 67 CE 51 3F B5 C2 B9 C7
00A0 | C6 35 20 6E 82 4F 6B FC 45 A2 59 CE 06 92 74 5E
00B0 | BF 3F DE 3D EE 35 09 03 FC 0E 2F F8 21 DA EC DF
00C0 | 33 3B 23 F7 78 66 A4 44 E2 AC 3B 1B C8 CC 2E A3
00D0 | 8D 4C 2C 3F F3 75 FF 70 CF AF 76 E3 5B E8 63 D5
00E0 | 49 69 CF 4A 88 7C 8D 62 23 87 40 17 B4 B5 09 CF
00F0 | 3D E0 96 E2 88 51 2F BE F2 95 D4 DE 4C C3 CA 6E
0100 | AE A7 79 B0 71 00 D8 CC 9E 2E F7 A6 B4 05 75 CC
0110 | C5 EC 93 E3 2E 7F 8E 4F D7 33 27 37 F3 B1 79 57
0120 | 3B 4B EC 13 AB D8 68 CC 06 A7 25 EC FF C2 94 94
0130 | FE 6A FF D3 CE F2 DE 94 68 1D 4A 3F 19 DD E0 CF
0140 | 9B B0 F1 39 74 44 3E A0 4D 6C E1 73 E0 65 5B AF
0150 | C8 47 B5 D5 53 93 BE 98 2E 00 90 3B 55 7B 61 FB
0160 | 38 F1 5A 88 CA DA 34 5B C8 B7 82 0B B1 C0 51 C0
0170 | A8 B1 3A E7 0A 54 79 E8 7D 6B CA 8A 7A A7 3C 30
0180 | 6A F0 FA CD 67 60 C5 66 01 4D E7 90
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 | E8300F00009B9E64 |
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 | DA603B0B6C74D60EC94A04D83AF2027D |
Value generated by client in Step 1 |
server_nonce | 40, 16 | 8C0C719D738B757866BA31F7EF439739 |
Value received from server in Step 2 |
encrypted_data | 56, 340 | FE500100E3B5716AC2E86342AD2E8C7B 75FD17C713CE5C8559659F8301258D63 D9101D1DB99EA9C1909315495C8776FD 7885CA40AB860F38C8BD946F90CCEC63 F3ED2A5A8F06F4E45BFDD0CC4A626AF7 4C299623B64E8E384BB7A66C36483EA6 67CE513FB5C2B9C7C635206E824F6BFC 45A259CE0692745EBF3FDE3DEE350903 FC0E2FF821DAECDF333B23F77866A444 E2AC3B1BC8CC2EA38D4C2C3FF375FF70 CFAF76E35BE863D54969CF4A887C8D62 23874017B4B509CF3DE096E288512FBE F295D4DE4CC3CA6EAEA779B07100D8CC 9E2EF7A6B40575CCC5EC93E32E7F8E4F D7332737F3B179573B4BEC13ABD868CC 06A725ECFFC29494FE6AFFD3CEF2DE94 681D4A3F19DDE0CF9BB0F13974443EA0 4D6CE173E0655BAFC847B5D55393BE98 2E00903B557B61FB38F15A88CADA345B C8B7820BB1C051C0A8B13AE70A5479E8 7D6BCA8A7AA73C306AF0FACD6760C566 014DE790 |
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 = 48892B997A14A133B6D5B234A7F9B19DCE70CB192B9238372639DD6230B1BCC8D31BBBCCFA7F00BBEF38303BAE50FFF3DC814333123CE6E5980EF4493A74F38AD6B05B6737E296ADF4C97C69C95C5EC840BC22694F4CBFC14598B28F83B5CD79FE881F6AB9615226DF63078688371B3CDD2F6E97B35D17E6710E29469E1476B596C1DE136F05D585290776B306D6946B1C33374A459ECB0E9BFBC5A43D145A6B37C276E94C840EA0950B0B2523744CD538817DBA33CD6C84175AEA8561EBA117D2589EFB30A304B0F7AF29FF141E6B3F6F9FA5CEFF31DF1166937EA07D850427B6D779BBAB5B062526D435206EA25158EABC659DE3DC5E4ABF0D93B87B35E5E7
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 84 8C 9F 00 9B 9E 64
0010 | 34 00 00 00 34 F7 CB 3B DA 60 3B 0B 6C 74 D6 0E
0020 | C9 4A 04 D8 3A F2 02 7D 8C 0C 71 9D 73 8B 75 78
0030 | 66 BA 31 F7 EF 43 97 39 B0 91 C6 77 C6 99 6C 09
0040 | FF 59 F2 F9 AB 28 16 78
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 | 01848C9F009B9E64 |
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 | DA603B0B6C74D60EC94A04D83AF2027D |
Value generated by client in Step 1 |
server_nonce | 40, 16 | 8C0C719D738B757866BA31F7EF439739 |
Value received from server in Step 2 |
new_nonce_hash1 | 56, 16 | B091C677C6996C09FF59F2F9AB281678 |
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. |