telegram-crawler/data/web/blogfork.telegram.org/mtproto/samples-auth_key.html
2024-04-22 11:05:10 +00:00

931 lines
49 KiB
HTML

<!DOCTYPE html>
<html class="">
<head>
<meta charset="utf-8">
<title>Auth key generation example</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta property="description" content="A full auth key generation example">
<meta property="og:title" content="Auth key generation example">
<meta property="og:image" content="71a15765997de28d38">
<meta property="og:description" content="A full auth key generation example">
<link rel="icon" type="image/svg+xml" href="/img/website_icon.svg?4">
<link rel="apple-touch-icon" sizes="180x180" href="/img/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/img/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/img/favicon-16x16.png">
<link rel="alternate icon" href="/img/favicon.ico" type="image/x-icon" />
<link href="/css/bootstrap.min.css?3" rel="stylesheet">
<link href="/css/telegram.css?237" rel="stylesheet" media="screen">
<style>
</style>
</head>
<body class="preload">
<div class="dev_page_wrap">
<div class="dev_page_head navbar navbar-static-top navbar-tg">
<div class="navbar-inner">
<div class="container clearfix">
<ul class="nav navbar-nav navbar-right hidden-xs"><li class="navbar-twitter"><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)"><i class="icon icon-twitter"></i><span> Twitter</span></a></li></ul>
<ul class="nav navbar-nav">
<li><a href="//telegram.org/">Home</a></li>
<li class="hidden-xs"><a href="//telegram.org/faq">FAQ</a></li>
<li class="hidden-xs"><a href="//telegram.org/apps">Apps</a></li>
<li class=""><a href="/api">API</a></li>
<li class="active"><a href="/mtproto">Protocol</a></li>
<li class=""><a href="/schema">Schema</a></li>
</ul>
</div>
</div>
</div>
<div class="container clearfix">
<div class="dev_page">
<div id="dev_page_content_wrap" class=" ">
<div class="dev_page_bread_crumbs"><ul class="breadcrumb clearfix"><li><a href="/mtproto" >Mobile Protocol</a></li><i class="icon icon-breadcrumb-divider"></i><li><a href="/mtproto/samples-auth_key" >Auth key generation example</a></li></ul></div>
<h1 id="dev_page_title">Auth key generation example</h1>
<div id="dev_page_content"><!-- scroll_nav -->
<p>In the examples below, the <a href="/mtproto#transport">transport</a> headers are omitted:</p>
<blockquote>
<p>For example, for the <a href="/mtproto/mtproto-transports#abridged">abridged version of the transport »</a>, the client sends <code>0xef</code> as the first byte (<strong>important:</strong> only prior to the very first data packet), then the packet length is encoded with a single byte (<code>0x01-0x7e</code> = data length divided by 4; or <code>0x7f</code> 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 <code>0xef</code>as the first byte).</p>
</blockquote>
<p>Detailed documentation on creating authorization keys is available <a href="/mtproto/auth_key">here »</a>.</p>
<h4><a class="anchor" href="#dh-exchange-initiation" id="dh-exchange-initiation" name="dh-exchange-initiation"><i class="anchor-icon"></i></a>DH exchange initiation</h4>
<h5><a class="anchor" href="#1-client-sends-query-to-server" id="1-client-sends-query-to-server" name="1-client-sends-query-to-server"><i class="anchor-icon"></i></a>1) Client sends query to server</h5>
<!-- start req_pq_multi -->
<p>Sent payload (excluding transport headers/trailers):</p>
<pre><code>0000 | 00 00 00 00 00 00 00 00 D4 72 06 00 50 3D C5 65
0010 | 14 00 00 00 F1 8E 7E BE 40 67 09 F6 12 FA DF BE
0020 | C3 F0 28 9D 0A A6 7E EF</code></pre>
<p>Payload (de)serialization:</p>
<pre><code>req_pq_multi#be7e8ef1 nonce:int128 = ResPQ;</code></pre>
<table class="table">
<thead>
<tr>
<th>Parameter</th>
<th>Offset, Length in bytes</th>
<th>Value</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>auth_key_id</td>
<td>0, 8</td>
<td><code>0000000000000000</code></td>
<td>0 since the message is in plain text</td>
</tr>
<tr>
<td>message_id</td>
<td>8, 8</td>
<td><code>D4720600503DC565</code></td>
<td>Message ID generated as specified <a href="/mtproto/description#message-identifier-msg-id">here »</a> (unixtime() &lt;&lt; 32) + (N*4)</td>
</tr>
<tr>
<td>message_length</td>
<td>16, 4</td>
<td><code>14000000</code> (20 in decimal)</td>
<td>Message body length</td>
</tr>
<tr>
<td>%(req_pq_multi)</td>
<td>20, 4</td>
<td><code>f18e7ebe</code></td>
<td><em>req_pq_multi</em> constructor number from TL schema</td>
</tr>
<tr>
<td>nonce</td>
<td>24, 16</td>
<td><code>406709F612FADFBEC3F0289D0AA67EEF</code></td>
<td>Random number</td>
</tr>
</tbody>
</table>
<!-- end req_pq_multi -->
<h5><a class="anchor" href="#2-server-sends-response-of-the-form" id="2-server-sends-response-of-the-form" name="2-server-sends-response-of-the-form"><i class="anchor-icon"></i></a>2) Server sends response of the form</h5>
<!-- start resPQ -->
<p>Received payload (excluding transport headers/trailers):</p>
<pre><code>0000 | 00 00 00 00 00 00 00 00 01 D8 31 75 50 3D C5 65
0010 | A8 00 00 00 63 24 16 05 40 67 09 F6 12 FA DF BE
0020 | C3 F0 28 9D 0A A6 7E EF E1 1D BC 3B C9 7D 91 A2
0030 | 61 54 F9 32 AF 01 99 43 08 25 65 95 ED B7 76 67
0040 | 97 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</code></pre>
<p>Payload (de)serialization:</p>
<pre><code>resPQ#05162463 nonce:int128 server_nonce:int128 pq:string server_public_key_fingerprints:Vector&lt;strlong&gt; = ResPQ;</code></pre>
<table class="table">
<thead>
<tr>
<th>Parameter</th>
<th>Offset, Length in bytes</th>
<th>Value</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>auth_key_id</td>
<td>0, 8</td>
<td><code>0000000000000000</code></td>
<td>0 since the message is in plain text</td>
</tr>
<tr>
<td>message_id</td>
<td>8, 8</td>
<td><code>01D83175503DC565</code></td>
<td>Message ID generated as specified <a href="/mtproto/description#message-identifier-msg-id">here »</a> (unixtime() &lt;&lt; 32) + (N*4)</td>
</tr>
<tr>
<td>message_length</td>
<td>16, 4</td>
<td><code>A8000000</code> (168 in decimal)</td>
<td>Message body length</td>
</tr>
<tr>
<td>%(resPQ)</td>
<td>20, 4</td>
<td><code>63241605</code></td>
<td><em>resPQ</em> constructor number from TL schema</td>
</tr>
<tr>
<td>nonce</td>
<td>24, 16</td>
<td><code>406709F612FADFBEC3F0289D0AA67EEF</code></td>
<td>Value generated by client in Step 1</td>
</tr>
<tr>
<td>server_nonce</td>
<td>40, 16</td>
<td><code>E11DBC3BC97D91A26154F932AF019943</code></td>
<td>Server-generated random number</td>
</tr>
<tr>
<td>pq</td>
<td>56, 12</td>
<td><code>08256595EDB7766797000000</code><br>TL byte deserialization <br>=&gt; bigendian conversion to decimal<br>=&gt; 2694724800268887959</td>
<td>Single-byte prefix denoting length, an 8-byte string, and three bytes of padding</td>
</tr>
<tr>
<td>%(Vector strlong)</td>
<td>68, 4</td>
<td><code>15c4b51c</code></td>
<td><em>Vector t</em> constructor number from TL schema</td>
</tr>
<tr>
<td>count</td>
<td>72, 4</td>
<td><code>03000000</code></td>
<td>Number of elements in server_public_key_fingerprints</td>
</tr>
<tr>
<td>server_public_key_fingerprints[0]</td>
<td>76, 8</td>
<td><code>A5B7F709355FC30B</code></td>
<td>64 lower-order bits of <code>SHA1(server_public_key)</code></td>
</tr>
<tr>
<td>server_public_key_fingerprints[1]</td>
<td>84, 8</td>
<td><code>216BE86C022BB4C3</code></td>
<td>64 lower-order bits of <code>SHA1(server_public_key)</code></td>
</tr>
<tr>
<td>server_public_key_fingerprints[2]</td>
<td>92, 8</td>
<td><code>85FD64DE851D9DD0</code></td>
<td>64 lower-order bits of <code>SHA1(server_public_key)</code></td>
</tr>
</tbody>
</table>
<!-- end resPQ -->
<p>In our case, the client only has the following public keys, with the following fingerprints:</p>
<!-- start fingerprints -->
<ul>
<li><code>85FD64DE851D9DD0</code></li>
</ul>
<p>Let's choose the only matching key, the one with fingerprint equal to <code>85FD64DE851D9DD0</code>.</p>
<!-- end fingerprints -->
<h4><a class="anchor" href="#proof-of-work" id="proof-of-work" name="proof-of-work"><i class="anchor-icon"></i></a>Proof of work</h4>
<h5><a class="anchor" href="#3-client-decomposes-pq-into-prime-factors-such-that-p-lt-q" id="3-client-decomposes-pq-into-prime-factors-such-that-p-lt-q" name="3-client-decomposes-pq-into-prime-factors-such-that-p-lt-q"><i class="anchor-icon"></i></a>3) Client decomposes pq into prime factors such that p &lt; q.</h5>
<!-- start pq -->
<pre><code>pq = 2694724800268887959</code></pre>
<p>Decompose into 2 prime cofactors <code>p &lt; q</code>: <code>2694724800268887959 = 1513098571 * 1780931429</code></p>
<pre><code>p = 1513098571
q = 1780931429</code></pre>
<!-- end pq -->
<h4><a class="anchor" href="#presenting-proof-of-work-server-authentication" id="presenting-proof-of-work-server-authentication" name="presenting-proof-of-work-server-authentication"><i class="anchor-icon"></i></a>Presenting proof of work; Server authentication</h4>
<h5><a class="anchor" href="#4-encrypted-data-payload-generation" id="4-encrypted-data-payload-generation" name="4-encrypted-data-payload-generation"><i class="anchor-icon"></i></a>4) <code>encrypted_data</code> payload generation</h5>
<p>First of all, generate an <code>encrypted_data</code> payload as follows:</p>
<!-- start p_q_inner_data_dc -->
<p>Generated payload (excluding transport headers/trailers):</p>
<pre><code>0000 | 95 5F F5 A9 08 25 65 95 ED B7 76 67 97 00 00 00
0010 | 04 5A 30 0D 4B 00 00 00 04 6A 26 DB 65 00 00 00
0020 | 40 67 09 F6 12 FA DF BE C3 F0 28 9D 0A A6 7E EF
0030 | E1 1D BC 3B C9 7D 91 A2 61 54 F9 32 AF 01 99 43
0040 | A8 BB C8 49 51 2D AC 6C 67 B6 EF D9 15 7D 6C A7
0050 | 37 7A 17 76 30 7D 84 26 5C 6B E9 BD CF 80 2A C1
0060 | 02 00 00 00</code></pre>
<p>Payload (de)serialization:</p>
<pre><code>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;</code></pre>
<table class="table">
<thead>
<tr>
<th>Parameter</th>
<th>Offset, Length in bytes</th>
<th>Value</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>%(p_q_inner_data_dc)</td>
<td>0, 4</td>
<td><code>955ff5a9</code></td>
<td><em>p_q_inner_data_dc</em> constructor number from TL schema</td>
</tr>
<tr>
<td>pq</td>
<td>4, 12</td>
<td><code>08256595EDB7766797000000</code><br>TL byte deserialization <br>=&gt; bigendian conversion to decimal<br>=&gt; 2694724800268887959</td>
<td>Single-byte prefix denoting length, 8-byte string, and three bytes of padding</td>
</tr>
<tr>
<td>p</td>
<td>16, 8</td>
<td><code>045A300D4B000000</code><br>TL byte deserialization <br>=&gt; bigendian conversion to decimal<br>=&gt; 1513098571</td>
<td>First prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding</td>
</tr>
<tr>
<td>q</td>
<td>24, 8</td>
<td><code>046A26DB65000000</code><br>TL byte deserialization <br>=&gt; bigendian conversion to decimal<br>=&gt; 1780931429</td>
<td>Second prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding</td>
</tr>
<tr>
<td>nonce</td>
<td>32, 16</td>
<td><code>406709F612FADFBEC3F0289D0AA67EEF</code></td>
<td>Value generated by client in Step 1</td>
</tr>
<tr>
<td>server_nonce</td>
<td>48, 16</td>
<td><code>E11DBC3BC97D91A26154F932AF019943</code></td>
<td>Value received from server in Step 2</td>
</tr>
<tr>
<td>new_nonce</td>
<td>64, 32</td>
<td><code>A8BBC849512DAC6C67B6EFD9157D6CA7</code> <code>377A1776307D84265C6BE9BDCF802AC1</code></td>
<td>Client-generated random number</td>
</tr>
<tr>
<td>dc</td>
<td>96, 4</td>
<td><code>02000000</code> (2 in decimal)</td>
<td>DC ID: <code>10000</code> (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.</td>
</tr>
</tbody>
</table>
<!-- end p_q_inner_data_dc -->
<p>The serialization of <em>P_Q_inner_data</em> produces <strong>data</strong>, which is used to generate <strong>encrypted_data</strong> as specified in <a href="/mtproto/auth_key">step 4.1</a>.<br>
These are the inputs to the algorithm specified in <a href="/mtproto/auth_key">step 4.1</a>:</p>
<!-- start p_q_inner_data_input -->
<pre><code>data = 955FF5A908256595EDB7766797000000045A300D4B000000046A26DB65000000406709F612FADFBEC3F0289D0AA67EEFE11DBC3BC97D91A26154F932AF019943A8BBC849512DAC6C67B6EFD9157D6CA7377A1776307D84265C6BE9BDCF802AC102000000
random_padding_bytes = D944BB8347C876177FE03C2562BF4E87258EF147A7815D8853AA4B1065A5A385D0DA7E0B6100FAF55728D04DFC84E7E0D20006E07E1CB036730F5B3209CF85B2365B39DE2CBC56F40B725AD347835E5D1973567ECE8A02CF343D54F7</code></pre>
<!-- end p_q_inner_data_input -->
<p>And this is the output:</p>
<!-- start p_q_inner_data_output -->
<pre><code>encrypted_data = B80632B3F0D1AB28EFAE2CF974C4A2D51A77FCB6DEFD415E1EC284CAB2B5F88D5C4C5B19AFF5E940CE14CCB6A7F340EC88DF7C1F091FB6F7323B047C02DC63212D0DEBE4B3B7A0310E26DB1289CBA24112DF37506C90DEAB797623E4AFF4643D2A921891346BC176C4E1CCE14F64FA59526DD021EFFA428E8F8ACEEB96DBD4729E99BBB26DDDC744D584B732415DFFE20418953F4EAFC81DADE5C6606A1E7FAA3EDB90F36ECF405422C97C360CC31A444B1EEB6C33D62C5802165C72BBC85D1ADBCCD17988DE7F43DA0F340502744B52B196A78EF1ED1372C6EA1232603FDB9C28F7F8783F29098FFD0FE9B066C460ECBA0A2962B82398C1B32D3DCB3BC3A59E</code></pre>
<!-- end p_q_inner_data_output -->
<p>The length of the final string is 256 bytes.</p>
<h5><a class="anchor" href="#5-send-req-dh-params-query-with-generated-encrypted-data" id="5-send-req-dh-params-query-with-generated-encrypted-data" name="5-send-req-dh-params-query-with-generated-encrypted-data"><i class="anchor-icon"></i></a>5) Send req_DH_params query with generated <code>encrypted_data</code></h5>
<!-- start req_DH_params -->
<p>Sent payload (excluding transport headers/trailers):</p>
<pre><code>0000 | 00 00 00 00 00 00 00 00 D8 72 06 00 50 3D C5 65
0010 | 40 01 00 00 BE E4 12 D7 40 67 09 F6 12 FA DF BE
0020 | C3 F0 28 9D 0A A6 7E EF E1 1D BC 3B C9 7D 91 A2
0030 | 61 54 F9 32 AF 01 99 43 04 5A 30 0D 4B 00 00 00
0040 | 04 6A 26 DB 65 00 00 00 85 FD 64 DE 85 1D 9D D0
0050 | FE 00 01 00 B8 06 32 B3 F0 D1 AB 28 EF AE 2C F9
0060 | 74 C4 A2 D5 1A 77 FC B6 DE FD 41 5E 1E C2 84 CA
0070 | B2 B5 F8 8D 5C 4C 5B 19 AF F5 E9 40 CE 14 CC B6
0080 | A7 F3 40 EC 88 DF 7C 1F 09 1F B6 F7 32 3B 04 7C
0090 | 02 DC 63 21 2D 0D EB E4 B3 B7 A0 31 0E 26 DB 12
00A0 | 89 CB A2 41 12 DF 37 50 6C 90 DE AB 79 76 23 E4
00B0 | AF F4 64 3D 2A 92 18 91 34 6B C1 76 C4 E1 CC E1
00C0 | 4F 64 FA 59 52 6D D0 21 EF FA 42 8E 8F 8A CE EB
00D0 | 96 DB D4 72 9E 99 BB B2 6D DD C7 44 D5 84 B7 32
00E0 | 41 5D FF E2 04 18 95 3F 4E AF C8 1D AD E5 C6 60
00F0 | 6A 1E 7F AA 3E DB 90 F3 6E CF 40 54 22 C9 7C 36
0100 | 0C C3 1A 44 4B 1E EB 6C 33 D6 2C 58 02 16 5C 72
0110 | BB C8 5D 1A DB CC D1 79 88 DE 7F 43 DA 0F 34 05
0120 | 02 74 4B 52 B1 96 A7 8E F1 ED 13 72 C6 EA 12 32
0130 | 60 3F DB 9C 28 F7 F8 78 3F 29 09 8F FD 0F E9 B0
0140 | 66 C4 60 EC BA 0A 29 62 B8 23 98 C1 B3 2D 3D CB
0150 | 3B C3 A5 9E</code></pre>
<p>Payload (de)serialization:</p>
<pre><code>req_DH_params#d712e4be nonce:int128 server_nonce:int128 p:string q:string public_key_fingerprint:long encrypted_data:string = Server_DH_Params;</code></pre>
<table class="table">
<thead>
<tr>
<th>Parameter</th>
<th>Offset, Length in bytes</th>
<th>Value</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>auth_key_id</td>
<td>0, 8</td>
<td><code>0000000000000000</code></td>
<td>0 since the message is in plain text</td>
</tr>
<tr>
<td>message_id</td>
<td>8, 8</td>
<td><code>D8720600503DC565</code></td>
<td>Message ID generated as specified <a href="/mtproto/description#message-identifier-msg-id">here »</a> (unixtime() &lt;&lt; 32) + (N*4)</td>
</tr>
<tr>
<td>message_length</td>
<td>16, 4</td>
<td><code>40010000</code> (320 in decimal)</td>
<td>Message body length</td>
</tr>
<tr>
<td>%(req_DH_params)</td>
<td>20, 4</td>
<td><code>bee412d7</code></td>
<td><em>req_DH_params</em> constructor number from TL schema</td>
</tr>
<tr>
<td>nonce</td>
<td>24, 16</td>
<td><code>406709F612FADFBEC3F0289D0AA67EEF</code></td>
<td>Value generated by client in Step 1</td>
</tr>
<tr>
<td>server_nonce</td>
<td>40, 16</td>
<td><code>E11DBC3BC97D91A26154F932AF019943</code></td>
<td>Value received from server in Step 2</td>
</tr>
<tr>
<td>p</td>
<td>56, 8</td>
<td><code>045A300D4B000000</code><br>TL byte deserialization <br>=&gt; bigendian conversion to decimal<br>=&gt; 1513098571</td>
<td>First prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding</td>
</tr>
<tr>
<td>q</td>
<td>64, 8</td>
<td><code>046A26DB65000000</code><br>TL byte deserialization <br>=&gt; bigendian conversion to decimal<br>=&gt; 1780931429</td>
<td>Second prime cofactor: single-byte prefix denoting length, 4-byte string, and three bytes of padding</td>
</tr>
<tr>
<td>public_key_fingerprint</td>
<td>72, 8</td>
<td><code>85FD64DE851D9DD0</code></td>
<td><code>fingerprint</code> of public key used</td>
</tr>
<tr>
<td>encrypted_data</td>
<td>80, 260</td>
<td><code>FE000100B80632B3F0D1AB28EFAE2CF9</code> <code>74C4A2D51A77FCB6DEFD415E1EC284CA</code> <code>B2B5F88D5C4C5B19AFF5E940CE14CCB6</code> <code>A7F340EC88DF7C1F091FB6F7323B047C</code> <code>02DC63212D0DEBE4B3B7A0310E26DB12</code> <code>89CBA24112DF37506C90DEAB797623E4</code> <code>AFF4643D2A921891346BC176C4E1CCE1</code> <code>4F64FA59526DD021EFFA428E8F8ACEEB</code> <code>96DBD4729E99BBB26DDDC744D584B732</code> <code>415DFFE20418953F4EAFC81DADE5C660</code> <code>6A1E7FAA3EDB90F36ECF405422C97C36</code> <code>0CC31A444B1EEB6C33D62C5802165C72</code> <code>BBC85D1ADBCCD17988DE7F43DA0F3405</code> <code>02744B52B196A78EF1ED1372C6EA1232</code> <code>603FDB9C28F7F8783F29098FFD0FE9B0</code> <code>66C460ECBA0A2962B82398C1B32D3DCB</code><br> <code>3BC3A59E</code></td>
<td>Value generated above</td>
</tr>
</tbody>
</table>
<!-- end req_DH_params -->
<h5><a class="anchor" href="#6-server-responds-with" id="6-server-responds-with" name="6-server-responds-with"><i class="anchor-icon"></i></a>6) Server responds with:</h5>
<!-- start server_DH_params_ok -->
<p>Received payload (excluding transport headers/trailers):</p>
<pre><code>0000 | 00 00 00 00 00 00 00 00 01 4C 6E 1E 51 3D C5 65
0010 | C4 02 00 00 5C 07 E8 D0 40 67 09 F6 12 FA DF BE
0020 | C3 F0 28 9D 0A A6 7E EF E1 1D BC 3B C9 7D 91 A2
0030 | 61 54 F9 32 AF 01 99 43 FE 50 02 00 6A D7 DD 5D
0040 | 8B 25 26 C7 61 AB E5 0E 93 C8 2A 6F 33 1B 1E AE
0050 | 0A D0 11 89 3D A9 76 E3 77 1D 4A A4 52 09 D2 34
0060 | FE A6 56 42 98 53 86 B8 17 BF 89 80 F5 17 F6 D3
0070 | 2D BE B4 7E 34 53 45 56 F9 50 DD F9 60 DB 72 1A
0080 | 48 48 02 31 61 91 61 11 26 82 C6 04 6D 56 29 C7
0090 | 1C D1 EC 80 61 DF CD D7 04 70 3E C7 A8 AE BD CB
00A0 | D1 59 57 9F C8 88 6D 9F A5 1E 00 9A F4 9B 5A B9
00B0 | 0C 76 28 EB 81 C9 78 8A 2E B6 AC 0E 75 7A 7D EB
00C0 | E3 D9 49 F8 0A 99 0B ED B4 D2 DB AE 43 F0 03 28
00D0 | B8 2F 4D 8F C8 3A 9B 9C FE EF 46 7E 15 93 BB 45
00E0 | 79 EE 32 41 2F 16 7A 78 0C FA 51 76 50 BD 0E B5
00F0 | 1C BF B5 0E 3A FE 97 88 39 46 61 31 FC D9 56 71
0100 | 1E 63 61 4F 00 6A 55 ED 35 ED 2B 1F 83 3C 29 F4
0110 | FD 7A 84 F0 C8 F1 C1 0D FC 1A 1A AF 9A 8A 57 10
0120 | 8D EC F2 06 E3 96 84 06 F0 FB 25 E9 22 DF 15 4F
0130 | 49 7B 51 52 7E 48 34 20 2F AB 47 7A 13 7D 0A 99
0140 | D1 C3 47 19 6F BA 10 69 9F 52 EA 56 F0 1E F9 38
0150 | 29 B3 10 A5 C9 7D B9 5F D5 7E 64 41 7E 52 6E B9
0160 | 20 D2 61 15 7C 6E 38 79 1B DD 53 89 EE B7 44 E0
0170 | 75 D9 52 DB 33 A8 15 12 07 D0 AB 3C 62 9E 30 A7
0180 | 23 A5 20 5F 8F A1 83 98 93 7E D2 71 4A 4E 76 A5
0190 | F4 51 25 08 A4 BE 1B 4D 6A E4 6F D1 56 C6 F0 63
01A0 | 47 AF 5E 07 CE 49 27 91 95 13 3B 07 CC E4 BC 67
01B0 | 75 D8 8F 36 11 18 0D 23 C4 C7 09 46 61 9A D7 59
01C0 | AB 9F 18 3A 38 5C CF 9B F1 93 15 FA DB E8 A4 FD
01D0 | C7 48 AF 52 DF 93 03 45 90 9C 87 0D E4 B4 89 01
01E0 | E9 F9 0E 56 D7 4C A5 34 D8 E1 FE 3A 35 A9 2A 18
01F0 | D6 76 95 8E B8 FC 3D 82 F9 CE E3 08 DF 2A 9E 4C
0200 | CD 23 FF 89 EA 25 5B 9E ED BC 33 78 14 88 79 66
0210 | 6F FC 2E 19 A4 31 CB B5 7A E1 A0 10 FF E5 CB 39
0220 | AB F1 31 AD D9 E9 0B F9 69 A1 12 C4 35 50 9B 78
0230 | 96 0E 0B 20 03 1C 82 21 90 84 15 61 E8 39 04 46
0240 | 22 76 60 BB AC CF 3D 53 57 4B FB A3 3B F4 76 E3
0250 | BD C9 EB 68 0A A2 A1 7F D6 75 6F 65 27 25 ED 03
0260 | 13 E5 EB 0F D6 A9 C8 C9 49 EE FB E8 09 A8 93 11
0270 | BF 20 F4 00 55 CA 25 FD 16 9D C1 3E E1 4B 31 50
0280 | 92 FD E4 18 46 38 D8 49 68 2F D8 62</code></pre>
<p>Payload (de)serialization:</p>
<pre><code>server_DH_params_ok#d0e8075c nonce:int128 server_nonce:int128 encrypted_answer:string = Server_DH_Params;</code></pre>
<table class="table">
<thead>
<tr>
<th>Parameter</th>
<th>Offset, Length in bytes</th>
<th>Value</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>auth_key_id</td>
<td>0, 8</td>
<td><code>0000000000000000</code></td>
<td>0 since the message is in plain text</td>
</tr>
<tr>
<td>message_id</td>
<td>8, 8</td>
<td><code>014C6E1E513DC565</code></td>
<td>Message ID generated as specified <a href="/mtproto/description#message-identifier-msg-id">here »</a> (unixtime() &lt;&lt; 32) + (N*4)</td>
</tr>
<tr>
<td>message_length</td>
<td>16, 4</td>
<td><code>C4020000</code> (708 in decimal)</td>
<td>Message body length</td>
</tr>
<tr>
<td>%(server_DH_params_ok)</td>
<td>20, 4</td>
<td><code>5c07e8d0</code></td>
<td><em>server_DH_params_ok</em> constructor number from TL schema</td>
</tr>
<tr>
<td>nonce</td>
<td>24, 16</td>
<td><code>406709F612FADFBEC3F0289D0AA67EEF</code></td>
<td>Value generated by client in Step 1</td>
</tr>
<tr>
<td>server_nonce</td>
<td>40, 16</td>
<td><code>E11DBC3BC97D91A26154F932AF019943</code></td>
<td>Value received from server in Step 2</td>
</tr>
<tr>
<td>encrypted_answer</td>
<td>56, 596</td>
<td><code>FE5002006AD7DD5D8B2526C761ABE50E</code> <code>93C82A6F331B1EAE0AD011893DA976E3</code> <code>771D4AA45209D234FEA65642985386B8</code> <code>17BF8980F517F6D32DBEB47E34534556</code> <code>F950DDF960DB721A4848023161916111</code> <code>2682C6046D5629C71CD1EC8061DFCDD7</code> <code>04703EC7A8AEBDCBD159579FC8886D9F</code> <code>A51E009AF49B5AB90C7628EB81C9788A</code> <code>2EB6AC0E757A7DEBE3D949F80A990BED</code> <code>B4D2DBAE43F00328B82F4D8FC83A9B9C</code> <code>FEEF467E1593BB4579EE32412F167A78</code> <code>0CFA517650BD0EB51CBFB50E3AFE9788</code> <code>39466131FCD956711E63614F006A55ED</code> <code>35ED2B1F833C29F4FD7A84F0C8F1C10D</code> <code>FC1A1AAF9A8A57108DECF206E3968406</code> <code>F0FB25E922DF154F497B51527E483420</code> <code>2FAB477A137D0A99D1C347196FBA1069</code> <code>9F52EA56F01EF93829B310A5C97DB95F</code> <code>D57E64417E526EB920D261157C6E3879</code> <code>1BDD5389EEB744E075D952DB33A81512</code> <code>07D0AB3C629E30A723A5205F8FA18398</code> <code>937ED2714A4E76A5F4512508A4BE1B4D</code> <code>6AE46FD156C6F06347AF5E07CE492791</code> <code>95133B07CCE4BC6775D88F3611180D23</code> <code>C4C70946619AD759AB9F183A385CCF9B</code> <code>F19315FADBE8A4FDC748AF52DF930345</code> <code>909C870DE4B48901E9F90E56D74CA534</code> <code>D8E1FE3A35A92A18D676958EB8FC3D82</code> <code>F9CEE308DF2A9E4CCD23FF89EA255B9E</code> <code>EDBC3378148879666FFC2E19A431CBB5</code> <code>7AE1A010FFE5CB39ABF131ADD9E90BF9</code> <code>69A112C435509B78960E0B20031C8221</code> <code>90841561E8390446227660BBACCF3D53</code> <code>574BFBA33BF476E3BDC9EB680AA2A17F</code> <code>D6756F652725ED0313E5EB0FD6A9C8C9</code> <code>49EEFBE809A89311BF20F40055CA25FD</code> <code>169DC13EE14B315092FDE4184638D849</code><br> <code>682FD862</code></td>
<td>See below</td>
</tr>
</tbody>
</table>
<!-- end server_DH_params_ok -->
<p>Decrypt <code>encrypted_answer</code> using the reverse of the process specified in <a href="/mtproto/auth_key#6-server-responds-with">step 6</a>:</p>
<!-- start server_DH_inner_data_input -->
<pre><code>encrypted_answer = 6AD7DD5D8B2526C761ABE50E93C82A6F331B1EAE0AD011893DA976E3771D4AA45209D234FEA65642985386B817BF8980F517F6D32DBEB47E34534556F950DDF960DB721A48480231619161112682C6046D5629C71CD1EC8061DFCDD704703EC7A8AEBDCBD159579FC8886D9FA51E009AF49B5AB90C7628EB81C9788A2EB6AC0E757A7DEBE3D949F80A990BEDB4D2DBAE43F00328B82F4D8FC83A9B9CFEEF467E1593BB4579EE32412F167A780CFA517650BD0EB51CBFB50E3AFE978839466131FCD956711E63614F006A55ED35ED2B1F833C29F4FD7A84F0C8F1C10DFC1A1AAF9A8A57108DECF206E3968406F0FB25E922DF154F497B51527E4834202FAB477A137D0A99D1C347196FBA10699F52EA56F01EF93829B310A5C97DB95FD57E64417E526EB920D261157C6E38791BDD5389EEB744E075D952DB33A8151207D0AB3C629E30A723A5205F8FA18398937ED2714A4E76A5F4512508A4BE1B4D6AE46FD156C6F06347AF5E07CE49279195133B07CCE4BC6775D88F3611180D23C4C70946619AD759AB9F183A385CCF9BF19315FADBE8A4FDC748AF52DF930345909C870DE4B48901E9F90E56D74CA534D8E1FE3A35A92A18D676958EB8FC3D82F9CEE308DF2A9E4CCD23FF89EA255B9EEDBC3378148879666FFC2E19A431CBB57AE1A010FFE5CB39ABF131ADD9E90BF969A112C435509B78960E0B20031C822190841561E8390446227660BBACCF3D53574BFBA33BF476E3BDC9EB680AA2A17FD6756F652725ED0313E5EB0FD6A9C8C949EEFBE809A89311BF20F40055CA25FD169DC13EE14B315092FDE4184638D849682FD862
tmp_aes_key = 5EA702F743E850F5546E857F08B7D5337BBAEDF9B61248751594851BE2E8C297
tmp_aes_iv = 1CEF8E372A63D97EBFA805C0DBB018BC7C1E0931693FBCB1A1AFC0C0A8BBC849</code></pre>
<!-- end server_DH_inner_data_input -->
<p>Yielding:</p>
<!-- start server_DH_inner_data_output -->
<pre><code>answer_with_hash = 60026275CC91DDEC5371C67B10331C4C1D362585BA0D89B5406709F612FADFBEC3F0289D0AA67EEFE11DBC3BC97D91A26154F932AF01994303000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE0001000A77200BDFF6E6C4C126A2C41DF310AB3A3BDBD698CD480749E1F3C64FB1CFC9DFC70AC6F1AA671019620A640055B2CF7D7D99CC86533645C0FA000954DE2987BAD68D7450CF134C9F0305F34C1BB285DA8233F65970A01C4BD3AFD5EA3CD5864B8F1DCB35D5E9737DF15063C54CF53048EF519A280498DDDAF23764F29FFB0C5813CAAD90C319BE8592B78C4BE815E65ADA7C62EA23754B5A2C5A86C4721872D0CC48E0F895C3EBE186E81E5F0E88A6B3F09101C409AF3410B64238FBF2A2095E3F3B7FFC7EB3A02A319B99A155647BC59958BCDFED8A1CC6EB7F13F8600E521D9D0247B0F639F2FA3B09F72987781F71C0E8AA950167DE5092380B4853E7F1513DC565C26F8049523E89D2
answer = BA0D89B5406709F612FADFBEC3F0289D0AA67EEFE11DBC3BC97D91A26154F932AF01994303000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE0001000A77200BDFF6E6C4C126A2C41DF310AB3A3BDBD698CD480749E1F3C64FB1CFC9DFC70AC6F1AA671019620A640055B2CF7D7D99CC86533645C0FA000954DE2987BAD68D7450CF134C9F0305F34C1BB285DA8233F65970A01C4BD3AFD5EA3CD5864B8F1DCB35D5E9737DF15063C54CF53048EF519A280498DDDAF23764F29FFB0C5813CAAD90C319BE8592B78C4BE815E65ADA7C62EA23754B5A2C5A86C4721872D0CC48E0F895C3EBE186E81E5F0E88A6B3F09101C409AF3410B64238FBF2A2095E3F3B7FFC7EB3A02A319B99A155647BC59958BCDFED8A1CC6EB7F13F8600E521D9D0247B0F639F2FA3B09F72987781F71C0E8AA950167DE5092380B4853E7F1513DC565C26F8049523E89D2</code></pre>
<!-- end server_DH_inner_data_output -->
<!-- start server_DH_inner_data -->
<p>Generated payload (excluding transport headers/trailers):</p>
<pre><code>0000 | BA 0D 89 B5 40 67 09 F6 12 FA DF BE C3 F0 28 9D
0010 | 0A A6 7E EF E1 1D BC 3B C9 7D 91 A2 61 54 F9 32
0020 | AF 01 99 43 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 | 0A 77 20 0B DF F6 E6 C4 C1 26 A2 C4 1D F3 10 AB
0140 | 3A 3B DB D6 98 CD 48 07 49 E1 F3 C6 4F B1 CF C9
0150 | DF C7 0A C6 F1 AA 67 10 19 62 0A 64 00 55 B2 CF
0160 | 7D 7D 99 CC 86 53 36 45 C0 FA 00 09 54 DE 29 87
0170 | BA D6 8D 74 50 CF 13 4C 9F 03 05 F3 4C 1B B2 85
0180 | DA 82 33 F6 59 70 A0 1C 4B D3 AF D5 EA 3C D5 86
0190 | 4B 8F 1D CB 35 D5 E9 73 7D F1 50 63 C5 4C F5 30
01A0 | 48 EF 51 9A 28 04 98 DD DA F2 37 64 F2 9F FB 0C
01B0 | 58 13 CA AD 90 C3 19 BE 85 92 B7 8C 4B E8 15 E6
01C0 | 5A DA 7C 62 EA 23 75 4B 5A 2C 5A 86 C4 72 18 72
01D0 | D0 CC 48 E0 F8 95 C3 EB E1 86 E8 1E 5F 0E 88 A6
01E0 | B3 F0 91 01 C4 09 AF 34 10 B6 42 38 FB F2 A2 09
01F0 | 5E 3F 3B 7F FC 7E B3 A0 2A 31 9B 99 A1 55 64 7B
0200 | C5 99 58 BC DF ED 8A 1C C6 EB 7F 13 F8 60 0E 52
0210 | 1D 9D 02 47 B0 F6 39 F2 FA 3B 09 F7 29 87 78 1F
0220 | 71 C0 E8 AA 95 01 67 DE 50 92 38 0B 48 53 E7 F1
0230 | 51 3D C5 65</code></pre>
<p>Payload (de)serialization:</p>
<pre><code>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;</code></pre>
<table class="table">
<thead>
<tr>
<th>Parameter</th>
<th>Offset, Length in bytes</th>
<th>Value</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>%(server_DH_inner_data)</td>
<td>0, 4</td>
<td><code>ba0d89b5</code></td>
<td><em>server_DH_inner_data</em> constructor number from TL schema</td>
</tr>
<tr>
<td>nonce</td>
<td>4, 16</td>
<td><code>406709F612FADFBEC3F0289D0AA67EEF</code></td>
<td>Value generated by client in Step 1</td>
</tr>
<tr>
<td>server_nonce</td>
<td>20, 16</td>
<td><code>E11DBC3BC97D91A26154F932AF019943</code></td>
<td>Value received from server in Step 2</td>
</tr>
<tr>
<td>g</td>
<td>36, 4</td>
<td><code>03000000</code> (3 in decimal)</td>
<td>Value received from server in Step 2</td>
</tr>
<tr>
<td>dh_prime</td>
<td>40, 260</td>
<td><code>FE000100C71CAEB9C6B1C9048E6C522F</code> <code>70F13F73980D40238E3E21C14934D037</code> <code>563D930F48198A0AA7C14058229493D2</code> <code>2530F4DBFA336F6E0AC925139543AED4</code> <code>4CCE7C3720FD51F69458705AC68CD4FE</code> <code>6B6B13ABDC9746512969328454F18FAF</code> <code>8C595F642477FE96BB2A941D5BCD1D4A</code> <code>C8CC49880708FA9B378E3C4F3A9060BE</code> <code>E67CF9A4A4A695811051907E162753B5</code> <code>6B0F6B410DBA74D8A84B2A14B3144E0E</code> <code>F1284754FD17ED950D5965B4B9DD4658</code> <code>2DB1178D169C6BC465B0D6FF9CA3928F</code> <code>EF5B9AE4E418FC15E83EBEA0F87FA9FF</code> <code>5EED70050DED2849F47BF959D956850C</code> <code>E929851F0D8115F635B105EE2E4E15D0</code> <code>4B2454BF6F4FADF034B10403119CD8E3</code><br> <code>B92FCC5B</code></td>
<td>2048-bit prime, in big-endian byte order, to be checked as specified in the auth key docs</td>
</tr>
<tr>
<td>g_a</td>
<td>300, 260</td>
<td><code>FE0001000A77200BDFF6E6C4C126A2C4</code> <code>1DF310AB3A3BDBD698CD480749E1F3C6</code> <code>4FB1CFC9DFC70AC6F1AA671019620A64</code> <code>0055B2CF7D7D99CC86533645C0FA0009</code> <code>54DE2987BAD68D7450CF134C9F0305F3</code> <code>4C1BB285DA8233F65970A01C4BD3AFD5</code> <code>EA3CD5864B8F1DCB35D5E9737DF15063</code> <code>C54CF53048EF519A280498DDDAF23764</code> <code>F29FFB0C5813CAAD90C319BE8592B78C</code> <code>4BE815E65ADA7C62EA23754B5A2C5A86</code> <code>C4721872D0CC48E0F895C3EBE186E81E</code> <code>5F0E88A6B3F09101C409AF3410B64238</code> <code>FBF2A2095E3F3B7FFC7EB3A02A319B99</code> <code>A155647BC59958BCDFED8A1CC6EB7F13</code> <code>F8600E521D9D0247B0F639F2FA3B09F7</code> <code>2987781F71C0E8AA950167DE5092380B</code><br> <code>4853E7F1</code></td>
<td><code>g_a</code> diffie-hellman parameter</td>
</tr>
<tr>
<td>server_time</td>
<td>560, 4</td>
<td><code>513DC565</code> (1707425105 in decimal)</td>
<td>Server time</td>
</tr>
</tbody>
</table>
<!-- end server_DH_inner_data -->
<h5><a class="anchor" href="#7-client-computes-random-2048-bit-number-b-using-a-sufficient-amount-of-entropy-and-sends-the-server-a-message" id="7-client-computes-random-2048-bit-number-b-using-a-sufficient-amount-of-entropy-and-sends-the-server-a-message" name="7-client-computes-random-2048-bit-number-b-using-a-sufficient-amount-of-entropy-and-sends-the-server-a-message"><i class="anchor-icon"></i></a>7) Client computes random 2048-bit number <em>b</em> (using a sufficient amount of entropy) and sends the server a message</h5>
<p>First, generate a secure random 2048-bit number b:</p>
<!-- start b -->
<pre><code>b = 1376A5A6BF7A9F874B47028F3D5CFF0689FD52F58949BB0EE9BACDBE81DD1CED07101844EB6F2AE19E61120B84799431F445785E33A18141399821479AE96786E0F4E9C5C6C9E46BF562C21C96B0F8F7438C8CABA3DFCB3DD3B886C2A37B95ED804315335C0DDFFEB3A278243D89F964278BC734D1087D6D4B554C1F78397A414F440E38BA9A4F1211B20AE835437762F81A45FDB035BB2220D939693084B39A3C7BE2481309AB9AE378EAB8BB3A15A69EBA80BEF683582E2218FA604E823EABD111553D31DBB46B9383A0D8EEF615FFF9CF266C970800AA28AC5E962D20351311A815FFA7562989CA6D6323BF2B5AF40EF3F45021B7445664852D07B80172CE</code></pre>
<!-- end b -->
<p>Then compute <code>g_b = pow(g, b) mod dh_prime</code></p>
<!-- start g_b -->
<pre><code>g_b = A215D057BC6648453D68C2F418A38D9D4F4FA47E5D520AC7EBC2ADC3B00075090C10A1E9D96A5DDA127317F2DDC165C5F6C8C2854648C106D0D9DF684DAE70B0E6021658806245B494B762B1979E8BD597B5CC8E43A80F96CA47FB0765C98D40529F3D94C82113AE32C603AA24411EF8B330565A1D66EA6B89C9D4F8AFFEEA397C4B247564215D147B6AD0DF7F3FB4499E89E34304531D87448B91967B5BD53093F09386C0F78940C1DD6AA7C8667E15857453E6AAD275F94CD386468CF49108FB7C54282596A4D0314DCE9EFED4066A6E072471439AEAAA74157DB7DD53F01982982534DEE8740610BA433BF459B3DFE38674561F31991CE007BA112DDA6718</code></pre>
<!-- end g_b -->
<h6>7.1) generation of encrypted_data</h6>
<!-- start client_DH_inner_data -->
<p>Generated payload (excluding transport headers/trailers):</p>
<pre><code>0000 | 54 B6 43 66 40 67 09 F6 12 FA DF BE C3 F0 28 9D
0010 | 0A A6 7E EF E1 1D BC 3B C9 7D 91 A2 61 54 F9 32
0020 | AF 01 99 43 00 00 00 00 00 00 00 00 FE 00 01 00
0030 | A2 15 D0 57 BC 66 48 45 3D 68 C2 F4 18 A3 8D 9D
0040 | 4F 4F A4 7E 5D 52 0A C7 EB C2 AD C3 B0 00 75 09
0050 | 0C 10 A1 E9 D9 6A 5D DA 12 73 17 F2 DD C1 65 C5
0060 | F6 C8 C2 85 46 48 C1 06 D0 D9 DF 68 4D AE 70 B0
0070 | E6 02 16 58 80 62 45 B4 94 B7 62 B1 97 9E 8B D5
0080 | 97 B5 CC 8E 43 A8 0F 96 CA 47 FB 07 65 C9 8D 40
0090 | 52 9F 3D 94 C8 21 13 AE 32 C6 03 AA 24 41 1E F8
00A0 | B3 30 56 5A 1D 66 EA 6B 89 C9 D4 F8 AF FE EA 39
00B0 | 7C 4B 24 75 64 21 5D 14 7B 6A D0 DF 7F 3F B4 49
00C0 | 9E 89 E3 43 04 53 1D 87 44 8B 91 96 7B 5B D5 30
00D0 | 93 F0 93 86 C0 F7 89 40 C1 DD 6A A7 C8 66 7E 15
00E0 | 85 74 53 E6 AA D2 75 F9 4C D3 86 46 8C F4 91 08
00F0 | FB 7C 54 28 25 96 A4 D0 31 4D CE 9E FE D4 06 6A
0100 | 6E 07 24 71 43 9A EA AA 74 15 7D B7 DD 53 F0 19
0110 | 82 98 25 34 DE E8 74 06 10 BA 43 3B F4 59 B3 DF
0120 | E3 86 74 56 1F 31 99 1C E0 07 BA 11 2D DA 67 18</code></pre>
<p>Payload (de)serialization:</p>
<pre><code>client_DH_inner_data#6643b654 nonce:int128 server_nonce:int128 retry_id:long g_b:string = Client_DH_Inner_Data;</code></pre>
<table class="table">
<thead>
<tr>
<th>Parameter</th>
<th>Offset, Length in bytes</th>
<th>Value</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>%(client_DH_inner_data)</td>
<td>0, 4</td>
<td><code>54b64366</code></td>
<td><em>client_DH_inner_data</em> constructor number from TL schema</td>
</tr>
<tr>
<td>nonce</td>
<td>4, 16</td>
<td><code>406709F612FADFBEC3F0289D0AA67EEF</code></td>
<td>Value generated by client in Step 1</td>
</tr>
<tr>
<td>server_nonce</td>
<td>20, 16</td>
<td><code>E11DBC3BC97D91A26154F932AF019943</code></td>
<td>Value received from server in Step 2</td>
</tr>
<tr>
<td>g_b</td>
<td>36, 260</td>
<td><code>FE000100A215D057BC6648453D68C2F4</code> <code>18A38D9D4F4FA47E5D520AC7EBC2ADC3</code> <code>B00075090C10A1E9D96A5DDA127317F2</code> <code>DDC165C5F6C8C2854648C106D0D9DF68</code> <code>4DAE70B0E6021658806245B494B762B1</code> <code>979E8BD597B5CC8E43A80F96CA47FB07</code> <code>65C98D40529F3D94C82113AE32C603AA</code> <code>24411EF8B330565A1D66EA6B89C9D4F8</code> <code>AFFEEA397C4B247564215D147B6AD0DF</code> <code>7F3FB4499E89E34304531D87448B9196</code> <code>7B5BD53093F09386C0F78940C1DD6AA7</code> <code>C8667E15857453E6AAD275F94CD38646</code> <code>8CF49108FB7C54282596A4D0314DCE9E</code> <code>FED4066A6E072471439AEAAA74157DB7</code> <code>DD53F01982982534DEE8740610BA433B</code> <code>F459B3DFE38674561F31991CE007BA11</code><br> <code>2DDA6718</code></td>
<td>Single-byte prefix denoting length, a 256-byte (2048-bit) string, and zero bytes of padding</td>
</tr>
<tr>
<td>retry_id</td>
<td>296, 8</td>
<td><code>0000000000000000</code></td>
<td>Equal to zero at the time of the first attempt; otherwise, it is equal to <code>auth_key_aux_hash</code> from the previous failed attempt (see Item 7).</td>
</tr>
</tbody>
</table>
<!-- end client_DH_inner_data -->
<p>The serialization of <em>Client_DH_Inner_Data</em> produces a string <strong>data</strong>. This is used to generate <strong>encrypted_data</strong> as specified in <a href="#7-client-computes-random-2048-bit-number-b-using-a-sufficient-amount-of-entropy-and-sends-the-server-a-message">step 6</a>, using the following inputs:</p>
<!-- start client_DH_inner_data_input -->
<pre><code>data = 54B64366406709F612FADFBEC3F0289D0AA67EEFE11DBC3BC97D91A26154F932AF0199430000000000000000FE000100A215D057BC6648453D68C2F418A38D9D4F4FA47E5D520AC7EBC2ADC3B00075090C10A1E9D96A5DDA127317F2DDC165C5F6C8C2854648C106D0D9DF684DAE70B0E6021658806245B494B762B1979E8BD597B5CC8E43A80F96CA47FB0765C98D40529F3D94C82113AE32C603AA24411EF8B330565A1D66EA6B89C9D4F8AFFEEA397C4B247564215D147B6AD0DF7F3FB4499E89E34304531D87448B91967B5BD53093F09386C0F78940C1DD6AA7C8667E15857453E6AAD275F94CD386468CF49108FB7C54282596A4D0314DCE9EFED4066A6E072471439AEAAA74157DB7DD53F01982982534DEE8740610BA433BF459B3DFE38674561F31991CE007BA112DDA6718
padding = 74876952857BA6AAA495A20D
tmp_aes_key = 5EA702F743E850F5546E857F08B7D5337BBAEDF9B61248751594851BE2E8C297
tmp_aes_iv = 1CEF8E372A63D97EBFA805C0DBB018BC7C1E0931693FBCB1A1AFC0C0A8BBC849</code></pre>
<!-- end client_DH_inner_data_input -->
<p>Process:</p>
<pre><code>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);</code></pre>
<p>Output:</p>
<!-- start client_DH_inner_data_output -->
<pre><code>encrypted_data = 14D185E575255986C29BE3A0437D525BA22430CBA0CD755225945AD3A1ACEFB536518514F5086892E6E3FA84D1CBB644BC8F7BEBCDE74E31BA8A073F47623EBB6E7D94B3A676A4C1AFD4689C52D05F73D21C33F64FE6AEABD04273D9117CD064E467E1F8E6C887BCAE4679E0399AD35DB1302A80629618F8C8485248D89A4E3568B464FF7B608CBE24B51EEB81B65D76224B62A1669EAA48A99C122E5E8A778E13DD441DC52175160088A498F186A2B99C736FE8C5C3E274D804C629564A0F15DDABC5B449356A7990900652A7432AFB1499C7CE09246F6B29006425DF2926465B04F17C0077B6A336A50E46B675AD5607F05818F84EADEC1F4847BF311027E742F8B1E183C01810C4CE964F2A0F36E257849C144C9B0B93B4A7A9E57391DB0CCB0D757A2B7A77257C8FF55553D66B6E1D45E9D8CA88E5A47B16322FF2ED5F5ABE099E7006B2D29C829D746B704130B1</code></pre>
<!-- end client_DH_inner_data_output -->
<p>The length of the final string is 336 bytes.</p>
<h6>7.2) set_client_DH_params query</h6>
<!-- start set_client_DH_params -->
<p>Sent payload (excluding transport headers/trailers):</p>
<pre><code>0000 | 00 00 00 00 00 00 00 00 18 5C 07 00 51 3D C5 65
0010 | 78 01 00 00 1F 5F 04 F5 40 67 09 F6 12 FA DF BE
0020 | C3 F0 28 9D 0A A6 7E EF E1 1D BC 3B C9 7D 91 A2
0030 | 61 54 F9 32 AF 01 99 43 FE 50 01 00 14 D1 85 E5
0040 | 75 25 59 86 C2 9B E3 A0 43 7D 52 5B A2 24 30 CB
0050 | A0 CD 75 52 25 94 5A D3 A1 AC EF B5 36 51 85 14
0060 | F5 08 68 92 E6 E3 FA 84 D1 CB B6 44 BC 8F 7B EB
0070 | CD E7 4E 31 BA 8A 07 3F 47 62 3E BB 6E 7D 94 B3
0080 | A6 76 A4 C1 AF D4 68 9C 52 D0 5F 73 D2 1C 33 F6
0090 | 4F E6 AE AB D0 42 73 D9 11 7C D0 64 E4 67 E1 F8
00A0 | E6 C8 87 BC AE 46 79 E0 39 9A D3 5D B1 30 2A 80
00B0 | 62 96 18 F8 C8 48 52 48 D8 9A 4E 35 68 B4 64 FF
00C0 | 7B 60 8C BE 24 B5 1E EB 81 B6 5D 76 22 4B 62 A1
00D0 | 66 9E AA 48 A9 9C 12 2E 5E 8A 77 8E 13 DD 44 1D
00E0 | C5 21 75 16 00 88 A4 98 F1 86 A2 B9 9C 73 6F E8
00F0 | C5 C3 E2 74 D8 04 C6 29 56 4A 0F 15 DD AB C5 B4
0100 | 49 35 6A 79 90 90 06 52 A7 43 2A FB 14 99 C7 CE
0110 | 09 24 6F 6B 29 00 64 25 DF 29 26 46 5B 04 F1 7C
0120 | 00 77 B6 A3 36 A5 0E 46 B6 75 AD 56 07 F0 58 18
0130 | F8 4E AD EC 1F 48 47 BF 31 10 27 E7 42 F8 B1 E1
0140 | 83 C0 18 10 C4 CE 96 4F 2A 0F 36 E2 57 84 9C 14
0150 | 4C 9B 0B 93 B4 A7 A9 E5 73 91 DB 0C CB 0D 75 7A
0160 | 2B 7A 77 25 7C 8F F5 55 53 D6 6B 6E 1D 45 E9 D8
0170 | CA 88 E5 A4 7B 16 32 2F F2 ED 5F 5A BE 09 9E 70
0180 | 06 B2 D2 9C 82 9D 74 6B 70 41 30 B1</code></pre>
<p>Payload (de)serialization:</p>
<pre><code>set_client_DH_params#f5045f1f nonce:int128 server_nonce:int128 encrypted_data:string = Set_client_DH_params_answer;</code></pre>
<table class="table">
<thead>
<tr>
<th>Parameter</th>
<th>Offset, Length in bytes</th>
<th>Value</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>auth_key_id</td>
<td>0, 8</td>
<td><code>0000000000000000</code></td>
<td>0 since the message is in plain text</td>
</tr>
<tr>
<td>message_id</td>
<td>8, 8</td>
<td><code>185C0700513DC565</code></td>
<td>Message ID generated as specified <a href="/mtproto/description#message-identifier-msg-id">here »</a> (unixtime() &lt;&lt; 32) + (N*4)</td>
</tr>
<tr>
<td>message_length</td>
<td>16, 4</td>
<td><code>78010000</code> (376 in decimal)</td>
<td>Message body length</td>
</tr>
<tr>
<td>%(set_client_DH_params)</td>
<td>20, 4</td>
<td><code>1f5f04f5</code></td>
<td><em>set_client_DH_params</em> constructor number from TL schema</td>
</tr>
<tr>
<td>nonce</td>
<td>24, 16</td>
<td><code>406709F612FADFBEC3F0289D0AA67EEF</code></td>
<td>Value generated by client in Step 1</td>
</tr>
<tr>
<td>server_nonce</td>
<td>40, 16</td>
<td><code>E11DBC3BC97D91A26154F932AF019943</code></td>
<td>Value received from server in Step 2</td>
</tr>
<tr>
<td>encrypted_data</td>
<td>56, 340</td>
<td><code>FE50010014D185E575255986C29BE3A0</code> <code>437D525BA22430CBA0CD755225945AD3</code> <code>A1ACEFB536518514F5086892E6E3FA84</code> <code>D1CBB644BC8F7BEBCDE74E31BA8A073F</code> <code>47623EBB6E7D94B3A676A4C1AFD4689C</code> <code>52D05F73D21C33F64FE6AEABD04273D9</code> <code>117CD064E467E1F8E6C887BCAE4679E0</code> <code>399AD35DB1302A80629618F8C8485248</code> <code>D89A4E3568B464FF7B608CBE24B51EEB</code> <code>81B65D76224B62A1669EAA48A99C122E</code> <code>5E8A778E13DD441DC52175160088A498</code> <code>F186A2B99C736FE8C5C3E274D804C629</code> <code>564A0F15DDABC5B449356A7990900652</code> <code>A7432AFB1499C7CE09246F6B29006425</code> <code>DF2926465B04F17C0077B6A336A50E46</code> <code>B675AD5607F05818F84EADEC1F4847BF</code> <code>311027E742F8B1E183C01810C4CE964F</code> <code>2A0F36E257849C144C9B0B93B4A7A9E5</code> <code>7391DB0CCB0D757A2B7A77257C8FF555</code> <code>53D66B6E1D45E9D8CA88E5A47B16322F</code> <code>F2ED5F5ABE099E7006B2D29C829D746B</code><br> <code>704130B1</code></td>
<td>Encrypted client_DH_inner_data generated previously, serialized as a TL byte string</td>
</tr>
</tbody>
</table>
<!-- end set_client_DH_params -->
<h5><a class="anchor" href="#8-auth-key-generation" id="8-auth-key-generation" name="8-auth-key-generation"><i class="anchor-icon"></i></a>8) Auth key generation</h5>
<p>The client computes the auth_key using formula <code>g_a^b mod dh_prime</code>:</p>
<!-- start auth_key -->
<pre><code>auth_key = ACA2547BAA3B4B3E6AD9129ADEE796042FC4ACAAABA40DCE7A1196640595829E2BA85C5E68E5D2B7B713B28720CCD0E65DA3B80CD8A9282BDE895755B924F4CBBCED119DEE057D3066D7095C25771A53D9AD6EC3464EE0E7FE1A4D9851F17B6CC7D6E636E0BDEA7D66153CF37005835A528E65673C1F5ADAA27465964BA89AA6FD045108B25B1DC9AB2D979864858C9EACBFA4A399CDBF2154D2CC6743C5CAA40683343D80A36C7F1289DC5AC5EE585DEA1E1CD296444EA6CD8F6C3564B2D355B310A3C02608EEA5EC36D38E941BF811489AB7A24C069E44FF54714CB4A45EEE2F310FDDC0A1B08BD3DFF8801E27C8508EFD7AD51EF3C13EF1D9A02EE4601741</code></pre>
<!-- end auth_key -->
<h5><a class="anchor" href="#9-final-server-reply" id="9-final-server-reply" name="9-final-server-reply"><i class="anchor-icon"></i></a>9) Final server reply</h5>
<p>The server verifies and confirms that auth_key_hash is unique: since it's unique, it replies with the following:</p>
<!-- start dh_gen_ok -->
<p>Received payload (excluding transport headers/trailers):</p>
<pre><code>0000 | 00 00 00 00 00 00 00 00 01 00 BE 91 51 3D C5 65
0010 | 74 00 00 00 34 F7 CB 3B 40 67 09 F6 12 FA DF BE
0020 | C3 F0 28 9D 0A A6 7E EF E1 1D BC 3B C9 7D 91 A2
0030 | 61 54 F9 32 AF 01 99 43 11 42 87 13 52 16 5E 59
0040 | E1 12 40 36 B4 8B 97 D3</code></pre>
<p>Payload (de)serialization:</p>
<pre><code>dh_gen_ok#3bcbf734 nonce:int128 server_nonce:int128 new_nonce_hash1:int128 = Set_client_DH_params_answer;</code></pre>
<table class="table">
<thead>
<tr>
<th>Parameter</th>
<th>Offset, Length in bytes</th>
<th>Value</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>auth_key_id</td>
<td>0, 8</td>
<td><code>0000000000000000</code></td>
<td>0 since the message is in plain text</td>
</tr>
<tr>
<td>message_id</td>
<td>8, 8</td>
<td><code>0100BE91513DC565</code></td>
<td>Message ID generated as specified <a href="/mtproto/description#message-identifier-msg-id">here »</a> (unixtime() &lt;&lt; 32) + (N*4)</td>
</tr>
<tr>
<td>message_length</td>
<td>16, 4</td>
<td><code>74000000</code> (116 in decimal)</td>
<td>Message body length</td>
</tr>
<tr>
<td>%(dh_gen_ok)</td>
<td>20, 4</td>
<td><code>34f7cb3b</code></td>
<td><em>dh_gen_ok</em> constructor number from TL schema</td>
</tr>
<tr>
<td>nonce</td>
<td>24, 16</td>
<td><code>406709F612FADFBEC3F0289D0AA67EEF</code></td>
<td>Value generated by client in Step 1</td>
</tr>
<tr>
<td>server_nonce</td>
<td>40, 16</td>
<td><code>E11DBC3BC97D91A26154F932AF019943</code></td>
<td>Value received from server in Step 2</td>
</tr>
<tr>
<td>new_nonce_hash1</td>
<td>56, 16</td>
<td><code>1142871352165E59E1124036B48B97D3</code></td>
<td>The 128 lower-order bits of SHA1 of the byte string derived from the <code>new_nonce</code> string by adding a single byte with the value of 1, 2, or 3, and followed by another 8 bytes with <code>auth_key_aux_hash</code>. Different values are required to prevent an intruder from changing server response dh_gen_ok into dh_gen_retry.</td>
</tr>
</tbody>
</table>
<!-- end dh_gen_ok --></div>
</div>
</div>
</div>
<div class="footer_wrap">
<div class="footer_columns_wrap footer_desktop">
<div class="footer_column footer_column_telegram">
<h5>Telegram</h5>
<div class="footer_telegram_description"></div>
Telegram is a cloud-based mobile and desktop messaging app with a focus on security and speed.
</div>
<div class="footer_column">
<h5><a href="//telegram.org/faq">About</a></h5>
<ul>
<li><a href="//telegram.org/faq">FAQ</a></li>
<li><a href="//telegram.org/privacy">Privacy</a></li>
<li><a href="//telegram.org/press">Press</a></li>
</ul>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps#mobile-apps">Mobile Apps</a></h5>
<ul>
<li><a href="//telegram.org/dl/ios">iPhone/iPad</a></li>
<li><a href="//telegram.org/android">Android</a></li>
<li><a href="//telegram.org/dl/web">Mobile Web</a></li>
</ul>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps#desktop-apps">Desktop Apps</a></h5>
<ul>
<li><a href="//desktop.telegram.org/">PC/Mac/Linux</a></li>
<li><a href="//macos.telegram.org/">macOS</a></li>
<li><a href="//telegram.org/dl/web">Web-browser</a></li>
</ul>
</div>
<div class="footer_column footer_column_platform">
<h5><a href="/">Platform</a></h5>
<ul>
<li><a href="/api">API</a></li>
<li><a href="//translations.telegram.org/">Translations</a></li>
<li><a href="//instantview.telegram.org/">Instant View</a></li>
</ul>
</div>
</div>
<div class="footer_columns_wrap footer_mobile">
<div class="footer_column">
<h5><a href="//telegram.org/faq">About</a></h5>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/blog">Blog</a></h5>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps">Apps</a></h5>
</div>
<div class="footer_column">
<h5><a href="/">Platform</a></h5>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/press">Press</a></h5>
</div>
</div>
</div>
</div>
<script src="/js/main.js?47"></script>
<script src="/js/jquery.min.js?1"></script>
<script src="/js/bootstrap.min.js?1"></script>
<script>window.initDevPageNav&&initDevPageNav();
backToTopInit("Go up");
removePreloadInit();
</script>
</body>
</html>