@@ -233,7 +233,8 @@ impl<Fq: FqTrait> Sqisign<Fq> {
233
233
. three_point_ladder ( & pk_basis, sig. chl_scalar , self . security_bits ) ;
234
234
chl_kernel = pk. curve . xmul_2e ( & chl_kernel, sig. backtracking ) ;
235
235
236
- // TODO: we need this chain to return errors on bad input.
236
+ // Compute the isogeny chain, a failure u32 is returned for the case of
237
+ // bad input.
237
238
pk. curve
238
239
. two_isogeny_chain ( & chl_kernel, self . f - sig. backtracking , & mut [ ] )
239
240
}
@@ -244,27 +245,32 @@ impl<Fq: FqTrait> Sqisign<Fq> {
244
245
where
245
246
[ ( ) ; Fq :: ENCODED_LENGTH ] : Sized ,
246
247
{
248
+ let mut shake_256 = Shake256 :: default ( ) ;
249
+
250
+ // For all but the last steps, we extract out hash_bytes from
251
+ // Shake256.
247
252
let hash_bytes = ( ( self . security_bits << 1 ) + 7 ) >> 3 ;
248
253
let mut xof_bytes = vec ! [ 0 ; hash_bytes] ;
249
254
250
255
// The first iteration hashes j(E_pk) || j(E_chl) || msg
251
- let mut sponge = Shake256 :: default ( ) ;
252
- sponge. update ( & E_pk . j_invariant ( ) . encode ( ) ) ;
253
- sponge. update ( & E_chl . j_invariant ( ) . encode ( ) ) ;
254
- sponge. update ( msg) ;
255
- sponge. finalize_xof_reset_into ( & mut xof_bytes) ;
256
+ shake_256. update ( & E_pk . j_invariant ( ) . encode ( ) ) ;
257
+ shake_256. update ( & E_chl . j_invariant ( ) . encode ( ) ) ;
258
+ shake_256. update ( msg) ;
259
+ shake_256. finalize_xof_reset_into ( & mut xof_bytes) ;
256
260
257
261
// Now iterate the hash many times to reach security goal
262
+ // We compute xof_bytes = Shake256(xof_bytes).read(hash_bytes)
258
263
for _ in 0 ..( self . hash_iterations - 2 ) {
259
- sponge . update ( & xof_bytes) ;
260
- sponge . finalize_xof_reset_into ( & mut xof_bytes) ;
264
+ shake_256 . update ( & xof_bytes) ;
265
+ shake_256 . finalize_xof_reset_into ( & mut xof_bytes) ;
261
266
}
262
267
263
- // For the last iteration we request a new number of bytes
268
+ // For the last iteration we request the number of bytes required
269
+ // for the scalar used to generate the challenge kernel.
264
270
let scalar_hash_bytes = ( self . security_bits + 7 ) >> 3 ;
265
271
let mut scalar = vec ! [ 0 ; scalar_hash_bytes] ;
266
- sponge . update ( & xof_bytes) ;
267
- sponge . finalize_xof_reset_into ( & mut scalar) ;
272
+ shake_256 . update ( & xof_bytes) ;
273
+ shake_256 . finalize_xof_reset_into ( & mut scalar) ;
268
274
269
275
// Finally we need to reduce this value modulo 2^(f - response_length)
270
276
let modulus_bit_length = self . f - self . response_length ;
@@ -398,11 +404,11 @@ impl<Fq: FqTrait> Sqisign<Fq> {
398
404
if chl_order == 0 {
399
405
return false ;
400
406
}
407
+
401
408
// Compute the challenge kernel and from this, E_chl from E_pk / <K>
409
+ // If the kernel is found to be maleformed in the 2^n isogeny chain.
410
+ // check = 0 and we must reject the signature.
402
411
let ( mut chl_curve, check) = self . compute_challenge_curve ( & pk, & sig) ;
403
-
404
- // If there is an error with the kernel derived from the signature, the 2^n isogeny chain
405
- // returns 0 and we reject the signature.
406
412
if check == 0 {
407
413
return false ;
408
414
}
@@ -412,6 +418,8 @@ impl<Fq: FqTrait> Sqisign<Fq> {
412
418
self . compute_torsion_bases ( & chl_curve, & sig, e_rsp_prime, chl_order) ;
413
419
414
420
// Compute the small 2-isogeny conditionally and push through the challenge basis.
421
+ // If the kernel is maleformed, `compute_small_isogeny` returns `false` and we must
422
+ // reject the signature.
415
423
if sig. two_resp_length > 0 {
416
424
if !Self :: compute_small_isogeny ( & mut chl_curve, & mut chl_basis, & sig, e_rsp_prime) {
417
425
return false ;
0 commit comments