Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: upgrade manta-crypto abstractions for new circuits #176

Merged
merged 8 commits into from
Jul 28, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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