inherence_verifier/
proof.rs1use ark_bn254::{Bn254, Fr};
4use ark_groth16::{Groth16, Proof, VerifyingKey, prepare_verifying_key};
5use ark_serialize::CanonicalDeserialize;
6use ark_snark::SNARK;
7use base64::Engine;
8use serde_json::Value;
9
10use crate::binding;
11use crate::error::VerifyError;
12use crate::VerifyConfig;
13
14pub fn verify_if_present(p: &Value, cfg: &VerifyConfig) -> Result<(), VerifyError> {
19 let proof_evidence = p["verification"]["evidence"].as_array()
20 .and_then(|arr| arr.iter().find(|e| e["type"] == "cryptographic_proof"))
21 .ok_or_else(|| VerifyError::SchemaViolation("no cryptographic_proof evidence".into()))?;
22
23 let proof_b64 = match proof_evidence.get("proof").and_then(|v| v.as_str()) {
24 Some(s) if !s.is_empty() => s,
25 _ => return Ok(()), };
27
28 let proof_bytes = base64::engine::general_purpose::STANDARD.decode(proof_b64)
29 .map_err(|e| VerifyError::ProofInvalid(format!("proof not base64: {e}")))?;
30 let proof = Proof::<Bn254>::deserialize_compressed(&proof_bytes[..])
31 .or_else(|_| Proof::<Bn254>::deserialize_uncompressed(&proof_bytes[..]))
32 .map_err(|e| VerifyError::ProofInvalid(format!("proof deserialize failed: {e}")))?;
33
34 let vk_hash = p["verification"]["public_inputs"]["vk_hash"].as_str().unwrap_or("");
35 let vk_bytes = cfg.lookup_vk(vk_hash)
36 .ok_or_else(|| VerifyError::UnknownVk(vk_hash.to_string()))?;
37 let vk = VerifyingKey::<Bn254>::deserialize_compressed(vk_bytes)
38 .or_else(|_| VerifyingKey::<Bn254>::deserialize_uncompressed(vk_bytes))
39 .map_err(|e| VerifyError::ProofInvalid(format!("vk deserialize failed: {e}")))?;
40
41 let pi = &p["verification"]["public_inputs"];
42 let action_hash = pi["action_hash"].as_str().unwrap_or("");
43 let contract_hash = pi["contract_hash"].as_str().unwrap_or("");
44 let decision_bit = pi["decision_bit"].as_i64().unwrap_or(-1) as u8;
45 let inputs_fr: Vec<Fr> = binding::public_inputs_fr(
46 action_hash, contract_hash, decision_bit, vk_hash,
47 )?;
48
49 let pvk = prepare_verifying_key(&vk);
50 let ok = Groth16::<Bn254>::verify_with_processed_vk(&pvk, &inputs_fr, &proof)
51 .map_err(|e| VerifyError::ProofInvalid(format!("verify call failed: {e}")))?;
52 if !ok {
53 return Err(VerifyError::ProofInvalid("verify returned false".into()));
54 }
55 Ok(())
56}