From ea3bf3ffc8537277bb45f8694cf634cc64d70f85 Mon Sep 17 00:00:00 2001
From: jrandom <jrandom>
Date: Mon, 3 Oct 2005 06:21:08 +0000
Subject: [PATCH] might as well commit this draft

---
 router/doc/net.png        | Bin 0 -> 24115 bytes
 router/doc/techintro.html | 982 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 982 insertions(+)
 create mode 100644 router/doc/net.png
 create mode 100644 router/doc/techintro.html

diff --git a/router/doc/net.png b/router/doc/net.png
new file mode 100644
index 0000000000000000000000000000000000000000..6eac3784245e13c794795634b797ec2ea0a2eab1
GIT binary patch
literal 24115
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
D6zp&p

literal 0
HcmV?d00001

diff --git a/router/doc/techintro.html b/router/doc/techintro.html
new file mode 100644
index 0000000000..c2d59356fd
--- /dev/null
+++ b/router/doc/techintro.html
@@ -0,0 +1,982 @@
+<html>
+<head>
+ <title>Introducing I2P - a scalable framework for anonymous communication</title>
+<style>
+p { font-size: 10; text-align: left; font-family: sans-serif }
+h1 { font-size: 12; font-family: sans-serif }
+h2 { font-size: 10; font-family: sans-serif }
+h3 { font-size: 10; font-family: sans-serif }
+blockquote { font-size: 10; font-family: monospace, sans-serif }
+pre { font-size: 10; font-family: sans-serif }
+.title { font-size: 14; font-family: sans-serif }
+.subtitle { font-size: 12; font-family: sans-serif }
+</style>
+</head>
+<body>
+
+<center>
+<b class="title">Introducing I2P</b><br />
+<span class="subtitle">a scalable framework for anonymous communication</span><br />
+<i style="font-size: 8">$Id: index.html,v 1.22 2005/10/03 00:31:27 jrandom Exp $</i>
+<br />
+<br />
+
+<table border="0" width="50%">
+<tr><td valign="top" align="left">
+<pre>
+* <a href="#intro">Introduction</a>
+* <a href="#op">Operation</a>
+  * <a href="#op.overview">Overview</a>
+  * <a href="#op.tunnels">Tunnels</a>
+  * <a href="#op.netdb">Network Database</a>
+  * <a href="#op.transport">Transport protocols</a>
+  * <a href="#op.crypto">Cryptography</a>
+</pre>
+</td>
+<td valign="top" align="left">
+<pre>
+* <a href="#future">Future</a>
+  * <a href="#future.restricted">Restricted routes</a>
+  * <a href="#future.variablelatency">Variable latency</a>
+  * <a href="#future.open">Open questions</a>
+</pre>
+</td>
+<td valign="top" align="left">
+<pre>
+* <a href="#similar">Similar systems</a>
+  * <a href="#similar.tor">Tor</a>
+  * <a href="#similar.freenet">Freenet</a>
+* <a href="#app">Appendix A: Application layer</a>
+</pre>
+</td>
+</tr></table>
+</center>
+
+<hr />
+
+<h1 id="intro">Introduction</h1>
+<p>
+I2P is a scalable, self organizing, resilient message based anonymous network layer, 
+upon which any number of different anonymity or security conscious applications
+can operate.  Each of these applications may make their own anonymity, latency, and
+throughput tradeoffs without worrying about the proper implementation of a free
+route mixnet, allowing them to blend their activity with the larger anonymity set of
+users already running on top of I2P.  Applications available already provide the full
+range of typical Internet activities - anonymous web browsing, anonymous web hosting,
+anonymous blogging (with <a href="#app.syndie">Syndie</a>), anonymous chat (via IRC or 
+jabber), anonymous swarming file transfers (with <a href="#app.i2pbt">i2p-bt</a> and 
+<a href="#app.azneti2p">Azureus</a>), anonymous file sharing (with
+<a href="#app.i2phex">I2Phex</a>), anonymous email (with <a href="#app.i2pmail">I2Pmail</a>
+and <a href="#app.i2pmail">susimail</a>), anonymous newsgroups, as well as several
+other applications under development.  Unlike web sites hosted within content
+distribution networks like <a href="#similar.freenet">Freenet</a> or
+<a href="http://www.ovmj.org/GNUnet/">GNUnet</a>, the services hosted on I2P are fully
+interactive - there are traditional web-style search engines, bulletin boards, blogs
+you can comment on, database driven sites, and bridges to query static systems like
+Freenet without needing to install it locally.
+</p>
+
+<p>
+With all of these anonymity enabled applications, I2P takes on the role of the message
+oriented middleware - applications say that they want to send some data to a cryptographic
+identifier (a "destination") and I2P takes care of making sure it gets there securely
+and anonymously.  I2P also bundles a simple <a href="#app.streaming">streaming</a> library
+to allow I2P's anonymous best-effort messages to transfer as reliable, in-order streams,
+transparently offering a TCP based congestion control algorithm tuned for the high
+bandwidth delay product of the network.  While there have been several simple SOCKS
+proxies available to tie existing applications into the network, their value has been
+limited as nearly every application routinely exposes what in an anonymity context is
+sensitive information.  The only safe way to go is to fully audit an application to
+ensure proper operation, and to assist in that we provide a series of APIs in various
+languages which can be used to make the most out of the network.
+</p>
+
+<!-- commented out because "The details [...] are " *NOT* " given later" -->
+<!--
+<p>
+The scope of I2P's anonymity protections varies upon the applications running on
+top of them, as well as the choices that each user makes.  The aim is to provide
+the options necessary so that a sufficient level of anonymity can be achieved while
+exposing the functionality that people facing up to state level adversaries require.
+At the same time, those facing less powerful adversaries are able to improve their 
+throughput and latency while reducing the resources required to provide the necessary
+level of cover.  The details of the techniques available for facing adversaries who
+are internal or external, passive or active, local, national, or global, are given
+later.
+</p>
+-->
+
+<p>
+I2P is not a research project - academic, commercial, or governmental, but is instead
+an engineering effort aimed at doing whatever is necessary to provide a sufficient
+level of anonymity to those who need it.  It has been in active development since
+early 2003 with one full time developer and a dedicated group of part time contributors
+from all over the world.  All of the work done on I2P is open source and 
+freely available on the <a href="http://www.i2p.net/">website</a>, with the majority
+of the code released outright into the public domain but making use of a few 
+cryptographic routines under BSD-style licenses.  The people working on I2P do not
+control what people release client applications under, and there are several GPL'ed
+applications available (<a href="#app.i2ptunnel">I2PTunnel</a>, 
+<a href="#app.i2pmail">susimail</a>, <a href="#app.azneti2p">Azureus</a>, 
+<a href="#app.i2phex">I2Phex</a>).  <a href="http://www.i2p.net/halloffame">Funding</a>
+for I2P comes entirely from donations, and does not receive any tax breaks in any
+jurisdiction, as many of the developers are themselves anonymous.
+</p>
+
+<h1 id="op">Operation</h1>
+<h2 id="op.overview">Overview</h2>
+
+<p>
+To understand I2P's operation, it is essential to understand a few key concepts.
+First, I2P makes a strict separation between the software participating
+in the network (a "router") and the anonymous endpoints ("destinations") associated
+with individual applications.  The fact that someone is running I2P is not usually
+a secret.  What is hidden is information on what the user is doing, if anything at
+all, as well as what router a particular destination is connected to.  End users 
+will typically have several local destinations on their router - for instance, one 
+proxying in to irc servers, another supporting the user's anonymous webserver ("eepsite"),
+another for an I2Phex instance, another for torrents, etc.
+</p>
+
+<p>
+Another critical concept to understand is the "tunnel" - a directed path through
+an explicitly selected set of routers, making use of layered encryption so that
+the messages sent in the tunnel's "gateway" appear entirely random at each hop 
+along the path until it reaches the tunnel's "endpoint".  These unidirectional
+tunnels can be seen as either "inbound" tunnels or "outbound" tunnels, referring
+to whether they are bringing messages to the tunnel's creator or away from them,
+respectively.  The gateway of an inbound tunnel can receive messages from any
+peer and will forward them down through the tunnel until it reaches the (anonymous)
+endpoint (the creator).  On the other hand, the gateway of an outbound tunnel is
+the tunnel's creator, and messages sent through that tunnel are encoded so that
+when they reach the outbound tunnel's endpoint, that router has the instructions
+necessary to forward the message on to the appropriate location.
+</p>
+
+<p>
+A third critical concept to understand is I2P's "network database" (or "netDb")
+- a pair of algorithms used to share network metadata.  The two types of metadata
+carried are "routerInfo" and "leaseSets" - the routerInfo gives routers the data
+necessary for contacting a particular router (their public keys, transport
+addresses, etc), while the leaseSet gives routers the information necessary for
+contacting a particular destination.  Within each leaseSet, there are any number
+of "leases", each of which specifies the gateway for one of that destination's
+inbound tunnels as well as when that tunnel will expire.  The leaseSet also
+contains a pair of public keys which can be used for layered garlic encryption.
+</p>
+
+<p>
+I2P's operation can be understood by putting those three concepts together:
+</p>
+
+<p><img src="net.png"></p>
+
+<p>
+When Alice wants to send a message to Bob, she first does a lookup in the 
+netDb to find Bob's leaseSet, giving her his current inbound tunnel gateways 
+(3 and 4).  She then picks one of her outbound tunnels and sends the message
+down it with instructions for the outbound tunnel's endpoint to forward the 
+message on to one of Bob's inbound tunnel gateways.  When the outbound 
+tunnel endpoint receives those instructions, it forwards the message as 
+requested, and when Bob's inbound tunnel gateway receives it, it is 
+forwarded down the tunnel to Bob's router.  If Alice wants Bob to be able 
+to reply to the message, she needs to transmit her own destination explicitly 
+as part of the message itself (taken care of transparently in the 
+<a href="#app.streaming">streaming</a> library).  Alice may also cut down on 
+the response time by bundling her most recent leaseSet with the message so 
+that Bob doesn't need to do a netDb lookup for it when he wants to reply, but this 
+is optional.
+</p>
+
+<p>
+While the tunnels themselves have layered encryption to prevent unauthorized
+disclosure to peers inside the network (as the transport layer itself does to
+prevent unauthorized disclosure to peers outside the network), it is necessary
+to add an additional end to end layer of encryption to hide the message from the 
+outbound tunnel endpoint and the inbound tunnel gateway.  This
+"<a href="#op.garlic">garlic encryption</a>" lets Alice's router wrap up multiple
+messages into a single "garlic message", encrypted to a particular public key
+so that intermediary peers cannot determine either how many messages are within
+the garlic, what those messages say, or where those individual cloves are
+destined.  For typical end to end communication between Alice and Bob, the
+garlic will be encrypted to the public key published in Bob's leaseSet,
+allowing the message to be encrypted without giving out the public key to Bob's
+own router.
+</p>
+
+<p>
+Another important fact to keep in mind is that I2P is entirely message based
+and that some messages may be lost along the way.  Applications using I2P
+can use the message oriented interfaces and take care of their own congestion
+control and reliability needs, but most would be best served by reusing the
+provided <a href="#app.streaming">streaming</a> library to view I2P as a streams
+based network.
+</p>
+
+<h2 id="op.tunnels">Tunnels</h2>
+
+<p>
+Both inbound and outbound tunnels work along similar principles - the tunnel
+gateway accumulates a number of tunnel messages, eventually preprocessing them
+into something for tunnel delivery.  Next, the gateway encrypts that preprocessed
+data and forwards it to the first hop.  That peer and subsequent tunnel
+participants add on a layer of encryption after verifying that it isn't a
+duplicate before forward it on to the next peer. Eventually, the 
+message arrives at the endpoint where the messages are split out again and
+forwarded on as requested.  The difference arises in what
+the tunnel's creator does - for inbound tunnels, the creator is the endpoint
+and they simply decrypt all of the layers added, while for outbound tunnels,
+the creator is the gateway and they pre-decrypt all of the layers so that after
+all of the layers of per-hop encryption are added, the message arrives in the
+clear at the tunnel endpoint.
+</p>
+
+<p>
+The choice of specific peers to pass on messages as well as their particular
+ordering is important to understanding both I2P's anonymity and performance 
+characteristics.  While the network database (below) has its own criteria for
+picking what peers to query and store entries on, tunnels may use any peers in
+the network in any order (and even any number of times) in a single tunnel.  If
+perfect latency and capacity data were globally known, selection and ordering 
+would be driven by the particular needs of the client in tandem with their threat
+model.  Unfortunately, latency and capacity data is not trivial to gather
+anonymously, and depending upon untrusted peers to provide this information has
+its own serious anonymity implications.
+</p>
+
+<p>
+From an anonymity perspective, the simplest technique would be to pick peers
+randomly from the entire network, order them randomly, and use those peers
+in that order for all eternity.  From a performance perspective, the simplest
+technique would be to pick the fastest peers with the necessary spare capacity,
+spreading the load across different peers to handle transparent failover, and
+to rebuild the tunnel whenever capacity information changes.  While the former
+is both brittle and inefficient, the later requires inaccessible information
+and offers insufficient anonymity.  I2P is instead working on offering a range
+of peer selection strategies, coupled with anonymity aware measurement code to
+organize the peers by their profiles.
+</p>
+
+<p>
+As a base, I2P is constantly profiling the peers with which it interacts with
+by measuring their indirect behavior - for instance, when a peer responds to
+a netDb lookup in 1.3 seconds, that round trip latency is recorded in the 
+profiles for all of the routers involved in the two tunnels (inbound and 
+outbound) through which the request and response passed, as well as the queried
+peer's profile.  Direction measurement, such as transport layer latency or
+congestion, is not used as part of the profile, as it can be manipulated and 
+associated with the measuring router, exposing them to trivial attacks.  While
+gathering these profiles, a series of calculations are run on each to summarize
+its performance - its latency, capacity to handle lots of activity, whether they
+are currently overloaded, and how well integrated into the network they seem to
+be.  These calculations are then compared for active peers to organize the routers
+into four tiers - fast and high capacity, high capacity, not failing, and failing.
+The thresholds for those tiers are determined dynamically, and while they
+currently use fairly simple algorithms, alternatives exist.
+</p>
+
+<p>
+Using this profile data, the simplest reasonable peer selection strategy is to
+pick peers randomly from the top tier (fast and high capacity), and this is
+currently deployed for client tunnels.  Exploratory tunnels (used for netDb
+and tunnel management) pick peers randomly from the not failing tier (which 
+includes routers in 'better' tiers as well), allowing the peer to sample
+routers more widely, in effect optimizing the peer selection through randomized
+hill climbing.  These strategies alone do however leak information regarding the
+peers in the router's tip tier through predecessor and netDb harvesting attacks.  
+In turn, several alternatives exist which, while not balancing the load as evenly,
+will address the attacks mounted by particular classes of adversaries.
+</p>
+
+<p>
+By picking a random key and ordering the peers according to their XOR distance
+from it, the information leaked is reduced in predecessor and harvesting attacks
+according to the peers' failure rate and the tier's churn.  Another simple strategy
+for dealing with netDb harvesting attacks is to simply fix the inbound tunnel
+gateway(s) yet randomize the peers further on in the tunnels.  To deal with 
+predecessor attacks for adversaries which the client contacts, the outbound tunnel
+endpoints would also remain fixed.  The selection of which peer to fix on the most
+exposed point would of course need to have a limit to the duration, as all peers
+fail eventually, so it could either be reactively adjusted or proactively avoided
+to mimic a measured mean time between failures of other routers.  These two strategies
+can in turn be combined, using a fixed exposed peer and an XOR based ordering within
+the tunnels themselves.  A more rigid strategy would fix the exact peers and ordering
+of a potential tunnel, only using individual peers if all of them agree to participate
+in the same way each time.  This varies from the XOR based ordering in that the 
+predecessor and successor of each peer is always the same, while the XOR only makes 
+sure their order doesn't change.
+</p>
+
+<p>
+As mentioned before, I2P currently (release 0.6.1.1) includes the tiered random
+strategy above, but the others are planned for the 0.6.2 release.  A more detailed
+discussion of the mechanics involved in tunnel operation, management, and peer
+selection can be found in the 
+<a href="http://dev.i2p.net/cgi-bin/cvsweb.cgi/i2p/router/doc/tunnel-alt.html?rev=HEAD">tunnel spec</a>.
+</p>
+
+<h2 id="op.netdb">Network Database</h2>
+
+<p>
+As mentioned earlier, I2P's netDb works to share the network's metadata.  Two
+algorithms are used to accomplish this - primarily, a small set of routers are
+designated as "floodfill peers", while the rest of the routers participate in
+the <a href="http://en.wikipedia.org/wiki/Kademlia">Kademlia </a> derived
+distributed hash table for redundancy.  To integrate the two algorithms, each
+router always uses the Kademlia style store and fetch, but acts as if the
+floodfill peers are 'closest' to the key in question.  Additionally, when a
+peer publishes a key into the netDb, after a brief delay they query another
+random floodfill peer, asking them for the key, and if that peer does not have
+it, they move on and republish the key again.  Behind the scenes, when one of
+the floodfill peers receives a new valid key, they republish it to the other
+floodfill peers who then cache it locally.
+</p>
+
+<p>
+Each piece of data in the netDb is self authenticating - signed by the
+appropriate party and verified by anyone who uses or stores it.  In addition,
+the data has liveliness information within it, allowing irrelevant entries to be
+dropped, newer entries to replace older ones, and, for the paranoid, protection
+against certain classes of attack.  This is also why I2P bundles the necessary
+code for maintaining the correct time, occasionally querying some SNTP servers
+(the <a href="http://www.pool.ntp.org/">pool.ntp.org</a> round robin by default)
+and detecting skew between routers at the transport layer.
+</p>
+
+<p>
+The routerInfo structure itself contains all of the information that one router
+needs to know to securely send messages to another router.  This includes their
+identity (made up of a 2048bit ElGamal public key, a 1024bit DSA public key, and
+a certificate), the transport addresses which they can be reached on, such as
+an IP address and port, when the structure was published, and a set of arbitrary
+uninterpreted text options.  In addition, there is a signature against all of
+that data as generated by the included DSA public key.  The key for this routerInfo
+structure in the netDb is the SHA256 hash of the router's identity.  The options
+published are often filled with information helpful in debugging I2P's operation,
+but when I2P reaches the 1.0 release, the options will be disabled and kept blank.
+</p>
+
+<p>
+The leaseSet structure is similar, in that it includes the I2P destination
+(comprised of a 2048bit ElGamal public key, a 1024bit DSA public key, and a
+certificate), a list of "leases", and a pair of public keys for garlic encrypting
+messages to the destination.  Each of the leases specify one of the destination's
+inbound tunnel gateways by including the SHA256 of the gateway's identity, a 4
+byte tunnel id on that gateway, and when that tunnel will expire.  The key for
+the leaseSet in the netDb is the SHA256 of the destination itself.
+</p>
+
+<p>
+As the router currently automatically bundles the leaseSet for the sender inside
+a garlic message to the recipient, the leaseSet for destinations which will not
+receive unsolicited messages do not need to be published in the netDb at all.  If
+the destination itself is sensitive, the leaseSet could instead be transmitted 
+through other means without ever going into the netDb.
+</p>
+
+<p>
+Bootstrapping the netDb itself is simple - once a router has at least one routerInfo
+of a reachable peer, they query that router for references to other routers in the
+network with the Kademlia healing algorithm.  Each routerInfo reference is stored in
+an individual file in the the router's netDb subdirectory, allowing people to easily
+share their references to bootstrap new users.
+</p>
+
+<p>
+Unlike traditional DHTs, the very act of conducting a search distributes the data
+as well, since rather passing Kademlia's standard IP+port pairs, references are given
+to the routers that the peer should query next (namely, the SHA256 of those routers'
+identities).  As such, iteratively searching for a particular destination's leaseSet
+or router's routerInfo will also provide you with the routerInfo of the peers along
+the way.  In addition, due to the time sensitivity of the data published, the information
+doesn't often need to migrate between peers - since a tunnel is only valid for 10
+minutes, the leaseSet can be dropped after that time has passed.  To take into 
+account Sybil attacks on the netDb, the Kademlia routing location used for any given
+key varies over time.  For instance, rather than storing a routerInfo on the peers
+closest to SHA256(routerInfo.identity), they are stored on the peers closest to 
+SHA256(routerInfo.identity + YYYYMMDD), requiring an adversary to remount the attack
+again daily so as to maintain their closeness to the current routing key.  As the
+very fact that a router is making a lookup for a given key may expose sensitive data
+(and the fact that a router is <i>publishing</i> a given key even more so), all netDb
+messages are transmitted through the router's exploratory tunnels.
+</p>
+
+<p>
+The netDb plays a very specific role in the I2P network, and the algorithms have 
+been tuned towards our needs.  This also means that it hasn't been tuned to address the
+needs we have yet to run into.  As the network grows, the primary floodfill algorithm
+will need to be refined to exploit the capacity available, or perhaps replaced with
+another technique for securely distributing the network metadata.
+</p>
+
+<h2 id="op.transport">Transport protocols</h2>
+
+<p>
+Communication between routers needs to provide confidentiality and integrity
+against external adversaries while authenticating that the router contacted
+is the one who should receive a given message.  The particulars of how routers
+communicate with other routers isn't critical - three separate protocols have
+been used at different points to provide those bare necessities.  To accommodate
+the need for high degree communication (as a number of routers will end up 
+speaking with many others), I2P is migrating from a TCP based transport
+to a UDP based one - "Secure Semireliable UDP", or "SSU".  As described in the
+<a href="http://dev.i2p.net/cgi-bin/cvsweb.cgi/i2p/router/doc/udp.html?rev=HEAD">SSU spec</a>:</p>
+
+<blockquote>
+The goal of this protocol is to provide secure, authenticated, 
+semireliable, and unordered message delivery, exposing only a minimal amount of 
+data easily discernible to third parties. It should support high degree 
+communication as well as TCP-friendly congestion control, and may include 
+PMTU detection. It should be capable of efficiently moving bulk data at rates 
+sufficient for home users. In addition, it should support techniques for 
+addressing network obstacles, like most NATs or firewalls.
+</blockquote>
+
+<h2 id="op.crypto">Cryptography</h2>
+
+<p>
+A bare minimum set of cryptographic primitives are combined together to provide I2P's
+layered defenses against a variety of adversaries.  At the lowest level, interrouter
+communication is protected by the transport layer security - SSU
+encrypts each packet with AES256/CBC with both an explicit IV and MAC (HMAC-SHA256-128)
+after agreeing upon an ephemeral session key through a 2048bit Diffie-Hellman exchange,
+station-to-station authentication with the other router's DSA key, plus each network
+message has their own SHA256 hash for local integrity checking. 
+<a href="#op.tunnels">Tunnel</a> messages passed over the transports have their own
+layered AES256/CBC encryption with an explicit IV and verified at the tunnel endpoint
+with an additional SHA256 hash.  Various other messages are passed along inside
+"garlic messages", which are encrypted with ElGamal/AES+SessionTags (explained below).  
+</p>
+
+<h3 id="op.garlic">Garlic messages</h3>
+
+<p>
+Garlic messages are an extension of "onion" layered encryption, allowing the contents
+of a single message to contain multiple "cloves" - fully formed messages along side
+their own instructions for delivery.  Messages are wrapped into a garlic message whenever
+the message would otherwise be passing in cleartext through a peer who should not have
+access to the information - for instance, when a router wants to ask another router to
+participate in a tunnel, they wrap the request inside a garlic, encrypt that garlic to
+the receiving router's 2048bit ElGamal public key, and forward it through a tunnel. 
+Another example is when a client wants to send a message to a destination - the sender's
+router will wrap up that data message (along side some other messages) into a garlic,
+encrypt that garlic to the 2048bit ElGamal public key published in the recipient's
+leaseSet, and forward it through the appropriate tunnels.
+</p>
+
+<p>
+The "instructions" attached to each clove inside the encryption layer includes the
+ability to request that the clove be forwarded locally, to a remote router, or to a 
+remote tunnel on a remote router.  There are fields in those instructions allowing a
+peer to request that the delivery be delayed until a certain time or condition has
+been met, though they won't be honored until the 
+<a href="#future.variablelatency">nontrivial delays</a> are deployed.  It is possible to
+explicitly route garlic messages any number of hops without building tunnels, or even
+to reroute tunnel messages by wrapping them in garlic messages and forwarding them a
+number of hops prior to delivering them to the next hop in the tunnel, but those 
+techniques are not currently used in the existing implementation.
+</p>
+
+<h3 id="op.sessiontags">Session tags</h3>
+
+<p>
+As an unreliable, unordered, message based system, I2P uses a simple combination of
+asymmetric and symmetric encryption algorithms to provide data confidentiality and
+integrity to garlic messages.  As a whole, the combination is referred to as
+ElGamal/AES+SessionTags, but that is an excessively verbose way to describe the simple
+use of 2048bit ElGamal, AES256, SHA256, and 32 byte nonces.
+</p>
+
+<p>
+The first time a router wants to encrypt a garlic message to another router, they encrypt 
+the keying material for an AES256 session key with ElGamal and append the AES256/CBC 
+encrypted payload after that encrypted ElGamal block.  In addition to the encrypted
+payload, the AES encrypted section contains the payload length, the SHA256 hash of the
+unencrypted payload, as well as a number of "session tags" - random 32 byte nonces.  The
+next time the sender wants to encrypt a garlic message to another router, rather than
+ElGamal encrypt a new session key they simply pick one of the previously delivered session
+tags and AES encrypt the payload like before, using the session key used with that
+session tag, prepended with the session tag itself.  When a router receives a garlic encrypted
+message, they check the first 32 bytes to see if it matches an available session tag - if
+it does, they simply AES decrypt the message, but if it does not, they ElGamal decrypt the
+first block.
+</p>
+
+<p>
+Each session tag can be used only once so as to prevent internal adversaries from unnecessarily
+correlating different messages as being between the same routers.  The sender of an 
+ElGamal/AES+SessionTag encrypted message chooses when and how many tags to deliver,
+prestocking the recipient with enough tags to cover a volley of messages.  Garlic messages 
+may detect the successful tag delivery by bundling a small additional message as a clove (a 
+"delivery status message") - when the garlic message arrives at the intended recipient and
+is decrypted successfully, this small delivery status message is one of the cloves exposed and 
+has instructions for the recipient to send the clove back to the original sender (through an
+inbound tunnel, of course).  When the original sender receives this delivery status message,
+they know that the session tags bundled in the garlic message were successfully delivered.
+</p>
+
+<p>
+Session tags themselves have a very short lifetime, after which they are discarded
+if not used.  In addition, the quantity stored for each key is limited, as are the
+number of keys themselves - if too many arrive, either new or old messages may be 
+dropped.  The sender keeps track whether messages using session tags are getting 
+through, and if there isn't sufficient communication it may drop the ones previously
+assumed to be properly delivered, reverting back to the full expensive ElGamal 
+encryption.
+</p>
+
+<p>
+One alternative is to transmit only a single session tag, and from that, seed a 
+deterministic PRNG for determining what tags to use or expect.  By keeping this
+PRNG roughly synchronized between the sender and recipient (the recipient precomputes a
+window of the next e.g. 50 tags), the overhead of periodically bundling a large number
+of tags is removed, allowing more options in the space/time tradeoff, and perhaps
+reducing the number of ElGamal encryptions necessary.  However, it would depend
+upon the strength of the PRNG to provide the necessary cover against internal
+adversaries, though perhaps by limiting the amount of times each PRNG is used, any
+weaknesses can be minimized.  At the moment, there are no immediate plans to move 
+towards these synchronized PRNGs.
+</p>
+
+<h1 id="future">Future</h1>
+<p>
+While I2P is currently functional and sufficient for many scenarios, there are
+several areas which require further improvement to meet the needs of those
+facing more powerful adversaries as well as substantial user experience optimization.
+</p>
+
+<h2 id="future.restricted">Restricted route operation</h2>
+
+<p>
+I2P is an overlay network designed to be run on top of a functional packet switched
+network, exploiting the end to end principle to offer anonymity and security.  
+While the Internet no longer fully embraces the end to end principle, I2P does require a
+substantial portion of the network to be reachable - there may be a number of peers
+along the edges running using restricted routes, but I2P does not include an
+appropriate routing algorithm for the degenerate case where most peers are 
+unreachable.  It would, however work on top of a network employing such an
+algorithm.
+</p>
+
+<p>
+Restricted route operation, where there are limits to what peers are
+reachable directly, has several different functional and anonymity
+implications, dependent upon how the restricted routes are handled.  At the most
+basic level, restricted routes exist when a peer is behind a NAT or firewall which
+does not allow inbound connections.  This was largely addressed in I2P 0.6.0.6 by
+integrating distributed hole punching into the transport layer, allowing people
+behind most NATs and firewalls to receive unsolicited connections without any
+configuration.  However, this does not limit the exposure of the peer's IP address to
+routers inside the network, as they can simply get introduced to the peer through
+the published introducer.
+</p>
+
+<p>
+Beyond the functional handling of restricted routes, there are two levels of 
+restricted operation that can be used to limit the exposure of one's IP address -
+using router-specific tunnels for communication, and offering 'client routers'.  For
+the former, routers can either build a new pool of tunnels or reuse their exploratory
+pool, publishing the inbound gateways to some of them as part of their routerInfo in
+place of their transport addresses.  When a peer wants to get in touch with them,
+they see those tunnel gateways in the netDb and simply send the relevant message to
+them through one of the published tunnels.  If the peer behind the restricted route
+wants to reply, it may do so either directly (if they are willing to expose their IP
+to the peer) or indirectly through their outbound tunnels.  When the routers that the
+peer has directly connections to want to reach it (to forward tunnel messages, for
+instance), they simply prioritize their direct connection over the published tunnel
+gateway.  The concept of 'client routers' simply extends the restricted route by not
+publishing any router addresses.  Such a router would not even need to publish their
+routerInfo in the netDb, merely providing their self signed routerInfo to the peers
+that it contacts (necessary to pass the router's public keys).  Both levels of
+restricted route operation are planned for I2P 2.0.
+</p>
+
+<p>
+There are tradeoffs for those behind restricted routes, as they would likely
+participate in other people's tunnels less frequently, and the routers which
+they are connected to would be able to infer traffic patterns that would not
+otherwise be exposed.  On the other hand, if the cost of that exposure is less
+than the cost of an IP being made available, it may be worthwhile.  This, of course,
+assumes that the peers that the router behind a restricted route contacts are not
+hostile - either the network is large enough that the probability of using a hostile
+peer to get connected is small enough, or trusted (and perhaps temporary) peers are
+used instead.
+</p>
+
+<h2 id="future.variablelatency">Variable latency</h2>
+
+<p>
+Even though the bulk of I2P's initial efforts have been on low latency communication,
+it was designed with variable latency services in mind from the beginning.  At the
+most basic level, applications running on top of I2P can offer the anonymity of 
+medium and high latency communication while still blending their traffic patterns
+in with low latency traffic.  Internally though, I2P can offer its own medium and
+high latency communication through the garlic encryption - specifying that the 
+message should be sent after a certain delay, at a certain time, after a certain
+number of messages have passed, or another mix strategy.  With the layered encryption,
+only the router that the clove exposed the delay request would know that the message
+requires high latency, allowing the traffic to blend in further with the low latency
+traffic.  Once the transmission precondition is met, the router holding on to the
+clove (which itself would likely be a garlic message) simply forwards it as 
+requested - to a router, to a tunnel, or, most likely, to a remote client destination.
+</p>
+
+<p>
+There are a substantial number of ways to exploit this capacity for high latency
+comm in I2P, but for the moment, doing so has been scheduled for the I2P 3.0 release.
+In the meantime, those requiring the anonymity that high latency comm can offer should
+look towards the application layer to provide it.
+</p>
+
+<h2 id="future.open">Open questions</h2>
+<pre>
+How to get rid of the timing constraint?
+Can we deal with the sessionTags more efficiently?
+What, if any, batching/mixing strategies should be made available on the tunnels?
+What other tunnel peer selection and ordering strategies should be available?
+</pre>
+
+<h1 id="similar">Similar systems</h1>
+<p>
+I2P's architecture builds on the concepts of message oriented middleware, the topology
+of DHTs, the anonymity and cryptography of free route mixnets, and the adaptability of
+packet switched networking.  The value comes not from novel concepts of algorithms
+though, but from careful engineering combining the research results of existing 
+systems and papers.  While there are a few similar efforts worth reviewing, both for 
+technical and functional comparisons, two in particular are pulled out here - Tor
+and Freenet.
+</p>
+
+<h2 id="similar.tor">Tor</h2>
+<p><i><a href="http://tor.eff.org/">website</a></i></p>
+
+<p>
+At first glance, Tor and I2P have many functional and anonymity related similarities.
+While I2P's development began before we were aware of the early stage efforts on Tor,
+many of the lessons of the original onion routing and ZKS efforts were integrated into
+I2P's design.  Rather than building an essentially trusted, centralized system with
+directory servers, I2P has a self organizing network database with each peer taking on
+the responsibility of profiling other routers to determine how best to exploit available
+resources.  Another key difference is that while both I2P and Tor use layered and
+ordered paths (tunnels and circuits/streams), I2P is fundamentally a packet switched
+network, while Tor is fundamentally a circuit switched one, allowing I2P to
+transparently route around congestion or other network failures, operate redundant
+pathways, and load balance the data across available resources.  While Tor offers
+the useful outproxy functionality by offering integrated outproxy discovery and
+selection, I2P leaves such application layer decisions up to applications running on
+top of I2P - in fact, I2P has even externalized the TCP-like streaming library itself
+to the application layer, allowing developers to experiment with different strategies,
+exploiting their domain specific knowledge to offer better performance.
+</p>
+
+<p>
+From an anonymity perspective, there is much similarity when the core networks are
+compared.  However, there are a few key differences.  When dealing with an internal
+adversary or most external adversaries, I2P's simplex tunnels expose half as much
+traffic data than would be exposed with Tor's duplex circuits by simply looking at
+the flows themselves - an HTTP request and response would follow the same path in
+Tor, while in I2P the packets making up the request would go out through one or 
+more outbound tunnels and the packets making up the response would come back through
+one or more different inbound tunnels.  While I2P's per selection and ordering 
+strategies should sufficiently address predecessor attacks, I2P can trivially 
+mimic Tor's non-redundant duplex tunnels by simply building an inbound and
+outbound tunnel along the same routers.</p>
+
+<p>
+Another anonymity issue comes up in Tor's use of telescopic tunnel creation, as
+simple packet counting and timing measurements as the cells in a circuit pass
+through an adversary's node exposes statistical information regarding where the 
+adversary is within the circuit.  I2P's use of exploratory tunnels for delivering
+and receiving the tunnel creation requests and responses effectively spreads the
+messages randomly across the network, so that each of the peers who forwards the
+individual tunnel creation messages only see the peer they transmit to or receive
+from, and thanks to the garlic encryption, they are not aware of whether the message
+is part of a tunnel creation process or not.  The participant positional information
+is useful to an adversary for mounting predecessor, intersection, and traffic
+confirmation attacks.
+</p>
+
+<p>
+Tor's support for a second tier of "onion proxies" does offer a nontrivial degree
+of anonymity while requiring a low cost of entry, while I2P will not offer this 
+topology until <a href="#future.restricted">2.0</a>.
+</p>
+
+<p>
+On the whole, Tor and I2P complement each other in their focus - Tor works towards
+offering high speed anonymous Internet outproxying, while I2P works towards offering
+a decentralized resilient network in itself.  In theory, both can be used to achieve
+both purposes, but given limited development resources, they both have their
+strengths and weaknesses.  The I2P developers have considered the steps necessary to
+modify Tor to take advantage of I2P's design, but concerns of Tor's viability under
+resource scarcity suggest that I2P's packet switching architecture will be able to
+exploit scarce resources more effectively.
+</p>
+
+<h2 id="similar.freenet">Freenet</h2>
+<p><i><a href="http://www.freenetproject.org/">website</a></i></p>
+
+<p>
+Freenet played a large part in the initial stages of I2P's design - giving proof to
+the viability of a vibrant pseudonymous community completely contained within the
+network, demonstrating that the dangers inherent in outproxies could be avoided.
+The first seed of I2P began as a replacement communication layer for Freenet, 
+attempting to factor out the complexities of a scalable, anonymous and secure point
+to point communication from the complexities of a censorship resistant distributed
+data store.  Over time however, some of the anonymity and scalability issues
+inherent in Freenet's algorithms made it clear that I2P's focus should stay strictly
+on providing a generic anonymous communication layer, rather than as a component of
+Freenet.  Over the years, the Freenet developers have come to see the weaknesses
+in the older design, prompting them to suggest that they will require a "premix" 
+layer to offer substantial anonymity.  In other words, Freenet needs to run on top
+of a mixnet such as I2P or Tor, with "client nodes" requesting and publishing data
+through the mixnet to the "server nodes" which then fetch and store the data according
+to Freenet's heuristic distributed data storage algorithms.
+</p>
+
+<p>
+Freenet's functionality is very complementary to I2P's, as Freenet natively provides
+many of the tools for operating medium and high latency systems, while I2P natively
+provides the low latency mix network suitable for offering adequate anonymity.  The
+logic of separating the mixnet from the censorship resistant distributed data store
+still seems self evident from an engineering, anonymity, security, and resource
+allocation perspective, so hopefully the Freenet team will pursue efforts in that
+direction, if not simply reusing (or helping to improve, as necessary) existing
+mixnets like I2P or Tor.
+</p>
+
+<p>
+It is worth mentioning that there has recently been discussion and work by the
+Freenet developers on a "globally scalable darknet" using restricted routes between
+peers of various trust.  While insufficient information has been made publicly 
+available regarding how such a system would operate for a full review, from what
+has been said the anonymity and scalability claims seem highly dubious.  In
+particular, the appropriateness for use in hostile regimes against state level
+adversaries has been tremendously overstated, and any analysis on the implications
+of resource scarcity upon the scalability of the network has seemingly been avoided.
+Further review of this "globally scalable darknet" will have to wait until the
+Freenet team makes more information available.
+</p>
+
+<h1 id="app">Appendix A: Application layer</h1>
+
+<p>
+I2P itself doesn't really do much - it simply sends messages to remote destinations 
+and receives messages targeting local destinations - most of the interesting work 
+goes on at the layers above it.  By itself, I2P could be seen as an anonymous and
+secure IP layer, and the bundled <a href="#app.streaming">streaming library</a> as
+an implementation of an anonymous and secure TCP layer on top of it.  Beyond that,
+<a href="#app.i2ptunnel">I2PTunnel</a> exposes a generic TCP proxying system for
+either getting into or out of the I2P network, plus a variety of network 
+applications provide further functionality for end users.
+</p>
+
+<h2 id="app.streaming">Streaming library</h2>
+
+<p>
+The streaming library has grown organically for I2P - first mihi implemented the
+"mini streaming library" as part of I2PTunnel, which was limited to a window
+size of 1 message (requiring an ACK before sending the next one), and then it was
+refactored out into a generic streaming interface (mirroring TCP sockets) and the
+full streaming implementation was deployed with a sliding window protocol and 
+optimizations to take into account the high bandwidth x delay product.  Individual
+streams may adjust the maximum packet size and other options, though the default
+of 4KB compressed seems a reasonable tradeoff between the bandwidth costs of 
+retransmitting lost messages and the latency of multiple messages.
+</p>
+
+<p>
+In addition, in consideration of the relatively high cost of subsequent messages, 
+the streaming library's protocol for scheduling and delivering messages has been optimized to
+allow individual messages passed to contain as much information as is available.
+For instance, a small HTTP transaction proxied through the streaming library can
+be completed in a single round trip - the first message bundles a SYN, FIN, and
+the small payload (an HTTP request typically fits) and the reply bundles the SYN,
+FIN, ACK, and the small payload (many HTTP responses fit).  While an additional
+ACK must be transmitted to tell the HTTP server that the SYN/FIN/ACK has been
+received, the local HTTP proxy can deliver the full response to the browser 
+immediately.  
+</p>
+
+<p>
+On the whole, however, the streaming library bears much resemblance to an 
+abstraction of TCP, with its sliding windows, congestion control algorithms
+(both slow start and congestion avoidance), and general packet behavior (ACK,
+SYN, FIN, RST, rto calculation, etc).  
+</p>
+
+<h2 id="app.naming">Naming library and addressbook</h2>
+<p><i>Developed by: mihi, Ragnarok</i></p>
+
+<p>
+Naming within I2P has been an oft-debated topic since the very beginning with
+advocates across the spectrum of possibilities.  However, given I2P's inherent
+demand for secure communication and decentralized operation, the traditional
+DNS-style naming system is clearly out, as are "majority rules" voting systems.
+Instead, I2P ships with a generic naming library and a base implementation 
+designed to work off a local name to destination mapping, as well as an optional
+add-on application called the "addressbook".  The addressbook is a web-of-trust
+driven secure, distributed, and human readable naming system, sacrificing only
+the call for all human readable names to be globally unique by mandating only
+local uniqueness.  While all messages in I2P are cryptographically addressed
+by their destination, different people can have local addressbook entries for
+"Alice" which refer to different destinations.  People can still discover new
+names by importing published addressbooks of peers specified in their web of trust,
+by adding in the entries provided through a third party, or (if some people organize
+a series of published addressbooks using a first come first serve registration
+system) people can choose to treat these addressbooks as name servers, emulating
+traditional DNS.
+</p>
+
+<p>
+I2P does not promote the use of DNS-like services though, as the damage done
+by hijacking a site can be tremendous - and insecure destinations have no
+value.  DNSsec itself still falls back on registrars and certificate authorities,
+while with I2P, requests sent to a destination cannot be intercepted or the reply
+spoofed, as they are encrypted to the destination's public keys, and a destination
+itself is just a pair of public keys and a certificate.  DNS-style systems on the
+other hand allow any of the name servers on the lookup path to mount simple denial
+of service and spoofing attacks.  Adding on a certificate authenticating the
+responses as signed by some centralized certificate authority would address many of
+the hostile nameserver issues but would leave open replay attacks as well as 
+hostile certificate authority attacks.
+</p>
+
+<p>
+Voting style naming is dangerous as well, especially given the effectiveness of
+Sybil attacks in anonymous systems - the attacker can simply create an arbitrarily
+high number of peers and "vote" with each to take over a given name.  Proof-of-work
+methods can be used to make identity non-free, but as the network grows the load
+required to contact everyone to conduct online voting is implausible, or if the
+full network is not queried, different sets of answers may be reachable.
+</p>
+
+<p>
+As with the Internet however, I2P is keeping the design and operation of a 
+naming system out of the (IP-like) communication layer.  The bundled naming library
+includes a simple service provider interface which alternate naming systems can
+plug into, allowing end users to drive what sort of naming tradeoffs they prefer.
+</p>
+
+<h2 id="app.syndie">Syndie</h2>
+
+<p>
+Syndie is a safe, anonymous blogging / content publication / content aggregation system.
+It lets you create information, share it with others, and read posts from those you're
+interested in, all while taking into consideration your needs for security and anonymity.
+Rather than building its own content distribution network, Syndie is designed to run on
+top of existing networks, syndicating content through eepsites, Tor hidden services,
+Freenet freesites, normal websites, usenet newgroups, email lists, RSS feeds, etc.  Data
+published with Syndie is done so as to offer pseudonymous authentication to anyone 
+reading or archiving it.
+</p>
+
+<h2 id="app.i2ptunnel">I2PTunnel</h2>
+<p><i>Developed by: mihi</i></p>
+
+<p>
+I2PTunnel is probably I2P's most popular and versatile client application, allowing
+generic proxying both into and out of the I2P network.  I2PTunnel can be viewed as
+four separate proxying applications - a "client" which receives inbound TCP connections
+and forwards them to a given I2P destination, an "httpclient" (aka "eepproxy") which 
+acts like an HTTP proxy and forwards the requests to the appropriate I2P destination 
+(after querying the naming service if necessary), a "server" which receives inbound I2P
+streaming connections on a destination and forwards them to a given TCP host+port,
+and an "httpserver" which extends the "server" by parsing the HTTP request and
+responses to allow safer operation.  There is an additional "socksclient" application,
+but its use is not encouraged for reasons previously mentioned.
+</p>
+
+<p>
+I2P itself is not an outproxy network - the anonymity and security concerns inherent
+in a mix net which forwards data into and out of the mix have kept I2P's design focused
+on providing an anonymous network which capable of meeting the user's needs without
+requiring external resources.  However, the I2PTunnel "httpclient" application offers
+a hook for outproxying - if the hostname requested doesn't end in ".i2p", it picks a
+random destination from a user-provided set of outproxies and forwards the request to
+them.  These destinations are simply I2PTunnel "server" instances run by volunteers 
+who have explicitly chosen to run outproxies - no one is an outproxy by default, and
+running an outproxy doesn't automatically tell other people to proxy through you.
+While outproxies do have inherent weaknesses, they offer a simple proof of concept for
+using I2P and provide some functionality under a threat model which may be sufficient
+for some users.
+</p>
+
+<p>
+I2PTunnel enables most of the applications in use.  An "httpserver" pointing at a
+webserver lets anyone run their own anonymous website (or "eepsite") - a webserver
+is bundled with I2P for this purpose, but any webserver can be used.  Anyone may 
+run a "client" pointing at one of the anonymously hosted IRC servers, each of which
+are running a "server" pointing at their local IRCd and communicating between IRCds
+over their own "client" tunnels.  End users also have "client" tunnels pointing at
+<a href="#app.i2pmail">I2Pmail's</a> POP3 and SMTP destinations (which in turn are 
+simply "server" instances pointing at POP3 and SMTP servers), as well as "client"
+tunnels pointing at I2P's CVS server, allowing anonymous development.  At times people have
+even run "client" proxies to access the "server" instances pointing at an NNTP server.
+</p>
+
+<h2 id="app.i2pbt">i2p-bt</h2>
+<p><i>Developed by: duck, et al</i></p>
+
+<p>
+i2p-bt is a port of the mainline python BitTorrent client to run both the tracker and
+peer communication over I2P.  Tracker requests are forwarded through the eepproxy to
+eepsites specified in the torrent file while tracker responses refer to peers by their
+destination explicitly, allowing i2p-bt to open up a 
+<a href="#app.streaming">streaming lib</a> connection to query them for blocks.
+</p>
+
+<p>
+In addition to i2p-bt, a port of bytemonsoon has been made to I2P, making a few
+modifications as necessary to strip any anonymity-compromising information from the
+application and to take into consideration the fact that IPs cannot be used for 
+identifying peers.  
+</p>
+
+<h2 id="app.azneti2p">Azureus/azneti2p</h2>
+<p><i>Developed by: parg, et al</i></p>
+
+<p>
+The developers of the <a href="http://azureus.sf.net/">Azureus</a> BitTorrent client
+have created an "azneti2p" plugin, allowing Azureus users to participate in anonymous
+swarms over I2P, or simply to access anonymously hosted trackers while contacting
+each peer directly.  In addition, Azureus' built in tracker lets people run their
+own anonymous trackers without running bytemonsoon (which has substantial prerequisites)
+or i2p-bt's tracker.  The plugin is currently (July 2005) fully functional, but is in early
+beta and has a fairly complicated configuration process, though it is hopefully going
+to be streamlined further.
+</p>
+
+<h2 id="app.i2phex">I2Phex</h2>
+<p><i>Developed by: sirup</i></p>
+
+<p>
+I2Phex is a fairly direct port of the Phex gnutella filesharing client to run 
+entirely on top of I2P.  While it has disabled some of Phex's functionality,
+such as integration with gnutella webcaches, the basic file sharing and chatting
+system is fully functional.
+</p>
+
+<h2 id="app.i2pmail">I2Pmail/susimail</h2>
+<p><i>Developed by: postman, susi23, mastiejaner</i></p>
+
+<p>
+I2Pmail is more a service than an application - postman offers both internal and
+external email with POP3 and SMTP service through I2PTunnel instances accessing a
+series of components developed with mastiejaner, allowing people to use their 
+preferred mail clients to send and receive mail pseudonymously.  However, as most
+mail clients expose substantial identifying information, I2P bundles susi23's
+web based susimail client which has been built specifically with I2P's anonymity 
+needs in mind.  The I2Pmail/mail.i2p service offers transparent virus and spam
+filtering as well as denial of service prevention with hashcash augmented quotas.
+In addition, each user has control of their batching strategy prior to delivery
+through the mail.i2p outproxies, which are separate from the mail.i2p SMTP and
+POP3 servers - both the outproxies and inproxies communicate with the mail.i2p
+SMTP and POP3 servers through I2P itself, so compromising those non-anonymous 
+locations does not give access to the mail accounts or activity patterns of the
+user.  Further details and plans for future refinements can be found on the
+eepsite <a href="http://www.postman.i2p/">www.postman.i2p</a>.
+</p>
+
+</body>
+</html>
-- 
GitLab