Skip to content

Commit 05735bf

Browse files
committed
feat: expose SnarkPack for Empty Sector Updates aggregation API
1 parent d1ad2f5 commit 05735bf

File tree

4 files changed

+183
-7
lines changed

4 files changed

+183
-7
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ blstrs = "0.7"
1515
lazy_static = "1.2"
1616
serde = "1.0.104"
1717
filecoin-proofs-v1 = { package = "filecoin-proofs", version = "~18.1.0", default-features = false }
18+
filecoin-hashers = { version = "~13.1.0", default-features = false, features = ["poseidon", "sha256"] }
1819
fr32 = { version = "~11.1.0", default-features = false }
1920
storage-proofs-core = { version = "~18.1.0", default-features = false }
2021

src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ pub use crate::registry::{
3030
pub use crate::types::{PartitionProofBytes, PrivateReplicaInfo, PublicReplicaInfo};
3131

3232
pub use filecoin_proofs_v1::types::{
33-
AggregateSnarkProof, ChallengeSeed, Commitment, PaddedBytesAmount, PartitionSnarkProof,
34-
PieceInfo, PoStType, ProverId, Ticket, UnpaddedByteIndex, UnpaddedBytesAmount,
33+
AggregateSnarkProof, ChallengeSeed, Commitment, EmptySectorUpdateProof, PaddedBytesAmount,
34+
PartitionSnarkProof, PieceInfo, PoStType, ProverId, SectorUpdateProofInputs, Ticket,
35+
UnpaddedByteIndex, UnpaddedBytesAmount,
3536
};
3637
pub use filecoin_proofs_v1::{FallbackPoStSectorProof, SnarkProof, VanillaProof};
3738
pub use fr32;

src/seal.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,8 +1067,7 @@ pub fn aggregate_seal_commit_proofs(
10671067
)
10681068
}
10691069

1070-
// TODO: Does this need to be public?
1071-
pub fn aggregate_seal_commit_proofs_inner<Tree: 'static + MerkleTreeTrait>(
1070+
fn aggregate_seal_commit_proofs_inner<Tree: 'static + MerkleTreeTrait>(
10721071
registered_proof: RegisteredSealProof,
10731072
comm_rs: &[Commitment],
10741073
seeds: &[Ticket],

src/update.rs

Lines changed: 178 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,19 @@ use std::io::{Read, Write};
33
use std::path::Path;
44

55
use anyhow::{ensure, Result};
6+
use bellperson::groth16::aggregate::AggregateVersion;
7+
use blstrs::Scalar as Fr;
68

79
use filecoin_proofs_v1::types::{
810
EmptySectorUpdateEncoded, EmptySectorUpdateProof, MerkleTreeTrait, PartitionProof,
9-
SectorUpdateConfig,
11+
SectorUpdateConfig, SectorUpdateProofInputs, TreeRHasher,
1012
};
11-
use filecoin_proofs_v1::{with_shape, TreeRHasher};
13+
use filecoin_proofs_v1::with_shape;
1214

13-
use crate::{types::PartitionProofBytes, Commitment, PieceInfo, RegisteredUpdateProof};
15+
use crate::{
16+
types::PartitionProofBytes, AggregateSnarkProof, Commitment, PieceInfo,
17+
RegisteredAggregationProof, RegisteredUpdateProof,
18+
};
1419

1520
fn empty_sector_update_encode_into_inner<Tree: 'static + MerkleTreeTrait<Hasher = TreeRHasher>>(
1621
registered_proof: RegisteredUpdateProof,
@@ -621,3 +626,173 @@ pub fn verify_empty_sector_update_proof(
621626
comm_d_new,
622627
)
623628
}
629+
630+
/// Given a `registered_proof` type and a list of sector update proofs, this method aggregates
631+
/// those proofs (naively padding the count if necessary up to a power of 2) and
632+
/// returns the aggregate proof bytes.
633+
///
634+
/// # Arguments
635+
///
636+
/// * `registered_proof` - Selected sector update operation.
637+
/// * `registered_aggregation` - Aggregation proof types; note that this method only supports SnarkPackV2+.
638+
/// * `sector_update_inputs` - Ordered list of input commitments used to generate the individual sector update proofs.
639+
/// * `sector_update_proofs` - Ordered list of sector update proofs.
640+
///
641+
/// Returns aggregate of zk-SNARK proofs in [`AggregateSnarkProof`].
642+
pub fn aggregate_empty_sector_update_proofs(
643+
registered_proof: RegisteredUpdateProof,
644+
registered_aggregation: RegisteredAggregationProof,
645+
sector_update_inputs: &[SectorUpdateProofInputs],
646+
sector_update_proofs: &[filecoin_proofs_v1::types::EmptySectorUpdateProof],
647+
) -> Result<AggregateSnarkProof> {
648+
ensure!(
649+
registered_proof.major_version() == 1,
650+
"unusupported version"
651+
);
652+
653+
ensure!(
654+
registered_aggregation == RegisteredAggregationProof::SnarkPackV2,
655+
"unsupported aggregation or registered proof version"
656+
);
657+
658+
let aggregate_version = AggregateVersion::V2;
659+
660+
with_shape!(
661+
u64::from(registered_proof.sector_size()),
662+
aggregate_empty_sector_update_proofs_inner,
663+
registered_proof,
664+
sector_update_inputs,
665+
sector_update_proofs,
666+
aggregate_version,
667+
)
668+
}
669+
670+
fn aggregate_empty_sector_update_proofs_inner<
671+
Tree: 'static + MerkleTreeTrait<Hasher = TreeRHasher>,
672+
>(
673+
registered_proof: RegisteredUpdateProof,
674+
sector_update_inputs: &[SectorUpdateProofInputs],
675+
sector_update_proofs: &[EmptySectorUpdateProof],
676+
aggregate_version: AggregateVersion,
677+
) -> Result<AggregateSnarkProof> {
678+
let config = registered_proof.as_v1_config();
679+
680+
filecoin_proofs_v1::aggregate_empty_sector_update_proofs::<Tree>(
681+
&config,
682+
sector_update_proofs,
683+
sector_update_inputs,
684+
aggregate_version,
685+
)
686+
}
687+
688+
/// Given the specified arguments, this method returns the inputs that were used to
689+
/// generate the sector update proof. This can be useful for proof aggregation, as verification
690+
/// requires these inputs.
691+
///
692+
/// This method allows them to be retrieved when needed, rather than storing them for
693+
/// some amount of time.
694+
///
695+
/// # Arguments
696+
///
697+
/// * `registered_proof` - Selected sector update proof operation.
698+
/// * `comm_r_old` - A commitment to a sector's previous replica.
699+
/// * `comm_r_new` - A commitment to a sector's current replica.
700+
/// * `comm_d_new` - A commitment to a sector's current data.
701+
///
702+
/// Returns the inputs that were used to generate seal proof.
703+
pub fn get_sector_update_inputs(
704+
registered_proof: RegisteredUpdateProof,
705+
comm_r_old: Commitment,
706+
comm_r_new: Commitment,
707+
comm_d_new: Commitment,
708+
) -> Result<Vec<Vec<Fr>>> {
709+
ensure!(
710+
registered_proof.major_version() == 1,
711+
"unusupported version"
712+
);
713+
714+
with_shape!(
715+
u64::from(registered_proof.sector_size()),
716+
get_sector_update_inputs_inner,
717+
registered_proof,
718+
comm_r_old,
719+
comm_r_new,
720+
comm_d_new,
721+
)
722+
}
723+
724+
fn get_sector_update_inputs_inner<Tree: 'static + MerkleTreeTrait<Hasher = TreeRHasher>>(
725+
registered_proof: RegisteredUpdateProof,
726+
comm_r_old: Commitment,
727+
comm_r_new: Commitment,
728+
comm_d_new: Commitment,
729+
) -> Result<Vec<Vec<Fr>>> {
730+
let config = registered_proof.as_v1_config();
731+
732+
filecoin_proofs_v1::get_sector_update_inputs::<Tree>(
733+
&config, comm_r_old, comm_r_new, comm_d_new,
734+
)
735+
}
736+
737+
/// Given a `registered_proof`, an aggregate proof, a list of proofs and a combined and flattened
738+
/// list of sector update public inputs, this method verifies the aggregate empty sector update proof.
739+
///
740+
/// # Arguments
741+
///
742+
/// * `registered_proof` - Selected seal operation.
743+
/// * `registered_aggregation` - Aggregation proof types.
744+
/// * `aggregate_proof_bytes` - The returned aggregate proof from [`aggregate_empty_sector_update_proofs`].
745+
/// * `inputs` - Ordered list of sector update input commitments.
746+
/// * `sector_update_inputs` - A flattened/combined and ordered list of all public inputs, which must match
747+
/// the ordering of the sector update proofs when aggregated.
748+
///
749+
/// Returns true if proof is validated.
750+
pub fn verify_aggregate_empty_sector_update_proofs(
751+
registered_proof: RegisteredUpdateProof,
752+
registered_aggregation: RegisteredAggregationProof,
753+
aggregate_proof_bytes: AggregateSnarkProof,
754+
inputs: &[SectorUpdateProofInputs],
755+
sector_update_inputs: Vec<Vec<Fr>>,
756+
) -> Result<bool> {
757+
ensure!(
758+
registered_proof.major_version() == 1,
759+
"unusupported version"
760+
);
761+
762+
ensure!(
763+
registered_aggregation == RegisteredAggregationProof::SnarkPackV2,
764+
"unsupported aggregation or registered proof version"
765+
);
766+
767+
let aggregate_version = AggregateVersion::V2;
768+
769+
with_shape!(
770+
u64::from(registered_proof.sector_size()),
771+
verify_aggregate_empty_sector_update_proofs_inner,
772+
registered_proof,
773+
aggregate_proof_bytes,
774+
inputs,
775+
sector_update_inputs,
776+
aggregate_version,
777+
)
778+
}
779+
780+
fn verify_aggregate_empty_sector_update_proofs_inner<
781+
Tree: 'static + MerkleTreeTrait<Hasher = TreeRHasher>,
782+
>(
783+
registered_proof: RegisteredUpdateProof,
784+
aggregate_proof_bytes: AggregateSnarkProof,
785+
inputs: &[SectorUpdateProofInputs],
786+
sector_update_inputs: Vec<Vec<Fr>>,
787+
aggregate_version: AggregateVersion,
788+
) -> Result<bool> {
789+
let config = registered_proof.as_v1_config();
790+
791+
filecoin_proofs_v1::verify_aggregate_sector_update_proofs::<Tree>(
792+
&config,
793+
aggregate_proof_bytes,
794+
inputs,
795+
sector_update_inputs,
796+
aggregate_version,
797+
)
798+
}

0 commit comments

Comments
 (0)