bc_envelope/
lib.rs

1#![doc(html_root_url = "https://docs.rs/bc-envelope/0.40.0")]
2#![warn(rust_2018_idioms)]
3
4//! # Gordian Envelope: A Flexible Container for Structured Data
5//!
6//! ## Introduction
7//!
8//! The [Gordian
9//! Envelope](https://www.blockchaincommons.com/introduction/Envelope-Intro/)
10//! protocol specifies a structured format for hierarchical binary data focused
11//! on the ability to transmit it in a privacy-focused way. Envelopes are
12//! designed to facilitate "smart documents" and have a number of unique
13//! features including: easy representation of a variety of semantic structures,
14//! a built-in Merkle-like digest tree, deterministic representation using CBOR,
15//! and the ability for the holder of a document to selectively encrypt or elide
16//! specific parts of a document without invalidating the document structure
17//! including the digest tree, or any cryptographic signatures that rely on it.
18//!
19//! ## Getting Started
20//!
21//! ```toml
22//! [dependencies]
23//! bc-envelope = "0.40.0"
24//! ```
25//!
26//! ## Specification
27//!
28//! Gordian Envelope is currently specified in [this IETF Internet
29//! Draft](https://datatracker.ietf.org/doc/draft-mcnally-envelope/).
30//!
31//! Envelopes are immutable. You create "mutations" by creating new envelopes
32//! from old envelopes.
33//!
34//! # Basic Envelope Creation
35//!
36//! * [`Envelope::new`] Creates an envelope with a `subject`.
37//! * [`Envelope::new_assertion`] Creates an assertion envelope with a
38//!   `predicate` and `object`.
39//!
40//! # Adding Assertions
41//!
42//! ### Adding Assertions with a Predicate and Object
43//!
44//! * [`Envelope::add_assertion`] Adds an assertion to an envelope.
45//! * [`Envelope::add_assertion_salted`] Adds an optionally salted assertion to
46//!   an envelope.
47//! * [`Envelope::add_optional_assertion`] Optionally adds an assertion to an
48//!   envelope.
49//!
50//! ### Adding Assertions with an Assertion Envelope
51//!
52//! * [`Envelope::add_assertion_envelope`] Adds an assertion envelope to an
53//!   envelope.
54//! * [`Envelope::add_assertion_envelope_salted`] Adds an optionally salted
55//!   assertion envelope to an envelope.
56//! * [`Envelope::add_assertion_envelopes`] Adds a vector of assertion envelopes
57//!   to an envelope.
58//! * [`Envelope::add_optional_assertion_envelope_salted`] Optionally adds an
59//!   assertion envelope to an envelope.
60//!
61//! # Removing and Replacing Assertions
62//!
63//! * [`Envelope::remove_assertion`] Removes an assertion from an envelope.
64//! * [`Envelope::replace_assertion`] Replaces an assertion in an envelope.
65//! * [`Envelope::replace_subject`] Replaces the subject of an envelope.
66//!
67//! # Queries
68//!
69//! ### Getting the basic parts of an envelope
70//!
71//! * [`Envelope::subject`] Returns the subject of an envelope.
72//! * [`Envelope::as_predicate`] If the envelope’s subject is an assertion
73//!   return its predicate, else return `None`.
74//! * [`Envelope::as_object`] If the envelope’s subject is an assertion return
75//!   its object, else return `None`.
76//!
77//! ### Getting assertions on an envelope
78//!
79//! * [`Envelope::assertions`] Returns the assertions of an envelope.
80//! * [`Envelope::has_assertions`] Returns whether an envelope has assertions.
81//! * [`Envelope::as_assertion`] If the envelope’s subject is an assertion
82//!   return it, else return `None`.
83//!
84//! ### Getting the specific types of an envelope
85//!
86//! * [`Envelope::as_leaf`] The envelope’s leaf CBOR object, or `None` if the
87//!   envelope is not a leaf.
88//! * [`Envelope::as_known_value`] The envelope’s known value, or `None` if the
89//!   envelope is not a known value.
90//!
91//! ### Determining the type of an envelope
92//!
93//! * [`Envelope::is_leaf`] Returns whether an envelope is a leaf.
94//! * [`Envelope::is_node`] Returns whether an envelope is a node (whether it
95//!   has at least one assertion).
96//! * [`Envelope::is_wrapped`] Returns whether an envelope is wrapped.
97//! * [`Envelope::is_known_value`] Returns whether an envelope is a known value.
98//! * [`Envelope::is_assertion`] Returns whether an envelope is an assertion.
99//! * [`Envelope::is_encrypted`] Returns whether an envelope is encrypted.
100//! * [`Envelope::is_compressed`] Returns whether an envelope is compressed.
101//! * [`Envelope::is_elided`] Returns whether an envelope is elided.
102//!
103//! ### Determining the type of an envelope’s subject
104//!
105//! * [`Envelope::is_subject_assertion`] Returns whether an envelope’s subject
106//!   is an assertion.
107//! * [`Envelope::is_subject_encrypted`] Returns whether an envelope’s subject
108//!   is encrypted.
109//! * [`Envelope::is_subject_compressed`] Returns whether an envelope’s subject
110//!   is compressed.
111//! * [`Envelope::is_subject_elided`] Returns whether an envelope’s subject is
112//!   elided.
113//! * [`Envelope::is_subject_obscured`] Returns whether an envelope’s subject is
114//!   obscured.
115//!
116//! ### Getting assertions and parts of assertions
117//!
118//! * [`Envelope::assertion_with_predicate`] Returns the assertion with the
119//!   given predicate.
120//! * [`Envelope::assertions_with_predicate`] Returns all assertions with the
121//!   given predicate.
122//! * [`Envelope::object_for_predicate`] Returns the object of the assertion
123//!   with the given predicate.
124//! * [`Envelope::objects_for_predicate`] Returns the objects of all assertions
125//!   with the matching predicate.
126//! * [`Envelope::elements_count`] Returns the number of elements in the
127//!   envelope.
128//!
129//! ### Extracting parts of envelopes as specific types
130//!
131//! * [`Envelope::extract_subject`] Returns the envelope’s subject, decoded as
132//!   the given type.
133//! * [`Envelope::extract_object_for_predicate`] Returns the object of the
134//!   assertion with the given predicate, decoded as the given type.
135//! * [`Envelope::extract_objects_for_predicate`] Returns the objects of all
136//!   assertions with the matching predicate, decoded as the given type.
137//!
138//! ### Other queries
139//!
140//! * [`Envelope::is_internal`] Returns whether an envelope is internal, that
141//!   is, if it has child elements.
142//! * [`Envelope::is_obscured`] Returns whether an envelope is obscured (elided,
143//!   encrypted, or compressed).
144//!
145//! # Wrapping and Unwrapping Envelopes
146//!
147//! * [`Envelope::wrap`] Wraps an envelope in a new envelope.
148//! * [`Envelope::try_unwrap`] Unwraps an envelope.
149//!
150//! # Formatting Envelopes
151//!
152//! ### Envelope notation
153//!
154//! * [`Envelope::format`] Formats an envelope in envelope notation.
155//! * [`Envelope::format_opt`] Formats an envelope in envelope notation, with
156//!   optional annotations.
157//!
158//! ### Tree notation
159//!
160//! * [`Envelope::tree_format`] Formats an envelope in envelope tree notation.
161//! * [`Envelope::tree_format_with_target`] Formats an envelope in envelope tree
162//!   notation, highlighting a target set of elements.
163//!
164//! ### CBOR diagnostic notation
165//!
166//! * [`Envelope::diagnostic`] Formats an envelope in CBOR diagnostic notation.
167//! * [`Envelope::diagnostic`] Formats an envelope in CBOR diagnostic notation,
168//!   with optional annotations.
169//!
170//! ### CBOR hexadecimal notation
171//!
172//! * [`Envelope::hex`] Formats an envelope in CBOR hexadecimal notation.
173//! * [`Envelope::hex_opt`] Formats an envelope in CBOR hexadecimal notation,
174//!   with optional annotations.
175//!
176//! # Working with the Digest Tree
177//!
178//! ### Semantic equivalence
179//!
180//! * [`bc_components::DigestProvider::digest`] Returns the digest of an
181//!   envelope.
182//! * [`Envelope::digests`] Returns the set of digests contained in the
183//!   envelope’s elements, down to the specified level.
184//! * [`Envelope::deep_digests`] Returns the set of all digests in the envelope.
185//! * [`Envelope::shallow_digests`] Returns the set of all digests in the
186//!   envelope, down to its second level.
187//! * [`Envelope::is_equivalent_to`] Tests two envelopes for semantic
188//!   equivalence.
189//!
190//! ### Structural identicality
191//!
192//! * [`Envelope::structural_digest`] Produce a value that will necessarily be
193//!   different if two envelopes differ structurally, even if they are
194//!   semantically equivalent.
195//! * [`Envelope::is_identical_to`] Tests two envelopes for structural equality.
196//!
197//! # Signing and Verifying Signatures
198//!
199//! ### Signing
200//!
201//! * [`Envelope::add_signature`] Creates a signature for the envelope's subject
202//!   and returns a new envelope with a `'signed': Signature` assertion.
203//! * [`Envelope::add_signature_opt`] Creates a signature for the envelope's
204//!   subject and returns a new envelope with a `'signed': Signature` assertion.
205//! * [`Envelope::add_signatures`] Creates several signatures for the envelope's
206//!   subject and returns a new envelope with additional `'signed': Signature`
207//!   assertions.
208//! * [`Envelope::add_signatures_opt`] Creates several signatures for the
209//!   envelope's subject and returns a new envelope with additional `'signed':
210//!   Signature` assertions.
211//! * [`Envelope::add_signature`] Creates a signature for the envelope's subject
212//!   and returns a new envelope with a `'signed': Signature` assertion.
213//!
214//! ### Verifying by returning a boolean
215//!
216//! * [`Envelope::is_verified_signature`] Returns whether the given signature is
217//!   valid.
218//! * [`Envelope::has_signature_from`] Returns whether the envelope's subject
219//!   has a valid signature from the given public key.
220//! * [`Envelope::has_signatures_from`] Returns whether the envelope's subject
221//!   has a set of signatures.
222//! * [`Envelope::has_signatures_from_threshold`] Returns whether the envelope's
223//!   subject has some threshold of signatures.
224//!
225//! ### Verifying by returning a result
226//!
227//! * [`Envelope::verify_signature`] Checks whether the given signature is valid
228//!   for the given public key.
229//! * [`Envelope::verify_signature_from`] Checks whether the envelope's subject
230//!   has a valid signature from the given public key.
231//! * [`Envelope::verify_signatures_from`] Checks whether the envelope's subject
232//!   has a set of signatures.
233//! * [`Envelope::verify_signatures_from_threshold`] Checks whether the
234//!   envelope's subject has some threshold of signatures.
235//!
236//! ### Helpers
237//!
238//! * [`Envelope::verify_signature`] Returns an array of `Signature`s from all
239//!   of the envelope's `signed` predicates.
240//! * [`Envelope::make_signed_assertion`] Convenience constructor for a `signed:
241//!   Signature` assertion envelope.
242//!
243//! # Splitting Envelopes with SSKR
244//!
245//! * [`Envelope::sskr_split`] Splits the envelope into a set of SSKR shares.
246//! * [`Envelope::sskr_join`] Creates a new envelope resulting from the joining
247//!   a set of envelopes split by SSKR.
248//!
249//! # Encryption
250//!
251//! * [`Envelope::encrypt_subject`] Returns a new envelope with its subject
252//!   encrypted.
253//! * [`Envelope::decrypt_subject`] Returns a new envelope with its subject
254//!   decrypted.
255//!
256//! # Public Key Encryption
257//!
258//! * [`Envelope::add_recipient`] Returns a new envelope with an added
259//!   `hasRecipient: SealedMessage` assertion.
260//! * [`Envelope::recipients`] Returns an array of `SealedMessage`s from all of
261//!   the envelope's `hasRecipient` assertions.
262//! * [`Envelope::encrypt_subject_to_recipients`] Returns an new envelope with
263//!   its subject encrypted and a `hasRecipient`
264//! * [`Envelope::encrypt_subject_to_recipient`] Returns a new envelope with its
265//!   subject encrypted and a `hasRecipient` assertion added for the
266//!   `recipient`.
267//! * [`Envelope::decrypt_to_recipient`] Returns a new envelope with its subject
268//!   decrypted using the recipient's `PrivateKeyBase`.
269//!
270//! # Compression
271//!
272//! * [`Envelope::compress`] Returns the compressed variant of this envelope.
273//! * [`Envelope::decompress`] Returns the decompressed variant of this
274//!   envelope.
275//! * [`Envelope::compress_subject`] Returns this envelope with its subject
276//!   compressed.
277//! * [`Envelope::decompress_subject`] Returns this envelope with its subject
278//!   decompressed.
279//!
280//! # Eliding, Encrypting, or Compressing Parts of an Envelope
281//!
282//! * [`Envelope::elide`] Returns the elided variant of this envelope.
283//!
284//! * Returns a version of this envelope with the given element(s) elided:
285//!     * [`Envelope::elide_removing_set`]
286//!     * [`Envelope::elide_removing_array`]
287//!     * [`Envelope::elide_removing_target`]
288//!
289//! * Returns a version with all elements except the given element(s) elided:
290//!     * [`Envelope::elide_revealing_set`]
291//!     * [`Envelope::elide_revealing_array`]
292//!     * [`Envelope::elide_revealing_target`]
293//!
294//! * As above, but takes a boolean to determine whether to remove or reveal:
295//!     * [`Envelope::elide_set`]
296//!     * [`Envelope::elide_array`]
297//!     * [`Envelope::elide_target`]
298//!
299//! * Returns a version with the given element(s) elided, encrypted, or
300//!   compressed:
301//!     * [`Envelope::elide_removing_set_with_action`]
302//!     * [`Envelope::elide_removing_array_with_action`]
303//!     * [`Envelope::elide_removing_target_with_action`]
304//!
305//! * Returns a version with all elements except the given element(s) elided,
306//!   encrypted, or compressed:
307//!     * [`Envelope::elide_revealing_set_with_action`]
308//!     * [`Envelope::elide_revealing_array_with_action`]
309//!     * [`Envelope::elide_revealing_target_with_action`]
310//!
311//! * As above, but takes a boolean to determine whether to remove or reveal:
312//!     * [`Envelope::elide_set_with_action`]
313//!     * [`Envelope::elide_array_with_action`]
314//!     * [`Envelope::elide_target_with_action`]
315//!
316//! * [`Envelope::unelide`] Returns the unelided variant of this envelope, given
317//!   the envelope that was elided.
318//!
319//! # Decorrelating Envelopes using Salt
320//!
321//! * [`Envelope::add_salt`] Add a number of bytes of salt generally
322//!   proportionate to the size of the object being salted.
323//! * [`Envelope::add_salt_with_len`] Add a specified number of bytes of salt.
324//! * [`Envelope::add_salt_in_range`] Add a number of bytes of salt chosen
325//!   randomly from the given range.
326//!
327//! # Walking an Envelope's Hierarchy
328//!
329//! * [`Envelope::walk`] Walk the envelope, calling the visitor function for
330//!   each element.
331//!
332//! # Envelope Expressions
333//!
334//! ### Constructing Expressions, Requests, and Responses
335//!
336//! * [`Expression::new`] Creates an envelope with a `«function»` subject.
337//! * [`Parameter::new_named`] Creates a new envelope containing a `❰parameter❱:
338//!   value` assertion.
339//! * [`Parameter::new_known`] Optionally adds a `❰parameter❱: value` assertion
340//!   to the envelope.
341//! * [`ExpressionBehavior::with_parameter`] Adds a `❰parameter❱: value`
342//!   assertion to the envelope.
343//! * [`ExpressionBehavior::with_optional_parameter`] Optionally adds a
344//!   `❰parameter❱: value` assertion to the envelope.
345//! * [`Request::new`] Creates an envelope with an `ARID` subject and a `body:
346//!   «function»` assertion.
347//! * [`Response::new_success`] Creates an envelope with an `ARID` subject and a
348//!   `result: value` assertion.
349//! * [`Response::new_success`] Creates an envelope with an `ARID` subject and a
350//!   `result: value` assertion for each provided result.
351//! * [`Response::new_failure`] Creates an envelope with an `ARID` subject and a
352//!   `error: value` assertion.
353//! * [`Response::new_early_failure`] Creates an envelope with an `unknown`
354//!   subject and a `error: value` assertion.
355//!
356//! ### Decoding Parameters and Results
357//!
358//! * [`ExpressionBehavior::extract_object_for_parameter`] Returns the argument
359//!   for the given parameter, decoded as the given type.
360//! * [`ExpressionBehavior::extract_objects_for_parameter`] Returns an array of
361//!   arguments for the given parameter, decoded as the given type.
362//! * [`ResponseBehavior::result`] Returns the object of the `result` predicate.
363//! * [`ResponseBehavior::result`] Returns the objects of every `result`
364//!   predicate.
365//! * [`ResponseBehavior::extract_result`] Returns the object of the `result`
366//!   predicate, decoded as the given type.
367//! * [`ResponseBehavior::extract_result`] Returns the objects of every `result`
368//!   predicate, decoded as the given type.
369//! * [`ResponseBehavior::extract_result`] Returns whether the `result`
370//!   predicate has the `KnownValue` `.ok`.
371//! * [`ResponseBehavior::extract_error`] Returns the error value, decoded as
372//!   the given type.
373
374pub mod base;
375pub use base::{
376    Assertion, Envelope, EnvelopeCase, EnvelopeEncodable, Error, Result,
377    elide::{self, ObscureAction},
378    walk::{self, EdgeType},
379};
380
381pub mod format;
382pub use format::{
383    DigestDisplayFormat, EnvelopeSummary, FormatContext, FormatContextOpt,
384    GLOBAL_FORMAT_CONTEXT, MermaidFormatOpts, MermaidOrientation, MermaidTheme,
385    TreeFormatOpts, register_tags, register_tags_in,
386};
387
388pub mod extension;
389pub mod prelude;
390pub mod seal;
391
392mod string_utils;
393
394#[cfg(feature = "recipient")]
395pub use bc_components::{
396    EncapsulationPrivateKey, Encrypter, PrivateKeyBase, PublicKeys,
397};
398#[cfg(feature = "signature")]
399pub use bc_components::{Signer, SigningOptions, Verifier};
400#[cfg(feature = "signature")]
401pub use extension::SignatureMetadata;
402#[cfg(feature = "known_value")]
403pub use known_values::{self, KNOWN_VALUES, KnownValue, KnownValuesStore};
404
405#[cfg(feature = "known_value")]
406/// Converts a KnownValue to an Envelope.
407impl EnvelopeEncodable for KnownValue {
408    fn into_envelope(self) -> Envelope { Envelope::new_with_known_value(self) }
409}
410
411#[cfg(feature = "attachment")]
412pub use extension::attachment::{Attachable, Attachments};
413#[cfg(feature = "expression")]
414pub use extension::expressions::{
415    Event, EventBehavior, Expression, ExpressionBehavior, Function,
416    IntoExpression, Parameter, Request, RequestBehavior, Response,
417    ResponseBehavior, functions, parameters,
418};