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

Add sign & verify_sign to trait SecureShareContent #3874

Merged
merged 6 commits into from
Apr 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
23 changes: 8 additions & 15 deletions massa-consensus-worker/src/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,11 +272,10 @@ impl ConsensusController for ConsensusControllerImpl {
}

if let Some(verifiable_block) = block_storage.read_blocks().get(&block_id) {
if let Ok(de_p) = DenunciationPrecursor::try_from(&verifiable_block.content.header) {
self.channels
.pool_command_sender
.add_denunciation_precursor(de_p);
}
let de_p = DenunciationPrecursor::from(&verifiable_block.content.header);
self.channels
.pool_command_sender
.add_denunciation_precursor(de_p);
}

if let Err(err) = self
Expand All @@ -303,16 +302,10 @@ impl ConsensusController for ConsensusControllerImpl {
}
}

if let Ok(de_p) = DenunciationPrecursor::try_from(&header) {
self.channels
.pool_command_sender
.add_denunciation_precursor(de_p);
} else {
warn!(
"Cannot create denunciation precursor from header: {}",
&header
);
}
let de_p = DenunciationPrecursor::from(&header);
self.channels
.pool_command_sender
.add_denunciation_precursor(de_p);

if let Err(err) = self
.command_sender
Expand Down
14 changes: 7 additions & 7 deletions massa-models/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,18 +67,18 @@ pub type SecureShareBlock = SecureShare<Block, BlockId>;

impl SecureShareContent for Block {
fn new_verifiable<SC: Serializer<Self>, U: Id>(
content: Self,
self,
content_serializer: SC,
_keypair: &KeyPair,
) -> Result<SecureShare<Self, U>, ModelsError> {
let mut content_serialized = Vec::new();
content_serializer.serialize(&content, &mut content_serialized)?;
content_serializer.serialize(&self, &mut content_serialized)?;
Ok(SecureShare {
signature: content.header.signature,
content_creator_pub_key: content.header.content_creator_pub_key,
content_creator_address: content.header.content_creator_address,
id: U::new(*content.header.id.get_hash()),
content,
signature: self.header.signature,
content_creator_pub_key: self.header.content_creator_pub_key,
content_creator_address: self.header.content_creator_address,
id: U::new(*self.header.id.get_hash()),
content: self,
serialized_data: content_serialized,
})
}
Expand Down
56 changes: 42 additions & 14 deletions massa-models/src/block_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,19 +92,13 @@ impl BlockHeader {
pub type SecuredHeader = SecureShare<BlockHeader, BlockId>;

impl SecureShareContent for BlockHeader {
/// Compute hash for Block header in SecuredHeader - taking care of Denunciation verification
fn compute_hash(
content: &Self,
content_serialized: &[u8],
content_creator_pub_key: &PublicKey,
) -> Hash {
let de_data = BlockHeaderDenunciationData::new(content.slot);

let mut hash_data = Vec::new();
hash_data.extend(content_creator_pub_key.to_bytes());
hash_data.extend(de_data.to_bytes());
hash_data.extend(Hash::compute_from(content_serialized).to_bytes());
Hash::compute_from(&hash_data)
/// compute the signed hash
fn compute_signed_hash(&self, public_key: &PublicKey, content_hash: &Hash) -> Hash {
let mut signed_data: Vec<u8> = Vec::new();
signed_data.extend(public_key.to_bytes());
signed_data.extend(BlockHeaderDenunciationData::new(self.slot).to_bytes());
signed_data.extend(content_hash.to_bytes());
Hash::compute_from(&signed_data)
}
}

Expand Down Expand Up @@ -559,7 +553,7 @@ mod test {
use crate::test_exports::{
gen_block_headers_for_denunciation, gen_endorsements_for_denunciation,
};
use massa_signature::KeyPair;
use massa_signature::{verify_signature_batch, KeyPair};

// Only for testing purpose
impl PartialEq for BlockHeader {
Expand Down Expand Up @@ -623,4 +617,38 @@ mod test {
assert_eq!(rem.is_empty(), true);
assert_eq!(block_header_1, block_header_der);
}

#[test]
fn test_verify_sig_batch() {
let (_slot, _keypair, secured_header_1, secured_header_2, secured_header_3) =
gen_block_headers_for_denunciation(None, None);

// Test with batch len == 1 (no // verif)
let batch_1 = [(
secured_header_1.compute_signed_hash(),
secured_header_1.signature,
secured_header_1.content_creator_pub_key,
)];
verify_signature_batch(&batch_1).unwrap();

// Test with batch len > 1 (// verif)
let batch_2 = [
(
secured_header_1.compute_signed_hash(),
secured_header_1.signature,
secured_header_1.content_creator_pub_key,
),
(
secured_header_2.compute_signed_hash(),
secured_header_2.signature,
secured_header_2.content_creator_pub_key,
),
(
secured_header_3.compute_signed_hash(),
secured_header_3.signature,
secured_header_3.content_creator_pub_key,
),
];
verify_signature_batch(&batch_2).unwrap();
}
}
123 changes: 44 additions & 79 deletions massa-models/src/denunciation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,11 @@ use num_enum::{IntoPrimitive, TryFromPrimitive};
use serde::{Deserialize, Serialize};
use thiserror::Error;

use crate::block_header::{
BlockHeader, BlockHeaderDenunciationData, BlockHeaderSerializer, SecuredHeader,
};
use crate::endorsement::{
Endorsement, EndorsementDenunciationData, EndorsementSerializer, SecureShareEndorsement,
};
use crate::block_header::{BlockHeaderDenunciationData, SecuredHeader};
use crate::endorsement::{EndorsementDenunciationData, SecureShareEndorsement};
use crate::slot::{Slot, SlotDeserializer, SlotSerializer};

use crate::secure_share::Id;
use massa_hash::{Hash, HashDeserializer, HashSerializer};
use massa_serialization::{
Deserializer, SerializeError, Serializer, U32VarIntDeserializer, U32VarIntSerializer,
Expand All @@ -43,14 +40,6 @@ pub struct EndorsementDenunciation {
}

impl EndorsementDenunciation {
/// Compute hash for Endorsement content
fn compute_content_hash(content: &Endorsement) -> Result<Hash, SerializeError> {
let mut buf = Vec::new();
let endorsement_serializer = EndorsementSerializer::new();
endorsement_serializer.serialize(content, &mut buf)?;
Ok(Hash::compute_from(&buf))
}

/// Rebuild full hash of SecureShareEndorsement from given arguments
fn compute_hash_for_sig_verif(
public_key: &PublicKey,
Expand Down Expand Up @@ -83,14 +72,6 @@ pub struct BlockHeaderDenunciation {
}

impl BlockHeaderDenunciation {
/// Compute hash for Block header content
fn compute_content_hash(content: &BlockHeader) -> Result<Hash, SerializeError> {
let mut buf = Vec::new();
let block_header_serializer = BlockHeaderSerializer::new();
block_header_serializer.serialize(content, &mut buf)?;
Ok(Hash::compute_from(&buf))
}

/// Rebuild full hash of SecuredHeader from given arguments
fn compute_hash_for_sig_verif(
public_key: &PublicKey,
Expand Down Expand Up @@ -137,21 +118,20 @@ impl Denunciation {
match self {
Denunciation::BlockHeader(_) => Ok(false),
Denunciation::Endorsement(endo_de) => {
let content_hash =
EndorsementDenunciation::compute_content_hash(&s_endorsement.content)?;
let content_hash = s_endorsement.id.get_hash();

let hash = EndorsementDenunciation::compute_hash_for_sig_verif(
&endo_de.public_key,
&endo_de.slot,
&endo_de.index,
&content_hash,
content_hash,
);

Ok(endo_de.slot == s_endorsement.content.slot
&& endo_de.index == s_endorsement.content.index
&& endo_de.public_key == s_endorsement.content_creator_pub_key
&& endo_de.hash_1 != content_hash
&& endo_de.hash_2 != content_hash
&& endo_de.hash_1 != *content_hash
&& endo_de.hash_2 != *content_hash
&& endo_de
.public_key
.verify_signature(&hash, &s_endorsement.signature)
Expand All @@ -168,19 +148,18 @@ impl Denunciation {
match self {
Denunciation::Endorsement(_) => Ok(false),
Denunciation::BlockHeader(endo_bh) => {
let content_hash =
BlockHeaderDenunciation::compute_content_hash(&s_block_header.content)?;
let content_hash = s_block_header.id.get_hash();

let hash = BlockHeaderDenunciation::compute_hash_for_sig_verif(
&endo_bh.public_key,
&endo_bh.slot,
&content_hash,
content_hash,
);

Ok(endo_bh.slot == s_block_header.content.slot
&& endo_bh.public_key == s_block_header.content_creator_pub_key
&& endo_bh.hash_1 != content_hash
&& endo_bh.hash_2 != content_hash
&& endo_bh.hash_1 != *content_hash
&& endo_bh.hash_2 != *content_hash
&& endo_bh
.public_key
.verify_signature(&hash, &s_block_header.signature)
Expand Down Expand Up @@ -294,20 +273,20 @@ impl TryFrom<(&SecureShareEndorsement, &SecureShareEndorsement)> for Denunciatio
}

// Check sig of s_e1 with s_e1.public_key, s_e1.slot, s_e1.index
let s_e1_hash_content = EndorsementDenunciation::compute_content_hash(&s_e1.content)?;
let s_e1_hash_content = s_e1.id.get_hash();
let s_e1_hash = EndorsementDenunciation::compute_hash_for_sig_verif(
&s_e1.content_creator_pub_key,
&s_e1.content.slot,
&s_e1.content.index,
&s_e1_hash_content,
s_e1_hash_content,
);
// Check sig of s_e2 but with s_e1.public_key, s_e1.slot, s_e1.index
let s_e2_hash_content = EndorsementDenunciation::compute_content_hash(&s_e2.content)?;
let s_e2_hash_content = s_e2.id.get_hash();
let s_e2_hash = EndorsementDenunciation::compute_hash_for_sig_verif(
&s_e1.content_creator_pub_key,
&s_e1.content.slot,
&s_e1.content.index,
&s_e2_hash_content,
s_e2_hash_content,
);

s_e1.content_creator_pub_key
Expand All @@ -321,8 +300,8 @@ impl TryFrom<(&SecureShareEndorsement, &SecureShareEndorsement)> for Denunciatio
index: s_e1.content.index,
signature_1: s_e1.signature,
signature_2: s_e2.signature,
hash_1: s_e1_hash_content,
hash_2: s_e2_hash_content,
hash_1: *s_e1_hash_content,
hash_2: *s_e2_hash_content,
}))
}
}
Expand All @@ -342,17 +321,17 @@ impl TryFrom<(&SecuredHeader, &SecuredHeader)> for Denunciation {
}

// Check sig of s_bh2 but with s_bh1.public_key, s_bh1.slot, s_bh1.index
let s_bh1_hash_content = BlockHeaderDenunciation::compute_content_hash(&s_bh1.content)?;
let s_bh1_hash_content = s_bh1.id.get_hash();
let s_bh1_hash = BlockHeaderDenunciation::compute_hash_for_sig_verif(
&s_bh1.content_creator_pub_key,
&s_bh1.content.slot,
&s_bh1_hash_content,
s_bh1_hash_content,
);
let s_bh2_hash_content = BlockHeaderDenunciation::compute_content_hash(&s_bh2.content)?;
let s_bh2_hash_content = s_bh2.id.get_hash();
let s_bh2_hash = BlockHeaderDenunciation::compute_hash_for_sig_verif(
&s_bh1.content_creator_pub_key,
&s_bh1.content.slot,
&s_bh2_hash_content,
s_bh2_hash_content,
);

s_bh1
Expand All @@ -367,8 +346,8 @@ impl TryFrom<(&SecuredHeader, &SecuredHeader)> for Denunciation {
slot: s_bh1.content.slot,
signature_1: s_bh1.signature,
signature_2: s_bh2.signature,
hash_1: s_bh1_hash_content,
hash_2: s_bh2_hash_content,
hash_1: *s_bh1_hash_content,
hash_2: *s_bh2_hash_content,
}))
}
}
Expand Down Expand Up @@ -1021,40 +1000,26 @@ impl DenunciationPrecursor {
}
}

impl TryFrom<&SecureShareEndorsement> for DenunciationPrecursor {
type Error = DenunciationError;

fn try_from(value: &SecureShareEndorsement) -> Result<Self, Self::Error> {
// TODO: find a way to avoid recomputing a hash
let hash = EndorsementDenunciation::compute_content_hash(&value.content)?;

Ok(DenunciationPrecursor::Endorsement(
EndorsementDenunciationPrecursor {
public_key: value.content_creator_pub_key,
slot: value.content.slot,
index: value.content.index,
hash,
signature: value.signature,
},
))
impl From<&SecureShareEndorsement> for DenunciationPrecursor {
fn from(value: &SecureShareEndorsement) -> Self {
DenunciationPrecursor::Endorsement(EndorsementDenunciationPrecursor {
public_key: value.content_creator_pub_key,
slot: value.content.slot,
index: value.content.index,
hash: *value.id.get_hash(),
signature: value.signature,
})
}
}

impl TryFrom<&SecuredHeader> for DenunciationPrecursor {
type Error = DenunciationError;

fn try_from(value: &SecuredHeader) -> Result<Self, Self::Error> {
// TODO: find a way to avoid recomputing a hash
let hash = BlockHeaderDenunciation::compute_content_hash(&value.content)?;

Ok(DenunciationPrecursor::BlockHeader(
BlockHeaderDenunciationPrecursor {
public_key: value.content_creator_pub_key,
slot: value.content.slot,
hash,
signature: value.signature,
},
))
impl From<&SecuredHeader> for DenunciationPrecursor {
fn from(value: &SecuredHeader) -> Self {
DenunciationPrecursor::BlockHeader(BlockHeaderDenunciationPrecursor {
public_key: value.content_creator_pub_key,
slot: value.content.slot,
hash: *value.id.get_hash(),
signature: value.signature,
})
}
}

Expand Down Expand Up @@ -1421,8 +1386,8 @@ mod tests {
gen_block_headers_for_denunciation(None, None);
let denunciation: Denunciation = (&s_block_header_1, &s_block_header_2).try_into().unwrap();

let de_p_1 = DenunciationPrecursor::try_from(&s_block_header_1).unwrap();
let de_p_2 = DenunciationPrecursor::try_from(&s_block_header_2).unwrap();
let de_p_1 = DenunciationPrecursor::from(&s_block_header_1);
let de_p_2 = DenunciationPrecursor::from(&s_block_header_2);
let denunciation_2: Denunciation = (&de_p_1, &de_p_2).try_into().unwrap();

assert_eq!(denunciation, denunciation_2);
Expand All @@ -1431,8 +1396,8 @@ mod tests {
gen_endorsements_for_denunciation(None, None);
let denunciation_3 = Denunciation::try_from((&s_endorsement_1, &s_endorsement_2)).unwrap();

let de_p_3 = DenunciationPrecursor::try_from(&s_endorsement_1).unwrap();
let de_p_4 = DenunciationPrecursor::try_from(&s_endorsement_2).unwrap();
let de_p_3 = DenunciationPrecursor::from(&s_endorsement_1);
let de_p_4 = DenunciationPrecursor::from(&s_endorsement_2);
let denunciation_4: Denunciation = (&de_p_3, &de_p_4).try_into().unwrap();

assert_eq!(denunciation_3, denunciation_4);
Expand Down
Loading