lisp.rs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. #![allow(non_snake_case)]
  2. use crate::types::LispCircuit;
  3. use crate::MalVal::Zk;
  4. use bellman::groth16::PreparedVerifyingKey;
  5. use sapvi::{ZKVMCircuit, ZKVirtualMachine};
  6. use simplelog::*;
  7. use bellman::{gadgets::Assignment, groth16, Circuit, ConstraintSystem, SynthesisError};
  8. use bls12_381::Bls12;
  9. use bls12_381::Scalar;
  10. use ff::PrimeField;
  11. use fnv::FnvHashMap;
  12. use itertools::Itertools;
  13. use rand::rngs::OsRng;
  14. use std::time::Instant;
  15. use std::{borrow::BorrowMut, rc::Rc};
  16. use std::{
  17. cell::RefCell,
  18. ops::{AddAssign, MulAssign, SubAssign},
  19. };
  20. use types::EnforceAllocation;
  21. use MalVal::ZKScalar;
  22. #[macro_use]
  23. extern crate clap;
  24. #[macro_use]
  25. extern crate lazy_static;
  26. extern crate fnv;
  27. extern crate itertools;
  28. extern crate regex;
  29. #[macro_use]
  30. mod types;
  31. use crate::types::MalErr::{ErrMalVal, ErrString};
  32. use crate::types::MalVal::{Bool, Func, Hash, List, MalFunc, Nil, Str, Sym, Vector, Enforce};
  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. pub const ZK_CIRCUIT_ENV_KEY: &str = "ZKC";
  41. // read
  42. fn read(str: &str) -> MalRet {
  43. reader::read_str(str.to_string())
  44. }
  45. // eval
  46. fn qq_iter(elts: &MalArgs) -> MalVal {
  47. let mut acc = list![];
  48. for elt in elts.iter().rev() {
  49. if let List(v, _) = elt {
  50. if v.len() == 2 {
  51. if let Sym(ref s) = v[0] {
  52. if s == "splice-unquote" {
  53. acc = list![Sym("concat".to_string()), v[1].clone(), acc];
  54. continue;
  55. }
  56. }
  57. }
  58. }
  59. acc = list![Sym("cons".to_string()), quasiquote(&elt), acc];
  60. }
  61. return acc;
  62. }
  63. fn quasiquote(ast: &MalVal) -> MalVal {
  64. match ast {
  65. List(v, _) => {
  66. if v.len() == 2 {
  67. if let Sym(ref s) = v[0] {
  68. if s == "unquote" {
  69. return v[1].clone();
  70. }
  71. }
  72. }
  73. return qq_iter(&v);
  74. }
  75. Vector(v, _) => return list![Sym("vec".to_string()), qq_iter(&v)],
  76. Hash(_, _) | Sym(_) => return list![Sym("quote".to_string()), ast.clone()],
  77. _ => ast.clone(),
  78. }
  79. }
  80. fn is_macro_call(ast: &MalVal, env: &Env) -> Option<(MalVal, MalArgs)> {
  81. match ast {
  82. List(v, _) => match v[0] {
  83. Sym(ref s) => match env_find(env, s) {
  84. Some(e) => match env_get(&e, &v[0]) {
  85. Ok(f @ MalFunc { is_macro: true, .. }) => Some((f, v[1..].to_vec())),
  86. _ => None,
  87. },
  88. _ => None,
  89. },
  90. _ => None,
  91. },
  92. _ => None,
  93. }
  94. }
  95. fn macroexpand(mut ast: MalVal, env: &Env) -> (bool, MalRet) {
  96. let mut was_expanded = false;
  97. while let Some((mf, args)) = is_macro_call(&ast, env) {
  98. //println!("macroexpand 1: {:?}", ast);
  99. ast = match mf.apply(args) {
  100. Err(e) => return (false, Err(e)),
  101. Ok(a) => a,
  102. };
  103. //println!("macroexpand 2: {:?}", ast);
  104. was_expanded = true;
  105. }
  106. (was_expanded, Ok(ast))
  107. }
  108. fn eval_ast(ast: &MalVal, env: &Env) -> MalRet {
  109. match ast {
  110. Sym(_) => Ok(env_get(&env, &ast)?),
  111. List(v, _) => {
  112. let mut lst: MalArgs = vec![];
  113. for a in v.iter() {
  114. lst.push(eval(a.clone(), env.clone())?)
  115. }
  116. Ok(list!(lst))
  117. }
  118. Vector(v, _) => {
  119. let mut lst: MalArgs = vec![];
  120. for a in v.iter() {
  121. lst.push(eval(a.clone(), env.clone())?)
  122. }
  123. Ok(vector!(lst))
  124. }
  125. Hash(hm, _) => {
  126. let mut new_hm: FnvHashMap<String, MalVal> = FnvHashMap::default();
  127. for (k, v) in hm.iter() {
  128. new_hm.insert(k.to_string(), eval(v.clone(), env.clone())?);
  129. }
  130. Ok(Hash(Rc::new(new_hm), Rc::new(Nil)))
  131. }
  132. _ => Ok(ast.clone()),
  133. }
  134. }
  135. fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
  136. let ret: MalRet;
  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 == "let*" => {
  160. env = env_new(Some(env.clone()));
  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 == "quote" => Ok(l[1].clone()),
  187. Sym(ref a0sym) if a0sym == "quasiquoteexpand" => Ok(quasiquote(&l[1])),
  188. Sym(ref a0sym) if a0sym == "quasiquote" => {
  189. ast = quasiquote(&l[1]);
  190. continue 'tco;
  191. }
  192. Sym(ref a0sym) if a0sym == "defmacro!" => {
  193. let (a1, a2) = (l[1].clone(), l[2].clone());
  194. let r = eval(a2, env.clone())?;
  195. match r {
  196. MalFunc {
  197. eval,
  198. ast,
  199. env,
  200. params,
  201. ..
  202. } => Ok(env_set(
  203. &env,
  204. a1.clone(),
  205. MalFunc {
  206. eval: eval,
  207. ast: ast.clone(),
  208. env: env.clone(),
  209. params: params.clone(),
  210. is_macro: true,
  211. meta: Rc::new(Nil),
  212. },
  213. )?),
  214. _ => error("set_macro on non-function"),
  215. }
  216. }
  217. Sym(ref a0sym) if a0sym == "macroexpand" => {
  218. match macroexpand(l[1].clone(), &env) {
  219. (_, Ok(new_ast)) => Ok(new_ast),
  220. (_, e) => return e,
  221. }
  222. }
  223. Sym(ref a0sym) if a0sym == "try*" => match eval(l[1].clone(), env.clone()) {
  224. Err(ref e) if l.len() >= 3 => {
  225. let exc = match e {
  226. ErrMalVal(mv) => mv.clone(),
  227. ErrString(s) => Str(s.to_string()),
  228. };
  229. match l[2].clone() {
  230. List(c, _) => {
  231. let catch_env = env_bind(
  232. Some(env.clone()),
  233. list!(vec![c[1].clone()]),
  234. vec![exc],
  235. )?;
  236. eval(c[2].clone(), catch_env)
  237. }
  238. _ => error("invalid catch block"),
  239. }
  240. }
  241. res => res,
  242. },
  243. Sym(ref a0sym) if a0sym == "do" => {
  244. match eval_ast(&list!(l[1..l.len() - 1].to_vec()), &env)? {
  245. List(_, _) => {
  246. ast = l.last().unwrap_or(&Nil).clone();
  247. continue 'tco;
  248. }
  249. _ => error("invalid do form"),
  250. }
  251. }
  252. Sym(ref a0sym) if a0sym == "if" => {
  253. let cond = eval(l[1].clone(), env.clone())?;
  254. match cond {
  255. Bool(false) | Nil if l.len() >= 4 => {
  256. ast = l[3].clone();
  257. continue 'tco;
  258. }
  259. Bool(false) | Nil => Ok(Nil),
  260. _ if l.len() >= 3 => {
  261. ast = l[2].clone();
  262. continue 'tco;
  263. }
  264. _ => Ok(Nil),
  265. }
  266. }
  267. Sym(ref a0sym) if a0sym == "fn*" => {
  268. let (a1, a2) = (l[1].clone(), l[2].clone());
  269. Ok(MalFunc {
  270. eval: eval,
  271. ast: Rc::new(a2),
  272. env: env,
  273. params: Rc::new(a1),
  274. is_macro: false,
  275. meta: Rc::new(Nil),
  276. })
  277. }
  278. Sym(ref a0sym) if a0sym == "eval" => {
  279. ast = eval(l[1].clone(), env.clone())?;
  280. while let Some(ref e) = env.clone().outer {
  281. env = e.clone();
  282. }
  283. continue 'tco;
  284. }
  285. Sym(ref a0sym) if a0sym == "setup" => {
  286. let a1 = l[1].clone();
  287. // todo
  288. let _pvk = setup(a1.clone(), env.clone())?;
  289. ast = eval(a1.clone(), env.clone())?;
  290. continue 'tco;
  291. }
  292. Sym(ref a0sym) if a0sym == "prove" => {
  293. let a1 = l[0].clone();
  294. println!("prove {:?}", a1);
  295. prove(a1.clone(), env.clone())
  296. }
  297. Sym(ref a0sym) if a0sym == "alloc-input" => {
  298. let a1 = l[1].clone();
  299. let value = eval(l[2].clone(), env.clone())?;
  300. let result = eval(value.clone(), env.clone())?;
  301. // let symbol = MalVal::Sym(a1.pr_str(false));
  302. // env_set(&env, Sym(a1.pr_str(false)), result.clone());
  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("AllocationsInput".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. if let Hash(allocs, _) = get_allocations(&env, "Allocations")? {
  322. let mut new_hm: FnvHashMap<String, MalVal> = FnvHashMap::default();
  323. for (k, v) in allocs.iter() {
  324. new_hm.insert(k.to_string(), eval(v.clone(), env.clone())?);
  325. }
  326. new_hm.insert(a1.pr_str(false), result);
  327. env_set(
  328. &env,
  329. Sym("Allocations".to_string()),
  330. Hash(Rc::new(new_hm), Rc::new(Nil)),
  331. )?;
  332. };
  333. Ok(Nil)
  334. }
  335. //Sym(ref a0sym) if a0sym == "verify" => {
  336. Sym(ref a0sym) if a0sym == "enforce" => {
  337. // here i'm considering that we always have tuple with only two elements
  338. // also it's important to keep in mind for the sake of brevity of this v0
  339. // we will not allow calculation or any lisp evaluations inside the enforce
  340. // it means that every symbol will be on allocations and we will do the
  341. // find/replace on the bellman circuit, it's nasty v0
  342. let mut left_vec = vec![];
  343. let mut right_vec = vec![];
  344. let mut out_vec = vec![];
  345. // todo extract a macro for this
  346. match l[1].clone() {
  347. List(v, _) | Vector(v, _) => {
  348. if let List(_, _) = &v.to_vec()[0] {
  349. for ele in v.to_vec().iter() {
  350. if let List(ele_vec, _) = ele {
  351. left_vec.push((
  352. ele_vec[0].pr_str(false),
  353. ele_vec[1].pr_str(false),
  354. ));
  355. }
  356. }
  357. } else {
  358. left_vec.push((v[0].pr_str(false), v[1].pr_str(false)));
  359. }
  360. }
  361. _ => {}
  362. };
  363. match l[2].clone() {
  364. List(v, _) | Vector(v, _) => {
  365. if let List(_, _) = &v.to_vec()[0] {
  366. for ele in v.to_vec().iter() {
  367. if let List(ele_vec, _) = ele {
  368. right_vec.push((
  369. ele_vec[0].pr_str(false),
  370. ele_vec[1].pr_str(false),
  371. ));
  372. }
  373. }
  374. } else {
  375. right_vec.push((v[0].pr_str(false), v[1].pr_str(false)));
  376. }
  377. }
  378. _ => {}
  379. };
  380. match l[3].clone() {
  381. List(v, _) | Vector(v, _) => {
  382. if let List(_, _) = &v.to_vec()[0] {
  383. for ele in v.to_vec().iter() {
  384. if let List(ele_vec, _) = ele {
  385. out_vec.push((
  386. ele_vec[0].pr_str(false),
  387. ele_vec[1].pr_str(false),
  388. ));
  389. }
  390. }
  391. } else {
  392. out_vec.push((v[0].pr_str(false), v[1].pr_str(false)));
  393. }
  394. }
  395. _ => {}
  396. };
  397. let enforce = EnforceAllocation {
  398. left: left_vec,
  399. right: right_vec,
  400. output: out_vec,
  401. };
  402. let mut new_vec: Vec<EnforceAllocation> = vec![enforce];
  403. match get_enforce_allocs(&env)? {
  404. Vector(v, _) => {
  405. for value in v.iter() {
  406. println!("VALUES {:?} \n", value);
  407. match value {
  408. Enforce(v) => {
  409. println!("{:?}", v);
  410. }
  411. _ => {}
  412. };
  413. }
  414. }
  415. v => {
  416. println!("something wrong. {:?}", v)
  417. }
  418. };
  419. env_set(
  420. &env,
  421. Sym("AllocationsEnforce".to_string()),
  422. vector![vec![Enforce(Rc::new(new_vec))]],
  423. );
  424. println!("\n\nallocations {:?}", get_allocations(&env, "Allocations"));
  425. println!(
  426. "\n\nallocations input {:?}",
  427. get_allocations(&env, "AllocationsInput")
  428. );
  429. println!("\n\nallocations enforce {:?}", get_enforce_allocs(&env));
  430. Ok(vector![vec![]])
  431. }
  432. _ => match eval_ast(&ast, &env)? {
  433. List(ref el, _) => {
  434. let ref f = el[0].clone();
  435. let args = el[1..].to_vec();
  436. match f {
  437. Func(_, _) => f.apply(args),
  438. MalFunc {
  439. ast: mast,
  440. env: menv,
  441. params,
  442. ..
  443. } => {
  444. let a = &**mast;
  445. let p = &**params;
  446. env = env_bind(Some(menv.clone()), p.clone(), args)?;
  447. ast = a.clone();
  448. continue 'tco;
  449. }
  450. _ => {
  451. Ok(vector![el.to_vec()])
  452. //error("call non-function")
  453. }
  454. }
  455. }
  456. _ => error("expected a list"),
  457. },
  458. }
  459. }
  460. _ => eval_ast(&ast, &env),
  461. };
  462. break;
  463. } // end 'tco loop
  464. ret
  465. }
  466. pub fn get_enforce_allocs(env: &Env) -> MalRet {
  467. let found = match env_find(env, "AllocationsEnforce") {
  468. Some(e) => match env_get(&e, &Sym("AllocationsEnforce".to_string())) {
  469. Ok(f) => {
  470. println!("Found {:?}", f);
  471. Ok(f)
  472. }
  473. _ => Ok(vector![vec![]]),
  474. },
  475. _ => Ok(vector![vec![]]),
  476. };
  477. found
  478. }
  479. pub fn get_allocations(env: &Env, key: &str) -> MalRet {
  480. let alloc_hm: FnvHashMap<String, MalVal> = FnvHashMap::default();
  481. match env_find(env, key) {
  482. Some(e) => match env_get(&e, &Sym(key.to_string())) {
  483. Ok(f) => Ok(f),
  484. _ => Ok(Hash(Rc::new(alloc_hm), Rc::new(Nil))),
  485. },
  486. _ => Ok(Hash(Rc::new(alloc_hm), Rc::new(Nil))),
  487. }
  488. }
  489. pub fn setup(_ast: MalVal, env: Env) -> Result<PreparedVerifyingKey<Bls12>, MalErr> {
  490. let start = Instant::now();
  491. // Create parameters for our circuit. In a production deployment these would
  492. // be generated securely using a multiparty computation.
  493. // get all allocs from env
  494. let c = LispCircuit {
  495. params: vec![],
  496. allocs: vec![],
  497. alloc_inputs: vec![],
  498. constraints: vec![],
  499. env: env.clone(),
  500. };
  501. // TODO move to another fn
  502. let random_parameters =
  503. groth16::generate_random_parameters::<Bls12, _, _>(c, &mut OsRng).unwrap();
  504. let pvk = groth16::prepare_verifying_key(&random_parameters.vk);
  505. println!("Setup: [{:?}]", start.elapsed());
  506. Ok(pvk)
  507. }
  508. pub fn prove(_ast: MalVal, env: Env) -> MalRet {
  509. // TODO remove it
  510. let _quantity = bls12_381::Scalar::from(3);
  511. // Create an instance of our circuit (with the preimage as a witness).
  512. let params = {
  513. let c = LispCircuit {
  514. params: vec![],
  515. allocs: vec![],
  516. alloc_inputs: vec![],
  517. constraints: vec![],
  518. env: env.clone(),
  519. };
  520. groth16::generate_random_parameters::<Bls12, _, _>(c, &mut OsRng).unwrap()
  521. };
  522. let circuit = LispCircuit {
  523. params: vec![],
  524. allocs: vec![],
  525. alloc_inputs: vec![],
  526. constraints: vec![],
  527. env: env.clone(),
  528. };
  529. let start = Instant::now();
  530. // Create a Groth16 proof with our parameters.
  531. let _proof = groth16::create_random_proof(circuit, &params, &mut OsRng).unwrap();
  532. println!("Prove: [{:?}]", start.elapsed());
  533. Ok(MalVal::Nil)
  534. }
  535. pub fn verify(_ast: &MalVal) -> MalRet {
  536. let _public_input = vec![bls12_381::Scalar::from(27)];
  537. let start = Instant::now();
  538. // Check the proof!
  539. //assert!(groth16::verify_proof(&pvk, &proof, &public_input).is_ok());
  540. println!("Verify: [{:?}]", start.elapsed());
  541. Ok(MalVal::Nil)
  542. }
  543. // print
  544. fn print(ast: &MalVal) -> String {
  545. ast.pr_str(true)
  546. }
  547. fn rep(str: &str, env: &Env) -> Result<String, MalErr> {
  548. let ast = read(str)?;
  549. let exp = eval(ast, env.clone())?;
  550. Ok(print(&exp))
  551. }
  552. fn main() -> Result<(), ()> {
  553. let matches = clap_app!(zklisp =>
  554. (version: "0.1.0")
  555. (author: "mileschet <miles.chet@gmail.com>")
  556. (about: "A Lisp Interpreter for Zero Knowledge Virtual Machine")
  557. (@subcommand load =>
  558. (about: "Load the file into the interpreter")
  559. (@arg FILE: +required "Lisp Contract filename")
  560. )
  561. )
  562. .get_matches();
  563. CombinedLogger::init(vec![TermLogger::new(
  564. LevelFilter::Debug,
  565. Config::default(),
  566. TerminalMode::Mixed,
  567. )
  568. .unwrap()])
  569. .unwrap();
  570. match matches.subcommand() {
  571. Some(("load", matches)) => {
  572. let file: String = matches.value_of("FILE").unwrap().parse().unwrap();
  573. repl_load(file)?;
  574. }
  575. _ => {
  576. eprintln!("error: Invalid subcommand invoked");
  577. std::process::exit(-1);
  578. }
  579. }
  580. Ok(())
  581. }
  582. fn repl_load(file: String) -> Result<(), ()> {
  583. let repl_env = env_new(None);
  584. for (k, v) in core::ns() {
  585. env_sets(&repl_env, k, v);
  586. }
  587. let _ = rep("(def! not (fn* (a) (if a false true)))", &repl_env);
  588. let _ = rep(
  589. "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \"\nnil)\")))))",
  590. &repl_env,
  591. );
  592. //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);
  593. match rep(&format!("(load-file \"{}\")", file), &repl_env) {
  594. Ok(_) => std::process::exit(0),
  595. Err(e) => {
  596. println!("Error: {}", format_error(e));
  597. std::process::exit(1);
  598. }
  599. }
  600. }