mirror of
https://github.com/codex-storage/circom-compat.git
synced 2025-02-09 17:44:01 +00:00
circom2 proof generation (#14)
* circom2 proof generation * fix fmt and test * fix clippy and format dependency * make clippy happy (circom2 changes) * make clippy happy (#12)
This commit is contained in:
parent
bf2b439fae
commit
1732e15d63
@ -7,6 +7,7 @@ edition = "2018"
|
|||||||
# WASM operations
|
# WASM operations
|
||||||
wasmer = { version = "2.0" }
|
wasmer = { version = "2.0" }
|
||||||
fnv = { version = "1.0.3", default-features = false }
|
fnv = { version = "1.0.3", default-features = false }
|
||||||
|
num = { version = "0.4.0" }
|
||||||
num-traits = { version = "0.2.0", default-features = false }
|
num-traits = { version = "0.2.0", default-features = false }
|
||||||
num-bigint = { version = "0.4", default-features = false, features = ["rand"] }
|
num-bigint = { version = "0.4", default-features = false, features = ["rand"] }
|
||||||
|
|
||||||
|
@ -31,6 +31,10 @@ pub trait Circom2 {
|
|||||||
fn get_field_num_len32(&self) -> Result<i32>;
|
fn get_field_num_len32(&self) -> Result<i32>;
|
||||||
fn get_raw_prime(&self) -> Result<()>;
|
fn get_raw_prime(&self) -> Result<()>;
|
||||||
fn read_shared_rw_memory(&self, i: i32) -> Result<i32>;
|
fn read_shared_rw_memory(&self, i: i32) -> Result<i32>;
|
||||||
|
fn write_shared_rw_memory(&self, i: i32, v: i32) -> Result<()>;
|
||||||
|
fn set_input_signal(&self, hmsb: i32, hlsb: i32, pos: i32) -> Result<()>;
|
||||||
|
fn get_witness(&self, i: i32) -> Result<()>;
|
||||||
|
fn get_witness_size(&self) -> Result<i32>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "circom-2"))]
|
#[cfg(not(feature = "circom-2"))]
|
||||||
@ -56,7 +60,7 @@ impl Circom2 for Wasm {
|
|||||||
|
|
||||||
fn get_raw_prime(&self) -> Result<()> {
|
fn get_raw_prime(&self) -> Result<()> {
|
||||||
let func = self.func("getRawPrime");
|
let func = self.func("getRawPrime");
|
||||||
let _result = func.call(&[])?;
|
func.call(&[])?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +69,30 @@ impl Circom2 for Wasm {
|
|||||||
let result = func.call(&[i.into()])?;
|
let result = func.call(&[i.into()])?;
|
||||||
Ok(result[0].unwrap_i32())
|
Ok(result[0].unwrap_i32())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn write_shared_rw_memory(&self, i: i32, v: i32) -> Result<()> {
|
||||||
|
let func = self.func("writeSharedRWMemory");
|
||||||
|
func.call(&[i.into(), v.into()])?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_input_signal(&self, hmsb: i32, hlsb: i32, pos: i32) -> Result<()> {
|
||||||
|
let func = self.func("setInputSignal");
|
||||||
|
func.call(&[hmsb.into(), hlsb.into(), pos.into()])?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_witness(&self, i: i32) -> Result<()> {
|
||||||
|
let func = self.func("getWitness");
|
||||||
|
func.call(&[i.into()])?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_witness_size(&self) -> Result<i32> {
|
||||||
|
let func = self.func("getWitnessSize");
|
||||||
|
let result = func.call(&[])?;
|
||||||
|
Ok(result[0].unwrap_i32())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CircomBase for Wasm {
|
impl CircomBase for Wasm {
|
||||||
|
@ -5,6 +5,9 @@ use num_traits::Zero;
|
|||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use wasmer::{imports, Function, Instance, Memory, MemoryType, Module, RuntimeError, Store};
|
use wasmer::{imports, Function, Instance, Memory, MemoryType, Module, RuntimeError, Store};
|
||||||
|
|
||||||
|
#[cfg(feature = "circom-2")]
|
||||||
|
use num::ToPrimitive;
|
||||||
|
|
||||||
#[cfg(feature = "circom-2")]
|
#[cfg(feature = "circom-2")]
|
||||||
use super::Circom2;
|
use super::Circom2;
|
||||||
|
|
||||||
@ -34,6 +37,21 @@ fn from_array32(arr: Vec<i32>) -> BigInt {
|
|||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "circom-2")]
|
||||||
|
fn to_array32(s: &BigInt, size: usize) -> Vec<i32> {
|
||||||
|
let mut res = vec![0; size as usize];
|
||||||
|
let mut rem = s.clone();
|
||||||
|
let radix = BigInt::from(0x100000000u64);
|
||||||
|
let mut c = size - 1;
|
||||||
|
while !rem.is_zero() {
|
||||||
|
res[c] = (&rem % &radix).to_i32().unwrap();
|
||||||
|
rem /= &radix;
|
||||||
|
c -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
impl WitnessCalculator {
|
impl WitnessCalculator {
|
||||||
pub fn new(path: impl AsRef<std::path::Path>) -> Result<Self> {
|
pub fn new(path: impl AsRef<std::path::Path>) -> Result<Self> {
|
||||||
let store = Store::default();
|
let store = Store::default();
|
||||||
@ -59,29 +77,25 @@ impl WitnessCalculator {
|
|||||||
};
|
};
|
||||||
let instance = Wasm::new(Instance::new(&module, &import_object)?);
|
let instance = Wasm::new(Instance::new(&module, &import_object)?);
|
||||||
|
|
||||||
let n32;
|
|
||||||
let prime: BigInt;
|
|
||||||
let mut safe_memory: SafeMemory;
|
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(feature = "circom-2")] {
|
if #[cfg(feature = "circom-2")] {
|
||||||
//let version = instance.get_version()?;
|
//let version = instance.get_version()?;
|
||||||
n32 = instance.get_field_num_len32()?;
|
let n32 = instance.get_field_num_len32()?;
|
||||||
safe_memory = SafeMemory::new(memory, n32 as usize, BigInt::zero());
|
let mut safe_memory = SafeMemory::new(memory, n32 as usize, BigInt::zero());
|
||||||
let _res = instance.get_raw_prime()?;
|
instance.get_raw_prime()?;
|
||||||
let mut arr = vec![0; n32 as usize];
|
let mut arr = vec![0; n32 as usize];
|
||||||
for i in 0..n32 {
|
for i in 0..n32 {
|
||||||
let res = instance.read_shared_rw_memory(i)?;
|
let res = instance.read_shared_rw_memory(i)?;
|
||||||
arr[(n32 as usize) - (i as usize) - 1] = res;
|
arr[(n32 as usize) - (i as usize) - 1] = res;
|
||||||
}
|
}
|
||||||
prime = from_array32(arr);
|
let prime = from_array32(arr);
|
||||||
} else {
|
} else {
|
||||||
// Fallback to Circom 1 behavior
|
// Fallback to Circom 1 behavior
|
||||||
//version = 1;
|
//version = 1;
|
||||||
n32 = (instance.get_fr_len()? >> 2) - 2;
|
let n32 = (instance.get_fr_len()? >> 2) - 2;
|
||||||
safe_memory = SafeMemory::new(memory, n32 as usize, BigInt::zero());
|
let mut safe_memory = SafeMemory::new(memory, n32 as usize, BigInt::zero());
|
||||||
let ptr = instance.get_ptr_raw_prime()?;
|
let ptr = instance.get_ptr_raw_prime()?;
|
||||||
prime = safe_memory.read_big(ptr as usize, n32 as usize)?;
|
let prime = safe_memory.read_big(ptr as usize, n32 as usize)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,37 +114,71 @@ impl WitnessCalculator {
|
|||||||
inputs: I,
|
inputs: I,
|
||||||
sanity_check: bool,
|
sanity_check: bool,
|
||||||
) -> Result<Vec<BigInt>> {
|
) -> Result<Vec<BigInt>> {
|
||||||
let old_mem_free_pos = self.memory.free_pos();
|
|
||||||
|
|
||||||
self.instance.init(sanity_check)?;
|
self.instance.init(sanity_check)?;
|
||||||
|
|
||||||
let p_sig_offset = self.memory.alloc_u32();
|
cfg_if::cfg_if! {
|
||||||
let p_fr = self.memory.alloc_fr();
|
if #[cfg(feature = "circom-2")] {
|
||||||
|
let n32 = self.instance.get_field_num_len32()?;
|
||||||
|
} else {
|
||||||
|
let old_mem_free_pos = self.memory.free_pos();
|
||||||
|
let p_sig_offset = self.memory.alloc_u32();
|
||||||
|
let p_fr = self.memory.alloc_fr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// allocate the inputs
|
// allocate the inputs
|
||||||
for (name, values) in inputs.into_iter() {
|
for (name, values) in inputs.into_iter() {
|
||||||
let (msb, lsb) = fnv(&name);
|
let (msb, lsb) = fnv(&name);
|
||||||
self.instance
|
|
||||||
.get_signal_offset32(p_sig_offset, 0, msb, lsb)?;
|
|
||||||
|
|
||||||
let sig_offset = self.memory.read_u32(p_sig_offset as usize) as usize;
|
cfg_if::cfg_if! {
|
||||||
|
if #[cfg(feature = "circom-2")] {
|
||||||
|
for (i, value) in values.into_iter().enumerate() {
|
||||||
|
let f_arr = to_array32(&value, n32 as usize);
|
||||||
|
for j in 0..n32 {
|
||||||
|
self.instance.write_shared_rw_memory(j as i32, f_arr[(n32 as usize) - 1 - (j as usize)])?;
|
||||||
|
}
|
||||||
|
self.instance.set_input_signal(msb as i32, lsb as i32, i as i32)?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.instance
|
||||||
|
.get_signal_offset32(p_sig_offset, 0, msb, lsb)?;
|
||||||
|
|
||||||
for (i, value) in values.into_iter().enumerate() {
|
let sig_offset = self.memory.read_u32(p_sig_offset as usize) as usize;
|
||||||
self.memory.write_fr(p_fr as usize, &value)?;
|
|
||||||
self.instance
|
for (i, value) in values.into_iter().enumerate() {
|
||||||
.set_signal(0, 0, (sig_offset + i) as i32, p_fr as i32)?;
|
self.memory.write_fr(p_fr as usize, &value)?;
|
||||||
|
self.instance
|
||||||
|
.set_signal(0, 0, (sig_offset + i) as i32, p_fr as i32)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut w = Vec::new();
|
let mut w = Vec::new();
|
||||||
let n_vars = self.instance.get_n_vars()?;
|
|
||||||
for i in 0..n_vars {
|
|
||||||
let ptr = self.instance.get_ptr_witness(i)? as usize;
|
|
||||||
let el = self.memory.read_fr(ptr)?;
|
|
||||||
w.push(el);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.memory.set_free_pos(old_mem_free_pos);
|
cfg_if::cfg_if! {
|
||||||
|
if #[cfg(feature = "circom-2")] {
|
||||||
|
let witness_size = self.instance.get_witness_size()?;
|
||||||
|
for i in 0..witness_size {
|
||||||
|
self.instance.get_witness(i)?;
|
||||||
|
let mut arr = vec![0; n32 as usize];
|
||||||
|
for j in 0..n32 {
|
||||||
|
arr[(n32 as usize) - 1- (j as usize)] = self.instance.read_shared_rw_memory(j)?;
|
||||||
|
}
|
||||||
|
w.push(from_array32(arr));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
let n_vars = self.instance.get_n_vars()?;
|
||||||
|
for i in 0..n_vars {
|
||||||
|
let ptr = self.instance.get_ptr_witness(i)? as usize;
|
||||||
|
let el = self.memory.read_fr(ptr)?;
|
||||||
|
w.push(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.memory.set_free_pos(old_mem_free_pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(w)
|
Ok(w)
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@ use num_traits::Zero;
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct Section {
|
struct Section {
|
||||||
position: u64,
|
position: u64,
|
||||||
|
#[allow(dead_code)]
|
||||||
size: usize,
|
size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +59,9 @@ pub fn read_zkey<R: Read + Seek>(
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct BinFile<'a, R> {
|
struct BinFile<'a, R> {
|
||||||
|
#[allow(dead_code)]
|
||||||
ftype: String,
|
ftype: String,
|
||||||
|
#[allow(dead_code)]
|
||||||
version: u32,
|
version: u32,
|
||||||
sections: HashMap<u32, Vec<Section>>,
|
sections: HashMap<u32, Vec<Section>>,
|
||||||
reader: &'a mut R,
|
reader: &'a mut R,
|
||||||
@ -255,16 +258,20 @@ impl ZVerifyingKey {
|
|||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct HeaderGroth {
|
struct HeaderGroth {
|
||||||
|
#[allow(dead_code)]
|
||||||
n8q: u32,
|
n8q: u32,
|
||||||
|
#[allow(dead_code)]
|
||||||
q: BigInteger256,
|
q: BigInteger256,
|
||||||
|
#[allow(dead_code)]
|
||||||
n8r: u32,
|
n8r: u32,
|
||||||
|
#[allow(dead_code)]
|
||||||
r: BigInteger256,
|
r: BigInteger256,
|
||||||
|
|
||||||
n_vars: usize,
|
n_vars: usize,
|
||||||
n_public: usize,
|
n_public: usize,
|
||||||
|
|
||||||
domain_size: u32,
|
domain_size: u32,
|
||||||
|
#[allow(dead_code)]
|
||||||
power: u32,
|
power: u32,
|
||||||
|
|
||||||
verifying_key: ZVerifyingKey,
|
verifying_key: ZVerifyingKey,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user