telegram-crawler/data/web/blogfork.telegram.org/mtproto/samples-auth_key.html
2024-09-23 18:02:35 +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?241" 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 2C A3 0D 00 0D 0D C3 66
0010 | 14 00 00 00 F1 8E 7E BE AC 7E C6 49 66 2E CF 3C
0020 | F3 BA 99 1B 9D 8D AB D5</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>2CA30D000D0DC366</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>AC7EC649662ECF3CF3BA991B9D8DABD5</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 74 FF E0 0D 0D C3 66
0010 | 90 00 00 00 63 24 16 05 AC 7E C6 49 66 2E CF 3C
0020 | F3 BA 99 1B 9D 8D AB D5 6C 8D 9C F5 77 54 AE 5A
0030 | 5C B3 05 75 9A 60 50 D0 08 1B E3 63 A4 6F 8E DF
0040 | C1 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>0174FFE00D0DC366</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>90000000</code> (144 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>AC7EC649662ECF3CF3BA991B9D8DABD5</code></td>
<td>Value generated by client in Step 1</td>
</tr>
<tr>
<td>server_nonce</td>
<td>40, 16</td>
<td><code>6C8D9CF57754AE5A5CB305759A6050D0</code></td>
<td>Server-generated random number</td>
</tr>
<tr>
<td>pq</td>
<td>56, 12</td>
<td><code>081BE363A46F8EDFC1000000</code><br>TL byte deserialization <br>=&gt; bigendian conversion to decimal<br>=&gt; 2009559416634793921</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 = 2009559416634793921</code></pre>
<p>Decompose into 2 prime cofactors <code>p &lt; q</code>: <code>2009559416634793921 = 1090123583 * 1843423487</code></p>
<pre><code>p = 1090123583
q = 1843423487</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 1B E3 63 A4 6F 8E DF C1 00 00 00
0010 | 04 40 F9 F7 3F 00 00 00 04 6D E0 68 FF 00 00 00
0020 | AC 7E C6 49 66 2E CF 3C F3 BA 99 1B 9D 8D AB D5
0030 | 6C 8D 9C F5 77 54 AE 5A 5C B3 05 75 9A 60 50 D0
0040 | DB 3F 7E 5E 2E E1 CF 4C 86 05 74 57 84 5C 5C 5B
0050 | 4F 2A 99 51 F0 38 E4 31 B2 94 33 4E 12 C6 C4 19
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>081BE363A46F8EDFC1000000</code><br>TL byte deserialization <br>=&gt; bigendian conversion to decimal<br>=&gt; 2009559416634793921</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>0440F9F73F000000</code><br>TL byte deserialization <br>=&gt; bigendian conversion to decimal<br>=&gt; 1090123583</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>046DE068FF000000</code><br>TL byte deserialization <br>=&gt; bigendian conversion to decimal<br>=&gt; 1843423487</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>AC7EC649662ECF3CF3BA991B9D8DABD5</code></td>
<td>Value generated by client in Step 1</td>
</tr>
<tr>
<td>server_nonce</td>
<td>48, 16</td>
<td><code>6C8D9CF57754AE5A5CB305759A6050D0</code></td>
<td>Value received from server in Step 2</td>
</tr>
<tr>
<td>new_nonce</td>
<td>64, 32</td>
<td><code>DB3F7E5E2EE1CF4C86057457845C5C5B</code> <code>4F2A9951F038E431B294334E12C6C419</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 = 955FF5A9081BE363A46F8EDFC10000000440F9F73F000000046DE068FF000000AC7EC649662ECF3CF3BA991B9D8DABD56C8D9CF57754AE5A5CB305759A6050D0DB3F7E5E2EE1CF4C86057457845C5C5B4F2A9951F038E431B294334E12C6C41902000000
random_padding_bytes = 82EF77A67CA950176B3C8A6AED8C49B22B5B8338E93D9A8077219C1F643736C7ADE8802882B4E6667914AA15469B2AAC5111CA5F9D52D0C5949AAB0B8F9D894DCDA3ECD755440EBBC1A5FD15EB5486870DA7BA006C53D35B1C76B0B4</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 = C71092A1879498AD33CCAF6BF2F48145F0F624E20B99A8439CFC4D59974ED6299399FE92C80D06DF951CDA757AAB3014EC0B33B7D9B1F9AB6BFF3CFB7284552A27BBC42FBCE1D5D22BB05E9D90F04691F50C990BF4F315D204F1208FCC938C59F04B7F8E612DAA6F65BD768A085D4263F024496447833F731DB4C9960BE5263F98F448C32F8943258C687DC7CD6C3581FD371B2114654F3A5CD92BC032E8C6B644D859D5615712BA528CF8EC73E1B0887E204CA81847304A2FB3C4AAAA8A45C364D6CC6FE070913B7B19C2045BE3426D2CFEC5533A0CA28D5B47D69752D68F740CB1BC9C23CD1559C2054BAF7EB8622C39348A2B95A7D79FD4F8A3901B1501C5</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 94 C9 0E 00 0E 0D C3 66
0010 | 40 01 00 00 BE E4 12 D7 AC 7E C6 49 66 2E CF 3C
0020 | F3 BA 99 1B 9D 8D AB D5 6C 8D 9C F5 77 54 AE 5A
0030 | 5C B3 05 75 9A 60 50 D0 04 40 F9 F7 3F 00 00 00
0040 | 04 6D E0 68 FF 00 00 00 85 FD 64 DE 85 1D 9D D0
0050 | FE 00 01 00 C7 10 92 A1 87 94 98 AD 33 CC AF 6B
0060 | F2 F4 81 45 F0 F6 24 E2 0B 99 A8 43 9C FC 4D 59
0070 | 97 4E D6 29 93 99 FE 92 C8 0D 06 DF 95 1C DA 75
0080 | 7A AB 30 14 EC 0B 33 B7 D9 B1 F9 AB 6B FF 3C FB
0090 | 72 84 55 2A 27 BB C4 2F BC E1 D5 D2 2B B0 5E 9D
00A0 | 90 F0 46 91 F5 0C 99 0B F4 F3 15 D2 04 F1 20 8F
00B0 | CC 93 8C 59 F0 4B 7F 8E 61 2D AA 6F 65 BD 76 8A
00C0 | 08 5D 42 63 F0 24 49 64 47 83 3F 73 1D B4 C9 96
00D0 | 0B E5 26 3F 98 F4 48 C3 2F 89 43 25 8C 68 7D C7
00E0 | CD 6C 35 81 FD 37 1B 21 14 65 4F 3A 5C D9 2B C0
00F0 | 32 E8 C6 B6 44 D8 59 D5 61 57 12 BA 52 8C F8 EC
0100 | 73 E1 B0 88 7E 20 4C A8 18 47 30 4A 2F B3 C4 AA
0110 | AA 8A 45 C3 64 D6 CC 6F E0 70 91 3B 7B 19 C2 04
0120 | 5B E3 42 6D 2C FE C5 53 3A 0C A2 8D 5B 47 D6 97
0130 | 52 D6 8F 74 0C B1 BC 9C 23 CD 15 59 C2 05 4B AF
0140 | 7E B8 62 2C 39 34 8A 2B 95 A7 D7 9F D4 F8 A3 90
0150 | 1B 15 01 C5</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>94C90E000E0DC366</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>AC7EC649662ECF3CF3BA991B9D8DABD5</code></td>
<td>Value generated by client in Step 1</td>
</tr>
<tr>
<td>server_nonce</td>
<td>40, 16</td>
<td><code>6C8D9CF57754AE5A5CB305759A6050D0</code></td>
<td>Value received from server in Step 2</td>
</tr>
<tr>
<td>p</td>
<td>56, 8</td>
<td><code>0440F9F73F000000</code><br>TL byte deserialization <br>=&gt; bigendian conversion to decimal<br>=&gt; 1090123583</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>046DE068FF000000</code><br>TL byte deserialization <br>=&gt; bigendian conversion to decimal<br>=&gt; 1843423487</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>FE000100C71092A1879498AD33CCAF6B</code> <code>F2F48145F0F624E20B99A8439CFC4D59</code> <code>974ED6299399FE92C80D06DF951CDA75</code> <code>7AAB3014EC0B33B7D9B1F9AB6BFF3CFB</code> <code>7284552A27BBC42FBCE1D5D22BB05E9D</code> <code>90F04691F50C990BF4F315D204F1208F</code> <code>CC938C59F04B7F8E612DAA6F65BD768A</code> <code>085D4263F024496447833F731DB4C996</code> <code>0BE5263F98F448C32F8943258C687DC7</code> <code>CD6C3581FD371B2114654F3A5CD92BC0</code> <code>32E8C6B644D859D5615712BA528CF8EC</code> <code>73E1B0887E204CA81847304A2FB3C4AA</code> <code>AA8A45C364D6CC6FE070913B7B19C204</code> <code>5BE3426D2CFEC5533A0CA28D5B47D697</code> <code>52D68F740CB1BC9C23CD1559C2054BAF</code> <code>7EB8622C39348A2B95A7D79FD4F8A390</code><br> <code>1B1501C5</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 3C 42 AF 0E 0D C3 66
0010 | F0 02 00 00 5C 07 E8 D0 AC 7E C6 49 66 2E CF 3C
0020 | F3 BA 99 1B 9D 8D AB D5 6C 8D 9C F5 77 54 AE 5A
0030 | 5C B3 05 75 9A 60 50 D0 FE 50 02 00 28 D0 E4 6D
0040 | 08 A4 80 08 9A 50 37 02 51 A2 2F 16 07 0A 5D 0F
0050 | C7 51 4D BB 6D F2 BE 81 A6 48 9E 9B 53 66 A1 DD
0060 | 30 C4 DD 51 E9 98 54 E0 FA 9A A1 A2 3F 97 F4 A2
0070 | E6 80 59 DF 84 AE C5 5C 3F 81 06 55 51 F3 A0 66
0080 | B1 17 8F 4C F2 82 C6 34 A6 07 87 3F 42 10 87 C0
0090 | 73 99 FE EC 09 07 36 B9 7C 5D 2E FD 71 DB 7D C0
00A0 | B7 2B F3 B6 36 C6 D6 3E 20 FE DE 5D 86 5A 71 8E
00B0 | 85 84 DE 49 9E 8C 94 54 38 03 B4 40 30 54 C8 FE
00C0 | DE C8 1C AF F5 C7 56 6B 65 6B 4D 85 EF 92 7A 7C
00D0 | 06 A3 CF ED 2E 45 19 A6 22 EE 63 D5 FE 5D 51 1F
00E0 | 3A 01 9B 63 FC 11 F9 5B BC E7 FD E9 B0 58 C9 A7
00F0 | 12 02 09 C8 0C 57 38 08 43 59 8B 62 3B 94 FC D7
0100 | 16 96 04 7F 2A E1 07 69 0E 2F CD 61 EB 05 DA 5A
0110 | 6E 0F 13 FA 1E E1 4C 7B E1 E5 5D 47 D0 96 A7 87
0120 | 6F 2E 27 A3 C3 62 44 A9 86 E6 17 D9 1A 36 44 D7
0130 | DE 98 96 8B FD 09 A4 2C EB 3B 66 14 7A 0F C7 76
0140 | 92 2A F1 2D A3 37 7C 8F 33 AA C5 CF C8 75 0C 2F
0150 | 4C F9 89 48 09 EF E9 81 F2 88 63 64 FA 81 C7 59
0160 | 0A 12 24 4D 00 66 B8 62 D4 2D 78 86 5D DE 8F 2C
0170 | 8C 3E 1E ED FA ED 40 1A E2 36 23 D9 19 23 AA CC
0180 | A0 71 EE 9D D6 E3 F8 F6 C4 25 A6 06 AF 0B FE F1
0190 | 75 A5 17 B6 D4 F7 5C 56 BE 51 F6 DC 45 95 D7 45
01A0 | 4D A1 B5 DA D0 5D 59 69 F8 3F E8 DA F2 1C E6 CD
01B0 | 4A 57 95 12 CA FF 5F 58 D9 BC 9A 8E 45 92 95 D1
01C0 | 35 45 DD 4A C9 B8 37 7B 7A EC 68 2C F3 D7 7E FB
01D0 | D4 6B 46 5D 74 40 1F DA C1 7A 6A E4 C3 2F 1A 80
01E0 | 53 23 DC 9B 87 DB 38 21 05 38 E1 5D B5 B9 DE DA
01F0 | 6A 83 92 E0 1C 4C C4 02 27 16 36 FE BE 42 FE 7A
0200 | 2C 81 35 C4 85 A1 A1 04 F4 9B 1F 48 4F B1 8A 80
0210 | C8 C0 97 D3 D0 C2 0A 9B 4D 93 09 86 33 8E 2D F5
0220 | 56 59 CD F5 0C DE 50 E4 5E 05 CA 09 A3 94 8B BE
0230 | 2F 3D 68 E3 EA 5F 3B BF 3E 2E 9F F2 1B B4 5B 18
0240 | AF B4 44 F6 75 41 6C 27 C5 5F 3F 52 DA 11 B6 10
0250 | D6 C0 D7 07 90 1B 5A 39 3F 81 51 80 1A 3E 2E 38
0260 | 75 37 DC 21 DA EF 83 D1 44 1C 47 48 86 60 C0 07
0270 | 5F FE 01 D0 E2 0F 65 57 8F FB 6C F2 B3 98 25 38
0280 | 4B 29 5F BD 83 9B 46 FA 64 16 C0 A4</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>013C42AF0E0DC366</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>F0020000</code> (752 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>AC7EC649662ECF3CF3BA991B9D8DABD5</code></td>
<td>Value generated by client in Step 1</td>
</tr>
<tr>
<td>server_nonce</td>
<td>40, 16</td>
<td><code>6C8D9CF57754AE5A5CB305759A6050D0</code></td>
<td>Value received from server in Step 2</td>
</tr>
<tr>
<td>encrypted_answer</td>
<td>56, 596</td>
<td><code>FE50020028D0E46D08A480089A503702</code> <code>51A22F16070A5D0FC7514DBB6DF2BE81</code> <code>A6489E9B5366A1DD30C4DD51E99854E0</code> <code>FA9AA1A23F97F4A2E68059DF84AEC55C</code> <code>3F81065551F3A066B1178F4CF282C634</code> <code>A607873F421087C07399FEEC090736B9</code> <code>7C5D2EFD71DB7DC0B72BF3B636C6D63E</code> <code>20FEDE5D865A718E8584DE499E8C9454</code> <code>3803B4403054C8FEDEC81CAFF5C7566B</code> <code>656B4D85EF927A7C06A3CFED2E4519A6</code> <code>22EE63D5FE5D511F3A019B63FC11F95B</code> <code>BCE7FDE9B058C9A7120209C80C573808</code> <code>43598B623B94FCD71696047F2AE10769</code> <code>0E2FCD61EB05DA5A6E0F13FA1EE14C7B</code> <code>E1E55D47D096A7876F2E27A3C36244A9</code> <code>86E617D91A3644D7DE98968BFD09A42C</code> <code>EB3B66147A0FC776922AF12DA3377C8F</code> <code>33AAC5CFC8750C2F4CF9894809EFE981</code> <code>F2886364FA81C7590A12244D0066B862</code> <code>D42D78865DDE8F2C8C3E1EEDFAED401A</code> <code>E23623D91923AACCA071EE9DD6E3F8F6</code> <code>C425A606AF0BFEF175A517B6D4F75C56</code> <code>BE51F6DC4595D7454DA1B5DAD05D5969</code> <code>F83FE8DAF21CE6CD4A579512CAFF5F58</code> <code>D9BC9A8E459295D13545DD4AC9B8377B</code> <code>7AEC682CF3D77EFBD46B465D74401FDA</code> <code>C17A6AE4C32F1A805323DC9B87DB3821</code> <code>0538E15DB5B9DEDA6A8392E01C4CC402</code> <code>271636FEBE42FE7A2C8135C485A1A104</code> <code>F49B1F484FB18A80C8C097D3D0C20A9B</code> <code>4D930986338E2DF55659CDF50CDE50E4</code> <code>5E05CA09A3948BBE2F3D68E3EA5F3BBF</code> <code>3E2E9FF21BB45B18AFB444F675416C27</code> <code>C55F3F52DA11B610D6C0D707901B5A39</code> <code>3F8151801A3E2E387537DC21DAEF83D1</code> <code>441C47488660C0075FFE01D0E20F6557</code> <code>8FFB6CF2B39825384B295FBD839B46FA</code><br> <code>6416C0A4</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 = 28D0E46D08A480089A50370251A22F16070A5D0FC7514DBB6DF2BE81A6489E9B5366A1DD30C4DD51E99854E0FA9AA1A23F97F4A2E68059DF84AEC55C3F81065551F3A066B1178F4CF282C634A607873F421087C07399FEEC090736B97C5D2EFD71DB7DC0B72BF3B636C6D63E20FEDE5D865A718E8584DE499E8C94543803B4403054C8FEDEC81CAFF5C7566B656B4D85EF927A7C06A3CFED2E4519A622EE63D5FE5D511F3A019B63FC11F95BBCE7FDE9B058C9A7120209C80C57380843598B623B94FCD71696047F2AE107690E2FCD61EB05DA5A6E0F13FA1EE14C7BE1E55D47D096A7876F2E27A3C36244A986E617D91A3644D7DE98968BFD09A42CEB3B66147A0FC776922AF12DA3377C8F33AAC5CFC8750C2F4CF9894809EFE981F2886364FA81C7590A12244D0066B862D42D78865DDE8F2C8C3E1EEDFAED401AE23623D91923AACCA071EE9DD6E3F8F6C425A606AF0BFEF175A517B6D4F75C56BE51F6DC4595D7454DA1B5DAD05D5969F83FE8DAF21CE6CD4A579512CAFF5F58D9BC9A8E459295D13545DD4AC9B8377B7AEC682CF3D77EFBD46B465D74401FDAC17A6AE4C32F1A805323DC9B87DB38210538E15DB5B9DEDA6A8392E01C4CC402271636FEBE42FE7A2C8135C485A1A104F49B1F484FB18A80C8C097D3D0C20A9B4D930986338E2DF55659CDF50CDE50E45E05CA09A3948BBE2F3D68E3EA5F3BBF3E2E9FF21BB45B18AFB444F675416C27C55F3F52DA11B610D6C0D707901B5A393F8151801A3E2E387537DC21DAEF83D1441C47488660C0075FFE01D0E20F65578FFB6CF2B39825384B295FBD839B46FA6416C0A4
tmp_aes_key = F9AC244019A3D256B2D0B2A57CCBCB837A05D4A70685F26C926FBAAED69F4148
tmp_aes_iv = 1F5D43DF6BEE2B294A86F4F1DCE4E0A30C97CECB011C15F2E09241A4DB3F7E5E</code></pre>
<!-- end server_DH_inner_data_input -->
<p>Yielding:</p>
<!-- start server_DH_inner_data_output -->
<pre><code>answer_with_hash = 581A0BF9CCAD9F42310DD6E06AAB84510994EDCFBA0D89B5AC7EC649662ECF3CF3BA991B9D8DABD56C8D9CF57754AE5A5CB305759A6050D003000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE0001007B42B299039FBDE3A58969368398697AC952271DC43A5438E7782BB65291F69483575A6ED2C3630E9175C7D423174305FF382CE1DED0895A9CEAFA2EE922D6ABF3096665988A10F86D458A967E1328154A8B6DEFA57C0443276AAAAFC9BF7EBEFDFD6B1A512B7A7DA6042C75AD9A1DA99C1B8DA5291E614F942FE51FD4FC134D8C8E4A2020215FD803455E0D1CF12A48B03E77FE29424D184D095B545539183AEAC1C5DA980ADA7EF3BC20493A00BBEAD819933981E9184BED92211B76C02B66DC1A54918634A1AEB3167178B846465FB172CD525C2AC7DEA4C7C342068EECED7240981B353F47601F45B52E83B7AD97D400CF5FD31F810808D8D857EB8924930E0DC36658A349CC05C7B750
answer = BA0D89B5AC7EC649662ECF3CF3BA991B9D8DABD56C8D9CF57754AE5A5CB305759A6050D003000000FE000100C71CAEB9C6B1C9048E6C522F70F13F73980D40238E3E21C14934D037563D930F48198A0AA7C14058229493D22530F4DBFA336F6E0AC925139543AED44CCE7C3720FD51F69458705AC68CD4FE6B6B13ABDC9746512969328454F18FAF8C595F642477FE96BB2A941D5BCD1D4AC8CC49880708FA9B378E3C4F3A9060BEE67CF9A4A4A695811051907E162753B56B0F6B410DBA74D8A84B2A14B3144E0EF1284754FD17ED950D5965B4B9DD46582DB1178D169C6BC465B0D6FF9CA3928FEF5B9AE4E418FC15E83EBEA0F87FA9FF5EED70050DED2849F47BF959D956850CE929851F0D8115F635B105EE2E4E15D04B2454BF6F4FADF034B10403119CD8E3B92FCC5BFE0001007B42B299039FBDE3A58969368398697AC952271DC43A5438E7782BB65291F69483575A6ED2C3630E9175C7D423174305FF382CE1DED0895A9CEAFA2EE922D6ABF3096665988A10F86D458A967E1328154A8B6DEFA57C0443276AAAAFC9BF7EBEFDFD6B1A512B7A7DA6042C75AD9A1DA99C1B8DA5291E614F942FE51FD4FC134D8C8E4A2020215FD803455E0D1CF12A48B03E77FE29424D184D095B545539183AEAC1C5DA980ADA7EF3BC20493A00BBEAD819933981E9184BED92211B76C02B66DC1A54918634A1AEB3167178B846465FB172CD525C2AC7DEA4C7C342068EECED7240981B353F47601F45B52E83B7AD97D400CF5FD31F810808D8D857EB8924930E0DC36658A349CC05C7B750</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 AC 7E C6 49 66 2E CF 3C F3 BA 99 1B
0010 | 9D 8D AB D5 6C 8D 9C F5 77 54 AE 5A 5C B3 05 75
0020 | 9A 60 50 D0 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 | 7B 42 B2 99 03 9F BD E3 A5 89 69 36 83 98 69 7A
0140 | C9 52 27 1D C4 3A 54 38 E7 78 2B B6 52 91 F6 94
0150 | 83 57 5A 6E D2 C3 63 0E 91 75 C7 D4 23 17 43 05
0160 | FF 38 2C E1 DE D0 89 5A 9C EA FA 2E E9 22 D6 AB
0170 | F3 09 66 65 98 8A 10 F8 6D 45 8A 96 7E 13 28 15
0180 | 4A 8B 6D EF A5 7C 04 43 27 6A AA AF C9 BF 7E BE
0190 | FD FD 6B 1A 51 2B 7A 7D A6 04 2C 75 AD 9A 1D A9
01A0 | 9C 1B 8D A5 29 1E 61 4F 94 2F E5 1F D4 FC 13 4D
01B0 | 8C 8E 4A 20 20 21 5F D8 03 45 5E 0D 1C F1 2A 48
01C0 | B0 3E 77 FE 29 42 4D 18 4D 09 5B 54 55 39 18 3A
01D0 | EA C1 C5 DA 98 0A DA 7E F3 BC 20 49 3A 00 BB EA
01E0 | D8 19 93 39 81 E9 18 4B ED 92 21 1B 76 C0 2B 66
01F0 | DC 1A 54 91 86 34 A1 AE B3 16 71 78 B8 46 46 5F
0200 | B1 72 CD 52 5C 2A C7 DE A4 C7 C3 42 06 8E EC ED
0210 | 72 40 98 1B 35 3F 47 60 1F 45 B5 2E 83 B7 AD 97
0220 | D4 00 CF 5F D3 1F 81 08 08 D8 D8 57 EB 89 24 93
0230 | 0E 0D C3 66</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>AC7EC649662ECF3CF3BA991B9D8DABD5</code></td>
<td>Value generated by client in Step 1</td>
</tr>
<tr>
<td>server_nonce</td>
<td>20, 16</td>
<td><code>6C8D9CF57754AE5A5CB305759A6050D0</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>FE0001007B42B299039FBDE3A5896936</code> <code>8398697AC952271DC43A5438E7782BB6</code> <code>5291F69483575A6ED2C3630E9175C7D4</code> <code>23174305FF382CE1DED0895A9CEAFA2E</code> <code>E922D6ABF3096665988A10F86D458A96</code> <code>7E1328154A8B6DEFA57C0443276AAAAF</code> <code>C9BF7EBEFDFD6B1A512B7A7DA6042C75</code> <code>AD9A1DA99C1B8DA5291E614F942FE51F</code> <code>D4FC134D8C8E4A2020215FD803455E0D</code> <code>1CF12A48B03E77FE29424D184D095B54</code> <code>5539183AEAC1C5DA980ADA7EF3BC2049</code> <code>3A00BBEAD819933981E9184BED92211B</code> <code>76C02B66DC1A54918634A1AEB3167178</code> <code>B846465FB172CD525C2AC7DEA4C7C342</code> <code>068EECED7240981B353F47601F45B52E</code> <code>83B7AD97D400CF5FD31F810808D8D857</code><br> <code>EB892493</code></td>
<td><code>g_a</code> diffie-hellman parameter</td>
</tr>
<tr>
<td>server_time</td>
<td>560, 4</td>
<td><code>0E0DC366</code> (1724058894 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 = 592CF3A19B9F0EAF00180A82A163D2734BD5B520CD6E7DFAFEACCDB4E64203CCB37CE3D94B45F10AF1D590B9FE8ACEED5FC0390C4B82FCC6E7FB83744382FC1643953D8E7B63AF64EEF000B16EAA8A5B80A8E432A1C23EDA3595E595FFEEB429F54B3CEA2A505B5E4CE9B43CA620FE8BB21079C53900852A26CD29062D22176B711435EBA75E446C8C72CE622E461D9D8C4322E0C2170E825E383B45C88A04E5C1CB33E19A859EB12D81F9AE6A3483A6DD45545F56227EE76841462EE855901E5121C73CAC985F6A21655557AE0ED4659B8F6B383C90F13B98ECF55A9F242EB1B0C5E695B83D1015236DED146C70C4D8C421E8B61F21BBBD8714C6656C06B162</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 = 8D1278EB55A89D367A6E59DA3EDE2FB197719FEDB8D0267AE15A609E6E631352A2BAF8C2877AD56010AF1A7C28C58F67C82E7F16360B40519FE75E169930B96F55D677B3F248E01472A76800BC08CE8DAA8919E4902D5E9C5B344AD4D75DFA7500701C0B6E43BCB27DD1038B77DA5BE15E0478C97F71650D656D8788144673597AA665EDDDC485F703AB0A326BCCB8C11D2CB748673D4DD5BD21C279F31F893036930DC74DD564CBC2DE3FB243032979A41CFDB7FD06463F43721E79D0C2FD44F4BE371C7385D48CC71D7A104CF1BB8CC21AC3FC7E64FD647021F77864DD28A617F2386160A7DCD7BA7EA71C1DE7D21B304BEE614B3F24031F70E2CE02368BC7</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 AC 7E C6 49 66 2E CF 3C F3 BA 99 1B
0010 | 9D 8D AB D5 6C 8D 9C F5 77 54 AE 5A 5C B3 05 75
0020 | 9A 60 50 D0 00 00 00 00 00 00 00 00 FE 00 01 00
0030 | 8D 12 78 EB 55 A8 9D 36 7A 6E 59 DA 3E DE 2F B1
0040 | 97 71 9F ED B8 D0 26 7A E1 5A 60 9E 6E 63 13 52
0050 | A2 BA F8 C2 87 7A D5 60 10 AF 1A 7C 28 C5 8F 67
0060 | C8 2E 7F 16 36 0B 40 51 9F E7 5E 16 99 30 B9 6F
0070 | 55 D6 77 B3 F2 48 E0 14 72 A7 68 00 BC 08 CE 8D
0080 | AA 89 19 E4 90 2D 5E 9C 5B 34 4A D4 D7 5D FA 75
0090 | 00 70 1C 0B 6E 43 BC B2 7D D1 03 8B 77 DA 5B E1
00A0 | 5E 04 78 C9 7F 71 65 0D 65 6D 87 88 14 46 73 59
00B0 | 7A A6 65 ED DD C4 85 F7 03 AB 0A 32 6B CC B8 C1
00C0 | 1D 2C B7 48 67 3D 4D D5 BD 21 C2 79 F3 1F 89 30
00D0 | 36 93 0D C7 4D D5 64 CB C2 DE 3F B2 43 03 29 79
00E0 | A4 1C FD B7 FD 06 46 3F 43 72 1E 79 D0 C2 FD 44
00F0 | F4 BE 37 1C 73 85 D4 8C C7 1D 7A 10 4C F1 BB 8C
0100 | C2 1A C3 FC 7E 64 FD 64 70 21 F7 78 64 DD 28 A6
0110 | 17 F2 38 61 60 A7 DC D7 BA 7E A7 1C 1D E7 D2 1B
0120 | 30 4B EE 61 4B 3F 24 03 1F 70 E2 CE 02 36 8B C7</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>AC7EC649662ECF3CF3BA991B9D8DABD5</code></td>
<td>Value generated by client in Step 1</td>
</tr>
<tr>
<td>server_nonce</td>
<td>20, 16</td>
<td><code>6C8D9CF57754AE5A5CB305759A6050D0</code></td>
<td>Value received from server in Step 2</td>
</tr>
<tr>
<td>g_b</td>
<td>36, 260</td>
<td><code>FE0001008D1278EB55A89D367A6E59DA</code> <code>3EDE2FB197719FEDB8D0267AE15A609E</code> <code>6E631352A2BAF8C2877AD56010AF1A7C</code> <code>28C58F67C82E7F16360B40519FE75E16</code> <code>9930B96F55D677B3F248E01472A76800</code> <code>BC08CE8DAA8919E4902D5E9C5B344AD4</code> <code>D75DFA7500701C0B6E43BCB27DD1038B</code> <code>77DA5BE15E0478C97F71650D656D8788</code> <code>144673597AA665EDDDC485F703AB0A32</code> <code>6BCCB8C11D2CB748673D4DD5BD21C279</code> <code>F31F893036930DC74DD564CBC2DE3FB2</code> <code>43032979A41CFDB7FD06463F43721E79</code> <code>D0C2FD44F4BE371C7385D48CC71D7A10</code> <code>4CF1BB8CC21AC3FC7E64FD647021F778</code> <code>64DD28A617F2386160A7DCD7BA7EA71C</code> <code>1DE7D21B304BEE614B3F24031F70E2CE</code><br> <code>02368BC7</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 = 54B64366AC7EC649662ECF3CF3BA991B9D8DABD56C8D9CF57754AE5A5CB305759A6050D00000000000000000FE0001008D1278EB55A89D367A6E59DA3EDE2FB197719FEDB8D0267AE15A609E6E631352A2BAF8C2877AD56010AF1A7C28C58F67C82E7F16360B40519FE75E169930B96F55D677B3F248E01472A76800BC08CE8DAA8919E4902D5E9C5B344AD4D75DFA7500701C0B6E43BCB27DD1038B77DA5BE15E0478C97F71650D656D8788144673597AA665EDDDC485F703AB0A326BCCB8C11D2CB748673D4DD5BD21C279F31F893036930DC74DD564CBC2DE3FB243032979A41CFDB7FD06463F43721E79D0C2FD44F4BE371C7385D48CC71D7A104CF1BB8CC21AC3FC7E64FD647021F77864DD28A617F2386160A7DCD7BA7EA71C1DE7D21B304BEE614B3F24031F70E2CE02368BC7
padding = FE5409530AA9DA24EA778019
tmp_aes_key = F9AC244019A3D256B2D0B2A57CCBCB837A05D4A70685F26C926FBAAED69F4148
tmp_aes_iv = 1F5D43DF6BEE2B294A86F4F1DCE4E0A30C97CECB011C15F2E09241A4DB3F7E5E</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 = 6DB219ECBF7D9D7F82C74ED3A0F94C6B2DD8EFD9D013CE3C83711187BCDFAF7A7D6422CC3563BF797CF49D6B019899E8B0A9F6BFF7343A2F7B257E37C5AF8BBEC9B107A84D17BD11567846C804C25CF1D64A669410EFCF2D6FDCE346ECD3431AFAB0B7C0A4B514CC502B6AA66D3FFFBB240B0926E2747E687910C2BA53CAFAC8F7F678D678896169CBD6178733F069AD85B23CA0A84BF76A52AA470FDA804A1F9FBF34A6C944E419697AE7D2B9A4FD2D28BD44204E66FF5E6E7178669128D68EDE1D03B26020A1E9E2F38780FEA68AEB6297F7A282E164C9BA2DC5317A7541B26F726AB2B13E8192AFCE8A664FCFC71FCD0B6A7F1A829ED70CB7F0126E0E15FCAFE07E103CA90992E00071C996A2257B25FA51EE5F2F97255C15FADCE648D9051C03F0F5F5ABA532CA7A5340E5424E4831B296F361FE4C47ACEC49F0F00E8DA434A5FC4CFAB5D004D9867C9CA9195EC6</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 98 C9 0E 00 0E 0D C3 66
0010 | 78 01 00 00 1F 5F 04 F5 AC 7E C6 49 66 2E CF 3C
0020 | F3 BA 99 1B 9D 8D AB D5 6C 8D 9C F5 77 54 AE 5A
0030 | 5C B3 05 75 9A 60 50 D0 FE 50 01 00 6D B2 19 EC
0040 | BF 7D 9D 7F 82 C7 4E D3 A0 F9 4C 6B 2D D8 EF D9
0050 | D0 13 CE 3C 83 71 11 87 BC DF AF 7A 7D 64 22 CC
0060 | 35 63 BF 79 7C F4 9D 6B 01 98 99 E8 B0 A9 F6 BF
0070 | F7 34 3A 2F 7B 25 7E 37 C5 AF 8B BE C9 B1 07 A8
0080 | 4D 17 BD 11 56 78 46 C8 04 C2 5C F1 D6 4A 66 94
0090 | 10 EF CF 2D 6F DC E3 46 EC D3 43 1A FA B0 B7 C0
00A0 | A4 B5 14 CC 50 2B 6A A6 6D 3F FF BB 24 0B 09 26
00B0 | E2 74 7E 68 79 10 C2 BA 53 CA FA C8 F7 F6 78 D6
00C0 | 78 89 61 69 CB D6 17 87 33 F0 69 AD 85 B2 3C A0
00D0 | A8 4B F7 6A 52 AA 47 0F DA 80 4A 1F 9F BF 34 A6
00E0 | C9 44 E4 19 69 7A E7 D2 B9 A4 FD 2D 28 BD 44 20
00F0 | 4E 66 FF 5E 6E 71 78 66 91 28 D6 8E DE 1D 03 B2
0100 | 60 20 A1 E9 E2 F3 87 80 FE A6 8A EB 62 97 F7 A2
0110 | 82 E1 64 C9 BA 2D C5 31 7A 75 41 B2 6F 72 6A B2
0120 | B1 3E 81 92 AF CE 8A 66 4F CF C7 1F CD 0B 6A 7F
0130 | 1A 82 9E D7 0C B7 F0 12 6E 0E 15 FC AF E0 7E 10
0140 | 3C A9 09 92 E0 00 71 C9 96 A2 25 7B 25 FA 51 EE
0150 | 5F 2F 97 25 5C 15 FA DC E6 48 D9 05 1C 03 F0 F5
0160 | F5 AB A5 32 CA 7A 53 40 E5 42 4E 48 31 B2 96 F3
0170 | 61 FE 4C 47 AC EC 49 F0 F0 0E 8D A4 34 A5 FC 4C
0180 | FA B5 D0 04 D9 86 7C 9C A9 19 5E C6</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>98C90E000E0DC366</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>AC7EC649662ECF3CF3BA991B9D8DABD5</code></td>
<td>Value generated by client in Step 1</td>
</tr>
<tr>
<td>server_nonce</td>
<td>40, 16</td>
<td><code>6C8D9CF57754AE5A5CB305759A6050D0</code></td>
<td>Value received from server in Step 2</td>
</tr>
<tr>
<td>encrypted_data</td>
<td>56, 340</td>
<td><code>FE5001006DB219ECBF7D9D7F82C74ED3</code> <code>A0F94C6B2DD8EFD9D013CE3C83711187</code> <code>BCDFAF7A7D6422CC3563BF797CF49D6B</code> <code>019899E8B0A9F6BFF7343A2F7B257E37</code> <code>C5AF8BBEC9B107A84D17BD11567846C8</code> <code>04C25CF1D64A669410EFCF2D6FDCE346</code> <code>ECD3431AFAB0B7C0A4B514CC502B6AA6</code> <code>6D3FFFBB240B0926E2747E687910C2BA</code> <code>53CAFAC8F7F678D678896169CBD61787</code> <code>33F069AD85B23CA0A84BF76A52AA470F</code> <code>DA804A1F9FBF34A6C944E419697AE7D2</code> <code>B9A4FD2D28BD44204E66FF5E6E717866</code> <code>9128D68EDE1D03B26020A1E9E2F38780</code> <code>FEA68AEB6297F7A282E164C9BA2DC531</code> <code>7A7541B26F726AB2B13E8192AFCE8A66</code> <code>4FCFC71FCD0B6A7F1A829ED70CB7F012</code> <code>6E0E15FCAFE07E103CA90992E00071C9</code> <code>96A2257B25FA51EE5F2F97255C15FADC</code> <code>E648D9051C03F0F5F5ABA532CA7A5340</code> <code>E5424E4831B296F361FE4C47ACEC49F0</code> <code>F00E8DA434A5FC4CFAB5D004D9867C9C</code><br> <code>A9195EC6</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 = BD19EE3E32B7F2A3B21CE27F251253E106ACFE7401C24BAFC48AFF27D4CE65087D21DA335CC0B0C3E61C9968FFFF1DFDC3B15F976115D216753C1ECE895D93F2C24F5FA5DF76AF1C3BE8FEF67D1A70133BF587A93E823EC2F1F859899F9EDA79E004873F21492438EF308B467B9F872C188AE7ED0EEFEA51861D70497863092E5ECD0A440C1CBDC9C183B861C21E6E176645F001E551F29188E07ED84C6BBE7E3266F151D0F2C0CC00F867F821824BB81DF5C510F8E83AEE99D4A08A24209A69817E9F7DEBE86C1C0102BB27D2CA185D60CD31C283EC0AAC6FE7CC02BE53B92EE051F9FC8CC703184DD92303C0F8D7DB74C2F3BC705FCF33BD02B3A8EB4E6957</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 74 0C 9C 0F 0D C3 66
0010 | 60 00 00 00 34 F7 CB 3B AC 7E C6 49 66 2E CF 3C
0020 | F3 BA 99 1B 9D 8D AB D5 6C 8D 9C F5 77 54 AE 5A
0030 | 5C B3 05 75 9A 60 50 D0 A1 20 67 1F 5B 7A 78 E9
0040 | DB D0 18 6D 6D B6 73 54</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>01740C9C0F0DC366</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>60000000</code> (96 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>AC7EC649662ECF3CF3BA991B9D8DABD5</code></td>
<td>Value generated by client in Step 1</td>
</tr>
<tr>
<td>server_nonce</td>
<td>40, 16</td>
<td><code>6C8D9CF57754AE5A5CB305759A6050D0</code></td>
<td>Value received from server in Step 2</td>
</tr>
<tr>
<td>new_nonce_hash1</td>
<td>56, 16</td>
<td><code>A120671F5B7A78E9DBD0186D6DB67354</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>