From 66cd35b7d65301f4a8ddb5a3d03b43f8bf3713c7 Mon Sep 17 00:00:00 2001 From: Nikita Masych Date: Thu, 26 Dec 2024 17:01:55 +0200 Subject: [PATCH] feat: custom gate serializer --- Cargo.lock | 8 ++-- Cargo.toml | 3 +- src/deserializer/custom.rs | 47 ++++++++++++++++++++ src/{deserializer.rs => deserializer/mod.rs} | 8 ++-- src/lib.rs | 18 +++----- src/validate.rs | 7 +-- 6 files changed, 65 insertions(+), 26 deletions(-) create mode 100644 src/deserializer/custom.rs rename src/{deserializer.rs => deserializer/mod.rs} (90%) diff --git a/Cargo.lock b/Cargo.lock index 03dd9a5..3e6f9f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -339,7 +339,7 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "plonky2" version = "1.0.0" -source = "git+https://github.com/distributed-lab/plonky2?branch=stable#4f4d41be1c7208eb45824ad7106e119708651560" +source = "git+https://github.com/distributed-lab/plonky2?branch=stable#f559fa7eb81dd9b5c990494e1740ef54c38362e0" dependencies = [ "anyhow", "hashbrown", @@ -368,7 +368,7 @@ dependencies = [ [[package]] name = "plonky2_field" version = "1.0.0" -source = "git+https://github.com/distributed-lab/plonky2?branch=stable#4f4d41be1c7208eb45824ad7106e119708651560" +source = "git+https://github.com/distributed-lab/plonky2?branch=stable#f559fa7eb81dd9b5c990494e1740ef54c38362e0" dependencies = [ "anyhow", "itertools", @@ -384,12 +384,12 @@ dependencies = [ [[package]] name = "plonky2_maybe_rayon" version = "1.0.0" -source = "git+https://github.com/distributed-lab/plonky2?branch=stable#4f4d41be1c7208eb45824ad7106e119708651560" +source = "git+https://github.com/distributed-lab/plonky2?branch=stable#f559fa7eb81dd9b5c990494e1740ef54c38362e0" [[package]] name = "plonky2_util" version = "1.0.0" -source = "git+https://github.com/distributed-lab/plonky2?branch=stable#4f4d41be1c7208eb45824ad7106e119708651560" +source = "git+https://github.com/distributed-lab/plonky2?branch=stable#f559fa7eb81dd9b5c990494e1740ef54c38362e0" [[package]] name = "ppv-lite86" diff --git a/Cargo.toml b/Cargo.toml index b85d4db..953ac80 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ resolver = "2" [dependencies] plonky2 = { git = "https://github.com/distributed-lab/plonky2", branch = "stable", default-features = false} + snafu = { version = "0.8.5", default-features = false } [dev-dependencies] @@ -24,4 +25,4 @@ default = ["std"] std = [ "plonky2/std", "snafu/std", -] \ No newline at end of file +] diff --git a/src/deserializer/custom.rs b/src/deserializer/custom.rs new file mode 100644 index 0000000..87f4529 --- /dev/null +++ b/src/deserializer/custom.rs @@ -0,0 +1,47 @@ +use plonky2::field::extension::Extendable; +use plonky2::hash::hash_types::RichField; +use plonky2::util::serialization::GateSerializer; +use plonky2::{get_gate_tag_impl, impl_gate_serializer, read_gate_impl}; + +use plonky2::gates::arithmetic_base::ArithmeticGate; +use plonky2::gates::arithmetic_extension::ArithmeticExtensionGate; +use plonky2::gates::base_sum::BaseSumGate; +use plonky2::gates::constant::ConstantGate; +use plonky2::gates::coset_interpolation::CosetInterpolationGate; +use plonky2::gates::exponentiation::ExponentiationGate; +use plonky2::gates::lookup::LookupGate; +use plonky2::gates::lookup_table::LookupTableGate; +use plonky2::gates::multiplication_extension::MulExtensionGate; +use plonky2::gates::noop::NoopGate; +use plonky2::gates::poseidon::PoseidonGate; +use plonky2::gates::poseidon_mds::PoseidonMdsGate; +use plonky2::gates::public_input::PublicInputGate; +use plonky2::gates::random_access::RandomAccessGate; +use plonky2::gates::reducing::ReducingGate; +use plonky2::gates::reducing_extension::ReducingExtensionGate; + +/// zkVerify employs gate serializer which essentially supports the same set, +/// as `DefaultGateSerializer` from `plonky2`, but with possibility of extending it in future. +#[derive(Debug)] +pub struct ZKVerifyGateSerializer; +impl, const D: usize> GateSerializer for ZKVerifyGateSerializer { + impl_gate_serializer! { + ZKVerifyGateSerializer, + ArithmeticGate, + ArithmeticExtensionGate, + BaseSumGate<2>, + ConstantGate, + CosetInterpolationGate, + ExponentiationGate, + LookupGate, + LookupTableGate, + MulExtensionGate, + NoopGate, + PoseidonMdsGate, + PoseidonGate, + PublicInputGate, + RandomAccessGate, + ReducingExtensionGate, + ReducingGate + } +} diff --git a/src/deserializer.rs b/src/deserializer/mod.rs similarity index 90% rename from src/deserializer.rs rename to src/deserializer/mod.rs index d0539a4..7b54f62 100644 --- a/src/deserializer.rs +++ b/src/deserializer/mod.rs @@ -1,9 +1,12 @@ +pub mod custom; + +use custom::ZKVerifyGateSerializer; + use plonky2::field::extension::Extendable; use plonky2::hash::hash_types::RichField; use plonky2::plonk::circuit_data::{CommonCircuitData, VerifierCircuitData}; use plonky2::plonk::config::GenericConfig; use plonky2::plonk::proof::ProofWithPublicInputs; -use plonky2::util::serialization::GateSerializer; #[cfg(not(feature = "std"))] use alloc::vec::Vec; @@ -22,13 +25,12 @@ pub enum DeserializeError { pub(crate) fn deserialize_vk( vk: &[u8], - gs: &dyn GateSerializer, ) -> Result, DeserializeError> where F: RichField + Extendable, C: GenericConfig, { - VerifierCircuitData::::from_bytes(Vec::from(vk), gs) + VerifierCircuitData::::from_bytes(Vec::from(vk), &ZKVerifyGateSerializer) .map_err(|_| DeserializeError::InvalidVerificationKey) } diff --git a/src/lib.rs b/src/lib.rs index ae5ad1d..feaabb3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,10 +13,9 @@ use deserializer::{deserialize_proof_with_pubs, deserialize_vk}; use plonky2::field::extension::Extendable; use plonky2::hash::hash_types::RichField; use plonky2::plonk::config::{GenericConfig, KeccakGoldilocksConfig, PoseidonGoldilocksConfig}; -use plonky2::util::serialization::{DefaultGateSerializer, GateSerializer}; use snafu::Snafu; -pub use deserializer::DeserializeError; +pub use deserializer::{custom::ZKVerifyGateSerializer, DeserializeError}; /// Verification error. #[derive(Debug, Snafu)] @@ -41,38 +40,31 @@ impl From for VerifyError { /// Verify the given proof `proof` and public inputs `pubs` using verification key `vk`. /// Use the given verification key `vk` to verify the proof `proof` against the public inputs `pubs`. -pub fn verify( - vk: &[u8], - proof: &[u8], - pubs: &[u8], - gs: &dyn GateSerializer, -) -> Result<(), VerifyError> +pub fn verify(vk: &[u8], proof: &[u8], pubs: &[u8]) -> Result<(), VerifyError> where F: RichField + Extendable, C: GenericConfig, { - let vk = deserialize_vk::(vk, gs)?; + let vk = deserialize_vk::(vk)?; let proof = deserialize_proof_with_pubs::(proof, pubs, &vk.common)?; vk.verify(proof).map_err(|_| VerifyError::Failure) } /// Verification with preset Poseidon over Goldilocks config available in `plonky2`. -/// Uses `DefaultGateSerializer`. pub fn verify_default_poseidon(vk: &[u8], proof: &[u8], pubs: &[u8]) -> Result<(), VerifyError> { const D: usize = 2; type C = PoseidonGoldilocksConfig; type F = >::F; - verify::(vk, proof, pubs, &DefaultGateSerializer) + verify::(vk, proof, pubs) } /// Verification with preset Keccak over Goldilocks config available in `plonky2`. -/// Uses `DefaultGateSerializer`. pub fn verify_default_keccak(vk: &[u8], proof: &[u8], pubs: &[u8]) -> Result<(), VerifyError> { const D: usize = 2; type C = KeccakGoldilocksConfig; type F = >::F; - verify::(vk, proof, pubs, &DefaultGateSerializer) + verify::(vk, proof, pubs) } diff --git a/src/validate.rs b/src/validate.rs index f88485f..5add071 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -3,7 +3,6 @@ use crate::deserializer::deserialize_vk; use crate::DeserializeError; use plonky2::plonk::config::{GenericConfig, KeccakGoldilocksConfig, PoseidonGoldilocksConfig}; -use plonky2::util::serialization::DefaultGateSerializer; use snafu::Snafu; /// Validation error. @@ -25,25 +24,23 @@ impl From for ValidateError { } /// Validate vk with preset Poseidon over Goldilocks config available in `plonky2`. -/// Uses `DefaultGateSerializer`. pub fn validate_vk_default_poseidon(vk: &[u8]) -> Result<(), ValidateError> { const D: usize = 2; type C = PoseidonGoldilocksConfig; type F = >::F; - deserialize_vk::(vk, &DefaultGateSerializer) + deserialize_vk::(vk) .map(|_| ()) // Discard `Ok` value, map it to `()` .map_err(ValidateError::from) // Convert `DeserializeError` to `ValidateError` } /// Validate vk with preset Keccak over Goldilocks config available in `plonky2`. -/// Uses `DefaultGateSerializer`. pub fn validate_vk_default_keccak(vk: &[u8]) -> Result<(), ValidateError> { const D: usize = 2; type C = KeccakGoldilocksConfig; type F = >::F; - deserialize_vk::(vk, &DefaultGateSerializer) + deserialize_vk::(vk) .map(|_| ()) // Discard `Ok` value, map it to `()` .map_err(ValidateError::from) // Convert `DeserializeError` to `ValidateError` }