Author Topic: Phönix aus der Asche?  (Read 5165 times)

0 Members and 1 Guest are viewing this topic.

Offline hummel

  • Elite
  • *****
  • Posts: 429
  • Karma: +12/-0
    • View Profile
Phönix aus der Asche?
« on: February 28, 2009, 07:33:00 PM »
Wie einigen von euch vielleicht aufgefallen ist, befindet sich meine planetpeer-Aktivität schon seit Monaten auf einem Tiefstand.
Seit Anfang Jahres bin ich beruflich ziemlich ausgelastet und davor war ich recht intensiv mit meinem eigenen Projekt (http://board.planetpeer.de/index.php/topic,5178.msg27379.html#msg27379) beschäftigt, so dass ich kaum Zeit hatte, mich wirklich ums Forum zu kümmern. Und leider muss ich euch nun mitteilen, dass aus dem Projekt, in dem doch mehr als ein halbes Jahr Fleiss und Müh steckt, nichts geworden ist. Es ist mir einfach über den Kopf gewachsen. Am Ende war es nur noch ein grosses Flickwerk, das schon im Testbetrieb an allen Ecken und Enden geblutet hat. Ausserdem hatte ich zunehmende Zweifel am eigentlichen Konzept.

So bleibt mir leider nichts anderes übrig, als das definitive Aus für das Projekt zu verkünden. :'( (Sollte jemand trotzdem Interesse haben an einer 300kb grossen Quellcode-Leiche als Beweis für meine sinnlos verschwendete Zeit, kann sich ja bei mir melden. ;) )

Bevor ich hier noch ganz in Lethargie verfalle, möchte ich doch noch verheissungsvollere Dinge ansprechen: Seit dem Untergang meines Projekts kreisen meine Gedanken um ein anonymes Netzwerk, welches nicht auf dem üblichen Modell der Datendurchleitung basiert, sondern Anonymität auf der Inhaltsebene durch Linearkombination von Datenblöcken herstellt. Da meine Idee langsam Formen annimmt, würde ich sie euch gerne vorstellen, aber nur sofern Interesse besteht.

Grob gesagt geht es einen verteilten Datenspeicher, bei dem zusätzlich zu den Blöcken auch deren Linearkombinationen auf den Knoten abgespeichert werden. Diese ermöglichen dann die Maskierung der eigentlichen Datentranfers. Der pro Datenblock anfallende (direkte) Overhead besteht letzten Endes aus einer Blockkombination, die gleich gross ist wie der Klartextblock. Der gesamte Overhead wird aber mehr als 100% betragen, da auch ein gewisses Mass an autonomer Netzwerkaktivität erforderlich ist. Für den ursprünglichen Insert (Upload) der Blöcke werden konventionelle Methoden verwendet, z.B. Onion Routing. Da dies aber nur einmal stattfinden muss, sollte der dabei entstehende Overhead aber nicht so ins Gewicht fallen. Der Ansatz taugt im Moment für kleinere Netze, könnte aber mit einer verteilten Hashtabelle verbunden werden, damit er skaliert.


« Last Edit: February 28, 2009, 07:34:54 PM by hummel »

Offline Äffchen

  • Mitquatscher
  • Elite
  • *****
  • Posts: 1390
  • Karma: +14/-7
    • View Profile
Re: Phönix aus der Asche?
« Reply #1 on: February 28, 2009, 08:21:45 PM »
Hey Hummel!

Magst du erklären, welche Zweifel aufgekommen sind, an dem, doch sehr ausfühlich geplanten und durchdachten Ur-Konzept?

Lass den Kopf nicht hängen, schön von dir zu hören!

Offline SupersurferDeluxe

  • Elite
  • *****
  • Posts: 446
  • Karma: +21/-7
    • View Profile
Re: Phönix aus der Asche?
« Reply #2 on: February 28, 2009, 11:13:27 PM »
Das ist doch mal wieder ein Grund hier zu posten! Würde auch gern mehr wissen, warum du das Projekt irgendwann bezweifelt hast.
Und noch wichtiger: erzähle uns bitte mehr über deine neue Idee!

Ich lechze ja immer noch nach FUNKTIONIERENDEN Alternativen zu den üblichen Routing-Ideen...

Offline rb2k

  • Advanced
  • ***
  • Posts: 297
  • Karma: +3/-0
    • View Profile
Re: Phönix aus der Asche?
« Reply #3 on: March 01, 2009, 08:31:12 AM »
Es ist ja nicht das Ziel dass am Ende was rauskommt sondern dass man auf dem Weg dahin was lernt ;)
Wenn du deine neue Idee mal mit Off vergleichen würdest, was wären denn die hauptunterschiede?

Offline hummel

  • Elite
  • *****
  • Posts: 429
  • Karma: +12/-0
    • View Profile
Re: Phönix aus der Asche?
« Reply #4 on: March 01, 2009, 01:35:23 PM »
Lass den Kopf nicht hängen, schön von dir zu hören!
Danke für die Ermunterung!

Magst du erklären, welche Zweifel aufgekommen sind, an dem, doch sehr ausfühlich geplanten und durchdachten Ur-Konzept?
Ok, um mich kurz zu halten: Nach wie vor bin ich der Überzeugung, dass man durch das geschickte Wiederverwenden von Routen (siehe http://board.planetpeer.de/index.php/topic,4275.msg25151.html#msg25151) eine im Vergleich zu herkömmlichen Netzen (wie I2P) deutlich gesteigerte Effizienz (bei gleichbleibender Anonymität) erreichen könnte.

Das Problem ist aber, dass es dafür eine Instanz braucht, die quasi im Gottmodus den genauen Aufenthaltsort der einzelnen Blöcke kennt. Da diese Instanz gleichzeitig vertrauenswürdig sein muss, kann sie nicht einfach aus einem einzigen Knoten bestehen. So entstand die Idee, dass die Blöcke durch mehrere Tickets adressiert werden, die von verschiedenen Ticketholder-Knoten "gehalten" werden. Da die Tickets für sich allein noch nichts über den Block aussagen, sondern nur ein ganzes Set an Tickets verwertbare Informationen erhält, müssen diese irgendwie zusammengeführt werden; und zwar so, dass der Knoten, der die Tickets enthält, lediglich den gesuchten Block identifizieren (und den Downloadvorgang initiieren) kann, von dem eigentlichen Klartext-Inhalt des Blocks aber nichts mitbekommt. Dieses Problem war noch einigermassen lösbar.

Um ein "Abgrasen" sämtlicher erforderlichen Tickets und das Enttarnen des entsprechenden Datenblocks zu verhindern, müssen die Tickets nach jedem Besitzerwechsel neu randomisiert werden. Das bedeutet aber auch, dass die einzelnen Tickets praktisch aus einer Zufallsfolge bestehen und ein böswilliger Knoten deshalb genau so gut irgendwelche Falschinformationen versenden kann, so dass die zusammengeführten Tickets am Ende nichts mehr hergeben.

Als Abhilfe bietet sich an, die Information redundant auf mehr Tickets zu verteilen, als für die Wiedergewinnung der Info nötig ist. Konkret genügen 2 von 3 Tickets für die Adressierung eines Blocks. Wenn also lediglich einer der drei Tickethalter falsche Daten verschickt, kann die Informationen trotzdem verwertet werden. Andererseits müssen lediglich 2 kollaborierende Knoten die Tickets gleichzeitig ergattern, um den Block identifizieren zu können. Die Behändigung der erforderlichen Tickets durch den Feind führt zwar noch nicht automatisch zur Enttarnung der Downloader des jeweiligen Blocks, bietet aber unter Umständen gezielte Angriffsmöglichkeiten und ist deshalb tunlichst zu vermeiden.

Das Grundsatzproblem besteht folglich darin, dass zwischen der Anonymität und der Funktionstüchtigkeit des Netzes ein verhängnisvoller Trade-Off besteht: Je ausfallsicherer das Netz (z.B. wenn 2 von 6 Tickets die Info enthalten), desto geringer ist die Anonymität. In diesem Fall muss der Feind nur 2 von 6 Tickethalter-Knoten kontrollieren, um den Block enttarnen zu können. Die Wahrscheinlichkeit 2 von 6 (zufälligen) Knoten zu kontrollieren ist aber grösser, als 2 von 3 zu kontrollieren. Das Netz wird letzten Endes immer entweder nur anonym oder ausfallsicher sein, nicht aber beides zusammen!

Dies und die andauernden Probleme mit der Threadsicherheit bewogen mich zur Aufgabe des Projekts.

Insgesamt habe ich folgende Dinge implementiert:
- eine Mathe- und Cryptobibliothek (natürlich aufbauend auf bestehenden BigInteger- und Cryptobibliotheken)
- ein funktionierendes Chord-Netz (eigentlich zwei, aber egal) mit der Möglichkeit redundanter Abfragen (sog. High-assurance locate, siehe http://www.daimi.au.dk/~nikos/papers/hasearch.pdf)
- Onion-Routing mit fixierter Message-Länge (siehe das Original von Chaum: http://www.freehaven.net/anonbib/cache/chaum-mix.pdf)
- Ticket-Insert
- Ticket-Fetch, das aber lediglich in 90% der Fälle funktioniert
- Block-Insert

es fehlen also vor allem die Ticket-Migration (inkl. Re-Randomisierung) sowie das ganze Drum-Herum, sprich: Dateiverwaltung, Up- und Downloadverwaltung, Oberfläche, etc.
« Last Edit: March 02, 2009, 02:21:37 PM by hummel »

Offline hummel

  • Elite
  • *****
  • Posts: 429
  • Karma: +12/-0
    • View Profile
Re: Phönix aus der Asche?
« Reply #5 on: March 01, 2009, 04:06:18 PM »
Und noch wichtiger: erzähle uns bitte mehr über deine neue Idee!

Also gut, aber zwei Dinge vorweg:
1) Der gegenwärtige Ansatz funktioniert nur in einem hinreichend kleinen Netz, in dem sich alle Knoten miteinander direkt verbinden können.
2) Zuerst wird ein vereinfachtes Modell dargestellt; gewisse Details werden erst am Schluss genannt.

Einfügen der Daten (Insert von Blöcken):
Auf konventionellem Weg, d.h. via Onion-Routing, gelangen die Blöcke an ihren Zielort. Da das Netz klein ist, braucht es keine spezielle Ordnung in Form einer DHT (verteilte Hashtabelle). Es genügt also, wenn die Blöcke auf zufällig gewählten Knoten platziert werden. Jedoch müssen die Blöcke jeweils an mehrere Knoten verschickt werden, um eine gewisse Redundanz zu haben. Für die technische Umsetzung des Onion-Routings würde sich Minx (http://www.cl.cam.ac.uk/users/gd216/minx.pdf) hervorragend eignen, weil es erstens einfach und zugleich sicherer ist als Chaum's Original (http://www.freehaven.net/anonbib/cache/chaum-mix.pdf).

Node-Caches
Jeder Knoten verfügt über zwei Caches: einen Block-Cache und einen Comb-Cache. Der Block-Cache ist unterteilt in einzelne Racks, die jeweils eine bestimmte Zahl von Blöcken aufnehmen können. Der Comb-Cache dient dagegen zur Abspeicherung von Linearkombinationen von Blöcken (nachfolgend Block-Kombinationen gennant) und ist in einen öffentlichen und einen geheimen Bereich unterteilt.

Ist ein Rack vollständig mit Blöcken aufgefüllt, so kommt der nächste zum Zug, usw. Sind alle Racks voll, wird der älteste (evtl. nach einem Weitergeben der Blöcke an andere Knoten) komplett gelöscht und dann mit den später ankommenden Blöcken aufgefüllt.

Linearkombination von Blöcken (Block-Kombination)
Daten lassen sich allgemein in Form von Zahlen ausdrücken. Ein kilobit an Information wäre eine Zahl zwischen 0 und 2^1024-1.
So ist es möglich, mit Datenblöcken wie mit gewöhnlichen Zahlen zu rechnen. Eine Linearkombination der Blöcke A1 bis An bedeutet dann c1*A1 + c2*A2 + ... + cn*An, wobei c1..cn (ganzzahlige) Koeffizienten sind. Beachte: Das Resultat ist nur zahlenmässig (deutlich) grösser ist als die in Form von Zahlen ausgedrückten Originalblöcke. Die Datenlänge des Resultats ist aber (glücklicherweise) nur unwesentlich grösser als die der Blöcke A1 bis An. 

Können c1..cn hinreichend grosse resp. kleine Zahlen sein und ist zudem n genügend gross, so gilt mit sehr hoher Wahrscheinlichkeit Folgendes:
n zufällig gebildete Blockkombinationen sind von einander linear unabhängig und können durch erneute Linearkombination (also Kombination der Kombinationen) jede mögliche Kombination der Blöcke A1..An darstellen, sofern man dafür auch reelwertige Koeffizienten zulässt. Oder anders ausgedrückt bilden die n Kombinationen eine Basis für die durch die Blöcke A1..An (quasi als Einheitsvektoren) gebildeten Vektorraum.
Das tönt jetzt sicher kompliziert, ist aber eigentlich halb so wild.

Informationspolitik der Knoten
Die Knoten geben einander auf Anfrage den Inhalt ihrer Racks (genauer gesagt: den Hash-Wert der einzelnen Blöcke) sowie die im öffentlichen Bereich des Comb-Caches abgelegten Block-Kombinationen bekannt. Der geheime Bereich des Comb-Caches wird dagegen nicht offenbart.

Autonomes Verhalten der Knoten
Neben der Tätigkeit als Durchleitungsknoten beim Insert von Blöcken (siehe oben) führen die Knoten folgende Aktivitäten durch:

1) Während der gesamten Laufzeit fordert unser Knoten von den anderen Knoten regelmässig Block-Kombinationen an, die über den gesamten Inhalt eines bestimmten Racks gebildet werden (letztere müssen dafür aber nicht notwendig bereits komplett aufgefüllt sein). Konkret schickt unser Knoten einem der anderen Knoten eine Reihe von zufällig gewählten Koeffizienten c1..cn und nennt das gewünschte Rack (ebenfalls zufällig); der angefragte Knoten antwortet darauf mit der Zusendung der entsprechenden Kombination von Blöcken des gewünschten Racks.

2) Darüber hinaus fordert unser Knoten (in einem noch zu bestimmten Verhältnis zu den soeben erwähnten Anfragen) von Knoten, die bereits eine oder mehrere Block-Kombinationen eines bestimmten Racks (der einem dritten Knoten gehört) besitzen, ebenfalls zufällig gewählte Kombinationen dieser bei ihnen vorhandenen Block-Kombinationen an. Dies dient u.a. der besseren Durchmischung der Kombinationen.

Mit der Zeit werden sich im Netz zu jedem Rack einige Block-Kombinationen finden. Sobald sich pro Rack mindestens n Kombinationen bei (sich ans Protokoll haltenden) Knoten befinden, liessen sich dadurch theoretisch sämtliche Kombinationen, die über den enstprechenden Rack möglich sind, herstellen (siehe oben). Dieses Erfordernis kann durch Ausnützung der Redundanz aber erheblich gelockert werden (dazu später mehr).
 
Die via 1) und 2) erhaltenen Block-Kombinationen speichert unser Knoten zufällig entweder im öffentlichen oder im geheimen Bereich des Comb-Caches ab. Das entsprechende Verhältnis könnte durch Simulation bestimmt bzw. optimiert werden.

Der eigentliche Download von Blöcken
Wegen der zufälligen Struktur des Netzes werden sich die gewünschten Blöcke zufällig auf die Knoten und deren Racks verteilen.
Unser Knoten könnte demjenigen Knoten die ersten Downloadanfragen stellen, der über das Rack mit den meisten für unseren Download benötigten Blöcken verfügt. Voraussetzung dafür ist allerdings, dass unser Knoten pro gewünschtem Block mindestens eine Block-Kombinationen besitzt (im geheimen Comb-Cache), die sich auf das entsprechende Rack bezieht. Ist unser Knoten z.B. an drei Blöcken interessiert, so bildet er aus drei zum Rack gehörenden Block-Kombination wiederum drei neue Kombinationen. (Dies fördert noch einmal die allgemeine Durchmischung der Blöcke).

Nun nimmt sich unser Knoten die erste Kombination vor und bildet eine Liste der jeweiligen Koeffizienten c1..cn. Zu demjenigen Koeffizienten, der zum ersehnten Block gehört, addiert er eine 1 (oder allenfalls eine Zufallszahl) und schickt dann die Liste in Form einer gewöhnlichen Block-Kombinations-Anfrage zum anderen Knoten, der uns darauf mit der angeforderten Kombination antwortet.
Unser Knoten muss dann lediglich die bereits vorhandene Block-Kombination von der soeben erhaltenen subtrahieren und erhält den gewünschten Block.

Diesen Vorgang wiederholt unser Knoten für die restlichen Blöcke und löscht anschliessend die zur Entschlüsselung verwendeten Block-Kombinationen aus dem Geheimbereich. Dies ist leider erforderlich, da einmal verwendete geheime Block-Kombinationen auf keinen Fall wiederverwendet werden dürfen!

Die eigentlichen Blockanfragen unterscheiden sich in keiner Weise von den autonomen Kombinationsanfragen. Die erhaltenen Kombinationen werden also hier wie dort entweder im geheimen oder im öffentlichen Bereich des Comb-Caches abgelegt.

Die Anonymität der Blockanfragen wird demzufolge auf zwei Arten hergestellt:
1. Wissen die Knoten gar nicht, ob eine Anfrage der autonomen Blockbeschaffung dient oder aber zu einer echten Downloadanfrage gehört.
2. Selbst wenn sie dies wüssten, wäre ihre einzige Information, dass unser Knoten an einem resp. einigen der sich im Rack befindenen (evtl. 1000en) von Blöcken interessiert ist. Sofern die Durchmischung der Blöcke in den Kombination hinreichend gross ist, könnte durch die Kombinationen der gesamte Vektorraum aufgespannt werden. Mit anderen Worten könnte sich eine angefragte Block-Kombination mit gleicher Wahrscheinlichkeit auf jeden beliebigen Block des Racks beziehen.

Soweit die Theorie. Zu Möglichkeiten der Effizienzsteigerung und der praktischen Umsetzung später mehr.



 




« Last Edit: March 02, 2009, 12:59:51 PM by hummel »

Offline Eroli

  • Elite
  • *****
  • Posts: 2435
  • Karma: +22/-0
  • StealthNet Developer
    • View Profile
Re: Phönix aus der Asche?
« Reply #6 on: March 01, 2009, 04:29:10 PM »
Kann es sein, dass sich dies viel einfacher umzusetzen anhört, als deine erste Idee?

Offline hummel

  • Elite
  • *****
  • Posts: 429
  • Karma: +12/-0
    • View Profile
Re: Phönix aus der Asche?
« Reply #7 on: March 01, 2009, 04:37:34 PM »
Kann es sein, dass sich dies viel einfacher umzusetzen anhört, als deine erste Idee?
Ja, auf jeden Fall!

Allerdings gibt es noch einige Dinge, die es bei der praktischen Umsetzung zu beachten gilt, darunter ein eher technisches Problem wegen der Performance (Festplatten-Leserate). Dazu schreibe ich heute Abend noch mehr.

Aber das Modell skaliert in dieser einfachen Form natürlich nicht. Zwar habe ich mir auch schon einige Gedanken gemacht, wie man das ganze mit einer DHT wie Kademlia verbinden könnte, doch bin ich damit noch nicht wirklich weit gekommen. Vielleicht kann ich diesbezüglich auf die Unterstützung der Community hoffen?

Offline hummel

  • Elite
  • *****
  • Posts: 429
  • Karma: +12/-0
    • View Profile
Re: Phönix aus der Asche?
« Reply #8 on: March 01, 2009, 08:01:37 PM »
Wenn du deine neue Idee mal mit Off vergleichen würdest, was wären denn die hauptunterschiede?

Der Hauptunterschied zu OFF ist, dass mein Konzept in erster Linie Anonymität anstrebt, während diese bei OFF eher zweitrangig ist.
Eine Ähnlichkeit zu OFF besteht darin, dass - abgesehen vom Insert - auch nach meiner Idee keine Originaldaten zwischen den Knoten ausgetauscht werden. Block-Kombinationen sind ja genauso wie OFF-Blöcke praktisch gesehen Zufallsfolgen.
Obschon zumindest in der gegenwärtigen Entwurfsphase meines Konzepts und im Gegensatz zu Freenet jedermann einsehen kann, welcher Knoten welche Blöcke in seinem Cache hat, kann niemandem die direkte (Weiter)verbreitung dieser Daten unterstellt werden (höchstens die Eigenschaft als Mitstörer hinsichtlich der späteren Wiederherstellung/Vervielfältigung des Originalblocks; auf dieses Thema möchte hier aber nicht mehr eingehen).

Da man jedoch praktisch gesehen nicht davon ausgehen kann, dass der betreffende Knoteninhaber auch weiss, was in seinem Cache gespeichert ist, werden die Daten wenigstens mangels Besitzwillen juristisch betrachtet nicht besessen. Das ist freilich nur bei illegalen Inhalten relevant, weil der Besitz urheberrechtsverletzender Werke sowieso zulässig ist (weder Besitz noch Konsum stellen urheberrechtlich relevante Nutzungen dar).

Natürlich könnte man andenken, auch in meinem Konzept den Besitz der Blöcke irgendwie zu verschleiern, aber das ist Zukunftsmusik.

Nun zu den bereits angetönten Fragen:

1) Gemäss meiner ersten Darstellung müssen für die höchstmögliche Sicherheit mindestens so viele Block-Kombinationen pro Rack auf den verschienden Knoten im Netz vorhanden sein, wie es Blöcke im Rack hat (nur dann kann nämlich der gesamte Vektorraum abgebildet werden). Da man in einem P2P-Netz davon ausgehen muss, dass laufend neue Knoten dazukommen und andere wieder verschwinden, müsste in der Praxis sogar noch um einiges mehr an Block-Kombinationen verfügbar sein, damit die Annahme auch noch bei einer Momentaufnahme des Netzwerks zutrifft. Das wäre aus Performance-Gründen ziemlich nachteilig.

Nun ist es aber zum Glück so, dass ein Block wegen der Redundanz in der Regel auf mehreren Knoten (bzw. in mehreren Racks) gespeichert ist. Demzufolge überschneidet sich der Blockbestand von je zwei zufällig gewählten Knoten in einem gewissen Bereich. Diese Schnittmenge ist umso grösser, je höher die Redundanz der Blöcke im Netz ist. Diese Tatsache können wir uns wie folgt zu Nutze machen: Bei jeder (autonomen) Block-Kombinationsanfrage der zweiten Art (nicht an den Inhaber des Racks gerichtet; siehe in der ursprünglichen Darstellung unter 2)), wird zusätzlich zu der aus den Block-Kombinationen gebildeten Neu-Kombination eine zufällige Kombination der ungebundenen bzw. freischwebenden Schnittmengen-Blöcke angefordert.

Somit werden laufend frische Blöcke in die Block-Kombinationen eingeflochten, welche sich damit immer mehr der Kontrolle des Rack-Inhabers entziehen. Gäbe es im Netzwerk keinerlei Überschneidungen der Blöcke, so könnte die Anonymität im hier verstanden Sinn - wie erwähnt - nur dann zu 100% garantiert werden, wenn ein Downloader für seine Gegen-Kombination (= die zu subtrahierende Kombination) aus mindestens n (= Anzahl Blöcke des Racks) zufälligen Block-Kombinationen gebildet hat. Da aber bei jeder autonomen Anfrage quasi immer wieder frisches "Erbgut" in die Block-Kombinationen gelangt, sollte bereits ein Bruchteil von Kombinationen ausreichen, um insgesamt betrachtet den Vektorraum des Racks vollständig generieren zu können. (Ist das so einigermassen verständlich?)

Es ist also glücklicherweise nicht nötig, dass n Block-Kombinationen im Netz vorhanden sind. Geht man davon aus, dass der Feind nur mit einem einzigen Knoten im Netz auftritt, so träfe bezüglich seiner Racks sogar Folgendes zu: Für die höchstmögliche Anonymität sind mindestens so viele Block-Kombinationen erforderlich, wie es verwaiste Blöcke in dessen Rack hat, d.h. Blöcke, die nur dort und nirgendwo sonst abgespeichert sind. Je mehr solche verwaiste Blöcke es in einem Rack hat, desto mehr Kombinationen werden für die Gewährleistung der Anonymität benötigt. Es wäre somit erwägenswert, Racks, deren verwaiste Blöcke einen gewissen Schwellenwert überschreiten, aus Sicherheitsgründen gänzlich unberücksichtigt zu lassen.

2) Da ein Rack mehrere Tausend Blöcke und damit einige 100 Megabyte an Daten umfassen kann, sind wir mit folgendem Problem konfrontiert: Würde ein Knoten für die Beantwortung jeder einzelnen Anfrage von neuem auf sämtliche Blöcke im Rack zugreifen, so reichte dafür die Leserate der Festplatte bei weitem nicht aus. Abhilfe ist jedoch in Sicht, denn...

Anstatt Blockanfragen sofort zu beantworten, werden die Anfragen über eine gewisse Zeitspanne lediglich entgegengenommen. Parallel dazu arbeit der Client jedes der Racks nacheinander von Anfang bis Ende ab. Es werden also sämtliche Blöcke des Racks eingelesen und entprechend der bis dahin erhaltenen Blockanfragen verarbeitet. Zunächst wird Block A1 gelesen und mit dem jeweils ersten Koeffizienten der Koeffizientenlisten multipliziert. Dann wird Block A2 geladen, mit dem zweiten Koeffizienten multipliziert und zu den vorhandenen Produkten addiert, usw. Sobald das gesamte Rack abgearbeitet worden ist, liegen die Kombinationen für jede der Anfragen (bezüglich dieses einen Racks) vor und müssen nur noch versandt werden. Je nach der Grösse des Caches (Anzahl Racks) und der Geschwindigkeit der Festplatte können zwischen Erhalt der Anfrage und deren Beantwortung trotzdem einige (Dutzend) Minuten vergehen. 

3) Die Tatsache, dass Block-Kombinationen ausgetauscht werden, lässt zwangsläufig die Frage aufkommen, wie man mit gefälschten Antworten umgehen soll. Gewöhnliche Hashwerte wie SHA-1 oder MD5 helfen da nicht weiter, weil sie durch die Linearkombination ihre Aussagekraft verlieren. Glücklicherweise ist man auch hier nicht auf verlorenem Posten, denn es gibt auch so genannte homomorphe Hash-Funktionen, welche die Grundoperationen überdauern. (Übrigens habe ich diese bereits in meinem ersten Projekt verwendet). Siehe http://eprint.iacr.org/2006/150.pdf und http://pdos.csail.mit.edu/papers/otfvec/paper.pdf

Diese basieren auf dem RSA-Modul und teilen auch sonst die Sicherheitsmerkmale von RSA. Leider muss der Hashwert also ziemlich lang (mind. 512, besser 1024 bit) sein, um Angriffe ausschliessen zu können. Angesichts der Tatsache, dass sich die Knoten über ihre Blöcke unterrichten müssen, entsteht leider etwas mehr Overhead als bei gewöhnlichen Hashverfahren.
Ausserdem ist das Generieren der Hashes ziemlich zeitintensiv; ein Datendurchsatz von einigen 100kbits liegt bei guter Implementation aber durchaus drin (im ersten Link sind ausführliche Performance-Tabellen aufgeführt). Solange der Datendurchsatz aber nicht tiefer ist als die Upload-Geschwindigkeit, sollte er auch keinen Flaschenhals darstellen.