Skip to content

Commit d584735

Browse files
committed
fix rfc6979 generation
1 parent 92f783b commit d584735

File tree

1 file changed

+20
-29
lines changed

1 file changed

+20
-29
lines changed

dsa/src/generate/secret_number.rs

+20-29
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,14 @@
33
//!
44
55
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};
98
use digest::{core_api::BlockSizeUser, Digest, FixedOutputReset};
10-
use rfc6979::HmacDrbg;
119
use signature::rand_core::CryptoRngCore;
12-
use zeroize::Zeroize;
10+
use zeroize::Zeroizing;
1311

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)..]
3014
}
3115

3216
/// Generate a per-message secret number k deterministically using the method described in RFC 6979
@@ -40,20 +24,27 @@ where
4024
D: Digest + BlockSizeUser + FixedOutputReset,
4125
{
4226
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);
4536

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);
4939

50-
let mut buffer = vec![0; k_size];
40+
let mut buffer = vec![0; size];
5141
loop {
52-
hmac.fill_bytes(&mut buffer);
42+
rfc6979::generate_k_mut::<D>(x_bytes, q_bytes, hash, &[], &mut buffer);
5343

5444
let k = BoxedUint::from_be_slice(&buffer, (buffer.len() * 8) as u32).unwrap();
5545
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()));
5748
return (k, inv_k);
5849
}
5950
}

0 commit comments

Comments
 (0)