Fix DID derivation and signature generation. #1

fix: fix did derivation and signature generation.

This fixes two bugs that were affecting did derivation and signature generation.

  • The UnsignedOperation and Operation types were not serializing prev as null and were instead skipping serialization when it was None.
  • The DID was being calculated from the hash of the JSON encoding instead of the CBOR encoding.

Note that there is still an issue with using p256 keys. For some reason the did:key serialization for p256 keys is the wrong length.

Changed files
+6 -8
src
+3 -3
src/builder.rs
··· 3 use crate::crypto::SigningKey; 4 use crate::did::Did; 5 use crate::document::ServiceEndpoint; 6 - use crate::encoding::{base32_encode, sha256}; 7 use crate::error::{PlcError, Result}; 8 use crate::operations::{Operation, UnsignedOperation}; 9 use crate::validation::{ ··· 229 230 // The DID is derived from the CID by taking the hash portion 231 // For simplicity, we'll hash the entire serialized operation 232 - let serialized = serde_json::to_vec(operation) 233 - .map_err(|e| PlcError::DagCborError(e.to_string()))?; 234 235 let hash = sha256(&serialized); 236 let encoded = base32_encode(&hash);
··· 3 use crate::crypto::SigningKey; 4 use crate::did::Did; 5 use crate::document::ServiceEndpoint; 6 + use crate::encoding::{base32_encode, dag_cbor_encode, sha256}; 7 use crate::error::{PlcError, Result}; 8 use crate::operations::{Operation, UnsignedOperation}; 9 use crate::validation::{ ··· 229 230 // The DID is derived from the CID by taking the hash portion 231 // For simplicity, we'll hash the entire serialized operation 232 + let serialized = 233 + dag_cbor_encode(operation).map_err(|e| PlcError::DagCborError(e.to_string()))?; 234 235 let hash = sha256(&serialized); 236 let encoded = base32_encode(&hash);
+3 -5
src/operations.rs
··· 30 services: HashMap<String, ServiceEndpoint>, 31 32 /// Previous operation CID (null for genesis) 33 - #[serde(skip_serializing_if = "Option::is_none")] 34 prev: Option<String>, 35 36 /// Base64url-encoded signature ··· 193 services: services.clone(), 194 prev: prev.clone(), 195 }, 196 - Operation::PlcTombstone { prev, .. } => UnsignedOperation::PlcTombstone { 197 - prev: prev.clone(), 198 - }, 199 Operation::LegacyCreate { 200 signing_key, 201 recovery_key, ··· 247 services: HashMap<String, ServiceEndpoint>, 248 249 /// CID of previous operation (None for genesis) 250 - #[serde(skip_serializing_if = "Option::is_none")] 251 prev: Option<String>, 252 }, 253
··· 30 services: HashMap<String, ServiceEndpoint>, 31 32 /// Previous operation CID (null for genesis) 33 prev: Option<String>, 34 35 /// Base64url-encoded signature ··· 192 services: services.clone(), 193 prev: prev.clone(), 194 }, 195 + Operation::PlcTombstone { prev, .. } => { 196 + UnsignedOperation::PlcTombstone { prev: prev.clone() } 197 + } 198 Operation::LegacyCreate { 199 signing_key, 200 recovery_key, ··· 246 services: HashMap<String, ServiceEndpoint>, 247 248 /// CID of previous operation (None for genesis) 249 prev: Option<String>, 250 }, 251