clock_hash/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2#![warn(missing_docs)]
3
4//! # ClockHash-256: Consensus Hash Function for ClockinChain
5//!
6//! ClockHash-256 is a deterministic, fixed-output cryptographic hash function designed
7//! for ClockinChain consensus operations. It provides 256-bit security with domain separation
8//! for multi-purpose blockchain use cases.
9//!
10//! ## Features
11//!
12//! - **256-bit security**: Preimage and collision resistance
13//! - **Domain separation**: Different hash outputs for different use cases
14//! - **no_std compatibility**: Works in embedded environments
15//! - **Incremental hashing**: Stream data processing
16//! - **Constant-time operations**: Side-channel resistant
17//! - **Performance optimized**: ~1.5 GB/s target on modern hardware
18//!
19//! ## Quick Start
20//!
21//! ```rust
22//! use clock_hash::clockhash256;
23//!
24//! let data = b"Hello, ClockinChain!";
25//! let hash = clockhash256(data);
26//! assert_eq!(hash.len(), 32);
27//! ```
28//!
29//! ## Domain Separation
30//!
31//! ClockHash-256 uses domain separation to ensure different use cases produce
32//! different hash outputs, preventing cross-domain collision attacks.
33//!
34//! ```rust
35//! use clock_hash::{clockhash256_domain, clockhash256_with_domain, DomainTag, tags};
36//!
37//! let data = b"block header data";
38//!
39//! // Using domain bytes
40//! let block_hash = clockhash256_domain(tags::CLK_BLOCK, data);
41//!
42//! // Using typed domain enum
43//! let tx_hash = clockhash256_with_domain(DomainTag::Transaction, data);
44//!
45//! assert_ne!(block_hash, tx_hash); // Different domains = different hashes
46//! ```
47//!
48//! ## Incremental Hashing
49//!
50//! For large or streaming data, use incremental hashing:
51//!
52//! ```rust
53//! use clock_hash::ClockHasher;
54//!
55//! let mut hasher = ClockHasher::new();
56//! hasher.update(b"part 1");
57//! hasher.update(b"part 2");
58//! hasher.update(b"part 3");
59//! let hash = hasher.finalize();
60//! ```
61//!
62//! ## Domain Use Cases
63//!
64//! ### Block Headers
65//! ```rust
66//! # use clock_hash::{clockhash256_with_domain, DomainTag};
67//! let block_header = b"previous_hash || merkle_root || timestamp || ...";
68//! let block_hash = clockhash256_with_domain(DomainTag::Block, block_header);
69//! ```
70//!
71//! ### Transaction IDs
72//! ```rust
73//! # use clock_hash::{clockhash256_with_domain, DomainTag};
74//! let tx_data = b"inputs || outputs || metadata";
75//! let tx_id = clockhash256_with_domain(DomainTag::Transaction, tx_data);
76//! ```
77//!
78//! ### Merkle Trees
79//! ```rust
80//! # use clock_hash::{clockhash256_with_domain, DomainTag};
81//! let left_node = b"left child data";
82//! let right_node = b"right child data";
83//! let left_hash = clockhash256_with_domain(DomainTag::Merkle, left_node);
84//! let right_hash = clockhash256_with_domain(DomainTag::Merkle, right_node);
85//! let parent_data = [left_hash, right_hash].concat();
86//! let parent_hash = clockhash256_with_domain(DomainTag::Merkle, &parent_data);
87//! ```
88//!
89//! ### Signature Nonces
90//! ```rust
91//! # use clock_hash::{clockhash256_with_domain, DomainTag};
92//! let secret_data = b"private_key || message || counter";
93//! let nonce = clockhash256_with_domain(DomainTag::Nonce, secret_data);
94//! ```
95//!
96//! ### Deterministic RNG
97//! ```rust
98//! # use clock_hash::{clockhash256_with_domain, DomainTag};
99//! let seed_data = b"user_seed || domain_info";
100//! let rng_seed = clockhash256_with_domain(DomainTag::Rng, seed_data);
101//! ```
102//!
103//! ## Security Properties
104//!
105//! - **Preimage resistance**: Hard to find input for a given hash
106//! - **Second preimage resistance**: Hard to find different input with same hash
107//! - **Collision resistance**: Hard to find any two inputs with same hash
108//! - **Avalanche effect**: Small input changes affect ~50% of output bits
109//! - **Domain separation**: Different domains cannot collide
110//!
111//! ## Performance
112//!
113//! ClockHash-256 is optimized for modern hardware:
114//! - **Throughput**: ~1.5 GB/s on x86_64 (target)
115//! - **Memory**: Minimal footprint, cache-friendly
116//! - **SIMD**: AVX2/AVX-512 acceleration available
117//! - **no_std**: Zero heap allocations in core path
118
119mod clockmix;
120mod clockpermute;
121pub mod constants;
122pub mod cpuid;
123mod domain;
124mod hasher;
125mod padding;
126mod performance;
127mod security;
128pub mod utils;
129
130#[cfg(feature = "simd")]
131pub mod simd;
132
133pub use constants::{IV, P0, P1, ROTATION_SCHEDULE, SBOX};
134pub use domain::{DomainTag, clockhash256_domain, clockhash256_with_domain, tags};
135pub use hasher::ClockHasher;
136pub use performance::estimate_memory_usage;
137#[cfg(feature = "std")]
138pub use performance::{benchmark_sizes, measure_throughput, performance_stats, verify_performance};
139#[cfg(all(feature = "simd", feature = "std"))]
140pub use simd::dispatch::get_avx512_stats;
141pub use security::{verify_avalanche, verify_collision_resistance, verify_domain_separation};
142pub use utils::{rotl8, rotl64, rotr64};
143
144// Expose primitive functions for benchmarking and testing
145#[cfg(any(test, feature = "bench"))]
146pub use clockmix::clock_mix;
147#[cfg(any(test, feature = "bench"))]
148pub use clockpermute::clock_permute;
149
150/// Compute the ClockHash-256 hash of the input data.
151///
152/// This is the main entry point for computing ClockHash-256 hashes.
153/// The function processes the input data in 128-byte blocks, applies
154/// the ClockMix and ClockPermute operations, and produces a 32-byte hash.
155///
156/// # Arguments
157///
158/// * `data` - The input data to hash (can be any length)
159///
160/// # Returns
161///
162/// A 32-byte array containing the ClockHash-256 hash in little-endian format
163///
164/// # Examples
165///
166/// Basic usage:
167/// ```rust
168/// use clock_hash::clockhash256;
169///
170/// let data = b"Hello, world!";
171/// let hash = clockhash256(data);
172/// assert_eq!(hash.len(), 32);
173/// // Hash is now available as a 32-byte array
174/// ```
175///
176/// Hashing different inputs produces different outputs:
177/// ```rust
178/// # use clock_hash::clockhash256;
179/// let hash1 = clockhash256(b"input1");
180/// let hash2 = clockhash256(b"input2");
181/// assert_ne!(hash1, hash2);
182/// ```
183///
184/// Empty input:
185/// ```rust
186/// # use clock_hash::clockhash256;
187/// let hash = clockhash256(b"");
188/// // Still produces a valid 32-byte hash
189/// assert_eq!(hash.len(), 32);
190/// ```
191///
192/// # Performance
193///
194/// This function is optimized for performance:
195/// - Processes data in 128-byte blocks
196/// - Uses SIMD instructions when available
197/// - Constant-time operations for security
198/// - Minimal memory allocations
199#[inline]
200pub fn clockhash256(data: &[u8]) -> [u8; 32] {
201    let mut hasher = ClockHasher::new();
202    hasher.update(data);
203    hasher.finalize()
204}
205
206#[cfg(test)]
207mod tests {
208    use super::*;
209
210    #[test]
211    fn test_empty_string() {
212        let hash = clockhash256(b"");
213        // Test vector will be verified once implementation is complete
214        assert_eq!(hash.len(), 32);
215    }
216}