dig_identity/lib.rs
1//! # dig-identity — the canonical DIG decentralized-identity profile format
2//!
3//! A DIG identity is an **identity anchor** (a Chia `did:chia:` singleton in v1) PAIRED with a
4//! chip35 DataLayer store that holds the anchor's **profile**. The profile is a **sparse merkle
5//! tree** of standard SLOTS — one fixed 256-bit position per field — so any implementation reads
6//! and writes the same bytes, and any field can be proved (or proved absent) against a single
7//! 32-byte root.
8//!
9//! The format core is **CHAIN-INDEPENDENT** (no chain calls, no chip35 dependency). WU3 adds on-chain
10//! DID resolution as a caller-supplied [`ChainSource`] TRAIT seam ([`resolve`]), so the crate still
11//! holds no network dependency and builds unchanged for wasm / no-network targets. The v2 **BLS
12//! identity key model** ([`bls`], SPEC §6a) — the single BLS12-381 G1 key that does both sign (G2)
13//! and seal-DH (G1) — is behind the default-on `bls` feature, so the pure format layer still builds
14//! with `default-features = false`. The DID→dig-store minting driver (WU2) remains a follow-on.
15//!
16//! ## What lives here
17//!
18//! | Concern | Module |
19//! |---|---|
20//! | Slot ids, the v1 slot map, slot-key derivation | [`slot`] |
21//! | The `tag ‖ len ‖ bytes` value encoding | [`value`] |
22//! | sha256 primitives + the SMT node hasher | [`hash`] |
23//! | The mutable tree: set/get/root/prove | [`tree`] |
24//! | Serializable proofs + root-only verification | [`proof`] |
25//! | The profile reader/writer + key resolution | [`profile`] / [`keys`] |
26//! | The identity anchor (DID) + discovery parse | [`did`] |
27//! | The canonical XCH receive-address field codec | [`xch`] |
28//! | The DID↔store bidirectional-pairing predicate + ownership proof | [`pairing`] |
29//! | Composed "this datum belongs to this DID" verification | [`verify`] |
30//! | On-chain DID→profile resolution over a caller [`ChainSource`] (WU3) | [`resolve`] |
31//! | The BLS12-381 G1 identity key model: derivation + sign/seal primitives (§6a) | [`bls`] |
32//! | The fail-closed store-update-authority predicate (owner or valid delegate) | [`authority`] |
33//!
34//! ## Proving a field against a root
35//!
36//! ```
37//! use dig_identity::{Profile, Value, slot::standard, proof};
38//!
39//! let mut profile = Profile::with_schema_v2();
40//! profile.set(standard::DISPLAY_NAME, Value::Utf8("Ada".into()));
41//!
42//! let tree = profile.build_tree().unwrap();
43//! let root = tree.root();
44//!
45//! // Prove the display name equals "Ada" using only (root, proof).
46//! let membership = tree.prove_membership(standard::DISPLAY_NAME).unwrap();
47//! let claim = Value::Utf8("Ada".into());
48//! assert!(proof::verify_membership(&root, standard::DISPLAY_NAME, &claim, &membership).unwrap());
49//!
50//! // Prove no peer id is present.
51//! let absent = tree.prove_non_membership(standard::PEER_ID).unwrap();
52//! assert!(proof::verify_non_membership(&root, standard::PEER_ID, &absent).unwrap());
53//! ```
54
55pub mod authority;
56#[cfg(feature = "bls")]
57pub mod bls;
58pub mod did;
59pub mod error;
60pub mod hash;
61pub mod identity_profile;
62pub mod keys;
63pub mod pairing;
64pub mod profile;
65pub mod proof;
66pub mod resolve;
67pub mod slot;
68pub mod tree;
69pub mod value;
70pub mod verify;
71pub mod xch;
72
73pub use authority::{DelegationKind, StoreUpdateAuthority, WriterDelegation};
74pub use did::{parse_did_from_description, Did};
75pub use error::{Error, Result};
76pub use identity_profile::IdentityProfile;
77pub use keys::DidKeys;
78pub use pairing::{
79 evaluate_pairing, is_authoritative_profile, store_belongs_to_did, IdentitySingleton,
80 PairingOutcome, SingletonLineage, StoreOwnershipProof, StoreRecord,
81};
82
83// Re-export the canonical Chia types the public API speaks, so consumers pin the same versions.
84pub use chia_protocol::{Bytes32, Coin};
85pub use profile::{resolve_did_keys, Profile};
86pub use proof::{verify_membership, verify_non_membership, ProfileProof};
87// The WU3 on-chain resolution seam. The chain `resolve_did_keys` stays module-qualified
88// (`resolve::resolve_did_keys`) to avoid colliding with the networkless [`profile::resolve_did_keys`].
89pub use resolve::{
90 resolve_bls_public_key, resolve_identity_profile, ChainSource, ChainStoreState, ResolveError,
91};
92// The BLS12-381 G1 identity key model (§6a), behind the default-on `bls` feature.
93#[cfg(feature = "bls")]
94pub use bls::{
95 derive_identity_sk, derive_identity_sk_at, g1_dh, g1_subgroup_check,
96 master_secret_key_from_seed, public_key_bytes, sign_message, verify_signature,
97 IDENTITY_DERIVATION_PATH,
98};
99pub use slot::SlotId;
100pub use tree::ProfileTree;
101pub use value::{Value, ValueTag};
102pub use verify::{verify_profile_field_absent_for_did, verify_profile_field_for_did};
103pub use xch::{is_valid_xch_address, parse_xch_address};