23
23
24
24
use crate :: { CommitEncode , CommitmentProtocol } ;
25
25
26
- /// Trait for equivalence verification. Implemented for all types implemeting
26
+ /// Error during commitment verification
27
+ #[ derive( Copy , Clone , Eq , PartialEq , Debug , Display , Error , From ) ]
28
+ #[ display( doc_comments) ]
29
+ pub enum EmbedVerifyError < E : std:: error:: Error > {
30
+ /// The verified commitment doesn't commit to the provided message.
31
+ CommitmentMismatch ,
32
+
33
+ /// The message is invalid since a commitment to it can't be created /
34
+ /// exist.
35
+ ///
36
+ /// Details: {0}
37
+ #[ from]
38
+ InvalidMessage ( E ) ,
39
+
40
+ /// The proof of the commitment is invalid and the commitment can't be
41
+ /// verified since the original container can't be restored from it.
42
+ InvalidProof ,
43
+
44
+ /// The proof of the commitment does not match to the proof generated for
45
+ /// the same message during the verification.
46
+ ProofMismatch ,
47
+ }
48
+
49
+ /// Trait for equivalence verification. Implemented for all types implementing
27
50
/// `Eq`. For non-`Eq` types this trait provides way to implement custom
28
51
/// equivalence verification used during commitment verification procedure.
29
52
pub trait VerifyEq {
@@ -47,10 +70,15 @@ where
47
70
{
48
71
/// Restores original container before the commitment from the proof data
49
72
/// and a container containing embedded commitment.
73
+ ///
74
+ /// # Error
75
+ ///
76
+ /// If the container can't be restored from the proof returns
77
+ /// [`EmbedVerifyError::InvalidProof`].
50
78
fn restore_original_container (
51
79
& self ,
52
80
commit_container : & Container ,
53
- ) -> Result < Container , Container :: VerifyError > ;
81
+ ) -> Result < Container , EmbedVerifyError < Container :: CommitError > > ;
54
82
}
55
83
56
84
/// Trait for *embed-commit-verify scheme*, where some data structure (named
82
110
/// combination of the same message and container type (each of each will have
83
111
/// its own `Proof` type defined as an associated generic).
84
112
///
85
- /// Usually represents an uninstantiable type, but may be a structure
113
+ /// Usually represents a non-instantiable type, but may be a structure
86
114
/// containing commitment protocol configuration or context objects.
87
115
///
88
116
/// ```
@@ -109,14 +137,11 @@ where
109
137
type Proof : EmbedCommitProof < Msg , Self , Protocol > ;
110
138
111
139
/// Error type that may be reported during [`Self::embed_commit`] procedure.
112
- /// It may also be returned from [`Self::verify`] in case the proof data are
113
- /// invalid and the commitment can't be re-created.
140
+ /// It may also be returned from [`Self::verify`] (wrapped into
141
+ /// [`EmbedVerifyError`] in case the proof data are invalid and the
142
+ /// commitment can't be re-created.
114
143
type CommitError : std:: error:: Error ;
115
144
116
- /// Error type that may be reported during [`Self::verify`] procedure.
117
- /// It must be a subset of [`Self::CommitError`].
118
- type VerifyError : std:: error:: Error + From < Self :: CommitError > ;
119
-
120
145
/// Creates a commitment to a message and embeds it into the provided
121
146
/// container (`self`) by mutating it and returning commitment proof.
122
147
///
@@ -131,31 +156,28 @@ where
131
156
/// [`Self::embed_commit`] procedure checking that the resulting proof and
132
157
/// commitment matches the provided `self` and `proof`.
133
158
///
134
- /// Errors if the provided commitment can't be created, i.e. the
135
- /// [`Self::embed_commit`] procedure for the original container, restored
136
- /// from the proof and current container, can't be performed. This means
137
- /// that the verification has failed and the commitment and proof are
138
- /// invalid. The function returns error in this case (ano not simply
139
- /// `false`) since this usually means the software error in managing
140
- /// container and proof data, or selection of a different commitment
141
- /// protocol parameters comparing to the ones used during commitment
142
- /// creation. In all these cases we'd like to provide devs with more
143
- /// information for debugging.
159
+ /// # Errors
144
160
///
145
- /// The proper way of using the function in a well-debugged software should
146
- /// be `if commitment.verify(...).expect("proof managing system") { .. }` .
147
- /// However if the proofs are provided by some sort of user/network input
148
- /// from an untrusted party, a proper form would be
149
- /// `if commitment.verify(...).unwrap_or(false) { .. }`.
150
- # [ inline ]
151
- fn verify ( & self , msg : & Msg , proof : & Self :: Proof ) -> Result < bool , Self :: VerifyError >
161
+ /// Errors if the commitment doesn't pass the validation (see
162
+ /// [`EmbedVerifyError`] variants for the cases when this may happen) .
163
+ fn verify (
164
+ & self ,
165
+ msg : & Msg ,
166
+ proof : & Self :: Proof ,
167
+ ) -> Result < ( ) , EmbedVerifyError < Self :: CommitError > >
152
168
where
153
169
Self : VerifyEq ,
154
170
Self :: Proof : VerifyEq ,
155
171
{
156
172
let mut container_prime = proof. restore_original_container ( self ) ?;
157
173
let proof_prime = container_prime. embed_commit ( msg) ?;
158
- Ok ( proof_prime. verify_eq ( proof) && self . verify_eq ( & container_prime) )
174
+ if !proof_prime. verify_eq ( proof) {
175
+ return Err ( EmbedVerifyError :: InvalidProof ) ;
176
+ }
177
+ if !self . verify_eq ( & container_prime) {
178
+ return Err ( EmbedVerifyError :: CommitmentMismatch ) ;
179
+ }
180
+ Ok ( ( ) )
159
181
}
160
182
161
183
/// Phantom method used to add `Protocol` generic parameter to the trait.
@@ -207,18 +229,18 @@ pub(crate) mod test_helpers {
207
229
} ) ;
208
230
209
231
// Testing verification
210
- assert ! ( commitment. clone( ) . verify( msg, & proof) . unwrap ( ) ) ;
232
+ assert ! ( commitment. clone( ) . verify( msg, & proof) . is_ok ( ) ) ;
211
233
212
234
messages. iter ( ) . for_each ( |m| {
213
235
// Testing that commitment verification succeeds only
214
236
// for the original message and fails for the rest
215
- assert_eq ! ( commitment. clone( ) . verify( m, & proof) . unwrap ( ) , m == msg) ;
237
+ assert_eq ! ( commitment. clone( ) . verify( m, & proof) . is_ok ( ) , m == msg) ;
216
238
} ) ;
217
239
218
240
acc. iter ( ) . for_each ( |cmt| {
219
241
// Testing that verification against other commitments
220
242
// returns `false`
221
- assert ! ( !cmt. clone( ) . verify( msg, & proof) . unwrap ( ) ) ;
243
+ assert ! ( !cmt. clone( ) . verify( msg, & proof) . is_ok ( ) ) ;
222
244
} ) ;
223
245
224
246
// Detecting collision: each message should produce a unique
@@ -253,18 +275,18 @@ pub(crate) mod test_helpers {
253
275
} ) ;
254
276
255
277
// Testing verification
256
- assert ! ( SUPPLEMENT . verify( msg, & commitment) . unwrap ( ) ) ;
278
+ assert ! ( SUPPLEMENT . verify( msg, & commitment) . is_ok ( ) ) ;
257
279
258
280
messages. iter ( ) . for_each ( |m| {
259
281
// Testing that commitment verification succeeds only
260
282
// for the original message and fails for the rest
261
- assert_eq ! ( SUPPLEMENT . verify( m, & commitment) . unwrap ( ) , m == msg) ;
283
+ assert_eq ! ( SUPPLEMENT . verify( m, & commitment) . is_ok ( ) , m == msg) ;
262
284
} ) ;
263
285
264
286
acc. iter ( ) . for_each ( |commitment| {
265
287
// Testing that verification against other commitments
266
288
// returns `false`
267
- assert ! ( !SUPPLEMENT . verify( msg, commitment) . unwrap ( ) ) ;
289
+ assert ! ( !SUPPLEMENT . verify( msg, commitment) . is_ok ( ) ) ;
268
290
} ) ;
269
291
270
292
// Detecting collision: each message should produce a unique
@@ -303,7 +325,10 @@ mod test {
303
325
impl < T > EmbedCommitProof < T , DummyVec , TestProtocol > for DummyProof
304
326
where T : AsRef < [ u8 ] > + Clone + CommitEncode
305
327
{
306
- fn restore_original_container ( & self , _: & DummyVec ) -> Result < DummyVec , Error > {
328
+ fn restore_original_container (
329
+ & self ,
330
+ _: & DummyVec ,
331
+ ) -> Result < DummyVec , EmbedVerifyError < Error > > {
307
332
Ok ( DummyVec ( self . 0 . clone ( ) ) )
308
333
}
309
334
}
@@ -313,7 +338,6 @@ mod test {
313
338
{
314
339
type Proof = DummyProof ;
315
340
type CommitError = Error ;
316
- type VerifyError = Error ;
317
341
318
342
fn embed_commit ( & mut self , msg : & T ) -> Result < Self :: Proof , Self :: CommitError > {
319
343
let proof = self . 0 . clone ( ) ;
0 commit comments