Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: expose SnarkPack for Empty Sector Updates aggregation API #96

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ readme = "README.md"

[dependencies]
anyhow = "1.0.26"
bellperson = "0.26.0"
bincode = "1.1.2"
blstrs = "0.7"
lazy_static = "1.2"
serde = "1.0.104"
filecoin-proofs-v1 = { package = "filecoin-proofs", version = "~18.1.0", default-features = false }
fr32 = { version = "~11.1.0", default-features = false }
storage-proofs-core = { version = "~18.1.0", default-features = false }
#filecoin-proofs-v1 = { package = "filecoin-proofs", version = "~18.1.0", default-features = false }
#fr32 = { version = "~11.1.0", default-features = false }
#storage-proofs-core = { version = "~18.1.0", default-features = false }
filecoin-proofs-v1 = { git = "https://github.com/filecoin-project/rust-fil-proofs", branch = "hanabi1224-upgrade-deps", package = "filecoin-proofs", default-features = false }
fr32 = { git = "https://github.com/filecoin-project/rust-fil-proofs", branch = "hanabi1224-upgrade-deps", default-features = false }
storage-proofs-core = { git = "https://github.com/filecoin-project/rust-fil-proofs", branch = "hanabi1224-upgrade-deps", default-features = false }

[features]
default = ["opencl", "cuda"]
Expand Down
2 changes: 1 addition & 1 deletion rust-toolchain
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.70.0
1.83.0
5 changes: 3 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ pub use crate::registry::{
pub use crate::types::{PartitionProofBytes, PrivateReplicaInfo, PublicReplicaInfo};

pub use filecoin_proofs_v1::types::{
AggregateSnarkProof, ChallengeSeed, Commitment, PaddedBytesAmount, PartitionSnarkProof,
PieceInfo, PoStType, ProverId, Ticket, UnpaddedByteIndex, UnpaddedBytesAmount,
AggregateSnarkProof, ChallengeSeed, Commitment, EmptySectorUpdateProof, PaddedBytesAmount,
PartitionSnarkProof, PieceInfo, PoStType, ProverId, SectorUpdateProofInputs, Ticket,
UnpaddedByteIndex, UnpaddedBytesAmount,
};
pub use filecoin_proofs_v1::{FallbackPoStSectorProof, SnarkProof, VanillaProof};
pub use fr32;
Expand Down
16 changes: 9 additions & 7 deletions src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -766,7 +766,7 @@ impl RegisteredUpdateProof {

match self {
StackedDrg2KiBV1 | StackedDrg8MiBV1 | StackedDrg512MiBV1 | StackedDrg32GiBV1
| StackedDrg64GiBV1 => ApiVersion::V1_1_0,
| StackedDrg64GiBV1 => ApiVersion::V1_2_0,
}
}

Expand Down Expand Up @@ -865,7 +865,7 @@ impl RegisteredUpdateProof {
match self {
StackedDrg2KiBV1 | StackedDrg8MiBV1 | StackedDrg512MiBV1 | StackedDrg32GiBV1
| StackedDrg64GiBV1 => {
assert_eq!(self.version(), ApiVersion::V1_1_0);
assert_eq!(self.version(), ApiVersion::V1_2_0);
PoRepConfig {
sector_size: self.sector_size(),
partitions: PoRepProofPartitions(self.partitions()),
Expand Down Expand Up @@ -982,6 +982,8 @@ mod tests {
}

fn test_porep_id_aux(rsp: &RegisteredSealProof) {
use std::fmt::Write;

let expected_porep_id = match rsp {
RegisteredSealProof::StackedDrg2KiBV1 => {
"0000000000000000000000000000000000000000000000000000000000000000"
Expand Down Expand Up @@ -1044,11 +1046,11 @@ mod tests {
"1300000000000000000000000000000000000000000000000000000000000000"
}
};
let hex: String = rsp
.porep_id()
.iter()
.map(|x| format!("{:01$x}", x, 2))
.collect();
let hex: String = rsp.porep_id().iter().fold(String::new(), |mut output, x| {
//let _ = write!("{:01$x}", x, 2);
let _ = write!(output, "{:01$x}", x, 2);
output
});

assert_eq!(expected_porep_id, &hex);
}
Expand Down
5 changes: 2 additions & 3 deletions src/seal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1085,8 +1085,7 @@ pub fn aggregate_seal_commit_proofs(
)
}

// TODO: Does this need to be public?
pub fn aggregate_seal_commit_proofs_inner<Tree: 'static + MerkleTreeTrait>(
fn aggregate_seal_commit_proofs_inner<Tree: 'static + MerkleTreeTrait>(
registered_proof: RegisteredSealProof,
comm_rs: &[Commitment],
seeds: &[Ticket],
Expand Down Expand Up @@ -1805,7 +1804,7 @@ pub fn unseal_range<T: Into<PathBuf> + AsRef<Path>, R: Read, W: Write>(
///
/// * `registered_proof` - Selected seal proof for this byte source.
/// * `source` - A readable source of unprocessed piece bytes. The piece's commitment will be
/// generated for the bytes read from the source plus any added padding.
/// generated for the bytes read from the source plus any added padding.
/// * `piece_size` - The number of unpadded user-bytes which can be read from source before EOF.
///
/// Returns piece commitment in [`PieceInfo`] struct.
Expand Down
187 changes: 184 additions & 3 deletions src/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@ use std::io::{Read, Write};
use std::path::Path;

use anyhow::{ensure, Result};
use bellperson::groth16::aggregate::AggregateVersion;
use blstrs::Scalar as Fr;

use filecoin_proofs_v1::types::{
EmptySectorUpdateEncoded, EmptySectorUpdateProof, MerkleTreeTrait, PartitionProof,
SectorUpdateConfig,
SectorUpdateConfig, SectorUpdateProofInputs, TreeRHasher,
};
use filecoin_proofs_v1::{with_shape, TreeRHasher};
use filecoin_proofs_v1::with_shape;

use crate::{types::PartitionProofBytes, Commitment, PieceInfo, RegisteredUpdateProof};
use crate::{
types::PartitionProofBytes, AggregateSnarkProof, Commitment, PieceInfo,
RegisteredAggregationProof, RegisteredUpdateProof,
};

fn empty_sector_update_encode_into_inner<Tree: 'static + MerkleTreeTrait<Hasher = TreeRHasher>>(
registered_proof: RegisteredUpdateProof,
Expand Down Expand Up @@ -621,3 +626,179 @@ pub fn verify_empty_sector_update_proof(
comm_d_new,
)
}

/// Given a `registered_proof` type and a list of sector update proofs, this method aggregates
/// those proofs (naively padding the count if necessary up to a power of 2) and
/// returns the aggregate proof bytes.
///
/// # Arguments
///
/// * `registered_proof` - Selected sector update operation.
/// * `registered_aggregation` - Aggregation proof types; note that this method only supports SnarkPackV2+.
/// * `sector_update_inputs` - Ordered list of input commitments used to generate the individual sector update proofs.
/// * `sector_update_proofs` - Ordered list of sector update proofs.
///
/// Returns aggregate of zk-SNARK proofs in [`AggregateSnarkProof`].
pub fn aggregate_empty_sector_update_proofs(
registered_proof: RegisteredUpdateProof,
registered_aggregation: RegisteredAggregationProof,
sector_update_inputs: &[SectorUpdateProofInputs],
sector_update_proofs: &[filecoin_proofs_v1::types::EmptySectorUpdateProof],
) -> Result<AggregateSnarkProof> {
ensure!(
registered_proof.major_version() == 1,
"unusupported version"
);

ensure!(
registered_aggregation == RegisteredAggregationProof::SnarkPackV2,
"unsupported aggregation or registered proof version"
);

let aggregate_version = AggregateVersion::V2;

with_shape!(
u64::from(registered_proof.sector_size()),
aggregate_empty_sector_update_proofs_inner,
registered_proof,
sector_update_inputs,
sector_update_proofs,
aggregate_version,
)
}

fn aggregate_empty_sector_update_proofs_inner<
Tree: 'static + MerkleTreeTrait<Hasher = TreeRHasher>,
>(
registered_proof: RegisteredUpdateProof,
sector_update_inputs: &[SectorUpdateProofInputs],
sector_update_proofs: &[EmptySectorUpdateProof],
aggregate_version: AggregateVersion,
) -> Result<AggregateSnarkProof> {
let config = registered_proof.as_v1_config();

filecoin_proofs_v1::aggregate_empty_sector_update_proofs::<Tree>(
&config,
sector_update_proofs,
sector_update_inputs,
aggregate_version,
)
}

/// Given the specified arguments, this method returns the inputs that were used to
/// generate the sector update proof. This can be useful for proof aggregation, as verification
/// requires these inputs.
///
/// This method allows them to be retrieved when needed, rather than storing them for
/// some amount of time.
///
/// # Arguments
///
/// * `registered_proof` - Selected sector update proof operation.
/// * `comm_r_old` - A commitment to a sector's previous replica.
/// * `comm_r_new` - A commitment to a sector's current replica.
/// * `comm_d_new` - A commitment to a sector's current data.
///
/// Returns the inputs that were used to generate seal proof.
pub fn get_sector_update_inputs(
registered_proof: RegisteredUpdateProof,
comm_r_old: Commitment,
comm_r_new: Commitment,
comm_d_new: Commitment,
) -> Result<Vec<Vec<Fr>>> {
ensure!(
registered_proof.major_version() == 1,
"unusupported version"
);

with_shape!(
u64::from(registered_proof.sector_size()),
get_sector_update_inputs_inner,
registered_proof,
comm_r_old,
comm_r_new,
comm_d_new,
)
}

fn get_sector_update_inputs_inner<Tree: 'static + MerkleTreeTrait<Hasher = TreeRHasher>>(
registered_proof: RegisteredUpdateProof,
comm_r_old: Commitment,
comm_r_new: Commitment,
comm_d_new: Commitment,
) -> Result<Vec<Vec<Fr>>> {
let config = registered_proof.as_v1_config();

filecoin_proofs_v1::get_sector_update_inputs::<Tree>(
&config, comm_r_old, comm_r_new, comm_d_new,
)
}

pub fn get_sector_update_h(registered_proof: RegisteredUpdateProof) -> usize {
let config = registered_proof.as_v1_config();

filecoin_proofs_v1::get_sector_update_h_select_from_porep_config(&config)
}

/// Given a `registered_proof`, an aggregate proof, a list of proofs and a combined and flattened
/// list of sector update public inputs, this method verifies the aggregate empty sector update proof.
///
/// # Arguments
///
/// * `registered_proof` - Selected seal operation.
/// * `registered_aggregation` - Aggregation proof types.
/// * `aggregate_proof_bytes` - The returned aggregate proof from [`aggregate_empty_sector_update_proofs`].
/// * `inputs` - Ordered list of sector update input commitments.
/// * `sector_update_inputs` - A flattened/combined and ordered list of all public inputs, which must match
/// the ordering of the sector update proofs when aggregated.
///
/// Returns true if proof is validated.
pub fn verify_aggregate_empty_sector_update_proofs(
registered_proof: RegisteredUpdateProof,
registered_aggregation: RegisteredAggregationProof,
aggregate_proof_bytes: AggregateSnarkProof,
inputs: &[SectorUpdateProofInputs],
sector_update_inputs: Vec<Vec<Fr>>,
) -> Result<bool> {
ensure!(
registered_proof.major_version() == 1,
"unusupported version"
);

ensure!(
registered_aggregation == RegisteredAggregationProof::SnarkPackV2,
"unsupported aggregation or registered proof version"
);

let aggregate_version = AggregateVersion::V2;

with_shape!(
u64::from(registered_proof.sector_size()),
verify_aggregate_empty_sector_update_proofs_inner,
registered_proof,
aggregate_proof_bytes,
inputs,
sector_update_inputs,
aggregate_version,
)
}

fn verify_aggregate_empty_sector_update_proofs_inner<
Tree: 'static + MerkleTreeTrait<Hasher = TreeRHasher>,
>(
registered_proof: RegisteredUpdateProof,
aggregate_proof_bytes: AggregateSnarkProof,
inputs: &[SectorUpdateProofInputs],
sector_update_inputs: Vec<Vec<Fr>>,
aggregate_version: AggregateVersion,
) -> Result<bool> {
let config = registered_proof.as_v1_config();

filecoin_proofs_v1::verify_aggregate_sector_update_proofs::<Tree>(
&config,
aggregate_proof_bytes,
inputs,
sector_update_inputs,
aggregate_version,
)
}