types.rs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. use bellman::{gadgets::Assignment, groth16, Circuit, ConstraintSystem, SynthesisError};
  2. use sapvi::bls_extensions::BlsStringConversion;
  3. use std::cell::RefCell;
  4. use std::ops::{Add, AddAssign, MulAssign, SubAssign};
  5. use std::rc::Rc;
  6. //use std::collections::HashMap;
  7. use fnv::FnvHashMap;
  8. use itertools::Itertools;
  9. use crate::env::{env_bind, Env};
  10. use crate::types::MalErr::{ErrMalVal, ErrString};
  11. use crate::types::MalVal::{Atom, Bool, Func, Hash, Int, List, MalFunc, Nil, Str, Sym, Vector};
  12. use bellman::Variable;
  13. use bls12_381::Bls12;
  14. use bls12_381::Scalar;
  15. #[derive(Debug, Clone)]
  16. pub struct Allocation {
  17. pub symbol: String,
  18. pub value: Scalar,
  19. }
  20. #[derive(Debug, Clone)]
  21. pub struct EnforceAllocation {
  22. pub left: Vec<(String, String)>,
  23. pub right: Vec<(String, String)>,
  24. pub output: Vec<(String, String)>,
  25. }
  26. pub struct VerifyKeyParams {
  27. pub random_params: groth16::Parameters<Bls12>,
  28. pub verifying_key: groth16::PreparedVerifyingKey<Bls12>,
  29. }
  30. #[derive(Debug, Clone)]
  31. pub struct LispCircuit {
  32. pub params: FnvHashMap<String, MalVal>,
  33. pub allocs: FnvHashMap<String, MalVal>,
  34. pub alloc_inputs: FnvHashMap<String, MalVal>,
  35. // todo change this for a ordered data structure so enforce
  36. pub constraints: Vec<EnforceAllocation>,
  37. }
  38. #[derive(Debug, Clone)]
  39. pub enum MalVal {
  40. Nil,
  41. Bool(bool),
  42. Int(i64),
  43. Str(String),
  44. Sym(String),
  45. List(Rc<Vec<MalVal>>, Rc<MalVal>),
  46. Vector(Rc<Vec<MalVal>>, Rc<MalVal>),
  47. Hash(Rc<FnvHashMap<String, MalVal>>, Rc<MalVal>),
  48. Func(fn(MalArgs) -> MalRet, Rc<MalVal>),
  49. MalFunc {
  50. eval: fn(ast: MalVal, env: Env) -> MalRet,
  51. ast: Rc<MalVal>,
  52. env: Env,
  53. params: Rc<MalVal>,
  54. is_macro: bool,
  55. meta: Rc<MalVal>,
  56. },
  57. Atom(Rc<RefCell<MalVal>>),
  58. Zk(Rc<LispCircuit>), // TODO remote it
  59. Enforce(Rc<Vec<EnforceAllocation>>),
  60. ZKScalar(bls12_381::Scalar),
  61. }
  62. impl Circuit<bls12_381::Scalar> for LispCircuit {
  63. fn synthesize<CS: ConstraintSystem<bls12_381::Scalar>>(
  64. self,
  65. cs: &mut CS,
  66. ) -> Result<(), SynthesisError> {
  67. let mut variables: FnvHashMap<String, Variable> = FnvHashMap::default();
  68. let mut params_const = self.params;
  69. println!("Allocations\n");
  70. for (k, v) in &self.allocs {
  71. println!("k {:?} v {:?}", k, v);
  72. match v {
  73. MalVal::ZKScalar(val) => {
  74. let var = cs.alloc(|| k, || Ok(*val))?;
  75. variables.insert(k.to_string(), var);
  76. }
  77. MalVal::Str(val) => {
  78. let val_scalar = bls12_381::Scalar::from_string(&*val);
  79. let var = cs.alloc(|| k, || Ok(val_scalar))?;
  80. variables.insert(k.to_string(), var);
  81. }
  82. _ => {
  83. println!("not allocated k {:?} v {:?}", k, v);
  84. }
  85. }
  86. }
  87. println!("Allocations Input\n");
  88. for (k, v) in &self.alloc_inputs {
  89. println!("k {:?} v {:?}", k, v);
  90. match v {
  91. MalVal::ZKScalar(val) => {
  92. let var = cs.alloc_input(|| k, || Ok(*val))?;
  93. variables.insert(k.to_string(), var);
  94. }
  95. MalVal::Str(val) => {
  96. let val_scalar = bls12_381::Scalar::from_string(&*val);
  97. let var = cs.alloc_input(|| k, || Ok(val_scalar))?;
  98. variables.insert(k.to_string(), var);
  99. }
  100. _ => {
  101. println!("not allocated k {:?} v {:?}", k, v);
  102. }
  103. }
  104. }
  105. println!("Enforce Allocations\n");
  106. // we need to keep order
  107. for alloc_value in self.constraints.iter() {
  108. let coeff = bls12_381::Scalar::one();
  109. let mut left = bellman::LinearCombination::<Scalar>::zero();
  110. let mut right = bellman::LinearCombination::<Scalar>::zero();
  111. let mut output = bellman::LinearCombination::<Scalar>::zero();
  112. for values in alloc_value.left.iter() {
  113. let (a, b) = values;
  114. let mut val_b = CS::one();
  115. if b != "cs::one" {
  116. val_b = *variables.get(b).unwrap();
  117. }
  118. if a == "scalar::one" {
  119. left = left + (coeff, val_b);
  120. } else if a == "scalar::one::neg" {
  121. left = left + (coeff.neg(), val_b);
  122. } else {
  123. if let Some(value) = params_const.get(a) {
  124. if let MalVal::ZKScalar(val) = value {
  125. left = left + (*val, val_b);
  126. }
  127. }
  128. }
  129. println!("left: a {:?} b {:?} val_b: {:?}", a, b, val_b);
  130. }
  131. for values in alloc_value.right.iter() {
  132. let (a, b) = values;
  133. let mut val_b = CS::one();
  134. if b != "cs::one" {
  135. val_b = *variables.get(b).unwrap();
  136. }
  137. if a == "scalar::one" {
  138. right = right + (coeff, val_b);
  139. } else if a == "scalar::one::neg" {
  140. right = right + (coeff.neg(), val_b);
  141. }
  142. println!("right: a {:?} b {:?} val_b: {:?}", a, b, val_b);
  143. }
  144. for values in alloc_value.output.iter() {
  145. let (a, b) = values;
  146. let mut val_b = CS::one();
  147. if b != "cs::one" {
  148. val_b = *variables.get(b).unwrap();
  149. }
  150. if a == "scalar::one" {
  151. output = output + (coeff, val_b);
  152. } else if a == "scalar::one::neg" {
  153. output = output + (coeff.neg(), val_b);
  154. }
  155. println!("output: a {:?} b {:?} val_b: {:?}", a, b, val_b);
  156. }
  157. println!("Enforcing ...");
  158. cs.enforce(
  159. || "constraint",
  160. |_| left.clone(),
  161. |_| right.clone(),
  162. |_| output.clone(),
  163. );
  164. }
  165. Ok(())
  166. }
  167. }
  168. #[derive(Debug)]
  169. pub enum MalErr {
  170. ErrString(String),
  171. ErrMalVal(MalVal),
  172. }
  173. impl From<SynthesisError> for MalErr {
  174. fn from(err: SynthesisError) -> MalErr {
  175. ErrString(err.to_string())
  176. }
  177. }
  178. pub type MalArgs = Vec<MalVal>;
  179. pub type MalRet = Result<MalVal, MalErr>;
  180. // type utility macros
  181. macro_rules! list {
  182. ($seq:expr) => {{
  183. List(Rc::new($seq),Rc::new(Nil))
  184. }};
  185. [$($args:expr),*] => {{
  186. let v: Vec<MalVal> = vec![$($args),*];
  187. List(Rc::new(v),Rc::new(Nil))
  188. }}
  189. }
  190. macro_rules! vector {
  191. ($seq:expr) => {{
  192. Vector(Rc::new($seq),Rc::new(Nil))
  193. }};
  194. [$($args:expr),*] => {{
  195. let v: Vec<MalVal> = vec![$($args),*];
  196. Vector(Rc::new(v),Rc::new(Nil))
  197. }}
  198. }
  199. // type utility functions
  200. pub fn error(s: &str) -> MalRet {
  201. Err(ErrString(s.to_string()))
  202. }
  203. pub fn format_error(e: MalErr) -> String {
  204. match e {
  205. ErrString(s) => s.clone(),
  206. ErrMalVal(mv) => mv.pr_str(true),
  207. }
  208. }
  209. pub fn atom(mv: &MalVal) -> MalVal {
  210. Atom(Rc::new(RefCell::new(mv.clone())))
  211. }
  212. impl MalVal {
  213. pub fn keyword(&self) -> MalRet {
  214. match self {
  215. Str(s) if s.starts_with("\u{29e}") => Ok(Str(s.to_string())),
  216. Str(s) => Ok(Str(format!("\u{29e}{}", s))),
  217. _ => error("invalid type for keyword"),
  218. }
  219. }
  220. pub fn empty_q(&self) -> MalRet {
  221. match self {
  222. List(l, _) | Vector(l, _) => Ok(Bool(l.len() == 0)),
  223. Nil => Ok(Bool(true)),
  224. _ => error("invalid type for empty?"),
  225. }
  226. }
  227. pub fn count(&self) -> MalRet {
  228. match self {
  229. List(l, _) | Vector(l, _) => Ok(Int(l.len() as i64)),
  230. Nil => Ok(Int(0)),
  231. _ => error("invalid type for count"),
  232. }
  233. }
  234. pub fn apply(&self, args: MalArgs) -> MalRet {
  235. match *self {
  236. Func(f, _) => f(args),
  237. MalFunc {
  238. eval,
  239. ref ast,
  240. ref env,
  241. ref params,
  242. ..
  243. } => {
  244. let a = &**ast;
  245. let p = &**params;
  246. let fn_env = env_bind(Some(env.clone()), p.clone(), args)?;
  247. Ok(eval(a.clone(), fn_env)?)
  248. }
  249. _ => error("attempt to call non-function"),
  250. }
  251. }
  252. pub fn keyword_q(&self) -> bool {
  253. match self {
  254. Str(s) if s.starts_with("\u{29e}") => true,
  255. _ => false,
  256. }
  257. }
  258. pub fn deref(&self) -> MalRet {
  259. match self {
  260. Atom(a) => Ok(a.borrow().clone()),
  261. _ => error("attempt to deref a non-Atom"),
  262. }
  263. }
  264. pub fn reset_bang(&self, new: &MalVal) -> MalRet {
  265. match self {
  266. Atom(a) => {
  267. *a.borrow_mut() = new.clone();
  268. Ok(new.clone())
  269. }
  270. _ => error("attempt to reset! a non-Atom"),
  271. }
  272. }
  273. pub fn swap_bang(&self, args: &MalArgs) -> MalRet {
  274. match self {
  275. Atom(a) => {
  276. let f = &args[0];
  277. let mut fargs = args[1..].to_vec();
  278. fargs.insert(0, a.borrow().clone());
  279. *a.borrow_mut() = f.apply(fargs)?;
  280. Ok(a.borrow().clone())
  281. }
  282. _ => error("attempt to swap! a non-Atom"),
  283. }
  284. }
  285. pub fn get_meta(&self) -> MalRet {
  286. match self {
  287. List(_, meta) | Vector(_, meta) | Hash(_, meta) => Ok((&**meta).clone()),
  288. Func(_, meta) => Ok((&**meta).clone()),
  289. MalFunc { meta, .. } => Ok((&**meta).clone()),
  290. _ => error("meta not supported by type"),
  291. }
  292. }
  293. pub fn with_meta(&mut self, new_meta: &MalVal) -> MalRet {
  294. match self {
  295. List(_, ref mut meta)
  296. | Vector(_, ref mut meta)
  297. | Hash(_, ref mut meta)
  298. | Func(_, ref mut meta)
  299. | MalFunc { ref mut meta, .. } => {
  300. *meta = Rc::new((&*new_meta).clone());
  301. }
  302. _ => return error("with-meta not supported by type"),
  303. };
  304. Ok(self.clone())
  305. }
  306. }
  307. impl PartialEq for MalVal {
  308. fn eq(&self, other: &MalVal) -> bool {
  309. match (self, other) {
  310. (Nil, Nil) => true,
  311. (Bool(ref a), Bool(ref b)) => a == b,
  312. (Int(ref a), Int(ref b)) => a == b,
  313. (Str(ref a), Str(ref b)) => a == b,
  314. (Sym(ref a), Sym(ref b)) => a == b,
  315. (List(ref a, _), List(ref b, _))
  316. | (Vector(ref a, _), Vector(ref b, _))
  317. | (List(ref a, _), Vector(ref b, _))
  318. | (Vector(ref a, _), List(ref b, _)) => a == b,
  319. (Hash(ref a, _), Hash(ref b, _)) => a == b,
  320. (MalFunc { .. }, MalFunc { .. }) => false,
  321. _ => false,
  322. }
  323. }
  324. }
  325. pub fn func(f: fn(MalArgs) -> MalRet) -> MalVal {
  326. Func(f, Rc::new(Nil))
  327. }
  328. pub fn _assoc(mut hm: FnvHashMap<String, MalVal>, kvs: MalArgs) -> MalRet {
  329. if kvs.len() % 2 != 0 {
  330. return error("odd number of elements");
  331. }
  332. for (k, v) in kvs.iter().tuples() {
  333. match k {
  334. Str(s) => {
  335. hm.insert(s.to_string(), v.clone());
  336. }
  337. _ => return error("key is not string"),
  338. }
  339. }
  340. Ok(Hash(Rc::new(hm), Rc::new(Nil)))
  341. }
  342. pub fn _dissoc(mut hm: FnvHashMap<String, MalVal>, ks: MalArgs) -> MalRet {
  343. for k in ks.iter() {
  344. match k {
  345. Str(ref s) => {
  346. hm.remove(s);
  347. }
  348. _ => return error("key is not string"),
  349. }
  350. }
  351. Ok(Hash(Rc::new(hm), Rc::new(Nil)))
  352. }
  353. pub fn hash_map(kvs: MalArgs) -> MalRet {
  354. let hm: FnvHashMap<String, MalVal> = FnvHashMap::default();
  355. _assoc(hm, kvs)
  356. }