use serde::{Deserialize, Serialize};
use crate::sidetree::{json_canonicalization_scheme, DIDSuffix, Delta, PublicKeyJwk, Sidetree};
use super::{jws_decode_verify_inner, PartialVerificationError, SidetreeOperation};
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub struct UpdateOperation {
pub did_suffix: DIDSuffix,
pub reveal_value: String,
pub delta: Delta,
pub signed_data: String,
}
#[derive(Debug, Clone)]
pub struct PartiallyVerifiedUpdateOperation {
pub reveal_value: String,
pub signed_delta: Delta,
pub signed_update_key: PublicKeyJwk,
}
impl SidetreeOperation for UpdateOperation {
type PartiallyVerifiedForm = PartiallyVerifiedUpdateOperation;
fn partial_verify<S: Sidetree>(
self,
) -> Result<PartiallyVerifiedUpdateOperation, PartialVerificationError> {
let (header, claims) =
jws_decode_verify_inner(&self.signed_data, |claims: &UpdateClaims| {
&claims.update_key
})?;
if header.algorithm != S::SIGNATURE_ALGORITHM {
return Err(PartialVerificationError::InvalidSignatureAlgorithm);
}
let canonicalized_public_key = json_canonicalization_scheme(&claims.update_key).unwrap();
let computed_reveal_value = S::reveal_value(canonicalized_public_key.as_bytes());
if self.reveal_value != computed_reveal_value {
return Err(PartialVerificationError::RevealValueMismatch {
computed: computed_reveal_value,
found: self.reveal_value,
});
}
let delta_string = json_canonicalization_scheme(&self.delta).unwrap();
let delta_hash = S::hash(delta_string.as_bytes());
if claims.delta_hash != delta_hash {
return Err(PartialVerificationError::DeltaHashMismatch);
}
Ok(PartiallyVerifiedUpdateOperation {
reveal_value: self.reveal_value,
signed_delta: self.delta,
signed_update_key: claims.update_key,
})
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct UpdateClaims {
pub update_key: PublicKeyJwk,
pub delta_hash: String,
}