use crate::macros::pattern;
use ed25519::Signature;
use ed25519_dalek::SignatureError;
use ed25519_dalek::Verifier;
use ed25519_dalek::VerifyingKey;
use itertools::Itertools;
use crate::blob::encodings::simplearchive::SimpleArchive;
use crate::blob::Blob;
use crate::inline::Inline;
use crate::query::find;
use crate::trible::TribleSet;
pub enum ValidationError {
AmbiguousSignature,
MissingSignature,
FailedValidation,
}
impl From<SignatureError> for ValidationError {
fn from(_: SignatureError) -> Self {
ValidationError::FailedValidation
}
}
pub fn verify(content: Blob<SimpleArchive>, metadata: TribleSet) -> Result<(), ValidationError> {
let handle = content.get_handle();
let (pubkey, r, s) = match find!(
(pubkey: Inline<_>, r, s),
pattern!(&metadata, [
{
super::content: handle,
crate::attestation::signed_by: ?pubkey,
crate::attestation::signature_r: ?r,
crate::attestation::signature_s: ?s
}]))
.at_most_one()
{
Ok(Some(result)) => result,
Ok(None) => return Err(ValidationError::MissingSignature),
Err(_) => return Err(ValidationError::AmbiguousSignature),
};
let pubkey: VerifyingKey = pubkey.try_from_inline()?;
let signature = Signature::from_components(r, s);
pubkey.verify(&content.bytes, &signature)?;
Ok(())
}