diff options
Diffstat (limited to 'src/lib/pubkey/rfc6979/rfc6979.cpp')
-rw-r--r-- | src/lib/pubkey/rfc6979/rfc6979.cpp | 53 |
1 files changed, 32 insertions, 21 deletions
diff --git a/src/lib/pubkey/rfc6979/rfc6979.cpp b/src/lib/pubkey/rfc6979/rfc6979.cpp index 3bd723d6d..58cdbaa1b 100644 --- a/src/lib/pubkey/rfc6979/rfc6979.cpp +++ b/src/lib/pubkey/rfc6979/rfc6979.cpp @@ -1,6 +1,6 @@ /* * RFC 6979 Deterministic Nonce Generator -* (C) 2014 Jack Lloyd +* (C) 2014,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -25,32 +25,43 @@ std::string hash_for_deterministic_signature(const std::string& emsa) return "SHA-512"; // safe default if nothing we understand } -BigInt generate_rfc6979_nonce(const BigInt& x, - const BigInt& q, - const BigInt& h, - const std::string& hash) +RFC6979_Nonce_Generator::RFC6979_Nonce_Generator(const std::string& hash, + const BigInt& order, + const BigInt& x) : + m_order(order), + m_qlen(m_order.bits()), + m_rlen(m_qlen / 8 + (m_qlen % 8 ? 1 : 0)), + m_hmac_drbg(new HMAC_DRBG(make_message_auth("HMAC(" + hash + ")").release())), + m_rng_in(m_rlen * 2), + m_rng_out(m_rlen) { - HMAC_DRBG rng(make_message_auth("HMAC(" + hash + ")").release(), nullptr); - - const size_t qlen = q.bits(); - const size_t rlen = qlen / 8 + (qlen % 8 ? 1 : 0); - - secure_vector<byte> input = BigInt::encode_1363(x, rlen); - - input += BigInt::encode_1363(h, rlen); - - rng.add_entropy(&input[0], input.size()); - - BigInt k; + BigInt::encode_1363(&m_rng_in[0], m_rlen, x); + } - secure_vector<byte> kbits(rlen); +const BigInt& RFC6979_Nonce_Generator::nonce_for(const BigInt& m) + { + BigInt::encode_1363(&m_rng_in[m_rlen], m_rlen, m); + m_hmac_drbg->clear(); + m_hmac_drbg->add_entropy(&m_rng_in[0], m_rng_in.size()); - while(k == 0 || k >= q) + do { - rng.randomize(&kbits[0], kbits.size()); - k = BigInt::decode(kbits) >> (8*rlen - qlen); + m_hmac_drbg->randomize(&m_rng_out[0], m_rng_out.size()); + m_k.binary_decode(&m_rng_out[0], m_rng_out.size()); + m_k >>= (8*m_rlen - m_qlen); } + while(m_k == 0 || m_k >= m_order); + return m_k; + } + +BigInt generate_rfc6979_nonce(const BigInt& x, + const BigInt& q, + const BigInt& h, + const std::string& hash) + { + RFC6979_Nonce_Generator gen(hash, q, x); + BigInt k = gen.nonce_for(h); return k; } |