Skip to content

Commit

Permalink
[feature] hyperledger#4285: Verifiable Random Function in Sumeragi
Browse files Browse the repository at this point in the history
Signed-off-by: Sam H. Smith <sam.henning.smith@protonmail.com>
  • Loading branch information
SamHSmith committed Apr 7, 2024
1 parent bc6be98 commit 84e609d
Show file tree
Hide file tree
Showing 20 changed files with 203 additions and 79 deletions.
52 changes: 52 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions cli/src/lib.rs
Expand Up @@ -625,14 +625,15 @@ mod tests {

use assertables::{assert_contains, assert_contains_as_result};
use iroha_config::parameters::user::RootPartial as PartialUserConfig;
use iroha_crypto::KeyPair;
use iroha_crypto::{Algorithm, KeyPair};
use iroha_primitives::addr::socket_addr;
use path_absolutize::Absolutize as _;

use super::*;

fn config_factory() -> PartialUserConfig {
let (pubkey, privkey) = KeyPair::random().into_parts();
let (pubkey, privkey) =
KeyPair::random_with_algorithm(Algorithm::Secp256k1).into_parts();

let mut base = PartialUserConfig::default();

Expand Down
12 changes: 6 additions & 6 deletions config/iroha_test_config.toml
@@ -1,6 +1,6 @@
chain_id = "00000000-0000-0000-0000-000000000000"
public_key = "ed01201C61FAF8FE94E253B93114240394F79A607B7FA55F9E5A41EBEC74B88055768B"
private_key = { algorithm = "ed25519", payload = "282ED9F3CF92811C3818DBC4AE594ED59DC1A2F78E4241E31924E101D6B1FB831C61FAF8FE94E253B93114240394F79A607B7FA55F9E5A41EBEC74B88055768B" }
public_key = "e70121039B861E76EBC90B3348142E3ED6C82DE4F6223A003E19159397D93008CEDB2CF3"
private_key = { algorithm = "secp256k1", payload = "D9CAA39CD8DF8E20BDE9E21CB2A8DFF3DC3F152954E651D96F03E1EC94DFE581" }

[network]
address = "127.0.0.1:1337"
Expand All @@ -15,19 +15,19 @@ address = "127.0.0.1:8080"

[[sumeragi.trusted_peers]]
address = "127.0.0.1:1337"
public_key = "ed01201C61FAF8FE94E253B93114240394F79A607B7FA55F9E5A41EBEC74B88055768B"
public_key = "e7012102E7A461547D04FF0EA7E9A473D67B51A58C41E53F7D9583096052492ABDB430D4"

[[sumeragi.trusted_peers]]
address = "127.0.0.1:1338"
public_key = "ed0120CC25624D62896D3A0BFD8940F928DC2ABF27CC57CEFEB442AA96D9081AAE58A1"
public_key = "e7012103F8DE33E3B492CE14346BCD330A0044FE8C03BFCA03168B513722CCB00BE42734"

[[sumeragi.trusted_peers]]
address = "127.0.0.1:1339"
public_key = "ed0120FACA9E8AA83225CB4D16D67F27DD4F93FC30FFA11ADC1F5C88FD5495ECC91020"
public_key = "e701210390292D847084F39975E805DF70CEEBDF1FEC61C1547C77DC0B2A353C29DD3B97"

[[sumeragi.trusted_peers]]
address = "127.0.0.1:1340"
public_key = "ed01208E351A70B6A603ED285D666B8D689B680865913BA03CE29FB7D13A166C4E7F1F"
public_key = "e701210360E53577CDA472A8873ABFF96376E0A82A5123D718F91499D284A45D57A322EC"

[logger]
format = "pretty"
Expand Down
11 changes: 11 additions & 0 deletions config/src/parameters/user.rs
Expand Up @@ -142,6 +142,12 @@ impl Root {
let key_pair =
KeyPair::new(self.public_key, self.private_key)
.wrap_err("failed to construct a key pair from `iroha.public_key` and `iroha.private_key` configuration parameters")
.map(|key| {
if key.algorithm() != iroha_crypto::Algorithm::Secp256k1 {
emitter.emit(eyre!("Peer key pair must use algorithm Secp256k1. Problematic public key = {}", key.public_key()));
}
key
})
.map_or_else(|err| {
emitter.emit(err);
None
Expand Down Expand Up @@ -422,6 +428,11 @@ impl Sumeragi {
} = self;

let trusted_peers = construct_unique_vec(trusted_peers.unwrap_or(vec![]))?;
for peer in &trusted_peers {
if peer.public_key.algorithm() != iroha_crypto::Algorithm::Secp256k1 {
return Err(eyre!("Only Secp256k1 key pairs are allowed in the trusted peers. Problematic public key = {}", peer.public_key));
}
}

Ok(actual::Sumeragi {
trusted_peers,
Expand Down
2 changes: 1 addition & 1 deletion config/tests/fixtures/base_trusted_peers.toml
@@ -1,3 +1,3 @@
[[sumeragi.trusted_peers]]
address = "127.0.0.1:1338"
public_key = "ed01208BA62848CF767D72E7F7F4B9D2D7BA07FEE33760F79ABE5597A51520E292A0CB"
public_key = "e7012103756A6D80129A39E94D40E91826D96FE9DAE6F0EE153ADE3BE1246E019394F445"
8 changes: 4 additions & 4 deletions config/tests/fixtures/minimal_file_and_env.toml
@@ -1,14 +1,14 @@
extends = "base_trusted_peers.toml"

chain_id = "0"
public_key = "ed01208BA62848CF767D72E7F7F4B9D2D7BA07FEE33760F79ABE5597A51520E292A0CB"
private_key.algorithm = "ed25519"
private_key.payload = "8f4c15e5d664da3f13778801d23d4e89b76e94c1b94b389544168b6cb894f84f8ba62848cf767d72e7f7f4b9d2d7ba07fee33760f79abe5597a51520e292a0cb"
public_key = "e7012103756A6D80129A39E94D40E91826D96FE9DAE6F0EE153ADE3BE1246E019394F445"
private_key.algorithm = "secp256k1"
private_key.payload = "1D39F2378F01F87F32AA830B7ABC4262EFEB44C67D7EA7BE277F1EA97C470CAE"

[network]
address = "127.0.0.1:1337"

[genesis]
public_key = "ed01208BA62848CF767D72E7F7F4B9D2D7BA07FEE33760F79ABE5597A51520E292A0CB"
public_key = "e7012103756A6D80129A39E94D40E91826D96FE9DAE6F0EE153ADE3BE1246E019394F445"

# `torii.address` should be in ENV
1 change: 1 addition & 0 deletions core/Cargo.toml
Expand Up @@ -66,6 +66,7 @@ nonzero_ext = { workspace = true }

uuid = { version = "1.4.1", features = ["v4"] }
indexmap = "2.1.0"
vrf = "0.2.4"

[dev-dependencies]
criterion = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion core/benches/blocks/common.rs
Expand Up @@ -40,7 +40,7 @@ pub fn create_block(
topology.clone(),
Vec::new(),
)
.chain(0, state)
.chain(0, Vec::new(), state)
.sign(key_pair)
.unpack(|_| {})
.commit(&topology)
Expand Down
2 changes: 1 addition & 1 deletion core/benches/kura.rs
Expand Up @@ -54,7 +54,7 @@ async fn measure_block_size_for_n_executors(n_executors: u32) {
let mut block = {
let mut state_block = state.block();
BlockBuilder::new(vec![tx], topology, Vec::new())
.chain(0, &mut state_block)
.chain(0, Vec::new(), &mut state_block)
.sign(&KeyPair::random())
.unpack(|_| {})
};
Expand Down
7 changes: 5 additions & 2 deletions core/benches/validation.rs
Expand Up @@ -179,8 +179,11 @@ fn sign_blocks(criterion: &mut Criterion) {
let mut count = 0;

let mut state_block = state.block();
let block =
BlockBuilder::new(vec![transaction], topology, Vec::new()).chain(0, &mut state_block);
let block = BlockBuilder::new(vec![transaction], topology, Vec::new()).chain(
0,
Vec::new(),
&mut state_block,
);

let _ = criterion.bench_function("sign_block", |b| {
b.iter_batched(
Expand Down
28 changes: 24 additions & 4 deletions core/src/block.rs
Expand Up @@ -20,7 +20,11 @@ use thiserror::Error;

pub(crate) use self::event::WithEvents;
pub use self::{chained::Chained, commit::CommittedBlock, valid::ValidBlock};
use crate::{prelude::*, sumeragi::network_topology::Topology, tx::AcceptTransactionFail};
use crate::{
prelude::*,
sumeragi::{network_topology::Topology, vrf::verify_vrf},
tx::AcceptTransactionFail,
};

/// Error during transaction validation
#[derive(Debug, displaydoc::Display, Error)]
Expand Down Expand Up @@ -74,6 +78,8 @@ pub enum BlockValidationError {
SignatureVerification(#[from] SignatureVerificationError),
/// Received view change index is too large
ViewChangeIndexTooLarge,
/// Block has an invalid VRF state
InvalidVRF,
}

/// Error during signature verification
Expand Down Expand Up @@ -148,11 +154,13 @@ mod pending {
previous_height: u64,
prev_block_hash: Option<HashOf<SignedBlock>>,
view_change_index: u64,
vrf_state: Vec<u8>,
transactions: &[TransactionValue],
) -> BlockHeader {
BlockHeader {
height: previous_height + 1,
previous_block_hash: prev_block_hash,
vrf_state,
transactions_hash: transactions
.iter()
.map(|value| value.as_ref().hash())
Expand Down Expand Up @@ -206,6 +214,7 @@ mod pending {
pub fn chain(
self,
view_change_index: u64,
vrf_state: Vec<u8>,
state: &mut StateBlock<'_>,
) -> BlockBuilder<Chained> {
let transactions = Self::categorize_transactions(self.0.transactions, state);
Expand All @@ -215,6 +224,7 @@ mod pending {
state.height(),
state.latest_block_hash(),
view_change_index,
vrf_state,
&transactions,
),
transactions,
Expand Down Expand Up @@ -320,6 +330,15 @@ mod valid {
)));
}

let leader_pk = &topology.ordered_peers[0].public_key;
if !verify_vrf(
&topology.get_vrf_state(),
&block.header().vrf_state,
leader_pk,
) {
return WithEvents::new(Err((block, BlockValidationError::InvalidVRF)));
}

if topology
.filter_signatures_by_roles(&[Role::Leader], block.signatures())
.is_empty()
Expand Down Expand Up @@ -491,6 +510,7 @@ mod valid {
.as_millis()
.try_into()
.expect("Time should fit into u64"),
vrf_state: Vec::new(),
},
transactions: Vec::new(),
commit_topology: UniqueVec::new(),
Expand Down Expand Up @@ -842,7 +862,7 @@ mod tests {
let transactions = vec![tx.clone(), tx];
let topology = Topology::new(UniqueVec::new());
let valid_block = BlockBuilder::new(transactions, topology, Vec::new())
.chain(0, &mut state_block)
.chain(0, Vec::new(), &mut state_block)
.sign(&alice_keys)
.unpack(|_| {});

Expand Down Expand Up @@ -917,7 +937,7 @@ mod tests {
let transactions = vec![tx0, tx, tx2];
let topology = Topology::new(UniqueVec::new());
let valid_block = BlockBuilder::new(transactions, topology, Vec::new())
.chain(0, &mut state_block)
.chain(0, Vec::new(), &mut state_block)
.sign(&alice_keys)
.unpack(|_| {});

Expand Down Expand Up @@ -987,7 +1007,7 @@ mod tests {
let transactions = vec![tx_fail, tx_accept];
let topology = Topology::new(UniqueVec::new());
let valid_block = BlockBuilder::new(transactions, topology, Vec::new())
.chain(0, &mut state_block)
.chain(0, Vec::new(), &mut state_block)
.sign(&alice_keys)
.unpack(|_| {});

Expand Down
6 changes: 3 additions & 3 deletions core/src/smartcontracts/isi/query.rs
Expand Up @@ -314,7 +314,7 @@ mod tests {

let topology = Topology::new(UniqueVec::new());
let first_block = BlockBuilder::new(transactions.clone(), topology.clone(), Vec::new())
.chain(0, &mut state_block)
.chain(0, Vec::new(), &mut state_block)
.sign(&ALICE_KEYS)
.unpack(|_| {})
.commit(&topology)
Expand All @@ -326,7 +326,7 @@ mod tests {

for _ in 1u64..blocks {
let block = BlockBuilder::new(transactions.clone(), topology.clone(), Vec::new())
.chain(0, &mut state_block)
.chain(0, Vec::new(), &mut state_block)
.sign(&ALICE_KEYS)
.unpack(|_| {})
.commit(&topology)
Expand Down Expand Up @@ -468,7 +468,7 @@ mod tests {

let topology = Topology::new(UniqueVec::new());
let vcb = BlockBuilder::new(vec![va_tx.clone()], topology.clone(), Vec::new())
.chain(0, &mut state_block)
.chain(0, Vec::new(), &mut state_block)
.sign(&ALICE_KEYS)
.unpack(|_| {})
.commit(&topology)
Expand Down

0 comments on commit 84e609d

Please sign in to comment.