diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c7e4781cf..a64c7697b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,7 +21,7 @@ jobs: # Pin the built site to ipfs-cluster, output the cid as `steps.ipfs.outputs.cid` # see: https://github.com/ipfs-shipyard/ipfs-github-action - - uses: ipfs-shipyard/ipfs-github-action@v1.0.0 + - uses: ipfs-shipyard/ipfs-github-action@v2.0.0 id: ipfs with: path_to_add: public diff --git a/README.md b/README.md index cf30278a2..b501203bd 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,19 @@ You can find examples in the `config.toml` source = "actors" target = "content/modules/actors" ``` -This makes files from external repos available for Hugo rendering. +This makes files from external repos available for Hugo rendering and allows for linking to up-to-date files that are directly pulled from other repositories. + +The configuration above gives the following information: + +- `path`: gives the repository you want to mount content from. +- `source`: the folder from the repository referenced in the `path` that we want to mount into our local Hugo filesystem. This is the "root" seen from your Hugo site where you pull content from. In the above case, this means that the source that will be mounted is `https://github.com/filecoin-project/specs-actors/actors/`. +- `target`: the folder in your local Hugo site where the mounted content appears. In our case folder `content` is where we include all Hugo content. + +Putting everything together in an example: if you want to link to the file `xyz.go` from `https://github.com/filecoin-project/specs-actors/actors/xyz-folder/xyz.go`, from any file within the local folder `content` (or any of its subfolders), then with the above configuration you have to include: + +``` +{{}} +``` These modules can be updated with @@ -126,15 +138,28 @@ Some text ``` ## Frontmatter + +Description for all the available frontmatter properties + ```md -title: Libraries + +title: Libraries + description: Libraries used from Filecoin + weight: 3 + bookCollapseSection: true + bookhidden: true + +dashboardWeight: 2 + +dashboardState: stable + dashboardAudit: 1 -dashboardState: wip -dashboardInterface: stable + +dashboardTests: 0 ``` ## Code fences @@ -245,4 +270,4 @@ $\line{9}{\bi}{\return \BinTreeProof_c \thin \{\ \leaf, \thin \root, \thin \path - [editor](https://mermaid-js.github.io/mermaid-live-editor) - [Pan/Zoom for SVG](https://github.com/anvaka/panzoom) - [Icons](https://css.gg/) -- [Working with submodules](https://github.blog/2016-02-01-working-with-submodules/) \ No newline at end of file +- [Working with submodules](https://github.blog/2016-02-01-working-with-submodules/) diff --git a/assets/_colors.scss b/assets/_colors.scss new file mode 100644 index 000000000..f22f0b5b5 --- /dev/null +++ b/assets/_colors.scss @@ -0,0 +1,15 @@ +// Colors +.text-incorrect {color: #ff0010;} +.text-wip {color: #ff6f00;} +.text-incomplete {color: #ffef00;} +.text-stable {color: #90ff00;} +.text-transparent { color: transparent;} +.text-black { color: black;} + +.bg-na { background-color: #6c8293;} +.bg-incorrect {background-color: #ff0010;} +.bg-wip {background-color: #ff6f00;} +.bg-incomplete {background-color: #ffef00;} +.bg-stable {background-color: #90ff00;} +.bg-transparent { background-color: transparent;} +.bg-black { background-color: black;} \ No newline at end of file diff --git a/assets/_custom.scss b/assets/_custom.scss index 02b329e6f..0833b53cf 100644 --- a/assets/_custom.scss +++ b/assets/_custom.scss @@ -5,6 +5,9 @@ // @import "plugins/numbered"; @import "plugins/scrollbars"; @import "plugins/toggles"; +@import "table-sort"; +@import "colors"; +@import "dashboard"; // SVG Diagrams .diagrams-container { diff --git a/assets/_dashboard.scss b/assets/_dashboard.scss new file mode 100644 index 000000000..d65432d71 --- /dev/null +++ b/assets/_dashboard.scss @@ -0,0 +1,17 @@ +.Dashboard tr th, +.Dashboard tr td { + padding: 0 1rem !important; + font-size: 12px; + text-align: center; +} +.Dashboard tr td:first-child { + text-align: left; +} + +.Dashboard-section { + // max-width:250px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + diff --git a/assets/_table-sort.scss b/assets/_table-sort.scss new file mode 100644 index 000000000..79c9b2119 --- /dev/null +++ b/assets/_table-sort.scss @@ -0,0 +1,37 @@ +th[role=columnheader]:not(.no-sort) { + cursor: pointer; + position: relative; + min-width: 110px; +} + +th[role=columnheader]:not(.no-sort):after { + content: ''; + position: absolute; + top: -3px; + right: 10px; + margin-top: 10px; + border-width: 0 4px 4px; + border-style: solid; + border-color: #404040 transparent; + visibility: hidden; + opacity: 0; + -ms-user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +th[aria-sort=ascending]:not(.no-sort):after { + border-bottom: none; + border-width: 4px 4px 0; +} + +th[aria-sort]:not(.no-sort):after { + visibility: visible; + opacity: 0.4; +} + +th[role=columnheader]:not(.no-sort):hover:after { + visibility: visible; + opacity: 1; +} \ No newline at end of file diff --git a/config.toml b/config.toml index 72e1fff4c..36779c4db 100644 --- a/config.toml +++ b/config.toml @@ -70,7 +70,7 @@ enableGitInfo = true # Enable "Edit this page" links for 'doc' page type. # Disabled by default. Uncomment to enable. Requires 'BookRepo' param. # Edit path must point to root directory of repo. - BookEditPath = 'edit/master' + BookEditPath = 'edit/beta' # Configure the date format used on the pages # - In git information diff --git a/content/algorithms/_index.md b/content/algorithms/_index.md index 01498f4bd..a2340a0f5 100644 --- a/content/algorithms/_index.md +++ b/content/algorithms/_index.md @@ -1,7 +1,9 @@ --- title: Algorithms -bookCollapseSection: true -dashboardState: incorrect -type: docs weight: 4 + +dashboardWeight: 2 +dashboardState: wip +dashboardAudit: 0 +dashboardTests: 0 --- diff --git a/content/algorithms/block_sync.md b/content/algorithms/block_sync.md index cf1ecfeaf..dd98883b7 100644 --- a/content/algorithms/block_sync.md +++ b/content/algorithms/block_sync.md @@ -1,6 +1,10 @@ --- title: "BlockSync" weight: 5 +dashboardWeight: 1 +dashboardState: wip +dashboardAudit: 0 +dashboardTests: 0 --- # BlockSync diff --git a/content/algorithms/crypto/_index.md b/content/algorithms/crypto/_index.md index b501fa89f..1fc6d0bfc 100644 --- a/content/algorithms/crypto/_index.md +++ b/content/algorithms/crypto/_index.md @@ -2,10 +2,10 @@ title: "Cryptographic Primitives" bookCollapseSection: true weight: 7 -entries: - - signatures - - vrf - - randomness +dashboardWeight: 2 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # Cryptographic Primitives diff --git a/content/algorithms/crypto/randomness.md b/content/algorithms/crypto/randomness.md index 787d79c3f..0aef64449 100644 --- a/content/algorithms/crypto/randomness.md +++ b/content/algorithms/crypto/randomness.md @@ -1,6 +1,10 @@ --- title: "Randomness" weight: 3 +dashboardWeight: 2 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # Randomness @@ -85,11 +89,7 @@ GetRandomness(dst, l, s): return H(buffer) ``` -{{< hint danger >}} -Issue with readfile -{{< /hint >}} - -{{}} +{{}} {{}} ## Entropy to be used with randomness diff --git a/content/algorithms/crypto/signatures.md b/content/algorithms/crypto/signatures.md index ba508a61b..9373e50d0 100644 --- a/content/algorithms/crypto/signatures.md +++ b/content/algorithms/crypto/signatures.md @@ -1,6 +1,10 @@ --- title: "Signatures" weight: 1 +dashboardWeight: 2 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # Signatures diff --git a/content/algorithms/crypto/vrf.md b/content/algorithms/crypto/vrf.md index bb6d91ae4..785b6672b 100644 --- a/content/algorithms/crypto/vrf.md +++ b/content/algorithms/crypto/vrf.md @@ -1,6 +1,10 @@ --- title: "Verifiable Random Function" weight: 2 +dashboardWeight: 2 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # Verifiable Random Function diff --git a/content/algorithms/cryptoecon/_index.md b/content/algorithms/cryptoecon/_index.md index adfb98168..1a51a8510 100644 --- a/content/algorithms/cryptoecon/_index.md +++ b/content/algorithms/cryptoecon/_index.md @@ -1,6 +1,10 @@ --- title: Cryptoecon weight: 8 +dashboardWeight: 2 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # Cryptoecon diff --git a/content/algorithms/expected_consensus/_index.md b/content/algorithms/expected_consensus/_index.md index 4b80f2733..fca97e3fa 100644 --- a/content/algorithms/expected_consensus/_index.md +++ b/content/algorithms/expected_consensus/_index.md @@ -1,6 +1,10 @@ --- title: "Expected Consensus" weight: 1 +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 1 +dashboardTests: 0 --- # Expected Consensus @@ -201,23 +205,28 @@ This is detectable when a given miner submits two blocks that satisfy any of the - both blocks have valid signatures - first block's epoch is smaller or equal than second block -Thereafter, the faults are: +### Types of faults -- 1. **double-fork mining fault**: two blocks mined at the same epoch. +1. **Double-Fork Mining Fault**: two blocks mined at the same epoch (even if they have the same tipset). - `B4.Epoch == B5.Epoch` {{< svg src="diagrams/double_fork.dot.svg" title="Double-Fork Mining Fault" >}} -- 2. **time-offset mining fault**: two blocks mined off of the same Tipset at different epochs (i.e. with different `ChallengeTickets` generated from the same input ticket). +2. **Time-Offset Mining Fault**: two blocks mined off of the same Tipset at different epochs. - `B3.Parents == B4.Parents && B3.Epoch != B4.Epoch` {{< svg src="diagrams/time_offset.dot.svg" title="Time-Offset Mining Fault" >}} -- 3. **parent-grinding fault**: one block's parent is a Tipset that provably should have included a given block but does not. While it cannot be proven that a missing block was willfully omitted in general (i.e. network latency could simply mean the miner did not receive a particular block), it can when a miner has successfully mined a block two epochs in a row and omitted one. That is, this condition should be evoked when a miner omits their own prior block. +3. **Parent-Grinding Fault**: one block's parent is a Tipset that provably should have included a given block but does not. While it cannot be proven that a missing block was willfully omitted in general (i.e. network latency could simply mean the miner did not receive a particular block), it can when a miner has successfully mined a block two epochs in a row and omitted one. That is, this condition should be evoked when a miner omits their own prior block. Specifically, this can be proven with a "witness" block, that is by submitting blocks B2, B3, B4 where B2 is B4's parent and B3's sibling but B3 is not B4's parent. - `!B4.Parents.Include(B3) && B4.Parents.Include(B2) && B3.Parents == B2.Parents && B3.Epoch == B2.Epoch` {{< svg src="diagrams/parent_grinding.dot.svg" title="Parent-Grinding fault" >}} -Any node that detects any of the above events should submit both block headers to the `StoragePowerActor`'s `ReportConsensusFault` method. The "slasher" will receive a portion of the offending miner's [Pledge Collateral](storage_power_actor#pledge-collateral) as a reward for notifying the network of the fault. Consensus faults (except for **uncommitted power fault** below which falls under storage faults with impact on consensus) will tentatively result in all pledge collateral being slashed and the miner removed from the power table. Some portion of the pledge collateral is given to the slasher as a function of some initial share (`SLASHER_INITIAL_SHARE`) and growth rate (`SLASHER_SHARE_GROWTH_RATE`). Slasher's share of the slashed collateral increases as block elapses since the block when the fault is committed. Default growth rate results in slasher's share reaches 1 after 250 blocks. However, only the first slasher gets its share of the pledge collateral and the remaining pledge collateral will be burned. The longer a slasher waits, the higher the likelihood that the slashed collateral will be claimed by another slasher. +### Penalization for faults +A single consensus fault results into: +- miner termination and removal of power from the power table, +- loss of all pledge collateral (which includes the initial pledge and blocks rewards yet to be vested) -It is important to note that there exists a third type of consensus fault directly reported by the `CronActor` on `StorageDeal` failures via the `ReportUncommittedPowerFault` method: +### Detection and Reporting -- 4. **uncommitted power fault** which occurs when a miner fails to submit their `PostProof` and is thus participating in leader election with undue power (see [Storage Faults](faults#storage-faults)). +A node that detects and report a consensus fault is called "slasher", any user in Filecoin can be a slasher. They can report consensus faults by calling the `ReportConsensusFault` on the `StorageMinerActor` of the faulty miner. The slasher is rewarded with a portion of the offending miner's [Pledge Collateral](storage_power_actor#pledge-collateral) for notifying the network of the consensu fault. + +The reward give to the slasher is a function of some initial share (`SLASHER_INITIAL_SHARE`) and growth rate (`SLASHER_SHARE_GROWTH_RATE`) and it has a maximum `maxReporterShare`. Slasher's share increases exponentially as epoch elapses since the block when the fault is committed (see `RewardForConsensusSlashReport`). Only the first slasher gets their share of the pledge collateral and the remaining pledge collateral is burned. The longer a slasher waits, the higher the likelihood that the slashed collateral will be claimed by another slasher. diff --git a/content/algorithms/gossip_sub.md b/content/algorithms/gossip_sub.md index b148111ea..06c7483dc 100644 --- a/content/algorithms/gossip_sub.md +++ b/content/algorithms/gossip_sub.md @@ -1,6 +1,10 @@ --- title: "GossipSub" weight: 6 +dashboardWeight: 1.5 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # GossipSub diff --git a/content/algorithms/payment_channels.md b/content/algorithms/payment_channels.md index b501d495a..a9cd1c643 100644 --- a/content/algorithms/payment_channels.md +++ b/content/algorithms/payment_channels.md @@ -1,6 +1,10 @@ --- title: "Payment Channels" weight: 4 +dashboardWeight: 1 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # Payment Channels diff --git a/content/algorithms/porep/_index.md b/content/algorithms/porep/_index.md index b514cf9e0..85c16c056 100644 --- a/content/algorithms/porep/_index.md +++ b/content/algorithms/porep/_index.md @@ -7,4 +7,6 @@ weight: 2 # Proof-of-Replication --- -{{< pdf src="https://filecoin.io/filecoin.pdf" title="Filecoin Paper">}} \ No newline at end of file +_Proof-of-Replication(PoRep)_, is a new kind of _Proof-of-Storage_, that can be used to prove that some data _D_ has been replicated to its own uniquely dedicated physical storage. Enforcing unique physical copies enables a verifier to check that a prover is not deduplicating multiple copies of _D_ into the same storage space. This construction is particularly useful in Cloud Computing and Decentralized Storage Networks, which must be transparently verifiable, resistant to Sybil attacks, and unfriendly to outsourcing. + +Section 3.2 of the [Filecoin Paper](https://filecoin.io/filecoin.pdf) provides the original introduction to Proof-of-Replication. diff --git a/content/algorithms/post/_index.md b/content/algorithms/post/_index.md index ae5c06d7d..5a2bf674c 100644 --- a/content/algorithms/post/_index.md +++ b/content/algorithms/post/_index.md @@ -2,8 +2,24 @@ title: Proof-of-Spacetime bookCollapseSection: true weight: 3 +dashboardWeight: 2 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # Proof-of-Spacetime --- -{{< pdf src="https://filecoin.io/filecoin.pdf" title="Filecoin Paper">}} +_Proof-of-Storage_ schemes allow a user to check if a storage provider is storing the outsourced data at the time +of the challenge. How can we use **PoS** schemes to prove that some data was being stored throughout a period +of time? A natural answer to this question is to require the user to repeatedly (e.g. every minute) send +challenges to the storage provider. However, the communication complexity required in each interaction can +be the bottleneck in systems such as Filecoin, where storage providers are required to submit their proofs to +the blockchain network. + +To address this question, we introduce a new proof, _Proof-of-Spacetime_, where a verifier can check if a prover +is storing her/his outsourced data for a range of time. The intuition is to require the prover to (1) generate +sequential Proofs-of-Storage (in our case Proof-of-Replication), as a way to determine time (2) recursively +compose the executions to generate a short proof. + +Section 3.3 of the [Filecoin Paper](https://filecoin.io/filecoin.pdf) provides the original introduction to Proof-of-Spacetime. diff --git a/content/algorithms/post/election_post.md b/content/algorithms/post/election_post.md index 008c13350..d25a9c698 100644 --- a/content/algorithms/post/election_post.md +++ b/content/algorithms/post/election_post.md @@ -1,5 +1,9 @@ --- title: Election PoSt +dashboardWeight: 2 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # Election PoSt diff --git a/content/algorithms/post/proof_of_spacetime_parameters.org b/content/algorithms/post/proof_of_spacetime_parameters.org index e6c5b708e..d63eb83fb 100644 --- a/content/algorithms/post/proof_of_spacetime_parameters.org +++ b/content/algorithms/post/proof_of_spacetime_parameters.org @@ -1,6 +1,10 @@ #+TITLE: PoSt Parameters #+HUGO_SECTION: algorithms/post #+HUGO_BASE_DIR: ../../ +#+dashboardWeight: 2 +#+dashboardState: incorrect +#+dashboardAudit: 0 +#+dashboardTests: 0 * Proof of Spacetime Paramerters diff --git a/content/algorithms/sdr/_index.md b/content/algorithms/sdr/_index.md index 9bc1d37c2..482a6115e 100644 --- a/content/algorithms/sdr/_index.md +++ b/content/algorithms/sdr/_index.md @@ -1,5 +1,1911 @@ --- title: "Stacked DRG PoRep" +description: "Stacked DRG Proof of Replication Specification" + bookCollapseSection: true weight: 1 +math-mode: true + +dashboardWeight: 2 +dashboardState: stable +dashboardAudit: 1 +dashboardTests: 0 --- + + +{{< plain hidden >}} +$$ +\gdef\createporepbatch{\textsf{create\_porep\_batch}} +\gdef\GrothProof{\textsf{Groth16Proof}} +\gdef\Groth{\textsf{Groth16}} +\gdef\GrothEvaluationKey{\textsf{Groth16EvaluationKey}} +\gdef\GrothVerificationKey{\textsf{Groth16VerificationKey}} +\gdef\creategrothproof{\textsf{create\_groth16\_proof}} +\gdef\ParentLabels{\textsf{ParentLabels}} +\gdef\or#1#2{\langle #1 | #2 \rangle} +\gdef\porepreplicas{\textsf{porep\_replicas}} +\gdef\postreplicas{\textsf{post\_replicas}} +\gdef\winningpartitions{\textsf{winning\_partitions}} +\gdef\windowpartitions{\textsf{window\_partitions}} +\gdef\sector{\textsf{sector}} +\gdef\lebitstolebytes{\textsf{le\_bits\_to\_le\_bytes}} +\gdef\lebinrep#1{{\llcorner #1 \lrcorner_{\lower{2pt}{2, \textsf{le}}}}} +\gdef\bebinrep#1{{\llcorner #1 \lrcorner_{\lower{2pt}{2, \textsf{be}}}}} +\gdef\lebytesbinrep#1{{\llcorner #1 \lrcorner_{\lower{2pt}{2, \textsf{le-bytes}}}}} +\gdef\fesitelrounds{\textsf{fesitel\_rounds}} +\gdef\int{\textsf{int}} +\gdef\lebytes{\textsf{le-bytes}} +\gdef\lebytestolebits{\textsf{le\_bytes\_to\_le\_bits}} +\gdef\letooctet{\textsf{le\_to\_octet}} +\gdef\byte{\textsf{byte}} +\gdef\postpartitions{\textsf{post\_partitions}} +\gdef\PostReplica{\textsf{PostReplica}} +\gdef\PostReplicas{\textsf{PostReplicas}} +\gdef\PostPartitionProof{\textsf{PostPartitionProof}} +\gdef\PostReplicaProof{\textsf{PostReplicaProof}} +\gdef\TreeRProofs{\textsf{TreeRProofs}} +\gdef\pad{\textsf{pad}} +\gdef\octettole{\textsf{octet\_to\_le}} +\gdef\packed{\textsf{packed}} +\gdef\val{\textsf{val}} +\gdef\bits{\textsf{bits}} +\gdef\partitions{\textsf{partitions}} +\gdef\Batch{\textsf{Batch}} +\gdef\batch{\textsf{batch}} +\gdef\postbatch{\textsf{post\_batch}} +\gdef\postchallenges{\textsf{post\_challenges}} +\gdef\Nonce{\textsf{Nonce}} +\gdef\createvanillaporepproof{\textsf{create\_vanilla\_porep\_proof}} +\gdef\PorepVersion{\textsf{PorepVersion}} +\gdef\bedecode{\textsf{be\_decode}} +\gdef\OR{\mathbin{|}} +\gdef\indexbits{\textsf{index\_bits}} +\gdef\nor{\textsf{nor}} +\gdef\and{\textsf{and}} +\gdef\norgadget{\textsf{nor\_gadget}} +\gdef\andgadget{\textsf{and\_gadget}} +\gdef\el{\textsf{el}} +\gdef\arr{\textsf{arr}} +\gdef\pickgadget{\textsf{pick\_gadget}} +\gdef\pick{\textsf{pick}} +\gdef\int{\textsf{int}} +\gdef\x{\textsf{x}} +\gdef\y{\textsf{y}} +\gdef\aap{{\langle \auxb | \pubb \rangle}} +\gdef\aapc{{\langle \auxb | \pubb | \constb \rangle}} +\gdef\TreeRProofs{\textsf{TreeRProofs}} +\gdef\parentlabelsbits{\textsf{parent\_labels\_bits}} +\gdef\label{\textsf{label}} +\gdef\layerbits{\textsf{layer\_bits}} +\gdef\labelbits{\textsf{label\_bits}} +\gdef\digestbits{\textsf{digest\_bits}} +\gdef\node{\textsf{node}} +\gdef\layerindex{\textsf{layer\_index}} +\gdef\be{\textsf{be}} +\gdef\octet{\textsf{octet}} +\gdef\reverse{\textsf{reverse}} +\gdef\LSBit{\textsf{LSBit}} +\gdef\MSBit{\textsf{MSBit}} +\gdef\LSByte{\textsf{LSByte}} +\gdef\MSByte{\textsf{MSByte}} +\gdef\PorepPartitionProof{\textsf{PorepPartitionProof}} +\gdef\PostPartitionProof{\textsf{PostPartitionProof}} +\gdef\lebinrep#1{{\llcorner #1 \lrcorner_{\lower{2pt}{2, \textsf{le}}}}} +\gdef\bebinrep#1{{\llcorner #1 \lrcorner_{\lower{2pt}{2, \textsf{be}}}}} +\gdef\octetbinrep#1{{\llcorner #1 \lrcorner_{\lower{2pt}{2, \textsf{octet}}}}} +\gdef\fieldelement{\textsf{field\_element}} +\gdef\Fqsafe{{\mathbb{F}_{q, \safe}}} +\gdef\elem{\textsf{elem}} +\gdef\challenge{\textsf{challenge}} +\gdef\challengeindex{\textsf{challenge\_index}} +\gdef\uniquechallengeindex{\textsf{unique\_challenge\_index}} +\gdef\replicaindex{\textsf{replica\_index}} +\gdef\uniquereplicaindex{\textsf{unique\_replica\_index}} +\gdef\nreplicas{\textsf{n\_replicas}} +\gdef\unique{\textsf{unique}} +\gdef\R{\mathcal{R}} +\gdef\getpostchallenge{\textsf{get\_post\_challenge}} +\gdef\verifyvanillapostproof{\textsf{verify\_vanilla\_post\_proof}} +\gdef\BinPathElement{\textsf{BinPathElement}} +\gdef\BinTreeDepth{\textsf{BinTreeDepth}} +\gdef\BinTree{\textsf{BinTree}} +\gdef\BinTreeProof{\textsf{BinTreeProof}} +\gdef\bintreeproofisvalid{\textsf{bintree\_proof\_is\_valid}} +\gdef\Bit{{\{0, 1\}}} +\gdef\Byte{\mathbb{B}} +\gdef\calculatebintreechallenge{\textsf{calculate\_bintree\_challenge}} +\gdef\calculateocttreechallenge{\textsf{calculate\_octtree\_challenge}} +\gdef\depth{\textsf{depth}} +\gdef\dot{\textsf{.}} +\gdef\for{\textsf{for }} +\gdef\Function{\textbf{Function: }} +\gdef\Fq{{\mathbb{F}_q}} +\gdef\leaf{\textsf{leaf}} +\gdef\line#1#2#3{\scriptsize{\textsf{#1.}#2}\ \normalsize{#3}} +\gdef\missing{\textsf{missing}} +\gdef\NodeIndex{\textsf{NodeIndex}} +\gdef\nodes{\textsf{nodes}} +\gdef\OctPathElement{\textsf{OctPathElement}} +\gdef\OctTree{\textsf{OctTree}} +\gdef\OctTreeDepth{\textsf{OctTreeDepth}} +\gdef\OctTreeProof{\textsf{OctTreeProof}} +\gdef\octtreeproofisvalid{\textsf{octtree\_proof\_is\_valid}} +\gdef\path{\textsf{path}} +\gdef\pathelem{\textsf{path\_elem}} +\gdef\return{\textsf{return }} +\gdef\root{\textsf{root}} +\gdef\Safe{{\Byte^{[32]}_\textsf{safe}}} +\gdef\sibling{\textsf{sibling}} +\gdef\siblings{\textsf{siblings}} +\gdef\struct{\textsf{struct }} +\gdef\Teq{\underset{{\small \mathbb{T}}}{=}} +\gdef\Tequiv{\underset{{\small \mathbb{T}}}{\equiv}} +\gdef\thin{{\thinspace}} +\gdef\AND{\mathbin{\&}} +\gdef\MOD{\mathbin{\%}} +\gdef\createproof{{\textsf{create\_proof}}} +\gdef\layer{\textsf{layer}} +\gdef\nodeindex{\textsf{node\_index}} +\gdef\childindex{\textsf{child\_index}} +\gdef\push{\textsf{push}} +\gdef\index{\textsf{index}} +\gdef\leaves{\textsf{leaves}} +\gdef\len{\textsf{len}} +\gdef\ColumnProof{\textsf{ColumnProof}} +\gdef\concat{\mathbin{\|}} +\gdef\inputs{\textsf{inputs}} +\gdef\Poseidon{\textsf{Poseidon}} +\gdef\bi{\ \ } +\gdef\Bool{{\{\textsf{True}, \textsf{False}\}}} +\gdef\curr{\textsf{curr}} +\gdef\if{\textsf{if }} +\gdef\else{\textsf{else}} +\gdef\proof{\textsf{proof}} +\gdef\Sha#1{\textsf{Sha#1}} +\gdef\ldotdot{{\ldotp\ldotp}} +\gdef\as{\textsf{ as }} +\gdef\bintreerootgadget{\textsf{bintree\_root\_gadget}} +\gdef\octtreerootgadget{\textsf{octtree\_root\_gadget}} +\gdef\cs{\textsf{cs}} +\gdef\RCS{\textsf{R1CS}} +\gdef\pathbits{\textsf{path\_bits}} +\gdef\missingbit{\textsf{missing\_bit}} +\gdef\missingbits{\textsf{missing\_bits}} +\gdef\pubb{\textbf{pub}} +\gdef\privb{\textbf{priv}} +\gdef\auxb{\textbf{aux}} +\gdef\constb{\textbf{const}} +\gdef\CircuitVal{\textsf{CircuitVal}} +\gdef\CircuitBit{{\textsf{CircuitVal}_\Bit}} +\gdef\Le{\textsf{le}} +\gdef\privateinput{\textsf{private\_input}} +\gdef\publicinput{\textsf{public\_input}} +\gdef\deq{\mathbin{\overset{\diamond}{=}}} +\gdef\alloc{\textsf{alloc}} +\gdef\insertgadget#1{\textsf{insert\_#1\_gadget}} +\gdef\block{\textsf{block}} +\gdef\shagadget#1#2{\textsf{sha#1\_#2\_gadget}} +\gdef\poseidongadget#1{\textsf{poseidon\_#1\_gadget}} +\gdef\refeq{\mathbin{\overset{{\small \&}}=}} +\gdef\ptreq{\mathbin{\overset{{\small \&}}=}} +\gdef\bit{\textsf{bit}} +\gdef\extend{\textsf{extend}} +\gdef\auxle{{[\textbf{aux}, \textsf{le}]}} +\gdef\SpecificNotation{{\underline{\text{Specific Notation}}}} +\gdef\repeat{\textsf{repeat}} +\gdef\preimage{\textsf{preimage}} +\gdef\digest{\textsf{digest}} +\gdef\digestbytes{\textsf{digest\_bytes}} +\gdef\digestint{\textsf{digest\_int}} +\gdef\leencode{\textsf{le\_encode}} +\gdef\ledecode{\textsf{le\_decode}} +\gdef\ReplicaID{\textsf{ReplicaID}} +\gdef\replicaid{\textsf{replica\_id}} +\gdef\replicaidbits{\textsf{replica\_id\_bits}} +\gdef\replicaidblock{\textsf{replica\_id\_block}} +\gdef\cc{\textsf{::}} +\gdef\new{\textsf{new}} +\gdef\lebitsgadget{\textsf{le\_bits\_gadget}} +\gdef\CircuitBitOrConst{{\textsf{CircuitValOrConst}_\Bit}} +\gdef\createporepcircuit{\textsf{create\_porep\_circuit}} +\gdef\CommD{\textsf{CommD}} +\gdef\CommC{\textsf{CommC}} +\gdef\CommR{\textsf{CommR}} +\gdef\CommCR{\textsf{CommCR}} +\gdef\commd{\textsf{comm\_d}} +\gdef\commc{\textsf{comm\_c}} +\gdef\commr{\textsf{comm\_r}} +\gdef\commcr{\textsf{comm\_cr}} +\gdef\assert{\textsf{assert}} +\gdef\asserteq{\textsf{assert\_eq}} +\gdef\TreeDProof{\textsf{TreeDProof}} +\gdef\TreeRProof{\textsf{TreeRProof}} +\gdef\TreeR{\textsf{TreeR}} +\gdef\ParentColumnProofs{\textsf{ParentColumnProofs}} +\gdef\challengebits{\textsf{challenge\_bits}} +\gdef\packedchallenge{\textsf{packed\_challenge}} +\gdef\PartitionProof{\textsf{PartitionProof}} +\gdef\u#1{\textsf{u#1}} +\gdef\packbitsasinputgadget{\textsf{pack\_bits\_as\_input\_gadget}} +\gdef\treedleaf{\textsf{tree\_d\_leaf}} +\gdef\treerleaf{\textsf{tree\_r\_leaf}} +\gdef\calculatedtreedroot{\textsf{calculated\_tree\_d\_root}} +\gdef\calculatedtreerleaf{\textsf{calculated\_tree\_r\_leaf}} +\gdef\calculatedcommd{\textsf{calculated\_comm\_d}} +\gdef\calculatedcommc{\textsf{calculated\_comm\_c}} +\gdef\calculatedcommr{\textsf{calculated\_comm\_r}} +\gdef\calculatedcommcr{\textsf{calculated\_comm\_cr}} +\gdef\layers{\textsf{layers}} +\gdef\total{\textsf{total}} +\gdef\column{\textsf{column}} +\gdef\parentcolumns{\textsf{parent\_columns}} +\gdef\columns{\textsf{columns}} +\gdef\parentlabel{\textsf{parent\_label}} +\gdef\label{\textsf{label}} +\gdef\calculatedtreecleaf{\textsf{calculated\_tree\_c\_leaf}} +\gdef\calculatedcolumn{\textsf{calculated\_column}} +\gdef\parentlabels{\textsf{parent\_labels}} +\gdef\drg{\textsf{drg}} +\gdef\exp{\textsf{exp}} +\gdef\parentlabelbits{\textsf{parent\_label\_bits}} +\gdef\parentlabelblock{\textsf{parent\_label\_block}} +\gdef\Bits{\textsf{ Bits}} +\gdef\safe{\textsf{safe}} +\gdef\calculatedlabel{\textsf{calculated\_label}} +\gdef\createlabelgadget{\textsf{create\_label\_gadget}} +\gdef\encodingkey{\textsf{encoding\_key}} +\gdef\encodegadget{\textsf{encode\_gadget}} +\gdef\TreeC{\textsf{TreeC}} +\gdef\value{\textsf{value}} +\gdef\encoded{\textsf{encoded}} +\gdef\unencoded{\textsf{unencoded}} +\gdef\key{\textsf{key}} +\gdef\lc{\textsf{lc}} +\gdef\LC{\textsf{LC}} +\gdef\LinearCombination{\textsf{LinearCombination}} +\gdef\one{\textsf{one}} +\gdef\constraint{\textsf{constraint}} +\gdef\proofs{\textsf{proofs}} +\gdef\merkleproofs{\textsf{merkle\_proofs}} +\gdef\TreeRProofs{\textsf{TreeRProofs}} +\gdef\challenges{\textsf{challenges}} +\gdef\pub{\textsf{pub}} +\gdef\priv{\textsf{priv}} +\gdef\last{\textsf{last}} +\gdef\TreeRProofs{\textsf{TreeRProofs}} +\gdef\post{\textsf{post}} +\gdef\SectorID{\textsf{SectorID}} +\gdef\winning{\textsf{winning}} +\gdef\window{\textsf{window}} +\gdef\Replicas{\textsf{Replicas}} +\gdef\P{\mathcal{P}} +\gdef\V{\mathcal{V}} +\gdef\ww{{\textsf{winning}|\textsf{window}}} +\gdef\replicasperk{{\textsf{replicas}/k}} +\gdef\replicas{\textsf{replicas}} +\gdef\Replica{\textsf{Replica}} +\gdef\createvanillapostproof{\textsf{create\_vanilla\_post\_proof}} +\gdef\createpostcircuit{\textsf{create\_post\_circuit}} +\gdef\ReplicaProof{\textsf{ReplicaProof}} +\gdef\aww{{\langle \ww \rangle}} +\gdef\partitionproof{\textsf{partition\_proof}} +\gdef\replicas{\textsf{replicas}} +\gdef\getdrgparents{\textsf{get\_drg\_parents}} +\gdef\getexpparents{\textsf{get\_exp\_parents}} +\gdef\DrgSeed{\textsf{DrgSeed}} +\gdef\DrgSeedPrefix{\textsf{DrgSeedPrefix}} +\gdef\FeistelKeysBytes{\textsf{FeistelKeysBytes}} +\gdef\porep{\textsf{porep}} +\gdef\rng{\textsf{rng}} +\gdef\ChaCha#1{\textsf{ChaCha#1}} +\gdef\cc{\textsf{::}} +\gdef\fromseed{\textsf{from\_seed}} +\gdef\buckets{\textsf{buckets}} +\gdef\meta{\textsf{meta}} +\gdef\dist{\textsf{dist}} +\gdef\each{\textsf{each}} +\gdef\PorepID{\textsf{PorepID}} +\gdef\porepgraphseed{\textsf{porep\_graph\_seed}} +\gdef\utf{\textsf{utf8}} +\gdef\DrgStringID{\textsf{DrgStringID}} +\gdef\FeistelStringID{\textsf{FeistelStringID}} +\gdef\graphid{\textsf{graph\_id}} +\gdef\createfeistelkeys{\textsf{create\_feistel\_keys}} +\gdef\FeistelKeys{\textsf{FeistelKeys}} +\gdef\feistelrounds{\textsf{fesitel\_rounds}} +\gdef\feistel{\textsf{feistel}} +\gdef\ExpEdgeIndex{\textsf{ExpEdgeIndex}} +\gdef\loop{\textsf{loop}} +\gdef\right{\textsf{right}} +\gdef\left{\textsf{left}} +\gdef\mask{\textsf{mask}} +\gdef\RightMask{\textsf{RightMask}} +\gdef\LeftMask{\textsf{LeftMask}} +\gdef\roundkey{\textsf{round\_key}} +\gdef\beencode{\textsf{be\_encode}} +\gdef\Blake{\textsf{Blake2b}} +\gdef\input{\textsf{input}} +\gdef\output{\textsf{output}} +\gdef\while{\textsf{while }} +\gdef\digestright{\textsf{digest\_right}} +\gdef\xor{\mathbin{\oplus_\text{xor}}} +\gdef\Edges{\textsf{ Edges}} +\gdef\edge{\textsf{edge}} +\gdef\expedge{\textsf{exp\_edge}} +\gdef\expedges{\textsf{exp\_edges}} +\gdef\createlabel{\textsf{create\_label}} +\gdef\Label{\textsf{Label}} +\gdef\Column{\textsf{Column}} +\gdef\Columns{\textsf{Columns}} +\gdef\ParentColumns{\textsf{ParentColumns}} +% `\tern` should be written as +% \gdef\tern#1?#2:#3{#1\ \text{?}\ #2 \ \text{:}\ #3} +% but that's not possible due to https://github.com/KaTeX/KaTeX/issues/2288 +\gdef\tern#1#2#3{#1\ \text{?}\ #2 \ \text{:}\ #3} +\gdef\repeattolength{\textsf{repeat\_to\_length}} +\gdef\verifyvanillaporepproof{\textsf{verify\_vanilla\_porep\_proof}} +\gdef\poreppartitions{\textsf{porep\_partitions}} +\gdef\challengeindex{\textsf{challenge\_index}} +\gdef\porepbatch{\textsf{porep\_batch}} +\gdef\winningchallenges{\textsf{winning\_challenges}} +\gdef\windowchallenges{\textsf{window\_challenges}} +\gdef\PorepPartitionProof{\textsf{PorepPartitionProof}} +\gdef\TreeD{\textsf{TreeD}} +\gdef\TreeCProof{\textsf{TreeCProof}} +\gdef\Labels{\textsf{Labels}} +\gdef\porepchallenges{\textsf{porep\_challenges}} +\gdef\postchallenges{\textsf{post\_challenges}} +\gdef\PorepChallengeSeed{\textsf{PorepChallengeSeed}} +\gdef\getporepchallenges{\textsf{get\_porep\_challenges}} +\gdef\getallparents{\textsf{get\_all\_parents}} +\gdef\PorepChallengeProof{\textsf{PorepChallengeProof}} +\gdef\challengeproof{\textsf{challenge\_proof}} +\gdef\PorepChallenges{\textsf{PorepChallenges}} +\gdef\replicate{\textsf{replicate}} +\gdef\createreplicaid{\textsf{create\_replica\_id}} +\gdef\ProverID{\textsf{ProverID}} +\gdef\replicaid{\textsf{replica\_id}} +\gdef\generatelabels{\textsf{generate\_labels}} +\gdef\labelwithdrgparents{\textsf{label\_with\_drg\_parents}} +\gdef\labelwithallparents{\textsf{label\_with\_all\_parents}} +\gdef\createtreecfromlabels{\textsf{create\_tree\_c\_from\_labels}} +\gdef\ColumnDigest{\textsf{ColumnDigest}} +\gdef\encode{\textsf{encode}} +$$ +{{< /plain >}} + +# Stacked DRG Proof of Replication +--- + +## Merkle Proofs + +**Implementation:** +* [`storage_proofs::merkle::MerkleTreeWrapper::gen_proof()`]() +* [`merkle_light::merkle::MerkleTree::gen_proof()`](https://github.com/filecoin-project/merkle_light/blob/64a468807c594d306d12d943dd90cc5f88d0d6b0/src/merkle.rs#L918) + +**Additional Notation:** + +`$\index_l: [\lfloor N_\nodes / 2^l \rfloor] \equiv [\len(\BinTree\dot\layer_l)]$`\ +The index of a node in a `$\BinTree$` layer `$l$`. The leftmost node in a tree has `$\index_l = 0$`. For each tree layer `$l$` (excluding the root layer) a Merkle proof verifier calculates the label of the node at `$\index_l$` from a single Merkle proof path element `$\BinTreeProof_c\dot\path[l - 1] \thin$`. + +### BinTreeProofs + +The method `$\BinTreeProof\dot\createproof$` is used to create a Merkle proof for a challenge node `$c$`. + +```text +$\overline{\underline{\Function \BinTree\dot\createproof(c: \NodeIndex) \rightarrow \BinTreeProof_c}}$ +$\line{1}{\bi}{\leaf: \Safe = \BinTree\dot\leaves[c]}$ +$\line{2}{\bi}{\root: \Safe = \BinTree\dot\root}$ + +$\line{3}{\bi}{\path: \BinPathElement^{[\BinTreeDepth]}= [\ ]}$ +$\line{4}{\bi}{\for l \in [\BinTreeDepth]:}$ +$\line{5}{\bi}{\quad \index_l: [\len(\BinTree\dot\layer_l)] = c \gg l}$ +$\line{6}{\bi}{\quad \missing: \Bit = \index_l \AND 1}$ +$\line{7}{\bi}{\quad \sibling: \Safe = \if \missing = 0:}$ +$\quad\quad\quad \BinTree\dot\layer_l[\index_l + 1]$ +$\quad\quad\thin \else:$ +$\quad\quad\quad \BinTree\dot\layer_l[\index_l - 1]$ +$\line{8}{\bi}{\quad \path\dot\push(\BinPathElement \thin \{\ \sibling, \thin \missing\ \} \thin )}$ + +$\line{9}{\bi}{\return \BinTreeProof_c \thin \{\ \leaf, \thin \root, \thin \path\ \}}$ +``` + +**Code Comments:** +* **Line 5:** Calculates the node index in layer `$l$` of the node that the verifier calculated using the previous lath element (or the `$\BinTreeProof_c\dot\leaf$` if `$l = 0$`). Note that `$c \gg l \equiv \lfloor c / 2^l \rfloor \thin$`. + +### OctTreeProofs + +The method `$\OctTreeProof\dot\createproof$` is used to create a Merkle proof for a challenge node `$c$`. + +**Additional Notation:** + +`$\index_l: [\lfloor N_\nodes / 8^l \rfloor] \equiv [\len(\OctTree\dot\layer_l)]$`\ +The index of a node in an `$\OctTree$` layer `$l$`. The leftmost node in a tree has `$\index_l = 0$`. For each tree layer `$l$` (excluding the root layer) a Merkle proof verifier calculates the label of the node at `$\index_l$` from a single Merkle proof path element `$\OctTreeProof_c\dot\path[l - 1] \thin$`. + +`$\textsf{first\_sibling}_l \thin, \textsf{last\_sibling}: [\lfloor N_\nodes / 8^l \rfloor]$`\ +The node indexes in tree layer `$l$` of the first and last nodes in this layer's Merkle path element's siblings array `$\OctTreeProof_c\dot\path[l]\dot\siblings \thin$`. + +```text +$\overline{\underline{\Function \OctTree\dot\createproof(c: \NodeIndex) \rightarrow \OctTreeProof_c}}$ +$\line{1}{\bi}{\leaf: \Fq = \OctTree\dot\leaves[c]}$ +$\line{2}{\bi}{\root: \Fq = \OctTree\dot\root}$ + +$\line{3}{\bi}{\path: \OctPathElement^{[\OctTreeDepth]}= [\ ]}$ +$\line{4}{\bi}{\for l \in [\OctTreeDepth]:}$ +$\line{5}{\bi}{\quad \index_l: [\len(\OctTree\dot\layer_l)] = c \gg (3 * l)}$ +$\line{6}{\bi}{\quad \missing: [8] = \index_l \MOD 8}$ + +$\line{7}{\bi}{\quad \textsf{first\_sibling}_l = \index_l - \missing}$ +$\line{8}{\bi}{\quad \textsf{last\_sibling}_l = \index_l + (7 - \missing)}$ +$\line{9}{\bi}{\quad \siblings: \Fq^{[7]} =}$ +$\quad\quad\quad \OctTree\dot\layer_l[\textsf{first\_sibling}_l \mathbin{\ldotdot} \index_l]$ +$\quad\quad\quad \|\ \OctTree\dot\layer_l[\index_l + 1 \mathbin{\ldotdot} \textsf{last\_sibling}_l + 1]$ + +$\line{10}{}{\quad \path\dot\push(\OctPathElement \thin \{\ \siblings, \thin \missing\ \} \thin )}$ +$\line{11}{}{\return \OctTreeProof_c \thin \{\ \leaf, \thin \root, \thin \path\ \}}$ +``` + +**Code Comments:** +* **Line 5:** Calculates the node index in layer `$l$` of the node that the verifier calculated themselves using the previous path element (or `$\OctTreeProof_c\dot\leaf$` if `$l = 0$`). Note that `$c \gg (3 * l) \equiv \lfloor c / 8^l \rfloor \thin$`. +* **Line 7-8:** Calculates the indexes in tree layer `$l$` of the first and last (both inclusive) Merkle hash inputs for layer `$l$`'s path element. +* **Line 9:** Copies the 7 Merkle hash inputs that will be in layer `$l$`'s path element `$\OctTreeProof\dot\path[l]\dot\siblings \thin$`. + +### Proof Root Validation + +The functions `$\bintreeproofisvalid$` and `$\octtreeproofisvalid$` are used to verify that a `$\BinTreeProof\dot\path$` or an `$\OctTreeProof\dot\path$` hash to the root found in the Merkle proof `$\BinTreeProof\dot\root$` and `$\OctTreeProof\dot\root$` respectively. + +Note that these functions do not verify that a `$\BinTreeProof\dot\path$` or an `$\OctTreeProof\dot\path$` correspond to the expected Merkle challenge `$c$`. To verify that a proof path is consistent with `$c$`, see the psuedocode functions `$\calculatebintreechallenge$` and `$\calculateocttreechallenge$`. + +**Implementation:** +* [`storage_proofs::core::merkle::proof::SingleProof::verify()`](https://github.com/filecoin-project/rust-fil-proofs/blob/f75804c503d9b97a2b02ef3ea2e5d44e8e2c6470/storage-proofs/core/src/merkle/proof.rs#L540) +* [`storage_proofs::core::merkle::proof::InclusionPath::root()`](https://github.com/filecoin-project/rust-fil-proofs/blob/f75804c503d9b97a2b02ef3ea2e5d44e8e2c6470/storage-proofs/core/src/merkle/proof.rs#L189) + +```text +$\overline{\underline{\Function \bintreeproofisvalid(\proof: \BinTreeProof) \rightarrow \Bool}\thin}$ +$\line{1}{\bi}{\curr: \Safe = \proof\dot\leaf}$ +$\line{2}{\bi}{\for \sibling, \missing \in \proof\dot\path:}$ +$\line{3}{\bi}{\quad \curr: \Safe = \if \missing = 0:}$ +$\quad\quad\quad\quad \Sha{254}_2([\curr, \sibling])$ +$\quad\quad\thin \else:$ +$\quad\quad\quad\quad \Sha{254}_2([\sibling, \curr])$ +$\line{4}{\bi}{\return \curr = \proof\dot\root}$ +``` + +The function `$\octtreeproofisvalid$` can receive as the type of its `$\proof$` argument either an `$\OctTreeProof$` or `$\ColumnProof$` (a `$\ColumnProof$` is just an `$\OctTreeProof$` with an adjoined field `$\column$`, `$\ColumnProof_c \equiv \OctTreeProof_c \cup \column_c \thin$`). + +```text +$\overline{\underline{\Function \octtreeproofisvalid(\proof: \OctTreeProof) \rightarrow \Bool}\thin}$ +$\line{1}{\bi}{\curr: \Fq = \proof\dot\leaf}$ +$\line{2}{\bi}{\for \siblings, \missing \in \proof\dot\path:}$ +$\line{3}{\bi}{\quad \inputs: \Fq^{[8]} = \siblings[\ldotdot \missing] \concat \curr \concat \siblings[\missing \ldotdot]}$ +$\line{4}{\bi}{\quad \curr = \Poseidon_8(\inputs)}$ +$\line{5}{\bi}{\return \curr = \proof\dot\root}$ +``` + +```text +$\overline{\underline{\Function \octtreeproofisvalid(\proof: \ColumnProof) \rightarrow \Bool}\thin}$ +$\line{1}{\bi}{\return \octtreeproofisvalid(\OctTreeProof\ \{\ \leaf, \root, \path \Leftarrow \ColumnProof\ \})}$ +``` + +### Merkle Proof Challenge Validation + +Given a Merkle path `$\path$` in a `$\BinTree$` or `$\OctTree$`, `$\calculatebintreechallenge$` and `$\calculateocttreechallenge$` calculate the Merkle challenge `$c$` for which the Merkle proof `$\path$` was generated. + +Given a Merkle challenge `$c$` and its path in a `$\BinTree$` or `$\OctTree$`, the concatentation of the `$\missing$` bits (or octal digits) in the Merkle path is the little-endian binary (or octal) representation of the integer `$c \thin$`: + +```text +$\line{1}{\bi}{c: \NodeIndex = \langle \text{challenge} \rangle}$ +$\line{2}{\bi}{\BinTreeProof_c = \BinTree\dot\createproof(c)}$ +$\line{3}{\bi}{\OctTreeProof_c = \OctTree\dot\createproof(c)}$ + +$\line{4}{\bi}{\llcorner c \lrcorner_{2, \Le}: \Bit^{[\hspace{1pt} \log_2(N_\nodes) \hspace{1pt}]} = \big\|_{\pathelem \hspace{1pt} \in \hspace{1pt} \BinTreeProof_c\dot\path} \thin \pathelem\dot\missing}$ + +$\line{5}{\bi}{\mathrlap{\llcorner c \lrcorner_{8, \Le}: [8]^{[\hspace{1pt} \log_8(N_\nodes) \hspace{1pt}]}}\hphantom{\llcorner c \lrcorner_{2, \Le}: \Bit^{[\hspace{1pt} \log_2(N_\nodes) \hspace{1pt}]}} = \big\|_{\pathelem \hspace{1pt} \in \hspace{1pt} \BinTreeProof_c\dot\path} \thin \pathelem\dot\missing}$ + +$\line{6}{\bi}{\mathrlap{\llcorner c \lrcorner_{2, \Le}: \Bit^{[\hspace{1pt} \log_2(N_\nodes) \hspace{1pt}]}}\hphantom{\llcorner c \lrcorner_{2, \Le}: \Bit^{[\hspace{1pt} \log_2(N_\nodes) \hspace{1pt}]}} = \big\|_{\pathelem \hspace{1pt} \in \hspace{1pt} \OctTreeProof_c\dot\path} \thin \llcorner \pathelem\dot\missing \lrcorner_{2, \Le}}$ +``` + + +**Implementation:** [`storage_proofs::merkle::MerkleProofTrait::path_index()`](https://github.com/filecoin-project/rust-fil-proofs/blob/f75804c503d9b97a2b02ef3ea2e5d44e8e2c6470/storage-proofs/core/src/merkle/proof.rs#L89) + +**Additional Notation:** + +`$\path = \BinTreeProof\dot\path$`\ +`$\path = \OctTreeProof\dot\path$`\ +The `$\path$` argument is the path field of a `$\BinTreeProof$` or `$\OctTreeProof$`. + +`$c: \NodeIndex$`\ +The challenge corresponding to `$\path$`. + +`$l \in [\BinTreeDepth]$`\ +`$l \in [\OctTreeDepth]$`\ +A path element's layer in a Merkle tree (the layer in the tree that contains the path elements `$\siblings$`). Layer `$l = 0$` is the leaves layer of the tree. Here, values for `$l$` do not include the root layer `$l \neq \BinTreeDepth, \OctTreeDepth \thin$`. + +```text +$\overline{\underline{\Function \calculatebintreechallenge(\path: \BinPathElement^{[\BinTreeDepth]}) \rightarrow c}}$ +$\line{1}{\bi}{\return \sum_{l \in [\BinTreeDepth]}{\path[l]\dot\missing * 2^l}}$ +``` + +```text +$\overline{\underline{\Function \calculateocttreechallenge(\path: \OctPathElement^{[\OctTreeDepth]}) \rightarrow c}}$ +$\line{1}{\bi}{\return \sum_{l \in [\OctTreeDepth]}{\path[l]\dot\missing * 8^l}}$ +``` + +## Stacked Depth Robust Graphs + +Filecoin utilizes the topological properties of depth robust graphs (DRG's) to build a sequential and regeneration resistant encoding scheme. We stack `$N_\layers$` of DRG's, each containing `$N_\nodes$` nodes, on top of one another and connect each adjacent pair of DRG layers via the edges of bipartite expander. The source layer of each expander is the DRG at layer `$l$` and the sink layer is the DRG at layer `$l + 1$`. The resulting graph is termed a Stacked-DRG. + +For every node `$v \in [N_\nodes]$` in the DRG at layer `$l \in [N_\layers]$`, we generate `$d_\drg$` number of DRG parent for `$v$` in layer `$l$`. DRG parents are generated using the [Bucket Sampling algorithm](https://eprint.iacr.org/2017/443.pdf). For every node `$v$` in layers `$l > 0$` we generate `$d_\exp$` number of expander parents for `$v$` where the parents are in layer `$l - 1$`. Expander parents are generated using a psuedorandom permutation (PRP) `$\pi: [N_\nodes] \rightarrow [N_\nodes]$` which maps a node in the DRG layer `$l$` to a node in the the DRG layer `$l - 1$`. The psudeorandom permutation is generated using a `$N_\fesitelrounds$`-round Feistel network whose round function is the keyed hash function `$\Blake$`, where round keys are specified by the constant `$\FeistelKeys$`. + +### DRG + +The function `$\getdrgparents$` are used to generate a node `$v$`'s DRG parents in the Stacked-DRG layer `$l_v \thin$`. The set of DRG parents returned for `$v$` is the same for all PoRep's of the same PoRep version `$\PorepID$`. + +**Implementation:** [`storage_proofs::core::drgraph::BucketGraph::parents()`](https://github.com/filecoin-project/rust-fil-proofs/blob/d15b4307abe384d49ab2ce76b57377204f935cec/storage-proofs/core/src/drgraph.rs#L130) + +**Additional Notation:** + +`$v, u: \NodeIndex$`\ +DRG child and parent node indexes respectively. A DRG child and its parents are in the same Stacked-DRG layer `$l$`. + +`$\mathbf{u}_\drg: \NodeIndex^{[d_\drg]}$`\ +The set of `$v$`'s DRG parents. + +`$v_\meta, u_\meta: [d_\meta * N_\nodes]$`\ +The indexes of `$v$` and `$u$` in the metagraph. + +`$\rng_{\PorepID, v}$`\ +The RNG used to sample `$v$`'s DRG parents. The RNG is seeded with the same bytes `$\DrgSeed_{\PorepID, v}$` every time `$\getdrgparents$` is called for node `$v$` from a PoRep having version `$\PorepID$`. + +`$x \xleftarrow[\rng]{} S$`\ +Samples `$x$` uniformly from `$S$` using the seeded `$\rng$`. + +`$b: [1, N_\buckets + 1]$`\ +The Bucket Sampling bucket index. **Bucket indexes start at 1.** + +`$\dist_{\min, b}$`\ +`$\dist_{\max, b}$`\ +The minimum and maximum parent distances in bucket `$b$`. + +`$\dist_{u_\meta}$`\ +The distance `$u_\meta$` is from `$v_\meta$` in the metagraph. + +```text +$\overline{\underline{\Function \getdrgparents(v: \NodeIndex) \rightarrow \NodeIndex^{[d_\drg]}}}$ +$\line{1}{\bi}{\DrgSeed_{\PorepID, v}: \Byte^{[32]} = \DrgSeed_\PorepID \concat \leencode(v) \as \Byte^{[4]}}$ +$\line{2}{\bi}{\rng_{\PorepID, v} = \ChaCha{8}\cc\fromseed(\DrgSeed_{\PorepID, v})}$ + +$\line{3}{\bi}{\mathbf{u}_\drg: \textsf{NodeIndex}^{[d_\drg]} = [\ ]}$ + +$\line{4}{\bi}{v_\meta = v * d_\textsf{meta}}$ +$\line{5}{\bi}{N_\buckets = \lceil \log_2(v_\meta) \rceil}$ +$\line{6}{\bi}{\for \each \in [d_\meta]:}$ +$\line{7}{\bi}{\quad b \xleftarrow[\rng]{} [1, N_\buckets + 1]}$ +$\line{8}{\bi}{\quad \dist_{\max, b} = \textsf{min}(v_\meta, 2^b)}$ +$\line{9}{\bi}{\quad \dist_{\min, b} = \textsf{max}(d_{\max, b} / 2, 2)}$ +$\line{10}{}{\quad \dist_{u_\meta} \xleftarrow[\rng]{} [\dist_{\min, b} \thin, \dist_{\max, b}]}$ +$\line{11}{}{\quad u_\meta = v_\meta - \dist_{u_\meta}}$ +$\line{12}{}{\quad u: \NodeIndex = \lfloor u_\meta / d_\meta \rfloor}$ +$\line{13}{}{\quad \mathbf{u}_\drg\dot\push(u)}$ + +$\line{14}{}{\mathbf{u}_\drg\dot\push(v - 1)}$ +$\line{15}{}{\return \mathbf{u}_\drg}$ +``` + +### Expander + +The function `$\getexpparents$` is used to generate a node `$v$`'s expander parents in the Stacked-DRG layer `$l_v - 1 \thin$`. The set of expander parents returned for a node `$v$` is the same for all PoRep's of the same version `$\PorepID$`. + +**Implementation:** [`storage_proofs::porep::stacked::vanilla::graph::StackedGraph::generate_expanded_parents()`](https://github.com/filecoin-project/rust-fil-proofs/blob/d15b4307abe384d49ab2ce76b57377204f935cec/storage-proofs/porep/src/stacked/vanilla/graph.rs#L448) + +**Additional Notation:** + +`$v, u: \NodeIndex$`\ +Expander child and parent node indexes respectively. Each expander parent `$u$` is in the Staked-DRG layer `$l - 1$` that precedes the child node `$v$`'s layer `$l$`. + +`$\mathbf{u}_\exp: \NodeIndex^{[d_\exp]}$`\ +The set of `$v$`'s expander parents. + +`$e_l \thin, e_{l - 1}: \ExpEdgeIndex$`\ +The index of an expander edge in the child `$v$`'s layer `$l$` and the parent `$u$`'s layer `$l - 1$` respectively. An expander edge connects edge indexes `$(e_{l - 1}, e_l)$` in adjacent Stacked-DRG layers. + +```text +$\overline{\underline{\Function \getexpparents(v: \NodeIndex) \rightarrow \NodeIndex^{[d_\exp]}}}$ +$\line{1}{\bi}{\mathbf{u}_\exp: \NodeIndex^{[d_\exp]} = [\ ]}$ +$\line{2}{\bi}{\for p\in [d_E]:}$ +$\line{3}{\bi}{\quad e_l = v * d_E + p}$ +$\line{4}{\bi}{\quad e_{l - 1} = \feistel(e_l)}$ +$\line{5}{\bi}{\quad u: \NodeIndex = \lfloor e_{l - 1} / d_\exp \rfloor}$ +$\line{6}{\bi}{\quad \mathbf{u}_\exp\dot\push(u)}$ +$\line{7}{\bi}{\return \mathbf{u}_\exp}$ +``` + +### Feistel Network PRP + +The function `$\feistel$` runs an `$N_\feistelrounds = 4$` round Feistel network as a psuedorandom permutation (PRP) over the set of expander edges `$[d_\exp * N_\nodes] = [2^{33}]$` in a Stacked-DRG layer. + +**Implementation:** [`storage_proofs::core::crypto::feistel::permute()`](https://github.com/filecoin-project/rust-fil-proofs/blob/d15b4307abe384d49ab2ce76b57377204f935cec/storage-proofs/core/src/crypto/feistel.rs#L34) + +**Additional Notation:** + +`$\input, \output$`\ +The Feistel network's input and output blocks respectively. The `$\input$` argument and the returned `$\output$` are guaranteed to be valid `$\u{33}$` expander edge indexes, however their intermediate values may be `$\u{34}$`. + +`$\u{64}_{(17)}$`\ +An unsigned 64-bit integer whose lowest 17 bits are utilized. The integer's 17 least significant bits are used and may be `$0$` or `$1$`, while the integer's 47 most significant bits are `$0$` and are not used. + +`$\left_r, \right_r$`\ +The left and right halves of round `$r$`'s input block. + +`$\left_{r + 1}, \right_{r + 1}$`\ +The left and right halves of the next round's `$r + 1$` input block. + +`$\FeistelKeys_\PorepID$`\ +Is the set of constant round keys associated with the PoRep version `$\PorepID$` that called `$\feistel$`. + +`$\key_r$`\ +Round `$r$`'s key. + +`$\digestright$`\ +The `$\ell_\mask^\bit = 17$` least significant bits of a round's Blake2b `$\digest$`. + +```text +$\overline{\underline{\Function \feistel(\input: \ExpEdgeIndex) \rightarrow \ExpEdgeIndex\ }\thin}$ +$\line{1}{\bi}{\output: \u{64}_{(34)} = \varnothing}$ + +$\line{2}{\bi}{\while \output \notin [N_\expedges]:}$ +$\line{3}{\bi}{\quad \right_r: \u{64}_{(17)} = \input \AND \mathsf{RightMask}}$ +$\line{4}{\bi}{\quad \left_r: \u{64}_{(17)} = (\input \AND \LeftMask) \gg \ell_\mask^\bit}$ + +$\line{5}{\bi}{\quad \for \key_r \in \FeistelKeys_\PorepID:}$ +$\line{6}{\bi}{\quad\quad \preimage: \Byte^{[16]} = \beencode(\right_r) \as \Byte^{[8]} \concat \beencode(\key_r) \as \Byte^{[8]}}$ +$\line{7}{\bi}{\quad\quad \digest: \Byte^{[8]} = \Blake(\preimage)[..8]}$ +$\line{8}{\bi}{\quad\quad \digest: \u{64} = \bedecode(\digest)}$ +$\line{9}{\bi}{\quad\quad \digestright: \u{64}_{(17)} = \digest \AND \RightMask}$ + +$\line{10}{}{\quad\quad \left_{r + 1}: \u{64}_{(17)} = \right_r}$ +$\line{11}{}{\quad\quad \right_{r + 1}: \u{64}_{(17)} = \left_r \xor \digestright}$ + +$\line{12}{}{\quad\quad \left_r, \right_r = \left_{r + 1}, \right_{r + 1}}$ + +$\line{13}{}{\quad \output: \u{64}_{(34)} = (\left_r \ll \ell_\mask^\bit) \OR \right_r}$ +$\line{14}{}{\return \output}$ +``` + +**Code Comments:** +* **Line 1:** Initializes the output of the network to the null value `$\varnothing \thin$`. The value of `$\output$` is a `$34 = 2 * \ell_\mask^\bit$`-bit integer and may not be a valid expander graph edge index after `$N_\feistelrounds$` rounds. +* **Line 2:** The network runs at least once and reruns if `$\output$`'s most significant bit (its 34th bit) is set to `$1$` (`$\output$` is not a valid `$\u{33}$` expander edge index). + +### All Parents + +The function `$\getallparents$` returns a node `$v$`'s set of DRG parents concatenated with its set of expander parents. The set of parents returned for `$v$` is the same across all PoRep's of the same PoRep version `$\PorepID$`. + +```text +$\overline{\underline{\Function \getallparents(v: \NodeIndex) \rightarrow \mathbf{u}_\total}}$ +$\line{1}{\bi}{\return \getdrgparents(v) \concat \getexpparents(v)}$ +``` + +## Labeling + +### Labeling a Node + +The labeling function for every node in a Stacked-DRG is `$\Sha{254}$` producing a 254-bit field element `$\Fqsafe$`. A unique preimage is derived for each node-layer tuple `$(v, l)$` in replica `$\ReplicaID$`'s Stacked-DRG. + +The labeling preimage for the first node `$v_0 = 0$` in every Stacked-DRG layer `$l \in [N_\layers]$` for a replica `$\ReplicaID$` is defined: + +```text +$\bi \preimage_{v_0, l}: \Byte^{[44]} =$ +$\bi\quad\quad \ReplicaID \concat \beencode(l \as \u{32}) \as \Byte^{[4]} \concat \beencode(v_0 \as \u{64}) \as \Byte^{[8]}$ +``` + +The labeling preimage for each node `$v > 0$` in the first layer `$l_0 = 0$` is defined: + +```text +$\bi \preimage_{v, l_0}: \Byte^{[1228]} =$ +$\bi\quad\quad \ReplicaID$ +$\bi\quad\quad \|\ \beencode(l_0 \as \u{32}) \as \Byte^{[4]}$ +$\bi\quad\quad \|\ \beencode(v \as \u{64}) \as \Byte^{[8]}$ +$\bi\quad\quad \big\|_{\Label_{u, l_0} \hspace{1pt} \in \hspace{1pt} \ParentLabels_{\mathbf{u}_\drg}^\star} \Label_{u, l_0} \as \Byte^{[32]} \vphantom{{|^|}^x}$ +``` + +The labeling preimage for each node `$v > 0$` in each layer `$l > 0$` is defined: + +```text +$\bi \preimage_{v, l}: \Byte^{[1228]} =$ +$\bi\quad\quad \ReplicaID$ +$\bi\quad\quad \|\ \beencode(l \as \u{32}) \as \Byte^{[4]}$ +$\bi\quad\quad \|\ \beencode(v \as \u{64}) \as \Byte^{[8]}$ +$\bi\quad\quad \big\|_{\Label_u \hspace{1pt} \in \hspace{1pt} \ParentLabels_{\mathbf{u}_\total}^\star} \Label_u \as \Byte^{[32]} \vphantom{{|^|}^x}$ +``` + +### The Labels Matrix + +The function `$\textsf{generate\_labels}$` describes how every Stacked-DRG node is labeled for a replica. Nodes in the first layer `$l_0 = 0$` are labeled using only DRG parents' labels, nodes in every subsequent layers `$l > 0$` are labeled using both their DRG and expander parents' labels. The first node `$v_0$` in every layer is not labeled using parents. + +**Additional Notation:** + +`$\Labels_R$`\ +Denotes that `$\Labels$` is the labeling for a single replica `$R$`. + +`$l_0 = 0$`\ +The constant `$l_0$` is used to signify the first Stacked-DRG layer. + +`$l_v$`\ +The Stacked-DRG layer in which a node `$v$` resides. + +`$\Label_{v, l_v}$`\ +The label of node `$v$` in the Stacked-DRG layer `$l_v$`. + +`$u_{\langle \drg | \exp \rangle}$`\ +Denotes that parent `$u$` may be a DRG or expander parent. + +`$\Label_{u_\drg}$`\ +The label of a DRG parent (in `$v$`'s layer `$l$`). + +`$\Label_u \equiv \or{\Label_{u_\drg, l_v}}{\Label_{u_\exp, l_v - 1}}$`\ +The label of either a DRG or expander parent (in layer `$l$` or `$l - 1$` respectively). + +```text +$\overline{\underline{\Function \generatelabels(\ReplicaID) \rightarrow \Labels_R}}$ +$\line{1}{\bi}{\Labels: {\Label^{[N_\nodes]}}^{[N_\layers]} += [\ ]}$ + +$\line{2}{\bi}{\for v \in [N_\nodes]:}$ +$\line{3}{\bi}{\quad \Labels[l_0][v] = \labelwithdrgparents(\ReplicaID, v, \Labels[l_0][..v])}$ + +$\line{4}{\bi}{\for l \in [1, N_\layers - 1]:}$ +$\line{5}{\bi}{\quad \for v \in [N_\mathsf{nodes}]:}$ +$\line{6}{\bi}{\quad\quad \Labels[l][v] = \labelwithallparents(\ReplicaID, l, v, \Labels[l][..v], \Labels[l - 1])}$ + +$\line{7}{\bi}{\return \Labels}$ +``` + +**Code Comments:** +* **Lines 2-3:** Label the first Stacked-DRG layer. +* **Lines 4-6:** Label the remaining Stacked-DRG layers. + +The function `$\labelwithdrgparents$` is used to label a node `$v$` in the first Stacked-DRG layer `$l_0 = 0 \thin$`. + +The label of each node `$v$` in `$l_0$` is dependent on the labels of `$v$`'s DRG parents (where `$v$`'s DRG parents are in layer `$l_v = l_0 \thin$`. `$v$`'s DRG parents always come from the node range `$[v]$` in layer `$l_v$`, thus we pass in the argument `$\Labels[l_0][..v]$` which contains the label of every node up to `$v$` in `$l_0 \thin$`. `$\Labels[l_0][..v]$` is guaranteed to be labeled up to node `$v$` because `$\labelwithdrgparents$` is called sequentially for each node `$v \in [N_\nodes] \thin$`. + +```text +$\overline{\underline{\Function \labelwithdrgparents(\ReplicaID, v: \NodeIndex, \Labels[l_0][..v]) \rightarrow \Label_{v, l_0}}}$ +$\line{1}{\bi}{\preimage: \Byte^{[*]} =}$ +$\quad\quad \ReplicaID \concat \beencode(l_0 \as \u{32}) \as \Byte^{[4]} \concat \beencode(v \as \u{64}) \as \Byte^{[8]}$ + +$\line{2}{\bi}{\if v > 0:}$ +$\line{3}{\bi}{\quad \mathbf{u}_\drg: \textsf{NodeIndex}^{[d_\drg]} = \getdrgparents(v)}$ +$\line{4}{\bi}{\quad \for i \in [N_\parentlabels]:}$ +$\line{5}{\bi}{\quad\quad u_\drg = \mathbf{u}_\drg[i \MOD d_\drg]}$ +$\line{6}{\bi}{\quad\quad \Label_{u_\drg, l_0}: \Fqsafe = \Labels[l_0][u_\drg]}$ +$\line{7}{\bi}{\quad\quad \preimage\dot\extend(\leencode(\Label_{u_\drg, l_0}) \as \Safe)}$ + +$\line{8}{\bi}{\return \Sha{254}(\preimage) \as \Fqsafe}$ +``` + +The function `$\labelwithallparents$` is used to label a node `$v$` in all layers other than the first Stacked-DRG layer `$l_v > 0 \thin$`. + +The label of a node `$v$` in layers `$l_v > 0$` is dependent on both the labels of `$v$`'s DRG and expander parents. `$\labelwithallparents$` takes the argument `$\Labels[l_v][..v]$` (the current layer `$l_v$` being labeled, contains labels up to node `$v$`) to retrieve the labels of `$v$`'s DRG parents and the argument `$\Labels[l_v - 1]$` (the previous layer's labels) to retrieve the labels of `$v$`'s expander parents. + +```text +$\overline{\Function \labelwithallparents(\bi}$ +$\quad \ReplicaID,$ +$\quad l_v \in [1, N_\layers - 1],$ +$\quad v: \NodeIndex,$ +$\quad \Labels[l_v][..v],$ +$\quad \Labels[l_v - 1],$ +$\underline{) \rightarrow \Label_{v, l_v} \qquad\qquad\qquad\qquad\qquad\bi}$ +$\line{1}{\bi}{\preimage: \Byte^{[*]} =}$ +$\quad\quad \ReplicaID \concat \beencode(l_v \as \u{32}) \as \Byte^{[4]} \concat \beencode(v \as \u{64}) \as \Byte^{[8]}$ + +$\line{2}{\bi}{\if v > 0:}$ +$\line{3}{\bi}{\quad \mathbf{u}_\total: \textsf{NodeIndex}^{[d_\total]} = \getallparents(v)}$ +$\line{4}{\bi}{\quad \for i \in [N_\parentlabels]:}$ +$\line{5}{\bi}{\quad\quad p = i \MOD d_\total}$ +$\line{6}{\bi}{\quad\quad u_{\langle \drg | \exp \rangle} = \mathbf{u}_\total[p]}$ +$\line{7}{\bi}{\quad\quad \Label_u: \Fqsafe = \if p < d_\drg}:$ +$\quad\quad\quad\quad \Labels[l_v][u_\drg]$ +$\quad\quad\quad \else:$ +$\quad\quad\quad\quad \Labels[l_v - 1][u_\exp]$ +$\line{8}{\bi}{\quad\quad \preimage\dot\extend(\leencode(\Label_u) \as \Safe)}$ + +$\line{9}{\bi}{\return \Sha{254}(\preimage) \as \Fqsafe}$ +``` + +## Column Commitments + +The column commitment process is used commit to a replica's labeling `$\Labels$`. The column commitment `$\CommC$` is generated by building an `$\TreeC: \OctTree$` over the labeling matrix `$\Labels$` and taking the tree's root. + +To build a tree over the matrix `$\Labels$` we hash each of its `$N_\nodes$` number of columns (where each column contains `$N_\layers$` number of `$\Label$`'s) using the hash function `$\Poseidon_{11}$` producing `$N_\nodes$` number of column digests. The `$i^{th}$` column digest is the `$i^{th}$` leaf in `$\TreeC$`. + +```text +$\overline{\underline{\Function \createtreecfromlabels(\Labels) \rightarrow \TreeC}}$ +$\line{1}{\bi}{\leaves: {\Fq}^{[N_\nodes]} = [\ ]}$ +$\line{2}{\bi}{\for v \in [N_\nodes]:}$ +$\line{3}{\bi}{\quad \column_v: \Fqsafe^{[N_\layers]} = \Labels[:][v]}$ +$\line{4}{\bi}{\quad \digest: \Fq = \Poseidon_{11}(\column_v)}$ +$\line{5}{\bi}{\quad \leaves\dot\push(\digest)}$ +$\line{6}{\bi}{\return \OctTree\cc\new(\leaves)}$ +``` + +## Encoding + +Encoding is the process by which a sector `$D: \Safe^{[N_\nodes]}$` is transformed into its encoding `$R: \Fqsafe^{[N_\nodes]}$`. The encoding function is *node-wise* prime field addition `$\oplus$`, where "node-wise" means that every distinct `$\Safe$` slice `$D_i \in D$` is discretely encoded. + +`$D$` is viewed as an array of `$N_\nodes$` distinct byte arrays `$D_i: \Safe$`. Sector preprocessing ensures that each `$D_i$` is a valid `$\Safe$` (represents a valid 254-bit or less field element `$\Fqsafe)$`. + +```text +$\bi D: \Safe^{[N_\nodes]} = [D_0, \ldots, D_{N_\nodes - 1}]$ +$\bi D_i: \Safe = D[i * 32 \thin\ldotdot\thin (i + 1) * 32]$ +``` + +A unique encoding key `$K$` is derived for every distinct `$\ReplicaID$` via the PoRep labeling process producing `$\Labels$`. Each `$D_i \in D$` is encoded by a distinct encoding key `$K_i \in K$`, where `$K_i$` is `$i^{th}$` node's label in the last Stacked-DRG layer. + +```text +$\bi K: \Label^{[N_\nodes]} = \Labels[N_\layers - 1][:]$ +$\bi K_i: \Label_{i, l_\last} = \Labels[N_\layers - 1][i]$ +``` + +`$D$` is encoded into `$R$` via *node-wise* field addition. Each `$D_i \in D$` is interpreted as a field element and encoded into `$R_i$` by adding `$K_i$` to `$D_i$`. The resulting array of field elements produced via field addition is the encoding `$R$` of `$D$`. + +```text +$\bi R: \Fq^{[N_\nodes]} = [R_0, \ldots, R_{N_\nodes - 1}]$ +$\bi R_i: \Fq = D_i \as \Fqsafe \oplus K_i$ +``` + +The function `$\encode$` is used to encode a sector `$D$` into `$R$` given a an encoding key `$K$` derived from `$R$`'s `$\ReplicaID$`. + +```text +$\overline{\underline{\Function \encode(D: \Safe, K: \Label^{[N_\nodes]}) \rightarrow R}}$ +$\line{1}{\bi}{R: \Fq^{[N_\nodes]} = [\ ]}$ +$\line{2}{\bi}{\for i \in [N_\nodes]:}$ +$\line{3}{\bi}{\quad D_i: \Safe = D[i]}$ +$\line{4}{\bi}{\quad K_i: \Label = K[i]}$ +$\line{5}{\bi}{\quad R_i = D_i \as \Fqsafe \oplus K_i}$ +$\line{6}{\bi}{\quad R\dot\push(R_i)}$ +$\line{7}{\bi}{\return R}$ +``` + +## Replication + +Replication is the entire process by which a sector `$D$` is uniquely encoded into a replica `$R$`. Replication encompasses Stacked-DRG labeling, encoding `$D$` into `$R$`, and the generation of trees `$\TreeC$` over `$\Labels$` and `$\TreeR$` over `$R$`. + +A miner derives a unique `$\ReplicaID$` for each `$R$` using the commitment to the replica's sector `$\CommD = \TreeD\dot\root \thin$` (where `$\TreeD$` is build over the nodes of the unencoded sector `$D$` associated with `$R \thin$`). + +Given a sector `$D$` and its commitment `$\CommD$`, replication proceeds as follows: + +1. Generate the `$R$`'s unique `$\ReplicaID$`. +2. Generate `$\Labels$` from `$\ReplicaID$`, thus deriving the key `$K$` that encodes `$D$` into `$R$`. +3. Generate `$\TreeC$` over the columns of `$\Labels$` via the column commitment process. +4. Encode `$D$` into `$R$` using the encoding key `$K$`. +5. Generate a `$\TreeR: \OctTree$` over the replica `$R$`. +6. Commit to `$R$` and its associated labeling `$\Labels$` via the commitment `$\CommCR$`. + +The function `$\replicate$` runs the entire replication process for a sector `$D$`. + +```text +$\overline{\Function \replicate( \qquad\qquad\qquad\qquad\qquad\quad\bi\ }$ +$\quad D: \Safe^{[N_\nodes]},$ +$\quad \CommD: \Safe,$ +$\quad \SectorID_D: \u{64},$ +$\quad \R_\replicaid: \Byte^{[32]},$ +$\underline{) \rightarrow \ReplicaID, R, \TreeC, \TreeR, \CommCR, \Labels}$ +$\line{1}{\bi}{\ReplicaID = \createreplicaid(\ProverID, \SectorID, \R_\replicaid, \CommD, \PorepID)}$ +$\line{2}{\bi}{\Labels = \generatelabels(\ReplicaID)}$ +$\line{3}{\bi}{\TreeC = \createtreecfromlabels(\Labels)}$ +$\line{4}{\bi}{K: \Label^{[N_\nodes]} = \Labels[N_\layers - 1][:]}$ +$\line{5}{\bi}{R: \Fq^{[N_\nodes]} = \textsf{encode}(D, K)}$ +$\line{6}{\bi}{\TreeR = \OctTree\cc\new(R)}$ +$\line{7}{\bi}{\CommCR: \Fq = \Poseidon_2([\TreeC\dot\root, \TreeR\dot\root])}$ +$\line{8}{\bi}{\return \ReplicaID, R, \TreeC, \TreeR, \CommCR, \Labels}$ +``` + +## ReplicaID Generation + +The function `$\createreplicaid$` describes how a miner having the ID `$\ProverID$` is able to generate a `$\ReplicaID$` for a replica `$R$` of sector `$D$`, where `$D$` has a unique ID `$\SectorID$` and commitment `$\CommD$`. The prover uses a unique random value `$\R_\ReplicaID$` for each `$\ReplicaID$` generated. + +**Implementation:** [`storage_proofs::porep::stacked::vanilla::params::generate_replica_id()`](https://github.com/filecoin-project/rust-fil-proofs/blob/b40b34b5ef7e2a7b8c7e7ea9e574d900728dac45/storage-proofs/porep/src/stacked/vanilla/params.rs#L736) + +```text +$\overline{\Function \createreplicaid(\ }$ +$\quad \ProverID: \Byte^{[32]},$ +$\quad \SectorID: \u{64},$ +$\quad \R_\replicaid: \Byte^{[32]},$ +$\quad \CommD: \Safe,$ +$\quad \PorepID: \Byte^{[32]},$ +$\underline{) \rightarrow \ReplicaID \qquad\qquad\qquad\bi\ }$ +$\line{1}{}{\preimage: \Byte^{[136]} =}$ +$\quad\quad \ProverID$ +$\quad\quad \|\ \beencode(\SectorID) \as \Byte^{[8]}$ +$\quad\quad \|\ \R_\ReplicaID$ +$\quad\quad \|\ \CommD$ +$\quad\quad \|\ \PorepID$ + +$\line{2}{}{\return \Sha{254}(\preimage) \as \Fqsafe}$ +``` + +## Sector Construction + +A sector `$D$` is constructed from Filecoin client data where the aggregating of client data of has been preprocessed/bit-padded such that two zero bits are placed between each distinct 254-bit slice of client data. This padding process results in a sector `$D$` such that every 256-bit slice represents a valid 254-bit field element `$\Safe \thin$`. + +A Merkle tree `$\TreeD: \BinTree$` is constructed for sector `$D$` whose leaves are the 256-bit slices `$D_i: \Safe \in D \thin$`. + +```text +$\bi D_i: \Safe = D[i * 32 \thin\ldotdot\thin (i + 1) * 32]$ +$\bi \TreeD = \BinTree\cc\new([D_0, \ldots, D_{N_\nodes - 1}])$ +$\bi \CommD: \Safe = \TreeD\dot\root$ +``` + +Each `$\TreeD$` is constructed over the preprocessed sector data `$D$`. + +## PoRep Challenges + +The function `$\getporepchallenges$` creates the PoRep challenge set for a replica `$R$`'s partition-`$k$` PoRep partition proof. + +**Implementation:** [`storage_proofs::porep::stacked::vanilla::challenges::LayerChallenges::derive_internal()`](https://github.com/filecoin-project/rust-fil-proofs/blob/c58918b9b2f749a5db40a7952d29a6501c765e13/storage-proofs/porep/src/stacked/vanilla/challenges.rs#L40) + +```text +$\overline{\Function\ \getporepchallenges( \quad}$ +$\quad \ReplicaID,$ +$\quad \R_\porepchallenges: \Byte^{[32]},$ +$\quad k: [N_\poreppartitions],$ +$\underline{) \rightarrow \PorepChallenges_{R, k} \qquad\qquad\qquad}$ +$\line{1}{\bi}{\challenges: \NodeIndex^{[N_{\porepchallenges / k}]} = [\ ]}$ +$\line{2}{\bi}{\for \challengeindex \in [N_\porepchallenges]:}$ +$\line{3}{\bi}{\quad \challengeindex_\porepbatch: \u{32} = k * N_{\porepchallenges / k} + \challengeindex}$ +$\line{4}{\bi}{\quad \preimage: \Byte^{[68]} =}$ +$\quad\quad\quad \leencode(\ReplicaID) \as \Byte^{[32]}$ +$\quad\quad\quad \|\ \R_\porepchallenges$ +$\quad\quad\quad \|\ \leencode(\challengeindex_\porepbatch) \as \Byte^{[4]}$ +$\line{5}{\bi}{\quad \digest: \Byte^{[32]} = \Sha{256}(\preimage)}$ +$\line{6}{\bi}{\quad \digestint: \u{256} = \ledecode(\digest)}$ +$\line{7}{\bi}{\quad c: \NodeIndex \setminus 0 = (\digestint \MOD (N_\nodes - 1)) + 1}$ +$\line{8}{\bi}{\quad \challenges\dot\push(c)}$ +$\line{9}{\bi}{\return \challenges}$ +``` + +## Vanilla PoRep + +### Proving + +A PoRep prover generates a `$\PorepPartitionProof_k$` for each partition `$k$` in a replica `$R$`'s batch of PoRep proofs. Each partition proof is generated for `$N_{\porepchallenges / k}$` number of challenges, the challenge set `$\PorepChallenges_{R, k}$` (each partition proof's challenge set is specific to the replica `$R$` and partition `$k$`). + +A single partition proof generated by a PoRep prover shows that: + +* The prover knows a valid Merkle path for `$c$` in `$\TreeD$` that is consistent with the public `$\CommD$`. +* The prover knows valid Merkle paths for `$c$` in trees `$\TreeC$` and `$\TreeR$` which are consistent with the committed to `$\CommCR$`. +* The prover knows `$c$`'s labeling in each Stacked-DRG layer `$\Column_c = \ColumnProof_c\dot\column \thin$` by hashing `$\Column_c$` into a leaf in `$\TreeC$` that is consistent with `$\CommCR$`. +* For each layer `$l$` in the Stacked-DRG, the prover knows `$c$`'s labeling preimage `$\ParentLabels$` (taken from the columns in `$\ParentColumnProofs$`), such that the parent labels are consistent with `$\CommCR$`. +* The prover knows the key `$K_c$` used to encode `$D_c$` into `$R_c$` (where `$D_c$`, `$K_c$`, and `$R_c$` were already shown to be consistent with the commitments `$\CommD$` and `$\CommCR$`). + +```text +$\overline{\mathbf{Function:}\ \createvanillaporepproof(\ }$ +$\quad k,$ +$\quad \ReplicaID,$ +$\quad \TreeD,$ +$\quad \TreeC,$ +$\quad \TreeR,$ +$\quad \Labels,$ +$\quad \R_\porepchallenges: \Byte^{[32]},$ +$\underline{) \rightarrow \PorepPartitionProof_{R, k} \qquad\qquad\qquad}$ +$\line{1}{\bi}{\PorepPartitionProof_{R, k}: \PorepChallengeProof^{\thin[N_\porepchallenges]} = [\ ]}$ +$\line{2}{\bi}{\PorepChallenges_{R, k} = \getporepchallenges(\ReplicaID, \R_\porepchallenges, k)}$ + +$\line{3}{\bi}{\for c \in \PorepChallenges_{R, k}:}$ +$\line{4}{\bi}{\quad \TreeDProof_c = \TreeD\dot\createproof(c)}$ + +$\line{5}{\bi}{\quad \ColumnProof_c\ \{}$ +$\quad\quad\quad \column: \Labels[:][c],$ +$\quad\quad\quad \leaf,\thin \root,\thin \path \Leftarrow \TreeC\dot\createproof(c),$ +$\quad\quad \}$ + +$\line{6}{\bi}{\quad \TreeRProof_c = \TreeR\dot\createproof(c)}$ + +$\line{7}{\bi}{\quad \ParentColumnProofs_{\mathbf{u}_\total}: \ColumnProof^{[d_\total]} = [\ ]}$ +$\line{8}{\bi}{\quad \mathbf{u}_\total: \NodeIndex^{[d_\total]} = \getallparents(c, \PorepID)}$ +$\line{9}{\bi}{\quad \for u \in \mathbf{u}_\total:}$ +$\line{10}{}{\quad\quad \ColumnProof_u\ \{}$ +$\quad\quad\quad\quad \column: \Labels[:][u],$ +$\quad\quad\quad\quad \leaf,\thin \root,\thin \path \Leftarrow \TreeC\dot\createproof(u),$ +$\quad\quad\quad \}$ +$\line{11}{}{\quad\quad \ParentColumnProofs_{\mathbf{u}_\total}\dot\push(\ColumnProof_u)}$ + +$\line{12}{}{\quad \PorepChallengeProof_c\ \{}$ +$\quad\quad\quad\quad \TreeDProof_c,$ +$\quad\quad\quad\quad \ColumnProof_c,$ +$\quad\quad\quad\quad \TreeRProof_c,$ +$\quad\quad\quad\quad \ParentColumnProofs_{\mathbf{u}_\total},$ +$\quad\quad \}$ +$\line{13}{}{\quad \PorepPartitionProof_{R, k}\dot\push(\PorepChallengeProof_c)}$ +$\line{14}{}{\return \PorepPartitionProof_{R, k}}$ +``` + +### Verification + +**Implementation:** +* [`storage_proofs::porep::stacked::vanilla::proof_scheme::StackedDrg::verify_all_partitions()`](https://github.com/filecoin-project/rust-fil-proofs/blob/c58918b9b2f749a5db40a7952d29a6501c765e13/storage-proofs/porep/src/stacked/vanilla/proof_scheme.rs#L82) +* [`storage_proofs::porep::stacked::vanilla::params::Proof::verify()`](https://github.com/filecoin-project/rust-fil-proofs/blob/447a8ba76da224b8b5f9b7b8dd624ba9a6a107a6/storage-proofs/porep/src/stacked/vanilla/params.rs#L191) + +```text +$\overline{\Function\ \verifyvanillaporepproof(}$ +$\quad \PorepPartitionProof_{R, k} \thin,$ +$\quad k: [N_\poreppartitions],$ +$\quad \ReplicaID,$ +$\quad \CommD,$ +$\quad \CommCR,$ +$\quad \R_\porepchallenges: \Byte^{[32]},$ +$\underline{) \qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad}$ +$\line{1}{\bi}{\PorepChallenges_{R, k} = \getporepchallenges(\ReplicaID, \R_\porepchallenges, k)}$ + +$\line{2}{\bi}{\for i \in [N_{\porepchallenges / k}]}:$ +$\line{3}{\bi}{\quad c = \PorepChallenges_{R, k}[i]}$ +$\line{4}{\bi}{\quad \TreeDProof_c, \ColumnProof_c, \TreeRProof_c, \ParentColumnProofs_{\mathbf{u}_\total}}$ +$\quad\quad\quad \Leftarrow \PorepPartitionProof_{R, k}[i]$ + +$\line{5}{\bi}{\quad \assert(\TreeDProof_c\dot\root = \CommD)}$ + +$\line{6}{\bi}{\quad \CommCR^\dagger = \Poseidon_2([\ColumnProof_c\dot\root, \TreeRProof_c\dot\root])}$ +$\line{7}{\bi}{\quad \assert(\CommCR^\dagger = \CommCR)}$ + +$\line{8}{\bi}{\quad \assert(\calculatebintreechallenge(\TreeDProof_c\dot\path) = c)}$ +$\line{9}{\bi}{\quad \assert(\calculateocttreechallenge(\ColumnProof_c) = c)}$ +$\line{10}{}{\quad \assert(\calculateocttreechallenge(\TreeRProof_c) = c)}$ + +$\line{11}{}{\quad \assert(\bintreeproofisvalid(\TreeDProof_c))}$ +$\line{12}{}{\quad \assert(\octtreeproofisvalid(\ColumnProof_c))}$ +$\line{13}{}{\quad \assert(\octtreeproofisvalid(\TreeRProof_c))}$ + +$\line{14}{}{\quad \assert(\ColumnProof_c.\leaf = \Poseidon_{11}(\ColumnProof_c.\column))}$ + +$\line{15}{}{\quad \mathbf{u}_\total: \NodeIndex^{[d_\total]} = \getallparents(c, \PorepID)}$ +$\line{16}{}{\quad \for p \in [d_\total]:}$ +$\line{17}{}{\quad\quad u = \mathbf{u}_\total[p]}$ +$\line{18}{}{\quad\quad \ColumnProof_u = \ParentColumnProofs_{\mathbf{u}_\total}[p]}$ +$\line{19}{}{\quad\quad \assert(\ColumnProof_u.\root = \ColumnProof_c.\root)}$ +$\line{20}{}{\quad\quad \assert(\calculateocttreechallenge(\ColumnProof_u\dot\path) = u)}$ +$\line{21}{}{\quad\quad \assert(\octtreeproofisvalid(\ColumnProof_u))}$ +$\line{22}{}{\quad\quad \assert(\ColumnProof_u.\leaf = \Poseidon_{11}(\ColumnProof_u.\column))}$ + +$\line{23}{}{\quad \for l \in [N_\layers]:}$ +$\line{24}{}{\quad\quad \calculatedlabel_{c, l} = \createlabel_\V(\ReplicaID, l, c, \ParentColumnProofs_{\mathbf{u}_\total})}$ +$\line{25}{}{\quad\quad \assert(\calculatedlabel_{c, l} = \ColumnProof_c.\column[l])}$ + +$\line{26}{}{\quad D_c = \TreeDProof.\leaf}$ +$\line{27}{}{\quad {R_c}^\dagger = \TreeRProof.\leaf}$ +$\line{28}{}{\quad {K_c}^\dagger = \ColumnProof_c.\column[N_\layers - 1]}$ +$\line{29}{}{\quad \assert({R_c}^\dagger \ominus {K_c}^\dagger = D_c)}$ +``` + +#### Verifier Labeling + +**Implementation:** [`storage_proofs::porep::stacked::vanilla::labeling_proof::LabelingProof::create_label()`](https://github.com/filecoin-project/rust-fil-proofs/blob/447a8ba76da224b8b5f9b7b8dd624ba9a6a107a6/storage-proofs/porep/src/stacked/vanilla/labeling_proof.rs#L27) + +**Additional Notation:** + +`$\createlabel_\V$`\ +Designates the function `$\createlabel$` as being used by a PoRep verifier `$\V$`. + +`$c: \NodeIndex \setminus 0$`\ +The node index of a PoRep challenge. The first node 0 is never challenged in PoRep proofs. + +`$d = \big[ \tern{l_c = 0}{d_\drg}{d_\total \big]}$`\ +The number of parents that challenge `$c$` has (where `$c$` is in the layer `$l_c$`). + +`$\Label_{c, l}^\dagger: \Fqsafe$`\ +The label of the challenge node `$c$` in layer `$l$` calculated from the unverified `$\ParentColumnProofs^\dagger$`. + +`$\Label_{u_\exp, l - 1}: \Fqsafe$`\ +The label of challenge `$c$`'s expander parent `$u_\exp$` in layer `$l - 1$`. Expander parents come from the layer prior to `$c$`'s layer `$l$`. + +`$p_\drg \in [d_\drg]$`\ +$p_\total \in [d_\total]$ +The index of a parent in `$c$`'s parent arrays `$\mathbf{u}_\drg$` and `$\mathbf{u}_\total$` respectively. + +`$u_\drg, u_\exp: \NodeIndex$`\ +The node index of a DRG or expander graph parent for `$c$`. + +`$\parentlabels': \Label^{[N_\parentlabels]}$`\ +The set of parent labels repeated until its length is `$N_\parentlabels$`. + + +```text +$\overline{\Function: \createlabel_\V( \qquad\ }$ +$\quad \ReplicaID,$ +$\quad l: [N_\layers],$ +$\quad c: \NodeIndex \setminus 0,$ +$\quad \ParentColumnProofs_{\mathbf{u}_\total}^\dagger,$ +$\underline{) \rightarrow \Label_{c, l}^\dagger \qquad\qquad\qquad\qquad\quad}$ +$\line{1}{\bi}{\parentlabels: {\Label_u}^{[d]} = [\ ]}$ + +$\line{2}{\bi}{\for p_\drg \in [d_\drg]:}$ +$\line{3}{\bi}{\quad\quad \Label_{u_\drg, l} = \ParentColumnProofs_{\mathbf{u}_\total}[p_\drg]\dot\column[l]}$ +$\line{4}{\bi}{\quad\quad \parentlabels\dot\push(\Label_{u_\drg, l})}$ + +$\line{5}{\bi}{\if l > 0:}$ +$\line{6}{\bi}{\quad \for p_\exp \in [d_\drg, d_\total - 1]:}$ +$\line{7}{\bi}{\quad\quad \Label_{u_\exp, l - 1} = \ParentColumnProofs_{\mathbf{u}_\total}[p_\exp]\dot\column[l - 1]}$ +$\line{8}{\bi}{\quad\quad \parentlabels\dot\push(\Label_{u_\exp, l - 1})}$ + +$\line{9}{\bi}{\parentlabels': \Label^{[N_\parentlabels]} = \parentlabels\dot\repeattolength(N_\parentlabels)}$ + +$\line{10}{}{\preimage: \Byte^{[1228]} =}$ +$\quad\quad \ReplicaID$ +$\quad\quad \|\ \beencode(l \as \u{32}) \as \Byte^{[4]}$ +$\quad\quad \|\ \beencode(c \as \u{64}) \as \Byte^{[8]}$ +$\quad\quad \big\|_{\Label_u \hspace{1pt} \in \hspace{1pt} \parentlabels'} \thin \Label_u \as \Byte^{[32]}$ + +$\line{11}{}{\return \Sha{254}(\preimage) \as \Fq}$ +``` + +## PoRep Circuit + +**Implementation:** +* [`storage_proofs::porep::stacked::circuit::proof::StackedCircuit::synthesize()`](https://github.com/filecoin-project/rust-fil-proofs/blob/master/storage-proofs/porep/src/stacked/circuit/proof.rs#L77) +* [`storage_proofs::porep::stacked::circuit::params::Proof::synthesize()`](https://github.com/filecoin-project/rust-fil-proofs/blob/master/storage-proofs/porep/src/stacked/circuit/params.rs#L77) + +**Additional Notation:** + +`$\PorepPartitionProof_{R, k}$`\ +The `$k^{th}$` PoRep partition proof generated for the replica `$R$`. + +`$\treedleaf_{\auxb, c}$`\ +The circuit value for a challenge `$c$`'s leaf in `$\TreeD$`. + +`$\calculatedcommd_{\auxb, c}$`\ +The circuit value calculated for `$\CommD$` using challenge `$c$`'s `$\TreeDProof_c$`. + +`$\column_{[\auxb], u}$`\ +The array circuit values representing a parent `$u$` of challenge `$c$`'s label in each Stacked-DRG layer. + +`$\parentcolumns_{[[\auxb]], \mathbf{u}_\total}$`\ +An array of an array of circuit values, the allocated column for each parent `$u \in \mathbf{u}_\total \thin$`. + +`$l_c$`\ +The challenge `$c$`'s layer in the Stacked-DRG. + +`$\parentlabelsbits_{[[\auxb + \constb, \lebytes]]}$`\ +An array where each element is a parent `$u$`'s label, an array of allocated and unallocated bits `$_{[\auxb + \constb]}$` having `$\lebytes$` bit order. + +`$\calculatedlabel_{\auxb, c, l}$`\ +The label calculated for challenge `$c$` in residing in layer `$l$`. + +```text +$\overline{\Function \createporepcircuit(}$ +$\quad \PorepPartitionProof_{R, k} \thin,$ +$\quad k,$ +$\quad \ReplicaID,$ +$\quad \CommD,$ +$\quad \CommC,$ +$\quad \CommR,$ +$\quad \CommCR,$ +$\quad \R_\porepchallenges: \Byte^{[32]},$ +$\underline{) \rightarrow \RCS \qquad\qquad\qquad\qquad\qquad}$ +$\line{1}{\bi}{\cs = \RCS\cc\new()}$ + +$\line{2}{\bi}{\replicaid_\pubb: \CircuitVal \deq \cs\dot\publicinput(\ReplicaID)}$ +$\line{3}{\bi}{\replicaidbits_{[\auxb, \Le]}: \CircuitBit^{[255]}\ \deq \lebitsgadget(\cs, \replicaid_\pubb, 255)}$ +$\line{4}{\bi}{\replicaidbits_{[\auxb+\constb, \lebytes]}: \CircuitBitOrConst^{[256]} =}$ +$\quad\quad \lebitstolebytes(\replicaidbits_{[\auxb, \Le]})$ + +$\line{5}{\bi}{\commd_\pubb: \CircuitVal \deq \cs\dot\publicinput(\CommD)}$ +$\line{6}{\bi}{\commcr_\pubb: \CircuitVal \deq \cs\dot\publicinput(\CommCR)}$ + +$\line{7}{\bi}{\commc_\auxb: \CircuitVal \deq \cs\dot\privateinput(\CommC)}$ +$\line{8}{\bi}{\commr_\auxb: \CircuitVal \deq \cs\dot\privateinput(\CommR)}$ + +$\line{9}{\bi}{\calculatedcommcr_\auxb: \CircuitVal\ \deq}$ +$\quad\quad \poseidongadget{2}(\cs, [\commc_\auxb, \thin \commr_\auxb])$ +$\line{10}{}{\cs\dot\assert(\calculatedcommcr_\auxb = \commcr_\pubb)}$ + +$\line{11}{}{\PorepChallenges_k = \getporepchallenges(\ReplicaID, \R_\porepchallenges, k)}$ + +$\line{12}{}{\for i \in [N_\porepchallenges]}:$ +$\line{13}{}{\quad c: \NodeIndex = \PorepChallenges[i]}$ +$\line{14}{}{\quad \TreeDProof_c, \ColumnProof_c, \TreeRProof_c, \ParentColumnProofs_{\mathbf{u}_\total}}$ +$\quad\quad\quad \Leftarrow \PorepPartitionProof[i]$ + +$\line{15}{}{\quad \challengebits_{[\auxb, \Le]}: \CircuitBit^{[64]} \deq \lebitsgadget(\cs, c, 64)}$ +$\line{16}{}{\quad \packedchallenge_\pubb: \CircuitVal\ \deq}$ +$\quad\quad\quad \packbitsasinputgadget(\cs, \challengebits_{[\auxb, \Le]})$ + +$\line{17}{}{\quad \treedleaf_{\auxb, c} \deq \cs\dot\privateinput(\TreeDProof_c\dot\leaf)}$ +$\line{18}{}{\quad \calculatedcommd_{\auxb, c}\ \deq}$ +$\quad\quad\quad \bintreerootgadget(\cs, \treedleaf_{\auxb, c}\thin, \TreeDProof_c\dot\path)$ +$\line{19}{}{\quad \cs\dot\assert(\calculatedcommd_{\auxb, c} = \commd_\pubb)}$ + +$\line{20}{}{\quad \parentcolumns_{[[\auxb]], \mathbf{u}_\total}: {\CircuitVal^{[N_\layers]}}^{[d_\total]} = [\ ]}$ +$\line{21}{}{\quad \for \ColumnProof_u \in \ParentColumnProofs_{\mathbf{u}_\total}:}$ +$\line{22}{}{\quad\quad \column_{[\auxb], u}: \CircuitVal^{[N_\layers]}\ \deq}$ +$\quad\quad\quad\quad [\thin \cs\dot\privateinput(\label_{u, l}) \mid \forall\thin \label_{u, l} \in \ColumnProof_u\dot\column \thin]$ +$\line{23}{}{\quad\quad \calculatedtreecleaf_{\auxb, u}: \CircuitVal \deq \poseidongadget{11}(\cs, \column_{[\auxb], u})}$ +$\line{24}{}{\quad\quad \calculatedcommc_{\auxb, u}: \CircuitVal\ \deq}$ +$\quad\quad\quad\quad \octtreerootgadget(\cs,\thin \calculatedtreecleaf_{\auxb, u},\thin \ColumnProof_u\dot\path)$ +$\line{25}{}{\quad\quad \cs\dot\assert(\calculatedcommc_{\auxb, c} = \commc_\auxb)}$ +$\line{26}{}{\quad\quad \parentcolumns_{[[\auxb]], \mathbf{u}_\total}\dot\push(\column_{[\auxb], u})}$ + +$\line{27}{}{\quad \calculatedcolumn_{[\auxb], c}: \CircuitVal^{[N_\layers]} = [\ ]}$ +$\line{28}{}{\quad \for l_c \in [N_\layers]:}$ +$\line{29}{}{\quad\quad \layerbits_{[\auxb, \Le]}: \CircuitBit^{[32]} \deq \lebitsgadget(\cs, l_c, 32)}$ + +$\line{30}{}{\quad\quad \parentlabels_{[\auxb]}: \CircuitVal^{[*]} = [\ ]}$ +$\line{28}{}{\quad\quad \for p_\drg \in [d_\drg]:}$ +$\line{31}{}{\quad\quad\quad \parentlabel_{\auxb, u_\drg} = \parentcolumns_{[[\auxb]], \mathbf{u}_\total}[p_\drg][l_c]}$ +$\line{32}{}{\quad\quad\quad \parentlabels_{[\auxb]}\dot\push(\parentlabel_{\auxb, u_\drg})}$ +$\line{33}{}{\quad\quad \if l_c > 0:}$ +$\line{34}{}{\quad\quad\quad \for p_\exp \in [d_\drg, d_\total - 1]:}$ +$\line{35}{}{\quad\quad\quad\quad \parentlabel_{\auxb, u_\exp} = \parentcolumns_{[[\auxb]], \mathbf{u}_\total}[p_\exp][l_c - 1]}$ +$\line{36}{}{\quad\quad\quad\quad \parentlabels_{[\auxb]}\dot\push(\parentlabel_{\auxb, u_\exp})}$ + +$\line{37}{}{\quad\quad \parentlabelsbits_{[[\auxb + \constb, \lebytes]]}: {\CircuitBitOrConst^{[256]}}^{[d_\drg\ \text{or}\ d_\exp]} = [\ ]}$ +$\line{38}{}{\quad\quad \for \parentlabel_\auxb \in \parentlabels_{[\auxb]}:}$ +$\line{39}{}{\quad\quad\quad \parentlabelbits_{[\auxb, \Le]}: \CircuitBit^{[255]} \deq}$ +$\quad\quad\quad\quad\quad\quad \lebitsgadget(\cs, \parentlabel_\auxb, 255)$ +$\line{40}{}{\quad\quad\quad \parentlabelbits_{[\auxb + \constb, \lebytes]}: \CircuitBitOrConst^{[256]} =}$ +$\quad\quad\quad\quad\quad\quad \lebitstolebytes(\parentlabelbits_{[\auxb, \Le]})$ +$\line{41}{}{\quad\quad\quad \parentlabelsbits_{[[\auxb + \constb, \lebytes]]}\dot\push(\parentlabelbits_{[\auxb + \constb, \lebytes]})}$ +$\line{42}{}{\quad\quad \parentlabelsbits_{[[\auxb + \constb, \lebytes]]}\dot\repeat(N_\parentlabels)}$ + +$\line{43}{}{\quad\quad \calculatedlabel_{\auxb, c, l}: \CircuitVal \deq \createlabelgadget(}$ +$\quad\quad\quad\quad \cs,$ +$\quad\quad\quad\quad \replicaidbits_{[\auxb + \constb, \lebytes]} \thin,$ +$\quad\quad\quad\quad \layerbits_{[\auxb, \Le]} \thin,$ +$\quad\quad\quad\quad \challengebits_{[\auxb, \Le]},$ +$\quad\quad\quad\quad \parentlabelsbits_{[[\auxb + \constb, \lebytes]]} \thin,$ +$\quad\quad\quad)$ +$\line{44}{}{\quad\quad \calculatedcolumn_{[\auxb], c}\dot\push(\calculatedlabel_{\auxb, c, l})}$ + +$\line{45}{}{\quad \calculatedcommr_{\auxb, c}: \CircuitVal\ \deq}$ +$\quad\quad\quad \octtreerootgadget(\cs,\thin \calculatedtreerleaf_{\auxb, c} \thin, \TreeRProof_c\dot\path)$ +$\line{46}{}{\quad \cs\dot\assert(\calculatedcommr_{\auxb, c} = \commr_\auxb)}$ + +$\line{47}{}{\quad \encodingkey_{\auxb, c}: \CircuitVal = \calculatedcolumn_{[\auxb], c}[N_\layers - 1]}$ +$\line{48}{}{\quad \calculatedtreerleaf_{\auxb, c}: \CircuitVal\ \deq}$ +$\quad\quad\quad \encodegadget(\cs,\thin \treedleaf_{\auxb, c} \thin, \encodingkey_{\auxb, c})$ + +$\line{49}{}{\quad \calculatedtreecleaf_{\auxb, c}: \CircuitVal\ \deq}$ +$\quad\quad\quad \poseidongadget{11}(\cs, \calculatedcolumn_{[\auxb], c})$ +$\line{50}{}{\quad \calculatedcommc_{\auxb, c}: \CircuitVal\ \deq}$ +$\quad\quad\quad \octtreerootgadget(\cs,\thin \calculatedtreecleaf_{\auxb, c} \thin, \ColumnProof_c\dot\path)$ +$\line{51}{}{\quad \cs\dot\assert(\calculatedcommc_{\auxb, c} = \commc_\auxb)}$ + +$\line{52}{}{\return \cs}$ +``` + +**Code Comments:** +* **Lines 9-10:** Computes `$\CommCR^\dagger$` within the circuit from the witnessed commitments and assert that `$\CommCR^\dagger$` is equal to the public input `$\CommCR$`. +* **Lines 15-16:** Adds the packed challenge `$c$` as a public input, used when calculating each challenge `$c$`'s column within the circuit. +* **Lines 17-19:** Verifies `$c$`'s `$\TreeDProof_c$` by computing `$\CommD_c^\dagger$` within the circuit and asserting that it is equal to the public input `$\CommD$`. +* **Lines 20-26:** Allocates each of `$c$`'s parent's `$u \in \mathbf{u}_\total$` label and checks that `$u$`'s `$\ColumnProof_u$` is consistent with the previously verified `$\CommC^\dagger \mapsto \CommC \thin$`. +* **Lines 27-44:** Calculates challenge `$c$`'s label in each Stacked-DRG layer `$l$` within the circuit using each parent's allocated column. +* **Lines 45-46:** Verifies that `$c$`'s `$\TreeRProof_c$` is consistent with the previously verified `$\CommR^\dagger \mapsto \CommR$`. +* **Lines 47-48:** Checks that the calculated encoding key `$K_c^\dagger$` for `$c$` encodes the previously verified sector and replica tree leaves `$D_c^\dagger \mapsto D_c$` into `$R_c^\dagger \mapsto R_c$`. +* **Lines 49-51:** Verifies `$c$`'s `$\ColumnProof_c$` against the previously verified `$\CommC$`. + +## PoSt Challenges + +The function `$\getpostchallenge$` is used to derive a Merkle challenge for a Winning or Window PoSt proof. + +**Implementation:** [`storage_proofs::post::fallback::vanilla::generate_leaf_challenge()`](https://github.com/filecoin-project/rust-fil-proofs/blob/8e8306c942c22571bc784f7536f1704058c45119/storage-proofs/post/src/fallback/vanilla.rs#L214) + +**Additional Notation:** + +`$\R_{\postchallenges, \batch \thin \aww}$`\ +A random value used to derive the challenge set for each of a PoSt prover's partition proofs in their current Winning or Window PoSt proof batch. + +`$\SectorID$`\ +The ID for the sector `$D$` associated with the replica `$R$` for which this Merkle challemnge is being generated. + +`$\challengeindex_\batch$`\ +The unique index of a Merkle challenge across all PoSt partition proofs that a PoSt prover is generating. For all partition proofs in the same PoSt batch, every Merkle challenge across all replicas will have a unique `$\challengeindex_\batch \thin$`. + +```text +$\overline{\Function\getpostchallenge(\qquad\qquad}$ +$\quad \R_{\postchallenges, \batch \thin \aww}: \Fq,$ +$\quad \SectorID: \u{64},$ +$\quad \challengeindex_\batch: \u{64},$ +$\underline{) \rightarrow \NodeIndex \qquad\qquad\qquad\qquad\qquad\quad}$ +$\line{1}{\bi}{\preimage: \Byte^{[48]} =}$ +$\quad\quad \leencode(\R_{\postchallenges, \batch \thin \aww}) \as \Byte^{[32]}$ +$\quad\quad \|\ \leencode(\SectorID) \as \Byte^{[8]}$ +$\quad\quad \|\ \leencode(\challengeindex_\batch) \as \Byte^{[8]}$ + +$\line{2}{\bi}{\digest: \Byte^{[32]} = \Sha{256}(\preimage)}$ +$\line{3}{\bi}{\digestint: \u{64} = \ledecode(\digest[\ldotdot 8])}$ +$\line{4}{\bi}{\return \digestint \MOD N_\nodes}$ +``` + +**Code Comments:** +* **Line 4:** modding by `$N_\nodes$` takes the 64-bit `$\digestint$` to a 32-bit node index `$\NodeIndex$`. + +## Vanilla PoSt + +### Proving + +**Implementation:** +* [`storage_proofs::post::fallback::vanilla::FallbackPoSt::prove()`](https://github.com/filecoin-project/rust-fil-proofs/blob/8e8306c942c22571bc784f7536f1704058c45119/storage-proofs/post/src/fallback/vanilla.rs#L249) + +**Additional Notation:** + +`$\nreplicas_k$`\ +The number of distinct replicas that the prover has for this PoSt partition proof. + +`$\replicaindex_k$`\ +$\replicaindex_\batch$ +The index of a challenged replica `$R$` in a partition `$k$`'s partition proof and the index of the challenged replica across all partition proofs that a prover is generating for batch. + +`$\challengeindex_R$`\ +$\challengeindex_\batch$ +The index of a Merkle challenge in a challenged replica `$R$` and the index of the Merkle challenge across all partition proofs that a prover is generating for batch. + +`$\TreeR_R, \CommC_R, \CommCR_R, \TreeRProofs_R$`\ +The subscript `$_R$` denotes each of these values as being for the replica `$R$` which is distinct within the prover's PoSt batch. + +`$\ell_\pad$`\ +The number of non-distinct `$\PostReplicaProof{\bf \sf s}$` that are added as padding to a PoSt prover's final partition proof in a batch. + +```text +$\overline{\Function \createvanillapostproof(\ }$ +$\quad k: \mathbb{N},$ +$\quad \PostReplicas_{P, k \thin \aww},$ +$\quad N_{\postreplicas / k \thin \aww},$ +$\quad N_{\postchallenges/R \thin \aww},$ +$\quad \R_{\postchallenges \thin \aww}: \Fq,$ +$\underline{) \rightarrow \PostPartitionProof_{k \thin \aww} \qquad}$ +$\line{1}{\bi}{\PostPartitionProof_{k \thin \aww} = [\ ]}$ +$\line{2}{\bi}{\nreplicas_k = \len(\PostReplicas_k)}$ + +$\line{3}{\bi}{\for \replicaindex_k \in [\nreplicas_k]}$ +$\line{4}{\bi}{\quad \TreeR_R, \CommC_R, \SectorID_R \Leftarrow \PostReplicas_k[\replicaindex_k]}$ +$\line{5}{\bi}{\quad \replicaindex_\batch: \u{64} = k * N_{\postreplicas / k} + \replicaindex_k}$ +$\line{6}{\bi}{\quad \TreeRProofs_R: {\TreeRProof}^{\thin[N_{\postchallenges / R}]} = [\ ]}$ +$\line{7}{\bi}{\quad \for \challengeindex_R \in [N_{\postchallenges / R}]:}$ +$\line{8}{\bi}{\quad\quad \challengeindex_\batch: \u{64} =}$ +$\quad\quad\quad\quad \replicaindex_\batch * N_{\postchallenges / R} + \challengeindex_R$ +$\line{9}{\bi}{\quad\quad c = \getpostchallenge(\R_\postchallenges, \SectorID, \challengeindex_\batch)}$ +$\line{10}{}{\quad\quad \TreeRProof_c = \TreeR\dot\createproof(c)}$ +$\line{11}{}{\quad\quad \TreeRProofs\dot\push(\TreeRProof_c)}$ +$\line{12}{}{\quad \PostPartitionProof\dot\push(\PostReplicaProof \{\thin \TreeRProofs,\thin \CommC\thin \})}$ + +$\line{13}{}{\ell_\textsf{pad} = N_{\postreplicas / k} - \nreplicas_k}$ +$\line{14}{}{\for i \in [\ell_\textsf{pad}]}$ +$\line{15}{}{\quad \PostPartitionProof\dot\push(\PostPartitionProof[\nreplicas_k - 1])}$ + +$\line{16}{}{\return \PartitionProof_{k \thin \aww}}$ +``` + +**Code Comments:** +* **Lines 13-15:** If the prover does not have enough replicas to fill an entire PoSt partition proof, pad the partition proof with copies of the last distinct replica's `$\PostReplicaProof_R \thin$`. + +### Verification + +**Implementation:** [`storage_proofs::post::fallback::vanilla::FallbackPoSt::verify_all_partitions()`](https://github.com/filecoin-project/rust-fil-proofs/blob/8e8306c942c22571bc784f7536f1704058c45119/storage-proofs/post/src/fallback/vanilla.rs#L357) + +**Additional Notation:** + +`$k: N_{\postpartitions, \P \thin \aww}$`\ +The number of partitions in a Winning or Window PoSt batch is dependent on the length of the PoSt prover `$\P$`'s replica set. + +`$\nreplicas_k$`\ +The number of distinct replicas that the prover has for this PoSt partition proof. + +`$\replicaindex_k$`\ +`$\replicaindex_\batch$`\ +The index of a challenged replica `$R$` in a partition `$k$`'s partition proofs in a PoSt prover's batch. + +`$\challengeindex_R$`\ +`$\challengeindex_\batch$`\ +The index of a Merkle challenge in a challenged replica `$R$` and the index of the Merkle challenge across all partition proofs in a PoSt prover's batch. + +```text +$\overline{\Function \verifyvanillapostproof( \bi}$ +$\quad \PostPartitionProof_{k \thin \aww},$ +$\quad k: [N_{\postpartitions, \P \thin \aww}],$ +$\quad \PostReplicas_{\V, k \thin \aww},$ +$\quad N_{\postreplicas / k \thin \aww},$ +$\quad N_{\postchallenges / R \thin \aww},$ +$\quad \R_\postchallenges: \Fq,$ +$\underline{) \qquad\qquad\qquad\qquad\qquad\qquad\qquad\quad\bi}$ +$\line{1}{\bi}{\nreplicas_k = \len(\PostReplicas_{\V, k})}$ + +$\line{2}{\bi}{\for \replicaindex_k \in [\nreplicas_k]:}$ +$\line{3}{\bi}{\quad \replicaindex_\batch = k * N_{\postreplicas / k} + \replicaindex_k}$ + +$\line{4}{\bi}{\quad \SectorID, \CommCR \Leftarrow \PostReplicas_{\V, k}[\replicaindex_k]}$ +$\line{5}{\bi}{\quad \CommC^\dagger, \TreeRProofs^\dagger \Leftarrow \PostPartitionProof[\replicaindex_k]}$ +$\line{6}{\bi}{\quad \CommR^\dagger = \TreeRProofs^\dagger[0]\dot\root}$ + +$\line{7}{\bi}{\quad \CommCR^\dagger = \Poseidon{2}([\CommC^\dagger, \CommR^\dagger])}$ +$\line{8}{\bi}{\quad \assert(\CommCR^\dagger = \CommCR)}$ + +$\line{9}{\bi}{\quad \for \challengeindex_R \in [N_{\postchallenges / R}]:}$ +$\line{10}{}{\quad\quad \challengeindex_\batch: \u{64} =}$ +$\quad\quad\quad\quad \replicaindex_\batch * N_{\postreplicas / k} + \challengeindex_R$ +$\line{11}{}{\quad\quad c = \getpostchallenge(\R_\postchallenges, \SectorID, \challengeindex_\batch)}$ + +$\line{12}{}{\quad\quad \TreeRProof^\dagger = \TreeRProofs^\dagger[\challengeindex_R]}$ +$\line{13}{}{\quad\quad \assert(\TreeRProof^\dagger\dot\root = \CommR)}$ +$\line{14}{}{\quad\quad \assert(\calculateocttreechallenge(\TreeRProof^\dagger\dot\path) = c)}$ +$\line{15}{}{\quad\quad \assert(\octtreeproofisvalid(\TreeRProof^\dagger))}$ +``` + +**Code Comments:** +* **Line 13:** The dagger is removed from `$\CommR^\dagger$` (producing `$\CommR$`) because `$\CommR^\dagger$` was verified to be consistent with the committed to `$\CommCR$` (Line 8). + +## PoSt Circuit + +The function `$\createpostcircuit$` is used to instantiate a Winning or Window PoSt circuit. + +**Addional Notation:** + +`$\PostPartitionProof_{k \thin \aww}$`\ +The partition-`$k$` proof in a PoSt prover's Winning or Window PoSt batch. `$\PostPartitionProof_k$` Contains any padded `$\PostReplicaProof{\bf \sf s}$`. + +`$\TreeR_R, \CommC_R, \CommCR_R$`\ +Each `$\PostReplica_R \in \PostReplicas_{\P \thin \aww}$` represents a unique replica `$R$` in the batch denoted by the subscript `$_R \thin$`. + +`$\TreeRProofs_R$`\ +Each `$\TreeRProofs$` is for a distinct replica `$R$`, denoted by the subscript `$_R \thin$`, in a PoSt batch. + +```text +$\overline{\Function \createpostcircuit( \quad\qquad}$ +$\quad \PostPartitionProof_{k \thin \aww},$ +$\quad \PostReplicas_{\P, k \thin \aww},$ +$\quad N_{\postreplicas / k \thin \aww},$ +$\underline{) \rightarrow \RCS \qquad\qquad\qquad\qquad\qquad\qquad\bi}$ +$\line{1}{\bi}{\cs = \RCS\cc\new()}$ +$\line{2}{\bi}{\nreplicas_k = \len(\PostReplicas_{\P, k})}$ + +$\line{3}{\bi}{\for \replicaindex_k \in [\nreplicas_k]:}$ +$\line{4}{\bi}{\quad \TreeR_R, \CommC_R, \CommCR_R \Leftarrow \PostReplicas_{\P, k}[\replicaindex_k]}$ +$\line{5}{\bi}{\quad \TreeRProofs_R \Leftarrow \PostPartitionProof_k[\replicaindex_k]}$ + +$\line{6}{\bi}{\quad \commcr_\pubb: \CircuitVal \deq \cs\dot\publicinput(\CommCR)}$ +$\line{7}{\bi}{\quad \commc_\auxb: \CircuitVal \deq \cs\dot\privateinput(\CommC)}$ +$\line{8}{\bi}{\quad \commr_\auxb: \CircuitVal \deq \cs\dot\privateinput(\CommR)}$ +$\line{9}{\bi}{\quad \calculatedcommcr_\auxb: \CircuitVal\ \deq}$ +$\quad\quad\quad \poseidongadget{2}(\cs, [\commc_\auxb, \thin \commr_\auxb])$ +$\line{10}{}{\quad \cs\dot\assert(\calculatedcommcr_\auxb = \commcr_\pubb)}$ + +$\line{11}{}{\quad \for \TreeRProof_c \in \TreeRProofs:}$ +$\line{12}{}{\quad\quad \treerleaf_{\auxb, c}: \CircuitVal \deq \cs\dot\privateinput(\TreeRProof_c\dot\leaf)}$ +$\line{13}{}{\quad\quad \calculatedcommr_{\auxb, c}: \CircuitVal\ \deq}$ +$\quad\quad\quad\quad \octtreerootgadget(\cs,\thin \treerleaf_{\auxb, c} \thin, \TreeRProof_c\dot\path)$ +$\line{14}{}{\quad\quad \cs\dot\assert(\calculatedcommr_{\auxb, c} = \commr_\auxb)}$ + +$\line{15}{}{\return \cs}$ +``` + +## Gadgets + +### Hash Functions + +We make use of the following hash function gadgets, however their implementation is beyond the scope of this document. + +```text +$\textsf{sha256\_gadget}(\cs: \RCS,\thin \preimage: \CircuitBitOrConst^{[*]}) \rightarrow \CircuitBit^{[256]}$ +$\shagadget{254}{2}(\cs: \RCS,\thin \inputs: \CircuitVal^{[2]}) \rightarrow \CircuitBit^{[254]}$ +$\poseidongadget{2}(\cs: \RCS,\thin \inputs: \CircuitVal^{[2]}) \rightarrow \CircuitVal$ +$\poseidongadget{8}(\cs: \RCS,\thin \inputs: \CircuitVal^{[8]}) \rightarrow \CircuitVal$ +$\poseidongadget{11}(\cs: \RCS,\thin \inputs: \CircuitVal^{[11]}) \rightarrow \CircuitVal$ +``` + +### BinTree Root Gadget + +The function `$\bintreerootgadget$` calculates and returns a `$\BinTree$` Merkle root from an allocated leaf `$\leaf_\auxb$` and an unallocated Merkle `$\path$`. Both the leaf and path are from a Merkle challenge `$c$`'s proof `$\BinTreeProof_c$`, where `$\path = \BinTreeProof_c\dot\path \thin$`. + +The gadget adds one public input to the constraint system for the packed Merkle proof path bits `$\pathbits_\auxle$` which are the binary representation of the `$c$`'s DRG node-index `$\llcorner c \lrcorner_{2, \Le} \equiv \pathbits_\auxle \thin$`). + +```text +$\overline{\Function \bintreerootgadget(\qquad\quad}$ +$\quad \cs: \RCS,$ +$\quad \leaf_\auxb: \CircuitVal,$ +$\quad \path: \BinPathElement^{[\BinTreeDepth]},$ +$\underline{) \rightarrow \CircuitVal \qquad\qquad\qquad\qquad\qquad\quad}$ +$\line{1}{\bi}{\curr_\auxb: \CircuitVal = \leaf_\auxb}$ +$\line{2}{\bi}{\pathbits_{[\auxb, \Le]}: \CircuitBit^{[\BinTreeDepth]} = [\ ]}$ + +$\line{3}{\bi}{\for \sibling, \missing \in \path:}$ +$\line{4}{\bi}{\quad \missingbit_\auxb: \CircuitBit \deq \cs\dot\privateinput(\missing)}$ +$\line{5}{\bi}{\quad \sibling_\auxb: \CircuitVal \deq \cs\dot\privateinput(\sibling)}$ +$\line{6}{\bi}{\quad \inputs_{[\auxb]}: \CircuitVal^{[2]} \deq}$ +$\quad\quad\quad \insertgadget{2}(\cs, [\sibling_\auxb],\thin \curr_\auxb,\thin \missingbit_\auxb)$ +$\line{7}{\bi}{\quad \curr_\auxb: \CircuitVal \deq \shagadget{254}{2}(\cs, \inputs_{[\auxb]})}$ +$\line{8}{\bi}{\quad \pathbits_{[\auxb, \Le]}\dot\push(\missingbit_\auxb)}$ + +$\line{9}{\bi}{\packedchallenge_\pubb: \CircuitVal\ \deq}$ +$\quad\quad \packbitsasinputgadget(\cs, \pathbits_{[\auxb, \Le]})$ + +$\line{10}{}{\return \curr_\auxb}$ +``` + +**Code Comments:** +* **Line 9:** A public input is added to `$\cs$` for the Merkle challenge `$c$` corresponding to the Merkle path which was used to calculate the returned root. +* **Line 10:** The final value for `$\curr_\auxb$` is the Merkle root calculated from `$\leaf_\auxb$` and `$\path$`. + +### OctTree Root Gadget + +The function `$\octtreerootgadget$` calculates and returns an `$\OctTree$` Merkle root from an allocated leaf `$\leaf_\auxb$` and an unallocated Merkle `$\path$`. Both the leaf and path are from a Merkle challenge `$c$`'s proof `$\OctTreeProof_c$`, where `$\path = \OctTreeProof_c\dot\path \thin$`. + +The gadget adds one public input to the constraint system for the packed Merkle proof path bits `$\pathbits_\auxle$` which are the binary representation of the `$c$`'s DRG node-index `$\llcorner c \lrcorner_{2, \Le} \equiv \pathbits_\auxle \thin$`). + +Note that the constant `$3 = \log_2(8)$`, the number of bits required to represent an index in the 8-element Merkle hash `$\inputs$` array, is used at various times in the following algorithm. + +```text +$\overline{\Function \octtreerootgadget( \qquad\quad}$ +$\quad \cs: \RCS,$ +$\quad \leaf_\auxb: \CircuitVal,$ +$\quad \path: \OctPathElement^{[\OctTreeDepth]},$ +$\underline{) \rightarrow \CircuitVal \qquad\qquad\qquad\qquad\qquad\quad}$ +$\line{1}{\bi}{\curr_\auxb: \CircuitVal = \leaf_\auxb}$ +$\line{2}{\bi}{\pathbits_\auxle: \CircuitBit^{[3 * \OctTreeDepth]} = [\ ]}$ + +$\line{3}{\bi}{\for \siblings, \missing \in \path:}$ +$\line{4}{\bi}{\quad \missingbits_\auxle: \CircuitBit^{[3]} = [\ ]}$ +$\line{5}{\bi}{\quad \for i \in [3]:}$ +$\line{6}{\bi}{\quad\quad \bit: \Bit = (\missing \gg i) \AND 1}$ +$\line{7}{\bi}{\quad\quad \bit_\auxb \deq \cs\dot\privateinput(\bit)}$ +$\line{8}{\bi}{\quad\quad \missingbits_\auxle\dot\push(\bit_\auxb)}$ + +$\line{9}{\bi}{\quad \siblings_{[\auxb]}: \CircuitVal^{[7]} = [\ ]}$ +$\line{10}{}{\quad \for \sibling \in \siblings:}$ +$\line{11}{}{\quad\quad \sibling_\auxb: \CircuitVal \deq \cs\dot\privateinput(\sibling)}$ +$\line{12}{}{\quad\quad \siblings_{[\auxb]}\dot\push(\sibling_\auxb)}$ + +$\line{13}{}{\quad \inputs_{[\auxb]}: \CircuitVal^{[8]}\thin \deq}$ +$\quad\quad\quad \insertgadget{8}(\cs, \siblings_{[\auxb]},\thin \curr_\auxb,\thin \missingbits_\auxle)$ +$\line{14}{}{\quad \curr_\auxb: \CircuitVal \deq \poseidongadget{8}(\cs, \inputs_{[\auxb]})}$ +$\line{15}{}{\quad \pathbits_\auxle\dot\extend(\missingbits_\auxle)}$ + +$\line{16}{}{\packedchallenge_\pubb: \CircuitVal\ \deq}$ +$\quad\quad \packbitsasinputgadget(\cs, \pathbits_{[\auxb, \Le]})$ + +$\line{17}{}{\return \curr_\auxb}$ +``` + +**Code Comments:** +* **Line 1:** Not a reallocation of `$\leaf_\auxb$` within `$\cs$`, but is an in-memory copy. +* **Lines 4-8:** Witnesses the 3-bit missing index for each path element. The first iteration `$i = 0$` corresponds to the least significant bit in `$\missing$`. +* **Lines 9-12:** Witnesses each path element's 7 Merkle hash inputs (the exlucded 8-th Merkle hash input is the calculated hash input `$\curr_\auxb$` for this tree depth). +* **Line 13:** Creates the Merkle hash inputs array by inserting `$\curr$` into `$\siblings$` at index `$\missing$`. +* **Line 14:** Hashes the 8 Merkle hash inputs. +* **Line 16:** Adds the challenge `$c$` as a public input. +* **Line 17:** Returns the calculated root. + +### Encoding Gadget + +The function `$\encodegadget$` runs the `$\encode$` function within a circuit. Used to encode `$\unencoded_{\auxb, v}$` (node `$v$`'s sector data `$D_v$`) into `$\encoded_{\auxb, v}$` (the replica node `$R_v$`) given an allocated encoding key `$\key_{\auxb, v}$` (`$K_v$`). + +**Implementation:** [`storage_proofs::core::gadgets::encode::encode()`](https://github.com/filecoin-project/rust-fil-proofs/blob/3cc8b5acb742d1469e10949fadc389806fa19c8c/storage-proofs/core/src/gadgets/encode.rs#L7) + +```text +$\overline{\Function \encodegadget(\qquad}$ +$\quad \cs: \RCS,$ +$\quad \unencoded_{\auxb, v}: \CircuitVal,$ +$\quad \key_{\auxb, v}: \CircuitVal,$ +$\underline{) \rightarrow \CircuitVal \qquad\qquad\qquad\qquad}$ +$\line{1}{\bi}{R_v: \Fq = \unencoded_{\auxb, v}\dot\value \oplus \key_{\auxb, v}\dot\value}$ +$\line{2}{\bi}{\encoded_{\auxb, v}: \CircuitVal \deq \cs\dot\privateinput(R_v)}$ +$\line{3}{\bi}{\lc_A: \LinearCombination \equiv \unencoded_{\auxb, v} + \key_{\auxb, v}}$ +$\line{4}{\bi}{\lc_B: \LinearCombination \equiv \cs\dot\one_\pubb}$ +$\line{5}{\bi}{\lc_C: \LinearCombination \equiv \encoded_{\auxb, v}}$ +$\line{6}{\bi}{\cs\dot\assert(\lc_A * \lc_B = \lc_C)}$ +$\line{7}{\bi}{\return \encoded_{\auxb, v}}$ +``` + +### Labeling Gadget + +The function `$\createlabelgadget$` is used to label a node `$\node$` in the Stacked-DRG layer `$\layerindex$` given the node's expanded parent labels `$\parentlabels$`. + +**Implementation:** [`storage_proofs::porep::stacked::circuit::create_label::create_label_circuit()`](https://github.com/filecoin-project/rust-fil-proofs/blob/3cc8b5acb742d1469e10949fadc389806fa19c8c/storage-proofs/porep/src/stacked/circuit/create_label.rs#L10) + +**Additional Notation:** + +`$\replicaid_{[\auxb + \constb, \lebytes]}$`\ +The allocated bits (and constant zero bit(s)) representing a `$\ReplicaID$`. + +`$\layerindex_{[\auxb, \Le]}$`\ +The allocated bits representing a layer `$l \in [N_\layers]$` as an unsigned 32-bit integer. + +`$\node_{[\auxb, \Le]}$`\ +A node index `$v \in [N_\nodes]$` allocated as 64 bits. + +`$\parentlabels_{[[\auxb + \constb, \lebytes]]}$`\ +An array containing `$N_\parentlabels$` allocated bit arrays, where each bit array is the label of one of `$\node$`'s parents. + +`$\label$`\ +Is the calculated label for `$\node$`. + +```text +$\overline{\Function \createlabelgadget( \qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\ }$ +$\quad \cs: \RCS,$ +$\quad \replicaid_{[\auxb + \constb, \lebytes]}: \CircuitBitOrConst^{[256]} \thin,$ +$\quad \layerindex_{[\auxb, \Le]}: \CircuitBit^{[32]} \thin,$ +$\quad \node_{[\auxb, \Le]}: \CircuitBit^{[64]} \thin,$ +$\quad \parentlabels_{[[\auxb + \constb, \lebytes]]}: {\CircuitBitOrConst^{[256]}}^{[N_\parentlabels]} \thin,$ +$\underline{) \rightarrow \CircuitVal \qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad}$ +$\line{1}{\bi}{\layerindex_{[\auxb, \be]}: \CircuitBit^{[32]} = \reverse(\layerindex_{[\auxb, \Le]})}$ +$\line{2}{\bi}{\nodeindex_{[\auxb, \be]}: \CircuitBit^{[64]} = \reverse(\node_{[\auxb, \Le]})}$ +$\line{3}{\bi}{\preimage_{[\auxb + \constb]}: \CircuitBitOrConst^{[9984]} =}$ +$\quad\quad \replicaid_{[\auxb + \constb, \lebytes]}$ +$\quad\quad \|\ \layerindex_{[\auxb, \be]}$ +$\quad\quad \|\ \nodeindex_{[\auxb, \be]}$ +$\quad\quad \|\ 0^{[160]}$ +$\quad\quad \big\|_{\parentlabel \hspace{1pt} \in \hspace{1pt} \parentlabels} \thin \parentlabel_{[\auxb + \constb, \lebytes]} \vphantom{{{|^|}^|}^x}$ + +$\line{4}{\bi}{\digestbits_{[\auxb, \lebytes]}: \CircuitBit^{[256]} \deq \textsf{sha256\_gadget}(\cs, \preimage_{[\auxb + \constb]})}$ +$\line{5}{\bi}{\digestbits_{[\auxb, \Le]}: \CircuitBit^{[256]} = \lebytestolebits(\digestbits_{[\auxb, \lebytes]})}$ +$\line{6}{\bi}{\digestbits_{[\auxb, \Le], \safe}: \CircuitBit^{[254]} = \digestbits_{[\auxb, \Le]}[0 \thin\ldotdot\thin 254]}$ +$\line{7}{\bi}{\label = \digestbits_{[\auxb, \Le], \safe} \thin\as\thin \Fqsafe}$ +$\line{8}{\bi}{\label_\auxb: \CircuitVal \deq \cs\dot\privateinput(\label)}$ + +$\line{9}{\bi}{\lc: \LinearCombination \equiv \sum_{i \in [254]}{2^i * \digestbits_{[\auxb, \Le], \safe}[i]}}$ +$\line{10}{}{\cs\dot\assert(\lc = \label_\auxb)}$ + +$\line{11}{}{\return \label_\auxb}$ +``` + +**Code Comments:** +* **Line 3:** The constant `$9984 = (2 + N_\parentlabels) * \ell_\block^\bit = (2 + 37) * 256 \thin$`. The constant `$160 = \ell_\block^\bit - \len(\layerindex) - \len(\nodeindex) = 256 - 32 - 64 \thin$`. +* **Lines 4-5:** The constant `$256 = \ell_\block^\bit \thin$`. +* **Lines 5-6:** These are not reallocations. +* **Lines 6-7:** The labeling function is `$\Sha{254}$` not `$\Sha{256}$`. +* **Lines 6,9:** The constant `$254 = \ell_{\Fq, \safe}^\bit \thin$`. + +### Little-Endian Bits Gadget + +The function `$\lebitsgadget$` receives a value `$\value$` allocated within a constraint system `$\cs$` and reallocates it as its `$n$`-bit little-endian binary representation. + +Note that the number of bits returned must be at least the number of bits required to represent `$\value$`: `$0 < \lceil \log_2(\value\dot\int) \rceil \leq n \thin$`. + +**Implementation:** [`bellman::gadgets::num::AllocatedNum::to_bits_le()`](https://github.com/filecoin-project/bellman/blob/e0ac6b879eac87832ba6ef2e37320e877d1d96b6/src/gadgets/num.rs#L193) + +```text +$\overline{\Function \lebitsgadget(}$ +$\quad \cs: \RCS,$ +$\quad \value_{\langle \auxb | \pubb \rangle}: \CircuitVal,$ +$\quad n: \mathbb{Z}^+,$ +$\underline{) \rightarrow \CircuitBit^{[n]} \qquad\quad}$ +$\line{1}{\bi}{\assert(n \geq \lceil \log_2(\value\dot\int) \rceil)}$ + +$\line{2}{\bi}{\bits_\Le: \Bit^{[n]} = \llcorner \value_{\langle \auxb | \pubb \rangle}\dot\int \lrcorner_{2, \Le}}$ +$\line{3}{\bi}{\bits_{[\auxb, \Le]}: \CircuitBit^{[n]} = [\ ]}$ +$\line{4}{\bi}{\for \bit \in \bits_\Le:}$ +$\line{5}{\bi}{\quad \bit_\auxb: \CircuitBit \overset{\diamond}{=} \cs\dot\privateinput(\bit)}$ +$\line{6}{\bi}{\quad \bits_{[\auxb, \Le]}\dot\push(\bit_\auxb)}$ + +$\line{7}{\bi}{\lc: \LinearCombination \equiv \sum_{i \in [n]}{2^i * \bits_{[\auxb, \Le]}[i]}}$ +$\line{8}{\bi}{\cs\dot\assert(\value_{\langle \auxb | \pubb \rangle} = \lc)}$ + +$\line{9}{\bi}{\return \bits_{[\auxb, \Le]}}$ +``` + +**Code Comments:** +* **Line 2:** This will pad `$n - \lceil \log_2(\value\dot\int) \rceil$` zero bits onto the most significant end of `$\llcorner \int \lrcorner_{2, \Le} \thin$`. + +### Pack Bits as Input Gadget + +The function `$\packbitsasinputgadget$` receives an array of `$n$` allocated little-endian bits `$\bits_{[\auxb, \Le]}$`, where `$0 < n \leq \ell_\Fqsafe^\bit \thin$`, and creates the field element `$\packed$` whose little-endian binary representation is that of `$\bits$`. The gadget adds one public input `$\packed_\pubb$` to the constraint system for the created field element. + +```text +$\overline{\Function \packbitsasinputgadget(}$ +$\quad \cs: \RCS,$ +$\quad \bits_{[\auxb, \Le]}: \CircuitBit^{[n]},$ +$\underline{) \rightarrow \CircuitVal \qquad\qquad\qquad\qquad\qquad\quad}$ +$\line{1}{\bi}{\assert(0 < n \leq \ell_\Fqsafe^\bit)}$ +$\line{2}{\bi}{\packed: \Fq = \bits_{[\auxb, \Le]} \as \Fq}$ +$\line{3}{\bi}{\packed_\pubb \overset{\diamond}{=} \cs\dot\publicinput(\packed)}$ +$\line{4}{\bi}{\lc: \LinearCombination \equiv \sum_{i \in [n]}{2^i * \bits_{[\auxb, \Le]}[i]}}$ +$\line{5}{\bi}{\cs\dot\assert(\lc = \packed_\pub)}$ +$\line{6}{\bi}{\return \packed_\pubb}$ +``` + +### Pick Gadget + +The `$\pickgadget$` is used to choose one of two allocated values, `$\x$` and `$\y$`, based upon the value of a binary condition `$\bit$`. + +If `$\bit$` is set, the gadget will reallocate and return `$\x$`, otherwise if `$\bit$` is not set, the gadget will reallocate and return `$\y$`. + +The `$\pickgadget$`, when given two allocated values `$\x, \y \in \Fq$` and an allocated boolean constrained value `$\bit \in \Bit$`, outputs the allocated value `$\pick \in \{ \x, \y \}$` and adds the `$\RCS$` quadratic constraint: + +$\bi (\y - \x) * (\bit) = (\y - \pick)$ + +This table shows that for `$\bit \in \Bit$` and `$\x, \y \in \Fq$` that the constraint is satisfied for the outputted values of `$\pick$`. + +| `$\bit$` | `$\pick$` | `$(\y - \x) * (\bit) = (\y - \pick)$` | +|--------|---------|------------------------------------| +| `$1$` | `$\x$` | `$(\y-\x) * (1) = (\y-\x)$` | +| `$0$` | `$\y$` | `$(\y-\x) * (0) = (\y-\y)$` | + +```text +$\overline{\Function \pickgadget( \qquad\quad\bi}$ +$\quad \cs: \RCS,$ +$\quad \bit_\aap: \CircuitBit,$ +$\quad \x_\aap: \CircuitVal,$ +$\quad \y_\aap: \CircuitVal,$ +$\underline{) \rightarrow \CircuitVal \qquad\qquad\qquad\qquad}$ +$\line{1}{\bi}{\pick_\auxb: \CircuitVal \deq \if \bit_\aap\dot\int = 1:}$ +$\quad\quad \cs\dot\privateinput(\x_\aap)$ +$\quad\else:$ +$\quad\quad \cs\dot\privateinput(\y_\aap)$ + +$\line{2}{\bi}{\lc_A: \LinearCombination \equiv \y_\aap - \x_\aap}$ +$\line{3}{\bi}{\lc_B: \LinearCombination \equiv \bit_\aap}$ +$\line{4}{\bi}{\lc_C: \LinearCombination \equiv \y_\aap - \pick_\auxb}$ +$\line{5}{\bi}{\cs\dot\assert(\lc_A * \lc_B = \lc_C)}$ + +$\line{6}{\bi}{\return \pick_\auxb}$ +``` + +### Insert-2 Gadget + +The `$\insertgadget{2}$` inserts `$\value$` into an array `$\arr$` at index `$\index$` and returns the inserted array of reallocated elements. + +The gadget receives an array containing one allocated element `$\arr[0]$` and a second allocated value `$\value$` and returns the two element array containing the reallocations of the two values where the index of the reallocated `$\value$` is at the index `$\index$` argument in the returned 2-element array. + +```text +$\overline{\Function \insertgadget{2}(\qquad\qquad\bi}$ +$\quad \cs: \RCS,$ +$\quad \arr_\aap: \CircuitVal^{[1]},$ +$\quad \value_\aap: \CircuitVal,$ +$\quad \index_\auxb: \CircuitBitOrConst,$ +$\underline{) \rightarrow \CircuitVal^{[2]} \qquad\qquad\qquad\qquad\qquad}$ +$\line{1}{\bi}{\el_{\auxb, 0}: \CircuitVal \deq \pickgadget(\cs,\thin \index_\auxb,\thin \arr_\aap[0] \thin,\thin \value_\aap \thin)}$ +$\line{2}{\bi}{\el_{\auxb, 1}: \CircuitVal \deq \pickgadget(\cs, \index_\auxb,\thin \value_\aap \thin,\thin \arr_\aap[0] \thin)}$ +$\line{3}{\bi}{\return [\el_{\auxb, 0}, \el_{\auxb, 1}]}$ +``` + +### Insert-8 Gadget + +The function `$\insertgadget{8}$` inserts a value `$\value$` into an array of 7 elements `$\arr$` at index in the 8 element array given by `$\indexbits$`. The values returned in the 8-element array are reallocations of `$\arr$` and `$\value$`. + +**Implementation:** [`storage_proofs::core::gadgets::insertion::insert_8()`](https://github.com/filecoin-project/rust-fil-proofs/blob/b9126bf56cfd2c73ce4ce1f6cb46fe001450f326/storage-proofs/core/src/gadgets/insertion.rs#L170) + +Note that the length of the `$\indexbits$` argument is `$3 = \log_2(8)$` bits, which is the number of bits required to represent an index in an array of 8 elements. + +**Additional Notation:** + +`$\arr'$`\ +The inserted array containing 8 reallocated values, the elements of the uninserted array `$\arr$` and the insertion value `$\value$`. + +`$\nor_{\auxb \thin (b_0, b_1)}$`\ +Set to true if neither `$\indexbits[0]$` nor `$\indexbits[1]$` are `$1$`. + +`$\and_{\auxb \thin (b_0, b_1)}$`\ +Set to true if both `$\indexbits[0]$` and `$\indexbits[1]$` are `$1$`. + +```text +$\pick_{\auxb, i(b_0)}$ +$\pick_{\auxb, i(b_0, b_1)}$ +$\pick_{\auxb, i(b_0, b_1, b_2)}$ +``` +The pick for the `$i^{th}$` element of the inserted array based upon the value of the first bit (least-significant), first and second bits, and the first, second and third bits respectively. + +```text +$b_i \equiv \indexbits_{[\aap, \Le]}[i]$ +$\pick_{i(b_0)} \equiv \pick_{\auxb, i(b_0)}$ +$\nor_{(b_0, b_1)} \equiv \nor_{\auxb \thin (b_0, b_1)}$ +$\and_{(b_0, b_1)} \equiv \and_{\auxb \thin (b_0, b_1)}$ +$\arr[i] \equiv \arr_{[\aap]}[i]$ +$\arr'[i] \equiv \arr'_{[\auxb]}[i]$ +``` +For ease of notation the subscripts `$_\auxb$` and `$_\aap$` are left off everywhere except in the function signature and when allocating of a value within the circuit. + +```text +$\overline{\Function \insertgadget{8}( \qquad\qquad\qquad\qquad\qquad\quad}$ +$\quad \cs: \RCS,$ +$\quad \arr_{[\aap]}: \CircuitVal^{[7]},$ +$\quad \value_\aap: \CircuitVal,$ +$\quad \indexbits_{[\aap, \Le]}: \CircuitBitOrConst^{[3]},$ +$\underline{) \rightarrow \CircuitVal^{[8]} \qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\bi}$ +$\line{1}{\bi}{\nor_{(b_0, b_1)}: \CircuitBit \deq \norgadget(\cs,\thin b_0 \thin,\thin b_1)}$ +$\line{2}{\bi}{\and_{\auxb \thin (b_0, b_1)}: \CircuitBit \deq \andgadget(\cs,\thin b_0 \thin,\thin b_1)}$ + +$\line{3}{\bi}{\arr'_{[\auxb]}: \CircuitVal^{[8]} = [\ ]}$ + +$\line{4}{\bi}{\pick_{\auxb, 0(b_0, b_1)}: \CircuitVal \deq \pickgadget(\cs,\thin \nor_{(b_0, b_1)},\thin \value,\thin \arr[0])}$ +$\line{5}{\bi}{\pick_{\auxb, 0(b_0, b_1, b_3)}: \CircuitVal \deq \pickgadget(\cs,\thin b_2,\thin \arr[0],\thin \pick_{0(b_0, b_1)})}$ +$\line{6}{\bi}{\arr'[0] = \pick_{0(b_0, b_1, b_3)}}$ + +$\line{7}{\bi}{\pick_{\auxb, 1(b_0)}: \CircuitVal \deq \pickgadget(\cs,\thin b_0,\thin \value,\thin \arr[0])}$ +$\line{8}{\bi}{\pick_{\auxb, 1(b_0, b_1)}: \CircuitVal \deq \pickgadget(\cs,\thin b_1,\thin \arr[1],\thin \pick_{1(b_0)})}$ +$\line{9}{\bi}{\pick_{\auxb, 1(b_0, b_1, b_3)}: \CircuitVal \deq \pickgadget(\cs,\thin b_2,\thin \arr[1],\thin \pick_{1(b_0, b_1)})}$ +$\line{10}{}{\arr'[1] = \pick_{1(b_0, b_1, b_3)}}$ + +$\line{11}{}{\pick_{\auxb, 2(b_0)}: \CircuitVal \deq \pickgadget(\cs,\thin b_0,\thin \arr[2],\thin \value)}$ +$\line{12}{}{\pick_{\auxb, 2(b_0, b_1)}: \CircuitVal \deq \pickgadget(\cs,\thin b_1,\thin \pick_{2(b_0)},\thin \arr[1])}$ +$\line{13}{}{\pick_{\auxb, 2(b_0, b_1, b_2)}: \CircuitVal \deq \pickgadget(\cs,\thin b_2,\thin \arr[2],\thin \pick_{2(b_0, b_1)})}$ +$\line{14}{}{\arr'[2] = \pick_{2(b_0, b_1, b_3)}}$ + +$\line{15}{}{\pick_{\auxb, 3(b_0, b_1)}: \CircuitVal \deq \pickgadget(\cs, \thin \and_{(b_0, b_1)}, \thin \value, \thin \arr[2])}$ +$\line{16}{}{\pick_{\auxb, 3(b_0, b_1, b_2)}: \CircuitVal \deq \pickgadget(\cs, \thin b_2, \thin \arr[3], \thin \pick_{3(b_0, b_1)})}$ +$\line{17}{}{\arr'[3] = \pick_{3(b_0, b_1, b_3)}}$ + +$\line{18}{}{\pick_{\auxb, 4(b_0, b_1)}: \CircuitVal \deq \pickgadget(\cs, \thin \nor_{(b_0, b_1)}, \thin \value, \thin \arr[4])}$ +$\line{19}{}{\pick_{\auxb, 4(b_0, b_1, b_2)}: \CircuitVal \deq \pickgadget(\cs, \thin b_2, \thin \pick_{4(b_0, b_1)}, \thin \arr[3])}$ +$\line{20}{}{\arr'[4] = \pick_{4(b_0, b_1, b_3)}}$ + +$\line{21}{}{\pick_{\auxb, 5(b_0)}: \CircuitVal \deq \pickgadget(\cs, \thin b_0, \thin \value, \thin \arr[4])}$ +$\line{22}{}{\pick_{\auxb, 5(b_0, b_1)}: \CircuitVal \deq \pickgadget(\cs, \thin b_1, \thin \arr[5], \thin \pick_{5(b_0)})}$ +$\line{23}{}{\pick_{\auxb, 5(b_0, b_1, b_2)}: \CircuitVal \deq \pickgadget(\cs, \thin b_2, \thin \pick_{5(b_0, b_1)}, \thin \arr[4])}$ +$\line{24}{}{\arr'[5] = \pick_{5(b_0, b_1, b_3)}}$ + +$\line{25}{}{\pick_{\auxb, 6(b_0)}: \CircuitVal \deq \pickgadget(\cs, \thin b_0, \thin \arr[6], \thin \value)}$ +$\line{26}{}{\pick_{\auxb, 6(b_0, b_1)}: \CircuitVal \deq \pickgadget(\cs, \thin b_1, \thin \pick_{6(b_0)}, \thin \arr[5])}$ +$\line{27}{}{\pick_{\auxb, 6(b_0, b_1, b_2)}: \CircuitVal \deq \pickgadget(\cs, \thin b_2, \thin \pick_{6(b_0, b_1)}, \thin \arr[5])}$ +$\line{28}{}{\arr'[6] = \pick_{6(b_0, b_1, b_3)}}$ + +$\line{27}{}{\pick_{\auxb, 7(b_0, b_1)}: \CircuitVal \deq \pickgadget(\cs, \thin \and_{(b_0, b_1)}, \thin \value, \thin \arr[6])}$ +$\line{28}{}{\pick_{\auxb, 7(b_0, b_1, b_2)}: \CircuitVal \deq \pickgadget(\cs, \thin b_2, \thin \pick_{7(b_0, b_1)}, \thin \arr[6])}$ +$\line{29}{}{\arr'[7] = \pick_{7(b_0, b_1, b_3)}}$ + +$\line{30}{}{\return \arr'}$ +``` + +### AND Gadget + +The function `$\andgadget$` returns an allocated bit `$1$` if both allocated bit arguments `$\x$` and `$\y$` are `$1$` and returns the allocated bit `$0$` otherwise. + +**Implementation:** [`bellman::gadgets::boolean::AllocatedBit::and()`](https://github.com/filecoin-project/bellman/blob/e0ac6b879eac87832ba6ef2e37320e877d1d96b6/src/gadgets/boolean.rs#L155) + +The `$\RCS$` quadratic constraint that is added by the `$\andgadget$`, when applied to two boolean constrained values `$\x, \y \in \Bit$` and outputting a third boolean constrained value `$\and \in \Bit$`, is: + +```text +$\bi (\x) * (\y) = (\and)$ +``` + +This table shows the satisfiablilty of the constraint for all values of `$\x, \y \in \Bit$` and corresponding outputted values of `$\and \in \Bit$`. + +| `$\x$` | `$\y$` | `$\and$` | `$(\x) * (\y) = (\and)$` | +|--------|---------|--------|-----------------------| +| `$0$` | `$0$` | `$0$` | `$(0) * (0) = (0)$` | +| `$1$` | `$0$` | `$0$` | `$(1) * (0) = (0)$` | +| `$0$` | `$1$` | `$0$` | `$(0) * (1) = (0)$` | +| `$1$` | `$1$` | `$1$` | `$(1) * (1) = (1)$` | + +```text +$\overline{\Function \andgadget(\qquad}$ +$\quad \cs: \RCS,$ +$\quad \x_\aap: \CircuitBit,$ +$\quad \y_\aap: \CircuitBit,$ +$\underline{) \rightarrow \CircuitBit \qquad\qquad\bi}$ +$\line{1}{\bi}{\and: \Bit = \x_\aap\dot\int \thin\AND\thin \y_\aap\dot\int}$ +$\line{2}{\bi}{\and_\auxb: \CircuitBit \deq \cs\dot\privateinput(\and)}$ +$\line{3}{\bi}{\cs\dot\assert(\x_\aap * \y_\aap = \and_\auxb)}$ +$\line{4}{\bi}{\return \and_\auxb}$ +``` + +### NOR Gadget + +The function `$\norgadget$` returns an allocated bit `$1$` if both allocated bit arguments `$\x$` and `$\y$` are `$0$` and returns the allocated bit `$0$` otherwise. + +**Implementation:** [`bellman::gadgets::boolean::AllocatedBit::nor()`](https://github.com/filecoin-project/bellman/blob/e0ac6b879eac87832ba6ef2e37320e877d1d96b6/src/gadgets/boolean.rs#L231) + +The `$\RCS$` quadratic constraint that is added by `$\norgadget$`, when applied to two boolean constrained values `$\x, \y \in \Bit$` and outputting a third boolean constrained value `$\nor \in \Bit$`, is: + +```text +$\bi (1 - \x) * (1 - \y) = (\nor)$ +``` + +The following table shows the satisfiablilty of the constraint for all values of `$\x, \y \in \Bit$` and corresponding outputted values for `$\nor \in \Bit$`. + +| `$\x$` | `$\y$` | `$\nor$` | `$(1 - \x) * (1 - \y) = (\nor)$` | +|--------|---------|--------|-----------------------| +| `$0$` | `$0$` | `$1$` | `$(1) * (1) = (1)$` | +| `$1$` | `$0$` | `$0$` | `$(0) * (1) = (0)$` | +| `$0$` | `$1$` | `$0$` | `$(1) * (0) = (0)$` | +| `$1$` | `$1$` | `$0$` | `$(0) * (0) = (0)$` | + +```text +$\overline{\Function \norgadget(\qquad}$ +$\quad \cs: \RCS,$ +$\quad \x_\aap: \CircuitBit,$ +$\quad \y_\aap: \CircuitBit,$ +$\underline{) \rightarrow \CircuitBit \qquad\qquad\bi}$ +$\line{1}{\bi}{\nor: \Bit = \neg (\x_\aap\dot\int \OR \y_\aap\dot\int)}$ +$\line{2}{\bi}{\nor_\auxb: \CircuitBit \deq \cs\dot\privateinput(\nor)}$ +$\line{3}{\bi}{\lc_A: \LinearCombination \equiv 1 - \x_\aap}$ +$\line{4}{\bi}{\lc_B: \LinearCombination \equiv 1 - \y_\aap}$ +$\line{5}{\bi}{\lc_C: \LinearCombination \equiv \nor_\auxb}$ +$\line{6}{\bi}{\cs\dot\assert(\lc_A * \lc_B = \lc_C)}$ +$\line{7}{\bi}{\return \nor_\auxb}$ +``` \ No newline at end of file diff --git a/content/algorithms/sdr/notation.md b/content/algorithms/sdr/notation.md index 66e43cd7f..bce6a62ad 100644 --- a/content/algorithms/sdr/notation.md +++ b/content/algorithms/sdr/notation.md @@ -3,6 +3,11 @@ title: "Notation, Constants, and Types" weight: 2 math-mode: true description: "Notation, Constants, and Types for Stacked DRG PoRep" + +dashboardWeight: 2 +dashboardState: stable +dashboardAudit: 1 +dashboardTests: 0 --- {{< plain hidden >}} diff --git a/content/algorithms/sdr/spec.md b/content/algorithms/sdr/spec.md deleted file mode 100644 index 81758d060..000000000 --- a/content/algorithms/sdr/spec.md +++ /dev/null @@ -1,1903 +0,0 @@ ---- -title: "Specification" -weight: 1 -math-mode: true -description: "Stacked DRG Proof of Replication Specification" ---- - -{{< plain hidden >}} -$$ -\gdef\createporepbatch{\textsf{create\_porep\_batch}} -\gdef\GrothProof{\textsf{Groth16Proof}} -\gdef\Groth{\textsf{Groth16}} -\gdef\GrothEvaluationKey{\textsf{Groth16EvaluationKey}} -\gdef\GrothVerificationKey{\textsf{Groth16VerificationKey}} -\gdef\creategrothproof{\textsf{create\_groth16\_proof}} -\gdef\ParentLabels{\textsf{ParentLabels}} -\gdef\or#1#2{\langle #1 | #2 \rangle} -\gdef\porepreplicas{\textsf{porep\_replicas}} -\gdef\postreplicas{\textsf{post\_replicas}} -\gdef\winningpartitions{\textsf{winning\_partitions}} -\gdef\windowpartitions{\textsf{window\_partitions}} -\gdef\sector{\textsf{sector}} -\gdef\lebitstolebytes{\textsf{le\_bits\_to\_le\_bytes}} -\gdef\lebinrep#1{{\llcorner #1 \lrcorner_{\lower{2pt}{2, \textsf{le}}}}} -\gdef\bebinrep#1{{\llcorner #1 \lrcorner_{\lower{2pt}{2, \textsf{be}}}}} -\gdef\lebytesbinrep#1{{\llcorner #1 \lrcorner_{\lower{2pt}{2, \textsf{le-bytes}}}}} -\gdef\fesitelrounds{\textsf{fesitel\_rounds}} -\gdef\int{\textsf{int}} -\gdef\lebytes{\textsf{le-bytes}} -\gdef\lebytestolebits{\textsf{le\_bytes\_to\_le\_bits}} -\gdef\letooctet{\textsf{le\_to\_octet}} -\gdef\byte{\textsf{byte}} -\gdef\postpartitions{\textsf{post\_partitions}} -\gdef\PostReplica{\textsf{PostReplica}} -\gdef\PostReplicas{\textsf{PostReplicas}} -\gdef\PostPartitionProof{\textsf{PostPartitionProof}} -\gdef\PostReplicaProof{\textsf{PostReplicaProof}} -\gdef\TreeRProofs{\textsf{TreeRProofs}} -\gdef\pad{\textsf{pad}} -\gdef\octettole{\textsf{octet\_to\_le}} -\gdef\packed{\textsf{packed}} -\gdef\val{\textsf{val}} -\gdef\bits{\textsf{bits}} -\gdef\partitions{\textsf{partitions}} -\gdef\Batch{\textsf{Batch}} -\gdef\batch{\textsf{batch}} -\gdef\postbatch{\textsf{post\_batch}} -\gdef\postchallenges{\textsf{post\_challenges}} -\gdef\Nonce{\textsf{Nonce}} -\gdef\createvanillaporepproof{\textsf{create\_vanilla\_porep\_proof}} -\gdef\PorepVersion{\textsf{PorepVersion}} -\gdef\bedecode{\textsf{be\_decode}} -\gdef\OR{\mathbin{|}} -\gdef\indexbits{\textsf{index\_bits}} -\gdef\nor{\textsf{nor}} -\gdef\and{\textsf{and}} -\gdef\norgadget{\textsf{nor\_gadget}} -\gdef\andgadget{\textsf{and\_gadget}} -\gdef\el{\textsf{el}} -\gdef\arr{\textsf{arr}} -\gdef\pickgadget{\textsf{pick\_gadget}} -\gdef\pick{\textsf{pick}} -\gdef\int{\textsf{int}} -\gdef\x{\textsf{x}} -\gdef\y{\textsf{y}} -\gdef\aap{{\langle \auxb | \pubb \rangle}} -\gdef\aapc{{\langle \auxb | \pubb | \constb \rangle}} -\gdef\TreeRProofs{\textsf{TreeRProofs}} -\gdef\parentlabelsbits{\textsf{parent\_labels\_bits}} -\gdef\label{\textsf{label}} -\gdef\layerbits{\textsf{layer\_bits}} -\gdef\labelbits{\textsf{label\_bits}} -\gdef\digestbits{\textsf{digest\_bits}} -\gdef\node{\textsf{node}} -\gdef\layerindex{\textsf{layer\_index}} -\gdef\be{\textsf{be}} -\gdef\octet{\textsf{octet}} -\gdef\reverse{\textsf{reverse}} -\gdef\LSBit{\textsf{LSBit}} -\gdef\MSBit{\textsf{MSBit}} -\gdef\LSByte{\textsf{LSByte}} -\gdef\MSByte{\textsf{MSByte}} -\gdef\PorepPartitionProof{\textsf{PorepPartitionProof}} -\gdef\PostPartitionProof{\textsf{PostPartitionProof}} -\gdef\lebinrep#1{{\llcorner #1 \lrcorner_{\lower{2pt}{2, \textsf{le}}}}} -\gdef\bebinrep#1{{\llcorner #1 \lrcorner_{\lower{2pt}{2, \textsf{be}}}}} -\gdef\octetbinrep#1{{\llcorner #1 \lrcorner_{\lower{2pt}{2, \textsf{octet}}}}} -\gdef\fieldelement{\textsf{field\_element}} -\gdef\Fqsafe{{\mathbb{F}_{q, \safe}}} -\gdef\elem{\textsf{elem}} -\gdef\challenge{\textsf{challenge}} -\gdef\challengeindex{\textsf{challenge\_index}} -\gdef\uniquechallengeindex{\textsf{unique\_challenge\_index}} -\gdef\replicaindex{\textsf{replica\_index}} -\gdef\uniquereplicaindex{\textsf{unique\_replica\_index}} -\gdef\nreplicas{\textsf{n\_replicas}} -\gdef\unique{\textsf{unique}} -\gdef\R{\mathcal{R}} -\gdef\getpostchallenge{\textsf{get\_post\_challenge}} -\gdef\verifyvanillapostproof{\textsf{verify\_vanilla\_post\_proof}} -\gdef\BinPathElement{\textsf{BinPathElement}} -\gdef\BinTreeDepth{\textsf{BinTreeDepth}} -\gdef\BinTree{\textsf{BinTree}} -\gdef\BinTreeProof{\textsf{BinTreeProof}} -\gdef\bintreeproofisvalid{\textsf{bintree\_proof\_is\_valid}} -\gdef\Bit{{\{0, 1\}}} -\gdef\Byte{\mathbb{B}} -\gdef\calculatebintreechallenge{\textsf{calculate\_bintree\_challenge}} -\gdef\calculateocttreechallenge{\textsf{calculate\_octtree\_challenge}} -\gdef\depth{\textsf{depth}} -\gdef\dot{\textsf{.}} -\gdef\for{\textsf{for }} -\gdef\Function{\textbf{Function: }} -\gdef\Fq{{\mathbb{F}_q}} -\gdef\leaf{\textsf{leaf}} -\gdef\line#1#2#3{\scriptsize{\textsf{#1.}#2}\ \normalsize{#3}} -\gdef\missing{\textsf{missing}} -\gdef\NodeIndex{\textsf{NodeIndex}} -\gdef\nodes{\textsf{nodes}} -\gdef\OctPathElement{\textsf{OctPathElement}} -\gdef\OctTree{\textsf{OctTree}} -\gdef\OctTreeDepth{\textsf{OctTreeDepth}} -\gdef\OctTreeProof{\textsf{OctTreeProof}} -\gdef\octtreeproofisvalid{\textsf{octtree\_proof\_is\_valid}} -\gdef\path{\textsf{path}} -\gdef\pathelem{\textsf{path\_elem}} -\gdef\return{\textsf{return }} -\gdef\root{\textsf{root}} -\gdef\Safe{{\Byte^{[32]}_\textsf{safe}}} -\gdef\sibling{\textsf{sibling}} -\gdef\siblings{\textsf{siblings}} -\gdef\struct{\textsf{struct }} -\gdef\Teq{\underset{{\small \mathbb{T}}}{=}} -\gdef\Tequiv{\underset{{\small \mathbb{T}}}{\equiv}} -\gdef\thin{{\thinspace}} -\gdef\AND{\mathbin{\&}} -\gdef\MOD{\mathbin{\%}} -\gdef\createproof{{\textsf{create\_proof}}} -\gdef\layer{\textsf{layer}} -\gdef\nodeindex{\textsf{node\_index}} -\gdef\childindex{\textsf{child\_index}} -\gdef\push{\textsf{push}} -\gdef\index{\textsf{index}} -\gdef\leaves{\textsf{leaves}} -\gdef\len{\textsf{len}} -\gdef\ColumnProof{\textsf{ColumnProof}} -\gdef\concat{\mathbin{\|}} -\gdef\inputs{\textsf{inputs}} -\gdef\Poseidon{\textsf{Poseidon}} -\gdef\bi{\ \ } -\gdef\Bool{{\{\textsf{True}, \textsf{False}\}}} -\gdef\curr{\textsf{curr}} -\gdef\if{\textsf{if }} -\gdef\else{\textsf{else}} -\gdef\proof{\textsf{proof}} -\gdef\Sha#1{\textsf{Sha#1}} -\gdef\ldotdot{{\ldotp\ldotp}} -\gdef\as{\textsf{ as }} -\gdef\bintreerootgadget{\textsf{bintree\_root\_gadget}} -\gdef\octtreerootgadget{\textsf{octtree\_root\_gadget}} -\gdef\cs{\textsf{cs}} -\gdef\RCS{\textsf{R1CS}} -\gdef\pathbits{\textsf{path\_bits}} -\gdef\missingbit{\textsf{missing\_bit}} -\gdef\missingbits{\textsf{missing\_bits}} -\gdef\pubb{\textbf{pub}} -\gdef\privb{\textbf{priv}} -\gdef\auxb{\textbf{aux}} -\gdef\constb{\textbf{const}} -\gdef\CircuitVal{\textsf{CircuitVal}} -\gdef\CircuitBit{{\textsf{CircuitVal}_\Bit}} -\gdef\Le{\textsf{le}} -\gdef\privateinput{\textsf{private\_input}} -\gdef\publicinput{\textsf{public\_input}} -\gdef\deq{\mathbin{\overset{\diamond}{=}}} -\gdef\alloc{\textsf{alloc}} -\gdef\insertgadget#1{\textsf{insert\_#1\_gadget}} -\gdef\block{\textsf{block}} -\gdef\shagadget#1#2{\textsf{sha#1\_#2\_gadget}} -\gdef\poseidongadget#1{\textsf{poseidon\_#1\_gadget}} -\gdef\refeq{\mathbin{\overset{{\small \&}}=}} -\gdef\ptreq{\mathbin{\overset{{\small \&}}=}} -\gdef\bit{\textsf{bit}} -\gdef\extend{\textsf{extend}} -\gdef\auxle{{[\textbf{aux}, \textsf{le}]}} -\gdef\SpecificNotation{{\underline{\text{Specific Notation}}}} -\gdef\repeat{\textsf{repeat}} -\gdef\preimage{\textsf{preimage}} -\gdef\digest{\textsf{digest}} -\gdef\digestbytes{\textsf{digest\_bytes}} -\gdef\digestint{\textsf{digest\_int}} -\gdef\leencode{\textsf{le\_encode}} -\gdef\ledecode{\textsf{le\_decode}} -\gdef\ReplicaID{\textsf{ReplicaID}} -\gdef\replicaid{\textsf{replica\_id}} -\gdef\replicaidbits{\textsf{replica\_id\_bits}} -\gdef\replicaidblock{\textsf{replica\_id\_block}} -\gdef\cc{\textsf{::}} -\gdef\new{\textsf{new}} -\gdef\lebitsgadget{\textsf{le\_bits\_gadget}} -\gdef\CircuitBitOrConst{{\textsf{CircuitValOrConst}_\Bit}} -\gdef\createporepcircuit{\textsf{create\_porep\_circuit}} -\gdef\CommD{\textsf{CommD}} -\gdef\CommC{\textsf{CommC}} -\gdef\CommR{\textsf{CommR}} -\gdef\CommCR{\textsf{CommCR}} -\gdef\commd{\textsf{comm\_d}} -\gdef\commc{\textsf{comm\_c}} -\gdef\commr{\textsf{comm\_r}} -\gdef\commcr{\textsf{comm\_cr}} -\gdef\assert{\textsf{assert}} -\gdef\asserteq{\textsf{assert\_eq}} -\gdef\TreeDProof{\textsf{TreeDProof}} -\gdef\TreeRProof{\textsf{TreeRProof}} -\gdef\TreeR{\textsf{TreeR}} -\gdef\ParentColumnProofs{\textsf{ParentColumnProofs}} -\gdef\challengebits{\textsf{challenge\_bits}} -\gdef\packedchallenge{\textsf{packed\_challenge}} -\gdef\PartitionProof{\textsf{PartitionProof}} -\gdef\u#1{\textsf{u#1}} -\gdef\packbitsasinputgadget{\textsf{pack\_bits\_as\_input\_gadget}} -\gdef\treedleaf{\textsf{tree\_d\_leaf}} -\gdef\treerleaf{\textsf{tree\_r\_leaf}} -\gdef\calculatedtreedroot{\textsf{calculated\_tree\_d\_root}} -\gdef\calculatedtreerleaf{\textsf{calculated\_tree\_r\_leaf}} -\gdef\calculatedcommd{\textsf{calculated\_comm\_d}} -\gdef\calculatedcommc{\textsf{calculated\_comm\_c}} -\gdef\calculatedcommr{\textsf{calculated\_comm\_r}} -\gdef\calculatedcommcr{\textsf{calculated\_comm\_cr}} -\gdef\layers{\textsf{layers}} -\gdef\total{\textsf{total}} -\gdef\column{\textsf{column}} -\gdef\parentcolumns{\textsf{parent\_columns}} -\gdef\columns{\textsf{columns}} -\gdef\parentlabel{\textsf{parent\_label}} -\gdef\label{\textsf{label}} -\gdef\calculatedtreecleaf{\textsf{calculated\_tree\_c\_leaf}} -\gdef\calculatedcolumn{\textsf{calculated\_column}} -\gdef\parentlabels{\textsf{parent\_labels}} -\gdef\drg{\textsf{drg}} -\gdef\exp{\textsf{exp}} -\gdef\parentlabelbits{\textsf{parent\_label\_bits}} -\gdef\parentlabelblock{\textsf{parent\_label\_block}} -\gdef\Bits{\textsf{ Bits}} -\gdef\safe{\textsf{safe}} -\gdef\calculatedlabel{\textsf{calculated\_label}} -\gdef\createlabelgadget{\textsf{create\_label\_gadget}} -\gdef\encodingkey{\textsf{encoding\_key}} -\gdef\encodegadget{\textsf{encode\_gadget}} -\gdef\TreeC{\textsf{TreeC}} -\gdef\value{\textsf{value}} -\gdef\encoded{\textsf{encoded}} -\gdef\unencoded{\textsf{unencoded}} -\gdef\key{\textsf{key}} -\gdef\lc{\textsf{lc}} -\gdef\LC{\textsf{LC}} -\gdef\LinearCombination{\textsf{LinearCombination}} -\gdef\one{\textsf{one}} -\gdef\constraint{\textsf{constraint}} -\gdef\proofs{\textsf{proofs}} -\gdef\merkleproofs{\textsf{merkle\_proofs}} -\gdef\TreeRProofs{\textsf{TreeRProofs}} -\gdef\challenges{\textsf{challenges}} -\gdef\pub{\textsf{pub}} -\gdef\priv{\textsf{priv}} -\gdef\last{\textsf{last}} -\gdef\TreeRProofs{\textsf{TreeRProofs}} -\gdef\post{\textsf{post}} -\gdef\SectorID{\textsf{SectorID}} -\gdef\winning{\textsf{winning}} -\gdef\window{\textsf{window}} -\gdef\Replicas{\textsf{Replicas}} -\gdef\P{\mathcal{P}} -\gdef\V{\mathcal{V}} -\gdef\ww{{\textsf{winning}|\textsf{window}}} -\gdef\replicasperk{{\textsf{replicas}/k}} -\gdef\replicas{\textsf{replicas}} -\gdef\Replica{\textsf{Replica}} -\gdef\createvanillapostproof{\textsf{create\_vanilla\_post\_proof}} -\gdef\createpostcircuit{\textsf{create\_post\_circuit}} -\gdef\ReplicaProof{\textsf{ReplicaProof}} -\gdef\aww{{\langle \ww \rangle}} -\gdef\partitionproof{\textsf{partition\_proof}} -\gdef\replicas{\textsf{replicas}} -\gdef\getdrgparents{\textsf{get\_drg\_parents}} -\gdef\getexpparents{\textsf{get\_exp\_parents}} -\gdef\DrgSeed{\textsf{DrgSeed}} -\gdef\DrgSeedPrefix{\textsf{DrgSeedPrefix}} -\gdef\FeistelKeysBytes{\textsf{FeistelKeysBytes}} -\gdef\porep{\textsf{porep}} -\gdef\rng{\textsf{rng}} -\gdef\ChaCha#1{\textsf{ChaCha#1}} -\gdef\cc{\textsf{::}} -\gdef\fromseed{\textsf{from\_seed}} -\gdef\buckets{\textsf{buckets}} -\gdef\meta{\textsf{meta}} -\gdef\dist{\textsf{dist}} -\gdef\each{\textsf{each}} -\gdef\PorepID{\textsf{PorepID}} -\gdef\porepgraphseed{\textsf{porep\_graph\_seed}} -\gdef\utf{\textsf{utf8}} -\gdef\DrgStringID{\textsf{DrgStringID}} -\gdef\FeistelStringID{\textsf{FeistelStringID}} -\gdef\graphid{\textsf{graph\_id}} -\gdef\createfeistelkeys{\textsf{create\_feistel\_keys}} -\gdef\FeistelKeys{\textsf{FeistelKeys}} -\gdef\feistelrounds{\textsf{fesitel\_rounds}} -\gdef\feistel{\textsf{feistel}} -\gdef\ExpEdgeIndex{\textsf{ExpEdgeIndex}} -\gdef\loop{\textsf{loop}} -\gdef\right{\textsf{right}} -\gdef\left{\textsf{left}} -\gdef\mask{\textsf{mask}} -\gdef\RightMask{\textsf{RightMask}} -\gdef\LeftMask{\textsf{LeftMask}} -\gdef\roundkey{\textsf{round\_key}} -\gdef\beencode{\textsf{be\_encode}} -\gdef\Blake{\textsf{Blake2b}} -\gdef\input{\textsf{input}} -\gdef\output{\textsf{output}} -\gdef\while{\textsf{while }} -\gdef\digestright{\textsf{digest\_right}} -\gdef\xor{\mathbin{\oplus_\text{xor}}} -\gdef\Edges{\textsf{ Edges}} -\gdef\edge{\textsf{edge}} -\gdef\expedge{\textsf{exp\_edge}} -\gdef\expedges{\textsf{exp\_edges}} -\gdef\createlabel{\textsf{create\_label}} -\gdef\Label{\textsf{Label}} -\gdef\Column{\textsf{Column}} -\gdef\Columns{\textsf{Columns}} -\gdef\ParentColumns{\textsf{ParentColumns}} -% `\tern` should be written as -% \gdef\tern#1?#2:#3{#1\ \text{?}\ #2 \ \text{:}\ #3} -% but that's not possible due to https://github.com/KaTeX/KaTeX/issues/2288 -\gdef\tern#1#2#3{#1\ \text{?}\ #2 \ \text{:}\ #3} -\gdef\repeattolength{\textsf{repeat\_to\_length}} -\gdef\verifyvanillaporepproof{\textsf{verify\_vanilla\_porep\_proof}} -\gdef\poreppartitions{\textsf{porep\_partitions}} -\gdef\challengeindex{\textsf{challenge\_index}} -\gdef\porepbatch{\textsf{porep\_batch}} -\gdef\winningchallenges{\textsf{winning\_challenges}} -\gdef\windowchallenges{\textsf{window\_challenges}} -\gdef\PorepPartitionProof{\textsf{PorepPartitionProof}} -\gdef\TreeD{\textsf{TreeD}} -\gdef\TreeCProof{\textsf{TreeCProof}} -\gdef\Labels{\textsf{Labels}} -\gdef\porepchallenges{\textsf{porep\_challenges}} -\gdef\postchallenges{\textsf{post\_challenges}} -\gdef\PorepChallengeSeed{\textsf{PorepChallengeSeed}} -\gdef\getporepchallenges{\textsf{get\_porep\_challenges}} -\gdef\getallparents{\textsf{get\_all\_parents}} -\gdef\PorepChallengeProof{\textsf{PorepChallengeProof}} -\gdef\challengeproof{\textsf{challenge\_proof}} -\gdef\PorepChallenges{\textsf{PorepChallenges}} -\gdef\replicate{\textsf{replicate}} -\gdef\createreplicaid{\textsf{create\_replica\_id}} -\gdef\ProverID{\textsf{ProverID}} -\gdef\replicaid{\textsf{replica\_id}} -\gdef\generatelabels{\textsf{generate\_labels}} -\gdef\labelwithdrgparents{\textsf{label\_with\_drg\_parents}} -\gdef\labelwithallparents{\textsf{label\_with\_all\_parents}} -\gdef\createtreecfromlabels{\textsf{create\_tree\_c\_from\_labels}} -\gdef\ColumnDigest{\textsf{ColumnDigest}} -\gdef\encode{\textsf{encode}} -$$ -{{< /plain >}} - -# Stacked DRG Proof of Replication ---- - -## Merkle Proofs - -**Implementation:** -* [`storage_proofs::merkle::MerkleTreeWrapper::gen_proof()`]() -* [`merkle_light::merkle::MerkleTree::gen_proof()`](https://github.com/filecoin-project/merkle_light/blob/64a468807c594d306d12d943dd90cc5f88d0d6b0/src/merkle.rs#L918) - -**Additional Notation:** - -`$\index_l: [\lfloor N_\nodes / 2^l \rfloor] \equiv [\len(\BinTree\dot\layer_l)]$`\ -The index of a node in a `$\BinTree$` layer `$l$`. The leftmost node in a tree has `$\index_l = 0$`. For each tree layer `$l$` (excluding the root layer) a Merkle proof verifier calculates the label of the node at `$\index_l$` from a single Merkle proof path element `$\BinTreeProof_c\dot\path[l - 1] \thin$`. - -### BinTreeProofs - -The method `$\BinTreeProof\dot\createproof$` is used to create a Merkle proof for a challenge node `$c$`. - -```text -$\overline{\underline{\Function \BinTree\dot\createproof(c: \NodeIndex) \rightarrow \BinTreeProof_c}}$ -$\line{1}{\bi}{\leaf: \Safe = \BinTree\dot\leaves[c]}$ -$\line{2}{\bi}{\root: \Safe = \BinTree\dot\root}$ - -$\line{3}{\bi}{\path: \BinPathElement^{[\BinTreeDepth]}= [\ ]}$ -$\line{4}{\bi}{\for l \in [\BinTreeDepth]:}$ -$\line{5}{\bi}{\quad \index_l: [\len(\BinTree\dot\layer_l)] = c \gg l}$ -$\line{6}{\bi}{\quad \missing: \Bit = \index_l \AND 1}$ -$\line{7}{\bi}{\quad \sibling: \Safe = \if \missing = 0:}$ -$\quad\quad\quad \BinTree\dot\layer_l[\index_l + 1]$ -$\quad\quad\thin \else:$ -$\quad\quad\quad \BinTree\dot\layer_l[\index_l - 1]$ -$\line{8}{\bi}{\quad \path\dot\push(\BinPathElement \thin \{\ \sibling, \thin \missing\ \} \thin )}$ - -$\line{9}{\bi}{\return \BinTreeProof_c \thin \{\ \leaf, \thin \root, \thin \path\ \}}$ -``` - -**Code Comments:** -* **Line 5:** Calculates the node index in layer `$l$` of the node that the verifier calculated using the previous lath element (or the `$\BinTreeProof_c\dot\leaf$` if `$l = 0$`). Note that `$c \gg l \equiv \lfloor c / 2^l \rfloor \thin$`. - -### OctTreeProofs - -The method `$\OctTreeProof\dot\createproof$` is used to create a Merkle proof for a challenge node `$c$`. - -**Additional Notation:** - -`$\index_l: [\lfloor N_\nodes / 8^l \rfloor] \equiv [\len(\OctTree\dot\layer_l)]$`\ -The index of a node in an `$\OctTree$` layer `$l$`. The leftmost node in a tree has `$\index_l = 0$`. For each tree layer `$l$` (excluding the root layer) a Merkle proof verifier calculates the label of the node at `$\index_l$` from a single Merkle proof path element `$\OctTreeProof_c\dot\path[l - 1] \thin$`. - -`$\textsf{first\_sibling}_l \thin, \textsf{last\_sibling}: [\lfloor N_\nodes / 8^l \rfloor]$`\ -The node indexes in tree layer `$l$` of the first and last nodes in this layer's Merkle path element's siblings array `$\OctTreeProof_c\dot\path[l]\dot\siblings \thin$`. - -```text -$\overline{\underline{\Function \OctTree\dot\createproof(c: \NodeIndex) \rightarrow \OctTreeProof_c}}$ -$\line{1}{\bi}{\leaf: \Fq = \OctTree\dot\leaves[c]}$ -$\line{2}{\bi}{\root: \Fq = \OctTree\dot\root}$ - -$\line{3}{\bi}{\path: \OctPathElement^{[\OctTreeDepth]}= [\ ]}$ -$\line{4}{\bi}{\for l \in [\OctTreeDepth]:}$ -$\line{5}{\bi}{\quad \index_l: [\len(\OctTree\dot\layer_l)] = c \gg (3 * l)}$ -$\line{6}{\bi}{\quad \missing: [8] = \index_l \MOD 8}$ - -$\line{7}{\bi}{\quad \textsf{first\_sibling}_l = \index_l - \missing}$ -$\line{8}{\bi}{\quad \textsf{last\_sibling}_l = \index_l + (7 - \missing)}$ -$\line{9}{\bi}{\quad \siblings: \Fq^{[7]} =}$ -$\quad\quad\quad \OctTree\dot\layer_l[\textsf{first\_sibling}_l \mathbin{\ldotdot} \index_l]$ -$\quad\quad\quad \|\ \OctTree\dot\layer_l[\index_l + 1 \mathbin{\ldotdot} \textsf{last\_sibling}_l + 1]$ - -$\line{10}{}{\quad \path\dot\push(\OctPathElement \thin \{\ \siblings, \thin \missing\ \} \thin )}$ -$\line{11}{}{\return \OctTreeProof_c \thin \{\ \leaf, \thin \root, \thin \path\ \}}$ -``` - -**Code Comments:** -* **Line 5:** Calculates the node index in layer `$l$` of the node that the verifier calculated themselves using the previous path element (or `$\OctTreeProof_c\dot\leaf$` if `$l = 0$`). Note that `$c \gg (3 * l) \equiv \lfloor c / 8^l \rfloor \thin$`. -* **Line 7-8:** Calculates the indexes in tree layer `$l$` of the first and last (both inclusive) Merkle hash inputs for layer `$l$`'s path element. -* **Line 9:** Copies the 7 Merkle hash inputs that will be in layer `$l$`'s path element `$\OctTreeProof\dot\path[l]\dot\siblings \thin$`. - -### Proof Root Validation - -The functions `$\bintreeproofisvalid$` and `$\octtreeproofisvalid$` are used to verify that a `$\BinTreeProof\dot\path$` or an `$\OctTreeProof\dot\path$` hash to the root found in the Merkle proof `$\BinTreeProof\dot\root$` and `$\OctTreeProof\dot\root$` respectively. - -Note that these functions do not verify that a `$\BinTreeProof\dot\path$` or an `$\OctTreeProof\dot\path$` correspond to the expected Merkle challenge `$c$`. To verify that a proof path is consistent with `$c$`, see the psuedocode functions `$\calculatebintreechallenge$` and `$\calculateocttreechallenge$`. - -**Implementation:** -* [`storage_proofs::core::merkle::proof::SingleProof::verify()`](https://github.com/filecoin-project/rust-fil-proofs/blob/f75804c503d9b97a2b02ef3ea2e5d44e8e2c6470/storage-proofs/core/src/merkle/proof.rs#L540) -* [`storage_proofs::core::merkle::proof::InclusionPath::root()`](https://github.com/filecoin-project/rust-fil-proofs/blob/f75804c503d9b97a2b02ef3ea2e5d44e8e2c6470/storage-proofs/core/src/merkle/proof.rs#L189) - -```text -$\overline{\underline{\Function \bintreeproofisvalid(\proof: \BinTreeProof) \rightarrow \Bool}\thin}$ -$\line{1}{\bi}{\curr: \Safe = \proof\dot\leaf}$ -$\line{2}{\bi}{\for \sibling, \missing \in \proof\dot\path:}$ -$\line{3}{\bi}{\quad \curr: \Safe = \if \missing = 0:}$ -$\quad\quad\quad\quad \Sha{254}_2([\curr, \sibling])$ -$\quad\quad\thin \else:$ -$\quad\quad\quad\quad \Sha{254}_2([\sibling, \curr])$ -$\line{4}{\bi}{\return \curr = \proof\dot\root}$ -``` - -The function `$\octtreeproofisvalid$` can receive as the type of its `$\proof$` argument either an `$\OctTreeProof$` or `$\ColumnProof$` (a `$\ColumnProof$` is just an `$\OctTreeProof$` with an adjoined field `$\column$`, `$\ColumnProof_c \equiv \OctTreeProof_c \cup \column_c \thin$`). - -```text -$\overline{\underline{\Function \octtreeproofisvalid(\proof: \OctTreeProof) \rightarrow \Bool}\thin}$ -$\line{1}{\bi}{\curr: \Fq = \proof\dot\leaf}$ -$\line{2}{\bi}{\for \siblings, \missing \in \proof\dot\path:}$ -$\line{3}{\bi}{\quad \inputs: \Fq^{[8]} = \siblings[\ldotdot \missing] \concat \curr \concat \siblings[\missing \ldotdot]}$ -$\line{4}{\bi}{\quad \curr = \Poseidon_8(\inputs)}$ -$\line{5}{\bi}{\return \curr = \proof\dot\root}$ -``` - -```text -$\overline{\underline{\Function \octtreeproofisvalid(\proof: \ColumnProof) \rightarrow \Bool}\thin}$ -$\line{1}{\bi}{\return \octtreeproofisvalid(\OctTreeProof\ \{\ \leaf, \root, \path \Leftarrow \ColumnProof\ \})}$ -``` - -### Merkle Proof Challenge Validation - -Given a Merkle path `$\path$` in a `$\BinTree$` or `$\OctTree$`, `$\calculatebintreechallenge$` and `$\calculateocttreechallenge$` calculate the Merkle challenge `$c$` for which the Merkle proof `$\path$` was generated. - -Given a Merkle challenge `$c$` and its path in a `$\BinTree$` or `$\OctTree$`, the concatentation of the `$\missing$` bits (or octal digits) in the Merkle path is the little-endian binary (or octal) representation of the integer `$c \thin$`: - -```text -$\line{1}{\bi}{c: \NodeIndex = \langle \text{challenge} \rangle}$ -$\line{2}{\bi}{\BinTreeProof_c = \BinTree\dot\createproof(c)}$ -$\line{3}{\bi}{\OctTreeProof_c = \OctTree\dot\createproof(c)}$ - -$\line{4}{\bi}{\llcorner c \lrcorner_{2, \Le}: \Bit^{[\hspace{1pt} \log_2(N_\nodes) \hspace{1pt}]} = \big\|_{\pathelem \hspace{1pt} \in \hspace{1pt} \BinTreeProof_c\dot\path} \thin \pathelem\dot\missing}$ - -$\line{5}{\bi}{\mathrlap{\llcorner c \lrcorner_{8, \Le}: [8]^{[\hspace{1pt} \log_8(N_\nodes) \hspace{1pt}]}}\hphantom{\llcorner c \lrcorner_{2, \Le}: \Bit^{[\hspace{1pt} \log_2(N_\nodes) \hspace{1pt}]}} = \big\|_{\pathelem \hspace{1pt} \in \hspace{1pt} \BinTreeProof_c\dot\path} \thin \pathelem\dot\missing}$ - -$\line{6}{\bi}{\mathrlap{\llcorner c \lrcorner_{2, \Le}: \Bit^{[\hspace{1pt} \log_2(N_\nodes) \hspace{1pt}]}}\hphantom{\llcorner c \lrcorner_{2, \Le}: \Bit^{[\hspace{1pt} \log_2(N_\nodes) \hspace{1pt}]}} = \big\|_{\pathelem \hspace{1pt} \in \hspace{1pt} \OctTreeProof_c\dot\path} \thin \llcorner \pathelem\dot\missing \lrcorner_{2, \Le}}$ -``` - - -**Implementation:** [`storage_proofs::merkle::MerkleProofTrait::path_index()`](https://github.com/filecoin-project/rust-fil-proofs/blob/f75804c503d9b97a2b02ef3ea2e5d44e8e2c6470/storage-proofs/core/src/merkle/proof.rs#L89) - -**Additional Notation:** - -`$\path = \BinTreeProof\dot\path$`\ -`$\path = \OctTreeProof\dot\path$`\ -The `$\path$` argument is the path field of a `$\BinTreeProof$` or `$\OctTreeProof$`. - -`$c: \NodeIndex$`\ -The challenge corresponding to `$\path$`. - -`$l \in [\BinTreeDepth]$`\ -`$l \in [\OctTreeDepth]$`\ -A path element's layer in a Merkle tree (the layer in the tree that contains the path elements `$\siblings$`). Layer `$l = 0$` is the leaves layer of the tree. Here, values for `$l$` do not include the root layer `$l \neq \BinTreeDepth, \OctTreeDepth \thin$`. - -```text -$\overline{\underline{\Function \calculatebintreechallenge(\path: \BinPathElement^{[\BinTreeDepth]}) \rightarrow c}}$ -$\line{1}{\bi}{\return \sum_{l \in [\BinTreeDepth]}{\path[l]\dot\missing * 2^l}}$ -``` - -```text -$\overline{\underline{\Function \calculateocttreechallenge(\path: \OctPathElement^{[\OctTreeDepth]}) \rightarrow c}}$ -$\line{1}{\bi}{\return \sum_{l \in [\OctTreeDepth]}{\path[l]\dot\missing * 8^l}}$ -``` - -## Stacked Depth Robust Graphs - -Filecoin utilizes the topological properties of depth robust graphs (DRG's) to build a sequential and regeneration resistant encoding scheme. We stack `$N_\layers$` of DRG's, each containing `$N_\nodes$` nodes, on top of one another and connect each adjacent pair of DRG layers via the edges of bipartite expander. The source layer of each expander is the DRG at layer `$l$` and the sink layer is the DRG at layer `$l + 1$`. The resulting graph is termed a Stacked-DRG. - -For every node `$v \in [N_\nodes]$` in the DRG at layer `$l \in [N_\layers]$`, we generate `$d_\drg$` number of DRG parent for `$v$` in layer `$l$`. DRG parents are generated using the [Bucket Sampling algorithm](https://eprint.iacr.org/2017/443.pdf). For every node `$v$` in layers `$l > 0$` we generate `$d_\exp$` number of expander parents for `$v$` where the parents are in layer `$l - 1$`. Expander parents are generated using a psuedorandom permutation (PRP) `$\pi: [N_\nodes] \rightarrow [N_\nodes]$` which maps a node in the DRG layer `$l$` to a node in the the DRG layer `$l - 1$`. The psudeorandom permutation is generated using a `$N_\fesitelrounds$`-round Feistel network whose round function is the keyed hash function `$\Blake$`, where round keys are specified by the constant `$\FeistelKeys$`. - -### DRG - -The function `$\getdrgparents$` are used to generate a node `$v$`'s DRG parents in the Stacked-DRG layer `$l_v \thin$`. The set of DRG parents returned for `$v$` is the same for all PoRep's of the same PoRep version `$\PorepID$`. - -**Implementation:** [`storage_proofs::core::drgraph::BucketGraph::parents()`](https://github.com/filecoin-project/rust-fil-proofs/blob/d15b4307abe384d49ab2ce76b57377204f935cec/storage-proofs/core/src/drgraph.rs#L130) - -**Additional Notation:** - -`$v, u: \NodeIndex$`\ -DRG child and parent node indexes respectively. A DRG child and its parents are in the same Stacked-DRG layer `$l$`. - -`$\mathbf{u}_\drg: \NodeIndex^{[d_\drg]}$`\ -The set of `$v$`'s DRG parents. - -`$v_\meta, u_\meta: [d_\meta * N_\nodes]$`\ -The indexes of `$v$` and `$u$` in the metagraph. - -`$\rng_{\PorepID, v}$`\ -The RNG used to sample `$v$`'s DRG parents. The RNG is seeded with the same bytes `$\DrgSeed_{\PorepID, v}$` every time `$\getdrgparents$` is called for node `$v$` from a PoRep having version `$\PorepID$`. - -`$x \xleftarrow[\rng]{} S$`\ -Samples `$x$` uniformly from `$S$` using the seeded `$\rng$`. - -`$b: [1, N_\buckets + 1]$`\ -The Bucket Sampling bucket index. **Bucket indexes start at 1.** - -`$\dist_{\min, b}$`\ -`$\dist_{\max, b}$`\ -The minimum and maximum parent distances in bucket `$b$`. - -`$\dist_{u_\meta}$`\ -The distance `$u_\meta$` is from `$v_\meta$` in the metagraph. - -```text -$\overline{\underline{\Function \getdrgparents(v: \NodeIndex) \rightarrow \NodeIndex^{[d_\drg]}}}$ -$\line{1}{\bi}{\DrgSeed_{\PorepID, v}: \Byte^{[32]} = \DrgSeed_\PorepID \concat \leencode(v) \as \Byte^{[4]}}$ -$\line{2}{\bi}{\rng_{\PorepID, v} = \ChaCha{8}\cc\fromseed(\DrgSeed_{\PorepID, v})}$ - -$\line{3}{\bi}{\mathbf{u}_\drg: \textsf{NodeIndex}^{[d_\drg]} = [\ ]}$ - -$\line{4}{\bi}{v_\meta = v * d_\textsf{meta}}$ -$\line{5}{\bi}{N_\buckets = \lceil \log_2(v_\meta) \rceil}$ -$\line{6}{\bi}{\for \each \in [d_\meta]:}$ -$\line{7}{\bi}{\quad b \xleftarrow[\rng]{} [1, N_\buckets + 1]}$ -$\line{8}{\bi}{\quad \dist_{\max, b} = \textsf{min}(v_\meta, 2^b)}$ -$\line{9}{\bi}{\quad \dist_{\min, b} = \textsf{max}(d_{\max, b} / 2, 2)}$ -$\line{10}{}{\quad \dist_{u_\meta} \xleftarrow[\rng]{} [\dist_{\min, b} \thin, \dist_{\max, b}]}$ -$\line{11}{}{\quad u_\meta = v_\meta - \dist_{u_\meta}}$ -$\line{12}{}{\quad u: \NodeIndex = \lfloor u_\meta / d_\meta \rfloor}$ -$\line{13}{}{\quad \mathbf{u}_\drg\dot\push(u)}$ - -$\line{14}{}{\mathbf{u}_\drg\dot\push(v - 1)}$ -$\line{15}{}{\return \mathbf{u}_\drg}$ -``` - -### Expander - -The function `$\getexpparents$` is used to generate a node `$v$`'s expander parents in the Stacked-DRG layer `$l_v - 1 \thin$`. The set of expander parents returned for a node `$v$` is the same for all PoRep's of the same version `$\PorepID$`. - -**Implementation:** [`storage_proofs::porep::stacked::vanilla::graph::StackedGraph::generate_expanded_parents()`](https://github.com/filecoin-project/rust-fil-proofs/blob/d15b4307abe384d49ab2ce76b57377204f935cec/storage-proofs/porep/src/stacked/vanilla/graph.rs#L448) - -**Additional Notation:** - -`$v, u: \NodeIndex$`\ -Expander child and parent node indexes respectively. Each expander parent `$u$` is in the Staked-DRG layer `$l - 1$` that precedes the child node `$v$`'s layer `$l$`. - -`$\mathbf{u}_\exp: \NodeIndex^{[d_\exp]}$`\ -The set of `$v$`'s expander parents. - -`$e_l \thin, e_{l - 1}: \ExpEdgeIndex$`\ -The index of an expander edge in the child `$v$`'s layer `$l$` and the parent `$u$`'s layer `$l - 1$` respectively. An expander edge connects edge indexes `$(e_{l - 1}, e_l)$` in adjacent Stacked-DRG layers. - -```text -$\overline{\underline{\Function \getexpparents(v: \NodeIndex) \rightarrow \NodeIndex^{[d_\exp]}}}$ -$\line{1}{\bi}{\mathbf{u}_\exp: \NodeIndex^{[d_\exp]} = [\ ]}$ -$\line{2}{\bi}{\for p\in [d_E]:}$ -$\line{3}{\bi}{\quad e_l = v * d_E + p}$ -$\line{4}{\bi}{\quad e_{l - 1} = \feistel(e_l)}$ -$\line{5}{\bi}{\quad u: \NodeIndex = \lfloor e_{l - 1} / d_\exp \rfloor}$ -$\line{6}{\bi}{\quad \mathbf{u}_\exp\dot\push(u)}$ -$\line{7}{\bi}{\return \mathbf{u}_\exp}$ -``` - -### Feistel Network PRP - -The function `$\feistel$` runs an `$N_\feistelrounds = 4$` round Feistel network as a psuedorandom permutation (PRP) over the set of expander edges `$[d_\exp * N_\nodes] = [2^{33}]$` in a Stacked-DRG layer. - -**Implementation:** [`storage_proofs::core::crypto::feistel::permute()`](https://github.com/filecoin-project/rust-fil-proofs/blob/d15b4307abe384d49ab2ce76b57377204f935cec/storage-proofs/core/src/crypto/feistel.rs#L34) - -**Additional Notation:** - -`$\input, \output$`\ -The Feistel network's input and output blocks respectively. The `$\input$` argument and the returned `$\output$` are guaranteed to be valid `$\u{33}$` expander edge indexes, however their intermediate values may be `$\u{34}$`. - -`$\u{64}_{(17)}$`\ -An unsigned 64-bit integer whose lowest 17 bits are utilized. The integer's 17 least significant bits are used and may be `$0$` or `$1$`, while the integer's 47 most significant bits are `$0$` and are not used. - -`$\left_r, \right_r$`\ -The left and right halves of round `$r$`'s input block. - -`$\left_{r + 1}, \right_{r + 1}$`\ -The left and right halves of the next round's `$r + 1$` input block. - -`$\FeistelKeys_\PorepID$`\ -Is the set of constant round keys associated with the PoRep version `$\PorepID$` that called `$\feistel$`. - -`$\key_r$`\ -Round `$r$`'s key. - -`$\digestright$`\ -The `$\ell_\mask^\bit = 17$` least significant bits of a round's Blake2b `$\digest$`. - -```text -$\overline{\underline{\Function \feistel(\input: \ExpEdgeIndex) \rightarrow \ExpEdgeIndex\ }\thin}$ -$\line{1}{\bi}{\output: \u{64}_{(34)} = \varnothing}$ - -$\line{2}{\bi}{\while \output \notin [N_\expedges]:}$ -$\line{3}{\bi}{\quad \right_r: \u{64}_{(17)} = \input \AND \mathsf{RightMask}}$ -$\line{4}{\bi}{\quad \left_r: \u{64}_{(17)} = (\input \AND \LeftMask) \gg \ell_\mask^\bit}$ - -$\line{5}{\bi}{\quad \for \key_r \in \FeistelKeys_\PorepID:}$ -$\line{6}{\bi}{\quad\quad \preimage: \Byte^{[16]} = \beencode(\right_r) \as \Byte^{[8]} \concat \beencode(\key_r) \as \Byte^{[8]}}$ -$\line{7}{\bi}{\quad\quad \digest: \Byte^{[8]} = \Blake(\preimage)[..8]}$ -$\line{8}{\bi}{\quad\quad \digest: \u{64} = \bedecode(\digest)}$ -$\line{9}{\bi}{\quad\quad \digestright: \u{64}_{(17)} = \digest \AND \RightMask}$ - -$\line{10}{}{\quad\quad \left_{r + 1}: \u{64}_{(17)} = \right_r}$ -$\line{11}{}{\quad\quad \right_{r + 1}: \u{64}_{(17)} = \left_r \xor \digestright}$ - -$\line{12}{}{\quad\quad \left_r, \right_r = \left_{r + 1}, \right_{r + 1}}$ - -$\line{13}{}{\quad \output: \u{64}_{(34)} = (\left_r \ll \ell_\mask^\bit) \OR \right_r}$ -$\line{14}{}{\return \output}$ -``` - -**Code Comments:** -* **Line 1:** Initializes the output of the network to the null value `$\varnothing \thin$`. The value of `$\output$` is a `$34 = 2 * \ell_\mask^\bit$`-bit integer and may not be a valid expander graph edge index after `$N_\feistelrounds$` rounds. -* **Line 2:** The network runs at least once and reruns if `$\output$`'s most significant bit (its 34th bit) is set to `$1$` (`$\output$` is not a valid `$\u{33}$` expander edge index). - -### All Parents - -The function `$\getallparents$` returns a node `$v$`'s set of DRG parents concatenated with its set of expander parents. The set of parents returned for `$v$` is the same across all PoRep's of the same PoRep version `$\PorepID$`. - -```text -$\overline{\underline{\Function \getallparents(v: \NodeIndex) \rightarrow \mathbf{u}_\total}}$ -$\line{1}{\bi}{\return \getdrgparents(v) \concat \getexpparents(v)}$ -``` - -## Labeling - -### Labeling a Node - -The labeling function for every node in a Stacked-DRG is `$\Sha{254}$` producing a 254-bit field element `$\Fqsafe$`. A unique preimage is derived for each node-layer tuple `$(v, l)$` in replica `$\ReplicaID$`'s Stacked-DRG. - -The labeling preimage for the first node `$v_0 = 0$` in every Stacked-DRG layer `$l \in [N_\layers]$` for a replica `$\ReplicaID$` is defined: - -```text -$\bi \preimage_{v_0, l}: \Byte^{[44]} =$ -$\bi\quad\quad \ReplicaID \concat \beencode(l \as \u{32}) \as \Byte^{[4]} \concat \beencode(v_0 \as \u{64}) \as \Byte^{[8]}$ -``` - -The labeling preimage for each node `$v > 0$` in the first layer `$l_0 = 0$` is defined: - -```text -$\bi \preimage_{v, l_0}: \Byte^{[1228]} =$ -$\bi\quad\quad \ReplicaID$ -$\bi\quad\quad \|\ \beencode(l_0 \as \u{32}) \as \Byte^{[4]}$ -$\bi\quad\quad \|\ \beencode(v \as \u{64}) \as \Byte^{[8]}$ -$\bi\quad\quad \big\|_{\Label_{u, l_0} \hspace{1pt} \in \hspace{1pt} \ParentLabels_{\mathbf{u}_\drg}^\star} \Label_{u, l_0} \as \Byte^{[32]} \vphantom{{|^|}^x}$ -``` - -The labeling preimage for each node `$v > 0$` in each layer `$l > 0$` is defined: - -```text -$\bi \preimage_{v, l}: \Byte^{[1228]} =$ -$\bi\quad\quad \ReplicaID$ -$\bi\quad\quad \|\ \beencode(l \as \u{32}) \as \Byte^{[4]}$ -$\bi\quad\quad \|\ \beencode(v \as \u{64}) \as \Byte^{[8]}$ -$\bi\quad\quad \big\|_{\Label_u \hspace{1pt} \in \hspace{1pt} \ParentLabels_{\mathbf{u}_\total}^\star} \Label_u \as \Byte^{[32]} \vphantom{{|^|}^x}$ -``` - -### The Labels Matrix - -The function `$\textsf{generate\_labels}$` describes how every Stacked-DRG node is labeled for a replica. Nodes in the first layer `$l_0 = 0$` are labeled using only DRG parents' labels, nodes in every subsequent layers `$l > 0$` are labeled using both their DRG and expander parents' labels. The first node `$v_0$` in every layer is not labeled using parents. - -**Additional Notation:** - -`$\Labels_R$`\ -Denotes that `$\Labels$` is the labeling for a single replica `$R$`. - -`$l_0 = 0$`\ -The constant `$l_0$` is used to signify the first Stacked-DRG layer. - -`$l_v$`\ -The Stacked-DRG layer in which a node `$v$` resides. - -`$\Label_{v, l_v}$`\ -The label of node `$v$` in the Stacked-DRG layer `$l_v$`. - -`$u_{\langle \drg | \exp \rangle}$`\ -Denotes that parent `$u$` may be a DRG or expander parent. - -`$\Label_{u_\drg}$`\ -The label of a DRG parent (in `$v$`'s layer `$l$`). - -`$\Label_u \equiv \or{\Label_{u_\drg, l_v}}{\Label_{u_\exp, l_v - 1}}$`\ -The label of either a DRG or expander parent (in layer `$l$` or `$l - 1$` respectively). - -```text -$\overline{\underline{\Function \generatelabels(\ReplicaID) \rightarrow \Labels_R}}$ -$\line{1}{\bi}{\Labels: {\Label^{[N_\nodes]}}^{[N_\layers]} -= [\ ]}$ - -$\line{2}{\bi}{\for v \in [N_\nodes]:}$ -$\line{3}{\bi}{\quad \Labels[l_0][v] = \labelwithdrgparents(\ReplicaID, v, \Labels[l_0][..v])}$ - -$\line{4}{\bi}{\for l \in [1, N_\layers - 1]:}$ -$\line{5}{\bi}{\quad \for v \in [N_\mathsf{nodes}]:}$ -$\line{6}{\bi}{\quad\quad \Labels[l][v] = \labelwithallparents(\ReplicaID, l, v, \Labels[l][..v], \Labels[l - 1])}$ - -$\line{7}{\bi}{\return \Labels}$ -``` - -**Code Comments:** -* **Lines 2-3:** Label the first Stacked-DRG layer. -* **Lines 4-6:** Label the remaining Stacked-DRG layers. - -The function `$\labelwithdrgparents$` is used to label a node `$v$` in the first Stacked-DRG layer `$l_0 = 0 \thin$`. - -The label of each node `$v$` in `$l_0$` is dependent on the labels of `$v$`'s DRG parents (where `$v$`'s DRG parents are in layer `$l_v = l_0 \thin$`. `$v$`'s DRG parents always come from the node range `$[v]$` in layer `$l_v$`, thus we pass in the argument `$\Labels[l_0][..v]$` which contains the label of every node up to `$v$` in `$l_0 \thin$`. `$\Labels[l_0][..v]$` is guaranteed to be labeled up to node `$v$` because `$\labelwithdrgparents$` is called sequentially for each node `$v \in [N_\nodes] \thin$`. - -```text -$\overline{\underline{\Function \labelwithdrgparents(\ReplicaID, v: \NodeIndex, \Labels[l_0][..v]) \rightarrow \Label_{v, l_0}}}$ -$\line{1}{\bi}{\preimage: \Byte^{[*]} =}$ -$\quad\quad \ReplicaID \concat \beencode(l_0 \as \u{32}) \as \Byte^{[4]} \concat \beencode(v \as \u{64}) \as \Byte^{[8]}$ - -$\line{2}{\bi}{\if v > 0:}$ -$\line{3}{\bi}{\quad \mathbf{u}_\drg: \textsf{NodeIndex}^{[d_\drg]} = \getdrgparents(v)}$ -$\line{4}{\bi}{\quad \for i \in [N_\parentlabels]:}$ -$\line{5}{\bi}{\quad\quad u_\drg = \mathbf{u}_\drg[i \MOD d_\drg]}$ -$\line{6}{\bi}{\quad\quad \Label_{u_\drg, l_0}: \Fqsafe = \Labels[l_0][u_\drg]}$ -$\line{7}{\bi}{\quad\quad \preimage\dot\extend(\leencode(\Label_{u_\drg, l_0}) \as \Safe)}$ - -$\line{8}{\bi}{\return \Sha{254}(\preimage) \as \Fqsafe}$ -``` - -The function `$\labelwithallparents$` is used to label a node `$v$` in all layers other than the first Stacked-DRG layer `$l_v > 0 \thin$`. - -The label of a node `$v$` in layers `$l_v > 0$` is dependent on both the labels of `$v$`'s DRG and expander parents. `$\labelwithallparents$` takes the argument `$\Labels[l_v][..v]$` (the current layer `$l_v$` being labeled, contains labels up to node `$v$`) to retrieve the labels of `$v$`'s DRG parents and the argument `$\Labels[l_v - 1]$` (the previous layer's labels) to retrieve the labels of `$v$`'s expander parents. - -```text -$\overline{\Function \labelwithallparents(\bi}$ -$\quad \ReplicaID,$ -$\quad l_v \in [1, N_\layers - 1],$ -$\quad v: \NodeIndex,$ -$\quad \Labels[l_v][..v],$ -$\quad \Labels[l_v - 1],$ -$\underline{) \rightarrow \Label_{v, l_v} \qquad\qquad\qquad\qquad\qquad\bi}$ -$\line{1}{\bi}{\preimage: \Byte^{[*]} =}$ -$\quad\quad \ReplicaID \concat \beencode(l_v \as \u{32}) \as \Byte^{[4]} \concat \beencode(v \as \u{64}) \as \Byte^{[8]}$ - -$\line{2}{\bi}{\if v > 0:}$ -$\line{3}{\bi}{\quad \mathbf{u}_\total: \textsf{NodeIndex}^{[d_\total]} = \getallparents(v)}$ -$\line{4}{\bi}{\quad \for i \in [N_\parentlabels]:}$ -$\line{5}{\bi}{\quad\quad p = i \MOD d_\total}$ -$\line{6}{\bi}{\quad\quad u_{\langle \drg | \exp \rangle} = \mathbf{u}_\total[p]}$ -$\line{7}{\bi}{\quad\quad \Label_u: \Fqsafe = \if p < d_\drg}:$ -$\quad\quad\quad\quad \Labels[l_v][u_\drg]$ -$\quad\quad\quad \else:$ -$\quad\quad\quad\quad \Labels[l_v - 1][u_\exp]$ -$\line{8}{\bi}{\quad\quad \preimage\dot\extend(\leencode(\Label_u) \as \Safe)}$ - -$\line{9}{\bi}{\return \Sha{254}(\preimage) \as \Fqsafe}$ -``` - -## Column Commitments - -The column commitment process is used commit to a replica's labeling `$\Labels$`. The column commitment `$\CommC$` is generated by building an `$\TreeC: \OctTree$` over the labeling matrix `$\Labels$` and taking the tree's root. - -To build a tree over the matrix `$\Labels$` we hash each of its `$N_\nodes$` number of columns (where each column contains `$N_\layers$` number of `$\Label$`'s) using the hash function `$\Poseidon_{11}$` producing `$N_\nodes$` number of column digests. The `$i^{th}$` column digest is the `$i^{th}$` leaf in `$\TreeC$`. - -```text -$\overline{\underline{\Function \createtreecfromlabels(\Labels) \rightarrow \TreeC}}$ -$\line{1}{\bi}{\leaves: {\Fq}^{[N_\nodes]} = [\ ]}$ -$\line{2}{\bi}{\for v \in [N_\nodes]:}$ -$\line{3}{\bi}{\quad \column_v: \Fqsafe^{[N_\layers]} = \Labels[:][v]}$ -$\line{4}{\bi}{\quad \digest: \Fq = \Poseidon_{11}(\column_v)}$ -$\line{5}{\bi}{\quad \leaves\dot\push(\digest)}$ -$\line{6}{\bi}{\return \OctTree\cc\new(\leaves)}$ -``` - -## Encoding - -Encoding is the process by which a sector `$D: \Safe^{[N_\nodes]}$` is transformed into its encoding `$R: \Fqsafe^{[N_\nodes]}$`. The encoding function is *node-wise* prime field addition `$\oplus$`, where "node-wise" means that every distinct `$\Safe$` slice `$D_i \in D$` is discretely encoded. - -`$D$` is viewed as an array of `$N_\nodes$` distinct byte arrays `$D_i: \Safe$`. Sector preprocessing ensures that each `$D_i$` is a valid `$\Safe$` (represents a valid 254-bit or less field element `$\Fqsafe)$`. - -```text -$\bi D: \Safe^{[N_\nodes]} = [D_0, \ldots, D_{N_\nodes - 1}]$ -$\bi D_i: \Safe = D[i * 32 \thin\ldotdot\thin (i + 1) * 32]$ -``` - -A unique encoding key `$K$` is derived for every distinct `$\ReplicaID$` via the PoRep labeling process producing `$\Labels$`. Each `$D_i \in D$` is encoded by a distinct encoding key `$K_i \in K$`, where `$K_i$` is `$i^{th}$` node's label in the last Stacked-DRG layer. - -```text -$\bi K: \Label^{[N_\nodes]} = \Labels[N_\layers - 1][:]$ -$\bi K_i: \Label_{i, l_\last} = \Labels[N_\layers - 1][i]$ -``` - -`$D$` is encoded into `$R$` via *node-wise* field addition. Each `$D_i \in D$` is interpreted as a field element and encoded into `$R_i$` by adding `$K_i$` to `$D_i$`. The resulting array of field elements produced via field addition is the encoding `$R$` of `$D$`. - -```text -$\bi R: \Fq^{[N_\nodes]} = [R_0, \ldots, R_{N_\nodes - 1}]$ -$\bi R_i: \Fq = D_i \as \Fqsafe \oplus K_i$ -``` - -The function `$\encode$` is used to encode a sector `$D$` into `$R$` given a an encoding key `$K$` derived from `$R$`'s `$\ReplicaID$`. - -```text -$\overline{\underline{\Function \encode(D: \Safe, K: \Label^{[N_\nodes]}) \rightarrow R}}$ -$\line{1}{\bi}{R: \Fq^{[N_\nodes]} = [\ ]}$ -$\line{2}{\bi}{\for i \in [N_\nodes]:}$ -$\line{3}{\bi}{\quad D_i: \Safe = D[i]}$ -$\line{4}{\bi}{\quad K_i: \Label = K[i]}$ -$\line{5}{\bi}{\quad R_i = D_i \as \Fqsafe \oplus K_i}$ -$\line{6}{\bi}{\quad R\dot\push(R_i)}$ -$\line{7}{\bi}{\return R}$ -``` - -## Replication - -Replication is the entire process by which a sector `$D$` is uniquely encoded into a replica `$R$`. Replication encompasses Stacked-DRG labeling, encoding `$D$` into `$R$`, and the generation of trees `$\TreeC$` over `$\Labels$` and `$\TreeR$` over `$R$`. - -A miner derives a unique `$\ReplicaID$` for each `$R$` using the commitment to the replica's sector `$\CommD = \TreeD\dot\root \thin$` (where `$\TreeD$` is build over the nodes of the unencoded sector `$D$` associated with `$R \thin$`). - -Given a sector `$D$` and its commitment `$\CommD$`, replication proceeds as follows: - -1. Generate the `$R$`'s unique `$\ReplicaID$`. -2. Generate `$\Labels$` from `$\ReplicaID$`, thus deriving the key `$K$` that encodes `$D$` into `$R$`. -3. Generate `$\TreeC$` over the columns of `$\Labels$` via the column commitment process. -4. Encode `$D$` into `$R$` using the encoding key `$K$`. -5. Generate a `$\TreeR: \OctTree$` over the replica `$R$`. -6. Commit to `$R$` and its associated labeling `$\Labels$` via the commitment `$\CommCR$`. - -The function `$\replicate$` runs the entire replication process for a sector `$D$`. - -```text -$\overline{\Function \replicate( \qquad\qquad\qquad\qquad\qquad\quad\bi\ }$ -$\quad D: \Safe^{[N_\nodes]},$ -$\quad \CommD: \Safe,$ -$\quad \SectorID_D: \u{64},$ -$\quad \R_\replicaid: \Byte^{[32]},$ -$\underline{) \rightarrow \ReplicaID, R, \TreeC, \TreeR, \CommCR, \Labels}$ -$\line{1}{\bi}{\ReplicaID = \createreplicaid(\ProverID, \SectorID, \R_\replicaid, \CommD, \PorepID)}$ -$\line{2}{\bi}{\Labels = \generatelabels(\ReplicaID)}$ -$\line{3}{\bi}{\TreeC = \createtreecfromlabels(\Labels)}$ -$\line{4}{\bi}{K: \Label^{[N_\nodes]} = \Labels[N_\layers - 1][:]}$ -$\line{5}{\bi}{R: \Fq^{[N_\nodes]} = \textsf{encode}(D, K)}$ -$\line{6}{\bi}{\TreeR = \OctTree\cc\new(R)}$ -$\line{7}{\bi}{\CommCR: \Fq = \Poseidon_2([\TreeC\dot\root, \TreeR\dot\root])}$ -$\line{8}{\bi}{\return \ReplicaID, R, \TreeC, \TreeR, \CommCR, \Labels}$ -``` - -## ReplicaID Generation - -The function `$\createreplicaid$` describes how a miner having the ID `$\ProverID$` is able to generate a `$\ReplicaID$` for a replica `$R$` of sector `$D$`, where `$D$` has a unique ID `$\SectorID$` and commitment `$\CommD$`. The prover uses a unique random value `$\R_\ReplicaID$` for each `$\ReplicaID$` generated. - -**Implementation:** [`storage_proofs::porep::stacked::vanilla::params::generate_replica_id()`](https://github.com/filecoin-project/rust-fil-proofs/blob/b40b34b5ef7e2a7b8c7e7ea9e574d900728dac45/storage-proofs/porep/src/stacked/vanilla/params.rs#L736) - -```text -$\overline{\Function \createreplicaid(\ }$ -$\quad \ProverID: \Byte^{[32]},$ -$\quad \SectorID: \u{64},$ -$\quad \R_\replicaid: \Byte^{[32]},$ -$\quad \CommD: \Safe,$ -$\quad \PorepID: \Byte^{[32]},$ -$\underline{) \rightarrow \ReplicaID \qquad\qquad\qquad\bi\ }$ -$\line{1}{}{\preimage: \Byte^{[136]} =}$ -$\quad\quad \ProverID$ -$\quad\quad \|\ \beencode(\SectorID) \as \Byte^{[8]}$ -$\quad\quad \|\ \R_\ReplicaID$ -$\quad\quad \|\ \CommD$ -$\quad\quad \|\ \PorepID$ - -$\line{2}{}{\return \Sha{254}(\preimage) \as \Fqsafe}$ -``` - -## Sector Construction - -A sector `$D$` is constructed from Filecoin client data where the aggregating of client data of has been preprocessed/bit-padded such that two zero bits are placed between each distinct 254-bit slice of client data. This padding process results in a sector `$D$` such that every 256-bit slice represents a valid 254-bit field element `$\Safe \thin$`. - -A Merkle tree `$\TreeD: \BinTree$` is constructed for sector `$D$` whose leaves are the 256-bit slices `$D_i: \Safe \in D \thin$`. - -```text -$\bi D_i: \Safe = D[i * 32 \thin\ldotdot\thin (i + 1) * 32]$ -$\bi \TreeD = \BinTree\cc\new([D_0, \ldots, D_{N_\nodes - 1}])$ -$\bi \CommD: \Safe = \TreeD\dot\root$ -``` - -Each `$\TreeD$` is constructed over the preprocessed sector data `$D$`. - -## PoRep Challenges - -The function `$\getporepchallenges$` creates the PoRep challenge set for a replica `$R$`'s partition-`$k$` PoRep partition proof. - -**Implementation:** [`storage_proofs::porep::stacked::vanilla::challenges::LayerChallenges::derive_internal()`](https://github.com/filecoin-project/rust-fil-proofs/blob/c58918b9b2f749a5db40a7952d29a6501c765e13/storage-proofs/porep/src/stacked/vanilla/challenges.rs#L40) - -```text -$\overline{\Function\ \getporepchallenges( \quad}$ -$\quad \ReplicaID,$ -$\quad \R_\porepchallenges: \Byte^{[32]},$ -$\quad k: [N_\poreppartitions],$ -$\underline{) \rightarrow \PorepChallenges_{R, k} \qquad\qquad\qquad}$ -$\line{1}{\bi}{\challenges: \NodeIndex^{[N_{\porepchallenges / k}]} = [\ ]}$ -$\line{2}{\bi}{\for \challengeindex \in [N_\porepchallenges]:}$ -$\line{3}{\bi}{\quad \challengeindex_\porepbatch: \u{32} = k * N_{\porepchallenges / k} + \challengeindex}$ -$\line{4}{\bi}{\quad \preimage: \Byte^{[68]} =}$ -$\quad\quad\quad \leencode(\ReplicaID) \as \Byte^{[32]}$ -$\quad\quad\quad \|\ \R_\porepchallenges$ -$\quad\quad\quad \|\ \leencode(\challengeindex_\porepbatch) \as \Byte^{[4]}$ -$\line{5}{\bi}{\quad \digest: \Byte^{[32]} = \Sha{256}(\preimage)}$ -$\line{6}{\bi}{\quad \digestint: \u{256} = \ledecode(\digest)}$ -$\line{7}{\bi}{\quad c: \NodeIndex \setminus 0 = (\digestint \MOD (N_\nodes - 1)) + 1}$ -$\line{8}{\bi}{\quad \challenges\dot\push(c)}$ -$\line{9}{\bi}{\return \challenges}$ -``` - -## Vanilla PoRep - -### Proving - -A PoRep prover generates a `$\PorepPartitionProof_k$` for each partition `$k$` in a replica `$R$`'s batch of PoRep proofs. Each partition proof is generated for `$N_{\porepchallenges / k}$` number of challenges, the challenge set `$\PorepChallenges_{R, k}$` (each partition proof's challenge set is specific to the replica `$R$` and partition `$k$`). - -A single partition proof generated by a PoRep prover shows that: - -* The prover knows a valid Merkle path for `$c$` in `$\TreeD$` that is consistent with the public `$\CommD$`. -* The prover knows valid Merkle paths for `$c$` in trees `$\TreeC$` and `$\TreeR$` which are consistent with the committed to `$\CommCR$`. -* The prover knows `$c$`'s labeling in each Stacked-DRG layer `$\Column_c = \ColumnProof_c\dot\column \thin$` by hashing `$\Column_c$` into a leaf in `$\TreeC$` that is consistent with `$\CommCR$`. -* For each layer `$l$` in the Stacked-DRG, the prover knows `$c$`'s labeling preimage `$\ParentLabels$` (taken from the columns in `$\ParentColumnProofs$`), such that the parent labels are consistent with `$\CommCR$`. -* The prover knows the key `$K_c$` used to encode `$D_c$` into `$R_c$` (where `$D_c$`, `$K_c$`, and `$R_c$` were already shown to be consistent with the commitments `$\CommD$` and `$\CommCR$`). - -```text -$\overline{\mathbf{Function:}\ \createvanillaporepproof(\ }$ -$\quad k,$ -$\quad \ReplicaID,$ -$\quad \TreeD,$ -$\quad \TreeC,$ -$\quad \TreeR,$ -$\quad \Labels,$ -$\quad \R_\porepchallenges: \Byte^{[32]},$ -$\underline{) \rightarrow \PorepPartitionProof_{R, k} \qquad\qquad\qquad}$ -$\line{1}{\bi}{\PorepPartitionProof_{R, k}: \PorepChallengeProof^{\thin[N_\porepchallenges]} = [\ ]}$ -$\line{2}{\bi}{\PorepChallenges_{R, k} = \getporepchallenges(\ReplicaID, \R_\porepchallenges, k)}$ - -$\line{3}{\bi}{\for c \in \PorepChallenges_{R, k}:}$ -$\line{4}{\bi}{\quad \TreeDProof_c = \TreeD\dot\createproof(c)}$ - -$\line{5}{\bi}{\quad \ColumnProof_c\ \{}$ -$\quad\quad\quad \column: \Labels[:][c],$ -$\quad\quad\quad \leaf,\thin \root,\thin \path \Leftarrow \TreeC\dot\createproof(c),$ -$\quad\quad \}$ - -$\line{6}{\bi}{\quad \TreeRProof_c = \TreeR\dot\createproof(c)}$ - -$\line{7}{\bi}{\quad \ParentColumnProofs_{\mathbf{u}_\total}: \ColumnProof^{[d_\total]} = [\ ]}$ -$\line{8}{\bi}{\quad \mathbf{u}_\total: \NodeIndex^{[d_\total]} = \getallparents(c, \PorepID)}$ -$\line{9}{\bi}{\quad \for u \in \mathbf{u}_\total:}$ -$\line{10}{}{\quad\quad \ColumnProof_u\ \{}$ -$\quad\quad\quad\quad \column: \Labels[:][u],$ -$\quad\quad\quad\quad \leaf,\thin \root,\thin \path \Leftarrow \TreeC\dot\createproof(u),$ -$\quad\quad\quad \}$ -$\line{11}{}{\quad\quad \ParentColumnProofs_{\mathbf{u}_\total}\dot\push(\ColumnProof_u)}$ - -$\line{12}{}{\quad \PorepChallengeProof_c\ \{}$ -$\quad\quad\quad\quad \TreeDProof_c,$ -$\quad\quad\quad\quad \ColumnProof_c,$ -$\quad\quad\quad\quad \TreeRProof_c,$ -$\quad\quad\quad\quad \ParentColumnProofs_{\mathbf{u}_\total},$ -$\quad\quad \}$ -$\line{13}{}{\quad \PorepPartitionProof_{R, k}\dot\push(\PorepChallengeProof_c)}$ -$\line{14}{}{\return \PorepPartitionProof_{R, k}}$ -``` - -### Verification - -**Implementation:** -* [`storage_proofs::porep::stacked::vanilla::proof_scheme::StackedDrg::verify_all_partitions()`](https://github.com/filecoin-project/rust-fil-proofs/blob/c58918b9b2f749a5db40a7952d29a6501c765e13/storage-proofs/porep/src/stacked/vanilla/proof_scheme.rs#L82) -* [`storage_proofs::porep::stacked::vanilla::params::Proof::verify()`](https://github.com/filecoin-project/rust-fil-proofs/blob/447a8ba76da224b8b5f9b7b8dd624ba9a6a107a6/storage-proofs/porep/src/stacked/vanilla/params.rs#L191) - -```text -$\overline{\Function\ \verifyvanillaporepproof(}$ -$\quad \PorepPartitionProof_{R, k} \thin,$ -$\quad k: [N_\poreppartitions],$ -$\quad \ReplicaID,$ -$\quad \CommD,$ -$\quad \CommCR,$ -$\quad \R_\porepchallenges: \Byte^{[32]},$ -$\underline{) \qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad}$ -$\line{1}{\bi}{\PorepChallenges_{R, k} = \getporepchallenges(\ReplicaID, \R_\porepchallenges, k)}$ - -$\line{2}{\bi}{\for i \in [N_{\porepchallenges / k}]}:$ -$\line{3}{\bi}{\quad c = \PorepChallenges_{R, k}[i]}$ -$\line{4}{\bi}{\quad \TreeDProof_c, \ColumnProof_c, \TreeRProof_c, \ParentColumnProofs_{\mathbf{u}_\total}}$ -$\quad\quad\quad \Leftarrow \PorepPartitionProof_{R, k}[i]$ - -$\line{5}{\bi}{\quad \assert(\TreeDProof_c\dot\root = \CommD)}$ - -$\line{6}{\bi}{\quad \CommCR^\dagger = \Poseidon_2([\ColumnProof_c\dot\root, \TreeRProof_c\dot\root])}$ -$\line{7}{\bi}{\quad \assert(\CommCR^\dagger = \CommCR)}$ - -$\line{8}{\bi}{\quad \assert(\calculatebintreechallenge(\TreeDProof_c\dot\path) = c)}$ -$\line{9}{\bi}{\quad \assert(\calculateocttreechallenge(\ColumnProof_c) = c)}$ -$\line{10}{}{\quad \assert(\calculateocttreechallenge(\TreeRProof_c) = c)}$ - -$\line{11}{}{\quad \assert(\bintreeproofisvalid(\TreeDProof_c))}$ -$\line{12}{}{\quad \assert(\octtreeproofisvalid(\ColumnProof_c))}$ -$\line{13}{}{\quad \assert(\octtreeproofisvalid(\TreeRProof_c))}$ - -$\line{14}{}{\quad \assert(\ColumnProof_c.\leaf = \Poseidon_{11}(\ColumnProof_c.\column))}$ - -$\line{15}{}{\quad \mathbf{u}_\total: \NodeIndex^{[d_\total]} = \getallparents(c, \PorepID)}$ -$\line{16}{}{\quad \for p \in [d_\total]:}$ -$\line{17}{}{\quad\quad u = \mathbf{u}_\total[p]}$ -$\line{18}{}{\quad\quad \ColumnProof_u = \ParentColumnProofs_{\mathbf{u}_\total}[p]}$ -$\line{19}{}{\quad\quad \assert(\ColumnProof_u.\root = \ColumnProof_c.\root)}$ -$\line{20}{}{\quad\quad \assert(\calculateocttreechallenge(\ColumnProof_u\dot\path) = u)}$ -$\line{21}{}{\quad\quad \assert(\octtreeproofisvalid(\ColumnProof_u))}$ -$\line{22}{}{\quad\quad \assert(\ColumnProof_u.\leaf = \Poseidon_{11}(\ColumnProof_u.\column))}$ - -$\line{23}{}{\quad \for l \in [N_\layers]:}$ -$\line{24}{}{\quad\quad \calculatedlabel_{c, l} = \createlabel_\V(\ReplicaID, l, c, \ParentColumnProofs_{\mathbf{u}_\total})}$ -$\line{25}{}{\quad\quad \assert(\calculatedlabel_{c, l} = \ColumnProof_c.\column[l])}$ - -$\line{26}{}{\quad D_c = \TreeDProof.\leaf}$ -$\line{27}{}{\quad {R_c}^\dagger = \TreeRProof.\leaf}$ -$\line{28}{}{\quad {K_c}^\dagger = \ColumnProof_c.\column[N_\layers - 1]}$ -$\line{29}{}{\quad \assert({R_c}^\dagger \ominus {K_c}^\dagger = D_c)}$ -``` - -#### Verifier Labeling - -**Implementation:** [`storage_proofs::porep::stacked::vanilla::labeling_proof::LabelingProof::create_label()`](https://github.com/filecoin-project/rust-fil-proofs/blob/447a8ba76da224b8b5f9b7b8dd624ba9a6a107a6/storage-proofs/porep/src/stacked/vanilla/labeling_proof.rs#L27) - -**Additional Notation:** - -`$\createlabel_\V$`\ -Designates the function `$\createlabel$` as being used by a PoRep verifier `$\V$`. - -`$c: \NodeIndex \setminus 0$`\ -The node index of a PoRep challenge. The first node 0 is never challenged in PoRep proofs. - -`$d = \big[ \tern{l_c = 0}{d_\drg}{d_\total \big]}$`\ -The number of parents that challenge `$c$` has (where `$c$` is in the layer `$l_c$`). - -`$\Label_{c, l}^\dagger: \Fqsafe$`\ -The label of the challenge node `$c$` in layer `$l$` calculated from the unverified `$\ParentColumnProofs^\dagger$`. - -`$\Label_{u_\exp, l - 1}: \Fqsafe$`\ -The label of challenge `$c$`'s expander parent `$u_\exp$` in layer `$l - 1$`. Expander parents come from the layer prior to `$c$`'s layer `$l$`. - -`$p_\drg \in [d_\drg]$`\ -$p_\total \in [d_\total]$ -The index of a parent in `$c$`'s parent arrays `$\mathbf{u}_\drg$` and `$\mathbf{u}_\total$` respectively. - -`$u_\drg, u_\exp: \NodeIndex$`\ -The node index of a DRG or expander graph parent for `$c$`. - -`$\parentlabels': \Label^{[N_\parentlabels]}$`\ -The set of parent labels repeated until its length is `$N_\parentlabels$`. - - -```text -$\overline{\Function: \createlabel_\V( \qquad\ }$ -$\quad \ReplicaID,$ -$\quad l: [N_\layers],$ -$\quad c: \NodeIndex \setminus 0,$ -$\quad \ParentColumnProofs_{\mathbf{u}_\total}^\dagger,$ -$\underline{) \rightarrow \Label_{c, l}^\dagger \qquad\qquad\qquad\qquad\quad}$ -$\line{1}{\bi}{\parentlabels: {\Label_u}^{[d]} = [\ ]}$ - -$\line{2}{\bi}{\for p_\drg \in [d_\drg]:}$ -$\line{3}{\bi}{\quad\quad \Label_{u_\drg, l} = \ParentColumnProofs_{\mathbf{u}_\total}[p_\drg]\dot\column[l]}$ -$\line{4}{\bi}{\quad\quad \parentlabels\dot\push(\Label_{u_\drg, l})}$ - -$\line{5}{\bi}{\if l > 0:}$ -$\line{6}{\bi}{\quad \for p_\exp \in [d_\drg, d_\total - 1]:}$ -$\line{7}{\bi}{\quad\quad \Label_{u_\exp, l - 1} = \ParentColumnProofs_{\mathbf{u}_\total}[p_\exp]\dot\column[l - 1]}$ -$\line{8}{\bi}{\quad\quad \parentlabels\dot\push(\Label_{u_\exp, l - 1})}$ - -$\line{9}{\bi}{\parentlabels': \Label^{[N_\parentlabels]} = \parentlabels\dot\repeattolength(N_\parentlabels)}$ - -$\line{10}{}{\preimage: \Byte^{[1228]} =}$ -$\quad\quad \ReplicaID$ -$\quad\quad \|\ \beencode(l \as \u{32}) \as \Byte^{[4]}$ -$\quad\quad \|\ \beencode(c \as \u{64}) \as \Byte^{[8]}$ -$\quad\quad \big\|_{\Label_u \hspace{1pt} \in \hspace{1pt} \parentlabels'} \thin \Label_u \as \Byte^{[32]}$ - -$\line{11}{}{\return \Sha{254}(\preimage) \as \Fq}$ -``` - -## PoRep Circuit - -**Implementation:** -* [`storage_proofs::porep::stacked::circuit::proof::StackedCircuit::synthesize()`](https://github.com/filecoin-project/rust-fil-proofs/blob/master/storage-proofs/porep/src/stacked/circuit/proof.rs#L77) -* [`storage_proofs::porep::stacked::circuit::params::Proof::synthesize()`](https://github.com/filecoin-project/rust-fil-proofs/blob/master/storage-proofs/porep/src/stacked/circuit/params.rs#L77) - -**Additional Notation:** - -`$\PorepPartitionProof_{R, k}$`\ -The `$k^{th}$` PoRep partition proof generated for the replica `$R$`. - -`$\treedleaf_{\auxb, c}$`\ -The circuit value for a challenge `$c$`'s leaf in `$\TreeD$`. - -`$\calculatedcommd_{\auxb, c}$`\ -The circuit value calculated for `$\CommD$` using challenge `$c$`'s `$\TreeDProof_c$`. - -`$\column_{[\auxb], u}$`\ -The array circuit values representing a parent `$u$` of challenge `$c$`'s label in each Stacked-DRG layer. - -`$\parentcolumns_{[[\auxb]], \mathbf{u}_\total}$`\ -An array of an array of circuit values, the allocated column for each parent `$u \in \mathbf{u}_\total \thin$`. - -`$l_c$`\ -The challenge `$c$`'s layer in the Stacked-DRG. - -`$\parentlabelsbits_{[[\auxb + \constb, \lebytes]]}$`\ -An array where each element is a parent `$u$`'s label, an array of allocated and unallocated bits `$_{[\auxb + \constb]}$` having `$\lebytes$` bit order. - -`$\calculatedlabel_{\auxb, c, l}$`\ -The label calculated for challenge `$c$` in residing in layer `$l$`. - -```text -$\overline{\Function \createporepcircuit(}$ -$\quad \PorepPartitionProof_{R, k} \thin,$ -$\quad k,$ -$\quad \ReplicaID,$ -$\quad \CommD,$ -$\quad \CommC,$ -$\quad \CommR,$ -$\quad \CommCR,$ -$\quad \R_\porepchallenges: \Byte^{[32]},$ -$\underline{) \rightarrow \RCS \qquad\qquad\qquad\qquad\qquad}$ -$\line{1}{\bi}{\cs = \RCS\cc\new()}$ - -$\line{2}{\bi}{\replicaid_\pubb: \CircuitVal \deq \cs\dot\publicinput(\ReplicaID)}$ -$\line{3}{\bi}{\replicaidbits_{[\auxb, \Le]}: \CircuitBit^{[255]}\ \deq \lebitsgadget(\cs, \replicaid_\pubb, 255)}$ -$\line{4}{\bi}{\replicaidbits_{[\auxb+\constb, \lebytes]}: \CircuitBitOrConst^{[256]} =}$ -$\quad\quad \lebitstolebytes(\replicaidbits_{[\auxb, \Le]})$ - -$\line{5}{\bi}{\commd_\pubb: \CircuitVal \deq \cs\dot\publicinput(\CommD)}$ -$\line{6}{\bi}{\commcr_\pubb: \CircuitVal \deq \cs\dot\publicinput(\CommCR)}$ - -$\line{7}{\bi}{\commc_\auxb: \CircuitVal \deq \cs\dot\privateinput(\CommC)}$ -$\line{8}{\bi}{\commr_\auxb: \CircuitVal \deq \cs\dot\privateinput(\CommR)}$ - -$\line{9}{\bi}{\calculatedcommcr_\auxb: \CircuitVal\ \deq}$ -$\quad\quad \poseidongadget{2}(\cs, [\commc_\auxb, \thin \commr_\auxb])$ -$\line{10}{}{\cs\dot\assert(\calculatedcommcr_\auxb = \commcr_\pubb)}$ - -$\line{11}{}{\PorepChallenges_k = \getporepchallenges(\ReplicaID, \R_\porepchallenges, k)}$ - -$\line{12}{}{\for i \in [N_\porepchallenges]}:$ -$\line{13}{}{\quad c: \NodeIndex = \PorepChallenges[i]}$ -$\line{14}{}{\quad \TreeDProof_c, \ColumnProof_c, \TreeRProof_c, \ParentColumnProofs_{\mathbf{u}_\total}}$ -$\quad\quad\quad \Leftarrow \PorepPartitionProof[i]$ - -$\line{15}{}{\quad \challengebits_{[\auxb, \Le]}: \CircuitBit^{[64]} \deq \lebitsgadget(\cs, c, 64)}$ -$\line{16}{}{\quad \packedchallenge_\pubb: \CircuitVal\ \deq}$ -$\quad\quad\quad \packbitsasinputgadget(\cs, \challengebits_{[\auxb, \Le]})$ - -$\line{17}{}{\quad \treedleaf_{\auxb, c} \deq \cs\dot\privateinput(\TreeDProof_c\dot\leaf)}$ -$\line{18}{}{\quad \calculatedcommd_{\auxb, c}\ \deq}$ -$\quad\quad\quad \bintreerootgadget(\cs, \treedleaf_{\auxb, c}\thin, \TreeDProof_c\dot\path)$ -$\line{19}{}{\quad \cs\dot\assert(\calculatedcommd_{\auxb, c} = \commd_\pubb)}$ - -$\line{20}{}{\quad \parentcolumns_{[[\auxb]], \mathbf{u}_\total}: {\CircuitVal^{[N_\layers]}}^{[d_\total]} = [\ ]}$ -$\line{21}{}{\quad \for \ColumnProof_u \in \ParentColumnProofs_{\mathbf{u}_\total}:}$ -$\line{22}{}{\quad\quad \column_{[\auxb], u}: \CircuitVal^{[N_\layers]}\ \deq}$ -$\quad\quad\quad\quad [\thin \cs\dot\privateinput(\label_{u, l}) \mid \forall\thin \label_{u, l} \in \ColumnProof_u\dot\column \thin]$ -$\line{23}{}{\quad\quad \calculatedtreecleaf_{\auxb, u}: \CircuitVal \deq \poseidongadget{11}(\cs, \column_{[\auxb], u})}$ -$\line{24}{}{\quad\quad \calculatedcommc_{\auxb, u}: \CircuitVal\ \deq}$ -$\quad\quad\quad\quad \octtreerootgadget(\cs,\thin \calculatedtreecleaf_{\auxb, u},\thin \ColumnProof_u\dot\path)$ -$\line{25}{}{\quad\quad \cs\dot\assert(\calculatedcommc_{\auxb, c} = \commc_\auxb)}$ -$\line{26}{}{\quad\quad \parentcolumns_{[[\auxb]], \mathbf{u}_\total}\dot\push(\column_{[\auxb], u})}$ - -$\line{27}{}{\quad \calculatedcolumn_{[\auxb], c}: \CircuitVal^{[N_\layers]} = [\ ]}$ -$\line{28}{}{\quad \for l_c \in [N_\layers]:}$ -$\line{29}{}{\quad\quad \layerbits_{[\auxb, \Le]}: \CircuitBit^{[32]} \deq \lebitsgadget(\cs, l_c, 32)}$ - -$\line{30}{}{\quad\quad \parentlabels_{[\auxb]}: \CircuitVal^{[*]} = [\ ]}$ -$\line{28}{}{\quad\quad \for p_\drg \in [d_\drg]:}$ -$\line{31}{}{\quad\quad\quad \parentlabel_{\auxb, u_\drg} = \parentcolumns_{[[\auxb]], \mathbf{u}_\total}[p_\drg][l_c]}$ -$\line{32}{}{\quad\quad\quad \parentlabels_{[\auxb]}\dot\push(\parentlabel_{\auxb, u_\drg})}$ -$\line{33}{}{\quad\quad \if l_c > 0:}$ -$\line{34}{}{\quad\quad\quad \for p_\exp \in [d_\drg, d_\total - 1]:}$ -$\line{35}{}{\quad\quad\quad\quad \parentlabel_{\auxb, u_\exp} = \parentcolumns_{[[\auxb]], \mathbf{u}_\total}[p_\exp][l_c - 1]}$ -$\line{36}{}{\quad\quad\quad\quad \parentlabels_{[\auxb]}\dot\push(\parentlabel_{\auxb, u_\exp})}$ - -$\line{37}{}{\quad\quad \parentlabelsbits_{[[\auxb + \constb, \lebytes]]}: {\CircuitBitOrConst^{[256]}}^{[d_\drg\ \text{or}\ d_\exp]} = [\ ]}$ -$\line{38}{}{\quad\quad \for \parentlabel_\auxb \in \parentlabels_{[\auxb]}:}$ -$\line{39}{}{\quad\quad\quad \parentlabelbits_{[\auxb, \Le]}: \CircuitBit^{[255]} \deq}$ -$\quad\quad\quad\quad\quad\quad \lebitsgadget(\cs, \parentlabel_\auxb, 255)$ -$\line{40}{}{\quad\quad\quad \parentlabelbits_{[\auxb + \constb, \lebytes]}: \CircuitBitOrConst^{[256]} =}$ -$\quad\quad\quad\quad\quad\quad \lebitstolebytes(\parentlabelbits_{[\auxb, \Le]})$ -$\line{41}{}{\quad\quad\quad \parentlabelsbits_{[[\auxb + \constb, \lebytes]]}\dot\push(\parentlabelbits_{[\auxb + \constb, \lebytes]})}$ -$\line{42}{}{\quad\quad \parentlabelsbits_{[[\auxb + \constb, \lebytes]]}\dot\repeat(N_\parentlabels)}$ - -$\line{43}{}{\quad\quad \calculatedlabel_{\auxb, c, l}: \CircuitVal \deq \createlabelgadget(}$ -$\quad\quad\quad\quad \cs,$ -$\quad\quad\quad\quad \replicaidbits_{[\auxb + \constb, \lebytes]} \thin,$ -$\quad\quad\quad\quad \layerbits_{[\auxb, \Le]} \thin,$ -$\quad\quad\quad\quad \challengebits_{[\auxb, \Le]},$ -$\quad\quad\quad\quad \parentlabelsbits_{[[\auxb + \constb, \lebytes]]} \thin,$ -$\quad\quad\quad)$ -$\line{44}{}{\quad\quad \calculatedcolumn_{[\auxb], c}\dot\push(\calculatedlabel_{\auxb, c, l})}$ - -$\line{45}{}{\quad \calculatedcommr_{\auxb, c}: \CircuitVal\ \deq}$ -$\quad\quad\quad \octtreerootgadget(\cs,\thin \calculatedtreerleaf_{\auxb, c} \thin, \TreeRProof_c\dot\path)$ -$\line{46}{}{\quad \cs\dot\assert(\calculatedcommr_{\auxb, c} = \commr_\auxb)}$ - -$\line{47}{}{\quad \encodingkey_{\auxb, c}: \CircuitVal = \calculatedcolumn_{[\auxb], c}[N_\layers - 1]}$ -$\line{48}{}{\quad \calculatedtreerleaf_{\auxb, c}: \CircuitVal\ \deq}$ -$\quad\quad\quad \encodegadget(\cs,\thin \treedleaf_{\auxb, c} \thin, \encodingkey_{\auxb, c})$ - -$\line{49}{}{\quad \calculatedtreecleaf_{\auxb, c}: \CircuitVal\ \deq}$ -$\quad\quad\quad \poseidongadget{11}(\cs, \calculatedcolumn_{[\auxb], c})$ -$\line{50}{}{\quad \calculatedcommc_{\auxb, c}: \CircuitVal\ \deq}$ -$\quad\quad\quad \octtreerootgadget(\cs,\thin \calculatedtreecleaf_{\auxb, c} \thin, \ColumnProof_c\dot\path)$ -$\line{51}{}{\quad \cs\dot\assert(\calculatedcommc_{\auxb, c} = \commc_\auxb)}$ - -$\line{52}{}{\return \cs}$ -``` - -**Code Comments:** -* **Lines 9-10:** Computes `$\CommCR^\dagger$` within the circuit from the witnessed commitments and assert that `$\CommCR^\dagger$` is equal to the public input `$\CommCR$`. -* **Lines 15-16:** Adds the packed challenge `$c$` as a public input, used when calculating each challenge `$c$`'s column within the circuit. -* **Lines 17-19:** Verifies `$c$`'s `$\TreeDProof_c$` by computing `$\CommD_c^\dagger$` within the circuit and asserting that it is equal to the public input `$\CommD$`. -* **Lines 20-26:** Allocates each of `$c$`'s parent's `$u \in \mathbf{u}_\total$` label and checks that `$u$`'s `$\ColumnProof_u$` is consistent with the previously verified `$\CommC^\dagger \mapsto \CommC \thin$`. -* **Lines 27-44:** Calculates challenge `$c$`'s label in each Stacked-DRG layer `$l$` within the circuit using each parent's allocated column. -* **Lines 45-46:** Verifies that `$c$`'s `$\TreeRProof_c$` is consistent with the previously verified `$\CommR^\dagger \mapsto \CommR$`. -* **Lines 47-48:** Checks that the calculated encoding key `$K_c^\dagger$` for `$c$` encodes the previously verified sector and replica tree leaves `$D_c^\dagger \mapsto D_c$` into `$R_c^\dagger \mapsto R_c$`. -* **Lines 49-51:** Verifies `$c$`'s `$\ColumnProof_c$` against the previously verified `$\CommC$`. - -## PoSt Challenges - -The function `$\getpostchallenge$` is used to derive a Merkle challenge for a Winning or Window PoSt proof. - -**Implementation:** [`storage_proofs::post::fallback::vanilla::generate_leaf_challenge()`](https://github.com/filecoin-project/rust-fil-proofs/blob/8e8306c942c22571bc784f7536f1704058c45119/storage-proofs/post/src/fallback/vanilla.rs#L214) - -**Additional Notation:** - -`$\R_{\postchallenges, \batch \thin \aww}$`\ -A random value used to derive the challenge set for each of a PoSt prover's partition proofs in their current Winning or Window PoSt proof batch. - -`$\SectorID$`\ -The ID for the sector `$D$` associated with the replica `$R$` for which this Merkle challemnge is being generated. - -`$\challengeindex_\batch$`\ -The unique index of a Merkle challenge across all PoSt partition proofs that a PoSt prover is generating. For all partition proofs in the same PoSt batch, every Merkle challenge across all replicas will have a unique `$\challengeindex_\batch \thin$`. - -```text -$\overline{\Function\getpostchallenge(\qquad\qquad}$ -$\quad \R_{\postchallenges, \batch \thin \aww}: \Fq,$ -$\quad \SectorID: \u{64},$ -$\quad \challengeindex_\batch: \u{64},$ -$\underline{) \rightarrow \NodeIndex \qquad\qquad\qquad\qquad\qquad\quad}$ -$\line{1}{\bi}{\preimage: \Byte^{[48]} =}$ -$\quad\quad \leencode(\R_{\postchallenges, \batch \thin \aww}) \as \Byte^{[32]}$ -$\quad\quad \|\ \leencode(\SectorID) \as \Byte^{[8]}$ -$\quad\quad \|\ \leencode(\challengeindex_\batch) \as \Byte^{[8]}$ - -$\line{2}{\bi}{\digest: \Byte^{[32]} = \Sha{256}(\preimage)}$ -$\line{3}{\bi}{\digestint: \u{64} = \ledecode(\digest[\ldotdot 8])}$ -$\line{4}{\bi}{\return \digestint \MOD N_\nodes}$ -``` - -**Code Comments:** -* **Line 4:** modding by `$N_\nodes$` takes the 64-bit `$\digestint$` to a 32-bit node index `$\NodeIndex$`. - -## Vanilla PoSt - -### Proving - -**Implementation:** -* [`storage_proofs::post::fallback::vanilla::FallbackPoSt::prove()`](https://github.com/filecoin-project/rust-fil-proofs/blob/8e8306c942c22571bc784f7536f1704058c45119/storage-proofs/post/src/fallback/vanilla.rs#L249) - -**Additional Notation:** - -`$\nreplicas_k$`\ -The number of distinct replicas that the prover has for this PoSt partition proof. - -`$\replicaindex_k$`\ -$\replicaindex_\batch$ -The index of a challenged replica `$R$` in a partition `$k$`'s partition proof and the index of the challenged replica across all partition proofs that a prover is generating for batch. - -`$\challengeindex_R$`\ -$\challengeindex_\batch$ -The index of a Merkle challenge in a challenged replica `$R$` and the index of the Merkle challenge across all partition proofs that a prover is generating for batch. - -`$\TreeR_R, \CommC_R, \CommCR_R, \TreeRProofs_R$`\ -The subscript `$_R$` denotes each of these values as being for the replica `$R$` which is distinct within the prover's PoSt batch. - -`$\ell_\pad$`\ -The number of non-distinct `$\PostReplicaProof{\bf \sf s}$` that are added as padding to a PoSt prover's final partition proof in a batch. - -```text -$\overline{\Function \createvanillapostproof(\ }$ -$\quad k: \mathbb{N},$ -$\quad \PostReplicas_{P, k \thin \aww},$ -$\quad N_{\postreplicas / k \thin \aww},$ -$\quad N_{\postchallenges/R \thin \aww},$ -$\quad \R_{\postchallenges \thin \aww}: \Fq,$ -$\underline{) \rightarrow \PostPartitionProof_{k \thin \aww} \qquad}$ -$\line{1}{\bi}{\PostPartitionProof_{k \thin \aww} = [\ ]}$ -$\line{2}{\bi}{\nreplicas_k = \len(\PostReplicas_k)}$ - -$\line{3}{\bi}{\for \replicaindex_k \in [\nreplicas_k]}$ -$\line{4}{\bi}{\quad \TreeR_R, \CommC_R, \SectorID_R \Leftarrow \PostReplicas_k[\replicaindex_k]}$ -$\line{5}{\bi}{\quad \replicaindex_\batch: \u{64} = k * N_{\postreplicas / k} + \replicaindex_k}$ -$\line{6}{\bi}{\quad \TreeRProofs_R: {\TreeRProof}^{\thin[N_{\postchallenges / R}]} = [\ ]}$ -$\line{7}{\bi}{\quad \for \challengeindex_R \in [N_{\postchallenges / R}]:}$ -$\line{8}{\bi}{\quad\quad \challengeindex_\batch: \u{64} =}$ -$\quad\quad\quad\quad \replicaindex_\batch * N_{\postchallenges / R} + \challengeindex_R$ -$\line{9}{\bi}{\quad\quad c = \getpostchallenge(\R_\postchallenges, \SectorID, \challengeindex_\batch)}$ -$\line{10}{}{\quad\quad \TreeRProof_c = \TreeR\dot\createproof(c)}$ -$\line{11}{}{\quad\quad \TreeRProofs\dot\push(\TreeRProof_c)}$ -$\line{12}{}{\quad \PostPartitionProof\dot\push(\PostReplicaProof \{\thin \TreeRProofs,\thin \CommC\thin \})}$ - -$\line{13}{}{\ell_\textsf{pad} = N_{\postreplicas / k} - \nreplicas_k}$ -$\line{14}{}{\for i \in [\ell_\textsf{pad}]}$ -$\line{15}{}{\quad \PostPartitionProof\dot\push(\PostPartitionProof[\nreplicas_k - 1])}$ - -$\line{16}{}{\return \PartitionProof_{k \thin \aww}}$ -``` - -**Code Comments:** -* **Lines 13-15:** If the prover does not have enough replicas to fill an entire PoSt partition proof, pad the partition proof with copies of the last distinct replica's `$\PostReplicaProof_R \thin$`. - -### Verification - -**Implementation:** [`storage_proofs::post::fallback::vanilla::FallbackPoSt::verify_all_partitions()`](https://github.com/filecoin-project/rust-fil-proofs/blob/8e8306c942c22571bc784f7536f1704058c45119/storage-proofs/post/src/fallback/vanilla.rs#L357) - -**Additional Notation:** - -`$k: N_{\postpartitions, \P \thin \aww}$`\ -The number of partitions in a Winning or Window PoSt batch is dependent on the length of the PoSt prover `$\P$`'s replica set. - -`$\nreplicas_k$`\ -The number of distinct replicas that the prover has for this PoSt partition proof. - -`$\replicaindex_k$`\ -`$\replicaindex_\batch$`\ -The index of a challenged replica `$R$` in a partition `$k$`'s partition proofs in a PoSt prover's batch. - -`$\challengeindex_R$`\ -`$\challengeindex_\batch$`\ -The index of a Merkle challenge in a challenged replica `$R$` and the index of the Merkle challenge across all partition proofs in a PoSt prover's batch. - -```text -$\overline{\Function \verifyvanillapostproof( \bi}$ -$\quad \PostPartitionProof_{k \thin \aww},$ -$\quad k: [N_{\postpartitions, \P \thin \aww}],$ -$\quad \PostReplicas_{\V, k \thin \aww},$ -$\quad N_{\postreplicas / k \thin \aww},$ -$\quad N_{\postchallenges / R \thin \aww},$ -$\quad \R_\postchallenges: \Fq,$ -$\underline{) \qquad\qquad\qquad\qquad\qquad\qquad\qquad\quad\bi}$ -$\line{1}{\bi}{\nreplicas_k = \len(\PostReplicas_{\V, k})}$ - -$\line{2}{\bi}{\for \replicaindex_k \in [\nreplicas_k]:}$ -$\line{3}{\bi}{\quad \replicaindex_\batch = k * N_{\postreplicas / k} + \replicaindex_k}$ - -$\line{4}{\bi}{\quad \SectorID, \CommCR \Leftarrow \PostReplicas_{\V, k}[\replicaindex_k]}$ -$\line{5}{\bi}{\quad \CommC^\dagger, \TreeRProofs^\dagger \Leftarrow \PostPartitionProof[\replicaindex_k]}$ -$\line{6}{\bi}{\quad \CommR^\dagger = \TreeRProofs^\dagger[0]\dot\root}$ - -$\line{7}{\bi}{\quad \CommCR^\dagger = \Poseidon{2}([\CommC^\dagger, \CommR^\dagger])}$ -$\line{8}{\bi}{\quad \assert(\CommCR^\dagger = \CommCR)}$ - -$\line{9}{\bi}{\quad \for \challengeindex_R \in [N_{\postchallenges / R}]:}$ -$\line{10}{}{\quad\quad \challengeindex_\batch: \u{64} =}$ -$\quad\quad\quad\quad \replicaindex_\batch * N_{\postreplicas / k} + \challengeindex_R$ -$\line{11}{}{\quad\quad c = \getpostchallenge(\R_\postchallenges, \SectorID, \challengeindex_\batch)}$ - -$\line{12}{}{\quad\quad \TreeRProof^\dagger = \TreeRProofs^\dagger[\challengeindex_R]}$ -$\line{13}{}{\quad\quad \assert(\TreeRProof^\dagger\dot\root = \CommR)}$ -$\line{14}{}{\quad\quad \assert(\calculateocttreechallenge(\TreeRProof^\dagger\dot\path) = c)}$ -$\line{15}{}{\quad\quad \assert(\octtreeproofisvalid(\TreeRProof^\dagger))}$ -``` - -**Code Comments:** -* **Line 13:** The dagger is removed from `$\CommR^\dagger$` (producing `$\CommR$`) because `$\CommR^\dagger$` was verified to be consistent with the committed to `$\CommCR$` (Line 8). - -## PoSt Circuit - -The function `$\createpostcircuit$` is used to instantiate a Winning or Window PoSt circuit. - -**Addional Notation:** - -`$\PostPartitionProof_{k \thin \aww}$`\ -The partition-`$k$` proof in a PoSt prover's Winning or Window PoSt batch. `$\PostPartitionProof_k$` Contains any padded `$\PostReplicaProof{\bf \sf s}$`. - -`$\TreeR_R, \CommC_R, \CommCR_R$`\ -Each `$\PostReplica_R \in \PostReplicas_{\P \thin \aww}$` represents a unique replica `$R$` in the batch denoted by the subscript `$_R \thin$`. - -`$\TreeRProofs_R$`\ -Each `$\TreeRProofs$` is for a distinct replica `$R$`, denoted by the subscript `$_R \thin$`, in a PoSt batch. - -```text -$\overline{\Function \createpostcircuit( \quad\qquad}$ -$\quad \PostPartitionProof_{k \thin \aww},$ -$\quad \PostReplicas_{\P, k \thin \aww},$ -$\quad N_{\postreplicas / k \thin \aww},$ -$\underline{) \rightarrow \RCS \qquad\qquad\qquad\qquad\qquad\qquad\bi}$ -$\line{1}{\bi}{\cs = \RCS\cc\new()}$ -$\line{2}{\bi}{\nreplicas_k = \len(\PostReplicas_{\P, k})}$ - -$\line{3}{\bi}{\for \replicaindex_k \in [\nreplicas_k]:}$ -$\line{4}{\bi}{\quad \TreeR_R, \CommC_R, \CommCR_R \Leftarrow \PostReplicas_{\P, k}[\replicaindex_k]}$ -$\line{5}{\bi}{\quad \TreeRProofs_R \Leftarrow \PostPartitionProof_k[\replicaindex_k]}$ - -$\line{6}{\bi}{\quad \commcr_\pubb: \CircuitVal \deq \cs\dot\publicinput(\CommCR)}$ -$\line{7}{\bi}{\quad \commc_\auxb: \CircuitVal \deq \cs\dot\privateinput(\CommC)}$ -$\line{8}{\bi}{\quad \commr_\auxb: \CircuitVal \deq \cs\dot\privateinput(\CommR)}$ -$\line{9}{\bi}{\quad \calculatedcommcr_\auxb: \CircuitVal\ \deq}$ -$\quad\quad\quad \poseidongadget{2}(\cs, [\commc_\auxb, \thin \commr_\auxb])$ -$\line{10}{}{\quad \cs\dot\assert(\calculatedcommcr_\auxb = \commcr_\pubb)}$ - -$\line{11}{}{\quad \for \TreeRProof_c \in \TreeRProofs:}$ -$\line{12}{}{\quad\quad \treerleaf_{\auxb, c}: \CircuitVal \deq \cs\dot\privateinput(\TreeRProof_c\dot\leaf)}$ -$\line{13}{}{\quad\quad \calculatedcommr_{\auxb, c}: \CircuitVal\ \deq}$ -$\quad\quad\quad\quad \octtreerootgadget(\cs,\thin \treerleaf_{\auxb, c} \thin, \TreeRProof_c\dot\path)$ -$\line{14}{}{\quad\quad \cs\dot\assert(\calculatedcommr_{\auxb, c} = \commr_\auxb)}$ - -$\line{15}{}{\return \cs}$ -``` - -## Gadgets - -### Hash Functions - -We make use of the following hash function gadgets, however their implementation is beyond the scope of this document. - -```text -$\textsf{sha256\_gadget}(\cs: \RCS,\thin \preimage: \CircuitBitOrConst^{[*]}) \rightarrow \CircuitBit^{[256]}$ -$\shagadget{254}{2}(\cs: \RCS,\thin \inputs: \CircuitVal^{[2]}) \rightarrow \CircuitBit^{[254]}$ -$\poseidongadget{2}(\cs: \RCS,\thin \inputs: \CircuitVal^{[2]}) \rightarrow \CircuitVal$ -$\poseidongadget{8}(\cs: \RCS,\thin \inputs: \CircuitVal^{[8]}) \rightarrow \CircuitVal$ -$\poseidongadget{11}(\cs: \RCS,\thin \inputs: \CircuitVal^{[11]}) \rightarrow \CircuitVal$ -``` - -### BinTree Root Gadget - -The function `$\bintreerootgadget$` calculates and returns a `$\BinTree$` Merkle root from an allocated leaf `$\leaf_\auxb$` and an unallocated Merkle `$\path$`. Both the leaf and path are from a Merkle challenge `$c$`'s proof `$\BinTreeProof_c$`, where `$\path = \BinTreeProof_c\dot\path \thin$`. - -The gadget adds one public input to the constraint system for the packed Merkle proof path bits `$\pathbits_\auxle$` which are the binary representation of the `$c$`'s DRG node-index `$\llcorner c \lrcorner_{2, \Le} \equiv \pathbits_\auxle \thin$`). - -```text -$\overline{\Function \bintreerootgadget(\qquad\quad}$ -$\quad \cs: \RCS,$ -$\quad \leaf_\auxb: \CircuitVal,$ -$\quad \path: \BinPathElement^{[\BinTreeDepth]},$ -$\underline{) \rightarrow \CircuitVal \qquad\qquad\qquad\qquad\qquad\quad}$ -$\line{1}{\bi}{\curr_\auxb: \CircuitVal = \leaf_\auxb}$ -$\line{2}{\bi}{\pathbits_{[\auxb, \Le]}: \CircuitBit^{[\BinTreeDepth]} = [\ ]}$ - -$\line{3}{\bi}{\for \sibling, \missing \in \path:}$ -$\line{4}{\bi}{\quad \missingbit_\auxb: \CircuitBit \deq \cs\dot\privateinput(\missing)}$ -$\line{5}{\bi}{\quad \sibling_\auxb: \CircuitVal \deq \cs\dot\privateinput(\sibling)}$ -$\line{6}{\bi}{\quad \inputs_{[\auxb]}: \CircuitVal^{[2]} \deq}$ -$\quad\quad\quad \insertgadget{2}(\cs, [\sibling_\auxb],\thin \curr_\auxb,\thin \missingbit_\auxb)$ -$\line{7}{\bi}{\quad \curr_\auxb: \CircuitVal \deq \shagadget{254}{2}(\cs, \inputs_{[\auxb]})}$ -$\line{8}{\bi}{\quad \pathbits_{[\auxb, \Le]}\dot\push(\missingbit_\auxb)}$ - -$\line{9}{\bi}{\packedchallenge_\pubb: \CircuitVal\ \deq}$ -$\quad\quad \packbitsasinputgadget(\cs, \pathbits_{[\auxb, \Le]})$ - -$\line{10}{}{\return \curr_\auxb}$ -``` - -**Code Comments:** -* **Line 9:** A public input is added to `$\cs$` for the Merkle challenge `$c$` corresponding to the Merkle path which was used to calculate the returned root. -* **Line 10:** The final value for `$\curr_\auxb$` is the Merkle root calculated from `$\leaf_\auxb$` and `$\path$`. - -### OctTree Root Gadget - -The function `$\octtreerootgadget$` calculates and returns an `$\OctTree$` Merkle root from an allocated leaf `$\leaf_\auxb$` and an unallocated Merkle `$\path$`. Both the leaf and path are from a Merkle challenge `$c$`'s proof `$\OctTreeProof_c$`, where `$\path = \OctTreeProof_c\dot\path \thin$`. - -The gadget adds one public input to the constraint system for the packed Merkle proof path bits `$\pathbits_\auxle$` which are the binary representation of the `$c$`'s DRG node-index `$\llcorner c \lrcorner_{2, \Le} \equiv \pathbits_\auxle \thin$`). - -Note that the constant `$3 = \log_2(8)$`, the number of bits required to represent an index in the 8-element Merkle hash `$\inputs$` array, is used at various times in the following algorithm. - -```text -$\overline{\Function \octtreerootgadget( \qquad\quad}$ -$\quad \cs: \RCS,$ -$\quad \leaf_\auxb: \CircuitVal,$ -$\quad \path: \OctPathElement^{[\OctTreeDepth]},$ -$\underline{) \rightarrow \CircuitVal \qquad\qquad\qquad\qquad\qquad\quad}$ -$\line{1}{\bi}{\curr_\auxb: \CircuitVal = \leaf_\auxb}$ -$\line{2}{\bi}{\pathbits_\auxle: \CircuitBit^{[3 * \OctTreeDepth]} = [\ ]}$ - -$\line{3}{\bi}{\for \siblings, \missing \in \path:}$ -$\line{4}{\bi}{\quad \missingbits_\auxle: \CircuitBit^{[3]} = [\ ]}$ -$\line{5}{\bi}{\quad \for i \in [3]:}$ -$\line{6}{\bi}{\quad\quad \bit: \Bit = (\missing \gg i) \AND 1}$ -$\line{7}{\bi}{\quad\quad \bit_\auxb \deq \cs\dot\privateinput(\bit)}$ -$\line{8}{\bi}{\quad\quad \missingbits_\auxle\dot\push(\bit_\auxb)}$ - -$\line{9}{\bi}{\quad \siblings_{[\auxb]}: \CircuitVal^{[7]} = [\ ]}$ -$\line{10}{}{\quad \for \sibling \in \siblings:}$ -$\line{11}{}{\quad\quad \sibling_\auxb: \CircuitVal \deq \cs\dot\privateinput(\sibling)}$ -$\line{12}{}{\quad\quad \siblings_{[\auxb]}\dot\push(\sibling_\auxb)}$ - -$\line{13}{}{\quad \inputs_{[\auxb]}: \CircuitVal^{[8]}\thin \deq}$ -$\quad\quad\quad \insertgadget{8}(\cs, \siblings_{[\auxb]},\thin \curr_\auxb,\thin \missingbits_\auxle)$ -$\line{14}{}{\quad \curr_\auxb: \CircuitVal \deq \poseidongadget{8}(\cs, \inputs_{[\auxb]})}$ -$\line{15}{}{\quad \pathbits_\auxle\dot\extend(\missingbits_\auxle)}$ - -$\line{16}{}{\packedchallenge_\pubb: \CircuitVal\ \deq}$ -$\quad\quad \packbitsasinputgadget(\cs, \pathbits_{[\auxb, \Le]})$ - -$\line{17}{}{\return \curr_\auxb}$ -``` - -**Code Comments:** -* **Line 1:** Not a reallocation of `$\leaf_\auxb$` within `$\cs$`, but is an in-memory copy. -* **Lines 4-8:** Witnesses the 3-bit missing index for each path element. The first iteration `$i = 0$` corresponds to the least significant bit in `$\missing$`. -* **Lines 9-12:** Witnesses each path element's 7 Merkle hash inputs (the exlucded 8-th Merkle hash input is the calculated hash input `$\curr_\auxb$` for this tree depth). -* **Line 13:** Creates the Merkle hash inputs array by inserting `$\curr$` into `$\siblings$` at index `$\missing$`. -* **Line 14:** Hashes the 8 Merkle hash inputs. -* **Line 16:** Adds the challenge `$c$` as a public input. -* **Line 17:** Returns the calculated root. - -### Encoding Gadget - -The function `$\encodegadget$` runs the `$\encode$` function within a circuit. Used to encode `$\unencoded_{\auxb, v}$` (node `$v$`'s sector data `$D_v$`) into `$\encoded_{\auxb, v}$` (the replica node `$R_v$`) given an allocated encoding key `$\key_{\auxb, v}$` (`$K_v$`). - -**Implementation:** [`storage_proofs::core::gadgets::encode::encode()`](https://github.com/filecoin-project/rust-fil-proofs/blob/3cc8b5acb742d1469e10949fadc389806fa19c8c/storage-proofs/core/src/gadgets/encode.rs#L7) - -```text -$\overline{\Function \encodegadget(\qquad}$ -$\quad \cs: \RCS,$ -$\quad \unencoded_{\auxb, v}: \CircuitVal,$ -$\quad \key_{\auxb, v}: \CircuitVal,$ -$\underline{) \rightarrow \CircuitVal \qquad\qquad\qquad\qquad}$ -$\line{1}{\bi}{R_v: \Fq = \unencoded_{\auxb, v}\dot\value \oplus \key_{\auxb, v}\dot\value}$ -$\line{2}{\bi}{\encoded_{\auxb, v}: \CircuitVal \deq \cs\dot\privateinput(R_v)}$ -$\line{3}{\bi}{\lc_A: \LinearCombination \equiv \unencoded_{\auxb, v} + \key_{\auxb, v}}$ -$\line{4}{\bi}{\lc_B: \LinearCombination \equiv \cs\dot\one_\pubb}$ -$\line{5}{\bi}{\lc_C: \LinearCombination \equiv \encoded_{\auxb, v}}$ -$\line{6}{\bi}{\cs\dot\assert(\lc_A * \lc_B = \lc_C)}$ -$\line{7}{\bi}{\return \encoded_{\auxb, v}}$ -``` - -### Labeling Gadget - -The function `$\createlabelgadget$` is used to label a node `$\node$` in the Stacked-DRG layer `$\layerindex$` given the node's expanded parent labels `$\parentlabels$`. - -**Implementation:** [`storage_proofs::porep::stacked::circuit::create_label::create_label_circuit()`](https://github.com/filecoin-project/rust-fil-proofs/blob/3cc8b5acb742d1469e10949fadc389806fa19c8c/storage-proofs/porep/src/stacked/circuit/create_label.rs#L10) - -**Additional Notation:** - -`$\replicaid_{[\auxb + \constb, \lebytes]}$`\ -The allocated bits (and constant zero bit(s)) representing a `$\ReplicaID$`. - -`$\layerindex_{[\auxb, \Le]}$`\ -The allocated bits representing a layer `$l \in [N_\layers]$` as an unsigned 32-bit integer. - -`$\node_{[\auxb, \Le]}$`\ -A node index `$v \in [N_\nodes]$` allocated as 64 bits. - -`$\parentlabels_{[[\auxb + \constb, \lebytes]]}$`\ -An array containing `$N_\parentlabels$` allocated bit arrays, where each bit array is the label of one of `$\node$`'s parents. - -`$\label$`\ -Is the calculated label for `$\node$`. - -```text -$\overline{\Function \createlabelgadget( \qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\ }$ -$\quad \cs: \RCS,$ -$\quad \replicaid_{[\auxb + \constb, \lebytes]}: \CircuitBitOrConst^{[256]} \thin,$ -$\quad \layerindex_{[\auxb, \Le]}: \CircuitBit^{[32]} \thin,$ -$\quad \node_{[\auxb, \Le]}: \CircuitBit^{[64]} \thin,$ -$\quad \parentlabels_{[[\auxb + \constb, \lebytes]]}: {\CircuitBitOrConst^{[256]}}^{[N_\parentlabels]} \thin,$ -$\underline{) \rightarrow \CircuitVal \qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad}$ -$\line{1}{\bi}{\layerindex_{[\auxb, \be]}: \CircuitBit^{[32]} = \reverse(\layerindex_{[\auxb, \Le]})}$ -$\line{2}{\bi}{\nodeindex_{[\auxb, \be]}: \CircuitBit^{[64]} = \reverse(\node_{[\auxb, \Le]})}$ -$\line{3}{\bi}{\preimage_{[\auxb + \constb]}: \CircuitBitOrConst^{[9984]} =}$ -$\quad\quad \replicaid_{[\auxb + \constb, \lebytes]}$ -$\quad\quad \|\ \layerindex_{[\auxb, \be]}$ -$\quad\quad \|\ \nodeindex_{[\auxb, \be]}$ -$\quad\quad \|\ 0^{[160]}$ -$\quad\quad \big\|_{\parentlabel \hspace{1pt} \in \hspace{1pt} \parentlabels} \thin \parentlabel_{[\auxb + \constb, \lebytes]} \vphantom{{{|^|}^|}^x}$ - -$\line{4}{\bi}{\digestbits_{[\auxb, \lebytes]}: \CircuitBit^{[256]} \deq \textsf{sha256\_gadget}(\cs, \preimage_{[\auxb + \constb]})}$ -$\line{5}{\bi}{\digestbits_{[\auxb, \Le]}: \CircuitBit^{[256]} = \lebytestolebits(\digestbits_{[\auxb, \lebytes]})}$ -$\line{6}{\bi}{\digestbits_{[\auxb, \Le], \safe}: \CircuitBit^{[254]} = \digestbits_{[\auxb, \Le]}[0 \thin\ldotdot\thin 254]}$ -$\line{7}{\bi}{\label = \digestbits_{[\auxb, \Le], \safe} \thin\as\thin \Fqsafe}$ -$\line{8}{\bi}{\label_\auxb: \CircuitVal \deq \cs\dot\privateinput(\label)}$ - -$\line{9}{\bi}{\lc: \LinearCombination \equiv \sum_{i \in [254]}{2^i * \digestbits_{[\auxb, \Le], \safe}[i]}}$ -$\line{10}{}{\cs\dot\assert(\lc = \label_\auxb)}$ - -$\line{11}{}{\return \label_\auxb}$ -``` - -**Code Comments:** -* **Line 3:** The constant `$9984 = (2 + N_\parentlabels) * \ell_\block^\bit = (2 + 37) * 256 \thin$`. The constant `$160 = \ell_\block^\bit - \len(\layerindex) - \len(\nodeindex) = 256 - 32 - 64 \thin$`. -* **Lines 4-5:** The constant `$256 = \ell_\block^\bit \thin$`. -* **Lines 5-6:** These are not reallocations. -* **Lines 6-7:** The labeling function is `$\Sha{254}$` not `$\Sha{256}$`. -* **Lines 6,9:** The constant `$254 = \ell_{\Fq, \safe}^\bit \thin$`. - -### Little-Endian Bits Gadget - -The function `$\lebitsgadget$` receives a value `$\value$` allocated within a constraint system `$\cs$` and reallocates it as its `$n$`-bit little-endian binary representation. - -Note that the number of bits returned must be at least the number of bits required to represent `$\value$`: `$0 < \lceil \log_2(\value\dot\int) \rceil \leq n \thin$`. - -**Implementation:** [`bellman::gadgets::num::AllocatedNum::to_bits_le()`](https://github.com/filecoin-project/bellman/blob/e0ac6b879eac87832ba6ef2e37320e877d1d96b6/src/gadgets/num.rs#L193) - -```text -$\overline{\Function \lebitsgadget(}$ -$\quad \cs: \RCS,$ -$\quad \value_{\langle \auxb | \pubb \rangle}: \CircuitVal,$ -$\quad n: \mathbb{Z}^+,$ -$\underline{) \rightarrow \CircuitBit^{[n]} \qquad\quad}$ -$\line{1}{\bi}{\assert(n \geq \lceil \log_2(\value\dot\int) \rceil)}$ - -$\line{2}{\bi}{\bits_\Le: \Bit^{[n]} = \llcorner \value_{\langle \auxb | \pubb \rangle}\dot\int \lrcorner_{2, \Le}}$ -$\line{3}{\bi}{\bits_{[\auxb, \Le]}: \CircuitBit^{[n]} = [\ ]}$ -$\line{4}{\bi}{\for \bit \in \bits_\Le:}$ -$\line{5}{\bi}{\quad \bit_\auxb: \CircuitBit \overset{\diamond}{=} \cs\dot\privateinput(\bit)}$ -$\line{6}{\bi}{\quad \bits_{[\auxb, \Le]}\dot\push(\bit_\auxb)}$ - -$\line{7}{\bi}{\lc: \LinearCombination \equiv \sum_{i \in [n]}{2^i * \bits_{[\auxb, \Le]}[i]}}$ -$\line{8}{\bi}{\cs\dot\assert(\value_{\langle \auxb | \pubb \rangle} = \lc)}$ - -$\line{9}{\bi}{\return \bits_{[\auxb, \Le]}}$ -``` - -**Code Comments:** -* **Line 2:** This will pad `$n - \lceil \log_2(\value\dot\int) \rceil$` zero bits onto the most significant end of `$\llcorner \int \lrcorner_{2, \Le} \thin$`. - -### Pack Bits as Input Gadget - -The function `$\packbitsasinputgadget$` receives an array of `$n$` allocated little-endian bits `$\bits_{[\auxb, \Le]}$`, where `$0 < n \leq \ell_\Fqsafe^\bit \thin$`, and creates the field element `$\packed$` whose little-endian binary representation is that of `$\bits$`. The gadget adds one public input `$\packed_\pubb$` to the constraint system for the created field element. - -```text -$\overline{\Function \packbitsasinputgadget(}$ -$\quad \cs: \RCS,$ -$\quad \bits_{[\auxb, \Le]}: \CircuitBit^{[n]},$ -$\underline{) \rightarrow \CircuitVal \qquad\qquad\qquad\qquad\qquad\quad}$ -$\line{1}{\bi}{\assert(0 < n \leq \ell_\Fqsafe^\bit)}$ -$\line{2}{\bi}{\packed: \Fq = \bits_{[\auxb, \Le]} \as \Fq}$ -$\line{3}{\bi}{\packed_\pubb \overset{\diamond}{=} \cs\dot\publicinput(\packed)}$ -$\line{4}{\bi}{\lc: \LinearCombination \equiv \sum_{i \in [n]}{2^i * \bits_{[\auxb, \Le]}[i]}}$ -$\line{5}{\bi}{\cs\dot\assert(\lc = \packed_\pub)}$ -$\line{6}{\bi}{\return \packed_\pubb}$ -``` - -### Pick Gadget - -The `$\pickgadget$` is used to choose one of two allocated values, `$\x$` and `$\y$`, based upon the value of a binary condition `$\bit$`. - -If `$\bit$` is set, the gadget will reallocate and return `$\x$`, otherwise if `$\bit$` is not set, the gadget will reallocate and return `$\y$`. - -The `$\pickgadget$`, when given two allocated values `$\x, \y \in \Fq$` and an allocated boolean constrained value `$\bit \in \Bit$`, outputs the allocated value `$\pick \in \{ \x, \y \}$` and adds the `$\RCS$` quadratic constraint: - -$\bi (\y - \x) * (\bit) = (\y - \pick)$ - -This table shows that for `$\bit \in \Bit$` and `$\x, \y \in \Fq$` that the constraint is satisfied for the outputted values of `$\pick$`. - -| `$\bit$` | `$\pick$` | `$(\y - \x) * (\bit) = (\y - \pick)$` | -|--------|---------|------------------------------------| -| `$1$` | `$\x$` | `$(\y-\x) * (1) = (\y-\x)$` | -| `$0$` | `$\y$` | `$(\y-\x) * (0) = (\y-\y)$` | - -```text -$\overline{\Function \pickgadget( \qquad\quad\bi}$ -$\quad \cs: \RCS,$ -$\quad \bit_\aap: \CircuitBit,$ -$\quad \x_\aap: \CircuitVal,$ -$\quad \y_\aap: \CircuitVal,$ -$\underline{) \rightarrow \CircuitVal \qquad\qquad\qquad\qquad}$ -$\line{1}{\bi}{\pick_\auxb: \CircuitVal \deq \if \bit_\aap\dot\int = 1:}$ -$\quad\quad \cs\dot\privateinput(\x_\aap)$ -$\quad\else:$ -$\quad\quad \cs\dot\privateinput(\y_\aap)$ - -$\line{2}{\bi}{\lc_A: \LinearCombination \equiv \y_\aap - \x_\aap}$ -$\line{3}{\bi}{\lc_B: \LinearCombination \equiv \bit_\aap}$ -$\line{4}{\bi}{\lc_C: \LinearCombination \equiv \y_\aap - \pick_\auxb}$ -$\line{5}{\bi}{\cs\dot\assert(\lc_A * \lc_B = \lc_C)}$ - -$\line{6}{\bi}{\return \pick_\auxb}$ -``` - -### Insert-2 Gadget - -The `$\insertgadget{2}$` inserts `$\value$` into an array `$\arr$` at index `$\index$` and returns the inserted array of reallocated elements. - -The gadget receives an array containing one allocated element `$\arr[0]$` and a second allocated value `$\value$` and returns the two element array containing the reallocations of the two values where the index of the reallocated `$\value$` is at the index `$\index$` argument in the returned 2-element array. - -```text -$\overline{\Function \insertgadget{2}(\qquad\qquad\bi}$ -$\quad \cs: \RCS,$ -$\quad \arr_\aap: \CircuitVal^{[1]},$ -$\quad \value_\aap: \CircuitVal,$ -$\quad \index_\auxb: \CircuitBitOrConst,$ -$\underline{) \rightarrow \CircuitVal^{[2]} \qquad\qquad\qquad\qquad\qquad}$ -$\line{1}{\bi}{\el_{\auxb, 0}: \CircuitVal \deq \pickgadget(\cs,\thin \index_\auxb,\thin \arr_\aap[0] \thin,\thin \value_\aap \thin)}$ -$\line{2}{\bi}{\el_{\auxb, 1}: \CircuitVal \deq \pickgadget(\cs, \index_\auxb,\thin \value_\aap \thin,\thin \arr_\aap[0] \thin)}$ -$\line{3}{\bi}{\return [\el_{\auxb, 0}, \el_{\auxb, 1}]}$ -``` - -### Insert-8 Gadget - -The function `$\insertgadget{8}$` inserts a value `$\value$` into an array of 7 elements `$\arr$` at index in the 8 element array given by `$\indexbits$`. The values returned in the 8-element array are reallocations of `$\arr$` and `$\value$`. - -**Implementation:** [`storage_proofs::core::gadgets::insertion::insert_8()`](https://github.com/filecoin-project/rust-fil-proofs/blob/b9126bf56cfd2c73ce4ce1f6cb46fe001450f326/storage-proofs/core/src/gadgets/insertion.rs#L170) - -Note that the length of the `$\indexbits$` argument is `$3 = \log_2(8)$` bits, which is the number of bits required to represent an index in an array of 8 elements. - -**Additional Notation:** - -`$\arr'$`\ -The inserted array containing 8 reallocated values, the elements of the uninserted array `$\arr$` and the insertion value `$\value$`. - -`$\nor_{\auxb \thin (b_0, b_1)}$`\ -Set to true if neither `$\indexbits[0]$` nor `$\indexbits[1]$` are `$1$`. - -`$\and_{\auxb \thin (b_0, b_1)}$`\ -Set to true if both `$\indexbits[0]$` and `$\indexbits[1]$` are `$1$`. - -```text -$\pick_{\auxb, i(b_0)}$ -$\pick_{\auxb, i(b_0, b_1)}$ -$\pick_{\auxb, i(b_0, b_1, b_2)}$ -``` -The pick for the `$i^{th}$` element of the inserted array based upon the value of the first bit (least-significant), first and second bits, and the first, second and third bits respectively. - -```text -$b_i \equiv \indexbits_{[\aap, \Le]}[i]$ -$\pick_{i(b_0)} \equiv \pick_{\auxb, i(b_0)}$ -$\nor_{(b_0, b_1)} \equiv \nor_{\auxb \thin (b_0, b_1)}$ -$\and_{(b_0, b_1)} \equiv \and_{\auxb \thin (b_0, b_1)}$ -$\arr[i] \equiv \arr_{[\aap]}[i]$ -$\arr'[i] \equiv \arr'_{[\auxb]}[i]$ -``` -For ease of notation the subscripts `$_\auxb$` and `$_\aap$` are left off everywhere except in the function signature and when allocating of a value within the circuit. - -```text -$\overline{\Function \insertgadget{8}( \qquad\qquad\qquad\qquad\qquad\quad}$ -$\quad \cs: \RCS,$ -$\quad \arr_{[\aap]}: \CircuitVal^{[7]},$ -$\quad \value_\aap: \CircuitVal,$ -$\quad \indexbits_{[\aap, \Le]}: \CircuitBitOrConst^{[3]},$ -$\underline{) \rightarrow \CircuitVal^{[8]} \qquad\qquad\qquad\qquad\qquad\qquad\qquad\qquad\bi}$ -$\line{1}{\bi}{\nor_{(b_0, b_1)}: \CircuitBit \deq \norgadget(\cs,\thin b_0 \thin,\thin b_1)}$ -$\line{2}{\bi}{\and_{\auxb \thin (b_0, b_1)}: \CircuitBit \deq \andgadget(\cs,\thin b_0 \thin,\thin b_1)}$ - -$\line{3}{\bi}{\arr'_{[\auxb]}: \CircuitVal^{[8]} = [\ ]}$ - -$\line{4}{\bi}{\pick_{\auxb, 0(b_0, b_1)}: \CircuitVal \deq \pickgadget(\cs,\thin \nor_{(b_0, b_1)},\thin \value,\thin \arr[0])}$ -$\line{5}{\bi}{\pick_{\auxb, 0(b_0, b_1, b_3)}: \CircuitVal \deq \pickgadget(\cs,\thin b_2,\thin \arr[0],\thin \pick_{0(b_0, b_1)})}$ -$\line{6}{\bi}{\arr'[0] = \pick_{0(b_0, b_1, b_3)}}$ - -$\line{7}{\bi}{\pick_{\auxb, 1(b_0)}: \CircuitVal \deq \pickgadget(\cs,\thin b_0,\thin \value,\thin \arr[0])}$ -$\line{8}{\bi}{\pick_{\auxb, 1(b_0, b_1)}: \CircuitVal \deq \pickgadget(\cs,\thin b_1,\thin \arr[1],\thin \pick_{1(b_0)})}$ -$\line{9}{\bi}{\pick_{\auxb, 1(b_0, b_1, b_3)}: \CircuitVal \deq \pickgadget(\cs,\thin b_2,\thin \arr[1],\thin \pick_{1(b_0, b_1)})}$ -$\line{10}{}{\arr'[1] = \pick_{1(b_0, b_1, b_3)}}$ - -$\line{11}{}{\pick_{\auxb, 2(b_0)}: \CircuitVal \deq \pickgadget(\cs,\thin b_0,\thin \arr[2],\thin \value)}$ -$\line{12}{}{\pick_{\auxb, 2(b_0, b_1)}: \CircuitVal \deq \pickgadget(\cs,\thin b_1,\thin \pick_{2(b_0)},\thin \arr[1])}$ -$\line{13}{}{\pick_{\auxb, 2(b_0, b_1, b_2)}: \CircuitVal \deq \pickgadget(\cs,\thin b_2,\thin \arr[2],\thin \pick_{2(b_0, b_1)})}$ -$\line{14}{}{\arr'[2] = \pick_{2(b_0, b_1, b_3)}}$ - -$\line{15}{}{\pick_{\auxb, 3(b_0, b_1)}: \CircuitVal \deq \pickgadget(\cs, \thin \and_{(b_0, b_1)}, \thin \value, \thin \arr[2])}$ -$\line{16}{}{\pick_{\auxb, 3(b_0, b_1, b_2)}: \CircuitVal \deq \pickgadget(\cs, \thin b_2, \thin \arr[3], \thin \pick_{3(b_0, b_1)})}$ -$\line{17}{}{\arr'[3] = \pick_{3(b_0, b_1, b_3)}}$ - -$\line{18}{}{\pick_{\auxb, 4(b_0, b_1)}: \CircuitVal \deq \pickgadget(\cs, \thin \nor_{(b_0, b_1)}, \thin \value, \thin \arr[4])}$ -$\line{19}{}{\pick_{\auxb, 4(b_0, b_1, b_2)}: \CircuitVal \deq \pickgadget(\cs, \thin b_2, \thin \pick_{4(b_0, b_1)}, \thin \arr[3])}$ -$\line{20}{}{\arr'[4] = \pick_{4(b_0, b_1, b_3)}}$ - -$\line{21}{}{\pick_{\auxb, 5(b_0)}: \CircuitVal \deq \pickgadget(\cs, \thin b_0, \thin \value, \thin \arr[4])}$ -$\line{22}{}{\pick_{\auxb, 5(b_0, b_1)}: \CircuitVal \deq \pickgadget(\cs, \thin b_1, \thin \arr[5], \thin \pick_{5(b_0)})}$ -$\line{23}{}{\pick_{\auxb, 5(b_0, b_1, b_2)}: \CircuitVal \deq \pickgadget(\cs, \thin b_2, \thin \pick_{5(b_0, b_1)}, \thin \arr[4])}$ -$\line{24}{}{\arr'[5] = \pick_{5(b_0, b_1, b_3)}}$ - -$\line{25}{}{\pick_{\auxb, 6(b_0)}: \CircuitVal \deq \pickgadget(\cs, \thin b_0, \thin \arr[6], \thin \value)}$ -$\line{26}{}{\pick_{\auxb, 6(b_0, b_1)}: \CircuitVal \deq \pickgadget(\cs, \thin b_1, \thin \pick_{6(b_0)}, \thin \arr[5])}$ -$\line{27}{}{\pick_{\auxb, 6(b_0, b_1, b_2)}: \CircuitVal \deq \pickgadget(\cs, \thin b_2, \thin \pick_{6(b_0, b_1)}, \thin \arr[5])}$ -$\line{28}{}{\arr'[6] = \pick_{6(b_0, b_1, b_3)}}$ - -$\line{27}{}{\pick_{\auxb, 7(b_0, b_1)}: \CircuitVal \deq \pickgadget(\cs, \thin \and_{(b_0, b_1)}, \thin \value, \thin \arr[6])}$ -$\line{28}{}{\pick_{\auxb, 7(b_0, b_1, b_2)}: \CircuitVal \deq \pickgadget(\cs, \thin b_2, \thin \pick_{7(b_0, b_1)}, \thin \arr[6])}$ -$\line{29}{}{\arr'[7] = \pick_{7(b_0, b_1, b_3)}}$ - -$\line{30}{}{\return \arr'}$ -``` - -### AND Gadget - -The function `$\andgadget$` returns an allocated bit `$1$` if both allocated bit arguments `$\x$` and `$\y$` are `$1$` and returns the allocated bit `$0$` otherwise. - -**Implementation:** [`bellman::gadgets::boolean::AllocatedBit::and()`](https://github.com/filecoin-project/bellman/blob/e0ac6b879eac87832ba6ef2e37320e877d1d96b6/src/gadgets/boolean.rs#L155) - -The `$\RCS$` quadratic constraint that is added by the `$\andgadget$`, when applied to two boolean constrained values `$\x, \y \in \Bit$` and outputting a third boolean constrained value `$\and \in \Bit$`, is: - -```text -$\bi (\x) * (\y) = (\and)$ -``` - -This table shows the satisfiablilty of the constraint for all values of `$\x, \y \in \Bit$` and corresponding outputted values of `$\and \in \Bit$`. - -| `$\x$` | `$\y$` | `$\and$` | `$(\x) * (\y) = (\and)$` | -|--------|---------|--------|-----------------------| -| `$0$` | `$0$` | `$0$` | `$(0) * (0) = (0)$` | -| `$1$` | `$0$` | `$0$` | `$(1) * (0) = (0)$` | -| `$0$` | `$1$` | `$0$` | `$(0) * (1) = (0)$` | -| `$1$` | `$1$` | `$1$` | `$(1) * (1) = (1)$` | - -```text -$\overline{\Function \andgadget(\qquad}$ -$\quad \cs: \RCS,$ -$\quad \x_\aap: \CircuitBit,$ -$\quad \y_\aap: \CircuitBit,$ -$\underline{) \rightarrow \CircuitBit \qquad\qquad\bi}$ -$\line{1}{\bi}{\and: \Bit = \x_\aap\dot\int \thin\AND\thin \y_\aap\dot\int}$ -$\line{2}{\bi}{\and_\auxb: \CircuitBit \deq \cs\dot\privateinput(\and)}$ -$\line{3}{\bi}{\cs\dot\assert(\x_\aap * \y_\aap = \and_\auxb)}$ -$\line{4}{\bi}{\return \and_\auxb}$ -``` - -### NOR Gadget - -The function `$\norgadget$` returns an allocated bit `$1$` if both allocated bit arguments `$\x$` and `$\y$` are `$0$` and returns the allocated bit `$0$` otherwise. - -**Implementation:** [`bellman::gadgets::boolean::AllocatedBit::nor()`](https://github.com/filecoin-project/bellman/blob/e0ac6b879eac87832ba6ef2e37320e877d1d96b6/src/gadgets/boolean.rs#L231) - -The `$\RCS$` quadratic constraint that is added by `$\norgadget$`, when applied to two boolean constrained values `$\x, \y \in \Bit$` and outputting a third boolean constrained value `$\nor \in \Bit$`, is: - -```text -$\bi (1 - \x) * (1 - \y) = (\nor)$ -``` - -The following table shows the satisfiablilty of the constraint for all values of `$\x, \y \in \Bit$` and corresponding outputted values for `$\nor \in \Bit$`. - -| `$\x$` | `$\y$` | `$\nor$` | `$(1 - \x) * (1 - \y) = (\nor)$` | -|--------|---------|--------|-----------------------| -| `$0$` | `$0$` | `$1$` | `$(1) * (1) = (1)$` | -| `$1$` | `$0$` | `$0$` | `$(0) * (1) = (0)$` | -| `$0$` | `$1$` | `$0$` | `$(1) * (0) = (0)$` | -| `$1$` | `$1$` | `$0$` | `$(0) * (0) = (0)$` | - -```text -$\overline{\Function \norgadget(\qquad}$ -$\quad \cs: \RCS,$ -$\quad \x_\aap: \CircuitBit,$ -$\quad \y_\aap: \CircuitBit,$ -$\underline{) \rightarrow \CircuitBit \qquad\qquad\bi}$ -$\line{1}{\bi}{\nor: \Bit = \neg (\x_\aap\dot\int \OR \y_\aap\dot\int)}$ -$\line{2}{\bi}{\nor_\auxb: \CircuitBit \deq \cs\dot\privateinput(\nor)}$ -$\line{3}{\bi}{\lc_A: \LinearCombination \equiv 1 - \x_\aap}$ -$\line{4}{\bi}{\lc_B: \LinearCombination \equiv 1 - \y_\aap}$ -$\line{5}{\bi}{\lc_C: \LinearCombination \equiv \nor_\auxb}$ -$\line{6}{\bi}{\cs\dot\assert(\lc_A * \lc_B = \lc_C)}$ -$\line{7}{\bi}{\return \nor_\auxb}$ -``` diff --git a/content/appendix/_index.md b/content/appendix/_index.md index 98e3ea519..c2d26f91e 100644 --- a/content/appendix/_index.md +++ b/content/appendix/_index.md @@ -1,6 +1,8 @@ --- title: Appendix weight: 7 -bookCollapseSection: true +dashboardWeight: 0.2 +dashboardState: incomplete +dashboardAudit: 0 --- diff --git a/content/appendix/address.md b/content/appendix/address.md index 3dac47813..4dbfbf6b2 100644 --- a/content/appendix/address.md +++ b/content/appendix/address.md @@ -1,6 +1,9 @@ --- title: "Address" weight: 2 +dashboardWeight: 0.2 +dashboardState: incomplete +dashboardAudit: 0 --- # Filecoin Address diff --git a/content/appendix/network_params.md b/content/appendix/network_params.md index 8b796c89c..703bb2aac 100644 --- a/content/appendix/network_params.md +++ b/content/appendix/network_params.md @@ -1,6 +1,9 @@ --- title: Filecoin Parameters weight: 3 +dashboardWeight: 0.2 +dashboardState: incomplete +dashboardAudit: 0 --- # Filecoin Parameters diff --git a/content/appendix/sharray.md b/content/appendix/sharray.md index 2cf3c7759..e171150a1 100644 --- a/content/appendix/sharray.md +++ b/content/appendix/sharray.md @@ -1,6 +1,9 @@ --- title: "Sharded IPLD Array" weight: 1 +dashboardWeight: 0.2 +dashboardState: incomplete +dashboardAudit: 0 --- # Sharded IPLD Array diff --git a/content/glossary/_index.md b/content/glossary/_index.md index d53acd006..c408d805f 100644 --- a/content/glossary/_index.md +++ b/content/glossary/_index.md @@ -1,6 +1,9 @@ --- title: "Glossary" weight: 6 +dashboardWeight: 0.2 +dashboardState: incomplete +dashboardAudit: 0 --- # Glossary diff --git a/content/implementations/_index.md b/content/implementations/_index.md new file mode 100644 index 000000000..eafd2408e --- /dev/null +++ b/content/implementations/_index.md @@ -0,0 +1,16 @@ +--- +title: Implementations +weight: 8 + +dashboardhidden: true +--- + +# Filecoin Implementations +--- + +In the meantime, you can follow each implementation’s progress at its respective repo on GitHub: + +{{}} + +https://filecoin.io/blog/announcing-filecoin-implementations-in-rust-and-c++/ + diff --git a/content/implementations/forest.md b/content/implementations/forest.md new file mode 100644 index 000000000..4b3ac6b29 --- /dev/null +++ b/content/implementations/forest.md @@ -0,0 +1,16 @@ +--- +title: Forest +weight: 3 +implAudit: 0 +implSpecCompliance: 0 +implRepo: https://github.com/ChainSafe/forest +--- + +# Forest is an implementation of Filecoin written in Rust +--- + +Forest is an implementation of Filecoin written in Rust. The implementation will take a modular approach to building a full Filecoin node in two parts — (i) building Filecoin’s security critical systems in Rust from the Filecoin Protocol Specification, specifically the virtual machine, blockchain, and node system, and (ii) integrating functional components for storage mining and storage & retrieval markets to compose a fully functional Filecoin node implementation. + +https://github.com/ChainSafe/forest + +https://chainsafe.github.io/forest/ \ No newline at end of file diff --git a/content/implementations/fuhon.md b/content/implementations/fuhon.md new file mode 100644 index 000000000..4107886b9 --- /dev/null +++ b/content/implementations/fuhon.md @@ -0,0 +1,14 @@ +--- +title: Fuhon (cpp-filecoin) +weight: 4 +implAudit: 0 +implSpecCompliance: 0 +implRepo: https://github.com/filecoin-project/cpp-filecoin +--- + +# Fuhon (cpp-filecoin) +--- + +C++17 implementation of blockchain based digital storage + +https://github.com/filecoin-project/cpp-filecoin \ No newline at end of file diff --git a/content/implementations/go-filecoin.md b/content/implementations/go-filecoin.md new file mode 100644 index 000000000..be43f7642 --- /dev/null +++ b/content/implementations/go-filecoin.md @@ -0,0 +1,14 @@ +--- +title: Filecoin (go-filecoin) +weight: 2 +implAudit: 0 +implSpecCompliance: 0 +implRepo: https://github.com/filecoin-project/go-filecoin +--- + +# Filecoin (go-filecoin) +--- + +The original Filecoin node implementation in Go. + +https://github.com/filecoin-project/go-filecoin \ No newline at end of file diff --git a/content/implementations/lotus.md b/content/implementations/lotus.md new file mode 100644 index 000000000..32ddfcd9e --- /dev/null +++ b/content/implementations/lotus.md @@ -0,0 +1,17 @@ +--- +title: Lotus +weight: 1 + +implAudit: 0 +implSpecCompliance: 0 +implRepo: https://github.com/filecoin-project/lotus +--- + +# Lotus +--- + +Lotus is an implementation of the Filecoin Distributed Storage Network. You can run the Lotus software client to join the Filecoin Testnet. + +https://github.com/filecoin-project/lotus + + diff --git a/content/intro/_index.md b/content/intro/_index.md index 34e81c48a..66277735b 100644 --- a/content/intro/_index.md +++ b/content/intro/_index.md @@ -1,8 +1,10 @@ --- title: Introduction weight: 1 + +dashboardWeight: 0.2 dashboardState: incomplete -bookCollapseSection: true +dashboardAudit: 0 --- # Introduction @@ -29,6 +31,11 @@ and other contract mechanisms recorded on the chain continue to be processed over time, without requiring further interaction from the original parties (such as the clients who requested the data storage). -# Status Overview +## Spec Status Overview +{{}} + +{{}} + +## Implementations Status -{{< dashboard name="Introduction" >}} \ No newline at end of file +{{}} \ No newline at end of file diff --git a/content/intro/arch.md b/content/intro/arch.md index 1a265846d..674c4dd91 100644 --- a/content/intro/arch.md +++ b/content/intro/arch.md @@ -1,8 +1,9 @@ --- title: "Architecture Diagrams" audit: 1 -dashboardState: permanent -dashboardInterface: incorrect +dashboardWeight: 0.2 +dashboardState: incomplete +dashboardAudit: 0 --- # Architecture Diagrams diff --git a/content/intro/concepts.md b/content/intro/concepts.md index e7c29add8..e66406f17 100644 --- a/content/intro/concepts.md +++ b/content/intro/concepts.md @@ -1,6 +1,9 @@ --- title: "Key Concepts" audit: 2 +dashboardWeight: 0.2 +dashboardState: incomplete +dashboardAudit: 0 --- # Key Concepts diff --git a/content/intro/filecoin_vm.md b/content/intro/filecoin_vm.md index 458674160..0f3dd4c8d 100644 --- a/content/intro/filecoin_vm.md +++ b/content/intro/filecoin_vm.md @@ -1,6 +1,9 @@ --- title: "Filecoin VM" weight: 3 +dashboardWeight: 0.2 +dashboardState: incomplete +dashboardAudit: 0 --- # Filecoin VM diff --git a/content/intro/systems/_index.md b/content/intro/systems/_index.md index 97c1df945..285d51ab3 100644 --- a/content/intro/systems/_index.md +++ b/content/intro/systems/_index.md @@ -2,4 +2,7 @@ title: System Decomposition weight: 6 bookCollapseSection: true +dashboardWeight: 0.2 +dashboardState: incomplete +dashboardAudit: 0 --- \ No newline at end of file diff --git a/content/intro/systems/impl_systems.md b/content/intro/systems/impl_systems.md index f5c50d758..e8a1ff232 100644 --- a/content/intro/systems/impl_systems.md +++ b/content/intro/systems/impl_systems.md @@ -1,6 +1,9 @@ --- title: Implementing Systems weight: 2 +dashboardWeight: 0.2 +dashboardState: incomplete +dashboardAudit: 0 --- # Implementing Systems diff --git a/content/intro/systems/why_systems.md b/content/intro/systems/why_systems.md index b823e36c8..7518b48a2 100644 --- a/content/intro/systems/why_systems.md +++ b/content/intro/systems/why_systems.md @@ -1,6 +1,9 @@ --- title: What are Systems? weight: 1 +dashboardWeight: 0.2 +dashboardState: incomplete +dashboardAudit: 0 --- # What are Systems? How do they work? diff --git a/content/libraries/_index.md b/content/libraries/_index.md index 5649f6e54..e317ad763 100644 --- a/content/libraries/_index.md +++ b/content/libraries/_index.md @@ -1,9 +1,8 @@ --- title: Libraries weight: 3 -bookCollapseSection: true +dashboardWeight: 1.5 +dashboardState: wip +dashboardAudit: 0 +dashboardTests: 0 --- - -## Status Overview - -{{< dashboard-level open="true">}} \ No newline at end of file diff --git a/content/libraries/fcs/_index.md b/content/libraries/fcs/_index.md index 977035913..2ec698868 100644 --- a/content/libraries/fcs/_index.md +++ b/content/libraries/fcs/_index.md @@ -1,6 +1,10 @@ --- title: FCS weight: 2 +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- {{< hint warning >}} Needs content. diff --git a/content/libraries/filcrypto/_index.md b/content/libraries/filcrypto/_index.md index 3631ee144..0a8a40a61 100644 --- a/content/libraries/filcrypto/_index.md +++ b/content/libraries/filcrypto/_index.md @@ -3,4 +3,8 @@ title: FIL Crypto description: Cryptographic libraries used in Filecoin weight: 1 bookCollapseSection: true +dashboardWeight: 1.5 +dashboardState: wip +dashboardAudit: 0 +dashboardTests: 0 --- diff --git a/content/libraries/filcrypto/filproofs/_index.md b/content/libraries/filcrypto/filproofs/_index.md index d33fe60e8..9d965081e 100644 --- a/content/libraries/filcrypto/filproofs/_index.md +++ b/content/libraries/filcrypto/filproofs/_index.md @@ -1,6 +1,10 @@ --- title: FIL Proofs description: Filecoin Storage Proofs +dashboardWeight: 1.5 +dashboardState: wip +dashboardAudit: 0 +dashboardTests: 0 --- # Filecoin Storage Proofs --- diff --git a/content/libraries/ipfs/_index.md b/content/libraries/ipfs/_index.md index b1d6864ee..284fb3780 100644 --- a/content/libraries/ipfs/_index.md +++ b/content/libraries/ipfs/_index.md @@ -2,4 +2,8 @@ title: IPFS description: IPFS - InterPlanetary File System weight: 5 +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- diff --git a/content/libraries/ipfs/bitswap.md b/content/libraries/ipfs/bitswap.md index 609c4b171..fb1e272b4 100644 --- a/content/libraries/ipfs/bitswap.md +++ b/content/libraries/ipfs/bitswap.md @@ -1,5 +1,9 @@ --- title: BitSwap +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- {{< hint danger >}} diff --git a/content/libraries/ipfs/graphsync.md b/content/libraries/ipfs/graphsync.md index 39946d774..29cbb8c06 100644 --- a/content/libraries/ipfs/graphsync.md +++ b/content/libraries/ipfs/graphsync.md @@ -1,5 +1,9 @@ --- title: GraphSync +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- {{< hint danger >}} diff --git a/content/libraries/ipfs/unixfs.md b/content/libraries/ipfs/unixfs.md index fc481b5b0..2b8012baa 100644 --- a/content/libraries/ipfs/unixfs.md +++ b/content/libraries/ipfs/unixfs.md @@ -1,5 +1,9 @@ --- title: UnixFS +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- {{< hint danger >}} diff --git a/content/libraries/ipld/_index.md b/content/libraries/ipld/_index.md index b187e10ef..579e89f92 100644 --- a/content/libraries/ipld/_index.md +++ b/content/libraries/ipld/_index.md @@ -3,6 +3,10 @@ title: IPLD description: IPLD - InterPlanetary Linked Data bookCollapseSection: true weight: 3 +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # IPLD - InterPlanetary Linked Data diff --git a/content/libraries/ipld/cid.md b/content/libraries/ipld/cid.md index b60a49d7e..51badf783 100644 --- a/content/libraries/ipld/cid.md +++ b/content/libraries/ipld/cid.md @@ -1,6 +1,10 @@ --- title: CID description: CIDs - Content IDentifiers +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # CIDs - Content IDentifiers diff --git a/content/libraries/ipld/datamodel.md b/content/libraries/ipld/datamodel.md index 3b07216af..6a0fa901e 100644 --- a/content/libraries/ipld/datamodel.md +++ b/content/libraries/ipld/datamodel.md @@ -1,5 +1,9 @@ --- title: Data Model +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- {{< hint danger >}} Needs content diff --git a/content/libraries/ipld/selectors.md b/content/libraries/ipld/selectors.md index 488df0e5c..a082db092 100644 --- a/content/libraries/ipld/selectors.md +++ b/content/libraries/ipld/selectors.md @@ -1,6 +1,10 @@ --- title: Selectors description: Selectors - IPLD Query Language +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Selectors - IPLD Query Language diff --git a/content/libraries/libp2p/_index.md b/content/libraries/libp2p/_index.md index a09754c13..cab4688ad 100644 --- a/content/libraries/libp2p/_index.md +++ b/content/libraries/libp2p/_index.md @@ -3,6 +3,10 @@ title: libp2p description: A modular network stack. Run your network applications free from runtime and address services, independently of their location. weight: 4 bookCollapseSection: true +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Libp2p - A modular network stack diff --git a/content/libraries/libp2p/fil_libp2p_nodes.md b/content/libraries/libp2p/fil_libp2p_nodes.md index 916f12d49..b0f35b6b8 100644 --- a/content/libraries/libp2p/fil_libp2p_nodes.md +++ b/content/libraries/libp2p/fil_libp2p_nodes.md @@ -1,6 +1,10 @@ --- title: FIL Libp2p Nodes description: Filecoin libp2p Nodes +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- {{< hint danger >}} diff --git a/content/libraries/libp2p/gossipsub.md b/content/libraries/libp2p/gossipsub.md index 8d0e86ad3..4f297f4ea 100644 --- a/content/libraries/libp2p/gossipsub.md +++ b/content/libraries/libp2p/gossipsub.md @@ -1,6 +1,10 @@ --- title: Gossipsub description: Gossipsub for broadcasts +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- {{< hint danger >}} Needs content diff --git a/content/libraries/libp2p/kad_dht.md b/content/libraries/libp2p/kad_dht.md index 9b1b48945..3ad4363f9 100644 --- a/content/libraries/libp2p/kad_dht.md +++ b/content/libraries/libp2p/kad_dht.md @@ -1,6 +1,10 @@ --- title: DHT description: Kademlia DHT for Peer Routing +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- {{< hint danger >}} diff --git a/content/libraries/multiformats/_index.md b/content/libraries/multiformats/_index.md index 8b83127bd..0103c80d6 100644 --- a/content/libraries/multiformats/_index.md +++ b/content/libraries/multiformats/_index.md @@ -2,6 +2,10 @@ title: Multiformats description: Multiformats - self describing protocol values weight: 6 +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Multiformats diff --git a/content/listings/_index.md b/content/listings/_index.md index 59176b0c9..5d119da52 100644 --- a/content/listings/_index.md +++ b/content/listings/_index.md @@ -1,5 +1,7 @@ --- title: Listings -bookCollapseSection: true weight: 5 +dashboardWeight: 0.2 +dashboardState: incomplete +dashboardAudit: 0 --- \ No newline at end of file diff --git a/content/listings/actors.md b/content/listings/actors.md index ad4105e73..430831057 100644 --- a/content/listings/actors.md +++ b/content/listings/actors.md @@ -1,6 +1,9 @@ --- title: "Filecoin VM Actors" weight: 1 +dashboardWeight: 0.2 +dashboardState: incomplete +dashboardAudit: 0 --- # Filecoin VM Actors diff --git a/content/listings/data_structures.md b/content/listings/data_structures.md index c512a75da..a7f0bc813 100644 --- a/content/listings/data_structures.md +++ b/content/listings/data_structures.md @@ -1,6 +1,9 @@ --- title: "Data Structures" weight: 3 +dashboardWeight: 0.2 +dashboardState: incomplete +dashboardAudit: 0 --- # Data Structures diff --git a/content/listings/libp2p_protocols/_index.md b/content/listings/libp2p_protocols/_index.md index 7a60fdbcb..b691014ca 100644 --- a/content/listings/libp2p_protocols/_index.md +++ b/content/listings/libp2p_protocols/_index.md @@ -2,6 +2,7 @@ title: "Libp2p Protocols" bookCollapseSection: true weight: 5 -entries: - - data_transfer_protocol +dashboardWeight: 0.2 +dashboardState: incomplete +dashboardAudit: 0 --- \ No newline at end of file diff --git a/content/listings/libp2p_protocols/data_transfer_protocol.md b/content/listings/libp2p_protocols/data_transfer_protocol.md index 2fece9109..34082c332 100644 --- a/content/listings/libp2p_protocols/data_transfer_protocol.md +++ b/content/listings/libp2p_protocols/data_transfer_protocol.md @@ -1,5 +1,8 @@ --- title: Data Transfer Protocol +dashboardWeight: 0.2 +dashboardState: incomplete +dashboardAudit: 0 --- # Data Transfer Protocol diff --git a/content/listings/reserved_ranges.md b/content/listings/reserved_ranges.md index d6a94e831..8d005d154 100644 --- a/content/listings/reserved_ranges.md +++ b/content/listings/reserved_ranges.md @@ -1,6 +1,9 @@ --- title: "Reserved Ranges" weight: 2 +dashboardWeight: 0.2 +dashboardState: incomplete +dashboardAudit: 0 --- # Reserved Ranges diff --git a/content/listings/system_map.md b/content/listings/system_map.md index f6c0162bb..ea351d355 100644 --- a/content/listings/system_map.md +++ b/content/listings/system_map.md @@ -1,6 +1,9 @@ --- title: "Components" weight: 4 +dashboardWeight: 0.2 +dashboardState: incomplete +dashboardAudit: 0 --- # Components diff --git a/content/systems/_index.md b/content/systems/_index.md index e887a8046..1062384bf 100644 --- a/content/systems/_index.md +++ b/content/systems/_index.md @@ -1,8 +1,12 @@ --- title: Systems description: Filecoin Systems -bookCollapseSection: true weight: 2 + +dashboardWeight: 1 +dashboardState: wip +dashboardAudit: 0 +dashboardTests: 0 --- # Systems diff --git a/content/systems/filecoin_blockchain/_index.md b/content/systems/filecoin_blockchain/_index.md index 5016bfed3..614b7752b 100644 --- a/content/systems/filecoin_blockchain/_index.md +++ b/content/systems/filecoin_blockchain/_index.md @@ -1,20 +1,16 @@ --- -menuIcon: 📦 title: "Blockchain" bookCollapseSection: true weight: 4 +dashboardWeight: 2 +dashboardState: wip dashboardAudit: 0 -dashboardState: incomplete -dashboardInterface: wip +dashboardTests: 0 --- # Blockchain --- -## Status Overview - -{{}} - The Filecoin Blockchain is a distributed virtual machine that achieves consensus, processes messages, accounts for storage, and maintains security in the Filecoin Protocol. It is the main interface linking various actors in the Filecoin system. It includes: diff --git a/content/systems/filecoin_blockchain/chainsync/_index.md b/content/systems/filecoin_blockchain/chainsync/_index.md index 5cb62b380..1a4e7481b 100644 --- a/content/systems/filecoin_blockchain/chainsync/_index.md +++ b/content/systems/filecoin_blockchain/chainsync/_index.md @@ -2,6 +2,10 @@ title: ChainSync weight: 3 description: ChainSync - synchronizing the Blockchain +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # ChainSync - synchronizing the Blockchain diff --git a/content/systems/filecoin_blockchain/message_pool/_index.md b/content/systems/filecoin_blockchain/message_pool/_index.md index 47552c3cd..5349750fc 100644 --- a/content/systems/filecoin_blockchain/message_pool/_index.md +++ b/content/systems/filecoin_blockchain/message_pool/_index.md @@ -2,6 +2,10 @@ title: Message Pool weight: 2 bookCollapseSection: true +dashboardWeight: 2 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # Message Pool diff --git a/content/systems/filecoin_blockchain/message_pool/message_storage.md b/content/systems/filecoin_blockchain/message_pool/message_storage.md index a3841ab0b..1c8f292df 100644 --- a/content/systems/filecoin_blockchain/message_pool/message_storage.md +++ b/content/systems/filecoin_blockchain/message_pool/message_storage.md @@ -1,6 +1,10 @@ --- title: Message Storage weight: 2 +dashboardWeight: 2 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # Message Storage diff --git a/content/systems/filecoin_blockchain/message_pool/message_syncer.md b/content/systems/filecoin_blockchain/message_pool/message_syncer.md index be54c56d7..2f373eb5b 100644 --- a/content/systems/filecoin_blockchain/message_pool/message_syncer.md +++ b/content/systems/filecoin_blockchain/message_pool/message_syncer.md @@ -1,6 +1,10 @@ --- title: Message Syncer weight: 1 +dashboardWeight: 2 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # Message Syncer diff --git a/content/systems/filecoin_blockchain/storage_power_consensus/_index.md b/content/systems/filecoin_blockchain/storage_power_consensus/_index.md index ece248992..7be950ab0 100644 --- a/content/systems/filecoin_blockchain/storage_power_consensus/_index.md +++ b/content/systems/filecoin_blockchain/storage_power_consensus/_index.md @@ -2,6 +2,10 @@ title: Storage Power Consensus weight: 4 bookCollapseSection: true +dashboardWeight: 2 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # Storage Power Consensus diff --git a/content/systems/filecoin_blockchain/storage_power_consensus/storage_power_actor.md b/content/systems/filecoin_blockchain/storage_power_consensus/storage_power_actor.md index 55862b182..21b593253 100644 --- a/content/systems/filecoin_blockchain/storage_power_consensus/storage_power_actor.md +++ b/content/systems/filecoin_blockchain/storage_power_consensus/storage_power_actor.md @@ -1,5 +1,9 @@ --- title: Storage Power Actor +dashboardWeight: 2 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # Storage Power Actor @@ -7,11 +11,11 @@ title: Storage Power Actor ## `StoragePowerActorState` implementation -{{}} +{{}} ## `StoragePowerActor` implementation -{{}} +{{}} ## The Power Table diff --git a/content/systems/filecoin_blockchain/struct/_index.md b/content/systems/filecoin_blockchain/struct/_index.md index 5aa92fb41..d01345e08 100644 --- a/content/systems/filecoin_blockchain/struct/_index.md +++ b/content/systems/filecoin_blockchain/struct/_index.md @@ -2,6 +2,10 @@ title: "Blocks" bookCollapseSection: true weight: 1 +dashboardWeight: 1.5 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # Blocks diff --git a/content/systems/filecoin_blockchain/struct/block/_index.md b/content/systems/filecoin_blockchain/struct/block/_index.md index 3fcc67599..194fddf69 100644 --- a/content/systems/filecoin_blockchain/struct/block/_index.md +++ b/content/systems/filecoin_blockchain/struct/block/_index.md @@ -1,6 +1,10 @@ --- title: Block weight: 1 +dashboardWeight: 1.5 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # Block diff --git a/content/systems/filecoin_blockchain/struct/block_producer/_index.md b/content/systems/filecoin_blockchain/struct/block_producer/_index.md index 792357233..1afe583b6 100644 --- a/content/systems/filecoin_blockchain/struct/block_producer/_index.md +++ b/content/systems/filecoin_blockchain/struct/block_producer/_index.md @@ -1,6 +1,10 @@ --- title: Block Producer weight: 5 +dashboardWeight: 1.5 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # Block Producer diff --git a/content/systems/filecoin_blockchain/struct/chain/_index.md b/content/systems/filecoin_blockchain/struct/chain/_index.md index aa42c6f74..e6109e93e 100644 --- a/content/systems/filecoin_blockchain/struct/chain/_index.md +++ b/content/systems/filecoin_blockchain/struct/chain/_index.md @@ -1,6 +1,10 @@ --- title: Chain weight: 3 +dashboardWeight: 1.5 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # Chain diff --git a/content/systems/filecoin_blockchain/struct/chain_manager/_index.md b/content/systems/filecoin_blockchain/struct/chain_manager/_index.md index c41bd6b6e..e0cda04fb 100644 --- a/content/systems/filecoin_blockchain/struct/chain_manager/_index.md +++ b/content/systems/filecoin_blockchain/struct/chain_manager/_index.md @@ -1,6 +1,10 @@ --- title: Chain Manager weight: 4 +dashboardWeight: 1.5 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # Chain Manager diff --git a/content/systems/filecoin_blockchain/struct/tipset/_index.md b/content/systems/filecoin_blockchain/struct/tipset/_index.md index 99a895a35..b33bb8941 100644 --- a/content/systems/filecoin_blockchain/struct/tipset/_index.md +++ b/content/systems/filecoin_blockchain/struct/tipset/_index.md @@ -1,6 +1,10 @@ --- title: Tipset weight: 2 +dashboardWeight: 1.5 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # Tipset diff --git a/content/systems/filecoin_files/_index.md b/content/systems/filecoin_files/_index.md index 80976652a..ac722d23b 100644 --- a/content/systems/filecoin_files/_index.md +++ b/content/systems/filecoin_files/_index.md @@ -2,9 +2,11 @@ title: Files & Data bookCollapseSection: true weight: 2 -dashboardAudit: 1 -dashboardState: stable -dashboardInterface: stable + +dashboardWeight: 1.5 +dashboardState: wip +dashboardAudit: 0 +dashboardTests: 0 --- # Files & Data @@ -12,8 +14,4 @@ dashboardInterface: stable Filecoin's primary aim is to store client's Files and Data. This section details data structures and tooling related to working with files, -chunking, encoding, graph representations, `Pieces`, storage abstractions, and more. - -## Status Overview - -{{< dashboard-level open="true">}} \ No newline at end of file +chunking, encoding, graph representations, `Pieces`, storage abstractions, and more. \ No newline at end of file diff --git a/content/systems/filecoin_files/data_transfer/_index.md b/content/systems/filecoin_files/data_transfer/_index.md index ef0d71ee9..590630135 100644 --- a/content/systems/filecoin_files/data_transfer/_index.md +++ b/content/systems/filecoin_files/data_transfer/_index.md @@ -1,9 +1,10 @@ --- title: Data Transfer weight: 3 -dashboardAudit: 1 -dashboardState: permanent -dashboardInterface: stable +dashboardWeight: 1 +dashboardState: stable +dashboardAudit: 0 +dashboardTests: 0 --- # Data Transfer in Filecoin diff --git a/content/systems/filecoin_files/file/_index.md b/content/systems/filecoin_files/file/_index.md index 57b24e4bb..9482d0dc6 100644 --- a/content/systems/filecoin_files/file/_index.md +++ b/content/systems/filecoin_files/file/_index.md @@ -2,9 +2,11 @@ title: File weight: 1 bookCollapseSection: true -dashboardAudit: 1 -dashboardState: permanent -dashboardInterface: stable +dashboardWeight: 1 +dashboardState: stable +dashboardAudit: 0 +dashboardTests: 0 + --- # File diff --git a/content/systems/filecoin_files/file/filestore.md b/content/systems/filecoin_files/file/filestore.md index 1686ec89b..0ca873c12 100644 --- a/content/systems/filecoin_files/file/filestore.md +++ b/content/systems/filecoin_files/file/filestore.md @@ -1,5 +1,9 @@ --- title: FileStore +dashboardWeight: 1 +dashboardState: stable +dashboardAudit: 0 +dashboardTests: 0 --- # FileStore - Local Storage for Files diff --git a/content/systems/filecoin_files/piece/_index.md b/content/systems/filecoin_files/piece/_index.md index 5b4de3cab..36e7eb79b 100644 --- a/content/systems/filecoin_files/piece/_index.md +++ b/content/systems/filecoin_files/piece/_index.md @@ -2,9 +2,10 @@ title: Piece weight: 2 bookCollapseSection: true -dashboardAudit: 1 -dashboardState: permanent -dashboardInterface: stable +dashboardWeight: 1.5 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Piece - Part of a file diff --git a/content/systems/filecoin_files/piece/piece_store.md b/content/systems/filecoin_files/piece/piece_store.md index f710cf27a..1addff523 100644 --- a/content/systems/filecoin_files/piece/piece_store.md +++ b/content/systems/filecoin_files/piece/piece_store.md @@ -1,5 +1,10 @@ --- title: PieceStore + +dashboardWeight: 1.5 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # PieceStore - Storing and indexing pieces diff --git a/content/systems/filecoin_files/serialization/_index.md b/content/systems/filecoin_files/serialization/_index.md index 42817dc8d..4e9271393 100644 --- a/content/systems/filecoin_files/serialization/_index.md +++ b/content/systems/filecoin_files/serialization/_index.md @@ -1,9 +1,10 @@ --- title: Formats and Serialization weight: 4 -dashboardAudit: 1 -dashboardState: wip -dashboardInterface: stable +dashboardWeight: 1 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # Data Formats and Serialization diff --git a/content/systems/filecoin_markets/_index.md b/content/systems/filecoin_markets/_index.md index 6b65491eb..05b81844f 100644 --- a/content/systems/filecoin_markets/_index.md +++ b/content/systems/filecoin_markets/_index.md @@ -3,9 +3,10 @@ title: "Market" description: "Markets in Filecoin" bookCollapseSection: true weight: 7 -dashboardAudit: 1 -dashboardState: wip -dashboardInterface: stable +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Markets @@ -14,8 +15,4 @@ dashboardInterface: stable The Filecoin project is a protocol, a platform, and a marketplace. There are two major components to Filecoin markets, storage market and retrieval market. While both markets are expected to happen primarily off the blockchain, storage deals made in storage market will be published on chain and enforced by the protocol. Storage deal negotiation and order matching are expected to happen off chain in the first version of Filecoin. Retrieval deals are also negotiated off chain and executed with micropayments between transacting parties in payment channels. Even though most of the market actions happen off the blockchain, there are on-chain invariants that create economic structure for network success and allow for positive emergent behavior. You can read more about the -relationship between on chain deals and storage power in [Storage Power Consensus](storage_power_consensus). - -## Status Overview - -{{< dashboard-level name="Market" open="true">}} \ No newline at end of file +relationship between on chain deals and storage power in [Storage Power Consensus](storage_power_consensus). \ No newline at end of file diff --git a/content/systems/filecoin_markets/retrieval_market/_index.md b/content/systems/filecoin_markets/retrieval_market/_index.md index 2de7ba8fa..a37eff5eb 100644 --- a/content/systems/filecoin_markets/retrieval_market/_index.md +++ b/content/systems/filecoin_markets/retrieval_market/_index.md @@ -2,6 +2,10 @@ title: Retrieval Market bookCollapseSection: true weight: 2 +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Retrieval Market in Filecoin diff --git a/content/systems/filecoin_markets/retrieval_market/retrieval_client.md b/content/systems/filecoin_markets/retrieval_market/retrieval_client.md index 62b6982ea..833585328 100644 --- a/content/systems/filecoin_markets/retrieval_market/retrieval_client.md +++ b/content/systems/filecoin_markets/retrieval_market/retrieval_client.md @@ -1,6 +1,10 @@ --- title: "Retrieval Client" weight: 3 +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Retrieval Client diff --git a/content/systems/filecoin_markets/retrieval_market/retrieval_peer_resolver.md b/content/systems/filecoin_markets/retrieval_market/retrieval_peer_resolver.md index cf90c401f..e4d3ae86c 100644 --- a/content/systems/filecoin_markets/retrieval_market/retrieval_peer_resolver.md +++ b/content/systems/filecoin_markets/retrieval_market/retrieval_peer_resolver.md @@ -1,6 +1,10 @@ --- title: "Retrieval Peer Resolver" weight: 1 +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Retrieval Peer Resolver diff --git a/content/systems/filecoin_markets/retrieval_market/retrieval_protocols.md b/content/systems/filecoin_markets/retrieval_market/retrieval_protocols.md index 5e90b2da5..2f9f92272 100644 --- a/content/systems/filecoin_markets/retrieval_market/retrieval_protocols.md +++ b/content/systems/filecoin_markets/retrieval_market/retrieval_protocols.md @@ -1,6 +1,10 @@ --- title: "Retrieval Protocols" weight: 2 +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Retrieval Protocols diff --git a/content/systems/filecoin_markets/retrieval_market/retrieval_provider.md b/content/systems/filecoin_markets/retrieval_market/retrieval_provider.md index 54a6b2d12..5858e8448 100644 --- a/content/systems/filecoin_markets/retrieval_market/retrieval_provider.md +++ b/content/systems/filecoin_markets/retrieval_market/retrieval_provider.md @@ -1,6 +1,10 @@ --- title: "Retrieval Provider (Miner)" weight: 4 +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Retrieval Provider (Miner) diff --git a/content/systems/filecoin_markets/storage_market/_index.md b/content/systems/filecoin_markets/storage_market/_index.md index 48c8c1712..61f6e6bf2 100644 --- a/content/systems/filecoin_markets/storage_market/_index.md +++ b/content/systems/filecoin_markets/storage_market/_index.md @@ -2,9 +2,10 @@ title: Storage Market weight: 1 bookCollapseSection: true +dashboardWeight: 2 +dashboardState: incomplete dashboardAudit: 1 -dashboardState: wip -dashboardInterface: stable +dashboardTests: 0 --- # Storage Market in Filecoin diff --git a/content/systems/filecoin_markets/storage_market/storage_client.md b/content/systems/filecoin_markets/storage_market/storage_client.md index ef7ad623c..51211446f 100644 --- a/content/systems/filecoin_markets/storage_market/storage_client.md +++ b/content/systems/filecoin_markets/storage_market/storage_client.md @@ -1,6 +1,10 @@ --- title: Storage Client weight: 4 +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 1 +dashboardTests: 0 --- # Storage Client diff --git a/content/systems/filecoin_markets/storage_market/storage_deal/_index.md b/content/systems/filecoin_markets/storage_market/storage_deal/_index.md index 713ee6dda..902766025 100644 --- a/content/systems/filecoin_markets/storage_market/storage_deal/_index.md +++ b/content/systems/filecoin_markets/storage_market/storage_deal/_index.md @@ -2,6 +2,10 @@ title: Storage Deal weight: 1 bookCollapseSection: true +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 1 +dashboardTests: 0 --- # Storage Deals @@ -15,5 +19,5 @@ This section describes the storage deal data type and a technical outline for de ## Data Types -{{< embed src="/docs/actors/actors/builtin/storage_market/storage_deal.go" lang="go" >}} +{{< embed src="/modules/actors/builtin/market/deal.go" lang="go" >}} diff --git a/content/systems/filecoin_markets/storage_market/storage_deal/faults.md b/content/systems/filecoin_markets/storage_market/storage_deal/faults.md index 14685d099..2cc36eafc 100644 --- a/content/systems/filecoin_markets/storage_market/storage_deal/faults.md +++ b/content/systems/filecoin_markets/storage_market/storage_deal/faults.md @@ -1,6 +1,10 @@ --- title: "Faults" weight: 3 +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 1 +dashboardTests: 0 --- # Faults diff --git a/content/systems/filecoin_markets/storage_market/storage_deal/storage_deal_flow.md b/content/systems/filecoin_markets/storage_market/storage_deal/storage_deal_flow.md index b3a674905..b92cca31f 100644 --- a/content/systems/filecoin_markets/storage_market/storage_deal/storage_deal_flow.md +++ b/content/systems/filecoin_markets/storage_market/storage_deal/storage_deal_flow.md @@ -1,6 +1,10 @@ --- title: Deal Flow weight: 1 +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 1 +dashboardTests: 0 --- # Storage Deal Flow diff --git a/content/systems/filecoin_markets/storage_market/storage_deal/storage_deal_states.md b/content/systems/filecoin_markets/storage_market/storage_deal/storage_deal_states.md index b77090628..2f133e452 100644 --- a/content/systems/filecoin_markets/storage_market/storage_deal/storage_deal_states.md +++ b/content/systems/filecoin_markets/storage_market/storage_deal/storage_deal_states.md @@ -1,6 +1,10 @@ --- title: Deal States weight: 2 +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 1 +dashboardTests: 0 --- # Storage Deal States diff --git a/content/systems/filecoin_markets/storage_market/storage_market_actor.md b/content/systems/filecoin_markets/storage_market/storage_market_actor.md index 4386e92e9..8c15451ee 100644 --- a/content/systems/filecoin_markets/storage_market/storage_market_actor.md +++ b/content/systems/filecoin_markets/storage_market/storage_market_actor.md @@ -1,6 +1,10 @@ --- title: Storage Market Actor weight: 2 +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 1 +dashboardTests: 0 --- # Storage Market Actor @@ -10,15 +14,12 @@ weight: 2 ## `StorageMarketActorState` implementation -{{}} +{{}} ## `StorageMarketActor` implementation -{{}} +{{}} -## `StorageMarketActor` implementation - -{{}} ## Storage Deal Collateral diff --git a/content/systems/filecoin_markets/storage_market/storage_provider.md b/content/systems/filecoin_markets/storage_market/storage_provider.md index 8d4863d31..4cf54077a 100644 --- a/content/systems/filecoin_markets/storage_market/storage_provider.md +++ b/content/systems/filecoin_markets/storage_market/storage_provider.md @@ -1,6 +1,10 @@ --- title: "Storage Provider" weight: 3 +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 1 +dashboardTests: 0 --- # Storage Provider diff --git a/content/systems/filecoin_mining/_index.md b/content/systems/filecoin_mining/_index.md index c4d5864f2..01ab2a9a7 100644 --- a/content/systems/filecoin_mining/_index.md +++ b/content/systems/filecoin_mining/_index.md @@ -2,9 +2,10 @@ title: Storage Mining bookCollapseSection: true weight: 6 -dashboardAudit: 1 -dashboardState: permanent -dashboardInterface: stable +dashboardWeight: 2 +dashboardState: wip +dashboardAudit: 0 +dashboardTests: 0 --- # Storage Mining System - proving storage for producing blocks @@ -24,7 +25,4 @@ algorithms that could be replaced by other, more optimized versions, but in thos important that the **protocol constraints** are satisfied. The **protocol constraints** are spelled out in clear detail (an unclear, unmentioned constraint is a "spec error"). It is up to implementers who deviate from the algorithms presented here to ensure their modifications -satisfy those constraints, especially those relating to protocol security. - -## Status Overview -{{< dashboard-level open="true">}} \ No newline at end of file +satisfy those constraints, especially those relating to protocol security. \ No newline at end of file diff --git a/content/systems/filecoin_mining/sector/_index.md b/content/systems/filecoin_mining/sector/_index.md index 84b089c9f..e51640206 100644 --- a/content/systems/filecoin_mining/sector/_index.md +++ b/content/systems/filecoin_mining/sector/_index.md @@ -2,6 +2,10 @@ title: Sector weight: 2 bookCollapseSection: true +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Sector diff --git a/content/systems/filecoin_mining/sector/lifecycle.md b/content/systems/filecoin_mining/sector/lifecycle.md index 6af4c3831..8157f1452 100644 --- a/content/systems/filecoin_mining/sector/lifecycle.md +++ b/content/systems/filecoin_mining/sector/lifecycle.md @@ -1,5 +1,9 @@ --- title: Sector Lifecycle +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Sector Lifecycle diff --git a/content/systems/filecoin_mining/sector/posting.md b/content/systems/filecoin_mining/sector/posting.md index 2e0eec2de..5ff45ddc3 100644 --- a/content/systems/filecoin_mining/sector/posting.md +++ b/content/systems/filecoin_mining/sector/posting.md @@ -1,5 +1,9 @@ --- title: Sector PoSting +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Sector PoSting diff --git a/content/systems/filecoin_mining/sector/sealing.md b/content/systems/filecoin_mining/sector/sealing.md index f6b5b9f61..96efb89ab 100644 --- a/content/systems/filecoin_mining/sector/sealing.md +++ b/content/systems/filecoin_mining/sector/sealing.md @@ -1,5 +1,9 @@ --- title: Sector Sealing +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Sector Sealing diff --git a/content/systems/filecoin_mining/sector/sectorset.md b/content/systems/filecoin_mining/sector/sectorset.md index 43bac26c6..a5e7a3299 100644 --- a/content/systems/filecoin_mining/sector/sectorset.md +++ b/content/systems/filecoin_mining/sector/sectorset.md @@ -1,5 +1,9 @@ --- title: Sector Set +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Sector Set diff --git a/content/systems/filecoin_mining/sector_index/_index.md b/content/systems/filecoin_mining/sector_index/_index.md index 54d71b6ca..cfa5ce628 100644 --- a/content/systems/filecoin_mining/sector_index/_index.md +++ b/content/systems/filecoin_mining/sector_index/_index.md @@ -2,6 +2,10 @@ title: Sector Index weight: 3 bookCollapseSection: true +dashboardWeight: 1 +dashboardState: wip +dashboardAudit: 0 +dashboardTests: 0 --- # Sector Index diff --git a/content/systems/filecoin_mining/sector_index/sector_builder.md b/content/systems/filecoin_mining/sector_index/sector_builder.md index 568354e99..ea05d9069 100644 --- a/content/systems/filecoin_mining/sector_index/sector_builder.md +++ b/content/systems/filecoin_mining/sector_index/sector_builder.md @@ -1,5 +1,9 @@ --- title: Sector Builder +dashboardWeight: 1 +dashboardState: wip +dashboardAudit: 0 +dashboardTests: 0 --- # Sector Builder diff --git a/content/systems/filecoin_mining/sector_index/sector_store.md b/content/systems/filecoin_mining/sector_index/sector_store.md index 51811e878..d7e9e9bc8 100644 --- a/content/systems/filecoin_mining/sector_index/sector_store.md +++ b/content/systems/filecoin_mining/sector_index/sector_store.md @@ -1,5 +1,9 @@ --- title: Sector Store +dashboardWeight: 1 +dashboardState: wip +dashboardAudit: 0 +dashboardTests: 0 --- # Sector Store diff --git a/content/systems/filecoin_mining/storage_mining/_index.md b/content/systems/filecoin_mining/storage_mining/_index.md index 653f071d7..3aea4b907 100644 --- a/content/systems/filecoin_mining/storage_mining/_index.md +++ b/content/systems/filecoin_mining/storage_mining/_index.md @@ -2,6 +2,10 @@ title: Storage Miner bookCollapseSection: true weight: 1 +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Storage Miner diff --git a/content/systems/filecoin_mining/storage_mining/mining_cycle/index.md b/content/systems/filecoin_mining/storage_mining/mining_cycle/index.md index 353f57818..06d05adb6 100644 --- a/content/systems/filecoin_mining/storage_mining/mining_cycle/index.md +++ b/content/systems/filecoin_mining/storage_mining/mining_cycle/index.md @@ -1,5 +1,9 @@ --- title: Storage Mining Cycle +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Storage Mining Cycle diff --git a/content/systems/filecoin_mining/storage_mining/storage_miner_actor.md b/content/systems/filecoin_mining/storage_mining/storage_miner_actor.md index 4e1837886..909536379 100644 --- a/content/systems/filecoin_mining/storage_mining/storage_miner_actor.md +++ b/content/systems/filecoin_mining/storage_mining/storage_miner_actor.md @@ -1,5 +1,9 @@ --- title: Storage Miner Actor +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Storage Miner Actor @@ -7,8 +11,8 @@ title: Storage Miner Actor ## `StorageMinerActorState` implementation -{{}} +{{}} ## `StorageMinerActorCode` implementation -{{}} +{{}} diff --git a/content/systems/filecoin_mining/storage_proving/_index.md b/content/systems/filecoin_mining/storage_proving/_index.md index 77d3e5f32..d03baafe3 100644 --- a/content/systems/filecoin_mining/storage_proving/_index.md +++ b/content/systems/filecoin_mining/storage_proving/_index.md @@ -2,6 +2,10 @@ title: Storage Proving weight: 4 bookCollapseSection: true +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Storage Proving diff --git a/content/systems/filecoin_mining/storage_proving/poster/_index.md b/content/systems/filecoin_mining/storage_proving/poster/_index.md index 11c05135e..c5f7a9f12 100644 --- a/content/systems/filecoin_mining/storage_proving/poster/_index.md +++ b/content/systems/filecoin_mining/storage_proving/poster/_index.md @@ -1,6 +1,9 @@ --- -menuTitle: Sector Poster title: Sector Poster +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Sector Poster diff --git a/content/systems/filecoin_mining/storage_proving/sealer/_index.md b/content/systems/filecoin_mining/storage_proving/sealer/_index.md index 04af21ca6..4ddc9c75d 100644 --- a/content/systems/filecoin_mining/storage_proving/sealer/_index.md +++ b/content/systems/filecoin_mining/storage_proving/sealer/_index.md @@ -1,6 +1,9 @@ --- -menuTitle: Sector Sealer title: Sector Sealer +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Sector Sealer diff --git a/content/systems/filecoin_nodes/_index.md b/content/systems/filecoin_nodes/_index.md index f76bd5499..0b4c7bc4c 100644 --- a/content/systems/filecoin_nodes/_index.md +++ b/content/systems/filecoin_nodes/_index.md @@ -2,9 +2,10 @@ title: Filecoin Nodes bookCollapseSection: true weight: 1 -dashboardAudit: 1 +dashboardWeight: 1 dashboardState: incomplete -dashboardInterface: stable +dashboardAudit: 0 +dashboardTests: 0 --- # Filecoin Nodes diff --git a/content/systems/filecoin_nodes/clock/_index.md b/content/systems/filecoin_nodes/clock/_index.md index 893dfc090..ee455a185 100644 --- a/content/systems/filecoin_nodes/clock/_index.md +++ b/content/systems/filecoin_nodes/clock/_index.md @@ -1,6 +1,10 @@ --- title: Clock weight: 4 +dashboardWeight: 1 +dashboardState: stable +dashboardAudit: 0 +dashboardTests: 0 --- # Clock diff --git a/content/systems/filecoin_nodes/network/_index.md b/content/systems/filecoin_nodes/network/_index.md index 91c3a308c..9371b04ad 100644 --- a/content/systems/filecoin_nodes/network/_index.md +++ b/content/systems/filecoin_nodes/network/_index.md @@ -1,6 +1,10 @@ --- title: Network Interface weight: 3 +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Interface diff --git a/content/systems/filecoin_nodes/node_types/_index.md b/content/systems/filecoin_nodes/node_types/_index.md index 976a2b31b..6f22c4c68 100644 --- a/content/systems/filecoin_nodes/node_types/_index.md +++ b/content/systems/filecoin_nodes/node_types/_index.md @@ -2,4 +2,8 @@ title: Node Types weight: 1 bookCollapseSection: true +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- \ No newline at end of file diff --git a/content/systems/filecoin_nodes/node_types/client_node.md b/content/systems/filecoin_nodes/node_types/client_node.md index 9dbc0f168..2d0c32738 100644 --- a/content/systems/filecoin_nodes/node_types/client_node.md +++ b/content/systems/filecoin_nodes/node_types/client_node.md @@ -1,6 +1,10 @@ --- title: Client Node weight: 4 +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Client Node diff --git a/content/systems/filecoin_nodes/node_types/node.md b/content/systems/filecoin_nodes/node_types/node.md index 1abfcb660..c1bb5d57a 100644 --- a/content/systems/filecoin_nodes/node_types/node.md +++ b/content/systems/filecoin_nodes/node_types/node.md @@ -1,6 +1,10 @@ --- title: Node Interface weight: 1 +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Node Interface diff --git a/content/systems/filecoin_nodes/node_types/node_types.md b/content/systems/filecoin_nodes/node_types/node_types.md index 5a1de59bb..7d3a5a854 100644 --- a/content/systems/filecoin_nodes/node_types/node_types.md +++ b/content/systems/filecoin_nodes/node_types/node_types.md @@ -1,6 +1,10 @@ --- title: Examples weight: 2 +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Examples diff --git a/content/systems/filecoin_nodes/node_types/relayer_node.md b/content/systems/filecoin_nodes/node_types/relayer_node.md index 0ec00dd20..78a9b4d40 100644 --- a/content/systems/filecoin_nodes/node_types/relayer_node.md +++ b/content/systems/filecoin_nodes/node_types/relayer_node.md @@ -1,6 +1,10 @@ --- title: Relayer Node weight: 7 +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Relayer Node diff --git a/content/systems/filecoin_nodes/node_types/retrieval_miner_node.md b/content/systems/filecoin_nodes/node_types/retrieval_miner_node.md index 7776c4f19..8fc56e1e7 100644 --- a/content/systems/filecoin_nodes/node_types/retrieval_miner_node.md +++ b/content/systems/filecoin_nodes/node_types/retrieval_miner_node.md @@ -1,6 +1,10 @@ --- title: Retrieval Miner Node weight: 6 +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Retrieval Miner Node diff --git a/content/systems/filecoin_nodes/node_types/storage_miner_node.md b/content/systems/filecoin_nodes/node_types/storage_miner_node.md index 73677ceb0..d42febe80 100644 --- a/content/systems/filecoin_nodes/node_types/storage_miner_node.md +++ b/content/systems/filecoin_nodes/node_types/storage_miner_node.md @@ -1,6 +1,10 @@ --- title: Storage Miner Node weight: 5 +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Storage Miner Node diff --git a/content/systems/filecoin_nodes/node_types/verifier_node.md b/content/systems/filecoin_nodes/node_types/verifier_node.md index 1cf4e194c..f7a77399f 100644 --- a/content/systems/filecoin_nodes/node_types/verifier_node.md +++ b/content/systems/filecoin_nodes/node_types/verifier_node.md @@ -1,6 +1,10 @@ --- title: Chain Verifier Node weight: 3 +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Chain Verifier Node diff --git a/content/systems/filecoin_nodes/repository/_index.md b/content/systems/filecoin_nodes/repository/_index.md index f0abe8fe0..17ddb2a2f 100644 --- a/content/systems/filecoin_nodes/repository/_index.md +++ b/content/systems/filecoin_nodes/repository/_index.md @@ -2,6 +2,10 @@ title: Repository weight: 2 bookCollapseSection: true +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Repository - Local Storage for Chain Data and Systems diff --git a/content/systems/filecoin_nodes/repository/config/_index.md b/content/systems/filecoin_nodes/repository/config/_index.md index a5e5e4e12..b84167046 100644 --- a/content/systems/filecoin_nodes/repository/config/_index.md +++ b/content/systems/filecoin_nodes/repository/config/_index.md @@ -1,6 +1,10 @@ --- title: Config weight: 1 +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Config - Local Storage for Configuration Values diff --git a/content/systems/filecoin_nodes/repository/ipldstore/_index.md b/content/systems/filecoin_nodes/repository/ipldstore/_index.md index ad8a5db9c..25ca635f6 100644 --- a/content/systems/filecoin_nodes/repository/ipldstore/_index.md +++ b/content/systems/filecoin_nodes/repository/ipldstore/_index.md @@ -1,6 +1,10 @@ --- title: IPLD Store weight: 3 +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # IPLD Store - Local Storage for hash-linked data diff --git a/content/systems/filecoin_nodes/repository/key_store/_index.md b/content/systems/filecoin_nodes/repository/key_store/_index.md index fdb442ecc..7091856c0 100644 --- a/content/systems/filecoin_nodes/repository/key_store/_index.md +++ b/content/systems/filecoin_nodes/repository/key_store/_index.md @@ -1,6 +1,10 @@ --- title: Key Store weight: 2 +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Key Store diff --git a/content/systems/filecoin_token/_index.md b/content/systems/filecoin_token/_index.md index 3523369ba..081c89112 100644 --- a/content/systems/filecoin_token/_index.md +++ b/content/systems/filecoin_token/_index.md @@ -2,14 +2,11 @@ title: "Token" bookCollapseSection: true weight: 5 -dashboardAudit: 1 +dashboardWeight: 1 dashboardState: incorrect -dashboardInterface: stable +dashboardAudit: 0 +dashboardTests: 0 --- # Token ---- - -## Status Overview - -{{}} \ No newline at end of file +--- \ No newline at end of file diff --git a/content/systems/filecoin_token/multisig/_index.md b/content/systems/filecoin_token/multisig/_index.md index 70145f5fe..3e4d8ebe0 100644 --- a/content/systems/filecoin_token/multisig/_index.md +++ b/content/systems/filecoin_token/multisig/_index.md @@ -3,4 +3,8 @@ title: Multisig Wallet description: Multisig - Wallet requiring multiple signatures weight: 3 bookCollapseSection: true +dashboardWeight: 1 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- \ No newline at end of file diff --git a/content/systems/filecoin_token/multisig/multisig_actor.md b/content/systems/filecoin_token/multisig/multisig_actor.md index e250198bd..a70a77c04 100644 --- a/content/systems/filecoin_token/multisig/multisig_actor.md +++ b/content/systems/filecoin_token/multisig/multisig_actor.md @@ -1,9 +1,13 @@ --- title: Multisig Actor +dashboardWeight: 1 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # Multisig Actor --- -{{}} -{{}} +{{}} +{{}} diff --git a/content/systems/filecoin_token/payment_channels/_index.md b/content/systems/filecoin_token/payment_channels/_index.md index 1fcf6b4d0..c7d423a59 100644 --- a/content/systems/filecoin_token/payment_channels/_index.md +++ b/content/systems/filecoin_token/payment_channels/_index.md @@ -2,9 +2,10 @@ title: Payment Channels weight: 2 bookCollapseSection: true +dashboardWeight: 1 +dashboardState: incorrect dashboardAudit: 0 -dashboardState: wip -dashboardInterface: wip +dashboardTests: 0 --- # Payment Channels diff --git a/content/systems/filecoin_token/payment_channels/payment_channel_actor.md b/content/systems/filecoin_token/payment_channels/payment_channel_actor.md index b046a050f..faea2596b 100644 --- a/content/systems/filecoin_token/payment_channels/payment_channel_actor.md +++ b/content/systems/filecoin_token/payment_channels/payment_channel_actor.md @@ -1,5 +1,9 @@ --- title: Payment Channel Actor +dashboardWeight: 1 +dashboardState: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # Payment Channel Actor diff --git a/content/systems/filecoin_token/wallets.md b/content/systems/filecoin_token/wallets.md index 15115626c..ec14699f5 100644 --- a/content/systems/filecoin_token/wallets.md +++ b/content/systems/filecoin_token/wallets.md @@ -1,9 +1,10 @@ --- title: Wallet weight: 1 -dashboardAudit: 0 +dashboardWeight: 1 dashboardState: incorrect -dashboardInterface: incorrect +dashboardAudit: 0 +dashboardTests: 0 --- # FIL Wallet diff --git a/content/systems/filecoin_vm/_index.md b/content/systems/filecoin_vm/_index.md index e200f22a6..62a4252df 100644 --- a/content/systems/filecoin_vm/_index.md +++ b/content/systems/filecoin_vm/_index.md @@ -3,17 +3,13 @@ title: Virtual Machine description: VM - Virtual Machine bookCollapseSection: true weight: 3 -dashboardAudit: 1 -dashboardState: permanent -dashboardInterface: stable +dashboardWeight: 2 +dashboardState: wip +dashboardAudit: 0 +dashboardTests: 0 --- # VM - Virtual Machine --- -## Status Overview - -{{}} - - {{}} diff --git a/content/systems/filecoin_vm/actor/_index.md b/content/systems/filecoin_vm/actor/_index.md index 6cd299f36..a137dfd6d 100644 --- a/content/systems/filecoin_vm/actor/_index.md +++ b/content/systems/filecoin_vm/actor/_index.md @@ -1,9 +1,10 @@ --- title: Actor weight: 1 +dashboardWeight: 2 +dashboardState: incomplete dashboardAudit: 0 -dashboardState: stable -dashboardInterface: stable +dashboardTests: 0 --- # VM Actor Interface diff --git a/content/systems/filecoin_vm/indices/_index.md b/content/systems/filecoin_vm/indices/_index.md index f35d7544f..850f4d99f 100644 --- a/content/systems/filecoin_vm/indices/_index.md +++ b/content/systems/filecoin_vm/indices/_index.md @@ -1,14 +1,13 @@ --- title: Indices weight: 3 -dashboardAudit: 0 +dashboardWeight: 1 dashboardState: incomplete -dashboardInterface: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # Macroeconomic Indices --- Indices are a set of global economic indicators computed from State Tree and a collection of pure functions to compute policy output based on user state/action. Indices are used to compute and implement economic mechanisms and policies for the system. There are no persistent states in Indicies. Neither can Indices introduce any state mutation. Note that where indices should live is a design decision. It is possible to break Indices into multiple files or place indices in different actors once all economic mechanisms have been decided on. Temporarily, Indices is a holding file for all potential macroeconomic indicators that the system needs to be aware of. - -{{}} diff --git a/content/systems/filecoin_vm/interpreter/_index.md b/content/systems/filecoin_vm/interpreter/_index.md index 7eeb4b005..0895ad210 100644 --- a/content/systems/filecoin_vm/interpreter/_index.md +++ b/content/systems/filecoin_vm/interpreter/_index.md @@ -1,9 +1,10 @@ --- title: Interpreter weight: 7 +dashboardWeight: 1 +dashboardState: incomplete dashboardAudit: 0 -dashboardState: wip -dashboardInterface: wip +dashboardTests: 0 --- # VM Interpreter - Message Invocation (Outside VM) diff --git a/content/systems/filecoin_vm/message/_index.md b/content/systems/filecoin_vm/message/_index.md index ea4c3db87..a47f52c22 100644 --- a/content/systems/filecoin_vm/message/_index.md +++ b/content/systems/filecoin_vm/message/_index.md @@ -1,9 +1,10 @@ --- title: Message weight: 4 +dashboardWeight: 1.5 +dashboardState: incomplete dashboardAudit: 0 -dashboardState: stable -dashboardInterface: stable +dashboardTests: 0 --- # VM Message - Actor Method Invocation diff --git a/content/systems/filecoin_vm/runtime/_index.md b/content/systems/filecoin_vm/runtime/_index.md index 78fd174b7..c3d803616 100644 --- a/content/systems/filecoin_vm/runtime/_index.md +++ b/content/systems/filecoin_vm/runtime/_index.md @@ -2,9 +2,10 @@ title: Runtime weight: 5 bookCollapseSection: true +dashboardWeight: 1 +dashboardState: incomplete dashboardAudit: 0 -dashboardState: wip -dashboardInterface: wip +dashboardTests: 0 --- # VM Runtime Environment (Inside the VM) @@ -22,7 +23,7 @@ A syntactically valid receipt has: ## `vm/runtime` interface -{{}} +{{}} ## `vm/runtime` implementation @@ -34,4 +35,4 @@ A syntactically valid receipt has: ## Exit codes -{{}} +{{}} diff --git a/content/systems/filecoin_vm/runtime/gascost/_index.md b/content/systems/filecoin_vm/runtime/gascost/_index.md index 3172c0330..bd50cf526 100644 --- a/content/systems/filecoin_vm/runtime/gascost/_index.md +++ b/content/systems/filecoin_vm/runtime/gascost/_index.md @@ -1,5 +1,9 @@ --- title: Gas Costs +dashboardWeight: 1 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # VM Gas Cost Constants diff --git a/content/systems/filecoin_vm/state_tree/_index.md b/content/systems/filecoin_vm/state_tree/_index.md index 413b3d664..88d8a199d 100644 --- a/content/systems/filecoin_vm/state_tree/_index.md +++ b/content/systems/filecoin_vm/state_tree/_index.md @@ -1,9 +1,10 @@ --- title: State Tree weight: 2 +dashboardWeight: 1.5 +dashboardState: incomplete dashboardAudit: 0 -dashboardState: wip -dashboardInterface: stable +dashboardTests: 0 --- # State Tree diff --git a/content/systems/filecoin_vm/sysactors/_index.md b/content/systems/filecoin_vm/sysactors/_index.md index 45d066dbb..4e11b51df 100644 --- a/content/systems/filecoin_vm/sysactors/_index.md +++ b/content/systems/filecoin_vm/sysactors/_index.md @@ -2,9 +2,10 @@ title: System Actors weight: 6 bookCollapseSection: true +dashboardWeight: 2 +dashboardState: incomplete dashboardAudit: 0 -dashboardState: wip -dashboardInterface: wip +dashboardTests: 0 --- # System Actors diff --git a/content/systems/filecoin_vm/sysactors/account_actor.md b/content/systems/filecoin_vm/sysactors/account_actor.md index 34fcc1d57..b582cef40 100644 --- a/content/systems/filecoin_vm/sysactors/account_actor.md +++ b/content/systems/filecoin_vm/sysactors/account_actor.md @@ -1,9 +1,13 @@ --- title: AccountActor weight: 3 +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # AccountActor --- -{{}} +{{}} diff --git a/content/systems/filecoin_vm/sysactors/cron_actor.md b/content/systems/filecoin_vm/sysactors/cron_actor.md index d1b9a54c5..c27651263 100644 --- a/content/systems/filecoin_vm/sysactors/cron_actor.md +++ b/content/systems/filecoin_vm/sysactors/cron_actor.md @@ -1,9 +1,13 @@ --- title: CronActor weight: 2 +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # CronActor --- -{{}} +{{}} diff --git a/content/systems/filecoin_vm/sysactors/init_actor.md b/content/systems/filecoin_vm/sysactors/init_actor.md index 7c0f721bc..2c8f18990 100644 --- a/content/systems/filecoin_vm/sysactors/init_actor.md +++ b/content/systems/filecoin_vm/sysactors/init_actor.md @@ -1,9 +1,13 @@ --- title: InitActor weight: 1 +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # InitActor --- -{{}} +{{}} diff --git a/content/systems/filecoin_vm/sysactors/reward_actor.md b/content/systems/filecoin_vm/sysactors/reward_actor.md index d65f5f3e3..abfe9ec59 100644 --- a/content/systems/filecoin_vm/sysactors/reward_actor.md +++ b/content/systems/filecoin_vm/sysactors/reward_actor.md @@ -1,5 +1,9 @@ --- title: RewardActor +dashboardWeight: 2 +dashboardState: incomplete +dashboardAudit: 0 +dashboardTests: 0 --- # RewardActor @@ -11,4 +15,4 @@ RewardActor is where unminted Filecoin tokens are kept. RewardActor contains a ` A `Reward` struct contains a `StartEpoch` that keeps track of when this `Reward` is created, `Value` that represents the total number of tokens rewarded, and `EndEpoch` which is when the reward will be fully vested. `VestingFunction` is currently an enum to represent the flexibility of different vesting functions. `AmountWithdrawn` records how many tokens have been withdrawn from a `Reward` struct so far. Owner addresses can call `WithdrawReward` which will withdraw all vested tokens that the investor address has from the RewardMap so far. When `AmountWithdrawn` equals `Value` in a `Reward` struct, the `Reward` struct will be removed from the `RewardMap`. -{{}} +{{}} diff --git a/layouts/shortcodes/dashboard-impl.html b/layouts/shortcodes/dashboard-impl.html new file mode 100644 index 000000000..5fc6d206c --- /dev/null +++ b/layouts/shortcodes/dashboard-impl.html @@ -0,0 +1,53 @@ + + + + + + + + + + + + {{- template "dashboard-impls-children" (dict "Section" ($.Site.GetPage "implementations") ) -}} + +
ImplementationTest CoverageCompliance TestsAuditCI
+ + +{{ define "dashboard-impls-children" }} + {{- $pages := where .Section.Pages "Params.bookhidden" "ne" true -}} + {{- range sort $pages "Weight" "asc" -}} + {{ $parts := split .Params.implRepo "/" }} + {{ $size := len $parts }} + {{ $path := delimit (slice (index $parts (sub $size 2)) (index $parts (sub $size 1))) "/" }} + {{ $url := printf "https://codecov.io/api/gh/%s" $path }} + {{ $data := getJSON $url }} + {{ $cov := $data.commit.totals.c }} + {{ $color := "bg-na"}} + {{ if gt $cov 0 }} + {{ $color = "bg-incorrect"}} + {{ else if gt $cov 25 }} + {{ $color = "bg-wip"}} + {{ else if gt $cov 50 }} + {{ $color = "bg-incomplete"}} + {{ else if gt $cov 75 }} + {{ $color = "bg-stable"}} + {{ end }} + + {{.Title}} + + {{ if $data.commit.totals.c }}{{ math.Round $data.commit.totals.c }}%{{ else }}N/A{{end}} + + + {{ .Page.Params.implSpecCompliance }} + + + {{ .Page.Params.implAudit }} + + + + + + + {{ end }} +{{ end }} \ No newline at end of file diff --git a/layouts/shortcodes/dashboard-progress.html b/layouts/shortcodes/dashboard-progress.html new file mode 100644 index 000000000..d4d9a649c --- /dev/null +++ b/layouts/shortcodes/dashboard-progress.html @@ -0,0 +1,55 @@ +{{- with .Site.GetPage "/" -}} + {{- $level := 0 -}} + {{- template "dashboard-progress" (dict "Site" $.Site "level" $level) -}} +{{- end -}} + + +{{ define "dashboard-progress" }} + {{- $count := .level -}} + {{- $countWeight:= 0 -}} + {{- $stable := 0 -}} + {{- $stableWeight := 0 -}} + {{- $pages := where .Site.AllPages "Params.bookhidden" "ne" true -}} + {{- $pages2 := where $pages "Params.dashboardhidden" "ne" true -}} + {{- $pages3 := where $pages2 "Kind" "in" (slice "section" "page") -}} + {{- $pages4 := where $pages3 "Language.Lang" "eq" "en" -}} + {{- range sort $pages4 "Weight" "asc" -}} + {{- if .Params.dashboardState -}} + {{- $count = add $count 1 -}} + {{- $countWeight = add $countWeight (mul 1 (float .Params.dashboardWeight)) -}} + {{- if eq .Params.dashboardState "stable" -}} + {{- $stable = add $stable 1 -}} + {{- $stableWeight = add $stableWeight (mul 1 (float .Params.dashboardWeight)) -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- $perc := lang.NumFmt 2 (div (float (mul $stable 100)) (float $count)) -}} + {{- $perc2 := lang.NumFmt 2 (div (mul $stableWeight 100) $countWeight) -}} + +

Progress

+
+ {{$perc}}% +
+

Consequence

+
+ {{$perc2}}% +
+ +{{ end }} \ No newline at end of file diff --git a/layouts/shortcodes/dashboard-spec.html b/layouts/shortcodes/dashboard-spec.html new file mode 100644 index 000000000..9e6c82614 --- /dev/null +++ b/layouts/shortcodes/dashboard-spec.html @@ -0,0 +1,74 @@ + + +{{- with .Site.GetPage "/" -}} + + + + + + + + + + + + {{- template "dashboard-section-children" (dict "Section" . "level" 0) -}} + +
SectionWeightStateTheory AuditCompliance Tests
+{{- end -}} + + + +{{ define "dashboard-section-children" }} + {{- $level := .level -}} + {{- $level = mul $level 10 -}} + {{- $pages := where .Section.Pages "Params.bookhidden" "ne" true -}} + {{- $pages2 := where $pages "Params.dashboardhidden" "ne" true -}} + {{- range sort $pages2 "Weight" "asc" -}} + {{- $level = add $level 1 -}} + {{- if .IsSection -}} + {{ template "dashboard-tr" (dict "Page" . "Level" $level) }} + {{ template "dashboard-section-children" (dict "Section" . "level" $level) }} + {{ else if and .IsPage .Content }} + {{ template "dashboard-tr" (dict "Page" . "Level" $level) }} + {{ end }} + {{ end }} +{{ end }} + + +{{- define "dashboard-tr" -}} + + + {{- delimit (split .Level "") "." }} + {{.Page.Title}} + + + + {{- (default 0 .Page.Params.dashboardWeight) -}} + + + + {{- if eq .Page.Params.dashboardState "wip" -}} + WIP + {{- else -}} + {{- (default "N/A" (humanize .Page.Params.dashboardState)) -}} + {{- end -}} + + + + {{ .Page.Params.dashboardaudit }} + + + + {{- if eq .Page.Params.dashboardTests 0 -}} + {{ .Page.Params.dashboardTests }} + {{- else if gt .Page.Params.dashboardTests 0 -}} + {{ .Page.Params.dashboardTests }} + {{- else -}} + N/A + {{- end -}} + + +{{- end -}} \ No newline at end of file diff --git a/layouts/shortcodes/pdf.html b/layouts/shortcodes/pdf.html index 664c0f294..07063710a 100644 --- a/layouts/shortcodes/pdf.html +++ b/layouts/shortcodes/pdf.html @@ -1,20 +1,13 @@ -{{ if not (.Page.Scratch.Get "panzoom") }} - - - - {{ .Page.Scratch.Set "panzoom" true }} -{{ end }} - -{{ if (.Get "src") }} +{{- if (.Get "src") -}}

This browser does not support inline PDFs. Please download the PDF to view it: Download {{ .Get "title" }} PDF

-{{ else }} +{{- else -}}
{{- printf "File '%s' not found from Page '%s'" ($.Scratch.Get "filepath") .Page.File }}
{{- warnf "File '%s' not found from Page '%s'" ($.Scratch.Get "filepath") .Page.File }} -{{ end }} \ No newline at end of file +{{- end -}} \ No newline at end of file diff --git a/package.json b/package.json index 922aaa62b..105369583 100644 --- a/package.json +++ b/package.json @@ -5,14 +5,13 @@ "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "serve": "hugo server --bind=0.0.0.0 --disableFastRender", + "serve": "hugo server --bind=0.0.0.0", "build": "hugo --gc --minify" }, "author": "", "license": "MIT", - "dependencies": { - }, + "dependencies": {}, "devDependencies": { - "hugo-extended": "^0.73.0" + "hugo-extended": "^0.74.2" } }