Niet iedereen is voldoende vertrouwd met de Engelse taal. Daarom hebben we de Bitcoin Whitepaper voor u naar het Nederlands vertaald. Hoewel er veel technische termen in voorkomen, bestaat de kans dat het nog steeds niet volledig begrijpelijk is. We hopen echter dat deze vertaling het document toegankelijker maakt. Veel leesplezier!
Bitcoin: Een Peer-to-Peer Elektronisch Geldsysteem
Satoshi Nakamoto
satoshin@gmx.com
Samenvatting. Een puur peer-to-peer versie van elektronisch geld zou online betalingen rechtstreeks van de ene partij naar de andere kunnen sturen zonder tussenkomst van een financiële instelling. Digitale handtekeningen bieden een deel van de oplossing, maar de belangrijkste voordelen gaan verloren als er nog steeds een vertrouwde derde partij nodig is om dubbel uitgeven te voorkomen. Wij stellen een oplossing voor het probleem van dubbel uitgeven voor met behulp van een peer-to-peer netwerk. Het netwerk voorziet transacties van een tijdstempel door ze te hashen in een doorlopende keten van op hash gebaseerde proof-of-work, waarmee een register wordt gevormd dat niet kan worden gewijzigd zonder het proof-of-work opnieuw uit te voeren. De langste keten dient niet alleen als bewijs van de reeks waargenomen gebeurtenissen, maar ook als bewijs dat deze afkomstig is van de grootste pool van rekenkracht. Zolang een meerderheid van de rekenkracht wordt beheerd door knooppunten die niet samenwerken om het netwerk aan te vallen, zullen ze de langste keten genereren en aanvallers voorbijstreven. Het netwerk zelf vereist minimale structuur. Berichten worden op basis van best effort uitgezonden, en knooppunten kunnen het netwerk naar believen verlaten en opnieuw aansluiten, waarbij ze de langste proof-of-work keten accepteren als bewijs van wat er gebeurde terwijl ze weg waren.
1. Inleiding
Handel op het internet is bijna uitsluitend afhankelijk geworden van financiële instellingen die fungeren als vertrouwde derde partijen voor het verwerken van elektronische betalingen. Hoewel het systeem goed genoeg werkt voor de meeste transacties, lijdt het nog steeds onder de inherente zwakheden van het op vertrouwen gebaseerde model. Volledig onomkeerbare transacties zijn eigenlijk niet mogelijk, aangezien financiële instellingen geschillen niet kunnen vermijden. De kosten van bemiddeling verhogen de transactiekosten, waardoor de praktische minimumgrootte van transacties beperkt wordt en de mogelijkheid voor kleine, informele transacties wordt uitgesloten, en er zijn bredere kosten in het verlies van het vermogen om onomkeerbare betalingen te doen voor onomkeerbare diensten. Met de mogelijkheid van terugdraaien verspreidt de noodzaak van vertrouwen zich. Handelaren moeten voorzichtig zijn met hun klanten, hen lastigvallen voor meer informatie dan ze anders zouden nodig hebben. Een bepaald percentage fraude wordt als onvermijdelijk geaccepteerd. Deze kosten en betalingsonzekerheden kunnen persoonlijk worden vermeden door fysiek geld te gebruiken, maar er bestaat geen mechanisme om betalingen over een communicatiekanaal te doen zonder een vertrouwde partij.
Wat nodig is, is een elektronisch betalingssysteem gebaseerd op cryptografisch bewijs in plaats van vertrouwen, waarmee twee willekeurige partijen rechtstreeks met elkaar kunnen handelen zonder de noodzaak van een vertrouwde derde partij. Transacties die computationeel onomkeerbaar zijn, zouden verkopers beschermen tegen fraude, en routinematige escrow-mechanismen zouden gemakkelijk kunnen worden geïmplementeerd om kopers te beschermen. In dit document stellen wij een oplossing voor het probleem van dubbel uitgeven voor met behulp van een peer-to-peer gedistribueerde tijdstempelserver om computationeel bewijs te genereren van de chronologische volgorde van transacties. Het systeem is veilig zolang eerlijke knooppunten collectief meer rekenkracht controleren dan welke groep aanvallende knooppunten dan ook.
2. Transacties
We definiëren een elektronische munt als een keten van digitale handtekeningen. Elke eigenaar draagt de munt over aan de volgende door een hash van de vorige transactie en de publieke sleutel van de volgende eigenaar digitaal te ondertekenen en deze aan het einde van de munt toe te voegen. Een begunstigde kan de handtekeningen verifiëren om de eigendomsketen te controleren.
Het probleem is natuurlijk dat de begunstigde niet kan verifiëren of een van de eigenaars de munt niet dubbel heeft uitgegeven. Een gebruikelijke oplossing is het introduceren van een vertrouwde centrale autoriteit, of munt, die elke transactie controleert op dubbel uitgeven. Na elke transactie moet de munt worden teruggestuurd naar de munt om een nieuwe munt uit te geven, en alleen munten die rechtstreeks van de munt worden uitgegeven, worden vertrouwd om niet dubbel uitgegeven te zijn. Het probleem met deze oplossing is dat het lot van het hele geldsysteem afhangt van het bedrijf dat de munt beheert, waarbij elke transactie via hen moet gaan, net als bij een bank.
We hebben een manier nodig voor de begunstigde om te weten dat de vorige eigenaars geen eerdere transacties hebben ondertekend. Voor onze doeleinden is de vroegste transactie degene die telt, dus we geven niets om latere pogingen tot dubbel uitgeven. De enige manier om de afwezigheid van een transactie te bevestigen, is door op de hoogte te zijn van alle transacties. In het muntgebaseerde model was de munt op de hoogte van alle transacties en besliste welke als eerste arriveerde. Om dit te bereiken zonder een vertrouwde partij, moeten transacties openbaar worden aangekondigd [1], en we hebben een systeem nodig waarmee deelnemers overeenstemming kunnen bereiken over een enkele geschiedenis van de volgorde waarin ze zijn ontvangen. De begunstigde heeft bewijs nodig dat op het moment van elke transactie de meerderheid van de knooppunten het erover eens was dat het de eerste ontvangen transactie was.
3. Timestamps Server
De oplossing die we voorstellen begint met een tijdstempelserver. Een tijdstempelserver werkt door een hash van een blok items dat moet worden voorzien van een tijdstempel te nemen en de hash op grote schaal te publiceren, bijvoorbeeld in een krant of Usenet-bericht [2-5]. De tijdstempel bewijst dat de gegevens op dat moment moeten hebben bestaan, aangezien ze in de hash zijn opgenomen. Elke tijdstempel bevat de vorige tijdstempel in zijn hash, waardoor een keten ontstaat, waarbij elke extra tijdstempel de voorgaande versterkt.
4. Proof-of-Work
Om een gedistribueerde tijdstempelserver op een peer-to-peer basis te implementeren, zullen we een proof-of-work systeem moeten gebruiken dat lijkt op Adam Back’s Hashcash [6], in plaats van kranten of Usenet-berichten. Het proof-of-work omvat het scannen naar een waarde die, wanneer gehasht, zoals met SHA-256, de hash begint met een aantal nullen. Het gemiddelde werk dat nodig is, is exponentieel in het aantal vereiste nullen en kan worden geverifieerd door een enkele hash uit te voeren.
Voor ons tijdstempelnetwerk implementeren we het proof-of-work door een nonce in het blok te verhogen totdat een waarde wordt gevonden die de hash van het blok de vereiste nullen geeft. Zodra de CPU-inspanning is geleverd om te voldoen aan het proof-of-work, kan het blok niet worden gewijzigd zonder het werk opnieuw te doen. Aangezien latere blokken erna worden geketend, zou het werk om het blok te wijzigen het opnieuw uitvoeren van alle blokken na het betreffende blok inhouden.
Het proof-of-work lost ook het probleem op van het bepalen van representatie in meerderheidsbesluitvorming. Als de meerderheid gebaseerd was op één-IP-adres-één-stem, zou dit kunnen worden ondermijnd door iedereen die in staat is om veel IP’s toe te wijzen. Proof-of-work is in wezen één-CPU-één-stem. Het meerderheidsbesluit wordt vertegenwoordigd door de langste keten, waarin de meeste proof-of-work is geïnvesteerd. Als een meerderheid van de rekenkracht wordt beheerd door eerlijke knooppunten, zal de eerlijke keten het snelst groeien en elke concurrerende keten inhalen. Om een vorig blok te wijzigen, zou een aanvaller het proof-of-work van het blok en alle blokken erna opnieuw moeten doen en vervolgens moeten inhalen en het werk van de eerlijke knooppunten overtreffen. We zullen later aantonen dat de kans dat een langzamere aanvaller inhaalt, exponentieel afneemt naarmate er meer blokken aan de keten worden toegevoegd.
Om te compenseren voor toenemende hardwaresnelheid en variërende interesse in het uitvoeren van knooppunten in de loop van de tijd, wordt de proof-of-work moeilijkheid bepaald door een voortschrijdend gemiddelde dat is gericht op een gemiddeld aantal blokken per uur. Als ze te snel worden gegenereerd, neemt de moeilijkheidsgraad toe.
5. Netwerk
De stappen om het netwerk te laten werken zijn als volgt:
- Nieuwe transacties worden naar alle knooppunten uitgezonden.
- Elk knooppunt verzamelt nieuwe transacties in een blok.
- Elk knooppunt werkt aan het vinden van een moeilijk proof-of-work voor zijn blok.
- Wanneer een knooppunt een proof-of-work vindt, wordt het blok naar alle knooppunten uitgezonden.
- Knooppunten accepteren het blok alleen als alle transacties erin geldig zijn en niet al zijn uitgegeven.
- Knooppunten tonen hun acceptatie van het blok door te werken aan het volgende blok in de keten, met behulp van de hash van het geaccepteerde blok als vorige hash.
Knooppunten beschouwen altijd de langste keten als de juiste en zullen doorgaan met het verlengen ervan. Als twee knooppunten tegelijkertijd verschillende versies van het blok uitzenden, kunnen sommige knooppunten de ene of de andere eerst ontvangen. In dat geval werken ze aan degene die ze het eerst hebben ontvangen, maar bewaren ze de andere tak voor het geval deze langer wordt. De patstelling wordt doorbroken wanneer de volgende proof-of-work wordt gevonden en een van de takken langer wordt; de knooppunten die aan de andere tak werkten, schakelen dan over naar de langere tak.
Nieuwe transactieberichten hoeven niet noodzakelijkerwijs alle knooppunten te bereiken. Zolang ze veel knooppunten bereiken, zullen ze binnen afzienbare tijd in een blok terechtkomen. Blokuitzendingen zijn ook tolerant voor verloren berichten. Als een knooppunt een blok niet ontvangt, zal het dit opvragen wanneer het het volgende blok ontvangt en zich realiseert dat het er een heeft gemist.
6. Incentive (Stimulans)
Volgens conventie is de eerste transactie in een blok een speciale transactie die een nieuwe munt start die eigendom is van de maker van het blok. Dit voegt een stimulans toe voor knooppunten om het netwerk te ondersteunen, en biedt een manier om aanvankelijk munten in omloop te brengen, aangezien er geen centrale autoriteit is om ze uit te geven. De voortdurende toevoeging van een constante hoeveelheid nieuwe munten is vergelijkbaar met goudzoekers die middelen inzetten om goud in omloop te brengen. In ons geval wordt er CPU-tijd en elektriciteit verbruikt.
De stimulans kan ook worden gefinancierd met transactiekosten. Als de uitvoerwaarde van een transactie lager is dan de invoerwaarde, is het verschil een transactiekost die wordt toegevoegd aan de stimulanswaarde van het blok dat de transactie bevat. Zodra een vooraf bepaald aantal munten in omloop is gebracht, kan de stimulans volledig overgaan op transactiekosten en volledig inflatievrij zijn.
De stimulans kan helpen om knooppunten eerlijk te houden. Als een hebzuchtige aanvaller in staat is om meer rekenkracht te verzamelen dan alle eerlijke knooppunten samen, zou hij moeten kiezen tussen het bedriegen van mensen door zijn betalingen terug te stelen, of het genereren van nieuwe munten. Hij zou het waarschijnlijk winstgevender vinden om zich aan de regels te houden, regels die hem begunstigen met meer nieuwe munten dan de rest bij elkaar, dan om het systeem te ondermijnen en de geldigheid van zijn eigen rijkdom te vernietigen.
7. Opslagruimte terugwinnen
Zodra de laatste transactie in een munt is begraven onder voldoende blokken, kunnen de eerder uitgegeven transacties worden verwijderd om opslagruimte te besparen. Om dit te vergemakkelijken zonder de hash van het blok te breken, worden transacties gehasht in een Merkle-boom [7][2][5], waarbij alleen de wortel in de hash van het blok wordt opgenomen. Oude blokken kunnen vervolgens worden gecomprimeerd door takken van de boom af te snijden. De interne hashes hoeven niet te worden opgeslagen.
Een blokheader zonder transacties zou ongeveer 80 bytes groot zijn. Als we aannemen dat er elke 10 minuten blokken worden gegenereerd, betekent dat 80 bytes * 6 * 24 * 365 = 4,2 MB per jaar. Met computersystemen die typisch worden verkocht met 2 GB RAM in 2008, en Moore’s Wet die een jaarlijkse groei van 1,2 GB voorspelt, zou opslag geen probleem moeten zijn, zelfs als de blokheaders in het geheugen moeten worden bewaard.
8. Vereenvoudigde betalingsverificatie
Het is mogelijk om betalingen te verifiëren zonder een volledig netwerk-knooppunt uit te voeren. Een gebruiker hoeft alleen een kopie van de blokheaders van de langste proof-of-work keten te bewaren, die hij kan verkrijgen door netwerk-knooppunten te raadplegen totdat hij overtuigd is dat hij de langste keten heeft, en de Merkle-tak op te halen die de transactie koppelt aan het blok waarin deze is voorzien van een tijdstempel. Hij kan de transactie niet zelf controleren, maar door deze te koppelen aan een plaats in de keten, kan hij zien dat een netwerk-knooppunt deze heeft geaccepteerd, en blokken die erna zijn toegevoegd, bevestigen verder dat het netwerk deze heeft geaccepteerd.
Zodoende is de verificatie betrouwbaar zolang eerlijke knooppunten het netwerk controleren, maar het is kwetsbaarder als het netwerk wordt overmeesterd door een aanvaller. Hoewel netwerk-knooppunten transacties voor zichzelf kunnen verifiëren, kan de vereenvoudigde methode worden misleid door de gefabriceerde transacties van een aanvaller zolang de aanvaller het netwerk kan blijven overmeesteren. Een strategie om dit te beschermen, zou zijn om waarschuwingen van netwerk-knooppunten te accepteren wanneer zij een ongeldig blok detecteren, waardoor de software van de gebruiker wordt aangespoord om het volledige blok en de gemelde transacties te downloaden om de inconsistentie te bevestigen. Bedrijven die regelmatig betalingen ontvangen, willen waarschijnlijk nog steeds hun eigen knooppunten draaien voor meer onafhankelijke beveiliging en snellere verificatie.
9. Waarde combineren en splitsen
Hoewel het mogelijk zou zijn om munten afzonderlijk te behandelen, zou het onpraktisch zijn om voor elke cent in een overdracht een aparte transactie te maken. Om waarde te kunnen splitsen en combineren, bevatten transacties meerdere invoer- en uitvoerwaarden. Normaal gesproken zal er ofwel een enkele invoer zijn van een grotere eerdere transactie of meerdere invoeren die kleinere bedragen combineren, en maximaal twee uitgangen: één voor de betaling en één om eventuele wisselgeld terug te geven aan de afzender.
Het moet worden opgemerkt dat “fan-out”, waarbij een transactie afhankelijk is van meerdere transacties, en die transacties afhankelijk zijn van nog veel meer transacties, hier geen probleem vormt. Er is nooit de noodzaak om een complete zelfstandige kopie van de transactiegeschiedenis van een transactie te extraheren.
10. Privacy
Het traditionele bankmodel bereikt een bepaald niveau van privacy door de toegang tot informatie te beperken tot de betrokken partijen en de vertrouwde derde partij. De noodzaak om alle transacties openbaar aan te kondigen, sluit deze methode uit, maar privacy kan nog steeds worden gehandhaafd door de informatiestroom op een andere plaats te onderbreken: door openbare sleutels anoniem te houden. Het publiek kan zien dat iemand een bedrag naar iemand anders stuurt, maar zonder informatie die de transactie aan iemand koppelt. Dit is vergelijkbaar met het niveau van informatie dat door beurzen wordt vrijgegeven, waar de tijd en omvang van individuele transacties, de “tape”, openbaar worden gemaakt, maar zonder te vermelden wie de partijen waren.
Als een extra beschermingsmaatregel moet voor elke transactie een nieuw sleutelpair worden gebruikt om te voorkomen dat ze aan een gemeenschappelijke eigenaar worden gekoppeld. Enige koppeling is nog steeds onvermijdelijk bij transacties met meerdere ingangen, die noodzakelijkerwijs onthullen dat hun ingangen door dezelfde eigenaar werden beheerd. Het risico is dat, als de eigenaar van een sleutel wordt onthuld, koppeling andere transacties kan onthullen die tot dezelfde eigenaar behoorden.
11. Berekeningen
We overwegen het scenario van een aanvaller die probeert een alternatieve keten sneller te genereren dan de eerlijke keten. Zelfs als dit lukt, staat het systeem niet open voor willekeurige wijzigingen, zoals waarde uit het niets creëren of geld nemen dat nooit van de aanvaller was. Knooppunten zullen een ongeldige transactie niet als betaling accepteren, en eerlijke knooppunten zullen nooit een blok accepteren dat ze bevat. Een aanvaller kan alleen proberen een van zijn eigen transacties te wijzigen om geld terug te nemen dat hij onlangs heeft uitgegeven.
De race tussen de eerlijke keten en de aanvallerketen kan worden gekarakteriseerd als een binomiale willekeurige wandeling. Het succesvolle evenement is dat de eerlijke keten met één blok wordt verlengd, waardoor de voorsprong met +1 toeneemt, en het mislukte evenement is dat de keten van de aanvaller met één blok wordt verlengd, waardoor de kloof met -1 afneemt.
De waarschijnlijkheid dat een aanvaller inhaalt vanuit een bepaald tekort is vergelijkbaar met een Gambler’s Ruin-probleem. Stel dat een gokker met onbeperkt krediet begint met een tekort en een mogelijk oneindig aantal proeven uitvoert om te proberen quitte te spelen. We kunnen de kans berekenen dat hij ooit quitte speelt, of dat een aanvaller ooit inhaalt met de eerlijke keten, als volgt [8]:
p = waarschijnlijkheid dat een eerlijk knooppunt het volgende blok vindt
q = waarschijnlijkheid dat de aanvaller het volgende blok vindt
qz = waarschijnlijkheid dat de aanvaller ooit inhaalt vanuit z blokken achterstand
qz = {1 als p ≤ q
(q / p)z als p > q}
Aangezien we aannemen dat p > q, neemt de waarschijnlijkheid exponentieel af naarmate het aantal blokken dat de aanvaller moet inhalen toeneemt. Met de kansen tegen hem, als hij niet vroeg een gelukkige sprong vooruit maakt, worden zijn kansen vrijwel nihil naarmate hij verder achterop raakt.
We overwegen nu hoe lang de ontvanger van een nieuwe transactie moet wachten voordat hij voldoende zeker is dat de afzender de transactie niet kan wijzigen. We gaan ervan uit dat de afzender een aanvaller is die de ontvanger wil laten geloven dat hij hem heeft betaald, om de transactie vervolgens na enige tijd terug te draaien naar zichzelf. De ontvanger zal worden gewaarschuwd wanneer dat gebeurt, maar de afzender hoopt dat het dan te laat zal zijn.
De ontvanger genereert een nieuw sleutelpair en geeft de publieke sleutel aan de afzender kort voor de ondertekening. Dit voorkomt dat de afzender vooraf een keten van blokken voorbereidt door er continu aan te werken totdat hij genoeg geluk heeft om ver genoeg vooruit te komen, en dan op dat moment de transactie uitvoert. Zodra de transactie is verzonden, begint de oneerlijke afzender in het geheim te werken aan een parallelle keten die een alternatieve versie van zijn transactie bevat.
De ontvanger wacht totdat de transactie is toegevoegd aan een blok en z blokken erna zijn gekoppeld. Hij weet niet precies hoeveel voortgang de aanvaller heeft geboekt, maar ervan uitgaande dat de eerlijke blokken de gemiddelde verwachte tijd per blok hebben genomen, zal de potentiële voortgang van de aanvaller een Poisson-verdeling zijn met verwachte waarde:
λ = z * (q / p)
Om de kans te berekenen dat de aanvaller nu nog kan inhalen, vermenigvuldigen we de Poisson-dichtheid voor elke hoeveelheid voortgang die hij zou kunnen hebben gemaakt met de kans dat hij vanaf dat punt nog kan inhalen:
∑ (k = 0 tot ∞) λ^k * e^(-λ) / k! * (q / p)^(z – k) als k ≤ z
1 als k > z
Herschikken om de oneindige staart van de verdeling te vermijden…
1 – ∑ (k = 0 tot z) λ^k * e^(-λ) / k! * (1 – (q / p)^(z – k))
Omgezet naar C code:
cCode kopiëren#include <math.h>
double AttackerSuccessProbability(double q, int z)
{
double p = 1.0 - q;
double lambda = z * (q / p);
double sum = 1.0;
int i, k;
for (k = 0; k <= z; k++)
{
double poisson = exp(-lambda);
for (i = 1; i <= k; i++)
poisson *= lambda / i;
sum -= poisson * (1 - pow(q / p, z - k));
}
return sum;
}
Als we enkele resultaten uitvoeren, zien we de waarschijnlijkheid exponentieel afnemen met z.
q = 0,1
z = 0 P = 1,0000000
z = 1 P = 0,2045873
z = 2 P = 0,0509779
z = 3 P = 0,0131722
z = 4 P = 0,0034552
z = 5 P = 0,0009137
z = 6 P = 0,0002428
z = 7 P = 0,0000647
z = 8 P = 0,0000173
z = 9 P = 0,0000046
z = 10 P = 0,0000012
q = 0,3
z = 0 P = 1,0000000
z = 5 P = 0,1773523
z = 10 P = 0,0416605
z = 15 P = 0,0101008
z = 20 P = 0,0024804
z = 25 P = 0,0006132
z = 30 P = 0,0001522
z = 35 P = 0,0000379
z = 40 P = 0,0000095
z = 45 P = 0,0000024
z = 50 P = 0,0000006
Oplossing voor P kleiner dan 0,1%…
P < 0,001
q = 0,10 z = 5
q = 0,15 z = 8
q = 0,20 z = 11
q = 0,25 z = 15
q = 0,30 z = 24
q = 0,35 z = 41
q = 0,40 z = 89
q = 0,45 z = 340
12. Conclusie
We hebben een systeem voorgesteld voor elektronische transacties zonder afhankelijk te zijn van vertrouwen. We begonnen met het gebruikelijke kader van munten gemaakt van digitale handtekeningen, wat sterke controle over eigendom biedt, maar onvolledig is zonder een manier om dubbel uitgeven te voorkomen. Om dit op te lossen, hebben we een peer-to-peer netwerk voorgesteld dat proof-of-work gebruikt om een openbaar geschiedenisregister van transacties vast te leggen dat snel computationeel onpraktisch wordt voor een aanvaller om te veranderen, zolang eerlijke knooppunten de meerderheid van de rekenkracht controleren. Het netwerk is robuust in zijn ongestructureerde eenvoud. Knooppunten werken allemaal tegelijk met weinig coördinatie. Ze hoeven niet geïdentificeerd te worden, aangezien berichten niet naar een specifieke locatie worden gerouteerd en alleen op basis van best effort hoeven te worden afgeleverd. Knooppunten kunnen het netwerk naar believen verlaten en opnieuw aansluiten, waarbij ze de proof-of-work keten accepteren als bewijs van wat er is gebeurd terwijl ze weg waren. Ze stemmen met hun rekenkracht door hun acceptatie van geldige blokken te tonen door eraan verder te werken en door het werk aan te weigeren bij ongeldige blokken. Alle benodigde regels en prikkels kunnen met dit consensusmechanisme worden afgedwongen.
Referenties
- W. Dai, “b-money,” http://www.weidai.com/bmoney.txt, 1998.
- H. Massias, X.S. Avila, en J.-J. Quisquater, “Design of a secure timestamping service with minimal trust requirements,” In 20th Symposium on Information Theory in the Benelux, mei 1999.
- S. Haber, W.S. Stornetta, “How to time-stamp a digital document,” In Journal of Cryptology, vol 3, nr. 2, pagina’s 99-111, 1991.
- D. Bayer, S. Haber, W.S. Stornetta, “Improving the efficiency and reliability of digital time-stamping,” In Sequences II: Methods in Communication, Security and Computer Science, pagina’s 329-334, 1993.
- S. Haber, W.S. Stornetta, “Secure names for bit-strings,” In Proceedings of the 4th ACM Conference on Computer and Communications Security, pagina’s 28-35, april 1997.
- A. Back, “Hashcash – a denial of service counter-measure,” http://www.hashcash.org/papers/hashcash.pdf, 2002.
- R.C. Merkle, “Protocols for public key cryptosystems,” In Proc. 1980 Symposium on Security and Privacy, IEEE Computer Society, pagina’s 122-133, april 1980.
- W. Feller, “An introduction to probability theory and its applications,” 1957.
Weergaven: 2