Skip to content

Commit

Permalink
feat: Add generate-proof-input for Transfer (#133)
Browse files Browse the repository at this point in the history
* feat: Add generate-proof-input for Transfer
* wip: add `extend_input` to sender & receiver
* feat: Add compatibility test
Co-authored-by: Brandon H. Gomes <bhgomes@pm.me>
  • Loading branch information
Boyuan Feng authored Jun 28, 2022
1 parent 128c55c commit 1c00559
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- [\#126](https://github.com/Manta-Network/manta-rs/pull/126) Add ECLAIR v0 scaffolding and deprecate old compiler patterns
- [\#128](https://github.com/Manta-Network/manta-rs/pull/128) Add more parameter loading utilities
- [\#130](https://github.com/Manta-Network/manta-rs/pull/130) Add the sage script and the hardcoded tests for the security of mds matrix
- [\#133](https://github.com/Manta-Network/manta-rs/pull/133) Add public input genenration to `Transfer`
- [\#136](https://github.com/Manta-Network/manta-rs/pull/136) Add pseudorandom permutation and sponge abstractions
- [\#134](https://github.com/Manta-Network/manta-rs/pull/134) Add signature scheme API and Schnorr signature implementaion

Expand Down
39 changes: 35 additions & 4 deletions manta-accounting/src/transfer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,13 @@ where
void_number: self.void_number,
}
}

/// Extends proof public input with `self`.
#[inline]
pub fn extend_input(&self, input: &mut ProofInput<C>) {
C::ProofSystem::extend(input, self.utxo_membership_proof.output());
C::ProofSystem::extend(input, &self.void_number);
}
}

/// Sender Variable
Expand Down Expand Up @@ -1195,8 +1202,6 @@ where
/// Extends proof public input with `self`.
#[inline]
pub fn extend_input(&self, input: &mut ProofInput<C>) {
// TODO: Add a "public part" trait that extracts the public part of `Sender` (using
// `SenderVar` to determine the types), then generate this method automatically.
C::ProofSystem::extend(input, &self.utxo_accumulator_output);
C::ProofSystem::extend(input, &self.void_number);
}
Expand Down Expand Up @@ -1396,6 +1401,12 @@ where
encrypted_note: self.encrypted_note,
}
}

/// Extends proof public input with `self`.
#[inline]
pub fn extend_input(&self, input: &mut ProofInput<C>) {
C::ProofSystem::extend(input, &self.utxo);
}
}

/// Receiver Variable
Expand Down Expand Up @@ -1610,8 +1621,6 @@ where
/// Extends proof public input with `self`.
#[inline]
pub fn extend_input(&self, input: &mut ProofInput<C>) {
// TODO: Add a "public part" trait that extracts the public part of `Receiver` (using
// `ReceiverVar` to determine the types), then generate this method automatically.
C::ProofSystem::extend(input, &self.utxo);
}

Expand Down Expand Up @@ -1724,6 +1733,28 @@ where
Self::new_unchecked(asset_id, sources, senders, receivers, sinks)
}

/// Generates the public input for the [`Transfer`] validation proof.
#[inline]
pub fn generate_proof_input(&self) -> ProofInput<C> {
let mut input = Default::default();
if let Some(asset_id) = self.asset_id {
C::ProofSystem::extend(&mut input, &asset_id);
}
self.sources
.iter()
.for_each(|source| C::ProofSystem::extend(&mut input, source));
self.senders
.iter()
.for_each(|sender| sender.extend_input(&mut input));
self.receivers
.iter()
.for_each(|receiver| receiver.extend_input(&mut input));
self.sinks
.iter()
.for_each(|sink| C::ProofSystem::extend(&mut input, sink));
input
}

/// Checks that the [`Transfer`] has a valid shape.
#[inline]
fn check_shape(has_visible_asset_id: bool) {
Expand Down
31 changes: 31 additions & 0 deletions manta-accounting/src/transfer/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ use manta_crypto::{
};
use manta_util::into_array_unchecked;

use super::ProofInput;

/// Samples a distribution over `count`-many values summing to `total`.
///
/// # Warning
Expand Down Expand Up @@ -243,6 +245,35 @@ where
&post.validity_proof,
)
}

/// Checks if `generate_proof_input` from [`Transfer`] and [`TransferPost`] gives the same [`ProofInput`].
#[inline]
pub fn sample_and_check_generate_proof_input_compatibility<A, R>(
public_parameters: &ProofSystemPublicParameters<C>,
parameters: &Parameters<C>,
utxo_accumulator: &mut A,
rng: &mut R,
) -> Result<bool, ProofSystemError<C>>
where
A: Accumulator<Item = Utxo<C>, Model = C::UtxoAccumulatorModel>,
R: CryptoRng + RngCore + ?Sized,
ProofInput<C>: PartialEq,
ProofSystemError<C>: Debug,
{
let transfer = Self::sample(
TransferDistribution {
parameters,
utxo_accumulator,
},
rng,
);
let full_parameters = FullParameters::new(parameters, utxo_accumulator.model());
let (proving_context, _) = Self::generate_context(public_parameters, full_parameters, rng)?;
Ok(transfer.generate_proof_input()
== transfer
.into_post(full_parameters, &proving_context, rng)?
.generate_proof_input())
}
}

impl<C> TransferPost<C>
Expand Down
42 changes: 42 additions & 0 deletions manta-pay/src/test/transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,48 @@ fn reclaim() {
);
}

/// Tests that `generate_proof_input` from [`Transfer`] and [`TransferPost`] gives the same [`ProofInput`].
#[test]
fn generate_proof_input_is_compatibile() {
let mut rng = OsRng;
assert!(
matches!(
Mint::sample_and_check_generate_proof_input_compatibility(
&(),
&rng.gen(),
&mut UtxoAccumulator::new(rng.gen()),
&mut rng
),
Ok(true),
),
"For a random Mint, `generate_proof_input` from `Transfer` and `TransferPost` should have given the same `ProofInput`."
);
assert!(
matches!(
PrivateTransfer::sample_and_check_generate_proof_input_compatibility(
&(),
&rng.gen(),
&mut UtxoAccumulator::new(rng.gen()),
&mut rng
),
Ok(true),
),
"For a random PrivateTransfer, `generate_proof_input` from `Transfer` and `TransferPost` should have given the same `ProofInput`."
);
assert!(
matches!(
Reclaim::sample_and_check_generate_proof_input_compatibility(
&(),
&rng.gen(),
&mut UtxoAccumulator::new(rng.gen()),
&mut rng
),
Ok(true),
),
"For a random Reclaim, `generate_proof_input` from `Transfer` and `TransferPost` should have given the same `ProofInput`."
);
}

/// Asserts that `proof` can be SCALE encoded and decoded with at least [`Vec`], [`Cursor`], and
/// [`File`](std::fs::File).
#[inline]
Expand Down

0 comments on commit 1c00559

Please sign in to comment.