Skip to content

Commit

Permalink
Added arithmetic operations
Browse files Browse the repository at this point in the history
  • Loading branch information
gabriel-barrett committed Jul 27, 2023
1 parent 6ab495a commit e952578
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 18 deletions.
60 changes: 59 additions & 1 deletion src/lem/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ use bellperson::{

use crate::circuit::gadgets::{
constraints::{
alloc_equal, alloc_equal_const, and, enforce_selector_with_premise, implies_equal,
add, alloc_equal, alloc_equal_const, and, enforce_selector_with_premise, implies_equal,
mul, sub,
},
data::{allocate_constant, hash_poseidon},
pointer::AllocatedPtr,
Expand Down Expand Up @@ -753,6 +754,48 @@ impl Func {
let allocated_ptr = AllocatedPtr::from_parts(tag, src.hash().clone());
bound_allocations.insert(tgt.clone(), allocated_ptr);
}
Op::Add(tgt, a, b) => {
let a = bound_allocations.get(a)?;
let b = bound_allocations.get(b)?;
// TODO check that the tags are correct
let a_num = a.hash();
let b_num = b.hash();
let c_num = add(&mut cs.namespace(|| "add"), a_num, b_num)?;
let tag = g
.global_allocator
.get_or_alloc_const(cs, Tag::Expr(Num).to_field())?;
let c = AllocatedPtr::from_parts(tag, c_num);
bound_allocations.insert(tgt.clone(), c);
}
Op::Sub(tgt, a, b) => {
let a = bound_allocations.get(a)?;
let b = bound_allocations.get(b)?;
// TODO check that the tags are correct
let a_num = a.hash();
let b_num = b.hash();
let c_num = sub(&mut cs.namespace(|| "sub"), a_num, b_num)?;
let tag = g
.global_allocator
.get_or_alloc_const(cs, Tag::Expr(Num).to_field())?;
let c = AllocatedPtr::from_parts(tag, c_num);
bound_allocations.insert(tgt.clone(), c);
}
Op::Mul(tgt, a, b) => {
let a = bound_allocations.get(a)?;
let b = bound_allocations.get(b)?;
// TODO check that the tags are correct
let a_num = a.hash();
let b_num = b.hash();
let c_num = mul(&mut cs.namespace(|| "mul"), a_num, b_num)?;
let tag = g
.global_allocator
.get_or_alloc_const(cs, Tag::Expr(Num).to_field())?;
let c = AllocatedPtr::from_parts(tag, c_num);
bound_allocations.insert(tgt.clone(), c);
}
Op::Div(_tgt, _a, _b) => {
// TODO
}
Op::Hide(tgt, _sec, _pay) => {
// TODO
let allocated_ptr = AllocatedPtr::from_parts(
Expand Down Expand Up @@ -1027,6 +1070,21 @@ impl Func {
Op::Cast(_tgt, tag, _src) => {
globals.insert(FWrap(tag.to_field()));
}
Op::Add(_, _, _) => {
globals.insert(FWrap(Tag::Expr(Num).to_field()));
num_constraints += 1;
}
Op::Sub(_, _, _) => {
globals.insert(FWrap(Tag::Expr(Num).to_field()));
num_constraints += 1;
}
Op::Mul(_, _, _) => {
globals.insert(FWrap(Tag::Expr(Num).to_field()));
num_constraints += 1;
}
Op::Div(_, _, _) => {
// TODO
}
Op::Hash2(_, tag, _) => {
// tag for the image
globals.insert(FWrap(tag.to_field()));
Expand Down
30 changes: 16 additions & 14 deletions src/lem/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ fn apply_cont() -> Func {
Op1::Num => {
match result.tag {
Expr::Num | Expr::Comm | Expr::Char | Expr::U64 => {
let cast = Cast(result, Expr::Num);
let cast = cast(result, Expr::Num);
return(cast, env, continuation, makethunk)
}
};
Expand All @@ -676,7 +676,7 @@ fn apply_cont() -> Func {
// But 2^64 is out-of-range of u64, so we will
// maybe use u128
// let limit = Num(18446744073709551616);
let cast = Cast(result, Expr::U64);
let cast = cast(result, Expr::U64);
return(cast, env, continuation, makethunk)
}
Expr::U64 => {
Expand All @@ -688,7 +688,7 @@ fn apply_cont() -> Func {
Op1::Comm => {
match result.tag {
Expr::Num | Expr::Comm => {
let cast = Cast(result, Expr::Num);
let cast = cast(result, Expr::Num);
return(cast, env, continuation, makethunk)
}
};
Expand All @@ -699,7 +699,7 @@ fn apply_cont() -> Func {
Expr::Num | Expr::Char => {
// TODO we also need to use `Mod` to truncate
// let limit = Num(4294967296);
let cast = Cast(result, Expr::Num);
let cast = cast(result, Expr::Num);
return(cast, env, continuation, makethunk)
}
};
Expand Down Expand Up @@ -759,7 +759,7 @@ fn apply_cont() -> Func {
return (result, env, err, errctrl)
}
Op2::Hide => {
let num = Cast(evaled_arg, Expr::Num);
let num = cast(evaled_arg, Expr::Num);
let hidden = hide(num, result);
return(hidden, env, continuation, makethunk)
}
Expand All @@ -768,19 +768,21 @@ fn apply_cont() -> Func {
return (result, env, err, errctrl)
}
Op2::Sum => {
// TODO
return (result, env, err, errctrl)
// TODO deal with U64
let val = add(evaled_arg, result);
return (val, env, continuation, makethunk)
}
Op2::Diff => {
// TODO
return (result, env, err, errctrl)
// TODO deal with U64
let val = sub(evaled_arg, result);
return (val, env, continuation, makethunk)
}
Op2::Product => {
// TODO
return (result, env, err, errctrl)
// TODO deal with U64
let val = mul(evaled_arg, result);
return (val, env, continuation, makethunk)
}
Op2::Quotient => {
// TODO
return (result, env, err, errctrl)
}
Op2::Modulo => {
Expand Down Expand Up @@ -877,8 +879,8 @@ mod tests {
use blstrs::Scalar as Fr;

const NUM_INPUTS: usize = 1;
const NUM_AUX: usize = 8024;
const NUM_CONSTRAINTS: usize = 9964;
const NUM_AUX: usize = 8027;
const NUM_CONSTRAINTS: usize = 9967;
const NUM_SLOTS: SlotsCounter = SlotsCounter {
hash2: 16,
hash3: 4,
Expand Down
44 changes: 44 additions & 0 deletions src/lem/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,50 @@ impl Block {
let tgt_ptr = src_ptr.cast(*tag);
bindings.insert(tgt.clone(), tgt_ptr);
}
Op::Add(tgt, a, b) => {
let a = bindings.get(a)?;
let b = bindings.get(b)?;
let c = match (a, b) {
(Ptr::Leaf(Tag::Expr(Num), f), Ptr::Leaf(Tag::Expr(Num), g)) => {
Ptr::Leaf(Tag::Expr(Num), *f + *g)
}
_ => bail!("Addition only works on numbers"),
};
bindings.insert(tgt.clone(), c);
}
Op::Sub(tgt, a, b) => {
let a = bindings.get(a)?;
let b = bindings.get(b)?;
let c = match (a, b) {
(Ptr::Leaf(Tag::Expr(Num), f), Ptr::Leaf(Tag::Expr(Num), g)) => {
Ptr::Leaf(Tag::Expr(Num), *f - *g)
}
_ => bail!("Addition only works on numbers"),
};
bindings.insert(tgt.clone(), c);
}
Op::Mul(tgt, a, b) => {
let a = bindings.get(a)?;
let b = bindings.get(b)?;
let c = match (a, b) {
(Ptr::Leaf(Tag::Expr(Num), f), Ptr::Leaf(Tag::Expr(Num), g)) => {
Ptr::Leaf(Tag::Expr(Num), *f * *g)
}
_ => bail!("Addition only works on numbers"),
};
bindings.insert(tgt.clone(), c);
}
Op::Div(tgt, a, b) => {
let a = bindings.get(a)?;
let b = bindings.get(b)?;
let c = match (a, b) {
(Ptr::Leaf(Tag::Expr(Num), f), Ptr::Leaf(Tag::Expr(Num), g)) => {
Ptr::Leaf(Tag::Expr(Num), *f * g.invert().unwrap())
}
_ => bail!("Division only works on numbers"),
};
bindings.insert(tgt.clone(), c);
}
Op::Hash2(img, tag, preimg) => {
let preimg_ptrs = bindings.get_many_cloned(preimg)?;
let tgt_ptr = store.intern_2_ptrs(*tag, preimg_ptrs[0], preimg_ptrs[1]);
Expand Down
74 changes: 71 additions & 3 deletions src/lem/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,41 @@ macro_rules! op {
$crate::lit!($constr($str))
)
};
( let $tgt:ident = Cast($src:ident, $kind:ident::$tag:ident) ) => {
( let $tgt:ident = cast($src:ident, $kind:ident::$tag:ident) ) => {
$crate::lem::Op::Cast(
$crate::var!($tgt),
$crate::tag!($kind::$tag),
$crate::var!($src),
)
};
( let $tgt:ident = add($a:ident, $b:ident) ) => {
$crate::lem::Op::Add(
$crate::var!($tgt),
$crate::var!($a),
$crate::var!($b),
)
};
( let $tgt:ident = sub($a:ident, $b:ident) ) => {
$crate::lem::Op::Sub(
$crate::var!($tgt),
$crate::var!($a),
$crate::var!($b),
)
};
( let $tgt:ident = mul($a:ident, $b:ident) ) => {
$crate::lem::Op::Mul(
$crate::var!($tgt),
$crate::var!($a),
$crate::var!($b),
)
};
( let $tgt:ident = div($a:ident, $b:ident) ) => {
$crate::lem::Op::Div(
$crate::var!($tgt),
$crate::var!($a),
$crate::var!($b),
)
};
( let $tgt:ident : $kind:ident::$tag:ident = hash2($src1:ident, $src2:ident) ) => {
$crate::lem::Op::Hash2(
$crate::var!($tgt),
Expand Down Expand Up @@ -208,12 +236,52 @@ macro_rules! block {
$($tail)*
)
};
(@seq {$($limbs:expr)*}, let $tgt:ident = Cast($src:ident, $kind:ident::$tag:ident) ; $($tail:tt)*) => {
(@seq {$($limbs:expr)*}, let $tgt:ident = cast($src:ident, $kind:ident::$tag:ident) ; $($tail:tt)*) => {
$crate::block! (
@seq
{
$($limbs)*
$crate::op!(let $tgt = cast($src, $kind::$tag))
},
$($tail)*
)
};
(@seq {$($limbs:expr)*}, let $tgt:ident = add($a:ident, $b:ident) ; $($tail:tt)*) => {
$crate::block! (
@seq
{
$($limbs)*
$crate::op!(let $tgt = add($a, $b))
},
$($tail)*
)
};
(@seq {$($limbs:expr)*}, let $tgt:ident = sub($a:ident, $b:ident) ; $($tail:tt)*) => {
$crate::block! (
@seq
{
$($limbs)*
$crate::op!(let $tgt = sub($a, $b))
},
$($tail)*
)
};
(@seq {$($limbs:expr)*}, let $tgt:ident = mul($a:ident, $b:ident) ; $($tail:tt)*) => {
$crate::block! (
@seq
{
$($limbs)*
$crate::op!(let $tgt = mul($a, $b))
},
$($tail)*
)
};
(@seq {$($limbs:expr)*}, let $tgt:ident = div($a:ident, $b:ident) ; $($tail:tt)*) => {
$crate::block! (
@seq
{
$($limbs)*
$crate::op!(let $tgt = Cast($src, $kind::$tag))
$crate::op!(let $tgt = div($a, $b))
},
$($tail)*
)
Expand Down
40 changes: 40 additions & 0 deletions src/lem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,14 @@ pub enum Op {
Lit(Var, Lit),
/// `Cast(y, t, x)` binds `y` to a pointer with tag `t` and the hash of `x`
Cast(Var, Tag, Var),
/// `Add(y, a, b)` binds `y` to the sum of `a` and `b`
Add(Var, Var, Var),
/// `Sub(y, a, b)` binds `y` to the sum of `a` and `b`
Sub(Var, Var, Var),
/// `Mul(y, a, b)` binds `y` to the sum of `a` and `b`
Mul(Var, Var, Var),
/// `Div(y, a, b)` binds `y` to the sum of `a` and `b`
Div(Var, Var, Var),
/// `Hash2(x, t, ys)` binds `x` to a `Ptr` with tag `t` and 2 children `ys`
Hash2(Var, Tag, [Var; 2]),
/// `Hash3(x, t, ys)` binds `x` to a `Ptr` with tag `t` and 3 children `ys`
Expand Down Expand Up @@ -327,6 +335,14 @@ impl Func {
is_bound(src, map)?;
is_unique(tgt, map);
}
Op::Add(tgt, a, b)
| Op::Sub(tgt, a, b)
| Op::Mul(tgt, a, b)
| Op::Div(tgt, a, b) => {
is_bound(a, map)?;
is_bound(b, map)?;
is_unique(tgt, map);
}
Op::Hash2(img, _tag, preimg) => {
preimg.iter().try_for_each(|arg| is_bound(arg, map))?;
is_unique(img, map);
Expand Down Expand Up @@ -524,6 +540,30 @@ impl Block {
let tgt = insert_one(map, uniq, &tgt);
ops.push(Op::Cast(tgt, tag, src))
}
Op::Add(tgt, a, b) => {
let a = map.get_cloned(&a)?;
let b = map.get_cloned(&b)?;
let tgt = insert_one(map, uniq, &tgt);
ops.push(Op::Add(tgt, a, b))
}
Op::Sub(tgt, a, b) => {
let a = map.get_cloned(&a)?;
let b = map.get_cloned(&b)?;
let tgt = insert_one(map, uniq, &tgt);
ops.push(Op::Sub(tgt, a, b))
}
Op::Mul(tgt, a, b) => {
let a = map.get_cloned(&a)?;
let b = map.get_cloned(&b)?;
let tgt = insert_one(map, uniq, &tgt);
ops.push(Op::Mul(tgt, a, b))
}
Op::Div(tgt, a, b) => {
let a = map.get_cloned(&a)?;
let b = map.get_cloned(&b)?;
let tgt = insert_one(map, uniq, &tgt);
ops.push(Op::Div(tgt, a, b))
}
Op::Hash2(img, tag, preimg) => {
let preimg = map.get_many_cloned(&preimg)?.try_into().unwrap();
let img = insert_one(map, uniq, &img);
Expand Down

0 comments on commit e952578

Please sign in to comment.