use did::{
did_details::{DidPublicKey, DidPublicKeyDetails},
DidSignature,
};
use frame_support::ensure;
use sp_core::ConstU32;
use sp_runtime::{traits::SaturatedConversion, BoundedVec};
use sp_std::vec::Vec;
use crate::{
merkle_proofs::v0::{
input_common::TimeBoundDidSignature,
output_common::{DidKeyRelationship, DipOriginInfo, RevealedDidKey, RevealedDidMerkleProofLeaf},
},
Error,
};
#[cfg(test)]
mod tests;
#[derive(Debug, PartialEq, Eq)]
#[cfg_attr(test, derive(Clone))]
pub struct DipRevealedDetailsAndUnverifiedDidSignature<
KiltDidKeyId,
KiltAccountId,
KiltBlockNumber,
KiltWeb3Name,
KiltLinkableAccountId,
ConsumerBlockNumber,
const MAX_REVEALED_LEAVES_COUNT: u32,
> {
pub(crate) revealed_leaves: BoundedVec<
RevealedDidMerkleProofLeaf<KiltDidKeyId, KiltAccountId, KiltBlockNumber, KiltWeb3Name, KiltLinkableAccountId>,
ConstU32<MAX_REVEALED_LEAVES_COUNT>,
>,
pub(crate) signature: TimeBoundDidSignature<ConsumerBlockNumber>,
}
impl<
KiltDidKeyId,
KiltAccountId,
KiltBlockNumber,
KiltWeb3Name,
KiltLinkableAccountId,
ConsumerBlockNumber,
const MAX_REVEALED_LEAVES_COUNT: u32,
>
DipRevealedDetailsAndUnverifiedDidSignature<
KiltDidKeyId,
KiltAccountId,
KiltBlockNumber,
KiltWeb3Name,
KiltLinkableAccountId,
ConsumerBlockNumber,
MAX_REVEALED_LEAVES_COUNT,
> where
ConsumerBlockNumber: PartialOrd,
{
pub fn verify_signature_time(
self,
block_number: &ConsumerBlockNumber,
) -> Result<
DipRevealedDetailsAndVerifiedDidSignatureFreshness<
KiltDidKeyId,
KiltAccountId,
KiltBlockNumber,
KiltWeb3Name,
KiltLinkableAccountId,
MAX_REVEALED_LEAVES_COUNT,
>,
Error,
> {
ensure!(self.signature.valid_until >= *block_number, Error::InvalidSignatureTime);
Ok(DipRevealedDetailsAndVerifiedDidSignatureFreshness {
revealed_leaves: self.revealed_leaves,
signature: self.signature.signature,
})
}
}
#[derive(Debug, PartialEq, Eq)]
pub struct DipRevealedDetailsAndVerifiedDidSignatureFreshness<
KiltDidKeyId,
KiltAccountId,
KiltBlockNumber,
KiltWeb3Name,
KiltLinkableAccountId,
const MAX_REVEALED_LEAVES_COUNT: u32,
> {
pub(crate) revealed_leaves: BoundedVec<
RevealedDidMerkleProofLeaf<KiltDidKeyId, KiltAccountId, KiltBlockNumber, KiltWeb3Name, KiltLinkableAccountId>,
ConstU32<MAX_REVEALED_LEAVES_COUNT>,
>,
pub(crate) signature: DidSignature,
}
impl<
KiltDidKeyId,
KiltAccountId,
KiltBlockNumber,
KiltWeb3Name,
KiltLinkableAccountId,
const MAX_REVEALED_LEAVES_COUNT: u32,
>
DipRevealedDetailsAndVerifiedDidSignatureFreshness<
KiltDidKeyId,
KiltAccountId,
KiltBlockNumber,
KiltWeb3Name,
KiltLinkableAccountId,
MAX_REVEALED_LEAVES_COUNT,
>
{
pub fn retrieve_signing_leaves_for_payload(
self,
payload: &[u8],
) -> Result<
DipOriginInfo<
KiltDidKeyId,
KiltAccountId,
KiltBlockNumber,
KiltWeb3Name,
KiltLinkableAccountId,
MAX_REVEALED_LEAVES_COUNT,
>,
Error,
> {
let revealed_verification_keys = self.revealed_leaves.iter().filter(|leaf| {
matches!(
leaf,
RevealedDidMerkleProofLeaf::DidKey(RevealedDidKey {
relationship: DidKeyRelationship::Verification(_),
..
})
)
});
let signing_leaves_indices: Vec<_> = revealed_verification_keys
.enumerate()
.filter(|(_, revealed_verification_key)| {
let RevealedDidMerkleProofLeaf::DidKey(RevealedDidKey {
details:
DidPublicKeyDetails {
key: DidPublicKey::PublicVerificationKey(verification_key),
..
},
..
}) = revealed_verification_key
else {
return false;
};
verification_key.verify_signature(payload, &self.signature).is_ok()
})
.map(|(index, _)| u32::saturated_from(index))
.collect();
ensure!(!signing_leaves_indices.is_empty(), Error::InvalidDidKeyRevealed);
let signing_leaves_indices_vector = signing_leaves_indices.try_into().map_err(|_| {
log::error!(target: "dip::consumer::DipRevealedDetailsAndVerifiedDidSignatureFreshnessV0", "Failed to convert vector of signing leaf indices into BoundedVec<u8, {MAX_REVEALED_LEAVES_COUNT}>.");
Error::Internal
})?;
Ok(DipOriginInfo {
revealed_leaves: self.revealed_leaves,
signing_leaves_indices: signing_leaves_indices_vector,
})
}
}