Skip to content

Commit

Permalink
feat: add new encryption scheme abstractions (#137)
Browse files Browse the repository at this point in the history
* feat: add new encryption scheme abstractions
* feat: add duplex-sponge encryption primitive

Co-authored-by: Boyuan Feng <bfeng9@wisc.edu>
Co-authored-by: Tom Shen <me@tomshen.io>
  • Loading branch information
3 people authored Jul 1, 2022
1 parent 0d15651 commit 759c91f
Show file tree
Hide file tree
Showing 20 changed files with 2,064 additions and 859 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- [\#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
- [\#137](https://github.com/Manta-Network/manta-rs/pull/137) Add new encryption scheme APIs and duplex-sponge encryption

### Changed
- [\#132](https://github.com/Manta-Network/manta-rs/pull/132) Simplify algebra APIs and removing ECC-specific design
Expand Down
74 changes: 45 additions & 29 deletions manta-accounting/src/transfer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ use manta_crypto::{
self, Add, Allocate, Allocator, AssertEq, Bool, Constant, Derived, ProofSystem,
ProofSystemInput, Public, Secret, Variable,
},
encryption::hybrid::{DecryptedMessage, EncryptedMessage, HybridPublicKeyEncryptionScheme},
encryption::{
self,
hybrid::{self, Hybrid},
Encrypt, EncryptedMessage,
},
key::{self, agreement::Derive},
rand::{CryptoRng, RngCore, Sample},
};
Expand Down Expand Up @@ -233,11 +237,16 @@ pub trait Configuration {
+ ProofSystemInput<VoidNumber<Self>>
+ ProofSystemInput<PublicKey<Self>>;

/// Note Encryption Scheme Type
type NoteEncryptionScheme: HybridPublicKeyEncryptionScheme<
Plaintext = Note<Self>,
KeyAgreementScheme = Self::KeyAgreementScheme,
>;
/// Note Base Encryption Scheme Type
type NoteEncryptionScheme: encryption::Encrypt<
EncryptionKey = SharedSecret<Self>,
Randomness = (),
Header = (),
Plaintext = Note<Self>,
> + encryption::Decrypt<
DecryptionKey = SharedSecret<Self>,
DecryptedPlaintext = Option<Note<Self>>,
>;
}

/// Asset Variable Type
Expand All @@ -255,6 +264,9 @@ pub type PublicKey<C> = <C as Configuration>::PublicKey;
/// Public Key Variable Type
pub type PublicKeyVar<C> = <C as Configuration>::PublicKeyVar;

/// Shared Secret Type
pub type SharedSecret<C> = key::agreement::SharedSecret<<C as Configuration>::KeyAgreementScheme>;

/// Unspend Transaction Output Type
pub type Utxo<C> = <C as Configuration>::Utxo;

Expand All @@ -281,10 +293,9 @@ pub type UtxoMembershipProofVar<C> =
MembershipProof<<C as Configuration>::UtxoAccumulatorModelVar, Compiler<C>>;

/// Encrypted Note Type
pub type EncryptedNote<C> = EncryptedMessage<<C as Configuration>::NoteEncryptionScheme>;

/// Decrypted Note Type
pub type DecryptedNote<C> = DecryptedMessage<<C as Configuration>::NoteEncryptionScheme>;
pub type EncryptedNote<C> = EncryptedMessage<
Hybrid<<C as Configuration>::KeyAgreementScheme, <C as Configuration>::NoteEncryptionScheme>,
>;

/// Transfer Configuration Compiler Type
pub type Compiler<C> = <C as Configuration>::Compiler;
Expand Down Expand Up @@ -314,36 +325,43 @@ pub type Proof<C> = <ProofSystemType<C> as ProofSystem>::Proof;
#[derive(derivative::Derivative)]
#[derivative(
Clone(bound = r"
C::KeyAgreementScheme: Clone,
C::NoteEncryptionScheme: Clone,
C::UtxoCommitmentScheme: Clone,
C::VoidNumberCommitmentScheme: Clone
"),
Copy(bound = r"
C::KeyAgreementScheme: Copy,
C::NoteEncryptionScheme: Copy,
C::UtxoCommitmentScheme: Copy,
C::VoidNumberCommitmentScheme: Copy
"),
Debug(bound = r"
C::KeyAgreementScheme: Debug,
C::NoteEncryptionScheme: Debug,
C::UtxoCommitmentScheme: Debug,
C::VoidNumberCommitmentScheme: Debug
"),
Default(bound = r"
C::KeyAgreementScheme: Default,
C::NoteEncryptionScheme: Default,
C::UtxoCommitmentScheme: Default,
C::VoidNumberCommitmentScheme: Default
"),
Eq(bound = r"
C::KeyAgreementScheme: Eq,
C::NoteEncryptionScheme: Eq,
C::UtxoCommitmentScheme: Eq,
C::VoidNumberCommitmentScheme: Eq
"),
Hash(bound = r"
C::KeyAgreementScheme: Hash,
C::NoteEncryptionScheme: Hash,
C::UtxoCommitmentScheme: Hash,
C::VoidNumberCommitmentScheme: Hash
"),
PartialEq(bound = r"
C::KeyAgreementScheme: PartialEq,
C::NoteEncryptionScheme: PartialEq,
C::UtxoCommitmentScheme: PartialEq,
C::VoidNumberCommitmentScheme: PartialEq
Expand All @@ -354,7 +372,7 @@ where
C: Configuration + ?Sized,
{
/// Note Encryption Scheme
pub note_encryption_scheme: C::NoteEncryptionScheme,
pub note_encryption_scheme: Hybrid<C::KeyAgreementScheme, C::NoteEncryptionScheme>,

/// UTXO Commitment Scheme
pub utxo_commitment: C::UtxoCommitmentScheme,
Expand All @@ -371,12 +389,16 @@ where
/// `void_number_commitment`.
#[inline]
pub fn new(
key_agreement_scheme: C::KeyAgreementScheme,
note_encryption_scheme: C::NoteEncryptionScheme,
utxo_commitment: C::UtxoCommitmentScheme,
void_number_commitment: C::VoidNumberCommitmentScheme,
) -> Self {
Self {
note_encryption_scheme,
note_encryption_scheme: Hybrid {
key_agreement_scheme,
encryption_scheme: note_encryption_scheme,
},
utxo_commitment,
void_number_commitment,
}
Expand All @@ -385,25 +407,17 @@ where
/// Returns the [`KeyAgreementScheme`](Configuration::KeyAgreementScheme) associated to `self`.
#[inline]
pub fn key_agreement_scheme(&self) -> &C::KeyAgreementScheme {
self.note_encryption_scheme.key_agreement_scheme()
&self.note_encryption_scheme.key_agreement_scheme
}

/// Derives a [`PublicKey`] from a borrowed `secret_key`.
#[inline]
pub fn derive(&self, secret_key: &SecretKey<C>) -> PublicKey<C> {
self.note_encryption_scheme
.key_agreement_scheme()
.key_agreement_scheme
.derive(secret_key, &mut ())
}

/// Derives a [`PublicKey`] from an owned `secret_key`.
#[inline]
pub fn derive_owned(&self, secret_key: SecretKey<C>) -> PublicKey<C> {
self.note_encryption_scheme
.key_agreement_scheme()
.derive(&secret_key, &mut ())
}

/// Computes the [`Utxo`] associated to `ephemeral_secret_key`, `public_spend_key`, and `asset`.
#[inline]
pub fn utxo(
Expand Down Expand Up @@ -561,7 +575,7 @@ where
Self {
key_agreement: this
.note_encryption_scheme
.key_agreement_scheme()
.key_agreement_scheme
.as_constant(compiler),
utxo_commitment: this.utxo_commitment.as_constant(compiler),
void_number_commitment: this.void_number_commitment.as_constant(compiler),
Expand Down Expand Up @@ -1363,15 +1377,17 @@ where
ephemeral_secret_key: SecretKey<C>,
asset: Asset,
) -> Self {
let randomness = hybrid::Randomness::from_key(ephemeral_secret_key);
Self {
utxo: parameters.utxo(&ephemeral_secret_key, &public_spend_key, &asset),
encrypted_note: EncryptedMessage::new(
&parameters.note_encryption_scheme,
&ephemeral_secret_key,
utxo: parameters.utxo(&randomness.ephemeral_secret_key, &public_spend_key, &asset),
encrypted_note: parameters.note_encryption_scheme.encrypt_into(
&public_view_key,
Note::new(ephemeral_secret_key.clone(), asset),
&randomness,
(),
&Note::new(randomness.ephemeral_secret_key.clone(), asset),
&mut (),
),
ephemeral_secret_key,
ephemeral_secret_key: randomness.ephemeral_secret_key,
public_spend_key,
asset,
}
Expand Down
17 changes: 11 additions & 6 deletions manta-accounting/src/transfer/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,10 @@ where
/// Parameters Distribution
#[derive(derivative::Derivative)]
#[derivative(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
pub struct ParametersDistribution<E = (), U = (), V = ()> {
pub struct ParametersDistribution<K = (), E = (), U = (), V = ()> {
/// Key Agreement Scheme Distribution
pub key_agreement_scheme: K,

/// Note Encryption Scheme Distribution
pub note_encryption_scheme: E,

Expand All @@ -91,19 +94,21 @@ pub struct ParametersDistribution<E = (), U = (), V = ()> {
pub void_number_commitment_scheme: V,
}

impl<E, U, V, C> Sample<ParametersDistribution<E, U, V>> for Parameters<C>
impl<K, E, U, V, C> Sample<ParametersDistribution<K, E, U, V>> for Parameters<C>
where
C: Configuration,
C::KeyAgreementScheme: Sample<K>,
C::NoteEncryptionScheme: Sample<E>,
C::UtxoCommitmentScheme: Sample<U>,
C::VoidNumberCommitmentScheme: Sample<V>,
{
#[inline]
fn sample<R>(distribution: ParametersDistribution<E, U, V>, rng: &mut R) -> Self
fn sample<R>(distribution: ParametersDistribution<K, E, U, V>, rng: &mut R) -> Self
where
R: RngCore + ?Sized,
{
Parameters::new(
rng.sample(distribution.key_agreement_scheme),
rng.sample(distribution.note_encryption_scheme),
rng.sample(distribution.utxo_commitment),
rng.sample(distribution.void_number_commitment_scheme),
Expand Down Expand Up @@ -325,8 +330,8 @@ where
.map(|v| {
Receiver::new(
parameters,
parameters.derive_owned(rng.gen()),
parameters.derive_owned(rng.gen()),
parameters.derive(&rng.gen()),
parameters.derive(&rng.gen()),
rng.gen(),
asset_id.with(*v),
)
Expand Down Expand Up @@ -447,7 +452,7 @@ where
&post.validity_proof,
)
.expect("Unable to verify proof."),
"Invalid proof: {:?}",
"Invalid proof: {:?}.",
post,
);
}
16 changes: 8 additions & 8 deletions manta-accounting/src/wallet/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,13 @@ use alloc::{boxed::Box, vec, vec::Vec};
use core::{convert::Infallible, fmt::Debug, hash::Hash};
use manta_crypto::{
accumulator::{Accumulator, ExactSizeAccumulator, OptimizedAccumulator},
encryption::hybrid::DecryptedMessage,
rand::{CryptoRng, FromEntropy, Rand, RngCore},
};
use manta_util::{
array_map, future::LocalBoxFutureResult, into_array_unchecked, iter::IteratorExt,
array_map,
future::LocalBoxFutureResult,
into_array_unchecked,
iter::{Finder, IteratorExt},
persistence::Rollback,
};

Expand Down Expand Up @@ -641,12 +643,10 @@ where
with_recovery: bool,
encrypted_note: EncryptedNote<C>,
) -> Option<ViewKeySelection<C::HierarchicalKeyDerivationScheme, Note<C>>> {
let mut finder = DecryptedMessage::find(encrypted_note);
view_key_table
.find_index_with_maybe_gap(with_recovery, move |k| {
finder.decrypt(&parameters.note_encryption_scheme, k)
})
.map(|selection| selection.map(|item| item.plaintext))
let mut finder = Finder::new(encrypted_note);
view_key_table.find_index_with_maybe_gap(with_recovery, move |k| {
finder.next(|note| note.decrypt(&parameters.note_encryption_scheme, k, &mut ()))
})
}

/// Inserts the new `utxo`-`note` pair into the `utxo_accumulator` adding the spendable amount
Expand Down
Loading

0 comments on commit 759c91f

Please sign in to comment.