Auth key generation example

In the examples below, the transport headers are omitted:

For example, for the abridged version of the transport », the client sends 0xef as the first byte (important: only prior to the very first data packet), then the packet length is encoded with a single byte (0x01-0x7e = data length divided by 4; or 0x7f followed by 3 bytes (little endian) divided by 4) followed by the data itself. In this case, server responses have the same structure (although the server does not send 0xefas the first byte). Detailed documentation on creating authorization keys is available here ».

DH exchange initiation

1) Client sends query to server

Sent payload (excluding transport headers/trailers):

0000 | 00 00 00 00 00 00 00 00 8C D5 00 00 FB EC 0E 6A
0010 | 14 00 00 00 F1 8E 7E BE 90 1B A6 09 42 DD 01 BE
0020 | 9E 03 34 D1 59 BC 67 B6

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 8CD50000FBEC0E6A 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 901BA60942DD01BE9E0334D159BC67B6 Random number
2) Server sends response of the form

Received payload (excluding transport headers/trailers):

0000 | 00 00 00 00 00 00 00 00 01 AC 6C 6F FB EC 0E 6A
0010 | 50 00 00 00 63 24 16 05 90 1B A6 09 42 DD 01 BE
0020 | 9E 03 34 D1 59 BC 67 B6 3C A5 BC 7D CD 71 5C D1
0030 | 8B AF 8F 5D F5 CD 21 A2 08 12 AE 13 A9 F6 4E 03
0040 | 6B 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 01AC6C6FFBEC0E6A 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 901BA60942DD01BE9E0334D159BC67B6 Value generated by client in Step 1
server_nonce 40, 16 3CA5BC7DCD715CD18BAF8F5DF5CD21A2 Server-generated random number
pq 56, 12 0812AE13A9F64E036B000000
TL byte deserialization
=> bigendian conversion to decimal
=> 1346034959333065579
Single-byte prefix denoting length, an 8-byte string, and three bytes of padding
%(Vector strlong) 68, 4 15c4b51c Vector t constructor number from TL schema
count 72, 4 03000000 Number of elements in server_public_key_fingerprints
server_public_key_fingerprints[0] 76, 8 85FD64DE851D9DD0 64 lower-order bits of SHA1(server_public_key)
server_public_key_fingerprints[1] 84, 8 A5B7F709355FC30B 64 lower-order bits of SHA1(server_public_key)
server_public_key_fingerprints[2] 92, 8 216BE86C022BB4C3 64 lower-order bits of SHA1(server_public_key)

In our case, the client only has the following public keys, with the following fingerprints:

  • 85FD64DE851D9DD0

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

Proof of work

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

Decompose into 2 prime cofactors p < q: 1346034959333065579 = 1046433977 * 1286306627

p = 1046433977
q = 1286306627

Presenting proof of work; Server authentication

4) encrypted_data payload generation

First of all, generate an encrypted_data payload as follows:

Generated payload (excluding transport headers/trailers):

0000 | 95 5F F5 A9 08 12 AE 13 A9 F6 4E 03 6B 00 00 00
0010 | 04 3E 5F 50 B9 00 00 00 04 4C AB 7B 43 00 00 00
0020 | 90 1B A6 09 42 DD 01 BE 9E 03 34 D1 59 BC 67 B6
0030 | 3C A5 BC 7D CD 71 5C D1 8B AF 8F 5D F5 CD 21 A2
0040 | 2E E0 6E 42 C6 7E F1 CB 25 27 43 BC 16 D6 88 8A
0050 | 07 75 D9 9D BD 81 19 A4 53 27 90 C9 7C 6C 28 63
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 0812AE13A9F64E036B000000
TL byte deserialization
=> bigendian conversion to decimal
=> 1346034959333065579
Single-byte prefix denoting length, 8-byte string, and three bytes of padding
p 16, 8 043E5F50B9000000
TL byte deserialization
=> bigendian conversion to decimal
=> 1046433977
First prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding
q 24, 8 044CAB7B43000000
TL byte deserialization
=> bigendian conversion to decimal
=> 1286306627
Second prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding
nonce 32, 16 901BA60942DD01BE9E0334D159BC67B6 Value generated by client in Step 1
server_nonce 48, 16 3CA5BC7DCD715CD18BAF8F5DF5CD21A2 Value received from server in Step 2
new_nonce 64, 32 2EE06E42C67EF1CB252743BC16D6888A 0775D99DBD8119A4532790C97C6C2863 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 = 955FF5A90812AE13A9F64E036B000000043E5F50B9000000044CAB7B43000000901BA60942DD01BE9E0334D159BC67B63CA5BC7DCD715CD18BAF8F5DF5CD21A22EE06E42C67EF1CB252743BC16D6888A0775D99DBD8119A4532790C97C6C286302000000
random_padding_bytes = 2B40F01DCC22F373832605FE4D743A45375ACB2763550B8D6AC5FD474E04282E2E03F8F786A2169A8C7C68C0BA59064FBA9255691AE8DF4C92B6BF8CF042BFA07C9789D98E48436DF7F72F8870B97EF8ACDE526AE358198AB45BEF44

And this is the output:

encrypted_data = 7CA05BCF32D654D4486AA7F272C4B1BC7DD4D1A3D11A2C79271924A548AB31B2E5F32588D2F0635D97E15957A2A9EE9E33F86034989A4ED58D4EECA17041560223B9FCB9F571AE22FCE915D3B299A447A0BF5F1821D15B5E99D3B7FB0EF7BF34971F3DAA248EB811AA63DE5AB48CEB84B9E4E56C0EF44FEDB9C82A17F9E41BA40A1520B80FE8FCC18665CF31CA302682ED760FDCA352078B67A3EB7D9BCBDC6607711C60169F42D4EF3956B458434F075CDBC182227AA28024AD284FCF928356E61A32CD29841F538F905CA925A16DB4CEE9E7B915AF0B9A8D39E46DE9BCD869780785C23403BBCAE4D7DF8654DF15B9150E895CCD5A59568814D5359D8B8864

The length of the final string is 256 bytes.

5) Send req_DH_params query with generated encrypted_data

Sent payload (excluding transport headers/trailers):

0000 | 00 00 00 00 00 00 00 00 20 FA 05 00 FB EC 0E 6A
0010 | 40 01 00 00 BE E4 12 D7 90 1B A6 09 42 DD 01 BE
0020 | 9E 03 34 D1 59 BC 67 B6 3C A5 BC 7D CD 71 5C D1
0030 | 8B AF 8F 5D F5 CD 21 A2 04 3E 5F 50 B9 00 00 00
0040 | 04 4C AB 7B 43 00 00 00 85 FD 64 DE 85 1D 9D D0
0050 | FE 00 01 00 7C A0 5B CF 32 D6 54 D4 48 6A A7 F2
0060 | 72 C4 B1 BC 7D D4 D1 A3 D1 1A 2C 79 27 19 24 A5
0070 | 48 AB 31 B2 E5 F3 25 88 D2 F0 63 5D 97 E1 59 57
0080 | A2 A9 EE 9E 33 F8 60 34 98 9A 4E D5 8D 4E EC A1
0090 | 70 41 56 02 23 B9 FC B9 F5 71 AE 22 FC E9 15 D3
00A0 | B2 99 A4 47 A0 BF 5F 18 21 D1 5B 5E 99 D3 B7 FB
00B0 | 0E F7 BF 34 97 1F 3D AA 24 8E B8 11 AA 63 DE 5A
00C0 | B4 8C EB 84 B9 E4 E5 6C 0E F4 4F ED B9 C8 2A 17
00D0 | F9 E4 1B A4 0A 15 20 B8 0F E8 FC C1 86 65 CF 31
00E0 | CA 30 26 82 ED 76 0F DC A3 52 07 8B 67 A3 EB 7D
00F0 | 9B CB DC 66 07 71 1C 60 16 9F 42 D4 EF 39 56 B4
0100 | 58 43 4F 07 5C DB C1 82 22 7A A2 80 24 AD 28 4F
0110 | CF 92 83 56 E6 1A 32 CD 29 84 1F 53 8F 90 5C A9
0120 | 25 A1 6D B4 CE E9 E7 B9 15 AF 0B 9A 8D 39 E4 6D
0130 | E9 BC D8 69 78 07 85 C2 34 03 BB CA E4 D7 DF 86
0140 | 54 DF 15 B9 15 0E 89 5C CD 5A 59 56 88 14 D5 35
0150 | 9D 8B 88 64

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 20FA0500FBEC0E6A 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 901BA60942DD01BE9E0334D159BC67B6 Value generated by client in Step 1
server_nonce 40, 16 3CA5BC7DCD715CD18BAF8F5DF5CD21A2 Value received from server in Step 2
p 56, 8 043E5F50B9000000
TL byte deserialization
=> bigendian conversion to decimal
=> 1046433977
First prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding
q 64, 8 044CAB7B43000000
TL byte deserialization
=> bigendian conversion to decimal
=> 1286306627
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 FE0001007CA05BCF32D654D4486AA7F2 72C4B1BC7DD4D1A3D11A2C79271924A5 48AB31B2E5F32588D2F0635D97E15957 A2A9EE9E33F86034989A4ED58D4EECA1 7041560223B9FCB9F571AE22FCE915D3 B299A447A0BF5F1821D15B5E99D3B7FB 0EF7BF34971F3DAA248EB811AA63DE5A B48CEB84B9E4E56C0EF44FEDB9C82A17 F9E41BA40A1520B80FE8FCC18665CF31 CA302682ED760FDCA352078B67A3EB7D 9BCBDC6607711C60169F42D4EF3956B4 58434F075CDBC182227AA28024AD284F CF928356E61A32CD29841F538F905CA9 25A16DB4CEE9E7B915AF0B9A8D39E46D E9BCD869780785C23403BBCAE4D7DF86 54DF15B9150E895CCD5A59568814D535
9D8B8864
Value generated above
6) Server responds with:

Received payload (excluding transport headers/trailers):

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

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 010055C4FBEC0E6A 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 901BA60942DD01BE9E0334D159BC67B6 Value generated by client in Step 1
server_nonce 40, 16 3CA5BC7DCD715CD18BAF8F5DF5CD21A2 Value received from server in Step 2
encrypted_answer 56, 596 FE500200F9A2017E4DA6861C9A491BAA 4987D046592694F25E24F5F3B6DFC0C1 4451E21201B2707CF827951384D6D68D BC569AF35ED70214B5FDFD93AACFEAB3 003570AA685349BC3C097CEC694D7B07 2A8E7DF7C2B06F53875AC6854A5D3337 FC52F306C8B70F1ED9B7FBB422B2A1F1 D318E6C6C4C2A492043423FF9F2E945F DAF029E7B84CCF4DF8A027895851CFDB 1BC272CF1F350D4CA7960AA3CA4BC359 96D811D9873A22D46B4A59F906C283D5 031EDA529923A0DE6E82F2D03ABEEE15 F7C6CDE1AF72A6714F4A60F27A564A2D FA0B6D8BC19FC0A22D0C1A2A3A796337 6DAC2F51DC9C8DFED358305375E3FC41 A7C9DA062846587938161C48A4F02EAD A94A88E508F28CFA806D75F990204E86 43D2A7F479BD01229308B69D2E0A0F8A FCDBD2E8D7C64D3E1CC6DC3B2A1BFB2C 893367384BB242497541E28B3E08B6F4 A484548D7930CE15DF334E96CE71FCF9 5FA12D0A3395AE17F3D20E6BF07084DE 3BCA2F863ED7298B9D2EC78F47554C4B 578D4D08CC72CAB48D6DB304570596D0 C1789853D8E063AE6E379AA60AAEF0E6 4EF0BB382FD47B00D13647146D83176F 5115BC4C6428A3E97A53A37EFA78E29E F69E1D7ABD664AA66DCCE18885A13BDE 18D6B6E2D97F6D06A461A3F98990E996 A0DD292021039C2C9634306938F0B99D 4928C3FC71EEB08076941933B57407B8 574461FFC2634B222396B48D6DE26BBF BB0247285975357EE7CD90BC750AB65F 5590784EE913C88C2193BD943F9C0A61 00927A03749EE38EBB426C2B50FFE3CF 27D8D15A5DFCC0B11801A2F7A9EFD74B 3C9F5E1498A8123782B72E4A0DECDD50
AB978918
See below

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

encrypted_answer = F9A2017E4DA6861C9A491BAA4987D046592694F25E24F5F3B6DFC0C14451E21201B2707CF827951384D6D68DBC569AF35ED70214B5FDFD93AACFEAB3003570AA685349BC3C097CEC694D7B072A8E7DF7C2B06F53875AC6854A5D3337FC52F306C8B70F1ED9B7FBB422B2A1F1D318E6C6C4C2A492043423FF9F2E945FDAF029E7B84CCF4DF8A027895851CFDB1BC272CF1F350D4CA7960AA3CA4BC35996D811D9873A22D46B4A59F906C283D5031EDA529923A0DE6E82F2D03ABEEE15F7C6CDE1AF72A6714F4A60F27A564A2DFA0B6D8BC19FC0A22D0C1A2A3A7963376DAC2F51DC9C8DFED358305375E3FC41A7C9DA062846587938161C48A4F02EADA94A88E508F28CFA806D75F990204E8643D2A7F479BD01229308B69D2E0A0F8AFCDBD2E8D7C64D3E1CC6DC3B2A1BFB2C893367384BB242497541E28B3E08B6F4A484548D7930CE15DF334E96CE71FCF95FA12D0A3395AE17F3D20E6BF07084DE3BCA2F863ED7298B9D2EC78F47554C4B578D4D08CC72CAB48D6DB304570596D0C1789853D8E063AE6E379AA60AAEF0E64EF0BB382FD47B00D13647146D83176F5115BC4C6428A3E97A53A37EFA78E29EF69E1D7ABD664AA66DCCE18885A13BDE18D6B6E2D97F6D06A461A3F98990E996A0DD292021039C2C9634306938F0B99D4928C3FC71EEB08076941933B57407B8574461FFC2634B222396B48D6DE26BBFBB0247285975357EE7CD90BC750AB65F5590784EE913C88C2193BD943F9C0A6100927A03749EE38EBB426C2B50FFE3CF27D8D15A5DFCC0B11801A2F7A9EFD74B3C9F5E1498A8123782B72E4A0DECDD50AB978918
tmp_aes_key = 262B0B32E662DB938A1763E82BDBF170FF80D72BBCE11F71C492CCE21CF90226
tmp_aes_iv = 62ED4104CB25FBF9E5261AC9187ECA573078D8F8C2230F192DD42C392EE06E42

Yielding:

answer_with_hash = CD3D25FA0D33CD2C405BB0868636FAA1B84B43E1BA0D89B5901BA60942DD01BE9E0334D159BC67B63CA5BC7DCD715CD18BAF8F5DF5CD21A203000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE0001000227A2C3283FB6E48D1B359CFB7E01D4858583E2ADADA0CEB5EB239D4AA55837424EEE3BF10F44C0335223CDD10C25917CF1EB62192BC478A4D3B21FD86439421BBB36512F481CF71549E7036CAF1BCE9869181F5A6F7FED5417ECACE36A9B089096982093CA2D92771A1D467A9D72E159AC7316AF0273812A7F13D0265E6663D7918BF90DD976E45DEEE9B761BD66026FB0B69090F7B56837CE1C1A327135D5BC31D8B8B67A62A5AF9556C60AA4C14508BB64963850FE09D569DDEFB024537972020D9E8E00233BAECC51E1E2CE3CEA980ACDE5B932EF8EF56EF2462D686B4E95C2E969B1B0EC7394CF18FB2CE45314D6E8E62CFFABB21A6669A4055A5E8AE0FBEC0E6AFEBA8E54101C545C
answer = BA0D89B5901BA60942DD01BE9E0334D159BC67B63CA5BC7DCD715CD18BAF8F5DF5CD21A203000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE0001000227A2C3283FB6E48D1B359CFB7E01D4858583E2ADADA0CEB5EB239D4AA55837424EEE3BF10F44C0335223CDD10C25917CF1EB62192BC478A4D3B21FD86439421BBB36512F481CF71549E7036CAF1BCE9869181F5A6F7FED5417ECACE36A9B089096982093CA2D92771A1D467A9D72E159AC7316AF0273812A7F13D0265E6663D7918BF90DD976E45DEEE9B761BD66026FB0B69090F7B56837CE1C1A327135D5BC31D8B8B67A62A5AF9556C60AA4C14508BB64963850FE09D569DDEFB024537972020D9E8E00233BAECC51E1E2CE3CEA980ACDE5B932EF8EF56EF2462D686B4E95C2E969B1B0EC7394CF18FB2CE45314D6E8E62CFFABB21A6669A4055A5E8AE0FBEC0E6AFEBA8E54101C545C

Generated payload (excluding transport headers/trailers):

0000 | BA 0D 89 B5 90 1B A6 09 42 DD 01 BE 9E 03 34 D1
0010 | 59 BC 67 B6 3C A5 BC 7D CD 71 5C D1 8B AF 8F 5D
0020 | F5 CD 21 A2 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 | 02 27 A2 C3 28 3F B6 E4 8D 1B 35 9C FB 7E 01 D4
0140 | 85 85 83 E2 AD AD A0 CE B5 EB 23 9D 4A A5 58 37
0150 | 42 4E EE 3B F1 0F 44 C0 33 52 23 CD D1 0C 25 91
0160 | 7C F1 EB 62 19 2B C4 78 A4 D3 B2 1F D8 64 39 42
0170 | 1B BB 36 51 2F 48 1C F7 15 49 E7 03 6C AF 1B CE
0180 | 98 69 18 1F 5A 6F 7F ED 54 17 EC AC E3 6A 9B 08
0190 | 90 96 98 20 93 CA 2D 92 77 1A 1D 46 7A 9D 72 E1
01A0 | 59 AC 73 16 AF 02 73 81 2A 7F 13 D0 26 5E 66 63
01B0 | D7 91 8B F9 0D D9 76 E4 5D EE E9 B7 61 BD 66 02
01C0 | 6F B0 B6 90 90 F7 B5 68 37 CE 1C 1A 32 71 35 D5
01D0 | BC 31 D8 B8 B6 7A 62 A5 AF 95 56 C6 0A A4 C1 45
01E0 | 08 BB 64 96 38 50 FE 09 D5 69 DD EF B0 24 53 79
01F0 | 72 02 0D 9E 8E 00 23 3B AE CC 51 E1 E2 CE 3C EA
0200 | 98 0A CD E5 B9 32 EF 8E F5 6E F2 46 2D 68 6B 4E
0210 | 95 C2 E9 69 B1 B0 EC 73 94 CF 18 FB 2C E4 53 14
0220 | D6 E8 E6 2C FF AB B2 1A 66 69 A4 05 5A 5E 8A E0
0230 | FB EC 0E 6A

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 901BA60942DD01BE9E0334D159BC67B6 Value generated by client in Step 1
server_nonce 20, 16 3CA5BC7DCD715CD18BAF8F5DF5CD21A2 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 FE0001000227A2C3283FB6E48D1B359C FB7E01D4858583E2ADADA0CEB5EB239D 4AA55837424EEE3BF10F44C0335223CD D10C25917CF1EB62192BC478A4D3B21F D86439421BBB36512F481CF71549E703 6CAF1BCE9869181F5A6F7FED5417ECAC E36A9B089096982093CA2D92771A1D46 7A9D72E159AC7316AF0273812A7F13D0 265E6663D7918BF90DD976E45DEEE9B7 61BD66026FB0B69090F7B56837CE1C1A 327135D5BC31D8B8B67A62A5AF9556C6 0AA4C14508BB64963850FE09D569DDEF B024537972020D9E8E00233BAECC51E1 E2CE3CEA980ACDE5B932EF8EF56EF246 2D686B4E95C2E969B1B0EC7394CF18FB 2CE45314D6E8E62CFFABB21A6669A405
5A5E8AE0
g_a diffie-hellman parameter
server_time 560, 4 FBEC0E6A (1779363067 in decimal) Server time
7) Client computes random 2048-bit number b (using a sufficient amount of entropy) and sends the server a message

First, generate a secure random 2048-bit number b:

b = F0B57C06B103B513FD3BBD29C12AA8B1A7BA985F63E18557591A9BA4C08B05EB9D2930C758D2F9ABB40E9DA0819CBAE848AF7A4E1977102441CBD0A8A4252728BE93AB399985FD8AB6538539E3238AA35FD65674EE725A0003A38AB2BFA96818D77DE302A8594D751852CDB65742CC8248DEEDFB79A66E46484C00B048E7361EEEE6026930F8A3EDA43C07F43F256063F30B705C9C7D92AEA961E8521090C4191A6D4F41EF1A118188B32C4F05023D1FF5F67DB38412F0BA4DEE3840350824F5128276FB7A47EA91BDDC1287F8E247FFE6A1043D63D7B9A8080ABEFB06FB0E2604A349ECEA9281644775B3316B3DE61F18E95D05E95A657707CBE32C0F0C2F2B

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

g_b = 7BF8875C7A40EAAA21941FA20ACC090954E42FC42F6F5A7996A4EC187D84E34908372DB63373BDBCC79BC39DB04C0AE8D2ED53FE457D6971D5D0C41E85E14022E6379EAF5362C1A7B9A7C928FBB8F8B67780D644F8E8A3803D1A87273A2695B594056F9FA5BED34ED38ED99A9349DA9568EF2D416E24A30401F85BE4372069FA9D8760348331E81C2DC70A312DB0BA6D34501EEF4F60809416A103BF6F7083C7E64DEE4BFB459FE507CC42FC45189479E9E408333439890BE580F8A58D00CABEE1B0D6D6CFA54857EC06799FCE7BB182917BB517042321874FB69E0886BC681F9073C07281402E097D108C735FD84AF83CC5C0C36845737BCF5A6192FA11A3DC
7.1) generation of encrypted_data

Generated payload (excluding transport headers/trailers):

0000 | 54 B6 43 66 90 1B A6 09 42 DD 01 BE 9E 03 34 D1
0010 | 59 BC 67 B6 3C A5 BC 7D CD 71 5C D1 8B AF 8F 5D
0020 | F5 CD 21 A2 00 00 00 00 00 00 00 00 FE 00 01 00
0030 | 7B F8 87 5C 7A 40 EA AA 21 94 1F A2 0A CC 09 09
0040 | 54 E4 2F C4 2F 6F 5A 79 96 A4 EC 18 7D 84 E3 49
0050 | 08 37 2D B6 33 73 BD BC C7 9B C3 9D B0 4C 0A E8
0060 | D2 ED 53 FE 45 7D 69 71 D5 D0 C4 1E 85 E1 40 22
0070 | E6 37 9E AF 53 62 C1 A7 B9 A7 C9 28 FB B8 F8 B6
0080 | 77 80 D6 44 F8 E8 A3 80 3D 1A 87 27 3A 26 95 B5
0090 | 94 05 6F 9F A5 BE D3 4E D3 8E D9 9A 93 49 DA 95
00A0 | 68 EF 2D 41 6E 24 A3 04 01 F8 5B E4 37 20 69 FA
00B0 | 9D 87 60 34 83 31 E8 1C 2D C7 0A 31 2D B0 BA 6D
00C0 | 34 50 1E EF 4F 60 80 94 16 A1 03 BF 6F 70 83 C7
00D0 | E6 4D EE 4B FB 45 9F E5 07 CC 42 FC 45 18 94 79
00E0 | E9 E4 08 33 34 39 89 0B E5 80 F8 A5 8D 00 CA BE
00F0 | E1 B0 D6 D6 CF A5 48 57 EC 06 79 9F CE 7B B1 82
0100 | 91 7B B5 17 04 23 21 87 4F B6 9E 08 86 BC 68 1F
0110 | 90 73 C0 72 81 40 2E 09 7D 10 8C 73 5F D8 4A F8
0120 | 3C C5 C0 C3 68 45 73 7B CF 5A 61 92 FA 11 A3 DC

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 901BA60942DD01BE9E0334D159BC67B6 Value generated by client in Step 1
server_nonce 20, 16 3CA5BC7DCD715CD18BAF8F5DF5CD21A2 Value received from server in Step 2
g_b 36, 260 FE0001007BF8875C7A40EAAA21941FA2 0ACC090954E42FC42F6F5A7996A4EC18 7D84E34908372DB63373BDBCC79BC39D B04C0AE8D2ED53FE457D6971D5D0C41E 85E14022E6379EAF5362C1A7B9A7C928 FBB8F8B67780D644F8E8A3803D1A8727 3A2695B594056F9FA5BED34ED38ED99A 9349DA9568EF2D416E24A30401F85BE4 372069FA9D8760348331E81C2DC70A31 2DB0BA6D34501EEF4F60809416A103BF 6F7083C7E64DEE4BFB459FE507CC42FC 45189479E9E408333439890BE580F8A5 8D00CABEE1B0D6D6CFA54857EC06799F CE7BB182917BB517042321874FB69E08 86BC681F9073C07281402E097D108C73 5FD84AF83CC5C0C36845737BCF5A6192
FA11A3DC
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 = 54B64366901BA60942DD01BE9E0334D159BC67B63CA5BC7DCD715CD18BAF8F5DF5CD21A20000000000000000FE0001007BF8875C7A40EAAA21941FA20ACC090954E42FC42F6F5A7996A4EC187D84E34908372DB63373BDBCC79BC39DB04C0AE8D2ED53FE457D6971D5D0C41E85E14022E6379EAF5362C1A7B9A7C928FBB8F8B67780D644F8E8A3803D1A87273A2695B594056F9FA5BED34ED38ED99A9349DA9568EF2D416E24A30401F85BE4372069FA9D8760348331E81C2DC70A312DB0BA6D34501EEF4F60809416A103BF6F7083C7E64DEE4BFB459FE507CC42FC45189479E9E408333439890BE580F8A58D00CABEE1B0D6D6CFA54857EC06799FCE7BB182917BB517042321874FB69E0886BC681F9073C07281402E097D108C735FD84AF83CC5C0C36845737BCF5A6192FA11A3DC
padding = C50B526EB83C76D736951E95
tmp_aes_key = 262B0B32E662DB938A1763E82BDBF170FF80D72BBCE11F71C492CCE21CF90226
tmp_aes_iv = 62ED4104CB25FBF9E5261AC9187ECA573078D8F8C2230F192DD42C392EE06E42

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

The length of the final string is 336 bytes.

7.2) set_client_DH_params query

Sent payload (excluding transport headers/trailers):

0000 | 00 00 00 00 00 00 00 00 24 FA 05 00 FB EC 0E 6A
0010 | 78 01 00 00 1F 5F 04 F5 90 1B A6 09 42 DD 01 BE
0020 | 9E 03 34 D1 59 BC 67 B6 3C A5 BC 7D CD 71 5C D1
0030 | 8B AF 8F 5D F5 CD 21 A2 FE 50 01 00 D1 88 9A 2D
0040 | 59 6A 37 19 89 E4 8F 36 6A AA F7 B8 2F D6 20 1D
0050 | 75 10 01 9C 2D AB 86 B2 8A 26 CA B5 D2 EE 5B 1A
0060 | DD 50 2A D2 37 28 3A 43 1F 87 62 6F 72 42 1F FA
0070 | 9C 47 93 11 86 BD B0 AD 6A F5 00 28 C4 96 99 00
0080 | 7F B8 94 3A F6 FB 5D FE 73 DC 74 BC 22 19 90 1F
0090 | 2D B1 C6 60 BD BD 31 60 8B 45 59 29 39 72 35 1B
00A0 | 68 30 5C FE 12 08 15 B6 F9 FC B6 77 15 B2 2A 91
00B0 | D2 04 BF 3E 20 CE 14 69 41 BF 22 54 90 26 D9 64
00C0 | A2 92 70 6D 68 37 48 F7 17 E8 56 06 5D E7 30 21
00D0 | 89 A2 A7 7B FB 52 CF B0 89 E5 9F BE 87 B7 E5 C9
00E0 | F7 18 E2 01 28 73 8A 47 9A 04 02 7E 8C 75 50 CD
00F0 | 39 CF E2 09 D5 1C 80 3A C7 54 4B F2 F4 E9 6E F0
0100 | D5 54 9A E1 34 BE 1B A1 15 4A 82 45 B6 B9 62 DC
0110 | 26 F0 D1 8B 26 02 89 01 F3 86 83 84 73 1C 05 6E
0120 | 73 58 CC EB 5D D7 DE 40 5D D6 83 ED F9 91 40 DB
0130 | 60 8F 3C C8 45 63 4D 01 2F A6 C9 A6 17 5F 31 D6
0140 | 60 BE 20 E3 FB D3 F0 E8 E3 06 DA 0E 43 1B 61 2F
0150 | F8 30 74 94 79 65 BC CE B2 6B 78 0B F9 0D 26 D9
0160 | 1C 1D A7 AA 99 45 EE DF EC 71 C5 CE 48 F6 B0 BB
0170 | BD 00 C0 A3 3F 89 F2 00 0A CD F8 E0 C3 F8 9B EE
0180 | 7A AF 4E 07 DF 31 AF 52 93 44 7A C2

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 24FA0500FBEC0E6A 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 901BA60942DD01BE9E0334D159BC67B6 Value generated by client in Step 1
server_nonce 40, 16 3CA5BC7DCD715CD18BAF8F5DF5CD21A2 Value received from server in Step 2
encrypted_data 56, 340 FE500100D1889A2D596A371989E48F36 6AAAF7B82FD6201D7510019C2DAB86B2 8A26CAB5D2EE5B1ADD502AD237283A43 1F87626F72421FFA9C47931186BDB0AD 6AF50028C49699007FB8943AF6FB5DFE 73DC74BC2219901F2DB1C660BDBD3160 8B4559293972351B68305CFE120815B6 F9FCB67715B22A91D204BF3E20CE1469 41BF22549026D964A292706D683748F7 17E856065DE7302189A2A77BFB52CFB0 89E59FBE87B7E5C9F718E20128738A47 9A04027E8C7550CD39CFE209D51C803A C7544BF2F4E96EF0D5549AE134BE1BA1 154A8245B6B962DC26F0D18B26028901 F3868384731C056E7358CCEB5DD7DE40 5DD683EDF99140DB608F3CC845634D01 2FA6C9A6175F31D660BE20E3FBD3F0E8 E306DA0E431B612FF83074947965BCCE B26B780BF90D26D91C1DA7AA9945EEDF EC71C5CE48F6B0BBBD00C0A33F89F200 0ACDF8E0C3F89BEE7AAF4E07DF31AF52
93447AC2
Encrypted client_DH_inner_data generated previously, serialized as a TL byte string
8) Auth key generation

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

auth_key = A88A5C6C40273CEC7538EE147AC93B98CE1BCCCC4013569C87EFF41727EFA60B9E9A6E24FBC0BB1B557D4428DA835FD5FE13E50957975CDF8154AE04FD4C7079FB08AB9AC7E58A953A0B58A9044EE4DC05C140A0091AA5331CDE82FDE8E69FEE24CF843DC336792052A44B945141285EFAD64494F1DB63B14EBDF35CBE8E9A0ED467BBA5F68C148B35120F1818D72F549458EA18E3CF357FAF6438C93E78B6CC3B9EAB1B81940759B24940E52CCFEE24CCF7CBEA92D3794ECC4F6BF22E43B5FC83359976AB30BE8819A45F9E3EB94ECAF78863852D7A8FE6E8CF3B5CAE58C4C651D254C516E4D8BDADCCE1070786A24CC622ED413A586B371C2C257EE03FA5D0
9) Final server reply

The server verifies and confirms that auth_key_hash is unique: since it's unique, it replies with the following:

Received payload (excluding transport headers/trailers):

0000 | 00 00 00 00 00 00 00 00 01 C4 72 7F FD EC 0E 6A
0010 | 34 00 00 00 34 F7 CB 3B 90 1B A6 09 42 DD 01 BE
0020 | 9E 03 34 D1 59 BC 67 B6 3C A5 BC 7D CD 71 5C D1
0030 | 8B AF 8F 5D F5 CD 21 A2 D2 CD 79 DB A1 18 5E 3B
0040 | F2 E4 E3 A4 6E F1 01 A1

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 01C4727FFDEC0E6A 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 901BA60942DD01BE9E0334D159BC67B6 Value generated by client in Step 1
server_nonce 40, 16 3CA5BC7DCD715CD18BAF8F5DF5CD21A2 Value received from server in Step 2
new_nonce_hash1 56, 16 D2CD79DBA1185E3BF2E4E3A46EF101A1 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.