root / dotorg / v8 / html / beps / bep_0008.html

Revision 10853, 27.4 kB (checked in by dave, 11 months ago)

regenerated html.

Line 
1<?xml version="1.0" encoding="utf-8" ?>
2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4<head>
5<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
7<title></title>
8<link rel="stylesheet" href="../css/bep.css" type="text/css" />
9</head>
10<body>
11<div class="document">
12
13<div id="upper" class="clear">
14<div id="wrap">
15<div id="header">
16<h1><a href="../index.html">BitTorrent<span>.org</span></a></h1>
17</div>
18<div id="nav">
19<ul>
20<li><a href="../index.html">Home</a></li>
21<li><a href="../introduction.html">For Users</a></li>
22<li><span>For Developers</span></li>
23<!-- <li><a href="./blog">Blog</a></li> -->
24<li><a href="../donate.html">Donate!</a></li>
25</ul>
26</div> <!-- nav -->
27<!-- ### Begin Content ### -->
28<div id="second">
29
30
31
32<table class="rfc2822 docutils field-list" frame="void" rules="none">
33<col class="field-name" />
34<col class="field-body" />
35<tbody valign="top">
36<tr class="field"><th class="field-name">BEP:</th><td class="field-body">8</td>
37</tr>
38<tr class="field"><th class="field-name">Title:</th><td class="field-body">Tracker Peer Obfuscation</td>
39</tr>
40<tr class="field"><th class="field-name">Version:</th><td class="field-body">10851</td>
41</tr>
42<tr class="field"><th class="field-name">Last-Modified:</th><td class="field-body"><a class="reference external" href="https://svn.bittorrent.com/trac.cgi/browser/dotorg/trunk/html/beps/bep_0008.rst">2008-02-15 15:04:41 -0800 (Fri, 15 Feb 2008)</a></td>
43</tr>
44<tr class="field"><th class="field-name">Author:</th><td class="field-body">David Harrison &lt;dave&#32;&#97;t&#32;bittorrent.com&gt;, Anthony Ciani &lt;tony&#32;&#97;t&#32;ciani.phy.uic.edu&gt;, Arvid Norberg &lt;arvid&#32;&#97;t&#32;bittorrent.com&gt;, Greg Hazel &lt;greg&#32;&#97;t&#32;bittorrent.com&gt;</td>
45</tr>
46<tr class="field"><th class="field-name">Status:</th><td class="field-body">Draft</td>
47</tr>
48<tr class="field"><th class="field-name">Type:</th><td class="field-body">Standards Track</td>
49</tr>
50<tr class="field"><th class="field-name">Created:</th><td class="field-body">31-Jan-2008</td>
51</tr>
52<tr class="field"><th class="field-name">Post-History:</th><td class="field-body"></td>
53</tr>
54</tbody>
55</table>
56<hr />
57<div class="contents topic" id="contents">
58<p class="topic-title first">Contents</p>
59<ul class="simple">
60<li><a class="reference internal" href="#announce-parameter" id="id8">Announce Parameter</a></li>
61<li><a class="reference internal" href="#announce-response" id="id9">Announce Response</a></li>
62<li><a class="reference internal" href="#peer-list-obfuscation" id="id10">Peer List Obfuscation</a></li>
63<li><a class="reference internal" href="#optimizations" id="id11">Optimizations</a></li>
64<li><a class="reference internal" href="#backwards-compatibility" id="id12">Backwards Compatibility</a></li>
65<li><a class="reference internal" href="#rationale" id="id13">Rationale</a></li>
66<li><a class="reference internal" href="#references" id="id14">References</a></li>
67<li><a class="reference internal" href="#example-python-code" id="id15">Example Python Code</a></li>
68</ul>
69</div>
70<p>This extends the tracker protocol to support simple obfuscation of the
71peers it returns, using the infohash as a shared secret between the
72peer and the tracker. The obfuscation does not provide any security
73against eavesdroppers that know the infohash of the torrent.  The goal
74is to prevent internet service providers and other network
75administrators from blocking or disrupting bittorrent traffic
76connections that span between the receiver of a tracker response and
77any peer IP-port appearing in that tracker response.</p>
78<p>The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;,
79&quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are
80to be interpreted as described in IETF <a class="reference external" href="http://tools.ietf.org/html/rfc2119">RFC 2119</a> <a class="footnote-reference" href="#id6" id="id7">[5]</a>.</p>
81<div class="section" id="announce-parameter">
82<h1>Announce Parameter</h1>
83<p>When using this extension, instead of passing the <tt class="docutils literal"><span class="pre">info_hash</span></tt> parameter
84to the tracker, a <tt class="docutils literal"><span class="pre">sha_ih</span></tt> is passed.</p>
85<p>The value of <tt class="docutils literal"><span class="pre">sha_ih</span></tt> MUST be the info-hash of the torrent, with a second
86SHA-1 applied to it.</p>
87<p>For example if a torrent has infohash with hex representation
88<tt class="docutils literal"><span class="pre">aaf4c61ddcc5e8a2dabedef3b482cd9aea9434d</span></tt> then its <tt class="docutils literal"><span class="pre">sha_ih</span></tt> is
89<tt class="docutils literal"><span class="pre">sha1(infohash)='6b4f89a54e2d27ecd7e8da5b4ab8fd9d1d8b119'</span></tt>.</p>
90<p>The value MUST be url encoded, just like the <tt class="docutils literal"><span class="pre">info_hash</span></tt>.  Thus the
91<tt class="docutils literal"><span class="pre">sha_ih</span></tt> above when url encoded becomes
92<tt class="docutils literal"><span class="pre">kO%89%A5N-%27%EC%D7%E8%DA%05%B4%AB%8F%D9%D1%D8%B1%19</span></tt>.</p>
93<p>This extension does not change the semantics of any parameter passed
94in the peer's announce.</p>
95</div>
96<div class="section" id="announce-response">
97<h1>Announce Response</h1>
98<p>If the tracker supports this extension, the response should be exactly
99the same as if the <tt class="docutils literal"><span class="pre">info_hash</span></tt> had been passed, except that any
100field that contains peer information (such as <tt class="docutils literal"><span class="pre">peers</span></tt>, <tt class="docutils literal"><span class="pre">peers6</span></tt> or
101any other field defined by another extension) MUST be obfuscated as
102described in the next section.</p>
103<p>There are additional parameters the tracker may OPTIONALLY return.
104These are discussed in the <a class="reference internal" href="#optimizations">optimizations</a> section.</p>
105</div>
106<div class="section" id="peer-list-obfuscation">
107<h1>Peer List Obfuscation</h1>
108<p>We distinguish between the <em>tracker peer list</em> and the <em>returned peer
109list</em>.  The <em>tracker peer list</em> contains the ip-port pairs of all
110known peers in a given torrent, i.e., those peers that have reported
111to the tracker that they are transferring the file with a given
112infohash.  The tracker may store this peer list however it wishes.
113The <em>returned peer list</em> contains a packed array of ip-port pairs
114conforming to the BitTorrent protocol specification.  If the swarm is
115sufficiently large then the returned ip-port pairs constitute a subset
116of the ip-port pairs in the <em>tracker peer list</em>.</p>
117<p>The returned peer list is encrypted using RC4-drop768 encryption using
118the infohash as a shared secret and optionally employing an
119initialization vector.</p>
120<p>For the remainder of this document RC4 refers to RC4-drop768.  In the
121process of encryption, RC4 generates a pseudorandom string that is
122XOR'd with the plaintext to generate the ciphertext.  The receiver
123recovers the plaintext by generating the same pseudorandom string and
124XOR'ing it with the ciphertext.  In generating the pseudorandom
125string, the tracker and client MUST discard the first 768 bytes.  The
126next 8 bytes in the pseudorandom string are reserved for optimizations
127discussed in the next section.</p>
128<p>To communicate an initialization vector, the tracker includes in the
129bencoded response the key <tt class="docutils literal"><span class="pre">iv</span></tt> with value set to a byte string
130containing the initialization vector.  The initialization vector can
131be of arbitrary length and is sent in plaintext.</p>
132<p>If the tracker sends no initialization vector then the infohash is
133used as the RC4 key (160 bit key).  If the tracker provides an
134initialization vector then the RC4 key is generated by appending the
135vector to the infohash and then hashing with SHA-1.  The resulting
136hash is then used as the RC4 key.</p>
137<p>For example, given infohash <tt class="docutils literal"><span class="pre">aaf4c61ddcc5e8a2dabedef3b482cd9aea9434d</span></tt>
138and initialization vector <tt class="docutils literal"><span class="pre">abcd</span></tt> both represented in hex, the RC4 key
139is derived as follows:</p>
140<pre class="literal-block">
141key = sha1( 'aaf4c61ddcc5e8a2dabedef3b482cd9aea9434dabcd' )
142</pre>
143<p>The resulting key in hex is <tt class="docutils literal"><span class="pre">f36e9cae87cf33e07645ef5ca745a8a83469f31e</span></tt>.</p>
144<p>It is RECOMMENDED that the tracker use the initialization vector, and
145that it change the <tt class="docutils literal"><span class="pre">iv</span></tt> on roughly the same period as the rerequest
146interval.  The reasoning for this is contained in the rationale.</p>
147</div>
148<div class="section" id="optimizations">
149<h1>Optimizations</h1>
150<p>The described optimizations are OPTIONAL for the tracker, but the
151corresponding client-side MUST be implemented by clients that support
152this extension.  These optimizations hobble the strength of the RC4
153encryption in order to improve tracker performance.  In the <a class="reference internal" href="#rationale">rationale</a>
154section we discuss why hobbling RC4 is reasonable and in many cases
155has negligible foreseen effect on security.</p>
156<p>For the purpose of these optimizations we assume that the tracker
157stores the tracker peer list for each infohash as a packed array that
158can be copied directly into the response.  We further assume that the
159packed array is reused many times and that with each request the
160tracker either returns the entire packed array or copies a single
161contiguous substring from the tracker peer list into the response.</p>
162<p>If the peerlist is represented and used as assumed then to improve
163randomness in the set of peers handed out by the tracker, it is
164RECOMMENDED that the tracker periodically reshuffle the peerlist with
165period similar to the rerequest interval.  After each reshuffle the
166tracker reperforms the operations described in this section.</p>
167<p>To reduce computation the tracker MAY cache the pseudorandom string
168generated by RC4 and reuse it as peers arrive and depart.</p>
169<p>The tracker MAY also cache the encrypted tracker peer list.  To
170support this the tracker MUST pass two additional keys <em>i</em> and <em>n</em>
171each with 32-bit integer values, except the tracker MAY omit <em>i</em> and
172<em>n</em> when <em>i=0</em> and the <em>returned peer list</em> is the entire <em>tracker peer
173list</em>.  Whether the tracker returns <em>i</em> and <em>n</em>, the first 8 bytes of
174the RC4 psuedorandom string are reserved for obscuring <em>i</em> and <em>n</em>.
175We come back to this momentarily.  Decryption starts by XORing from
176<em>6i</em> bytes for ipv4 (or <em>18i</em> for ipv6) into the pseudorandom string
177after the discarded and reserved bytes.  Assuming that the tracker
178encrypted the tracker peer list starting from the first byte after the
179discarded and reserved bytes in the pseudorandom string then <em>i</em> also
180corresponds to the <em>ith</em> ip-port pair in the tracker peer list.</p>
181<p>So that the client and the tracker do not have to generate an
182arbitrarily long pseudorandom string to support large swarms, we
183assume the tracker bounds the length of the pseudorandom string and
184reports the length in ip-port pairs as the value to key <em>n</em><em>n</em>
185excludes reserved and discarded bytes.  We RECOMMEND that <em>n</em> be equal
186to the length of the tracker peer list or random but within constant
187factor of the longest peerlist returned by the tracker, whichever is
188smaller.  Thus the tracker encrypts the <em>jth</em> byte of the <em>ith</em>
189ip-port pair in an ipv4 tracker peer list by XORing with the byte
190<em>(6i+j)</em> <cite>mod</cite> <em>n</em> bytes into the pseudorandom string.</p>
191<p>Transmitting <em>i</em> and <em>n</em> as plaintext would significantly reduce the
192cost for an attacker to recover the pseudorandom string.  The tracker
193MUST XOR the value of <em>i</em> with the first 32 bits of the pseudorandom
194string.  The tracker then XORs <em>n</em> with the next 32 bits from the
195pseudorandom string (see Figure 1).</p>
196<div class="figure">
197<img alt="bep_0008_pseudo.png" src="bep_0008_pseudo.png" />
198<p class="caption"><strong>Figure 1:</strong> The first 768 bytes of the RC4 pseudorandom
199string are discarded.  The key <em>i</em> in the tracker response has
200value <tt class="docutils literal"><span class="pre">x</span> <span class="pre">xor</span> <span class="pre">i</span></tt>.  The key <em>n</em> has value <tt class="docutils literal"><span class="pre">y</span> <span class="pre">xor</span> <span class="pre">n</span></tt>.</p>
201</div>
202<p>We describe encryption in the following example for an ipv4 tracker peer
203list consisting of 3 ip-port pairs, and using an RC4 pseudorandom string
204of length <em>n=2</em>. <em>n</em> is small for purposes of illustration.  Also, for the
205purpose of illustration, the tracker returns only 2 peers at a time.</p>
206<pre class="literal-block">
207Given the following peer list
208(208.72.193.86, 6881), (209.81.173.15,14321), (128.213.6.8, 6881)
209
210As a packed array represented in hex it becomes
211
212d048c1561ae1d151ad0f37f180d506081ae1
213
214which we XOR with an RC4 pseudorandom string excluding discarded and
215reserved bytes, e.g.,
216
217a496e5f9b83e835013d42226
218
219to generate
220
22174de24afa2df5201bedb15d72443e3f1a2df
222</pre>
223<p>Because the RC4 pseudorandom string is shorter than the tracker
224peer list, we wrap to the beginning of the pseudorandom string.</p>
225<p>A tracker returning the first two peers would return the bencoded
226equivalent of:</p>
227<pre class="literal-block">
228peers=74de24afa2df5201bedb15d7, i=0, n=2
229</pre>
230<p>A tracker returning the second and third peer would return the
231bencoded equivalent of:</p>
232<pre class="literal-block">
233peers=5201bedb15d72443e3f1a2df, i=1, n=2
234</pre>
235<p>In each response the tracker includes additional parameters such as
236the rerequest <tt class="docutils literal"><span class="pre">interval</span></tt> and the initialization vector <tt class="docutils literal"><span class="pre">iv</span></tt>.</p>
237<p>The tracker response MUST remain a valid bencoded message.</p>
238</div>
239<div class="section" id="backwards-compatibility">
240<h1>Backwards Compatibility</h1>
241<p>Trackers that support obfuscation are identified in the .torrent file
242by the inclusion of an <tt class="docutils literal"><span class="pre">obfuscate-announce-list</span></tt> which otherwise has the
243same semantics as the <tt class="docutils literal"><span class="pre">announce-list</span></tt> key.  Peers that do not support
244obfuscation simply ignore the <tt class="docutils literal"><span class="pre">obfuscate-announce-list</span></tt>.</p>
245<p>A client that is configured to use this extension should always send
246the <tt class="docutils literal"><span class="pre">sha_ih</span></tt> to any tracker supporting obfuscation.  The client
247SHOULD only contact trackers in the <tt class="docutils literal"><span class="pre">announce-list</span></tt> once the client
248has attempted all trackers in the <tt class="docutils literal"><span class="pre">obfuscate-announce-list</span></tt> and all failed.</p>
249<p>If a tracker that supports obfuscation wishes to allow legacy peers to
250connect to the tracker then the announce URL should appear in both the
251<tt class="docutils literal"><span class="pre">obfuscate-announce-list</span></tt> and the <tt class="docutils literal"><span class="pre">announce-list</span></tt>.</p>
252<p>If a tracker URL appears in both lists running on the same port, and
253the tracker failed to respond when selected from the
254<tt class="docutils literal"><span class="pre">obfuscate-announce-list</span></tt> then the client MAY treat the tracker in
255the <tt class="docutils literal"><span class="pre">announce-list</span></tt> as if it were temporarily unreachable and defer
256trying it until it has tried other trackers in the <tt class="docutils literal"><span class="pre">announce-list</span></tt>.</p>
257<p>Peers MUST never send both the <tt class="docutils literal"><span class="pre">info_hash</span></tt> and <tt class="docutils literal"><span class="pre">sha_ih</span></tt> parameters
258in the same request, since that would defeat the purpose of the shared
259secret.</p>
260<p>Any peer that requests with a <tt class="docutils literal"><span class="pre">sha_ih</span></tt> SHOULD implement Message
261Stream Encryption (MSE) <a class="footnote-reference" href="#mse" id="id1">[1]</a>.  Any peer returned from the tracker
262in response to a request with a <tt class="docutils literal"><span class="pre">sha_ih</span></tt> SHOULD be assumed to
263support Message Stream Encryption.  We include these provisions
264because if a peer communicates with another peer without using MSE
265then the BitTorrent protocol is trivially identified from the first
266twenty bytes of the BitTorrent header and the <tt class="docutils literal"><span class="pre">info_hash</span></tt> appears in
267plaintext as the next twenty bytes, hence also defeating the purpose
268of the shared secret.</p>
269<p>If the tracker does not know enough peers assumed to support MSE to
270return the desired number of peers then it MAY include peers that are
271not assumed to support MSE.  If a peer closes a connection in response
272to an encrypted header then the initiating peer SHOULD assume that the
273peer does not support MSE.  The initiating peer however SHOULD ONLY
274initiate unencrypted connections when all peers have been tried and
275those that support MSE fail to provide &quot;adequate performance.&quot;  We
276intentionally omit any definition of &quot;adequate performance.&quot;</p>
277</div>
278<div class="section" id="rationale">
279<h1>Rationale</h1>
280<p>This extension directly addresses a known attack on the BitTorrent
281protocol performed by some deployed network hardware.  By obscuring
282the ip-port pairs network hardware can no longer easily identify
283ip-port pairs that are running BitTorrent by observing peer-to-tracker
284communications.  This deployed hardware under some conditions disrupts
285BitTorrent connections by injecting forged TCP reset packets.</p>
286<p>This hardware was presumably deployed to get around BitTorrent
287Message Stream Encryption <a class="footnote-reference" href="#mse" id="id2">[1]</a>.  Peers implementing BitTorrent Message Stream
288Encryption obfuscate peer-to-peer connections by employing RC4
289encryption on every byte from the first byte transferred. BitTorrent
290Message Stream Encryption thus increases the difficulty for a device
291observing passing packets to identify BitTorrent peer-to-peer
292connections.</p>
293<p>By using the SHA-1 of the infohash, the tracker is able to identify
294torrents without sending the plaintext infohash and without requiring
295an additional prior exchange of a shared secret.  Where trackers now
296maintain mappings from infohash to the corresponding torrent's
297peerlist and other torrent-specific state, obfuscated trackers would
298need one additional mapping from <tt class="docutils literal"><span class="pre">sha_ih</span></tt> to the torrent's state.
299Trackers may also cache the encrypted version of each torrent's
300tracker peer list, to increase computational performance at the
301expense of increasing memory footprint by a constant factor.</p>
302<p>The obfuscation method meets the following criteria:</p>
303<ul class="simple">
304<li>The entire plaintext of the peer list is not easily obtained even if
305an eavesdropper identifies ip-port pairs from subsequent connections
306initiated by a peer that has received a tracker response.</li>
307<li>Even when a subsequent connection from a peer that has received a
308tracker response is observed by an eavesdropper, it is difficult to
309map the ip-port pair to specific ciphertext to verify that the
310connection is using BitTorrent.</li>
311</ul>
312<p>When the <a class="reference internal" href="#optimizations">optimizations</a> are used,</p>
313<ul class="simple">
314<li>Few computations are performed at request time.</li>
315<li>Encryption may be performed at the time a peer is added.
316The encrypted peer ip and port may be handed out hundreds of times.</li>
317<li>Security is minimally impacted.</li>
318</ul>
319<p>The objective is NOT to create a cryptographically secure protocol
320that can survive unlimited observation of passing packets and
321substantial computational resources on network timescales.  The objective
322is to raise the bar sufficiently to deter attacks based on observing
323ip-port numbers in peer-to-tracker communications.</p>
324<p>If a tracker observes a large number of tracker requests and responses
325and subsequent connections, it is possible to attack the encryption.
326RC4 is known to have a number of weaknesses especially in the way it
327was used with WEP <a class="footnote-reference" href="#borisov" id="id3">[2]</a> <a class="footnote-reference" href="#scott" id="id4">[3]</a> <a class="footnote-reference" href="#stubblefeld" id="id5">[4]</a>.  However,
328with tracker peer obfuscation, the number of bytes transferred between
329the tracker and a client is likely significantly smaller than transferred
330between a wireless computer and a basestation.  An attacker faces a
331much larger task in obtaining sufficient probable plaintext to
332directly break the encryption.</p>
333<p>Hobbling the RC4 encryption by using a bounded-length RC4 pseudorandom
334string for small swarms is likely to have negilgible impact on
335security over any other encyption method since the pseudorandom string
336is probably equal to or longer than the plaintext and thus no part of
337it is repeated in the XOR except as peers arrive or leave the swarm.
338Thus on the timescales of rerequest intervals, nearly the same
339ciphertext is handed to every peer requesting the same infohash.
340Intercepting the same ciphertext multiple times provides no additional
341information to the attacker.  The attacker could correlate ip-port
342pairs in connections following tracker responses, but an attacker
343could do this regardless of the encryption method employed.
344Furthermore more direct methods of traffic analysis applied to
345peer-to-peer communication is available to network operators.</p>
346<p>For larger swarms, hobbling RC4 may more significantly impact breaking
347the encryption since the same pseudorandom string is used repeatedly
348across the peer list.  Some study is in order on this point taking
349into account that the tracker can periodically change intiailization
350vectors.</p>
351<p>We know from experience that periodically reshuffling peer lists on
352the order of the rerequest interval negligibly impacts tracker
353performance even with swarms containing millions of peers.  Generating
354a new pseudorandom string using RC4 on this same time interval is
355likely to incur negligible performance penalty because 1) RC4 is a
356small constant factor more expensive than a shuffle on an input string
357of equal length, 2) the generated pseudorandom string is only <em>n</em>
358ip-port pairs long where recommended <em>n</em> is within a small constant
359factor larger than the largest <em>returned peer list</em> and thus much
360smaller than the <em>tracker peer list</em> for large swarms, and 3) the cost
361of the XOR operation is lighter weight than performing a random
362shuffle.</p>
363</div>
364<div class="section" id="references">
365<h1>References</h1>
366<table class="docutils footnote" frame="void" id="mse" rules="none">
367<colgroup><col class="label" /><col /></colgroup>
368<tbody valign="top">
369<tr><td class="label">[1]</td><td><em>(<a class="fn-backref" href="#id1">1</a>, <a class="fn-backref" href="#id2">2</a>)</em> BitTorrent Message Stream Encryption
370(<a class="reference external" href="http://www.azureuswiki.com/index.php/Message_Stream_Encryption">http://www.azureuswiki.com/index.php/Message_Stream_Encryption</a>)</td></tr>
371</tbody>
372</table>
373<table class="docutils footnote" frame="void" id="borisov" rules="none">
374<colgroup><col class="label" /><col /></colgroup>
375<tbody valign="top">
376<tr><td class="label"><a class="fn-backref" href="#id3">[2]</a></td><td>Nikita Borisov, Ian Goldberg, and David Wagner. Intercepting
377mobile communications: the insecurity of 802.11. In ACM MobiCom 2001,
378pages 180-189. ACM Press, 2001.</td></tr>
379</tbody>
380</table>
381<table class="docutils footnote" frame="void" id="scott" rules="none">
382<colgroup><col class="label" /><col /></colgroup>
383<tbody valign="top">
384<tr><td class="label"><a class="fn-backref" href="#id4">[3]</a></td><td>Scott R. Fluhrer, Itsik Mantin, and Adi
385Shamir. Weaknesses in the key scheduling algorithm of RC4. In Serge
386Vaudenay and Amr M. Youssef, editors, Selected Areas in
387Cryptography 2001, volume 2259 of Lecture Notes in Computer
388Science, pages 1-24. Springer, 2001.</td></tr>
389</tbody>
390</table>
391<table class="docutils footnote" frame="void" id="stubblefeld" rules="none">
392<colgroup><col class="label" /><col /></colgroup>
393<tbody valign="top">
394<tr><td class="label"><a class="fn-backref" href="#id5">[4]</a></td><td>Adam Stubblefeld, John Ioannidis, and Aviel
395D. Rubin. A key recovery attack on the 802.11b wired equivalent
396privacy protocol (WEP). ACM Transactions on Information and System
397Security, 7(2):319-332, May 2004.</td></tr>
398</tbody>
399</table>
400<table class="docutils footnote" frame="void" id="id6" rules="none">
401<colgroup><col class="label" /><col /></colgroup>
402<tbody valign="top">
403<tr><td class="label"><a class="fn-backref" href="#id7">[5]</a></td><td><a class="reference external" href="http://tools.ietf.org/html/rfc2119">http://tools.ietf.org/html/rfc2119</a></td></tr>
404</tbody>
405</table>
406</div>
407<div class="section" id="example-python-code">
408<h1>Example Python Code</h1>
409<p>Request handling in a dummy tracker implementing tracker peer obfuscation:</p>
410<pre class="literal-block">
411from sha import sha
412from random import randint
413from struct import unpack
414from rc4 import rc4  # rc4(k) generates k RC4 pseudorandom bytes.
415
416rand = open(&quot;/dev/random&quot;,&quot;r&quot;).read
417rc4 = rc4()
418
419# tracker configuration
420MAX_PEERS = 100
421
422# per torrent state.
423infohash = sha(&quot;dummy_info&quot;).digest()
424pseudo = ''                        # pseudorandom RC4 string.
425num_peers = 1000                   # current swarm size.
426tracker_peer_list = rand(6) * num_peers
427obfuscated_tracker_peer_list = ''
428
429def xor(plaintext,pseudo):
430  isint = False
431  if type(plaintext) == int: # convert to byte string.
432    plaintext = &quot;&quot;.join([chr(int(x,16)) for x in &quot;%.4x&quot; % plaintext])
433    isint = True
434  n = len(pseudo)
435  ciphertext = &quot;&quot;.join(
436    [chr(ord(pseudo[i%n])^ord(plaintext[i])) for i in xrange(len(plaintext))])
437  if isint:
438    ciphertext = unpack(&quot;!I&quot;, ciphertext)[0]   # convert back to unsigned int
439  return ciphertext
440
441def init():  # called once per rerequest interval.
442  global iv, x, n, n_xor_y, obfuscated_tracker_peer_list
443  iv = rand(20)
444  rc4.key = sha(infohash + iv).digest()
445  rc4(768)                         # discard first 768
446  x = rc4(4)
447  y = rc4(4)
448  n = min(num_peers, randint(MAX_PEERS * 2, MAX_PEERS * 4))
449  n_xor_y = xor(n,y)
450  pseudo = rc4(n*6)
451  obfuscated_tracker_peer_list = xor(tracker_peer_list,pseudo)
452
453def getpeers( numwant ):
454  global iv, x, n, n_xor_y, obfuscated_tracker_peer_list
455  response = {}
456  response['iv'] = iv
457  numwant = min(numwant, MAX_PEERS)
458  if numwant &gt;= num_peers:
459    response['peers'] = obfuscated_tracker_peer_list
460    return response
461
462  i = randint(0,num_peers-numwant)
463