use crate::merkle_tree::{BatchPath, Path};
use blake2::digest::{Digest, FixedOutput};
use {
crate::multi_sig::{Signature, VerificationKey, VerificationKeyPoP},
blst::BLST_ERROR,
};
#[derive(Debug, thiserror::Error, Eq, PartialEq)]
pub enum MultiSignatureError {
#[error("Invalid single signature")]
SignatureInvalid(Signature),
#[error("Invalid aggregated signature")]
AggregateSignatureInvalid,
#[error("Invalid bytes")]
SerializationError,
#[error("Key with invalid PoP")]
KeyInvalid(Box<VerificationKeyPoP>),
#[error("One signature in the batch is invalid")]
BatchInvalid,
}
#[derive(Debug, Clone, thiserror::Error)]
pub enum StmSignatureError {
#[error("Received index, {0}, is higher than what the security parameter allows, {1}.")]
IndexBoundFailed(u64, u64),
#[error("The claimed evaluation of function phi is incorrect.")]
EvalInvalid([u8; 64]),
#[error("Lottery for this epoch was lost.")]
LotteryLost,
#[error("A provided signature is invalid")]
SignatureInvalid(Signature),
#[error("Batch verification of STM signatures failed")]
BatchInvalid,
#[error("Invalid bytes")]
SerializationError,
}
#[derive(Debug, Clone, thiserror::Error)]
pub enum StmAggregateSignatureError<D: Digest + FixedOutput> {
#[error("Aggregated key does not correspond to the expected key.")]
IvkInvalid(Box<VerificationKey>),
#[error("Invalid bytes")]
SerializationError,
#[error("Batch path does not verify against root")]
PathInvalid(BatchPath<D>),
#[error("Batch verification of STM aggregate signatures failed")]
BatchInvalid,
#[error("Core verification error: {0}")]
CoreVerificationError(#[source] CoreVerifierError),
}
#[derive(Debug, Clone, thiserror::Error)]
pub enum CoreVerifierError {
#[error("No Quorum was found. Expected {0} signatures but got {1}")]
NoQuorum(u64, u64),
#[error("Indices are not unique.")]
IndexNotUnique,
#[error("Aggregate signature is invalid")]
AggregateSignatureInvalid,
#[error("Individual signature is invalid: {0}")]
IndividualSignatureInvalid(#[source] StmSignatureError),
}
#[derive(Debug, Clone, thiserror::Error)]
pub enum AggregationError {
#[error("Not enough signatures. Got only {0} out of {1}.")]
NotEnoughSignatures(u64, u64),
#[error("Invalid usize conversion")]
UsizeConversionInvalid,
}
#[derive(Debug, Clone, thiserror::Error)]
pub enum MerkleTreeError<D: Digest + FixedOutput> {
#[error("Serialization of a merkle tree failed")]
SerializationError,
#[error("Path does not verify against root")]
PathInvalid(Path<D>),
#[error("Batch path does not verify against root")]
BatchPathInvalid(BatchPath<D>),
}
#[derive(Debug, Clone, thiserror::Error, PartialEq, Eq)]
pub enum RegisterError {
#[error("This key has already been registered.")]
KeyRegistered(Box<VerificationKey>),
#[error("The verification of correctness of the supplied key is invalid.")]
KeyInvalid(Box<VerificationKeyPoP>),
#[error("Serialization error")]
SerializationError,
#[error("Initializer not registered. Cannot participate as a signer.")]
UnregisteredInitializer,
}
impl From<MultiSignatureError> for StmSignatureError {
fn from(e: MultiSignatureError) -> Self {
match e {
MultiSignatureError::SerializationError => Self::SerializationError,
MultiSignatureError::SignatureInvalid(e) => Self::SignatureInvalid(e),
MultiSignatureError::BatchInvalid => unreachable!(),
MultiSignatureError::KeyInvalid(_) => unreachable!(),
MultiSignatureError::AggregateSignatureInvalid => unreachable!(),
}
}
}
impl<D: Digest + FixedOutput> From<MerkleTreeError<D>> for StmSignatureError {
fn from(e: MerkleTreeError<D>) -> Self {
match e {
MerkleTreeError::SerializationError => Self::SerializationError,
_ => unreachable!(),
}
}
}
impl<D: Digest + FixedOutput> From<MerkleTreeError<D>> for StmAggregateSignatureError<D> {
fn from(e: MerkleTreeError<D>) -> Self {
match e {
MerkleTreeError::BatchPathInvalid(e) => Self::PathInvalid(e),
MerkleTreeError::SerializationError => Self::SerializationError,
MerkleTreeError::PathInvalid(_e) => unreachable!(),
}
}
}
impl<D: Digest + FixedOutput> From<MultiSignatureError> for StmAggregateSignatureError<D> {
fn from(e: MultiSignatureError) -> Self {
match e {
MultiSignatureError::AggregateSignatureInvalid => {
Self::from(CoreVerifierError::from(e))
}
MultiSignatureError::BatchInvalid => Self::BatchInvalid,
MultiSignatureError::SerializationError => unreachable!(),
MultiSignatureError::KeyInvalid(_) => unreachable!(),
MultiSignatureError::SignatureInvalid(_) => {
Self::CoreVerificationError(CoreVerifierError::from(e))
}
}
}
}
impl<D: Digest + FixedOutput> From<CoreVerifierError> for StmAggregateSignatureError<D> {
fn from(e: CoreVerifierError) -> Self {
Self::CoreVerificationError(e)
}
}
impl<D: Digest + FixedOutput> From<StmSignatureError> for StmAggregateSignatureError<D> {
fn from(e: StmSignatureError) -> Self {
match e {
StmSignatureError::SerializationError => Self::SerializationError,
_ => unreachable!(),
}
}
}
impl From<AggregationError> for CoreVerifierError {
fn from(e: AggregationError) -> Self {
match e {
AggregationError::NotEnoughSignatures(e, _e) => Self::NoQuorum(e, e),
AggregationError::UsizeConversionInvalid => unreachable!(),
}
}
}
impl From<MultiSignatureError> for CoreVerifierError {
fn from(e: MultiSignatureError) -> Self {
match e {
MultiSignatureError::AggregateSignatureInvalid => Self::AggregateSignatureInvalid,
MultiSignatureError::BatchInvalid => unreachable!(),
MultiSignatureError::SerializationError => unreachable!(),
MultiSignatureError::KeyInvalid(_) => unreachable!(),
MultiSignatureError::SignatureInvalid(_e) => unreachable!(),
}
}
}
impl From<StmSignatureError> for CoreVerifierError {
fn from(e: StmSignatureError) -> Self {
CoreVerifierError::IndividualSignatureInvalid(e)
}
}
impl From<MultiSignatureError> for RegisterError {
fn from(e: MultiSignatureError) -> Self {
match e {
MultiSignatureError::SerializationError => Self::SerializationError,
MultiSignatureError::KeyInvalid(e) => Self::KeyInvalid(e),
_ => unreachable!(),
}
}
}
pub(crate) fn blst_err_to_mithril(
e: BLST_ERROR,
sig: Option<Signature>,
) -> Result<(), MultiSignatureError> {
match e {
BLST_ERROR::BLST_SUCCESS => Ok(()),
BLST_ERROR::BLST_VERIFY_FAIL => {
if let Some(s) = sig {
Err(MultiSignatureError::SignatureInvalid(s))
} else {
Err(MultiSignatureError::AggregateSignatureInvalid)
}
}
_ => Err(MultiSignatureError::SerializationError),
}
}