$$ \def\line#1{{{\small \rm \rlap{#1.}\hphantom{10.}} \ \ }} \def\SECTORSIZE{\textsf{SECTOR_SIZE}} \def\ReplicaID{\text{ReplicaID}} \def\NIPARTS{\textsf{NI_POREP_PARTITIONS}} \def\NICHALLENGES{\textsf{NI_POREP_CHALLENGES}} \def\PARTCHALLENGES{\textsf{POREP_PARTITION_CHALLENGES}} \def\thin{\thinspace} \def\const{\textbf{const }} \def\type{\textbf{type }} \def\bullet{\ {\small \text{• }}} $$ # NI-PoRep Audit Spec ## Constants & Types $\bullet \const \SECTORSIZE \in \{2 \text{ KiB}, 4 \text{ KiB}, 16 \text{ KiB}, 32 \text{ KiB}, 8 \text{ MiB}, 16 \text{ MiB}, 512 \text{ MiB}, 1 \text{ GiB}, 32 \text{ GiB}, 64 \text{ GiB}\}$ $\bullet \const \textsf{SECTOR_NODES} = {\SECTORSIZE \over 32 \text{ bytes per node}}$ $\bullet \type \ReplicaID \equiv [\texttt{u8;} \thin 32]$ $\bullet \type \text{CommR} \equiv [\texttt{u8;} \thin 32]$ ${\small \text{• }} \type \text{Challenge} \equiv \mathbb{N} \in [1, \textsf{SECTOR_NODES})$ ### PoRep [Interactive]: $\bullet \const \PARTCHALLENGES = \begin{cases}18 & \text{if } \SECTORSIZE \geq 32 \text{ GiB} \\ 2 & \text{otherwise}\end{cases}$ $\bullet \const \textsf{POREP_MIN_CHALLENGES} = \begin{cases} 176 & \text{if } \SECTORSIZE \geq 32\ \text{GiB} \\ 2 &\text{otherwise}\end{cases}$ ### NI-PoRep: $\bullet \const \textsf{NI_POREP_MIN_CHALLENGES} = \left\lceil 12.8 * \textsf{POREP_MIN_CHALLENGES} \right\rceil = \begin{cases}2253 & \text{if } \SECTORSIZE \geq 32 \text{ GiB} \\ 26 & \text{otherwise}\end{cases}$ $\bullet \const \NIPARTS = \left\lceil {\textsf{NI_POREP_MIN_CHALLENGES} \over \PARTCHALLENGES} \right\rceil = \begin{cases}126 & \text{if } \SECTORSIZE \geq 32 \text{ GiB} \\ 13 & \text{otherwise}\end{cases}$ $\bullet \const \NICHALLENGES = \NIPARTS * \PARTCHALLENGES = \begin{cases} 2268 & \text{if } \SECTORSIZE \geq 32\ \text{GiB} \\ 2 &\text{otherwise}\end{cases}$ ## Challenge Generation [Link to challenge generation code in `rust-fil-proofs`](https://github.com/filecoin-project/rust-fil-proofs/blob/23c09732dd56c384078b76c3ba36be69f5118e07/storage-proofs-porep/src/stacked/vanilla/challenges.rs#L127-L157) $\bullet \const \textsf{NI_POREP_CHALLENGE_GEN_TAG}: [\texttt{u8;}\thin 36] = \texttt{utf8_bytes}(\text{“filecoin.io|PoRep|1|NonInteractive|1"})$ $\overline{\underline{\text{Function:}\ \texttt{gen_niporep_challenges}(\text{ReplicaID}, \text{CommR}) \rightarrow \left[\text{Challenge} \texttt{;}\thin \NICHALLENGES\right]}}$ $\line{1} \text{challenges}: [\text{Challenge} \texttt{;}\thin \NICHALLENGES] = [\thinspace]$ $\line{2} \text{preimg_prefix}: [\texttt{u8}; 100] = \textsf{NI_POREP_CHALLENGE_GEN_TAG} \mathbin\Vert \text{ReplicaID} \mathbin\Vert \text{CommR}$ $\line{3} \texttt{for } \text{challenge_index} \in [0, \textsf{NI_POREP_CHALLENGES})\thinspace \textbf{:}$ $\line{4} \quad \text{preimg}: [\texttt{u8}; 104] = \text{preimg_prefix} \mathbin\Vert \texttt{le_bytes}(\text{challenge_index}, 4)$ $\line{5} \quad \text{digest_words}: [\texttt{u32}; 8] = \texttt{sha256}(\text{preimg})$ $\line{6} \quad \text{digest_int}: \texttt{u256} = \texttt{u256::from_le_u32s}(\text{digest_words})$ $\line{7} \quad \text{challenge}: \text{Challenge} = (\text{digest_int} \mathbin\% (\text{SECTOR_NODES} - 1)) + 1$ $\line{8} \quad \text{challenges}\textbf{.}\texttt{push}(\text{challenge})$ $\line{9} \texttt{return } \text{challenges}$ ## Groth16 Proving $\bullet \textbf{const } \textsf{POREP_MAX_GROTH16_BATCH_SIZE} = 10$ $\overline{\underline{\text{Function:}\ \texttt{ni_porep_groth16_batch_prove}(\text{circuits}: [\text{PoRepCircuit}\texttt{;}\thin \NIPARTS]) \rightarrow [\text{Groth16Proof}\texttt{;}\thin \NIPARTS]}}$ $\line{1} \text{groth16_proofs}: [\text{Groth16Proof}; \NIPARTS] = [\thin]$ $\line{2} \textbf{for } \text{circuit_batch} \in \text{circuits}\texttt{.chunks}(\textsf{POREP_MAX_GROTH16_BATCH_SIZE}) \thin\textbf{:}$ $\line{3} \quad \text{groth16_proofs} = \text{groth16_proofs} \mathbin{\Vert} \texttt{groth16_batch_prove}(\text{circuit_batch})$ $\line{4} \texttt{return } \text{groth16_proofs}$ ## Groth16 Aggregation [Link to NI-PoRep SnarkPack proving in `rust-fil-proofs`](https://github.com/filecoin-project/rust-fil-proofs/blob/23c09732dd56c384078b76c3ba36be69f5118e07/filecoin-proofs/src/api/seal.rs#L570-L579) [Link to NI-PoRep SnarkPack verification in `rust-fil-proofs`](https://github.com/filecoin-project/rust-fil-proofs/blob/23c09732dd56c384078b76c3ba36be69f5118e07/filecoin-proofs/src/api/seal.rs#L906-L924) $\overline{\text{Function:}\ \texttt{ni_porep_snarkpack_aggregate}( \quad\quad\quad\quad\quad\quad\quad\quad}$ $\quad \textsf{groth16_proofs}: [\text{Groth16Proof}\texttt{;}\thin \NIPARTS],$ $\quad \textsf{comm_r}: \text{CommR},$ $\quad \textsf{challenge_seed}: [\texttt{u8;} \thin 32],$ $\underline{) \rightarrow \text{SnarkPackProof}\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\ \ }$ $\line{1} \textsf{proofs_len} = \NIPARTS$ $\line{2} \textsf{agg_proofs_len} = 2^{\lceil \log_2(\textsf{proofs_len}) \rceil}$ $\line{3} \textsf{agg_pad_len} = \textsf{agg_proofs_len} - \textsf{proofs_len}$ $\line{4} \textsf{proofs_padded}: [\text{Groth16Proof} \texttt{;}\thin \textsf{agg_proofs_len}] = \textsf{groth16_proofs} \mathbin\Vert [\textsf{groth16_proofs}\texttt{.last}() \texttt{;}\thin \textsf{agg_pad_len}]$ $\line{5} \textsf{transcript}: [\texttt{u8;} 32] = \texttt{sha256}(\textsf{challenge_seed} \mathbin\Vert \textsf{comm_r})$ $\line{6} \texttt{return snarkpack_prove}(\textsf{proofs_padded}, \textsf{transcript})$