evidence 0.1.0

Type-level tags for cryptographic primitives
Documentation
//! Type-level tags for cryptographic primitives.
//!
//! `evidence` provides wrapper types like [`Digest<T, P, C>`](digest::Digest),
//! [`Signed<T, S, C>`](signed::Signed), and [`Encrypted<T, E, C>`](encrypted::Encrypted)
//! that wrap cryptographic output (hashes, signatures, ciphertext) with phantom
//! type parameters encoding type-level information about them. The parameters
//! are never stored at runtime — they exist only at compile time to prevent
//! misuse:
//!
//! - `T` tracks _what_ was hashed, signed, or encrypted
//! - `P`/`S`/`E` tracks _which_ algorithm was used (e.g., SHA-256, Ed25519)
//! - `C` tracks _how_ the value was serialized before the operation
//!
//! Because these parameters are part of the type, the compiler rejects
//! mistakes like comparing a `Digest<User, Sha256, _>` to a
//! `Digest<Post, Sha256, _>`, or verifying a signature against the
//! wrong key type — all at zero runtime cost.
//!
//! # Digest Example
//!
//! ```
//! # #[cfg(feature = "sha2")]
//! # {
//! use evidence::digest::{Digest, sha2::Sha256};
//! use evidence::codec::Identity;
//!
//! // Distinct types for different data
//! struct User([u8; 4]);
//! struct Post([u8; 4]);
//!
//! impl AsRef<[u8]> for User {
//!     fn as_ref(&self) -> &[u8] { &self.0 }
//! }
//!
//! impl AsRef<[u8]> for Post {
//!     fn as_ref(&self) -> &[u8] { &self.0 }
//! }
//!
//! let user = User([1, 2, 3, 4]);
//! let post = Post([5, 6, 7, 8]);
//!
//! // These are different types — can't be mixed up!
//! let user_hash: Digest<User, Sha256, Identity> = Digest::hash(&user);
//! let post_hash: Digest<Post, Sha256, Identity> = Digest::hash(&post);
//!
//! // Compile error if uncommented: mismatched types
//! // let _: Digest<User, Sha256, Identity> = post_hash;
//! # }
//! ```
//!
//! # Cargo Features
//!
//! All features are opt-in. No features are enabled by default.
//!
//! | Feature            | Provides |
//! |--------------------|----------|
//! | `sha2`             | `Sha256`, `Sha384`, `Sha512` |
//! | `sha3`             | `Sha3_224`, `Sha3_256`, `Sha3_384`, `Sha3_512`, `Keccak256`, `Keccak512` |
//! | `blake3`           | `Blake3` |
//! | `ed25519`          | `Ed25519` signature primitive + `Signer`/`AsyncSigner` impl |
//! | `hmac`             | `HmacSha256`, `HmacSha384`, `HmacSha512` |
//! | `chacha20poly1305` | `ChaCha20Poly1305` AEAD |
//! | `aes-gcm`          | `Aes128Gcm`, `Aes256Gcm` AEAD |
//! | `minicbor`         | `Cbor` codec `Encode`/`Decode` impls |
//! | `serde_json`       | `Json` codec `Encode`/`Decode` impls (requires `std`) |
//! | `serde`            | `Serialize`/`Deserialize` impls |
//! | `rkyv`             | Zero-copy `Archive`/`Serialize`/`Deserialize` impls |
//! | `arbitrary`        | `Arbitrary` impl for fuzzing |
//! | `bolero`           | `TypeGenerator` impl for bolero |
//! | `proptest`         | `Arbitrary` impl for proptest (requires `std`) |
//!
//! # Signature Example
//!
//! ```
//! # #[cfg(feature = "ed25519")]
//! # {
//! use evidence::{codec::Identity, signature::{ed25519::Ed25519, Signer}, signed::Signed, verified::Verified};
//!
//! let signing_key = ed25519_dalek::SigningKey::from_bytes(&[1u8; 32]);
//! let data = b"hello world";
//!
//! // Sign the data
//! let signed: Signed<[u8; 11], Ed25519, Identity> = Signed::seal(&signing_key, data);
//!
//! // Payload is inaccessible until verified
//! let verified: Verified<[u8; 11], Ed25519, Identity> = signed.try_verify().unwrap();
//! assert_eq!(verified.payload(), data);
//! # }
//! ```

#![no_std]
#![forbid(unsafe_code)]

extern crate alloc;

pub mod codec;
pub mod digest;
pub mod encrypted;
pub mod encryption;
pub mod fingerprint;
pub mod mac;
pub mod signature;
pub mod signed;
pub mod verified;