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 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
//! # 🛡️ Bitwark: Binary Bulwark in Rust
//! Bitwark is a cryptographic Rust library (used ring, ed25519-dalek), 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.
//! 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.
//!
//! ## 🚀 Getting Started
//! Engage in a fortified cryptographic experience with Bitwark, utilizing functionalities like secure payload creation, signature encoding, and strategic key rotation with simplicity and efficacy.
//!
//! ### 🔐 Key Features:
//! * *Binary* Signed Payload: Compact binary encoding of signed payload (similar to JWT)
//! * *Default* Cryptography: Bitwark by default uses EdDSA for signing and verifying with SHA3-384 (EdDSA_SHA3-384).
//! * *Rotation* Easily rotate keys and salts, ensuring your application adapts to the dynamic security landscape.
//! * *Salting*: Random data injection to increase entropy and slow brute force attacks.
//! * *Lightweight*: Minimal overhead, ensuring optimal performance even in high-throughput scenarios.
//!
//! ## Signed Payload decoded as binary (alternative to JWT)
//! ```
//! # use bitwark::{exp::AutoExpiring, signed_exp::ExpiringSigned, salt::Salt64, keys::{ed::EdDsaKey}};
//! # use serde::{Serialize, Deserialize};
//! # use chrono::Duration;
//! #[derive(Serialize,Deserialize)]
//! pub struct Claims {
//! pub permissions: Vec<String>,
//! }
//! // Generate an EdDSA key pair with a validity period of 10 minutes and a salt with a validity of 5 minutes.
//! let exp_key = AutoExpiring::<EdDsaKey>::generate(
//! Duration::minutes(10)
//! ).unwrap();
//! let exp_salt = AutoExpiring::<Salt64>::generate(
//! Duration::minutes(5)
//! ).unwrap();
//!
//! // Instantiate a token with specified claims.
//! let claims = Claims { permissions: vec!["users:read".to_string(), "users:write".to_string()]};
//! let token = ExpiringSigned::<Claims>::new(Duration::seconds(120), claims).unwrap();
//!
//! // Create a binary encoding of the token, signed with the key and salt.
//! let signed_token_bytes = token.encode_and_sign_salted(&exp_salt, &*exp_key)
//! .expect("Failed to sign token");
//!
//! // Decode the token and verify its signature and validity.
//! let decoded_token = ExpiringSigned::<Claims>::decode_and_verify_salted(
//! &signed_token_bytes, &exp_salt, &*exp_key
//! ).expect("Failed to decode a token");
//! assert_eq!(2, decoded_token.permissions.len(), "Failed to find 2 permissions");
//! ```
//! ## Key Generation and Management
//! Bitwark enables the generation and rotation of cryptographic keys, ensuring persistent security through periodic key renewals.
//! ```
//! # use bitwark::keys::ed::EdDsaKey;
//! # use bitwark::Generator;
//! // Generate an EdDSA key pair.
//! let key = EdDsaKey::generate().unwrap();
//! ```
//! ## Key Rotation for Enhanced Security
//! Effortlessly manage and rotate your keys, maintaining a fresh and secure application environment through time-based key expiration and renewals.
//! ```
//! # use bitwark::keys::ed::EdDsaKey;
//! # use bitwark::Rotation;
//! # use bitwark::exp::AutoExpiring;
//! # use bitwark::Generator;
//! # use chrono::Duration;
//! let key = EdDsaKey::generate().unwrap();
//! let mut expiring_key = AutoExpiring::new(Duration::seconds(10), key).unwrap();
//! if expiring_key.is_expired() {
//! // update key internally
//! expiring_key.rotate().unwrap();
//! }
//! ```
//!
//! ## Payload Creation and Management
//! Construct, encode, and decode secure payloads, ensuring message integrity through signature verification.
//! ```
//! # use bitwark::keys::ed::EdDsaKey;
//! # use bitwark::exp::AutoExpiring;
//! # use bitwark::keys::{BwVerifier, BwSigner};
//! # use bitwark::payload::SignedPayload;
//! # use bitwark::Generator;
//! # use chrono::Duration;
//! let key = EdDsaKey::generate().unwrap();
//! // Construct a payload.
//! let payload = SignedPayload::<String>::new("A signed message".to_string());
//!
//! // Encode the payload.
//! let signed_payload_bytes = payload.encode(&key).unwrap();
//!
//! // Decode, verifying the signature.
//! let decoded_payload = SignedPayload::<String>::decode(&signed_payload_bytes, &key).unwrap();
//! assert_eq!(*decoded_payload, *payload);
//! ```
//!
//! ## Salting
//! The `Salt[N]` struct can be utilized to generate random salts which are pivotal in
//! cryptographic operations to safeguard against various forms of attack and to ensure
//! that identical inputs do not produce identical outputs across different users or sessions.
//!
//! ### Salt variants
//! * `Salt126` - 126 bytes length
//! * `Salt64`
//! * `Salt32`
//! * `Salt16`
//! * `Salt12`
//!
//! ```
//! use bitwark::salt::Salt64;
//! use bitwark::Generator;
//!
//! let salt1 = Salt64::generate().unwrap();
//! let salt2 = Salt64::generate().unwrap();
//!
//! // Assert that different generated salts are not equal.
//! // In cryptographic operations, unique salts are pivotal to secure storage and transmission.
//! assert_ne!(*salt1, *salt2, "Salts should be unique across generations.");
//! ```
//!
//! Salts can also be seamlessly integrated into rotation operations, frequently refreshing
//! them to enhance security further. This is particularly valuable in contexts where the
//! same data might be encrypted multiple times, ensuring each instance yields different ciphertext.
//!
//! Example with Rotation (Assuming `Expiring` is a structure which utilizes the `Rotation` trait):
//!
//! ```
//! use bitwark::{salt::Salt64, exp::AutoExpiring, keys::ed::EdDsaKey, Rotation, Generator};
//! use bitwark::payload::SignedPayload;
//! use chrono::Duration;
//!
//! // Make a new salt.
//! let salt = Salt64::generate().unwrap();
//!
//! // Make a salt that lasts for 10 seconds.
//! let mut expiring_salt = AutoExpiring::<Salt64>::new(Duration::seconds(10), salt).unwrap();
//!
//! // Change the salt if it's too old.
//! if expiring_salt.is_expired() {
//! expiring_salt.rotate().expect("Salt rotation failed.");
//! }
//!
//! // Make a key that lasts for 120 seconds.
//! let key = AutoExpiring::<EdDsaKey>::generate(Duration::seconds(120)).unwrap();
//! // Make a payload for signing
//! let payload = SignedPayload::<String>::new("Hello, world!".to_string());
//!
//! // Combine the message and a special code (signature) into one piece.
//! let signature_bytes = payload.encode_salted(&expiring_salt, &*key).expect("Failed to encode");
//!
//! // Separate the message and the signature, checking they're valid.
//! let decoded_result = SignedPayload::<String>::decode_salted(&signature_bytes, &expiring_salt, &*key);
//! assert!(decoded_result.is_ok());
//! ```
//!
//! Using salts and rotating them regularly strengthens security by ensuring
//! that even repeated data or credentials produce different hashes or ciphertexts
//! across different instances or sessions.
//!
use error::BwError;
pub mod error;
pub mod exp;
pub mod keys;
pub mod payload;
pub mod salt;
pub mod signed_exp;
/// The `Generator` trait defines a common interface for types that require
/// a generation phase, typically resulting in the instantiation of a unique
/// or random state.
///
/// # Example
///
/// ```
/// # use bitwark::Generator;
/// # use bitwark::keys::ed::EdDsaKey;
/// let generated_key = EdDsaKey::generate().expect("Key generation failed");
/// ```
///
/// Implementing `Generator` trait for your own types enables the structured
/// creation of instances, particularly in cryptographic or secure contexts
/// where randomness or uniqueness is crucial.
pub trait Generator {
/// Generates and returns an instance of the implementing type.
///
/// # Errors
///
/// Returns [`crate::BwError`] in cases where generation
/// fails, e.g., due to insufficient system entropy, internal failures, etc.
fn generate() -> Result<Self, BwError>
where
Self: Sized;
}
/// The `Rotation` trait encapsulates the best practice of rotating
/// cryptographic or sensitive materials, minimizing the potential
/// impact of key compromise or algorithmic predictions.
///
/// Secure systems often implement rotation to limit the utility
/// of compromised keys and to periodically refresh cryptographic
/// materials, ensuring persistent protection against evolving threats.
///
/// # Example
///
/// ```
/// # use bitwark::{Generator, Rotation};
/// # use bitwark::keys::ed::EdDsaKey;
/// # use bitwark::exp::AutoExpiring;
/// # use chrono::Duration;
///
/// let key = EdDsaKey::generate().expect("Key generation failed");
/// let mut expiring_key = AutoExpiring::new(Duration::seconds(10), key).unwrap();
/// expiring_key.rotate().expect("Key generation failed");
/// ```
///
/// # Good Practices
///
/// Implement the `Rotation` trait for entities in your application
/// where periodical change or refreshment is vital for sustaining
/// security, especially for cryptographic keys, tokens, or salts.
pub trait Rotation {
fn rotate(&mut self) -> Result<(), BwError>;
}