Skip to content

Commit

Permalink
temp
Browse files Browse the repository at this point in the history
  • Loading branch information
HoOngEe committed Nov 22, 2019
1 parent b9d3b52 commit c23cfa3
Show file tree
Hide file tree
Showing 15 changed files with 485 additions and 314 deletions.
11 changes: 4 additions & 7 deletions core/src/consensus/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ use crate::account_provider::AccountProvider;
use crate::block::{ExecutedBlock, SealedBlock};
use crate::client::ConsensusClient;
use crate::codechain_machine::CodeChainMachine;
use crate::consensus::sortition::VRFSeed;
use crate::consensus::sortition::seed::SeedInfo;
use crate::error::Error;
use crate::transaction::UnverifiedTransaction;
use crate::views::HeaderView;
Expand All @@ -69,8 +69,7 @@ pub enum Seal {
cur_view: View,
precommits: Vec<SchnorrSignature>,
precommit_bitset: BitSet,
vrf_seed: VRFSeed,
vrf_seed_proof: Vec<u8>,
vrf_seed_info: SeedInfo,
},
None,
}
Expand All @@ -86,15 +85,13 @@ impl Seal {
cur_view,
precommits,
precommit_bitset,
vrf_seed,
vrf_seed_proof,
vrf_seed_info,
} => Some(vec![
::rlp::encode(prev_view).into_vec(),
::rlp::encode(cur_view).into_vec(),
::rlp::encode_list(precommits).into_vec(),
::rlp::encode(precommit_bitset).into_vec(),
::rlp::encode(vrf_seed).into_vec(),
::rlp::encode(vrf_seed_proof).into_vec(),
::rlp::encode(vrf_seed_info).into_vec(),
]),
}
}
Expand Down
10 changes: 7 additions & 3 deletions core/src/consensus/signer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,18 @@ impl EngineSigner {

#[allow(dead_code)]
/// Generate a vrf random hash.
pub fn vrf_hash(&self, hash: H256, vrf_inst: &mut ECVRF) -> Result<Vec<u8>, AccountProviderError> {
pub fn vrf_proof_and_hash(
&self,
message: &[u8],
vrf_inst: &mut ECVRF,
) -> Result<(Vec<u8>, Vec<u8>), AccountProviderError> {
Ok(match &self.decrypted_account {
Some(account) => account.vrf_hash(&hash, vrf_inst)?,
Some(account) => account.vrf_proof_and_hash(message, vrf_inst)?,
None => {
let address = self.signer.map(|(address, _)| address).unwrap_or_default();
self.account_provider
.get_unlocked_account(&address)
.and_then(|account| account.vrf_hash(&hash, vrf_inst).map_err(From::from))?
.and_then(|account| account.vrf_proof_and_hash(message, vrf_inst).map_err(From::from))?
}
})
}
Expand Down
49 changes: 34 additions & 15 deletions core/src/consensus/sortition/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,54 @@

mod binom_cdf;
mod draw;
pub mod seed;
pub mod vrf_sortition;

use std::sync::Arc;

use ckey::Public;
use primitives::H256;
use vrf::openssl::Error as VrfError;
use vrf::openssl::{Error as VRFError, ECVRF};

use self::vrf_sortition::{PriorityInfo, VRFSortition};
use self::seed::{SeedInfo, VRFSeed};
use self::vrf_sortition::{Priority, PriorityInfo, VRFSortition};
use crate::consensus::{Height, View};

pub type VRFSeed = H256;

#[derive(Debug, PartialEq, RlpEncodable, RlpDecodable)]
#[derive(Debug, Eq, PartialEq, Clone, RlpEncodable, RlpDecodable)]
pub struct PriorityMessage {
pub seed: VRFSeed,
pub info: PriorityInfo,
pub seed: SeedInfo,
pub priority: PriorityInfo,
}

impl PriorityMessage {
pub fn verify(
pub fn seed(&self) -> &VRFSeed {
self.seed.seed()
}

pub fn verify_seed(
&self,
height: Height,
view: View,
prev_seed: &VRFSeed,
signer_public: &Public,
vrf_inst: &mut ECVRF,
) -> Result<bool, VRFError> {
self.seed.verify(height, view, prev_seed, signer_public, vrf_inst)
}

pub fn verify_priority(
&self,
signer_public: &Public,
voting_power: u64,
sortition_scheme: &VRFSortition,
) -> Result<bool, VrfError> {
) -> Result<bool, VRFError> {
// fast verification first
Ok(self.info.verify_sub_user_idx(voting_power, sortition_scheme.total_power, sortition_scheme.expectation)
&& self.info.verify_priority()
&& self.info.verify_vrf_hash(signer_public, &self.seed, Arc::clone(&sortition_scheme.vrf_inst))?)
Ok(self.priority.verify_sub_user_idx(voting_power, sortition_scheme.total_power, sortition_scheme.expectation)
&& self.priority.verify_priority()
&& self.priority.verify_vrf_hash(signer_public, self.seed(), Arc::clone(&sortition_scheme.vrf_inst))?)
}

pub fn priority(&self) -> Priority {
self.priority.priority()
}
}

Expand Down Expand Up @@ -80,7 +99,7 @@ mod priority_message_tests {
sortition_scheme.create_highest_priority_info(seed, priv_key, voting_power).unwrap().unwrap();

let priority_message = PriorityMessage {
seed,
seed: seed.into(),
info: priority_info,
};
assert!(priority_message.verify(&pub_key, voting_power, &sortition_scheme).unwrap());
Expand All @@ -104,7 +123,7 @@ mod priority_message_tests {
sortition_scheme.create_highest_priority_info(seed, priv_key, voting_power).unwrap().unwrap();

let priority_message = PriorityMessage {
seed,
seed: seed.into(),
info: priority_info,
};
rlp_encode_and_decode_test!(priority_message);
Expand Down
106 changes: 106 additions & 0 deletions core/src/consensus/sortition/seed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Copyright 2019 Kodebox, Inc.
// This file is part of CodeChain.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use ckey::{standard_uncompressed_pubkey, Public};
use primitives::H256;
use vrf::openssl::{Error as VRFError, ECVRF};
use vrf::VRF;

use crate::consensus::{Height, View};

#[derive(Debug, Eq, PartialEq, Clone, Copy, RlpEncodable, RlpDecodable)]
pub struct VRFSeed(H256);

impl AsRef<[u8]> for VRFSeed {
#[inline]
fn as_ref(&self) -> &[u8] {
&self.0
}
}

impl ::core::ops::Deref for VRFSeed {
type Target = [u8];

#[inline]
fn deref(&self) -> &[u8] {
&self.0
}
}

impl From<H256> for VRFSeed {
fn from(hash: H256) -> Self {
VRFSeed(hash)
}
}

impl From<VRFSeed> for H256 {
fn from(seed: VRFSeed) -> Self {
seed.0
}
}

#[cfg(test)]
impl From<u64> for VRFSeed {
fn from(mut value: u64) -> Self {
let hash: H256 = value.into();
hash.into()
}
}

impl VRFSeed {
pub fn zero() -> Self {
VRFSeed(H256::zero())
}
}

impl VRFSeed {
/// Calculate the common message used in next seed generation.
pub fn generate_next_msg(&self, height: Height, view: View) -> Vec<u8> {
[&self[..], &height.to_be_bytes(), &view.to_be_bytes()].concat()
}
}

#[derive(Debug, Eq, PartialEq, Clone, RlpEncodable, RlpDecodable)]
pub struct SeedInfo {
seed: VRFSeed,
proof: Vec<u8>,
}

impl SeedInfo {
pub fn from_seed_and_proof(seed: Vec<u8>, proof: Vec<u8>) -> Self {
Self {
seed: H256::from_slice(&seed).into(),
proof,
}
}

pub fn seed(&self) -> &VRFSeed {
&self.seed
}

pub fn verify(
&self,
height: Height,
view: View,
prev_seed: &VRFSeed,
signer_public: &Public,
vrf_inst: &mut ECVRF,
) -> Result<bool, VRFError> {
let msg = prev_seed.generate_next_msg(height, view);
let standard_pubkey = standard_uncompressed_pubkey(signer_public);
vrf_inst.verify(&standard_pubkey, &self.proof, &msg).map(|expected_seed| expected_seed == self.seed.to_vec())
}
}
21 changes: 12 additions & 9 deletions core/src/consensus/sortition/vrf_sortition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@
use std::sync::Arc;

use ccrypto::sha256;
use ckey::{standard_uncompressed_pubkey, Private, Public};
use ckey::{standard_uncompressed_pubkey, Public};
use parking_lot::RwLock;
use primitives::H256;
use vrf::openssl::{Error as VrfError, ECVRF};
use vrf::openssl::{Error as VRFError, ECVRF};
use vrf::VRF;

use super::super::signer::EngineSigner;
use super::draw::draw;
use super::seed::VRFSeed;
use crate::AccountProviderError;

pub type Priority = H256;

pub struct VRFSortition {
Expand All @@ -45,13 +49,12 @@ pub struct PriorityInfo {
impl VRFSortition {
pub fn create_highest_priority_info(
&self,
seed: H256,
priv_key: Private,
seed: VRFSeed,
signer: &EngineSigner,
voting_power: u64,
) -> Result<Option<PriorityInfo>, VrfError> {
) -> Result<Option<PriorityInfo>, AccountProviderError> {
let mut vrf_inst = self.vrf_inst.write();
let vrf_proof = vrf_inst.prove(&*priv_key, &*seed)?;
let vrf_hash = vrf_inst.proof_to_hash(&vrf_proof)?;
let (vrf_proof, vrf_hash) = signer.vrf_proof_and_hash(seed.into(), &mut vrf_inst)?;
let j = draw(voting_power, self.total_power, self.expectation, &vrf_hash);

Ok((0..j)
Expand Down Expand Up @@ -86,7 +89,7 @@ impl PriorityInfo {
signer_public: &Public,
seed: &[u8],
vrf_inst: Arc<RwLock<ECVRF>>,
) -> Result<bool, VrfError> {
) -> Result<bool, VRFError> {
// CodeChain is using uncompressed form of public keys without prefix, so the prefix is required
// for public keys to be used in openssl.

Expand Down Expand Up @@ -186,7 +189,7 @@ mod vrf_tests {
sortition_scheme.create_highest_priority_info(seed, priv_key.into(), voting_power).unwrap().unwrap();
assert!(priority_info.verify_vrf_hash(&pub_key, &seed, Arc::clone(&sortition_scheme.vrf_inst)).unwrap());
match priority_info.verify_vrf_hash(&wrong_pub_key, &seed, Arc::clone(&sortition_scheme.vrf_inst)) {
Err(VrfError::InvalidProof) => (),
Err(VRFError::InvalidProof) => (),
_ => panic!(),
}
}
Expand Down
Loading

0 comments on commit c23cfa3

Please sign in to comment.