Skip to content

Commit 9c60e91

Browse files
authored
fix: 1GiB sectors porep & post key (#791)
1 parent c89551c commit 9c60e91

File tree

11 files changed

+105
-22
lines changed

11 files changed

+105
-22
lines changed

Diff for: .gitattributes

+2
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
Cargo.lock -diff
2+
*.vk binary
3+
*.vk.scale binary

Diff for: .gitignore

+4-4
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,13 @@ coverage/
3131

3232
# PoRep Params
3333
*.porep.params
34-
*.porep.vk
35-
*.porep.vk.scale
34+
/*.porep.vk
35+
/*.porep.vk.scale
3636

3737
# PoSt Params
3838
*.post.params
39-
*.post.vk
40-
*.post.vk.scale
39+
/*.post.vk
40+
/*.post.vk.scale
4141

4242
# File logs from the SP
4343
logs/

Diff for: examples/1GiB.porep.vk

31.6 KB
Binary file not shown.

Diff for: examples/1GiB.porep.vk.scale

15.8 KB
Binary file not shown.

Diff for: examples/1GiB.post.vk

2.37 MB
Binary file not shown.

Diff for: examples/1GiB.post.vk.scale

1.18 MB
Binary file not shown.

Diff for: lib/polka-storage-proofs/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ workspace = true
4040

4141
[features]
4242
cuda = ["filecoin-proofs?/cuda", "filecoin-proofs?/multicore-sdr", "std"]
43-
default = ["opencl"]
43+
default = ["opencl", "substrate"]
4444
opencl = ["filecoin-proofs?/multicore-sdr", "filecoin-proofs?/opencl", "std"]
4545
std = [
4646
"codec?/std",

Diff for: lib/polka-storage-proofs/src/groth16/mod.rs

+25-10
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,15 @@ const G1AFFINE_UNCOMPRESSED_BYTES: usize = 96;
5050
/// The number of bytes when serialising a `G1Affine` by using `G1Affine::to_uncompressed()`.
5151
const G2AFFINE_UNCOMPRESSED_BYTES: usize = 192;
5252

53+
/// Number of G1Affine constants in a [`VerifyingKey`].
54+
const G1AFFINE_PARAMS: usize = 3;
55+
/// Number of G2Affine constants in a [`VerifyingKey`].
56+
const G2AFFINE_PARAMS: usize = 3;
57+
/// Maximum number of ic params in a [`VerifyingKey`] in a secure PoRep of Sector Size of 1GiB.
58+
const MAX_PRODUCTION_POREP_VK_IC_LEN: usize = 328;
59+
/// Maximum number of ic params in a [`VerifyingKey`] in a secure PoSt of Sector Size of 1GiB.
60+
const MAX_PRODUCTION_POST_VK_IC_LEN: usize = 25840;
61+
5362
/// This constant specifies the minimum number of bytes of a serialised `VerifyingKey`.
5463
///
5564
/// It gets calculated by the defined number of serialised bytes of `G1Affine` and `G2Affine` in
@@ -58,7 +67,7 @@ const G2AFFINE_UNCOMPRESSED_BYTES: usize = 192;
5867
/// 3 x `G2Affine`. One serialised `u32` variable will be added.
5968
/// That computes to: 3 x 48 + 3 * 96 + 4 = 436.
6069
pub const VERIFYINGKEY_MIN_BYTES: usize =
61-
3 * G1AFFINE_COMPRESSED_BYTES + 3 * G2AFFINE_COMPRESSED_BYTES + 4;
70+
G1AFFINE_PARAMS * G1AFFINE_COMPRESSED_BYTES + G2AFFINE_PARAMS * G2AFFINE_COMPRESSED_BYTES + 4;
6271

6372
/// This constant specifies the minimum number of bytes of a serialised `VerifyingKey` of usual
6473
/// public implementations. Usual public implementations means similar implementations in crates
@@ -69,15 +78,21 @@ pub const VERIFYINGKEY_MIN_BYTES: usize =
6978
/// serialised `G2Affine` are 192 bytes. In `VerifyingKey` we have for sure 3 x `G1Affine` and
7079
/// 3 x `G2Affine`. One serialised `u32` variable will be added.
7180
/// That computes to: 3 x 96 + 3 * 192 + 4 = 868.
72-
pub const VERIFYINGKEY_MIN_BYTES_STD: usize =
73-
3 * G1AFFINE_UNCOMPRESSED_BYTES + 3 * G2AFFINE_UNCOMPRESSED_BYTES + 4;
74-
75-
/// This constant specifies the maximum number of bytes of a serialised `VerifyingKey`.
76-
///
77-
/// The maximum number of parameters in field `ic` is 40 because its depedency can be resolved to
78-
/// possible sector sizes. This computes to: 3 * 96 + 3 * 192 + 4 + 40 * 96 = 4704.
79-
pub const VERIFYINGKEY_MAX_BYTES: usize =
80-
43 * G1AFFINE_UNCOMPRESSED_BYTES + 3 * G2AFFINE_UNCOMPRESSED_BYTES + 4;
81+
pub const VERIFYINGKEY_MIN_BYTES_STD: usize = G1AFFINE_PARAMS * G1AFFINE_UNCOMPRESSED_BYTES
82+
+ G2AFFINE_PARAMS * G2AFFINE_UNCOMPRESSED_BYTES
83+
+ 4;
84+
85+
/// This constant specifies the maximum number of bytes of a serialised PoRep 1GiB `VerifyingKey`.
86+
pub const POREP_VERIFYINGKEY_MAX_BYTES: usize = (G1AFFINE_PARAMS + MAX_PRODUCTION_POREP_VK_IC_LEN)
87+
* G1AFFINE_COMPRESSED_BYTES
88+
+ G2AFFINE_PARAMS * G2AFFINE_COMPRESSED_BYTES
89+
+ 4;
90+
91+
/// This constant specifies the maximum number of bytes of a serialised PoSt 1GiB `VerifyingKey`.
92+
pub const POST_VERIFYINGKEY_MAX_BYTES: usize = (G1AFFINE_PARAMS + MAX_PRODUCTION_POST_VK_IC_LEN)
93+
* G1AFFINE_COMPRESSED_BYTES
94+
+ G2AFFINE_PARAMS * G2AFFINE_COMPRESSED_BYTES
95+
+ 4;
8196

8297
/// This constant specifies the number of bytes of a serialised `Proof`.
8398
///

Diff for: lib/polka-storage-proofs/src/groth16/std.rs

+32
Original file line numberDiff line numberDiff line change
@@ -190,4 +190,36 @@ mod tests {
190190
// Compare initial struct with this one.
191191
assert_eq!(bp_proof, bp_proof_result);
192192
}
193+
194+
#[test]
195+
fn decodes_production_1gib_porep_verifying_key() {
196+
let vk_bytes = include_bytes!("../../../../examples/1GiB.porep.vk");
197+
// decode expects &mut mutability
198+
let vk_bytes = vk_bytes.to_vec();
199+
let key = bp_g16::VerifyingKey::<blstrs::Bls12>::read(&mut vk_bytes.as_slice());
200+
201+
assert!(key.is_ok(), "failed to parse 1GiB PoRep verifying key");
202+
let key = key.unwrap();
203+
let substrate_key = VerifyingKey::<Bls12>::try_from(key);
204+
assert!(
205+
substrate_key.is_ok(),
206+
"failed to convert 1GiB PoRep bellperson key to substrate key"
207+
);
208+
}
209+
210+
#[test]
211+
fn decodes_production_1gib_post_verifying_key() {
212+
let vk_bytes = include_bytes!("../../../../examples/1GiB.post.vk");
213+
// decode expects &mut mutability
214+
let vk_bytes = vk_bytes.to_vec();
215+
let key = bp_g16::VerifyingKey::<blstrs::Bls12>::read(&mut vk_bytes.as_slice());
216+
217+
assert!(key.is_ok(), "failed to parse 1GiB PoSt verifying key");
218+
let key = key.unwrap();
219+
let substrate_key = VerifyingKey::<Bls12>::try_from(key);
220+
assert!(
221+
substrate_key.is_ok(),
222+
"failed to convert 1GiB PoSt bellperson key to substrate key"
223+
);
224+
}
193225
}

Diff for: lib/polka-storage-proofs/src/groth16/substrate.rs

+29-2
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,17 @@ where
2525
E: Engine<G1Affine = G1Affine, G2Affine = G2Affine>,
2626
{
2727
fn decode<I: ::codec::Input>(input: &mut I) -> Result<Self, ::codec::Error> {
28-
let mut buffer = [0u8; VERIFYINGKEY_MAX_BYTES];
28+
// We can't allocate 1.4MiB required for PoSt on stack.
29+
let mut buffer = alloc::vec::Vec::with_capacity(POST_VERIFYINGKEY_MAX_BYTES);
2930
let Some(n_bytes) = input.remaining_len()? else {
3031
return Err(::codec::Error::from("unable to get remaining_len"));
3132
};
33+
if n_bytes > POST_VERIFYINGKEY_MAX_BYTES {
34+
return Err(::codec::Error::from(
35+
"provided verifying key is too big for the current limit of bytes",
36+
));
37+
}
38+
buffer.resize(n_bytes, 0);
3239
input.read(&mut buffer[..n_bytes])?;
3340
VerifyingKey::<E>::from_bytes(&buffer[..n_bytes])
3441
.map_err(|e| codec::Error::from(e.as_static_str()))
@@ -73,7 +80,7 @@ where
7380
E: Engine<G1Affine = G1Affine, G2Affine = G2Affine>,
7481
{
7582
fn max_encoded_len() -> usize {
76-
VERIFYINGKEY_MAX_BYTES
83+
MAX_PRODUCTION_POST_VK_IC_LEN
7784
}
7885
}
7986

@@ -240,4 +247,24 @@ mod tests {
240247
proof.into_bytes(&mut bytes_regular.as_mut_slice()).unwrap();
241248
assert_eq!(bytes_regular.as_slice(), bytes_scale.as_slice());
242249
}
250+
251+
#[test]
252+
fn decodes_production_1gib_porep_verifying_key() {
253+
let vk_bytes = include_bytes!("../../../../examples/1GiB.porep.vk.scale");
254+
// decode expects &mut mutability
255+
let vk_bytes = vk_bytes.to_vec();
256+
let key = VerifyingKey::<Bls12>::decode(&mut vk_bytes.as_slice());
257+
258+
assert!(key.is_ok(), "failed to parse 1GiB PoRep verifying key");
259+
}
260+
261+
#[test]
262+
fn decodes_production_1gib_post_verifying_key() {
263+
let vk_bytes = include_bytes!("../../../../examples/1GiB.post.vk.scale");
264+
// decode expects &mut mutability
265+
let vk_bytes = vk_bytes.to_vec();
266+
let key = VerifyingKey::<Bls12>::decode(&mut vk_bytes.as_slice());
267+
268+
assert!(key.is_ok(), "failed to parse 1GiB PoSt verifying key");
269+
}
243270
}

Diff for: pallets/proofs/src/lib.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,13 @@ mod tests;
2424
#[cfg(feature = "runtime-benchmarks")]
2525
mod benchmarking;
2626

27-
#[frame_support::pallet]
27+
#[frame_support::pallet(dev_mode)]
2828
pub mod pallet {
2929
pub const LOG_TARGET: &'static str = "runtime::proofs";
3030

3131
use frame_support::{pallet_prelude::*, sp_runtime::BoundedBTreeMap};
3232
use frame_system::pallet_prelude::*;
33+
use polka_storage_proofs::POREP_VERIFYINGKEY_MAX_BYTES;
3334
use primitives::{
3435
commitment::RawCommitment,
3536
pallets::ProofVerification,
@@ -89,14 +90,19 @@ pub mod pallet {
8990

9091
#[pallet::call]
9192
impl<T: Config> Pallet<T> {
92-
#[pallet::call_index(0)]
93-
#[pallet::weight((T::WeightInfo::set_porep_verifying_key(), DispatchClass::Operational))]
93+
// TODO(@th7nder,#790,03/03/2025): benchmarking was previously done for small params, not for production 1GiB sectors
94+
// #[pallet::call_index(0)]
95+
// #[pallet::weight((T::WeightInfo::set_porep_verifying_key(), DispatchClass::Operational))]
9496
pub fn set_porep_verifying_key(
9597
origin: OriginFor<T>,
9698
registered_seal_proof: RegisteredSealProof,
9799
verifying_key: crate::Vec<u8>,
98100
) -> DispatchResult {
99101
let caller = ensure_signed(origin)?;
102+
if verifying_key.len() > POREP_VERIFYINGKEY_MAX_BYTES {
103+
log::error!(target: LOG_TARGET, "verifying key is longer ({}) than the maximum expected ({})", verifying_key.len(), POREP_VERIFYINGKEY_MAX_BYTES);
104+
return Err(Error::<T>::InvalidVerifyingKey.into());
105+
}
100106
let vkey =
101107
VerifyingKey::<Bls12>::decode(&mut verifying_key.as_slice()).map_err(|e| {
102108
log::error!(target: LOG_TARGET, "failed to parse PoRep verifying key {:?}", e);
@@ -111,8 +117,9 @@ pub mod pallet {
111117
Ok(())
112118
}
113119

114-
#[pallet::call_index(1)]
115-
#[pallet::weight((T::WeightInfo::set_post_verifying_key(), DispatchClass::Operational))]
120+
// TODO(@th7nder,#790,03/03/2025): benchmarking was previously done for small params, not for production 1GiB sectors
121+
// #[pallet::call_index(1)]
122+
// #[pallet::weight((T::WeightInfo::set_post_verifying_key(), DispatchClass::Operational))]
116123
pub fn set_post_verifying_key(
117124
origin: OriginFor<T>,
118125
registered_post_proof: RegisteredPoStProof,

0 commit comments

Comments
 (0)