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
//! Verification of cryptographic signatures.
//!
//! # Purpose
//!
//! This module defines the [`Verifier`] trait, which abstracts the process
//! of checking whether a given byte slice and a cryptographic signature are
//! valid according to a specific public key or verification context. In a
//! version control system, signature verification is used to confirm the
//! authenticity and integrity of signed objects such as commits and tags.
//!
//! # Design Rationale
//!
//! Verification is separated from signing for several reasons:
//!
//! - **Separation of concerns**: Signing requires private key material,
//! while verification only requires public information. Separating them
//! allows distributing verifiers widely without exposing secrets.
//! - **Different lifecycles**: A signer may be short-lived and stateful,
//! whereas a verifier can often be stateless and shared across threads.
//! - **Testability**: Dummy or deterministic verifiers simplify unit tests
//! of higher-level integrity checks.
//! - **Flexibility**: Different signature algorithms (Ed25519, RSA, ECDSA)
//! can be supported by implementing the same trait, keeping the rest of
//! the system agnostic.
//!
//! # Why `Result<bool>`?
//!
//! The [`Verifier::verify`] method returns `Result<bool, VctrlError>` rather
//! than a plain `bool` to allow distinguishing between:
//!
//! - A valid signature (`Ok(true)`).
//! - An invalid signature (`Ok(false)`).
//! - A failure to perform verification at all (`Err(...)`), for example
//! because the signature is malformed, the public key is invalid, or an
//! internal cryptographic error occurred.
//!
//! This design prevents callers from silently treating verification failures
//! as `false` and potentially accepting tampered data without realizing the
//! verifier itself failed.
//!
//! # Internal Mechanism
//!
//! A typical implementation receives the raw data, the signature bytes, and
//! uses its internal public key or verification context to perform the
//! cryptographic check. The exact steps depend on the algorithm, but the
//! trait ensures a uniform interface.
//!
//! # Relationship to [`Signer`](crate::Signer)
//!
//! A [`Signer`](crate::Signer) produces signatures, and a [`Verifier`]
//! checks them. They are designed as separate traits to reflect real-world
//! security practices where signing and verification use different keys and
//! often different software components.
//!
//! # Examples
//!
//! A simple verifier that compares data and signature for equality:
//!
//! ```
//! use libvctrl_handler::{Verifier, VctrlError};
//!
//! struct EqualityVerifier;
//!
//! impl Verifier for EqualityVerifier {
//! fn verify(&self, data: &[u8], signature: &[u8]) -> Result<bool, VctrlError> {
//! Ok(data == signature)
//! }
//! }
//!
//! let verifier = EqualityVerifier;
//! assert!(verifier.verify(b"msg", b"msg").unwrap());
//! assert!(!verifier.verify(b"msg", b"bad").unwrap());
//! ```
use crateVctrlError;
/// Defines the interface for verifying cryptographic signatures.
///
/// # Purpose
///
/// A `Verifier` checks whether a given byte slice and signature pair are
/// valid according to a specific cryptographic key or verification context.
/// It is the counterpart to [`Signer`](crate::Signer), which produces
/// signatures. Verification is used to confirm that data has not been
/// altered and was indeed signed by the claimed entity.
///
/// # Design Rationale
///
/// Returns `Result<bool, VctrlError>` rather than just `bool` to allow for
/// verification failures that are not strictly boolean (e.g., malformed
/// signature inputs, invalid public keys, or internal cryptographic errors).
/// This distinction is critical for security-sensitive code: callers can
/// detect whether verification could not be performed and treat such cases
/// differently from a signature that is simply invalid.
///
/// # Why `&self`?
///
/// The method takes `&self` because verification is generally a read-only
/// operation. A verifier holds a public key or verification context that can
/// be safely shared and reused. This also allows a single verifier instance
/// to be used concurrently across threads if the implementation is
/// [`Sync`].
///
/// # Why `&[u8]` for Data and Signature?
///
/// Both parameters are byte slices to keep the interface generic. The data
/// is typically a serialized object or message, and the signature is the
/// algorithm-specific byte encoding. Using slices avoids lifetime
/// constraints and allows verification of any byte sequence.
///
/// # Internal Mechanism
///
/// The implementation receives the raw data and signature bytes, retrieves
/// its public key or verification state, and performs the cryptographic
/// check. It returns `Ok(true)` if the signature is valid, `Ok(false)` if it
/// is not, or an error if the verification process itself fails (for
/// example, because the signature is malformed).
///
/// # Examples
///
/// A dummy verifier that compares data and signature:
///
/// ```
/// use libvctrl_handler::{Verifier, VctrlError};
///
/// struct DummyVerifier;
///
/// impl Verifier for DummyVerifier {
/// fn verify(&self, data: &[u8], signature: &[u8]) -> Result<bool, VctrlError> {
/// Ok(data == signature)
/// }
/// }
///
/// let verifier = DummyVerifier;
/// assert!(verifier.verify(b"msg", b"msg").unwrap());
/// assert!(!verifier.verify(b"msg", b"bad").unwrap());
/// ```