diff --git a/benches/centralized_telescope/verifying_time.rs b/benches/centralized_telescope/verifying_time.rs index 09d58021..b7eb8c7b 100644 --- a/benches/centralized_telescope/verifying_time.rs +++ b/benches/centralized_telescope/verifying_time.rs @@ -24,7 +24,8 @@ fn verify_duration(params: &BenchParam, truncate_size: u64, n: u64) -> Duration // Truncate the dataset to give truncate_size elements to the prover dataset.truncate(truncate_size as usize); // Generate the proof - let proof_opt: Option = telescope.prove(&dataset); + let proof_opt: Option> = + telescope.prove(&dataset); if let Some(proof) = proof_opt { // Iterate on each sample `n` times diff --git a/examples/aggregate_signature/helpers.rs b/examples/aggregate_signature/helpers.rs index 701c4471..8650416a 100644 --- a/examples/aggregate_signature/helpers.rs +++ b/examples/aggregate_signature/helpers.rs @@ -1,6 +1,6 @@ use crate::aggregate_signature::registration::Registration; use crate::aggregate_signature::signature::IndividualSignature; -use crate::{AlbaThresholdSignature, Element}; +use crate::AlbaThresholdSignature; use blake2::digest::{Update, VariableOutput}; use blake2::Blake2bVar; use blst::min_sig::{AggregatePublicKey, AggregateSignature, PublicKey, Signature}; @@ -26,7 +26,7 @@ pub(crate) fn collect_valid_signatures( signature_list: &[IndividualSignature], registration: &Registration, msg: &[u8], -) -> HashMap { +) -> HashMap<[u8; 48], usize> { let mut valid_signatures = HashMap::new(); match ®istration.checksum { diff --git a/examples/centralized_threshold.rs b/examples/centralized_threshold.rs index 1aacab21..b5ed531e 100644 --- a/examples/centralized_threshold.rs +++ b/examples/centralized_threshold.rs @@ -12,13 +12,14 @@ use rand_chacha::ChaCha20Rng; use rand_core::SeedableRng; use std::time::Instant; mod aggregate_signature; + const DATA_LENGTH: usize = 48; -pub(crate) type Element = [u8; DATA_LENGTH]; +pub(crate) type Data = [u8; DATA_LENGTH]; #[derive(Debug, Clone)] pub(crate) struct AlbaThresholdSignature { /// Centralized telescope proof - pub(crate) proof: Proof, + pub(crate) proof: Proof, /// Registration indices of the element sequence signers pub(crate) indices: Vec, /// Commitment `Hash(checksum || msg)` @@ -57,7 +58,7 @@ impl AlbaThresholdSignature { } // Collect the byte representation of valid signatures into a Vec - let prover_set: Vec = valid_signatures.keys().copied().collect(); + let prover_set: Vec = valid_signatures.keys().copied().collect(); println!("-- Creating alba proof. "); let time_gen_proof = Instant::now(); @@ -83,7 +84,7 @@ impl AlbaThresholdSignature { let indices: Vec = proof .element_sequence .iter() - .filter_map(|element| valid_signatures.get(element.as_slice()).copied()) + .filter_map(|element: &Data| valid_signatures.get(element.as_slice()).copied()) .collect(); let commitment = get_commitment::(checksum, msg).to_vec(); diff --git a/examples/simple_example.rs b/examples/simple_example.rs index 3aef04b2..cf9cde5e 100644 --- a/examples/simple_example.rs +++ b/examples/simple_example.rs @@ -10,9 +10,6 @@ use blst::min_sig::PublicKey; use rand_chacha::ChaCha20Rng; use rand_core::{RngCore, SeedableRng}; -const DATA_LENGTH: usize = 48; -type Element = [u8; DATA_LENGTH]; - fn main() { let mut rng = ChaCha20Rng::from_seed(Default::default()); let mut msg = [0u8; 16]; diff --git a/examples/simple_threshold_signature/threshold_signature.rs b/examples/simple_threshold_signature/threshold_signature.rs index 601ad872..b172de21 100644 --- a/examples/simple_threshold_signature/threshold_signature.rs +++ b/examples/simple_threshold_signature/threshold_signature.rs @@ -1,12 +1,14 @@ use crate::simple_threshold_signature::signature::Signature; -use crate::Element; use alba::centralized_telescope::proof::Proof; use alba::centralized_telescope::Telescope; use blst::min_sig::{PublicKey, Signature as BlsSignature}; use blst::BLST_ERROR; +const DATA_LENGTH: usize = 48; +pub(crate) type Data = [u8; DATA_LENGTH]; + pub(crate) struct ThresholdSignature { - proof: Proof, + proof: Proof, } impl ThresholdSignature { @@ -19,10 +21,7 @@ impl ThresholdSignature { public_key_list: &[(usize, PublicKey)], ) -> (Self, Vec) { // Convert signatures to bytes and collect as the prover set. - let prover_set = signatures - .iter() - .map(|s| s.signature.to_bytes()) - .collect::>(); + let prover_set: Vec = signatures.iter().map(|s| s.signature.to_bytes()).collect(); println!("-- Creating alba proof. "); // Create alba proof with the prover set diff --git a/src/centralized_telescope/proof.rs b/src/centralized_telescope/proof.rs index fe2bb8c1..cb302210 100644 --- a/src/centralized_telescope/proof.rs +++ b/src/centralized_telescope/proof.rs @@ -4,24 +4,21 @@ use super::params::Params; use super::round::Round; -use crate::utils::{ - sample, - types::{Element, Hash}, -}; +use crate::utils::{sample, types::Hash}; use blake2::{Blake2s256, Digest}; /// Centralized Telescope proof #[derive(Debug, Clone)] -pub struct Proof { +pub struct Proof + Clone + Ord> { /// Numbers of retries done to find the proof pub retry_counter: u64, /// Index of the searched subtree to find the proof pub search_counter: u64, /// Sequence of elements from prover's set - pub element_sequence: Vec, + pub element_sequence: Vec, } -impl Proof { +impl + Clone + Ord> Proof { /// Centralized Telescope's proving algorithm, based on a DFS algorithm. /// Calls up to `params.max_retries` times the prove_index function and /// returns a `Proof` if a suitable candidate tuple is found. @@ -35,7 +32,7 @@ impl Proof { /// # Returns /// /// A `Proof` structure - pub(super) fn new(set_size: u64, params: &Params, prover_set: &[Element]) -> Option { + pub(super) fn new(set_size: u64, params: &Params, prover_set: &[E]) -> Option { debug_assert!(crate::utils::misc::check_distinct(prover_set)); Self::prove_routine(set_size, params, prover_set).1 @@ -68,7 +65,7 @@ impl Proof { /// } /// let (setps, proof_opt) = Proof::bench(set_size, ¶ms, &prover_set); /// ``` - pub fn bench(set_size: u64, params: &Params, prover_set: &[Element]) -> (u64, Option) { + pub fn bench(set_size: u64, params: &Params, prover_set: &[E]) -> (u64, Option) { Self::prove_routine(set_size, params, prover_set) } @@ -76,11 +73,7 @@ impl Proof { /// Calls up to `params.max_retries` times the prove_index function and /// returns the number of steps done when searching a proof as well as a /// `Proof` if a suitable candidate tuple is found, otherwise `None`. - fn prove_routine( - set_size: u64, - params: &Params, - prover_set: &[Element], - ) -> (u64, Option) { + fn prove_routine(set_size: u64, params: &Params, prover_set: &[E]) -> (u64, Option>) { let mut steps: u64 = 0; // Run prove_index up to max_retries times @@ -121,14 +114,15 @@ impl Proof { } // Initialise a round with given retry and search counters - let Some(mut round) = Round::new(self.retry_counter, self.search_counter, set_size) else { + let Some(mut round) = Round::::new(self.retry_counter, self.search_counter, set_size) + else { return false; }; // For each element in the proof's sequence - for &element in &self.element_sequence { + for element in &self.element_sequence { // Retrieve the bin id associated to this new element - let Some(bin_id) = Proof::bin_hash(set_size, self.retry_counter, element) else { + let Some(bin_id) = Self::bin_hash(set_size, self.retry_counter, element) else { return false; }; // Check that the new element was chosen correctly @@ -151,21 +145,21 @@ impl Proof { fn prove_index( set_size: u64, params: &Params, - prover_set: &[Element], + prover_set: &[E], retry_counter: u64, ) -> (u64, Option) { // Initialize set_size bins - let mut bins: Vec> = Vec::with_capacity(set_size as usize); + let mut bins = Vec::with_capacity(set_size as usize); for _ in 0..set_size { bins.push(Vec::new()); } // Take only up to 2*set_size elements for efficiency and fill the bins // with them - for &element in prover_set.iter().take(set_size.saturating_mul(2) as usize) { - match Proof::bin_hash(set_size, retry_counter, element) { + for element in prover_set.iter().take(set_size.saturating_mul(2) as usize) { + match Self::bin_hash(set_size, retry_counter, element) { Some(bin_index) => { - bins[bin_index as usize].push(element); + bins[bin_index as usize].push(element.clone()); } None => return (0, None), } @@ -202,8 +196,8 @@ impl Proof { /// - proof_hash(round_hash(... round_hash((round_hash(v, t), x_1), ..., x_u)) = true fn dfs( params: &Params, - bins: &[Vec], - round: &Round, + bins: &[Vec], + round: &Round, mut step: u64, ) -> (u64, Option) { // If current round comprises params.proof_size elements and satisfies @@ -222,7 +216,7 @@ impl Proof { } // For each element in bin numbered id - for &element in &bins[round.id as usize] { + for element in &bins[round.id as usize] { // If DFS was called more than params.dfs_bound times, abort this // round if step == params.dfs_bound { @@ -246,19 +240,19 @@ impl Proof { /// Oracle producing a uniformly random value in [0, set_size[ used for /// prehashing S_p - fn bin_hash(set_size: u64, retry_counter: u64, element: Element) -> Option { + fn bin_hash(set_size: u64, retry_counter: u64, element: &E) -> Option { let retry_bytes: [u8; 8] = retry_counter.to_be_bytes(); let mut hasher = Blake2s256::new(); hasher.update(b"Telescope-bin_hash"); hasher.update(retry_bytes); - hasher.update(element); + hasher.update(element.as_ref()); let digest: Hash = hasher.finalize().into(); sample::sample_uniform(&digest, set_size) } /// Oracle defined as Bernoulli(q) returning 1 with probability q and 0 /// otherwise - fn proof_hash(valid_proof_probability: f64, r: &Round) -> bool { + fn proof_hash(valid_proof_probability: f64, r: &Round) -> bool { let mut hasher = Blake2s256::new(); hasher.update(b"Telescope-proof_hash"); hasher.update(r.hash); diff --git a/src/centralized_telescope/round.rs b/src/centralized_telescope/round.rs index 1e8ce657..57216c9e 100644 --- a/src/centralized_telescope/round.rs +++ b/src/centralized_telescope/round.rs @@ -2,21 +2,18 @@ #![doc = include_str!("../../docs/rustdoc/centralized_telescope/round.md")] -use crate::utils::{ - sample, - types::{Element, Hash}, -}; +use crate::utils::{sample, types::Hash}; use blake2::{Blake2s256, Digest}; /// Round parameters #[derive(Debug, Clone)] -pub struct Round { +pub struct Round + Clone + Ord> { /// Numbers of retries done so far pub retry_counter: u64, /// Index of the current subtree being searched pub search_counter: u64, /// Candidate element sequence - pub element_sequence: Vec, + pub element_sequence: Vec, /// Candidate round hash pub hash: Hash, /// Candidate round id, i.e. round hash mapped to [1, set_size] @@ -25,7 +22,7 @@ pub struct Round { pub set_size: u64, } -impl Round { +impl + Clone + Ord> Round { /// Output a round from retry and search counters as well as set_size /// Initilialises the hash with round_hash(retry_counter || search_bytes) /// and random value as oracle(round_hash(retry_counter || search_bytes), set_size) @@ -45,10 +42,10 @@ impl Round { /// Updates a round with an element /// Replaces the hash $h$ with $h' = round_hash(h, s)$ and the random value as oracle(h', set_size) - pub(super) fn update(r: &Self, element: Element) -> Option { + pub(super) fn update(r: &Self, element: &E) -> Option { let mut element_sequence = r.element_sequence.clone(); - element_sequence.push(element); - let (hash, id_opt) = Self::round_hash(&r.hash, &element, r.set_size); + element_sequence.push(element.clone()); + let (hash, id_opt) = Self::round_hash(&r.hash, element.as_ref(), r.set_size); id_opt.map(|id| Self { retry_counter: r.retry_counter, search_counter: r.search_counter, diff --git a/src/centralized_telescope/telescope.rs b/src/centralized_telescope/telescope.rs index e3dc66fd..764a77ec 100644 --- a/src/centralized_telescope/telescope.rs +++ b/src/centralized_telescope/telescope.rs @@ -1,7 +1,6 @@ //! Customer facing Centralized Telescope structure use super::params::Params; use super::proof::Proof; -use crate::utils::types::Element; /// The main centralized Telescope struct with prove and verify functions. #[derive(Debug, Clone, Copy)] @@ -138,7 +137,7 @@ impl Telescope { /// } /// let proof = telescope.prove(&prover_set).unwrap(); /// ``` - pub fn prove(&self, prover_set: &[Element]) -> Option { + pub fn prove + Clone + Ord>(&self, prover_set: &[E]) -> Option> { Proof::new(self.set_size, &self.params, prover_set) } @@ -166,7 +165,7 @@ impl Telescope { /// let proof = telescope.prove(&prover_set).unwrap(); /// assert!(telescope.verify(&proof)); /// ``` - pub fn verify(&self, proof: &Proof) -> bool { + pub fn verify + Clone + Ord>(&self, proof: &Proof) -> bool { proof.verify(self.set_size, &self.params) } } diff --git a/src/lib.rs b/src/lib.rs index c5a2fe12..7463bb98 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ // #![deny(missing_docs)] #![doc = include_str!("../README.md")] -mod utils; +pub mod utils; pub mod centralized_telescope; pub mod simple_lottery; diff --git a/src/simple_lottery/lottery.rs b/src/simple_lottery/lottery.rs index 6e95fe93..5ea0fa77 100644 --- a/src/simple_lottery/lottery.rs +++ b/src/simple_lottery/lottery.rs @@ -1,7 +1,6 @@ //! Customer facing Lottery structure use super::params::Params; use super::proof::Proof; -use crate::utils::types::Element; /// The main simple lottery struct with prove and verify functions. #[derive(Debug, Clone, Copy)] @@ -107,7 +106,7 @@ impl Lottery { /// } /// let proof = lottery.prove(&prover_set).unwrap(); /// ``` - pub fn prove(&self, prover_set: &[Element]) -> Option { + pub fn prove + Clone + Ord>(&self, prover_set: &[E]) -> Option> { Proof::new(&self.params, prover_set) } @@ -135,7 +134,7 @@ impl Lottery { /// let proof = lottery.prove(&prover_set).unwrap(); /// assert!(lottery.verify(&proof)); /// ``` - pub fn verify(&self, proof: &Proof) -> bool { + pub fn verify + Clone + Ord>(&self, proof: &Proof) -> bool { proof.verify(&self.params) } } diff --git a/src/simple_lottery/proof.rs b/src/simple_lottery/proof.rs index 9dea654a..33ae0d3e 100644 --- a/src/simple_lottery/proof.rs +++ b/src/simple_lottery/proof.rs @@ -1,19 +1,16 @@ //! Simple Lottery's Proof structure use super::params::Params; -use crate::utils::{ - sample, - types::{Element, Hash}, -}; +use crate::utils::{sample, types::Hash}; use blake2::{Blake2s256, Digest}; /// Simple lottery proof #[derive(Debug, Clone)] -pub struct Proof { +pub struct Proof + Clone + Ord> { /// Sequence of elements from prover's set - pub element_sequence: Vec, + pub element_sequence: Vec, } -impl Proof { +impl + Clone + Ord> Proof { /// Simple Lottery's proving algorithm, based on a DFS algorithm. /// /// # Arguments @@ -38,13 +35,13 @@ impl Proof { /// } /// let proof = Proof::new(¶ms, &prover_set).unwrap(); /// ``` - pub fn new(params: &Params, prover_set: &[Element]) -> Option { + pub fn new(params: &Params, prover_set: &[E]) -> Option { debug_assert!(crate::utils::misc::check_distinct(prover_set)); let mut element_sequence = Vec::with_capacity(params.proof_size as usize); - for &element in prover_set { + for element in prover_set { if Proof::lottery_hash(params.lottery_probability, element) { - element_sequence.push(element); + element_sequence.push(element.clone()); } if element_sequence.len() as u64 >= params.proof_size { element_sequence.sort_unstable(); @@ -87,14 +84,14 @@ impl Proof { && self .element_sequence .iter() - .all(|&element| Proof::lottery_hash(params.lottery_probability, element)) + .all(|element| Self::lottery_hash(params.lottery_probability, element)) } /// Oracle defined as Bernoulli(q) returning 1 with probability q and 0 /// otherwise - fn lottery_hash(lottery_probability: f64, element: Element) -> bool { + fn lottery_hash(lottery_probability: f64, element: &E) -> bool { let mut hasher = Blake2s256::new(); - hasher.update(element); + hasher.update(element.as_ref()); let digest: Hash = hasher.finalize().into(); sample::sample_bernoulli(&digest, lottery_probability) } diff --git a/src/utils/misc.rs b/src/utils/misc.rs index 16148a81..9febac88 100644 --- a/src/utils/misc.rs +++ b/src/utils/misc.rs @@ -1,7 +1,5 @@ -use super::types::Element; - /// Returns true iff all elements in the slice are distinct. -pub(crate) fn check_distinct(elements: &[Element]) -> bool { +pub(crate) fn check_distinct + Clone + Ord>(elements: &[E]) -> bool { let mut elements = elements.to_vec(); elements.sort_unstable(); elements.is_sorted_by(|a, b| a < b) diff --git a/src/utils/mod.rs b/src/utils/mod.rs index bc01c2bc..59362b22 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,5 +1,7 @@ +//! Shared utility functions + pub(crate) mod sample; -pub(crate) mod types; +pub mod types; pub(crate) mod misc; diff --git a/src/utils/types.rs b/src/utils/types.rs index fa6a6165..4418c760 100644 --- a/src/utils/types.rs +++ b/src/utils/types.rs @@ -1,7 +1,4 @@ -pub(crate) const DATA_LENGTH: usize = 48; - -/// Type of dataset's elements to lower bound -pub(crate) type Element = [u8; DATA_LENGTH]; +//! Types and implementation /// Digest size for internal hashes pub(crate) const DIGEST_SIZE: usize = 32; diff --git a/tests/centralized_telescope.rs b/tests/centralized_telescope.rs index 83f456a8..b0ab4457 100644 --- a/tests/centralized_telescope.rs +++ b/tests/centralized_telescope.rs @@ -9,6 +9,7 @@ mod common; use common::gen_items; const DATA_LENGTH: usize = 48; +type Data = [u8; DATA_LENGTH]; fn test(created_with_params: bool) { let mut rng = ChaCha20Rng::from_seed(Default::default()); @@ -20,7 +21,7 @@ fn test(created_with_params: bool) { let lower_bound = nb_elements.saturating_mul(20).div_ceil(100); for _t in 0..nb_tests { let seed = rng.next_u32().to_be_bytes().to_vec(); - let s_p = gen_items::(&seed, nb_elements); + let s_p: Vec = gen_items::(&seed, nb_elements); let alba = if created_with_params { Telescope::create(soundness_param, completeness_param, set_size, lower_bound) } else { @@ -47,7 +48,7 @@ fn test(created_with_params: bool) { let proof_item = Proof { retry_counter: proof.retry_counter, search_counter: proof.search_counter, - element_sequence: Vec::new(), + element_sequence: Vec::::new(), }; assert!(!alba.verify(&proof_item)); // Checking that the proof fails when wrong elements are included