Skip to content

Commit

Permalink
Use prepared verifying key for non-batch Groth16 verification (#3092)
Browse files Browse the repository at this point in the history
  • Loading branch information
teor2345 authored Nov 23, 2021
1 parent b39f4ca commit 29d5da3
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 50 deletions.
53 changes: 24 additions & 29 deletions zebra-consensus/src/primitives/groth16.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::{
};

use bellman::{
groth16::{batch, prepare_verifying_key, VerifyingKey},
groth16::{batch, VerifyingKey},
VerificationError,
};
use bls12_381::Bls12;
Expand Down Expand Up @@ -40,31 +40,28 @@ pub use params::{Groth16Parameters, GROTH16_PARAMETERS};
/// handle.
pub static SPEND_VERIFIER: Lazy<
Fallback<Batch<Verifier, Item>, ServiceFn<fn(Item) -> Ready<Result<(), VerificationError>>>>,
> =
Lazy::new(|| {
Fallback::new(
Batch::new(
Verifier::new(&GROTH16_PARAMETERS.sapling.spend.vk),
super::MAX_BATCH_SIZE,
super::MAX_BATCH_LATENCY,
),
// We want to fallback to individual verification if batch verification
// fails, so we need a Service to use. The obvious way to do this would
// be to write a closure that returns an async block. But because we
// have to specify the type of a static, we need to be able to write the
// type of the closure and its return value, and both closures and async
// blocks have eldritch types whose names cannot be written. So instead,
// we use a Ready to avoid an async block and cast the closure to a
// function (which is possible because it doesn't capture any state).
tower::service_fn(
(|item: Item| {
ready(item.verify_single(&prepare_verifying_key(
&GROTH16_PARAMETERS.sapling.spend.vk,
)))
}) as fn(_) -> _,
),
)
});
> = Lazy::new(|| {
Fallback::new(
Batch::new(
Verifier::new(&GROTH16_PARAMETERS.sapling.spend.vk),
super::MAX_BATCH_SIZE,
super::MAX_BATCH_LATENCY,
),
// We want to fallback to individual verification if batch verification
// fails, so we need a Service to use. The obvious way to do this would
// be to write a closure that returns an async block. But because we
// have to specify the type of a static, we need to be able to write the
// type of the closure and its return value, and both closures and async
// blocks have eldritch types whose names cannot be written. So instead,
// we use a Ready to avoid an async block and cast the closure to a
// function (which is possible because it doesn't capture any state).
tower::service_fn(
(|item: Item| {
ready(item.verify_single(&GROTH16_PARAMETERS.sapling.spend_prepared_verifying_key))
}) as fn(_) -> _,
),
)
});

/// Global batch verification context for Groth16 proofs of Output statements.
///
Expand Down Expand Up @@ -93,9 +90,7 @@ pub static OUTPUT_VERIFIER: Lazy<
// function (which is possible because it doesn't capture any state).
tower::service_fn(
(|item: Item| {
ready(item.verify_single(&prepare_verifying_key(
&GROTH16_PARAMETERS.sapling.output.vk,
)))
ready(item.verify_single(&GROTH16_PARAMETERS.sapling.output_prepared_verifying_key))
}) as fn(_) -> _,
),
)
Expand Down
35 changes: 14 additions & 21 deletions zebra-consensus/src/primitives/groth16/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,21 +62,18 @@ where
#[tokio::test]
async fn verify_sapling_groth16() {
// Use separate verifiers so shared batch tasks aren't killed when the test ends (#2390)
let mut spend_verifier =
Fallback::new(
Batch::new(
Verifier::new(&GROTH16_PARAMETERS.sapling.spend.vk),
crate::primitives::MAX_BATCH_SIZE,
crate::primitives::MAX_BATCH_LATENCY,
),
tower::service_fn(
(|item: Item| {
ready(item.verify_single(&prepare_verifying_key(
&GROTH16_PARAMETERS.sapling.spend.vk,
)))
}) as fn(_) -> _,
),
);
let mut spend_verifier = Fallback::new(
Batch::new(
Verifier::new(&GROTH16_PARAMETERS.sapling.spend.vk),
crate::primitives::MAX_BATCH_SIZE,
crate::primitives::MAX_BATCH_LATENCY,
),
tower::service_fn(
(|item: Item| {
ready(item.verify_single(&GROTH16_PARAMETERS.sapling.spend_prepared_verifying_key))
}) as fn(_) -> _,
),
);
let mut output_verifier = Fallback::new(
Batch::new(
Verifier::new(&GROTH16_PARAMETERS.sapling.output.vk),
Expand All @@ -85,9 +82,7 @@ async fn verify_sapling_groth16() {
),
tower::service_fn(
(|item: Item| {
ready(item.verify_single(&prepare_verifying_key(
&GROTH16_PARAMETERS.sapling.output.vk,
)))
ready(item.verify_single(&GROTH16_PARAMETERS.sapling.output_prepared_verifying_key))
}) as fn(_) -> _,
),
);
Expand Down Expand Up @@ -163,9 +158,7 @@ async fn correctly_err_on_invalid_output_proof() {
),
tower::service_fn(
(|item: Item| {
ready(item.verify_single(&prepare_verifying_key(
&GROTH16_PARAMETERS.sapling.output.vk,
)))
ready(item.verify_single(&GROTH16_PARAMETERS.sapling.output_prepared_verifying_key))
}) as fn(_) -> _,
),
);
Expand Down

0 comments on commit 29d5da3

Please sign in to comment.