json_digest/
lib.rs

1#![warn(missing_docs)]
2
3//! This library provides some algorithms to calculate cryptographically secure digests of JSON documents.
4//! Since JSON is an ambiguous serialization format, we also had to define a canonical deterministic subset
5//! of all allowed documents. Order of keys in an object and Unicode normalization are well-defined in this
6//! subset, making it suitable for hashing.
7//!
8//! ```
9//! let data = serde_json::json!({
10//!   "address": {
11//!     "value": "6 Unter den Linden, Berlin, Germany",
12//!     "nonce": "uN_FTaYe8JM-EZ8SU94kAOf0k0YvnhLcZgdpQ3BU9Ymbu"
13//!   },
14//!   "dateOfBirth": {
15//!     "value": "16/02/2002",
16//!     "nonce": "ufxkENKgXuf4yG50p6xpSyaQ8Gz7KsuqXid2yw533TUMK"
17//!   },
18//!   "placeOfBirth": {
19//!     "city": "Berlin",
20//!     "country": "Germany",
21//!     "nonce": "ukhFsI4a6vIZEDUOBRxJmLroPEQ8FQCjJwbI-Z7bEocGo"
22//!   },
23//! });
24//!
25//! let digest = json_digest::digest_data(&data).unwrap();
26//! assert_eq!(digest, "cjuQR3pDJeaiRv9oCZ-fBE7T8QWpUGfjP40sAXq0bLwr-8");
27//!
28//! let partial_digest = json_digest::selective_digest_data(&data, ".dateOfBirth").unwrap();
29//! let expected_partial_digest = serde_json::json!({
30//!   "address": "cjuvIf1PmPH_31JN5XqJ1xkcNDJyiw9zQ-7ansSB78gnt4",
31//!   "dateOfBirth": {
32//!     "nonce": "ufxkENKgXuf4yG50p6xpSyaQ8Gz7KsuqXid2yw533TUMK",
33//!     "value":"16/02/2002"
34//!   },
35//!   "placeOfBirth": "cjub0Nxb0Kz0pI4bWCdSbaCutk1s5qieFT-ZmqUU1xcuAc"
36//! });
37//! assert_eq!(partial_digest, serde_json::to_string(&expected_partial_digest).unwrap());
38//!
39//! let digest_from_partial = json_digest::digest_json_str(&partial_digest).unwrap();
40//! assert_eq!(digest, digest_from_partial);
41//! ```
42
43mod digest;
44pub mod json_path;
45mod nonce;
46
47pub use digest::*;
48pub use nonce::*;
49
50use std::collections::HashMap;
51
52use anyhow::{bail, ensure, Result};
53use serde::{Deserialize, Serialize};