diff options
author | lloyd <[email protected]> | 2014-12-10 04:08:39 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2014-12-10 04:08:39 +0000 |
commit | 63215db88ae3bbb982966de37fe112c44f616a1d (patch) | |
tree | 7c73da7eaf981de4bfbeb15e137320940dcbcfd5 /src/lib/pubkey/dsa/dsa.cpp | |
parent | 10cfa8fd826e072a5cd76bf52f4ae80d34eba507 (diff) |
Implement RFC 6979 determinstic signatures for DSA and ECDSA.
Drop the GNU MP engine. Its implementations were potentially faster in
some scenarios but not well protected against side channels.
Diffstat (limited to 'src/lib/pubkey/dsa/dsa.cpp')
-rw-r--r-- | src/lib/pubkey/dsa/dsa.cpp | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/src/lib/pubkey/dsa/dsa.cpp b/src/lib/pubkey/dsa/dsa.cpp index c66db52f6..1dc2173da 100644 --- a/src/lib/pubkey/dsa/dsa.cpp +++ b/src/lib/pubkey/dsa/dsa.cpp @@ -1,6 +1,6 @@ /* * DSA -* (C) 1999-2010 Jack Lloyd +* (C) 1999-2010,2014 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -8,7 +8,9 @@ #include <botan/dsa.h> #include <botan/numthry.h> #include <botan/keypair.h> +#include <botan/rfc6979.h> #include <future> + namespace Botan { /* @@ -65,11 +67,13 @@ bool DSA_PrivateKey::check_key(RandomNumberGenerator& rng, bool strong) const return KeyPair::signature_consistency_check(rng, *this, "EMSA1(SHA-1)"); } -DSA_Signature_Operation::DSA_Signature_Operation(const DSA_PrivateKey& dsa) : +DSA_Signature_Operation::DSA_Signature_Operation(const DSA_PrivateKey& dsa, + const std::string& emsa) : q(dsa.group_q()), x(dsa.get_x()), powermod_g_p(dsa.group_g(), dsa.group_p()), - mod_q(dsa.group_q()) + mod_q(dsa.group_q()), + m_hash(hash_for_deterministic_signature(emsa)) { } @@ -80,22 +84,22 @@ DSA_Signature_Operation::sign(const byte msg[], size_t msg_len, rng.add_entropy(msg, msg_len); BigInt i(msg, msg_len); - BigInt r = 0, s = 0; - - while(r == 0 || s == 0) - { - BigInt k; - do - k.randomize(rng, q.bits()); - while(k >= q); - - auto future_r = std::async(std::launch::async, - [&]() { return mod_q.reduce(powermod_g_p(k)); }); - - s = inverse_mod(k, q); - r = future_r.get(); - s = mod_q.multiply(s, mul_add(x, r, i)); - } + + if(i >= q) + i -= q; + + const BigInt k = generate_rfc6979_nonce(x, q, i, m_hash); + + auto future_r = std::async(std::launch::async, + [&]() { return mod_q.reduce(powermod_g_p(k)); }); + + BigInt s = inverse_mod(k, q); + const BigInt r = future_r.get(); + s = mod_q.multiply(s, mul_add(x, r, i)); + + // With overwhelming probability, a bug rather than actual zero r/s + BOTAN_ASSERT(s != 0, "invalid s"); + BOTAN_ASSERT(r != 0, "invalid r"); secure_vector<byte> output(2*q.bytes()); r.binary_encode(&output[output.size() / 2 - r.bytes()]); |