Skip to content

Commit

Permalink
feat: upgrade manta-crypto abstractions for new circuits (#176)
Browse files Browse the repository at this point in the history
* feat: upgrade manta-crypto abstractions for new circuits
* feat: add implementations of `BitAnd` to arkworks backend
* fix: remove blanket implementation for ECLAIR traits for now
* fix: resolve clippy issues and missing comment
* chore: update dependencies
* chore: address comments and update dependencies
* fix: update based on new nightly compiler version

Signed-off-by: Brandon H. Gomes <bhgomes@pm.me>
  • Loading branch information
bhgomes authored Jul 28, 2022
1 parent e61ad15 commit 849a9bd
Show file tree
Hide file tree
Showing 27 changed files with 590 additions and 195 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
## [Unreleased]
### Added
- [\#131](https://github.com/Manta-Network/manta-rs/pull/131) Add abstract Phase 1 for Groth16 trusted setup
- [\#176](https://github.com/Manta-Network/manta-rs/pull/176) Add ECLAIR utilities for the new circuits
- [\#175](https://github.com/Manta-Network/manta-rs/pull/175) Add more documentation around `cargo-hakari`

### Changed
Expand Down
8 changes: 5 additions & 3 deletions manta-accounting/src/transfer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use crate::asset::{Asset, AssetId, AssetValue};
use alloc::vec::Vec;
use core::{fmt::Debug, hash::Hash, marker::PhantomData, ops::Deref};
use manta_crypto::{
accumulator::{AssertValidVerification, MembershipProof, Model},
accumulator::{self, AssertValidVerification, MembershipProof, Model},
constraint::{
self, Add, Allocate, Allocator, AssertEq, Bool, Constant, Derived, ProofSystem,
ProofSystemInput, Public, Secret, Variable,
Expand Down Expand Up @@ -280,10 +280,12 @@ pub type VoidNumber<C> = <C as Configuration>::VoidNumber;
pub type VoidNumberVar<C> = <C as Configuration>::VoidNumberVar;

/// UTXO Accumulator Witness Type
pub type UtxoAccumulatorWitness<C> = <<C as Configuration>::UtxoAccumulatorModel as Model>::Witness;
pub type UtxoAccumulatorWitness<C> =
<<C as Configuration>::UtxoAccumulatorModel as accumulator::Types>::Witness;

/// UTXO Accumulator Output Type
pub type UtxoAccumulatorOutput<C> = <<C as Configuration>::UtxoAccumulatorModel as Model>::Output;
pub type UtxoAccumulatorOutput<C> =
<<C as Configuration>::UtxoAccumulatorModel as accumulator::Types>::Output;

/// UTXO Membership Proof Type
pub type UtxoMembershipProof<C> = MembershipProof<<C as Configuration>::UtxoAccumulatorModel>;
Expand Down
2 changes: 1 addition & 1 deletion manta-accounting/src/transfer/sender.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ where
/// called before [`is_unspent`](Self::is_unspent) and
/// [`has_matching_utxo_accumulator_output`](Self::has_matching_utxo_accumulator_output).
///
/// [`S::Output`]: manta_crypto::accumulator::Model::Output
/// [`S::Output`]: manta_crypto::accumulator::Types::Output
type ValidUtxoAccumulatorOutput: AsRef<UtxoAccumulatorOutput<C>>;

/// Super Posting Key
Expand Down
4 changes: 2 additions & 2 deletions manta-benchmark/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ instant = { version = "0.1.12", default-features = false, features = [ "wasm-bin
manta-accounting = { path = "../manta-accounting", default-features = false, features = ["test"] }
manta-crypto = { path = "../manta-crypto", default-features = false, features = ["getrandom", "test"] }
manta-pay = { path = "../manta-pay", default-features = false, features = ["groth16", "test"] }
wasm-bindgen = { version = "0.2.81", default-features = false }
wasm-bindgen = { version = "0.2.82", default-features = false }
wasm-bindgen-test = { version = "0.3.30", default-features = false }
web-sys = { version = "0.3.58", default-features = false, features = ["console"] }
web-sys = { version = "0.3.59", default-features = false, features = ["console"] }
workspace-hack = { version = "0.1.0", path = "../workspace-hack" }

[dev-dependencies]
Expand Down
221 changes: 158 additions & 63 deletions manta-crypto/src/accumulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@

//! Dynamic Cryptographic Accumulators

/// Accumulator Membership Model
pub trait Model<COM = ()> {
use crate::constraint::{Allocate, Allocator, Constant, Derived, Variable};
use core::marker::PhantomData;

/// Accumulator Membership Model Types
pub trait Types {
/// Item Type
type Item: ?Sized;

Expand All @@ -26,7 +29,10 @@ pub trait Model<COM = ()> {

/// Output Type
type Output;
}

/// Accumulator Membership Model
pub trait Model<COM = ()>: Types {
/// Verification Type
///
/// Typically this is either [`bool`], a [`Result`] type, or a circuit boolean variable.
Expand All @@ -43,6 +49,16 @@ pub trait Model<COM = ()> {
) -> Self::Verification;
}

/// Accumulator Item Hash Function
pub trait ItemHashFunction<T, COM = ()> {
/// Item Type
type Item;

/// Converts `value` into an [`Item`](Self::Item) that is compatible with the relevant
/// accumulator.
fn item_hash(&self, value: &T, compiler: &mut COM) -> Self::Item;
}

/// Accumulator Membership Model Validity Assertion
///
/// For situations where we just want to assert validity of the membership proof, we can use this
Expand All @@ -64,8 +80,11 @@ pub trait AssertValidVerification<COM = ()>: Model<COM> {
);
}

/// Accumulator Witness Type
pub type Witness<A> = <<A as Accumulator>::Model as Types>::Witness;

/// Accumulator Output Type
pub type Output<A> = <<A as Accumulator>::Model as Model>::Output;
pub type Output<A> = <<A as Accumulator>::Model as Types>::Output;

/// Accumulator
pub trait Accumulator {
Expand Down Expand Up @@ -193,6 +212,102 @@ pub trait OptimizedAccumulator: Accumulator {
}
}

/// Item Hash Accumulator Model
pub struct ItemHashAccumulatorModel<T, H, A>
where
H: ItemHashFunction<T>,
A: Accumulator<Item = H::Item>,
{
/// Item Hash Function
item_hash_function: H,

/// Accumulator
accumulator: A,

/// Type Parameter Marker
__: PhantomData<T>,
}

impl<T, H, A> Types for ItemHashAccumulatorModel<T, H, A>
where
H: ItemHashFunction<T>,
A: Accumulator<Item = H::Item>,
{
type Item = T;
type Witness = Witness<A>;
type Output = Output<A>;
}

impl<T, H, A> Model for ItemHashAccumulatorModel<T, H, A>
where
H: ItemHashFunction<T>,
A: Accumulator<Item = H::Item>,
{
type Verification = <A::Model as Model>::Verification;

#[inline]
fn verify(
&self,
item: &Self::Item,
witness: &Self::Witness,
output: &Self::Output,
compiler: &mut (),
) -> Self::Verification {
self.accumulator.model().verify(
&self.item_hash_function.item_hash(item, compiler),
witness,
output,
compiler,
)
}
}

/// Item Hash Accumulator
pub struct ItemHashAccumulator<T, H, A>
where
H: ItemHashFunction<T>,
A: Accumulator<Item = H::Item>,
{
/// Item Hash Accumulator Model
model: ItemHashAccumulatorModel<T, H, A>,
}

impl<T, H, A> Accumulator for ItemHashAccumulator<T, H, A>
where
H: ItemHashFunction<T>,
A: Accumulator<Item = H::Item>,
{
type Item = T;
type Model = ItemHashAccumulatorModel<T, H, A>;

#[inline]
fn model(&self) -> &Self::Model {
&self.model
}

#[inline]
fn insert(&mut self, item: &Self::Item) -> bool {
self.model
.accumulator
.insert(&self.model.item_hash_function.item_hash(item, &mut ()))
}

#[inline]
fn prove(&self, item: &Self::Item) -> Option<MembershipProof<Self::Model>> {
self.model
.accumulator
.prove(&self.model.item_hash_function.item_hash(item, &mut ()))
.map(MembershipProof::into)
}

#[inline]
fn contains(&self, item: &Self::Item) -> bool {
self.model
.accumulator
.contains(&self.model.item_hash_function.item_hash(item, &mut ()))
}
}

/// Accumulator Membership Proof
pub struct MembershipProof<M, COM = ()>
where
Expand All @@ -203,6 +318,9 @@ where

/// Accumulator Output
output: M::Output,

/// Type Parameter Marker
__: PhantomData<COM>,
}

impl<M, COM> MembershipProof<M, COM>
Expand All @@ -212,10 +330,14 @@ where
/// Builds a new [`MembershipProof`] from `witness` and `output`.
#[inline]
pub fn new(witness: M::Witness, output: M::Output) -> Self {
Self { witness, output }
Self {
witness,
output,
__: PhantomData,
}
}

/// Returns the accumulated output part of `self`, dropping the [`M::Witness`](Model::Witness).
/// Returns the accumulated output part of `self`, dropping the [`M::Witness`](Types::Witness).
#[inline]
pub fn into_output(self) -> M::Output {
self.output
Expand All @@ -241,71 +363,44 @@ where
{
model.assert_valid(item, &self.witness, &self.output, compiler)
}
}

/// Constraint System Gadgets
pub mod constraint {
use super::*;
use crate::constraint::{Allocate, Allocator, Constant, Derived, Variable};
use core::marker::PhantomData;

/// Membership Proof Allocation Mode Entry
#[derive(derivative::Derivative)]
#[derivative(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
pub struct MembershipProofModeEntry<WitnessMode, OutputMode> {
/// Secret Witness Allocation Mode
pub witness: WitnessMode,

/// Accumulated Value Allocation Mode
pub output: OutputMode,
}

impl<WitnessMode, OutputMode> MembershipProofModeEntry<WitnessMode, OutputMode> {
/// Builds a new [`MembershipProofModeEntry`] from a witness` mode and an `output` mode.
#[inline]
pub fn new(witness: WitnessMode, output: OutputMode) -> Self {
Self { witness, output }
}
}

impl<WitnessMode, OutputMode> From<Derived> for MembershipProofModeEntry<WitnessMode, OutputMode>
/// Converts `self` from the `M` accumulator model to the `N` accumulator model.
///
/// # Validity
///
/// This function cannot guarantee that the point-wise conversion of the witness and output
/// preserves the membership proof validity.
#[inline]
pub fn into<N>(self) -> MembershipProof<N, COM>
where
WitnessMode: From<Derived>,
OutputMode: From<Derived>,
N: Model<COM> + ?Sized,
M::Witness: Into<N::Witness>,
M::Output: Into<N::Output>,
{
#[inline]
fn from(d: Derived) -> Self {
Self::new(d.into(), d.into())
}
MembershipProof::new(self.witness.into(), self.output.into())
}
}

/// Membership Proof Allocation Mode
#[derive(derivative::Derivative)]
#[derivative(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct MembershipProofMode<WitnessMode, OutputMode>(PhantomData<(WitnessMode, OutputMode)>);
impl<M, W, O, COM> Variable<Derived<(W, O)>, COM> for MembershipProof<M, COM>
where
M: Model<COM> + Constant<COM>,
M::Type: Model,
M::Witness: Variable<W, COM, Type = <M::Type as Types>::Witness>,
M::Output: Variable<O, COM, Type = <M::Type as Types>::Output>,
{
type Type = MembershipProof<M::Type>;

impl<M, WitnessMode, OutputMode, COM>
Variable<MembershipProofMode<WitnessMode, OutputMode>, COM> for MembershipProof<M, COM>
where
M: Model<COM> + Constant<COM>,
M::Type: Model,
M::Witness: Variable<WitnessMode, COM, Type = <M::Type as Model>::Witness>,
M::Output: Variable<OutputMode, COM, Type = <M::Type as Model>::Output>,
{
type Type = MembershipProof<M::Type>;

#[inline]
fn new_known(this: &Self::Type, compiler: &mut COM) -> Self {
Self::new(
this.witness.as_known(compiler),
this.output.as_known(compiler),
)
}
#[inline]
fn new_unknown(compiler: &mut COM) -> Self {
Self::new(compiler.allocate_unknown(), compiler.allocate_unknown())
}

#[inline]
fn new_unknown(compiler: &mut COM) -> Self {
Self::new(compiler.allocate_unknown(), compiler.allocate_unknown())
}
#[inline]
fn new_known(this: &Self::Type, compiler: &mut COM) -> Self {
Self::new(
this.witness.as_known(compiler),
this.output.as_known(compiler),
)
}
}

Expand Down
4 changes: 2 additions & 2 deletions manta-crypto/src/algebra.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ where
where
R: Read,
{
Ok(Self::new(G::decode(&mut reader)?))
Ok(Self::new(Decode::decode(&mut reader)?))
}
}

Expand All @@ -165,7 +165,7 @@ where
where
R: RngCore + ?Sized,
{
Self::new(G::sample(distribution, rng))
Self::new(Sample::sample(distribution, rng))
}
}

Expand Down
5 changes: 3 additions & 2 deletions manta-crypto/src/constraint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ pub use crate::eclair::{
},
bool::{Assert, AssertEq, Bool, ConditionalSelect, ConditionalSwap},
cmp::{Eq, PartialEq},
ops::{Add, Not, Sub},
Has, Native,
num::Zero,
ops::{Add, BitAnd, BitOr, Not, Sub},
Has, Native, NonNative,
};

/// Proof System
Expand Down
Loading

0 comments on commit 849a9bd

Please sign in to comment.