circom-compat/src/witness/circom.rs
src/witness/circom.rsRaw
1use color_eyre::Result;
2use wasmer::{Function, Instance, Value};
3
4#[derive(Clone, Debug)]
5pub struct Wasm(Instance);
6
7pub trait CircomBase {
8 fn init(&self, sanity_check: bool) -> Result<()>;
9 fn func(&self, name: &str) -> &Function;
10 fn get_ptr_witness_buffer(&self) -> Result<i32>;
11 fn get_ptr_witness(&self, w: i32) -> Result<i32>;
12 fn get_n_vars(&self) -> Result<i32>;
13 fn get_signal_offset32(
14 &self,
15 p_sig_offset: u32,
16 component: u32,
17 hash_msb: u32,
18 hash_lsb: u32,
19 ) -> Result<()>;
20 fn set_signal(&self, c_idx: i32, component: i32, signal: i32, p_val: i32) -> Result<()>;
21 fn get_i32(&self, name: &str) -> Result<i32>;
22}
23
24pub trait Circom {
25 fn get_fr_len(&self) -> Result<i32>;
26 fn get_ptr_raw_prime(&self) -> Result<i32>;
27}
28
29pub trait Circom2 {
30 fn get_version(&self) -> Result<i32>;
31 fn get_field_num_len32(&self) -> Result<i32>;
32 fn get_raw_prime(&self) -> Result<()>;
33 fn read_shared_rw_memory(&self, i: i32) -> Result<i32>;
34}
35
36#[cfg(not(feature = "circom-2"))]
37impl Circom for Wasm {
38 fn get_fr_len(&self) -> Result<i32> {
39 self.get_i32("getFrLen")
40 }
41
42 fn get_ptr_raw_prime(&self) -> Result<i32> {
43 self.get_i32("getPRawPrime")
44 }
45}
46
47#[cfg(feature = "circom-2")]
48impl Circom2 for Wasm {
49 fn get_version(&self) -> Result<i32> {
50 self.get_i32("getVersion")
51 }
52
53 fn get_field_num_len32(&self) -> Result<i32> {
54 self.get_i32("getFieldNumLen32")
55 }
56
57 fn get_raw_prime(&self) -> Result<()> {
58 let func = self.func("getRawPrime");
59 let _result = func.call(&[])?;
60 Ok(())
61 }
62
63 fn read_shared_rw_memory(&self, i: i32) -> Result<i32> {
64 let func = self.func("readSharedRWMemory");
65 let result = func.call(&[i.into()])?;
66 Ok(result[0].unwrap_i32())
67 }
68}
69
70impl CircomBase for Wasm {
71 fn init(&self, sanity_check: bool) -> Result<()> {
72 let func = self.func("init");
73 func.call(&[Value::I32(sanity_check as i32)])?;
74 Ok(())
75 }
76
77 fn get_ptr_witness_buffer(&self) -> Result<i32> {
78 self.get_i32("getWitnessBuffer")
79 }
80
81 fn get_ptr_witness(&self, w: i32) -> Result<i32> {
82 let func = self.func("getPWitness");
83 let res = func.call(&[w.into()])?;
84
85 Ok(res[0].unwrap_i32())
86 }
87
88 fn get_n_vars(&self) -> Result<i32> {
89 self.get_i32("getNVars")
90 }
91
92 fn get_signal_offset32(
93 &self,
94 p_sig_offset: u32,
95 component: u32,
96 hash_msb: u32,
97 hash_lsb: u32,
98 ) -> Result<()> {
99 let func = self.func("getSignalOffset32");
100 func.call(&[
101 p_sig_offset.into(),
102 component.into(),
103 hash_msb.into(),
104 hash_lsb.into(),
105 ])?;
106
107 Ok(())
108 }
109
110 fn set_signal(&self, c_idx: i32, component: i32, signal: i32, p_val: i32) -> Result<()> {
111 let func = self.func("setSignal");
112 func.call(&[c_idx.into(), component.into(), signal.into(), p_val.into()])?;
113
114 Ok(())
115 }
116
117 fn get_i32(&self, name: &str) -> Result<i32> {
118 let func = self.func(name);
119 let result = func.call(&[])?;
120 Ok(result[0].unwrap_i32())
121 }
122
123 fn func(&self, name: &str) -> &Function {
124 self.0
125 .exports
126 .get_function(name)
127 .unwrap_or_else(|_| panic!("function {} not found", name))
128 }
129}
130
131impl Wasm {
132 pub fn new(instance: Instance) -> Self {
133 Self(instance)
134 }
135}