bitwark/
lib.rs

1//! # 🛡️ Bitwark: Binary Bulwark in Rust
2//! Bitwark is a cryptographic Rust library (used ring, ed25519-dalek, blake3), designed to facilitate secure digital interactions through a meticulous amalgamation of lightweight binary JWT tokens, dynamic key rotation, and strategic salt functionalities, all embedded in a minimalistic API.
3//! Through Bitwark, developers can seamlessly perform crucial security operations, such as key and salt generation, payload signing, and integrity message verification, all whilst ensuring optimal performance and security in their applications.
4//!
5//! ## 🚀 Getting Started
6//! Engage in a fortified cryptographic experience with Bitwark, utilizing functionalities like secure payload creation, signature encoding, and strategic key rotation with simplicity and efficacy.
7//!
8//! ### 🔐 Key Features:
9//! * **Compact Tokens**: Uses binary format for signed payloads, saving space compared to traditional JWTs.
10//! * **Advanced Encryption**: Employs EdDSA with Blake3 for robust signing and verification out of the box.
11//! * **Dynamic Key Rotation**: Simplifies the process to update keys and salts, keeping your security measures up-to-date.
12//! * **Enhanced Security with Salting**: Adds random data to payloads, making it tougher for attackers to crack.
13//! * **Performance Optimized**: Designed to be lightweight, ensuring your applications run smoothly under pressure.
14//!
15//! ## Signed Payload decoded as binary (alternative to JWT)
16//! ```
17//! # use bitwark::{exp::AutoExpiring, signed_exp::ExpiringSigned, salt::{Salt64,SaltInfo}, keys::{ed::EdDsaKey}};
18//! # use serde::{Serialize, Deserialize};
19//! # use chrono::Duration;
20//! #[derive(Serialize,Deserialize, Clone)]
21//! pub struct Claims {
22//!     pub permissions: Vec<String>,
23//! }
24//! // Generate an EdDSA key pair with a validity period of 10 minutes and a salt with a validity of 5 minutes.
25//! let exp_key = AutoExpiring::<EdDsaKey>::generate(
26//!     Duration::minutes(10)
27//! ).unwrap();
28//! let exp_salt = AutoExpiring::<Salt64>::generate(
29//!     Duration::minutes(5)
30//! ).unwrap();
31//!
32//! // Instantiate a token with specified claims.
33//! let claims = Claims { permissions: vec!["users:read".to_string(), "users:write".to_string()]};
34//! let token = ExpiringSigned::<Claims>::new(Duration::seconds(120), claims).unwrap();
35//!
36//! // Create a binary encoding of the token, signed with the key and salt.
37//! let signed_token_bytes = token.encode_and_sign_salted(exp_salt.as_bytes(), &*exp_key)
38//!     .expect("Failed to sign token");
39//!
40//! // Decode the token and verify its signature and validity.
41//! let decoded_token = ExpiringSigned::<Claims>::decode_and_verify_salted(
42//!     &signed_token_bytes, exp_salt.as_bytes(), &*exp_key
43//! ).expect("Failed to decode a token");
44//! assert_eq!(2, decoded_token.permissions.len(), "Failed to find 2 permissions");
45//! ```
46//! ## Key Generation and Management
47//! Bitwark enables the generation and rotation of cryptographic keys, ensuring persistent security through periodic key renewals.
48//! ```
49//! # use bitwark::keys::ed::EdDsaKey;
50//! # use bitwark::Generator;
51//! // Generate an EdDSA key pair.
52//! let key = EdDsaKey::generate().unwrap();
53//! ```
54//! ## Key Rotation for Enhanced Security
55//! Effortlessly manage and rotate your keys, maintaining a fresh and secure application environment through time-based key expiration and renewals.
56//! ```
57//! # use bitwark::keys::ed::EdDsaKey;
58//! # use bitwark::Rotation;
59//! # use bitwark::exp::AutoExpiring;
60//! # use bitwark::Generator;
61//! # use chrono::Duration;
62//! let key = EdDsaKey::generate().unwrap();
63//! let mut expiring_key = AutoExpiring::new(Duration::seconds(10), key).unwrap();
64//! if expiring_key.is_expired() {
65//!     // update key internally
66//!     expiring_key.rotate().unwrap();
67//! }
68//! ```
69//!
70//! ## Payload Creation and Management
71//! Construct, encode, and decode secure payloads, ensuring message integrity through signature verification.
72//! ```
73//! # use bitwark::keys::ed::EdDsaKey;
74//! # use bitwark::exp::AutoExpiring;
75//! # use bitwark::keys::{BwVerifier, BwSigner};
76//! # use bitwark::payload::SignedPayload;
77//! # use bitwark::Generator;
78//! # use chrono::Duration;
79//! let key = EdDsaKey::generate().unwrap();
80//! // Construct a payload.
81//! let payload = SignedPayload::<String>::new("A signed message".to_string());
82//!
83//! // Encode the payload.
84//! let signed_payload_bytes = payload.encode_and_sign(&key).unwrap();
85//!
86//! // Decode, verifying the signature.
87//! let decoded_payload = SignedPayload::<String>::decode_and_verify(&signed_payload_bytes, &key).unwrap();
88//! assert_eq!(*decoded_payload, *payload);
89//! ```
90//!
91//! ## Salting
92//! The `Salt[N]` struct can be utilized to generate random salts which are pivotal in
93//! cryptographic operations to safeguard against various forms of attack and to ensure
94//! that identical inputs do not produce identical outputs across different users or sessions.
95//!
96//! ### Salt variants
97//! * `Salt126` - 126 bytes length
98//! * `Salt64`
99//! * `Salt32`
100//! * `Salt16`
101//! * `Salt12`
102//!
103//! ```
104//! use bitwark::salt::Salt64;
105//! use bitwark::Generator;
106//!
107//! let salt1 = Salt64::generate().unwrap();
108//! let salt2 = Salt64::generate().unwrap();
109//!
110//! // Assert that different generated salts are not equal.
111//! // In cryptographic operations, unique salts are pivotal to secure storage and transmission.
112//! assert_ne!(*salt1, *salt2, "Salts should be unique across generations.");
113//! ```
114//!
115//! Salts can also be seamlessly integrated into rotation operations, frequently refreshing
116//! them to enhance security further. This is particularly valuable in contexts where the
117//! same data might be encrypted multiple times, ensuring each instance yields different ciphertext.
118//!
119//! Example with Rotation (Assuming `Expiring` is a structure which utilizes the `Rotation` trait):
120//!
121//! ```
122//! use bitwark::{salt::{Salt64, SaltInfo}, exp::AutoExpiring, keys::ed::EdDsaKey, Rotation, Generator};
123//! use bitwark::payload::SignedPayload;
124//! use chrono::Duration;
125//!
126//! // Make a new salt.
127//! let salt = Salt64::generate().unwrap();
128//!
129//! // Make a salt that lasts for 10 seconds.
130//! let mut expiring_salt = AutoExpiring::<Salt64>::new(Duration::seconds(10), salt).unwrap();
131//!
132//! // Change the salt if it's too old.
133//! if expiring_salt.is_expired() {
134//!     expiring_salt.rotate().expect("Salt rotation failed.");
135//! }
136//!
137//! // Make a key that lasts for 120 seconds.
138//! let key = AutoExpiring::<EdDsaKey>::generate(Duration::seconds(120)).unwrap();
139//! // Make a payload for signing
140//! let payload = SignedPayload::<String>::new("Hello, world!".to_string());
141//!
142//! // Combine the message and a special code (signature) into one piece.
143//! let signature_bytes = payload.encode_and_sign_salted(expiring_salt.as_bytes(), &*key).expect("Failed to encode");
144//!
145//! // Separate the message and the signature, checking they're valid.
146//! let decoded_result = SignedPayload::<String>::decode_and_verify_salted(&signature_bytes, expiring_salt.as_bytes(), &*key);
147//! assert!(decoded_result.is_ok());
148//! ```
149//!
150//! Using salts and rotating them regularly strengthens security by ensuring
151//! that even repeated data or credentials produce different hashes or ciphertexts
152//! across different instances or sessions.
153//!
154pub use error::BwError;
155
156pub mod error;
157pub mod exp;
158pub mod keys;
159pub mod payload;
160pub mod salt;
161pub mod signed_exp;
162
163/// The `Generator` trait defines a common interface for types that require
164/// a generation phase, typically resulting in the instantiation of a unique
165/// or random state.
166///
167/// # Example
168///
169/// ```
170/// # use bitwark::Generator;
171/// # use bitwark::keys::ed::EdDsaKey;
172/// let generated_key = EdDsaKey::generate().expect("Key generation failed");
173/// ```
174///
175/// Implementing `Generator` trait for your own types enables the structured
176/// creation of instances, particularly in cryptographic or secure contexts
177/// where randomness or uniqueness is crucial.
178pub trait Generator {
179    /// Generates and returns an instance of the implementing type.
180    ///
181    /// # Errors
182    ///
183    /// Returns [`crate::BwError`] in cases where generation
184    /// fails, e.g., due to insufficient system entropy, internal failures, etc.
185    fn generate() -> Result<Self, BwError>
186    where
187        Self: Sized;
188}
189
190/// The `Rotation` trait encapsulates the best practice of rotating
191/// cryptographic or sensitive materials, minimizing the potential
192/// impact of key compromise or algorithmic predictions.
193///
194/// Secure systems often implement rotation to limit the utility
195/// of compromised keys and to periodically refresh cryptographic
196/// materials, ensuring persistent protection against evolving threats.
197///
198/// # Example
199///
200/// ```
201/// # use bitwark::{Generator, Rotation};
202/// # use bitwark::keys::ed::EdDsaKey;
203/// # use bitwark::exp::AutoExpiring;
204/// # use chrono::Duration;
205///
206/// let key = EdDsaKey::generate().expect("Key generation failed");
207/// let mut expiring_key = AutoExpiring::new(Duration::seconds(10), key).unwrap();
208/// expiring_key.rotate().expect("Key generation failed");
209/// ```
210///
211/// # Good Practices
212///
213/// Implement the `Rotation` trait for entities in your application
214/// where periodical change or refreshment is vital for sustaining
215/// security, especially for cryptographic keys, tokens, or salts.
216pub trait Rotation {
217    fn rotate(&mut self) -> Result<(), BwError>;
218}