Generic attest over a JSON-LD value — the *one* canonicalization/signing path all typed nodes share. Fills `attributedTo` (from the identity's `did:atomic`) when absent, computes the content hash over `hashing_view`, signs `jcs(signing_view)`, and attaches the proof. Returns the value.
(mut value: Value, identity: &Identity, keypair: &KeyPair)
| 60 | /// `did:atomic`) when absent, computes the content hash over `hashing_view`, |
| 61 | /// signs `jcs(signing_view)`, and attaches the proof. Returns the value. |
| 62 | pub fn attest_value(mut value: Value, identity: &Identity, keypair: &KeyPair) -> Value { |
| 63 | let did = did::did_for_public_key(&identity.public_key); |
| 64 | |
| 65 | if let Some(obj) = value.as_object_mut() { |
| 66 | // Fill attributedTo only if there is no non-empty value already. |
| 67 | let has_author = obj |
| 68 | .get(PROP_ATTRIBUTED_TO) |
| 69 | .and_then(Value::as_str) |
| 70 | .map(|s| !s.is_empty()) |
| 71 | .unwrap_or(false); |
| 72 | if !has_author { |
| 73 | obj.insert(PROP_ATTRIBUTED_TO.to_string(), Value::String(did.clone())); |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | // Hash first (over the value without proof/contentHash), then sign (over |
| 78 | // the value with contentHash, without proof). |
| 79 | let content_hash = hash::content_hash(&hashing_view(&value)); |
| 80 | if let Some(obj) = value.as_object_mut() { |
| 81 | obj.insert(PROP_CONTENT_HASH.to_string(), Value::String(content_hash)); |
| 82 | } |
| 83 | |
| 84 | let signing_bytes = jcs::canonicalize(&signing_view(&value)).into_bytes(); |
| 85 | let signature = Signer::new(keypair).sign(&signing_bytes); |
| 86 | let proof = Proof { |
| 87 | type_: PROOF_TYPE.to_string(), |
| 88 | cryptosuite: CRYPTOSUITE.to_string(), |
| 89 | verification_method: did::verification_method(&did), |
| 90 | proof_purpose: PROOF_PURPOSE.to_string(), |
| 91 | proof_value: encode_proof_value(&signature), |
| 92 | }; |
| 93 | if let Some(obj) = value.as_object_mut() { |
| 94 | obj.insert( |
| 95 | PROP_PROOF.to_string(), |
| 96 | serde_json::to_value(proof).expect("proof serialization is infallible"), |
| 97 | ); |
| 98 | } |
| 99 | value |
| 100 | } |
| 101 | |
| 102 | /// Generic verify over a JSON-LD value — the same three checks as the typed |
| 103 | /// path: (1) the content hash recomputes over `hashing_view`, (2) the signature |