removed /lisp and added king.png

This commit is contained in:
lunar-mining
2021-09-13 09:13:39 +02:00
parent a0cc6735b4
commit 7de40e7f01
18 changed files with 0 additions and 3806 deletions

BIN
king.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

View File

@@ -1,12 +0,0 @@
## zklisp
This is a DSL for ZkVmCircuit from drk language.
It uses the mal (lisp) version of rust with some modifications to interact with bellman backend and also drk vm.
## run
```
cargo run --bin lisp load new.lisp
```

View File

@@ -1,7 +0,0 @@
## TODO
- Document the language
- Integrate with zkvm command line
- Integrate with ZkVmCircuit: allocs and constraints
- Added CryptoOperation such double and square to core.rs
- Adapt ZkContract to use lisp to read contract and execute

View File

@@ -1,831 +0,0 @@
use rand::Rng;
use std::fs::File;
use std::io::Read;
use std::rc::Rc;
use std::time::{SystemTime, UNIX_EPOCH};
use crate::printer::pr_seq;
use crate::reader::read_str;
use crate::types::MalErr::ErrMalVal;
use crate::types::MalVal::{
Atom, Bool, Func, Hash, Int, List, MalFunc, Nil, Str, Sym, Vector, ZKScalar,
};
use crate::types::{MalArgs, MalRet, MalVal, _assoc, _dissoc, atom, error, func, hash_map};
use bls12_381;
use ff::{Field, PrimeField};
use rand::rngs::OsRng;
use drk::bls_extensions::BlsStringConversion;
use std::ops::{AddAssign, MulAssign, SubAssign};
macro_rules! fn_t_int_int {
($ret:ident, $fn:expr) => {{
|a: MalArgs| match (a[0].clone(), a[1].clone()) {
(Int(a0), Int(a1)) => Ok($ret($fn(a0, a1))),
_ => error("expecting (int,int) args"),
}
}};
}
macro_rules! fn_is_type {
($($ps:pat),*) => {{
|a:MalArgs| { Ok(Bool(match a[0] { $($ps => true,)* _ => false})) }
}};
($p:pat if $e:expr) => {{
|a:MalArgs| { Ok(Bool(match a[0] { $p if $e => true, _ => false})) }
}};
($p:pat if $e:expr,$($ps:pat),*) => {{
|a:MalArgs| { Ok(Bool(match a[0] { $p if $e => true, $($ps => true,)* _ => false})) }
}};
}
macro_rules! fn_str {
($fn:expr) => {{
|a: MalArgs| match a[0].clone() {
Str(a0) => $fn(a0),
_ => error("expecting (str) arg"),
}
}};
}
fn symbol(a: MalArgs) -> MalRet {
match a[0] {
Str(ref s) => Ok(Sym(s.to_string())),
_ => error("illegal symbol call"),
}
}
fn slurp(f: String) -> MalRet {
let mut s = String::new();
match File::open(f).and_then(|mut f| f.read_to_string(&mut s)) {
Ok(_) => Ok(Str(s)),
Err(e) => error(&e.to_string()),
}
}
fn time_ms(_a: MalArgs) -> MalRet {
let ms_e = match SystemTime::now().duration_since(UNIX_EPOCH) {
Ok(d) => d,
Err(e) => return error(&format!("{:?}", e)),
};
Ok(Int(
ms_e.as_secs() as i64 * 1000 + ms_e.subsec_nanos() as i64 / 1_000_000
))
}
fn get(a: MalArgs) -> MalRet {
match (a[0].clone(), a[1].clone()) {
(Nil, _) => Ok(Nil),
(Hash(ref hm, _), Str(ref s)) => match hm.get(s) {
Some(mv) => Ok(mv.clone()),
None => Ok(Nil),
},
_ => error("illegal get args"),
}
}
fn assoc(a: MalArgs) -> MalRet {
match a[0] {
Hash(ref hm, _) => _assoc((**hm).clone(), a[1..].to_vec()),
_ => error("assoc on non-Hash Map"),
}
}
fn dissoc(a: MalArgs) -> MalRet {
match a[0] {
Hash(ref hm, _) => _dissoc((**hm).clone(), a[1..].to_vec()),
_ => error("dissoc on non-Hash Map"),
}
}
fn contains_q(a: MalArgs) -> MalRet {
match (a[0].clone(), a[1].clone()) {
(Hash(ref hm, _), Str(ref s)) => Ok(Bool(hm.contains_key(s))),
_ => error("illegal get args"),
}
}
fn keys(a: MalArgs) -> MalRet {
match a[0] {
Hash(ref hm, _) => Ok(list!(hm.keys().map(|k| { Str(k.to_string()) }).collect())),
_ => error("keys requires Hash Map"),
}
}
fn vals(a: MalArgs) -> MalRet {
match a[0] {
Hash(ref hm, _) => Ok(list!(hm.values().map(|v| { v.clone() }).collect())),
_ => error("keys requires Hash Map"),
}
}
fn vec(a: MalArgs) -> MalRet {
match a[0] {
List(ref v, _) | Vector(ref v, _) => Ok(vector!(v.to_vec())),
_ => error("non-seq passed to vec"),
}
}
fn cons(a: MalArgs) -> MalRet {
match a[1].clone() {
List(v, _) | Vector(v, _) => {
let mut new_v = vec![a[0].clone()];
new_v.extend_from_slice(&v);
Ok(list!(new_v.to_vec()))
}
_ => error("cons expects seq as second arg"),
}
}
fn concat(a: MalArgs) -> MalRet {
let mut new_v = vec![];
for seq in a.iter() {
match seq {
List(v, _) | Vector(v, _) => new_v.extend_from_slice(v),
_ => return error("non-seq passed to concat"),
}
}
Ok(list!(new_v.to_vec()))
}
fn nth(a: MalArgs) -> MalRet {
match (a[0].clone(), a[1].clone()) {
(List(seq, _), Int(idx)) | (Vector(seq, _), Int(idx)) => {
if seq.len() <= idx as usize {
return error("nth: index out of range");
}
Ok(seq[idx as usize].clone())
}
_ => error("invalid args to nth"),
}
}
fn unpack_bits(a: MalArgs) -> MalRet {
let mut result = vec![];
match a[0].clone() {
Str(ref s) => {
let value = bls12_381::Scalar::from_string(s);
for (_, bit) in value.to_le_bits().into_iter().enumerate() {
match bit {
true => result.push(bls12_381::Scalar::one()),
false => result.push(bls12_381::Scalar::zero()),
}
}
Ok(list!(result
.iter()
.map(|a| Str(std::string::ToString::to_string(&a)[2..].to_string()))
.collect::<Vec<MalVal>>()))
}
ZKScalar(ref s) => {
for (_, bit) in s.to_le_bits().into_iter().enumerate() {
match bit {
true => result.push(bls12_381::Scalar::one()),
false => result.push(bls12_381::Scalar::zero()),
}
}
Ok(list!(result
.iter()
.map(|a| Str(std::string::ToString::to_string(&a)[2..].to_string()))
.collect::<Vec<MalVal>>()))
}
_ => error(&format!("invalid args to unpack-bits found \n {:?}", a).to_string()),
}
}
fn last(a: MalArgs) -> MalRet {
match a[0].clone() {
List(ref seq, _) | Vector(ref seq, _) if seq.len() == 0 => Ok(Nil),
List(ref seq, _) | Vector(ref seq, _) => Ok(seq[seq.len() - 1].clone()),
Nil => Ok(Nil),
_ => error("invalid args to first"),
}
}
fn first(a: MalArgs) -> MalRet {
match a[0].clone() {
List(ref seq, _) | Vector(ref seq, _) if seq.len() == 0 => Ok(Nil),
List(ref seq, _) | Vector(ref seq, _) => Ok(seq[0].clone()),
Nil => Ok(Nil),
_ => error("invalid args to first"),
}
}
fn second(a: MalArgs) -> MalRet {
match a[0].clone() {
List(ref seq, _) | Vector(ref seq, _) if seq.len() < 2 => Ok(Nil),
List(ref seq, _) | Vector(ref seq, _) => Ok(seq[1].clone()),
Nil => Ok(Nil),
_ => error("invalid args to first"),
}
}
fn rest(a: MalArgs) -> MalRet {
match a[0].clone() {
List(ref seq, _) | Vector(ref seq, _) => {
if seq.len() > 1 {
Ok(list!(seq[1..].to_vec()))
} else {
Ok(list![])
}
}
Nil => Ok(list![]),
_ => error("invalid args to first"),
}
}
fn apply(a: MalArgs) -> MalRet {
match a[a.len() - 1] {
List(ref v, _) | Vector(ref v, _) => {
let f = &a[0];
let mut fargs = a[1..a.len() - 1].to_vec();
fargs.extend_from_slice(&v);
f.apply(fargs)
}
_ => error("apply called with non-seq"),
}
}
fn map(a: MalArgs) -> MalRet {
match a[1] {
List(ref v, _) | Vector(ref v, _) => {
let mut res = vec![];
for mv in v.iter() {
res.push(a[0].apply(vec![mv.clone()])?)
}
Ok(list!(res))
}
_ => error("map called with non-seq"),
}
}
fn conj(a: MalArgs) -> MalRet {
match a[0] {
List(ref v, _) => {
let sl = a[1..]
.iter()
.rev()
.map(|a| a.clone())
.collect::<Vec<MalVal>>();
Ok(list!([&sl[..], v].concat()))
}
Vector(ref v, _) => Ok(vector!([v, &a[1..]].concat())),
_ => error("conj: called with non-seq"),
}
}
fn sub_scalar(a: MalArgs) -> MalRet {
match (a[0].clone(), a[1].clone()) {
(Func(_, _), ZKScalar(a1)) => {
if let Vector(ref values, _) = a[0].apply(vec![]).unwrap() {
if let ZKScalar(mut a0) = values[0] {
a0.sub_assign(a1);
Ok(ZKScalar(a0))
} else {
error("scalar sub expect (zkscalar, zkscalar) found (func, zkscalar)")
}
} else {
error("scalar sub expect (zkscalar, zkscalar)")
}
}
(Func(_, _), Str(a1)) => {
if let Vector(ref values, _) = a[0].apply(vec![]).unwrap() {
let s1 = bls12_381::Scalar::from_string(&a1);
if let ZKScalar(mut a0) = values[0] {
a0.sub_assign(s1);
Ok(ZKScalar(a0))
} else {
error("scalar sub expect (zkscalar, zkscalar) found (func, zkscalar)")
}
} else {
error("scalar sub expect (zkscalar, zkscalar)")
}
}
(ZKScalar(mut a0), ZKScalar(a1)) => {
a0.sub_assign(a1);
Ok(ZKScalar(a0))
}
(Str(a0), ZKScalar(a1)) => {
let (mut s0, s1) = (bls12_381::Scalar::from_string(&a0), a1);
s0.sub_assign(s1);
Ok(Str(std::string::ToString::to_string(&s0)[2..].to_string()))
}
(ZKScalar(a0), Str(a1)) => {
let (mut s0, s1) = (a0, bls12_381::Scalar::from_string(&a1));
s0.sub_assign(s1);
Ok(Str(std::string::ToString::to_string(&s0)[2..].to_string()))
}
(Str(a0), Str(a1)) => {
let (mut s0, s1) = (
bls12_381::Scalar::from_string(&a0),
bls12_381::Scalar::from_string(&a1),
);
s0.sub_assign(s1);
Ok(Str(std::string::ToString::to_string(&s0)[2..].to_string()))
}
_ => error(&format!("scalar sub expect (zkscalar, zkscalar) found \n {:?}", a).to_string()),
}
}
fn mul_scalar(a: MalArgs) -> MalRet {
println!("mul {:?}", a[0]);
match (a[0].clone(), a[1].clone()) {
(Func(_, _), ZKScalar(a1)) => {
if let Vector(ref values, _) = a[0].apply(vec![]).unwrap() {
if let ZKScalar(mut a0) = values[0] {
a0.mul_assign(a1);
Ok(ZKScalar(a0))
} else {
error("scalar mul expect (zkscalar, zkscalar) found (func, zkscalar)")
}
} else {
error("scalar mul expect (zkscalar, zkscalar)")
}
}
(ZKScalar(a1), Func(_, _)) => {
if let Vector(ref values, _) = a[1].apply(vec![]).unwrap() {
if let ZKScalar(mut a0) = values[0] {
a0.mul_assign(a1);
Ok(ZKScalar(a0))
} else {
error("scalar mul expect (zkscalar, zkscalar) found (func, zkscalar)")
}
} else {
error("scalar mul expect (zkscalar, zkscalar)")
}
}
(ZKScalar(mut a0), ZKScalar(a1)) => {
a0.mul_assign(a1);
Ok(ZKScalar(a0))
}
(Str(a0), Str(a1)) => {
let (mut s0, s1) = (
bls12_381::Scalar::from_string(&a0),
bls12_381::Scalar::from_string(&a1),
);
s0.mul_assign(s1);
Ok(Str(std::string::ToString::to_string(&s0)[2..].to_string()))
}
(ZKScalar(a0), Str(a1)) => {
let (mut s0, s1) = (a0, bls12_381::Scalar::from_string(&a1));
s0.mul_assign(s1);
Ok(Str(std::string::ToString::to_string(&s0)[2..].to_string()))
}
(Str(a0), ZKScalar(a1)) => {
let (mut s0, s1) = (bls12_381::Scalar::from_string(&a0), a1);
s0.mul_assign(s1);
Ok(Str(std::string::ToString::to_string(&s0)[2..].to_string()))
}
_ => error(&format!("scalar mul expect (zkscalar, zkscalar) \n {:?}", a).to_string()),
}
}
fn div_scalar(a: MalArgs) -> MalRet {
match (a[0].clone(), a[1].clone()) {
(ZKScalar(s0), ZKScalar(s1)) => {
let ret = s1.invert().map(|other| *&s0 * other);
if bool::from(ret.is_some()) {
Ok(Str(
std::string::ToString::to_string(&ret.unwrap())[2..].to_string()
))
} else {
error("DivisionByZero")
}
}
(Str(a0), ZKScalar(a1)) => {
let (s0, s1) = (bls12_381::Scalar::from_string(&a0), a1);
let ret = s1.invert().map(|other| *&s0 * other);
if bool::from(ret.is_some()) {
Ok(Str(
std::string::ToString::to_string(&ret.unwrap())[2..].to_string()
))
} else {
error("DivisionByZero")
}
}
(Str(a0), Str(a1)) => {
let (s0, s1) = (
bls12_381::Scalar::from_string(&a0),
bls12_381::Scalar::from_string(&a1),
);
let ret = s1.invert().map(|other| *&s0 * other);
if bool::from(ret.is_some()) {
Ok(Str(
std::string::ToString::to_string(&ret.unwrap())[2..].to_string()
))
} else {
error("DivisionByZero")
}
}
_ => error(&format!("scalar div expect (zkscalar, zkscalar) \n {:?}", a).to_string()),
}
}
fn range(a: MalArgs) -> MalRet {
let mut result = vec![];
match (a[0].clone(), a[1].clone()) {
(Int(a0), Int(a1)) => {
for n in a0..a1 {
result.push(n);
}
Ok(list!(result.iter().map(|_a| Nil).collect::<Vec<MalVal>>()))
}
_ => error("expected int int"),
}
}
fn scalar_zero(a: MalArgs) -> MalRet {
match a.len() {
0 => Ok(vector![vec![ZKScalar(bls12_381::Scalar::zero())]]),
_ => Ok(vector![vec![
ZKScalar(bls12_381::Scalar::zero()),
a[0].clone()
]]),
}
}
fn scalar_one(a: MalArgs) -> MalRet {
match a.len() {
0 => Ok(vector![vec![ZKScalar(bls12_381::Scalar::one())]]),
_ => Ok(vector![vec![
ZKScalar(bls12_381::Scalar::one()),
a[0].clone()
]]),
}
}
fn scalar_one_neg(a: MalArgs) -> MalRet {
match a.len() {
0 => Ok(vector![vec![ZKScalar(bls12_381::Scalar::one().neg())]]),
_ => Ok(vector![vec![
ZKScalar(bls12_381::Scalar::one().neg()),
a[0].clone()
]]),
}
}
fn cs_one(_a: MalArgs) -> MalRet {
Ok(vector![vec![Sym("cs::one".to_string())]])
}
fn negate_from(a: MalArgs) -> MalRet {
match a[0].clone() {
ZKScalar(a0) => Ok(ZKScalar(a0.neg())),
_ => match a[0].apply(vec![])? {
List(v, _) | Vector(v, _) => match v[0] {
ZKScalar(val) => Ok(vector![vec![ZKScalar(val.neg())]]),
_ => error("not scalar"),
},
_ => return error("non zkscalar passed to negate"),
},
}
}
fn scalar_from(a: MalArgs) -> MalRet {
match a[0].clone() {
ZKScalar(s0) => Ok(ZKScalar(s0)),
Str(a0) => {
let s0 = bls12_381::Scalar::from_string(&a0.to_string());
Ok(ZKScalar(s0))
}
Int(a0) => {
let s0 = bls12_381::Scalar::from(a0 as u64);
Ok(ZKScalar(s0))
}
_ => error("scalar from expected (string or int)"),
}
}
fn scalar_square(a: MalArgs) -> MalRet {
match a[0].clone() {
ZKScalar(a0) => {
let z0 = a0.clone();
Ok(ZKScalar(z0.square()))
}
Str(a0) => {
let s0 = bls12_381::Scalar::from_string(&a0);
Ok(ZKScalar(s0.square()))
}
_ => error(
&format!("scalar square expect (zkscalar or string) found \n {:?}", a).to_string(),
),
}
}
fn scalar_double(a: MalArgs) -> MalRet {
match a[0].clone() {
Func(_, _) => {
if let Vector(ref values, _) = a[0].apply(vec![]).unwrap() {
if let ZKScalar(a0) = values[0] {
a0.double();
Ok(ZKScalar(a0))
} else {
error(
&format!("scalar double expect (zkscalar or string) found \n {:?}", a)
.to_string(),
)
}
} else {
error(
&format!("scalar double expect (zkscalar or string) found \n {:?}", a)
.to_string(),
)
}
}
ZKScalar(a0) => {
let z0 = a0.clone();
Ok(ZKScalar(z0.double()))
}
Str(a0) => {
let s0 = bls12_381::Scalar::from_string(&a0);
Ok(ZKScalar(s0.double()))
}
_ => error(
&format!("scalar double expect (zkscalar or string) found \n {:?}", a).to_string(),
),
}
}
fn scalar_invert(a: MalArgs) -> MalRet {
match a[0].clone() {
Func(_, _) => {
if let Vector(ref values, _) = a[0].apply(vec![]).unwrap() {
if let ZKScalar(a0) = values[0] {
if a0.is_zero() {
error(&format!("scalar invert divizion by zero \n {:?}", a0).to_string())
} else {
Ok(ZKScalar(a0.invert().unwrap()))
}
} else {
error(
&format!("scalar invert expect (zkscalar or string) found \n {:?}", a)
.to_string(),
)
}
} else {
error(
&format!("scalar invert expect (zkscalar or string) found \n {:?}", a)
.to_string(),
)
}
}
ZKScalar(a0) => {
let z0 = a0.clone();
Ok(ZKScalar(z0.invert().unwrap()))
}
Str(a0) => {
let s0 = bls12_381::Scalar::from_string(&a0);
Ok(ZKScalar(s0.invert().unwrap()))
}
_ => error(
&format!("scalar invert expect (zkscalar or string) found \n {:?}", a).to_string(),
),
}
}
fn scalar_is_zero(a: MalArgs) -> MalRet {
match a[0].clone() {
Func(_, _) => {
if let Vector(ref values, _) = a[0].apply(vec![]).unwrap() {
if let ZKScalar(a0) = values[0] {
Ok(Bool(a0.is_zero()))
} else {
error(
&format!(
"scalar is zero expect (zkscalar or string) found \n {:?}",
a
)
.to_string(),
)
}
} else {
error(
&format!(
"scalar is zero expect (zkscalar or string) found \n {:?}",
a
)
.to_string(),
)
}
}
ZKScalar(a0) => {
let z0 = a0.clone();
Ok(Bool(z0.is_zero()))
}
Str(a0) => {
let s0 = bls12_381::Scalar::from_string(&a0);
Ok(Bool(s0.is_zero()))
}
_ => error(
&format!(
"scalar is zero expect (zkscalar or string) found \n {:?}",
a
)
.to_string(),
),
}
}
fn add_scalar(a: MalArgs) -> MalRet {
println!("add_scalar {:?}", a);
match (a[0].clone(), a[1].clone()) {
(Func(_, _), ZKScalar(a1)) => {
if let Vector(ref values, _) = a[0].apply(vec![]).unwrap() {
if let ZKScalar(mut a0) = values[0] {
a0.add_assign(a1);
Ok(ZKScalar(a0))
} else {
error("scalar add expect (zkscalar, zkscalar) found (func, zkscalar)")
}
} else {
error("scalar add expect (zkscalar, zkscalar)")
}
}
(Func(_, _), Str(a1)) => {
if let Vector(ref values, _) = a[0].apply(vec![]).unwrap() {
if let ZKScalar(mut a0) = values[0] {
let s1 = bls12_381::Scalar::from_string(&a1);
a0.add_assign(s1);
Ok(ZKScalar(a0))
} else {
error("scalar add expect (zkscalar, zkscalar) found (func, zkscalar)")
}
} else {
error("scalar add expect (zkscalar, zkscalar)")
}
}
(ZKScalar(a0), ZKScalar(a1)) => {
let (mut z0, z1) = (a0.clone(), a1.clone());
z0.add_assign(z1);
Ok(ZKScalar(z0))
}
(Str(a0), Str(a1)) => {
let (mut s0, s1) = (
bls12_381::Scalar::from_string(&a0),
bls12_381::Scalar::from_string(&a1),
);
s0.add_assign(s1);
Ok(ZKScalar(s0))
}
(Str(a0), ZKScalar(a1)) => {
let (mut s0, s1) = (bls12_381::Scalar::from_string(&a0), a1);
s0.add_assign(s1);
Ok(ZKScalar(s0))
}
(ZKScalar(a1), Str(a0)) => {
let (mut s0, s1) = (bls12_381::Scalar::from_string(&a0), a1);
s0.add_assign(s1);
Ok(ZKScalar(s0))
}
// (List(a0, _), ZKScalar(mut a1)) => {
// let first_slice = a0.to_vec();
// let result = first_slice[0].apply(first_slice[1..].to_vec());
// println!("result {:?}", result);
// if let ZKScalar(value) = result.unwrap() {
// a1.add_assign(value);
// }
// Ok(ZKScalar(a1))
// }
_ => error(&format!("scalar add expect (zkscalar, zkscalar) found \n {:?}", a).to_string()),
}
}
fn seq(a: MalArgs) -> MalRet {
match a[0] {
List(ref v, _) | Vector(ref v, _) if v.len() == 0 => Ok(Nil),
List(ref v, _) | Vector(ref v, _) => Ok(list!(v.to_vec())),
Str(ref s) if s.len() == 0 => Ok(Nil),
Str(ref s) if !a[0].keyword_q() => {
Ok(list!(s.chars().map(|c| { Str(c.to_string()) }).collect()))
}
Nil => Ok(Nil),
_ => error("seq: called with non-seq"),
}
}
fn gen_rand(_a: MalArgs) -> MalRet {
let mut rng = rand::thread_rng();
Ok(MalVal::Int(rng.gen::<i64>()))
}
fn scalar_rnd(_a: MalArgs) -> MalRet {
let randomness_value: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
let value = bls12_381::Scalar::from_bytes(&randomness_value.to_bytes());
Ok(MalVal::ZKScalar(value.unwrap()))
}
pub fn ns() -> Vec<(&'static str, MalVal)> {
vec![
("=", func(|a| Ok(Bool(a[0] == a[1])))),
("throw", func(|a| Err(ErrMalVal(a[0].clone())))),
("nil?", func(fn_is_type!(Nil))),
("true?", func(fn_is_type!(Bool(true)))),
("false?", func(fn_is_type!(Bool(false)))),
("symbol", func(symbol)),
("symbol?", func(fn_is_type!(Sym(_)))),
(
"string?",
func(fn_is_type!(Str(ref s) if !s.starts_with("\u{29e}"))),
),
("keyword", func(|a| a[0].keyword())),
(
"keyword?",
func(fn_is_type!(Str(ref s) if s.starts_with("\u{29e}"))),
),
("number?", func(fn_is_type!(Int(_)))),
(
"fn?",
func(fn_is_type!(MalFunc{is_macro,..} if !is_macro,Func(_,_))),
),
(
"macro?",
func(fn_is_type!(MalFunc{is_macro,..} if is_macro)),
),
("pr-str", func(|a| Ok(Str(pr_seq(&a, true, "", "", " "))))),
("str", func(|a| Ok(Str(pr_seq(&a, false, "", "", ""))))),
(
"prn",
func(|a| {
println!("{}", pr_seq(&a, true, "", "", " "));
Ok(Nil)
}),
),
(
"println",
func(|a| {
println!("{}", pr_seq(&a, false, "", "", " "));
Ok(Nil)
}),
),
("read-string", func(fn_str!(|s| { read_str(s) }))),
("slurp", func(fn_str!(|f| { slurp(f) }))),
("<", func(fn_t_int_int!(Bool, |i, j| { i < j }))),
("<=", func(fn_t_int_int!(Bool, |i, j| { i <= j }))),
(">", func(fn_t_int_int!(Bool, |i, j| { i > j }))),
(">=", func(fn_t_int_int!(Bool, |i, j| { i >= j }))),
("+", func(add_scalar)),
("-", func(sub_scalar)),
("*", func(mul_scalar)),
("/", func(div_scalar)),
("time-ms", func(time_ms)),
("i+", func(fn_t_int_int!(Int, |i, j| { i + j }))),
("i-", func(fn_t_int_int!(Int, |i, j| { i - j }))),
("i*", func(fn_t_int_int!(Int, |i, j| { i * j }))),
("i/", func(fn_t_int_int!(Int, |i, j| { i / j }))),
("i<", func(fn_t_int_int!(Bool, |i, j| { i < j }))),
("i<=", func(fn_t_int_int!(Bool, |i, j| { i <= j }))),
("i>", func(fn_t_int_int!(Bool, |i, j| { i > j }))),
("i>=", func(fn_t_int_int!(Bool, |i, j| { i >= j }))),
("time-ms", func(time_ms)),
("sequential?", func(fn_is_type!(List(_, _), Vector(_, _)))),
("list", func(|a| Ok(list!(a)))),
("list?", func(fn_is_type!(List(_, _)))),
("vector", func(|a| Ok(vector!(a)))),
("vector?", func(fn_is_type!(Vector(_, _)))),
("hash-map", func(|a| hash_map(a))),
("map?", func(fn_is_type!(Hash(_, _)))),
("assoc", func(assoc)),
("dissoc", func(dissoc)),
("get", func(get)),
("contains?", func(contains_q)),
("keys", func(keys)),
("vals", func(vals)),
("vec", func(vec)),
("cons", func(cons)),
("concat", func(concat)),
("empty?", func(|a| a[0].empty_q())),
("nth", func(nth)),
("first", func(first)),
("last", func(last)),
("rest", func(rest)),
("count", func(|a| a[0].count())),
("apply", func(apply)),
("map", func(map)),
("conj", func(conj)),
("seq", func(seq)),
("meta", func(|a| a[0].get_meta())),
("with-meta", func(|a| a[0].clone().with_meta(&a[1]))),
("atom", func(|a| Ok(atom(&a[0])))),
("atom?", func(fn_is_type!(Atom(_)))),
("deref", func(|a| a[0].deref())),
("reset!", func(|a| a[0].reset_bang(&a[1]))),
("swap!", func(|a| a[0].swap_bang(&a[1..].to_vec()))),
("unpack-bits", func(unpack_bits)),
("range", func(range)),
("scalar::one", func(scalar_one)),
("scalar::one::neg", func(scalar_one_neg)),
("neg", func(negate_from)),
("scalar::zero", func(scalar_zero)),
("scalar", func(scalar_from)),
("square", func(scalar_square)),
("cs::one", func(cs_one)),
("second", func(second)),
("genrand", func(gen_rand)),
("double", func(scalar_double)),
("invert", func(scalar_invert)),
("zero?", func(scalar_is_zero)),
("rnd-scalar", func(scalar_rnd)),
]
}

View File

@@ -1,85 +0,0 @@
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
// use fnv::FnvHashMap;
use crate::types::MalErr::ErrString;
use crate::types::MalVal::{List, Nil, Sym, Vector};
use crate::types::{error, MalErr, MalRet, MalVal};
#[derive(Debug)]
pub struct EnvStruct {
data: RefCell<HashMap<String, MalVal>>,
pub outer: Option<Env>,
}
pub type Env = Rc<EnvStruct>;
// TODO: it would be nice to use impl here but it doesn't work on
// a deftype (i.e. Env)
pub fn env_new(outer: Option<Env>) -> Env {
Rc::new(EnvStruct {
data: RefCell::new(HashMap::default()),
outer: outer,
})
}
// TODO: mbinds and exprs as & types
pub fn env_bind(outer: Option<Env>, mbinds: MalVal, exprs: Vec<MalVal>) -> Result<Env, MalErr> {
let env = env_new(outer);
match mbinds {
List(binds, _) | Vector(binds, _) => {
for (i, b) in binds.iter().enumerate() {
match b {
Sym(s) if s == "&" => {
env_set(&env, binds[i + 1].clone(), list!(exprs[i..].to_vec()))?;
break;
}
_ => {
env_set(&env, b.clone(), exprs[i].clone())?;
}
}
}
Ok(env)
}
_ => Err(ErrString("env_bind binds not List/Vector".to_string())),
}
}
pub fn env_find(env: &Env, key: &str) -> Option<Env> {
match (env.data.borrow().contains_key(key), env.outer.clone()) {
(true, _) => Some(env.clone()),
(false, Some(o)) => env_find(&o, key),
_ => None,
}
}
pub fn env_get(env: &Env, key: &MalVal) -> MalRet {
match key {
Sym(ref s) => match env_find(env, s) {
Some(e) => Ok(e
.data
.borrow()
.get(s)
.ok_or(ErrString(format!("'{}' not found", s)))?
.clone()),
_ => error(&format!("'{}' not found", s)),
},
_ => error("Env.get called with non-Str"),
}
}
pub fn env_set(env: &Env, key: MalVal, val: MalVal) -> MalRet {
match key {
Sym(ref s) => {
env.data.borrow_mut().insert(s.to_string(), val.clone());
Ok(val)
}
_ => error("Env.set called with non-Str"),
}
}
pub fn env_sets(env: &Env, key: &str, val: MalVal) {
env.data.borrow_mut().insert(key.to_string(), val);
}

View File

@@ -1,52 +0,0 @@
(println "jubjub-add-macro.lisp")
(load-file "util.lisp")
(defmacro! jubjub-add (fn* [param1 param2 param3 param4]
(let* [u1 (gensym) v1 (gensym) u2 (gensym) v2 (gensym)
EDWARDS_D (gensym) U (gensym) A (gensym) B (gensym)
C (gensym) u3 (gensym) v3 (gensym)] (
`(def! ~u1 (alloc ~u1 param1))
`(def! ~v1 (alloc ~v1 param2))
`(def! ~u2 (alloc ~u2 param3))
`(def! ~v2 (alloc ~v2 param4))
`(def! ~EDWARDS_D (alloc-const ~EDWARDS_D (scalar "2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1")))
`(def! ~U (alloc ~U (* (+ ~u1 ~v1) (+ ~u2 ~v2))))
`(def! ~A (alloc ~A (* ~v2 ~u1)))
`(def! ~B (alloc ~B (* ~u2 ~v1)))
`(def! ~C (alloc ~C (* ~EDWARDS_D (* ~A ~B))))
`(def! ~u3 (alloc-input ~u3 (/ (+ ~A ~B) (+ scalar::one ~C))))
`(def! ~v3 (alloc-input ~v3 (/ (- (- ~U ~A) ~B) (- scalar::one ~C))))
`(enforce
((scalar::one ~u1) (scalar::one ~v1))
((scalar::one ~u2) (scalar::one ~v2))
(scalar::one ~U)
)
`(enforce
(~EDWARDS_D ~A)
(scalar::one ~B)
(scalar::one ~C)
)
`(enforce
((scalar::one cs::one)(scalar::one ~C))
(scalar::one ~u3)
((scalar::one ~A) (scalar::one ~B))
)
`(enforce
((scalar::one cs::one) (scalar::one::neg ~C))
(scalar::one ~v3)
((scalar::one ~U) (scalar::one::neg ~A) (scalar::one::neg ~B))
)
)
;; improve return values
)
))
(def! param4 (scalar "015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891"))
(def! param3 (scalar "15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e"))
(def! param2 (scalar "015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891"))
(def! param1 (scalar "15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e"))
(prove (
(def! result1 (jubjub-add param1 param2 param3 param4))
(println 'jubjub-result result1)
))

View File

@@ -1,79 +0,0 @@
(println "jubjub-add.lisp")
(load-file "util.lisp")
(defmacro! zk-square (fn* [var] (
(let* [v1 (gensym)
v2 (gensym)] (
`(alloc ~v1 ~var)
`(alloc ~v2 (square ~var))
`(enforce
(scalar::one ~v1)
(scalar::one ~v1)
(scalar::one ~v2)
)
)
))
))
;; -u^2 + v^2 = 1 + du^2v^2
(defmacro! zk-witness (fn* [val1 val2] (
(let* [v (gensym)
u (gensym)
u2v2 (gensym)] (
`(alloc ~v1 ~var)
`(alloc ~v2 (square ~var))
`(enforce
(scalar::one ~v1)
(scalar::one ~v1)
(scalar::one ~v2)
)
)
))
))
(defmacro! jubjub-add (fn* [param1 param2 param3 param4]
(let* [u1 (gensym) v1 (gensym) u2 (gensym) v2 (gensym)
EDWARDS_D (gensym) U (gensym) A (gensym) B (gensym)
C (gensym) u3 (gensym) v3 (gensym)] (
`(def! ~u1 (alloc ~u1 param1))
`(def! ~v1 (alloc ~v1 param2))
`(def! ~u2 (alloc ~u2 param3))
`(def! ~v2 (alloc ~v2 param4))
`(def! ~EDWARDS_D (alloc-const ~EDWARDS_D (scalar "2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1")))
`(def! ~U (alloc ~U (* (+ ~u1 ~v1) (+ ~u2 ~v2))))
`(def! ~A (alloc ~A (* ~v2 ~u1)))
`(def! ~B (alloc ~B (* ~u2 ~v1)))
`(def! ~C (alloc ~C (* ~EDWARDS_D (* ~A ~B))))
`(def! ~u3 (alloc-input ~u3 (/ (+ ~A ~B) (+ scalar::one ~C))))
`(def! ~v3 (alloc-input ~v3 (/ (- (- ~U ~A) ~B) (- scalar::one ~C))))
`(enforce
((scalar::one ~u1) (scalar::one ~v1))
((scalar::one ~u2) (scalar::one ~v2))
(scalar::one ~U)
)
`(enforce
(~EDWARDS_D ~A)
(scalar::one ~B)
(scalar::one ~C)
)
`(enforce
((scalar::one cs::one)(scalar::one ~C))
(scalar::one ~u3)
((scalar::one ~A) (scalar::one ~B))
)
`(enforce
((scalar::one cs::one) (scalar::one::neg ~C))
(scalar::one ~v3)
((scalar::one ~U) (scalar::one::neg ~A) (scalar::one::neg ~B))
)
)
;; improve return values
)
))
(prove
(
(def! result-witness (zk-witness param1 param2))
(println 'result-witness (nth (nth result-witness 0) 1))
)
)

View File

@@ -1,321 +0,0 @@
(load-file "util.lisp")
(def! zk-not-small-order? (fn* [u v] (
(def! first-doubling (last (last (zk-double u v))))
(def! second-doubling (last (last
(zk-double (get first-doubling "u3") (get first-doubling "v3")))))
(def! third-doubling (last (last
(zk-double (get second-doubling "u3") (get second-doubling "v3")))))
(zk-nonzero? (get third-doubling "u3"))
)
)
)
(defmacro! zk-nonzero? (fn* [var] (
(let* [inv (gensym)
v1 (gensym)] (
`(alloc ~inv (invert ~var))
`(alloc ~v1 ~var)
`(enforce
(scalar::one ~v1)
(scalar::one ~inv)
(scalar::one cs::one)
)
)
))
))
(defmacro! zk-square (fn* [var] (
(let* [v1 (gensym)
v2 (gensym)] (
`(alloc ~v1 ~var)
`(def! output (alloc-input ~v2 (square ~var)))
`(enforce
(scalar::one ~v1)
(scalar::one ~v1)
(scalar::one ~v2)
)
`{ "v2" output }
)
))
))
(defmacro! zk-mul (fn* [val1 val2] (
(let* [v1 (gensym)
v2 (gensym)
var (gensym)] (
`(alloc ~v1 ~val1)
`(alloc ~v2 ~val2)
`(def! result (alloc-input ~var (* ~val1 ~val2)))
`(enforce
(scalar::one ~v1)
(scalar::one ~v2)
(scalar::one ~var)
)
`{ "result" result }
)
))
))
(defmacro! zk-witness (fn* [val1 val2] (
(let* [u2 (gensym)
v2 (gensym)
u2v2 (gensym)
EDWARDS_D (gensym)] (
`(def! ~EDWARDS_D (alloc-const ~EDWARDS_D (scalar "2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1")))
`(def! ~u2 (alloc ~u2 (get (nth (nth (zk-square ~val1) 0) 3) "v2")))
`(def! ~v2 (alloc ~v2 (get (nth (nth (zk-square ~val2) 0) 3) "v2")))
`(def! result (alloc-input ~u2v2 (get (last (last (zk-mul ~u2 ~v2))) "result")))
`(enforce
((scalar::one::neg ~u2) (scalar::one ~v2))
(scalar::one cs::one)
((scalar::one cs::one) (~EDWARDS_D ~u2v2))
)
`{ "result" result }
)
))
))
(defmacro! zk-double (fn* [val1 val2] (
(let* [u (gensym)
v (gensym)
u3 (gensym)
v3 (gensym)
T (gensym)
A (gensym)
C (gensym)
EDWARDS_D (gensym)] (
`(def! ~EDWARDS_D (alloc-const ~EDWARDS_D (scalar "2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1")))
`(def! ~u (alloc ~u ~val1))
`(def! ~v (alloc ~v ~val2))
`(def! ~T (alloc ~T (* (+ ~val1 ~val2) (+ ~val1 ~val2))))
`(def! ~A (alloc ~A (* ~u ~v)))
`(def! ~C (alloc ~C (* (square ~A) ~EDWARDS_D)))
`(def! ~u3 (alloc-input ~u3 (/ (double ~A) (+ scalar::one ~C))))
`(def! ~v3 (alloc-input ~v3 (/ (- ~T (double ~A)) (- scalar::one ~C))))
`(enforce
((scalar::one ~u) (scalar::one ~v))
((scalar::one ~u) (scalar::one ~v))
(scalar::one ~T)
)
`(enforce
(~EDWARDS_D ~A)
(scalar::one ~A)
(scalar::one ~C)
)
`(enforce
((scalar::one cs::one) (scalar::one ~C))
(scalar::one ~u3)
((scalar::one ~A) (scalar::one ~A))
)
`(enforce
((scalar::one cs::one) (scalar::one::neg ~C))
(scalar::one ~v3)
((scalar::one ~T) (scalar::one::neg ~A) (scalar::one::neg ~A))
)
{ "u3" u3, "v3" v3 }
)
))
))
(defmacro! conditionally-select (fn* [val1 val2 val3] (
(let* [u-prime (gensym)
v-prime (gensym)
u (gensym)
v (gensym)
condition (gensym)
] (
`(def! ~u (alloc ~u ~val1))
`(def! ~v (alloc ~v ~val2))
`(def! ~condition (alloc ~condition ~val3))
`(def! ~u-prime (alloc-input ~u-prime (* ~u ~condition)))
`(def! ~v-prime (alloc-input ~v-prime (* ~v ~condition)))
`(enforce
(scalar::one ~u)
(scalar::one ~condition)
(scalar::one ~u-prime)
)
`(enforce
(scalar::one ~v)
(scalar::one ~condition)
(scalar::one ~v-prime)
)
{ "u-prime" u-prime, "v-prime" v-prime }
)
))))
(defmacro! jj-add (fn* [param1 param2 param3 param4]
(let* [u1 (gensym) v1 (gensym) u2 (gensym) v2 (gensym)
EDWARDS_D (gensym) U (gensym) A (gensym) B (gensym)
C (gensym) u3 (gensym) v3 (gensym)] (
;; debug
;; `(println 'jj-add ~param1 ~param2 ~param3 ~param4)
`(def! ~u1 (alloc ~u1 ~param1))
`(def! ~v1 (alloc ~v1 ~param2))
`(def! ~u2 (alloc ~u2 ~param3))
`(def! ~v2 (alloc ~v2 ~param4))
`(def! ~EDWARDS_D (alloc-const ~EDWARDS_D (scalar "2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1")))
`(def! ~U (alloc ~U (* (+ ~u1 ~v1) (+ ~u2 ~v2))))
`(def! ~A (alloc ~A (* ~v2 ~u1)))
`(def! ~B (alloc ~B (* ~u2 ~v1)))
`(def! ~C (alloc ~C (* ~EDWARDS_D (* ~A ~B))))
`(def! ~u3 (alloc-input ~u3 (/ (+ ~A ~B) (+ scalar::one ~C))))
`(def! ~v3 (alloc-input ~v3 (/ (- (- ~U ~A) ~B) (- scalar::one ~C))))
`(enforce
((scalar::one ~u1) (scalar::one ~v1))
((scalar::one ~u2) (scalar::one ~v2))
(scalar::one ~U)
)
`(enforce
(~EDWARDS_D ~A)
(scalar::one ~B)
(scalar::one ~C)
)
`(enforce
((scalar::one cs::one)(scalar::one ~C))
(scalar::one ~u3)
((scalar::one ~A) (scalar::one ~B))
)
`(enforce
((scalar::one cs::one) (scalar::one::neg ~C))
(scalar::one ~v3)
((scalar::one ~U) (scalar::one::neg ~A) (scalar::one::neg ~B))
)
`{ "u3" u3, "v3" v3 }
)
)
))
(defmacro! zk-boolean (fn* [val] (
(let* [var (gensym)] (
`(alloc ~var ~val)
`(enforce
(scalar::one cs::one) (scalar::one ~var)
(scalar::one ~var)
()
)
)
))))
(def! jj-mul (fn* [u v b] (
(def! result (unpack-bits b))
(eval (map zk-boolean result))
(def! val (last (last (zk-double u v))))
(def! acc 0)
(dotimes (count result) (
(def! u3 (get val "u3"))
(def! v3 (get val "v3"))
(def! r (nth result acc))
(def! cond-result (last (last (conditionally-select u3 v3 r))))
(def! u-prime (get cond-result "u-prime"))
(def! v-prime (get cond-result "v-prime"))
(def! add-result (last (jj-add u3 v3 u-prime v-prime)))
(def! u-add (get add-result "u3"))
(def! v-add (get add-result "v3"))
(def! val (last (last (zk-double u-add v-add))))
(def! acc (i+ acc 1))
))
(val)
;; { "u3" (get val "u3"), "v3" (get val "v3") }
)))
(load-file "mimc-constants.lisp")
(defmacro! mimc-macro (fn* [left-value right-value acc] (
(let* [tmp-xl (gensym2 'tmp_xl)
xl-new-value (gensym2 'xl_new_value)
cur-mimc-const (gensym2 'cur_mimc_const)
xl (gensym2 'xl)
xr (gensym2 'xr)] (
`(def! ~xl (alloc ~xl ~left-value))
`(def! ~xr (alloc ~xr ~right-value))
`(def! ~cur-mimc-const (alloc-const ~cur-mimc-const (nth mimc-constants ~acc)))
`(def! ~tmp-xl (alloc ~tmp-xl (square (+ ~cur-mimc-const ~xl))))
`(enforce
((scalar::one ~xl) (~cur-mimc-const cs::one))
((scalar::one ~xl) (~cur-mimc-const cs::one))
(scalar::one ~tmp-xl)
)
`(def! new-value (+ (* ~tmp-xl (+ ~cur-mimc-const ~xl)) ~xr))
`(if (= ~acc 321)
(def! ~xl-new-value (alloc-input ~xl-new-value new-value))
(def! ~xl-new-value (alloc ~xl-new-value new-value))
)
`(enforce
(scalar::one ~tmp-xl)
((scalar::one ~xl) (~cur-mimc-const cs::one))
((scalar::one ~xl-new-value) (scalar::one::neg ~xr))
)
`{ "left" new-value }
)
))))
(def! mimc (fn* [left right] (
(def! acc 0)
(def! xl left)
(def! xr right)
(dotimes 322 (
(def! result (mimc-macro xl xr acc))
(def! result-value (get (last (last result)) "left"))
(println acc)
(println xl xr)
(println result-value)
(def! xr xl)
(def! xl result-value)
(def! acc (i+ acc 1))
))
)))
(def! mint-contract (fn* [public-u public-v] (
(def! randomness (rnd-scalar))
(def! witness-result (zk-witness public-u public-v))
(def! not-small-order (zk-not-small-order? public-u public-v))
(def! g-vcr-u (alloc-input "g-vcr-u" public-u))
(def! g-vcr-v (alloc-input "g-vcr-v" public-v))
(def! mul-result (last (last (jj-mul g-vcr-u g-vcr-v randomness))))
(def! rcvu (alloc "rcvu" (get mul-result "u3")))
(def! rcvr (alloc "rcvr" (get mul-result "v3")))
(enforce
(scalar::one rcvu)
(scalar::one cs::one)
(scalar::one rcvu)
)
(enforce
(scalar::one rcvr)
(scalar::one cs::one)
(scalar::one rcvr)
)
)))
(prove
(
(def! param-u (scalar "6800f4fa0f001cfc7ff6826ad58004b4d1d8da41af03744e3bce3b7793664337"))
(def! param-v (scalar "6d81d3a9cb45dedbe6fb2a6e1e22ab50ad46f1b0473b803b3caefab9380b6a8b"))
(mint-contract param-u param-v)
)
)
;; following some examples
;; (def! left (scalar "15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e"))
;; (def! right (scalar "015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891"))
;; (mimc left right)
;; (def! param3 (rnd-scalar))
;; (jj-mul param-u param-v param3)
;; (def! param3 (rnd-scalar))
;; (def! param-u (scalar "6800f4fa0f001cfc7ff6826ad58004b4d1d8da41af03744e3bce3b7793664337"))
;; (def! param-v (scalar "6d81d3a9cb45dedbe6fb2a6e1e22ab50ad46f1b0473b803b3caefab9380b6a8b"))
;; (jj-mul param-u param-v param3)
;; (def! param3 (rnd-scalar))
;; (println 'rnd-scalar param3)
;; (def! param-u (scalar "6800f4fa0f001cfc7ff6826ad58004b4d1d8da41af03744e3bce3b7793664337"))
;; (def! param-v (scalar "6d81d3a9cb45dedbe6fb2a6e1e22ab50ad46f1b0473b803b3caefab9380b6a8b"))
;; (println (zk-mul param1 param2))
;; (jj-mul param-u param-v param3)
;; (println (zk-mul param1 param2))
;; (def! param1 (scalar 3))
;; (def! param2 (scalar 9))
;; (println (zk-square param1))
;; (println (zk-mul param1 param2))
;; (println 'witness (zk-witness param-u param-v))
;; (println 'double (last (last (zk-double param-u param-v))))
;; (println 'nonzero (zk-nonzero? param3))
;; (println 'not-small-order? (zk-not-small-order? param-u param-v))

View File

@@ -1,323 +0,0 @@
(def! mimc-constants ("4699afdd3f9ce9916eaffcfbef597c5009ae9d3209c3b15feb6928a4a8d4b59e"
"41e2431761fee4a40b468524d91b3d64590b3c242de10d18f55f0c5e3883ef02"
"5a04a1ea758bf1cc1140fcec1ce2c9d68da53d6cf7ee8dfeedfb2ee45db08c27"
"2e4b930078e93e73581d7b71120a8e8b9627955a0aabf139bbfa5feceaab2e3b"
"6a9db69e4fd0a3f94402cf22076bd18300c344c69bf665542129ad887f0030ab"
"4458f2de4e16ce2ead3fe9dd164cca36d2b70a25e71f55cf0c51ca553a4f83ad"
"04f539ab6ea2d344049219c720a16c4e6033f8360b124519fdbb6d441428143b"
"6b9c7b12a4b3cf92e2f2b386426058709573f9abdf1bcc5411dacd7ea0eaf8f3"
"4375e3120921697155b3ea15c32b9412adce3a8ff8e28e1b8c95935cc71ad853"
"041854bb643e9e5e5d8aa6e828dc4c732c8fa24192a160f40da85737372c5d0c"
"65d9cc7ab2a2060d198d66310a902bddeeb7f5150173190036d2fae68de1c2b9"
"1e7d2b472c6a40254a228b0543aff318084e7f6152617a6cf7fc405d917bfc37"
"35293381012ebaf649d8c6db4e4d5e594bd114c99c234ddff7b9b5f6f8a9ec36"
"3a50794418ac54a1467578ed61e34d8be5d52c5f188f42955fe8d5e257ad3e89"
"446d905f60110dbd51129896a63a0e34bb0502101ad6311998ad2dfd74818277"
"3eee70356bab144c54b5fc1095f9bce59c727a57a5582dcbbd5c3afc3c61ceca"
"40b08ae056833e12c82f7e15e2dc72febc15d3275b51ec70afaffa6ce8bbb3d0"
"205923e6eb137869a552b4857bb64f946c912f3335a94291ebb8b29ecd3e6034"
"2a6aebced756f7e33c466bca2169ba24c471a088c8363fe0a966a223fd3b59ea"
"566efaf4e022036a8e073fd9812376888ac9f37c794daebe3fa77b1a87bf109e"
"1ee814f2660e7272712d588477e458c06f8f06950402e97c542d3682ad5f9aed"
"257fe0ace4965622be247dba9185f108707f4ab16c910c03c565afab43b0fb4f"
"43e156f0cad02ff6b763645c97663ab72229bb0a34f975681359797ccd58093c"
"317f43b78cc26f0332a3ec3ec187332d4de0f2baf04f62fe76bee9b11256130b"
"076ca6cd23830e3b3ece767b774e1b2243408098a7c5b816e7c616cb88f6b916"
"14e30a644f034c72cf40b1bc790200c2e8ab3e750e38f3fb0160188e817e4560"
"02eb02bfbac795a497a0882d66b718bb23de64f9fe7644179ddd3241cc407942"
"644f175cf6f2268d451e5188e467c508bc91d870646de9297911be2aedf26daf"
"14aef8f4f5499a0387e521a1c6064094590f149c52fb99e37b583434ca6bd46c"
"2ddc7c6bba8895913f3deee128bc63b5e34797274de80da775c4a0c810ac60e6"
"46adc33428a63a20459699183272b14797a5a7d1d66079701d214bced9a4be71"
"552847d9a2a5b03f726b277ba01ad61c0e28114667e7a9e11229b83224f74349"
"624921e44f5811f76c06ab74a11ad56e5241e4c597e9d172ee3c862bf6d4b1fd"
"506af906fab5f9407ee71824d72dfcd99115c5a2eb53b55a1d5877910a645282"
"514ddde7e75b27ae6f31efb7375bc209dcdd0ab4c277ee0f8b362cb5211def31"
"2e3be2e2a10f8e24b411902d9578d44e2a4a5042036ecc397e1cc5ab88e76329"
"61755a2f6a9729a3bd8d21aea98f4cf885aa1751a714e251a517395711674bf5"
"68f8f91713d81c2a6d601411447e944c27f7a1862855b940ef3521cbf4074e96"
"32e6b3dfaa0162846620ace97838a93f48999b5bbc078964687c795a9e5b71a0"
"3c783bf0caa35bd381603b9e3aa5dbcc4ed4fc93b03d69a49fa15286a6374f8d"
"4a3f322f033de27244d79dd5c6c2f34d84c24c917ce95cfb6458d72124280e70"
"3ee0abb7af79168e05566994017fade2d69bdb55c4253f996362b73d49f3f70e"
"15498a06e80c6060320e9a01292ee1a805c2aafd7b92f76b5f5e8be515e0a3b3"
"02424410de65455350831f5b1c3554626f6bbf373ed0f627b42f0d3ec2fdd487"
"5886da407f6014665272b45d213cb388987503398d407732f278c9a35267622d"
"15f6180f287d2ef5d9d057dc18eb7df732d97632bfb31e93ac065dcf0c67fd40"
"65f5dc85c9660f184a09ee768ae9af0f62911af31920d3b5c49ac0360d261441"
"65751a6bbccb0ea7fd79fe7231d03d2f14ec6a24c5d9c4a77d1a86acf3d027a9"
"4c21c6990442cb96b2ca684c9d427dc41090447248378f50b4de15b616f1f133"
"34cde97ef5c2459e29dbad8324fbefa5097f744f737cc59ad2681e49dfa43f99"
"5df3e3787510f9e2b32beb2fdf76fc6d646b3fb94d4ede65309762fc515ffb55"
"30394778b396dd8191e78cb7627636eb82b15b0de788c1e2db2788b05caedd8b"
"695a64cc6953c658f40c1c2666715790410e302d3d902fcb809924896c2d1f4e"
"6a4fe5863990f4b4d588841b0e52c4dc7a8c4644edfec7c721ab66b162ec5de9"
"62e4428cb1856ae809589806e5e7869ab0fb818d6c0a696d94ee616fe549400e"
"0b1e8a6d6581c13b6888d0bd9816bda3695f917d03510d9b42452f3501e3d55a"
"5e5a2b767f853d0f0bf0e3cae872fb942065db112cb48a12dbce3ce4da28aa87"
"2c1c59e21a9741edbaf1e5a275c573bbeb395c6a79abdd0e532e000298dc8c00"
"25d648572388935cac47095b4f38b3ebe6519766a0d03bf7de9b4368b7bc1b58"
"475a00fdc58c8a7092cae8942af520dd5e0f476dc469f0c3e908da68be55e6ff"
"3fe62baf8e0a5286b0055e16e712ad06d233fa71fb374557d4c3d585e33dd37b"
"54d74923f593c55659f92b34bf5c05a400187e143850173786c8a1dd2f3a1283"
"6aa3afe84262b6c5bc8994a2c0e66a64a534904efcf47ead067fa09cd2d58a6a"
"2069d079cd963cec28ccac413172576ace57da0b4ab502c11289fff6ff2de6eb"
"364b3a05a8b1271aa61d5894b51a445c5896e86a535869b70e56e1e0f7f49f42"
"1c904753197233afda76661025e67f6a8e7a5c209292e151a7f34119397c281f"
"45f6d1ed8bc4395ccc6cfc90a1cf5f636248e966d82d040d795014f5d184b3ac"
"1bdbb396d84fe4c8b5b230e1c925e9f0f5f88faea9b713b319c7c11c307cbdbe"
"347c35497a65e93d8f4ec06c1546991841fd680868e145849195e38ef783d1a4"
"1d9c23cb0d4a20c384d629c6e706ebaf12fe0fc4eb0860c8175e687742e941cc"
"59378cc30bc5948d66a6f1671e84e2e9ef342e0e3dd682015d93f96a68159f3a"
"59992c34faff2238e03be3d6e87086a427e6eef2c5647a690363a9ddc0c82d67"
"60b13d9cae9b2504ca982c50b14ee5a628d40832bab95108e6640b9a8ef8a853"
"4cea35b5ebf7d7956c0c592d4238051c37bdb8bcb4c08fa29239ffaff00793bf"
"25344d0db88e9df26d216c287ddc36a958ba1e4d4c05a9cd59715de870d47e36"
"19a1c0a1f3aa80db57b014a2dad65eecf645fcd442a09b97e78d044a50ba58c3"
"32a6b9ba275d0204fd0e3de5fed3eac823aa8ce0ef5eca627fe92030e4506fe3"
"4e4f1056e9e3b8861117ba8bba1a1c37e784ef9e1358473aa55156e3b1523dff"
"710f51f9f3866ab261df0fad6ad3986f75d9990bf7776f4e4775f9c8f95045c2"
"48623d21c816d6a47a6339d9bda7ff31f2b32b8491c72967b93f2734ec37f64d"
"69aae3a126e0625c52d05e8c98ea912f56a582419cef7f13f31be66ec14bd43c"
"2f7264fc97a0ff9188c506d5df4bf3d4f28cb1d12fa2767e18d023f8a7e907b0"
"54bf8632b89211a06bbf9c0ee5ba2328b1f2cbc1892b76282599c0fb432d761d"
"0deb44dd3e20b34cfb473944f4f8f07b4d337da0fc18021777c983bf3e4e7f44"
"37a108a7b9e612231e21f0b4c7186163e3cc59325cbb17a39e1e25b4c4345dba"
"317515ddac6dcb33a4ac68d4c02c6d93d147b61cd892474292258ebceaf5ce83"
"38e225b4f524fa89f414976687473eb4c5f3edfe983dbdd07d3e8486f3b93c0a"
"636b27e505a14fb8362beb2e436582db991e3089e6edaeb9aaba3d67f58c8c60"
"28fd1afb8cf1e9c7594b5b8d6b50ff1f81aa19f211c5c271f2181836158bb625"
"1a8cf4f8569d80ca7d878d7a76d959956ac5e7edb37fbcfd2f5d130e3841dbc0"
"2cfbffcc25a0a01ab7cd1e700030d0e363ac170dd000397fa83d107a6d12bd54"
"325355d6824f71f550b102c6fa6c8c129de58d325174c5981c562e606a58c55f"
"1716f66b4ad2388a23ce111dd5ff7c04d4478dd81930050fdf0c4a90fcd6d381"
"02992cefec8ee9bef9602858d51c87a2c4180d9fe0c02e6c6003531010793572"
"2132b3fd309dd69a9f3c39b450534d857721dd5a2bcb23b479a29b08e8f8551e"
"369986658b8e7e4f990fd6fc09b99a056d81ee47c7a9e46b4109d8af0956678c"
"25e00309f0c3097a6500df9ed5587ec128b20a97379814b4a0522f7e775a4548"
"529a8ecdddfb500c68b664f7303dad768da802c29a933801b2199cf74a3470f5"
"3cf98a6dc8290785ede38da9455dbd28a64a1bda35a48d6c6b1b35ba6df3268b"
"127401f379aa992d492782910baee0fb331b3e9c1a66492c9b002a37999f356a"
"449dabe3e12e7b495e0421de157acbd4b3852cb824bba7171c8e3da565e3f95e"
"410d1d4fb041736101f5468ebdfd9380f2066593534339bc419f35d530c92cd7"
"09747f87db187d67e7881e1b64345754ec9bc9ec353e9b055bc377f1618ef17e"
"5fec471449175525c56b18200dd8ab96b2f9ee383849545628f0ceff76f631d8"
"0c7e402c723170d5dc5f15e229f4bacc5eb50b34dbfb6129215ee662288e159c"
"158896654586f5c3a34808ef7ab93def61fc9257d5b7631ed6869259a45d1d01"
"57ab3eab90ec38cfb23625e7110948e4b56e38a1ccc2cfffc344876d28aceddd"
"08d08f8650f5ca7bf03aad9a80ae09c697327a131827a9c2aec67d1d9f58064e"
"273607089f1e9c2b99812e032dfb62c359438c76556a15692a3de02b8c13df4d"
"55bf5cd5a1a89d7e3d1d274cc5b1b765e42a9eab5cfd32148c1633550ecfffce"
"5c4f6e0acb889fbb573583767535e95bc537641769c35063c0bd3a65812ade57"
"581faa1d0a57ef947001fd8e57eee26e645d15eebedb7ebb1d85581968544ca6"
"48b77ab45f5fb6d615bd759a6661097bb8a3b5c27ba35f1b127d2ee12f043bc4"
"590618389009da43c679b6254ae4cc86dbfa397981f4dff30e064e07bfdc9eab"
"3ef9bd95ccaa3c577ab98d3fad87fe69953bbbba6c8bbca0301a6c88e9bed8e6"
"2bc1dd87795feb2a5e8d98759371592ba7147ee4c2a3473d18c496ebe3721216"
"620ba5be31e353f1f3c72a4380f32c016f0746f5446f9e1743fb01fe6994051e"
"151d0bcf972db311553ef8da672b1c861d118e9b78da632d24c49d4a0fa177b7"
"01f1bda7ed65ad241d6fa13d8c5cb40cc335a0b2a31b433f2c65cb01e8dad5bc"
"4aec58578fdfd5e59d18063bdcc69086dae303518f5155facdc2824878862c53"
"1ca2d39cd13b6c690faf2be3da4d4517e28244fbf9ca0f8f4d80565205fb86f2"
"72432f39b454d6457ffae81f2e843df03c1526920384c50136beca0627f9054a"
"1910c2e6bb35a12e22ec46cd0db6185f352bf3581cf46d2f9c494daf8d94b993"
"4e47d6f9080e682d34ae07d5886c29869d16324c468782bea9c62334b583251f"
"3240024a0dd08da0c135caf8114ea8d333ab181e94a3a01edabb760a64adcee4"
"1669aabbd01c4541575f150981af0cf9a196e0b98908af53ea14b81734ecce5a"
"316aa08fd611919a73b60dc2b3175b3843f17035d71b9edf2f72c32850629574"
"4919d1e48c28eb1d36a689d8a5826c4ae4cd4e84a8347a9c9238b825a0b53a8e"
"4572211d4d1c8257d142ff2335eea65ccbf3177a982fed00931410f3bdf08c19"
"5d2d04f110bb9a50adf25427b232870f2be2307685f19df47f9b2f1bae984a04"
"472609c977c6854de75985c9154f70a7fda1843a38f10dd4985ab8dc353ad5a7"
"5c2ba4f8bec80b52e65afbe7b2ff41ad73542275e40acba8730403e9e33c7697"
"267614d22d526f429346fb2e9dcc4930880971780e85ef44a199feabe2b48227"
"1110d3da8ece3e4eda99c2d63f6724779af505b9527f0b191b34b5bfabbf5584"
"68fc77023c046909572d302630c6508922cbc03e6c6d9a05108bc8db71e045ff"
"1b6630a5ab959106f3951689fcbc6a757c97511d08a3d4652b8ee7eab820d575"
"2e34a9c19201971c6cffc366e7955b33d0b7dc59fbaf87cadeb8d0c099cfb541"
"060bd11957a053af7aec4b2c2caf7e227512d9e856552e5cf6f4ed4b04753bec"
"0d8a6987303d76b12f97eaeacfd783401ffef6ac2e994182eaa93843300385ae"
"0e9b15bfa73141c59edc9d11ec4ee316525ba53c4b91e4f1a8adb8d372e91dff"
"55215d958a6afccf90247026efb61dd9bae318cd31ad27746b227de8873add8c"
"4ccb674b94da03efd3404a424a422d42fd4f3a8b9f73de3aa7377e728400e797"
"256f31bdb0e0cad47ec44da9bdd1fc146d0284f1d71c596e12b0c690e202d1c4"
"60797d9977e8cf8484240c0ac4d3703818c096db8d61ca640bab83ea4e675919"
"57fd867a56f6fba130d5cd80d1aa2562ca3bdb6956892c0f66e8d9bbe1fe49e7"
"09115f248d518063beb8d89c11115a6b53ac2927b2eeb0c50b50b3e82c314e5e"
"6a10f8ecb4e14465b19148ae366be2452b809596eec80f4913a2240e5e89c98d"
"0399008978536884058e8b36c86b622d5da6cde04ceabb591fe8057153f6c7b2"
"2c7ba50ad84ce603d8206950a09277dbf59da814c5b5119763a208953d946812"
"02a697c90f23766d5fde4b61101665b865375243f1bde57522bcb4bcda33804d"
"3bba46c732127685e3a7c6963ec063f961bfa23dce70af06fbbdba02d295aa8a"
"206c47de6dfd8600586a42f98aea1284742671c605e7a274a306e188015e031d"
"608a94a91f8e4e1b0adf94c1af4992b0176fc84d8d79b881ec02d2613f4d9083"
"28f906b6e3e6d01ac90251789b81001bb5d96ec2f55be04354b37bd7211c8731"
"25c66f7f7c9db885d9f7d7b64bd555f7e2e939878a6f1f1056c0c5af008949a7"
"4992f08ef5816859cd16e02a367e55fb073cc08ba19fce061e83288caba6e308"
"432fd05cdbd6ce762396cc6b88f6db33f0e6daa1e4faf602a599575fe797979d"
"4961bcdf4ad6da150ed71fe78f84c9faaa28e63e378af83aedd33870e337c362"
"4d1025421a43054ecb8eab1d4ed666a8cfc7b3e1d3f5243bd945032b7ae19a1b"
"0eb68c99851461def5baf569dff154f8ac4591e8ad194f641dc5fcfbc157c07d"
"256cd6ef41e108838bc52d51af281be02ad6c5d2a3e6f49f2cb864bcf2397447"
"0df82b76b04d8813711f92ed2bc6dda5f32e4778b5f1b328bd3b2a3b82928645"
"73397a58cf55ae9d2b14647125725f053dc0a9d5d5599f67955b8b8ceb8c43d8"
"352a6762b6764cd234a5e7e24e1beaed50618b691be9e40d4b15813d6023439a"
"4ebe36c93f3561edd31170f6775e38889598f0b40a3a2967882b60c6bcf8d6f6"
"4af798462ebca10935795dcb09770d98e2a93bc25a99af876c1f080fdf04047e"
"6f9acbad33e5d972376f1f67457fb5565582c0cc233006fe51942c48479a3c9f"
"395558ce9453ad4999a1d87585bc88b08731882ae0ffbbec886db1cc3fc7ee62"
"17b48a7db220b2b4e4a3e9139168f050056e71049e4080ded3949222d3915dd2"
"13266faaffcb6e011f73a4065bb1f7bdc373571d1b9c0210674f4f9d18cdbf3f"
"0edbbed85597c4beb59685811f7f3c0ce807083c032e6c71e5869004bb37c93d"
"64a7409e0e833df31fb574e1c12f764ecf0e3d335cc53afcdc22ac13d7a81da8"
"730fbba0d85d06eabf3f517d4826457bacb2fa8c2f24168c1b026ada9eca5bf5"
"1ffdde6d216f269f8d25efca3b28590416ea7340d92df2c02d111e30302ba020"
"6551f0ba88e2b256f61e052c2ed98e5253fb7791614da7f7f10f9db1dbace96f"
"5a40abaaa2542543cd1710bab187798b01f6c7d93395e3a1cdaed5b8866018e9"
"7021fa2631484663ef5e14124c49b3078b460d77c9972b9f3aa8fe7bed79bed6"
"28e1b47a74ed1328c9cf0188bcce0e6bc8e32d808ad91d62d747382141e7c439"
"267bb1817a59e83c9cb67f740cb31fccde2ae0f6dc49745f826267f78136bc5a"
"6f2a6bdaf2152c1368e51b4d1ae3ce48bb8a62e00d92f2f9f21393c691243aee"
"00cd4b3d36b639b44a828c3dfe8e8da68a7cccaf7063fa92877683c0e5080869"
"3e8e056dee60929e925fdcd2395a9959202ef71b82a638fd1e3decba9051d016"
"651baeb3fea106c59cefec6a9c8973347a481a75b04f547d8d2f63a1ced57161"
"1e6ea48da02249378957d446d9603e4a1e0efd343426933d0cf5a1400148f654"
"5eb2faa76b282614614ae97db1e0bb722146ac8230739cf9abb35058ae7f6363"
"6400a9ba34a8ce081b7755a5241338c78c10c07ff6cc97ac94f29b23775922f3"
"5c475b1284568d5c55fae4840fd5bf9b9f8041fb4c75f3fd902681d97d4b09d2"
"037e3fa79fcab75541fe4ceed6404d2a89228694646835e0422fb558477fb128"
"39186a11b8693a21684796f4dd227523ac2782d6d23330d8287d77e19f106923"
"44b4264d680b2bfa7081436798dce5bc3b20bedf250dfb2103abdde5b3f24eb2"
"01fd3211afd7ab17103dd5a181b91982d83e69f9df9568ed132db65c23bfba2d"
"66bd19f66bf63ef557cd87c638d6a97f2853a284307ff04392e61b7a68e56b12"
"09e3ea8c3c87110454cb0045179ac850f74285652c6854351682cd1706b54f88"
"22b7ffce8814457850e403085d0f725dc72396144565f4542d5bf826f4627106"
"255b1285cd235b83bbdc8032f637a74bc8b33a798e2751969ebe67c593b578bb"
"5b568413938daa1acec17d776af723451fc067e63ed8a24d58cefc27ef7feca9"
"4fc38e950b447f3040484e58a7d106386da69400c9292640014886e33eb7596f"
"044e95a76627fade400c813061a56bd38ae137734ac1b7b11fce4a12eed6bb68"
"129d3939b05352392ee46921665e027d3cb9c9857f0b2f161bb1f0fdd58a74bf"
"327b98a9fc847d6b6d54a175aaed3678172d615d37cf1c4448c9d4588a2eb7c7"
"63675e996ad78bc6725b923b4cbeacf40f7d4b85bf38fd8b5ed0f63424779ab5"
"7374af204d7432c7954dbbd12ed973b79fd0a6d7109061ffd10ecb2f6942d5fd"
"0fdf70b408b29ce4bb3ef9a02c333ba7789fffbf2b17dc2ef4dce8714ada06a8"
"4373b306976a59fbd07f82bb44c4ee4e4a11806801960c5c18f32f7679321d3c"
"1b218fbc57953d8d44ab45c19993b223939a121a1e6bf87b4ca549e06699880a"
"09b95f647fc4e11ed6a4757be6287d3f4d6bbdc6da8173da072d7a5d046862b1"
"1def7155ba82eebd07611e2dd694a49dac9085004c1b4e9de2b4f0bf40c063fd"
"38921799f2fae22e5dc387e3b63a8d4d2210ad60690f61cce190bad2a304c035"
"2cfc11979ac028eea6636015cd2241a9ca2b9256bcdbae2f89df853751f63589"
"21e602b39eade2ce622e3da4c76124a5f9b2580296037a33f88044895aa8562c"
"25c9a818e3691a8d36cc881eed8513110fbcd2c855270ae265cc4a53283e2f4e"
"6d17e4bdef0620c74ce13ee9b219e49bf2c8ac57cb1882bca03c64ec7c7c69fc"
"2285fe01b02e1cb4331c2e86272f10d7e7daeac3d368b914e9115d832aab4e12"
"3fb801cc1a5264babd7f35a65091d15eb9b47a6f06ab9422defafaee4cd35a84"
"5b2ae60ec46971d3b3535743c3ab4d99f07ee2f551bfb2212ecfc7120169c8eb"
"5322e28426199923aab00dcb5aa2c0c92690628e69ddbeaa8a9e0b92e4d84aa4"
"1db225ddf28a651a6f809533078dfc8a006d4b76b59afde3d3356c7f26bf1ac2"
"600fcc0f370b76ed88186364efc8d0435ba4efe84abd6b2573e87e213cb405dc"
"007c21ae6a4471fb33141d353cb73f3769ee63d78cbc5d7e6a8c1bdb7cf3eb4f"
"17520db9848586770ced86adfca305209a0884592720f70eb91f9e3a22c23a94"
"3db8aeed94f87b37fc9cfee7a7c027605bec03af4965b840a8942b89fef39ecf"
"10b3102359b66388bf079dd2f30d8131ec4da41bf159fae392838a9708e1cfc9"
"0c9f537a5a0efc930019893a3fbd46c5e2a85b78b22b4bb60c0c1ec2da334a07"
"165f9cb0313efaf5a0636141f39c3ff22089c0f9c494ebc40e9e8060b84f149f"
"001879a49e2e539bf9e9c713416f517ee14f6e510a9cafb9a321fef9ca23ed49"
"32e53a1e65305675144ebd5bb49bdcf81879daab30fff361eba5cfef952184a3"
"51b4edb20a2bbb2daf144d4ab3b72a5a4cc956d9bd9e2ba5017c2163928118c3"
"140c9db4c384a0e3757a41ae5005b2557148cb3c190ab7101059053039d655ed"
"1737e47c806e74be09d8f7daf7c9d12ede33929f5152eda6c8c008064cfc1be3"
"23f3501123499df44f5cd31b08fa1338be61194a023c9101a41ce7518acddcdd"
"68dcbacbeb6727e3b47ef3a6291421496a78d81a645f2451c2cd89818715329b"
"2f1dd4d3ce3e7b49d67a4bca9ba8b5b64ee37a20496ddbc302aa8c1bed9b2fbf"
"2b5427a54294793e926c0ed030eff8b5020801ae8a46b1d7cecc49d01d2cd4a1"
"1bcdebbdce2545485d5db25d9776f7bdc31dc799c61cb726e20e0071e939e4c4"
"6021616995863e2b6fb9015892f2f361b60656bf1998239aa471d4c698564e9f"
"4816704f77b55fba8188d9424143ffd7b015587467072992b2482e9bacd4f072"
"60aad5cbecde71eae3fb3e8355137d5890f2947227093bacd23291a731720e79"
"5bff651adb907adde66b4a4810173bb8cc0cc618e6698e236979750865b68466"
"4dc639d5986ad912fc2632704ad03b039c6982fccad820b16ce2e519de54dcb0"
"1780c0f66f7afefb6b32a019956b2a209224b9eeba8a643a222f7355214be300"
"6d23740f70b21671e66d9bb35d7387b017dd56c78b65973db44e5479567c27a0"
"1784ada0fe2211721dff5b63c46ddbd0cc2a7161e42f24b26b10cf0a807398c9"
"3721b5cbdc714dc02db737a41bac0ad9dfd640229e4ef73c780f2abc7907a101"
"6777e0e8612172897bde7e5e4d7edafdfac32f855d07b645ef0a2c2b6815d7bd"
"5430480105f06250a915e429d5436268eeff94a54606848883d84eece231db3a"
"5b06f0578c8e419abaf9365b1e0e4605a270d831b886b1310c2b30830f70aa05"
"064faf1daa9415f3bf666dccf10e96a660e3c3e08945cecfad74bcf656a09b63"
"5a7cf453cdc309e004ac0d4b161686c9497ddd5333302ce1ac689d3cd3f15fe8"
"3d1cdaba6330736b0b9c17a27d3f31b58ea7b0aa1a46faa5cbc191faef9e41ef"
"59c894b434302a88c78f3438263ff4a3f82f27af2f086958497b75ba9ede3267"
"4f96eab2814accfe7cc529624df63fd4d9d3932ecace112a52d488ebd64f86a9"
"5c3395a99f651f587c1e9f88fb32ffde50f312874219daec0f67f604ba56f55a"
"10bc86369a85dae2cbcb60d1a110675555b1f29f01af909d0b0a452fd6f8aa0a"
"025c11c9d5846be858ed85b2706718d0859b14b5e6afafc50e5b7cab9390e88d"
"6a0df7099df32bbf845516682d8b2c40d5b238bab4493508146ec7da5280b31d"
"15dee1455b9289a97a4fb4561cd05cc4eaac7f45e2098e6db369c4e38780a898"
"6b00cd849365b050f85b3bcb73dc91ae063ed60360b053ccecd4ea226f5d3480"
"36ba01e51f6cce897b12718e2947d0ded1b43f1ad65045d9e80792cc0d2afbcf"
"705ec3f8f1bdd15381e69d0241b37349e11963b509f73dde27e4d00f7173e9d2"
"00259c2c2a277983602c80547343f0037a7a3c7edfdf98a1ffd16bea20204aa2"
"07ba65993dc66a3359f96e202f8408f9367d24e37a83164c622f682ef4d113d0"
"56324ef5c5a36793bc76d0c2a38e6ae35916ab04bc072325036d9e832981518d"
"3cdc6e8fc9101d4e6be6b5fb368a3911ac13c4090ea7da9f345cd5f7ae7b1e6c"
"3fe62a321b08da7f8f6cd2080867b98b6c9f54bf910bac77db5a71da68b18270"
"53915ca5503403181327eea9143a99782e31f1636a324a946882376fb9d07681"
"45ec1e9c297bdd973aec556197b1168f8a55b0d7bb0519b5db479f95d11cd045"
"7310ab366f789b5264f16fd563b6dd31462f3e352a92fbb5e2357a9fbb9a1f16"
"739ebe2484fabba7b18d7f3a213bb9d3bb2d78a8c05f41515aa20533b933cc2e"
"048f8d7f23612a95c09d90137f7a4d87e340a1e83ec3c94284d6784ea8006423"
"49a59faf4bbf57ee29b5e186bb0008a4ec74c8fdb7ea8fe7e1aa46bc40873b50"
"5cf260d13f5da4870855a40e71d4effda202f310a955db2d140e9317e4238998"
"38c2eba027b51ab146dc61e33b7403789b63641a5cba018829e3dfc9336cbcb8"
"1f90a83ada4e0d548c8beea8f902f4bdd8466948161fe2760a0127f44a0edea8"
"6b65cc39e2d766f83e8f6f59fd5e40290bf8b887c99da8c166417d5a9cae1444"
"1da9f1f317f97e9c6132dc6808def44d32daa0c2dbcffe580d8f35b85400ccc3"
"3df94f558d1e935080d48183a3e742f6be2992f5aea51387f01c90219e980fa2"
"59974c89246e978cbee6e84478252843235f550eb7ba45324d4a7ea572ca7e2b"
"094be891b94edbc55530775ac31dd8f5ac0d1e2462579c158ce2f28843a2e9b2"
"02c997879aff55f85e9e19e36a32758b868a0504ff0cb4a704fabdb897f308bd"
"090a6946efff80828d498845e43aebaf02f19cc8a5459db7b12952e4924e1fd1"
"3cf7d767a121eb81462c2731ee18da4f5579e007ed7e198ed9c74d0e4122d247"
"4dafcb7ed415b248c5f169092d29b0f5d213e599e2bf15ade507d9ae2c9d764d"
"5204fb985e7a86bb77fd705bf71787c4a09b97e7729318e6828a422f70aabcea"
"0e1b38375d5ded933a6c9d7512ade1e96679651be670f381f875dd62c7279827"
"6b612638db66a469241a60b7222956ca0364f2d77ea8849aeb99fad2a0b5637f"
"3626c1544bd18d8a9bde32d6210aa6179839b1ebefb87fdb914d3735db50f92e"
"222fd118f0cc69ef015f43fdd95a4db3fc08eec734f4cd3fce78e73348373e03"
"369885b7348e2be8c21dce937e248cc6c390c703a09dddbb88b39bbfb3fa2943"
"0794753806f2502ff43f7b8c4990e446c37677a49f78e0a8e38622a23c34eb60"
"4b9b69b8b54c2ba38a23c409263b2ea543ba2082b6fded12c3c9b9dc754c4202"
"06fae323404cc19a099fb298803a76737720c25913e21f38a75f1c8e63a96b9c"
"50461e3977f12ec2de486071fc3924cd1aef82a6bc9fbde215eaddee6780de1d"
"5ff12618767830d17a759dadc62c40221cc848ef84da8cd91b76e5ca59ccaa37"
"6b7bdeac8d4dc989219510a928aa2e2a8995f4aba16e9f59d85e88ae3f6f5f5f"
"5fbc48469f2e94eaee4ce3cc7af5c45f27a6532f0b7d8aaad76e61091a319ecd"
"024ec0f964b1ce01b08352c231662c238c623cd66a2da4ef330debc7323dba8e"
"0dfd978f5c1e804bd89e9d579edb44c49335296cd5948420d7650775cf88fc0c"
"57ecafcf80a257780a9bbac3793c3e772fde0c88d6ce8e39399c7eb0a7e76d6a"
"705b423e84afdccba45b0286397d1a29896cc1dc3fb41721e9e14942a2c13db6"
"61efd69d156931b397d7aebd87d6c7599f6a5e2925cb7d8891fd751b7757c486"
"5b0a8e0bc9d55850e65cb119b6b43abd5eda13de38ffd6e45130a6b2c7184251"
"2ee9eb134a2f83e93bb4b09c71da3e7810d9a2bd01acaacf70fc7b43ccc2fec6"
"136a3734420b9a29249f23e3292d871653540c3a86fdfbdbb655596aac99d0ce"
"11ea5a840d53c0f0eaa111e6f43d953cdadcddedd8b7658d82266fd0897cd71a"
"51a4d6a93c09813a72f272b043ef5cf88fe27eeadb2065cb75c95620874ea281"
"00b698d1b30b8486b7fb7cafdae54bb93ac182be3623f1feffa7edc12486d4e8"
"22386f894f2a9326c7ab4cfbceae435cb69f3e359ee49946dc566f242f4238de"
"636d98aea6cb6afe50fd1e96bb8bfdf18a9d54a87e66fd79e3dff80abda98c18"
"067a4de70930459165ff7d84a0dc375adb145ac07e67eb0e1fadebd4e2610eeb"
"64721850463f2d1dfe148e429e472914d67d9867409de6c39150225106d4d425"
"6c87827aa64247be6bb132c49e271a6e23c54c8334f2c3eca5551b4ae5260f05"
"65cbbc751ea4f5e7956628b8645708187b37f2d65c6c297a5854355256de476e"
"6bf24b343856b4066e2835b1fe3e5d16496a36f41386c2afd44d001ba886fdc7"
"41d82825d409ab7c996773b516f6720e34cbfdebdc9c069fa579dcea11ef44f6"
"45f741f2e9481a85b86467ab30d363fd0328e33d53fce6b39286c2494ee7bd28"
"6c06f72d4e071f9c1ddca4f9ea231853f6d8c5e9b7418e9c564c995912d19c18"
"154f9ecfb65370a8b59a12cd736348aead2e59a7e3701d20a669bec15363fe62"
"0c4d910fbd3b57be6d6680e8d2db47c1454712b240b78468cb764702be5c1aec"
"0e1ac575e1125f5ee86da3342018bc4f3c1e2310148043d5074eb4ee22fc55b6"
"273531c7d0d03d8f97b722ef1f0c324dac39f804e0222202f7502946647ef332"
"101464d19cf380958e5aef1084736db89f4cb131033ae670f6de0a5cf9d92b73"
"597cdd384abdad1beccc73fb39f74a18eb44d056951d602c2ef6ef6448fc5626"
))

View File

@@ -1,341 +0,0 @@
(load-file "util.lisp")
(def! zk-not-small-order? (fn* [u v] (
(def! first-doubling (last (last (zk-double u v))))
(def! second-doubling (last (last
(zk-double (get first-doubling "u3") (get first-doubling "v3")))))
(def! third-doubling (last (last
(zk-double (get second-doubling "u3") (get second-doubling "v3")))))
(zk-nonzero? (get third-doubling "u3"))
)
)
)
(defmacro! zk-nonzero? (fn* [var] (
(let* [inv (gensym)
v1 (gensym)] (
`(alloc ~inv (invert ~var))
`(alloc ~v1 ~var)
`(enforce
(scalar::one ~v1)
(scalar::one ~inv)
(scalar::one cs::one)
)
)
))
))
(defmacro! zk-square (fn* [var] (
(let* [v1 (gensym)
v2 (gensym)] (
`(alloc ~v1 ~var)
`(def! output (alloc-input ~v2 (square ~var)))
`(enforce
(scalar::one ~v1)
(scalar::one ~v1)
(scalar::one ~v2)
)
`{ "v2" output }
)
))
))
(defmacro! zk-mul (fn* [val1 val2] (
(let* [v1 (gensym)
v2 (gensym)
var (gensym)] (
`(alloc ~v1 ~val1)
`(alloc ~v2 ~val2)
`(def! result (alloc-input ~var (* ~val1 ~val2)))
`(enforce
(scalar::one ~v1)
(scalar::one ~v2)
(scalar::one ~var)
)
`{ "result" result }
)
))
))
(defmacro! zk-witness (fn* [val1 val2] (
(let* [u2 (gensym)
v2 (gensym)
u2v2 (gensym)
EDWARDS_D (gensym)] (
`(def! ~EDWARDS_D (alloc-const ~EDWARDS_D (scalar "2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1")))
`(def! ~u2 (alloc ~u2 (get (nth (nth (zk-square ~val1) 0) 3) "v2")))
`(def! ~v2 (alloc ~v2 (get (nth (nth (zk-square ~val2) 0) 3) "v2")))
`(def! result (alloc-input ~u2v2 (get (last (last (zk-mul ~u2 ~v2))) "result")))
`(enforce
((scalar::one::neg ~u2) (scalar::one ~v2))
(scalar::one cs::one)
((scalar::one cs::one) (~EDWARDS_D ~u2v2))
)
`{ "result" result }
)
))
))
(defmacro! zk-double (fn* [val1 val2] (
(let* [u (gensym)
v (gensym)
u3 (gensym)
v3 (gensym)
T (gensym)
A (gensym)
C (gensym)
EDWARDS_D (gensym)] (
`(def! ~EDWARDS_D (alloc-const ~EDWARDS_D (scalar "2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1")))
`(def! ~u (alloc ~u ~val1))
`(def! ~v (alloc ~v ~val2))
`(def! ~T (alloc ~T (* (+ ~val1 ~val2) (+ ~val1 ~val2))))
`(def! ~A (alloc ~A (* ~u ~v)))
`(def! ~C (alloc ~C (* (square ~A) ~EDWARDS_D)))
`(def! ~u3 (alloc ~u3 (/ (double ~A) (+ scalar::one ~C))))
`(def! ~v3 (alloc ~v3 (/ (- ~T (double ~A)) (- scalar::one ~C))))
`(enforce
((scalar::one ~u) (scalar::one ~v))
((scalar::one ~u) (scalar::one ~v))
(scalar::one ~T)
)
`(enforce
(~EDWARDS_D ~A)
(scalar::one ~A)
(scalar::one ~C)
)
`(enforce
((scalar::one cs::one) (scalar::one ~C))
(scalar::one ~u3)
((scalar::one ~A) (scalar::one ~A))
)
`(enforce
((scalar::one cs::one) (scalar::one::neg ~C))
(scalar::one ~v3)
((scalar::one ~T) (scalar::one::neg ~A) (scalar::one::neg ~A))
)
{ "u3" u3, "v3" v3 }
)
))
))
(defmacro! conditionally-select (fn* [val1 val2 val3] (
(let* [u-prime (gensym)
v-prime (gensym)
u (gensym)
v (gensym)
condition (gensym)
] (
`(def! ~u (alloc ~u ~val1))
`(def! ~v (alloc ~v ~val2))
`(def! ~condition (alloc ~condition ~val3))
`(def! ~u-prime (alloc ~u-prime (* ~u ~condition)))
`(def! ~v-prime (alloc ~v-prime (* ~v ~condition)))
`(enforce
(scalar::one ~u)
(scalar::one ~condition)
(scalar::one ~u-prime)
)
`(enforce
(scalar::one ~v)
(scalar::one ~condition)
(scalar::one ~v-prime)
)
{ "u-prime" u-prime, "v-prime" v-prime }
)
))))
(defmacro! jj-add (fn* [param1 param2 param3 param4]
(let* [u1 (gensym) v1 (gensym) u2 (gensym) v2 (gensym)
EDWARDS_D (gensym) U (gensym) A (gensym) B (gensym)
C (gensym) u3 (gensym) v3 (gensym)] (
;; debug
;; `(println 'jj-add ~param1 ~param2 ~param3 ~param4)
`(def! ~u1 (alloc ~u1 ~param1))
`(def! ~v1 (alloc ~v1 ~param2))
`(def! ~u2 (alloc ~u2 ~param3))
`(def! ~v2 (alloc ~v2 ~param4))
`(def! ~EDWARDS_D (alloc-const ~EDWARDS_D (scalar "2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1")))
`(def! ~U (alloc ~U (* (+ ~u1 ~v1) (+ ~u2 ~v2))))
`(def! ~A (alloc ~A (* ~v2 ~u1)))
`(def! ~B (alloc ~B (* ~u2 ~v1)))
`(def! ~C (alloc ~C (* ~EDWARDS_D (* ~A ~B))))
`(def! ~u3 (alloc ~u3 (/ (+ ~A ~B) (+ scalar::one ~C))))
`(def! ~v3 (alloc ~v3 (/ (- (- ~U ~A) ~B) (- scalar::one ~C))))
`(enforce
((scalar::one ~u1) (scalar::one ~v1))
((scalar::one ~u2) (scalar::one ~v2))
(scalar::one ~U)
)
`(enforce
(~EDWARDS_D ~A)
(scalar::one ~B)
(scalar::one ~C)
)
`(enforce
((scalar::one cs::one)(scalar::one ~C))
(scalar::one ~u3)
((scalar::one ~A) (scalar::one ~B))
)
`(enforce
((scalar::one cs::one) (scalar::one::neg ~C))
(scalar::one ~v3)
((scalar::one ~U) (scalar::one::neg ~A) (scalar::one::neg ~B))
)
{ "u3" u3, "v3" v3 }
)
)
))
(defmacro! zk-boolean (fn* [val] (
(let* [var (gensym)] (
`(alloc ~var ~val)
`(enforce
((scalar::one cs::one) (scalar::one::neg ~var))
(scalar::one ~var)
()
)
)
))))
(def! jj-mul (fn* [u v b] (
(def! result (unpack-bits b))
(eval (map zk-boolean result))
(def! val (last (last (zk-double u v))))
(def! acc 0)
(dotimes (count result) (
(def! u3 (get val "u3"))
(def! v3 (get val "v3"))
(def! r (nth result acc))
(def! cond-result (last (last (conditionally-select u3 v3 r))))
(def! u-prime (get cond-result "u-prime"))
(def! v-prime (get cond-result "v-prime"))
(def! add-result (last (jj-add u3 v3 u-prime v-prime)))
(def! u-add (get add-result "u3"))
(def! v-add (get add-result "v3"))
(def! val (last (last (zk-double u-add v-add))))
(println acc val)
(def! acc (i+ acc 1))
))
(val)
;; { "u3" (get val "u3"), "v3" (get val "v3") }
)))
(load-file "mimc-constants.lisp")
(defmacro! mimc-macro (fn* [left-value right-value acc] (
(let* [tmp-xl (gensym2 'tmp_xl)
xl-new-value (gensym2 'xl_new_value)
cur-mimc-const (gensym2 'cur_mimc_const)
xl (gensym2 'xl)
xr (gensym2 'xr)] (
`(def! ~xl (alloc ~xl ~left-value))
`(def! ~xr (alloc ~xr ~right-value))
`(def! ~cur-mimc-const (alloc-const ~cur-mimc-const (nth mimc-constants ~acc)))
`(def! ~tmp-xl (alloc ~tmp-xl (square (+ ~cur-mimc-const ~xl))))
`(enforce
((scalar::one ~xl) (~cur-mimc-const cs::one))
((scalar::one ~xl) (~cur-mimc-const cs::one))
(scalar::one ~tmp-xl)
)
`(def! new-value (+ (* ~tmp-xl (+ ~cur-mimc-const ~xl)) ~xr))
`(if (= ~acc 321)
(def! ~xl-new-value (alloc-input ~xl-new-value new-value))
(def! ~xl-new-value (alloc ~xl-new-value new-value))
)
`(enforce
(scalar::one ~tmp-xl)
((scalar::one ~xl) (~cur-mimc-const cs::one))
((scalar::one ~xl-new-value) (scalar::one::neg ~xr))
)
`{ "left" new-value }
)
))))
(def! mimc (fn* [left right] (
(def! acc 0)
(def! xl left)
(def! xr right)
(dotimes 322 (
(def! result (mimc-macro xl xr acc))
(def! result-value (get (last (last result)) "left"))
(def! xr xl)
(def! xl result-value)
(def! acc (i+ acc 1))
))
{ "result" result-value }
)))
(defmacro! rangeproof-alloc (fn* [value value-digit] (
(let* [bit (gensym2 'bit)
digit (gensym2 'digit)] (
`(def! ~bit (alloc ~bit ~value))
`(def! ~digit (alloc-const ~digit ~value-digit))
`(enforce
(scalar::one ~bit)
((scalar::one cs::one) (scalar::one::neg ~bit))
()
)
{ "lc" ((str digit) (str bit)) }
)))))
(def! rangeproof (fn* [value] (
(def! values-bit (unpack-bits value))
(def! idx 0)
(def! digit (scalar 1))
(def! value-result ())
(dotimes 64 (
(def! bit (nth values-bit idx))
(def! value-result
(conj value-result
(get (last (last
(rangeproof-alloc bit digit))) "lc")))
(def! digit (double digit))
(def! idx (i+ idx 1))
))
(def! value-alloc (alloc-input "value-alloc" value))
(enforce
(value-result)
(scalar::one cs::one)
(scalar::one value-alloc)
)
)))
;; mint contract
(def! generator-coin-u (scalar "0d7b70a0c82cbabf8f59ee61a63b8e0adcff42e9f2da7bda84f9308b3531dd18"))
(def! generator-coin-v (scalar "0d89cafb242b9e892153ac70335956e6f5c042997da77cf5e164233a9bbfb7b4"))
(def! generator-value-commit-u (scalar "01ae4ea270f5c6a1c0cd1dd4e067a82110fa27409dfc0aa4edd18883897a4c6b"))
(def! generator-value-commit-v (scalar "09d2a25018194750e9adacf78531ee3bfddbadd767671d517aa788c352641ff1"))
(def! generator-value-random-u (scalar "002924d15ccf8014ce724a41753d17dce3a9f7382a3db18fba3c8e286bb77382"))
(def! generator-value-random-v (scalar "0cb825b790b0601c4999e52d9added7d10d013b33fd95ca7d2ddd51691a09075"))
(def! mint-contract (fn* [public-u public-v value serial rnd-coin rnd-value] (
(def! mimc-round-1 (get (last (mimc public-u public-v)) "result"))
(def! mimc-round-2 (get (last (mimc mimc-round-1 value)) "result"))
(def! mimc-round-3 (get (last (mimc mimc-round-2 serial)) "result"))
(def! coin (get (last (mimc mimc-round-3 rnd-coin)) "result"))
(rangeproof value)
(def! result-mul-value
(last (last (jj-mul generator-value-commit-u generator-value-commit-v value))))
(def! result-mul-rnd-value
(last (last (jj-mul generator-value-random-u generator-value-random-v rnd-value))))
(def! add-result (jj-add (get result-mul-value "u3") (get result-mul-value "v3")
(get result-mul-rnd-value "u3") (get result-mul-rnd-value "v3")))
(println 'add-result add-result)
;;(alloc-input "value-commit" add-result)
)))
;; (def! spend-contract (fn*
;; [secret-u secret-v serial coin-merkle-branch coin-merkle-is-right] (
;; (def! nullifier (mimc secret serial))
;; )))
(prove
(
(def! public-u (scalar "0d7b70a0c82cbabf8f59ee61a63b8e0adcff42e9f2da7bda84f9308b3531dd18"))
(def! public-v (scalar "0cb825b790b0601c4999e52d9added7d10d013b33fd95ca7d2ddd51691a09075"))
(def! value (scalar 3))
(def! serial (scalar 4))
(def! rnd-coin (rnd-scalar))
(def! rnd-value (rnd-scalar))
(mint-contract public-u public-v value serial rnd-coin rnd-value)
)
)

View File

@@ -1,26 +0,0 @@
(def! inc (fn* [a] (i+ a 1)))
(def! gensym
(let* [counter (atom 0)]
(fn* []
(symbol (str "G__" (swap! counter inc))))))
(def! gensym2
(let* [counter (atom 0)]
(fn* [name]
(symbol (str name "__" (swap! counter inc))))))
;; Like load-file, but will never load the same path twice.
;; This file is normally loaded with `load-file`, so it needs a
;; different mechanism to neutralize multiple inclusions of
;; itself. Moreover, the file list should never be reset.
(def! load-file-once
(try*
load-file-once
(catch* _
(let* [seen (atom {"../lib/util.mal" nil})]
(fn* [filename]
(if (not (contains? @seen filename))
(do
(swap! seen assoc filename nil)
(load-file filename))))))))

View File

@@ -1,781 +0,0 @@
#![allow(non_snake_case)]
use crate::types::LispCircuit;
use drk::BlsStringConversion;
use bellman::groth16;
use bls12_381::Bls12;
// use fnv::FnvHashMap;
use itertools::Itertools;
use rand::rngs::OsRng;
use std::rc::Rc;
use std::time::Instant;
use std::{cell::RefCell, collections::HashMap};
use types::EnforceAllocation;
#[macro_use]
extern crate clap;
#[macro_use]
extern crate lazy_static;
// extern crate fnv;
extern crate itertools;
extern crate regex;
#[macro_use]
mod types;
use crate::types::MalErr::{ErrMalVal, ErrString};
use crate::types::MalVal::{
Alloc, Bool, Enforce, Func, Hash, List, MalFunc, Nil, Str, Sym, Vector,
};
use crate::types::VerifyKeyParams;
use crate::types::{error, format_error, MalArgs, MalErr, MalRet, MalVal};
mod env;
mod printer;
mod reader;
use crate::env::{env_bind, env_find, env_get, env_new, env_set, env_sets, Env};
#[macro_use]
mod core;
// read
fn read(str: &str) -> MalRet {
reader::read_str(str.to_string())
}
// eval
fn qq_iter(elts: &MalArgs) -> MalVal {
let mut acc = list![];
for elt in elts.iter().rev() {
if let List(v, _) = elt {
if v.len() == 2 {
if let Sym(ref s) = v[0] {
if s == "splice-unquote" {
acc = list![Sym("concat".to_string()), v[1].clone(), acc];
continue;
}
}
}
}
acc = list![Sym("cons".to_string()), quasiquote(&elt), acc];
}
return acc;
}
fn quasiquote(ast: &MalVal) -> MalVal {
match ast {
List(v, _) => {
if v.len() == 2 {
if let Sym(ref s) = v[0] {
if s == "unquote" {
return v[1].clone();
}
}
}
return qq_iter(&v);
}
Vector(v, _) => return list![Sym("vec".to_string()), qq_iter(&v)],
Hash(_, _) | Sym(_) => return list![Sym("quote".to_string()), ast.clone()],
_ => ast.clone(),
}
}
fn is_macro_call(ast: &MalVal, env: &Env) -> Option<(MalVal, MalArgs)> {
match ast {
List(v, _) => match v[0] {
Sym(ref s) => match env_find(env, s) {
Some(e) => match env_get(&e, &v[0]) {
Ok(f @ MalFunc { is_macro: true, .. }) => Some((f, v[1..].to_vec())),
_ => None,
},
_ => None,
},
_ => None,
},
_ => None,
}
}
fn macroexpand(mut ast: MalVal, env: &Env) -> (bool, MalRet) {
let mut was_expanded = false;
while let Some((mf, args)) = is_macro_call(&ast, env) {
// println!("macroexpand 1: {:?}", ast);
ast = match mf.apply(args) {
Err(e) => return (false, Err(e)),
Ok(a) => a,
};
// println!("macroexpand 2: {:?}", ast);
was_expanded = true;
}
(was_expanded, Ok(ast))
}
fn eval_ast(ast: &MalVal, env: &Env) -> MalRet {
match ast {
Sym(_) => Ok(env_get(&env, &ast)?),
List(v, _) => {
let mut lst: MalArgs = vec![];
for a in v.iter() {
lst.push(eval(a.clone(), env.clone())?)
}
Ok(list!(lst))
}
Vector(v, _) => {
let mut lst: MalArgs = vec![];
for a in v.iter() {
lst.push(eval(a.clone(), env.clone())?)
}
Ok(vector!(lst))
}
Hash(hm, _) => {
let mut new_hm: HashMap<String, MalVal> = HashMap::default();
for (k, v) in hm.iter() {
new_hm.insert(k.to_string(), eval(v.clone(), env.clone())?);
}
Ok(Hash(Rc::new(new_hm), Rc::new(Nil)))
}
_ => Ok(ast.clone()),
}
}
fn eval(mut _ast: MalVal, mut env: Env) -> MalRet {
let ret: MalRet;
let start = Instant::now();
'tco: loop {
// TODO check DEBUG symbol on env
println!("debug eval \t {:?} \t {:?}", _ast, start.elapsed());
ret = match _ast.clone() {
List(l, _) => {
if l.len() == 0 {
return Ok(_ast);
}
match macroexpand(_ast.clone(), &env) {
(true, Ok(new_ast)) => {
_ast = new_ast;
continue 'tco;
}
(_, Err(e)) => return Err(e),
_ => (),
}
if l.len() == 0 {
return Ok(_ast);
}
let a0 = &l[0];
match a0 {
Sym(ref a0sym) if a0sym == "def!" => {
env_set(&env, l[1].clone(), eval(l[2].clone(), env.clone())?)
}
Sym(ref a0sym) if a0sym == "zk*" => {
// println!("zk* {:?}", l[1]);
let (a1, a2) = (l[1].clone(), l[2].clone());
match a1 {
List(ref binds, _) | Vector(ref binds, _) => {
for (b, e) in binds.iter().tuples() {
match b {
Sym(_) => {
let _ = env_set(
&env,
b.clone(),
eval(e.clone(), env.clone())?,
);
}
_ => {
return error("let* with non-Sym binding");
}
}
}
}
_ => {
return error("let* with non-List bindings");
}
};
_ast = a2;
continue 'tco;
}
Sym(ref a0sym) if a0sym == "let*" => {
env = env_new(Some(env.clone()));
let (a1, a2) = (l[1].clone(), l[2].clone());
match a1 {
List(ref binds, _) | Vector(ref binds, _) => {
for (b, e) in binds.iter().tuples() {
match b {
Sym(_) => {
let _ = env_set(
&env,
b.clone(),
eval(e.clone(), env.clone())?,
);
}
_ => {
return error("let* with non-Sym binding");
}
}
}
}
_ => {
return error("let* with non-List bindings");
}
};
_ast = a2;
continue 'tco;
}
Sym(ref a0sym) if a0sym == "quote" => Ok(l[1].clone()),
Sym(ref a0sym) if a0sym == "quasiquoteexpand" => Ok(quasiquote(&l[1])),
Sym(ref a0sym) if a0sym == "quasiquote" => {
_ast = quasiquote(&l[1]);
continue 'tco;
}
Sym(ref a0sym) if a0sym == "defmacro!" => {
let (a1, a2) = (l[1].clone(), l[2].clone());
let r = eval(a2, env.clone())?;
match r {
MalFunc {
eval,
ast,
env,
params,
..
} => Ok(env_set(
&env,
a1.clone(),
MalFunc {
eval,
ast: ast.clone(),
env: env.clone(),
params: params.clone(),
is_macro: true,
meta: Rc::new(Nil),
},
)?),
_ => error("set_macro on non-function"),
}
}
Sym(ref a0sym) if a0sym == "macroexpand" => {
match macroexpand(l[1].clone(), &env) {
(_, Ok(new_ast)) => Ok(new_ast),
(_, e) => return e,
}
}
Sym(ref a0sym) if a0sym == "try*" => match eval(l[1].clone(), env.clone()) {
Err(ref e) if l.len() >= 3 => {
let exc = match e {
ErrMalVal(mv) => mv.clone(),
ErrString(s) => Str(s.to_string()),
};
match l[2].clone() {
List(c, _) => {
let catch_env = env_bind(
Some(env.clone()),
list!(vec![c[1].clone()]),
vec![exc],
)?;
eval(c[2].clone(), catch_env)
}
_ => error("invalid catch block"),
}
}
res => res,
},
Sym(ref a0sym) if a0sym == "do" => {
match eval_ast(&list!(l[1..l.len() - 1].to_vec()), &env)? {
List(_, _) => {
_ast = l.last().unwrap_or(&Nil).clone();
continue 'tco;
}
_ => error("invalid do form"),
}
}
Sym(ref a0sym) if a0sym == "dotimes" => {
match eval(l[1].clone(), env.clone())? {
MalVal::Int(v) => {
for _i in 0..v {
_ast = eval_ast(&l[2], &env)?;
}
Ok(Nil)
}
_ => error("invalid args for dotimes"),
}
}
Sym(ref a0sym) if a0sym == "if" => {
let cond = eval(l[1].clone(), env.clone())?;
match cond {
Bool(false) | Nil if l.len() >= 4 => {
_ast = l[3].clone();
continue 'tco;
}
Bool(false) | Nil => Ok(Nil),
_ if l.len() >= 3 => {
_ast = l[2].clone();
continue 'tco;
}
_ => Ok(Nil),
}
}
Sym(ref a0sym) if a0sym == "fn*" => {
let (a1, a2) = (l[1].clone(), l[2].clone());
Ok(MalFunc {
eval,
ast: Rc::new(a2),
env,
params: Rc::new(a1),
is_macro: false,
meta: Rc::new(Nil),
})
}
Sym(ref a0sym) if a0sym == "eval" => {
_ast = eval(l[1].clone(), env.clone())?;
while let Some(ref e) = env.clone().outer {
env = e.clone();
}
continue 'tco;
}
Sym(ref a0sym) if a0sym == "setup" => {
let a1 = l[1].clone();
// todo
_ast = eval(a1.clone(), env.clone())?;
// let _pvk = setup(a1.clone(), env.clone())?;
continue 'tco;
}
Sym(ref a0sym) if a0sym == "prove" => {
let a1 = l[1].clone();
eval(a1.clone(), env.clone())?;
// TODO add debug param
prove(a1.clone(), env.clone())
}
Sym(ref a0sym) if a0sym == "kill" => {
error(&format!("KILL at: {:?}", _ast).to_string())
}
Sym(ref a0sym) if a0sym == "alloc-const" => {
let start = Instant::now();
let a1 = l[1].clone();
let mut value = eval(l[2].clone(), env.clone())?;
if let Func(_, _) = value {
value = value.apply(vec![]).unwrap();
}
let result = eval(value.clone(), env.clone())?;
let allocs = get_allocations(&env, "AllocationsConst");
allocs.borrow_mut().insert(a1.pr_str(false), result.clone());
if let Some(e) = &env.outer {
env_set(&e, Sym("AllocationsConst".to_string()), Alloc(allocs))?;
} else {
env_set(&env, Sym("AllocationsConst".to_string()), Alloc(allocs))?;
}
println!("Alloc Const: {:?}", start.elapsed());
Ok(result.clone())
}
Sym(ref a0sym) if a0sym == "alloc-input" => {
let start = Instant::now();
let a1 = l[1].clone();
let mut value = eval(l[2].clone(), env.clone())?;
if let Func(_, _) = value {
value = value.apply(vec![]).unwrap();
}
let result = eval(value.clone(), env.clone())?;
let allocs = get_allocations(&env, "AllocationsInput");
allocs.borrow_mut().insert(a1.pr_str(false), result.clone());
if let Some(e) = &env.outer {
env_set(&e, Sym("AllocationsInput".to_string()), Alloc(allocs))?;
} else {
env_set(&env, Sym("AllocationsInput".to_string()), Alloc(allocs))?;
}
println!("Alloc Input: {:?}", start.elapsed());
Ok(result.clone())
}
Sym(ref a0sym) if a0sym == "alloc" => {
let start = Instant::now();
let a1 = l[1].clone();
let mut value = eval(l[2].clone(), env.clone())?;
if let Func(_, _) = value {
value = value.apply(vec![]).unwrap();
}
let result = eval(value.clone(), env.clone())?;
let allocs = get_allocations(&env, "Allocations");
allocs.borrow_mut().insert(a1.pr_str(false), result.clone());
if let Some(e) = &env.outer {
env_set(&e, Sym("Allocations".to_string()), Alloc(allocs))?;
} else {
env_set(&env, Sym("Allocations".to_string()), Alloc(allocs))?;
}
println!("Alloc:\t{:?}\t{:?}\t{:?}", value, result, start.elapsed());
Ok(result.clone())
}
//Sym(ref a0sym) if a0sym == "verify" => {
Sym(ref a0sym) if a0sym == "enforce" => {
let mut left_vec = vec![];
let mut right_vec = vec![];
let mut out_vec = vec![];
match l[1].clone() {
List(v, _) | Vector(v, _) => {
if v.to_vec().len() > 0 {
// println!("{:?} {:?}", v, v.to_vec().len());
if let List(_, _) = &v.to_vec()[0] {
for ele in v.to_vec().iter() {
if let List(ele_vec, _) = ele {
left_vec.push((
ele_vec[0].pr_str(false),
ele_vec[1].pr_str(false),
));
}
}
} else {
if v.to_vec().len() == 1 {
let result = eval(v.to_vec()[0].clone(), env.clone())?;
if let List(val, _) = result {
for ele in val.iter() {
// println!("{:?}", ele);
if let Vector(ele_vec, _) = ele {
left_vec.push((
ele_vec[0].pr_str(false),
ele_vec[1].pr_str(false),
));
}
}
}
} else {
left_vec.push((v[0].pr_str(false), v[1].pr_str(false)));
}
}
}
}
_ => {}
};
match l[2].clone() {
List(v, _) | Vector(v, _) => {
if v.to_vec().len() > 0 {
if let List(_, _) = &v.to_vec()[0] {
for ele in v.to_vec().iter() {
if let List(ele_vec, _) = ele {
right_vec.push((
ele_vec[0].pr_str(false),
ele_vec[1].pr_str(false),
));
}
}
} else {
if v.to_vec().len() == 1 {
let result = eval(v.to_vec()[0].clone(), env.clone())?;
if let List(val, _) = result {
for ele in val.iter() {
// println!("{:?}", ele);
if let Vector(ele_vec, _) = ele {
right_vec.push((
ele_vec[0].pr_str(false),
ele_vec[1].pr_str(false),
));
}
}
}
} else {
right_vec
.push((v[0].pr_str(false), v[1].pr_str(false)));
}
}
}
}
_ => {}
};
match l[3].clone() {
List(v, _) | Vector(v, _) => {
if v.to_vec().len() > 0 {
if let List(_, _) = &v.to_vec()[0] {
for ele in v.to_vec().iter() {
if let List(ele_vec, _) = ele {
out_vec.push((
ele_vec[0].pr_str(false),
ele_vec[1].pr_str(false),
));
}
}
} else {
if v.to_vec().len() == 1 {
let result = eval(v.to_vec()[0].clone(), env.clone())?;
if let List(val, _) = result {
for ele in val.iter() {
// println!("{:?}", ele);
if let Vector(ele_vec, _) = ele {
out_vec.push((
ele_vec[0].pr_str(false),
ele_vec[1].pr_str(false),
));
}
}
}
} else {
out_vec.push((v[0].pr_str(false), v[1].pr_str(false)));
}
}
}
}
_ => {}
};
let mut enforce_vec = get_enforce_allocs(&env).clone();
let enforce = EnforceAllocation {
idx: enforce_vec.len() + 1,
left: left_vec,
right: right_vec,
output: out_vec,
};
enforce_vec.push(enforce);
if let Some(e) = &env.outer {
env_set(
&e,
Sym("AllocationsEnforce".to_string()),
vector![vec![Enforce(Rc::new(enforce_vec))]],
)?;
} else {
env_set(
&env,
Sym("AllocationsEnforce".to_string()),
vector![vec![Enforce(Rc::new(enforce_vec))]],
)?;
}
Ok(MalVal::Str("enforce-eof".to_string()))
}
_ => match eval_ast(&_ast, &env)? {
List(ref el, _) => {
let ref f = el[0].clone();
let args = el[1..].to_vec();
match f {
Func(_, _) => f.apply(args),
MalFunc {
ast: mast,
env: menv,
params,
..
} => {
let a = &**mast;
let p = &**params;
env = env_bind(Some(menv.clone()), p.clone(), args)?;
_ast = a.clone();
continue 'tco;
}
_ => {
// println!("{:?}", args);
Ok(vector![el.to_vec()])
//error("call non-function")
}
}
}
_ => error("expected a list"),
},
}
}
_ => eval_ast(&_ast, &env),
};
break;
} // end 'tco loop
// println!("debug eval \t {:?} \t {:?}", ast, start.elapsed());
ret
}
pub fn get_enforce_allocs(env: &Env) -> Vec<EnforceAllocation> {
if let Some(e) = &env.outer {
get_enforce_allocs_nested(&e)
} else {
get_enforce_allocs_nested(&env)
}
}
pub fn get_enforce_allocs_nested(env: &Env) -> Vec<EnforceAllocation> {
match env_find(env, "AllocationsEnforce") {
Some(e) => match env_get(&e, &Sym("AllocationsEnforce".to_string())) {
Ok(f) => {
if let Vector(val, _) = f {
if let Enforce(ret) = &val[0] {
ret.to_vec()
} else {
vec![]
}
} else {
vec![]
}
}
_ => vec![],
},
_ => vec![],
}
}
pub fn get_allocations(env: &Env, key: &str) -> RefCell<HashMap<String, MalVal>> {
if let Some(e) = &env.outer {
get_allocations_nested(&e, key)
} else {
get_allocations_nested(&env, key)
}
}
pub fn get_allocations_nested(env: &Env, key: &str) -> RefCell<HashMap<String, MalVal>> {
let alloc_hm: RefCell<HashMap<String, MalVal>> = RefCell::new(HashMap::default());
match env_find(env, key) {
Some(e) => match env_get(&e, &Sym(key.to_string())) {
Ok(f) => {
if let MalVal::Alloc(allocs) = f {
allocs
} else {
alloc_hm
}
}
_ => alloc_hm,
},
_ => alloc_hm,
}
}
pub fn setup(_ast: MalVal, _env: Env) -> Result<VerifyKeyParams, MalErr> {
let start = Instant::now();
let c = LispCircuit {
params: HashMap::default(),
allocs: HashMap::default(),
alloc_inputs: HashMap::default(),
constraints: Vec::new(),
};
let random_parameters =
groth16::generate_random_parameters::<Bls12, _, _>(c, &mut OsRng).unwrap();
let pvk = groth16::prepare_verifying_key(&random_parameters.vk);
println!("Setup: [{:?}]", start.elapsed());
Ok(VerifyKeyParams {
verifying_key: pvk,
random_params: random_parameters,
})
}
pub fn prove(_ast: MalVal, env: Env) -> MalRet {
let start = Instant::now();
let allocs_input = get_allocations(&env, "AllocationsInput");
let allocs = get_allocations(&env, "Allocations");
let enforce_allocs = get_enforce_allocs(&env);
let allocs_const = get_allocations(&env, "AllocationsConst");
//setup
let params = Some({
let circuit = LispCircuit {
params: allocs_const.borrow().clone(),
allocs: allocs.borrow().clone(),
alloc_inputs: allocs_input.borrow().clone(),
constraints: enforce_allocs.clone(),
};
groth16::generate_random_parameters::<Bls12, _, _>(circuit, &mut OsRng)?
});
let verifying_key = Some(groth16::prepare_verifying_key(&params.as_ref().unwrap().vk));
// prove
let circuit = LispCircuit {
params: allocs_const.borrow().clone(),
allocs: allocs.borrow().clone(),
alloc_inputs: allocs_input.borrow().clone(),
constraints: enforce_allocs.clone(),
};
let proof = groth16::create_random_proof(circuit, params.as_ref().unwrap(), &mut OsRng)?;
let mut vec_input = vec![];
for (_k, val) in allocs_input.borrow_mut().iter() {
match val {
MalVal::Str(v) => {
vec_input.push(bls12_381::Scalar::from_string(&v.to_string()));
}
MalVal::ZKScalar(v) => {
vec_input.push(bls12_381::Scalar::from(*v));
}
_ => {}
};
}
println!("groth16::create_random_proof: {:?}", start.elapsed());
// verification process
let start = Instant::now();
let result = groth16::verify_proof(verifying_key.as_ref().unwrap(), &proof, &vec_input);
println!("groth16::verify_proof: {:?}", start.elapsed());
println!("vec public {:?}", vec_input);
println!("result {:?}", result);
Ok(MalVal::Nil)
}
pub fn verify(_ast: &MalVal) -> MalRet {
let _public_input = vec![bls12_381::Scalar::from(27)];
let start = Instant::now();
println!("Verify: [{:?}]", start.elapsed());
Ok(MalVal::Nil)
}
// print
fn print(ast: &MalVal) -> String {
ast.pr_str(true)
}
fn rep(str: &str, env: &Env) -> Result<String, MalErr> {
let ast = read(str)?;
let exp = eval(ast, env.clone())?;
Ok(print(&exp))
}
fn main() -> Result<(), ()> {
let matches = clap_app!(zklisp =>
(version: "0.1.0")
(author: "Dark Renaissance")
(about: "A Lisp Interpreter for Zero Knowledge Virtual Machine")
(@subcommand load =>
(about: "Load the file into the interpreter")
(@arg FILE: +required "Lisp Contract filename")
)
)
.get_matches();
// CombinedLogger::init(vec![TermLogger::new(
// LevelFilter::Debug,
// Config::default(),
// TerminalMode::Mixed,
// )
// .unwrap()])
// .unwrap();
match matches.subcommand() {
("load", matches) => {
if let Some(matches) = matches {
let file: String = matches.value_of("FILE").unwrap().parse().unwrap();
repl_load(file)?;
}
}
_ => {
eprintln!("error: Invalid subcommand invoked");
std::process::exit(-1);
}
}
Ok(())
}
fn repl_load(file: String) -> Result<(), ()> {
let start = Instant::now();
let repl_env = env_new(None);
for (k, v) in core::ns() {
env_sets(&repl_env, k, v);
}
let _ = rep("(def! not (fn* (a) (if a false true)))", &repl_env);
let _ = rep(
"(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \"\nnil)\")))))",
&repl_env,
);
match rep(&format!("(load-file \"{}\")", file), &repl_env) {
Ok(_) => {
println!("lisp end \t {:?}", start.elapsed());
std::process::exit(0)
}
Err(e) => {
println!("Error: {}", format_error(e));
std::process::exit(1);
}
}
}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}

View File

@@ -1,63 +0,0 @@
use crate::types::MalVal;
use crate::types::MalVal::{Atom, Bool, Func, Hash, Int, List, MalFunc, Nil, Str, Sym, Vector};
fn escape_str(s: &str) -> String {
s.chars()
.map(|c| match c {
'"' => "\\\"".to_string(),
'\n' => "\\n".to_string(),
'\\' => "\\\\".to_string(),
_ => c.to_string(),
})
.collect::<Vec<String>>()
.join("")
}
impl MalVal {
pub fn pr_str(&self, print_readably: bool) -> String {
match self {
Nil => String::from("nil"),
Bool(true) => String::from("true"),
Bool(false) => String::from("false"),
Int(i) => format!("{}", i),
//Float(f) => format!("{}", f),
Str(s) => {
if s.starts_with("\u{29e}") {
format!(":{}", &s[2..])
} else if print_readably {
format!("\"{}\"", escape_str(s))
} else {
s.clone()
}
}
Sym(s) => s.clone(),
List(l, _) => pr_seq(&**l, print_readably, "(", ")", " "),
Vector(l, _) => pr_seq(&**l, print_readably, "[", "]", " "),
Hash(hm, _) => {
let l: Vec<MalVal> = hm
.iter()
.flat_map(|(k, v)| vec![Str(k.to_string()), v.clone()])
.collect();
pr_seq(&l, print_readably, "{", "}", " ")
}
Func(f, _) => format!("#<fn {:?}>", f),
MalFunc {
ast: a, params: p, ..
} => format!("(fn* {} {})", p.pr_str(true), a.pr_str(true)),
Atom(a) => format!("(atom {})", a.borrow().pr_str(true)),
MalVal::ZKScalar(a) => format!("{:?}", a),
i => format!("{:?}", i.pr_str(true)),
}
}
}
pub fn pr_seq(
seq: &Vec<MalVal>,
print_readably: bool,
start: &str,
end: &str,
join: &str,
) -> String {
let strs: Vec<String> = seq.iter().map(|x| x.pr_str(print_readably)).collect();
format!("{}{}{}", start, strs.join(join), end)
}

View File

@@ -1,113 +0,0 @@
#lang racket
(require "zk.rkt")
(struct jj_point
(u v)
)
(define (create_jj_param_point name)
(jj_point
(zk_param (string-append name "_u"))
(zk_param (string-append name "_v"))
)
)
(define (create_jj_public_point name)
(jj_point
(zk_public (string-append name "_u"))
(zk_public (string-append name "_v"))
)
)
(define (zk_jj_add namespace result a b)
(zk_comment "call jj_add()")
(let* ([namespace (append namespace (list "_jj_add"))]
[U (zk_private namespace 'U)]
[A (zk_private namespace 'A)]
[B (zk_private namespace 'B)]
[C (zk_private namespace 'C)]
[tmp (zk_local namespace 'tmp)])
(zk_comment "Compute U = (x1 + y1) * (y2 - EDWARDS_A*x2)")
(zk_comment " = (x1 + y1) * (x2 + y2)")
(zk_set U (jj_point-u a))
(zk_add U (jj_point-v a))
(zk_set tmp (jj_point-u b))
(zk_add tmp (jj_point-v b))
(zk_mul U tmp)
(zk_comment "assert (x1 + y1) * (x2 + y2) == U")
(zk_lc0_add (jj_point-u a))
(zk_lc0_add (jj_point-v a))
(zk_lc1_add (jj_point-u b))
(zk_lc1_add (jj_point-v b))
(zk_lc2_add U)
(zk_enforce)
(zk_comment "Compute A = y2 * x1")
(zk_set A (jj_point-v b))
(zk_mul A (jj_point-u a))
(zk_comment "Compute B = x2 * y1")
(zk_set B (jj_point-u b))
(zk_mul B (jj_point-v a))
(zk_comment "Compute C = d*A*B")
(zk_load C const_d)
(zk_mul C A)
(zk_mul C B)
(zk_comment "assert (d * A) * (B) == C")
(zk_lc0_add_coeff const_d A)
(zk_lc1_add B)
(zk_lc2_add C)
(zk_enforce)
(zk_comment "Compute P.x = (A + B) / (1 + C)")
(zk_set (jj_point-u result) A)
(zk_add (jj_point-u result) B)
; Re-use the tmp variable from earlier here
(zk_load tmp const_one)
(zk_add tmp C)
(zk_divide (jj_point-u result) tmp)
(zk_lc0_add_one)
(zk_lc0_add C)
(zk_lc1_add (jj_point-u result))
(zk_lc2_add A)
(zk_lc2_add B)
(zk_enforce)
(zk_comment "Compute P.y = (U - A - B) / (1 - C)")
(zk_set (jj_point-v result) U)
(zk_sub (jj_point-v result) A)
(zk_sub (jj_point-v result) B)
; Re-use the tmp variable from earlier here
(zk_load tmp const_one)
(zk_sub tmp C)
(zk_divide (jj_point-v result) tmp)
(zk_lc0_add_one)
(zk_lc0_sub C)
(zk_lc1_add (jj_point-v result))
(zk_lc2_add U)
(zk_lc2_sub A)
(zk_lc2_sub B)
(zk_enforce)
)
)
(create_zk_output "jj.psm")
(define const_d (zk_constant
"d" "0x2a9318e74bfa2b48f5fd9207e6bd7fd4292d7f6d37579d2601065fd6d6343eb1"))
(define const_one (zk_constant
"one" "0x0000000000000000000000000000000000000000000000000000000000000001"))
(zk_contract_begin "foo")
(define namespace (list "_"))
(define a (create_jj_param_point "a"))
(define b (create_jj_param_point "b"))
(define result (create_jj_public_point "result"))
(zk_jj_add namespace result a b)
(zk_contract_end)

View File

@@ -1,141 +0,0 @@
#lang racket
(provide zk_variable)
(provide zk_constant)
(provide zk_param)
(provide zk_public)
(provide zk_local)
(provide zk_private)
(provide zk_comment)
(provide zk_set)
(provide zk_add)
(provide zk_sub)
(provide zk_mul)
(provide zk_divide)
(provide zk_load)
(provide zk_lc0_add)
(provide zk_lc1_add)
(provide zk_lc2_add)
(provide zk_lc0_sub)
(provide zk_lc1_sub)
(provide zk_lc2_sub)
(provide zk_lc0_add_coeff)
(provide zk_lc1_add_coeff)
(provide zk_lc2_add_coeff)
(provide zk_lc0_add_one)
(provide zk_lc1_add_one)
(provide zk_lc2_add_one)
(provide zk_enforce)
(provide create_zk_output)
(provide zk_contract_begin)
(provide zk_contract_end)
(define out '0)
(define (create_zk_output filename)
(set! out (open-output-file "jj.psm" #:exists 'truncate))
)
(struct zk_variable
(name type)
)
(define (zk_constant name hex_value)
(fprintf out "constant ~a ~a\n" name hex_value)
name
)
(define (zk_contract_begin contract_name)
(fprintf out "contract ~a\n" contract_name)
)
(define (zk_contract_end)
(fprintf out "end\n")
)
(define (zk_param name)
(fprintf out "param ~a\n" name)
(zk_variable name 'param)
)
(define (zk_public name)
(fprintf out "public ~a\n" name)
(zk_variable name 'public)
)
(define (strings->string sts)
(apply string-append sts))
(define (apply_ns namespace name)
(strings->string
(append namespace
(list "__" (symbol->string name))
)))
(define (zk_local namespace name)
(let ([name (apply_ns namespace name)])
(fprintf out "local ~a\n" name)
(zk_variable name 'local)
)
)
(define (zk_private namespace name)
(let ([name (apply_ns namespace name)])
(fprintf out "private ~a\n" name)
(zk_variable name 'private)
)
)
(define (zk_comment str)
(fprintf out "# ~a\n" str)
)
(define (zk_set self other)
(fprintf out "set ~a ~a\n" (zk_variable-name self) (zk_variable-name other))
)
(define (zk_add self other)
(fprintf out "add ~a ~a\n" (zk_variable-name self) (zk_variable-name other))
)
(define (zk_sub self other)
(fprintf out "sub ~a ~a\n" (zk_variable-name self) (zk_variable-name other))
)
(define (zk_mul self other)
(fprintf out "mul ~a ~a\n" (zk_variable-name self) (zk_variable-name other))
)
(define (zk_divide self other)
(fprintf out "divide ~a ~a\n"
(zk_variable-name self) (zk_variable-name other))
)
(define (zk_load self constant)
(fprintf out "load ~a ~a\n" (zk_variable-name self) constant)
)
(define (zk_lc0_add self)
(fprintf out "lc0_add ~a\n" (zk_variable-name self)))
(define (zk_lc1_add self)
(fprintf out "lc1_add ~a\n" (zk_variable-name self)))
(define (zk_lc2_add self)
(fprintf out "lc2_add ~a\n" (zk_variable-name self)))
(define (zk_lc0_sub self)
(fprintf out "lc0_sub ~a\n" (zk_variable-name self)))
(define (zk_lc1_sub self)
(fprintf out "lc1_sub ~a\n" (zk_variable-name self)))
(define (zk_lc2_sub self)
(fprintf out "lc2_sub ~a\n" (zk_variable-name self)))
(define (zk_lc0_add_coeff constant self)
(fprintf out "lc0_add_coeff ~a ~a\n" constant (zk_variable-name self)))
(define (zk_lc1_add_coeff constant self)
(fprintf out "lc1_add_coeff ~a ~a\n" constant (zk_variable-name self)))
(define (zk_lc2_add_coeff constant self)
(fprintf out "lc2_add_coeff ~a ~a\n" constant (zk_variable-name self)))
(define (zk_lc0_add_one)
(fprintf out "lc0_add_one\n"))
(define (zk_lc1_add_one)
(fprintf out "lc1_add_one\n"))
(define (zk_lc2_add_one)
(fprintf out "lc2_add_one\n"))
(define (zk_enforce)
(fprintf out "enforce\n")
)

View File

@@ -1,156 +0,0 @@
use regex::{Captures, Regex};
use std::rc::Rc;
use crate::types::MalErr::ErrString;
use crate::types::MalVal::{Bool, Int, List, Nil, Str, Sym, Vector};
use crate::types::{error, hash_map, MalErr, MalRet, MalVal};
#[derive(Debug, Clone)]
struct Reader {
tokens: Vec<String>,
pos: usize,
}
impl Reader {
fn next(&mut self) -> Result<String, MalErr> {
self.pos = self.pos + 1;
Ok(self
.tokens
.get(self.pos - 1)
.ok_or(ErrString("underflow".to_string()))?
.to_string())
}
fn peek(&self) -> Result<String, MalErr> {
Ok(self
.tokens
.get(self.pos)
.ok_or(ErrString("underflow".to_string()))?
.to_string())
}
}
fn tokenize(str: &str) -> Vec<String> {
lazy_static! {
static ref RE: Regex = Regex::new(
r###"[\s,]*(~@|[\[\]{}()'`~^@]|"(?:\\.|[^\\"])*"?|;.*|[^\s\[\]{}('"`,;)]+)"###
)
.unwrap();
}
let mut res = vec![];
for cap in RE.captures_iter(str) {
if cap[1].starts_with(";") {
continue;
}
res.push(String::from(&cap[1]));
}
res
}
fn unescape_str(s: &str) -> String {
lazy_static! {
static ref RE: Regex = Regex::new(r#"\\(.)"#).unwrap();
}
RE.replace_all(&s, |caps: &Captures| {
format!("{}", if &caps[1] == "n" { "\n" } else { &caps[1] })
})
.to_string()
}
fn read_atom(rdr: &mut Reader) -> MalRet {
lazy_static! {
static ref INT_RE: Regex = Regex::new(r"^-?[0-9]+$").unwrap();
static ref STR_RE: Regex = Regex::new(r#""(?:\\.|[^\\"])*""#).unwrap();
}
let token = rdr.next()?;
match &token[..] {
"nil" => Ok(Nil),
"false" => Ok(Bool(false)),
"true" => Ok(Bool(true)),
_ => {
if INT_RE.is_match(&token) {
Ok(Int(token.parse().unwrap()))
} else if STR_RE.is_match(&token) {
Ok(Str(unescape_str(&token[1..token.len() - 1])))
} else if token.starts_with("\"") {
error("expected '\"', got EOF")
} else if token.starts_with(":") {
Ok(Str(format!("\u{29e}{}", &token[1..])))
} else {
Ok(Sym(token.to_string()))
}
}
}
}
fn read_seq(rdr: &mut Reader, end: &str) -> MalRet {
let mut seq: Vec<MalVal> = vec![];
rdr.next()?;
loop {
let token = match rdr.peek() {
Ok(t) => t,
Err(_) => return error(&format!("expected '{}', got EOF", end)),
};
if token == end {
break;
}
seq.push(read_form(rdr)?)
}
let _ = rdr.next();
match end {
")" => Ok(list!(seq)),
"]" => Ok(vector!(seq)),
"}" => hash_map(seq),
_ => error("read_seq unknown end value"),
}
}
fn read_form(rdr: &mut Reader) -> MalRet {
let token = rdr.peek()?;
match &token[..] {
"'" => {
let _ = rdr.next();
Ok(list![Sym("quote".to_string()), read_form(rdr)?])
}
"`" => {
let _ = rdr.next();
Ok(list![Sym("quasiquote".to_string()), read_form(rdr)?])
}
"~" => {
let _ = rdr.next();
Ok(list![Sym("unquote".to_string()), read_form(rdr)?])
}
"~@" => {
let _ = rdr.next();
Ok(list![Sym("splice-unquote".to_string()), read_form(rdr)?])
}
"^" => {
let _ = rdr.next();
let meta = read_form(rdr)?;
Ok(list![Sym("with-meta".to_string()), read_form(rdr)?, meta])
}
"@" => {
let _ = rdr.next();
Ok(list![Sym("deref".to_string()), read_form(rdr)?])
}
")" => error("unexpected ')'"),
"(" => read_seq(rdr, ")"),
"]" => error("unexpected ']'"),
"[" => read_seq(rdr, "]"),
"}" => error("unexpected '}'"),
"{" => read_seq(rdr, "}"),
_ => read_atom(rdr),
}
}
pub fn read_str(str: String) -> MalRet {
let tokens = tokenize(&str);
//println!("tokens: {:?}", tokens);
if tokens.len() == 0 {
return error("no input");
}
read_form(&mut Reader {
pos: 0,
tokens: tokens,
})
}

View File

@@ -1,4 +0,0 @@
export RUST_BACKTRACE=full
cargo run --bin lisp load mint2.lisp
#cargo run --bin lisp load jubjub-mul.lisp
#cargo run --bin lisp load new-cs.lisp

View File

@@ -1,471 +0,0 @@
use bellman::{groth16, Circuit, ConstraintSystem, SynthesisError};
use drk::bls_extensions::BlsStringConversion;
use std::rc::Rc;
use std::time::Instant;
use std::{cell::RefCell, collections::HashMap};
// use fnv::FnvHashMap;
use itertools::Itertools;
use crate::env::{env_bind, Env};
use crate::types::MalErr::{ErrMalVal, ErrString};
use crate::types::MalVal::{Atom, Bool, Func, Hash, Int, List, MalFunc, Nil, Str, Sym, Vector};
use bellman::Variable;
use bls12_381::Bls12;
use bls12_381::Scalar;
#[derive(Debug, Clone)]
pub struct Allocation {
pub symbol: String,
pub value: Scalar,
}
#[derive(Debug, Clone)]
pub struct EnforceAllocation {
pub idx: usize,
pub left: Vec<(String, String)>,
pub right: Vec<(String, String)>,
pub output: Vec<(String, String)>,
}
pub struct VerifyKeyParams {
pub random_params: groth16::Parameters<Bls12>,
pub verifying_key: groth16::PreparedVerifyingKey<Bls12>,
}
#[derive(Debug, Clone)]
pub struct LispCircuit {
pub params: HashMap<String, MalVal>,
pub allocs: HashMap<String, MalVal>,
pub alloc_inputs: HashMap<String, MalVal>,
pub constraints: Vec<EnforceAllocation>,
}
#[derive(Debug, Clone)]
pub enum MalVal {
Nil,
Bool(bool),
Int(i64),
Str(String),
Sym(String),
List(Rc<Vec<MalVal>>, Rc<MalVal>),
Vector(Rc<Vec<MalVal>>, Rc<MalVal>),
Hash(Rc<HashMap<String, MalVal>>, Rc<MalVal>),
Func(fn(MalArgs) -> MalRet, Rc<MalVal>),
MalFunc {
eval: fn(ast: MalVal, env: Env) -> MalRet,
ast: Rc<MalVal>,
env: Env,
params: Rc<MalVal>,
is_macro: bool,
meta: Rc<MalVal>,
},
Atom(Rc<RefCell<MalVal>>),
Alloc(RefCell<HashMap<String, MalVal>>),
Enforce(Rc<Vec<EnforceAllocation>>),
ZKScalar(bls12_381::Scalar),
}
impl Circuit<bls12_381::Scalar> for LispCircuit {
fn synthesize<CS: ConstraintSystem<bls12_381::Scalar>>(
self,
cs: &mut CS,
) -> Result<(), SynthesisError> {
let mut variables: HashMap<String, Variable> = HashMap::default();
// TODO change the name from alloc-const to constant
let params_const = self.params;
let circuitTime = Instant::now();
let start = Instant::now();
// println!("Allocations\n");
// TODO is the private and params
for (k, v) in &self.allocs {
match v {
MalVal::ZKScalar(val) => {
let var = cs.alloc(|| k, || Ok(*val))?;
variables.insert(k.to_string(), var);
}
MalVal::Str(val) => {
let val_scalar = bls12_381::Scalar::from_string(&*val);
let var = cs.alloc(|| k, || Ok(val_scalar))?;
variables.insert(k.to_string(), var);
}
MalVal::Vector(val, _) => {
if let MalVal::ZKScalar(v) = &val.to_vec()[0] {
let var = cs.alloc(|| k, || Ok(*v))?;
variables.insert(k.to_string(), var);
}
}
_ => {
println!("not allocated k {:?} v {:?}", k, v);
}
}
}
println!("circuit alloc \t {:?}", start.elapsed());
let start = Instant::now();
// println!("Allocations Input\n");
// TODO alloc-input is the public value
for (k, v) in &self.alloc_inputs {
match v {
MalVal::ZKScalar(val) => {
let var = cs.alloc_input(|| k, || Ok(*val))?;
variables.insert(k.to_string(), var);
// println!("k {:?} v {:?} var {:?}", k, v, var);
}
MalVal::Str(val) => {
let val_scalar = bls12_381::Scalar::from_string(&*val);
let var = cs.alloc_input(|| k, || Ok(val_scalar))?;
variables.insert(k.to_string(), var);
// println!("k {:?} v {:?} var {:?}", k, v, var);
}
_ => {
println!("not allocated k {:?} v {:?}", k, v);
}
}
}
println!("circuit alloc input \t {:?}", start.elapsed());
let start = Instant::now();
let enforce_sorted = self.constraints.clone();
// enforce_sorted.sort_by(|a, b| a.idx.cmp(&b.idx));
for alloc_value in enforce_sorted.iter() {
// println!("Enforce -> {:?}", alloc_value);
let coeff = bls12_381::Scalar::one();
let mut left = bellman::LinearCombination::<Scalar>::zero();
let mut right = bellman::LinearCombination::<Scalar>::zero();
let mut output = bellman::LinearCombination::<Scalar>::zero();
for values in alloc_value.left.iter() {
let (a, b) = values;
let mut val_b = CS::one();
if b != "cs::one" {
// println!("{:?}", b);
val_b = *variables.get(b).unwrap();
}
if a == "scalar::one" {
left = left + (coeff, val_b);
} else if a == "scalar::one::neg" {
left = left + (coeff.neg(), val_b);
} else {
if let Some(value) = params_const.get(a) {
match value {
MalVal::ZKScalar(val) => {
left = left + (*val, val_b);
}
MalVal::Str(s) => {
let val = bls12_381::Scalar::from_string(&s.to_string());
left = left + (val, val_b);
}
MalVal::Func(_, _) => {
if let MalVal::Vector(val, _) = value.apply(vec![]).unwrap() {
if let MalVal::ZKScalar(res) = val.to_vec()[0] {
left = left + (res, val_b);
}
}
}
_ => {
println!("not a valid param {:?}", value)
}
}
}
}
// println!("left: a {:?} b {:?} val_b: {:?}", a, b, val_b);
}
for values in alloc_value.right.iter() {
let (a, b) = values;
let mut val_b = CS::one();
if b != "cs::one" {
val_b = *variables.get(b).unwrap();
}
if a == "scalar::one" {
right = right + (coeff, val_b);
} else if a == "scalar::one::neg" {
right = right + (coeff.neg(), val_b);
} else {
if let Some(value) = params_const.get(a) {
match value {
MalVal::ZKScalar(val) => {
right = right + (*val, val_b);
}
MalVal::Str(s) => {
let val = bls12_381::Scalar::from_string(&s.to_string());
right = right + (val, val_b);
}
MalVal::Func(_, _) => {
if let MalVal::Vector(val, _) = value.apply(vec![]).unwrap() {
if let MalVal::ZKScalar(res) = val.to_vec()[0] {
right = right + (res, val_b);
}
}
}
_ => {
println!("not a valid param {:?}", value)
}
}
}
}
// println!("right: a {:?} b {:?} val_b: {:?}", a, b, val_b);
}
for values in alloc_value.output.iter() {
let (a, b) = values;
let mut val_b = CS::one();
if b != "cs::one" {
// println!("{:?}", b);
val_b = *variables.get(b).unwrap();
}
if a == "scalar::one" {
output = output + (coeff, val_b);
} else if a == "scalar::one::neg" {
output = output + (coeff.neg(), val_b);
} else {
if let Some(value) = params_const.get(a) {
match value {
MalVal::ZKScalar(val) => {
output = output + (*val, val_b);
}
MalVal::Str(s) => {
let val = bls12_381::Scalar::from_string(&s.to_string());
output = output + (val, val_b);
}
MalVal::Func(_, _) => {
if let MalVal::Vector(val, _) = value.apply(vec![]).unwrap() {
if let MalVal::ZKScalar(res) = val.to_vec()[0] {
output = output + (res, val_b);
}
}
}
_ => {
println!("not a valid param {:?}", value)
}
}
}
}
// println!("output: a {:?} b {:?} val_b: {:?}", a, b, val_b);
}
// println!("Enforcing ...");
cs.enforce(
|| "constraint",
|_| left.clone(),
|_| right.clone(),
|_| output.clone(),
);
}
println!("circuit enforce \t {:?}", start.elapsed());
println!("end circuit \t {:?}", circuitTime.elapsed());
Ok(())
}
}
#[derive(Debug)]
pub enum MalErr {
ErrString(String),
ErrMalVal(MalVal),
}
impl From<SynthesisError> for MalErr {
fn from(err: SynthesisError) -> MalErr {
ErrString(err.to_string())
}
}
pub type MalArgs = Vec<MalVal>;
pub type MalRet = Result<MalVal, MalErr>;
// type utility macros
macro_rules! list {
($seq:expr) => {{
List(Rc::new($seq),Rc::new(Nil))
}};
[$($args:expr),*] => {{
let v: Vec<MalVal> = vec![$($args),*];
List(Rc::new(v),Rc::new(Nil))
}}
}
macro_rules! vector {
($seq:expr) => {{
Vector(Rc::new($seq),Rc::new(Nil))
}};
[$($args:expr),*] => {{
let v: Vec<MalVal> = vec![$($args),*];
Vector(Rc::new(v),Rc::new(Nil))
}}
}
// type utility functions
pub fn error(s: &str) -> MalRet {
Err(ErrString(s.to_string()))
}
pub fn format_error(e: MalErr) -> String {
match e {
ErrString(s) => s.clone(),
ErrMalVal(mv) => mv.pr_str(true),
}
}
pub fn atom(mv: &MalVal) -> MalVal {
Atom(Rc::new(RefCell::new(mv.clone())))
}
impl MalVal {
pub fn keyword(&self) -> MalRet {
match self {
Str(s) if s.starts_with("\u{29e}") => Ok(Str(s.to_string())),
Str(s) => Ok(Str(format!("\u{29e}{}", s))),
_ => error("invalid type for keyword"),
}
}
pub fn empty_q(&self) -> MalRet {
match self {
List(l, _) | Vector(l, _) => Ok(Bool(l.len() == 0)),
Nil => Ok(Bool(true)),
_ => error("invalid type for empty?"),
}
}
pub fn count(&self) -> MalRet {
match self {
List(l, _) | Vector(l, _) => Ok(Int(l.len() as i64)),
Nil => Ok(Int(0)),
_ => error("invalid type for count"),
}
}
pub fn apply(&self, args: MalArgs) -> MalRet {
match *self {
Func(f, _) => f(args),
MalFunc {
eval,
ref ast,
ref env,
ref params,
..
} => {
let a = &**ast;
let p = &**params;
let fn_env = env_bind(Some(env.clone()), p.clone(), args)?;
Ok(eval(a.clone(), fn_env)?)
}
_ => error("attempt to call non-function"),
}
}
pub fn keyword_q(&self) -> bool {
match self {
Str(s) if s.starts_with("\u{29e}") => true,
_ => false,
}
}
pub fn deref(&self) -> MalRet {
match self {
Atom(a) => Ok(a.borrow().clone()),
_ => error("attempt to deref a non-Atom"),
}
}
pub fn reset_bang(&self, new: &MalVal) -> MalRet {
match self {
Atom(a) => {
*a.borrow_mut() = new.clone();
Ok(new.clone())
}
_ => error("attempt to reset! a non-Atom"),
}
}
pub fn swap_bang(&self, args: &MalArgs) -> MalRet {
match self {
Atom(a) => {
let f = &args[0];
let mut fargs = args[1..].to_vec();
fargs.insert(0, a.borrow().clone());
*a.borrow_mut() = f.apply(fargs)?;
Ok(a.borrow().clone())
}
_ => error("attempt to swap! a non-Atom"),
}
}
pub fn get_meta(&self) -> MalRet {
match self {
List(_, meta) | Vector(_, meta) | Hash(_, meta) => Ok((&**meta).clone()),
Func(_, meta) => Ok((&**meta).clone()),
MalFunc { meta, .. } => Ok((&**meta).clone()),
_ => error("meta not supported by type"),
}
}
pub fn with_meta(&mut self, new_meta: &MalVal) -> MalRet {
match self {
List(_, ref mut meta)
| Vector(_, ref mut meta)
| Hash(_, ref mut meta)
| Func(_, ref mut meta)
| MalFunc { ref mut meta, .. } => {
*meta = Rc::new((&*new_meta).clone());
}
_ => return error("with-meta not supported by type"),
};
Ok(self.clone())
}
}
impl PartialEq for MalVal {
fn eq(&self, other: &MalVal) -> bool {
match (self, other) {
(Nil, Nil) => true,
(Bool(ref a), Bool(ref b)) => a == b,
(Int(ref a), Int(ref b)) => a == b,
(Str(ref a), Str(ref b)) => a == b,
(Sym(ref a), Sym(ref b)) => a == b,
(List(ref a, _), List(ref b, _))
| (Vector(ref a, _), Vector(ref b, _))
| (List(ref a, _), Vector(ref b, _))
| (Vector(ref a, _), List(ref b, _)) => a == b,
(Hash(ref a, _), Hash(ref b, _)) => a == b,
(MalFunc { .. }, MalFunc { .. }) => false,
_ => false,
}
}
}
pub fn func(f: fn(MalArgs) -> MalRet) -> MalVal {
Func(f, Rc::new(Nil))
}
pub fn _assoc(mut hm: HashMap<String, MalVal>, kvs: MalArgs) -> MalRet {
if kvs.len() % 2 != 0 {
return error("odd number of elements");
}
for (k, v) in kvs.iter().tuples() {
match k {
Str(s) => {
hm.insert(s.to_string(), v.clone());
}
_ => return error("key is not string"),
}
}
Ok(Hash(Rc::new(hm), Rc::new(Nil)))
}
pub fn _dissoc(mut hm: HashMap<String, MalVal>, ks: MalArgs) -> MalRet {
for k in ks.iter() {
match k {
Str(ref s) => {
hm.remove(s);
}
_ => return error("key is not string"),
}
}
Ok(Hash(Rc::new(hm), Rc::new(Nil)))
}
pub fn hash_map(kvs: MalArgs) -> MalRet {
let hm: HashMap<String, MalVal> = HashMap::default();
_assoc(hm, kvs)
}