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 18 1D 06 00 89 0C EB 65
0010 | 14 00 00 00 F1 8E 7E BE 6C 5D 01 83 C0 9B 3D 4C
0020 | 65 0C 7A 02 E4 D8 BD F8
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 | 181D0600890CEB65 |
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 | 6C5D0183C09B3D4C650C7A02E4D8BDF8 |
Random number |
Received payload (excluding transport headers/trailers):
0000 | 00 00 00 00 00 00 00 00 01 B4 BF 94 89 0C EB 65
0010 | B0 00 00 00 63 24 16 05 6C 5D 01 83 C0 9B 3D 4C
0020 | 65 0C 7A 02 E4 D8 BD F8 F3 9F 03 F1 56 5D 6D 00
0030 | 28 51 C6 FC AC 8A CD 0D 08 22 0D C2 2C A4 0D 5C
0040 | A7 00 00 00 15 C4 B5 1C 03 00 00 00 A5 B7 F7 09
0050 | 35 5F C3 0B 21 6B E8 6C 02 2B B4 C3 85 FD 64 DE
0060 | 85 1D 9D D0
Payload (de)serialization:
resPQ#05162463 nonce:int128 server_nonce:int128 pq:string server_public_key_fingerprints:Vector<strlong> = ResPQ;
Parameter | Offset, Length in bytes | Value | Description |
---|---|---|---|
auth_key_id | 0, 8 | 0000000000000000 |
0 since the message is in plain text |
message_id | 8, 8 | 01B4BF94890CEB65 |
Message ID generated as specified here » (unixtime() << 32) + (N*4) |
message_length | 16, 4 | B0000000 (176 in decimal) |
Message body length |
%(resPQ) | 20, 4 | 63241605 |
resPQ constructor number from TL schema |
nonce | 24, 16 | 6C5D0183C09B3D4C650C7A02E4D8BDF8 |
Value generated by client in Step 1 |
server_nonce | 40, 16 | F39F03F1565D6D002851C6FCAC8ACD0D |
Server-generated random number |
pq | 56, 12 | 08220DC22CA40D5CA7000000 TL byte deserialization => bigendian conversion to decimal => 2453830868973477031 |
Single-byte prefix denoting length, an 8-byte string, and three bytes of padding |
%(Vector strlong) | 68, 4 | 15c4b51c |
Vector t constructor number from TL schema |
count | 72, 4 | 03000000 |
Number of elements in server_public_key_fingerprints |
server_public_key_fingerprints[0] | 76, 8 | A5B7F709355FC30B |
64 lower-order bits of SHA1(server_public_key) |
server_public_key_fingerprints[1] | 84, 8 | 216BE86C022BB4C3 |
64 lower-order bits of SHA1(server_public_key) |
server_public_key_fingerprints[2] | 92, 8 | 85FD64DE851D9DD0 |
64 lower-order bits of SHA1(server_public_key) |
In our case, the client only has the following public keys, with the following fingerprints:
85FD64DE851D9DD0
Let's choose the only matching key, the one with fingerprint equal to 85FD64DE851D9DD0
.
pq = 2453830868973477031
Decompose into 2 prime cofactors p < q
: 2453830868973477031 = 1343866633 * 1825948207
p = 1343866633
q = 1825948207
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 22 0D C2 2C A4 0D 5C A7 00 00 00
0010 | 04 50 19 C7 09 00 00 00 04 6C D5 C2 2F 00 00 00
0020 | 6C 5D 01 83 C0 9B 3D 4C 65 0C 7A 02 E4 D8 BD F8
0030 | F3 9F 03 F1 56 5D 6D 00 28 51 C6 FC AC 8A CD 0D
0040 | 2D 1F 97 69 1A D9 39 B4 94 C3 01 53 E1 9A A2 61
0050 | FB 11 10 FF 51 D2 5D 56 06 34 70 CA D9 8B 7D 1D
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 | 08220DC22CA40D5CA7000000 TL byte deserialization => bigendian conversion to decimal => 2453830868973477031 |
Single-byte prefix denoting length, 8-byte string, and three bytes of padding |
p | 16, 8 | 045019C709000000 TL byte deserialization => bigendian conversion to decimal => 1343866633 |
First prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding |
q | 24, 8 | 046CD5C22F000000 TL byte deserialization => bigendian conversion to decimal => 1825948207 |
Second prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding |
nonce | 32, 16 | 6C5D0183C09B3D4C650C7A02E4D8BDF8 |
Value generated by client in Step 1 |
server_nonce | 48, 16 | F39F03F1565D6D002851C6FCAC8ACD0D |
Value received from server in Step 2 |
new_nonce | 64, 32 | 2D1F97691AD939B494C30153E19AA261 FB1110FF51D25D56063470CAD98B7D1D |
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 = 955FF5A908220DC22CA40D5CA7000000045019C709000000046CD5C22F0000006C5D0183C09B3D4C650C7A02E4D8BDF8F39F03F1565D6D002851C6FCAC8ACD0D2D1F97691AD939B494C30153E19AA261FB1110FF51D25D56063470CAD98B7D1D02000000
random_padding_bytes = 4347A0F58FFA3C09FD35129D919DE5F28204BB1881B4DFD74F34E8D37F1B2B174B8080BDD94DB34876588957B1A27EB6A4772FF102569EF27B2E578F3EF0B687B25025A6F22D214797C028053702E7E327622A09BBFCE461F08E17AB
And this is the output:
encrypted_data = E29CDFF0C375F9AA616187FCD985672C5DC7854BEAF2DCF07B1BDF7E51DA27CB15CD1F5A8DA506C6C877334ED1A148B09D5322FA4F066B502996B4D483D56A2DA40F253CC65F3EE4B0D3D778CB716DA0E710D57EB9FF959A4D3D6A557329CC0E01F74127B7F6B99DAC0E63E44538CF6F3B7FD8B076DC13DDECF55CE62B33F7928B3301870860690F1E15541BBE3CE1F2995D91C6CA352BAB250D06B6FA0F2A095B07009379108B37FFF3BBF01E119449BADDADF175411DA2E5E33C849BE410DCAEF6CE325A33B9F602E064EE47EDDD1C083E17CF8E0465EA838C98535CFC5043C754BF3B1954DED2140FB28FA523C54727F1DEE9544673EB1B82ABB53F567A60
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 F4 F2 09 00 89 0C EB 65
0010 | 40 01 00 00 BE E4 12 D7 6C 5D 01 83 C0 9B 3D 4C
0020 | 65 0C 7A 02 E4 D8 BD F8 F3 9F 03 F1 56 5D 6D 00
0030 | 28 51 C6 FC AC 8A CD 0D 04 50 19 C7 09 00 00 00
0040 | 04 6C D5 C2 2F 00 00 00 85 FD 64 DE 85 1D 9D D0
0050 | FE 00 01 00 E2 9C DF F0 C3 75 F9 AA 61 61 87 FC
0060 | D9 85 67 2C 5D C7 85 4B EA F2 DC F0 7B 1B DF 7E
0070 | 51 DA 27 CB 15 CD 1F 5A 8D A5 06 C6 C8 77 33 4E
0080 | D1 A1 48 B0 9D 53 22 FA 4F 06 6B 50 29 96 B4 D4
0090 | 83 D5 6A 2D A4 0F 25 3C C6 5F 3E E4 B0 D3 D7 78
00A0 | CB 71 6D A0 E7 10 D5 7E B9 FF 95 9A 4D 3D 6A 55
00B0 | 73 29 CC 0E 01 F7 41 27 B7 F6 B9 9D AC 0E 63 E4
00C0 | 45 38 CF 6F 3B 7F D8 B0 76 DC 13 DD EC F5 5C E6
00D0 | 2B 33 F7 92 8B 33 01 87 08 60 69 0F 1E 15 54 1B
00E0 | BE 3C E1 F2 99 5D 91 C6 CA 35 2B AB 25 0D 06 B6
00F0 | FA 0F 2A 09 5B 07 00 93 79 10 8B 37 FF F3 BB F0
0100 | 1E 11 94 49 BA DD AD F1 75 41 1D A2 E5 E3 3C 84
0110 | 9B E4 10 DC AE F6 CE 32 5A 33 B9 F6 02 E0 64 EE
0120 | 47 ED DD 1C 08 3E 17 CF 8E 04 65 EA 83 8C 98 53
0130 | 5C FC 50 43 C7 54 BF 3B 19 54 DE D2 14 0F B2 8F
0140 | A5 23 C5 47 27 F1 DE E9 54 46 73 EB 1B 82 AB B5
0150 | 3F 56 7A 60
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 | F4F20900890CEB65 |
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 | 6C5D0183C09B3D4C650C7A02E4D8BDF8 |
Value generated by client in Step 1 |
server_nonce | 40, 16 | F39F03F1565D6D002851C6FCAC8ACD0D |
Value received from server in Step 2 |
p | 56, 8 | 045019C709000000 TL byte deserialization => bigendian conversion to decimal => 1343866633 |
First prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding |
q | 64, 8 | 046CD5C22F000000 TL byte deserialization => bigendian conversion to decimal => 1825948207 |
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 | FE000100E29CDFF0C375F9AA616187FC D985672C5DC7854BEAF2DCF07B1BDF7E 51DA27CB15CD1F5A8DA506C6C877334E D1A148B09D5322FA4F066B502996B4D4 83D56A2DA40F253CC65F3EE4B0D3D778 CB716DA0E710D57EB9FF959A4D3D6A55 7329CC0E01F74127B7F6B99DAC0E63E4 4538CF6F3B7FD8B076DC13DDECF55CE6 2B33F7928B3301870860690F1E15541B BE3CE1F2995D91C6CA352BAB250D06B6 FA0F2A095B07009379108B37FFF3BBF0 1E119449BADDADF175411DA2E5E33C84 9BE410DCAEF6CE325A33B9F602E064EE 47EDDD1C083E17CF8E0465EA838C9853 5CFC5043C754BF3B1954DED2140FB28F A523C54727F1DEE9544673EB1B82ABB5 3F567A60 |
Value generated above |
Received payload (excluding transport headers/trailers):
0000 | 00 00 00 00 00 00 00 00 01 64 78 42 8A 0C EB 65
0010 | DC 02 00 00 5C 07 E8 D0 6C 5D 01 83 C0 9B 3D 4C
0020 | 65 0C 7A 02 E4 D8 BD F8 F3 9F 03 F1 56 5D 6D 00
0030 | 28 51 C6 FC AC 8A CD 0D FE 50 02 00 FC 5B 35 4A
0040 | 74 FF 07 4F 47 36 CD 0C 00 15 17 6F 2F 85 8D 3A
0050 | 2D FC 31 74 2A 4B DC 67 CD 55 FF 1E 0B 1C E7 5D
0060 | 39 2A F5 7B D8 C4 A0 B9 00 8C 9B 8D C2 20 B8 67
0070 | 53 0C CB C2 BB 5F 74 91 09 3C 3B CD 51 F2 7E 71
0080 | AD E0 10 ED 22 A4 F6 16 71 D3 5E AB 57 61 8C 0C
0090 | 1A 35 99 8F C1 4A 91 7C CD 6C 63 C8 3E A3 36 EA
00A0 | 9C 40 16 48 7D 9A 18 DB 4F DC 65 0C A8 DF F7 F3
00B0 | FC 8B 78 D5 0E DA FE 30 F2 01 52 AA 2F EB 0C 14
00C0 | C1 20 38 8E 0B 28 EC 8E 3D 4B 49 05 A7 96 64 FE
00D0 | 99 7C 8E 4A 43 52 32 9A E0 0B 62 84 F7 38 2C DA
00E0 | 1B 19 E5 36 EE 68 6E 90 3D 82 13 B5 D4 CD 8E 2B
00F0 | E0 2B 3E 98 83 92 A7 3B 7B F8 FB 7B 02 82 EA 85
0100 | 3F 5C EF 28 2C 8F 1B DB 7D 46 4C DC 09 54 63 B7
0110 | A7 E9 87 87 94 26 B3 E6 6E 8A 39 EE 8A 0A D5 94
0120 | AC 87 AD 5E 4A 38 E4 07 FE D3 E7 0E B5 30 0A AE
0130 | 05 87 4E 0E 81 F2 24 E2 F5 7C 37 0F 48 48 78 90
0140 | 5F 7A 04 35 EC 4F F0 6E 47 72 23 16 3D AA E0 7F
0150 | AE C5 FB 3B 64 48 AD 9C 38 90 FB E0 1A 95 7F 8C
0160 | DD 37 83 CD AF 78 AC 60 68 4E F4 C9 A0 7D E2 21
0170 | 1F F9 C1 86 5F 74 5E 4A 4A 2C 56 74 7E 49 63 47
0180 | 35 64 A1 98 40 C1 82 66 9C FE 84 63 A0 37 6E 3F
0190 | B5 FB B0 47 DA 0B 87 C1 88 A5 B3 26 33 CF 55 EE
01A0 | 1B D9 35 B5 6B F8 0E 44 77 B1 84 6A 9C B2 79 50
01B0 | 3E 6C 44 EB 00 91 B0 EC A1 08 0E ED 47 44 CF 55
01C0 | 89 B8 92 6C 5C 8B 6E 78 B2 14 B7 46 83 4E B0 7C
01D0 | DB 37 B3 F3 C3 7D E7 BD F7 28 65 5B 4C 6D 32 E7
01E0 | D9 F8 A2 84 05 62 29 9D 10 32 2C 29 D8 03 13 EA
01F0 | 17 A2 8B 0C 86 85 A4 26 F7 0E FE BA 8D 57 EE D1
0200 | B7 E6 0D 11 17 BF A3 F9 49 B1 10 CB E2 08 54 C2
0210 | F1 AB 4C 37 A0 91 60 08 AB 20 63 B6 75 E2 32 97
0220 | 9B D9 94 83 69 57 A1 86 1B CD 63 CE 8A C2 D1 EE
0230 | 99 97 DC 48 F5 4F 68 F4 C1 83 85 D4 47 A9 42 83
0240 | 91 A2 C7 77 13 FE 4C C7 5B 92 1C 7C 2E BA A2 80
0250 | 16 C5 40 12 8B 17 9B F5 63 27 90 27 3E F1 64 7F
0260 | AA 5B 98 27 DD 89 C2 9D 61 ED DD A7 68 E8 AF C4
0270 | F0 4F BA 8B 02 5E F4 B4 45 1C 71 DB 63 26 52 92
0280 | 84 27 BE 66 B6 F1 FE 0A 88 94 3B 2F
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 | 016478428A0CEB65 |
Message ID generated as specified here » (unixtime() << 32) + (N*4) |
message_length | 16, 4 | DC020000 (732 in decimal) |
Message body length |
%(server_DH_params_ok) | 20, 4 | 5c07e8d0 |
server_DH_params_ok constructor number from TL schema |
nonce | 24, 16 | 6C5D0183C09B3D4C650C7A02E4D8BDF8 |
Value generated by client in Step 1 |
server_nonce | 40, 16 | F39F03F1565D6D002851C6FCAC8ACD0D |
Value received from server in Step 2 |
encrypted_answer | 56, 596 | FE500200FC5B354A74FF074F4736CD0C 0015176F2F858D3A2DFC31742A4BDC67 CD55FF1E0B1CE75D392AF57BD8C4A0B9 008C9B8DC220B867530CCBC2BB5F7491 093C3BCD51F27E71ADE010ED22A4F616 71D35EAB57618C0C1A35998FC14A917C CD6C63C83EA336EA9C4016487D9A18DB 4FDC650CA8DFF7F3FC8B78D50EDAFE30 F20152AA2FEB0C14C120388E0B28EC8E 3D4B4905A79664FE997C8E4A4352329A E00B6284F7382CDA1B19E536EE686E90 3D8213B5D4CD8E2BE02B3E988392A73B 7BF8FB7B0282EA853F5CEF282C8F1BDB 7D464CDC095463B7A7E987879426B3E6 6E8A39EE8A0AD594AC87AD5E4A38E407 FED3E70EB5300AAE05874E0E81F224E2 F57C370F484878905F7A0435EC4FF06E 477223163DAAE07FAEC5FB3B6448AD9C 3890FBE01A957F8CDD3783CDAF78AC60 684EF4C9A07DE2211FF9C1865F745E4A 4A2C56747E4963473564A19840C18266 9CFE8463A0376E3FB5FBB047DA0B87C1 88A5B32633CF55EE1BD935B56BF80E44 77B1846A9CB279503E6C44EB0091B0EC A1080EED4744CF5589B8926C5C8B6E78 B214B746834EB07CDB37B3F3C37DE7BD F728655B4C6D32E7D9F8A2840562299D 10322C29D80313EA17A28B0C8685A426 F70EFEBA8D57EED1B7E60D1117BFA3F9 49B110CBE20854C2F1AB4C37A0916008 AB2063B675E232979BD994836957A186 1BCD63CE8AC2D1EE9997DC48F54F68F4 C18385D447A9428391A2C77713FE4CC7 5B921C7C2EBAA28016C540128B179BF5 632790273EF1647FAA5B9827DD89C29D 61EDDDA768E8AFC4F04FBA8B025EF4B4 451C71DB632652928427BE66B6F1FE0A 88943B2F |
See below |
Decrypt encrypted_answer
using the reverse of the process specified in step 6:
encrypted_answer = FC5B354A74FF074F4736CD0C0015176F2F858D3A2DFC31742A4BDC67CD55FF1E0B1CE75D392AF57BD8C4A0B9008C9B8DC220B867530CCBC2BB5F7491093C3BCD51F27E71ADE010ED22A4F61671D35EAB57618C0C1A35998FC14A917CCD6C63C83EA336EA9C4016487D9A18DB4FDC650CA8DFF7F3FC8B78D50EDAFE30F20152AA2FEB0C14C120388E0B28EC8E3D4B4905A79664FE997C8E4A4352329AE00B6284F7382CDA1B19E536EE686E903D8213B5D4CD8E2BE02B3E988392A73B7BF8FB7B0282EA853F5CEF282C8F1BDB7D464CDC095463B7A7E987879426B3E66E8A39EE8A0AD594AC87AD5E4A38E407FED3E70EB5300AAE05874E0E81F224E2F57C370F484878905F7A0435EC4FF06E477223163DAAE07FAEC5FB3B6448AD9C3890FBE01A957F8CDD3783CDAF78AC60684EF4C9A07DE2211FF9C1865F745E4A4A2C56747E4963473564A19840C182669CFE8463A0376E3FB5FBB047DA0B87C188A5B32633CF55EE1BD935B56BF80E4477B1846A9CB279503E6C44EB0091B0ECA1080EED4744CF5589B8926C5C8B6E78B214B746834EB07CDB37B3F3C37DE7BDF728655B4C6D32E7D9F8A2840562299D10322C29D80313EA17A28B0C8685A426F70EFEBA8D57EED1B7E60D1117BFA3F949B110CBE20854C2F1AB4C37A0916008AB2063B675E232979BD994836957A1861BCD63CE8AC2D1EE9997DC48F54F68F4C18385D447A9428391A2C77713FE4CC75B921C7C2EBAA28016C540128B179BF5632790273EF1647FAA5B9827DD89C29D61EDDDA768E8AFC4F04FBA8B025EF4B4451C71DB632652928427BE66B6F1FE0A88943B2F
tmp_aes_key = D67A9AF27A626BEB5A05876F54041BEB5B740B5AD508AFF47098B475BFF245C9
tmp_aes_iv = 633E1706BCD8F7B53618C96E9156EA9D01C547EE97A967AFC46D7AF92D1F9769
Yielding:
answer_with_hash = 3CEEF63E6429077AC0AF699997900135D70CBADEBA0D89B56C5D0183C09B3D4C650C7A02E4D8BDF8F39F03F1565D6D002851C6FCAC8ACD0D03000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE0001006039629EBA52516DC5B01C7C7F28BE83F751F923A88085CC05C25F388E6031FFBDC0821E95B2E859E0E1FB132F6CC448DF87D23823055E13B4F8A9F1656B71424521EE9C0B806CF8FEB8A3331BA08694FD538A92A50F6A15382ED36D15EB3DB939232FC8965BA089AC4A6E03F5187E5BB1E2E80B559B944B613A588A61F984C177D453EFA668B93F97AB8819018D937C9BFAFF671C115D710EC9784B2DD1F52628466E5B070E30A43CFF773713383359D49C41330AFC2A6EAB26393E72E102A5CDF6C7E26648D9902B75B39CD4CC4D2F6E2E9B38B54FFF23292894B6BD403EFE742A88EAF2742DD50234A8D2BE05E7D506174EB47E11EEA074A0FC226D4D9D358A0CEB6527AF3FBAABC99484
answer = BA0D89B56C5D0183C09B3D4C650C7A02E4D8BDF8F39F03F1565D6D002851C6FCAC8ACD0D03000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE0001006039629EBA52516DC5B01C7C7F28BE83F751F923A88085CC05C25F388E6031FFBDC0821E95B2E859E0E1FB132F6CC448DF87D23823055E13B4F8A9F1656B71424521EE9C0B806CF8FEB8A3331BA08694FD538A92A50F6A15382ED36D15EB3DB939232FC8965BA089AC4A6E03F5187E5BB1E2E80B559B944B613A588A61F984C177D453EFA668B93F97AB8819018D937C9BFAFF671C115D710EC9784B2DD1F52628466E5B070E30A43CFF773713383359D49C41330AFC2A6EAB26393E72E102A5CDF6C7E26648D9902B75B39CD4CC4D2F6E2E9B38B54FFF23292894B6BD403EFE742A88EAF2742DD50234A8D2BE05E7D506174EB47E11EEA074A0FC226D4D9D358A0CEB6527AF3FBAABC99484
Generated payload (excluding transport headers/trailers):
0000 | BA 0D 89 B5 6C 5D 01 83 C0 9B 3D 4C 65 0C 7A 02
0010 | E4 D8 BD F8 F3 9F 03 F1 56 5D 6D 00 28 51 C6 FC
0020 | AC 8A CD 0D 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 | 60 39 62 9E BA 52 51 6D C5 B0 1C 7C 7F 28 BE 83
0140 | F7 51 F9 23 A8 80 85 CC 05 C2 5F 38 8E 60 31 FF
0150 | BD C0 82 1E 95 B2 E8 59 E0 E1 FB 13 2F 6C C4 48
0160 | DF 87 D2 38 23 05 5E 13 B4 F8 A9 F1 65 6B 71 42
0170 | 45 21 EE 9C 0B 80 6C F8 FE B8 A3 33 1B A0 86 94
0180 | FD 53 8A 92 A5 0F 6A 15 38 2E D3 6D 15 EB 3D B9
0190 | 39 23 2F C8 96 5B A0 89 AC 4A 6E 03 F5 18 7E 5B
01A0 | B1 E2 E8 0B 55 9B 94 4B 61 3A 58 8A 61 F9 84 C1
01B0 | 77 D4 53 EF A6 68 B9 3F 97 AB 88 19 01 8D 93 7C
01C0 | 9B FA FF 67 1C 11 5D 71 0E C9 78 4B 2D D1 F5 26
01D0 | 28 46 6E 5B 07 0E 30 A4 3C FF 77 37 13 38 33 59
01E0 | D4 9C 41 33 0A FC 2A 6E AB 26 39 3E 72 E1 02 A5
01F0 | CD F6 C7 E2 66 48 D9 90 2B 75 B3 9C D4 CC 4D 2F
0200 | 6E 2E 9B 38 B5 4F FF 23 29 28 94 B6 BD 40 3E FE
0210 | 74 2A 88 EA F2 74 2D D5 02 34 A8 D2 BE 05 E7 D5
0220 | 06 17 4E B4 7E 11 EE A0 74 A0 FC 22 6D 4D 9D 35
0230 | 8A 0C EB 65
Payload (de)serialization:
server_DH_inner_data#b5890dba nonce:int128 server_nonce:int128 g:int dh_prime:string g_a:string server_time:int = Server_DH_inner_data;
Parameter | Offset, Length in bytes | Value | Description |
---|---|---|---|
%(server_DH_inner_data) | 0, 4 | ba0d89b5 |
server_DH_inner_data constructor number from TL schema |
nonce | 4, 16 | 6C5D0183C09B3D4C650C7A02E4D8BDF8 |
Value generated by client in Step 1 |
server_nonce | 20, 16 | F39F03F1565D6D002851C6FCAC8ACD0D |
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 | FE0001006039629EBA52516DC5B01C7C 7F28BE83F751F923A88085CC05C25F38 8E6031FFBDC0821E95B2E859E0E1FB13 2F6CC448DF87D23823055E13B4F8A9F1 656B71424521EE9C0B806CF8FEB8A333 1BA08694FD538A92A50F6A15382ED36D 15EB3DB939232FC8965BA089AC4A6E03 F5187E5BB1E2E80B559B944B613A588A 61F984C177D453EFA668B93F97AB8819 018D937C9BFAFF671C115D710EC9784B 2DD1F52628466E5B070E30A43CFF7737 13383359D49C41330AFC2A6EAB26393E 72E102A5CDF6C7E26648D9902B75B39C D4CC4D2F6E2E9B38B54FFF23292894B6 BD403EFE742A88EAF2742DD50234A8D2 BE05E7D506174EB47E11EEA074A0FC22 6D4D9D35 |
g_a diffie-hellman parameter |
server_time | 560, 4 | 8A0CEB65 (1709902986 in decimal) |
Server time |
First, generate a secure random 2048-bit number b:
b = 3926B53315738C46D2E423FFB79850E2E379B64D1C5B3C83CDA52239918B87012F35E0AAA6C2F8D49E400DCC9791422AF46EDE0981A4DD725D31D9EAB91C6339BFBCF932A05074ACE182A78F385A72BCD28FF6F83D6BC67CC578F20BDACC27F213D7002B8505D41F538D97DEF151582FEFD432499059672725C202781982214D50E85D6BC462B27991DD3F644BF615805B96AED7FC8E08AB2F64D6F72BCB237C7E615521AC6C6729557E295E40FEA37A20357FF8EAB9CB6E67878D25ABCE71461855F44C14F01142B7965507053E6CDC9AA9DF1523733D53999C6B0AB865D90E7629F26766B5BFFAC67560D5046B67A9A9200D137D9ECE173D6CEC464307FB3D
Then compute g_b = pow(g, b) mod dh_prime
g_b = 1DDC05FBEF7A9710530DAFAA636EA23AC840EF6E4568F46808A5C9C066BE1167EE71D5991672D79B803D6BE374076C3583B55143641F0347E0AD51DEA2C33C787915879FF333ED3BA33A2B58DF37E435910A5462C47F0CFAC658ABFA6020E36188719355D6D5477C93A69F9795EBEF0C43744E5E267579439E0ABC8D15365DE72709B19ECB516D148BB07836AA3BB3B05B4E0A226FC9DCDBE56CAF573D831D4384ECECB7529009E06996DE5F71A3CD1E2614467187C4569098571D90F5B6BD6A59214AD6F073E35A5D2436117F087FA67FC8BE53C1788338342990DE6AE9C08522CA490795B9D4E9E177D228BCDCDA2ABF27904917C2E22C36CD7746FA1F2C53
Generated payload (excluding transport headers/trailers):
0000 | 54 B6 43 66 6C 5D 01 83 C0 9B 3D 4C 65 0C 7A 02
0010 | E4 D8 BD F8 F3 9F 03 F1 56 5D 6D 00 28 51 C6 FC
0020 | AC 8A CD 0D 00 00 00 00 00 00 00 00 FE 00 01 00
0030 | 1D DC 05 FB EF 7A 97 10 53 0D AF AA 63 6E A2 3A
0040 | C8 40 EF 6E 45 68 F4 68 08 A5 C9 C0 66 BE 11 67
0050 | EE 71 D5 99 16 72 D7 9B 80 3D 6B E3 74 07 6C 35
0060 | 83 B5 51 43 64 1F 03 47 E0 AD 51 DE A2 C3 3C 78
0070 | 79 15 87 9F F3 33 ED 3B A3 3A 2B 58 DF 37 E4 35
0080 | 91 0A 54 62 C4 7F 0C FA C6 58 AB FA 60 20 E3 61
0090 | 88 71 93 55 D6 D5 47 7C 93 A6 9F 97 95 EB EF 0C
00A0 | 43 74 4E 5E 26 75 79 43 9E 0A BC 8D 15 36 5D E7
00B0 | 27 09 B1 9E CB 51 6D 14 8B B0 78 36 AA 3B B3 B0
00C0 | 5B 4E 0A 22 6F C9 DC DB E5 6C AF 57 3D 83 1D 43
00D0 | 84 EC EC B7 52 90 09 E0 69 96 DE 5F 71 A3 CD 1E
00E0 | 26 14 46 71 87 C4 56 90 98 57 1D 90 F5 B6 BD 6A
00F0 | 59 21 4A D6 F0 73 E3 5A 5D 24 36 11 7F 08 7F A6
0100 | 7F C8 BE 53 C1 78 83 38 34 29 90 DE 6A E9 C0 85
0110 | 22 CA 49 07 95 B9 D4 E9 E1 77 D2 28 BC DC DA 2A
0120 | BF 27 90 49 17 C2 E2 2C 36 CD 77 46 FA 1F 2C 53
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 | 6C5D0183C09B3D4C650C7A02E4D8BDF8 |
Value generated by client in Step 1 |
server_nonce | 20, 16 | F39F03F1565D6D002851C6FCAC8ACD0D |
Value received from server in Step 2 |
g_b | 36, 260 | FE0001001DDC05FBEF7A9710530DAFAA 636EA23AC840EF6E4568F46808A5C9C0 66BE1167EE71D5991672D79B803D6BE3 74076C3583B55143641F0347E0AD51DE A2C33C787915879FF333ED3BA33A2B58 DF37E435910A5462C47F0CFAC658ABFA 6020E36188719355D6D5477C93A69F97 95EBEF0C43744E5E267579439E0ABC8D 15365DE72709B19ECB516D148BB07836 AA3BB3B05B4E0A226FC9DCDBE56CAF57 3D831D4384ECECB7529009E06996DE5F 71A3CD1E2614467187C4569098571D90 F5B6BD6A59214AD6F073E35A5D243611 7F087FA67FC8BE53C1788338342990DE 6AE9C08522CA490795B9D4E9E177D228 BCDCDA2ABF27904917C2E22C36CD7746 FA1F2C53 |
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 = 54B643666C5D0183C09B3D4C650C7A02E4D8BDF8F39F03F1565D6D002851C6FCAC8ACD0D0000000000000000FE0001001DDC05FBEF7A9710530DAFAA636EA23AC840EF6E4568F46808A5C9C066BE1167EE71D5991672D79B803D6BE374076C3583B55143641F0347E0AD51DEA2C33C787915879FF333ED3BA33A2B58DF37E435910A5462C47F0CFAC658ABFA6020E36188719355D6D5477C93A69F9795EBEF0C43744E5E267579439E0ABC8D15365DE72709B19ECB516D148BB07836AA3BB3B05B4E0A226FC9DCDBE56CAF573D831D4384ECECB7529009E06996DE5F71A3CD1E2614467187C4569098571D90F5B6BD6A59214AD6F073E35A5D2436117F087FA67FC8BE53C1788338342990DE6AE9C08522CA490795B9D4E9E177D228BCDCDA2ABF27904917C2E22C36CD7746FA1F2C53
padding = D1AB41649AEDE24CDBCA70A7
tmp_aes_key = D67A9AF27A626BEB5A05876F54041BEB5B740B5AD508AFF47098B475BFF245C9
tmp_aes_iv = 633E1706BCD8F7B53618C96E9156EA9D01C547EE97A967AFC46D7AF92D1F9769
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 = C0C869F3A61EDF52A8B225272E29F60F285210BBF02753CEA722A48CF940F4E7E4060252F991B8EBC7F9F0BCDE9F061AD4CA836C2B72814BE43B740F4BAA645137DB09776DA20D31C22F50A00CE3F2258F59BACBA2EFFB8D42BEAE51CFD796261DE24CE486471FE7B8CE22E2EA3474019C973AFB610730F903B0A23F50DB7880A0C290F6F55FE00E34A406161150151B1967EBD4896933BD40BA93636F5C9AC89E98CE8B948812B6BBABAF5ABAF3E2C1C67D22DE739F852D578A98A0E23F6362EAC4709764E6F4C7EEFAA0FE3580F5D609E06CDC23B011BEF6D496374EB37BA44B4BDAAED57A25CDD48B59B19CDFA328660D58186DC45C3450DA3FD7DFAE686CDA17744DA85A885C03D084F607520B9A6E50B97F658DE0AA1CA39291B66D3600D880036D6BD09830F05768BB0923FCCA119128B88C1A4481451337915FFAF4905978E04CC7EE7B4C7F7A48BD61B04E44
The length of the final string is 336 bytes.
Sent payload (excluding transport headers/trailers):
0000 | 00 00 00 00 00 00 00 00 A0 58 07 00 8A 0C EB 65
0010 | 78 01 00 00 1F 5F 04 F5 6C 5D 01 83 C0 9B 3D 4C
0020 | 65 0C 7A 02 E4 D8 BD F8 F3 9F 03 F1 56 5D 6D 00
0030 | 28 51 C6 FC AC 8A CD 0D FE 50 01 00 C0 C8 69 F3
0040 | A6 1E DF 52 A8 B2 25 27 2E 29 F6 0F 28 52 10 BB
0050 | F0 27 53 CE A7 22 A4 8C F9 40 F4 E7 E4 06 02 52
0060 | F9 91 B8 EB C7 F9 F0 BC DE 9F 06 1A D4 CA 83 6C
0070 | 2B 72 81 4B E4 3B 74 0F 4B AA 64 51 37 DB 09 77
0080 | 6D A2 0D 31 C2 2F 50 A0 0C E3 F2 25 8F 59 BA CB
0090 | A2 EF FB 8D 42 BE AE 51 CF D7 96 26 1D E2 4C E4
00A0 | 86 47 1F E7 B8 CE 22 E2 EA 34 74 01 9C 97 3A FB
00B0 | 61 07 30 F9 03 B0 A2 3F 50 DB 78 80 A0 C2 90 F6
00C0 | F5 5F E0 0E 34 A4 06 16 11 50 15 1B 19 67 EB D4
00D0 | 89 69 33 BD 40 BA 93 63 6F 5C 9A C8 9E 98 CE 8B
00E0 | 94 88 12 B6 BB AB AF 5A BA F3 E2 C1 C6 7D 22 DE
00F0 | 73 9F 85 2D 57 8A 98 A0 E2 3F 63 62 EA C4 70 97
0100 | 64 E6 F4 C7 EE FA A0 FE 35 80 F5 D6 09 E0 6C DC
0110 | 23 B0 11 BE F6 D4 96 37 4E B3 7B A4 4B 4B DA AE
0120 | D5 7A 25 CD D4 8B 59 B1 9C DF A3 28 66 0D 58 18
0130 | 6D C4 5C 34 50 DA 3F D7 DF AE 68 6C DA 17 74 4D
0140 | A8 5A 88 5C 03 D0 84 F6 07 52 0B 9A 6E 50 B9 7F
0150 | 65 8D E0 AA 1C A3 92 91 B6 6D 36 00 D8 80 03 6D
0160 | 6B D0 98 30 F0 57 68 BB 09 23 FC CA 11 91 28 B8
0170 | 8C 1A 44 81 45 13 37 91 5F FA F4 90 59 78 E0 4C
0180 | C7 EE 7B 4C 7F 7A 48 BD 61 B0 4E 44
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 | A05807008A0CEB65 |
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 | 6C5D0183C09B3D4C650C7A02E4D8BDF8 |
Value generated by client in Step 1 |
server_nonce | 40, 16 | F39F03F1565D6D002851C6FCAC8ACD0D |
Value received from server in Step 2 |
encrypted_data | 56, 340 | FE500100C0C869F3A61EDF52A8B22527 2E29F60F285210BBF02753CEA722A48C F940F4E7E4060252F991B8EBC7F9F0BC DE9F061AD4CA836C2B72814BE43B740F 4BAA645137DB09776DA20D31C22F50A0 0CE3F2258F59BACBA2EFFB8D42BEAE51 CFD796261DE24CE486471FE7B8CE22E2 EA3474019C973AFB610730F903B0A23F 50DB7880A0C290F6F55FE00E34A40616 1150151B1967EBD4896933BD40BA9363 6F5C9AC89E98CE8B948812B6BBABAF5A BAF3E2C1C67D22DE739F852D578A98A0 E23F6362EAC4709764E6F4C7EEFAA0FE 3580F5D609E06CDC23B011BEF6D49637 4EB37BA44B4BDAAED57A25CDD48B59B1 9CDFA328660D58186DC45C3450DA3FD7 DFAE686CDA17744DA85A885C03D084F6 07520B9A6E50B97F658DE0AA1CA39291 B66D3600D880036D6BD09830F05768BB 0923FCCA119128B88C1A448145133791 5FFAF4905978E04CC7EE7B4C7F7A48BD 61B04E44 |
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 = 74C1BCCC199791B64A8A55CA88337D2072B99630263D6D8B84CD192860D90F764C4FC4782DA33326611B7606EB60A82552AEED09FBDA4EAF44FA57D36B22C1085110BCAB8FB0C6582E883E90A60F0CE02B4F249BC76CEBA166BA109AC35CC8317702460F4C64AEA5555963D660FBDEFACF415F08064D149DA32E0406CAC149B1D4B02F544966552D2BD5DAC78B946DEABBA890363350868AA4AF8EE572A8430616B5B977B9E5E79C1139EE0C3902D6533C5446853AA14DCB85C2FBD7BAA5FCD9FD2ED7F203935426BF6831B06C950B404016C430904F18D74A56E8CF3AA8C86E5A69E5429BB314F7A12C485D643A03F48759E4DEC722C1C6EFD698710E6B8003
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 08 02 06 8B 0C EB 65
0010 | A4 00 00 00 34 F7 CB 3B 6C 5D 01 83 C0 9B 3D 4C
0020 | 65 0C 7A 02 E4 D8 BD F8 F3 9F 03 F1 56 5D 6D 00
0030 | 28 51 C6 FC AC 8A CD 0D A0 0A 66 F3 13 69 78 A2
0040 | 68 1E ED 6D E8 21 EF 13
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 | 010802068B0CEB65 |
Message ID generated as specified here » (unixtime() << 32) + (N*4) |
message_length | 16, 4 | A4000000 (164 in decimal) |
Message body length |
%(dh_gen_ok) | 20, 4 | 34f7cb3b |
dh_gen_ok constructor number from TL schema |
nonce | 24, 16 | 6C5D0183C09B3D4C650C7A02E4D8BDF8 |
Value generated by client in Step 1 |
server_nonce | 40, 16 | F39F03F1565D6D002851C6FCAC8ACD0D |
Value received from server in Step 2 |
new_nonce_hash1 | 56, 16 | A00A66F3136978A2681EED6DE821EF13 |
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. |