lisp.rs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. #![allow(non_snake_case)]
  2. use crate::groth16::VerifyingKey;
  3. use crate::types::LispCircuit;
  4. use sapvi::ZKVMCircuit;
  5. use sapvi::bls_extensions::BlsStringConversion;
  6. use simplelog::*;
  7. use bellman::{
  8. gadgets::{
  9. Assignment,
  10. },
  11. groth16, Circuit, ConstraintSystem, SynthesisError,
  12. };
  13. use bls12_381::Bls12;
  14. use bls12_381::Scalar;
  15. use ff::{Field, PrimeField};
  16. use rand::rngs::OsRng;
  17. use std::ops::{AddAssign, MulAssign, SubAssign};
  18. use std::time::Instant;
  19. use std::rc::Rc;
  20. //use std::collections::HashMap;
  21. use fnv::FnvHashMap;
  22. use itertools::Itertools;
  23. #[macro_use]
  24. extern crate clap;
  25. #[macro_use]
  26. extern crate lazy_static;
  27. extern crate fnv;
  28. extern crate itertools;
  29. extern crate regex;
  30. #[macro_use]
  31. mod types;
  32. use crate::types::MalErr::{ErrMalVal, ErrString};
  33. use crate::types::MalVal::{
  34. Bool, Func, Hash, List, MalFunc, Nil, Str,
  35. Sym, Vector,
  36. };
  37. use crate::types::{error, format_error, MalArgs, MalErr, MalRet, MalVal};
  38. mod env;
  39. mod printer;
  40. mod reader;
  41. use crate::env::{env_bind, env_find, env_get, env_new, env_set, env_sets, Env};
  42. #[macro_use]
  43. mod core;
  44. // read
  45. fn read(str: &str) -> MalRet {
  46. reader::read_str(str.to_string())
  47. }
  48. // eval
  49. fn qq_iter(elts: &MalArgs) -> MalVal {
  50. let mut acc = list![];
  51. for elt in elts.iter().rev() {
  52. if let List(v, _) = elt {
  53. if v.len() == 2 {
  54. if let Sym(ref s) = v[0] {
  55. if s == "splice-unquote" {
  56. acc = list![Sym("concat".to_string()), v[1].clone(), acc];
  57. continue;
  58. }
  59. }
  60. }
  61. }
  62. acc = list![Sym("cons".to_string()), quasiquote(&elt), acc];
  63. }
  64. return acc;
  65. }
  66. fn quasiquote(ast: &MalVal) -> MalVal {
  67. match ast {
  68. List(v, _) => {
  69. if v.len() == 2 {
  70. if let Sym(ref s) = v[0] {
  71. if s == "unquote" {
  72. return v[1].clone();
  73. }
  74. }
  75. }
  76. return qq_iter(&v);
  77. }
  78. Vector(v, _) => return list![Sym("vec".to_string()), qq_iter(&v)],
  79. Hash(_, _) | Sym(_) => return list![Sym("quote".to_string()), ast.clone()],
  80. _ => ast.clone(),
  81. }
  82. }
  83. fn is_macro_call(ast: &MalVal, env: &Env) -> Option<(MalVal, MalArgs)> {
  84. match ast {
  85. List(v, _) => match v[0] {
  86. Sym(ref s) => match env_find(env, s) {
  87. Some(e) => match env_get(&e, &v[0]) {
  88. Ok(f @ MalFunc { is_macro: true, .. }) => Some((f, v[1..].to_vec())),
  89. _ => None,
  90. },
  91. _ => None,
  92. },
  93. _ => None,
  94. },
  95. _ => None,
  96. }
  97. }
  98. fn macroexpand(mut ast: MalVal, env: &Env) -> (bool, MalRet) {
  99. let mut was_expanded = false;
  100. while let Some((mf, args)) = is_macro_call(&ast, env) {
  101. //println!("macroexpand 1: {:?}", ast);
  102. ast = match mf.apply(args) {
  103. Err(e) => return (false, Err(e)),
  104. Ok(a) => a,
  105. };
  106. //println!("macroexpand 2: {:?}", ast);
  107. was_expanded = true;
  108. }
  109. (was_expanded, Ok(ast))
  110. }
  111. fn eval_ast(ast: &MalVal, env: &Env) -> MalRet {
  112. match ast {
  113. Sym(_) => Ok(env_get(&env, &ast)?),
  114. List(v, _) => {
  115. let mut lst: MalArgs = vec![];
  116. for a in v.iter() {
  117. lst.push(eval(a.clone(), env.clone())?)
  118. }
  119. Ok(list!(lst))
  120. }
  121. Vector(v, _) => {
  122. let mut lst: MalArgs = vec![];
  123. for a in v.iter() {
  124. lst.push(eval(a.clone(), env.clone())?)
  125. }
  126. Ok(vector!(lst))
  127. }
  128. Hash(hm, _) => {
  129. let mut new_hm: FnvHashMap<String, MalVal> = FnvHashMap::default();
  130. for (k, v) in hm.iter() {
  131. new_hm.insert(k.to_string(), eval(v.clone(), env.clone())?);
  132. }
  133. Ok(Hash(Rc::new(new_hm), Rc::new(Nil)))
  134. }
  135. _ => Ok(ast.clone()),
  136. }
  137. }
  138. fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
  139. let ret: MalRet;
  140. 'tco: loop {
  141. ret = match ast.clone() {
  142. List(l, _) => {
  143. if l.len() == 0 {
  144. return Ok(ast);
  145. }
  146. match macroexpand(ast.clone(), &env) {
  147. (true, Ok(new_ast)) => {
  148. ast = new_ast;
  149. continue 'tco;
  150. }
  151. (_, Err(e)) => return Err(e),
  152. _ => (),
  153. }
  154. if l.len() == 0 {
  155. return Ok(ast);
  156. }
  157. let a0 = &l[0];
  158. match a0 {
  159. Sym(ref a0sym) if a0sym == "def!" => {
  160. env_set(&env, l[1].clone(), eval(l[2].clone(), env.clone())?)
  161. }
  162. Sym(ref a0sym) if a0sym == "let*" => {
  163. env = env_new(Some(env.clone()));
  164. let (a1, a2) = (l[1].clone(), l[2].clone());
  165. match a1 {
  166. List(ref binds, _) | Vector(ref binds, _) => {
  167. for (b, e) in binds.iter().tuples() {
  168. match b {
  169. Sym(_) => {
  170. let _ = env_set(
  171. &env,
  172. b.clone(),
  173. eval(e.clone(), env.clone())?,
  174. );
  175. }
  176. _ => {
  177. return error("let* with non-Sym binding");
  178. }
  179. }
  180. }
  181. }
  182. _ => {
  183. return error("let* with non-List bindings");
  184. }
  185. };
  186. ast = a2;
  187. continue 'tco;
  188. }
  189. Sym(ref a0sym) if a0sym == "quote" => Ok(l[1].clone()),
  190. Sym(ref a0sym) if a0sym == "quasiquoteexpand" => Ok(quasiquote(&l[1])),
  191. Sym(ref a0sym) if a0sym == "quasiquote" => {
  192. ast = quasiquote(&l[1]);
  193. continue 'tco;
  194. }
  195. Sym(ref a0sym) if a0sym == "defmacro!" => {
  196. let (a1, a2) = (l[1].clone(), l[2].clone());
  197. let r = eval(a2, env.clone())?;
  198. match r {
  199. MalFunc {
  200. eval,
  201. ast,
  202. env,
  203. params,
  204. ..
  205. } => Ok(env_set(
  206. &env,
  207. a1.clone(),
  208. MalFunc {
  209. eval: eval,
  210. ast: ast.clone(),
  211. env: env.clone(),
  212. params: params.clone(),
  213. is_macro: true,
  214. meta: Rc::new(Nil),
  215. },
  216. )?),
  217. _ => error("set_macro on non-function"),
  218. }
  219. }
  220. Sym(ref a0sym) if a0sym == "macroexpand" => {
  221. match macroexpand(l[1].clone(), &env) {
  222. (_, Ok(new_ast)) => Ok(new_ast),
  223. (_, e) => return e,
  224. }
  225. }
  226. Sym(ref a0sym) if a0sym == "try*" => match eval(l[1].clone(), env.clone()) {
  227. Err(ref e) if l.len() >= 3 => {
  228. let exc = match e {
  229. ErrMalVal(mv) => mv.clone(),
  230. ErrString(s) => Str(s.to_string()),
  231. };
  232. match l[2].clone() {
  233. List(c, _) => {
  234. let catch_env = env_bind(
  235. Some(env.clone()),
  236. list!(vec![c[1].clone()]),
  237. vec![exc],
  238. )?;
  239. eval(c[2].clone(), catch_env)
  240. }
  241. _ => error("invalid catch block"),
  242. }
  243. }
  244. res => res,
  245. },
  246. Sym(ref a0sym) if a0sym == "do" => {
  247. match eval_ast(&list!(l[1..l.len() - 1].to_vec()), &env)? {
  248. List(_, _) => {
  249. ast = l.last().unwrap_or(&Nil).clone();
  250. continue 'tco;
  251. }
  252. _ => error("invalid do form"),
  253. }
  254. }
  255. Sym(ref a0sym) if a0sym == "if" => {
  256. let cond = eval(l[1].clone(), env.clone())?;
  257. match cond {
  258. Bool(false) | Nil if l.len() >= 4 => {
  259. ast = l[3].clone();
  260. continue 'tco;
  261. }
  262. Bool(false) | Nil => Ok(Nil),
  263. _ if l.len() >= 3 => {
  264. ast = l[2].clone();
  265. continue 'tco;
  266. }
  267. _ => Ok(Nil),
  268. }
  269. }
  270. Sym(ref a0sym) if a0sym == "setup" => {
  271. let a1 = l[1].clone();
  272. eval(a1.clone(), env.clone())
  273. }
  274. //Sym(ref a0sym) if a0sym == "prove" => {
  275. //Sym(ref a0sym) if a0sym == "verify" => {
  276. Sym(ref a0sym) if a0sym == "enforce" => {
  277. let (a1, a2) = (l[1].clone(), l[2].clone());
  278. let value = eval_ast(&a2, &env)?;
  279. match value {
  280. List(ref el, _) => {
  281. //let val = zkcons_eval(el.to_vec(), &a1, &env)?;
  282. //val.clone();
  283. println!("{:?}", el.to_vec());
  284. }
  285. _ => println!("invalid format"),
  286. }
  287. // println!("3 {:?}", eval(a1.clone(), env.clone()));
  288. env_set(&env, a1.clone(), eval(a1.clone(), env.clone())?);
  289. eval(a1.clone(), env.clone())
  290. }
  291. Sym(ref a0sym) if a0sym == "fn*" => {
  292. let (a1, a2) = (l[1].clone(), l[2].clone());
  293. Ok(MalFunc {
  294. eval: eval,
  295. ast: Rc::new(a2),
  296. env: env,
  297. params: Rc::new(a1),
  298. is_macro: false,
  299. meta: Rc::new(Nil),
  300. })
  301. }
  302. Sym(ref a0sym) if a0sym == "eval" => {
  303. ast = eval(l[1].clone(), env.clone())?;
  304. while let Some(ref e) = env.clone().outer {
  305. env = e.clone();
  306. }
  307. continue 'tco;
  308. }
  309. _ => match eval_ast(&ast, &env)? {
  310. List(ref el, _) => {
  311. let ref f = el[0].clone();
  312. let args = el[1..].to_vec();
  313. match f {
  314. Func(_, _) => f.apply(args),
  315. MalFunc {
  316. ast: mast,
  317. env: menv,
  318. params,
  319. ..
  320. } => {
  321. let a = &**mast;
  322. let p = &**params;
  323. env = env_bind(Some(menv.clone()), p.clone(), args)?;
  324. ast = a.clone();
  325. continue 'tco;
  326. }
  327. _ => {
  328. Ok(Nil)
  329. //error("call non-function")
  330. }
  331. }
  332. }
  333. _ => error("expected a list"),
  334. },
  335. }
  336. }
  337. _ => eval_ast(&ast, &env),
  338. };
  339. break;
  340. } // end 'tco loop
  341. ret
  342. }
  343. pub fn setup(ast: &MalVal) -> MalRet {
  344. // TODO get params from ast
  345. let start = Instant::now();
  346. // Create parameters for our circuit. In a production deployment these would
  347. // be generated securely using a multiparty computation.
  348. let c = LispCircuit { params: Rc::new(vector!(vec![])) };
  349. // TODO move to another fn
  350. let random_parameters = groth16::generate_random_parameters::<Bls12, _, _>(c.clone(), &mut OsRng).unwrap();
  351. let pvk = groth16::prepare_verifying_key(&random_parameters.vk);
  352. println!("Setup: [{:?}]", start.elapsed());
  353. Ok(MalVal::Zk(Rc::new(c)))
  354. }
  355. pub fn prove(ast: &MalVal) -> MalRet {
  356. // Pick a preimage and compute its hash.
  357. let quantity = bls12_381::Scalar::from(3);
  358. // Create an instance of our circuit (with the preimage as a witness).
  359. let c = LispCircuit {
  360. params: Rc::new(vector![vec![
  361. MalVal::Scalar(std::string::ToString::to_string(&quantity)),
  362. MalVal::Scalar(std::string::ToString::to_string(&(quantity * quantity))),
  363. MalVal::Scalar(std::string::ToString::to_string(&(quantity * quantity * quantity))),
  364. ]]),
  365. };
  366. let start = Instant::now();
  367. // Create a Groth16 proof with our parameters.
  368. //let proof = groth16::create_random_proof(c, &params, &mut OsRng).unwrap();
  369. println!("Prove: [{:?}]", start.elapsed());
  370. Ok(MalVal::Nil)
  371. }
  372. pub fn verify(ast: &MalVal) -> MalRet {
  373. let public_input = vec![bls12_381::Scalar::from(27)];
  374. let start = Instant::now();
  375. // Check the proof!
  376. //assert!(groth16::verify_proof(&pvk, &proof, &public_input).is_ok());
  377. println!("Verify: [{:?}]", start.elapsed());
  378. Ok(MalVal::Nil)
  379. }
  380. // print
  381. fn print(ast: &MalVal) -> String {
  382. ast.pr_str(true)
  383. }
  384. fn rep(str: &str, env: &Env) -> Result<String, MalErr> {
  385. let ast = read(str)?;
  386. let exp = eval(ast, env.clone())?;
  387. Ok(print(&exp))
  388. }
  389. fn main() -> Result<(), ()> {
  390. let matches = clap_app!(zklisp =>
  391. (version: "0.1.0")
  392. (author: "mileschet <miles.chet@gmail.com>")
  393. (about: "A Lisp Interpreter for Zero Knowledge Virtual Machine")
  394. (@subcommand load =>
  395. (about: "Load the file into the interpreter")
  396. (@arg FILE: +required "Lisp Contract filename")
  397. )
  398. )
  399. .get_matches();
  400. CombinedLogger::init(vec![TermLogger::new(
  401. LevelFilter::Debug,
  402. Config::default(),
  403. TerminalMode::Mixed,
  404. )
  405. .unwrap()])
  406. .unwrap();
  407. match matches.subcommand() {
  408. Some(("load", matches)) => {
  409. let file: String = matches.value_of("FILE").unwrap().parse().unwrap();
  410. repl_load(file);
  411. }
  412. _ => {
  413. eprintln!("error: Invalid subcommand invoked");
  414. std::process::exit(-1);
  415. }
  416. }
  417. Ok(())
  418. }
  419. fn repl_load(file: String) -> Result<(), ()> {
  420. let repl_env = env_new(None);
  421. for (k, v) in core::ns() {
  422. env_sets(&repl_env, k, v);
  423. }
  424. let _ = rep("(def! not (fn* (a) (if a false true)))", &repl_env);
  425. let _ = rep(
  426. "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \"\nnil)\")))))",
  427. &repl_env,
  428. );
  429. let _ = rep("(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))", &repl_env);
  430. match rep(&format!("(load-file \"{}\")", file), &repl_env) {
  431. Ok(_) => std::process::exit(0),
  432. Err(e) => {
  433. println!("Error: {}", format_error(e));
  434. std::process::exit(1);
  435. }
  436. }
  437. Ok(())
  438. }