A new proof type which removes on-chain interaction simplifying the whole onboarding pipeline and allowing for a real separation between storage and proving, without compromising security.
Quick Links
📊 Motivation
PoRep is currently interactive and it is composed by two steps: PreCommit
and ProveCommit
.
At PreCommit
SP put down a collateral and wait 150 epochs in order to receive a challenge seed from the chain which enables the ProveCommit
step. This means that
- Mining pipeline is not flexible. In order to add a sector to the network, that sector needs to be first precommited and
ProveCommit
needs to happen within a time window lastingMaxSectorDuration
epochs. - Given
PreCommit
needs a collateral, there is no real possible trustless separation between the entity which stores the sector and the entity which actually proves it. This means that if anyone wants to outsource the task of proving a sector, then the entity which proves and the entity which outsource the task need to agree on who puts down the collateral (trusting the other part).
A first step to mitigate PoRep bottlenecks was the introduction of Synthetic PoRep. Nevertheless, if we really want to remove the aforementioned limitations, NI-PoRep is the way to go: indeed, non interactive PoRep would remove the PreCommit
step, without compromising security, allowing for a simplified pipeline which can reduce costs and enable a full separation between storage and proving. Note that this is particularly relevant now that we have SaaS and SN sealing software (see below).
🗺️ How to get there
There are two ways we can get NI-PoRep
In this doc, we assume to re-use existing circuits.
🚀 Impact on Filecoin
Why NI-PoRep in Filecoin?
Improvements of NI-PoRep vs status quo
🔥 Current Risks
🥜 NI PoRep Protocol in a nutshell
NI-PoRep protocol can be summarized as follows:
Graph Labelling and commitments (similar to the current PC1
and PC2
computation)
- Using
ReplicaID
(which containsCommD
), SP computes the labels for all layers and the replica R; - SP compute the column commitments
CommC
,CommRLast
and finally computesCommR=Poseidon_2(CommC, CommRLast)
;
Storage Provider locally generates NI_ChallengesNumber
challenges and vanilla proofs;
- Each challenge is of the form
ch_i = H(prefix, commR,
tag
, i)
; - SP computes responses for all the
NI_ChallengesNumber
challenges, which result inNI_ChallengesNumber
vanilla proofs;
Storage Provider publishes the new NI_ProveCommitSector
proof
- SP takes the
NI_ChallengesNumber
vanilla proofs and computes the corresponding SNARK proofs for these challenges. - SP publishes the snark and commitment
CommR
(either in individual or aggregated form). - Note in this step the SP will, by default, use the SnarkPack aggregation technique to prove even only one sector (see “product considerations” section for the motivation).
Chain verifies proof
- Using
CommR
as a seed, the chain generatesNI_ChallengesNumber
challenges and this are fed into proof verification
🛑 NI-PoRep Security Considerations
Fiat-Shamir Heuristic and its effects
NI-PoRep is based on the well-known Fiat-Shamir Heuristic, which allows for having a non interactive protocol starting from any 3-message interactive protocol. However, the heuristic requires the interactive protocol to have at least 80 bits of security (instead of the current 10). This means that for NI-PoRep we need 8x challenges compared to the current interactive PoRep protocol to ensure no loss in security with respect to the status quo. Therefore NI_ChallengesNumber
= 1408.
Sectors need to be anchored to the chain: how to take SealRandomness
?
Interactive PoRep
The epoch in which sealing took place is identified by the corresponding chain reference, called SealRandomness
which is the anchor of the sector to the chain. SealRandomness
must be taken from the VRF chain, in order to ensure that no other fork can replay the Seal.
On one hand, SealRandomness
needs to be taken from finalized blocks, but on the other hand it can not be taken farther back than necessary (in order to protect against long-range attacks). This means that SealRandomness
needs to be verified.
Due to current on-chain interaction, randomness verification is not too complicated and works as follows.
Given:
F
– Finality (number of epochs)X
– epoch in which sealing startsZ
– epoch in which the sealed sector appears (in a block)Y
– epoch announced incommitSector
(should be X, but an SP could use any Y <= X)T
– estimated time for sealing, dependent on sector sizeG = T + variance
– necessary flexibility to account for network delay and sealing time variance.
When starting to prepare a seal in epoch X, the SP should draw randomness from X-F with which to compute the seal.
When verifying a seal in round Z, a verifier should ensure that the ticket used to seal the sector is found in the range of epochs [Z-F-G, Z-T-F+G]
.
In practice, the Filecoin protocol will include a MaxSealDuration
for each sector size and proof type.
As a result, each epoch determines the oldest seal challenge epoch that will be accepted in that epoch, defined as
sealChallengeEarliest
= currEpoch
- ChainFinality
- MaxSealDuration
NI-PoRep
If interaction is removed, SealRandomness
verification becomes more difficult, but still necessary to protect the chain against the same class of attacks mentioned above.
We'll set up an interval similar to what we have today, which holds for all the sectors committed onchain together.
This means that, if sealing happens locally over time resulting in different sectors sealed in different moments in time and committed onchain at the end of the process, all sectors committed together should have a randomness which verifies against the same time window.
This means that we have de facto a MaxNI-SealDuration
, which could be potentially set as larger than today, in order to have NI-sealChallengeEarliest
= currEpoch
- ChainFinality
- MaxNI-SealDuration
to be wide enough to fit meaningful use cases, while still preserving security (research needed here in order to find the right value, considering both security and use cases that will be covered).
Note that we could also use the same values as today as an initial step, relaxing the randomness sampling rule for the single sector, while keeping the same sealChallengeEarliest
. In this case we'd have a NI-PoRep step to be completed within sealChallengeEarliest
epochs overall to be valid.
Potential Risks (and mitigations) due to interaction removal
One point to take into account when dealing with NI-PoRep, compared with the status quo, is that a malicious party willing to take over the network could potentially keep accumulating sectors locally adding them to the network all in a sudden.
This could in theory allow for an attack which can not be detected in advance which would result in taking over the entire network.
Why not today?
Such an attack is (in theory) doable today as well. An adversary can add sector until she gets a percentage of the network power which allows for taking over the network. Nevertheless, such a growth in power would be noticed over time, given that each sector, before being added to the network, needs to be precommited.
Does NI-PoRep open the door to Network takeover? TL;DR: NO.
It is true that with NI-PoRep and the associated removal of PreCommit
this traceability of sectors that will be added to the network is not possible anymore. Nevertheless, this is not an issue, for multiple reasons:
- Accumulating sectors and suddenly post them onchain is not the best way to attack the network.
- NI-PoRep removes
PreCommit
and PCD, but keeps IP as it is today. This means that adding EiBs of sectors results in a massive costs both in terms of hardware and pledge. Latest analysis from CryptoNet lab show that network today is mostly secured by pledge, and this is not going to change with NI-PoRep. See and related analysis - Given the point above, cost-wise the best strategy for an adversary willing to takeover the network is actually to bribe and take control of existing sectors for a window of time rather than paying both hardware and pledge cost for adding a massive amount of sectors which need to be maintained later on.
We are not concerned that accumulating sectors and suddenly post them onchain is a real venue for an attack in order to take over the network. We are convinced that NI-PoRep does not augment the risk of such an attack with respect of today. What if we are still concerned this is an issue?
If we are still concerned that too many sectors are added all in a sudden without any possibility of "early detection” we could take one of the following paths:
- Add
NI-Timestamp
message, a light pre-commit-like step in which we timestamp sectors which were sealed in the last 900 epochs (Proposed mitigation, if we are convinced this is a real issue) - Pros: this would both mitigate the aforementioned issue and the anchorage of sectors to the chain
- Cons:
- this solution would re-introduce a sort of pre-commit step, even if way lighter than today.
- No PCD required for
NI-Timestamp
could lead to malicious SP spamming the network with light-precommit messages that do not translate into actual sector added to the network - TODOs: estimate gas costs
- Add a
NI-PreliminaryProof
message, with which an SP need to pre-validate a sector by submitting a valid proof for it. This preliminary proof does not lead to sector activation (we'd still wait the first WindowPost). Note that this would mitigate the spamming issue mentioned above. - Pros: Prevents
NI-Timestamp
messages spamming the network - Cons: Additional gas costs for the preliminary proof
- Bound the per day percentage of NI-PoRep Sector added
- Pros: Practically making takeover using NI-PoRep unfeasible by design
- Cons: Not great from the product perspective. Moreover, it introduces potential coordination issues (what happens to added sector which exceed the cap?)
- Hardcode the maximum number of sectors which can be added with a single NI-PoRep
- Pros: easy change
- Cons: It does not really enforce security against the aforementioned attack in practice (what if a malicious SP adds plenty of NI-PoRep? each one is bounded, but the total is not).
- Limit the number of sectors added for each NI-PoRep to
Max_NI-Sectors
in order to mitigate the potential issue mentioned above and re-estabilish an early detection mechanism. This limitation should take into account that we want NI-PoRep to unlock SN improvements at full potential. this would translate in havingMax_NI-Sectors
≥ maximum number of sectors which can be sealed in parallel. - Note that
Max_NI-Sectors
does not really limit the total number of sector an SP can add, but only the nuemr of sector which can be added in a single NI-PoRep iteration (i.e. a malicious SP can run multiple NI-PoRep iteration and overcome the limit)
🔀 Which Proof System for NI-PoRep? Groth16 Vs Nova
Dealing with NI-PoRep Challenges using Groth16
Using Groth16 to prove NI-PoRep’s 1408 challenges requires generating 79 Groth16 PoRep proofs; each proof having 18 public inputs dedicated to challenges (resulting in a 1422 total challenge public inputs per NI-PoRep). Using SnarkPack, these 79 proofs can be aggregated into a single proof (see a more detailed analysis in Interactive/Non Interactive-PoRep Gas Cost Comparison ).
Dealing with NI-PoRep Challenges using Nova
Using Nova to prove NI-PoRep would produce a single Nova proof per NI-PoRep (this proof may or may not be smaller than 79 Groth16 proofs, but not smaller than a single SnarkPack proof) and would require the generation of slightly fewer challenge public inputs (1408, versus Groth16’s 1422) by the verifier. Because Nova does not require a trusted setup, the PoRep circuit can be augmented to include in-circuit challenge generation, thus reducing the out-of-circuit challenge generation work performed by the verifier.
If challenges are computed in-circuit using a circuit-friendly hash function (e.g. Poseidon), the increase in Nova’s proving/verifying time would be marginal (according to FilCrypto Intuition) and would remove almost all challenge public inputs (the tag
and challenge_index
used in NI-PoRep challenge generation may each require a public input, thus reducing the number of challenge public inputs from 1408 to 2).
Nova Pros and Cons
Nova proving is faster than the current (i.e. non-SupraSeal) Groth16, whereas its verification time is slower than both Groth16 and SnarkPack (however verifying a single Nova proof may be on-par with, or faster than, verifying 79 Groth16 proofs). Nova’s proving time versus SupraSeal has yet to be benchmarked.
A drawback to Nova is that it uses different curve groups and fields than Groth16, thus any sector sealed using Nova NI-PoRep would require also using Nova for PoSt.
Technical Analysis
NI-PoRep: Proving Overhead Analysis
🎯 Workplan (TBD)
📈 Progress so far
👥 People
- Research:
- Luca
- TBD
- Engineering:
- FilCrypto
- PM
- Jennifer (?)
Meeting Notes
Meeting Notes Sept 12 Kuba, LucaMeeting notes Sept 19thInteractive/Non Interactive-PoRep Gas Cost Comparison
NI-PoRep: Proving Overhead Analysis
NI-PoRep Sector Gas Balancer [WIP]
Potential Risks (and mitigations) due to interaction removal