openvm_sdk/
types.rs
1use itertools::Itertools;
2use openvm_native_recursion::halo2::{Fr, RawEvmProof};
3use serde::{Deserialize, Serialize};
4use serde_with::serde_as;
5use thiserror::Error;
6
7const BN254_BYTES: usize = 32;
9const NUM_BN254_ACCUMULATORS: usize = 12;
11const NUM_BN254_PROOF: usize = 43;
13
14#[serde_as]
15#[derive(Clone, Deserialize, Serialize)]
16pub struct EvmProof {
17 #[serde_as(as = "serde_with::hex::Hex")]
18 pub accumulators: Vec<u8>,
20 #[serde_as(as = "serde_with::hex::Hex")]
21 pub exe_commit: [u8; BN254_BYTES],
23 #[serde_as(as = "serde_with::hex::Hex")]
24 pub leaf_commit: [u8; BN254_BYTES],
26 #[serde_as(as = "serde_with::hex::Hex")]
27 pub user_public_values: Vec<u8>,
29 #[serde_as(as = "serde_with::hex::Hex")]
30 pub proof: Vec<u8>,
32}
33
34#[derive(Debug, Error)]
35pub enum EvmProofConversionError {
36 #[error("Invalid length of proof")]
37 InvalidLengthProof,
38 #[error("Invalid length of instances")]
39 InvalidLengthInstances,
40 #[error("Invalid length of user public values")]
41 InvalidUserPublicValuesLength,
42 #[error("Invalid length of accumulators")]
43 InvalidLengthAccumulators,
44}
45
46impl EvmProof {
47 pub fn verifier_calldata(&self) -> Vec<u8> {
49 let evm_proof: RawEvmProof = self.clone().try_into().unwrap();
50 evm_proof.verifier_calldata()
51 }
52}
53
54impl TryFrom<RawEvmProof> for EvmProof {
55 type Error = EvmProofConversionError;
56
57 fn try_from(evm_proof: RawEvmProof) -> Result<Self, Self::Error> {
58 let RawEvmProof { instances, proof } = evm_proof;
59 if NUM_BN254_ACCUMULATORS + 2 >= instances.len() {
60 return Err(EvmProofConversionError::InvalidLengthInstances);
61 }
62 if proof.len() != NUM_BN254_PROOF * BN254_BYTES {
63 return Err(EvmProofConversionError::InvalidLengthProof);
64 }
65 let accumulators = instances[0..NUM_BN254_ACCUMULATORS]
66 .iter()
67 .flat_map(|f| f.to_bytes())
68 .collect::<Vec<_>>();
69 let exe_commit = instances[NUM_BN254_ACCUMULATORS].to_bytes();
70 let leaf_commit = instances[NUM_BN254_ACCUMULATORS + 1].to_bytes();
71 let user_public_values = instances[NUM_BN254_ACCUMULATORS + 2..]
72 .iter()
73 .flat_map(|f| f.to_bytes())
74 .collect::<Vec<_>>();
75 Ok(Self {
76 accumulators,
77 exe_commit,
78 leaf_commit,
79 user_public_values,
80 proof,
81 })
82 }
83}
84
85impl TryFrom<EvmProof> for RawEvmProof {
86 type Error = EvmProofConversionError;
87 fn try_from(evm_openvm_proof: EvmProof) -> Result<Self, Self::Error> {
88 let EvmProof {
89 accumulators,
90 exe_commit,
91 leaf_commit,
92 user_public_values,
93 proof,
94 } = evm_openvm_proof;
95 if proof.len() != NUM_BN254_PROOF * BN254_BYTES {
96 return Err(EvmProofConversionError::InvalidLengthProof);
97 }
98 let instances = {
99 if accumulators.len() != NUM_BN254_ACCUMULATORS * BN254_BYTES {
100 return Err(EvmProofConversionError::InvalidLengthAccumulators);
101 }
102 if user_public_values.is_empty() || user_public_values.len() % BN254_BYTES != 0 {
103 return Err(EvmProofConversionError::InvalidUserPublicValuesLength);
104 }
105 let mut ret = Vec::new();
106 for chunk in &accumulators
107 .iter()
108 .chain(&exe_commit)
109 .chain(&leaf_commit)
110 .chain(&user_public_values)
111 .chunks(BN254_BYTES)
112 {
113 let c = chunk.copied().collect::<Vec<_>>().try_into().unwrap();
114 ret.push(Fr::from_bytes(&c).unwrap());
115 }
116 ret
117 };
118 Ok(RawEvmProof { instances, proof })
119 }
120}