@@ -56,11 +56,16 @@ impl<P: SignatureParams> Signature<P> {
56
56
// Algorithm 27 sigDecode
57
57
pub fn decode ( enc : & EncodedSignature < P > ) -> Option < Self > {
58
58
let ( c_tilde, z, h) = P :: split_sig ( & enc) ;
59
- Some ( Self {
60
- c_tilde : c_tilde. clone ( ) ,
61
- z : P :: decode_z ( z) ,
62
- h : Hint :: bit_unpack ( h) ?,
63
- } )
59
+
60
+ let c_tilde = c_tilde. clone ( ) ;
61
+ let z = P :: decode_z ( z) ;
62
+ let h = Hint :: bit_unpack ( h) ?;
63
+
64
+ if z. infinity_norm ( ) >= P :: GAMMA1_MINUS_BETA {
65
+ return None ;
66
+ }
67
+
68
+ Some ( Self { c_tilde, z, h } )
64
69
}
65
70
}
66
71
@@ -164,24 +169,27 @@ impl<P: ParameterSet> SigningKey<P> {
164
169
let z = & y + & cs1;
165
170
let r0 = ( & w - & cs2) . low_bits :: < P :: Gamma2 > ( ) ;
166
171
167
- let gamma1_threshold = P :: Gamma1 :: U32 - P :: BETA ;
168
- let gamma2_threshold = P :: Gamma2 :: U32 - P :: BETA ;
169
- if r0 . infinity_norm ( ) > gamma2_threshold || z . infinity_norm ( ) > gamma1_threshold {
172
+ if z . infinity_norm ( ) > = P :: GAMMA1_MINUS_BETA
173
+ || r0 . infinity_norm ( ) >= P :: GAMMA2_MINUS_BETA
174
+ {
170
175
continue ;
171
176
}
172
177
173
178
let ct0 = ( & c_hat * & t0_hat) . ntt_inverse ( ) ;
174
179
let h = Hint :: < P > :: new ( -& ct0, & ( & w - & cs2) + & ct0) ;
175
180
176
- if ct0. infinity_norm ( ) > P :: Gamma2 :: U32 || h. hamming_weight ( ) > P :: Omega :: USIZE {
181
+ if ct0. infinity_norm ( ) >= P :: Gamma2 :: U32 || h. hamming_weight ( ) > P :: Omega :: USIZE {
177
182
continue ;
178
183
}
179
184
180
185
let z = z. mod_plus_minus ( FieldElement ( FieldElement :: Q ) ) ;
181
186
return Signature { c_tilde, z, h } ;
182
187
}
183
188
184
- // TODO(RLB) Make this method fallible
189
+ // XXX(RLB) We could be more parsimonious about the number of iterations here, and still
190
+ // have an overwhelming probability of success.
191
+ // XXX(RLB) I still don't love panicking. Maybe we should expose the fact that this method
192
+ // can fail?
185
193
panic ! ( "Rejection sampling failed to find a valid signature" ) ;
186
194
}
187
195
@@ -228,17 +236,17 @@ pub struct VerificationKey<P: ParameterSet> {
228
236
}
229
237
230
238
impl < P : ParameterSet > VerificationKey < P > {
231
- pub fn verify ( & self , Mp : & [ u8 ] , sigma : & Signature < P > ) -> bool
239
+ pub fn verify_internal ( & self , Mp : & [ u8 ] , sigma : & Signature < P > ) -> bool
232
240
where
233
241
P : VerificationKeyParams + SignatureParams ,
234
242
{
235
243
// TODO(RLB) pre-compute these and store them on the signing key struct
236
244
let A_hat = NttMatrix :: < P :: K , P :: L > :: expand_a ( & self . rho ) ;
237
- let t1_hat = ( FieldElement ( 1 << 13 ) * & self . t1 ) . ntt ( ) ;
245
+ let t1 = FieldElement ( 1 << 13 ) * & self . t1 ;
246
+ let t1_hat = t1. ntt ( ) ;
238
247
let tr: B64 = H :: default ( ) . absorb ( & self . encode ( ) ) . squeeze_new ( ) ;
239
248
240
249
// Compute the message representative
241
- // XXX(RLB) might need to run bytes_to_bits()?
242
250
let mu: B64 = H :: default ( ) . absorb ( & tr) . absorb ( & Mp ) . squeeze_new ( ) ;
243
251
244
252
// Reconstruct w
@@ -259,7 +267,7 @@ impl<P: ParameterSet> VerificationKey<P> {
259
267
. squeeze_new :: < P :: Lambda > ( ) ;
260
268
261
269
let gamma1_threshold = P :: Gamma1 :: U32 - P :: BETA ;
262
- return sigma. z . infinity_norm ( ) < gamma1_threshold && sigma . c_tilde == cp_tilde;
270
+ sigma. c_tilde == cp_tilde
263
271
}
264
272
265
273
// Algorithm 22 pkEncode
@@ -354,6 +362,12 @@ mod test {
354
362
let sk_bytes = sk. encode ( ) ;
355
363
let sk2 = SigningKey :: < P > :: decode ( & sk_bytes) ;
356
364
assert ! ( sk == sk2) ;
365
+
366
+ let sig = sk. sign_internal ( & [ 0 , 1 , 2 , 3 ] , ( & [ 0u8 ; 32 ] ) . into ( ) ) ;
367
+ let sig_bytes = sig. encode ( ) ;
368
+ println ! ( "sig_bytes: {:?}" , hex:: encode( & sig_bytes) ) ;
369
+ let sig2 = Signature :: < P > :: decode ( & sig_bytes) . unwrap ( ) ;
370
+ assert ! ( sig == sig2) ;
357
371
}
358
372
359
373
#[ test]
@@ -370,14 +384,13 @@ mod test {
370
384
let mut rng = rand:: thread_rng ( ) ;
371
385
372
386
let seed: [ u8 ; 32 ] = rng. gen ( ) ;
373
- let ( _pk , sk) = SigningKey :: < P > :: key_gen_internal ( & seed. into ( ) ) ;
387
+ let ( pk , sk) = SigningKey :: < P > :: key_gen_internal ( & seed. into ( ) ) ;
374
388
375
389
let rnd: [ u8 ; 32 ] = rng. gen ( ) ;
376
390
let Mp = b"Hello world" ;
377
- let _sig = sk. sign_internal ( Mp , & rnd. into ( ) ) ;
391
+ let sig = sk. sign_internal ( Mp , & rnd. into ( ) ) ;
378
392
379
- // TODO(RLB) Re-enable and debug
380
- // assert!(pk.verify(Mp, &sig));
393
+ assert ! ( pk. verify_internal( Mp , & sig) ) ;
381
394
}
382
395
383
396
#[ test]
0 commit comments