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

Using generics inputs #139

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion benches/centralized_telescope/verifying_time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<alba::centralized_telescope::proof::Proof> = telescope.prove(&dataset);
let proof_opt: Option<alba::centralized_telescope::proof::Proof<[u8; 48]>> =
telescope.prove(&dataset);

if let Some(proof) = proof_opt {
// Iterate on each sample `n` times
Expand Down
4 changes: 2 additions & 2 deletions examples/aggregate_signature/helpers.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -26,7 +26,7 @@ pub(crate) fn collect_valid_signatures<const N: usize>(
signature_list: &[IndividualSignature],
registration: &Registration,
msg: &[u8],
) -> HashMap<Element, usize> {
) -> HashMap<[u8; 48], usize> {
let mut valid_signatures = HashMap::new();

match &registration.checksum {
Expand Down
9 changes: 5 additions & 4 deletions examples/centralized_threshold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Data>,
/// Registration indices of the element sequence signers
pub(crate) indices: Vec<usize>,
/// Commitment `Hash(checksum || msg)`
Expand Down Expand Up @@ -57,7 +58,7 @@ impl AlbaThresholdSignature {
}

// Collect the byte representation of valid signatures into a Vec
let prover_set: Vec<Element> = valid_signatures.keys().copied().collect();
let prover_set: Vec<Data> = valid_signatures.keys().copied().collect();

println!("-- Creating alba proof. ");
let time_gen_proof = Instant::now();
Expand All @@ -83,7 +84,7 @@ impl AlbaThresholdSignature {
let indices: Vec<usize> = 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::<N>(checksum, msg).to_vec();
Expand Down
3 changes: 0 additions & 3 deletions examples/simple_example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down
11 changes: 5 additions & 6 deletions examples/simple_threshold_signature/threshold_signature.rs
Original file line number Diff line number Diff line change
@@ -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];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe call it SigBytes?


pub(crate) struct ThresholdSignature {
proof: Proof,
proof: Proof<Data>,
}

impl ThresholdSignature {
Expand All @@ -19,10 +21,7 @@ impl ThresholdSignature {
public_key_list: &[(usize, PublicKey)],
) -> (Self, Vec<usize>) {
// Convert signatures to bytes and collect as the prover set.
let prover_set = signatures
.iter()
.map(|s| s.signature.to_bytes())
.collect::<Vec<Element>>();
let prover_set: Vec<Data> = signatures.iter().map(|s| s.signature.to_bytes()).collect();

println!("-- Creating alba proof. ");
// Create alba proof with the prover set
Expand Down
50 changes: 22 additions & 28 deletions src/centralized_telescope/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<E: AsRef<[u8]> + 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<Element>,
pub element_sequence: Vec<E>,
}

impl Proof {
impl<E: AsRef<[u8]> + Clone + Ord> Proof<E> {
/// 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.
Expand All @@ -35,7 +32,7 @@ impl Proof {
/// # Returns
///
/// A `Proof` structure
pub(super) fn new(set_size: u64, params: &Params, prover_set: &[Element]) -> Option<Self> {
pub(super) fn new(set_size: u64, params: &Params, prover_set: &[E]) -> Option<Self> {
debug_assert!(crate::utils::misc::check_distinct(prover_set));

Self::prove_routine(set_size, params, prover_set).1
Expand Down Expand Up @@ -68,19 +65,15 @@ impl Proof {
/// }
/// let (setps, proof_opt) = Proof::bench(set_size, &params, &prover_set);
/// ```
pub fn bench(set_size: u64, params: &Params, prover_set: &[Element]) -> (u64, Option<Proof>) {
pub fn bench(set_size: u64, params: &Params, prover_set: &[E]) -> (u64, Option<Self>) {
Self::prove_routine(set_size, params, prover_set)
}

/// Alba's prove routine.
/// 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<Proof>) {
fn prove_routine(set_size: u64, params: &Params, prover_set: &[E]) -> (u64, Option<Proof<E>>) {
let mut steps: u64 = 0;

// Run prove_index up to max_retries times
Expand Down Expand Up @@ -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::<E>::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
Expand All @@ -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<Self>) {
// Initialize set_size bins
let mut bins: Vec<Vec<Element>> = 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),
}
Expand Down Expand Up @@ -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<Element>],
round: &Round,
bins: &[Vec<E>],
round: &Round<E>,
mut step: u64,
) -> (u64, Option<Self>) {
// If current round comprises params.proof_size elements and satisfies
Expand All @@ -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 {
Expand All @@ -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<u64> {
fn bin_hash(set_size: u64, retry_counter: u64, element: &E) -> Option<u64> {
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<E>) -> bool {
let mut hasher = Blake2s256::new();
hasher.update(b"Telescope-proof_hash");
hasher.update(r.hash);
Expand Down
17 changes: 7 additions & 10 deletions src/centralized_telescope/round.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<E: AsRef<[u8]> + 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<Element>,
pub element_sequence: Vec<E>,
/// Candidate round hash
pub hash: Hash,
/// Candidate round id, i.e. round hash mapped to [1, set_size]
Expand All @@ -25,7 +22,7 @@ pub struct Round {
pub set_size: u64,
}

impl Round {
impl<E: AsRef<[u8]> + Clone + Ord> Round<E> {
/// 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)
Expand All @@ -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<Self> {
pub(super) fn update(r: &Self, element: &E) -> Option<Self> {
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,
Expand Down
5 changes: 2 additions & 3 deletions src/centralized_telescope/telescope.rs
Original file line number Diff line number Diff line change
@@ -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)]
Expand Down Expand Up @@ -138,7 +137,7 @@ impl Telescope {
/// }
/// let proof = telescope.prove(&prover_set).unwrap();
/// ```
pub fn prove(&self, prover_set: &[Element]) -> Option<Proof> {
pub fn prove<E: AsRef<[u8]> + Clone + Ord>(&self, prover_set: &[E]) -> Option<Proof<E>> {
Proof::new(self.set_size, &self.params, prover_set)
}

Expand Down Expand Up @@ -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<E: AsRef<[u8]> + Clone + Ord>(&self, proof: &Proof<E>) -> bool {
proof.verify(self.set_size, &self.params)
}
}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
5 changes: 2 additions & 3 deletions src/simple_lottery/lottery.rs
Original file line number Diff line number Diff line change
@@ -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)]
Expand Down Expand Up @@ -107,7 +106,7 @@ impl Lottery {
/// }
/// let proof = lottery.prove(&prover_set).unwrap();
/// ```
pub fn prove(&self, prover_set: &[Element]) -> Option<Proof> {
pub fn prove<E: AsRef<[u8]> + Clone + Ord>(&self, prover_set: &[E]) -> Option<Proof<E>> {
Proof::new(&self.params, prover_set)
}

Expand Down Expand Up @@ -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<E: AsRef<[u8]> + Clone + Ord>(&self, proof: &Proof<E>) -> bool {
proof.verify(&self.params)
}
}
Loading
Loading