chore: implement Gt and GtEq as syntactic sugar (#216)
* Implement Gt and GtEq as syntactic sugar * Update src/backends/plonky2/circuits/mainpod.rs Co-authored-by: Eduard S. <eduardsanou@posteo.net> * Op verification circuit refactor * Code review * Add range check to Eq case of LtEq * Style * Factor out ValueOf statement argument type checks * Formatting * Clean-up * Safety * Take sign into account * Simplify sign check --------- Co-authored-by: Eduard S. <eduardsanou@posteo.net>
This commit is contained in:
parent
e420aa7b32
commit
53ade6ea26
6 changed files with 451 additions and 170 deletions
|
|
@ -60,16 +60,15 @@ pub enum NativeOperation {
|
|||
CopyStatement = 2,
|
||||
EqualFromEntries = 3,
|
||||
NotEqualFromEntries = 4,
|
||||
GtFromEntries = 5,
|
||||
LtEqFromEntries = 5,
|
||||
LtFromEntries = 6,
|
||||
TransitiveEqualFromStatements = 7,
|
||||
GtToNotEqual = 8,
|
||||
LtToNotEqual = 9,
|
||||
ContainsFromEntries = 10,
|
||||
NotContainsFromEntries = 11,
|
||||
SumOf = 13,
|
||||
ProductOf = 14,
|
||||
MaxOf = 15,
|
||||
LtToNotEqual = 8,
|
||||
ContainsFromEntries = 9,
|
||||
NotContainsFromEntries = 10,
|
||||
SumOf = 11,
|
||||
ProductOf = 12,
|
||||
MaxOf = 13,
|
||||
|
||||
// Syntactic sugar operations. These operations are not supported by the backend. The
|
||||
// frontend compiler is responsible of translating these operations into the operations above.
|
||||
|
|
@ -78,6 +77,9 @@ pub enum NativeOperation {
|
|||
SetContainsFromEntries = 1003,
|
||||
SetNotContainsFromEntries = 1004,
|
||||
ArrayContainsFromEntries = 1005,
|
||||
GtEqFromEntries = 1006,
|
||||
GtFromEntries = 1007,
|
||||
GtToNotEqual = 1008,
|
||||
}
|
||||
|
||||
impl ToFields for NativeOperation {
|
||||
|
|
@ -102,12 +104,11 @@ impl OperationType {
|
|||
NativeOperation::NotEqualFromEntries => {
|
||||
Some(Predicate::Native(NativePredicate::NotEqual))
|
||||
}
|
||||
NativeOperation::GtFromEntries => Some(Predicate::Native(NativePredicate::Gt)),
|
||||
NativeOperation::LtEqFromEntries => Some(Predicate::Native(NativePredicate::LtEq)),
|
||||
NativeOperation::LtFromEntries => Some(Predicate::Native(NativePredicate::Lt)),
|
||||
NativeOperation::TransitiveEqualFromStatements => {
|
||||
Some(Predicate::Native(NativePredicate::Equal))
|
||||
}
|
||||
NativeOperation::GtToNotEqual => Some(Predicate::Native(NativePredicate::NotEqual)),
|
||||
NativeOperation::LtToNotEqual => Some(Predicate::Native(NativePredicate::NotEqual)),
|
||||
NativeOperation::ContainsFromEntries => {
|
||||
Some(Predicate::Native(NativePredicate::Contains))
|
||||
|
|
@ -133,10 +134,9 @@ pub enum Operation {
|
|||
CopyStatement(Statement),
|
||||
EqualFromEntries(Statement, Statement),
|
||||
NotEqualFromEntries(Statement, Statement),
|
||||
GtFromEntries(Statement, Statement),
|
||||
LtEqFromEntries(Statement, Statement),
|
||||
LtFromEntries(Statement, Statement),
|
||||
TransitiveEqualFromStatements(Statement, Statement),
|
||||
GtToNotEqual(Statement),
|
||||
LtToNotEqual(Statement),
|
||||
ContainsFromEntries(
|
||||
/* root */ Statement,
|
||||
|
|
@ -165,10 +165,9 @@ impl Operation {
|
|||
Self::CopyStatement(_) => OT::Native(CopyStatement),
|
||||
Self::EqualFromEntries(_, _) => OT::Native(EqualFromEntries),
|
||||
Self::NotEqualFromEntries(_, _) => OT::Native(NotEqualFromEntries),
|
||||
Self::GtFromEntries(_, _) => OT::Native(GtFromEntries),
|
||||
Self::LtEqFromEntries(_, _) => OT::Native(LtEqFromEntries),
|
||||
Self::LtFromEntries(_, _) => OT::Native(LtFromEntries),
|
||||
Self::TransitiveEqualFromStatements(_, _) => OT::Native(TransitiveEqualFromStatements),
|
||||
Self::GtToNotEqual(_) => OT::Native(GtToNotEqual),
|
||||
Self::LtToNotEqual(_) => OT::Native(LtToNotEqual),
|
||||
Self::ContainsFromEntries(_, _, _, _) => OT::Native(ContainsFromEntries),
|
||||
Self::NotContainsFromEntries(_, _, _) => OT::Native(NotContainsFromEntries),
|
||||
|
|
@ -186,10 +185,9 @@ impl Operation {
|
|||
Self::CopyStatement(s) => vec![s],
|
||||
Self::EqualFromEntries(s1, s2) => vec![s1, s2],
|
||||
Self::NotEqualFromEntries(s1, s2) => vec![s1, s2],
|
||||
Self::GtFromEntries(s1, s2) => vec![s1, s2],
|
||||
Self::LtEqFromEntries(s1, s2) => vec![s1, s2],
|
||||
Self::LtFromEntries(s1, s2) => vec![s1, s2],
|
||||
Self::TransitiveEqualFromStatements(s1, s2) => vec![s1, s2],
|
||||
Self::GtToNotEqual(s) => vec![s],
|
||||
Self::LtToNotEqual(s) => vec![s],
|
||||
Self::ContainsFromEntries(s1, s2, s3, _pf) => vec![s1, s2, s3],
|
||||
Self::NotContainsFromEntries(s1, s2, _pf) => vec![s1, s2],
|
||||
|
|
@ -229,8 +227,8 @@ impl Operation {
|
|||
(NO::NotEqualFromEntries, (Some(s1), Some(s2), None), OA::None, 2) => {
|
||||
Self::NotEqualFromEntries(s1, s2)
|
||||
}
|
||||
(NO::GtFromEntries, (Some(s1), Some(s2), None), OA::None, 2) => {
|
||||
Self::GtFromEntries(s1, s2)
|
||||
(NO::LtEqFromEntries, (Some(s1), Some(s2), None), OA::None, 2) => {
|
||||
Self::LtEqFromEntries(s1, s2)
|
||||
}
|
||||
(NO::LtFromEntries, (Some(s1), Some(s2), None), OA::None, 2) => {
|
||||
Self::LtFromEntries(s1, s2)
|
||||
|
|
@ -282,8 +280,8 @@ impl Operation {
|
|||
(Self::NotEqualFromEntries(ValueOf(ak1, v1), ValueOf(ak2, v2)), NotEqual(ak3, ak4)) => {
|
||||
Ok(v1 != v2 && ak3 == ak1 && ak4 == ak2)
|
||||
}
|
||||
(Self::GtFromEntries(ValueOf(ak1, v1), ValueOf(ak2, v2)), Gt(ak3, ak4)) => {
|
||||
Ok(v1 > v2 && ak3 == ak1 && ak4 == ak2)
|
||||
(Self::LtEqFromEntries(ValueOf(ak1, v1), ValueOf(ak2, v2)), LtEq(ak3, ak4)) => {
|
||||
Ok(v1 <= v2 && ak3 == ak1 && ak4 == ak2)
|
||||
}
|
||||
(Self::LtFromEntries(ValueOf(ak1, v1), ValueOf(ak2, v2)), Lt(ak3, ak4)) => {
|
||||
Ok(v1 < v2 && ak3 == ak1 && ak4 == ak2)
|
||||
|
|
@ -302,7 +300,6 @@ impl Operation {
|
|||
Self::TransitiveEqualFromStatements(Equal(ak1, ak2), Equal(ak3, ak4)),
|
||||
Equal(ak5, ak6),
|
||||
) => Ok(ak2 == ak3 && ak5 == ak1 && ak6 == ak4),
|
||||
(Self::GtToNotEqual(Gt(ak1, ak2)), NotEqual(ak3, ak4)) => Ok(ak1 == ak3 && ak2 == ak4),
|
||||
(Self::LtToNotEqual(Lt(ak1, ak2)), NotEqual(ak3, ak4)) => Ok(ak1 == ak3 && ak2 == ak4),
|
||||
(
|
||||
Self::SumOf(ValueOf(ak1, v1), ValueOf(ak2, v2), ValueOf(ak3, v3)),
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ pub enum NativePredicate {
|
|||
ValueOf = 1,
|
||||
Equal = 2,
|
||||
NotEqual = 3,
|
||||
Gt = 4,
|
||||
LtEq = 4,
|
||||
Lt = 5,
|
||||
Contains = 6,
|
||||
NotContains = 7,
|
||||
|
|
@ -40,6 +40,8 @@ pub enum NativePredicate {
|
|||
SetContains = 1002,
|
||||
SetNotContains = 1003,
|
||||
ArrayContains = 1004, // there is no ArrayNotContains
|
||||
GtEq = 1005,
|
||||
Gt = 1006,
|
||||
}
|
||||
|
||||
impl ToFields for NativePredicate {
|
||||
|
|
@ -89,7 +91,7 @@ pub enum Statement {
|
|||
ValueOf(AnchoredKey, Value),
|
||||
Equal(AnchoredKey, AnchoredKey),
|
||||
NotEqual(AnchoredKey, AnchoredKey),
|
||||
Gt(AnchoredKey, AnchoredKey),
|
||||
LtEq(AnchoredKey, AnchoredKey),
|
||||
Lt(AnchoredKey, AnchoredKey),
|
||||
Contains(
|
||||
/* root */ AnchoredKey,
|
||||
|
|
@ -114,7 +116,7 @@ impl Statement {
|
|||
Self::ValueOf(_, _) => Native(NativePredicate::ValueOf),
|
||||
Self::Equal(_, _) => Native(NativePredicate::Equal),
|
||||
Self::NotEqual(_, _) => Native(NativePredicate::NotEqual),
|
||||
Self::Gt(_, _) => Native(NativePredicate::Gt),
|
||||
Self::LtEq(_, _) => Native(NativePredicate::LtEq),
|
||||
Self::Lt(_, _) => Native(NativePredicate::Lt),
|
||||
Self::Contains(_, _, _) => Native(NativePredicate::Contains),
|
||||
Self::NotContains(_, _) => Native(NativePredicate::NotContains),
|
||||
|
|
@ -131,7 +133,7 @@ impl Statement {
|
|||
Self::ValueOf(ak, v) => vec![Key(ak), Literal(v)],
|
||||
Self::Equal(ak1, ak2) => vec![Key(ak1), Key(ak2)],
|
||||
Self::NotEqual(ak1, ak2) => vec![Key(ak1), Key(ak2)],
|
||||
Self::Gt(ak1, ak2) => vec![Key(ak1), Key(ak2)],
|
||||
Self::LtEq(ak1, ak2) => vec![Key(ak1), Key(ak2)],
|
||||
Self::Lt(ak1, ak2) => vec![Key(ak1), Key(ak2)],
|
||||
Self::Contains(ak1, ak2, ak3) => vec![Key(ak1), Key(ak2), Key(ak3)],
|
||||
Self::NotContains(ak1, ak2) => vec![Key(ak1), Key(ak2)],
|
||||
|
|
@ -172,11 +174,11 @@ impl Statement {
|
|||
Err(Error::incorrect_statements_args())
|
||||
}
|
||||
}
|
||||
Native(NativePredicate::Gt) => {
|
||||
Native(NativePredicate::LtEq) => {
|
||||
if let (StatementArg::Key(a0), StatementArg::Key(a1)) =
|
||||
(args[0].clone(), args[1].clone())
|
||||
{
|
||||
Ok(Self::Gt(a0, a1))
|
||||
Ok(Self::LtEq(a0, a1))
|
||||
} else {
|
||||
Err(Error::incorrect_statements_args())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue