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

Replace ECDSA with Schnorr signature #264

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 2 additions & 2 deletions core/src/account_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use std::fmt;
use std::sync::Arc;

use ckeys::{
public_to_address, ECDSASignature, Error as KeysError, Generator, KeyPair, Message, Private, Public, Random,
public_to_address, Error as KeysError, Generator, KeyPair, Message, Private, Public, Random, SchnorrSignature,
};
use ckeystore::accounts_dir::MemoryDirectory;
use ckeystore::{Error as KeystoreError, KeyStore, SimpleSecretStore};
Expand Down Expand Up @@ -97,7 +97,7 @@ impl AccountProvider {
Ok(address)
}

pub fn sign(&self, address: Address, message: Message) -> Result<ECDSASignature, SignError> {
pub fn sign(&self, address: Address, message: Message) -> Result<SchnorrSignature, SignError> {
let signature = self.keystore.read().sign(&address, "password", &message)?;
Ok(signature)
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/codechain_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl CodeChainMachine {
got: t.fee,
}.into())
}
t.verify_basic(self.params().network_id, false)?;
t.verify_basic(self.params().network_id)?;

Ok(())
}
Expand Down
4 changes: 2 additions & 2 deletions core/src/consensus/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub use self::validator_set::ValidatorSet;
use std::fmt;
use std::sync::{Arc, Weak};

use ckeys::ECDSASignature;
use ckeys::SchnorrSignature;
use cnetwork::NetworkExtension;
use ctypes::{Address, Bytes, H256};
use unexpected::{Mismatch, OutOfBounds};
Expand Down Expand Up @@ -203,7 +203,7 @@ pub trait ConsensusEngine<M: Machine>: Sync + Send {
fn set_signer(&self, _ap: Arc<AccountProvider>, _address: Address) {}

/// Sign using the EngineSigner, to be used for consensus parcel signing.
fn sign(&self, _hash: H256) -> Result<ECDSASignature, Error> {
fn sign(&self, _hash: H256) -> Result<SchnorrSignature, Error> {
unimplemented!()
}

Expand Down
4 changes: 2 additions & 2 deletions core/src/consensus/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

use std::sync::Arc;

use ckeys::ECDSASignature;
use ckeys::SchnorrSignature;
use ctypes::{Address, H256};

use super::super::account_provider::{AccountProvider, SignError};
Expand Down Expand Up @@ -45,7 +45,7 @@ impl EngineSigner {
}

/// Sign a consensus message hash.
pub fn sign(&self, hash: H256) -> Result<ECDSASignature, SignError> {
pub fn sign(&self, hash: H256) -> Result<SchnorrSignature, SignError> {
self.account_provider.sign(self.address.unwrap_or_else(Default::default), hash)
}

Expand Down
12 changes: 6 additions & 6 deletions core/src/consensus/solo_authority.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
use std::sync::{Arc, Weak};

use cjson;
use ckeys::{public_to_address, recover_ecdsa, ECDSASignature};
use ckeys::{public_to_address, recover_schnorr, SchnorrSignature};
use cnetwork::NetworkExtension;
use ctypes::{Address, H256, H520, U256};
use ctypes::{Address, H256, H512, U256};
use parking_lot::RwLock;

use super::super::account_provider::AccountProvider;
Expand Down Expand Up @@ -85,8 +85,8 @@ fn verify_external(header: &Header, validators: &ValidatorSet) -> Result<(), Err
use rlp::UntrustedRlp;

// Check if the signature belongs to a validator, can depend on parent state.
let sig = UntrustedRlp::new(&header.seal()[0]).as_val::<H520>()?;
let signer = public_to_address(&recover_ecdsa(&sig.into(), &header.bare_hash())?);
let sig = UntrustedRlp::new(&header.seal()[0]).as_val::<H512>()?;
let signer = public_to_address(&recover_schnorr(&sig.into(), &header.bare_hash())?);

if *header.author() != signer {
return Err(EngineError::NotAuthorized(header.author().clone()).into())
Expand Down Expand Up @@ -123,7 +123,7 @@ impl ConsensusEngine<CodeChainMachine> for SoloAuthority {
if self.validators.contains(header.parent_hash(), author) {
// account should be permanently unlocked, otherwise sealing will fail
if let Ok(signature) = self.sign(header.bare_hash()) {
return Seal::Regular(vec![::rlp::encode(&(&H520::from(signature) as &[u8])).into_vec()])
return Seal::Regular(vec![::rlp::encode(&(&H512::from(signature) as &[u8])).into_vec()])
} else {
ctrace!(SOLO_AUTHORITY, "generate_seal: FAIL: accounts secret key unavailable");
}
Expand Down Expand Up @@ -201,7 +201,7 @@ impl ConsensusEngine<CodeChainMachine> for SoloAuthority {
self.signer.write().set(ap, address);
}

fn sign(&self, hash: H256) -> Result<ECDSASignature, Error> {
fn sign(&self, hash: H256) -> Result<SchnorrSignature, Error> {
self.signer.read().sign(hash).map_err(Into::into)
}

Expand Down
16 changes: 8 additions & 8 deletions core/src/consensus/tendermint/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
use std::cmp;

use ccrypto::blake256;
use ckeys::{public_to_address, recover_ecdsa};
use ctypes::{Address, Bytes, H256, H520};
use ckeys::{public_to_address, recover_schnorr};
use ctypes::{Address, Bytes, H256, H512};
use rlp::{Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp};

use super::super::super::error::Error;
Expand Down Expand Up @@ -123,11 +123,11 @@ impl Decodable for TendermintMessage {
pub struct ConsensusMessage {
pub vote_step: VoteStep,
pub block_hash: Option<BlockHash>,
pub signature: H520,
pub signature: H512,
}

impl ConsensusMessage {
pub fn new(signature: H520, height: Height, view: View, step: Step, block_hash: Option<BlockHash>) -> Self {
pub fn new(signature: H512, height: Height, view: View, step: Step, block_hash: Option<BlockHash>) -> Self {
ConsensusMessage {
signature,
block_hash,
Expand All @@ -146,7 +146,7 @@ impl ConsensusMessage {
pub fn verify(&self) -> Result<Address, Error> {
let full_rlp = ::rlp::encode(self);
let block_info = ::rlp::Rlp::new(&full_rlp).at(1);
let public_key = recover_ecdsa(&self.signature.into(), &blake256(block_info.as_raw()))?;
let public_key = recover_schnorr(&self.signature.into(), &blake256(block_info.as_raw()))?;
Ok(public_to_address(&public_key))
}
}
Expand All @@ -158,15 +158,15 @@ pub fn consensus_view(header: &Header) -> Result<View, ::rlp::DecoderError> {
}

/// Proposal signature.
pub fn proposal_signature(header: &Header) -> Result<H520, ::rlp::DecoderError> {
pub fn proposal_signature(header: &Header) -> Result<H512, ::rlp::DecoderError> {
UntrustedRlp::new(header.seal().get(1).expect("seal passed basic verification; seal has 3 fields; qed").as_slice())
.as_val()
}

impl Message for ConsensusMessage {
type Round = VoteStep;

fn signature(&self) -> H520 {
fn signature(&self) -> H512 {
self.signature
}

Expand Down Expand Up @@ -215,7 +215,7 @@ pub fn message_info_rlp(vote_step: &VoteStep, block_hash: Option<BlockHash>) ->
s.out()
}

pub fn message_full_rlp(signature: &H520, vote_info: &Bytes) -> Bytes {
pub fn message_full_rlp(signature: &H512, vote_info: &Bytes) -> Bytes {
let mut s = RlpStream::new_list(2);
s.append(signature).append_raw(vote_info, 1);
s.out()
Expand Down
21 changes: 10 additions & 11 deletions core/src/consensus/tendermint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,9 @@ use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering};
use std::sync::{Arc, Weak};

use ccrypto::blake256;
use ckeys::{public_to_address, recover_ecdsa};
use ckeys::{ECDSASignature, Message};
use ckeys::{public_to_address, recover_schnorr, Message, SchnorrSignature};
use cnetwork::{Api, NetworkExtension, NodeId, TimerToken};
use ctypes::{Address, Bytes, H256, H520, U128, U256};
use ctypes::{Address, Bytes, H256, H512, U128, U256};
use parking_lot::{Mutex, RwLock};
use rand::{thread_rng, Rng};
use rlp::{self, Decodable, DecoderError, Encodable, RlpStream, UntrustedRlp};
Expand Down Expand Up @@ -518,7 +517,7 @@ impl ConsensusEngine<CodeChainMachine> for Tendermint {
};
let address = match self.votes.get(&precommit) {
Some(a) => a,
None => public_to_address(&recover_ecdsa(&precommit.signature.into(), &precommit_hash)?),
None => public_to_address(&recover_schnorr(&precommit.signature.into(), &precommit_hash)?),
};
if !self.validators.contains(header.parent_hash(), &address) {
return Err(EngineError::NotAuthorized(address.to_owned()).into())
Expand Down Expand Up @@ -560,7 +559,7 @@ impl ConsensusEngine<CodeChainMachine> for Tendermint {
let message: ConsensusMessage = rlp.as_val().map_err(fmt_err)?;
if !self.votes.is_old_or_known(&message) {
let msg_hash = blake256(rlp.at(1).map_err(fmt_err)?.as_raw());
let sender = public_to_address(&recover_ecdsa(&message.signature.into(), &msg_hash).map_err(fmt_err)?);
let sender = public_to_address(&recover_schnorr(&message.signature.into(), &msg_hash).map_err(fmt_err)?);

if !self.is_authority(&sender) {
return Err(EngineError::NotAuthorized(sender))
Expand Down Expand Up @@ -666,8 +665,8 @@ impl ConsensusEngine<CodeChainMachine> for Tendermint {
Ok((list, finalize)) => {
let verifier = Box::new(EpochVerifier {
subchain_validators: list,
recover: |signature: &ECDSASignature, message: &Message| {
Ok(public_to_address(&recover_ecdsa(&signature, &message)?))
recover: |signature: &SchnorrSignature, message: &Message| {
Ok(public_to_address(&recover_schnorr(&signature, &message)?))
},
});

Expand Down Expand Up @@ -696,7 +695,7 @@ impl ConsensusEngine<CodeChainMachine> for Tendermint {
self.to_step(Step::Propose);
}

fn sign(&self, hash: H256) -> Result<ECDSASignature, Error> {
fn sign(&self, hash: H256) -> Result<SchnorrSignature, Error> {
self.signer.read().sign(hash).map_err(Into::into)
}

Expand Down Expand Up @@ -735,22 +734,22 @@ impl ConsensusEngine<CodeChainMachine> for Tendermint {

struct EpochVerifier<F>
where
F: Fn(&ECDSASignature, &Message) -> Result<Address, Error> + Send + Sync, {
F: Fn(&SchnorrSignature, &Message) -> Result<Address, Error> + Send + Sync, {
subchain_validators: ValidatorList,
recover: F,
}

impl<F> super::EpochVerifier<CodeChainMachine> for EpochVerifier<F>
where
F: Fn(&ECDSASignature, &Message) -> Result<Address, Error> + Send + Sync,
F: Fn(&SchnorrSignature, &Message) -> Result<Address, Error> + Send + Sync,
{
fn verify_light(&self, header: &Header) -> Result<(), Error> {
let message = header.bare_hash();

let mut addresses = HashSet::new();
let ref header_signatures_field = header.seal().get(2).ok_or(BlockError::InvalidSeal)?;
for rlp in UntrustedRlp::new(header_signatures_field).iter() {
let signature: H520 = rlp.as_val()?;
let signature: H512 = rlp.as_val()?;
let address = (self.recover)(&signature.into(), &message)?;

if !self.subchain_validators.contains(header.parent_hash(), &address) {
Expand Down
8 changes: 4 additions & 4 deletions core/src/consensus/vote_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ use std::collections::{BTreeMap, HashMap, HashSet};
use std::fmt::Debug;
use std::hash::Hash;

use ctypes::{Address, Bytes, H256, H520};
use ctypes::{Address, Bytes, H256, H512};
use parking_lot::RwLock;
use rlp::{Encodable, RlpStream};

pub trait Message: Clone + PartialEq + Eq + Hash + Encodable + Debug {
type Round: Clone + PartialEq + Eq + Hash + Default + Debug + Ord;

fn signature(&self) -> H520;
fn signature(&self) -> H512;

fn block_hash(&self) -> Option<H256>;

Expand All @@ -43,7 +43,7 @@ pub struct VoteCollector<M: Message> {
#[derive(Debug, Default)]
struct StepCollector<M: Message> {
voted: HashMap<Address, M>,
block_votes: HashMap<Option<H256>, HashMap<H520, Address>>,
block_votes: HashMap<Option<H256>, HashMap<H512, Address>>,
messages: HashSet<M>,
}

Expand Down Expand Up @@ -136,7 +136,7 @@ impl<M: Message + Default + Encodable + Debug> VoteCollector<M> {
}

/// Collects the signatures for a given round and hash.
pub fn round_signatures(&self, round: &M::Round, block_hash: &H256) -> Vec<H520> {
pub fn round_signatures(&self, round: &M::Round, block_hash: &H256) -> Vec<H512> {
let guard = self.votes.read();
guard
.get(round)
Expand Down
1 change: 0 additions & 1 deletion core/src/miner/mem_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,6 @@ impl MemPool {
balance: client_account.balance,
})
}
parcel.check_low_s()?;
// No invalid parcels beyond this point.
let id = self.next_parcel_id;
self.next_parcel_id += 1;
Expand Down
Loading