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

Function verify_value

atomic-canonical/src/proof.rs:157–209  ·  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

155/// verifies over `jcs(signing_view)`, (3) the proof's verificationMethod DID
156/// belongs to this key.
157pub fn verify_value(value: &Value, public_key: &PublicKey) -> Result<()> {
158 let obj = value
159 .as_object()
160 .ok_or_else(|| CanonicalError::Proof("value is not a JSON object".into()))?;
161
162 // 1. Content hash integrity.
163 let expected = obj
164 .get(PROP_CONTENT_HASH)
165 .and_then(Value::as_str)
166 .ok_or_else(|| CanonicalError::Proof("node carries no contentHash".into()))?;
167 let actual = hash::content_hash(&hashing_view(value));
168 if expected != actual {
169 return Err(CanonicalError::HashMismatch {
170 expected: expected.to_string(),
171 actual,
172 });
173 }
174
175 // 2. Signature over the canonical signing bytes.
176 let proof: Proof = obj
177 .get(PROP_PROOF)
178 .cloned()
179 .and_then(|p| serde_json::from_value(p).ok())
180 .ok_or_else(|| CanonicalError::Proof("node carries no proof".into()))?;
181
182 // The proof's own metadata is stripped by `signing_view`, so it is not
183 // covered by the signature. Enforce the suite/purpose/type we expect here,
184 // otherwise a stored node's declared cryptosuite is silently mutable.
185 if proof.type_ != PROOF_TYPE
186 || proof.cryptosuite != CRYPTOSUITE
187 || proof.proof_purpose != PROOF_PURPOSE
188 {
189 return Err(CanonicalError::Verification(format!(
190 "unexpected proof metadata: type='{}' cryptosuite='{}' proofPurpose='{}'",
191 proof.type_, proof.cryptosuite, proof.proof_purpose
192 )));
193 }
194
195 let signature = decode_proof_value(&proof.proof_value)?;
196 let signing_bytes = jcs::canonicalize(&signing_view(value)).into_bytes();
197 signature
198 .verify(&signing_bytes, public_key)
199 .map_err(|e| CanonicalError::Verification(e.to_string()))?;
200
201 // 3. The proof's verificationMethod DID must belong to this key.
202 let did = did::did_from_verification_method(&proof.verification_method);
203 if !did::did_matches_public_key(did, public_key) {
204 return Err(CanonicalError::Verification(
205 "verificationMethod DID does not match the public key".into(),
206 ));
207 }
208 Ok(())
209}
210
211/// Produce a fully attested Intent node — a thin wrapper over
212/// [`attest_value`] so hash and signature can never drift from any other node

Callers 6

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