solutions/pallets/zkp_verify/src/lib.rs

370 lines
9.6 KiB
Rust
Executable File

#![cfg_attr(not(feature = "std"), no_std)]
/// Edit this file to define custom logic or remove it if it is not needed.
/// Learn more about FRAME and the core library of Substrate FRAME pallets:
/// <https://docs.substrate.io/reference/frame-pallets/>
pub use pallet::*;
use dusk_plonk::prelude::{Proof, Verifier, BlsScalar};
use rkyv::Deserialize;
#[cfg(test)]
mod mock;
#[cfg(test)]
mod tests;
#[cfg(feature = "runtime-benchmarks")]
mod benchmarking;
pub mod weights;
pub use weights::*;
mod groth16;
use crate::groth16::{G1AffineParts, G2AffineParts, ProofParts, VKParts};
#[frame_support::pallet]
pub mod pallet {
use super::*;
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
use ark_bn254::{Bn254, Fq, Fq2, Fr, G1Affine, G2Affine, Config as Bn254Config};
use ark_ec::bn::Bn;
use ark_gm17::{prepare_verifying_key as gm17_prepare_verification_key, Proof as gm17_proof, VerifyingKey as gm17_verification_key, verify_proof as gm17_verify_proof, GM17};
use ark_groth16::{prepare_verifying_key as g16_prepare_verification_key, Proof as g16_proof, VerifyingKey as g16_verification_key, Groth16};
use ark_ff::{Field, Zero, vec,Fp};
use ark_snark::SNARK;
use ark_bls12_381::{Bls12_381, Fr as BlsFr};
use ark_serialize::{CanonicalDeserialize, Compress, Validate};
use ark_std::{
io::{Cursor},
vec::Vec,
};
#[pallet::pallet]
pub struct Pallet<T>(_);
/// Configure the pallet by specifying the parameters and types on which it depends.
#[pallet::config]
pub trait Config: frame_system::Config {
/// Because this pallet emits events, it depends on the runtime's definition of an event.
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
/// Type representing the weight of this pallet
type WeightInfo: WeightInfo;
}
// The pallet's runtime storage items.
// https://docs.substrate.io/main-docs/build/runtime-storage/
#[pallet::storage]
#[pallet::getter(fn something)]
// Learn more about declaring storage items:
// https://docs.substrate.io/main-docs/build/runtime-storage/#declaring-storage-items
pub type Something<T> = StorageValue<_, u32>;
// Pallets use events to inform users when important changes are made.
// https://docs.substrate.io/main-docs/build/events-errors/
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// Event documentation should end with an array that provides descriptive names for event
/// parameters. [something, who]
ValidationSuccess { who: T::AccountId },
}
#[pallet::error]
pub enum Error<T> {
ValidationFailed,
}
// Dispatchable functions allows users to interact with the pallet and invoke state changes.
// These functions materialize as "extrinsics", which are often compared to transactions.
// Dispatchable functions must be annotated with a weight and must return a DispatchResult.
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::call_index(0)]
#[pallet::weight(T::WeightInfo::cause_error())]
pub fn verify_g16(
origin: OriginFor<T>,
// vk: Vec<u8>,
vk_alpha_1: Vec<u8>,
vk_alpha_2: Vec<u8>,
vk_beta_1_1: Vec<u8>,
vk_beta_1_2: Vec<u8>,
vk_beta_2_1: Vec<u8>,
vk_beta_2_2: Vec<u8>,
vk_gamma_1_1: Vec<u8>,
vk_gamma_1_2: Vec<u8>,
vk_gamma_2_1: Vec<u8>,
vk_gamma_2_2: Vec<u8>,
vk_delta_1_1: Vec<u8>,
vk_delta_1_2: Vec<u8>,
vk_delta_2_1: Vec<u8>,
vk_delta_2_2: Vec<u8>,
vk_gamma_abc_1_1: Vec<u8>,
vk_gamma_abc_1_2: Vec<u8>,
vk_gamma_abc_2_1: Vec<u8>,
vk_gamma_abc_2_2: Vec<u8>,
inputs: Vec<u8>,
// proof: Vec<u8>,
proof_a_1: Vec<u8>,
proof_a_2: Vec<u8>,
proof_b_1_1: Vec<u8>,
proof_b_1_2: Vec<u8>,
proof_b_2_1: Vec<u8>,
proof_b_2_2: Vec<u8>,
proof_c_1: Vec<u8>,
proof_c_2: Vec<u8>,
) -> DispatchResult {
let who = ensure_signed(origin)?;
let vk_parts = VKParts {
alpha: G1AffineParts {
part_1: vk_alpha_1,
part_2: vk_alpha_2,
},
beta: G2AffineParts {
part_1_1: vk_beta_1_1,
part_1_2: vk_beta_1_2,
part_2_1: vk_beta_2_1,
part_2_2: vk_beta_2_2,
},
gamma: G2AffineParts {
part_1_1: vk_gamma_1_1,
part_1_2: vk_gamma_1_2,
part_2_1: vk_gamma_2_1,
part_2_2: vk_gamma_2_2,
},
delta: G2AffineParts {
part_1_1: vk_delta_1_1,
part_1_2: vk_delta_1_2,
part_2_1: vk_delta_2_1,
part_2_2: vk_delta_2_2,
},
gamma_abc_1: G1AffineParts{
part_1: vk_gamma_abc_1_1,
part_2: vk_gamma_abc_1_2,
},
gamma_abc_2: G1AffineParts{
part_1: vk_gamma_abc_2_1,
part_2: vk_gamma_abc_2_2,
},
};
let proof_parts = ProofParts {
a: G1AffineParts {
part_1: proof_a_1,
part_2: proof_a_2,
},
b: G2AffineParts {
part_1_1: proof_b_1_1,
part_1_2: proof_b_1_2,
part_2_1: proof_b_2_1,
part_2_2: proof_b_2_2,
},
c: G1AffineParts {
part_1: proof_c_1,
part_2: proof_c_2,
},
};
// let result = Groth16::<Bls12_381>::verify(&vk, &[inputs], &proof).unwrap();
let result: bool = groth16::verify(&vk_parts, &proof_parts, &inputs);
if result {
Self::deposit_event(Event::ValidationSuccess { who });
Ok(())
} else {
Err(Error::<T>::ValidationFailed.into())
}
}
#[pallet::call_index(1)]
#[pallet::weight(T::WeightInfo::cause_error())]
pub fn verify_plonk(origin: OriginFor<T>, vk: Vec<u8>, inputs: Vec<u8>,proof: Vec<u8>) -> DispatchResult {
let who = ensure_signed(origin)?;
let result_vk = Verifier::try_from_bytes(&vk[..]);
let verifier = match result_vk {
Ok(verifier) => verifier,
Err(_) => return Err(Error::<T>::ValidationFailed.into()),
};
let archived = match rkyv::check_archived_root::<Proof>(&proof[..]){
Ok(archived) => archived,
Err(_) => return Err(Error::<T>::ValidationFailed.into()),
};
let proof: Proof = match archived.deserialize(&mut rkyv::Infallible) {
Ok(proof) => proof,
Err(_) => return Err(Error::<T>::ValidationFailed.into()),
};
let archived = match rkyv::check_archived_root::<Vec<BlsScalar>>(&inputs[..]) {
Ok(archived) => archived,
Err(_) => return Err(Error::<T>::ValidationFailed.into()),
};
let inputs: Vec<BlsScalar> = match archived.deserialize(&mut rkyv::Infallible) {
Ok(inputs) => inputs,
Err(_) => return Err(Error::<T>::ValidationFailed.into()),
};
let verification =verifier.verify(&proof, &inputs);
let result = verification.is_ok();
if result {
Self::deposit_event(Event::ValidationSuccess { who });
Ok(())
}else{
Err(Error::<T>::ValidationFailed.into())
}
}
/*#[pallet::call_index(1)]
#[pallet::weight(T::WeightInfo::cause_error())]
pub fn verify_proof_gm17(origin: OriginFor<T>, vk: Vec<u8>, inputs: Vec<u8>,proof: Vec<u8>) -> DispatchResult {
let who = ensure_signed(origin)?;
let cursor = Cursor::new(&vk);
let pvk = <GM17<Bls12_381> as SNARK<BlsFr>>::VerifyingKey::deserialize_with_mode(
cursor,
Compress::No,
Validate::No,
).unwrap();
let cursor = Cursor::new(&inputs);
let inputs: ark_ff::Fp<ark_ff::MontBackend<ark_bls12_381::FrConfig, 4>, 4> =
Fp::deserialize_with_mode(cursor, Compress::No, Validate::No).unwrap();
let cursor = Cursor::new(&proof);
let proof =
<GM17<Bls12_381> as SNARK<BlsFr>>::Proof::deserialize_with_mode(
cursor,
Compress::No,
Validate::No,
)
.unwrap();
let result = gm17_verify_proof(&vk, &proof, &[inputs]).unwrap();
if(result){
Ok(())
}else{
Err(Error::<T>::NoneValue.into())
}
}*/
}
/*pub trait ZKPVerifyInterface {
fn verify_g16(
origin: OriginFor<T>,
// vk: Vec<u8>,
vk_alpha_1: Vec<u8>,
vk_alpha_2: Vec<u8>,
vk_beta_1_1: Vec<u8>,
vk_beta_1_2: Vec<u8>,
vk_beta_2_1: Vec<u8>,
vk_beta_2_2: Vec<u8>,
vk_gamma_1_1: Vec<u8>,
vk_gamma_1_2: Vec<u8>,
vk_gamma_2_1: Vec<u8>,
vk_gamma_2_2: Vec<u8>,
vk_delta_1_1: Vec<u8>,
vk_delta_1_2: Vec<u8>,
vk_delta_2_1: Vec<u8>,
vk_delta_2_2: Vec<u8>,
vk_gamma_abc_1_1: Vec<u8>,
vk_gamma_abc_1_2: Vec<u8>,
vk_gamma_abc_2_1: Vec<u8>,
vk_gamma_abc_2_2: Vec<u8>,
inputs: Vec<u8>,
// proof: Vec<u8>,
proof_a_1: Vec<u8>,
proof_a_2: Vec<u8>,
proof_b_1_1: Vec<u8>,
proof_b_1_2: Vec<u8>,
proof_b_2_1: Vec<u8>,
proof_b_2_2: Vec<u8>,
proof_c_1: Vec<u8>,
proof_c_2: Vec<u8>,
) -> DispatchResult;
}*/
/*
impl<T: Config> ZKPVerifyInterface for Pallet<T> {
fn verify_g16(
origin: OriginFor<T>,
// vk: Vec<u8>,
vk_alpha_1: Vec<u8>,
vk_alpha_2: Vec<u8>,
vk_beta_1_1: Vec<u8>,
vk_beta_1_2: Vec<u8>,
vk_beta_2_1: Vec<u8>,
vk_beta_2_2: Vec<u8>,
vk_gamma_1_1: Vec<u8>,
vk_gamma_1_2: Vec<u8>,
vk_gamma_2_1: Vec<u8>,
vk_gamma_2_2: Vec<u8>,
vk_delta_1_1: Vec<u8>,
vk_delta_1_2: Vec<u8>,
vk_delta_2_1: Vec<u8>,
vk_delta_2_2: Vec<u8>,
vk_gamma_abc_1_1: Vec<u8>,
vk_gamma_abc_1_2: Vec<u8>,
vk_gamma_abc_2_1: Vec<u8>,
vk_gamma_abc_2_2: Vec<u8>,
inputs: Vec<u8>,
// proof: Vec<u8>,
proof_a_1: Vec<u8>,
proof_a_2: Vec<u8>,
proof_b_1_1: Vec<u8>,
proof_b_1_2: Vec<u8>,
proof_b_2_1: Vec<u8>,
proof_b_2_2: Vec<u8>,
proof_c_1: Vec<u8>,
proof_c_2: Vec<u8>,
) -> DistpacthResult {
//) -> Result<DispatchResult, DispatchError> {
return Self::verify_g16(
origin,
vk_alpha_1,
vk_alpha_2,
vk_beta_1_1,
vk_beta_1_2,
vk_beta_2_1,
vk_beta_2_2,
vk_gamma_1_1,
vk_gamma_1_2,
vk_gamma_2_1,
vk_gamma_2_2,
vk_delta_1_1,
vk_delta_1_2,
vk_delta_2_1,
vk_delta_2_2,
vk_gamma_abc_1_1,
vk_gamma_abc_1_2,
vk_gamma_abc_2_1,
vk_gamma_abc_2_2,
inputs,
proof_a_1,
proof_a_2,
proof_b_1_1,
proof_b_1_2,
proof_b_2_1,
proof_b_2_2,
proof_c_1,
proof_c_2,
);
}
*/
}