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 60 97 05 00 EB E5 77 67
0010 | 14 00 00 00 F1 8E 7E BE 79 F0 AF B5 02 52 E5 FC
0020 | 96 92 4B FC EC DA 4F 05
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 | 60970500EBE57767 |
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 | 79F0AFB50252E5FC96924BFCECDA4F05 |
Random number |
Received payload (excluding transport headers/trailers):
0000 | 00 00 00 00 00 00 00 00 01 28 FB D2 EB E5 77 67
0010 | 50 00 00 00 63 24 16 05 79 F0 AF B5 02 52 E5 FC
0020 | 96 92 4B FC EC DA 4F 05 80 17 75 A3 EF BF D2 70
0030 | 1A A2 8A D7 27 BE 46 46 08 13 0B 74 75 66 9F EB
0040 | 8B 00 00 00 15 C4 B5 1C 03 00 00 00 85 FD 64 DE
0050 | 85 1D 9D D0 A5 B7 F7 09 35 5F C3 0B 21 6B E8 6C
0060 | 02 2B B4 C3
Payload (de)serialization:
resPQ#05162463 nonce:int128 server_nonce:int128 pq:string server_public_key_fingerprints:Vector<strlong> = ResPQ;
Parameter | Offset, Length in bytes | Value | Description |
---|---|---|---|
auth_key_id | 0, 8 | 0000000000000000 |
0 since the message is in plain text |
message_id | 8, 8 | 0128FBD2EBE57767 |
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 | 79F0AFB50252E5FC96924BFCECDA4F05 |
Value generated by client in Step 1 |
server_nonce | 40, 16 | 801775A3EFBFD2701AA28AD727BE4646 |
Server-generated random number |
pq | 56, 12 | 08130B7475669FEB8B000000 TL byte deserialization => bigendian conversion to decimal => 1372318559046200203 |
Single-byte prefix denoting length, an 8-byte string, and three bytes of padding |
%(Vector strlong) | 68, 4 | 15c4b51c |
Vector t constructor number from TL schema |
count | 72, 4 | 03000000 |
Number of elements in server_public_key_fingerprints |
server_public_key_fingerprints[0] | 76, 8 | 85FD64DE851D9DD0 |
64 lower-order bits of SHA1(server_public_key) |
server_public_key_fingerprints[1] | 84, 8 | A5B7F709355FC30B |
64 lower-order bits of SHA1(server_public_key) |
server_public_key_fingerprints[2] | 92, 8 | 216BE86C022BB4C3 |
64 lower-order bits of SHA1(server_public_key) |
In our case, the client only has the following public keys, with the following fingerprints:
85FD64DE851D9DD0
Let's choose the only matching key, the one with fingerprint equal to 85FD64DE851D9DD0
.
pq = 1372318559046200203
Decompose into 2 prime cofactors p < q
: 1372318559046200203 = 1141464581 * 1202243663
p = 1141464581
q = 1202243663
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 13 0B 74 75 66 9F EB 8B 00 00 00
0010 | 04 44 09 5E 05 00 00 00 04 47 A8 C8 4F 00 00 00
0020 | 79 F0 AF B5 02 52 E5 FC 96 92 4B FC EC DA 4F 05
0030 | 80 17 75 A3 EF BF D2 70 1A A2 8A D7 27 BE 46 46
0040 | 26 4F 83 5B 0B 7B DF F9 C6 ED 6C F8 19 FD 6D F5
0050 | DC D1 7E 90 D6 7A DD 2C 2C 1E 37 75 C7 A6 A0 AC
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 | 08130B7475669FEB8B000000 TL byte deserialization => bigendian conversion to decimal => 1372318559046200203 |
Single-byte prefix denoting length, 8-byte string, and three bytes of padding |
p | 16, 8 | 0444095E05000000 TL byte deserialization => bigendian conversion to decimal => 1141464581 |
First prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding |
q | 24, 8 | 0447A8C84F000000 TL byte deserialization => bigendian conversion to decimal => 1202243663 |
Second prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding |
nonce | 32, 16 | 79F0AFB50252E5FC96924BFCECDA4F05 |
Value generated by client in Step 1 |
server_nonce | 48, 16 | 801775A3EFBFD2701AA28AD727BE4646 |
Value received from server in Step 2 |
new_nonce | 64, 32 | 264F835B0B7BDFF9C6ED6CF819FD6DF5 DCD17E90D67ADD2C2C1E3775C7A6A0AC |
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 = 955FF5A908130B7475669FEB8B0000000444095E050000000447A8C84F00000079F0AFB50252E5FC96924BFCECDA4F05801775A3EFBFD2701AA28AD727BE4646264F835B0B7BDFF9C6ED6CF819FD6DF5DCD17E90D67ADD2C2C1E3775C7A6A0AC02000000
random_padding_bytes = C1C3E221C1EAECF4788AC3FEA0DECFEFD0E81AE6C6A1AB2AB8729D0634E08A3A12A9D53E06134F87B74BBD9EC90793B091C7FBF4CDBCBE4536397902388D4F68EBAA138CCD068244DB026332B7FC17E5DFAC09E7A71FA5353E3EEBDC
And this is the output:
encrypted_data = 35D750FBDF8B804F609512959103977D8F3B90189B7B2DE9C14F53FF8B5910AB2371A1B8D855B5787B94BC67068CAE657367C68170C0DE7E3DBEA38980F15A4BE1C0A6F3B2C0FF279D68496585D2F58924EE2CCCB55746FABAAE2DC0CCBB9E168B79ABC0BC7E68BEE0130708E680938F7A2BFA633285DA63784C8EBEF6156755504F68006E66CDF346B13B8512ABE830706DD9265329EFDE99DFB0F72AA11119140C941537353423295C519F04A25CACEE3293E8CF2C799515175E96DD36F913BB4B1A19D92EAE3BC8883A333523AC18D4A5165A32FD67990497F1208EF643CA0093D01DCF2E537DCBCC22581630291B7217600B8725E657383D156905B2BF16
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 68 E5 08 00 EB E5 77 67
0010 | 40 01 00 00 BE E4 12 D7 79 F0 AF B5 02 52 E5 FC
0020 | 96 92 4B FC EC DA 4F 05 80 17 75 A3 EF BF D2 70
0030 | 1A A2 8A D7 27 BE 46 46 04 44 09 5E 05 00 00 00
0040 | 04 47 A8 C8 4F 00 00 00 85 FD 64 DE 85 1D 9D D0
0050 | FE 00 01 00 35 D7 50 FB DF 8B 80 4F 60 95 12 95
0060 | 91 03 97 7D 8F 3B 90 18 9B 7B 2D E9 C1 4F 53 FF
0070 | 8B 59 10 AB 23 71 A1 B8 D8 55 B5 78 7B 94 BC 67
0080 | 06 8C AE 65 73 67 C6 81 70 C0 DE 7E 3D BE A3 89
0090 | 80 F1 5A 4B E1 C0 A6 F3 B2 C0 FF 27 9D 68 49 65
00A0 | 85 D2 F5 89 24 EE 2C CC B5 57 46 FA BA AE 2D C0
00B0 | CC BB 9E 16 8B 79 AB C0 BC 7E 68 BE E0 13 07 08
00C0 | E6 80 93 8F 7A 2B FA 63 32 85 DA 63 78 4C 8E BE
00D0 | F6 15 67 55 50 4F 68 00 6E 66 CD F3 46 B1 3B 85
00E0 | 12 AB E8 30 70 6D D9 26 53 29 EF DE 99 DF B0 F7
00F0 | 2A A1 11 19 14 0C 94 15 37 35 34 23 29 5C 51 9F
0100 | 04 A2 5C AC EE 32 93 E8 CF 2C 79 95 15 17 5E 96
0110 | DD 36 F9 13 BB 4B 1A 19 D9 2E AE 3B C8 88 3A 33
0120 | 35 23 AC 18 D4 A5 16 5A 32 FD 67 99 04 97 F1 20
0130 | 8E F6 43 CA 00 93 D0 1D CF 2E 53 7D CB CC 22 58
0140 | 16 30 29 1B 72 17 60 0B 87 25 E6 57 38 3D 15 69
0150 | 05 B2 BF 16
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 | 68E50800EBE57767 |
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 | 79F0AFB50252E5FC96924BFCECDA4F05 |
Value generated by client in Step 1 |
server_nonce | 40, 16 | 801775A3EFBFD2701AA28AD727BE4646 |
Value received from server in Step 2 |
p | 56, 8 | 0444095E05000000 TL byte deserialization => bigendian conversion to decimal => 1141464581 |
First prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding |
q | 64, 8 | 0447A8C84F000000 TL byte deserialization => bigendian conversion to decimal => 1202243663 |
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 | FE00010035D750FBDF8B804F60951295 9103977D8F3B90189B7B2DE9C14F53FF 8B5910AB2371A1B8D855B5787B94BC67 068CAE657367C68170C0DE7E3DBEA389 80F15A4BE1C0A6F3B2C0FF279D684965 85D2F58924EE2CCCB55746FABAAE2DC0 CCBB9E168B79ABC0BC7E68BEE0130708 E680938F7A2BFA633285DA63784C8EBE F6156755504F68006E66CDF346B13B85 12ABE830706DD9265329EFDE99DFB0F7 2AA11119140C941537353423295C519F 04A25CACEE3293E8CF2C799515175E96 DD36F913BB4B1A19D92EAE3BC8883A33 3523AC18D4A5165A32FD67990497F120 8EF643CA0093D01DCF2E537DCBCC2258 1630291B7217600B8725E657383D1569 05B2BF16 |
Value generated above |
Received payload (excluding transport headers/trailers):
0000 | 00 00 00 00 00 00 00 00 01 AC 68 E8 EB E5 77 67
0010 | 78 02 00 00 5C 07 E8 D0 79 F0 AF B5 02 52 E5 FC
0020 | 96 92 4B FC EC DA 4F 05 80 17 75 A3 EF BF D2 70
0030 | 1A A2 8A D7 27 BE 46 46 FE 50 02 00 9A 46 DC E9
0040 | D5 4D E4 2C 5E 4F 0D 19 D7 76 C8 C1 F3 18 EB 1A
0050 | F8 83 65 00 B5 DA 1B 1A 80 D5 80 38 A5 54 FE AF
0060 | 62 7E 6D C4 E4 92 49 43 60 2D 8E 19 48 8A 6E 38
0070 | A0 B8 13 46 25 7E 4D B5 BE 6E 9E 00 FE 99 1F D6
0080 | C5 6D 61 8D 3D 0A 24 93 20 26 77 AC 7C F2 45 84
0090 | 6C 14 94 F6 0D 08 E6 1B 7F EA 8B B7 2D D8 BA 53
00A0 | F6 CB F7 8F 2B 38 77 57 FE 2E 7F 34 5A 36 8A BB
00B0 | EC 69 4E FD E0 66 DC 3D 23 75 CF 01 0D 1E 1B F4
00C0 | 35 17 24 B2 69 E6 8B 54 14 09 E0 76 49 FE EE 1D
00D0 | F6 DC 5B 3C 18 16 68 79 CC 67 87 67 82 D4 3E C9
00E0 | B7 9A F8 AC F6 78 68 F4 AB 7D E4 08 26 03 B6 70
00F0 | EC 62 2B 5D FB BB 9E 90 8F E0 24 45 93 A4 D2 24
0100 | 74 31 60 20 CE 0E 76 A5 C6 AD 02 1D 39 89 45 1E
0110 | 0B 3E 8E E4 8C 35 59 92 DB 90 30 0B 37 6B 29 6E
0120 | 18 BB 47 03 00 C7 DF 14 BF AE 05 A4 52 58 3E AD
0130 | 93 16 79 41 20 8B BB 5A C8 09 9F 04 94 AA 27 D6
0140 | C1 A5 B6 78 AD 12 B1 9F B7 D4 23 BB 4A 29 C0 EB
0150 | 03 16 9E C5 38 21 1D 82 FE B5 0F 20 96 52 D0 0D
0160 | 33 99 98 6B 3B 0C A0 9C EB 5E 2F CC B4 90 17 FE
0170 | E5 F5 49 30 D9 DE 37 11 72 B3 FF 10 80 D7 33 E5
0180 | DD 62 0B 42 DB B7 6A 3E 9C 25 B1 B8 9A B8 AA 35
0190 | C0 99 32 2C A3 90 E2 69 D8 81 8E A8 72 20 08 DE
01A0 | 53 77 05 B4 07 1D A7 DE F5 02 FC D5 A3 0D 20 26
01B0 | EA 8A 87 A0 F4 91 58 03 A8 27 1B 66 56 90 E9 6A
01C0 | AB DF C0 B4 79 53 8A E6 1B A7 01 ED FF 14 F7 21
01D0 | 23 70 95 8E D4 1E C8 E4 1E 42 7C 40 7F BB 03 60
01E0 | 56 5C 1A 6B DF 28 5B C5 12 0B 11 63 1B 75 80 3D
01F0 | FB F8 AA EB DC 47 41 8A 1F 06 17 47 00 5A BA 93
0200 | 14 EE 5E 26 1C 3E 50 4E AE 0A DA AC 83 2B 41 4B
0210 | F6 F7 00 29 82 CE 5B 5A E2 51 37 61 EE 29 FA 1C
0220 | BA 09 0B 9A 39 AA CE 29 48 A8 0E 14 4D B2 C6 22
0230 | 58 9D 79 FB 42 E3 DA E4 91 10 4E 8A 65 3D ED 76
0240 | 29 CD E0 8B 6C 41 E9 0E 55 B0 EB CD 4F 1F C5 0F
0250 | AD DF 4A 7A 9F 6D 71 1F 09 59 DF EF 04 A7 44 A6
0260 | AD FD 89 0B 2A B4 05 B9 AD 5F 8E 3F 38 92 81 08
0270 | F4 CD 0B A5 01 A4 92 FC 46 3B C7 BE 8C 50 6B 5F
0280 | 7D 24 CC 81 9A 95 92 91 66 B6 E8 14
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 | 01AC68E8EBE57767 |
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 | 79F0AFB50252E5FC96924BFCECDA4F05 |
Value generated by client in Step 1 |
server_nonce | 40, 16 | 801775A3EFBFD2701AA28AD727BE4646 |
Value received from server in Step 2 |
encrypted_answer | 56, 596 | FE5002009A46DCE9D54DE42C5E4F0D19 D776C8C1F318EB1AF8836500B5DA1B1A 80D58038A554FEAF627E6DC4E4924943 602D8E19488A6E38A0B81346257E4DB5 BE6E9E00FE991FD6C56D618D3D0A2493 202677AC7CF245846C1494F60D08E61B 7FEA8BB72DD8BA53F6CBF78F2B387757 FE2E7F345A368ABBEC694EFDE066DC3D 2375CF010D1E1BF4351724B269E68B54 1409E07649FEEE1DF6DC5B3C18166879 CC67876782D43EC9B79AF8ACF67868F4 AB7DE4082603B670EC622B5DFBBB9E90 8FE0244593A4D22474316020CE0E76A5 C6AD021D3989451E0B3E8EE48C355992 DB90300B376B296E18BB470300C7DF14 BFAE05A452583EAD93167941208BBB5A C8099F0494AA27D6C1A5B678AD12B19F B7D423BB4A29C0EB03169EC538211D82 FEB50F209652D00D3399986B3B0CA09C EB5E2FCCB49017FEE5F54930D9DE3711 72B3FF1080D733E5DD620B42DBB76A3E 9C25B1B89AB8AA35C099322CA390E269 D8818EA8722008DE537705B4071DA7DE F502FCD5A30D2026EA8A87A0F4915803 A8271B665690E96AABDFC0B479538AE6 1BA701EDFF14F7212370958ED41EC8E4 1E427C407FBB0360565C1A6BDF285BC5 120B11631B75803DFBF8AAEBDC47418A 1F061747005ABA9314EE5E261C3E504E AE0ADAAC832B414BF6F7002982CE5B5A E2513761EE29FA1CBA090B9A39AACE29 48A80E144DB2C622589D79FB42E3DAE4 91104E8A653DED7629CDE08B6C41E90E 55B0EBCD4F1FC50FADDF4A7A9F6D711F 0959DFEF04A744A6ADFD890B2AB405B9 AD5F8E3F38928108F4CD0BA501A492FC 463BC7BE8C506B5F7D24CC819A959291 66B6E814 |
See below |
Decrypt encrypted_answer
using the reverse of the process specified in step 6:
encrypted_answer = 9A46DCE9D54DE42C5E4F0D19D776C8C1F318EB1AF8836500B5DA1B1A80D58038A554FEAF627E6DC4E4924943602D8E19488A6E38A0B81346257E4DB5BE6E9E00FE991FD6C56D618D3D0A2493202677AC7CF245846C1494F60D08E61B7FEA8BB72DD8BA53F6CBF78F2B387757FE2E7F345A368ABBEC694EFDE066DC3D2375CF010D1E1BF4351724B269E68B541409E07649FEEE1DF6DC5B3C18166879CC67876782D43EC9B79AF8ACF67868F4AB7DE4082603B670EC622B5DFBBB9E908FE0244593A4D22474316020CE0E76A5C6AD021D3989451E0B3E8EE48C355992DB90300B376B296E18BB470300C7DF14BFAE05A452583EAD93167941208BBB5AC8099F0494AA27D6C1A5B678AD12B19FB7D423BB4A29C0EB03169EC538211D82FEB50F209652D00D3399986B3B0CA09CEB5E2FCCB49017FEE5F54930D9DE371172B3FF1080D733E5DD620B42DBB76A3E9C25B1B89AB8AA35C099322CA390E269D8818EA8722008DE537705B4071DA7DEF502FCD5A30D2026EA8A87A0F4915803A8271B665690E96AABDFC0B479538AE61BA701EDFF14F7212370958ED41EC8E41E427C407FBB0360565C1A6BDF285BC5120B11631B75803DFBF8AAEBDC47418A1F061747005ABA9314EE5E261C3E504EAE0ADAAC832B414BF6F7002982CE5B5AE2513761EE29FA1CBA090B9A39AACE2948A80E144DB2C622589D79FB42E3DAE491104E8A653DED7629CDE08B6C41E90E55B0EBCD4F1FC50FADDF4A7A9F6D711F0959DFEF04A744A6ADFD890B2AB405B9AD5F8E3F38928108F4CD0BA501A492FC463BC7BE8C506B5F7D24CC819A95929166B6E814
tmp_aes_key = E68CA5ABA101FFCA0ADDA66303A57AFFAA2712FB16A7B8DAFC72C25E8A73A368
tmp_aes_iv = 0A355D4431B9DDD91A51EFF3F7D340D64F0390C53F91DC53C331D43C264F835B
Yielding:
answer_with_hash = 4262AD6A332AC2A3050B5142711CE3B7BFD76FABBA0D89B579F0AFB50252E5FC96924BFCECDA4F05801775A3EFBFD2701AA28AD727BE464603000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE000100236F6D779877A357465CEC030AC5FDA6D6B377372BFA75574289988FD87D966A29B47E0C00BC788900304EA5E03F3856058C309A6CB508553913788D41A61B1D82B0A2F932C68F18FC21851E66D8649AD9E2092F08C96AD67810724369BF0511E74E1F71F1A825EDDFA1D5DC30E359693C0366FF9FB6828699ACFD1F037116F95ADD42F6C64B580B3287AA32FBA518E4B8C9C7B52413B501247DB05ADDD891794394DB529E66890603BCD75CF70E6151398EE85F6D8178EA72C6A61937BCE32BFDAEA86B57A27EBC379933F54C7D44F3E407ED26685D88F0F10A344CDF62F4E20974B374BA1D41DF223A867DD19713CF0FF71F24465D79258B1742916EE35EE3EBE57767E9A54498509543E9
answer = BA0D89B579F0AFB50252E5FC96924BFCECDA4F05801775A3EFBFD2701AA28AD727BE464603000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE000100236F6D779877A357465CEC030AC5FDA6D6B377372BFA75574289988FD87D966A29B47E0C00BC788900304EA5E03F3856058C309A6CB508553913788D41A61B1D82B0A2F932C68F18FC21851E66D8649AD9E2092F08C96AD67810724369BF0511E74E1F71F1A825EDDFA1D5DC30E359693C0366FF9FB6828699ACFD1F037116F95ADD42F6C64B580B3287AA32FBA518E4B8C9C7B52413B501247DB05ADDD891794394DB529E66890603BCD75CF70E6151398EE85F6D8178EA72C6A61937BCE32BFDAEA86B57A27EBC379933F54C7D44F3E407ED26685D88F0F10A344CDF62F4E20974B374BA1D41DF223A867DD19713CF0FF71F24465D79258B1742916EE35EE3EBE57767E9A54498509543E9
Generated payload (excluding transport headers/trailers):
0000 | BA 0D 89 B5 79 F0 AF B5 02 52 E5 FC 96 92 4B FC
0010 | EC DA 4F 05 80 17 75 A3 EF BF D2 70 1A A2 8A D7
0020 | 27 BE 46 46 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 | 23 6F 6D 77 98 77 A3 57 46 5C EC 03 0A C5 FD A6
0140 | D6 B3 77 37 2B FA 75 57 42 89 98 8F D8 7D 96 6A
0150 | 29 B4 7E 0C 00 BC 78 89 00 30 4E A5 E0 3F 38 56
0160 | 05 8C 30 9A 6C B5 08 55 39 13 78 8D 41 A6 1B 1D
0170 | 82 B0 A2 F9 32 C6 8F 18 FC 21 85 1E 66 D8 64 9A
0180 | D9 E2 09 2F 08 C9 6A D6 78 10 72 43 69 BF 05 11
0190 | E7 4E 1F 71 F1 A8 25 ED DF A1 D5 DC 30 E3 59 69
01A0 | 3C 03 66 FF 9F B6 82 86 99 AC FD 1F 03 71 16 F9
01B0 | 5A DD 42 F6 C6 4B 58 0B 32 87 AA 32 FB A5 18 E4
01C0 | B8 C9 C7 B5 24 13 B5 01 24 7D B0 5A DD D8 91 79
01D0 | 43 94 DB 52 9E 66 89 06 03 BC D7 5C F7 0E 61 51
01E0 | 39 8E E8 5F 6D 81 78 EA 72 C6 A6 19 37 BC E3 2B
01F0 | FD AE A8 6B 57 A2 7E BC 37 99 33 F5 4C 7D 44 F3
0200 | E4 07 ED 26 68 5D 88 F0 F1 0A 34 4C DF 62 F4 E2
0210 | 09 74 B3 74 BA 1D 41 DF 22 3A 86 7D D1 97 13 CF
0220 | 0F F7 1F 24 46 5D 79 25 8B 17 42 91 6E E3 5E E3
0230 | EB E5 77 67
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 | 79F0AFB50252E5FC96924BFCECDA4F05 |
Value generated by client in Step 1 |
server_nonce | 20, 16 | 801775A3EFBFD2701AA28AD727BE4646 |
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 | FE000100236F6D779877A357465CEC03 0AC5FDA6D6B377372BFA75574289988F D87D966A29B47E0C00BC788900304EA5 E03F3856058C309A6CB508553913788D 41A61B1D82B0A2F932C68F18FC21851E 66D8649AD9E2092F08C96AD678107243 69BF0511E74E1F71F1A825EDDFA1D5DC 30E359693C0366FF9FB6828699ACFD1F 037116F95ADD42F6C64B580B3287AA32 FBA518E4B8C9C7B52413B501247DB05A DDD891794394DB529E66890603BCD75C F70E6151398EE85F6D8178EA72C6A619 37BCE32BFDAEA86B57A27EBC379933F5 4C7D44F3E407ED26685D88F0F10A344C DF62F4E20974B374BA1D41DF223A867D D19713CF0FF71F24465D79258B174291 6EE35EE3 |
g_a diffie-hellman parameter |
server_time | 560, 4 | EBE57767 (1735910891 in decimal) |
Server time |
First, generate a secure random 2048-bit number b:
b = F2987DDA0ABCE0B7CE23A7B850BE126641CBAABC1F4C250C839E1844E2E2CBE57BC0A30B45F6C21D8635F5E927DB0D7498A2F03C6A42D3FB2F3787D5B4D63C2F17A6EB197C0412237E528B68D3D70ADCDEEBD7CD6BACEC59D4FB8F17125ED00B95B34A2D5D8A2133937B5DFEF6DB09F0A3A1BC207A87D9FE4761C59880CA551432E4AFFCF3982B11EABC526977215F4AC2CE20FA7C808A971DA8C8A08FF26DEBB326EE580B551BEAF0C4B677FCE00E5C6AAEDA3A5A42F38C9C6E226EEDED0502A6BEFC991CC1E0B504E187206D172E72E05D958009FB8C27616EBDD28247262A33AF25E911C9DC22D9A88C6E31A623E6C1E1011CDBD184F6DFFC4F77F5370F16
Then compute g_b = pow(g, b) mod dh_prime
g_b = 5EEDFBF6A2199CD1B06182C5C4E0DC26B69ECDE1AD6430D192CD8A69E7434B66A42900AF29B3F41C619AD383FB3721705CF52C34C0507433F743592EE5D4FC50F64E0F8686870E36179AF8C8F4587BD572E98AF4A8247DE2F524BCD48642B38F36104046D7502CDC14BF39A88422B4B1111D886A326C473D1145E69E37C676E1E8FDA07E470482F853886700AE1E7FFDE69FF6D40547C515110B74C6680C844B61504FE0A2D3E08BB7BAE70016C97D7E6B7FA4CEBFE6B5BE30C884849ADE39CC50FD9B4FB16F671EFE8533D0BF7FF8BF13957F1E0D55E713199CEACC72419AF60CDB1D561084565E9F090141B9F8732B2E806C1B01B25BAFFC4EE1BD5525CB8A
Generated payload (excluding transport headers/trailers):
0000 | 54 B6 43 66 79 F0 AF B5 02 52 E5 FC 96 92 4B FC
0010 | EC DA 4F 05 80 17 75 A3 EF BF D2 70 1A A2 8A D7
0020 | 27 BE 46 46 00 00 00 00 00 00 00 00 FE 00 01 00
0030 | 5E ED FB F6 A2 19 9C D1 B0 61 82 C5 C4 E0 DC 26
0040 | B6 9E CD E1 AD 64 30 D1 92 CD 8A 69 E7 43 4B 66
0050 | A4 29 00 AF 29 B3 F4 1C 61 9A D3 83 FB 37 21 70
0060 | 5C F5 2C 34 C0 50 74 33 F7 43 59 2E E5 D4 FC 50
0070 | F6 4E 0F 86 86 87 0E 36 17 9A F8 C8 F4 58 7B D5
0080 | 72 E9 8A F4 A8 24 7D E2 F5 24 BC D4 86 42 B3 8F
0090 | 36 10 40 46 D7 50 2C DC 14 BF 39 A8 84 22 B4 B1
00A0 | 11 1D 88 6A 32 6C 47 3D 11 45 E6 9E 37 C6 76 E1
00B0 | E8 FD A0 7E 47 04 82 F8 53 88 67 00 AE 1E 7F FD
00C0 | E6 9F F6 D4 05 47 C5 15 11 0B 74 C6 68 0C 84 4B
00D0 | 61 50 4F E0 A2 D3 E0 8B B7 BA E7 00 16 C9 7D 7E
00E0 | 6B 7F A4 CE BF E6 B5 BE 30 C8 84 84 9A DE 39 CC
00F0 | 50 FD 9B 4F B1 6F 67 1E FE 85 33 D0 BF 7F F8 BF
0100 | 13 95 7F 1E 0D 55 E7 13 19 9C EA CC 72 41 9A F6
0110 | 0C DB 1D 56 10 84 56 5E 9F 09 01 41 B9 F8 73 2B
0120 | 2E 80 6C 1B 01 B2 5B AF FC 4E E1 BD 55 25 CB 8A
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 | 79F0AFB50252E5FC96924BFCECDA4F05 |
Value generated by client in Step 1 |
server_nonce | 20, 16 | 801775A3EFBFD2701AA28AD727BE4646 |
Value received from server in Step 2 |
g_b | 36, 260 | FE0001005EEDFBF6A2199CD1B06182C5 C4E0DC26B69ECDE1AD6430D192CD8A69 E7434B66A42900AF29B3F41C619AD383 FB3721705CF52C34C0507433F743592E E5D4FC50F64E0F8686870E36179AF8C8 F4587BD572E98AF4A8247DE2F524BCD4 8642B38F36104046D7502CDC14BF39A8 8422B4B1111D886A326C473D1145E69E 37C676E1E8FDA07E470482F853886700 AE1E7FFDE69FF6D40547C515110B74C6 680C844B61504FE0A2D3E08BB7BAE700 16C97D7E6B7FA4CEBFE6B5BE30C88484 9ADE39CC50FD9B4FB16F671EFE8533D0 BF7FF8BF13957F1E0D55E713199CEACC 72419AF60CDB1D561084565E9F090141 B9F8732B2E806C1B01B25BAFFC4EE1BD 5525CB8A |
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 = 54B6436679F0AFB50252E5FC96924BFCECDA4F05801775A3EFBFD2701AA28AD727BE46460000000000000000FE0001005EEDFBF6A2199CD1B06182C5C4E0DC26B69ECDE1AD6430D192CD8A69E7434B66A42900AF29B3F41C619AD383FB3721705CF52C34C0507433F743592EE5D4FC50F64E0F8686870E36179AF8C8F4587BD572E98AF4A8247DE2F524BCD48642B38F36104046D7502CDC14BF39A88422B4B1111D886A326C473D1145E69E37C676E1E8FDA07E470482F853886700AE1E7FFDE69FF6D40547C515110B74C6680C844B61504FE0A2D3E08BB7BAE70016C97D7E6B7FA4CEBFE6B5BE30C884849ADE39CC50FD9B4FB16F671EFE8533D0BF7FF8BF13957F1E0D55E713199CEACC72419AF60CDB1D561084565E9F090141B9F8732B2E806C1B01B25BAFFC4EE1BD5525CB8A
padding = 8347525EB8B63DE9CE3A1FCC
tmp_aes_key = E68CA5ABA101FFCA0ADDA66303A57AFFAA2712FB16A7B8DAFC72C25E8A73A368
tmp_aes_iv = 0A355D4431B9DDD91A51EFF3F7D340D64F0390C53F91DC53C331D43C264F835B
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 = FA29896EE19D3CCB08FB07CF1C922CFFBF5D38D98BA56D926D63064C77741F423BCE22B5A2C100E34BB5D7CE3027E85E65006205B6926C0E42EF29E7CC24EEC4523650F692A530FB95D57EF3604C490155FB8530C94E9E2EBDF272BDB3DD98FFCA65FF51E5DBCA4CF799D6660F6D0BA1A8B1CE6FE9D26F401B1B79E057EE273CAE14D8D8D60030C862E13B2E49FE97008AEA0EC8ADE90AE3DDDC641AE7C0844A37EFC4DA3B27308B9C40B1FD2028C12B37EA719D593DC7EDC892B8630B82E05168FCC0D76E7CA23106FEF13B09D3BAE83D612CDF2E3A5ADDE4E807EEED660C9921AD364CFF6614350F313A48AB3483F08AB81A226F7763A575F44A04BD53C58A49ABD2EE4A885F2610A8387803E418C371AF9378A0941F2DB0AA9CE019048B6C9ED0C7FCB33985624E2392233CAA5E66A3891AB18544685E96EF5C2B55E69EA2C62B33E6058DA2944F087B803F251A7C
The length of the final string is 336 bytes.
Sent payload (excluding transport headers/trailers):
0000 | 00 00 00 00 00 00 00 00 6C E5 08 00 EB E5 77 67
0010 | 78 01 00 00 1F 5F 04 F5 79 F0 AF B5 02 52 E5 FC
0020 | 96 92 4B FC EC DA 4F 05 80 17 75 A3 EF BF D2 70
0030 | 1A A2 8A D7 27 BE 46 46 FE 50 01 00 FA 29 89 6E
0040 | E1 9D 3C CB 08 FB 07 CF 1C 92 2C FF BF 5D 38 D9
0050 | 8B A5 6D 92 6D 63 06 4C 77 74 1F 42 3B CE 22 B5
0060 | A2 C1 00 E3 4B B5 D7 CE 30 27 E8 5E 65 00 62 05
0070 | B6 92 6C 0E 42 EF 29 E7 CC 24 EE C4 52 36 50 F6
0080 | 92 A5 30 FB 95 D5 7E F3 60 4C 49 01 55 FB 85 30
0090 | C9 4E 9E 2E BD F2 72 BD B3 DD 98 FF CA 65 FF 51
00A0 | E5 DB CA 4C F7 99 D6 66 0F 6D 0B A1 A8 B1 CE 6F
00B0 | E9 D2 6F 40 1B 1B 79 E0 57 EE 27 3C AE 14 D8 D8
00C0 | D6 00 30 C8 62 E1 3B 2E 49 FE 97 00 8A EA 0E C8
00D0 | AD E9 0A E3 DD DC 64 1A E7 C0 84 4A 37 EF C4 DA
00E0 | 3B 27 30 8B 9C 40 B1 FD 20 28 C1 2B 37 EA 71 9D
00F0 | 59 3D C7 ED C8 92 B8 63 0B 82 E0 51 68 FC C0 D7
0100 | 6E 7C A2 31 06 FE F1 3B 09 D3 BA E8 3D 61 2C DF
0110 | 2E 3A 5A DD E4 E8 07 EE ED 66 0C 99 21 AD 36 4C
0120 | FF 66 14 35 0F 31 3A 48 AB 34 83 F0 8A B8 1A 22
0130 | 6F 77 63 A5 75 F4 4A 04 BD 53 C5 8A 49 AB D2 EE
0140 | 4A 88 5F 26 10 A8 38 78 03 E4 18 C3 71 AF 93 78
0150 | A0 94 1F 2D B0 AA 9C E0 19 04 8B 6C 9E D0 C7 FC
0160 | B3 39 85 62 4E 23 92 23 3C AA 5E 66 A3 89 1A B1
0170 | 85 44 68 5E 96 EF 5C 2B 55 E6 9E A2 C6 2B 33 E6
0180 | 05 8D A2 94 4F 08 7B 80 3F 25 1A 7C
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 | 6CE50800EBE57767 |
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 | 79F0AFB50252E5FC96924BFCECDA4F05 |
Value generated by client in Step 1 |
server_nonce | 40, 16 | 801775A3EFBFD2701AA28AD727BE4646 |
Value received from server in Step 2 |
encrypted_data | 56, 340 | FE500100FA29896EE19D3CCB08FB07CF 1C922CFFBF5D38D98BA56D926D63064C 77741F423BCE22B5A2C100E34BB5D7CE 3027E85E65006205B6926C0E42EF29E7 CC24EEC4523650F692A530FB95D57EF3 604C490155FB8530C94E9E2EBDF272BD B3DD98FFCA65FF51E5DBCA4CF799D666 0F6D0BA1A8B1CE6FE9D26F401B1B79E0 57EE273CAE14D8D8D60030C862E13B2E 49FE97008AEA0EC8ADE90AE3DDDC641A E7C0844A37EFC4DA3B27308B9C40B1FD 2028C12B37EA719D593DC7EDC892B863 0B82E05168FCC0D76E7CA23106FEF13B 09D3BAE83D612CDF2E3A5ADDE4E807EE ED660C9921AD364CFF6614350F313A48 AB3483F08AB81A226F7763A575F44A04 BD53C58A49ABD2EE4A885F2610A83878 03E418C371AF9378A0941F2DB0AA9CE0 19048B6C9ED0C7FCB33985624E239223 3CAA5E66A3891AB18544685E96EF5C2B 55E69EA2C62B33E6058DA2944F087B80 3F251A7C |
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 = 83CBD31C0303361FF1C29437A77CBA749C84F28A118646038C7EDD29EF718A1F6A493047D476A6E678D97A4A5CC7990CEA552D68E109869E5BFC86570049CD8F2EB4BA10B6C4123FB8A977774B4C5185B5C96AF7BD7A71DB78E6E6148CED2048869A21B8ED7FBA7F6F2E7722BFA28447AB84A245CB0E6D01261191B753191E744DCFDA522D50167832EE4D5EE90AAA6F31821248F0F06BF5692EF604CFC4316CEDE078F71E17BCEBBE388589E6707AF5BA26E8DD063BB116C4B4E7BEF3B462C3350D0376D42F95D353E46BE4C378D2A60141A2339641F8B712EB3ECFB42B7F26F69E9BB15373E0AC4BE266E1681859DDAAB8CD7D877BB847D2A8BD068A784943
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 CC 0A 7B ED E5 77 67
0010 | 34 00 00 00 34 F7 CB 3B 79 F0 AF B5 02 52 E5 FC
0020 | 96 92 4B FC EC DA 4F 05 80 17 75 A3 EF BF D2 70
0030 | 1A A2 8A D7 27 BE 46 46 51 07 0B 3D B6 72 B7 60
0040 | 2E 4E E2 FE 76 1B 36 A2
Payload (de)serialization:
dh_gen_ok#3bcbf734 nonce:int128 server_nonce:int128 new_nonce_hash1:int128 = Set_client_DH_params_answer;
Parameter | Offset, Length in bytes | Value | Description |
---|---|---|---|
auth_key_id | 0, 8 | 0000000000000000 |
0 since the message is in plain text |
message_id | 8, 8 | 01CC0A7BEDE57767 |
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 | 79F0AFB50252E5FC96924BFCECDA4F05 |
Value generated by client in Step 1 |
server_nonce | 40, 16 | 801775A3EFBFD2701AA28AD727BE4646 |
Value received from server in Step 2 |
new_nonce_hash1 | 56, 16 | 51070B3DB672B7602E4EE2FE761B36A2 |
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. |