Rust and WASM did-method-plc tools and structures

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.

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