lisp.rs 32 KB

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