lisp.rs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  1. #![allow(non_snake_case)]
  2. use crate::types::LispCircuit;
  3. use bellman::groth16::PreparedVerifyingKey;
  4. use sapvi::{BlsStringConversion, Decodable, Encodable, ZKContract, ZKProof};
  5. use simplelog::*;
  6. use bellman::groth16;
  7. use bls12_381::Bls12;
  8. // use fnv::FnvHashMap;
  9. use itertools::Itertools;
  10. use rand::rngs::OsRng;
  11. use std::{collections::HashMap, cell::RefCell};
  12. use std::rc::Rc;
  13. use std::time::Instant;
  14. use std::{
  15. borrow::{Borrow, BorrowMut},
  16. fs,
  17. };
  18. use types::EnforceAllocation;
  19. #[macro_use]
  20. extern crate clap;
  21. #[macro_use]
  22. extern crate lazy_static;
  23. // extern crate fnv;
  24. extern crate itertools;
  25. extern crate regex;
  26. #[macro_use]
  27. mod types;
  28. use crate::types::MalErr::{ErrMalVal, ErrString};
  29. use crate::types::MalVal::{Bool, Enforce, Func, Hash, List, MalFunc, Nil, Str, Sym, Vector, Alloc};
  30. use crate::types::VerifyKeyParams;
  31. use crate::types::{error, format_error, MalArgs, MalErr, MalRet, MalVal};
  32. mod env;
  33. mod printer;
  34. mod reader;
  35. use crate::env::{env_bind, env_find, env_get, env_new, env_set, env_sets, Env};
  36. #[macro_use]
  37. mod core;
  38. // read
  39. fn read(str: &str) -> MalRet {
  40. reader::read_str(str.to_string())
  41. }
  42. // eval
  43. fn qq_iter(elts: &MalArgs) -> MalVal {
  44. let mut acc = list![];
  45. for elt in elts.iter().rev() {
  46. if let List(v, _) = elt {
  47. if v.len() == 2 {
  48. if let Sym(ref s) = v[0] {
  49. if s == "splice-unquote" {
  50. acc = list![Sym("concat".to_string()), v[1].clone(), acc];
  51. continue;
  52. }
  53. }
  54. }
  55. }
  56. acc = list![Sym("cons".to_string()), quasiquote(&elt), acc];
  57. }
  58. return acc;
  59. }
  60. fn quasiquote(ast: &MalVal) -> MalVal {
  61. match ast {
  62. List(v, _) => {
  63. if v.len() == 2 {
  64. if let Sym(ref s) = v[0] {
  65. if s == "unquote" {
  66. return v[1].clone();
  67. }
  68. }
  69. }
  70. return qq_iter(&v);
  71. }
  72. Vector(v, _) => return list![Sym("vec".to_string()), qq_iter(&v)],
  73. Hash(_, _) | Sym(_) => return list![Sym("quote".to_string()), ast.clone()],
  74. _ => ast.clone(),
  75. }
  76. }
  77. fn is_macro_call(ast: &MalVal, env: &Env) -> Option<(MalVal, MalArgs)> {
  78. match ast {
  79. List(v, _) => match v[0] {
  80. Sym(ref s) => match env_find(env, s) {
  81. Some(e) => match env_get(&e, &v[0]) {
  82. Ok(f @ MalFunc { is_macro: true, .. }) => Some((f, v[1..].to_vec())),
  83. _ => None,
  84. },
  85. _ => None,
  86. },
  87. _ => None,
  88. },
  89. _ => None,
  90. }
  91. }
  92. fn macroexpand(mut ast: MalVal, env: &Env) -> (bool, MalRet) {
  93. let mut was_expanded = false;
  94. while let Some((mf, args)) = is_macro_call(&ast, env) {
  95. // println!("macroexpand 1: {:?}", ast);
  96. ast = match mf.apply(args) {
  97. Err(e) => return (false, Err(e)),
  98. Ok(a) => a,
  99. };
  100. // println!("macroexpand 2: {:?}", ast);
  101. was_expanded = true;
  102. }
  103. (was_expanded, Ok(ast))
  104. }
  105. fn eval_ast(ast: &MalVal, env: &Env) -> MalRet {
  106. match ast {
  107. Sym(_) => Ok(env_get(&env, &ast)?),
  108. List(v, _) => {
  109. let mut lst: MalArgs = vec![];
  110. for a in v.iter() {
  111. lst.push(eval(a.clone(), env.clone())?)
  112. }
  113. Ok(list!(lst))
  114. }
  115. Vector(v, _) => {
  116. let mut lst: MalArgs = vec![];
  117. for a in v.iter() {
  118. lst.push(eval(a.clone(), env.clone())?)
  119. }
  120. Ok(vector!(lst))
  121. }
  122. Hash(hm, _) => {
  123. let mut new_hm: HashMap<String, MalVal> = HashMap::default();
  124. for (k, v) in hm.iter() {
  125. new_hm.insert(k.to_string(), eval(v.clone(), env.clone())?);
  126. }
  127. Ok(Hash(Rc::new(new_hm), Rc::new(Nil)))
  128. }
  129. _ => Ok(ast.clone()),
  130. }
  131. }
  132. fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
  133. let ret: MalRet;
  134. 'tco: loop {
  135. ret = match ast.clone() {
  136. List(l, _) => {
  137. if l.len() == 0 {
  138. return Ok(ast);
  139. }
  140. match macroexpand(ast.clone(), &env) {
  141. (true, Ok(new_ast)) => {
  142. ast = new_ast;
  143. continue 'tco;
  144. }
  145. (_, Err(e)) => return Err(e),
  146. _ => (),
  147. }
  148. if l.len() == 0 {
  149. return Ok(ast);
  150. }
  151. let a0 = &l[0];
  152. match a0 {
  153. Sym(ref a0sym) if a0sym == "def!" => {
  154. env_set(&env, l[1].clone(), eval(l[2].clone(), env.clone())?)
  155. }
  156. Sym(ref a0sym) if a0sym == "zk*" => {
  157. // println!("zk* {:?}", l[1]);
  158. let (a1, a2) = (l[1].clone(), l[2].clone());
  159. match a1 {
  160. List(ref binds, _) | Vector(ref binds, _) => {
  161. for (b, e) in binds.iter().tuples() {
  162. match b {
  163. Sym(_) => {
  164. let _ = env_set(
  165. &env,
  166. b.clone(),
  167. eval(e.clone(), env.clone())?,
  168. );
  169. }
  170. _ => {
  171. return error("let* with non-Sym binding");
  172. }
  173. }
  174. }
  175. }
  176. _ => {
  177. return error("let* with non-List bindings");
  178. }
  179. };
  180. ast = a2;
  181. continue 'tco;
  182. }
  183. Sym(ref a0sym) if a0sym == "let*" => {
  184. env = env_new(Some(env.clone()));
  185. let (a1, a2) = (l[1].clone(), l[2].clone());
  186. match a1 {
  187. List(ref binds, _) | Vector(ref binds, _) => {
  188. for (b, e) in binds.iter().tuples() {
  189. match b {
  190. Sym(_) => {
  191. let _ = env_set(
  192. &env,
  193. b.clone(),
  194. eval(e.clone(), env.clone())?,
  195. );
  196. }
  197. _ => {
  198. return error("let* with non-Sym binding");
  199. }
  200. }
  201. }
  202. }
  203. _ => {
  204. return error("let* with non-List bindings");
  205. }
  206. };
  207. ast = a2;
  208. continue 'tco;
  209. }
  210. Sym(ref a0sym) if a0sym == "quote" => Ok(l[1].clone()),
  211. Sym(ref a0sym) if a0sym == "quasiquoteexpand" => Ok(quasiquote(&l[1])),
  212. Sym(ref a0sym) if a0sym == "quasiquote" => {
  213. ast = quasiquote(&l[1]);
  214. continue 'tco;
  215. }
  216. Sym(ref a0sym) if a0sym == "defmacro!" => {
  217. let (a1, a2) = (l[1].clone(), l[2].clone());
  218. let r = eval(a2, env.clone())?;
  219. match r {
  220. MalFunc {
  221. eval,
  222. ast,
  223. env,
  224. params,
  225. ..
  226. } => Ok(env_set(
  227. &env,
  228. a1.clone(),
  229. MalFunc {
  230. eval: eval,
  231. ast: ast.clone(),
  232. env: env.clone(),
  233. params: params.clone(),
  234. is_macro: true,
  235. meta: Rc::new(Nil),
  236. },
  237. )?),
  238. _ => error("set_macro on non-function"),
  239. }
  240. }
  241. Sym(ref a0sym) if a0sym == "macroexpand" => {
  242. match macroexpand(l[1].clone(), &env) {
  243. (_, Ok(new_ast)) => Ok(new_ast),
  244. (_, e) => return e,
  245. }
  246. }
  247. Sym(ref a0sym) if a0sym == "try*" => match eval(l[1].clone(), env.clone()) {
  248. Err(ref e) if l.len() >= 3 => {
  249. let exc = match e {
  250. ErrMalVal(mv) => mv.clone(),
  251. ErrString(s) => Str(s.to_string()),
  252. };
  253. match l[2].clone() {
  254. List(c, _) => {
  255. let catch_env = env_bind(
  256. Some(env.clone()),
  257. list!(vec![c[1].clone()]),
  258. vec![exc],
  259. )?;
  260. eval(c[2].clone(), catch_env)
  261. }
  262. _ => error("invalid catch block"),
  263. }
  264. }
  265. res => res,
  266. },
  267. Sym(ref a0sym) if a0sym == "do" => {
  268. match eval_ast(&list!(l[1..l.len() - 1].to_vec()), &env)? {
  269. List(_, _) => {
  270. ast = l.last().unwrap_or(&Nil).clone();
  271. continue 'tco;
  272. }
  273. _ => error("invalid do form"),
  274. }
  275. }
  276. Sym(ref a0sym) if a0sym == "dotimes" => {
  277. match eval(l[1].clone(), env.clone())? {
  278. MalVal::Int(v) => {
  279. for _i in 0..v {
  280. eval(l[2].clone(), env.clone())?;
  281. }
  282. Ok(Nil)
  283. }
  284. _ => error("invalid args for dotimes"),
  285. }
  286. }
  287. Sym(ref a0sym) if a0sym == "if" => {
  288. let cond = eval(l[1].clone(), env.clone())?;
  289. match cond {
  290. Bool(false) | Nil if l.len() >= 4 => {
  291. ast = l[3].clone();
  292. continue 'tco;
  293. }
  294. Bool(false) | Nil => Ok(Nil),
  295. _ if l.len() >= 3 => {
  296. ast = l[2].clone();
  297. continue 'tco;
  298. }
  299. _ => Ok(Nil),
  300. }
  301. }
  302. Sym(ref a0sym) if a0sym == "fn*" => {
  303. let (a1, a2) = (l[1].clone(), l[2].clone());
  304. Ok(MalFunc {
  305. eval: eval,
  306. ast: Rc::new(a2),
  307. env: env,
  308. params: Rc::new(a1),
  309. is_macro: false,
  310. meta: Rc::new(Nil),
  311. })
  312. }
  313. Sym(ref a0sym) if a0sym == "eval" => {
  314. ast = eval(l[1].clone(), env.clone())?;
  315. while let Some(ref e) = env.clone().outer {
  316. env = e.clone();
  317. }
  318. continue 'tco;
  319. }
  320. Sym(ref a0sym) if a0sym == "setup" => {
  321. let a1 = l[1].clone();
  322. // todo
  323. ast = eval(a1.clone(), env.clone())?;
  324. // let _pvk = setup(a1.clone(), env.clone())?;
  325. continue 'tco;
  326. }
  327. Sym(ref a0sym) if a0sym == "prove" => {
  328. let a1 = l[1].clone();
  329. eval(a1.clone(), env.clone())?;
  330. prove(a1.clone(), env.clone())
  331. }
  332. Sym(ref a0sym) if a0sym == "alloc-const" => {
  333. // let start = Instant::now();
  334. let a1 = l[1].clone();
  335. let value = eval(l[2].clone(), env.clone())?;
  336. let result = eval(value.clone(), env.clone())?;
  337. let allocs = get_allocations(&env, "AllocationsConst");
  338. allocs.borrow_mut().insert(a1.pr_str(false), result.clone());
  339. // let mut new_hm: HashMap<String, MalVal> = HashMap::default();
  340. // for (k, v) in allocs.borrow_mut().iter() {
  341. // new_hm.insert(k.to_string(), eval(v.clone(), env.clone())?);
  342. // }
  343. // new_hm.insert(a1.pr_str(false), result.clone());
  344. if let Some(e) = &env.outer {
  345. env_set(
  346. &e,
  347. Sym("AllocationsConst".to_string()),
  348. Alloc(allocs),
  349. )?;
  350. } else {
  351. env_set(
  352. &env,
  353. Sym("AllocationsConst".to_string()),
  354. Alloc(allocs),
  355. )?;
  356. }
  357. // println!("Alloc Const: {:?}", start.elapsed());
  358. Ok(result.clone())
  359. }
  360. Sym(ref a0sym) if a0sym == "alloc-input" => {
  361. // let start = Instant::now();
  362. let a1 = l[1].clone();
  363. let value = eval(l[2].clone(), env.clone())?;
  364. let result = eval(value.clone(), env.clone())?;
  365. let allocs = get_allocations(&env, "AllocationsInput");
  366. allocs.borrow_mut().insert(a1.pr_str(false), result.clone());
  367. // let mut new_hm: HashMap<String, MalVal> = HashMap::default();
  368. // for (k, v) in allocs.borrow_mut().iter() {
  369. // new_hm.insert(k.to_string(), eval(v.clone(), env.clone())?);
  370. // }
  371. // new_hm.insert(a1.pr_str(false), result.clone());
  372. if let Some(e) = &env.outer {
  373. env_set(
  374. &e,
  375. Sym("AllocationsInput".to_string()),
  376. Alloc(allocs),
  377. )?;
  378. } else {
  379. env_set(
  380. &env,
  381. Sym("AllocationsInput".to_string()),
  382. Alloc(allocs),
  383. )?;
  384. }
  385. // println!("Alloc Input: {:?}", start.elapsed());
  386. Ok(result.clone())
  387. }
  388. Sym(ref a0sym) if a0sym == "alloc" => {
  389. // let start = Instant::now();
  390. let a1 = l[1].clone();
  391. let mut value = eval(l[2].clone(), env.clone())?;
  392. if let Func(_, _) = value {
  393. value = value.apply(vec![]).unwrap();
  394. }
  395. let result = eval(value.clone(), env.clone())?;
  396. let allocs = get_allocations(&env, "Allocations");
  397. allocs.borrow_mut().insert(a1.pr_str(false), result.clone());
  398. // let mut new_hm: HashMap<String, MalVal> = HashMap::default();
  399. // for (k, v) in allocs.borrow_mut().iter() {
  400. // new_hm.insert(k.to_string(), eval(v.clone(), env.clone())?);
  401. // }
  402. // new_hm.insert(a1.pr_str(false), result.clone());
  403. if let Some(e) = &env.outer {
  404. env_set(
  405. &e,
  406. Sym("Allocations".to_string()),
  407. Alloc(allocs),
  408. )?;
  409. } else {
  410. env_set(
  411. &env,
  412. Sym("Allocations".to_string()),
  413. Alloc(allocs),
  414. )?;
  415. }
  416. // println!("Alloc: {:?}", start.elapsed());
  417. Ok(result.clone())
  418. }
  419. //Sym(ref a0sym) if a0sym == "verify" => {
  420. Sym(ref a0sym) if a0sym == "enforce" => {
  421. // here i'm considering that we always have tuple with only two elements
  422. // also it's important to keep in mind for the sake of brevity of this v0
  423. // we will not allow calculation or any lisp evaluations inside the enforce
  424. // it means that every symbol will be on allocations and we will do the
  425. // find/replace on the bellman circuit, it's nasty v0
  426. let mut left_vec = vec![];
  427. let mut right_vec = vec![];
  428. let mut out_vec = vec![];
  429. // todo extract a macro for this
  430. match l[1].clone() {
  431. List(v, _) | Vector(v, _) => {
  432. if let List(_, _) = &v.to_vec()[0] {
  433. for ele in v.to_vec().iter() {
  434. if let List(ele_vec, _) = ele {
  435. left_vec.push((
  436. ele_vec[0].pr_str(false),
  437. ele_vec[1].pr_str(false),
  438. ));
  439. }
  440. }
  441. } else {
  442. left_vec.push((v[0].pr_str(false), v[1].pr_str(false)));
  443. }
  444. }
  445. _ => {}
  446. };
  447. match l[2].clone() {
  448. List(v, _) | Vector(v, _) => {
  449. if let List(_, _) = &v.to_vec()[0] {
  450. for ele in v.to_vec().iter() {
  451. if let List(ele_vec, _) = ele {
  452. right_vec.push((
  453. ele_vec[0].pr_str(false),
  454. ele_vec[1].pr_str(false),
  455. ));
  456. }
  457. }
  458. } else {
  459. right_vec.push((v[0].pr_str(false), v[1].pr_str(false)));
  460. }
  461. }
  462. _ => {}
  463. };
  464. match l[3].clone() {
  465. List(v, _) | Vector(v, _) => {
  466. if let List(_, _) = &v.to_vec()[0] {
  467. for ele in v.to_vec().iter() {
  468. if let List(ele_vec, _) = ele {
  469. out_vec.push((
  470. ele_vec[0].pr_str(false),
  471. ele_vec[1].pr_str(false),
  472. ));
  473. }
  474. }
  475. } else {
  476. out_vec.push((v[0].pr_str(false), v[1].pr_str(false)));
  477. }
  478. }
  479. _ => {}
  480. };
  481. let mut enforce_vec = get_enforce_allocs(&env).clone();
  482. let enforce = EnforceAllocation {
  483. idx: enforce_vec.len() + 1,
  484. left: left_vec,
  485. right: right_vec,
  486. output: out_vec,
  487. };
  488. enforce_vec.push(enforce);
  489. // let mut new_vec: Vec<EnforceAllocation> = vec![enforce];
  490. // for value in enforce_vec.iter() {
  491. // new_vec.push(value.clone());
  492. // }
  493. if let Some(e) = &env.outer {
  494. env_set(
  495. &e,
  496. Sym("AllocationsEnforce".to_string()),
  497. vector![vec![Enforce(Rc::new(enforce_vec))]],
  498. )?;
  499. } else {
  500. env_set(
  501. &env,
  502. Sym("AllocationsEnforce".to_string()),
  503. vector![vec![Enforce(Rc::new(enforce_vec))]],
  504. )?;
  505. }
  506. // println!(
  507. // "allocs here {:?}",
  508. // get_allocations_nested(&env, "Allocations")
  509. // );
  510. // println!("enforce here {:?}", get_enforce_allocs_nested(&env));
  511. Ok(MalVal::Str("enforce-eof".to_string()))
  512. }
  513. _ => match eval_ast(&ast, &env)? {
  514. List(ref el, _) => {
  515. let ref f = el[0].clone();
  516. let args = el[1..].to_vec();
  517. match f {
  518. Func(_, _) => f.apply(args),
  519. MalFunc {
  520. ast: mast,
  521. env: menv,
  522. params,
  523. ..
  524. } => {
  525. let a = &**mast;
  526. let p = &**params;
  527. env = env_bind(Some(menv.clone()), p.clone(), args)?;
  528. ast = a.clone();
  529. continue 'tco;
  530. }
  531. _ => {
  532. // println!("{:?}", args);
  533. Ok(vector![el.to_vec()])
  534. //error("call non-function")
  535. }
  536. }
  537. }
  538. _ => error("expected a list"),
  539. },
  540. }
  541. }
  542. _ => eval_ast(&ast, &env),
  543. };
  544. break;
  545. } // end 'tco loop
  546. ret
  547. }
  548. pub fn get_enforce_allocs(env: &Env) -> Vec<EnforceAllocation> {
  549. if let Some(e) = &env.outer {
  550. get_enforce_allocs_nested(&e)
  551. } else {
  552. get_enforce_allocs_nested(&env)
  553. }
  554. }
  555. pub fn get_enforce_allocs_nested(env: &Env) -> Vec<EnforceAllocation> {
  556. match env_find(env, "AllocationsEnforce") {
  557. Some(e) => match env_get(&e, &Sym("AllocationsEnforce".to_string())) {
  558. Ok(f) => {
  559. if let Vector(val, _) = f {
  560. if let Enforce(ret) = &val[0] {
  561. ret.to_vec()
  562. } else {
  563. vec![]
  564. }
  565. } else {
  566. vec![]
  567. }
  568. }
  569. _ => vec![],
  570. },
  571. _ => vec![],
  572. }
  573. }
  574. pub fn get_allocations(env: &Env, key: &str) -> RefCell<HashMap<String, MalVal>> {
  575. if let Some(e) = &env.outer {
  576. get_allocations_nested(&e, key)
  577. } else {
  578. get_allocations_nested(&env, key)
  579. }
  580. }
  581. pub fn get_allocations_nested(env: &Env, key: &str) -> RefCell<HashMap<String, MalVal>> {
  582. let alloc_hm: RefCell<HashMap<String, MalVal>> = RefCell::new(HashMap::default());
  583. match env_find(env, key) {
  584. Some(e) => match env_get(&e, &Sym(key.to_string())) {
  585. Ok(f) => {
  586. if let MalVal::Alloc(allocs) = f {
  587. allocs
  588. } else {
  589. alloc_hm
  590. }
  591. }
  592. _ => alloc_hm,
  593. },
  594. _ => alloc_hm,
  595. }
  596. }
  597. pub fn setup(_ast: MalVal, env: Env) -> Result<VerifyKeyParams, MalErr> {
  598. let start = Instant::now();
  599. let c = LispCircuit {
  600. params: HashMap::default(),
  601. allocs: HashMap::default(),
  602. alloc_inputs: HashMap::default(),
  603. constraints: Vec::new(),
  604. };
  605. let random_parameters =
  606. groth16::generate_random_parameters::<Bls12, _, _>(c, &mut OsRng).unwrap();
  607. let pvk = groth16::prepare_verifying_key(&random_parameters.vk);
  608. println!("Setup: [{:?}]", start.elapsed());
  609. Ok(VerifyKeyParams {
  610. verifying_key: pvk,
  611. random_params: random_parameters,
  612. })
  613. }
  614. pub fn prove(_ast: MalVal, env: Env) -> MalRet {
  615. let start = Instant::now();
  616. let allocs_input = get_allocations(&env, "AllocationsInput");
  617. let allocs = get_allocations(&env, "Allocations");
  618. let enforce_allocs = get_enforce_allocs(&env);
  619. let allocs_const = get_allocations(&env, "AllocationsConst");
  620. //setup
  621. let params = Some({
  622. let circuit = LispCircuit {
  623. params: allocs_const.borrow().clone(),
  624. allocs: allocs.borrow().clone(),
  625. alloc_inputs: allocs_input.borrow().clone(),
  626. constraints: enforce_allocs.clone(),
  627. };
  628. groth16::generate_random_parameters::<Bls12, _, _>(circuit, &mut OsRng)?
  629. });
  630. let verifying_key = Some(groth16::prepare_verifying_key(&params.as_ref().unwrap().vk));
  631. // prove
  632. let circuit = LispCircuit {
  633. params: allocs_const.borrow().clone(),
  634. allocs: allocs.borrow().clone(),
  635. alloc_inputs: allocs_input.borrow().clone(),
  636. constraints: enforce_allocs.clone(),
  637. };
  638. let proof = groth16::create_random_proof(circuit, params.as_ref().unwrap(), &mut OsRng)?;
  639. let mut vec_input = vec![];
  640. for (k, val) in allocs_input.borrow_mut().iter() {
  641. match val {
  642. MalVal::Str(v) => {
  643. vec_input.push(bls12_381::Scalar::from_string(&v.to_string()));
  644. }
  645. MalVal::ZKScalar(v) => {
  646. vec_input.push(bls12_381::Scalar::from(*v));
  647. }
  648. _ => {}
  649. };
  650. }
  651. let result = groth16::verify_proof(verifying_key.as_ref().unwrap(), &proof, &vec_input);
  652. println!("vec public {:?}", vec_input);
  653. println!("result {:?}", result);
  654. println!("Elapsed time: {:?}", start.elapsed());
  655. Ok(MalVal::Nil)
  656. }
  657. pub fn verify(_ast: &MalVal) -> MalRet {
  658. let _public_input = vec![bls12_381::Scalar::from(27)];
  659. let start = Instant::now();
  660. println!("Verify: [{:?}]", start.elapsed());
  661. Ok(MalVal::Nil)
  662. }
  663. // print
  664. fn print(ast: &MalVal) -> String {
  665. ast.pr_str(true)
  666. }
  667. fn rep(str: &str, env: &Env) -> Result<String, MalErr> {
  668. let ast = read(str)?;
  669. let exp = eval(ast, env.clone())?;
  670. Ok(print(&exp))
  671. }
  672. fn main() -> Result<(), ()> {
  673. let matches = clap_app!(zklisp =>
  674. (version: "0.1.0")
  675. (author: "Dark Renaissance")
  676. (about: "A Lisp Interpreter for Zero Knowledge Virtual Machine")
  677. (@subcommand load =>
  678. (about: "Load the file into the interpreter")
  679. (@arg FILE: +required "Lisp Contract filename")
  680. )
  681. )
  682. .get_matches();
  683. // CombinedLogger::init(vec![TermLogger::new(
  684. // LevelFilter::Debug,
  685. // Config::default(),
  686. // TerminalMode::Mixed,
  687. // )
  688. // .unwrap()])
  689. // .unwrap();
  690. match matches.subcommand() {
  691. Some(("load", matches)) => {
  692. let file: String = matches.value_of("FILE").unwrap().parse().unwrap();
  693. repl_load(file)?;
  694. }
  695. _ => {
  696. eprintln!("error: Invalid subcommand invoked");
  697. std::process::exit(-1);
  698. }
  699. }
  700. Ok(())
  701. }
  702. fn repl_load(file: String) -> Result<(), ()> {
  703. let repl_env = env_new(None);
  704. for (k, v) in core::ns() {
  705. env_sets(&repl_env, k, v);
  706. }
  707. let _ = rep("(def! not (fn* (a) (if a false true)))", &repl_env);
  708. let _ = rep(
  709. "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \"\nnil)\")))))",
  710. &repl_env,
  711. );
  712. match rep(&format!("(load-file \"{}\")", file), &repl_env) {
  713. Ok(_) => std::process::exit(0),
  714. Err(e) => {
  715. println!("Error: {}", format_error(e));
  716. std::process::exit(1);
  717. }
  718. }
  719. }