arnaucube
arnaucube/circom-compatPublic Self-hosted repository
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    fn write_shared_rw_memory(&self, i: i32, v: i32) -> Result<()>;
 35    fn set_input_signal(&self, hmsb: i32, hlsb: i32, pos: i32) -> Result<()>;
 36    fn get_witness(&self, i: i32) -> Result<()>;
 37    fn get_witness_size(&self) -> Result<i32>;
 38}
 39
 40#[cfg(not(feature = "circom-2"))]
 41impl Circom for Wasm {
 42    fn get_fr_len(&self) -> Result<i32> {
 43        self.get_i32("getFrLen")
 44    }
 45
 46    fn get_ptr_raw_prime(&self) -> Result<i32> {
 47        self.get_i32("getPRawPrime")
 48    }
 49}
 50
 51#[cfg(feature = "circom-2")]
 52impl Circom2 for Wasm {
 53    fn get_version(&self) -> Result<i32> {
 54        self.get_i32("getVersion")
 55    }
 56
 57    fn get_field_num_len32(&self) -> Result<i32> {
 58        self.get_i32("getFieldNumLen32")
 59    }
 60
 61    fn get_raw_prime(&self) -> Result<()> {
 62        let func = self.func("getRawPrime");
 63        func.call(&[])?;
 64        Ok(())
 65    }
 66
 67    fn read_shared_rw_memory(&self, i: i32) -> Result<i32> {
 68        let func = self.func("readSharedRWMemory");
 69        let result = func.call(&[i.into()])?;
 70        Ok(result[0].unwrap_i32())
 71    }
 72
 73    fn write_shared_rw_memory(&self, i: i32, v: i32) -> Result<()> {
 74        let func = self.func("writeSharedRWMemory");
 75        func.call(&[i.into(), v.into()])?;
 76        Ok(())
 77    }
 78
 79    fn set_input_signal(&self, hmsb: i32, hlsb: i32, pos: i32) -> Result<()> {
 80        let func = self.func("setInputSignal");
 81        func.call(&[hmsb.into(), hlsb.into(), pos.into()])?;
 82        Ok(())
 83    }
 84
 85    fn get_witness(&self, i: i32) -> Result<()> {
 86        let func = self.func("getWitness");
 87        func.call(&[i.into()])?;
 88        Ok(())
 89    }
 90
 91    fn get_witness_size(&self) -> Result<i32> {
 92        let func = self.func("getWitnessSize");
 93        let result = func.call(&[])?;
 94        Ok(result[0].unwrap_i32())
 95    }
 96}
 97
 98impl CircomBase for Wasm {
 99    fn init(&self, sanity_check: bool) -> Result<()> {
100        let func = self.func("init");
101        func.call(&[Value::I32(sanity_check as i32)])?;
102        Ok(())
103    }
104
105    fn get_ptr_witness_buffer(&self) -> Result<i32> {
106        self.get_i32("getWitnessBuffer")
107    }
108
109    fn get_ptr_witness(&self, w: i32) -> Result<i32> {
110        let func = self.func("getPWitness");
111        let res = func.call(&[w.into()])?;
112
113        Ok(res[0].unwrap_i32())
114    }
115
116    fn get_n_vars(&self) -> Result<i32> {
117        self.get_i32("getNVars")
118    }
119
120    fn get_signal_offset32(
121        &self,
122        p_sig_offset: u32,
123        component: u32,
124        hash_msb: u32,
125        hash_lsb: u32,
126    ) -> Result<()> {
127        let func = self.func("getSignalOffset32");
128        func.call(&[
129            p_sig_offset.into(),
130            component.into(),
131            hash_msb.into(),
132            hash_lsb.into(),
133        ])?;
134
135        Ok(())
136    }
137
138    fn set_signal(&self, c_idx: i32, component: i32, signal: i32, p_val: i32) -> Result<()> {
139        let func = self.func("setSignal");
140        func.call(&[c_idx.into(), component.into(), signal.into(), p_val.into()])?;
141
142        Ok(())
143    }
144
145    fn get_i32(&self, name: &str) -> Result<i32> {
146        let func = self.func(name);
147        let result = func.call(&[])?;
148        Ok(result[0].unwrap_i32())
149    }
150
151    fn func(&self, name: &str) -> &Function {
152        self.0
153            .exports
154            .get_function(name)
155            .unwrap_or_else(|_| panic!("function {} not found", name))
156    }
157}
158
159impl Wasm {
160    pub fn new(instance: Instance) -> Self {
161        Self(instance)
162    }
163}