Botan  1.11.15
src/lib/pubkey/rfc6979/rfc6979.cpp
Go to the documentation of this file.
00001 /*
00002 * RFC 6979 Deterministic Nonce Generator
00003 * (C) 2014 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/rfc6979.h>
00009 #include <botan/hmac_drbg.h>
00010 #include <botan/scan_name.h>
00011 #include <botan/internal/algo_registry.h>
00012 
00013 namespace Botan {
00014 
00015 std::string hash_for_deterministic_signature(const std::string& emsa)
00016    {
00017    SCAN_Name emsa_name(emsa);
00018 
00019    if(emsa_name.arg_count() > 0)
00020       {
00021       const std::string pos_hash = emsa_name.arg(0);
00022       return pos_hash;
00023       }
00024 
00025    return "SHA-512"; // safe default if nothing we understand
00026    }
00027 
00028 BigInt generate_rfc6979_nonce(const BigInt& x,
00029                               const BigInt& q,
00030                               const BigInt& h,
00031                               const std::string& hash)
00032    {
00033    auto& macs = Algo_Registry<MessageAuthenticationCode>::global_registry();
00034    HMAC_DRBG rng(macs.make("HMAC(" + hash + ")"), nullptr);
00035 
00036    const size_t qlen = q.bits();
00037    const size_t rlen = qlen / 8 + (qlen % 8 ? 1 : 0);
00038 
00039    secure_vector<byte> input = BigInt::encode_1363(x, rlen);
00040 
00041    input += BigInt::encode_1363(h, rlen);
00042 
00043    rng.add_entropy(&input[0], input.size());
00044 
00045    BigInt k;
00046 
00047    secure_vector<byte> kbits(rlen);
00048 
00049    while(k == 0 || k >= q)
00050       {
00051       rng.randomize(&kbits[0], kbits.size());
00052       k = BigInt::decode(kbits) >> (8*rlen - qlen);
00053       }
00054 
00055    return k;
00056    }
00057 
00058 }