1use fnv::FnvHasher;
2pub use 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 mod [<$x _witness_c>] {
14 extern "C" {
15 pub fn witness_c_init() -> *mut std::ffi::c_void;
16 pub fn witness_c_resolver() -> *mut std::ffi::c_void;
17 pub fn witness_c_cleanup(instance: *mut std::ffi::c_void);
18 }
19 }
20 extern "C" {
21 pub fn [<$x Instantiate>](i: *mut std::ffi::c_void, resolveImports: *mut std::ffi::c_void);
22 pub fn [<$x FreeInstance>](i: *mut std::ffi::c_void);
23 pub fn [<$x _getFieldNumLen32>](i: *mut std::ffi::c_void) -> u32;
24 pub fn [<$x _getRawPrime>](i: *mut std::ffi::c_void);
25 pub fn [<$x _getWitnessSize>](i: *mut std::ffi::c_void) -> u32;
26 pub fn [<$x _readSharedRWMemory>](i: *mut std::ffi::c_void, l0: u32) -> u32;
27 pub fn [<$x _writeSharedRWMemory>](i: *mut std::ffi::c_void, l0: u32, l1: u32);
28 pub fn [<$x _setInputSignal>](i: *mut std::ffi::c_void, l0: u32, l1: u32, l2: u32);
29 pub fn [<$x _getWitness>](i: *mut std::ffi::c_void, l0: u32);
30 pub fn [<$x _init>](i: *mut std::ffi::c_void, l0: u32);
31 }
32
33 pub unsafe fn [<$x _c_init>]() -> *mut std::ffi::c_void {
36 unsafe { [<$x _witness_c>]::witness_c_init() }
37 }
38
39 pub unsafe fn [<$x _c_resolver>]() -> *mut std::ffi::c_void {
40 unsafe { [<$x _witness_c>]::witness_c_resolver() }
41 }
42
43 pub unsafe fn [<$x _c_cleanup>](v: *mut std::ffi::c_void) {
44 unsafe {
45 [<$x _witness_c>]::witness_c_cleanup(v);
46 }
47 }
48 }
49 rust_witness::paste::item! {
50 pub fn [<$x _witness>]<I: IntoIterator<Item = (String, Vec<rust_witness::BigInt>)>>(inputs: I) -> Vec<rust_witness::BigInt> {
51 unsafe {
53 let instance = [<$x _c_init>]();
54 let resolver = [<$x _c_resolver>]();
55 [<$x Instantiate>](instance, resolver);
58
59 let n32 = [<$x _getFieldNumLen32>](instance);
62 [<$x _getRawPrime>](instance);
63 let mut arr = vec![0; n32 as usize];
64 for x in 0..n32 {
65 let res = [<$x _readSharedRWMemory>](instance, x);
66 arr[(n32 as usize) - (x as usize) - 1] = res;
67 }
68 [<$x _init>](instance, 0);
73
74 for (name, values) in inputs.into_iter() {
76 let (msb, lsb) = rust_witness::fnv(&name);
77
78 for (i, value) in values.into_iter().enumerate() {
79 let f_arr = rust_witness::to_array32(&value, n32 as usize);
80 for j in 0..n32 {
81 [<$x _writeSharedRWMemory>](
82 instance,
83 j,
84 f_arr[(n32 as usize) - 1 - (j as usize)],
85 );
86 }
87 [<$x _setInputSignal>](instance, msb, lsb, i as u32);
88 }
89 }
90
91 let mut w = Vec::new();
92
93 let witness_size = [<$x _getWitnessSize>](instance);
94 for i in 0..witness_size {
95 [<$x _getWitness>](instance, i);
96 let mut arr = vec![0; n32 as usize];
97 for j in 0..n32 {
98 arr[(n32 as usize) - 1 - (j as usize)] =
99 [<$x _readSharedRWMemory>](instance, j);
100 }
101 w.push(rust_witness::from_array32(arr));
102 }
103
104 [<$x FreeInstance>](instance);
106 [<$x _c_cleanup>](instance);
107
108 w
109
110 }
126 }
127 }
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}