From fc3682c6763997ff67611d30a162daa501db4877 Mon Sep 17 00:00:00 2001 From: Aaron Feickert <66188213+AaronFeickert@users.noreply.github.com> Date: Thu, 8 Aug 2024 22:44:34 -0500 Subject: [PATCH] Relax `Arc` requirement for parameters (#102) This PR relaxes the `Arc` requirement for parameters. Specifically, it removes the requirement that the caller use an `Arc` wrapper for `TriptychParameters`. Instead, this wrapping is handled internally. Closes #65. BREAKING CHANGE: Updates the public API. --- benches/parallel.rs | 13 +++++-------- benches/triptych.rs | 13 +++++-------- examples/ringct.rs | 5 +---- src/lib.rs | 6 +----- src/parallel/mod.rs | 6 +----- src/parallel/parameters.rs | 6 +++--- src/parallel/proof.rs | 10 +++++----- src/parallel/statement.rs | 6 +++--- src/parallel/witness.rs | 10 ++++------ src/parameters.rs | 6 +++--- src/proof.rs | 4 ++-- src/statement.rs | 6 +++--- src/witness.rs | 10 ++++------ 13 files changed, 40 insertions(+), 61 deletions(-) diff --git a/benches/parallel.rs b/benches/parallel.rs index 36dddec..4ac8073 100644 --- a/benches/parallel.rs +++ b/benches/parallel.rs @@ -5,9 +5,6 @@ #[macro_use] extern crate criterion; -extern crate alloc; - -use alloc::sync::Arc; use criterion::{BatchSize, Criterion}; use curve25519_dalek::{RistrettoPoint, Scalar}; @@ -33,7 +30,7 @@ const BATCH_SIZES: [usize; 1] = [2]; #[allow(non_snake_case)] #[allow(clippy::arithmetic_side_effects)] fn generate_data( - params: &Arc, + params: &TriptychParameters, b: usize, rng: &mut R, ) -> (Vec, Vec, Vec) { @@ -94,7 +91,7 @@ fn generate_proof(c: &mut Criterion) { for n in N_VALUES { for m in M_VALUES { // Generate parameters - let params = Arc::new(TriptychParameters::new(n, m).unwrap()); + let params = TriptychParameters::new(n, m).unwrap(); let label = format!("Generate proof: n = {}, m = {} (N = {})", n, m, params.get_N()); group.bench_function(&label, |b| { @@ -125,7 +122,7 @@ fn generate_proof_vartime(c: &mut Criterion) { for n in N_VALUES { for m in M_VALUES { // Generate parameters - let params = Arc::new(TriptychParameters::new(n, m).unwrap()); + let params = TriptychParameters::new(n, m).unwrap(); let label = format!( "Generate proof (variable time): n = {}, m = {} (N = {})", @@ -161,7 +158,7 @@ fn verify_proof(c: &mut Criterion) { for n in N_VALUES { for m in M_VALUES { // Generate parameters - let params = Arc::new(TriptychParameters::new(n, m).unwrap()); + let params = TriptychParameters::new(n, m).unwrap(); let label = format!("Verify proof: n = {}, m = {} (N = {})", n, m, params.get_N()); group.bench_function(&label, |b| { @@ -197,7 +194,7 @@ fn verify_batch_proof(c: &mut Criterion) { for n in N_VALUES { for m in M_VALUES { // Generate parameters - let params = Arc::new(TriptychParameters::new(n, m).unwrap()); + let params = TriptychParameters::new(n, m).unwrap(); for batch in BATCH_SIZES { let label = format!( diff --git a/benches/triptych.rs b/benches/triptych.rs index cb2b823..1f1d7e3 100644 --- a/benches/triptych.rs +++ b/benches/triptych.rs @@ -5,9 +5,6 @@ #[macro_use] extern crate criterion; -extern crate alloc; - -use alloc::sync::Arc; use criterion::{BatchSize, Criterion}; use curve25519_dalek::{RistrettoPoint, Scalar}; @@ -31,7 +28,7 @@ const BATCH_SIZES: [usize; 1] = [2]; #[allow(non_snake_case)] #[allow(clippy::arithmetic_side_effects)] fn generate_data( - params: &Arc, + params: &TriptychParameters, b: usize, rng: &mut R, ) -> (Vec, Vec, Vec) { @@ -84,7 +81,7 @@ fn generate_proof(c: &mut Criterion) { for n in N_VALUES { for m in M_VALUES { // Generate parameters - let params = Arc::new(TriptychParameters::new(n, m).unwrap()); + let params = TriptychParameters::new(n, m).unwrap(); let label = format!("Generate proof: n = {}, m = {} (N = {})", n, m, params.get_N()); group.bench_function(&label, |b| { @@ -115,7 +112,7 @@ fn generate_proof_vartime(c: &mut Criterion) { for n in N_VALUES { for m in M_VALUES { // Generate parameters - let params = Arc::new(TriptychParameters::new(n, m).unwrap()); + let params = TriptychParameters::new(n, m).unwrap(); let label = format!( "Generate proof (variable time): n = {}, m = {} (N = {})", @@ -151,7 +148,7 @@ fn verify_proof(c: &mut Criterion) { for n in N_VALUES { for m in M_VALUES { // Generate parameters - let params = Arc::new(TriptychParameters::new(n, m).unwrap()); + let params = TriptychParameters::new(n, m).unwrap(); let label = format!("Verify proof: n = {}, m = {} (N = {})", n, m, params.get_N()); group.bench_function(&label, |b| { @@ -187,7 +184,7 @@ fn verify_batch_proof(c: &mut Criterion) { for n in N_VALUES { for m in M_VALUES { // Generate parameters - let params = Arc::new(TriptychParameters::new(n, m).unwrap()); + let params = TriptychParameters::new(n, m).unwrap(); for batch in BATCH_SIZES { let label = format!( diff --git a/examples/ringct.rs b/examples/ringct.rs index 00976ff..fd23a62 100644 --- a/examples/ringct.rs +++ b/examples/ringct.rs @@ -10,8 +10,6 @@ //! This example shows how to use Triptych. #[cfg(test)] mod test { - use std::sync::Arc; - use curve25519_dalek::{RistrettoPoint, Scalar}; use merlin::Transcript; use rand_chacha::ChaCha12Rng; @@ -25,10 +23,9 @@ mod test { let mut rng = ChaCha12Rng::seed_from_u64(8675309); // Parameters that will define the number of outputs used in the proof: 2^4 == 16 - // The parameters are `Arc`-wrapped since it's likely they could be reused let n = 2; let m = 4; - let params = Arc::new(TriptychParameters::new(n, m).unwrap()); + let params = TriptychParameters::new(n, m).unwrap(); let number_outputs = params.get_N(); // Value commitments use the Triptych `G` generator for masks, and need another component for values diff --git a/src/lib.rs b/src/lib.rs index 21012f8..cee6183 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -67,9 +67,6 @@ //! ``` //! # #[cfg(feature = "rand")] //! # { -//! # extern crate alloc; -//! use alloc::sync::Arc; -//! //! use curve25519_dalek::RistrettoPoint; //! use rand_core::OsRng; //! use triptych::*; @@ -77,10 +74,9 @@ //! let mut rng = OsRng; //! //! // Generate parameters -//! // This is `Arc`-wrapped to facilitate efficient reuse! //! const n: u32 = 2; //! const m: u32 = 3; -//! let params = Arc::new(TriptychParameters::new(n, m).unwrap()); +//! let params = TriptychParameters::new(n, m).unwrap(); //! //! // Generate a random witness, which includes the signing key and an index where it will appear //! let witness = TriptychWitness::random(¶ms, &mut rng); diff --git a/src/parallel/mod.rs b/src/parallel/mod.rs index 64df1ad..e64a118 100644 --- a/src/parallel/mod.rs +++ b/src/parallel/mod.rs @@ -21,9 +21,6 @@ //! ``` //! # #[cfg(feature = "rand")] //! # { -//! # extern crate alloc; -//! use alloc::sync::Arc; -//! //! use curve25519_dalek::{RistrettoPoint, Scalar}; //! use rand_core::OsRng; //! use triptych::{parallel::*, Transcript}; @@ -31,10 +28,9 @@ //! let mut rng = OsRng; //! //! // Generate parameters -//! // This is `Arc`-wrapped to facilitate efficient reuse! //! const n: u32 = 2; //! const m: u32 = 3; -//! let params = Arc::new(TriptychParameters::new(n, m).unwrap()); +//! let params = TriptychParameters::new(n, m).unwrap(); //! //! // Generate a random witness, which includes the signing key, auxiliary key, and an index where they will appear //! let witness = TriptychWitness::random(¶ms, &mut rng); diff --git a/src/parallel/parameters.rs b/src/parallel/parameters.rs index 588b650..dc23d25 100644 --- a/src/parallel/parameters.rs +++ b/src/parallel/parameters.rs @@ -1,7 +1,7 @@ // Copyright (c) 2024, The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use alloc::{vec, vec::Vec}; +use alloc::{sync::Arc, vec, vec::Vec}; use core::iter::once; use blake3::Hasher; @@ -29,7 +29,7 @@ pub struct TriptychParameters { G: RistrettoPoint, G1: RistrettoPoint, U: RistrettoPoint, - CommitmentG: Vec, + CommitmentG: Arc>, CommitmentH: RistrettoPoint, hash: Vec, } @@ -149,7 +149,7 @@ impl TriptychParameters { G: *G, G1: *G1, U: *U, - CommitmentG, + CommitmentG: Arc::new(CommitmentG), CommitmentH, hash, }) diff --git a/src/parallel/proof.rs b/src/parallel/proof.rs index b315809..9b7da69 100644 --- a/src/parallel/proof.rs +++ b/src/parallel/proof.rs @@ -1022,7 +1022,7 @@ impl BorshDeserialize for TriptychProof { #[cfg(test)] mod test { - use alloc::{sync::Arc, vec::Vec}; + use alloc::vec::Vec; use curve25519_dalek::{traits::Identity, RistrettoPoint, Scalar}; use itertools::izip; @@ -1061,7 +1061,7 @@ mod test { rng: &mut R, ) -> (Vec, Vec, Vec) { // Generate parameters - let params = Arc::new(TriptychParameters::new(n, m).unwrap()); + let params = TriptychParameters::new(n, m).unwrap(); // Generate witnesses; for this test, we use adjacent indexes for simplicity // This means the batch size must not exceed the input set size! @@ -1090,7 +1090,7 @@ mod test { offsets.push(r_offset * params.get_G1()); M1[witness.get_l() as usize] = witness.compute_auxiliary_verification_key() + offsets.last().unwrap(); } - let input_set = Arc::new(TriptychInputSet::new(&M, &M1).unwrap()); + let input_set = TriptychInputSet::new(&M, &M1).unwrap(); // Generate statements let mut statements = Vec::with_capacity(b); @@ -1375,7 +1375,7 @@ mod test { let M1 = statements[0].get_input_set().get_auxiliary_keys().to_vec(); let index = ((witnesses[0].get_l() + 1) % witnesses[0].get_params().get_N()) as usize; M[index] = RistrettoPoint::random(&mut rng); - let evil_input_set = Arc::new(TriptychInputSet::new(&M, &M1).unwrap()); + let evil_input_set = TriptychInputSet::new(&M, &M1).unwrap(); let evil_statement = TriptychStatement::new( statements[0].get_params(), &evil_input_set, @@ -1407,7 +1407,7 @@ mod test { let mut M1 = statements[0].get_input_set().get_auxiliary_keys().to_vec(); let index = ((witnesses[0].get_l() + 1) % witnesses[0].get_params().get_N()) as usize; M1[index] = RistrettoPoint::random(&mut rng); - let evil_input_set = Arc::new(TriptychInputSet::new(&M, &M1).unwrap()); + let evil_input_set = TriptychInputSet::new(&M, &M1).unwrap(); let evil_statement = TriptychStatement::new( statements[0].get_params(), &evil_input_set, diff --git a/src/parallel/statement.rs b/src/parallel/statement.rs index 1197128..93b2be9 100644 --- a/src/parallel/statement.rs +++ b/src/parallel/statement.rs @@ -129,7 +129,7 @@ impl TriptychInputSet { #[allow(non_snake_case)] #[derive(Clone, Eq, PartialEq)] pub struct TriptychStatement { - params: Arc, + params: TriptychParameters, input_set: TriptychInputSet, offset: RistrettoPoint, J: RistrettoPoint, @@ -161,7 +161,7 @@ impl TriptychStatement { /// otherwise provided externally. #[allow(non_snake_case)] pub fn new( - params: &Arc, + params: &TriptychParameters, input_set: &TriptychInputSet, offset: &RistrettoPoint, J: &RistrettoPoint, @@ -203,7 +203,7 @@ impl TriptychStatement { } /// Get the parameters for this [`TriptychStatement`]. - pub fn get_params(&self) -> &Arc { + pub fn get_params(&self) -> &TriptychParameters { &self.params } diff --git a/src/parallel/witness.rs b/src/parallel/witness.rs index 9a1431d..1af3845 100644 --- a/src/parallel/witness.rs +++ b/src/parallel/witness.rs @@ -1,8 +1,6 @@ // Copyright (c) 2024, The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use alloc::sync::Arc; - use curve25519_dalek::{RistrettoPoint, Scalar}; use rand_core::CryptoRngCore; use snafu::prelude::*; @@ -18,7 +16,7 @@ use crate::parallel::TriptychParameters; #[derive(Zeroize, ZeroizeOnDrop)] pub struct TriptychWitness { #[zeroize(skip)] - params: Arc, + params: TriptychParameters, l: u32, r: Scalar, r1: Scalar, @@ -40,7 +38,7 @@ impl TriptychWitness { /// /// If you'd like a [`TriptychWitness`] generated securely for you, use [`TriptychWitness::random`] instead. #[allow(non_snake_case)] - pub fn new(params: &Arc, l: u32, r: &Scalar, r1: &Scalar) -> Result { + pub fn new(params: &TriptychParameters, l: u32, r: &Scalar, r1: &Scalar) -> Result { if r == &Scalar::ZERO || r1 == &Scalar::ZERO { return Err(WitnessError::InvalidParameter); } @@ -63,7 +61,7 @@ impl TriptychWitness { /// /// If you'd rather provide your own secret data, use [`TriptychWitness::new`] instead. #[allow(clippy::cast_possible_truncation)] - pub fn random(params: &Arc, rng: &mut R) -> Self { + pub fn random(params: &TriptychParameters, rng: &mut R) -> Self { // Generate a random index using wide reduction // This can't truncate since `N` is bounded by `u32` // It is also defined since `N > 0` @@ -79,7 +77,7 @@ impl TriptychWitness { } /// Get the [`TriptychParameters`] from this [`TriptychWitness`]. - pub fn get_params(&self) -> &Arc { + pub fn get_params(&self) -> &TriptychParameters { &self.params } diff --git a/src/parameters.rs b/src/parameters.rs index 45e321c..6331ede 100644 --- a/src/parameters.rs +++ b/src/parameters.rs @@ -1,7 +1,7 @@ // Copyright (c) 2024, The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use alloc::{vec, vec::Vec}; +use alloc::{sync::Arc, vec, vec::Vec}; use core::iter::once; use blake3::Hasher; @@ -28,7 +28,7 @@ pub struct TriptychParameters { m: u32, G: RistrettoPoint, U: RistrettoPoint, - CommitmentG: Vec, + CommitmentG: Arc>, CommitmentH: RistrettoPoint, hash: Vec, } @@ -132,7 +132,7 @@ impl TriptychParameters { m, G: *G, U: *U, - CommitmentG, + CommitmentG: Arc::new(CommitmentG), CommitmentH, hash, }) diff --git a/src/proof.rs b/src/proof.rs index d4fc35f..be7e01f 100644 --- a/src/proof.rs +++ b/src/proof.rs @@ -941,7 +941,7 @@ impl BorshDeserialize for TriptychProof { #[cfg(test)] mod test { - use alloc::{sync::Arc, vec::Vec}; + use alloc::vec::Vec; use curve25519_dalek::{traits::Identity, RistrettoPoint, Scalar}; use itertools::izip; @@ -978,7 +978,7 @@ mod test { rng: &mut R, ) -> (Vec, Vec, Vec) { // Generate parameters - let params = Arc::new(TriptychParameters::new(n, m).unwrap()); + let params = TriptychParameters::new(n, m).unwrap(); // Generate witnesses; for this test, we use adjacent indexes for simplicity // This means the batch size must not exceed the input set size! diff --git a/src/statement.rs b/src/statement.rs index 103c519..8f0f67e 100644 --- a/src/statement.rs +++ b/src/statement.rs @@ -98,7 +98,7 @@ impl TriptychInputSet { #[allow(non_snake_case)] #[derive(Clone, Eq, PartialEq)] pub struct TriptychStatement { - params: Arc, + params: TriptychParameters, input_set: TriptychInputSet, J: RistrettoPoint, hash: Vec, @@ -129,7 +129,7 @@ impl TriptychStatement { /// otherwise provided externally. #[allow(non_snake_case)] pub fn new( - params: &Arc, + params: &TriptychParameters, input_set: &TriptychInputSet, J: &RistrettoPoint, ) -> Result { @@ -159,7 +159,7 @@ impl TriptychStatement { } /// Get the parameters for this [`TriptychStatement`]. - pub fn get_params(&self) -> &Arc { + pub fn get_params(&self) -> &TriptychParameters { &self.params } diff --git a/src/witness.rs b/src/witness.rs index 24fbb46..f0b0c70 100644 --- a/src/witness.rs +++ b/src/witness.rs @@ -1,8 +1,6 @@ // Copyright (c) 2024, The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use alloc::sync::Arc; - use curve25519_dalek::{RistrettoPoint, Scalar}; use rand_core::CryptoRngCore; use snafu::prelude::*; @@ -18,7 +16,7 @@ use crate::TriptychParameters; #[derive(Zeroize, ZeroizeOnDrop)] pub struct TriptychWitness { #[zeroize(skip)] - params: Arc, + params: TriptychParameters, l: u32, r: Scalar, } @@ -39,7 +37,7 @@ impl TriptychWitness { /// /// If you'd like a [`TriptychWitness`] generated securely for you, use [`TriptychWitness::random`] instead. #[allow(non_snake_case)] - pub fn new(params: &Arc, l: u32, r: &Scalar) -> Result { + pub fn new(params: &TriptychParameters, l: u32, r: &Scalar) -> Result { if r == &Scalar::ZERO { return Err(WitnessError::InvalidParameter); } @@ -61,7 +59,7 @@ impl TriptychWitness { /// /// If you'd rather provide your own secret data, use [`TriptychWitness::new`] instead. #[allow(clippy::cast_possible_truncation)] - pub fn random(params: &Arc, rng: &mut R) -> Self { + pub fn random(params: &TriptychParameters, rng: &mut R) -> Self { // Generate a random index using wide reduction // This can't truncate since `N` is bounded by `u32` // It is also defined since `N > 0` @@ -76,7 +74,7 @@ impl TriptychWitness { } /// Get the [`TriptychParameters`] from this [`TriptychWitness`]. - pub fn get_params(&self) -> &Arc { + pub fn get_params(&self) -> &TriptychParameters { &self.params }