1use fnv::FnvHasher;
2use num_bigint::BigInt;
3use num_traits::{ToPrimitive, Zero};
4pub use paste;
5use std::hash::Hasher;
6
7pub mod transpile;
8
9#[macro_export]
10macro_rules! witness {
11 ($x: ident) => {
12 rust_witness::paste::item! {
13 extern "C" {
14 pub fn [<$x Instantiate>](i: *mut std::ffi::c_void, resolveImports: *mut std::ffi::c_void);
15 pub fn [<$x FreeInstance>](i: *mut std::ffi::c_void);
16 pub fn [<$x _getFieldNumLen32>](i: *mut std::ffi::c_void) -> u32;
17 pub fn [<$x _getRawPrime>](i: *mut std::ffi::c_void);
18 pub fn [<$x _getWitnessSize>](i: *mut std::ffi::c_void) -> u32;
19 pub fn [<$x _readSharedRWMemory>](i: *mut std::ffi::c_void, l0: u32) -> u32;
20 pub fn [<$x _writeSharedRWMemory>](i: *mut std::ffi::c_void, l0: u32, l1: u32);
21 pub fn [<$x _setInputSignal>](i: *mut std::ffi::c_void, l0: u32, l1: u32, l2: u32);
22 pub fn [<$x _getWitness>](i: *mut std::ffi::c_void, l0: u32);
23 pub fn [<$x _init>](i: *mut std::ffi::c_void, l0: u32);
24 }
25 }
26 rust_witness::paste::item! {
27 pub fn [<$x _witness>]<I: IntoIterator<Item = (String, Vec<num_bigint::BigInt>)>>(inputs: I) -> Vec<num_bigint::BigInt> {
28 unsafe {
30 let instance = rust_witness::c_init();
31 let resolver = rust_witness::c_resolver();
32 [<$x Instantiate>](instance, resolver);
35
36 let n32 = [<$x _getFieldNumLen32>](instance);
39 [<$x _getRawPrime>](instance);
40 let mut arr = vec![0; n32 as usize];
41 for x in 0..n32 {
42 let res = [<$x _readSharedRWMemory>](instance, x);
43 arr[(n32 as usize) - (x as usize) - 1] = res;
44 }
45 [<$x _init>](instance, 0);
50
51 for (name, values) in inputs.into_iter() {
53 let (msb, lsb) = rust_witness::fnv(&name);
54
55 for (i, value) in values.into_iter().enumerate() {
56 let f_arr = rust_witness::to_array32(&value, n32 as usize);
57 for j in 0..n32 {
58 [<$x _writeSharedRWMemory>](
59 instance,
60 j,
61 f_arr[(n32 as usize) - 1 - (j as usize)],
62 );
63 }
64 [<$x _setInputSignal>](instance, msb, lsb, i as u32);
65 }
66 }
67
68 let mut w = Vec::new();
69
70 let witness_size = [<$x _getWitnessSize>](instance);
71 for i in 0..witness_size {
72 [<$x _getWitness>](instance, i);
73 let mut arr = vec![0; n32 as usize];
74 for j in 0..n32 {
75 arr[(n32 as usize) - 1 - (j as usize)] =
76 [<$x _readSharedRWMemory>](instance, j);
77 }
78 w.push(rust_witness::from_array32(arr));
79 }
80
81 [<$x FreeInstance>](instance);
83 rust_witness::c_cleanup(instance);
84
85 w
86
87 }
103 }
104 }
105 };
106}
107
108extern "C" {
110 pub fn witness_c_init() -> *mut std::ffi::c_void;
111 pub fn witness_c_resolver() -> *mut std::ffi::c_void;
112 pub fn witness_c_cleanup(instance: *mut std::ffi::c_void);
113}
114
115pub fn c_init() -> *mut std::ffi::c_void {
118 unsafe { witness_c_init() }
119}
120
121pub fn c_resolver() -> *mut std::ffi::c_void {
122 unsafe { witness_c_resolver() }
123}
124
125pub fn c_cleanup(v: *mut std::ffi::c_void) {
126 unsafe {
127 witness_c_cleanup(v);
128 }
129}
130
131pub fn fnv(inp: &str) -> (u32, u32) {
132 let mut hasher = FnvHasher::default();
133 hasher.write(inp.as_bytes());
134 let h = hasher.finish();
135
136 ((h >> 32) as u32, h as u32)
137}
138
139pub fn from_array32(arr: Vec<u32>) -> BigInt {
140 let mut res = BigInt::zero();
141 let radix = BigInt::from(0x100000000u64);
142 for &val in arr.iter() {
143 res = res * &radix + BigInt::from(val);
144 }
145 res
146}
147
148pub fn to_array32(s: &BigInt, size: usize) -> Vec<u32> {
149 let mut res = vec![0; size];
150 let mut rem = s.clone();
151 let radix = BigInt::from(0x100000000u64);
152 let mut c = size;
153 while !rem.is_zero() {
154 c -= 1;
155 res[c] = (&rem % &radix).to_u32().unwrap();
156 rem /= &radix;
157 }
158
159 res
160}