github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/docs/source/architecture/poet.rst (about) 1 ********************** 2 PoET 1.0 Specification 3 ********************** 4 5 Introduction 6 ============ 7 8 The Proof of Elapsed Time (PoET) Consensus method offers a solution to the 9 Byzantine Generals Problem that utilizes a “trusted execution environment” to 10 improve on the efficiency of present solutions such as Proof-of-Work. The 11 initial reference implementation of PoET released to Hyperledger was written for 12 an abstract TEE to keep it flexible to any TEE implementation. This 13 specification defines a concrete implementation for SGX. The following 14 presentation assumes the use of Intel SGX as the trusted execution environment. 15 16 At a high-level, PoET stochastically elects individual peers to execute requests 17 at a given target rate. Individual peers sample an exponentially distributed 18 random variable and wait for an amount of time dictated by the sample. The peer 19 with the smallest sample wins the election. Cheating is prevented through the 20 use of a trusted execution environment, identity verification and blacklisting 21 based on asymmetric key cryptography, and an additional set of election 22 policies. 23 24 For the purpose of achieving distributed consensus efficiently, 25 a good lottery function has several characteristics: 26 27 * Fairness: The function should distribute leader election 28 across the broadest possible population of participants. 29 30 * Investment: The cost of controlling the leader election 31 process should be proportional to the value gained from it. 32 33 * Verification: It should be relatively simple for all participants 34 to verify that the leader was legitimately selected. 35 36 PoET is designed to achieve these goals using new secure CPU instructions 37 which are becoming widely available in consumer and enterprise processors. 38 PoET uses these features to ensure the safety and randomness of the leader 39 election process without requiring the costly investment of power and specialized 40 hardware inherent in most “proof” algorithms. 41 42 Sawtooth includes an implementation which simulates the secure instructions. 43 This should make it easier for the community to work with the software but 44 also forgoes Byzantine fault tolerance. 45 46 PoET essentially works as follows: 47 48 #. Every validator requests a wait time from an enclave (a trusted function). 49 50 #. The validator with the shortest wait time for a particular transaction 51 block is elected the leader. 52 53 #. One function, such as “CreateTimer”, creates a timer for a transaction 54 block that is guaranteed to have been created by the enclave. 55 56 #. Another function, such as “CheckTimer”, verifies that the timer 57 was created by the enclave. If the timer has expired, this function 58 creates an attestation that can be used to verify that validator did 59 wait the allotted time before claiming the leadership role. 60 61 The PoET leader election algorithm meets the criteria for a good lottery 62 algorithm. It randomly distributes leadership election across the entire 63 population of validators with distribution that is similar to what is 64 provided by other lottery algorithms. The probability of election 65 is proportional to the resources contributed (in this case, resources 66 are general purpose processors with a trusted execution environment). 67 An attestation of execution provides information for verifying that the 68 certificate was created within the enclave (and that the validator waited 69 the allotted time). Further, the low cost of participation increases the 70 likelihood that the population of validators will be large, increasing 71 the robustness of the consensus algorithm. 72 73 Definitions 74 =========== 75 76 The following terms are used throughout the PoET spec and are defined here for 77 reference. 78 79 Enclave 80 A protected area in an application’s address space which provides 81 confidentiality and integrity even in the presence of privileged malware. 82 83 The term can also be used to refer to a specific enclave that has been 84 initialized with a specific code and data. 85 86 Basename 87 A service provider base name. In our context the service provider 88 entity is the distributed ledger network. Each distinct network should have 89 its own Basename and Service Provider ID (see EPID and IAS specifications). 90 91 EPID 92 An anonymous credential system. See E. Brickell and Jiangtao Li: “Enhanced 93 Privacy ID from Bilinear Pairing for Hardware Authentication and Attestation”. 94 IEEE International Conference on Social Computing / IEEE International 95 Conference on Privacy, Security, Risk and Trust. 2010. 96 97 EPID Pseudonym 98 Pseudonym of an SGX platform used in linkable quotes. It is 99 part of the IAS attestation response according to IAS API specifications. It 100 is computed as a function of the service Basename (validator network in our 101 case) and the device's EPID private key. 102 103 PPK, PSK 104 PoET ECC public and private key created by the PoET enclave. 105 106 IAS Report Key 107 IAS public key used to sign attestation reports as specified 108 in the current IAS API Guide. 109 110 PSEmanifest 111 Platform Services Enclave manifest. It is part of an SGX quote 112 for enclaves using Platform Services like Trusted Time and Monotonic 113 Counters. 114 115 AEP 116 Attestation evidence payload sent to IAS (see IAS API specifications). 117 Contains JSON encodings of the quote, an optional PSEmanifest, and an optional 118 nonce. 119 120 AVR 121 Attestation verification report, the response to a quote attestation 122 request from the IAS. It is verified with the IAS Report Key. It contains 123 a copy of the input AEP. 124 125 :math:`WaitCertId_{n}` 126 The :math:`n`-th or most recent WaitCertificate digest. We 127 assume :math:`n >= 0` represents the current number of blocks in the ledger. 128 WaitCertId is a function of the contents of the Wait Certificate. For 129 instance the SHA256 digest of the WaitCertificate ECDSA signature. 130 131 OPK, OSK 132 Originator ECDSA public and private key. These are the higher level 133 ECDSA keys a validator uses to sign messages. 134 135 OPKhash 136 SHA256 digest of OPK 137 138 blockDigest 139 ECDSA signature with OSK of SHA256 digest of transaction block 140 that the validator wants to commit. 141 142 localMean 143 Estimated wait time local mean. 144 145 MCID 146 SGX Monotonic Counter identifier. 147 148 SealKey 149 The SGX enclave Seal Key. It is used by the SGX ``sgx_seal_data()`` 150 and ``sgx_unseal_data()`` functions. 151 152 PoetSealKey 153 The Poet SGX enclave Seal Key. It must be obtained through the 154 SGX SDK ```sgx_get_key()`` function passing a fixed 32 byte constant as 155 ``key_id`` argument. 156 157 PoET\_MRENCLAVE 158 Public MRENCLAVE (see SGX SDK documentation) value of valid 159 PoET SGX enclave. 160 161 :math:`T_{WT}` 162 WaitTimer timeout in seconds. A validator has at most :math:`T_{WT}` 163 seconds to consume a WaitTimer, namely obtain a WaitCertificate on it after 164 the WaitTimer itself has expired. 165 166 :math:`K` 167 Number of blocks a validator can commit before having to sign-up with 168 a fresh PPK. 169 170 :math:`c` 171 The "sign-up delay", i.e., number of blocks a validator has to wait after 172 sign-up before starting to participate in elections. 173 174 minDuration 175 Minimum duration for a WaitTimer. 176 177 P2P PoET SGX Enclave Specifications 178 =================================== 179 The P2P PoET SGX enclave uses the following data structures:: 180 181 WaitTimer { 182 double requestTime 183 double duration 184 byte[32] WaitCertId:sub:`n` 185 double localMean 186 } 187 188 WaitCertificate { 189 WaitTimer waitTimer 190 byte[32] nonce 191 byte[] blockDigest 192 } 193 194 It uses the following global variables:: 195 196 WaitTimer activeWT # The unique active WaitTimer object 197 byte[64] PPK 198 byte[64] PSK 199 MCID # SGX Monotonic Counter Identifier 200 201 It exports the following functions: 202 203 ``generateSignUpData(OPKhash)`` 204 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 205 206 **Returns** 207 208 .. code:: console 209 210 byte[64] PPK 211 byte[432] report # SGX Report Data Structure 212 byte[256] PSEmanifest 213 byte[672] sealedSignUpData # (PPK, PSK, MCID) tuple encrypted with SealKey 214 215 ****Parameters**** 216 217 .. code:: console 218 219 byte[32] OPKhash # SHA256 digest of OPK 220 221 **Description** 222 223 1. Generate fresh ECC key pair (PPK, PSK) 224 #. Create monotonic counter and save its identifier as MCID. 225 #. Use the SGX ``sgx_seal_data()`` function to encrypt (PPK, PSK, MCID) with 226 SealKey (using MRENCLAVE policy) 227 :math:`sealedSignupData = \textnormal{AES-GCM}_{SealKey} (PPK | PSK | MCID)` 228 #. Create SGX enclave report, store ``SHA256(OPKhash|PPK)`` in ``report_data`` 229 field. 230 #. Get SGX PSE manifest: PSEManifest. 231 #. Save (PPK, PSK, MCID) as global variables within the enclave. 232 #. Set active WaitTimer instance activeWT to NULL. 233 #. Return (PPK, report, PSEmanifest, sealedSignUpData). 234 235 .. note:: 236 **Implementation Note:** Normally, there is a maximum number of monotonic 237 counters that can be created. One way to deal with this limitation is to 238 destroy a previously created monotonic counter if this is not the first time 239 the generateSignupData function was called. 240 241 ``unsealSignUpData(sealedSignUpData)`` 242 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 243 244 **Returns** 245 246 .. code:: console 247 248 byte[64] PPK 249 250 **Parameters** 251 252 .. code:: console 253 254 byte[672] sealedSignUpData # (PPK, PSK, MCID) tuple encrypted with SealKey 255 256 **Description** 257 258 1. Use the ``sgx_unseal_data()`` function to decrypt sealedSignUpData into (PPK, 259 PSK, MCID) with SealKey (using MRENCLAVE policy). 260 #. Save (PPK, PSK, MCID) as global variables within the enclave. 261 #. Set global active WaitTimer instance activeWT to NULL. 262 #. Return PPK 263 264 ``createWaitTimer(localMean, WaitCertId_n)`` 265 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 266 267 **Returns** 268 269 .. code:: console 270 271 WaitTimer waitTimer 272 byte[64] signature # ECDSA PSK signature of waitTimer 273 274 **Parameters** 275 276 .. code:: console 277 278 double localMean # Estimated wait time local mean 279 byte[32] WaitCertId_n # SHA256 digest of WaitCertificate owner's ECDSA 280 # signature 281 282 **Description** 283 284 1. Increment monotonic counter MCID and store value in global variable 285 counterValue. 286 #. Compute :math:`tag = \textnormal{AES-CMAC}_{PoetSealKey} (WaitCertId_{n})`. 287 #. Convert lowest 64-bits of tag into double precision number in :math:`[0, 1]`: 288 tagd. 289 #. Compute :math:`duration = minimumDuration - localMean * log(tagd)`. 290 #. Set requestTime equal to SGX Trusted Time value. 291 #. Create WaitTimer object :math:`waitTimer = WaitTimer(requestTime, duration, 292 WaitCertId_{n}, localMean)`. 293 #. Compute ECDSA signature of waitTimer using PSK: :math:`signature = 294 ECDSA_{PSK} (waitTimer)`. 295 #. Set global active WaitTimer instance activeWT equal to waitTimer. 296 #. Return (waitTimer, signature). 297 298 ``createWaitCertificate(blockDigest)`` 299 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 300 301 **Returns** 302 303 .. code:: console 304 305 WaitCertificate waitCertificate 306 byte[64] signature # ECDSA PSK signature of waitCertificate 307 308 **Parameters** 309 310 .. code:: console 311 312 byte[] blockDigest # ECDSA signature with originator private key of SHA256 313 # digest of transaction block that the validator wants 314 # to commit 315 316 **Description** 317 318 1. If activeWT is equal to NULL, exit. 319 #. Read monotonic counter MCID and compare its value to global variable 320 counterValue. If values do not match, exit. 321 #. Read SGX Trusted time into variable currentTime. If currentTime is smaller 322 than :math:`waitTimer.requestTime + waitTimer.duration`, exit (the duration 323 has not elapsed yet). 324 #. If currentTime is larger than :math:`waitTimer.requestTime + 325 waitTimer.duration+T_{WT}`, exit. 326 #. Generate random nonce. 327 #. Create WaitCertificate object :math:`waitCertificate = 328 WaitCertificate(waitTimer, nonce, blockDigest)`. 329 #. Compute ECDSA signature of waitCertificate using PSK: :math:`signature = 330 ECDSA_{PSK} (waitCertificate)`. 331 #. Set activeWT to NULL. 332 #. Return (waitCertificate, signature). 333 334 Sign-up Phase 335 ------------- 336 337 A participant joins as a validator by downloading the PoET SGX enclave and a 338 SPID certificate for the blockchain. The client side of the validator runs the 339 following sign-up procedure: 340 341 1. Start PoET SGX enclave: ENC. 342 #. Generate sign-up data: :math:`(PPK, report, PSEmanifest, sealedSignUpData) = 343 \textnormal{ENC.generateSignUpData(OPKhash)}` The ``report_data`` (512 bits) 344 field in the report body includes the SHA256 digest of (OPKhash | PPK). 345 #. Ask SGX Quoting Enclave (QE) for linkable quote on the report (using the 346 validator network's Basename). 347 #. If Self Attestation is enabled in IAS API: request attestation of linkable 348 quote and PSE manifest to IAS. The AEP sent to IAS must contain: 349 350 * isvEnclaveQuote: base64 encoded quote 351 * pseManifest: base64 encoded PSEmanifest 352 * nonce: :math:`WaitCertId_{n}` 353 354 The IAS sends back a signed AVR containing a copy of the input AEP and the 355 EPID Pseudonym. 356 357 #. If Self Attestation is enabled in IAS API: broadcast self-attested join 358 request, (OPK, PPK, AEP, AVR) to known participants. 359 360 #. If Self Attestation is NOT enabled in IAS API: broadcast join request, (OPK, 361 PPK, quote, PSEmanifest) to known participants. 362 363 A validator has to wait for :math:`c` block to be published on the distributed 364 ledger before participating in an election. 365 366 The server side of the validator runs the following sign-up procedure: 367 368 1. Wait for a join request. 369 #. Upon arrival of a join request do the verification: 370 371 If the join request is self attested (Self Attestation is enabled in IAS 372 API): (OPK, PPK, AEP, AVR) 373 374 a. Verify AVR legitimacy using IAS Report Key and therefore quote legitimacy. 375 #. Verify the ``report_data`` field within the quote contains the SHA256 376 digest of (OPKhash | PPK). 377 #. Verify the nonce in the AVR is equal to :math:`WaitCertId_{n}`, namely the 378 digest of the most recently committed block. It may be that the sender has 379 not seen :math:`WaitCertId_{n}` yet and could be sending 380 :math:`WaitCertId_{n'}` where :math:`n'<n`. In this case the sender should 381 be urged to updated his/her view of the ledger by appending the new blocks 382 and retry. It could also happen that the receiving validator has not seen 383 :math:`WaitCertId_{n}` in which case he/she should try to update his/her 384 view of the ledger and verify again. 385 #. Verify MRENCLAVE value within quote is equal to PoET\_MRENCLAVE (there 386 could be more than one allowed value). 387 #. Verify PSE Manifest SHA256 digest in AVR is equal to SHA256 digest of 388 PSEmanifest in AEP. 389 #. Verify basename in the quote is equal to distributed ledger Basename. 390 #. Verify attributes field in the quote has the allowed value (normally the 391 enclave must be in initialized state and not be a debug enclave). 392 393 If the join request is not self attested (Self Attestation is NOT enabled in 394 IAS API): (OPK, PPK, quote, PSEmanifest) 395 396 a. Create AEP with quote and PSEmanifest : 397 398 * isvEnclaveQuote: base64 encoded quote 399 * pseManifest: base64 encoded PSEmanifest 400 401 #. Send AEP to IAS. The IAS sends back a signed AVR. 402 #. Verify received AVR attests to validity of both quote and PSEmanifest and 403 save EPID Pseudonym. 404 #. Verify ``report_data`` field within the quote contains the SHA256 digest 405 of (OPKhash | PPK). 406 #. Verify MRENCLAVE value within quote is equal to PoET\_MRENCLAVE (there 407 could be more than one allowed value). 408 #. Verify basename in the quote is equal to distributed ledger Basename. 409 #. Verify attributes field in the quote has the allowed value (normally the 410 enclave must be in initialized state and not be a debug enclave). 411 412 If the verification fails, exit. 413 414 If the verification succeeds but the SGX platform identified by the EPID 415 Pseudonym in the quote has already signed up, ignore the join request, exit. 416 417 If the verification succeeds: 418 419 a. Pass sign-up certificate of new participant (OPK, EPID Pseudonym, PPK, 420 current :math:`WaitCertId_{n}` to upper layers for registration in EndPoint 421 registry. 422 #. Goto 1. 423 424 Election Phase 425 -------------- 426 427 Assume the identifier of the most recent valid block is :math:`WaitCertId_{n}`. 428 Broadcast messages are signed by a validator with his/her PPK. To participate in 429 the election phase a validator runs the following procedure on the client side: 430 431 1. Start the PoET SGX enclave: ENC. 432 #. Read the sealedSignUpData from disk and load it into enclave: 433 :math:`ENC.\textnormal{unsealSignUpData}(sealedSignUpData)` 434 #. Call :math:`(waitTimer, signature) = ENC.createWaitTimer(localMean, 435 WaitCertId_{n})`. 436 #. Wait waitTimer.duration seconds. 437 #. Call :math:`(waitCertificate, signature) = 438 ENC.createWaitCertificate(blockDigest)`. 439 #. If the ``createWaitCertificate()`` call is successful, broadcast 440 (waitCertificate, signature, block, OPK, PPK) where block is the transaction 441 block identified by blockDigest. 442 443 On the server side a validator waits for incoming (waitCertificate, signature, 444 block, OPK, PPK) tuples. When one is received the following validity checks are 445 performed: 446 447 1. Verify the PPK and OPK belong to a registered validator by checking the EndPoint 448 registry. 449 450 #. Verify the signature is valid using sender's PPK. 451 452 #. Verify the PPK was used by sender to commit less than :math:`K` blocks by 453 checking EndPoint registry (otherwise sender needs to re-sign). 454 455 #. Verify the waitCertificate.waitTimer.localMean is correct by comparing against 456 localMean computed locally. 457 458 #. Verify the waitCertificate.blockDigest is a valid ECDSA signature of the SHA256 459 hash of block using OPK. 460 461 #. Verify the sender has been winning elections according to the expected 462 distribution (see z-test documentation). 463 464 #. Verify the sender signed up at least :math:`c` committed blocks ago, i.e., 465 respected the :math:`c` block start-up delay. 466 467 A valid waitCertificate is passed to the upper ledger layer and the 468 waitCertificate with the lowest value of waitCertificate.waitTimer.duration 469 determines the election winner. 470 471 Revocation 472 ---------- 473 474 Two mechanisms are put in place to blacklist validators whose EPID key has been 475 revoked by IAS. The first one affects each validator periodically, although 476 infrequently. The second one is an asynchronous revocation check that each 477 validator could perform on other validators' EPID keys at any time. 478 479 1. **Periodic regeneration of PPK** a validator whose EPID key has been revoked 480 by the IAS would not be able to obtain any valid AVR and therefore would be 481 prevented from signing-up. Forcing validators to periodically re-sign with a 482 fresh sign-up certificate leaves validators whose EPID keys have been revoked 483 out of the system. Validators have to re-sign after they commit :math:`K` 484 blocks and if they do not they are considered revoked. 485 486 #. **Asynchronous sign-up quote verification** A validator can (at any time) ask 487 IAS for attestation on a quote that another validator used to sign-up to 488 check if his/her EPID key has been revoked since. If so the returned AVR will 489 indicate that the key is revoked. A validator who obtains such an AVR from 490 IAS can broadcast it in a blacklisting transaction, so that all the 491 validators can check the veracity of the AVR and proceed with the 492 blacklisting. To limit the use of blacklisting transactions as a means to 493 thwart liveness for malicious validators one can control the rate at which 494 they can be committed in different ways: 495 496 * A certain number of participation tokens needs to be burned to commit a 497 blacklisting transaction. 498 499 * A validator can commit a blacklisting transaction only once he/she wins one 500 or more elections. 501 502 * A validator who commits a certain number of non-legit blacklisting 503 transactions is blacklisted. 504 505 Security Considerations 506 ----------------------- 507 508 1. :math:`T_{WT}` **motivation**: A validator has at most :math:`T_{WT}` seconds 509 to consume a WaitTimer, namely obtain a WaitCertificate on it after the 510 WaitTimer itself has expired. This constraint is enforced to avoid that in 511 case there are no transactions to build a block for some time several 512 validators might hold back after they waited the duration of their WaitTimers 513 and generate the WaitCertificate only once enough transactions are available. 514 At the point they will all send out their WaitCertificates generating a lot 515 of traffic and possibly inducing forks. The timeout mitigates this problem. 516 517 #. **Enclave compromise:** a compromised SGX platform that is able to 518 arbitrarily win elections cannot affect the correctness of the system, but 519 can hinder progress by publishing void transactions. This problem is 520 mitigated by limiting the frequency with which a validator (identified by 521 his/her PPK) can win elections in a given time frame (see z-test 522 documentation). 523 524 #. **WaitTimer duration manipulation:** 525 526 a. Imposing a :math:`c` block participation delay after sign-up prevents 527 validators from generating different pairs of OPK, PPK and pick the one that 528 would result in the lowest value of the next WaitTimer duration as follows: 529 530 i. Generate as many PPK,PSK pairs and therefore monotonic counters as 531 possible. 532 533 #. Do not sign up but use all the enclaves (each using a different PPK, 534 PSK and MCID) to create a WaitTimer every time a new block is committed 535 until a very low duration is obtained (good chance of winning the 536 election). Then collect all the different waitCertIds. 537 538 #. Ask each enclave to create the next waitTimer, whose duration depends 539 on each of the different winning waitCertIds. Choose the PPK of the 540 enclave giving me the lowest next duration and sign up with that. 541 542 #. As a result an attacker can win the first the election (with high 543 probability) and can chain the above 3 steps to get a good chance of 544 winning several elections in a row. 545 546 #. The nonce field in WaitCertificate is set to a random value so that a 547 validator does not have control over the resulting :math:`WaitCertId_{n}`. 548 A validator winning an election could otherwise try different blockDigest 549 input values to createWaitCertificate and broadcast the WaitCertificate 550 whose :math:`WaitCertId_{n}` results in the lowest duration of his/her 551 next WaitTimer. 552 553 #. The call ``createWaitTimer()`` in step 1 of the election phase (client 554 side) is bound to the subsequent call to ``createWaitCertificate()`` by 555 the internal state of the PoET enclave. More precisely only one call to 556 ``createWaitCertificate()`` is allowed after a call to 557 ``createWaitTimer()`` (and the duration has elapsed) as the value of the 558 global active WaitTimer object activeWT is set to null at the end of 559 ``createWaitCertificate()`` so that subsequent calls would fail. Therefore 560 only one transaction block (identified by the input parameter blockDigest) 561 can be attached to a WaitCertificate object. This prevents a malicious 562 user from creating multiple WaitCertificates (each with a different nonce) 563 resulting in different WaitCertId digests without re-creating a WaitTimer 564 (and waiting for its duration) each time. It follows that as long as the 565 duration of WaitTimer is not too small a malicious validator who wins the 566 current election has very limited control over the duration of his/hers 567 next WaitTimer. 568 569 #. The check on the Monotonic Counter value guarantees only one enclave 570 instance can obtain a WaitCertificate after the WaitTimer duration 571 elapses. This again prevents a malicious user from running multiple 572 instances of the enclave to create multiple WaitCertificates (each with a 573 different nonce) resulting in different WaitCertId digests and selecting 574 the one that would result in the lowest duration for a new WaitTimer. 575 576 #. A monotonic counter with id MCID is created at the same time PPK and PSK 577 are generated and the triple (MCID, PPK, PSK) is encrypted using AES-GCM 578 with the Seal Key and saved in permanent storage. A malicious validator 579 cannot run multiple enclave instances (before signing up) to create 580 multiple monotonic counters without being forced to commit to using only 581 one eventually. As a monotonic counter is bound to PPK, PSK through the 582 AES-GCM encryption with the Seal Key, when a validator signs-up with a PPK 583 it automatically commits to using the monotonic counter that was created 584 along with PPK, PSK. 585 586 #. **Sign-up AEP replay:** the use of the nonce field in the AEP, which is set 587 equal to :math:`WaitCertId_{n}`, is used to prevent the replay of old AEPs. 588 589 Comments on Multi-user or Multi-ledger SGX Enclave Service 590 ---------------------------------------------------------- 591 592 It is possible to use the same enclave for multiple users or ledgers by 593 providing username and ledgername as input parameters to 594 ``generateSignUpData()`` and ``unsealSignUpData()``. Then the sign-up tuple 595 (username, ledgername, PPK, PSK, MCID) is sealed to disk, with username and 596 ledgername used to generate the filename. Anytime a user authenticates to the 597 service the latter can have the enclave unseal and use the sign-up tuple from 598 the file corresponding to that user (and ledger). 599 600 Population Size and Local Mean Computation 601 ========================================== 602 603 **Parameters**: 604 605 1. targetWaitTime: the desired average wait time. This depends on the network 606 diameter and is selected to minimize the probability of a collision. 607 608 #. initialWaitTime: the initial wait time used in the bootstrapping phase until 609 the ledger contains sampleLength blocks. 610 611 #. sampleLength: number of blocks that need to be on the ledger to finish the 612 bootstrapping phase 613 614 #. minimumWaitTime: a lower bound on the wait time. 615 616 The population size is computed as follows: 617 618 1. :math:`sumMeans = 0` 619 #. :math:`sumWaits = 0` 620 #. | **foreach** wait certificate :math:`wc` stored on the ledger: 621 | :math:`sumWaits += wc\textrm{.duration}-\textrm{minimumWaitTime}` 622 | :math:`sumMeans += wc\textrm{.localMean}` 623 624 #. :math:`populationSize = sumMeans / sumWaits` 625 626 Assuming :math:`b` is the number of blocks currently claimed, the local mean is computed as follows: 627 628 1. | if :math:`b < \textrm{sampleLength}` then 629 | :math:`ratio = 1.0\cdot b / \textrm{sampleLength}` and 630 | :math:`\textrm{localMean} = \textrm{targetWaitTime}\cdot (1 - ratio^2) + \textrm{initialWaitTime}\cdot ratio^2`. 631 #. else :math:`\textrm{localMean}= \textrm{targetWaitTime}\cdot 632 \textrm{populationSize}` 633 634 z-test 635 ====== 636 637 A z-test is used to test the hypothesis that a validator won elections at a 638 higher average rate than expected. 639 640 **Parameters**: 641 642 1. zmax: test value, it measures the maximum deviation from the expected mean. 643 It is selected so that the desired confidence interval $\alpha$ is obtained. 644 Example configurations are: 645 646 a. :math:`\textrm{ztest}=1.645 \leftrightarrow \alpha=0.05` 647 #. :math:`\textrm{ztest}=2.325 \rightarrow \alpha=0.01` 648 #. :math:`\textrm{ztest}=2.575 \rightarrow \alpha=0.005` 649 #. :math:`\textrm{ztest}=3.075 \rightarrow \alpha=0.001` 650 651 2. testValidatorId: the validator identifier under test. 652 653 #. blockArray: an array containing pairs of validator identifier and estimated 654 population size. Each pair represents one published transaction block. 655 656 #. minObservedWins: minimum number of election wins that needs to be observed 657 for the identifier under test. 658 659 The z-test is computed as follows:: 660 661 observedWins = expectedWins = blockCount = 0 662 foreach block = (validatorId, populationEstimate) in blockArray: 663 blockCount += 1 664 expectedWins += 1 / populationEstimate 665 666 if validatorId is equal to testValidatorId: 667 observedWins += 1 668 if observedWins > minObservedWins and observedWins > expectedWins: 669 p = expectedWins / blockCount 670 σ = sqrt(blockCount * p * (1.0 - p)) 671 z = (observedWins - expectedWins) / σ 672 if z > zmax: 673 return False 674 return True 675 676 If the z-test fails (False is returned) then the validator under test won 677 elections at a higher average rate than expected. 678 679 .. Licensed under Creative Commons Attribution 4.0 International License 680 .. https://creativecommons.org/licenses/by/4.0/