Skip to content
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
7 changes: 4 additions & 3 deletions dash/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "dashcore"
version = "0.36.1"
version = "0.36.2"
authors = [
"Samuel Westrich <sam@dash.org>",
"Anton Suprunchuk <anton@dash.org>",
Expand All @@ -19,7 +19,7 @@ edition = "2021"

# Please don't forget to add relevant features to docs.rs below
[features]
default = [ "std", "secp-recovery", "bincode", "quorum_validation" ]
default = [ "std", "secp-recovery", "bincode" ]
base64 = [ "base64-compat" ]
rand-std = ["secp256k1/rand"]
rand = ["secp256k1/rand"]
Expand All @@ -31,6 +31,7 @@ core-block-hash-use-x11 = ["dashcore_hashes/x11"]
bls = ["blsful"]
eddsa = ["ed25519-dalek"]
quorum_validation = ["bls"]
message_verification = ["bls"]
bincode = [ "dep:bincode", "dashcore_hashes/bincode" ]

# At least one of std, no-std must be enabled.
Expand Down Expand Up @@ -80,7 +81,7 @@ secp256k1 = { features = [ "recovery", "rand", "hashes" ], version="0.30.0" }
bip39 = "2.0.0"
bincode_test = {package = "bincode", version= "1.3.3" }
assert_matches = "1.5.0"
dashcore = { path = ".", features = ["core-block-hash-use-x11"] }
dashcore = { path = ".", features = ["core-block-hash-use-x11", "message_verification", "quorum_validation"] }

[[example]]
name = "bip32"
Expand Down
1 change: 1 addition & 0 deletions dash/src/sml/masternode_list_engine/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod helpers;
#[cfg(feature = "message_verification")]
mod message_request_verification;
mod non_rotated_quorum_construction;
mod rotated_quorum_construction;
Expand Down
3 changes: 3 additions & 0 deletions dash/src/sml/quorum_entry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ pub mod quorum_modifier_type;

#[cfg(feature = "quorum_validation")]
mod validation;

#[cfg(feature = "message_verification")]
mod verify_message;
54 changes: 1 addition & 53 deletions dash/src/sml/quorum_entry/validation.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
use bls_signatures::{BasicSchemeMPL, G1Element, G2Element, Scheme};
use blsful::Bls12381G2Impl;
use hashes::{Hash, sha256d};
use hashes::Hash;

use crate::bls_sig_utils::BLSSignature;
use crate::sml::masternode_list_entry::MasternodeListEntry;
use crate::sml::message_verification_error::MessageVerificationError;
use crate::sml::quorum_entry::qualified_quorum_entry::QualifiedQuorumEntry;
use crate::sml::quorum_validation_error::QuorumValidationError;

Expand Down Expand Up @@ -112,56 +110,6 @@ impl QualifiedQuorumEntry {
.map_err(|e| QuorumValidationError::ThresholdSignatureNotValid(e.to_string()))
}

/// Verifies a message digest using a BLS threshold signature.
///
/// This function checks whether the provided BLS signature is valid for the given
/// `message_digest` using the quorum's public key. It converts the stored quorum public key
/// and the provided BLS signature into the appropriate types before performing the verification.
///
/// # Arguments
///
/// * `message_digest` - A SHA-256 double-hashed (`sha256d::Hash`) digest of the message to be verified.
/// * `signature` - The BLS signature (`BLSSignature`) that should authenticate the message.
///
/// # Returns
///
/// * `Ok(())` if the signature is valid for the given digest and quorum public key.
/// * `Err(MessageVerificationError::ThresholdSignatureNotValid)` if the signature verification fails.
///
/// # Errors
///
/// Returns `MessageVerificationError::ThresholdSignatureNotValid` if:
/// - The quorum's public key cannot be converted to the required `blsful::PublicKey<Bls12381G2Impl>`.
/// - The provided signature cannot be converted to `blsful::Signature<Bls12381G2Impl>`.
/// - The BLS verification process determines that the signature is invalid.
///
/// # Implementation Details
///
/// - The function retrieves the quorum's public key and attempts to convert it into the expected `blsful::PublicKey` type.
/// - It converts the provided `BLSSignature` into a `blsful::Signature`.
/// - It then calls the `verify` method, which checks if the signature is valid for the given message digest.
/// - If verification fails, it returns a `MessageVerificationError::ThresholdSignatureNotValid` with relevant details.
///
pub fn verify_message_digest(
&self,
message_digest: [u8; 32],
signature: BLSSignature,
) -> Result<(), MessageVerificationError> {
let public_key: blsful::PublicKey<Bls12381G2Impl> =
self.quorum_entry.quorum_public_key.try_into()?;
let bls_signature: blsful::Signature<Bls12381G2Impl> = signature.try_into()?;
bls_signature.verify(&public_key, message_digest).map_err(|e| {
MessageVerificationError::ThresholdSignatureNotValid(
signature,
sha256d::Hash::from_byte_array(message_digest),
self.quorum_entry.quorum_public_key,
self.quorum_entry.quorum_hash,
self.quorum_entry.llmq_type,
e.to_string(),
)
})
}

/// Performs full quorum validation by verifying all necessary signatures.
///
/// This function validates the quorum by checking:
Expand Down
58 changes: 58 additions & 0 deletions dash/src/sml/quorum_entry/verify_message.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use blsful::Bls12381G2Impl;
use hashes::{Hash, sha256d};

use crate::bls_sig_utils::BLSSignature;
use crate::sml::message_verification_error::MessageVerificationError;
use crate::sml::quorum_entry::qualified_quorum_entry::QualifiedQuorumEntry;

impl QualifiedQuorumEntry {
/// Verifies a message digest using a BLS threshold signature.
///
/// This function checks whether the provided BLS signature is valid for the given
/// `message_digest` using the quorum's public key. It converts the stored quorum public key
/// and the provided BLS signature into the appropriate types before performing the verification.
///
/// # Arguments
///
/// * `message_digest` - A SHA-256 double-hashed (`sha256d::Hash`) digest of the message to be verified.
/// * `signature` - The BLS signature (`BLSSignature`) that should authenticate the message.
///
/// # Returns
///
/// * `Ok(())` if the signature is valid for the given digest and quorum public key.
/// * `Err(MessageVerificationError::ThresholdSignatureNotValid)` if the signature verification fails.
///
/// # Errors
///
/// Returns `MessageVerificationError::ThresholdSignatureNotValid` if:
/// - The quorum's public key cannot be converted to the required `blsful::PublicKey<Bls12381G2Impl>`.
/// - The provided signature cannot be converted to `blsful::Signature<Bls12381G2Impl>`.
/// - The BLS verification process determines that the signature is invalid.
///
/// # Implementation Details
///
/// - The function retrieves the quorum's public key and attempts to convert it into the expected `blsful::PublicKey` type.
/// - It converts the provided `BLSSignature` into a `blsful::Signature`.
/// - It then calls the `verify` method, which checks if the signature is valid for the given message digest.
/// - If verification fails, it returns a `MessageVerificationError::ThresholdSignatureNotValid` with relevant details.
///
pub fn verify_message_digest(
&self,
message_digest: [u8; 32],
signature: BLSSignature,
) -> Result<(), MessageVerificationError> {
let public_key: blsful::PublicKey<Bls12381G2Impl> =
self.quorum_entry.quorum_public_key.try_into()?;
let bls_signature: blsful::Signature<Bls12381G2Impl> = signature.try_into()?;
bls_signature.verify(&public_key, message_digest).map_err(|e| {
MessageVerificationError::ThresholdSignatureNotValid(
signature,
sha256d::Hash::from_byte_array(message_digest),
self.quorum_entry.quorum_public_key,
self.quorum_entry.quorum_hash,
self.quorum_entry.llmq_type,
e.to_string(),
)
})
}
}
2 changes: 1 addition & 1 deletion hashes/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "dashcore_hashes"
version = "0.15.1"
version = "0.15.2"
authors = ["Samuel Westrich <sam@dash.org>"]
license = "CC0-1.0"
repository = "https://github.com/rust-dashcore/dash_hashes/"
Expand Down
Loading