Skip to content

Commit

Permalink
WASM: add bindings for Witness
Browse files Browse the repository at this point in the history
  • Loading branch information
andiflabs committed Dec 4, 2024
1 parent 1a313d2 commit 007e1ac
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 9 deletions.
1 change: 1 addition & 0 deletions ironfish-rust-wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub mod merkle_note;
pub mod note;
pub mod primitives;
pub mod transaction;
pub mod witness;

/// Creates a [`wasm_bindgen`] wrapper for an existing type.
///
Expand Down
90 changes: 90 additions & 0 deletions ironfish-rust-wasm/src/witness.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use crate::{merkle_note::MerkleNoteHash, primitives::Scalar, wasm_bindgen_wrapper};
use ironfish::witness::WitnessTrait;
use wasm_bindgen::prelude::*;

wasm_bindgen_wrapper! {
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Witness(ironfish::witness::Witness);
}

#[wasm_bindgen]
impl Witness {
#[wasm_bindgen(constructor)]
pub fn new(tree_size: usize, root_hash: Scalar, auth_path: Vec<WitnessNode>) -> Self {
Self(ironfish::witness::Witness {
tree_size,
root_hash: root_hash.into(),
auth_path: auth_path.into_iter().map(WitnessNode::into).collect(),
})
}

#[wasm_bindgen(getter)]
pub fn tree_size(&self) -> usize {
self.0.tree_size
}

#[wasm_bindgen(getter)]
pub fn root_hash(&self) -> Scalar {
self.0.root_hash.into()
}

#[wasm_bindgen(getter)]
pub fn auth_path(&self) -> Vec<WitnessNode> {
self.0
.auth_path
.iter()
.cloned()
.map(WitnessNode::from)
.collect()
}

#[wasm_bindgen]
pub fn verify(&self, hash: &MerkleNoteHash) -> bool {
self.0.verify(hash.as_ref())
}
}

wasm_bindgen_wrapper! {
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct WitnessNode(ironfish::witness::WitnessNode<blstrs::Scalar>);
}

#[wasm_bindgen]
impl WitnessNode {
#[wasm_bindgen]
pub fn left(hash: Scalar) -> Self {
Self(ironfish::witness::WitnessNode::Left(hash.into()))
}

#[wasm_bindgen]
pub fn right(hash: Scalar) -> Self {
Self(ironfish::witness::WitnessNode::Right(hash.into()))
}

#[wasm_bindgen(getter)]
pub fn is_left(&self) -> bool {
match self.0 {
ironfish::witness::WitnessNode::Left(_) => true,
ironfish::witness::WitnessNode::Right(_) => false,
}
}

#[wasm_bindgen(getter)]
pub fn is_right(&self) -> bool {
!self.is_left()
}

#[wasm_bindgen(getter)]
pub fn hash(&self) -> Scalar {
match self.0 {
ironfish::witness::WitnessNode::Left(ref hash) => hash,
ironfish::witness::WitnessNode::Right(ref hash) => hash,
}
.to_owned()
.into()
}
}
10 changes: 1 addition & 9 deletions ironfish-rust/src/witness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,13 @@ pub trait WitnessTrait {

/// A Rust implementation of a WitnessTrait, used for testing Witness-related
/// code within Rust.
#[derive(Clone, PartialEq, Eq)]
pub struct Witness {
pub tree_size: usize,
pub root_hash: Scalar,
pub auth_path: Vec<WitnessNode<Scalar>>,
}

/// Implement partial equality, ignoring the Sapling Arc
impl PartialEq for Witness {
fn eq(&self, other: &Witness) -> bool {
self.tree_size == other.tree_size
&& self.root_hash == other.root_hash
&& self.auth_path == other.auth_path
}
}

impl WitnessTrait for Witness {
fn verify(&self, my_hash: &MerkleNoteHash) -> bool {
let mut cur_hash = my_hash.0;
Expand Down

0 comments on commit 007e1ac

Please sign in to comment.