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
//! Constant-time equality comparison for cryptographic secrets.
//!
//! > **Import path:** `use secure_gate::ConstantTimeEq;`
//!
//! This module defines the [`ConstantTimeEq`] trait, which provides timing-attack-
//! resistant equality checks. Regular `==` operators can short-circuit on the first
//! differing byte, leaking information about secret values through execution time.
//!
//! All implementations use the `subtle` crate's constant-time primitives to ensure
//! comparisons take the same amount of time regardless of the data.
//!
//! Requires the `ct-eq` feature to be enabled.
//!
//! # Security Warning
//!
//! **Never** use `==` to compare cryptographic secrets, authentication tokens,
//! MACs, signatures, or other sensitive data. Always use `.ct_eq()`.
//!
//! # When to Use
//!
//! Use `ConstantTimeEq::ct_eq()` for all secret comparisons: keys, nonces, MACs,
//! tags, signatures, and variable-length secrets. It is deterministic and
//! constant-time; for very large buffers, compare in chunks or use a protocol-level
//! digest if you need a fixed-size equality check.
//!
//! `==` is deliberately not implemented on secret wrappers — always use `ct_eq`.
//!
//! # Examples
//!
//! ```rust
//! use secure_gate::ConstantTimeEq;
//!
//! let a = [1u8, 2, 3, 4].as_slice();
//! let b = [1u8, 2, 3, 4].as_slice();
//! let c = [1u8, 5, 3, 4].as_slice();
//!
//! assert!(a.ct_eq(b)); // equal — constant time
//! assert!(!a.ct_eq(c)); // not equal — same time as equal case
//!
//! // Works on fixed-size arrays and secret wrappers
//! use secure_gate::Fixed;
//! let key1: Fixed<[u8; 32]> = Fixed::new([0u8; 32]);
//! let key2: Fixed<[u8; 32]> = Fixed::new([0u8; 32]);
//! assert!(key1.ct_eq(&key2));
//! ```
//!
//! # Trait Implementations
//!
//! Blanket impls are provided for:
//!
//! - `&[u8]` / `[u8]` (byte slices)
//! - `[u8; N]` (fixed-size byte arrays)
//! - `Vec<u8>` / `String` (when `alloc` feature is enabled)
//!
//! These cover the most common secret types in cryptographic applications.
/// Constant-time equality comparison, preventing timing side-channel attacks.
///
/// Requires the `ct-eq` feature. Backed by the [`subtle`] crate internally.
/// Constant-time equality for byte slices.
/// Constant-time equality for fixed-size byte arrays.
/// Constant-time equality for owned byte vectors.
/// Constant-time equality for owned strings.
///
/// Compares raw UTF-8 bytes — callers must normalize Unicode before comparing
/// if normalization matters for their use case.