From fa409f746a0f52668415cd13b6b867657c635c20 Mon Sep 17 00:00:00 2001 From: Baptiste Lemoine <contact@cipherbliss.com> Date: Tue, 5 May 2020 17:53:34 +0200 Subject: [PATCH] [feat] fix table of content --- Makefile | 12 + README.md | 7 + build/whitepaper_en.epub | Bin 0 -> 195430 bytes build/whitepaper_en.fb2 | 739 ++++++++++++++++++++++ build/whitepaper_en.html | 1012 +++++++++---------------------- build/whitepaper_en.md | 855 ++++++++++++++------------ build/whitepaper_en.mobi | Bin 0 -> 58760 bytes build/whitepaper_fr.epub | Bin 0 -> 54578 bytes build/whitepaper_fr.fb2 | 742 +++++++++++++++++++++++ build/whitepaper_fr.html | 1011 +++++++++---------------------- build/whitepaper_fr.md | 851 ++++++++++++++------------ build/whitepaper_fr.mobi | Bin 0 -> 58742 bytes chapters/en/1_intro.md.txt | 4 +- publication.sh | 44 +- src/head.html | 53 +- src/js/jquery.js | 5 - src/js/toc.js | 65 -- src/main.css | 42 +- whitepaper.html | 434 ------------- whitepaper.md | 1178 ------------------------------------ 20 files changed, 3074 insertions(+), 3980 deletions(-) create mode 100644 Makefile create mode 100644 build/whitepaper_en.epub create mode 100644 build/whitepaper_en.fb2 create mode 100644 build/whitepaper_en.mobi create mode 100644 build/whitepaper_fr.epub create mode 100644 build/whitepaper_fr.fb2 create mode 100644 build/whitepaper_fr.mobi delete mode 100644 src/js/jquery.js delete mode 100644 src/js/toc.js delete mode 100644 whitepaper.html delete mode 100644 whitepaper.md diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f81c4d1 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +default: convert +convert: + bash publication.sh +clean: +git: + # git add files + #git add whitepaper.md whitepaper.html + #git add chapters/1_intro.md.txt chapters/2_looking_at_Bitcoin.md.txt chapters/3_blockchain.md.txt chapters/4_Web_Of_Trust.md.txt chapters/5_individualized_difficulty.md.txt chapters/6_conclusion.md.txt chapters/9_sources.md.txt + #git add publication.sh + + #we want to add the .pdf only for publication + # git add whitepaper.pdf diff --git a/README.md b/README.md index d412047..0fe884e 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,13 @@ Rédaction d'un Whitepaper pour le projet Duniter. Je ne suis pas compétent pour entrer dans les détails du projet. Cependant, je le suis assez pour rédiger la majeure partie du texte explicatif. J'invite qui le souhaite à m'accompagner dans cette rédaction. +## Installation et compilation sur système Debian +Pour compiler les sources markdown vers les versions html, ebook et pdf vous allez avoir besoin de ces dépendances: +```bash +sudo apt install texlive-latex-base pandoc texlive-fonts-recommended calibre +make +``` + ## TODO * grouper les assets dans ce dépot dans src/img et non les mettre en hotlink. * Table Of Content sur la version HTML. diff --git a/build/whitepaper_en.epub b/build/whitepaper_en.epub new file mode 100644 index 0000000000000000000000000000000000000000..eda7e1b9a2db2be6bb5498c09dfc2c0cb538171c GIT binary patch literal 195430 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	UH@e8Xr!mq(B`bE1GDG(TnQGyqvgI3} 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 literal 0 HcmV?d00001 diff --git a/build/whitepaper_en.fb2 b/build/whitepaper_en.fb2 new file mode 100644 index 0000000..feb6aa8 --- /dev/null +++ b/build/whitepaper_en.fb2 @@ -0,0 +1,739 @@ +<?xml version="1.0" encoding="UTF-8"?> +<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:xlink="http://www.w3.org/1999/xlink"> + <description> + <title-info> + <genre>antique</genre> + <author><first-name></first-name><last-name>Inconnu(e)</last-name></author> + <book-title>whitepaper en</book-title> + + <lang>fr</lang> + + + + </title-info> + <document-info> + <author><first-name></first-name><last-name>Inconnu(e)</last-name></author> + <program-used>calibre 3.46.0</program-used> + <date>5.5.2020</date> + <id>5e6bf4d6-ac49-48cd-9e7e-afc96068fd4a</id> + <version>1.0</version> + </document-info> + <publish-info> + + + + </publish-info> + </description> +<body> +<section> +<empty-line /><p>Duniter: A libre currency blockchain generator.</p> + +<p>Abstract</p> + +<p>Many currency principles involve non-equal rights to monetary creation between humans. We propose a monetary creation based on the Relative Theory of Money, which guarantee equal monetary creation for each willing human. This type of currency can be centralised, however, this could lead to censorship and arbitrary choices of the central institution. Thus, strongly inspired by Bitcoin example, we want the currency to be as decentralised as possible, in the transaction network as in the human identification process. We use a Web of Trust between living humans for identification. This web of trust allows us to impose personalised difficulty for transaction validation, keeping the calculation accessible to low-end hardware and allowing all competent members to secure the currency.</p> + +<p>Introduction</p> + +<p>Duniter is a software to create and manage “libre currencies”. Libre currency is a concept defined by S.Laborde in the Relative Theory of Money (RTM) that was published in 2010. This theory demonstrates the possibility of an invariant monetary unit : the Universal Dividend. Doing so, the RTM answers the question :</p> + +<p>How should a currency be created to match the principle of equality between all humans, now and between generations ?</p> + +<p>The results of this demonstration implies a monetary creation :</p> + +<p>on a regular basis</p> + +<p>for each human being</p> + +<p>which amount has to be reassessed on fixed intervals according to a fixed formula.</p> + +<p>Thus, Duniter project will associate a human to a digital identity. It will use a Web of Trust with specific rules. As the number of members may evolve, the Universal Dividend has to be created according to the formula :</p><empty-line /><p>$$ UD(t+1) = UD(t) + c²*( {M(t) \over N(t) }) $$</p><empty-line /><p>Duniter is based on a decentralized Blockchain. This technical choice allows irreversibility of transaction and uncensorability of trades and identities. While inspired by Bitcoin, Duniter uses a Web of Trust and the Proof of Work to secure the computation network, thus making obsolete the power race model used in Bitcoin.</p> + +<p>The first currency created through Duniter is Ğ1, pronounced “June”. It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software.</p> + +<p>1. State of the art : Bitcoin case</p> + +<p>Duniter uses the crypto-currency concept introduced by Bitcoin<sup>1</sup>, which is to use cryptographic tools such as signatures to create trustless digital currencies. Duniter fits this definition, but it has two completely different principles than Bitcoin : the Web of Trust and the Universal Dividend . These differences are on both monetary and technical aspects.</p> + +<p>1.1. Monetary creation of Bitcoin : a space-time asymmetry</p> + +<p>Space-time asymmetry refers to the relative access of individuals to newly created money<sup>2</sup>. Concretely, most existing currencies (c. 2020) are both spatially and temporally asymmetrical for their users. Let's take Bitcoin as an example to understand why.</p> + +<p>1.1.1. Spatial asymmetry</p> + +<p>When new Bitcoins are created, only some Bitcoin users (the miners) are given new Bitcoins, while everyone else get nothing. We believe this is the first injustice. However, some might say:</p> + +<p>"Miners used their electricity and time to get it!"</p> + +<p>... we would answer that this work should not have been rewarded by newly created Bitcoins. New units should be distributed to the whole community. Miners should be rewared another way, but not by money issuance. Of course, Bitcoin cannot create money through Basic Income since Bitcoin users are not strongly identified, and one might benefit from money creation multiple times if they owned several wallets. Duniter gets rid of this problem by identifying its users and creating the same amount of Basic Income to everyone.</p> + +<p>1.1.2. Temporal-asymmetry</p> + +<p>Bitcoin has an absolute limit of 21 million BTC (its unit of currency), which means ever fewer bitcoins will be created over time until no new BTC are being generated. So, once the first adopters have mined every bitcoin, how will future joiners get Bitcoins? Just like most of us do for Euros or Dollars: to get money, they will have to work for the ones who already own it.</p> + +<p>We believe this is the second injustice. Every member of a monetary community should be equal concerning monetary creation, and get the same relative amount of money over time, even if they are a late adopter. Duniter aims to fix this by making the Universal Dividend (a.k.a. UD) grow by the time according to precise rules, thus making members equal toward money issuance on a half-lifespan.</p> + +<p>Most currencies present one of these two asymmetries, including metal currencies and mutual credit, as exposed in the RTM.</p> + +<p>1.1.3. A solution</p> + +<p>Bitcoin has taught us that it is possible to create a currency system allowing one to both create digital money and to exchange it without a central authority. What we need to change is the way money is issued so we finally have a symmetrical system. We need Bitcoin + Universal Dividend. But Universal Dividend implies that the community consists of only identified people. This is where the Web of Trust (WoT) comes into place.</p> + +<p>This concept, introduced by cryptography with the OpenPGP format<sup>3</sup>, allows us to identify people in a decentralized manner. It works as follows: each person creates a personal identity that is linked to its cyptographic certificate. The identity must be confirmed by others members who use their own cryptographic key. It is that simple: people choose who is part of the community and who is not, not a central authority.</p> + +<p>However, Duniter will not use OpenPGP for its cryptographic features: Elliptic Curves<sup>4</sup> will be used instead for the conciseness of its generated keys and its pratical advantages. Duniter has its own Web of Trust principles, that will be exposed later.</p> + +<p>1.2. Proof-of-Work mining : a power race</p> + +<p>In Bitcoin Model, the calculation and incentive principles cause a power race : new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. This leads to a power race an places the control over the currency in the hands of the richest hardware owners. We want to make Duniter blockchain validation much less energy and hardware consuming while keeping a strong level of security. This will be further explained later. A consequence of this choice is the participation of low-end hardware in the Duniter network, leading to a better decentralization of blockchain validation.</p> + +<p>1.2.1 What about Proof of Stake ?</p> + +<p>Proof of stake consensus algorythm was first introduced in 2012<sup>5</sup>. The basic principle is to allow the richest wallets to issue blocks, putting their coin balance as a “stake” they would lose in case of cheat.</p> + +<p>At the time of conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. We did not chose this consensus principle. Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead to placing power over the currency in the richests hands : this is contrary to the symmetical principles of a libre currency.</p> + +<p>2. Duniters Blockchain</p> + +<p>Duniters Blockchain follows the basic principles of Bitcoins. This is essential for synchronization between peers, as to prevent double-spend attacks. However, Duniters Blockchain will store different informations than Bitcoins.</p> + +<p>The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no generation transaction exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either:</p> + +<p>a former transaction (as in Bitcoin)</p> + +<p>a Universal Dividend (specific to Duniter).</p> + +<p>Duniters Web of Trust is also written in the Blockchain. The identity of each member gets registered much like transactions are, with a strong link to the time reference. Thus, the Blockchain is a representation of a space-time frame of reference, where “space” are members of the WoT and “time” the basic blockchain units : the blocks. On each point of time, one can determine which account is legitimate to create the UD, only with a blockchain analysis.</p> + +<p>2.1. Spam countermeasures</p> + +<p>An issue of most cryptocurrency projects is to prevent the common ledger from growing too much. This would require nodes to have a lot of storage and computing power to be usable. In particular, we don’t want an attacker to be able to make the Blockchain grow too fast. Most projects implement transaction fees as a way to prevent this, making the attacker lose money. We don’t want to introduce this mean since a currency with automatic fees on transactions is no more neutral. Several countermeasuers against such spam attacks are implemented.</p> + +<p>2.1.1. Minimum output amount</p> + +<p>Fixing a minimal output amount reduces the power of an attack. Duniter deals with cents of Ğ1 or 1/1000 of the first UD. An attacker could create thousand accounts with only 1 UD. To prevent this, a valid transaction must have output amounts of minimum 1Ğ1. This reduces the power an attack by 100.</p> + +<p>2.1.2. Limited block size and chainability</p> + +<p>The block size is always limited. While the protocol allows this limit to evolve to address scaling issues, an attacker cannot register as many transaction as they wish.</p> + +<p>With the same goal to prevent too many transactions to get registered, while transactions can be “chained” (refer to another transaction in the same block), the chainability of transactions is limited to 5.</p> + +<p>2.2. Scaling</p> + +<p>Most of the time, the scaling issue rises for distributed systems that should work on a very large scale. This is not the case of Duniter, for multiple reasons :</p> + +<p>Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don’t want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT should limit its size to around 16 million members.</p> + +<p>Duniter’s aim is to be used to create multiple libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community.</p> + +<p>However, Duniter has assets that will help if the number of users and transactions grow.</p> + +<p>2.2.1 Dynamic block size</p> + +<p>While Bitcoin has a fixed block size, Duniters blocks size can evolve. On low use of the blockchain, the maximal block size is 500 bytes. On high use of the blockchain, the maximal block size would be 110% of the average size of the current window blocks(see “personalised difficulty” part for more information). This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it. The block size (in bytes) is limited as so :</p> + +<p>block_size < max(500 ; CEIL(1.10 * (average block size))</p> + +<p>2.2.2. Lightning Networks</p> + +<p>The Lightning Networks<sup>6</sup> allow almost instant and off-chain transactions. They were first implemented on Lightcoin, and are now on Bitcoin. One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. While not available yet, this payment channel might get implemented when needed.</p> + +<p>2.2.3. Unit base</p> + +<p>As the Universal Dividend grows exponentially, with time Duniter nodes would have had to deal with always largest amounts, eventually reaching the BIGINT limit. To avoid this, the amounts are expressed with a unit base in base 10. We want the UD amount to always fit in 4 digits. To manage it, the unitbase is updated each time the UD value reaches 100.00 : it goes from 99.99*10^(unitbase) to 10.00*10^(unitbase+1). All the unit amounts are thus divided by 10. While this might seem strange, this process has already hapened in state currencies. Moreover, the amounts expressed in UD will not change.</p> + +<p>With a monetary growth of 10% each year and a stable population, such a change of unit base would happen each 25 years.</p> + +<p>3. Duniter Web of Trust</p> + +<p>3.1. Basic Principles</p> + +<p>In order to identify “members” accounts - which create monetary units - and other accounts, Duniter uses a Web of Trust. This can be summarized into few principles:</p> + +<p>Each account becomes a member if it received a minimal number of certifications - 5 for Ğ1 currency.</p> + +<p>Only members accounts can send certifications. Certifications have a limited lifespan.</p> + +<p>A certification indicates that the sender accepts the receiver as a legitimate identity.</p> + +<p>The aim of the WoT is to identify a blockchain account to a living human. According to Lauterbach et.al<sup>7</sup>, the strengh of a relationship should be considered when building a vouch system. For this reason, the Ğ1 Web of Trust rules are expressed in a licence stating what WoT certifications are. A certification represents a strong human relationship : one may certify a close relative, not an acquaintance. Each member has to accept this licence before being included in the WoT. Thus, if a member is part of an attack on the currency, they can be found by mutual relatives. Additional security rules occur to prevent cheat and attacks on a large scale.</p> + +<p>Note that non-members accounts can use the currency, but cannot create money. Non-members accounts can be used by individuals as secondary wallets, or by institutions.</p> + +<p>We were inspired by the OpenPGP Trust system<sup>8</sup>. However, the OpenPGP trust principles aim at defining trust from a particular point of view while Duniter needs to identify humans for the whole community. To achieve this goal, while OpenPGP allows each user to tweak its trust parameters individually, Duniter sets rules in the “genesis” block for the whole community.</p> + +<p>3.2. Why do we need a Web of Trust ?</p> + +<p>There are two reasons we need it :</p> + +<p>To make sure that only one Universal Dividend is produced per member at each specified creation interval. In the Ğ1’s case this interval is set as daily 86 400 seconds, it is the <emphasis>monetary parameter</emphasis> known as dt.</p> + +<p>To identify the nodes hashing the blocks and assign each a personalised difficulty. This custom difficulty proof of work is there to avoid the blockchain’s validation mechanism becoming too centralised as is the case with many 'non-libre’ cryptocurrencies.</p><empty-line /><p>Monetary parameter : Each currency that use Duniter has its own blockchain whose behaviour is dictated by a set of ‘parameters’ defined in block zero - the so-called genesis block - that can be tweaked to achieve the desired results. At the time of writing the Whitepaper, the Duniter Blockchain Protocol (DUBP) has a total of 21 parameters of which 10 are for the WoT alone. We’ll focus on these 10.</p> + +<p>Suffice to say that in the Ğ1’s case, the DU is created every 24 hours - 86 400 seconds. This interval is set through the time derivative dt parameter and can have a different value in other implementations of the protocol.</p> + +<p>We want to make sure that each member can only have one account. As we all know, achieving zero-risk isn’t possible<sup>9</sup>. Our goal is therefore not to create a WoT within which fraud would be absolutely impossible, but instead to discourage it. Here is a rewording of our goal in 4 smaller ones :</p> + +<p>Make the certification process lengthy enough that all members exercise due diligence and are wary of risks.</p> + +<p>Make fraudulent acts as hard as we can to the extent that they become pointless.</p> + +<p>Ensure that any Sybil attacks have a negligible impact on the currency by ensuring that illegitimate double Universal Dividends have no significant bearing on the legitimate monetary mass</p> + +<p>Slow the growth of ‘Sybil regions’ to give enough time for the community to react and isolate the threat.</p><empty-line /><p>Sybil attack : A Sybil attack is an attack perpetrated on a reputation system through the creation of fake identities. A Web of Trust is a specific instance of a Reputation System.</p> + +<p>There are plenty of Sybil attack scenarios we can think of and just as many reasons why their perpetrators would want to carry them out. Our objective is that the configuration of the WoT protects both users and its IT backbone infrastructure against these attacks.</p> + +<p>This means that micro-attacks performed by small groups of individuals looking for personal enrichment are of no interest to us. The web’s role isn’t to deter these attacks, this being instead the role of the community. Just like the town you live in is responsible for providing your tap water and electricity but isn’t responsible for any burglaries, etc. Much in the same way, Duniter’s WoT guarantees us all a functional currency, but do not detect small fraud.</p> + +<p>3.3. The importance of having our own certification system</p> + +<p>Centralized identification systems can achieve the goal we want. State Identification is an example. However, this has many drawbacks :</p> + +<p>The authority may have arbitrary criteria for identification, for example preventing people without an official state-provided identity or homeless people to be included in the WoT.</p> + +<p>Payment might be required to get identified, thus making the monetary creation not “free”.</p> + +<p>The authority is a point of failure for any attacker.</p> + +<p>It is of the utmost importance that we remain free from any state or corporation. The WoT is an answer to this criterium. To this day we depend only on the Internet and yet, were it to fail, there are already alternatives being tested around the world for a decentralised communication network.</p> + +<p>3.4. A few foundational concepts on graph theory : a bit of vocabulary</p><empty-line /><p>Graph: set of points -called ‘vertices’- joined by edges -called paths/walks-.</p> + +<p>Simple graph: a graph with no loops and with no multiple edges. That is, each edge connects two distinct endpoints and no two edges have the same endpoints. A simple edge is an edge that is not part of a multiple adjacency -of edges-. In many cases, graphs are assumed to be simple unless specified otherwise.</p> + +<p>Directed graph: a graph in which the edges have a distinguished direction, from one vertex to another. A directed edge can also be called a path or walk. Arrow A –> B is therefore different from arrow B –> A.</p> + +<p>Endpoints: the edge with vertex A –> B has A and B as endpoints, respectively as start and end of the path/walk.</p> + +<p>Isolated vertex: a vertex whose degree is zero, that is, a vertex with no incident edges.</p> + +<p>Degree of a vertex: number of its incident edges -in and out-.</p> + +<p>Out-degree of vertex A: number of outbound edges / tail ends from A.</p> + +<p>In-degree of vertex A: number of incoming edges / head ends to A.</p><empty-line /><p><emphasis>degrees of a vertex diagram</emphasis></p><empty-line /><p>Path: -aka “walk”- path to follow to get from vertex A to vertex B.</p> + +<p>3.5. Definition of the Duniter Web of Trust</p> + +<p>The Duniter WoTs -one per currency- are simple directed graphs without isolated vertices. The vertices are the members and the edges are the certifications given and received.</p> + +<p><emphasis>Directed</emphasis> means that the responsibility of issuing a certification is unique and personal to the certifier. The trust they place in the receiver cannot be imposed in the other direction although in most circumstances both parties equally trust each other.</p> + +<p>In addition, all vertices are either currently active members or past-members. Past-member vertices are in a specific ‘deactivated state’ and can no longer issue or receive certifications although the ones already issued or received to/from other members are still considered ‘pending’ to avoid a collapse of the WoT. If these old members don’t come back into the WoT, their pending certifications will eventually expire and they will switch from ‘deactivated’ to ‘isolated’ vertices.</p> + +<p>To wrap up with old members, after a certain period of time - set in the currency’s parameters - their deactivated vertex is removed from the web and the associated identity is ‘revoked’. The person who owned the account can no longer use this identity but is free to join the web with another one.</p> + +<p>Identity : An identity is a set of three pieces of information: a public key, a name and a blockstamp. A blockstamp points to a specific block in the chain. Its main use is to freeze the point in time at which an identity was created and to link this identity to a specific chain and a currency - each currency having its own blockchain.</p> + +<p>An identity can be in any one of 5 different status: pending, member, old member, revoked or excluded.</p> + +<p>Let’s take a simple example:</p> + +<p> A -> B -> C + | + \--> D</p> + +<p>If, for whatever reason, A were to lose its member status, the web would crumble and all other members would be excluded as a consequence. To avoid this, the certification from A –> B will remain valid until its expiry date, leaving enough time for B to receive certifications from C or D.</p> + +<p>Because our WoT doesn’t have any isolated vertices, each new identity created needs to be pulled into the web with all of the certifications it has received, all in the same block. This calls for a temporary ‘buffer’ storage space for pending identities and the certifications they have received. This storage space is called ‘the pool’ of Duniter nodes, which we could also have called the ‘sandbox’ as that’s the name used in Duniter’s code. Duniter nodes inclued other ‘pools’ for other documents and metadata not mentioned here.</p> + +<p>3.6. Exploring the rules behind a Duniter Web of Trust</p> + +<p>The Duniter WoTs - one per currency - works with a set of eight fundamental rules enforced through eleven different parameters. Ten of these parameters are set within the genesis block, the eleventh one - msPeriod- having being hard-coded in the Ğ1’s code subsequently.</p> + +<p>3.6.1. Distance rule and referent members (</p> + +<p>stepMax</p> + +<p> and</p> + +<p>xPercent</p> + +<p>)</p> + +<p>These two parameters are closely linked and together define the ‘distance rule’. The ‘distance rule’ can only be described after defining what a ‘referent member’ is:</p> + +<p>Referent member: member A is said to be ‘referent’ if and only if the total of their degrees are greater than or equal to CEIL-N^-1/stepMax where N is the total number of members. As the size of the web will grow this number will grow too, meaning it will take more certification issuances to become a referent member. The number of certifications needed to become a member shouldn’t change.</p> + +<p>Let’s now define the distance rule:</p> + +<p>Distance rule: member A is said to observe this rule if and only if for a subset xPercent % of referent members R there exists a path of length less than or equal to stepMax between R and A.</p> + +<p>Referent members only exist so that the distance rule can take effect, they have no special privileges over non-referent members. In a perfect web, that is one in which each member has certified all members they legitimately can, all members would be referent members. However, because the web progressively grows in size and because members die and are replaced by new ones, there are always members at any given time t who haven’t yet certified all members they legitimately could. These members would hinder the evolution of the web if they were taken into account in the calculation of the distance rule and the web would effectively stop growing.</p> + +<p>Because verifying the application of the distance rule is calculation-greedy, it is only performed when a new identity gets confirmed into the web or an existing member gets renewed. There is an exception to this rule: the distance rule is not observed in the genesis block -when the web is first implemented.</p> + +<p>3.6.2. Rule of the minimum number of certifications needed (</p> + +<p>sigQty</p> + +<p>)</p> + +<p>This is the simplest rule, it essentially says that each member must at any given time -meaning in any single block- have received at least sigQty active certifications. If, for whatever reason, member A were to have less than sigQty active certifications in a given block, they would cease to be a member and be required to publish a request for identity renewal.</p> + +<p>3.6.3. The membership renewal rule (</p> + +<p>msValidity</p> + +<p>,</p> + +<p>msPeriod</p> + +<p> and</p> + +<p>msWindow</p> + +<p>)</p> + +<p>Bear in mind that a membership doesn’t last a lifetime but instead has a lifespan set to msValidity seconds.</p> + +<p>Every single member -or old member who hasn’t revoked his identity or been excluded- can request a membership renewal so long as the last request was made more than msPeriod seconds ago. If a member has never requested a renewal, the date of last renewal is equal to the timestamp at which his membership was first created. A new request will be stored in the ‘pool’ for a maximum of msWindow seconds before it’s included in the blockchain. Once again, this can only happen once/if the member meets both the siqQty rule and the distance rule -if these criterion are already matched it’s just a case of waiting for a new block to be mined-.</p> + +<p>If a member hasn’t requested a renewal for longer than msValidity seconds, they automatically cease to be a member. From this moment on, the ex-member has another msValidity window to renew their membership. When this period of 2 × msValidity runs out, the membership will expire and this identity will never be available for use again in the web. If the person so desires, they will have to publish new identity and membership documents and find enough certifiers, as any newcomer.</p> + +<p>3.6.4. Rule of certification lifespan (</p> + +<p>sigValidity</p> + +<p>)</p> + +<p>All certifications included in the blockchain expire sigValidity seconds after they were issued.</p> + +<p>/!\ The issuance and the inclusion of a certification in the blockchain occur at different times. When member A issues a certification at time t1, it gets stored in the pool starting at t1 and only finds its way into the blockchain at t2 when all of the web’s rules are observed. Several weeks can thus go by between t1 and t2!!!</p> + +<p>3.6.5. Rule of limited supply of active certifications (</p> + +<p>sigStock</p> + +<p>)</p> + +<p>By ‘active certifications’ we refer to certifications included in the blockchain and that haven’t yet expired.</p> + +<p>The total of active certifications issued by any member at any single time must be less than or equal to sigStock. When this threshold is reached the member will have to wait for one of his active certifications to expire before he/she can issue a new one.</p> + +<p>3.6.6. Rule of the time period between two certification issuances. (</p> + +<p>sigPeriod</p> + +<p>)</p> + +<p>As soon as a certification issued by member A gets included in the blockchain, they will be unable to issue a new one before another sigPeriod seconds.</p> + +<p>3.6.7. Expiry of a certification issuance (</p> + +<p>sigWindow</p> + +<p>)</p> + +<p>When a certification is issued by member A, it will be stored in the ‘pool’ for a maximum of sigWindow seconds. If the certification hasn’t been included in the blockchain by then, it will be cancelled and the member’s sigStock will be repleted by one.</p> + +<p>3.6.8. Lifespan of a ‘pending’ identity (</p> + +<p>idtyWindow</p> + +<p>)</p> + +<p>When a new identity is created, it is stored in the ‘pool’ for a maximum of idtyWindow seconds. If the person hasn’t achieved member status by then, the certification will simply be cancelled.</p> + +<p>3.7. Details on some of the WoT’s peculiarities at the genesis block</p> + +<p>The aforementioned rules can only be enforced with an existing web. They cannot be observed when first creating the web, that is when defining the genesis block.</p> + +<p>Only rules 2 and 5 can be observed at the genesis block.</p> + +<p>The genesis block has to be manually created by the founding members. In practice this means that there must be a choice on which identities to include on the premise that all of them observe rules 2 and 5. In addition, the genesis block must be signed with the private key of one of these identities.</p> + +<p>As soon as the genesis block has been created, the other identities can start mining the blockchain and the member who created block #0 effectively looses the decision power he had at creation.</p> + +<p>3.8. Why these rules and application cases in the Ğ1</p> + +<p>3.8.1. Distance and maximum size</p> + +<p>The distance rule is there to curb the maximum size of a Sybil region as well as that of the monetary community as a whole. The xpercent parameter prevents the creation of a ‘faction’ that could take hold of the blockchain.</p><empty-line /><p><emphasis>Sybil region</emphasis></p> + +<p>The Sybil regions are isolated from the rest of the graph in the sense that they can only receive certifications from other ill-intentioned Sybil members. As a consequence, the shortest edge/path between a legitimate member and a Sybil one has to have the attack’s author as an endpoint. The maximum depth the Sybil region can attain is therefore contingent on the distance between the attacking edge-s- and the xpercent% closest referent members, this distance is known as stepAttackers. The maximum size of a Sybil region created by sigQty members depends on the L parameter, defined as L = sigQty/sigStock:</p> + +<p>MaxSybilSize= (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L)</p> + +<p>The maximum size of the Web of Trust is given by the following formula:</p> + +<p>WoTmax = (sigStock)*L^(stepMax-1)</p> + +<p>However we know for a fact that members will never use all of their available certifications. According to Dunbar<sup>10</sup>, on average, one is able to maintain relationships to around 150 people. Being conservative, we will consider that on average, each person will certify 50 accounts. We can calculate the size of the average web of trust WoTavg :</p> + +<p>WoTavg= (50)*(sigQty/50)^(stepMax-1)</p> + +<p>Our goal with the Ğ1 is to create a community of about one million members to test the consequences of a libre monetary system. Let’s see how we can tweak the pair of sigQty and stepMax- to reach this size:</p><empty-line /><p><emphasis>Average WoT size graph as a function of sigQty and stepMax</emphasis></p> + +<p>The maximum size of a Sybil region grows linearly with sigQty but exponentially with stepMax. Logic has it that we need to keep stepMax as low as possible to ensure sufficient strength to the web. The above graph shows that the lowest value of stepMax for a web of a million members is of 5. This is an order of magnitude and is likely to be much higher in reality, we cannot measure it for sure.</p> + +<p>For sigQty we can choose a value of 4 for a web of 1.5 million members or 5 for half a million members. Bear in mind these are gross figures and could be significantly higher, we are talking anywhere between 1 and 10 million in reality. Calculating WOTavg gives us a pretty good idea of how the web would scale bearing in mind that it considers all members are referent members too -which isn’t the case as explained previously-. Hence the maximum size of the web is likely larger, a ballpark figure of half a million is enough for now especially knowing that the smaller sigQty is, the easier it is to launch a Sybil attack -it’s easier to find four accomplices than five-. For security reasons we have settled on five:</p> + +<p>stepMax = 5 +sigQty = 5 +sigStock \>= 50</p> + +<p>The maximum size of a Sybil region therefore is:</p> + +<p>(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5))</p> + +<p>with sigStock = 50 we have a Sybil region of:</p> + +<p>45*(1-10^(5-stepAttackers))/(-9)</p> + +<p>A good practice for protecting the web is to maximise stepAttackers. That’s why we decided that referent members in the genesis block had to be at least four steps away from each other.</p> + +<p>Another way to keep a Sybil attack at bay, were it slow enough for members to notice it, would be for referent members to ‘stretch’ the web intentionally to limit the growth of the region by ensuring that the attackers’ legitimate certifications received in the first place aren’t renewed. But what if bot accounts were created and certified each other super fast and following all rules, how would we counter that? By introducing a minimum length of time between two certifications!</p> + +<p>3.8.2. Time is our friend</p> + +<p>To help us deter a Sybil attack, we’ve decided to impose a minimum period of time between any two certifications issued from a single account. This parameter called sigPeriod affords us a greater chance to detect the formation of a ‘hostile’ faction.</p> + +<p>Here is a graph showing the evolution of a Sybil region with the variation of sigPeriod. The simulation considers that honest members and attackers both issue a certification each sigPeriod interval, in days:</p><empty-line /><p><emphasis>size of the WoT according to sigPeriod and stepAttackers</emphasis></p> + +<p>As we see, there is a strong link between the growth speed of the region and sigPeriod. As evidenced here, we need a sigPeriod high enough in order to ensure that the legitimate web can grow at least as fast as a Sybil region. In addition, the higher sigPeriod is, the more members will exercise their certification power gingerly, the action coming at a higher ‘cost’.</p> + +<p>There are numerous advantages to giving sigPeriod a high value and no technical barriers to it, hence our choice of five days.</p> + +<p>We could have also gone for one week for the sake of simplicity. However there is an underlying idea behind our choice which was quite simply the pace of today’s life. Certifying someone can be a lengthy process as one needs to make sure they are correctly applying the Ğ1 licence and people nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea to allow one to certify at the end of every working week -five days- instead of a whole calendar one.</p> + +<p>3.8.3. Trust me now, trust me forever ? (</p> + +<p>sigValidity</p> + +<p>,</p> + +<p>msValidity</p> + +<p>)</p> + +<p>There would be two main drawbacks to a lifetime membership in the Ğ1’s Web of Trust:</p> + +<p>First of all, some members will pass and those accounts should no longer produce the Universal Dividend.</p> + +<p>Secondly it is of the utmost importance that ‘rogue’ accounts can be excluded from the web at some point.</p> + +<p>To achieve this, certifications have a limited lifespan. Members need to seek renewal from their peers after sigValidity time. On the other hand, this time can’t be too short that members would spend more time seeking renewal than they would exchanging in the currency. Furthermore, a certification with too short a lifespan would foster careless certifying behaviours. The act of certifying must have a high-enough ‘perceived’ cost to make it feel like an important act. Lastly, we also wanted this lifespan to be easy to remember. Historically speaking, we first settled on the values of sigPeriod and sigStock, meant one could issue all of their certifications in 495 days, one year was therefore not long enough. We deemed three years to be too much and that’s how we agreed on two years in the end.</p> + +<p>Thinking that a deceased member could continue producing the UD for two long years without anyone benefitting from it was also something we needed to address. We chose a value of one year for msValidity. The act of renewing every year is done through one of the clients interacting with the blockchain, through a simple click on a button. This parameter is less important than others and is mostly there to ‘prune’ the web of past or inactive members who don’t renew their membership.</p> + +<p>3.8.4. Keeping the pools free of information glut (</p> + +<p>idtyWindow</p> + +<p>,</p> + +<p>sigWindow</p> + +<p>,</p> + +<p>msWindow</p> + +<p>)</p> + +<p>The pools need to be cleaned up on a regular basis to avoid them clogging up with information and to ensure that machines with less calculating power can still run a Duniter node.</p> + +<p>To achieve this, identities with pending membership approval and the corresponding certifications have to remain the shortest time possible in the pool while still having a chance of making it into the blockchain.</p> + +<p>For the Ğ1, our opinion was that two months would be enough for all potential certifiers to agree on a specific identity to certify. We also wanted a time period that would be easy enough to remember by all. We settled on two months, and gave this value to all three parameters idtyWindow, sigWindow and msWindow.</p> + +<p>3.8.5. Avoiding single members from ‘knowing too many people’ (</p> + +<p>sigStock</p> + +<p>)</p> + +<p>We considered that on average, each person will certify 50 people. However, we know for a fact that some members will use more than 50 certifications. The maximum social network of one individual is around 150 people<sup>11</sup>. Being conservative, we settled on a maximum certification number sigstock of 100.</p><empty-line /><p> +Since sigStock’s impact on the size of a Sybil region is fairly limited, we did not investigate further this parameter.</p> + +<p>3.8.6. Avoiding locking minorities (</p> + +<p>xpercent</p> + +<p>)</p> + +<p>It’s easy enough to become a referent member, one of the Sybil strategies could therefore be to create a region of referent members. Such a region would grow slower than otherwise but could confer a locking power to its members by using the distance rule. That’s why the distance rule cannot be calculated on 100% of the referent members. Hence the introduction of the xpercent parameter which defines the percentage of referent members needing to be less than five edges -steps- from each other.</p> + +<p>This percentage needs to be low enough to prevent the formation of a locking minority -referent Sybil members being too far from legitimate referent members-. On the other hand, it needs to be high enough so as to restrict the maximum size of the Sybil region through the distance rule. The xpercent parameter was one of the hardest to define, therefore we might decide to change its value during the Ğ1 experiment.</p> + +<p>We were inspired by the Pareto principle<sup>12</sup>: if at least 20% of members give good density to the web, 80% of the referent members will be five or less steps from any other member -referent or not-. The maximum value for xpercent is therefore 80%, anything above that and the distance rule could be too restrictive for legitimate use cases. With security our top concern, we chose the maximum value of 80%.</p> + +<p>3.8.7. Spam protection with (</p> + +<p>msPeriod</p> + +<p>)</p> + +<p>This parameter stands out a bit on its own, as it was added after the genesis block. It is there to protect the Duniter P2P infrastructure against ‘spam’ attacks. We had to think of a strategy against attacks such as high-frequency membership renewal requests -i.e: in every block, every five minutes- or worse still, hundreds of these requests per minute to flood the Duniter nodes. Without such limits, nodes are supposed to address all renewal requests, even in cases where they were last published five minutes ago! The msPeriod parameter was given the same value as idtyWindow, sigWindow and msWindow, i.e. two months.</p> + +<p>4. Proof of Work with personal difficulty</p> + +<p>As each P2P cryptocurrency, Duniter has a way to synchronize its peers. It uses a proof of Work (PoW) to write the Blockchain on a regular basis, much like BitCoin. However, Duniter has a unique asset : the WoT, where each member represents a unique living human.</p> + +<p>This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each “winning” member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. A view of the whole network is not needed.</p> + +<p>Another strong difference is that forging peers are not rewarded by the protocol. There is no economical incentive on forging lots of blocs, neither on having a lot of computing power.</p> + +<p>One could say that Duniter uses a PoW that needs very low energy consumption compared to BitCoin : an “ecological” PoW ?</p> + +<p>4.1. Why do we need Proof of Work ?</p> + +<p>Duniter nodes share a database as part of a p2p environment. The proof of work (PoW) allows machines to synchronize with each other. In Duniter’s case, the blockchain is our database, and acts as a ledger keeping a trace of all transactions, status of the WoT and more. How can we let several machines add data (ie: a transaction) at the same time? In addition, how do we settle on how much time has gone by since the blockchain was last updated? Agreement on time is of the utmost importance as we want to create Universal Dividends on a regular basis, and keep track of membership status, both in human time.</p> + +<p>Proof-of-work provides a clever solution to both problems:</p><empty-line /><p>Any machine can write into the blockchain (create a new block) but is only authorised to do so if it has previously solved a mathematical equation that require a certain amount of work. The challenge has to be hard enough to prevent two machines to solve it at the same time, ensuring the unicity of a block’s creator.</p> + +<p>Solving this challenge takes a certain amount of time, which depends on the calculating power of the whole network. This provides a common ground for defining the needed time reference. A block time is set (ie: 1 block = 5 min) and Duniter adapts the challenge difficulty to get an average duration corresponding to this block time.</p> + +<p>4.2. Only members can “mine”</p> + +<p>One of Duniter’s major differences with other PoW-based cryptocurrencies is that only members are allowed to author blocks. Each block is signed with the member’s private key, allowing the algorithm to determine a personalised difficulty.</p> + +<p>This personalised difficulty eliminates the rat-race for the most sophisticated and powerful mining equipment. Another benefit is the fact that no “supercomputer” can take control of the blockchain. Lastly, Duniter implements a rotation in forging members thanks to this personalized difficulty.</p> + +<p>This lightweight PoW is much less energy-consuming than other PoW cryptocurrencies. Members can mine with anything from a raspberry pi to a privacy-first internet cube.</p> + +<p>4.3. How does it work ?</p> + +<p>4.3.1. The hash (aka digest)</p> + +<p>Example of a valid hash:</p> + +<p>00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653</p> + +<p>As you can see this hash starts with five zeros which was very hard to achieve and took a lot of work for someone’s computer. Hence the term “proof of work”.</p> + +<p>4.3.2. The common difficulty</p> + +<p>A common difficulty is needed to settle on a yardstick for our time reference. Its role is to make sure the blockchain moves forward at a steady pace - one block every avgGenTime seconds, avgGenTime being one of the 20 parameters behind the Duniter protocol-.</p> + +<p>This difficulty’s initial value can be set to any arbitrary value (70 in Duniter v1.5.x) and then acts as a spring, regulating blocktime creation by increasing itself if the creation interval drops under avgGenTime and vice-versa.</p> + +<p>4.3.2.1. How is difficulty applied ?</p> + +<p>The numeric value of difficulty is taken from an array of possible hashes out of all possible hashes. In DUBPv13 the hash of a block is its sha256 hexadecimal hash.</p> + +<p>To understand the difficulty, we make a euclidiean division of the difficulty by 16.</p> + +<p>Here’s an example with a difficulty value of 70 :</p> + +<p>70 // 16 = 4 with a remainder of 6.</p> + +<p>The valid hashes are the ones starting with four zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). The valid hashes are then written as starting with : 0000[0-9]. This is a bit different from Bitcoin, where the difficulty is only ruled by the number of zeroes.</p> + +<p>4.3.2.2. The Nonce</p> + +<p>When a member is forging a new block, his computer freezes the block’s content and changes the Nonce until the hash reaches the required number of zeroes.</p> + +<p>The nonce allows us to mine a new block by finding a hash. The hash value allows us to determine the difficulty level of the proof-of-work performed. Examples of possible Nonce values:</p> + +<p>10100000112275</p> + +<p>10300000288743</p> + +<p>10400000008538</p> + +<p>10700000079653</p> + +<p>10300000070919</p> + +<p>In reality the Nonce value follows a pre-determined format akin to XYY00000000000. The Nonce’s value isn’t the number of attempts but rather a value within a set of possible ones. This is how the Nonce is built:</p><empty-line /><p>X is a number assigned to a specific peer. Let’s assume that someone has several nodes each with the same private key, this would lead to possible collisions if this person were to mine the same block with different nodes. Each <strikethrough>block</strikethrough> node ? will therefore have its own unique X to prevent this from happening.</p> + +<p>Y is the number of cores of the processor. The Nonce starting with 107[…] belongs to a seven cores processor, while 199[...] could be the proof generated by a 99 cores processor.</p> + +<p>The rest of the Nonce, the part that follows after the XYY, is the numerical space for this individual node and is unique to each of the CPU’s core. This space is comprised of eleven digits (00000000000). For the sake of accuracy, we use the term CPU in the wider sense, it can be understood as a bi-CPU for example. We take into consideration the number of cores for the resulting PoW.</p> + +<p>4.4. Personalised difficulty</p> + +<p>Earlier in this article, we explained that the personalised difficulty is the new and key concept that sets Duniter apart from other PoW-based cryptocurrencies.</p> + +<p>Here is how this personalised difficulty is calculated and assigned:</p> + +<p>It is determined by a combination of two different constraints with complimentary roles: the exclusion factor and the handicap.</p> + +<p>Let powMin be the common difficulty, exFact a member’s exclusion factor and handicap their handicap. This member’s personalised difficulty diff is:</p> + +<p>diff = powMin*exFact + handicap</p> + +<p>4.4.1. Understanding</p> + +<p>exFact</p> + +<p>, the exclusion factor</p> + +<p>Members who have never produced blocks or haven’t for quite some time are assigned an exclusion factor of 1. Their personalised difficulty is therefore simply the sum of powMin + handicap.</p> + +<p>Before reading on, let’s precise the role of this exclusion factor. When a member adds a block to the chain, his exFact jumps up from one to a very high value, to prevent them from forging other blocks immediately after and taking control of the blockchain.</p> + +<p>The exclusion factor will then rapidly return to one. This delay is expressed as a number of blocks. It is calculated as a proportion of the number of members forging. In the Ğ1’s case, this proportion is 1/3, meaning that if there are fifteen members currently forging, the member’s exclusion factor will drop down to one after five blocks.</p> + +<p>4.4.1.1. What is intended by “the number of members forging” ?</p> + +<p>We mean the number of members trying to create the next block. In reality, there is no way to precisely know how many members are calculating at any given time, because it is impossible to view the entire network. But we need this information, whithout which assigning a personalised difficulty is impossible. To achieve this, Duniter looks back at the blockchain and assumes that there is as much members forging as those who have found at least one block in the last blocks in the current window, minus the very last one.</p> + +<p>4.4.1.2. Current window</p> + +<p>We use the concept of current window. The current window is the number of blocks we look back at to determine how many members are forging. Let’s see how it works:</p><empty-line /><p>issuersFrame is the size of the current window in blocks.</p> + +<p>issuersCount the number of members who have calculated at least one block during the current window.</p> + +<p>Both issuersFrame and issuersCount are block fields. When first starting a blockchain, the very first block has an issuersFrame=1 and an issuersCount=0. The genesis block is excluded as there are no members in the current window!</p> + +<p>From the second block onwards (block #1) we track the variation of issuersCount. The member having mined block #0 enters the current window and in block #1 we will therefore mention issuersCount=1.</p> + +<p>issuersFrame then varies as follows:</p> + +<p>if issuersCount increases by N (with a maximum step of N = 1), then issuersFrame will increase by one unit over a period of 5N blocks.</p> + +<p>Conversely, if issuersCount decreases by Y (with a maximum step of Y = 2 = current window inching forward + loss of one calculating member), then issuersFrame will decrease by one unit during 5Y blocks.</p> + +<p>When such events overlap, issuersFrame evolves as so :</p><empty-line /><p><strong>bloc</strong></p> + +<p><strong>event</strong></p> + +<p><strong>issuersFrame</strong></p><empty-line /><p>T</p> + +<p>Babar writes a block and enters issuersCount</p> + +<p>160</p><empty-line /><p>T+1</p> + +<p>Celeste leaves issuersCount</p> + +<p>160 +1 = 161</p><empty-line /><p>T+2</p> + +<p>N/a</p> + +<p>161 +1 -1 = 161</p><empty-line /><p>T+3/4/5</p> + +<p>N/a</p> + +<p>161 +1 -1 = 161</p><empty-line /><p>T+6</p> + +<p>N/a</p> + +<p>161 -1 = 160</p><empty-line /><p>The calculation can be found under rules BR_G05 and BR_G06 of the DUP protocol.</p> + +<p>4.4.1.3. exFact and the personalised difficulty</p> + +<p>We explained that exFact spikes immediately after the member has found a block. It decreases then rapidly to 1 after a number of blocks equal to 1/3 * issuersCount. Let’s see precisely how we calculate exFact:</p><empty-line /><p>nbPreviousIssuers is the value of issuersCount at the last block N found by the member.</p> + +<p>nbBlocksSince is the number of blocks found by the rest of the network since block N.</p> + +<p>percentRot is the number of <emphasis>not excluded</emphasis> peers we want. It is a monetary parameter, its value is 0.67 for Ğ1 currency.</p> + +<p>a = FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) +exFact = MAX [ 1 ; a ]</p> + +<p>The FLOOR is a simple truncate function. For exFact to exclude the member, we need :</p> + +<p>(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2</p> + +<p>We can see that the member is not excluded if nbBlocksSince is greater than 1/3 of the calculating members. Take as an example nbPreviousIssuers = 6 and nbBlocksSince = 3:</p> + +<p>(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1</p> + +<p>However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded:</p> + +<p>(0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2</p> + +<p>Moreover if the last block was authored by the said member, then:</p> + +<p>nbBlocksSince=0 and +exFact = 0.67 * nbPreviousIssuers</p> + +<p>ExFact value increases according to the number of members calculating. Thus, if there is enough members calculating, even mining farms would be excluded. We have therefore succeeded in our intent to deter attempts to seize the blockchain and its currency.</p> + +<p>However, at any time t, the two-thirds of calculating members all have an exclusion factor of 1, even though they might not all have the same computational power at hand. If the personalised difficulty only took into account the exclusion factor, then only the members with the highest computational power from the remaining third would be able to author new blocks and the other 2/3s would almost always be excluded. Lesser machines wouldn’t stand a chance…</p> + +<p>4.4.2. The handicap</p> + +<p>The handicap is the second parameter of the personalised difficulty. Its main role is to improve the rotation of forging peers. A higher handicap is assigned to members with higher calculating power, so lesser machines can also compute blocks. As a consequence, there is no incentive on forging with powerful computers. Security can be achieved with less computing power than with pure PoW.</p> + +<p>The aim is to handicap the half that has authored most blocks (the most powerful half) to favour the other one. So, the handicap formula will use the median number of blocks authored by peers within the current window.</p><empty-line /><p>nbPersonalBlocksInFrame is the number of blocks authored by a single member within the current window.</p> + +<p>medianOfBlocksInFrame is the median number of blocks written by the calculating members during the same timeframe.</p> + +<p>a = (nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame +handicap = FLOOR(LN(MAX( 1 ; a )) / LN(1.189))</p> + +<p>Let’s unwrap the formula:</p> + +<p>(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)</p> + +<p>is simply the ratio between the number of blocks authored by the peer and the median number of blocks. For example, if a peer has authored 9 blocks in the current window and the median is 5, then the ratio will be (9+1)/5 = 2. The MAX function allows us to ensure that the handicap has a value at least equal to 1.</p> + +<p>The Napierian Logarithm of this ratio prevents the handicap from becoming excluding. We want the handicap to level the calculating field so that all peers stand a chance, not to exclude peers.</p> + +<p>If we wanted the handicap to be applied as soon as the median is reached, we would divide it by LN(1). The problem is that we have already set a minimum value of 1 with the MAX function. If we were to divide the ratio by LN(1) all calculating peers would have a handicap \>= 1. In addition, is it really fair to handicap a member who is right on the median?</p> + +<p>That’s why we went for 1.189 rather than 1. A member has to be at least 18.9% above the median to be assigned a handicap. 18.9% is actually 16^(1/16), the difficulty factor between two levels of the proof work (hexadecimal hash).</p> + +<p>To conclude, you have to remember that :</p> + +<p>The handicap is indexed on the logarithm of the ratio to the median,</p> + +<p>Handicap is only applied on members whose ratio to the median is greater than the ratio between two levels of the proof-of-work’s difficulty.</p> + +<p>Conclusion</p> + +<p>Duniter’s Blockchain can be compared to Bitcoin’s : a common document retracing the history of the currency. However, Duniter registers not only trades, but also the history of relationships in the community as a mean to identify a human to a digital account. This way, Duniter has information about the fondamental reference of RTM : living humans. A libre Currency can be issued thanks to the Universal Dividend.</p> + +<p>More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers, maintaining a good security and helping decentralization of calculation.</p> + +<p>The ultimate goal of Duniter project is to allow people to participate in a libre economy, thanks to a libre currency. What is a libre economy ? The Relative Theory of Money defines it through four economic liberties :</p> + +<p>The freedom to choose your currency system: because money should not be imposed.</p> + +<p>The freedom to access resources: because we all should have access to economic & monetary resources.</p> + +<p>The freedom to estimate and produce value: because value is a purely relative to each individual.</p> + +<p>The freedom to trade with the money: because we should not be limited by the avaible money supply.</p> + +<p>Those 4 economic freedoms should be understood together, not exclusively. Plus, “freedom” has to be understood as “non-nuisance”. So here, freedom does not mean the right to take all of a resource (like water source in a desert) so no more is available to the others. Now you get it, this is the goal: free economy through free currency.</p> + +<p>Sources :</p> + +<p>Relative Theory of Money, S.Laborde, 2010: en.trm.creationmonetaire.info/</p> + +<p>Bitcoin Whitepaper, S.Nakamoto, 2008: bitcoin.org/bitcoin.pdf</p> + +<p>The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : lightning.network/lightning-network-paper.pdf</p> + +<p>The GNU Privacy Handbook, M.Ashley, 1999 : www.gnupg.org/gph/en/manual.html#AEN335</p> + +<p>High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. cr.yp.to/papers.html#ed25519.</p> + +<p>PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : archive.org/details/PPCoinPaper</p> + +<p>Duniter Blockchain Protocol, v13, draft by Elois : git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md</p> + +<p>The Sibyl Attack, J.R.Douceur: www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</p> + +<p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992</p><empty-line /><empty-line /><empty-line /><p>Bitcoin Whitepaper, S.Nakamoto, 2008: bitcoin.org/bitcoin.pdf↩</p> + +<p>Relative Theory of Money, S.Laborde, 2010: en.trm.creationmonetaire.info/↩</p> + +<p>OpenPGP protocol defines standard formats for encrypted messages, signatures, private keys, and certificates for exchanging public keys. The GNU Privacy Handbook, M.Ashley, 1999 : www.gnupg.org/gph/en/manual.html#AEN335↩</p> + +<p>High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. cr.yp.to/papers.html#ed25519.↩</p> + +<p>PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : archive.org/details/PPCoinPaper↩</p> + +<p>The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : lightning.network/lightning-network-paper.pdf↩</p> + +<p>Surfing a Web of Trust, Reputation and Reciprocity on CouchSurfing.com, D.Lauterbach, H.Truong, T.Shah, L.Adamic: snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf↩</p> + +<p>Public key validation on GnuPG manual, M.Ashley, 1999 : www.gnupg.org/gph/en/manual.html#AEN335↩</p> + +<p>The Sibyl Attack, J.R.Douceur: www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf↩</p> + +<p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992↩</p> + +<p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992↩</p> + +<p>Pareto principle : en.wikipedia.org/wiki/Pareto_principle↩</p><empty-line /> +</section> + +</body> +</FictionBook> \ No newline at end of file diff --git a/build/whitepaper_en.html b/build/whitepaper_en.html index 7232bd3..2887602 100644 --- a/build/whitepaper_en.html +++ b/build/whitepaper_en.html @@ -10,26 +10,61 @@ Duniter Whitepaper href='bulma.css' > <link rel='stylesheet' href='main.css' > -<script src='js/jquery.js' ></script > -<script src='js/toc.js' ></script > -<script type='javascript' > - if ($) { - $('#whitepaper').tableofcontents({ id: '#toc' }); - } +<script type='text/javascript' > + /** + * Generates a table of contents for your document based on the headings + * present. Anchors are injected into the document and the + * entries in the table of contents are linked to them. The table of + * contents will be generated inside of the first element with the id `toc`. + * @param {HTMLDOMDocument} documentRef Optional A reference to the document + * object. Defaults to `document`. + * @author Matthew Christopher Kastor-Inare III + * @version 20130726 + * @example + * // call this after the page has loaded + * htmlTableOfContents(); + */ + function htmlTableOfContents(documentRef) { + var documentRef = documentRef || document; + var toc = documentRef.getElementById('table_of_contents'); + var headings = [].slice.call(documentRef.body.querySelectorAll('h1, h2, h3, h4, h5, h6')); + headings.forEach(function (heading, index) { + var anchor = documentRef.createElement('a'); + anchor.setAttribute('name', 'toc' + index); + anchor.setAttribute('id', 'toc' + index); + + var link = documentRef.createElement('a'); + link.setAttribute('href', '#toc' + index); + link.textContent = heading.textContent; + + var div = documentRef.createElement('div'); + div.setAttribute('class', heading.tagName.toLowerCase()); + + div.appendChild(link); + toc.appendChild(div); + heading.parentNode.insertBefore(anchor, heading); + }); + } + + try { + module.exports = htmlTableOfContents; + } catch (e) { + // module.exports is not defined + console.error('e', e) + } </script > </head > -<body> +<body onload="htmlTableOfContents();"> <main> -<div id="toc"> - -</div> +<nav id='table_of_contents' ></nav > <article id="whitepaper" class="content"> -<h1 id="duniter-a-libre-currency-blockchain-generator">Duniter : A libre currency blockchain generator !</h1> -<h2 id="abstract-todo">Abstract (TODO)</h2> +<h1 id="duniter-a-libre-currency-blockchain-generator.">Duniter: A libre currency blockchain generator.</h1> +<h2 id="abstract">Abstract</h2> +<p>Many currency principles involve non-equal rights to monetary creation between humans. We propose a monetary creation based on the Relative Theory of Money, which guarantee equal monetary creation for each willing human. This type of currency can be centralised, however, this could lead to censorship and arbitrary choices of the central institution. Thus, strongly inspired by Bitcoin example, we want the currency to be as decentralised as possible, in the transaction network as in the human identification process. We use a Web of Trust between living humans for identification. This web of trust allows us to impose personalised difficulty for transaction validation, keeping the calculation accessible to low-end hardware and allowing all competent members to secure the currency.</p> <h2 id="introduction">Introduction</h2> <p>Duniter is a software to create and manage “libre currencies”. Libre currency is a concept defined by S.Laborde in the Relative Theory of Money (RTM) that was published in 2010. This theory demonstrates the possibility of an invariant monetary unit : the Universal Dividend. Doing so, the RTM answers the question :</p> <blockquote> -<p>How should a currency be created to match the principle of equality between all humans ?</p> +<p>How should a currency be created to match the principle of equality between all humans, now and between generations ?</p> </blockquote> <p>The results of this demonstration implies a monetary creation :</p> <ul> @@ -38,752 +73,267 @@ Duniter Whitepaper <li>which amount has to be reassessed on fixed intervals according to a fixed formula.</li> </ul> <p>Thus, Duniter project will associate a human to a digital identity. It will use a Web of Trust with specific rules. As the number of members may evolve, the Universal Dividend has to be created according to the formula :</p> -<blockquote> -<p>UD(t+1) = UD(t) + c² * ( M(t) / N(t) )</p> -</blockquote> +<p><br /><span class="math display">$$ UD(t+1) = UD(t) + c²*( {M(t) \over N(t) }) $$</span><br /></p> <p>Duniter is based on a decentralized Blockchain. This technical choice allows irreversibility of transaction and uncensorability of trades and identities. While inspired by Bitcoin, Duniter uses a Web of Trust and the Proof of Work to secure the computation network, thus making obsolete the power race model used in Bitcoin.</p> -<p>The first currency created through Duniter is Ğ1 (say “June”). It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software.</p> -<h2 id="state-of-the-art-bitcoin-case">State of the art : Bitcoin case</h2> +<p>The first currency created through Duniter is Ğ1, pronounced “June”. It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software.</p> +<h2 id="state-of-the-art-bitcoin-case">1. State of the art : Bitcoin case</h2> <!-- source : https://duniter.org/en/theoretical/ --> -<p>Duniter uses the crypto-currency concept introduced by Bitcoin, which is to use cryptographic tools such as <em>signatures</em> to create digital currencies. Duniter fits this definition, but it has completely different principles than Bitcoin : the Web of Trust and the Universal Dividend . These differences are on both monetary and technical aspects.</p> -<h3 id="monetary-creation-of-bitcoin-a-space-time-asymmetry">Monetary creation of Bitcoin : a space-time asymmetry</h3> -<p>Space-time asymmetry refers to the relative access of individuals to newly created money (Relative Theory of Money, S.Laborde, 2010). Concretely, all existing currencies (c. 2015) are both spatially and temporally asymmetrical for their users. Let's take Bitcoin as an example to understand why.</p> -<h4 id="spatial-asymmetry">Spatial asymmetry</h4> -<p>When new Bitcoins are created, <em>only some Bitcoin users</em> (the miners) are given new Bitcoins, while everyone else get nothing. <strong>We believe this is the <em>first</em> injustice.</strong> However, some might say:</p> -<blockquote> -<p>"Miners used their <em>electricity and time</em> to get it!"</p> -</blockquote> -<p>... we would answer that this work <em>shouldn't have been rewarded by newly created Bitcoins</em>. New Bitcoins should be distributed to the whole Bitcoin community. Miners should be rewared another way, but not by money issuance. Of course, Bitcoin can't create money through Basic Income since <em>Bitcoin users are not strongly identified</em>, and one might benefit from money creation multiple times if he owned several wallets. Duniter gets rid of this problem completely by identifying its users and giving <em>the same amount of Basic Income to everyone</em>.</p> -<h4 id="temporal-asymmetry">Temporal-asymmetry</h4> -<p>Bitcoin has an absolute limit of 21 million BTC (its unit of currency), which means ever fewer bitcoins will be created over time until no new BTC are being generated. So, once the first adopters have mined every bitcoin, how will future joiners get Bitcoins? Just like Euros or Dollars: to get money, they will have to work for the ones who already own it. <strong>We believe this is the <em>second</em> injustice.</strong> Every member of a monetary community should be equal concerning monetary creation, and get the same relative amount of money over time, <em>even if they are a late adopter</em>. Duniter aims to fix this by making the Universal Dividend (a.k.a. <em>UD</em>) <em>grow by the time</em> (S.Laborde, 2010) according to precise rules, thus making members equal toward money issuance on a half-lifespan.</p> -<h4 id="a-solution">A solution</h4> -<p>Bitcoin has taught us that <em>it is possible</em> to create a currency system allowing one to both create digital money and to exchange it without a central authority. What we need to change is <em>the way money is issued</em> so we finally have a symmetrical system. We need Bitcoin <em>+ Universal Dividend</em>. But Universal Dividend <em>implies</em> that the community consists of only identified people. This is where the Web of Trust (WoT) comes into place. This concept, introduced by cryptography with the <a href="https://www.wikiwand.com/en/Pretty_Good_Privacy">OpenPGP</a> format, allows us to identify people in a <em>decentralized</em> manner. It works as follows: each person creates <em>a personal identity</em> that is linked to its cyptographic certificate. The identity must be confirmed by others members who use their own cryptographic key. It is that simple: <strong>people choose who is part of the community and who is not, not a central authority.</strong></p> -<blockquote> -<p>Duniter however won't use OpenPGP for its cryptographic features: Elliptic Curves will be used instead for the conciseness of its generated keys and its pratical advantages. Duniter has its own Web of Trust principles, that shall be exposed later.</p> -</blockquote> -<h3 id="proof-of-work-mining-a-power-race-todo">Proof-of-Work mining : a power race (TODO)</h3> -<p>In Bitcoin Model, the calculation and incentive principles cause a power race : new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. The goal of Duniter is to make blockchain validation much less energy and hardware consuming while keeping a strong level of security. As a consequence, even low-power hardware can secure Duniter Blockchain, which leads to a better decentralization of forging operations.</p> -<h3 id="other-projects">Other projects ?</h3> -<h4 id="what-about-pos">What about PoS ?</h4> -<p>When conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead to placing power over the currency in the richests hands : this is contrary to the symmetical principles of Duniter.</p> -<p>Now that PoS is well-tested, one could try to use Duniter’s WoT to create a PoS-like algorithm with equal chances among members. But this is not our aim for now.</p> -<h4 id="what-about-directed-acyclic-graph">What about Directed Acyclic Graph ?</h4> -<p>The Circles project uses DAG in a basic income cryptocurrency. However, in this project, one peer cannot know the whole monetary mass and the exact number of other peers. The calculation of Universal Dividend <code>UD = c * M/N</code> seems impossible, since we know neither M nor N.</p> -<h2 id="duniters-blockchain">Duniters Blockchain</h2> +<p>Duniter uses the crypto-currency concept introduced by Bitcoin<a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a>, which is to use cryptographic tools such as signatures to create trustless digital currencies. Duniter fits this definition, but it has two completely different principles than Bitcoin : the Web of Trust and the Universal Dividend . These differences are on both monetary and technical aspects.</p> +<h3 id="monetary-creation-a-space-time-asymmetry">1.1. Monetary creation of Bitcoin : a space-time asymmetry</h3> +<p>Space-time asymmetry refers to the relative access of individuals to newly created money<a href="#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a>. Concretely, most existing currencies (c. 2020) are both spatially and temporally asymmetrical for their users. Let's take Bitcoin as an example to understand why.</p> +<h4 id="spatial-asymmetry">1.1.1. Spatial asymmetry</h4> +<p>When new Bitcoins are created, only some Bitcoin users (the miners) are given new Bitcoins, while everyone else get nothing. We believe this is the first injustice. However, some might say:</p> +<blockquote> +<p>"Miners used their electricity and time to get it!"</p> +</blockquote> +<p>... we would answer that this work should not have been rewarded by newly created Bitcoins. New units should be distributed to the whole community. Miners should be rewared another way, but not by money issuance. Of course, Bitcoin cannot create money through Basic Income since Bitcoin users are not strongly identified, and one might benefit from money creation multiple times if they owned several wallets. Duniter gets rid of this problem by identifying its users and creating the same amount of Basic Income to everyone.</p> +<h4 id="temporal-asymmetry">1.1.2. Temporal-asymmetry</h4> +<p>Bitcoin has an absolute limit of 21 million BTC (its unit of currency), which means ever fewer bitcoins will be created over time until no new BTC are being generated. So, once the first adopters have mined every bitcoin, how will future joiners get Bitcoins? Just like most of us do for Euros or Dollars: to get money, they will have to work for the ones who already own it.</p> +<p>We believe this is the second injustice. Every member of a monetary community should be equal concerning monetary creation, and get the same relative amount of money over time, even if they are a late adopter. Duniter aims to fix this by making the Universal Dividend (a.k.a. UD) grow by the time according to precise rules, thus making members equal toward money issuance on a half-lifespan.</p> +<p>Most currencies present one of these two asymmetries, including metal currencies and mutual credit, as exposed in the RTM.</p> +<h4 id="a-solution">1.1.3. A solution</h4> +<p>Bitcoin has taught us that it is possible to create a currency system allowing one to both create digital money and to exchange it without a central authority. What we need to change is the way money is issued so we finally have a symmetrical system. We need <strong>Bitcoin + Universal Dividend</strong>. But Universal Dividend implies that the community consists of only identified people. This is where the Web of Trust (WoT) comes into place.</p> +<p>This concept, introduced by cryptography with the OpenPGP format<a href="#fn3" class="footnote-ref" id="fnref3"><sup>3</sup></a>, allows us to identify people in a decentralized manner. It works as follows: each person creates a personal identity that is linked to its cyptographic certificate. The identity must be confirmed by others members who use their own cryptographic key. It is that simple: people choose who is part of the community and who is not, not a central authority.</p> +<p>However, Duniter will not use OpenPGP for its cryptographic features: Elliptic Curves<a href="#fn4" class="footnote-ref" id="fnref4"><sup>4</sup></a> will be used instead for the conciseness of its generated keys and its pratical advantages. Duniter has its own Web of Trust principles, that will be exposed later.</p> +<h3 id="proof-of-work-mining-a-power-race">1.2. Proof-of-Work mining : a power race</h3> +<p>In Bitcoin Model, the calculation and incentive principles cause a power race : new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. This leads to a power race an places the control over the currency in the hands of the richest hardware owners. We want to make Duniter blockchain validation much less energy and hardware consuming while keeping a strong level of security. This will be further explained later. A consequence of this choice is the participation of low-end hardware in the Duniter network, leading to a better decentralization of blockchain validation.</p> +<h4 id="what-about-proof-of-stake">1.2.1 What about Proof of Stake ?</h4> +<p>Proof of stake consensus algorythm was first introduced in 2012<a href="#fn5" class="footnote-ref" id="fnref5"><sup>5</sup></a>. The basic principle is to allow the richest wallets to issue blocks, putting their coin balance as a “stake” they would lose in case of cheat.</p> +<p>At the time of conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. We did not chose this consensus principle. Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead to placing power over the currency in the richests hands : this is contrary to the symmetical principles of a libre currency.</p> +<h2 id="duniters-blockchain">2. Duniters Blockchain</h2> <!-- source : https://duniter.org/en/theoretical/ --> <p>Duniters Blockchain follows the basic principles of Bitcoins. This is essential for synchronization between peers, as to prevent double-spend attacks. However, Duniters Blockchain will store different informations than Bitcoins.</p> -<p>The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no <em>generation transaction</em> exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either:</p> +<p>The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no generation transaction exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either:</p> <ul> <li>a former transaction (as in Bitcoin)</li> <li>a Universal Dividend (specific to Duniter).</li> </ul> -<p>Duniters Web of Trust is also written in the Blockchain. The identity of each member gets registered much like transactinos are, with a strong link to the time reference. Thus, the Blockchain is a representation of a space-time frame of reference, where “space” are members of the WoT and “time” the basci blockchain units : the blocks. On each point of time, one can determain whick account is legitimate to create the UD, only with a blockchain analysis.</p> -<h3 id="spam-countermeasures-todo">Spam countermeasures (TODO)</h3> -<p>An issue of most cryptocurrency projects is to prevent the common ledger from growing too much and require lot of storage and computing power to be usable. In particular, we don’t want an attacker to be able to make the Blockchain grow too fast. Most projects implement transaction fees as a way to prevent this, making the attacker lose money. We don’t want to do this since a currency with automatic fees on transactions is no more neutral. Several countermeasuers against such spam attacks are implemented.</p> +<p>Duniters Web of Trust is also written in the Blockchain. The identity of each member gets registered much like transactions are, with a strong link to the time reference. Thus, the Blockchain is a representation of a space-time frame of reference, where “space” are members of the WoT and “time” the basic blockchain units : the blocks. On each point of time, one can determine which account is legitimate to create the UD, only with a blockchain analysis.</p> +<h3 id="spam-countermeasures">2.1. Spam countermeasures</h3> +<p>An issue of most cryptocurrency projects is to prevent the common ledger from growing too much. This would require nodes to have a lot of storage and computing power to be usable. In particular, we don’t want an attacker to be able to make the Blockchain grow too fast. Most projects implement transaction fees as a way to prevent this, making the attacker lose money. We don’t want to introduce this mean since a currency with automatic fees on transactions is no more neutral. Several countermeasuers against such spam attacks are implemented.</p> <!-- see : https://forum.duniter.org/t/sans-frais-de-transaction-comment-resister-aux-attaques/3846/25 (implemented ?)--> -<ul> -<li>output minimal de 100*Unitbase / 1 unité -> empêche un attaquant de faire grossir la BC et les index trop vite (DUBP v12)</li> -<li>chaînage maximal des tx</li> -<li>seuils de dépense (implémentés ? en tout et par issuer ?)</li> -</ul> -<h3 id="scaling">Scaling</h3> +<h4 id="minimum-output-amount">2.1.1. Minimum output amount</h4> +<!-- This has to be implemented in DUBPv13. --> +<p>Fixing a minimal output amount reduces the power of an attack. Duniter deals with cents of Ğ1 or 1/1000 of the first UD. An attacker could create thousand accounts with only 1 UD. To prevent this, a valid transaction must have output amounts of minimum 1Ğ1. This reduces the power an attack by 100.</p> +<h4 id="limited-block-size-and-chainability">2.1.2. Limited block size and chainability</h4> +<p>The block size is always limited. While the protocol allows this limit to evolve to address scaling issues, an attacker cannot register as many transaction as they wish.</p> +<p>With the same goal to prevent too many transactions to get registered, while transactions can be “chained” (refer to another transaction in the same block), the chainability of transactions is limited to 5.</p> +<h3 id="scaling">2.2. Scaling</h3> <p>Most of the time, the scaling issue rises for distributed systems that should work on a very large scale. This is not the case of Duniter, for multiple reasons :</p> <ul> -<li>Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don’t want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT limits its size to around 16 million members.</li> -<li>Duniter’s aim is to be used to create <em>multiple</em> libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community.</li> -</ul> -<p>However, Duniter has two assets that might be used if the number of users grow.</p> -<h4 id="dynamic-block-size">Dynamic block size</h4> -<p>While Bitcoin has a fixed block size, Duniters blocks size can evolve. On low use of the blockchain, the maximal block size is 500 bytes. On high use of the blockchain, the maximal block size would be 110% of the average size of the current window blocks( <em>current window</em> will be described in the PoW part). This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it.</p> -<div class="{highlight}"> -<p>block_size < max(500 ; CEIL(1.10 * (average block size))</p> -</div> -<h4 id="lightning-networks">Lightning Networks</h4> -<p>The Lightning Networks allow almost instant and off-chain transactions. They were first implemented on Lightcoin, and are now on Bitcoin. One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. While not available yet, this payment channel might get implemented when needed.</p> -<h2 id="duniter-web-of-trust">Duniter Web of Trust</h2> -<!-- source : https://duniter.org/en/deep-dive-into-the-web-of-trust --> -<h3 id="basic-principles">Basic Principles</h3> -<p>In order to identify “members” account - which create monetary units - from other accounts, Duniter uses a Web of Trust. This can be summarized into few principles:</p> -<ul> -<li>Each account becomes a member if it received a minimal number of certifications (5 for Ğ1 currency)</li> +<li>Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don’t want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT should limit its size to around 16 million members.</li> +<li>Duniter’s aim is to be used to create multiple libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community.</li> +</ul> +<p>However, Duniter has assets that will help if the number of users and transactions grow.</p> +<h4 id="dynamic-block-size">2.2.1 Dynamic block size</h4> +<p>While Bitcoin has a fixed block size, Duniters blocks size can evolve. On low use of the blockchain, the maximal block size is 500 bytes. On high use of the blockchain, the maximal block size would be 110% of the average size of the current window blocks(see “personalised difficulty” part for more information). This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it. The block size (in bytes) is limited as so :</p> +<pre><code>block_size < max(500 ; CEIL(1.10 * (average block size))</code></pre> +<h4 id="lightning-networks">2.2.2. Lightning Networks</h4> +<p>The Lightning Networks<a href="#fn6" class="footnote-ref" id="fnref6"><sup>6</sup></a> allow almost instant and off-chain transactions. They were first implemented on Lightcoin, and are now on Bitcoin. One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. While not available yet, this payment channel might get implemented when needed.</p> +<h4 id="unit-base">2.2.3. Unit base</h4> +<p>As the Universal Dividend grows exponentially, with time Duniter nodes would have had to deal with always largest amounts, eventually reaching the BIGINT limit. To avoid this, the amounts are expressed with a unit base in base 10. We want the UD amount to always fit in 4 digits. To manage it, the <code>unitbase</code> is updated each time the UD value reaches 100.00 : it goes from <code>99.99*10^(unitbase)</code> to <code>10.00*10^(unitbase+1)</code>. All the unit amounts are thus divided by 10. While this might seem strange, this process has already hapened in state currencies. Moreover, the amounts expressed in UD will not change.</p> +<p>With a monetary growth of 10% each year and a stable population, such a change of unit base would happen each 25 years.</p> +<h2 id="duniter-web-of-trust">3. Duniter Web of Trust</h2> +<h3 id="duniter-wot-basic-principles">3.1. Basic Principles</h3> +<p>In order to identify “members” accounts - which create monetary units - and other accounts, Duniter uses a Web of Trust. This can be summarized into few principles:</p> +<ul> +<li>Each account becomes a member if it received a minimal number of certifications - 5 for Ğ1 currency.</li> <li>Only members accounts can send certifications. Certifications have a limited lifespan.</li> <li>A certification indicates that the sender accepts the receiver as a legitimate identity.</li> </ul> -<p>The aim of the WoT is to identify a blockchain account to a living human. Each member of the Ğ1 currency signs a licence stating that they will only certify humans they know well (among other rules). Thus, if a member is part of an attack on the currency, they can be found by mutual friends. The security of Ğ1 currency stands on:</p> -<ul> -<li>Corroborating informations on members (5 certifications)</li> -<li>Peer pressure by close relatives</li> -<li>Law if the licence has not been respected.</li> -</ul> -<p>Note that non-members accounts can use the currency, but cannot create money. They can be used by individuals as secondary wallets, or by institutions.</p> -<p>However, the WoT does not rely only on trust betwenn people. Rules have been added to increase the security, and we will present them.</p> -<h3 id="why-do-we-need-a-web-of-trust">Why do we need a Web of Trust?</h3> +<p>The aim of the WoT is to identify a blockchain account to a living human. According to Lauterbach et.al<a href="#fn7" class="footnote-ref" id="fnref7"><sup>7</sup></a>, the strengh of a relationship should be considered when building a vouch system. For this reason, the Ğ1 Web of Trust rules are expressed in a licence stating what WoT certifications are. A certification represents a strong human relationship : one may certify a close relative, not an acquaintance. Each member has to accept this licence before being included in the WoT. Thus, if a member is part of an attack on the currency, they can be found by mutual relatives. Additional security rules occur to prevent cheat and attacks on a large scale.</p> +<p>Note that non-members accounts can use the currency, but cannot create money. Non-members accounts can be used by individuals as secondary wallets, or by institutions.</p> +<p>We were inspired by the OpenPGP Trust system<a href="#fn8" class="footnote-ref" id="fnref8"><sup>8</sup></a>. However, the OpenPGP trust principles aim at defining trust from a particular point of view while Duniter needs to identify humans for the whole community. To achieve this goal, while OpenPGP allows each user to tweak its trust parameters individually, Duniter sets rules in the “genesis” block for the whole community.</p> +<h3 id="why-do-we-need-a-web-of-trust">3.2. Why do we need a Web of Trust ?</h3> <p>There are two reasons we need it :</p> <ol type="1"> -<li>To make sure that only one Universal Dividend is produced per member at each specified creation interval -in the Ğ1’s case this interval is set as daily <code>86 400</code> seconds-, it is the <em>monetary parameter</em> known as <code>dt</code>-.</li> -<li><p>To identify the nodes hashing the blocks and assign them each a personalised difficulty. This custom difficulty <a href="https://en.wikipedia.org/wiki/Proof-of-work_system">proof of work</a> is there to avoid the blockchain’s validation mechanism becoming too centralised as is the case with many 'non-libre’ cryptocurrencies.</p> -<blockquote> -<p>Wait, what’s a ‘monetary parameter’ ?</p> -</blockquote></li> +<li>To make sure that only one Universal Dividend is produced per member at each specified creation interval. In the Ğ1’s case this interval is set as daily <code>86 400</code> seconds, it is the <em>monetary parameter</em> known as <code>dt</code>.</li> +<li>To identify the nodes hashing the blocks and assign each a personalised difficulty. This custom difficulty proof of work is there to avoid the blockchain’s validation mechanism becoming too centralised as is the case with many 'non-libre’ cryptocurrencies.</li> </ol> -<p>Every currency implementing Duniter has its own blockchain whose behaviour is dictated by a set of ‘parameters’ -defined in block zero, the so-called genesis block- that can be tweaked to achieve the desired results. At the time of writing this article, the Duniter protocol -aka DUP- has a total of 21 parameters of which 10 are for the WoT alone. We’ll focus on these 10.</p> -<p>Suffice to say that in the Ğ1’s case, the DU is created every 24 hours -86 400 seconds- but this interval -set through the time derivative <code>dt</code> parameter- can have a different value in an other implementation of the protocol.</p> -<p>I won’t write about the second parameter having to do with the proof of work, it’s outside our scope here, just know that the Web of Trust allows us to <strong>identify</strong> the members providing hashing power, which we couldn’t do without it. This crucial feature means we can impose a rotation between the members hashing the blocks so that no single rich individual or group invests in a giant ‘hash farm’ and takes a hold of the blockchain, paralysing the community!</p> -<p>Let’s go back to the first objective: to make sure that each member can only have one account. As we all know, achieving zero-risk isn’t possible, our goal is therefore not to create a WoT within which fraud would be absolutely impossible but instead to discourage it. Here is a rewording of our goal in 4 smaller ones :</p> -<ol type="1"> -<li>To make the certification process lengthy enough that all members exercise due diligence and are wary of risks.</li> -<li>To make fraudulent acts as hard as we can to the extent that they become pointless.</li> -<li>To ensure that any Sybil attacks have a negligible impact on the currency -<em>by ensuring that illegitimate double Universal Dividends have no significant bearing on the legitimate monetary mass</em>-</li> -<li>To slow the growth of ‘Sybil regions’ to give enough time for the community to react and isolate the threat.</li> -</ol> -<blockquote> -<p><strong>Wait, a Sybil what ?</strong></p> -</blockquote> -<p>A <a href="https://en.wikipedia.org/wiki/Sybil_attack"><strong>Sybil attack</strong></a>, is the name given to attacks perpetrated on a reputation system through the creation of fake identities. A Web of Trust is a specific instance of a <a href="https://en.wikipedia.org/wiki/Reputation_system"><strong>Reputation System</strong></a>.</p> -<p>There are plenty of Sybil attack scenarios we can think of and just as many reasons why their perpetrators would want to carry them out. Our objective is that the configuration of the WoT protects both users and its IT backbone infrastructure against these attacks.</p> -<p>This means that micro-attacks performed by small groups of individuals looking for personal enrichment are of no interest to us. The web’s role isn’t to deter these attacks, this being instead the role of the community. Just like the town you live in is responsible for providing your tap water and electricity but isn’t responsible for any burglaries etc. Much in the same way, Duniter’s WoT guarantees us all a functional currency and that’s quite a feat in itself!</p> -<h3 id="the-importance-of-having-our-own-certification-system">The importance of having our own certification system</h3> -<p>We are regularly offered to switch over to third-party or state-owned authentication systems but these are centralised and go against the principles of our community. We feel that we would lose our independence and universality by adopting a state-controlled system. People without an official state-provided identity or homeless people would also run the risk of being excluded from the WoT. It is of the utmost importance that we remain free from any state or corporation. To this day we depend only on the Internet and yet, were it to fail, there are already alternatives being tested around the world for a decentralised network.</p> -<h3 id="a-few-foundational-concepts-on-graph-theory-a-bit-of-vocabulary">A few foundational concepts on graph theory : a bit of vocabulary</h3> -<ul> -<li><p><strong>Graph</strong>: set of points -called ‘vertices’- joined by edges -called paths/walks-.</p></li> -<li><p><strong>Simple graph</strong>: a graph with no loops and with no multiple edges. That is, each edge connects two distinct endpoints and no two edges have the same endpoints. A simple edge is an edge that is not part of a multiple adjacency -of edges-. In many cases, graphs are assumed to be simple unless specified otherwise. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a></p></li> -<li><p><strong>Directed graph</strong>: a graph in which the edges have a distinguished direction, from one vertex to another. A directed edge can also be called a path or walk. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a> Arrow A –> B is therefore different from arrow B –> A.</p></li> -<li><p><strong>Endpoints</strong>: the edge with vertex A –> B has A and B as endpoints, respectively as start and end of the path/walk.</p></li> -<li><p><strong>Isolated vertex</strong>: a vertex whose degree is zero, that is, a vertex with no incident edges. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a></p></li> -<li><p><strong>Degree of a vertex</strong>: number of its incident edges -in and out-.</p></li> -<li><p><strong>Out-degree of vertex A</strong>: number of outbound edges / tail ends from A.</p></li> -<li><p><strong>In-degree of vertex A</strong>: number of incoming edges / head ends to A.</p></li> -</ul> -<figure> -<img src="https://duniter.org/en/images/wiki/degrees.jpg" alt="degress of a vertex diagram" /><figcaption>degress of a vertex diagram</figcaption> -</figure> -<ul> -<li><strong>Path</strong>: -aka “walk”- path to follow to get from vertex A to vertex B.</li> -</ul> -<h3 id="definition-of-the-duniter-web-of-trust">Definition of the Duniter Web of Trust</h3> -<p>The Duniter WoTs -one per currency- are simple directed graphs without isolated vertices. The vertices are the members and the edges are the certifications given and received.</p> -<p>Directed, what does that mean?</p> -<p>The responsibility of issuing a certification is unique and personal to the certifier. The trust he/she places in the receiver cannot be imposed in the other direction although in most circumstances both parties equally trust each other.</p> -<p>In addition, all vertices are either currently active members or past-members. Past-member vertices are in a specific ‘deactivated state’ and can no longer issue or receive certifications although the ones already issued or received to/from other members are still considered ‘pending’ to avoid the web collapsing like a house of cards.</p> -<p>If these old members don’t come back into the web, their pending certifications will eventually expire and they will switch from ‘deactivated’ to ‘isolated’ vertices.</p> -<p>To wrap up with old members, after a certain period of time -set in the currency’s parameters - their deactivated vertex is removed from the web and the associated identity is ‘revoked’. The person who owned the account can no longer use this identity but is free to join the web with another one. :-)</p> -<blockquote> -<p>What do you mean by ‘identity’?</p> -</blockquote> -<p>An identity is a set of three pieces of information: a public key, a name and a blockstamp. A blockstamp points to a specific block in the chain. Its main use is to freeze the point in time at which an identity was created and to link this identity to a specific chain and of course, a currency -each currency having its own blockchain-.</p> -<p>An identity can be in any one of 5 different status: pending, member, old member, revoked or excluded.</p> -<p>Let’s take a simple example:</p> -<div class="highlight"> -<pre><code>A -> B -> C - | - \--> D</code></pre> -</div> -<p>If, for whatever reason, A were to lose its member status, the web would crumble and all other members would be excluded as a consequence. To avoid this, the certification from A –> B will remain valid until its expiry date, leaving enough time for B to receive certifications from C or D.</p> -<p>Because our WoT doesn’t have any isolated vertices, each new identity created needs to be pulled into the web with all of the certifications it has received -in the same block-. This calls for a temporary ‘buffer’ storage space for <strong>pending</strong> identities and the certifications they’ve received. This storage space is called ‘the pool’ -of Duniter nodes- which we could also have called the ‘sandbox’ as that’s the name used in Duniter’s code. I might add that these ‘pools’ also include other documents and metadata not mentioned here.</p> -<h3 id="exploring-the-rules-behind-a-duniter-web-of-trust">Exploring the rules behind a Duniter Web of Trust</h3> -<p>The Duniter WoTs -one per currency- work with a set of eight fundamental rules, themselves enforced through eleven different parameters. Ten of these parameters are set within the genesis block, the eleventh one - <code>msPeriod</code>- having being hard-coded in the Ğ1’s code subsequently.</p> -<h4 id="distance-rule-and-referent-members-stepmax-and-xpercent-1distance-rule-and-referent-members-stepmax-and-xpercent">1.Distance rule and referent members (<code>stepMax</code> and <code>xPercent</code>) {#1distance-rule-and-referent-members-stepmax-and-xpercent}</h4> -<p>These two parameters are closely linked and together define the ‘distance rule’. The ‘distance rule’ can only be described after defining what a ‘referent member’ is:</p> -<blockquote> -<p><strong>Referent member</strong>: member A is said to be ‘referent’ if and only if the total of his/her degrees are greater than or equal to <code>CEIl-N^-1/stepMax--</code> where N is the total number of members.** As the size of the web will grow this number will grow too, meaning it will take more certification issuances to become a referent member as the number of certifications needed to become a member shouldn’t change.</p> -</blockquote> -<p>Let’s now define the distance rule:</p> -<blockquote> -<p><strong>Distance rule</strong>: member A is said to observe this rule if and only if for a subset xPercent % of referent members R there exists a path of length less than or equal to <code>stepMax</code> between R and A.**</p> -</blockquote> -<p>Referent members only exist so that the distance rule can take effect, they have no special privileges over non-referent members. In a perfect web, that is one in which each member has certified all members he/she legitimately can, all members would be referent members. However, because the web progressively grows in size and because members die and are replaced by new ones, there are always members at any given time <code>t</code> who haven’t yet certified all members they legitimately could. These members would hinder the evolution of the web if they were taken into account in the calculation of the distance rule and the web would effectively stop growing. -You can see what would happen if the notion of ‘referent member’ didn’t exist by going to the ‘gaussianWotQuality’ page on <a href="https://g1-monit.librelois.fr/gaussianWotQuality?lg=en&unit=quality">currency-monit</a> and activating ‘if the concept of referent members didn’t exist’-.</p> <blockquote> -<p><strong>When is the distance rule applied?</strong></p> +<p><strong>Monetary parameter</strong> : Each currency that use Duniter has its own blockchain whose behaviour is dictated by a set of ‘parameters’ defined in block zero - the so-called genesis block - that can be tweaked to achieve the desired results. At the time of writing the Whitepaper, the Duniter Blockchain Protocol (DUBP) has a total of 21 parameters of which 10 are for the WoT alone. We’ll focus on these 10.</p> +<p>Suffice to say that in the Ğ1’s case, the DU is created every 24 hours - 86 400 seconds. This interval is set through the time derivative <code>dt</code> parameter and can have a different value in other implementations of the protocol.</p> </blockquote> -<p>Because verifying the application of the distance rule is calculation-greedy, it is only performed when a new identity gets confirmed into the web or an existing member gets renewed. <em>Exception to the rule: the distance rule is not observed in the genesis block -when the web is first implemented-.</em></p> -<h4 id="rule-of-the-minimum-number-of-certifications-needed-sigqty-2-rule-of-the-minimum-number-of-certifications-needed-sigqty">2. Rule of the minimum number of certifications needed (<code>sigQty</code>) {#2-rule-of-the-minimum-number-of-certifications-needed-sigqty}</h4> -<p>This is the simplest rule, it essentially says that each member must at any given time -meaning in any single block- have received at least <code>sigQty</code> active certifications. If, for whatever reason, member A were to have less than <code>sigQty</code> active certifications in a given block, he/she would cease being a member and be required to publish a request for identity renewal.</p> -<h4 id="the-membership-renewal-rule-msvalidity-msperiod-and-mswindow-3-the-membership-renewal-rule-msvalidity-msperiod-and-mswindow">3. The membership renewal rule (<code>msValidity</code>, <code>msPeriod</code> and <code>msWindow</code>) {#3-the-membership-renewal-rule-msvalidity-msperiod-and-mswindow}</h4> -<p>Bear in mind that a membership doesn’t last a lifetime but instead has a lifespan set to <code>msValidity</code> seconds.</p> -<p>Every single member -or old member who hasn’t revoked his identity or been excluded- can request a membership renewal so long as the last request was made more than <code>msPeriod</code> seconds ago -if a member has never requested a renewal, the date of last renewal is equal to the timestamp at which his membership was first created. A new request will be stored in the ‘pool’ for a maximum of <code>msWindow</code> seconds before it’s included in the blockchain. Once again, this can only happen once/if the member meets both the <code>siqQty</code> rule and the distance rule -if these criterion are already matched it’s just a case of waiting for a new block to be mined-.</p> -<p>If a member hasn’t requested a renewal for longer than <code>msValidity</code> seconds, he/she automatically ceases being a member. From this moment on, the ex-member has another <code>msValidity</code> window to renew his/her membership. When this period of `2 × msValidity’ runs out, the membership will expire and this identity will never be available for use again in the web. If the person so desires, he/she will have to start from zero to regain access to the WoT.</p> -<h4 id="rule-of-certification-lifespan-sigvalidity-4-rule-of-certification-lifespan-sigvalidity">4. Rule of certification lifespan (<code>sigValidity</code>) {#4-rule-of-certification-lifespan-sigvalidity}</h4> -<p>All certifications included in the blockchain expire <strong>sigValidity</strong> seconds after they were <strong>issued</strong>.</p> -<p>/!\ The issuance and the inclusion of a certification in the blockchain occur at different times. When member A issues a certification at time t1, it gets stored in the pool starting at t1 and only finds its way into the blockchain at t2 when all of the web’s rules are observed. Several weeks can thus go by between t1 and t2!!!</p> -<h4 id="rule-of-limited-supply-of-active-certifications-sigstock-5-rule-of-limited-supply-of-active-certifications-sigstock">5. Rule of limited supply of active certifications (<code>sigStock</code>) {#5-rule-of-limited-supply-of-active-certifications-sigstock}</h4> -<p>By ‘active certifications’ we refer to certifications included in the blockchain and that haven’t yet expired.</p> -<p>The total of active certifications issued by any member at any single time must be less than or equal to <code>sigStock</code>. When this threshold is reached the member will have to wait for one of his active certifications to expire before he/she can issue a new one.</p> -<h4 id="rule-of-the-time-period-between-two-certification-issuances.-sigperiod-6-rule-of-the-time-period-between-two-certification-issuances-sigperiod">6. Rule of the time period between two certification issuances. (<code>sigPeriod</code>) {#6-rule-of-the-time-period-between-two-certification-issuances-sigperiod}</h4> -<p>As soon as a certification issued by member A gets included in the blockchain, he/she will be unable to issue a new one before another <code>sigPeriod</code> seconds.</p> -<h4 id="expiry-of-a-certification-issuance-sigwindow-7-expiry-of-a-certification-issuance-sigwindow">7. Expiry of a certification issuance (<code>sigWindow</code>) {#7-expiry-of-a-certification-issuance-sigwindow}</h4> -<p>When a certification is issued by member A, it will be stored in the ‘pool’ for a maximum of <code>sigWindow</code> seconds. If the certification hasn’t been included in the blockchain by then, it will be cancelled and the member’s <code>sigStock</code> will be repleted by one.</p> -<h4 id="lifespan-of-a-pending-active-certification-idtywindow-8-lifespan-of-a-pending-active-certification-idtywindow">8. Lifespan of a ‘pending’ active certification (<code>idtyWindow</code>) {#8-lifespan-of-a-pending-active-certification-idtywindow}</h4> -<p>When a new identity is created, it is stored in the ‘pool’ for a maximum of <code>idtyWindow</code> seconds. If the person hasn’t achieved member status by then, the certification will simply be cancelled.</p> -<h3 id="details-on-some-of-the-wots-peculiarities-at-the-genesis-block">Details on some of the WoT’s peculiarities at the genesis block.</h3> -<p>The aforementioned rules can only be enforced with an existing web. They cannot be observed when first creating the web, that is when defining the genesis block.</p> -<p>Only rules 2 and 5 can be observed at the genesis block.</p> -<p>The genesis block has to be manually created by the founding members. In practice this means that there must be a choice of which identities to include on the premise that all of them observe rules 2 and 5. In addition, the genesis block must be signed with the private key of one of these identities.</p> -<p>As soon as the genesis block has been created, the other identities can start mining the blockchain and the member who begat block #0 effectively looses the decision power he had at creation.</p> -<h3 id="why-these-rules-and-application-cases-in-the-g1">Why these rules and application cases in the Ğ1</h3> -<h4 id="distance-and-maximum-size-1-distance-and-maximum-size">1. Distance and maximum size {#1-distance-and-maximum-size}</h4> -<p>The distance rule is there to curb the maximum size of a Sybil region as well as that of the monetary community as a whole. The <code>xpercent</code> parameter prevents the creation of a ‘faction’ that could take hold of the blockchain.</p> -<figure> -<img src="https://duniter.org/en/images/wiki/wot-sybil.jpg" alt="Sybil region" /><figcaption>Sybil region</figcaption> -</figure> -<p>The Sybil regions are isolated from the rest of the graph in the sense that they can only receive certifications from other ill-intentioned Sybil members. As a consequence, the shortest edge/path between a legitimate member and a Sybil one has to have the attack’s author as an endpoint. The maximum depth the Sybil region can attain is therefore contingent on the distance between the attacking edge-s- and the xpercent% closest referent members, this distance is known as <code>stepAttackers</code>. The maximum size of a Sybil region created by <code>sigQty</code> members depends on the L parameter, defined as L = sigQty/sigStock:</p> -<div class="highlight"> -<pre><code>Maximum Sybil region size = (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L)</code></pre> -</div> -<p>The maximum size of the Web of Trust is given by the following formula:</p> -<div class="highlight"> -<pre><code>WoTmax = (sigStock)*L^(stepMax-1)</code></pre> -</div> -<p>However we know for a fact that members will never use all of their available certifications. Many studies have proven that we all know a maximum average of fifty people, let’s then replace sigStock by fifty:</p> -<div class="highlight"> -<pre><code>WoTavg= (50)*(sigQty/50)^(stepMax-1)</code></pre> -</div> -<p>Our goal with the Ğ1 is to create a community of about one million members enjoying the world’s first true <a href="https://en.wikipedia.org/wiki/Catallaxy">catallaxy</a> -free economy with a spontaneous order of things-. Let’s see how we can tweak the pair of sigQty and stepMax- to reach this size:</p> -<figure> -<img src="https://duniter.org/en/images/wiki/graph-WoTmoy.png" alt="graphe WoTmoy en fonction de sigQty et stepMax" /><figcaption>graphe WoTmoy en fonction de sigQty et stepMax</figcaption> -</figure> -<p>The maximum size of a Sybil region grows linearly with <code>sigQty</code> but exponentially with <code>stepMax</code>. Logic has it that we need to keep <code>stepMax</code> as low as possible to ensure sufficient strength to the web. The above graph shows that the lowest value of <code>stepMax</code> for a web of a million members is of 5. This is an order of magnitude and is likely to be much higher in reality, we cannot measure it for sure.</p> -<p>For <code>sigQty</code> we can choose a value of <strong>4</strong> for a web of <strong>1.5 million members</strong> or <strong>5</strong> for <strong>half a million members</strong>. Bear in mind these are gross figures and could be significantly higher, we are talking anywhere between 1 and 10 million in reality. Calculating WOTavg gives us a pretty good idea of how the web would scale bearing in mind that it considers all members are referent members too -which isn’t the case as explained previously-. Hence the maximum size of the web is likely larger, a ballpark figure of half a million is enough for now especially knowing that the smaller <code>sigQty</code> is, the easier it is to launch a Sybil attack -it’s easier to find four accomplices than five-. For security reasons we have settled on five:</p> -<p>stepMax = 5 sigQty = 5 sigStock >= 50</p> -<p>The maximum size of a Sybil region therefore is: <code>(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5))</code></p> -<p>with sigStock = 50 we have a Sybil region of: <code>45*(1-10^(5-stepAttackers))/(-9)</code></p> -<p>A good practice for protecting the web is to maximise <code>stepAttackers</code>. That’s why we decided that referent members in the genesis block had to be at least four steps away from each other.</p> -<p>Another way to keep a Sybil attack at bay, were it slow enough for members to notice it, would be for referent members to ‘stretch’ the web intentionally to limit the growth of the region by ensuring that the attackers’ legitimate certifications received in the first place aren’t renewed. But what if bot accounts were created and certified each other super fast and following all rules, how would we counter that? By introducing a minimum length of time between two certifications!</p> -<h4 id="time-is-our-friend-2-time-is-our-friend">2. Time is our friend {#2-time-is-our-friend}</h4> -<p>To help us deter a Sybil attack, we’ve decided to impose a minimum period of time between any two certifications issued from a single account. This parameter called <code>sigPeriod</code> affords us a greater chance to detect the formation of a ‘hostile’ faction.</p> -<p>Here is a graph showing the evolution of a Sybil region with the variation of <code>sigPeriod</code>:</p> -<figure> -<img src="https://duniter.org/en/images/wiki/impact_sig_period.png" alt="graph of the WoT's size according to sigPeriod and stepAttackers" /><figcaption>graph of the WoT's size according to sigPeriod and stepAttackers</figcaption> -</figure> -<p>As you’ll easily be able to tell, there is a strong link between the growth speed of the region and <code>sigPeriod</code>. As evidenced here, we need a <code>sigPeriod</code> high enough in order to ensure that the legitimate web can grow at least as fast as a Sybil region. In addition, the higher <code>sigPeriod</code> is, the more members will exercise their certification power gingerly, the action coming at a higher ‘cost’.</p> -<p>There are numerous advantages to giving <code>sigPeriod</code> a high value and no technical barriers to it, hence our choice of five days.</p> -<p>We could have also gone for days days -one week- for the sake of simplicity however there was an underlying idea behind our choice which was quite simply the pace of today’s life. Certifying someone can be a lengthy process as one needs to make sure he/she is correctly applying the Ğ1 licence and people nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea to allow one to certify at the end of every working week -five days- instead of a whole calendar one.</p> -<h4 id="trust-me-now-trust-me-forever-sigvalidity-msvalidity-3-trust-me-now-trust-me-forever-sigvalidity-msvalidity">3. Trust me now, trust me forever? (<code>sigValidity</code>, <code>msValidity</code>) {#3-trust-me-now-trust-me-forever-sigvalidity-msvalidity}</h4> -<p>There would be two main drawbacks to a lifetime membership in the Ğ1’s Web of Trust:</p> -<blockquote> -<p>First of all we need to take into account that some members will pass and those accounts should no longer produce the Universal Dividend. Secondly it is of the utmost importance that ‘rogue’ accounts can be excluded from the web at some point.</p> -</blockquote> -<p>To achieve this, certifications have a limited lifetime and members need to seek renewal from their peers after <code>sigValidity</code> time. On the other hand, this time can’t be too short that members would spend more time seeking renewal than they would exchanging in the currency. Furthermore, a certification with too short a lifetime would foster careless certifying behaviours. The act of certifying must have a ‘perceived’ cost high-enough to make it feel like an important act. Lastly, we also wanted this lifetime to be easy enough to remember. Historically speaking, we first settled on the values of <code>sigPeriod</code> and <code>sigStock</code>, meant one could issue all of his/her certifications in 495 days, one year was therefore not long enough. We deemed three years to bee much and that’s how we agreed on two years in the end.</p> -<p>Thinking that a deceased member could continue producing the UD for two long years without anyone benefitting from it was also something we needed to address. We choose a value of one year for <strong>msValidity</strong>. The act of renewing every year is done through one of the clients interacting with the blockchain, through a simple click on a button. This parameter is less important than others and is mostly there to ‘prune’ the web of past or inactive members who don’t renew their membership.</p> -<h4 id="keeping-the-pools-free-of-information-glut--idtywindow-sigwindow-mswindow-4-keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow">4. Keeping the pools free of information glut -(<code>idtyWindow</code>, <code>sigWindow</code>, <code>msWindow</code>) {#4-keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow}</h4> -<p>The pools need to be cleaned up on a regular basis to avoid them clogging up with information and to ensure that machines with less calculating power can still run a Duniter node.</p> -<p>To achieve this, identities with pending membership approval and the corresponding certifications have to remain the shortest time possible in the pool while still having a chance of making it into the blockchain.</p> -<p>For the Ğ1, our opinion was that two months would be enough for all potential certifiers to agree on a specific identity to certify. We also wanted a time period that would be easy enough to remember by all. We settled on two months, and gave this value to all three parameters <code>idtyWindow</code>, <code>sigWindow</code> and <code>msWindow</code>.</p> -<h4 id="avoiding-single-members-from-knowing-too-many-people-sigstock-5-avoiding-single-members-from-knowing-too-many-people-sigstock">5. Avoiding single members from ‘knowing too many people’ (<code>sigStock</code>) {#5-avoiding-single-members-from-knowing-too-many-people-sigstock}</h4> -<p>Many sociology studies have shown that we all know an average of fifty people. This of course is an average, some of us know more than fifty people, others much less. Once again we went for a number that would be easy to remember. Although <code>sigStock</code>’s impact on the size of a Sybil region is fairly limited, its value nonetheless has to be kept reasonable. We settled on hundred.</p> -<h4 id="avoiding-locking-minorities-xpercent-6-avoiding-locking-minorities-xpercent">6. Avoiding locking minorities (<code>xpercent</code>) {#6-avoiding-locking-minorities-xpercent}</h4> -<p>It’s easy enough to become a referent member, one of the Sybil strategies could therefore be to create a region of referent members. Such a region would grow slower than otherwise but could confer a locking power to its members by using the distance rule. That’s why the distance rule cannot be calculated on 100% of the referent members. Hence the introduction of the <code>xpercent</code> parameter which defines the percentage of referent members needing to be less than five edges -steps- from each other.</p> -<p>This percentage needs to be low enough to prevent the formation of a locking minority -referent Sybil members being too far from legitimate referent members-. On the other hand, it needs to be high enough so as to restrict the maximum size of the Sybil region through the distance rule. The <code>xpercent</code> parameter was one of the hardest to define, we therefore reserve ourselves the right of modifying its value during the Ğ1 experiment.</p> -<p>We were inspired by the <a href="https://en.wikipedia.org/wiki/Pareto_principle">Pareto principle</a>: if at least 20% of members give good density to the web, 80% of the referent members will be five or less steps from any other member -referent or non-. The maximum value for <code>xpercent</code> is therefore 80%, anything above that and the distance rule could be too restrictive for legitimate use cases. With security our top concern, we chose the maximum value of 80%.</p> -<h4 id="spam-protection-with-msperiod-7-spam-protection-with-msperiod">7. Spam protection with (<code>msPeriod</code>) {#7-spam-protection-with-msperiod}</h4> -<p>This parameter stands out a bit on its own, as it was added after the genesis block. It is there to protect the Duniter P2P infrastructure against ‘spam’ attacks. We had to think of a strategy against attacks such as high-frequency membership renewal requests -i.e: in every block, every five minutes- or worse still, hundreds of these requests per minute to flood the Duniter nodes. Without such limits, nodes are supposed to address all renewal requests, even in cases where they were last published five minutes ago! The <code>msPeriod</code> parameter was given the same value as <code>idtyWindow</code>, <code>sigWindow</code> and <code>msWindow</code>, i.e. two months.</p> -<h2 id="proof-of-work-with-personal-difficulty">Proof of Work with personal difficulty</h2> -<p>As each P2P cryptocurrency, Duniter has a way to synchronize its peers. It uses a proof of Work (PoW) to write the Blockchain on a regular basis, much like BitCoin. However, Duniter has a unique asset : the WoT, where each member represents a unique living human.</p> -<p>This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each “winning” member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. The knowledge of the whole network is not needed.</p> -<p>Another strong difference is that forging peers are not rewarded by the protocol. There is no economical incentive on forging lots of blocs, neither on having a lot of computing power.</p> -<p>One could say that Duniter uses a PoW that needs very low energy consumption compared to BitCoin : an “ecological” PoW ?</p> -<!-- source : https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/ --> -<h3 id="why-do-we-need-proof-of-work">Why do we need Proof of Work ?</h3> -<p>Duniter nodes share a database as part of a p2p environment. The proof of work (PoW) allows machines to synchronize with each other. In Duniter’s case, the blockchain is our database, and acts as a ledger keeping a trace of all transactions, status of the WoT and more. How can we let several machines add data (ie: a transaction) at the same time? In addition, how do we settle on how much time has gone by since the blockchain was last updated? Agreement on time is of the utmost importance as we want to create Universal Dividends on a regular basis, and keep track of membership status, both in human time.</p> -<p>Proof-of-work provides a clever solution to both problems: 1. Any machine can write into the blockchain (create a new block) but is only authorised to do so if it has previously solved a mathematical equation that require a certain amount of work. The challenge has to be hard enough to prevent two machines to solve it at the same time, ensuring the unicity of a block’s creator.</p> -<ol start="2" type="1"> -<li>Solving this challenge takes a certain amount of time, which depends on the calculating power of the whole network. This provides a common ground for defining the needed time reference. A block time is set (ie: 1 block = 5 min) and Duniter adapts the challenge difficulty to get an <em>average</em> duration corresponding to this block time.</li> -</ol> -<h3 id="only-members-can-mine">Only members can “mine”</h3> -<p>One of Duniter’s major differences with other PoW-based cryptocurrencies is that only members are allowed to author blocks. Each block is signed with the member’s private key, allowing the algorithm to determine a <em>personalised difficulty</em>.</p> -<p>This personalised difficulty eliminates the rat-race for the most sophisticated and powerful mining equipment. Another benefit is the fact that no “supercomputer” can take control of the blockchain. Lastly, Duniter implements a rotation in forging members thanks to this personalized difficulty.</p> -<p>This lightweight PoW is much less energy-consuming than other PoW cryptocurrencies. Members can mine with anything from a raspberry pi to a privacy-first internet cube.</p> -<h3 id="how-does-it-work">How does it work?</h3> -<h4 id="the-hash-aka-digest">The hash (aka digest)</h4> -<p>Example of a valid hash:</p> -<div class="highlight"> -<pre><code>00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653</code></pre> -</div> -<p>As you can see this hash starts with five zeros which was very hard to achieve and took a lot of <em>work</em> for someone’s computer. Hence the term “proof of work”.</p> -<h4 id="the-common-difficulty">The common difficulty</h4> -<p>A common difficulty is needed to settle on a yardstick for our time reference. Its role is to make sure the blockchain moves forward at a steady pace - one block every <code>avgGenTime</code> seconds, <code>avgGenTime</code> being one of the 20 parameters behind the Duniter protocol-.</p> -<p>This difficulty’s initial value can be set to any arbitrary value (<code>70</code> in Duniter <code>v1.5.x</code>) and then acts as a spring, regulating blocktime creation by increasing itself if the creation interval drops under <code>avgGenTime</code> and vice-versa.</p> -<h5 id="how-is-difficulty-applied">How is difficulty applied?</h5> -<p>The numeric value of difficulty is taken from an array of possible hashes out of all possible hashes. In duniter v1.5.x the hash of a block is its sha256 hexadecimal hash.</p> -<p>To understand the difficulty, we make a euclidiean division of the difficulty by 16.</p> -<p>Here’s an example with a difficulty value of <code>70</code> : 70 // 16 = <strong>4</strong> with a remainder of <strong>6</strong>. The valid hashes are the ones starting with four zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). The valid hashes are then written as starting with : <code>0000[0-9]</code>. This is a bit different from Bitcoin, where the difficulty is only ruled by the number of zeroes.</p> -<blockquote> -<p>Fine, but the hash of a mined block will never change and there’s no reason it should start with a given sequence of numbers. So how then can we make sure a block hash starts with exactly the sequence needed?</p> -</blockquote> -<p>Enter the nonce, short for “number once”. When a member is forging a new block, his computer freezes the block’s content and changes the Nonce until the hash reaches the required number of zeroes.</p> -<h5 id="the-nonce">The Nonce</h5> -<p>The nonce allows us to mine a new block by finding a hash. The hash value allows us to determine the difficulty level of the proof-of-work performed. Examples of possible Nonce values:</p> -<ul> -<li>10100000112275</li> -<li>10300000288743</li> -<li>10400000008538</li> -<li>10700000079653</li> -<li>10300000070919</li> -</ul> -<p>In reality the <code>Nonce</code> value follows a pre-determined format akin to <code>XYY00000000000</code>. The Nonce’s value isn’t the number of attempts but rather a value within a set of possible ones. This is how the Nonce is built:</p> -<ul> -<li><p>X is a number assigned to a specific peer. Let’s assume that someone has several nodes each with the same private key, this would lead to possible collisions if this person were to mine the same block with different nodes. Each block will therefore have its own unique X to prevent this from happening.</p></li> -<li><p>Y is the number of cores of the processor. The Nonce starting with <code>107[…]</code> belongs to a seven cores processor, while <code>199[...]</code> could be the proof generated by a 99 cores processor.</p></li> -</ul> -<p>The rest of the Nonce, the part that follows after the XYY, is the numerical space for this individual node and is unique to each of the CPU’s core. This space is comprised of eleven digits (<code>00000000000</code>). For the sake of accuracy, we use the term CPU in the wider sense, it can be understood as a bi-CPU for example. We take into consideration the number of cores for the resulting PoW.</p> -<h3 id="personalised-difficulty">Personalised difficulty</h3> -<p>Earlier in this article, we explained that the personalised difficulty is the new and key concept that sets Duniter apart from other <em>PoW-based</em> cryptocurrencies such as Bitcoin.</p> -<p>Here is how this personalised difficulty is calculated and assigned:</p> -<p>It is determined by a combination of two different constraints with complimentary roles: the <strong>exclusion factor</strong> and the <strong>handicap</strong>.</p> -<p>Let <code>powMin</code> be the common difficulty, <code>exFact</code> a member’s exclusion factor and <code>handicap</code> their handicap. This member’s personalised difficulty <code>diff</code> is:</p> -<div class="highlight"> -<pre><code>diff = powMin*exFact + handicap</code></pre> -</div> -<h4 id="understanding-exfact-the-exclusion-factor">Understanding <code>exFact</code>, the exclusion factor</h4> -<p>Members who have never produced blocks or haven’t for quite some time are assigned an exclusion factor of <code>1</code>. Their personalised difficulty is therefore simply the sum of <code>powMin + handicap</code>.</p> -<p>Before reading on, let’s precise the role of this exclusion factor. When a member adds a block to the chain, his <code>exFact</code> jumps up from one to a very high value, to prevent them from forging other blocks immediately after and taking control of the blockchain.</p> -<p>The exclusion factor will then rapidly return to one. This delay is expressed as a number of blocks. It is calculated as a proportion of the number of members forging. In the Ğ1’s case, this proportion is 1/3, meaning that if there are fifteen members currently forging, the member’s exclusion factor will drop down to one after five blocks.</p> -<blockquote> -<p>What is intended by “the number of members forging”?</p> -</blockquote> -<p>We mean the number of members trying to create the next block. In reality, there is no way to precisely know how many members are calculating at any given time, because it is impossible to view the entire network. But we need this information, whithout which assigning a personalised difficulty is impossible. To achieve this, Duniter looks back at the blockchain and assumes that there is as much members forging as those who have found at least one block in the last X blocks, minus the very last one.</p> -<blockquote> -<p>Hox is X determined?</p> -</blockquote> -<p>We use the concept of <strong>current window</strong>. X’s value is equal to the size of this window. Let’s see how it works:</p> -<ul> -<li><p><code>issuersFrame</code> is the size of the current window in blocks.</p></li> -<li><p><code>issuersCount</code> the number of members who have calculated at least one block during the current window.</p></li> -</ul> -<p>Both <code>issuersFrame</code> and <code>issuersCount</code> are block fields. When first starting a blockchain, the very first block has an <code>issuersFrame=1</code> and an <code>issuersCount=0</code>. The genesis block is excluded as there are no members in the current window!</p> -<p>From the second block onwards (block #1) we track the variation of <code>issuersCount</code>. The member having mined block #0 enters the current window and in block #1 we will therefore mention <code>issuersCount=1</code>.</p> -<p><code>issuersFrame</code> then varies as follows:</p> -<ul> -<li>if <code>issuersCount</code> increases by N (with a maximum step of N = 1), then <code>issuersFrame</code> will increase by one unit over a period of 5N blocks.</li> -<li>Conversely, if <code>issuersCount</code> decreases by Y (with a maximum step of Y = 2 = current window inching forward + loss of one calculating member), then <code>issuersFrame</code> will decrease by one unit during 5Y blocks.</li> -<li>When such events overlap, <code>issuersFrame</code> evolves as so :</li> -</ul> -<table> -<thead> -<tr class="header"> -<th>bloc</th> -<th>event</th> -<th>issuersFrame</th> -</tr> -</thead> -<tbody> -<tr class="odd"> -<td>T</td> -<td>Babar writes a block and enters issuersCount</td> -<td>160</td> -</tr> -<tr class="even"> -<td>T+1</td> -<td>Celeste leaves issuersCount</td> -<td>160 +1 = 161</td> -</tr> -<tr class="odd"> -<td>T+2</td> -<td>N/a</td> -<td>161 +1 -1 = 161</td> -</tr> -<tr class="even"> -<td>T+3/4/5</td> -<td>N/a</td> -<td>161 +1 -1 = 161</td> -</tr> -<tr class="odd"> -<td>T+6</td> -<td>N/a</td> -<td>161 -1 = 160</td> -</tr> -</tbody> -</table> -<p>The calculation can be found under rules <a href="https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g05-headissuersframe">BR_G05</a> and <a href="https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g06-headissuersframevar">BR_G06</a> of the DUP protocol.</p> -<blockquote> -<p>Let’s go back to the personalised difficulty.</p> -</blockquote> -<p>We explained that <code>exFact</code> spikes immediately after the member has found a block. It decreases then rapidly to <code>1</code> after a number of blocks <code>X = 1/3 * issuersCount</code>. Let’s see precisely how we calculate <code>exFact</code>:</p> -<ul> -<li><p><code>nbPreviousIssuers</code> is the value of issuersCount at the last block <code>N</code> found by the member.</p></li> -<li><p><code>nbBlocksSince</code> is the number of blocks found by the rest of the network since block <code>N</code>.</p></li> -<li><p><code>percentRot</code> is the number of <em>not excluded</em> peers we want. It is a monetary parameter, its value is 0.67 for Ğ1 currency.</p></li> -</ul> -<div class="highlight"> -<pre><code>exFact = MAX [ 1 ; FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) ]</code></pre> -</div> -<p>The FLOOR is a simple truncate function. For <code>exFact</code> to exclude the member, we need :</p> -<blockquote> -<p>(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2</p> -</blockquote> -<p>We can see that the member is not excluded if <code>nbBlocksSince</code> is greater than 1/3 of the calculating members. Take as an example nbPreviousIssuers = 6 and nbBlocksSince = 3:</p> -<blockquote> -<p>(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1</p> -</blockquote> -<p>However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded: > (0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2</p> -<p>Moreover if the last block was authored by the said member, then: > <code>nbBlocksSince=0</code> and > <code>exFact</code> = <code>0.67 * nbPreviousIssuers</code></p> -<p>ExFact value increases according to the number of members calculating. Thus, if there is enough members calculating, even mining farms would be excluded. We have therefore succeeded in our intent to deter attempts to seize the blockchain and its currency.</p> -<p>However, at any time t, the two-thirds of calculating members all have an exclusion factor of <code>1</code>, even though they might not all have the same computational power at hand. If the personalised difficulty only took into account the exclusion factor, then only the members with the highest computational power from the remaining third would be able to author new blocks and the other 2/3s would almost always be excluded. Lesser machines wouldn’t stand a chance…</p> -<h4 id="the-handicap">The handicap</h4> -<p>The handicap is the second parameter of the personalised difficulty. Its main role is to improve the rotation of forging peers. A higher handicap is assined to members with higher calculating power, so lesser machines can also compute blocks. As a consequence, there is no incentive on forging with powerful computers. Security can be achieved with less computing power than with pure PoW.</p> -<p>The aim is to handicap the half that has authored most blocks (the most powerful half) to favour the other one. So, the handicap formula will use the median number of blocks authored by peers within the current window.</p> -<ul> -<li><p><code>nbPersonalBlocksInFrame</code> is the number of blocks authored by a single member within the current window.</p></li> -<li><p><code>medianOfBlocksInFrame</code> is the median number of blocks written by the calculating members during the same timeframe.</p></li> -</ul> -<div class="highlight"> -<pre><code>handicap = FLOOR(LN(MAX(1;(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)) / LN(1.189))</code></pre> -</div> -<p>Let’s unwrap the formula: <code>(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)</code> is simply the ratio between the number of blocks authored by the peer and the median number of blocks. For example, if a peer has authored <code>9</code> blocks in the current window and the median is <code>5</code>, then the ratio will be <code>(9+1)/5 = 2</code>. The MAX function allows us to ensure that the handicap has a value at least equal to <code>1</code>.</p> -<p>The Napierian Logarithm of this ratio prevents the handicap from becoming excluding. We want the handicap to level the calculating field so that all peers stand a chance, not to exclude peers.</p> -<p>If we want the handicap to be applied as soon as the median is reached, we’d have to divide it by <code>LN(1)</code>, the problem is that we’ve already set a minimum value of <code>1</code> with the MAX function, so if we were to divide the ratio by <code>LN(1)</code> all calculating peers would have a handicap >= <code>1</code>. In addition, is it really fair to handicap a member who’s right on the median?</p> -<p>That’s why we went for <code>1.189</code> rather than <code>1</code>. A member has to be at least <code>18.9%</code> above the median to be assigned a handicap. 18.9% is actually 16^(1/16), the difficulty factor between two levels of the proof work (hexadecimal hash).</p> -<p>To conclude, you have to remember that :</p> -<ul> -<li>the handicap is indexed on the logarithm of the ratio to the median,</li> -<li>handicap is only applied on members whose ratio to the median is greater than the ratio between two levels of the proof-of-work’s difficulty.</li> -</ul> -<h2 id="conclusion">Conclusion</h2> -<!-- source : https://duniter.org/en/theoretical/ --> -<p>Duniter’s Blockchain can be compared to Bitcoin’s : a common document retracing the history of the currency. However, Duniter registers not only trades, but also the history of relationships in the community as a mean to identify a human to a digital account. This way, Duniter has information about the fondamental reference of RTM : living humans. A libre Currency can be issued thanks to the Universal Dividend.</p> -<p>More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers while maintaining a good security on the network.</p> -<p>The ultimate goal of Duniter project is to allow people to participate in a libre economy, thanks to a libre currency. What is a libre economy ? The Relative Theory of Money defines it through four economic liberties :</p> -<ul> -<li>The freedom to choose your currency system: because money should not be imposed</li> -<li>The freedom to access resources: because we all should have access to economic & monetary resources</li> -<li>The freedom to estimate and produce value: because value is a purely relative to each individual</li> -<li>The freedom to trade with the money: because we should not be limited by the avaible money supply</li> -</ul> -<p>Those 4 economic freedoms should be understood together, not exclusively. Plus, “freedom” has to be understood as “non-nuisance”. So here, freedom does not mean the right to take all of a resource (like water source in a desert) so no more is available to the others. Now you get it, this is the goal: free economy through free currency.</p> -<h2 id="duniter-projects-sources">Duniter project’s sources :</h2> -<ul> -<li>Theoretical, by Cgeek: https://duniter.org/en/theoretical/</li> -<li>Lock conditions, by Inso: https://duniter.org/en/transactions-0-2-overview/</li> -<li>Individualised Proof of Work, by Elois: https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/</li> -<li>Deep dive into the Web of Trust, by Elois: https://duniter.org/en/deep-dive-into-the-web-of-trust/</li> -<li>Whitepaper sources: https://git.duniter.org/communication/duniter-whitepaper</li> -</ul> -<h2 id="other-sources">Other sources :</h2> -<ul> -<li>Relative Theory of Money, S.Laborde, 2010: http://en.trm.creationmonetaire.info/</li> -<li>Bitcoin Whitepaper, S.Nakamoto, 2008: https://bitcoin.org/bitcoin.pdf</li> -<li>Circles Whitepaper, A.Milenius, 2018: https://github.com/CirclesUBI/docs/blob/master/Circles.md</li> -<li>The Sibyl Attack, J.R.Douceur: https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</li> -</ul> -<!-- travaux en theorie des graphes pourla TdC --> -</article> -</main> -</body> -</html> -<!--doctype html--> -<html lang='en' > -<head > -<title> -Duniter Whitepaper -</title > -<meta charset='UTF-8' /> -<link - rel='stylesheet' - href='bulma.css' > <link - rel='stylesheet' - href='main.css' > -<script src='js/jquery.js' ></script > -<script src='js/toc.js' ></script > -<script type='javascript' > - if ($) { - $('#whitepaper').tableofcontents({ id: '#toc' }); - } - </script > -</head > -<body> -<main> -<div id="toc"> - -</div> -<article id="whitepaper" class="content"> -<h1 id="duniter-a-libre-currency-blockchain-generator-1">Duniter : A libre currency blockchain generator !</h1> -<h2 id="abstract-todo-1">Abstract (TODO)</h2> -<h2 id="introduction-1">Introduction</h2> -<p>Duniter is a software to create and manage “libre currencies”. Libre currency is a concept defined by S.Laborde in the Relative Theory of Money (RTM) that was published in 2010. This theory demonstrates the possibility of an invariant monetary unit : the Universal Dividend. Doing so, the RTM answers the question :</p> -<blockquote> -<p>How should a currency be created to match the principle of equality between all humans ?</p> -</blockquote> -<p>The results of this demonstration implies a monetary creation :</p> -<ul> -<li>on a regular basis</li> -<li>for each human being</li> -<li>which amount has to be reassessed on fixed intervals according to a fixed formula.</li> -</ul> -<p>Thus, Duniter project will associate a human to a digital identity. It will use a Web of Trust with specific rules. As the number of members may evolve, the Universal Dividend has to be created according to the formula :</p> -<blockquote> -<p>UD(t+1) = UD(t) + c² * ( M(t) / N(t) )</p> -</blockquote> -<p>Duniter is based on a decentralized Blockchain. This technical choice allows irreversibility of transaction and uncensorability of trades and identities. While inspired by Bitcoin, Duniter uses a Web of Trust and the Proof of Work to secure the computation network, thus making obsolete the power race model used in Bitcoin.</p> -<p>The first currency created through Duniter is Ğ1 (say “June”). It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software.</p> -<h2 id="state-of-the-art-bitcoin-case-1">State of the art : Bitcoin case</h2> -<!-- source : https://duniter.org/en/theoretical/ --> -<p>Duniter uses the crypto-currency concept introduced by Bitcoin, which is to use cryptographic tools such as <em>signatures</em> to create digital currencies. Duniter fits this definition, but it has completely different principles than Bitcoin : the Web of Trust and the Universal Dividend . These differences are on both monetary and technical aspects.</p> -<h3 id="monetary-creation-of-bitcoin-a-space-time-asymmetry-1">Monetary creation of Bitcoin : a space-time asymmetry</h3> -<p>Space-time asymmetry refers to the relative access of individuals to newly created money (Relative Theory of Money, S.Laborde, 2010). Concretely, all existing currencies (c. 2015) are both spatially and temporally asymmetrical for their users. Let's take Bitcoin as an example to understand why.</p> -<h4 id="spatial-asymmetry-1">Spatial asymmetry</h4> -<p>When new Bitcoins are created, <em>only some Bitcoin users</em> (the miners) are given new Bitcoins, while everyone else get nothing. <strong>We believe this is the <em>first</em> injustice.</strong> However, some might say:</p> -<blockquote> -<p>"Miners used their <em>electricity and time</em> to get it!"</p> -</blockquote> -<p>... we would answer that this work <em>shouldn't have been rewarded by newly created Bitcoins</em>. New Bitcoins should be distributed to the whole Bitcoin community. Miners should be rewared another way, but not by money issuance. Of course, Bitcoin can't create money through Basic Income since <em>Bitcoin users are not strongly identified</em>, and one might benefit from money creation multiple times if he owned several wallets. Duniter gets rid of this problem completely by identifying its users and giving <em>the same amount of Basic Income to everyone</em>.</p> -<h4 id="temporal-asymmetry-1">Temporal-asymmetry</h4> -<p>Bitcoin has an absolute limit of 21 million BTC (its unit of currency), which means ever fewer bitcoins will be created over time until no new BTC are being generated. So, once the first adopters have mined every bitcoin, how will future joiners get Bitcoins? Just like Euros or Dollars: to get money, they will have to work for the ones who already own it. <strong>We believe this is the <em>second</em> injustice.</strong> Every member of a monetary community should be equal concerning monetary creation, and get the same relative amount of money over time, <em>even if they are a late adopter</em>. Duniter aims to fix this by making the Universal Dividend (a.k.a. <em>UD</em>) <em>grow by the time</em> (S.Laborde, 2010) according to precise rules, thus making members equal toward money issuance on a half-lifespan.</p> -<h4 id="a-solution-1">A solution</h4> -<p>Bitcoin has taught us that <em>it is possible</em> to create a currency system allowing one to both create digital money and to exchange it without a central authority. What we need to change is <em>the way money is issued</em> so we finally have a symmetrical system. We need Bitcoin <em>+ Universal Dividend</em>. But Universal Dividend <em>implies</em> that the community consists of only identified people. This is where the Web of Trust (WoT) comes into place. This concept, introduced by cryptography with the <a href="https://www.wikiwand.com/en/Pretty_Good_Privacy">OpenPGP</a> format, allows us to identify people in a <em>decentralized</em> manner. It works as follows: each person creates <em>a personal identity</em> that is linked to its cyptographic certificate. The identity must be confirmed by others members who use their own cryptographic key. It is that simple: <strong>people choose who is part of the community and who is not, not a central authority.</strong></p> -<blockquote> -<p>Duniter however won't use OpenPGP for its cryptographic features: Elliptic Curves will be used instead for the conciseness of its generated keys and its pratical advantages. Duniter has its own Web of Trust principles, that shall be exposed later.</p> -</blockquote> -<h3 id="proof-of-work-mining-a-power-race-todo-1">Proof-of-Work mining : a power race (TODO)</h3> -<p>In Bitcoin Model, the calculation and incentive principles cause a power race : new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. The goal of Duniter is to make blockchain validation much less energy and hardware consuming while keeping a strong level of security. As a consequence, even low-power hardware can secure Duniter Blockchain, which leads to a better decentralization of forging operations.</p> -<h3 id="other-projects-1">Other projects ?</h3> -<h4 id="what-about-pos-1">What about PoS ?</h4> -<p>When conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead to placing power over the currency in the richests hands : this is contrary to the symmetical principles of Duniter.</p> -<p>Now that PoS is well-tested, one could try to use Duniter’s WoT to create a PoS-like algorithm with equal chances among members. But this is not our aim for now.</p> -<h4 id="what-about-directed-acyclic-graph-1">What about Directed Acyclic Graph ?</h4> -<p>The Circles project uses DAG in a basic income cryptocurrency. However, in this project, one peer cannot know the whole monetary mass and the exact number of other peers. The calculation of Universal Dividend <code>UD = c * M/N</code> seems impossible, since we know neither M nor N.</p> -<h2 id="duniters-blockchain-1">Duniters Blockchain</h2> -<!-- source : https://duniter.org/en/theoretical/ --> -<p>Duniters Blockchain follows the basic principles of Bitcoins. This is essential for synchronization between peers, as to prevent double-spend attacks. However, Duniters Blockchain will store different informations than Bitcoins.</p> -<p>The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no <em>generation transaction</em> exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either:</p> -<ul> -<li>a former transaction (as in Bitcoin)</li> -<li>a Universal Dividend (specific to Duniter).</li> -</ul> -<p>Duniters Web of Trust is also written in the Blockchain. The identity of each member gets registered much like transactinos are, with a strong link to the time reference. Thus, the Blockchain is a representation of a space-time frame of reference, where “space” are members of the WoT and “time” the basci blockchain units : the blocks. On each point of time, one can determain whick account is legitimate to create the UD, only with a blockchain analysis.</p> -<h3 id="spam-countermeasures-todo-1">Spam countermeasures (TODO)</h3> -<p>An issue of most cryptocurrency projects is to prevent the common ledger from growing too much and require lot of storage and computing power to be usable. In particular, we don’t want an attacker to be able to make the Blockchain grow too fast. Most projects implement transaction fees as a way to prevent this, making the attacker lose money. We don’t want to do this since a currency with automatic fees on transactions is no more neutral. Several countermeasuers against such spam attacks are implemented.</p> -<!-- see : https://forum.duniter.org/t/sans-frais-de-transaction-comment-resister-aux-attaques/3846/25 (implemented ?)--> -<ul> -<li>output minimal de 100*Unitbase / 1 unité -> empêche un attaquant de faire grossir la BC et les index trop vite (DUBP v12)</li> -<li>chaînage maximal des tx</li> -<li>seuils de dépense (implémentés ? en tout et par issuer ?)</li> -</ul> -<h3 id="scaling-1">Scaling</h3> -<p>Most of the time, the scaling issue rises for distributed systems that should work on a very large scale. This is not the case of Duniter, for multiple reasons :</p> -<ul> -<li>Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don’t want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT limits its size to around 16 million members.</li> -<li>Duniter’s aim is to be used to create <em>multiple</em> libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community.</li> -</ul> -<p>However, Duniter has two assets that might be used if the number of users grow.</p> -<h4 id="dynamic-block-size-1">Dynamic block size</h4> -<p>While Bitcoin has a fixed block size, Duniters blocks size can evolve. On low use of the blockchain, the maximal block size is 500 bytes. On high use of the blockchain, the maximal block size would be 110% of the average size of the current window blocks( <em>current window</em> will be described in the PoW part). This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it.</p> -<div class="{highlight}"> -<p>block_size < max(500 ; CEIL(1.10 * (average block size))</p> -</div> -<h4 id="lightning-networks-1">Lightning Networks</h4> -<p>The Lightning Networks allow almost instant and off-chain transactions. They were first implemented on Lightcoin, and are now on Bitcoin. One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. While not available yet, this payment channel might get implemented when needed.</p> -<h2 id="duniter-web-of-trust-1">Duniter Web of Trust</h2> -<!-- source : https://duniter.org/en/deep-dive-into-the-web-of-trust --> -<h3 id="basic-principles-1">Basic Principles</h3> -<p>In order to identify “members” account - which create monetary units - from other accounts, Duniter uses a Web of Trust. This can be summarized into few principles:</p> -<ul> -<li>Each account becomes a member if it received a minimal number of certifications (5 for Ğ1 currency)</li> -<li>Only members accounts can send certifications. Certifications have a limited lifespan.</li> -<li>A certification indicates that the sender accepts the receiver as a legitimate identity.</li> -</ul> -<p>The aim of the WoT is to identify a blockchain account to a living human. Each member of the Ğ1 currency signs a licence stating that they will only certify humans they know well (among other rules). Thus, if a member is part of an attack on the currency, they can be found by mutual friends. The security of Ğ1 currency stands on:</p> -<ul> -<li>Corroborating informations on members (5 certifications)</li> -<li>Peer pressure by close relatives</li> -<li>Law if the licence has not been respected.</li> -</ul> -<p>Note that non-members accounts can use the currency, but cannot create money. They can be used by individuals as secondary wallets, or by institutions.</p> -<p>However, the WoT does not rely only on trust betwenn people. Rules have been added to increase the security, and we will present them.</p> -<h3 id="why-do-we-need-a-web-of-trust-1">Why do we need a Web of Trust?</h3> -<p>There are two reasons we need it :</p> +<p>We want to make sure that each member can only have one account. As we all know, achieving zero-risk isn’t possible<a href="#fn9" class="footnote-ref" id="fnref9"><sup>9</sup></a>. Our goal is therefore not to create a WoT within which fraud would be absolutely impossible, but instead to discourage it. Here is a rewording of our goal in 4 smaller ones :</p> <ol type="1"> -<li>To make sure that only one Universal Dividend is produced per member at each specified creation interval -in the Ğ1’s case this interval is set as daily <code>86 400</code> seconds-, it is the <em>monetary parameter</em> known as <code>dt</code>-.</li> -<li><p>To identify the nodes hashing the blocks and assign them each a personalised difficulty. This custom difficulty <a href="https://en.wikipedia.org/wiki/Proof-of-work_system">proof of work</a> is there to avoid the blockchain’s validation mechanism becoming too centralised as is the case with many 'non-libre’ cryptocurrencies.</p> -<blockquote> -<p>Wait, what’s a ‘monetary parameter’ ?</p> -</blockquote></li> -</ol> -<p>Every currency implementing Duniter has its own blockchain whose behaviour is dictated by a set of ‘parameters’ -defined in block zero, the so-called genesis block- that can be tweaked to achieve the desired results. At the time of writing this article, the Duniter protocol -aka DUP- has a total of 21 parameters of which 10 are for the WoT alone. We’ll focus on these 10.</p> -<p>Suffice to say that in the Ğ1’s case, the DU is created every 24 hours -86 400 seconds- but this interval -set through the time derivative <code>dt</code> parameter- can have a different value in an other implementation of the protocol.</p> -<p>I won’t write about the second parameter having to do with the proof of work, it’s outside our scope here, just know that the Web of Trust allows us to <strong>identify</strong> the members providing hashing power, which we couldn’t do without it. This crucial feature means we can impose a rotation between the members hashing the blocks so that no single rich individual or group invests in a giant ‘hash farm’ and takes a hold of the blockchain, paralysing the community!</p> -<p>Let’s go back to the first objective: to make sure that each member can only have one account. As we all know, achieving zero-risk isn’t possible, our goal is therefore not to create a WoT within which fraud would be absolutely impossible but instead to discourage it. Here is a rewording of our goal in 4 smaller ones :</p> -<ol type="1"> -<li>To make the certification process lengthy enough that all members exercise due diligence and are wary of risks.</li> -<li>To make fraudulent acts as hard as we can to the extent that they become pointless.</li> -<li>To ensure that any Sybil attacks have a negligible impact on the currency -<em>by ensuring that illegitimate double Universal Dividends have no significant bearing on the legitimate monetary mass</em>-</li> -<li>To slow the growth of ‘Sybil regions’ to give enough time for the community to react and isolate the threat.</li> +<li>Make the certification process lengthy enough that all members exercise due diligence and are wary of risks.</li> +<li>Make fraudulent acts as hard as we can to the extent that they become pointless.</li> +<li>Ensure that any Sybil attacks have a negligible impact on the currency by ensuring that illegitimate double Universal Dividends have no significant bearing on the legitimate monetary mass</li> +<li>Slow the growth of ‘Sybil regions’ to give enough time for the community to react and isolate the threat.</li> </ol> <blockquote> -<p><strong>Wait, a Sybil what ?</strong></p> +<p><strong>Sybil attack</strong> : A Sybil attack is an attack perpetrated on a reputation system through the creation of fake identities. A Web of Trust is a specific instance of a Reputation System.</p> </blockquote> -<p>A <a href="https://en.wikipedia.org/wiki/Sybil_attack"><strong>Sybil attack</strong></a>, is the name given to attacks perpetrated on a reputation system through the creation of fake identities. A Web of Trust is a specific instance of a <a href="https://en.wikipedia.org/wiki/Reputation_system"><strong>Reputation System</strong></a>.</p> <p>There are plenty of Sybil attack scenarios we can think of and just as many reasons why their perpetrators would want to carry them out. Our objective is that the configuration of the WoT protects both users and its IT backbone infrastructure against these attacks.</p> -<p>This means that micro-attacks performed by small groups of individuals looking for personal enrichment are of no interest to us. The web’s role isn’t to deter these attacks, this being instead the role of the community. Just like the town you live in is responsible for providing your tap water and electricity but isn’t responsible for any burglaries etc. Much in the same way, Duniter’s WoT guarantees us all a functional currency and that’s quite a feat in itself!</p> -<h3 id="the-importance-of-having-our-own-certification-system-1">The importance of having our own certification system</h3> -<p>We are regularly offered to switch over to third-party or state-owned authentication systems but these are centralised and go against the principles of our community. We feel that we would lose our independence and universality by adopting a state-controlled system. People without an official state-provided identity or homeless people would also run the risk of being excluded from the WoT. It is of the utmost importance that we remain free from any state or corporation. To this day we depend only on the Internet and yet, were it to fail, there are already alternatives being tested around the world for a decentralised network.</p> -<h3 id="a-few-foundational-concepts-on-graph-theory-a-bit-of-vocabulary-1">A few foundational concepts on graph theory : a bit of vocabulary</h3> +<p>This means that micro-attacks performed by small groups of individuals looking for personal enrichment are of no interest to us. The web’s role isn’t to deter these attacks, this being instead the role of the community. Just like the town you live in is responsible for providing your tap water and electricity but isn’t responsible for any burglaries, etc. Much in the same way, Duniter’s WoT guarantees us all a functional currency, but do not detect small fraud.</p> +<h3 id="own-certification-system">3.3. The importance of having our own certification system</h3> +<p>Centralized identification systems can achieve the goal we want. State Identification is an example. However, this has many drawbacks :</p> +<ul> +<li>The authority may have arbitrary criteria for identification, for example preventing people without an official state-provided identity or homeless people to be included in the WoT.</li> +<li>Payment might be required to get identified, thus making the monetary creation not “free”.</li> +<li>The authority is a point of failure for any attacker.</li> +</ul> +<p>It is of the utmost importance that we remain free from any state or corporation. The WoT is an answer to this criterium. To this day we depend only on the Internet and yet, were it to fail, there are already alternatives being tested around the world for a decentralised communication network.</p> +<h3 id="graph-theory-vocabulary">3.4. A few foundational concepts on graph theory : a bit of vocabulary</h3> <ul> <li><p><strong>Graph</strong>: set of points -called ‘vertices’- joined by edges -called paths/walks-.</p></li> -<li><p><strong>Simple graph</strong>: a graph with no loops and with no multiple edges. That is, each edge connects two distinct endpoints and no two edges have the same endpoints. A simple edge is an edge that is not part of a multiple adjacency -of edges-. In many cases, graphs are assumed to be simple unless specified otherwise. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a></p></li> -<li><p><strong>Directed graph</strong>: a graph in which the edges have a distinguished direction, from one vertex to another. A directed edge can also be called a path or walk. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a> Arrow A –> B is therefore different from arrow B –> A.</p></li> +<li><p><strong>Simple graph</strong>: a graph with no loops and with no multiple edges. That is, each edge connects two distinct endpoints and no two edges have the same endpoints. A simple edge is an edge that is not part of a multiple adjacency -of edges-. In many cases, graphs are assumed to be simple unless specified otherwise.</p></li> +<li><p><strong>Directed graph</strong>: a graph in which the edges have a distinguished direction, from one vertex to another. A directed edge can also be called a path or walk. Arrow A –> B is therefore different from arrow B –> A.</p></li> <li><p><strong>Endpoints</strong>: the edge with vertex A –> B has A and B as endpoints, respectively as start and end of the path/walk.</p></li> -<li><p><strong>Isolated vertex</strong>: a vertex whose degree is zero, that is, a vertex with no incident edges. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a></p></li> +<li><p><strong>Isolated vertex</strong>: a vertex whose degree is zero, that is, a vertex with no incident edges.</p></li> <li><p><strong>Degree of a vertex</strong>: number of its incident edges -in and out-.</p></li> <li><p><strong>Out-degree of vertex A</strong>: number of outbound edges / tail ends from A.</p></li> <li><p><strong>In-degree of vertex A</strong>: number of incoming edges / head ends to A.</p></li> </ul> <figure> -<img src="https://duniter.org/en/images/wiki/degrees.jpg" alt="degress of a vertex diagram" /><figcaption>degress of a vertex diagram</figcaption> +<img src="./images/degres.jpg" alt="degrees of a vertex diagram" /><figcaption>degrees of a vertex diagram</figcaption> </figure> <ul> <li><strong>Path</strong>: -aka “walk”- path to follow to get from vertex A to vertex B.</li> </ul> -<h3 id="definition-of-the-duniter-web-of-trust-1">Definition of the Duniter Web of Trust</h3> +<h3 id="definition-of-the-duniter-web-of-trust">3.5. Definition of the Duniter Web of Trust</h3> <p>The Duniter WoTs -one per currency- are simple directed graphs without isolated vertices. The vertices are the members and the edges are the certifications given and received.</p> -<p>Directed, what does that mean?</p> -<p>The responsibility of issuing a certification is unique and personal to the certifier. The trust he/she places in the receiver cannot be imposed in the other direction although in most circumstances both parties equally trust each other.</p> -<p>In addition, all vertices are either currently active members or past-members. Past-member vertices are in a specific ‘deactivated state’ and can no longer issue or receive certifications although the ones already issued or received to/from other members are still considered ‘pending’ to avoid the web collapsing like a house of cards.</p> -<p>If these old members don’t come back into the web, their pending certifications will eventually expire and they will switch from ‘deactivated’ to ‘isolated’ vertices.</p> -<p>To wrap up with old members, after a certain period of time -set in the currency’s parameters - their deactivated vertex is removed from the web and the associated identity is ‘revoked’. The person who owned the account can no longer use this identity but is free to join the web with another one. :-)</p> +<p><em>Directed</em> means that the responsibility of issuing a certification is unique and personal to the certifier. The trust they place in the receiver cannot be imposed in the other direction although in most circumstances both parties equally trust each other.</p> +<p>In addition, all vertices are either currently active members or past-members. Past-member vertices are in a specific ‘deactivated state’ and can no longer issue or receive certifications although the ones already issued or received to/from other members are still considered ‘pending’ to avoid a collapse of the WoT. If these old members don’t come back into the WoT, their pending certifications will eventually expire and they will switch from ‘deactivated’ to ‘isolated’ vertices.</p> +<p>To wrap up with old members, after a certain period of time - set in the currency’s parameters - their deactivated vertex is removed from the web and the associated identity is ‘revoked’. The person who owned the account can no longer use this identity but is free to join the web with another one.</p> <blockquote> -<p>What do you mean by ‘identity’?</p> -</blockquote> -<p>An identity is a set of three pieces of information: a public key, a name and a blockstamp. A blockstamp points to a specific block in the chain. Its main use is to freeze the point in time at which an identity was created and to link this identity to a specific chain and of course, a currency -each currency having its own blockchain-.</p> +<p><strong>Identity</strong> : An identity is a set of three pieces of information: a public key, a name and a blockstamp. A blockstamp points to a specific block in the chain. Its main use is to freeze the point in time at which an identity was created and to link this identity to a specific chain and a currency - each currency having its own blockchain.</p> <p>An identity can be in any one of 5 different status: pending, member, old member, revoked or excluded.</p> +</blockquote> <p>Let’s take a simple example:</p> -<div class="highlight"> -<pre><code>A -> B -> C - | - \--> D</code></pre> -</div> +<pre><code> A -> B -> C + | + \--> D</code></pre> <p>If, for whatever reason, A were to lose its member status, the web would crumble and all other members would be excluded as a consequence. To avoid this, the certification from A –> B will remain valid until its expiry date, leaving enough time for B to receive certifications from C or D.</p> -<p>Because our WoT doesn’t have any isolated vertices, each new identity created needs to be pulled into the web with all of the certifications it has received -in the same block-. This calls for a temporary ‘buffer’ storage space for <strong>pending</strong> identities and the certifications they’ve received. This storage space is called ‘the pool’ -of Duniter nodes- which we could also have called the ‘sandbox’ as that’s the name used in Duniter’s code. I might add that these ‘pools’ also include other documents and metadata not mentioned here.</p> -<h3 id="exploring-the-rules-behind-a-duniter-web-of-trust-1">Exploring the rules behind a Duniter Web of Trust</h3> -<p>The Duniter WoTs -one per currency- work with a set of eight fundamental rules, themselves enforced through eleven different parameters. Ten of these parameters are set within the genesis block, the eleventh one - <code>msPeriod</code>- having being hard-coded in the Ğ1’s code subsequently.</p> -<h4 id="distance-rule-and-referent-members-stepmax-and-xpercent-1distance-rule-and-referent-members-stepmax-and-xpercent-1">1.Distance rule and referent members (<code>stepMax</code> and <code>xPercent</code>) {#1distance-rule-and-referent-members-stepmax-and-xpercent}</h4> +<p>Because our WoT doesn’t have any isolated vertices, each new identity created needs to be pulled into the web with all of the certifications it has received, all in the same block. This calls for a temporary ‘buffer’ storage space for <strong>pending</strong> identities and the certifications they have received. This storage space is called ‘the pool’ of Duniter nodes, which we could also have called the ‘sandbox’ as that’s the name used in Duniter’s code. Duniter nodes inclued other ‘pools’ for other documents and metadata not mentioned here.</p> +<h3 id="exploring-the-rules-behind-duniter-wot">3.6. Exploring the rules behind a Duniter Web of Trust</h3> +<p>The Duniter WoTs - one per currency - works with a set of eight fundamental rules enforced through eleven different parameters. Ten of these parameters are set within the genesis block, the eleventh one - <code>msPeriod</code>- having being hard-coded in the Ğ1’s code subsequently.</p> +<h4 id="distance-rule-and-referent-members-stepmax-and-xpercent">3.6.1. Distance rule and referent members (<code>stepMax</code> and <code>xPercent</code>)</h4> <p>These two parameters are closely linked and together define the ‘distance rule’. The ‘distance rule’ can only be described after defining what a ‘referent member’ is:</p> <blockquote> -<p><strong>Referent member</strong>: member A is said to be ‘referent’ if and only if the total of his/her degrees are greater than or equal to <code>CEIl-N^-1/stepMax--</code> where N is the total number of members.** As the size of the web will grow this number will grow too, meaning it will take more certification issuances to become a referent member as the number of certifications needed to become a member shouldn’t change.</p> +<p><strong>Referent member</strong>: member A is said to be ‘referent’ if and only if the total of their degrees are greater than or equal to <code>CEIL-N^-1/stepMax</code> where N is the total number of members. As the size of the web will grow this number will grow too, meaning it will take more certification issuances to become a referent member. The number of certifications needed to become a member shouldn’t change.</p> </blockquote> <p>Let’s now define the distance rule:</p> <blockquote> -<p><strong>Distance rule</strong>: member A is said to observe this rule if and only if for a subset xPercent % of referent members R there exists a path of length less than or equal to <code>stepMax</code> between R and A.**</p> -</blockquote> -<p>Referent members only exist so that the distance rule can take effect, they have no special privileges over non-referent members. In a perfect web, that is one in which each member has certified all members he/she legitimately can, all members would be referent members. However, because the web progressively grows in size and because members die and are replaced by new ones, there are always members at any given time <code>t</code> who haven’t yet certified all members they legitimately could. These members would hinder the evolution of the web if they were taken into account in the calculation of the distance rule and the web would effectively stop growing. -You can see what would happen if the notion of ‘referent member’ didn’t exist by going to the ‘gaussianWotQuality’ page on <a href="https://g1-monit.librelois.fr/gaussianWotQuality?lg=en&unit=quality">currency-monit</a> and activating ‘if the concept of referent members didn’t exist’-.</p> -<blockquote> -<p><strong>When is the distance rule applied?</strong></p> +<p><strong>Distance rule</strong>: member A is said to observe this rule if and only if for a subset xPercent % of referent members R there exists a path of length less than or equal to <code>stepMax</code> between R and A.</p> </blockquote> -<p>Because verifying the application of the distance rule is calculation-greedy, it is only performed when a new identity gets confirmed into the web or an existing member gets renewed. <em>Exception to the rule: the distance rule is not observed in the genesis block -when the web is first implemented-.</em></p> -<h4 id="rule-of-the-minimum-number-of-certifications-needed-sigqty-2-rule-of-the-minimum-number-of-certifications-needed-sigqty-1">2. Rule of the minimum number of certifications needed (<code>sigQty</code>) {#2-rule-of-the-minimum-number-of-certifications-needed-sigqty}</h4> -<p>This is the simplest rule, it essentially says that each member must at any given time -meaning in any single block- have received at least <code>sigQty</code> active certifications. If, for whatever reason, member A were to have less than <code>sigQty</code> active certifications in a given block, he/she would cease being a member and be required to publish a request for identity renewal.</p> -<h4 id="the-membership-renewal-rule-msvalidity-msperiod-and-mswindow-3-the-membership-renewal-rule-msvalidity-msperiod-and-mswindow-1">3. The membership renewal rule (<code>msValidity</code>, <code>msPeriod</code> and <code>msWindow</code>) {#3-the-membership-renewal-rule-msvalidity-msperiod-and-mswindow}</h4> +<p>Referent members only exist so that the distance rule can take effect, they have no special privileges over non-referent members. In a perfect web, that is one in which each member has certified all members they legitimately can, all members would be referent members. However, because the web progressively grows in size and because members die and are replaced by new ones, there are always members at any given time <code>t</code> who haven’t yet certified all members they legitimately could. These members would hinder the evolution of the web if they were taken into account in the calculation of the distance rule and the web would effectively stop growing.</p> +<p>Because verifying the application of the distance rule is calculation-greedy, it is only performed when a new identity gets confirmed into the web or an existing member gets renewed. There is an exception to this rule: the distance rule is not observed in the genesis block -when the web is first implemented.</p> +<h4 id="rule-of-the-minimum-number-of-certifications-needed-sigqty">3.6.2. Rule of the minimum number of certifications needed (<code>sigQty</code>)</h4> +<p>This is the simplest rule, it essentially says that each member must at any given time -meaning in any single block- have received at least <code>sigQty</code> active certifications. If, for whatever reason, member A were to have less than <code>sigQty</code> active certifications in a given block, they would cease to be a member and be required to publish a request for identity renewal.</p> +<h4 id="the-membership-renewal-rule-msvalidity-msperiod-and-mswindow">3.6.3. The membership renewal rule (<code>msValidity</code>, <code>msPeriod</code> and <code>msWindow</code>)</h4> <p>Bear in mind that a membership doesn’t last a lifetime but instead has a lifespan set to <code>msValidity</code> seconds.</p> -<p>Every single member -or old member who hasn’t revoked his identity or been excluded- can request a membership renewal so long as the last request was made more than <code>msPeriod</code> seconds ago -if a member has never requested a renewal, the date of last renewal is equal to the timestamp at which his membership was first created. A new request will be stored in the ‘pool’ for a maximum of <code>msWindow</code> seconds before it’s included in the blockchain. Once again, this can only happen once/if the member meets both the <code>siqQty</code> rule and the distance rule -if these criterion are already matched it’s just a case of waiting for a new block to be mined-.</p> -<p>If a member hasn’t requested a renewal for longer than <code>msValidity</code> seconds, he/she automatically ceases being a member. From this moment on, the ex-member has another <code>msValidity</code> window to renew his/her membership. When this period of `2 × msValidity’ runs out, the membership will expire and this identity will never be available for use again in the web. If the person so desires, he/she will have to start from zero to regain access to the WoT.</p> -<h4 id="rule-of-certification-lifespan-sigvalidity-4-rule-of-certification-lifespan-sigvalidity-1">4. Rule of certification lifespan (<code>sigValidity</code>) {#4-rule-of-certification-lifespan-sigvalidity}</h4> +<p>Every single member -or old member who hasn’t revoked his identity or been excluded- can request a membership renewal so long as the last request was made more than <code>msPeriod</code> seconds ago. If a member has never requested a renewal, the date of last renewal is equal to the timestamp at which his membership was first created. A new request will be stored in the ‘pool’ for a maximum of <code>msWindow</code> seconds before it’s included in the blockchain. Once again, this can only happen once/if the member meets both the <code>siqQty</code> rule and the distance rule -if these criterion are already matched it’s just a case of waiting for a new block to be mined-.</p> +<p>If a member hasn’t requested a renewal for longer than <code>msValidity</code> seconds, they automatically cease to be a member. From this moment on, the ex-member has another <code>msValidity</code> window to renew their membership. When this period of <code>2 × msValidity</code> runs out, the membership will expire and this identity will never be available for use again in the web. If the person so desires, they will have to publish new identity and membership documents and find enough certifiers, as any newcomer.</p> +<h4 id="rule-of-certification-lifespan-sigvalidity">3.6.4. Rule of certification lifespan (<code>sigValidity</code>)</h4> <p>All certifications included in the blockchain expire <strong>sigValidity</strong> seconds after they were <strong>issued</strong>.</p> +<blockquote> <p>/!\ The issuance and the inclusion of a certification in the blockchain occur at different times. When member A issues a certification at time t1, it gets stored in the pool starting at t1 and only finds its way into the blockchain at t2 when all of the web’s rules are observed. Several weeks can thus go by between t1 and t2!!!</p> -<h4 id="rule-of-limited-supply-of-active-certifications-sigstock-5-rule-of-limited-supply-of-active-certifications-sigstock-1">5. Rule of limited supply of active certifications (<code>sigStock</code>) {#5-rule-of-limited-supply-of-active-certifications-sigstock}</h4> +</blockquote> +<h4 id="rule-of-limited-supply-of-active-certifications-sigstock">3.6.5. Rule of limited supply of active certifications (<code>sigStock</code>)</h4> <p>By ‘active certifications’ we refer to certifications included in the blockchain and that haven’t yet expired.</p> <p>The total of active certifications issued by any member at any single time must be less than or equal to <code>sigStock</code>. When this threshold is reached the member will have to wait for one of his active certifications to expire before he/she can issue a new one.</p> -<h4 id="rule-of-the-time-period-between-two-certification-issuances.-sigperiod-6-rule-of-the-time-period-between-two-certification-issuances-sigperiod-1">6. Rule of the time period between two certification issuances. (<code>sigPeriod</code>) {#6-rule-of-the-time-period-between-two-certification-issuances-sigperiod}</h4> -<p>As soon as a certification issued by member A gets included in the blockchain, he/she will be unable to issue a new one before another <code>sigPeriod</code> seconds.</p> -<h4 id="expiry-of-a-certification-issuance-sigwindow-7-expiry-of-a-certification-issuance-sigwindow-1">7. Expiry of a certification issuance (<code>sigWindow</code>) {#7-expiry-of-a-certification-issuance-sigwindow}</h4> +<h4 id="rule-of-the-time-period-between-two-certification-issuances-sigperiod">3.6.6. Rule of the time period between two certification issuances. (<code>sigPeriod</code>)</h4> +<p>As soon as a certification issued by member A gets included in the blockchain, they will be unable to issue a new one before another <code>sigPeriod</code> seconds.</p> +<h4 id="expiry-of-a-certification-issuance-sigwindow">3.6.7. Expiry of a certification issuance (<code>sigWindow</code>)</h4> <p>When a certification is issued by member A, it will be stored in the ‘pool’ for a maximum of <code>sigWindow</code> seconds. If the certification hasn’t been included in the blockchain by then, it will be cancelled and the member’s <code>sigStock</code> will be repleted by one.</p> -<h4 id="lifespan-of-a-pending-active-certification-idtywindow-8-lifespan-of-a-pending-active-certification-idtywindow-1">8. Lifespan of a ‘pending’ active certification (<code>idtyWindow</code>) {#8-lifespan-of-a-pending-active-certification-idtywindow}</h4> +<h4 id="lifespan-of-a-pending-identity-idtywindow">3.6.8. Lifespan of a ‘pending’ identity (<code>idtyWindow</code>)</h4> <p>When a new identity is created, it is stored in the ‘pool’ for a maximum of <code>idtyWindow</code> seconds. If the person hasn’t achieved member status by then, the certification will simply be cancelled.</p> -<h3 id="details-on-some-of-the-wots-peculiarities-at-the-genesis-block">Details on some of the WoT’s peculiarities at the genesis block.</h3> +<h3 id="details-on-some-of-the-wots-peculiarities-at-the-genesis-block">3.7. Details on some of the WoT’s peculiarities at the genesis block</h3> <p>The aforementioned rules can only be enforced with an existing web. They cannot be observed when first creating the web, that is when defining the genesis block.</p> <p>Only rules 2 and 5 can be observed at the genesis block.</p> -<p>The genesis block has to be manually created by the founding members. In practice this means that there must be a choice of which identities to include on the premise that all of them observe rules 2 and 5. In addition, the genesis block must be signed with the private key of one of these identities.</p> -<p>As soon as the genesis block has been created, the other identities can start mining the blockchain and the member who begat block #0 effectively looses the decision power he had at creation.</p> -<h3 id="why-these-rules-and-application-cases-in-the-g1">Why these rules and application cases in the Ğ1</h3> -<h4 id="distance-and-maximum-size-1-distance-and-maximum-size-1">1. Distance and maximum size {#1-distance-and-maximum-size}</h4> +<p>The genesis block has to be manually created by the founding members. In practice this means that there must be a choice on which identities to include on the premise that all of them observe rules 2 and 5. In addition, the genesis block must be signed with the private key of one of these identities.</p> +<p>As soon as the genesis block has been created, the other identities can start mining the blockchain and the member who created block #0 effectively looses the decision power he had at creation.</p> +<h3 id="why-these-rules-and-application-cases-in-the-g1">3.8. Why these rules and application cases in the Ğ1</h3> +<h4 id="distance-and-maximum-size">3.8.1. Distance and maximum size</h4> <p>The distance rule is there to curb the maximum size of a Sybil region as well as that of the monetary community as a whole. The <code>xpercent</code> parameter prevents the creation of a ‘faction’ that could take hold of the blockchain.</p> <figure> -<img src="https://duniter.org/en/images/wiki/wot-sybil.jpg" alt="Sybil region" /><figcaption>Sybil region</figcaption> +<img src="./images/wot-sybil.jpg" alt="Sybil region" /><figcaption>Sybil region</figcaption> </figure> -<p>The Sybil regions are isolated from the rest of the graph in the sense that they can only receive certifications from other ill-intentioned Sybil members. As a consequence, the shortest edge/path between a legitimate member and a Sybil one has to have the attack’s author as an endpoint. The maximum depth the Sybil region can attain is therefore contingent on the distance between the attacking edge-s- and the xpercent% closest referent members, this distance is known as <code>stepAttackers</code>. The maximum size of a Sybil region created by <code>sigQty</code> members depends on the L parameter, defined as L = sigQty/sigStock:</p> -<div class="highlight"> -<pre><code>Maximum Sybil region size = (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L)</code></pre> -</div> +<p>The Sybil regions are isolated from the rest of the graph in the sense that they can only receive certifications from other ill-intentioned Sybil members. As a consequence, the shortest edge/path between a legitimate member and a Sybil one has to have the attack’s author as an endpoint. The maximum depth the Sybil region can attain is therefore contingent on the distance between the attacking edge-s- and the xpercent% closest referent members, this distance is known as <code>stepAttackers</code>. The maximum size of a Sybil region created by <code>sigQty</code> members depends on the L parameter, defined as <code>L = sigQty/sigStock</code>:</p> +<pre><code>MaxSybilSize= (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L)</code></pre> <p>The maximum size of the Web of Trust is given by the following formula:</p> -<div class="highlight"> <pre><code>WoTmax = (sigStock)*L^(stepMax-1)</code></pre> -</div> -<p>However we know for a fact that members will never use all of their available certifications. Many studies have proven that we all know a maximum average of fifty people, let’s then replace sigStock by fifty:</p> -<div class="highlight"> +<p>However we know for a fact that members will never use all of their available certifications. According to Dunbar<a href="#fn10" class="footnote-ref" id="fnref10"><sup>10</sup></a>, on average, one is able to maintain relationships to around 150 people. Being conservative, we will consider that on average, each person will certify 50 accounts. We can calculate the size of the average web of trust <code>WoTavg</code> :</p> <pre><code>WoTavg= (50)*(sigQty/50)^(stepMax-1)</code></pre> -</div> -<p>Our goal with the Ğ1 is to create a community of about one million members enjoying the world’s first true <a href="https://en.wikipedia.org/wiki/Catallaxy">catallaxy</a> -free economy with a spontaneous order of things-. Let’s see how we can tweak the pair of sigQty and stepMax- to reach this size:</p> +<p>Our goal with the Ğ1 is to create a community of about one million members to test the consequences of a libre monetary system. Let’s see how we can tweak the pair of sigQty and stepMax- to reach this size:</p> <figure> -<img src="https://duniter.org/en/images/wiki/graph-WoTmoy.png" alt="graphe WoTmoy en fonction de sigQty et stepMax" /><figcaption>graphe WoTmoy en fonction de sigQty et stepMax</figcaption> +<img src="./images/wot-moy.png" alt="Average WoT size graph as a function of sigQty and stepMax" /><figcaption>Average WoT size graph as a function of sigQty and stepMax</figcaption> </figure> <p>The maximum size of a Sybil region grows linearly with <code>sigQty</code> but exponentially with <code>stepMax</code>. Logic has it that we need to keep <code>stepMax</code> as low as possible to ensure sufficient strength to the web. The above graph shows that the lowest value of <code>stepMax</code> for a web of a million members is of 5. This is an order of magnitude and is likely to be much higher in reality, we cannot measure it for sure.</p> <p>For <code>sigQty</code> we can choose a value of <strong>4</strong> for a web of <strong>1.5 million members</strong> or <strong>5</strong> for <strong>half a million members</strong>. Bear in mind these are gross figures and could be significantly higher, we are talking anywhere between 1 and 10 million in reality. Calculating WOTavg gives us a pretty good idea of how the web would scale bearing in mind that it considers all members are referent members too -which isn’t the case as explained previously-. Hence the maximum size of the web is likely larger, a ballpark figure of half a million is enough for now especially knowing that the smaller <code>sigQty</code> is, the easier it is to launch a Sybil attack -it’s easier to find four accomplices than five-. For security reasons we have settled on five:</p> -<p>stepMax = 5 sigQty = 5 sigStock >= 50</p> -<p>The maximum size of a Sybil region therefore is: <code>(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5))</code></p> -<p>with sigStock = 50 we have a Sybil region of: <code>45*(1-10^(5-stepAttackers))/(-9)</code></p> +<pre><code>stepMax = 5 +sigQty = 5 +sigStock \>= 50</code></pre> +<p>The maximum size of a Sybil region therefore is:</p> +<pre><code>(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5))</code></pre> +<p>with sigStock = 50 we have a Sybil region of:</p> +<pre><code>45*(1-10^(5-stepAttackers))/(-9)</code></pre> <p>A good practice for protecting the web is to maximise <code>stepAttackers</code>. That’s why we decided that referent members in the genesis block had to be at least four steps away from each other.</p> <p>Another way to keep a Sybil attack at bay, were it slow enough for members to notice it, would be for referent members to ‘stretch’ the web intentionally to limit the growth of the region by ensuring that the attackers’ legitimate certifications received in the first place aren’t renewed. But what if bot accounts were created and certified each other super fast and following all rules, how would we counter that? By introducing a minimum length of time between two certifications!</p> -<h4 id="time-is-our-friend-2-time-is-our-friend-1">2. Time is our friend {#2-time-is-our-friend}</h4> +<h4 id="time-is-our-friend">3.8.2. Time is our friend</h4> <p>To help us deter a Sybil attack, we’ve decided to impose a minimum period of time between any two certifications issued from a single account. This parameter called <code>sigPeriod</code> affords us a greater chance to detect the formation of a ‘hostile’ faction.</p> -<p>Here is a graph showing the evolution of a Sybil region with the variation of <code>sigPeriod</code>:</p> +<p>Here is a graph showing the evolution of a Sybil region with the variation of <code>sigPeriod</code>. The simulation considers that honest members and attackers both issue a certification each <code>sigPeriod</code> interval, in days:</p> <figure> -<img src="https://duniter.org/en/images/wiki/impact_sig_period.png" alt="graph of the WoT's size according to sigPeriod and stepAttackers" /><figcaption>graph of the WoT's size according to sigPeriod and stepAttackers</figcaption> +<img src="./images/impact_sig_period.png" alt="size of the WoT according to sigPeriod and stepAttackers" /><figcaption>size of the WoT according to sigPeriod and stepAttackers</figcaption> </figure> -<p>As you’ll easily be able to tell, there is a strong link between the growth speed of the region and <code>sigPeriod</code>. As evidenced here, we need a <code>sigPeriod</code> high enough in order to ensure that the legitimate web can grow at least as fast as a Sybil region. In addition, the higher <code>sigPeriod</code> is, the more members will exercise their certification power gingerly, the action coming at a higher ‘cost’.</p> +<p>As we see, there is a strong link between the growth speed of the region and <code>sigPeriod</code>. As evidenced here, we need a <code>sigPeriod</code> high enough in order to ensure that the legitimate web can grow at least as fast as a Sybil region. In addition, the higher <code>sigPeriod</code> is, the more members will exercise their certification power gingerly, the action coming at a higher ‘cost’.</p> <p>There are numerous advantages to giving <code>sigPeriod</code> a high value and no technical barriers to it, hence our choice of five days.</p> -<p>We could have also gone for days days -one week- for the sake of simplicity however there was an underlying idea behind our choice which was quite simply the pace of today’s life. Certifying someone can be a lengthy process as one needs to make sure he/she is correctly applying the Ğ1 licence and people nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea to allow one to certify at the end of every working week -five days- instead of a whole calendar one.</p> -<h4 id="trust-me-now-trust-me-forever-sigvalidity-msvalidity-3-trust-me-now-trust-me-forever-sigvalidity-msvalidity-1">3. Trust me now, trust me forever? (<code>sigValidity</code>, <code>msValidity</code>) {#3-trust-me-now-trust-me-forever-sigvalidity-msvalidity}</h4> +<p>We could have also gone for one week for the sake of simplicity. However there is an underlying idea behind our choice which was quite simply the pace of today’s life. Certifying someone can be a lengthy process as one needs to make sure they are correctly applying the Ğ1 licence and people nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea to allow one to certify at the end of every working week -five days- instead of a whole calendar one.</p> +<h4 id="trust-me-now-trust-me-forever-sigvalidity-msvalidity">3.8.3. Trust me now, trust me forever ? (<code>sigValidity</code>, <code>msValidity</code>)</h4> <p>There would be two main drawbacks to a lifetime membership in the Ğ1’s Web of Trust:</p> -<blockquote> -<p>First of all we need to take into account that some members will pass and those accounts should no longer produce the Universal Dividend. Secondly it is of the utmost importance that ‘rogue’ accounts can be excluded from the web at some point.</p> -</blockquote> -<p>To achieve this, certifications have a limited lifetime and members need to seek renewal from their peers after <code>sigValidity</code> time. On the other hand, this time can’t be too short that members would spend more time seeking renewal than they would exchanging in the currency. Furthermore, a certification with too short a lifetime would foster careless certifying behaviours. The act of certifying must have a ‘perceived’ cost high-enough to make it feel like an important act. Lastly, we also wanted this lifetime to be easy enough to remember. Historically speaking, we first settled on the values of <code>sigPeriod</code> and <code>sigStock</code>, meant one could issue all of his/her certifications in 495 days, one year was therefore not long enough. We deemed three years to bee much and that’s how we agreed on two years in the end.</p> -<p>Thinking that a deceased member could continue producing the UD for two long years without anyone benefitting from it was also something we needed to address. We choose a value of one year for <strong>msValidity</strong>. The act of renewing every year is done through one of the clients interacting with the blockchain, through a simple click on a button. This parameter is less important than others and is mostly there to ‘prune’ the web of past or inactive members who don’t renew their membership.</p> -<h4 id="keeping-the-pools-free-of-information-glut--idtywindow-sigwindow-mswindow-4-keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow-1">4. Keeping the pools free of information glut -(<code>idtyWindow</code>, <code>sigWindow</code>, <code>msWindow</code>) {#4-keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow}</h4> +<ul> +<li>First of all, some members will pass and those accounts should no longer produce the Universal Dividend.</li> +<li>Secondly it is of the utmost importance that ‘rogue’ accounts can be excluded from the web at some point.</li> +</ul> +<p>To achieve this, certifications have a limited lifespan. Members need to seek renewal from their peers after <code>sigValidity</code> time. On the other hand, this time can’t be too short that members would spend more time seeking renewal than they would exchanging in the currency. Furthermore, a certification with too short a lifespan would foster careless certifying behaviours. The act of certifying must have a high-enough ‘perceived’ cost to make it feel like an important act. Lastly, we also wanted this lifespan to be easy to remember. Historically speaking, we first settled on the values of <code>sigPeriod</code> and <code>sigStock</code>, meant one could issue all of their certifications in 495 days, one year was therefore not long enough. We deemed three years to be too much and that’s how we agreed on two years in the end.</p> +<p>Thinking that a deceased member could continue producing the UD for two long years without anyone benefitting from it was also something we needed to address. We chose a value of one year for <strong>msValidity</strong>. The act of renewing every year is done through one of the clients interacting with the blockchain, through a simple click on a button. This parameter is less important than others and is mostly there to ‘prune’ the web of past or inactive members who don’t renew their membership.</p> +<h4 id="keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow">3.8.4. Keeping the pools free of information glut (<code>idtyWindow</code>, <code>sigWindow</code>, <code>msWindow</code>)</h4> <p>The pools need to be cleaned up on a regular basis to avoid them clogging up with information and to ensure that machines with less calculating power can still run a Duniter node.</p> <p>To achieve this, identities with pending membership approval and the corresponding certifications have to remain the shortest time possible in the pool while still having a chance of making it into the blockchain.</p> <p>For the Ğ1, our opinion was that two months would be enough for all potential certifiers to agree on a specific identity to certify. We also wanted a time period that would be easy enough to remember by all. We settled on two months, and gave this value to all three parameters <code>idtyWindow</code>, <code>sigWindow</code> and <code>msWindow</code>.</p> -<h4 id="avoiding-single-members-from-knowing-too-many-people-sigstock-5-avoiding-single-members-from-knowing-too-many-people-sigstock-1">5. Avoiding single members from ‘knowing too many people’ (<code>sigStock</code>) {#5-avoiding-single-members-from-knowing-too-many-people-sigstock}</h4> -<p>Many sociology studies have shown that we all know an average of fifty people. This of course is an average, some of us know more than fifty people, others much less. Once again we went for a number that would be easy to remember. Although <code>sigStock</code>’s impact on the size of a Sybil region is fairly limited, its value nonetheless has to be kept reasonable. We settled on hundred.</p> -<h4 id="avoiding-locking-minorities-xpercent-6-avoiding-locking-minorities-xpercent-1">6. Avoiding locking minorities (<code>xpercent</code>) {#6-avoiding-locking-minorities-xpercent}</h4> +<h4 id="avoiding-single-members-from-knowing-too-many-people-sigstock">3.8.5. Avoiding single members from ‘knowing too many people’ (<code>sigStock</code>)</h4> +<p>We considered that on average, each person will certify 50 people. However, we know for a fact that some members will use more than 50 certifications. The maximum social network of one individual is around 150 people<a href="#fn11" class="footnote-ref" id="fnref11"><sup>11</sup></a>. Being conservative, we settled on a maximum certification number <code>sigstock</code> of 100.<br /> +Since <code>sigStock</code>’s impact on the size of a Sybil region is fairly limited, we did not investigate further this parameter.</p> +<h4 id="avoiding-locking-minorities-xpercent">3.8.6. Avoiding locking minorities (<code>xpercent</code>)</h4> <p>It’s easy enough to become a referent member, one of the Sybil strategies could therefore be to create a region of referent members. Such a region would grow slower than otherwise but could confer a locking power to its members by using the distance rule. That’s why the distance rule cannot be calculated on 100% of the referent members. Hence the introduction of the <code>xpercent</code> parameter which defines the percentage of referent members needing to be less than five edges -steps- from each other.</p> -<p>This percentage needs to be low enough to prevent the formation of a locking minority -referent Sybil members being too far from legitimate referent members-. On the other hand, it needs to be high enough so as to restrict the maximum size of the Sybil region through the distance rule. The <code>xpercent</code> parameter was one of the hardest to define, we therefore reserve ourselves the right of modifying its value during the Ğ1 experiment.</p> -<p>We were inspired by the <a href="https://en.wikipedia.org/wiki/Pareto_principle">Pareto principle</a>: if at least 20% of members give good density to the web, 80% of the referent members will be five or less steps from any other member -referent or non-. The maximum value for <code>xpercent</code> is therefore 80%, anything above that and the distance rule could be too restrictive for legitimate use cases. With security our top concern, we chose the maximum value of 80%.</p> -<h4 id="spam-protection-with-msperiod-7-spam-protection-with-msperiod-1">7. Spam protection with (<code>msPeriod</code>) {#7-spam-protection-with-msperiod}</h4> +<p>This percentage needs to be low enough to prevent the formation of a locking minority -referent Sybil members being too far from legitimate referent members-. On the other hand, it needs to be high enough so as to restrict the maximum size of the Sybil region through the distance rule. The <code>xpercent</code> parameter was one of the hardest to define, therefore we might decide to change its value during the Ğ1 experiment.</p> +<p>We were inspired by the Pareto principle<a href="#fn12" class="footnote-ref" id="fnref12"><sup>12</sup></a>: if at least 20% of members give good density to the web, 80% of the referent members will be five or less steps from any other member -referent or not-. The maximum value for <code>xpercent</code> is therefore 80%, anything above that and the distance rule could be too restrictive for legitimate use cases. With security our top concern, we chose the maximum value of 80%.</p> +<h4 id="spam-protection-with-msperiod">3.8.7. Spam protection with (<code>msPeriod</code>)</h4> <p>This parameter stands out a bit on its own, as it was added after the genesis block. It is there to protect the Duniter P2P infrastructure against ‘spam’ attacks. We had to think of a strategy against attacks such as high-frequency membership renewal requests -i.e: in every block, every five minutes- or worse still, hundreds of these requests per minute to flood the Duniter nodes. Without such limits, nodes are supposed to address all renewal requests, even in cases where they were last published five minutes ago! The <code>msPeriod</code> parameter was given the same value as <code>idtyWindow</code>, <code>sigWindow</code> and <code>msWindow</code>, i.e. two months.</p> -<h2 id="proof-of-work-with-personal-difficulty-1">Proof of Work with personal difficulty</h2> +<h2 id="proof-of-work-with-personalized-difficulty">4. Proof of Work with personal difficulty</h2> <p>As each P2P cryptocurrency, Duniter has a way to synchronize its peers. It uses a proof of Work (PoW) to write the Blockchain on a regular basis, much like BitCoin. However, Duniter has a unique asset : the WoT, where each member represents a unique living human.</p> -<p>This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each “winning” member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. The knowledge of the whole network is not needed.</p> +<p>This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each “winning” member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. A view of the whole network is not needed.</p> <p>Another strong difference is that forging peers are not rewarded by the protocol. There is no economical incentive on forging lots of blocs, neither on having a lot of computing power.</p> <p>One could say that Duniter uses a PoW that needs very low energy consumption compared to BitCoin : an “ecological” PoW ?</p> <!-- source : https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/ --> -<h3 id="why-do-we-need-proof-of-work-1">Why do we need Proof of Work ?</h3> +<h3 id="why-proof-of-work">4.1. Why do we need Proof of Work ?</h3> <p>Duniter nodes share a database as part of a p2p environment. The proof of work (PoW) allows machines to synchronize with each other. In Duniter’s case, the blockchain is our database, and acts as a ledger keeping a trace of all transactions, status of the WoT and more. How can we let several machines add data (ie: a transaction) at the same time? In addition, how do we settle on how much time has gone by since the blockchain was last updated? Agreement on time is of the utmost importance as we want to create Universal Dividends on a regular basis, and keep track of membership status, both in human time.</p> -<p>Proof-of-work provides a clever solution to both problems: 1. Any machine can write into the blockchain (create a new block) but is only authorised to do so if it has previously solved a mathematical equation that require a certain amount of work. The challenge has to be hard enough to prevent two machines to solve it at the same time, ensuring the unicity of a block’s creator.</p> -<ol start="2" type="1"> -<li>Solving this challenge takes a certain amount of time, which depends on the calculating power of the whole network. This provides a common ground for defining the needed time reference. A block time is set (ie: 1 block = 5 min) and Duniter adapts the challenge difficulty to get an <em>average</em> duration corresponding to this block time.</li> +<p>Proof-of-work provides a clever solution to both problems:</p> +<ol type="1"> +<li><p>Any machine can write into the blockchain (create a new block) but is only authorised to do so if it has previously solved a mathematical equation that require a certain amount of work. The challenge has to be hard enough to prevent two machines to solve it at the same time, ensuring the unicity of a block’s creator.</p></li> +<li><p>Solving this challenge takes a certain amount of time, which depends on the calculating power of the whole network. This provides a common ground for defining the needed time reference. A block time is set (ie: 1 block = 5 min) and Duniter adapts the challenge difficulty to get an average duration corresponding to this block time.</p></li> </ol> -<h3 id="only-members-can-mine-1">Only members can “mine”</h3> -<p>One of Duniter’s major differences with other PoW-based cryptocurrencies is that only members are allowed to author blocks. Each block is signed with the member’s private key, allowing the algorithm to determine a <em>personalised difficulty</em>.</p> +<h3 id="only-members-can-mine">4.2. Only members can “mine”</h3> +<p>One of Duniter’s major differences with other PoW-based cryptocurrencies is that only members are allowed to author blocks. Each block is signed with the member’s private key, allowing the algorithm to determine a personalised difficulty.</p> <p>This personalised difficulty eliminates the rat-race for the most sophisticated and powerful mining equipment. Another benefit is the fact that no “supercomputer” can take control of the blockchain. Lastly, Duniter implements a rotation in forging members thanks to this personalized difficulty.</p> <p>This lightweight PoW is much less energy-consuming than other PoW cryptocurrencies. Members can mine with anything from a raspberry pi to a privacy-first internet cube.</p> -<h3 id="how-does-it-work-1">How does it work?</h3> -<h4 id="the-hash-aka-digest-1">The hash (aka digest)</h4> +<h3 id="how-does-duniter-pow-work">4.3. How does it work ?</h3> +<h4 id="the-hash">4.3.1. The hash (aka digest)</h4> <p>Example of a valid hash:</p> -<div class="highlight"> <pre><code>00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653</code></pre> -</div> -<p>As you can see this hash starts with five zeros which was very hard to achieve and took a lot of <em>work</em> for someone’s computer. Hence the term “proof of work”.</p> -<h4 id="the-common-difficulty-1">The common difficulty</h4> +<p>As you can see this hash starts with five zeros which was very hard to achieve and took a lot of work for someone’s computer. Hence the term “proof of work”.</p> +<h4 id="common-difficulty">4.3.2. The common difficulty</h4> <p>A common difficulty is needed to settle on a yardstick for our time reference. Its role is to make sure the blockchain moves forward at a steady pace - one block every <code>avgGenTime</code> seconds, <code>avgGenTime</code> being one of the 20 parameters behind the Duniter protocol-.</p> <p>This difficulty’s initial value can be set to any arbitrary value (<code>70</code> in Duniter <code>v1.5.x</code>) and then acts as a spring, regulating blocktime creation by increasing itself if the creation interval drops under <code>avgGenTime</code> and vice-versa.</p> -<h5 id="how-is-difficulty-applied-1">How is difficulty applied?</h5> -<p>The numeric value of difficulty is taken from an array of possible hashes out of all possible hashes. In duniter v1.5.x the hash of a block is its sha256 hexadecimal hash.</p> +<h5 id="how-is-difficulty-applied">4.3.2.1. How is difficulty applied ?</h5> +<p>The numeric value of difficulty is taken from an array of possible hashes out of all possible hashes. In DUBPv13 the hash of a block is its sha256 hexadecimal hash.</p> <p>To understand the difficulty, we make a euclidiean division of the difficulty by 16.</p> -<p>Here’s an example with a difficulty value of <code>70</code> : 70 // 16 = <strong>4</strong> with a remainder of <strong>6</strong>. The valid hashes are the ones starting with four zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). The valid hashes are then written as starting with : <code>0000[0-9]</code>. This is a bit different from Bitcoin, where the difficulty is only ruled by the number of zeroes.</p> -<blockquote> -<p>Fine, but the hash of a mined block will never change and there’s no reason it should start with a given sequence of numbers. So how then can we make sure a block hash starts with exactly the sequence needed?</p> -</blockquote> -<p>Enter the nonce, short for “number once”. When a member is forging a new block, his computer freezes the block’s content and changes the Nonce until the hash reaches the required number of zeroes.</p> -<h5 id="the-nonce-1">The Nonce</h5> +<p>Here’s an example with a difficulty value of 70 :</p> +<pre><code>70 // 16 = 4 with a remainder of 6. </code></pre> +<p>The valid hashes are the ones starting with four zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). The valid hashes are then written as starting with : <code>0000[0-9]</code>. This is a bit different from Bitcoin, where the difficulty is only ruled by the number of zeroes.</p> +<h5 id="the-nonce">4.3.2.2. The Nonce</h5> +<p>When a member is forging a new block, his computer freezes the block’s content and changes the Nonce until the hash reaches the required number of zeroes.</p> <p>The nonce allows us to mine a new block by finding a hash. The hash value allows us to determine the difficulty level of the proof-of-work performed. Examples of possible Nonce values:</p> <ul> <li>10100000112275</li> @@ -794,30 +344,24 @@ Duniter Whitepaper </ul> <p>In reality the <code>Nonce</code> value follows a pre-determined format akin to <code>XYY00000000000</code>. The Nonce’s value isn’t the number of attempts but rather a value within a set of possible ones. This is how the Nonce is built:</p> <ul> -<li><p>X is a number assigned to a specific peer. Let’s assume that someone has several nodes each with the same private key, this would lead to possible collisions if this person were to mine the same block with different nodes. Each block will therefore have its own unique X to prevent this from happening.</p></li> +<li><p>X is a number assigned to a specific peer. Let’s assume that someone has several nodes each with the same private key, this would lead to possible collisions if this person were to mine the same block with different nodes. Each <del>block</del> <strong>node ?</strong> will therefore have its own unique X to prevent this from happening.</p></li> <li><p>Y is the number of cores of the processor. The Nonce starting with <code>107[…]</code> belongs to a seven cores processor, while <code>199[...]</code> could be the proof generated by a 99 cores processor.</p></li> </ul> <p>The rest of the Nonce, the part that follows after the XYY, is the numerical space for this individual node and is unique to each of the CPU’s core. This space is comprised of eleven digits (<code>00000000000</code>). For the sake of accuracy, we use the term CPU in the wider sense, it can be understood as a bi-CPU for example. We take into consideration the number of cores for the resulting PoW.</p> -<h3 id="personalised-difficulty-1">Personalised difficulty</h3> -<p>Earlier in this article, we explained that the personalised difficulty is the new and key concept that sets Duniter apart from other <em>PoW-based</em> cryptocurrencies such as Bitcoin.</p> +<h3 id="personalised-difficulty">4.4. Personalised difficulty</h3> +<p>Earlier in this article, we explained that the personalised difficulty is the new and key concept that sets Duniter apart from other PoW-based cryptocurrencies.</p> <p>Here is how this personalised difficulty is calculated and assigned:</p> <p>It is determined by a combination of two different constraints with complimentary roles: the <strong>exclusion factor</strong> and the <strong>handicap</strong>.</p> <p>Let <code>powMin</code> be the common difficulty, <code>exFact</code> a member’s exclusion factor and <code>handicap</code> their handicap. This member’s personalised difficulty <code>diff</code> is:</p> -<div class="highlight"> <pre><code>diff = powMin*exFact + handicap</code></pre> -</div> -<h4 id="understanding-exfact-the-exclusion-factor-1">Understanding <code>exFact</code>, the exclusion factor</h4> +<h4 id="the-exclusion-factor">4.4.1. Understanding <code>exFact</code>, the exclusion factor</h4> <p>Members who have never produced blocks or haven’t for quite some time are assigned an exclusion factor of <code>1</code>. Their personalised difficulty is therefore simply the sum of <code>powMin + handicap</code>.</p> <p>Before reading on, let’s precise the role of this exclusion factor. When a member adds a block to the chain, his <code>exFact</code> jumps up from one to a very high value, to prevent them from forging other blocks immediately after and taking control of the blockchain.</p> <p>The exclusion factor will then rapidly return to one. This delay is expressed as a number of blocks. It is calculated as a proportion of the number of members forging. In the Ğ1’s case, this proportion is 1/3, meaning that if there are fifteen members currently forging, the member’s exclusion factor will drop down to one after five blocks.</p> -<blockquote> -<p>What is intended by “the number of members forging”?</p> -</blockquote> -<p>We mean the number of members trying to create the next block. In reality, there is no way to precisely know how many members are calculating at any given time, because it is impossible to view the entire network. But we need this information, whithout which assigning a personalised difficulty is impossible. To achieve this, Duniter looks back at the blockchain and assumes that there is as much members forging as those who have found at least one block in the last X blocks, minus the very last one.</p> -<blockquote> -<p>Hox is X determined?</p> -</blockquote> -<p>We use the concept of <strong>current window</strong>. X’s value is equal to the size of this window. Let’s see how it works:</p> +<h5 id="what-is-intended-by-the-number-of-members-forging">4.4.1.1. What is intended by “the number of members forging” ?</h5> +<p>We mean the number of members trying to create the next block. In reality, there is no way to precisely know how many members are calculating at any given time, because it is impossible to view the entire network. But we need this information, whithout which assigning a personalised difficulty is impossible. To achieve this, Duniter looks back at the blockchain and assumes that there is as much members forging as those who have found at least one block in the last blocks in the current window, minus the very last one.</p> +<h5 id="current-window">4.4.1.2. Current window</h5> +<p>We use the concept of <strong>current window</strong>. The current window is the number of blocks we look back at to determine how many members are forging. Let’s see how it works:</p> <ul> <li><p><code>issuersFrame</code> is the size of the current window in blocks.</p></li> <li><p><code>issuersCount</code> the number of members who have calculated at least one block during the current window.</p></li> @@ -867,78 +411,88 @@ Duniter Whitepaper </tbody> </table> <p>The calculation can be found under rules <a href="https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g05-headissuersframe">BR_G05</a> and <a href="https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g06-headissuersframevar">BR_G06</a> of the DUP protocol.</p> -<blockquote> -<p>Let’s go back to the personalised difficulty.</p> -</blockquote> -<p>We explained that <code>exFact</code> spikes immediately after the member has found a block. It decreases then rapidly to <code>1</code> after a number of blocks <code>X = 1/3 * issuersCount</code>. Let’s see precisely how we calculate <code>exFact</code>:</p> +<h5 id="exfact-and-the-personalised-difficulty">4.4.1.3. exFact and the personalised difficulty</h5> +<p>We explained that <code>exFact</code> spikes immediately after the member has found a block. It decreases then rapidly to <code>1</code> after a number of blocks equal to <code>1/3 * issuersCount</code>. Let’s see precisely how we calculate <code>exFact</code>:</p> <ul> <li><p><code>nbPreviousIssuers</code> is the value of issuersCount at the last block <code>N</code> found by the member.</p></li> <li><p><code>nbBlocksSince</code> is the number of blocks found by the rest of the network since block <code>N</code>.</p></li> <li><p><code>percentRot</code> is the number of <em>not excluded</em> peers we want. It is a monetary parameter, its value is 0.67 for Ğ1 currency.</p></li> </ul> -<div class="highlight"> -<pre><code>exFact = MAX [ 1 ; FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) ]</code></pre> -</div> +<pre><code>a = FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) +exFact = MAX [ 1 ; a ]</code></pre> <p>The FLOOR is a simple truncate function. For <code>exFact</code> to exclude the member, we need :</p> -<blockquote> -<p>(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2</p> -</blockquote> -<p>We can see that the member is not excluded if <code>nbBlocksSince</code> is greater than 1/3 of the calculating members. Take as an example nbPreviousIssuers = 6 and nbBlocksSince = 3:</p> -<blockquote> -<p>(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1</p> -</blockquote> -<p>However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded: > (0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2</p> -<p>Moreover if the last block was authored by the said member, then: > <code>nbBlocksSince=0</code> and > <code>exFact</code> = <code>0.67 * nbPreviousIssuers</code></p> +<pre><code>(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2</code></pre> +<p>We can see that the member is not excluded if <code>nbBlocksSince</code> is greater than 1/3 of the calculating members. Take as an example <code>nbPreviousIssuers = 6</code> and <code>nbBlocksSince = 3</code>:</p> +<pre><code>(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1</code></pre> +<p>However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded:</p> +<pre><code>(0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2</code></pre> +<p>Moreover if the last block was authored by the said member, then:</p> +<pre><code>nbBlocksSince=0 and +exFact = 0.67 * nbPreviousIssuers</code></pre> <p>ExFact value increases according to the number of members calculating. Thus, if there is enough members calculating, even mining farms would be excluded. We have therefore succeeded in our intent to deter attempts to seize the blockchain and its currency.</p> -<p>However, at any time t, the two-thirds of calculating members all have an exclusion factor of <code>1</code>, even though they might not all have the same computational power at hand. If the personalised difficulty only took into account the exclusion factor, then only the members with the highest computational power from the remaining third would be able to author new blocks and the other 2/3s would almost always be excluded. Lesser machines wouldn’t stand a chance…</p> -<h4 id="the-handicap-1">The handicap</h4> -<p>The handicap is the second parameter of the personalised difficulty. Its main role is to improve the rotation of forging peers. A higher handicap is assined to members with higher calculating power, so lesser machines can also compute blocks. As a consequence, there is no incentive on forging with powerful computers. Security can be achieved with less computing power than with pure PoW.</p> +<p>However, at any time <code>t</code>, the two-thirds of calculating members all have an exclusion factor of <code>1</code>, even though they might not all have the same computational power at hand. If the personalised difficulty only took into account the exclusion factor, then only the members with the highest computational power from the remaining third would be able to author new blocks and the other 2/3s would almost always be excluded. Lesser machines wouldn’t stand a chance…</p> +<h4 id="the-handicap">4.4.2. The handicap</h4> +<p>The handicap is the second parameter of the personalised difficulty. Its main role is to improve the rotation of forging peers. A higher handicap is assigned to members with higher calculating power, so lesser machines can also compute blocks. As a consequence, there is no incentive on forging with powerful computers. Security can be achieved with less computing power than with pure PoW.</p> <p>The aim is to handicap the half that has authored most blocks (the most powerful half) to favour the other one. So, the handicap formula will use the median number of blocks authored by peers within the current window.</p> <ul> <li><p><code>nbPersonalBlocksInFrame</code> is the number of blocks authored by a single member within the current window.</p></li> <li><p><code>medianOfBlocksInFrame</code> is the median number of blocks written by the calculating members during the same timeframe.</p></li> </ul> -<div class="highlight"> -<pre><code>handicap = FLOOR(LN(MAX(1;(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)) / LN(1.189))</code></pre> -</div> -<p>Let’s unwrap the formula: <code>(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)</code> is simply the ratio between the number of blocks authored by the peer and the median number of blocks. For example, if a peer has authored <code>9</code> blocks in the current window and the median is <code>5</code>, then the ratio will be <code>(9+1)/5 = 2</code>. The MAX function allows us to ensure that the handicap has a value at least equal to <code>1</code>.</p> +<pre><code>a = (nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame +handicap = FLOOR(LN(MAX( 1 ; a )) / LN(1.189))</code></pre> +<p>Let’s unwrap the formula:</p> +<pre><code>(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)</code></pre> +<p>is simply the ratio between the number of blocks authored by the peer and the median number of blocks. For example, if a peer has authored <code>9</code> blocks in the current window and the median is <code>5</code>, then the ratio will be <code>(9+1)/5 = 2</code>. The MAX function allows us to ensure that the handicap has a value at least equal to <code>1</code>.</p> <p>The Napierian Logarithm of this ratio prevents the handicap from becoming excluding. We want the handicap to level the calculating field so that all peers stand a chance, not to exclude peers.</p> -<p>If we want the handicap to be applied as soon as the median is reached, we’d have to divide it by <code>LN(1)</code>, the problem is that we’ve already set a minimum value of <code>1</code> with the MAX function, so if we were to divide the ratio by <code>LN(1)</code> all calculating peers would have a handicap >= <code>1</code>. In addition, is it really fair to handicap a member who’s right on the median?</p> +<p>If we wanted the handicap to be applied as soon as the median is reached, we would divide it by <code>LN(1)</code>. The problem is that we have already set a minimum value of <code>1</code> with the MAX function. If we were to divide the ratio by <code>LN(1)</code> all calculating peers would have a handicap <code>\>= 1</code>. In addition, is it really fair to handicap a member who is right on the median?</p> <p>That’s why we went for <code>1.189</code> rather than <code>1</code>. A member has to be at least <code>18.9%</code> above the median to be assigned a handicap. 18.9% is actually 16^(1/16), the difficulty factor between two levels of the proof work (hexadecimal hash).</p> <p>To conclude, you have to remember that :</p> <ul> -<li>the handicap is indexed on the logarithm of the ratio to the median,</li> -<li>handicap is only applied on members whose ratio to the median is greater than the ratio between two levels of the proof-of-work’s difficulty.</li> +<li>The handicap is indexed on the logarithm of the ratio to the median,</li> +<li>Handicap is only applied on members whose ratio to the median is greater than the ratio between two levels of the proof-of-work’s difficulty.</li> </ul> -<h2 id="conclusion-1">Conclusion</h2> +<h2 id="conclusion">Conclusion</h2> <!-- source : https://duniter.org/en/theoretical/ --> <p>Duniter’s Blockchain can be compared to Bitcoin’s : a common document retracing the history of the currency. However, Duniter registers not only trades, but also the history of relationships in the community as a mean to identify a human to a digital account. This way, Duniter has information about the fondamental reference of RTM : living humans. A libre Currency can be issued thanks to the Universal Dividend.</p> -<p>More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers while maintaining a good security on the network.</p> +<p>More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers, maintaining a good security and helping decentralization of calculation.</p> <p>The ultimate goal of Duniter project is to allow people to participate in a libre economy, thanks to a libre currency. What is a libre economy ? The Relative Theory of Money defines it through four economic liberties :</p> <ul> -<li>The freedom to choose your currency system: because money should not be imposed</li> -<li>The freedom to access resources: because we all should have access to economic & monetary resources</li> -<li>The freedom to estimate and produce value: because value is a purely relative to each individual</li> -<li>The freedom to trade with the money: because we should not be limited by the avaible money supply</li> +<li>The freedom to choose your currency system: because money should not be imposed.</li> +<li>The freedom to access resources: because we all should have access to economic & monetary resources.</li> +<li>The freedom to estimate and produce value: because value is a purely relative to each individual.</li> +<li>The freedom to trade with the money: because we should not be limited by the avaible money supply.</li> </ul> <p>Those 4 economic freedoms should be understood together, not exclusively. Plus, “freedom” has to be understood as “non-nuisance”. So here, freedom does not mean the right to take all of a resource (like water source in a desert) so no more is available to the others. Now you get it, this is the goal: free economy through free currency.</p> -<h2 id="duniter-projects-sources-1">Duniter project’s sources :</h2> -<ul> -<li>Theoretical, by Cgeek: https://duniter.org/en/theoretical/</li> -<li>Lock conditions, by Inso: https://duniter.org/en/transactions-0-2-overview/</li> -<li>Individualised Proof of Work, by Elois: https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/</li> -<li>Deep dive into the Web of Trust, by Elois: https://duniter.org/en/deep-dive-into-the-web-of-trust/</li> -<li>Whitepaper sources: https://git.duniter.org/communication/duniter-whitepaper</li> -</ul> -<h2 id="other-sources-1">Other sources :</h2> -<ul> -<li>Relative Theory of Money, S.Laborde, 2010: http://en.trm.creationmonetaire.info/</li> -<li>Bitcoin Whitepaper, S.Nakamoto, 2008: https://bitcoin.org/bitcoin.pdf</li> -<li>Circles Whitepaper, A.Milenius, 2018: https://github.com/CirclesUBI/docs/blob/master/Circles.md</li> -<li>The Sibyl Attack, J.R.Douceur: https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</li> +<h2 id="sources">Sources :</h2> +<ul> +<li>Relative Theory of Money, S.Laborde, 2010: <a href="http://en.trm.creationmonetaire.info/">en.trm.creationmonetaire.info/</a></li> +<li>Bitcoin Whitepaper, S.Nakamoto, 2008: <a href="https://bitcoin.org/bitcoin.pdf">bitcoin.org/bitcoin.pdf</a></li> +<li>The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : <a href="http://lightning.network/lightning-network-paper.pdf">lightning.network/lightning-network-paper.pdf</a></li> +<li>The GNU Privacy Handbook, M.Ashley, 1999 : <a href="https://www.gnupg.org/gph/en/manual.html#AEN335">www.gnupg.org/gph/en/manual.html#AEN335</a></li> +<li>High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. <a href="https://cr.yp.to/papers.html#ed25519">cr.yp.to/papers.html#ed25519</a>.</li> +<li>PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : <a href="https://archive.org/details/PPCoinPaper">archive.org/details/PPCoinPaper</a></li> +<li>Duniter Blockchain Protocol, v13, draft by Elois : <a href="https://git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md">git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md</a></li> +<li>The Sibyl Attack, J.R.Douceur: <a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf">www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</a></li> +<li>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992</li> </ul> -<!-- travaux en theorie des graphes pourla TdC --> </article> </main> </body> </html> +<section class="footnotes"> +<hr /> +<ol> +<li id="fn1"><p>Bitcoin Whitepaper, S.Nakamoto, 2008: <a href="https://bitcoin.org/bitcoin.pdf">bitcoin.org/bitcoin.pdf</a><a href="#fnref1" class="footnote-back">↩</a></p></li> +<li id="fn2"><p>Relative Theory of Money, S.Laborde, 2010: <a href="http://en.trm.creationmonetaire.info/">en.trm.creationmonetaire.info/</a><a href="#fnref2" class="footnote-back">↩</a></p></li> +<li id="fn3"><p>OpenPGP protocol defines standard formats for encrypted messages, signatures, private keys, and certificates for exchanging public keys. The GNU Privacy Handbook, M.Ashley, 1999 : <a href="https://www.gnupg.org/gph/en/manual.html#AEN335">www.gnupg.org/gph/en/manual.html#AEN335</a><a href="#fnref3" class="footnote-back">↩</a></p></li> +<li id="fn4"><p>High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. <a href="https://cr.yp.to/papers.html#ed25519">cr.yp.to/papers.html#ed25519</a>.<a href="#fnref4" class="footnote-back">↩</a></p></li> +<li id="fn5"><p>PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : <a href="https://archive.org/details/PPCoinPaper">archive.org/details/PPCoinPaper</a><a href="#fnref5" class="footnote-back">↩</a></p></li> +<li id="fn6"><p>The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : <a href="http://lightning.network/lightning-network-paper.pdf">lightning.network/lightning-network-paper.pdf</a><a href="#fnref6" class="footnote-back">↩</a></p></li> +<li id="fn7"><p>Surfing a Web of Trust, Reputation and Reciprocity on CouchSurfing.com, D.Lauterbach, H.Truong, T.Shah, L.Adamic: <a href="http://snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf">snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf</a><a href="#fnref7" class="footnote-back">↩</a></p></li> +<li id="fn8"><p>Public key validation on GnuPG manual, M.Ashley, 1999 : <a href="https://www.gnupg.org/gph/en/manual.html#AEN335">www.gnupg.org/gph/en/manual.html#AEN335</a><a href="#fnref8" class="footnote-back">↩</a></p></li> +<li id="fn9"><p>The Sibyl Attack, J.R.Douceur: <a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf">www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</a><a href="#fnref9" class="footnote-back">↩</a></p></li> +<li id="fn10"><p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992<a href="#fnref10" class="footnote-back">↩</a></p></li> +<li id="fn11"><p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992<a href="#fnref11" class="footnote-back">↩</a></p></li> +<li id="fn12"><p>Pareto principle : <a href="https://en.wikipedia.org/wiki/Pareto_principle">en.wikipedia.org/wiki/Pareto_principle</a><a href="#fnref12" class="footnote-back">↩</a></p></li> +</ol> +</section> diff --git a/build/whitepaper_en.md b/build/whitepaper_en.md index a459ae6..a73c873 100644 --- a/build/whitepaper_en.md +++ b/build/whitepaper_en.md @@ -1,13 +1,22 @@ -Duniter : A libre currency blockchain generator ! +Duniter: A libre currency blockchain generator. ======================================= -## Abstract (TODO) +## Abstract {#abstract} -## Introduction +Many currency principles involve non-equal rights to monetary creation between humans. +We propose a monetary creation based on the Relative Theory of Money, which guarantee equal monetary creation for each willing human. +This type of currency can be centralised, however, this could lead to censorship and arbitrary choices of the central institution. +Thus, strongly inspired by Bitcoin example, we want the currency to be as decentralised as possible, in the transaction network as in the human identification process. +We use a Web of Trust between living humans for identification. +This web of trust allows us to impose personalised difficulty for transaction validation, keeping the calculation accessible to low-end hardware and allowing all competent members to secure the currency. + + + +## Introduction {#introduction} Duniter is a software to create and manage "libre currencies". Libre currency is a concept defined by S.Laborde in the Relative Theory of Money (RTM) that was published in 2010. This theory demonstrates the possibility of an invariant monetary unit : the Universal Dividend. Doing so, the RTM answers the question : -> How should a currency be created to match the principle of equality between all humans ? +> How should a currency be created to match the principle of equality between all humans, now and between generations ? The results of this demonstration implies a monetary creation : @@ -17,111 +26,118 @@ The results of this demonstration implies a monetary creation : Thus, Duniter project will associate a human to a digital identity. It will use a Web of Trust with specific rules. As the number of members may evolve, the Universal Dividend has to be created according to the formula : -> UD(t+1) = UD(t) + c² * ( M(t) / N(t) ) +$$ UD(t+1) = UD(t) + c²*( {M(t) \over N(t) }) $$ + Duniter is based on a decentralized Blockchain. This technical choice allows irreversibility of transaction and uncensorability of trades and identities. While inspired by Bitcoin, Duniter uses a Web of Trust and the Proof of Work to secure the computation network, thus making obsolete the power race model used in Bitcoin. -The first currency created through Duniter is Ğ1 (say "June"). It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software. +The first currency created through Duniter is Ğ1, pronounced "June". It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software. -## State of the art : Bitcoin case + +## 1. State of the art : Bitcoin case {#state-of-the-art-bitcoin-case} <!-- source : https://duniter.org/en/theoretical/ --> -Duniter uses the crypto-currency concept introduced by Bitcoin, which is -to use cryptographic tools such as *signatures* to create digital -currencies. Duniter fits this definition, but it has completely +Duniter uses the crypto-currency concept introduced by Bitcoin[^BTC_whitepaper], which is +to use cryptographic tools such as signatures to create trustless digital +currencies. Duniter fits this definition, but it has two completely different principles than Bitcoin : the Web of Trust and the Universal Dividend . These differences are on both monetary and technical aspects. -### Monetary creation of Bitcoin : a space-time asymmetry +[^BTC_whitepaper]: Bitcoin Whitepaper, S.Nakamoto, 2008: [bitcoin.org/bitcoin.pdf](https://bitcoin.org/bitcoin.pdf) + +### 1.1. Monetary creation of Bitcoin : a space-time asymmetry {#monetary-creation-a-space-time-asymmetry} Space-time asymmetry refers to the relative access of individuals to -newly created money (Relative Theory of Money, S.Laborde, 2010). Concretely, all existing currencies (c. 2015) are +newly created money[^RTM]. Concretely, most existing currencies (c. 2020) are both spatially and temporally asymmetrical for their users. Let\'s take Bitcoin as an example to understand why. -#### Spatial asymmetry +[^RTM]: Relative Theory of Money, S.Laborde, 2010: [en.trm.creationmonetaire.info/](http://en.trm.creationmonetaire.info/) + +#### 1.1.1. Spatial asymmetry {#spatial-asymmetry} -When new Bitcoins are created, *only some Bitcoin users* (the miners) -are given new Bitcoins, while everyone else get nothing. **We believe -this is the *first* injustice.** However, some might say: +When new Bitcoins are created, only some Bitcoin users (the miners) +are given new Bitcoins, while everyone else get nothing. We believe +this is the first injustice. However, some might say: -> \"Miners used their *electricity and time* to get it!\" +> \"Miners used their electricity and time to get it!\" -\... we would answer that this work *shouldn\'t have been rewarded by -newly created Bitcoins*. New Bitcoins should be distributed to the whole -Bitcoin community. Miners should be rewared another way, but not by -money issuance. Of course, Bitcoin can\'t create money through Basic -Income since *Bitcoin users are not strongly identified*, and one might -benefit from money creation multiple times if he owned several wallets. -Duniter gets rid of this problem completely by identifying its users and -giving *the same amount of Basic Income to everyone*. +\... we would answer that this work should not have been rewarded by +newly created Bitcoins. New units should be distributed to the whole +community. Miners should be rewared another way, but not by +money issuance. Of course, Bitcoin cannot create money through Basic +Income since Bitcoin users are not strongly identified, and one might +benefit from money creation multiple times if they owned several wallets. +Duniter gets rid of this problem by identifying its users and +creating the same amount of Basic Income to everyone. -#### Temporal-asymmetry +#### 1.1.2. Temporal-asymmetry {#temporal-asymmetry} Bitcoin has an absolute limit of 21 million BTC (its unit of currency), which means ever fewer bitcoins will be created over time until no new BTC are being generated. So, once the first adopters have mined every bitcoin, -how will future joiners get Bitcoins? Just like Euros or +how will future joiners get Bitcoins? Just like most of us do for Euros or Dollars: to get money, they will have to work for the ones who already own it. -**We believe this is the *second* injustice.** Every member of a + +We believe this is the second injustice. Every member of a monetary community should be equal concerning monetary creation, and get -the same relative amount of money over time, *even if they are a late -adopter*. Duniter aims to fix this by making the Universal Dividend -(a.k.a. *UD*) *grow by the time* (S.Laborde, 2010) according to precise rules, thus making +the same relative amount of money over time, even if they are a late +adopter. Duniter aims to fix this by making the Universal Dividend +(a.k.a. UD) grow by the time according to precise rules, thus making members equal toward money issuance on a half-lifespan. +Most currencies present one of these two asymmetries, including metal currencies +and mutual credit, as exposed in the RTM. +#### 1.1.3. A solution {#a-solution} - -#### A solution - -Bitcoin has taught us that *it is possible* to create a currency system +Bitcoin has taught us that it is possible to create a currency system allowing one to both create digital money and to exchange it without a -central authority. What we need to change is *the way money is issued* -so we finally have a symmetrical system. We need Bitcoin *+ Universal -Dividend*. But Universal Dividend *implies* that the community consists +central authority. What we need to change is the way money is issued +so we finally have a symmetrical system. We need **Bitcoin + Universal +Dividend**. But Universal Dividend implies that the community consists of only identified people. This is where the Web of Trust (WoT) comes -into place. This concept, introduced by cryptography with the -[OpenPGP](https://www.wikiwand.com/en/Pretty_Good_Privacy) format, -allows us to identify people in a *decentralized* manner. It works as -follows: each person creates *a personal identity* that is linked to its +into place. + +This concept, introduced by cryptography with the OpenPGP format[^OpenPGP], +allows us to identify people in a decentralized manner. It works as +follows: each person creates a personal identity that is linked to its cyptographic certificate. The identity must be confirmed by others -members who use their own cryptographic key. It is that simple: **people +members who use their own cryptographic key. It is that simple: people choose who is part of the community and who is not, not a central -authority.** +authority. -> Duniter however won\'t use OpenPGP for its cryptographic features: -> Elliptic Curves will be used instead for the conciseness of its -> generated keys and its pratical advantages. Duniter has its own Web -> of Trust principles, that shall be exposed later. +[^OpenPGP]: OpenPGP protocol defines standard formats for encrypted messages, signatures, private keys, and certificates for exchanging public keys. The GNU Privacy Handbook, M.Ashley, 1999 : [www.gnupg.org/gph/en/manual.html#AEN335](https://www.gnupg.org/gph/en/manual.html#AEN335) -### Proof-of-Work mining : a power race (TODO) +However, Duniter will not use OpenPGP for its cryptographic features: +Elliptic Curves[^Elliptic] will be used instead for the conciseness of its +generated keys and its pratical advantages. Duniter has its own Web +of Trust principles, that will be exposed later. -In Bitcoin Model, the calculation and incentive principles cause a power race : -new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. -The goal of Duniter is to make blockchain validation much less energy and hardware consuming while -keeping a strong level of security. As a consequence, even low-power hardware can secure Duniter Blockchain, -which leads to a better decentralization of forging operations. +[^Elliptic]: High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. [cr.yp.to/papers.html#ed25519](https://cr.yp.to/papers.html#ed25519). -### Other projects ? +### 1.2. Proof-of-Work mining : a power race {#proof-of-work-mining-a-power-race} -#### What about PoS ? +In Bitcoin Model, the calculation and incentive principles cause a power race : +new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. +This leads to a power race an places the control over the currency in the hands of the richest hardware owners. +We want to make Duniter blockchain validation much less energy and hardware consuming while +keeping a strong level of security. This will be further explained later. A consequence of +this choice is the participation of low-end hardware in the Duniter network, +leading to a better decentralization of blockchain validation. -When conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. -Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead -to placing power over the currency in the richests hands : this is contrary to the symmetical principles of Duniter. +#### 1.2.1 What about Proof of Stake ? {#what-about-proof-of-stake} -Now that PoS is well-tested, one could try to use Duniter's WoT to create a PoS-like algorithm with equal chances among members. -But this is not our aim for now. +Proof of stake consensus algorythm was first introduced in 2012[^PPCoin]. The basic principle is to allow the richest wallets to issue blocks, putting their coin balance as a "stake" they would lose in case of cheat. -#### What about Directed Acyclic Graph ? +[^PPCoin]: PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : [archive.org/details/PPCoinPaper](https://archive.org/details/PPCoinPaper) -The Circles project uses DAG in a basic income cryptocurrency. However, in this project, -one peer cannot know the whole monetary mass and the exact number of other peers. -The calculation of Universal Dividend `UD = c * M/N` seems impossible, since we know neither M nor N. +At the time of conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. We did not chose this consensus principle. +Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead +to placing power over the currency in the richests hands : this is contrary to the symmetical principles of a libre currency. -## Duniters Blockchain +## 2. Duniters Blockchain {#duniters-blockchain} <!-- source : https://duniter.org/en/theoretical/ --> @@ -130,138 +146,165 @@ Duniters Blockchain follows the basic principles of Bitcoins. This is essential for synchronization between peers, as to prevent double-spend attacks. However, Duniters Blockchain will store different informations than Bitcoins. -The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no *generation transaction* exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either: +The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no generation transaction exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either: * a former transaction (as in Bitcoin) * a Universal Dividend (specific to Duniter). -Duniters Web of Trust is also written in the Blockchain. The identity of each member gets registered much like transactinos are, with a strong link to the time reference. Thus, the Blockchain is a representation of a space-time frame of reference, where "space" are members of the WoT and "time" the basci blockchain units : the blocks. On each point of time, one can determain whick account is legitimate to create the UD, only with a blockchain analysis. +Duniters Web of Trust is also written in the Blockchain. The identity of each +member gets registered much like transactions are, with a strong link to the +time reference. Thus, the Blockchain is a representation of a space-time frame +of reference, where "space" are members of the WoT and "time" the basic blockchain +units : the blocks. On each point of time, one can determine which account is +legitimate to create the UD, only with a blockchain analysis. +### 2.1. Spam countermeasures {#spam-countermeasures} -### Spam countermeasures (TODO) -An issue of most cryptocurrency projects is to prevent the common ledger from growing too much and require lot of storage and computing power to be usable. In particular, we don't want an attacker to be able to make the Blockchain grow too fast. Most projects implement transaction fees as a way to prevent this, making the attacker lose money. We don't want to do this since a currency with automatic fees on transactions is no more neutral. Several countermeasuers against such spam attacks are implemented. +An issue of most cryptocurrency projects is to prevent the common ledger from +growing too much. This would require nodes to have a lot of storage and computing +power to be usable. In particular, we don't want an attacker to be able to make the +Blockchain grow too fast. Most projects implement transaction fees as a way to prevent +this, making the attacker lose money. We don't want to introduce this mean since a +currency with automatic fees on transactions is no more neutral. Several +countermeasuers against such spam attacks are implemented. <!-- see : https://forum.duniter.org/t/sans-frais-de-transaction-comment-resister-aux-attaques/3846/25 (implemented ?)--> -* output minimal de 100*Unitbase / 1 unité -> empêche un attaquant de faire grossir la BC et les index trop vite (DUBP v12) -* chaînage maximal des tx -* seuils de dépense (implémentés ? en tout et par issuer ?) +#### 2.1.1. Minimum output amount {#minimum-output-amount} + +<!-- This has to be implemented in DUBPv13. --> + +Fixing a minimal output amount reduces the power of an attack. Duniter deals with cents of Ğ1 or 1/1000 of the first UD. An attacker could create thousand accounts with only 1 UD. To prevent this, a valid transaction must have output amounts of minimum 1Ğ1. This reduces the power an attack by 100. + +#### 2.1.2. Limited block size and chainability {#limited-block-size-and-chainability} + +The block size is always limited. While the protocol allows this limit to evolve to address scaling issues, an attacker cannot register as many transaction as they wish. -### Scaling +With the same goal to prevent too many transactions to get registered, while transactions can be "chained" (refer to another transaction in the same block), the chainability of transactions is limited to 5. + + +### 2.2. Scaling {#scaling} Most of the time, the scaling issue rises for distributed systems that should work on a very large scale. This is not the case of Duniter, for multiple reasons : -* Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don't want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT limits its size to around 16 million members. -* Duniter's aim is to be used to create *multiple* libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community. +* Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don't want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT should limit its size to around 16 million members. +* Duniter's aim is to be used to create multiple libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community. -However, Duniter has two assets that might be used if the number of users grow. +However, Duniter has assets that will help if the number of users and transactions grow. -#### Dynamic block size +#### 2.2.1 Dynamic block size {#dynamic-block-size} While Bitcoin has a fixed block size, Duniters blocks size can evolve. On low use of the blockchain, the maximal block size is 500 bytes. -On high use of the blockchain, the maximal block size would be 110% of the average size of the current window blocks( *current window* will be described in the PoW part). -This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it. +On high use of the blockchain, the maximal block size would be 110% of the +average size of the current window blocks(see "personalised difficulty" part for more information). +This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it. The block size (in bytes) is limited as so : -:::{highlight} +``` block_size < max(500 ; CEIL(1.10 * (average block size)) -::: - +``` -#### Lightning Networks +#### 2.2.2. Lightning Networks {#lightning-networks} -The Lightning Networks allow almost instant and off-chain transactions. +The Lightning Networks[^Lightning] allow almost instant and off-chain transactions. They were first implemented on Lightcoin, and are now on Bitcoin. One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. While not available yet, this payment channel might get implemented when needed. +[^Lightning]: The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : [lightning.network/lightning-network-paper.pdf](http://lightning.network/lightning-network-paper.pdf) + +#### 2.2.3. Unit base {#unit-base} + +As the Universal Dividend grows exponentially, with time Duniter nodes would have had to deal with always largest amounts, eventually reaching the BIGINT limit. To avoid this, the amounts are expressed with a unit base in base 10. We want the UD amount to always fit in 4 digits. To manage it, the `unitbase` is updated each time the UD value reaches 100.00 : it goes from `99.99*10^(unitbase)` to `10.00*10^(unitbase+1)`. All the unit amounts are thus divided by 10. While this might seem strange, this process has already hapened in state currencies. Moreover, the amounts expressed in UD will not change. + +With a monetary growth of 10% each year and a stable population, such a change of unit base would happen each 25 years. -## Duniter Web of Trust +## 3. Duniter Web of Trust -<!-- source : https://duniter.org/en/deep-dive-into-the-web-of-trust --> -### Basic Principles +### 3.1. Basic Principles {#duniter-wot-basic-principles} -In order to identify "members" account - which create monetary units - from other accounts, Duniter uses a Web of Trust. This can be summarized into few principles: +In order to identify "members" accounts - which create monetary units - +and other accounts, Duniter uses a Web of Trust. This can be summarized +into few principles: -* Each account becomes a member if it received a minimal number of certifications (5 for Ğ1 currency) -* Only members accounts can send certifications. Certifications have a limited lifespan. -* A certification indicates that the sender accepts the receiver as a legitimate identity. +- Each account becomes a member if it received a minimal number of + certifications - 5 for Ğ1 currency. +- Only members accounts can send certifications. Certifications have a + limited lifespan. +- A certification indicates that the sender accepts the receiver as a + legitimate identity. -The aim of the WoT is to identify a blockchain account to a living human. Each member of the Ğ1 currency signs a licence stating that they will only certify humans they know well (among other rules). -Thus, if a member is part of an attack on the currency, they can be found by mutual friends. The security of Ğ1 currency stands on: +The aim of the WoT is to identify a blockchain account to a living +human. According to Lauterbach et.al[^Couchsurf], the strengh of a relationship should be considered when building a vouch system. +For this reason, the Ğ1 Web of Trust rules are expressed in a licence stating what WoT certifications are. +A certification represents a strong human relationship : one may certify a close relative, not an acquaintance. +Each member has to accept this licence before being included in the WoT. +Thus, if a member is part of an attack on the currency, they can be found by mutual relatives. +Additional security rules occur to prevent cheat and attacks on a large scale. -* Corroborating informations on members (5 certifications) -* Peer pressure by close relatives -* Law if the licence has not been respected. +[^Couchsurf]: Surfing a Web of Trust, Reputation and Reciprocity on CouchSurfing.com, D.Lauterbach, H.Truong, T.Shah, L.Adamic: [snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf](http://snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf) -Note that non-members accounts can use the currency, but cannot create money. They can be used by individuals as secondary wallets, or by institutions. +Note that non-members accounts can use the currency, but cannot create +money. Non-members accounts can be used by individuals as secondary wallets, or by +institutions. -However, the WoT does not rely only on trust betwenn people. Rules have been added to increase the security, and we will present them. +We were inspired by the OpenPGP Trust system[^OpenPGP_Trust]. However, the OpenPGP +trust principles aim at defining trust from a particular point of view while Duniter needs to +identify humans for the whole community. To achieve this goal, while OpenPGP allows each +user to tweak its trust parameters individually, Duniter sets rules in the "genesis" block for the whole community. +[^OpenPGP_Trust]: Public key validation on GnuPG manual, M.Ashley, 1999 : [www.gnupg.org/gph/en/manual.html#AEN335](https://www.gnupg.org/gph/en/manual.html#AEN335) -### Why do we need a Web of Trust? +### 3.2. Why do we need a Web of Trust ? {#why-do-we-need-a-web-of-trust} There are two reasons we need it : 1. To make sure that only one Universal Dividend is produced per member - at each specified creation interval -in the Ğ1's case this interval - is set as daily `86 400` seconds-, it is the *monetary parameter* - known as `dt`-. -2. To identify the nodes hashing the blocks and assign them each a - personalised difficulty. This custom difficulty [proof of - work](https://en.wikipedia.org/wiki/Proof-of-work_system) is there - to avoid the blockchain's validation mechanism becoming too + at each specified creation interval. In the Ğ1's case this interval + is set as daily `86 400` seconds, it is the *monetary parameter* + known as `dt`. +2. To identify the nodes hashing the blocks and assign each a + personalised difficulty. This custom difficulty proof of work is + there to avoid the blockchain's validation mechanism becoming too centralised as is the case with many \'non-libre' cryptocurrencies. - > Wait, what's a 'monetary parameter' ? - -Every currency implementing Duniter has its own blockchain whose -behaviour is dictated by a set of 'parameters' -defined in block zero, -the so-called genesis block- that can be tweaked to achieve the desired -results. At the time of writing this article, the Duniter protocol -aka -DUP- has a total of 21 parameters of which 10 are for the WoT alone. -We'll focus on these 10. - -Suffice to say that in the Ğ1's case, the DU is created every 24 hours --86 400 seconds- but this interval -set through the time derivative `dt` -parameter- can have a different value in an other implementation of the -protocol. - -I won't write about the second parameter having to do with the proof of -work, it's outside our scope here, just know that the Web of Trust -allows us to **identify** the members providing hashing power, which we -couldn't do without it. This crucial feature means we can impose a -rotation between the members hashing the blocks so that no single rich -individual or group invests in a giant 'hash farm' and takes a hold of -the blockchain, paralysing the community! - -Let's go back to the first objective: to make sure that each member can -only have one account. As we all know, achieving zero-risk isn't -possible, our goal is therefore not to create a WoT within which fraud -would be absolutely impossible but instead to discourage it. Here is a +> **Monetary parameter** : Each currency that use Duniter has its own blockchain whose behaviour is +> dictated by a set of 'parameters' defined in block zero - the so-called +> genesis block - that can be tweaked to achieve the desired results. At +> the time of writing the Whitepaper, the Duniter Blockchain Protocol +> (DUBP) has a total of 21 parameters of which 10 are for the WoT alone. +> We'll focus on these 10. +> +> Suffice to say that in the Ğ1's case, the DU is created every 24 hours - +> 86 400 seconds. This interval is set through the time derivative `dt` +> parameter and can have a different value in other implementations of the +> protocol. + +We want to make sure that each member can only have one account. As we +all know, achieving zero-risk isn't possible[^Sybil_Attack]. +Our goal is therefore not to create a WoT within which fraud +would be absolutely impossible, but instead to discourage it. Here is a rewording of our goal in 4 smaller ones : -1. To make the certification process lengthy enough that all members +1. Make the certification process lengthy enough that all members exercise due diligence and are wary of risks. -2. To make fraudulent acts as hard as we can to the extent that they +2. Make fraudulent acts as hard as we can to the extent that they become pointless. -3. To ensure that any Sybil attacks have a negligible impact on the - currency -*by ensuring that illegitimate double Universal Dividends - have no significant bearing on the legitimate monetary mass*- -4. To slow the growth of 'Sybil regions' to give enough time for the +3. Ensure that any Sybil attacks have a negligible impact on the + currency by ensuring that illegitimate double Universal Dividends + have no significant bearing on the legitimate monetary mass +4. Slow the growth of 'Sybil regions' to give enough time for the community to react and isolate the threat. + +[^Sybil_Attack]: The Sibyl Attack, J.R.Douceur: [www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf](https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf) -> **Wait, a Sybil what ?** - -A [**Sybil attack**](https://en.wikipedia.org/wiki/Sybil_attack), is the -name given to attacks perpetrated on a reputation system through the -creation of fake identities. A Web of Trust is a specific instance of a -[**Reputation -System**](https://en.wikipedia.org/wiki/Reputation_system). +> **Sybil attack** : A Sybil attack is an attack perpetrated on a +> reputation system through the creation of fake identities. A Web of +> Trust is a specific instance of a Reputation System. There are plenty of Sybil attack scenarios we can think of and just as many reasons why their perpetrators would want to carry them out. Our @@ -272,23 +315,28 @@ This means that micro-attacks performed by small groups of individuals looking for personal enrichment are of no interest to us. The web's role isn't to deter these attacks, this being instead the role of the community. Just like the town you live in is responsible for providing -your tap water and electricity but isn't responsible for any burglaries +your tap water and electricity but isn't responsible for any burglaries, etc. Much in the same way, Duniter's WoT guarantees us all a functional -currency and that's quite a feat in itself! +currency, but do not detect small fraud. + +### 3.3. The importance of having our own certification system {#own-certification-system} -### The importance of having our own certification system +Centralized identification systems can achieve the goal we want. State +Identification is an example. However, this has many drawbacks : -We are regularly offered to switch over to third-party or state-owned -authentication systems but these are centralised and go against the -principles of our community. We feel that we would lose our independence -and universality by adopting a state-controlled system. People without -an official state-provided identity or homeless people would also run -the risk of being excluded from the WoT. It is of the utmost importance -that we remain free from any state or corporation. To this day we depend -only on the Internet and yet, were it to fail, there are already -alternatives being tested around the world for a decentralised network. +* The authority may have arbitrary criteria for identification, for example +preventing people without an official state-provided identity or +homeless people to be included in the WoT. +* Payment might be required +to get identified, thus making the monetary creation not "free". +* The authority is a point of failure for any attacker. -### A few foundational concepts on graph theory : a bit of vocabulary +It is of the utmost importance that we remain free from any state or +corporation. The WoT is an answer to this criterium. To this day we +depend only on the Internet and yet, were it to fail, there are already +alternatives being tested around the world for a decentralised communication network. + +### 3.4. A few foundational concepts on graph theory : a bit of vocabulary {#graph-theory-vocabulary} - **Graph**: set of points -called 'vertices'- joined by edges -called paths/walks-. @@ -298,12 +346,10 @@ alternatives being tested around the world for a decentralised network. have the same endpoints. A simple edge is an edge that is not part of a multiple adjacency -of edges-. In many cases, graphs are assumed to be simple unless specified otherwise. - [Wikipedia](https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms) - + - **Directed graph**: a graph in which the edges have a distinguished direction, from one vertex to another. A directed edge can also be called a path or walk. - [Wikipedia](https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms) Arrow A --\> B is therefore different from arrow B --\> A. - **Endpoints**: the edge with vertex A --\> B has A and B as @@ -311,7 +357,6 @@ alternatives being tested around the world for a decentralised network. - **Isolated vertex**: a vertex whose degree is zero, that is, a vertex with no incident edges. - [Wikipedia](https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms) - **Degree of a vertex**: number of its incident edges -in and out-. @@ -321,59 +366,52 @@ alternatives being tested around the world for a decentralised network. - **In-degree of vertex A**: number of incoming edges / head ends to A. - + - **Path**: -aka "walk"- path to follow to get from vertex A to vertex B. -### Definition of the Duniter Web of Trust +### 3.5. Definition of the Duniter Web of Trust {#definition-of-the-duniter-web-of-trust} The Duniter WoTs -one per currency- are simple directed graphs without isolated vertices. The vertices are the members and the edges are the certifications given and received. -Directed, what does that mean? - -The responsibility of issuing a certification is unique and personal to -the certifier. The trust he/she places in the receiver cannot be imposed -in the other direction although in most circumstances both parties -equally trust each other. +*Directed* means that the responsibility of issuing a certification is +unique and personal to the certifier. The trust they place in the +receiver cannot be imposed in the other direction although in most +circumstances both parties equally trust each other. In addition, all vertices are either currently active members or past-members. Past-member vertices are in a specific 'deactivated state' and can no longer issue or receive certifications although the ones already issued or received to/from other members are still considered -'pending' to avoid the web collapsing like a house of cards. - -If these old members don't come back into the web, their pending -certifications will eventually expire and they will switch from -'deactivated' to 'isolated' vertices. +'pending' to avoid a collapse of the WoT. If these old members don't +come back into the WoT, their pending certifications will eventually +expire and they will switch from 'deactivated' to 'isolated' vertices. -To wrap up with old members, after a certain period of time -set in the +To wrap up with old members, after a certain period of time - set in the currency's parameters - their deactivated vertex is removed from the web and the associated identity is 'revoked'. The person who owned the account can no longer use this identity but is free to join the web with -another one. :-) - -> What do you mean by 'identity'? +another one. -An identity is a set of three pieces of information: a public key, a -name and a blockstamp. A blockstamp points to a specific block in the -chain. Its main use is to freeze the point in time at which an identity -was created and to link this identity to a specific chain and of course, -a currency -each currency having its own blockchain-. - -An identity can be in any one of 5 different status: pending, member, -old member, revoked or excluded. +> **Identity** : An identity is a set of three pieces of information: a public key, a +> name and a blockstamp. A blockstamp points to a specific block in the +> chain. Its main use is to freeze the point in time at which an identity +> was created and to link this identity to a specific chain and a currency +> - each currency having its own blockchain. +> +> An identity can be in any one of 5 different status: pending, member, +> old member, revoked or excluded. Let's take a simple example: -::: {.highlight} +``` A -> B -> C | \--> D -::: +``` If, for whatever reason, A were to lose its member status, the web would crumble and all other members would be excluded as a consequence. To @@ -383,80 +421,73 @@ or D. Because our WoT doesn't have any isolated vertices, each new identity created needs to be pulled into the web with all of the certifications -it has received -in the same block-. This calls for a temporary 'buffer' -storage space for **pending** identities and the certifications they've -received. This storage space is called 'the pool' -of Duniter nodes- -which we could also have called the 'sandbox' as that's the name used in -Duniter's code. I might add that these 'pools' also include other +it has received, all in the same block. This calls for a temporary +'buffer' storage space for **pending** identities and the certifications +they have received. This storage space is called 'the pool' of Duniter +nodes, which we could also have called the 'sandbox' as that's the name +used in Duniter's code. Duniter nodes inclued other 'pools' for other documents and metadata not mentioned here. -### Exploring the rules behind a Duniter Web of Trust +### 3.6. Exploring the rules behind a Duniter Web of Trust {#exploring-the-rules-behind-duniter-wot} -The Duniter WoTs -one per currency- work with a set of eight fundamental -rules, themselves enforced through eleven different parameters. Ten of +The Duniter WoTs - one per currency - works with a set of eight +fundamental rules enforced through eleven different parameters. Ten of these parameters are set within the genesis block, the eleventh one - `msPeriod`- having being hard-coded in the Ğ1's code subsequently. -#### 1.Distance rule and referent members (`stepMax` and `xPercent`) {#1distance-rule-and-referent-members-stepmax-and-xpercent} +#### 3.6.1. Distance rule and referent members (`stepMax` and `xPercent`) {#distance-rule-and-referent-members-stepmax-and-xpercent} These two parameters are closely linked and together define the 'distance rule'. The 'distance rule' can only be described after defining what a 'referent member' is: > **Referent member**: member A is said to be 'referent' if and only if -> the total of his/her degrees are greater than or equal to -> `CEIl-N^-1/stepMax--` where N is the total number of members.\*\* As -> the size of the web will grow this number will grow too, meaning it -> will take more certification issuances to become a referent member as -> the number of certifications needed to become a member shouldn't -> change. +> the total of their degrees are greater than or equal to +> `CEIL-N^-1/stepMax` where N is the total number of members. As the +> size of the web will grow this number will grow too, meaning it will +> take more certification issuances to become a referent member. The +> number of certifications needed to become a member shouldn't change. Let's now define the distance rule: > **Distance rule**: member A is said to observe this rule if and only > if for a subset xPercent % of referent members R there exists a path -> of length less than or equal to `stepMax` between R and A.\*\* +> of length less than or equal to `stepMax` between R and A. Referent members only exist so that the distance rule can take effect, they have no special privileges over non-referent members. In a perfect -web, that is one in which each member has certified all members he/she +web, that is one in which each member has certified all members they legitimately can, all members would be referent members. However, because the web progressively grows in size and because members die and are replaced by new ones, there are always members at any given time `t` who haven't yet certified all members they legitimately could. These members would hinder the evolution of the web if they were taken into account in the calculation of the distance rule and the web would -effectively stop growing. -You can see what would happen if the notion -of 'referent member' didn't exist by going to the 'gaussianWotQuality' -page on -[currency-monit](https://g1-monit.librelois.fr/gaussianWotQuality?lg=en&unit=quality) -and activating 'if the concept of referent members didn't exist'-. - -> **When is the distance rule applied?** +effectively stop growing. Because verifying the application of the distance rule is calculation-greedy, it is only performed when a new identity gets -confirmed into the web or an existing member gets renewed. *Exception to -the rule: the distance rule is not observed in the genesis block -when -the web is first implemented-.* +confirmed into the web or an existing member gets renewed. There is an +exception to this rule: the distance rule is not observed in the genesis +block -when the web is first implemented. -#### 2. Rule of the minimum number of certifications needed (`sigQty`) {#2-rule-of-the-minimum-number-of-certifications-needed-sigqty} +#### 3.6.2. Rule of the minimum number of certifications needed (`sigQty`) {#rule-of-the-minimum-number-of-certifications-needed-sigqty} This is the simplest rule, it essentially says that each member must at any given time -meaning in any single block- have received at least `sigQty` active certifications. If, for whatever reason, member A were -to have less than `sigQty` active certifications in a given block, -he/she would cease being a member and be required to publish a request -for identity renewal. +to have less than `sigQty` active certifications in a given block, they +would cease to be a member and be required to publish a request for +identity renewal. -#### 3. The membership renewal rule (`msValidity`, `msPeriod` and `msWindow`) {#3-the-membership-renewal-rule-msvalidity-msperiod-and-mswindow} +#### 3.6.3. The membership renewal rule (`msValidity`, `msPeriod` and `msWindow`) {#the-membership-renewal-rule-msvalidity-msperiod-and-mswindow} Bear in mind that a membership doesn't last a lifetime but instead has a lifespan set to `msValidity` seconds. Every single member -or old member who hasn't revoked his identity or been excluded- can request a membership renewal so long as the last -request was made more than `msPeriod` seconds ago -if a member has never +request was made more than `msPeriod` seconds ago. If a member has never requested a renewal, the date of last renewal is equal to the timestamp at which his membership was first created. A new request will be stored in the 'pool' for a maximum of `msWindow` seconds before it's included @@ -466,25 +497,25 @@ are already matched it's just a case of waiting for a new block to be mined-. If a member hasn't requested a renewal for longer than `msValidity` -seconds, he/she automatically ceases being a member. From this moment -on, the ex-member has another `msValidity` window to renew his/her -membership. When this period of \`2 × msValidity' runs out, the -membership will expire and this identity will never be available for use -again in the web. If the person so desires, he/she will have to start -from zero to regain access to the WoT. +seconds, they automatically cease to be a member. From this moment on, +the ex-member has another `msValidity` window to renew their membership. +When this period of `2 × msValidity` runs out, the membership will +expire and this identity will never be available for use again in the +web. If the person so desires, they will have to publish new identity +and membership documents and find enough certifiers, as any newcomer. -#### 4. Rule of certification lifespan (`sigValidity`) {#4-rule-of-certification-lifespan-sigvalidity} +#### 3.6.4. Rule of certification lifespan (`sigValidity`) {#rule-of-certification-lifespan-sigvalidity} All certifications included in the blockchain expire **sigValidity** seconds after they were **issued**. -/!\\ The issuance and the inclusion of a certification in the blockchain -occur at different times. When member A issues a certification at time -t1, it gets stored in the pool starting at t1 and only finds its way -into the blockchain at t2 when all of the web's rules are observed. -Several weeks can thus go by between t1 and t2!!! +> /!\\ The issuance and the inclusion of a certification in the +> blockchain occur at different times. When member A issues a +> certification at time t1, it gets stored in the pool starting at t1 +> and only finds its way into the blockchain at t2 when all of the web's +> rules are observed. Several weeks can thus go by between t1 and t2!!! -#### 5. Rule of limited supply of active certifications (`sigStock`) {#5-rule-of-limited-supply-of-active-certifications-sigstock} +#### 3.6.5. Rule of limited supply of active certifications (`sigStock`) {#rule-of-limited-supply-of-active-certifications-sigstock} By 'active certifications' we refer to certifications included in the blockchain and that haven't yet expired. @@ -494,26 +525,26 @@ time must be less than or equal to `sigStock`. When this threshold is reached the member will have to wait for one of his active certifications to expire before he/she can issue a new one. -#### 6. Rule of the time period between two certification issuances. (`sigPeriod`) {#6-rule-of-the-time-period-between-two-certification-issuances-sigperiod} +#### 3.6.6. Rule of the time period between two certification issuances. (`sigPeriod`) {#rule-of-the-time-period-between-two-certification-issuances-sigperiod} As soon as a certification issued by member A gets included in the -blockchain, he/she will be unable to issue a new one before another +blockchain, they will be unable to issue a new one before another `sigPeriod` seconds. -#### 7. Expiry of a certification issuance (`sigWindow`) {#7-expiry-of-a-certification-issuance-sigwindow} +#### 3.6.7. Expiry of a certification issuance (`sigWindow`) {#expiry-of-a-certification-issuance-sigwindow} When a certification is issued by member A, it will be stored in the 'pool' for a maximum of `sigWindow` seconds. If the certification hasn't been included in the blockchain by then, it will be cancelled and the member's `sigStock` will be repleted by one. -#### 8. Lifespan of a 'pending' active certification (`idtyWindow`) {#8-lifespan-of-a-pending-active-certification-idtywindow} +#### 3.6.8. Lifespan of a 'pending' identity (`idtyWindow`) {#lifespan-of-a-pending-identity-idtywindow} When a new identity is created, it is stored in the 'pool' for a maximum of `idtyWindow` seconds. If the person hasn't achieved member status by then, the certification will simply be cancelled. -### Details on some of the WoT's peculiarities at the genesis block. {#details-on-some-of-the-wots-peculiarities-at-the-genesis-block} +### 3.7. Details on some of the WoT's peculiarities at the genesis block {#details-on-some-of-the-wots-peculiarities-at-the-genesis-block} The aforementioned rules can only be enforced with an existing web. They cannot be observed when first creating the web, that is when defining @@ -522,25 +553,25 @@ the genesis block. Only rules 2 and 5 can be observed at the genesis block. The genesis block has to be manually created by the founding members. In -practice this means that there must be a choice of which identities to +practice this means that there must be a choice on which identities to include on the premise that all of them observe rules 2 and 5. In addition, the genesis block must be signed with the private key of one of these identities. As soon as the genesis block has been created, the other identities can -start mining the blockchain and the member who begat block \#0 +start mining the blockchain and the member who created block \#0 effectively looses the decision power he had at creation. -### Why these rules and application cases in the Ğ1 {#why-these-rules-and-application-cases-in-the-g1} +### 3.8. Why these rules and application cases in the Ğ1 {#why-these-rules-and-application-cases-in-the-g1} -#### 1. Distance and maximum size {#1-distance-and-maximum-size} +#### 3.8.1. Distance and maximum size {#distance-and-maximum-size} The distance rule is there to curb the maximum size of a Sybil region as well as that of the monetary community as a whole. The `xpercent` parameter prevents the creation of a 'faction' that could take hold of the blockchain. - + The Sybil regions are isolated from the rest of the graph in the sense that they can only receive certifications from other ill-intentioned @@ -550,34 +581,36 @@ endpoint. The maximum depth the Sybil region can attain is therefore contingent on the distance between the attacking edge-s- and the xpercent% closest referent members, this distance is known as `stepAttackers`. The maximum size of a Sybil region created by `sigQty` -members depends on the L parameter, defined as L = sigQty/sigStock: +members depends on the L parameter, defined as `L = sigQty/sigStock`: -::: {.highlight} - Maximum Sybil region size = (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L) -::: +``` +MaxSybilSize= (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L) +``` The maximum size of the Web of Trust is given by the following formula: -::: {.highlight} - WoTmax = (sigStock)*L^(stepMax-1) -::: +``` +WoTmax = (sigStock)*L^(stepMax-1) +``` However we know for a fact that members will never use all of their -available certifications. Many studies have proven that we all know a -maximum average of fifty people, let's then replace sigStock by fifty: +available certifications. +According to Dunbar[^Dunbar], on average, one is able to maintain relationships to around 150 people. +Being conservative, we will consider that on average, each person will certify 50 accounts. +We can calculate the size of the average web of trust `WoTavg` : + +``` +WoTavg= (50)*(sigQty/50)^(stepMax-1) +``` + +[^Dunbar]: Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992 -::: {.highlight} - WoTavg= (50)*(sigQty/50)^(stepMax-1) -::: Our goal with the Ğ1 is to create a community of about one million -members enjoying the world's first true -[catallaxy](https://en.wikipedia.org/wiki/Catallaxy) -free economy with -a spontaneous order of things-. Let's see how we can tweak the pair of -sigQty and stepMax- to reach this size: +members to test the consequences of a libre monetary system. Let's see +how we can tweak the pair of sigQty and stepMax- to reach this size: - + The maximum size of a Sybil region grows linearly with `sigQty` but exponentially with `stepMax`. Logic has it that we need to keep @@ -598,13 +631,23 @@ knowing that the smaller `sigQty` is, the easier it is to launch a Sybil attack -it's easier to find four accomplices than five-. For security reasons we have settled on five: -stepMax = 5 sigQty = 5 sigStock \>= 50 +``` +stepMax = 5 +sigQty = 5 +sigStock \>= 50 +``` The maximum size of a Sybil region therefore is: -`(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5))` + +``` +(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5)) +``` with sigStock = 50 we have a Sybil region of: -`45*(1-10^(5-stepAttackers))/(-9)` + +``` +45*(1-10^(5-stepAttackers))/(-9) +``` A good practice for protecting the web is to maximise `stepAttackers`. That's why we decided that referent members in the genesis block had to @@ -618,7 +661,7 @@ renewed. But what if bot accounts were created and certified each other super fast and following all rules, how would we counter that? By introducing a minimum length of time between two certifications! -#### 2. Time is our friend {#2-time-is-our-friend} +#### 3.8.2. Time is our friend {#time-is-our-friend} To help us deter a Sybil attack, we've decided to impose a minimum period of time between any two certifications issued from a single @@ -626,12 +669,12 @@ account. This parameter called `sigPeriod` affords us a greater chance to detect the formation of a 'hostile' faction. Here is a graph showing the evolution of a Sybil region with the -variation of `sigPeriod`: +variation of `sigPeriod`. The simulation considers that honest members +and attackers both issue a certification each `sigPeriod` interval, in days: - + -As you'll easily be able to tell, there is a strong link between the +As we see, there is a strong link between the growth speed of the region and `sigPeriod`. As evidenced here, we need a `sigPeriod` high enough in order to ensure that the legitimate web can grow at least as fast as a Sybil region. In addition, the higher @@ -641,47 +684,47 @@ gingerly, the action coming at a higher 'cost'. There are numerous advantages to giving `sigPeriod` a high value and no technical barriers to it, hence our choice of five days. -We could have also gone for days days -one week- for the sake of -simplicity however there was an underlying idea behind our choice which -was quite simply the pace of today's life. Certifying someone can be a -lengthy process as one needs to make sure he/she is correctly applying -the Ğ1 licence and people nowadays wait for the weekend to enjoy a bit -of free-time. Thus the idea to allow one to certify at the end of every -working week -five days- instead of a whole calendar one. +We could have also gone for one week for the sake of simplicity. However +there is an underlying idea behind our choice which was quite simply the +pace of today's life. Certifying someone can be a lengthy process as one +needs to make sure they are correctly applying the Ğ1 licence and people +nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea +to allow one to certify at the end of every working week -five days- +instead of a whole calendar one. -#### 3. Trust me now, trust me forever? (`sigValidity`, `msValidity`) {#3-trust-me-now-trust-me-forever-sigvalidity-msvalidity} +#### 3.8.3. Trust me now, trust me forever ? (`sigValidity`, `msValidity`) {#trust-me-now-trust-me-forever-sigvalidity-msvalidity} There would be two main drawbacks to a lifetime membership in the Ğ1's Web of Trust: -> First of all we need to take into account that some members will pass -> and those accounts should no longer produce the Universal Dividend. -> Secondly it is of the utmost importance that 'rogue' accounts can be -> excluded from the web at some point. +- First of all, some members will pass and those accounts should no + longer produce the Universal Dividend. +- Secondly it is of the utmost importance that 'rogue' accounts can be + excluded from the web at some point. -To achieve this, certifications have a limited lifetime and members need -to seek renewal from their peers after `sigValidity` time. On the other +To achieve this, certifications have a limited lifespan. Members need to +seek renewal from their peers after `sigValidity` time. On the other hand, this time can't be too short that members would spend more time seeking renewal than they would exchanging in the currency. Furthermore, -a certification with too short a lifetime would foster careless -certifying behaviours. The act of certifying must have a 'perceived' -cost high-enough to make it feel like an important act. Lastly, we also -wanted this lifetime to be easy enough to remember. Historically -speaking, we first settled on the values of `sigPeriod` and `sigStock`, -meant one could issue all of his/her certifications in 495 days, one -year was therefore not long enough. We deemed three years to bee much -and that's how we agreed on two years in the end. +a certification with too short a lifespan would foster careless +certifying behaviours. The act of certifying must have a high-enough +'perceived' cost to make it feel like an important act. Lastly, we also +wanted this lifespan to be easy to remember. Historically speaking, we +first settled on the values of `sigPeriod` and `sigStock`, meant one +could issue all of their certifications in 495 days, one year was +therefore not long enough. We deemed three years to be too much and +that's how we agreed on two years in the end. Thinking that a deceased member could continue producing the UD for two long years without anyone benefitting from it was also something we -needed to address. We choose a value of one year for **msValidity**. The +needed to address. We chose a value of one year for **msValidity**. The act of renewing every year is done through one of the clients interacting with the blockchain, through a simple click on a button. This parameter is less important than others and is mostly there to 'prune' the web of past or inactive members who don't renew their membership. -#### 4. Keeping the pools free of information glut -(`idtyWindow`, `sigWindow`, `msWindow`) {#4-keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow} +#### 3.8.4. Keeping the pools free of information glut (`idtyWindow`, `sigWindow`, `msWindow`) {#keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow} The pools need to be cleaned up on a regular basis to avoid them clogging up with information and to ensure that machines with less @@ -698,16 +741,15 @@ wanted a time period that would be easy enough to remember by all. We settled on two months, and gave this value to all three parameters `idtyWindow`, `sigWindow` and `msWindow`. -#### 5. Avoiding single members from 'knowing too many people' (`sigStock`) {#5-avoiding-single-members-from-knowing-too-many-people-sigstock} +#### 3.8.5. Avoiding single members from 'knowing too many people' (`sigStock`) {#avoiding-single-members-from-knowing-too-many-people-sigstock} -Many sociology studies have shown that we all know an average of fifty -people. This of course is an average, some of us know more than fifty -people, others much less. Once again we went for a number that would be -easy to remember. Although `sigStock`'s impact on the size of a Sybil -region is fairly limited, its value nonetheless has to be kept -reasonable. We settled on hundred. +We considered that on average, each person will certify 50 people. +However, we know for a fact that some members will use more than 50 certifications. +The maximum social network of one individual is around 150 people[^Dunbar]. +Being conservative, we settled on a maximum certification number `sigstock` of 100. +Since `sigStock`'s impact on the size of a Sybil region is fairly limited, we did not investigate further this parameter. -#### 6. Avoiding locking minorities (`xpercent`) {#6-avoiding-locking-minorities-xpercent} +#### 3.8.6. Avoiding locking minorities (`xpercent`) {#avoiding-locking-minorities-xpercent} It's easy enough to become a referent member, one of the Sybil strategies could therefore be to create a region of referent members. @@ -722,19 +764,20 @@ This percentage needs to be low enough to prevent the formation of a locking minority -referent Sybil members being too far from legitimate referent members-. On the other hand, it needs to be high enough so as to restrict the maximum size of the Sybil region through the distance -rule. The `xpercent` parameter was one of the hardest to define, we -therefore reserve ourselves the right of modifying its value during the -Ğ1 experiment. +rule. The `xpercent` parameter was one of the hardest to define, +therefore we might decide to change its value during the Ğ1 experiment. -We were inspired by the [Pareto -principle](https://en.wikipedia.org/wiki/Pareto_principle): if at least +We were inspired by the Pareto +principle[^Pareto]: if at least 20% of members give good density to the web, 80% of the referent members -will be five or less steps from any other member -referent or non-. The +will be five or less steps from any other member -referent or not-. The maximum value for `xpercent` is therefore 80%, anything above that and the distance rule could be too restrictive for legitimate use cases. With security our top concern, we chose the maximum value of 80%. -#### 7. Spam protection with (`msPeriod`) {#7-spam-protection-with-msperiod} +[^Pareto]: Pareto principle : [en.wikipedia.org/wiki/Pareto_principle](https://en.wikipedia.org/wiki/Pareto_principle) + +#### 3.8.7. Spam protection with (`msPeriod`) {#spam-protection-with-msperiod} This parameter stands out a bit on its own, as it was added after the genesis block. It is there to protect the Duniter P2P infrastructure @@ -744,13 +787,14 @@ every five minutes- or worse still, hundreds of these requests per minute to flood the Duniter nodes. Without such limits, nodes are supposed to address all renewal requests, even in cases where they were last published five minutes ago! The `msPeriod` parameter was given the -same value as `idtyWindow`, `sigWindow` and `msWindow`, i.e. two months. +same value as `idtyWindow`, `sigWindow` and `msWindow`, i.e. two months. + -## Proof of Work with personal difficulty +## 4. Proof of Work with personal difficulty {#proof-of-work-with-personalized-difficulty} As each P2P cryptocurrency, Duniter has a way to synchronize its peers. It uses a proof of Work (PoW) to write the Blockchain on a regular basis, much like BitCoin. However, Duniter has a unique asset : the WoT, where each member represents a unique living human. -This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each "winning" member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. The knowledge of the whole network is not needed. +This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each "winning" member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. A view of the whole network is not needed. Another strong difference is that forging peers are not rewarded by the protocol. There is no economical incentive on forging lots of blocs, neither on having a lot of computing power. @@ -760,7 +804,7 @@ One could say that Duniter uses a PoW that needs very low energy consumption com <!-- source : https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/ --> -### Why do we need Proof of Work ? +### 4.1. Why do we need Proof of Work ? {#why-proof-of-work} Duniter nodes share a database as part of a p2p environment. The proof of work (PoW) allows machines to synchronize with each other. In Duniter's case, the blockchain is @@ -773,9 +817,9 @@ as we want to create Universal Dividends on a regular basis, and keep track of membership status, both in human time. -Proof-of-work provides a clever solution to both problems: -1. Any -machine can write into the blockchain (create a new block) but is only +Proof-of-work provides a clever solution to both problems: + +1. Any machine can write into the blockchain (create a new block) but is only authorised to do so if it has previously solved a mathematical equation that require a certain amount of work. The challenge has to be hard enough to prevent two machines to solve it at the same time, @@ -785,15 +829,15 @@ ensuring the unicity of a block's creator. takes a certain amount of time, which depends on the calculating power of the whole network. This provides a common ground for defining the needed time reference. A block time is set (ie: 1 block = 5 min) and -Duniter adapts the challenge difficulty to get an *average* duration +Duniter adapts the challenge difficulty to get an average duration corresponding to this block time. -### Only members can "mine" +### 4.2. Only members can "mine" {#only-members-can-mine} One of Duniter's major differences with other PoW-based cryptocurrencies is that only members are allowed to author blocks. Each block is signed with the member's private key, allowing the algorithm to determine a -*personalised difficulty*. +personalised difficulty. This personalised difficulty eliminates the rat-race for the most sophisticated and powerful mining equipment. Another benefit is the fact @@ -804,21 +848,21 @@ This lightweight PoW is much less energy-consuming than other PoW cryptocurrenci Members can mine with anything from a raspberry pi to a privacy-first internet cube. -### How does it work? +### 4.3. How does it work ? {#how-does-duniter-pow-work} -#### The hash (aka digest) +#### 4.3.1. The hash (aka digest) {#the-hash} Example of a valid hash: -::: {.highlight} - 00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653 -::: +``` +00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653 +``` As you can see this hash starts with five zeros which was very hard to -achieve and took a lot of *work* for someone's computer. Hence the term +achieve and took a lot of work for someone's computer. Hence the term "proof of work". -#### The common difficulty +#### 4.3.2. The common difficulty {#common-difficulty} A common difficulty is needed to settle on a yardstick for our time reference. Its role is to make sure the blockchain moves forward @@ -830,32 +874,32 @@ Duniter `v1.5.x`) and then acts as a spring, regulating blocktime creation by increasing itself if the creation interval drops under `avgGenTime` and vice-versa. -##### How is difficulty applied? +##### 4.3.2.1. How is difficulty applied ? {#how-is-difficulty-applied} The numeric value of difficulty is taken from an array of possible -hashes out of all possible hashes. In duniter v1.5.x the hash +hashes out of all possible hashes. In DUBPv13 the hash of a block is its sha256 hexadecimal hash. To understand the difficulty, we make a euclidiean division of the difficulty by 16. -Here's an example with a difficulty value of `70` : 70 // 16 = **4** with a -remainder of **6**. The valid hashes are the ones starting with four +Here's an example with a difficulty value of 70 : + +``` +70 // 16 = 4 with a remainder of 6. +``` + +The valid hashes are the ones starting with four zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). The valid hashes are then written as starting with : `0000[0-9]`. This is a bit different from Bitcoin, where the difficulty is only ruled by the number of zeroes. -> Fine, but the hash of a mined block will never change and there's no -> reason it should start with a given sequence of numbers. So how then -> can we make sure a block hash starts with exactly the sequence -> needed? +##### 4.3.2.2. The Nonce {#the-nonce} -Enter the nonce, short for "number once". When a member is forging a new +When a member is forging a new block, his computer freezes the block's content and changes the Nonce -until the hash reaches the required number of zeroes. - -##### The Nonce +until the hash reaches the required number of zeroes. The nonce allows us to mine a new block by finding a hash. The hash value allows us to determine the difficulty level of the @@ -875,7 +919,7 @@ built: - X is a number assigned to a specific peer. Let's assume that someone has several nodes each with the same private key, this would lead to possible collisions if this person were to mine the same block with - different nodes. Each block will therefore have its own unique X to + different nodes. Each ~~block~~ **node ?** will therefore have its own unique X to prevent this from happening. - Y is the number of cores of the processor. The Nonce starting with @@ -889,11 +933,11 @@ For the sake of accuracy, we use the term CPU in the wider sense, it can be understood as a bi-CPU for example. We take into consideration the number of cores for the resulting PoW. -### Personalised difficulty +### 4.4. Personalised difficulty {#personalised-difficulty} Earlier in this article, we explained that the personalised difficulty is the new and key concept that sets Duniter apart from other -*PoW-based* cryptocurrencies such as Bitcoin. +PoW-based cryptocurrencies. Here is how this personalised difficulty is calculated and assigned: @@ -904,11 +948,11 @@ Let `powMin` be the common difficulty, `exFact` a member's exclusion factor and `handicap` their handicap. This member's personalised difficulty `diff` is: -::: {.highlight} - diff = powMin*exFact + handicap -::: +``` +diff = powMin*exFact + handicap +``` -#### Understanding `exFact`, the exclusion factor +#### 4.4.1. Understanding `exFact`, the exclusion factor {#the-exclusion-factor} Members who have never produced blocks or haven't for quite some time are assigned an exclusion factor of `1`. Their personalised difficulty @@ -926,7 +970,7 @@ proportion is 1/3, meaning that if there are fifteen members currently forging, the member's exclusion factor will drop down to one after five blocks. -> What is intended by "the number of members forging"? +##### 4.4.1.1. What is intended by "the number of members forging" ? We mean the number of members trying to create the next block. In reality, there is no way to precisely know how @@ -935,12 +979,12 @@ to view the entire network. But we need this information, whithout which assigning a personalised difficulty is impossible. To achieve this, Duniter looks back at the blockchain and assumes that there is as much members forging as those who have found at least one block -in the last X blocks, minus the very last one. +in the last blocks in the current window, minus the very last one. -> Hox is X determined? +##### 4.4.1.2. Current window -We use the concept of **current window**. X's value is equal to the size of -this window. Let's see how it works: +We use the concept of **current window**. The current window is the number of blocks we look back at to determine how many members are forging. +Let's see how it works: * `issuersFrame` is the size of the current window in blocks. @@ -979,11 +1023,11 @@ and [BR\_G06](https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g06-headissuersframevar) of the DUP protocol. -> Let's go back to the personalised difficulty. +##### 4.4.1.3. exFact and the personalised difficulty {#exfact-and-the-personalised-difficulty} We explained that `exFact` spikes immediately after the member has found a block. It decreases then rapidly to `1` after a number of -blocks `X = 1/3 * issuersCount`. Let's see precisely +blocks equal to `1/3 * issuersCount`. Let's see precisely how we calculate `exFact`: * `nbPreviousIssuers` is the value of issuersCount at the @@ -994,27 +1038,36 @@ found by the rest of the network since block `N`. * `percentRot` is the number of *not excluded* peers we want. It is a monetary parameter, its value is 0.67 for Ğ1 currency. -::: {.highlight} - exFact = MAX [ 1 ; FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) ] -::: +``` +a = FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) +exFact = MAX [ 1 ; a ] +``` The FLOOR is a simple truncate function. For `exFact` to exclude the member, we need : -> (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2 +``` +(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2 +``` We can see that the member is not excluded if `nbBlocksSince` is greater than 1/3 of -the calculating members. Take as an example nbPreviousIssuers = 6 and nbBlocksSince = 3: +the calculating members. Take as an example `nbPreviousIssuers = 6` and `nbBlocksSince = 3`: -> (0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1 +``` +(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1 +``` However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded: -> (0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2 +``` +(0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2 +``` Moreover if the last block was authored by the said member, then: -> `nbBlocksSince=0` and -> `exFact` = `0.67 * nbPreviousIssuers` +``` +nbBlocksSince=0 and +exFact = 0.67 * nbPreviousIssuers +``` ExFact value increases according to the number of members calculating. Thus, if there is enough members calculating, even @@ -1023,7 +1076,7 @@ succeeded in our intent to deter attempts to seize the blockchain and its currency. -However, at any time t, the two-thirds of +However, at any time `t`, the two-thirds of calculating members all have an exclusion factor of `1`, even though they might not all have the same computational power at hand. If the personalised difficulty only took into account the exclusion factor, then @@ -1032,11 +1085,11 @@ third would be able to author new blocks and the other 2/3s would almost always be excluded. Lesser machines wouldn't stand a chance... -#### The handicap +#### 4.4.2. The handicap {#the-handicap} The handicap is the second parameter of the personalised difficulty. Its main role is to improve the rotation of forging peers. -A higher handicap is assined to members with higher calculating +A higher handicap is assigned to members with higher calculating power, so lesser machines can also compute blocks. As a consequence, there is no incentive on forging with powerful computers. Security can be achieved with less computing power than with pure PoW. @@ -1052,12 +1105,18 @@ single member within the current window. median number of blocks written by the calculating members during the same timeframe. -::: {.highlight} - handicap = FLOOR(LN(MAX(1;(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)) / LN(1.189)) -::: +``` +a = (nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame +handicap = FLOOR(LN(MAX( 1 ; a )) / LN(1.189)) +``` Let's unwrap the formula: -`(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)` is simply the + +``` +(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame) +``` + +is simply the ratio between the number of blocks authored by the peer and the median number of blocks. For example, if a peer has authored `9` blocks in the current window and the median is `5`, then the ratio @@ -1067,11 +1126,11 @@ the handicap has a value at least equal to `1`. The Napierian Logarithm of this ratio prevents the handicap from becoming excluding. We want the handicap to level the calculating field so that all peers stand a chance, not to exclude peers. -If we want the handicap to be applied as soon as the median is reached, -we'd have to divide it by `LN(1)`, the problem is that we've already set -a minimum value of `1` with the MAX function, so if we were to divide -the ratio by `LN(1)` all calculating peers would have a handicap \>= -`1`. In addition, is it really fair to handicap a member who's right on +If we wanted the handicap to be applied as soon as the median is reached, +we would divide it by `LN(1)`. The problem is that we have already set +a minimum value of `1` with the MAX function. If we were to divide +the ratio by `LN(1)` all calculating peers would have a handicap `\>= +1`. In addition, is it really fair to handicap a member who is right on the median? That's why we went for `1.189` rather than `1`. A member has to @@ -1081,43 +1140,39 @@ factor between two levels of the proof work (hexadecimal hash). To conclude, you have to remember that : -* the handicap is indexed on the logarithm of the ratio to the median, -* handicap is only applied on members whose ratio to the median is greater than the ratio between two +* The handicap is indexed on the logarithm of the ratio to the median, +* Handicap is only applied on members whose ratio to the median is greater than the ratio between two levels of the proof-of-work's difficulty. -## Conclusion + +## Conclusion {#conclusion} <!-- source : https://duniter.org/en/theoretical/ --> Duniter's Blockchain can be compared to Bitcoin's : a common document retracing the history of the currency. However, Duniter registers not only trades, but also the history of relationships in the community as a mean to identify a human to a digital account. This way, Duniter has information about the fondamental reference of RTM : living humans. A libre Currency can be issued thanks to the Universal Dividend. -More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers while maintaining a good security on the network. +More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers, maintaining a good security and helping decentralization of calculation. The ultimate goal of Duniter project is to allow people to participate in a libre economy, thanks to a libre currency. What is a libre economy ? The Relative Theory of Money defines it through four economic liberties : -* The freedom to choose your currency system: because money should not be imposed -* The freedom to access resources: because we all should have access to economic & monetary resources -* The freedom to estimate and produce value: because value is a purely relative to each individual -* The freedom to trade with the money: because we should not be limited by the avaible money supply +* The freedom to choose your currency system: because money should not be imposed. +* The freedom to access resources: because we all should have access to economic & monetary resources. +* The freedom to estimate and produce value: because value is a purely relative to each individual. +* The freedom to trade with the money: because we should not be limited by the avaible money supply. Those 4 economic freedoms should be understood together, not exclusively. Plus, "freedom" has to be understood as "non-nuisance". So here, freedom does not mean the right to take all of a resource (like water source in a desert) so no more is available to the others. Now you get it, this is the goal: free economy through free currency. -## Duniter project's sources : - -* Theoretical, by Cgeek: https://duniter.org/en/theoretical/ -* Lock conditions, by Inso: https://duniter.org/en/transactions-0-2-overview/ -* Individualised Proof of Work, by Elois: https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/ -* Deep dive into the Web of Trust, by Elois: https://duniter.org/en/deep-dive-into-the-web-of-trust/ -* Whitepaper sources: https://git.duniter.org/communication/duniter-whitepaper - -## Other sources : - -* Relative Theory of Money, S.Laborde, 2010: http://en.trm.creationmonetaire.info/ -* Bitcoin Whitepaper, S.Nakamoto, 2008: https://bitcoin.org/bitcoin.pdf -* Circles Whitepaper, A.Milenius, 2018: https://github.com/CirclesUBI/docs/blob/master/Circles.md -* The Sibyl Attack, J.R.Douceur: https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf - -<!-- travaux en theorie des graphes pourla TdC --> +## Sources : {#sources} + +* Relative Theory of Money, S.Laborde, 2010: [en.trm.creationmonetaire.info/](http://en.trm.creationmonetaire.info/) +* Bitcoin Whitepaper, S.Nakamoto, 2008: [bitcoin.org/bitcoin.pdf](https://bitcoin.org/bitcoin.pdf) +* The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : [lightning.network/lightning-network-paper.pdf](http://lightning.network/lightning-network-paper.pdf) +* The GNU Privacy Handbook, M.Ashley, 1999 : [www.gnupg.org/gph/en/manual.html#AEN335](https://www.gnupg.org/gph/en/manual.html#AEN335) +* High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. [cr.yp.to/papers.html#ed25519](https://cr.yp.to/papers.html#ed25519). +* PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : [archive.org/details/PPCoinPaper](https://archive.org/details/PPCoinPaper) +* Duniter Blockchain Protocol, v13, draft by Elois : [git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md](https://git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md) +* The Sibyl Attack, J.R.Douceur: [www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf](https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf) +* Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992 diff --git a/build/whitepaper_en.mobi b/build/whitepaper_en.mobi new file mode 100644 index 0000000000000000000000000000000000000000..9c136aa1c73dd60d6341483c1e50adf9bbe47eb5 GIT binary patch literal 58760 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 Cn7z#a literal 0 HcmV?d00001 diff --git a/build/whitepaper_fr.epub b/build/whitepaper_fr.epub new file mode 100644 index 0000000000000000000000000000000000000000..757507f6e7510c050ec501d34e11d6be49e18404 GIT binary patch literal 54578 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 UD;r3)AcG)75(@*vt_vU@07v#0>;M1& literal 0 HcmV?d00001 diff --git a/build/whitepaper_fr.fb2 b/build/whitepaper_fr.fb2 new file mode 100644 index 0000000..5b804e8 --- /dev/null +++ b/build/whitepaper_fr.fb2 @@ -0,0 +1,742 @@ +<?xml version="1.0" encoding="UTF-8"?> +<FictionBook xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" xmlns:xlink="http://www.w3.org/1999/xlink"> + <description> + <title-info> + <genre>antique</genre> + <author><first-name></first-name><last-name>Inconnu(e)</last-name></author> + <book-title>whitepaper fr</book-title> + + <lang>fr</lang> + + + + </title-info> + <document-info> + <author><first-name></first-name><last-name>Inconnu(e)</last-name></author> + <program-used>calibre 3.46.0</program-used> + <date>5.5.2020</date> + <id>e13c9ea4-7536-44c5-8117-25f915c2e2da</id> + <version>1.0</version> + </document-info> + <publish-info> + + + + </publish-info> + </description> +<body> +<section> +<empty-line /><p>Duniter: A libre currency blockchain generator.</p> + +<p>Abstract</p> + +<p>Many currency principles involve non-equal rights to monetary creation between humans. We propose a monetary creation based on the Relative Theory of Money, which guarantee equal monetary creation for each willing human. This type of currency can be centralised, however, this could lead to censorship and arbitrary choices of the central institution. Thus, strongly inspired by Bitcoin example, we want the currency to be as decentralised as possible, in the transaction network as in the human identification process. We use a Web of Trust between living humans for identification. This web of trust allows us to impose personalised difficulty for transaction validation, keeping the calculation accessible to low-end hardware and allowing all competent members to secure the currency.</p> + +<p>Introduction</p> + +<p>Duniter is a software to create and manage “libre currencies”. Libre currency is a concept defined by S.Laborde in the Relative Theory of Money (RTM) that was published in 2010. This theory demonstrates the possibility of an invariant monetary unit : the Universal Dividend. Doing so, the RTM answers the question :</p> + +<p>How should a currency be created to match the principle of equality between all humans, now and between generations ?</p> + +<p>The results of this demonstration implies a monetary creation :</p> + +<p>on a regular basis</p> + +<p>for each human being</p> + +<p>which amount has to be reassessed on fixed intervals according to a fixed formula.</p> + +<p>Thus, Duniter project will associate a human to a digital identity. It will use a Web of Trust with specific rules. As the number of members may evolve, the Universal Dividend has to be created according to the formula :</p> + +<p>$$ UD(t+1) = UD(t) + c²*( {M(t) \over N(t) }) $$</p> + +<p>Duniter is based on a decentralized Blockchain. This technical choice allows irreversibility of transaction and uncensorability of trades and identities. While inspired by Bitcoin, Duniter uses a Web of Trust and the Proof of Work to secure the computation network, thus making obsolete the power race model used in Bitcoin.</p> + +<p>The first currency created through Duniter is Ğ1, pronounced “June”. It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software.</p> + +<p>1. State of the art : Bitcoin case</p> + +<p>Duniter uses the crypto-currency concept introduced by Bitcoin<sup>1</sup>, which is to use cryptographic tools such as signatures to create trustless digital currencies. Duniter fits this definition, but it has two completely different principles than Bitcoin : the Web of Trust and the Universal Dividend . These differences are on both monetary and technical aspects.</p> + +<p>1.1. Monetary creation of Bitcoin : a space-time asymmetry</p> + +<p>Space-time asymmetry refers to the relative access of individuals to newly created money<sup>2</sup>. Concretely, most existing currencies (c. 2020) are both spatially and temporally asymmetrical for their users. Let's take Bitcoin as an example to understand why.</p> + +<p>1.1.1. Spatial asymmetry</p> + +<p>When new Bitcoins are created, only some Bitcoin users (the miners) are given new Bitcoins, while everyone else get nothing. We believe this is the first injustice. However, some might say:</p> + +<p>"Miners used their electricity and time to get it!"</p> + +<p>... we would answer that this work should not have been rewarded by newly created Bitcoins. New units should be distributed to the whole community. Miners should be rewared another way, but not by money issuance. Of course, Bitcoin cannot create money through Basic Income since Bitcoin users are not strongly identified, and one might benefit from money creation multiple times if they owned several wallets. Duniter gets rid of this problem by identifying its users and creating the same amount of Basic Income to everyone.</p> + +<p>1.1.2. Temporal-asymmetry</p> + +<p>Bitcoin has an absolute limit of 21 million BTC (its unit of currency), which means ever fewer bitcoins will be created over time until no new BTC are being generated. So, once the first adopters have mined every bitcoin, how will future joiners get Bitcoins? Just like most of us do for Euros or Dollars: to get money, they will have to work for the ones who already own it.</p> + +<p>We believe this is the second injustice. Every member of a monetary community should be equal concerning monetary creation, and get the same relative amount of money over time, even if they are a late adopter. Duniter aims to fix this by making the Universal Dividend (a.k.a. UD) grow by the time according to precise rules, thus making members equal toward money issuance on a half-lifespan.</p> + +<p>Most currencies present one of these two asymmetries, including metal currencies and mutual credit, as exposed in the RTM.</p> + +<p>1.1.3. A solution</p> + +<p>Bitcoin has taught us that it is possible to create a currency system allowing one to both create digital money and to exchange it without a central authority. What we need to change is the way money is issued so we finally have a symmetrical system. We need Bitcoin + Universal Dividend. But Universal Dividend implies that the community consists of only identified people. This is where the Web of Trust (WoT) comes into place.</p> + +<p>This concept, introduced by cryptography with the OpenPGP format<sup>3</sup>, allows us to identify people in a decentralized manner. It works as follows: each person creates a personal identity that is linked to its cyptographic certificate. The identity must be confirmed by others members who use their own cryptographic key. It is that simple: people choose who is part of the community and who is not, not a central authority.</p> + +<p>However, Duniter will not use OpenPGP for its cryptographic features: Elliptic Curves<sup>4</sup> will be used instead for the conciseness of its generated keys and its pratical advantages. Duniter has its own Web of Trust principles, that will be exposed later.</p> + +<p>1.2. Proof-of-Work mining : a power race</p> + +<p>In Bitcoin Model, the calculation and incentive principles cause a power race : new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. This leads to a power race an places the control over the currency in the hands of the richest hardware owners. We want to make Duniter blockchain validation much less energy and hardware consuming while keeping a strong level of security. This will be further explained later. A consequence of this choice is the participation of low-end hardware in the Duniter network, leading to a better decentralization of blockchain validation.</p> + +<p>1.2.1 What about Proof of Stake ?</p> + +<p>Proof of stake consensus algorythm was first introduced in 2012<sup>5</sup>. The basic principle is to allow the richest wallets to issue blocks, putting their coin balance as a “stake” they would lose in case of cheat.</p> + +<p>At the time of conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. We did not chose this consensus principle. Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead to placing power over the currency in the richests hands : this is contrary to the symmetical principles of a libre currency.</p> + +<p>2. Duniters Blockchain</p> + +<p>Duniters Blockchain follows the basic principles of Bitcoins. This is essential for synchronization between peers, as to prevent double-spend attacks. However, Duniters Blockchain will store different informations than Bitcoins.</p> + +<p>The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no generation transaction exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either:</p> + +<p>a former transaction (as in Bitcoin)</p> + +<p>a Universal Dividend (specific to Duniter).</p> + +<p>Duniters Web of Trust is also written in the Blockchain. The identity of each member gets registered much like transactions are, with a strong link to the time reference. Thus, the Blockchain is a representation of a space-time frame of reference, where “space” are members of the WoT and “time” the basic blockchain units : the blocks. On each point of time, one can determine which account is legitimate to create the UD, only with a blockchain analysis.</p> + +<p>2.1. Spam countermeasures</p> + +<p>An issue of most cryptocurrency projects is to prevent the common ledger from growing too much. This would require nodes to have a lot of storage and computing power to be usable. In particular, we don’t want an attacker to be able to make the Blockchain grow too fast. Most projects implement transaction fees as a way to prevent this, making the attacker lose money. We don’t want to introduce this mean since a currency with automatic fees on transactions is no more neutral. Several countermeasuers against such spam attacks are implemented.</p> + +<p>2.1.1. Minimum output amount</p> + +<p>Fixing a minimal output amount reduces the power of an attack. Duniter deals with cents of Ğ1 or 1/1000 of the first UD. An attacker could create thousand accounts with only 1 UD. To prevent this, a valid transaction must have output amounts of minimum 1Ğ1. This reduces the power an attack by 100.</p> + +<p>2.1.2. Limited block size and chainability</p> + +<p>The block size is always limited. While the protocol allows this limit to evolve to address scaling issues, an attacker cannot register as many transaction as they wish.</p> + +<p>With the same goal to prevent too many transactions to get registered, while transactions can be “chained” (refer to another transaction in the same block), the chainability of transactions is limited to 5.</p> + +<p>2.2. Scaling</p> + +<p>Most of the time, the scaling issue rises for distributed systems that should work on a very large scale. This is not the case of Duniter, for multiple reasons :</p> + +<p>Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don’t want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT should limit its size to around 16 million members.</p> + +<p>Duniter’s aim is to be used to create multiple libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community.</p> + +<p>However, Duniter has assets that will help if the number of users and transactions grow.</p> + +<p>2.2.1 Dynamic block size</p> + +<p>While Bitcoin has a fixed block size, Duniters blocks size can evolve. On low use of the blockchain, the maximal block size is 500 bytes. On high use of the blockchain, the maximal block size would be 110% of the average size of the current window blocks(see “personalised difficulty” part for more information). This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it. The block size (in bytes) is limited as so :</p> + +<p>block_size < max(500 ; CEIL(1.10 * (average block size))</p> + +<p>2.2.2. Lightning Networks</p> + +<p>The Lightning Networks<sup>6</sup> allow almost instant and off-chain transactions. They were first implemented on Lightcoin, and are now on Bitcoin. One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. While not available yet, this payment channel might get implemented when needed.</p> + +<p>2.2.3. Unit base</p> + +<p>As the Universal Dividend grows exponentially, with time Duniter nodes would have had to deal with always largest amounts, eventually reaching the BIGINT limit. To avoid this, the amounts are expressed with a unit base in base 10. We want the UD amount to always fit in 4 digits. To manage it, the unitbase is updated each time the UD value reaches 100.00 : it goes from 99.99*10^(unitbase) to 10.00*10^(unitbase+1). All the unit amounts are thus divided by 10. While this might seem strange, this process has already hapened in state currencies. Moreover, the amounts expressed in UD will not change.</p> + +<p>With a monetary growth of 10% each year and a stable population, such a change of unit base would happen each 25 years.</p> + +<p>3. Duniter Web of Trust</p> + +<p>3.1. Basic Principles</p> + +<p>In order to identify “members” accounts - which create monetary units - and other accounts, Duniter uses a Web of Trust. This can be summarized into few principles:</p> + +<p>Each account becomes a member if it received a minimal number of certifications - 5 for Ğ1 currency.</p> + +<p>Only members accounts can send certifications. Certifications have a limited lifespan.</p> + +<p>A certification indicates that the sender accepts the receiver as a legitimate identity.</p> + +<p>The aim of the WoT is to identify a blockchain account to a living human. According to Lauterbach et.al<sup>7</sup>, the strengh of a relationship should be considered when building a vouch system. For this reason, the Ğ1 Web of Trust rules are expressed in a licence stating what WoT certifications are. A certification represents a strong human relationship : one may certify a close relative, not an acquaintance. Each member has to accept this licence before being included in the WoT. Thus, if a member is part of an attack on the currency, they can be found by mutual relatives. Additional security rules occur to prevent cheat and attacks on a large scale.</p> + +<p>Note that non-members accounts can use the currency, but cannot create money. Non-members accounts can be used by individuals as secondary wallets, or by institutions.</p> + +<p>We were inspired by the OpenPGP Trust system<sup>8</sup>. However, the OpenPGP trust principles aim at defining trust from a particular point of view while Duniter needs to identify humans for the whole community. To achieve this goal, while OpenPGP allows each user to tweak its trust parameters individually, Duniter sets rules in the “genesis” block for the whole community.</p> + +<p>3.2. Why do we need a Web of Trust ?</p> + +<p>There are two reasons we need it :</p> + +<p>To make sure that only one Universal Dividend is produced per member at each specified creation interval. In the Ğ1’s case this interval is set as daily 86 400 seconds, it is the <emphasis>monetary parameter</emphasis> known as dt.</p> + +<p>To identify the nodes hashing the blocks and assign each a personalised difficulty. This custom difficulty proof of work is there to avoid the blockchain’s validation mechanism becoming too centralised as is the case with many 'non-libre’ cryptocurrencies.</p><empty-line /><p>Monetary parameter : Each currency that use Duniter has its own blockchain whose behaviour is dictated by a set of ‘parameters’ defined in block zero - the so-called genesis block - that can be tweaked to achieve the desired results. At the time of writing the Whitepaper, the Duniter Blockchain Protocol (DUBP) has a total of 21 parameters of which 10 are for the WoT alone. We’ll focus on these 10.</p> + +<p>Suffice to say that in the Ğ1’s case, the DU is created every 24 hours - 86 400 seconds. This interval is set through the time derivative dt parameter and can have a different value in other implementations of the protocol.</p> + +<p>We want to make sure that each member can only have one account. As we all know, achieving zero-risk isn’t possible<sup>9</sup>. Our goal is therefore not to create a WoT within which fraud would be absolutely impossible, but instead to discourage it. Here is a rewording of our goal in 4 smaller ones :</p> + +<p>Make the certification process lengthy enough that all members exercise due diligence and are wary of risks.</p> + +<p>Make fraudulent acts as hard as we can to the extent that they become pointless.</p> + +<p>Ensure that any Sybil attacks have a negligible impact on the currency by ensuring that illegitimate double Universal Dividends have no significant bearing on the legitimate monetary mass</p> + +<p>Slow the growth of ‘Sybil regions’ to give enough time for the community to react and isolate the threat.</p><empty-line /><p>Sybil attack : A Sybil attack is an attack perpetrated on a reputation system through the creation of fake identities. A Web of Trust is a specific instance of a Reputation System.</p> + +<p>There are plenty of Sybil attack scenarios we can think of and just as many reasons why their perpetrators would want to carry them out. Our objective is that the configuration of the WoT protects both users and its IT backbone infrastructure against these attacks.</p> + +<p>This means that micro-attacks performed by small groups of individuals looking for personal enrichment are of no interest to us. The web’s role isn’t to deter these attacks, this being instead the role of the community. Just like the town you live in is responsible for providing your tap water and electricity but isn’t responsible for any burglaries, etc. Much in the same way, Duniter’s WoT guarantees us all a functional currency, but do not detect small fraud.</p> + +<p>3.3. The importance of having our own certification system</p> + +<p>Centralized identification systems can achieve the goal we want. State Identification is an example. However, this has many drawbacks :</p> + +<p>The authority may have arbitrary criteria for identification, for example preventing people without an official state-provided identity or homeless people to be included in the WoT.</p> + +<p>Payment might be required to get identified, thus making the monetary creation not “free”.</p> + +<p>The authority is a point of failure for any attacker.</p> + +<p>It is of the utmost importance that we remain free from any state or corporation. The WoT is an answer to this criterium. To this day we depend only on the Internet and yet, were it to fail, there are already alternatives being tested around the world for a decentralised communication network.</p> + +<p>3.4. A few foundational concepts on graph theory : a bit of vocabulary</p><empty-line /><p>Graph: set of points -called ‘vertices’- joined by edges -called paths/walks-.</p> + +<p>Simple graph: a graph with no loops and with no multiple edges. That is, each edge connects two distinct endpoints and no two edges have the same endpoints. A simple edge is an edge that is not part of a multiple adjacency -of edges-. In many cases, graphs are assumed to be simple unless specified otherwise.</p> + +<p>Directed graph: a graph in which the edges have a distinguished direction, from one vertex to another. A directed edge can also be called a path or walk. Arrow A –> B is therefore different from arrow B –> A.</p> + +<p>Endpoints: the edge with vertex A –> B has A and B as endpoints, respectively as start and end of the path/walk.</p> + +<p>Isolated vertex: a vertex whose degree is zero, that is, a vertex with no incident edges.</p> + +<p>Degree of a vertex: number of its incident edges -in and out-.</p> + +<p>Out-degree of vertex A: number of outbound edges / tail ends from A.</p> + +<p>In-degree of vertex A: number of incoming edges / head ends to A.</p><empty-line /><p><emphasis>degrees of a vertex diagram</emphasis></p><empty-line /><p>Path: -aka “walk”- path to follow to get from vertex A to vertex B.</p> + +<p>3.5. Definition of the Duniter Web of Trust</p> + +<p>The Duniter WoTs -one per currency- are simple directed graphs without isolated vertices. The vertices are the members and the edges are the certifications given and received.</p> + +<p><emphasis>Directed</emphasis> means that the responsibility of issuing a certification is unique and personal to the certifier. The trust they place in the receiver cannot be imposed in the other direction although in most circumstances both parties equally trust each other.</p> + +<p>In addition, all vertices are either currently active members or past-members. Past-member vertices are in a specific ‘deactivated state’ and can no longer issue or receive certifications although the ones already issued or received to/from other members are still considered ‘pending’ to avoid a collapse of the WoT. If these old members don’t come back into the WoT, their pending certifications will eventually expire and they will switch from ‘deactivated’ to ‘isolated’ vertices.</p> + +<p>To wrap up with old members, after a certain period of time - set in the currency’s parameters - their deactivated vertex is removed from the web and the associated identity is ‘revoked’. The person who owned the account can no longer use this identity but is free to join the web with another one.</p> + +<p>Identity : An identity is a set of three pieces of information: a public key, a name and a blockstamp. A blockstamp points to a specific block in the chain. Its main use is to freeze the point in time at which an identity was created and to link this identity to a specific chain and a currency - each currency having its own blockchain.</p> + +<p>An identity can be in any one of 5 different status: pending, member, old member, revoked or excluded.</p> + +<p>Let’s take a simple example:</p> + +<p> A -> B -> C + | + \--> D</p> + +<p>If, for whatever reason, A were to lose its member status, the web would crumble and all other members would be excluded as a consequence. To avoid this, the certification from A –> B will remain valid until its expiry date, leaving enough time for B to receive certifications from C or D.</p> + +<p>Because our WoT doesn’t have any isolated vertices, each new identity created needs to be pulled into the web with all of the certifications it has received, all in the same block. This calls for a temporary ‘buffer’ storage space for pending identities and the certifications they have received. This storage space is called ‘the pool’ of Duniter nodes, which we could also have called the ‘sandbox’ as that’s the name used in Duniter’s code. Duniter nodes inclued other ‘pools’ for other documents and metadata not mentioned here.</p> + +<p>3.6. Exploring the rules behind a Duniter Web of Trust</p> + +<p>The Duniter WoTs - one per currency - works with a set of eight fundamental rules enforced through eleven different parameters. Ten of these parameters are set within the genesis block, the eleventh one - msPeriod- having being hard-coded in the Ğ1’s code subsequently.</p> + +<p>3.6.1. Distance rule and referent members (</p> + +<p>stepMax</p> + +<p> and</p> + +<p>xPercent</p> + +<p>)</p> + +<p>These two parameters are closely linked and together define the ‘distance rule’. The ‘distance rule’ can only be described after defining what a ‘referent member’ is:</p> + +<p>Referent member: member A is said to be ‘referent’ if and only if the total of their degrees are greater than or equal to CEIL-N^-1/stepMax where N is the total number of members. As the size of the web will grow this number will grow too, meaning it will take more certification issuances to become a referent member. The number of certifications needed to become a member shouldn’t change.</p> + +<p>Let’s now define the distance rule:</p> + +<p>Distance rule: member A is said to observe this rule if and only if for a subset xPercent % of referent members R there exists a path of length less than or equal to stepMax between R and A.</p> + +<p>Referent members only exist so that the distance rule can take effect, they have no special privileges over non-referent members. In a perfect web, that is one in which each member has certified all members they legitimately can, all members would be referent members. However, because the web progressively grows in size and because members die and are replaced by new ones, there are always members at any given time t who haven’t yet certified all members they legitimately could. These members would hinder the evolution of the web if they were taken into account in the calculation of the distance rule and the web would effectively stop growing.</p> + +<p>Because verifying the application of the distance rule is calculation-greedy, it is only performed when a new identity gets confirmed into the web or an existing member gets renewed. There is an exception to this rule: the distance rule is not observed in the genesis block -when the web is first implemented.</p> + +<p>3.6.2. Rule of the minimum number of certifications needed (</p> + +<p>sigQty</p> + +<p>)</p> + +<p>This is the simplest rule, it essentially says that each member must at any given time -meaning in any single block- have received at least sigQty active certifications. If, for whatever reason, member A were to have less than sigQty active certifications in a given block, they would cease to be a member and be required to publish a request for identity renewal.</p> + +<p>3.6.3. The membership renewal rule (</p> + +<p>msValidity</p> + +<p>,</p> + +<p>msPeriod</p> + +<p> and</p> + +<p>msWindow</p> + +<p>)</p> + +<p>Bear in mind that a membership doesn’t last a lifetime but instead has a lifespan set to msValidity seconds.</p> + +<p>Every single member -or old member who hasn’t revoked his identity or been excluded- can request a membership renewal so long as the last request was made more than msPeriod seconds ago. If a member has never requested a renewal, the date of last renewal is equal to the timestamp at which his membership was first created. A new request will be stored in the ‘pool’ for a maximum of msWindow seconds before it’s included in the blockchain. Once again, this can only happen once/if the member meets both the siqQty rule and the distance rule -if these criterion are already matched it’s just a case of waiting for a new block to be mined-.</p> + +<p>If a member hasn’t requested a renewal for longer than msValidity seconds, they automatically cease to be a member. From this moment on, the ex-member has another msValidity window to renew their membership. When this period of 2 × msValidity runs out, the membership will expire and this identity will never be available for use again in the web. If the person so desires, they will have to publish new identity and membership documents and find enough certifiers, as any newcomer.</p> + +<p>3.6.4. Rule of certification lifespan (</p> + +<p>sigValidity</p> + +<p>)</p> + +<p>All certifications included in the blockchain expire sigValidity seconds after they were issued.</p> + +<p>/!\ The issuance and the inclusion of a certification in the blockchain occur at different times. When member A issues a certification at time t1, it gets stored in the pool starting at t1 and only finds its way into the blockchain at t2 when all of the web’s rules are observed. Several weeks can thus go by between t1 and t2!!!</p> + +<p>3.6.5. Rule of limited supply of active certifications (</p> + +<p>sigStock</p> + +<p>)</p> + +<p>By ‘active certifications’ we refer to certifications included in the blockchain and that haven’t yet expired.</p> + +<p>The total of active certifications issued by any member at any single time must be less than or equal to sigStock. When this threshold is reached the member will have to wait for one of his active certifications to expire before he/she can issue a new one.</p> + +<p>3.6.6. Rule of the time period between two certification issuances. (</p> + +<p>sigPeriod</p> + +<p>)</p> + +<p>As soon as a certification issued by member A gets included in the blockchain, they will be unable to issue a new one before another sigPeriod seconds.</p> + +<p>3.6.7. Expiry of a certification issuance (</p> + +<p>sigWindow</p> + +<p>)</p> + +<p>When a certification is issued by member A, it will be stored in the ‘pool’ for a maximum of sigWindow seconds. If the certification hasn’t been included in the blockchain by then, it will be cancelled and the member’s sigStock will be repleted by one.</p> + +<p>3.6.8. Lifespan of a ‘pending’ identity (</p> + +<p>idtyWindow</p> + +<p>)</p> + +<p>When a new identity is created, it is stored in the ‘pool’ for a maximum of idtyWindow seconds. If the person hasn’t achieved member status by then, the certification will simply be cancelled.</p> + +<p>3.7. Details on some of the WoT’s peculiarities at the genesis block</p> + +<p>The aforementioned rules can only be enforced with an existing web. They cannot be observed when first creating the web, that is when defining the genesis block.</p> + +<p>Only rules 2 and 5 can be observed at the genesis block.</p> + +<p>The genesis block has to be manually created by the founding members. In practice this means that there must be a choice on which identities to include on the premise that all of them observe rules 2 and 5. In addition, the genesis block must be signed with the private key of one of these identities.</p> + +<p>As soon as the genesis block has been created, the other identities can start mining the blockchain and the member who created block #0 effectively looses the decision power he had at creation.</p> + +<p>3.8. Why these rules and application cases in the Ğ1</p> + +<p>3.8.1. Distance and maximum size</p> + +<p>The distance rule is there to curb the maximum size of a Sybil region as well as that of the monetary community as a whole. The xpercent parameter prevents the creation of a ‘faction’ that could take hold of the blockchain.</p><empty-line /><p><emphasis>Sybil region</emphasis></p> + +<p>The Sybil regions are isolated from the rest of the graph in the sense that they can only receive certifications from other ill-intentioned Sybil members. As a consequence, the shortest edge/path between a legitimate member and a Sybil one has to have the attack’s author as an endpoint. The maximum depth the Sybil region can attain is therefore contingent on the distance between the attacking edge-s- and the xpercent% closest referent members, this distance is known as stepAttackers. The maximum size of a Sybil region created by sigQty members depends on the L parameter, defined as L = sigQty/sigStock:</p> + +<p>MaxSybilSize= (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L)</p> + +<p>The maximum size of the Web of Trust is given by the following formula:</p> + +<p>WoTmax = (sigStock)*L^(stepMax-1)</p> + +<p>However we know for a fact that members will never use all of their available certifications. According to Dunbar<sup>10</sup>, on average, one is able to maintain relationships to around 150 people. Being conservative, we will consider that on average, each person will certify 50 accounts. We can calculate the size of the average web of trust WoTavg :</p> + +<p>WoTavg= (50)*(sigQty/50)^(stepMax-1)</p> + +<p>Our goal with the Ğ1 is to create a community of about one million members to test the consequences of a libre monetary system. Let’s see how we can tweak the pair of sigQty and stepMax- to reach this size:</p><empty-line /><p><emphasis>Average WoT size graph as a function of sigQty and stepMax</emphasis></p> + +<p>The maximum size of a Sybil region grows linearly with sigQty but exponentially with stepMax. Logic has it that we need to keep stepMax as low as possible to ensure sufficient strength to the web. The above graph shows that the lowest value of stepMax for a web of a million members is of 5. This is an order of magnitude and is likely to be much higher in reality, we cannot measure it for sure.</p> + +<p>For sigQty we can choose a value of 4 for a web of 1.5 million members or 5 for half a million members. Bear in mind these are gross figures and could be significantly higher, we are talking anywhere between 1 and 10 million in reality. Calculating WOTavg gives us a pretty good idea of how the web would scale bearing in mind that it considers all members are referent members too -which isn’t the case as explained previously-. Hence the maximum size of the web is likely larger, a ballpark figure of half a million is enough for now especially knowing that the smaller sigQty is, the easier it is to launch a Sybil attack -it’s easier to find four accomplices than five-. For security reasons we have settled on five:</p> + +<p>stepMax = 5 +sigQty = 5 +sigStock \>= 50</p> + +<p>The maximum size of a Sybil region therefore is:</p> + +<p>(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5))</p> + +<p>with sigStock = 50 we have a Sybil region of:</p> + +<p>45*(1-10^(5-stepAttackers))/(-9)</p> + +<p>A good practice for protecting the web is to maximise stepAttackers. That’s why we decided that referent members in the genesis block had to be at least four steps away from each other.</p> + +<p>Another way to keep a Sybil attack at bay, were it slow enough for members to notice it, would be for referent members to ‘stretch’ the web intentionally to limit the growth of the region by ensuring that the attackers’ legitimate certifications received in the first place aren’t renewed. But what if bot accounts were created and certified each other super fast and following all rules, how would we counter that? By introducing a minimum length of time between two certifications!</p> + +<p>3.8.2. Time is our friend</p> + +<p>To help us deter a Sybil attack, we’ve decided to impose a minimum period of time between any two certifications issued from a single account. This parameter called sigPeriod affords us a greater chance to detect the formation of a ‘hostile’ faction.</p> + +<p>Here is a graph showing the evolution of a Sybil region with the variation of sigPeriod. The simulation considers that honest members and attackers both issue a certification each sigPeriod interval, in days:</p><empty-line /><p><emphasis>size of the WoT according to sigPeriod and stepAttackers</emphasis></p> + +<p>As we see, there is a strong link between the growth speed of the region and sigPeriod. As evidenced here, we need a sigPeriod high enough in order to ensure that the legitimate web can grow at least as fast as a Sybil region. In addition, the higher sigPeriod is, the more members will exercise their certification power gingerly, the action coming at a higher ‘cost’.</p> + +<p>There are numerous advantages to giving sigPeriod a high value and no technical barriers to it, hence our choice of five days.</p> + +<p>We could have also gone for one week for the sake of simplicity. However there is an underlying idea behind our choice which was quite simply the pace of today’s life. Certifying someone can be a lengthy process as one needs to make sure they are correctly applying the Ğ1 licence and people nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea to allow one to certify at the end of every working week -five days- instead of a whole calendar one.</p> + +<p>3.8.3. Trust me now, trust me forever ? (</p> + +<p>sigValidity</p> + +<p>,</p> + +<p>msValidity</p> + +<p>)</p> + +<p>There would be two main drawbacks to a lifetime membership in the Ğ1’s Web of Trust:</p> + +<p>First of all, some members will pass and those accounts should no longer produce the Universal Dividend.</p> + +<p>Secondly it is of the utmost importance that ‘rogue’ accounts can be excluded from the web at some point.</p> + +<p>To achieve this, certifications have a limited lifespan. Members need to seek renewal from their peers after sigValidity time. On the other hand, this time can’t be too short that members would spend more time seeking renewal than they would exchanging in the currency. Furthermore, a certification with too short a lifespan would foster careless certifying behaviours. The act of certifying must have a high-enough ‘perceived’ cost to make it feel like an important act. Lastly, we also wanted this lifespan to be easy to remember. Historically speaking, we first settled on the values of sigPeriod and sigStock, meant one could issue all of their certifications in 495 days, one year was therefore not long enough. We deemed three years to be too much and that’s how we agreed on two years in the end.</p> + +<p>Thinking that a deceased member could continue producing the UD for two long years without anyone benefitting from it was also something we needed to address. We chose a value of one year for msValidity. The act of renewing every year is done through one of the clients interacting with the blockchain, through a simple click on a button. This parameter is less important than others and is mostly there to ‘prune’ the web of past or inactive members who don’t renew their membership.</p> + +<p>3.8.4. Keeping the pools free of information glut (</p> + +<p>idtyWindow</p> + +<p>,</p> + +<p>sigWindow</p> + +<p>,</p> + +<p>msWindow</p> + +<p>)</p> + +<p>The pools need to be cleaned up on a regular basis to avoid them clogging up with information and to ensure that machines with less calculating power can still run a Duniter node.</p> + +<p>To achieve this, identities with pending membership approval and the corresponding certifications have to remain the shortest time possible in the pool while still having a chance of making it into the blockchain.</p> + +<p>For the Ğ1, our opinion was that two months would be enough for all potential certifiers to agree on a specific identity to certify. We also wanted a time period that would be easy enough to remember by all. We settled on two months, and gave this value to all three parameters idtyWindow, sigWindow and msWindow.</p> + +<p>3.8.5. Avoiding single members from ‘knowing too many people’ (</p> + +<p>sigStock</p> + +<p>)</p> + +<p>We considered that on average, each person will certify 50 people. However, we know for a fact that some members will use more than 50 certifications. The maximum social network of one individual is around 150 people<sup>11</sup>. Being conservative, we settled on a maximum certification number sigstock of 100. Since sigStock’s impact on the size of a Sybil region is fairly limited, we did not investigate further this parameter.</p> + +<p>3.8.6. Avoiding locking minorities (</p> + +<p>xpercent</p> + +<p>)</p> + +<p>It’s easy enough to become a referent member, one of the Sybil strategies could therefore be to create a region of referent members. Such a region would grow slower than otherwise but could confer a locking power to its members by using the distance rule. That’s why the distance rule cannot be calculated on 100% of the referent members. Hence the introduction of the xpercent parameter which defines the percentage of referent members needing to be less than five edges -steps- from each other.</p> + +<p>This percentage needs to be low enough to prevent the formation of a locking minority -referent Sybil members being too far from legitimate referent members-. On the other hand, it needs to be high enough so as to restrict the maximum size of the Sybil region through the distance rule. The xpercent parameter was one of the hardest to define, therefore we might decide to change its value during the Ğ1 experiment.</p> + +<p>We were inspired by the Pareto principle<sup>12</sup>: if at least 20% of members give good density to the web, 80% of the referent members will be five or less steps from any other member -referent or not-. The maximum value for xpercent is therefore 80%, anything above that and the distance rule could be too restrictive for legitimate use cases. With security our top concern, we chose the maximum value of 80%.</p> + +<p>3.8.7. Spam protection with (</p> + +<p>msPeriod</p> + +<p>)</p> + +<p>This parameter stands out a bit on its own, as it was added after the genesis block. It is there to protect the Duniter P2P infrastructure against ‘spam’ attacks. We had to think of a strategy against attacks such as high-frequency membership renewal requests -i.e: in every block, every five minutes- or worse still, hundreds of these requests per minute to flood the Duniter nodes. Without such limits, nodes are supposed to address all renewal requests, even in cases where they were last published five minutes ago! The msPeriod parameter was given the same value as idtyWindow, sigWindow and msWindow, i.e. two months.</p> + +<p>4. Proof of Work with personal difficulty</p> + +<p>As each P2P cryptocurrency, Duniter has a way to synchronize its peers. It uses a proof of Work (PoW) to write the Blockchain on a regular basis, much like BitCoin. However, Duniter has a unique asset : the WoT, where each member represents a unique living human.</p> + +<p>This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each “winning” member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. A view of the whole network is not needed.</p> + +<p>Another strong difference is that forging peers are not rewarded by the protocol. There is no economical incentive on forging lots of blocs, neither on having a lot of computing power.</p> + +<p>One could say that Duniter uses a PoW that needs very low energy consumption compared to BitCoin : an “ecological” PoW ?</p> + +<p>4.1. Why do we need Proof of Work ?</p> + +<p>Duniter nodes share a database as part of a p2p environment. The proof of work (PoW) allows machines to synchronize with each other. In Duniter’s case, the blockchain is our database, and acts as a ledger keeping a trace of all transactions, status of the WoT and more. How can we let several machines add data (ie: a transaction) at the same time? In addition, how do we settle on how much time has gone by since the blockchain was last updated? Agreement on time is of the utmost importance as we want to create Universal Dividends on a regular basis, and keep track of membership status, both in human time.</p> + +<p>Proof-of-work provides a clever solution to both problems:</p><empty-line /><p>Any machine can write into the blockchain (create a new block) but is only authorised to do so if it has previously solved a mathematical equation that require a certain amount of work. The challenge has to be hard enough to prevent two machines to solve it at the same time, ensuring the unicity of a block’s creator.</p> + +<p>Solving this challenge takes a certain amount of time, which depends on the calculating power of the whole network. This provides a common ground for defining the needed time reference. A block time is set (ie: 1 block = 5 min) and Duniter adapts the challenge difficulty to get an average duration corresponding to this block time.</p> + +<p>4.2. Only members can “mine”</p> + +<p>One of Duniter’s major differences with other PoW-based cryptocurrencies is that only members are allowed to author blocks. Each block is signed with the member’s private key, allowing the algorithm to determine a personalised difficulty.</p> + +<p>This personalised difficulty eliminates the rat-race for the most sophisticated and powerful mining equipment. Another benefit is the fact that no “supercomputer” can take control of the blockchain. Lastly, Duniter implements a rotation in forging members thanks to this personalized difficulty.</p> + +<p>This lightweight PoW is much less energy-consuming than other PoW cryptocurrencies. Members can mine with anything from a raspberry pi to a privacy-first internet cube.</p> + +<p>4.3. How does it work ?</p> + +<p>4.3.1. The hash (aka digest)</p> + +<p>Example of a valid hash:</p> + +<p>00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653</p> + +<p>As you can see this hash starts with five zeros which was very hard to achieve and took a lot of work for someone’s computer. Hence the term “proof of work”.</p> + +<p>4.3.2. The common difficulty</p> + +<p>A common difficulty is needed to settle on a yardstick for our time reference. Its role is to make sure the blockchain moves forward at a steady pace - one block every avgGenTime seconds, avgGenTime being one of the 20 parameters behind the Duniter protocol-.</p> + +<p>This difficulty’s initial value can be set to any arbitrary value (70 in Duniter v1.5.x) and then acts as a spring, regulating blocktime creation by increasing itself if the creation interval drops under avgGenTime and vice-versa.</p> + +<p>4.3.2.1. How is difficulty applied ?</p> + +<p>The numeric value of difficulty is taken from an array of possible hashes out of all possible hashes. In DUBPv13 the hash of a block is its sha256 hexadecimal hash.</p> + +<p>To understand the difficulty, we make a euclidiean division of the difficulty by 16.</p> + +<p>Here’s an example with a difficulty value of 70 :</p> + +<p>70 // 16 = 4 with a remainder of 6.</p> + +<p>The valid hashes are the ones starting with four zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). The valid hashes are then written as starting with : 0000[0-9]. This is a bit different from Bitcoin, where the difficulty is only ruled by the number of zeroes.</p> + +<p>4.3.2.2. The Nonce</p> + +<p>When a member is forging a new block, his computer freezes the block’s content and changes the Nonce until the hash reaches the required number of zeroes.</p> + +<p>The nonce allows us to mine a new block by finding a hash. The hash value allows us to determine the difficulty level of the proof-of-work performed. Examples of possible Nonce values:</p> + +<p>10100000112275</p> + +<p>10300000288743</p> + +<p>10400000008538</p> + +<p>10700000079653</p> + +<p>10300000070919</p> + +<p>In reality the Nonce value follows a pre-determined format akin to XYY00000000000. The Nonce’s value isn’t the number of attempts but rather a value within a set of possible ones. This is how the Nonce is built:</p><empty-line /><p>X is a number assigned to a specific peer. Let’s assume that someone has several nodes each with the same private key, this would lead to possible collisions if this person were to mine the same block with different nodes. Each <strikethrough>block</strikethrough> node ? will therefore have its own unique X to prevent this from happening.</p> + +<p>Y is the number of cores of the processor. The Nonce starting with 107[…] belongs to a seven cores processor, while 199[...] could be the proof generated by a 99 cores processor.</p> + +<p>The rest of the Nonce, the part that follows after the XYY, is the numerical space for this individual node and is unique to each of the CPU’s core. This space is comprised of eleven digits (00000000000). For the sake of accuracy, we use the term CPU in the wider sense, it can be understood as a bi-CPU for example. We take into consideration the number of cores for the resulting PoW.</p> + +<p>4.4. Personalised difficulty</p> + +<p>Earlier in this article, we explained that the personalised difficulty is the new and key concept that sets Duniter apart from other PoW-based cryptocurrencies.</p> + +<p>Here is how this personalised difficulty is calculated and assigned:</p> + +<p>It is determined by a combination of two different constraints with complimentary roles: the exclusion factor and the handicap.</p> + +<p>Let powMin be the common difficulty, exFact a member’s exclusion factor and handicap their handicap. This member’s personalised difficulty diff is:</p> + +<p>diff = powMin*exFact + handicap</p> + +<p>4.4.1. Understanding</p> + +<p>exFact</p> + +<p>, the exclusion factor</p> + +<p>Members who have never produced blocks or haven’t for quite some time are assigned an exclusion factor of 1. Their personalised difficulty is therefore simply the sum of powMin + handicap.</p> + +<p>Before reading on, let’s precise the role of this exclusion factor. When a member adds a block to the chain, his exFact jumps up from one to a very high value, to prevent them from forging other blocks immediately after and taking control of the blockchain.</p> + +<p>The exclusion factor will then rapidly return to one. This delay is expressed as a number of blocks. It is calculated as a proportion of the number of members forging. In the Ğ1’s case, this proportion is 1/3, meaning that if there are fifteen members currently forging, the member’s exclusion factor will drop down to one after five blocks.</p> + +<p>4.4.1.1. What is intended by “the number of members forging” ?</p> + +<p>We mean the number of members trying to create the next block. In reality, there is no way to precisely know how many members are calculating at any given time, because it is impossible to view the entire network. But we need this information, whithout which assigning a personalised difficulty is impossible. To achieve this, Duniter looks back at the blockchain and assumes that there is as much members forging as those who have found at least one block in the last blocks in the current window, minus the very last one.</p> + +<p>4.4.1.2. Current window</p> + +<p>We use the concept of current window. The current window is the number of blocks we look back at to determine how many members are forging. Let’s see how it works:</p><empty-line /><p>issuersFrame is the size of the current window in blocks.</p> + +<p>issuersCount the number of members who have calculated at least one block during the current window.</p> + +<p>Both issuersFrame and issuersCount are block fields. When first starting a blockchain, the very first block has an issuersFrame=1 and an issuersCount=0. The genesis block is excluded as there are no members in the current window!</p> + +<p>From the second block onwards (block #1) we track the variation of issuersCount. The member having mined block #0 enters the current window and in block #1 we will therefore mention issuersCount=1.</p> + +<p>issuersFrame then varies as follows:</p> + +<p>if issuersCount increases by N (with a maximum step of N = 1), then issuersFrame will increase by one unit over a period of 5N blocks.</p> + +<p>Conversely, if issuersCount decreases by Y (with a maximum step of Y = 2 = current window inching forward + loss of one calculating member), then issuersFrame will decrease by one unit during 5Y blocks.</p> + +<p>When such events overlap, issuersFrame evolves as so :</p><empty-line /><p><strong>bloc</strong></p> + +<p><strong>event</strong></p> + +<p><strong>issuersFrame</strong></p><empty-line /><p>T</p> + +<p>Babar writes a block and enters issuersCount</p> + +<p>160</p><empty-line /><p>T+1</p> + +<p>Celeste leaves issuersCount</p> + +<p>160 +1 = 161</p><empty-line /><p>T+2</p> + +<p>N/a</p> + +<p>161 +1 -1 = 161</p><empty-line /><p>T+3/4/5</p> + +<p>N/a</p> + +<p>161 +1 -1 = 161</p><empty-line /><p>T+6</p> + +<p>N/a</p> + +<p>161 -1 = 160</p><empty-line /><p>The calculation can be found under rules BR_G05 and BR_G06 of the DUP protocol.</p> + +<p>4.4.1.3. exFact and the personalised difficulty</p> + +<p>We explained that exFact spikes immediately after the member has found a block. It decreases then rapidly to 1 after a number of blocks equal to 1/3 * issuersCount. Let’s see precisely how we calculate exFact:</p><empty-line /><p>nbPreviousIssuers is the value of issuersCount at the last block N found by the member.</p> + +<p>nbBlocksSince is the number of blocks found by the rest of the network since block N.</p> + +<p>percentRot is the number of <emphasis>not excluded</emphasis> peers we want. It is a monetary parameter, its value is 0.67 for Ğ1 currency.</p> + +<p>a = FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) +exFact = MAX [ 1 ; a ]</p> + +<p>The FLOOR is a simple truncate function. For exFact to exclude the member, we need :</p> + +<p>(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2</p> + +<p>We can see that the member is not excluded if nbBlocksSince is greater than 1/3 of the calculating members. Take as an example nbPreviousIssuers = 6 and nbBlocksSince = 3:</p> + +<p>(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1</p> + +<p>However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded:</p> + +<p>(0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2</p> + +<p>Moreover if the last block was authored by the said member, then:</p> + +<p>nbBlocksSince=0 and +exFact = 0.67 * nbPreviousIssuers</p> + +<p>ExFact value increases according to the number of members calculating. Thus, if there is enough members calculating, even mining farms would be excluded. We have therefore succeeded in our intent to deter attempts to seize the blockchain and its currency.</p> + +<p>However, at any time t, the two-thirds of calculating members all have an exclusion factor of 1, even though they might not all have the same computational power at hand. If the personalised difficulty only took into account the exclusion factor, then only the members with the highest computational power from the remaining third would be able to author new blocks and the other 2/3s would almost always be excluded. Lesser machines wouldn’t stand a chance…</p> + +<p>4.4.2. The handicap</p> + +<p>The handicap is the second parameter of the personalised difficulty. Its main role is to improve the rotation of forging peers. A higher handicap is assigned to members with higher calculating power, so lesser machines can also compute blocks. As a consequence, there is no incentive on forging with powerful computers. Security can be achieved with less computing power than with pure PoW.</p> + +<p>The aim is to handicap the half that has authored most blocks (the most powerful half) to favour the other one. So, the handicap formula will use the median number of blocks authored by peers within the current window.</p><empty-line /><p>nbPersonalBlocksInFrame is the number of blocks authored by a single member within the current window.</p> + +<p>medianOfBlocksInFrame is the median number of blocks written by the calculating members during the same timeframe.</p> + +<p>a = (nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame +handicap = FLOOR(LN(MAX( 1 ; a )) / LN(1.189))</p> + +<p>Let’s unwrap the formula:</p> + +<p>(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)</p> + +<p>is simply the ratio between the number of blocks authored by the peer and the median number of blocks. For example, if a peer has authored 9 blocks in the current window and the median is 5, then the ratio will be (9+1)/5 = 2. The MAX function allows us to ensure that the handicap has a value at least equal to 1.</p> + +<p>The Napierian Logarithm of this ratio prevents the handicap from becoming excluding. We want the handicap to level the calculating field so that all peers stand a chance, not to exclude peers.</p> + +<p>If we wanted the handicap to be applied as soon as the median is reached, we would divide it by LN(1). The problem is that we have already set a minimum value of 1 with the MAX function. If we were to divide the ratio by LN(1) all calculating peers would have a handicap \>= 1. In addition, is it really fair to handicap a member who is right on the median?</p> + +<p>That’s why we went for 1.189 rather than 1. A member has to be at least 18.9% above the median to be assigned a handicap. 18.9% is actually 16^(1/16), the difficulty factor between two levels of the proof work (hexadecimal hash).</p> + +<p>To conclude, you have to remember that :</p> + +<p>The handicap is indexed on the logarithm of the ratio to the median,</p> + +<p>Handicap is only applied on members whose ratio to the median is greater than the ratio between two levels of the proof-of-work’s difficulty.</p> + +<p>Conclusion</p> + +<p>Duniter’s Blockchain can be compared to Bitcoin’s : a common document retracing the history of the currency. However, Duniter registers not only trades, but also the history of relationships in the community as a mean to identify a human to a digital account. This way, Duniter has information about the fondamental reference of RTM : living humans. A libre Currency can be issued thanks to the Universal Dividend.</p> + +<p>More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers, maintaining a good security and helping decentralization of calculation.</p> + +<p>The ultimate goal of Duniter project is to allow people to participate in a libre economy, thanks to a libre currency. What is a libre economy ? The Relative Theory of Money defines it through four economic liberties :</p> + +<p>The freedom to choose your currency system: because money should not be imposed.</p> + +<p>The freedom to access resources: because we all should have access to economic & monetary resources.</p> + +<p>The freedom to estimate and produce value: because value is a purely relative to each individual.</p> + +<p>The freedom to trade with the money: because we should not be limited by the avaible money supply.</p> + +<p>Those 4 economic freedoms should be understood together, not exclusively. Plus, “freedom” has to be understood as “non-nuisance”. So here, freedom does not mean the right to take all of a resource (like water source in a desert) so no more is available to the others. Now you get it, this is the goal: free economy through free currency.</p> + +<p>Sources :</p> + +<p>Relative Theory of Money, S.Laborde, 2010: en.trm.creationmonetaire.info/</p> + +<p>Bitcoin Whitepaper, S.Nakamoto, 2008: bitcoin.org/bitcoin.pdf</p> + +<p>The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : lightning.network/lightning-network-paper.pdf</p> + +<p>The GNU Privacy Handbook, M.Ashley, 1999 : www.gnupg.org/gph/en/manual.html#AEN335</p> + +<p>High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. cr.yp.to/papers.html#ed25519.</p> + +<p>PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : archive.org/details/PPCoinPaper</p> + +<p>Duniter Blockchain Protocol, v13, draft by Elois : git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md</p> + +<p>The Sibyl Attack, J.R.Douceur: www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</p> + +<p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992</p><empty-line /><empty-line /><empty-line /><p>Bitcoin Whitepaper, S.Nakamoto, 2008: bitcoin.org/bitcoin.pdf↩</p> + +<p>Relative Theory of Money, S.Laborde, 2010: en.trm.creationmonetaire.info/↩</p> + +<p>OpenPGP protocol defines standard formats for encrypted messages, signatures, private keys, and certificates for exchanging public keys. The GNU Privacy Handbook, M.Ashley, 1999 : www.gnupg.org/gph/en/manual.html#AEN335↩</p> + +<p>High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. cr.yp.to/papers.html#ed25519.↩</p> + +<p>PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : archive.org/details/PPCoinPaper↩</p> + +<p>The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : lightning.network/lightning-network-paper.pdf↩</p> + +<p>Surfing a Web of Trust, Reputation and Reciprocity on CouchSurfing.com, D.Lauterbach, H.Truong, T.Shah, L.Adamic: snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf↩</p> + +<p>Public key validation on GnuPG manual, M.Ashley, 1999 : www.gnupg.org/gph/en/manual.html#AEN335↩</p> + +<p>The Sibyl Attack, J.R.Douceur: www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf↩</p> + +<p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992↩</p> + +<p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992↩</p> + +<p>Pareto principle : en.wikipedia.org/wiki/Pareto_principle↩</p><empty-line /> +</section> + +</body> +</FictionBook> \ No newline at end of file diff --git a/build/whitepaper_fr.html b/build/whitepaper_fr.html index 7232bd3..aa82115 100644 --- a/build/whitepaper_fr.html +++ b/build/whitepaper_fr.html @@ -10,26 +10,61 @@ Duniter Whitepaper href='bulma.css' > <link rel='stylesheet' href='main.css' > -<script src='js/jquery.js' ></script > -<script src='js/toc.js' ></script > -<script type='javascript' > - if ($) { - $('#whitepaper').tableofcontents({ id: '#toc' }); - } +<script type='text/javascript' > + /** + * Generates a table of contents for your document based on the headings + * present. Anchors are injected into the document and the + * entries in the table of contents are linked to them. The table of + * contents will be generated inside of the first element with the id `toc`. + * @param {HTMLDOMDocument} documentRef Optional A reference to the document + * object. Defaults to `document`. + * @author Matthew Christopher Kastor-Inare III + * @version 20130726 + * @example + * // call this after the page has loaded + * htmlTableOfContents(); + */ + function htmlTableOfContents(documentRef) { + var documentRef = documentRef || document; + var toc = documentRef.getElementById('table_of_contents'); + var headings = [].slice.call(documentRef.body.querySelectorAll('h1, h2, h3, h4, h5, h6')); + headings.forEach(function (heading, index) { + var anchor = documentRef.createElement('a'); + anchor.setAttribute('name', 'toc' + index); + anchor.setAttribute('id', 'toc' + index); + + var link = documentRef.createElement('a'); + link.setAttribute('href', '#toc' + index); + link.textContent = heading.textContent; + + var div = documentRef.createElement('div'); + div.setAttribute('class', heading.tagName.toLowerCase()); + + div.appendChild(link); + toc.appendChild(div); + heading.parentNode.insertBefore(anchor, heading); + }); + } + + try { + module.exports = htmlTableOfContents; + } catch (e) { + // module.exports is not defined + console.error('e', e) + } </script > </head > -<body> +<body onload="htmlTableOfContents();"> <main> -<div id="toc"> - -</div> +<nav id='table_of_contents' ></nav > <article id="whitepaper" class="content"> -<h1 id="duniter-a-libre-currency-blockchain-generator">Duniter : A libre currency blockchain generator !</h1> -<h2 id="abstract-todo">Abstract (TODO)</h2> +<h1 id="duniter-a-libre-currency-blockchain-generator.">Duniter: A libre currency blockchain generator.</h1> +<h2 id="abstract">Abstract</h2> +<p>Many currency principles involve non-equal rights to monetary creation between humans. We propose a monetary creation based on the Relative Theory of Money, which guarantee equal monetary creation for each willing human. This type of currency can be centralised, however, this could lead to censorship and arbitrary choices of the central institution. Thus, strongly inspired by Bitcoin example, we want the currency to be as decentralised as possible, in the transaction network as in the human identification process. We use a Web of Trust between living humans for identification. This web of trust allows us to impose personalised difficulty for transaction validation, keeping the calculation accessible to low-end hardware and allowing all competent members to secure the currency.</p> <h2 id="introduction">Introduction</h2> <p>Duniter is a software to create and manage “libre currencies”. Libre currency is a concept defined by S.Laborde in the Relative Theory of Money (RTM) that was published in 2010. This theory demonstrates the possibility of an invariant monetary unit : the Universal Dividend. Doing so, the RTM answers the question :</p> <blockquote> -<p>How should a currency be created to match the principle of equality between all humans ?</p> +<p>How should a currency be created to match the principle of equality between all humans, now and between generations ?</p> </blockquote> <p>The results of this demonstration implies a monetary creation :</p> <ul> @@ -38,752 +73,266 @@ Duniter Whitepaper <li>which amount has to be reassessed on fixed intervals according to a fixed formula.</li> </ul> <p>Thus, Duniter project will associate a human to a digital identity. It will use a Web of Trust with specific rules. As the number of members may evolve, the Universal Dividend has to be created according to the formula :</p> -<blockquote> -<p>UD(t+1) = UD(t) + c² * ( M(t) / N(t) )</p> -</blockquote> +<pre><code>$$ UD(t+1) = UD(t) + c²*( {M(t) \over N(t) }) $$</code></pre> <p>Duniter is based on a decentralized Blockchain. This technical choice allows irreversibility of transaction and uncensorability of trades and identities. While inspired by Bitcoin, Duniter uses a Web of Trust and the Proof of Work to secure the computation network, thus making obsolete the power race model used in Bitcoin.</p> -<p>The first currency created through Duniter is Ğ1 (say “June”). It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software.</p> -<h2 id="state-of-the-art-bitcoin-case">State of the art : Bitcoin case</h2> +<p>The first currency created through Duniter is Ğ1, pronounced “June”. It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software.</p> +<h2 id="state-of-the-art-bitcoin-case">1. State of the art : Bitcoin case</h2> <!-- source : https://duniter.org/en/theoretical/ --> -<p>Duniter uses the crypto-currency concept introduced by Bitcoin, which is to use cryptographic tools such as <em>signatures</em> to create digital currencies. Duniter fits this definition, but it has completely different principles than Bitcoin : the Web of Trust and the Universal Dividend . These differences are on both monetary and technical aspects.</p> -<h3 id="monetary-creation-of-bitcoin-a-space-time-asymmetry">Monetary creation of Bitcoin : a space-time asymmetry</h3> -<p>Space-time asymmetry refers to the relative access of individuals to newly created money (Relative Theory of Money, S.Laborde, 2010). Concretely, all existing currencies (c. 2015) are both spatially and temporally asymmetrical for their users. Let's take Bitcoin as an example to understand why.</p> -<h4 id="spatial-asymmetry">Spatial asymmetry</h4> -<p>When new Bitcoins are created, <em>only some Bitcoin users</em> (the miners) are given new Bitcoins, while everyone else get nothing. <strong>We believe this is the <em>first</em> injustice.</strong> However, some might say:</p> -<blockquote> -<p>"Miners used their <em>electricity and time</em> to get it!"</p> -</blockquote> -<p>... we would answer that this work <em>shouldn't have been rewarded by newly created Bitcoins</em>. New Bitcoins should be distributed to the whole Bitcoin community. Miners should be rewared another way, but not by money issuance. Of course, Bitcoin can't create money through Basic Income since <em>Bitcoin users are not strongly identified</em>, and one might benefit from money creation multiple times if he owned several wallets. Duniter gets rid of this problem completely by identifying its users and giving <em>the same amount of Basic Income to everyone</em>.</p> -<h4 id="temporal-asymmetry">Temporal-asymmetry</h4> -<p>Bitcoin has an absolute limit of 21 million BTC (its unit of currency), which means ever fewer bitcoins will be created over time until no new BTC are being generated. So, once the first adopters have mined every bitcoin, how will future joiners get Bitcoins? Just like Euros or Dollars: to get money, they will have to work for the ones who already own it. <strong>We believe this is the <em>second</em> injustice.</strong> Every member of a monetary community should be equal concerning monetary creation, and get the same relative amount of money over time, <em>even if they are a late adopter</em>. Duniter aims to fix this by making the Universal Dividend (a.k.a. <em>UD</em>) <em>grow by the time</em> (S.Laborde, 2010) according to precise rules, thus making members equal toward money issuance on a half-lifespan.</p> -<h4 id="a-solution">A solution</h4> -<p>Bitcoin has taught us that <em>it is possible</em> to create a currency system allowing one to both create digital money and to exchange it without a central authority. What we need to change is <em>the way money is issued</em> so we finally have a symmetrical system. We need Bitcoin <em>+ Universal Dividend</em>. But Universal Dividend <em>implies</em> that the community consists of only identified people. This is where the Web of Trust (WoT) comes into place. This concept, introduced by cryptography with the <a href="https://www.wikiwand.com/en/Pretty_Good_Privacy">OpenPGP</a> format, allows us to identify people in a <em>decentralized</em> manner. It works as follows: each person creates <em>a personal identity</em> that is linked to its cyptographic certificate. The identity must be confirmed by others members who use their own cryptographic key. It is that simple: <strong>people choose who is part of the community and who is not, not a central authority.</strong></p> -<blockquote> -<p>Duniter however won't use OpenPGP for its cryptographic features: Elliptic Curves will be used instead for the conciseness of its generated keys and its pratical advantages. Duniter has its own Web of Trust principles, that shall be exposed later.</p> -</blockquote> -<h3 id="proof-of-work-mining-a-power-race-todo">Proof-of-Work mining : a power race (TODO)</h3> -<p>In Bitcoin Model, the calculation and incentive principles cause a power race : new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. The goal of Duniter is to make blockchain validation much less energy and hardware consuming while keeping a strong level of security. As a consequence, even low-power hardware can secure Duniter Blockchain, which leads to a better decentralization of forging operations.</p> -<h3 id="other-projects">Other projects ?</h3> -<h4 id="what-about-pos">What about PoS ?</h4> -<p>When conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead to placing power over the currency in the richests hands : this is contrary to the symmetical principles of Duniter.</p> -<p>Now that PoS is well-tested, one could try to use Duniter’s WoT to create a PoS-like algorithm with equal chances among members. But this is not our aim for now.</p> -<h4 id="what-about-directed-acyclic-graph">What about Directed Acyclic Graph ?</h4> -<p>The Circles project uses DAG in a basic income cryptocurrency. However, in this project, one peer cannot know the whole monetary mass and the exact number of other peers. The calculation of Universal Dividend <code>UD = c * M/N</code> seems impossible, since we know neither M nor N.</p> -<h2 id="duniters-blockchain">Duniters Blockchain</h2> +<p>Duniter uses the crypto-currency concept introduced by Bitcoin<a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a>, which is to use cryptographic tools such as signatures to create trustless digital currencies. Duniter fits this definition, but it has two completely different principles than Bitcoin : the Web of Trust and the Universal Dividend . These differences are on both monetary and technical aspects.</p> +<h3 id="monetary-creation-a-space-time-asymmetry">1.1. Monetary creation of Bitcoin : a space-time asymmetry</h3> +<p>Space-time asymmetry refers to the relative access of individuals to newly created money<a href="#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a>. Concretely, most existing currencies (c. 2020) are both spatially and temporally asymmetrical for their users. Let's take Bitcoin as an example to understand why.</p> +<h4 id="spatial-asymmetry">1.1.1. Spatial asymmetry</h4> +<p>When new Bitcoins are created, only some Bitcoin users (the miners) are given new Bitcoins, while everyone else get nothing. We believe this is the first injustice. However, some might say:</p> +<blockquote> +<p>"Miners used their electricity and time to get it!"</p> +</blockquote> +<p>... we would answer that this work should not have been rewarded by newly created Bitcoins. New units should be distributed to the whole community. Miners should be rewared another way, but not by money issuance. Of course, Bitcoin cannot create money through Basic Income since Bitcoin users are not strongly identified, and one might benefit from money creation multiple times if they owned several wallets. Duniter gets rid of this problem by identifying its users and creating the same amount of Basic Income to everyone.</p> +<h4 id="temporal-asymmetry">1.1.2. Temporal-asymmetry</h4> +<p>Bitcoin has an absolute limit of 21 million BTC (its unit of currency), which means ever fewer bitcoins will be created over time until no new BTC are being generated. So, once the first adopters have mined every bitcoin, how will future joiners get Bitcoins? Just like most of us do for Euros or Dollars: to get money, they will have to work for the ones who already own it.</p> +<p>We believe this is the second injustice. Every member of a monetary community should be equal concerning monetary creation, and get the same relative amount of money over time, even if they are a late adopter. Duniter aims to fix this by making the Universal Dividend (a.k.a. UD) grow by the time according to precise rules, thus making members equal toward money issuance on a half-lifespan.</p> +<p>Most currencies present one of these two asymmetries, including metal currencies and mutual credit, as exposed in the RTM.</p> +<h4 id="a-solution">1.1.3. A solution</h4> +<p>Bitcoin has taught us that it is possible to create a currency system allowing one to both create digital money and to exchange it without a central authority. What we need to change is the way money is issued so we finally have a symmetrical system. We need <strong>Bitcoin + Universal Dividend</strong>. But Universal Dividend implies that the community consists of only identified people. This is where the Web of Trust (WoT) comes into place.</p> +<p>This concept, introduced by cryptography with the OpenPGP format<a href="#fn3" class="footnote-ref" id="fnref3"><sup>3</sup></a>, allows us to identify people in a decentralized manner. It works as follows: each person creates a personal identity that is linked to its cyptographic certificate. The identity must be confirmed by others members who use their own cryptographic key. It is that simple: people choose who is part of the community and who is not, not a central authority.</p> +<p>However, Duniter will not use OpenPGP for its cryptographic features: Elliptic Curves<a href="#fn4" class="footnote-ref" id="fnref4"><sup>4</sup></a> will be used instead for the conciseness of its generated keys and its pratical advantages. Duniter has its own Web of Trust principles, that will be exposed later.</p> +<h3 id="proof-of-work-mining-a-power-race">1.2. Proof-of-Work mining : a power race</h3> +<p>In Bitcoin Model, the calculation and incentive principles cause a power race : new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. This leads to a power race an places the control over the currency in the hands of the richest hardware owners. We want to make Duniter blockchain validation much less energy and hardware consuming while keeping a strong level of security. This will be further explained later. A consequence of this choice is the participation of low-end hardware in the Duniter network, leading to a better decentralization of blockchain validation.</p> +<h4 id="what-about-proof-of-stake">1.2.1 What about Proof of Stake ?</h4> +<p>Proof of stake consensus algorythm was first introduced in 2012<a href="#fn5" class="footnote-ref" id="fnref5"><sup>5</sup></a>. The basic principle is to allow the richest wallets to issue blocks, putting their coin balance as a “stake” they would lose in case of cheat.</p> +<p>At the time of conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. We did not chose this consensus principle. Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead to placing power over the currency in the richests hands : this is contrary to the symmetical principles of a libre currency.</p> +<h2 id="duniters-blockchain">2. Duniters Blockchain</h2> <!-- source : https://duniter.org/en/theoretical/ --> <p>Duniters Blockchain follows the basic principles of Bitcoins. This is essential for synchronization between peers, as to prevent double-spend attacks. However, Duniters Blockchain will store different informations than Bitcoins.</p> -<p>The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no <em>generation transaction</em> exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either:</p> +<p>The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no generation transaction exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either:</p> <ul> <li>a former transaction (as in Bitcoin)</li> <li>a Universal Dividend (specific to Duniter).</li> </ul> -<p>Duniters Web of Trust is also written in the Blockchain. The identity of each member gets registered much like transactinos are, with a strong link to the time reference. Thus, the Blockchain is a representation of a space-time frame of reference, where “space” are members of the WoT and “time” the basci blockchain units : the blocks. On each point of time, one can determain whick account is legitimate to create the UD, only with a blockchain analysis.</p> -<h3 id="spam-countermeasures-todo">Spam countermeasures (TODO)</h3> -<p>An issue of most cryptocurrency projects is to prevent the common ledger from growing too much and require lot of storage and computing power to be usable. In particular, we don’t want an attacker to be able to make the Blockchain grow too fast. Most projects implement transaction fees as a way to prevent this, making the attacker lose money. We don’t want to do this since a currency with automatic fees on transactions is no more neutral. Several countermeasuers against such spam attacks are implemented.</p> +<p>Duniters Web of Trust is also written in the Blockchain. The identity of each member gets registered much like transactions are, with a strong link to the time reference. Thus, the Blockchain is a representation of a space-time frame of reference, where “space” are members of the WoT and “time” the basic blockchain units : the blocks. On each point of time, one can determine which account is legitimate to create the UD, only with a blockchain analysis.</p> +<h3 id="spam-countermeasures">2.1. Spam countermeasures</h3> +<p>An issue of most cryptocurrency projects is to prevent the common ledger from growing too much. This would require nodes to have a lot of storage and computing power to be usable. In particular, we don’t want an attacker to be able to make the Blockchain grow too fast. Most projects implement transaction fees as a way to prevent this, making the attacker lose money. We don’t want to introduce this mean since a currency with automatic fees on transactions is no more neutral. Several countermeasuers against such spam attacks are implemented.</p> <!-- see : https://forum.duniter.org/t/sans-frais-de-transaction-comment-resister-aux-attaques/3846/25 (implemented ?)--> -<ul> -<li>output minimal de 100*Unitbase / 1 unité -> empêche un attaquant de faire grossir la BC et les index trop vite (DUBP v12)</li> -<li>chaînage maximal des tx</li> -<li>seuils de dépense (implémentés ? en tout et par issuer ?)</li> -</ul> -<h3 id="scaling">Scaling</h3> +<h4 id="minimum-output-amount">2.1.1. Minimum output amount</h4> +<!-- This has to be implemented in DUBPv13. --> +<p>Fixing a minimal output amount reduces the power of an attack. Duniter deals with cents of Ğ1 or 1/1000 of the first UD. An attacker could create thousand accounts with only 1 UD. To prevent this, a valid transaction must have output amounts of minimum 1Ğ1. This reduces the power an attack by 100.</p> +<h4 id="limited-block-size-and-chainability">2.1.2. Limited block size and chainability</h4> +<p>The block size is always limited. While the protocol allows this limit to evolve to address scaling issues, an attacker cannot register as many transaction as they wish.</p> +<p>With the same goal to prevent too many transactions to get registered, while transactions can be “chained” (refer to another transaction in the same block), the chainability of transactions is limited to 5.</p> +<h3 id="scaling">2.2. Scaling</h3> <p>Most of the time, the scaling issue rises for distributed systems that should work on a very large scale. This is not the case of Duniter, for multiple reasons :</p> <ul> -<li>Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don’t want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT limits its size to around 16 million members.</li> -<li>Duniter’s aim is to be used to create <em>multiple</em> libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community.</li> -</ul> -<p>However, Duniter has two assets that might be used if the number of users grow.</p> -<h4 id="dynamic-block-size">Dynamic block size</h4> -<p>While Bitcoin has a fixed block size, Duniters blocks size can evolve. On low use of the blockchain, the maximal block size is 500 bytes. On high use of the blockchain, the maximal block size would be 110% of the average size of the current window blocks( <em>current window</em> will be described in the PoW part). This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it.</p> -<div class="{highlight}"> -<p>block_size < max(500 ; CEIL(1.10 * (average block size))</p> -</div> -<h4 id="lightning-networks">Lightning Networks</h4> -<p>The Lightning Networks allow almost instant and off-chain transactions. They were first implemented on Lightcoin, and are now on Bitcoin. One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. While not available yet, this payment channel might get implemented when needed.</p> -<h2 id="duniter-web-of-trust">Duniter Web of Trust</h2> -<!-- source : https://duniter.org/en/deep-dive-into-the-web-of-trust --> -<h3 id="basic-principles">Basic Principles</h3> -<p>In order to identify “members” account - which create monetary units - from other accounts, Duniter uses a Web of Trust. This can be summarized into few principles:</p> -<ul> -<li>Each account becomes a member if it received a minimal number of certifications (5 for Ğ1 currency)</li> +<li>Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don’t want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT should limit its size to around 16 million members.</li> +<li>Duniter’s aim is to be used to create multiple libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community.</li> +</ul> +<p>However, Duniter has assets that will help if the number of users and transactions grow.</p> +<h4 id="dynamic-block-size">2.2.1 Dynamic block size</h4> +<p>While Bitcoin has a fixed block size, Duniters blocks size can evolve. On low use of the blockchain, the maximal block size is 500 bytes. On high use of the blockchain, the maximal block size would be 110% of the average size of the current window blocks(see “personalised difficulty” part for more information). This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it. The block size (in bytes) is limited as so :</p> +<pre><code>block_size < max(500 ; CEIL(1.10 * (average block size))</code></pre> +<h4 id="lightning-networks">2.2.2. Lightning Networks</h4> +<p>The Lightning Networks<a href="#fn6" class="footnote-ref" id="fnref6"><sup>6</sup></a> allow almost instant and off-chain transactions. They were first implemented on Lightcoin, and are now on Bitcoin. One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. While not available yet, this payment channel might get implemented when needed.</p> +<h4 id="unit-base">2.2.3. Unit base</h4> +<p>As the Universal Dividend grows exponentially, with time Duniter nodes would have had to deal with always largest amounts, eventually reaching the BIGINT limit. To avoid this, the amounts are expressed with a unit base in base 10. We want the UD amount to always fit in 4 digits. To manage it, the <code>unitbase</code> is updated each time the UD value reaches 100.00 : it goes from <code>99.99*10^(unitbase)</code> to <code>10.00*10^(unitbase+1)</code>. All the unit amounts are thus divided by 10. While this might seem strange, this process has already hapened in state currencies. Moreover, the amounts expressed in UD will not change.</p> +<p>With a monetary growth of 10% each year and a stable population, such a change of unit base would happen each 25 years.</p> +<h2 id="duniter-web-of-trust">3. Duniter Web of Trust</h2> +<h3 id="duniter-wot-basic-principles">3.1. Basic Principles</h3> +<p>In order to identify “members” accounts - which create monetary units - and other accounts, Duniter uses a Web of Trust. This can be summarized into few principles:</p> +<ul> +<li>Each account becomes a member if it received a minimal number of certifications - 5 for Ğ1 currency.</li> <li>Only members accounts can send certifications. Certifications have a limited lifespan.</li> <li>A certification indicates that the sender accepts the receiver as a legitimate identity.</li> </ul> -<p>The aim of the WoT is to identify a blockchain account to a living human. Each member of the Ğ1 currency signs a licence stating that they will only certify humans they know well (among other rules). Thus, if a member is part of an attack on the currency, they can be found by mutual friends. The security of Ğ1 currency stands on:</p> -<ul> -<li>Corroborating informations on members (5 certifications)</li> -<li>Peer pressure by close relatives</li> -<li>Law if the licence has not been respected.</li> -</ul> -<p>Note that non-members accounts can use the currency, but cannot create money. They can be used by individuals as secondary wallets, or by institutions.</p> -<p>However, the WoT does not rely only on trust betwenn people. Rules have been added to increase the security, and we will present them.</p> -<h3 id="why-do-we-need-a-web-of-trust">Why do we need a Web of Trust?</h3> +<p>The aim of the WoT is to identify a blockchain account to a living human. According to Lauterbach et.al<a href="#fn7" class="footnote-ref" id="fnref7"><sup>7</sup></a>, the strengh of a relationship should be considered when building a vouch system. For this reason, the Ğ1 Web of Trust rules are expressed in a licence stating what WoT certifications are. A certification represents a strong human relationship : one may certify a close relative, not an acquaintance. Each member has to accept this licence before being included in the WoT. Thus, if a member is part of an attack on the currency, they can be found by mutual relatives. Additional security rules occur to prevent cheat and attacks on a large scale.</p> +<p>Note that non-members accounts can use the currency, but cannot create money. Non-members accounts can be used by individuals as secondary wallets, or by institutions.</p> +<p>We were inspired by the OpenPGP Trust system<a href="#fn8" class="footnote-ref" id="fnref8"><sup>8</sup></a>. However, the OpenPGP trust principles aim at defining trust from a particular point of view while Duniter needs to identify humans for the whole community. To achieve this goal, while OpenPGP allows each user to tweak its trust parameters individually, Duniter sets rules in the “genesis” block for the whole community.</p> +<h3 id="why-do-we-need-a-web-of-trust">3.2. Why do we need a Web of Trust ?</h3> <p>There are two reasons we need it :</p> <ol type="1"> -<li>To make sure that only one Universal Dividend is produced per member at each specified creation interval -in the Ğ1’s case this interval is set as daily <code>86 400</code> seconds-, it is the <em>monetary parameter</em> known as <code>dt</code>-.</li> -<li><p>To identify the nodes hashing the blocks and assign them each a personalised difficulty. This custom difficulty <a href="https://en.wikipedia.org/wiki/Proof-of-work_system">proof of work</a> is there to avoid the blockchain’s validation mechanism becoming too centralised as is the case with many 'non-libre’ cryptocurrencies.</p> -<blockquote> -<p>Wait, what’s a ‘monetary parameter’ ?</p> -</blockquote></li> +<li>To make sure that only one Universal Dividend is produced per member at each specified creation interval. In the Ğ1’s case this interval is set as daily <code>86 400</code> seconds, it is the <em>monetary parameter</em> known as <code>dt</code>.</li> +<li>To identify the nodes hashing the blocks and assign each a personalised difficulty. This custom difficulty proof of work is there to avoid the blockchain’s validation mechanism becoming too centralised as is the case with many 'non-libre’ cryptocurrencies.</li> </ol> -<p>Every currency implementing Duniter has its own blockchain whose behaviour is dictated by a set of ‘parameters’ -defined in block zero, the so-called genesis block- that can be tweaked to achieve the desired results. At the time of writing this article, the Duniter protocol -aka DUP- has a total of 21 parameters of which 10 are for the WoT alone. We’ll focus on these 10.</p> -<p>Suffice to say that in the Ğ1’s case, the DU is created every 24 hours -86 400 seconds- but this interval -set through the time derivative <code>dt</code> parameter- can have a different value in an other implementation of the protocol.</p> -<p>I won’t write about the second parameter having to do with the proof of work, it’s outside our scope here, just know that the Web of Trust allows us to <strong>identify</strong> the members providing hashing power, which we couldn’t do without it. This crucial feature means we can impose a rotation between the members hashing the blocks so that no single rich individual or group invests in a giant ‘hash farm’ and takes a hold of the blockchain, paralysing the community!</p> -<p>Let’s go back to the first objective: to make sure that each member can only have one account. As we all know, achieving zero-risk isn’t possible, our goal is therefore not to create a WoT within which fraud would be absolutely impossible but instead to discourage it. Here is a rewording of our goal in 4 smaller ones :</p> -<ol type="1"> -<li>To make the certification process lengthy enough that all members exercise due diligence and are wary of risks.</li> -<li>To make fraudulent acts as hard as we can to the extent that they become pointless.</li> -<li>To ensure that any Sybil attacks have a negligible impact on the currency -<em>by ensuring that illegitimate double Universal Dividends have no significant bearing on the legitimate monetary mass</em>-</li> -<li>To slow the growth of ‘Sybil regions’ to give enough time for the community to react and isolate the threat.</li> -</ol> -<blockquote> -<p><strong>Wait, a Sybil what ?</strong></p> -</blockquote> -<p>A <a href="https://en.wikipedia.org/wiki/Sybil_attack"><strong>Sybil attack</strong></a>, is the name given to attacks perpetrated on a reputation system through the creation of fake identities. A Web of Trust is a specific instance of a <a href="https://en.wikipedia.org/wiki/Reputation_system"><strong>Reputation System</strong></a>.</p> -<p>There are plenty of Sybil attack scenarios we can think of and just as many reasons why their perpetrators would want to carry them out. Our objective is that the configuration of the WoT protects both users and its IT backbone infrastructure against these attacks.</p> -<p>This means that micro-attacks performed by small groups of individuals looking for personal enrichment are of no interest to us. The web’s role isn’t to deter these attacks, this being instead the role of the community. Just like the town you live in is responsible for providing your tap water and electricity but isn’t responsible for any burglaries etc. Much in the same way, Duniter’s WoT guarantees us all a functional currency and that’s quite a feat in itself!</p> -<h3 id="the-importance-of-having-our-own-certification-system">The importance of having our own certification system</h3> -<p>We are regularly offered to switch over to third-party or state-owned authentication systems but these are centralised and go against the principles of our community. We feel that we would lose our independence and universality by adopting a state-controlled system. People without an official state-provided identity or homeless people would also run the risk of being excluded from the WoT. It is of the utmost importance that we remain free from any state or corporation. To this day we depend only on the Internet and yet, were it to fail, there are already alternatives being tested around the world for a decentralised network.</p> -<h3 id="a-few-foundational-concepts-on-graph-theory-a-bit-of-vocabulary">A few foundational concepts on graph theory : a bit of vocabulary</h3> -<ul> -<li><p><strong>Graph</strong>: set of points -called ‘vertices’- joined by edges -called paths/walks-.</p></li> -<li><p><strong>Simple graph</strong>: a graph with no loops and with no multiple edges. That is, each edge connects two distinct endpoints and no two edges have the same endpoints. A simple edge is an edge that is not part of a multiple adjacency -of edges-. In many cases, graphs are assumed to be simple unless specified otherwise. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a></p></li> -<li><p><strong>Directed graph</strong>: a graph in which the edges have a distinguished direction, from one vertex to another. A directed edge can also be called a path or walk. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a> Arrow A –> B is therefore different from arrow B –> A.</p></li> -<li><p><strong>Endpoints</strong>: the edge with vertex A –> B has A and B as endpoints, respectively as start and end of the path/walk.</p></li> -<li><p><strong>Isolated vertex</strong>: a vertex whose degree is zero, that is, a vertex with no incident edges. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a></p></li> -<li><p><strong>Degree of a vertex</strong>: number of its incident edges -in and out-.</p></li> -<li><p><strong>Out-degree of vertex A</strong>: number of outbound edges / tail ends from A.</p></li> -<li><p><strong>In-degree of vertex A</strong>: number of incoming edges / head ends to A.</p></li> -</ul> -<figure> -<img src="https://duniter.org/en/images/wiki/degrees.jpg" alt="degress of a vertex diagram" /><figcaption>degress of a vertex diagram</figcaption> -</figure> -<ul> -<li><strong>Path</strong>: -aka “walk”- path to follow to get from vertex A to vertex B.</li> -</ul> -<h3 id="definition-of-the-duniter-web-of-trust">Definition of the Duniter Web of Trust</h3> -<p>The Duniter WoTs -one per currency- are simple directed graphs without isolated vertices. The vertices are the members and the edges are the certifications given and received.</p> -<p>Directed, what does that mean?</p> -<p>The responsibility of issuing a certification is unique and personal to the certifier. The trust he/she places in the receiver cannot be imposed in the other direction although in most circumstances both parties equally trust each other.</p> -<p>In addition, all vertices are either currently active members or past-members. Past-member vertices are in a specific ‘deactivated state’ and can no longer issue or receive certifications although the ones already issued or received to/from other members are still considered ‘pending’ to avoid the web collapsing like a house of cards.</p> -<p>If these old members don’t come back into the web, their pending certifications will eventually expire and they will switch from ‘deactivated’ to ‘isolated’ vertices.</p> -<p>To wrap up with old members, after a certain period of time -set in the currency’s parameters - their deactivated vertex is removed from the web and the associated identity is ‘revoked’. The person who owned the account can no longer use this identity but is free to join the web with another one. :-)</p> -<blockquote> -<p>What do you mean by ‘identity’?</p> -</blockquote> -<p>An identity is a set of three pieces of information: a public key, a name and a blockstamp. A blockstamp points to a specific block in the chain. Its main use is to freeze the point in time at which an identity was created and to link this identity to a specific chain and of course, a currency -each currency having its own blockchain-.</p> -<p>An identity can be in any one of 5 different status: pending, member, old member, revoked or excluded.</p> -<p>Let’s take a simple example:</p> -<div class="highlight"> -<pre><code>A -> B -> C - | - \--> D</code></pre> -</div> -<p>If, for whatever reason, A were to lose its member status, the web would crumble and all other members would be excluded as a consequence. To avoid this, the certification from A –> B will remain valid until its expiry date, leaving enough time for B to receive certifications from C or D.</p> -<p>Because our WoT doesn’t have any isolated vertices, each new identity created needs to be pulled into the web with all of the certifications it has received -in the same block-. This calls for a temporary ‘buffer’ storage space for <strong>pending</strong> identities and the certifications they’ve received. This storage space is called ‘the pool’ -of Duniter nodes- which we could also have called the ‘sandbox’ as that’s the name used in Duniter’s code. I might add that these ‘pools’ also include other documents and metadata not mentioned here.</p> -<h3 id="exploring-the-rules-behind-a-duniter-web-of-trust">Exploring the rules behind a Duniter Web of Trust</h3> -<p>The Duniter WoTs -one per currency- work with a set of eight fundamental rules, themselves enforced through eleven different parameters. Ten of these parameters are set within the genesis block, the eleventh one - <code>msPeriod</code>- having being hard-coded in the Ğ1’s code subsequently.</p> -<h4 id="distance-rule-and-referent-members-stepmax-and-xpercent-1distance-rule-and-referent-members-stepmax-and-xpercent">1.Distance rule and referent members (<code>stepMax</code> and <code>xPercent</code>) {#1distance-rule-and-referent-members-stepmax-and-xpercent}</h4> -<p>These two parameters are closely linked and together define the ‘distance rule’. The ‘distance rule’ can only be described after defining what a ‘referent member’ is:</p> -<blockquote> -<p><strong>Referent member</strong>: member A is said to be ‘referent’ if and only if the total of his/her degrees are greater than or equal to <code>CEIl-N^-1/stepMax--</code> where N is the total number of members.** As the size of the web will grow this number will grow too, meaning it will take more certification issuances to become a referent member as the number of certifications needed to become a member shouldn’t change.</p> -</blockquote> -<p>Let’s now define the distance rule:</p> -<blockquote> -<p><strong>Distance rule</strong>: member A is said to observe this rule if and only if for a subset xPercent % of referent members R there exists a path of length less than or equal to <code>stepMax</code> between R and A.**</p> -</blockquote> -<p>Referent members only exist so that the distance rule can take effect, they have no special privileges over non-referent members. In a perfect web, that is one in which each member has certified all members he/she legitimately can, all members would be referent members. However, because the web progressively grows in size and because members die and are replaced by new ones, there are always members at any given time <code>t</code> who haven’t yet certified all members they legitimately could. These members would hinder the evolution of the web if they were taken into account in the calculation of the distance rule and the web would effectively stop growing. -You can see what would happen if the notion of ‘referent member’ didn’t exist by going to the ‘gaussianWotQuality’ page on <a href="https://g1-monit.librelois.fr/gaussianWotQuality?lg=en&unit=quality">currency-monit</a> and activating ‘if the concept of referent members didn’t exist’-.</p> <blockquote> -<p><strong>When is the distance rule applied?</strong></p> +<p><strong>Monetary parameter</strong> : Each currency that use Duniter has its own blockchain whose behaviour is dictated by a set of ‘parameters’ defined in block zero - the so-called genesis block - that can be tweaked to achieve the desired results. At the time of writing the Whitepaper, the Duniter Blockchain Protocol (DUBP) has a total of 21 parameters of which 10 are for the WoT alone. We’ll focus on these 10.</p> +<p>Suffice to say that in the Ğ1’s case, the DU is created every 24 hours - 86 400 seconds. This interval is set through the time derivative <code>dt</code> parameter and can have a different value in other implementations of the protocol.</p> </blockquote> -<p>Because verifying the application of the distance rule is calculation-greedy, it is only performed when a new identity gets confirmed into the web or an existing member gets renewed. <em>Exception to the rule: the distance rule is not observed in the genesis block -when the web is first implemented-.</em></p> -<h4 id="rule-of-the-minimum-number-of-certifications-needed-sigqty-2-rule-of-the-minimum-number-of-certifications-needed-sigqty">2. Rule of the minimum number of certifications needed (<code>sigQty</code>) {#2-rule-of-the-minimum-number-of-certifications-needed-sigqty}</h4> -<p>This is the simplest rule, it essentially says that each member must at any given time -meaning in any single block- have received at least <code>sigQty</code> active certifications. If, for whatever reason, member A were to have less than <code>sigQty</code> active certifications in a given block, he/she would cease being a member and be required to publish a request for identity renewal.</p> -<h4 id="the-membership-renewal-rule-msvalidity-msperiod-and-mswindow-3-the-membership-renewal-rule-msvalidity-msperiod-and-mswindow">3. The membership renewal rule (<code>msValidity</code>, <code>msPeriod</code> and <code>msWindow</code>) {#3-the-membership-renewal-rule-msvalidity-msperiod-and-mswindow}</h4> -<p>Bear in mind that a membership doesn’t last a lifetime but instead has a lifespan set to <code>msValidity</code> seconds.</p> -<p>Every single member -or old member who hasn’t revoked his identity or been excluded- can request a membership renewal so long as the last request was made more than <code>msPeriod</code> seconds ago -if a member has never requested a renewal, the date of last renewal is equal to the timestamp at which his membership was first created. A new request will be stored in the ‘pool’ for a maximum of <code>msWindow</code> seconds before it’s included in the blockchain. Once again, this can only happen once/if the member meets both the <code>siqQty</code> rule and the distance rule -if these criterion are already matched it’s just a case of waiting for a new block to be mined-.</p> -<p>If a member hasn’t requested a renewal for longer than <code>msValidity</code> seconds, he/she automatically ceases being a member. From this moment on, the ex-member has another <code>msValidity</code> window to renew his/her membership. When this period of `2 × msValidity’ runs out, the membership will expire and this identity will never be available for use again in the web. If the person so desires, he/she will have to start from zero to regain access to the WoT.</p> -<h4 id="rule-of-certification-lifespan-sigvalidity-4-rule-of-certification-lifespan-sigvalidity">4. Rule of certification lifespan (<code>sigValidity</code>) {#4-rule-of-certification-lifespan-sigvalidity}</h4> -<p>All certifications included in the blockchain expire <strong>sigValidity</strong> seconds after they were <strong>issued</strong>.</p> -<p>/!\ The issuance and the inclusion of a certification in the blockchain occur at different times. When member A issues a certification at time t1, it gets stored in the pool starting at t1 and only finds its way into the blockchain at t2 when all of the web’s rules are observed. Several weeks can thus go by between t1 and t2!!!</p> -<h4 id="rule-of-limited-supply-of-active-certifications-sigstock-5-rule-of-limited-supply-of-active-certifications-sigstock">5. Rule of limited supply of active certifications (<code>sigStock</code>) {#5-rule-of-limited-supply-of-active-certifications-sigstock}</h4> -<p>By ‘active certifications’ we refer to certifications included in the blockchain and that haven’t yet expired.</p> -<p>The total of active certifications issued by any member at any single time must be less than or equal to <code>sigStock</code>. When this threshold is reached the member will have to wait for one of his active certifications to expire before he/she can issue a new one.</p> -<h4 id="rule-of-the-time-period-between-two-certification-issuances.-sigperiod-6-rule-of-the-time-period-between-two-certification-issuances-sigperiod">6. Rule of the time period between two certification issuances. (<code>sigPeriod</code>) {#6-rule-of-the-time-period-between-two-certification-issuances-sigperiod}</h4> -<p>As soon as a certification issued by member A gets included in the blockchain, he/she will be unable to issue a new one before another <code>sigPeriod</code> seconds.</p> -<h4 id="expiry-of-a-certification-issuance-sigwindow-7-expiry-of-a-certification-issuance-sigwindow">7. Expiry of a certification issuance (<code>sigWindow</code>) {#7-expiry-of-a-certification-issuance-sigwindow}</h4> -<p>When a certification is issued by member A, it will be stored in the ‘pool’ for a maximum of <code>sigWindow</code> seconds. If the certification hasn’t been included in the blockchain by then, it will be cancelled and the member’s <code>sigStock</code> will be repleted by one.</p> -<h4 id="lifespan-of-a-pending-active-certification-idtywindow-8-lifespan-of-a-pending-active-certification-idtywindow">8. Lifespan of a ‘pending’ active certification (<code>idtyWindow</code>) {#8-lifespan-of-a-pending-active-certification-idtywindow}</h4> -<p>When a new identity is created, it is stored in the ‘pool’ for a maximum of <code>idtyWindow</code> seconds. If the person hasn’t achieved member status by then, the certification will simply be cancelled.</p> -<h3 id="details-on-some-of-the-wots-peculiarities-at-the-genesis-block">Details on some of the WoT’s peculiarities at the genesis block.</h3> -<p>The aforementioned rules can only be enforced with an existing web. They cannot be observed when first creating the web, that is when defining the genesis block.</p> -<p>Only rules 2 and 5 can be observed at the genesis block.</p> -<p>The genesis block has to be manually created by the founding members. In practice this means that there must be a choice of which identities to include on the premise that all of them observe rules 2 and 5. In addition, the genesis block must be signed with the private key of one of these identities.</p> -<p>As soon as the genesis block has been created, the other identities can start mining the blockchain and the member who begat block #0 effectively looses the decision power he had at creation.</p> -<h3 id="why-these-rules-and-application-cases-in-the-g1">Why these rules and application cases in the Ğ1</h3> -<h4 id="distance-and-maximum-size-1-distance-and-maximum-size">1. Distance and maximum size {#1-distance-and-maximum-size}</h4> -<p>The distance rule is there to curb the maximum size of a Sybil region as well as that of the monetary community as a whole. The <code>xpercent</code> parameter prevents the creation of a ‘faction’ that could take hold of the blockchain.</p> -<figure> -<img src="https://duniter.org/en/images/wiki/wot-sybil.jpg" alt="Sybil region" /><figcaption>Sybil region</figcaption> -</figure> -<p>The Sybil regions are isolated from the rest of the graph in the sense that they can only receive certifications from other ill-intentioned Sybil members. As a consequence, the shortest edge/path between a legitimate member and a Sybil one has to have the attack’s author as an endpoint. The maximum depth the Sybil region can attain is therefore contingent on the distance between the attacking edge-s- and the xpercent% closest referent members, this distance is known as <code>stepAttackers</code>. The maximum size of a Sybil region created by <code>sigQty</code> members depends on the L parameter, defined as L = sigQty/sigStock:</p> -<div class="highlight"> -<pre><code>Maximum Sybil region size = (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L)</code></pre> -</div> -<p>The maximum size of the Web of Trust is given by the following formula:</p> -<div class="highlight"> -<pre><code>WoTmax = (sigStock)*L^(stepMax-1)</code></pre> -</div> -<p>However we know for a fact that members will never use all of their available certifications. Many studies have proven that we all know a maximum average of fifty people, let’s then replace sigStock by fifty:</p> -<div class="highlight"> -<pre><code>WoTavg= (50)*(sigQty/50)^(stepMax-1)</code></pre> -</div> -<p>Our goal with the Ğ1 is to create a community of about one million members enjoying the world’s first true <a href="https://en.wikipedia.org/wiki/Catallaxy">catallaxy</a> -free economy with a spontaneous order of things-. Let’s see how we can tweak the pair of sigQty and stepMax- to reach this size:</p> -<figure> -<img src="https://duniter.org/en/images/wiki/graph-WoTmoy.png" alt="graphe WoTmoy en fonction de sigQty et stepMax" /><figcaption>graphe WoTmoy en fonction de sigQty et stepMax</figcaption> -</figure> -<p>The maximum size of a Sybil region grows linearly with <code>sigQty</code> but exponentially with <code>stepMax</code>. Logic has it that we need to keep <code>stepMax</code> as low as possible to ensure sufficient strength to the web. The above graph shows that the lowest value of <code>stepMax</code> for a web of a million members is of 5. This is an order of magnitude and is likely to be much higher in reality, we cannot measure it for sure.</p> -<p>For <code>sigQty</code> we can choose a value of <strong>4</strong> for a web of <strong>1.5 million members</strong> or <strong>5</strong> for <strong>half a million members</strong>. Bear in mind these are gross figures and could be significantly higher, we are talking anywhere between 1 and 10 million in reality. Calculating WOTavg gives us a pretty good idea of how the web would scale bearing in mind that it considers all members are referent members too -which isn’t the case as explained previously-. Hence the maximum size of the web is likely larger, a ballpark figure of half a million is enough for now especially knowing that the smaller <code>sigQty</code> is, the easier it is to launch a Sybil attack -it’s easier to find four accomplices than five-. For security reasons we have settled on five:</p> -<p>stepMax = 5 sigQty = 5 sigStock >= 50</p> -<p>The maximum size of a Sybil region therefore is: <code>(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5))</code></p> -<p>with sigStock = 50 we have a Sybil region of: <code>45*(1-10^(5-stepAttackers))/(-9)</code></p> -<p>A good practice for protecting the web is to maximise <code>stepAttackers</code>. That’s why we decided that referent members in the genesis block had to be at least four steps away from each other.</p> -<p>Another way to keep a Sybil attack at bay, were it slow enough for members to notice it, would be for referent members to ‘stretch’ the web intentionally to limit the growth of the region by ensuring that the attackers’ legitimate certifications received in the first place aren’t renewed. But what if bot accounts were created and certified each other super fast and following all rules, how would we counter that? By introducing a minimum length of time between two certifications!</p> -<h4 id="time-is-our-friend-2-time-is-our-friend">2. Time is our friend {#2-time-is-our-friend}</h4> -<p>To help us deter a Sybil attack, we’ve decided to impose a minimum period of time between any two certifications issued from a single account. This parameter called <code>sigPeriod</code> affords us a greater chance to detect the formation of a ‘hostile’ faction.</p> -<p>Here is a graph showing the evolution of a Sybil region with the variation of <code>sigPeriod</code>:</p> -<figure> -<img src="https://duniter.org/en/images/wiki/impact_sig_period.png" alt="graph of the WoT's size according to sigPeriod and stepAttackers" /><figcaption>graph of the WoT's size according to sigPeriod and stepAttackers</figcaption> -</figure> -<p>As you’ll easily be able to tell, there is a strong link between the growth speed of the region and <code>sigPeriod</code>. As evidenced here, we need a <code>sigPeriod</code> high enough in order to ensure that the legitimate web can grow at least as fast as a Sybil region. In addition, the higher <code>sigPeriod</code> is, the more members will exercise their certification power gingerly, the action coming at a higher ‘cost’.</p> -<p>There are numerous advantages to giving <code>sigPeriod</code> a high value and no technical barriers to it, hence our choice of five days.</p> -<p>We could have also gone for days days -one week- for the sake of simplicity however there was an underlying idea behind our choice which was quite simply the pace of today’s life. Certifying someone can be a lengthy process as one needs to make sure he/she is correctly applying the Ğ1 licence and people nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea to allow one to certify at the end of every working week -five days- instead of a whole calendar one.</p> -<h4 id="trust-me-now-trust-me-forever-sigvalidity-msvalidity-3-trust-me-now-trust-me-forever-sigvalidity-msvalidity">3. Trust me now, trust me forever? (<code>sigValidity</code>, <code>msValidity</code>) {#3-trust-me-now-trust-me-forever-sigvalidity-msvalidity}</h4> -<p>There would be two main drawbacks to a lifetime membership in the Ğ1’s Web of Trust:</p> -<blockquote> -<p>First of all we need to take into account that some members will pass and those accounts should no longer produce the Universal Dividend. Secondly it is of the utmost importance that ‘rogue’ accounts can be excluded from the web at some point.</p> -</blockquote> -<p>To achieve this, certifications have a limited lifetime and members need to seek renewal from their peers after <code>sigValidity</code> time. On the other hand, this time can’t be too short that members would spend more time seeking renewal than they would exchanging in the currency. Furthermore, a certification with too short a lifetime would foster careless certifying behaviours. The act of certifying must have a ‘perceived’ cost high-enough to make it feel like an important act. Lastly, we also wanted this lifetime to be easy enough to remember. Historically speaking, we first settled on the values of <code>sigPeriod</code> and <code>sigStock</code>, meant one could issue all of his/her certifications in 495 days, one year was therefore not long enough. We deemed three years to bee much and that’s how we agreed on two years in the end.</p> -<p>Thinking that a deceased member could continue producing the UD for two long years without anyone benefitting from it was also something we needed to address. We choose a value of one year for <strong>msValidity</strong>. The act of renewing every year is done through one of the clients interacting with the blockchain, through a simple click on a button. This parameter is less important than others and is mostly there to ‘prune’ the web of past or inactive members who don’t renew their membership.</p> -<h4 id="keeping-the-pools-free-of-information-glut--idtywindow-sigwindow-mswindow-4-keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow">4. Keeping the pools free of information glut -(<code>idtyWindow</code>, <code>sigWindow</code>, <code>msWindow</code>) {#4-keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow}</h4> -<p>The pools need to be cleaned up on a regular basis to avoid them clogging up with information and to ensure that machines with less calculating power can still run a Duniter node.</p> -<p>To achieve this, identities with pending membership approval and the corresponding certifications have to remain the shortest time possible in the pool while still having a chance of making it into the blockchain.</p> -<p>For the Ğ1, our opinion was that two months would be enough for all potential certifiers to agree on a specific identity to certify. We also wanted a time period that would be easy enough to remember by all. We settled on two months, and gave this value to all three parameters <code>idtyWindow</code>, <code>sigWindow</code> and <code>msWindow</code>.</p> -<h4 id="avoiding-single-members-from-knowing-too-many-people-sigstock-5-avoiding-single-members-from-knowing-too-many-people-sigstock">5. Avoiding single members from ‘knowing too many people’ (<code>sigStock</code>) {#5-avoiding-single-members-from-knowing-too-many-people-sigstock}</h4> -<p>Many sociology studies have shown that we all know an average of fifty people. This of course is an average, some of us know more than fifty people, others much less. Once again we went for a number that would be easy to remember. Although <code>sigStock</code>’s impact on the size of a Sybil region is fairly limited, its value nonetheless has to be kept reasonable. We settled on hundred.</p> -<h4 id="avoiding-locking-minorities-xpercent-6-avoiding-locking-minorities-xpercent">6. Avoiding locking minorities (<code>xpercent</code>) {#6-avoiding-locking-minorities-xpercent}</h4> -<p>It’s easy enough to become a referent member, one of the Sybil strategies could therefore be to create a region of referent members. Such a region would grow slower than otherwise but could confer a locking power to its members by using the distance rule. That’s why the distance rule cannot be calculated on 100% of the referent members. Hence the introduction of the <code>xpercent</code> parameter which defines the percentage of referent members needing to be less than five edges -steps- from each other.</p> -<p>This percentage needs to be low enough to prevent the formation of a locking minority -referent Sybil members being too far from legitimate referent members-. On the other hand, it needs to be high enough so as to restrict the maximum size of the Sybil region through the distance rule. The <code>xpercent</code> parameter was one of the hardest to define, we therefore reserve ourselves the right of modifying its value during the Ğ1 experiment.</p> -<p>We were inspired by the <a href="https://en.wikipedia.org/wiki/Pareto_principle">Pareto principle</a>: if at least 20% of members give good density to the web, 80% of the referent members will be five or less steps from any other member -referent or non-. The maximum value for <code>xpercent</code> is therefore 80%, anything above that and the distance rule could be too restrictive for legitimate use cases. With security our top concern, we chose the maximum value of 80%.</p> -<h4 id="spam-protection-with-msperiod-7-spam-protection-with-msperiod">7. Spam protection with (<code>msPeriod</code>) {#7-spam-protection-with-msperiod}</h4> -<p>This parameter stands out a bit on its own, as it was added after the genesis block. It is there to protect the Duniter P2P infrastructure against ‘spam’ attacks. We had to think of a strategy against attacks such as high-frequency membership renewal requests -i.e: in every block, every five minutes- or worse still, hundreds of these requests per minute to flood the Duniter nodes. Without such limits, nodes are supposed to address all renewal requests, even in cases where they were last published five minutes ago! The <code>msPeriod</code> parameter was given the same value as <code>idtyWindow</code>, <code>sigWindow</code> and <code>msWindow</code>, i.e. two months.</p> -<h2 id="proof-of-work-with-personal-difficulty">Proof of Work with personal difficulty</h2> -<p>As each P2P cryptocurrency, Duniter has a way to synchronize its peers. It uses a proof of Work (PoW) to write the Blockchain on a regular basis, much like BitCoin. However, Duniter has a unique asset : the WoT, where each member represents a unique living human.</p> -<p>This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each “winning” member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. The knowledge of the whole network is not needed.</p> -<p>Another strong difference is that forging peers are not rewarded by the protocol. There is no economical incentive on forging lots of blocs, neither on having a lot of computing power.</p> -<p>One could say that Duniter uses a PoW that needs very low energy consumption compared to BitCoin : an “ecological” PoW ?</p> -<!-- source : https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/ --> -<h3 id="why-do-we-need-proof-of-work">Why do we need Proof of Work ?</h3> -<p>Duniter nodes share a database as part of a p2p environment. The proof of work (PoW) allows machines to synchronize with each other. In Duniter’s case, the blockchain is our database, and acts as a ledger keeping a trace of all transactions, status of the WoT and more. How can we let several machines add data (ie: a transaction) at the same time? In addition, how do we settle on how much time has gone by since the blockchain was last updated? Agreement on time is of the utmost importance as we want to create Universal Dividends on a regular basis, and keep track of membership status, both in human time.</p> -<p>Proof-of-work provides a clever solution to both problems: 1. Any machine can write into the blockchain (create a new block) but is only authorised to do so if it has previously solved a mathematical equation that require a certain amount of work. The challenge has to be hard enough to prevent two machines to solve it at the same time, ensuring the unicity of a block’s creator.</p> -<ol start="2" type="1"> -<li>Solving this challenge takes a certain amount of time, which depends on the calculating power of the whole network. This provides a common ground for defining the needed time reference. A block time is set (ie: 1 block = 5 min) and Duniter adapts the challenge difficulty to get an <em>average</em> duration corresponding to this block time.</li> -</ol> -<h3 id="only-members-can-mine">Only members can “mine”</h3> -<p>One of Duniter’s major differences with other PoW-based cryptocurrencies is that only members are allowed to author blocks. Each block is signed with the member’s private key, allowing the algorithm to determine a <em>personalised difficulty</em>.</p> -<p>This personalised difficulty eliminates the rat-race for the most sophisticated and powerful mining equipment. Another benefit is the fact that no “supercomputer” can take control of the blockchain. Lastly, Duniter implements a rotation in forging members thanks to this personalized difficulty.</p> -<p>This lightweight PoW is much less energy-consuming than other PoW cryptocurrencies. Members can mine with anything from a raspberry pi to a privacy-first internet cube.</p> -<h3 id="how-does-it-work">How does it work?</h3> -<h4 id="the-hash-aka-digest">The hash (aka digest)</h4> -<p>Example of a valid hash:</p> -<div class="highlight"> -<pre><code>00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653</code></pre> -</div> -<p>As you can see this hash starts with five zeros which was very hard to achieve and took a lot of <em>work</em> for someone’s computer. Hence the term “proof of work”.</p> -<h4 id="the-common-difficulty">The common difficulty</h4> -<p>A common difficulty is needed to settle on a yardstick for our time reference. Its role is to make sure the blockchain moves forward at a steady pace - one block every <code>avgGenTime</code> seconds, <code>avgGenTime</code> being one of the 20 parameters behind the Duniter protocol-.</p> -<p>This difficulty’s initial value can be set to any arbitrary value (<code>70</code> in Duniter <code>v1.5.x</code>) and then acts as a spring, regulating blocktime creation by increasing itself if the creation interval drops under <code>avgGenTime</code> and vice-versa.</p> -<h5 id="how-is-difficulty-applied">How is difficulty applied?</h5> -<p>The numeric value of difficulty is taken from an array of possible hashes out of all possible hashes. In duniter v1.5.x the hash of a block is its sha256 hexadecimal hash.</p> -<p>To understand the difficulty, we make a euclidiean division of the difficulty by 16.</p> -<p>Here’s an example with a difficulty value of <code>70</code> : 70 // 16 = <strong>4</strong> with a remainder of <strong>6</strong>. The valid hashes are the ones starting with four zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). The valid hashes are then written as starting with : <code>0000[0-9]</code>. This is a bit different from Bitcoin, where the difficulty is only ruled by the number of zeroes.</p> -<blockquote> -<p>Fine, but the hash of a mined block will never change and there’s no reason it should start with a given sequence of numbers. So how then can we make sure a block hash starts with exactly the sequence needed?</p> -</blockquote> -<p>Enter the nonce, short for “number once”. When a member is forging a new block, his computer freezes the block’s content and changes the Nonce until the hash reaches the required number of zeroes.</p> -<h5 id="the-nonce">The Nonce</h5> -<p>The nonce allows us to mine a new block by finding a hash. The hash value allows us to determine the difficulty level of the proof-of-work performed. Examples of possible Nonce values:</p> -<ul> -<li>10100000112275</li> -<li>10300000288743</li> -<li>10400000008538</li> -<li>10700000079653</li> -<li>10300000070919</li> -</ul> -<p>In reality the <code>Nonce</code> value follows a pre-determined format akin to <code>XYY00000000000</code>. The Nonce’s value isn’t the number of attempts but rather a value within a set of possible ones. This is how the Nonce is built:</p> -<ul> -<li><p>X is a number assigned to a specific peer. Let’s assume that someone has several nodes each with the same private key, this would lead to possible collisions if this person were to mine the same block with different nodes. Each block will therefore have its own unique X to prevent this from happening.</p></li> -<li><p>Y is the number of cores of the processor. The Nonce starting with <code>107[…]</code> belongs to a seven cores processor, while <code>199[...]</code> could be the proof generated by a 99 cores processor.</p></li> -</ul> -<p>The rest of the Nonce, the part that follows after the XYY, is the numerical space for this individual node and is unique to each of the CPU’s core. This space is comprised of eleven digits (<code>00000000000</code>). For the sake of accuracy, we use the term CPU in the wider sense, it can be understood as a bi-CPU for example. We take into consideration the number of cores for the resulting PoW.</p> -<h3 id="personalised-difficulty">Personalised difficulty</h3> -<p>Earlier in this article, we explained that the personalised difficulty is the new and key concept that sets Duniter apart from other <em>PoW-based</em> cryptocurrencies such as Bitcoin.</p> -<p>Here is how this personalised difficulty is calculated and assigned:</p> -<p>It is determined by a combination of two different constraints with complimentary roles: the <strong>exclusion factor</strong> and the <strong>handicap</strong>.</p> -<p>Let <code>powMin</code> be the common difficulty, <code>exFact</code> a member’s exclusion factor and <code>handicap</code> their handicap. This member’s personalised difficulty <code>diff</code> is:</p> -<div class="highlight"> -<pre><code>diff = powMin*exFact + handicap</code></pre> -</div> -<h4 id="understanding-exfact-the-exclusion-factor">Understanding <code>exFact</code>, the exclusion factor</h4> -<p>Members who have never produced blocks or haven’t for quite some time are assigned an exclusion factor of <code>1</code>. Their personalised difficulty is therefore simply the sum of <code>powMin + handicap</code>.</p> -<p>Before reading on, let’s precise the role of this exclusion factor. When a member adds a block to the chain, his <code>exFact</code> jumps up from one to a very high value, to prevent them from forging other blocks immediately after and taking control of the blockchain.</p> -<p>The exclusion factor will then rapidly return to one. This delay is expressed as a number of blocks. It is calculated as a proportion of the number of members forging. In the Ğ1’s case, this proportion is 1/3, meaning that if there are fifteen members currently forging, the member’s exclusion factor will drop down to one after five blocks.</p> -<blockquote> -<p>What is intended by “the number of members forging”?</p> -</blockquote> -<p>We mean the number of members trying to create the next block. In reality, there is no way to precisely know how many members are calculating at any given time, because it is impossible to view the entire network. But we need this information, whithout which assigning a personalised difficulty is impossible. To achieve this, Duniter looks back at the blockchain and assumes that there is as much members forging as those who have found at least one block in the last X blocks, minus the very last one.</p> -<blockquote> -<p>Hox is X determined?</p> -</blockquote> -<p>We use the concept of <strong>current window</strong>. X’s value is equal to the size of this window. Let’s see how it works:</p> -<ul> -<li><p><code>issuersFrame</code> is the size of the current window in blocks.</p></li> -<li><p><code>issuersCount</code> the number of members who have calculated at least one block during the current window.</p></li> -</ul> -<p>Both <code>issuersFrame</code> and <code>issuersCount</code> are block fields. When first starting a blockchain, the very first block has an <code>issuersFrame=1</code> and an <code>issuersCount=0</code>. The genesis block is excluded as there are no members in the current window!</p> -<p>From the second block onwards (block #1) we track the variation of <code>issuersCount</code>. The member having mined block #0 enters the current window and in block #1 we will therefore mention <code>issuersCount=1</code>.</p> -<p><code>issuersFrame</code> then varies as follows:</p> -<ul> -<li>if <code>issuersCount</code> increases by N (with a maximum step of N = 1), then <code>issuersFrame</code> will increase by one unit over a period of 5N blocks.</li> -<li>Conversely, if <code>issuersCount</code> decreases by Y (with a maximum step of Y = 2 = current window inching forward + loss of one calculating member), then <code>issuersFrame</code> will decrease by one unit during 5Y blocks.</li> -<li>When such events overlap, <code>issuersFrame</code> evolves as so :</li> -</ul> -<table> -<thead> -<tr class="header"> -<th>bloc</th> -<th>event</th> -<th>issuersFrame</th> -</tr> -</thead> -<tbody> -<tr class="odd"> -<td>T</td> -<td>Babar writes a block and enters issuersCount</td> -<td>160</td> -</tr> -<tr class="even"> -<td>T+1</td> -<td>Celeste leaves issuersCount</td> -<td>160 +1 = 161</td> -</tr> -<tr class="odd"> -<td>T+2</td> -<td>N/a</td> -<td>161 +1 -1 = 161</td> -</tr> -<tr class="even"> -<td>T+3/4/5</td> -<td>N/a</td> -<td>161 +1 -1 = 161</td> -</tr> -<tr class="odd"> -<td>T+6</td> -<td>N/a</td> -<td>161 -1 = 160</td> -</tr> -</tbody> -</table> -<p>The calculation can be found under rules <a href="https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g05-headissuersframe">BR_G05</a> and <a href="https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g06-headissuersframevar">BR_G06</a> of the DUP protocol.</p> -<blockquote> -<p>Let’s go back to the personalised difficulty.</p> -</blockquote> -<p>We explained that <code>exFact</code> spikes immediately after the member has found a block. It decreases then rapidly to <code>1</code> after a number of blocks <code>X = 1/3 * issuersCount</code>. Let’s see precisely how we calculate <code>exFact</code>:</p> -<ul> -<li><p><code>nbPreviousIssuers</code> is the value of issuersCount at the last block <code>N</code> found by the member.</p></li> -<li><p><code>nbBlocksSince</code> is the number of blocks found by the rest of the network since block <code>N</code>.</p></li> -<li><p><code>percentRot</code> is the number of <em>not excluded</em> peers we want. It is a monetary parameter, its value is 0.67 for Ğ1 currency.</p></li> -</ul> -<div class="highlight"> -<pre><code>exFact = MAX [ 1 ; FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) ]</code></pre> -</div> -<p>The FLOOR is a simple truncate function. For <code>exFact</code> to exclude the member, we need :</p> -<blockquote> -<p>(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2</p> -</blockquote> -<p>We can see that the member is not excluded if <code>nbBlocksSince</code> is greater than 1/3 of the calculating members. Take as an example nbPreviousIssuers = 6 and nbBlocksSince = 3:</p> -<blockquote> -<p>(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1</p> -</blockquote> -<p>However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded: > (0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2</p> -<p>Moreover if the last block was authored by the said member, then: > <code>nbBlocksSince=0</code> and > <code>exFact</code> = <code>0.67 * nbPreviousIssuers</code></p> -<p>ExFact value increases according to the number of members calculating. Thus, if there is enough members calculating, even mining farms would be excluded. We have therefore succeeded in our intent to deter attempts to seize the blockchain and its currency.</p> -<p>However, at any time t, the two-thirds of calculating members all have an exclusion factor of <code>1</code>, even though they might not all have the same computational power at hand. If the personalised difficulty only took into account the exclusion factor, then only the members with the highest computational power from the remaining third would be able to author new blocks and the other 2/3s would almost always be excluded. Lesser machines wouldn’t stand a chance…</p> -<h4 id="the-handicap">The handicap</h4> -<p>The handicap is the second parameter of the personalised difficulty. Its main role is to improve the rotation of forging peers. A higher handicap is assined to members with higher calculating power, so lesser machines can also compute blocks. As a consequence, there is no incentive on forging with powerful computers. Security can be achieved with less computing power than with pure PoW.</p> -<p>The aim is to handicap the half that has authored most blocks (the most powerful half) to favour the other one. So, the handicap formula will use the median number of blocks authored by peers within the current window.</p> -<ul> -<li><p><code>nbPersonalBlocksInFrame</code> is the number of blocks authored by a single member within the current window.</p></li> -<li><p><code>medianOfBlocksInFrame</code> is the median number of blocks written by the calculating members during the same timeframe.</p></li> -</ul> -<div class="highlight"> -<pre><code>handicap = FLOOR(LN(MAX(1;(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)) / LN(1.189))</code></pre> -</div> -<p>Let’s unwrap the formula: <code>(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)</code> is simply the ratio between the number of blocks authored by the peer and the median number of blocks. For example, if a peer has authored <code>9</code> blocks in the current window and the median is <code>5</code>, then the ratio will be <code>(9+1)/5 = 2</code>. The MAX function allows us to ensure that the handicap has a value at least equal to <code>1</code>.</p> -<p>The Napierian Logarithm of this ratio prevents the handicap from becoming excluding. We want the handicap to level the calculating field so that all peers stand a chance, not to exclude peers.</p> -<p>If we want the handicap to be applied as soon as the median is reached, we’d have to divide it by <code>LN(1)</code>, the problem is that we’ve already set a minimum value of <code>1</code> with the MAX function, so if we were to divide the ratio by <code>LN(1)</code> all calculating peers would have a handicap >= <code>1</code>. In addition, is it really fair to handicap a member who’s right on the median?</p> -<p>That’s why we went for <code>1.189</code> rather than <code>1</code>. A member has to be at least <code>18.9%</code> above the median to be assigned a handicap. 18.9% is actually 16^(1/16), the difficulty factor between two levels of the proof work (hexadecimal hash).</p> -<p>To conclude, you have to remember that :</p> -<ul> -<li>the handicap is indexed on the logarithm of the ratio to the median,</li> -<li>handicap is only applied on members whose ratio to the median is greater than the ratio between two levels of the proof-of-work’s difficulty.</li> -</ul> -<h2 id="conclusion">Conclusion</h2> -<!-- source : https://duniter.org/en/theoretical/ --> -<p>Duniter’s Blockchain can be compared to Bitcoin’s : a common document retracing the history of the currency. However, Duniter registers not only trades, but also the history of relationships in the community as a mean to identify a human to a digital account. This way, Duniter has information about the fondamental reference of RTM : living humans. A libre Currency can be issued thanks to the Universal Dividend.</p> -<p>More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers while maintaining a good security on the network.</p> -<p>The ultimate goal of Duniter project is to allow people to participate in a libre economy, thanks to a libre currency. What is a libre economy ? The Relative Theory of Money defines it through four economic liberties :</p> -<ul> -<li>The freedom to choose your currency system: because money should not be imposed</li> -<li>The freedom to access resources: because we all should have access to economic & monetary resources</li> -<li>The freedom to estimate and produce value: because value is a purely relative to each individual</li> -<li>The freedom to trade with the money: because we should not be limited by the avaible money supply</li> -</ul> -<p>Those 4 economic freedoms should be understood together, not exclusively. Plus, “freedom” has to be understood as “non-nuisance”. So here, freedom does not mean the right to take all of a resource (like water source in a desert) so no more is available to the others. Now you get it, this is the goal: free economy through free currency.</p> -<h2 id="duniter-projects-sources">Duniter project’s sources :</h2> -<ul> -<li>Theoretical, by Cgeek: https://duniter.org/en/theoretical/</li> -<li>Lock conditions, by Inso: https://duniter.org/en/transactions-0-2-overview/</li> -<li>Individualised Proof of Work, by Elois: https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/</li> -<li>Deep dive into the Web of Trust, by Elois: https://duniter.org/en/deep-dive-into-the-web-of-trust/</li> -<li>Whitepaper sources: https://git.duniter.org/communication/duniter-whitepaper</li> -</ul> -<h2 id="other-sources">Other sources :</h2> -<ul> -<li>Relative Theory of Money, S.Laborde, 2010: http://en.trm.creationmonetaire.info/</li> -<li>Bitcoin Whitepaper, S.Nakamoto, 2008: https://bitcoin.org/bitcoin.pdf</li> -<li>Circles Whitepaper, A.Milenius, 2018: https://github.com/CirclesUBI/docs/blob/master/Circles.md</li> -<li>The Sibyl Attack, J.R.Douceur: https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</li> -</ul> -<!-- travaux en theorie des graphes pourla TdC --> -</article> -</main> -</body> -</html> -<!--doctype html--> -<html lang='en' > -<head > -<title> -Duniter Whitepaper -</title > -<meta charset='UTF-8' /> -<link - rel='stylesheet' - href='bulma.css' > <link - rel='stylesheet' - href='main.css' > -<script src='js/jquery.js' ></script > -<script src='js/toc.js' ></script > -<script type='javascript' > - if ($) { - $('#whitepaper').tableofcontents({ id: '#toc' }); - } - </script > -</head > -<body> -<main> -<div id="toc"> - -</div> -<article id="whitepaper" class="content"> -<h1 id="duniter-a-libre-currency-blockchain-generator-1">Duniter : A libre currency blockchain generator !</h1> -<h2 id="abstract-todo-1">Abstract (TODO)</h2> -<h2 id="introduction-1">Introduction</h2> -<p>Duniter is a software to create and manage “libre currencies”. Libre currency is a concept defined by S.Laborde in the Relative Theory of Money (RTM) that was published in 2010. This theory demonstrates the possibility of an invariant monetary unit : the Universal Dividend. Doing so, the RTM answers the question :</p> -<blockquote> -<p>How should a currency be created to match the principle of equality between all humans ?</p> -</blockquote> -<p>The results of this demonstration implies a monetary creation :</p> -<ul> -<li>on a regular basis</li> -<li>for each human being</li> -<li>which amount has to be reassessed on fixed intervals according to a fixed formula.</li> -</ul> -<p>Thus, Duniter project will associate a human to a digital identity. It will use a Web of Trust with specific rules. As the number of members may evolve, the Universal Dividend has to be created according to the formula :</p> -<blockquote> -<p>UD(t+1) = UD(t) + c² * ( M(t) / N(t) )</p> -</blockquote> -<p>Duniter is based on a decentralized Blockchain. This technical choice allows irreversibility of transaction and uncensorability of trades and identities. While inspired by Bitcoin, Duniter uses a Web of Trust and the Proof of Work to secure the computation network, thus making obsolete the power race model used in Bitcoin.</p> -<p>The first currency created through Duniter is Ğ1 (say “June”). It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software.</p> -<h2 id="state-of-the-art-bitcoin-case-1">State of the art : Bitcoin case</h2> -<!-- source : https://duniter.org/en/theoretical/ --> -<p>Duniter uses the crypto-currency concept introduced by Bitcoin, which is to use cryptographic tools such as <em>signatures</em> to create digital currencies. Duniter fits this definition, but it has completely different principles than Bitcoin : the Web of Trust and the Universal Dividend . These differences are on both monetary and technical aspects.</p> -<h3 id="monetary-creation-of-bitcoin-a-space-time-asymmetry-1">Monetary creation of Bitcoin : a space-time asymmetry</h3> -<p>Space-time asymmetry refers to the relative access of individuals to newly created money (Relative Theory of Money, S.Laborde, 2010). Concretely, all existing currencies (c. 2015) are both spatially and temporally asymmetrical for their users. Let's take Bitcoin as an example to understand why.</p> -<h4 id="spatial-asymmetry-1">Spatial asymmetry</h4> -<p>When new Bitcoins are created, <em>only some Bitcoin users</em> (the miners) are given new Bitcoins, while everyone else get nothing. <strong>We believe this is the <em>first</em> injustice.</strong> However, some might say:</p> -<blockquote> -<p>"Miners used their <em>electricity and time</em> to get it!"</p> -</blockquote> -<p>... we would answer that this work <em>shouldn't have been rewarded by newly created Bitcoins</em>. New Bitcoins should be distributed to the whole Bitcoin community. Miners should be rewared another way, but not by money issuance. Of course, Bitcoin can't create money through Basic Income since <em>Bitcoin users are not strongly identified</em>, and one might benefit from money creation multiple times if he owned several wallets. Duniter gets rid of this problem completely by identifying its users and giving <em>the same amount of Basic Income to everyone</em>.</p> -<h4 id="temporal-asymmetry-1">Temporal-asymmetry</h4> -<p>Bitcoin has an absolute limit of 21 million BTC (its unit of currency), which means ever fewer bitcoins will be created over time until no new BTC are being generated. So, once the first adopters have mined every bitcoin, how will future joiners get Bitcoins? Just like Euros or Dollars: to get money, they will have to work for the ones who already own it. <strong>We believe this is the <em>second</em> injustice.</strong> Every member of a monetary community should be equal concerning monetary creation, and get the same relative amount of money over time, <em>even if they are a late adopter</em>. Duniter aims to fix this by making the Universal Dividend (a.k.a. <em>UD</em>) <em>grow by the time</em> (S.Laborde, 2010) according to precise rules, thus making members equal toward money issuance on a half-lifespan.</p> -<h4 id="a-solution-1">A solution</h4> -<p>Bitcoin has taught us that <em>it is possible</em> to create a currency system allowing one to both create digital money and to exchange it without a central authority. What we need to change is <em>the way money is issued</em> so we finally have a symmetrical system. We need Bitcoin <em>+ Universal Dividend</em>. But Universal Dividend <em>implies</em> that the community consists of only identified people. This is where the Web of Trust (WoT) comes into place. This concept, introduced by cryptography with the <a href="https://www.wikiwand.com/en/Pretty_Good_Privacy">OpenPGP</a> format, allows us to identify people in a <em>decentralized</em> manner. It works as follows: each person creates <em>a personal identity</em> that is linked to its cyptographic certificate. The identity must be confirmed by others members who use their own cryptographic key. It is that simple: <strong>people choose who is part of the community and who is not, not a central authority.</strong></p> -<blockquote> -<p>Duniter however won't use OpenPGP for its cryptographic features: Elliptic Curves will be used instead for the conciseness of its generated keys and its pratical advantages. Duniter has its own Web of Trust principles, that shall be exposed later.</p> -</blockquote> -<h3 id="proof-of-work-mining-a-power-race-todo-1">Proof-of-Work mining : a power race (TODO)</h3> -<p>In Bitcoin Model, the calculation and incentive principles cause a power race : new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. The goal of Duniter is to make blockchain validation much less energy and hardware consuming while keeping a strong level of security. As a consequence, even low-power hardware can secure Duniter Blockchain, which leads to a better decentralization of forging operations.</p> -<h3 id="other-projects-1">Other projects ?</h3> -<h4 id="what-about-pos-1">What about PoS ?</h4> -<p>When conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead to placing power over the currency in the richests hands : this is contrary to the symmetical principles of Duniter.</p> -<p>Now that PoS is well-tested, one could try to use Duniter’s WoT to create a PoS-like algorithm with equal chances among members. But this is not our aim for now.</p> -<h4 id="what-about-directed-acyclic-graph-1">What about Directed Acyclic Graph ?</h4> -<p>The Circles project uses DAG in a basic income cryptocurrency. However, in this project, one peer cannot know the whole monetary mass and the exact number of other peers. The calculation of Universal Dividend <code>UD = c * M/N</code> seems impossible, since we know neither M nor N.</p> -<h2 id="duniters-blockchain-1">Duniters Blockchain</h2> -<!-- source : https://duniter.org/en/theoretical/ --> -<p>Duniters Blockchain follows the basic principles of Bitcoins. This is essential for synchronization between peers, as to prevent double-spend attacks. However, Duniters Blockchain will store different informations than Bitcoins.</p> -<p>The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no <em>generation transaction</em> exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either:</p> -<ul> -<li>a former transaction (as in Bitcoin)</li> -<li>a Universal Dividend (specific to Duniter).</li> -</ul> -<p>Duniters Web of Trust is also written in the Blockchain. The identity of each member gets registered much like transactinos are, with a strong link to the time reference. Thus, the Blockchain is a representation of a space-time frame of reference, where “space” are members of the WoT and “time” the basci blockchain units : the blocks. On each point of time, one can determain whick account is legitimate to create the UD, only with a blockchain analysis.</p> -<h3 id="spam-countermeasures-todo-1">Spam countermeasures (TODO)</h3> -<p>An issue of most cryptocurrency projects is to prevent the common ledger from growing too much and require lot of storage and computing power to be usable. In particular, we don’t want an attacker to be able to make the Blockchain grow too fast. Most projects implement transaction fees as a way to prevent this, making the attacker lose money. We don’t want to do this since a currency with automatic fees on transactions is no more neutral. Several countermeasuers against such spam attacks are implemented.</p> -<!-- see : https://forum.duniter.org/t/sans-frais-de-transaction-comment-resister-aux-attaques/3846/25 (implemented ?)--> -<ul> -<li>output minimal de 100*Unitbase / 1 unité -> empêche un attaquant de faire grossir la BC et les index trop vite (DUBP v12)</li> -<li>chaînage maximal des tx</li> -<li>seuils de dépense (implémentés ? en tout et par issuer ?)</li> -</ul> -<h3 id="scaling-1">Scaling</h3> -<p>Most of the time, the scaling issue rises for distributed systems that should work on a very large scale. This is not the case of Duniter, for multiple reasons :</p> -<ul> -<li>Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don’t want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT limits its size to around 16 million members.</li> -<li>Duniter’s aim is to be used to create <em>multiple</em> libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community.</li> -</ul> -<p>However, Duniter has two assets that might be used if the number of users grow.</p> -<h4 id="dynamic-block-size-1">Dynamic block size</h4> -<p>While Bitcoin has a fixed block size, Duniters blocks size can evolve. On low use of the blockchain, the maximal block size is 500 bytes. On high use of the blockchain, the maximal block size would be 110% of the average size of the current window blocks( <em>current window</em> will be described in the PoW part). This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it.</p> -<div class="{highlight}"> -<p>block_size < max(500 ; CEIL(1.10 * (average block size))</p> -</div> -<h4 id="lightning-networks-1">Lightning Networks</h4> -<p>The Lightning Networks allow almost instant and off-chain transactions. They were first implemented on Lightcoin, and are now on Bitcoin. One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. While not available yet, this payment channel might get implemented when needed.</p> -<h2 id="duniter-web-of-trust-1">Duniter Web of Trust</h2> -<!-- source : https://duniter.org/en/deep-dive-into-the-web-of-trust --> -<h3 id="basic-principles-1">Basic Principles</h3> -<p>In order to identify “members” account - which create monetary units - from other accounts, Duniter uses a Web of Trust. This can be summarized into few principles:</p> -<ul> -<li>Each account becomes a member if it received a minimal number of certifications (5 for Ğ1 currency)</li> -<li>Only members accounts can send certifications. Certifications have a limited lifespan.</li> -<li>A certification indicates that the sender accepts the receiver as a legitimate identity.</li> -</ul> -<p>The aim of the WoT is to identify a blockchain account to a living human. Each member of the Ğ1 currency signs a licence stating that they will only certify humans they know well (among other rules). Thus, if a member is part of an attack on the currency, they can be found by mutual friends. The security of Ğ1 currency stands on:</p> -<ul> -<li>Corroborating informations on members (5 certifications)</li> -<li>Peer pressure by close relatives</li> -<li>Law if the licence has not been respected.</li> -</ul> -<p>Note that non-members accounts can use the currency, but cannot create money. They can be used by individuals as secondary wallets, or by institutions.</p> -<p>However, the WoT does not rely only on trust betwenn people. Rules have been added to increase the security, and we will present them.</p> -<h3 id="why-do-we-need-a-web-of-trust-1">Why do we need a Web of Trust?</h3> -<p>There are two reasons we need it :</p> +<p>We want to make sure that each member can only have one account. As we all know, achieving zero-risk isn’t possible<a href="#fn9" class="footnote-ref" id="fnref9"><sup>9</sup></a>. Our goal is therefore not to create a WoT within which fraud would be absolutely impossible, but instead to discourage it. Here is a rewording of our goal in 4 smaller ones :</p> <ol type="1"> -<li>To make sure that only one Universal Dividend is produced per member at each specified creation interval -in the Ğ1’s case this interval is set as daily <code>86 400</code> seconds-, it is the <em>monetary parameter</em> known as <code>dt</code>-.</li> -<li><p>To identify the nodes hashing the blocks and assign them each a personalised difficulty. This custom difficulty <a href="https://en.wikipedia.org/wiki/Proof-of-work_system">proof of work</a> is there to avoid the blockchain’s validation mechanism becoming too centralised as is the case with many 'non-libre’ cryptocurrencies.</p> -<blockquote> -<p>Wait, what’s a ‘monetary parameter’ ?</p> -</blockquote></li> -</ol> -<p>Every currency implementing Duniter has its own blockchain whose behaviour is dictated by a set of ‘parameters’ -defined in block zero, the so-called genesis block- that can be tweaked to achieve the desired results. At the time of writing this article, the Duniter protocol -aka DUP- has a total of 21 parameters of which 10 are for the WoT alone. We’ll focus on these 10.</p> -<p>Suffice to say that in the Ğ1’s case, the DU is created every 24 hours -86 400 seconds- but this interval -set through the time derivative <code>dt</code> parameter- can have a different value in an other implementation of the protocol.</p> -<p>I won’t write about the second parameter having to do with the proof of work, it’s outside our scope here, just know that the Web of Trust allows us to <strong>identify</strong> the members providing hashing power, which we couldn’t do without it. This crucial feature means we can impose a rotation between the members hashing the blocks so that no single rich individual or group invests in a giant ‘hash farm’ and takes a hold of the blockchain, paralysing the community!</p> -<p>Let’s go back to the first objective: to make sure that each member can only have one account. As we all know, achieving zero-risk isn’t possible, our goal is therefore not to create a WoT within which fraud would be absolutely impossible but instead to discourage it. Here is a rewording of our goal in 4 smaller ones :</p> -<ol type="1"> -<li>To make the certification process lengthy enough that all members exercise due diligence and are wary of risks.</li> -<li>To make fraudulent acts as hard as we can to the extent that they become pointless.</li> -<li>To ensure that any Sybil attacks have a negligible impact on the currency -<em>by ensuring that illegitimate double Universal Dividends have no significant bearing on the legitimate monetary mass</em>-</li> -<li>To slow the growth of ‘Sybil regions’ to give enough time for the community to react and isolate the threat.</li> +<li>Make the certification process lengthy enough that all members exercise due diligence and are wary of risks.</li> +<li>Make fraudulent acts as hard as we can to the extent that they become pointless.</li> +<li>Ensure that any Sybil attacks have a negligible impact on the currency by ensuring that illegitimate double Universal Dividends have no significant bearing on the legitimate monetary mass</li> +<li>Slow the growth of ‘Sybil regions’ to give enough time for the community to react and isolate the threat.</li> </ol> <blockquote> -<p><strong>Wait, a Sybil what ?</strong></p> +<p><strong>Sybil attack</strong> : A Sybil attack is an attack perpetrated on a reputation system through the creation of fake identities. A Web of Trust is a specific instance of a Reputation System.</p> </blockquote> -<p>A <a href="https://en.wikipedia.org/wiki/Sybil_attack"><strong>Sybil attack</strong></a>, is the name given to attacks perpetrated on a reputation system through the creation of fake identities. A Web of Trust is a specific instance of a <a href="https://en.wikipedia.org/wiki/Reputation_system"><strong>Reputation System</strong></a>.</p> <p>There are plenty of Sybil attack scenarios we can think of and just as many reasons why their perpetrators would want to carry them out. Our objective is that the configuration of the WoT protects both users and its IT backbone infrastructure against these attacks.</p> -<p>This means that micro-attacks performed by small groups of individuals looking for personal enrichment are of no interest to us. The web’s role isn’t to deter these attacks, this being instead the role of the community. Just like the town you live in is responsible for providing your tap water and electricity but isn’t responsible for any burglaries etc. Much in the same way, Duniter’s WoT guarantees us all a functional currency and that’s quite a feat in itself!</p> -<h3 id="the-importance-of-having-our-own-certification-system-1">The importance of having our own certification system</h3> -<p>We are regularly offered to switch over to third-party or state-owned authentication systems but these are centralised and go against the principles of our community. We feel that we would lose our independence and universality by adopting a state-controlled system. People without an official state-provided identity or homeless people would also run the risk of being excluded from the WoT. It is of the utmost importance that we remain free from any state or corporation. To this day we depend only on the Internet and yet, were it to fail, there are already alternatives being tested around the world for a decentralised network.</p> -<h3 id="a-few-foundational-concepts-on-graph-theory-a-bit-of-vocabulary-1">A few foundational concepts on graph theory : a bit of vocabulary</h3> +<p>This means that micro-attacks performed by small groups of individuals looking for personal enrichment are of no interest to us. The web’s role isn’t to deter these attacks, this being instead the role of the community. Just like the town you live in is responsible for providing your tap water and electricity but isn’t responsible for any burglaries, etc. Much in the same way, Duniter’s WoT guarantees us all a functional currency, but do not detect small fraud.</p> +<h3 id="own-certification-system">3.3. The importance of having our own certification system</h3> +<p>Centralized identification systems can achieve the goal we want. State Identification is an example. However, this has many drawbacks :</p> +<ul> +<li>The authority may have arbitrary criteria for identification, for example preventing people without an official state-provided identity or homeless people to be included in the WoT.</li> +<li>Payment might be required to get identified, thus making the monetary creation not “free”.</li> +<li>The authority is a point of failure for any attacker.</li> +</ul> +<p>It is of the utmost importance that we remain free from any state or corporation. The WoT is an answer to this criterium. To this day we depend only on the Internet and yet, were it to fail, there are already alternatives being tested around the world for a decentralised communication network.</p> +<h3 id="graph-theory-vocabulary">3.4. A few foundational concepts on graph theory : a bit of vocabulary</h3> <ul> <li><p><strong>Graph</strong>: set of points -called ‘vertices’- joined by edges -called paths/walks-.</p></li> -<li><p><strong>Simple graph</strong>: a graph with no loops and with no multiple edges. That is, each edge connects two distinct endpoints and no two edges have the same endpoints. A simple edge is an edge that is not part of a multiple adjacency -of edges-. In many cases, graphs are assumed to be simple unless specified otherwise. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a></p></li> -<li><p><strong>Directed graph</strong>: a graph in which the edges have a distinguished direction, from one vertex to another. A directed edge can also be called a path or walk. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a> Arrow A –> B is therefore different from arrow B –> A.</p></li> +<li><p><strong>Simple graph</strong>: a graph with no loops and with no multiple edges. That is, each edge connects two distinct endpoints and no two edges have the same endpoints. A simple edge is an edge that is not part of a multiple adjacency -of edges-. In many cases, graphs are assumed to be simple unless specified otherwise.</p></li> +<li><p><strong>Directed graph</strong>: a graph in which the edges have a distinguished direction, from one vertex to another. A directed edge can also be called a path or walk. Arrow A –> B is therefore different from arrow B –> A.</p></li> <li><p><strong>Endpoints</strong>: the edge with vertex A –> B has A and B as endpoints, respectively as start and end of the path/walk.</p></li> -<li><p><strong>Isolated vertex</strong>: a vertex whose degree is zero, that is, a vertex with no incident edges. <a href="https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms">Wikipedia</a></p></li> +<li><p><strong>Isolated vertex</strong>: a vertex whose degree is zero, that is, a vertex with no incident edges.</p></li> <li><p><strong>Degree of a vertex</strong>: number of its incident edges -in and out-.</p></li> <li><p><strong>Out-degree of vertex A</strong>: number of outbound edges / tail ends from A.</p></li> <li><p><strong>In-degree of vertex A</strong>: number of incoming edges / head ends to A.</p></li> </ul> <figure> -<img src="https://duniter.org/en/images/wiki/degrees.jpg" alt="degress of a vertex diagram" /><figcaption>degress of a vertex diagram</figcaption> +<img src="./images/degres.jpg" alt="degrees of a vertex diagram" /><figcaption>degrees of a vertex diagram</figcaption> </figure> <ul> <li><strong>Path</strong>: -aka “walk”- path to follow to get from vertex A to vertex B.</li> </ul> -<h3 id="definition-of-the-duniter-web-of-trust-1">Definition of the Duniter Web of Trust</h3> +<h3 id="definition-of-the-duniter-web-of-trust">3.5. Definition of the Duniter Web of Trust</h3> <p>The Duniter WoTs -one per currency- are simple directed graphs without isolated vertices. The vertices are the members and the edges are the certifications given and received.</p> -<p>Directed, what does that mean?</p> -<p>The responsibility of issuing a certification is unique and personal to the certifier. The trust he/she places in the receiver cannot be imposed in the other direction although in most circumstances both parties equally trust each other.</p> -<p>In addition, all vertices are either currently active members or past-members. Past-member vertices are in a specific ‘deactivated state’ and can no longer issue or receive certifications although the ones already issued or received to/from other members are still considered ‘pending’ to avoid the web collapsing like a house of cards.</p> -<p>If these old members don’t come back into the web, their pending certifications will eventually expire and they will switch from ‘deactivated’ to ‘isolated’ vertices.</p> -<p>To wrap up with old members, after a certain period of time -set in the currency’s parameters - their deactivated vertex is removed from the web and the associated identity is ‘revoked’. The person who owned the account can no longer use this identity but is free to join the web with another one. :-)</p> +<p><em>Directed</em> means that the responsibility of issuing a certification is unique and personal to the certifier. The trust they place in the receiver cannot be imposed in the other direction although in most circumstances both parties equally trust each other.</p> +<p>In addition, all vertices are either currently active members or past-members. Past-member vertices are in a specific ‘deactivated state’ and can no longer issue or receive certifications although the ones already issued or received to/from other members are still considered ‘pending’ to avoid a collapse of the WoT. If these old members don’t come back into the WoT, their pending certifications will eventually expire and they will switch from ‘deactivated’ to ‘isolated’ vertices.</p> +<p>To wrap up with old members, after a certain period of time - set in the currency’s parameters - their deactivated vertex is removed from the web and the associated identity is ‘revoked’. The person who owned the account can no longer use this identity but is free to join the web with another one.</p> <blockquote> -<p>What do you mean by ‘identity’?</p> -</blockquote> -<p>An identity is a set of three pieces of information: a public key, a name and a blockstamp. A blockstamp points to a specific block in the chain. Its main use is to freeze the point in time at which an identity was created and to link this identity to a specific chain and of course, a currency -each currency having its own blockchain-.</p> +<p><strong>Identity</strong> : An identity is a set of three pieces of information: a public key, a name and a blockstamp. A blockstamp points to a specific block in the chain. Its main use is to freeze the point in time at which an identity was created and to link this identity to a specific chain and a currency - each currency having its own blockchain.</p> <p>An identity can be in any one of 5 different status: pending, member, old member, revoked or excluded.</p> +</blockquote> <p>Let’s take a simple example:</p> -<div class="highlight"> -<pre><code>A -> B -> C - | - \--> D</code></pre> -</div> +<pre><code> A -> B -> C + | + \--> D</code></pre> <p>If, for whatever reason, A were to lose its member status, the web would crumble and all other members would be excluded as a consequence. To avoid this, the certification from A –> B will remain valid until its expiry date, leaving enough time for B to receive certifications from C or D.</p> -<p>Because our WoT doesn’t have any isolated vertices, each new identity created needs to be pulled into the web with all of the certifications it has received -in the same block-. This calls for a temporary ‘buffer’ storage space for <strong>pending</strong> identities and the certifications they’ve received. This storage space is called ‘the pool’ -of Duniter nodes- which we could also have called the ‘sandbox’ as that’s the name used in Duniter’s code. I might add that these ‘pools’ also include other documents and metadata not mentioned here.</p> -<h3 id="exploring-the-rules-behind-a-duniter-web-of-trust-1">Exploring the rules behind a Duniter Web of Trust</h3> -<p>The Duniter WoTs -one per currency- work with a set of eight fundamental rules, themselves enforced through eleven different parameters. Ten of these parameters are set within the genesis block, the eleventh one - <code>msPeriod</code>- having being hard-coded in the Ğ1’s code subsequently.</p> -<h4 id="distance-rule-and-referent-members-stepmax-and-xpercent-1distance-rule-and-referent-members-stepmax-and-xpercent-1">1.Distance rule and referent members (<code>stepMax</code> and <code>xPercent</code>) {#1distance-rule-and-referent-members-stepmax-and-xpercent}</h4> +<p>Because our WoT doesn’t have any isolated vertices, each new identity created needs to be pulled into the web with all of the certifications it has received, all in the same block. This calls for a temporary ‘buffer’ storage space for <strong>pending</strong> identities and the certifications they have received. This storage space is called ‘the pool’ of Duniter nodes, which we could also have called the ‘sandbox’ as that’s the name used in Duniter’s code. Duniter nodes inclued other ‘pools’ for other documents and metadata not mentioned here.</p> +<h3 id="exploring-the-rules-behind-duniter-wot">3.6. Exploring the rules behind a Duniter Web of Trust</h3> +<p>The Duniter WoTs - one per currency - works with a set of eight fundamental rules enforced through eleven different parameters. Ten of these parameters are set within the genesis block, the eleventh one - <code>msPeriod</code>- having being hard-coded in the Ğ1’s code subsequently.</p> +<h4 id="distance-rule-and-referent-members-stepmax-and-xpercent">3.6.1. Distance rule and referent members (<code>stepMax</code> and <code>xPercent</code>)</h4> <p>These two parameters are closely linked and together define the ‘distance rule’. The ‘distance rule’ can only be described after defining what a ‘referent member’ is:</p> <blockquote> -<p><strong>Referent member</strong>: member A is said to be ‘referent’ if and only if the total of his/her degrees are greater than or equal to <code>CEIl-N^-1/stepMax--</code> where N is the total number of members.** As the size of the web will grow this number will grow too, meaning it will take more certification issuances to become a referent member as the number of certifications needed to become a member shouldn’t change.</p> +<p><strong>Referent member</strong>: member A is said to be ‘referent’ if and only if the total of their degrees are greater than or equal to <code>CEIL-N^-1/stepMax</code> where N is the total number of members. As the size of the web will grow this number will grow too, meaning it will take more certification issuances to become a referent member. The number of certifications needed to become a member shouldn’t change.</p> </blockquote> <p>Let’s now define the distance rule:</p> <blockquote> -<p><strong>Distance rule</strong>: member A is said to observe this rule if and only if for a subset xPercent % of referent members R there exists a path of length less than or equal to <code>stepMax</code> between R and A.**</p> -</blockquote> -<p>Referent members only exist so that the distance rule can take effect, they have no special privileges over non-referent members. In a perfect web, that is one in which each member has certified all members he/she legitimately can, all members would be referent members. However, because the web progressively grows in size and because members die and are replaced by new ones, there are always members at any given time <code>t</code> who haven’t yet certified all members they legitimately could. These members would hinder the evolution of the web if they were taken into account in the calculation of the distance rule and the web would effectively stop growing. -You can see what would happen if the notion of ‘referent member’ didn’t exist by going to the ‘gaussianWotQuality’ page on <a href="https://g1-monit.librelois.fr/gaussianWotQuality?lg=en&unit=quality">currency-monit</a> and activating ‘if the concept of referent members didn’t exist’-.</p> -<blockquote> -<p><strong>When is the distance rule applied?</strong></p> +<p><strong>Distance rule</strong>: member A is said to observe this rule if and only if for a subset xPercent % of referent members R there exists a path of length less than or equal to <code>stepMax</code> between R and A.</p> </blockquote> -<p>Because verifying the application of the distance rule is calculation-greedy, it is only performed when a new identity gets confirmed into the web or an existing member gets renewed. <em>Exception to the rule: the distance rule is not observed in the genesis block -when the web is first implemented-.</em></p> -<h4 id="rule-of-the-minimum-number-of-certifications-needed-sigqty-2-rule-of-the-minimum-number-of-certifications-needed-sigqty-1">2. Rule of the minimum number of certifications needed (<code>sigQty</code>) {#2-rule-of-the-minimum-number-of-certifications-needed-sigqty}</h4> -<p>This is the simplest rule, it essentially says that each member must at any given time -meaning in any single block- have received at least <code>sigQty</code> active certifications. If, for whatever reason, member A were to have less than <code>sigQty</code> active certifications in a given block, he/she would cease being a member and be required to publish a request for identity renewal.</p> -<h4 id="the-membership-renewal-rule-msvalidity-msperiod-and-mswindow-3-the-membership-renewal-rule-msvalidity-msperiod-and-mswindow-1">3. The membership renewal rule (<code>msValidity</code>, <code>msPeriod</code> and <code>msWindow</code>) {#3-the-membership-renewal-rule-msvalidity-msperiod-and-mswindow}</h4> +<p>Referent members only exist so that the distance rule can take effect, they have no special privileges over non-referent members. In a perfect web, that is one in which each member has certified all members they legitimately can, all members would be referent members. However, because the web progressively grows in size and because members die and are replaced by new ones, there are always members at any given time <code>t</code> who haven’t yet certified all members they legitimately could. These members would hinder the evolution of the web if they were taken into account in the calculation of the distance rule and the web would effectively stop growing.</p> +<p>Because verifying the application of the distance rule is calculation-greedy, it is only performed when a new identity gets confirmed into the web or an existing member gets renewed. There is an exception to this rule: the distance rule is not observed in the genesis block -when the web is first implemented.</p> +<h4 id="rule-of-the-minimum-number-of-certifications-needed-sigqty">3.6.2. Rule of the minimum number of certifications needed (<code>sigQty</code>)</h4> +<p>This is the simplest rule, it essentially says that each member must at any given time -meaning in any single block- have received at least <code>sigQty</code> active certifications. If, for whatever reason, member A were to have less than <code>sigQty</code> active certifications in a given block, they would cease to be a member and be required to publish a request for identity renewal.</p> +<h4 id="the-membership-renewal-rule-msvalidity-msperiod-and-mswindow">3.6.3. The membership renewal rule (<code>msValidity</code>, <code>msPeriod</code> and <code>msWindow</code>)</h4> <p>Bear in mind that a membership doesn’t last a lifetime but instead has a lifespan set to <code>msValidity</code> seconds.</p> -<p>Every single member -or old member who hasn’t revoked his identity or been excluded- can request a membership renewal so long as the last request was made more than <code>msPeriod</code> seconds ago -if a member has never requested a renewal, the date of last renewal is equal to the timestamp at which his membership was first created. A new request will be stored in the ‘pool’ for a maximum of <code>msWindow</code> seconds before it’s included in the blockchain. Once again, this can only happen once/if the member meets both the <code>siqQty</code> rule and the distance rule -if these criterion are already matched it’s just a case of waiting for a new block to be mined-.</p> -<p>If a member hasn’t requested a renewal for longer than <code>msValidity</code> seconds, he/she automatically ceases being a member. From this moment on, the ex-member has another <code>msValidity</code> window to renew his/her membership. When this period of `2 × msValidity’ runs out, the membership will expire and this identity will never be available for use again in the web. If the person so desires, he/she will have to start from zero to regain access to the WoT.</p> -<h4 id="rule-of-certification-lifespan-sigvalidity-4-rule-of-certification-lifespan-sigvalidity-1">4. Rule of certification lifespan (<code>sigValidity</code>) {#4-rule-of-certification-lifespan-sigvalidity}</h4> +<p>Every single member -or old member who hasn’t revoked his identity or been excluded- can request a membership renewal so long as the last request was made more than <code>msPeriod</code> seconds ago. If a member has never requested a renewal, the date of last renewal is equal to the timestamp at which his membership was first created. A new request will be stored in the ‘pool’ for a maximum of <code>msWindow</code> seconds before it’s included in the blockchain. Once again, this can only happen once/if the member meets both the <code>siqQty</code> rule and the distance rule -if these criterion are already matched it’s just a case of waiting for a new block to be mined-.</p> +<p>If a member hasn’t requested a renewal for longer than <code>msValidity</code> seconds, they automatically cease to be a member. From this moment on, the ex-member has another <code>msValidity</code> window to renew their membership. When this period of <code>2 × msValidity</code> runs out, the membership will expire and this identity will never be available for use again in the web. If the person so desires, they will have to publish new identity and membership documents and find enough certifiers, as any newcomer.</p> +<h4 id="rule-of-certification-lifespan-sigvalidity">3.6.4. Rule of certification lifespan (<code>sigValidity</code>)</h4> <p>All certifications included in the blockchain expire <strong>sigValidity</strong> seconds after they were <strong>issued</strong>.</p> +<blockquote> <p>/!\ The issuance and the inclusion of a certification in the blockchain occur at different times. When member A issues a certification at time t1, it gets stored in the pool starting at t1 and only finds its way into the blockchain at t2 when all of the web’s rules are observed. Several weeks can thus go by between t1 and t2!!!</p> -<h4 id="rule-of-limited-supply-of-active-certifications-sigstock-5-rule-of-limited-supply-of-active-certifications-sigstock-1">5. Rule of limited supply of active certifications (<code>sigStock</code>) {#5-rule-of-limited-supply-of-active-certifications-sigstock}</h4> +</blockquote> +<h4 id="rule-of-limited-supply-of-active-certifications-sigstock">3.6.5. Rule of limited supply of active certifications (<code>sigStock</code>)</h4> <p>By ‘active certifications’ we refer to certifications included in the blockchain and that haven’t yet expired.</p> <p>The total of active certifications issued by any member at any single time must be less than or equal to <code>sigStock</code>. When this threshold is reached the member will have to wait for one of his active certifications to expire before he/she can issue a new one.</p> -<h4 id="rule-of-the-time-period-between-two-certification-issuances.-sigperiod-6-rule-of-the-time-period-between-two-certification-issuances-sigperiod-1">6. Rule of the time period between two certification issuances. (<code>sigPeriod</code>) {#6-rule-of-the-time-period-between-two-certification-issuances-sigperiod}</h4> -<p>As soon as a certification issued by member A gets included in the blockchain, he/she will be unable to issue a new one before another <code>sigPeriod</code> seconds.</p> -<h4 id="expiry-of-a-certification-issuance-sigwindow-7-expiry-of-a-certification-issuance-sigwindow-1">7. Expiry of a certification issuance (<code>sigWindow</code>) {#7-expiry-of-a-certification-issuance-sigwindow}</h4> +<h4 id="rule-of-the-time-period-between-two-certification-issuances-sigperiod">3.6.6. Rule of the time period between two certification issuances. (<code>sigPeriod</code>)</h4> +<p>As soon as a certification issued by member A gets included in the blockchain, they will be unable to issue a new one before another <code>sigPeriod</code> seconds.</p> +<h4 id="expiry-of-a-certification-issuance-sigwindow">3.6.7. Expiry of a certification issuance (<code>sigWindow</code>)</h4> <p>When a certification is issued by member A, it will be stored in the ‘pool’ for a maximum of <code>sigWindow</code> seconds. If the certification hasn’t been included in the blockchain by then, it will be cancelled and the member’s <code>sigStock</code> will be repleted by one.</p> -<h4 id="lifespan-of-a-pending-active-certification-idtywindow-8-lifespan-of-a-pending-active-certification-idtywindow-1">8. Lifespan of a ‘pending’ active certification (<code>idtyWindow</code>) {#8-lifespan-of-a-pending-active-certification-idtywindow}</h4> +<h4 id="lifespan-of-a-pending-identity-idtywindow">3.6.8. Lifespan of a ‘pending’ identity (<code>idtyWindow</code>)</h4> <p>When a new identity is created, it is stored in the ‘pool’ for a maximum of <code>idtyWindow</code> seconds. If the person hasn’t achieved member status by then, the certification will simply be cancelled.</p> -<h3 id="details-on-some-of-the-wots-peculiarities-at-the-genesis-block">Details on some of the WoT’s peculiarities at the genesis block.</h3> +<h3 id="details-on-some-of-the-wots-peculiarities-at-the-genesis-block">3.7. Details on some of the WoT’s peculiarities at the genesis block</h3> <p>The aforementioned rules can only be enforced with an existing web. They cannot be observed when first creating the web, that is when defining the genesis block.</p> <p>Only rules 2 and 5 can be observed at the genesis block.</p> -<p>The genesis block has to be manually created by the founding members. In practice this means that there must be a choice of which identities to include on the premise that all of them observe rules 2 and 5. In addition, the genesis block must be signed with the private key of one of these identities.</p> -<p>As soon as the genesis block has been created, the other identities can start mining the blockchain and the member who begat block #0 effectively looses the decision power he had at creation.</p> -<h3 id="why-these-rules-and-application-cases-in-the-g1">Why these rules and application cases in the Ğ1</h3> -<h4 id="distance-and-maximum-size-1-distance-and-maximum-size-1">1. Distance and maximum size {#1-distance-and-maximum-size}</h4> +<p>The genesis block has to be manually created by the founding members. In practice this means that there must be a choice on which identities to include on the premise that all of them observe rules 2 and 5. In addition, the genesis block must be signed with the private key of one of these identities.</p> +<p>As soon as the genesis block has been created, the other identities can start mining the blockchain and the member who created block #0 effectively looses the decision power he had at creation.</p> +<h3 id="why-these-rules-and-application-cases-in-the-g1">3.8. Why these rules and application cases in the Ğ1</h3> +<h4 id="distance-and-maximum-size">3.8.1. Distance and maximum size</h4> <p>The distance rule is there to curb the maximum size of a Sybil region as well as that of the monetary community as a whole. The <code>xpercent</code> parameter prevents the creation of a ‘faction’ that could take hold of the blockchain.</p> <figure> -<img src="https://duniter.org/en/images/wiki/wot-sybil.jpg" alt="Sybil region" /><figcaption>Sybil region</figcaption> +<img src="./images/wot-sybil.jpg" alt="Sybil region" /><figcaption>Sybil region</figcaption> </figure> -<p>The Sybil regions are isolated from the rest of the graph in the sense that they can only receive certifications from other ill-intentioned Sybil members. As a consequence, the shortest edge/path between a legitimate member and a Sybil one has to have the attack’s author as an endpoint. The maximum depth the Sybil region can attain is therefore contingent on the distance between the attacking edge-s- and the xpercent% closest referent members, this distance is known as <code>stepAttackers</code>. The maximum size of a Sybil region created by <code>sigQty</code> members depends on the L parameter, defined as L = sigQty/sigStock:</p> -<div class="highlight"> -<pre><code>Maximum Sybil region size = (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L)</code></pre> -</div> +<p>The Sybil regions are isolated from the rest of the graph in the sense that they can only receive certifications from other ill-intentioned Sybil members. As a consequence, the shortest edge/path between a legitimate member and a Sybil one has to have the attack’s author as an endpoint. The maximum depth the Sybil region can attain is therefore contingent on the distance between the attacking edge-s- and the xpercent% closest referent members, this distance is known as <code>stepAttackers</code>. The maximum size of a Sybil region created by <code>sigQty</code> members depends on the L parameter, defined as <code>L = sigQty/sigStock</code>:</p> +<pre><code>MaxSybilSize= (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L)</code></pre> <p>The maximum size of the Web of Trust is given by the following formula:</p> -<div class="highlight"> <pre><code>WoTmax = (sigStock)*L^(stepMax-1)</code></pre> -</div> -<p>However we know for a fact that members will never use all of their available certifications. Many studies have proven that we all know a maximum average of fifty people, let’s then replace sigStock by fifty:</p> -<div class="highlight"> +<p>However we know for a fact that members will never use all of their available certifications. According to Dunbar<a href="#fn10" class="footnote-ref" id="fnref10"><sup>10</sup></a>, on average, one is able to maintain relationships to around 150 people. Being conservative, we will consider that on average, each person will certify 50 accounts. We can calculate the size of the average web of trust <code>WoTavg</code> :</p> <pre><code>WoTavg= (50)*(sigQty/50)^(stepMax-1)</code></pre> -</div> -<p>Our goal with the Ğ1 is to create a community of about one million members enjoying the world’s first true <a href="https://en.wikipedia.org/wiki/Catallaxy">catallaxy</a> -free economy with a spontaneous order of things-. Let’s see how we can tweak the pair of sigQty and stepMax- to reach this size:</p> +<p>Our goal with the Ğ1 is to create a community of about one million members to test the consequences of a libre monetary system. Let’s see how we can tweak the pair of sigQty and stepMax- to reach this size:</p> <figure> -<img src="https://duniter.org/en/images/wiki/graph-WoTmoy.png" alt="graphe WoTmoy en fonction de sigQty et stepMax" /><figcaption>graphe WoTmoy en fonction de sigQty et stepMax</figcaption> +<img src="./images/wot-moy.png" alt="Average WoT size graph as a function of sigQty and stepMax" /><figcaption>Average WoT size graph as a function of sigQty and stepMax</figcaption> </figure> <p>The maximum size of a Sybil region grows linearly with <code>sigQty</code> but exponentially with <code>stepMax</code>. Logic has it that we need to keep <code>stepMax</code> as low as possible to ensure sufficient strength to the web. The above graph shows that the lowest value of <code>stepMax</code> for a web of a million members is of 5. This is an order of magnitude and is likely to be much higher in reality, we cannot measure it for sure.</p> <p>For <code>sigQty</code> we can choose a value of <strong>4</strong> for a web of <strong>1.5 million members</strong> or <strong>5</strong> for <strong>half a million members</strong>. Bear in mind these are gross figures and could be significantly higher, we are talking anywhere between 1 and 10 million in reality. Calculating WOTavg gives us a pretty good idea of how the web would scale bearing in mind that it considers all members are referent members too -which isn’t the case as explained previously-. Hence the maximum size of the web is likely larger, a ballpark figure of half a million is enough for now especially knowing that the smaller <code>sigQty</code> is, the easier it is to launch a Sybil attack -it’s easier to find four accomplices than five-. For security reasons we have settled on five:</p> -<p>stepMax = 5 sigQty = 5 sigStock >= 50</p> -<p>The maximum size of a Sybil region therefore is: <code>(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5))</code></p> -<p>with sigStock = 50 we have a Sybil region of: <code>45*(1-10^(5-stepAttackers))/(-9)</code></p> +<pre><code>stepMax = 5 +sigQty = 5 +sigStock \>= 50</code></pre> +<p>The maximum size of a Sybil region therefore is:</p> +<pre><code>(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5))</code></pre> +<p>with sigStock = 50 we have a Sybil region of:</p> +<pre><code>45*(1-10^(5-stepAttackers))/(-9)</code></pre> <p>A good practice for protecting the web is to maximise <code>stepAttackers</code>. That’s why we decided that referent members in the genesis block had to be at least four steps away from each other.</p> <p>Another way to keep a Sybil attack at bay, were it slow enough for members to notice it, would be for referent members to ‘stretch’ the web intentionally to limit the growth of the region by ensuring that the attackers’ legitimate certifications received in the first place aren’t renewed. But what if bot accounts were created and certified each other super fast and following all rules, how would we counter that? By introducing a minimum length of time between two certifications!</p> -<h4 id="time-is-our-friend-2-time-is-our-friend-1">2. Time is our friend {#2-time-is-our-friend}</h4> +<h4 id="time-is-our-friend">3.8.2. Time is our friend</h4> <p>To help us deter a Sybil attack, we’ve decided to impose a minimum period of time between any two certifications issued from a single account. This parameter called <code>sigPeriod</code> affords us a greater chance to detect the formation of a ‘hostile’ faction.</p> -<p>Here is a graph showing the evolution of a Sybil region with the variation of <code>sigPeriod</code>:</p> +<p>Here is a graph showing the evolution of a Sybil region with the variation of <code>sigPeriod</code>. The simulation considers that honest members and attackers both issue a certification each <code>sigPeriod</code> interval, in days:</p> <figure> -<img src="https://duniter.org/en/images/wiki/impact_sig_period.png" alt="graph of the WoT's size according to sigPeriod and stepAttackers" /><figcaption>graph of the WoT's size according to sigPeriod and stepAttackers</figcaption> +<img src="./images/impact_sig_period.png" alt="size of the WoT according to sigPeriod and stepAttackers" /><figcaption>size of the WoT according to sigPeriod and stepAttackers</figcaption> </figure> -<p>As you’ll easily be able to tell, there is a strong link between the growth speed of the region and <code>sigPeriod</code>. As evidenced here, we need a <code>sigPeriod</code> high enough in order to ensure that the legitimate web can grow at least as fast as a Sybil region. In addition, the higher <code>sigPeriod</code> is, the more members will exercise their certification power gingerly, the action coming at a higher ‘cost’.</p> +<p>As we see, there is a strong link between the growth speed of the region and <code>sigPeriod</code>. As evidenced here, we need a <code>sigPeriod</code> high enough in order to ensure that the legitimate web can grow at least as fast as a Sybil region. In addition, the higher <code>sigPeriod</code> is, the more members will exercise their certification power gingerly, the action coming at a higher ‘cost’.</p> <p>There are numerous advantages to giving <code>sigPeriod</code> a high value and no technical barriers to it, hence our choice of five days.</p> -<p>We could have also gone for days days -one week- for the sake of simplicity however there was an underlying idea behind our choice which was quite simply the pace of today’s life. Certifying someone can be a lengthy process as one needs to make sure he/she is correctly applying the Ğ1 licence and people nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea to allow one to certify at the end of every working week -five days- instead of a whole calendar one.</p> -<h4 id="trust-me-now-trust-me-forever-sigvalidity-msvalidity-3-trust-me-now-trust-me-forever-sigvalidity-msvalidity-1">3. Trust me now, trust me forever? (<code>sigValidity</code>, <code>msValidity</code>) {#3-trust-me-now-trust-me-forever-sigvalidity-msvalidity}</h4> +<p>We could have also gone for one week for the sake of simplicity. However there is an underlying idea behind our choice which was quite simply the pace of today’s life. Certifying someone can be a lengthy process as one needs to make sure they are correctly applying the Ğ1 licence and people nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea to allow one to certify at the end of every working week -five days- instead of a whole calendar one.</p> +<h4 id="trust-me-now-trust-me-forever-sigvalidity-msvalidity">3.8.3. Trust me now, trust me forever ? (<code>sigValidity</code>, <code>msValidity</code>)</h4> <p>There would be two main drawbacks to a lifetime membership in the Ğ1’s Web of Trust:</p> -<blockquote> -<p>First of all we need to take into account that some members will pass and those accounts should no longer produce the Universal Dividend. Secondly it is of the utmost importance that ‘rogue’ accounts can be excluded from the web at some point.</p> -</blockquote> -<p>To achieve this, certifications have a limited lifetime and members need to seek renewal from their peers after <code>sigValidity</code> time. On the other hand, this time can’t be too short that members would spend more time seeking renewal than they would exchanging in the currency. Furthermore, a certification with too short a lifetime would foster careless certifying behaviours. The act of certifying must have a ‘perceived’ cost high-enough to make it feel like an important act. Lastly, we also wanted this lifetime to be easy enough to remember. Historically speaking, we first settled on the values of <code>sigPeriod</code> and <code>sigStock</code>, meant one could issue all of his/her certifications in 495 days, one year was therefore not long enough. We deemed three years to bee much and that’s how we agreed on two years in the end.</p> -<p>Thinking that a deceased member could continue producing the UD for two long years without anyone benefitting from it was also something we needed to address. We choose a value of one year for <strong>msValidity</strong>. The act of renewing every year is done through one of the clients interacting with the blockchain, through a simple click on a button. This parameter is less important than others and is mostly there to ‘prune’ the web of past or inactive members who don’t renew their membership.</p> -<h4 id="keeping-the-pools-free-of-information-glut--idtywindow-sigwindow-mswindow-4-keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow-1">4. Keeping the pools free of information glut -(<code>idtyWindow</code>, <code>sigWindow</code>, <code>msWindow</code>) {#4-keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow}</h4> +<ul> +<li>First of all, some members will pass and those accounts should no longer produce the Universal Dividend.</li> +<li>Secondly it is of the utmost importance that ‘rogue’ accounts can be excluded from the web at some point.</li> +</ul> +<p>To achieve this, certifications have a limited lifespan. Members need to seek renewal from their peers after <code>sigValidity</code> time. On the other hand, this time can’t be too short that members would spend more time seeking renewal than they would exchanging in the currency. Furthermore, a certification with too short a lifespan would foster careless certifying behaviours. The act of certifying must have a high-enough ‘perceived’ cost to make it feel like an important act. Lastly, we also wanted this lifespan to be easy to remember. Historically speaking, we first settled on the values of <code>sigPeriod</code> and <code>sigStock</code>, meant one could issue all of their certifications in 495 days, one year was therefore not long enough. We deemed three years to be too much and that’s how we agreed on two years in the end.</p> +<p>Thinking that a deceased member could continue producing the UD for two long years without anyone benefitting from it was also something we needed to address. We chose a value of one year for <strong>msValidity</strong>. The act of renewing every year is done through one of the clients interacting with the blockchain, through a simple click on a button. This parameter is less important than others and is mostly there to ‘prune’ the web of past or inactive members who don’t renew their membership.</p> +<h4 id="keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow">3.8.4. Keeping the pools free of information glut (<code>idtyWindow</code>, <code>sigWindow</code>, <code>msWindow</code>)</h4> <p>The pools need to be cleaned up on a regular basis to avoid them clogging up with information and to ensure that machines with less calculating power can still run a Duniter node.</p> <p>To achieve this, identities with pending membership approval and the corresponding certifications have to remain the shortest time possible in the pool while still having a chance of making it into the blockchain.</p> <p>For the Ğ1, our opinion was that two months would be enough for all potential certifiers to agree on a specific identity to certify. We also wanted a time period that would be easy enough to remember by all. We settled on two months, and gave this value to all three parameters <code>idtyWindow</code>, <code>sigWindow</code> and <code>msWindow</code>.</p> -<h4 id="avoiding-single-members-from-knowing-too-many-people-sigstock-5-avoiding-single-members-from-knowing-too-many-people-sigstock-1">5. Avoiding single members from ‘knowing too many people’ (<code>sigStock</code>) {#5-avoiding-single-members-from-knowing-too-many-people-sigstock}</h4> -<p>Many sociology studies have shown that we all know an average of fifty people. This of course is an average, some of us know more than fifty people, others much less. Once again we went for a number that would be easy to remember. Although <code>sigStock</code>’s impact on the size of a Sybil region is fairly limited, its value nonetheless has to be kept reasonable. We settled on hundred.</p> -<h4 id="avoiding-locking-minorities-xpercent-6-avoiding-locking-minorities-xpercent-1">6. Avoiding locking minorities (<code>xpercent</code>) {#6-avoiding-locking-minorities-xpercent}</h4> +<h4 id="avoiding-single-members-from-knowing-too-many-people-sigstock">3.8.5. Avoiding single members from ‘knowing too many people’ (<code>sigStock</code>)</h4> +<p>We considered that on average, each person will certify 50 people. However, we know for a fact that some members will use more than 50 certifications. The maximum social network of one individual is around 150 people<a href="#fn11" class="footnote-ref" id="fnref11"><sup>11</sup></a>. Being conservative, we settled on a maximum certification number <code>sigstock</code> of 100. Since <code>sigStock</code>’s impact on the size of a Sybil region is fairly limited, we did not investigate further this parameter.</p> +<h4 id="avoiding-locking-minorities-xpercent">3.8.6. Avoiding locking minorities (<code>xpercent</code>)</h4> <p>It’s easy enough to become a referent member, one of the Sybil strategies could therefore be to create a region of referent members. Such a region would grow slower than otherwise but could confer a locking power to its members by using the distance rule. That’s why the distance rule cannot be calculated on 100% of the referent members. Hence the introduction of the <code>xpercent</code> parameter which defines the percentage of referent members needing to be less than five edges -steps- from each other.</p> -<p>This percentage needs to be low enough to prevent the formation of a locking minority -referent Sybil members being too far from legitimate referent members-. On the other hand, it needs to be high enough so as to restrict the maximum size of the Sybil region through the distance rule. The <code>xpercent</code> parameter was one of the hardest to define, we therefore reserve ourselves the right of modifying its value during the Ğ1 experiment.</p> -<p>We were inspired by the <a href="https://en.wikipedia.org/wiki/Pareto_principle">Pareto principle</a>: if at least 20% of members give good density to the web, 80% of the referent members will be five or less steps from any other member -referent or non-. The maximum value for <code>xpercent</code> is therefore 80%, anything above that and the distance rule could be too restrictive for legitimate use cases. With security our top concern, we chose the maximum value of 80%.</p> -<h4 id="spam-protection-with-msperiod-7-spam-protection-with-msperiod-1">7. Spam protection with (<code>msPeriod</code>) {#7-spam-protection-with-msperiod}</h4> +<p>This percentage needs to be low enough to prevent the formation of a locking minority -referent Sybil members being too far from legitimate referent members-. On the other hand, it needs to be high enough so as to restrict the maximum size of the Sybil region through the distance rule. The <code>xpercent</code> parameter was one of the hardest to define, therefore we might decide to change its value during the Ğ1 experiment.</p> +<p>We were inspired by the Pareto principle<a href="#fn12" class="footnote-ref" id="fnref12"><sup>12</sup></a>: if at least 20% of members give good density to the web, 80% of the referent members will be five or less steps from any other member -referent or not-. The maximum value for <code>xpercent</code> is therefore 80%, anything above that and the distance rule could be too restrictive for legitimate use cases. With security our top concern, we chose the maximum value of 80%.</p> +<h4 id="spam-protection-with-msperiod">3.8.7. Spam protection with (<code>msPeriod</code>)</h4> <p>This parameter stands out a bit on its own, as it was added after the genesis block. It is there to protect the Duniter P2P infrastructure against ‘spam’ attacks. We had to think of a strategy against attacks such as high-frequency membership renewal requests -i.e: in every block, every five minutes- or worse still, hundreds of these requests per minute to flood the Duniter nodes. Without such limits, nodes are supposed to address all renewal requests, even in cases where they were last published five minutes ago! The <code>msPeriod</code> parameter was given the same value as <code>idtyWindow</code>, <code>sigWindow</code> and <code>msWindow</code>, i.e. two months.</p> -<h2 id="proof-of-work-with-personal-difficulty-1">Proof of Work with personal difficulty</h2> +<h2 id="proof-of-work-with-personalized-difficulty">4. Proof of Work with personal difficulty</h2> <p>As each P2P cryptocurrency, Duniter has a way to synchronize its peers. It uses a proof of Work (PoW) to write the Blockchain on a regular basis, much like BitCoin. However, Duniter has a unique asset : the WoT, where each member represents a unique living human.</p> -<p>This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each “winning” member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. The knowledge of the whole network is not needed.</p> +<p>This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each “winning” member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. A view of the whole network is not needed.</p> <p>Another strong difference is that forging peers are not rewarded by the protocol. There is no economical incentive on forging lots of blocs, neither on having a lot of computing power.</p> <p>One could say that Duniter uses a PoW that needs very low energy consumption compared to BitCoin : an “ecological” PoW ?</p> <!-- source : https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/ --> -<h3 id="why-do-we-need-proof-of-work-1">Why do we need Proof of Work ?</h3> +<h3 id="why-proof-of-work">4.1. Why do we need Proof of Work ?</h3> <p>Duniter nodes share a database as part of a p2p environment. The proof of work (PoW) allows machines to synchronize with each other. In Duniter’s case, the blockchain is our database, and acts as a ledger keeping a trace of all transactions, status of the WoT and more. How can we let several machines add data (ie: a transaction) at the same time? In addition, how do we settle on how much time has gone by since the blockchain was last updated? Agreement on time is of the utmost importance as we want to create Universal Dividends on a regular basis, and keep track of membership status, both in human time.</p> -<p>Proof-of-work provides a clever solution to both problems: 1. Any machine can write into the blockchain (create a new block) but is only authorised to do so if it has previously solved a mathematical equation that require a certain amount of work. The challenge has to be hard enough to prevent two machines to solve it at the same time, ensuring the unicity of a block’s creator.</p> -<ol start="2" type="1"> -<li>Solving this challenge takes a certain amount of time, which depends on the calculating power of the whole network. This provides a common ground for defining the needed time reference. A block time is set (ie: 1 block = 5 min) and Duniter adapts the challenge difficulty to get an <em>average</em> duration corresponding to this block time.</li> +<p>Proof-of-work provides a clever solution to both problems:</p> +<ol type="1"> +<li><p>Any machine can write into the blockchain (create a new block) but is only authorised to do so if it has previously solved a mathematical equation that require a certain amount of work. The challenge has to be hard enough to prevent two machines to solve it at the same time, ensuring the unicity of a block’s creator.</p></li> +<li><p>Solving this challenge takes a certain amount of time, which depends on the calculating power of the whole network. This provides a common ground for defining the needed time reference. A block time is set (ie: 1 block = 5 min) and Duniter adapts the challenge difficulty to get an average duration corresponding to this block time.</p></li> </ol> -<h3 id="only-members-can-mine-1">Only members can “mine”</h3> -<p>One of Duniter’s major differences with other PoW-based cryptocurrencies is that only members are allowed to author blocks. Each block is signed with the member’s private key, allowing the algorithm to determine a <em>personalised difficulty</em>.</p> +<h3 id="only-members-can-mine">4.2. Only members can “mine”</h3> +<p>One of Duniter’s major differences with other PoW-based cryptocurrencies is that only members are allowed to author blocks. Each block is signed with the member’s private key, allowing the algorithm to determine a personalised difficulty.</p> <p>This personalised difficulty eliminates the rat-race for the most sophisticated and powerful mining equipment. Another benefit is the fact that no “supercomputer” can take control of the blockchain. Lastly, Duniter implements a rotation in forging members thanks to this personalized difficulty.</p> <p>This lightweight PoW is much less energy-consuming than other PoW cryptocurrencies. Members can mine with anything from a raspberry pi to a privacy-first internet cube.</p> -<h3 id="how-does-it-work-1">How does it work?</h3> -<h4 id="the-hash-aka-digest-1">The hash (aka digest)</h4> +<h3 id="how-does-duniter-pow-work">4.3. How does it work ?</h3> +<h4 id="the-hash">4.3.1. The hash (aka digest)</h4> <p>Example of a valid hash:</p> -<div class="highlight"> <pre><code>00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653</code></pre> -</div> -<p>As you can see this hash starts with five zeros which was very hard to achieve and took a lot of <em>work</em> for someone’s computer. Hence the term “proof of work”.</p> -<h4 id="the-common-difficulty-1">The common difficulty</h4> +<p>As you can see this hash starts with five zeros which was very hard to achieve and took a lot of work for someone’s computer. Hence the term “proof of work”.</p> +<h4 id="common-difficulty">4.3.2. The common difficulty</h4> <p>A common difficulty is needed to settle on a yardstick for our time reference. Its role is to make sure the blockchain moves forward at a steady pace - one block every <code>avgGenTime</code> seconds, <code>avgGenTime</code> being one of the 20 parameters behind the Duniter protocol-.</p> <p>This difficulty’s initial value can be set to any arbitrary value (<code>70</code> in Duniter <code>v1.5.x</code>) and then acts as a spring, regulating blocktime creation by increasing itself if the creation interval drops under <code>avgGenTime</code> and vice-versa.</p> -<h5 id="how-is-difficulty-applied-1">How is difficulty applied?</h5> -<p>The numeric value of difficulty is taken from an array of possible hashes out of all possible hashes. In duniter v1.5.x the hash of a block is its sha256 hexadecimal hash.</p> +<h5 id="how-is-difficulty-applied">4.3.2.1. How is difficulty applied ?</h5> +<p>The numeric value of difficulty is taken from an array of possible hashes out of all possible hashes. In DUBPv13 the hash of a block is its sha256 hexadecimal hash.</p> <p>To understand the difficulty, we make a euclidiean division of the difficulty by 16.</p> -<p>Here’s an example with a difficulty value of <code>70</code> : 70 // 16 = <strong>4</strong> with a remainder of <strong>6</strong>. The valid hashes are the ones starting with four zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). The valid hashes are then written as starting with : <code>0000[0-9]</code>. This is a bit different from Bitcoin, where the difficulty is only ruled by the number of zeroes.</p> -<blockquote> -<p>Fine, but the hash of a mined block will never change and there’s no reason it should start with a given sequence of numbers. So how then can we make sure a block hash starts with exactly the sequence needed?</p> -</blockquote> -<p>Enter the nonce, short for “number once”. When a member is forging a new block, his computer freezes the block’s content and changes the Nonce until the hash reaches the required number of zeroes.</p> -<h5 id="the-nonce-1">The Nonce</h5> +<p>Here’s an example with a difficulty value of 70 :</p> +<pre><code>70 // 16 = 4 with a remainder of 6. </code></pre> +<p>The valid hashes are the ones starting with four zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). The valid hashes are then written as starting with : <code>0000[0-9]</code>. This is a bit different from Bitcoin, where the difficulty is only ruled by the number of zeroes.</p> +<h5 id="the-nonce">4.3.2.2. The Nonce</h5> +<p>When a member is forging a new block, his computer freezes the block’s content and changes the Nonce until the hash reaches the required number of zeroes.</p> <p>The nonce allows us to mine a new block by finding a hash. The hash value allows us to determine the difficulty level of the proof-of-work performed. Examples of possible Nonce values:</p> <ul> <li>10100000112275</li> @@ -794,30 +343,24 @@ Duniter Whitepaper </ul> <p>In reality the <code>Nonce</code> value follows a pre-determined format akin to <code>XYY00000000000</code>. The Nonce’s value isn’t the number of attempts but rather a value within a set of possible ones. This is how the Nonce is built:</p> <ul> -<li><p>X is a number assigned to a specific peer. Let’s assume that someone has several nodes each with the same private key, this would lead to possible collisions if this person were to mine the same block with different nodes. Each block will therefore have its own unique X to prevent this from happening.</p></li> +<li><p>X is a number assigned to a specific peer. Let’s assume that someone has several nodes each with the same private key, this would lead to possible collisions if this person were to mine the same block with different nodes. Each <del>block</del> <strong>node ?</strong> will therefore have its own unique X to prevent this from happening.</p></li> <li><p>Y is the number of cores of the processor. The Nonce starting with <code>107[…]</code> belongs to a seven cores processor, while <code>199[...]</code> could be the proof generated by a 99 cores processor.</p></li> </ul> <p>The rest of the Nonce, the part that follows after the XYY, is the numerical space for this individual node and is unique to each of the CPU’s core. This space is comprised of eleven digits (<code>00000000000</code>). For the sake of accuracy, we use the term CPU in the wider sense, it can be understood as a bi-CPU for example. We take into consideration the number of cores for the resulting PoW.</p> -<h3 id="personalised-difficulty-1">Personalised difficulty</h3> -<p>Earlier in this article, we explained that the personalised difficulty is the new and key concept that sets Duniter apart from other <em>PoW-based</em> cryptocurrencies such as Bitcoin.</p> +<h3 id="personalised-difficulty">4.4. Personalised difficulty</h3> +<p>Earlier in this article, we explained that the personalised difficulty is the new and key concept that sets Duniter apart from other PoW-based cryptocurrencies.</p> <p>Here is how this personalised difficulty is calculated and assigned:</p> <p>It is determined by a combination of two different constraints with complimentary roles: the <strong>exclusion factor</strong> and the <strong>handicap</strong>.</p> <p>Let <code>powMin</code> be the common difficulty, <code>exFact</code> a member’s exclusion factor and <code>handicap</code> their handicap. This member’s personalised difficulty <code>diff</code> is:</p> -<div class="highlight"> <pre><code>diff = powMin*exFact + handicap</code></pre> -</div> -<h4 id="understanding-exfact-the-exclusion-factor-1">Understanding <code>exFact</code>, the exclusion factor</h4> +<h4 id="the-exclusion-factor">4.4.1. Understanding <code>exFact</code>, the exclusion factor</h4> <p>Members who have never produced blocks or haven’t for quite some time are assigned an exclusion factor of <code>1</code>. Their personalised difficulty is therefore simply the sum of <code>powMin + handicap</code>.</p> <p>Before reading on, let’s precise the role of this exclusion factor. When a member adds a block to the chain, his <code>exFact</code> jumps up from one to a very high value, to prevent them from forging other blocks immediately after and taking control of the blockchain.</p> <p>The exclusion factor will then rapidly return to one. This delay is expressed as a number of blocks. It is calculated as a proportion of the number of members forging. In the Ğ1’s case, this proportion is 1/3, meaning that if there are fifteen members currently forging, the member’s exclusion factor will drop down to one after five blocks.</p> -<blockquote> -<p>What is intended by “the number of members forging”?</p> -</blockquote> -<p>We mean the number of members trying to create the next block. In reality, there is no way to precisely know how many members are calculating at any given time, because it is impossible to view the entire network. But we need this information, whithout which assigning a personalised difficulty is impossible. To achieve this, Duniter looks back at the blockchain and assumes that there is as much members forging as those who have found at least one block in the last X blocks, minus the very last one.</p> -<blockquote> -<p>Hox is X determined?</p> -</blockquote> -<p>We use the concept of <strong>current window</strong>. X’s value is equal to the size of this window. Let’s see how it works:</p> +<h5 id="what-is-intended-by-the-number-of-members-forging">4.4.1.1. What is intended by “the number of members forging” ?</h5> +<p>We mean the number of members trying to create the next block. In reality, there is no way to precisely know how many members are calculating at any given time, because it is impossible to view the entire network. But we need this information, whithout which assigning a personalised difficulty is impossible. To achieve this, Duniter looks back at the blockchain and assumes that there is as much members forging as those who have found at least one block in the last blocks in the current window, minus the very last one.</p> +<h5 id="current-window">4.4.1.2. Current window</h5> +<p>We use the concept of <strong>current window</strong>. The current window is the number of blocks we look back at to determine how many members are forging. Let’s see how it works:</p> <ul> <li><p><code>issuersFrame</code> is the size of the current window in blocks.</p></li> <li><p><code>issuersCount</code> the number of members who have calculated at least one block during the current window.</p></li> @@ -867,78 +410,88 @@ Duniter Whitepaper </tbody> </table> <p>The calculation can be found under rules <a href="https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g05-headissuersframe">BR_G05</a> and <a href="https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g06-headissuersframevar">BR_G06</a> of the DUP protocol.</p> -<blockquote> -<p>Let’s go back to the personalised difficulty.</p> -</blockquote> -<p>We explained that <code>exFact</code> spikes immediately after the member has found a block. It decreases then rapidly to <code>1</code> after a number of blocks <code>X = 1/3 * issuersCount</code>. Let’s see precisely how we calculate <code>exFact</code>:</p> +<h5 id="exfact-and-the-personalised-difficulty">4.4.1.3. exFact and the personalised difficulty</h5> +<p>We explained that <code>exFact</code> spikes immediately after the member has found a block. It decreases then rapidly to <code>1</code> after a number of blocks equal to <code>1/3 * issuersCount</code>. Let’s see precisely how we calculate <code>exFact</code>:</p> <ul> <li><p><code>nbPreviousIssuers</code> is the value of issuersCount at the last block <code>N</code> found by the member.</p></li> <li><p><code>nbBlocksSince</code> is the number of blocks found by the rest of the network since block <code>N</code>.</p></li> <li><p><code>percentRot</code> is the number of <em>not excluded</em> peers we want. It is a monetary parameter, its value is 0.67 for Ğ1 currency.</p></li> </ul> -<div class="highlight"> -<pre><code>exFact = MAX [ 1 ; FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) ]</code></pre> -</div> +<pre><code>a = FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) +exFact = MAX [ 1 ; a ]</code></pre> <p>The FLOOR is a simple truncate function. For <code>exFact</code> to exclude the member, we need :</p> -<blockquote> -<p>(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2</p> -</blockquote> -<p>We can see that the member is not excluded if <code>nbBlocksSince</code> is greater than 1/3 of the calculating members. Take as an example nbPreviousIssuers = 6 and nbBlocksSince = 3:</p> -<blockquote> -<p>(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1</p> -</blockquote> -<p>However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded: > (0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2</p> -<p>Moreover if the last block was authored by the said member, then: > <code>nbBlocksSince=0</code> and > <code>exFact</code> = <code>0.67 * nbPreviousIssuers</code></p> +<pre><code>(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2</code></pre> +<p>We can see that the member is not excluded if <code>nbBlocksSince</code> is greater than 1/3 of the calculating members. Take as an example <code>nbPreviousIssuers = 6</code> and <code>nbBlocksSince = 3</code>:</p> +<pre><code>(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1</code></pre> +<p>However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded:</p> +<pre><code>(0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2</code></pre> +<p>Moreover if the last block was authored by the said member, then:</p> +<pre><code>nbBlocksSince=0 and +exFact = 0.67 * nbPreviousIssuers</code></pre> <p>ExFact value increases according to the number of members calculating. Thus, if there is enough members calculating, even mining farms would be excluded. We have therefore succeeded in our intent to deter attempts to seize the blockchain and its currency.</p> -<p>However, at any time t, the two-thirds of calculating members all have an exclusion factor of <code>1</code>, even though they might not all have the same computational power at hand. If the personalised difficulty only took into account the exclusion factor, then only the members with the highest computational power from the remaining third would be able to author new blocks and the other 2/3s would almost always be excluded. Lesser machines wouldn’t stand a chance…</p> -<h4 id="the-handicap-1">The handicap</h4> -<p>The handicap is the second parameter of the personalised difficulty. Its main role is to improve the rotation of forging peers. A higher handicap is assined to members with higher calculating power, so lesser machines can also compute blocks. As a consequence, there is no incentive on forging with powerful computers. Security can be achieved with less computing power than with pure PoW.</p> +<p>However, at any time <code>t</code>, the two-thirds of calculating members all have an exclusion factor of <code>1</code>, even though they might not all have the same computational power at hand. If the personalised difficulty only took into account the exclusion factor, then only the members with the highest computational power from the remaining third would be able to author new blocks and the other 2/3s would almost always be excluded. Lesser machines wouldn’t stand a chance…</p> +<h4 id="the-handicap">4.4.2. The handicap</h4> +<p>The handicap is the second parameter of the personalised difficulty. Its main role is to improve the rotation of forging peers. A higher handicap is assigned to members with higher calculating power, so lesser machines can also compute blocks. As a consequence, there is no incentive on forging with powerful computers. Security can be achieved with less computing power than with pure PoW.</p> <p>The aim is to handicap the half that has authored most blocks (the most powerful half) to favour the other one. So, the handicap formula will use the median number of blocks authored by peers within the current window.</p> <ul> <li><p><code>nbPersonalBlocksInFrame</code> is the number of blocks authored by a single member within the current window.</p></li> <li><p><code>medianOfBlocksInFrame</code> is the median number of blocks written by the calculating members during the same timeframe.</p></li> </ul> -<div class="highlight"> -<pre><code>handicap = FLOOR(LN(MAX(1;(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)) / LN(1.189))</code></pre> -</div> -<p>Let’s unwrap the formula: <code>(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)</code> is simply the ratio between the number of blocks authored by the peer and the median number of blocks. For example, if a peer has authored <code>9</code> blocks in the current window and the median is <code>5</code>, then the ratio will be <code>(9+1)/5 = 2</code>. The MAX function allows us to ensure that the handicap has a value at least equal to <code>1</code>.</p> +<pre><code>a = (nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame +handicap = FLOOR(LN(MAX( 1 ; a )) / LN(1.189))</code></pre> +<p>Let’s unwrap the formula:</p> +<pre><code>(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)</code></pre> +<p>is simply the ratio between the number of blocks authored by the peer and the median number of blocks. For example, if a peer has authored <code>9</code> blocks in the current window and the median is <code>5</code>, then the ratio will be <code>(9+1)/5 = 2</code>. The MAX function allows us to ensure that the handicap has a value at least equal to <code>1</code>.</p> <p>The Napierian Logarithm of this ratio prevents the handicap from becoming excluding. We want the handicap to level the calculating field so that all peers stand a chance, not to exclude peers.</p> -<p>If we want the handicap to be applied as soon as the median is reached, we’d have to divide it by <code>LN(1)</code>, the problem is that we’ve already set a minimum value of <code>1</code> with the MAX function, so if we were to divide the ratio by <code>LN(1)</code> all calculating peers would have a handicap >= <code>1</code>. In addition, is it really fair to handicap a member who’s right on the median?</p> +<p>If we wanted the handicap to be applied as soon as the median is reached, we would divide it by <code>LN(1)</code>. The problem is that we have already set a minimum value of <code>1</code> with the MAX function. If we were to divide the ratio by <code>LN(1)</code> all calculating peers would have a handicap <code>\>= 1</code>. In addition, is it really fair to handicap a member who is right on the median?</p> <p>That’s why we went for <code>1.189</code> rather than <code>1</code>. A member has to be at least <code>18.9%</code> above the median to be assigned a handicap. 18.9% is actually 16^(1/16), the difficulty factor between two levels of the proof work (hexadecimal hash).</p> <p>To conclude, you have to remember that :</p> <ul> -<li>the handicap is indexed on the logarithm of the ratio to the median,</li> -<li>handicap is only applied on members whose ratio to the median is greater than the ratio between two levels of the proof-of-work’s difficulty.</li> +<li>The handicap is indexed on the logarithm of the ratio to the median,</li> +<li>Handicap is only applied on members whose ratio to the median is greater than the ratio between two levels of the proof-of-work’s difficulty.</li> </ul> -<h2 id="conclusion-1">Conclusion</h2> +<h2 id="conclusion">Conclusion</h2> <!-- source : https://duniter.org/en/theoretical/ --> <p>Duniter’s Blockchain can be compared to Bitcoin’s : a common document retracing the history of the currency. However, Duniter registers not only trades, but also the history of relationships in the community as a mean to identify a human to a digital account. This way, Duniter has information about the fondamental reference of RTM : living humans. A libre Currency can be issued thanks to the Universal Dividend.</p> -<p>More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers while maintaining a good security on the network.</p> +<p>More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers, maintaining a good security and helping decentralization of calculation.</p> <p>The ultimate goal of Duniter project is to allow people to participate in a libre economy, thanks to a libre currency. What is a libre economy ? The Relative Theory of Money defines it through four economic liberties :</p> <ul> -<li>The freedom to choose your currency system: because money should not be imposed</li> -<li>The freedom to access resources: because we all should have access to economic & monetary resources</li> -<li>The freedom to estimate and produce value: because value is a purely relative to each individual</li> -<li>The freedom to trade with the money: because we should not be limited by the avaible money supply</li> +<li>The freedom to choose your currency system: because money should not be imposed.</li> +<li>The freedom to access resources: because we all should have access to economic & monetary resources.</li> +<li>The freedom to estimate and produce value: because value is a purely relative to each individual.</li> +<li>The freedom to trade with the money: because we should not be limited by the avaible money supply.</li> </ul> <p>Those 4 economic freedoms should be understood together, not exclusively. Plus, “freedom” has to be understood as “non-nuisance”. So here, freedom does not mean the right to take all of a resource (like water source in a desert) so no more is available to the others. Now you get it, this is the goal: free economy through free currency.</p> -<h2 id="duniter-projects-sources-1">Duniter project’s sources :</h2> -<ul> -<li>Theoretical, by Cgeek: https://duniter.org/en/theoretical/</li> -<li>Lock conditions, by Inso: https://duniter.org/en/transactions-0-2-overview/</li> -<li>Individualised Proof of Work, by Elois: https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/</li> -<li>Deep dive into the Web of Trust, by Elois: https://duniter.org/en/deep-dive-into-the-web-of-trust/</li> -<li>Whitepaper sources: https://git.duniter.org/communication/duniter-whitepaper</li> -</ul> -<h2 id="other-sources-1">Other sources :</h2> -<ul> -<li>Relative Theory of Money, S.Laborde, 2010: http://en.trm.creationmonetaire.info/</li> -<li>Bitcoin Whitepaper, S.Nakamoto, 2008: https://bitcoin.org/bitcoin.pdf</li> -<li>Circles Whitepaper, A.Milenius, 2018: https://github.com/CirclesUBI/docs/blob/master/Circles.md</li> -<li>The Sibyl Attack, J.R.Douceur: https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</li> +<h2 id="sources">Sources :</h2> +<ul> +<li>Relative Theory of Money, S.Laborde, 2010: <a href="http://en.trm.creationmonetaire.info/">en.trm.creationmonetaire.info/</a></li> +<li>Bitcoin Whitepaper, S.Nakamoto, 2008: <a href="https://bitcoin.org/bitcoin.pdf">bitcoin.org/bitcoin.pdf</a></li> +<li>The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : <a href="http://lightning.network/lightning-network-paper.pdf">lightning.network/lightning-network-paper.pdf</a></li> +<li>The GNU Privacy Handbook, M.Ashley, 1999 : <a href="https://www.gnupg.org/gph/en/manual.html#AEN335">www.gnupg.org/gph/en/manual.html#AEN335</a></li> +<li>High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. <a href="https://cr.yp.to/papers.html#ed25519">cr.yp.to/papers.html#ed25519</a>.</li> +<li>PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : <a href="https://archive.org/details/PPCoinPaper">archive.org/details/PPCoinPaper</a></li> +<li>Duniter Blockchain Protocol, v13, draft by Elois : <a href="https://git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md">git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md</a></li> +<li>The Sibyl Attack, J.R.Douceur: <a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf">www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</a></li> +<li>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992</li> </ul> -<!-- travaux en theorie des graphes pourla TdC --> </article> </main> </body> </html> +<section class="footnotes"> +<hr /> +<ol> +<li id="fn1"><p>Bitcoin Whitepaper, S.Nakamoto, 2008: <a href="https://bitcoin.org/bitcoin.pdf">bitcoin.org/bitcoin.pdf</a><a href="#fnref1" class="footnote-back">↩</a></p></li> +<li id="fn2"><p>Relative Theory of Money, S.Laborde, 2010: <a href="http://en.trm.creationmonetaire.info/">en.trm.creationmonetaire.info/</a><a href="#fnref2" class="footnote-back">↩</a></p></li> +<li id="fn3"><p>OpenPGP protocol defines standard formats for encrypted messages, signatures, private keys, and certificates for exchanging public keys. The GNU Privacy Handbook, M.Ashley, 1999 : <a href="https://www.gnupg.org/gph/en/manual.html#AEN335">www.gnupg.org/gph/en/manual.html#AEN335</a><a href="#fnref3" class="footnote-back">↩</a></p></li> +<li id="fn4"><p>High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. <a href="https://cr.yp.to/papers.html#ed25519">cr.yp.to/papers.html#ed25519</a>.<a href="#fnref4" class="footnote-back">↩</a></p></li> +<li id="fn5"><p>PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : <a href="https://archive.org/details/PPCoinPaper">archive.org/details/PPCoinPaper</a><a href="#fnref5" class="footnote-back">↩</a></p></li> +<li id="fn6"><p>The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : <a href="http://lightning.network/lightning-network-paper.pdf">lightning.network/lightning-network-paper.pdf</a><a href="#fnref6" class="footnote-back">↩</a></p></li> +<li id="fn7"><p>Surfing a Web of Trust, Reputation and Reciprocity on CouchSurfing.com, D.Lauterbach, H.Truong, T.Shah, L.Adamic: <a href="http://snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf">snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf</a><a href="#fnref7" class="footnote-back">↩</a></p></li> +<li id="fn8"><p>Public key validation on GnuPG manual, M.Ashley, 1999 : <a href="https://www.gnupg.org/gph/en/manual.html#AEN335">www.gnupg.org/gph/en/manual.html#AEN335</a><a href="#fnref8" class="footnote-back">↩</a></p></li> +<li id="fn9"><p>The Sibyl Attack, J.R.Douceur: <a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf">www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</a><a href="#fnref9" class="footnote-back">↩</a></p></li> +<li id="fn10"><p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992<a href="#fnref10" class="footnote-back">↩</a></p></li> +<li id="fn11"><p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992<a href="#fnref11" class="footnote-back">↩</a></p></li> +<li id="fn12"><p>Pareto principle : <a href="https://en.wikipedia.org/wiki/Pareto_principle">en.wikipedia.org/wiki/Pareto_principle</a><a href="#fnref12" class="footnote-back">↩</a></p></li> +</ol> +</section> diff --git a/build/whitepaper_fr.md b/build/whitepaper_fr.md index a459ae6..6ab8bfa 100644 --- a/build/whitepaper_fr.md +++ b/build/whitepaper_fr.md @@ -1,13 +1,22 @@ -Duniter : A libre currency blockchain generator ! +Duniter: A libre currency blockchain generator. ======================================= -## Abstract (TODO) +## Abstract {#abstract} -## Introduction +Many currency principles involve non-equal rights to monetary creation between humans. +We propose a monetary creation based on the Relative Theory of Money, which guarantee equal monetary creation for each willing human. +This type of currency can be centralised, however, this could lead to censorship and arbitrary choices of the central institution. +Thus, strongly inspired by Bitcoin example, we want the currency to be as decentralised as possible, in the transaction network as in the human identification process. +We use a Web of Trust between living humans for identification. +This web of trust allows us to impose personalised difficulty for transaction validation, keeping the calculation accessible to low-end hardware and allowing all competent members to secure the currency. + + + +## Introduction {#introduction} Duniter is a software to create and manage "libre currencies". Libre currency is a concept defined by S.Laborde in the Relative Theory of Money (RTM) that was published in 2010. This theory demonstrates the possibility of an invariant monetary unit : the Universal Dividend. Doing so, the RTM answers the question : -> How should a currency be created to match the principle of equality between all humans ? +> How should a currency be created to match the principle of equality between all humans, now and between generations ? The results of this demonstration implies a monetary creation : @@ -17,111 +26,118 @@ The results of this demonstration implies a monetary creation : Thus, Duniter project will associate a human to a digital identity. It will use a Web of Trust with specific rules. As the number of members may evolve, the Universal Dividend has to be created according to the formula : -> UD(t+1) = UD(t) + c² * ( M(t) / N(t) ) - +``` +$$ UD(t+1) = UD(t) + c²*( {M(t) \over N(t) }) $$ +``` Duniter is based on a decentralized Blockchain. This technical choice allows irreversibility of transaction and uncensorability of trades and identities. While inspired by Bitcoin, Duniter uses a Web of Trust and the Proof of Work to secure the computation network, thus making obsolete the power race model used in Bitcoin. -The first currency created through Duniter is Ğ1 (say "June"). It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software. +The first currency created through Duniter is Ğ1, pronounced "June". It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software. -## State of the art : Bitcoin case + +## 1. State of the art : Bitcoin case {#state-of-the-art-bitcoin-case} <!-- source : https://duniter.org/en/theoretical/ --> -Duniter uses the crypto-currency concept introduced by Bitcoin, which is -to use cryptographic tools such as *signatures* to create digital -currencies. Duniter fits this definition, but it has completely +Duniter uses the crypto-currency concept introduced by Bitcoin[^BTC_whitepaper], which is +to use cryptographic tools such as signatures to create trustless digital +currencies. Duniter fits this definition, but it has two completely different principles than Bitcoin : the Web of Trust and the Universal Dividend . These differences are on both monetary and technical aspects. -### Monetary creation of Bitcoin : a space-time asymmetry +[^BTC_whitepaper]: Bitcoin Whitepaper, S.Nakamoto, 2008: [bitcoin.org/bitcoin.pdf](https://bitcoin.org/bitcoin.pdf) + +### 1.1. Monetary creation of Bitcoin : a space-time asymmetry {#monetary-creation-a-space-time-asymmetry} Space-time asymmetry refers to the relative access of individuals to -newly created money (Relative Theory of Money, S.Laborde, 2010). Concretely, all existing currencies (c. 2015) are +newly created money[^RTM]. Concretely, most existing currencies (c. 2020) are both spatially and temporally asymmetrical for their users. Let\'s take Bitcoin as an example to understand why. -#### Spatial asymmetry +[^RTM]: Relative Theory of Money, S.Laborde, 2010: [en.trm.creationmonetaire.info/](http://en.trm.creationmonetaire.info/) + +#### 1.1.1. Spatial asymmetry {#spatial-asymmetry} -When new Bitcoins are created, *only some Bitcoin users* (the miners) -are given new Bitcoins, while everyone else get nothing. **We believe -this is the *first* injustice.** However, some might say: +When new Bitcoins are created, only some Bitcoin users (the miners) +are given new Bitcoins, while everyone else get nothing. We believe +this is the first injustice. However, some might say: -> \"Miners used their *electricity and time* to get it!\" +> \"Miners used their electricity and time to get it!\" -\... we would answer that this work *shouldn\'t have been rewarded by -newly created Bitcoins*. New Bitcoins should be distributed to the whole -Bitcoin community. Miners should be rewared another way, but not by -money issuance. Of course, Bitcoin can\'t create money through Basic -Income since *Bitcoin users are not strongly identified*, and one might -benefit from money creation multiple times if he owned several wallets. -Duniter gets rid of this problem completely by identifying its users and -giving *the same amount of Basic Income to everyone*. +\... we would answer that this work should not have been rewarded by +newly created Bitcoins. New units should be distributed to the whole +community. Miners should be rewared another way, but not by +money issuance. Of course, Bitcoin cannot create money through Basic +Income since Bitcoin users are not strongly identified, and one might +benefit from money creation multiple times if they owned several wallets. +Duniter gets rid of this problem by identifying its users and +creating the same amount of Basic Income to everyone. -#### Temporal-asymmetry +#### 1.1.2. Temporal-asymmetry {#temporal-asymmetry} Bitcoin has an absolute limit of 21 million BTC (its unit of currency), which means ever fewer bitcoins will be created over time until no new BTC are being generated. So, once the first adopters have mined every bitcoin, -how will future joiners get Bitcoins? Just like Euros or +how will future joiners get Bitcoins? Just like most of us do for Euros or Dollars: to get money, they will have to work for the ones who already own it. -**We believe this is the *second* injustice.** Every member of a + +We believe this is the second injustice. Every member of a monetary community should be equal concerning monetary creation, and get -the same relative amount of money over time, *even if they are a late -adopter*. Duniter aims to fix this by making the Universal Dividend -(a.k.a. *UD*) *grow by the time* (S.Laborde, 2010) according to precise rules, thus making +the same relative amount of money over time, even if they are a late +adopter. Duniter aims to fix this by making the Universal Dividend +(a.k.a. UD) grow by the time according to precise rules, thus making members equal toward money issuance on a half-lifespan. +Most currencies present one of these two asymmetries, including metal currencies +and mutual credit, as exposed in the RTM. +#### 1.1.3. A solution {#a-solution} - -#### A solution - -Bitcoin has taught us that *it is possible* to create a currency system +Bitcoin has taught us that it is possible to create a currency system allowing one to both create digital money and to exchange it without a -central authority. What we need to change is *the way money is issued* -so we finally have a symmetrical system. We need Bitcoin *+ Universal -Dividend*. But Universal Dividend *implies* that the community consists +central authority. What we need to change is the way money is issued +so we finally have a symmetrical system. We need **Bitcoin + Universal +Dividend**. But Universal Dividend implies that the community consists of only identified people. This is where the Web of Trust (WoT) comes -into place. This concept, introduced by cryptography with the -[OpenPGP](https://www.wikiwand.com/en/Pretty_Good_Privacy) format, -allows us to identify people in a *decentralized* manner. It works as -follows: each person creates *a personal identity* that is linked to its +into place. + +This concept, introduced by cryptography with the OpenPGP format[^OpenPGP], +allows us to identify people in a decentralized manner. It works as +follows: each person creates a personal identity that is linked to its cyptographic certificate. The identity must be confirmed by others -members who use their own cryptographic key. It is that simple: **people +members who use their own cryptographic key. It is that simple: people choose who is part of the community and who is not, not a central -authority.** +authority. -> Duniter however won\'t use OpenPGP for its cryptographic features: -> Elliptic Curves will be used instead for the conciseness of its -> generated keys and its pratical advantages. Duniter has its own Web -> of Trust principles, that shall be exposed later. +[^OpenPGP]: OpenPGP protocol defines standard formats for encrypted messages, signatures, private keys, and certificates for exchanging public keys. The GNU Privacy Handbook, M.Ashley, 1999 : [www.gnupg.org/gph/en/manual.html#AEN335](https://www.gnupg.org/gph/en/manual.html#AEN335) -### Proof-of-Work mining : a power race (TODO) +However, Duniter will not use OpenPGP for its cryptographic features: +Elliptic Curves[^Elliptic] will be used instead for the conciseness of its +generated keys and its pratical advantages. Duniter has its own Web +of Trust principles, that will be exposed later. -In Bitcoin Model, the calculation and incentive principles cause a power race : -new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. -The goal of Duniter is to make blockchain validation much less energy and hardware consuming while -keeping a strong level of security. As a consequence, even low-power hardware can secure Duniter Blockchain, -which leads to a better decentralization of forging operations. +[^Elliptic]: High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. [cr.yp.to/papers.html#ed25519](https://cr.yp.to/papers.html#ed25519). -### Other projects ? +### 1.2. Proof-of-Work mining : a power race {#proof-of-work-mining-a-power-race} -#### What about PoS ? +In Bitcoin Model, the calculation and incentive principles cause a power race : +new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. +This leads to a power race an places the control over the currency in the hands of the richest hardware owners. +We want to make Duniter blockchain validation much less energy and hardware consuming while +keeping a strong level of security. This will be further explained later. A consequence of +this choice is the participation of low-end hardware in the Duniter network, +leading to a better decentralization of blockchain validation. -When conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. -Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead -to placing power over the currency in the richests hands : this is contrary to the symmetical principles of Duniter. +#### 1.2.1 What about Proof of Stake ? {#what-about-proof-of-stake} -Now that PoS is well-tested, one could try to use Duniter's WoT to create a PoS-like algorithm with equal chances among members. -But this is not our aim for now. +Proof of stake consensus algorythm was first introduced in 2012[^PPCoin]. The basic principle is to allow the richest wallets to issue blocks, putting their coin balance as a "stake" they would lose in case of cheat. -#### What about Directed Acyclic Graph ? +[^PPCoin]: PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : [archive.org/details/PPCoinPaper](https://archive.org/details/PPCoinPaper) -The Circles project uses DAG in a basic income cryptocurrency. However, in this project, -one peer cannot know the whole monetary mass and the exact number of other peers. -The calculation of Universal Dividend `UD = c * M/N` seems impossible, since we know neither M nor N. +At the time of conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. We did not chose this consensus principle. +Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead +to placing power over the currency in the richests hands : this is contrary to the symmetical principles of a libre currency. -## Duniters Blockchain +## 2. Duniters Blockchain {#duniters-blockchain} <!-- source : https://duniter.org/en/theoretical/ --> @@ -130,138 +146,165 @@ Duniters Blockchain follows the basic principles of Bitcoins. This is essential for synchronization between peers, as to prevent double-spend attacks. However, Duniters Blockchain will store different informations than Bitcoins. -The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no *generation transaction* exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either: +The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no generation transaction exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either: * a former transaction (as in Bitcoin) * a Universal Dividend (specific to Duniter). -Duniters Web of Trust is also written in the Blockchain. The identity of each member gets registered much like transactinos are, with a strong link to the time reference. Thus, the Blockchain is a representation of a space-time frame of reference, where "space" are members of the WoT and "time" the basci blockchain units : the blocks. On each point of time, one can determain whick account is legitimate to create the UD, only with a blockchain analysis. +Duniters Web of Trust is also written in the Blockchain. The identity of each +member gets registered much like transactions are, with a strong link to the +time reference. Thus, the Blockchain is a representation of a space-time frame +of reference, where "space" are members of the WoT and "time" the basic blockchain +units : the blocks. On each point of time, one can determine which account is +legitimate to create the UD, only with a blockchain analysis. +### 2.1. Spam countermeasures {#spam-countermeasures} -### Spam countermeasures (TODO) -An issue of most cryptocurrency projects is to prevent the common ledger from growing too much and require lot of storage and computing power to be usable. In particular, we don't want an attacker to be able to make the Blockchain grow too fast. Most projects implement transaction fees as a way to prevent this, making the attacker lose money. We don't want to do this since a currency with automatic fees on transactions is no more neutral. Several countermeasuers against such spam attacks are implemented. +An issue of most cryptocurrency projects is to prevent the common ledger from +growing too much. This would require nodes to have a lot of storage and computing +power to be usable. In particular, we don't want an attacker to be able to make the +Blockchain grow too fast. Most projects implement transaction fees as a way to prevent +this, making the attacker lose money. We don't want to introduce this mean since a +currency with automatic fees on transactions is no more neutral. Several +countermeasuers against such spam attacks are implemented. <!-- see : https://forum.duniter.org/t/sans-frais-de-transaction-comment-resister-aux-attaques/3846/25 (implemented ?)--> -* output minimal de 100*Unitbase / 1 unité -> empêche un attaquant de faire grossir la BC et les index trop vite (DUBP v12) -* chaînage maximal des tx -* seuils de dépense (implémentés ? en tout et par issuer ?) +#### 2.1.1. Minimum output amount {#minimum-output-amount} + +<!-- This has to be implemented in DUBPv13. --> + +Fixing a minimal output amount reduces the power of an attack. Duniter deals with cents of Ğ1 or 1/1000 of the first UD. An attacker could create thousand accounts with only 1 UD. To prevent this, a valid transaction must have output amounts of minimum 1Ğ1. This reduces the power an attack by 100. + +#### 2.1.2. Limited block size and chainability {#limited-block-size-and-chainability} -### Scaling +The block size is always limited. While the protocol allows this limit to evolve to address scaling issues, an attacker cannot register as many transaction as they wish. + +With the same goal to prevent too many transactions to get registered, while transactions can be "chained" (refer to another transaction in the same block), the chainability of transactions is limited to 5. + + +### 2.2. Scaling {#scaling} Most of the time, the scaling issue rises for distributed systems that should work on a very large scale. This is not the case of Duniter, for multiple reasons : -* Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don't want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT limits its size to around 16 million members. -* Duniter's aim is to be used to create *multiple* libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community. +* Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don't want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT should limit its size to around 16 million members. +* Duniter's aim is to be used to create multiple libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community. -However, Duniter has two assets that might be used if the number of users grow. +However, Duniter has assets that will help if the number of users and transactions grow. -#### Dynamic block size +#### 2.2.1 Dynamic block size {#dynamic-block-size} While Bitcoin has a fixed block size, Duniters blocks size can evolve. On low use of the blockchain, the maximal block size is 500 bytes. -On high use of the blockchain, the maximal block size would be 110% of the average size of the current window blocks( *current window* will be described in the PoW part). -This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it. +On high use of the blockchain, the maximal block size would be 110% of the +average size of the current window blocks(see "personalised difficulty" part for more information). +This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it. The block size (in bytes) is limited as so : -:::{highlight} +``` block_size < max(500 ; CEIL(1.10 * (average block size)) -::: +``` +#### 2.2.2. Lightning Networks {#lightning-networks} -#### Lightning Networks - -The Lightning Networks allow almost instant and off-chain transactions. +The Lightning Networks[^Lightning] allow almost instant and off-chain transactions. They were first implemented on Lightcoin, and are now on Bitcoin. One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. While not available yet, this payment channel might get implemented when needed. +[^Lightning]: The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : [lightning.network/lightning-network-paper.pdf](http://lightning.network/lightning-network-paper.pdf) + +#### 2.2.3. Unit base {#unit-base} + +As the Universal Dividend grows exponentially, with time Duniter nodes would have had to deal with always largest amounts, eventually reaching the BIGINT limit. To avoid this, the amounts are expressed with a unit base in base 10. We want the UD amount to always fit in 4 digits. To manage it, the `unitbase` is updated each time the UD value reaches 100.00 : it goes from `99.99*10^(unitbase)` to `10.00*10^(unitbase+1)`. All the unit amounts are thus divided by 10. While this might seem strange, this process has already hapened in state currencies. Moreover, the amounts expressed in UD will not change. -## Duniter Web of Trust +With a monetary growth of 10% each year and a stable population, such a change of unit base would happen each 25 years. -<!-- source : https://duniter.org/en/deep-dive-into-the-web-of-trust --> +## 3. Duniter Web of Trust -### Basic Principles -In order to identify "members" account - which create monetary units - from other accounts, Duniter uses a Web of Trust. This can be summarized into few principles: +### 3.1. Basic Principles {#duniter-wot-basic-principles} -* Each account becomes a member if it received a minimal number of certifications (5 for Ğ1 currency) -* Only members accounts can send certifications. Certifications have a limited lifespan. -* A certification indicates that the sender accepts the receiver as a legitimate identity. +In order to identify "members" accounts - which create monetary units - +and other accounts, Duniter uses a Web of Trust. This can be summarized +into few principles: -The aim of the WoT is to identify a blockchain account to a living human. Each member of the Ğ1 currency signs a licence stating that they will only certify humans they know well (among other rules). -Thus, if a member is part of an attack on the currency, they can be found by mutual friends. The security of Ğ1 currency stands on: +- Each account becomes a member if it received a minimal number of + certifications - 5 for Ğ1 currency. +- Only members accounts can send certifications. Certifications have a + limited lifespan. +- A certification indicates that the sender accepts the receiver as a + legitimate identity. -* Corroborating informations on members (5 certifications) -* Peer pressure by close relatives -* Law if the licence has not been respected. +The aim of the WoT is to identify a blockchain account to a living +human. According to Lauterbach et.al[^Couchsurf], the strengh of a relationship should be considered when building a vouch system. +For this reason, the Ğ1 Web of Trust rules are expressed in a licence stating what WoT certifications are. +A certification represents a strong human relationship : one may certify a close relative, not an acquaintance. +Each member has to accept this licence before being included in the WoT. +Thus, if a member is part of an attack on the currency, they can be found by mutual relatives. +Additional security rules occur to prevent cheat and attacks on a large scale. -Note that non-members accounts can use the currency, but cannot create money. They can be used by individuals as secondary wallets, or by institutions. +[^Couchsurf]: Surfing a Web of Trust, Reputation and Reciprocity on CouchSurfing.com, D.Lauterbach, H.Truong, T.Shah, L.Adamic: [snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf](http://snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf) -However, the WoT does not rely only on trust betwenn people. Rules have been added to increase the security, and we will present them. +Note that non-members accounts can use the currency, but cannot create +money. Non-members accounts can be used by individuals as secondary wallets, or by +institutions. +We were inspired by the OpenPGP Trust system[^OpenPGP_Trust]. However, the OpenPGP +trust principles aim at defining trust from a particular point of view while Duniter needs to +identify humans for the whole community. To achieve this goal, while OpenPGP allows each +user to tweak its trust parameters individually, Duniter sets rules in the "genesis" block for the whole community. -### Why do we need a Web of Trust? +[^OpenPGP_Trust]: Public key validation on GnuPG manual, M.Ashley, 1999 : [www.gnupg.org/gph/en/manual.html#AEN335](https://www.gnupg.org/gph/en/manual.html#AEN335) + +### 3.2. Why do we need a Web of Trust ? {#why-do-we-need-a-web-of-trust} There are two reasons we need it : 1. To make sure that only one Universal Dividend is produced per member - at each specified creation interval -in the Ğ1's case this interval - is set as daily `86 400` seconds-, it is the *monetary parameter* - known as `dt`-. -2. To identify the nodes hashing the blocks and assign them each a - personalised difficulty. This custom difficulty [proof of - work](https://en.wikipedia.org/wiki/Proof-of-work_system) is there - to avoid the blockchain's validation mechanism becoming too + at each specified creation interval. In the Ğ1's case this interval + is set as daily `86 400` seconds, it is the *monetary parameter* + known as `dt`. +2. To identify the nodes hashing the blocks and assign each a + personalised difficulty. This custom difficulty proof of work is + there to avoid the blockchain's validation mechanism becoming too centralised as is the case with many \'non-libre' cryptocurrencies. - > Wait, what's a 'monetary parameter' ? - -Every currency implementing Duniter has its own blockchain whose -behaviour is dictated by a set of 'parameters' -defined in block zero, -the so-called genesis block- that can be tweaked to achieve the desired -results. At the time of writing this article, the Duniter protocol -aka -DUP- has a total of 21 parameters of which 10 are for the WoT alone. -We'll focus on these 10. - -Suffice to say that in the Ğ1's case, the DU is created every 24 hours --86 400 seconds- but this interval -set through the time derivative `dt` -parameter- can have a different value in an other implementation of the -protocol. - -I won't write about the second parameter having to do with the proof of -work, it's outside our scope here, just know that the Web of Trust -allows us to **identify** the members providing hashing power, which we -couldn't do without it. This crucial feature means we can impose a -rotation between the members hashing the blocks so that no single rich -individual or group invests in a giant 'hash farm' and takes a hold of -the blockchain, paralysing the community! - -Let's go back to the first objective: to make sure that each member can -only have one account. As we all know, achieving zero-risk isn't -possible, our goal is therefore not to create a WoT within which fraud -would be absolutely impossible but instead to discourage it. Here is a +> **Monetary parameter** : Each currency that use Duniter has its own blockchain whose behaviour is +> dictated by a set of 'parameters' defined in block zero - the so-called +> genesis block - that can be tweaked to achieve the desired results. At +> the time of writing the Whitepaper, the Duniter Blockchain Protocol +> (DUBP) has a total of 21 parameters of which 10 are for the WoT alone. +> We'll focus on these 10. +> +> Suffice to say that in the Ğ1's case, the DU is created every 24 hours - +> 86 400 seconds. This interval is set through the time derivative `dt` +> parameter and can have a different value in other implementations of the +> protocol. + +We want to make sure that each member can only have one account. As we +all know, achieving zero-risk isn't possible[^Sybil_Attack]. +Our goal is therefore not to create a WoT within which fraud +would be absolutely impossible, but instead to discourage it. Here is a rewording of our goal in 4 smaller ones : -1. To make the certification process lengthy enough that all members +1. Make the certification process lengthy enough that all members exercise due diligence and are wary of risks. -2. To make fraudulent acts as hard as we can to the extent that they +2. Make fraudulent acts as hard as we can to the extent that they become pointless. -3. To ensure that any Sybil attacks have a negligible impact on the - currency -*by ensuring that illegitimate double Universal Dividends - have no significant bearing on the legitimate monetary mass*- -4. To slow the growth of 'Sybil regions' to give enough time for the +3. Ensure that any Sybil attacks have a negligible impact on the + currency by ensuring that illegitimate double Universal Dividends + have no significant bearing on the legitimate monetary mass +4. Slow the growth of 'Sybil regions' to give enough time for the community to react and isolate the threat. -> **Wait, a Sybil what ?** +[^Sybil_Attack]: The Sibyl Attack, J.R.Douceur: [www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf](https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf) -A [**Sybil attack**](https://en.wikipedia.org/wiki/Sybil_attack), is the -name given to attacks perpetrated on a reputation system through the -creation of fake identities. A Web of Trust is a specific instance of a -[**Reputation -System**](https://en.wikipedia.org/wiki/Reputation_system). +> **Sybil attack** : A Sybil attack is an attack perpetrated on a +> reputation system through the creation of fake identities. A Web of +> Trust is a specific instance of a Reputation System. There are plenty of Sybil attack scenarios we can think of and just as many reasons why their perpetrators would want to carry them out. Our @@ -272,23 +315,28 @@ This means that micro-attacks performed by small groups of individuals looking for personal enrichment are of no interest to us. The web's role isn't to deter these attacks, this being instead the role of the community. Just like the town you live in is responsible for providing -your tap water and electricity but isn't responsible for any burglaries +your tap water and electricity but isn't responsible for any burglaries, etc. Much in the same way, Duniter's WoT guarantees us all a functional -currency and that's quite a feat in itself! +currency, but do not detect small fraud. + +### 3.3. The importance of having our own certification system {#own-certification-system} -### The importance of having our own certification system +Centralized identification systems can achieve the goal we want. State +Identification is an example. However, this has many drawbacks : -We are regularly offered to switch over to third-party or state-owned -authentication systems but these are centralised and go against the -principles of our community. We feel that we would lose our independence -and universality by adopting a state-controlled system. People without -an official state-provided identity or homeless people would also run -the risk of being excluded from the WoT. It is of the utmost importance -that we remain free from any state or corporation. To this day we depend -only on the Internet and yet, were it to fail, there are already -alternatives being tested around the world for a decentralised network. +* The authority may have arbitrary criteria for identification, for example +preventing people without an official state-provided identity or +homeless people to be included in the WoT. +* Payment might be required +to get identified, thus making the monetary creation not "free". +* The authority is a point of failure for any attacker. -### A few foundational concepts on graph theory : a bit of vocabulary +It is of the utmost importance that we remain free from any state or +corporation. The WoT is an answer to this criterium. To this day we +depend only on the Internet and yet, were it to fail, there are already +alternatives being tested around the world for a decentralised communication network. + +### 3.4. A few foundational concepts on graph theory : a bit of vocabulary {#graph-theory-vocabulary} - **Graph**: set of points -called 'vertices'- joined by edges -called paths/walks-. @@ -298,12 +346,10 @@ alternatives being tested around the world for a decentralised network. have the same endpoints. A simple edge is an edge that is not part of a multiple adjacency -of edges-. In many cases, graphs are assumed to be simple unless specified otherwise. - [Wikipedia](https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms) - **Directed graph**: a graph in which the edges have a distinguished direction, from one vertex to another. A directed edge can also be called a path or walk. - [Wikipedia](https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms) Arrow A --\> B is therefore different from arrow B --\> A. - **Endpoints**: the edge with vertex A --\> B has A and B as @@ -311,7 +357,6 @@ alternatives being tested around the world for a decentralised network. - **Isolated vertex**: a vertex whose degree is zero, that is, a vertex with no incident edges. - [Wikipedia](https://en.wikipedia.org/wiki/Glossary_of_graph_theory_terms) - **Degree of a vertex**: number of its incident edges -in and out-. @@ -321,59 +366,52 @@ alternatives being tested around the world for a decentralised network. - **In-degree of vertex A**: number of incoming edges / head ends to A. - + - **Path**: -aka "walk"- path to follow to get from vertex A to vertex B. -### Definition of the Duniter Web of Trust +### 3.5. Definition of the Duniter Web of Trust {#definition-of-the-duniter-web-of-trust} The Duniter WoTs -one per currency- are simple directed graphs without isolated vertices. The vertices are the members and the edges are the certifications given and received. -Directed, what does that mean? - -The responsibility of issuing a certification is unique and personal to -the certifier. The trust he/she places in the receiver cannot be imposed -in the other direction although in most circumstances both parties -equally trust each other. +*Directed* means that the responsibility of issuing a certification is +unique and personal to the certifier. The trust they place in the +receiver cannot be imposed in the other direction although in most +circumstances both parties equally trust each other. In addition, all vertices are either currently active members or past-members. Past-member vertices are in a specific 'deactivated state' and can no longer issue or receive certifications although the ones already issued or received to/from other members are still considered -'pending' to avoid the web collapsing like a house of cards. +'pending' to avoid a collapse of the WoT. If these old members don't +come back into the WoT, their pending certifications will eventually +expire and they will switch from 'deactivated' to 'isolated' vertices. -If these old members don't come back into the web, their pending -certifications will eventually expire and they will switch from -'deactivated' to 'isolated' vertices. - -To wrap up with old members, after a certain period of time -set in the +To wrap up with old members, after a certain period of time - set in the currency's parameters - their deactivated vertex is removed from the web and the associated identity is 'revoked'. The person who owned the account can no longer use this identity but is free to join the web with -another one. :-) - -> What do you mean by 'identity'? - -An identity is a set of three pieces of information: a public key, a -name and a blockstamp. A blockstamp points to a specific block in the -chain. Its main use is to freeze the point in time at which an identity -was created and to link this identity to a specific chain and of course, -a currency -each currency having its own blockchain-. +another one. -An identity can be in any one of 5 different status: pending, member, -old member, revoked or excluded. +> **Identity** : An identity is a set of three pieces of information: a public key, a +> name and a blockstamp. A blockstamp points to a specific block in the +> chain. Its main use is to freeze the point in time at which an identity +> was created and to link this identity to a specific chain and a currency +> - each currency having its own blockchain. +> +> An identity can be in any one of 5 different status: pending, member, +> old member, revoked or excluded. Let's take a simple example: -::: {.highlight} +``` A -> B -> C | \--> D -::: +``` If, for whatever reason, A were to lose its member status, the web would crumble and all other members would be excluded as a consequence. To @@ -383,80 +421,73 @@ or D. Because our WoT doesn't have any isolated vertices, each new identity created needs to be pulled into the web with all of the certifications -it has received -in the same block-. This calls for a temporary 'buffer' -storage space for **pending** identities and the certifications they've -received. This storage space is called 'the pool' -of Duniter nodes- -which we could also have called the 'sandbox' as that's the name used in -Duniter's code. I might add that these 'pools' also include other +it has received, all in the same block. This calls for a temporary +'buffer' storage space for **pending** identities and the certifications +they have received. This storage space is called 'the pool' of Duniter +nodes, which we could also have called the 'sandbox' as that's the name +used in Duniter's code. Duniter nodes inclued other 'pools' for other documents and metadata not mentioned here. -### Exploring the rules behind a Duniter Web of Trust +### 3.6. Exploring the rules behind a Duniter Web of Trust {#exploring-the-rules-behind-duniter-wot} -The Duniter WoTs -one per currency- work with a set of eight fundamental -rules, themselves enforced through eleven different parameters. Ten of +The Duniter WoTs - one per currency - works with a set of eight +fundamental rules enforced through eleven different parameters. Ten of these parameters are set within the genesis block, the eleventh one - `msPeriod`- having being hard-coded in the Ğ1's code subsequently. -#### 1.Distance rule and referent members (`stepMax` and `xPercent`) {#1distance-rule-and-referent-members-stepmax-and-xpercent} +#### 3.6.1. Distance rule and referent members (`stepMax` and `xPercent`) {#distance-rule-and-referent-members-stepmax-and-xpercent} These two parameters are closely linked and together define the 'distance rule'. The 'distance rule' can only be described after defining what a 'referent member' is: > **Referent member**: member A is said to be 'referent' if and only if -> the total of his/her degrees are greater than or equal to -> `CEIl-N^-1/stepMax--` where N is the total number of members.\*\* As -> the size of the web will grow this number will grow too, meaning it -> will take more certification issuances to become a referent member as -> the number of certifications needed to become a member shouldn't -> change. +> the total of their degrees are greater than or equal to +> `CEIL-N^-1/stepMax` where N is the total number of members. As the +> size of the web will grow this number will grow too, meaning it will +> take more certification issuances to become a referent member. The +> number of certifications needed to become a member shouldn't change. Let's now define the distance rule: > **Distance rule**: member A is said to observe this rule if and only > if for a subset xPercent % of referent members R there exists a path -> of length less than or equal to `stepMax` between R and A.\*\* +> of length less than or equal to `stepMax` between R and A. Referent members only exist so that the distance rule can take effect, they have no special privileges over non-referent members. In a perfect -web, that is one in which each member has certified all members he/she +web, that is one in which each member has certified all members they legitimately can, all members would be referent members. However, because the web progressively grows in size and because members die and are replaced by new ones, there are always members at any given time `t` who haven't yet certified all members they legitimately could. These members would hinder the evolution of the web if they were taken into account in the calculation of the distance rule and the web would -effectively stop growing. -You can see what would happen if the notion -of 'referent member' didn't exist by going to the 'gaussianWotQuality' -page on -[currency-monit](https://g1-monit.librelois.fr/gaussianWotQuality?lg=en&unit=quality) -and activating 'if the concept of referent members didn't exist'-. - -> **When is the distance rule applied?** +effectively stop growing. Because verifying the application of the distance rule is calculation-greedy, it is only performed when a new identity gets -confirmed into the web or an existing member gets renewed. *Exception to -the rule: the distance rule is not observed in the genesis block -when -the web is first implemented-.* +confirmed into the web or an existing member gets renewed. There is an +exception to this rule: the distance rule is not observed in the genesis +block -when the web is first implemented. -#### 2. Rule of the minimum number of certifications needed (`sigQty`) {#2-rule-of-the-minimum-number-of-certifications-needed-sigqty} +#### 3.6.2. Rule of the minimum number of certifications needed (`sigQty`) {#rule-of-the-minimum-number-of-certifications-needed-sigqty} This is the simplest rule, it essentially says that each member must at any given time -meaning in any single block- have received at least `sigQty` active certifications. If, for whatever reason, member A were -to have less than `sigQty` active certifications in a given block, -he/she would cease being a member and be required to publish a request -for identity renewal. +to have less than `sigQty` active certifications in a given block, they +would cease to be a member and be required to publish a request for +identity renewal. -#### 3. The membership renewal rule (`msValidity`, `msPeriod` and `msWindow`) {#3-the-membership-renewal-rule-msvalidity-msperiod-and-mswindow} +#### 3.6.3. The membership renewal rule (`msValidity`, `msPeriod` and `msWindow`) {#the-membership-renewal-rule-msvalidity-msperiod-and-mswindow} Bear in mind that a membership doesn't last a lifetime but instead has a lifespan set to `msValidity` seconds. Every single member -or old member who hasn't revoked his identity or been excluded- can request a membership renewal so long as the last -request was made more than `msPeriod` seconds ago -if a member has never +request was made more than `msPeriod` seconds ago. If a member has never requested a renewal, the date of last renewal is equal to the timestamp at which his membership was first created. A new request will be stored in the 'pool' for a maximum of `msWindow` seconds before it's included @@ -466,25 +497,25 @@ are already matched it's just a case of waiting for a new block to be mined-. If a member hasn't requested a renewal for longer than `msValidity` -seconds, he/she automatically ceases being a member. From this moment -on, the ex-member has another `msValidity` window to renew his/her -membership. When this period of \`2 × msValidity' runs out, the -membership will expire and this identity will never be available for use -again in the web. If the person so desires, he/she will have to start -from zero to regain access to the WoT. +seconds, they automatically cease to be a member. From this moment on, +the ex-member has another `msValidity` window to renew their membership. +When this period of `2 × msValidity` runs out, the membership will +expire and this identity will never be available for use again in the +web. If the person so desires, they will have to publish new identity +and membership documents and find enough certifiers, as any newcomer. -#### 4. Rule of certification lifespan (`sigValidity`) {#4-rule-of-certification-lifespan-sigvalidity} +#### 3.6.4. Rule of certification lifespan (`sigValidity`) {#rule-of-certification-lifespan-sigvalidity} All certifications included in the blockchain expire **sigValidity** seconds after they were **issued**. -/!\\ The issuance and the inclusion of a certification in the blockchain -occur at different times. When member A issues a certification at time -t1, it gets stored in the pool starting at t1 and only finds its way -into the blockchain at t2 when all of the web's rules are observed. -Several weeks can thus go by between t1 and t2!!! +> /!\\ The issuance and the inclusion of a certification in the +> blockchain occur at different times. When member A issues a +> certification at time t1, it gets stored in the pool starting at t1 +> and only finds its way into the blockchain at t2 when all of the web's +> rules are observed. Several weeks can thus go by between t1 and t2!!! -#### 5. Rule of limited supply of active certifications (`sigStock`) {#5-rule-of-limited-supply-of-active-certifications-sigstock} +#### 3.6.5. Rule of limited supply of active certifications (`sigStock`) {#rule-of-limited-supply-of-active-certifications-sigstock} By 'active certifications' we refer to certifications included in the blockchain and that haven't yet expired. @@ -494,26 +525,26 @@ time must be less than or equal to `sigStock`. When this threshold is reached the member will have to wait for one of his active certifications to expire before he/she can issue a new one. -#### 6. Rule of the time period between two certification issuances. (`sigPeriod`) {#6-rule-of-the-time-period-between-two-certification-issuances-sigperiod} +#### 3.6.6. Rule of the time period between two certification issuances. (`sigPeriod`) {#rule-of-the-time-period-between-two-certification-issuances-sigperiod} As soon as a certification issued by member A gets included in the -blockchain, he/she will be unable to issue a new one before another +blockchain, they will be unable to issue a new one before another `sigPeriod` seconds. -#### 7. Expiry of a certification issuance (`sigWindow`) {#7-expiry-of-a-certification-issuance-sigwindow} +#### 3.6.7. Expiry of a certification issuance (`sigWindow`) {#expiry-of-a-certification-issuance-sigwindow} When a certification is issued by member A, it will be stored in the 'pool' for a maximum of `sigWindow` seconds. If the certification hasn't been included in the blockchain by then, it will be cancelled and the member's `sigStock` will be repleted by one. -#### 8. Lifespan of a 'pending' active certification (`idtyWindow`) {#8-lifespan-of-a-pending-active-certification-idtywindow} +#### 3.6.8. Lifespan of a 'pending' identity (`idtyWindow`) {#lifespan-of-a-pending-identity-idtywindow} When a new identity is created, it is stored in the 'pool' for a maximum of `idtyWindow` seconds. If the person hasn't achieved member status by then, the certification will simply be cancelled. -### Details on some of the WoT's peculiarities at the genesis block. {#details-on-some-of-the-wots-peculiarities-at-the-genesis-block} +### 3.7. Details on some of the WoT's peculiarities at the genesis block {#details-on-some-of-the-wots-peculiarities-at-the-genesis-block} The aforementioned rules can only be enforced with an existing web. They cannot be observed when first creating the web, that is when defining @@ -522,25 +553,25 @@ the genesis block. Only rules 2 and 5 can be observed at the genesis block. The genesis block has to be manually created by the founding members. In -practice this means that there must be a choice of which identities to +practice this means that there must be a choice on which identities to include on the premise that all of them observe rules 2 and 5. In addition, the genesis block must be signed with the private key of one of these identities. As soon as the genesis block has been created, the other identities can -start mining the blockchain and the member who begat block \#0 +start mining the blockchain and the member who created block \#0 effectively looses the decision power he had at creation. -### Why these rules and application cases in the Ğ1 {#why-these-rules-and-application-cases-in-the-g1} +### 3.8. Why these rules and application cases in the Ğ1 {#why-these-rules-and-application-cases-in-the-g1} -#### 1. Distance and maximum size {#1-distance-and-maximum-size} +#### 3.8.1. Distance and maximum size {#distance-and-maximum-size} The distance rule is there to curb the maximum size of a Sybil region as well as that of the monetary community as a whole. The `xpercent` parameter prevents the creation of a 'faction' that could take hold of the blockchain. - + The Sybil regions are isolated from the rest of the graph in the sense that they can only receive certifications from other ill-intentioned @@ -550,34 +581,36 @@ endpoint. The maximum depth the Sybil region can attain is therefore contingent on the distance between the attacking edge-s- and the xpercent% closest referent members, this distance is known as `stepAttackers`. The maximum size of a Sybil region created by `sigQty` -members depends on the L parameter, defined as L = sigQty/sigStock: +members depends on the L parameter, defined as `L = sigQty/sigStock`: -::: {.highlight} - Maximum Sybil region size = (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L) -::: +``` +MaxSybilSize= (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L) +``` The maximum size of the Web of Trust is given by the following formula: -::: {.highlight} - WoTmax = (sigStock)*L^(stepMax-1) -::: +``` +WoTmax = (sigStock)*L^(stepMax-1) +``` However we know for a fact that members will never use all of their -available certifications. Many studies have proven that we all know a -maximum average of fifty people, let's then replace sigStock by fifty: +available certifications. +According to Dunbar[^Dunbar], on average, one is able to maintain relationships to around 150 people. +Being conservative, we will consider that on average, each person will certify 50 accounts. +We can calculate the size of the average web of trust `WoTavg` : + +``` +WoTavg= (50)*(sigQty/50)^(stepMax-1) +``` + +[^Dunbar]: Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992 -::: {.highlight} - WoTavg= (50)*(sigQty/50)^(stepMax-1) -::: Our goal with the Ğ1 is to create a community of about one million -members enjoying the world's first true -[catallaxy](https://en.wikipedia.org/wiki/Catallaxy) -free economy with -a spontaneous order of things-. Let's see how we can tweak the pair of -sigQty and stepMax- to reach this size: +members to test the consequences of a libre monetary system. Let's see +how we can tweak the pair of sigQty and stepMax- to reach this size: - + The maximum size of a Sybil region grows linearly with `sigQty` but exponentially with `stepMax`. Logic has it that we need to keep @@ -598,13 +631,23 @@ knowing that the smaller `sigQty` is, the easier it is to launch a Sybil attack -it's easier to find four accomplices than five-. For security reasons we have settled on five: -stepMax = 5 sigQty = 5 sigStock \>= 50 +``` +stepMax = 5 +sigQty = 5 +sigStock \>= 50 +``` The maximum size of a Sybil region therefore is: -`(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5))` + +``` +(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5)) +``` with sigStock = 50 we have a Sybil region of: -`45*(1-10^(5-stepAttackers))/(-9)` + +``` +45*(1-10^(5-stepAttackers))/(-9) +``` A good practice for protecting the web is to maximise `stepAttackers`. That's why we decided that referent members in the genesis block had to @@ -618,7 +661,7 @@ renewed. But what if bot accounts were created and certified each other super fast and following all rules, how would we counter that? By introducing a minimum length of time between two certifications! -#### 2. Time is our friend {#2-time-is-our-friend} +#### 3.8.2. Time is our friend {#time-is-our-friend} To help us deter a Sybil attack, we've decided to impose a minimum period of time between any two certifications issued from a single @@ -626,12 +669,12 @@ account. This parameter called `sigPeriod` affords us a greater chance to detect the formation of a 'hostile' faction. Here is a graph showing the evolution of a Sybil region with the -variation of `sigPeriod`: +variation of `sigPeriod`. The simulation considers that honest members +and attackers both issue a certification each `sigPeriod` interval, in days: - + -As you'll easily be able to tell, there is a strong link between the +As we see, there is a strong link between the growth speed of the region and `sigPeriod`. As evidenced here, we need a `sigPeriod` high enough in order to ensure that the legitimate web can grow at least as fast as a Sybil region. In addition, the higher @@ -641,47 +684,47 @@ gingerly, the action coming at a higher 'cost'. There are numerous advantages to giving `sigPeriod` a high value and no technical barriers to it, hence our choice of five days. -We could have also gone for days days -one week- for the sake of -simplicity however there was an underlying idea behind our choice which -was quite simply the pace of today's life. Certifying someone can be a -lengthy process as one needs to make sure he/she is correctly applying -the Ğ1 licence and people nowadays wait for the weekend to enjoy a bit -of free-time. Thus the idea to allow one to certify at the end of every -working week -five days- instead of a whole calendar one. +We could have also gone for one week for the sake of simplicity. However +there is an underlying idea behind our choice which was quite simply the +pace of today's life. Certifying someone can be a lengthy process as one +needs to make sure they are correctly applying the Ğ1 licence and people +nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea +to allow one to certify at the end of every working week -five days- +instead of a whole calendar one. -#### 3. Trust me now, trust me forever? (`sigValidity`, `msValidity`) {#3-trust-me-now-trust-me-forever-sigvalidity-msvalidity} +#### 3.8.3. Trust me now, trust me forever ? (`sigValidity`, `msValidity`) {#trust-me-now-trust-me-forever-sigvalidity-msvalidity} There would be two main drawbacks to a lifetime membership in the Ğ1's Web of Trust: -> First of all we need to take into account that some members will pass -> and those accounts should no longer produce the Universal Dividend. -> Secondly it is of the utmost importance that 'rogue' accounts can be -> excluded from the web at some point. +- First of all, some members will pass and those accounts should no + longer produce the Universal Dividend. +- Secondly it is of the utmost importance that 'rogue' accounts can be + excluded from the web at some point. -To achieve this, certifications have a limited lifetime and members need -to seek renewal from their peers after `sigValidity` time. On the other +To achieve this, certifications have a limited lifespan. Members need to +seek renewal from their peers after `sigValidity` time. On the other hand, this time can't be too short that members would spend more time seeking renewal than they would exchanging in the currency. Furthermore, -a certification with too short a lifetime would foster careless -certifying behaviours. The act of certifying must have a 'perceived' -cost high-enough to make it feel like an important act. Lastly, we also -wanted this lifetime to be easy enough to remember. Historically -speaking, we first settled on the values of `sigPeriod` and `sigStock`, -meant one could issue all of his/her certifications in 495 days, one -year was therefore not long enough. We deemed three years to bee much -and that's how we agreed on two years in the end. +a certification with too short a lifespan would foster careless +certifying behaviours. The act of certifying must have a high-enough +'perceived' cost to make it feel like an important act. Lastly, we also +wanted this lifespan to be easy to remember. Historically speaking, we +first settled on the values of `sigPeriod` and `sigStock`, meant one +could issue all of their certifications in 495 days, one year was +therefore not long enough. We deemed three years to be too much and +that's how we agreed on two years in the end. Thinking that a deceased member could continue producing the UD for two long years without anyone benefitting from it was also something we -needed to address. We choose a value of one year for **msValidity**. The +needed to address. We chose a value of one year for **msValidity**. The act of renewing every year is done through one of the clients interacting with the blockchain, through a simple click on a button. This parameter is less important than others and is mostly there to 'prune' the web of past or inactive members who don't renew their membership. -#### 4. Keeping the pools free of information glut -(`idtyWindow`, `sigWindow`, `msWindow`) {#4-keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow} +#### 3.8.4. Keeping the pools free of information glut (`idtyWindow`, `sigWindow`, `msWindow`) {#keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow} The pools need to be cleaned up on a regular basis to avoid them clogging up with information and to ensure that machines with less @@ -698,16 +741,15 @@ wanted a time period that would be easy enough to remember by all. We settled on two months, and gave this value to all three parameters `idtyWindow`, `sigWindow` and `msWindow`. -#### 5. Avoiding single members from 'knowing too many people' (`sigStock`) {#5-avoiding-single-members-from-knowing-too-many-people-sigstock} +#### 3.8.5. Avoiding single members from 'knowing too many people' (`sigStock`) {#avoiding-single-members-from-knowing-too-many-people-sigstock} -Many sociology studies have shown that we all know an average of fifty -people. This of course is an average, some of us know more than fifty -people, others much less. Once again we went for a number that would be -easy to remember. Although `sigStock`'s impact on the size of a Sybil -region is fairly limited, its value nonetheless has to be kept -reasonable. We settled on hundred. +We considered that on average, each person will certify 50 people. +However, we know for a fact that some members will use more than 50 certifications. +The maximum social network of one individual is around 150 people[^Dunbar]. +Being conservative, we settled on a maximum certification number `sigstock` of 100. +Since `sigStock`'s impact on the size of a Sybil region is fairly limited, we did not investigate further this parameter. -#### 6. Avoiding locking minorities (`xpercent`) {#6-avoiding-locking-minorities-xpercent} +#### 3.8.6. Avoiding locking minorities (`xpercent`) {#avoiding-locking-minorities-xpercent} It's easy enough to become a referent member, one of the Sybil strategies could therefore be to create a region of referent members. @@ -722,19 +764,20 @@ This percentage needs to be low enough to prevent the formation of a locking minority -referent Sybil members being too far from legitimate referent members-. On the other hand, it needs to be high enough so as to restrict the maximum size of the Sybil region through the distance -rule. The `xpercent` parameter was one of the hardest to define, we -therefore reserve ourselves the right of modifying its value during the -Ğ1 experiment. +rule. The `xpercent` parameter was one of the hardest to define, +therefore we might decide to change its value during the Ğ1 experiment. -We were inspired by the [Pareto -principle](https://en.wikipedia.org/wiki/Pareto_principle): if at least +We were inspired by the Pareto +principle[^Pareto]: if at least 20% of members give good density to the web, 80% of the referent members -will be five or less steps from any other member -referent or non-. The +will be five or less steps from any other member -referent or not-. The maximum value for `xpercent` is therefore 80%, anything above that and the distance rule could be too restrictive for legitimate use cases. With security our top concern, we chose the maximum value of 80%. -#### 7. Spam protection with (`msPeriod`) {#7-spam-protection-with-msperiod} +[^Pareto]: Pareto principle : [en.wikipedia.org/wiki/Pareto_principle](https://en.wikipedia.org/wiki/Pareto_principle) + +#### 3.8.7. Spam protection with (`msPeriod`) {#spam-protection-with-msperiod} This parameter stands out a bit on its own, as it was added after the genesis block. It is there to protect the Duniter P2P infrastructure @@ -746,11 +789,12 @@ supposed to address all renewal requests, even in cases where they were last published five minutes ago! The `msPeriod` parameter was given the same value as `idtyWindow`, `sigWindow` and `msWindow`, i.e. two months. -## Proof of Work with personal difficulty + +## 4. Proof of Work with personal difficulty {#proof-of-work-with-personalized-difficulty} As each P2P cryptocurrency, Duniter has a way to synchronize its peers. It uses a proof of Work (PoW) to write the Blockchain on a regular basis, much like BitCoin. However, Duniter has a unique asset : the WoT, where each member represents a unique living human. -This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each "winning" member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. The knowledge of the whole network is not needed. +This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each "winning" member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. A view of the whole network is not needed. Another strong difference is that forging peers are not rewarded by the protocol. There is no economical incentive on forging lots of blocs, neither on having a lot of computing power. @@ -760,7 +804,7 @@ One could say that Duniter uses a PoW that needs very low energy consumption com <!-- source : https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/ --> -### Why do we need Proof of Work ? +### 4.1. Why do we need Proof of Work ? {#why-proof-of-work} Duniter nodes share a database as part of a p2p environment. The proof of work (PoW) allows machines to synchronize with each other. In Duniter's case, the blockchain is @@ -773,9 +817,9 @@ as we want to create Universal Dividends on a regular basis, and keep track of membership status, both in human time. -Proof-of-work provides a clever solution to both problems: -1. Any -machine can write into the blockchain (create a new block) but is only +Proof-of-work provides a clever solution to both problems: + +1. Any machine can write into the blockchain (create a new block) but is only authorised to do so if it has previously solved a mathematical equation that require a certain amount of work. The challenge has to be hard enough to prevent two machines to solve it at the same time, @@ -785,15 +829,15 @@ ensuring the unicity of a block's creator. takes a certain amount of time, which depends on the calculating power of the whole network. This provides a common ground for defining the needed time reference. A block time is set (ie: 1 block = 5 min) and -Duniter adapts the challenge difficulty to get an *average* duration +Duniter adapts the challenge difficulty to get an average duration corresponding to this block time. -### Only members can "mine" +### 4.2. Only members can "mine" {#only-members-can-mine} One of Duniter's major differences with other PoW-based cryptocurrencies is that only members are allowed to author blocks. Each block is signed with the member's private key, allowing the algorithm to determine a -*personalised difficulty*. +personalised difficulty. This personalised difficulty eliminates the rat-race for the most sophisticated and powerful mining equipment. Another benefit is the fact @@ -804,21 +848,21 @@ This lightweight PoW is much less energy-consuming than other PoW cryptocurrenci Members can mine with anything from a raspberry pi to a privacy-first internet cube. -### How does it work? +### 4.3. How does it work ? {#how-does-duniter-pow-work} -#### The hash (aka digest) +#### 4.3.1. The hash (aka digest) {#the-hash} Example of a valid hash: -::: {.highlight} - 00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653 -::: +``` +00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653 +``` As you can see this hash starts with five zeros which was very hard to -achieve and took a lot of *work* for someone's computer. Hence the term +achieve and took a lot of work for someone's computer. Hence the term "proof of work". -#### The common difficulty +#### 4.3.2. The common difficulty {#common-difficulty} A common difficulty is needed to settle on a yardstick for our time reference. Its role is to make sure the blockchain moves forward @@ -830,32 +874,32 @@ Duniter `v1.5.x`) and then acts as a spring, regulating blocktime creation by increasing itself if the creation interval drops under `avgGenTime` and vice-versa. -##### How is difficulty applied? +##### 4.3.2.1. How is difficulty applied ? {#how-is-difficulty-applied} The numeric value of difficulty is taken from an array of possible -hashes out of all possible hashes. In duniter v1.5.x the hash +hashes out of all possible hashes. In DUBPv13 the hash of a block is its sha256 hexadecimal hash. To understand the difficulty, we make a euclidiean division of the difficulty by 16. -Here's an example with a difficulty value of `70` : 70 // 16 = **4** with a -remainder of **6**. The valid hashes are the ones starting with four +Here's an example with a difficulty value of 70 : + +``` +70 // 16 = 4 with a remainder of 6. +``` + +The valid hashes are the ones starting with four zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). The valid hashes are then written as starting with : `0000[0-9]`. This is a bit different from Bitcoin, where the difficulty is only ruled by the number of zeroes. -> Fine, but the hash of a mined block will never change and there's no -> reason it should start with a given sequence of numbers. So how then -> can we make sure a block hash starts with exactly the sequence -> needed? +##### 4.3.2.2. The Nonce {#the-nonce} -Enter the nonce, short for "number once". When a member is forging a new +When a member is forging a new block, his computer freezes the block's content and changes the Nonce -until the hash reaches the required number of zeroes. - -##### The Nonce +until the hash reaches the required number of zeroes. The nonce allows us to mine a new block by finding a hash. The hash value allows us to determine the difficulty level of the @@ -875,7 +919,7 @@ built: - X is a number assigned to a specific peer. Let's assume that someone has several nodes each with the same private key, this would lead to possible collisions if this person were to mine the same block with - different nodes. Each block will therefore have its own unique X to + different nodes. Each ~~block~~ **node ?** will therefore have its own unique X to prevent this from happening. - Y is the number of cores of the processor. The Nonce starting with @@ -889,11 +933,11 @@ For the sake of accuracy, we use the term CPU in the wider sense, it can be understood as a bi-CPU for example. We take into consideration the number of cores for the resulting PoW. -### Personalised difficulty +### 4.4. Personalised difficulty {#personalised-difficulty} Earlier in this article, we explained that the personalised difficulty is the new and key concept that sets Duniter apart from other -*PoW-based* cryptocurrencies such as Bitcoin. +PoW-based cryptocurrencies. Here is how this personalised difficulty is calculated and assigned: @@ -904,11 +948,11 @@ Let `powMin` be the common difficulty, `exFact` a member's exclusion factor and `handicap` their handicap. This member's personalised difficulty `diff` is: -::: {.highlight} - diff = powMin*exFact + handicap -::: +``` +diff = powMin*exFact + handicap +``` -#### Understanding `exFact`, the exclusion factor +#### 4.4.1. Understanding `exFact`, the exclusion factor {#the-exclusion-factor} Members who have never produced blocks or haven't for quite some time are assigned an exclusion factor of `1`. Their personalised difficulty @@ -926,7 +970,7 @@ proportion is 1/3, meaning that if there are fifteen members currently forging, the member's exclusion factor will drop down to one after five blocks. -> What is intended by "the number of members forging"? +##### 4.4.1.1. What is intended by "the number of members forging" ? We mean the number of members trying to create the next block. In reality, there is no way to precisely know how @@ -935,12 +979,12 @@ to view the entire network. But we need this information, whithout which assigning a personalised difficulty is impossible. To achieve this, Duniter looks back at the blockchain and assumes that there is as much members forging as those who have found at least one block -in the last X blocks, minus the very last one. +in the last blocks in the current window, minus the very last one. -> Hox is X determined? +##### 4.4.1.2. Current window -We use the concept of **current window**. X's value is equal to the size of -this window. Let's see how it works: +We use the concept of **current window**. The current window is the number of blocks we look back at to determine how many members are forging. +Let's see how it works: * `issuersFrame` is the size of the current window in blocks. @@ -979,11 +1023,11 @@ and [BR\_G06](https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g06-headissuersframevar) of the DUP protocol. -> Let's go back to the personalised difficulty. +##### 4.4.1.3. exFact and the personalised difficulty {#exfact-and-the-personalised-difficulty} We explained that `exFact` spikes immediately after the member has found a block. It decreases then rapidly to `1` after a number of -blocks `X = 1/3 * issuersCount`. Let's see precisely +blocks equal to `1/3 * issuersCount`. Let's see precisely how we calculate `exFact`: * `nbPreviousIssuers` is the value of issuersCount at the @@ -994,27 +1038,36 @@ found by the rest of the network since block `N`. * `percentRot` is the number of *not excluded* peers we want. It is a monetary parameter, its value is 0.67 for Ğ1 currency. -::: {.highlight} - exFact = MAX [ 1 ; FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) ] -::: +``` +a = FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) +exFact = MAX [ 1 ; a ] +``` The FLOOR is a simple truncate function. For `exFact` to exclude the member, we need : -> (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2 +``` +(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2 +``` We can see that the member is not excluded if `nbBlocksSince` is greater than 1/3 of -the calculating members. Take as an example nbPreviousIssuers = 6 and nbBlocksSince = 3: +the calculating members. Take as an example `nbPreviousIssuers = 6` and `nbBlocksSince = 3`: -> (0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1 +``` +(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1 +``` However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded: -> (0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2 +``` +(0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2 +``` Moreover if the last block was authored by the said member, then: -> `nbBlocksSince=0` and -> `exFact` = `0.67 * nbPreviousIssuers` +``` +nbBlocksSince=0 and +exFact = 0.67 * nbPreviousIssuers +``` ExFact value increases according to the number of members calculating. Thus, if there is enough members calculating, even @@ -1023,7 +1076,7 @@ succeeded in our intent to deter attempts to seize the blockchain and its currency. -However, at any time t, the two-thirds of +However, at any time `t`, the two-thirds of calculating members all have an exclusion factor of `1`, even though they might not all have the same computational power at hand. If the personalised difficulty only took into account the exclusion factor, then @@ -1032,11 +1085,11 @@ third would be able to author new blocks and the other 2/3s would almost always be excluded. Lesser machines wouldn't stand a chance... -#### The handicap +#### 4.4.2. The handicap {#the-handicap} The handicap is the second parameter of the personalised difficulty. Its main role is to improve the rotation of forging peers. -A higher handicap is assined to members with higher calculating +A higher handicap is assigned to members with higher calculating power, so lesser machines can also compute blocks. As a consequence, there is no incentive on forging with powerful computers. Security can be achieved with less computing power than with pure PoW. @@ -1052,12 +1105,18 @@ single member within the current window. median number of blocks written by the calculating members during the same timeframe. -::: {.highlight} - handicap = FLOOR(LN(MAX(1;(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)) / LN(1.189)) -::: +``` +a = (nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame +handicap = FLOOR(LN(MAX( 1 ; a )) / LN(1.189)) +``` Let's unwrap the formula: -`(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)` is simply the + +``` +(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame) +``` + +is simply the ratio between the number of blocks authored by the peer and the median number of blocks. For example, if a peer has authored `9` blocks in the current window and the median is `5`, then the ratio @@ -1067,11 +1126,11 @@ the handicap has a value at least equal to `1`. The Napierian Logarithm of this ratio prevents the handicap from becoming excluding. We want the handicap to level the calculating field so that all peers stand a chance, not to exclude peers. -If we want the handicap to be applied as soon as the median is reached, -we'd have to divide it by `LN(1)`, the problem is that we've already set -a minimum value of `1` with the MAX function, so if we were to divide -the ratio by `LN(1)` all calculating peers would have a handicap \>= -`1`. In addition, is it really fair to handicap a member who's right on +If we wanted the handicap to be applied as soon as the median is reached, +we would divide it by `LN(1)`. The problem is that we have already set +a minimum value of `1` with the MAX function. If we were to divide +the ratio by `LN(1)` all calculating peers would have a handicap `\>= +1`. In addition, is it really fair to handicap a member who is right on the median? That's why we went for `1.189` rather than `1`. A member has to @@ -1081,43 +1140,39 @@ factor between two levels of the proof work (hexadecimal hash). To conclude, you have to remember that : -* the handicap is indexed on the logarithm of the ratio to the median, -* handicap is only applied on members whose ratio to the median is greater than the ratio between two +* The handicap is indexed on the logarithm of the ratio to the median, +* Handicap is only applied on members whose ratio to the median is greater than the ratio between two levels of the proof-of-work's difficulty. -## Conclusion + +## Conclusion {#conclusion} <!-- source : https://duniter.org/en/theoretical/ --> Duniter's Blockchain can be compared to Bitcoin's : a common document retracing the history of the currency. However, Duniter registers not only trades, but also the history of relationships in the community as a mean to identify a human to a digital account. This way, Duniter has information about the fondamental reference of RTM : living humans. A libre Currency can be issued thanks to the Universal Dividend. -More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers while maintaining a good security on the network. +More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers, maintaining a good security and helping decentralization of calculation. The ultimate goal of Duniter project is to allow people to participate in a libre economy, thanks to a libre currency. What is a libre economy ? The Relative Theory of Money defines it through four economic liberties : -* The freedom to choose your currency system: because money should not be imposed -* The freedom to access resources: because we all should have access to economic & monetary resources -* The freedom to estimate and produce value: because value is a purely relative to each individual -* The freedom to trade with the money: because we should not be limited by the avaible money supply +* The freedom to choose your currency system: because money should not be imposed. +* The freedom to access resources: because we all should have access to economic & monetary resources. +* The freedom to estimate and produce value: because value is a purely relative to each individual. +* The freedom to trade with the money: because we should not be limited by the avaible money supply. Those 4 economic freedoms should be understood together, not exclusively. Plus, "freedom" has to be understood as "non-nuisance". So here, freedom does not mean the right to take all of a resource (like water source in a desert) so no more is available to the others. Now you get it, this is the goal: free economy through free currency. -## Duniter project's sources : - -* Theoretical, by Cgeek: https://duniter.org/en/theoretical/ -* Lock conditions, by Inso: https://duniter.org/en/transactions-0-2-overview/ -* Individualised Proof of Work, by Elois: https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/ -* Deep dive into the Web of Trust, by Elois: https://duniter.org/en/deep-dive-into-the-web-of-trust/ -* Whitepaper sources: https://git.duniter.org/communication/duniter-whitepaper - -## Other sources : - -* Relative Theory of Money, S.Laborde, 2010: http://en.trm.creationmonetaire.info/ -* Bitcoin Whitepaper, S.Nakamoto, 2008: https://bitcoin.org/bitcoin.pdf -* Circles Whitepaper, A.Milenius, 2018: https://github.com/CirclesUBI/docs/blob/master/Circles.md -* The Sibyl Attack, J.R.Douceur: https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf - -<!-- travaux en theorie des graphes pourla TdC --> +## Sources : {#sources} + +* Relative Theory of Money, S.Laborde, 2010: [en.trm.creationmonetaire.info/](http://en.trm.creationmonetaire.info/) +* Bitcoin Whitepaper, S.Nakamoto, 2008: [bitcoin.org/bitcoin.pdf](https://bitcoin.org/bitcoin.pdf) +* The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : [lightning.network/lightning-network-paper.pdf](http://lightning.network/lightning-network-paper.pdf) +* The GNU Privacy Handbook, M.Ashley, 1999 : [www.gnupg.org/gph/en/manual.html#AEN335](https://www.gnupg.org/gph/en/manual.html#AEN335) +* High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. [cr.yp.to/papers.html#ed25519](https://cr.yp.to/papers.html#ed25519). +* PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : [archive.org/details/PPCoinPaper](https://archive.org/details/PPCoinPaper) +* Duniter Blockchain Protocol, v13, draft by Elois : [git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md](https://git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md) +* The Sibyl Attack, J.R.Douceur: [www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf](https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf) +* Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992 diff --git a/build/whitepaper_fr.mobi b/build/whitepaper_fr.mobi new file mode 100644 index 0000000000000000000000000000000000000000..464a160f26f9bd5eebda3c7bce5be7fb634c1ead GIT binary patch literal 58742 zcmXTV$Sg@MNGwP#icc$Izz*UzcAp1fbXg~Ve{WxZCr<_j23N40G6Mr+2AIX5+{3`Y zz{J3yUC6+|z{0>_T)@D<z{bE}oyfqzz`?-aEXTmWz{SAe^@@Rkfro)1XfFc;10MrJ zR1O0Jg8&0VVl)E-gAfBl#wrE|1`!5^d<g~y1~CSPQg#Lg1_=g+>NgAw3{ngX%|;9i z3^EK1T`>#{3~~$%6K60mFeorE%xGm`U{GRUSWwBpz@Wmwu>21L1A`g^!@4^R3=A3! z3|mtf7#Oq|7<NZ7FfiyaFdS57U|`T=U^w=kfq}t*f#GZy0|SE*1H+a13=9k=3=DT9 z85kJM7#JS4FfcG!Ffcq?#K6E{#lY}*5(5K+4FkhdCI$uuI|hcQN(>AP4h#%W-53}c zoER9Mf&$eA5*7@M8>AUz1i%3V4YwB%nZGZuZ@&2z6hi-r1PlxevJ4DNA`A=+ypRwC z8w(=X7#J8pz5%h3aR4$08yjXdHaP}H26+Ys21W)321O{X0HwjoL3%+95Dmf%3=GU5 zH@ZfIcrY+9f<lj%fq{t!6zkxGmI8`j&%EUPyu4D4R80m3#_tRa45H=m^r!$<21-6U zi5AI5CdQ^lx<;m{#=0h^76!T&DdwiS7N)7jNr?uQsg}v0=maG(ljOvl%%q}JE8_Gp zf&!h#)ydzRfq@|llr)SCj0|)QOmz)RLkvx=OpUBejP*<`4J=K}wG9lc3=9|;7|uWg z{3HVd!&xXB6fozYY*11-4`DY+GcYieK-dhq3=9m-P&O#6(ESP$8^xm`Fd71*Aut*O zqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OqaiRF0;3@?8Umvs zFd71*Aut*OqaiRF0z*3lY%)r6bL?y~QWI0`Y|=|JQ&R10ic-^3i&FEFQ@>Oeq}nQ# z<R>eA$t=lfNC-(x%1M2nb~rz;BsH(3Sm{}2PHI7Zv8{oDfq|icrJ1>bg1()Nep8Nq z)9s}EluA3Bf)}Zo=@})qN+zkfO5Zb6N-}Jf3<^q=>}-k)67wFVC+Fwn7uhN)8yg!p zNHiQsYxa2Duq7=mtwBP`j^oe*2y9Ta(QlM&4rmf=Y;SBbNd!S9JB3EQ0y~@Bqynpg z#PrmpqSVCfh8Yd*4Na~3Ehk&`TQ!?r6=zm;1eiBeBsJH!t~N6^Gd5GQb1BWsEJ-c0 zI`}5DX~*NzqOOURk8<*pvy(FtGxMIO=A{-TmgE=dwY+O;XmxM#S2F4>Z}D&OZEk4s zZ}D&Oa!e{NDN0N(X%+`V0Yk&~^k(^{{w`nN#JtM3@`9qwyyVP+oYdl%d1d)IWvTD- z^K?@SOA~WGHC-(JlK(b8FSR7GsPRO%KuKnPze8$Cd1`9ji_+Z0ykfoUsZ9y_lMGTH zHr6-RCl;rsywCfRk$NdLr(r{LL`X(zext#Z4By5Hl{()uGLti&mnIe^PI-~~w8g2Z zzNt1XzvyXVV?=poPEKZCdW*GQQ%7cN!}JAB3)}UQryT5)m|jqnn3LHOpz|WXJhd#f zNT;QvaYk}}X->+U=^pKcjUL7MMa3DJ1rPI59u_5KHlAo<%*fA7?u=-9(dO9H(|MtI z){D}Xi!G9+#X6r$it_W)b1EAi7GxH+KS-)Plv$FTKk-0nMPhFEjP{Du@9iE<*{!85 z9IY9N#ZOXOr?(gsf5<N`&Yb%}r)fjuqJ|fF#S>n1%<PmX&o9bubZq$2vFK$=lSXD* zW^(7{UX3<^-tN-gtnk#Nw$6~E(&Cc7eL0zBUHgi=tD4-~T{{nyH$E<De3Y1zlV4uk zw4qHhGj~E#L26NPeqNhQN@iLULupP)Wz(eA?|I)EB~qF$>AX%&Eogq(u_-a9v7_~N zVsh)n4$fxI<^<i;o(~y`MJeTpa|L>%S|l4EHhA={$Sp`+F8MY!H>t&=ac6OAw?`94 z_w>rS-xu9qbibi}(fxVTXV=f0K5zOQ{&~~wJo^^pr<ArInztPSo9&y{&)Yt4!_t<Q z#eEZs^V3Q?W=%_+IkV$+UqqXS0`sGWIm_mEFl43{Ge2sWt9Pbh{S?clpyd2b8U-a& zBGNMRrfCQ3`6MRg7p0_5ww+f#uY6vif<{n?uV$k}V##!asUJ#{CRk)N88n_S+Uzm6 zwsCh#>U@jki6yf+nhs7c&dkZ2Skbg#T4Y{XVo~PI&IQxjcPdylHihQ3XcQICX>ghP zVroH(-jUfA=^YL8En5RZe48wa%O^xNG!&Mm&OI^df>rnX-UI773rq7mH}t3H_H{O# z@977_PLKTZ&l!t$by;kD*Uiz>wb&^)v1FM<d(s-)_Q2(<+BeS0ot8N#SZB?L^1iHw zr(0Co42l)(C)KycHRLyBO}ajfz0JMNz0Iv}#i!Kbxht0M>7CFU-}!QWK+YtE_50Vl zcb)G#nUYyH?ReKD{e~HKHl;Z&?k$cvnF}gQXIU63?F*mb-df*U-&(uSvb7<7;ew*g zD>I8*#Bws5?zjJFx^LWc9}MqqUbgCRQtG4|P4AoDH@z?hQy}KM?WYrS^Gh3EWXvqs zVBF<UT)ce6&c|t)6*E80_h|O$o{*e8$75wwe*2Dw->nw8?H`t{Z@H;on$!Qh`*X{B z5bS@lEppM_jTf>~ljkMup0U}WI6paa(WQ=-7O9lX^vseS6E|j+RO+2<?Ae^YIjuai zB;#{IYVxLypGtF5x9o77b33ne?Zn2!wNG;sE1!bOi0wb-*Uzut5Y>5fwr;0*!-2+) z9bcxLpFe&6^cmkf#n*kG_|VR#r13%LdRwLW(k0Ffg-UiRDolqKgt};yXd7xW9a>=9 zklYZU&2(r%GSi_=S{h7;7F7E-bj9SiDKH&c;Mb5<+n}JL(sHg@a9;a7`9Awr{Z{>! z=^LJJcs^sor0Cv=)a2HNqQwDK4KtjYIY9;CzN;mv$r*Y3Gj>^kN`T%M`#xv3TXY{> zbA6wC)4?8#(v1u9it~#S8|51%QWi=!e3)=&;RL<w8JWvxWabqYWEO4u?37uOymrCl z?Gq0yx;gRu#1l=HeVGA8`3(yiB*OEHviH5;_j><}(vl^{OE#1@3QRm$I>|G8LT7$b zaehu}|BTJa8&-TuY<I}bPf49xwbiMmWmfr~@3Y){_(5=$a$06l>xB(|8_Y6_@=Mb* z+UvS6Fddm^s53h=Z$UzGqr~0@uhP8Ky-KqRr)xBRZF|uA(V`?n?`&exB7t28%=<(Z z%>b`J?b2;J@FB4%F}HoitcE6w)QZHl4;pS*zv$rT+o97mqw~SMie~BVi2P=OqBogI zT_;-q&ApY}laQa=w7hv%U&F2i^SinY+m3=VczI$`YL|bP2dqMBx&f<?y4|Pyce~Fi zGuv~s`+D~!P&H)SaKcdU@&t`tyE+3Ci%Jx%`qs8P6sOLXpIzRs-mhr5PQ3YjbNp=c zsr^%giz*9B@^$;?=l4|<l&oVc%1<fnyE(nzrnt0uLvikG13Q~_k;v7ssj-Q9`}`$5 zY5932kMnaFni`rRRjiS@aZ0k1ouQ3BNXo9k#zsG}L7_M|F(;?Nv9!PrQmMQw{*wQ- zIQ22u+VrBtf`$_fEAn%SKbJO2BsMr?rspM=loq8n79|&@CYGdr0Ts<Tsl~-lKuJF_ z=W%HfsOgZITC8^jQqw-mENNVk(d>|tnwHtHATvKt=TT|N%aRvO4@%0LCgkT9<fN9Q z=2SK%q@|@c8I*h|%4|w#IMBqHm<O&>GV>Iy8Y)t+rzX8myV9chFfXNHRcKyjS!z*n zON2{iS!POV!w$VG8L4eQnvNznRU{UrzR!D<Uy=c>X)BwQK}k6?xrrgMxF9vTq*$+u zuK=lKVuao@X*BG#s7kd}GHs|xYM7FopVM;~+;-?Wpl7Iews~%sS4TseXWRG0&jpFe zsk$YZxv4D<mASd8B}J7jeoZ%8mbWZdGBj-QXj$K~u0<BqS}{pfvI}l{-}LTNYR8Md zS6!AxsW~kN${IP6J1dG?erD#SbWJQxoUozMATPDNH(`QzN|#cl&7_?+lT{M?51_=Z znTc7aey4^}%l}T1saK4qUI)PfJH5mCdCeCl7V0$L=>L&gky%`lnU_9=zgR&dS&!+^ z0?-Om&Hk$Xq^<)cnN0!xxw!@TMGe&*KK-}S@{2kQGmB>IESeVKlUkzQz9BI?wbyLw zfhiMGD-x$3oF$Z((wI=vbg(?5a^n78`CiG1`+LPF?uWt?y*Jtzdyh|8-`U<g9Sqqg zELXA%&q&SdTiDJzQ@Zbu&dh{Ph2s2)6FOKsE-7eC%*@TqYe?uePM^4<$-l{Su~Vl+ z>YM|W6D^+R%*jYkEqT{7p?87aynsikIhl<D3!RtDY&wvZ+0`)lK-PSY%;Z$P6Zz#$ zhB__5x$T^v6DzISuXk~Pns9}s`AdGxP0#JR*l@n19t<m$eA^ba8!kFDAtE(rLB&Ld z%#w+3W-<03Xba3NQB>*)Z}tOKOFioses3{vF>f)`)6@IjS^;VkH7_VGUsbTeqomUq z)I#~3(eSD(VpT*JLsDw@kD}D_#G;he3rUr8-RC;>tkpZ$E3uYy-Hj&cq?Llj?E-5q zw69#?U7nHO`(Vw7+{Vnxr8hcGH?D8aYV1htt8C>cPn@%2-N%-NEgTDO_01?QO<a9L z?|fQQMQKrSs?Mae<ixzj%uQPwyGtPD+o8nbEg7D9EfT3S9hxMj$WM`)ys`0P>y7-p z^!9}H8%r|NGN&Hw^_;wLVscVy-WGw9XGQtB%{FWJa!YecHb?dynj(?b{<HFZd0yLt z;>kN_?<ilGkh)>PwrBk>ia%vGYcw|YtSBhTPs&NnZ9m!KQn_Sjw_|Hf%Y^3D4LiC8 zixby4=H{19;Mic;-ahHq%)N{H=l!4ee^U6O{zd(ho-gWORB5#1#tIqTMbj5eZ=Mf@ z{8QiC^_uP%Tp5rED%2-kc$1miBhemUWZ1JKC#U<RQ;4&IMyFEOj)sTpY$`PueoEe} zkvfB+BkNh}49BFUuH{V%Qyizu<~J(NdDS%`GiSnsCDqLm8>~{hPo_@@C~B-+H6wr7 z&q+HL&reLrFX;PFJZtu{pD8`g&09h3+vdw@r6r|JJF*%!G)`PlI9u2L)Y1#>9UFIS zHEKIiTKpt`GnZ>=QU0zIMMv^;auSP*trq1@Ii)lCce7NBQNxS*U0a?^+t~gfBmZGe z`-zmPL6a>e+V?Jp!3_p${MYzTl}Js_pSojB_|cA{+|=Bp?u@n_iLIMT5*t=5Ok1e_ zw6JvMhbE2W)S|o|#>VnFEOVpVf6iD|l$z6Uqa|X-`?-tz#dLZ$wr`l5()Tm*%_7A< zk-7efnYnEV-4`+|+HNnon3z3BH#D!=qo}x5!zHt9?#UDdjYPd{y+pmME}GAa`YReI zG)7Lkm6)8IUzF1LDS!Tg)a1-<3yMl}Qny!>Wb|t^J?RvldZL4?B!A7p71LKt>I-Py zkdc^^rkj(QmI~^D_30y^lAZ75$XPs@6E#|X6fX%_;k4AMq2f#V#0&H1G-~Mdy-3a} zZJX3Eqc^jOzvp7^bc=?K>jN@NdNbN)R21az_&8spV`or^Z|i;tTq?g*zRiEB{8C9{ zy@UHJ7G9XBvE=@e`_1tn*mS;Ae98SKH%k&X8<fmBxa-p5AL|T3or84_eIK`MNnEn* zb7gVKdWj7Q`Q@FRT_+nol6EjOmV%mBU55S9U7YJ8E0Qx3^U_nBHOn(gW_(y2@wn%~ zriY284HJrXD}}cN?mv;2y2rb5@0{Y@9FycG8ExfU@L}o4yp|P}3%e6r9r}JJH+^Vb z+;pR9OBZYR^X})}4?AVGXWXB0ugAXeeK&hIgWjRG8;$2@Ez8U;SoEPgrY&({{(=|9 znZ+9<rb^`J?X%x!@gX&T&xNfSOO}*pq|T3MVhm4BYU~UtTJ5P3o*$ywG;<$g-kg&; ziAysk#zSCRd|SL-^Q@((3a0O9+5oD^lUo)nC`g7^wHa#z`#-eI^e;%w3vdru>zSKa z0;=YB6zBFFu(L_*705}Q^a9%3HnlV}o>4xdz^KK(rv_TJ8@K5-*d#V6G;Pr@236<} za~PT%8d`Gl%ZtAjf60HDlA2eNnO6BBHNPMy^=00}C#lH|8$f-+s??OXiFtXcMS3So zzULQZ7e6e1mY>t4Y4tQQIiv9bs8jVAT-`S^H1s6qH2o>5{F0Ga^0N3%W?pvFg64}Q z#g9SF6i|C1BQyDNYEer-W^$8)-j$4&gvPhIrNt$WQXl8%rDYc7HZdeszAwpWHUM?5 z8XU_r^4n&lHhZLI7QHWTscib5{5rL=O{ztqC8;<wx4prt{b+JVetzSJCc{R7g2bYd z_i0U;%`0+qOY>SR6Z29UdGqp1bQ(0<6FOramX>7X7d1NQL7O->`p6Z%A!bG2^aC>d z0IQ=t@*y4LBh4#QiyCL-<TOXMeS}6w4?|HGce{GKLRt?)X;Es=4%eKV%z~1J8P26e zWvRtB#icC?;Kr1lO(N>Rh?$A8SxZiFe}}D-QOom|$Hvg;GHJU8i>_wL*6iMZ)`XNv z3B@I;i7BmFUBP+DnZ>Djsl~-zFWVT?8w!g0J5qWXCtm0lXxLfMuwa5m*NT*~#JrNk z^weU#j=qd342_!ois7kAO_3o*69o&3GMhR23W|05m0L<vE7}X16>^#bihBO{{O|c; z1fn{of|@uT>pND1+c!#fhI&SN7mD)p({vjo!e<J+&CJWpOINU(5!hEz^eHhpwRvBY zM~irixRRk^^NtqziQ*H*CklB&+G%qmeDhOMbJ{bzUL@uum$q|c&hhB7%A0aBvn;h^ z|HO*KNt!L&lT%wY@>0v2dV2(lnj+>o^&ao`m@PP?B{#o2BCj+zwJ5)|+oLHetu#kL zqj_UrWqPG<e?W0*he5jL%%26N-8=d?LNXR`PMEOxQj2+uL1NyAoCc3MFDH7H6y@i< zpW)Ha4QYN>F8SHen9-cj(pQw3oRQkH0NlTCV{C2KoABcM#1GAxxry1SllYQA&4%QR z#HNh0<q9dCt8+`21$1f@x9M~lH7#qKwm@L!hp82*1r3FXpIajuJaXo4Xq}MuIkmN5 zfn|I16xFoSqNSZv5_6g_Oes6q^eDBkw4I~%LEFN{9ZMQA8!DC-^+_yg$m~;S4Q^Ce z{X#djm3{4@M$dNHywsAli8|d?t&ZJYNvS0bFW3FAYU=A)-myGyX8ctDW#LoZXU5Nr zpL%^}{LDzh>vL`<Cgqow%-r4lGq|Le(|)G<O!embVCX+nUdgWMSaH*#ZmvFtX+Lt( z^NT7=GIA$e*k+JfH1R;@<jj=P<fW4oj0_BoR@Q@{g@tkZ^p*83<|}JWLHw2V1$Nu5 zlM;*9ddxNJU({Q$n{zsQt3!FijMU`^c0MdFE^R!~yKs(VX-P@H()L>mP9-JgBu=Vq z*GL49V{|xyhA<ixEB9HH=1gJO-r1OtoY>&dnb2&ISkgbg`#1=;PwzgiWal_Lqjf?_ zW^U8u^&P31Wi1b<oLQP2kRRL=UOY`BWjj|=YU(tD_K2Q<)I4yfE^$+7TU1(UUP@x_ z)DIgTbRI~Zua%P7#5{9BTfofU{nNUR>8&g%N?kOwMZ3GdHK4nw)p2=xPGV7d7e{V> zY2N0{wB;xAIv=!5n90)|QIwchoR~aIDS4SheqK)H>`9G=%Nm;|E;n8lzbwA*dvUYC zvc*<y%x%)m3`Nb88a<0aE&3gs*G+GI^d>WDsbtfYKKVWgaPMvxLn8;QbJs7vgS}sT zy4>6c^VZK>KX29c4}EWn4=pmA7e4*}r0LtsoBNyoPnthzM$_}9;%WK4l`C$~{N6Er zTj?5^28ne$b`*9#*tW8`GA}t}?S>VsD-M)Tepry&?4dI`u#d55-Gr8ol>E}9oK)T7 zg4K<QB_)Zo7wDbn+b}7rmA#dH{i5QM$rV!`q@|_y>{x8sd?UBHtM%f<idMT$@lNsC z%RBi&&~B0ZzK87}Tl_b_ElN$#oVBA<W1+#+^=%Gr`;|HcHcRS!pPe<idA38>@!2oh zC0e_uYBuRly;!!$bBRT<f<~v)j!VhOGjD0`@>*Ze$XvAf#e&(5e0qmABusD5Z}!!h zx8wPq%3kN@?RmQ#+9u3woU^l}@nG__84b5G5(`>1CIrl>Ea~@H6d3BFcR62Y_Rik< zonbmB+nDEBc6Ov@?#;C7Id5l^l3CVszvo872FQ3%uYRv)PUb?+(wQ3!l^XjRZZ_KY zrT3-xB`xQesIV}wJzPPf`$Fr6jwPBc%W^WC^S2l_=NUKWLttoL<}`)k85>-BW~5B# z>|;#MOq*2DW6|lOIhDV8p?>K$hN<>b?VHP+%jdawuMJO4nrawQRJ!}&o|(n@--|L! zO6CZxSkrTUr*zB1lFX9I#*?Xu$r+%Us?#EUN8_}&8x?X(8y@6j?w`@cKfxohD0SM6 zz8NbMiuY$sevy-zm%Zxh)~ce^xlYL&9YQin7Z|j-&x&ddY}8n=VNu{@@71r0!F|Ri zrL>}%3mY~x<u&h^<dC{Ys?l+eWJ^IC%hIf7$MF1+nMREkO`dyw=Iz;U)uP>{xKVlk zSH1Hy5;|rUOn6b!)YT-QGyTPe3DYuCQaf(sW;PU*gT{j&CMV~EEBw+tP}Q88o>`Ka z3+kiiKQ2mb2+Byk>Z0>LFQ@W*W=Y0F#Gv=Xyu_T!;>=>~wI-;0+_(X0;J(rDb0$jn z7&5v5twN0S4D~J-B<40;X!(&^l$)AZTw0V`-0aqPp?QAud{D*V(7e2PS+gjt%5}_Z zUr=0{`abP#esLoQxG9tjEyO<*<!6C9>>U?7Dhi5H%Tk*xIvSJnb93|aIvY~bQ;R^o zoaaUP<(YZujRE;@OOrG7u4FWxC<k@lKBX3xW)`Ks%TGyd%F0MAOYL&V$uDXCSX`1{ zl$hSok(bhRv!Jx3DX<{Fyy-<_MpEk6V$k%4-pRZViA5!u$)!1oMLOS8pXBE;KWdm+ z@;$NTL1IrsNl9XIcH_Cmoehz>iP?S8PQCYAXSOz_B^H<Ho$XL;Uk@73$ZhX}6gMTA z?Gw^c+ZYlXB$^v4JGOUh%q-SvHtbMpc4%?S$uCarX2?se)Vto=-rCf}k(pNlX%v3! zZ0I-0oA4p8p&{{cPweE~r6u`O9%LrB7`GI(T+iz@%4>JX@3u@WZMcy$iJ|31gU2NK zNfN0=tv}K`7}^Vpdp$l+)@-eAxX}2c{a$LywC$7SCreJ-K3RO)b|^gHo0*rHTbld6 zw4^`dVQwqqwDZ%>H*W_+^=ZeI?A$UddNdQ?HXF8oXf~hkSd`jbIK`k>W3u!Vfr;n9 zLpz-bPf`<erZIG1OzueN?nqMr4ZyuGQZUpvG%zq|=xowV%Pi`O2zAjrIQf6~%;_f< zspU@-nD!wtxhJaW$f8+>jkiK3#ZQV({Fa!LnbNP`-;i6{>@o9J+x(`Yd4gSY3|kdu zKWPtd4{f)5)O^CgpznXTKM3~y@B80<zwdwFPb0lEnYmpODJ!iTcg?#!dt+i!W=>{F zWq*Euev3K?Hc#)*SF#Ifd(dn@Lo+dF&W&{mEy}YOWMnRo>`*MqU-lzEr%@s&zr5q% z`h|^-b39Ya@^iW_Gz283q^x!*{+!$+FezZAQP0f2|Bn;%@|M0R+Bl(jV&Q@XxruoT zX7tuKENtE}_hWHJcX+!w3@X`$Pb_ScEKbZ#eV#vU#p36yXE(oJ(9+0}p4uv&nzFK@ zBf8PNxXp2;C1?_$=TmA5sQOgUC`wIRC7jr<k<k#@xP0k^miX>lnmQX+_x-P&@u+e6 zl21KTns%CkhBS7TchpZlKlywo|K#&VlXnL9Hcz@g>3*~MPJYm&L-+RX4I8@V>wpHO z+N~#S-}$g8vv{^Z+JY4+-4;ceNu}+Q#g*MNa{GTKwtkrZVnGCGXk+clc_&hfD&Hg) zZJ*GTxoyYXs&!nuSrRucXuhx{MW>kyG>DM7=0e|$#Nw`nR&D>mC3ZW1mj$fEZVzt{ z%*kAIvb3uKR$_Pbcl393E&thSuzY<^X41xnt+q1-QyMvoOEPnEo>mm37Ip5(D_NsB zarF+zlEn5OD^5)+EGXKZ(YABP_Z?s79B%a3s?qqeJR`sTLzhF&w8T!1l|LK9yM=lc z@>gD7eXw&wW?n;ClVVVa@BYA|)chWUzV4#ZoIZ)<jJ*!~IT~j)tZa`A&kyN+yU;ju zb;M$;85fII-$+p~G+TWkCuhy4)ZC<9FQ(nk$?UG5_Mp4oxVs(<Yx}=+bS&GDncICU ze{NxE@ht02UnZREsqd-CTsm_KS9zOMS{ujQf}X^p1)K8o8WK{I^Yij^8xyvEXf|k3 z$SY1QENx<#4(gUa-jTR<c4tJ3!My9!l@=^WYs^|cA+eWRciN>HKGQk7Z>^Cm=yqtd z><(x>k=W*xn3LQP(JPZ$u_z#K#*3nciAkV&!JZQ(<&6$)*V``d*6x_zF*UKYBtLgD zLvmBzT;;@Goi@R;)ZQKQ91=HHfC|FqmzjG{=H_;vtnBme^VBcRS){)9e4jiB+Ij5W zG1;pxW$%af2gSvylLC4k&kW2+%_-=TZ2y>7+R8QmMcaa+#*E1t-R<2C=|%bFE%%q5 z2hDY?{J-*ltNqIVD}Ndusmx2v?Od>{eO3Ibc<?~q^k()B`)v%HPl3kz^EZCzP@2+E z(Yv5Iy;H5YVfE~ot(<#q>z&V=CQ#mSa?Rexpv|Y|CFdqqWadsyXxcw>qp5+xqso%$ znoSZJtv8y~p-^Rp@ni=>Lj%>uqmu-R64xm<3N|d6D%`g-FQql0&0C{5b+^!pinRxp z6im%b$xKVjoW7x?a`!|~&v3o=k{e4G%y_wyNpr)SsTwVxJDwyqS|lwIY>Mcb(Z#*_ zMQ2lSr@@LF69XshoW5c5jLfpu8Iv+{=HJ*>Fw?R_ze7LoU21B|mV%PGn>)-EG#XxX zS!wR8PnlNmIe$y~M8?KNg{Aq;68o-C^q=TI<&IH9MM>j>iO+47x<bHnGEI}>8w;5Z zEl|rTv1U57pw~d7?*P-G1q}(#uAV*`hI)n#1zJpp7HIUGVLG&+aTAExsj1n@*Bm(Q z7^ojoSPHJZ^Gj0kjZTBc?(tW^MtVkiXPPWQeYbO|C7=vmY@^@UXlJ9}c%dP-pn1Nn zk|C%vZsv#8!66x`P2Zco7ne3=VDG`28=085@wagpHN9{B0`0w;wcJDWULS&{VH*r` z^NUMf<`tJDHd!R*rMyo|(@h3VtAByjhWUBLprQK8@2N$pEh~x|7v>h^q~@mPm83Q< z$ZLyE&d<!#X);P|bjWMwXt>~%*>Fhjd|qnPhcBHTMUPVRQqwX^ia`?;Zxgdq8!m#I zFfGi*CHYMTiEr{t8V|M97e8#6k(ZpR)3~6t_)}_1X>ylklVEyLeo02NPg8vhL-$1J z0)P*V8u^_YI-HAdctmJuwq9}$4r>S~&1*c_bs#S#vw3n!M)QKUU8%{b#l?w5m8}Om z%=*&%()6xp^f7ceG@d9+%*;tlYAC2oEot4@zM~+qvhh;OkG#CpoVQJa&r`decRei6 zNX=_rkeZU3qBpr80w>B(SD$D;U46QMvEJ2=8IKZ+Q>WdZc)mFt1e=aeyRT&D*jbp` zbPzPXk(hG?JiXENqUS+(MruVteqP&$%<dPJI!ztD4JDbmJ>T>4Q&Nk+gPJ=p63bE> zG*Y??Q&O8U8mkg>$`dP#-y{~Lr%uTL&3ERN6ze=KYdTQcba29o#N><#Yn?pZJ^e!7 zWaeg;ObE#D>B!G)TF~RrQ#je8Nw{CAm7%C#qWfiY(u9Iek(mJv&V~kkA5y>1+}NJv z(j?Mq+45%EkH$umCz<Kf1Dbc`CgvrkH(5+jN>%8#?d_kpsH9;=aY15pLVDNJG}AQG zw7$&l=?xnVP0Y+Jl<ZhQ%Q{*$TOKwf_Wo-!Y_MqRY>sbY@0~iwu(Tj0adKzp&YtSF zGi8Z6rKw%jJsS)S4D<{P6s+15p654oq!s1ow)w+g3y9@oX{l#vsby#or_nZ7vu!yD zHpRCsZ(Gn4(8%Ai9|D`wTlTl??w?^`(6YZ}hqhtMc@S*MZ#my`LhoQsPS>kRhbCX| zp17<aWoA*zqsqzFi?kL_S}0tcnwq=f#fpmb6<muVi}IJOoaxZykkcEHQrVDDuv#Hy zisZTvC8_X<uPG6}t8V1a`7r%`i{$k4jVt;ulxMbjEd9AuGCg$(`-1Ht*uKAgzmi?} ztmNGJH%eB1T#&fd+t5ID^5)9a#G;MATW78;EXXe?%}HD%r~{sNYe{K5IA{OD*n;*M zP0>cCO-046%Uc(KJEL<Lk~#&l8^9}H+U6Uz&2O7ONp$6fRr6QPUo~r0#WLOS)TCC; z5YRN;s_Uz+cd0k`gWx(aZLDXgcPOzqGx<VMX5WX67mAzfL9lnGVY5PWJ9xBvk!Rlf zqLj9b?UCyQK!b<iPCsb0d)*CC%jIEm^2FD=TO%^NFC=$mOfKkm>!@t_*mrQxg{F+g zxjLO`rNxUp5<BO2&e+>H?LzWg!_@u<xw(l&9R*Wvwq&HGmQP>N-fGouZf7&|N4tC1 z4rr5N<IVPdo1DyLmm3X~8o^z_j^iE2I}W){mTa?W`H`HT+s4$f`(@gSmqn?`sXI8P zf##GlbGP2eD{W+Imq<=6>PpB=o_4F_qv^B!B5>1mu5IPi>p7XN<;yr*%Zyvg!LZan zZ%0M%oZj}Xi^Y3ZwxqWt>K$%qZ+W<fD{<%TwgS*F`Et*e|1JMpej0-*5c8j7i+J<I zevXue$gT+`8Hu}ow>nNdom$X(qhV&(pN19P7jsf~OLQwtJ~7p~q>H_kOTRQ{2LICK zE%!mtE@Z{a%-r6I%?rcxLv{wv$gga^0Un21vSQ_o2~!(6Iy=iU^U`0G?q9HeM#GJw zl!nfR7e0xl(>Ekd(o8MUOU$t;E}eR!c%nqBM&h&e9f$>3=4OV53+lItw3aVOgcj1~ z?b8};61S{u+N|F!xxRSgjnusK)t3^xELQynt@QbvvC3(7Lvq7}c7>w;j`ECE3zAAR zb6P(oe#>9uSX^0LlA5b`Z0d$BQu8+yuQhBIoMt&My?91K>0E>DLYw6~8#^_Urzf;5 zY%ys1QQkkX+j7GEDO!y;x)d6=PxLBEZA$F%m>}4;A-}t}ZF}2BtM_?J8WJlT|Mad* z&dJ}nqtUu-m%(<;#si7Tg{6HSC5bHy^p5s&&ReqUV&BdwLhX}VpC+Zwz0qLV#<^rh zPU+r{Z9gW?Sr%BjJY&I*h4OnBBo>wQC^hc@_sCi;8fPuw?MiB0u|ha)(uJNI^E^sR zN*5)xKAqd)n36L6MSfnxhT_!557S?CPsvYisAxUd=~33{vGc{67rUjK7d1-sSS1$i zno*pbn6qDh<Mf&RGyA8=&+MPs;g>&0VD7HG{5;*o%NH+SpV)5SZk1Hp<dK-yqqy;X zYNg&eP{XC8rOBeBYGGknW=d&dPVvKH1#n$n3~C^zBo<YEPt3_lEh*M{U-YOFR6%Bz zl$K<IYC~d2svkoa%E7Aa@YL_AMX5~_3o?sRQ<^@OWTc*l%o<z)<#f>ONouZ5acQ$e zac)Zj#)!0qftg{mN-?+}Z`3@$c{XfF+M=}&QK{>lfDVVZ#J5D0v_v7+wmr<ueOU4& zH4QvK+{lwwl;5xe(QE#YpV?xOpY|;?wfuWV>jCIG08rZsX%Ygm<n38^K=a4)jQqw5 zP`|!$Vx``d{D;XInXL?s44K8x^AmG)nzppYwk7137e8(E_*&d-(acd&o|>5bvZT47 z%^S3KBeg}Lxcfy4sIDw++)=61a<90*<5OvSU}j!R5~!Dz4jM(z1TVD$HyK*pTisio zCTyRuy=Mi8>;;d5_pa}Sje{HO8R=cmsC<$?v7>WWw?=qsQrE$W+V;)!nlzffH-86> zV$5j%KV|)t^;1@bWK5Zv*q~5Sp8qK|v3R;e^S;ay1*>LuJDbi2&EoA0kOD0~r#Zek zGAHv}Voqth2dtCSGQDMb%jA4eYvyxl%gT(&8$d&o4H~Ie^D?JK6es2!>C;TjYZWM- zYLTB(n%r7Y&=&wIdK)YnH%yoWTFsD|mf7$kx$VI`&3=yl2`wM=PWDHG`r)7<i{i(L z#gkncWt%=uxbd*~Nn&P;Mn`I2`0PiJ$~o^*dRr;Da_%>5S4XX!EzA^53=A3qyTzIm z8!VbCoBbQVcZ#+wSem(1qL-mnqD`~0H?whh<MPG@xm^q;%YM#CYu?s4zj1!ERd!x} zd0zX=mU2)X2f|I$+xNHcPAO@h4}y)?Thf*6W~=A4R!sVDH0i(br2mutH-%67zl6Q> zWL|#C{0$k2#Tm;EHB6YFwS2~;4~fOandy0xqL({NevqG+n3GvNsR7jNU%qmw)5Mj@ zb55+NXgEIQ<lG4jpml^xDtf)9EnK#tEI%`)IUn5ioTAjWBQs^Hb8c$Gj=ap`+(-Qt zxh<da^B=c9C~8sZxzYb;>Lbt^t(gz<Dizd0`5b(fSJQ^+H$XF5;IXK64XNAgyR!82 zH)OO}6_)0gq%LEh&(v@p)XH1>e(C$AFMTJwPj+7#*Eqjtx}Ad6(QeLGo}Qg^f2>Pb z^RMT_x}qtSo&9SZ8#R(rGZM=(^Gl055>qmhOA<?VJx-kasQU-=qlOt9#5+2-SuOk7 zRP!sfC|^OhE2ubMH+jR0h7TK98f6+jw(LlrUb!-Jvp}OlU*cA=)TR@~`z{rw7Ecf; z);n0za0t}ppWs!LSu)u+JfrPFLE@wpyC1jbI<@l$6y^6GSoK1~CDbWEv%@K|c|pmN z8%+g9hTY~JFPeU2WOg|i8mw#DS_-O=G<tSyS}~zAC#T`Y)QnXV8X3C;3=Jks?{5dK zlW0ia0Gjg=pZ&c*y+1v;bjHUSO2vu&A-kunu`f>Tm=fAIbM2|F1>Fjhb{Ltw=uar_ zX;{U*B6p6-+WTv7L)S9&n5U!`WtPnr=$){5`m+5H*tQ-*gUH6~9rb<ei>oHRoR+bt zVUg9sjK&4agE}?y7yf(+?k_Z)SZLJ0tL@?9go#mo;XTJeE-RQX-^bCrzIT1Ad8<)) z--X161HCKuT<^WL;?(XrtuOZmwF&L51WlBe=9SDaDE{71G5Nx#nL0D)%<!CjQnx6x zc*V~Zf+ZjFS1(A)Nwq01E$DH`ZQKAYI2&$2CtWQ}3=MjZ_a13|zNFE}9K4*$vZJlR zCb8!uxQ5j`zwkzS{>0g9g=SvZaIn2=^5>q8S(d9g7ay8!nO2lonzHUjY0lz;Mgh=@ zh|-eO4vt=lHXWTurPDb<(|!xHQZkD>78E6>_f6<H;jy8yc}L>H2^%$1I%aO1*)lCp z!Q^vmVK+zDjA8|=HouM!DVb$+^5<lM*GVp%(6_x|!_IcYo$a6z^Zxh!@B3f*_D|d_ zm0GlOMP~Ar&yyQKotZbOdFdq?l~40#+f3Nd?>S+0@zaXbqU5a^Po`<4Waeb9+OU9O z*Q@pi<r^d0Crpssa(ur&2)3?=z+SG>R*sel$s0ece36k@v~$yxf~l1~9c>p=D@qzQ zTOTzvRPOGcwIF{{K~B2?sD0gX(ilvE8r$bw^Jc!^>ls{`l$rAoTyMAhoc|~<HNDee z662)E)(2~2c8YKNklGZuDS4IRM1k~84|1nwrsS74J`BxUu2EDx$pW(CYo$iBaNg<{ zndy0bS*;35sfkTq%{oo~Z};WqCKeZWsCTG$D42jL^$zt7>N)x4%|W1HjgpMLA|1g+ z%`cX1*sIy|B7Lplq^oORZd=;(BX?)zCV~9M1)Y+UCT7l&Xg#<-D`W1(-s`O!_4DU% zSP{R%JvA3xr7PLlfLm+eVgRwCz2Tsp4XA4ltEa)M{LGZ>ko*c-#BOJ!-<aQ+4Xec! ztPWmooSyx%_+ef{Zb52ML25}+Vo7Ss`-TmlQVU8;5=$~0G9c}+FOZc$4GyWG!TiVh zY0na~Qz0|@C7{)I%?{zINevgl4gF>((27&gN@`GBBQY;IwUIILQnPt*vyon#e@7WO z!@Pj5%m)qdcgA-{w%>2RZx@o0T9o>*L7^b0)u6KZW=DAYi{j+eyu_l+{NnFzH#%07 zWMt-Lw+iK@ylT@-EPk7qSJ|;6u{b}k(Ica>!!xs}^Ll<!!wyi7^m}59K}mj7L{U+r z6=<AU?|f;|`y|kSer8$cjN*nHiH#mzjrn<LndzlX23>0!R)*(?d?;#PkX%v>TEF+T zIJH@$Wo2f=49}29tv{0T^O`d9(uxv`ONvU9OG?`_(-XTrn=FeP3firTyPg+xncFHE zc9}z9Ye#NsV*88MUAdXbMfti-cRCEy@{4jOen_hP3|jE`d}2jGaa(3)9;Dfjm{a^F zKR-J&Fa245=dG@c#GI#jpqb;`o)^7VjWhD{8#k2n9%$3dZ$F`TrDH~UDyUsCv-nef zP8VlhLq;Q0N@`<5dwI)Doj$|P1F6l09hs?#DP6l7A9c%s8aAMnkd=C;`Ym%ZrzJF; zEXgm=`<Y+bFrhaxueY!zqoDsmW>OPF>#w5xwhc``8$FsoBo_2vXmRZ2OwH-t(YB%K z!K2a{hOOC6`c2xCRwk7erRPlHNNrt_T9T}Hwlq1Td1Xsrabj-!fy7FkBdvj{MIBrd z9;TNj7EKOFO)c(Zc-TE7@mXo!qz_%Iz!h3vGH7vsN`BXZ28&LQ<dR;Ii8D%5CTyRu zeb(~{+b3*>v<yv`Y+tf{$rfWh<KE;<(1OAFX&H%Soq?U6T{n|ci%J$WE*4MCoqxYU z0kq^1vf^=S{M7iVQO=V*iV|~LBW8LmIn^BA98^5tC^0!BGqvwSw_$pI=Y;tm=HAr1 zyktS@$;SJQH&-@;b`31D0JS$8UldKY$ymsnQj}OeXCtVb)3>vk!O>>l1)Cpi-q6-= zX9H<Ubt@P`yN95b#&TE40+7ioa}z7OS1v!9l-W_SBp|urL~2pyM1#pEI?lI!)M;4M z_Ga3Jwi^u}dOHeI^BX3XXEq&}WYHmzpVqh{v$JBIM@g#g4CC&wRX>Yf<mb-dC|+=| z@z-35q*<29Ii-zJ({4}GnEX8_v;F(zAMM|b+rNY1*MP*zMO?X!8=DJ@z%x(H1<fzg zQ|Ab@_oSxuE}S_bH*rZ&OJMFQg_2I`ZD(d?f*Pi2MX9NvPIRk%t9`4bF_^M%weQvM z)$feh@u(nwdBm>Z%$&6!7aUy{oLbcUz4;@kE4hB{|K{T$Xy>`dYx$nilHB|~7w3wv zn>B->C^dKEg#{N<TP%w5b6cGHz4~@0=NC0j=;WHOyu@<G;SC4M*GT5iXr3HXn%n5m zFehb7N3%dmYC-BshWxyoi2)OwJ=X{JaI8F4nOdUL=+I%2x$aiS%HGa>s);$h5-A-o zavE2*B$TaSSZ`div7o;par22LkEV;|`9*sgx|*6#?6+8OsJKyM{gru7nqM?VWOw^7 zKE5KoTYg3QiuCUFE7FbiO!N*uOD%6vXj#ylwdQ7i_kx0b63sWj3x`@W^C$nXYIT@f z(Cb*1pPZOfx?xA<isLJeFPaa6t?3|g(fmgHHU-FdX?}k|qkhBrhEt9G?d#jux36(; z>ug=#Xg;NVN`uws{*HEs>7R-fbd$GC=s5stVy)Uxl9`-Zyxl|hRl|>l9Z8i>Q_}kb z8eIz#OEQY}%M)|5i*<YVx28AbH)PK}zUcql<89~L`#ZuL&Ub`2_IHGLgm(l7&*oVE zqF<<0zA+y(!;v^4Wp&~bhBx{71+yNeG)x1}l{C%lNSY%#cSB~e&eLrP4XY;I%-b(e z{G~kqNoMgnjr|R?Cv>|sRW=1QeC+Dps5CRNI5D^BM5FK2gT-ykO^3FBX^32y)X=a} zvLLaj&nU6wd16Xd;_QIrN(J496U|z>dh-=_GAAb%r?z&q2Q|%@*I8U#n!DC|?S|$h zrFk2Ff%*k&XT4t_SU&ege|}GWLq2FmY^{EOe(&?X<^A~$=Ry2FcF^3I%jSgS#XtM& z`|BI)`|JB_S67s0WcD%iX!a~$I<faxdTC~HM$>_mX0E--Yc6h`@oi>AYDMSG#GZmq zf!>{s-i;F`bgy}tQ{44x=9A4cW`0=LIg7DzMp03IdE*J@M-7wJ(o3ul^?h7DY2}5r z6Ef4%8WP$xHcW0Ta%wDd?3v!Vydl45de3wd5Yc@eL^goQZuy?+cCOP>TiF}Kd-8j- zx}VOD?%LBa-Kl3raYMt*k4{r3%yie;Ib*8f7RPN98gA??n6aQSaJ$p)$=#hxi#qe$ z>g{awlfczAG@*dT)b(>RVdVyBb+;0%0yHitfp1M~NU*a>YCP7c*Koe!Ok+Q;THUia zKL=D#e@iVYNv*KaZ!~O4Xl!q6hSlp<4;y2?XXF>BK1oe4N=<!P{42F6Uk9{guAxAu z(H+#^c$fb&FF7+MwP`_W3TOdWb9{$-11L%LnStic+K+?ChVvk@oxh{s&ZVt6Kdp_g z)xU9m$MTLvd8N5YsYQ(|GfRrw{oB11bTjiF=B2zZEzxb?-g3MlzkPfAc5@KX_8vqw zoClF@^6lI0{97LMg|un(o^fo=Z`|L0z5ROorM4eQ`K9d+?VI(#BxdG3%}Xf;%_tpg zf8O%FA;0~3`*RBr(Jl`n8_t8sHvRVJcAj~lMnn7k#_b@we^p*`er{%7di%YM)Wi;l z_M0X7?dRLm+t0V3Z_p^sY5m@|U&$ynw{3sh{<d8Yb28KOY?YEHH>4IdT4d&?H!Mv` zEKbeI%u7}JT$F69q^F;mo7l>r-(FO#msOD7*wC;dy>SD0p4Fh^bn%S(jt423iRnd& zxoztjpEo{le5laAzdgJmzacXvv#i~`-3Z(+F3o9I@4Y!;zTt%V?Y|oB`^Edk`$Ym0 zOEOyW8}(c3`?_=!vmq;)K=~h38tZ;&JkTeYmJgoN2ux2cnN~c}wP9sLic`OPUs*xh z|F$2k<*kJ+M#Y&`>yujFx4v(EZLDXicLY2h0vguoi7d%TJyP1xF!=|lQ8p9YC~H@5 zP-uuLXwmQdVA#35#k_fWM`}nj|MmQkWeWLusUI2&pjC6F?!%(g)(^P_IU5u*i&B#} zX-+s$kWsvT(t?T&7MtFeWF}8uaHZ)&Lur##TVihNtiXnbg&!IkXIVFVO>V4A%S=ve z|5^Mzvn+L0ck_zWhK!W%<L&wFncdUdQ>KQu*SA-?w6RQ^-{{}yKW%1iYGRATcBPh^ zvn&c)7Gy#u&=*7%7nd#wOl;lXyJ;sw7idpd>!q%MVo?8k;>ULR%+#Vz?vlRDhLe>a zauSnweaLIBY47SWNX*O2FL~5(A-7<UK}w@&euG9)PfPR8#GIbM^o&Nv-2A2$$(cpT zrMbl=iFrMoNsSHD4VqsxWPrCv=2SL+0j;%Zs_yy^ft~X^=db$sFePQ`EuEH%oc{0q zjHwd?CT%Neev#OEplrhQ{Gyg0#U;88EqWIk%A3NQ0(WbI+P&Qi=NT~0NNE#jN|?gb z-cXVX8Vu=v)%oIG{+s-~^d^no&dvixU2l7jPp<9~>-v?~T$od|?nh<g<$XIE?@fJ? zufO0^kM*>DGXqO9+aDxP%uGowYK&+VDA*`4F`?z)1cyY>@WRA{i!%}ninkOsFPy`m zcd{X=VP#HA)3KENyv7IJGjmfPB_?NgXiVy9T%pt8nc2nAY}|Id?QnTZW9qDklK#!9 z6$KMF%#p2ZWG<c;Fu|g2QP=#gnXPLYR?OFJm^j~U;(P?O3(5b!$m46lqM-KWMa7dO z(w3~8^*gbD#jJ?T{2qf&j?4}V-Op<!W|S<=ZMjiA-7+yZweiKWf{r_F?MtQCY0Pyf zO3lsh%WU7&WLdsiV#(daV$g=Q#z}o1c_s6AHZJIJC`v8M&+f3Ar#)Z!dq)2I^1KNz z8-FGz=a;t6oTA=VP}+B*B%{fqX<pLGPc0Iu4HxoX<+n{~iR@UExPW1@;*<&9`P~`2 zzHh$1>r}(}9`T*ad-ON&^=ygRw7k*3w|vDytAooKI`Zc@_9#sK)y7zmIpfE?h!rpL zKn?OKTvm++1*J(ja}%;tEBki5>-o@amH4PNaqfcL0=?Y=4dov?97@(O%q*Cn-pJHH zFJr=rnGKBwxf6bN-E5h$PqQVVYSZK<tHwzaXRb>q&&Zr^(X*h<t~{~$@qCAV&;Ccf zpzcbqeWOu}e~V}Hqc)kzcPA&T3TkM}NGzLEnAyrPVMpuh*45qNz2NPM4e7Jy_r33X zKkI*Qe{X+pdF2$RO@^&Iw=wM3=(RB2#F3V^)S&Uj%8RANR*Ot^=J@E$S>KQ_{mzQW z)QaSs(v&^R+xXkc8*&yLpDNgT9t=<Uq?XJJDoM=l-SBz)gPctg6%#Jxq*~1|?`ZGz zZ&q(sZ&m~~wi{l6XOo-v+bV5Y0-jBV?|yb<I<!C+RFN_rTHw?W=4_Kx)b_Bb(X7Fh z>Cl3jhUX328(d;^b=APtT{?K`*#$nTT+*P~kb>y1;+t4*tc3MlVYQfNn$ENQqVE}r zC7|8HpyAE@Je`A}apy1jZ}N*%UzQYuR>n076qh8HlosoJ$w+NfNCHnsJ}xTFP0C3H z?Ih00dEfA(sBunlqe@chQ*bz?HYyZ9Y$*V*mjLZE2Mzjy@>J7_%%(q}o&~7ung}XM zLDf(TsO>gct)t>l+mB|CqSV~P%)D=jIgK|;^GY&vTC-9s3Nni-pS11Jd6Sw5nmTz3 zUOxIIGdHz;lT$k*Xoe`WtU13qtGKz?`F+t5z3#MvZh2cJ!)|#nlyyo?PAu(`$S*Cr zo*(igKeZUL<m*LZ^Nz&4%9q9YIjtTk-&z!tQ`>)l%BXj#<u6lG+g6lRb_=97D&?i7 zrWCiH?5Zdz&B<w)k(t*}(bJY$lF=ib)}`NeJhS;=ar@R3oyMpxj>gF1#Euh_ntCdF z3?4VU=!odhNc@rt>RTmttpGJqlS<RlQj6LQCRBi`y9Wh{$z7W}OOrrNP1uk^L26z~ zPr)?)M)%J1ohRDwW~NR|n6#rUzb&s}MrD_ETWjl?mhCMY+d?`6T5mL27UbvWw7%?= z0MC0*jmXPS={{JVk=cEsyg6X%ti+t+{ATVZp2m+&8pSOgN%<8`id`8cGe0y$v^2fz z((Lc(+1d29;Z<_8fL?QZb7P~#jE2UDnbl1vS}qnh?d%F{*qoA|T$<Yv&|#dLT9P<z zLt+z0Nkc{_M}A%tN25pTRQIXw3*x7`cUObbIe1rH4}Y(Jucxt|ncmTgf`$z<KeoLr zD$Qx#kd&H{Ip47@FMRTWt^{zM*>`-YdQ1DvgN7{{E&VgkPhg+G6w=(#%$FZhtf2co zulGSi1*p<oxS_IP256zfVvgynKBtznI5vAdE6q#kNysZnTxigGC^fHZLvo){(So4V zoaHO>o@7odYz+92SkyS9c|!3dkA@4gl;?hEIR9|Pfo9L<g)`59XACAA%zU);antRV z4Xq1xXRPbKuVmDIVx8wyg}g`U?SH`|=RG?+)}xM`=N1Q~7G>tAG$eM*H5qQW-W=Dp zzH7Daw8Fl^q|^pO&^mP8DJQ2EwH^cw(@!n?T$;3&yCkP_()Ygd73O{U?edepw}emn zKIx<3jE2lj9UC}$rKSrNrS{}({Hif&e%t$IeUmPC5N!V5<=*97T#{Pgn^@6h4}#6% zZS_t4ZS}3UTKyaUH~w$+2f?P}t^Tb(75xp#9TQr^L9jW#HN0thYq(~s`CRe7<sjJP zKPi1K*Nh7#<@qzd&-k1STAY|u3EJMVKXL8L{Pfgi#i?nTGbXHZN$LNdlREjp+Mf;Q z8_qM%T*EM@Ag^h~_8luPBo}2SHQh{G@Udypw94`|9t$j*7$)gY(rOaSEVgQ|@Axq{ z5j<+PGQ9mj!}*329qL`}UF}^hL7=&juJ4WQo%=g?ST*__+;XxwF|*@i+s@Ygn+jj1 zbzW*;)sWCRu_S+4=91N!?FZ9~Qg?jpUeFMb*pav;q0^)2X<=z&MAL~0-xpt>;tztY z`=|I%@dhot(e;bdHPoN^e9H7G)0>w!`R_YkzBTh)`^UERd8HkT+8)f`qj#{8xpiUt zl07GqdRFA*v{&SpH%w@fXgt%fy(B+hr%5Am!lcZ#jtv(|60=j^=1+N<S_Il~mz=os zVv9m?>14;|h#tk{{Jk#{m&msyPubim-Xz~7(ISwVx{9-jKe1o5I0G~ume*I%VbOCU zeXqLyWP8vE+#L74*XOu*^>_98q)u#XacF-r>;JY5v*c5!--p5G{b1JZweOoH+O9X2 zx4KV1KmB~?qWsMgMP;os8&+)4ntp!zsl5yK-P{sc@?%Aef@+UvulvTBp!SRX8mSd6 z7iOGTa$%2T8fetFAs{EUc+$$5^5}5W`Wfdzu<?H<`@|pM11Z`JIv5=%rh~@TC#FwK z?_J+252~t`=66o%HtMYUoZoS?Wa9fh`&Pf4C6t<$mYQ6m(<oW_BC&TzUOuP|mf00h zP?TAgnUk76D<i+G-vTtT(kni1t7l%%&eWnN&v}iYT|E6S@~582%v<myGdbgFVuQxS zmW;&W*-O_ioLABMwZ*A<251HI@*iyxtr0q)z2@a}Bv<`xiEoJoZPaP?(3yKMv2<JF zVwr-X{8bIb#hGPIGZ$?vZn?N5sOM&5YqM%fX2an%o<*qzIf==w4oQ^@E|j-zEbi=T zc+kiQSt8STZ);~>vqE!3w?gK^4-?h%N<KqoMZwjnlATRSi5=QmCE%QI+VB88+}p4f zc~MJAgQkssBO_>(_h*AeQ((iK#`BFQVD;(ujC{~C9Z2Q!Gqq6yl8{nU9_HkLD$>-V z;x8Ggm2cn+w{t3+B1&^oKue~IQycBd8&<x^%mcMX7lO_W0M8)5PiyEZPfdE+5LMZb zP?Y*5F*`NyWnM}C!{nwFtp=HSjZw*<?KnA!jo(wBWP%#r$*G`&2p;C8G%ahs42iqU zvR2OGlKcYbT57$HbGY|Sb^Y%&?=%G0nC%8-sYRJ-l}#1Rn-U8Oax#;_OC<he7Prag z=jnoazA2SDFWWha-{-YT6r>h`T72CJ<ry6siI6HZ546Vqd1^_M0B9VzQL0m_y*9t7 z{ln9W=8l%e9_Gf$MX5~&sXe#58JZIsgOXDVTBDk@8dkJQTD5L(-Cq1IzvO*VacWUn z^R7m%^rj8P4G+ML9R=OiroOh~XPHICZ3n<}My)@Ze{@fW!by;-XgXt3k9v<1tX>6G zNJe^>S|z(nav`gu-<7t%YS=LKNzdvwhwhFx0gaZprWZ5Ho41<Go(_U7^|PnXo?M)n z9#~R2dp`&^`?vjXYH$0m*{a@nuk$(xHu+CYpPCTT_pm{tle4&|spml7$;qcui;E|{ zoOfX+Lt<s4Wn#mI#N>=gvbm*=4Gjwt^QLgj^5{3n%uQ9$%}q_rn;bZyqTyz7Lqbo$ zgd*KVLX!_9r#5yhJW#SQAhF4!L%l=Is5>77+m?e!2wtw<F@3pG;(|#N-cNX?cQQ@q z*(`_h4vExxH`+K7i}UkzIzk<nvaIB8n^D|ZmDdL9lY?=~c?28An!dD`vG+{RE1lIb zD}E)n3$#s2TKc2ib(LX517xtX_eaAIP%A#OIHOUaVdEshPR}Lh77Hcj%$J|)4}zWk zGt}Fr&rqK)X}omTrq+zig67;Mujj?jv~T)8FTTef3T<<X!$7OS+g|j<gJ5%hTYS^< zws@V1daeGA&q1{r3>OD%(a2AM44F2^x7s&NZ?*4#)EW-1_rSGW)A82u*0Au*yp;TM zP_5S*4y*T8vbUN~-VcIJ{xkRQOG=y;khk&W^oZpjXZTJoN`W;1mq{!WOnj4>mbyYH zsdPI-9%za#WkJWT6%DsKb`__V%-q;Ef5Gw2?;zMJ-}!w?|CIhN_Ad73{3h`Q&me0* zisy=V#)Dv!d6T)4o$HDf>%$i2=q_-`Ulh<#Q=YNnW9Jlb_iGWy7NLcyjSWeuOESQ{ zi9H3nk2@k3?d^U(Km2q4oBYiY-5T2rd%PNZ%NthYCZ@DB<ga<SroMYWGMx3ldp!s? zv3J&YuYH)Fzv<&@@rjjrn`PRpc51fQuH|~NMd5u~dv1q!mqTMigU6&7jha&&i%Sx7 z3wBGEXJqc((4E*N-|;Igv#3cSd0RoVgWfiari?E3%$%I{g~cUZ3@I}_n@)n7s-T8t zpTT;s))SyLy`{M=6Wf<VdhT8SJN|e5U$A@unBN=^7X6i!+NzNHvZS?Qd*h_TZL!-| zf#>J-&gUg>cSvtY=+^8En0yno0HS9?LBW(2`HdX<nQ4uudQ);!Q%jl^@=G!rHnq$L zkG6kr|K9q&{rmpZ!u{!>(I_x}y#3YM%!x^v6ExaxHf+*uW8QZlxhS(_>c_l?oeYUN z69iH!`yxt`GddYNo3l!1?@CT=?CASYo|suOpQC@z#K11D$rC3Utkjr0VUalmwmxrt zu4FgEe}>n>*ctBAOIsx8A8d4(cf9*PGF(;P{T~FI#M|U2-!GmURr#>AB)@AzW^!WA zq=@9yuE@^jc3-_?Mftgt7w6{Zu85c%G2c72LboHoZ^mSghJ@z-dEnXxR`rlt>p(M2 zW=Um3p^bi{C+G++#|De0nGJKA#G3@*)ekr)e98ZmnwQ$(k&&8N1g&&3G7I#sXQbve z?8q$s0B*g$Pg7`G-n5{N9|D{IxAC{mFj8PTJpFB(IRrM@x0&00D$Of?Us|Hm#@PD3 zpzQ~EWq)Q7sN2`(oSBlESJE8O@Hr3EdwkT$09i7dllm;b=xcGqg!IJByqE1iQ@^Js z>77h#Na_F$Fn!K{l3LvKpt$)|QxAC4PA9ZjY33+zp5LO`%Kik@+i18^+;A$bCj-*c zdkm>Z8y$2WHvFt?@=VUpO)b*vWJ9mSS_EL*n7Wtt{O*xV>ipmN3%T?+(YsXIexvV2 z^OfYplFW7m(DJ{&MH<c9njCt{n|Vzpu!CUp^$F|~n2R&h`=5hgb9r-lTYb~|wpz_r z|HgZr;UL)LKWYD@9gck&9r+y@6K~{!Mh8+;CaeY5PRSV)Ehn2aPi^_$^1bC_dwpfA zdt-VF|FnaUBBTF9TFF#}$<nFK`e3M)SzKJ2n$pbPXy44<%rMEn<40Q*xFOx?X4L5b zYDsr4?_AzAziFnvV$79}6D@*?dC9Z4Hgt4eES@xRvP5Fn@yS|U<z1!u$;qWf4@;h8 zrlqydXpSh!%uOv`(lSf>V6#(dCr49%Q&;1O#>y{-IxkC}r_L5AF3B(Iy$;Ie4KorO zH{_)^HW{`ifpX{^ul|h273GPQjT7b-w6eD{HFg?(Z%Is?XwkM{p$cfct$0a8PRq*P zfP8TEoSLF{d9h<+PNPC<cJbqx1|=D##n1B}RWANf(r}<*MvHcdk)onv@Bbb?P{VlI z^xnXp@AIF}%<pZV7(V}r>HOz8pk>OP8pWjr1sx8(k;x^Q%Nn}=&v06hKU=+d`ht8A zoOmBZrU#d_b1Vo4!RGk3_f6B=-Y*DmH3#uKk2m>G+dgfBQ>6l^{OXABh%fGM=$o<g z!&HOy8ymha>|fYFNq*vi8J8w`Z0yWyawz$kTC&I`WzO@~ei&4;n<H70UoyF(Prl`P z%jJbilV5InIIE|nprNpM#)1hQv!p<q-FN()Hlet+an1u!&!p)=dqvOmo@qwlH5u<) z`yn)lY>sd5Ulz0A@P4L}j6D-F@^iXZ%!vSvFtj^#ziijpYu?6Dp16=<e`kK)4522@ z&i>B+rXBg~Rg+R1J62li7dLH~7ul7y#9)77lSl7+2<+TH&A;vYH2=AVW^>Kk5_=vM zfU<O-!osiRQ`lFXS!1*Ez})#W@|*w9o!`412Gavtta|r@U~_tVeAE2)__@nl?ICmN zP5u+6@BO%bLjH!x4c|MqPrtj#ZKKfK{JHsavvqdAnRszVLTO%N(oDwu{`38(C)`cU z%Wv!`n(@E={fz&h{aS7LAQFO`)0_A^N<XJ2=Wkmv<$Bk05Nw^^Ti<lNw|>e+bG@T8 zPHt@OPM;z^MPLeh-}z?!DeN8lVK6g2d~Zd5IfUDs-qznVzpZ}?d#inCItVuTcTex0 zu%xM@yrXpT`^oQgUY1O{S6niQVT#!14WLB4S#zmk;#){v)g9P&e$w+UeGqK*2ayom zoZcQj>G`C`Czm{KU*5hjBe8hf=cJ{Iv(;y-@9626(J*0lLP!0om&vI)IgJfFtJmo^ zbrg4q!(bafh_(5B2Y&~Db9@JX2XAXBsPmCp()W3T{UrWL{Llp>;Nl)~4kD-*0qJsp zHsgcO8_F-TRZ>PSmn`(oK+o%VpY{-(c0pr6nR)4;oCaM3QmLR}qu-<mD*Fo>Vw&xh zOqwl98fG*(C8alqg1am&k}d40gB6)6C6$o&QA1&~UK6;^XwGi~ub*#Qtl8?`cn|Xg zh2{epwo0A#O@6R?B|IZFucIO_wY)<=vlwzrM2gPKl7>o9`H`CP5_E=P=cD}moX(SJ z`9+N%z*~SybGt5rj)61kTn~aR$3Y|ngPKomS3!v+FQr)TWLoPk$gzGe5{vU%Z<K(R zho+Xb?Eo!=Of72H01Z7ps%$LG(`j6UG<Mi{19T8#+lt(RoXSTHFF=c6a&l5r^m^ob z<l9ex$iD9&ICZMI-jURj#LS%H_j#Z5b5pxswoDAq4{7~S+*XiWnv<DWlnGj3^RT4h z6?j;vw*g#;Pn4f1-^xBw(y(PkEB{3GuJEp)kfsZX{Q;@D6FKwqI%gD><}`2U;Ar{L zk)4{?D3IK612paTFz;zaW^u`E22izkB_p-6u`w^dq_GfOPIf;mpTd}ySybG-WAehr z&bGkD6+MD&2ihtcwLqt5<u&|m_iy*;{@?b0hIrd|5LB}BZ{uuhHflYPqF~x~s8v6u z>wEKhWY{&QslKUV%FZwO%{y}w^GXwQT2{=_nKET|Lg~`3sV&n^=6wL2XPKFt+9=Qz z0qSlvS#<7foKV!1P}+5(X+h%SjQmE+X@;N;#`8-jzHHu+39ii=e$9;PPsl88TG<rP zk}&zre1VSHo$Z~CEnbN!DNP0WGmo@AZ+qBcTAZ0a@#RFJX6wwdc7fLu9yAL~y3p*? ze4~}UI~)O(>>QVV$Zy-x^|R%C_xhFtlU^)uYgEkdeAvQ2-Fd->qLQ~$<eP+&GZI&< z=rC-UxyYwHBfs}~vy-yH)3mhI-hi^yz7sk5`NiD_8)u}XCTA8edRUNO-gu*7LPp}` zt{KJod7yUVqUY`37d>C}yrX^5bK@O};Te-=bzAg#w{e1cugiUt6I&VA*MP?57R4`$ zZ>e7t-_j0;O@_-07G|ufY>C>`+V~NC_`>}O?#<Vm-6y!uo}ALG+rDwp$(h<S7?Mki zlKP~Z?@!4}ybN0C_9->J<K)DK^7S(&755sfS(7{U#zcm>Gx9+vnC#MQ6iA#9n3KBv z)sFKW`*)lN!8Z3D=Xac`*cOpI<-?BsAlSs-;l5)>0eG=<$>far24zhKQ@kg)wy)kV zk+$e${?5qu=;Zv;oaq*c*;6I*8v@$z%&?yt-pkOitFSbG-iN94b0;`9obO$)v{+-o z16!rGjfgqdDH&)}uIZ`8`sMj0y2U*&!Sk*&8V;m4o@hVbe!TrapM8E_t6yV&V}7UB z<n66>pxSy0|D5<K{7uWJ@ONgk=;yC>NSyp2vp7Fzp%-YUPFGh^>dK6+H=qR`Ya`}3 z7pLZ}ncGmYt7!LU(761f6OhK+JeA_6$;(o5a&$AhF6{l=;=IXirNTyz#s#T`rKvL+ zR#+Ej<QJ8+WP;|(^$QZ$t^jS2Tv?g;rcI%w$D_|;`IbdWO;^?hZtKZNY`M@>2|6nw zIeSt?b4F=N(}S5(c~A3F3i4ZC%(R}vnvz<uQKxhHl2gqunmjsY%>A2|-(}JIqGZj9 zc8+bb^V3?Fwy3WYY+I;Xth@H!thuU>bJn~pX`YbQ^r5Mv)23r(^Ma;h4GExi&I=aJ zo<8qA1Wr_+_kP}M&~U6{t5fre`Qjkhq(9kT$*#+Png25XF5j)JmEhT8(2Vi>=HspJ zTi=3*4nRX0t=k*Fw{D+3quZwc;)EH+eXc%B`*j)~q%H86?9e?Qq5?{8^--{Gl4!lC z-(V43GT)$09t4}>+vJt(tXA+ZcVEH3(0`#n$n>V`D+)@BrU-&3lzbB_`lNyz8<`F* z&}fa-ZN06jrD3S+6Q?nWu`xn-l6%(%O-=oVkD9GwZRwz8xS;(pE%)2kFWWOYeR6W| zLC{QgWJpoztb~~f=}QHAHdHpef=rUnah&@hw=^fQ^F9c+<U<en1y^!PcHm`^kQxrO zWwNAU4)oAp(8zsi9^^dB@cfY6#0t<!mLTU9XQl_2<R@oqYWc)zfP&OFu|n4nG_>{; zRKEo_q$cGwdVrh2@ENV<29)D{T5_AOD8p(f&}d;<YSH)9*LnHn&+>~NK1)n40j<V> zc7U1!a&q1^MwJ$)K5Qt+PivG&&1`Idbypw>G!xV#0BzVfn4Fwnl#-d3{w4oNX<kxd z5oocnolS9WlYpH~a{$VT$QBj`MxEO`x3nH_JpkKbVQA372H9e<N55H7=Y3wwjntyV z^wfsL)R)B%TMb(hK=WHA4GN!9b6T@AG7E|uE+!V`m*%A?7@8VDj&9OBl-eek+^CUS zRMuEf*3{71&@roFV`fUnhR&kq={lf8o0=qwiW^omMt8ibRA{=8*m0mVucT8TymLij zUV}nTa%oFI%ZrTE_D5ZRnp&GXk{V`#wv8yXuk8$<%vM~`RFRb4*$Qqon0A>rY(XC5 zoV+8kEWIJHE3Qd#vVODQ#OD(qD_Av7>zgsfeu_E>w)W3}z^;}HGb&9DG___d3@oYC zZ%CLif5!aQauC^4-%{VPzHNWoPXE#(&^C|8h?0yRB~aNr@#TaM$wjHXnu(3zQ=T$Q zDtlIf4#4SunfkWhV^YD)eT_3pQhPg^3@33FmV)LFiyJq+$xJG0T+n!;B(bRSb7k9( zT)i`?C7|X}@#oa8h&c-;CrnfX?;B|fDoC8Yp-G@)^24bO9lgyHTNNhXD9LD@(H+@q z4uT!K!96N@rTHG2>3KaTdN!o?%&@_+KxL{2q_E7*uhc8ZOK<FG*pS}1qdUDjy*t5i z+L!)_>6<|%U&h0^0nbYFlIPrP4{r}otY}*YI;3{WrwQc~${X@0+@Em2{dm)IP?tNT z`^8!X(8&yQ^&r(p_lES=Owiip;=T)csfk57m6McbnNR;dw;lwW|Ie+TTip>1V$a}j z{NDP$qa$gmMruXD<chqK%#|K3-y7G1`<dTczBjXj`kOtk!K1YQ8~?ZbSF)RaAU{1b z`9=SW%*|h>UjWTyPFtCsnp)5r4};C=Fji}Pb9iffS4gWw&YTks7F!<_XKq@Pnpa#p zuc5d!ZHGi=x5m_jWfkd*3>P>|e6UVK@5;K3N%>{dbBpIIEDUIGY*cJIv2Y@2Tjyk^ zmhkrF5ZJmNLc__$Y5DsDw%8^v4__X#IHTc!Y1_|+h~1HMPZaIA*sx>4iIoYZDeWib z2{gRO$;?ij!qBlJY1V|&r4<=-JQ_3h%v#J*Qn_1c`GLIrl4gy>u3Hlhv{*JI>Mh$o z&)-(baGw7>|F-hBQnx09_WG{#5ZIL7b$-tFIorFAgJ4T|*P(S^K!=VMZ@SojzHv`d z<MqZ%u=cpga{fl~rsuuOdzUn|H<mZGgO1HI?c3hBxmmn%d9!%4V3&K-@uuTVhfJHy z8^xQ<TV0#%8}*y)mFzMSb0!~e6>oapxWDQ7qMc4_0wx{I&7AyTwm`Sxq=dB|#l_Du z(<fz2Elg>=QJRx7rL(UfFLRzkVqVEqjVYI>R5czfNzBR4%-dm*S6SY0Ahoe$&xO=H z1;ZvSLxWbiY3X{0Aw&HojTgiHLlVo<pJ$depD5iPSx}T(vh7EDe*TOPDXEFQmHRI) zT=Ko;QgL$PVvnS@iYCLh=?hQHIFX#6SKRnuPQ<z!bN01PEJ{slb?A7|u(l*WUqQD# zBXjnSOvuFe;>*eVI+iWmsF0JmjU%PyAZSNRaZaVK-ig$_<n|vs<afxm+Ri%<I*F-s zVdA5ff`Y`N?Cy}ZOMT&;R?QQ@v-1<I^4fQ#f|e?770zyGXfIsxuQ<2iz(S8%>*s!l zz=`Y-8bVI`KJ`*&u};gbr5u?{fA&OlGj?#4=5_sm<Pykk0tMa7lJ0``hQ{JXhqOM) zwEWV!4#~;+xuB_u2`kzQ@)~ZGrFQRF8d;p0Tv{~AVNzppzr&QojKoa>#S;(Y^m=qz zG*()zSU<}HwrsF5VZ|4t72j8U@BH8SyWQVbsd>l5i{R>X<3C%bLkmo8l8R>UEVAqT z+OWQ1b#O@w1Jj`eF`(5N4G#@k-gRwnOlUP*XAc^*ZrR@b-)>jrl>8~#-E)gl(<goG zc`<__f8)#Ij{hJCI(r2~xA=Gb@A#$BzE&4Ju>h_`E5UWO2CQDxH`R>OFx3UsjE>-K z6sbkUnwt8J@{LlO=u1BuKA_f<wxA_=@b!-1qxdmbet>!^pPOYAY!yrmzNdmFtscVK zvYGjL@6)WB=M~u5G;aqVBQU?D=|fd2Xa!5_#ujs1CFFYD#I$3kp+Sd#hrfodW&3*w zYzc1(Z{FYjzWs&c^Zfi2SpVZ$eo;e4Q$j;UUiz1e)Q*g#m&IT5!Tt5j;#7s^r)}@s z-hs}ne3aho3aOf!zoS-7?e6Uk4V`W0nj+iNo7>vt+obibWF$hWf$tfWy$?ZMgOt>i z)(?p#y${k-yTJ#%H%q+CYug3x+qE6&{MBF4Sdssze?iHc)WqVFj)>Bt&n+K{AC@Op zf)=BI>ely73`Keq;=7N7mXI9pKHj>%`&eF+*7v3p%?Chb=j5`)j-nRNq{K>{wvM9I zm)#CI`Q?zI%3iCs*2W)A8NDwvOBxG6)52|zjgsxp8$n(98O0?<sh|Ps8U6fuC5;Z# zH4<}jS|;W62b6Sr7v-1F6v$6&D4G$IRM`?yTv{|yyEUTWVe9E;ho*};jUJ%0o@RW2 z_kf!@i<=~pQ!~qY8G1s}GK;z^3UU(LBobRI8b9>z%u6j#P0>44TGDr*Ss*j*QGUro z(0Z@DlKza2gULmy%>pS8^HQ2^8wz^OKbICX7^L-eHY%p&=X6=LZfy4e%^()*yy!a7 zd3fTBrcaGC+BVuBs_eK4KE9}N)mzB)S=*1i^o}i=xvAY9ph@MnhVuOO`t~ZtiS7_M zD_?15XVS#$6XAucv7UvV(ewq)8>jx5s+m@lnVOffpnt)0NHS~YpK@QxE+oHkLQcWg z;#nRYfm4q6{hZR-E3o3jY`grIxdr(P4s`tQUXi)zK*#@%--&sXUUbS&m<k#`ZSt5c zl-Qw=m!8v<(eFL)XS)NqH`P*=+<T!hW5Mzz>JZpozeIhBN@jXMYu6HX5NzV_Y*(^- zm^M2hrMR;*ac04k&Q^nr#Jp(@9S^!RlV@@_I?U+U6y2CGCn6&sbhu4d=TwE&3-a?8 z9fu6ZwdA+tE7^H0%xdvYEZBBn+Jkkzsb%>&rOn^B-EWw%L#t5}bVh%xT>J5EbqH+P z4xvG0b9&qU_3AATiYML3X?dMIamVBr%VsWkn32COW4ZnOz$JMLH)c$hZr?EZdXwcs zujcFR<`CGb51~P1b9%e^q|h~nMP-ROIxB9bBvuw%O~_v`VZYyg^9dV3jh%_&O3MWx z%W>D8fOHL)Z){kUgti`ctw(xlaf3y{6odFSgZO#E;1<t~h7;*c9IeMeZQRa<8(G8i zL*`y8N}0SXzpJBTO3$YK<vkbL-Zh<XI^WT?Y<asJsLME0yd$xLeWrNR^4*s=Ui_Sz zs?*vyvvkLd{MLq!1=;J;x4$ngNL@T*hy28cZIylX6YoP{%X$b6BAe6Ow$J2iJCIs7 zW5(hQDIE)n+8Np%@>&ljf_L|VcKEtC+as~loA~>tW%Pol3>qw^YfN<5otWP+qqwvu zV_s3WW=^-p#v7{=+ANaRugL33nzy6j#=fHBeOr2eE=ym<akA${N=oC8{Jegx=2guW zE!R8DA+Sv!LW9WW^bYg+e#I@PbMxC5EZqtkegbc;%iNXF@FR1R#nSr8GYay{+bq&& zT}Um;sce$oxVc$k_l@}s9Ubkpn|>s3`myQ3rsW_wb2_N^rDV7IMyo+$g97Ae%<YaT zWr=wu3upE|OwTN9e%L-AJg@e@>wj}QjMeqOIlZ-i&$P+bs{+<9oa>O6{{?jVd6!4d zqr{@3%#FA5UzX@}RO}7RFWtK`KeHh+?OA47>KY+X#|?x*MYED!cxuCp(wsRRiA@cO zImMkBTO*$37rk$ASnQD9kkuDhoS5DGXuAcdR?RG_)H~5Xp=_q$(zv{@c{3N}RCdpt z-;lVpAtSS0p^g80M&`By<uh&+mS)ZpXqr^nthJtDZE}9whY2@|moG?5)jK@dt7%nn zer{^Z%h?N)b}r0;Y)|}9l%Jeh+@et2`fAa`F0I_wlXL&1R!$7sz)_T%T++NEv7q_J zhNR{Xpbo>E%w$j}0J7sgF)szuM|ziEo(M|n-xD)Sp5+&P$w>X4nwp*3s8N#tG%qW^ z^5LU~ANgs|ic%pbxa(cXC@pR*%1lX3Y>Z3<E&YC<m)ejCDNY+Nlr$<e6*m4zElVw` z{GML~+9}p-rJ$RZS(f^wML`#|%`P>uF(~nSMt&<ta$-*7gT$hygV;~h!*UKSq<f5O z0N6s$xXlC9KYQDerSqksv?HUnQo&w9qxo1<KtoKkypl<?L<#u7mApsk&7k8}Ow*cw zHa|xl>@Chr2hXj8rU@&X&6+$LESeTJm$&tUVYiM#YdB~bJ!Gc5X?<&WYe;S}sNvG; z4?0@0)xT+Zt1oy=xNkiOHu*Ps!8+KWZG%%AK-Jl!$tTM5-zH|}Jt;~oPfASAo+>cq z1ZWO@>c+kUpe+laV<#qOOt}P#IdK2%dTP?-gA=l>T9$*)6>HhvvH`MZzBH$my_FHN z(X0IeY@=73eVcuom0M=f<Q3C*=H%#n&TkEGe36p_+A02U&P33r3uskV{5hljQXY8C z_tcC6aMje|(RLv;Z`Oq((BAsYvbh?0DYN)<GF$s?m5f^ZjiHk~y}{sP8*(aNmb@%( zz1Tbvw8N^+0lWpSBr&hWX#odl{-`KFy)?Dkq4j?96v+iAAPZYl7G22CUHm3#;l>WF zg8a<9lGg358}&<bKowqVI|$l^OfX2!$eh>FtdLo(vy=rku<#<W;lf16+{}`ejERlY zUh19gvB^tq*fA-gc<I8T)V$R4t^=)0GrLcuHX0_TmGo%L$e)pCH2XRTwyvLjeWCj7 z`ykj{-X!0C?919D|LMt~1^Dd=c`3^sIxHGK^#t}@D4E5S-!72R`=a;s6t&4l#RcmO zb64zWJlqkv&a$JlaYnP%dd|kiz8eh_(i<gbrzDpaHD)AN>K!XBYDsL$)agFZQ{Ge1 zS5cDD5<mA(=cT68X_GbD9Fh}@Qgc#goY<Vw?3t9>7XaGeUc8laX5g${jpA?D{p_#F zn53Ya3U2pL)htLYN=}`*AZ4m&^0dJIj@-oT?Gig4q^9Pycr;|RI7}C9d68VAcP6p8 zB&Skm>Wz6E#reB3@+KK}OSL|0N|@f5SX|i<S(MuKTJJ<AXojKvLC&m-ZiU3Il}$-$ z3pN#}mXzc)6?B~FQk*+$_N4yvlkFjJqWWa}$##&{nUnQFu!(=N{$!0M7aPS}$|0~R zzoopT3_SJ(s<&J6o7h|OcPQqj_MFVmo7^z53e=Y9IhnK6W^Tdc_W7Tt{4lXJeUezY z;6md`(AhnG1~WM}Gp0?SnU`O(TI=b=CcTXvPg45~`W=f>8y9b`n&pyPnw+tANn*)n zsf_&ciBjo}6@ATHD;jst<XNk}qkXwM2)2LU(UO@rXVpBW#8!di$rG9jCKq>1S^J<Q zGp}RC#_GoAjU6ttZWOg_Y7c6;J*P0gv?(L6vg2mb{DQR1k|u`q70fdpbOug8wRYw7 z4GlNi9ahd<xjHc=rD(24=c43o!qc34CU&<qKWu-S)Xv_{1nb!57OyDnv}=s-i0_D8 zz~8K~RH^0Q27#i==H@vsQkq}({#YQ?khsk!IVUr9tLEkpsYOi^ZIhO4YIu>9Gv&sz z8<}~l3>zOOPM?umkkfc6IlJ#+;-k`%lKf2)JqwEW2^1xEJm`^FuyE<dMd~Y0t$DOx zyHQ}5<ARFGzq$mMd@L%>+a<MAw>6<)@rn0M3-Veumn~R3EhE3}<+?-dkEWk#WXZ@Z znCuRL^ZIR-=C16n@44P{5!7Hb(L0@*S}>`#AU{8+c%sIP7p)1IdHo!@>xI*ECUt1^ z$<LeLoNu!5I|#OzFZ{mnbL$J}wAUhb5NytGyWX_C?YhpCZK$h^mfL5hLz)oHP#VN* zd=4T(xM@A;Ad%c+#402(%UZM5yzw4rC~S&)lmC4F<w=ue7YDAslAN>tLqkDn!5r<P z)b!Gv`58%x#j|!S0c|H)voJNcF(E%aeQIW7#=K8c<r{CTy_mmdLUHLF$yJrPiOI_z z?0(UhHBW2rhU8|3g<J*s<*Nm|UKE#PZZ4SH(82*)+&zCM=s2+1%i9s4q4h-z$1;JI zip;G6nJG&(GD|XBrWS1c(c(E@|6##;iPaHXd{Q6h7ZrhfnW@DE`FWtBP1GSzQ1|ak z{wMId`!5-(pEL4{N>YnUK<n$l7kVY-q`qwU3<~}48JP_eK#ky>Cc&nIiH|c9^O95F zr@c+gZkP$W1*Yji<4*A8S))K^9?_NKW3;1h-13W>nn2Zu&im4$_XU}GZ2{jCiyKZP zwr(iTf7^H?qxd_xCQ5~Lxt=w?NNk-^kPo`DE;BKwqcpXs@kRc_^rF-@j=Z)E&=5qY z<;#@D$dbxN#>V1Gz3Zt>4#oM+EAmQGQyMEeqf<faxm%2z?<W>lwy<_Pr-G`nN0lv+ zO;M1-#-jN|>wBGtc`46(er049gU)#A4Qk^o$!PTi_cBsTT3>c8?OX&|b!gOusI0qu zAsyMS{|zW(tUU_Q1lmy8TLzn#Z4&S0)oDqG!KUz*^p=$3%=DIc5Cl!Fx5Rb{p%rGu zxy6u@40OU;OYZdj5ZLN(tJIR2)YRV81k3-RtYoTpuq;1w-l5_KjX4V@eFpCW1kX2v zW;+^wmgG-5k(gIGRU^M32fV9FL8E0_vqJ0r=C>xD<{;Rzz0<sRS#Zhx0uZm$yg9zz zy=i*8J2*#l$%9~%e-D2T$83+}<rC&L6wOYUt2IBc3_Jv`GuI(GW1e8~qQqqf=jSMx z8gwoJZ3$0pY|#0h`nv1HqV8vj$%}V1br$C@u;`I(GAb=@=*Tacr`cuEl(2?<4Wr(b zWf{=f<;EY$OIGHkF0d%dUKN<1w;FV(SY}FT!-WM7pwaYcI}BU)*%X&{R21hfIACYf zlCkE(+6B;4J}eE)4Z7o}Kk4}2?Pvr!<-^dh>sy0OV(-qT-TKXndWTXs3AG+bEh=l{ zDC<1X5wVQDBcm;~-F?l+ywc^X`k%M-L+YH?d{CWJ4B<4#Pe@;IrR#>Ffq~xT%&jvU zLFdtd&!%hI-?D%DcgQJq&GDd9>gH@HewkY^sc}Q*p3Ihl)<VcA*CvMauEq%-X^ELd zptbqAnOhWkyizh#-sSJ!ShkNLGd-~+^;v0Alf%xHjSDtTTT(tN9t1n)&oytoKG%Fn zq1lr1Hyr{Ej=7n6`H*St#r5<2o4zlu@9u}fzKXdklJ_b=c+K%`{!P={{1?}^ns=&$ zV3U7edS8NPNng?a|NDO>r6w<wOzd+=TjJ1oU}3S&{Gfh^{)PR)#U(|34C$RWL6ee8 zXEsh)JR!BopeZrAD7BxnDRIK0#t%)~mncu?C|$OrQLennE4^sxjpCeT854GPSL8R{ zEYDmTkyP3i*r++*pedp8Mqg|}V{`t?lH%oRNtMe5HZ!#zNCB;7p4C`Xy0S22#e@!} z@{Gzx_D0sniFs2K+Y%sap4$=@NzFN++7a5;-qz}o+QixL5O&1!Vy4EH{``6Vla7O6 z?|Tpl!Oijg?-#So_G^EU*&_g+b?*yk)oePlc|-5~cKP)mQfEm`EP9h#+_<szLE7qy zrzz=82H=snV%`1PTTk@~&09aU9|T*Mw=P$*3t7n3^1Q{d`9_QJ#ExnD1w}gyngrT1 zr!?fQmtLwh|M>hvl?uA;Y|}PRJhv&TBtL(dLs6S|&Qyhx%%+0=<BhetdgoU(w|l)v z%v(Mov!qqORU@OlqSdrG|6#+Sq7@!RnR}UbyRTY1JAWoiNye@Z?V3}|r<H@wRD$5{ zcnA$5K_vi)Zns!?zvDzvO8bQNi<4*TEZo0QFn7Yth8xM5DT|c50{Ro?%><3nw{Ivd znpX=dXP>rOX6Cj!OnMK2t<zhlE7^rNe{7M+%mZEaHs536iDt!s#G=$mllC}(F2A%X zE^Yb&J4$r=f*j;qLXC|ry5D!dX|7*q2+LeXtz`{1iCrJTnak?s)P|DDD-t^^j26$H z@-}^TWO{ynN@qY`@ifa;h1SaQ)Fd4Ri>2&S-5alf`q)zv=Vs*>&HX*MXu5J@Ugb2I z#>q3;8w*!7Ob?hGI5o6qb?=AC&)fe`ehz{i_w$Qv!IhnoavJii7U)Fc<kY;9hD7)P zDrl^+!J?!gv0-+DA$leBviJ+=sFbw)qErP7167@ed6gv@nR)3Clk&?_8$KkKG%QGI zw0r_erFoDQ_e~k4IVq1C74q{xr52YIWhR$oHZEw&K&<xvTHKhBSe#m{cO7(PAZUa- zv!wEUX;I^Yf+mlq1x0x}-y1zL@*68aw^vkv=7>NwP3rr!mY;g<C|8=H^)TB@AT<xD zf7!v_0dMhvN_=zhY3(11@=H?NKwGvVS}io1(;7c?={M~)Y1+~Cvpeundec>KHPt+` zxxHayZ#&}x*e<8ub`WfiZxe5t-X;z%<U8JjV3YrZ_z4jq850tqHDGGd=YEfr;$DgV z505fS-sin6Y3L~Lbx163Nci4hk(iQ_n({EMac1vI@HlLf2e_G_cd}%%SbspbY-13p zfz!A#z$oA)=nR-i44@-m8UqqRi%5%0z*SVofm~335;7AoNig+A;*^5?CXLLz><I@G zTQiC#d!$!3UTduRT$-HGTA0xhp_>L;yq=nuTnU{9&d4m7dLS>gJTa%iq2WPsJBMzj zUaD2ggr}fhf19^XLr&VXkGYw7r6sAwy6=m==NC;a0JnB@UX<pg6s2~qOlucxIMK9j zu0-RJ){AL5`T4WDJ9P8%Q)c|_p4hr8Co{LZL#N^K!;S->g^V*kw14V8F?&YCft=Qd zZR*XHtyR4hd9!za?_thJt(+~;5RlWI@S!v*2XqEQLEH9b$Mk%~D=jysxKD92nhv@i za{i>_5E?`_$4@!FRA$QZ$(`w~8F`(LiW@d8c++s8NgaG$W_@dYbA4-lYxT?oXww4H z*=-VU?N_qH->m3-w)P}yv!c%z(WvM+KI;PLin$U{<BKDscwPC@4)DpOsJHSiYd2cf zzO23N>WT>~<5$M7j4}aTH8bZ0<T}Xp)^lzY=jYA*06N<ZboPEpCHMr>`Kx9cHXmqF zU$wk_e)}xP;-`u8B9<#AgRcqLeqnAwa;47vdl{<?r`@QWw-J1gMp1rVTf*w1g4C7| ztE_fuG&-&lXyaGV2*?lDY&=-Lt6}G6r=^X_87nN-PE1^|ARTnd|D(h;J9OSIx}4qU zky+xLpP2`0bu9bXGQDMTL&l<lSvQJPOBAe{9);(J>{VEl)wXMub+bgll8Ds2)`mvV zt+bhW=__XBCg%0qcj<3A-lYzLTaNTRY~GQVywtPt!{^l0+@%XMa}!rzNLsmIOGoRe zwI}lOi*oZzi<=_yir3FhZ4)TZ$joWqmE69gtF<Vx;X%iP6&9VKLlFx~OIlABbgU?9 zn32;P-Y1Z{*`RUb;tiQ8i6xnhGq#>sVo{QjxIHK@ziHC;v$^@J3%d(JXCXIftP$v9 z2OTm~o|%`|+`#;(VQyDx;|}oFf?WsGHcKReTKRpAiES%7IW~RF%xzZiZTgVkduii_ z%?0Hd`5hAL5}S9nrMD%g_gN%1GUTOXCMOo`Q<}Ulr{O{VUc<@VJsTz*aNKlZx5EC2 zDGvF?#hFQ+KT4*2C{53pP~U!Oi$;F=cB5HQnO&8$>btK@O=ybjKGAl1dU{t-bMMX# zr8(UOyR;e`8h7Y72Xy?HwjnRGICtBMr7PCo*fb+8vneB~a*9M^N_%AE&%Kjo2sO=U z*PLLV+P<S*s_)Xf)V+lr44s>rHk20VmgMX9UFiH-P`S^iY5L|9yDt<JG(KqcYu5Od znOfeM+hfq4k(avMVy?i1MJ3HasVOu35pYpPlSi*)aY^Tj^cnLP2DEAPSaxkl@9*l< zN}Qn4{1AM}-=xA$hgQx-5=$KNbM*FGHY!Zro!V)TpF813&da6+c_q6YX3T6_I`v1- zqK?Ex4tc37A9Oi&zHH>2F4QPE`TXQl?Vy8cpjgSyKd&dUG$&<$MeEOYgE_VHL?-QQ zIMi1>VMAq0K=}fL)S~pt{#T{B1#^>HE_Q54=`&pZXTgE~19Ln&7;^H{I~eCAHm$S= zZ7kpXzxDj)|4KVwZvMad|K{I@;PWciHcS+3@z~NnF|&F4=JU<(H=l3*-nqYXf9K9l z)x7+aPL1M>35khM5=#=7C(eJ^;n7<(qrs@4GovhX(uUmr0~2;_cAsXn*?GQ6?$R5X zc}+XEwr_3PRkZBTRHqdRdA;Bk|C)m43kw@(wRiuR{35@!sO8#RhP;%A$(thkUgo5x zq_<gsC%}|T)^@cXT$l+u_q#Ep@4=KA#U+U)>sQRNSva#PaYf>GrG>k?4=hhC-rhMq zpe-&jWobu?f`Ue7>VyeR*Yoq*50o@bDqiok`htDi#l{Jl4L@~WG(G5>y)&R>{(~6{ z8y4)2YHZwcC_R5#z#M_%Ssy#hJB-U4IdT$<_Zt)}ewku_FuiEIKu<+eVUt#8VA_|A z)UV(=zXW_fIcT?a38-iKu=soG_r$!CFQEHT5=&CALar4}gr2*dms0#b@8Ks<S3R-l zQDSjsF{qCRx<&d+QDSoT`!rCs(Rd*vv*0sm|9hiGQhrIsOUPZ`Uovx3$?o6=K(F8e z?P&f`l;0{?-0~thC$)9M=lq<~lFZhMwua_MjS`^S8jG!(_k)K`o6k3&fDD`F=d{ST zNJ559QyXE&CpTJxYgEvM&M#nRCbivfyWe)xF|YD1=y0yQ)W@9}<wco|2Qu^80!lJc zA2lT=XC!uIX!M4Fw(B*V)_hdjccV8j2eiK>BfluKI5nliF(toa$IG;rB`^ACfbM9? z%r7l&^ysW8Yt%?=KGCeupplu}e;~E6v>~8NGb6F2e+TGVmgd6b)QJaL7(geJw{i4O z=rPp0((<F_LJny7zeA!~qWfb*U{MOB1K%*Q`C#hg$nyMl-^QR8t(KR~8SS9c&Qd2v z=`_A5E-lK;OK&(-nwOcJSyI`2FtL3zs2xx|b$5Qzq~qP&L5DfzWcDq$RWj;ZZrr!L z_daO9bHjNM*|)rJNpRbZ*55rhI^|0ev!|}^>hJ1l-(3z`?fN9OVD{VgpFJ0n=P;Bs zH5TNTPtRy<Y&cP#k)M+~A)@O*PjPd?jO#56a&wy`(u<lEQl8}(HJwPy%<I|;T1Yd| zvH3)QL|ST5>VgY;2fKwE4mWjxY7&jiR4WC;hBLMbrf)OzG#5Cz^gJkOnUI*0SWwcp zVnTm=0k{%uz0rH4zaYKIW7>zrxdn+0FH4IigVvrEL568sE=^zAyrV_GpS?%CA-|tp zKR;*D@qUd($9w%j`-mn8nD#aH-tWBy>)xB_8R?y$Rk&==oK>J&p?w7?JI`&YZ%|lt zzxleM;iUD=_nZAEs`}4w=nLqQnKmmoF{{_I^FUAaT8qqO3CkL~6$0|Zb=OGrE`U_O z$)%kq@{%(f4LUpK&RU?=x;Js|!<?Ln6BZOLc-(cmSnuc@k8YEG!_4%&MvLa6KFucO zmPG|cnPrPtW~WxJf6&x8Ni;DheQ`!fM(*OQ)HaPy$;lTAnty-}nOWjB!MrcLvweej zXFUii*-iW1biL{NWQNq7%;pEJ7E_cb-O%0gB6a$vwx%7N#rXwI3d<u)mOq^OV^&pK zY0k9HwvEdt7UV8XnBkDuy*Vj0Z{~*8Qca#|iOEYdyA$&AC#)<kZJ9AUprEu*iE-}4 ztofF040$C*n@-HlS!WL!d+sWj`E}2Qtr5*T=I$)Y-z72Q<U)qlAL%Uz`{p*E$je^& zXr@+2Sye}Qw>vV-X`ET!cxv*&_K&%x6FWfnBCmM?D%5q`If_d=PfW;cUolm0%Ks^U z^v=!-?~Yt0IN2jHud>aei2<}&w*6vaaY3U+QRRossgou@POj8V%Pi_+*fAruXnDos z(xe6Z+x6#z@%;Vm`{(bUzrz^RRN1*<R%gj}DFyra<@3v%`{$QKZ|4AA$2-Yzm-fyZ z844PS*@=Ay>8Zsfn$7z`urI%Pd$W39zLK45MdGA~J8y6Qk(tt*WYx5O+xhL&yUd%u zw=D;)*KB;y+;6MYpAA{3X#fI7=4O@+8kWY6jwU8%28NE7E+)nXmX@yOPG-g~PHvX2 zPEMw#PR`D5E@qCdMh4F2MwU*dCeCK2#x38PE!Tfv-{0X5nr3R*-{Iz1{4>9F3R7|F z9*60Q-K&aA5{qW<n9>BASOcAz)zGlVt30vzTk4dCjKrc<%Ai988#NX_EXmK$?pl$P zzmI8R(c(hT{9*n^&y_b89G!GxUEu<!m4*vX?)7Ng(RgLyiD~Wq?)~oV>^<R=zPC>Y zovg6UW75YKi`+#G3;Da2cl`$~ya9zp*Y>UrP50M?b)5j^-pz|agL{)d?%(mVOJViP zPV4;AH7E9c_>{UmMek&f$I1z*tCR9~WUMkMF5PCZihUL1x{R{95={o>Jv-M#B=%XP zCZ;SruzsO#b3<dx)81e0x}Eo@=@l1Dn30s;b`{*6>e|`fjygq`SeEXdnitY~qoJ_# zUz6k1{^q>S>7A21Cam0%Qmg|yWD$a!rbB2D3EC~uvOFnujb`V{ttmzZT>(Xjx%*}o zH~d(u(O1!MVr%cz7wb9lb9AR}pTrJ=&DWc+Z;qMxeCDD(9wnKHIZHE3r{3rYoM5ni z#q6JXl@E)OGE0gQ`!+NRYqUM@@`u2d{4W14Z*zk#eh_TD-e%v$F=au=)kc5F#7Rqe z)AE+`mf|u)JyX4k7SOrY(;L6HOjokgTq>NAn)fidq!?TUKP-Ou8FY?#x(=jbEon#q zpUDl{iv~K_bVh#Oqso_g4TZ&xoS7xXsX1vc)4pUh>Ng6Mq=FVOJSoaADE<oC1g`+= zs5d|_Br^i-n*>jTHeE=Et}#{yhqP(KgT|<aZOHw7Xi&FYXeeyDs*f0Ah0SO_%uD%} znVhN%zKBDw31crIbR&;JK}kz(>t&OMilnChP4LZxCVHSF#0^22^JOt;yB(xU^ANO2 zJ~c%Fev&xoH1X#2w)l|l9pE|s%w%YnzPZ0Qp%}cGAGGMG{lLSbqQuHZ%>r;UJ16x; zVsS=l@%z$}hMkEyISuz4ZtI=QI}+*?P-bY{@6@ofF=--qv*rYk&l!nEre<vd6^Wpg zPq`Bq8UwrjxAVgxNB+d$#U;Hfn?JUF*ZH3Mw(UntKx%1nPG(AGYP&>AW?5$O6w6kL z#{Q0~sUHl@TKW-C$<8CS2vmp6oH-%yX+>ggL8k*~*;tE0vwu&zxq*UJbNj><ofAQ; z&$=v{&lokIZ$3X$ex`IwI_eTJa|5PB3-tAw4lOV=V>+||w5ra8>Cl3f%9#pGhZca3 z`|141bZ9|-8q=W#W_mNzXX;PUY+2XQ-*UX=c#D2V{}ieAip-Qrp@~JQ-G}n?8Zvqh z6fH{XR7%S)EdrGxoj+3=7B@zwWu`R*BxfWRB_=Pt@g}u+>WPeQiG0uoy-5)z`3jZ_ z8fJ?gOcrn0k(Xbxc#)>wl@|XN|E3Rl;9CJ39F{w@v^PJrTC%-+KKNMF?H%Tz!%;!y zVYGp+W$cpmOV)R{H}QAbE7`R%&hlInnUq;FDQj{>W5C>7;0uy6^QO<pXxK3A_<TFi z9?DOpIg36_H)v#Ba3HBGVTwlg#CZ-=-23gPAMdyCNMG*WI(@nOawnti(|-AR$*Gh2 zCp~XY2f?Q69qCGT;k_#p-=?;4wY^BoFG}xS32LD&-mLSY;RI;CW9h_+X+^22Rs9Rv zPc|~mRZ4F9&?PxJbJB;r^hS}^qD3c4GAEr_Hg)TV<cT{QI*TT+$Smqg0PTQlI}d|1 z(|dL_KU(dOU%ul;b4C8!%)DiaZO{4y)8?LNpS?<}TdUP-(d{PoCWe&M4v8kM3CAZK z%1JFt%~|1EfZTjdE$Z5ko0_6`beZ)eg$?^VWty{!mx;HpSoNcQfBOzdi?uYTgTI3_ zC$sT0yt&%x-s#@yWN2VGE7QQx(8$Q#wE0_3X4C$;j!pZFoAyJXanmj%3k!1-h`<gA z1(q`~Y1(CAU}0)(0a7_D2t-1#dDCWdOEc5f@}~VwJ53>CAhJWJ>4T-AWz+tq9r~p? z)7DR0-_#F+cAj}NZ{}o9ZkTMj+<et^2yEKFYWk|lQ?yo<gJ9$PmgP!zGfmR+XIdvt zf03#?(=KIEXKvzx1KFD@W^pv7gGPcuxOso;^47%>k&zQh8WbTrL7L24-*1SX!?Vn& zEjhC|uc4r1-Tft-61SbmEhs5|R9f;WvEfBgdqLym?UL;biJwzT<~^VHV9&+P?HT#y zE7mu3g0AZ*nZFzYC$dB6M*B?@mTQ7C-m)3sw*JY+{_gxv`%cS<o!K2JiER(k`)>AC zv`;8VP0n0lu-qcG2(((hE2vSUG<T(8{{v8c+TpQkWhX~jYEfd&ng=N>EH*fHzUtUj zoY*)4)QC%L*^r%Dsnf8b8FJg=YL3L_NnQ6^HF7eGGxPJhZmizf7_b_&qx<{bL+f*z z&aH25&e}h{#cIug7RQO<9r7J=HpO;LT$6500-r?KWVbJWU;e(#=9voi`}iB}o7|fm z%QJI!&MHcsCDHk^Y~qZ`Kl01-b~R)cPTmpG(N)wnqlu$K2-Ik5j3_8b&D%C(mwbOc zsI9+Te|`9J{Rz(}E}xX&aDGyLV?Q`apNO24IqUw+%H(#A9gB9p0Ud>&KPh9*yU!(w zMJ0PR`<Qz87wJP_OZ+1JMcV5hL^D5XSQfkRKL|Flx5f7=B&Fu$=cTt*%n0gnY)fg= z)A^o}nUe~wiNN(6%61n}g@p6?81x#+(9$wmPfsrvGy>gd3EJmk2)Y@mVGbyh!K$T( z4$vTS>X(ev51?H3JT)&BbYOVHj>?A$mX?hgMXALNAHjYr(rY$@b@@tCK>?GK2|9%n zzG22z33ZsbZGOxAmYE?f9?cac@6%dVfr}lTR_4T_k_L~&l4s!aFpD3im82FmJc@{n z)OlIlkOZx@5_3L-?lo;JXjE(f9Z{1Bx(B7<0%$(^VO~n(!qU9V!qN_je9-FI=CjTL zq2L}``zO6CO^i*|4IZE}t0=R$Q=u^<6;z7kJ;_YZEGbsd=<e@(4uKv1eb4(I8yFZg zNHl2m{RhD&`L1*&J59Y~?T=DFCuXO%W+s9*xF;r8>U>ZATHJrSOCz_vv6G{rsn?)u zM{#OiarcGHrUR`z8!Pe}b`+Q7=chdEe()$$w{d0H&s0zqmec7F-c-;WnVHvB0a^{; z6bU+ouIX~mjija<Egq9r_uTHERGL$gnU{VcKYTKO!6g1J1JJ(SZrLu&qz?NID@1q8 zMDIfD4Nz~UcN4fjm)ty|a$0&<T=Vv+y9}Enn)gpV-ksi^<eFHNli7BoOKPIT)P&6B zoGylLht!IKoW#t$<`YvtO-ll8l_{y5CYM@1<x_TQWtU-cYQgj?#i^4OT&7N#ell^! zBv3AR-?*Wu^QCT5V$)1W_pCpmC^auRGqt#DdE56n>)YOgAh^<=ekdcqyzO)A|JMJl ze`X(ONLa+xCJ4S~qy2_e3qJzdd6qQYOi7&@*yXk4(Hx7U%)CjT=WZ;|Z%Jy+Xp+h+ zE-C8X(b)m2^yjY1$;@qdkXTgtDL*H**s43L<tnJHIf)TG-dNnMnU<Jbl3z4&d1HTT z`Kq1mCqdo0rt3|YGa5aXdK5HGZ}e}P-ZY{2Kj<u#&hL%i8^0^r`J|S##LZm3WIqTt zr7zjPWN$%!xo>9PlIbAW_`M~(<HF{co`l@4hKbj8TKQqHS-zFOl_#~rtv3K7)cC!X zzxU?b)TN5+AN61Fzub4Ki5;@Et<}FdzSY0gdjc<HmrE0SYkX@&mq%vNizb<^Dy`q= z>d)1mtJSo<4SE(v3y9`!+6gJY8=tqnZ+($jykPpY1&G|XzJ1#JY42P6Tf3Xy+bS(D zhV-3UF56Bm)tazWyL)>JUu*dsiI%Y0;gE6k&F@>%H^1Nf!cgz(&d1Fsw`(-#cbYfV zoAl&^V6%HqK4{v$r@o!P*}wI8Q+w-iB|DwDPBZwI-)}t+3JXwu+4Q~tukTc&H77Fi zr*V{R?=0KK09p06?q`o?@%w2%%Tn{ERcv=?C@3u5e&Ta}?jnnI5xWf<6gG>@dC}TF zw|B#i_VW|JcZ-8y>+){#Zehc&_aNAKzCC~Ki#ZqO2F_`p)4qRsQEEF!+k?!l29@2f zic9w$Xk$l)Yp>5pRM1|yt*spdoBZ3_x8(QV2f-Hm#_x?Eo!Xs?QWIxH<>%?VNiA90 zU6h*K@uL0JUdDZ^maXjD-?tll7|GhShbbw=4FwZ7eaYV}ow5Ic&Wpw$ZRK6!5ZHRZ zOB}Q-A3VIdzy193Sy`pI1;t+ro)zWyUC3+q$Zy>+{X}J}MS2FfNj>{Sen;T+9VKm^ zxsBDGE7CigCPvO=&CJbBP036wNu4+$F|DK{a4SbiVs>L-a*IZnL6>%F<Lr)Aee4hj zT6d^qH!Y#3eYP!V+OgR%?^9wyW=cy%QEEwPQC?eOyT_I%DXBS$)2mV|+Bu46SSI!! z%q#6PYV~M4taq}c(K0zPXQn{gk4BdTKML}TN}3P0t!cbIA-K5HwMnA+MWX;{u65F* z<iz5xn=O`2_RX4x`o=nq9}@FA7nWosHeYCZwCG}kLRx0mfwlw9tebV(1)4)vdhgy3 znsDoQk<z^4Nq%|9+=pr4il`*D2(+{p+_}PWwKHn@uViP_2<=IMx-*z35t!(i=o#vP zMw$~#UKYR1D@n~uNlkeKK1^dyNk;0s(%hsLgZ#9&sSSa}&+?1XGr<QG%vG>&>1&o~ zc@Bl)O7MM|;i*kO67#-*hAX}lRW^6P24WknQ!7e34(pxF`;?lPlUY)!)9|n;wJkF* z|9fI(<Hmv_&<^j^oJ!Dk&KC^|xrup|&1{K{9gu1N#FA#uj*Nz%>D?DvW@P53>O4wK zPAn~MI?(By3++I)MC5~}2U=#O=9OeNMdX36$!yu-R9f=Ap%HYaTQ^hZi`-_7{5((% zUy_mEC<z)7eAv{Hp4a^AL(7Kzyta<w#tYzrz2!kkW%K>!o1jxnlQS|?Cvr6X)B#<3 zHF051etvfGqr~Lww#1g3onFbH%P`w+q%>!i=B9RC=s(#xEwT7*X-h<Zcz;mC!PbEG z59OdU;+iYc@=KcxAv;js=QWG83p7{dG;Ex@x?wJ8cTFe9gbdKBRyuDp^GcfzrhZE; zs%)Ix<S<=*k~;`aSD&sv>H2i_>B>fWhg;ZN7^a?|dcL_I1e^X(JwNr-gq`hNpk75m zn?{;K(_GL^uPrM(Kue2~8|$0(?fL_{_#4;sHqI<>UfEqUxugGQ|M&bSsS{RoH-Jwk z?91%80yP=I)%fSs#^C80(>#l<I_2$bQZmar^*c3SE&I;;&PvEwbk7gi65dA3)=i*& z=^Ma}(^HN8{m1(cg2tL!b`%#ZypfdNxfjxH@12giEGl#QkM<94MTxno4UO$=O@R#- zO)DGbG^zLW+jYNfvFyG%oxSIO%Y?P-`+m1ggEV<M+uL?_#2I(CckJ(M?`&^44<cc> zJsrd<cAmeX1jOiUZ&L4U?`)VFzV7(ch()!l-!3m$w0zOBl+vR0zq<9ib-M1izi-Iz zy02fFGw=Sq`<?2bJ8|rs@=G%2g+b0r=`wH12eBq^2a#RoP3kTET?T7GOH84C=cas6 zAG&Wph-~Qx$uIoWtDKgZnv+tjcRge0jI_+6J`T`0*ski$-?#5rKdsTY@pr~%iPjg* z<)Atogj>#o$nH{G!?yn**ks=Jzq_SnJ1Xp+Ut((j5o$7T*}fqcJh#5YVE2|{$T_^T zIG5b&InnbnFMoF49{XA1<%;XB&lCqi(26oUx1#*q70#*KU!=6;<mZ(q7Nry`Xf#wS z8)|M@SW>j5vHw+KQ6{K?l(#dy>p3c%R^N3U1l#Jnu6H&sIXLy<&W&wnl?|Te?Fv}` zxXXWi)5OH}OWPN;&jb~wJ;}QTnoj1mZ)#BoT@nVut@R*sQr&cY&<t9WdHeeIl@r7v z5H_O?q30}b%?H6I_164N&Uur#QWrK9Lz}BsZR+48*=F8m085f>?QM;_+YNVv?@5|| zzQw)8DRb(1$gwgV`<voHtUhxP*|EP#y`{bbbmB$P&J`Uik}A(BXq0Dey#YH$W=%k9 z!R$;w1zQC}%{5X}>|u=r2;FxaLN}>{?#`VV)n?kJx&I^RE|~Wl6WSuc=klbqX`1@Y z)-IlUeZOK~y-{DiabJC3ee?h3zs~u2%?8D(Ih8su`|fvKhrp)&AR5MRQU{$B1L+%p z3w<TKC#lIrsi0LPk1B71+**?H5WI!1H1~5!YQg)oh6}a|Mhyy}QY1C6<U9CCu$Ots zprtF%@{2%mtf2iSzqq)uGe0l&F>F7nAmp$WP0$g~dC=~Toek!|Tizpr18<-e)Tu?q z&|KW~R3DO!o9mm@As*?F0Hufyw+_qJhoG=}Qd-pd&@>WSku^Qbf#2fL`oI`^i9<s~ zL5Wh+1jzAT4GG}$PgaC?7#5c%XFM(IYUrF%mRgjPSfJB!9|oJnVJr~cq~2<7*YYAi zr)<K5#NyBS3Rdm^+kfbn=GfUJ6*YJ?XqF@<<)n5rf;UN(<QKFqENU%RP61u+o2t|( z-zc5Y(BIIN)Dqvg3(^B<tM1Wkvu{4xvAo&5*|13;l;}G6J9si$<Xhw$zqiP@$n+M0 z?x+XhCUX!8!HwTr)LT^gw)brZ<-wNtrhEw95~*L(SJ->K_j;>%@1+!wb<Oh4@~urF zt@^F}P0w3FyT3s#V6GI<NL%Cm#{10+of4B0i$DWd(<J99Kg>&cnpe`r@v_U?Ilr`T zd8;}IHv5A}2yVRJs?G!&hcjrt4}neWVES$!YYTgCc>{Pzq_;%du)(tFd0RW^ti{Iv zjlZ2!b5b|1c$1pA@MO1qw=`%x1%f;66toSua2T4k{BLrby1euJ)a6b8o7*9<!_cT_ zf6xA=?>+mQ*g>ob(?OOs-fzC|r=JL7f-uwtVE2Hex?Xe}>UR6L*n?nGdQ&=x?$w`i zzGr?zf6M!({+{{T#`-4urv2Y1nK#KpVAma}Q~x)D_u5Wz2f<GFDemp-p_>cmx34hk zG4C;N`rc#S#13Lj$OqXEvU7?%h}C?*i5=k@ka)LGx5)}ne5tpnH~E9&Z;F1epguUQ z;Ou8N%?F*-7LozaU77iL4GAq3sn3>uNCA&*e=1$U(0niPMNw*+tx`rwNkOrdzJ7XU ziC#)+-j<Fcz5JqdeNflBSRZt^RDPa*N`A8bR)r+}+{9G^Mfyc)$@&Hc2A1(Ijg#Y@ zwsC@69q|E0`6c-+KjOm-4fS$Ul#`0$(+x~@Gg1>%R?kT*O3dwe-sS^4qrxdD-rc~o zlP|H+zP-Ima%W~+I#!r!)|TFuQkGcMR^L|NR%g~$-)P@f-&UEQ_N7n4B{bke^BTRz zZ3PqhL9l5OWEC2yaoMci5^V;`C`xuF;8vxv-qQ-V#N?7Lq2`4JZ5H`?(|;7FrhrGz zCmEDfHh*hs01d~2aP$7Q`{Ak09R)dE6-_@%G7?LA_q85ZGFp6dmVJ{dq~XwX9olf1 z)7+LkCw$g&$Q72|^NI^HvuAX`oBcVJ57Q=abgTjuZw(O{iN&*25+6-CsCTjiT8=ip zXpDfg^BX^u<bx;7?}Nye_igvv?rhg@+upXl@qF9%8Hd`W65o}!aZNhVdZ_qmVQFFx zBugPkLw#cft(P;BojW~x;z13ErtsGFtt*h4QK=t54O?(Q4l4Iw<d=VkClc5o6PcxM zDmZi-0-Lt#BX0DBl($NDR*iiH;9Bwp^h!9x)ZFF?(A!fG6CDj3APu?J35bSV5_F?{ zdj_m6*Ukz$R}X~S@;l-?IP#JLic-NR1bBjuF)S+X*bahC{vF$u?7*ui+l}9+H8eCO zIp>!)79^H5yvj)|E_u`z*_RHfKHK=4K@};FA7sT^<N4P9){eB63n`B(TP}fOF11Ln zNv|7pL1lJMW?y;h!d^e)zVhDnedT@S4d+2*M?M6$E$_(hD|Tx7SR9<0mz>&h9t4~8 zJI?oo=aqKM?2BxzD(>uW_*j(M7t!#bF$ml*$ZoyRJfokzSsrw^HVC(rx6SWo2XzRW z)!Xdbtozct%Nz3h()-elK}7F-5ZQ1ZM1t<V0pT|G_Vewhz+0d4N`ms2`ge$Th&PFM zi1+#T`S+}A-_ba|ak^bzehH*umYULB)|lUz-}I{>bw0yd!Scks61|fp&7FyF^CvVU z7FB+LoCTFyr1P?*c)^uM2?ISd^GO+yo30<17J<foDtqg@`Wy0l>-9@>x|jFlD;ceR z(Zdgdo%U@`&8H!w5{b|`7dIb&{~)GA3pBcqGaXu>wUU1&KjQ-ZMgv2pLkqNLx6f|U z)U-(|YTa36x0$zThp%G<)1d{?OotXUc33kVTF@L3+n(2_-k#o`SO6YwJ>OH_QyS9m z(fX@LyEqec1oM}o(!AuIH`5v%Ko>jc9qT?Zaet@$RCN$+UO!cRm;WyRsqAgfyU(}I zpTt#?Ke=>``oxS$6F`%(3cLMxdvv@9wS79Sx3%}r2SFvfesct5I<x?E>_XoSqrUL= z^1krC@YeR$_Llb@`$79zANME}r*>@Id8Xrb-_5!5odTKj=C|MPiwD8x?S1hZ@3-r3 zyx%vyUA;-a_5R{1=|!oNJBnH#<|!EJ8*kKwbu2UU(%Wi^^{ymlr#_t8k=M2&aq6sQ ze((m${<i*>^tS%C-oE*LvlMI<%pk$gl;3u~?L^}C3ytC}*CDVezvX&&e0N;S24iUB z+`nbJlHE*x5S-jUxxe-PO#Y_pGx=w7ul1a9qI1Fw56v0g#?xO;KVhh6U|<Tm4`hbp z0{w=QGp4uxpD}&LbkHDIOL@Dyk{$S@qfJ(mqGyzV##Bp7W>_RXYWfM<%NmlHp0A+M zt=_F{sHrpApw+V>!>DgoQ{k3?^eHR1RZioa^|k9e2!ckoKy+I>h+KTCn|ZO1VK<AB zo<T!L*Z;1+i~AwFja$WA#arsT{&)TG%`ZyL?`G)w3(C1&F6DDT_wY3eq&%u@_*I;k znX)#mp(C%;9|S?QHJHBM>EG$qXWwUGYcSJumquR7%!b|Roorp(=0BhRr1Lxkf|i=M z{O>%kWam058?-1r^<`f2@(abOogJX1Fe#H}Zs+Knm{&TrX@$q~Gb{4*(pP9?lon5W zTGZq*MFPCxu(7<ce40R6YTnz-yk^F<#G+jA_Mn~*sZ+1%UGM&oShj0dQR;M#-VLS6 z$-7o;T$%U2v_B)Sq+6j?G9`6wV`523YHmSEal^#o)Sd^ew>p`UGZGtD%xuhTWa#;v zT&dT;zw^1Rl40j_5S+Js-jeMCiFuPQWah4a4jGBbho32rcRnDkF%or(x&-fG@}Q>p zm-2kwl8nrvl;Zbku(o<;UOH%9T53`8!<-z@)~$zm;4%d?Edx6CD!-_4VY7alKLob4 zxB0hu8$vjZ=iB_-JX6b3^V$mXOVcyjR#v{vOwTBJmtWHQy*;xSbg|Hn+=9}Qb_LM5 z_J{oP)S`zajT(6=dMDEwy$ae-H2lnjRofjqN-E#y<y3yj&(DS&NS~Zv+A^VWX2<=G z+g-o%8mBZebk&w;mb7ZUXjMopZmVo*Z)pV$WjAVpCw=pJDtomcJGpu?l5*M>v`Cb; zA1Hd4S`O|C^fu(BG~UW@&?r(c(l>5i(6}ivCpW*j0dlN=lVa<vl+^YeKB>jUjTyO+ z^=*wk;G_5ZCX_UFCO+=uNCr(`FYEaSIVZR~5;7yw_5jk2C@AUIozUFBFsb)@?<Y`O z#n=qeS~1eQ(lN0)0JI#oS*&qEb3Oz%-Jfv2X?bG7%i;;rsmb|m4F!os6B0_=7fciA zpWZ*cf69ajCB+>FGV?y=cTZ?C1f5q=ls{=nQGV~^CQtArZel@dQ-R*We&wPT{l*{Q z5&67kjV6Z)%O@;oOqnC!<S-#q=X3s>UjAOL<XI;Ya~e)e{G8hVrg=fLK*Nf>V$fN6 zy&Y4mids+QwVr60kXMq~dSj|%Yf1B`=BTvNoTlD3#^BWC(xS}iJDLk8FKm7>J7S7K z<HVMkjU}yV%^8gmP2Hu<8v^pf_4?$Ipj2XJZugNcw^>YyIlVXM-fCYl!>Q%Lbfp<F z8naI|bhiC#+^E@<n3h<UU)tI^Gc-RhwS7kZirvj&of^446|E7AJW7lE7lTGx+a2;s zdw=$yoPD=NH>q-ha!1s}2aPMc5{kNCG|T{vXm#xG*pZT1)^WZAx|*@Ip;I2#@R)_v z@MtM2EX|*=1J>%88^88G0x~YhOA44J<J6JmnddfJa$P?NHr4m9SF)R%+Rfh0-p!WS z+L4z&XT~h;?r;!XRMY+sGGNs8zC*F|m~q$pE_Kk*cf)xQ3Bw)bUGKXDCwKd&b=^mX z(?Db9BIWZNO1AFk=I9DqlD{-BWx;|iO}kn^3tQ4!8oT{F;v4e2{q;+8I?KE4m5dh5 z2c5UjdAn`9tx~@W_(&mGRje_^y)(ZvOB>V`(*!M!=qhjIZ{z?~znMjL^Y1oQfh%hb zA3qIW#|Vuk4yHp3z?E=-W>av(2}3<Y3rkJS_Gdlf?f2VnF2CRI-tOMEzBkS%wPX)R z@z=caqUCdz<X9~PukLB)Z{`QB@o8S(<=^EA+Mox)jXWLt5D03*w)A)CcW6wlDBfL= zGo`v{ci@(QlJeB43Jc|@@h_C0CbGuz;r<EJw>Pfexy>!V=xIe_v&YVk%(O)>8V_wc z-_$Ydcvt$ob`WfvKd*gWv*q09bDwvvZ#>_TKKDVp%yRSP=H>0`?aG}en(`s7yw?8a z<Ddx?QwSH-=u@)W71f&EdwG{uQYxe-1(D7CE!SJFXjp0+YU-OR*eV!-oZG72B;Ts8 zWCvPRI`0GM<h53fyoaDu9cCX`8Ib=pueh{m|Hj0UHm?O=Cp_Lb`5|Pe72Ixb+}XUm zT^s^i{<n*_3ol;Lb{qs7&$k_4lfO`5_I^XqT@Q`l8^3le^h+$rOf8y}=#!tGxZyxX z?#!9H4T}3}Kx<*A2yB|%aSl|Z^=l;O=WetFPlly51n6DgaU!ufqp^J1&iu|BWvQJj zHrH>i0*?WH&hNh6vtZ7w1r;UJ0}~%NNhHrL$jfh<(Cg6bG{3nRa)1(qRI>9-``#Ko ze?x12YxdL+pfgM}8*WVCD9)eQxNH9G(?y_zq*GILnym6m+blqfd0Jj%mMq!XdmL0D zfx8)1skTbsWm7n3sX@mRKW^BHymZRPPs32N!P7>+5q#RPWP?RhVZ)rp_l+-L9SXfG z;Q8sKoYY)U3qP?0dWKX^QEFmJ<>%CrhtLy(z*94z!{)CyT`10M6GuSC1%|EPL9p?B z>vtu)@0p+@`clt2Mt~v{+<-ip)+Sk=T9o=F{|RWixgns@qA0PE<56YneHd&JZ@u6B zzWY6RsuMKb`71Fe2U1bC9LP)mkeXTqZVaUK@HALJHaLJ<91z^RzIA%*6!2MIwhG<L z!96zi*7Xx7dFDM#Ny+Sv)R{Olv*c51TSVov#LS}ZiLL7<t^n^1{+^NF7+D0WIp62? zWP!@P#60^J=nkz$Nk}!*_XAeVw3WA%w-km<tpJUtcdp2&>|fldk(OW7310gOBAfX; z>!&;gWoytu*PZE&?_0k2b4+f?X#X&4MIL0e9f)jN-!gqB$h7j7^2YNm<$4EuYBLh& z2h8x8EC5O2kfZ-VWV3n8|CYZNdX}oK@*vpwzEyt4#H9S`J0^T@H7zdAOwUVAnbBXM zr_gLPX=7q?N$C_OL$f#yLw!RtO`Rqw@YKhw7bR0JCYMau06LB}HMMC&d4Btjveca7 zWsZ%BD<m2MKug#aG%`}53(yjCIs-E_^*~L25N=!Fw%#rzzhMUWMB!AOpZTTpZnvE% zO6{pxy~?Ut-_B;~f@b?>3)skQbANMZPUf0w_%b2T60n(1)?3aEndg|7l3LNNFy~KB zetKfjYKGiS*_E$b5A^)kX<e3+*^)o;VoRPeWVW>>*Q3S1g`+P4oMl>yJB{Zn<`;un zrg@Dk)0Zfe%ua2s2iMut({vjo`d2Pen%Lgo-*yl@9thvt)a;Pmu%My6p=rW)qY2yF z`)AEHYp6)-knfNJw-y>sI8W3nUbUn7TVuq8_08%^hK60+oAsOKcWni2X6snd_Q?s< zdj=2BY+f+0A+@m}w;-{oTcIlhx?Zd?$ZEDl!-L%J8!4b$4^}NK0^JXvyj8RFVMb>0 ztcuF6Sja$bawTY~VYfz+&XMNJjR(>j6M8@9<*&ckccIB6CAC=RQEABzf#N>zrs<6{ zc2wr)fevArvawmZrJ-r&gcI{S`VTC4yzfL_NoHEZh8Lx|4T}@|Jkm2u=DtXToC>CQ zrRm4_#LAZAD+Dw1HU{K2CoMkNQqdgP<&l!uzOad-C^ap$?P6-n!JrV|jvG0dWgUji zMa8RT=44KgINTxA^%OMf+jVhDLH6pTrkkO8nH?{Rn@+ei8MNL=ne5-szUX=%ctwYj zoo{~gh3P$sC2jAg-6)tD(dn6&TK+aaB{gTqrsCAzh}NHp6Y6JvX#bJ-bo$H8{=_*E zPg0W`B8n1ortV1Tys396v3LS&lXFi-=f&%(Nu7)#MWve@$`{UPs$5jiuDIqzW^t21 z<Fwqw?3NRKvl4S=XLSEAD$QxwklWS>+Ev|ku(*>$w`E0Y^27s^9s4AbGx9TgGS)9_ zyD)FT+KN>ViYLBkxe3}tGMS^XASb_Ex9i7rsnW?mb(&9P_ASWFYyX{|pWm{+eNskh zPC>)N_UlzGkDDr5<MVo_BjD=Ai#aykC`oNmm=MtPp?80NR(oOFk7<@UZ5rUCi#8U` zjVS5mC}_OcJ8|-v)DDLH+-Vmk$2Z)avp;+@XXmEI^^GeO>}Om^y)?UP%YufCIV!&S zd8w5h5owuuJqI#pTr2`L-X|H97B&9KOl~SnZQ0N$vGqFycFIHOM*FVtuJEo9&@#c4 z{M`116E19cx$8$!`?1fJi*Mvw&1pzZEN%F(Y(m=x$n|AQn&x`u&WxPnzbzaDTh7Da z5{1;_;za?)EjJn>TFT2)`xRSiGZK3^8gm+VbjztF<`!7DUMflKdC=qruFE@(!4&jH zh2~4M5~lo`v2x0cl+xJ~nqIZuZ>XBoT~NBVq2=Htl_tT&<ctOEIiS_zt$`+BDjY(t znzhMuardIezE7>{T|fH6`vY?_b7xzmJlZ1BSdmzkn3*)|#)LJc1qC_#kMBP|Uw*!P zt3C*3Oz|}76K|bT+)~>TQJR;sWI@Ri#ghE=)RK%;$T1i?@1Vml#hGQPIhA@B8X|N+ zJ51+5!wR&O?nPqpm;6Vm;Ne=xLZaeEL(m;(d8L`fiFwJXjS+g6^IxPErRqFuVt$gJ zTHI`vo0^#SB_s6{sA6d9EJ@5xeVCK;KJDSB)Z+ZoqU2NsjhxJe1LcV&sYRa~W@qL# za-^gdrxulHHY{jrc$;6;aG>~MSz=}mXeOd*QqvDm-=|pbTz>h_{L<&CB`-^K8Xhzj zG)OcmrspT-ShY$$P0r8D&#i3O0ZtGNtKnq@Y~?iQaDRAlR+O5U-7o`Go)xs8XuF8z zoX93k$T?M@Vh(M2K*NdP_M&11tLA-;0WIR7N#JHZ!)Ev_aC3b#bQZX|05*8ovaLlG z)?f%q%}FeokZ~m=HNU8`=OH*f>s;3JNleNwO6hxHWMF7urO<L0X-M2kUq3ZZucRnf zFS%m}s6CL|_@N{*vnW+BGcPS)zxjCk6X@>p#_b^3VV2mSkdxUi-(AoyZ`>~5F5evA zE(<PaC(Q`Y$Sg@MNGwP#YJ2IIn4OrLUy|SU(ZB+9!hT6Xaodli#?PQp_lC5Bl(gpj zw&QIF8|xeE8!NygKRw1^s=ryit*<xYP}>@x#*2BGdFkgMqlY@D^aAqp^Ax~2;fkJ1 zQDs(QpOTqEyM4QTpH@zjtzM5qlV!tn-G(W;owwSbw;XSO+N2MKS{>6nrguy+0aMeP zuXjxEnBeXgdZ8$@EHSzAL}Fe_Qht6%hOeGuaYoLxMng+WOVH&L{VwI@<$CFPr3LA| zx6%tTrk&7-oc*ttQIeaZ?C9!eY;4*h-u}G(A#`HoALxGY_ARDhYJ2nY_H7=G1-iur zt53XWh)P}Nky%o?_(pnOVoB+037sQ)UV2WcMW73@GV^rK>A93<rs+&L;FFk_KJP(* zUT|_od16vSgp+QhUSz`ty;Dmr<Rz{Rat80(1s{i;nS3-aJu@#gwP<puk%Gpg6-Jsm z3g+g_j~XUhSn7d$Td$If^ePMVO7ivle-(F3PE9c~H8r$s``$IZYhvT_#^sGmyX+g^ zciiu|u`aw@zgyF+TOS0Q!kfYZ0-R?%SY2q}0NNbd;MlQ7*LmZSCX14c$uIKrK{a~t z_Q1u8-kp|noELYdB<9R<GMZxF8QvL^Sd^Txrecy&%8Hpe#riGM0UegD=AHSSnT`8F zu&A>g6dC5w$Vl&)=2Dus%A@EIv>IPx(0-#NztKVGo1wAJlcL15l1G(CbMp5{w3oM+ zw-<wFaGI)HZ{_9h-vFAr+0X!<xk<{&Pts2*O)7|QIsu)$F*J;Ck%@1Sk8hEU4>L5@ z%S~y0-|64!30f(Gib01&cB@!`DfL$SW&O)Kf-{pUa}Ji2Bqp!h6r|^pUz(g+TGZ9v z)xJzWH#4~?zc@dwM6Yeb5(C}RV*LdHsS_pj%L{aq8!x2hmFSli<m4x&6zgyQVWe+h zsP7pN5)j;wxn92I_;PztR}q2N|L-jCEVb+`2f>!@on?NhJq|@BsTIpFRHZ&Fe%Pq6 zd`3~PL&^KR=SBIY1r494RumLv<|dY`_!y+;spq?52I%zkZiVIhJxbTUI0`xwvm`Tr z<%x|yj25kL?Ets6GQe}MDVb%h+l*3kTLZvz68Sl8>}`zg_J-~D4L2L@8!ZbOo;N)2 zknfQ10B7j=1=lmCTCAM3gcF>Xry4BYX<#w&_{8HA4<|K#o-wH*b%OZ>^9d%PEZn!e zZ&Bj2%pBMO6%7(51}4T$<xS;H1<a4yRyJO5P$-x%y)(wBGrps~Gah6U=r*^`7;urb z5?W;S7lMnd&Q3^)wf4nY3j@%Kl9GbX3Rp2!l-lHxpSSSF>X}G|lzY1)sB~)F-XY)l zzVn^AiDA?FruCig!SIc7=lf3n&i7zTK|*i*3sUm}+yiDwEPwqZH7zqQwfJ*MVqQvO z5oqh-tQW-%j!*NFcLt`WyiF}GPE4OY6V!}PEGb<$L1&I<*&L78sg(@{O&p+|-=Hg& z=lpDvu2@}=m%b|ye9cyJW0qd;%j15bn{PBp?2+(j{E(ENzcK()y7V>9U0}KSd!PAA zXvs3oE4?72?}YyR9i@pm$OTJBeE0nosnCMuSI_^x^L=M63@j|0zBhgEI}e6uO#06E zzVAEV@Vo?a7BNFx18a+|65>uA^aD3MGSf43iwjayQ$Ph0Xb`KU@^dD*L@G)x#$F^{ z(E}ApsX7-hi=_P0qP)bM_i2Z*6-t?T=?X>)8b$_&DCLrZjee`Aoefeg1e%zIms8*h zq!<zq@ZzfNGi*{7QfM{1>L)^qExnfTG~|S5VP<L4xV*W)xdW8&nvORp6o6_hI~&NX zTdJ*+snUzo?tqe>-QYR7URiLu@BQE0-l`f906Mq8>Oxloq|EEC(RGH-0)Yy?3!uf~ zx(yP+po_>og7v(6IKkCXLxx{sN@9+VLQkfGRgXI8HcU_%m|2zzs_yhtQo;A)fJ(w{ z&Q|k|?HwCI<zVCfqR#2v>D?)Y1_nlkP1~EccY_YRPw!4K>rU@#?@k9LSg=q^NJi?R z%#!5R9cLOZ=5=xUp;U=oJt2_lu&c|gtG}zitD~y{R3GLwSwpJBskihBQqo$Ecer;r zLMuf5CM~etsb;1Y2B7=X!S<wgr<kK#9b8(J*7Y&*dTP=l$q>-#nL3wJ3rb58OESAX z67y0TDv~n`it>|}b~em#&M!^QXuPABoS(b&qEBLJNorA2VseJg3B4wZ{Jiv~H-j@0 z8z%VZIi@7$W+wNF_loxl73U=u=z;E2P0KGz(MwG!)lbezEH2hhE;ceUDc1#!bTnra z>*qAv8CaIICiYHm``%Rw%G@yAC*CLCCuV78V${66c{!LT-X~(wC*Et`Ck_fhkkFE= zrAayKGqO`Fn;A1xdRI3{xaXAyxW7%zD_z_P$(N~>ItrkAe`a`(`{FzBdVi5odO?PM zYMy?R@w(m63ctSnfBR2pzWmoI-}S!hjgf(wkp(DYf-BwkU2iPA-gohLfy*3_(31Ge znXu|)@uwg?m+3!1wF&r$i|HAV%48;IhX$xF*{_khRuM~GV$^;CsV<pzzU6qgIiel` zv8L<yxc9gjo0yoju(z=HxPzgKp+S#-cYcpQC@^~bd;EKR{8ICi^FehCs3H2Wc<F?8 zj^dJ{#LUKu=@sdaT4v(`NG+3Eyet4z&FHy+Z|Ug$0m<>p13gNo>;Ts`GiS~?Wz;vl zBfTTR#L~prwB>$BIuxcFcBHqrcYqTzR0t-8PA8ffS(=z2>or2vyZmcnQEEwkyJX&0 zft=K3=jW`SvnDl9uRJq5vjDXCc*(1VLj5N0_$Iz)|F-LG7eQ;^K|_n}?>qN*?lm>E zG;ey}1Y+;++@qhLV`l?zv2U%&*6&pBN=VJ^RPSuuz>uD2tCT!{M`}@9=mbk!rL~<& zb|HyLoeC+b#b-A<Fdbg8u)#(@soA6XP4kJS|4sjGm2?eFdbHZs?{G3OH8wG~Gi=?~ z_`Z+5@qOd_#y4h*IVM|xnIP`_#+R06#&*U?0<X+WjLqy!kVIZvSQy)F6F?GqVQ$pf zVTL5|+RV_<&KybLm4$(sp&hbCuT2aM>@1O#ytXhfvNJS*1`KF(z$efVZFYu})!|}a zjEybq3@7Wu1m-R>0M+DkJ~#fElRqarQNhkeKhaLXCQ-qTVOaxb3!G=8pV**~l%G;* zXQK~l9NRHGYH0TKbBSPJU^u{l089)F3@;cM7#JBC{=WSG|Nnmm1_oY)G?>K*CI^my zyEnwq9prumkb4;!85x)unHZQESr}LtIY6#sWHN9DJKobJB81@q0|T0Wq5fbD0QnK* zR}cni9ITkhz<^)=G@JO2*$qqvhWu>i%}lEs8kh`>_}MJiG3{+?U@|b~XS06Ie6yv2 z$-so4&Hf1U{<a1t15<uB=Vqoi9SuwdX8dff@0s3oH82^N^Rs!}W<J!@z+_;-&*n3i z>26;GlYu2ao8K?yjtLD+29Eq}K}}3OlNy)|ocP&7`j~pAHZU1D^RtD`;`}_LfdL$@ z2N+H>Tw{31@P^?#BNHPpqXeTeqaLFrqYDE=qhX^_qj952qiLgAqj{r6qh*t!L6f0j zlc7=bqqda{Za$vD3=9k$433Zx2Zui+12Y2y7&C(SZq8seA`A=+0-$&Xt7P0D4W=0w SKylB(zz9mO3=A*(c)0*uCbe<^ literal 0 HcmV?d00001 diff --git a/chapters/en/1_intro.md.txt b/chapters/en/1_intro.md.txt index 437d2c6..8dfb6c7 100644 --- a/chapters/en/1_intro.md.txt +++ b/chapters/en/1_intro.md.txt @@ -26,9 +26,9 @@ The results of this demonstration implies a monetary creation : Thus, Duniter project will associate a human to a digital identity. It will use a Web of Trust with specific rules. As the number of members may evolve, the Universal Dividend has to be created according to the formula : -``` $$ UD(t+1) = UD(t) + c²*( {M(t) \over N(t) }) $$ -``` + + Duniter is based on a decentralized Blockchain. This technical choice allows irreversibility of transaction and uncensorability of trades and identities. While inspired by Bitcoin, Duniter uses a Web of Trust and the Proof of Work to secure the computation network, thus making obsolete the power race model used in Bitcoin. The first currency created through Duniter is Ğ1, pronounced "June". It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software. diff --git a/publication.sh b/publication.sh index 93cdce2..0e2a6a1 100644 --- a/publication.sh +++ b/publication.sh @@ -6,13 +6,13 @@ # ce script doit être lancé dans le dossier contenant les chapitres. # dépendances : pandoc -hash pandoc 2>/dev/null || { echo >&2 "Ce générateur a besoin de la commande pandoc pour fonctionner. Mais cette commande n'est pas installée."; exit 1; } +hash pandoc 2>/dev/null || { echo >&2 "Ce générateur a besoin de la commande pandoc pour fonctionner. Mais cette commande n'est pas installée. Fin de l'exécution."; exit 1; } mkdir -p build/src/js ## Clean des dossiers de build et copie des assets [ -f whitepaper.html ] && rm whitepaper.html -rm -rf build +rm -rf build temp_whitepaper_html_en temp_whitepaper_html_fr temp_whitepaper_en.md temp_whitepaper_fr.md mkdir -p build/js -cp src/js/* build/js/ +#cp src/js/* build/js/ mkdir build/img cp src/img/* build/img/ cp src/*.css build/ @@ -43,33 +43,33 @@ cat src/foot.html >> temp_whitepaper_html_fr ## Générer le html à partir du md pandoc -o whitepaper_fr.html temp_whitepaper_html_fr pandoc -o whitepaper_en.html temp_whitepaper_html_en -## déplacer dans le dossier de build -mv temp_whitepaper_fr.md build/whitepaper_fr.md -mv temp_whitepaper_en.md build/whitepaper_en.md + mv whitepaper_fr.html build/whitepaper_fr.html mv whitepaper_en.html build/whitepaper_en.html -# clean de fichiers temporaires -rm temp_whitepaper_html_fr temp_whitepaper_html_en - -firefox build/whitepaper_en.html - +firefox "$PWD/build/whitepaper_en.html" ## add ebook conversion -hash pandoc 2>/dev/null || { echo >&2 "Ce générateur peut utiliser ebook-convert fourni avec Calibre, disponible dans les dépots apt. Mais cette commande n'est pas installée."; exit 1; } -ebook-convert build/whitepaper.html build/whitepaper.mobi -ebook-convert build/whitepaper.html build/whitepaper.fb2 -ebook-convert build/whitepaper.html build/whitepaper.epub +hash pandoc 2>/dev/null || { echo >&2 "Ce générateur peut utiliser ebook-convert fourni avec Calibre, disponible dans les dépots apt. Mais cette commande n'est pas installée. Fin de l'exécution."; exit 1; } +ebook-convert build/whitepaper_fr.html build/whitepaper_fr.mobi +ebook-convert build/whitepaper_en.html build/whitepaper_en.mobi +ebook-convert build/whitepaper_fr.html build/whitepaper_fr.fb2 +ebook-convert build/whitepaper_en.html build/whitepaper_en.fb2 +ebook-convert build/whitepaper_fr.html build/whitepaper_fr.epub +ebook-convert build/whitepaper_en.html build/whitepaper_en.epub echo "===== ok ebooks" ls -lArth build ## Création du fichier lateX et pdf ## Attention, certains caractères (U+2028) ne sont pas acceptés par LaTeX. -pandoc -o whitepaper.pdf temp_whitepaper.md +pandoc -o whitepaper_fr.pdf temp_whitepaper_fr.md +pandoc -o whitepaper_en.pdf temp_whitepaper_en.md -# git add files -git add whitepaper.md whitepaper.html -git add chapters/1_intro.md.txt chapters/2_looking_at_Bitcoin.md.txt chapters/3_blockchain.md.txt chapters/4_Web_Of_Trust.md.txt chapters/5_individualized_difficulty.md.txt chapters/6_conclusion.md.txt chapters/9_sources.md.txt -git add publication.sh +## déplacer les md, html et pdf dans le dossier de build +mv temp_whitepaper_fr.md build/whitepaper_fr.md +mv temp_whitepaper_en.md build/whitepaper_en.md -#we want to add the .pdf only for publication -# git add whitepaper.pdf +mv whitepaper_fr.pdf build/whitepaper_fr.pdf +mv whitepaper_en.pdf build/whitepaper_en.pdf + +# clean de fichiers temporaires +rm temp_whitepaper_fr.md temp_whitepaper_en.md temp_whitepaper_html_fr temp_whitepaper_html_en missfont.log diff --git a/src/head.html b/src/head.html index eded7e1..02dbdab 100644 --- a/src/head.html +++ b/src/head.html @@ -9,18 +9,53 @@ <link rel='stylesheet' href='main.css' > - <script src='js/jquery.js' ></script > - <script src='js/toc.js' ></script > - <script type='javascript' > - if ($) { - $('#whitepaper').tableofcontents({ id: '#toc' }); - } + <script type='text/javascript' > + /** + * Generates a table of contents for your document based on the headings + * present. Anchors are injected into the document and the + * entries in the table of contents are linked to them. The table of + * contents will be generated inside of the first element with the id `toc`. + * @param {HTMLDOMDocument} documentRef Optional A reference to the document + * object. Defaults to `document`. + * @author Matthew Christopher Kastor-Inare III + * @version 20130726 + * @example + * // call this after the page has loaded + * htmlTableOfContents(); + */ + function htmlTableOfContents(documentRef) { + var documentRef = documentRef || document; + var toc = documentRef.getElementById('table_of_contents'); + var headings = [].slice.call(documentRef.body.querySelectorAll('h1, h2, h3, h4, h5, h6')); + headings.forEach(function (heading, index) { + var anchor = documentRef.createElement('a'); + anchor.setAttribute('name', 'toc' + index); + anchor.setAttribute('id', 'toc' + index); + + var link = documentRef.createElement('a'); + link.setAttribute('href', '#toc' + index); + link.textContent = heading.textContent; + + var div = documentRef.createElement('div'); + div.setAttribute('class', heading.tagName.toLowerCase()); + + div.appendChild(link); + toc.appendChild(div); + heading.parentNode.insertBefore(anchor, heading); + }); + } + + try { + module.exports = htmlTableOfContents; + } catch (e) { + // module.exports is not defined + console.error('e', e) + } </script > </head > -<body > +<body onload='htmlTableOfContents();' > <main > - <div id='toc' ></div > + <nav id='table_of_contents' ></nav > <article id='whitepaper' class='content' > - diff --git a/src/js/jquery.js b/src/js/jquery.js deleted file mode 100644 index d105c25..0000000 --- a/src/js/jquery.js +++ /dev/null @@ -1,5 +0,0 @@ -/*! jQuery v1.11.3 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */ -!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.3",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b="length"in a&&a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\f]' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function qa(){}qa.prototype=d.filters=d.pseudos,d.setFilters=new qa,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function ra(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1; - - return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function aa(){return!0}function ba(){return!1}function ca(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[m.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=Z.test(e)?this.mouseHooks:Y.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new m.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||y),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||y,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==ca()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===ca()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return m.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return m.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=m.extend(new m.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?m.event.trigger(e,null,b):m.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},m.removeEvent=y.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===K&&(a[d]=null),a.detachEvent(d,c))},m.Event=function(a,b){return this instanceof m.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?aa:ba):this.type=a,b&&m.extend(this,b),this.timeStamp=a&&a.timeStamp||m.now(),void(this[m.expando]=!0)):new m.Event(a,b)},m.Event.prototype={isDefaultPrevented:ba,isPropagationStopped:ba,isImmediatePropagationStopped:ba,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=aa,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=aa,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=aa,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},m.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){m.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!m.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.submitBubbles||(m.event.special.submit={setup:function(){return m.nodeName(this,"form")?!1:void m.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=m.nodeName(b,"input")||m.nodeName(b,"button")?b.form:void 0;c&&!m._data(c,"submitBubbles")&&(m.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),m._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&m.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return m.nodeName(this,"form")?!1:void m.event.remove(this,"._submit")}}),k.changeBubbles||(m.event.special.change={setup:function(){return X.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(m.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),m.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),m.event.simulate("change",this,a,!0)})),!1):void m.event.add(this,"beforeactivate._change",function(a){var b=a.target;X.test(b.nodeName)&&!m._data(b,"changeBubbles")&&(m.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||m.event.simulate("change",this.parentNode,a,!0)}),m._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return m.event.remove(this,"._change"),!X.test(this.nodeName)}}),k.focusinBubbles||m.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){m.event.simulate(b,a.target,m.event.fix(a),!0)};m.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=m._data(d,b);e||d.addEventListener(a,c,!0),m._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=m._data(d,b)-1;e?m._data(d,b,e):(d.removeEventListener(a,c,!0),m._removeData(d,b))}}}),m.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=ba;else if(!d)return this;return 1===e&&(g=d,d=function(a){return m().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=m.guid++)),this.each(function(){m.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,m(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=ba),this.each(function(){m.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){m.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?m.event.trigger(a,b,c,!0):void 0}});function da(a){var b=ea.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var ea="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",fa=/ jQuery\d+="(?:null|\d+)"/g,ga=new RegExp("<(?:"+ea+")[\\s/>]","i"),ha=/^\s+/,ia=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ja=/<([\w:]+)/,ka=/<tbody/i,la=/<|&#?\w+;/,ma=/<(?:script|style|link)/i,na=/checked\s*(?:[^=]|=\s*.checked.)/i,oa=/^$|\/(?:java|ecma)script/i,pa=/^true\/(.*)/,qa=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ra={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:k.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},sa=da(y),ta=sa.appendChild(y.createElement("div"));ra.optgroup=ra.option,ra.tbody=ra.tfoot=ra.colgroup=ra.caption=ra.thead,ra.th=ra.td;function ua(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ua(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function va(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wa(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xa(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function ya(a){var b=pa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function za(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Aa(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Ba(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xa(b).text=a.text,ya(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!ga.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ta.innerHTML=a.outerHTML,ta.removeChild(f=ta.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ua(f),h=ua(a),g=0;null!=(e=h[g]);++g)d[g]&&Ba(e,d[g]);if(b)if(c)for(h=h||ua(a),d=d||ua(f),g=0;null!=(e=h[g]);g++)Aa(e,d[g]);else Aa(a,f);return d=ua(f,"script"),d.length>0&&za(d,!i&&ua(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=da(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(la.test(f)){h=h||o.appendChild(b.createElement("div")),i=(ja.exec(f)||["",""])[1].toLowerCase(),l=ra[i]||ra._default,h.innerHTML=l[1]+f.replace(ia,"<$1></$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&ha.test(f)&&p.push(b.createTextNode(ha.exec(f)[0])),!k.tbody){f="table"!==i||ka.test(f)?"<table>"!==l[1]||ka.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ua(p,"input"),va),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ua(o.appendChild(f),"script"),g&&za(h),c)){e=0;while(f=h[e++])oa.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ua(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&za(ua(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ua(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fa,""):void 0;if(!("string"!=typeof a||ma.test(a)||!k.htmlSerialize&&ga.test(a)||!k.leadingWhitespace&&ha.test(a)||ra[(ja.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ia,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ua(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ua(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&na.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ua(i,"script"),xa),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ua(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,ya),j=0;f>j;j++)d=g[j],oa.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qa,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Ca,Da={};function Ea(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fa(a){var b=y,c=Da[a];return c||(c=Ea(a,b),"none"!==c&&c||(Ca=(Ca||m("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Ca[0].contentWindow||Ca[0].contentDocument).document,b.write(),b.close(),c=Ea(a,b),Ca.detach()),Da[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Ga=/^margin/,Ha=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ia,Ja,Ka=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ia=function(b){return b.ownerDocument.defaultView.opener?b.ownerDocument.defaultView.getComputedStyle(b,null):a.getComputedStyle(b,null)},Ja=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ia(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Ha.test(g)&&Ga.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):y.documentElement.currentStyle&&(Ia=function(a){return a.currentStyle},Ja=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ia(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Ha.test(g)&&!Ka.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function La(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight),b.removeChild(i)),b.innerHTML="<table><tr><td></td><td>t</td></tr></table>",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Ma=/alpha\([^)]*\)/i,Na=/opacity\s*=\s*([^)]*)/,Oa=/^(none|table(?!-c[ea]).+)/,Pa=new RegExp("^("+S+")(.*)$","i"),Qa=new RegExp("^([+-])=("+S+")","i"),Ra={position:"absolute",visibility:"hidden",display:"block"},Sa={letterSpacing:"0",fontWeight:"400"},Ta=["Webkit","O","Moz","ms"];function Ua(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Ta.length;while(e--)if(b=Ta[e]+c,b in a)return b;return d}function Va(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fa(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Wa(a,b,c){var d=Pa.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xa(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Ya(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ia(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Ja(a,b,f),(0>e||null==e)&&(e=a.style[b]),Ha.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xa(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Ja(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ua(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qa.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ua(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Ja(a,b,d)),"normal"===f&&b in Sa&&(f=Sa[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Oa.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Ra,function(){return Ya(a,b,d)}):Ya(a,b,d):void 0},set:function(a,c,d){var e=d&&Ia(a);return Wa(a,c,d?Xa(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Na.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Ma,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Ma.test(f)?f.replace(Ma,e):f+" "+e)}}),m.cssHooks.marginRight=La(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Ja,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Ga.test(a)||(m.cssHooks[a+b].set=Wa)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ia(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Va(this,!0)},hide:function(){return Va(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Za(a,b,c,d,e){ - return new Za.prototype.init(a,b,c,d,e)}m.Tween=Za,Za.prototype={constructor:Za,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")},cur:function(){var a=Za.propHooks[this.prop];return a&&a.get?a.get(this):Za.propHooks._default.get(this)},run:function(a){var b,c=Za.propHooks[this.prop];return this.options.duration?this.pos=b=m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Za.propHooks._default.set(this),this}},Za.prototype.init.prototype=Za.prototype,Za.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Za.propHooks.scrollTop=Za.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Za.prototype.init,m.fx.step={};var $a,_a,ab=/^(?:toggle|show|hide)$/,bb=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cb=/queueHooks$/,db=[ib],eb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bb.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bb.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fb(){return setTimeout(function(){$a=void 0}),$a=m.now()}function gb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hb(a,b,c){for(var d,e=(eb[b]||[]).concat(eb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fa(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fa(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ab.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fa(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hb(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=db.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$a||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$a||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);g>f;f++)if(d=db[f].call(j,a,k,j.opts))return d;return m.map(k,hb,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kb,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],eb[c]=eb[c]||[],eb[c].unshift(b)},prefilter:function(a,b){b?db.unshift(a):db.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kb(this,m.extend({},a),f);(e||m._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gb(b,!0),a,d,e)}}),m.each({slideDown:gb("show"),slideUp:gb("hide"),slideToggle:gb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($a=m.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||m.fx.stop(),$a=void 0},m.fx.timer=function(a){m.timers.push(a),a()?m.fx.start():m.timers.pop()},m.fx.interval=13,m.fx.start=function(){_a||(_a=setInterval(m.fx.tick,m.fx.interval))},m.fx.stop=function(){clearInterval(_a),_a=null},m.fx.speeds={slow:600,fast:200,_default:400},m.fn.delay=function(a,b){return a=m.fx?m.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e;b=y.createElement("div"),b.setAttribute("className","t"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lb=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lb,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mb,nb,ob=m.expr.attrHandle,pb=/^(?:checked|selected)$/i,qb=k.getSetAttribute,rb=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nb:mb)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rb&&qb||!pb.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qb?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nb={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rb&&qb||!pb.test(c)?a.setAttribute(!qb&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=ob[b]||m.find.attr;ob[b]=rb&&qb||!pb.test(b)?function(a,b,d){var e,f;return d||(f=ob[b],ob[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,ob[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rb&&qb||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mb&&mb.set(a,b,c)}}),qb||(mb={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},ob.id=ob.name=ob.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mb.set},m.attrHooks.contenteditable={set:function(a,b,c){mb.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sb=/^(?:input|select|textarea|button|object)$/i,tb=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sb.test(a.nodeName)||tb.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var ub=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ub," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ub," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ub," ").indexOf(b)>=0)return!0;return!1}}),m.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var vb=m.now(),wb=/\?/,xb=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xb,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yb,zb,Ab=/#.*$/,Bb=/([?&])_=[^&]*/,Cb=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Db=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Eb=/^(?:GET|HEAD)$/,Fb=/^\/\//,Gb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hb={},Ib={},Jb="*/".concat("*");try{zb=location.href}catch(Kb){zb=y.createElement("a"),zb.href="",zb=zb.href}yb=Gb.exec(zb.toLowerCase())||[];function Lb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mb(a,b,c,d){var e={},f=a===Ib;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Nb(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Ob(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zb,type:"GET",isLocal:Db.test(yb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nb(Nb(a,m.ajaxSettings),b):Nb(m.ajaxSettings,a)},ajaxPrefilter:Lb(Hb),ajaxTransport:Lb(Ib),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cb.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zb)+"").replace(Ab,"").replace(Fb,yb[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gb.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yb[1]&&c[2]===yb[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yb[3]||("http:"===yb[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mb(Hb,k,b,v),2===t)return v;h=m.event&&k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Eb.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wb.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bb.test(e)?e.replace(Bb,"$1_="+vb++):e+(wb.test(e)?"&":"?")+"_="+vb++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Jb+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mb(Ib,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Ob(k,v,c)),u=Pb(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qb=/%20/g,Rb=/\[\]$/,Sb=/\r?\n/g,Tb=/^(?:submit|button|image|reset|file)$/i,Ub=/^(?:input|select|textarea|keygen)/i;function Vb(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rb.test(a)?d(a,e):Vb(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vb(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vb(c,a[c],b,e);return d.join("&").replace(Qb,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Ub.test(this.nodeName)&&!Tb.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sb,"\r\n")}}):{name:b.name,value:c.replace(Sb,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zb()||$b()}:Zb;var Wb=0,Xb={},Yb=m.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in Xb)Xb[a](void 0,!0)}),k.cors=!!Yb&&"withCredentials"in Yb,Yb=k.ajax=!!Yb,Yb&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wb;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xb[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xb[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zb(){try{return new a.XMLHttpRequest}catch(b){}}function $b(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _b=[],ac=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_b.pop()||m.expando+"_"+vb++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ac.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ac.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ac,"$1"+e):b.jsonp!==!1&&(b.url+=(wb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_b.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bc=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bc)return bc.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("<div>").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cc=a.document.documentElement;function dc(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dc(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cc;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cc})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dc(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=La(k.pixelPosition,function(a,c){return c?(c=Ja(a,b),Ha.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ec=a.jQuery,fc=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fc),b&&a.jQuery===m&&(a.jQuery=ec),m},typeof b===K&&(a.jQuery=a.$=m),m}); diff --git a/src/js/toc.js b/src/js/toc.js deleted file mode 100644 index d24dbbb..0000000 --- a/src/js/toc.js +++ /dev/null @@ -1,65 +0,0 @@ -(function ($) { - $.fn.tableofcontents = function(options) { - var settings = $.extend({ - id: "container", // target element id - css: { - "padding": "3px", // padding size - "border": "solid 1px #CCC", // border style - "width": null // width - } - }, options); - - options = $.extend(settings, options); - - var target = $(options.id) - .append($("<div></div>").html("Contents").css({ "font-weight": "bold" })) - .append("<ul></ul>") - .css(options.css); - - var prevLevel = 0; - var getLevel = function(tagname) { - switch(tagname) { - case "H1": return 1; - case "H2": return 2; - case "H3": return 3; - case "H4": return 4; - case "H5": return 5; - case "H6": return 6; - } - - return 0; - }; - - var getUniqId = function() { - return "__toc_id:" + Math.floor(Math.random() * 100000); - }; - - this.find("h1, h2, h3, h4, h5, h6").each(function() { - var that = $(this); - var currentLevel = getLevel(that[0].tagName); - if(currentLevel > prevLevel) { - var tmp = $("<ul></ul>").data("level", currentLevel); - target = target.append(tmp); - target = tmp; - - }else { - while(target.parent().length && currentLevel <= target.parent().data("level")) { - target = target.parent(); - } - } - - var txt = that.html(); - var txtId = that.attr("id"); - if(!!!txtId) { - txtId = getUniqId(); - that.attr({ "id": txtId }); - } - - var alink = $("<a></a>").text(txt).attr({ "href": "#" + txtId }); - target.append($("<li></li>").append(alink)); - prevLevel = currentLevel; - }); - - return this; - }; -}(jQuery)); diff --git a/src/main.css b/src/main.css index afec412..ac400d5 100644 --- a/src/main.css +++ b/src/main.css @@ -1,48 +1,72 @@ -body{ +html{ + background: #999; +} +body { + background: #fff; padding: 4em 6em; max-width: 65em; margin: 0 auto; box-shadow: 0 0 1em #ccc; + margin-left: 550px; } -#toc { +#table_of_contents { top: 0px; left: 0px; height: 100%; position: fixed; background: #333; box-shadow: inset -5px 0 5px 0px #000; - width: 150px; + width: 458px; padding-top: 20px; color: #fff; + padding-left: 2em; + overflow: auto; + padding-bottom: 5em; +} +.h2 { + margin-left: 2ch; + font-size: 0.85em; +} +.h3 { + margin-left: 4ch; + font-size: 0.75em; +} +.h4 { + margin-left: 6ch; + font-size: 0.65em; } -#toc ul { +#table_of_contents ul { margin: 0; padding: 0; list-style: none; } -#toc li { +#table_of_contents li { padding: 5px 10px; } -#toc a { +#table_of_contents a { color: #fff; text-decoration: none; display: block; } -#toc .toc-h2 { +#table_of_contents .table_of_contents-h2 { padding-left: 10px; } -#toc .toc-h3 { +#table_of_contents .table_of_contents-h3 { padding-left: 20px; } -#toc .toc-active { +#table_of_contents .table_of_contents-active { background: #336699; box-shadow: inset -5px 0px 10px -5px #000; } + +table tr:nth-of-type(odd) { + background: #dedede; +} diff --git a/whitepaper.html b/whitepaper.html deleted file mode 100644 index 3a0e616..0000000 --- a/whitepaper.html +++ /dev/null @@ -1,434 +0,0 @@ -<h1 id="duniter-a-libre-currency-blockchain-generator.">Duniter: A libre currency blockchain generator.</h1> -<h2 id="abstract">Abstract</h2> -<p>Many currency principles involve non-equal rights to monetary creation between humans. We propose a monetary creation based on the Relative Theory of Money, which guarantee equal monetary creation for each willing human. This type of currency can be centralised, however, this could lead to censorship and arbitrary choices of the central institution. Thus, strongly inspired by Bitcoin example, we want the currency to be as decentralised as possible, in the transaction network as in the human identification process. We use a Web of Trust between living humans for identification. This web of trust allows us to impose personalised difficulty for transaction validation, keeping the calculation accessible to low-end hardware and allowing all competent members to secure the currency.</p> -<h2 id="introduction">Introduction</h2> -<p>Duniter is a software to create and manage “libre currencies”. Libre currency is a concept defined by S.Laborde in the Relative Theory of Money (RTM) that was published in 2010. This theory demonstrates the possibility of an invariant monetary unit : the Universal Dividend. Doing so, the RTM answers the question :</p> -<blockquote> -<p>How should a currency be created to match the principle of equality between all humans, now and between generations ?</p> -</blockquote> -<p>The results of this demonstration implies a monetary creation :</p> -<ul> -<li>on a regular basis</li> -<li>for each human being</li> -<li>which amount has to be reassessed on fixed intervals according to a fixed formula.</li> -</ul> -<p>Thus, Duniter project will associate a human to a digital identity. It will use a Web of Trust with specific rules. As the number of members may evolve, the Universal Dividend has to be created according to the formula :</p> -<pre><code>UD(t+1) = UD(t) + c² * ( M(t) / N(t) )</code></pre> -<p>Duniter is based on a decentralized Blockchain. This technical choice allows irreversibility of transaction and uncensorability of trades and identities. While inspired by Bitcoin, Duniter uses a Web of Trust and the Proof of Work to secure the computation network, thus making obsolete the power race model used in Bitcoin.</p> -<p>The first currency created through Duniter is Ğ1, pronounced “June”. It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software.</p> -<h2 id="state-of-the-art-bitcoin-case">1. State of the art : Bitcoin case</h2> -<!-- source : https://duniter.org/en/theoretical/ --> -<p>Duniter uses the crypto-currency concept introduced by Bitcoin<a href="#fn1" class="footnote-ref" id="fnref1"><sup>1</sup></a>, which is to use cryptographic tools such as signatures to create trustless digital currencies. Duniter fits this definition, but it has two completely different principles than Bitcoin : the Web of Trust and the Universal Dividend . These differences are on both monetary and technical aspects.</p> -<h3 id="monetary-creation-a-space-time-asymmetry">1.1. Monetary creation of Bitcoin : a space-time asymmetry</h3> -<p>Space-time asymmetry refers to the relative access of individuals to newly created money<a href="#fn2" class="footnote-ref" id="fnref2"><sup>2</sup></a>. Concretely, most existing currencies (c. 2020) are both spatially and temporally asymmetrical for their users. Let's take Bitcoin as an example to understand why.</p> -<h4 id="spatial-asymmetry">1.1.1. Spatial asymmetry</h4> -<p>When new Bitcoins are created, only some Bitcoin users (the miners) are given new Bitcoins, while everyone else get nothing. We believe this is the first injustice. However, some might say:</p> -<blockquote> -<p>"Miners used their electricity and time to get it!"</p> -</blockquote> -<p>... we would answer that this work should not have been rewarded by newly created Bitcoins. New units should be distributed to the whole community. Miners should be rewared another way, but not by money issuance. Of course, Bitcoin cannot create money through Basic Income since Bitcoin users are not strongly identified, and one might benefit from money creation multiple times if they owned several wallets. Duniter gets rid of this problem by identifying its users and creating the same amount of Basic Income to everyone.</p> -<h4 id="temporal-asymmetry">1.1.2. Temporal-asymmetry</h4> -<p>Bitcoin has an absolute limit of 21 million BTC (its unit of currency), which means ever fewer bitcoins will be created over time until no new BTC are being generated. So, once the first adopters have mined every bitcoin, how will future joiners get Bitcoins? Just like most of us do for Euros or Dollars: to get money, they will have to work for the ones who already own it.</p> -<p>We believe this is the second injustice. Every member of a monetary community should be equal concerning monetary creation, and get the same relative amount of money over time, even if they are a late adopter. Duniter aims to fix this by making the Universal Dividend (a.k.a. UD) grow by the time according to precise rules, thus making members equal toward money issuance on a half-lifespan.</p> -<p>Most currencies present one of these two asymmetries, including metal currencies and mutual credit, as exposed in the RTM.</p> -<h4 id="a-solution">1.1.3. A solution</h4> -<p>Bitcoin has taught us that it is possible to create a currency system allowing one to both create digital money and to exchange it without a central authority. What we need to change is the way money is issued so we finally have a symmetrical system. We need <strong>Bitcoin + Universal Dividend</strong>. But Universal Dividend implies that the community consists of only identified people. This is where the Web of Trust (WoT) comes into place.</p> -<p>This concept, introduced by cryptography with the OpenPGP format<a href="#fn3" class="footnote-ref" id="fnref3"><sup>3</sup></a>, allows us to identify people in a decentralized manner. It works as follows: each person creates a personal identity that is linked to its cyptographic certificate. The identity must be confirmed by others members who use their own cryptographic key. It is that simple: people choose who is part of the community and who is not, not a central authority.</p> -<p>However, Duniter will not use OpenPGP for its cryptographic features: Elliptic Curves<a href="#fn4" class="footnote-ref" id="fnref4"><sup>4</sup></a> will be used instead for the conciseness of its generated keys and its pratical advantages. Duniter has its own Web of Trust principles, that will be exposed later.</p> -<h3 id="proof-of-work-mining-a-power-race">1.2. Proof-of-Work mining : a power race</h3> -<p>In Bitcoin Model, the calculation and incentive principles cause a power race : new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. This leads to a power race an places the control over the currency in the hands of the richest hardware owners. We want to make Duniter blockchain validation much less energy and hardware consuming while keeping a strong level of security. This will be further explained later. A consequence of this choice is the participation of low-end hardware in the Duniter network, leading to a better decentralization of blockchain validation.</p> -<h4 id="what-about-proof-of-stake">1.2.1 What about Proof of Stake ?</h4> -<p>Proof of stake consensus algorythm was first introduced in 2012<a href="#fn5" class="footnote-ref" id="fnref5"><sup>5</sup></a>. The basic principle is to allow the richest wallets to issue blocks, putting their coin balance as a “stake” they would lose in case of cheat.</p> -<p>At the time of conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. We did not chose this consensus principle. Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead to placing power over the currency in the richests hands : this is contrary to the symmetical principles of a libre currency.</p> -<h2 id="duniters-blockchain">2. Duniters Blockchain</h2> -<!-- source : https://duniter.org/en/theoretical/ --> -<p>Duniters Blockchain follows the basic principles of Bitcoins. This is essential for synchronization between peers, as to prevent double-spend attacks. However, Duniters Blockchain will store different informations than Bitcoins.</p> -<p>The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no generation transaction exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either:</p> -<ul> -<li>a former transaction (as in Bitcoin)</li> -<li>a Universal Dividend (specific to Duniter).</li> -</ul> -<p>Duniters Web of Trust is also written in the Blockchain. The identity of each member gets registered much like transactions are, with a strong link to the time reference. Thus, the Blockchain is a representation of a space-time frame of reference, where “space” are members of the WoT and “time” the basic blockchain units : the blocks. On each point of time, one can determine which account is legitimate to create the UD, only with a blockchain analysis.</p> -<h3 id="spam-countermeasures">2.1. Spam countermeasures</h3> -<p>An issue of most cryptocurrency projects is to prevent the common ledger from growing too much. This would require nodes to have a lot of storage and computing power to be usable. In particular, we don’t want an attacker to be able to make the Blockchain grow too fast. Most projects implement transaction fees as a way to prevent this, making the attacker lose money. We don’t want to introduce this mean since a currency with automatic fees on transactions is no more neutral. Several countermeasuers against such spam attacks are implemented.</p> -<!-- see : https://forum.duniter.org/t/sans-frais-de-transaction-comment-resister-aux-attaques/3846/25 (implemented ?)--> -<h4 id="minimum-output-amount">2.1.1. Minimum output amount</h4> -<!-- This has to be implemented in DUBPv13. --> -<p>Fixing a minimal output amount reduces the power of an attack. Duniter deals with cents of Ğ1 or 1/1000 of the first UD. An attacker could create thousand accounts with only 1 UD. To prevent this, a valid transaction must have output amounts of minimum 1Ğ1. This reduces the power an attack by 100.</p> -<h4 id="limited-block-size-and-chainability">2.1.2. Limited block size and chainability</h4> -<p>The block size is always limited. While the protocol allows this limit to evolve to address scaling issues, an attacker cannot register as many transaction as they wish.</p> -<p>With the same goal to prevent too many transactions to get registered, while transactions can be “chained” (refer to another transaction in the same block), the chainability of transactions is limited to 5.</p> -<h3 id="scaling">2.2. Scaling</h3> -<p>Most of the time, the scaling issue rises for distributed systems that should work on a very large scale. This is not the case of Duniter, for multiple reasons :</p> -<ul> -<li>Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don’t want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT should limit its size to around 16 million members.</li> -<li>Duniter’s aim is to be used to create multiple libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community.</li> -</ul> -<p>However, Duniter has assets that will help if the number of users and transactions grow.</p> -<h4 id="dynamic-block-size">2.2.1 Dynamic block size</h4> -<p>While Bitcoin has a fixed block size, Duniters blocks size can evolve. On low use of the blockchain, the maximal block size is 500 bytes. On high use of the blockchain, the maximal block size would be 110% of the average size of the current window blocks(see “personalised difficulty” part for more information). This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it. The block size (in bytes) is limited as so :</p> -<pre><code>block_size < max(500 ; CEIL(1.10 * (average block size))</code></pre> -<h4 id="lightning-networks">2.2.2. Lightning Networks</h4> -<p>The Lightning Networks<a href="#fn6" class="footnote-ref" id="fnref6"><sup>6</sup></a> allow almost instant and off-chain transactions. They were first implemented on Lightcoin, and are now on Bitcoin. One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. While not available yet, this payment channel might get implemented when needed.</p> -<h4 id="unit-base">2.2.3. Unit base</h4> -<p>As the Universal Dividend grows exponentially, with time Duniter nodes would have had to deal with always largest amounts, eventually reaching the BIGINT limit. To avoid this, the amounts are expressed with a unit base in base 10. We want the UD amount to always fit in 4 digits. To manage it, the <code>unitbase</code> is updated each time the UD value reaches 100.00 : it goes from <code>99.99*10^(unitbase)</code> to <code>10.00*10^(unitbase+1)</code>. All the unit amounts are thus divided by 10. While this might seem strange, this process has already hapened in state currencies. Moreover, the amounts expressed in UD will not change.</p> -<p>With a monetary growth of 10% each year and a stable population, such a change of unit base would happen each 25 years.</p> -<h2 id="duniter-web-of-trust">3. Duniter Web of Trust</h2> -<h3 id="duniter-wot-basic-principles">3.1. Basic Principles</h3> -<p>In order to identify “members” accounts - which create monetary units - and other accounts, Duniter uses a Web of Trust. This can be summarized into few principles:</p> -<ul> -<li>Each account becomes a member if it received a minimal number of certifications - 5 for Ğ1 currency.</li> -<li>Only members accounts can send certifications. Certifications have a limited lifespan.</li> -<li>A certification indicates that the sender accepts the receiver as a legitimate identity.</li> -</ul> -<p>The aim of the WoT is to identify a blockchain account to a living human. According to Lauterbach et.al<a href="#fn7" class="footnote-ref" id="fnref7"><sup>7</sup></a>, the strengh of a relationship should be considered when building a vouch system. For this reason, the Ğ1 Web of Trust rules are expressed in a licence stating what WoT certifications are. A certification represents a strong human relationship : one may certify a close relative, not an acquaintance. Each member has to accept this licence before being included in the WoT. Thus, if a member is part of an attack on the currency, they can be found by mutual relatives. Additional security rules occur to prevent cheat and attacks on a large scale.</p> -<p>Note that non-members accounts can use the currency, but cannot create money. Non-members accounts can be used by individuals as secondary wallets, or by institutions.</p> -<p>We were inspired by the OpenPGP Trust system<a href="#fn8" class="footnote-ref" id="fnref8"><sup>8</sup></a>. However, the OpenPGP trust principles aim at defining trust from a particular point of view while Duniter needs to identify humans for the whole community. To achieve this goal, while OpenPGP allows each user to tweak its trust parameters individually, Duniter sets rules in the “genesis” block for the whole community.</p> -<h3 id="why-do-we-need-a-web-of-trust">3.2. Why do we need a Web of Trust ?</h3> -<p>There are two reasons we need it :</p> -<ol type="1"> -<li>To make sure that only one Universal Dividend is produced per member at each specified creation interval. In the Ğ1’s case this interval is set as daily <code>86 400</code> seconds, it is the <em>monetary parameter</em> known as <code>dt</code>.</li> -<li>To identify the nodes hashing the blocks and assign each a personalised difficulty. This custom difficulty proof of work is there to avoid the blockchain’s validation mechanism becoming too centralised as is the case with many 'non-libre’ cryptocurrencies.</li> -</ol> -<blockquote> -<p><strong>Monetary parameter</strong> : Each currency that use Duniter has its own blockchain whose behaviour is dictated by a set of ‘parameters’ defined in block zero - the so-called genesis block - that can be tweaked to achieve the desired results. At the time of writing the Whitepaper, the Duniter Blockchain Protocol (DUBP) has a total of 21 parameters of which 10 are for the WoT alone. We’ll focus on these 10.</p> -<p>Suffice to say that in the Ğ1’s case, the DU is created every 24 hours - 86 400 seconds. This interval is set through the time derivative <code>dt</code> parameter and can have a different value in other implementations of the protocol.</p> -</blockquote> -<p>We want to make sure that each member can only have one account. As we all know, achieving zero-risk isn’t possible<a href="#fn9" class="footnote-ref" id="fnref9"><sup>9</sup></a>. Our goal is therefore not to create a WoT within which fraud would be absolutely impossible, but instead to discourage it. Here is a rewording of our goal in 4 smaller ones :</p> -<ol type="1"> -<li>Make the certification process lengthy enough that all members exercise due diligence and are wary of risks.</li> -<li>Make fraudulent acts as hard as we can to the extent that they become pointless.</li> -<li>Ensure that any Sybil attacks have a negligible impact on the currency by ensuring that illegitimate double Universal Dividends have no significant bearing on the legitimate monetary mass</li> -<li>Slow the growth of ‘Sybil regions’ to give enough time for the community to react and isolate the threat.</li> -</ol> -<blockquote> -<p><strong>Sybil attack</strong> : A Sybil attack is an attack perpetrated on a reputation system through the creation of fake identities. A Web of Trust is a specific instance of a Reputation System.</p> -</blockquote> -<p>There are plenty of Sybil attack scenarios we can think of and just as many reasons why their perpetrators would want to carry them out. Our objective is that the configuration of the WoT protects both users and its IT backbone infrastructure against these attacks.</p> -<p>This means that micro-attacks performed by small groups of individuals looking for personal enrichment are of no interest to us. The web’s role isn’t to deter these attacks, this being instead the role of the community. Just like the town you live in is responsible for providing your tap water and electricity but isn’t responsible for any burglaries, etc. Much in the same way, Duniter’s WoT guarantees us all a functional currency, but do not detect small fraud.</p> -<h3 id="own-certification-system">3.3. The importance of having our own certification system</h3> -<p>Centralized identification systems can achieve the goal we want. State Identification is an example. However, this has many drawbacks :</p> -<ul> -<li>The authority may have arbitrary criteria for identification, for example preventing people without an official state-provided identity or homeless people to be included in the WoT.</li> -<li>Payment might be required to get identified, thus making the monetary creation not “free”.</li> -<li>The authority is a point of failure for any attacker.</li> -</ul> -<p>It is of the utmost importance that we remain free from any state or corporation. The WoT is an answer to this criterium. To this day we depend only on the Internet and yet, were it to fail, there are already alternatives being tested around the world for a decentralised communication network.</p> -<h3 id="graph-theory-vocabulary">3.4. A few foundational concepts on graph theory : a bit of vocabulary</h3> -<ul> -<li><p><strong>Graph</strong>: set of points -called ‘vertices’- joined by edges -called paths/walks-.</p></li> -<li><p><strong>Simple graph</strong>: a graph with no loops and with no multiple edges. That is, each edge connects two distinct endpoints and no two edges have the same endpoints. A simple edge is an edge that is not part of a multiple adjacency -of edges-. In many cases, graphs are assumed to be simple unless specified otherwise.</p></li> -<li><p><strong>Directed graph</strong>: a graph in which the edges have a distinguished direction, from one vertex to another. A directed edge can also be called a path or walk. Arrow A –> B is therefore different from arrow B –> A.</p></li> -<li><p><strong>Endpoints</strong>: the edge with vertex A –> B has A and B as endpoints, respectively as start and end of the path/walk.</p></li> -<li><p><strong>Isolated vertex</strong>: a vertex whose degree is zero, that is, a vertex with no incident edges.</p></li> -<li><p><strong>Degree of a vertex</strong>: number of its incident edges -in and out-.</p></li> -<li><p><strong>Out-degree of vertex A</strong>: number of outbound edges / tail ends from A.</p></li> -<li><p><strong>In-degree of vertex A</strong>: number of incoming edges / head ends to A.</p></li> -</ul> -<figure> -<img src="./images/degres.jpg" alt="degrees of a vertex diagram" /><figcaption>degrees of a vertex diagram</figcaption> -</figure> -<ul> -<li><strong>Path</strong>: -aka “walk”- path to follow to get from vertex A to vertex B.</li> -</ul> -<h3 id="definition-of-the-duniter-web-of-trust">3.5. Definition of the Duniter Web of Trust</h3> -<p>The Duniter WoTs -one per currency- are simple directed graphs without isolated vertices. The vertices are the members and the edges are the certifications given and received.</p> -<p><em>Directed</em> means that the responsibility of issuing a certification is unique and personal to the certifier. The trust they place in the receiver cannot be imposed in the other direction although in most circumstances both parties equally trust each other.</p> -<p>In addition, all vertices are either currently active members or past-members. Past-member vertices are in a specific ‘deactivated state’ and can no longer issue or receive certifications although the ones already issued or received to/from other members are still considered ‘pending’ to avoid a collapse of the WoT. If these old members don’t come back into the WoT, their pending certifications will eventually expire and they will switch from ‘deactivated’ to ‘isolated’ vertices.</p> -<p>To wrap up with old members, after a certain period of time - set in the currency’s parameters - their deactivated vertex is removed from the web and the associated identity is ‘revoked’. The person who owned the account can no longer use this identity but is free to join the web with another one.</p> -<blockquote> -<p><strong>Identity</strong> : An identity is a set of three pieces of information: a public key, a name and a blockstamp. A blockstamp points to a specific block in the chain. Its main use is to freeze the point in time at which an identity was created and to link this identity to a specific chain and a currency - each currency having its own blockchain.</p> -<p>An identity can be in any one of 5 different status: pending, member, old member, revoked or excluded.</p> -</blockquote> -<p>Let’s take a simple example:</p> -<pre><code> A -> B -> C - | - \--> D</code></pre> -<p>If, for whatever reason, A were to lose its member status, the web would crumble and all other members would be excluded as a consequence. To avoid this, the certification from A –> B will remain valid until its expiry date, leaving enough time for B to receive certifications from C or D.</p> -<p>Because our WoT doesn’t have any isolated vertices, each new identity created needs to be pulled into the web with all of the certifications it has received, all in the same block. This calls for a temporary ‘buffer’ storage space for <strong>pending</strong> identities and the certifications they have received. This storage space is called ‘the pool’ of Duniter nodes, which we could also have called the ‘sandbox’ as that’s the name used in Duniter’s code. Duniter nodes inclued other ‘pools’ for other documents and metadata not mentioned here.</p> -<h3 id="exploring-the-rules-behind-duniter-wot">3.6. Exploring the rules behind a Duniter Web of Trust</h3> -<p>The Duniter WoTs - one per currency - works with a set of eight fundamental rules enforced through eleven different parameters. Ten of these parameters are set within the genesis block, the eleventh one - <code>msPeriod</code>- having being hard-coded in the Ğ1’s code subsequently.</p> -<h4 id="distance-rule-and-referent-members-stepmax-and-xpercent">3.6.1. Distance rule and referent members (<code>stepMax</code> and <code>xPercent</code>)</h4> -<p>These two parameters are closely linked and together define the ‘distance rule’. The ‘distance rule’ can only be described after defining what a ‘referent member’ is:</p> -<blockquote> -<p><strong>Referent member</strong>: member A is said to be ‘referent’ if and only if the total of their degrees are greater than or equal to <code>CEIL-N^-1/stepMax</code> where N is the total number of members. As the size of the web will grow this number will grow too, meaning it will take more certification issuances to become a referent member. The number of certifications needed to become a member shouldn’t change.</p> -</blockquote> -<p>Let’s now define the distance rule:</p> -<blockquote> -<p><strong>Distance rule</strong>: member A is said to observe this rule if and only if for a subset xPercent % of referent members R there exists a path of length less than or equal to <code>stepMax</code> between R and A.</p> -</blockquote> -<p>Referent members only exist so that the distance rule can take effect, they have no special privileges over non-referent members. In a perfect web, that is one in which each member has certified all members they legitimately can, all members would be referent members. However, because the web progressively grows in size and because members die and are replaced by new ones, there are always members at any given time <code>t</code> who haven’t yet certified all members they legitimately could. These members would hinder the evolution of the web if they were taken into account in the calculation of the distance rule and the web would effectively stop growing.</p> -<p>Because verifying the application of the distance rule is calculation-greedy, it is only performed when a new identity gets confirmed into the web or an existing member gets renewed. There is an exception to this rule: the distance rule is not observed in the genesis block -when the web is first implemented.</p> -<h4 id="rule-of-the-minimum-number-of-certifications-needed-sigqty">3.6.2. Rule of the minimum number of certifications needed (<code>sigQty</code>)</h4> -<p>This is the simplest rule, it essentially says that each member must at any given time -meaning in any single block- have received at least <code>sigQty</code> active certifications. If, for whatever reason, member A were to have less than <code>sigQty</code> active certifications in a given block, they would cease to be a member and be required to publish a request for identity renewal.</p> -<h4 id="the-membership-renewal-rule-msvalidity-msperiod-and-mswindow">3.6.3. The membership renewal rule (<code>msValidity</code>, <code>msPeriod</code> and <code>msWindow</code>)</h4> -<p>Bear in mind that a membership doesn’t last a lifetime but instead has a lifespan set to <code>msValidity</code> seconds.</p> -<p>Every single member -or old member who hasn’t revoked his identity or been excluded- can request a membership renewal so long as the last request was made more than <code>msPeriod</code> seconds ago. If a member has never requested a renewal, the date of last renewal is equal to the timestamp at which his membership was first created. A new request will be stored in the ‘pool’ for a maximum of <code>msWindow</code> seconds before it’s included in the blockchain. Once again, this can only happen once/if the member meets both the <code>siqQty</code> rule and the distance rule -if these criterion are already matched it’s just a case of waiting for a new block to be mined-.</p> -<p>If a member hasn’t requested a renewal for longer than <code>msValidity</code> seconds, they automatically cease to be a member. From this moment on, the ex-member has another <code>msValidity</code> window to renew their membership. When this period of <code>2 × msValidity</code> runs out, the membership will expire and this identity will never be available for use again in the web. If the person so desires, they will have to publish new identity and membership documents and find enough certifiers, as any newcomer.</p> -<h4 id="rule-of-certification-lifespan-sigvalidity">3.6.4. Rule of certification lifespan (<code>sigValidity</code>)</h4> -<p>All certifications included in the blockchain expire <strong>sigValidity</strong> seconds after they were <strong>issued</strong>.</p> -<blockquote> -<p>/!\ The issuance and the inclusion of a certification in the blockchain occur at different times. When member A issues a certification at time t1, it gets stored in the pool starting at t1 and only finds its way into the blockchain at t2 when all of the web’s rules are observed. Several weeks can thus go by between t1 and t2!!!</p> -</blockquote> -<h4 id="rule-of-limited-supply-of-active-certifications-sigstock">3.6.5. Rule of limited supply of active certifications (<code>sigStock</code>)</h4> -<p>By ‘active certifications’ we refer to certifications included in the blockchain and that haven’t yet expired.</p> -<p>The total of active certifications issued by any member at any single time must be less than or equal to <code>sigStock</code>. When this threshold is reached the member will have to wait for one of his active certifications to expire before he/she can issue a new one.</p> -<h4 id="rule-of-the-time-period-between-two-certification-issuances-sigperiod">3.6.6. Rule of the time period between two certification issuances. (<code>sigPeriod</code>)</h4> -<p>As soon as a certification issued by member A gets included in the blockchain, they will be unable to issue a new one before another <code>sigPeriod</code> seconds.</p> -<h4 id="expiry-of-a-certification-issuance-sigwindow">3.6.7. Expiry of a certification issuance (<code>sigWindow</code>)</h4> -<p>When a certification is issued by member A, it will be stored in the ‘pool’ for a maximum of <code>sigWindow</code> seconds. If the certification hasn’t been included in the blockchain by then, it will be cancelled and the member’s <code>sigStock</code> will be repleted by one.</p> -<h4 id="lifespan-of-a-pending-identity-idtywindow">3.6.8. Lifespan of a ‘pending’ identity (<code>idtyWindow</code>)</h4> -<p>When a new identity is created, it is stored in the ‘pool’ for a maximum of <code>idtyWindow</code> seconds. If the person hasn’t achieved member status by then, the certification will simply be cancelled.</p> -<h3 id="details-on-some-of-the-wots-peculiarities-at-the-genesis-block">3.7. Details on some of the WoT’s peculiarities at the genesis block</h3> -<p>The aforementioned rules can only be enforced with an existing web. They cannot be observed when first creating the web, that is when defining the genesis block.</p> -<p>Only rules 2 and 5 can be observed at the genesis block.</p> -<p>The genesis block has to be manually created by the founding members. In practice this means that there must be a choice on which identities to include on the premise that all of them observe rules 2 and 5. In addition, the genesis block must be signed with the private key of one of these identities.</p> -<p>As soon as the genesis block has been created, the other identities can start mining the blockchain and the member who created block #0 effectively looses the decision power he had at creation.</p> -<h3 id="why-these-rules-and-application-cases-in-the-g1">3.8. Why these rules and application cases in the Ğ1</h3> -<h4 id="distance-and-maximum-size">3.8.1. Distance and maximum size</h4> -<p>The distance rule is there to curb the maximum size of a Sybil region as well as that of the monetary community as a whole. The <code>xpercent</code> parameter prevents the creation of a ‘faction’ that could take hold of the blockchain.</p> -<figure> -<img src="./images/wot-sybil.jpg" alt="Sybil region" /><figcaption>Sybil region</figcaption> -</figure> -<p>The Sybil regions are isolated from the rest of the graph in the sense that they can only receive certifications from other ill-intentioned Sybil members. As a consequence, the shortest edge/path between a legitimate member and a Sybil one has to have the attack’s author as an endpoint. The maximum depth the Sybil region can attain is therefore contingent on the distance between the attacking edge-s- and the xpercent% closest referent members, this distance is known as <code>stepAttackers</code>. The maximum size of a Sybil region created by <code>sigQty</code> members depends on the L parameter, defined as <code>L = sigQty/sigStock</code>:</p> -<pre><code>MaxSybilSize= (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L)</code></pre> -<p>The maximum size of the Web of Trust is given by the following formula:</p> -<pre><code>WoTmax = (sigStock)*L^(stepMax-1)</code></pre> -<p>However we know for a fact that members will never use all of their available certifications. According to Dunbar<a href="#fn10" class="footnote-ref" id="fnref10"><sup>10</sup></a>, on average, one is able to maintain relationships to around 150 people. Being conservative, we will consider that on average, each person will certify 50 accounts. We can calculate the size of the average web of trust <code>WoTavg</code> :</p> -<pre><code>WoTavg= (50)*(sigQty/50)^(stepMax-1)</code></pre> -<p>Our goal with the Ğ1 is to create a community of about one million members to test the consequences of a libre monetary system. Let’s see how we can tweak the pair of sigQty and stepMax- to reach this size:</p> -<figure> -<img src="./images/wot-moy.png" alt="Average WoT size graph as a function of sigQty and stepMax" /><figcaption>Average WoT size graph as a function of sigQty and stepMax</figcaption> -</figure> -<p>The maximum size of a Sybil region grows linearly with <code>sigQty</code> but exponentially with <code>stepMax</code>. Logic has it that we need to keep <code>stepMax</code> as low as possible to ensure sufficient strength to the web. The above graph shows that the lowest value of <code>stepMax</code> for a web of a million members is of 5. This is an order of magnitude and is likely to be much higher in reality, we cannot measure it for sure.</p> -<p>For <code>sigQty</code> we can choose a value of <strong>4</strong> for a web of <strong>1.5 million members</strong> or <strong>5</strong> for <strong>half a million members</strong>. Bear in mind these are gross figures and could be significantly higher, we are talking anywhere between 1 and 10 million in reality. Calculating WOTavg gives us a pretty good idea of how the web would scale bearing in mind that it considers all members are referent members too -which isn’t the case as explained previously-. Hence the maximum size of the web is likely larger, a ballpark figure of half a million is enough for now especially knowing that the smaller <code>sigQty</code> is, the easier it is to launch a Sybil attack -it’s easier to find four accomplices than five-. For security reasons we have settled on five:</p> -<pre><code>stepMax = 5 -sigQty = 5 -sigStock \>= 50</code></pre> -<p>The maximum size of a Sybil region therefore is:</p> -<pre><code>(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5))</code></pre> -<p>with sigStock = 50 we have a Sybil region of:</p> -<pre><code>45*(1-10^(5-stepAttackers))/(-9)</code></pre> -<p>A good practice for protecting the web is to maximise <code>stepAttackers</code>. That’s why we decided that referent members in the genesis block had to be at least four steps away from each other.</p> -<p>Another way to keep a Sybil attack at bay, were it slow enough for members to notice it, would be for referent members to ‘stretch’ the web intentionally to limit the growth of the region by ensuring that the attackers’ legitimate certifications received in the first place aren’t renewed. But what if bot accounts were created and certified each other super fast and following all rules, how would we counter that? By introducing a minimum length of time between two certifications!</p> -<h4 id="time-is-our-friend">3.8.2. Time is our friend</h4> -<p>To help us deter a Sybil attack, we’ve decided to impose a minimum period of time between any two certifications issued from a single account. This parameter called <code>sigPeriod</code> affords us a greater chance to detect the formation of a ‘hostile’ faction.</p> -<p>Here is a graph showing the evolution of a Sybil region with the variation of <code>sigPeriod</code>. The simulation considers that honest members and attackers both issue a certification each <code>sigPeriod</code> interval, in days:</p> -<figure> -<img src="./images/impact_sig_period.png" alt="size of the WoT according to sigPeriod and stepAttackers" /><figcaption>size of the WoT according to sigPeriod and stepAttackers</figcaption> -</figure> -<p>As we see, there is a strong link between the growth speed of the region and <code>sigPeriod</code>. As evidenced here, we need a <code>sigPeriod</code> high enough in order to ensure that the legitimate web can grow at least as fast as a Sybil region. In addition, the higher <code>sigPeriod</code> is, the more members will exercise their certification power gingerly, the action coming at a higher ‘cost’.</p> -<p>There are numerous advantages to giving <code>sigPeriod</code> a high value and no technical barriers to it, hence our choice of five days.</p> -<p>We could have also gone for one week for the sake of simplicity. However there is an underlying idea behind our choice which was quite simply the pace of today’s life. Certifying someone can be a lengthy process as one needs to make sure they are correctly applying the Ğ1 licence and people nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea to allow one to certify at the end of every working week -five days- instead of a whole calendar one.</p> -<h4 id="trust-me-now-trust-me-forever-sigvalidity-msvalidity">3.8.3. Trust me now, trust me forever ? (<code>sigValidity</code>, <code>msValidity</code>)</h4> -<p>There would be two main drawbacks to a lifetime membership in the Ğ1’s Web of Trust:</p> -<ul> -<li>First of all, some members will pass and those accounts should no longer produce the Universal Dividend.</li> -<li>Secondly it is of the utmost importance that ‘rogue’ accounts can be excluded from the web at some point.</li> -</ul> -<p>To achieve this, certifications have a limited lifespan. Members need to seek renewal from their peers after <code>sigValidity</code> time. On the other hand, this time can’t be too short that members would spend more time seeking renewal than they would exchanging in the currency. Furthermore, a certification with too short a lifespan would foster careless certifying behaviours. The act of certifying must have a high-enough ‘perceived’ cost to make it feel like an important act. Lastly, we also wanted this lifespan to be easy to remember. Historically speaking, we first settled on the values of <code>sigPeriod</code> and <code>sigStock</code>, meant one could issue all of their certifications in 495 days, one year was therefore not long enough. We deemed three years to be too much and that’s how we agreed on two years in the end.</p> -<p>Thinking that a deceased member could continue producing the UD for two long years without anyone benefitting from it was also something we needed to address. We chose a value of one year for <strong>msValidity</strong>. The act of renewing every year is done through one of the clients interacting with the blockchain, through a simple click on a button. This parameter is less important than others and is mostly there to ‘prune’ the web of past or inactive members who don’t renew their membership.</p> -<h4 id="keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow">3.8.4. Keeping the pools free of information glut (<code>idtyWindow</code>, <code>sigWindow</code>, <code>msWindow</code>)</h4> -<p>The pools need to be cleaned up on a regular basis to avoid them clogging up with information and to ensure that machines with less calculating power can still run a Duniter node.</p> -<p>To achieve this, identities with pending membership approval and the corresponding certifications have to remain the shortest time possible in the pool while still having a chance of making it into the blockchain.</p> -<p>For the Ğ1, our opinion was that two months would be enough for all potential certifiers to agree on a specific identity to certify. We also wanted a time period that would be easy enough to remember by all. We settled on two months, and gave this value to all three parameters <code>idtyWindow</code>, <code>sigWindow</code> and <code>msWindow</code>.</p> -<h4 id="avoiding-single-members-from-knowing-too-many-people-sigstock">3.8.5. Avoiding single members from ‘knowing too many people’ (<code>sigStock</code>)</h4> -<p>We considered that on average, each person will certify 50 people. However, we know for a fact that some members will use more than 50 certifications. The maximum social network of one individual is around 150 people<a href="#fn11" class="footnote-ref" id="fnref11"><sup>11</sup></a>. Being conservative, we settled on a maximum certification number <code>sigstock</code> of 100.<br /> -Since <code>sigStock</code>’s impact on the size of a Sybil region is fairly limited, we did not investigate further this parameter.</p> -<h4 id="avoiding-locking-minorities-xpercent">3.8.6. Avoiding locking minorities (<code>xpercent</code>)</h4> -<p>It’s easy enough to become a referent member, one of the Sybil strategies could therefore be to create a region of referent members. Such a region would grow slower than otherwise but could confer a locking power to its members by using the distance rule. That’s why the distance rule cannot be calculated on 100% of the referent members. Hence the introduction of the <code>xpercent</code> parameter which defines the percentage of referent members needing to be less than five edges -steps- from each other.</p> -<p>This percentage needs to be low enough to prevent the formation of a locking minority -referent Sybil members being too far from legitimate referent members-. On the other hand, it needs to be high enough so as to restrict the maximum size of the Sybil region through the distance rule. The <code>xpercent</code> parameter was one of the hardest to define, therefore we might decide to change its value during the Ğ1 experiment.</p> -<p>We were inspired by the Pareto principle<a href="#fn12" class="footnote-ref" id="fnref12"><sup>12</sup></a>: if at least 20% of members give good density to the web, 80% of the referent members will be five or less steps from any other member -referent or not-. The maximum value for <code>xpercent</code> is therefore 80%, anything above that and the distance rule could be too restrictive for legitimate use cases. With security our top concern, we chose the maximum value of 80%.</p> -<h4 id="spam-protection-with-msperiod">3.8.7. Spam protection with (<code>msPeriod</code>)</h4> -<p>This parameter stands out a bit on its own, as it was added after the genesis block. It is there to protect the Duniter P2P infrastructure against ‘spam’ attacks. We had to think of a strategy against attacks such as high-frequency membership renewal requests -i.e: in every block, every five minutes- or worse still, hundreds of these requests per minute to flood the Duniter nodes. Without such limits, nodes are supposed to address all renewal requests, even in cases where they were last published five minutes ago! The <code>msPeriod</code> parameter was given the same value as <code>idtyWindow</code>, <code>sigWindow</code> and <code>msWindow</code>, i.e. two months.</p> -<h2 id="proof-of-work-with-personalized-difficulty">4. Proof of Work with personal difficulty</h2> -<p>As each P2P cryptocurrency, Duniter has a way to synchronize its peers. It uses a proof of Work (PoW) to write the Blockchain on a regular basis, much like BitCoin. However, Duniter has a unique asset : the WoT, where each member represents a unique living human.</p> -<p>This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each “winning” member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. A view of the whole network is not needed.</p> -<p>Another strong difference is that forging peers are not rewarded by the protocol. There is no economical incentive on forging lots of blocs, neither on having a lot of computing power.</p> -<p>One could say that Duniter uses a PoW that needs very low energy consumption compared to BitCoin : an “ecological” PoW ?</p> -<!-- source : https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/ --> -<h3 id="why-proof-of-work">4.1. Why do we need Proof of Work ?</h3> -<p>Duniter nodes share a database as part of a p2p environment. The proof of work (PoW) allows machines to synchronize with each other. In Duniter’s case, the blockchain is our database, and acts as a ledger keeping a trace of all transactions, status of the WoT and more. How can we let several machines add data (ie: a transaction) at the same time? In addition, how do we settle on how much time has gone by since the blockchain was last updated? Agreement on time is of the utmost importance as we want to create Universal Dividends on a regular basis, and keep track of membership status, both in human time.</p> -<p>Proof-of-work provides a clever solution to both problems:</p> -<ol type="1"> -<li><p>Any machine can write into the blockchain (create a new block) but is only authorised to do so if it has previously solved a mathematical equation that require a certain amount of work. The challenge has to be hard enough to prevent two machines to solve it at the same time, ensuring the unicity of a block’s creator.</p></li> -<li><p>Solving this challenge takes a certain amount of time, which depends on the calculating power of the whole network. This provides a common ground for defining the needed time reference. A block time is set (ie: 1 block = 5 min) and Duniter adapts the challenge difficulty to get an average duration corresponding to this block time.</p></li> -</ol> -<h3 id="only-members-can-mine">4.2. Only members can “mine”</h3> -<p>One of Duniter’s major differences with other PoW-based cryptocurrencies is that only members are allowed to author blocks. Each block is signed with the member’s private key, allowing the algorithm to determine a personalised difficulty.</p> -<p>This personalised difficulty eliminates the rat-race for the most sophisticated and powerful mining equipment. Another benefit is the fact that no “supercomputer” can take control of the blockchain. Lastly, Duniter implements a rotation in forging members thanks to this personalized difficulty.</p> -<p>This lightweight PoW is much less energy-consuming than other PoW cryptocurrencies. Members can mine with anything from a raspberry pi to a privacy-first internet cube.</p> -<h3 id="how-does-duniter-pow-work">4.3. How does it work ?</h3> -<h4 id="the-hash">4.3.1. The hash (aka digest)</h4> -<p>Example of a valid hash:</p> -<pre><code>00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653</code></pre> -<p>As you can see this hash starts with five zeros which was very hard to achieve and took a lot of work for someone’s computer. Hence the term “proof of work”.</p> -<h4 id="common-difficulty">4.3.2. The common difficulty</h4> -<p>A common difficulty is needed to settle on a yardstick for our time reference. Its role is to make sure the blockchain moves forward at a steady pace - one block every <code>avgGenTime</code> seconds, <code>avgGenTime</code> being one of the 20 parameters behind the Duniter protocol-.</p> -<p>This difficulty’s initial value can be set to any arbitrary value (<code>70</code> in Duniter <code>v1.5.x</code>) and then acts as a spring, regulating blocktime creation by increasing itself if the creation interval drops under <code>avgGenTime</code> and vice-versa.</p> -<h5 id="how-is-difficulty-applied">4.3.2.1. How is difficulty applied ?</h5> -<p>The numeric value of difficulty is taken from an array of possible hashes out of all possible hashes. In DUBPv13 the hash of a block is its sha256 hexadecimal hash.</p> -<p>To understand the difficulty, we make a euclidiean division of the difficulty by 16.</p> -<p>Here’s an example with a difficulty value of 70 :</p> -<pre><code>70 // 16 = 4 with a remainder of 6. </code></pre> -<p>The valid hashes are the ones starting with four zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). The valid hashes are then written as starting with : <code>0000[0-9]</code>. This is a bit different from Bitcoin, where the difficulty is only ruled by the number of zeroes.</p> -<h5 id="the-nonce">4.3.2.2. The Nonce</h5> -<p>When a member is forging a new block, his computer freezes the block’s content and changes the Nonce until the hash reaches the required number of zeroes.</p> -<p>The nonce allows us to mine a new block by finding a hash. The hash value allows us to determine the difficulty level of the proof-of-work performed. Examples of possible Nonce values:</p> -<ul> -<li>10100000112275</li> -<li>10300000288743</li> -<li>10400000008538</li> -<li>10700000079653</li> -<li>10300000070919</li> -</ul> -<p>In reality the <code>Nonce</code> value follows a pre-determined format akin to <code>XYY00000000000</code>. The Nonce’s value isn’t the number of attempts but rather a value within a set of possible ones. This is how the Nonce is built:</p> -<ul> -<li><p>X is a number assigned to a specific peer. Let’s assume that someone has several nodes each with the same private key, this would lead to possible collisions if this person were to mine the same block with different nodes. Each <del>block</del> <strong>node ?</strong> will therefore have its own unique X to prevent this from happening.</p></li> -<li><p>Y is the number of cores of the processor. The Nonce starting with <code>107[…]</code> belongs to a seven cores processor, while <code>199[...]</code> could be the proof generated by a 99 cores processor.</p></li> -</ul> -<p>The rest of the Nonce, the part that follows after the XYY, is the numerical space for this individual node and is unique to each of the CPU’s core. This space is comprised of eleven digits (<code>00000000000</code>). For the sake of accuracy, we use the term CPU in the wider sense, it can be understood as a bi-CPU for example. We take into consideration the number of cores for the resulting PoW.</p> -<h3 id="personalised-difficulty">4.4. Personalised difficulty</h3> -<p>Earlier in this article, we explained that the personalised difficulty is the new and key concept that sets Duniter apart from other PoW-based cryptocurrencies.</p> -<p>Here is how this personalised difficulty is calculated and assigned:</p> -<p>It is determined by a combination of two different constraints with complimentary roles: the <strong>exclusion factor</strong> and the <strong>handicap</strong>.</p> -<p>Let <code>powMin</code> be the common difficulty, <code>exFact</code> a member’s exclusion factor and <code>handicap</code> their handicap. This member’s personalised difficulty <code>diff</code> is:</p> -<pre><code>diff = powMin*exFact + handicap</code></pre> -<h4 id="the-exclusion-factor">4.4.1. Understanding <code>exFact</code>, the exclusion factor</h4> -<p>Members who have never produced blocks or haven’t for quite some time are assigned an exclusion factor of <code>1</code>. Their personalised difficulty is therefore simply the sum of <code>powMin + handicap</code>.</p> -<p>Before reading on, let’s precise the role of this exclusion factor. When a member adds a block to the chain, his <code>exFact</code> jumps up from one to a very high value, to prevent them from forging other blocks immediately after and taking control of the blockchain.</p> -<p>The exclusion factor will then rapidly return to one. This delay is expressed as a number of blocks. It is calculated as a proportion of the number of members forging. In the Ğ1’s case, this proportion is 1/3, meaning that if there are fifteen members currently forging, the member’s exclusion factor will drop down to one after five blocks.</p> -<h5 id="what-is-intended-by-the-number-of-members-forging">4.4.1.1. What is intended by “the number of members forging” ?</h5> -<p>We mean the number of members trying to create the next block. In reality, there is no way to precisely know how many members are calculating at any given time, because it is impossible to view the entire network. But we need this information, whithout which assigning a personalised difficulty is impossible. To achieve this, Duniter looks back at the blockchain and assumes that there is as much members forging as those who have found at least one block in the last blocks in the current window, minus the very last one.</p> -<h5 id="current-window">4.4.1.2. Current window</h5> -<p>We use the concept of <strong>current window</strong>. The current window is the number of blocks we look back at to determine how many members are forging. Let’s see how it works:</p> -<ul> -<li><p><code>issuersFrame</code> is the size of the current window in blocks.</p></li> -<li><p><code>issuersCount</code> the number of members who have calculated at least one block during the current window.</p></li> -</ul> -<p>Both <code>issuersFrame</code> and <code>issuersCount</code> are block fields. When first starting a blockchain, the very first block has an <code>issuersFrame=1</code> and an <code>issuersCount=0</code>. The genesis block is excluded as there are no members in the current window!</p> -<p>From the second block onwards (block #1) we track the variation of <code>issuersCount</code>. The member having mined block #0 enters the current window and in block #1 we will therefore mention <code>issuersCount=1</code>.</p> -<p><code>issuersFrame</code> then varies as follows:</p> -<ul> -<li>if <code>issuersCount</code> increases by N (with a maximum step of N = 1), then <code>issuersFrame</code> will increase by one unit over a period of 5N blocks.</li> -<li>Conversely, if <code>issuersCount</code> decreases by Y (with a maximum step of Y = 2 = current window inching forward + loss of one calculating member), then <code>issuersFrame</code> will decrease by one unit during 5Y blocks.</li> -<li>When such events overlap, <code>issuersFrame</code> evolves as so :</li> -</ul> -<table> -<thead> -<tr class="header"> -<th>bloc</th> -<th>event</th> -<th>issuersFrame</th> -</tr> -</thead> -<tbody> -<tr class="odd"> -<td>T</td> -<td>Babar writes a block and enters issuersCount</td> -<td>160</td> -</tr> -<tr class="even"> -<td>T+1</td> -<td>Celeste leaves issuersCount</td> -<td>160 +1 = 161</td> -</tr> -<tr class="odd"> -<td>T+2</td> -<td>N/a</td> -<td>161 +1 -1 = 161</td> -</tr> -<tr class="even"> -<td>T+3/4/5</td> -<td>N/a</td> -<td>161 +1 -1 = 161</td> -</tr> -<tr class="odd"> -<td>T+6</td> -<td>N/a</td> -<td>161 -1 = 160</td> -</tr> -</tbody> -</table> -<p>The calculation can be found under rules <a href="https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g05-headissuersframe">BR_G05</a> and <a href="https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g06-headissuersframevar">BR_G06</a> of the DUP protocol.</p> -<h5 id="exfact-and-the-personalised-difficulty">4.4.1.3. exFact and the personalised difficulty</h5> -<p>We explained that <code>exFact</code> spikes immediately after the member has found a block. It decreases then rapidly to <code>1</code> after a number of blocks equal to <code>1/3 * issuersCount</code>. Let’s see precisely how we calculate <code>exFact</code>:</p> -<ul> -<li><p><code>nbPreviousIssuers</code> is the value of issuersCount at the last block <code>N</code> found by the member.</p></li> -<li><p><code>nbBlocksSince</code> is the number of blocks found by the rest of the network since block <code>N</code>.</p></li> -<li><p><code>percentRot</code> is the number of <em>not excluded</em> peers we want. It is a monetary parameter, its value is 0.67 for Ğ1 currency.</p></li> -</ul> -<pre><code>a = FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) -exFact = MAX [ 1 ; a ]</code></pre> -<p>The FLOOR is a simple truncate function. For <code>exFact</code> to exclude the member, we need :</p> -<pre><code>(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2</code></pre> -<p>We can see that the member is not excluded if <code>nbBlocksSince</code> is greater than 1/3 of the calculating members. Take as an example <code>nbPreviousIssuers = 6</code> and <code>nbBlocksSince = 3</code>:</p> -<pre><code>(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1</code></pre> -<p>However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded:</p> -<pre><code>(0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2</code></pre> -<p>Moreover if the last block was authored by the said member, then:</p> -<pre><code>nbBlocksSince=0 and -exFact = 0.67 * nbPreviousIssuers</code></pre> -<p>ExFact value increases according to the number of members calculating. Thus, if there is enough members calculating, even mining farms would be excluded. We have therefore succeeded in our intent to deter attempts to seize the blockchain and its currency.</p> -<p>However, at any time <code>t</code>, the two-thirds of calculating members all have an exclusion factor of <code>1</code>, even though they might not all have the same computational power at hand. If the personalised difficulty only took into account the exclusion factor, then only the members with the highest computational power from the remaining third would be able to author new blocks and the other 2/3s would almost always be excluded. Lesser machines wouldn’t stand a chance…</p> -<h4 id="the-handicap">4.4.2. The handicap</h4> -<p>The handicap is the second parameter of the personalised difficulty. Its main role is to improve the rotation of forging peers. A higher handicap is assigned to members with higher calculating power, so lesser machines can also compute blocks. As a consequence, there is no incentive on forging with powerful computers. Security can be achieved with less computing power than with pure PoW.</p> -<p>The aim is to handicap the half that has authored most blocks (the most powerful half) to favour the other one. So, the handicap formula will use the median number of blocks authored by peers within the current window.</p> -<ul> -<li><p><code>nbPersonalBlocksInFrame</code> is the number of blocks authored by a single member within the current window.</p></li> -<li><p><code>medianOfBlocksInFrame</code> is the median number of blocks written by the calculating members during the same timeframe.</p></li> -</ul> -<pre><code>a = (nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame -handicap = FLOOR(LN(MAX( 1 ; a )) / LN(1.189))</code></pre> -<p>Let’s unwrap the formula:</p> -<pre><code>(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame)</code></pre> -<p>is simply the ratio between the number of blocks authored by the peer and the median number of blocks. For example, if a peer has authored <code>9</code> blocks in the current window and the median is <code>5</code>, then the ratio will be <code>(9+1)/5 = 2</code>. The MAX function allows us to ensure that the handicap has a value at least equal to <code>1</code>.</p> -<p>The Napierian Logarithm of this ratio prevents the handicap from becoming excluding. We want the handicap to level the calculating field so that all peers stand a chance, not to exclude peers.</p> -<p>If we wanted the handicap to be applied as soon as the median is reached, we would divide it by <code>LN(1)</code>. The problem is that we have already set a minimum value of <code>1</code> with the MAX function. If we were to divide the ratio by <code>LN(1)</code> all calculating peers would have a handicap <code>\>= 1</code>. In addition, is it really fair to handicap a member who is right on the median?</p> -<p>That’s why we went for <code>1.189</code> rather than <code>1</code>. A member has to be at least <code>18.9%</code> above the median to be assigned a handicap. 18.9% is actually 16^(1/16), the difficulty factor between two levels of the proof work (hexadecimal hash).</p> -<p>To conclude, you have to remember that :</p> -<ul> -<li>The handicap is indexed on the logarithm of the ratio to the median,</li> -<li>Handicap is only applied on members whose ratio to the median is greater than the ratio between two levels of the proof-of-work’s difficulty.</li> -</ul> -<h2 id="conclusion">Conclusion</h2> -<!-- source : https://duniter.org/en/theoretical/ --> -<p>Duniter’s Blockchain can be compared to Bitcoin’s : a common document retracing the history of the currency. However, Duniter registers not only trades, but also the history of relationships in the community as a mean to identify a human to a digital account. This way, Duniter has information about the fondamental reference of RTM : living humans. A libre Currency can be issued thanks to the Universal Dividend.</p> -<p>More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers, maintaining a good security and helping decentralization of calculation.</p> -<p>The ultimate goal of Duniter project is to allow people to participate in a libre economy, thanks to a libre currency. What is a libre economy ? The Relative Theory of Money defines it through four economic liberties :</p> -<ul> -<li>The freedom to choose your currency system: because money should not be imposed.</li> -<li>The freedom to access resources: because we all should have access to economic & monetary resources.</li> -<li>The freedom to estimate and produce value: because value is a purely relative to each individual.</li> -<li>The freedom to trade with the money: because we should not be limited by the avaible money supply.</li> -</ul> -<p>Those 4 economic freedoms should be understood together, not exclusively. Plus, “freedom” has to be understood as “non-nuisance”. So here, freedom does not mean the right to take all of a resource (like water source in a desert) so no more is available to the others. Now you get it, this is the goal: free economy through free currency.</p> -<h2 id="sources">Sources :</h2> -<ul> -<li>Relative Theory of Money, S.Laborde, 2010: <a href="http://en.trm.creationmonetaire.info/">en.trm.creationmonetaire.info/</a></li> -<li>Bitcoin Whitepaper, S.Nakamoto, 2008: <a href="https://bitcoin.org/bitcoin.pdf">bitcoin.org/bitcoin.pdf</a></li> -<li>The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : <a href="http://lightning.network/lightning-network-paper.pdf">lightning.network/lightning-network-paper.pdf</a></li> -<li>The GNU Privacy Handbook, M.Ashley, 1999 : <a href="https://www.gnupg.org/gph/en/manual.html#AEN335">www.gnupg.org/gph/en/manual.html#AEN335</a></li> -<li>High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. <a href="https://cr.yp.to/papers.html#ed25519">cr.yp.to/papers.html#ed25519</a>.</li> -<li>PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : <a href="https://archive.org/details/PPCoinPaper">archive.org/details/PPCoinPaper</a></li> -<li>Duniter Blockchain Protocol, v13, draft by Elois : <a href="https://git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md">git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md</a></li> -<li>The Sibyl Attack, J.R.Douceur: <a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf">www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</a></li> -<li>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992</li> -</ul> -<section class="footnotes"> -<hr /> -<ol> -<li id="fn1"><p>Bitcoin Whitepaper, S.Nakamoto, 2008: <a href="https://bitcoin.org/bitcoin.pdf">bitcoin.org/bitcoin.pdf</a><a href="#fnref1" class="footnote-back">↩</a></p></li> -<li id="fn2"><p>Relative Theory of Money, S.Laborde, 2010: <a href="http://en.trm.creationmonetaire.info/">en.trm.creationmonetaire.info/</a><a href="#fnref2" class="footnote-back">↩</a></p></li> -<li id="fn3"><p>OpenPGP protocol defines standard formats for encrypted messages, signatures, private keys, and certificates for exchanging public keys. The GNU Privacy Handbook, M.Ashley, 1999 : <a href="https://www.gnupg.org/gph/en/manual.html#AEN335">www.gnupg.org/gph/en/manual.html#AEN335</a><a href="#fnref3" class="footnote-back">↩</a></p></li> -<li id="fn4"><p>High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. <a href="https://cr.yp.to/papers.html#ed25519">cr.yp.to/papers.html#ed25519</a>.<a href="#fnref4" class="footnote-back">↩</a></p></li> -<li id="fn5"><p>PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : <a href="https://archive.org/details/PPCoinPaper">archive.org/details/PPCoinPaper</a><a href="#fnref5" class="footnote-back">↩</a></p></li> -<li id="fn6"><p>The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : <a href="http://lightning.network/lightning-network-paper.pdf">lightning.network/lightning-network-paper.pdf</a><a href="#fnref6" class="footnote-back">↩</a></p></li> -<li id="fn7"><p>Surfing a Web of Trust, Reputation and Reciprocity on CouchSurfing.com, D.Lauterbach, H.Truong, T.Shah, L.Adamic: <a href="http://snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf">snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf</a><a href="#fnref7" class="footnote-back">↩</a></p></li> -<li id="fn8"><p>Public key validation on GnuPG manual, M.Ashley, 1999 : <a href="https://www.gnupg.org/gph/en/manual.html#AEN335">www.gnupg.org/gph/en/manual.html#AEN335</a><a href="#fnref8" class="footnote-back">↩</a></p></li> -<li id="fn9"><p>The Sibyl Attack, J.R.Douceur: <a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf">www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf</a><a href="#fnref9" class="footnote-back">↩</a></p></li> -<li id="fn10"><p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992<a href="#fnref10" class="footnote-back">↩</a></p></li> -<li id="fn11"><p>Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992<a href="#fnref11" class="footnote-back">↩</a></p></li> -<li id="fn12"><p>Pareto principle : <a href="https://en.wikipedia.org/wiki/Pareto_principle">en.wikipedia.org/wiki/Pareto_principle</a><a href="#fnref12" class="footnote-back">↩</a></p></li> -</ol> -</section> diff --git a/whitepaper.md b/whitepaper.md deleted file mode 100644 index 4b01d36..0000000 --- a/whitepaper.md +++ /dev/null @@ -1,1178 +0,0 @@ -Duniter: A libre currency blockchain generator. -======================================= - -## Abstract {#abstract} - -Many currency principles involve non-equal rights to monetary creation between humans. -We propose a monetary creation based on the Relative Theory of Money, which guarantee equal monetary creation for each willing human. -This type of currency can be centralised, however, this could lead to censorship and arbitrary choices of the central institution. -Thus, strongly inspired by Bitcoin example, we want the currency to be as decentralised as possible, in the transaction network as in the human identification process. -We use a Web of Trust between living humans for identification. -This web of trust allows us to impose personalised difficulty for transaction validation, keeping the calculation accessible to low-end hardware and allowing all competent members to secure the currency. - - - -## Introduction {#introduction} - -Duniter is a software to create and manage "libre currencies". Libre currency is a concept defined by S.Laborde in the Relative Theory of Money (RTM) that was published in 2010. This theory demonstrates the possibility of an invariant monetary unit : the Universal Dividend. Doing so, the RTM answers the question : - -> How should a currency be created to match the principle of equality between all humans, now and between generations ? - -The results of this demonstration implies a monetary creation : - -* on a regular basis -* for each human being -* which amount has to be reassessed on fixed intervals according to a fixed formula. - -Thus, Duniter project will associate a human to a digital identity. It will use a Web of Trust with specific rules. As the number of members may evolve, the Universal Dividend has to be created according to the formula : - -``` -UD(t+1) = UD(t) + c² * ( M(t) / N(t) ) -``` -Duniter is based on a decentralized Blockchain. This technical choice allows irreversibility of transaction and uncensorability of trades and identities. While inspired by Bitcoin, Duniter uses a Web of Trust and the Proof of Work to secure the computation network, thus making obsolete the power race model used in Bitcoin. - -The first currency created through Duniter is Ğ1, pronounced "June". It was created on the 8th. March 2017. This whitepaper uses Ğ1 parameters as examples ; however, one can create another libre currency with custom parameters while still using Duniter software. - - -## 1. State of the art : Bitcoin case {#state-of-the-art-bitcoin-case} - -<!-- source : https://duniter.org/en/theoretical/ --> - -Duniter uses the crypto-currency concept introduced by Bitcoin[^BTC_whitepaper], which is -to use cryptographic tools such as signatures to create trustless digital -currencies. Duniter fits this definition, but it has two completely -different principles than Bitcoin : the Web of Trust and the Universal -Dividend . These differences are on both monetary and technical aspects. - -[^BTC_whitepaper]: Bitcoin Whitepaper, S.Nakamoto, 2008: [bitcoin.org/bitcoin.pdf](https://bitcoin.org/bitcoin.pdf) - -### 1.1. Monetary creation of Bitcoin : a space-time asymmetry {#monetary-creation-a-space-time-asymmetry} - -Space-time asymmetry refers to the relative access of individuals to -newly created money[^RTM]. Concretely, most existing currencies (c. 2020) are -both spatially and temporally asymmetrical for their users. Let\'s take -Bitcoin as an example to understand why. - -[^RTM]: Relative Theory of Money, S.Laborde, 2010: [en.trm.creationmonetaire.info/](http://en.trm.creationmonetaire.info/) - -#### 1.1.1. Spatial asymmetry {#spatial-asymmetry} - -When new Bitcoins are created, only some Bitcoin users (the miners) -are given new Bitcoins, while everyone else get nothing. We believe -this is the first injustice. However, some might say: - -> \"Miners used their electricity and time to get it!\" - -\... we would answer that this work should not have been rewarded by -newly created Bitcoins. New units should be distributed to the whole -community. Miners should be rewared another way, but not by -money issuance. Of course, Bitcoin cannot create money through Basic -Income since Bitcoin users are not strongly identified, and one might -benefit from money creation multiple times if they owned several wallets. -Duniter gets rid of this problem by identifying its users and -creating the same amount of Basic Income to everyone. - -#### 1.1.2. Temporal-asymmetry {#temporal-asymmetry} - -Bitcoin has an absolute limit of 21 million BTC (its unit of currency), -which means ever fewer bitcoins will be created over time until no new BTC are -being generated. So, once the first adopters have mined every bitcoin, -how will future joiners get Bitcoins? Just like most of us do for Euros or -Dollars: to get money, they will have to work for the ones who already own it. - -We believe this is the second injustice. Every member of a -monetary community should be equal concerning monetary creation, and get -the same relative amount of money over time, even if they are a late -adopter. Duniter aims to fix this by making the Universal Dividend -(a.k.a. UD) grow by the time according to precise rules, thus making -members equal toward money issuance on a half-lifespan. - -Most currencies present one of these two asymmetries, including metal currencies -and mutual credit, as exposed in the RTM. - -#### 1.1.3. A solution {#a-solution} - -Bitcoin has taught us that it is possible to create a currency system -allowing one to both create digital money and to exchange it without a -central authority. What we need to change is the way money is issued -so we finally have a symmetrical system. We need **Bitcoin + Universal -Dividend**. But Universal Dividend implies that the community consists -of only identified people. This is where the Web of Trust (WoT) comes -into place. - -This concept, introduced by cryptography with the OpenPGP format[^OpenPGP], -allows us to identify people in a decentralized manner. It works as -follows: each person creates a personal identity that is linked to its -cyptographic certificate. The identity must be confirmed by others -members who use their own cryptographic key. It is that simple: people -choose who is part of the community and who is not, not a central -authority. - -[^OpenPGP]: OpenPGP protocol defines standard formats for encrypted messages, signatures, private keys, and certificates for exchanging public keys. The GNU Privacy Handbook, M.Ashley, 1999 : [www.gnupg.org/gph/en/manual.html#AEN335](https://www.gnupg.org/gph/en/manual.html#AEN335) - -However, Duniter will not use OpenPGP for its cryptographic features: -Elliptic Curves[^Elliptic] will be used instead for the conciseness of its -generated keys and its pratical advantages. Duniter has its own Web -of Trust principles, that will be exposed later. - -[^Elliptic]: High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. [cr.yp.to/papers.html#ed25519](https://cr.yp.to/papers.html#ed25519). - -### 1.2. Proof-of-Work mining : a power race {#proof-of-work-mining-a-power-race} - -In Bitcoin Model, the calculation and incentive principles cause a power race : -new Bitcoins are created for the owners of the most numerous, powerful (and energy-consuming) computers. -This leads to a power race an places the control over the currency in the hands of the richest hardware owners. -We want to make Duniter blockchain validation much less energy and hardware consuming while -keeping a strong level of security. This will be further explained later. A consequence of -this choice is the participation of low-end hardware in the Duniter network, -leading to a better decentralization of blockchain validation. - -#### 1.2.1 What about Proof of Stake ? {#what-about-proof-of-stake} - -Proof of stake consensus algorythm was first introduced in 2012[^PPCoin]. The basic principle is to allow the richest wallets to issue blocks, putting their coin balance as a "stake" they would lose in case of cheat. - -[^PPCoin]: PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : [archive.org/details/PPCoinPaper](https://archive.org/details/PPCoinPaper) - -At the time of conceiving Duniter, the PoS algorythms had not been tested enough to be used as a fundamental base. We did not chose this consensus principle. -Moreover, the principle of allowing owners of large amounts of money to validate transaction can only lead -to placing power over the currency in the richests hands : this is contrary to the symmetical principles of a libre currency. - -## 2. Duniters Blockchain {#duniters-blockchain} - -<!-- source : https://duniter.org/en/theoretical/ --> - - -Duniters Blockchain follows the basic principles of Bitcoins. -This is essential for synchronization between peers, as to prevent double-spend attacks. -However, Duniters Blockchain will store different informations than Bitcoins. - -The basic use of Blockchain will be registering transactions. For this part, we use the same principles as Bitcoin : transactions have inputs (spending accounts) and outputs (receiving accounts). But contrary to Bitcoin, no generation transaction exists : monetary creation happens only through UD. So, in Duniters Blockchain, Inputs can be either: - -* a former transaction (as in Bitcoin) -* a Universal Dividend (specific to Duniter). - -Duniters Web of Trust is also written in the Blockchain. The identity of each -member gets registered much like transactions are, with a strong link to the -time reference. Thus, the Blockchain is a representation of a space-time frame -of reference, where "space" are members of the WoT and "time" the basic blockchain -units : the blocks. On each point of time, one can determine which account is -legitimate to create the UD, only with a blockchain analysis. - - -### 2.1. Spam countermeasures {#spam-countermeasures} - - -An issue of most cryptocurrency projects is to prevent the common ledger from -growing too much. This would require nodes to have a lot of storage and computing -power to be usable. In particular, we don't want an attacker to be able to make the -Blockchain grow too fast. Most projects implement transaction fees as a way to prevent -this, making the attacker lose money. We don't want to introduce this mean since a -currency with automatic fees on transactions is no more neutral. Several -countermeasuers against such spam attacks are implemented. - -<!-- see : https://forum.duniter.org/t/sans-frais-de-transaction-comment-resister-aux-attaques/3846/25 (implemented ?)--> - -#### 2.1.1. Minimum output amount {#minimum-output-amount} - -<!-- This has to be implemented in DUBPv13. --> - -Fixing a minimal output amount reduces the power of an attack. Duniter deals with cents of Ğ1 or 1/1000 of the first UD. An attacker could create thousand accounts with only 1 UD. To prevent this, a valid transaction must have output amounts of minimum 1Ğ1. This reduces the power an attack by 100. - -#### 2.1.2. Limited block size and chainability {#limited-block-size-and-chainability} - -The block size is always limited. While the protocol allows this limit to evolve to address scaling issues, an attacker cannot register as many transaction as they wish. - -With the same goal to prevent too many transactions to get registered, while transactions can be "chained" (refer to another transaction in the same block), the chainability of transactions is limited to 5. - - -### 2.2. Scaling {#scaling} - -Most of the time, the scaling issue rises for distributed systems that should work on a very large scale. This is not the case of Duniter, for multiple reasons : - -* Ğ1 is the first libre currency, and is still experimental on the monetary creation principle. We don't want it to reach the whole world, we only want it to work, to validate or invalidate the RTM. Moreover, the rules chosen for the Ğ1 WoT should limit its size to around 16 million members. -* Duniter's aim is to be used to create multiple libre currencies, that would fit local or regional economies. As a consequence, it would deal with less transactions than if it was a world-scale system. The RTM proposes a formula to calculate the exchange rate between two currencies, that could be used to create automatic exchanges for a member travelling away from their community. - -However, Duniter has assets that will help if the number of users and transactions grow. - -#### 2.2.1 Dynamic block size {#dynamic-block-size} - -While Bitcoin has a fixed block size, Duniters blocks size can evolve. -On low use of the blockchain, the maximal block size is 500 bytes. -On high use of the blockchain, the maximal block size would be 110% of the -average size of the current window blocks(see "personalised difficulty" part for more information). -This way, the blocks are bounded in size, but can slowly grow if a massive and legitimate use of the blockchain needs it. The block size (in bytes) is limited as so : - -``` -block_size < max(500 ; CEIL(1.10 * (average block size)) -``` - -#### 2.2.2. Lightning Networks {#lightning-networks} - -The Lightning Networks[^Lightning] allow almost instant and off-chain transactions. -They were first implemented on Lightcoin, and are now on Bitcoin. -One of their benefits is to make the blockchain store a lot of transactions at once, thus reducing the groth of the blockchain. -The Duniter protocol allows XHX() and CSV() unlock conditions that are necessary to implement Lightning Networks. -While not available yet, this payment channel might get implemented when needed. - -[^Lightning]: The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : [lightning.network/lightning-network-paper.pdf](http://lightning.network/lightning-network-paper.pdf) - -#### 2.2.3. Unit base {#unit-base} - -As the Universal Dividend grows exponentially, with time Duniter nodes would have had to deal with always largest amounts, eventually reaching the BIGINT limit. To avoid this, the amounts are expressed with a unit base in base 10. We want the UD amount to always fit in 4 digits. To manage it, the `unitbase` is updated each time the UD value reaches 100.00 : it goes from `99.99*10^(unitbase)` to `10.00*10^(unitbase+1)`. All the unit amounts are thus divided by 10. While this might seem strange, this process has already hapened in state currencies. Moreover, the amounts expressed in UD will not change. - -With a monetary growth of 10% each year and a stable population, such a change of unit base would happen each 25 years. - -## 3. Duniter Web of Trust - - -### 3.1. Basic Principles {#duniter-wot-basic-principles} - -In order to identify "members" accounts - which create monetary units - -and other accounts, Duniter uses a Web of Trust. This can be summarized -into few principles: - -- Each account becomes a member if it received a minimal number of - certifications - 5 for Ğ1 currency. -- Only members accounts can send certifications. Certifications have a - limited lifespan. -- A certification indicates that the sender accepts the receiver as a - legitimate identity. - -The aim of the WoT is to identify a blockchain account to a living -human. According to Lauterbach et.al[^Couchsurf], the strengh of a relationship should be considered when building a vouch system. -For this reason, the Ğ1 Web of Trust rules are expressed in a licence stating what WoT certifications are. -A certification represents a strong human relationship : one may certify a close relative, not an acquaintance. -Each member has to accept this licence before being included in the WoT. -Thus, if a member is part of an attack on the currency, they can be found by mutual relatives. -Additional security rules occur to prevent cheat and attacks on a large scale. - -[^Couchsurf]: Surfing a Web of Trust, Reputation and Reciprocity on CouchSurfing.com, D.Lauterbach, H.Truong, T.Shah, L.Adamic: [snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf](http://snap.stanford.edu/class/cs224w-readings/lauterbach09trust.pdf) - -Note that non-members accounts can use the currency, but cannot create -money. Non-members accounts can be used by individuals as secondary wallets, or by -institutions. - -We were inspired by the OpenPGP Trust system[^OpenPGP_Trust]. However, the OpenPGP -trust principles aim at defining trust from a particular point of view while Duniter needs to -identify humans for the whole community. To achieve this goal, while OpenPGP allows each -user to tweak its trust parameters individually, Duniter sets rules in the "genesis" block for the whole community. - -[^OpenPGP_Trust]: Public key validation on GnuPG manual, M.Ashley, 1999 : [www.gnupg.org/gph/en/manual.html#AEN335](https://www.gnupg.org/gph/en/manual.html#AEN335) - -### 3.2. Why do we need a Web of Trust ? {#why-do-we-need-a-web-of-trust} - -There are two reasons we need it : - -1. To make sure that only one Universal Dividend is produced per member - at each specified creation interval. In the Ğ1's case this interval - is set as daily `86 400` seconds, it is the *monetary parameter* - known as `dt`. -2. To identify the nodes hashing the blocks and assign each a - personalised difficulty. This custom difficulty proof of work is - there to avoid the blockchain's validation mechanism becoming too - centralised as is the case with many \'non-libre' cryptocurrencies. - -> **Monetary parameter** : Each currency that use Duniter has its own blockchain whose behaviour is -> dictated by a set of 'parameters' defined in block zero - the so-called -> genesis block - that can be tweaked to achieve the desired results. At -> the time of writing the Whitepaper, the Duniter Blockchain Protocol -> (DUBP) has a total of 21 parameters of which 10 are for the WoT alone. -> We'll focus on these 10. -> -> Suffice to say that in the Ğ1's case, the DU is created every 24 hours - -> 86 400 seconds. This interval is set through the time derivative `dt` -> parameter and can have a different value in other implementations of the -> protocol. - -We want to make sure that each member can only have one account. As we -all know, achieving zero-risk isn't possible[^Sybil_Attack]. -Our goal is therefore not to create a WoT within which fraud -would be absolutely impossible, but instead to discourage it. Here is a -rewording of our goal in 4 smaller ones : - -1. Make the certification process lengthy enough that all members - exercise due diligence and are wary of risks. -2. Make fraudulent acts as hard as we can to the extent that they - become pointless. -3. Ensure that any Sybil attacks have a negligible impact on the - currency by ensuring that illegitimate double Universal Dividends - have no significant bearing on the legitimate monetary mass -4. Slow the growth of 'Sybil regions' to give enough time for the - community to react and isolate the threat. - -[^Sybil_Attack]: The Sibyl Attack, J.R.Douceur: [www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf](https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf) - -> **Sybil attack** : A Sybil attack is an attack perpetrated on a -> reputation system through the creation of fake identities. A Web of -> Trust is a specific instance of a Reputation System. - -There are plenty of Sybil attack scenarios we can think of and just as -many reasons why their perpetrators would want to carry them out. Our -objective is that the configuration of the WoT protects both users and -its IT backbone infrastructure against these attacks. - -This means that micro-attacks performed by small groups of individuals -looking for personal enrichment are of no interest to us. The web's role -isn't to deter these attacks, this being instead the role of the -community. Just like the town you live in is responsible for providing -your tap water and electricity but isn't responsible for any burglaries, -etc. Much in the same way, Duniter's WoT guarantees us all a functional -currency, but do not detect small fraud. - -### 3.3. The importance of having our own certification system {#own-certification-system} - -Centralized identification systems can achieve the goal we want. State -Identification is an example. However, this has many drawbacks : - -* The authority may have arbitrary criteria for identification, for example -preventing people without an official state-provided identity or -homeless people to be included in the WoT. -* Payment might be required -to get identified, thus making the monetary creation not "free". -* The authority is a point of failure for any attacker. - -It is of the utmost importance that we remain free from any state or -corporation. The WoT is an answer to this criterium. To this day we -depend only on the Internet and yet, were it to fail, there are already -alternatives being tested around the world for a decentralised communication network. - -### 3.4. A few foundational concepts on graph theory : a bit of vocabulary {#graph-theory-vocabulary} - -- **Graph**: set of points -called 'vertices'- joined by edges -called - paths/walks-. - -- **Simple graph**: a graph with no loops and with no multiple edges. - That is, each edge connects two distinct endpoints and no two edges - have the same endpoints. A simple edge is an edge that is not part - of a multiple adjacency -of edges-. In many cases, graphs are - assumed to be simple unless specified otherwise. - -- **Directed graph**: a graph in which the edges have a distinguished - direction, from one vertex to another. A directed edge can also be - called a path or walk. - Arrow A --\> B is therefore different from arrow B --\> A. - -- **Endpoints**: the edge with vertex A --\> B has A and B as - endpoints, respectively as start and end of the path/walk. - -- **Isolated vertex**: a vertex whose degree is zero, that is, a - vertex with no incident edges. - -- **Degree of a vertex**: number of its incident edges -in and out-. - -- **Out-degree of vertex A**: number of outbound edges / tail ends - from A. - -- **In-degree of vertex A**: number of incoming edges / head ends - to A. - - - -- **Path**: -aka "walk"- path to follow to get from vertex A to - vertex B. - -### 3.5. Definition of the Duniter Web of Trust {#definition-of-the-duniter-web-of-trust} - -The Duniter WoTs -one per currency- are simple directed graphs without -isolated vertices. The vertices are the members and the edges are the -certifications given and received. - -*Directed* means that the responsibility of issuing a certification is -unique and personal to the certifier. The trust they place in the -receiver cannot be imposed in the other direction although in most -circumstances both parties equally trust each other. - -In addition, all vertices are either currently active members or -past-members. Past-member vertices are in a specific 'deactivated state' -and can no longer issue or receive certifications although the ones -already issued or received to/from other members are still considered -'pending' to avoid a collapse of the WoT. If these old members don't -come back into the WoT, their pending certifications will eventually -expire and they will switch from 'deactivated' to 'isolated' vertices. - -To wrap up with old members, after a certain period of time - set in the -currency's parameters - their deactivated vertex is removed from the web -and the associated identity is 'revoked'. The person who owned the -account can no longer use this identity but is free to join the web with -another one. - -> **Identity** : An identity is a set of three pieces of information: a public key, a -> name and a blockstamp. A blockstamp points to a specific block in the -> chain. Its main use is to freeze the point in time at which an identity -> was created and to link this identity to a specific chain and a currency -> - each currency having its own blockchain. -> -> An identity can be in any one of 5 different status: pending, member, -> old member, revoked or excluded. - -Let's take a simple example: - -``` - A -> B -> C - | - \--> D -``` - -If, for whatever reason, A were to lose its member status, the web would -crumble and all other members would be excluded as a consequence. To -avoid this, the certification from A --\> B will remain valid until its -expiry date, leaving enough time for B to receive certifications from C -or D. - -Because our WoT doesn't have any isolated vertices, each new identity -created needs to be pulled into the web with all of the certifications -it has received, all in the same block. This calls for a temporary -'buffer' storage space for **pending** identities and the certifications -they have received. This storage space is called 'the pool' of Duniter -nodes, which we could also have called the 'sandbox' as that's the name -used in Duniter's code. Duniter nodes inclued other 'pools' for other -documents and metadata not mentioned here. - -### 3.6. Exploring the rules behind a Duniter Web of Trust {#exploring-the-rules-behind-duniter-wot} - -The Duniter WoTs - one per currency - works with a set of eight -fundamental rules enforced through eleven different parameters. Ten of -these parameters are set within the genesis block, the eleventh one - -`msPeriod`- having being hard-coded in the Ğ1's code subsequently. - -#### 3.6.1. Distance rule and referent members (`stepMax` and `xPercent`) {#distance-rule-and-referent-members-stepmax-and-xpercent} - -These two parameters are closely linked and together define the -'distance rule'. The 'distance rule' can only be described after -defining what a 'referent member' is: - -> **Referent member**: member A is said to be 'referent' if and only if -> the total of their degrees are greater than or equal to -> `CEIL-N^-1/stepMax` where N is the total number of members. As the -> size of the web will grow this number will grow too, meaning it will -> take more certification issuances to become a referent member. The -> number of certifications needed to become a member shouldn't change. - -Let's now define the distance rule: - -> **Distance rule**: member A is said to observe this rule if and only -> if for a subset xPercent % of referent members R there exists a path -> of length less than or equal to `stepMax` between R and A. - -Referent members only exist so that the distance rule can take effect, -they have no special privileges over non-referent members. In a perfect -web, that is one in which each member has certified all members they -legitimately can, all members would be referent members. However, -because the web progressively grows in size and because members die and -are replaced by new ones, there are always members at any given time `t` -who haven't yet certified all members they legitimately could. These -members would hinder the evolution of the web if they were taken into -account in the calculation of the distance rule and the web would -effectively stop growing. - -Because verifying the application of the distance rule is -calculation-greedy, it is only performed when a new identity gets -confirmed into the web or an existing member gets renewed. There is an -exception to this rule: the distance rule is not observed in the genesis -block -when the web is first implemented. - -#### 3.6.2. Rule of the minimum number of certifications needed (`sigQty`) {#rule-of-the-minimum-number-of-certifications-needed-sigqty} - -This is the simplest rule, it essentially says that each member must at -any given time -meaning in any single block- have received at least -`sigQty` active certifications. If, for whatever reason, member A were -to have less than `sigQty` active certifications in a given block, they -would cease to be a member and be required to publish a request for -identity renewal. - -#### 3.6.3. The membership renewal rule (`msValidity`, `msPeriod` and `msWindow`) {#the-membership-renewal-rule-msvalidity-msperiod-and-mswindow} - -Bear in mind that a membership doesn't last a lifetime but instead has a -lifespan set to `msValidity` seconds. - -Every single member -or old member who hasn't revoked his identity or -been excluded- can request a membership renewal so long as the last -request was made more than `msPeriod` seconds ago. If a member has never -requested a renewal, the date of last renewal is equal to the timestamp -at which his membership was first created. A new request will be stored -in the 'pool' for a maximum of `msWindow` seconds before it's included -in the blockchain. Once again, this can only happen once/if the member -meets both the `siqQty` rule and the distance rule -if these criterion -are already matched it's just a case of waiting for a new block to be -mined-. - -If a member hasn't requested a renewal for longer than `msValidity` -seconds, they automatically cease to be a member. From this moment on, -the ex-member has another `msValidity` window to renew their membership. -When this period of `2 × msValidity` runs out, the membership will -expire and this identity will never be available for use again in the -web. If the person so desires, they will have to publish new identity -and membership documents and find enough certifiers, as any newcomer. - -#### 3.6.4. Rule of certification lifespan (`sigValidity`) {#rule-of-certification-lifespan-sigvalidity} - -All certifications included in the blockchain expire **sigValidity** -seconds after they were **issued**. - -> /!\\ The issuance and the inclusion of a certification in the -> blockchain occur at different times. When member A issues a -> certification at time t1, it gets stored in the pool starting at t1 -> and only finds its way into the blockchain at t2 when all of the web's -> rules are observed. Several weeks can thus go by between t1 and t2!!! - -#### 3.6.5. Rule of limited supply of active certifications (`sigStock`) {#rule-of-limited-supply-of-active-certifications-sigstock} - -By 'active certifications' we refer to certifications included in the -blockchain and that haven't yet expired. - -The total of active certifications issued by any member at any single -time must be less than or equal to `sigStock`. When this threshold is -reached the member will have to wait for one of his active -certifications to expire before he/she can issue a new one. - -#### 3.6.6. Rule of the time period between two certification issuances. (`sigPeriod`) {#rule-of-the-time-period-between-two-certification-issuances-sigperiod} - -As soon as a certification issued by member A gets included in the -blockchain, they will be unable to issue a new one before another -`sigPeriod` seconds. - -#### 3.6.7. Expiry of a certification issuance (`sigWindow`) {#expiry-of-a-certification-issuance-sigwindow} - -When a certification is issued by member A, it will be stored in the -'pool' for a maximum of `sigWindow` seconds. If the certification hasn't -been included in the blockchain by then, it will be cancelled and the -member's `sigStock` will be repleted by one. - -#### 3.6.8. Lifespan of a 'pending' identity (`idtyWindow`) {#lifespan-of-a-pending-identity-idtywindow} - -When a new identity is created, it is stored in the 'pool' for a maximum -of `idtyWindow` seconds. If the person hasn't achieved member status by -then, the certification will simply be cancelled. - -### 3.7. Details on some of the WoT's peculiarities at the genesis block {#details-on-some-of-the-wots-peculiarities-at-the-genesis-block} - -The aforementioned rules can only be enforced with an existing web. They -cannot be observed when first creating the web, that is when defining -the genesis block. - -Only rules 2 and 5 can be observed at the genesis block. - -The genesis block has to be manually created by the founding members. In -practice this means that there must be a choice on which identities to -include on the premise that all of them observe rules 2 and 5. In -addition, the genesis block must be signed with the private key of one -of these identities. - -As soon as the genesis block has been created, the other identities can -start mining the blockchain and the member who created block \#0 -effectively looses the decision power he had at creation. - -### 3.8. Why these rules and application cases in the Ğ1 {#why-these-rules-and-application-cases-in-the-g1} - -#### 3.8.1. Distance and maximum size {#distance-and-maximum-size} - -The distance rule is there to curb the maximum size of a Sybil region as -well as that of the monetary community as a whole. The `xpercent` -parameter prevents the creation of a 'faction' that could take hold of -the blockchain. - - - -The Sybil regions are isolated from the rest of the graph in the sense -that they can only receive certifications from other ill-intentioned -Sybil members. As a consequence, the shortest edge/path between a -legitimate member and a Sybil one has to have the attack's author as an -endpoint. The maximum depth the Sybil region can attain is therefore -contingent on the distance between the attacking edge-s- and the -xpercent% closest referent members, this distance is known as -`stepAttackers`. The maximum size of a Sybil region created by `sigQty` -members depends on the L parameter, defined as `L = sigQty/sigStock`: - -``` -MaxSybilSize= (sigStock-sigQty)*(1-L^(stepMax-stepAttackers))/(1-L) -``` - -The maximum size of the Web of Trust is given by the following formula: - -``` -WoTmax = (sigStock)*L^(stepMax-1) -``` - -However we know for a fact that members will never use all of their -available certifications. -According to Dunbar[^Dunbar], on average, one is able to maintain relationships to around 150 people. -Being conservative, we will consider that on average, each person will certify 50 accounts. -We can calculate the size of the average web of trust `WoTavg` : - -``` -WoTavg= (50)*(sigQty/50)^(stepMax-1) -``` - -[^Dunbar]: Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992 - - -Our goal with the Ğ1 is to create a community of about one million -members to test the consequences of a libre monetary system. Let's see -how we can tweak the pair of sigQty and stepMax- to reach this size: - - - -The maximum size of a Sybil region grows linearly with `sigQty` but -exponentially with `stepMax`. Logic has it that we need to keep -`stepMax` as low as possible to ensure sufficient strength to the web. -The above graph shows that the lowest value of `stepMax` for a web of a -million members is of 5. This is an order of magnitude and is likely to -be much higher in reality, we cannot measure it for sure. - -For `sigQty` we can choose a value of **4** for a web of **1.5 million -members** or **5** for **half a million members**. Bear in mind these -are gross figures and could be significantly higher, we are talking -anywhere between 1 and 10 million in reality. Calculating WOTavg gives -us a pretty good idea of how the web would scale bearing in mind that it -considers all members are referent members too -which isn't the case as -explained previously-. Hence the maximum size of the web is likely -larger, a ballpark figure of half a million is enough for now especially -knowing that the smaller `sigQty` is, the easier it is to launch a Sybil -attack -it's easier to find four accomplices than five-. For security -reasons we have settled on five: - -``` -stepMax = 5 -sigQty = 5 -sigStock \>= 50 -``` - -The maximum size of a Sybil region therefore is: - -``` -(sigStock-sigQty)*(1-(sigStock/5)^(5-stepAttackers))/(1-(sigStock/5)) -``` - -with sigStock = 50 we have a Sybil region of: - -``` -45*(1-10^(5-stepAttackers))/(-9) -``` - -A good practice for protecting the web is to maximise `stepAttackers`. -That's why we decided that referent members in the genesis block had to -be at least four steps away from each other. - -Another way to keep a Sybil attack at bay, were it slow enough for -members to notice it, would be for referent members to 'stretch' the web -intentionally to limit the growth of the region by ensuring that the -attackers' legitimate certifications received in the first place aren't -renewed. But what if bot accounts were created and certified each other -super fast and following all rules, how would we counter that? By -introducing a minimum length of time between two certifications! - -#### 3.8.2. Time is our friend {#time-is-our-friend} - -To help us deter a Sybil attack, we've decided to impose a minimum -period of time between any two certifications issued from a single -account. This parameter called `sigPeriod` affords us a greater chance -to detect the formation of a 'hostile' faction. - -Here is a graph showing the evolution of a Sybil region with the -variation of `sigPeriod`. The simulation considers that honest members -and attackers both issue a certification each `sigPeriod` interval, in days: - - - -As we see, there is a strong link between the -growth speed of the region and `sigPeriod`. As evidenced here, we need a -`sigPeriod` high enough in order to ensure that the legitimate web can -grow at least as fast as a Sybil region. In addition, the higher -`sigPeriod` is, the more members will exercise their certification power -gingerly, the action coming at a higher 'cost'. - -There are numerous advantages to giving `sigPeriod` a high value and no -technical barriers to it, hence our choice of five days. - -We could have also gone for one week for the sake of simplicity. However -there is an underlying idea behind our choice which was quite simply the -pace of today's life. Certifying someone can be a lengthy process as one -needs to make sure they are correctly applying the Ğ1 licence and people -nowadays wait for the weekend to enjoy a bit of free-time. Thus the idea -to allow one to certify at the end of every working week -five days- -instead of a whole calendar one. - -#### 3.8.3. Trust me now, trust me forever ? (`sigValidity`, `msValidity`) {#trust-me-now-trust-me-forever-sigvalidity-msvalidity} - -There would be two main drawbacks to a lifetime membership in the Ğ1's -Web of Trust: - -- First of all, some members will pass and those accounts should no - longer produce the Universal Dividend. -- Secondly it is of the utmost importance that 'rogue' accounts can be - excluded from the web at some point. - -To achieve this, certifications have a limited lifespan. Members need to -seek renewal from their peers after `sigValidity` time. On the other -hand, this time can't be too short that members would spend more time -seeking renewal than they would exchanging in the currency. Furthermore, -a certification with too short a lifespan would foster careless -certifying behaviours. The act of certifying must have a high-enough -'perceived' cost to make it feel like an important act. Lastly, we also -wanted this lifespan to be easy to remember. Historically speaking, we -first settled on the values of `sigPeriod` and `sigStock`, meant one -could issue all of their certifications in 495 days, one year was -therefore not long enough. We deemed three years to be too much and -that's how we agreed on two years in the end. - -Thinking that a deceased member could continue producing the UD for two -long years without anyone benefitting from it was also something we -needed to address. We chose a value of one year for **msValidity**. The -act of renewing every year is done through one of the clients -interacting with the blockchain, through a simple click on a button. -This parameter is less important than others and is mostly there to -'prune' the web of past or inactive members who don't renew their -membership. - -#### 3.8.4. Keeping the pools free of information glut (`idtyWindow`, `sigWindow`, `msWindow`) {#keeping-the-pools-free-of-information-glut-idtywindow-sigwindow-mswindow} - -The pools need to be cleaned up on a regular basis to avoid them -clogging up with information and to ensure that machines with less -calculating power can still run a Duniter node. - -To achieve this, identities with pending membership approval and the -corresponding certifications have to remain the shortest time possible -in the pool while still having a chance of making it into the -blockchain. - -For the Ğ1, our opinion was that two months would be enough for all -potential certifiers to agree on a specific identity to certify. We also -wanted a time period that would be easy enough to remember by all. We -settled on two months, and gave this value to all three parameters -`idtyWindow`, `sigWindow` and `msWindow`. - -#### 3.8.5. Avoiding single members from 'knowing too many people' (`sigStock`) {#avoiding-single-members-from-knowing-too-many-people-sigstock} - -We considered that on average, each person will certify 50 people. -However, we know for a fact that some members will use more than 50 certifications. -The maximum social network of one individual is around 150 people[^Dunbar]. -Being conservative, we settled on a maximum certification number `sigstock` of 100. -Since `sigStock`'s impact on the size of a Sybil region is fairly limited, we did not investigate further this parameter. - -#### 3.8.6. Avoiding locking minorities (`xpercent`) {#avoiding-locking-minorities-xpercent} - -It's easy enough to become a referent member, one of the Sybil -strategies could therefore be to create a region of referent members. -Such a region would grow slower than otherwise but could confer a -locking power to its members by using the distance rule. That's why the -distance rule cannot be calculated on 100% of the referent members. -Hence the introduction of the `xpercent` parameter which defines the -percentage of referent members needing to be less than five edges --steps- from each other. - -This percentage needs to be low enough to prevent the formation of a -locking minority -referent Sybil members being too far from legitimate -referent members-. On the other hand, it needs to be high enough so as -to restrict the maximum size of the Sybil region through the distance -rule. The `xpercent` parameter was one of the hardest to define, -therefore we might decide to change its value during the Ğ1 experiment. - -We were inspired by the Pareto -principle[^Pareto]: if at least -20% of members give good density to the web, 80% of the referent members -will be five or less steps from any other member -referent or not-. The -maximum value for `xpercent` is therefore 80%, anything above that and -the distance rule could be too restrictive for legitimate use cases. -With security our top concern, we chose the maximum value of 80%. - -[^Pareto]: Pareto principle : [en.wikipedia.org/wiki/Pareto_principle](https://en.wikipedia.org/wiki/Pareto_principle) - -#### 3.8.7. Spam protection with (`msPeriod`) {#spam-protection-with-msperiod} - -This parameter stands out a bit on its own, as it was added after the -genesis block. It is there to protect the Duniter P2P infrastructure -against 'spam' attacks. We had to think of a strategy against attacks -such as high-frequency membership renewal requests -i.e: in every block, -every five minutes- or worse still, hundreds of these requests per -minute to flood the Duniter nodes. Without such limits, nodes are -supposed to address all renewal requests, even in cases where they were -last published five minutes ago! The `msPeriod` parameter was given the -same value as `idtyWindow`, `sigWindow` and `msWindow`, i.e. two months. - - -## 4. Proof of Work with personal difficulty {#proof-of-work-with-personalized-difficulty} - -As each P2P cryptocurrency, Duniter has a way to synchronize its peers. It uses a proof of Work (PoW) to write the Blockchain on a regular basis, much like BitCoin. However, Duniter has a unique asset : the WoT, where each member represents a unique living human. - -This difference might seem minimal, but it has an enormous consequence : while Bitcoin uses a race based on computing power only, Duniter creates a validation frame that is no race. It is more like a lottery where each "winning" member is excluded for a certain amount of time. Moreover, those who have more computing power get a handicap, as a way to let other peers win. All this is possible through the WoT, that allows personalised difficulty while PoW is used for synchronization. All the rules of this PoW/WoT mechanism can be verified by reading the blockchain. As a consequence, a peer only needs to have an up-to-date copy of the blockchain to apply the rules. A view of the whole network is not needed. - -Another strong difference is that forging peers are not rewarded by the protocol. There is no economical incentive on forging lots of blocs, neither on having a lot of computing power. - -One could say that Duniter uses a PoW that needs very low energy consumption compared to BitCoin : an "ecological" PoW ? - - - -<!-- source : https://duniter.org/en/wiki/duniter/2018-11-27-duniter-proof-of-work/ --> - -### 4.1. Why do we need Proof of Work ? {#why-proof-of-work} - -Duniter nodes share a database as part of a p2p environment. The proof of -work (PoW) allows machines to synchronize with each other. In Duniter's case, the blockchain is -our database, and acts as a ledger keeping -a trace of all transactions, status of the WoT and more. -How can we let several machines add data (ie: a transaction) at -the same time? In addition, how do we settle on how much time has gone -by since the blockchain was last updated? Agreement on time is of the utmost importance -as we want to create Universal Dividends on a regular basis, and keep track -of membership status, both in human time. - - -Proof-of-work provides a clever solution to both problems: - -1. Any machine can write into the blockchain (create a new block) but is only -authorised to do so if it has previously solved a mathematical equation -that require a certain amount of work. The challenge has to -be hard enough to prevent two machines to solve it at the same time, -ensuring the unicity of a block's creator. - -2. Solving this challenge -takes a certain amount of time, which depends on the calculating power -of the whole network. This provides a common ground for defining -the needed time reference. A block time is set (ie: 1 block = 5 min) and -Duniter adapts the challenge difficulty to get an average duration -corresponding to this block time. - -### 4.2. Only members can "mine" {#only-members-can-mine} - -One of Duniter's major differences with other PoW-based cryptocurrencies -is that only members are allowed to author blocks. Each block is signed -with the member's private key, allowing the algorithm to determine a -personalised difficulty. - -This personalised difficulty eliminates the rat-race for the most -sophisticated and powerful mining equipment. Another benefit is the fact -that no "supercomputer" can take control of the blockchain. Lastly, Duniter -implements a rotation in forging members thanks to this personalized difficulty. - -This lightweight PoW is much less energy-consuming than other PoW cryptocurrencies. -Members can mine with anything from a raspberry pi to a privacy-first -internet cube. - -### 4.3. How does it work ? {#how-does-duniter-pow-work} - -#### 4.3.1. The hash (aka digest) {#the-hash} - -Example of a valid hash: - -``` -00000276902793AA44601A9D43099E7B63DBF9EBB55BCCFD6AE20C729B54C653 -``` - -As you can see this hash starts with five zeros which was very hard to -achieve and took a lot of work for someone's computer. Hence the term -"proof of work". - -#### 4.3.2. The common difficulty {#common-difficulty} - -A common difficulty is needed to settle on a yardstick for our time reference. -Its role is to make sure the blockchain moves forward -at a steady pace - one block every `avgGenTime` seconds, `avgGenTime` -being one of the 20 parameters behind the Duniter protocol-. - -This difficulty's initial value can be set to any arbitrary value (`70` in -Duniter `v1.5.x`) and then acts as a spring, regulating blocktime -creation by increasing itself if the creation interval drops under -`avgGenTime` and vice-versa. - -##### 4.3.2.1. How is difficulty applied ? {#how-is-difficulty-applied} - -The numeric value of difficulty is taken from an array of possible -hashes out of all possible hashes. In DUBPv13 the hash -of a block is its sha256 hexadecimal hash. - -To understand the difficulty, we make a euclidiean division of the -difficulty by 16. - -Here's an example with a difficulty value of 70 : - -``` -70 // 16 = 4 with a remainder of 6. -``` - -The valid hashes are the ones starting with four -zeros and with the fifth character less than or equal to 9 (6 in hexadecimal notation). -The valid hashes are then written as starting with : `0000[0-9]`. -This is a bit different from Bitcoin, -where the difficulty is only ruled by the number of zeroes. - -##### 4.3.2.2. The Nonce {#the-nonce} - -When a member is forging a new -block, his computer freezes the block's content and changes the Nonce -until the hash reaches the required number of zeroes. - -The nonce allows us to mine a new block by finding a hash. The -hash value allows us to determine the difficulty level of the -proof-of-work performed. Examples of possible Nonce values: - -- 10100000112275 -- 10300000288743 -- 10400000008538 -- 10700000079653 -- 10300000070919 - -In reality the `Nonce` value follows a pre-determined format akin to -`XYY00000000000`. The Nonce's value isn't the number of attempts but -rather a value within a set of possible ones. This is how the Nonce is -built: - -- X is a number assigned to a specific peer. Let's assume that someone - has several nodes each with the same private key, this would lead to - possible collisions if this person were to mine the same block with - different nodes. Each ~~block~~ **node ?** will therefore have its own unique X to - prevent this from happening. - -- Y is the number of cores of the processor. The Nonce starting with - `107[…]` belongs to a seven cores processor, while `199[...]` could - be the proof generated by a 99 cores processor. - -The rest of the Nonce, the part that follows after the XYY, is the -numerical space for this individual node and is unique to each of the -CPU's core. This space is comprised of eleven digits (`00000000000`). -For the sake of accuracy, we use the term CPU in the wider sense, it can -be understood as a bi-CPU for example. We take into consideration the -number of cores for the resulting PoW. - -### 4.4. Personalised difficulty {#personalised-difficulty} - -Earlier in this article, we explained that the personalised difficulty -is the new and key concept that sets Duniter apart from other -PoW-based cryptocurrencies. - -Here is how this personalised difficulty is calculated and assigned: - -It is determined by a combination of two different constraints with -complimentary roles: the **exclusion factor** and the **handicap**. - -Let `powMin` be the common difficulty, `exFact` a member's exclusion -factor and `handicap` their handicap. This member's personalised -difficulty `diff` is: - -``` -diff = powMin*exFact + handicap -``` - -#### 4.4.1. Understanding `exFact`, the exclusion factor {#the-exclusion-factor} - -Members who have never produced blocks or haven't for quite some time -are assigned an exclusion factor of `1`. Their personalised difficulty -is therefore simply the sum of `powMin + handicap`. - -Before reading on, let's precise the role of this exclusion factor. -When a member adds a block to the chain, his `exFact` jumps up from one to -a very high value, to prevent them from forging other blocks -immediately after and taking control of the blockchain. - -The exclusion factor will then rapidly return to one. -This delay is expressed as a number of blocks. It is calculated as a -proportion of the number of members forging. In the Ğ1's case, this -proportion is 1/3, meaning that if there are fifteen members currently -forging, the member's exclusion factor will drop down to one after five -blocks. - -##### 4.4.1.1. What is intended by "the number of members forging" ? - -We mean the number of members trying to create the next block. -In reality, there is no way to precisely know how -many members are calculating at any given time, because it is impossible -to view the entire network. But we need this information, whithout which -assigning a personalised difficulty is impossible. -To achieve this, Duniter looks back at the blockchain and assumes that there is as much -members forging as those who have found at least one block -in the last blocks in the current window, minus the very last one. - -##### 4.4.1.2. Current window - -We use the concept of **current window**. The current window is the number of blocks we look back at to determine how many members are forging. -Let's see how it works: - -* `issuersFrame` is the size of the -current window in blocks. - -* `issuersCount` the number of members who -have calculated at least one block during the current window. - -Both `issuersFrame` and `issuersCount` are block fields. When first -starting a blockchain, the very first block has an `issuersFrame=1` and -an `issuersCount=0`. The genesis block is excluded as there are no members in the current -window! - -From the second block onwards (block \#1) we track the variation of -`issuersCount`. The member having mined block \#0 enters the current -window and in block \#1 we will therefore mention `issuersCount=1`. - - -`issuersFrame` then varies as follows: - -* if `issuersCount` increases by N (with a maximum step of N = 1), then `issuersFrame` will increase by one unit over a period of 5N blocks. -* Conversely, if `issuersCount` decreases by Y (with a maximum step of Y = 2 = current window inching forward + loss of one calculating member), then `issuersFrame` will decrease by one unit during 5Y blocks. -* When such events overlap, `issuersFrame` evolves as so : - -| bloc | event | issuersFrame| -|---|---|---| -| T | Babar writes a block and enters issuersCount | 160 | -| T+1 | Celeste leaves issuersCount | 160 +1 = 161 | -| T+2 | N/a | 161 +1 -1 = 161 | -| T+3/4/5 | N/a | 161 +1 -1 = 161 | -| T+6 | N/a | 161 -1 = 160 | - - -The calculation can be found under rules -[BR\_G05](https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g05-headissuersframe) -and -[BR\_G06](https://git.duniter.org/nodes/common/doc/blob/master/rfc/0009_Duniter_Blockchain_Protocol_V11.md#br_g06-headissuersframevar) -of the DUP protocol. - -##### 4.4.1.3. exFact and the personalised difficulty {#exfact-and-the-personalised-difficulty} - -We explained that `exFact` spikes immediately after the member has -found a block. It decreases then rapidly to `1` after a number of -blocks equal to `1/3 * issuersCount`. Let's see precisely -how we calculate `exFact`: - -* `nbPreviousIssuers` is the value of issuersCount at the -last block `N` found by the member. - -* `nbBlocksSince` is the number of blocks -found by the rest of the network since block `N`. - -* `percentRot` is the number of *not excluded* peers we want. It is a monetary parameter, its value is 0.67 for Ğ1 currency. - -``` -a = FLOOR (percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) -exFact = MAX [ 1 ; a ] -``` - -The FLOOR is a simple truncate function. For `exFact` to exclude the -member, we need : - -``` -(percentRot * nbPreviousIssuers / (1 + nbBlocksSince)) >= 2 -``` - -We can see that the member is not excluded if `nbBlocksSince` is greater than 1/3 of -the calculating members. Take as an example `nbPreviousIssuers = 6` and `nbBlocksSince = 3`: - -``` -(0.67* 6 / )1 + 3)) = 1.005 -> exFact = 1 -``` - -However, if the member computed a block one block ago (nbBlocksSince = 1), exFact = 2 and the forging peer is excluded: - -``` -(0.67 * 6 / (1 + 1)) = 2.01 -> exFact = 2 -``` - -Moreover if the last block was authored by the said member, then: -``` -nbBlocksSince=0 and -exFact = 0.67 * nbPreviousIssuers -``` - -ExFact value increases according to the number of -members calculating. Thus, if there is enough members calculating, even -mining farms would be excluded. We have therefore -succeeded in our intent to deter attempts to seize the blockchain and -its currency. - - -However, at any time `t`, the two-thirds of -calculating members all have an exclusion factor of `1`, even though -they might not all have the same computational power at hand. If the -personalised difficulty only took into account the exclusion factor, then -only the members with the highest computational power from the remaining -third would be able to author new blocks and the other 2/3s would almost -always be excluded. Lesser machines wouldn't stand a -chance... - -#### 4.4.2. The handicap {#the-handicap} - -The handicap is the second parameter of the personalised difficulty. Its -main role is to improve the rotation of forging peers. -A higher handicap is assigned to members with higher calculating -power, so lesser machines can also compute blocks. As a consequence, -there is no incentive on forging with powerful computers. -Security can be achieved with less computing power than with pure PoW. - -The aim is to handicap the half that has -authored most blocks (the most powerful half) to favour the other one. -So, the handicap formula will use the median number of blocks authored by peers within the current window. - -* `nbPersonalBlocksInFrame` is the number of blocks authored by a -single member within the current window. - -* `medianOfBlocksInFrame` is the -median number of blocks written by the calculating members during the -same timeframe. - -``` -a = (nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame -handicap = FLOOR(LN(MAX( 1 ; a )) / LN(1.189)) -``` - -Let's unwrap the formula: - -``` -(nbPersonalBlocksInFrame + 1) / medianOfBlocksInFrame) -``` - -is simply the -ratio between the number of blocks authored by the peer and the median -number of blocks. For example, if a peer has authored `9` -blocks in the current window and the median is `5`, then the ratio -will be `(9+1)/5 = 2`. The MAX function allows us to ensure that -the handicap has a value at least equal to `1`. - -The Napierian Logarithm of this ratio prevents the handicap from becoming excluding. -We want the handicap to level the calculating field so that all peers stand a chance, not to exclude peers. - -If we wanted the handicap to be applied as soon as the median is reached, -we would divide it by `LN(1)`. The problem is that we have already set -a minimum value of `1` with the MAX function. If we were to divide -the ratio by `LN(1)` all calculating peers would have a handicap `\>= -1`. In addition, is it really fair to handicap a member who is right on -the median? - -That's why we went for `1.189` rather than `1`. A member has to -be at least `18.9%` above the median to be assigned a handicap. -18.9% is actually 16\^(1/16), the difficulty -factor between two levels of the proof work (hexadecimal hash). - -To conclude, you have to remember that : - -* The handicap is indexed on the logarithm of the ratio to the median, -* Handicap is only applied on members whose ratio to the median is greater than the ratio between two -levels of the proof-of-work's difficulty. - - - -## Conclusion {#conclusion} - -<!-- source : https://duniter.org/en/theoretical/ --> - -Duniter's Blockchain can be compared to Bitcoin's : a common document retracing the history of the currency. However, Duniter registers not only trades, but also the history of relationships in the community as a mean to identify a human to a digital account. This way, Duniter has information about the fondamental reference of RTM : living humans. A libre Currency can be issued thanks to the Universal Dividend. - -More than that, Duniter proposes a new model for securing a Blockchain in an efficient and decentralized way. Basing the security on a Web of Trust with an individualised security makes the calculation rules more fair. A side-effect of this choice is a network consisting mostly of low-end computers, maintaining a good security and helping decentralization of calculation. - -The ultimate goal of Duniter project is to allow people to participate in a libre economy, thanks to a libre currency. What is a libre economy ? The Relative Theory of Money defines it through four economic liberties : - - -* The freedom to choose your currency system: because money should not be imposed. -* The freedom to access resources: because we all should have access to economic & monetary resources. -* The freedom to estimate and produce value: because value is a purely relative to each individual. -* The freedom to trade with the money: because we should not be limited by the avaible money supply. - - -Those 4 economic freedoms should be understood together, not exclusively. Plus, "freedom" has to be understood as "non-nuisance". So here, freedom does not mean the right to take all of a resource (like water source in a desert) so no more is available to the others. Now you get it, this is the goal: free economy through free currency. - -## Sources : {#sources} - -* Relative Theory of Money, S.Laborde, 2010: [en.trm.creationmonetaire.info/](http://en.trm.creationmonetaire.info/) -* Bitcoin Whitepaper, S.Nakamoto, 2008: [bitcoin.org/bitcoin.pdf](https://bitcoin.org/bitcoin.pdf) -* The Bitcoin Lightning Network, J.Poon & T.Dryja, 2016 : [lightning.network/lightning-network-paper.pdf](http://lightning.network/lightning-network-paper.pdf) -* The GNU Privacy Handbook, M.Ashley, 1999 : [www.gnupg.org/gph/en/manual.html#AEN335](https://www.gnupg.org/gph/en/manual.html#AEN335) -* High-speed high-security signatures, D.J.Bernstein, N.Duif, T.Lange, P.Schwabe, B-Y.Yang. Journal of Cryptographic Engineering 2 (2012), 77–89. [cr.yp.to/papers.html#ed25519](https://cr.yp.to/papers.html#ed25519). -* PPCoin: Peer-to-Peer Crypto-Currency with Proof-of-Stake, S.King & S.Nadal, 2012 : [archive.org/details/PPCoinPaper](https://archive.org/details/PPCoinPaper) -* Duniter Blockchain Protocol, v13, draft by Elois : [git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md](https://git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md) -* The Sibyl Attack, J.R.Douceur: [www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf](https://www.microsoft.com/en-us/research/wp-content/uploads/2002/01/IPTPS2002.pdf) -* Neocortex size as a constraint on group size in primates, R.I.M.Dunbar, Journal of Human Evolution, 1992 -- GitLab