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

fix: simplify algebra APIs #132

Merged
merged 9 commits into from
Jun 27, 2022
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- [\#130](https://github.com/Manta-Network/manta-rs/pull/130) Add the sage script and the hardcoded tests for the security of mds matrix

### Changed
- [\#132](https://github.com/Manta-Network/manta-rs/pull/132) Simplify algebra APIs and removing ECC-specific design
bhgomes marked this conversation as resolved.
Show resolved Hide resolved
- [\#127](https://github.com/Manta-Network/manta-rs/pull/127) Remove the `CryptoRng` requirement from the `Sample` API

### Deprecated
Expand Down
2 changes: 1 addition & 1 deletion manta-accounting/src/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use core::{
marker::PhantomData,
};
use manta_crypto::{
key::KeyDerivationFunction,
key::kdf::KeyDerivationFunction,
rand::{RngCore, Sample},
};

Expand Down
35 changes: 18 additions & 17 deletions manta-accounting/src/transfer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ use manta_crypto::{
ProofSystemInput, Public, Secret, Variable,
},
encryption::hybrid::{DecryptedMessage, EncryptedMessage, HybridPublicKeyEncryptionScheme},
key::{KeyAgreementScheme, KeyDerivationFunction},
key::{self, agreement::Derive},
rand::{CryptoRng, RngCore, Sample},
};
use manta_util::SizeLimit;
Expand Down Expand Up @@ -116,10 +116,9 @@ pub trait Configuration {
type PublicKey: Clone;

/// Key Agreement Scheme Type
type KeyAgreementScheme: KeyAgreementScheme<
SecretKey = SecretKey<Self>,
PublicKey = PublicKey<Self>,
>;
type KeyAgreementScheme: key::agreement::Types<SecretKey = SecretKey<Self>, PublicKey = PublicKey<Self>>
+ key::agreement::Agree
+ key::agreement::Derive;

/// Secret Key Variable Type
type SecretKeyVar: Variable<Secret, Self::Compiler, Type = SecretKey<Self>>;
Expand All @@ -129,11 +128,10 @@ pub trait Configuration {
+ constraint::PartialEq<Self::PublicKeyVar, Self::Compiler>;

/// Key Agreement Scheme Variable Type
type KeyAgreementSchemeVar: KeyAgreementScheme<
Self::Compiler,
SecretKey = SecretKeyVar<Self>,
PublicKey = PublicKeyVar<Self>,
> + Constant<Self::Compiler, Type = Self::KeyAgreementScheme>;
type KeyAgreementSchemeVar: Constant<Self::Compiler, Type = Self::KeyAgreementScheme>
+ key::agreement::Types<SecretKey = SecretKeyVar<Self>, PublicKey = PublicKeyVar<Self>>
+ key::agreement::Agree<Self::Compiler>
+ key::agreement::Derive<Self::Compiler>;

/// Unspent Transaction Output Type
type Utxo: PartialEq;
Expand All @@ -152,13 +150,14 @@ pub trait Configuration {
+ constraint::PartialEq<Self::UtxoVar, Self::Compiler>;

/// UTXO Commitment Scheme Variable Type
type UtxoCommitmentSchemeVar: UtxoCommitmentScheme<
type UtxoCommitmentSchemeVar: Constant<Self::Compiler, Type = Self::UtxoCommitmentScheme>
+ UtxoCommitmentScheme<
Self::Compiler,
EphemeralSecretKey = SecretKeyVar<Self>,
PublicSpendKey = PublicKeyVar<Self>,
Asset = AssetVar<Self>,
Utxo = UtxoVar<Self>,
> + Constant<Self::Compiler, Type = Self::UtxoCommitmentScheme>;
>;

/// Void Number Type
type VoidNumber: PartialEq;
Expand All @@ -175,12 +174,13 @@ pub trait Configuration {
+ constraint::PartialEq<Self::VoidNumberVar, Self::Compiler>;

/// Void Number Commitment Scheme Variable Type
type VoidNumberCommitmentSchemeVar: VoidNumberCommitmentScheme<
type VoidNumberCommitmentSchemeVar: Constant<Self::Compiler, Type = Self::VoidNumberCommitmentScheme>
+ VoidNumberCommitmentScheme<
Self::Compiler,
SecretSpendKey = SecretKeyVar<Self>,
Utxo = UtxoVar<Self>,
VoidNumber = VoidNumberVar<Self>,
> + Constant<Self::Compiler, Type = Self::VoidNumberCommitmentScheme>;
>;

/// UTXO Accumulator Model Type
type UtxoAccumulatorModel: Model<Item = Self::Utxo, Verification = bool>;
Expand All @@ -200,14 +200,15 @@ pub trait Configuration {
>;

/// UTXO Accumulator Model Variable Type
type UtxoAccumulatorModelVar: AssertValidVerification<Self::Compiler>
type UtxoAccumulatorModelVar: Constant<Self::Compiler, Type = Self::UtxoAccumulatorModel>
+ AssertValidVerification<Self::Compiler>
+ Model<
Self::Compiler,
Item = Self::UtxoVar,
Witness = Self::UtxoAccumulatorWitnessVar,
Output = Self::UtxoAccumulatorOutputVar,
Verification = Bool<Self::Compiler>,
> + Constant<Self::Compiler, Type = Self::UtxoAccumulatorModel>;
>;

/// Asset Id Variable Type
type AssetIdVar: Variable<Public, Self::Compiler, Type = AssetId>
Expand Down Expand Up @@ -400,7 +401,7 @@ where
pub fn derive_owned(&self, secret_key: SecretKey<C>) -> PublicKey<C> {
self.note_encryption_scheme
.key_agreement_scheme()
.derive_owned(secret_key, &mut ())
.derive(&secret_key, &mut ())
}

/// Computes the [`Utxo`] associated to `ephemeral_secret_key`, `public_spend_key`, and `asset`.
Expand Down
224 changes: 224 additions & 0 deletions manta-crypto/src/algebra.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
// Copyright 2019-2022 Manta Network.
// This file is part of manta-rs.
//
// manta-rs is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// manta-rs is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with manta-rs. If not, see <http://www.gnu.org/licenses/>.

//! Algebraic Constructions

use crate::{
eclair::alloc::Constant,
key,
rand::{RngCore, Sample},
};
use core::marker::PhantomData;
use manta_util::codec::{Decode, DecodeError, Encode, Read, Write};

#[cfg(feature = "serde")]
use manta_util::serde::{Deserialize, Serialize};

/// Ring of Scalars
pub trait Scalar<COM = ()> {
/// Adds `rhs` to `self` in the ring.
fn add(&self, rhs: &Self, compiler: &mut COM) -> Self;

/// Multiplies `self` by `rhs` in the ring.
fn mul(&self, rhs: &Self, compiler: &mut COM) -> Self;
}

/// Group
pub trait Group<COM = ()> {
/// Ring of Scalars
type Scalar: Scalar<COM>;

/// Adds `rhs` to `self` in the group.
fn add(&self, rhs: &Self, compiler: &mut COM) -> Self;

/// Multiplies `self` by `scalar` in the group.
fn mul(&self, scalar: &Self::Scalar, compiler: &mut COM) -> Self;
}

/// Diffie-Hellman Key Agreement Scheme
#[cfg_attr(
feature = "serde",
derive(Deserialize, Serialize),
serde(crate = "manta_util::serde", deny_unknown_fields)
)]
#[derive(derivative::Derivative)]
#[derivative(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct DiffieHellman<G, COM = ()> {
/// Group Generator
pub generator: G,

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

impl<G, COM> DiffieHellman<G, COM> {
/// Builds a new [`DiffieHellman`] key agreement scheme from the given `generator`.
#[inline]
pub fn new(generator: G) -> Self {
Self {
generator,
__: PhantomData,
}
}

/// Converts `self` into the group generator.
#[inline]
pub fn into_inner(self) -> G {
self.generator
}
}

impl<G, COM> Constant<COM> for DiffieHellman<G, COM>
where
G: Constant<COM>,
{
type Type = DiffieHellman<G::Type>;

#[inline]
fn new_constant(value: &Self::Type, compiler: &mut COM) -> Self {
Self::new(G::new_constant(&value.generator, compiler))
}
}

impl<G, COM> key::agreement::Types for DiffieHellman<G, COM>
where
G: Group<COM> + security::ComputationalDiffieHellmanHardness,
{
type SecretKey = G::Scalar;
type PublicKey = G;
type SharedSecret = G;
}

impl<G, COM> key::agreement::Derive<COM> for DiffieHellman<G, COM>
where
G: Group<COM> + security::ComputationalDiffieHellmanHardness,
{
#[inline]
fn derive(&self, secret_key: &Self::SecretKey, compiler: &mut COM) -> Self::PublicKey {
self.generator.mul(secret_key, compiler)
}
}

impl<G, COM> key::agreement::Agree<COM> for DiffieHellman<G, COM>
where
G: Group<COM> + security::ComputationalDiffieHellmanHardness,
{
#[inline]
fn agree(
&self,
public_key: &Self::PublicKey,
secret_key: &Self::SecretKey,
compiler: &mut COM,
) -> Self::SharedSecret {
public_key.mul(secret_key, compiler)
}
}

impl<G, COM> Decode for DiffieHellman<G, COM>
where
G: Decode,
{
type Error = G::Error;

#[inline]
fn decode<R>(mut reader: R) -> Result<Self, DecodeError<R::Error, Self::Error>>
where
R: Read,
{
Ok(Self::new(G::decode(&mut reader)?))
}
}

impl<G, COM> Encode for DiffieHellman<G, COM>
where
G: Encode,
{
#[inline]
fn encode<W>(&self, mut writer: W) -> Result<(), W::Error>
where
W: Write,
{
self.generator.encode(&mut writer)?;
Ok(())
}
}

impl<D, G> Sample<D> for DiffieHellman<G>
where
G: Sample<D>,
{
#[inline]
fn sample<R>(distribution: D, rng: &mut R) -> Self
where
R: RngCore + ?Sized,
{
Self::new(G::sample(distribution, rng))
}
}

/// Security Assumptions
///
/// The following outlines some standard security assumptions for cryptographic protocols built on
/// [`Group`] types. These security properties can be attached to instances of [`Group`] which we
/// assume to have these hardness properties.
pub mod security {
/// Discrete Logarithm Hardness Assumption
///
/// For a [`Group`](super::Group) `G`, it should be infeasible to find a procedure `f` that
/// makes this function return `true`:
///
/// ```text
/// fn solve<F>(g: G, y: G, f: F) -> bool
/// where
/// F: FnOnce(G, G) -> G::Scalar,
/// {
/// y == g.mul(f(g, y))
/// }
/// ```
pub trait DiscreteLogarithmHardness {}

/// Computational Diffie-Hellman Hardness Assumption
///
/// For a [`Group`](super::Group) `G`, it should be infeasible to find a procedure `f` that
/// makes this function return `true`:
///
/// ```text
/// fn solve<F>(g: G, a: G::Scalar, b: G::Scalar, f: F) -> bool
/// where
/// F: FnOnce(G, G, G) -> G,
/// {
/// f(g, g.mul(a), g.mul(b)) == g.mul(a.mul(b))
/// }
/// ```
pub trait ComputationalDiffieHellmanHardness: DiscreteLogarithmHardness {}

/// Decisional Diffie-Hellman Hardness Assumption
///
/// For a [`Group`](super::Group) `G`, it should be infeasible to distinguish the probability
/// distributions over the following two functions when [`G::Scalar](super::Group::Scalar)
/// inputs are sampled uniformly from their domain (and `g` the generator is fixed):
///
/// ```text
/// fn dh_triple(g: G, a: G::Scalar, b: G::Scalar) -> (G, G, G) {
/// (g.mul(a), g.mul(b), g.mul(a.mul(b)))
/// }
///
/// fn random_triple(g: G, a: G::Scalar, b: G::Scalar, c: G::Scalar) -> (G, G, G) {
/// (g.mul(a), g.mul(b), g.mul(c))
/// }
/// ```
pub trait DecisionalDiffieHellmanHardness: ComputationalDiffieHellmanHardness {}
}
Loading