root / dotorg / v6 / html / beps / bep_0008.html

Revision 10818, 27.9 kB (checked in by dave, 11 months ago)

regenerated html reflecting changes in previous commit.

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">10811</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 00:55:45 -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.  The string from which the RC4 key
137is derived whether it be the infohash or the SHA-1 of the
138initialization vector appended to the infohash is called the
139<em>intermediate string</em>.</p>
140<p>For example, given infohash <tt class="docutils literal"><span class="pre">aaf4c61ddcc5e8a2dabedef3b482cd9aea9434d</span></tt>
141and initialization vector <tt class="docutils literal"><span class="pre">abcd</span></tt> both represented in hex, the RC4 key
142is derived as follows:</p>
143<pre class="literal-block">
144key = sha1( 'aaf4c61ddcc5e8a2dabedef3b482cd9aea9434dabcd' )
145</pre>
146<p>where [i:j] denotes the <em>ith</em> through <em>jth</em> bit including the <em>ith</em>
147but excluding the <em>jth</em>.  The resulting key in hex is
148<tt class="docutils literal"><span class="pre">f36e9cae87cf33e07645ef5ca745a8a83469f31e</span></tt>.</p>
149<p>It is RECOMMENDED that the tracker use the initialization vector, and
150that it change the <tt class="docutils literal"><span class="pre">iv</span></tt> on roughly the same period as the rerequest
151interval.  The reasoning for this is contained in the rationale.</p>
152</div>
153<div class="section" id="optimizations">
154<h1>Optimizations</h1>
155<p>The described optimizations are OPTIONAL for the tracker, but the
156corresponding client-side MUST be implemented by clients that support
157this extension.  These optimizations hobble the strength of the RC4
158encryption in order to improve tracker performance.  In the <a class="reference internal" href="#rationale">rationale</a>
159section we discuss why hobbling RC4 is reasonable and in many cases
160has negligible foreseen effect on security.</p>
161<p>For the purpose of these optimizations we assume that the tracker
162stores the tracker peer list for each infohash as a packed array that
163can be copied directly into the response.  We further assume that the
164packed array is reused many times and that with each request the
165tracker either returns the entire packed array or copies a single
166contiguous substring from the tracker peer list into the response.</p>
167<p>If the peerlist is represented and used as assumed then to improve
168randomness in the set of peers handed out by the tracker, it is
169RECOMMENDED that the tracker periodically reshuffle the peerlist with
170period similar to the rerequest interval.  After each reshuffle the
171tracker reperforms the operations described in this section.</p>
172<p>To reduce computation the tracker MAY cache the pseudorandom string
173generated by RC4 and reuse it as peers arrive and depart.</p>
174<p>The tracker MAY also cache the encrypted tracker peer list.  To
175support this the tracker MUST pass two additional keys <em>i</em> and <em>n</em>
176each with 32-bit integer values, except the tracker MAY omit <em>i</em> and
177<em>n</em> when <em>i=0</em> and the <em>returned peer list</em> is the entire <em>tracker peer
178list</em>.  Whether the tracker returns <em>i</em> and <em>n</em>, the first 8 bytes of
179the RC4 psuedorandom string are reserved for obscuring <em>i</em> and <em>n</em>.
180We come back to this momentarily.  Decryption starts by XORing from
181<em>6i</em> bytes for ipv4 (or <em>18i</em> for ipv6) into the pseudorandom string
182after the discarded and reserved bytes.  Assuming that the tracker
183encrypted the tracker peer list starting from the first byte after the
184discarded and reserved bytes in the pseudorandom string then <em>i</em> also
185corresponds to the <em>ith</em> ip-port pair in the tracker peer list.</p>
186<p>So that the client and the tracker do not have to generate an
187arbitrarily long pseudorandom string to support large swarms, we
188assume the tracker bounds the length of the pseudorandom string and
189reports the length in ip-port pairs as the value to key <em>n</em><em>n</em>
190excludes reserved and discarded bytes.  We RECOMMEND that <em>n</em> be equal
191to the length of the tracker peer list or random but within constant
192factor of the longest peerlist returned by the tracker, whichever is
193smaller.  Thus the tracker encrypts the <em>jth</em> byte of the <em>ith</em>
194ip-port pair in an ipv4 tracker peer list by XORing with the byte
195<em>(6i+j)</em> <cite>mod</cite> <em>n</em> bytes into the pseudorandom string.</p>
196<p>Transmitting <em>i</em> and <em>n</em> as plaintext would significantly reduce the
197cost for an attacker to recover the pseudorandom string.  The tracker
198MUST XOR the value of <em>i</em> with the first 32 bits of the pseudorandom
199string.  The tracker then XORs <em>n</em> with the next 32 bits from the
200pseudorandom string (see Figure 1).</p>
201<div class="figure">
202<img alt="bep_0008_pseudo.png" src="bep_0008_pseudo.png" />
203<p class="caption"><strong>Figure 1:</strong> The first 768 bytes of the RC4 pseudorandom
204string are discarded.  The key <em>i</em> in the tracker response has
205value <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>
206</div>
207<p>We describe encryption in the following example for an ipv4 tracker peer
208list consisting of 3 ip-port pairs, and using an RC4 pseudorandom string
209of length <em>n=2</em>. <em>n</em> is small for purposes of illustration.  Also, for the
210purpose of illustration, the tracker returns only 2 peers at a time.</p>
211<pre class="literal-block">
212Given the following peer list
213(208.72.193.86, 6881), (209.81.173.15,14321), (128.213.6.8, 6881)
214
215As a packed array represented in hex it becomes
216
217d048c1561ae1d151ad0f37f180d506081ae1
218
219which we XOR with an RC4 pseudorandom string excluding discarded and
220reserved bytes, e.g.,
221
222a496e5f9b83e835013d42226
223
224to generate
225
22674de24afa2df5201bedb15d72443e3f1a2df
227</pre>
228<p>Because the RC4 pseudorandom string is shorter than the tracker
229peer list, we wrap to the beginning of the pseudorandom string.</p>
230<p>A tracker returning the first two peers would return the bencoded
231equivalent of:</p>
232<pre class="literal-block">
233peers=74de24afa2df5201bedb15d7, i=0, n=2
234</pre>
235<p>A tracker returning the second and third peer would return the
236bencoded equivalent of:</p>
237<pre class="literal-block">
238peers=5201bedb15d72443e3f1a2df, i=1, n=2
239</pre>
240<p>In each response the tracker includes additional parameters such as
241the 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>
242<p>The tracker response MUST remain a valid bencoded message.</p>
243</div>
244<div class="section" id="backwards-compatibility">
245<h1>Backwards Compatibility</h1>
246<p>Trackers that support obfuscation are identified in the .torrent file
247by the inclusion of an <tt class="docutils literal"><span class="pre">obfuscate-announce-list</span></tt> which otherwise has the
248same semantics as the <tt class="docutils literal"><span class="pre">announce-list</span></tt> key.  Peers that do not support
249obfuscation simply ignore the <tt class="docutils literal"><span class="pre">obfuscate-announce-list</span></tt>.</p>
250<p>A client that is configured to use this extension should always send
251the <tt class="docutils literal"><span class="pre">sha_ih</span></tt> to any tracker supporting obfuscation.  The client
252SHOULD only contact trackers in the <tt class="docutils literal"><span class="pre">announce-list</span></tt> once the client
253has attempted all trackers in the <tt class="docutils literal"><span class="pre">obfuscate-announce-list</span></tt> and all failed.</p>
254<p>If a tracker that supports obfuscation wishes to allow legacy peers to
255connect to the tracker then the announce URL should appear in both the
256<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>
257<p>If a tracker URL appears in both lists running on the same port, and
258the tracker failed to respond when selected from the
259<tt class="docutils literal"><span class="pre">obfuscate-announce-list</span></tt> then the client MAY treat the tracker in
260the <tt class="docutils literal"><span class="pre">announce-list</span></tt> as if it were temporarily unreachable and defer
261trying it until it has tried other trackers in the <tt class="docutils literal"><span class="pre">announce-list</span></tt>.</p>
262<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
263in the same request, since that would defeat the purpose of the shared
264secret.</p>
265<p>Any peer that requests with a <tt class="docutils literal"><span class="pre">sha_ih</span></tt> SHOULD implement Message
266Stream Encryption (MSE) <a class="footnote-reference" href="#mse" id="id1">[1]</a>.  Any peer returned from the tracker
267in response to a request with a <tt class="docutils literal"><span class="pre">sha_ih</span></tt> SHOULD be assumed to
268support Message Stream Encryption.  We include these provisions
269because if a peer communicates with another peer without using MSE
270then the BitTorrent protocol is trivially identified from the first
271twenty bytes of the BitTorrent header and the <tt class="docutils literal"><span class="pre">info_hash</span></tt> appears in
272plaintext as the next twenty bytes, hence also defeating the purpose
273of the shared secret.</p>
274<p>If the tracker does not know enough peers assumed to support MSE to
275return the desired number of peers then it MAY include peers that are
276not assumed to support MSE.  If a peer closes a connection in response
277to an encrypted header then the initiating peer SHOULD assume that the
278peer does not support MSE.  The initiating peer however SHOULD ONLY
279initiate unencrypted connections when all peers have been tried and
280those that support MSE fail to provide &quot;adequate performance.&quot;  We
281intentionally omit any definition of &quot;adequate performance.&quot;</p>
282</div>
283<div class="section" id="rationale">
284<h1>Rationale</h1>
285<p>This extension directly addresses a known attack on the BitTorrent
286protocol performed by some deployed network hardware.  By obscuring
287the ip-port pairs network hardware can no longer easily identify
288ip-port pairs that are running BitTorrent by observing peer-to-tracker
289communications.  This deployed hardware under some conditions disrupts
290BitTorrent connections by injecting forged TCP reset packets.  Once a
291BitTorrent connection has been identified, other attacks could also be
292performed such as severely rate limiting or blocking these
293connections.</p>
294<p>This hardware was presumably deployed to get around BitTorrent
295Message Stream Encryption <a class="footnote-reference" href="#mse" id="id2">[1]</a>.  Peers implementing BitTorrent Message Stream
296Encryption obfuscate peer-to-peer connections by employing RC4
297encryption on every byte from the first byte transferred. BitTorrent
298Message Stream Encryption thus increases the difficulty for a device
299observing passing packets to identify BitTorrent peer-to-peer
300connections.</p>
301<p>By using the SHA-1 of the infohash, the tracker is able to identify
302torrents without sending the plaintext infohash and without requiring
303an additional prior exchange of a shared secret.  Where trackers now
304maintain mappings from infohash to the corresponding torrent's
305peerlist and other torrent-specific state, obfuscated trackers would need
306one additional mapping from <tt class="docutils literal"><span class="pre">sha_ih</span></tt> to the torrent's state.
307Tracker may also store encrypted versions of each torrent's peer list,
308to increase computation performance at the expense of increasing
309memory footprint by a constant factor.</p>
310<p>The obfuscation method meets the following criteria:</p>
311<ul class="simple">
312<li>The entire plaintext of the peer list is not easily obtained even if
313an eavesdropper identifies ip-port pairs from subsequent connections
314initiated by a peer that has received a tracker response.</li>
315<li>Even when a subsequent connection from a peer that has received a
316tracker response is observed by an eavesdropper, it is difficult to
317map the ip-port pair to specific ciphertext to verify that the
318connection is using BitTorrent.</li>
319</ul>
320<p>When the <a class="reference internal" href="#optimizations">optimizations</a> are used,</p>
321<ul class="simple">
322<li>Few computations are performed at request time.</li>
323<li>Encryption may be performed at the time a peer is added.
324The encrypted peer ip and port may be handed out hundreds of times.</li>
325<li>Security is minimally impacted.</li>
326</ul>
327<p>The objective is NOT to create a cryptographically secure protocol
328that can survive unlimited observation of passing packets and
329substantial computational resources on network timescales.  The objective
330is to raise the bar sufficiently to deter attacks based on observing
331ip-port numbers in peer-to-tracker communications.</p>
332<p>If a tracker observes a large number of tracker requests and responses
333and subsequent connections, it is possible to attack the encryption.
334RC4 is known to have a number of weaknesses especially in the way it
335was 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,
336with tracker peer obfuscation, the number of bytes transferred between
337the tracker and a client is likely significantly smaller than transferred
338between a wireless computer and a basestation.  An attacker faces a
339much larger task in obtaining sufficient probable plaintext to
340directly break the encryption.</p>
341<p>Hobbling the RC4 encryption by using a bounded-length RC4 pseudorandom
342string for small swarms is likely to have negilgible impact on
343security over any other encyption method since the pseudorandom string
344is probably equal to or longer than the plaintext and thus no part of
345it is repeated in the XOR except as peers arrive or leave the swarm.
346Thus on the timescales of rerequest intervals, nearly the same
347ciphertext is handed to every peer requesting the same infohash.
348Intercepting the same ciphertext multiple times provides no additional
349information to the attacker.  The attacker could correlate ip-port
350pairs in connections following tracker responses, but an attacker
351could do this regardless of the encryption method employed.
352Furthermore more direct methods of traffic analysis applied to
353peer-to-peer communication is available to network operators.</p>
354<p>For larger swarms, hobbling RC4 may more significantly impact breaking
355the encryption since the same pseudorandom string is used repeatedly
356across the peer list.  Some study is in order on this point taking
357into account that the tracker can periodically change intiailization
358vectors.</p>
359<p>We know from experience that periodically reshuffling peer lists on
360the order of the rerequest interval negligibly impacts tracker
361performance even with swarms containing millions of peers.  Generating
362a new pseudorandom string using RC4 on this same time interval is
363likely to incur negligible performance penalty because 1) RC4 is a
364small constant factor more expensive than a shuffle on an input string
365of equal length, 2) the generated pseudorandom string is only <em>n</em>
366ip-port pairs long where recommended <em>n</em> is within a small constant
367factor larger than the largest <em>returned peer list</em> and thus much
368smaller than the <em>tracker peer list</em> for large swarms, and 3) the cost
369of the XOR operation is lighter weight than performing a random
370shuffle.</p>
371</div>
372<div class="section" id="references">
373<h1>References</h1>
374<table class="docutils footnote" frame="void" id="mse" rules="none">
375<colgroup><col class="label" /><col /></colgroup>
376<tbody valign="top">
377<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
378(<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>
379</tbody>
380</table>
381<table class="docutils footnote" frame="void" id="borisov" rules="none">
382<colgroup><col class="label" /><col /></colgroup>
383<tbody valign="top">
384<tr><td class="label"><a class="fn-backref" href="#id3">[2]</a></td><td>Nikita Borisov, Ian Goldberg, and David Wagner. Intercepting
385mobile communications: the insecurity of 802.11. In ACM MobiCom 2001,
386pages 180-189. ACM Press, 2001.</td></tr>
387</tbody>
388</table>
389<table class="docutils footnote" frame="void" id="scott" rules="none">
390<colgroup><col class="label" /><col /></colgroup>
391<tbody valign="top">
392<tr><td class="label"><a class="fn-backref" href="#id4">[3]</a></td><td>Scott R. Fluhrer, Itsik Mantin, and Adi
393Shamir. Weaknesses in the key scheduling algorithm of RC4. In Serge
394Vaudenay and Amr M. Youssef, editors, Selected Areas in
395Cryptography 2001, volume 2259 of Lecture Notes in Computer
396Science, pages 1-24. Springer, 2001.</td></tr>
397</tbody>
398</table>
399<table class="docutils footnote" frame="void" id="stubblefeld" rules="none">
400<colgroup><col class="label" /><col /></colgroup>
401<tbody valign="top">
402<tr><td class="label"><a class="fn-backref" href="#id5">[4]</a></td><td>Adam Stubblefeld, John Ioannidis, and Aviel
403D. Rubin. A key recovery attack on the 802.11b wired equivalent
404privacy protocol (WEP). ACM Transactions on Information and System
405Security, 7(2):319-332, May 2004.</td></tr>
406</tbody>
407</table>
408<table class="docutils footnote" frame="void" id="id6" rules="none">
409<colgroup><col class="label" /><col /></colgroup>
410<tbody valign="top">
411<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>
412</tbody>
413</table>
414</div>
415<div class="section" id="example-python-code">
416<h1>Example Python Code</h1>
417<p>Request handling in a dummy tracker implementing tracker peer obfuscation:</p>
418<pre class="literal-block">
419from sha import sha
420from random import randint
421from struct import unpack
422from rc4 import rc4  # rc4(k) generates k RC4 pseudorandom bytes.
423
424rand = open(&quot;/dev/random&quot;,&quot;r&quot;).read
425rc4 = rc4()
426
427# tracker configuration
428MAX_PEERS = 100
429
430# per torrent state.
431infohash = sha(&quot;dummy_info&quot;).digest()
432pseudo = ''                        # pseudorandom RC4 string.
433num_peers = 1000                   # current swarm size.
434tracker_peer_list = rand(6) * num_peers
435obfuscated_tracker_peer_list = ''
436
437def xor(plaintext,pseudo):
438  isint = False
439  if type(plaintext) == int: # convert to byte string.
440    plaintext = &quot;&quot;.join([chr(int(x,16)) for x in &quot;%.4x&quot; % plaintext])
441    isint = True
442  n = len(pseudo)
443  ciphertext = &quot;&quot;.join(
444    [chr(ord(pseudo[i%n])^ord(plaintext[i])) for i in xrange(len(plaintext))])
445  if isint:
446    ciphertext = unpack(&quot;!I&quot;, ciphertext)[0]   # convert back to unsigned int
447  return ciphertext
448
449def init():  # called once per rerequest interval.
450  global iv, x, n, n_xor_y, obfuscated_tracker_peer_list
451  iv = rand(20)
452  rc4.key = sha(infohash + iv).digest()
453  rc4(768)                         # discard first 768
454  x = rc4(4)
455  y = rc4(4)