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}
 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}