Use prepared verifying key for non-batch Groth16 verification (#3092)
This commit is contained in:
parent
b39f4ca5aa
commit
29d5da320f
|
|
@ -9,7 +9,7 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use bellman::{
|
use bellman::{
|
||||||
groth16::{batch, prepare_verifying_key, VerifyingKey},
|
groth16::{batch, VerifyingKey},
|
||||||
VerificationError,
|
VerificationError,
|
||||||
};
|
};
|
||||||
use bls12_381::Bls12;
|
use bls12_381::Bls12;
|
||||||
|
|
@ -40,31 +40,28 @@ pub use params::{Groth16Parameters, GROTH16_PARAMETERS};
|
||||||
/// handle.
|
/// handle.
|
||||||
pub static SPEND_VERIFIER: Lazy<
|
pub static SPEND_VERIFIER: Lazy<
|
||||||
Fallback<Batch<Verifier, Item>, ServiceFn<fn(Item) -> Ready<Result<(), VerificationError>>>>,
|
Fallback<Batch<Verifier, Item>, ServiceFn<fn(Item) -> Ready<Result<(), VerificationError>>>>,
|
||||||
> =
|
> = Lazy::new(|| {
|
||||||
Lazy::new(|| {
|
Fallback::new(
|
||||||
Fallback::new(
|
Batch::new(
|
||||||
Batch::new(
|
Verifier::new(&GROTH16_PARAMETERS.sapling.spend.vk),
|
||||||
Verifier::new(&GROTH16_PARAMETERS.sapling.spend.vk),
|
super::MAX_BATCH_SIZE,
|
||||||
super::MAX_BATCH_SIZE,
|
super::MAX_BATCH_LATENCY,
|
||||||
super::MAX_BATCH_LATENCY,
|
),
|
||||||
),
|
// We want to fallback to individual verification if batch verification
|
||||||
// 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
|
||||||
// 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
|
||||||
// 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
|
||||||
// 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
|
||||||
// type of the closure and its return value, and both closures and async
|
// blocks have eldritch types whose names cannot be written. So instead,
|
||||||
// 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
|
||||||
// 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).
|
||||||
// function (which is possible because it doesn't capture any state).
|
tower::service_fn(
|
||||||
tower::service_fn(
|
(|item: Item| {
|
||||||
(|item: Item| {
|
ready(item.verify_single(&GROTH16_PARAMETERS.sapling.spend_prepared_verifying_key))
|
||||||
ready(item.verify_single(&prepare_verifying_key(
|
}) as fn(_) -> _,
|
||||||
&GROTH16_PARAMETERS.sapling.spend.vk,
|
),
|
||||||
)))
|
)
|
||||||
}) as fn(_) -> _,
|
});
|
||||||
),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
/// Global batch verification context for Groth16 proofs of Output statements.
|
/// Global batch verification context for Groth16 proofs of Output statements.
|
||||||
///
|
///
|
||||||
|
|
@ -93,9 +90,7 @@ pub static OUTPUT_VERIFIER: Lazy<
|
||||||
// function (which is possible because it doesn't capture any state).
|
// function (which is possible because it doesn't capture any state).
|
||||||
tower::service_fn(
|
tower::service_fn(
|
||||||
(|item: Item| {
|
(|item: Item| {
|
||||||
ready(item.verify_single(&prepare_verifying_key(
|
ready(item.verify_single(&GROTH16_PARAMETERS.sapling.output_prepared_verifying_key))
|
||||||
&GROTH16_PARAMETERS.sapling.output.vk,
|
|
||||||
)))
|
|
||||||
}) as fn(_) -> _,
|
}) as fn(_) -> _,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -62,21 +62,18 @@ where
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn verify_sapling_groth16() {
|
async fn verify_sapling_groth16() {
|
||||||
// Use separate verifiers so shared batch tasks aren't killed when the test ends (#2390)
|
// Use separate verifiers so shared batch tasks aren't killed when the test ends (#2390)
|
||||||
let mut spend_verifier =
|
let mut spend_verifier = Fallback::new(
|
||||||
Fallback::new(
|
Batch::new(
|
||||||
Batch::new(
|
Verifier::new(&GROTH16_PARAMETERS.sapling.spend.vk),
|
||||||
Verifier::new(&GROTH16_PARAMETERS.sapling.spend.vk),
|
crate::primitives::MAX_BATCH_SIZE,
|
||||||
crate::primitives::MAX_BATCH_SIZE,
|
crate::primitives::MAX_BATCH_LATENCY,
|
||||||
crate::primitives::MAX_BATCH_LATENCY,
|
),
|
||||||
),
|
tower::service_fn(
|
||||||
tower::service_fn(
|
(|item: Item| {
|
||||||
(|item: Item| {
|
ready(item.verify_single(&GROTH16_PARAMETERS.sapling.spend_prepared_verifying_key))
|
||||||
ready(item.verify_single(&prepare_verifying_key(
|
}) as fn(_) -> _,
|
||||||
&GROTH16_PARAMETERS.sapling.spend.vk,
|
),
|
||||||
)))
|
);
|
||||||
}) as fn(_) -> _,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
let mut output_verifier = Fallback::new(
|
let mut output_verifier = Fallback::new(
|
||||||
Batch::new(
|
Batch::new(
|
||||||
Verifier::new(&GROTH16_PARAMETERS.sapling.output.vk),
|
Verifier::new(&GROTH16_PARAMETERS.sapling.output.vk),
|
||||||
|
|
@ -85,9 +82,7 @@ async fn verify_sapling_groth16() {
|
||||||
),
|
),
|
||||||
tower::service_fn(
|
tower::service_fn(
|
||||||
(|item: Item| {
|
(|item: Item| {
|
||||||
ready(item.verify_single(&prepare_verifying_key(
|
ready(item.verify_single(&GROTH16_PARAMETERS.sapling.output_prepared_verifying_key))
|
||||||
&GROTH16_PARAMETERS.sapling.output.vk,
|
|
||||||
)))
|
|
||||||
}) as fn(_) -> _,
|
}) as fn(_) -> _,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -163,9 +158,7 @@ async fn correctly_err_on_invalid_output_proof() {
|
||||||
),
|
),
|
||||||
tower::service_fn(
|
tower::service_fn(
|
||||||
(|item: Item| {
|
(|item: Item| {
|
||||||
ready(item.verify_single(&prepare_verifying_key(
|
ready(item.verify_single(&GROTH16_PARAMETERS.sapling.output_prepared_verifying_key))
|
||||||
&GROTH16_PARAMETERS.sapling.output.vk,
|
|
||||||
)))
|
|
||||||
}) as fn(_) -> _,
|
}) as fn(_) -> _,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue