How to achieve the Eternity?

Tonda Beneš, KSI MFF UK Praha

May 28, 1998

Abstract

The Eternity Service is a highly reliable system for data storage and retrieval. Using redundancy and anonymity a very good data availability is achieved. We are proposing some improvements concerning used cryptographic techniques. We also divided the whole system into a two parts. The lower layer represents a mission independent mixing router capable to support various applications such as anonymous http or ftp protocol, anonymous mail or news system etc. The upper layer implements Eternity service specific servers and clients.

1 Introduction

In 1996 Ross Anderson had proposed a new system of data storage - The Eternity Service [1]. The main idea was to randomly distribute redundant copies of a data across some wide area network (for example Internet) servers, without keeping track which servers were involved in the transaction. In such arrangement for a potential attacker it is very difficult to find and destroy all copies of the data.

The Eternity Service ^{1} does not support the notion user, or data owner. Everybody can ask any data and, if available, system will provide it. Such anonymity is crucial for achievment of a good availability of a data. Without knowledge of requester’s identity no selective denial-service attack could be mounted easily.

All transactions within the Service are end-to-end encrypted. It brings further protection of data availability because under such conditions it is even more difficult to track transferred messages or to couple requests with corresponding responses and with stored files.

When client wishes to acquire some information from the Service it has to specify, which one it should be. He can do that directly if he knows the server that holds the information or indirectly. In such case it contacts any server and asks for required information. The server then in cooperation with other servers finds some copy of the relevant data and sends it to the client. It is not difficult to imagine an appropriate mechanism allowing such finding of the relevant data. For example we can associate some list of keywords with every data and then conduct sort of pattern matching tests.

1It should be mentioned that the denotation “The Eternity Service” uses for his system Adam Back. His system is a light simplification of Aderson’s proposal. It is only a text storage and retrieval system, implemented in Perl as cgi-script for WWW servers. For more information see http://eternity.internexus.net

Service itself provides no means for assuring privacy and data secrecy. If client wishes to keep submitted data secret it has to achieve it at his own account using appropriate cryptography techniques.

In the Anderson’s basic article some other techniques was briefly discussed that was supposed to strenghen resistence of the Service against various attacks. It should be mentioned not only classical threads such as natural disasters, technical failures, vandals and hackers were considered. The Service should protect stored data against court decisions, religional leader’s orders or special services activities.

The additional techniques are various sorts of administrative arrangements. Althought clever, its are not very interesting from algorithmic point of view. That is why we will not describe its now.

We have decided to re-think original Anderson’s design. Our goal was to strenghen important features of the Service to make it even more resistent against attacks held by highly professional oponents. We have divided it into two relatively independent parts.

The lower part is general message routing mechanism with very strong cryptographic features. It prevents any possibility of a communication analysis and provides mutualy anonymous communication for parties. It also hides physical topology of the system. All that anyone knows about its peer is peer’s digital pseudonym. We will propose some new protocols for this purpose.

Services provided by the routing mechanism are used by upper level servers and clients to communicate each with others. We use several types of the servers and clients to accomplish necessary functions of the Service.

The main feature of our design is a high degree of independence of individual parts of the Service. No server or client functionality relies on proper function of any other component. Anyone could in any moment arrange selected type of server and start its conducting. If any server is destroyed or gets by any other reason lost, no negative consequences will impact the rest of the system.

In following sections of the article we will describe the most important parts of our proposal.

2 Routing mechanism

We believe that a lack of information is the best protection for a data inside any large system. When anybody wants to destroy or modify the data it have at first to find the exact place where the data are stored. In large enough system it is likely to be a very difficult task. The solution will probably be time consuming and expensive.

In fact the attacker could try to manage attack of one of the two main types. The first it could try to locate exactly the information and then damage it “in place”. The second an attacker could conduct an attack that will impact large enough part of the system and hope that the information will be injured. Recall, that among potential attackers we place politics, courts, governments or religious leaders. For such attacker it could be feasible at some circustamces at least.

The routing mechanism should overcome first type threads. Unfortunately a message have to contain complete information about its recipient in order to be deliverable. The widely used trick [3, 6] is to subdivide the adress of a recipient of the message into several parts. These parts describes path of the message across intermediate nodes. Each part is encrypted so that it si readable only for relevant node. When the message is transferred, only the very first part of the path description is transmitted as a plaintext (the rest parts are either still encrypted, either stripped from message by previos nodes). Each node first strips the first part of path description (which points to it) and then decrypts the following part. Using standard message passing mechanism the message is transferred to next node and finaly to the recipient.

The would be attacker have to trace message across the nodes and at every node find where the message was routed next. To accomplish such task is not very easy and we can arrange the behaviour of the nodes such that it will be even more complicated.

At first, we can completely change the message at every node. It could be done using encryption – the node encrypts the message with respective key before it is sent further. With modern fast symmetric encryption algorithms it is pretty feasible. The next possibility is to “standardize” sizes of the messages. It is simmilar to the method by which a files are stored on a disc. Size of a message is to be rounded up so that it is multiple of some basic block. The unused space at the end of message is filled with a random padding. Both two previous arrangements follow the same goal. Its complicate to attacker any passive analysis of communication and coupling corresponding incomming and outgoing messages.

The attacker can in such situation attack directly the node and attempt to acquire the needed information from its internal data structures. For this reason the node should not keep any execution log of performed transactions. The node should not have any persistent data structures. All necessary information should be constructed just before the moment it is to be used and destroyed immediatelly after finishing of the transaction. Such behaviour is often called Perfect Forward Secrecy.

The mentioned mechanisms could be considered as sort of “collective defense”. Its are effective only if there is enough of other messages. In such situation we can every message hide among other ones. So we need the system is large enough and the traffic is reasonable strong. Our opponent could refine some interesting information from monitoring of the whole network. For example he could invoke heavy communication with some node. Then by comparison of the load of the lines he could identify the path of messages.

To overcome this problem we will use a padding traffic. When there is a lack of the real communication the system itself generates an inner communication. Thanks to encryption, this traffic is indistinguishable from a real data. We must assure that the messages invoked by client requests or any other legal reasons are transmitted without any noticeable increase of traffic load. There are two ways it could be achieved. We could maintain a stable level of communication load using continuous issuing of padding messages. When the real data transfer is necessary, we only the padding messages replace with real messages. The second way is to randomly generate bunches of padding messages. In the case the data are to be transmitted we just stop the padding traffic production and send the data in several randomly delayed bunches of messages.

The trick is to achieve such arrangement, that no noticeable changes in statistical charakteristic of message flow will owing to real data transmission. Note that the real data will represent a bigger part of a communication. An occasionally communication peaks we will spread into longer time period and padding will be used only to fill moments, where no reasonable data are available. The concrete setting depends on a local situation and is a question of fine-tunning. It is only necessary that changes in the setting will not follow changes in communication load too closely.

There left the last problem to solve. We have to construct message path description without knowing the exact location of the recipient, which looks uncontrollable. We can divide the problem into two parts that both are pretty manageable. Each node, that wants to receive any message releases so called Access Certificate (AC). The certificate contains description of the secont part of the path that ends at the recipient. It also contains recipient’s digital pseudonym.

When anyone wants to send a message to an arbitrary recipient it first gains its AC. Then it completes the path description adding the first part of the path to the description provided in certificate. To be recipient able to response to the message, sender appends to the message its own access certificate. Then it prepares data and sends the message.

Message is passed through an arbitrary number of intermediate nodes, as was mentioned above. The nodes we name Mixes. Each part of the path description is to be encrypted in such a way so that only the relevant Mix could decrypt it. It could be easily done using public key encryption. For this puspose each Mix issues Mix certificate (MC) containing public key of the Mix and some other necessary information.

The both part of path description should be created using randomly selected Mixes.

We also need to change message at every Mix. It is done by encyphering the message with some conventional (symmetric) encryption algorithm. The problem is from where the keys will be taken. The answear is very simple, the keys are part of the path description. Besides a next Mix address, each part of the path description contains a symmetric key.

A Mix then works uniformly nevertheless it belongs to the first or second part of the path. The message consists of two parts. The first part is a path description, the second one is a clients data. Mix first of all strips its own adress from the first part. Then it decrypts the first part of the message. Together with the address of the next Mix it decrypts a symmetric key. The key Mix uses to encrypt the second part of the message. It also pads the first part to the original length. After this work is done, Mix sends the message to a next node – unless the next address is its own too. In such case the Mix passes the message to an upper layer server. As a last part of its task Mix destroys all the data associated with the transaction.

Because the recipient had created its own AC, it knows all the symmetric keys used to encrypt message during the second part of the path. So it is able to take steps to decrypt the message finaly. What it lacks to succeed in this mission are the keys used in the first part of a message journey. The sender must help here. It have to decrypt (in reverse order) the message before sending with all the symmetric keys it used to construct the first part of the path.

The data itself is encrypted with recipient’s public key, so they are protected even it the “middle” of the path. During the first part of message transfer are removed changes involved by decryption with client specified symmetric keys. Thanks to features of encryption algorithm the changes of message between Mixes are totaly unpredictable for everybody including the recipient. Mixes along the second part of a transfer repeatedly encrypts the data with its symmetric key. It makes the message untraceable for everybody including the sender. In both cases only the constructor of the corresponding part of the path could track the message. The first part of the message keeps the same length along the path. Thus no Mix can gues its order within the path.

Let’s put it all in more formal expression:

The Access Certificate of the server is of the form:

{Sn/2|An/2 − 1|… |{S2|A1|{S1|A0}Kpbl_{M1} }Kpbl_{M2} … }Kpbl_{Mn/2}

|KpblA|Texp|Tmax|Misc|Sign

Here Kpbli denotes public key of Mix i, Ai its address and Si is the symmetric key which the Mix i will use to encrypt transferred data before sending it to a next node. An encipherment of the message m with key K is written {m}_{K}, | is used for concatenation. KpblA is a public key of the server A used for encryption, Texp is an expiration time of the certificate, Tmax a maximal time for which a data can be stored at the server and Misc represents a space for additional information. The whole certificate is digitally signed and the resulting sign Sign is appended to its end.

Here is a message just prepared by sender:

An|{Sn|An − 1|{Sn − 1|… |A1|{S1 |A0}Kpbl_{M1} … }Kpbl_{Mn − 1} }Kpbl_{Mn}
|{{… {{AC|data}_{KpblB} }Sn/2 + 1^{−1}… }Sn − 1^{−1}}Sn^{−1}

Note that {m}_{K^{−1}} means decipherment of a message m with key K.

Bellow the paragraph you can see the same message after processing at first along the path Mix just before sending to a next Mix. The first part was decrypted with private key of the Mix and after stripping the symmetric key and address of a next Mix padded with padd to original length. The secon part was encrypted with key Sn i.e. the transformation caused by decryption with this key was removed.

An − 1|{Sn − 1|… |A1|{S1|A0}Kpbl_{M1} … }Kpbl_{Mn − 1} |padd
|{… {{AC|data}_{KpblB} }Sn/2 + 1^{−1}… }Sn − 1^{−1}

The second part of the message “in the middle” of the path is protected by recipient’s public key. The more correct record should contain changes of the padding because each Mix appends new padding of the size of stripped information. The padding will never be interpreted, it serves only to keep the same size of the first part. So we omit this detail.

An/2|{Sn/2 − 1|… |A1|{S1|A0}Kpbl_{M1} … }Kpbl_{Mn/2} |padd
|{AC|data}_{KpblB}

The more correct record should contain changes of the padding because each Mix appends new padding of the size of stripped information. The padding will never be interpreted, it serves only to keep the same size of the first part. That is why we omit this detail.

After first Mix within the second part of the path the message looks as follows:

An/2 − 1|{Sn/2 − 1|… |A1|{S1|A0}Kpbl_{M1} … }Kpbl_{Mn/2 − 1} |padd
|{{AC|data}_{KpblB} }Sn/2

In fact the whole thing is little more complicated. Each address block Ai contains not only the address of a next Mix but a number of additional usefull information too. Besides others there is a protocol number, used encryption algorithms and relevant parameters, identification of used public key (a Mix could issue several MC-s) and so on.

The MC contains a public key of the Mix and some additional information. For example there is a list of supported protocols, expiration time of the certificate, max size allowed size of the message etc.

The public key encryption algorithms are many times slower than general symmetric ciphers. Thus everywhere the public key encryption of large data is to be performed, we use standard trick. A large data are encrypted using randomly generated symmetric key and only the key itself is encrypted with public-key algorithm and then appended to the data.

3 Service specific servers

The Service uses three types of servers. Before we will start to discuss each type separately, let us look at some to all types common features. Individual servers cooperate together, but each server is totaly independent on any other particular machine. It only needs that there is an arbitrary number of properly working servers of different types available.

Such arrangement has several advantages. As was mentioned at the begining, the Service is easily scalable. Everyone could simple start conducting of any server without need to register itself somewhere or so. Flat architecture without any central element reduces the risk of a bottle-neck. The main purpose of existence of the Service is to survive attacks and disasters. We must take into account that from time to time some server will be destroyed or damaged at least. Proposed architecture minimizes loses of such events, because there are no coupling between servers. In fact the Service is everywhere but no at any point.

3.1 The Eternity Server

The most important server is The Eternity server (ES). It implements the main part of the functionality of the whole Service. Althougt the substantial part of security of the Service is provided by the routing mechanism described in the previous section there still left a couple of problems to solve. Much of them is solved within the design of ES.

There are some unususal circustamces that worth our attention. The protection mechanisms are normaly designed to defend against outside threads. We need something more. Besides the traditional protection we want to protect the owner of the server against the knowledge, what the data his server actually processes.

Why such a strange provision? The Service should act as a unchangeable memory of its clients. We hope that the overal reliability a trustworthiness of the Service will be strenghenned if nobody including the server administrator will have direct access to stored data. We also believe that there is little chance that legal action will be targeted against the whole Service. But it is probable that the administrators of all servers within some country or even larger region will be ordered to remove some specific files.

The Trusted Computing Base (TCB) is used to solve the problem of secrecy of stored data. A handled data is at every moment encrypted with some key in such a way, that it could be decrypted only by TCB. We will not go into details of data processing. Everything we need for understanding how the server works is the fact, that only the TCB “knows” what data server handles.

When the server obtains any request concerning data, it does not understand it. It refer the request to a TCB which tells back, what to do. Server then takes corresponding steps, but it works on encrypted files not knowing, what they contain. When server realises that it needs for example reencrypt data with some communicationg key, it requests TCB again.

TCB works like a filter. To defined inputs it responses with corresponding results. It covers all cryptography operations over stored data. All computing including any auxiliary data structures is done inside its secure perimeter.

TCB needs many necessary data structures to be able to work properly. It is not able to keep these structures inside its secure perimeter. Thus it stores them outside protected by encryption with various keys. Even the keys represents too large amount of data to be stored inside. So TCB uses a hierarchy of keys and everything it stores permanently inside its secure perimeter is the key at the very top of the hierarchy – the TCB master key. All other keys are stored outside encrypted with some higher order key. There is no way how to obtain any key used by TCB.

The TCB should be implemented in hardware. This is the only solution that provides high level of security. Because the hardware device is likely to be expensive, especially for amateur enthusiasts, it could be substitued with software modul. Such solution unfortunately has negative impact on resistance of the server.

The ES processes two types of requests. The first is a request to store data for some period. The second is request to provide data corresponding to a given specification. No less, no more. After specified period is the data removed automatically. No way to change or remove stored data is available.

If the server keeps corresponding data, it provides it to requester. If not, it tries to acquire data from several randomly selected servers. The depth of the search is limited to avoid flooding of the system with requests. Server restricts the volume of its response. In the case of too wide request it does not provide the actual data, but only responses with aproximation of total amount of corresponding data.

A list of client specified keywords is associated with every data file. Before depositing each data file is labeled with server-wide unique name. Together with the server pseudonym it is likely to constitute system-wide unique identification. Not necessarily, because a server names must not be different in every cases.

A client could form his request using relevant keywords or a name of a file or both. He could record pseudonym of some of the servers to which he had submitted the data. This enables him later to request directly the server that keeps its data and get faster response. On the other hand he should not record all servers, because the record could be compromised and then it represents security risk for the servers.

The storage of a large amount of data mostly for a long time periods is a very expensive business. The problem of payments for the storage is rather complicated, because the both parties does not know each other. We also must assure, that payments will be carried out only for an actually provided services, i.e. we need some mechanism that allows proofs that server is still keeping the relevant data. At the same time we must prevent the server from performing the proof based on a data acquired from an other server. We also need that none, but the server can perform the proof.

It is clear that individual copies of the data have to be different. This prevents the server from “borrowing” the data elsewhere and use it for a proof of data ownership. There should not be any feasible way how to transform one copy into any other using only small amount of additional information. On the other hand it should be simple to recover original data from any copy.

The solution is surprisingly simple. At the beginnig of each copy of the data we place a (different) random string. A copy is then encrypted with private key of public-key algorithm. Corresponding public key is concatenated to resulting data and the private key is discarded. Thus anybody could remove the privatekey encryption, but nobody can construct the copy of data from any other. The exact form of copy of data is as follows:

Kpbl|{rand| data}_{Kprv}

The next part of the problem of data ownership proof is tighly connected with problem of payment protocol. We will discuss both problems at once.

The following protocol solves all mentioned problems:

A client prepares as many copies of the data as he wish. Then he contacts randomly selected servers and asks them for storage of his data. Each server tells conditions under which it will store the data. The conditions contains a price of storage, payment calendar, bank identification etc.

When client complies with conditions, he sends to the server one copy of the data together with list of keywords. The server stores data and responses with a payment plan. The whole period of data storage can be divided into several subperiods. Each item of the plan (one for each period) contain identification of the bank, the price, identification of payment, and a special part called Sealed Server Authenticator. The Server Authenticator (SA) is required by bank before any payment is carried out. Thus, only the owner of SA can receive the payment. This provision prevents client from maquerading the server and receiving payments back. Sealed Server Authenticator is created form SA by encryption the SA with bank’s public key.

Using information from previous step, the client prepares payment orders. Each order contain an Owner Authenticator (OA). The OA will be used as an initialization vector in the proof of data ownership and prevents server from pre-computing the proof and discarding the data prematurely. The order also contains an information about time, when it could be carried at first.

Bank records all payments and sends back confirmation of its. Client resends the confirmation to server. In the case the server will not obtain confirmation from bank within some agreed period, it discards all corresponding data.

From this time server holds the data and periodically according to payment plan requests bank for payment. The bank checks whether the payment could be carried out already. If so, it sends to the server OA. Server uses the received OA as an initialization vector and computes a hash function over its copy of the data. To the result it append stored SA and the whole message sends to the bank.

Bank compares received values with those it has stored and if they matches, carries out the payment. The server is notified about the result. Notification allows to a server respond to situation. For example it could discard data for that it is repeatedly unable to receive payment.

Let us describe the whole situation more formally. Let C be a client, E be a randomly selected Eternity Server and B be a bank that carries payments. TId stands for transaction identification, Time is requested time of storage, Size is the size of data to be stored. In its response server identifies bank or banks that will carry payments (BankID) and counts aproximation of total price (Price). After receiving the data server prepares payment plan. (For a sake of simplicity our protocol assumes only one payment.) S-PayID is server’s internal identification of the payment.

The whole protocol consist of following steps:

1.  C⟶E : {TId|Time|Size|Misc}_{KpblE}
2.  E⟶C : {TId|Yes/No|BankId|Price}_{KpblC}

3.  C⟶E : \{TId|Keywords|\overbrace{[Kpblx|\{Rand_{x}|Data\}_{Kprvx}]}^{unique copy of the data}\}_{KpblE}

4.  E⟶C : \{TId|BankId|\overbrace{\{S-PayId|SA\}_{KpblB}}^{Sealed SA}|Price|KpblE \}_{KpblC}
5.  C⟶B : {KpblE |Pay-Order|Time|Sealed SA|OA|MAC}_{KpblB}
6.  B⟶C : {{S-PayId|B-PayId|Pay-Conf}_{KpblE} |⟨Pay-Order⟩_{KprvB} }_{KpblC}
7.  C⟶E : {TId}_{KpblE} |{S-PayId|B-PayId|Pay-Conf}_{KpblE}

After performing these steps there are prepared payments in the bank and the server holds stored data and is ready to provide it to any client. Note that ⟨m⟩_{K} means digital signature of message m with key K. The Pay-Conf is a confirmation of a payment from bank. Bank commits itself to carry the payment in the future. It contains no information about money source.

The protocol for proofs of data ownership and for payments between server and bank is straightforward. Server asks for payment, bank sends to it OA. Server computes MAC of the data based on the OA and the result sends back together with SA. Bank compares both values with stored copies and if they fits, it carries out the payment and notifies the server. A simple hash function like SHA or MD-5 is used for computing MAC. Here is the protocol:

1.  E⟶B : {B-PayId|S-PayID}_{KpblB}
2.  B⟶E : {B-PayId|S-PayID|OA}_{KpblE}
3.  E⟶B : {B-PayId|S-PayID|MAC}_{KpblB}
4.  B⟶E : {B-PayId|S-PayID|Yes/No}_{KpblE}

The easiest way to destroy a data kept by server is to shift its system time. The server in such case would consider stored data as expired and deletes it.

There must be some provision against such thread. From time to time each ES contacts several randomly selected servers and acquires from them their local time. Based on obtained information it corrects its local time. Before correcting the local time server checks, whether there is any payment, that should be realized as a consequence of time change. If the server encounters any payment, that bank refuses due to too early request, it sets local time before time of the payment and notifies administrator. It looks quite difficult to “push” time on large number of servers at once. Together with the second condition the mechanism looks to be robust enough.

All communication with other servers and with clients uses routing mechanism described in previous section.

3.2 The Access Certificate Server

When anybody wants to contact the Service it needs at least one AC of an Eternity Server and an arbitrary number of Mix certificates MC to be able to construct own certificate and the path. Because the ES servers and the Mixes are hidden as good as possible, there must be any “entry point” to the Service. This is a role for Access Certificate Server (ACS). ACSs are the only directly accesible and widely publicised parts of the Service.

The ACS is a multiplatform server. It could have different interfaces, for example via http or ftp protocols. In any case the main communication interface of the ACS should be routing mechanism described in section 2.

The main interface is used for regular processing. Servers uses the main interface to obtain needed certificates and to publicise their new ones. The additional interfaces are used mainly in the first contact with the Service. In such case any client (or a potential future server conductor) needs a way how to obtain their first in the life certificates.

3.3 The Mix Server

The Mix Server does not have any substantial functionality. It represents the administrator’s interface only. Normaly the Mix works as a part of upper level server software. We assume, that much more Mixes will be conducted as standalone routers together with regular IP routers, firewalls, gateways and other Internet servers. It is a simple and easy way how to make the Service bigger and thus more secure.

4 Other servers

We believe the routing mechanism described in section 2 is able to support various types of servers. We consider this fact as very important. When more different servers will use the same “hiding” mechanism, then individual systems could provide protection each to others. Re-use of the same transport protocol brings better protection for all due to huge overal volume of communication.

It is also effective from point of view of implementation of the systems providing high level of security. When there exists good transport protocol with necessary features, the implementation of such systems could be substantially simpler and faster.

We assume the most widespread Internet servers will be very simple to “anonymise” using our routing mechanism. Adjustment of a http server is straighforward. All that we need is to replace SSL layer with an interface to our routing mechanism. There are two possible solutions on the side of http client. The first possibility is to upgrade an existing client and add to it ability to use our routing mechanism. Fro this purpose the Netscape’s plug-in modules seems to be a good solution. The second possibility is arrange a special types of http proxies that will act as application gateway between a http client and our routing.

The ftp server could be adjusted in the same way as an http server. Due to more simple client software, there seems to be reasonable to create new client able directly use “Eternity routing”.

Anonymous remailers and anonymous news servers could be also turned to the same platform. In the place of adress the servers will work with access certificates of its clients.

5 Conclusion

Todays trends in information technology surprisingly brings a less fault tolerant handling of information. Thanks to global access to informations, the overal number of copies of the individual information is greatly reduced. It represents a great growth of the risk of loss of the information, or inconspicuous change. The Eternity Service brings a way, how to store data with almost absolute certainty that it will survive without any modification. We have proposed a new protocols that strenghen important features of the Service. Namely it is a design of the routing mechanism, the protocol for payments and for proofs of data ownership and the mechanism of a time synchronisation. We propose to separate routing mechanism as independent platform capable of supporting various types of services.

Introduced protocols and the whole desing are not the final form. The design is still in progress. Currently a group of students at Faculty of Mathematics and Physics of Charles University works together with author towards the liveimplementation of the Service based on these ideas. For more information, visit http://www.kolej.mff.cuni.cz/˜ eternity/index.html

References

[1] Ross. J. Andersson: The Eternity Service, article, Pragocrypt 1996

(http://www.cl.cam.ac.uk/rja/eternity.html)

[2] Andre Bacard: Anonymous Remailer FAQ, http://www.well.com/user/abacard/remail.html

[3] David M. Goldschlag et. al.: Hiding Routing Information, Workshop on Information Hiding, Cambridge, UK, May 1996

[4] D. Chaum: Untraceable Electronic Mail, Return Addresses, and Digital Pseudonyms, Communications of the ACM, v. 24, n. 2, Feb. 1981, pp. 84–88.

[5] D. Chaum: The Dinning Cryptographers Problem: Unconditional Sender and Recipient Untraceability, Journal of Cryptology, 11, 1988, pp. 65–75

[6] Ian Goldberg, David Wagner:TAZ Servers and the Reweb Network