1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//! 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);
//! # }
//! ```
extern crate alloc;