Skip to content

Commit

Permalink
Merge 3c2ac6b into 7176d85
Browse files Browse the repository at this point in the history
  • Loading branch information
greenhat committed Jul 23, 2020
2 parents 7176d85 + 3c2ac6b commit 2e34fcf
Show file tree
Hide file tree
Showing 8 changed files with 191 additions and 48 deletions.
3 changes: 1 addition & 2 deletions bindings/ergo-wallet-lib-android/src/main/rust/exception.rs
Expand Up @@ -12,8 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#![allow(dead_code)]

use failure::Error;
use jni::JNIEnv;
use std::any::Any;
Expand Down Expand Up @@ -47,6 +45,7 @@ pub fn unwrap_exc_or<T>(env: &JNIEnv, res: ExceptionResult<T>, error_val: T) ->
}

// Same as `unwrap_exc_or` but returns default value.
#[allow(dead_code)]
pub fn unwrap_exc_or_default<T: Default>(env: &JNIEnv, res: ExceptionResult<T>) -> T {
unwrap_exc_or(env, res, T::default())
}
Expand Down
2 changes: 2 additions & 0 deletions sigma-tree/src/chain.rs
Expand Up @@ -19,8 +19,10 @@ pub use address::*;
pub use base16_bytes::Base16DecodedBytes;
pub use base16_bytes::Base16EncodedBytes;
pub use box_id::*;
pub use context_extension::*;
pub use contract::*;
pub use ergo_box::*;
pub use input::*;
pub use prover_result::*;
pub use token::*;
pub use transaction::*;
1 change: 0 additions & 1 deletion sigma-tree/src/chain/contract.rs
Expand Up @@ -5,7 +5,6 @@ use crate::ErgoTree;
use sigma_ser::serializer::SerializationError;

/// High-level wrapper for ErgoTree
#[allow(dead_code)]
pub struct Contract {
ergo_tree: ErgoTree,
}
Expand Down
2 changes: 0 additions & 2 deletions sigma-tree/src/ergo_tree.rs
Expand Up @@ -12,7 +12,6 @@ use std::rc::Rc;
use vlq_encode::{ReadSigmaVlqExt, WriteSigmaVlqExt};

#[derive(PartialEq, Eq, Debug, Clone)]
#[allow(dead_code)]
struct ParsedTree {
constants: Vec<Constant>,
root: Result<Rc<Expr>, ErgoTreeRootParsingError>,
Expand All @@ -21,7 +20,6 @@ struct ParsedTree {
/** The root of ErgoScript IR. Serialized instances of this class are self sufficient and can be passed around.
*/
#[derive(PartialEq, Eq, Debug, Clone)]
#[allow(dead_code)]
pub struct ErgoTree {
header: ErgoTreeHeader,
tree: Result<ParsedTree, ErgoTreeConstantsParsingError>,
Expand Down
210 changes: 171 additions & 39 deletions sigma-tree/src/eval.rs
@@ -1,7 +1,14 @@
use crate::ast::{ops::BinOp, ops::NumOp, Expr};
#![allow(dead_code)]
#![allow(unused_variables)]

use crate::{
ast::{ops::BinOp, ops::NumOp, Expr},
chain::{ContextExtension, ProverResult},
sigma_protocol::SigmaBoolean,
ErgoTree, ErgoTreeParsingError,
};

use cost_accum::CostAccumulator;
use costs::Costs;
use value::Value;

mod cost_accum;
Expand All @@ -10,45 +17,170 @@ mod value;

pub struct Env();

pub enum EvalError {}

pub trait Executor {
fn eval(&mut self, expr: &Expr, env: &Env) -> Result<Value, EvalError>;
fn add_cost_of(&mut self, expr: &Expr);
}

pub struct Interpreter {
costs: Costs,
cost_accum: CostAccumulator,
}

impl Executor for Interpreter {
#[allow(unconditional_recursion)]
fn eval(&mut self, expr: &Expr, env: &Env) -> Result<Value, EvalError> {
match expr {
Expr::Const(_) => todo!(), //Ok(EvalResult(*v)),
Expr::Coll { .. } => todo!(),
Expr::Tup { .. } => todo!(),
Expr::PredefFunc(_) => todo!(),
Expr::CollM(_) => todo!(),
Expr::BoxM(_) => todo!(),
Expr::CtxM(_) => todo!(),
Expr::MethodCall { .. } => todo!(),
Expr::BinOp(bin_op, l, r) => {
let v_l = self.eval(l, env)?;
let v_r = self.eval(r, env)?;
self.add_cost_of(expr);
Ok(match bin_op {
BinOp::Num(op) => match op {
NumOp::Add => v_l + v_r,
},
})
}
pub enum EvalError {
InvalidResultType,
}

pub struct VerificationResult {
result: bool,
cost: u64,
}

pub struct ReductionResult {
sigma_prop: SigmaBoolean,
cost: u64,
}

pub trait Evaluator {
// TODO: add the cost to the returned result
fn reduce_to_crypto(&self, expr: &Expr, env: &Env) -> Result<SigmaBoolean, EvalError> {
let mut ca = CostAccumulator::new(0, None);
eval(expr, env, &mut ca).and_then(|v| match v {
Value::Boolean(b) => Ok(SigmaBoolean::TrivialProp(b)),
Value::SigmaProp(sb) => Ok(*sb),
_ => Err(EvalError::InvalidResultType),
})
}
}

#[allow(unconditional_recursion)]
fn eval(expr: &Expr, env: &Env, ca: &mut CostAccumulator) -> Result<Value, EvalError> {
match expr {
Expr::Const(_) => todo!(), //Ok(EvalResult(*v)),
Expr::Coll { .. } => todo!(),
Expr::Tup { .. } => todo!(),
Expr::PredefFunc(_) => todo!(),
Expr::CollM(_) => todo!(),
Expr::BoxM(_) => todo!(),
Expr::CtxM(_) => todo!(),
Expr::MethodCall { .. } => todo!(),
Expr::BinOp(bin_op, l, r) => {
let v_l = eval(l, env, ca)?;
let v_r = eval(r, env, ca)?;
ca.add_cost_of(expr);
Ok(match bin_op {
BinOp::Num(op) => match op {
NumOp::Add => v_l + v_r,
},
})
}
}
}

// TODO: extract tree types to sigma_protocol

pub enum ProofTree {
UncheckedTree(UncheckedTree),
UnprovenTree(UnprovenTree),
}

pub enum UnprovenTree {}

pub enum UncheckedSigmaTree {}

pub enum UncheckedTree {
NoProof,
UncheckedSigmaTree(UncheckedSigmaTree),
}

fn serialize_sig(tree: UncheckedTree) -> Vec<u8> {
todo!()
}

// TODO: extract Prover

pub struct TestProver {}

impl Evaluator for TestProver {}
impl Prover for TestProver {}

pub enum ProverError {
ErgoTreeError(ErgoTreeParsingError),
EvalError(EvalError),
ReducedToFalse,
}

impl From<ErgoTreeParsingError> for ProverError {
fn from(err: ErgoTreeParsingError) -> Self {
ProverError::ErgoTreeError(err)
}
}

pub trait Prover: Evaluator {
fn prove(
&self,
tree: &ErgoTree,
env: &Env,
message: &[u8],
) -> Result<ProverResult, ProverError> {
let expr = tree.proposition()?;
let proof = self
.reduce_to_crypto(expr.as_ref(), env)
.map_err(ProverError::EvalError)
.and_then(|v| match v {
SigmaBoolean::TrivialProp(true) => Ok(UncheckedTree::NoProof),
SigmaBoolean::TrivialProp(false) => Err(ProverError::ReducedToFalse),
sb => {
let tree = self.convert_to_unproven(sb);
let unchecked_tree = self.prove_to_unchecked(tree, message);
Ok(UncheckedTree::UncheckedSigmaTree(unchecked_tree))
}
});
proof.map(|v| ProverResult {
proof: serialize_sig(v),
extension: ContextExtension::empty(),
})
}

fn convert_to_unproven(&self, sigma_tree: SigmaBoolean) -> UnprovenTree {
todo!()
}

fn prove_to_unchecked(
&self,
unproven_tree: UnprovenTree,
message: &[u8],
) -> UncheckedSigmaTree {
todo!()
}
}

// TODO: extract Verifier

pub enum VerifierError {
ErgoTreeError(ErgoTreeParsingError),
EvalError(EvalError),
}

impl From<ErgoTreeParsingError> for VerifierError {
fn from(err: ErgoTreeParsingError) -> Self {
VerifierError::ErgoTreeError(err)
}
}

impl From<EvalError> for VerifierError {
fn from(err: EvalError) -> Self {
VerifierError::EvalError(err)
}
}

fn add_cost_of(&mut self, expr: &Expr) {
let cost = self.costs.cost_of(expr);
self.cost_accum.add(cost);
pub trait Verifier: Evaluator {
fn verify(
&mut self,
tree: &ErgoTree,
env: &Env,
proof: &[u8],
message: &[u8],
) -> Result<VerificationResult, VerifierError> {
let expr = tree.proposition()?;
let cprop = self.reduce_to_crypto(expr.as_ref(), env)?;
let res: bool = match cprop {
SigmaBoolean::TrivialProp(b) => b,
sb => todo!(),
};
Ok(VerificationResult {
result: res,
cost: 0,
})
}
}
16 changes: 14 additions & 2 deletions sigma-tree/src/eval/cost_accum.rs
@@ -1,8 +1,20 @@
use super::costs::Cost;
use super::costs::{Cost, Costs};
use crate::ast::Expr;

pub struct CostAccumulator {}
pub struct CostAccumulator {
costs: Costs,
}

impl CostAccumulator {
pub fn new(initial_cost: u64, cost_limit: Option<u64>) -> CostAccumulator {
todo!()
}

pub fn add_cost_of(&mut self, expr: &Expr) {
let cost = self.costs.cost_of(expr);
self.add(cost);
}

pub fn add(&self, _: Cost) {
todo!();
}
Expand Down
1 change: 1 addition & 0 deletions sigma-tree/src/serialization/sigmaboolean.rs
Expand Up @@ -18,6 +18,7 @@ impl SigmaSerializable for SigmaBoolean {
SigmaProofOfKnowledgeTree::ProveDlog(v) => v.sigma_serialize(w),
},
SigmaBoolean::CAND(_) => todo!(),
SigmaBoolean::TrivialProp(_) => Ok(()), // besides opCode no additional bytes
}
}

Expand Down
4 changes: 2 additions & 2 deletions sigma-tree/src/sigma_protocol.rs
Expand Up @@ -34,7 +34,6 @@ impl DlogProverInput {
}

/// public key of discrete logarithm signature protocol
#[allow(dead_code)]
fn public_image(&self) -> ProveDlog {
// test it, see https://github.com/ergoplatform/sigma-rust/issues/38
let g = EcPoint::generator();
Expand All @@ -49,7 +48,6 @@ pub trait PrivateInput {
}

impl PrivateInput for DlogProverInput {
#[allow(dead_code)]
fn public_image(&self) -> SigmaProofOfKnowledgeTree {
SigmaProofOfKnowledgeTree::ProveDlog(self.public_image())
}
Expand Down Expand Up @@ -94,6 +92,8 @@ pub enum SigmaProofOfKnowledgeTree {
/// Values of this type are used as values of SigmaProp type
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum SigmaBoolean {
/// Represents boolean values (true/false)
TrivialProp(bool),
/// Sigma proposition
ProofOfKnowledge(SigmaProofOfKnowledgeTree),
/// AND conjunction for sigma propositions
Expand Down

0 comments on commit 2e34fcf

Please sign in to comment.