Skip to main content

lys_core/
lib.rs

1//! `lys-core` — domain-agnostic cryptographic trust primitives.
2//!
3//! A focused library of trust primitives: certificate authority operations,
4//! Merkle transparency-log operations, signed attestations, sealed payload
5//! transport, and Ed25519 key management. Consumers compose domain meaning
6//! on top — this crate knows nothing about any higher-level concepts.
7//!
8//! The foundation laid here is [`TrustError`], [`TrustResult`], and
9//! [`Ed25519Identity`]. The [`ca`], [`merkle`], [`attestation`], `receipt`,
10//! `bundle`, `delegation`, [`seal`], [`checkpoint`], and [`tlog`] modules are
11//! implemented on top of these primitives. (`receipt`, `bundle` and
12//! `delegation` are named without intra-doc links because they exist only under
13//! `unstable-anchor`; a link from ungated docs to a gated item resolves under
14//! `--all-features` and breaks in the default doc build, which is the shape
15//! consumers get.)
16//!
17//! ```
18//! use lys_core::TrustResult;
19//!
20//! fn fallible_op() -> TrustResult<()> {
21//!     Ok(())
22//! }
23//!
24//! assert!(fallible_op().is_ok());
25//! ```
26
27// Library code contains no unsafe whatsoever, and no test in this crate uses
28// unsafe code either. Non-test builds forbid it outright; test builds are held
29// by the workspace-level `deny`, which no test overrides.
30#![cfg_attr(not(test), forbid(unsafe_code))]
31
32pub mod attestation;
33#[cfg(feature = "unstable-anchor")]
34pub mod bundle;
35pub mod ca;
36mod cbor;
37pub mod checkpoint;
38#[cfg(feature = "unstable-anchor")]
39pub mod delegation;
40pub mod error;
41pub mod keys;
42pub mod merkle;
43#[cfg(feature = "unstable-anchor")]
44pub mod receipt;
45pub mod seal;
46pub mod tlog;
47
48pub use error::{TrustError, TrustResult};
49pub use keys::Ed25519Identity;
50
51/// Lowercase hex encoding of a byte slice.
52pub(crate) fn hex_lower(bytes: &[u8]) -> String {
53    const DIGITS: &[u8; 16] = b"0123456789abcdef";
54    let mut s = String::with_capacity(bytes.len() * 2);
55    for &b in bytes {
56        s.push(char::from(DIGITS[usize::from(b >> 4)]));
57        s.push(char::from(DIGITS[usize::from(b & 0x0f)]));
58    }
59    s
60}