lisp.rs 20 KB

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