bc_envelope/
lib.rs

1#![doc(html_root_url = "https://docs.rs/bc-envelope/0.27.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.27.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 return
73//!   its predicate, else return `None`.
74//! * [`Envelope::as_object`] If the envelope’s subject is an assertion return its
75//!   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 return
82//!   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_envelope`] Wraps an envelope in a new envelope.
148//! * [`Envelope::unwrap_envelope`] 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
168//!   notation, 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 and
202//!   returns a new envelope with a `'signed': Signature` assertion.
203//! * [`Envelope::add_signature_opt`] Creates a signature for the envelope's subject
204//!   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
212//!   envelope's subject and returns a new envelope with a `'signed':
213//!   Signature` assertion.
214//!
215//! ### Verifying by returning a boolean
216//!
217//! * [`Envelope::is_verified_signature`] Returns whether the given signature is
218//!   valid.
219//! * [`Envelope::has_signature_from`] Returns whether the envelope's subject
220//!   has a valid signature from the given public key.
221//! * [`Envelope::has_signatures_from`] Returns whether the envelope's subject
222//!   has a set of signatures.
223//! * [`Envelope::has_signatures_from_threshold`] Returns whether the envelope's
224//!   subject has some threshold of signatures.
225//!
226//! ### Verifying by returning a result
227//!
228//! * [`Envelope::verify_signature`] Checks whether the given signature is valid
229//!   for the given public key.
230//! * [`Envelope::verify_signature_from`] Checks whether the envelope's subject
231//!   has a valid signature from the given public key.
232//! * [`Envelope::verify_signatures_from`] Checks whether the envelope's subject
233//!   has a set of signatures.
234//! * [`Envelope::verify_signatures_from_threshold`] Checks whether the
235//!   envelope's subject has some threshold of signatures.
236//!
237//! ### Helpers
238//!
239//! * [`Envelope::verify_signature`] Returns an array of `Signature`s from all of the
240//!   envelope's `signed` predicates.
241//! * [`Envelope::make_signed_assertion`] Convenience constructor for a
242//!   `signed: Signature` assertion envelope.
243//!
244//! # Splitting Envelopes with SSKR
245//!
246//! * [`Envelope::sskr_split`] Splits the envelope into a set of SSKR shares.
247//! * [`Envelope::sskr_join`] Creates a new envelope resulting from the joining
248//!   a set of envelopes split by SSKR.
249//!
250//! # Encryption
251//!
252//! * [`Envelope::encrypt_subject`] Returns a new envelope with its subject
253//!   encrypted.
254//! * [`Envelope::decrypt_subject`] Returns a new envelope with its subject
255//!   decrypted.
256//!
257//! # Public Key Encryption
258//!
259//! * [`Envelope::add_recipient`] Returns a new envelope with an added
260//!   `hasRecipient: SealedMessage` assertion.
261//! * [`Envelope::recipients`] Returns an array of `SealedMessage`s from all of
262//!   the envelope's `hasRecipient` assertions.
263//! * [`Envelope::encrypt_subject_to_recipients`] Returns an new envelope with
264//!   its subject encrypted and a `hasRecipient`
265//! * [`Envelope::encrypt_subject_to_recipient`] Returns a new envelope with its
266//!   subject encrypted and a `hasRecipient` assertion added for the
267//!   `recipient`.
268//! * [`Envelope::decrypt_to_recipient`] Returns a new envelope with its subject
269//!   decrypted using the recipient's `PrivateKeyBase`.
270//!
271//! # Compression
272//!
273//! * [`Envelope::compress`] Returns the compressed variant of this envelope.
274//! * [`Envelope::uncompress`] Returns the uncompressed variant of this
275//!   envelope.
276//! * [`Envelope::compress_subject`] Returns this envelope with its subject
277//!   compressed.
278//! * [`Envelope::uncompress_subject`] Returns this envelope with its subject
279//!   uncompressed.
280//!
281//! # Eliding, Encrypting, or Compressing Parts of an Envelope
282//!
283//! * [`Envelope::elide`] Returns the elided variant of this envelope.
284//!
285//! * Returns a version of this envelope with the given element(s) elided:
286//!     * [`Envelope::elide_removing_set`]
287//!     * [`Envelope::elide_removing_array`]
288//!     * [`Envelope::elide_removing_target`]
289//!
290//! * Returns a version with all elements except the given element(s) elided:
291//!     * [`Envelope::elide_revealing_set`]
292//!     * [`Envelope::elide_revealing_array`]
293//!     * [`Envelope::elide_revealing_target`]
294//!
295//! * As above, but takes a boolean to determine whether to remove or reveal:
296//!     * [`Envelope::elide_set`]
297//!     * [`Envelope::elide_array`]
298//!     * [`Envelope::elide_target`]
299//!
300//! * Returns a version with the given element(s) elided, encrypted, or
301//!     compressed:
302//!     * [`Envelope::elide_removing_set_with_action`]
303//!     * [`Envelope::elide_removing_array_with_action`]
304//!     * [`Envelope::elide_removing_target_with_action`]
305//!
306//! * Returns a version with all elements except the given element(s) elided,
307//!     encrypted, or compressed:
308//!     * [`Envelope::elide_revealing_set_with_action`]
309//!     * [`Envelope::elide_revealing_array_with_action`]
310//!     * [`Envelope::elide_revealing_target_with_action`]
311//!
312//! * As above, but takes a boolean to determine whether to remove or reveal:
313//!     * [`Envelope::elide_set_with_action`]
314//!     * [`Envelope::elide_array_with_action`]
315//!     * [`Envelope::elide_target_with_action`]
316//!
317//! * [`Envelope::unelide`] Returns the unelided variant of this envelope, given
318//!   the envelope that was elided.
319//!
320//! # Decorrelating Envelopes using Salt
321//!
322//! * [`Envelope::add_salt`] Add a number of bytes of salt generally
323//!   proportionate to the size of the object being salted.
324//! * [`Envelope::add_salt_with_len`] Add a specified number of bytes of salt.
325//! * [`Envelope::add_salt_in_range`] Add a number of bytes of salt chosen
326//!   randomly from the given range.
327//!
328//! # Walking an Envelope's Hierarchy
329//!
330//! * [`Envelope::walk`] Walk the envelope, calling the visitor function for
331//!   each element.
332//!
333//! # Envelope Expressions
334//!
335//! ### Constructing Expressions, Requests, and Responses
336//!
337//! * [`Expression::new`] Creates an envelope with a `«function»`
338//!   subject.
339//! * [`Parameter::new_named`] Creates a new envelope containing a
340//!   `❰parameter❱: value` assertion.
341//! * [`Parameter::new_known`] Optionally adds a `❰parameter❱:
342//!   value` assertion to the envelope.
343//! * [`ExpressionBehavior::with_parameter`] Adds a `❰parameter❱: value` assertion to the
344//!   envelope.
345//! * [`ExpressionBehavior::with_optional_parameter`] Optionally adds a `❰parameter❱:
346//!   value` assertion to the envelope.
347//! * [`Request::new`] Creates an envelope with an `ARID` subject and a
348//!   `body: «function»` assertion.
349//! * [`Response::new_success`] Creates an envelope with an `ARID` subject and a
350//!   `result: value` assertion.
351//! * [`Response::new_success`] Creates an envelope with an `ARID`
352//!   subject and a `result: value` assertion for each provided result.
353//! * [`Response::new_failure`] Creates an envelope with an `ARID`
354//!   subject and a `error: value` assertion.
355//! * [`Response::new_early_failure`] Creates an envelope with an `unknown`
356//!   subject and a `error: value` assertion.
357//!
358//! ### Decoding Parameters and Results
359//!
360//! * [`ExpressionBehavior::extract_object_for_parameter`] Returns the argument for the
361//!   given parameter, decoded as the given type.
362//! * [`ExpressionBehavior::extract_objects_for_parameter`] Returns an array of arguments
363//!   for the given parameter, decoded as the given type.
364//! * [`ResponseBehavior::result`] Returns the object of the `result` predicate.
365//! * [`ResponseBehavior::result`] Returns the objects of every `result` predicate.
366//! * [`ResponseBehavior::extract_result`] Returns the object of the `result` predicate,
367//!   decoded as the given type.
368//! * [`ResponseBehavior::extract_result`] Returns the objects of every `result`
369//!   predicate, decoded as the given type.
370//! * [`ResponseBehavior::extract_result`] Returns whether the `result` predicate has the
371//!   `KnownValue` `.ok`.
372//! * [`ResponseBehavior::extract_error`] Returns the error value, decoded as the given type.
373
374pub mod base;
375pub use base::elide::{ self, ObscureAction };
376pub use base::walk::{ self, EdgeType };
377pub use base::{ register_tags, register_tags_in, FormatContext, GLOBAL_FORMAT_CONTEXT };
378pub use base::{ Assertion, Envelope, EnvelopeEncodable, Error, Result };
379
380pub mod extension;
381pub mod prelude;
382pub mod seal;
383
384mod string_utils;
385
386#[cfg(feature = "signature")]
387pub use bc_components::{ Signer, Verifier };
388
389#[cfg(feature = "signature")]
390pub use extension::SignatureMetadata;
391
392#[cfg(feature = "recipient")]
393pub use bc_components::{ EncapsulationPrivateKey, Encrypter, SigningOptions };
394
395#[cfg(feature = "recipient")]
396pub use bc_components::{ PrivateKeyBase, PublicKeys };
397
398#[cfg(feature = "known_value")]
399pub use known_values::{ self, KnownValue, KnownValuesStore, KNOWN_VALUES };
400
401#[cfg(feature = "known_value")]
402/// Converts a KnownValue to an Envelope.
403impl EnvelopeEncodable for KnownValue {
404    fn into_envelope(self) -> Envelope {
405        Envelope::new_with_known_value(self)
406    }
407}
408
409#[cfg(feature = "expression")]
410pub use extension::expressions::{
411    functions,
412    parameters,
413    Event,
414    EventBehavior,
415    Expression,
416    ExpressionBehavior,
417    Function,
418    IntoExpression,
419    Parameter,
420    Request,
421    RequestBehavior,
422    Response,
423    ResponseBehavior,
424};
425
426#[cfg(feature = "attachment")]
427pub use extension::attachment::{ Attachments, Attachable };