From 175447e45280bc49950f79da9b00a8a63029ade3 Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Fri, 10 Jan 2025 20:36:21 +0300 Subject: [PATCH 01/24] a simple example for demo --- Cargo.toml | 1 + examples/simple_example.rs | 127 +++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 examples/simple_example.rs diff --git a/Cargo.toml b/Cargo.toml index edbfa649..17aa01a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ include = ["**/*.rs", "Cargo.toml", "README.md", ".gitignore"] [dependencies] blake2 = "0.10.6" +blst = "0.3.13" [dev-dependencies] rand_core = "0.6.4" diff --git a/examples/simple_example.rs b/examples/simple_example.rs new file mode 100644 index 00000000..4744b761 --- /dev/null +++ b/examples/simple_example.rs @@ -0,0 +1,127 @@ +//! Centralized Telescope example with BLS signatures + +use alba::centralized_telescope::params::Params; +use alba::centralized_telescope::proof::Proof; +use alba::centralized_telescope::CentralizedTelescope; +use blst::min_sig::{AggregatePublicKey, AggregateSignature, PublicKey, SecretKey, Signature}; +use blst::BLST_ERROR; +use rand_chacha::ChaCha20Rng; +use rand_core::{CryptoRng, RngCore, SeedableRng}; +use std::collections::HashMap; + +const DATA_LENGTH: usize = 48; +pub(crate) type Element = [u8; DATA_LENGTH]; + +struct AlbaSigner { + signing_key: SecretKey, + verification_key: PublicKey, +} + +struct ThresholdSignature { + proof: Proof, + key_list: Vec, +} + +impl AlbaSigner { + fn new(rng: &mut (impl RngCore + CryptoRng)) -> Self { + let mut ikm = [0u8; 32]; + rng.fill_bytes(&mut ikm); + let sk = SecretKey::key_gen(&ikm, &[]) + .expect("Error occurs when the length of ikm < 32. This will not happen here."); + let pk: PublicKey = sk.sk_to_pk(); + Self { + signing_key: sk, + verification_key: pk, + } + } + + fn sign(&self, msg: &[u8]) -> [u8; N] { + let mut signature_to_byte = [0u8; N]; + signature_to_byte.copy_from_slice(&self.signing_key.sign(&msg, &[], &[]).to_bytes()); + signature_to_byte + } +} + +impl ThresholdSignature { + fn aggregate( + alba_signatures: HashMap, + params: &Params, + key_list: HashMap, + ) -> Self { + let prover_set: Vec = alba_signatures.keys().cloned().collect(); + let alba = CentralizedTelescope::create(params); + let proof = alba.prove(&prover_set).unwrap(); + let signatures = proof.element_sequence.clone(); + let mut public_keys = Vec::with_capacity(signatures.len()); + + for sig in signatures { + public_keys.push( + *key_list + .get(alba_signatures.get(sig.as_slice()).unwrap()) + .unwrap(), + ); + } + Self { + proof, + key_list: public_keys, + } + } + + fn validate_signatures(&self, msg: &[u8]) -> bool { + let mut signatures = Vec::with_capacity(self.proof.element_sequence.len()); + for sig_bytes in &self.proof.element_sequence { + let signature = Signature::from_bytes(sig_bytes.as_slice()).unwrap(); + signatures.push(signature); + } + let signature_refs: Vec<&Signature> = signatures.iter().collect(); + let public_key_refs: Vec<&PublicKey> = self.key_list.iter().collect(); + + let aggregate_signature = AggregateSignature::aggregate(signature_refs.as_slice(), false) + .unwrap() + .to_signature(); + let aggregate_public_key = AggregatePublicKey::aggregate(public_key_refs.as_slice(), false) + .unwrap() + .to_public_key(); + let result = aggregate_signature.fast_aggregate_verify_pre_aggregated( + false, + msg, + &[], + &aggregate_public_key, + ); + result == BLST_ERROR::BLST_SUCCESS + } + + fn verify(&self, msg: &[u8], params: &Params) -> bool { + if self.validate_signatures(msg) { + let alba = CentralizedTelescope::create(params); + return alba.verify(&self.proof); + } + false + } +} + +fn main() { + let mut rng = ChaCha20Rng::from_seed(Default::default()); + let mut msg = [0u8; 16]; + rng.fill_bytes(&mut msg); + let set_size = 1000; + let params = Params { + soundness_param: 10.0, + completeness_param: 10.0, + set_size: 80 * set_size / 100, + lower_bound: 20 * set_size / 100, + }; + + let mut key_list = HashMap::with_capacity(set_size as usize); + let mut signature_list = HashMap::with_capacity(set_size as usize); + + for i in 0..set_size as usize { + let signer = AlbaSigner::new(&mut rng); + key_list.insert(i, signer.verification_key); + signature_list.insert(signer.sign::(&msg), i); + } + let threshold_signature = + ThresholdSignature::aggregate::(signature_list, ¶ms, key_list); + + print!("{:?}", threshold_signature.verify(&msg, ¶ms)); +} From 907907c2565d06e94737336280bc657ca061ffbc Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Fri, 10 Jan 2025 20:40:19 +0300 Subject: [PATCH 02/24] clippy warnings --- examples/simple_example.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/simple_example.rs b/examples/simple_example.rs index 4744b761..540a4876 100644 --- a/examples/simple_example.rs +++ b/examples/simple_example.rs @@ -37,18 +37,18 @@ impl AlbaSigner { fn sign(&self, msg: &[u8]) -> [u8; N] { let mut signature_to_byte = [0u8; N]; - signature_to_byte.copy_from_slice(&self.signing_key.sign(&msg, &[], &[]).to_bytes()); + signature_to_byte.copy_from_slice(&self.signing_key.sign(msg, &[], &[]).to_bytes()); signature_to_byte } } impl ThresholdSignature { fn aggregate( - alba_signatures: HashMap, + alba_signatures: &HashMap, params: &Params, - key_list: HashMap, + key_list: &HashMap, ) -> Self { - let prover_set: Vec = alba_signatures.keys().cloned().collect(); + let prover_set: Vec = alba_signatures.keys().copied().collect(); let alba = CentralizedTelescope::create(params); let proof = alba.prove(&prover_set).unwrap(); let signatures = proof.element_sequence.clone(); @@ -121,7 +121,7 @@ fn main() { signature_list.insert(signer.sign::(&msg), i); } let threshold_signature = - ThresholdSignature::aggregate::(signature_list, ¶ms, key_list); + ThresholdSignature::aggregate::(&signature_list, ¶ms, &key_list); print!("{:?}", threshold_signature.verify(&msg, ¶ms)); } From 9247cea96cd7c281d8d388f8daf713f11113d855 Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Tue, 14 Jan 2025 15:26:34 +0300 Subject: [PATCH 03/24] revise --- examples/simple_example.rs | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/examples/simple_example.rs b/examples/simple_example.rs index 540a4876..e9ebc7cd 100644 --- a/examples/simple_example.rs +++ b/examples/simple_example.rs @@ -67,21 +67,38 @@ impl ThresholdSignature { } } + /// Validates individual signatures in the threshold signature fn validate_signatures(&self, msg: &[u8]) -> bool { let mut signatures = Vec::with_capacity(self.proof.element_sequence.len()); for sig_bytes in &self.proof.element_sequence { - let signature = Signature::from_bytes(sig_bytes.as_slice()).unwrap(); - signatures.push(signature); + match Signature::from_bytes(sig_bytes.as_slice()) { + Ok(signature) => signatures.push(signature), + Err(_) => { + println!("Error: Failed to parse signature from bytes."); + return false; + } + } } let signature_refs: Vec<&Signature> = signatures.iter().collect(); + let aggregate_signature = + match AggregateSignature::aggregate(signature_refs.as_slice(), false) { + Ok(agg_sig) => agg_sig.to_signature(), + Err(_) => { + println!("Error: Failed to aggregate signatures."); + return false; + } + }; + let public_key_refs: Vec<&PublicKey> = self.key_list.iter().collect(); + let aggregate_public_key = + match AggregatePublicKey::aggregate(public_key_refs.as_slice(), false) { + Ok(agg_pk) => agg_pk.to_public_key(), + Err(_) => { + println!("Error: Failed to aggregate public keys."); + return false; + } + }; - let aggregate_signature = AggregateSignature::aggregate(signature_refs.as_slice(), false) - .unwrap() - .to_signature(); - let aggregate_public_key = AggregatePublicKey::aggregate(public_key_refs.as_slice(), false) - .unwrap() - .to_public_key(); let result = aggregate_signature.fast_aggregate_verify_pre_aggregated( false, msg, From a1ade3dda986a64d1d94469f115c0f16a1efe20e Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Tue, 14 Jan 2025 15:46:33 +0300 Subject: [PATCH 04/24] clippy --- examples/simple_example.rs | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/examples/simple_example.rs b/examples/simple_example.rs index e9ebc7cd..e02c1d20 100644 --- a/examples/simple_example.rs +++ b/examples/simple_example.rs @@ -71,32 +71,29 @@ impl ThresholdSignature { fn validate_signatures(&self, msg: &[u8]) -> bool { let mut signatures = Vec::with_capacity(self.proof.element_sequence.len()); for sig_bytes in &self.proof.element_sequence { - match Signature::from_bytes(sig_bytes.as_slice()) { - Ok(signature) => signatures.push(signature), - Err(_) => { - println!("Error: Failed to parse signature from bytes."); - return false; - } + if let Ok(signature) = Signature::from_bytes(sig_bytes.as_slice()) { + signatures.push(signature); + } else { + println!("Error: Failed to parse signature from bytes."); + return false; } } let signature_refs: Vec<&Signature> = signatures.iter().collect(); let aggregate_signature = - match AggregateSignature::aggregate(signature_refs.as_slice(), false) { - Ok(agg_sig) => agg_sig.to_signature(), - Err(_) => { - println!("Error: Failed to aggregate signatures."); - return false; - } + if let Ok(agg_sig) = AggregateSignature::aggregate(signature_refs.as_slice(), false) { + agg_sig.to_signature(); + } else { + println!("Error: Failed to aggregate signatures."); + return false; }; let public_key_refs: Vec<&PublicKey> = self.key_list.iter().collect(); let aggregate_public_key = - match AggregatePublicKey::aggregate(public_key_refs.as_slice(), false) { - Ok(agg_pk) => agg_pk.to_public_key(), - Err(_) => { - println!("Error: Failed to aggregate public keys."); - return false; - } + if let Ok(agg_pk) = AggregatePublicKey::aggregate(public_key_refs.as_slice(), false) { + agg_pk.to_public_key(); + } else { + println!("Error: Failed to aggregate public keys."); + return false; }; let result = aggregate_signature.fast_aggregate_verify_pre_aggregated( From de18f055a5d54c95d4025135bd29aaacd7dfe242 Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Tue, 14 Jan 2025 15:53:44 +0300 Subject: [PATCH 05/24] clippy error --- examples/simple_example.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/examples/simple_example.rs b/examples/simple_example.rs index e02c1d20..b8113e10 100644 --- a/examples/simple_example.rs +++ b/examples/simple_example.rs @@ -81,7 +81,7 @@ impl ThresholdSignature { let signature_refs: Vec<&Signature> = signatures.iter().collect(); let aggregate_signature = if let Ok(agg_sig) = AggregateSignature::aggregate(signature_refs.as_slice(), false) { - agg_sig.to_signature(); + agg_sig.to_signature() } else { println!("Error: Failed to aggregate signatures."); return false; @@ -90,18 +90,14 @@ impl ThresholdSignature { let public_key_refs: Vec<&PublicKey> = self.key_list.iter().collect(); let aggregate_public_key = if let Ok(agg_pk) = AggregatePublicKey::aggregate(public_key_refs.as_slice(), false) { - agg_pk.to_public_key(); + agg_pk.to_public_key() } else { println!("Error: Failed to aggregate public keys."); return false; }; - let result = aggregate_signature.fast_aggregate_verify_pre_aggregated( - false, - msg, - &[], - &aggregate_public_key, - ); + let result = + aggregate_signature.verify(false, &msg, &[], &[], &aggregate_public_key, false); result == BLST_ERROR::BLST_SUCCESS } From bb4a648f7c7004f930737c0a0b5ec5f21d1aa815 Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Tue, 14 Jan 2025 19:13:27 +0300 Subject: [PATCH 06/24] clippy warning --- examples/simple_example.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/simple_example.rs b/examples/simple_example.rs index b8113e10..2a9df286 100644 --- a/examples/simple_example.rs +++ b/examples/simple_example.rs @@ -97,7 +97,7 @@ impl ThresholdSignature { }; let result = - aggregate_signature.verify(false, &msg, &[], &[], &aggregate_public_key, false); + aggregate_signature.verify(false, msg, &[], &[], &aggregate_public_key, false); result == BLST_ERROR::BLST_SUCCESS } From bb96e535a287913663f521f1747346d3a2e66add Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Tue, 14 Jan 2025 19:15:15 +0300 Subject: [PATCH 07/24] fmt --- examples/simple_example.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/simple_example.rs b/examples/simple_example.rs index 2a9df286..b55ab362 100644 --- a/examples/simple_example.rs +++ b/examples/simple_example.rs @@ -96,8 +96,7 @@ impl ThresholdSignature { return false; }; - let result = - aggregate_signature.verify(false, msg, &[], &[], &aggregate_public_key, false); + let result = aggregate_signature.verify(false, msg, &[], &[], &aggregate_public_key, false); result == BLST_ERROR::BLST_SUCCESS } From c162f3572b40318318db07591cd3c16f55e171a6 Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Wed, 15 Jan 2025 21:00:47 +0300 Subject: [PATCH 08/24] move blst to dev dependencies --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 17aa01a1..e48d4c89 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,12 +10,12 @@ include = ["**/*.rs", "Cargo.toml", "README.md", ".gitignore"] [dependencies] blake2 = "0.10.6" -blst = "0.3.13" [dev-dependencies] rand_core = "0.6.4" rand_chacha = "0.3.1" test-case = "3.3.1" +blst = "0.3.13" [lints.rust] missing-copy-implementations = "warn" From 1ff40a7395a1d4466dae8726d7e8d2d0d1bda9be Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Wed, 15 Jan 2025 21:25:42 +0300 Subject: [PATCH 09/24] simplify aggregation --- examples/simple_example.rs | 43 +++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/examples/simple_example.rs b/examples/simple_example.rs index b55ab362..5550d5ef 100644 --- a/examples/simple_example.rs +++ b/examples/simple_example.rs @@ -71,32 +71,33 @@ impl ThresholdSignature { fn validate_signatures(&self, msg: &[u8]) -> bool { let mut signatures = Vec::with_capacity(self.proof.element_sequence.len()); for sig_bytes in &self.proof.element_sequence { - if let Ok(signature) = Signature::from_bytes(sig_bytes.as_slice()) { - signatures.push(signature); - } else { - println!("Error: Failed to parse signature from bytes."); + let Ok(signature) = Signature::from_bytes(sig_bytes.as_slice()) else { return false; - } + }; + signatures.push(signature); } let signature_refs: Vec<&Signature> = signatures.iter().collect(); - let aggregate_signature = - if let Ok(agg_sig) = AggregateSignature::aggregate(signature_refs.as_slice(), false) { - agg_sig.to_signature() - } else { - println!("Error: Failed to aggregate signatures."); - return false; - }; + let Ok(aggregate_signature) = + AggregateSignature::aggregate(signature_refs.as_slice(), false) + else { + return false; + }; + let final_signature = aggregate_signature.to_signature(); let public_key_refs: Vec<&PublicKey> = self.key_list.iter().collect(); - let aggregate_public_key = - if let Ok(agg_pk) = AggregatePublicKey::aggregate(public_key_refs.as_slice(), false) { - agg_pk.to_public_key() - } else { - println!("Error: Failed to aggregate public keys."); - return false; - }; - - let result = aggregate_signature.verify(false, msg, &[], &[], &aggregate_public_key, false); + let Ok(aggregate_verification_key) = AggregatePublicKey::aggregate(public_key_refs.as_slice(), false)else { + return false; + }; + let final_verification_key = aggregate_verification_key.to_public_key(); + + let result = final_signature.verify( + false, + msg, + &[], + &[], + &final_verification_key, + false, + ); result == BLST_ERROR::BLST_SUCCESS } From 1915514b7e20f4b3938866a4c974b422500f11f6 Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Wed, 15 Jan 2025 22:12:37 +0300 Subject: [PATCH 10/24] cargo fmt --- examples/simple_example.rs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/examples/simple_example.rs b/examples/simple_example.rs index 5550d5ef..54710eff 100644 --- a/examples/simple_example.rs +++ b/examples/simple_example.rs @@ -85,19 +85,14 @@ impl ThresholdSignature { let final_signature = aggregate_signature.to_signature(); let public_key_refs: Vec<&PublicKey> = self.key_list.iter().collect(); - let Ok(aggregate_verification_key) = AggregatePublicKey::aggregate(public_key_refs.as_slice(), false)else { + let Ok(aggregate_verification_key) = + AggregatePublicKey::aggregate(public_key_refs.as_slice(), false) + else { return false; }; let final_verification_key = aggregate_verification_key.to_public_key(); - let result = final_signature.verify( - false, - msg, - &[], - &[], - &final_verification_key, - false, - ); + let result = final_signature.verify(false, msg, &[], &[], &final_verification_key, false); result == BLST_ERROR::BLST_SUCCESS } From 20cedea557d0b9ed36305e90ee6a78d45b5dff21 Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Thu, 16 Jan 2025 18:50:45 +0300 Subject: [PATCH 11/24] moving structs to separate files --- examples/simple_aggregate_signature/mod.rs | 2 + examples/simple_aggregate_signature/signer.rs | 27 +++++ .../threshold_signature.rs | 75 +++++++++++++ examples/simple_example.rs | 105 +----------------- 4 files changed, 110 insertions(+), 99 deletions(-) create mode 100644 examples/simple_aggregate_signature/mod.rs create mode 100644 examples/simple_aggregate_signature/signer.rs create mode 100644 examples/simple_aggregate_signature/threshold_signature.rs diff --git a/examples/simple_aggregate_signature/mod.rs b/examples/simple_aggregate_signature/mod.rs new file mode 100644 index 00000000..6b65c726 --- /dev/null +++ b/examples/simple_aggregate_signature/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod signer; +pub(crate) mod threshold_signature; diff --git a/examples/simple_aggregate_signature/signer.rs b/examples/simple_aggregate_signature/signer.rs new file mode 100644 index 00000000..a5107ef8 --- /dev/null +++ b/examples/simple_aggregate_signature/signer.rs @@ -0,0 +1,27 @@ +use blst::min_sig::{PublicKey, SecretKey}; +use rand_core::{CryptoRng, RngCore}; + +pub(crate) struct Signer { + signing_key: SecretKey, + pub(crate) verification_key: PublicKey, +} + +impl Signer { + pub(crate) fn new(rng: &mut (impl RngCore + CryptoRng)) -> Self { + let mut ikm = [0u8; 32]; + rng.fill_bytes(&mut ikm); + let sk = SecretKey::key_gen(&ikm, &[]) + .expect("Error occurs when the length of ikm < 32. This will not happen here."); + let pk: PublicKey = sk.sk_to_pk(); + Self { + signing_key: sk, + verification_key: pk, + } + } + + pub(crate) fn sign(&self, msg: &[u8]) -> [u8; N] { + let mut signature_to_byte = [0u8; N]; + signature_to_byte.copy_from_slice(&self.signing_key.sign(msg, &[], &[]).to_bytes()); + signature_to_byte + } +} diff --git a/examples/simple_aggregate_signature/threshold_signature.rs b/examples/simple_aggregate_signature/threshold_signature.rs new file mode 100644 index 00000000..c560e678 --- /dev/null +++ b/examples/simple_aggregate_signature/threshold_signature.rs @@ -0,0 +1,75 @@ +use crate::Element; +use alba::centralized_telescope::params::Params; +use alba::centralized_telescope::proof::Proof; +use alba::centralized_telescope::CentralizedTelescope; +use blst::min_sig::{AggregatePublicKey, AggregateSignature, PublicKey, Signature}; +use blst::BLST_ERROR; +use std::collections::HashMap; + +pub(crate) struct ThresholdSignature { + proof: Proof, + key_list: Vec, +} + +impl ThresholdSignature { + pub(crate) fn aggregate( + alba_signatures: &HashMap, + params: &Params, + key_list: &HashMap, + ) -> Self { + let prover_set: Vec = alba_signatures.keys().copied().collect(); + let alba = CentralizedTelescope::create(params); + let proof = alba.prove(&prover_set).unwrap(); + let signatures = proof.element_sequence.clone(); + let mut public_keys = Vec::with_capacity(signatures.len()); + + for sig in signatures { + public_keys.push( + *key_list + .get(alba_signatures.get(sig.as_slice()).unwrap()) + .unwrap(), + ); + } + Self { + proof, + key_list: public_keys, + } + } + + /// Validates individual signatures in the threshold signature + fn validate_signatures(&self, msg: &[u8]) -> bool { + let mut signatures = Vec::with_capacity(self.proof.element_sequence.len()); + for sig_bytes in &self.proof.element_sequence { + let Ok(signature) = Signature::from_bytes(sig_bytes.as_slice()) else { + return false; + }; + signatures.push(signature); + } + let signature_refs: Vec<&Signature> = signatures.iter().collect(); + let Ok(aggregate_signature) = + AggregateSignature::aggregate(signature_refs.as_slice(), false) + else { + return false; + }; + let final_signature = aggregate_signature.to_signature(); + + let public_key_refs: Vec<&PublicKey> = self.key_list.iter().collect(); + let Ok(aggregate_verification_key) = + AggregatePublicKey::aggregate(public_key_refs.as_slice(), false) + else { + return false; + }; + let final_verification_key = aggregate_verification_key.to_public_key(); + + let result = final_signature.verify(false, msg, &[], &[], &final_verification_key, false); + result == BLST_ERROR::BLST_SUCCESS + } + + pub(crate) fn verify(&self, msg: &[u8], params: &Params) -> bool { + if self.validate_signatures(msg) { + let alba = CentralizedTelescope::create(params); + return alba.verify(&self.proof); + } + false + } +} diff --git a/examples/simple_example.rs b/examples/simple_example.rs index 54710eff..5f081942 100644 --- a/examples/simple_example.rs +++ b/examples/simple_example.rs @@ -1,110 +1,17 @@ //! Centralized Telescope example with BLS signatures +mod simple_aggregate_signature; + +use crate::simple_aggregate_signature::signer::Signer; +use crate::simple_aggregate_signature::threshold_signature::ThresholdSignature; use alba::centralized_telescope::params::Params; -use alba::centralized_telescope::proof::Proof; -use alba::centralized_telescope::CentralizedTelescope; -use blst::min_sig::{AggregatePublicKey, AggregateSignature, PublicKey, SecretKey, Signature}; -use blst::BLST_ERROR; use rand_chacha::ChaCha20Rng; -use rand_core::{CryptoRng, RngCore, SeedableRng}; +use rand_core::{RngCore, SeedableRng}; use std::collections::HashMap; const DATA_LENGTH: usize = 48; pub(crate) type Element = [u8; DATA_LENGTH]; -struct AlbaSigner { - signing_key: SecretKey, - verification_key: PublicKey, -} - -struct ThresholdSignature { - proof: Proof, - key_list: Vec, -} - -impl AlbaSigner { - fn new(rng: &mut (impl RngCore + CryptoRng)) -> Self { - let mut ikm = [0u8; 32]; - rng.fill_bytes(&mut ikm); - let sk = SecretKey::key_gen(&ikm, &[]) - .expect("Error occurs when the length of ikm < 32. This will not happen here."); - let pk: PublicKey = sk.sk_to_pk(); - Self { - signing_key: sk, - verification_key: pk, - } - } - - fn sign(&self, msg: &[u8]) -> [u8; N] { - let mut signature_to_byte = [0u8; N]; - signature_to_byte.copy_from_slice(&self.signing_key.sign(msg, &[], &[]).to_bytes()); - signature_to_byte - } -} - -impl ThresholdSignature { - fn aggregate( - alba_signatures: &HashMap, - params: &Params, - key_list: &HashMap, - ) -> Self { - let prover_set: Vec = alba_signatures.keys().copied().collect(); - let alba = CentralizedTelescope::create(params); - let proof = alba.prove(&prover_set).unwrap(); - let signatures = proof.element_sequence.clone(); - let mut public_keys = Vec::with_capacity(signatures.len()); - - for sig in signatures { - public_keys.push( - *key_list - .get(alba_signatures.get(sig.as_slice()).unwrap()) - .unwrap(), - ); - } - Self { - proof, - key_list: public_keys, - } - } - - /// Validates individual signatures in the threshold signature - fn validate_signatures(&self, msg: &[u8]) -> bool { - let mut signatures = Vec::with_capacity(self.proof.element_sequence.len()); - for sig_bytes in &self.proof.element_sequence { - let Ok(signature) = Signature::from_bytes(sig_bytes.as_slice()) else { - return false; - }; - signatures.push(signature); - } - let signature_refs: Vec<&Signature> = signatures.iter().collect(); - let Ok(aggregate_signature) = - AggregateSignature::aggregate(signature_refs.as_slice(), false) - else { - return false; - }; - let final_signature = aggregate_signature.to_signature(); - - let public_key_refs: Vec<&PublicKey> = self.key_list.iter().collect(); - let Ok(aggregate_verification_key) = - AggregatePublicKey::aggregate(public_key_refs.as_slice(), false) - else { - return false; - }; - let final_verification_key = aggregate_verification_key.to_public_key(); - - let result = final_signature.verify(false, msg, &[], &[], &final_verification_key, false); - result == BLST_ERROR::BLST_SUCCESS - } - - fn verify(&self, msg: &[u8], params: &Params) -> bool { - if self.validate_signatures(msg) { - let alba = CentralizedTelescope::create(params); - return alba.verify(&self.proof); - } - false - } -} - fn main() { let mut rng = ChaCha20Rng::from_seed(Default::default()); let mut msg = [0u8; 16]; @@ -121,7 +28,7 @@ fn main() { let mut signature_list = HashMap::with_capacity(set_size as usize); for i in 0..set_size as usize { - let signer = AlbaSigner::new(&mut rng); + let signer = Signer::new(&mut rng); key_list.insert(i, signer.verification_key); signature_list.insert(signer.sign::(&msg), i); } From acb5159fc532fbfb95cbd55b5d3c614429ff6f45 Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Thu, 16 Jan 2025 18:55:33 +0300 Subject: [PATCH 12/24] removing generics --- examples/simple_aggregate_signature/signer.rs | 4 ++-- examples/simple_aggregate_signature/threshold_signature.rs | 2 +- examples/simple_example.rs | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/examples/simple_aggregate_signature/signer.rs b/examples/simple_aggregate_signature/signer.rs index a5107ef8..344217d2 100644 --- a/examples/simple_aggregate_signature/signer.rs +++ b/examples/simple_aggregate_signature/signer.rs @@ -19,8 +19,8 @@ impl Signer { } } - pub(crate) fn sign(&self, msg: &[u8]) -> [u8; N] { - let mut signature_to_byte = [0u8; N]; + pub(crate) fn sign(&self, msg: &[u8]) -> [u8; 48] { + let mut signature_to_byte = [0u8; 48]; signature_to_byte.copy_from_slice(&self.signing_key.sign(msg, &[], &[]).to_bytes()); signature_to_byte } diff --git a/examples/simple_aggregate_signature/threshold_signature.rs b/examples/simple_aggregate_signature/threshold_signature.rs index c560e678..513ba080 100644 --- a/examples/simple_aggregate_signature/threshold_signature.rs +++ b/examples/simple_aggregate_signature/threshold_signature.rs @@ -12,7 +12,7 @@ pub(crate) struct ThresholdSignature { } impl ThresholdSignature { - pub(crate) fn aggregate( + pub(crate) fn aggregate( alba_signatures: &HashMap, params: &Params, key_list: &HashMap, diff --git a/examples/simple_example.rs b/examples/simple_example.rs index 5f081942..d43f2d01 100644 --- a/examples/simple_example.rs +++ b/examples/simple_example.rs @@ -30,10 +30,9 @@ fn main() { for i in 0..set_size as usize { let signer = Signer::new(&mut rng); key_list.insert(i, signer.verification_key); - signature_list.insert(signer.sign::(&msg), i); + signature_list.insert(signer.sign(&msg), i); } - let threshold_signature = - ThresholdSignature::aggregate::(&signature_list, ¶ms, &key_list); + let threshold_signature = ThresholdSignature::aggregate(&signature_list, ¶ms, &key_list); print!("{:?}", threshold_signature.verify(&msg, ¶ms)); } From 8775e191a4848a22bcca152d621c4723b41332be Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Thu, 16 Jan 2025 19:26:32 +0300 Subject: [PATCH 13/24] signatures verified individually --- .../threshold_signature.rs | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/examples/simple_aggregate_signature/threshold_signature.rs b/examples/simple_aggregate_signature/threshold_signature.rs index 513ba080..de779087 100644 --- a/examples/simple_aggregate_signature/threshold_signature.rs +++ b/examples/simple_aggregate_signature/threshold_signature.rs @@ -2,7 +2,7 @@ use crate::Element; use alba::centralized_telescope::params::Params; use alba::centralized_telescope::proof::Proof; use alba::centralized_telescope::CentralizedTelescope; -use blst::min_sig::{AggregatePublicKey, AggregateSignature, PublicKey, Signature}; +use blst::min_sig::{PublicKey, Signature}; use blst::BLST_ERROR; use std::collections::HashMap; @@ -37,6 +37,12 @@ impl ThresholdSignature { } /// Validates individual signatures in the threshold signature + /// This function verifies each individual signature separately. + /// The verification could also be done by using aggregation from blst library as follows: + /// - Aggregate signatures with: `AggregateSignature::aggregate`, + /// - Aggregate public keys with: `AggregatePublicKey::aggregate`, + /// - Convert aggregate signature to a signature and aggregate public key to a public key + /// - Verify the signature with public key against given message. fn validate_signatures(&self, msg: &[u8]) -> bool { let mut signatures = Vec::with_capacity(self.proof.element_sequence.len()); for sig_bytes in &self.proof.element_sequence { @@ -45,24 +51,14 @@ impl ThresholdSignature { }; signatures.push(signature); } - let signature_refs: Vec<&Signature> = signatures.iter().collect(); - let Ok(aggregate_signature) = - AggregateSignature::aggregate(signature_refs.as_slice(), false) - else { - return false; - }; - let final_signature = aggregate_signature.to_signature(); - - let public_key_refs: Vec<&PublicKey> = self.key_list.iter().collect(); - let Ok(aggregate_verification_key) = - AggregatePublicKey::aggregate(public_key_refs.as_slice(), false) - else { - return false; - }; - let final_verification_key = aggregate_verification_key.to_public_key(); - - let result = final_signature.verify(false, msg, &[], &[], &final_verification_key, false); - result == BLST_ERROR::BLST_SUCCESS + for (i, signature) in signatures.iter().enumerate() { + if signature.verify(false, msg, &[], &[], &self.key_list[i], false) + != BLST_ERROR::BLST_SUCCESS + { + return false; + } + } + return true; } pub(crate) fn verify(&self, msg: &[u8], params: &Params) -> bool { From 5e6b2573e377806da987875c93e47d99bb647bc0 Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Thu, 16 Jan 2025 20:24:17 +0300 Subject: [PATCH 14/24] signature struct, no hashmap to collect signatures --- examples/simple_aggregate_signature/mod.rs | 1 + .../simple_aggregate_signature/signature.rs | 21 +++++++++ examples/simple_aggregate_signature/signer.rs | 10 +++-- .../threshold_signature.rs | 44 +++++++++++++------ examples/simple_example.rs | 5 ++- 5 files changed, 62 insertions(+), 19 deletions(-) create mode 100644 examples/simple_aggregate_signature/signature.rs diff --git a/examples/simple_aggregate_signature/mod.rs b/examples/simple_aggregate_signature/mod.rs index 6b65c726..b18e8dfc 100644 --- a/examples/simple_aggregate_signature/mod.rs +++ b/examples/simple_aggregate_signature/mod.rs @@ -1,2 +1,3 @@ +pub(crate) mod signature; pub(crate) mod signer; pub(crate) mod threshold_signature; diff --git a/examples/simple_aggregate_signature/signature.rs b/examples/simple_aggregate_signature/signature.rs new file mode 100644 index 00000000..54b6ff8d --- /dev/null +++ b/examples/simple_aggregate_signature/signature.rs @@ -0,0 +1,21 @@ +use blst::min_sig::{PublicKey, Signature as BLSSignature}; +use blst::BLST_ERROR; + +/// Single signature +#[derive(Debug, Clone)] +pub(crate) struct Signature { + /// Signature of type bls signature + pub(crate) signature: BLSSignature, + /// Verification index of the signer + pub(crate) index: usize, +} + +impl Signature { + /// Verify signature against `commitment = Hash(checksum || msg)` + pub(crate) fn verify(&self, msg: &[u8], verification_key: &PublicKey) -> bool { + let result = self + .signature + .verify(false, msg, &[], &[], verification_key, false); + result == BLST_ERROR::BLST_SUCCESS + } +} diff --git a/examples/simple_aggregate_signature/signer.rs b/examples/simple_aggregate_signature/signer.rs index 344217d2..1dad6b99 100644 --- a/examples/simple_aggregate_signature/signer.rs +++ b/examples/simple_aggregate_signature/signer.rs @@ -1,3 +1,4 @@ +use crate::simple_aggregate_signature::signature::Signature; use blst::min_sig::{PublicKey, SecretKey}; use rand_core::{CryptoRng, RngCore}; @@ -19,9 +20,10 @@ impl Signer { } } - pub(crate) fn sign(&self, msg: &[u8]) -> [u8; 48] { - let mut signature_to_byte = [0u8; 48]; - signature_to_byte.copy_from_slice(&self.signing_key.sign(msg, &[], &[]).to_bytes()); - signature_to_byte + pub(crate) fn sign(&self, msg: &[u8], index: usize) -> Signature { + Signature { + signature: self.signing_key.sign(msg, &[], &[]), + index, + } } } diff --git a/examples/simple_aggregate_signature/threshold_signature.rs b/examples/simple_aggregate_signature/threshold_signature.rs index de779087..a2ec50ed 100644 --- a/examples/simple_aggregate_signature/threshold_signature.rs +++ b/examples/simple_aggregate_signature/threshold_signature.rs @@ -1,8 +1,9 @@ +use crate::simple_aggregate_signature::signature::Signature; use crate::Element; use alba::centralized_telescope::params::Params; use alba::centralized_telescope::proof::Proof; use alba::centralized_telescope::CentralizedTelescope; -use blst::min_sig::{PublicKey, Signature}; +use blst::min_sig::{PublicKey, Signature as BLSSignature}; use blst::BLST_ERROR; use std::collections::HashMap; @@ -13,22 +14,39 @@ pub(crate) struct ThresholdSignature { impl ThresholdSignature { pub(crate) fn aggregate( - alba_signatures: &HashMap, + alba_signatures: &[Signature], params: &Params, key_list: &HashMap, ) -> Self { - let prover_set: Vec = alba_signatures.keys().copied().collect(); + let prover_set = alba_signatures + .iter() + .map(|s| s.signature.to_bytes()) + .collect::>(); let alba = CentralizedTelescope::create(params); let proof = alba.prove(&prover_set).unwrap(); - let signatures = proof.element_sequence.clone(); - let mut public_keys = Vec::with_capacity(signatures.len()); + let proof_elements = proof.element_sequence.clone(); + // let mut public_keys = Vec::with_capacity(proof_elements.len()); - for sig in signatures { - public_keys.push( - *key_list - .get(alba_signatures.get(sig.as_slice()).unwrap()) - .unwrap(), - ); + let proof_signatures = proof_elements + .iter() + .map(|element| BLSSignature::from_bytes(element).unwrap()) + .collect::>(); + + // Resolve public keys corresponding to each signature + let mut public_keys = Vec::with_capacity(proof_signatures.len()); + for sig in &proof_signatures { + // Find the index of the signature in `alba_signatures` + if let Some(signature_entry) = + alba_signatures.iter().find(|entry| entry.signature == *sig) + { + if let Some(public_key) = key_list.get(&signature_entry.index) { + public_keys.push(*public_key); + } else { + panic!("Public key not found for index: {}", signature_entry.index); + } + } else { + panic!("Signature not found in alba_signatures: {:?}", sig); + } } Self { proof, @@ -46,7 +64,7 @@ impl ThresholdSignature { fn validate_signatures(&self, msg: &[u8]) -> bool { let mut signatures = Vec::with_capacity(self.proof.element_sequence.len()); for sig_bytes in &self.proof.element_sequence { - let Ok(signature) = Signature::from_bytes(sig_bytes.as_slice()) else { + let Ok(signature) = BLSSignature::from_bytes(sig_bytes.as_slice()) else { return false; }; signatures.push(signature); @@ -58,7 +76,7 @@ impl ThresholdSignature { return false; } } - return true; + true } pub(crate) fn verify(&self, msg: &[u8], params: &Params) -> bool { diff --git a/examples/simple_example.rs b/examples/simple_example.rs index d43f2d01..6b1d1425 100644 --- a/examples/simple_example.rs +++ b/examples/simple_example.rs @@ -2,6 +2,7 @@ mod simple_aggregate_signature; +use crate::simple_aggregate_signature::signature::Signature; use crate::simple_aggregate_signature::signer::Signer; use crate::simple_aggregate_signature::threshold_signature::ThresholdSignature; use alba::centralized_telescope::params::Params; @@ -25,12 +26,12 @@ fn main() { }; let mut key_list = HashMap::with_capacity(set_size as usize); - let mut signature_list = HashMap::with_capacity(set_size as usize); + let mut signature_list: Vec = Vec::with_capacity(set_size as usize); for i in 0..set_size as usize { let signer = Signer::new(&mut rng); key_list.insert(i, signer.verification_key); - signature_list.insert(signer.sign(&msg), i); + signature_list.push(signer.sign(&msg, i)); } let threshold_signature = ThresholdSignature::aggregate(&signature_list, ¶ms, &key_list); From e35ed4c57db0b921b104f5f6ebbbb968d51e6830 Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Thu, 16 Jan 2025 20:26:11 +0300 Subject: [PATCH 15/24] remove compy paste left over --- examples/simple_aggregate_signature/signature.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/examples/simple_aggregate_signature/signature.rs b/examples/simple_aggregate_signature/signature.rs index 54b6ff8d..cbd62bcb 100644 --- a/examples/simple_aggregate_signature/signature.rs +++ b/examples/simple_aggregate_signature/signature.rs @@ -9,13 +9,3 @@ pub(crate) struct Signature { /// Verification index of the signer pub(crate) index: usize, } - -impl Signature { - /// Verify signature against `commitment = Hash(checksum || msg)` - pub(crate) fn verify(&self, msg: &[u8], verification_key: &PublicKey) -> bool { - let result = self - .signature - .verify(false, msg, &[], &[], verification_key, false); - result == BLST_ERROR::BLST_SUCCESS - } -} From f17060779091b9ed9dd66ca132bacf030dd03fd2 Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Thu, 16 Jan 2025 20:49:50 +0300 Subject: [PATCH 16/24] remove key_list from ThresholdSignature --- .../simple_aggregate_signature/signature.rs | 3 +-- .../threshold_signature.rs | 26 ++++++++----------- examples/simple_example.rs | 16 +++++++----- 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/examples/simple_aggregate_signature/signature.rs b/examples/simple_aggregate_signature/signature.rs index cbd62bcb..2ed519d2 100644 --- a/examples/simple_aggregate_signature/signature.rs +++ b/examples/simple_aggregate_signature/signature.rs @@ -1,5 +1,4 @@ -use blst::min_sig::{PublicKey, Signature as BLSSignature}; -use blst::BLST_ERROR; +use blst::min_sig::Signature as BLSSignature; /// Single signature #[derive(Debug, Clone)] diff --git a/examples/simple_aggregate_signature/threshold_signature.rs b/examples/simple_aggregate_signature/threshold_signature.rs index a2ec50ed..e2e0b64c 100644 --- a/examples/simple_aggregate_signature/threshold_signature.rs +++ b/examples/simple_aggregate_signature/threshold_signature.rs @@ -5,19 +5,17 @@ use alba::centralized_telescope::proof::Proof; use alba::centralized_telescope::CentralizedTelescope; use blst::min_sig::{PublicKey, Signature as BLSSignature}; use blst::BLST_ERROR; -use std::collections::HashMap; pub(crate) struct ThresholdSignature { proof: Proof, - key_list: Vec, } impl ThresholdSignature { pub(crate) fn aggregate( alba_signatures: &[Signature], params: &Params, - key_list: &HashMap, - ) -> Self { + key_list: &[(usize, PublicKey)], + ) -> (Self, Vec) { let prover_set = alba_signatures .iter() .map(|s| s.signature.to_bytes()) @@ -25,21 +23,22 @@ impl ThresholdSignature { let alba = CentralizedTelescope::create(params); let proof = alba.prove(&prover_set).unwrap(); let proof_elements = proof.element_sequence.clone(); - // let mut public_keys = Vec::with_capacity(proof_elements.len()); let proof_signatures = proof_elements .iter() .map(|element| BLSSignature::from_bytes(element).unwrap()) .collect::>(); - // Resolve public keys corresponding to each signature let mut public_keys = Vec::with_capacity(proof_signatures.len()); for sig in &proof_signatures { // Find the index of the signature in `alba_signatures` if let Some(signature_entry) = alba_signatures.iter().find(|entry| entry.signature == *sig) { - if let Some(public_key) = key_list.get(&signature_entry.index) { + if let Some((_, public_key)) = key_list + .iter() + .find(|entry| entry.0 == signature_entry.index) + { public_keys.push(*public_key); } else { panic!("Public key not found for index: {}", signature_entry.index); @@ -48,10 +47,7 @@ impl ThresholdSignature { panic!("Signature not found in alba_signatures: {:?}", sig); } } - Self { - proof, - key_list: public_keys, - } + (Self { proof }, public_keys) } /// Validates individual signatures in the threshold signature @@ -61,7 +57,7 @@ impl ThresholdSignature { /// - Aggregate public keys with: `AggregatePublicKey::aggregate`, /// - Convert aggregate signature to a signature and aggregate public key to a public key /// - Verify the signature with public key against given message. - fn validate_signatures(&self, msg: &[u8]) -> bool { + fn validate_signatures(&self, msg: &[u8], public_keys: &[PublicKey]) -> bool { let mut signatures = Vec::with_capacity(self.proof.element_sequence.len()); for sig_bytes in &self.proof.element_sequence { let Ok(signature) = BLSSignature::from_bytes(sig_bytes.as_slice()) else { @@ -70,7 +66,7 @@ impl ThresholdSignature { signatures.push(signature); } for (i, signature) in signatures.iter().enumerate() { - if signature.verify(false, msg, &[], &[], &self.key_list[i], false) + if signature.verify(false, msg, &[], &[], &public_keys[i], false) != BLST_ERROR::BLST_SUCCESS { return false; @@ -79,8 +75,8 @@ impl ThresholdSignature { true } - pub(crate) fn verify(&self, msg: &[u8], params: &Params) -> bool { - if self.validate_signatures(msg) { + pub(crate) fn verify(&self, msg: &[u8], params: &Params, public_keys: &[PublicKey]) -> bool { + if self.validate_signatures(msg, public_keys) { let alba = CentralizedTelescope::create(params); return alba.verify(&self.proof); } diff --git a/examples/simple_example.rs b/examples/simple_example.rs index 6b1d1425..5ea58e4e 100644 --- a/examples/simple_example.rs +++ b/examples/simple_example.rs @@ -6,12 +6,12 @@ use crate::simple_aggregate_signature::signature::Signature; use crate::simple_aggregate_signature::signer::Signer; use crate::simple_aggregate_signature::threshold_signature::ThresholdSignature; use alba::centralized_telescope::params::Params; +use blst::min_sig::PublicKey; use rand_chacha::ChaCha20Rng; use rand_core::{RngCore, SeedableRng}; -use std::collections::HashMap; const DATA_LENGTH: usize = 48; -pub(crate) type Element = [u8; DATA_LENGTH]; +type Element = [u8; DATA_LENGTH]; fn main() { let mut rng = ChaCha20Rng::from_seed(Default::default()); @@ -25,15 +25,19 @@ fn main() { lower_bound: 20 * set_size / 100, }; - let mut key_list = HashMap::with_capacity(set_size as usize); + let mut key_list: Vec<(usize, PublicKey)> = Vec::with_capacity(set_size as usize); let mut signature_list: Vec = Vec::with_capacity(set_size as usize); for i in 0..set_size as usize { let signer = Signer::new(&mut rng); - key_list.insert(i, signer.verification_key); + key_list.push((i, signer.verification_key)); signature_list.push(signer.sign(&msg, i)); } - let threshold_signature = ThresholdSignature::aggregate(&signature_list, ¶ms, &key_list); + let (threshold_signature, public_keys) = + ThresholdSignature::aggregate(&signature_list, ¶ms, &key_list); - print!("{:?}", threshold_signature.verify(&msg, ¶ms)); + print!( + "{:?}", + threshold_signature.verify(&msg, ¶ms, &public_keys) + ); } From 63503c70b52b73fc12aa790f58fdee0c1e5389f6 Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Thu, 16 Jan 2025 21:05:38 +0300 Subject: [PATCH 17/24] some improvements --- examples/simple_example.rs | 8 +++---- .../mod.rs | 0 .../signature.rs | 0 .../signer.rs | 2 +- .../threshold_signature.rs | 23 +++++++------------ 5 files changed, 13 insertions(+), 20 deletions(-) rename examples/{simple_aggregate_signature => simple_threshold_signature}/mod.rs (100%) rename examples/{simple_aggregate_signature => simple_threshold_signature}/signature.rs (100%) rename examples/{simple_aggregate_signature => simple_threshold_signature}/signer.rs (92%) rename examples/{simple_aggregate_signature => simple_threshold_signature}/threshold_signature.rs (77%) diff --git a/examples/simple_example.rs b/examples/simple_example.rs index 5ea58e4e..9162b2e3 100644 --- a/examples/simple_example.rs +++ b/examples/simple_example.rs @@ -1,10 +1,10 @@ //! Centralized Telescope example with BLS signatures -mod simple_aggregate_signature; +mod simple_threshold_signature; -use crate::simple_aggregate_signature::signature::Signature; -use crate::simple_aggregate_signature::signer::Signer; -use crate::simple_aggregate_signature::threshold_signature::ThresholdSignature; +use crate::simple_threshold_signature::signature::Signature; +use crate::simple_threshold_signature::signer::Signer; +use crate::simple_threshold_signature::threshold_signature::ThresholdSignature; use alba::centralized_telescope::params::Params; use blst::min_sig::PublicKey; use rand_chacha::ChaCha20Rng; diff --git a/examples/simple_aggregate_signature/mod.rs b/examples/simple_threshold_signature/mod.rs similarity index 100% rename from examples/simple_aggregate_signature/mod.rs rename to examples/simple_threshold_signature/mod.rs diff --git a/examples/simple_aggregate_signature/signature.rs b/examples/simple_threshold_signature/signature.rs similarity index 100% rename from examples/simple_aggregate_signature/signature.rs rename to examples/simple_threshold_signature/signature.rs diff --git a/examples/simple_aggregate_signature/signer.rs b/examples/simple_threshold_signature/signer.rs similarity index 92% rename from examples/simple_aggregate_signature/signer.rs rename to examples/simple_threshold_signature/signer.rs index 1dad6b99..35a48fec 100644 --- a/examples/simple_aggregate_signature/signer.rs +++ b/examples/simple_threshold_signature/signer.rs @@ -1,4 +1,4 @@ -use crate::simple_aggregate_signature::signature::Signature; +use crate::simple_threshold_signature::signature::Signature; use blst::min_sig::{PublicKey, SecretKey}; use rand_core::{CryptoRng, RngCore}; diff --git a/examples/simple_aggregate_signature/threshold_signature.rs b/examples/simple_threshold_signature/threshold_signature.rs similarity index 77% rename from examples/simple_aggregate_signature/threshold_signature.rs rename to examples/simple_threshold_signature/threshold_signature.rs index e2e0b64c..7af1af50 100644 --- a/examples/simple_aggregate_signature/threshold_signature.rs +++ b/examples/simple_threshold_signature/threshold_signature.rs @@ -1,4 +1,4 @@ -use crate::simple_aggregate_signature::signature::Signature; +use crate::simple_threshold_signature::signature::Signature; use crate::Element; use alba::centralized_telescope::params::Params; use alba::centralized_telescope::proof::Proof; @@ -12,39 +12,32 @@ pub(crate) struct ThresholdSignature { impl ThresholdSignature { pub(crate) fn aggregate( - alba_signatures: &[Signature], + signatures: &[Signature], params: &Params, key_list: &[(usize, PublicKey)], ) -> (Self, Vec) { - let prover_set = alba_signatures + let prover_set = signatures .iter() .map(|s| s.signature.to_bytes()) .collect::>(); let alba = CentralizedTelescope::create(params); let proof = alba.prove(&prover_set).unwrap(); - let proof_elements = proof.element_sequence.clone(); - let proof_signatures = proof_elements + let proof_signatures: Vec = proof + .element_sequence .iter() - .map(|element| BLSSignature::from_bytes(element).unwrap()) - .collect::>(); + .filter_map(|element| BLSSignature::from_bytes(element).ok()) + .collect(); let mut public_keys = Vec::with_capacity(proof_signatures.len()); for sig in &proof_signatures { - // Find the index of the signature in `alba_signatures` - if let Some(signature_entry) = - alba_signatures.iter().find(|entry| entry.signature == *sig) - { + if let Some(signature_entry) = signatures.iter().find(|entry| entry.signature == *sig) { if let Some((_, public_key)) = key_list .iter() .find(|entry| entry.0 == signature_entry.index) { public_keys.push(*public_key); - } else { - panic!("Public key not found for index: {}", signature_entry.index); } - } else { - panic!("Signature not found in alba_signatures: {:?}", sig); } } (Self { proof }, public_keys) From b36c5bae0c57b95960fbf2f32fbe6152a9a220c2 Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Thu, 16 Jan 2025 21:12:41 +0300 Subject: [PATCH 18/24] change params for main function --- examples/simple_example.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/simple_example.rs b/examples/simple_example.rs index 9162b2e3..6ac87506 100644 --- a/examples/simple_example.rs +++ b/examples/simple_example.rs @@ -19,8 +19,8 @@ fn main() { rng.fill_bytes(&mut msg); let set_size = 1000; let params = Params { - soundness_param: 10.0, - completeness_param: 10.0, + soundness_param: 128.0, + completeness_param: 128.0, set_size: 80 * set_size / 100, lower_bound: 20 * set_size / 100, }; From f6e84f24949478eed9cebc8a12929dae518a9157 Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Tue, 21 Jan 2025 17:30:29 +0300 Subject: [PATCH 19/24] new structure adjustments --- examples/simple_example.rs | 19 +++++++++---------- .../threshold_signature.rs | 9 +++------ 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/examples/simple_example.rs b/examples/simple_example.rs index 6ac87506..6b3cbcbd 100644 --- a/examples/simple_example.rs +++ b/examples/simple_example.rs @@ -5,7 +5,7 @@ mod simple_threshold_signature; use crate::simple_threshold_signature::signature::Signature; use crate::simple_threshold_signature::signer::Signer; use crate::simple_threshold_signature::threshold_signature::ThresholdSignature; -use alba::centralized_telescope::params::Params; +use alba::centralized_telescope::Telescope; use blst::min_sig::PublicKey; use rand_chacha::ChaCha20Rng; use rand_core::{RngCore, SeedableRng}; @@ -17,13 +17,12 @@ fn main() { let mut rng = ChaCha20Rng::from_seed(Default::default()); let mut msg = [0u8; 16]; rng.fill_bytes(&mut msg); - let set_size = 1000; - let params = Params { - soundness_param: 128.0, - completeness_param: 128.0, - set_size: 80 * set_size / 100, - lower_bound: 20 * set_size / 100, - }; + let nb_elements: u64 = 1_000; + let soundness_param = 128.0; + let completeness_param = 128.0; + let set_size = nb_elements.saturating_mul(80).div_ceil(100); + let lower_bound = nb_elements.saturating_mul(20).div_ceil(100); + let alba = Telescope::create(soundness_param, completeness_param, set_size, lower_bound); let mut key_list: Vec<(usize, PublicKey)> = Vec::with_capacity(set_size as usize); let mut signature_list: Vec = Vec::with_capacity(set_size as usize); @@ -34,10 +33,10 @@ fn main() { signature_list.push(signer.sign(&msg, i)); } let (threshold_signature, public_keys) = - ThresholdSignature::aggregate(&signature_list, ¶ms, &key_list); + ThresholdSignature::aggregate(&signature_list, &alba, &key_list); print!( "{:?}", - threshold_signature.verify(&msg, ¶ms, &public_keys) + threshold_signature.verify(&msg, &alba, &public_keys) ); } diff --git a/examples/simple_threshold_signature/threshold_signature.rs b/examples/simple_threshold_signature/threshold_signature.rs index 7af1af50..fbc5fdef 100644 --- a/examples/simple_threshold_signature/threshold_signature.rs +++ b/examples/simple_threshold_signature/threshold_signature.rs @@ -1,8 +1,7 @@ use crate::simple_threshold_signature::signature::Signature; use crate::Element; -use alba::centralized_telescope::params::Params; use alba::centralized_telescope::proof::Proof; -use alba::centralized_telescope::CentralizedTelescope; +use alba::centralized_telescope::Telescope; use blst::min_sig::{PublicKey, Signature as BLSSignature}; use blst::BLST_ERROR; @@ -13,14 +12,13 @@ pub(crate) struct ThresholdSignature { impl ThresholdSignature { pub(crate) fn aggregate( signatures: &[Signature], - params: &Params, + alba: &Telescope, key_list: &[(usize, PublicKey)], ) -> (Self, Vec) { let prover_set = signatures .iter() .map(|s| s.signature.to_bytes()) .collect::>(); - let alba = CentralizedTelescope::create(params); let proof = alba.prove(&prover_set).unwrap(); let proof_signatures: Vec = proof @@ -68,9 +66,8 @@ impl ThresholdSignature { true } - pub(crate) fn verify(&self, msg: &[u8], params: &Params, public_keys: &[PublicKey]) -> bool { + pub(crate) fn verify(&self, msg: &[u8], alba: &Telescope, public_keys: &[PublicKey]) -> bool { if self.validate_signatures(msg, public_keys) { - let alba = CentralizedTelescope::create(params); return alba.verify(&self.proof); } false From c95f1fe45488a6242639ff213992bc05f4a44e2e Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Tue, 21 Jan 2025 19:00:03 +0300 Subject: [PATCH 20/24] revision --- examples/simple_example.rs | 30 ++++++++++++++++--- .../threshold_signature.rs | 14 +++++++++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/examples/simple_example.rs b/examples/simple_example.rs index 6b3cbcbd..f1d47cb1 100644 --- a/examples/simple_example.rs +++ b/examples/simple_example.rs @@ -17,11 +17,21 @@ fn main() { let mut rng = ChaCha20Rng::from_seed(Default::default()); let mut msg = [0u8; 16]; rng.fill_bytes(&mut msg); + + println!("\n-------------- ALBA with Multi-Signature ---------------"); + println!("--------------------------------------------------------"); + let nb_elements: u64 = 1_000; let soundness_param = 128.0; let completeness_param = 128.0; let set_size = nb_elements.saturating_mul(80).div_ceil(100); let lower_bound = nb_elements.saturating_mul(20).div_ceil(100); + + println!(" - Soundness parameter: {soundness_param}"); + println!(" - Completeness parameter: {completeness_param}"); + println!(" - Prover set size: {set_size}"); + println!(" - Lower bound: {lower_bound}"); + let alba = Telescope::create(soundness_param, completeness_param, set_size, lower_bound); let mut key_list: Vec<(usize, PublicKey)> = Vec::with_capacity(set_size as usize); @@ -32,11 +42,23 @@ fn main() { key_list.push((i, signer.verification_key)); signature_list.push(signer.sign(&msg, i)); } + println!("--------------------------------------------------------"); + println!(" -- {set_size} (sk, pk) are generated."); + println!(" -- {set_size} signatures are generated."); + + println!("--------------------------------------------------------"); + println!("----------- Generating Alba multi-signature. -----------"); let (threshold_signature, public_keys) = ThresholdSignature::aggregate(&signature_list, &alba, &key_list); - print!( - "{:?}", - threshold_signature.verify(&msg, &alba, &public_keys) - ); + println!("-- Alba multi-signature is generated."); + println!("--------------------------------------------------------"); + println!("----------- Verifying Alba multi-signature. ------------"); + + if threshold_signature.verify(&msg, &alba, &public_keys) { + println!("-- Verification successful."); + } else { + println!("-- Verification failed."); + } + println!("--------------------------------------------------------"); } diff --git a/examples/simple_threshold_signature/threshold_signature.rs b/examples/simple_threshold_signature/threshold_signature.rs index fbc5fdef..9e1f912c 100644 --- a/examples/simple_threshold_signature/threshold_signature.rs +++ b/examples/simple_threshold_signature/threshold_signature.rs @@ -19,7 +19,21 @@ impl ThresholdSignature { .iter() .map(|s| s.signature.to_bytes()) .collect::>(); + println!("-- Creating alba proof. "); let proof = alba.prove(&prover_set).unwrap(); + println!("-- Alba proof created: "); + println!( + " - Numbers of retries done to find the proof: {}", + proof.retry_counter + ); + println!( + " - Index of the searched subtree to find the proof: {}", + proof.search_counter + ); + println!( + " - Number of elements in the proof sequence: {}", + proof.element_sequence.len() + ); let proof_signatures: Vec = proof .element_sequence From 1f604d3324b2655b153859b3ad21fec166fb78bc Mon Sep 17 00:00:00 2001 From: curiecrypt <36852463+curiecrypt@users.noreply.github.com> Date: Wed, 22 Jan 2025 18:41:40 +0300 Subject: [PATCH 21/24] Update examples/simple_threshold_signature/threshold_signature.rs Co-authored-by: Tolik Zinovyev --- examples/simple_threshold_signature/threshold_signature.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/simple_threshold_signature/threshold_signature.rs b/examples/simple_threshold_signature/threshold_signature.rs index 9e1f912c..9499d806 100644 --- a/examples/simple_threshold_signature/threshold_signature.rs +++ b/examples/simple_threshold_signature/threshold_signature.rs @@ -81,9 +81,6 @@ impl ThresholdSignature { } pub(crate) fn verify(&self, msg: &[u8], alba: &Telescope, public_keys: &[PublicKey]) -> bool { - if self.validate_signatures(msg, public_keys) { - return alba.verify(&self.proof); - } - false + self.validate_signatures(msg, public_keys) && alba.verify(&self.proof) } } From b7f71f980e75b8f4cbeb49fd9afeb89683fb2947 Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Wed, 22 Jan 2025 18:56:35 +0300 Subject: [PATCH 22/24] sent all public keys to verification --- examples/simple_example.rs | 10 ++--- .../simple_threshold_signature/signature.rs | 4 +- .../threshold_signature.rs | 44 +++++++++++++------ 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/examples/simple_example.rs b/examples/simple_example.rs index f1d47cb1..9aae108a 100644 --- a/examples/simple_example.rs +++ b/examples/simple_example.rs @@ -34,12 +34,12 @@ fn main() { let alba = Telescope::create(soundness_param, completeness_param, set_size, lower_bound); - let mut key_list: Vec<(usize, PublicKey)> = Vec::with_capacity(set_size as usize); + let mut public_key_list: Vec<(usize, PublicKey)> = Vec::with_capacity(set_size as usize); let mut signature_list: Vec = Vec::with_capacity(set_size as usize); for i in 0..set_size as usize { let signer = Signer::new(&mut rng); - key_list.push((i, signer.verification_key)); + public_key_list.push((i, signer.verification_key)); signature_list.push(signer.sign(&msg, i)); } println!("--------------------------------------------------------"); @@ -48,14 +48,14 @@ fn main() { println!("--------------------------------------------------------"); println!("----------- Generating Alba multi-signature. -----------"); - let (threshold_signature, public_keys) = - ThresholdSignature::aggregate(&signature_list, &alba, &key_list); + let (threshold_signature, indices) = + ThresholdSignature::aggregate(&signature_list, &alba, &public_key_list); println!("-- Alba multi-signature is generated."); println!("--------------------------------------------------------"); println!("----------- Verifying Alba multi-signature. ------------"); - if threshold_signature.verify(&msg, &alba, &public_keys) { + if threshold_signature.verify(&msg, &alba, &public_key_list, &indices) { println!("-- Verification successful."); } else { println!("-- Verification failed."); diff --git a/examples/simple_threshold_signature/signature.rs b/examples/simple_threshold_signature/signature.rs index 2ed519d2..9f46a298 100644 --- a/examples/simple_threshold_signature/signature.rs +++ b/examples/simple_threshold_signature/signature.rs @@ -1,10 +1,10 @@ -use blst::min_sig::Signature as BLSSignature; +use blst::min_sig::Signature as BlsSignature; /// Single signature #[derive(Debug, Clone)] pub(crate) struct Signature { /// Signature of type bls signature - pub(crate) signature: BLSSignature, + pub(crate) signature: BlsSignature, /// Verification index of the signer pub(crate) index: usize, } diff --git a/examples/simple_threshold_signature/threshold_signature.rs b/examples/simple_threshold_signature/threshold_signature.rs index 9499d806..7d4a234e 100644 --- a/examples/simple_threshold_signature/threshold_signature.rs +++ b/examples/simple_threshold_signature/threshold_signature.rs @@ -13,8 +13,8 @@ impl ThresholdSignature { pub(crate) fn aggregate( signatures: &[Signature], alba: &Telescope, - key_list: &[(usize, PublicKey)], - ) -> (Self, Vec) { + public_key_list: &[(usize, PublicKey)], + ) -> (Self, Vec) { let prover_set = signatures .iter() .map(|s| s.signature.to_bytes()) @@ -41,18 +41,18 @@ impl ThresholdSignature { .filter_map(|element| BLSSignature::from_bytes(element).ok()) .collect(); - let mut public_keys = Vec::with_capacity(proof_signatures.len()); + let mut indices = Vec::with_capacity(proof_signatures.len()); for sig in &proof_signatures { if let Some(signature_entry) = signatures.iter().find(|entry| entry.signature == *sig) { - if let Some((_, public_key)) = key_list + if public_key_list .iter() - .find(|entry| entry.0 == signature_entry.index) + .any(|entry| entry.0 == signature_entry.index) { - public_keys.push(*public_key); + indices.push(signature_entry.index); } } } - (Self { proof }, public_keys) + (Self { proof }, indices) } /// Validates individual signatures in the threshold signature @@ -62,7 +62,12 @@ impl ThresholdSignature { /// - Aggregate public keys with: `AggregatePublicKey::aggregate`, /// - Convert aggregate signature to a signature and aggregate public key to a public key /// - Verify the signature with public key against given message. - fn validate_signatures(&self, msg: &[u8], public_keys: &[PublicKey]) -> bool { + fn validate_signatures( + &self, + msg: &[u8], + public_key_list: &[(usize, PublicKey)], + indices: &[usize], + ) -> bool { let mut signatures = Vec::with_capacity(self.proof.element_sequence.len()); for sig_bytes in &self.proof.element_sequence { let Ok(signature) = BLSSignature::from_bytes(sig_bytes.as_slice()) else { @@ -70,17 +75,28 @@ impl ThresholdSignature { }; signatures.push(signature); } - for (i, signature) in signatures.iter().enumerate() { - if signature.verify(false, msg, &[], &[], &public_keys[i], false) - != BLST_ERROR::BLST_SUCCESS - { + + for (signature, &index) in signatures.iter().zip(indices.iter()) { + if let Some((_, public_key)) = public_key_list.iter().find(|(idx, _)| *idx == index) { + if signature.verify(false, msg, &[], &[], public_key, false) + != BLST_ERROR::BLST_SUCCESS + { + return false; + } + } else { return false; } } true } - pub(crate) fn verify(&self, msg: &[u8], alba: &Telescope, public_keys: &[PublicKey]) -> bool { - self.validate_signatures(msg, public_keys) && alba.verify(&self.proof) + pub(crate) fn verify( + &self, + msg: &[u8], + alba: &Telescope, + public_key_list: &[(usize, PublicKey)], + indices: &[usize], + ) -> bool { + self.validate_signatures(msg, public_key_list, indices) && alba.verify(&self.proof) } } From cb2bd3db845355a54fca0ab165f88d7d34d0085e Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Wed, 22 Jan 2025 19:09:46 +0300 Subject: [PATCH 23/24] more comments on functions --- examples/simple_threshold_signature/signer.rs | 2 ++ .../threshold_signature.rs | 20 +++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/examples/simple_threshold_signature/signer.rs b/examples/simple_threshold_signature/signer.rs index 35a48fec..d3a9832e 100644 --- a/examples/simple_threshold_signature/signer.rs +++ b/examples/simple_threshold_signature/signer.rs @@ -8,6 +8,7 @@ pub(crate) struct Signer { } impl Signer { + /// Create a pair of bls signing key and verification key pub(crate) fn new(rng: &mut (impl RngCore + CryptoRng)) -> Self { let mut ikm = [0u8; 32]; rng.fill_bytes(&mut ikm); @@ -20,6 +21,7 @@ impl Signer { } } + /// Sign given message. Return the signature and given signer index. pub(crate) fn sign(&self, msg: &[u8], index: usize) -> Signature { Signature { signature: self.signing_key.sign(msg, &[], &[]), diff --git a/examples/simple_threshold_signature/threshold_signature.rs b/examples/simple_threshold_signature/threshold_signature.rs index 7d4a234e..601ad872 100644 --- a/examples/simple_threshold_signature/threshold_signature.rs +++ b/examples/simple_threshold_signature/threshold_signature.rs @@ -2,7 +2,7 @@ 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::min_sig::{PublicKey, Signature as BlsSignature}; use blst::BLST_ERROR; pub(crate) struct ThresholdSignature { @@ -10,16 +10,22 @@ pub(crate) struct ThresholdSignature { } impl ThresholdSignature { + // Create the Alba proof. Convert signatures to bytes and use them as the prover set. Create Alba proof with the + // prover set. Collect signatures by converting proof elements to bls signatures. Find each signature's index and + // collect them in a list. Return alba proof and the indices. pub(crate) fn aggregate( signatures: &[Signature], alba: &Telescope, 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::>(); + println!("-- Creating alba proof. "); + // Create alba proof with the prover set let proof = alba.prove(&prover_set).unwrap(); println!("-- Alba proof created: "); println!( @@ -35,12 +41,14 @@ impl ThresholdSignature { proof.element_sequence.len() ); - let proof_signatures: Vec = proof + // Convert proof elements to signatures to obtain their indexes + let proof_signatures: Vec = proof .element_sequence .iter() - .filter_map(|element| BLSSignature::from_bytes(element).ok()) + .filter_map(|element| BlsSignature::from_bytes(element).ok()) .collect(); + // Collect the indices of the signatures that create alba proof. let mut indices = Vec::with_capacity(proof_signatures.len()); for sig in &proof_signatures { if let Some(signature_entry) = signatures.iter().find(|entry| entry.signature == *sig) { @@ -69,13 +77,16 @@ impl ThresholdSignature { indices: &[usize], ) -> bool { let mut signatures = Vec::with_capacity(self.proof.element_sequence.len()); + // Get the bls signatures from byte representation for sig_bytes in &self.proof.element_sequence { - let Ok(signature) = BLSSignature::from_bytes(sig_bytes.as_slice()) else { + let Ok(signature) = BlsSignature::from_bytes(sig_bytes.as_slice()) else { return false; }; signatures.push(signature); } + // Find the public key from the public key lest for the corresponding index (and signature) + // Verify the signature with this public key against given message. for (signature, &index) in signatures.iter().zip(indices.iter()) { if let Some((_, public_key)) = public_key_list.iter().find(|(idx, _)| *idx == index) { if signature.verify(false, msg, &[], &[], public_key, false) @@ -90,6 +101,7 @@ impl ThresholdSignature { true } + /// Verify `ThresholdSignature` by validating the signatures included in alba proof and verifying the alba proof. pub(crate) fn verify( &self, msg: &[u8], From d21df97c03fa134713603648acb71ca886f87c76 Mon Sep 17 00:00:00 2001 From: curiecrypt Date: Wed, 22 Jan 2025 19:39:06 +0300 Subject: [PATCH 24/24] nbelements signers --- examples/simple_example.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/examples/simple_example.rs b/examples/simple_example.rs index 9aae108a..3aef04b2 100644 --- a/examples/simple_example.rs +++ b/examples/simple_example.rs @@ -21,6 +21,7 @@ fn main() { println!("\n-------------- ALBA with Multi-Signature ---------------"); println!("--------------------------------------------------------"); + // Define telescope parameters let nb_elements: u64 = 1_000; let soundness_param = 128.0; let completeness_param = 128.0; @@ -32,25 +33,28 @@ fn main() { println!(" - Prover set size: {set_size}"); println!(" - Lower bound: {lower_bound}"); + // Create the telescope structure let alba = Telescope::create(soundness_param, completeness_param, set_size, lower_bound); - let mut public_key_list: Vec<(usize, PublicKey)> = Vec::with_capacity(set_size as usize); + let mut public_key_list: Vec<(usize, PublicKey)> = Vec::with_capacity(nb_elements as usize); let mut signature_list: Vec = Vec::with_capacity(set_size as usize); - for i in 0..set_size as usize { + // Generate `nb_elements` signers and `set_size` signatures + for i in 0..nb_elements as usize { let signer = Signer::new(&mut rng); public_key_list.push((i, signer.verification_key)); - signature_list.push(signer.sign(&msg, i)); + if i < set_size as usize { + signature_list.push(signer.sign(&msg, i)); + } } println!("--------------------------------------------------------"); - println!(" -- {set_size} (sk, pk) are generated."); + println!(" -- {nb_elements} (sk, pk) are generated."); println!(" -- {set_size} signatures are generated."); println!("--------------------------------------------------------"); println!("----------- Generating Alba multi-signature. -----------"); let (threshold_signature, indices) = ThresholdSignature::aggregate(&signature_list, &alba, &public_key_list); - println!("-- Alba multi-signature is generated."); println!("--------------------------------------------------------"); println!("----------- Verifying Alba multi-signature. ------------");