Fe contains (#145)
* Contains should take three arguments (root, key, value) * Add a test for frontend Dictionaries * Separate frontend and middleware operations * Make tests pass: add arg to contains * Cargo fmt * Merkleproof verify circuit (#143) * merkletree: add keypath circuit * merkletree-circuit: implement proof of existence verification in-circuit * parametrize max_depth at the tree circuit * Constrain selectors in-circuit * implement merketree nonexistence proof circuit, and add edgecase tests * add non-existence proofs documentation in the mdbook, mv EMPTY->EMPTY_VALUE & NULL->EMPTY_HASH, dependency clean and public exposure methods * review comments, some extra polishing and add a test that expects wrong proofs to fail * Add circuit to check only merkleproofs-of-existence With this, the merkletree_circuit module offers two different circuits: - `MerkleProofCircuit`: allows to verify both proofs of existence and proofs non-existence with the same circuit. - `MerkleProofExistenceCircuit`: allows to verify proofs of existence only. In this way, if only proofs of existence are needed, `MerkleProofExistenceCircuit` should be used, which requires less amount of constraints than `MerkleProofCircuit`. * Code review --------- Co-authored-by: Ahmad <root@ahmadafuni.com> * Towards Contains/NotContains in middleware and backend * Fix build * Adding error handling to deal with op compile introduce extra ops * Incorporate Merkle proofs into MockMainPod * Merkleproof verify circuit (#143) * merkletree: add keypath circuit * merkletree-circuit: implement proof of existence verification in-circuit * parametrize max_depth at the tree circuit * Constrain selectors in-circuit * implement merketree nonexistence proof circuit, and add edgecase tests * add non-existence proofs documentation in the mdbook, mv EMPTY->EMPTY_VALUE & NULL->EMPTY_HASH, dependency clean and public exposure methods * review comments, some extra polishing and add a test that expects wrong proofs to fail * Add circuit to check only merkleproofs-of-existence With this, the merkletree_circuit module offers two different circuits: - `MerkleProofCircuit`: allows to verify both proofs of existence and proofs non-existence with the same circuit. - `MerkleProofExistenceCircuit`: allows to verify proofs of existence only. In this way, if only proofs of existence are needed, `MerkleProofExistenceCircuit` should be used, which requires less amount of constraints than `MerkleProofCircuit`. * Code review --------- Co-authored-by: Ahmad <root@ahmadafuni.com> * Towards Contains/NotContains in middleware and backend * Frontend compound types -- allow one frontend operation to produce multiple middleware statements (in progress) * Incorporate Merkle proofs into MockMainPod * Incorporate Merkle proof op arg into frontend * Compile one statement to many, in progress * Fix remaining tests * Minor clean-up * Oops I did a bunch of work in the middle of a rebase, committing * Incorporate Merkle proof op arg into frontend * still working on frontend compound types, refactor compile() to output multiple statements * Contains statements for frontend types: code compiles * Tests pass * Examples use front-end compound types * Remove old Contains and NotContains from frontend * Add nin to typos * Code review --------- Co-authored-by: arnaucube <git@arnaucube.com> Co-authored-by: Ahmad <root@ahmadafuni.com>
This commit is contained in:
parent
d6033b7090
commit
d00ff95f41
16 changed files with 789 additions and 162 deletions
|
|
@ -1,7 +1,10 @@
|
|||
use std::fmt;
|
||||
|
||||
use super::{SignedPod, Statement, Value};
|
||||
use crate::middleware::OperationType;
|
||||
use super::{NativePredicate, Predicate, SignedPod, Statement, Value};
|
||||
use crate::{
|
||||
backends::plonky2::primitives::merkletree::MerkleProof,
|
||||
middleware::{self, OperationAux},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum OperationArg {
|
||||
|
|
@ -69,7 +72,120 @@ impl<V: Into<Value>> From<(&str, V)> for OperationArg {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Operation(pub OperationType, pub Vec<OperationArg>);
|
||||
pub enum OperationType {
|
||||
Native(NativeOperation),
|
||||
Custom(middleware::CustomPredicateRef),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum NativeOperation {
|
||||
None = 0,
|
||||
NewEntry = 1,
|
||||
CopyStatement = 2,
|
||||
EqualFromEntries = 3,
|
||||
NotEqualFromEntries = 4,
|
||||
GtFromEntries = 5,
|
||||
LtFromEntries = 6,
|
||||
TransitiveEqualFromStatements = 7,
|
||||
GtToNotEqual = 8,
|
||||
LtToNotEqual = 9,
|
||||
SumOf = 13,
|
||||
ProductOf = 14,
|
||||
MaxOf = 15,
|
||||
DictContainsFromEntries = 16,
|
||||
DictNotContainsFromEntries = 17,
|
||||
SetContainsFromEntries = 18,
|
||||
SetNotContainsFromEntries = 19,
|
||||
ArrayContainsFromEntries = 20,
|
||||
}
|
||||
|
||||
impl TryFrom<OperationType> for middleware::OperationType {
|
||||
type Error = anyhow::Error;
|
||||
fn try_from(fe_ot: OperationType) -> Result<Self, Self::Error> {
|
||||
type FeOT = OperationType;
|
||||
type FeNO = NativeOperation;
|
||||
type MwOT = middleware::OperationType;
|
||||
type MwNO = middleware::NativeOperation;
|
||||
let mw_ot = match fe_ot {
|
||||
FeOT::Native(FeNO::None) => MwOT::Native(MwNO::None),
|
||||
FeOT::Native(FeNO::NewEntry) => MwOT::Native(MwNO::NewEntry),
|
||||
FeOT::Native(FeNO::CopyStatement) => MwOT::Native(MwNO::CopyStatement),
|
||||
FeOT::Native(FeNO::EqualFromEntries) => MwOT::Native(MwNO::EqualFromEntries),
|
||||
FeOT::Native(FeNO::NotEqualFromEntries) => MwOT::Native(MwNO::NotEqualFromEntries),
|
||||
FeOT::Native(FeNO::GtFromEntries) => MwOT::Native(MwNO::GtFromEntries),
|
||||
FeOT::Native(FeNO::LtFromEntries) => MwOT::Native(MwNO::LtFromEntries),
|
||||
FeOT::Native(FeNO::TransitiveEqualFromStatements) => {
|
||||
MwOT::Native(MwNO::TransitiveEqualFromStatements)
|
||||
}
|
||||
FeOT::Native(FeNO::GtToNotEqual) => MwOT::Native(MwNO::GtToNotEqual),
|
||||
FeOT::Native(FeNO::LtToNotEqual) => MwOT::Native(MwNO::LtToNotEqual),
|
||||
FeOT::Native(FeNO::SumOf) => MwOT::Native(MwNO::SumOf),
|
||||
FeOT::Native(FeNO::ProductOf) => MwOT::Native(MwNO::ProductOf),
|
||||
FeOT::Native(FeNO::MaxOf) => MwOT::Native(MwNO::MaxOf),
|
||||
FeOT::Native(FeNO::DictContainsFromEntries) => MwOT::Native(MwNO::ContainsFromEntries),
|
||||
FeOT::Native(FeNO::DictNotContainsFromEntries) => {
|
||||
MwOT::Native(MwNO::NotContainsFromEntries)
|
||||
}
|
||||
FeOT::Native(FeNO::SetContainsFromEntries) => MwOT::Native(MwNO::ContainsFromEntries),
|
||||
FeOT::Native(FeNO::SetNotContainsFromEntries) => {
|
||||
MwOT::Native(MwNO::NotContainsFromEntries)
|
||||
}
|
||||
FeOT::Native(FeNO::ArrayContainsFromEntries) => MwOT::Native(MwNO::ContainsFromEntries),
|
||||
FeOT::Custom(mw_cpr) => MwOT::Custom(mw_cpr),
|
||||
};
|
||||
Ok(mw_ot)
|
||||
}
|
||||
}
|
||||
|
||||
impl OperationType {
|
||||
/// Gives the type of predicate that the operation will output, if known.
|
||||
/// CopyStatement may output any predicate (it will match the statement copied),
|
||||
/// so output_predicate returns None on CopyStatement.
|
||||
pub fn output_predicate(&self) -> Option<Predicate> {
|
||||
match self {
|
||||
OperationType::Native(native_op) => match native_op {
|
||||
NativeOperation::None => Some(Predicate::Native(NativePredicate::None)),
|
||||
NativeOperation::NewEntry => Some(Predicate::Native(NativePredicate::ValueOf)),
|
||||
NativeOperation::CopyStatement => None,
|
||||
NativeOperation::EqualFromEntries => {
|
||||
Some(Predicate::Native(NativePredicate::Equal))
|
||||
}
|
||||
NativeOperation::NotEqualFromEntries => {
|
||||
Some(Predicate::Native(NativePredicate::NotEqual))
|
||||
}
|
||||
NativeOperation::GtFromEntries => Some(Predicate::Native(NativePredicate::Gt)),
|
||||
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::SumOf => Some(Predicate::Native(NativePredicate::SumOf)),
|
||||
NativeOperation::ProductOf => Some(Predicate::Native(NativePredicate::ProductOf)),
|
||||
NativeOperation::MaxOf => Some(Predicate::Native(NativePredicate::MaxOf)),
|
||||
NativeOperation::DictContainsFromEntries => {
|
||||
Some(Predicate::Native(NativePredicate::DictContains))
|
||||
}
|
||||
NativeOperation::DictNotContainsFromEntries => {
|
||||
Some(Predicate::Native(NativePredicate::DictNotContains))
|
||||
}
|
||||
NativeOperation::SetContainsFromEntries => {
|
||||
Some(Predicate::Native(NativePredicate::SetContains))
|
||||
}
|
||||
NativeOperation::SetNotContainsFromEntries => {
|
||||
Some(Predicate::Native(NativePredicate::SetNotContains))
|
||||
}
|
||||
NativeOperation::ArrayContainsFromEntries => {
|
||||
Some(Predicate::Native(NativePredicate::ArrayContains))
|
||||
}
|
||||
},
|
||||
OperationType::Custom(cpr) => Some(Predicate::Custom(cpr.clone())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Operation(pub OperationType, pub Vec<OperationArg>, pub OperationAux);
|
||||
|
||||
impl fmt::Display for Operation {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue