attrkey 0.1.0-alpha.1

Pure Rust implementation of a Selection-Sensitive Attribute-Based Key Derivation Scheme.
Documentation
//! A Rust implementation of Selection-Sensitive Attribute-Based Key
//! Derivation, providing a novel scheme where cryptographic keys are derived
//! from a collection of attributes, with sensitivity to selection within the
//! collection.
//!
//! An **attribute** is a piece of data that contributes to key derivation. A
//! collection of attributes is first hardened using memory-hard key
//! derivation, then organised into a keyspace from which attribute-based keys
//! can be selected.
//!
//! A **keyspace** consists of:
//! - A collection of hardened attribute values derived through parallel
//! [Argon2id](argon2::Argon2) key derivation with per-attribute salts.
//! - A proof-of-work constraint parameter for
//! [annihilative pair](annihilation::AnnihlKey::new_pair) generation.
//!
//! Key derivation requires selecting a subset of attribute indices, which
//! partitions the collection into two sets: selected and remaining attributes.
//! These are concatenated to form keying material for an
//! **annihilative pair**, where selected attributes become key material and
//! remaining attributes become antikey material. The derivation process mines
//! a pair satisfying the configured proof-of-work constraint, computes the
//! pair's [annihilation key](annihilation::AnnihlKey::to_annihilation), then
//! uses this key as a seed for [ChaCha8 CSPRNG](rand_chacha::ChaCha8Rng)
//! expansion to produce the final derived key.
//!
//! Derived keys depend on both which attributes are selected and which are
//! not. Different selections produce cryptographically independent keys,
//! even when there is overlap in selection. The memory-hard nature of Argon2id
//! makes brute-force attacks on individual attributes computationally
//! expensive, and the derived key's dependence on all attributes prevents an
//! attacker with knowledge of attribute selection from optimising by
//! discarding remaining attributes.
//!
//! The requirement to select at least one attribute, but not all attributes,
//! ensures that both partition sets are non-empty and the annihilative pair
//! can be constructed.
//!
//! # Example
//! ```
//! use attrkey::{Attributes, Params};
//! use sha2::Sha256;
//!
//! fn main() {
//!     let arr = vec![
//!         b"Pigs on the Wing I".to_vec(),
//!         b"Dogs".to_vec(),
//!         b"Pigs (Three Different Ones)".to_vec(),
//!         b"Sheep".to_vec(),
//!         b"Pigs on the Wing II".to_vec(),
//!     ];
//!
//!     // Create a collection of attributes with default parameters
//!     let attributes = Attributes::<Sha256>::new(arr, Params::default())
//!         .expect("valid set of attributes should produce collection");
//!
//!     // Harden attributes into a keyspace
//!     let salt = b"Animals";
//!     let keyspace = attributes
//!         .harden(salt)
//!         .expect("Argon2id should be able to harden all attributes");
//!
//!     // Derive keys from two selections within the same keyspace
//!     let selection_1 = vec![0, 2, 4];
//!     let selection_2 = vec![1, 3];
//!
//!     let dk_1 = keyspace
//!         .derive_key(&selection_1, Some(32))
//!         .expect("valid selection");
//!
//!     let mut dk_2 = [0u8; 32];
//!     keyspace
//!         .derive_key_into(&selection_2, &mut dk_2)
//!         .expect("valid selection");
//!
//!     // Different selections produce different keys
//!     assert_ne!(dk_1, dk_2);
//! }
//! ```
mod attributes;
mod errors;
mod keyspace;
mod params;

pub use crate::errors::ArrkeyError;
pub use crate::params::Params;
pub use attributes::Attributes;
pub use keyspace::Keyspace;