MCPcopy Create free account
hub / github.com/atomicdotdev/atomic / verify_value

Function verify_value

atomic-canonical/src/proof.rs:106–158  ·  view source on GitHub ↗

Generic verify over a JSON-LD value — the same three checks as the typed path: (1) the content hash recomputes over `hashing_view`, (2) the signature verifies over `jcs(signing_view)`, (3) the proof's verificationMethod DID belongs to this key.

(value: &Value, public_key: &PublicKey)

Source from the content-addressed store, hash-verified

104/// verifies over `jcs(signing_view)`, (3) the proof's verificationMethod DID
105/// belongs to this key.
106pub fn verify_value(value: &Value, public_key: &PublicKey) -> Result<()> {
107 let obj = value
108 .as_object()
109 .ok_or_else(|| CanonicalError::Proof("value is not a JSON object".into()))?;
110
111 // 1. Content hash integrity.
112 let expected = obj
113 .get(PROP_CONTENT_HASH)
114 .and_then(Value::as_str)
115 .ok_or_else(|| CanonicalError::Proof("node carries no contentHash".into()))?;
116 let actual = hash::content_hash(&hashing_view(value));
117 if expected != actual {
118 return Err(CanonicalError::HashMismatch {
119 expected: expected.to_string(),
120 actual,
121 });
122 }
123
124 // 2. Signature over the canonical signing bytes.
125 let proof: Proof = obj
126 .get(PROP_PROOF)
127 .cloned()
128 .and_then(|p| serde_json::from_value(p).ok())
129 .ok_or_else(|| CanonicalError::Proof("node carries no proof".into()))?;
130
131 // The proof's own metadata is stripped by `signing_view`, so it is not
132 // covered by the signature. Enforce the suite/purpose/type we expect here,
133 // otherwise a stored node's declared cryptosuite is silently mutable.
134 if proof.type_ != PROOF_TYPE
135 || proof.cryptosuite != CRYPTOSUITE
136 || proof.proof_purpose != PROOF_PURPOSE
137 {
138 return Err(CanonicalError::Verification(format!(
139 "unexpected proof metadata: type='{}' cryptosuite='{}' proofPurpose='{}'",
140 proof.type_, proof.cryptosuite, proof.proof_purpose
141 )));
142 }
143
144 let signature = decode_proof_value(&proof.proof_value)?;
145 let signing_bytes = jcs::canonicalize(&signing_view(value)).into_bytes();
146 signature
147 .verify(&signing_bytes, public_key)
148 .map_err(|e| CanonicalError::Verification(e.to_string()))?;
149
150 // 3. The proof's verificationMethod DID must belong to this key.
151 let did = did::did_from_verification_method(&proof.verification_method);
152 if !did::did_matches_public_key(did, public_key) {
153 return Err(CanonicalError::Verification(
154 "verificationMethod DID does not match the public key".into(),
155 ));
156 }
157 Ok(())
158}
159
160/// Produce a fully attested Intent node — a thin wrapper over
161/// [`attest_value`] so hash and signature can never drift from any other node

Callers 4

verify_provFunction · 0.85
verifyFunction · 0.85
verify_memoryFunction · 0.85

Calls 10

ProofClass · 0.85
content_hashFunction · 0.85
hashing_viewFunction · 0.85
decode_proof_valueFunction · 0.85
canonicalizeFunction · 0.85
signing_viewFunction · 0.85
did_matches_public_keyFunction · 0.85
getMethod · 0.65
verifyMethod · 0.45