3
3
//!
4
4
5
5
use crate :: { Components , SigningKey } ;
6
- use alloc:: { vec, vec:: Vec } ;
7
- use core:: cmp:: min;
8
- use crypto_bigint:: { BoxedUint , InvMod , NonZero , RandomBits } ;
6
+ use alloc:: vec;
7
+ use crypto_bigint:: { BoxedUint , Integer , InvMod , NonZero , RandomBits } ;
9
8
use digest:: { core_api:: BlockSizeUser , Digest , FixedOutputReset } ;
10
- use rfc6979:: HmacDrbg ;
11
9
use signature:: rand_core:: CryptoRngCore ;
12
- use zeroize:: Zeroize ;
10
+ use zeroize:: Zeroizing ;
13
11
14
- /// Reduce the hash into an RFC-6979 appropriate form
15
- fn reduce_hash ( q : & NonZero < BoxedUint > , hash : & [ u8 ] ) -> Vec < u8 > {
16
- // Reduce the hash modulo Q
17
- let q_byte_len = q. bits ( ) / 8 ;
18
-
19
- let hash_len = min ( hash. len ( ) , q_byte_len as usize ) ;
20
- let hash = & hash[ ..hash_len] ;
21
-
22
- let hash = BoxedUint :: from_be_slice ( hash, ( hash. len ( ) * 8 ) as u32 ) . unwrap ( ) ;
23
- let mut reduced = Vec :: from ( ( hash % q) . to_be_bytes ( ) ) ;
24
-
25
- while reduced. len ( ) < q_byte_len as usize {
26
- reduced. insert ( 0 , 0 ) ;
27
- }
28
-
29
- reduced
12
+ fn strip_leading_zeros ( buffer : & [ u8 ] , desired_size : usize ) -> & [ u8 ] {
13
+ & buffer[ ( buffer. len ( ) - desired_size) ..]
30
14
}
31
15
32
16
/// Generate a per-message secret number k deterministically using the method described in RFC 6979
@@ -40,20 +24,27 @@ where
40
24
D : Digest + BlockSizeUser + FixedOutputReset ,
41
25
{
42
26
let q = signing_key. verifying_key ( ) . components ( ) . q ( ) ;
43
- let k_size = ( q. bits ( ) / 8 ) as usize ;
44
- let hash = reduce_hash ( q, hash) ;
27
+ let size = ( q. bits ( ) / 8 ) as usize ;
28
+
29
+ // Reduce hash mod q
30
+ let hash = BoxedUint :: from_be_slice ( hash, ( hash. len ( ) * 8 ) as u32 ) . unwrap ( ) ;
31
+ let hash = ( hash % q) . to_be_bytes ( ) ;
32
+ let hash = strip_leading_zeros ( & hash, size) ;
33
+
34
+ let q_bytes = q. to_be_bytes ( ) ;
35
+ let q_bytes = strip_leading_zeros ( & q_bytes, size) ;
45
36
46
- let mut x_bytes = signing_key. x ( ) . to_be_bytes ( ) ;
47
- let mut hmac = HmacDrbg :: < D > :: new ( & x_bytes, & hash, & [ ] ) ;
48
- x_bytes. zeroize ( ) ;
37
+ let x_bytes = Zeroizing :: new ( signing_key. x ( ) . to_be_bytes ( ) ) ;
38
+ let x_bytes = strip_leading_zeros ( & x_bytes, size) ;
49
39
50
- let mut buffer = vec ! [ 0 ; k_size ] ;
40
+ let mut buffer = vec ! [ 0 ; size ] ;
51
41
loop {
52
- hmac . fill_bytes ( & mut buffer) ;
42
+ rfc6979 :: generate_k_mut :: < D > ( x_bytes , q_bytes , hash , & [ ] , & mut buffer) ;
53
43
54
44
let k = BoxedUint :: from_be_slice ( & buffer, ( buffer. len ( ) * 8 ) as u32 ) . unwrap ( ) ;
55
45
if let Some ( inv_k) = k. inv_mod ( q) . into ( ) {
56
- if k > BoxedUint :: zero ( ) && k < * * q {
46
+ if ( bool:: from ( k. is_nonzero ( ) ) ) & ( k < * * q) {
47
+ debug_assert ! ( bool :: from( k. is_odd( ) ) ) ;
57
48
return ( k, inv_k) ;
58
49
}
59
50
}
0 commit comments