Skip to content

Commit

Permalink
feat(pallet-proofs): expose the proof interface to other pallets (#440)
Browse files Browse the repository at this point in the history
  • Loading branch information
th7nder authored Oct 9, 2024
1 parent 7541a46 commit 2b15fc6
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 137 deletions.
5 changes: 5 additions & 0 deletions lib/polka-storage-proofs/src/groth16/substrate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ where
}
}

impl<E> ::codec::EncodeLike for VerifyingKey<E> where
E: Engine<G1Affine = G1Affine, G2Affine = G2Affine>
{
}

impl<E> ::codec::Encode for VerifyingKey<E>
where
E: Engine<G1Affine = G1Affine, G2Affine = G2Affine>,
Expand Down
12 changes: 6 additions & 6 deletions pallets/proofs/src/crypto/groth16.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::Vec;
/// - <https://github.com/zkcrypto/bellman/blob/3a1c43b01a89d426842df39b432de979917951e6/groth16/src/lib.rs#L400>
/// - <https://github.com/filecoin-project/bellperson/blob/a594f329b05b6224047903fb51658e8a35a12fbd/src/groth16/verifying_key.rs#L200>
#[derive(Clone, Decode, Default, Encode)]
pub(crate) struct PreparedVerifyingKey<E: MultiMillerLoop> {
struct PreparedVerifyingKey<E: MultiMillerLoop> {
pub alpha_g1_beta_g2: E::Gt,
pub neg_gamma_g2: E::G2Prepared,
pub neg_delta_g2: E::G2Prepared,
Expand All @@ -40,9 +40,7 @@ impl<E: MultiMillerLoop> From<VerifyingKey<E>> for PreparedVerifyingKey<E> {
///
/// References:
/// - <https://github.com/zkcrypto/bellman/blob/3a1c43b01a89d426842df39b432de979917951e6/groth16/src/verifier.rs#L11>
pub(crate) fn prepare_verifying_key<E: MultiMillerLoop>(
vkey: VerifyingKey<E>,
) -> PreparedVerifyingKey<E> {
fn prepare_verifying_key<E: MultiMillerLoop>(vkey: VerifyingKey<E>) -> PreparedVerifyingKey<E> {
PreparedVerifyingKey::<E>::from(vkey)
}

Expand All @@ -53,11 +51,13 @@ pub(crate) fn prepare_verifying_key<E: MultiMillerLoop>(
/// References:
/// - <https://github.com/zkcrypto/bellman/blob/3a1c43b01a89d426842df39b432de979917951e6/groth16/src/verifier.rs#L23>
/// - <https://github.com/filecoin-project/bellperson/blob/a594f329b05b6224047903fb51658e8a35a12fbd/src/groth16/verifier.rs#L38>
pub(crate) fn verify_proof<'a, E: MultiMillerLoop>(
pvk: &'a PreparedVerifyingKey<E>,
pub fn verify_proof<E: MultiMillerLoop>(
vk: VerifyingKey<E>,
proof: &Proof<E>,
public_inputs: &[E::Fr],
) -> Result<(), VerificationError> {
let pvk = prepare_verifying_key(vk);

if (public_inputs.len() + 1) != pvk.ic.len() {
return Err(VerificationError::InvalidVerifyingKey);
}
Expand Down
10 changes: 10 additions & 0 deletions pallets/proofs/src/graphs/bucket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,16 @@ pub(crate) const fn ceil_log2(n: u64) -> u64 {
mod test {
use super::*;

#[test]
fn ceil_log2_computation_same_as_filecoin() {
for n in 0..10001 {
let n_u64 = n as u64;
let n_buckets_fc = (n_u64 as f64).log2().ceil() as u64;
let n_buckets_we = crate::graphs::bucket::ceil_log2(n_u64);
assert_eq!(n_buckets_fc, n_buckets_we);
}
}

#[test]
fn constructs_graph() {
for &nodes in &[4, 16, 256, 2048] {
Expand Down
66 changes: 33 additions & 33 deletions pallets/proofs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ mod tests;

#[frame_support::pallet(dev_mode)]
pub mod pallet {
use frame_support::{dispatch::DispatchResultWithPostInfo, pallet_prelude::*};
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
use primitives_proofs::{RegisteredSealProof, SectorNumber};
use primitives_proofs::{
ProofVerification, ProverId, RawCommitment, RegisteredSealProof, SectorNumber, Ticket,
};

use crate::{
crypto::groth16::{self, Bls12, Proof, VerifyingKey},
crypto::groth16::{Bls12, Proof, VerifyingKey},
porep,
};

Expand All @@ -38,17 +40,18 @@ pub mod pallet {
#[pallet::pallet]
pub struct Pallet<T>(_);

#[pallet::storage]
pub type PoRepVerifyingKey<T: Config> = StorageValue<_, VerifyingKey<Bls12>, OptionQuery>;

#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
SomethingStored {
block_number: BlockNumberFor<T>,
who: T::AccountId,
},
PoRepVerifyingKeyChanged { who: T::AccountId },
}

#[pallet::error]
pub enum Error<T> {
MissingPoRepVerifyingKey,
/// Returned when a given PoRep proof was invalid in a verification.
InvalidPoRepProof,
/// Returned when the given verifying key was invalid.
Expand All @@ -59,47 +62,44 @@ pub mod pallet {

#[pallet::call]
impl<T: Config> Pallet<T> {
// TODO(@neutrinoks,07.10.2024): Remove testing extrinsics (#410).
/// Temporary! Only for testing purposes only!
pub fn do_something(origin: OriginFor<T>, bn: u32) -> DispatchResultWithPostInfo {
let who = ensure_signed(origin)?;
let block_number: BlockNumberFor<T> = bn.into();
Self::deposit_event(Event::SomethingStored { block_number, who });

Ok(().into())
pub fn set_porep_verifying_key(
origin: OriginFor<T>,
verifying_key: crate::Vec<u8>,
) -> DispatchResult {
let caller = ensure_signed(origin)?;
let vkey = VerifyingKey::<Bls12>::decode(&mut verifying_key.as_slice())
.map_err(|_| Error::<T>::Conversion)?;

PoRepVerifyingKey::<T>::set(Some(vkey));

Self::deposit_event(Event::PoRepVerifyingKeyChanged { who: caller });

Ok(())
}
}

// TODO(@neutrinoks,07.10.2024): Finalise interface of this extrinsic (#410).
/// Temporary! Only for testing purposes only!
pub fn verify_porep(
origin: OriginFor<T>,
impl<T: Config> ProofVerification for Pallet<T> {
fn verify_porep(
prover_id: ProverId,
seal_proof: RegisteredSealProof,
comm_r: porep::Commitment,
comm_d: porep::Commitment,
comm_r: RawCommitment,
comm_d: RawCommitment,
sector: SectorNumber,
ticket: porep::Ticket,
seed: porep::Ticket,
vkey: crate::Vec<u8>,
ticket: Ticket,
seed: Ticket,
proof: crate::Vec<u8>,
) -> DispatchResult {
let _who = ensure_signed(origin)?;
let vkey = VerifyingKey::<Bls12>::decode(&mut vkey.as_slice())
.map_err(|_| Error::<T>::Conversion)?;
let proof = Proof::<Bls12>::decode(&mut proof.as_slice())
.map_err(|_| Error::<T>::Conversion)?;
let proof_scheme = porep::ProofScheme::setup(seal_proof);

// TODO(@th7nder,23/09/2024): not sure how to convert generic Account into [u8; 32]. It is AccountId32, but at this point we don't know it.
let pvk = groth16::prepare_verifying_key(vkey);
let account = [0u8; 32]; // TODO: who.as_ref()

let vkey = PoRepVerifyingKey::<T>::get().ok_or(Error::<T>::MissingPoRepVerifyingKey)?;
proof_scheme
.verify(
&comm_r, &comm_d, &account, sector, &ticket, &seed, &pvk, &proof,
&comm_r, &comm_d, &prover_id, sector, &ticket, &seed, vkey, &proof,
)
.map_err(Into::<Error<T>>::into)?;

// TODO(@th7nder,23/09/2024): verify_porep ain't an extrinsic, this is just a method which will be called by Storage Provider Pallet via a Trait (in primitives-proofs).
Ok(())
}
}
Expand Down
21 changes: 7 additions & 14 deletions pallets/proofs/src/porep/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
mod config;

use config::{Config, PoRepID};
use primitives_proofs::RegisteredSealProof;
use primitives_proofs::{ProverId, RawCommitment, RegisteredSealProof, Ticket};
use sha2::{Digest, Sha256};

use crate::{
crypto::groth16::{
verify_proof, Bls12, Fr, PreparedVerifyingKey, PrimeField, Proof, VerificationError,
verify_proof, Bls12, Fr, PrimeField, Proof, VerificationError, VerifyingKey,
},
fr32,
graphs::{
Expand All @@ -16,13 +16,6 @@ use crate::{
vec, Error, Vec,
};

/// Byte representation of the entity that was signing the proof.
/// It must match the ProverId used for Proving.
pub type ProverId = [u8; 32];
/// Byte representation of a commitment - CommR or CommD.
pub type Commitment = [u8; 32];
/// Byte representation of randomness seed, it's used for challenge generation.
pub type Ticket = [u8; 32];
/// A unique 32-byte ID assigned to each distinct replica.
/// Replication is the entire process by which a sector is uniquely encoded into a replica.
pub type ReplicaId = Fr;
Expand Down Expand Up @@ -138,13 +131,13 @@ impl ProofScheme {

pub fn verify(
&self,
comm_r: &Commitment,
comm_d: &Commitment,
comm_r: &RawCommitment,
comm_d: &RawCommitment,
prover_id: &ProverId,
sector: u64,
ticket: &Ticket,
seed: &Ticket,
pvk: &PreparedVerifyingKey<Bls12>,
vk: VerifyingKey<Bls12>,
proof: &Proof<Bls12>,
) -> Result<(), ProofError> {
let comm_d_fr = fr32::bytes_into_fr(comm_d).map_err(|_| ProofError::Conversion)?;
Expand All @@ -162,7 +155,7 @@ impl ProofScheme {

let public_inputs = self.generate_public_inputs(public_inputs, None)?;

verify_proof(pvk, proof, public_inputs.as_slice()).map_err(Into::<ProofError>::into)
verify_proof(vk, proof, public_inputs.as_slice()).map_err(Into::<ProofError>::into)
}

/// References:
Expand All @@ -172,7 +165,7 @@ impl ProofScheme {
prover_id: &ProverId,
sector: u64,
ticket: &Ticket,
comm_d: &Commitment,
comm_d: &RawCommitment,
) -> ReplicaId {
let hash = Sha256::new()
.chain_update(prover_id)
Expand Down
Loading

0 comments on commit 2b15fc6

Please sign in to comment.