Offchain Verification Endpoint

V1. Accept requests of the form:

{ "vk": { ... }, "proof": { ... }, "inputs": [ "1", "2", ... ] }

where vk and proof are in the upa format. In this way, groth16 with commits is supported and we have conversion functionality from snarkjs and gnark formats.

Existing code for endpoint (circuits create in upa repo):

Service<_>, HTTPServer<>

In prover_daemon crate. Already has a multi-threaded server impl.

Verifier

upa_circuits::batch_verifier::types::UniversalBatchVerifierInput

#[derive(Clone, Debug, Deserialize, Serialize)] pub struct UniversalBatchVerifierInput<F = Fr> where F: EccPrimeField, { pub vk: VerificationKey, pub proof: Proof, pub inputs: PublicInputs<F>, }

A json request to the verifier service can be UniversalBatchVerifierInput or Vec<UniversalBatchVerifierInput>.

upacircuits::batch_verifier::universal::native

pub fn verify_universal_groth16_batch<B, I>( batch: B, max_num_public_inputs: usize, ) -> bool where B: IntoIterator<Item = I>, I: Borrow<UniversalBatchVerifierInput>,

This handles a sequence of UniversalBatchVerifierInputs. If we make the endpoint accept a list of UniversalBatchVerifierInputs, we can use this function as-is and get batched verification for multi-proof requests.

Client

  • Initially:
    ​​upa remote-verify --endpoint <URL> --format <snarkjs,gnark> --vk <file> --proof <file>
    
  • Later: could create a standalone typescript package which uses upa as a dependency and implements a dedicated CLI:
    ​​nebra-verify --endpoint <URL> --format <snarkjs,gnark> --vk <file> --proof <file>