diff --git a/src/crypto/mod.rs b/src/crypto/mod.rs index 9ca5fdeab..f63edc39b 100644 --- a/src/crypto/mod.rs +++ b/src/crypto/mod.rs @@ -1,4 +1 @@ pub mod multi_party_schnorr; - -#[cfg(test)] -mod test_multi_party_schnorr; diff --git a/src/crypto/multi_party_schnorr/mock_impl.rs b/src/crypto/multi_party_schnorr/mock_impl.rs new file mode 100644 index 000000000..9722743d0 --- /dev/null +++ b/src/crypto/multi_party_schnorr/mock_impl.rs @@ -0,0 +1,157 @@ +use crate::crypto::multi_party_schnorr::traits::key_generation_protocol::{ + KeyGenerationProtocol, NodeShare, NodeVSS, +}; +use crate::crypto::multi_party_schnorr::traits::signature_issuing_protocol::{ + BlockShare, BlockVSS, LocalSig, SignatureIssuingProtocol, +}; +use crate::crypto::multi_party_schnorr::traits::{Error, Secret, Signature}; +use secp256k1::rand::prelude::ThreadRng; +use secp256k1::rand::thread_rng; +use secp256k1::{PublicKey, SecretKey}; +use std::collections::hash_map::RandomState; +use std::collections::HashSet; +use std::str::FromStr; + +struct MockImpl; + +fn random_pubkey() -> PublicKey { + let secp = secp256k1::Secp256k1::new(); + PublicKey::from_secret_key(&secp, &SecretKey::new(&mut thread_rng())) +} + +fn random_secret() -> Secret { + Secret::from(SecretKey::new(&mut thread_rng())) +} + +impl KeyGenerationProtocol for MockImpl { + fn create_node_vss( + node_private_key: &SecretKey, + signer_keys: &Vec, + threshold: usize, + ) -> HashSet { + let vss = NodeVSS { + sender_pubkey: random_pubkey(), + receiver_pubkey: random_pubkey(), + commitments: vec![], + secret: random_secret(), + }; + let mut set = HashSet::new(); + set.insert(vss); + set + } + + fn verify_node_vss(vss: &NodeVSS) -> Result<(), Error> { + Ok(()) + } + + fn aggregate_node_vss(vss_set: &HashSet) -> NodeShare { + NodeShare { + aggregated_pubkey: random_pubkey(), + secret_share: random_secret(), + } + } +} + +impl SignatureIssuingProtocol for MockImpl { + fn create_block_vss( + signer_keys: &Vec, + threshold: usize, + ) -> HashSet { + let vss = BlockVSS { + sender_pubkey: random_pubkey(), + receiver_pubkey: random_pubkey(), + positive_commitments: vec![], + positive_secret: random_secret(), + negative_commitments: vec![], + negative_secret: random_secret(), + }; + let mut set = HashSet::new(); + set.insert(vss); + set + } + + fn verify_block_vss(vss: &BlockVSS) -> Result<(), Error> { + Ok(()) + } + + fn aggregate_block_vss(vss_set: &HashSet) -> BlockShare { + BlockShare { + aggregated_pubkey: random_pubkey(), + positive_secret_share: random_secret(), + negative_secret_share: random_secret(), + } + } + + fn create_local_sig( + message: &[u8; 32], + node_share: &NodeShare, + block_share: &BlockShare, + ) -> LocalSig { + LocalSig { + signer_pubkey: random_pubkey(), + gamma_i: random_secret(), + } + } + + fn verify_local_sig( + local_sig: &LocalSig, + node_vss_set: &HashSet, + block_vss_set: &HashSet, + ) -> Result<(), Error> { + Ok(()) + } + + fn compute_final_signature( + local_sigs: &HashSet, + threshold: usize, + ) -> Result { + Ok(Signature { + r_x: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + ], + sigma: [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + ], + }) + } +} + +#[cfg(test)] +mod tests { + use crate::crypto::multi_party_schnorr::mock_impl::MockImpl; + use crate::crypto::multi_party_schnorr::traits::key_generation_protocol::KeyGenerationProtocol; + use crate::crypto::multi_party_schnorr::traits::signature_issuing_protocol::SignatureIssuingProtocol; + use crate::tests::helper::keys::TEST_KEYS; + use secp256k1::PublicKey; + use std::collections::HashSet; + + #[test] + fn test() { + let signer_keys = TEST_KEYS + .pubkeys() + .into_iter() + .map(|i| i.key) + .collect::>(); + let node_vss_set = MockImpl::create_node_vss(&TEST_KEYS.key[0].key, &signer_keys, 3); + for vss in node_vss_set.iter() { + MockImpl::verify_node_vss(vss); + } + let node_share = MockImpl::aggregate_node_vss(&node_vss_set); + + let block_vss_set = MockImpl::create_block_vss(&signer_keys, 3); + for vss in block_vss_set.iter() { + MockImpl::verify_block_vss(vss); + } + let block_share = MockImpl::aggregate_block_vss(&block_vss_set); + let message = [0u8; 32]; + let local_sig = MockImpl::create_local_sig(&message, &node_share, &block_share); + MockImpl::verify_local_sig(&local_sig, &node_vss_set, &block_vss_set); + let mut local_sigs = HashSet::new(); + local_sigs.insert(local_sig); + MockImpl::compute_final_signature(&local_sigs, 3); + } +} diff --git a/src/crypto/multi_party_schnorr.rs b/src/crypto/multi_party_schnorr/mod.rs similarity index 99% rename from src/crypto/multi_party_schnorr.rs rename to src/crypto/multi_party_schnorr/mod.rs index c20933725..b95358975 100644 --- a/src/crypto/multi_party_schnorr.rs +++ b/src/crypto/multi_party_schnorr/mod.rs @@ -27,6 +27,9 @@ use curv::cryptographic_primitives::secret_sharing::feldman_vss::VerifiableSS; use curv::{BigInt, FE, GE}; use sha2::{Digest, Sha256}; +pub mod mock_impl; +pub mod traits; + const SECURITY: usize = 256; pub struct Keys { @@ -348,3 +351,6 @@ mod tests { assert_eq!(expected, compute_e(&v, &y, &message[..])); } } + +#[cfg(test)] +mod test; diff --git a/src/crypto/test_multi_party_schnorr.rs b/src/crypto/multi_party_schnorr/test.rs similarity index 100% rename from src/crypto/test_multi_party_schnorr.rs rename to src/crypto/multi_party_schnorr/test.rs diff --git a/src/crypto/multi_party_schnorr/traits.rs b/src/crypto/multi_party_schnorr/traits.rs new file mode 100644 index 000000000..bd8296cfa --- /dev/null +++ b/src/crypto/multi_party_schnorr/traits.rs @@ -0,0 +1,116 @@ +use secp256k1::{constants, SecretKey}; +use std::ops::Deref; + +pub enum Error { + VerifyVSS, + VerifyLocalSig, +} + +pub type Message = [u8; 32]; + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct Secret([u8; 32]); + +impl From for Secret { + fn from(seckey: SecretKey) -> Self { + let mut data = [0u8; constants::SECRET_KEY_SIZE]; + data.copy_from_slice(&seckey[..]); + Secret(data) + } +} + +/// The schnorr signature what the distributed signing scheme produce finally +pub struct Signature { + /// R.x + pub r_x: [u8; 32], + /// sigma + pub sigma: [u8; 32], +} + +pub mod key_generation_protocol { + use crate::crypto::multi_party_schnorr::traits::{Error, Secret}; + use secp256k1::{PublicKey, SecretKey}; + use std::collections::HashSet; + + #[derive(Clone, Debug, PartialEq, Eq, Hash)] + pub struct NodeVSS { + pub sender_pubkey: PublicKey, + pub receiver_pubkey: PublicKey, + pub commitments: Vec, + pub secret: Secret, + } + + /// Struct for a shared secret and an aggregated public key + #[derive(Clone, Debug)] + pub struct NodeShare { + /// Aggregated Public Key + pub aggregated_pubkey: PublicKey, + /// Secret share for a signer + pub secret_share: Secret, + } + + pub trait KeyGenerationProtocol { + fn create_node_vss( + node_private_key: &SecretKey, + signer_keys: &Vec, + threshold: usize, + ) -> HashSet; + fn verify_node_vss(vss: &NodeVSS) -> Result<(), Error>; + fn aggregate_node_vss(vss_set: &HashSet) -> NodeShare; + } +} + +pub mod signature_issuing_protocol { + use crate::crypto::multi_party_schnorr::traits::key_generation_protocol::{NodeShare, NodeVSS}; + use crate::crypto::multi_party_schnorr::traits::{Error, Message, Secret, Signature}; + use secp256k1::{PublicKey, SecretKey}; + use std::collections::HashSet; + + #[derive(Clone, Debug, PartialEq, Eq, Hash)] + pub struct BlockVSS { + pub sender_pubkey: PublicKey, + pub receiver_pubkey: PublicKey, + pub positive_commitments: Vec, + pub positive_secret: Secret, + pub negative_commitments: Vec, + pub negative_secret: Secret, + } + + /// The Struct for a shared secret and an aggregated public key + #[derive(Clone, Debug)] + pub struct BlockShare { + /// Aggregated Public Key + pub aggregated_pubkey: PublicKey, + /// Secret share for a signer + pub positive_secret_share: Secret, + /// Secret share for a signer + pub negative_secret_share: Secret, + } + + /// The Signature + #[derive(Clone, Debug, PartialEq, Eq, Hash)] + pub struct LocalSig { + pub signer_pubkey: PublicKey, + pub gamma_i: Secret, + } + + pub trait SignatureIssuingProtocol { + fn create_block_vss(signer_keys: &Vec, threshold: usize) -> HashSet; + fn verify_block_vss(vss: &BlockVSS) -> Result<(), Error>; + fn aggregate_block_vss(vss_set: &HashSet) -> BlockShare; + fn create_local_sig( + message: &Message, + node_share: &NodeShare, + block_share: &BlockShare, + ) -> LocalSig; + fn verify_local_sig( + local_sig: &LocalSig, + node_vss_set: &HashSet, + block_vss_set: &HashSet, + ) -> Result<(), Error>; + fn compute_final_signature( + local_sigs: &HashSet, + threshold: usize, + ) -> Result; + } +}