-
Notifications
You must be signed in to change notification settings - Fork 8
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
Defne public interface for distributed schnorr signature scheme #71
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1 @@ | ||
pub mod multi_party_schnorr; | ||
|
||
#[cfg(test)] | ||
mod test_multi_party_schnorr; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<PublicKey>, | ||
threshold: usize, | ||
) -> HashSet<NodeVSS, RandomState> { | ||
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<NodeVSS, RandomState>) -> NodeShare { | ||
NodeShare { | ||
aggregated_pubkey: random_pubkey(), | ||
secret_share: random_secret(), | ||
} | ||
} | ||
} | ||
|
||
impl SignatureIssuingProtocol for MockImpl { | ||
fn create_block_vss( | ||
signer_keys: &Vec<PublicKey>, | ||
threshold: usize, | ||
) -> HashSet<BlockVSS, RandomState> { | ||
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<BlockVSS, RandomState>) -> BlockShare { | ||
BlockShare { | ||
aggregated_pubkey: random_pubkey(), | ||
positive_secret_share: random_secret(), | ||
negative_secret_share: random_secret(), | ||
} | ||
} | ||
|
||
fn create_local_sig( | ||
message: &[u8; 32], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use Message type. |
||
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<NodeVSS, RandomState>, | ||
block_vss_set: &HashSet<BlockVSS, RandomState>, | ||
) -> Result<(), Error> { | ||
Ok(()) | ||
} | ||
|
||
fn compute_final_signature( | ||
local_sigs: &HashSet<LocalSig, RandomState>, | ||
threshold: usize, | ||
) -> Result<Signature, Error> { | ||
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::<Vec<PublicKey>>(); | ||
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); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
use secp256k1::{constants, SecretKey}; | ||
use std::ops::Deref; | ||
|
||
pub enum Error { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why define these errors here, not in errors.rs? |
||
VerifyVSS, | ||
VerifyLocalSig, | ||
} | ||
|
||
pub type Message = [u8; 32]; | ||
|
||
#[derive(Clone, Debug, PartialEq, Eq, Hash)] | ||
pub struct Secret([u8; 32]); | ||
|
||
impl From<SecretKey> 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<PublicKey>, | ||
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( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I prefer the return type of these functions is Result<...., Error> even if it does not return error now. |
||
node_private_key: &SecretKey, | ||
signer_keys: &Vec<PublicKey>, | ||
threshold: usize, | ||
) -> HashSet<NodeVSS>; | ||
fn verify_node_vss(vss: &NodeVSS) -> Result<(), Error>; | ||
fn aggregate_node_vss(vss_set: &HashSet<NodeVSS>) -> NodeShare; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should return Result<NodeShare, Error> |
||
} | ||
} | ||
|
||
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<PublicKey>, | ||
pub positive_secret: Secret, | ||
pub negative_commitments: Vec<PublicKey>, | ||
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<PublicKey>, threshold: usize) -> HashSet<BlockVSS>; | ||
fn verify_block_vss(vss: &BlockVSS) -> Result<(), Error>; | ||
fn aggregate_block_vss(vss_set: &HashSet<BlockVSS>) -> 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<NodeVSS>, | ||
block_vss_set: &HashSet<BlockVSS>, | ||
) -> Result<(), Error>; | ||
fn compute_final_signature( | ||
local_sigs: &HashSet<LocalSig>, | ||
threshold: usize, | ||
) -> Result<Signature, Error>; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't have confidence whether the arguments are enough or not. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It need to have signer index to calculate Lagrange interpolation. I will add it into LocalSig. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To compute Signatre.r_x, a set of BlockVSS is needed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's true. I will add it. |
||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This struct should be public.