lisp.rs 17 KB

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